← back to hs3180__disclaude

Function bodies 284 total

All specs Real LLM only Function bodies
getDevelopmentConfig function · typescript · L94-L113 (20 LOC)
src/utils/logger.ts
function getDevelopmentConfig(): LoggerOptions {
  return {
    level: getDefaultLogLevel(),
    transport: {
      target: 'pino-pretty',
      options: {
        colorize: true,
        translateTime: 'SYS:standard',
        ignore: 'pid,hostname',
        singleLine: false,
        messageFormat: '[{context}] {msg}' // Add context prefix if present
      }
    },
    formatters: {
      level: (label) => {
        return { level: label };
      }
    }
  };
}
getProductionConfig function · typescript · L118-L136 (19 LOC)
src/utils/logger.ts
function getProductionConfig(): LoggerOptions {
  return {
    level: getDefaultLogLevel(),
    formatters: {
      level: (label) => {
        return { level: label };
      }
    },
    timestamp: pino.stdTimeFunctions.isoTime,
    serializers: {
      err: pino.stdSerializers.err,
      error: pino.stdSerializers.err
    },
    base: {
      pid: true,
      hostname: true
    }
  };
}
setupFileLogging function · typescript · L143-L172 (30 LOC)
src/utils/logger.ts
async function setupFileLogging(
  logDir: string
): Promise<NodeJS.WritableStream> {
  try {
    // Create logs directory if it doesn't exist
    const logsPath = path.resolve(process.cwd(), logDir);

    if (!fs.existsSync(logsPath)) {
      fs.mkdirSync(logsPath, { recursive: true });
    }

    // Dynamic import of pino-roll (no types available)
     
    const pinoRoll = (await import('pino-roll')) as unknown as (file: string, options: unknown) => NodeJS.WritableStream;

    // Combined log file with rotation
    const logFile = path.join(logsPath, 'disclaude-combined.log');
    const rollStream = pinoRoll(logFile, {
      size: '10M',
      limit: { count: 30 },
      compress: true
    });

    return rollStream;
  } catch (error) {
    // If pino-roll fails, fall back to stdout
    console.warn('Failed to setup file logging, falling back to stdout:', error);
    return process.stdout;
  }
}
createRedactionSerializer function · typescript · L177-L190 (14 LOC)
src/utils/logger.ts
function createRedactionSerializer(fields: string[] = SENSITIVE_FIELDS) {
  const redactPaths = fields.map((field) => `*.${field}`);

  return {
    serializers: {
      err: pino.stdSerializers.err,
      error: pino.stdSerializers.err
    },
    redact: {
      paths: redactPaths,
      remove: true
    }
  };
}
initLogger function · typescript · L209-L261 (53 LOC)
src/utils/logger.ts
export async function initLogger(config: LoggerConfig = {}): Promise<Logger> {
  if (rootLogger) {
    return rootLogger;
  }

  const isDev = isDevelopment();
  const logDir = config.logDir ?? process.env.LOG_DIR ?? './logs';

  // Get base configuration
  let options: LoggerOptions = isDev ? getDevelopmentConfig() : getProductionConfig();

  // Override log level if specified
  if (config.level) {
    options.level = config.level;
  }

  // Add redaction for sensitive fields
  if (!isDev || config.redact) {
    const redactConfig = createRedactionSerializer(config.redact);
    options = {
      ...options,
      serializers: {
        ...options.serializers,
        ...redactConfig.serializers
      },
      redact: redactConfig.redact
    };
  }

  // Add metadata if provided
  if (config.metadata) {
    options.base = {
      ...options.base,
      ...config.metadata
    };
  }

  // Setup file logging for production or if explicitly requested
  let logStream: NodeJS.WritableStream
createLogger function · typescript · L288-L307 (20 LOC)
src/utils/logger.ts
export function createLogger(
  context: string,
  metadata?: Record<string, unknown>
): Logger {
  // Ensure root logger is initialized
  if (!rootLogger) {
    // Synchronous initialization for immediate use
    const isDev = isDevelopment();
    const options = isDev ? getDevelopmentConfig() : getProductionConfig();
    rootLogger = pino(options, process.stdout);
  }

  // Create child logger with context
  const childLogger = rootLogger.child({
    context,
    ...metadata
  });

  return childLogger;
}
getRootLogger function · typescript · L316-L323 (8 LOC)
src/utils/logger.ts
export function getRootLogger(): Logger {
  if (!rootLogger) {
    const isDev = isDevelopment();
    const options = isDev ? getDevelopmentConfig() : getProductionConfig();
    rootLogger = pino(options, process.stdout);
  }
  return rootLogger;
}
Methodology: Repobility · https://repobility.com/research/state-of-ai-code-2026/
flushLogger function · typescript · L353-L361 (9 LOC)
src/utils/logger.ts
export function flushLogger(): Promise<void> {
  if (rootLogger) {
    return new Promise((resolve) => {
      // Pino uses async writes, give it time to flush
      setTimeout(resolve, 100);
    });
  }
  return Promise.resolve();
}
getColorForMessageType function · typescript · L29-L48 (20 LOC)
src/utils/output-adapter.ts
function getColorForMessageType(messageType: AgentMessageType): keyof typeof colors {
  switch (messageType) {
    case 'tool_use':
      return 'yellow';
    case 'tool_progress':
      return 'blue';
    case 'tool_result':
      return 'cyan';
    case 'error':
      return 'red';
    case 'status':
      return 'magenta';
    case 'result':
      return 'green';
    case 'notification':
      return 'dim';
    default:
      return 'reset';
  }
}
CLIOutputAdapter.write method · typescript · L86-L103 (18 LOC)
src/utils/output-adapter.ts
  write(content: string, messageType: AgentMessageType = 'text'): void {
    // Add newline between different message types
    if (messageType !== this.lastMessageType && messageType !== 'text') {
      console.log('');
    }

    // Format and output message
    const colorName = getColorForMessageType(messageType);
    const formatted = colorText(content, colorName);
    process.stdout.write(formatted);

    // Add newline for non-text messages
    if (messageType !== 'text') {
      console.log('');
    }

    this.lastMessageType = messageType;
  }
CLIOutputAdapter.finalize method · typescript · L108-L114 (7 LOC)
src/utils/output-adapter.ts
  finalize(): void {
    if (this.lastMessageType !== 'text') {
      console.log('');
    } else {
      console.log('');
    }
  }
FeishuOutputAdapter.constructor method · typescript · L154-L161 (8 LOC)
src/utils/output-adapter.ts
  constructor(private options: FeishuOutputAdapterOptions) {
    this.throttleIntervalMs = options.throttleIntervalMs ?? 2000;
    this.fileAttachmentConfig = {
      minLines: options.fileAttachment?.minLines ?? 500,
      minChars: options.fileAttachment?.minChars ?? 10000,
      patterns: options.fileAttachment?.patterns ?? ['*-report.md', 'summary.md', 'analysis-report.md'],
    };
  }
FeishuOutputAdapter.shouldSendProgress method · typescript · L180-L190 (11 LOC)
src/utils/output-adapter.ts
  private shouldSendProgress(toolName: string): boolean {
    const key = `${this.options.chatId}:${toolName}`;
    const now = Date.now();
    const lastSent = this.progressThrottleMap.get(key);

    if (lastSent === undefined || now - lastSent >= this.throttleIntervalMs) {
      this.progressThrottleMap.set(key, now);
      return true;
    }
    return false;
  }
FeishuOutputAdapter.clearThrottleState method · typescript · L195-L201 (7 LOC)
src/utils/output-adapter.ts
  clearThrottleState(): void {
    for (const key of this.progressThrottleMap.keys()) {
      if (key.startsWith(`${this.options.chatId}:`)) {
        this.progressThrottleMap.delete(key);
      }
    }
  }
FeishuOutputAdapter.shouldAutoAttachFile method · typescript · L211-L226 (16 LOC)
src/utils/output-adapter.ts
  private shouldAutoAttachFile(filePath: string, lineCount: number, charCount: number): boolean {
    const fileName = path.basename(filePath);

    // Check if file matches any of the configured patterns
    const matchesPattern = this.fileAttachmentConfig.patterns.some(pattern => {
      // Simple glob matching for *-report.md patterns
      const regex = new RegExp(`^${pattern.replace(/\*/g, '.*').replace(/\?/g, '.')}$`);
      return regex.test(fileName);
    });

    // Check thresholds
    const exceedsLineThreshold = lineCount >= this.fileAttachmentConfig.minLines;
    const exceedsCharThreshold = charCount >= this.fileAttachmentConfig.minChars;

    return matchesPattern || exceedsLineThreshold || exceedsCharThreshold;
  }
Repobility · code-quality intelligence platform · https://repobility.com
FeishuOutputAdapter.write method · typescript · L228-L273 (46 LOC)
src/utils/output-adapter.ts
  async write(
    content: string,
    messageType: AgentMessageType = 'text',
    metadata?: MessageMetadata
  ): Promise<void> {
    // Skip empty or whitespace-only content
    const trimmedContent = content.trim();
    if (!trimmedContent) {
      return;
    }

    // Skip SDK completion messages (they create visual noise)
    if (messageType === 'result' && trimmedContent.startsWith('✅ Complete')) {
      return;
    }

    // Throttle progress messages
    if (messageType === 'tool_progress') {
      // Extract tool name from content if possible
      const toolMatch = content.match(/Using (\w+):/);
      const toolName = toolMatch ? toolMatch[1] : 'unknown';
      if (!this.shouldSendProgress(toolName)) {
        return; // Skip this message due to throttling
      }
    }

    let cardSent = false;

    // Handle Edit tool use with unified diff card
    if (messageType === 'tool_use' && metadata?.toolName === 'Edit' && metadata?.toolInputRaw) {
      cardSent = await this.sen
FeishuOutputAdapter.sendEditDiffCard method · typescript · L281-L315 (35 LOC)
src/utils/output-adapter.ts
  private async sendEditDiffCard(toolInput: Record<string, unknown>): Promise<boolean> {
    logger.debug({ keys: Object.keys(toolInput) }, 'Edit tool input keys');
    logger.debug({ toolInput }, 'Edit tool input');

    try {
      // Dynamic import to avoid circular dependencies
      const { parseEditToolInput, buildUnifiedDiffCard } = await import('../feishu/diff-card-builder.js');

      const codeChange = parseEditToolInput(toolInput);
      logger.debug({ success: !!codeChange }, 'Parse edit tool input result');

      if (!codeChange) {
        logger.debug({
          file_path: toolInput.file_path,
          filePath: toolInput.filePath,
        }, 'File path check');
      }

      if (codeChange) {
        const card = buildUnifiedDiffCard([codeChange], '📝 代码编辑', 'blue');
        logger.debug('Card built, sending...');
        await this.options.sendCard(this.options.chatId, card);
        logger.debug('Card sent successfully');
        return true;
      }
    } catch (er
FeishuOutputAdapter.sendWriteContentCard method · typescript · L323-L389 (67 LOC)
src/utils/output-adapter.ts
  private async sendWriteContentCard(toolInput: Record<string, unknown>): Promise<boolean> {
    logger.debug({ keys: Object.keys(toolInput) }, 'Write tool input keys');
    logger.debug({ toolInput }, 'Write tool input');

    try {
      // Dynamic import to avoid circular dependencies
      const { parseWriteToolInput, buildWriteContentCard } = await import('../feishu/write-card-builder.js');

      const writeContent = parseWriteToolInput(toolInput);
      logger.debug({ success: !!writeContent }, 'Parse write tool input result');

      if (!writeContent) {
        logger.debug({
          file_path: toolInput.file_path,
          filePath: toolInput.filePath,
        }, 'File path check');
      }

      if (writeContent) {
        const card = buildWriteContentCard(writeContent, '✍️ 文件写入', 'green');
        logger.debug('Card built, sending...');
        await this.options.sendCard(this.options.chatId, card);
        logger.debug('Card sent successfully');

        // Check if f
safeStringify function · typescript · L31-L38 (8 LOC)
src/utils/sdk.ts
function safeStringify(obj: unknown, maxLength: number = 100): string {
  try {
    const str = JSON.stringify(obj);
    return truncate(str, maxLength);
  } catch {
    return String(obj);
  }
}
formatToolInput function · typescript · L43-L96 (54 LOC)
src/utils/sdk.ts
function formatToolInput(toolName: string, input: Record<string, unknown> | undefined): string {
  if (!input) {return '';}

  switch (toolName) {
    case 'Bash':
      const cmd = input.command as string | undefined;
      return `Running: ${cmd || '<no command>'}`;

    case 'Edit':
      const editPath = (input.file_path as string | undefined) || (input.filePath as string | undefined);
      return `Editing: ${editPath || '<unknown file>'}`;

    case 'Read':
      const readPath = input.file_path as string | undefined;
      return `Reading: ${readPath || '<unknown file>'}`;

    case 'Write': {
      const writePath = input.file_path as string | undefined;
      const writeContent = input.content as string | undefined;
      const lineCount = writeContent ? writeContent.split('\n').length : 0;
      return writePath
        ? `Writing: ${writePath} (${lineCount} lines)`
        : 'Writing: <unknown file>';
    }

    case 'Grep': {
      const pattern = input.pattern as string | 
formatEditToolUse function · typescript · L102-L137 (36 LOC)
src/utils/sdk.ts
function formatEditToolUse(input: Record<string, unknown>): string {
  // SDK uses snake_case for Edit tool parameters
  const filePath = (input.file_path as string | undefined) || (input.filePath as string | undefined);
  const oldString = (input.old_string as string | undefined) || (input.oldString as string | undefined);
  const newString = (input.new_string as string | undefined) || (input.newString as string | undefined);

  if (!filePath) {
    return '🔧 Editing: <unknown file>';
  }

  // Build rich formatted output
  const lines: string[] = [];

  // Header with file path (cyan for file)
  lines.push(`\x1b[36m📝 Editing:\x1b[0m \x1b[1;34m${filePath}\x1b[0m`);

  // Show content preview if available
  if (oldString !== undefined && newString !== undefined) {
    // Truncate long strings for display
    const maxPreview = 100;
    const oldPreview = oldString.length > maxPreview
      ? `${oldString.substring(0, maxPreview)  }...`
      : oldString;
    const newPreview = newStrin
parseSDKMessage function · typescript · L146-L341 (196 LOC)
src/utils/sdk.ts
export function parseSDKMessage(message: SDKMessage): ParsedSDKMessage {
  const result: ParsedSDKMessage = {
    type: 'text',
    content: '',
    metadata: {},
  };

  // Extract session_id from any message that has it
  if ('session_id' in message && message.session_id) {
    result.sessionId = message.session_id;
  }

  switch (message.type) {
    case 'assistant': {
      const apiMessage = message.message;
      if (!apiMessage || !Array.isArray(apiMessage.content)) {
        return { type: 'text', content: '' };
      }

      // Check for tool_use blocks in content
      const toolBlocks = apiMessage.content.filter(
        (block) => block.type === 'tool_use'
      );

      // Check for text blocks
      const textBlocks = apiMessage.content.filter(
        (block) => block.type === 'text' && 'text' in block
      );

      // Accumulate all content blocks (tool uses + text)
      const contentParts: string[] = [];

      // Process all tool use blocks
      for (const block
extractText function · typescript · L353-L370 (18 LOC)
src/utils/sdk.ts
export function extractText(message: AgentMessage): string {
  const { content } = message;

  if (typeof content === 'string') {
    return content;
  }

  if (Array.isArray(content)) {
    return content
      .filter((block): block is ContentBlock & { text: string } =>
        'text' in block && typeof block.text === 'string'
      )
      .map(block => block.text)
      .join('');
  }

  return '';
}
Repobility · code-quality intelligence · https://repobility.com
buildSdkEnv function · typescript · L381-L411 (31 LOC)
src/utils/sdk.ts
export function buildSdkEnv(
  apiKey: string,
  apiBaseUrl?: string,
  extraEnv?: Record<string, string | undefined>
): Record<string, string | undefined> {
  const nodeBinDir = getNodeBinDir();
  const newPath = `${nodeBinDir}:${process.env.PATH || ''}`;

  // Priority (highest to lowest):
  // 1. Our forced values (API_KEY, PATH, BASE_URL, DEBUG)
  // 2. process.env (system environment)
  // 3. extraEnv (caller-provided defaults)
  // This ensures system env vars can't be accidentally overridden by extraEnv,
  // but our critical values always take precedence.
  const env: Record<string, string | undefined> = {
    ...extraEnv,
    ...(process.env as Record<string, string | undefined>),
    ANTHROPIC_API_KEY: apiKey,
    PATH: newPath,
    // Enable SDK debug logging by default for better troubleshooting
    // SDK subprocess errors go to stderr and are critical for debugging
    DEBUG_CLAUDE_AGENT_SDK: process.env.DEBUG_CLAUDE_AGENT_SDK ?? '1',
  };

  // Set base URL if provided (
copyDirectory function · typescript · L97-L117 (21 LOC)
src/utils/skills-setup.ts
async function copyDirectory(source: string, target: string): Promise<void> {
  // Create target directory
  await fs.mkdir(target, { recursive: true });

  // Read source directory
  const entries = await fs.readdir(source, { withFileTypes: true });

  // Copy each entry
  for (const entry of entries) {
    const sourcePath = path.join(source, entry.name);
    const targetPath = path.join(target, entry.name);

    if (entry.isDirectory()) {
      // Recursively copy subdirectory
      await copyDirectory(sourcePath, targetPath);
    } else {
      // Copy file
      await fs.copyFile(sourcePath, targetPath);
    }
  }
}
TaskTracker.ensureTasksDir method · typescript · L46-L52 (7 LOC)
src/utils/task-tracker.ts
  async ensureTasksDir(): Promise<void> {
    try {
      await fs.mkdir(this.tasksDir, { recursive: true });
    } catch (error) {
      console.error('Failed to create tasks directory:', error);
    }
  }
TaskTracker.ensureTaskDir method · typescript · L58-L69 (12 LOC)
src/utils/task-tracker.ts
  private async ensureTaskDir(messageId: string): Promise<string> {
    await this.ensureTasksDir();
    const sanitized = messageId.replace(/[^a-zA-Z0-9_-]/g, '_');
    const taskDir = path.join(this.tasksDir, sanitized);
    try {
      await fs.mkdir(taskDir, { recursive: true });
      return taskDir;
    } catch (error) {
      console.error(`Failed to create task directory for ${messageId}:`, error);
      throw error;
    }
  }
TaskTracker.ensureTaskDirSync method · typescript · L75-L97 (23 LOC)
src/utils/task-tracker.ts
  private ensureTaskDirSync(messageId: string): string {
    const dirExists = syncFs.existsSync(this.tasksDir);
    if (!dirExists) {
      try {
        syncFs.mkdirSync(this.tasksDir, { recursive: true });
      } catch (error) {
        console.error('Failed to create regular tasks directory:', error);
        throw error;
      }
    }
    const sanitized = messageId.replace(/[^a-zA-Z0-9_-]/g, '_');
    const taskDir = path.join(this.tasksDir, sanitized);
    const taskDirExists = syncFs.existsSync(taskDir);
    if (!taskDirExists) {
      try {
        syncFs.mkdirSync(taskDir, { recursive: true });
      } catch (error) {
        console.error(`Failed to create task directory for ${messageId}:`, error);
        throw error;
      }
    }
    return taskDir;
  }
TaskTracker.getTaskFilePath method · typescript · L102-L107 (6 LOC)
src/utils/task-tracker.ts
  getTaskFilePath(messageId: string): string {
    // Sanitize message_id to make it a valid filename
    // Replace characters that are invalid in filenames
    const sanitized = messageId.replace(/[^a-zA-Z0-9_-]/g, '_');
    return path.join(this.tasksDir, sanitized, 'task.md');
  }
TaskTracker.saveTaskRecord method · typescript · L118-L143 (26 LOC)
src/utils/task-tracker.ts
  async saveTaskRecord(
    messageId: string,
    metadata: {
      chatId: string;
      senderType?: string;
      senderId?: string;
      text: string;
      timestamp?: string;
    },
    content: string
  ): Promise<void> {
    await this.ensureTaskDir(messageId);

    const filePath = this.getTaskFilePath(messageId);
    const timestamp = metadata.timestamp || new Date().toISOString();

    // Use new dialogue format
    const markdown = this.formatDialogueTaskRecord(messageId, metadata, content, timestamp);

    try {
      await fs.writeFile(filePath, markdown, 'utf-8');
      console.log(`[Task saved] ${messageId} -> ${filePath}`);
    } catch (error) {
      console.error(`[Task save failed] ${messageId}:`, error);
    }
  }
TaskTracker.saveTaskRecordSync method · typescript · L153-L179 (27 LOC)
src/utils/task-tracker.ts
  saveTaskRecordSync(
    messageId: string,
    metadata: {
      chatId: string;
      senderType?: string;
      senderId?: string;
      text: string;
      timestamp?: string;
    },
    content: string
  ): void {
    // Ensure task directory exists synchronously
    this.ensureTaskDirSync(messageId);

    const filePath = this.getTaskFilePath(messageId);
    const timestamp = metadata.timestamp || new Date().toISOString();

    // Use new dialogue format
    const markdown = this.formatDialogueTaskRecord(messageId, metadata, content, timestamp);

    try {
      syncFs.writeFileSync(filePath, markdown, 'utf-8');
      console.log(`[Task saved sync] ${messageId} -> ${filePath}`);
    } catch (error) {
      console.error(`[Task save failed] ${messageId}:`, error);
    }
  }
Repobility analyzer · published findings · https://repobility.com
TaskTracker.formatDialogueTaskRecord method · typescript · L185-L214 (30 LOC)
src/utils/task-tracker.ts
  private formatDialogueTaskRecord(
    messageId: string,
    metadata: {
      chatId: string;
      senderType?: string;
      senderId?: string;
      text: string;
    },
    _content: string,
    timestamp: string
  ): string {
    // Extract title from first line or first 50 chars
    const [firstLine] = metadata.text.split('\n');
    const title = firstLine.substring(0, 50) + (firstLine.length > 50 ? '...' : '');

    return `# Task: ${title}

**Task ID**: ${messageId}
**Created**: ${timestamp}
**Chat ID**: ${metadata.chatId}
**User ID**: ${metadata.senderId || 'N/A'}
${metadata.senderType ? `**Sender Type**: ${metadata.senderType}` : ''}

## Original Request

\`\`\`
${metadata.text}
\`\`\`
`;
  }
TaskTracker.createDialogueTask method · typescript · L238-L278 (41 LOC)
src/utils/task-tracker.ts
  async createDialogueTask(
    messageId: string,
    metadata: {
      chatId: string;
      userId?: string;
      text: string;
      timestamp?: string;
    }
  ): Promise<string> {
    await this.ensureTaskDir(messageId);

    const taskPath = this.getDialogueTaskPath(messageId);
    const timestamp = metadata.timestamp || new Date().toISOString();

    // Extract title from first line or first 50 chars
    const [firstLine] = metadata.text.split('\n');
    const title = firstLine.substring(0, 50) + (firstLine.length > 50 ? '...' : '');

    const content = `# Task: ${title}

**Task ID**: ${messageId}
**Created**: ${timestamp}
**Chat ID**: ${metadata.chatId}
**User ID**: ${metadata.userId || 'N/A'}

## Original Request

\`\`\`
${metadata.text}
\`\`\`
`;

    try {
      await fs.writeFile(taskPath, content, 'utf-8');
      console.log(`[Dialogue task created] ${messageId} -> ${taskPath}`);
      return taskPath;
    } catch (error) {
      console.error(`[Dialogue task creation f
TaskTracker.appendTaskDefinition method · typescript · L287-L336 (50 LOC)
src/utils/task-tracker.ts
  async appendTaskDefinition(
    taskPath: string,
    details: TaskDefinitionDetails
  ): Promise<void> {
    const existingContent = await fs.readFile(taskPath, 'utf-8');

    const appendContent = `

## Task Objectives

### Primary Goal
${details.primary_goal}

### Success Criteria
${details.success_criteria.map(c => `- ${c}`).join('\n')}

### Expected Outcome
${details.expected_outcome}

## Delivery Specifications

### Required Deliverables
${details.deliverables.map(d => `- ${d}`).join('\n')}
${details.format_requirements?.length ? `
### Format Requirements
${details.format_requirements.map(r => `- ${r}`).join('\n')}
` : ''}
${details.constraints?.length ? `
### Constraints
${details.constraints.map(c => `- ${c}`).join('\n')}
` : ''}

## Quality Criteria

${details.quality_criteria.map(q => `- ${q}`).join('\n')}

---

*Task definition generated by Pilot*
*This document serves as a record and will not be modified during execution.*
`;

    try {
      await fs.writeFile(taskPath, 
‹ prevpage 6 / 6