claude-ws 0.4.4 → 0.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +3 -3
- package/.next/fallback-build-manifest.json +3 -3
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +1 -1
- package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/server/chunks/src_lib_agent-manager_ts_0o7~e5j._.js +2 -2
- package/.next/server/chunks/src_lib_agent-manager_ts_0o7~e5j._.js.map +1 -1
- package/.next/server/middleware/middleware-manifest.json +1 -1
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/middleware-manifest.json +1 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/package.json +1 -1
- package/packages/agentic-sdk/src/agent/claude-sdk-agent-provider.ts +2 -17
- package/src/lib/providers/claude-sdk-query-options-builder.ts +3 -13
- /package/.next/static/{64tB4MNnFYxf4Ic_rwxWx → 5G902DD-80Ibj1L3h4Q-7}/_buildManifest.js +0 -0
- /package/.next/static/{64tB4MNnFYxf4Ic_rwxWx → 5G902DD-80Ibj1L3h4Q-7}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{64tB4MNnFYxf4Ic_rwxWx → 5G902DD-80Ibj1L3h4Q-7}/_ssgManifest.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/agent-manager.ts","../../../src/lib/system-prompt.ts","../../../src/lib/providers/claude-sdk-provider.ts","../../../packages/agentic-sdk/src/agent/claude-sdk-message-to-output-adapter.ts","../../../src/lib/sdk-event-adapter.ts","../../../src/lib/providers/claude-sdk-mcp-config-loader.ts","../../../src/lib/providers/claude-sdk-model-alias-and-server-command-utils.ts","../../../src/lib/providers/claude-sdk-query-options-builder.ts","../../../src/lib/providers/claude-cli-session-and-pending-question-types.ts","../../../src/lib/providers/claude-cli-process-spawner.ts","../../../src/lib/providers/claude-cli-stdout-line-to-provider-event-parser.ts","../../../src/lib/providers/claude-cli-provider.ts","../../../src/lib/providers/index.ts","../../../src/lib/agent-output-handler.ts","../../../src/lib/agent-event-wiring.ts","../../../src/lib/context-health.ts","../../../src/lib/usage-context-token-calculator.ts","../../../src/lib/usage-tracker.ts","../../../src/lib/git-stats-collector.ts","../../../src/lib/agent-workflow-message-tracker.ts","../../../src/lib/agent-persistent-question-store.ts"],"sourcesContent":["/**\n * Agent Manager - Thin orchestrator delegating to providers\n *\n * Selects between Claude CLI and SDK providers, builds prompts,\n * and forwards provider events to AgentManager events (identical API).\n * Cross-cutting concerns: sessionManager, checkpointManager, usageTracker, workflowTracker.\n */\n\n// Ensure file checkpointing is always enabled\nprocess.env.CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING = '1';\n\n// Enable SDK task system (opt-in feature since v0.2.19)\nprocess.env.CLAUDE_CODE_ENABLE_TASKS = 'true';\n\nimport { EventEmitter } from 'events';\nimport { readFile } from 'fs/promises';\nimport { resolve, isAbsolute } from 'path';\nimport type { ClaudeOutput } from '../types';\nimport type { BackgroundShellInfo } from './sdk-event-adapter';\nimport { getSystemPrompt } from './system-prompt';\nimport { modelIdToDisplayName } from './models';\nimport { createLogger } from './logger';\nimport { getActiveProvider, getProvider, type Provider, type ProviderSession } from './providers';\nimport { buildOutputFormatPrompt } from './agent-output-handler';\nimport { wireProviderEvents, type EventWiringContext } from './agent-event-wiring';\nimport { PersistentQuestionStore, type PersistentQuestionData } from './agent-persistent-question-store';\n\nconst log = createLogger('AgentManager');\nconst FALLBACK_MODEL_ID = 'claude-opus-4-6';\n\nfunction resolveDefaultModelFromEnv(): string {\n const envCandidates = [\n process.env.ANTHROPIC_MODEL,\n process.env.ANTHROPIC_DEFAULT_OPUS_MODEL,\n process.env.ANTHROPIC_DEFAULT_SONNET_MODEL,\n process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL,\n ];\n\n for (const candidate of envCandidates) {\n const value = candidate?.trim();\n if (value) return value;\n }\n\n return FALLBACK_MODEL_ID;\n}\n\ninterface AgentInstance {\n attemptId: string;\n session: ProviderSession;\n provider: Provider;\n startedAt: number;\n outputFormat?: string;\n}\n\ninterface AgentEvents {\n started: (data: { attemptId: string; taskId: string }) => void;\n json: (data: { attemptId: string; data: ClaudeOutput }) => void;\n stderr: (data: { attemptId: string; content: string }) => void;\n exit: (data: { attemptId: string; code: number | null }) => void;\n question: (data: { attemptId: string; toolUseId: string; questions: unknown[] }) => void;\n questionResolved: (data: { attemptId: string }) => void;\n backgroundShell: (data: { attemptId: string; shell: BackgroundShellInfo }) => void;\n trackedProcess: (data: { attemptId: string; pid: number; command: string; logFile?: string }) => void;\n promptTooLong: (data: { attemptId: string }) => void;\n}\n\nexport interface AgentStartOptions {\n attemptId: string;\n projectPath: string;\n prompt: string;\n model?: string;\n provider?: 'claude-cli' | 'claude-sdk';\n sessionOptions?: {\n resume?: string;\n resumeSessionAt?: string;\n };\n filePaths?: string[];\n outputFormat?: string;\n outputSchema?: string;\n maxTurns?: number;\n}\n\n/**\n * AgentManager - Singleton orchestrator that delegates to providers\n */\nclass AgentManager extends EventEmitter {\n private agents = new Map<string, AgentInstance>();\n // Track Bash tool_use commands to correlate with BGPID results\n private pendingBashCommands = new Map<string, { command: string; attemptId: string }>();\n // Persistent question storage — survives agent cleanup (keyed by taskId)\n private persistentQuestionStore = new PersistentQuestionStore();\n\n constructor() {\n super();\n process.on('exit', () => this.cancelAll());\n }\n\n /**\n * Build the EventWiringContext interface for extracted event wiring\n */\n private buildWiringContext(): EventWiringContext {\n return {\n getSessionId: (attemptId: string) => this.agents.get(attemptId)?.session.sessionId,\n setSessionId: (attemptId: string, sessionId: string) => {\n const instance = this.agents.get(attemptId);\n if (instance) instance.session.sessionId = sessionId;\n },\n deleteAgent: (attemptId: string) => this.agents.delete(attemptId),\n emit: (event: string, data: unknown) => this.emit(event as keyof AgentEvents, data as any),\n pendingBashCommands: this.pendingBashCommands,\n };\n }\n\n /**\n * Start a new agent query via the active provider\n */\n async start(options: AgentStartOptions): Promise<void> {\n const { attemptId, projectPath, prompt, sessionOptions, filePaths, outputFormat, outputSchema, maxTurns, model, provider: requestedProvider } = options;\n\n if (this.agents.has(attemptId)) return;\n\n // Build full prompt — resolve @filepath mentions and file attachments\n // into inline file content so they work in stream-json / SDK mode\n let fullPrompt = prompt;\n\n // Collect all file paths: from filePaths param (attachments) and @mentions in prompt\n const allFilePaths: string[] = [];\n if (filePaths && filePaths.length > 0) {\n allFilePaths.push(...filePaths);\n }\n\n // Extract @filepath references from the prompt text (added by buildPromptWithMentions)\n const mentionRegex = /@([\\w.\\/\\\\-]+(?:#L\\d+(?:-\\d+)?)?)/g;\n let mentionMatch;\n const mentionPaths: { fullMatch: string; filePath: string; lineRange?: string }[] = [];\n while ((mentionMatch = mentionRegex.exec(prompt)) !== null) {\n const ref = mentionMatch[1];\n const hashIdx = ref.indexOf('#');\n const filePath = hashIdx >= 0 ? ref.substring(0, hashIdx) : ref;\n const lineRange = hashIdx >= 0 ? ref.substring(hashIdx + 1) : undefined;\n // Skip if it looks like an email or non-path reference\n if (filePath.includes('.') || filePath.includes('/')) {\n mentionPaths.push({ fullMatch: mentionMatch[0], filePath, lineRange });\n }\n }\n\n // Read file contents and build context block\n const fileContextParts: string[] = [];\n const processedPaths = new Set<string>();\n\n // Process file attachment paths\n for (const fp of allFilePaths) {\n const absPath = isAbsolute(fp) ? fp : resolve(projectPath, fp);\n if (processedPaths.has(absPath)) continue;\n processedPaths.add(absPath);\n try {\n const content = await readFile(absPath, 'utf-8');\n fileContextParts.push(`<file path=\"${fp}\">\\n${content}\\n</file>`);\n } catch (err) {\n log.warn({ path: absPath }, 'Could not read attached file, falling back to @reference');\n fileContextParts.push(`@${fp}`);\n }\n }\n\n // Process @mention paths from prompt text\n for (const mention of mentionPaths) {\n const absPath = isAbsolute(mention.filePath) ? mention.filePath : resolve(projectPath, mention.filePath);\n if (processedPaths.has(absPath)) continue;\n processedPaths.add(absPath);\n try {\n let content = await readFile(absPath, 'utf-8');\n // If line range specified, extract those lines\n if (mention.lineRange) {\n const lines = content.split('\\n');\n const rangeMatch = mention.lineRange.match(/^L(\\d+)(?:-(\\d+))?$/);\n if (rangeMatch) {\n const start = Math.max(1, parseInt(rangeMatch[1])) - 1;\n const end = rangeMatch[2] ? parseInt(rangeMatch[2]) : start + 1;\n content = lines.slice(start, end).join('\\n');\n fileContextParts.push(`<file path=\"${mention.filePath}\" lines=\"${mention.lineRange}\">\\n${content}\\n</file>`);\n } else {\n fileContextParts.push(`<file path=\"${mention.filePath}\">\\n${content}\\n</file>`);\n }\n } else {\n fileContextParts.push(`<file path=\"${mention.filePath}\">\\n${content}\\n</file>`);\n }\n } catch {\n // File not found — leave the @reference as-is in the prompt\n log.debug({ path: absPath }, 'Could not read mentioned file, keeping @reference');\n }\n }\n\n // Strip resolved @mentions from prompt text and prepend file context\n if (fileContextParts.length > 0) {\n let cleanedPrompt = prompt;\n // Remove @mentions that were successfully resolved\n for (const mention of mentionPaths) {\n const absPath = isAbsolute(mention.filePath) ? mention.filePath : resolve(projectPath, mention.filePath);\n if (processedPaths.has(absPath)) {\n cleanedPrompt = cleanedPrompt.replace(mention.fullMatch, '').trim();\n }\n }\n fullPrompt = `${fileContextParts.join('\\n\\n')}\\n\\n${cleanedPrompt}`;\n }\n\n const systemPrompt = getSystemPrompt({ prompt, projectPath });\n if (systemPrompt) {\n fullPrompt += `\\n\\n${systemPrompt}`;\n }\n\n if (outputFormat) {\n fullPrompt += buildOutputFormatPrompt(outputFormat, outputSchema, attemptId);\n }\n\n // Build model identity and project context for system prompt\n const effectiveModel = model?.trim() || resolveDefaultModelFromEnv();\n const modelDisplayName = modelIdToDisplayName(effectiveModel);\n const modelIdentity = modelDisplayName !== effectiveModel\n ? `You are powered by the model named ${modelDisplayName}. The exact model ID is ${effectiveModel}.`\n : `You are powered by the model ${effectiveModel}.`;\n const projectContext = `Your current working directory is ${projectPath}. All file operations should use paths relative to or within this directory.`;\n\n // Use per-request provider if specified, otherwise fall back to env-based default\n const provider = requestedProvider ? getProvider(requestedProvider) : getActiveProvider();\n\n // Wire up provider events for this attempt\n wireProviderEvents(this.buildWiringContext(), provider, attemptId, outputFormat, projectPath);\n\n try {\n const session = await provider.start({\n attemptId,\n projectPath,\n prompt: fullPrompt,\n model: effectiveModel,\n sessionOptions,\n maxTurns,\n systemPromptAppend: `${modelIdentity}\\n${projectContext}`,\n outputFormat,\n outputSchema,\n });\n\n const instance: AgentInstance = {\n attemptId,\n session,\n provider,\n startedAt: Date.now(),\n outputFormat,\n };\n\n this.agents.set(attemptId, instance);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n log.error({ attemptId, err: error }, 'Failed to start provider');\n this.emit('stderr', { attemptId, content: errorMessage });\n this.emit('exit', { attemptId, code: 1 });\n }\n }\n\n // --- Public API (identical to original) ---\n\n answerQuestion(attemptId: string, toolUseId: string | undefined, questions: unknown[], answers: Record<string, string>): boolean {\n const instance = this.agents.get(attemptId);\n if (!instance) return false;\n return instance.provider.answerQuestion(attemptId, toolUseId, questions, answers);\n }\n\n cancelQuestion(attemptId: string): boolean {\n const instance = this.agents.get(attemptId);\n if (!instance) return false;\n return instance.provider.cancelQuestion(attemptId);\n }\n\n hasPendingQuestion(attemptId: string): boolean {\n const instance = this.agents.get(attemptId);\n if (!instance) return false;\n return instance.provider.hasPendingQuestion(attemptId);\n }\n\n getPendingQuestionData(attemptId: string): { toolUseId: string; questions: unknown[]; timestamp: number } | null {\n const instance = this.agents.get(attemptId);\n if (!instance) return null;\n return instance.provider.getPendingQuestionData(attemptId);\n }\n\n getAllPendingQuestions(): Array<{ attemptId: string; toolUseId: string; questions: unknown[]; timestamp: number }> {\n const result: Array<{ attemptId: string; toolUseId: string; questions: unknown[]; timestamp: number }> = [];\n for (const [attemptId, instance] of this.agents) {\n const data = instance.provider.getPendingQuestionData(attemptId);\n if (data) result.push({ attemptId, ...data });\n }\n return result;\n }\n\n // Persistent question methods — question data survives agent cleanup\n setPersistentQuestion(taskId: string, data: PersistentQuestionData): void {\n this.persistentQuestionStore.set(taskId, data);\n }\n\n getPersistentQuestion(taskId: string): PersistentQuestionData | null {\n return this.persistentQuestionStore.get(taskId);\n }\n\n clearPersistentQuestion(taskId: string): void {\n this.persistentQuestionStore.clear(taskId);\n }\n\n async sendInput(attemptId: string, _input: string): Promise<boolean> {\n const instance = this.agents.get(attemptId);\n if (!instance || !instance.session.sessionId) return false;\n return false;\n }\n\n async compact(options: { attemptId: string; projectPath: string; conversationSummary?: string; model?: string; provider?: AgentStartOptions['provider'] }): Promise<void> {\n const { attemptId, projectPath, conversationSummary, model, provider } = options;\n const compactPrompt = conversationSummary\n ? `You are continuing a previous conversation that reached the context limit. Here is a summary of the previous context:\\n\\n${conversationSummary}\\n\\nPlease acknowledge this context briefly and let the user know you're ready to continue.`\n : 'A previous conversation reached the context limit. Please let the user know you are ready to continue with a fresh context.';\n\n await this.start({ attemptId, projectPath, prompt: compactPrompt, maxTurns: 1, model, provider });\n }\n\n cancel(attemptId: string): boolean {\n const instance = this.agents.get(attemptId);\n if (!instance) return false;\n\n instance.session.cancel();\n this.agents.delete(attemptId);\n return true;\n }\n\n cancelAll(): void {\n for (const [, instance] of this.agents) {\n instance.session.cancel();\n }\n this.agents.clear();\n }\n\n isRunning(attemptId: string): boolean {\n return this.agents.has(attemptId);\n }\n\n get runningCount(): number {\n return this.agents.size;\n }\n\n getRunningAttempts(): string[] {\n return Array.from(this.agents.keys());\n }\n\n getSessionId(attemptId: string): string | undefined {\n return this.agents.get(attemptId)?.session.sessionId;\n }\n\n // Type-safe event emitter methods\n override on<K extends keyof AgentEvents>(event: K, listener: AgentEvents[K]): this {\n return super.on(event, listener);\n }\n\n override emit<K extends keyof AgentEvents>(event: K, ...args: Parameters<AgentEvents[K]>): boolean {\n return super.emit(event, ...args);\n }\n}\n\n// Export singleton instance (global for cross-module access)\nconst globalKey = '__claude_agent_manager__' as const;\n\ndeclare global {\n var __claude_agent_manager__: AgentManager | undefined;\n}\n\nexport const agentManager: AgentManager =\n (globalThis as any)[globalKey] ?? new AgentManager();\n\nif (!(globalThis as any)[globalKey]) {\n (globalThis as any)[globalKey] = agentManager;\n}\n","/**\n * Minimal System Prompt - Only project-specific rules\n * SDK already provides: Tools, Skills, MCP, Agents documentation\n */\nexport const ENGINEERING_SYSTEM_PROMPT = `\n## BACKGROUND SERVERS - CRITICAL\n- Unless specified otherwise, create files/folders ONLY within the project's path and organize files/folders using the PARA method, also create docs, plans, reports, executions if needed\n- Respond in the same language as the user's prompt, except for CLAUDE.md requirements.\n`.trim();\n\n/**\n * Detect if task involves starting a server\n * Task-specific prompt additions\n */\nconst TASK_HINTS: Record<string, string> = {\n fix: `\\n## MODE: BUG FIX\\nFind root cause FIRST. Grep→Read→Trace→Fix→Test`,\n feature: `\\n## MODE: FEATURE\\nMatch existing patterns. Glob→Read similar→Implement→Test`,\n debug: `\\n## MODE: DEBUG\\nReproduce first. Logs→Grep→Trace→Hypothesize→Test`,\n refactor: `\\n## MODE: REFACTOR\\nPreserve behavior. Read→Grep usages→Small edits→Test EACH`,\n question: `\\n## MODE: QUESTION\\nCite file:line. Grep/Glob→Read→Answer with references`,\n setup: `\\n## MODE: SETUP\\nFollow official docs. Read configs→Check package.json→Verify`,\n server: `\\n## MODE: SERVER`,\n};\n\n/**\n * Detect task type from prompt content\n */\nfunction isServerTask(prompt: string): boolean {\n const lower = prompt.toLowerCase();\n return /run.*(start|dev|server)|start.*(directus|strapi|server)|npm run (dev|start)|npx.*(start|dev)/.test(lower);\n}\n\nexport interface SystemPromptOptions {\n projectPath?: string;\n prompt?: string;\n isResume?: boolean;\n attemptCount?: number;\n outputFormat?: string; // File extension: json, html, md, csv, tsv, txt, xml, etc.\n outputSchema?: string;\n attemptId?: string;\n outputFilePath?: string; // Absolute path to output file (without extension)\n}\n\n/**\n * Get system prompt - only includes BGPID rule for server tasks\n * SDK handles all other documentation (Tools, Skills, MCP, etc.)\n */\nexport function getSystemPrompt(options: SystemPromptOptions | string = {}): string {\n // Support legacy string parameter (projectPath only)\n if (typeof options === 'string') {\n return ENGINEERING_SYSTEM_PROMPT;\n }\n\n const { prompt, outputFormat, outputSchema, attemptId, outputFilePath } = options;\n\n // Base prompt is always included\n let finalPrompt = ENGINEERING_SYSTEM_PROMPT;\n\n // Add output format instructions if specified\n if (outputFormat && attemptId) {\n const formatInstructions = getOutputFormatInstructions(outputFormat, outputSchema, attemptId, outputFilePath);\n finalPrompt += '\\n' + formatInstructions;\n }\n\n // Add server-specific hints if task involves starting a server\n if (prompt && isServerTask(prompt) && TASK_HINTS.server) {\n finalPrompt += '\\n' + TASK_HINTS.server;\n }\n\n return finalPrompt;\n}\n\n/**\n * Get output format instructions for Claude\n */\nfunction getOutputFormatInstructions(\n format: string,\n schema: string | undefined,\n attemptId: string,\n outputFilePath?: string // Absolute path to output file (without extension)\n): string {\n // Use absolute path if provided, otherwise fall back to relative path\n const filePath = outputFilePath || `data/tmp/${attemptId}`;\n\n // Schema provided - include format specification in instructions\n if (schema) {\n return `## OUTPUT FORMAT: ${format.toUpperCase()}\nYou MUST save your work results to a ${format.toUpperCase()} file at \\`${filePath}.${format}\\`.\n\nFormat specification:\n${schema}\n\nCRITICAL: Your task is INCOMPLETE until you:\n1. Write your generated results to the file using the Write tool\n2. Read back the file to verify it matches the format specification\n\nThe file MUST contain your actual work output - not empty, not placeholders.`;\n }\n\n // Generic output format - use the format string as file extension\n // SDK agent understands common formats: csv, tsv, txt, xml, log, etc.\n return `## OUTPUT FORMAT: ${format.toUpperCase()}\nYou MUST save your work results to a ${format.toUpperCase()} file at \\`${filePath}.${format}\\`.\nWrite valid ${format.toUpperCase()} format that follows standard conventions for this file type.\nInclude your work summary, files changed, and results in the file.\n\nCRITICAL: Your task is INCOMPLETE until you:\n1. Write your generated results to the file using the Write tool\n2. Read back the file to verify it is valid ${format.toUpperCase()}\n\nThe file MUST contain your actual work output - not empty, not placeholders.`;\n}\n","/**\n * Claude SDK Provider - Uses @anthropic-ai/claude-agent-sdk query()\n *\n * Orchestrator: delegates MCP loading, model alias resolution, and query\n * option construction to focused sub-modules. Owns session lifecycle,\n * AskUserQuestion promise coordination, and event emission.\n *\n * Sub-modules:\n * - MCP config loader → claude-sdk-mcp-config-loader.ts\n * - Model alias utils → claude-sdk-model-alias-and-server-command-utils.ts\n * - Query opts builder → claude-sdk-query-options-builder.ts\n */\n\nimport { EventEmitter } from 'events';\nimport { query, type Query } from '@anthropic-ai/claude-agent-sdk';\nimport { adaptSDKMessage, isValidSDKMessage, type SDKResultMessage } from '../sdk-event-adapter';\nimport { createLogger } from '../logger';\nimport { loadMCPConfig, getMCPToolWildcards } from './claude-sdk-mcp-config-loader';\nimport { resolveModel } from './claude-sdk-model-alias-and-server-command-utils';\nimport { buildQueryOptions, buildCanUseToolCallback } from './claude-sdk-query-options-builder';\nimport type { Provider, ProviderSession, ProviderStartOptions, ProviderEventData, ProviderId } from './types';\n\nconst log = createLogger('SDKProvider');\n\ninterface PendingQuestion {\n toolUseId: string;\n resolve: (answer: { questions: unknown[]; answers: Record<string, string> } | null) => void;\n}\n\nclass SDKSession implements ProviderSession {\n readonly providerId: ProviderId = 'claude-sdk';\n sessionId: string | undefined;\n outputFormat?: string;\n queryRef?: Query;\n constructor(readonly attemptId: string, readonly controller: AbortController, outputFormat?: string) {\n this.outputFormat = outputFormat;\n }\n cancel(): void {\n if (this.queryRef) { try { this.queryRef.close(); } catch { this.controller.abort(); } }\n else { this.controller.abort(); }\n }\n}\n\nexport class ClaudeSDKProvider extends EventEmitter implements Provider {\n readonly id: ProviderId = 'claude-sdk';\n private sessions = new Map<string, SDKSession>();\n private pendingQuestions = new Map<string, PendingQuestion>();\n private pendingQuestionData = new Map<string, { toolUseId: string; questions: unknown[]; timestamp: number }>();\n\n resolveModel(displayModelId: string): string { return resolveModel(displayModelId); }\n\n async start(options: ProviderStartOptions): Promise<ProviderSession> {\n const { attemptId, projectPath, prompt, sessionOptions, maxTurns, model, systemPromptAppend, outputFormat } = options;\n const controller = new AbortController();\n const session = new SDKSession(attemptId, controller, outputFormat);\n this.sessions.set(attemptId, session);\n this.runQuery(session, projectPath, prompt, sessionOptions, maxTurns, model, systemPromptAppend);\n return session;\n }\n\n private makeCanUseTool(attemptId: string) {\n return buildCanUseToolCallback(\n attemptId,\n () => this.pendingQuestions.has(attemptId),\n (toolUseId, questions) => {\n this.pendingQuestionData.set(attemptId, { toolUseId, questions, timestamp: Date.now() });\n this.emit('question', { attemptId, toolUseId, questions });\n },\n (toolUseId) => new Promise<{ questions: unknown[]; answers: Record<string, string> } | null>(resolve => {\n this.pendingQuestions.set(attemptId, { toolUseId, resolve });\n }).then(answer => {\n this.pendingQuestions.delete(attemptId);\n this.pendingQuestionData.delete(attemptId);\n return answer;\n }),\n );\n }\n\n private async runQuery(\n session: SDKSession, projectPath: string, prompt: string,\n sessionOptions?: { resume?: string; resumeSessionAt?: string },\n maxTurns?: number, model?: string, systemPromptAppend?: string,\n ): Promise<void> {\n const { attemptId, controller } = session;\n try {\n const mcpConfig = loadMCPConfig(projectPath);\n const mcpToolWildcards = mcpConfig?.mcpServers ? getMCPToolWildcards(mcpConfig.mcpServers) : [];\n const effectiveModel = model ? this.resolveModel(model) : 'opus';\n\n const opts = buildQueryOptions({\n projectPath, model: effectiveModel, sessionOptions, maxTurns,\n mcpServers: mcpConfig?.mcpServers, mcpToolWildcards, controller,\n canUseToolCallback: this.makeCanUseTool(attemptId),\n });\n\n log.info({\n endpoint: process.env.ANTHROPIC_BASE_URL || 'https://api.anthropic.com',\n prompt: prompt.substring(0, 200) + (prompt.length > 200 ? '...' : ''),\n model: opts.model, cwd: opts.cwd,\n }, 'SDK Query starting');\n\n const response = query({ prompt, options: opts });\n session.queryRef = response;\n\n for await (const message of response) {\n if (controller.signal.aborted) break;\n try {\n if (!isValidSDKMessage(message)) continue;\n const adapted = adaptSDKMessage(message);\n if (adapted.sessionId) session.sessionId = adapted.sessionId;\n this.emit('message', {\n attemptId, output: adapted.output, sessionId: adapted.sessionId,\n checkpointUuid: adapted.checkpointUuid, backgroundShell: adapted.backgroundShell,\n resultMessage: message.type === 'result' ? message as SDKResultMessage : undefined,\n usageEvent: adapted.usageEvent,\n rawMessage: message,\n });\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'Unknown message error';\n log.error({ err, message: msg }, 'Message processing error');\n if (!msg.includes('Unexpected end of JSON')) this.emit('stderr', { attemptId, content: `Warning: ${msg}` });\n }\n }\n\n this.cleanupPendingQuestions(attemptId);\n this.sessions.delete(attemptId);\n this.emit('complete', { attemptId, sessionId: session.sessionId });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n const errorName = error instanceof Error ? error.name : 'UnknownError';\n const wasResuming = !!sessionOptions?.resume;\n log.error({ err: error, message: errorMessage, attemptId }, 'SDK Error - Query failed');\n if (wasResuming && !controller.signal.aborted) {\n log.warn({ attemptId }, 'Resume failed, retrying without resume');\n this.sessions.set(attemptId, session);\n return this.runQuery(session, projectPath, prompt, undefined, maxTurns, model, systemPromptAppend);\n }\n const isPromptTooLong = errorMessage.toLowerCase().includes('prompt is too long') ||\n errorMessage.toLowerCase().includes('request too large');\n this.cleanupPendingQuestions(attemptId);\n this.sessions.delete(attemptId);\n this.emit('error', { attemptId, error: errorMessage, errorName, isPromptTooLong, wasResuming });\n }\n }\n\n answerQuestion(attemptId: string, toolUseId: string | undefined, questions: unknown[], answers: Record<string, string>): boolean {\n const pending = this.pendingQuestions.get(attemptId);\n if (!pending) return false;\n if (toolUseId && pending.toolUseId !== toolUseId) {\n log.warn({ attemptId, expected: pending.toolUseId, received: toolUseId }, 'Rejecting stale answer');\n return false;\n }\n pending.resolve({ questions, answers });\n this.pendingQuestions.delete(attemptId);\n this.pendingQuestionData.delete(attemptId);\n this.emit('questionResolved', { attemptId });\n return true;\n }\n\n cancelQuestion(attemptId: string): boolean {\n const pending = this.pendingQuestions.get(attemptId);\n if (!pending) return false;\n pending.resolve(null);\n this.pendingQuestions.delete(attemptId);\n this.pendingQuestionData.delete(attemptId);\n this.emit('questionResolved', { attemptId });\n return true;\n }\n\n hasPendingQuestion(attemptId: string): boolean { return this.pendingQuestions.has(attemptId); }\n\n getPendingQuestionData(attemptId: string): { toolUseId: string; questions: unknown[]; timestamp: number } | null {\n return this.pendingQuestionData.get(attemptId) || null;\n }\n\n cancelSession(attemptId: string): boolean {\n const session = this.sessions.get(attemptId);\n if (!session) return false;\n this.cleanupPendingQuestions(attemptId);\n session.cancel();\n this.sessions.delete(attemptId);\n return true;\n }\n\n private cleanupPendingQuestions(attemptId: string): void {\n const pending = this.pendingQuestions.get(attemptId);\n if (pending) { pending.resolve(null); this.pendingQuestions.delete(attemptId); this.pendingQuestionData.delete(attemptId); }\n }\n\n override on<K extends keyof ProviderEventData>(event: K, listener: (data: ProviderEventData[K]) => void): this {\n return super.on(event, listener as (...args: unknown[]) => void);\n }\n\n override emit<K extends keyof ProviderEventData>(event: K, data: ProviderEventData[K]): boolean {\n return super.emit(event, data);\n }\n}\n","/**\n * Claude SDK message-to-output adapter — normalizes SDK stream messages to internal ClaudeOutput format.\n * Handles system, assistant, user, result, and stream_event message types.\n * Detects AskUserQuestion tool use and background shell (run_in_background=true).\n */\n\nimport { createLogger } from '../lib/pino-logger';\nimport type { BackgroundShellInfo } from './agent-start-options-and-event-types';\n\nconst log = createLogger('SDKAdapter');\n\n// --- SDK message types ---\n\nexport interface MCPServerStatus {\n name: string;\n status: 'connected' | 'failed' | 'connecting';\n error?: string;\n tools?: string[];\n}\n\nexport interface SDKSystemMessage {\n type: 'system';\n subtype: 'init' | string;\n session_id?: string;\n tools?: unknown[];\n mcp_servers?: MCPServerStatus[];\n}\n\nexport interface SDKAssistantMessage {\n type: 'assistant';\n message: {\n id?: string;\n role: 'assistant';\n content: SDKContentBlock[];\n model?: string;\n stop_reason?: string;\n usage?: { input_tokens: number; output_tokens: number };\n };\n}\n\nexport interface SDKUserMessage {\n type: 'user';\n message: { role: 'user'; content: SDKContentBlock[] };\n uuid?: string; // Checkpoint UUID (when replay-user-messages enabled)\n}\n\nexport interface SDKResultMessage {\n type: 'result';\n subtype: string;\n session_id?: string;\n cost_usd?: number;\n is_error?: boolean;\n duration_ms?: number;\n num_turns?: number;\n}\n\nexport interface SDKStreamEvent {\n type: 'stream_event';\n event: {\n type: string;\n index?: number;\n delta?: {\n type: 'text_delta' | 'thinking_delta' | 'input_json_delta';\n text?: string;\n thinking?: string;\n };\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n };\n message?: {\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n };\n };\n };\n}\n\nexport interface SDKContentBlock {\n type: 'text' | 'thinking' | 'tool_use' | 'tool_result';\n text?: string;\n thinking?: string;\n id?: string;\n name?: string;\n input?: unknown;\n tool_use_id?: string;\n content?: string | unknown[];\n is_error?: boolean;\n}\n\nexport type SDKMessage =\n | SDKSystemMessage\n | SDKAssistantMessage\n | SDKUserMessage\n | SDKResultMessage\n | SDKStreamEvent\n | { type: string; [key: string]: unknown };\n\nexport interface ClaudeOutput {\n type: string;\n [key: string]: unknown;\n}\n\nexport interface UsageEvent {\n input_tokens: number;\n output_tokens: number;\n cache_read_input_tokens: number;\n cache_creation_input_tokens: number;\n}\n\nexport interface AdaptedMessage {\n output: ClaudeOutput;\n sessionId?: string;\n checkpointUuid?: string;\n askUserQuestion?: { toolUseId: string; questions: unknown[] };\n backgroundShell?: BackgroundShellInfo;\n usageEvent?: UsageEvent;\n}\n\n// --- Type guard ---\n\nexport function isValidSDKMessage(msg: unknown): msg is SDKMessage {\n if (typeof msg !== 'object' || msg === null) return false;\n if (!('type' in msg)) return false;\n return typeof (msg as { type: unknown }).type === 'string';\n}\n\n// --- Internal helpers ---\n\nfunction detectAskUserQuestion(\n content: SDKContentBlock[]\n): { toolUseId: string; questions: unknown[] } | undefined {\n for (const block of content) {\n if (block.type === 'tool_use' && block.name === 'AskUserQuestion') {\n return {\n toolUseId: block.id || '',\n questions: (block.input as { questions?: unknown[] })?.questions || [],\n };\n }\n }\n return undefined;\n}\n\nfunction detectBackgroundShell(content: SDKContentBlock[]): BackgroundShellInfo | undefined {\n // Method 1: Bash tool_use with run_in_background=true\n for (const block of content) {\n if (block.type === 'tool_use' && block.name === 'Bash') {\n const input = block.input as { command?: string; run_in_background?: boolean; description?: string } | undefined;\n if (input?.run_in_background === true && input?.command) {\n log.info({ commandPreview: input.command.substring(0, 50) }, 'Background shell detected via run_in_background=true');\n return { toolUseId: block.id || '', command: input.command, description: input.description };\n }\n }\n }\n // Method 2: Markdown ```background-shell``` code block\n for (const block of content) {\n if (block.type === 'text' && block.text) {\n const match = block.text.match(/```background-shell\\n([\\s\\S]+?)\\n```/);\n if (match) {\n const command = match[1].trim();\n if (command) {\n return { toolUseId: `bg-shell-${Date.now()}`, command, description: 'Background shell from markdown block' };\n }\n }\n }\n }\n return undefined;\n}\n\n// --- Main adapter ---\n\nexport function adaptSDKMessage(message: SDKMessage): AdaptedMessage {\n const result: AdaptedMessage = { output: { type: message.type } };\n\n switch (message.type) {\n case 'system': {\n const sys = message as SDKSystemMessage;\n result.output = { type: 'system', subtype: sys.subtype, session_id: sys.session_id };\n if (sys.subtype === 'init' && sys.session_id) result.sessionId = sys.session_id;\n if (sys.subtype === 'init' && sys.mcp_servers) {\n for (const s of sys.mcp_servers) {\n if (s.status === 'connected') log.info({ name: s.name }, `MCP connected: ${s.name}`);\n else if (s.status === 'failed') log.error({ name: s.name, error: s.error }, `MCP failed: ${s.name}`);\n }\n }\n break;\n }\n case 'assistant': {\n const asst = message as SDKAssistantMessage;\n result.output = {\n type: 'assistant',\n message: { role: 'assistant', content: asst.message.content },\n };\n const askQ = detectAskUserQuestion(asst.message.content);\n if (askQ) result.askUserQuestion = askQ;\n const bgShell = detectBackgroundShell(asst.message.content);\n if (bgShell) result.backgroundShell = bgShell;\n break;\n }\n case 'user': {\n const user = message as SDKUserMessage;\n result.output = { type: 'user', message: { role: 'user', content: user.message.content } };\n if (user.uuid) result.checkpointUuid = user.uuid;\n break;\n }\n case 'result': {\n const res = message as SDKResultMessage;\n result.output = { type: 'result', subtype: res.subtype, session_id: res.session_id, is_error: res.is_error };\n if (res.session_id) result.sessionId = res.session_id;\n break;\n }\n case 'stream_event': {\n const stream = message as SDKStreamEvent;\n const event = stream.event;\n if (event.type === 'content_block_delta' && event.delta) {\n if (event.delta.type === 'text_delta' && event.delta.text) {\n result.output = { type: 'content_block_delta', index: event.index, delta: { type: 'text_delta', text: event.delta.text } };\n } else if (event.delta.type === 'thinking_delta' && event.delta.thinking) {\n result.output = { type: 'content_block_delta', index: event.index, delta: { type: 'thinking_delta', thinking: event.delta.thinking } };\n }\n }\n // Capture usage from message_delta events (per-turn token counts from the API)\n if (event.type === 'message_delta' && event.usage) {\n result.usageEvent = {\n input_tokens: event.usage.input_tokens || 0,\n output_tokens: event.usage.output_tokens || 0,\n cache_read_input_tokens: event.usage.cache_read_input_tokens || 0,\n cache_creation_input_tokens: event.usage.cache_creation_input_tokens || 0,\n };\n }\n // Capture usage from message_start events (initial context size)\n if (event.type === 'message_start' && event.message?.usage) {\n result.usageEvent = {\n input_tokens: event.message.usage.input_tokens || 0,\n output_tokens: event.message.usage.output_tokens || 0,\n cache_read_input_tokens: event.message.usage.cache_read_input_tokens || 0,\n cache_creation_input_tokens: event.message.usage.cache_creation_input_tokens || 0,\n };\n }\n break;\n }\n default:\n result.output = { type: message.type };\n }\n\n return result;\n}\n","/**\n * Re-export from agentic-sdk shared module, with type bridge for claude-ws ClaudeOutput.\n * Consumers import from './sdk-event-adapter' — this shim keeps those imports working.\n */\n\nimport {\n adaptSDKMessage as _adaptSDKMessage,\n type AdaptedMessage as _AdaptedMessage,\n} from '../../packages/agentic-sdk/src/agent/claude-sdk-message-to-output-adapter';\nimport type { ClaudeOutput } from '../types';\n\n// Re-export SDK types directly\nexport type {\n MCPServerStatus,\n SDKSystemMessage,\n SDKAssistantMessage,\n SDKUserMessage,\n SDKResultMessage,\n SDKStreamEvent,\n SDKContentBlock,\n SDKMessage,\n UsageEvent,\n} from '../../packages/agentic-sdk/src/agent/claude-sdk-message-to-output-adapter';\n\nexport { isValidSDKMessage } from '../../packages/agentic-sdk/src/agent/claude-sdk-message-to-output-adapter';\n\n// Re-export BackgroundShellInfo from its canonical location\nexport type { BackgroundShellInfo } from '../../packages/agentic-sdk/src/agent/agent-start-options-and-event-types';\n\n// Bridge AdaptedMessage to use claude-ws's ClaudeOutput type\nexport interface AdaptedMessage extends Omit<_AdaptedMessage, 'output'> {\n output: ClaudeOutput;\n}\n\n/** Wraps agentic-sdk adapter, casting output to claude-ws ClaudeOutput type */\nexport function adaptSDKMessage(message: Parameters<typeof _adaptSDKMessage>[0]): AdaptedMessage {\n return _adaptSDKMessage(message) as unknown as AdaptedMessage;\n}\n","/**\n * MCP Configuration Loader for Claude SDK Provider\n *\n * Loads MCP server configurations from:\n * 1. ~/.claude.json (global + per-project)\n * 2. <projectPath>/.mcp.json (project-local)\n *\n * Merges and interpolates environment variables in server configs.\n */\n\nimport { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport { createLogger } from '../logger';\n\nconst log = createLogger('SDKProvider:MCP');\n\n// --- MCP Configuration Types ---\n\nexport interface MCPStdioServerConfig {\n type?: 'stdio';\n command: string;\n args?: string[];\n env?: Record<string, string>;\n}\n\nexport interface MCPHttpServerConfig {\n type: 'http';\n url: string;\n headers?: Record<string, string>;\n}\n\nexport interface MCPSSEServerConfig {\n type: 'sse';\n url: string;\n headers?: Record<string, string>;\n}\n\nexport type MCPServerConfig = MCPStdioServerConfig | MCPHttpServerConfig | MCPSSEServerConfig;\n\nexport interface MCPConfig {\n mcpServers?: Record<string, MCPServerConfig>;\n}\n\n// --- Loader Functions ---\n\nfunction loadSingleMCPConfig(configPath: string): Record<string, MCPServerConfig> | null {\n if (!existsSync(configPath)) return null;\n\n try {\n const content = readFileSync(configPath, 'utf-8');\n let config = JSON.parse(content) as MCPConfig;\n\n if (!config.mcpServers) {\n const keys = Object.keys(config);\n const looksLikeServers = keys.some(key => {\n const val = (config as Record<string, unknown>)[key];\n return val && typeof val === 'object' && ('command' in val || 'url' in val || 'type' in val);\n });\n if (looksLikeServers) {\n config = { mcpServers: config as unknown as Record<string, MCPServerConfig> };\n }\n }\n\n return config.mcpServers || null;\n } catch (error) {\n log.warn({ err: error, path: configPath }, 'Failed to parse config file');\n return null;\n }\n}\n\nfunction interpolateEnvVars(servers: Record<string, MCPServerConfig>): void {\n for (const [, serverConfig] of Object.entries(servers)) {\n if ('env' in serverConfig && serverConfig.env) {\n for (const [key, value] of Object.entries(serverConfig.env)) {\n if (typeof value === 'string' && value.startsWith('${') && value.endsWith('}')) {\n const envVar = value.slice(2, -1);\n serverConfig.env[key] = process.env[envVar] || '';\n }\n }\n }\n if ('headers' in serverConfig && serverConfig.headers) {\n for (const [key, value] of Object.entries(serverConfig.headers)) {\n if (typeof value === 'string' && value.includes('${')) {\n serverConfig.headers[key] = value.replace(/\\$\\{([^}]+)\\}/g, (_, envVar) => process.env[envVar] || '');\n }\n }\n }\n }\n}\n\n/**\n * Load and merge MCP server configs from global ~/.claude.json and project .mcp.json.\n * Returns null if no servers are found.\n */\nexport function loadMCPConfig(projectPath: string): MCPConfig | null {\n const claudeConfigPath = join(homedir(), '.claude.json');\n const projectConfigPath = join(projectPath, '.mcp.json');\n let userServers: Record<string, MCPServerConfig> | null = null;\n\n if (existsSync(claudeConfigPath)) {\n try {\n const content = readFileSync(claudeConfigPath, 'utf-8');\n const config = JSON.parse(content);\n\n if (config.mcpServers && typeof config.mcpServers === 'object' && Object.keys(config.mcpServers).length > 0) {\n userServers = config.mcpServers as Record<string, MCPServerConfig>;\n log.info({ servers: Object.keys(userServers || {}), path: claudeConfigPath }, 'Loaded global MCP config');\n }\n\n if (config.projects && config.projects[projectPath]?.mcpServers) {\n const projectServers = config.projects[projectPath].mcpServers as Record<string, MCPServerConfig>;\n if (Object.keys(projectServers).length > 0) {\n userServers = { ...(userServers || {}), ...projectServers };\n log.info({ servers: Object.keys(projectServers), projectPath }, 'Loaded CLI project MCP config');\n }\n }\n } catch (error) {\n log.warn({ err: error, path: claudeConfigPath }, 'Failed to parse config file');\n }\n }\n\n const projectServers = loadSingleMCPConfig(projectConfigPath);\n if (projectServers) {\n log.info({ servers: Object.keys(projectServers), path: projectConfigPath }, 'Loaded project MCP config');\n }\n\n const mergedServers: Record<string, MCPServerConfig> = {\n ...(userServers || {}),\n ...(projectServers || {}),\n };\n\n if (Object.keys(mergedServers).length === 0) {\n log.info('No MCP servers found in user or project config');\n return null;\n }\n\n interpolateEnvVars(mergedServers);\n log.info({ servers: Object.keys(mergedServers) }, 'Merged MCP servers');\n return { mcpServers: mergedServers };\n}\n\n/**\n * Derive tool wildcard patterns from MCP server names.\n * e.g. serverName \"playwright\" → \"mcp__playwright__*\"\n */\nexport function getMCPToolWildcards(mcpServers: Record<string, MCPServerConfig>): string[] {\n return Object.keys(mcpServers).map(serverName => `mcp__${serverName}__*`);\n}\n","/**\n * Model Alias Mapper and Server Command Detector for Claude SDK Provider\n *\n * - MODEL_ALIAS_MAP: maps full model IDs to short SDK aliases (opus, sonnet, haiku)\n * - resolveModel: translates a display model ID to the SDK-expected alias\n * - isServerCommand: detects long-running server commands that need BGPID fix\n */\n\n// --- Model Alias Mapping ---\n\nconst MODEL_ALIAS_MAP: Record<string, string> = {\n 'claude-opus-4-6': 'opus',\n 'claude-sonnet-4-5-20250929': 'sonnet',\n 'claude-haiku-4-5-20251001': 'haiku',\n 'claude-3-5-sonnet-20241022': 'sonnet',\n};\n\n/**\n * Translate a full display model ID to its SDK short alias.\n * Falls back to the original ID if no mapping exists.\n */\nexport function resolveModel(displayModelId: string): string {\n return MODEL_ALIAS_MAP[displayModelId] || displayModelId;\n}\n\n// --- Server Command Detection ---\n\nconst SERVER_PATTERNS = [\n /npm\\s+run\\s+(dev|start|serve)/i,\n /yarn\\s+(dev|start|serve)/i,\n /pnpm\\s+(dev|start|serve)/i,\n /npx\\s+(directus|strapi|next|vite|nuxt)/i,\n /nohup\\s+/i,\n];\n\n/**\n * Detect whether a Bash command launches a long-running server process\n * that requires the BGPID background PID fix.\n */\nexport function isServerCommand(command: string): boolean {\n return SERVER_PATTERNS.some(p => p.test(command));\n}\n","/**\n * Query Options Builder for Claude SDK Provider\n *\n * Constructs the full options object passed to the SDK query() call, including:\n * - allowed tools list (built-ins + MCP wildcards)\n * - session resume/resumeSessionAt passthrough\n * - checkpoint options\n * - canUseTool callback factory (AskUserQuestion gate + Bash BGPID fix)\n * - subprocess environment (strips proxy/session detection vars)\n * - system prompt preset\n * - Windows claude.exe path resolution\n */\n\nimport { mkdirSync } from 'fs';\nimport { resolve } from 'path';\nimport { checkpointManager } from '../checkpoint-manager';\nimport { findClaudePath } from '../cli-query';\nimport { createLogger } from '../logger';\nimport { isServerCommand } from './claude-sdk-model-alias-and-server-command-utils';\nimport type { MCPServerConfig } from './claude-sdk-mcp-config-loader';\n\nconst log = createLogger('SDKProvider:QueryBuilder');\n\nexport interface AskUserQuestionAnswer {\n questions: unknown[];\n answers: Record<string, string>;\n}\n\nexport type CanUseToolCallback = (toolName: string, input: Record<string, unknown>) => Promise<\n | { behavior: 'allow'; updatedInput: Record<string, unknown> }\n | { behavior: 'deny'; message: string }\n>;\n\nexport interface QueryOptionsBuilderParams {\n projectPath: string;\n model: string;\n sessionOptions?: { resume?: string; resumeSessionAt?: string };\n maxTurns?: number;\n systemPromptAppend?: string;\n mcpServers?: Record<string, MCPServerConfig>;\n mcpToolWildcards: string[];\n controller: AbortController;\n canUseToolCallback: CanUseToolCallback;\n}\n\n/**\n * Build the options object for SDK query(), minus prompt.\n */\nexport function buildQueryOptions(params: QueryOptionsBuilderParams) {\n const {\n projectPath, model, sessionOptions, maxTurns,\n mcpServers, mcpToolWildcards, controller, canUseToolCallback,\n } = params;\n\n const checkpointOptions = checkpointManager.getCheckpointingOptions();\n\n // Resolve Claude CLI executable path (all platforms)\n const resolvedClaudePath = findClaudePath();\n if (!resolvedClaudePath) {\n log.warn('Claude Code CLI not found. Install it (npm install -g @anthropic-ai/claude-code) or set CLAUDE_PATH for best reliability.');\n }\n\n // Match query options shape from 964deb6 for performance — minimal env override only\n const queryOptions = {\n cwd: projectPath,\n model,\n permissionMode: 'bypassPermissions' as const,\n ...(mcpServers ? { mcpServers } : {}),\n allowedTools: [\n 'Skill', 'Task',\n 'Read', 'Write', 'Edit', 'NotebookEdit',\n 'Bash', 'Grep', 'Glob',\n 'WebFetch', 'WebSearch',\n 'TodoWrite', 'AskUserQuestion',\n ...mcpToolWildcards,\n ],\n ...(sessionOptions?.resume ? { resume: sessionOptions.resume } : {}),\n ...(sessionOptions?.resumeSessionAt ? { resumeSessionAt: sessionOptions.resumeSessionAt } : {}),\n ...checkpointOptions,\n ...(maxTurns ? { maxTurns } : {}),\n abortController: controller,\n canUseTool: canUseToolCallback,\n ...(resolvedClaudePath ? { pathToClaudeCodeExecutable: resolvedClaudePath } : {}),\n // Build isolated env: strip Claude Code session/auth vars so the SDK subprocess\n // doesn't inherit remote MCP servers, login state, or nested session detection.\n // Only pass through vars needed for LLM API calls and basic operation.\n env: buildIsolatedSubprocessEnv(model),\n };\n\n log.debug({ model, cwd: projectPath, mcpCount: mcpToolWildcards.length }, 'Query options built');\n return queryOptions;\n}\n\n/**\n * Build the canUseTool callback that:\n * 1. Gates AskUserQuestion via a promise resolved by answerQuestion()\n * 2. Injects BGPID capture for server Bash commands\n */\nexport function buildCanUseToolCallback(\n attemptId: string,\n hasPending: () => boolean,\n registerQuestion: (toolUseId: string, questions: unknown[]) => void,\n waitForAnswer: (toolUseId: string) => Promise<AskUserQuestionAnswer | null>,\n): CanUseToolCallback {\n return async (toolName: string, input: Record<string, unknown>) => {\n log.debug({ toolName, attemptId }, 'canUseTool called');\n\n if (toolName === 'AskUserQuestion') {\n if (hasPending()) {\n return { behavior: 'deny', message: 'Duplicate question' };\n }\n const toolUseId = `ask-${Date.now()}`;\n const questions = (input.questions as unknown[]) || [];\n registerQuestion(toolUseId, questions);\n\n const answer = await waitForAnswer(toolUseId);\n\n if (!answer || Object.keys(answer.answers).length === 0) {\n return { behavior: 'deny', message: 'User cancelled' };\n }\n return { behavior: 'allow', updatedInput: answer as unknown as Record<string, unknown> };\n }\n\n // Bash BGPID fix — intercept server commands missing background PID capture\n if (toolName === 'Bash') {\n const command = input.command as string | undefined;\n if (command && isServerCommand(command) && !command.includes('echo \"BGPID:$!\"')) {\n if (/>\\s*\\/tmp\\/[^\\s]+\\.log\\s*$/.test(command)) {\n const fixedCommand = command.trim() + ' 2>&1 & echo \"BGPID:$!\"';\n log.debug({ fixedCommand }, 'Fixed BGPID pattern');\n return { behavior: 'allow', updatedInput: { ...input, command: fixedCommand } };\n }\n }\n }\n\n return { behavior: 'allow', updatedInput: input };\n };\n}\n\n// ─── Isolated Subprocess Environment ─────────────────────────────────────────\n\n/**\n * Vars to strip from subprocess env to prevent the SDK CLI from:\n * - Detecting a nested Claude Code session (CLAUDECODE)\n * - Inheriting Claude Code entrypoint metadata\n * - Loading remote MCP servers via claude.ai auth tokens\n * - Picking up ClaudeKit plugin state\n */\nconst STRIPPED_ENV_PREFIXES = [\n 'CLAUDECODE', // nested session detection\n 'CLAUDE_CODE_ENTRYPOINT', // entrypoint metadata\n 'CK_', // ClaudeKit plugin vars\n];\n\n/**\n * Build a clean env for the SDK subprocess.\n * Keeps all system/LLM vars, strips session/auth/plugin vars,\n * and redirects CLAUDE_CONFIG_DIR to an isolated empty dir\n * so the CLI can't fetch remote MCP servers from claude.ai.\n */\nfunction buildIsolatedSubprocessEnv(model: string): Record<string, string | undefined> {\n const env: Record<string, string | undefined> = {};\n\n for (const [key, value] of Object.entries(process.env)) {\n // Skip vars that leak session state or plugin config\n if (STRIPPED_ENV_PREFIXES.some(prefix => key.startsWith(prefix))) continue;\n env[key] = value;\n }\n\n // Override model for the subprocess\n env.ANTHROPIC_MODEL = model;\n\n // Point CLI config to an isolated dir so it has no auth tokens\n // and cannot fetch remote MCP servers from claude.ai\n // Must be absolute so SDK subprocess (cwd=projectPath) resolves the same location\n const isolatedConfigDir = resolve(\n process.env.DATA_DIR || './data',\n 'claude-sdk-isolated-config'\n );\n try { mkdirSync(isolatedConfigDir, { recursive: true }); } catch { /* exists */ }\n env.CLAUDE_CONFIG_DIR = isolatedConfigDir;\n\n return env;\n}\n","/**\n * CLI Session and Pending Question Types for Claude CLI Provider\n *\n * CLISession wraps a spawned Claude CLI child process and tracks:\n * - the child process reference for stdin writes and kill signals\n * - the current pending AskUserQuestion (toolUseId, questions, timestamp)\n *\n * PendingQuestion holds the data needed to answer or cancel an in-flight\n * AskUserQuestion intercepted from CLI stdout.\n */\n\nimport { type ChildProcess } from 'child_process';\nimport type { ProviderId, ProviderSession } from './types';\n\n// --- Pending Question ---\n\nexport interface PendingQuestion {\n toolUseId: string;\n questions: unknown[];\n timestamp: number;\n}\n\n// --- CLI Session ---\n\nexport class CLISession implements ProviderSession {\n readonly providerId: ProviderId = 'claude-cli';\n sessionId: string | undefined;\n outputFormat?: string;\n child: ChildProcess;\n activeBackgroundAgents: number = 0;\n /** Timer ref for background agent wait polling — cleared on cancel */\n backgroundWaitTimer: ReturnType<typeof setInterval> | null = null;\n /** True when AskUserQuestion popup is shown but user hasn't answered yet — delays stdin close */\n waitingForUserAnswer = false;\n private pendingQuestion: PendingQuestion | null = null;\n\n constructor(\n readonly attemptId: string,\n child: ChildProcess,\n outputFormat?: string,\n ) {\n this.child = child;\n this.outputFormat = outputFormat;\n }\n\n setPendingQuestion(q: PendingQuestion | null): void {\n this.pendingQuestion = q;\n }\n\n getPendingQuestion(): PendingQuestion | null {\n return this.pendingQuestion;\n }\n\n /**\n * Write a tool_result answer to the CLI process stdin.\n * Returns false if stdin is unavailable or already destroyed.\n */\n writeToolResult(toolUseId: string, content: string): boolean {\n if (!this.child.stdin || this.child.stdin.destroyed) return false;\n const msg = JSON.stringify({\n type: 'user',\n message: {\n role: 'user',\n content: [{ type: 'tool_result', tool_use_id: toolUseId, content }],\n },\n });\n return this.child.stdin.write(msg + '\\n');\n }\n\n /**\n * Write a follow-up text message to the CLI process stdin.\n * Used to send AskUserQuestion answers as a \"Chat about this\" message.\n * Returns false if stdin is unavailable or already destroyed.\n */\n writeUserMessage(text: string): boolean {\n if (!this.child.stdin || this.child.stdin.destroyed) return false;\n const msg = JSON.stringify({\n type: 'user',\n message: {\n role: 'user',\n content: [{ type: 'text', text }],\n },\n });\n return this.child.stdin.write(msg + '\\n');\n }\n\n cancel(): void {\n if (this.backgroundWaitTimer) {\n clearInterval(this.backgroundWaitTimer);\n this.backgroundWaitTimer = null;\n }\n if (this.child && !this.child.killed) {\n this.child.kill('SIGTERM');\n setTimeout(() => {\n if (this.child && !this.child.killed) {\n this.child.kill('SIGKILL');\n }\n }, 3000);\n }\n }\n}\n","/**\n * CLI Process Spawner for Claude CLI Provider\n *\n * Builds the argument list and spawns the Claude CLI child process\n * with the correct stdio, env, and working directory configuration.\n * Extracted from ClaudeCLIProvider.start() to reduce that method's size.\n */\n\nimport { spawn, type ChildProcess } from 'child_process';\nimport { createLogger } from '../logger';\n\nconst log = createLogger('CLIProvider:Spawner');\n\nexport interface SpawnCLIOptions {\n claudePath: string;\n projectPath: string;\n model?: string;\n sessionResume?: string;\n maxTurns?: number;\n systemPromptAppend?: string;\n attemptId: string;\n}\n\n/**\n * Spawn the Claude CLI child process with stream-json I/O.\n * Returns the ChildProcess ready for stdin writes and stdout/stderr listeners.\n */\nexport function spawnCLIProcess(opts: SpawnCLIOptions): ChildProcess {\n const { claudePath, projectPath, model, sessionResume, maxTurns, systemPromptAppend, attemptId } = opts;\n\n const args: string[] = [\n '--input-format', 'stream-json',\n '--output-format', 'stream-json',\n '--verbose',\n '--permission-mode', 'bypassPermissions',\n ];\n\n if (model) args.push('--model', model);\n if (sessionResume) args.push('--resume', sessionResume);\n if (maxTurns) args.push('--max-turns', String(maxTurns));\n if (systemPromptAppend) args.push('--append-system-prompt', systemPromptAppend);\n\n // Normalize path for Windows\n const normalizedProjectPath = process.platform === 'win32'\n ? projectPath.replace(/\\//g, '\\\\')\n : projectPath;\n\n log.info({ claudePath, argsCount: args.length, attemptId }, 'Spawning CLI process');\n\n // Strip SDK-specific env vars so CLI uses its own auth, not the custom endpoint\n const { ANTHROPIC_AUTH_TOKEN, ANTHROPIC_BASE_URL, ...cleanEnv } = process.env;\n\n return spawn(claudePath, args, {\n cwd: normalizedProjectPath,\n stdio: ['pipe', 'pipe', 'pipe'],\n env: {\n ...cleanEnv,\n FORCE_COLOR: '0',\n NO_COLOR: '1',\n TERM: 'dumb',\n PATH: process.platform === 'win32'\n ? (process.env.PATH || '').split(';').filter(p => {\n const lp = p.toLowerCase().trim().replace(/\\//g, '\\\\');\n return !lp.startsWith('c:\\\\windows') &&\n !lp.startsWith('c:\\\\program files (x86)\\\\windows kits');\n }).join(';')\n : `${process.env.PATH}:/opt/homebrew/bin:/usr/local/bin`,\n },\n });\n}\n\n/**\n * Write the initial user prompt to the child process stdin as a stream-json message.\n */\nexport function sendInitialPrompt(child: ChildProcess, prompt: string): void {\n const msg = JSON.stringify({\n type: 'user',\n message: { role: 'user', content: [{ type: 'text', text: prompt }] },\n });\n child.stdin?.write(msg + '\\n');\n}\n","/**\n * CLI Stdout Line Parser for Claude CLI Provider\n *\n * Parses a single newline-delimited JSON line from the CLI stdout stream,\n * adapts it via sdk-event-adapter, and returns a structured result that\n * the provider can act on (emit events, update session state, close stdin).\n *\n * Separated from the provider class to keep processMessage logic testable\n * and to reduce the provider file size.\n */\n\nimport { adaptSDKMessage, isValidSDKMessage, type SDKResultMessage } from '../sdk-event-adapter';\nimport { createLogger } from '../logger';\nimport type { CLISession } from './claude-cli-session-and-pending-question-types';\n\nconst log = createLogger('CLIProvider:Parser');\n\nexport interface ParsedCLILine {\n /** Adapted output + metadata ready to emit as a 'message' event */\n messagePayload: {\n output: ReturnType<typeof adaptSDKMessage>['output'];\n sessionId?: string;\n checkpointUuid?: string;\n backgroundShell?: ReturnType<typeof adaptSDKMessage>['backgroundShell'];\n resultMessage?: SDKResultMessage;\n rawMessage: unknown;\n };\n /** Set when an AskUserQuestion tool-use was detected */\n askUserQuestion?: { toolUseId: string; questions: unknown[] };\n /** True when the CLI auto-handled a pending AskUserQuestion via tool_result */\n cliAutoHandledQuestion: boolean;\n /** True when this is a result message — caller should close stdin */\n isResultMessage: boolean;\n}\n\n/**\n * Parse one line of CLI stdout output.\n * Returns null if the line is not valid JSON or not a recognised SDK message.\n */\nexport function parseCLILine(line: string, session: CLISession): ParsedCLILine | null {\n let message: unknown;\n try {\n message = JSON.parse(line);\n } catch {\n log.trace({ line: line.substring(0, 100) }, 'Non-JSON line');\n return null;\n }\n\n const { attemptId } = session;\n log.debug({ type: (message as Record<string, unknown>)?.type, attemptId }, 'CLI message received');\n\n if (!isValidSDKMessage(message)) {\n log.debug({ type: (message as Record<string, unknown>)?.type }, 'Invalid message skipped');\n return null;\n }\n\n const adapted = adaptSDKMessage(message);\n\n // Detect AskUserQuestion tool-use in assistant message\n let askUserQuestion: ParsedCLILine['askUserQuestion'];\n if (adapted.askUserQuestion) {\n askUserQuestion = adapted.askUserQuestion;\n }\n\n // Detect CLI auto-handling AskUserQuestion via a user/tool_result message\n let cliAutoHandledQuestion = false;\n if (\n (message as Record<string, unknown>).type === 'user' &&\n session.getPendingQuestion()\n ) {\n const rawContent = (message as { message?: { content?: Array<{ type: string; tool_use_id?: string }> } })\n .message?.content || [];\n const pending = session.getPendingQuestion();\n for (const block of rawContent) {\n if (\n block.type === 'tool_result' &&\n block.tool_use_id &&\n pending &&\n block.tool_use_id === pending.toolUseId\n ) {\n log.info(\n { attemptId, toolUseId: block.tool_use_id },\n 'CLI auto-handled AskUserQuestion, clearing pending (answer will use auto-retry flow)',\n );\n cliAutoHandledQuestion = true;\n break;\n }\n }\n }\n\n const isResultMessage = (message as Record<string, unknown>).type === 'result';\n\n return {\n messagePayload: {\n output: adapted.output,\n sessionId: adapted.sessionId,\n checkpointUuid: adapted.checkpointUuid,\n backgroundShell: adapted.backgroundShell,\n resultMessage: isResultMessage ? (message as SDKResultMessage) : undefined,\n rawMessage: message,\n },\n askUserQuestion,\n cliAutoHandledQuestion,\n isResultMessage,\n };\n}\n","/**\n * Claude CLI Provider - Spawns Claude CLI with stream-json protocol\n *\n * Orchestrator: delegates process spawning and stdout parsing to focused\n * sub-modules. Owns session lifecycle, AskUserQuestion coordination,\n * and event emission.\n *\n * Sub-modules:\n * - CLISession / PendingQuestion → claude-cli-session-and-pending-question-types.ts\n * - Process spawner → claude-cli-process-spawner.ts\n * - Stdout line parser → claude-cli-stdout-line-to-provider-event-parser.ts\n */\n\nimport { EventEmitter } from 'events';\nimport { findClaudePath } from '../cli-query';\nimport { createLogger } from '../logger';\nimport { CLISession } from './claude-cli-session-and-pending-question-types';\nimport { spawnCLIProcess, sendInitialPrompt } from './claude-cli-process-spawner';\nimport { parseCLILine } from './claude-cli-stdout-line-to-provider-event-parser';\nimport type { Provider, ProviderSession, ProviderStartOptions, ProviderEventData, ProviderId } from './types';\n\nconst log = createLogger('CLIProvider');\n\nexport class ClaudeCLIProvider extends EventEmitter implements Provider {\n readonly id: ProviderId = 'claude-cli';\n\n private sessions = new Map<string, CLISession>();\n\n resolveModel(displayModelId: string): string {\n return displayModelId; // CLI accepts full model IDs directly\n }\n\n async start(options: ProviderStartOptions): Promise<ProviderSession> {\n const { attemptId, projectPath, prompt, sessionOptions, maxTurns, model, systemPromptAppend, outputFormat } = options;\n\n const claudePath = findClaudePath();\n if (!claudePath) {\n const error = 'Claude CLI not found. Set CLAUDE_PATH in your .env file.';\n this.emit('error', { attemptId, error, errorName: 'CLINotFound' });\n throw new Error(error);\n }\n\n const child = spawnCLIProcess({\n claudePath, projectPath, model, attemptId,\n sessionResume: sessionOptions?.resume,\n maxTurns, systemPromptAppend,\n });\n\n const session = new CLISession(attemptId, child, outputFormat);\n this.sessions.set(attemptId, session);\n sendInitialPrompt(child, prompt);\n\n let buffer = '';\n\n child.stdout?.on('data', (chunk: Buffer) => {\n buffer += chunk.toString();\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n for (const line of lines) {\n if (line.trim()) this.processLine(session, line);\n }\n });\n\n child.stderr?.on('data', (chunk: Buffer) => {\n const content = chunk.toString();\n log.debug({ attemptId, content: content.substring(0, 200) }, 'stderr received');\n this.emit('stderr', { attemptId, content });\n });\n\n child.on('error', (err) => {\n log.error({ attemptId, err }, 'Process error');\n this.sessions.delete(attemptId);\n this.emit('error', { attemptId, error: err.message, errorName: err.name });\n });\n\n child.on('exit', (code) => {\n log.info({ attemptId, code }, 'Process exited');\n if (buffer.trim()) this.processLine(session, buffer);\n this.sessions.delete(attemptId);\n this.emit('complete', { attemptId, sessionId: session.sessionId });\n });\n\n return session;\n }\n\n private processLine(session: CLISession, line: string): void {\n const { attemptId } = session;\n const parsed = parseCLILine(line, session);\n if (!parsed) return;\n\n if (parsed.messagePayload.sessionId) session.sessionId = parsed.messagePayload.sessionId;\n\n if (parsed.askUserQuestion) {\n const { toolUseId, questions } = parsed.askUserQuestion;\n session.setPendingQuestion({ toolUseId, questions, timestamp: Date.now() });\n session.waitingForUserAnswer = true; // keep stdin open until user answers\n this.emit('question', { attemptId, toolUseId, questions });\n }\n\n // CLI auto-handled AskUserQuestion — clear pending, user's answer will\n // be sent as a follow-up text message via stdin (\"chat about this\" approach)\n if (parsed.cliAutoHandledQuestion) {\n session.setPendingQuestion(null);\n // Strip is_error from auto-handled response so the tool block doesn't show red\n const output = parsed.messagePayload.output as unknown as Record<string, unknown>;\n const msg = output?.message as { content?: Array<{ type: string; is_error?: boolean }> };\n if (msg?.content) {\n for (const block of msg.content) {\n if (block.type === 'tool_result' && block.is_error) {\n delete block.is_error;\n }\n }\n }\n }\n\n this.emit('message', { attemptId, ...parsed.messagePayload });\n\n // Track active background agents from system events\n const rawMessage = parsed.messagePayload.rawMessage as Record<string, unknown>;\n if (rawMessage.type === 'system' && (rawMessage as { subtype?: string }).subtype === 'task_started') {\n session.activeBackgroundAgents = (session.activeBackgroundAgents || 0) + 1;\n log.info({ attemptId, active: session.activeBackgroundAgents }, 'Background agent started');\n }\n if (rawMessage.type === 'system' && (rawMessage as { subtype?: string }).subtype === 'task_notification') {\n session.activeBackgroundAgents = Math.max(0, (session.activeBackgroundAgents || 0) - 1);\n log.info({ attemptId, active: session.activeBackgroundAgents }, 'Background agent notification received');\n }\n\n // Close stdin on result message so CLI process can exit naturally\n if (parsed.isResultMessage) {\n // Don't close stdin if user hasn't answered AskUserQuestion popup yet —\n // keep the session alive so their answer can be sent as a follow-up message\n if (session.waitingForUserAnswer) {\n log.info({ attemptId }, 'Result received but waiting for user answer — keeping stdin open');\n return;\n }\n\n const activeAgents = session.activeBackgroundAgents || 0;\n if (activeAgents > 0) {\n log.info({ attemptId, activeAgents }, 'Result received but background agents still active, delaying stdin close');\n const maxWait = 60000;\n const checkInterval = 2000;\n let waited = 0;\n session.backgroundWaitTimer = setInterval(() => {\n waited += checkInterval;\n const remaining = session.activeBackgroundAgents || 0;\n if (remaining <= 0 || waited >= maxWait) {\n if (session.backgroundWaitTimer) {\n clearInterval(session.backgroundWaitTimer);\n session.backgroundWaitTimer = null;\n }\n log.info({ attemptId, waited, remaining }, 'Closing stdin (background agents done or timeout)');\n session.child.stdin?.end();\n }\n }, checkInterval);\n } else {\n log.info({ attemptId }, 'Result message received, closing stdin');\n session.child.stdin?.end();\n }\n }\n }\n\n answerQuestion(attemptId: string, _toolUseId: string | undefined, _questions: unknown[], answers: Record<string, string>): boolean {\n const session = this.sessions.get(attemptId);\n if (!session) { log.warn({ attemptId }, 'answerQuestion: session not found'); return false; }\n\n // CLI auto-handles AskUserQuestion internally, so we can't inject a tool_result.\n // Instead, send user's answers as a follow-up text message via stdin\n // (equivalent to \"Chat about this\" in CLI interactive mode).\n const answerText = Object.entries(answers)\n .map(([q, a]) => `Q: ${q}\\nA: ${a}`)\n .join('\\n\\n');\n const prompt = `The user answered the previous question:\\n${answerText}\\n\\nPlease continue based on these answers.`;\n\n const success = session.writeUserMessage(prompt);\n if (success) {\n log.info({ attemptId }, 'Answer sent to CLI as follow-up message via stdin');\n session.waitingForUserAnswer = false; // allow stdin close on next result\n session.setPendingQuestion(null);\n this.emit('questionResolved', { attemptId });\n } else {\n log.error({ attemptId }, 'Failed to write answer to CLI stdin (process may have exited)');\n }\n return success;\n }\n\n cancelQuestion(attemptId: string): boolean {\n const session = this.sessions.get(attemptId);\n if (!session) return false;\n const pending = session.getPendingQuestion();\n if (!pending) return false;\n const success = session.writeToolResult(pending.toolUseId, 'User cancelled');\n if (success) {\n session.setPendingQuestion(null);\n this.emit('questionResolved', { attemptId });\n }\n return success;\n }\n\n hasPendingQuestion(attemptId: string): boolean {\n return !!this.sessions.get(attemptId)?.getPendingQuestion();\n }\n\n getPendingQuestionData(attemptId: string): { toolUseId: string; questions: unknown[]; timestamp: number } | null {\n return this.sessions.get(attemptId)?.getPendingQuestion() || null;\n }\n\n cancelSession(attemptId: string): boolean {\n const session = this.sessions.get(attemptId);\n if (!session) return false;\n session.cancel();\n this.sessions.delete(attemptId);\n return true;\n }\n\n override on<K extends keyof ProviderEventData>(event: K, listener: (data: ProviderEventData[K]) => void): this {\n return super.on(event, listener as (...args: unknown[]) => void);\n }\n\n override emit<K extends keyof ProviderEventData>(event: K, data: ProviderEventData[K]): boolean {\n return super.emit(event, data);\n }\n}\n","/**\n * Provider Registry — Factory for Claude providers\n */\n\nimport type { Provider, ProviderId } from './types';\nimport { ClaudeSDKProvider } from './claude-sdk-provider';\nimport { ClaudeCLIProvider } from './claude-cli-provider';\n\nexport type { Provider, ProviderId, ProviderSession, ProviderStartOptions, ProviderEventData } from './types';\n\nconst providers = new Map<ProviderId, Provider>();\n\nfunction getOrCreate(id: ProviderId): Provider {\n if (!providers.has(id)) {\n switch (id) {\n case 'claude-sdk':\n providers.set(id, new ClaudeSDKProvider());\n break;\n case 'claude-cli':\n providers.set(id, new ClaudeCLIProvider());\n break;\n default:\n throw new Error(`Unknown provider: ${id}`);\n }\n }\n return providers.get(id)!;\n}\n\n/**\n * Get the active provider based on CLAUDE_PROVIDER env var.\n * Default: 'claude-sdk'\n */\nexport function getActiveProvider(): Provider {\n const envProvider = process.env.CLAUDE_PROVIDER;\n const id: ProviderId = envProvider === 'cli' ? 'claude-cli' : 'claude-sdk';\n return getOrCreate(id);\n}\n\n/**\n * Get a specific provider by ID\n */\nexport function getProvider(id: ProviderId): Provider {\n return getOrCreate(id);\n}\n","/**\n * Agent Output Handler - Output format prompt building and file reading\n *\n * Extracted from agent-manager.ts. Handles output format instructions\n * that get appended to prompts, and reading custom output files after completion.\n */\n\nimport { resolve } from 'path';\nimport { createLogger } from './logger';\n\nconst log = createLogger('AgentOutputHandler');\n\n/**\n * Check if command is a server/dev command that should run in background\n */\nexport function isServerCommand(command: string): boolean {\n const patterns = [\n /npm\\s+run\\s+(dev|start|serve)/i,\n /yarn\\s+(dev|start|serve)/i,\n /pnpm\\s+(dev|start|serve)/i,\n /npx\\s+(directus|strapi|next|vite|nuxt)/i,\n /nohup\\s+/i,\n ];\n return patterns.some(p => p.test(command));\n}\n\n/**\n * Build output format instructions to append to prompt\n */\nexport function buildOutputFormatPrompt(outputFormat: string, outputSchema?: string, attemptId?: string): string {\n const dataDir = process.env.DATA_DIR || process.cwd();\n const outputFilePath = resolve(dataDir, 'tmp', attemptId || 'unknown');\n\n const example = getOutputFormatExample(outputFormat);\n\n let prompt = `\\n\\n=== REQUIRED OUTPUT ===\\nYou MUST write your WORK RESULTS to a ${outputFormat.toUpperCase()} file at: ${outputFilePath}.${outputFormat}`;\n if (outputSchema) prompt += `\\n\\nFormat:\\n${outputSchema}`;\n prompt += `\\n\\nCRITICAL INSTRUCTIONS:\n1. Use Write tool with PARAMETER 1 (file path) and PARAMETER 2 (your content)\n2. DO NOT wrap content in metadata like {\"file_path\": ..., \"content\": ...}\n3. The file should contain ONLY the actual ${outputFormat.toUpperCase()} data\n4. MANDATORY: After writing, you MUST use Read tool to verify the file was written correctly\n5. If the file content is invalid, fix it and rewrite\n\n${example}\n\nYour task is INCOMPLETE until:\\n1. File exists with valid content\\n2. You have Read it back to verify\\n========================`;\n\n return prompt;\n}\n\n/**\n * Get format-specific example text for output instructions\n */\nfunction getOutputFormatExample(outputFormat: string): string {\n switch (outputFormat.toLowerCase()) {\n case 'json': return `Example: Write:\\n[\"Max\", \"Bella\", \"Charlie\"]\\n\\nNOT:\\n{Max, Bella, Charlie} (unquoted strings - invalid JSON)\\nNOT:\\n{\"file_path\":\"...\", \"content\":[\"Max\"]} (don't wrap in metadata)`;\n case 'yaml': case 'yml': return `Example: Write:\\n- Max\\n- Bella\\n- Charlie\\n\\nNOT:\\n[\"Max\", \"Bella\", \"Charlie\"] (that's JSON, not YAML)`;\n case 'html': case 'htm': return `Example: Write:\\n<div class=\"container\">\\n <h1>Results</h1>\\n</div>\\n\\nNOT:\\n{\"html\": \"<div>...\"} (don't wrap in metadata)`;\n case 'css': return `Example: Write:\\n.container { color: red; }\\n\\nNOT:\\n{\"css\": \".container {...}\"} (don't wrap in metadata)`;\n case 'js': return `Example: Write:\\nconst result = [\"Max\", \"Bella\"];\\nconsole.log(result);\\n\\nNOT:\\n{\"javascript\": \"const...\"} (don't wrap in metadata)`;\n case 'md': case 'markdown': return `Example: Write:\\n# Results\\n\\n- Max\\n- Bella\\n- Charlie\\n\\nNOT:\\n{\"markdown\": \"# Results\"} (don't wrap in metadata)`;\n case 'csv': return `Example: Write:\\nMax,Bella,Charlie\\n\\nNOT:\\n[\"Max\",\"Bella\",\"Charlie\"] (that's JSON, not CSV)`;\n case 'tsv': return `Example: Write:\\nMax\\tBella\\tCharlie\\n\\nNOT:\\n[\"Max\",\"Bella\",\"Charlie\"] (that's JSON, not TSV)`;\n case 'txt': return `Example: Write:\\nMax\\nBella\\nCharlie\\n\\nNOT:\\n{\"content\": \"Max\\\\nBella\"} (don't wrap in metadata)`;\n case 'xml': return `Example: Write:\\n<?xml version=\"1.0\"?>\\n<root>\\n <item>Max</item>\\n</root>\\n\\nNOT:\\n{\"xml\": \"<?xml...>\"} (don't wrap in metadata)`;\n default: return `Example: Write the actual ${outputFormat.toUpperCase()} content directly, not wrapped in any metadata or JSON object.`;\n }\n}\n\n/** Emitter interface expected by readOutputFile */\nexport interface OutputFileEmitter {\n emit(event: string, data: unknown): boolean;\n}\n\n/**\n * Read custom output file after completion and emit result\n */\nexport function readOutputFile(emitter: OutputFileEmitter, attemptId: string, outputFormat: string): void {\n try {\n const fs = require('fs');\n const dataDir = process.env.DATA_DIR || process.cwd();\n const outputFilePath = resolve(dataDir, 'tmp', `${attemptId}.${outputFormat}`);\n\n if (fs.existsSync(outputFilePath)) {\n const fileContent = fs.readFileSync(outputFilePath, 'utf-8');\n emitter.emit('json', {\n attemptId,\n data: {\n type: 'result',\n subtype: 'success',\n is_error: false,\n content: fileContent,\n outputFormat,\n },\n });\n } else {\n emitter.emit('stderr', { attemptId, content: `Error: Expected output file not found: ${outputFilePath}` });\n }\n } catch (readError) {\n log.error({ err: readError }, 'Failed to read output file');\n }\n}\n","/**\n * Agent Event Wiring - Provider event listener setup and workflow tracking\n *\n * Extracted from agent-manager.ts. Wires provider events (message, question,\n * complete, error, stderr) to AgentManager events. Also tracks subagent\n * workflow and Bash commands from raw SDK/CLI messages.\n */\n\nimport type { ClaudeOutput } from '../types';\nimport type { BackgroundShellInfo, SDKResultMessage, UsageEvent } from './sdk-event-adapter';\nimport { sessionManager } from './session-manager';\nimport { checkpointManager } from './checkpoint-manager';\nimport { usageTracker } from './usage-tracker';\nimport { collectGitStats, gitStatsCache } from './git-stats-collector';\nimport { readOutputFile } from './agent-output-handler';\nimport { trackWorkflowFromMessage } from './agent-workflow-message-tracker';\nimport type { Provider } from './providers';\n\n/** Interface for the AgentManager context needed by event wiring */\nexport interface EventWiringContext {\n getSessionId(attemptId: string): string | undefined;\n setSessionId(attemptId: string, sessionId: string): void;\n deleteAgent(attemptId: string): void;\n emit(event: string, data: unknown): boolean;\n pendingBashCommands: Map<string, { command: string; attemptId: string }>;\n}\n\n/**\n * Wire provider events to AgentManager events for a specific attempt.\n * Returns a cleanup function that removes all listeners.\n */\nexport function wireProviderEvents(\n ctx: EventWiringContext,\n provider: Provider,\n attemptId: string,\n outputFormat?: string,\n projectPath?: string,\n): () => void {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const listeners: Array<{ event: string; fn: (...args: any[]) => void }> = [];\n\n const cleanup = () => {\n for (const { event, fn } of listeners) {\n provider.removeListener(event, fn);\n }\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const addListener = (event: string, fn: (...args: any[]) => void) => {\n listeners.push({ event, fn });\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n provider.on(event as any, fn);\n };\n\n addListener('message', async (data: {\n attemptId: string;\n output: ClaudeOutput;\n sessionId?: string;\n checkpointUuid?: string;\n backgroundShell?: BackgroundShellInfo;\n resultMessage?: SDKResultMessage;\n usageEvent?: UsageEvent;\n rawMessage?: unknown;\n }) => {\n if (data.attemptId !== attemptId) return;\n\n if (data.sessionId) {\n ctx.setSessionId(attemptId, data.sessionId);\n await sessionManager.saveSession(attemptId, data.sessionId);\n }\n\n if (data.checkpointUuid) {\n checkpointManager.captureCheckpointUuid(attemptId, data.checkpointUuid);\n }\n\n if (data.rawMessage) {\n trackWorkflowFromMessage(ctx, attemptId, data.rawMessage);\n }\n\n if (data.resultMessage) {\n usageTracker.trackResult(attemptId, data.resultMessage);\n }\n\n if (data.usageEvent) {\n usageTracker.trackUsageEvent(attemptId, data.usageEvent);\n }\n\n if (data.backgroundShell) {\n ctx.emit('backgroundShell', { attemptId, shell: data.backgroundShell });\n }\n\n // Emit adapted message (suppress result if custom output format)\n if (!(data.output.type === 'result' && outputFormat)) {\n if (outputFormat) {\n data.output.outputFormat = outputFormat;\n }\n ctx.emit('json', { attemptId, data: data.output });\n }\n });\n\n addListener('question', (data: { attemptId: string; toolUseId: string; questions: unknown[] }) => {\n if (data.attemptId !== attemptId) return;\n ctx.emit('question', data);\n });\n\n addListener('questionResolved', (data: { attemptId: string }) => {\n if (data.attemptId !== attemptId) return;\n ctx.emit('questionResolved', data);\n });\n\n addListener('complete', async (data: { attemptId: string; sessionId?: string }) => {\n if (data.attemptId !== attemptId) return;\n\n if (outputFormat) {\n readOutputFile(ctx, attemptId, outputFormat);\n }\n\n if (projectPath) {\n try {\n const gitStats = await collectGitStats(projectPath);\n if (gitStats) gitStatsCache.set(attemptId, gitStats);\n } catch { /* continue */ }\n }\n\n ctx.deleteAgent(attemptId);\n ctx.emit('exit', { attemptId, code: 0 });\n cleanup();\n });\n\n addListener('error', (data: { attemptId: string; error: string; errorName: string; isPromptTooLong?: boolean }) => {\n if (data.attemptId !== attemptId) return;\n\n ctx.emit('stderr', { attemptId, content: `${data.errorName}: ${data.error}` });\n\n if (data.isPromptTooLong) {\n ctx.emit('promptTooLong', { attemptId });\n }\n\n ctx.deleteAgent(attemptId);\n ctx.emit('exit', { attemptId, code: 1 });\n cleanup();\n });\n\n addListener('stderr', (data: { attemptId: string; content: string }) => {\n if (data.attemptId !== attemptId) return;\n ctx.emit('stderr', data);\n });\n\n return cleanup;\n}\n","/**\n * Context Health - Context window health tracking and management\n *\n * Implements ClaudeKit Engineer's context health monitoring formulas:\n * - Health status thresholds (HEALTHY/WARNING/CRITICAL/EMERGENCY)\n * - Auto-compact trigger calculation\n * - Budget allocation with buffer reserve\n * - Context usage tracking (input + output)\n */\n\n/**\n * Health status levels based on context utilization\n */\nexport type ContextHealthStatus = 'HEALTHY' | 'WARNING' | 'CRITICAL' | 'EMERGENCY';\n\n/**\n * Context health metrics\n */\nexport interface ContextHealth {\n status: ContextHealthStatus;\n score: number; // 0.0-1.0\n utilization: number; // 0.0-1.0 (percentage as decimal)\n utilizationPercent: number; // 0-100\n totalTokens: number;\n limit: number;\n remaining: number;\n shouldCompact: boolean; // Auto-compact trigger\n compactThreshold: number;\n}\n\n/**\n * Budget allocation configuration\n */\nexport interface ContextBudget {\n systemPrompt: number;\n toolDefinitions: number;\n retrievedDocs: number;\n messageHistory: number;\n bufferPercent: number; // 0.0-1.0 (default: 0.15 = 15%)\n totalBudget: number;\n warningThreshold: number; // 70% of budget\n criticalThreshold: number; // 80% of budget\n}\n\n/**\n * Default budget values from ClaudeKit Engineer\n */\nconst DEFAULT_BUDGET_CONFIG = {\n systemPrompt: 2000,\n toolDefinitions: 1500,\n retrievedDocs: 3000,\n messageHistory: 5000,\n bufferPercent: 0.15, // 15% buffer\n};\n\n/**\n * Calculate context budget allocation\n *\n * Formula from ClaudeKit:\n * - subtotal = system + tools + docs + history\n * - buffer = subtotal × buffer_pct\n * - total = subtotal + buffer\n * - warning = total × 0.70\n * - critical = total × 0.80\n */\nexport function calculateContextBudget(config = DEFAULT_BUDGET_CONFIG): ContextBudget {\n const subtotal =\n config.systemPrompt +\n config.toolDefinitions +\n config.retrievedDocs +\n config.messageHistory;\n\n const buffer = Math.floor(subtotal * config.bufferPercent);\n const totalBudget = subtotal + buffer;\n\n return {\n ...config,\n totalBudget,\n warningThreshold: Math.floor(totalBudget * 0.70),\n criticalThreshold: Math.floor(totalBudget * 0.80),\n };\n}\n\n/**\n * Calculate auto-compact threshold\n *\n * Aligned with Claude Code CLI recommendations:\n * - For window >= 1M: threshold = size × 0.33 (33%)\n * - For window < 1M: threshold = size × 0.75 (75%)\n *\n * Example: 200K window → 150K threshold\n * This preserves ~25% for output and working memory\n */\nexport function calculateCompactThreshold(contextWindowSize: number): number {\n if (contextWindowSize >= 1_000_000) {\n return Math.floor(contextWindowSize * 0.33);\n }\n return Math.floor(contextWindowSize * 0.75);\n}\n\n/**\n * Determine health status based on utilization\n *\n * Aligned with Claude Code CLI thresholds:\n * - < 60%: HEALTHY (score 1.0)\n * - 60-75%: WARNING (score 0.8)\n * - 75-90%: CRITICAL (score 0.5)\n * - >= 90%: EMERGENCY (score 0.2)\n */\nexport function getHealthStatus(utilization: number): { status: ContextHealthStatus; score: number } {\n if (utilization < 0.60) {\n return { status: 'HEALTHY', score: 1.0 };\n } else if (utilization < 0.75) {\n return { status: 'WARNING', score: 0.8 };\n } else if (utilization < 0.90) {\n return { status: 'CRITICAL', score: 0.5 };\n } else {\n return { status: 'EMERGENCY', score: 0.2 };\n }\n}\n\n/**\n * Calculate comprehensive context health metrics\n *\n * Context calculation from ClaudeKit:\n * usage = (context_input + context_output) / context_size × 100\n *\n * Note: This differs from prompt caching metrics where:\n * - context_input = input_tokens + cache_read_tokens + cache_creation_tokens\n * - context_output = output_tokens\n */\nexport function calculateContextHealth(\n inputTokens: number,\n outputTokens: number,\n contextLimit: number\n): ContextHealth {\n // Total context = input + output (ClaudeKit formula)\n const totalTokens = inputTokens + outputTokens;\n\n // Utilization as decimal (0.0-1.0)\n const utilization = totalTokens / contextLimit;\n const utilizationPercent = utilization * 100;\n\n // Remaining tokens\n const remaining = contextLimit - totalTokens;\n\n // Health status and score\n const { status, score } = getHealthStatus(utilization);\n\n // Auto-compact trigger\n const compactThreshold = calculateCompactThreshold(contextLimit);\n const shouldCompact = totalTokens >= compactThreshold;\n\n return {\n status,\n score,\n utilization,\n utilizationPercent,\n totalTokens,\n limit: contextLimit,\n remaining,\n shouldCompact,\n compactThreshold,\n };\n}\n\n// Re-export display helpers for backwards compatibility\nexport { formatHealthStatus, getHealthRecommendations } from './context-health-display-helpers';\n","/**\n * Usage Context Token Calculator - Compute context window usage from SDK token counts\n *\n * Extracted from usage-tracker.ts. Pure functions that calculate context utilization,\n * baseline tracking, and health metrics from raw SDK usage fields.\n */\n\nimport { calculateContextHealth, type ContextHealth } from './context-health';\nimport { createLogger } from './logger';\n\nconst log = createLogger('UsageContextTokenCalculator');\n\nexport interface RawTokenUsage {\n input_tokens: number;\n output_tokens: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n}\n\nexport interface ContextTokenResult {\n contextUsed: number;\n contextPercentage: number;\n baselineContext: number; // only set on first turn (numTurns === 0)\n contextHealth: ContextHealth;\n}\n\n/**\n * Calculate context window metrics from a single SDK turn's raw token usage.\n *\n * Anthropic's context window includes ALL of:\n * - input_tokens: new user message\n * - cache_read_input_tokens: cached content (still occupies window)\n * - cache_creation_input_tokens: new cache entries\n * - output_tokens: model response\n *\n * @param usage Raw token counts from the SDK result message\n * @param contextLimit Current context window size (default 200K)\n * @param isFirstTurn Whether this is the first turn (to capture baseline)\n */\nexport function calculateContextTokens(\n usage: RawTokenUsage,\n contextLimit: number,\n isFirstTurn: boolean\n): ContextTokenResult {\n const inputTokens = usage.input_tokens || 0;\n const cacheRead = usage.cache_read_input_tokens || 0;\n const cacheCreation = usage.cache_creation_input_tokens || 0;\n const outputTokens = usage.output_tokens || 0;\n\n // Baseline: first-turn cache_read tokens (for reference only)\n let baselineContext = 0;\n if (isFirstTurn && cacheRead > 0) {\n baselineContext = cacheRead;\n log.info(`First turn baseline (cached): ${cacheRead} tokens`);\n }\n\n // Active context = all tokens in the 200K window\n const contextUsed = inputTokens + cacheRead + cacheCreation + outputTokens;\n const contextPercentage = (contextUsed / contextLimit) * 100;\n\n const contextHealth = calculateContextHealth(\n inputTokens + cacheRead + cacheCreation, // total input (including cached)\n outputTokens,\n contextLimit\n );\n\n log.debug({\n contextUsed,\n contextLimit,\n contextPercentage: contextPercentage.toFixed(1),\n healthStatus: contextHealth.status,\n inputTokens,\n cacheRead,\n cacheCreation,\n outputTokens,\n totalInput: inputTokens + cacheRead + cacheCreation,\n }, 'Context updated (includes cache_read)');\n\n return { contextUsed, contextPercentage, baselineContext, contextHealth };\n}\n","/**\n * Usage Tracker - Collect and aggregate usage statistics from SDK messages\n *\n * Tracks token usage, costs, and plan limits in-memory for status line display.\n * Context token calculation extracted to: usage-context-token-calculator.ts\n */\n\nimport { EventEmitter } from 'events';\nimport type { SDKResultMessage, UsageEvent } from './sdk-event-adapter';\nimport type { ContextHealth } from './context-health';\nimport { calculateContextHealth } from './context-health';\nimport { calculateContextTokens } from './usage-context-token-calculator';\n\nimport { createLogger } from './logger';\n\nconst log = createLogger('UsageTracker');\n\n/**\n * Aggregated usage statistics for a session\n */\nexport interface UsageStats {\n totalInputTokens: number;\n totalOutputTokens: number;\n totalCacheCreationTokens: number;\n totalCacheReadTokens: number;\n totalTokens: number;\n totalCostUSD: number;\n numTurns: number;\n durationMs: number;\n durationApiMs: number;\n\n // Context usage tracking (full context window)\n contextUsed: number;\n contextLimit: number;\n contextPercentage: number;\n baselineContext: number;\n\n // Context health metrics (ClaudeKit formulas)\n contextHealth?: ContextHealth;\n\n // Per-model breakdown\n modelUsage: Record<string, {\n inputTokens: number;\n outputTokens: number;\n cacheReadInputTokens: number;\n cacheCreationInputTokens: number;\n costUSD: number;\n contextWindow: number;\n }>;\n\n // Session metadata\n sessionId?: string;\n startedAt: number;\n lastUpdatedAt: number;\n}\n\n/**\n * Account info from Claude Code (from accountInfo() API)\n */\nexport interface AccountInfo {\n email?: string;\n organization?: string;\n subscriptionType?: string;\n tokenSource?: string;\n apiKeySource?: string;\n}\n\n/**\n * Plan limits - retrieved once and cached\n */\nexport interface PlanLimits {\n maxTokensPerWindow?: number;\n windowDurationMs?: number;\n}\n\ninterface UsageTrackerEvents {\n 'usage-update': (data: { attemptId: string; usage: UsageStats }) => void;\n}\n\n/**\n * UsageTracker - Singleton to track usage statistics\n */\nclass UsageTracker extends EventEmitter {\n private sessions = new Map<string, UsageStats>();\n private accountInfo?: AccountInfo;\n\n constructor() {\n super();\n }\n\n /** Initialize or get usage stats for an attempt */\n initSession(attemptId: string): UsageStats {\n if (!this.sessions.has(attemptId)) {\n const stats: UsageStats = {\n totalInputTokens: 0,\n totalOutputTokens: 0,\n totalCacheCreationTokens: 0,\n totalCacheReadTokens: 0,\n totalTokens: 0,\n totalCostUSD: 0,\n numTurns: 0,\n durationMs: 0,\n durationApiMs: 0,\n contextUsed: 0,\n contextLimit: 200000,\n contextPercentage: 0,\n baselineContext: 0,\n modelUsage: {},\n startedAt: Date.now(),\n lastUpdatedAt: Date.now(),\n };\n this.sessions.set(attemptId, stats);\n }\n return this.sessions.get(attemptId)!;\n }\n\n /** Update usage stats from SDKResultMessage */\n trackResult(attemptId: string, result: SDKResultMessage): void {\n const stats = this.initSession(attemptId);\n\n if ('session_id' in result) {\n stats.sessionId = result.session_id;\n }\n\n if ('usage' in result) {\n const usage = result.usage as {\n input_tokens: number;\n output_tokens: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n };\n\n stats.totalInputTokens += usage.input_tokens;\n stats.totalOutputTokens += usage.output_tokens;\n stats.totalCacheCreationTokens += usage.cache_creation_input_tokens || 0;\n stats.totalCacheReadTokens += usage.cache_read_input_tokens || 0;\n stats.totalTokens = stats.totalInputTokens + stats.totalOutputTokens;\n\n const { contextUsed, contextPercentage, baselineContext, contextHealth } =\n calculateContextTokens(usage, stats.contextLimit, stats.numTurns === 0);\n\n stats.contextUsed = contextUsed;\n stats.contextPercentage = contextPercentage;\n if (baselineContext > 0) stats.baselineContext = baselineContext;\n stats.contextHealth = contextHealth;\n }\n\n if ('total_cost_usd' in result) stats.totalCostUSD += result.total_cost_usd as number;\n if ('num_turns' in result) stats.numTurns += result.num_turns || 0;\n if ('duration_ms' in result) stats.durationMs += result.duration_ms || 0;\n if ('duration_api_ms' in result) stats.durationApiMs += (result as any).duration_api_ms || 0;\n\n // Merge per-model usage (only in success variant)\n if (result.subtype === 'success' && 'modelUsage' in result && result.modelUsage) {\n for (const [modelName, modelStats] of Object.entries(result.modelUsage)) {\n if (!stats.modelUsage[modelName]) {\n stats.modelUsage[modelName] = {\n inputTokens: 0,\n outputTokens: 0,\n cacheReadInputTokens: 0,\n cacheCreationInputTokens: 0,\n costUSD: 0,\n contextWindow: (modelStats as any).contextWindow || 200000,\n };\n }\n const existing = stats.modelUsage[modelName];\n const ms = modelStats as any;\n existing.inputTokens += ms.inputTokens || 0;\n existing.outputTokens += ms.outputTokens || 0;\n existing.cacheReadInputTokens += ms.cacheReadInputTokens || 0;\n existing.cacheCreationInputTokens += ms.cacheCreationInputTokens || 0;\n existing.costUSD += ms.costUSD || 0;\n\n // Update context limit from model context window if available\n if (ms.contextWindow && ms.contextWindow > 0) {\n stats.contextLimit = ms.contextWindow;\n }\n }\n }\n\n stats.lastUpdatedAt = Date.now();\n this.emit('usage-update', { attemptId, usage: stats });\n }\n\n /**\n * Track per-turn usage from message_start/message_delta stream events.\n *\n * The Anthropic API emits usage on every API response:\n * - message_start: input_tokens, cache_read, cache_creation (full input context at this turn)\n * - message_delta: output_tokens (output for this turn)\n *\n * input_tokens + cache_read + cache_creation = total input context for this API call\n * (includes system prompt, tool definitions, full conversation history, tool results)\n *\n * This gives us accurate, real-time context tracking without estimation.\n */\n trackUsageEvent(attemptId: string, usage: UsageEvent): void {\n const stats = this.initSession(attemptId);\n\n const inputContext = (usage.input_tokens || 0) + (usage.cache_read_input_tokens || 0) + (usage.cache_creation_input_tokens || 0);\n const outputTokens = usage.output_tokens || 0;\n\n // Track baseline from first message_start (before any output)\n if (stats.baselineContext === 0 && inputContext > 0) {\n stats.baselineContext = inputContext;\n log.info({ attemptId, baseline: inputContext }, 'Context baseline set from first usage event');\n }\n\n // Context used = input context + output tokens for this API call\n // This is the actual context window usage at this point in the conversation\n if (inputContext > 0) {\n stats.contextUsed = inputContext + outputTokens;\n stats.contextPercentage = (stats.contextUsed / stats.contextLimit) * 100;\n\n stats.contextHealth = calculateContextHealth(\n inputContext,\n outputTokens,\n stats.contextLimit\n );\n\n log.debug({\n attemptId,\n contextUsed: stats.contextUsed,\n contextLimit: stats.contextLimit,\n contextPct: stats.contextPercentage.toFixed(1),\n input: usage.input_tokens,\n cacheRead: usage.cache_read_input_tokens,\n cacheCreate: usage.cache_creation_input_tokens,\n output: outputTokens,\n }, 'Context updated from stream usage event');\n }\n\n stats.lastUpdatedAt = Date.now();\n this.emit('usage-update', { attemptId, usage: stats });\n }\n\n /** Get current usage stats for an attempt */\n getUsage(attemptId: string): UsageStats | undefined {\n return this.sessions.get(attemptId);\n }\n\n /** Clear usage stats for an attempt */\n clearSession(attemptId: string): void {\n this.sessions.delete(attemptId);\n }\n\n /** Get all active sessions */\n getAllSessions(): Map<string, UsageStats> {\n return this.sessions;\n }\n\n /** Set account info (from accountInfo() API call) */\n setAccountInfo(info: AccountInfo): void {\n this.accountInfo = info;\n }\n\n /** Get cached account info */\n getAccountInfo(): AccountInfo | undefined {\n return this.accountInfo;\n }\n\n override on<K extends keyof UsageTrackerEvents>(\n event: K,\n listener: UsageTrackerEvents[K]\n ): this {\n return super.on(event, listener);\n }\n\n override emit<K extends keyof UsageTrackerEvents>(\n event: K,\n ...args: Parameters<UsageTrackerEvents[K]>\n ): boolean {\n return super.emit(event, ...args);\n }\n}\n\n// Export singleton instance\nexport const usageTracker = new UsageTracker();\n","/**\n * Git Stats Collector - Capture git changes snapshot on stream completion\n *\n * Collects git diff stats (additions/deletions) when streaming finishes.\n * Only runs once per attempt, on final result.\n */\n\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\n\nimport { createLogger } from './logger';\n\nconst log = createLogger('GitStatsCollector');\n\nconst execAsync = promisify(exec);\n\n/**\n * Git statistics snapshot\n */\nexport interface GitStats {\n additions: number;\n deletions: number;\n filesChanged: number;\n capturedAt: number;\n}\n\n/**\n * Parse git diff --numstat output\n * Format: <additions>\\t<deletions>\\t<filename>\n */\nfunction parseNumstat(output: string): GitStats {\n const lines = output.trim().split('\\n').filter(Boolean);\n\n let additions = 0;\n let deletions = 0;\n let filesChanged = 0;\n\n for (const line of lines) {\n const parts = line.split('\\t');\n if (parts.length < 3) continue;\n\n const [add, del] = parts;\n\n // Handle binary files (marked as '-')\n if (add !== '-') additions += parseInt(add, 10) || 0;\n if (del !== '-') deletions += parseInt(del, 10) || 0;\n\n filesChanged++;\n }\n\n return {\n additions,\n deletions,\n filesChanged,\n capturedAt: Date.now(),\n };\n}\n\n/**\n * Collect git diff stats for current working directory\n */\nexport async function collectGitStats(cwd: string): Promise<GitStats | null> {\n try {\n // Get git diff --numstat (staged + unstaged changes)\n const { stdout } = await execAsync('git diff --numstat HEAD', { cwd });\n\n if (!stdout.trim()) {\n // No changes\n return {\n additions: 0,\n deletions: 0,\n filesChanged: 0,\n capturedAt: Date.now(),\n };\n }\n\n return parseNumstat(stdout);\n } catch (error) {\n // Not a git repo or git command failed\n log.error({ error: error }, '[GitStats] Failed to collect git stats:');\n return null;\n }\n}\n\n/**\n * In-memory cache for git stats per attempt\n */\nclass GitStatsCache {\n private cache = new Map<string, GitStats | null>();\n\n set(attemptId: string, stats: GitStats | null): void {\n this.cache.set(attemptId, stats);\n }\n\n get(attemptId: string): GitStats | null | undefined {\n return this.cache.get(attemptId);\n }\n\n clear(attemptId: string): void {\n this.cache.delete(attemptId);\n }\n\n getAll(): Map<string, GitStats | null> {\n return this.cache;\n }\n}\n\n// Export singleton cache\nexport const gitStatsCache = new GitStatsCache();\n","/**\n * Agent Workflow Message Tracker - Parse raw SDK/CLI messages to track subagent workflow events\n *\n * Extracted from agent-event-wiring.ts. Processes assistant/user message blocks to track\n * Task/Agent tool subagent starts/ends, TeamCreate events, SendMessage events,\n * TaskCreate/TaskUpdate events, and Bash BGPID patterns.\n */\n\nimport { workflowTracker } from './workflow-tracker';\nimport { isServerCommand } from './agent-output-handler';\nimport type { EventWiringContext } from './agent-event-wiring';\n\n/**\n * Track workflow from raw SDK/CLI messages (subagent starts/ends, team creation, Bash commands).\n */\nexport function trackWorkflowFromMessage(\n ctx: EventWiringContext,\n attemptId: string,\n message: unknown\n): void {\n const msg = message as {\n type: string;\n message?: { content: Array<{ type: string; id?: string; name?: string; input?: unknown }> };\n parent_tool_use_id?: string | null;\n };\n\n if (msg.type === 'assistant' && msg.message?.content) {\n for (const block of msg.message.content) {\n if (block.type === 'tool_use' && (block.name === 'Task' || block.name === 'Agent') && block.id) {\n const taskInput = (block as { input?: { subagent_type?: string; model?: string; team_name?: string; name?: string; prompt?: string; description?: string } }).input;\n workflowTracker.trackSubagentStart(\n attemptId, block.id, taskInput?.subagent_type || taskInput?.model || 'agent',\n msg.parent_tool_use_id || null,\n { teamName: taskInput?.team_name, name: taskInput?.name, prompt: taskInput?.prompt || taskInput?.description },\n );\n }\n if (block.type === 'tool_use' && block.name === 'TeamCreate' && block.id) {\n const teamInput = (block as { input?: { team_name?: string } }).input;\n if (teamInput?.team_name) workflowTracker.trackTeamCreate(attemptId, teamInput.team_name);\n }\n if (block.type === 'tool_use' && block.name === 'SendMessage' && block.id) {\n const msgInput = (block as { input?: { type?: string; to?: string; recipient?: string; content?: string; message?: string | object; summary?: string } }).input;\n if (msgInput) {\n // Best-effort sender inference: find most recent active agent\n const workflow = workflowTracker.getWorkflow(attemptId);\n let inferredSender: string | undefined;\n if (workflow) {\n const activeNodes = workflow.activeNodes\n .map(id => workflow.nodes.get(id))\n .filter(Boolean)\n .sort((a, b) => (b!.startedAt || 0) - (a!.startedAt || 0));\n inferredSender = activeNodes[0]?.name || activeNodes[0]?.type;\n }\n const messageContent = typeof msgInput.message === 'string' ? msgInput.message : (msgInput.content || '');\n workflowTracker.trackMessage(attemptId, {\n ...msgInput,\n content: messageContent,\n fromAgent: inferredSender,\n isBroadcast: msgInput.to === '*',\n });\n }\n }\n if (block.type === 'tool_use' && block.name === 'TaskCreate' && block.id) {\n const tcInput = (block as { input?: { subject?: string; description?: string; activeForm?: string } }).input;\n if (tcInput) workflowTracker.trackTaskCreate(attemptId, block.id, tcInput);\n }\n if (block.type === 'tool_use' && block.name === 'TaskUpdate' && block.id) {\n const tuInput = (block as { input?: { taskId?: string; status?: string; owner?: string; subject?: string; activeForm?: string } }).input;\n if (tuInput) workflowTracker.trackTaskUpdate(attemptId, tuInput);\n }\n // Track Bash tool_uses for BGPID correlation\n if (block.type === 'tool_use' && block.name === 'Bash' && block.id) {\n const bashInput = block.input as { command?: string } | undefined;\n const toolId = block.id;\n if (bashInput?.command) {\n ctx.pendingBashCommands.set(toolId, { command: bashInput.command, attemptId });\n setTimeout(() => ctx.pendingBashCommands.delete(toolId), 5 * 60 * 1000);\n }\n }\n }\n }\n\n if (msg.type === 'user' && msg.message?.content) {\n const userContent = msg.message.content as Array<{\n type: string;\n tool_use_id?: string;\n is_error?: boolean;\n content?: string | unknown[];\n }>;\n\n for (const block of userContent) {\n if (block.type === 'tool_result' && block.tool_use_id) {\n // Extract result content for Task tool results\n let resultContent = '';\n if (typeof block.content === 'string') {\n resultContent = block.content;\n } else if (Array.isArray(block.content)) {\n resultContent = (block.content as Array<{ text?: string }>)\n .filter(c => c && typeof c === 'object' && 'text' in c)\n .map(c => c.text || '').join('');\n }\n\n // Register actual taskId from TaskCreate results (toolUseId → numeric taskId mapping)\n {\n const workflow = workflowTracker.getWorkflow(attemptId);\n if (workflow) {\n const isTaskCreate = workflow.tasks.some((t) => t.id === block.tool_use_id);\n if (isTaskCreate && resultContent) {\n try {\n const parsed = JSON.parse(resultContent);\n if (parsed.taskId) {\n workflowTracker.registerTaskId(attemptId, block.tool_use_id!, String(parsed.taskId));\n }\n } catch {\n // Text format: \"Task #5 created successfully: ...\"\n const match = resultContent.match(/Task\\s*#(\\d+)/i) ||\n resultContent.match(/taskId[\"\\s:]+(\\d+)/);\n if (match) {\n workflowTracker.registerTaskId(attemptId, block.tool_use_id!, match[1]);\n }\n }\n }\n }\n }\n\n // Extract the meaningful agent output from result, stripping SDK boilerplate\n let cleanResult = resultContent;\n const agentIdIdx = resultContent.indexOf('agentId:');\n const usageIdx = resultContent.indexOf('<usage>');\n if (agentIdIdx > 0 || usageIdx > 0) {\n const cutoff = Math.min(\n agentIdIdx > 0 ? agentIdIdx : Infinity,\n usageIdx > 0 ? usageIdx : Infinity,\n );\n cleanResult = resultContent.slice(0, cutoff).trim();\n }\n // Strip \"Spawned successfully...\" preamble for foreground agents that returned real content\n const pipeIdx = cleanResult.indexOf('|');\n if (pipeIdx > 0 && cleanResult.includes('Spawned successfully')) {\n cleanResult = cleanResult.slice(pipeIdx + 1).trim();\n } else if (cleanResult.startsWith('Spawned successfully')) {\n // Background agent - no real content yet\n cleanResult = '';\n }\n\n workflowTracker.trackSubagentEnd(\n attemptId, block.tool_use_id, !block.is_error,\n block.is_error ? resultContent : undefined,\n cleanResult || resultContent,\n );\n\n // Detect BGPID pattern\n let content = '';\n if (typeof block.content === 'string') {\n content = block.content;\n } else if (Array.isArray(block.content)) {\n content = (block.content as Array<{ text?: string }>)\n .filter(c => c && typeof c === 'object' && 'text' in c)\n .map(c => c.text || '').join('');\n }\n\n const bgpidMatch = content.match(/BGPID:(\\d+)/);\n const emptyBgpidMatch = content.match(/BGPID:\\s*$/m) || content.trim() === 'BGPID:';\n\n if (bgpidMatch && block.tool_use_id) {\n const pid = parseInt(bgpidMatch[1], 10);\n const bashInfo = ctx.pendingBashCommands.get(block.tool_use_id);\n const command = bashInfo?.command || `Background process (PID: ${pid})`;\n const logMatch = command.match(/>\\s*([^\\s]+\\.log)/);\n ctx.emit('trackedProcess', { attemptId, pid, command, logFile: logMatch?.[1] });\n ctx.pendingBashCommands.delete(block.tool_use_id);\n } else if (emptyBgpidMatch && block.tool_use_id) {\n const bashInfo = ctx.pendingBashCommands.get(block.tool_use_id);\n if (bashInfo?.command && isServerCommand(bashInfo.command)) {\n const nohupMatch = bashInfo.command.match(/nohup\\s+(.+?)\\s*>\\s*\\/tmp\\//);\n if (nohupMatch) {\n ctx.emit('backgroundShell', {\n attemptId,\n shell: {\n toolUseId: block.tool_use_id,\n command: nohupMatch[1].trim(),\n description: 'Auto-spawned from empty BGPID',\n originalCommand: bashInfo.command,\n },\n });\n }\n }\n ctx.pendingBashCommands.delete(block.tool_use_id);\n }\n }\n }\n }\n}\n","/**\n * Agent Persistent Question Store - Task-scoped AskUserQuestion data that survives agent cleanup\n *\n * Extracted from agent-manager.ts. Stores pending question payloads keyed by taskId\n * so they remain accessible after the agent attempt completes or is cancelled.\n * Used when CLI auto-handles AskUserQuestion and the attempt ends before user answers.\n */\n\nexport interface PersistentQuestionData {\n attemptId: string;\n toolUseId: string;\n questions: unknown[];\n timestamp: number;\n}\n\n/**\n * PersistentQuestionStore - in-memory map of taskId → question data\n */\nexport class PersistentQuestionStore {\n private store = new Map<string, PersistentQuestionData>();\n\n /** Persist question data for a task (survives agent cleanup) */\n set(taskId: string, data: PersistentQuestionData): void {\n this.store.set(taskId, data);\n }\n\n /** Retrieve persisted question data for a task, or null if absent */\n get(taskId: string): PersistentQuestionData | null {\n return this.store.get(taskId) || null;\n }\n\n /** Remove persisted question data for a task */\n clear(taskId: string): void {\n this.store.delete(taskId);\n }\n}\n"],"names":["ENGINEERING_SYSTEM_PROMPT","trim","TASK_HINTS","fix","feature","debug","refactor","question","setup","server","isServerTask","prompt","lower","toLowerCase","test","getSystemPrompt","options","outputFormat","outputSchema","attemptId","outputFilePath","finalPrompt","formatInstructions","getOutputFormatInstructions","format","schema","filePath","toUpperCase"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/agent-manager.ts","../../../src/lib/system-prompt.ts","../../../src/lib/providers/claude-sdk-provider.ts","../../../packages/agentic-sdk/src/agent/claude-sdk-message-to-output-adapter.ts","../../../src/lib/sdk-event-adapter.ts","../../../src/lib/providers/claude-sdk-mcp-config-loader.ts","../../../src/lib/providers/claude-sdk-model-alias-and-server-command-utils.ts","../../../src/lib/providers/claude-sdk-query-options-builder.ts","../../../src/lib/providers/claude-cli-provider.ts","../../../src/lib/providers/claude-cli-session-and-pending-question-types.ts","../../../src/lib/providers/claude-cli-process-spawner.ts","../../../src/lib/providers/claude-cli-stdout-line-to-provider-event-parser.ts","../../../src/lib/providers/index.ts","../../../src/lib/agent-output-handler.ts","../../../src/lib/agent-event-wiring.ts","../../../src/lib/context-health.ts","../../../src/lib/usage-context-token-calculator.ts","../../../src/lib/usage-tracker.ts","../../../src/lib/git-stats-collector.ts","../../../src/lib/agent-workflow-message-tracker.ts","../../../src/lib/agent-persistent-question-store.ts"],"sourcesContent":["/**\n * Agent Manager - Thin orchestrator delegating to providers\n *\n * Selects between Claude CLI and SDK providers, builds prompts,\n * and forwards provider events to AgentManager events (identical API).\n * Cross-cutting concerns: sessionManager, checkpointManager, usageTracker, workflowTracker.\n */\n\n// Ensure file checkpointing is always enabled\nprocess.env.CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING = '1';\n\n// Enable SDK task system (opt-in feature since v0.2.19)\nprocess.env.CLAUDE_CODE_ENABLE_TASKS = 'true';\n\nimport { EventEmitter } from 'events';\nimport { readFile } from 'fs/promises';\nimport { resolve, isAbsolute } from 'path';\nimport type { ClaudeOutput } from '../types';\nimport type { BackgroundShellInfo } from './sdk-event-adapter';\nimport { getSystemPrompt } from './system-prompt';\nimport { modelIdToDisplayName } from './models';\nimport { createLogger } from './logger';\nimport { getActiveProvider, getProvider, type Provider, type ProviderSession } from './providers';\nimport { buildOutputFormatPrompt } from './agent-output-handler';\nimport { wireProviderEvents, type EventWiringContext } from './agent-event-wiring';\nimport { PersistentQuestionStore, type PersistentQuestionData } from './agent-persistent-question-store';\n\nconst log = createLogger('AgentManager');\nconst FALLBACK_MODEL_ID = 'claude-opus-4-6';\n\nfunction resolveDefaultModelFromEnv(): string {\n const envCandidates = [\n process.env.ANTHROPIC_MODEL,\n process.env.ANTHROPIC_DEFAULT_OPUS_MODEL,\n process.env.ANTHROPIC_DEFAULT_SONNET_MODEL,\n process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL,\n ];\n\n for (const candidate of envCandidates) {\n const value = candidate?.trim();\n if (value) return value;\n }\n\n return FALLBACK_MODEL_ID;\n}\n\ninterface AgentInstance {\n attemptId: string;\n session: ProviderSession;\n provider: Provider;\n startedAt: number;\n outputFormat?: string;\n}\n\ninterface AgentEvents {\n started: (data: { attemptId: string; taskId: string }) => void;\n json: (data: { attemptId: string; data: ClaudeOutput }) => void;\n stderr: (data: { attemptId: string; content: string }) => void;\n exit: (data: { attemptId: string; code: number | null }) => void;\n question: (data: { attemptId: string; toolUseId: string; questions: unknown[] }) => void;\n questionResolved: (data: { attemptId: string }) => void;\n backgroundShell: (data: { attemptId: string; shell: BackgroundShellInfo }) => void;\n trackedProcess: (data: { attemptId: string; pid: number; command: string; logFile?: string }) => void;\n promptTooLong: (data: { attemptId: string }) => void;\n}\n\nexport interface AgentStartOptions {\n attemptId: string;\n projectPath: string;\n prompt: string;\n model?: string;\n provider?: 'claude-cli' | 'claude-sdk';\n sessionOptions?: {\n resume?: string;\n resumeSessionAt?: string;\n };\n filePaths?: string[];\n outputFormat?: string;\n outputSchema?: string;\n maxTurns?: number;\n}\n\n/**\n * AgentManager - Singleton orchestrator that delegates to providers\n */\nclass AgentManager extends EventEmitter {\n private agents = new Map<string, AgentInstance>();\n // Track Bash tool_use commands to correlate with BGPID results\n private pendingBashCommands = new Map<string, { command: string; attemptId: string }>();\n // Persistent question storage — survives agent cleanup (keyed by taskId)\n private persistentQuestionStore = new PersistentQuestionStore();\n\n constructor() {\n super();\n process.on('exit', () => this.cancelAll());\n }\n\n /**\n * Build the EventWiringContext interface for extracted event wiring\n */\n private buildWiringContext(): EventWiringContext {\n return {\n getSessionId: (attemptId: string) => this.agents.get(attemptId)?.session.sessionId,\n setSessionId: (attemptId: string, sessionId: string) => {\n const instance = this.agents.get(attemptId);\n if (instance) instance.session.sessionId = sessionId;\n },\n deleteAgent: (attemptId: string) => this.agents.delete(attemptId),\n emit: (event: string, data: unknown) => this.emit(event as keyof AgentEvents, data as any),\n pendingBashCommands: this.pendingBashCommands,\n };\n }\n\n /**\n * Start a new agent query via the active provider\n */\n async start(options: AgentStartOptions): Promise<void> {\n const { attemptId, projectPath, prompt, sessionOptions, filePaths, outputFormat, outputSchema, maxTurns, model, provider: requestedProvider } = options;\n\n if (this.agents.has(attemptId)) return;\n\n // Build full prompt — resolve @filepath mentions and file attachments\n // into inline file content so they work in stream-json / SDK mode\n let fullPrompt = prompt;\n\n // Collect all file paths: from filePaths param (attachments) and @mentions in prompt\n const allFilePaths: string[] = [];\n if (filePaths && filePaths.length > 0) {\n allFilePaths.push(...filePaths);\n }\n\n // Extract @filepath references from the prompt text (added by buildPromptWithMentions)\n const mentionRegex = /@([\\w.\\/\\\\-]+(?:#L\\d+(?:-\\d+)?)?)/g;\n let mentionMatch;\n const mentionPaths: { fullMatch: string; filePath: string; lineRange?: string }[] = [];\n while ((mentionMatch = mentionRegex.exec(prompt)) !== null) {\n const ref = mentionMatch[1];\n const hashIdx = ref.indexOf('#');\n const filePath = hashIdx >= 0 ? ref.substring(0, hashIdx) : ref;\n const lineRange = hashIdx >= 0 ? ref.substring(hashIdx + 1) : undefined;\n // Skip if it looks like an email or non-path reference\n if (filePath.includes('.') || filePath.includes('/')) {\n mentionPaths.push({ fullMatch: mentionMatch[0], filePath, lineRange });\n }\n }\n\n // Read file contents and build context block\n const fileContextParts: string[] = [];\n const processedPaths = new Set<string>();\n\n // Process file attachment paths\n for (const fp of allFilePaths) {\n const absPath = isAbsolute(fp) ? fp : resolve(projectPath, fp);\n if (processedPaths.has(absPath)) continue;\n processedPaths.add(absPath);\n try {\n const content = await readFile(absPath, 'utf-8');\n fileContextParts.push(`<file path=\"${fp}\">\\n${content}\\n</file>`);\n } catch (err) {\n log.warn({ path: absPath }, 'Could not read attached file, falling back to @reference');\n fileContextParts.push(`@${fp}`);\n }\n }\n\n // Process @mention paths from prompt text\n for (const mention of mentionPaths) {\n const absPath = isAbsolute(mention.filePath) ? mention.filePath : resolve(projectPath, mention.filePath);\n if (processedPaths.has(absPath)) continue;\n processedPaths.add(absPath);\n try {\n let content = await readFile(absPath, 'utf-8');\n // If line range specified, extract those lines\n if (mention.lineRange) {\n const lines = content.split('\\n');\n const rangeMatch = mention.lineRange.match(/^L(\\d+)(?:-(\\d+))?$/);\n if (rangeMatch) {\n const start = Math.max(1, parseInt(rangeMatch[1])) - 1;\n const end = rangeMatch[2] ? parseInt(rangeMatch[2]) : start + 1;\n content = lines.slice(start, end).join('\\n');\n fileContextParts.push(`<file path=\"${mention.filePath}\" lines=\"${mention.lineRange}\">\\n${content}\\n</file>`);\n } else {\n fileContextParts.push(`<file path=\"${mention.filePath}\">\\n${content}\\n</file>`);\n }\n } else {\n fileContextParts.push(`<file path=\"${mention.filePath}\">\\n${content}\\n</file>`);\n }\n } catch {\n // File not found — leave the @reference as-is in the prompt\n log.debug({ path: absPath }, 'Could not read mentioned file, keeping @reference');\n }\n }\n\n // Strip resolved @mentions from prompt text and prepend file context\n if (fileContextParts.length > 0) {\n let cleanedPrompt = prompt;\n // Remove @mentions that were successfully resolved\n for (const mention of mentionPaths) {\n const absPath = isAbsolute(mention.filePath) ? mention.filePath : resolve(projectPath, mention.filePath);\n if (processedPaths.has(absPath)) {\n cleanedPrompt = cleanedPrompt.replace(mention.fullMatch, '').trim();\n }\n }\n fullPrompt = `${fileContextParts.join('\\n\\n')}\\n\\n${cleanedPrompt}`;\n }\n\n const systemPrompt = getSystemPrompt({ prompt, projectPath });\n if (systemPrompt) {\n fullPrompt += `\\n\\n${systemPrompt}`;\n }\n\n if (outputFormat) {\n fullPrompt += buildOutputFormatPrompt(outputFormat, outputSchema, attemptId);\n }\n\n // Build model identity and project context for system prompt\n const effectiveModel = model?.trim() || resolveDefaultModelFromEnv();\n const modelDisplayName = modelIdToDisplayName(effectiveModel);\n const modelIdentity = modelDisplayName !== effectiveModel\n ? `You are powered by the model named ${modelDisplayName}. The exact model ID is ${effectiveModel}.`\n : `You are powered by the model ${effectiveModel}.`;\n const projectContext = `Your current working directory is ${projectPath}. All file operations should use paths relative to or within this directory.`;\n\n // Use per-request provider if specified, otherwise fall back to env-based default\n const provider = requestedProvider ? getProvider(requestedProvider) : getActiveProvider();\n\n // Wire up provider events for this attempt\n wireProviderEvents(this.buildWiringContext(), provider, attemptId, outputFormat, projectPath);\n\n try {\n const session = await provider.start({\n attemptId,\n projectPath,\n prompt: fullPrompt,\n model: effectiveModel,\n sessionOptions,\n maxTurns,\n systemPromptAppend: `${modelIdentity}\\n${projectContext}`,\n outputFormat,\n outputSchema,\n });\n\n const instance: AgentInstance = {\n attemptId,\n session,\n provider,\n startedAt: Date.now(),\n outputFormat,\n };\n\n this.agents.set(attemptId, instance);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n log.error({ attemptId, err: error }, 'Failed to start provider');\n this.emit('stderr', { attemptId, content: errorMessage });\n this.emit('exit', { attemptId, code: 1 });\n }\n }\n\n // --- Public API (identical to original) ---\n\n answerQuestion(attemptId: string, toolUseId: string | undefined, questions: unknown[], answers: Record<string, string>): boolean {\n const instance = this.agents.get(attemptId);\n if (!instance) return false;\n return instance.provider.answerQuestion(attemptId, toolUseId, questions, answers);\n }\n\n cancelQuestion(attemptId: string): boolean {\n const instance = this.agents.get(attemptId);\n if (!instance) return false;\n return instance.provider.cancelQuestion(attemptId);\n }\n\n hasPendingQuestion(attemptId: string): boolean {\n const instance = this.agents.get(attemptId);\n if (!instance) return false;\n return instance.provider.hasPendingQuestion(attemptId);\n }\n\n getPendingQuestionData(attemptId: string): { toolUseId: string; questions: unknown[]; timestamp: number } | null {\n const instance = this.agents.get(attemptId);\n if (!instance) return null;\n return instance.provider.getPendingQuestionData(attemptId);\n }\n\n getAllPendingQuestions(): Array<{ attemptId: string; toolUseId: string; questions: unknown[]; timestamp: number }> {\n const result: Array<{ attemptId: string; toolUseId: string; questions: unknown[]; timestamp: number }> = [];\n for (const [attemptId, instance] of this.agents) {\n const data = instance.provider.getPendingQuestionData(attemptId);\n if (data) result.push({ attemptId, ...data });\n }\n return result;\n }\n\n // Persistent question methods — question data survives agent cleanup\n setPersistentQuestion(taskId: string, data: PersistentQuestionData): void {\n this.persistentQuestionStore.set(taskId, data);\n }\n\n getPersistentQuestion(taskId: string): PersistentQuestionData | null {\n return this.persistentQuestionStore.get(taskId);\n }\n\n clearPersistentQuestion(taskId: string): void {\n this.persistentQuestionStore.clear(taskId);\n }\n\n async sendInput(attemptId: string, _input: string): Promise<boolean> {\n const instance = this.agents.get(attemptId);\n if (!instance || !instance.session.sessionId) return false;\n return false;\n }\n\n async compact(options: { attemptId: string; projectPath: string; conversationSummary?: string; model?: string; provider?: AgentStartOptions['provider'] }): Promise<void> {\n const { attemptId, projectPath, conversationSummary, model, provider } = options;\n const compactPrompt = conversationSummary\n ? `You are continuing a previous conversation that reached the context limit. Here is a summary of the previous context:\\n\\n${conversationSummary}\\n\\nPlease acknowledge this context briefly and let the user know you're ready to continue.`\n : 'A previous conversation reached the context limit. Please let the user know you are ready to continue with a fresh context.';\n\n await this.start({ attemptId, projectPath, prompt: compactPrompt, maxTurns: 1, model, provider });\n }\n\n cancel(attemptId: string): boolean {\n const instance = this.agents.get(attemptId);\n if (!instance) return false;\n\n instance.session.cancel();\n this.agents.delete(attemptId);\n return true;\n }\n\n cancelAll(): void {\n for (const [, instance] of this.agents) {\n instance.session.cancel();\n }\n this.agents.clear();\n }\n\n isRunning(attemptId: string): boolean {\n return this.agents.has(attemptId);\n }\n\n get runningCount(): number {\n return this.agents.size;\n }\n\n getRunningAttempts(): string[] {\n return Array.from(this.agents.keys());\n }\n\n getSessionId(attemptId: string): string | undefined {\n return this.agents.get(attemptId)?.session.sessionId;\n }\n\n // Type-safe event emitter methods\n override on<K extends keyof AgentEvents>(event: K, listener: AgentEvents[K]): this {\n return super.on(event, listener);\n }\n\n override emit<K extends keyof AgentEvents>(event: K, ...args: Parameters<AgentEvents[K]>): boolean {\n return super.emit(event, ...args);\n }\n}\n\n// Export singleton instance (global for cross-module access)\nconst globalKey = '__claude_agent_manager__' as const;\n\ndeclare global {\n var __claude_agent_manager__: AgentManager | undefined;\n}\n\nexport const agentManager: AgentManager =\n (globalThis as any)[globalKey] ?? new AgentManager();\n\nif (!(globalThis as any)[globalKey]) {\n (globalThis as any)[globalKey] = agentManager;\n}\n","/**\n * Minimal System Prompt - Only project-specific rules\n * SDK already provides: Tools, Skills, MCP, Agents documentation\n */\nexport const ENGINEERING_SYSTEM_PROMPT = `\n## BACKGROUND SERVERS - CRITICAL\n- Unless specified otherwise, create files/folders ONLY within the project's path and organize files/folders using the PARA method, also create docs, plans, reports, executions if needed\n- Respond in the same language as the user's prompt, except for CLAUDE.md requirements.\n`.trim();\n\n/**\n * Detect if task involves starting a server\n * Task-specific prompt additions\n */\nconst TASK_HINTS: Record<string, string> = {\n fix: `\\n## MODE: BUG FIX\\nFind root cause FIRST. Grep→Read→Trace→Fix→Test`,\n feature: `\\n## MODE: FEATURE\\nMatch existing patterns. Glob→Read similar→Implement→Test`,\n debug: `\\n## MODE: DEBUG\\nReproduce first. Logs→Grep→Trace→Hypothesize→Test`,\n refactor: `\\n## MODE: REFACTOR\\nPreserve behavior. Read→Grep usages→Small edits→Test EACH`,\n question: `\\n## MODE: QUESTION\\nCite file:line. Grep/Glob→Read→Answer with references`,\n setup: `\\n## MODE: SETUP\\nFollow official docs. Read configs→Check package.json→Verify`,\n server: `\\n## MODE: SERVER`,\n};\n\n/**\n * Detect task type from prompt content\n */\nfunction isServerTask(prompt: string): boolean {\n const lower = prompt.toLowerCase();\n return /run.*(start|dev|server)|start.*(directus|strapi|server)|npm run (dev|start)|npx.*(start|dev)/.test(lower);\n}\n\nexport interface SystemPromptOptions {\n projectPath?: string;\n prompt?: string;\n isResume?: boolean;\n attemptCount?: number;\n outputFormat?: string; // File extension: json, html, md, csv, tsv, txt, xml, etc.\n outputSchema?: string;\n attemptId?: string;\n outputFilePath?: string; // Absolute path to output file (without extension)\n}\n\n/**\n * Get system prompt - only includes BGPID rule for server tasks\n * SDK handles all other documentation (Tools, Skills, MCP, etc.)\n */\nexport function getSystemPrompt(options: SystemPromptOptions | string = {}): string {\n // Support legacy string parameter (projectPath only)\n if (typeof options === 'string') {\n return ENGINEERING_SYSTEM_PROMPT;\n }\n\n const { prompt, outputFormat, outputSchema, attemptId, outputFilePath } = options;\n\n // Base prompt is always included\n let finalPrompt = ENGINEERING_SYSTEM_PROMPT;\n\n // Add output format instructions if specified\n if (outputFormat && attemptId) {\n const formatInstructions = getOutputFormatInstructions(outputFormat, outputSchema, attemptId, outputFilePath);\n finalPrompt += '\\n' + formatInstructions;\n }\n\n // Add server-specific hints if task involves starting a server\n if (prompt && isServerTask(prompt) && TASK_HINTS.server) {\n finalPrompt += '\\n' + TASK_HINTS.server;\n }\n\n return finalPrompt;\n}\n\n/**\n * Get output format instructions for Claude\n */\nfunction getOutputFormatInstructions(\n format: string,\n schema: string | undefined,\n attemptId: string,\n outputFilePath?: string // Absolute path to output file (without extension)\n): string {\n // Use absolute path if provided, otherwise fall back to relative path\n const filePath = outputFilePath || `data/tmp/${attemptId}`;\n\n // Schema provided - include format specification in instructions\n if (schema) {\n return `## OUTPUT FORMAT: ${format.toUpperCase()}\nYou MUST save your work results to a ${format.toUpperCase()} file at \\`${filePath}.${format}\\`.\n\nFormat specification:\n${schema}\n\nCRITICAL: Your task is INCOMPLETE until you:\n1. Write your generated results to the file using the Write tool\n2. Read back the file to verify it matches the format specification\n\nThe file MUST contain your actual work output - not empty, not placeholders.`;\n }\n\n // Generic output format - use the format string as file extension\n // SDK agent understands common formats: csv, tsv, txt, xml, log, etc.\n return `## OUTPUT FORMAT: ${format.toUpperCase()}\nYou MUST save your work results to a ${format.toUpperCase()} file at \\`${filePath}.${format}\\`.\nWrite valid ${format.toUpperCase()} format that follows standard conventions for this file type.\nInclude your work summary, files changed, and results in the file.\n\nCRITICAL: Your task is INCOMPLETE until you:\n1. Write your generated results to the file using the Write tool\n2. Read back the file to verify it is valid ${format.toUpperCase()}\n\nThe file MUST contain your actual work output - not empty, not placeholders.`;\n}\n","/**\n * Claude SDK Provider - Uses @anthropic-ai/claude-agent-sdk query()\n *\n * Orchestrator: delegates MCP loading, model alias resolution, and query\n * option construction to focused sub-modules. Owns session lifecycle,\n * AskUserQuestion promise coordination, and event emission.\n *\n * Sub-modules:\n * - MCP config loader → claude-sdk-mcp-config-loader.ts\n * - Model alias utils → claude-sdk-model-alias-and-server-command-utils.ts\n * - Query opts builder → claude-sdk-query-options-builder.ts\n */\n\nimport { EventEmitter } from 'events';\nimport { query, type Query } from '@anthropic-ai/claude-agent-sdk';\nimport { adaptSDKMessage, isValidSDKMessage, type SDKResultMessage } from '../sdk-event-adapter';\nimport { createLogger } from '../logger';\nimport { loadMCPConfig, getMCPToolWildcards } from './claude-sdk-mcp-config-loader';\nimport { resolveModel } from './claude-sdk-model-alias-and-server-command-utils';\nimport { buildQueryOptions, buildCanUseToolCallback } from './claude-sdk-query-options-builder';\nimport type { Provider, ProviderSession, ProviderStartOptions, ProviderEventData, ProviderId } from './types';\n\nconst log = createLogger('SDKProvider');\n\ninterface PendingQuestion {\n toolUseId: string;\n resolve: (answer: { questions: unknown[]; answers: Record<string, string> } | null) => void;\n}\n\nclass SDKSession implements ProviderSession {\n readonly providerId: ProviderId = 'claude-sdk';\n sessionId: string | undefined;\n outputFormat?: string;\n queryRef?: Query;\n constructor(readonly attemptId: string, readonly controller: AbortController, outputFormat?: string) {\n this.outputFormat = outputFormat;\n }\n cancel(): void {\n if (this.queryRef) { try { this.queryRef.close(); } catch { this.controller.abort(); } }\n else { this.controller.abort(); }\n }\n}\n\nexport class ClaudeSDKProvider extends EventEmitter implements Provider {\n readonly id: ProviderId = 'claude-sdk';\n private sessions = new Map<string, SDKSession>();\n private pendingQuestions = new Map<string, PendingQuestion>();\n private pendingQuestionData = new Map<string, { toolUseId: string; questions: unknown[]; timestamp: number }>();\n\n resolveModel(displayModelId: string): string { return resolveModel(displayModelId); }\n\n async start(options: ProviderStartOptions): Promise<ProviderSession> {\n const { attemptId, projectPath, prompt, sessionOptions, maxTurns, model, systemPromptAppend, outputFormat } = options;\n const controller = new AbortController();\n const session = new SDKSession(attemptId, controller, outputFormat);\n this.sessions.set(attemptId, session);\n this.runQuery(session, projectPath, prompt, sessionOptions, maxTurns, model, systemPromptAppend);\n return session;\n }\n\n private makeCanUseTool(attemptId: string) {\n return buildCanUseToolCallback(\n attemptId,\n () => this.pendingQuestions.has(attemptId),\n (toolUseId, questions) => {\n this.pendingQuestionData.set(attemptId, { toolUseId, questions, timestamp: Date.now() });\n this.emit('question', { attemptId, toolUseId, questions });\n },\n (toolUseId) => new Promise<{ questions: unknown[]; answers: Record<string, string> } | null>(resolve => {\n this.pendingQuestions.set(attemptId, { toolUseId, resolve });\n }).then(answer => {\n this.pendingQuestions.delete(attemptId);\n this.pendingQuestionData.delete(attemptId);\n return answer;\n }),\n );\n }\n\n private async runQuery(\n session: SDKSession, projectPath: string, prompt: string,\n sessionOptions?: { resume?: string; resumeSessionAt?: string },\n maxTurns?: number, model?: string, systemPromptAppend?: string,\n ): Promise<void> {\n const { attemptId, controller } = session;\n try {\n const mcpConfig = loadMCPConfig(projectPath);\n const mcpToolWildcards = mcpConfig?.mcpServers ? getMCPToolWildcards(mcpConfig.mcpServers) : [];\n const effectiveModel = model ? this.resolveModel(model) : 'opus';\n\n const opts = buildQueryOptions({\n projectPath, model: effectiveModel, sessionOptions, maxTurns,\n mcpServers: mcpConfig?.mcpServers, mcpToolWildcards, controller,\n canUseToolCallback: this.makeCanUseTool(attemptId),\n });\n\n log.info({\n endpoint: process.env.ANTHROPIC_BASE_URL || 'https://api.anthropic.com',\n prompt: prompt.substring(0, 200) + (prompt.length > 200 ? '...' : ''),\n model: opts.model, cwd: opts.cwd,\n }, 'SDK Query starting');\n\n const response = query({ prompt, options: opts });\n session.queryRef = response;\n\n for await (const message of response) {\n if (controller.signal.aborted) break;\n try {\n if (!isValidSDKMessage(message)) continue;\n const adapted = adaptSDKMessage(message);\n if (adapted.sessionId) session.sessionId = adapted.sessionId;\n this.emit('message', {\n attemptId, output: adapted.output, sessionId: adapted.sessionId,\n checkpointUuid: adapted.checkpointUuid, backgroundShell: adapted.backgroundShell,\n resultMessage: message.type === 'result' ? message as SDKResultMessage : undefined,\n usageEvent: adapted.usageEvent,\n rawMessage: message,\n });\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'Unknown message error';\n log.error({ err, message: msg }, 'Message processing error');\n if (!msg.includes('Unexpected end of JSON')) this.emit('stderr', { attemptId, content: `Warning: ${msg}` });\n }\n }\n\n this.cleanupPendingQuestions(attemptId);\n this.sessions.delete(attemptId);\n this.emit('complete', { attemptId, sessionId: session.sessionId });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n const errorName = error instanceof Error ? error.name : 'UnknownError';\n const wasResuming = !!sessionOptions?.resume;\n log.error({ err: error, message: errorMessage, attemptId }, 'SDK Error - Query failed');\n if (wasResuming && !controller.signal.aborted) {\n log.warn({ attemptId }, 'Resume failed, retrying without resume');\n this.sessions.set(attemptId, session);\n return this.runQuery(session, projectPath, prompt, undefined, maxTurns, model, systemPromptAppend);\n }\n const isPromptTooLong = errorMessage.toLowerCase().includes('prompt is too long') ||\n errorMessage.toLowerCase().includes('request too large');\n this.cleanupPendingQuestions(attemptId);\n this.sessions.delete(attemptId);\n this.emit('error', { attemptId, error: errorMessage, errorName, isPromptTooLong, wasResuming });\n }\n }\n\n answerQuestion(attemptId: string, toolUseId: string | undefined, questions: unknown[], answers: Record<string, string>): boolean {\n const pending = this.pendingQuestions.get(attemptId);\n if (!pending) return false;\n if (toolUseId && pending.toolUseId !== toolUseId) {\n log.warn({ attemptId, expected: pending.toolUseId, received: toolUseId }, 'Rejecting stale answer');\n return false;\n }\n pending.resolve({ questions, answers });\n this.pendingQuestions.delete(attemptId);\n this.pendingQuestionData.delete(attemptId);\n this.emit('questionResolved', { attemptId });\n return true;\n }\n\n cancelQuestion(attemptId: string): boolean {\n const pending = this.pendingQuestions.get(attemptId);\n if (!pending) return false;\n pending.resolve(null);\n this.pendingQuestions.delete(attemptId);\n this.pendingQuestionData.delete(attemptId);\n this.emit('questionResolved', { attemptId });\n return true;\n }\n\n hasPendingQuestion(attemptId: string): boolean { return this.pendingQuestions.has(attemptId); }\n\n getPendingQuestionData(attemptId: string): { toolUseId: string; questions: unknown[]; timestamp: number } | null {\n return this.pendingQuestionData.get(attemptId) || null;\n }\n\n cancelSession(attemptId: string): boolean {\n const session = this.sessions.get(attemptId);\n if (!session) return false;\n this.cleanupPendingQuestions(attemptId);\n session.cancel();\n this.sessions.delete(attemptId);\n return true;\n }\n\n private cleanupPendingQuestions(attemptId: string): void {\n const pending = this.pendingQuestions.get(attemptId);\n if (pending) { pending.resolve(null); this.pendingQuestions.delete(attemptId); this.pendingQuestionData.delete(attemptId); }\n }\n\n override on<K extends keyof ProviderEventData>(event: K, listener: (data: ProviderEventData[K]) => void): this {\n return super.on(event, listener as (...args: unknown[]) => void);\n }\n\n override emit<K extends keyof ProviderEventData>(event: K, data: ProviderEventData[K]): boolean {\n return super.emit(event, data);\n }\n}\n","/**\n * Claude SDK message-to-output adapter — normalizes SDK stream messages to internal ClaudeOutput format.\n * Handles system, assistant, user, result, and stream_event message types.\n * Detects AskUserQuestion tool use and background shell (run_in_background=true).\n */\n\nimport { createLogger } from '../lib/pino-logger';\nimport type { BackgroundShellInfo } from './agent-start-options-and-event-types';\n\nconst log = createLogger('SDKAdapter');\n\n// --- SDK message types ---\n\nexport interface MCPServerStatus {\n name: string;\n status: 'connected' | 'failed' | 'connecting';\n error?: string;\n tools?: string[];\n}\n\nexport interface SDKSystemMessage {\n type: 'system';\n subtype: 'init' | string;\n session_id?: string;\n tools?: unknown[];\n mcp_servers?: MCPServerStatus[];\n}\n\nexport interface SDKAssistantMessage {\n type: 'assistant';\n message: {\n id?: string;\n role: 'assistant';\n content: SDKContentBlock[];\n model?: string;\n stop_reason?: string;\n usage?: { input_tokens: number; output_tokens: number };\n };\n}\n\nexport interface SDKUserMessage {\n type: 'user';\n message: { role: 'user'; content: SDKContentBlock[] };\n uuid?: string; // Checkpoint UUID (when replay-user-messages enabled)\n}\n\nexport interface SDKResultMessage {\n type: 'result';\n subtype: string;\n session_id?: string;\n cost_usd?: number;\n is_error?: boolean;\n duration_ms?: number;\n num_turns?: number;\n}\n\nexport interface SDKStreamEvent {\n type: 'stream_event';\n event: {\n type: string;\n index?: number;\n delta?: {\n type: 'text_delta' | 'thinking_delta' | 'input_json_delta';\n text?: string;\n thinking?: string;\n };\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n };\n message?: {\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n };\n };\n };\n}\n\nexport interface SDKContentBlock {\n type: 'text' | 'thinking' | 'tool_use' | 'tool_result';\n text?: string;\n thinking?: string;\n id?: string;\n name?: string;\n input?: unknown;\n tool_use_id?: string;\n content?: string | unknown[];\n is_error?: boolean;\n}\n\nexport type SDKMessage =\n | SDKSystemMessage\n | SDKAssistantMessage\n | SDKUserMessage\n | SDKResultMessage\n | SDKStreamEvent\n | { type: string; [key: string]: unknown };\n\nexport interface ClaudeOutput {\n type: string;\n [key: string]: unknown;\n}\n\nexport interface UsageEvent {\n input_tokens: number;\n output_tokens: number;\n cache_read_input_tokens: number;\n cache_creation_input_tokens: number;\n}\n\nexport interface AdaptedMessage {\n output: ClaudeOutput;\n sessionId?: string;\n checkpointUuid?: string;\n askUserQuestion?: { toolUseId: string; questions: unknown[] };\n backgroundShell?: BackgroundShellInfo;\n usageEvent?: UsageEvent;\n}\n\n// --- Type guard ---\n\nexport function isValidSDKMessage(msg: unknown): msg is SDKMessage {\n if (typeof msg !== 'object' || msg === null) return false;\n if (!('type' in msg)) return false;\n return typeof (msg as { type: unknown }).type === 'string';\n}\n\n// --- Internal helpers ---\n\nfunction detectAskUserQuestion(\n content: SDKContentBlock[]\n): { toolUseId: string; questions: unknown[] } | undefined {\n for (const block of content) {\n if (block.type === 'tool_use' && block.name === 'AskUserQuestion') {\n return {\n toolUseId: block.id || '',\n questions: (block.input as { questions?: unknown[] })?.questions || [],\n };\n }\n }\n return undefined;\n}\n\nfunction detectBackgroundShell(content: SDKContentBlock[]): BackgroundShellInfo | undefined {\n // Method 1: Bash tool_use with run_in_background=true\n for (const block of content) {\n if (block.type === 'tool_use' && block.name === 'Bash') {\n const input = block.input as { command?: string; run_in_background?: boolean; description?: string } | undefined;\n if (input?.run_in_background === true && input?.command) {\n log.info({ commandPreview: input.command.substring(0, 50) }, 'Background shell detected via run_in_background=true');\n return { toolUseId: block.id || '', command: input.command, description: input.description };\n }\n }\n }\n // Method 2: Markdown ```background-shell``` code block\n for (const block of content) {\n if (block.type === 'text' && block.text) {\n const match = block.text.match(/```background-shell\\n([\\s\\S]+?)\\n```/);\n if (match) {\n const command = match[1].trim();\n if (command) {\n return { toolUseId: `bg-shell-${Date.now()}`, command, description: 'Background shell from markdown block' };\n }\n }\n }\n }\n return undefined;\n}\n\n// --- Main adapter ---\n\nexport function adaptSDKMessage(message: SDKMessage): AdaptedMessage {\n const result: AdaptedMessage = { output: { type: message.type } };\n\n switch (message.type) {\n case 'system': {\n const sys = message as SDKSystemMessage;\n result.output = { type: 'system', subtype: sys.subtype, session_id: sys.session_id };\n if (sys.subtype === 'init' && sys.session_id) result.sessionId = sys.session_id;\n if (sys.subtype === 'init' && sys.mcp_servers) {\n for (const s of sys.mcp_servers) {\n if (s.status === 'connected') log.info({ name: s.name }, `MCP connected: ${s.name}`);\n else if (s.status === 'failed') log.error({ name: s.name, error: s.error }, `MCP failed: ${s.name}`);\n }\n }\n break;\n }\n case 'assistant': {\n const asst = message as SDKAssistantMessage;\n result.output = {\n type: 'assistant',\n message: { role: 'assistant', content: asst.message.content },\n };\n const askQ = detectAskUserQuestion(asst.message.content);\n if (askQ) result.askUserQuestion = askQ;\n const bgShell = detectBackgroundShell(asst.message.content);\n if (bgShell) result.backgroundShell = bgShell;\n break;\n }\n case 'user': {\n const user = message as SDKUserMessage;\n result.output = { type: 'user', message: { role: 'user', content: user.message.content } };\n if (user.uuid) result.checkpointUuid = user.uuid;\n break;\n }\n case 'result': {\n const res = message as SDKResultMessage;\n result.output = { type: 'result', subtype: res.subtype, session_id: res.session_id, is_error: res.is_error };\n if (res.session_id) result.sessionId = res.session_id;\n break;\n }\n case 'stream_event': {\n const stream = message as SDKStreamEvent;\n const event = stream.event;\n if (event.type === 'content_block_delta' && event.delta) {\n if (event.delta.type === 'text_delta' && event.delta.text) {\n result.output = { type: 'content_block_delta', index: event.index, delta: { type: 'text_delta', text: event.delta.text } };\n } else if (event.delta.type === 'thinking_delta' && event.delta.thinking) {\n result.output = { type: 'content_block_delta', index: event.index, delta: { type: 'thinking_delta', thinking: event.delta.thinking } };\n }\n }\n // Capture usage from message_delta events (per-turn token counts from the API)\n if (event.type === 'message_delta' && event.usage) {\n result.usageEvent = {\n input_tokens: event.usage.input_tokens || 0,\n output_tokens: event.usage.output_tokens || 0,\n cache_read_input_tokens: event.usage.cache_read_input_tokens || 0,\n cache_creation_input_tokens: event.usage.cache_creation_input_tokens || 0,\n };\n }\n // Capture usage from message_start events (initial context size)\n if (event.type === 'message_start' && event.message?.usage) {\n result.usageEvent = {\n input_tokens: event.message.usage.input_tokens || 0,\n output_tokens: event.message.usage.output_tokens || 0,\n cache_read_input_tokens: event.message.usage.cache_read_input_tokens || 0,\n cache_creation_input_tokens: event.message.usage.cache_creation_input_tokens || 0,\n };\n }\n break;\n }\n default:\n result.output = { type: message.type };\n }\n\n return result;\n}\n","/**\n * Re-export from agentic-sdk shared module, with type bridge for claude-ws ClaudeOutput.\n * Consumers import from './sdk-event-adapter' — this shim keeps those imports working.\n */\n\nimport {\n adaptSDKMessage as _adaptSDKMessage,\n type AdaptedMessage as _AdaptedMessage,\n} from '../../packages/agentic-sdk/src/agent/claude-sdk-message-to-output-adapter';\nimport type { ClaudeOutput } from '../types';\n\n// Re-export SDK types directly\nexport type {\n MCPServerStatus,\n SDKSystemMessage,\n SDKAssistantMessage,\n SDKUserMessage,\n SDKResultMessage,\n SDKStreamEvent,\n SDKContentBlock,\n SDKMessage,\n UsageEvent,\n} from '../../packages/agentic-sdk/src/agent/claude-sdk-message-to-output-adapter';\n\nexport { isValidSDKMessage } from '../../packages/agentic-sdk/src/agent/claude-sdk-message-to-output-adapter';\n\n// Re-export BackgroundShellInfo from its canonical location\nexport type { BackgroundShellInfo } from '../../packages/agentic-sdk/src/agent/agent-start-options-and-event-types';\n\n// Bridge AdaptedMessage to use claude-ws's ClaudeOutput type\nexport interface AdaptedMessage extends Omit<_AdaptedMessage, 'output'> {\n output: ClaudeOutput;\n}\n\n/** Wraps agentic-sdk adapter, casting output to claude-ws ClaudeOutput type */\nexport function adaptSDKMessage(message: Parameters<typeof _adaptSDKMessage>[0]): AdaptedMessage {\n return _adaptSDKMessage(message) as unknown as AdaptedMessage;\n}\n","/**\n * MCP Configuration Loader for Claude SDK Provider\n *\n * Loads MCP server configurations from:\n * 1. ~/.claude.json (global + per-project)\n * 2. <projectPath>/.mcp.json (project-local)\n *\n * Merges and interpolates environment variables in server configs.\n */\n\nimport { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport { createLogger } from '../logger';\n\nconst log = createLogger('SDKProvider:MCP');\n\n// --- MCP Configuration Types ---\n\nexport interface MCPStdioServerConfig {\n type?: 'stdio';\n command: string;\n args?: string[];\n env?: Record<string, string>;\n}\n\nexport interface MCPHttpServerConfig {\n type: 'http';\n url: string;\n headers?: Record<string, string>;\n}\n\nexport interface MCPSSEServerConfig {\n type: 'sse';\n url: string;\n headers?: Record<string, string>;\n}\n\nexport type MCPServerConfig = MCPStdioServerConfig | MCPHttpServerConfig | MCPSSEServerConfig;\n\nexport interface MCPConfig {\n mcpServers?: Record<string, MCPServerConfig>;\n}\n\n// --- Loader Functions ---\n\nfunction loadSingleMCPConfig(configPath: string): Record<string, MCPServerConfig> | null {\n if (!existsSync(configPath)) return null;\n\n try {\n const content = readFileSync(configPath, 'utf-8');\n let config = JSON.parse(content) as MCPConfig;\n\n if (!config.mcpServers) {\n const keys = Object.keys(config);\n const looksLikeServers = keys.some(key => {\n const val = (config as Record<string, unknown>)[key];\n return val && typeof val === 'object' && ('command' in val || 'url' in val || 'type' in val);\n });\n if (looksLikeServers) {\n config = { mcpServers: config as unknown as Record<string, MCPServerConfig> };\n }\n }\n\n return config.mcpServers || null;\n } catch (error) {\n log.warn({ err: error, path: configPath }, 'Failed to parse config file');\n return null;\n }\n}\n\nfunction interpolateEnvVars(servers: Record<string, MCPServerConfig>): void {\n for (const [, serverConfig] of Object.entries(servers)) {\n if ('env' in serverConfig && serverConfig.env) {\n for (const [key, value] of Object.entries(serverConfig.env)) {\n if (typeof value === 'string' && value.startsWith('${') && value.endsWith('}')) {\n const envVar = value.slice(2, -1);\n serverConfig.env[key] = process.env[envVar] || '';\n }\n }\n }\n if ('headers' in serverConfig && serverConfig.headers) {\n for (const [key, value] of Object.entries(serverConfig.headers)) {\n if (typeof value === 'string' && value.includes('${')) {\n serverConfig.headers[key] = value.replace(/\\$\\{([^}]+)\\}/g, (_, envVar) => process.env[envVar] || '');\n }\n }\n }\n }\n}\n\n/**\n * Load and merge MCP server configs from global ~/.claude.json and project .mcp.json.\n * Returns null if no servers are found.\n */\nexport function loadMCPConfig(projectPath: string): MCPConfig | null {\n const claudeConfigPath = join(homedir(), '.claude.json');\n const projectConfigPath = join(projectPath, '.mcp.json');\n let userServers: Record<string, MCPServerConfig> | null = null;\n\n if (existsSync(claudeConfigPath)) {\n try {\n const content = readFileSync(claudeConfigPath, 'utf-8');\n const config = JSON.parse(content);\n\n if (config.mcpServers && typeof config.mcpServers === 'object' && Object.keys(config.mcpServers).length > 0) {\n userServers = config.mcpServers as Record<string, MCPServerConfig>;\n log.info({ servers: Object.keys(userServers || {}), path: claudeConfigPath }, 'Loaded global MCP config');\n }\n\n if (config.projects && config.projects[projectPath]?.mcpServers) {\n const projectServers = config.projects[projectPath].mcpServers as Record<string, MCPServerConfig>;\n if (Object.keys(projectServers).length > 0) {\n userServers = { ...(userServers || {}), ...projectServers };\n log.info({ servers: Object.keys(projectServers), projectPath }, 'Loaded CLI project MCP config');\n }\n }\n } catch (error) {\n log.warn({ err: error, path: claudeConfigPath }, 'Failed to parse config file');\n }\n }\n\n const projectServers = loadSingleMCPConfig(projectConfigPath);\n if (projectServers) {\n log.info({ servers: Object.keys(projectServers), path: projectConfigPath }, 'Loaded project MCP config');\n }\n\n const mergedServers: Record<string, MCPServerConfig> = {\n ...(userServers || {}),\n ...(projectServers || {}),\n };\n\n if (Object.keys(mergedServers).length === 0) {\n log.info('No MCP servers found in user or project config');\n return null;\n }\n\n interpolateEnvVars(mergedServers);\n log.info({ servers: Object.keys(mergedServers) }, 'Merged MCP servers');\n return { mcpServers: mergedServers };\n}\n\n/**\n * Derive tool wildcard patterns from MCP server names.\n * e.g. serverName \"playwright\" → \"mcp__playwright__*\"\n */\nexport function getMCPToolWildcards(mcpServers: Record<string, MCPServerConfig>): string[] {\n return Object.keys(mcpServers).map(serverName => `mcp__${serverName}__*`);\n}\n","/**\n * Model Alias Mapper and Server Command Detector for Claude SDK Provider\n *\n * - MODEL_ALIAS_MAP: maps full model IDs to short SDK aliases (opus, sonnet, haiku)\n * - resolveModel: translates a display model ID to the SDK-expected alias\n * - isServerCommand: detects long-running server commands that need BGPID fix\n */\n\n// --- Model Alias Mapping ---\n\nconst MODEL_ALIAS_MAP: Record<string, string> = {\n 'claude-opus-4-6': 'opus',\n 'claude-sonnet-4-5-20250929': 'sonnet',\n 'claude-haiku-4-5-20251001': 'haiku',\n 'claude-3-5-sonnet-20241022': 'sonnet',\n};\n\n/**\n * Translate a full display model ID to its SDK short alias.\n * Falls back to the original ID if no mapping exists.\n */\nexport function resolveModel(displayModelId: string): string {\n return MODEL_ALIAS_MAP[displayModelId] || displayModelId;\n}\n\n// --- Server Command Detection ---\n\nconst SERVER_PATTERNS = [\n /npm\\s+run\\s+(dev|start|serve)/i,\n /yarn\\s+(dev|start|serve)/i,\n /pnpm\\s+(dev|start|serve)/i,\n /npx\\s+(directus|strapi|next|vite|nuxt)/i,\n /nohup\\s+/i,\n];\n\n/**\n * Detect whether a Bash command launches a long-running server process\n * that requires the BGPID background PID fix.\n */\nexport function isServerCommand(command: string): boolean {\n return SERVER_PATTERNS.some(p => p.test(command));\n}\n","/**\n * Query Options Builder for Claude SDK Provider\n *\n * Constructs the full options object passed to the SDK query() call, including:\n * - allowed tools list (built-ins + MCP wildcards)\n * - session resume/resumeSessionAt passthrough\n * - checkpoint options\n * - canUseTool callback factory (AskUserQuestion gate + Bash BGPID fix)\n * - subprocess environment (strips proxy/session detection vars)\n * - system prompt preset\n */\n\nimport { mkdirSync } from 'fs';\nimport { resolve } from 'path';\nimport { checkpointManager } from '../checkpoint-manager';\nimport { createLogger } from '../logger';\nimport { isServerCommand } from './claude-sdk-model-alias-and-server-command-utils';\nimport type { MCPServerConfig } from './claude-sdk-mcp-config-loader';\n\nconst log = createLogger('SDKProvider:QueryBuilder');\n\nexport interface AskUserQuestionAnswer {\n questions: unknown[];\n answers: Record<string, string>;\n}\n\nexport type CanUseToolCallback = (toolName: string, input: Record<string, unknown>) => Promise<\n | { behavior: 'allow'; updatedInput: Record<string, unknown> }\n | { behavior: 'deny'; message: string }\n>;\n\nexport interface QueryOptionsBuilderParams {\n projectPath: string;\n model: string;\n sessionOptions?: { resume?: string; resumeSessionAt?: string };\n maxTurns?: number;\n systemPromptAppend?: string;\n mcpServers?: Record<string, MCPServerConfig>;\n mcpToolWildcards: string[];\n controller: AbortController;\n canUseToolCallback: CanUseToolCallback;\n}\n\n/**\n * Build the options object for SDK query(), minus prompt.\n */\nexport function buildQueryOptions(params: QueryOptionsBuilderParams) {\n const {\n projectPath, model, sessionOptions, maxTurns,\n mcpServers, mcpToolWildcards, controller, canUseToolCallback,\n } = params;\n\n const checkpointOptions = checkpointManager.getCheckpointingOptions();\n\n // SDK has its own bundled cli.js — no need to find an external Claude CLI executable.\n // Use process.execPath (absolute node path) so SDK spawn works under PM2/systemd with nvm.\n const queryOptions = {\n executable: process.execPath as 'node',\n cwd: projectPath,\n model,\n permissionMode: 'bypassPermissions' as const,\n ...(mcpServers ? { mcpServers } : {}),\n allowedTools: [\n 'Skill', 'Task',\n 'Read', 'Write', 'Edit', 'NotebookEdit',\n 'Bash', 'Grep', 'Glob',\n 'WebFetch', 'WebSearch',\n 'TodoWrite', 'AskUserQuestion',\n ...mcpToolWildcards,\n ],\n ...(sessionOptions?.resume ? { resume: sessionOptions.resume } : {}),\n ...(sessionOptions?.resumeSessionAt ? { resumeSessionAt: sessionOptions.resumeSessionAt } : {}),\n ...checkpointOptions,\n ...(maxTurns ? { maxTurns } : {}),\n abortController: controller,\n canUseTool: canUseToolCallback,\n env: buildIsolatedSubprocessEnv(model),\n };\n\n log.debug({ model, cwd: projectPath, mcpCount: mcpToolWildcards.length }, 'Query options built');\n return queryOptions;\n}\n\n/**\n * Build the canUseTool callback that:\n * 1. Gates AskUserQuestion via a promise resolved by answerQuestion()\n * 2. Injects BGPID capture for server Bash commands\n */\nexport function buildCanUseToolCallback(\n attemptId: string,\n hasPending: () => boolean,\n registerQuestion: (toolUseId: string, questions: unknown[]) => void,\n waitForAnswer: (toolUseId: string) => Promise<AskUserQuestionAnswer | null>,\n): CanUseToolCallback {\n return async (toolName: string, input: Record<string, unknown>) => {\n log.debug({ toolName, attemptId }, 'canUseTool called');\n\n if (toolName === 'AskUserQuestion') {\n if (hasPending()) {\n return { behavior: 'deny', message: 'Duplicate question' };\n }\n const toolUseId = `ask-${Date.now()}`;\n const questions = (input.questions as unknown[]) || [];\n registerQuestion(toolUseId, questions);\n\n const answer = await waitForAnswer(toolUseId);\n\n if (!answer || Object.keys(answer.answers).length === 0) {\n return { behavior: 'deny', message: 'User cancelled' };\n }\n return { behavior: 'allow', updatedInput: answer as unknown as Record<string, unknown> };\n }\n\n // Bash BGPID fix — intercept server commands missing background PID capture\n if (toolName === 'Bash') {\n const command = input.command as string | undefined;\n if (command && isServerCommand(command) && !command.includes('echo \"BGPID:$!\"')) {\n if (/>\\s*\\/tmp\\/[^\\s]+\\.log\\s*$/.test(command)) {\n const fixedCommand = command.trim() + ' 2>&1 & echo \"BGPID:$!\"';\n log.debug({ fixedCommand }, 'Fixed BGPID pattern');\n return { behavior: 'allow', updatedInput: { ...input, command: fixedCommand } };\n }\n }\n }\n\n return { behavior: 'allow', updatedInput: input };\n };\n}\n\n// ─── Isolated Subprocess Environment ─────────────────────────────────────────\n\n/**\n * Vars to strip from subprocess env to prevent the SDK CLI from:\n * - Detecting a nested Claude Code session (CLAUDECODE)\n * - Inheriting Claude Code entrypoint metadata\n * - Loading remote MCP servers via claude.ai auth tokens\n * - Picking up ClaudeKit plugin state\n */\nconst STRIPPED_ENV_PREFIXES = [\n 'CLAUDECODE', // nested session detection\n 'CLAUDE_CODE_ENTRYPOINT', // entrypoint metadata\n 'CK_', // ClaudeKit plugin vars\n];\n\n/**\n * Build a clean env for the SDK subprocess.\n * Keeps all system/LLM vars, strips session/auth/plugin vars,\n * and redirects CLAUDE_CONFIG_DIR to an isolated empty dir\n * so the CLI can't fetch remote MCP servers from claude.ai.\n */\nfunction buildIsolatedSubprocessEnv(model: string): Record<string, string | undefined> {\n const env: Record<string, string | undefined> = {};\n\n for (const [key, value] of Object.entries(process.env)) {\n // Skip vars that leak session state or plugin config\n if (STRIPPED_ENV_PREFIXES.some(prefix => key.startsWith(prefix))) continue;\n env[key] = value;\n }\n\n // Override model for the subprocess\n env.ANTHROPIC_MODEL = model;\n\n // Point CLI config to an isolated dir so it has no auth tokens\n // and cannot fetch remote MCP servers from claude.ai\n // Must be absolute so SDK subprocess (cwd=projectPath) resolves the same location\n const isolatedConfigDir = resolve(\n process.env.DATA_DIR || './data',\n 'claude-sdk-isolated-config'\n );\n try { mkdirSync(isolatedConfigDir, { recursive: true }); } catch { /* exists */ }\n env.CLAUDE_CONFIG_DIR = isolatedConfigDir;\n\n return env;\n}\n","/**\n * Claude CLI Provider - Spawns Claude CLI with stream-json protocol\n *\n * Orchestrator: delegates process spawning and stdout parsing to focused\n * sub-modules. Owns session lifecycle, AskUserQuestion coordination,\n * and event emission.\n *\n * Sub-modules:\n * - CLISession / PendingQuestion → claude-cli-session-and-pending-question-types.ts\n * - Process spawner → claude-cli-process-spawner.ts\n * - Stdout line parser → claude-cli-stdout-line-to-provider-event-parser.ts\n */\n\nimport { EventEmitter } from 'events';\nimport { findClaudePath } from '../cli-query';\nimport { createLogger } from '../logger';\nimport { CLISession } from './claude-cli-session-and-pending-question-types';\nimport { spawnCLIProcess, sendInitialPrompt } from './claude-cli-process-spawner';\nimport { parseCLILine } from './claude-cli-stdout-line-to-provider-event-parser';\nimport type { Provider, ProviderSession, ProviderStartOptions, ProviderEventData, ProviderId } from './types';\n\nconst log = createLogger('CLIProvider');\n\nexport class ClaudeCLIProvider extends EventEmitter implements Provider {\n readonly id: ProviderId = 'claude-cli';\n\n private sessions = new Map<string, CLISession>();\n\n resolveModel(displayModelId: string): string {\n return displayModelId; // CLI accepts full model IDs directly\n }\n\n async start(options: ProviderStartOptions): Promise<ProviderSession> {\n const { attemptId, projectPath, prompt, sessionOptions, maxTurns, model, systemPromptAppend, outputFormat } = options;\n\n const claudePath = findClaudePath();\n if (!claudePath) {\n const error = 'Claude CLI not found. Set CLAUDE_PATH in your .env file.';\n this.emit('error', { attemptId, error, errorName: 'CLINotFound' });\n throw new Error(error);\n }\n\n const child = spawnCLIProcess({\n claudePath, projectPath, model, attemptId,\n sessionResume: sessionOptions?.resume,\n maxTurns, systemPromptAppend,\n });\n\n const session = new CLISession(attemptId, child, outputFormat);\n this.sessions.set(attemptId, session);\n sendInitialPrompt(child, prompt);\n\n let buffer = '';\n\n child.stdout?.on('data', (chunk: Buffer) => {\n buffer += chunk.toString();\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n for (const line of lines) {\n if (line.trim()) this.processLine(session, line);\n }\n });\n\n child.stderr?.on('data', (chunk: Buffer) => {\n const content = chunk.toString();\n log.debug({ attemptId, content: content.substring(0, 200) }, 'stderr received');\n this.emit('stderr', { attemptId, content });\n });\n\n child.on('error', (err) => {\n log.error({ attemptId, err }, 'Process error');\n this.sessions.delete(attemptId);\n this.emit('error', { attemptId, error: err.message, errorName: err.name });\n });\n\n child.on('exit', (code) => {\n log.info({ attemptId, code }, 'Process exited');\n if (buffer.trim()) this.processLine(session, buffer);\n this.sessions.delete(attemptId);\n this.emit('complete', { attemptId, sessionId: session.sessionId });\n });\n\n return session;\n }\n\n private processLine(session: CLISession, line: string): void {\n const { attemptId } = session;\n const parsed = parseCLILine(line, session);\n if (!parsed) return;\n\n if (parsed.messagePayload.sessionId) session.sessionId = parsed.messagePayload.sessionId;\n\n if (parsed.askUserQuestion) {\n const { toolUseId, questions } = parsed.askUserQuestion;\n session.setPendingQuestion({ toolUseId, questions, timestamp: Date.now() });\n session.waitingForUserAnswer = true; // keep stdin open until user answers\n this.emit('question', { attemptId, toolUseId, questions });\n }\n\n // CLI auto-handled AskUserQuestion — clear pending, user's answer will\n // be sent as a follow-up text message via stdin (\"chat about this\" approach)\n if (parsed.cliAutoHandledQuestion) {\n session.setPendingQuestion(null);\n // Strip is_error from auto-handled response so the tool block doesn't show red\n const output = parsed.messagePayload.output as unknown as Record<string, unknown>;\n const msg = output?.message as { content?: Array<{ type: string; is_error?: boolean }> };\n if (msg?.content) {\n for (const block of msg.content) {\n if (block.type === 'tool_result' && block.is_error) {\n delete block.is_error;\n }\n }\n }\n }\n\n this.emit('message', { attemptId, ...parsed.messagePayload });\n\n // Track active background agents from system events\n const rawMessage = parsed.messagePayload.rawMessage as Record<string, unknown>;\n if (rawMessage.type === 'system' && (rawMessage as { subtype?: string }).subtype === 'task_started') {\n session.activeBackgroundAgents = (session.activeBackgroundAgents || 0) + 1;\n log.info({ attemptId, active: session.activeBackgroundAgents }, 'Background agent started');\n }\n if (rawMessage.type === 'system' && (rawMessage as { subtype?: string }).subtype === 'task_notification') {\n session.activeBackgroundAgents = Math.max(0, (session.activeBackgroundAgents || 0) - 1);\n log.info({ attemptId, active: session.activeBackgroundAgents }, 'Background agent notification received');\n }\n\n // Close stdin on result message so CLI process can exit naturally\n if (parsed.isResultMessage) {\n // Don't close stdin if user hasn't answered AskUserQuestion popup yet —\n // keep the session alive so their answer can be sent as a follow-up message\n if (session.waitingForUserAnswer) {\n log.info({ attemptId }, 'Result received but waiting for user answer — keeping stdin open');\n return;\n }\n\n const activeAgents = session.activeBackgroundAgents || 0;\n if (activeAgents > 0) {\n log.info({ attemptId, activeAgents }, 'Result received but background agents still active, delaying stdin close');\n const maxWait = 60000;\n const checkInterval = 2000;\n let waited = 0;\n session.backgroundWaitTimer = setInterval(() => {\n waited += checkInterval;\n const remaining = session.activeBackgroundAgents || 0;\n if (remaining <= 0 || waited >= maxWait) {\n if (session.backgroundWaitTimer) {\n clearInterval(session.backgroundWaitTimer);\n session.backgroundWaitTimer = null;\n }\n log.info({ attemptId, waited, remaining }, 'Closing stdin (background agents done or timeout)');\n session.child.stdin?.end();\n }\n }, checkInterval);\n } else {\n log.info({ attemptId }, 'Result message received, closing stdin');\n session.child.stdin?.end();\n }\n }\n }\n\n answerQuestion(attemptId: string, _toolUseId: string | undefined, _questions: unknown[], answers: Record<string, string>): boolean {\n const session = this.sessions.get(attemptId);\n if (!session) { log.warn({ attemptId }, 'answerQuestion: session not found'); return false; }\n\n // CLI auto-handles AskUserQuestion internally, so we can't inject a tool_result.\n // Instead, send user's answers as a follow-up text message via stdin\n // (equivalent to \"Chat about this\" in CLI interactive mode).\n const answerText = Object.entries(answers)\n .map(([q, a]) => `Q: ${q}\\nA: ${a}`)\n .join('\\n\\n');\n const prompt = `The user answered the previous question:\\n${answerText}\\n\\nPlease continue based on these answers.`;\n\n const success = session.writeUserMessage(prompt);\n if (success) {\n log.info({ attemptId }, 'Answer sent to CLI as follow-up message via stdin');\n session.waitingForUserAnswer = false; // allow stdin close on next result\n session.setPendingQuestion(null);\n this.emit('questionResolved', { attemptId });\n } else {\n log.error({ attemptId }, 'Failed to write answer to CLI stdin (process may have exited)');\n }\n return success;\n }\n\n cancelQuestion(attemptId: string): boolean {\n const session = this.sessions.get(attemptId);\n if (!session) return false;\n const pending = session.getPendingQuestion();\n if (!pending) return false;\n const success = session.writeToolResult(pending.toolUseId, 'User cancelled');\n if (success) {\n session.setPendingQuestion(null);\n this.emit('questionResolved', { attemptId });\n }\n return success;\n }\n\n hasPendingQuestion(attemptId: string): boolean {\n return !!this.sessions.get(attemptId)?.getPendingQuestion();\n }\n\n getPendingQuestionData(attemptId: string): { toolUseId: string; questions: unknown[]; timestamp: number } | null {\n return this.sessions.get(attemptId)?.getPendingQuestion() || null;\n }\n\n cancelSession(attemptId: string): boolean {\n const session = this.sessions.get(attemptId);\n if (!session) return false;\n session.cancel();\n this.sessions.delete(attemptId);\n return true;\n }\n\n override on<K extends keyof ProviderEventData>(event: K, listener: (data: ProviderEventData[K]) => void): this {\n return super.on(event, listener as (...args: unknown[]) => void);\n }\n\n override emit<K extends keyof ProviderEventData>(event: K, data: ProviderEventData[K]): boolean {\n return super.emit(event, data);\n }\n}\n","/**\n * CLI Session and Pending Question Types for Claude CLI Provider\n *\n * CLISession wraps a spawned Claude CLI child process and tracks:\n * - the child process reference for stdin writes and kill signals\n * - the current pending AskUserQuestion (toolUseId, questions, timestamp)\n *\n * PendingQuestion holds the data needed to answer or cancel an in-flight\n * AskUserQuestion intercepted from CLI stdout.\n */\n\nimport { type ChildProcess } from 'child_process';\nimport type { ProviderId, ProviderSession } from './types';\n\n// --- Pending Question ---\n\nexport interface PendingQuestion {\n toolUseId: string;\n questions: unknown[];\n timestamp: number;\n}\n\n// --- CLI Session ---\n\nexport class CLISession implements ProviderSession {\n readonly providerId: ProviderId = 'claude-cli';\n sessionId: string | undefined;\n outputFormat?: string;\n child: ChildProcess;\n activeBackgroundAgents: number = 0;\n /** Timer ref for background agent wait polling — cleared on cancel */\n backgroundWaitTimer: ReturnType<typeof setInterval> | null = null;\n /** True when AskUserQuestion popup is shown but user hasn't answered yet — delays stdin close */\n waitingForUserAnswer = false;\n private pendingQuestion: PendingQuestion | null = null;\n\n constructor(\n readonly attemptId: string,\n child: ChildProcess,\n outputFormat?: string,\n ) {\n this.child = child;\n this.outputFormat = outputFormat;\n }\n\n setPendingQuestion(q: PendingQuestion | null): void {\n this.pendingQuestion = q;\n }\n\n getPendingQuestion(): PendingQuestion | null {\n return this.pendingQuestion;\n }\n\n /**\n * Write a tool_result answer to the CLI process stdin.\n * Returns false if stdin is unavailable or already destroyed.\n */\n writeToolResult(toolUseId: string, content: string): boolean {\n if (!this.child.stdin || this.child.stdin.destroyed) return false;\n const msg = JSON.stringify({\n type: 'user',\n message: {\n role: 'user',\n content: [{ type: 'tool_result', tool_use_id: toolUseId, content }],\n },\n });\n return this.child.stdin.write(msg + '\\n');\n }\n\n /**\n * Write a follow-up text message to the CLI process stdin.\n * Used to send AskUserQuestion answers as a \"Chat about this\" message.\n * Returns false if stdin is unavailable or already destroyed.\n */\n writeUserMessage(text: string): boolean {\n if (!this.child.stdin || this.child.stdin.destroyed) return false;\n const msg = JSON.stringify({\n type: 'user',\n message: {\n role: 'user',\n content: [{ type: 'text', text }],\n },\n });\n return this.child.stdin.write(msg + '\\n');\n }\n\n cancel(): void {\n if (this.backgroundWaitTimer) {\n clearInterval(this.backgroundWaitTimer);\n this.backgroundWaitTimer = null;\n }\n if (this.child && !this.child.killed) {\n this.child.kill('SIGTERM');\n setTimeout(() => {\n if (this.child && !this.child.killed) {\n this.child.kill('SIGKILL');\n }\n }, 3000);\n }\n }\n}\n","/**\n * CLI Process Spawner for Claude CLI Provider\n *\n * Builds the argument list and spawns the Claude CLI child process\n * with the correct stdio, env, and working directory configuration.\n * Extracted from ClaudeCLIProvider.start() to reduce that method's size.\n */\n\nimport { spawn, type ChildProcess } from 'child_process';\nimport { createLogger } from '../logger';\n\nconst log = createLogger('CLIProvider:Spawner');\n\nexport interface SpawnCLIOptions {\n claudePath: string;\n projectPath: string;\n model?: string;\n sessionResume?: string;\n maxTurns?: number;\n systemPromptAppend?: string;\n attemptId: string;\n}\n\n/**\n * Spawn the Claude CLI child process with stream-json I/O.\n * Returns the ChildProcess ready for stdin writes and stdout/stderr listeners.\n */\nexport function spawnCLIProcess(opts: SpawnCLIOptions): ChildProcess {\n const { claudePath, projectPath, model, sessionResume, maxTurns, systemPromptAppend, attemptId } = opts;\n\n const args: string[] = [\n '--input-format', 'stream-json',\n '--output-format', 'stream-json',\n '--verbose',\n '--permission-mode', 'bypassPermissions',\n ];\n\n if (model) args.push('--model', model);\n if (sessionResume) args.push('--resume', sessionResume);\n if (maxTurns) args.push('--max-turns', String(maxTurns));\n if (systemPromptAppend) args.push('--append-system-prompt', systemPromptAppend);\n\n // Normalize path for Windows\n const normalizedProjectPath = process.platform === 'win32'\n ? projectPath.replace(/\\//g, '\\\\')\n : projectPath;\n\n log.info({ claudePath, argsCount: args.length, attemptId }, 'Spawning CLI process');\n\n // Strip SDK-specific env vars so CLI uses its own auth, not the custom endpoint\n const { ANTHROPIC_AUTH_TOKEN, ANTHROPIC_BASE_URL, ...cleanEnv } = process.env;\n\n return spawn(claudePath, args, {\n cwd: normalizedProjectPath,\n stdio: ['pipe', 'pipe', 'pipe'],\n env: {\n ...cleanEnv,\n FORCE_COLOR: '0',\n NO_COLOR: '1',\n TERM: 'dumb',\n PATH: process.platform === 'win32'\n ? (process.env.PATH || '').split(';').filter(p => {\n const lp = p.toLowerCase().trim().replace(/\\//g, '\\\\');\n return !lp.startsWith('c:\\\\windows') &&\n !lp.startsWith('c:\\\\program files (x86)\\\\windows kits');\n }).join(';')\n : `${process.env.PATH}:/opt/homebrew/bin:/usr/local/bin`,\n },\n });\n}\n\n/**\n * Write the initial user prompt to the child process stdin as a stream-json message.\n */\nexport function sendInitialPrompt(child: ChildProcess, prompt: string): void {\n const msg = JSON.stringify({\n type: 'user',\n message: { role: 'user', content: [{ type: 'text', text: prompt }] },\n });\n child.stdin?.write(msg + '\\n');\n}\n","/**\n * CLI Stdout Line Parser for Claude CLI Provider\n *\n * Parses a single newline-delimited JSON line from the CLI stdout stream,\n * adapts it via sdk-event-adapter, and returns a structured result that\n * the provider can act on (emit events, update session state, close stdin).\n *\n * Separated from the provider class to keep processMessage logic testable\n * and to reduce the provider file size.\n */\n\nimport { adaptSDKMessage, isValidSDKMessage, type SDKResultMessage } from '../sdk-event-adapter';\nimport { createLogger } from '../logger';\nimport type { CLISession } from './claude-cli-session-and-pending-question-types';\n\nconst log = createLogger('CLIProvider:Parser');\n\nexport interface ParsedCLILine {\n /** Adapted output + metadata ready to emit as a 'message' event */\n messagePayload: {\n output: ReturnType<typeof adaptSDKMessage>['output'];\n sessionId?: string;\n checkpointUuid?: string;\n backgroundShell?: ReturnType<typeof adaptSDKMessage>['backgroundShell'];\n resultMessage?: SDKResultMessage;\n rawMessage: unknown;\n };\n /** Set when an AskUserQuestion tool-use was detected */\n askUserQuestion?: { toolUseId: string; questions: unknown[] };\n /** True when the CLI auto-handled a pending AskUserQuestion via tool_result */\n cliAutoHandledQuestion: boolean;\n /** True when this is a result message — caller should close stdin */\n isResultMessage: boolean;\n}\n\n/**\n * Parse one line of CLI stdout output.\n * Returns null if the line is not valid JSON or not a recognised SDK message.\n */\nexport function parseCLILine(line: string, session: CLISession): ParsedCLILine | null {\n let message: unknown;\n try {\n message = JSON.parse(line);\n } catch {\n log.trace({ line: line.substring(0, 100) }, 'Non-JSON line');\n return null;\n }\n\n const { attemptId } = session;\n log.debug({ type: (message as Record<string, unknown>)?.type, attemptId }, 'CLI message received');\n\n if (!isValidSDKMessage(message)) {\n log.debug({ type: (message as Record<string, unknown>)?.type }, 'Invalid message skipped');\n return null;\n }\n\n const adapted = adaptSDKMessage(message);\n\n // Detect AskUserQuestion tool-use in assistant message\n let askUserQuestion: ParsedCLILine['askUserQuestion'];\n if (adapted.askUserQuestion) {\n askUserQuestion = adapted.askUserQuestion;\n }\n\n // Detect CLI auto-handling AskUserQuestion via a user/tool_result message\n let cliAutoHandledQuestion = false;\n if (\n (message as Record<string, unknown>).type === 'user' &&\n session.getPendingQuestion()\n ) {\n const rawContent = (message as { message?: { content?: Array<{ type: string; tool_use_id?: string }> } })\n .message?.content || [];\n const pending = session.getPendingQuestion();\n for (const block of rawContent) {\n if (\n block.type === 'tool_result' &&\n block.tool_use_id &&\n pending &&\n block.tool_use_id === pending.toolUseId\n ) {\n log.info(\n { attemptId, toolUseId: block.tool_use_id },\n 'CLI auto-handled AskUserQuestion, clearing pending (answer will use auto-retry flow)',\n );\n cliAutoHandledQuestion = true;\n break;\n }\n }\n }\n\n const isResultMessage = (message as Record<string, unknown>).type === 'result';\n\n return {\n messagePayload: {\n output: adapted.output,\n sessionId: adapted.sessionId,\n checkpointUuid: adapted.checkpointUuid,\n backgroundShell: adapted.backgroundShell,\n resultMessage: isResultMessage ? (message as SDKResultMessage) : undefined,\n rawMessage: message,\n },\n askUserQuestion,\n cliAutoHandledQuestion,\n isResultMessage,\n };\n}\n","/**\n * Provider Registry — Factory for Claude providers\n */\n\nimport type { Provider, ProviderId } from './types';\nimport { ClaudeSDKProvider } from './claude-sdk-provider';\nimport { ClaudeCLIProvider } from './claude-cli-provider';\n\nexport type { Provider, ProviderId, ProviderSession, ProviderStartOptions, ProviderEventData } from './types';\n\nconst providers = new Map<ProviderId, Provider>();\n\nfunction getOrCreate(id: ProviderId): Provider {\n if (!providers.has(id)) {\n switch (id) {\n case 'claude-sdk':\n providers.set(id, new ClaudeSDKProvider());\n break;\n case 'claude-cli':\n providers.set(id, new ClaudeCLIProvider());\n break;\n default:\n throw new Error(`Unknown provider: ${id}`);\n }\n }\n return providers.get(id)!;\n}\n\n/**\n * Get the active provider based on CLAUDE_PROVIDER env var.\n * Default: 'claude-sdk'\n */\nexport function getActiveProvider(): Provider {\n const envProvider = process.env.CLAUDE_PROVIDER;\n const id: ProviderId = envProvider === 'cli' ? 'claude-cli' : 'claude-sdk';\n return getOrCreate(id);\n}\n\n/**\n * Get a specific provider by ID\n */\nexport function getProvider(id: ProviderId): Provider {\n return getOrCreate(id);\n}\n","/**\n * Agent Output Handler - Output format prompt building and file reading\n *\n * Extracted from agent-manager.ts. Handles output format instructions\n * that get appended to prompts, and reading custom output files after completion.\n */\n\nimport { resolve } from 'path';\nimport { createLogger } from './logger';\n\nconst log = createLogger('AgentOutputHandler');\n\n/**\n * Check if command is a server/dev command that should run in background\n */\nexport function isServerCommand(command: string): boolean {\n const patterns = [\n /npm\\s+run\\s+(dev|start|serve)/i,\n /yarn\\s+(dev|start|serve)/i,\n /pnpm\\s+(dev|start|serve)/i,\n /npx\\s+(directus|strapi|next|vite|nuxt)/i,\n /nohup\\s+/i,\n ];\n return patterns.some(p => p.test(command));\n}\n\n/**\n * Build output format instructions to append to prompt\n */\nexport function buildOutputFormatPrompt(outputFormat: string, outputSchema?: string, attemptId?: string): string {\n const dataDir = process.env.DATA_DIR || process.cwd();\n const outputFilePath = resolve(dataDir, 'tmp', attemptId || 'unknown');\n\n const example = getOutputFormatExample(outputFormat);\n\n let prompt = `\\n\\n=== REQUIRED OUTPUT ===\\nYou MUST write your WORK RESULTS to a ${outputFormat.toUpperCase()} file at: ${outputFilePath}.${outputFormat}`;\n if (outputSchema) prompt += `\\n\\nFormat:\\n${outputSchema}`;\n prompt += `\\n\\nCRITICAL INSTRUCTIONS:\n1. Use Write tool with PARAMETER 1 (file path) and PARAMETER 2 (your content)\n2. DO NOT wrap content in metadata like {\"file_path\": ..., \"content\": ...}\n3. The file should contain ONLY the actual ${outputFormat.toUpperCase()} data\n4. MANDATORY: After writing, you MUST use Read tool to verify the file was written correctly\n5. If the file content is invalid, fix it and rewrite\n\n${example}\n\nYour task is INCOMPLETE until:\\n1. File exists with valid content\\n2. You have Read it back to verify\\n========================`;\n\n return prompt;\n}\n\n/**\n * Get format-specific example text for output instructions\n */\nfunction getOutputFormatExample(outputFormat: string): string {\n switch (outputFormat.toLowerCase()) {\n case 'json': return `Example: Write:\\n[\"Max\", \"Bella\", \"Charlie\"]\\n\\nNOT:\\n{Max, Bella, Charlie} (unquoted strings - invalid JSON)\\nNOT:\\n{\"file_path\":\"...\", \"content\":[\"Max\"]} (don't wrap in metadata)`;\n case 'yaml': case 'yml': return `Example: Write:\\n- Max\\n- Bella\\n- Charlie\\n\\nNOT:\\n[\"Max\", \"Bella\", \"Charlie\"] (that's JSON, not YAML)`;\n case 'html': case 'htm': return `Example: Write:\\n<div class=\"container\">\\n <h1>Results</h1>\\n</div>\\n\\nNOT:\\n{\"html\": \"<div>...\"} (don't wrap in metadata)`;\n case 'css': return `Example: Write:\\n.container { color: red; }\\n\\nNOT:\\n{\"css\": \".container {...}\"} (don't wrap in metadata)`;\n case 'js': return `Example: Write:\\nconst result = [\"Max\", \"Bella\"];\\nconsole.log(result);\\n\\nNOT:\\n{\"javascript\": \"const...\"} (don't wrap in metadata)`;\n case 'md': case 'markdown': return `Example: Write:\\n# Results\\n\\n- Max\\n- Bella\\n- Charlie\\n\\nNOT:\\n{\"markdown\": \"# Results\"} (don't wrap in metadata)`;\n case 'csv': return `Example: Write:\\nMax,Bella,Charlie\\n\\nNOT:\\n[\"Max\",\"Bella\",\"Charlie\"] (that's JSON, not CSV)`;\n case 'tsv': return `Example: Write:\\nMax\\tBella\\tCharlie\\n\\nNOT:\\n[\"Max\",\"Bella\",\"Charlie\"] (that's JSON, not TSV)`;\n case 'txt': return `Example: Write:\\nMax\\nBella\\nCharlie\\n\\nNOT:\\n{\"content\": \"Max\\\\nBella\"} (don't wrap in metadata)`;\n case 'xml': return `Example: Write:\\n<?xml version=\"1.0\"?>\\n<root>\\n <item>Max</item>\\n</root>\\n\\nNOT:\\n{\"xml\": \"<?xml...>\"} (don't wrap in metadata)`;\n default: return `Example: Write the actual ${outputFormat.toUpperCase()} content directly, not wrapped in any metadata or JSON object.`;\n }\n}\n\n/** Emitter interface expected by readOutputFile */\nexport interface OutputFileEmitter {\n emit(event: string, data: unknown): boolean;\n}\n\n/**\n * Read custom output file after completion and emit result\n */\nexport function readOutputFile(emitter: OutputFileEmitter, attemptId: string, outputFormat: string): void {\n try {\n const fs = require('fs');\n const dataDir = process.env.DATA_DIR || process.cwd();\n const outputFilePath = resolve(dataDir, 'tmp', `${attemptId}.${outputFormat}`);\n\n if (fs.existsSync(outputFilePath)) {\n const fileContent = fs.readFileSync(outputFilePath, 'utf-8');\n emitter.emit('json', {\n attemptId,\n data: {\n type: 'result',\n subtype: 'success',\n is_error: false,\n content: fileContent,\n outputFormat,\n },\n });\n } else {\n emitter.emit('stderr', { attemptId, content: `Error: Expected output file not found: ${outputFilePath}` });\n }\n } catch (readError) {\n log.error({ err: readError }, 'Failed to read output file');\n }\n}\n","/**\n * Agent Event Wiring - Provider event listener setup and workflow tracking\n *\n * Extracted from agent-manager.ts. Wires provider events (message, question,\n * complete, error, stderr) to AgentManager events. Also tracks subagent\n * workflow and Bash commands from raw SDK/CLI messages.\n */\n\nimport type { ClaudeOutput } from '../types';\nimport type { BackgroundShellInfo, SDKResultMessage, UsageEvent } from './sdk-event-adapter';\nimport { sessionManager } from './session-manager';\nimport { checkpointManager } from './checkpoint-manager';\nimport { usageTracker } from './usage-tracker';\nimport { collectGitStats, gitStatsCache } from './git-stats-collector';\nimport { readOutputFile } from './agent-output-handler';\nimport { trackWorkflowFromMessage } from './agent-workflow-message-tracker';\nimport type { Provider } from './providers';\n\n/** Interface for the AgentManager context needed by event wiring */\nexport interface EventWiringContext {\n getSessionId(attemptId: string): string | undefined;\n setSessionId(attemptId: string, sessionId: string): void;\n deleteAgent(attemptId: string): void;\n emit(event: string, data: unknown): boolean;\n pendingBashCommands: Map<string, { command: string; attemptId: string }>;\n}\n\n/**\n * Wire provider events to AgentManager events for a specific attempt.\n * Returns a cleanup function that removes all listeners.\n */\nexport function wireProviderEvents(\n ctx: EventWiringContext,\n provider: Provider,\n attemptId: string,\n outputFormat?: string,\n projectPath?: string,\n): () => void {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const listeners: Array<{ event: string; fn: (...args: any[]) => void }> = [];\n\n const cleanup = () => {\n for (const { event, fn } of listeners) {\n provider.removeListener(event, fn);\n }\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const addListener = (event: string, fn: (...args: any[]) => void) => {\n listeners.push({ event, fn });\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n provider.on(event as any, fn);\n };\n\n addListener('message', async (data: {\n attemptId: string;\n output: ClaudeOutput;\n sessionId?: string;\n checkpointUuid?: string;\n backgroundShell?: BackgroundShellInfo;\n resultMessage?: SDKResultMessage;\n usageEvent?: UsageEvent;\n rawMessage?: unknown;\n }) => {\n if (data.attemptId !== attemptId) return;\n\n if (data.sessionId) {\n ctx.setSessionId(attemptId, data.sessionId);\n await sessionManager.saveSession(attemptId, data.sessionId);\n }\n\n if (data.checkpointUuid) {\n checkpointManager.captureCheckpointUuid(attemptId, data.checkpointUuid);\n }\n\n if (data.rawMessage) {\n trackWorkflowFromMessage(ctx, attemptId, data.rawMessage);\n }\n\n if (data.resultMessage) {\n usageTracker.trackResult(attemptId, data.resultMessage);\n }\n\n if (data.usageEvent) {\n usageTracker.trackUsageEvent(attemptId, data.usageEvent);\n }\n\n if (data.backgroundShell) {\n ctx.emit('backgroundShell', { attemptId, shell: data.backgroundShell });\n }\n\n // Emit adapted message (suppress result if custom output format)\n if (!(data.output.type === 'result' && outputFormat)) {\n if (outputFormat) {\n data.output.outputFormat = outputFormat;\n }\n ctx.emit('json', { attemptId, data: data.output });\n }\n });\n\n addListener('question', (data: { attemptId: string; toolUseId: string; questions: unknown[] }) => {\n if (data.attemptId !== attemptId) return;\n ctx.emit('question', data);\n });\n\n addListener('questionResolved', (data: { attemptId: string }) => {\n if (data.attemptId !== attemptId) return;\n ctx.emit('questionResolved', data);\n });\n\n addListener('complete', async (data: { attemptId: string; sessionId?: string }) => {\n if (data.attemptId !== attemptId) return;\n\n if (outputFormat) {\n readOutputFile(ctx, attemptId, outputFormat);\n }\n\n if (projectPath) {\n try {\n const gitStats = await collectGitStats(projectPath);\n if (gitStats) gitStatsCache.set(attemptId, gitStats);\n } catch { /* continue */ }\n }\n\n ctx.deleteAgent(attemptId);\n ctx.emit('exit', { attemptId, code: 0 });\n cleanup();\n });\n\n addListener('error', (data: { attemptId: string; error: string; errorName: string; isPromptTooLong?: boolean }) => {\n if (data.attemptId !== attemptId) return;\n\n ctx.emit('stderr', { attemptId, content: `${data.errorName}: ${data.error}` });\n\n if (data.isPromptTooLong) {\n ctx.emit('promptTooLong', { attemptId });\n }\n\n ctx.deleteAgent(attemptId);\n ctx.emit('exit', { attemptId, code: 1 });\n cleanup();\n });\n\n addListener('stderr', (data: { attemptId: string; content: string }) => {\n if (data.attemptId !== attemptId) return;\n ctx.emit('stderr', data);\n });\n\n return cleanup;\n}\n","/**\n * Context Health - Context window health tracking and management\n *\n * Implements ClaudeKit Engineer's context health monitoring formulas:\n * - Health status thresholds (HEALTHY/WARNING/CRITICAL/EMERGENCY)\n * - Auto-compact trigger calculation\n * - Budget allocation with buffer reserve\n * - Context usage tracking (input + output)\n */\n\n/**\n * Health status levels based on context utilization\n */\nexport type ContextHealthStatus = 'HEALTHY' | 'WARNING' | 'CRITICAL' | 'EMERGENCY';\n\n/**\n * Context health metrics\n */\nexport interface ContextHealth {\n status: ContextHealthStatus;\n score: number; // 0.0-1.0\n utilization: number; // 0.0-1.0 (percentage as decimal)\n utilizationPercent: number; // 0-100\n totalTokens: number;\n limit: number;\n remaining: number;\n shouldCompact: boolean; // Auto-compact trigger\n compactThreshold: number;\n}\n\n/**\n * Budget allocation configuration\n */\nexport interface ContextBudget {\n systemPrompt: number;\n toolDefinitions: number;\n retrievedDocs: number;\n messageHistory: number;\n bufferPercent: number; // 0.0-1.0 (default: 0.15 = 15%)\n totalBudget: number;\n warningThreshold: number; // 70% of budget\n criticalThreshold: number; // 80% of budget\n}\n\n/**\n * Default budget values from ClaudeKit Engineer\n */\nconst DEFAULT_BUDGET_CONFIG = {\n systemPrompt: 2000,\n toolDefinitions: 1500,\n retrievedDocs: 3000,\n messageHistory: 5000,\n bufferPercent: 0.15, // 15% buffer\n};\n\n/**\n * Calculate context budget allocation\n *\n * Formula from ClaudeKit:\n * - subtotal = system + tools + docs + history\n * - buffer = subtotal × buffer_pct\n * - total = subtotal + buffer\n * - warning = total × 0.70\n * - critical = total × 0.80\n */\nexport function calculateContextBudget(config = DEFAULT_BUDGET_CONFIG): ContextBudget {\n const subtotal =\n config.systemPrompt +\n config.toolDefinitions +\n config.retrievedDocs +\n config.messageHistory;\n\n const buffer = Math.floor(subtotal * config.bufferPercent);\n const totalBudget = subtotal + buffer;\n\n return {\n ...config,\n totalBudget,\n warningThreshold: Math.floor(totalBudget * 0.70),\n criticalThreshold: Math.floor(totalBudget * 0.80),\n };\n}\n\n/**\n * Calculate auto-compact threshold\n *\n * Aligned with Claude Code CLI recommendations:\n * - For window >= 1M: threshold = size × 0.33 (33%)\n * - For window < 1M: threshold = size × 0.75 (75%)\n *\n * Example: 200K window → 150K threshold\n * This preserves ~25% for output and working memory\n */\nexport function calculateCompactThreshold(contextWindowSize: number): number {\n if (contextWindowSize >= 1_000_000) {\n return Math.floor(contextWindowSize * 0.33);\n }\n return Math.floor(contextWindowSize * 0.75);\n}\n\n/**\n * Determine health status based on utilization\n *\n * Aligned with Claude Code CLI thresholds:\n * - < 60%: HEALTHY (score 1.0)\n * - 60-75%: WARNING (score 0.8)\n * - 75-90%: CRITICAL (score 0.5)\n * - >= 90%: EMERGENCY (score 0.2)\n */\nexport function getHealthStatus(utilization: number): { status: ContextHealthStatus; score: number } {\n if (utilization < 0.60) {\n return { status: 'HEALTHY', score: 1.0 };\n } else if (utilization < 0.75) {\n return { status: 'WARNING', score: 0.8 };\n } else if (utilization < 0.90) {\n return { status: 'CRITICAL', score: 0.5 };\n } else {\n return { status: 'EMERGENCY', score: 0.2 };\n }\n}\n\n/**\n * Calculate comprehensive context health metrics\n *\n * Context calculation from ClaudeKit:\n * usage = (context_input + context_output) / context_size × 100\n *\n * Note: This differs from prompt caching metrics where:\n * - context_input = input_tokens + cache_read_tokens + cache_creation_tokens\n * - context_output = output_tokens\n */\nexport function calculateContextHealth(\n inputTokens: number,\n outputTokens: number,\n contextLimit: number\n): ContextHealth {\n // Total context = input + output (ClaudeKit formula)\n const totalTokens = inputTokens + outputTokens;\n\n // Utilization as decimal (0.0-1.0)\n const utilization = totalTokens / contextLimit;\n const utilizationPercent = utilization * 100;\n\n // Remaining tokens\n const remaining = contextLimit - totalTokens;\n\n // Health status and score\n const { status, score } = getHealthStatus(utilization);\n\n // Auto-compact trigger\n const compactThreshold = calculateCompactThreshold(contextLimit);\n const shouldCompact = totalTokens >= compactThreshold;\n\n return {\n status,\n score,\n utilization,\n utilizationPercent,\n totalTokens,\n limit: contextLimit,\n remaining,\n shouldCompact,\n compactThreshold,\n };\n}\n\n// Re-export display helpers for backwards compatibility\nexport { formatHealthStatus, getHealthRecommendations } from './context-health-display-helpers';\n","/**\n * Usage Context Token Calculator - Compute context window usage from SDK token counts\n *\n * Extracted from usage-tracker.ts. Pure functions that calculate context utilization,\n * baseline tracking, and health metrics from raw SDK usage fields.\n */\n\nimport { calculateContextHealth, type ContextHealth } from './context-health';\nimport { createLogger } from './logger';\n\nconst log = createLogger('UsageContextTokenCalculator');\n\nexport interface RawTokenUsage {\n input_tokens: number;\n output_tokens: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n}\n\nexport interface ContextTokenResult {\n contextUsed: number;\n contextPercentage: number;\n baselineContext: number; // only set on first turn (numTurns === 0)\n contextHealth: ContextHealth;\n}\n\n/**\n * Calculate context window metrics from a single SDK turn's raw token usage.\n *\n * Anthropic's context window includes ALL of:\n * - input_tokens: new user message\n * - cache_read_input_tokens: cached content (still occupies window)\n * - cache_creation_input_tokens: new cache entries\n * - output_tokens: model response\n *\n * @param usage Raw token counts from the SDK result message\n * @param contextLimit Current context window size (default 200K)\n * @param isFirstTurn Whether this is the first turn (to capture baseline)\n */\nexport function calculateContextTokens(\n usage: RawTokenUsage,\n contextLimit: number,\n isFirstTurn: boolean\n): ContextTokenResult {\n const inputTokens = usage.input_tokens || 0;\n const cacheRead = usage.cache_read_input_tokens || 0;\n const cacheCreation = usage.cache_creation_input_tokens || 0;\n const outputTokens = usage.output_tokens || 0;\n\n // Baseline: first-turn cache_read tokens (for reference only)\n let baselineContext = 0;\n if (isFirstTurn && cacheRead > 0) {\n baselineContext = cacheRead;\n log.info(`First turn baseline (cached): ${cacheRead} tokens`);\n }\n\n // Active context = all tokens in the 200K window\n const contextUsed = inputTokens + cacheRead + cacheCreation + outputTokens;\n const contextPercentage = (contextUsed / contextLimit) * 100;\n\n const contextHealth = calculateContextHealth(\n inputTokens + cacheRead + cacheCreation, // total input (including cached)\n outputTokens,\n contextLimit\n );\n\n log.debug({\n contextUsed,\n contextLimit,\n contextPercentage: contextPercentage.toFixed(1),\n healthStatus: contextHealth.status,\n inputTokens,\n cacheRead,\n cacheCreation,\n outputTokens,\n totalInput: inputTokens + cacheRead + cacheCreation,\n }, 'Context updated (includes cache_read)');\n\n return { contextUsed, contextPercentage, baselineContext, contextHealth };\n}\n","/**\n * Usage Tracker - Collect and aggregate usage statistics from SDK messages\n *\n * Tracks token usage, costs, and plan limits in-memory for status line display.\n * Context token calculation extracted to: usage-context-token-calculator.ts\n */\n\nimport { EventEmitter } from 'events';\nimport type { SDKResultMessage, UsageEvent } from './sdk-event-adapter';\nimport type { ContextHealth } from './context-health';\nimport { calculateContextHealth } from './context-health';\nimport { calculateContextTokens } from './usage-context-token-calculator';\n\nimport { createLogger } from './logger';\n\nconst log = createLogger('UsageTracker');\n\n/**\n * Aggregated usage statistics for a session\n */\nexport interface UsageStats {\n totalInputTokens: number;\n totalOutputTokens: number;\n totalCacheCreationTokens: number;\n totalCacheReadTokens: number;\n totalTokens: number;\n totalCostUSD: number;\n numTurns: number;\n durationMs: number;\n durationApiMs: number;\n\n // Context usage tracking (full context window)\n contextUsed: number;\n contextLimit: number;\n contextPercentage: number;\n baselineContext: number;\n\n // Context health metrics (ClaudeKit formulas)\n contextHealth?: ContextHealth;\n\n // Per-model breakdown\n modelUsage: Record<string, {\n inputTokens: number;\n outputTokens: number;\n cacheReadInputTokens: number;\n cacheCreationInputTokens: number;\n costUSD: number;\n contextWindow: number;\n }>;\n\n // Session metadata\n sessionId?: string;\n startedAt: number;\n lastUpdatedAt: number;\n}\n\n/**\n * Account info from Claude Code (from accountInfo() API)\n */\nexport interface AccountInfo {\n email?: string;\n organization?: string;\n subscriptionType?: string;\n tokenSource?: string;\n apiKeySource?: string;\n}\n\n/**\n * Plan limits - retrieved once and cached\n */\nexport interface PlanLimits {\n maxTokensPerWindow?: number;\n windowDurationMs?: number;\n}\n\ninterface UsageTrackerEvents {\n 'usage-update': (data: { attemptId: string; usage: UsageStats }) => void;\n}\n\n/**\n * UsageTracker - Singleton to track usage statistics\n */\nclass UsageTracker extends EventEmitter {\n private sessions = new Map<string, UsageStats>();\n private accountInfo?: AccountInfo;\n\n constructor() {\n super();\n }\n\n /** Initialize or get usage stats for an attempt */\n initSession(attemptId: string): UsageStats {\n if (!this.sessions.has(attemptId)) {\n const stats: UsageStats = {\n totalInputTokens: 0,\n totalOutputTokens: 0,\n totalCacheCreationTokens: 0,\n totalCacheReadTokens: 0,\n totalTokens: 0,\n totalCostUSD: 0,\n numTurns: 0,\n durationMs: 0,\n durationApiMs: 0,\n contextUsed: 0,\n contextLimit: 200000,\n contextPercentage: 0,\n baselineContext: 0,\n modelUsage: {},\n startedAt: Date.now(),\n lastUpdatedAt: Date.now(),\n };\n this.sessions.set(attemptId, stats);\n }\n return this.sessions.get(attemptId)!;\n }\n\n /** Update usage stats from SDKResultMessage */\n trackResult(attemptId: string, result: SDKResultMessage): void {\n const stats = this.initSession(attemptId);\n\n if ('session_id' in result) {\n stats.sessionId = result.session_id;\n }\n\n if ('usage' in result) {\n const usage = result.usage as {\n input_tokens: number;\n output_tokens: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n };\n\n stats.totalInputTokens += usage.input_tokens;\n stats.totalOutputTokens += usage.output_tokens;\n stats.totalCacheCreationTokens += usage.cache_creation_input_tokens || 0;\n stats.totalCacheReadTokens += usage.cache_read_input_tokens || 0;\n stats.totalTokens = stats.totalInputTokens + stats.totalOutputTokens;\n\n const { contextUsed, contextPercentage, baselineContext, contextHealth } =\n calculateContextTokens(usage, stats.contextLimit, stats.numTurns === 0);\n\n stats.contextUsed = contextUsed;\n stats.contextPercentage = contextPercentage;\n if (baselineContext > 0) stats.baselineContext = baselineContext;\n stats.contextHealth = contextHealth;\n }\n\n if ('total_cost_usd' in result) stats.totalCostUSD += result.total_cost_usd as number;\n if ('num_turns' in result) stats.numTurns += result.num_turns || 0;\n if ('duration_ms' in result) stats.durationMs += result.duration_ms || 0;\n if ('duration_api_ms' in result) stats.durationApiMs += (result as any).duration_api_ms || 0;\n\n // Merge per-model usage (only in success variant)\n if (result.subtype === 'success' && 'modelUsage' in result && result.modelUsage) {\n for (const [modelName, modelStats] of Object.entries(result.modelUsage)) {\n if (!stats.modelUsage[modelName]) {\n stats.modelUsage[modelName] = {\n inputTokens: 0,\n outputTokens: 0,\n cacheReadInputTokens: 0,\n cacheCreationInputTokens: 0,\n costUSD: 0,\n contextWindow: (modelStats as any).contextWindow || 200000,\n };\n }\n const existing = stats.modelUsage[modelName];\n const ms = modelStats as any;\n existing.inputTokens += ms.inputTokens || 0;\n existing.outputTokens += ms.outputTokens || 0;\n existing.cacheReadInputTokens += ms.cacheReadInputTokens || 0;\n existing.cacheCreationInputTokens += ms.cacheCreationInputTokens || 0;\n existing.costUSD += ms.costUSD || 0;\n\n // Update context limit from model context window if available\n if (ms.contextWindow && ms.contextWindow > 0) {\n stats.contextLimit = ms.contextWindow;\n }\n }\n }\n\n stats.lastUpdatedAt = Date.now();\n this.emit('usage-update', { attemptId, usage: stats });\n }\n\n /**\n * Track per-turn usage from message_start/message_delta stream events.\n *\n * The Anthropic API emits usage on every API response:\n * - message_start: input_tokens, cache_read, cache_creation (full input context at this turn)\n * - message_delta: output_tokens (output for this turn)\n *\n * input_tokens + cache_read + cache_creation = total input context for this API call\n * (includes system prompt, tool definitions, full conversation history, tool results)\n *\n * This gives us accurate, real-time context tracking without estimation.\n */\n trackUsageEvent(attemptId: string, usage: UsageEvent): void {\n const stats = this.initSession(attemptId);\n\n const inputContext = (usage.input_tokens || 0) + (usage.cache_read_input_tokens || 0) + (usage.cache_creation_input_tokens || 0);\n const outputTokens = usage.output_tokens || 0;\n\n // Track baseline from first message_start (before any output)\n if (stats.baselineContext === 0 && inputContext > 0) {\n stats.baselineContext = inputContext;\n log.info({ attemptId, baseline: inputContext }, 'Context baseline set from first usage event');\n }\n\n // Context used = input context + output tokens for this API call\n // This is the actual context window usage at this point in the conversation\n if (inputContext > 0) {\n stats.contextUsed = inputContext + outputTokens;\n stats.contextPercentage = (stats.contextUsed / stats.contextLimit) * 100;\n\n stats.contextHealth = calculateContextHealth(\n inputContext,\n outputTokens,\n stats.contextLimit\n );\n\n log.debug({\n attemptId,\n contextUsed: stats.contextUsed,\n contextLimit: stats.contextLimit,\n contextPct: stats.contextPercentage.toFixed(1),\n input: usage.input_tokens,\n cacheRead: usage.cache_read_input_tokens,\n cacheCreate: usage.cache_creation_input_tokens,\n output: outputTokens,\n }, 'Context updated from stream usage event');\n }\n\n stats.lastUpdatedAt = Date.now();\n this.emit('usage-update', { attemptId, usage: stats });\n }\n\n /** Get current usage stats for an attempt */\n getUsage(attemptId: string): UsageStats | undefined {\n return this.sessions.get(attemptId);\n }\n\n /** Clear usage stats for an attempt */\n clearSession(attemptId: string): void {\n this.sessions.delete(attemptId);\n }\n\n /** Get all active sessions */\n getAllSessions(): Map<string, UsageStats> {\n return this.sessions;\n }\n\n /** Set account info (from accountInfo() API call) */\n setAccountInfo(info: AccountInfo): void {\n this.accountInfo = info;\n }\n\n /** Get cached account info */\n getAccountInfo(): AccountInfo | undefined {\n return this.accountInfo;\n }\n\n override on<K extends keyof UsageTrackerEvents>(\n event: K,\n listener: UsageTrackerEvents[K]\n ): this {\n return super.on(event, listener);\n }\n\n override emit<K extends keyof UsageTrackerEvents>(\n event: K,\n ...args: Parameters<UsageTrackerEvents[K]>\n ): boolean {\n return super.emit(event, ...args);\n }\n}\n\n// Export singleton instance\nexport const usageTracker = new UsageTracker();\n","/**\n * Git Stats Collector - Capture git changes snapshot on stream completion\n *\n * Collects git diff stats (additions/deletions) when streaming finishes.\n * Only runs once per attempt, on final result.\n */\n\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\n\nimport { createLogger } from './logger';\n\nconst log = createLogger('GitStatsCollector');\n\nconst execAsync = promisify(exec);\n\n/**\n * Git statistics snapshot\n */\nexport interface GitStats {\n additions: number;\n deletions: number;\n filesChanged: number;\n capturedAt: number;\n}\n\n/**\n * Parse git diff --numstat output\n * Format: <additions>\\t<deletions>\\t<filename>\n */\nfunction parseNumstat(output: string): GitStats {\n const lines = output.trim().split('\\n').filter(Boolean);\n\n let additions = 0;\n let deletions = 0;\n let filesChanged = 0;\n\n for (const line of lines) {\n const parts = line.split('\\t');\n if (parts.length < 3) continue;\n\n const [add, del] = parts;\n\n // Handle binary files (marked as '-')\n if (add !== '-') additions += parseInt(add, 10) || 0;\n if (del !== '-') deletions += parseInt(del, 10) || 0;\n\n filesChanged++;\n }\n\n return {\n additions,\n deletions,\n filesChanged,\n capturedAt: Date.now(),\n };\n}\n\n/**\n * Collect git diff stats for current working directory\n */\nexport async function collectGitStats(cwd: string): Promise<GitStats | null> {\n try {\n // Get git diff --numstat (staged + unstaged changes)\n const { stdout } = await execAsync('git diff --numstat HEAD', { cwd });\n\n if (!stdout.trim()) {\n // No changes\n return {\n additions: 0,\n deletions: 0,\n filesChanged: 0,\n capturedAt: Date.now(),\n };\n }\n\n return parseNumstat(stdout);\n } catch (error) {\n // Not a git repo or git command failed\n log.error({ error: error }, '[GitStats] Failed to collect git stats:');\n return null;\n }\n}\n\n/**\n * In-memory cache for git stats per attempt\n */\nclass GitStatsCache {\n private cache = new Map<string, GitStats | null>();\n\n set(attemptId: string, stats: GitStats | null): void {\n this.cache.set(attemptId, stats);\n }\n\n get(attemptId: string): GitStats | null | undefined {\n return this.cache.get(attemptId);\n }\n\n clear(attemptId: string): void {\n this.cache.delete(attemptId);\n }\n\n getAll(): Map<string, GitStats | null> {\n return this.cache;\n }\n}\n\n// Export singleton cache\nexport const gitStatsCache = new GitStatsCache();\n","/**\n * Agent Workflow Message Tracker - Parse raw SDK/CLI messages to track subagent workflow events\n *\n * Extracted from agent-event-wiring.ts. Processes assistant/user message blocks to track\n * Task/Agent tool subagent starts/ends, TeamCreate events, SendMessage events,\n * TaskCreate/TaskUpdate events, and Bash BGPID patterns.\n */\n\nimport { workflowTracker } from './workflow-tracker';\nimport { isServerCommand } from './agent-output-handler';\nimport type { EventWiringContext } from './agent-event-wiring';\n\n/**\n * Track workflow from raw SDK/CLI messages (subagent starts/ends, team creation, Bash commands).\n */\nexport function trackWorkflowFromMessage(\n ctx: EventWiringContext,\n attemptId: string,\n message: unknown\n): void {\n const msg = message as {\n type: string;\n message?: { content: Array<{ type: string; id?: string; name?: string; input?: unknown }> };\n parent_tool_use_id?: string | null;\n };\n\n if (msg.type === 'assistant' && msg.message?.content) {\n for (const block of msg.message.content) {\n if (block.type === 'tool_use' && (block.name === 'Task' || block.name === 'Agent') && block.id) {\n const taskInput = (block as { input?: { subagent_type?: string; model?: string; team_name?: string; name?: string; prompt?: string; description?: string } }).input;\n workflowTracker.trackSubagentStart(\n attemptId, block.id, taskInput?.subagent_type || taskInput?.model || 'agent',\n msg.parent_tool_use_id || null,\n { teamName: taskInput?.team_name, name: taskInput?.name, prompt: taskInput?.prompt || taskInput?.description },\n );\n }\n if (block.type === 'tool_use' && block.name === 'TeamCreate' && block.id) {\n const teamInput = (block as { input?: { team_name?: string } }).input;\n if (teamInput?.team_name) workflowTracker.trackTeamCreate(attemptId, teamInput.team_name);\n }\n if (block.type === 'tool_use' && block.name === 'SendMessage' && block.id) {\n const msgInput = (block as { input?: { type?: string; to?: string; recipient?: string; content?: string; message?: string | object; summary?: string } }).input;\n if (msgInput) {\n // Best-effort sender inference: find most recent active agent\n const workflow = workflowTracker.getWorkflow(attemptId);\n let inferredSender: string | undefined;\n if (workflow) {\n const activeNodes = workflow.activeNodes\n .map(id => workflow.nodes.get(id))\n .filter(Boolean)\n .sort((a, b) => (b!.startedAt || 0) - (a!.startedAt || 0));\n inferredSender = activeNodes[0]?.name || activeNodes[0]?.type;\n }\n const messageContent = typeof msgInput.message === 'string' ? msgInput.message : (msgInput.content || '');\n workflowTracker.trackMessage(attemptId, {\n ...msgInput,\n content: messageContent,\n fromAgent: inferredSender,\n isBroadcast: msgInput.to === '*',\n });\n }\n }\n if (block.type === 'tool_use' && block.name === 'TaskCreate' && block.id) {\n const tcInput = (block as { input?: { subject?: string; description?: string; activeForm?: string } }).input;\n if (tcInput) workflowTracker.trackTaskCreate(attemptId, block.id, tcInput);\n }\n if (block.type === 'tool_use' && block.name === 'TaskUpdate' && block.id) {\n const tuInput = (block as { input?: { taskId?: string; status?: string; owner?: string; subject?: string; activeForm?: string } }).input;\n if (tuInput) workflowTracker.trackTaskUpdate(attemptId, tuInput);\n }\n // Track Bash tool_uses for BGPID correlation\n if (block.type === 'tool_use' && block.name === 'Bash' && block.id) {\n const bashInput = block.input as { command?: string } | undefined;\n const toolId = block.id;\n if (bashInput?.command) {\n ctx.pendingBashCommands.set(toolId, { command: bashInput.command, attemptId });\n setTimeout(() => ctx.pendingBashCommands.delete(toolId), 5 * 60 * 1000);\n }\n }\n }\n }\n\n if (msg.type === 'user' && msg.message?.content) {\n const userContent = msg.message.content as Array<{\n type: string;\n tool_use_id?: string;\n is_error?: boolean;\n content?: string | unknown[];\n }>;\n\n for (const block of userContent) {\n if (block.type === 'tool_result' && block.tool_use_id) {\n // Extract result content for Task tool results\n let resultContent = '';\n if (typeof block.content === 'string') {\n resultContent = block.content;\n } else if (Array.isArray(block.content)) {\n resultContent = (block.content as Array<{ text?: string }>)\n .filter(c => c && typeof c === 'object' && 'text' in c)\n .map(c => c.text || '').join('');\n }\n\n // Register actual taskId from TaskCreate results (toolUseId → numeric taskId mapping)\n {\n const workflow = workflowTracker.getWorkflow(attemptId);\n if (workflow) {\n const isTaskCreate = workflow.tasks.some((t) => t.id === block.tool_use_id);\n if (isTaskCreate && resultContent) {\n try {\n const parsed = JSON.parse(resultContent);\n if (parsed.taskId) {\n workflowTracker.registerTaskId(attemptId, block.tool_use_id!, String(parsed.taskId));\n }\n } catch {\n // Text format: \"Task #5 created successfully: ...\"\n const match = resultContent.match(/Task\\s*#(\\d+)/i) ||\n resultContent.match(/taskId[\"\\s:]+(\\d+)/);\n if (match) {\n workflowTracker.registerTaskId(attemptId, block.tool_use_id!, match[1]);\n }\n }\n }\n }\n }\n\n // Extract the meaningful agent output from result, stripping SDK boilerplate\n let cleanResult = resultContent;\n const agentIdIdx = resultContent.indexOf('agentId:');\n const usageIdx = resultContent.indexOf('<usage>');\n if (agentIdIdx > 0 || usageIdx > 0) {\n const cutoff = Math.min(\n agentIdIdx > 0 ? agentIdIdx : Infinity,\n usageIdx > 0 ? usageIdx : Infinity,\n );\n cleanResult = resultContent.slice(0, cutoff).trim();\n }\n // Strip \"Spawned successfully...\" preamble for foreground agents that returned real content\n const pipeIdx = cleanResult.indexOf('|');\n if (pipeIdx > 0 && cleanResult.includes('Spawned successfully')) {\n cleanResult = cleanResult.slice(pipeIdx + 1).trim();\n } else if (cleanResult.startsWith('Spawned successfully')) {\n // Background agent - no real content yet\n cleanResult = '';\n }\n\n workflowTracker.trackSubagentEnd(\n attemptId, block.tool_use_id, !block.is_error,\n block.is_error ? resultContent : undefined,\n cleanResult || resultContent,\n );\n\n // Detect BGPID pattern\n let content = '';\n if (typeof block.content === 'string') {\n content = block.content;\n } else if (Array.isArray(block.content)) {\n content = (block.content as Array<{ text?: string }>)\n .filter(c => c && typeof c === 'object' && 'text' in c)\n .map(c => c.text || '').join('');\n }\n\n const bgpidMatch = content.match(/BGPID:(\\d+)/);\n const emptyBgpidMatch = content.match(/BGPID:\\s*$/m) || content.trim() === 'BGPID:';\n\n if (bgpidMatch && block.tool_use_id) {\n const pid = parseInt(bgpidMatch[1], 10);\n const bashInfo = ctx.pendingBashCommands.get(block.tool_use_id);\n const command = bashInfo?.command || `Background process (PID: ${pid})`;\n const logMatch = command.match(/>\\s*([^\\s]+\\.log)/);\n ctx.emit('trackedProcess', { attemptId, pid, command, logFile: logMatch?.[1] });\n ctx.pendingBashCommands.delete(block.tool_use_id);\n } else if (emptyBgpidMatch && block.tool_use_id) {\n const bashInfo = ctx.pendingBashCommands.get(block.tool_use_id);\n if (bashInfo?.command && isServerCommand(bashInfo.command)) {\n const nohupMatch = bashInfo.command.match(/nohup\\s+(.+?)\\s*>\\s*\\/tmp\\//);\n if (nohupMatch) {\n ctx.emit('backgroundShell', {\n attemptId,\n shell: {\n toolUseId: block.tool_use_id,\n command: nohupMatch[1].trim(),\n description: 'Auto-spawned from empty BGPID',\n originalCommand: bashInfo.command,\n },\n });\n }\n }\n ctx.pendingBashCommands.delete(block.tool_use_id);\n }\n }\n }\n }\n}\n","/**\n * Agent Persistent Question Store - Task-scoped AskUserQuestion data that survives agent cleanup\n *\n * Extracted from agent-manager.ts. Stores pending question payloads keyed by taskId\n * so they remain accessible after the agent attempt completes or is cancelled.\n * Used when CLI auto-handles AskUserQuestion and the attempt ends before user answers.\n */\n\nexport interface PersistentQuestionData {\n attemptId: string;\n toolUseId: string;\n questions: unknown[];\n timestamp: number;\n}\n\n/**\n * PersistentQuestionStore - in-memory map of taskId → question data\n */\nexport class PersistentQuestionStore {\n private store = new Map<string, PersistentQuestionData>();\n\n /** Persist question data for a task (survives agent cleanup) */\n set(taskId: string, data: PersistentQuestionData): void {\n this.store.set(taskId, data);\n }\n\n /** Retrieve persisted question data for a task, or null if absent */\n get(taskId: string): PersistentQuestionData | null {\n return this.store.get(taskId) || null;\n }\n\n /** Remove persisted question data for a task */\n clear(taskId: string): void {\n this.store.delete(taskId);\n }\n}\n"],"names":["ENGINEERING_SYSTEM_PROMPT","trim","TASK_HINTS","fix","feature","debug","refactor","question","setup","server","isServerTask","prompt","lower","toLowerCase","test","getSystemPrompt","options","outputFormat","outputSchema","attemptId","outputFilePath","finalPrompt","formatInstructions","getOutputFormatInstructions","format","schema","filePath","toUpperCase"],"mappings":"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"}
|