zencode-cli 0.2.3 → 0.4.1

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/llm/client.ts","../../src/tools/registry.ts","../../src/tools/read-file.ts","../../src/tools/write-file.ts","../../src/tools/edit-file.ts","../../src/tools/bash.ts","../../src/tools/glob.ts","../../src/tools/grep.ts","../../src/tools/register.ts","../../src/tools/permission.ts","../../src/core/conversation.ts","../../src/core/read-tracker.ts","../../src/core/agent.ts","../../src/core/prompt/layers/core.ts","../../src/core/prompt/layers/planning.ts","../../src/core/prompt/layers/parallel.ts","../../src/core/prompt/layers/git.ts","../../src/core/prompt/layers/agents.ts","../../src/core/prompt/layers/project.ts","../../src/core/prompt/builder.ts","../../src/core/todo-store.ts","../../src/core/sub-agents/registry.ts","../../src/core/sub-agents/presets.ts","../../src/core/sub-agents/loader.ts","../../src/core/skills/registry.ts","../../src/core/skills/loader.ts","../../src/core/sub-agent.ts","../../src/tools/spawn-agents.ts","../../src/tools/todo.ts","../../src/core/sub-agents/runner.ts","../../src/tools/dispatch.ts","../../src/cli/tui/bridge.ts","../../src/core/sub-agent-tracker.ts","../../src/cli/tui/state.ts","../../src/cli/tui/components/ToolCallLine.tsx","../../src/cli/tui/components/MessageBubble.tsx","../../src/cli/tui/components/ChatArea.tsx","../../src/cli/tui/components/InputArea.tsx","../../src/cli/tui/components/StatusBar.tsx","../../src/cli/tui/components/ConfirmPrompt.tsx","../../src/cli/tui/components/TodoPanel.tsx","../../src/cli/tui/components/Header.tsx","../../src/cli/tui/App.tsx","../../src/cli/tui/index.tsx","../../src/cli/index.ts","../../src/config/loader.ts","../../src/config/defaults.ts","../../src/cli/repl.ts","../../src/cli/ui.ts","../../bin/zencode.ts"],"sourcesContent":["import OpenAI from 'openai';\nimport type {\n Message,\n ToolDefinition,\n ToolCall,\n StreamDelta,\n} from './types.js';\n\nexport interface LLMClientOptions {\n apiKey: string;\n baseURL: string;\n model: string;\n temperature?: number;\n maxTokens?: number;\n}\n\nexport interface StreamCallbacks {\n onContent?: (text: string) => void;\n onToolCall?: (toolCall: ToolCall) => void;\n onToolCallStreaming?: (index: number, name: string, accumulatedArgs: string) => void;\n onFinish?: (message: Message) => void;\n onError?: (error: Error) => void;\n}\n\nexport class LLMClient {\n private client: OpenAI;\n private model: string;\n private temperature: number;\n private maxTokens: number;\n private activeAbortController: AbortController | null = null;\n\n constructor(options: LLMClientOptions) {\n this.client = new OpenAI({\n apiKey: options.apiKey,\n baseURL: options.baseURL,\n });\n this.model = options.model;\n this.temperature = options.temperature ?? 0.7;\n this.maxTokens = options.maxTokens ?? 8192;\n }\n\n /**\n * 流式调用 LLM,实时回调文本内容和工具调用\n */\n async chatStream(\n messages: Message[],\n tools: ToolDefinition[] | undefined,\n callbacks: StreamCallbacks,\n ): Promise<Message> {\n const params: OpenAI.Chat.ChatCompletionCreateParamsStreaming = {\n model: this.model,\n messages: messages as OpenAI.Chat.ChatCompletionMessageParam[],\n temperature: this.temperature,\n max_tokens: this.maxTokens,\n stream: true,\n };\n\n if (tools && tools.length > 0) {\n params.tools = tools as OpenAI.Chat.ChatCompletionTool[];\n params.tool_choice = 'auto';\n }\n\n // Request usage info in stream\n params.stream_options = { include_usage: true };\n\n const abortController = new AbortController();\n this.activeAbortController = abortController;\n\n try {\n const stream = await this.client.chat.completions.create(params, {\n signal: abortController.signal,\n });\n\n let contentParts: string[] = [];\n let reasoningParts: string[] = [];\n let reasoningStarted = false;\n let reasoningEnded = false;\n const toolCallMap = new Map<number, { id: string; name: string; args: string }>();\n let usageInfo: { prompt_tokens: number; completion_tokens: number; total_tokens: number } | null = null;\n\n for await (const chunk of stream) {\n // 捕获 usage(最后一个 chunk 包含)\n const chunkUsage = (chunk as any).usage;\n if (chunkUsage && chunkUsage.total_tokens) {\n usageInfo = {\n prompt_tokens: chunkUsage.prompt_tokens ?? 0,\n completion_tokens: chunkUsage.completion_tokens ?? 0,\n total_tokens: chunkUsage.total_tokens,\n };\n }\n\n const choice = chunk.choices[0];\n if (!choice) continue;\n\n const delta: StreamDelta = choice.delta as StreamDelta;\n\n // 处理 reasoning_content(deepseek-reasoner 思维链)\n if (delta.reasoning_content) {\n reasoningParts.push(delta.reasoning_content);\n // 首个 reasoning chunk 前注入 <think> 标签,让 thinkFilter 渲染\n if (!reasoningStarted) {\n reasoningStarted = true;\n callbacks.onContent?.('<think>');\n }\n callbacks.onContent?.(delta.reasoning_content);\n }\n\n // 处理文本内容\n if (delta.content) {\n // reasoning → content 过渡时注入 </think>\n if (reasoningStarted && !reasoningEnded) {\n reasoningEnded = true;\n callbacks.onContent?.('</think>');\n }\n contentParts.push(delta.content);\n callbacks.onContent?.(delta.content);\n }\n\n // 处理工具调用(流式中分片到达)\n if (delta.tool_calls) {\n for (const tc of delta.tool_calls) {\n const existing = toolCallMap.get(tc.index);\n if (existing) {\n if (tc.function?.arguments) {\n existing.args += tc.function.arguments;\n }\n } else {\n toolCallMap.set(tc.index, {\n id: tc.id || '',\n name: tc.function?.name || '',\n args: tc.function?.arguments || '',\n });\n }\n\n // 流式回调:write-file / edit-file 的参数实时推送\n const entry = toolCallMap.get(tc.index);\n if (entry && callbacks.onToolCallStreaming) {\n const n = entry.name;\n if (n === 'write-file' || n === 'edit-file') {\n callbacks.onToolCallStreaming(tc.index, n, entry.args);\n }\n }\n }\n }\n }\n\n // reasoning 结束但没有 content 跟随时(如只返回 tool_calls),关闭 think 标签\n if (reasoningStarted && !reasoningEnded) {\n reasoningEnded = true;\n callbacks.onContent?.('</think>');\n }\n\n // 组装完整的 tool_calls\n const toolCalls: ToolCall[] = [];\n for (const [, tc] of [...toolCallMap.entries()].sort(([a], [b]) => a - b)) {\n const toolCall: ToolCall = {\n id: tc.id,\n type: 'function',\n function: {\n name: tc.name,\n arguments: tc.args,\n },\n };\n toolCalls.push(toolCall);\n callbacks.onToolCall?.(toolCall);\n }\n\n const fullContent = contentParts.join('');\n const fullReasoning = reasoningParts.join('');\n const assistantMessage: Message = {\n role: 'assistant',\n content: fullContent || null,\n };\n\n if (fullReasoning) {\n assistantMessage.reasoning_content = fullReasoning;\n }\n\n if (toolCalls.length > 0) {\n assistantMessage.tool_calls = toolCalls;\n }\n\n if (usageInfo) {\n assistantMessage.usage = usageInfo;\n }\n\n callbacks.onFinish?.(assistantMessage);\n return assistantMessage;\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n if (!isAbortError(err)) {\n callbacks.onError?.(err);\n }\n throw err;\n } finally {\n if (this.activeAbortController === abortController) {\n this.activeAbortController = null;\n }\n }\n }\n\n /**\n * 非流式调用 LLM\n */\n async chat(\n messages: Message[],\n tools?: ToolDefinition[],\n ): Promise<Message> {\n const params: OpenAI.Chat.ChatCompletionCreateParamsNonStreaming = {\n model: this.model,\n messages: messages as OpenAI.Chat.ChatCompletionMessageParam[],\n temperature: this.temperature,\n max_tokens: this.maxTokens,\n stream: false,\n };\n\n if (tools && tools.length > 0) {\n params.tools = tools as OpenAI.Chat.ChatCompletionTool[];\n params.tool_choice = 'auto';\n }\n\n const response = await this.client.chat.completions.create(params);\n const choice = response.choices[0];\n if (!choice) {\n throw new Error('No response from LLM');\n }\n\n const msg = choice.message;\n const result: Message = {\n role: 'assistant',\n content: msg.content,\n };\n\n // 捕获 reasoning_content(deepseek-reasoner)\n const reasoning = (msg as unknown as Record<string, unknown>).reasoning_content;\n if (reasoning && typeof reasoning === 'string') {\n result.reasoning_content = reasoning;\n }\n\n if (msg.tool_calls && msg.tool_calls.length > 0) {\n result.tool_calls = msg.tool_calls.map((tc) => ({\n id: tc.id,\n type: 'function' as const,\n function: {\n name: tc.function.name,\n arguments: tc.function.arguments,\n },\n }));\n }\n\n // 捕获 token 用量\n if (response.usage) {\n result.usage = {\n prompt_tokens: response.usage.prompt_tokens,\n completion_tokens: response.usage.completion_tokens,\n total_tokens: response.usage.total_tokens,\n };\n }\n\n return result;\n }\n\n get modelName(): string {\n return this.model;\n }\n\n abortActiveStream(): void {\n if (this.activeAbortController) {\n this.activeAbortController.abort();\n this.activeAbortController = null;\n }\n }\n}\n\nexport function isAbortError(error: unknown): boolean {\n if (!error) return false;\n const err = error as { name?: string; message?: string; code?: string; cause?: { name?: string; code?: string } };\n const name = err.name || err.cause?.name || '';\n const code = err.code || err.cause?.code || '';\n const message = err.message || '';\n\n return (\n name === 'AbortError' ||\n name === 'APIUserAbortError' ||\n code === 'ABORT_ERR' ||\n /abort|aborted|cancel|cancelled|canceled|interrupted/i.test(message)\n );\n}\n\n/**\n * 从配置创建 LLM 客户端\n */\nexport function createLLMClient(options: LLMClientOptions): LLMClient {\n return new LLMClient(options);\n}\n","import type { Tool, ToolResult } from './types.js';\nimport type { ToolDefinition } from '../llm/types.js';\nimport type { PermissionsConfig } from '../config/types.js';\n\nexport class ToolRegistry {\n private tools = new Map<string, Tool>();\n private permissionOverrides: PermissionsConfig | null = null;\n\n register(tool: Tool): void {\n this.tools.set(tool.name, tool);\n }\n\n get(name: string): Tool | undefined {\n return this.tools.get(name);\n }\n\n has(name: string): boolean {\n return this.tools.has(name);\n }\n\n unregister(name: string): boolean {\n return this.tools.delete(name);\n }\n\n /**\n * 设置权限覆盖配置\n */\n setPermissions(permissions: PermissionsConfig): void {\n this.permissionOverrides = permissions;\n }\n\n /**\n * 运行时将某工具升级为自动批准(始终允许)\n */\n addAutoApprove(toolName: string): void {\n if (!this.permissionOverrides) {\n this.permissionOverrides = { auto_approve: [], require_approval: [] };\n }\n if (!this.permissionOverrides.auto_approve.includes(toolName)) {\n this.permissionOverrides.auto_approve.push(toolName);\n }\n // 从 require_approval 中移除\n this.permissionOverrides.require_approval =\n this.permissionOverrides.require_approval.filter((n) => n !== toolName);\n }\n\n /**\n * 获取工具的有效权限级别\n */\n getPermissionLevel(toolName: string): 'auto' | 'confirm' | 'deny' {\n if (this.permissionOverrides) {\n if (this.permissionOverrides.auto_approve.includes(toolName)) return 'auto';\n if (this.permissionOverrides.require_approval.includes(toolName)) return 'confirm';\n }\n const tool = this.tools.get(toolName);\n return tool?.permissionLevel ?? 'confirm';\n }\n\n /**\n * 执行工具调用\n */\n async execute(name: string, params: Record<string, unknown>, maxOutput: number): Promise<ToolResult> {\n const tool = this.tools.get(name);\n if (!tool) {\n return { content: `错误:未找到工具 \"${name}\"` };\n }\n\n try {\n const result = await tool.execute(params);\n\n // 截断过长的输出\n if (result.content.length > maxOutput) {\n return {\n content: result.content.slice(0, maxOutput) + '\\n\\n[输出已截断]',\n truncated: true,\n };\n }\n\n return result;\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return { content: `工具执行错误:${msg}` };\n }\n }\n\n /**\n * 导出为 OpenAI function calling 格式\n */\n toToolDefinitions(filter?: string[]): ToolDefinition[] {\n const tools: ToolDefinition[] = [];\n for (const [name, tool] of this.tools) {\n if (filter && !filter.includes(name)) continue;\n tools.push({\n type: 'function',\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters as unknown as Record<string, unknown>,\n },\n });\n }\n return tools;\n }\n\n /**\n * 获取所有已注册的工具名\n */\n listTools(): string[] {\n return [...this.tools.keys()];\n }\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { Tool, ToolResult } from './types.js';\n\nexport const readFileTool: Tool = {\n name: 'read-file',\n description: '读取文件内容。修改文件前必须先读取。支持 offset/limit 读取大文件的指定部分。返回带行号的内容。',\n parameters: {\n type: 'object',\n properties: {\n path: {\n type: 'string',\n description: '文件路径(相对于工作目录或绝对路径)',\n },\n offset: {\n type: 'number',\n description: '起始行号(从1开始),默认从头读取',\n },\n limit: {\n type: 'number',\n description: '读取的行数,默认读取全部',\n },\n },\n required: ['path'],\n },\n permissionLevel: 'auto',\n\n async execute(params: Record<string, unknown>): Promise<ToolResult> {\n const filePath = path.resolve(params['path'] as string);\n const offset = (params['offset'] as number) || 1;\n const limit = params['limit'] as number | undefined;\n\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n const lines = content.split('\\n');\n\n const startIdx = Math.max(0, offset - 1);\n const endIdx = limit ? startIdx + limit : lines.length;\n const selectedLines = lines.slice(startIdx, endIdx);\n\n // 带行号输出\n const numbered = selectedLines\n .map((line, i) => `${String(startIdx + i + 1).padStart(5)}\\t${line}`)\n .join('\\n');\n\n return { content: numbered || '(空文件)' };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return { content: `读取文件失败:${msg}` };\n }\n },\n};\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { Tool, ToolResult } from './types.js';\n\nexport const writeFileTool: Tool = {\n name: 'write-file',\n description: '创建新文件或完整重写文件。如果是修改已有文件,优先使用 edit-file。会自动创建父目录。',\n parameters: {\n type: 'object',\n properties: {\n path: {\n type: 'string',\n description: '文件路径',\n },\n content: {\n type: 'string',\n description: '要写入的文件内容',\n },\n overwrite: {\n type: 'boolean',\n description: '文件已存在时是否确认覆盖,默认 false',\n },\n },\n required: ['path', 'content'],\n },\n permissionLevel: 'confirm',\n\n async execute(params: Record<string, unknown>): Promise<ToolResult> {\n const filePath = path.resolve(params['path'] as string);\n const content = params['content'] as string;\n\n try {\n // 确保父目录存在\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, content, 'utf-8');\n return { content: `文件已写入:${filePath}` };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return { content: `写入文件失败:${msg}` };\n }\n },\n};\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { Tool, ToolResult } from './types.js';\n\nexport const editFileTool: Tool = {\n name: 'edit-file',\n description: '通过字符串替换编辑文件(推荐的文件修改方式)。old_string 必须在文件中唯一匹配,将被替换为 new_string。匹配失败时请提供更多上下文使其唯一,或使用 replace_all。',\n parameters: {\n type: 'object',\n properties: {\n path: {\n type: 'string',\n description: '文件路径',\n },\n old_string: {\n type: 'string',\n description: '要被替换的原始字符串(必须唯一匹配)',\n },\n new_string: {\n type: 'string',\n description: '替换后的字符串',\n },\n replace_all: {\n type: 'boolean',\n description: '是否替换所有匹配项,默认 false',\n },\n },\n required: ['path', 'old_string', 'new_string'],\n },\n permissionLevel: 'confirm',\n\n async execute(params: Record<string, unknown>): Promise<ToolResult> {\n const filePath = path.resolve(params['path'] as string);\n const oldString = params['old_string'] as string;\n const newString = params['new_string'] as string;\n const replaceAll = (params['replace_all'] as boolean) ?? false;\n\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n\n if (replaceAll) {\n const newContent = content.split(oldString).join(newString);\n if (newContent === content) {\n return { content: `未找到匹配内容:${oldString.slice(0, 50)}...` };\n }\n await fs.writeFile(filePath, newContent, 'utf-8');\n const count = content.split(oldString).length - 1;\n return { content: `已替换 ${count} 处匹配` };\n }\n\n // 检查唯一性\n const firstIdx = content.indexOf(oldString);\n if (firstIdx === -1) {\n return { content: `未找到匹配内容:${oldString.slice(0, 100)}` };\n }\n\n const secondIdx = content.indexOf(oldString, firstIdx + 1);\n if (secondIdx !== -1) {\n return { content: `old_string 不唯一,找到多处匹配。请提供更多上下文使其唯一。` };\n }\n\n const newContent = content.slice(0, firstIdx) + newString + content.slice(firstIdx + oldString.length);\n await fs.writeFile(filePath, newContent, 'utf-8');\n\n return { content: `文件已编辑:${filePath}` };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return { content: `编辑文件失败:${msg}` };\n }\n },\n};\n","import { exec } from 'node:child_process';\nimport type { Tool, ToolResult } from './types.js';\n\nconst DEFAULT_TIMEOUT = 120_000; // 2 minutes\nconst IS_WIN = process.platform === 'win32';\n\n/**\n * Windows cmd.exe 默认用系统代码页(如 GBK/CP936)输出,\n * 需要先以 buffer 读取再用正确编码解码,否则中文乱码。\n */\nfunction decodeBuffer(buf: Buffer): string {\n if (!IS_WIN) return buf.toString('utf-8');\n try {\n // Node.js 不原生支持 GBK,优先尝试 TextDecoder\n const decoder = new TextDecoder('gbk');\n return decoder.decode(buf);\n } catch {\n return buf.toString('utf-8');\n }\n}\n\nexport const bashTool: Tool = {\n name: 'bash',\n description: IS_WIN\n ? '执行系统命令(shell: cmd.exe)。用于运行构建、测试、git 等。Windows 环境请使用 Windows 命令(dir、type、copy)或 Python 跨平台命令,不要使用 Unix 命令(ls、cat、cp)。不要用 bash 做文件读写(用 read-file/edit-file/write-file)或搜索(用 glob/grep)。'\n : '执行 shell 命令(shell: /bin/bash)。用于运行构建、测试、git 操作等系统命令。不要用 bash 做文件读写(用 read-file/edit-file/write-file)或搜索(用 glob/grep)。',\n parameters: {\n type: 'object',\n properties: {\n command: {\n type: 'string',\n description: '要执行的 shell 命令',\n },\n timeout: {\n type: 'number',\n description: '超时时间(毫秒),默认 120000',\n },\n },\n required: ['command'],\n },\n permissionLevel: 'confirm',\n\n async execute(params: Record<string, unknown>): Promise<ToolResult> {\n const command = params['command'] as string;\n const timeout = (params['timeout'] as number) || DEFAULT_TIMEOUT;\n\n return new Promise<ToolResult>((resolve) => {\n exec(\n command,\n {\n cwd: process.cwd(),\n timeout,\n maxBuffer: 1024 * 1024 * 10, // 10MB\n shell: process.platform === 'win32' ? 'cmd.exe' : '/bin/bash',\n encoding: 'buffer',\n },\n (error, stdoutBuf, stderrBuf) => {\n const stdout = stdoutBuf ? decodeBuffer(stdoutBuf) : '';\n const stderr = stderrBuf ? decodeBuffer(stderrBuf) : '';\n\n let output = '';\n if (stdout) output += stdout;\n if (stderr) output += (output ? '\\n' : '') + `[stderr]\\n${stderr}`;\n if (error && error.killed) {\n output += `\\n[命令超时,已终止]`;\n } else if (error && !stdout && !stderr) {\n output = `命令执行失败:${error.message}`;\n }\n\n resolve({ content: output || '(无输出)' });\n },\n );\n });\n },\n};\n","import { glob as globFn } from 'glob';\nimport type { Tool, ToolResult } from './types.js';\n\nexport const globTool: Tool = {\n name: 'glob',\n description: '按 glob 模式搜索文件路径。用于查找文件位置,如 \"**/*.ts\"、\"src/**/config.*\"。自动忽略 node_modules 和 .git。',\n parameters: {\n type: 'object',\n properties: {\n pattern: {\n type: 'string',\n description: 'Glob 模式,如 \"**/*.ts\"、\"src/**/*.js\"',\n },\n cwd: {\n type: 'string',\n description: '搜索的根目录,默认为工作目录',\n },\n },\n required: ['pattern'],\n },\n permissionLevel: 'auto',\n\n async execute(params: Record<string, unknown>): Promise<ToolResult> {\n const pattern = params['pattern'] as string;\n const cwd = (params['cwd'] as string) || process.cwd();\n\n try {\n const files = await globFn(pattern, {\n cwd,\n nodir: true,\n dot: false,\n ignore: ['**/node_modules/**', '**/.git/**'],\n });\n\n if (files.length === 0) {\n return { content: '未找到匹配的文件' };\n }\n\n return { content: files.join('\\n') };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return { content: `搜索失败:${msg}` };\n }\n },\n};\n","import { exec } from 'node:child_process';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { Tool, ToolResult } from './types.js';\n\n/**\n * 纯 JS 实现的 grep,不依赖外部命令\n */\nasync function jsGrep(\n pattern: string,\n searchPath: string,\n options: { ignoreCase?: boolean; maxResults?: number; glob?: string },\n): Promise<string[]> {\n const regex = new RegExp(pattern, options.ignoreCase ? 'i' : '');\n const results: string[] = [];\n const maxResults = options.maxResults ?? 200;\n\n async function searchFile(filePath: string) {\n if (results.length >= maxResults) return;\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n const lines = content.split('\\n');\n for (let i = 0; i < lines.length; i++) {\n if (results.length >= maxResults) break;\n if (regex.test(lines[i]!)) {\n results.push(`${filePath}:${i + 1}: ${lines[i]}`);\n }\n }\n } catch {\n // 跳过无法读取的文件\n }\n }\n\n async function searchDir(dirPath: string) {\n if (results.length >= maxResults) return;\n try {\n const entries = await fs.readdir(dirPath, { withFileTypes: true });\n for (const entry of entries) {\n if (results.length >= maxResults) break;\n const fullPath = path.join(dirPath, entry.name);\n\n // 跳过常见无关目录\n if (entry.isDirectory()) {\n if (['node_modules', '.git', 'dist', '.next', '__pycache__'].includes(entry.name)) {\n continue;\n }\n await searchDir(fullPath);\n } else if (entry.isFile()) {\n // 简单过滤二进制文件\n const ext = path.extname(entry.name).toLowerCase();\n const textExts = [\n '.ts', '.tsx', '.js', '.jsx', '.json', '.md', '.txt', '.yaml', '.yml',\n '.toml', '.css', '.scss', '.html', '.vue', '.svelte', '.py', '.go',\n '.rs', '.java', '.c', '.cpp', '.h', '.hpp', '.rb', '.php', '.sh',\n '.bash', '.zsh', '.fish', '.sql', '.xml', '.svg', '.env', '.gitignore',\n '.editorconfig', '.prettierrc', '.eslintrc',\n ];\n if (ext && !textExts.includes(ext)) continue;\n await searchFile(fullPath);\n }\n }\n } catch {\n // 跳过无法访问的目录\n }\n }\n\n const stat = await fs.stat(searchPath);\n if (stat.isFile()) {\n await searchFile(searchPath);\n } else {\n await searchDir(searchPath);\n }\n\n return results;\n}\n\nexport const grepTool: Tool = {\n name: 'grep',\n description: '在文件内容中搜索正则表达式。用于查找函数定义、类引用、特定代码模式。返回匹配的文件路径、行号和内容。',\n parameters: {\n type: 'object',\n properties: {\n pattern: {\n type: 'string',\n description: '正则表达式搜索模式',\n },\n path: {\n type: 'string',\n description: '搜索的文件或目录路径,默认为工作目录',\n },\n ignore_case: {\n type: 'boolean',\n description: '是否忽略大小写',\n },\n },\n required: ['pattern'],\n },\n permissionLevel: 'auto',\n\n async execute(params: Record<string, unknown>): Promise<ToolResult> {\n const pattern = params['pattern'] as string;\n const searchPath = (params['path'] as string) || process.cwd();\n const ignoreCase = (params['ignore_case'] as boolean) ?? false;\n\n try {\n const resolvedPath = path.resolve(searchPath);\n const results = await jsGrep(pattern, resolvedPath, {\n ignoreCase,\n maxResults: 200,\n });\n\n if (results.length === 0) {\n return { content: '未找到匹配内容' };\n }\n\n return { content: results.join('\\n') };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return { content: `搜索失败:${msg}` };\n }\n },\n};\n","import { ToolRegistry } from '../tools/registry.js';\nimport { readFileTool } from '../tools/read-file.js';\nimport { writeFileTool } from '../tools/write-file.js';\nimport { editFileTool } from '../tools/edit-file.js';\nimport { bashTool } from '../tools/bash.js';\nimport { globTool } from '../tools/glob.js';\nimport { grepTool } from '../tools/grep.js';\n\n/**\n * 注册所有核心工具\n */\nexport function registerCoreTools(registry: ToolRegistry): void {\n registry.register(readFileTool);\n registry.register(writeFileTool);\n registry.register(editFileTool);\n registry.register(bashTool);\n registry.register(globTool);\n registry.register(grepTool);\n}\n","import chalk from 'chalk';\n\n/**\n * 确认处理函数类型\n * 接收提示文本,返回用户是否同意\n */\nexport type ConfirmHandler = (prompt: string) => Promise<boolean>;\n\n/**\n * 结构化确认结果\n */\nexport interface ConfirmExecutionResult {\n approved: boolean;\n feedback?: string;\n}\n\n/**\n * 结构化确认处理函数类型\n * 接收工具名和参数,返回确认结果(含可选反馈)\n * 用于 TUI 模式,避免 chalk 格式化字符串\n */\nexport type StructuredConfirmHandler = (\n toolName: string,\n params: Record<string, unknown>,\n) => Promise<ConfirmExecutionResult>;\n\n/**\n * 全局确认处理函数(由 REPL 注入)\n * 默认实现:自动拒绝(安全兜底)\n */\nlet globalConfirmHandler: ConfirmHandler = async () => false;\n\n/**\n * 结构化确认处理函数(由 TUI 注入)\n * 当设置时,confirmExecution 优先使用此 handler,跳过 stderr 输出\n */\nlet structuredConfirmHandler: StructuredConfirmHandler | null = null;\n\n/**\n * 设置全局确认处理函数\n */\nexport function setConfirmHandler(handler: ConfirmHandler): void {\n globalConfirmHandler = handler;\n}\n\n/**\n * 设置结构化确认处理函数(TUI 模式使用)\n * 当设置后,confirmExecution 将直接传递 toolName 和 params,\n * 而不是格式化为 chalk 字符串输出到 stderr\n */\nexport function setStructuredConfirmHandler(handler: StructuredConfirmHandler | null): void {\n structuredConfirmHandler = handler;\n}\n\n/**\n * 格式化工具调用的详细信息\n */\nfunction formatToolDetail(toolName: string, params: Record<string, unknown>): string {\n const lines: string[] = [];\n\n switch (toolName) {\n case 'bash':\n lines.push(` ${chalk.dim('命令:')} ${chalk.white(String(params['command'] || ''))}`);\n break;\n case 'write-file':\n lines.push(` ${chalk.dim('文件:')} ${chalk.white(String(params['path'] || ''))}`);\n if (params['content']) {\n const content = String(params['content']);\n const preview = content.length > 200 ? content.slice(0, 200) + '...' : content;\n lines.push(` ${chalk.dim('内容:')} ${chalk.gray(preview.split('\\n').join('\\n '))}`);\n }\n break;\n case 'edit-file':\n lines.push(` ${chalk.dim('文件:')} ${chalk.white(String(params['path'] || ''))}`);\n if (params['old_string']) {\n const old = String(params['old_string']);\n const preview = old.length > 100 ? old.slice(0, 100) + '...' : old;\n lines.push(` ${chalk.dim('替换:')} ${chalk.red(preview)}`);\n }\n if (params['new_string']) {\n const neu = String(params['new_string']);\n const preview = neu.length > 100 ? neu.slice(0, 100) + '...' : neu;\n lines.push(` ${chalk.dim('为 :')} ${chalk.green(preview)}`);\n }\n break;\n case 'git':\n lines.push(` ${chalk.dim('命令:')} git ${chalk.white(String(params['command'] || ''))}`);\n break;\n default:\n for (const [key, value] of Object.entries(params)) {\n const str = typeof value === 'string' ? value : JSON.stringify(value);\n lines.push(` ${chalk.dim(key + ':')} ${str.slice(0, 120)}`);\n }\n break;\n }\n\n return lines.join('\\n');\n}\n\n/**\n * 向用户确认是否执行危险操作\n */\nexport async function confirmExecution(\n toolName: string,\n params: Record<string, unknown>,\n): Promise<ConfirmExecutionResult> {\n // TUI 模式:使用结构化 handler,跳过 stderr 输出\n if (structuredConfirmHandler) {\n return structuredConfirmHandler(toolName, params);\n }\n\n // REPL 模式:格式化并输出到 stderr\n const detail = formatToolDetail(toolName, params);\n const prompt = `\\n${chalk.yellow('⚠')} ${chalk.bold('需要确认')} ${chalk.cyan(`[${toolName}]`)}\\n${detail}\\n`;\n\n process.stderr.write(prompt);\n const approved = await globalConfirmHandler(`${chalk.yellow('?')} 是否执行?(${chalk.green('y')}/${chalk.red('N')}) `);\n return { approved };\n}\n","import type { Message } from '../llm/types.js';\n\n/**\n * 对话历史管理\n */\nexport class Conversation {\n private messages: Message[] = [];\n private systemPrompt: string = '';\n\n setSystemPrompt(prompt: string): void {\n this.systemPrompt = prompt;\n }\n\n addMessage(message: Message): void {\n this.messages.push(message);\n }\n\n addUserMessage(content: string): void {\n this.messages.push({ role: 'user', content });\n }\n\n addAssistantMessage(message: Message): void {\n this.messages.push(message);\n }\n\n addToolResult(toolCallId: string, content: string): void {\n this.messages.push({\n role: 'tool',\n tool_call_id: toolCallId,\n content,\n });\n }\n\n /**\n * 清除历史消息中的 reasoning_content(新一轮对话开始时调用)\n * deepseek-reasoner 要求同一轮 tool call 循环内保留 reasoning_content,\n * 但新一轮用户问题开始时应清除以节省带宽,API 也会忽略旧的 reasoning_content\n */\n clearReasoningContent(): void {\n for (const msg of this.messages) {\n if (msg.reasoning_content !== undefined) {\n msg.reasoning_content = undefined;\n }\n }\n }\n\n /**\n * 获取完整的消息列表(包含系统提示词)\n */\n getMessages(): Message[] {\n const result: Message[] = [];\n if (this.systemPrompt) {\n result.push({ role: 'system', content: this.systemPrompt });\n }\n result.push(...this.messages);\n return result;\n }\n\n /**\n * 获取不含系统提示词的历史消息\n */\n getHistory(): Message[] {\n return [...this.messages];\n }\n\n /**\n * 清空对话历史(保留系统提示词)\n */\n clear(): void {\n this.messages = [];\n }\n\n /**\n * 获取消息数量\n */\n get length(): number {\n return this.messages.length;\n }\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\n/**\n * 跟踪当前 Agent 会话中已读取的文件路径\n *\n * 用于强制执行\"先读后改\"规则:\n * - read-file 成功后标记为已读\n * - write-file 成功后标记为已读(agent 刚写入,知道内容)\n * - edit-file 调用前检查是否已读,未读则拒绝并提示\n *\n * 同时提供 write-file 覆盖检查:\n * - 文件已存在且未传 overwrite: true → 返回警告\n */\nexport class ReadTracker {\n private files = new Set<string>();\n\n /** 标记文件已被读取 */\n markRead(filePath: string): void {\n this.files.add(this.normalize(filePath));\n }\n\n /** 标记文件已被写入(新建/重写,agent 已知内容) */\n markWritten(filePath: string): void {\n this.files.add(this.normalize(filePath));\n }\n\n /** 检查文件是否已读取 */\n hasRead(filePath: string): boolean {\n return this.files.has(this.normalize(filePath));\n }\n\n /**\n * 检查 write-file 是否会覆盖已有文件\n * @returns 警告消息(需要拦截),或 null(可以继续执行)\n */\n checkWriteOverwrite(filePath: string, overwrite?: boolean): string | null {\n const resolved = path.resolve(filePath);\n if (!overwrite && fs.existsSync(resolved)) {\n return `⚠ 文件已存在:${filePath}\\n修改已有文件请用 read-file + edit-file(更精确安全)。\\n如确需完整重写,请重新调用 write-file 并设置 overwrite: true。`;\n }\n return null;\n }\n\n private normalize(filePath: string): string {\n return filePath.replace(/\\\\/g, '/').replace(/^\\.\\//, '');\n }\n}\n","import type { ZenCodeConfig } from '../config/types.js';\nimport type { Message, ToolDefinition } from '../llm/types.js';\nimport type { LLMClient, StreamCallbacks } from '../llm/client.js';\nimport type { ToolRegistry } from '../tools/registry.js';\nimport { confirmExecution } from '../tools/permission.js';\nimport { Conversation } from './conversation.js';\nimport { ReadTracker } from './read-tracker.js';\n\nexport interface AgentCallbacks extends StreamCallbacks {\n onToolExecuting?: (toolName: string, params: Record<string, unknown>) => void;\n onToolResult?: (toolName: string, result: string, truncated: boolean) => void;\n onDenied?: (toolName: string, feedback?: string) => void;\n}\n\n/**\n * 单 Agent 循环\n *\n * 消息流程:\n * 用户输入 → 构建消息 → LLM (带tools) → 处理响应\n * ├─ 含工具调用 → 执行工具 → 结果加入历史 → 回到 LLM\n * └─ 纯文本响应 → 返回\n */\nexport class Agent {\n private conversation: Conversation;\n private client: LLMClient;\n private registry: ToolRegistry;\n private config: ZenCodeConfig;\n private fixedTools?: ToolDefinition[];\n private readTracker = new ReadTracker();\n private interrupted = false;\n\n constructor(\n client: LLMClient,\n registry: ToolRegistry,\n config: ZenCodeConfig,\n systemPrompt: string,\n tools?: ToolDefinition[],\n ) {\n this.client = client;\n this.registry = registry;\n this.config = config;\n this.conversation = new Conversation();\n this.conversation.setSystemPrompt(systemPrompt);\n this.fixedTools = tools;\n }\n\n /**\n * 执行一轮完整的 agent 循环\n */\n async run(userMessage: string, callbacks: AgentCallbacks = {}): Promise<string> {\n this.interrupted = false;\n // 新一轮对话:清除历史中的 reasoning_content(deepseek-reasoner 兼容)\n this.conversation.clearReasoningContent();\n this.conversation.addUserMessage(userMessage);\n\n let lastContent = '';\n\n while (true) {\n if (this.interrupted) break;\n // 每轮动态获取工具列表,确保 /parallel /todo 等切换生效\n const tools = this.fixedTools || this.registry.toToolDefinitions();\n\n // 调用 LLM\n const assistantMsg = await this.client.chatStream(\n this.conversation.getMessages(),\n tools.length > 0 ? tools : undefined,\n callbacks,\n );\n\n this.conversation.addAssistantMessage(assistantMsg);\n\n // 如果没有工具调用,结束循环\n if (!assistantMsg.tool_calls || assistantMsg.tool_calls.length === 0) {\n lastContent = assistantMsg.content || '';\n break;\n }\n\n // 执行所有工具调用\n for (const toolCall of assistantMsg.tool_calls) {\n if (this.interrupted) break;\n const toolName = toolCall.function.name;\n let params: Record<string, unknown>;\n try {\n params = JSON.parse(toolCall.function.arguments);\n } catch {\n this.conversation.addToolResult(toolCall.id, '参数解析失败:无效的 JSON');\n continue;\n }\n\n try {\n // 先读后改:edit-file 必须先 read-file\n if (toolName === 'edit-file') {\n const editPath = params['path'] as string;\n if (!this.readTracker.hasRead(editPath)) {\n this.conversation.addToolResult(toolCall.id,\n `⚠ 禁止编辑未读取的文件。请先 read-file \"${editPath}\" 了解当前内容,再 edit-file。`);\n continue;\n }\n }\n\n // write-file 覆盖检查:文件已存在时需要 overwrite: true\n if (toolName === 'write-file') {\n const warn = this.readTracker.checkWriteOverwrite(\n params['path'] as string,\n params['overwrite'] as boolean | undefined,\n );\n if (warn) {\n this.conversation.addToolResult(toolCall.id, warn);\n continue;\n }\n }\n\n // 权限检查\n const permLevel = this.registry.getPermissionLevel(toolName);\n if (permLevel === 'deny') {\n callbacks.onDenied?.(toolName);\n this.conversation.addToolResult(toolCall.id, `工具 \"${toolName}\" 已被禁止执行`);\n continue;\n }\n\n // 自动执行的工具直接显示并执行\n if (permLevel === 'auto') {\n callbacks.onToolExecuting?.(toolName, params);\n }\n\n if (permLevel === 'confirm') {\n const confirmResult = await confirmExecution(toolName, params);\n if (!confirmResult.approved) {\n callbacks.onDenied?.(toolName, confirmResult.feedback);\n const denyMsg = confirmResult.feedback\n ? `用户拒绝了此操作,用户反馈: ${confirmResult.feedback}`\n : '用户拒绝了此操作';\n this.conversation.addToolResult(toolCall.id, denyMsg);\n continue;\n }\n }\n\n // 执行工具\n const result = await this.registry.execute(toolName, params, this.config.max_tool_output);\n callbacks.onToolResult?.(toolName, result.content, result.truncated ?? false);\n\n // 跟踪已读/已写文件\n if (toolName === 'read-file') {\n this.readTracker.markRead(params['path'] as string);\n } else if (toolName === 'write-file') {\n this.readTracker.markWritten(params['path'] as string);\n }\n\n this.conversation.addToolResult(toolCall.id, result.content);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.conversation.addToolResult(toolCall.id, `工具执行异常:${msg}`);\n }\n }\n\n // 记录最后的文本内容\n if (assistantMsg.content) {\n lastContent = assistantMsg.content;\n }\n }\n\n return lastContent;\n }\n\n interrupt(): void {\n this.interrupted = true;\n this.client.abortActiveStream();\n }\n\n /**\n * 获取对话历史\n */\n getConversation(): Conversation {\n return this.conversation;\n }\n}\n","import * as os from 'node:os';\n\nconst IS_WIN = os.platform() === 'win32';\n\n/**\n * Layer 0 - 核心层(始终加载)\n */\nexport function buildCorePrompt(): string {\n const shellInfo = IS_WIN\n ? 'cmd.exe(Windows)。请使用 Windows 命令(dir、type、copy 等)或 Python 跨平台命令(python -c \"...\"),不要使用 Unix 命令(ls、cat、cp 等)'\n : '/bin/bash';\n\n return `你是 ZenCode,一个 CLI 环境下的 AI 编程助手。你帮助用户完成软件工程任务:修bug、加功能、重构代码、解释代码等。\n\n工作目录:${process.cwd()}\n系统:${os.platform()} ${os.arch()}\n\n# 工具使用原则\n\n你有以下工具可用,请根据任务选择最合适的工具:\n\n- **read-file**:读取文件内容。修改代码前必须先读取目标文件。支持 offset/limit 读取大文件的特定部分。\n- **edit-file**:通过字符串替换编辑文件。优先使用 edit-file 而非 write-file 修改已有文件——它更精确、更安全。\n - ⚠️ 系统强制:未用 read-file 读取过的文件无法 edit-file,会被拦截\n - old_string 必须与文件中的内容**完全一致**(包括缩进、空格、换行符)\n - old_string 不唯一时,包含更多上下文行(建议 3-5 行)使其唯一\n - 不要凭记忆猜测文件内容,必须基于 read-file 的实际返回值\n- **write-file**:创建新文件或完整重写文件。仅在创建新文件或需要大幅重写时使用。\n- **glob**:按模式搜索文件路径。用于查找文件位置(如 \\`**/*.ts\\`、\\`src/**/config.*\\`)。\n- **grep**:在文件内容中搜索正则表达式。用于查找函数定义、引用、特定代码模式。\n- **bash**:执行系统命令,当前 shell:${shellInfo}。用于运行构建、测试、git 操作等。不要用 bash 做能用上述工具完成的事(文件读写用 read-file/edit-file/write-file,搜索用 glob/grep)。\n\n关键规则:\n- **先读后改**:修改文件前必须 read-file 读取该文件(系统会拦截未读取就 edit 的操作)\n- edit-file 的 old_string 必须从 read-file 返回的内容中精确复制,不要手动输入或凭记忆\n- 优先 edit-file 编辑已有文件,而非 write-file 重写\n- 不要创建不必要的新文件,优先在现有文件中修改\n- 只做必要的最小改动,不做额外\"改进\"\n- 不要添加用户未要求的注释、文档、类型注解\n- 不要引入安全漏洞(注入、XSS、SQL 注入等 OWASP Top 10)\n- 引用代码时使用 \\`文件路径:行号\\` 格式(如 \\`src/app.ts:42\\`),方便用户跳转\n\n# 交互风格\n\n- 保持技术客观性,基于事实回答,不过度赞同或恭维用户,必要时直接指出问题\n- 不确定时先调查验证,而非直觉性地确认用户的假设\n- 不要给出时间预估(\"大概需要几分钟\"之类)\n- 回复简洁,直接给结果`;\n}\n","/**\n * Layer 1 - 工作方法层(默认开启)\n */\nexport function buildPlanningPrompt(): string {\n return `# 工作方法\n\n处理编程任务时:\n1. 先用 read-file / grep / glob 阅读相关代码,理解现有逻辑和上下文\n2. 判断任务的复杂程度,简单任务直接执行,复杂任务先做计划\n3. 如果用户的要求不清晰,一定要询问用户,确定细节\n\n多步任务管理:\n- 对于 3 个以上步骤的任务,使用 todo 工具创建计划再逐步执行\n- 开始步骤前标记 in-progress,完成后标记 completed\n- 每步完成后检查计划,决定下一步\n\n代码质量:\n- 如果删除了代码,就彻底删除,不要留注释说\"已移除\",不要保留未使用的兼容性变量\n- 不要留下TODO然后放着不管`;\n}\n\n","/**\n * Layer - 并行子 Agent 提示词层\n *\n * 核心原则:让\"并行\"成为默认行为,而非可选项。\n * LLM 天然倾向串行调用工具,必须用强指令扭转这一惯性。\n */\nexport function buildParallelPrompt(): string {\n return `# 并行执行(重要)\n\n当需要读取、搜索或分析 2 个以上独立目标时,必须使用 spawn-agents 并行执行,不要逐个串行调用。\n\n规则:\n- 需要读 2+ 个文件 → spawn-agents 并行读取\n- 需要搜索 2+ 个模式 → spawn-agents 并行搜索\n- 需要了解 2+ 个模块 → spawn-agents 并行分析\n- 只有 1 个目标 → 直接用工具,无需 spawn-agents\n\n示例 - 用户说\"帮我理解认证模块\":\n 正确:spawn-agents 同时读 auth controller、auth service、auth middleware、auth types\n 错误:先 read-file controller,再 read-file service,再 read-file middleware...\n\n每个子 Agent 有独立对话,默认可用 read-file、glob、grep。`;\n}\n","/**\n * Layer 2 - Git 层(检测到 .git 时加载)\n */\nexport function buildGitPrompt(): string {\n return `# Git 操作\n\n当前项目使用 git 管理。\n\n提交规范:\n- 只在用户明确要求时才创建 commit\n- 用 git diff 查看变更,再写 commit message\n- commit message 描述\"为什么\"而非\"改了什么\"\n\n安全规则:\n- 不要 force push、reset --hard、checkout .、clean -f 等破坏性操作,除非用户明确要求\n- 不要 --no-verify 跳过 hook,除非用户明确要求\n- 优先创建新 commit,不要 --amend 修改已有 commit,除非用户明确要求(hook 失败后 amend 会破坏上一个 commit)\n- git add 时指定具体文件,避免 git add -A 意外暂存敏感文件(.env、credentials 等)\n- 不要使用交互式标志(git rebase -i、git add -i),CLI 环境不支持\n- 不要修改 git config`;\n}\n","import type { SubAgentConfig } from '../../sub-agents/types.js';\n\n/**\n * Layer - 子 Agent 提示词层\n *\n * 当有可用子 Agent 时注入,告诉模型何时使用 dispatch。\n */\nexport function buildAgentsPrompt(agents: SubAgentConfig[]): string | null {\n if (agents.length === 0) return null;\n\n const agentList = agents\n .map(a => `- **${a.name}**:${a.description}`)\n .join('\\n');\n\n return `# 子 Agent\n\n你可以通过 dispatch 工具调度以下专用子 Agent:\n\n${agentList}\n\n使用场景:当任务需要专业角色(如代码审查、架构分析)且子 Agent 的能力比你直接做更合适时,使用 dispatch 委派。`;\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\n/**\n * Layer 3 - 项目层(从 ZENCODE.md 加载)\n */\nexport async function buildProjectPrompt(): Promise<string | null> {\n try {\n const content = await fs.readFile(path.resolve('ZENCODE.md'), 'utf-8');\n return content.trim() || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Layer 4 - 用户自定义提示词(从指定路径加载)\n */\nexport async function loadUserPrompts(paths: string[]): Promise<string[]> {\n const prompts: string[] = [];\n for (const p of paths) {\n try {\n const resolved = p.startsWith('~')\n ? path.join(process.env['HOME'] || process.env['USERPROFILE'] || '', p.slice(1))\n : path.resolve(p);\n const content = await fs.readFile(resolved, 'utf-8');\n if (content.trim()) {\n prompts.push(content.trim());\n }\n } catch {\n // 跳过不存在的文件\n }\n }\n return prompts;\n}\n","import * as fs from 'node:fs';\nimport type { ZenCodeConfig } from '../../config/types.js';\nimport type { SubAgentConfig } from '../sub-agents/types.js';\nimport { buildCorePrompt } from './layers/core.js';\nimport { buildPlanningPrompt } from './layers/planning.js';\nimport { buildParallelPrompt } from './layers/parallel.js';\nimport { buildGitPrompt } from './layers/git.js';\nimport { buildAgentsPrompt } from './layers/agents.js';\nimport { buildProjectPrompt, loadUserPrompts } from './layers/project.js';\n\nexport interface PromptBuildResult {\n systemPrompt: string;\n layers: string[];\n}\n\n/**\n * 检测当前目录是否为 git 仓库\n */\nfunction isGitRepo(): boolean {\n try {\n fs.statSync('.git');\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * 分层提示词构建器 - 按需组装各层\n */\nexport async function buildPrompt(config: ZenCodeConfig, agents?: SubAgentConfig[]): Promise<PromptBuildResult> {\n const layers: string[] = [];\n\n // Layer 0: 核心层(始终加载)\n layers.push(buildCorePrompt());\n\n // Layer 1: 思考层(默认开启)\n if (config.features.planning_layer === 'on') {\n layers.push(buildPlanningPrompt());\n }\n\n // Layer 2: Git 层(自动检测或手动开启)\n const gitEnabled =\n config.features.git === 'on' ||\n (config.features.git === 'auto' && isGitRepo());\n if (gitEnabled) {\n layers.push(buildGitPrompt());\n }\n\n // Layer 3: 并行子 Agent 层\n if (config.features.parallel_agents === 'on') {\n layers.push(buildParallelPrompt());\n }\n\n // Layer 4: 子 Agent 层(有可用 agent 时加载)\n if (agents && agents.length > 0) {\n const agentsPrompt = buildAgentsPrompt(agents);\n if (agentsPrompt) {\n layers.push(agentsPrompt);\n }\n }\n\n // Layer 5: 项目层(ZENCODE.md)\n const projectPrompt = await buildProjectPrompt();\n if (projectPrompt) {\n layers.push(projectPrompt);\n }\n\n // Layer 6: 用户自定义提示词\n if (config.prompts.length > 0) {\n const userPrompts = await loadUserPrompts(config.prompts);\n layers.push(...userPrompts);\n }\n\n // 合并所有层\n const systemPrompt = layers.join('\\n\\n');\n\n return { systemPrompt, layers };\n}\n\n","export interface TodoItem {\n id: string;\n title: string;\n status: 'pending' | 'in-progress' | 'completed';\n}\n\nexport interface TodoPlan {\n items: TodoItem[];\n}\n\ntype TodoListener = (plan: TodoPlan | null) => void;\n\n/**\n * Todo 状态存储(可观察)\n *\n * LLM 通过 todo 工具操作,TUI 订阅变化实时渲染面板\n */\nexport class TodoStore {\n private plan: TodoPlan | null = null;\n private listeners = new Set<TodoListener>();\n\n create(items: { id: string; title: string }[]): TodoPlan {\n this.plan = {\n items: items.map((item) => ({\n id: item.id,\n title: item.title,\n status: 'pending' as const,\n })),\n };\n this.notify();\n return this.plan;\n }\n\n update(id: string, status: TodoItem['status']): TodoItem | null {\n if (!this.plan) return null;\n const item = this.plan.items.find((i) => i.id === id);\n if (!item) return null;\n item.status = status;\n this.notify();\n return { ...item };\n }\n\n list(): TodoPlan | null {\n return this.plan;\n }\n\n clear(): void {\n this.plan = null;\n this.notify();\n }\n\n subscribe(listener: TodoListener): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n private notify(): void {\n const snapshot = this.plan\n ? { items: this.plan.items.map((i) => ({ ...i })) }\n : null;\n for (const listener of this.listeners) {\n listener(snapshot);\n }\n }\n}\n","import type { SubAgentConfig } from './types.js';\n\n/**\n * 子 Agent 配置注册表\n */\nexport class SubAgentConfigRegistry {\n private configs = new Map<string, SubAgentConfig>();\n\n register(config: SubAgentConfig): void {\n this.configs.set(config.name, config);\n }\n\n get(name: string): SubAgentConfig | undefined {\n return this.configs.get(name);\n }\n\n has(name: string): boolean {\n return this.configs.has(name);\n }\n\n list(): SubAgentConfig[] {\n return [...this.configs.values()];\n }\n\n listNames(): string[] {\n return [...this.configs.keys()];\n }\n\n /**\n * 生成子 Agent 列表描述(用于 dispatch 工具的说明)\n */\n buildAgentListDescription(): string {\n if (this.configs.size === 0) return '暂无可用子 Agent';\n return [...this.configs.values()]\n .map(s => `- ${s.name}: ${s.description}`)\n .join('\\n');\n }\n}\n","import type { SubAgentConfig } from './types.js';\n\n/**\n * 内置预置子 Agent\n *\n * 优先级最低,可被全局/项目 YAML 同名配置覆盖。\n */\nexport const presetAgents: SubAgentConfig[] = [\n {\n name: 'reviewer',\n description: '代码审查:发现 bug、安全漏洞、性能问题',\n prompt: `你是代码审查专家。审查用户指定的代码,输出发现的问题。\n\n审查维度(按优先级):\n1. 正确性:逻辑错误、边界条件、空值/未定义处理\n2. 安全:注入、XSS、敏感信息泄露、权限检查\n3. 性能:不必要的循环、内存泄漏、N+1 查询\n4. 可维护性:命名、重复代码、过度复杂\n\n输出格式:\n- 每个问题:文件路径:行号 + 问题描述 + 建议修复\n- 没有问题就说没有问题,不要硬凑\n- 不要重写代码,只指出问题和修复方向`,\n tools: ['read-file', 'glob', 'grep'],\n max_turns: 10,\n timeout: 60,\n },\n {\n name: 'researcher',\n description: '代码库研究:深度分析架构、依赖和实现细节',\n prompt: `你是代码库研究员。深入分析用户指定的代码库或模块,输出结构化的分析报告。\n\n分析方法:\n1. 先 glob 了解文件结构\n2. grep 搜索关键入口点、导出、依赖\n3. read-file 阅读核心文件\n\n输出内容:\n- 模块职责和边界\n- 关键文件及其作用\n- 数据流和调用链\n- 外部依赖\n- 如有用户具体问题,针对性回答`,\n tools: ['read-file', 'glob', 'grep'],\n max_turns: 15,\n timeout: 120,\n },\n {\n name: 'refactor',\n description: '重构专家:分析代码结构并实施重构',\n prompt: `你是重构专家。分析用户指定的代码,找出可重构的点并实施重构。\n\n重构原则:\n- 只做有明确收益的重构(消除重复、降低复杂度、改善命名)\n- 保持行为不变,不添加新功能\n- 每次只做一个重构,不要同时改太多\n- 修改前必须 read-file 确认当前内容\n\n常见重构:\n- 提取重复代码为函数\n- 简化过深的嵌套(提前返回)\n- 拆分过大的函数\n- 改善命名使意图更清晰`,\n tools: ['read-file', 'write-file', 'edit-file', 'glob', 'grep'],\n max_turns: 15,\n timeout: 120,\n },\n];\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\nimport { parse as parseYaml } from 'yaml';\nimport type { SubAgentConfig } from './types.js';\nimport { presetAgents } from './presets.js';\n\n/**\n * 从 YAML 文件加载单个子 Agent 配置\n */\nfunction loadAgentYaml(filePath: string): SubAgentConfig | null {\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n const parsed = parseYaml(content) as Record<string, unknown>;\n if (!parsed || typeof parsed !== 'object') return null;\n if (!parsed['name'] || !parsed['prompt'] || !parsed['tools']) return null;\n\n return {\n name: parsed['name'] as string,\n description: (parsed['description'] as string) || '',\n prompt: parsed['prompt'] as string,\n tools: parsed['tools'] as string[],\n max_turns: parsed['max_turns'] as number | undefined,\n timeout: parsed['timeout'] as number | undefined,\n model: parsed['model'] as SubAgentConfig['model'],\n };\n } catch {\n return null;\n }\n}\n\n/**\n * 从目录加载所有 YAML 子 Agent 配置\n */\nfunction loadAgentsFromDir(dir: string): SubAgentConfig[] {\n try {\n if (!fs.existsSync(dir)) return [];\n const files = fs.readdirSync(dir).filter(f => f.endsWith('.yaml') || f.endsWith('.yml'));\n const agents: SubAgentConfig[] = [];\n for (const file of files) {\n const agent = loadAgentYaml(path.join(dir, file));\n if (agent) agents.push(agent);\n }\n return agents;\n } catch {\n return [];\n }\n}\n\n/**\n * 加载所有子 Agent 配置(按优先级低→高合并)\n *\n * 1. 内置预设(代码中)\n * 2. 全局用户目录:~/.zencode/agents/*.yaml\n * 3. 项目目录:.zencode/agents/*.yaml\n *\n * 同名配置高优先级覆盖低优先级\n */\nexport function loadAllAgentConfigs(): SubAgentConfig[] {\n const configMap = new Map<string, SubAgentConfig>();\n\n // 1. 内置预置(最低优先级)\n for (const agent of presetAgents) {\n configMap.set(agent.name, agent);\n }\n\n // 2. 全局用户目录:~/.zencode/agents/*.yaml\n const globalDir = path.join(os.homedir(), '.zencode', 'agents');\n for (const agent of loadAgentsFromDir(globalDir)) {\n configMap.set(agent.name, agent);\n }\n\n // 3. 项目目录:.zencode/agents/*.yaml(最高优先级)\n const projectDir = path.resolve('.zencode', 'agents');\n for (const agent of loadAgentsFromDir(projectDir)) {\n configMap.set(agent.name, agent);\n }\n\n return [...configMap.values()];\n}\n","import type { Skill } from './types.js';\n\n/**\n * Skill 注册表 - 管理用户可调用的技能\n */\nexport class SkillRegistry {\n private skills = new Map<string, Skill>();\n\n register(skill: Skill): void {\n this.skills.set(skill.name, skill);\n }\n\n get(name: string): Skill | undefined {\n return this.skills.get(name);\n }\n\n has(name: string): boolean {\n return this.skills.has(name);\n }\n\n list(): Skill[] {\n return [...this.skills.values()];\n }\n\n listNames(): string[] {\n return [...this.skills.keys()];\n }\n\n /**\n * 展开 skill 的 prompt 模板,替换 $ARGS 为用户参数\n */\n expandPrompt(skill: Skill, args: string): string {\n if (args && skill.prompt.includes('$ARGS')) {\n return skill.prompt.replace(/\\$ARGS/g, args);\n }\n // 没有 $ARGS 占位符时,将用户参数追加到末尾\n if (args) {\n return `${skill.prompt}\\n\\n用户补充: ${args}`;\n }\n return skill.prompt;\n }\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\nimport { parse as parseYaml } from 'yaml';\nimport type { Skill } from './types.js';\n\n/**\n * 从 YAML 文件加载单个 Skill\n */\nfunction loadSkillYaml(filePath: string): Skill | null {\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n const parsed = parseYaml(content) as Record<string, unknown>;\n if (!parsed || typeof parsed !== 'object') return null;\n if (!parsed['name'] || !parsed['prompt']) return null;\n\n return {\n name: parsed['name'] as string,\n description: (parsed['description'] as string) || '',\n prompt: parsed['prompt'] as string,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * 从目录加载所有 YAML Skill 文件\n */\nfunction loadSkillsFromDir(dir: string): Skill[] {\n try {\n if (!fs.existsSync(dir)) return [];\n const files = fs.readdirSync(dir).filter(f => f.endsWith('.yaml') || f.endsWith('.yml'));\n const skills: Skill[] = [];\n for (const file of files) {\n const skill = loadSkillYaml(path.join(dir, file));\n if (skill) skills.push(skill);\n }\n return skills;\n } catch {\n return [];\n }\n}\n\n/**\n * 加载所有 Skill(按优先级低→高合并)\n *\n * 1. 全局用户目录:~/.zencode/skills/*.yaml\n * 2. 项目目录:.zencode/skills/*.yaml\n *\n * 同名 skill 高优先级覆盖低优先级\n */\nexport function loadAllSkills(): Skill[] {\n const skillMap = new Map<string, Skill>();\n\n // 1. 全局用户目录\n const globalDir = path.join(os.homedir(), '.zencode', 'skills');\n for (const skill of loadSkillsFromDir(globalDir)) {\n skillMap.set(skill.name, skill);\n }\n\n // 2. 项目目录\n const projectDir = path.resolve('.zencode', 'skills');\n for (const skill of loadSkillsFromDir(projectDir)) {\n skillMap.set(skill.name, skill);\n }\n\n return [...skillMap.values()];\n}\n","import type { ZenCodeConfig } from '../config/types.js';\nimport type { LLMClient } from '../llm/client.js';\nimport type { ToolRegistry } from '../tools/registry.js';\nimport type { SubAgentTracker } from './sub-agent-tracker.js';\nimport { Conversation } from './conversation.js';\nimport { ReadTracker } from './read-tracker.js';\n\nconst DEFAULT_TIMEOUT_MS = 120_000; // 2 minutes\n\n/**\n * 轻量子 Agent - 独立对话,只读工具,非流式\n *\n * 用于并行执行多个子任务(如同时读多个文件、搜索多处代码)\n */\nexport class SubAgent {\n private client: LLMClient;\n private registry: ToolRegistry;\n private config: ZenCodeConfig;\n private task: string;\n private allowedTools: string[];\n private maxTurns: number;\n private timeoutMs: number;\n private tracker?: SubAgentTracker;\n\n constructor(\n client: LLMClient,\n registry: ToolRegistry,\n config: ZenCodeConfig,\n task: string,\n allowedTools: string[] = ['read-file', 'glob', 'grep'],\n maxTurns: number = 10,\n timeoutMs: number = DEFAULT_TIMEOUT_MS,\n tracker?: SubAgentTracker,\n ) {\n this.client = client;\n this.registry = registry;\n this.config = config;\n this.task = task;\n // 禁止递归:排除 spawn-agents 和 todo\n this.allowedTools = allowedTools.filter((t) => t !== 'spawn-agents' && t !== 'todo');\n this.maxTurns = Math.min(maxTurns, 15);\n this.timeoutMs = timeoutMs;\n this.tracker = tracker;\n }\n\n async run(): Promise<string> {\n return Promise.race([\n this.execute(),\n this.timeout(),\n ]);\n }\n\n private timeout(): Promise<never> {\n return new Promise((_, reject) => {\n setTimeout(\n () => reject(new Error(`子 Agent 超时(${this.timeoutMs / 1000}s)`)),\n this.timeoutMs,\n );\n });\n }\n\n private async execute(): Promise<string> {\n const conversation = new Conversation();\n const readTracker = new ReadTracker();\n\n const systemPrompt = `你是 ZenCode 子 Agent。你的任务:${this.task}\\n完成后直接返回结果,不要多余解释。`;\n\n conversation.setSystemPrompt(systemPrompt);\n conversation.addUserMessage(this.task);\n\n const tools = this.registry.toToolDefinitions(this.allowedTools);\n let lastContent = '';\n\n for (let turn = 0; turn < this.maxTurns; turn++) {\n const assistantMsg = await this.client.chat(\n conversation.getMessages(),\n tools.length > 0 ? tools : undefined,\n );\n\n // 报告 token 用量\n if (assistantMsg.usage && this.tracker) {\n this.tracker.addTokens(assistantMsg.usage.total_tokens);\n }\n\n conversation.addAssistantMessage(assistantMsg);\n\n if (!assistantMsg.tool_calls || assistantMsg.tool_calls.length === 0) {\n lastContent = assistantMsg.content || '';\n break;\n }\n\n for (const toolCall of assistantMsg.tool_calls) {\n const toolName = toolCall.function.name;\n\n if (!this.allowedTools.includes(toolName)) {\n conversation.addToolResult(\n toolCall.id,\n `子 Agent 不允许使用工具 \"${toolName}\"`,\n );\n continue;\n }\n\n let params: Record<string, unknown>;\n try {\n params = JSON.parse(toolCall.function.arguments);\n } catch {\n conversation.addToolResult(toolCall.id, '参数解析失败:无效的 JSON');\n continue;\n }\n\n try {\n // 先读后改:edit-file 必须先 read-file\n if (toolName === 'edit-file') {\n const editPath = params['path'] as string;\n if (!readTracker.hasRead(editPath)) {\n conversation.addToolResult(toolCall.id,\n `⚠ 禁止编辑未读取的文件。请先 read-file \"${editPath}\" 了解当前内容,再 edit-file。`);\n continue;\n }\n }\n\n // write-file 覆盖检查:文件已存在时需要 overwrite: true\n if (toolName === 'write-file') {\n const warn = readTracker.checkWriteOverwrite(\n params['path'] as string,\n params['overwrite'] as boolean | undefined,\n );\n if (warn) {\n conversation.addToolResult(toolCall.id, warn);\n continue;\n }\n }\n\n const result = await this.registry.execute(\n toolName,\n params,\n this.config.max_tool_output,\n );\n\n // 跟踪已读/已写文件\n if (toolName === 'read-file') {\n readTracker.markRead(params['path'] as string);\n } else if (toolName === 'write-file') {\n readTracker.markWritten(params['path'] as string);\n }\n\n conversation.addToolResult(toolCall.id, result.content);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n conversation.addToolResult(toolCall.id, `工具执行异常:${msg}`);\n }\n }\n\n if (assistantMsg.content) {\n lastContent = assistantMsg.content;\n }\n }\n\n return lastContent;\n }\n}\n","import type { Tool, ToolResult } from './types.js';\nimport type { LLMClient } from '../llm/client.js';\nimport type { ToolRegistry } from './registry.js';\nimport type { ZenCodeConfig } from '../config/types.js';\nimport type { SubAgentTracker } from '../core/sub-agent-tracker.js';\nimport { SubAgent } from '../core/sub-agent.js';\n\ninterface TaskInput {\n description: string;\n tools?: string[];\n}\n\nconst DEFAULT_TOOLS = ['read-file', 'glob', 'grep'];\nconst MAX_CONCURRENT = 10;\nconst MAX_TURNS_LIMIT = 15;\n\n/**\n * 创建 spawn-agents 工具 - 并行启动多个子 Agent\n */\nexport function createSpawnAgentsTool(\n client: LLMClient,\n registry: ToolRegistry,\n config: ZenCodeConfig,\n tracker?: SubAgentTracker,\n): Tool {\n return {\n name: 'spawn-agents',\n description:\n '并行启动多个子 Agent 执行任务。每个子 Agent 有独立对话,默认只能用只读工具 (read-file, glob, grep)。适用于同时读取和分析多个文件、搜索多个模式等场景。',\n parameters: {\n type: 'object',\n properties: {\n tasks: {\n type: 'array',\n description: '要并行执行的任务列表',\n items: {\n type: 'object',\n properties: {\n description: {\n type: 'string',\n description: '任务描述',\n },\n tools: {\n type: 'array',\n description:\n '允许使用的工具列表(默认 read-file, glob, grep),不可包含 spawn-agents',\n items: { type: 'string' },\n },\n },\n required: ['description'],\n },\n },\n max_turns: {\n type: 'number',\n description: '每个子 Agent 的最大轮数(默认 10,上限 15)',\n },\n },\n required: ['tasks'],\n },\n permissionLevel: 'auto',\n\n async execute(params: Record<string, unknown>): Promise<ToolResult> {\n const tasks = params['tasks'] as TaskInput[];\n const maxTurns = Math.min(\n (params['max_turns'] as number) || 10,\n MAX_TURNS_LIMIT,\n );\n\n if (!tasks || tasks.length === 0) {\n return { content: '错误:未提供任务' };\n }\n\n if (tasks.length > MAX_CONCURRENT) {\n return { content: `错误:最多支持 ${MAX_CONCURRENT} 个并发任务` };\n }\n\n // 获取 auto 权限的工具列表\n const autoTools = registry\n .listTools()\n .filter((t) => registry.getPermissionLevel(t) === 'auto' && t !== 'spawn-agents');\n\n const descriptions = tasks.map((t) => t.description);\n\n // 通知 tracker 开始\n tracker?.start(descriptions);\n\n const agents = tasks.map((task) => {\n // 取请求工具与 auto 工具的交集,排除 spawn-agents\n let tools = task.tools\n ? task.tools\n .filter((t) => t !== 'spawn-agents')\n .filter((t) => autoTools.includes(t))\n : DEFAULT_TOOLS.filter((t) => autoTools.includes(t));\n\n if (tools.length === 0) {\n tools = DEFAULT_TOOLS.filter((t) => autoTools.includes(t));\n }\n\n return new SubAgent(client, registry, config, task.description, tools, maxTurns, undefined, tracker);\n });\n\n // 包装每个 agent 的 run,追踪完成/失败\n const wrappedRuns = agents.map((agent) =>\n agent.run().then(\n (result) => { tracker?.markCompleted(); return result; },\n (err) => { tracker?.markFailed(); throw err; },\n ),\n );\n\n const results = await Promise.allSettled(wrappedRuns);\n\n // 通知 tracker 结束\n tracker?.finish();\n\n const succeeded = results.filter((r) => r.status === 'fulfilled').length;\n const failed = results.filter((r) => r.status === 'rejected').length;\n\n const output = results\n .map((result, i) => {\n const task = tasks[i]!;\n const status = result.status === 'fulfilled' ? '✓' : '✗';\n const header = `=== ${status} 任务 ${i + 1}: ${task.description} ===`;\n if (result.status === 'fulfilled') {\n return `${header}\\n${result.value}`;\n }\n return `${header}\\n错误: ${result.reason}`;\n })\n .join('\\n\\n');\n\n const summary = `[${succeeded} 成功${failed > 0 ? `, ${failed} 失败` : ''}]`;\n\n return { content: `${summary}\\n\\n${output}` };\n },\n };\n}\n","import type { Tool, ToolResult } from './types.js';\nimport type { TodoStore } from '../core/todo-store.js';\n\n/**\n * 创建 todo 工具 - 计划管理\n */\nexport function createTodoTool(store: TodoStore): Tool {\n return {\n name: 'todo',\n description:\n '管理任务计划。支持创建计划、更新条目状态、查看计划和清空计划。对于包含多个步骤的任务,先创建计划再逐步执行。',\n parameters: {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n description: '操作类型',\n enum: ['create', 'update', 'list', 'clear'],\n },\n items: {\n type: 'array',\n description: 'create 时必填:计划条目列表',\n items: {\n type: 'object',\n properties: {\n id: { type: 'string', description: '条目 ID' },\n title: { type: 'string', description: '条目标题' },\n },\n required: ['id', 'title'],\n },\n },\n id: {\n type: 'string',\n description: 'update 时必填:要更新的条目 ID',\n },\n status: {\n type: 'string',\n description: 'update 时必填:新状态',\n enum: ['pending', 'in-progress', 'completed'],\n },\n },\n required: ['action'],\n },\n permissionLevel: 'auto',\n\n async execute(params: Record<string, unknown>): Promise<ToolResult> {\n const action = params['action'] as string;\n\n switch (action) {\n case 'create': {\n const items = params['items'] as\n | { id: string; title: string }[]\n | undefined;\n if (!items || items.length === 0) {\n return { content: '错误:create 需要提供 items' };\n }\n const plan = store.create(items);\n const lines = plan.items.map(\n (item) => `○ [${item.id}] ${item.title}`,\n );\n return {\n content: `计划已创建(${plan.items.length} 个条目):\\n${lines.join('\\n')}`,\n };\n }\n\n case 'update': {\n const id = params['id'] as string | undefined;\n const status = params['status'] as string | undefined;\n if (!id || !status) {\n return { content: '错误:update 需要提供 id 和 status' };\n }\n const item = store.update(\n id,\n status as 'pending' | 'in-progress' | 'completed',\n );\n if (!item) {\n return { content: `错误:未找到条目 \"${id}\"` };\n }\n const icon =\n item.status === 'completed'\n ? '●'\n : item.status === 'in-progress'\n ? '◐'\n : '○';\n return {\n content: `已更新:${icon} [${item.id}] ${item.title} → ${item.status}`,\n };\n }\n\n case 'list': {\n const plan = store.list();\n if (!plan) {\n return { content: '当前没有计划' };\n }\n const completed = plan.items.filter(\n (i) => i.status === 'completed',\n ).length;\n const lines = plan.items.map((item) => {\n const icon =\n item.status === 'completed'\n ? '●'\n : item.status === 'in-progress'\n ? '◐'\n : '○';\n return `${icon} [${item.id}] ${item.title}`;\n });\n return {\n content: `计划进度 ${completed}/${plan.items.length}:\\n${lines.join('\\n')}`,\n };\n }\n\n case 'clear': {\n store.clear();\n return { content: '计划已清空' };\n }\n\n default:\n return {\n content: `错误:未知操作 \"${action}\"。支持: create, update, list, clear`,\n };\n }\n },\n };\n}\n","import type { ZenCodeConfig } from '../../config/types.js';\nimport type { LLMClient } from '../../llm/client.js';\nimport type { ToolRegistry } from '../../tools/registry.js';\nimport type { AgentCallbacks } from '../agent.js';\nimport type { SubAgentConfig } from './types.js';\nimport type { SubAgentTracker } from '../sub-agent-tracker.js';\nimport { Conversation } from '../conversation.js';\nimport { confirmExecution } from '../../tools/permission.js';\nimport { ReadTracker } from '../read-tracker.js';\n\nconst DEFAULT_MAX_TURNS = 15;\n\n/**\n * SubAgentRunner - 执行可配置子 Agent\n *\n * 基于 SubAgentConfig 运行子 Agent。\n * 使用流式 chatStream(),TUI 可实时显示输出。\n */\nexport class SubAgentRunner {\n private client: LLMClient;\n private registry: ToolRegistry;\n private config: ZenCodeConfig;\n private agentConfig: SubAgentConfig;\n private tracker?: SubAgentTracker;\n\n constructor(\n client: LLMClient,\n registry: ToolRegistry,\n config: ZenCodeConfig,\n agentConfig: SubAgentConfig,\n tracker?: SubAgentTracker,\n ) {\n this.client = client;\n this.registry = registry;\n this.config = config;\n this.agentConfig = agentConfig;\n this.tracker = tracker;\n }\n\n /**\n * 执行子 Agent 任务\n */\n async execute(task: string, context?: string, callbacks: AgentCallbacks = {}): Promise<string> {\n const timeoutMs = (this.agentConfig.timeout ?? 120) * 1000;\n const maxTurns = this.agentConfig.max_turns ?? DEFAULT_MAX_TURNS;\n\n return Promise.race([\n this.run(task, context, maxTurns, callbacks),\n this.timeout(timeoutMs),\n ]);\n }\n\n private timeout(ms: number): Promise<never> {\n return new Promise((_, reject) => {\n setTimeout(\n () => reject(new Error(`子 Agent \"${this.agentConfig.name}\" 超时(${ms / 1000}s)`)),\n ms,\n );\n });\n }\n\n private async run(task: string, context: string | undefined, maxTurns: number, callbacks: AgentCallbacks): Promise<string> {\n const conversation = new Conversation();\n const readTracker = new ReadTracker();\n\n conversation.setSystemPrompt(this.agentConfig.prompt);\n\n // 组装任务消息\n let taskMessage = task;\n if (context) {\n taskMessage += `\\n\\n[上下文]\\n${context}`;\n }\n conversation.addUserMessage(taskMessage);\n\n // 构建工具列表:取子 Agent 声明的工具与注册表的交集\n const tools = this.registry.toToolDefinitions(this.agentConfig.tools);\n let lastContent = '';\n\n for (let turn = 0; turn < maxTurns; turn++) {\n const assistantMsg = await this.client.chatStream(\n conversation.getMessages(),\n tools.length > 0 ? tools : undefined,\n callbacks,\n );\n\n // 报告 token 用量\n if (assistantMsg.usage && this.tracker) {\n this.tracker.addTokens(assistantMsg.usage.total_tokens);\n }\n\n conversation.addAssistantMessage(assistantMsg);\n\n if (!assistantMsg.tool_calls || assistantMsg.tool_calls.length === 0) {\n lastContent = assistantMsg.content || '';\n break;\n }\n\n for (const toolCall of assistantMsg.tool_calls) {\n const toolName = toolCall.function.name;\n\n // 检查工具是否在子 Agent 允许列表中\n if (!this.agentConfig.tools.includes(toolName)) {\n conversation.addToolResult(\n toolCall.id,\n `子 Agent \"${this.agentConfig.name}\" 不允许使用工具 \"${toolName}\"`,\n );\n continue;\n }\n\n let params: Record<string, unknown>;\n try {\n params = JSON.parse(toolCall.function.arguments);\n } catch {\n conversation.addToolResult(toolCall.id, '参数解析失败:无效的 JSON');\n continue;\n }\n\n try {\n // 先读后改检查\n if (toolName === 'edit-file') {\n const editPath = params['path'] as string;\n if (!readTracker.hasRead(editPath)) {\n conversation.addToolResult(toolCall.id,\n `⚠ 禁止编辑未读取的文件。请先 read-file \"${editPath}\" 了解当前内容,再 edit-file。`);\n continue;\n }\n }\n\n // write-file 覆盖检查\n if (toolName === 'write-file') {\n const warn = readTracker.checkWriteOverwrite(\n params['path'] as string,\n params['overwrite'] as boolean | undefined,\n );\n if (warn) {\n conversation.addToolResult(toolCall.id, warn);\n continue;\n }\n }\n\n // 权限检查\n const permLevel = this.registry.getPermissionLevel(toolName);\n if (permLevel === 'deny') {\n callbacks.onDenied?.(toolName);\n conversation.addToolResult(toolCall.id, `工具 \"${toolName}\" 已被禁止执行`);\n continue;\n }\n\n if (permLevel === 'auto') {\n callbacks.onToolExecuting?.(toolName, params);\n }\n\n if (permLevel === 'confirm') {\n const confirmResult = await confirmExecution(toolName, params);\n if (!confirmResult.approved) {\n callbacks.onDenied?.(toolName, confirmResult.feedback);\n const denyMsg = confirmResult.feedback\n ? `用户拒绝了此操作,用户反馈: ${confirmResult.feedback}`\n : '用户拒绝了此操作';\n conversation.addToolResult(toolCall.id, denyMsg);\n continue;\n }\n }\n\n // 执行工具\n const result = await this.registry.execute(toolName, params, this.config.max_tool_output);\n callbacks.onToolResult?.(toolName, result.content, result.truncated ?? false);\n\n // 跟踪已读/已写文件\n if (toolName === 'read-file') {\n readTracker.markRead(params['path'] as string);\n } else if (toolName === 'write-file') {\n readTracker.markWritten(params['path'] as string);\n }\n\n conversation.addToolResult(toolCall.id, result.content);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n conversation.addToolResult(toolCall.id, `工具执行异常:${msg}`);\n }\n }\n\n if (assistantMsg.content) {\n lastContent = assistantMsg.content;\n }\n }\n\n return lastContent;\n }\n}\n","import type { Tool, ToolResult } from './types.js';\nimport type { LLMClient } from '../llm/client.js';\nimport type { ToolRegistry } from './registry.js';\nimport type { ZenCodeConfig } from '../config/types.js';\nimport type { AgentCallbacks } from '../core/agent.js';\nimport type { SubAgentConfigRegistry } from '../core/sub-agents/registry.js';\nimport type { SubAgentTracker } from '../core/sub-agent-tracker.js';\nimport { SubAgentRunner } from '../core/sub-agents/runner.js';\nimport { createLLMClient } from '../llm/client.js';\n\n/**\n * 创建 dispatch 工具 - 主 Agent 调度子 Agent 的入口\n */\nexport function createDispatchTool(\n defaultClient: LLMClient,\n toolRegistry: ToolRegistry,\n config: ZenCodeConfig,\n agentRegistry: SubAgentConfigRegistry,\n tracker?: SubAgentTracker,\n callbacks?: () => AgentCallbacks,\n): Tool {\n return {\n name: 'dispatch',\n description: '调度子 Agent 执行专门任务。子 Agent 有独立对话和专属系统提示词,适用于需要专业角色的场景。',\n parameters: {\n type: 'object',\n properties: {\n agent: {\n type: 'string',\n description: `子 Agent 名称。可选: ${agentRegistry.listNames().join(', ')}`,\n enum: agentRegistry.listNames(),\n },\n task: {\n type: 'string',\n description: '要执行的具体任务描述',\n },\n context: {\n type: 'string',\n description: '可选的额外上下文信息(如参考文件路径、依赖关系等)',\n },\n },\n required: ['agent', 'task'],\n },\n permissionLevel: 'auto',\n\n async execute(params: Record<string, unknown>): Promise<ToolResult> {\n const agentName = params['agent'] as string;\n const task = params['task'] as string;\n const context = params['context'] as string | undefined;\n\n const agentConfig = agentRegistry.get(agentName);\n if (!agentConfig) {\n return { content: `错误:未找到子 Agent \"${agentName}\"。可用: ${agentRegistry.listNames().join(', ')}` };\n }\n\n // 决定使用的 LLM 客户端\n let client = defaultClient;\n if (agentConfig.model) {\n client = createLLMClient({\n apiKey: agentConfig.model.api_key || config.api_key,\n baseURL: agentConfig.model.base_url || config.base_url,\n model: agentConfig.model.model || config.model,\n temperature: config.temperature,\n maxTokens: config.max_tokens,\n });\n }\n\n const runner = new SubAgentRunner(client, toolRegistry, config, agentConfig, tracker);\n\n // 通知 tracker 开始\n tracker?.start([`${agentName}: ${task.slice(0, 60)}`]);\n\n try {\n const result = await runner.execute(task, context, callbacks?.() ?? {});\n tracker?.finish();\n return { content: result || '(子 Agent 执行完成,无输出)' };\n } catch (err) {\n tracker?.finish();\n const msg = err instanceof Error ? err.message : String(err);\n return { content: `子 Agent 执行错误:${msg}` };\n }\n },\n };\n}\n","// Bridge: Agent callbacks → TUI dispatch\r\n// Includes token batching to avoid excessive React re-renders\r\n\r\nimport type { Dispatch } from 'react';\r\nimport type { AgentCallbacks } from '../../core/agent.js';\r\nimport type { TuiAction } from './state.js';\r\n\r\nconst BATCH_INTERVAL_MS = 64; // ~15fps, balances smoothness vs flicker for fullscreen redraw\r\n\r\nconst ANSI_GRAY = '\\x1b[90m';\r\nconst ANSI_RESET = '\\x1b[0m';\r\n\r\nfunction gray(text: string): string {\r\n return `${ANSI_GRAY}${text}${ANSI_RESET}`;\r\n}\r\n\r\n/**\r\n * 流式 <think> 标签转换器 (For standard REPL)\r\n * 轻量样式:标题 + 缩进内容(无边框)\r\n */\r\nexport function createThinkFilter() {\r\n let inThink = false;\r\n let tagBuffer = '';\r\n let thinkLineBuffer = '';\r\n let thinkHasVisibleContent = false;\r\n let thinkLastEmittedBlank = false;\r\n let postThink = false;\r\n\r\n function flushThinkLine(rawLine: string): string {\r\n const normalized = rawLine.trim();\r\n if (!thinkHasVisibleContent && normalized.length === 0) return '';\r\n if (normalized.length === 0) {\r\n if (thinkLastEmittedBlank) return '';\r\n thinkLastEmittedBlank = true;\r\n return '\\n';\r\n }\r\n thinkHasVisibleContent = true;\r\n thinkLastEmittedBlank = false;\r\n return `${gray(` ${normalized}`)}\\n`;\r\n }\r\n\r\n function appendOutsideText(current: string, text: string): string {\r\n if (!postThink) return current + text;\r\n let result = current;\r\n for (let i = 0; i < text.length; i++) {\r\n const ch = text[i]!;\r\n if (postThink && (ch === '\\n' || ch === '\\r' || ch === ' ' || ch === '\\t')) {\r\n continue;\r\n }\r\n postThink = false;\r\n result += text.slice(i);\r\n break;\r\n }\r\n return result;\r\n }\r\n\r\n function appendThinkText(current: string, text: string): string {\r\n let result = current;\r\n for (let i = 0; i < text.length; i++) {\r\n const ch = text[i]!;\r\n if (ch === '\\r') continue;\r\n if (ch === '\\n') {\r\n result += flushThinkLine(thinkLineBuffer);\r\n thinkLineBuffer = '';\r\n } else {\r\n thinkLineBuffer += ch;\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n return function filter(text: string): string {\r\n let result = '';\r\n for (let i = 0; i < text.length; i++) {\r\n const ch = text[i]!;\r\n if (tagBuffer.length > 0) {\r\n tagBuffer += ch;\r\n if (tagBuffer === '<think>') {\r\n inThink = true;\r\n thinkLineBuffer = '';\r\n thinkHasVisibleContent = false;\r\n thinkLastEmittedBlank = false;\r\n tagBuffer = '';\r\n result += `${gray('Thinking')}\\n`;\r\n } else if (tagBuffer === '</think>') {\r\n inThink = false;\r\n postThink = true;\r\n tagBuffer = '';\r\n if (thinkLineBuffer.length > 0) {\r\n result += flushThinkLine(thinkLineBuffer);\r\n thinkLineBuffer = '';\r\n }\r\n while (result.endsWith('\\n\\n\\n')) result = result.slice(0, -1);\r\n result += '\\n';\r\n } else if (!'<think>'.startsWith(tagBuffer) && !'</think>'.startsWith(tagBuffer)) {\r\n if (inThink) result = appendThinkText(result, tagBuffer);\r\n else result = appendOutsideText(result, tagBuffer);\r\n tagBuffer = '';\r\n }\r\n continue;\r\n }\r\n if (ch === '<') {\r\n tagBuffer = '<';\r\n continue;\r\n }\r\n if (inThink) result = appendThinkText(result, ch);\r\n else result = appendOutsideText(result, ch);\r\n }\r\n return result;\r\n };\r\n}\r\n\r\n/**\r\n * Creates a token batcher that accumulates streaming content\r\n * and flushes to dispatch at a fixed interval.\r\n */\r\nfunction createTokenBatcher(dispatch: Dispatch<TuiAction>, type: 'APPEND_CONTENT' | 'APPEND_THOUGHT') {\r\n let buffer = '';\r\n let timer: ReturnType<typeof setInterval> | null = null;\r\n\r\n function flush() {\r\n if (buffer.length > 0) {\r\n const text = buffer;\r\n buffer = '';\r\n dispatch({ type, text } as any);\r\n }\r\n }\r\n\r\n function start() {\r\n if (!timer) {\r\n timer = setInterval(flush, BATCH_INTERVAL_MS);\r\n }\r\n }\r\n\r\n function stop() {\r\n flush();\r\n if (timer) {\r\n clearInterval(timer);\r\n timer = null;\r\n }\r\n }\r\n\r\n function append(text: string) {\r\n buffer += text;\r\n start();\r\n }\r\n\r\n function pause() {\r\n if (timer) {\r\n clearInterval(timer);\r\n timer = null;\r\n }\r\n }\r\n\r\n return { append, stop, flush, pause };\r\n}\r\n\r\n// Track tool call IDs for mapping tool results back\r\nlet toolCallCounter = 0;\r\nlet activeToolIds: Map<string, string> = new Map();\r\n// Track streaming tool index → id\r\nlet streamingToolIds: Map<number, string> = new Map();\r\n// Track last streaming args per tool id (for computing code line count on result)\r\nlet lastStreamingArgs: Map<string, string> = new Map();\r\n\r\n/**\r\n * 从部分 JSON 参数中提取代码内容(write-file 的 content 或 edit-file 的 new_string)\r\n */\r\nfunction extractCodeFromArgs(name: string, args: string): string | null {\r\n const field = name === 'write-file' ? 'content' : 'new_string';\r\n const patterns = [`\"${field}\": \"`, `\"${field}\":\"`];\r\n for (const pattern of patterns) {\r\n const idx = args.indexOf(pattern);\r\n if (idx >= 0) {\r\n let raw = args.slice(idx + pattern.length);\r\n if (raw.endsWith('\"}')) raw = raw.slice(0, -2);\r\n else if (raw.endsWith('\"')) raw = raw.slice(0, -1);\r\n return raw\r\n .replace(/\\\\n/g, '\\n')\r\n .replace(/\\\\t/g, '\\t')\r\n .replace(/\\\\\"/g, '\"')\r\n .replace(/\\\\\\\\/g, '\\\\');\r\n }\r\n }\r\n return null;\r\n}\r\n\r\n/**\r\n * Register a confirm tool id so that subsequent onToolResult/onDenied\r\n * can find it by tool name.\r\n */\r\nexport function registerConfirmToolId(toolName: string, id: string): void {\r\n activeToolIds.set(toolName, id);\r\n}\r\n\r\n/**\r\n * Creates AgentCallbacks that dispatch to TUI state.\r\n */\r\nexport function createBridgeCallbacks(dispatch: Dispatch<TuiAction>): AgentCallbacks & { _stopBatcher: () => void } {\r\n const contentBatcher = createTokenBatcher(dispatch, 'APPEND_CONTENT');\r\n const thoughtBatcher = createTokenBatcher(dispatch, 'APPEND_THOUGHT');\r\n \r\n let inThink = false;\r\n let tagBuffer = '';\r\n\r\n activeToolIds = new Map();\r\n streamingToolIds = new Map();\r\n lastStreamingArgs = new Map();\r\n toolCallCounter = 0;\r\n\r\n let streamingThrottleTimer: ReturnType<typeof setTimeout> | null = null;\r\n let pendingStreamingUpdate: (() => void) | null = null;\r\n\r\n function flushStreamingUpdate() {\r\n if (pendingStreamingUpdate) {\r\n pendingStreamingUpdate();\r\n pendingStreamingUpdate = null;\r\n }\r\n if (streamingThrottleTimer) {\r\n clearTimeout(streamingThrottleTimer);\r\n streamingThrottleTimer = null;\r\n }\r\n }\r\n\r\n return {\r\n onContent: (text: string) => {\r\n for (let i = 0; i < text.length; i++) {\r\n const ch = text[i]!;\r\n\r\n if (tagBuffer.length > 0 || ch === '<') {\r\n tagBuffer += ch;\r\n if (tagBuffer === '<think>') {\r\n contentBatcher.flush();\r\n inThink = true;\r\n tagBuffer = '';\r\n continue;\r\n } else if (tagBuffer === '</think>') {\r\n thoughtBatcher.flush();\r\n inThink = false;\r\n tagBuffer = '';\r\n continue;\r\n } else if (!'<think>'.startsWith(tagBuffer) && !'</think>'.startsWith(tagBuffer)) {\r\n if (inThink) {\r\n thoughtBatcher.append(tagBuffer);\r\n } else {\r\n contentBatcher.append(tagBuffer);\r\n }\r\n tagBuffer = '';\r\n }\r\n continue;\r\n }\r\n\r\n if (inThink) {\r\n thoughtBatcher.append(ch);\r\n } else {\r\n contentBatcher.append(ch);\r\n }\r\n }\r\n },\r\n\r\n onToolCallStreaming: (index: number, name: string, accumulatedArgs: string) => {\r\n if (!streamingToolIds.has(index)) {\r\n contentBatcher.flush();\r\n thoughtBatcher.flush();\r\n const id = `tool-${++toolCallCounter}`;\r\n streamingToolIds.set(index, id);\r\n activeToolIds.set(name, id);\r\n dispatch({ type: 'TOOL_STREAMING', id, name, streamingContent: '0' });\r\n }\r\n const id = streamingToolIds.get(index)!;\r\n lastStreamingArgs.set(id, accumulatedArgs);\r\n const lineCount = (accumulatedArgs.match(/\\\\n/g) || []).length;\r\n\r\n pendingStreamingUpdate = () => {\r\n dispatch({ type: 'TOOL_STREAMING', id, name, streamingContent: String(lineCount) });\r\n };\r\n if (!streamingThrottleTimer) {\r\n streamingThrottleTimer = setTimeout(() => {\r\n flushStreamingUpdate();\r\n }, 80);\r\n }\r\n },\r\n\r\n onToolExecuting: (name: string, params: Record<string, unknown>) => {\r\n flushStreamingUpdate();\r\n contentBatcher.flush();\r\n thoughtBatcher.flush();\r\n contentBatcher.pause();\r\n thoughtBatcher.pause();\r\n const existingId = activeToolIds.get(name);\r\n const id = existingId || `tool-${++toolCallCounter}`;\r\n activeToolIds.set(name, id);\r\n dispatch({ type: 'TOOL_EXECUTING', id, name, params });\r\n },\r\n\r\n onToolResult: (name: string, result: string, truncated: boolean) => {\r\n const id = activeToolIds.get(name) || `tool-${++toolCallCounter}`;\r\n const lines = result.split('\\n');\r\n const isWriteTool = name === 'write-file' || name === 'edit-file';\r\n let summary: string;\r\n if (isWriteTool) {\r\n const code = extractCodeFromArgs(name, lastStreamingArgs.get(id) || '');\r\n const codeLines = code ? code.split('\\n').length : 0;\r\n summary = codeLines > 0 ? `${codeLines} lines` : (truncated ? 'truncated' : `${lines.length} lines`);\r\n } else {\r\n summary = truncated ? `truncated` : `${lines.length} lines`;\r\n }\r\n\r\n const preview = lines.slice(0, 5).join('\\n').slice(0, 200);\r\n const resultContent = lines.length > 5 || preview.length >= 200\r\n ? preview + '...'\r\n : preview;\r\n dispatch({ type: 'TOOL_RESULT', id, resultSummary: summary, resultContent });\r\n },\r\n\r\n onDenied: (toolName: string, feedback?: string) => {\r\n const id = activeToolIds.get(toolName) || `tool-${++toolCallCounter}`;\r\n dispatch({ type: 'TOOL_DENIED', id, feedback });\r\n },\r\n\r\n onError: (err: Error) => {\r\n contentBatcher.stop();\r\n thoughtBatcher.stop();\r\n dispatch({ type: 'SET_ERROR', error: err.message });\r\n },\r\n\r\n _stopBatcher: () => {\r\n contentBatcher.stop();\r\n thoughtBatcher.stop();\r\n },\r\n };\r\n}\r\n","/**\n * 子 Agent 并行执行追踪器\n *\n * spawn-agents 工具在执行时更新状态,TUI 订阅变化实时渲染。\n */\n\nexport interface SubAgentProgress {\n total: number;\n completed: number;\n failed: number;\n descriptions: string[];\n tokens: number;\n}\n\ntype ProgressListener = (progress: SubAgentProgress | null) => void;\n\nexport class SubAgentTracker {\n private progress: SubAgentProgress | null = null;\n private listeners = new Set<ProgressListener>();\n\n start(descriptions: string[]): void {\n this.progress = {\n total: descriptions.length,\n completed: 0,\n failed: 0,\n descriptions,\n tokens: 0,\n };\n this.notify();\n }\n\n markCompleted(): void {\n if (!this.progress) return;\n this.progress = { ...this.progress, completed: this.progress.completed + 1 };\n this.notify();\n }\n\n markFailed(): void {\n if (!this.progress) return;\n this.progress = { ...this.progress, failed: this.progress.failed + 1 };\n this.notify();\n }\n\n addTokens(count: number): void {\n if (!this.progress) return;\n this.progress = { ...this.progress, tokens: this.progress.tokens + count };\n this.notify();\n }\n\n finish(): void {\n this.progress = null;\n this.notify();\n }\n\n get current(): SubAgentProgress | null {\n return this.progress;\n }\n\n subscribe(listener: ProgressListener): () => void {\n this.listeners.add(listener);\n return () => { this.listeners.delete(listener); };\n }\n\n private notify(): void {\n const snapshot = this.progress ? { ...this.progress } : null;\n for (const listener of this.listeners) {\n listener(snapshot);\n }\n }\n}\n","import type { TodoPlan } from '../../core/todo-store.js';\r\nimport type { SubAgentProgress } from '../../core/sub-agent-tracker.js';\r\n\r\n// TUI state management with useReducer\r\n\r\nexport interface ToolCallState {\r\n id: string;\r\n name: string;\r\n params: Record<string, unknown>;\r\n status: 'running' | 'done' | 'denied' | 'confirming';\r\n resultSummary?: string;\r\n resultContent?: string;\r\n denyFeedback?: string;\r\n streamingContent?: string;\r\n}\r\n\r\nexport type ConfirmResult = 'allow' | 'deny' | 'always' | { feedback: string };\r\n\r\nexport interface ConfirmPending {\r\n toolName: string;\r\n params: Record<string, unknown>;\r\n resolve: (result: ConfirmResult) => void;\r\n}\r\n\r\n// Content blocks: text, tool calls and thoughts are interleaved in order\r\nexport type ContentBlock =\r\n | { type: 'text'; text: string }\r\n | { type: 'thought'; text: string }\r\n | { type: 'tool'; toolCall: ToolCallState };\r\n\r\nexport interface ChatMessage {\r\n id: string;\r\n role: 'user' | 'assistant' | 'system';\r\n blocks: ContentBlock[];\r\n isStreaming: boolean;\r\n confirmPending?: ConfirmPending;\r\n}\r\n\r\nexport interface TuiState {\r\n messages: ChatMessage[];\r\n isRunning: boolean;\r\n error?: string;\r\n modelName: string;\r\n todoPlan: TodoPlan | null;\r\n subAgentProgress: SubAgentProgress | null;\r\n}\r\n\r\nexport function createInitialState(modelName: string): TuiState {\r\n return {\r\n messages: [],\r\n isRunning: false,\r\n error: undefined,\r\n modelName,\r\n todoPlan: null,\r\n subAgentProgress: null,\r\n };\r\n}\r\n\r\n// Action types\r\nexport type TuiAction =\r\n | { type: 'ADD_USER_MESSAGE'; text: string }\r\n | { type: 'START_ASSISTANT' }\r\n | { type: 'APPEND_CONTENT'; text: string }\r\n | { type: 'APPEND_THOUGHT'; text: string }\r\n | { type: 'TOOL_EXECUTING'; id: string; name: string; params: Record<string, unknown> }\r\n | { type: 'TOOL_STREAMING'; id: string; name: string; streamingContent: string }\r\n | { type: 'TOOL_RESULT'; id: string; resultSummary: string; resultContent?: string }\r\n | { type: 'TOOL_DENIED'; id: string; feedback?: string }\r\n | { type: 'TOOL_CONFIRMING'; id: string; name: string; params: Record<string, unknown>; resolve: (r: ConfirmResult) => void }\r\n | { type: 'CONFIRM_RESPONDED'; id: string }\r\n | { type: 'FINISH_STREAMING' }\r\n | { type: 'SET_RUNNING'; running: boolean }\r\n | { type: 'SET_ERROR'; error: string }\r\n | { type: 'CLEAR_ERROR' }\r\n | { type: 'CLEAR_MESSAGES' }\r\n | { type: 'SET_TODO_PLAN'; plan: TodoPlan | null }\r\n | { type: 'SET_SUB_AGENT_PROGRESS'; progress: SubAgentProgress | null };\r\n\r\nlet messageCounter = 0;\r\nfunction nextId(): string {\r\n return `msg-${++messageCounter}`;\r\n}\r\n\r\nfunction updateLastAssistant(messages: ChatMessage[], updater: (msg: ChatMessage) => ChatMessage): ChatMessage[] {\r\n const result = [...messages];\r\n for (let i = result.length - 1; i >= 0; i--) {\r\n if (result[i]!.role === 'assistant') {\r\n result[i] = updater(result[i]!);\r\n return result;\r\n }\r\n }\r\n return result;\r\n}\r\n\r\n/** Helper to find and update a tool block by id across all blocks */\r\nfunction updateToolInBlocks(blocks: ContentBlock[], toolId: string, updater: (tc: ToolCallState) => ToolCallState): ContentBlock[] {\r\n return blocks.map(b => {\r\n if (b.type === 'tool' && b.toolCall.id === toolId) {\r\n return { type: 'tool' as const, toolCall: updater(b.toolCall) };\r\n }\r\n return b;\r\n });\r\n}\r\n\r\nexport function tuiReducer(state: TuiState, action: TuiAction): TuiState {\r\n switch (action.type) {\r\n case 'ADD_USER_MESSAGE':\r\n return {\r\n ...state,\r\n messages: [\r\n ...state.messages,\r\n {\r\n id: nextId(),\r\n role: 'user',\r\n blocks: [{ type: 'text', text: action.text }],\r\n isStreaming: false,\r\n },\r\n ],\r\n };\r\n\r\n case 'START_ASSISTANT':\r\n return {\r\n ...state,\r\n error: undefined,\r\n messages: [\r\n ...state.messages,\r\n {\r\n id: nextId(),\r\n role: 'assistant',\r\n blocks: [],\r\n isStreaming: true,\r\n },\r\n ],\r\n };\r\n\r\n case 'APPEND_CONTENT': {\r\n return {\r\n ...state,\r\n messages: updateLastAssistant(state.messages, (msg) => {\r\n const blocks = [...msg.blocks];\r\n const last = blocks[blocks.length - 1];\r\n if (last && last.type === 'text') {\r\n // Append to existing text block\r\n blocks[blocks.length - 1] = { type: 'text', text: last.text + action.text };\r\n } else {\r\n // Create new text block (after a tool block or empty)\r\n blocks.push({ type: 'text', text: action.text });\r\n }\r\n return { ...msg, blocks };\r\n }),\r\n };\r\n }\r\n\r\n case 'APPEND_THOUGHT': {\r\n return {\r\n ...state,\r\n messages: updateLastAssistant(state.messages, (msg) => {\r\n const blocks = [...msg.blocks];\r\n const last = blocks[blocks.length - 1];\r\n if (last && last.type === 'thought') {\r\n // Append to existing thought block\r\n blocks[blocks.length - 1] = { type: 'thought', text: last.text + action.text };\r\n } else {\r\n // Create new thought block\r\n blocks.push({ type: 'thought', text: action.text });\r\n }\r\n return { ...msg, blocks };\r\n }),\r\n };\r\n }\r\n\r\n case 'TOOL_EXECUTING': {\r\n return {\r\n ...state,\r\n messages: updateLastAssistant(state.messages, (msg) => {\r\n // Check if a tool block with this id already exists (from confirming or streaming)\r\n const existingIdx = msg.blocks.findIndex(\r\n b => b.type === 'tool' && b.toolCall.id === action.id,\r\n );\r\n if (existingIdx >= 0) {\r\n // Update existing block: set status to running, fill in final params\r\n return {\r\n ...msg,\r\n blocks: updateToolInBlocks(msg.blocks, action.id, tc => ({\r\n ...tc,\r\n status: 'running' as const,\r\n params: action.params,\r\n })),\r\n };\r\n }\r\n // Add new tool block\r\n return {\r\n ...msg,\r\n blocks: [\r\n ...msg.blocks,\r\n {\r\n type: 'tool' as const,\r\n toolCall: {\r\n id: action.id,\r\n name: action.name,\r\n params: action.params,\r\n status: 'running' as const,\r\n },\r\n },\r\n ],\r\n };\r\n }),\r\n };\r\n }\r\n\r\n case 'TOOL_STREAMING': {\r\n return {\r\n ...state,\r\n messages: updateLastAssistant(state.messages, (msg) => {\r\n // Check if streaming tool block already exists\r\n const existingIdx = msg.blocks.findIndex(\r\n b => b.type === 'tool' && b.toolCall.id === action.id,\r\n );\r\n if (existingIdx >= 0) {\r\n // Update streaming content\r\n return {\r\n ...msg,\r\n blocks: updateToolInBlocks(msg.blocks, action.id, tc => ({\r\n ...tc,\r\n streamingContent: action.streamingContent,\r\n })),\r\n };\r\n }\r\n // Create new tool block with streaming status\r\n return {\r\n ...msg,\r\n blocks: [\r\n ...msg.blocks,\r\n {\r\n type: 'tool' as const,\r\n toolCall: {\r\n id: action.id,\r\n name: action.name,\r\n params: {},\r\n status: 'running' as const,\r\n streamingContent: action.streamingContent,\r\n },\r\n },\r\n ],\r\n };\r\n }),\r\n };\r\n }\r\n\r\n case 'TOOL_RESULT': {\r\n return {\r\n ...state,\r\n messages: updateLastAssistant(state.messages, (msg) => ({\r\n ...msg,\r\n blocks: updateToolInBlocks(msg.blocks, action.id, tc => ({\r\n ...tc,\r\n status: 'done' as const,\r\n resultSummary: action.resultSummary,\r\n resultContent: action.resultContent,\r\n })),\r\n })),\r\n };\r\n }\r\n\r\n case 'TOOL_DENIED': {\r\n return {\r\n ...state,\r\n messages: updateLastAssistant(state.messages, (msg) => ({\r\n ...msg,\r\n blocks: updateToolInBlocks(msg.blocks, action.id, tc => ({\r\n ...tc,\r\n status: 'denied' as const,\r\n denyFeedback: action.feedback,\r\n })),\r\n })),\r\n };\r\n }\r\n\r\n case 'TOOL_CONFIRMING': {\r\n return {\r\n ...state,\r\n messages: updateLastAssistant(state.messages, (msg) => ({\r\n ...msg,\r\n blocks: [\r\n ...msg.blocks,\r\n {\r\n type: 'tool' as const,\r\n toolCall: {\r\n id: action.id,\r\n name: action.name,\r\n params: action.params,\r\n status: 'confirming' as const,\r\n },\r\n },\r\n ],\r\n confirmPending: {\r\n toolName: action.name,\r\n params: action.params,\r\n resolve: action.resolve,\r\n },\r\n })),\r\n };\r\n }\r\n\r\n case 'CONFIRM_RESPONDED': {\r\n return {\r\n ...state,\r\n messages: updateLastAssistant(state.messages, (msg) => ({\r\n ...msg,\r\n confirmPending: undefined,\r\n })),\r\n };\r\n }\r\n\r\n case 'FINISH_STREAMING':\r\n return {\r\n ...state,\r\n messages: updateLastAssistant(state.messages, (msg) => ({\r\n ...msg,\r\n isStreaming: false,\r\n })),\r\n };\r\n\r\n case 'SET_RUNNING':\r\n return { ...state, isRunning: action.running };\r\n\r\n case 'SET_ERROR':\r\n return { ...state, error: action.error, isRunning: false };\r\n\r\n case 'CLEAR_ERROR':\r\n return { ...state, error: undefined };\r\n\r\n case 'CLEAR_MESSAGES':\r\n return { ...state, messages: [] };\r\n\r\n case 'SET_TODO_PLAN':\r\n return { ...state, todoPlan: action.plan };\r\n\r\n case 'SET_SUB_AGENT_PROGRESS':\r\n return { ...state, subAgentProgress: action.progress };\r\n\r\n default:\r\n return state;\r\n }\r\n}\r\n","import React from 'react';\r\nimport { Box, Text } from 'ink';\r\nimport type { ToolCallState } from '../state.js';\r\n\r\ninterface ToolCallLineProps {\r\n toolCall: ToolCallState;\r\n}\r\n\r\nexport function getToolParamSummary(name: string, params: Record<string, unknown>): string {\r\n switch (name) {\r\n case 'bash':\r\n return String(params['command'] || '').slice(0, 100);\r\n case 'read-file':\r\n case 'write-file':\r\n case 'edit-file':\r\n return String(params['path'] || '');\r\n case 'glob':\r\n case 'grep':\r\n return String(params['pattern'] || '');\r\n case 'spawn-agents': {\r\n const tasks = params['tasks'] as Array<{ description?: string }> | undefined;\r\n if (!tasks || tasks.length === 0) return '';\r\n return `${tasks.length} tasks: ${tasks.map(t => t.description || '?').join(' | ').slice(0, 100)}`;\r\n }\r\n case 'dispatch':\r\n return `${params['agent'] || '?'}: ${String(params['task'] || '').slice(0, 80)}`;\r\n default:\r\n const keys = Object.keys(params);\r\n if (keys.length === 0) return '';\r\n const val = params[keys[0]];\r\n if (val === null || val === undefined) return '';\r\n if (typeof val === 'string') return val.slice(0, 60);\r\n if (typeof val === 'number' || typeof val === 'boolean') return String(val);\r\n return JSON.stringify(val).slice(0, 60);\r\n }\r\n}\r\n\r\nfunction truncateContent(text: string, maxLines: number): string[] {\r\n const lines = text.split('\\n');\r\n const result: string[] = [];\r\n for (let line of lines) {\r\n if (result.length >= maxLines) break;\r\n // Replace tabs with spaces and strip \\r to avoid terminal width miscalculation\r\n result.push(line.replace(/\\r/g, '').replace(/\\t/g, ' '));\r\n }\r\n if (lines.length > maxLines) {\r\n result.push(`... (and ${lines.length - maxLines} more lines)`);\r\n }\r\n return result;\r\n}\r\n\r\nexport function ToolCallLine({ toolCall }: ToolCallLineProps) {\r\n const { name, params, status, resultContent, denyFeedback } = toolCall;\r\n const summary = getToolParamSummary(name, params);\r\n\r\n let borderColor = '#504945';\r\n let titleColor = '#fabd2f';\r\n let statusColor = '#fabd2f';\r\n let statusText = 'RUNNING';\r\n\r\n if (status === 'done') {\r\n borderColor = '#b8bb26';\r\n titleColor = '#b8bb26';\r\n statusColor = '#b8bb26';\r\n statusText = 'DONE';\r\n } else if (status === 'denied') {\r\n borderColor = '#fb4934';\r\n titleColor = '#fb4934';\r\n statusColor = '#fb4934';\r\n statusText = 'DENIED';\r\n } else if (status === 'confirming') {\r\n borderColor = '#fe8019';\r\n titleColor = '#fe8019';\r\n statusColor = '#fe8019';\r\n statusText = 'CONFIRM';\r\n }\r\n\r\n const contentLines = resultContent ? truncateContent(resultContent, 15) : [];\r\n\r\n return (\r\n <Box flexDirection=\"column\" marginTop={0} marginBottom={1} width=\"100%\">\r\n <Box \r\n flexDirection=\"column\" \r\n borderStyle=\"round\" \r\n borderColor={borderColor} \r\n paddingX={1}\r\n width=\"100%\"\r\n >\r\n <Box gap={1}>\r\n <Box backgroundColor={statusColor} width={9} justifyContent=\"center\">\r\n <Text color=\"#282828\" bold>{statusText}</Text>\r\n </Box>\r\n <Text color={titleColor} bold>{name.toUpperCase()}</Text>\r\n <Text color=\"#ebdbb2\" dimColor italic wrap=\"truncate-end\">{summary}</Text>\r\n </Box>\r\n\r\n {status === 'done' && contentLines.length > 0 && (\r\n <Box flexDirection=\"column\" marginTop={1}>\r\n {contentLines.map((line, i) => (\r\n <Text key={i} color=\"#ebdbb2\" wrap=\"truncate-end\">{line}</Text>\r\n ))}\r\n </Box>\r\n )}\r\n\r\n {status === 'denied' && denyFeedback && (\r\n <Box gap={1} marginTop={0}>\r\n <Text color=\"#fb4934\" bold>REASON:</Text>\r\n <Text color=\"#ebdbb2\">{denyFeedback}</Text>\r\n </Box>\r\n )}\r\n\r\n {status === 'confirming' && (\r\n <Box marginTop={0}>\r\n <Text color=\"#fe8019\" italic>Waiting for your permission...</Text>\r\n </Box>\r\n )}\r\n </Box>\r\n </Box>\r\n );\r\n}\r\n","import React from 'react';\r\nimport { Box, Text } from 'ink';\r\nimport type { ChatMessage } from '../state.js';\r\nimport { ToolCallLine } from './ToolCallLine.js';\r\n\r\ninterface MessageBubbleProps {\r\n message: ChatMessage;\r\n}\r\n\r\nexport const MessageBubble = React.memo(function MessageBubble({ message }: MessageBubbleProps) {\r\n const { role, blocks, isStreaming } = message;\r\n\r\n const isUser = role === 'user';\r\n const label = isUser ? 'USER' : 'AI';\r\n const labelBg = isUser ? '#b8bb26' : '#83a598';\r\n const labelFg = '#282828';\r\n const contentColor = isUser ? '#ebdbb2' : '#ebdbb2';\r\n\r\n return (\r\n <Box flexDirection=\"column\" marginBottom={1} width=\"100%\">\r\n <Box marginBottom={0}>\r\n <Box backgroundColor={labelBg} width={9} paddingLeft={1} marginRight={1}>\r\n <Text color={labelFg} bold>{label}</Text>\r\n </Box>\r\n {isStreaming && <Text color=\"#83a598\" dimColor italic>typing...</Text>}\r\n </Box>\r\n\r\n <Box flexDirection=\"column\" width=\"100%\">\r\n {blocks.map((block, i) => {\r\n if (block.type === 'text') {\r\n const text = block.text.trim();\r\n if (!text && !isStreaming) return null;\r\n return (\r\n <Box key={`text-${i}`} paddingLeft={2} marginBottom={i < blocks.length - 1 ? 1 : 0} width=\"100%\">\r\n <Text color={contentColor}>{text}</Text>\r\n </Box>\r\n );\r\n } else if (block.type === 'thought') {\r\n return (\r\n <Box key={`thought-${i}`} flexDirection=\"column\" marginBottom={0} width=\"100%\">\r\n <Box gap={1} marginBottom={0}>\r\n <Box backgroundColor=\"#504945\" width={9} justifyContent=\"center\">\r\n <Text color=\"#a89984\" bold>THINK</Text>\r\n </Box>\r\n </Box>\r\n <Box paddingLeft={2} marginBottom={0}>\r\n <Text color=\"#928374\" italic>{block.text.trim()}</Text>\r\n </Box>\r\n </Box>\r\n );\r\n } else {\r\n return (\r\n <Box key={block.toolCall.id} paddingLeft={2} width=\"100%\">\r\n <ToolCallLine toolCall={block.toolCall} />\r\n </Box>\r\n );\r\n }\r\n })}\r\n {blocks.length === 0 && isStreaming && (\r\n <Box paddingLeft={2}>\r\n <Text dimColor>...</Text>\r\n </Box>\r\n )}\r\n </Box>\r\n </Box>\r\n );\r\n});\r\n","import React from 'react';\r\nimport { Box } from 'ink';\r\nimport type { ChatMessage } from '../state.js';\r\nimport { MessageBubble } from './MessageBubble.js';\r\n\r\ninterface ChatAreaProps {\r\n messages: ChatMessage[];\r\n}\r\n\r\nexport const ChatArea = React.memo(function ChatArea({ messages }: ChatAreaProps) {\r\n return (\r\n <Box flexDirection=\"column\" width=\"100%\">\r\n {messages.map((msg) => (\r\n <MessageBubble key={msg.id} message={msg} />\r\n ))}\r\n </Box>\r\n );\r\n});\r\n","import React, { useRef, useState } from 'react';\r\nimport { Box, Text, useInput } from 'ink';\r\n\r\ninterface InputAreaProps {\r\n onSubmit: (text: string) => void;\r\n isRunning: boolean;\r\n onExitRequest: () => void;\r\n onScroll?: (direction: 'up' | 'down') => void;\r\n}\r\n\r\n/**\r\n * Custom text input that only accepts printable characters.\r\n */\r\nfunction CleanTextInput({ \r\n onSubmit, \r\n placeholder, \r\n onExitRequest, \r\n onScroll \r\n}: { \r\n onSubmit: (text: string) => void; \r\n placeholder?: string; \r\n onExitRequest: () => void;\r\n onScroll?: (direction: 'up' | 'down') => void;\r\n}) {\r\n const [value, setValue] = useState('');\r\n const [cursor, setCursor] = useState(0);\r\n const lastCtrlCAtRef = useRef(0);\r\n\r\n useInput((input, key) => {\r\n // Scroll handling\r\n if (onScroll) {\r\n if (key.pageUp || (key.upArrow && key.shift)) {\r\n onScroll('up');\r\n return;\r\n }\r\n if (key.pageDown || (key.downArrow && key.shift)) {\r\n onScroll('down');\r\n return;\r\n }\r\n }\r\n\r\n if (input === 'c' && key.ctrl) {\r\n if (value.length > 0) {\r\n setValue('');\r\n setCursor(0);\r\n lastCtrlCAtRef.current = 0;\r\n return;\r\n }\r\n\r\n const now = Date.now();\r\n const isDoublePress = now - lastCtrlCAtRef.current <= 1200;\r\n if (isDoublePress) {\r\n onExitRequest();\r\n lastCtrlCAtRef.current = 0;\r\n } else {\r\n lastCtrlCAtRef.current = now;\r\n }\r\n return;\r\n }\r\n\r\n if (key.return) {\r\n const trimmed = value.trim();\r\n if (trimmed) {\r\n onSubmit(trimmed);\r\n }\r\n setValue('');\r\n setCursor(0);\r\n return;\r\n }\r\n if (key.backspace || key.delete) {\r\n if (cursor > 0) {\r\n setValue(prev => prev.slice(0, cursor - 1) + prev.slice(cursor));\r\n setCursor(prev => prev - 1);\r\n }\r\n return;\r\n }\r\n if (key.leftArrow) { setCursor(prev => Math.max(0, prev - 1)); return; }\r\n if (key.rightArrow) { setCursor(prev => Math.min(value.length, prev + 1)); return; }\r\n if (input === 'a' && key.ctrl) { setCursor(0); return; }\r\n if (input === 'e' && key.ctrl) { setCursor(value.length); return; }\r\n if (input === 'u' && key.ctrl) { setValue(prev => prev.slice(cursor)); setCursor(0); return; }\r\n\r\n if (key.ctrl || key.meta || key.escape) return;\r\n if (!input || input.length === 0) return;\r\n if (input.includes('\\x1b') || input.includes('\\x00')) return;\r\n \r\n // Filter out some common terminal escape sequences\r\n if (/^(?:\\[<\\d+;\\d+;\\d+[Mm])+$/.test(input)) return;\r\n if (/^\\[<[0-9;Mm]*$/.test(input)) return;\r\n if (input === '[5~' || input === '[6~') return;\r\n\r\n for (let i = 0; i < input.length; i++) {\r\n const code = input.charCodeAt(i);\r\n if (code < 0x20 && code !== 0x09) return;\r\n if (code === 0x7f || (code >= 0x80 && code <= 0x9f)) return;\r\n }\r\n\r\n setValue(prev => prev.slice(0, cursor) + input + prev.slice(cursor));\r\n setCursor(prev => prev + input.length);\r\n });\r\n\r\n if (value.length === 0) {\r\n return (\r\n <>\r\n <Text inverse> </Text>\r\n <Text dimColor>{placeholder || ''}</Text>\r\n </>\r\n );\r\n }\r\n\r\n const before = value.slice(0, cursor);\r\n const at = cursor < value.length ? value[cursor] : ' ';\r\n const after = cursor < value.length ? value.slice(cursor + 1) : '';\r\n\r\n return (\r\n <>\r\n <Text>{before}</Text>\r\n <Text inverse>{at}</Text>\r\n <Text>{after}</Text>\r\n </>\r\n );\r\n}\r\n\r\nexport function InputArea({ onSubmit, isRunning, onExitRequest, onScroll }: InputAreaProps) {\r\n return (\r\n <Box paddingX={0}>\r\n <Box backgroundColor={isRunning ? \"#504945\" : \"#b8bb26\"} paddingX={1} marginRight={1}>\r\n <Text color=\"#282828\" bold>{isRunning ? \" WAIT \" : \" INPUT \"}</Text>\r\n </Box>\r\n <Box flexGrow={1}>\r\n {isRunning ? (\r\n <Box flexGrow={1} onWheel={(event) => {\r\n // Ink handles wheel? Not really, but just in case for future.\r\n }}>\r\n <Text color=\"#a89984\" italic>Thinking...</Text>\r\n </Box>\r\n ) : (\r\n <CleanTextInput\r\n onSubmit={onSubmit}\r\n placeholder=\"Type a message or /command...\"\r\n onExitRequest={onExitRequest}\r\n onScroll={onScroll}\r\n />\r\n )}\r\n </Box>\r\n </Box>\r\n );\r\n}\r\n","import React from 'react';\r\nimport { Box, Text } from 'ink';\r\nimport type { TodoPlan } from '../../../core/todo-store.js';\r\nimport type { SubAgentProgress } from '../../../core/sub-agent-tracker.js';\r\n\r\ninterface StatusBarProps {\r\n isRunning: boolean;\r\n modelName: string;\r\n todoPlan?: TodoPlan | null;\r\n subAgentProgress?: SubAgentProgress | null;\r\n}\r\n\r\nfunction formatTokens(n: number): string {\r\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\r\n if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`;\r\n return String(n);\r\n}\r\n\r\nexport function StatusBar({ isRunning, modelName, todoPlan, subAgentProgress }: StatusBarProps) {\r\n\r\n const todoProgress = todoPlan\r\n ? `${todoPlan.items.filter((i) => i.status === 'completed').length}/${todoPlan.items.length}`\r\n : null;\r\n\r\n return (\r\n <Box marginTop={1}>\r\n <Box backgroundColor=\"#3c3836\" paddingX={1}>\r\n <Text color=\"#ebdbb2\" bold> ZENCODE </Text>\r\n </Box>\r\n\r\n <Box backgroundColor=\"#504945\" paddingX={1} flexGrow={1}>\r\n <Text color=\"#ebdbb2\">{modelName}</Text>\r\n\r\n {isRunning && !subAgentProgress && (\r\n <>\r\n <Text color=\"#ebdbb2\"> │ </Text>\r\n <Text color=\"#8ec07c\">● thinking...</Text>\r\n </>\r\n )}\r\n\r\n {subAgentProgress && (\r\n <>\r\n <Text color=\"#ebdbb2\"> │ </Text>\r\n <Text color=\"#b8bb26\">Agents: {subAgentProgress.completed + subAgentProgress.failed}/{subAgentProgress.total}</Text>\r\n <Text color=\"#ebdbb2\"> │ </Text>\r\n <Text color=\"#83a598\">tokens: {formatTokens(subAgentProgress.tokens)}</Text>\r\n </>\r\n )}\r\n\r\n {todoProgress && (\r\n <>\r\n <Text color=\"#ebdbb2\"> │ </Text>\r\n <Text color=\"#fabd2f\">Plan: {todoProgress}</Text>\r\n </>\r\n )}\r\n </Box>\r\n\r\n <Box backgroundColor=\"#3c3836\" paddingX={1}>\r\n <Text color=\"#ebdbb2\">/help</Text>\r\n </Box>\r\n </Box>\r\n );\r\n}\r\n","import React, { useState } from 'react';\r\nimport { Box, Text, useInput } from 'ink';\r\nimport type { ConfirmPending, ConfirmResult } from '../state.js';\r\n\r\ninterface ConfirmPromptProps {\r\n confirm: ConfirmPending;\r\n onRespond: (result: ConfirmResult) => void;\r\n}\r\n\r\nconst OPTIONS: { key: 'allow' | 'always' | 'deny'; label: string }[] = [\r\n { key: 'allow', label: '允许' },\r\n { key: 'always', label: '始终允许' },\r\n { key: 'deny', label: '拒绝' },\r\n];\r\n\r\nfunction getToolDetails(toolName: string, params: Record<string, unknown>): { lines: string[]; label: string } {\r\n const lines: string[] = [];\r\n let label = toolName;\r\n\r\n switch (toolName) {\r\n case 'bash':\r\n label = 'Bash';\r\n lines.push(`命令: ${String(params['command'] || '')}`);\r\n break;\r\n case 'write-file':\r\n label = 'Write';\r\n lines.push(`文件: ${String(params['path'] || '')}`);\r\n if (params['content']) {\r\n const content = String(params['content']);\r\n const preview = content.length > 120 ? content.slice(0, 120) + '...' : content;\r\n lines.push(`内容: ${preview.split('\\n').slice(0, 3).join('\\n ')}`);\r\n }\r\n break;\r\n case 'edit-file':\r\n label = 'Edit';\r\n lines.push(`文件: ${String(params['path'] || '')}`);\r\n if (params['old_string']) {\r\n const old = String(params['old_string']);\r\n const preview = old.length > 80 ? old.slice(0, 80) + '...' : old;\r\n lines.push(`替换: ${preview}`);\r\n }\r\n if (params['new_string']) {\r\n const neu = String(params['new_string']);\r\n const preview = neu.length > 80 ? neu.slice(0, 80) + '...' : neu;\r\n lines.push(`为: ${preview}`);\r\n }\r\n break;\r\n case 'git':\r\n label = 'Git';\r\n lines.push(`命令: git ${String(params['command'] || '')}`);\r\n break;\r\n default:\r\n for (const [key, value] of Object.entries(params)) {\r\n const str = typeof value === 'string' ? value : JSON.stringify(value);\r\n lines.push(`${key}: ${str.slice(0, 80)}`);\r\n }\r\n break;\r\n }\r\n\r\n return { lines, label };\r\n}\r\n\r\n/** Minimal clean text input — only accepts printable chars, ignores escape sequences */\r\nfunction FeedbackInput({ onSubmit }: { onSubmit: (text: string) => void }) {\r\n const [value, setValue] = useState('');\r\n const [cursor, setCursor] = useState(0);\r\n\r\n useInput((input, key) => {\r\n if (key.return) {\r\n onSubmit(value);\r\n setValue('');\r\n setCursor(0);\r\n return;\r\n }\r\n if (key.backspace || key.delete) {\r\n if (cursor > 0) {\r\n setValue(prev => prev.slice(0, cursor - 1) + prev.slice(cursor));\r\n setCursor(prev => prev - 1);\r\n }\r\n return;\r\n }\r\n if (key.leftArrow) { setCursor(prev => Math.max(0, prev - 1)); return; }\r\n if (key.rightArrow) { setCursor(prev => Math.min(value.length, prev + 1)); return; }\r\n if (key.escape) { onSubmit(''); return; } // Escape cancels feedback\r\n\r\n if (key.ctrl || key.meta) return;\r\n if (!input || input.length === 0) return;\r\n if (input.includes('\\x1b') || input.includes('\\x00')) return;\r\n for (let i = 0; i < input.length; i++) {\r\n const code = input.charCodeAt(i);\r\n if (code < 0x20) return;\r\n if (code === 0x7f || (code >= 0x80 && code <= 0x9f)) return;\r\n }\r\n\r\n setValue(prev => prev.slice(0, cursor) + input + prev.slice(cursor));\r\n setCursor(prev => prev + input.length);\r\n });\r\n\r\n if (value.length === 0) {\r\n return (\r\n <>\r\n <Text inverse> </Text>\r\n <Text dimColor>输入反馈指令给 AI...</Text>\r\n </>\r\n );\r\n }\r\n\r\n const before = value.slice(0, cursor);\r\n const at = cursor < value.length ? value[cursor] : ' ';\r\n const after = cursor < value.length ? value.slice(cursor + 1) : '';\r\n\r\n return (\r\n <>\r\n <Text>{before}</Text>\r\n <Text inverse>{at}</Text>\r\n <Text>{after}</Text>\r\n </>\r\n );\r\n}\r\n\r\nexport function ConfirmPrompt({ confirm, onRespond }: ConfirmPromptProps) {\r\n const [selected, setSelected] = useState(0);\r\n const [feedbackMode, setFeedbackMode] = useState(false);\r\n\r\n useInput((input, key) => {\r\n if (feedbackMode) return;\r\n\r\n if (key.leftArrow) {\r\n setSelected((prev) => (prev - 1 + OPTIONS.length) % OPTIONS.length);\r\n } else if (key.rightArrow) {\r\n setSelected((prev) => (prev + 1) % OPTIONS.length);\r\n }\r\n else if (key.return) {\r\n onRespond(OPTIONS[selected]!.key);\r\n }\r\n else if (input === 'y' || input === 'Y') {\r\n onRespond('allow');\r\n } else if (input === 'n' || input === 'N') {\r\n onRespond('deny');\r\n } else if (input === 'a' || input === 'A') {\r\n onRespond('always');\r\n }\r\n else if (key.tab) {\r\n setFeedbackMode(true);\r\n }\r\n else if (key.escape) {\r\n onRespond('deny');\r\n }\r\n }, { isActive: !feedbackMode });\r\n\r\n const { lines, label } = getToolDetails(confirm.toolName, confirm.params);\r\n\r\n if (feedbackMode) {\r\n return (\r\n <Box flexDirection=\"column\" paddingX={0} marginY={1}>\r\n <Box backgroundColor=\"#fe8019\" paddingX={1}>\r\n <Text color=\"#282828\" bold> FEEDBACK </Text>\r\n </Box>\r\n <Box\r\n flexDirection=\"column\"\r\n borderStyle=\"round\"\r\n borderColor=\"#fe8019\"\r\n paddingX={1}\r\n >\r\n <Text bold color=\"#fabd2f\">{label}</Text>\r\n {lines.map((line, i) => (\r\n <Text key={i} color=\"#a89984\">{line}</Text>\r\n ))}\r\n <Box marginTop={1} gap={1}>\r\n <Text color=\"#83a598\" bold>Reason: </Text>\r\n <FeedbackInput\r\n onSubmit={(text) => {\r\n const trimmed = text.trim();\r\n if (trimmed) {\r\n onRespond({ feedback: trimmed });\r\n } else {\r\n setFeedbackMode(false);\r\n }\r\n }}\r\n />\r\n </Box>\r\n </Box>\r\n <Box paddingX={1}>\r\n <Text dimColor>Enter to send · Esc to cancel</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n return (\r\n <Box flexDirection=\"column\" paddingX={0} marginY={1}>\r\n <Box backgroundColor=\"#fe8019\" paddingX={1}>\r\n <Text color=\"#282828\" bold> CONFIRMATION REQUIRED </Text>\r\n </Box>\r\n <Box\r\n flexDirection=\"column\"\r\n borderStyle=\"round\"\r\n borderColor=\"#fe8019\"\r\n paddingX={1}\r\n >\r\n <Text bold color=\"#fabd2f\">{label}</Text>\r\n {lines.map((line, i) => (\r\n <Text key={i} color=\"#a89984\">{line}</Text>\r\n ))}\r\n\r\n <Box marginTop={1} gap={2} justifyContent=\"center\">\r\n {OPTIONS.map((opt, i) => {\r\n const isSelected = i === selected;\r\n const optColor = opt.key === 'deny' ? '#fb4934' : opt.key === 'allow' ? '#b8bb26' : '#8ec07c';\r\n return (\r\n <Box key={opt.key}>\r\n {isSelected ? (\r\n <Text bold backgroundColor={optColor} color=\"#282828\"> {opt.label} </Text>\r\n ) : (\r\n <Text color={optColor}> {opt.label} </Text>\r\n )}\r\n </Box>\r\n );\r\n })}\r\n </Box>\r\n </Box>\r\n\r\n <Box paddingX={1}>\r\n <Text dimColor>\r\n ← → select · Enter confirm · y/n shortcuts · Tab feedback\r\n </Text>\r\n </Box>\r\n </Box>\r\n );\r\n}\r\n","import React from 'react';\r\nimport { Box, Text } from 'ink';\r\nimport type { TodoPlan } from '../../../core/todo-store.js';\r\n\r\ninterface TodoPanelProps {\r\n plan: TodoPlan;\r\n}\r\n\r\nfunction getStatusIcon(status: string): string {\r\n switch (status) {\r\n case 'completed':\r\n return '✅';\r\n case 'in-progress':\r\n return '⏳';\r\n default:\r\n return '⚪';\r\n }\r\n}\r\n\r\nfunction getStatusColor(status: string): string {\r\n switch (status) {\r\n case 'completed':\r\n return '#b8bb26';\r\n case 'in-progress':\r\n return '#fabd2f';\r\n default:\r\n return '#928374';\r\n }\r\n}\r\n\r\nexport function TodoPanel({ plan }: TodoPanelProps) {\r\n const completed = plan.items.filter((i) => i.status === 'completed').length;\r\n const total = plan.items.length;\r\n\r\n return (\r\n <Box\r\n flexDirection=\"column\"\r\n borderStyle=\"round\"\r\n borderColor=\"#83a598\"\r\n paddingX={1}\r\n marginY={1}\r\n >\r\n <Box justifyContent=\"space-between\" marginBottom={1}>\r\n <Text bold color=\"#83a598\">\r\n 📋 PROJECT PLAN\r\n </Text>\r\n <Text color=\"#ebdbb2\">\r\n {completed}/{total} tasks\r\n </Text>\r\n </Box>\r\n {plan.items.map((item) => (\r\n <Box key={item.id} gap={1}>\r\n <Text color={getStatusColor(item.status)}>\r\n {getStatusIcon(item.status)}\r\n </Text>\r\n <Text\r\n color={item.status === 'completed' ? '#b8bb26' : item.status === 'in-progress' ? '#fabd2f' : '#ebdbb2'}\r\n dimColor={item.status === 'pending'}\r\n strikethrough={item.status === 'completed'}\r\n >\r\n {item.title}\r\n </Text>\r\n </Box>\r\n ))}\r\n </Box>\r\n );\r\n}\r\n","import React from 'react';\r\nimport { Box, Text } from 'ink';\r\n\r\ninterface HeaderProps {\r\n modelName: string;\r\n}\r\n\r\nexport function Header({ modelName }: HeaderProps) {\r\n return (\r\n <Box \r\n flexDirection=\"column\"\r\n width=\"100%\"\r\n borderStyle=\"round\"\r\n borderColor=\"#504945\"\r\n paddingX={1}\r\n marginTop={0}\r\n marginBottom={1}\r\n >\r\n <Box justifyContent=\"space-between\">\r\n <Box gap={1}>\r\n <Text bold color=\"#fe8019\">ZEN CODE</Text>\r\n <Text color=\"#a89984\" dimColor>v0.2.1</Text>\r\n </Box>\r\n <Text color=\"#83a598\" bold>{modelName}</Text>\r\n </Box>\r\n </Box>\r\n );\r\n}\r\n","import React, { useReducer, useCallback, useEffect, useRef, useState } from 'react';\r\nimport { Box, Text, useInput, useStdout } from 'ink';\r\nimport type { ZenCodeConfig } from '../../config/types.js';\r\nimport type { Agent } from '../../core/agent.js';\r\nimport type { ToolRegistry } from '../../tools/registry.js';\r\nimport type { TodoStore } from '../../core/todo-store.js';\r\nimport type { SubAgentTracker } from '../../core/sub-agent-tracker.js';\r\nimport type { SubAgentConfigRegistry } from '../../core/sub-agents/registry.js';\r\nimport type { SkillRegistry } from '../../core/skills/registry.js';\r\nimport { isAbortError, type LLMClient } from '../../llm/client.js';\r\nimport { setStructuredConfirmHandler } from '../../tools/permission.js';\r\nimport type { ConfirmExecutionResult } from '../../tools/permission.js';\r\nimport { tuiReducer, createInitialState, type TuiAction, type ConfirmPending, type ConfirmResult } from './state.js';\r\nimport { createBridgeCallbacks, registerConfirmToolId } from './bridge.js';\r\nimport { createSpawnAgentsTool } from '../../tools/spawn-agents.js';\r\nimport { createTodoTool } from '../../tools/todo.js';\r\nimport { ChatArea } from './components/ChatArea.js';\r\nimport { InputArea } from './components/InputArea.js';\r\nimport { StatusBar } from './components/StatusBar.js';\r\nimport { ConfirmPrompt } from './components/ConfirmPrompt.js';\r\nimport { TodoPanel } from './components/TodoPanel.js';\r\nimport { Header } from './components/Header.js';\r\n\r\ninterface AppProps {\r\n config: ZenCodeConfig;\r\n client: LLMClient;\r\n agent: Agent;\r\n registry: ToolRegistry;\r\n todoStore: TodoStore;\r\n subAgentTracker: SubAgentTracker;\r\n agentRegistry: SubAgentConfigRegistry;\r\n skillRegistry: SkillRegistry;\r\n}\r\n\r\nexport function App({ config, client, agent, registry, todoStore, subAgentTracker, agentRegistry, skillRegistry }: AppProps) {\r\n const { stdout } = useStdout();\r\n const [, setWidth] = useState(stdout.columns);\r\n\r\n useEffect(() => {\r\n const onResize = () => {\r\n setWidth(stdout.columns);\r\n };\r\n stdout.on('resize', onResize);\r\n return () => { stdout.off('resize', onResize); };\r\n }, [stdout]);\r\n\r\n const [state, dispatch] = useReducer(\r\n tuiReducer,\r\n createInitialState(config.model),\r\n );\r\n\r\n // Reset counter: forces full re-mount when /clear is used\r\n const [resetKey, setResetKey] = useState(0);\r\n const currentCallbacksRef = useRef<(ReturnType<typeof createBridgeCallbacks> & { _stopBatcher?: () => void }) | null>(null);\r\n\r\n const agentRef = useRef(agent);\r\n const todoStoreRef = useRef(todoStore);\r\n const subAgentTrackerRef = useRef(subAgentTracker);\r\n agentRef.current = agent;\r\n todoStoreRef.current = todoStore;\r\n subAgentTrackerRef.current = subAgentTracker;\r\n\r\n // Subscribe to TodoStore changes\r\n useEffect(() => {\r\n return todoStoreRef.current.subscribe((plan) => {\r\n dispatch({ type: 'SET_TODO_PLAN', plan });\r\n });\r\n }, []);\r\n\r\n // Subscribe to SubAgentTracker changes (throttled to reduce re-renders)\r\n useEffect(() => {\r\n let timer: ReturnType<typeof setTimeout> | null = null;\r\n let latest: import('../../core/sub-agent-tracker.js').SubAgentProgress | null = null;\r\n\r\n const unsub = subAgentTrackerRef.current.subscribe((progress) => {\r\n latest = progress;\r\n if (progress === null) {\r\n if (timer) { clearTimeout(timer); timer = null; }\r\n dispatch({ type: 'SET_SUB_AGENT_PROGRESS', progress: null });\r\n return;\r\n }\r\n if (!timer) {\r\n dispatch({ type: 'SET_SUB_AGENT_PROGRESS', progress });\r\n timer = setTimeout(() => {\r\n timer = null;\r\n if (latest) dispatch({ type: 'SET_SUB_AGENT_PROGRESS', progress: latest });\r\n }, 2000);\r\n }\r\n });\r\n\r\n return () => { unsub(); if (timer) clearTimeout(timer); };\r\n }, []);\r\n\r\n // Find active confirm pending\r\n const confirmPending = state.messages.reduce<ConfirmPending | undefined>(\r\n (found, msg) => found || msg.confirmPending,\r\n undefined,\r\n );\r\n\r\n // --- Register structured confirm handler ---\r\n useEffect(() => {\r\n setStructuredConfirmHandler((toolName, params) => {\r\n return new Promise<ConfirmExecutionResult>((resolve) => {\r\n const id = `confirm-${Date.now()}`;\r\n registerConfirmToolId(toolName, id);\r\n dispatch({\r\n type: 'TOOL_CONFIRMING',\r\n id,\r\n name: toolName,\r\n params,\r\n resolve: (result: ConfirmResult) => {\r\n if (result === 'always') {\r\n registry.addAutoApprove(toolName);\r\n resolve({ approved: true });\r\n } else if (result === 'allow') {\r\n resolve({ approved: true });\r\n } else if (result === 'deny') {\r\n resolve({ approved: false });\r\n } else {\r\n resolve({ approved: false, feedback: result.feedback });\r\n }\r\n },\r\n });\r\n });\r\n });\r\n return () => { setStructuredConfirmHandler(null); };\r\n }, [registry]);\r\n\r\n // --- Run agent with a message ---\r\n const runAgent = useCallback(async (text: string) => {\r\n dispatch({ type: 'ADD_USER_MESSAGE', text });\r\n dispatch({ type: 'START_ASSISTANT' });\r\n dispatch({ type: 'SET_RUNNING', running: true });\r\n\r\n const callbacks = createBridgeCallbacks(dispatch);\r\n currentCallbacksRef.current = callbacks as ReturnType<typeof createBridgeCallbacks> & { _stopBatcher?: () => void };\r\n\r\n try {\r\n await agentRef.current.run(text, callbacks);\r\n } catch (err) {\r\n if (!isAbortError(err)) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n dispatch({ type: 'SET_ERROR', error: msg });\r\n }\r\n } finally {\r\n currentCallbacksRef.current = null;\r\n }\r\n\r\n (callbacks as any)._stopBatcher?.();\r\n dispatch({ type: 'FINISH_STREAMING' });\r\n dispatch({ type: 'SET_RUNNING', running: false });\r\n }, []);\r\n\r\n // --- Handle user message submission ---\r\n const handleSubmit = useCallback(async (text: string) => {\r\n if (text.startsWith('/')) {\r\n // Check if it's a user-defined skill first\r\n const parts = text.slice(1).split(/\\s+/);\r\n const skillName = parts[0]!;\r\n const skillArgs = parts.slice(1).join(' ');\r\n const skill = skillRegistry.get(skillName);\r\n\r\n if (skill) {\r\n // Execute skill: expand prompt and send to agent\r\n const expandedPrompt = skillRegistry.expandPrompt(skill, skillArgs);\r\n await runAgent(expandedPrompt);\r\n return;\r\n }\r\n\r\n // Otherwise handle built-in slash commands\r\n handleSlashCommand(text, {\r\n config, agent: agentRef.current, registry, dispatch, setResetKey,\r\n client, todoStore, subAgentTracker, agentRegistry, skillRegistry,\r\n });\r\n return;\r\n }\r\n\r\n await runAgent(text);\r\n }, [config, runAgent]);\r\n\r\n // --- Handle confirm response ---\r\n const handleConfirmResponse = useCallback((result: ConfirmResult) => {\r\n if (confirmPending) {\r\n confirmPending.resolve(result);\r\n dispatch({ type: 'CONFIRM_RESPONDED', id: '' });\r\n const approved = result === 'allow' || result === 'always';\r\n if (approved) {\r\n for (const msg of state.messages) {\r\n for (const block of msg.blocks) {\r\n if (block.type === 'tool' && block.toolCall.status === 'confirming') {\r\n dispatch({ type: 'TOOL_EXECUTING', id: block.toolCall.id, name: block.toolCall.name, params: block.toolCall.params });\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }, [confirmPending, state.messages]);\r\n\r\n // --- Keyboard shortcuts ---\r\n useInput((input, key) => {\r\n if (key.escape) {\r\n if (state.isRunning) {\r\n agentRef.current.interrupt();\r\n currentCallbacksRef.current?._stopBatcher?.();\r\n dispatch({ type: 'SET_RUNNING', running: false });\r\n dispatch({ type: 'FINISH_STREAMING' });\r\n }\r\n return;\r\n }\r\n\r\n if (input === 'c' && key.ctrl) {\r\n if (state.isRunning) {\r\n agentRef.current.interrupt();\r\n currentCallbacksRef.current?._stopBatcher?.();\r\n dispatch({ type: 'SET_RUNNING', running: false });\r\n dispatch({ type: 'FINISH_STREAMING' });\r\n return;\r\n }\r\n }\r\n if (input === 'd' && key.ctrl) {\r\n process.exit(0);\r\n }\r\n });\r\n\r\n return (\r\n <Box key={resetKey} flexDirection=\"column\" paddingX={0} width=\"100%\">\r\n <Box paddingX={1} flexDirection=\"column\">\r\n <Header modelName={state.modelName} />\r\n <ChatArea messages={state.messages} />\r\n </Box>\r\n\r\n {state.error && (\r\n <Box borderStyle=\"round\" borderColor=\"#fb4934\" paddingX={1} marginBottom={1}>\r\n <Text color=\"#fb4934\" bold>ERROR: </Text>\r\n <Text color=\"#fb4934\">{state.error}</Text>\r\n </Box>\r\n )}\r\n\r\n {confirmPending && (\r\n <ConfirmPrompt confirm={confirmPending} onRespond={handleConfirmResponse} />\r\n )}\r\n\r\n {state.todoPlan && <TodoPanel plan={state.todoPlan} />}\r\n\r\n <Box marginTop={1}>\r\n <InputArea\r\n onSubmit={handleSubmit}\r\n isRunning={state.isRunning || !!confirmPending}\r\n onExitRequest={() => process.exit(0)}\r\n />\r\n </Box>\r\n\r\n <Box marginTop={0}>\r\n <StatusBar\r\n isRunning={state.isRunning}\r\n modelName={state.modelName}\r\n todoPlan={state.todoPlan}\r\n subAgentProgress={state.subAgentProgress}\r\n />\r\n </Box>\r\n </Box>\r\n );\r\n}\r\n\r\n// --- Slash commands ---\r\ninterface SlashCommandContext {\r\n config: ZenCodeConfig;\r\n agent: Agent;\r\n registry: ToolRegistry;\r\n dispatch: React.Dispatch<TuiAction>;\r\n setResetKey: React.Dispatch<React.SetStateAction<number>>;\r\n client: LLMClient;\r\n todoStore: TodoStore;\r\n subAgentTracker: SubAgentTracker;\r\n agentRegistry: SubAgentConfigRegistry;\r\n skillRegistry: SkillRegistry;\r\n}\r\n\r\nfunction handleSlashCommand(input: string, ctx: SlashCommandContext) {\r\n const { config, agent, registry, dispatch, setResetKey, client, todoStore, subAgentTracker, agentRegistry, skillRegistry } = ctx;\r\n const parts = input.trim().split(/\\s+/);\r\n const command = parts[0];\r\n\r\n switch (command) {\r\n case '/help':\r\n dispatch({ type: 'ADD_USER_MESSAGE', text: input });\r\n dispatch({ type: 'START_ASSISTANT' });\r\n {\r\n let helpText = `可用命令:\r\n /help 显示此帮助信息\r\n /skills 列出所有可用技能\r\n /agents 列出所有可用子 Agent\r\n /parallel 切换并行子 Agent 功能 on/off\r\n /todo 切换 todo 计划功能 on/off\r\n /clear 清空对话历史\r\n /info 显示当前配置\r\n Ctrl+C 取消当前请求 / 退出\r\n Ctrl+D 退出`;\r\n const skills = skillRegistry.list();\r\n if (skills.length > 0) {\r\n helpText += `\\n\\n可用技能:\\n${skills.map(s => ` /${s.name} ${s.description}`).join('\\n')}`;\r\n }\r\n dispatch({ type: 'APPEND_CONTENT', text: helpText });\r\n }\r\n dispatch({ type: 'FINISH_STREAMING' });\r\n break;\r\n\r\n case '/skills': {\r\n const skills = skillRegistry.list();\r\n dispatch({ type: 'ADD_USER_MESSAGE', text: input });\r\n dispatch({ type: 'START_ASSISTANT' });\r\n if (skills.length === 0) {\r\n dispatch({ type: 'APPEND_CONTENT', text: '暂无可用技能。在 ~/.zencode/skills/ 或 .zencode/skills/ 放置 YAML 文件添加技能。' });\r\n } else {\r\n const lines = skills.map(s => ` /${s.name}: ${s.description}`);\r\n dispatch({ type: 'APPEND_CONTENT', text: `可用技能 (${skills.length}):\\n${lines.join('\\n')}` });\r\n }\r\n dispatch({ type: 'FINISH_STREAMING' });\r\n break;\r\n }\r\n\r\n case '/agents': {\r\n const agents = agentRegistry.list();\r\n dispatch({ type: 'ADD_USER_MESSAGE', text: input });\r\n dispatch({ type: 'START_ASSISTANT' });\r\n if (agents.length === 0) {\r\n dispatch({ type: 'APPEND_CONTENT', text: '暂无可用子 Agent。' });\r\n } else {\r\n const lines = agents.map(a => ` ${a.name}: ${a.description} [tools: ${a.tools.join(', ')}]`);\r\n dispatch({ type: 'APPEND_CONTENT', text: `可用子 Agent (${agents.length}):\\n${lines.join('\\n')}` });\r\n }\r\n dispatch({ type: 'FINISH_STREAMING' });\r\n break;\r\n }\r\n\r\n case '/clear':\r\n agent.getConversation().clear();\r\n dispatch({ type: 'CLEAR_MESSAGES' });\r\n setResetKey(prev => prev + 1);\r\n break;\r\n\r\n case '/parallel': {\r\n const current = config.features.parallel_agents;\r\n const next = current === 'on' ? 'off' : 'on';\r\n config.features.parallel_agents = next;\r\n if (next === 'off') {\r\n registry.unregister('spawn-agents');\r\n } else if (!registry.has('spawn-agents')) {\r\n registry.register(createSpawnAgentsTool(client, registry, config, subAgentTracker));\r\n }\r\n dispatch({ type: 'ADD_USER_MESSAGE', text: input });\r\n dispatch({ type: 'START_ASSISTANT' });\r\n dispatch({ type: 'APPEND_CONTENT', text: `并行子 Agent 功能已${next === 'on' ? '开启' : '关闭'}` });\r\n dispatch({ type: 'FINISH_STREAMING' });\r\n break;\r\n }\r\n\r\n case '/todo': {\r\n const current = config.features.todo;\r\n const next = current === 'on' ? 'off' : 'on';\r\n config.features.todo = next;\r\n if (next === 'off') {\r\n registry.unregister('todo');\r\n } else if (!registry.has('todo')) {\r\n registry.register(createTodoTool(todoStore));\r\n }\r\n dispatch({ type: 'ADD_USER_MESSAGE', text: input });\r\n dispatch({ type: 'START_ASSISTANT' });\r\n dispatch({ type: 'APPEND_CONTENT', text: `Todo 计划功能已${next === 'on' ? '开启' : '关闭'}` });\r\n dispatch({ type: 'FINISH_STREAMING' });\r\n break;\r\n }\r\n\r\n case '/info':\r\n dispatch({ type: 'ADD_USER_MESSAGE', text: input });\r\n dispatch({ type: 'START_ASSISTANT' });\r\n dispatch({\r\n type: 'APPEND_CONTENT',\r\n text: `模型: ${config.model}\\n基础 URL: ${config.base_url}\\n子 Agent: ${agentRegistry.listNames().join(', ') || '无'}\\n技能: ${skillRegistry.listNames().map(n => '/' + n).join(', ') || '无'}`,\r\n });\r\n dispatch({ type: 'FINISH_STREAMING' });\r\n break;\r\n\r\n default:\r\n dispatch({ type: 'ADD_USER_MESSAGE', text: input });\r\n dispatch({ type: 'START_ASSISTANT' });\r\n dispatch({\r\n type: 'APPEND_CONTENT',\r\n text: `未知命令: ${command}。输入 /help 查看帮助。`,\r\n });\r\n dispatch({ type: 'FINISH_STREAMING' });\r\n break;\r\n }\r\n}\r\n","import React from 'react';\r\nimport { render } from 'ink';\r\nimport type { ZenCodeConfig } from '../../config/types.js';\r\nimport { createLLMClient } from '../../llm/client.js';\r\nimport { ToolRegistry } from '../../tools/registry.js';\r\nimport { registerCoreTools } from '../../tools/register.js';\r\nimport { Agent } from '../../core/agent.js';\r\nimport { buildPrompt } from '../../core/prompt/builder.js';\r\nimport { TodoStore } from '../../core/todo-store.js';\r\nimport { SubAgentTracker } from '../../core/sub-agent-tracker.js';\r\nimport { SubAgentConfigRegistry } from '../../core/sub-agents/registry.js';\r\nimport { loadAllAgentConfigs } from '../../core/sub-agents/loader.js';\r\nimport { SkillRegistry } from '../../core/skills/registry.js';\r\nimport { loadAllSkills } from '../../core/skills/loader.js';\r\nimport { createSpawnAgentsTool } from '../../tools/spawn-agents.js';\r\nimport { createTodoTool } from '../../tools/todo.js';\r\nimport { createDispatchTool } from '../../tools/dispatch.js';\r\nimport { App } from './App.js';\r\n\r\ninterface TuiOptions {\r\n config: ZenCodeConfig;\r\n}\r\n\r\n/**\r\n * Start the full-screen TUI using Ink (React for CLI)\r\n */\r\nexport async function startTui(options: TuiOptions): Promise<void> {\r\n const { config } = options;\r\n\r\n // Load sub-agent configs (before buildPrompt so agents layer can be included)\r\n const agentRegistry = new SubAgentConfigRegistry();\r\n for (const agentConfig of loadAllAgentConfigs()) {\r\n agentRegistry.register(agentConfig);\r\n }\r\n\r\n // Build system prompt\r\n const { systemPrompt } = await buildPrompt(config, agentRegistry.list());\r\n\r\n // Register tools\r\n const registry = new ToolRegistry();\r\n registerCoreTools(registry);\r\n registry.setPermissions(config.permissions);\r\n\r\n // Create LLM client\r\n const client = createLLMClient({\r\n apiKey: config.api_key,\r\n baseURL: config.base_url,\r\n model: config.model,\r\n temperature: config.temperature,\r\n maxTokens: config.max_tokens,\r\n });\r\n\r\n // Create stores\r\n const todoStore = new TodoStore();\r\n const subAgentTracker = new SubAgentTracker();\r\n\r\n // Load skills\r\n const skillRegistry = new SkillRegistry();\r\n for (const skill of loadAllSkills()) {\r\n skillRegistry.register(skill);\r\n }\r\n\r\n // Register tools based on feature flags\r\n if (config.features.parallel_agents === 'on') {\r\n registry.register(createSpawnAgentsTool(client, registry, config, subAgentTracker));\r\n }\r\n if (config.features.todo === 'on') {\r\n registry.register(createTodoTool(todoStore));\r\n }\r\n // Register dispatch tool (sub-agent system)\r\n registry.register(createDispatchTool(client, registry, config, agentRegistry, subAgentTracker));\r\n\r\n // Create agent\r\n const agent = new Agent(client, registry, config, systemPrompt);\r\n\r\n // Render the full-screen TUI\r\n const { waitUntilExit } = render(\r\n <App\r\n config={config}\r\n client={client}\r\n agent={agent}\r\n registry={registry}\r\n todoStore={todoStore}\r\n subAgentTracker={subAgentTracker}\r\n agentRegistry={agentRegistry}\r\n skillRegistry={skillRegistry}\r\n />,\r\n {\r\n patchConsole: true,\r\n exitOnCtrlC: false,\r\n },\r\n );\r\n\r\n await waitUntilExit();\r\n}\r\n","import { Command } from 'commander';\r\nimport type { CliOptions } from '../config/loader.js';\r\nimport { loadConfig } from '../config/loader.js';\r\nimport { createLLMClient } from '../llm/client.js';\r\nimport { ToolRegistry } from '../tools/registry.js';\r\nimport { registerCoreTools } from '../tools/register.js';\r\nimport { Agent, type AgentCallbacks } from '../core/agent.js';\r\nimport { buildPrompt } from '../core/prompt/builder.js';\r\nimport { startRepl } from './repl.js';\r\nimport { TodoStore } from '../core/todo-store.js';\r\nimport { SubAgentConfigRegistry } from '../core/sub-agents/registry.js';\r\nimport { loadAllAgentConfigs } from '../core/sub-agents/loader.js';\r\nimport { createSpawnAgentsTool } from '../tools/spawn-agents.js';\r\nimport { createTodoTool } from '../tools/todo.js';\r\nimport { createDispatchTool } from '../tools/dispatch.js';\r\nimport { createThinkFilter } from './tui/bridge.js';\r\nimport { printStream, printToolCall, printToolResult, printError, printInfo } from './ui.js';\r\n\r\nexport { registerCoreTools };\r\n\r\n/**\r\n * 单次执行模式(非交互式)\r\n */\r\nasync function runOnce(prompt: string, config: ReturnType<typeof loadConfig>): Promise<void> {\r\n // Load sub-agent configs (before buildPrompt so agents layer can be included)\r\n const agentRegistry = new SubAgentConfigRegistry();\r\n for (const agentConfig of loadAllAgentConfigs()) {\r\n agentRegistry.register(agentConfig);\r\n }\r\n\r\n const { systemPrompt } = await buildPrompt(config, agentRegistry.list());\r\n const registry = new ToolRegistry();\r\n registerCoreTools(registry);\r\n registry.setPermissions(config.permissions);\r\n\r\n const client = createLLMClient({\r\n apiKey: config.api_key,\r\n baseURL: config.base_url,\r\n model: config.model,\r\n temperature: config.temperature,\r\n maxTokens: config.max_tokens,\r\n });\r\n\r\n // Register tools based on feature flags\r\n const todoStore = new TodoStore();\r\n if (config.features.parallel_agents === 'on') {\r\n registry.register(createSpawnAgentsTool(client, registry, config));\r\n }\r\n if (config.features.todo === 'on') {\r\n registry.register(createTodoTool(todoStore));\r\n }\r\n\r\n registry.register(createDispatchTool(client, registry, config, agentRegistry));\r\n\r\n let isStreaming = false;\r\n const thinkFilter = createThinkFilter();\r\n const callbacks: AgentCallbacks = {\r\n onContent: (text) => {\r\n const filtered = thinkFilter(text);\r\n if (!filtered) return;\r\n if (!isStreaming) {\r\n isStreaming = true;\r\n }\r\n printStream(filtered);\r\n },\r\n onToolExecuting: (name, params) => {\r\n if (isStreaming) {\r\n process.stdout.write('\\n');\r\n isStreaming = false;\r\n }\r\n printToolCall(name, params);\r\n },\r\n onToolResult: (name, result, truncated) => {\r\n printToolResult(name, result, truncated);\r\n },\r\n onError: (err) => {\r\n printError(err.message);\r\n },\r\n };\r\n\r\n try {\r\n const agent = new Agent(client, registry, config, systemPrompt);\r\n await agent.run(prompt, callbacks);\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n printError(msg);\r\n process.exit(1);\r\n }\r\n\r\n if (isStreaming) {\r\n process.stdout.write('\\n');\r\n }\r\n}\r\n\r\n/**\r\n * 创建 CLI 程序\r\n */\r\nexport function createCli(): Command {\r\n const program = new Command();\r\n\r\n program\r\n .name('zencode')\r\n .description('极简 CLI AI 编程工具')\r\n .version('0.2.3')\r\n .option('-m, --model <model>', '指定模型名称')\r\n .option('-k, --api-key <key>', 'API 密钥')\r\n .option('-u, --base-url <url>', 'API 基础 URL')\r\n .option('--simple', '使用简单 REPL 模式(非全屏 TUI)')\r\n .argument('[prompt...]', '直接执行的提示词(非交互式)')\r\n .action(async (promptParts: string[], opts: CliOptions & { simple?: boolean }) => {\r\n const config = loadConfig(opts);\r\n\r\n // 验证 API key\r\n if (!config.api_key) {\r\n printError('未设置 API 密钥。请通过以下方式之一设置:');\r\n printError(' 1. 环境变量 ZENCODE_API_KEY');\r\n printError(' 2. 配置文件 ~/.zencode/config.yaml 中设置 api_key');\r\n printError(' 3. CLI 参数 --api-key');\r\n process.exit(1);\r\n }\r\n\r\n const prompt = promptParts.join(' ');\r\n\r\n if (prompt) {\r\n // 单次执行模式\r\n await runOnce(prompt, config);\r\n } else if (opts.simple) {\r\n // 简单 REPL 模式(旧版)\r\n await startRepl({ config });\r\n } else {\r\n // 全屏 TUI 模式(默认)\r\n const { startTui } = await import('./tui/index.js');\r\n await startTui({ config });\r\n }\r\n });\r\n\r\n return program;\r\n}\r\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\nimport { parse as parseYaml } from 'yaml';\nimport type { ZenCodeConfig } from './types.js';\nimport { DEFAULT_CONFIG } from './defaults.js';\n\n/**\n * 深度合并两个对象,source 中的值覆盖 target 中的值\n */\nfunction deepMerge(target: Record<string, any>, source: Record<string, any>): any {\n const result = { ...target };\n for (const key of Object.keys(source)) {\n const sourceVal = source[key];\n const targetVal = target[key];\n if (\n sourceVal !== undefined &&\n sourceVal !== null &&\n typeof sourceVal === 'object' &&\n !Array.isArray(sourceVal) &&\n typeof targetVal === 'object' &&\n !Array.isArray(targetVal) &&\n targetVal !== null\n ) {\n result[key] = deepMerge(targetVal, sourceVal);\n } else if (sourceVal !== undefined) {\n result[key] = sourceVal;\n }\n }\n return result;\n}\n\n/**\n * 加载 YAML 配置文件,如果不存在返回空对象\n */\nfunction loadYamlFile(filePath: string): Partial<ZenCodeConfig> {\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n return (parseYaml(content) as Partial<ZenCodeConfig>) || {};\n } catch {\n return {};\n }\n}\n\n/**\n * 从环境变量加载配置\n */\nfunction loadEnvConfig(): Partial<ZenCodeConfig> {\n const config: Partial<ZenCodeConfig> = {};\n\n if (process.env['ZENCODE_API_KEY']) {\n config.api_key = process.env['ZENCODE_API_KEY'];\n }\n if (process.env['ZENCODE_MODEL']) {\n config.model = process.env['ZENCODE_MODEL'];\n }\n if (process.env['ZENCODE_BASE_URL']) {\n config.base_url = process.env['ZENCODE_BASE_URL'];\n }\n\n return config;\n}\n\n/**\n * 从 CLI 参数加载配置\n */\nexport interface CliOptions {\n model?: string;\n apiKey?: string;\n baseUrl?: string;\n}\n\nfunction loadCliConfig(opts: CliOptions): Partial<ZenCodeConfig> {\n const config: Partial<ZenCodeConfig> = {};\n\n if (opts.model) config.model = opts.model;\n if (opts.apiKey) config.api_key = opts.apiKey;\n if (opts.baseUrl) config.base_url = opts.baseUrl;\n\n return config;\n}\n\n/**\n * 加载并合并所有配置源\n * 优先级(从低到高):默认值 < 全局配置 < 项目配置 < 环境变量 < CLI参数\n */\nexport function loadConfig(cliOpts: CliOptions = {}): ZenCodeConfig {\n const globalConfigPath = path.join(os.homedir(), '.zencode', 'config.yaml');\n const projectDirConfigPath = path.resolve('.zencode', 'config.yaml');\n const projectFileConfigPath = path.resolve('.zencode.yaml');\n\n let config = { ...DEFAULT_CONFIG };\n config = deepMerge(config, loadYamlFile(globalConfigPath));\n config = deepMerge(config, loadYamlFile(projectDirConfigPath));\n config = deepMerge(config, loadYamlFile(projectFileConfigPath));\n config = deepMerge(config, loadEnvConfig());\n config = deepMerge(config, loadCliConfig(cliOpts));\n\n return config;\n}\n","import type { ZenCodeConfig } from './types.js';\n\nexport const DEFAULT_CONFIG: ZenCodeConfig = {\n model: 'deepseek-chat',\n api_key: '',\n base_url: 'https://api.deepseek.com/v1',\n temperature: 0.7,\n max_tokens: 8192,\n\n features: {\n git: 'auto',\n mcp: 'off',\n planning_layer: 'on',\n parallel_agents: 'on',\n todo: 'on',\n },\n\n permissions: {\n auto_approve: ['read-file', 'glob', 'grep', 'spawn-agents', 'todo', 'dispatch'],\n require_approval: ['write-file', 'edit-file', 'bash', 'git'],\n },\n\n mcp_servers: [],\n prompts: [],\n max_tool_output: 30000,\n};\n","import * as readline from 'node:readline';\r\nimport type { ZenCodeConfig } from '../config/types.js';\r\nimport { createLLMClient, type LLMClient } from '../llm/client.js';\r\nimport { ToolRegistry } from '../tools/registry.js';\r\nimport { Agent, type AgentCallbacks } from '../core/agent.js';\r\nimport { buildPrompt } from '../core/prompt/builder.js';\r\nimport { registerCoreTools } from '../tools/register.js';\r\nimport { setConfirmHandler } from '../tools/permission.js';\r\nimport { TodoStore } from '../core/todo-store.js';\r\nimport { SubAgentConfigRegistry } from '../core/sub-agents/registry.js';\r\nimport { loadAllAgentConfigs } from '../core/sub-agents/loader.js';\r\nimport { SkillRegistry } from '../core/skills/registry.js';\r\nimport { loadAllSkills } from '../core/skills/loader.js';\r\nimport { createSpawnAgentsTool } from '../tools/spawn-agents.js';\r\nimport { createTodoTool } from '../tools/todo.js';\r\nimport { createDispatchTool } from '../tools/dispatch.js';\r\nimport { createThinkFilter } from './tui/bridge.js';\r\nimport {\r\n printWelcome,\r\n printStream,\r\n printToolCall,\r\n printToolResult,\r\n printError,\r\n printInfo,\r\n printSuccess,\r\n printWarning,\r\n} from './ui.js';\r\n\r\ninterface ReplOptions {\r\n config: ZenCodeConfig;\r\n}\r\n\r\n/**\r\n * 处理斜杠命令\r\n */\r\nfunction handleSlashCommand(\r\n input: string,\r\n context: {\r\n config: ZenCodeConfig;\r\n registry: ToolRegistry;\r\n client: LLMClient;\r\n todoStore: TodoStore;\r\n agentRegistry: SubAgentConfigRegistry;\r\n skillRegistry: SkillRegistry;\r\n },\r\n): boolean | 'clear' {\r\n const parts = input.trim().split(/\\s+/);\r\n const command = parts[0];\r\n\r\n switch (command) {\r\n case '/help':\r\n console.log(`\r\n可用命令:\r\n /help 显示此帮助信息\r\n /skills 列出所有可用技能(用户自定义斜杠命令)\r\n /agents 列出所有可用子 Agent\r\n /parallel 切换并行子 Agent 功能 on/off\r\n /todo 切换 todo 计划功能 on/off\r\n /clear 清空对话历史\r\n /info 显示当前配置\r\n /exit 退出\r\n`);\r\n return true;\r\n\r\n case '/skills': {\r\n const skills = context.skillRegistry.list();\r\n if (skills.length === 0) {\r\n printInfo('暂无可用技能。在 ~/.zencode/skills/ 或 .zencode/skills/ 中添加 YAML 文件定义技能。');\r\n } else {\r\n printInfo(`可用技能 (${skills.length}):`);\r\n for (const s of skills) {\r\n printInfo(` /${s.name}: ${s.description}`);\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n case '/agents': {\r\n const agents = context.agentRegistry.list();\r\n if (agents.length === 0) {\r\n printInfo('暂无可用子 Agent');\r\n } else {\r\n printInfo(`可用子 Agent (${agents.length}):`);\r\n for (const a of agents) {\r\n printInfo(` ${a.name}: ${a.description}`);\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n case '/clear':\r\n printSuccess('对话历史已清空');\r\n return 'clear';\r\n\r\n case '/parallel': {\r\n const current = context.config.features.parallel_agents;\r\n const next = current === 'on' ? 'off' : 'on';\r\n context.config.features.parallel_agents = next;\r\n if (next === 'off') {\r\n context.registry.unregister('spawn-agents');\r\n } else if (!context.registry.has('spawn-agents')) {\r\n context.registry.register(\r\n createSpawnAgentsTool(context.client, context.registry, context.config),\r\n );\r\n }\r\n printSuccess(`并行子 Agent 功能已${next === 'on' ? '开启' : '关闭'}`);\r\n return true;\r\n }\r\n\r\n case '/todo': {\r\n const current = context.config.features.todo;\r\n const next = current === 'on' ? 'off' : 'on';\r\n context.config.features.todo = next;\r\n if (next === 'off') {\r\n context.registry.unregister('todo');\r\n } else if (!context.registry.has('todo')) {\r\n context.registry.register(createTodoTool(context.todoStore));\r\n }\r\n printSuccess(`Todo 计划功能已${next === 'on' ? '开启' : '关闭'}`);\r\n return true;\r\n }\r\n\r\n case '/info':\r\n printInfo(`模型: ${context.config.model}`);\r\n printInfo(`基础 URL: ${context.config.base_url}`);\r\n printInfo(`子 Agent: ${context.agentRegistry.listNames().join(', ') || '无'}`);\r\n printInfo(`技能: ${context.skillRegistry.listNames().join(', ') || '无'}`);\r\n return true;\r\n\r\n case '/exit':\r\n process.exit(0);\r\n\r\n default:\r\n printWarning(`未知命令: ${command}。输入 /help 查看帮助。`);\r\n return true;\r\n }\r\n}\r\n\r\n/**\r\n * 启动交互式 REPL\r\n */\r\nexport async function startRepl(options: ReplOptions): Promise<void> {\r\n const { config } = options;\r\n\r\n // Load sub-agent configs (before buildPrompt so agents layer can be included)\r\n const agentRegistry = new SubAgentConfigRegistry();\r\n for (const agentConfig of loadAllAgentConfigs()) {\r\n agentRegistry.register(agentConfig);\r\n }\r\n\r\n // 构建提示词\r\n const { systemPrompt } = await buildPrompt(config, agentRegistry.list());\r\n\r\n // 注册工具\r\n const registry = new ToolRegistry();\r\n registerCoreTools(registry);\r\n registry.setPermissions(config.permissions);\r\n\r\n // 创建 LLM 客户端\r\n const client = createLLMClient({\r\n apiKey: config.api_key,\r\n baseURL: config.base_url,\r\n model: config.model,\r\n temperature: config.temperature,\r\n maxTokens: config.max_tokens,\r\n });\r\n\r\n // 创建 stores 并注册新工具\r\n const todoStore = new TodoStore();\r\n if (config.features.parallel_agents === 'on') {\r\n registry.register(createSpawnAgentsTool(client, registry, config));\r\n }\r\n if (config.features.todo === 'on') {\r\n registry.register(createTodoTool(todoStore));\r\n }\r\n\r\n // Load skills\r\n const skillRegistry = new SkillRegistry();\r\n for (const skill of loadAllSkills()) {\r\n skillRegistry.register(skill);\r\n }\r\n\r\n // Register dispatch tool (sub-agent system)\r\n registry.register(createDispatchTool(client, registry, config, agentRegistry));\r\n\r\n // 创建 Agent\r\n let agent = new Agent(client, registry, config, systemPrompt);\r\n\r\n // 打印欢迎信息\r\n printWelcome(config.model);\r\n\r\n // 创建 readline 接口\r\n const rl = readline.createInterface({\r\n input: process.stdin,\r\n output: process.stdout,\r\n prompt: '> ',\r\n historySize: 100,\r\n });\r\n\r\n // 注入确认处理函数\r\n setConfirmHandler(async (promptText: string): Promise<boolean> => {\r\n return new Promise<boolean>((resolve) => {\r\n process.stdout.write(promptText);\r\n const onData = (data: Buffer) => {\r\n process.stdin.removeListener('data', onData);\r\n process.stdin.pause();\r\n const answer = data.toString().trim().toLowerCase();\r\n resolve(answer === 'y');\r\n };\r\n process.stdin.resume();\r\n process.stdin.once('data', onData);\r\n });\r\n });\r\n\r\n rl.prompt();\r\n\r\n rl.on('line', async (line) => {\r\n const input = line.trim();\r\n if (!input) {\r\n rl.prompt();\r\n return;\r\n }\r\n\r\n // 处理斜杠命令\r\n if (input.startsWith('/')) {\r\n // 先检查是否是用户定义的 skill\r\n const slashParts = input.slice(1).split(/\\s+/);\r\n const skillName = slashParts[0] ?? '';\r\n const skillArgs = slashParts.slice(1).join(' ');\r\n const skill = skillRegistry.get(skillName);\r\n\r\n if (skill) {\r\n // 展开 skill prompt 并发送给主 Agent\r\n const expandedPrompt = skillRegistry.expandPrompt(skill, skillArgs);\r\n rl.pause();\r\n\r\n let isStreaming = false;\r\n const thinkFilter = createThinkFilter();\r\n const callbacks: AgentCallbacks = {\r\n onContent: (text) => {\r\n const filtered = thinkFilter(text);\r\n if (!filtered) return;\r\n if (!isStreaming) {\r\n isStreaming = true;\r\n process.stdout.write('\\n');\r\n }\r\n printStream(filtered);\r\n },\r\n onToolExecuting: (name, params) => {\r\n if (isStreaming) {\r\n process.stdout.write('\\n');\r\n isStreaming = false;\r\n }\r\n printToolCall(name, params);\r\n },\r\n onToolResult: (name, result, truncated) => {\r\n printToolResult(name, result, truncated);\r\n },\r\n onError: (err) => {\r\n if (isStreaming) {\r\n process.stdout.write('\\n');\r\n isStreaming = false;\r\n }\r\n printError(err.message);\r\n },\r\n };\r\n\r\n try {\r\n await agent.run(expandedPrompt, callbacks);\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n printError(msg);\r\n }\r\n\r\n if (isStreaming) {\r\n process.stdout.write('\\n');\r\n }\r\n console.log();\r\n rl.resume();\r\n rl.prompt();\r\n return;\r\n }\r\n\r\n // 内置斜杠命令\r\n const handled = handleSlashCommand(input, {\r\n config,\r\n registry,\r\n client,\r\n todoStore,\r\n agentRegistry,\r\n skillRegistry,\r\n });\r\n if (handled === 'clear') {\r\n // 重建 Agent,清空对话历史\r\n agent = new Agent(client, registry, config, systemPrompt);\r\n rl.prompt();\r\n return;\r\n }\r\n if (handled) {\r\n rl.prompt();\r\n return;\r\n }\r\n }\r\n\r\n // 暂停 REPL readline,防止和确认弹窗抢 stdin\r\n rl.pause();\r\n\r\n // 构建回调\r\n let isStreaming = false;\r\n const thinkFilter = createThinkFilter();\r\n const callbacks: AgentCallbacks = {\r\n onContent: (text) => {\r\n const filtered = thinkFilter(text);\r\n if (!filtered) return;\r\n if (!isStreaming) {\r\n isStreaming = true;\r\n process.stdout.write('\\n');\r\n }\r\n printStream(filtered);\r\n },\r\n onToolExecuting: (name, params) => {\r\n if (isStreaming) {\r\n process.stdout.write('\\n');\r\n isStreaming = false;\r\n }\r\n printToolCall(name, params);\r\n },\r\n onToolResult: (name, result, truncated) => {\r\n printToolResult(name, result, truncated);\r\n },\r\n onError: (err) => {\r\n if (isStreaming) {\r\n process.stdout.write('\\n');\r\n isStreaming = false;\r\n }\r\n printError(err.message);\r\n },\r\n };\r\n\r\n try {\r\n await agent.run(input, callbacks);\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n printError(msg);\r\n }\r\n\r\n if (isStreaming) {\r\n process.stdout.write('\\n');\r\n }\r\n console.log(); // 空行分隔\r\n\r\n // 恢复 REPL readline\r\n rl.resume();\r\n rl.prompt();\r\n });\r\n\r\n rl.on('close', () => {\r\n console.log('\\n再见!');\r\n process.exit(0);\r\n });\r\n}\r\n","import chalk from 'chalk';\r\nimport ora, { type Ora } from 'ora';\r\nimport { marked } from 'marked';\r\nimport * as _markedTerminal from 'marked-terminal';\r\nimport { createTwoFilesPatch } from 'diff';\r\n\r\n// 配置 marked 使用终端渲染器\r\n// marked-terminal v7: named export 'markedTerminal' is the factory, default is the old Renderer class\r\nconst markedTerminal = (_markedTerminal as any).markedTerminal as () => any;\r\nmarked.use(markedTerminal());\r\n\r\n/**\r\n * 渲染 Markdown 到终端\r\n */\r\nexport function renderMarkdown(text: string): string {\r\n return (marked.parse(text) as string).trim();\r\n}\r\n\r\n/**\r\n * 创建加载动画\r\n */\r\nexport function createSpinner(text: string): Ora {\r\n return ora({ text, color: 'cyan' });\r\n}\r\n\r\n/**\r\n * 打印用户输入提示\r\n */\r\nexport function printPrompt(): void {\r\n process.stdout.write(chalk.green('> '));\r\n}\r\n\r\n/**\r\n * 打印助手回复\r\n */\r\nexport function printAssistant(text: string): void {\r\n console.log(renderMarkdown(text));\r\n}\r\n\r\n/**\r\n * 打印流式内容(不换行)\r\n */\r\nexport function printStream(text: string): void {\r\n process.stdout.write(text);\r\n}\r\n\r\n/**\r\n * 打印工具调用信息\r\n */\r\nexport function printToolCall(toolName: string, params: Record<string, unknown>): void {\r\n let detail = '';\r\n if (toolName === 'bash' && params['command']) {\r\n detail = ` ${chalk.dim(String(params['command']).slice(0, 80))}`;\r\n } else if ((toolName === 'read-file' || toolName === 'write-file' || toolName === 'edit-file') && params['path']) {\r\n detail = ` ${chalk.dim(String(params['path']))}`;\r\n } else if (toolName === 'glob' && params['pattern']) {\r\n detail = ` ${chalk.dim(String(params['pattern']))}`;\r\n } else if (toolName === 'grep' && params['pattern']) {\r\n detail = ` ${chalk.dim(String(params['pattern']))}`;\r\n } else if (toolName === 'spawn-agents' && params['tasks']) {\r\n const tasks = params['tasks'] as { description: string }[];\r\n detail = ` ${chalk.dim(`${tasks.length} 个并行任务`)}`;\r\n } else if (toolName === 'todo' && params['action']) {\r\n const action = String(params['action']);\r\n const id = params['id'] ? ` [${params['id']}]` : '';\r\n detail = ` ${chalk.dim(`${action}${id}`)}`;\r\n }\r\n const icon = toolName === 'spawn-agents' ? '⚡' : toolName === 'todo' ? '📋' : '⚙';\r\n console.log(chalk.yellow(` ${icon} ${toolName}`) + detail);\r\n}\r\n\r\n/**\r\n * 打印工具执行结果\r\n */\r\nexport function printToolResult(toolName: string, result: string, truncated: boolean): void {\r\n if (truncated) {\r\n console.log(chalk.dim(` ✓ ${toolName} (输出已截断)`));\r\n } else {\r\n const lines = result.split('\\n').length;\r\n console.log(chalk.dim(` ✓ ${toolName} (${lines} 行)`));\r\n }\r\n}\r\n\r\n/**\r\n * 打印错误信息\r\n */\r\nexport function printError(message: string): void {\r\n console.error(chalk.red(`✗ ${message}`));\r\n}\r\n\r\n/**\r\n * 打印信息\r\n */\r\nexport function printInfo(message: string): void {\r\n console.log(chalk.cyan(`ℹ ${message}`));\r\n}\r\n\r\n/**\r\n * 打印警告\r\n */\r\nexport function printWarning(message: string): void {\r\n console.log(chalk.yellow(`⚠ ${message}`));\r\n}\r\n\r\n/**\r\n * 打印成功消息\r\n */\r\nexport function printSuccess(message: string): void {\r\n console.log(chalk.green(`✓ ${message}`));\r\n}\r\n\r\n/**\r\n * 打印 diff\r\n */\r\nexport function printDiff(oldContent: string, newContent: string, filePath: string): void {\r\n const patch = createTwoFilesPatch(filePath, filePath, oldContent, newContent);\r\n const lines = patch.split('\\n');\r\n for (const line of lines) {\r\n if (line.startsWith('+') && !line.startsWith('+++')) {\r\n console.log(chalk.green(line));\r\n } else if (line.startsWith('-') && !line.startsWith('---')) {\r\n console.log(chalk.red(line));\r\n } else if (line.startsWith('@@')) {\r\n console.log(chalk.cyan(line));\r\n } else {\r\n console.log(chalk.dim(line));\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * 打印模式信息\r\n */\r\n/**\r\n * 打印欢迎信息\r\n */\r\nexport function printWelcome(modelName: string): void {\r\n console.log(chalk.bold.cyan('\\n ZenCode') + chalk.dim(' - 极简 AI 编程助手\\n'));\r\n console.log(chalk.dim(` 模型: ${modelName}`));\r\n console.log(chalk.dim(` 输入 /help 查看命令,Ctrl+C 退出\\n`));\r\n}\r\n","import { createCli } from '../src/cli/index.js';\n\nconst program = createCli();\nprogram.parse();\n"],"mappings":"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","names":["fs","path","fs","path","fs","path","newContent","resolve","fs","path","stat","fs","path","os","IS_WIN","fs","path","fs","init_registry","fs","path","os","parseYaml","init_registry","fs","path","os","parseYaml","init_loader","id","Box","Text","jsx","jsxs","MessageBubble","React","Box","jsx","ChatArea","Box","Text","jsx","jsxs","Box","Text","Fragment","jsx","jsxs","useState","Box","Text","useInput","Fragment","jsx","jsxs","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","useRef","useState","Box","Text","useInput","jsx","jsxs","resolve","handleSlashCommand","jsx","init_registry","init_loader","init_registry","init_loader","chalk","markedTerminal","chalk","chalk","resolve","isStreaming","thinkFilter","callbacks","init_registry","program","startTui"]}
1
+ {"version":3,"sources":["../../src/llm/client.ts","../../src/tools/registry.ts","../../src/tools/read-file.ts","../../src/tools/write-file.ts","../../src/tools/edit-file.ts","../../src/tools/bash.ts","../../src/tools/glob.ts","../../src/tools/grep.ts","../../src/tools/register.ts","../../src/tools/permission.ts","../../src/core/conversation.ts","../../src/core/read-tracker.ts","../../src/core/agent.ts","../../src/core/prompt/layers/core.ts","../../src/core/prompt/layers/planning.ts","../../src/core/prompt/layers/parallel.ts","../../src/core/prompt/layers/git.ts","../../src/core/prompt/layers/agents.ts","../../src/core/prompt/layers/project.ts","../../src/core/prompt/builder.ts","../../src/core/todo-store.ts","../../src/core/sub-agents/registry.ts","../../src/core/sub-agents/presets.ts","../../src/core/sub-agents/loader.ts","../../src/core/skills/registry.ts","../../src/core/skills/loader.ts","../../src/core/sub-agent.ts","../../src/tools/spawn-agents.ts","../../src/tools/todo.ts","../../src/core/sub-agents/runner.ts","../../src/tools/dispatch.ts","../../src/cli/tui/stores/progressStore.ts","../../src/cli/tui/bridge.ts","../../src/cli/ui.ts","../../src/core/sub-agent-tracker.ts","../../src/cli/tui/state.ts","../../src/cli/tui/components/ToolCallLine.tsx","../../src/cli/tui/components/MessageBubble.tsx","../../src/cli/tui/components/Header.tsx","../../src/cli/tui/components/ChatArea.tsx","../../src/cli/tui/components/InputArea.tsx","../../src/cli/tui/components/StatusBar.tsx","../../src/cli/tui/components/ConfirmPrompt.tsx","../../src/cli/tui/components/TodoPanel.tsx","../../src/cli/tui/App.tsx","../../src/cli/tui/index.tsx","../../src/cli/index.ts","../../src/config/loader.ts","../../src/config/defaults.ts","../../src/cli/repl.ts","../../bin/zencode.ts"],"sourcesContent":["import OpenAI from 'openai';\nimport type {\n Message,\n ToolDefinition,\n ToolCall,\n StreamDelta,\n} from './types.js';\n\nexport interface LLMClientOptions {\n apiKey: string;\n baseURL: string;\n model: string;\n temperature?: number;\n maxTokens?: number;\n}\n\nexport interface StreamCallbacks {\n onContent?: (text: string) => void;\n onToolCall?: (toolCall: ToolCall) => void;\n onToolCallStreaming?: (index: number, name: string, accumulatedArgs: string) => void;\n onFinish?: (message: Message) => void;\n onError?: (error: Error) => void;\n}\n\nexport class LLMClient {\n private client: OpenAI;\n private model: string;\n private temperature: number;\n private maxTokens: number;\n private activeAbortController: AbortController | null = null;\n\n constructor(options: LLMClientOptions) {\n this.client = new OpenAI({\n apiKey: options.apiKey,\n baseURL: options.baseURL,\n });\n this.model = options.model;\n this.temperature = options.temperature ?? 0.7;\n this.maxTokens = options.maxTokens ?? 8192;\n }\n\n /**\n * 流式调用 LLM,实时回调文本内容和工具调用\n */\n async chatStream(\n messages: Message[],\n tools: ToolDefinition[] | undefined,\n callbacks: StreamCallbacks,\n ): Promise<Message> {\n const params: OpenAI.Chat.ChatCompletionCreateParamsStreaming = {\n model: this.model,\n messages: messages as OpenAI.Chat.ChatCompletionMessageParam[],\n temperature: this.temperature,\n max_tokens: this.maxTokens,\n stream: true,\n };\n\n if (tools && tools.length > 0) {\n params.tools = tools as OpenAI.Chat.ChatCompletionTool[];\n params.tool_choice = 'auto';\n }\n\n // Request usage info in stream\n params.stream_options = { include_usage: true };\n\n const abortController = new AbortController();\n this.activeAbortController = abortController;\n\n try {\n const stream = await this.client.chat.completions.create(params, {\n signal: abortController.signal,\n });\n\n let contentParts: string[] = [];\n let reasoningParts: string[] = [];\n let reasoningStarted = false;\n let reasoningEnded = false;\n const toolCallMap = new Map<number, { id: string; name: string; args: string }>();\n let usageInfo: { prompt_tokens: number; completion_tokens: number; total_tokens: number } | null = null;\n\n for await (const chunk of stream) {\n // 捕获 usage(最后一个 chunk 包含)\n const chunkUsage = (chunk as any).usage;\n if (chunkUsage && chunkUsage.total_tokens) {\n usageInfo = {\n prompt_tokens: chunkUsage.prompt_tokens ?? 0,\n completion_tokens: chunkUsage.completion_tokens ?? 0,\n total_tokens: chunkUsage.total_tokens,\n };\n }\n\n const choice = chunk.choices[0];\n if (!choice) continue;\n\n const delta: StreamDelta = choice.delta as StreamDelta;\n\n // 处理 reasoning_content(deepseek-reasoner 思维链)\n if (delta.reasoning_content) {\n reasoningParts.push(delta.reasoning_content);\n // 首个 reasoning chunk 前注入 <think> 标签,让 thinkFilter 渲染\n if (!reasoningStarted) {\n reasoningStarted = true;\n callbacks.onContent?.('<think>');\n }\n callbacks.onContent?.(delta.reasoning_content);\n }\n\n // 处理文本内容\n if (delta.content) {\n // reasoning → content 过渡时注入 </think>\n if (reasoningStarted && !reasoningEnded) {\n reasoningEnded = true;\n callbacks.onContent?.('</think>');\n }\n contentParts.push(delta.content);\n callbacks.onContent?.(delta.content);\n }\n\n // 处理工具调用(流式中分片到达)\n if (delta.tool_calls) {\n for (const tc of delta.tool_calls) {\n const existing = toolCallMap.get(tc.index);\n if (existing) {\n if (tc.function?.arguments) {\n existing.args += tc.function.arguments;\n }\n } else {\n toolCallMap.set(tc.index, {\n id: tc.id || '',\n name: tc.function?.name || '',\n args: tc.function?.arguments || '',\n });\n }\n\n // 流式回调:write-file / edit-file 的参数实时推送\n const entry = toolCallMap.get(tc.index);\n if (entry && callbacks.onToolCallStreaming) {\n const n = entry.name;\n if (n === 'write-file' || n === 'edit-file') {\n callbacks.onToolCallStreaming(tc.index, n, entry.args);\n }\n }\n }\n }\n }\n\n // reasoning 结束但没有 content 跟随时(如只返回 tool_calls),关闭 think 标签\n if (reasoningStarted && !reasoningEnded) {\n reasoningEnded = true;\n callbacks.onContent?.('</think>');\n }\n\n // 组装完整的 tool_calls\n const toolCalls: ToolCall[] = [];\n for (const [, tc] of [...toolCallMap.entries()].sort(([a], [b]) => a - b)) {\n const toolCall: ToolCall = {\n id: tc.id,\n type: 'function',\n function: {\n name: tc.name,\n arguments: tc.args,\n },\n };\n toolCalls.push(toolCall);\n callbacks.onToolCall?.(toolCall);\n }\n\n const fullContent = contentParts.join('');\n const fullReasoning = reasoningParts.join('');\n const assistantMessage: Message = {\n role: 'assistant',\n content: fullContent || null,\n };\n\n if (fullReasoning) {\n assistantMessage.reasoning_content = fullReasoning;\n }\n\n if (toolCalls.length > 0) {\n assistantMessage.tool_calls = toolCalls;\n }\n\n if (usageInfo) {\n assistantMessage.usage = usageInfo;\n }\n\n callbacks.onFinish?.(assistantMessage);\n return assistantMessage;\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n if (!isAbortError(err)) {\n callbacks.onError?.(err);\n }\n throw err;\n } finally {\n if (this.activeAbortController === abortController) {\n this.activeAbortController = null;\n }\n }\n }\n\n /**\n * 非流式调用 LLM\n */\n async chat(\n messages: Message[],\n tools?: ToolDefinition[],\n ): Promise<Message> {\n const params: OpenAI.Chat.ChatCompletionCreateParamsNonStreaming = {\n model: this.model,\n messages: messages as OpenAI.Chat.ChatCompletionMessageParam[],\n temperature: this.temperature,\n max_tokens: this.maxTokens,\n stream: false,\n };\n\n if (tools && tools.length > 0) {\n params.tools = tools as OpenAI.Chat.ChatCompletionTool[];\n params.tool_choice = 'auto';\n }\n\n const response = await this.client.chat.completions.create(params);\n const choice = response.choices[0];\n if (!choice) {\n throw new Error('No response from LLM');\n }\n\n const msg = choice.message;\n const result: Message = {\n role: 'assistant',\n content: msg.content,\n };\n\n // 捕获 reasoning_content(deepseek-reasoner)\n const reasoning = (msg as unknown as Record<string, unknown>).reasoning_content;\n if (reasoning && typeof reasoning === 'string') {\n result.reasoning_content = reasoning;\n }\n\n if (msg.tool_calls && msg.tool_calls.length > 0) {\n result.tool_calls = msg.tool_calls.map((tc) => ({\n id: tc.id,\n type: 'function' as const,\n function: {\n name: tc.function.name,\n arguments: tc.function.arguments,\n },\n }));\n }\n\n // 捕获 token 用量\n if (response.usage) {\n result.usage = {\n prompt_tokens: response.usage.prompt_tokens,\n completion_tokens: response.usage.completion_tokens,\n total_tokens: response.usage.total_tokens,\n };\n }\n\n return result;\n }\n\n get modelName(): string {\n return this.model;\n }\n\n abortActiveStream(): void {\n if (this.activeAbortController) {\n this.activeAbortController.abort();\n this.activeAbortController = null;\n }\n }\n}\n\nexport function isAbortError(error: unknown): boolean {\n if (!error) return false;\n const err = error as { name?: string; message?: string; code?: string; cause?: { name?: string; code?: string } };\n const name = err.name || err.cause?.name || '';\n const code = err.code || err.cause?.code || '';\n const message = err.message || '';\n\n return (\n name === 'AbortError' ||\n name === 'APIUserAbortError' ||\n code === 'ABORT_ERR' ||\n /abort|aborted|cancel|cancelled|canceled|interrupted/i.test(message)\n );\n}\n\n/**\n * 从配置创建 LLM 客户端\n */\nexport function createLLMClient(options: LLMClientOptions): LLMClient {\n return new LLMClient(options);\n}\n","import type { Tool, ToolResult } from './types.js';\nimport type { ToolDefinition } from '../llm/types.js';\nimport type { PermissionsConfig } from '../config/types.js';\n\nexport class ToolRegistry {\n private tools = new Map<string, Tool>();\n private permissionOverrides: PermissionsConfig | null = null;\n\n register(tool: Tool): void {\n this.tools.set(tool.name, tool);\n }\n\n get(name: string): Tool | undefined {\n return this.tools.get(name);\n }\n\n has(name: string): boolean {\n return this.tools.has(name);\n }\n\n unregister(name: string): boolean {\n return this.tools.delete(name);\n }\n\n /**\n * 设置权限覆盖配置\n */\n setPermissions(permissions: PermissionsConfig): void {\n this.permissionOverrides = permissions;\n }\n\n /**\n * 运行时将某工具升级为自动批准(始终允许)\n */\n addAutoApprove(toolName: string): void {\n if (!this.permissionOverrides) {\n this.permissionOverrides = { auto_approve: [], require_approval: [] };\n }\n if (!this.permissionOverrides.auto_approve.includes(toolName)) {\n this.permissionOverrides.auto_approve.push(toolName);\n }\n // 从 require_approval 中移除\n this.permissionOverrides.require_approval =\n this.permissionOverrides.require_approval.filter((n) => n !== toolName);\n }\n\n /**\n * 获取工具的有效权限级别\n */\n getPermissionLevel(toolName: string): 'auto' | 'confirm' | 'deny' {\n if (this.permissionOverrides) {\n if (this.permissionOverrides.auto_approve.includes(toolName)) return 'auto';\n if (this.permissionOverrides.require_approval.includes(toolName)) return 'confirm';\n }\n const tool = this.tools.get(toolName);\n return tool?.permissionLevel ?? 'confirm';\n }\n\n /**\n * 执行工具调用\n */\n async execute(name: string, params: Record<string, unknown>, maxOutput: number): Promise<ToolResult> {\n const tool = this.tools.get(name);\n if (!tool) {\n return { content: `错误:未找到工具 \"${name}\"` };\n }\n\n try {\n const result = await tool.execute(params);\n\n // 截断过长的输出\n if (result.content.length > maxOutput) {\n return {\n content: result.content.slice(0, maxOutput) + '\\n\\n[输出已截断]',\n truncated: true,\n };\n }\n\n return result;\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return { content: `工具执行错误:${msg}` };\n }\n }\n\n /**\n * 导出为 OpenAI function calling 格式\n */\n toToolDefinitions(filter?: string[]): ToolDefinition[] {\n const tools: ToolDefinition[] = [];\n for (const [name, tool] of this.tools) {\n if (filter && !filter.includes(name)) continue;\n tools.push({\n type: 'function',\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters as unknown as Record<string, unknown>,\n },\n });\n }\n return tools;\n }\n\n /**\n * 获取所有已注册的工具名\n */\n listTools(): string[] {\n return [...this.tools.keys()];\n }\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { Tool, ToolResult } from './types.js';\n\nexport const readFileTool: Tool = {\n name: 'read-file',\n description: '读取文件内容。修改文件前必须先读取。支持 offset/limit 读取大文件的指定部分。返回带行号的内容。',\n parameters: {\n type: 'object',\n properties: {\n path: {\n type: 'string',\n description: '文件路径(相对于工作目录或绝对路径)',\n },\n offset: {\n type: 'number',\n description: '起始行号(从1开始),默认从头读取',\n },\n limit: {\n type: 'number',\n description: '读取的行数,默认读取全部',\n },\n },\n required: ['path'],\n },\n permissionLevel: 'auto',\n\n async execute(params: Record<string, unknown>): Promise<ToolResult> {\n const filePath = path.resolve(params['path'] as string);\n const offset = (params['offset'] as number) || 1;\n const limit = params['limit'] as number | undefined;\n\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n const lines = content.split('\\n');\n\n const startIdx = Math.max(0, offset - 1);\n const endIdx = limit ? startIdx + limit : lines.length;\n const selectedLines = lines.slice(startIdx, endIdx);\n\n // 带行号输出\n const numbered = selectedLines\n .map((line, i) => `${String(startIdx + i + 1).padStart(5)}\\t${line}`)\n .join('\\n');\n\n return { content: numbered || '(空文件)' };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return { content: `读取文件失败:${msg}` };\n }\n },\n};\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { Tool, ToolResult } from './types.js';\n\nexport const writeFileTool: Tool = {\n name: 'write-file',\n description: '创建新文件或完整重写文件。如果是修改已有文件,优先使用 edit-file。会自动创建父目录。',\n parameters: {\n type: 'object',\n properties: {\n path: {\n type: 'string',\n description: '文件路径',\n },\n content: {\n type: 'string',\n description: '要写入的文件内容',\n },\n overwrite: {\n type: 'boolean',\n description: '文件已存在时是否确认覆盖,默认 false',\n },\n },\n required: ['path', 'content'],\n },\n permissionLevel: 'confirm',\n\n async execute(params: Record<string, unknown>): Promise<ToolResult> {\n const filePath = path.resolve(params['path'] as string);\n const content = params['content'] as string;\n\n try {\n // 确保父目录存在\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n await fs.writeFile(filePath, content, 'utf-8');\n return { content: `文件已写入:${filePath}` };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return { content: `写入文件失败:${msg}` };\n }\n },\n};\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { Tool, ToolResult } from './types.js';\n\nexport const editFileTool: Tool = {\n name: 'edit-file',\n description: '通过字符串替换编辑文件(推荐的文件修改方式)。old_string 必须在文件中唯一匹配,将被替换为 new_string。匹配失败时请提供更多上下文使其唯一,或使用 replace_all。',\n parameters: {\n type: 'object',\n properties: {\n path: {\n type: 'string',\n description: '文件路径',\n },\n old_string: {\n type: 'string',\n description: '要被替换的原始字符串(必须唯一匹配)',\n },\n new_string: {\n type: 'string',\n description: '替换后的字符串',\n },\n replace_all: {\n type: 'boolean',\n description: '是否替换所有匹配项,默认 false',\n },\n },\n required: ['path', 'old_string', 'new_string'],\n },\n permissionLevel: 'confirm',\n\n async execute(params: Record<string, unknown>): Promise<ToolResult> {\n const filePath = path.resolve(params['path'] as string);\n const oldString = params['old_string'] as string;\n const newString = params['new_string'] as string;\n const replaceAll = (params['replace_all'] as boolean) ?? false;\n\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n\n if (replaceAll) {\n const newContent = content.split(oldString).join(newString);\n if (newContent === content) {\n return { content: `未找到匹配内容:${oldString.slice(0, 50)}...` };\n }\n await fs.writeFile(filePath, newContent, 'utf-8');\n const count = content.split(oldString).length - 1;\n return { content: `已替换 ${count} 处匹配` };\n }\n\n // 检查唯一性\n const firstIdx = content.indexOf(oldString);\n if (firstIdx === -1) {\n return { content: `未找到匹配内容:${oldString.slice(0, 100)}` };\n }\n\n const secondIdx = content.indexOf(oldString, firstIdx + 1);\n if (secondIdx !== -1) {\n return { content: `old_string 不唯一,找到多处匹配。请提供更多上下文使其唯一。` };\n }\n\n const newContent = content.slice(0, firstIdx) + newString + content.slice(firstIdx + oldString.length);\n await fs.writeFile(filePath, newContent, 'utf-8');\n\n return { content: `文件已编辑:${filePath}` };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return { content: `编辑文件失败:${msg}` };\n }\n },\n};\n","import { exec } from 'node:child_process';\nimport type { Tool, ToolResult } from './types.js';\n\nconst DEFAULT_TIMEOUT = 120_000; // 2 minutes\nconst IS_WIN = process.platform === 'win32';\n\n/**\n * Windows cmd.exe 默认用系统代码页(如 GBK/CP936)输出,\n * 需要先以 buffer 读取再用正确编码解码,否则中文乱码。\n */\nfunction decodeBuffer(buf: Buffer): string {\n if (!IS_WIN) return buf.toString('utf-8');\n try {\n // Node.js 不原生支持 GBK,优先尝试 TextDecoder\n const decoder = new TextDecoder('gbk');\n return decoder.decode(buf);\n } catch {\n return buf.toString('utf-8');\n }\n}\n\nexport const bashTool: Tool = {\n name: 'bash',\n description: IS_WIN\n ? '执行系统命令(shell: cmd.exe)。用于运行构建、测试、git 等。Windows 环境请使用 Windows 命令(dir、type、copy)或 Python 跨平台命令,不要使用 Unix 命令(ls、cat、cp)。不要用 bash 做文件读写(用 read-file/edit-file/write-file)或搜索(用 glob/grep)。'\n : '执行 shell 命令(shell: /bin/bash)。用于运行构建、测试、git 操作等系统命令。不要用 bash 做文件读写(用 read-file/edit-file/write-file)或搜索(用 glob/grep)。',\n parameters: {\n type: 'object',\n properties: {\n command: {\n type: 'string',\n description: '要执行的 shell 命令',\n },\n timeout: {\n type: 'number',\n description: '超时时间(毫秒),默认 120000',\n },\n },\n required: ['command'],\n },\n permissionLevel: 'confirm',\n\n async execute(params: Record<string, unknown>): Promise<ToolResult> {\n const command = params['command'] as string;\n const timeout = (params['timeout'] as number) || DEFAULT_TIMEOUT;\n\n return new Promise<ToolResult>((resolve) => {\n exec(\n command,\n {\n cwd: process.cwd(),\n timeout,\n maxBuffer: 1024 * 1024 * 10, // 10MB\n shell: process.platform === 'win32' ? 'cmd.exe' : '/bin/bash',\n encoding: 'buffer',\n },\n (error, stdoutBuf, stderrBuf) => {\n const stdout = stdoutBuf ? decodeBuffer(stdoutBuf) : '';\n const stderr = stderrBuf ? decodeBuffer(stderrBuf) : '';\n\n let output = '';\n if (stdout) output += stdout;\n if (stderr) output += (output ? '\\n' : '') + `[stderr]\\n${stderr}`;\n if (error && error.killed) {\n output += `\\n[命令超时,已终止]`;\n } else if (error && !stdout && !stderr) {\n output = `命令执行失败:${error.message}`;\n }\n\n resolve({ content: output || '(无输出)' });\n },\n );\n });\n },\n};\n","import { glob as globFn } from 'glob';\nimport type { Tool, ToolResult } from './types.js';\n\nexport const globTool: Tool = {\n name: 'glob',\n description: '按 glob 模式搜索文件路径。用于查找文件位置,如 \"**/*.ts\"、\"src/**/config.*\"。自动忽略 node_modules 和 .git。',\n parameters: {\n type: 'object',\n properties: {\n pattern: {\n type: 'string',\n description: 'Glob 模式,如 \"**/*.ts\"、\"src/**/*.js\"',\n },\n cwd: {\n type: 'string',\n description: '搜索的根目录,默认为工作目录',\n },\n },\n required: ['pattern'],\n },\n permissionLevel: 'auto',\n\n async execute(params: Record<string, unknown>): Promise<ToolResult> {\n const pattern = params['pattern'] as string;\n const cwd = (params['cwd'] as string) || process.cwd();\n\n try {\n const files = await globFn(pattern, {\n cwd,\n nodir: true,\n dot: false,\n ignore: ['**/node_modules/**', '**/.git/**'],\n });\n\n if (files.length === 0) {\n return { content: '未找到匹配的文件' };\n }\n\n return { content: files.join('\\n') };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return { content: `搜索失败:${msg}` };\n }\n },\n};\n","import { exec } from 'node:child_process';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport type { Tool, ToolResult } from './types.js';\n\n/**\n * 纯 JS 实现的 grep,不依赖外部命令\n */\nasync function jsGrep(\n pattern: string,\n searchPath: string,\n options: { ignoreCase?: boolean; maxResults?: number; glob?: string },\n): Promise<string[]> {\n const regex = new RegExp(pattern, options.ignoreCase ? 'i' : '');\n const results: string[] = [];\n const maxResults = options.maxResults ?? 200;\n\n async function searchFile(filePath: string) {\n if (results.length >= maxResults) return;\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n const lines = content.split('\\n');\n for (let i = 0; i < lines.length; i++) {\n if (results.length >= maxResults) break;\n if (regex.test(lines[i]!)) {\n results.push(`${filePath}:${i + 1}: ${lines[i]}`);\n }\n }\n } catch {\n // 跳过无法读取的文件\n }\n }\n\n async function searchDir(dirPath: string) {\n if (results.length >= maxResults) return;\n try {\n const entries = await fs.readdir(dirPath, { withFileTypes: true });\n for (const entry of entries) {\n if (results.length >= maxResults) break;\n const fullPath = path.join(dirPath, entry.name);\n\n // 跳过常见无关目录\n if (entry.isDirectory()) {\n if (['node_modules', '.git', 'dist', '.next', '__pycache__'].includes(entry.name)) {\n continue;\n }\n await searchDir(fullPath);\n } else if (entry.isFile()) {\n // 简单过滤二进制文件\n const ext = path.extname(entry.name).toLowerCase();\n const textExts = [\n '.ts', '.tsx', '.js', '.jsx', '.json', '.md', '.txt', '.yaml', '.yml',\n '.toml', '.css', '.scss', '.html', '.vue', '.svelte', '.py', '.go',\n '.rs', '.java', '.c', '.cpp', '.h', '.hpp', '.rb', '.php', '.sh',\n '.bash', '.zsh', '.fish', '.sql', '.xml', '.svg', '.env', '.gitignore',\n '.editorconfig', '.prettierrc', '.eslintrc',\n ];\n if (ext && !textExts.includes(ext)) continue;\n await searchFile(fullPath);\n }\n }\n } catch {\n // 跳过无法访问的目录\n }\n }\n\n const stat = await fs.stat(searchPath);\n if (stat.isFile()) {\n await searchFile(searchPath);\n } else {\n await searchDir(searchPath);\n }\n\n return results;\n}\n\nexport const grepTool: Tool = {\n name: 'grep',\n description: '在文件内容中搜索正则表达式。用于查找函数定义、类引用、特定代码模式。返回匹配的文件路径、行号和内容。',\n parameters: {\n type: 'object',\n properties: {\n pattern: {\n type: 'string',\n description: '正则表达式搜索模式',\n },\n path: {\n type: 'string',\n description: '搜索的文件或目录路径,默认为工作目录',\n },\n ignore_case: {\n type: 'boolean',\n description: '是否忽略大小写',\n },\n },\n required: ['pattern'],\n },\n permissionLevel: 'auto',\n\n async execute(params: Record<string, unknown>): Promise<ToolResult> {\n const pattern = params['pattern'] as string;\n const searchPath = (params['path'] as string) || process.cwd();\n const ignoreCase = (params['ignore_case'] as boolean) ?? false;\n\n try {\n const resolvedPath = path.resolve(searchPath);\n const results = await jsGrep(pattern, resolvedPath, {\n ignoreCase,\n maxResults: 200,\n });\n\n if (results.length === 0) {\n return { content: '未找到匹配内容' };\n }\n\n return { content: results.join('\\n') };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return { content: `搜索失败:${msg}` };\n }\n },\n};\n","import { ToolRegistry } from '../tools/registry.js';\nimport { readFileTool } from '../tools/read-file.js';\nimport { writeFileTool } from '../tools/write-file.js';\nimport { editFileTool } from '../tools/edit-file.js';\nimport { bashTool } from '../tools/bash.js';\nimport { globTool } from '../tools/glob.js';\nimport { grepTool } from '../tools/grep.js';\n\n/**\n * 注册所有核心工具\n */\nexport function registerCoreTools(registry: ToolRegistry): void {\n registry.register(readFileTool);\n registry.register(writeFileTool);\n registry.register(editFileTool);\n registry.register(bashTool);\n registry.register(globTool);\n registry.register(grepTool);\n}\n","import chalk from 'chalk';\n\n/**\n * 确认处理函数类型\n * 接收提示文本,返回用户是否同意\n */\nexport type ConfirmHandler = (prompt: string) => Promise<boolean>;\n\n/**\n * 结构化确认结果\n */\nexport interface ConfirmExecutionResult {\n approved: boolean;\n feedback?: string;\n}\n\n/**\n * 结构化确认处理函数类型\n * 接收工具名和参数,返回确认结果(含可选反馈)\n * 用于 TUI 模式,避免 chalk 格式化字符串\n */\nexport type StructuredConfirmHandler = (\n toolName: string,\n params: Record<string, unknown>,\n) => Promise<ConfirmExecutionResult>;\n\n/**\n * 全局确认处理函数(由 REPL 注入)\n * 默认实现:自动拒绝(安全兜底)\n */\nlet globalConfirmHandler: ConfirmHandler = async () => false;\n\n/**\n * 结构化确认处理函数(由 TUI 注入)\n * 当设置时,confirmExecution 优先使用此 handler,跳过 stderr 输出\n */\nlet structuredConfirmHandler: StructuredConfirmHandler | null = null;\n\n/**\n * 正在等待确认的 Promise resolve 函数\n */\nlet pendingConfirmResolver: ((result: ConfirmExecutionResult) => void) | null = null;\n\n/**\n * 设置全局确认处理函数\n */\nexport function setConfirmHandler(handler: ConfirmHandler): void {\n globalConfirmHandler = handler;\n}\n\n/**\n * 强行取消当前正在等待的工具确认(通常用于 Ctrl+C 中断)\n */\nexport function cancelPendingConfirmation(): void {\n if (pendingConfirmResolver) {\n pendingConfirmResolver({ approved: false });\n pendingConfirmResolver = null;\n }\n}\n\n/**\n * 设置结构化确认处理函数(TUI 模式使用)\n * 当设置后,confirmExecution 将直接传递 toolName 和 params,\n * 而不是格式化为 chalk 字符串输出到 stderr\n */\nexport function setStructuredConfirmHandler(handler: StructuredConfirmHandler | null): void {\n structuredConfirmHandler = handler;\n}\n\n/**\n * 格式化工具调用的详细信息\n */\nfunction formatToolDetail(toolName: string, params: Record<string, unknown>): string {\n const lines: string[] = [];\n\n switch (toolName) {\n case 'bash':\n lines.push(` ${chalk.dim('命令:')} ${chalk.white(String(params['command'] || ''))}`);\n break;\n case 'write-file':\n lines.push(` ${chalk.dim('文件:')} ${chalk.white(String(params['path'] || ''))}`);\n if (params['content']) {\n const content = String(params['content']);\n const preview = content.length > 200 ? content.slice(0, 200) + '...' : content;\n lines.push(` ${chalk.dim('内容:')} ${chalk.gray(preview.split('\\n').join('\\n '))}`);\n }\n break;\n case 'edit-file':\n lines.push(` ${chalk.dim('文件:')} ${chalk.white(String(params['path'] || ''))}`);\n if (params['old_string']) {\n const old = String(params['old_string']);\n const preview = old.length > 100 ? old.slice(0, 100) + '...' : old;\n lines.push(` ${chalk.dim('替换:')} ${chalk.red(preview)}`);\n }\n if (params['new_string']) {\n const neu = String(params['new_string']);\n const preview = neu.length > 100 ? neu.slice(0, 100) + '...' : neu;\n lines.push(` ${chalk.dim('为 :')} ${chalk.green(preview)}`);\n }\n break;\n case 'git':\n lines.push(` ${chalk.dim('命令:')} git ${chalk.white(String(params['command'] || ''))}`);\n break;\n default:\n for (const [key, value] of Object.entries(params)) {\n const str = typeof value === 'string' ? value : JSON.stringify(value);\n lines.push(` ${chalk.dim(key + ':')} ${str.slice(0, 120)}`);\n }\n break;\n }\n\n return lines.join('\\n');\n}\n\n/**\n * 向用户确认是否执行危险操作\n */\nexport async function confirmExecution(\n toolName: string,\n params: Record<string, unknown>,\n): Promise<ConfirmExecutionResult> {\n // TUI 模式:使用结构化 handler,跳过 stderr 输出\n if (structuredConfirmHandler) {\n const result = await new Promise<ConfirmExecutionResult>((resolve) => {\n pendingConfirmResolver = resolve;\n structuredConfirmHandler!(toolName, params).then(res => {\n if (pendingConfirmResolver === resolve) {\n pendingConfirmResolver = null;\n resolve(res);\n }\n });\n });\n return result;\n }\n\n // REPL 模式:格式化并输出到 stderr\n const detail = formatToolDetail(toolName, params);\n const prompt = `\\n${chalk.yellow('⚠')} ${chalk.bold('需要确认')} ${chalk.cyan(`[${toolName}]`)}\\n${detail}\\n`;\n\n process.stderr.write(prompt);\n const approved = await globalConfirmHandler(`${chalk.yellow('?')} 是否执行?(${chalk.green('y')}/${chalk.red('N')}) `);\n return { approved };\n}\n","import type { Message } from '../llm/types.js';\n\n/**\n * 对话历史管理\n */\nexport class Conversation {\n private messages: Message[] = [];\n private systemPrompt: string = '';\n\n setSystemPrompt(prompt: string): void {\n this.systemPrompt = prompt;\n }\n\n addMessage(message: Message): void {\n this.messages.push(message);\n }\n\n addUserMessage(content: string): void {\n this.messages.push({ role: 'user', content });\n }\n\n addAssistantMessage(message: Message): void {\n this.messages.push(message);\n }\n\n addToolResult(toolCallId: string, content: string): void {\n this.messages.push({\n role: 'tool',\n tool_call_id: toolCallId,\n content,\n });\n }\n\n /**\n * 清除历史消息中的 reasoning_content(新一轮对话开始时调用)\n * deepseek-reasoner 要求同一轮 tool call 循环内保留 reasoning_content,\n * 但新一轮用户问题开始时应清除以节省带宽,API 也会忽略旧的 reasoning_content\n */\n clearReasoningContent(): void {\n for (const msg of this.messages) {\n if (msg.reasoning_content !== undefined) {\n msg.reasoning_content = undefined;\n }\n }\n }\n\n /**\n * 获取完整的消息列表(包含系统提示词)\n */\n getMessages(): Message[] {\n const result: Message[] = [];\n if (this.systemPrompt) {\n result.push({ role: 'system', content: this.systemPrompt });\n }\n result.push(...this.messages);\n return result;\n }\n\n /**\n * 获取不含系统提示词的历史消息\n */\n getHistory(): Message[] {\n return [...this.messages];\n }\n\n /**\n * 清空对话历史(保留系统提示词)\n */\n clear(): void {\n this.messages = [];\n }\n\n /**\n * 获取消息数量\n */\n get length(): number {\n return this.messages.length;\n }\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\n/**\n * 跟踪当前 Agent 会话中已读取的文件路径\n *\n * 用于强制执行\"先读后改\"规则:\n * - read-file 成功后标记为已读\n * - write-file 成功后标记为已读(agent 刚写入,知道内容)\n * - edit-file 调用前检查是否已读,未读则拒绝并提示\n *\n * 同时提供 write-file 覆盖检查:\n * - 文件已存在且未传 overwrite: true → 返回警告\n */\nexport class ReadTracker {\n private files = new Set<string>();\n\n /** 标记文件已被读取 */\n markRead(filePath: string): void {\n this.files.add(this.normalize(filePath));\n }\n\n /** 标记文件已被写入(新建/重写,agent 已知内容) */\n markWritten(filePath: string): void {\n this.files.add(this.normalize(filePath));\n }\n\n /** 检查文件是否已读取 */\n hasRead(filePath: string): boolean {\n return this.files.has(this.normalize(filePath));\n }\n\n /**\n * 检查 write-file 是否会覆盖已有文件\n * @returns 警告消息(需要拦截),或 null(可以继续执行)\n */\n checkWriteOverwrite(filePath: string, overwrite?: boolean): string | null {\n const resolved = path.resolve(filePath);\n if (!overwrite && fs.existsSync(resolved)) {\n return `⚠ 文件已存在:${filePath}\\n修改已有文件请用 read-file + edit-file(更精确安全)。\\n如确需完整重写,请重新调用 write-file 并设置 overwrite: true。`;\n }\n return null;\n }\n\n private normalize(filePath: string): string {\n return filePath.replace(/\\\\/g, '/').replace(/^\\.\\//, '');\n }\n}\n","import type { ZenCodeConfig } from '../config/types.js';\nimport type { Message, ToolDefinition } from '../llm/types.js';\nimport type { LLMClient, StreamCallbacks } from '../llm/client.js';\nimport type { ToolRegistry } from '../tools/registry.js';\nimport { confirmExecution } from '../tools/permission.js';\nimport { Conversation } from './conversation.js';\nimport { ReadTracker } from './read-tracker.js';\n\nexport interface AgentCallbacks extends StreamCallbacks {\n onToolExecuting?: (toolName: string, params: Record<string, unknown>) => void;\n onToolResult?: (toolName: string, result: string, truncated: boolean) => void;\n onDenied?: (toolName: string, feedback?: string) => void;\n}\n\n/**\n * 单 Agent 循环\n *\n * 消息流程:\n * 用户输入 → 构建消息 → LLM (带tools) → 处理响应\n * ├─ 含工具调用 → 执行工具 → 结果加入历史 → 回到 LLM\n * └─ 纯文本响应 → 返回\n */\nexport class Agent {\n private conversation: Conversation;\n private client: LLMClient;\n private registry: ToolRegistry;\n private config: ZenCodeConfig;\n private fixedTools?: ToolDefinition[];\n private readTracker = new ReadTracker();\n private interrupted = false;\n\n constructor(\n client: LLMClient,\n registry: ToolRegistry,\n config: ZenCodeConfig,\n systemPrompt: string,\n tools?: ToolDefinition[],\n ) {\n this.client = client;\n this.registry = registry;\n this.config = config;\n this.conversation = new Conversation();\n this.conversation.setSystemPrompt(systemPrompt);\n this.fixedTools = tools;\n }\n\n /**\n * 执行一轮完整的 agent 循环\n */\n async run(userMessage: string, callbacks: AgentCallbacks = {}): Promise<string> {\n this.interrupted = false;\n // 新一轮对话:清除历史中的 reasoning_content(deepseek-reasoner 兼容)\n this.conversation.clearReasoningContent();\n this.conversation.addUserMessage(userMessage);\n\n let lastContent = '';\n\n while (true) {\n if (this.interrupted) break;\n // 每轮动态获取工具列表,确保 /parallel /todo 等切换生效\n const tools = this.fixedTools || this.registry.toToolDefinitions();\n\n // 调用 LLM\n const assistantMsg = await this.client.chatStream(\n this.conversation.getMessages(),\n tools.length > 0 ? tools : undefined,\n callbacks,\n );\n\n // 过滤并处理工具调用\n const validToolCalls: typeof assistantMsg.tool_calls = [];\n const invalidToolCalls: typeof assistantMsg.tool_calls = [];\n if (assistantMsg.tool_calls) {\n for (const toolCall of assistantMsg.tool_calls) {\n try {\n JSON.parse(toolCall.function.arguments);\n validToolCalls.push(toolCall);\n } catch {\n invalidToolCalls.push(toolCall);\n }\n }\n }\n\n // 更新消息中的工具调用为仅包含合法 JSON 的调用,避免后续请求 400 错误\n assistantMsg.tool_calls = validToolCalls.length > 0 ? validToolCalls : undefined;\n this.conversation.addAssistantMessage(assistantMsg);\n\n // 对于无效的工具调用,通知 UI 显示错误,但不加入对话历史\n for (const toolCall of invalidToolCalls) {\n callbacks.onToolResult?.(toolCall.function.name, `参数解析失败:无效的 JSON 字符串\\n${toolCall.function.arguments}`, false);\n }\n\n // 如果没有有效的工具调用,结束循环\n if (validToolCalls.length === 0) {\n lastContent = assistantMsg.content || '';\n break;\n }\n\n // 执行所有有效的工具调用\n for (const toolCall of validToolCalls) {\n if (this.interrupted) break;\n const toolName = toolCall.function.name;\n // 此时 JSON.parse 必然成功\n const params: Record<string, unknown> = JSON.parse(toolCall.function.arguments);\n\n try {\n // 先读后改:edit-file 必须先 read-file\n if (toolName === 'edit-file') {\n const editPath = params['path'] as string;\n if (!this.readTracker.hasRead(editPath)) {\n this.conversation.addToolResult(toolCall.id,\n `⚠ 禁止编辑未读取的文件。请先 read-file \"${editPath}\" 了解当前内容,再 edit-file。`);\n continue;\n }\n }\n\n // write-file 覆盖检查:文件已存在时需要 overwrite: true\n if (toolName === 'write-file') {\n const warn = this.readTracker.checkWriteOverwrite(\n params['path'] as string,\n params['overwrite'] as boolean | undefined,\n );\n if (warn) {\n this.conversation.addToolResult(toolCall.id, warn);\n continue;\n }\n }\n\n // 权限检查\n const permLevel = this.registry.getPermissionLevel(toolName);\n if (permLevel === 'deny') {\n callbacks.onDenied?.(toolName);\n this.conversation.addToolResult(toolCall.id, `工具 \"${toolName}\" 已被禁止执行`);\n continue;\n }\n\n // 自动执行的工具直接显示并执行\n if (permLevel === 'auto') {\n callbacks.onToolExecuting?.(toolName, params);\n }\n\n if (permLevel === 'confirm') {\n const confirmResult = await confirmExecution(toolName, params);\n if (!confirmResult.approved) {\n callbacks.onDenied?.(toolName, confirmResult.feedback);\n const denyMsg = confirmResult.feedback\n ? `用户拒绝了此操作,用户反馈: ${confirmResult.feedback}`\n : '用户拒绝了此操作';\n this.conversation.addToolResult(toolCall.id, denyMsg);\n continue;\n }\n }\n\n // 执行工具\n const result = await this.registry.execute(toolName, params, this.config.max_tool_output);\n callbacks.onToolResult?.(toolName, result.content, result.truncated ?? false);\n\n // 跟踪已读/已写文件\n if (toolName === 'read-file') {\n this.readTracker.markRead(params['path'] as string);\n } else if (toolName === 'write-file') {\n this.readTracker.markWritten(params['path'] as string);\n }\n\n this.conversation.addToolResult(toolCall.id, result.content);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.conversation.addToolResult(toolCall.id, `工具执行异常:${msg}`);\n }\n }\n\n // 记录最后的文本内容\n if (assistantMsg.content) {\n lastContent = assistantMsg.content;\n }\n }\n\n return lastContent;\n }\n\n interrupt(): void {\n this.interrupted = true;\n this.client.abortActiveStream();\n }\n\n /**\n * 获取对话历史\n */\n getConversation(): Conversation {\n return this.conversation;\n }\n}\n","import * as os from 'node:os';\n\nconst IS_WIN = os.platform() === 'win32';\n\n/**\n * Layer 0 - 核心层(始终加载)\n */\nexport function buildCorePrompt(): string {\n const shellInfo = IS_WIN\n ? 'cmd.exe(Windows)。请使用 Windows 命令(dir、type、copy 等)或 Python 跨平台命令(python -c \"...\"),不要使用 Unix 命令(ls、cat、cp 等)'\n : '/bin/bash';\n\n return `你是 ZenCode,一个 CLI 环境下的 AI 编程助手。你帮助用户完成软件工程任务:修bug、加功能、重构代码、解释代码等。\n\n工作目录:${process.cwd()}\n系统:${os.platform()} ${os.arch()}\n\n# 工具使用原则\n\n你有以下工具可用,请根据任务选择最合适的工具:\n\n- **read-file**:读取文件内容。修改代码前必须先读取目标文件。支持 offset/limit 读取大文件的特定部分。\n- **edit-file**:通过字符串替换编辑文件。优先使用 edit-file 而非 write-file 修改已有文件——它更精确、更安全。\n - ⚠️ 系统强制:未用 read-file 读取过的文件无法 edit-file,会被拦截\n - old_string 必须与文件中的内容**完全一致**(包括缩进、空格、换行符)\n - old_string 不唯一时,包含更多上下文行(建议 3-5 行)使其唯一\n - 不要凭记忆猜测文件内容,必须基于 read-file 的实际返回值\n- **write-file**:创建新文件或完整重写文件。仅在创建新文件或需要大幅重写时使用。\n- **glob**:按模式搜索文件路径。用于查找文件位置(如 \\`**/*.ts\\`、\\`src/**/config.*\\`)。\n- **grep**:在文件内容中搜索正则表达式。用于查找函数定义、引用、特定代码模式。\n- **bash**:执行系统命令,当前 shell:${shellInfo}。用于运行构建、测试、git 操作等。不要用 bash 做能用上述工具完成的事(文件读写用 read-file/edit-file/write-file,搜索用 glob/grep)。\n\n关键规则:\n- **先读后改**:修改文件前必须 read-file 读取该文件(系统会拦截未读取就 edit 的操作)\n- edit-file 的 old_string 必须从 read-file 返回的内容中精确复制,不要手动输入或凭记忆\n- 优先 edit-file 编辑已有文件,而非 write-file 重写\n- 不要创建不必要的新文件,优先在现有文件中修改\n- 只做必要的最小改动,不做额外\"改进\"\n- 不要添加用户未要求的注释、文档、类型注解\n- 不要引入安全漏洞(注入、XSS、SQL 注入等 OWASP Top 10)\n- 引用代码时使用 \\`文件路径:行号\\` 格式(如 \\`src/app.ts:42\\`),方便用户跳转\n- 绝对禁止使用 \\`// ... existing code\\`、\\`// TODO\\` 或任何形式的省略占位符。必须提供完整且可运行的代码。\n- 永远不要假设某个第三方库已安装。在使用任何非 Node.js 内置模块前,必须确认其在项目中已配置。\n\n# 交互风格\n\n- 保持技术客观性,基于事实回答,不过度赞同或恭维用户,必要时直接指出问题\n- 不确定时先调查验证,而非直觉性地确认用户的假设\n- 不要给出时间预估(\"大概需要几分钟\"之类)\n- 回复简洁,直接给结果`;\n}\n","/**\n * Layer 1 - 工作方法层(默认开启)\n */\nexport function buildPlanningPrompt(): string {\n return `# 工作方法\n\n处理编程任务时:\n1. 先用 read-file / grep / glob 阅读相关代码,理解现有逻辑和上下文\n2. 判断任务的复杂程度,简单任务直接执行,复杂任务先做计划\n3. 如果用户的要求不清晰,一定要询问用户,确定细节\n\n多步任务管理:\n- 对于 3 个以上步骤的任务,使用 todo 工具创建计划再逐步执行\n- 开始步骤前标记 in-progress,完成后标记 completed\n- 每步完成后检查计划,决定下一步\n\n代码质量:\n- 如果删除了代码,就彻底删除,不要留注释说\"已移除\",不要保留未使用的兼容性变量\n- 不要留下TODO然后放着不管\n- 执行修改后必须进行闭环验证。主动检查代码逻辑,或使用 bash 运行构建、Lint 等命令确保修改没有引入错误`;\n}\n\n","/**\n * Layer - 并行子 Agent 提示词层\n *\n * 核心原则:让\"并行\"成为默认行为,而非可选项。\n * LLM 天然倾向串行调用工具,必须用强指令扭转这一惯性。\n */\nexport function buildParallelPrompt(): string {\n return `# 并行执行(重要)\n\n当需要读取、搜索或分析 2 个以上独立目标时,必须使用 spawn-agents 并行执行,不要逐个串行调用。\n\n规则:\n- 需要读 2+ 个文件 → spawn-agents 并行读取\n- 需要搜索 2+ 个模式 → spawn-agents 并行搜索\n- 需要了解 2+ 个模块 → spawn-agents 并行分析\n- 只有 1 个目标 → 直接用工具,无需 spawn-agents\n- 必须为每个子 Agent 分配明确且无重叠的目标,避免多个 Agent 重复处理同一对象造成浪费\n\n示例 - 用户说\"帮我理解认证模块\":\n 正确:spawn-agents 同时读 auth controller、auth service、auth middleware、auth types\n 错误:先 read-file controller,再 read-file service,再 read-file middleware...\n\n每个子 Agent 有独立对话,默认可用 read-file、glob、grep。`;\n}\n","/**\n * Layer 2 - Git 层(检测到 .git 时加载)\n */\nexport function buildGitPrompt(): string {\n return `# Git 操作\n\n当前项目使用 git 管理。\n\n提交规范:\n- 只在用户明确要求时才创建 commit\n- 提交前必须用 git status 和 git diff --staged 检查即将提交的内容,确保没有混入不相关文件或调试代码\n- 建议遵循 Conventional Commits 规范(如 feat: ..., fix: ...)\n- commit message 描述\"为什么\"而非\"改了什么\"\n\n安全规则:\n- 不要 force push、reset --hard、checkout .、clean -f 等破坏性操作,除非用户明确要求\n- 不要 --no-verify 跳过 hook,除非用户明确要求\n- 优先创建新 commit,不要 --amend 修改已有 commit,除非用户明确要求(hook 失败后 amend 会破坏上一个 commit)\n- git add 时指定具体文件,避免 git add -A 意外暂存敏感文件(.env、credentials 等)\n- 不要使用交互式标志(git rebase -i、git add -i),CLI 环境不支持\n- 不要修改 git config`;\n}\n","import type { SubAgentConfig } from '../../sub-agents/types.js';\n\n/**\n * Layer - 子 Agent 提示词层\n *\n * 当有可用子 Agent 时注入,告诉模型何时使用 dispatch。\n */\nexport function buildAgentsPrompt(agents: SubAgentConfig[]): string | null {\n if (agents.length === 0) return null;\n\n const agentList = agents\n .map(a => `- **${a.name}**:${a.description}`)\n .join('\\n');\n\n return `# 子 Agent\n\n你可以通过 dispatch 工具调度以下专用子 Agent:\n\n${agentList}\n\n使用场景:当任务需要专业角色(如代码审查、架构分析)且子 Agent 的能力比你直接做更合适时,使用 dispatch 委派。`;\n}\n","import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\n\n/**\n * Layer 3 - 项目层(从 ZENCODE.md 加载)\n */\nexport async function buildProjectPrompt(): Promise<string | null> {\n try {\n const content = await fs.readFile(path.resolve('ZENCODE.md'), 'utf-8');\n return content.trim() || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Layer 4 - 用户自定义提示词(从指定路径加载)\n */\nexport async function loadUserPrompts(paths: string[]): Promise<string[]> {\n const prompts: string[] = [];\n for (const p of paths) {\n try {\n const resolved = p.startsWith('~')\n ? path.join(process.env['HOME'] || process.env['USERPROFILE'] || '', p.slice(1))\n : path.resolve(p);\n const content = await fs.readFile(resolved, 'utf-8');\n if (content.trim()) {\n prompts.push(content.trim());\n }\n } catch {\n // 跳过不存在的文件\n }\n }\n return prompts;\n}\n","import * as fs from 'node:fs';\nimport type { ZenCodeConfig } from '../../config/types.js';\nimport type { SubAgentConfig } from '../sub-agents/types.js';\nimport { buildCorePrompt } from './layers/core.js';\nimport { buildPlanningPrompt } from './layers/planning.js';\nimport { buildParallelPrompt } from './layers/parallel.js';\nimport { buildGitPrompt } from './layers/git.js';\nimport { buildAgentsPrompt } from './layers/agents.js';\nimport { buildProjectPrompt, loadUserPrompts } from './layers/project.js';\n\nexport interface PromptBuildResult {\n systemPrompt: string;\n layers: string[];\n}\n\n/**\n * 检测当前目录是否为 git 仓库\n */\nfunction isGitRepo(): boolean {\n try {\n fs.statSync('.git');\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * 分层提示词构建器 - 按需组装各层\n */\nexport async function buildPrompt(config: ZenCodeConfig, agents?: SubAgentConfig[]): Promise<PromptBuildResult> {\n const layers: string[] = [];\n\n // Layer 0: 核心层(始终加载)\n layers.push(buildCorePrompt());\n\n // Layer 1: 思考层(默认开启)\n if (config.features.planning_layer === 'on') {\n layers.push(buildPlanningPrompt());\n }\n\n // Layer 2: Git 层(自动检测或手动开启)\n const gitEnabled =\n config.features.git === 'on' ||\n (config.features.git === 'auto' && isGitRepo());\n if (gitEnabled) {\n layers.push(buildGitPrompt());\n }\n\n // Layer 3: 并行子 Agent 层\n if (config.features.parallel_agents === 'on') {\n layers.push(buildParallelPrompt());\n }\n\n // Layer 4: 子 Agent 层(有可用 agent 时加载)\n if (agents && agents.length > 0) {\n const agentsPrompt = buildAgentsPrompt(agents);\n if (agentsPrompt) {\n layers.push(agentsPrompt);\n }\n }\n\n // Layer 5: 项目层(ZENCODE.md)\n const projectPrompt = await buildProjectPrompt();\n if (projectPrompt) {\n layers.push(projectPrompt);\n }\n\n // Layer 6: 用户自定义提示词\n if (config.prompts.length > 0) {\n const userPrompts = await loadUserPrompts(config.prompts);\n layers.push(...userPrompts);\n }\n\n // 合并所有层\n const systemPrompt = layers.join('\\n\\n');\n\n return { systemPrompt, layers };\n}\n\n","export interface TodoItem {\n id: string;\n title: string;\n status: 'pending' | 'in-progress' | 'completed';\n}\n\nexport interface TodoPlan {\n items: TodoItem[];\n}\n\ntype TodoListener = (plan: TodoPlan | null) => void;\n\n/**\n * Todo 状态存储(可观察)\n *\n * LLM 通过 todo 工具操作,TUI 订阅变化实时渲染面板\n */\nexport class TodoStore {\n private plan: TodoPlan | null = null;\n private listeners = new Set<TodoListener>();\n\n create(items: { id: string; title: string }[]): TodoPlan {\n this.plan = {\n items: items.map((item) => ({\n id: item.id,\n title: item.title,\n status: 'pending' as const,\n })),\n };\n this.notify();\n return this.plan;\n }\n\n update(id: string, status: TodoItem['status']): TodoItem | null {\n if (!this.plan) return null;\n const item = this.plan.items.find((i) => i.id === id);\n if (!item) return null;\n item.status = status;\n this.notify();\n return { ...item };\n }\n\n list(): TodoPlan | null {\n return this.plan;\n }\n\n clear(): void {\n this.plan = null;\n this.notify();\n }\n\n subscribe(listener: TodoListener): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n private notify(): void {\n const snapshot = this.plan\n ? { items: this.plan.items.map((i) => ({ ...i })) }\n : null;\n for (const listener of this.listeners) {\n listener(snapshot);\n }\n }\n}\n","import type { SubAgentConfig } from './types.js';\n\n/**\n * 子 Agent 配置注册表\n */\nexport class SubAgentConfigRegistry {\n private configs = new Map<string, SubAgentConfig>();\n\n register(config: SubAgentConfig): void {\n this.configs.set(config.name, config);\n }\n\n get(name: string): SubAgentConfig | undefined {\n return this.configs.get(name);\n }\n\n has(name: string): boolean {\n return this.configs.has(name);\n }\n\n list(): SubAgentConfig[] {\n return [...this.configs.values()];\n }\n\n listNames(): string[] {\n return [...this.configs.keys()];\n }\n\n /**\n * 生成子 Agent 列表描述(用于 dispatch 工具的说明)\n */\n buildAgentListDescription(): string {\n if (this.configs.size === 0) return '暂无可用子 Agent';\n return [...this.configs.values()]\n .map(s => `- ${s.name}: ${s.description}`)\n .join('\\n');\n }\n}\n","import type { SubAgentConfig } from './types.js';\n\n/**\n * 内置预置子 Agent\n *\n * 优先级最低,可被全局/项目 YAML 同名配置覆盖。\n */\nexport const presetAgents: SubAgentConfig[] = [\n {\n name: 'reviewer',\n description: '代码审查:发现 bug、安全漏洞、性能问题',\n prompt: `你是代码审查专家。审查用户指定的代码,输出发现的问题。\n\n审查维度(按优先级):\n1. 正确性:逻辑错误、边界条件、空值/未定义处理\n2. 安全:注入、XSS、敏感信息泄露、权限检查\n3. 性能:不必要的循环、内存泄漏、N+1 查询\n4. 可维护性:命名、重复代码、过度复杂\n\n输出格式:\n- 每个问题:文件路径:行号 + 问题描述 + 建议修复\n- 没有问题就说没有问题,不要硬凑\n- 不要重写代码,只指出问题和修复方向`,\n tools: ['read-file', 'glob', 'grep'],\n max_turns: 10,\n timeout: 60,\n },\n {\n name: 'researcher',\n description: '代码库研究:深度分析架构、依赖和实现细节',\n prompt: `你是代码库研究员。深入分析用户指定的代码库或模块,输出结构化的分析报告。\n\n分析方法:\n1. 先 glob 了解文件结构\n2. grep 搜索关键入口点、导出、依赖\n3. read-file 阅读核心文件\n\n输出内容:\n- 模块职责和边界\n- 关键文件及其作用\n- 数据流和调用链\n- 外部依赖\n- 如有用户具体问题,针对性回答`,\n tools: ['read-file', 'glob', 'grep'],\n max_turns: 15,\n timeout: 120,\n },\n {\n name: 'refactor',\n description: '重构专家:分析代码结构并实施重构',\n prompt: `你是重构专家。分析用户指定的代码,找出可重构的点并实施重构。\n\n重构原则:\n- 只做有明确收益的重构(消除重复、降低复杂度、改善命名)\n- 保持行为不变,不添加新功能\n- 每次只做一个重构,不要同时改太多\n- 修改前必须 read-file 确认当前内容\n\n常见重构:\n- 提取重复代码为函数\n- 简化过深的嵌套(提前返回)\n- 拆分过大的函数\n- 改善命名使意图更清晰`,\n tools: ['read-file', 'write-file', 'edit-file', 'glob', 'grep'],\n max_turns: 15,\n timeout: 120,\n },\n];\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\nimport { parse as parseYaml } from 'yaml';\nimport type { SubAgentConfig } from './types.js';\nimport { presetAgents } from './presets.js';\n\n/**\n * 从 YAML 文件加载单个子 Agent 配置\n */\nfunction loadAgentYaml(filePath: string): SubAgentConfig | null {\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n const parsed = parseYaml(content) as Record<string, unknown>;\n if (!parsed || typeof parsed !== 'object') return null;\n if (!parsed['name'] || !parsed['prompt'] || !parsed['tools']) return null;\n\n return {\n name: parsed['name'] as string,\n description: (parsed['description'] as string) || '',\n prompt: parsed['prompt'] as string,\n tools: parsed['tools'] as string[],\n max_turns: parsed['max_turns'] as number | undefined,\n timeout: parsed['timeout'] as number | undefined,\n model: parsed['model'] as SubAgentConfig['model'],\n };\n } catch {\n return null;\n }\n}\n\n/**\n * 从目录加载所有 YAML 子 Agent 配置\n */\nfunction loadAgentsFromDir(dir: string): SubAgentConfig[] {\n try {\n if (!fs.existsSync(dir)) return [];\n const files = fs.readdirSync(dir).filter(f => f.endsWith('.yaml') || f.endsWith('.yml'));\n const agents: SubAgentConfig[] = [];\n for (const file of files) {\n const agent = loadAgentYaml(path.join(dir, file));\n if (agent) agents.push(agent);\n }\n return agents;\n } catch {\n return [];\n }\n}\n\n/**\n * 加载所有子 Agent 配置(按优先级低→高合并)\n *\n * 1. 内置预设(代码中)\n * 2. 全局用户目录:~/.zencode/agents/*.yaml\n * 3. 项目目录:.zencode/agents/*.yaml\n *\n * 同名配置高优先级覆盖低优先级\n */\nexport function loadAllAgentConfigs(): SubAgentConfig[] {\n const configMap = new Map<string, SubAgentConfig>();\n\n // 1. 内置预置(最低优先级)\n for (const agent of presetAgents) {\n configMap.set(agent.name, agent);\n }\n\n // 2. 全局用户目录:~/.zencode/agents/*.yaml\n const globalDir = path.join(os.homedir(), '.zencode', 'agents');\n for (const agent of loadAgentsFromDir(globalDir)) {\n configMap.set(agent.name, agent);\n }\n\n // 3. 项目目录:.zencode/agents/*.yaml(最高优先级)\n const projectDir = path.resolve('.zencode', 'agents');\n for (const agent of loadAgentsFromDir(projectDir)) {\n configMap.set(agent.name, agent);\n }\n\n return [...configMap.values()];\n}\n","import type { Skill } from './types.js';\n\n/**\n * Skill 注册表 - 管理用户可调用的技能\n */\nexport class SkillRegistry {\n private skills = new Map<string, Skill>();\n\n register(skill: Skill): void {\n this.skills.set(skill.name, skill);\n }\n\n get(name: string): Skill | undefined {\n return this.skills.get(name);\n }\n\n has(name: string): boolean {\n return this.skills.has(name);\n }\n\n list(): Skill[] {\n return [...this.skills.values()];\n }\n\n listNames(): string[] {\n return [...this.skills.keys()];\n }\n\n /**\n * 展开 skill 的 prompt 模板,替换 $ARGS 为用户参数\n */\n expandPrompt(skill: Skill, args: string): string {\n if (args && skill.prompt.includes('$ARGS')) {\n return skill.prompt.replace(/\\$ARGS/g, args);\n }\n // 没有 $ARGS 占位符时,将用户参数追加到末尾\n if (args) {\n return `${skill.prompt}\\n\\n用户补充: ${args}`;\n }\n return skill.prompt;\n }\n}\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\nimport { parse as parseYaml } from 'yaml';\nimport type { Skill } from './types.js';\n\n/**\n * 从 YAML 文件加载单个 Skill\n */\nfunction loadSkillYaml(filePath: string): Skill | null {\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n const parsed = parseYaml(content) as Record<string, unknown>;\n if (!parsed || typeof parsed !== 'object') return null;\n if (!parsed['name'] || !parsed['prompt']) return null;\n\n return {\n name: parsed['name'] as string,\n description: (parsed['description'] as string) || '',\n prompt: parsed['prompt'] as string,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * 从目录加载所有 YAML Skill 文件\n */\nfunction loadSkillsFromDir(dir: string): Skill[] {\n try {\n if (!fs.existsSync(dir)) return [];\n const files = fs.readdirSync(dir).filter(f => f.endsWith('.yaml') || f.endsWith('.yml'));\n const skills: Skill[] = [];\n for (const file of files) {\n const skill = loadSkillYaml(path.join(dir, file));\n if (skill) skills.push(skill);\n }\n return skills;\n } catch {\n return [];\n }\n}\n\n/**\n * 加载所有 Skill(按优先级低→高合并)\n *\n * 1. 全局用户目录:~/.zencode/skills/*.yaml\n * 2. 项目目录:.zencode/skills/*.yaml\n *\n * 同名 skill 高优先级覆盖低优先级\n */\nexport function loadAllSkills(): Skill[] {\n const skillMap = new Map<string, Skill>();\n\n // 1. 全局用户目录\n const globalDir = path.join(os.homedir(), '.zencode', 'skills');\n for (const skill of loadSkillsFromDir(globalDir)) {\n skillMap.set(skill.name, skill);\n }\n\n // 2. 项目目录\n const projectDir = path.resolve('.zencode', 'skills');\n for (const skill of loadSkillsFromDir(projectDir)) {\n skillMap.set(skill.name, skill);\n }\n\n return [...skillMap.values()];\n}\n","import type { ZenCodeConfig } from '../config/types.js';\nimport type { LLMClient } from '../llm/client.js';\nimport type { ToolRegistry } from '../tools/registry.js';\nimport type { SubAgentTracker } from './sub-agent-tracker.js';\nimport { Conversation } from './conversation.js';\nimport { ReadTracker } from './read-tracker.js';\n\nconst DEFAULT_TIMEOUT_MS = 120_000; // 2 minutes\n\n/**\n * 轻量子 Agent - 独立对话,只读工具,非流式\n *\n * 用于并行执行多个子任务(如同时读多个文件、搜索多处代码)\n */\nexport class SubAgent {\n private client: LLMClient;\n private registry: ToolRegistry;\n private config: ZenCodeConfig;\n private task: string;\n private allowedTools: string[];\n private maxTurns: number;\n private timeoutMs: number;\n private tracker?: SubAgentTracker;\n\n constructor(\n client: LLMClient,\n registry: ToolRegistry,\n config: ZenCodeConfig,\n task: string,\n allowedTools: string[] = ['read-file', 'glob', 'grep'],\n maxTurns: number = 10,\n timeoutMs: number = DEFAULT_TIMEOUT_MS,\n tracker?: SubAgentTracker,\n ) {\n this.client = client;\n this.registry = registry;\n this.config = config;\n this.task = task;\n // 禁止递归:排除 spawn-agents 和 todo\n this.allowedTools = allowedTools.filter((t) => t !== 'spawn-agents' && t !== 'todo');\n this.maxTurns = Math.min(maxTurns, 15);\n this.timeoutMs = timeoutMs;\n this.tracker = tracker;\n }\n\n async run(): Promise<string> {\n return Promise.race([\n this.execute(),\n this.timeout(),\n ]);\n }\n\n private timeout(): Promise<never> {\n return new Promise((_, reject) => {\n setTimeout(\n () => reject(new Error(`子 Agent 超时(${this.timeoutMs / 1000}s)`)),\n this.timeoutMs,\n );\n });\n }\n\n private async execute(): Promise<string> {\n const conversation = new Conversation();\n const readTracker = new ReadTracker();\n\n const systemPrompt = `你是 ZenCode 子 Agent。你的任务:${this.task}\\n完成后直接返回结果,不要多余解释。`;\n\n conversation.setSystemPrompt(systemPrompt);\n conversation.addUserMessage(this.task);\n\n const tools = this.registry.toToolDefinitions(this.allowedTools);\n let lastContent = '';\n\n for (let turn = 0; turn < this.maxTurns; turn++) {\n const assistantMsg = await this.client.chat(\n conversation.getMessages(),\n tools.length > 0 ? tools : undefined,\n );\n\n // 报告 token 用量\n if (assistantMsg.usage && this.tracker) {\n this.tracker.addTokens(assistantMsg.usage.total_tokens);\n }\n\n conversation.addAssistantMessage(assistantMsg);\n\n if (!assistantMsg.tool_calls || assistantMsg.tool_calls.length === 0) {\n lastContent = assistantMsg.content || '';\n break;\n }\n\n for (const toolCall of assistantMsg.tool_calls) {\n const toolName = toolCall.function.name;\n\n if (!this.allowedTools.includes(toolName)) {\n conversation.addToolResult(\n toolCall.id,\n `子 Agent 不允许使用工具 \"${toolName}\"`,\n );\n continue;\n }\n\n let params: Record<string, unknown>;\n try {\n params = JSON.parse(toolCall.function.arguments);\n } catch {\n conversation.addToolResult(toolCall.id, '参数解析失败:无效的 JSON');\n continue;\n }\n\n try {\n // 先读后改:edit-file 必须先 read-file\n if (toolName === 'edit-file') {\n const editPath = params['path'] as string;\n if (!readTracker.hasRead(editPath)) {\n conversation.addToolResult(toolCall.id,\n `⚠ 禁止编辑未读取的文件。请先 read-file \"${editPath}\" 了解当前内容,再 edit-file。`);\n continue;\n }\n }\n\n // write-file 覆盖检查:文件已存在时需要 overwrite: true\n if (toolName === 'write-file') {\n const warn = readTracker.checkWriteOverwrite(\n params['path'] as string,\n params['overwrite'] as boolean | undefined,\n );\n if (warn) {\n conversation.addToolResult(toolCall.id, warn);\n continue;\n }\n }\n\n const result = await this.registry.execute(\n toolName,\n params,\n this.config.max_tool_output,\n );\n\n // 跟踪已读/已写文件\n if (toolName === 'read-file') {\n readTracker.markRead(params['path'] as string);\n } else if (toolName === 'write-file') {\n readTracker.markWritten(params['path'] as string);\n }\n\n conversation.addToolResult(toolCall.id, result.content);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n conversation.addToolResult(toolCall.id, `工具执行异常:${msg}`);\n }\n }\n\n if (assistantMsg.content) {\n lastContent = assistantMsg.content;\n }\n }\n\n return lastContent;\n }\n}\n","import type { Tool, ToolResult } from './types.js';\nimport type { LLMClient } from '../llm/client.js';\nimport type { ToolRegistry } from './registry.js';\nimport type { ZenCodeConfig } from '../config/types.js';\nimport type { SubAgentTracker } from '../core/sub-agent-tracker.js';\nimport { SubAgent } from '../core/sub-agent.js';\n\ninterface TaskInput {\n description: string;\n tools?: string[];\n}\n\nconst DEFAULT_TOOLS = ['read-file', 'glob', 'grep'];\nconst MAX_CONCURRENT = 10;\nconst MAX_TURNS_LIMIT = 15;\n\n/**\n * 创建 spawn-agents 工具 - 并行启动多个子 Agent\n */\nexport function createSpawnAgentsTool(\n client: LLMClient,\n registry: ToolRegistry,\n config: ZenCodeConfig,\n tracker?: SubAgentTracker,\n): Tool {\n return {\n name: 'spawn-agents',\n description:\n '并行启动多个子 Agent 执行任务。每个子 Agent 有独立对话,默认只能用只读工具 (read-file, glob, grep)。适用于同时读取和分析多个文件、搜索多个模式等场景。',\n parameters: {\n type: 'object',\n properties: {\n tasks: {\n type: 'array',\n description: '要并行执行的任务列表',\n items: {\n type: 'object',\n properties: {\n description: {\n type: 'string',\n description: '任务描述',\n },\n tools: {\n type: 'array',\n description:\n '允许使用的工具列表(默认 read-file, glob, grep),不可包含 spawn-agents',\n items: { type: 'string' },\n },\n },\n required: ['description'],\n },\n },\n max_turns: {\n type: 'number',\n description: '每个子 Agent 的最大轮数(默认 10,上限 15)',\n },\n },\n required: ['tasks'],\n },\n permissionLevel: 'auto',\n\n async execute(params: Record<string, unknown>): Promise<ToolResult> {\n const tasks = params['tasks'] as TaskInput[];\n const maxTurns = Math.min(\n (params['max_turns'] as number) || 10,\n MAX_TURNS_LIMIT,\n );\n\n if (!tasks || tasks.length === 0) {\n return { content: '错误:未提供任务' };\n }\n\n if (tasks.length > MAX_CONCURRENT) {\n return { content: `错误:最多支持 ${MAX_CONCURRENT} 个并发任务` };\n }\n\n // 获取 auto 权限的工具列表\n const autoTools = registry\n .listTools()\n .filter((t) => registry.getPermissionLevel(t) === 'auto' && t !== 'spawn-agents');\n\n const descriptions = tasks.map((t) => t.description);\n\n // 通知 tracker 开始\n tracker?.start(descriptions);\n\n const agents = tasks.map((task) => {\n // 取请求工具与 auto 工具的交集,排除 spawn-agents\n let tools = task.tools\n ? task.tools\n .filter((t) => t !== 'spawn-agents')\n .filter((t) => autoTools.includes(t))\n : DEFAULT_TOOLS.filter((t) => autoTools.includes(t));\n\n if (tools.length === 0) {\n tools = DEFAULT_TOOLS.filter((t) => autoTools.includes(t));\n }\n\n return new SubAgent(client, registry, config, task.description, tools, maxTurns, undefined, tracker);\n });\n\n // 包装每个 agent 的 run,追踪完成/失败\n const wrappedRuns = agents.map((agent) =>\n agent.run().then(\n (result) => { tracker?.markCompleted(); return result; },\n (err) => { tracker?.markFailed(); throw err; },\n ),\n );\n\n const results = await Promise.allSettled(wrappedRuns);\n\n // 通知 tracker 结束\n tracker?.finish();\n\n const succeeded = results.filter((r) => r.status === 'fulfilled').length;\n const failed = results.filter((r) => r.status === 'rejected').length;\n\n const output = results\n .map((result, i) => {\n const task = tasks[i]!;\n const status = result.status === 'fulfilled' ? '✓' : '✗';\n const header = `=== ${status} 任务 ${i + 1}: ${task.description} ===`;\n if (result.status === 'fulfilled') {\n return `${header}\\n${result.value}`;\n }\n return `${header}\\n错误: ${result.reason}`;\n })\n .join('\\n\\n');\n\n const summary = `[${succeeded} 成功${failed > 0 ? `, ${failed} 失败` : ''}]`;\n\n return { content: `${summary}\\n\\n${output}` };\n },\n };\n}\n","import type { Tool, ToolResult } from './types.js';\nimport type { TodoStore } from '../core/todo-store.js';\n\n/**\n * 创建 todo 工具 - 计划管理\n */\nexport function createTodoTool(store: TodoStore): Tool {\n return {\n name: 'todo',\n description:\n '管理任务计划。支持创建计划、更新条目状态、查看计划和清空计划。对于包含多个步骤的任务,先创建计划再逐步执行。',\n parameters: {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n description: '操作类型',\n enum: ['create', 'update', 'list', 'clear'],\n },\n items: {\n type: 'array',\n description: 'create 时必填:计划条目列表',\n items: {\n type: 'object',\n properties: {\n id: { type: 'string', description: '条目 ID' },\n title: { type: 'string', description: '条目标题' },\n },\n required: ['id', 'title'],\n },\n },\n id: {\n type: 'string',\n description: 'update 时必填:要更新的条目 ID',\n },\n status: {\n type: 'string',\n description: 'update 时必填:新状态',\n enum: ['pending', 'in-progress', 'completed'],\n },\n },\n required: ['action'],\n },\n permissionLevel: 'auto',\n\n async execute(params: Record<string, unknown>): Promise<ToolResult> {\n const action = params['action'] as string;\n\n switch (action) {\n case 'create': {\n const items = params['items'] as\n | { id: string; title: string }[]\n | undefined;\n if (!items || items.length === 0) {\n return { content: '错误:create 需要提供 items' };\n }\n const plan = store.create(items);\n const lines = plan.items.map(\n (item) => `○ [${item.id}] ${item.title}`,\n );\n return {\n content: `计划已创建(${plan.items.length} 个条目):\\n${lines.join('\\n')}`,\n };\n }\n\n case 'update': {\n const id = params['id'] as string | undefined;\n const status = params['status'] as string | undefined;\n if (!id || !status) {\n return { content: '错误:update 需要提供 id 和 status' };\n }\n const item = store.update(\n id,\n status as 'pending' | 'in-progress' | 'completed',\n );\n if (!item) {\n return { content: `错误:未找到条目 \"${id}\"` };\n }\n const icon =\n item.status === 'completed'\n ? '●'\n : item.status === 'in-progress'\n ? '◐'\n : '○';\n return {\n content: `已更新:${icon} [${item.id}] ${item.title} → ${item.status}`,\n };\n }\n\n case 'list': {\n const plan = store.list();\n if (!plan) {\n return { content: '当前没有计划' };\n }\n const completed = plan.items.filter(\n (i) => i.status === 'completed',\n ).length;\n const lines = plan.items.map((item) => {\n const icon =\n item.status === 'completed'\n ? '●'\n : item.status === 'in-progress'\n ? '◐'\n : '○';\n return `${icon} [${item.id}] ${item.title}`;\n });\n return {\n content: `计划进度 ${completed}/${plan.items.length}:\\n${lines.join('\\n')}`,\n };\n }\n\n case 'clear': {\n store.clear();\n return { content: '计划已清空' };\n }\n\n default:\n return {\n content: `错误:未知操作 \"${action}\"。支持: create, update, list, clear`,\n };\n }\n },\n };\n}\n","import type { ZenCodeConfig } from '../../config/types.js';\nimport type { LLMClient } from '../../llm/client.js';\nimport type { ToolRegistry } from '../../tools/registry.js';\nimport type { AgentCallbacks } from '../agent.js';\nimport type { SubAgentConfig } from './types.js';\nimport type { SubAgentTracker } from '../sub-agent-tracker.js';\nimport { Conversation } from '../conversation.js';\nimport { confirmExecution } from '../../tools/permission.js';\nimport { ReadTracker } from '../read-tracker.js';\n\nconst DEFAULT_MAX_TURNS = 15;\n\n/**\n * SubAgentRunner - 执行可配置子 Agent\n *\n * 基于 SubAgentConfig 运行子 Agent。\n * 使用流式 chatStream(),TUI 可实时显示输出。\n */\nexport class SubAgentRunner {\n private client: LLMClient;\n private registry: ToolRegistry;\n private config: ZenCodeConfig;\n private agentConfig: SubAgentConfig;\n private tracker?: SubAgentTracker;\n\n constructor(\n client: LLMClient,\n registry: ToolRegistry,\n config: ZenCodeConfig,\n agentConfig: SubAgentConfig,\n tracker?: SubAgentTracker,\n ) {\n this.client = client;\n this.registry = registry;\n this.config = config;\n this.agentConfig = agentConfig;\n this.tracker = tracker;\n }\n\n /**\n * 执行子 Agent 任务\n */\n async execute(task: string, context?: string, callbacks: AgentCallbacks = {}): Promise<string> {\n const timeoutMs = (this.agentConfig.timeout ?? 120) * 1000;\n const maxTurns = this.agentConfig.max_turns ?? DEFAULT_MAX_TURNS;\n\n return Promise.race([\n this.run(task, context, maxTurns, callbacks),\n this.timeout(timeoutMs),\n ]);\n }\n\n private timeout(ms: number): Promise<never> {\n return new Promise((_, reject) => {\n setTimeout(\n () => reject(new Error(`子 Agent \"${this.agentConfig.name}\" 超时(${ms / 1000}s)`)),\n ms,\n );\n });\n }\n\n private async run(task: string, context: string | undefined, maxTurns: number, callbacks: AgentCallbacks): Promise<string> {\n const conversation = new Conversation();\n const readTracker = new ReadTracker();\n\n conversation.setSystemPrompt(this.agentConfig.prompt);\n\n // 组装任务消息\n let taskMessage = task;\n if (context) {\n taskMessage += `\\n\\n[上下文]\\n${context}`;\n }\n conversation.addUserMessage(taskMessage);\n\n // 构建工具列表:取子 Agent 声明的工具与注册表的交集\n const tools = this.registry.toToolDefinitions(this.agentConfig.tools);\n let lastContent = '';\n\n for (let turn = 0; turn < maxTurns; turn++) {\n const assistantMsg = await this.client.chatStream(\n conversation.getMessages(),\n tools.length > 0 ? tools : undefined,\n callbacks,\n );\n\n // 报告 token 用量\n if (assistantMsg.usage && this.tracker) {\n this.tracker.addTokens(assistantMsg.usage.total_tokens);\n }\n\n conversation.addAssistantMessage(assistantMsg);\n\n if (!assistantMsg.tool_calls || assistantMsg.tool_calls.length === 0) {\n lastContent = assistantMsg.content || '';\n break;\n }\n\n for (const toolCall of assistantMsg.tool_calls) {\n const toolName = toolCall.function.name;\n\n // 检查工具是否在子 Agent 允许列表中\n if (!this.agentConfig.tools.includes(toolName)) {\n conversation.addToolResult(\n toolCall.id,\n `子 Agent \"${this.agentConfig.name}\" 不允许使用工具 \"${toolName}\"`,\n );\n continue;\n }\n\n let params: Record<string, unknown>;\n try {\n params = JSON.parse(toolCall.function.arguments);\n } catch {\n conversation.addToolResult(toolCall.id, '参数解析失败:无效的 JSON');\n continue;\n }\n\n try {\n // 先读后改检查\n if (toolName === 'edit-file') {\n const editPath = params['path'] as string;\n if (!readTracker.hasRead(editPath)) {\n conversation.addToolResult(toolCall.id,\n `⚠ 禁止编辑未读取的文件。请先 read-file \"${editPath}\" 了解当前内容,再 edit-file。`);\n continue;\n }\n }\n\n // write-file 覆盖检查\n if (toolName === 'write-file') {\n const warn = readTracker.checkWriteOverwrite(\n params['path'] as string,\n params['overwrite'] as boolean | undefined,\n );\n if (warn) {\n conversation.addToolResult(toolCall.id, warn);\n continue;\n }\n }\n\n // 权限检查\n const permLevel = this.registry.getPermissionLevel(toolName);\n if (permLevel === 'deny') {\n callbacks.onDenied?.(toolName);\n conversation.addToolResult(toolCall.id, `工具 \"${toolName}\" 已被禁止执行`);\n continue;\n }\n\n if (permLevel === 'auto') {\n callbacks.onToolExecuting?.(toolName, params);\n }\n\n if (permLevel === 'confirm') {\n const confirmResult = await confirmExecution(toolName, params);\n if (!confirmResult.approved) {\n callbacks.onDenied?.(toolName, confirmResult.feedback);\n const denyMsg = confirmResult.feedback\n ? `用户拒绝了此操作,用户反馈: ${confirmResult.feedback}`\n : '用户拒绝了此操作';\n conversation.addToolResult(toolCall.id, denyMsg);\n continue;\n }\n }\n\n // 执行工具\n const result = await this.registry.execute(toolName, params, this.config.max_tool_output);\n callbacks.onToolResult?.(toolName, result.content, result.truncated ?? false);\n\n // 跟踪已读/已写文件\n if (toolName === 'read-file') {\n readTracker.markRead(params['path'] as string);\n } else if (toolName === 'write-file') {\n readTracker.markWritten(params['path'] as string);\n }\n\n conversation.addToolResult(toolCall.id, result.content);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n conversation.addToolResult(toolCall.id, `工具执行异常:${msg}`);\n }\n }\n\n if (assistantMsg.content) {\n lastContent = assistantMsg.content;\n }\n }\n\n return lastContent;\n }\n}\n","import type { Tool, ToolResult } from './types.js';\nimport type { LLMClient } from '../llm/client.js';\nimport type { ToolRegistry } from './registry.js';\nimport type { ZenCodeConfig } from '../config/types.js';\nimport type { AgentCallbacks } from '../core/agent.js';\nimport type { SubAgentConfigRegistry } from '../core/sub-agents/registry.js';\nimport type { SubAgentTracker } from '../core/sub-agent-tracker.js';\nimport { SubAgentRunner } from '../core/sub-agents/runner.js';\nimport { createLLMClient } from '../llm/client.js';\n\n/**\n * 创建 dispatch 工具 - 主 Agent 调度子 Agent 的入口\n */\nexport function createDispatchTool(\n defaultClient: LLMClient,\n toolRegistry: ToolRegistry,\n config: ZenCodeConfig,\n agentRegistry: SubAgentConfigRegistry,\n tracker?: SubAgentTracker,\n callbacks?: () => AgentCallbacks,\n): Tool {\n return {\n name: 'dispatch',\n description: '调度子 Agent 执行专门任务。子 Agent 有独立对话和专属系统提示词,适用于需要专业角色的场景。',\n parameters: {\n type: 'object',\n properties: {\n agent: {\n type: 'string',\n description: `子 Agent 名称。可选: ${agentRegistry.listNames().join(', ')}`,\n enum: agentRegistry.listNames(),\n },\n task: {\n type: 'string',\n description: '要执行的具体任务描述',\n },\n context: {\n type: 'string',\n description: '可选的额外上下文信息(如参考文件路径、依赖关系等)',\n },\n },\n required: ['agent', 'task'],\n },\n permissionLevel: 'auto',\n\n async execute(params: Record<string, unknown>): Promise<ToolResult> {\n const agentName = params['agent'] as string;\n const task = params['task'] as string;\n const context = params['context'] as string | undefined;\n\n const agentConfig = agentRegistry.get(agentName);\n if (!agentConfig) {\n return { content: `错误:未找到子 Agent \"${agentName}\"。可用: ${agentRegistry.listNames().join(', ')}` };\n }\n\n // 决定使用的 LLM 客户端\n let client = defaultClient;\n if (agentConfig.model) {\n client = createLLMClient({\n apiKey: agentConfig.model.api_key || config.api_key,\n baseURL: agentConfig.model.base_url || config.base_url,\n model: agentConfig.model.model || config.model,\n temperature: config.temperature,\n maxTokens: config.max_tokens,\n });\n }\n\n const runner = new SubAgentRunner(client, toolRegistry, config, agentConfig, tracker);\n\n // 通知 tracker 开始\n tracker?.start([`${agentName}: ${task.slice(0, 60)}`]);\n\n try {\n const result = await runner.execute(task, context, callbacks?.() ?? {});\n tracker?.finish();\n return { content: result || '(子 Agent 执行完成,无输出)' };\n } catch (err) {\n tracker?.finish();\n const msg = err instanceof Error ? err.message : String(err);\n return { content: `子 Agent 执行错误:${msg}` };\n }\n },\n };\n}\n","import { EventEmitter } from 'events';\r\n\r\nexport interface StreamingProgress {\r\n name: string;\r\n progress: string;\r\n}\r\n\r\nclass ProgressStore extends EventEmitter {\r\n private current?: StreamingProgress;\r\n\r\n update(progress?: StreamingProgress) {\r\n this.current = progress;\r\n this.emit('change', progress);\r\n }\r\n\r\n get() {\r\n return this.current;\r\n }\r\n}\r\n\r\nexport const progressStore = new ProgressStore();\r\n","// Bridge: Agent callbacks → TUI dispatch\r\n// Includes token batching to avoid excessive React re-renders\r\n\r\nimport type { Dispatch } from 'react';\r\nimport type { AgentCallbacks } from '../../core/agent.js';\r\nimport type { TuiAction } from './state.js';\r\nimport { progressStore } from './stores/progressStore.js';\r\n\r\nconst ANSI_GRAY = '\\x1b[90m';\r\nconst ANSI_RESET = '\\x1b[0m';\r\n\r\nfunction gray(text: string): string {\r\n return `${ANSI_GRAY}${text}${ANSI_RESET}`;\r\n}\r\n\r\n/**\r\n * 流式 <think> 标签转换器 (For standard REPL)\r\n * 轻量样式:标题 + 缩进内容(无边框)\r\n */\r\nexport function createThinkFilter() {\r\n let inThink = false;\r\n let tagBuffer = '';\r\n let thinkLineBuffer = '';\r\n let thinkHasVisibleContent = false;\r\n let thinkLastEmittedBlank = false;\r\n let postThink = false;\r\n\r\n function flushThinkLine(rawLine: string): string {\r\n const normalized = rawLine.trim();\r\n if (!thinkHasVisibleContent && normalized.length === 0) return '';\r\n if (normalized.length === 0) {\r\n if (thinkLastEmittedBlank) return '';\r\n thinkLastEmittedBlank = true;\r\n return '\\n';\r\n }\r\n thinkHasVisibleContent = true;\r\n thinkLastEmittedBlank = false;\r\n return `${gray(` ${normalized}`)}\\n`;\r\n }\r\n\r\n function appendOutsideText(current: string, text: string): string {\r\n if (!postThink) return current + text;\r\n let result = current;\r\n for (let i = 0; i < text.length; i++) {\r\n const ch = text[i]!;\r\n if (postThink && (ch === '\\n' || ch === '\\r' || ch === ' ' || ch === '\\t')) {\r\n continue;\r\n }\r\n postThink = false;\r\n result += text.slice(i);\r\n break;\r\n }\r\n return result;\r\n }\r\n\r\n function appendThinkText(current: string, text: string): string {\r\n let result = current;\r\n for (let i = 0; i < text.length; i++) {\r\n const ch = text[i]!;\r\n if (ch === '\\r') continue;\r\n if (ch === '\\n') {\r\n result += flushThinkLine(thinkLineBuffer);\r\n thinkLineBuffer = '';\r\n } else {\r\n thinkLineBuffer += ch;\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n return function filter(text: string): string {\r\n let result = '';\r\n for (let i = 0; i < text.length; i++) {\r\n const ch = text[i]!;\r\n if (tagBuffer.length > 0) {\r\n tagBuffer += ch;\r\n if (tagBuffer === '<think>') {\r\n inThink = true;\r\n thinkLineBuffer = '';\r\n thinkHasVisibleContent = false;\r\n thinkLastEmittedBlank = false;\r\n tagBuffer = '';\r\n result += `${gray('Thinking')}\\n`;\r\n } else if (tagBuffer === '</think>') {\r\n inThink = false;\r\n postThink = true;\r\n tagBuffer = '';\r\n if (thinkLineBuffer.length > 0) {\r\n result += flushThinkLine(thinkLineBuffer);\r\n thinkLineBuffer = '';\r\n }\r\n while (result.endsWith('\\n\\n\\n')) result = result.slice(0, -1);\r\n result += '\\n';\r\n } else if (!'<think>'.startsWith(tagBuffer) && !'</think>'.startsWith(tagBuffer)) {\r\n if (inThink) result = appendThinkText(result, tagBuffer);\r\n else result = appendOutsideText(result, tagBuffer);\r\n tagBuffer = '';\r\n }\r\n continue;\r\n }\r\n if (ch === '<') {\r\n tagBuffer = '<';\r\n continue;\r\n }\r\n if (inThink) result = appendThinkText(result, ch);\r\n else result = appendOutsideText(result, ch);\r\n }\r\n return result;\r\n };\r\n}\r\n\r\n/**\r\n * Creates a unified action batcher that collects dispatches and flushes them\r\n * at a fixed interval to minimize terminal flickering and React re-renders.\r\n */\r\nfunction createActionBatcher(dispatch: Dispatch<TuiAction>) {\r\n let pendingActions: Map<string, TuiAction> = new Map();\r\n let timer: ReturnType<typeof setInterval> | null = null;\r\n\r\n function flush() {\r\n if (pendingActions.size > 0) {\r\n const actions = Array.from(pendingActions.values());\r\n pendingActions.clear();\r\n dispatch({ type: 'BATCH', actions });\r\n }\r\n }\r\n\r\n function start() {\r\n if (!timer) {\r\n timer = setInterval(flush, 200); // Optimized for smoothness\r\n }\r\n }\r\n\r\n function stop() {\r\n flush();\r\n if (timer) {\r\n clearInterval(timer);\r\n timer = null;\r\n }\r\n }\r\n\r\n function queue(key: string, action: TuiAction) {\r\n if (action.type === 'APPEND_CONTENT' || action.type === 'APPEND_THOUGHT') {\r\n const existing = pendingActions.get(key) as any;\r\n if (existing) {\r\n action = { ...action, text: existing.text + (action as any).text } as TuiAction;\r\n }\r\n }\r\n pendingActions.set(key, action);\r\n start();\r\n }\r\n\r\n return { queue, stop, flush };\r\n}\r\n\r\n// Track tool call IDs for mapping tool results back\r\nlet toolCallCounter = 0;\r\nlet activeToolIds: Map<string, string> = new Map();\r\n// Track streaming tool index → id\r\nlet streamingToolIds: Map<number, string> = new Map();\r\n// Track last streaming value per tool id to avoid redundant updates\r\nlet lastStreamingValues: Map<string, string> = new Map();\r\n\r\n/**\r\n * 从部分 JSON 参数中提取代码内容(write-file 的 content 或 edit-file 的 new_string)\r\n */\r\nfunction extractCodeFromArgs(name: string, args: string): string | null {\r\n const field = name === 'write-file' ? 'content' : 'new_string';\r\n const patterns = [`\"${field}\": \"`, `\"${field}\":\"`];\r\n for (const pattern of patterns) {\r\n const idx = args.indexOf(pattern);\r\n if (idx >= 0) {\r\n let raw = args.slice(idx + pattern.length);\r\n if (raw.endsWith('\"}')) raw = raw.slice(0, -2);\r\n else if (raw.endsWith('\"')) raw = raw.slice(0, -1);\r\n return raw\r\n .replace(/\\\\n/g, '\\n')\r\n .replace(/\\\\t/g, '\\t')\r\n .replace(/\\\\\"/g, '\"')\r\n .replace(/\\\\\\\\/g, '\\\\');\r\n }\r\n }\r\n return null;\r\n}\r\n\r\n/**\r\n * Register a confirm tool id so that subsequent onToolResult/onDenied\r\n * can find it by tool name.\r\n */\r\nexport function registerConfirmToolId(toolName: string, id: string): void {\r\n activeToolIds.set(toolName, id);\r\n}\r\n\r\n/**\r\n * Creates AgentCallbacks that dispatch to TUI state.\r\n */\r\nexport function createBridgeCallbacks(dispatch: Dispatch<TuiAction>): AgentCallbacks & { _stopBatcher: () => void } {\r\n const batcher = createActionBatcher(dispatch);\r\n \r\n let inThink = false;\r\n let tagBuffer = '';\r\n\r\n activeToolIds = new Map();\r\n streamingToolIds = new Map();\r\n lastStreamingValues = new Map();\r\n toolCallCounter = 0;\r\n\r\n return {\r\n onContent: (text: string) => {\r\n let contentAcc = '';\r\n let thoughtAcc = '';\r\n\r\n for (let i = 0; i < text.length; i++) {\r\n const ch = text[i]!;\r\n\r\n if (tagBuffer.length > 0 || ch === '<') {\r\n tagBuffer += ch;\r\n if (tagBuffer === '<think>') {\r\n if (contentAcc) batcher.queue('content', { type: 'APPEND_CONTENT', text: contentAcc });\r\n contentAcc = '';\r\n batcher.flush();\r\n inThink = true;\r\n tagBuffer = '';\r\n continue;\r\n } else if (tagBuffer === '</think>') {\r\n if (thoughtAcc) batcher.queue('thought', { type: 'APPEND_THOUGHT', text: thoughtAcc });\r\n thoughtAcc = '';\r\n batcher.flush();\r\n inThink = false;\r\n tagBuffer = '';\r\n continue;\r\n } else if (!'<think>'.startsWith(tagBuffer) && !'</think>'.startsWith(tagBuffer)) {\r\n if (inThink) thoughtAcc += tagBuffer;\r\n else contentAcc += tagBuffer;\r\n tagBuffer = '';\r\n }\r\n continue;\r\n }\r\n\r\n if (inThink) thoughtAcc += ch;\r\n else contentAcc += ch;\r\n }\r\n\r\n if (thoughtAcc) batcher.queue('thought', { type: 'APPEND_THOUGHT', text: thoughtAcc });\r\n if (contentAcc) batcher.queue('content', { type: 'APPEND_CONTENT', text: contentAcc });\r\n },\r\n\r\n onToolCallStreaming: (index: number, name: string, accumulatedArgs: string) => {\r\n if (!streamingToolIds.has(index)) {\r\n batcher.flush();\r\n const id = `tool-${++toolCallCounter}`;\r\n streamingToolIds.set(index, id);\r\n activeToolIds.set(name, id);\r\n lastStreamingValues.set(id, '0');\r\n // Still queue the action to ensure the block is created in the history, but it won't update repeatedly\r\n batcher.queue(`tool-${id}`, { type: 'TOOL_STREAMING', id, name, streamingContent: '0' });\r\n }\r\n \r\n const id = streamingToolIds.get(index)!;\r\n const lineCount = (accumulatedArgs.match(/\\\\n/g) || []).length;\r\n const streamingContent = String(lineCount);\r\n\r\n if (lastStreamingValues.get(id) !== streamingContent) {\r\n lastStreamingValues.set(id, streamingContent);\r\n // CRITICAL: Update the offline store directly\r\n progressStore.update({ name, progress: `${streamingContent} lines` });\r\n }\r\n },\r\n\r\n onToolExecuting: (name: string, params: Record<string, unknown>) => {\r\n progressStore.update(undefined); // Clear progress when tool starts execution\r\n batcher.flush();\r\n const existingId = activeToolIds.get(name);\r\n const id = existingId || `tool-${++toolCallCounter}`;\r\n activeToolIds.set(name, id);\r\n lastStreamingValues.set(id, JSON.stringify(params));\r\n dispatch({ type: 'TOOL_EXECUTING', id, name, params });\r\n },\r\n\r\n onToolResult: (name: string, result: string, truncated: boolean) => {\r\n progressStore.update(undefined); // Clear progress on result\r\n batcher.flush();\r\n const id = activeToolIds.get(name) || `tool-${++toolCallCounter}`;\r\n const lines = result.split('\\n');\r\n const isWriteTool = name === 'write-file' || name === 'edit-file';\r\n let summary: string;\r\n if (isWriteTool) {\r\n const stored = lastStreamingValues.get(id) || '';\r\n const code = extractCodeFromArgs(name, stored);\r\n const codeLines = code ? code.split('\\n').length : 0;\r\n summary = codeLines > 0 ? `${codeLines} lines` : (truncated ? 'truncated' : `${lines.length} lines`);\r\n } else {\r\n summary = truncated ? `truncated` : `${lines.length} lines`;\r\n }\r\n\r\n const preview = lines.slice(0, 5).join('\\n').slice(0, 200);\r\n const resultContent = lines.length > 5 || preview.length >= 200\r\n ? preview + '...'\r\n : preview;\r\n dispatch({ type: 'TOOL_RESULT', id, resultSummary: summary, resultContent });\r\n },\r\n\r\n onDenied: (toolName: string, feedback?: string) => {\r\n batcher.flush();\r\n const id = activeToolIds.get(toolName) || `tool-${++toolCallCounter}`;\r\n dispatch({ type: 'TOOL_DENIED', id, feedback });\r\n },\r\n\r\n onError: (err: Error) => {\r\n batcher.stop();\r\n dispatch({ type: 'SET_ERROR', error: err.message });\r\n },\r\n\r\n _stopBatcher: () => {\r\n batcher.stop();\r\n },\r\n };\r\n}\r\n","import chalk from 'chalk';\r\nimport ora, { type Ora } from 'ora';\r\nimport { Marked } from 'marked';\r\nimport * as _markedTerminal from 'marked-terminal';\r\nimport { createTwoFilesPatch } from 'diff';\r\n\r\n// 配置 marked 使用终端渲染器\r\nconst markedTerminal = (_markedTerminal as any).markedTerminal as (options?: any) => any;\r\nconst marked = new Marked(markedTerminal({\r\n reflowText: false,\r\n code: chalk.cyan,\r\n codespan: chalk.yellow,\r\n heading: chalk.bold.magenta,\r\n hr: () => chalk.dim('─'.repeat(Math.max(0, (process.stdout.columns || 80) - 12))),\r\n strong: chalk.bold,\r\n em: chalk.italic,\r\n link: chalk.blue,\r\n href: chalk.blue.underline,\r\n}));\r\n\r\n// 补充修复: 确保列表项中的嵌套行内元素(如加粗)能正确渲染\r\nmarked.use({\r\n renderer: {\r\n text(this: any, token: any) {\r\n if (typeof token === 'object' && token.tokens) {\r\n return this.parser.parseInline(token.tokens);\r\n }\r\n return typeof token === 'string' ? token : token.text;\r\n }\r\n }\r\n});\r\n\r\n/**\r\n * 渲染 Markdown 到终端\r\n */\r\nexport function renderMarkdown(text: string): string {\r\n const rendered = (marked.parse(text) as string) as string;\r\n // 移除末尾换行,由 ink 组件控制布局\r\n return rendered.replace(/\\n+$/, '');\r\n}\r\n\r\n/**\r\n * 创建加载动画\r\n */\r\nexport function createSpinner(text: string): Ora {\r\n return ora({ text, color: 'cyan' });\r\n}\r\n\r\n/**\r\n * 打印用户输入提示\r\n */\r\nexport function printPrompt(): void {\r\n process.stdout.write(chalk.green('> '));\r\n}\r\n\r\n/**\r\n * 打印助手回复\r\n */\r\nexport function printAssistant(text: string): void {\r\n console.log(renderMarkdown(text));\r\n}\r\n\r\n/**\r\n * 打印流式内容(不换行)\r\n */\r\nexport function printStream(text: string): void {\r\n process.stdout.write(text);\r\n}\r\n\r\n/**\r\n * 打印工具调用信息\r\n */\r\nexport function printToolCall(toolName: string, params: Record<string, unknown>): void {\r\n let detail = '';\r\n if (toolName === 'bash' && params['command']) {\r\n detail = ` ${chalk.dim(String(params['command']).slice(0, 80))}`;\r\n } else if ((toolName === 'read-file' || toolName === 'write-file' || toolName === 'edit-file') && params['path']) {\r\n detail = ` ${chalk.dim(String(params['path']))}`;\r\n } else if (toolName === 'glob' && params['pattern']) {\r\n detail = ` ${chalk.dim(String(params['pattern']))}`;\r\n } else if (toolName === 'grep' && params['pattern']) {\r\n detail = ` ${chalk.dim(String(params['pattern']))}`;\r\n } else if (toolName === 'spawn-agents' && params['tasks']) {\r\n const tasks = params['tasks'] as { description: string }[];\r\n detail = ` ${chalk.dim(`${tasks.length} 个并行任务`)}`;\r\n } else if (toolName === 'todo' && params['action']) {\r\n const action = String(params['action']);\r\n const id = params['id'] ? ` [${params['id']}]` : '';\r\n detail = ` ${chalk.dim(`${action}${id}`)}`;\r\n }\r\n const icon = toolName === 'spawn-agents' ? '>>' : toolName === 'todo' ? '#' : '>';\r\n console.log(chalk.yellow(` ${icon} ${toolName}`) + detail);\r\n}\r\n\r\n/**\r\n * 打印工具执行结果\r\n */\r\nexport function printToolResult(toolName: string, result: string, truncated: boolean): void {\r\n if (truncated) {\r\n console.log(chalk.dim(` ✓ ${toolName} (输出已截断)`));\r\n } else {\r\n const lines = result.split('\\n').length;\r\n console.log(chalk.dim(` ✓ ${toolName} (${lines} 行)`));\r\n }\r\n}\r\n\r\n/**\r\n * 打印错误信息\r\n */\r\nexport function printError(message: string): void {\r\n console.error(chalk.red(`✗ ${message}`));\r\n}\r\n\r\n/**\r\n * 打印信息\r\n */\r\nexport function printInfo(message: string): void {\r\n console.log(chalk.cyan(`ℹ ${message}`));\r\n}\r\n\r\n/**\r\n * 打印警告\r\n */\r\nexport function printWarning(message: string): void {\r\n console.log(chalk.yellow(`⚠ ${message}`));\r\n}\r\n\r\n/**\r\n * 打印成功消息\r\n */\r\nexport function printSuccess(message: string): void {\r\n console.log(chalk.green(`✓ ${message}`));\r\n}\r\n\r\n/**\r\n * 打印 diff\r\n */\r\nexport function printDiff(oldContent: string, newContent: string, filePath: string): void {\r\n const patch = createTwoFilesPatch(filePath, filePath, oldContent, newContent);\r\n const lines = patch.split('\\n');\r\n for (const line of lines) {\r\n if (line.startsWith('+') && !line.startsWith('+++')) {\r\n console.log(chalk.green(line));\r\n } else if (line.startsWith('-') && !line.startsWith('---')) {\r\n console.log(chalk.red(line));\r\n } else if (line.startsWith('@@')) {\r\n console.log(chalk.cyan(line));\r\n } else {\r\n console.log(chalk.dim(line));\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * 打印模式信息\r\n */\r\n/**\r\n * 打印欢迎信息\r\n */\r\nexport function printWelcome(modelName: string): void {\r\n console.log(chalk.bold.cyan('\\n ZenCode') + chalk.dim(' - 极简 AI 编程助手\\n'));\r\n console.log(chalk.dim(` 模型: ${modelName}`));\r\n console.log(chalk.dim(` 输入 /help 查看命令,Ctrl+C 退出\\n`));\r\n}\r\n","/**\n * 子 Agent 并行执行追踪器\n *\n * spawn-agents 工具在执行时更新状态,TUI 订阅变化实时渲染。\n */\n\nexport interface SubAgentProgress {\n total: number;\n completed: number;\n failed: number;\n descriptions: string[];\n tokens: number;\n}\n\ntype ProgressListener = (progress: SubAgentProgress | null) => void;\n\nexport class SubAgentTracker {\n private progress: SubAgentProgress | null = null;\n private listeners = new Set<ProgressListener>();\n\n start(descriptions: string[]): void {\n this.progress = {\n total: descriptions.length,\n completed: 0,\n failed: 0,\n descriptions,\n tokens: 0,\n };\n this.notify();\n }\n\n markCompleted(): void {\n if (!this.progress) return;\n this.progress = { ...this.progress, completed: this.progress.completed + 1 };\n this.notify();\n }\n\n markFailed(): void {\n if (!this.progress) return;\n this.progress = { ...this.progress, failed: this.progress.failed + 1 };\n this.notify();\n }\n\n addTokens(count: number): void {\n if (!this.progress) return;\n this.progress = { ...this.progress, tokens: this.progress.tokens + count };\n this.notify();\n }\n\n finish(): void {\n this.progress = null;\n this.notify();\n }\n\n get current(): SubAgentProgress | null {\n return this.progress;\n }\n\n subscribe(listener: ProgressListener): () => void {\n this.listeners.add(listener);\n return () => { this.listeners.delete(listener); };\n }\n\n private notify(): void {\n const snapshot = this.progress ? { ...this.progress } : null;\n for (const listener of this.listeners) {\n listener(snapshot);\n }\n }\n}\n","import type { TodoPlan } from '../../core/todo-store.js';\r\nimport type { SubAgentProgress } from '../../core/sub-agent-tracker.js';\r\n\r\n// TUI state management with useReducer\r\n\r\nexport interface ToolCallState {\r\n id: string;\r\n name: string;\r\n params: Record<string, unknown>;\r\n status: 'running' | 'done' | 'denied' | 'confirming';\r\n resultSummary?: string;\r\n resultContent?: string;\r\n denyFeedback?: string;\r\n streamingContent?: string;\r\n}\r\n\r\nexport type ConfirmResult = 'allow' | 'deny' | 'always' | { feedback: string };\r\n\r\nexport interface ConfirmPending {\r\n toolName: string;\r\n params: Record<string, unknown>;\r\n resolve: (result: ConfirmResult) => void;\r\n}\r\n\r\n// Content blocks: text, tool calls and thoughts are interleaved in order\r\nexport type ContentBlock =\r\n | { type: 'text'; text: string }\r\n | { type: 'thought'; text: string }\r\n | { type: 'tool'; toolCall: ToolCallState };\r\n\r\nexport interface ChatMessage {\r\n id: string;\r\n role: 'user' | 'assistant' | 'system';\r\n blocks: ContentBlock[];\r\n isStreaming: boolean;\r\n confirmPending?: ConfirmPending;\r\n}\r\n\r\nexport interface TuiState {\r\n messages: ChatMessage[];\r\n isRunning: boolean;\r\n error?: string;\r\n modelName: string;\r\n todoPlan: TodoPlan | null;\r\n subAgentProgress: SubAgentProgress | null;\r\n}\r\n\r\nexport function createInitialState(modelName: string): TuiState {\r\n return {\r\n messages: [],\r\n isRunning: false,\r\n error: undefined,\r\n modelName,\r\n todoPlan: null,\r\n subAgentProgress: null,\r\n };\r\n}\r\n\r\n// Action types\r\nexport type TuiAction =\r\n | { type: 'ADD_USER_MESSAGE'; text: string }\r\n | { type: 'START_ASSISTANT' }\r\n | { type: 'APPEND_CONTENT'; text: string }\r\n | { type: 'APPEND_THOUGHT'; text: string }\r\n | { type: 'TOOL_EXECUTING'; id: string; name: string; params: Record<string, unknown> }\r\n | { type: 'TOOL_STREAMING'; id: string; name: string; streamingContent: string }\r\n | { type: 'TOOL_RESULT'; id: string; resultSummary: string; resultContent?: string }\r\n | { type: 'TOOL_DENIED'; id: string; feedback?: string }\r\n | { type: 'TOOL_CONFIRMING'; id: string; name: string; params: Record<string, unknown>; resolve: (r: ConfirmResult) => void }\r\n | { type: 'CONFIRM_RESPONDED'; id: string }\r\n | { type: 'FINISH_STREAMING' }\r\n | { type: 'SET_RUNNING'; running: boolean }\r\n | { type: 'SET_ERROR'; error: string }\r\n | { type: 'CLEAR_ERROR' }\r\n | { type: 'CLEAR_MESSAGES' }\r\n | { type: 'SET_TODO_PLAN'; plan: TodoPlan | null }\r\n | { type: 'SET_SUB_AGENT_PROGRESS'; progress: SubAgentProgress | null }\r\n | { type: 'BATCH'; actions: TuiAction[] };\r\n\r\nlet messageCounter = 0;\r\nfunction nextId(): string {\r\n return `msg-${++messageCounter}`;\r\n}\r\n\r\nfunction updateLastAssistant(messages: ChatMessage[], updater: (msg: ChatMessage) => ChatMessage): ChatMessage[] {\r\n const result = [...messages];\r\n for (let i = result.length - 1; i >= 0; i--) {\r\n if (result[i]!.role === 'assistant') {\r\n const updated = updater(result[i]!);\r\n if (updated === result[i]) return messages; // CRITICAL: Bail out if no change\r\n result[i] = updated;\r\n return result;\r\n }\r\n }\r\n return result;\r\n}\r\n\r\n/** Helper to find and update a tool block by id across all blocks */\r\nfunction updateToolInBlocks(blocks: ContentBlock[], toolId: string, updater: (tc: ToolCallState) => ToolCallState): ContentBlock[] {\r\n let changed = false;\r\n const newBlocks = blocks.map(b => {\r\n if (b.type === 'tool' && b.toolCall.id === toolId) {\r\n const updatedTc = updater(b.toolCall);\r\n if (updatedTc === b.toolCall) return b;\r\n changed = true;\r\n return { type: 'tool' as const, toolCall: updatedTc };\r\n }\r\n return b;\r\n });\r\n return changed ? newBlocks : blocks;\r\n}\r\n\r\nexport function tuiReducer(state: TuiState, action: TuiAction): TuiState {\r\n switch (action.type) {\r\n case 'ADD_USER_MESSAGE':\r\n return {\r\n ...state,\r\n messages: [\r\n ...state.messages,\r\n {\r\n id: nextId(),\r\n role: 'user',\r\n blocks: [{ type: 'text', text: action.text }],\r\n isStreaming: false,\r\n },\r\n ],\r\n };\r\n\r\n case 'START_ASSISTANT':\r\n return {\r\n ...state,\r\n error: undefined,\r\n messages: [\r\n ...state.messages,\r\n {\r\n id: nextId(),\r\n role: 'assistant',\r\n blocks: [],\r\n isStreaming: true,\r\n },\r\n ],\r\n };\r\n\r\n case 'APPEND_CONTENT': {\r\n if (!action.text) return state;\r\n const newMessages = updateLastAssistant(state.messages, (msg) => {\r\n const blocks = [...msg.blocks];\r\n const last = blocks[blocks.length - 1];\r\n if (last && last.type === 'text') {\r\n blocks[blocks.length - 1] = { type: 'text', text: last.text + action.text };\r\n } else {\r\n blocks.push({ type: 'text', text: action.text });\r\n }\r\n return { ...msg, blocks };\r\n });\r\n if (newMessages === state.messages) return state;\r\n return { ...state, messages: newMessages };\r\n }\r\n\r\n case 'APPEND_THOUGHT': {\r\n if (!action.text) return state;\r\n const newMessages = updateLastAssistant(state.messages, (msg) => {\r\n const blocks = [...msg.blocks];\r\n const last = blocks[blocks.length - 1];\r\n if (last && last.type === 'thought') {\r\n blocks[blocks.length - 1] = { type: 'thought', text: last.text + action.text };\r\n } else {\r\n blocks.push({ type: 'thought', text: action.text });\r\n }\r\n return { ...msg, blocks };\r\n });\r\n if (newMessages === state.messages) return state;\r\n return { ...state, messages: newMessages };\r\n }\r\n\r\n case 'TOOL_EXECUTING': {\r\n const newMessages = updateLastAssistant(state.messages, (msg) => {\r\n const existingIdx = msg.blocks.findIndex(\r\n b => b.type === 'tool' && b.toolCall.id === action.id,\r\n );\r\n if (existingIdx >= 0) {\r\n const newBlocks = updateToolInBlocks(msg.blocks, action.id, tc => {\r\n if (tc.status === 'running' && JSON.stringify(tc.params) === JSON.stringify(action.params)) return tc;\r\n return { ...tc, status: 'running' as const, params: action.params };\r\n });\r\n if (newBlocks === msg.blocks) return msg;\r\n return { ...msg, blocks: newBlocks };\r\n }\r\n return {\r\n ...msg,\r\n blocks: [\r\n ...msg.blocks,\r\n {\r\n type: 'tool' as const,\r\n toolCall: {\r\n id: action.id,\r\n name: action.name,\r\n params: action.params,\r\n status: 'running' as const,\r\n },\r\n },\r\n ],\r\n };\r\n });\r\n \r\n if (newMessages === state.messages) return state;\r\n return { ...state, messages: newMessages };\r\n }\r\n\r\n case 'TOOL_STREAMING': {\r\n const { id, streamingContent, name } = action;\r\n const newMessages = updateLastAssistant(state.messages, (msg) => {\r\n const existingBlock = msg.blocks.find(\r\n b => b.type === 'tool' && b.toolCall.id === id,\r\n );\r\n if (existingBlock && existingBlock.type === 'tool' && existingBlock.toolCall.streamingContent === streamingContent) {\r\n return msg; // NO VISUAL CHANGE -> BAIL OUT\r\n }\r\n\r\n if (existingBlock) {\r\n return {\r\n ...msg,\r\n blocks: updateToolInBlocks(msg.blocks, id, tc => ({\r\n ...tc,\r\n streamingContent,\r\n })),\r\n };\r\n }\r\n return {\r\n ...msg,\r\n blocks: [\r\n ...msg.blocks,\r\n {\r\n type: 'tool' as const,\r\n toolCall: {\r\n id,\r\n name,\r\n params: {},\r\n status: 'running' as const,\r\n streamingContent,\r\n },\r\n },\r\n ],\r\n };\r\n });\r\n\r\n if (newMessages === state.messages) {\r\n return state;\r\n }\r\n return { ...state, messages: newMessages };\r\n }\r\n\r\n case 'TOOL_RESULT': {\r\n const newMessages = updateLastAssistant(state.messages, (msg) => {\r\n const newBlocks = updateToolInBlocks(msg.blocks, action.id, tc => {\r\n if (tc.status === 'done' && tc.resultSummary === action.resultSummary) return tc;\r\n return { ...tc, status: 'done' as const, resultSummary: action.resultSummary, resultContent: action.resultContent };\r\n });\r\n if (newBlocks === msg.blocks) return msg;\r\n return { ...msg, blocks: newBlocks };\r\n });\r\n \r\n if (newMessages === state.messages) return state;\r\n return { ...state, messages: newMessages };\r\n }\r\n\r\n case 'TOOL_DENIED': {\r\n const newMessages = updateLastAssistant(state.messages, (msg) => {\r\n const newBlocks = updateToolInBlocks(msg.blocks, action.id, tc => ({\r\n ...tc,\r\n status: 'denied' as const,\r\n denyFeedback: action.feedback,\r\n }));\r\n if (newBlocks === msg.blocks) return msg;\r\n return { ...msg, blocks: newBlocks };\r\n });\r\n if (newMessages === state.messages) return state;\r\n return { ...state, messages: newMessages };\r\n }\r\n\r\n case 'TOOL_CONFIRMING': {\r\n const newMessages = updateLastAssistant(state.messages, (msg) => ({\r\n ...msg,\r\n blocks: [\r\n ...msg.blocks,\r\n {\r\n type: 'tool' as const,\r\n toolCall: {\r\n id: action.id,\r\n name: action.name,\r\n params: action.params,\r\n status: 'confirming' as const,\r\n },\r\n },\r\n ],\r\n confirmPending: {\r\n toolName: action.name,\r\n params: action.params,\r\n resolve: action.resolve,\r\n },\r\n }));\r\n return { ...state, messages: newMessages };\r\n }\r\n\r\n case 'CONFIRM_RESPONDED': {\r\n const newMessages = updateLastAssistant(state.messages, (msg) => {\r\n if (!msg.confirmPending) return msg;\r\n return { ...msg, confirmPending: undefined };\r\n });\r\n if (newMessages === state.messages) return state;\r\n return { ...state, messages: newMessages };\r\n }\r\n\r\n case 'FINISH_STREAMING':\r\n const newMessages = updateLastAssistant(state.messages, (msg) => {\r\n if (!msg.isStreaming) return msg;\r\n return { ...msg, isStreaming: false };\r\n });\r\n if (newMessages === state.messages) return state;\r\n return { ...state, messages: newMessages };\r\n\r\n case 'SET_RUNNING':\r\n if (state.isRunning === action.running) return state;\r\n return { ...state, isRunning: action.running };\r\n\r\n case 'SET_ERROR':\r\n return { ...state, error: action.error, isRunning: false };\r\n\r\n case 'CLEAR_ERROR':\r\n if (state.error === undefined) return state;\r\n return { ...state, error: undefined };\r\n\r\n case 'CLEAR_MESSAGES':\r\n if (state.messages.length === 0) return state;\r\n return { ...state, messages: [] };\r\n\r\n case 'SET_TODO_PLAN':\r\n if (state.todoPlan === action.plan) return state;\r\n return { ...state, todoPlan: action.plan };\r\n\r\n case 'SET_SUB_AGENT_PROGRESS':\r\n if (JSON.stringify(state.subAgentProgress) === JSON.stringify(action.progress)) return state;\r\n return { ...state, subAgentProgress: action.progress };\r\n\r\n case 'BATCH':\r\n const newState = action.actions.reduce((s, a) => tuiReducer(s, a), state);\r\n return newState === state ? state : newState;\r\n\r\n default:\r\n return state;\r\n }\r\n}\r\n","import React from 'react';\r\nimport { Box, Text } from 'ink';\r\nimport type { ToolCallState } from '../state.js';\r\n\r\ninterface ToolCallLineProps {\r\n toolCall: ToolCallState;\r\n}\r\n\r\nexport function getToolParamSummary(name: string, params: Record<string, unknown>): string {\r\n switch (name) {\r\n case 'bash':\r\n return String(params['command'] || '').slice(0, 100);\r\n case 'read-file':\r\n case 'write-file':\r\n case 'edit-file':\r\n return String(params['path'] || '');\r\n case 'glob':\r\n case 'grep':\r\n return String(params['pattern'] || '');\r\n case 'spawn-agents': {\r\n const tasks = params['tasks'] as Array<{ description?: string }> | undefined;\r\n if (!tasks || tasks.length === 0) return '';\r\n return `${tasks.length} tasks: ${tasks.map(t => t.description || '?').join(' | ').slice(0, 100)}`;\r\n }\r\n case 'dispatch':\r\n return `${params['agent'] || '?'}: ${String(params['task'] || '').slice(0, 80)}`;\r\n default:\r\n const keys = Object.keys(params);\r\n if (keys.length === 0) return '';\r\n const val = params[keys[0]];\r\n if (val === null || val === undefined) return '';\r\n if (typeof val === 'string') return val.slice(0, 60);\r\n if (typeof val === 'number' || typeof val === 'boolean') return String(val);\r\n return JSON.stringify(val).slice(0, 60);\r\n }\r\n}\r\n\r\nfunction truncateContent(text: string, maxLines: number): string[] {\r\n const lines = text.split('\\n');\r\n const result: string[] = [];\r\n for (let line of lines) {\r\n if (result.length >= maxLines) break;\r\n // Replace tabs with spaces and strip \\r to avoid terminal width miscalculation\r\n result.push(line.replace(/\\r/g, '').replace(/\\t/g, ' '));\r\n }\r\n if (lines.length > maxLines) {\r\n result.push(`... (and ${lines.length - maxLines} more lines)`);\r\n }\r\n return result;\r\n}\r\n\r\nexport const ToolCallLine = React.memo(function ToolCallLine({ toolCall }: ToolCallLineProps) {\r\n const { name, params, status, resultContent, denyFeedback } = toolCall;\r\n const summary = getToolParamSummary(name, params);\r\n\r\n let borderColor = '#504945';\r\n let titleColor = '#fabd2f';\r\n let statusColor = '#fabd2f';\r\n let statusText = 'RUNNING';\r\n\r\n if (status === 'done') {\r\n borderColor = '#b8bb26';\r\n titleColor = '#b8bb26';\r\n statusColor = '#b8bb26';\r\n statusText = 'DONE';\r\n } else if (status === 'denied') {\r\n borderColor = '#fb4934';\r\n titleColor = '#fb4934';\r\n statusColor = '#fb4934';\r\n statusText = 'DENIED';\r\n } else if (status === 'confirming') {\r\n borderColor = '#fe8019';\r\n titleColor = '#fe8019';\r\n statusColor = '#fe8019';\r\n statusText = 'CONFIRM';\r\n }\r\n\r\n const contentLines = resultContent ? truncateContent(resultContent, 15) : [];\r\n\r\n return (\r\n <Box flexDirection=\"column\" marginTop={0} marginBottom={1} width=\"100%\">\r\n <Box\r\n flexDirection=\"column\"\r\n borderStyle=\"round\"\r\n borderColor={borderColor}\r\n paddingX={1}\r\n width=\"100%\"\r\n >\r\n <Box gap={1}>\r\n <Box backgroundColor={statusColor} width={9} justifyContent=\"center\">\r\n <Text color=\"#282828\" bold>{statusText}</Text>\r\n </Box>\r\n <Text color={titleColor} bold>{name.toUpperCase()}</Text>\r\n <Text color=\"#ebdbb2\" dimColor italic wrap=\"truncate-end\">{summary}</Text>\r\n </Box>\r\n\r\n {status === 'done' && contentLines.length > 0 && (\r\n <Box flexDirection=\"column\" marginTop={1}>\r\n {contentLines.map((line, i) => (\r\n <Text key={i} color=\"#ebdbb2\" wrap=\"truncate-end\">{line}</Text>\r\n ))}\r\n </Box>\r\n )}\r\n\r\n {status === 'denied' && denyFeedback && (\r\n <Box gap={1} marginTop={0}>\r\n <Text color=\"#fb4934\" bold>REASON:</Text>\r\n <Text color=\"#ebdbb2\">{denyFeedback}</Text>\r\n </Box>\r\n )}\r\n\r\n {status === 'confirming' && (\r\n <Box marginTop={0}>\r\n <Text color=\"#fe8019\" italic>Waiting for your permission...</Text>\r\n </Box>\r\n )}\r\n </Box>\r\n </Box>\r\n );\r\n});\r\n","import React, { useMemo } from 'react';\r\nimport { Box, Text, useStdout } from 'ink';\r\nimport { renderMarkdown } from '../../ui.js';\r\nimport type { ChatMessage } from '../state.js';\r\nimport { ToolCallLine } from './ToolCallLine.js';\r\n\r\ninterface MessageBubbleProps {\r\n message: ChatMessage;\r\n}\r\n\r\nconst MemoizedMarkdown = React.memo(({ text }: { text: string }) => {\r\n const { stdout } = useStdout();\r\n const rendered = useMemo(() => renderMarkdown(text), [text, stdout.columns]);\r\n return <Text>{rendered}</Text>;\r\n});\r\n\r\nconst MemoizedThought = React.memo(({ text, isStreaming }: { text: string; isStreaming: boolean }) => {\r\n // Avoid trimming during streaming to prevent text jumping as spaces are added\r\n const displayText = isStreaming ? text : text.trim();\r\n return <Text color=\"#928374\" italic>{displayText}</Text>;\r\n});\r\n\r\nexport const MessageBubble = React.memo(function MessageBubble({ message }: MessageBubbleProps) {\r\n const { role, blocks, isStreaming } = message;\r\n\r\n const isUser = role === 'user';\r\n const label = isUser ? 'USER' : 'AI';\r\n const labelBg = isUser ? '#b8bb26' : '#83a598';\r\n const labelFg = '#282828';\r\n const contentColor = isUser ? '#ebdbb2' : '#ebdbb2';\r\n\r\n return (\r\n <Box flexDirection=\"column\" marginBottom={1} width=\"100%\">\r\n <Box marginBottom={0}>\r\n <Box backgroundColor={labelBg} width={9} paddingLeft={1} marginRight={1}>\r\n <Text color={labelFg} bold>{label}</Text>\r\n </Box>\r\n {isStreaming && <Text color=\"#83a598\" dimColor italic>typing...</Text>}\r\n </Box>\r\n\r\n <Box flexDirection=\"column\" width=\"100%\">\r\n {blocks.map((block, i) => {\r\n if (block.type === 'text') {\r\n const text = block.text.trim();\r\n if (!text && !isStreaming) return null;\r\n \r\n return (\r\n <Box key={`text-${i}`} paddingLeft={2} marginBottom={i < blocks.length - 1 ? 1 : 0} width=\"100%\">\r\n {isUser ? (\r\n <Text color={contentColor}>{text}</Text>\r\n ) : (\r\n <MemoizedMarkdown text={text} />\r\n )}\r\n </Box>\r\n );\r\n } else if (block.type === 'thought') {\r\n return (\r\n <Box key={`thought-${i}`} flexDirection=\"column\" marginBottom={0} width=\"100%\">\r\n <Box gap={1} marginBottom={0}>\r\n <Box backgroundColor=\"#504945\" width={9} justifyContent=\"center\">\r\n <Text color=\"#a89984\" bold>THINK</Text>\r\n </Box>\r\n </Box>\r\n <Box paddingLeft={2} marginBottom={0}>\r\n <MemoizedThought text={block.text} isStreaming={isStreaming} />\r\n </Box>\r\n </Box>\r\n );\r\n } else {\r\n return (\r\n <Box key={block.toolCall.id} paddingLeft={2} width=\"100%\">\r\n <ToolCallLine toolCall={block.toolCall} />\r\n </Box>\r\n );\r\n }\r\n })}\r\n {blocks.length === 0 && isStreaming && (\r\n <Box paddingLeft={2}>\r\n <Text dimColor>...</Text>\r\n </Box>\r\n )}\r\n </Box>\r\n </Box>\r\n );\r\n});\r\n","import React from 'react';\r\nimport { Box, Text, useStdout } from 'ink';\r\n\r\ninterface HeaderProps {\r\n modelName: string;\r\n}\r\n\r\nexport function Header({ modelName }: HeaderProps) {\r\n const { stdout } = useStdout();\r\n // ZenCode ASCII Logo (Small & Clean)\r\n const logo = [\r\n ' ███████╗███████╗███╗ ██╗ ██████╗ ██████╗ ██████╗ ███████╗',\r\n ' ╚══███╔╝██╔════╝████╗ ██║██╔════╝ ██╔═══██╗██╔══██╗██╔════╝',\r\n ' ███╔╝ █████╗ ██╔██╗ ██║██║ ██║ ██║██║ ██║█████╗ ',\r\n ' ███╔╝ ██╔══╝ ██║╚██╗██║██║ ██║ ██║██║ ██║██╔══╝ ',\r\n ' ███████╗███████╗██║ ╚████║╚██████╗ ╚██████╔╝██████╔╝███████╗',\r\n ' ╚══════╝╚══════╝╚═╝ ╚═══╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝',\r\n ];\r\n\r\n // Parent App has paddingLeft=1 + paddingRight=1, so available width = columns - 2\r\n const width = (stdout?.columns ?? 80) - 2;\r\n\r\n return (\r\n <Box\r\n flexDirection=\"column\"\r\n width={width}\r\n borderStyle=\"round\"\r\n borderColor=\"#504945\"\r\n paddingX={1}\r\n marginTop={0}\r\n marginBottom={1}\r\n >\r\n <Box flexDirection=\"column\" marginBottom={1} alignItems=\"center\">\r\n {logo.map((line, i) => (\r\n <Text key={i} color=\"#fe8019\" bold>\r\n {line}\r\n </Text>\r\n ))}\r\n </Box>\r\n\r\n <Box justifyContent=\"space-between\" borderStyle=\"single\" borderTop={true} borderBottom={false} borderLeft={false} borderRight={false} borderColor=\"#3c3836\" paddingTop={0}>\r\n <Box gap={1}>\r\n <Text bold color=\"#fabd2f\">ZEN CODE</Text>\r\n <Text color=\"#a89984\" dimColor>v0.4.1</Text>\r\n </Box>\r\n <Text color=\"#83a598\" bold>{modelName}</Text>\r\n </Box>\r\n </Box>\r\n );\r\n}\r\n","import React, { useMemo } from 'react';\r\nimport { Box, Static, useStdout } from 'ink';\r\nimport type { ChatMessage } from '../state.js';\r\nimport { MessageBubble } from './MessageBubble.js';\r\nimport { Header } from './Header.js';\r\n\r\ninterface ChatAreaProps {\r\n messages: ChatMessage[];\r\n modelName: string;\r\n}\r\n\r\n// 定义一个稳定的 Header 项引用,防止 Static 组件重复渲染它\r\nconst HEADER_ITEM = { id: 'static-header', isHeader: true };\r\n\r\nexport const ChatArea = React.memo(function ChatArea({ messages, modelName }: ChatAreaProps) {\r\n const completedMessages = messages.filter(m => !m.isStreaming);\r\n const activeMessages = messages.filter(m => m.isStreaming);\r\n\r\n // Only update static items when the number of completed messages changes\r\n // or when an assistant message finishes streaming.\r\n const completedCount = completedMessages.length;\r\n const lastCompletedId = completedMessages[completedMessages.length - 1]?.id;\r\n\r\n // 构造稳定引用的静态项列表\r\n const staticItems = useMemo(() => [\r\n HEADER_ITEM,\r\n ...completedMessages\r\n ], [completedCount, lastCompletedId]);\r\n\r\n return (\r\n <Box flexDirection=\"column\" width=\"100%\">\r\n <Static items={staticItems}>\r\n {(item: any) => {\r\n if (item.isHeader) {\r\n return <Header key=\"header\" modelName={modelName} />;\r\n }\r\n return <MessageBubble key={item.id} message={item} />;\r\n }}\r\n </Static>\r\n {activeMessages.map((msg) => (\r\n <MessageBubble key={msg.id} message={msg} />\r\n ))}\r\n </Box>\r\n );\r\n}, (prev, next) => {\r\n return prev.messages === next.messages && prev.modelName === next.modelName;\r\n});\r\n","import React, { useRef, useState } from 'react';\r\nimport { Box, Text, useInput, useStdout } from 'ink';\r\n\r\ninterface InputAreaProps {\r\n onSubmit: (text: string) => void;\r\n isRunning: boolean;\r\n onExitRequest: () => void;\r\n onScroll?: (direction: 'up' | 'down') => void;\r\n}\r\n\r\n/**\r\n * Custom text input that only accepts printable characters.\r\n */\r\nfunction CleanTextInput({\r\n onSubmit,\r\n placeholder,\r\n onExitRequest,\r\n onScroll\r\n}: {\r\n onSubmit: (text: string) => void;\r\n placeholder?: string;\r\n onExitRequest: () => void;\r\n onScroll?: (direction: 'up' | 'down') => void;\r\n}) {\r\n const [value, setValue] = useState('');\r\n const [cursor, setCursor] = useState(0);\r\n const lastCtrlCAtRef = useRef(0);\r\n const pastedTextsRef = useRef<string[]>([]);\r\n\r\n useInput((input, key) => {\r\n // Scroll handling\r\n if (onScroll) {\r\n if (key.pageUp || (key.upArrow && key.shift)) {\r\n onScroll('up');\r\n return;\r\n }\r\n if (key.pageDown || (key.downArrow && key.shift)) {\r\n onScroll('down');\r\n return;\r\n }\r\n }\r\n\r\n if (input === 'c' && key.ctrl) {\r\n if (value.length > 0) {\r\n setValue('');\r\n setCursor(0);\r\n lastCtrlCAtRef.current = 0;\r\n pastedTextsRef.current = [];\r\n return;\r\n }\r\n\r\n const now = Date.now();\r\n const isDoublePress = now - lastCtrlCAtRef.current <= 1200;\r\n if (isDoublePress) {\r\n onExitRequest();\r\n lastCtrlCAtRef.current = 0;\r\n } else {\r\n lastCtrlCAtRef.current = now;\r\n }\r\n return;\r\n }\r\n\r\n if (key.return) {\r\n let trimmed = value.trim();\r\n if (trimmed) {\r\n // Expand [pasted text#N] placeholders with actual stored text\r\n const stored = pastedTextsRef.current;\r\n trimmed = trimmed.replace(/\\[pasted text#(\\d+)\\]/g, (_match, numStr) => {\r\n const idx = parseInt(numStr, 10) - 1;\r\n return idx >= 0 && idx < stored.length ? stored[idx] : _match;\r\n });\r\n onSubmit(trimmed);\r\n }\r\n setValue('');\r\n setCursor(0);\r\n pastedTextsRef.current = [];\r\n return;\r\n }\r\n if (key.backspace || key.delete) {\r\n if (cursor > 0) {\r\n setValue(prev => prev.slice(0, cursor - 1) + prev.slice(cursor));\r\n setCursor(prev => prev - 1);\r\n }\r\n return;\r\n }\r\n if (key.leftArrow) { setCursor(prev => Math.max(0, prev - 1)); return; }\r\n if (key.rightArrow) { setCursor(prev => Math.min(value.length, prev + 1)); return; }\r\n if (input === 'a' && key.ctrl) { setCursor(0); return; }\r\n if (input === 'e' && key.ctrl) { setCursor(value.length); return; }\r\n if (input === 'u' && key.ctrl) { setValue(prev => prev.slice(cursor)); setCursor(0); return; }\r\n\r\n // Multi-line paste detection\r\n if (input.includes('\\n') || input.includes('\\r')) {\r\n // Clean escape sequences and normalize newlines\r\n const cleaned = input\r\n .replace(/\\x1b\\[[0-9;]*[A-Za-z]/g, '')\r\n .replace(/\\r\\n/g, '\\n')\r\n .replace(/\\r/g, '\\n')\r\n .trim();\r\n if (cleaned.length > 0) {\r\n pastedTextsRef.current.push(cleaned);\r\n const placeholder = `[pasted text#${pastedTextsRef.current.length}]`;\r\n setValue(prev => prev.slice(0, cursor) + placeholder + prev.slice(cursor));\r\n setCursor(prev => prev + placeholder.length);\r\n }\r\n return;\r\n }\r\n\r\n if (key.ctrl || key.meta || key.escape) return;\r\n if (!input || input.length === 0) return;\r\n if (input.includes('\\x1b') || input.includes('\\x00')) return;\r\n\r\n // Filter out some common terminal escape sequences\r\n if (/^(?:\\[<\\d+;\\d+;\\d+[Mm])+$/.test(input)) return;\r\n if (/^\\[<[0-9;Mm]*$/.test(input)) return;\r\n if (input === '[5~' || input === '[6~') return;\r\n\r\n for (let i = 0; i < input.length; i++) {\r\n const code = input.charCodeAt(i);\r\n if (code < 0x20 && code !== 0x09) return;\r\n if (code === 0x7f || (code >= 0x80 && code <= 0x9f)) return;\r\n }\r\n\r\n setValue(prev => prev.slice(0, cursor) + input + prev.slice(cursor));\r\n setCursor(prev => prev + input.length);\r\n });\r\n\r\n if (value.length === 0) {\r\n return (\r\n <Text wrap=\"wrap\">\r\n <Text inverse> </Text>\r\n <Text dimColor>{placeholder || ''}</Text>\r\n </Text>\r\n );\r\n }\r\n\r\n const before = value.slice(0, cursor);\r\n const at = cursor < value.length ? value[cursor] : ' ';\r\n const after = cursor < value.length ? value.slice(cursor + 1) : '';\r\n\r\n return (\r\n <Text wrap=\"wrap\">\r\n {before}<Text inverse>{at}</Text>{after}\r\n </Text>\r\n );\r\n}\r\n\r\nexport const InputArea = React.memo(function InputArea({ onSubmit, isRunning, onExitRequest, onScroll }: InputAreaProps) {\r\n const { stdout } = useStdout();\r\n // Label box: paddingX(1) + \" INPUT \"(7) + paddingX(1) = 9 cols, + marginRight(1) = 10\r\n const labelCols = 10;\r\n const textWidth = (stdout?.columns ?? 80) - 2 - labelCols;\r\n\r\n return (\r\n <Box paddingX={0}>\r\n <Box backgroundColor={isRunning ? \"#504945\" : \"#b8bb26\"} paddingX={1} marginRight={1}>\r\n <Text color=\"#282828\" bold>{isRunning ? \" WAIT \" : \" INPUT \"}</Text>\r\n </Box>\r\n <Box width={textWidth}>\r\n {isRunning ? (\r\n <Text color=\"#a89984\" italic>Thinking...</Text>\r\n ) : (\r\n <CleanTextInput\r\n onSubmit={onSubmit}\r\n placeholder=\"Type a message or /command...\"\r\n onExitRequest={onExitRequest}\r\n onScroll={onScroll}\r\n />\r\n )}\r\n </Box>\r\n </Box>\r\n );\r\n});\r\n","import React, { useEffect, useState } from 'react';\r\nimport { Box, Text } from 'ink';\r\nimport type { TodoPlan } from '../../../core/todo-store.js';\r\nimport type { SubAgentProgress } from '../../../core/sub-agent-tracker.js';\r\nimport { progressStore, type StreamingProgress } from '../stores/progressStore.js';\r\n\r\ninterface StatusBarProps {\r\n isRunning: boolean;\r\n modelName: string;\r\n todoPlan?: TodoPlan | null;\r\n subAgentProgress?: SubAgentProgress | null;\r\n}\r\n\r\nfunction formatTokens(n: number): string {\r\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\r\n if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`;\r\n return String(n);\r\n}\r\n\r\nexport const StatusBar = React.memo(function StatusBar({ isRunning, modelName, todoPlan, subAgentProgress }: StatusBarProps) {\r\n const [activeStreamingTool, setActiveStreamingTool] = useState<StreamingProgress | undefined>(progressStore.get());\r\n\r\n useEffect(() => {\r\n const handleUpdate = (progress?: StreamingProgress) => {\r\n setActiveStreamingTool(progress);\r\n };\r\n progressStore.on('change', handleUpdate);\r\n return () => { progressStore.off('change', handleUpdate); };\r\n }, []);\r\n\r\n const todoProgress = todoPlan\r\n ? `${todoPlan.items.filter((i) => i.status === 'completed').length}/${todoPlan.items.length}`\r\n : null;\r\n\r\n return (\r\n <Box marginTop={1} height={1} width=\"100%\">\r\n <Box backgroundColor=\"#3c3836\" paddingX={1} flexShrink={0}>\r\n <Text color=\"#ebdbb2\" bold>ZENCODE</Text>\r\n </Box>\r\n\r\n <Box backgroundColor=\"#504945\" paddingX={1} flexGrow={1} flexBasis={0}>\r\n <Text color=\"#ebdbb2\" wrap=\"truncate-end\">{modelName}</Text>\r\n\r\n {isRunning && !subAgentProgress && !activeStreamingTool && (\r\n <>\r\n <Text color=\"#ebdbb2\"> │ </Text>\r\n <Text color=\"#8ec07c\">● thinking...</Text>\r\n </>\r\n )}\r\n\r\n {activeStreamingTool && (\r\n <>\r\n <Text color=\"#ebdbb2\"> │ </Text>\r\n <Text color=\"#fabd2f\" wrap=\"truncate-end\">● {activeStreamingTool.name}: {activeStreamingTool.progress}</Text>\r\n </>\r\n )}\r\n\r\n {subAgentProgress && (\r\n <>\r\n <Text color=\"#ebdbb2\"> │ </Text>\r\n <Text color=\"#b8bb26\">Agents: {subAgentProgress.completed + subAgentProgress.failed}/{subAgentProgress.total}</Text>\r\n <Text color=\"#ebdbb2\"> │ </Text>\r\n <Text color=\"#83a598\">tokens: {formatTokens(subAgentProgress.tokens)}</Text>\r\n </>\r\n )}\r\n\r\n {todoProgress && (\r\n <>\r\n <Text color=\"#ebdbb2\"> │ </Text>\r\n <Text color=\"#fabd2f\">Plan: {todoProgress}</Text>\r\n </>\r\n )}\r\n </Box>\r\n\r\n <Box backgroundColor=\"#3c3836\" paddingX={1} flexShrink={0}>\r\n <Text color=\"#ebdbb2\">/help</Text>\r\n </Box>\r\n </Box>\r\n );\r\n});\r\n","import React, { useState } from 'react';\r\nimport { Box, Text, useInput } from 'ink';\r\nimport type { ConfirmPending, ConfirmResult } from '../state.js';\r\n\r\ninterface ConfirmPromptProps {\r\n confirm: ConfirmPending;\r\n onRespond: (result: ConfirmResult) => void;\r\n}\r\n\r\nconst OPTIONS: { key: 'allow' | 'always' | 'deny'; label: string }[] = [\r\n { key: 'allow', label: '允许' },\r\n { key: 'always', label: '始终允许' },\r\n { key: 'deny', label: '拒绝' },\r\n];\r\n\r\nfunction getToolDetails(toolName: string, params: Record<string, unknown>): { lines: string[]; label: string } {\r\n const lines: string[] = [];\r\n let label = toolName;\r\n\r\n switch (toolName) {\r\n case 'bash':\r\n label = 'Bash';\r\n lines.push(`命令: ${String(params['command'] || '')}`);\r\n break;\r\n case 'write-file':\r\n label = 'Write';\r\n lines.push(`文件: ${String(params['path'] || '')}`);\r\n if (params['content']) {\r\n const content = String(params['content']);\r\n const preview = content.length > 120 ? content.slice(0, 120) + '...' : content;\r\n lines.push(`内容: ${preview.split('\\n').slice(0, 3).join('\\n ')}`);\r\n }\r\n break;\r\n case 'edit-file':\r\n label = 'Edit';\r\n lines.push(`文件: ${String(params['path'] || '')}`);\r\n if (params['old_string']) {\r\n const old = String(params['old_string']);\r\n const preview = old.length > 80 ? old.slice(0, 80) + '...' : old;\r\n lines.push(`替换: ${preview}`);\r\n }\r\n if (params['new_string']) {\r\n const neu = String(params['new_string']);\r\n const preview = neu.length > 80 ? neu.slice(0, 80) + '...' : neu;\r\n lines.push(`为: ${preview}`);\r\n }\r\n break;\r\n case 'git':\r\n label = 'Git';\r\n lines.push(`命令: git ${String(params['command'] || '')}`);\r\n break;\r\n default:\r\n for (const [key, value] of Object.entries(params)) {\r\n const str = typeof value === 'string' ? value : JSON.stringify(value);\r\n lines.push(`${key}: ${str.slice(0, 80)}`);\r\n }\r\n break;\r\n }\r\n\r\n return { lines, label };\r\n}\r\n\r\n/** Minimal clean text input — only accepts printable chars, ignores escape sequences */\r\nfunction FeedbackInput({ onSubmit }: { onSubmit: (text: string) => void }) {\r\n const [value, setValue] = useState('');\r\n const [cursor, setCursor] = useState(0);\r\n\r\n useInput((input, key) => {\r\n if (key.return) {\r\n onSubmit(value);\r\n setValue('');\r\n setCursor(0);\r\n return;\r\n }\r\n if (key.backspace || key.delete) {\r\n if (cursor > 0) {\r\n setValue(prev => prev.slice(0, cursor - 1) + prev.slice(cursor));\r\n setCursor(prev => prev - 1);\r\n }\r\n return;\r\n }\r\n if (key.leftArrow) { setCursor(prev => Math.max(0, prev - 1)); return; }\r\n if (key.rightArrow) { setCursor(prev => Math.min(value.length, prev + 1)); return; }\r\n if (key.escape) { onSubmit(''); return; } // Escape cancels feedback\r\n\r\n if (key.ctrl || key.meta) return;\r\n if (!input || input.length === 0) return;\r\n if (input.includes('\\x1b') || input.includes('\\x00')) return;\r\n for (let i = 0; i < input.length; i++) {\r\n const code = input.charCodeAt(i);\r\n if (code < 0x20) return;\r\n if (code === 0x7f || (code >= 0x80 && code <= 0x9f)) return;\r\n }\r\n\r\n setValue(prev => prev.slice(0, cursor) + input + prev.slice(cursor));\r\n setCursor(prev => prev + input.length);\r\n });\r\n\r\n if (value.length === 0) {\r\n return (\r\n <>\r\n <Text inverse> </Text>\r\n <Text dimColor>输入反馈指令给 AI...</Text>\r\n </>\r\n );\r\n }\r\n\r\n const before = value.slice(0, cursor);\r\n const at = cursor < value.length ? value[cursor] : ' ';\r\n const after = cursor < value.length ? value.slice(cursor + 1) : '';\r\n\r\n return (\r\n <>\r\n <Text>{before}</Text>\r\n <Text inverse>{at}</Text>\r\n <Text>{after}</Text>\r\n </>\r\n );\r\n}\r\n\r\nexport function ConfirmPrompt({ confirm, onRespond }: ConfirmPromptProps) {\r\n const [selected, setSelected] = useState(0);\r\n const [feedbackMode, setFeedbackMode] = useState(false);\r\n\r\n useInput((input, key) => {\r\n if (feedbackMode) return;\r\n\r\n if (key.leftArrow) {\r\n setSelected((prev) => (prev - 1 + OPTIONS.length) % OPTIONS.length);\r\n } else if (key.rightArrow) {\r\n setSelected((prev) => (prev + 1) % OPTIONS.length);\r\n }\r\n else if (key.return) {\r\n onRespond(OPTIONS[selected]!.key);\r\n }\r\n else if (input === 'y' || input === 'Y') {\r\n onRespond('allow');\r\n } else if (input === 'n' || input === 'N') {\r\n onRespond('deny');\r\n } else if (input === 'a' || input === 'A') {\r\n onRespond('always');\r\n }\r\n else if (key.tab) {\r\n setFeedbackMode(true);\r\n }\r\n else if (key.escape) {\r\n onRespond('deny');\r\n }\r\n }, { isActive: !feedbackMode });\r\n\r\n const { lines, label } = getToolDetails(confirm.toolName, confirm.params);\r\n\r\n if (feedbackMode) {\r\n return (\r\n <Box flexDirection=\"column\" paddingX={0} marginY={0}>\r\n <Box backgroundColor=\"#fe8019\" paddingX={1}>\r\n <Text color=\"#282828\" bold> FEEDBACK </Text>\r\n </Box>\r\n <Box\r\n flexDirection=\"column\"\r\n borderStyle=\"round\"\r\n borderColor=\"#fe8019\"\r\n paddingX={1}\r\n >\r\n <Text bold color=\"#fabd2f\">{label}</Text>\r\n {lines.map((line, i) => (\r\n <Text key={i} color=\"#a89984\">{line}</Text>\r\n ))}\r\n <Box marginTop={0} gap={1}>\r\n <Text color=\"#83a598\" bold>Reason: </Text>\r\n <FeedbackInput\r\n onSubmit={(text) => {\r\n const trimmed = text.trim();\r\n if (trimmed) {\r\n onRespond({ feedback: trimmed });\r\n } else {\r\n setFeedbackMode(false);\r\n }\r\n }}\r\n />\r\n </Box>\r\n </Box>\r\n <Box paddingX={1}>\r\n <Text dimColor>Enter to send · Esc to cancel</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n return (\r\n <Box flexDirection=\"column\" paddingX={0} marginY={0}>\r\n <Box backgroundColor=\"#fe8019\" paddingX={1}>\r\n <Text color=\"#282828\" bold> CONFIRMATION REQUIRED </Text>\r\n </Box>\r\n <Box\r\n flexDirection=\"column\"\r\n borderStyle=\"round\"\r\n borderColor=\"#fe8019\"\r\n paddingX={1}\r\n >\r\n <Text bold color=\"#fabd2f\">{label}</Text>\r\n {lines.map((line, i) => (\r\n <Text key={i} color=\"#a89984\">{line}</Text>\r\n ))}\r\n\r\n <Box marginTop={0} gap={2} justifyContent=\"center\">\r\n {OPTIONS.map((opt, i) => {\r\n const isSelected = i === selected;\r\n const optColor = opt.key === 'deny' ? '#fb4934' : opt.key === 'allow' ? '#b8bb26' : '#8ec07c';\r\n return (\r\n <Box key={opt.key}>\r\n {isSelected ? (\r\n <Text bold backgroundColor={optColor} color=\"#282828\"> {opt.label} </Text>\r\n ) : (\r\n <Text color={optColor}> {opt.label} </Text>\r\n )}\r\n </Box>\r\n );\r\n })}\r\n </Box>\r\n </Box>\r\n\r\n <Box paddingX={1}>\r\n <Text dimColor>\r\n ← → select · Enter confirm · y/n shortcuts · Tab feedback\r\n </Text>\r\n </Box>\r\n </Box>\r\n );\r\n}\r\n","import React from 'react';\r\nimport { Box, Text } from 'ink';\r\nimport type { TodoPlan } from '../../../core/todo-store.js';\r\n\r\ninterface TodoPanelProps {\r\n plan: TodoPlan;\r\n}\r\n\r\nfunction getStatusIcon(status: string): string {\r\n switch (status) {\r\n case 'completed':\r\n return '*';\r\n case 'in-progress':\r\n return '>';\r\n default:\r\n return ' ';\r\n }\r\n}\r\n\r\nfunction getStatusColor(status: string): string {\r\n switch (status) {\r\n case 'completed':\r\n return '#b8bb26';\r\n case 'in-progress':\r\n return '#fabd2f';\r\n default:\r\n return '#928374';\r\n }\r\n}\r\n\r\nexport const TodoPanel = React.memo(function TodoPanel({ plan }: TodoPanelProps) {\r\n const completed = plan.items.filter((i) => i.status === 'completed').length;\r\n const total = plan.items.length;\r\n\r\n return (\r\n <Box\r\n flexDirection=\"column\"\r\n borderStyle=\"round\"\r\n borderColor=\"#83a598\"\r\n paddingX={1}\r\n marginY={0}\r\n width=\"100%\"\r\n >\r\n <Box justifyContent=\"space-between\" marginBottom={0}>\r\n <Text bold color=\"#83a598\">\r\n PROJECT PLAN\r\n </Text>\r\n <Text color=\"#ebdbb2\">\r\n {completed}/{total} tasks\r\n </Text>\r\n </Box>\r\n {plan.items.map((item) => (\r\n <Box key={item.id} gap={0}>\r\n <Text color={getStatusColor(item.status)}>\r\n [{getStatusIcon(item.status)}]\r\n </Text>\r\n <Text> </Text>\r\n <Text\r\n color={item.status === 'completed' ? '#b8bb26' : item.status === 'in-progress' ? '#fabd2f' : '#ebdbb2'}\r\n dimColor={item.status === 'pending'}\r\n strikethrough={item.status === 'completed'}\r\n >\r\n {item.title}\r\n </Text>\r\n </Box>\r\n ))}\r\n </Box>\r\n );\r\n}, (prev, next) => {\r\n // 核心优化:只要计划没变,无论外界状态怎么跳动,绝不重绘\r\n return prev.plan === next.plan;\r\n});\r\n","import React, { useReducer, useCallback, useEffect, useRef, useState } from 'react';\r\nimport { Box, Text, useInput, useStdout } from 'ink';\r\nimport type { ZenCodeConfig } from '../../config/types.js';\r\nimport type { Agent } from '../../core/agent.js';\r\nimport type { ToolRegistry } from '../../tools/registry.js';\r\nimport type { TodoStore } from '../../core/todo-store.js';\r\nimport type { SubAgentTracker } from '../../core/sub-agent-tracker.js';\r\nimport type { SubAgentConfigRegistry } from '../../core/sub-agents/registry.js';\r\nimport type { SkillRegistry } from '../../core/skills/registry.js';\r\nimport { isAbortError, type LLMClient } from '../../llm/client.js';\r\nimport { setStructuredConfirmHandler } from '../../tools/permission.js';\r\nimport type { ConfirmExecutionResult } from '../../tools/permission.js';\r\nimport { tuiReducer, createInitialState, type TuiAction, type ConfirmPending, type ConfirmResult } from './state.js';\r\nimport { createBridgeCallbacks, registerConfirmToolId } from './bridge.js';\r\nimport { createSpawnAgentsTool } from '../../tools/spawn-agents.js';\r\nimport { createTodoTool } from '../../tools/todo.js';\r\nimport { ChatArea } from './components/ChatArea.js';\r\nimport { InputArea } from './components/InputArea.js';\r\nimport { StatusBar } from './components/StatusBar.js';\r\nimport { ConfirmPrompt } from './components/ConfirmPrompt.js';\r\nimport { TodoPanel } from './components/TodoPanel.js';\r\n\r\ninterface AppProps {\r\n config: ZenCodeConfig;\r\n client: LLMClient;\r\n agent: Agent;\r\n registry: ToolRegistry;\r\n todoStore: TodoStore;\r\n subAgentTracker: SubAgentTracker;\r\n agentRegistry: SubAgentConfigRegistry;\r\n skillRegistry: SkillRegistry;\r\n}\r\n\r\nexport function App({ config, client, agent, registry, todoStore, subAgentTracker, agentRegistry, skillRegistry }: AppProps) {\r\n const { stdout } = useStdout();\r\n // Reset counter: forces full re-mount when /clear is used or terminal resizes\r\n const [resetKey, setResetKey] = useState(0);\r\n\r\n useEffect(() => {\r\n let timer: ReturnType<typeof setTimeout>;\r\n let lastCols = stdout.columns;\r\n let lastRows = stdout.rows;\r\n\r\n const onResize = () => {\r\n if (stdout.columns === lastCols && stdout.rows === lastRows) return;\r\n lastCols = stdout.columns;\r\n lastRows = stdout.rows;\r\n\r\n clearTimeout(timer);\r\n timer = setTimeout(() => {\r\n // Clear terminal (screen + scrollback) and home cursor\r\n process.stdout.write('\\x1b[2J\\x1b[3J\\x1b[H');\r\n setResetKey(prev => prev + 1);\r\n }, 100);\r\n };\r\n stdout.on('resize', onResize);\r\n return () => {\r\n stdout.off('resize', onResize);\r\n clearTimeout(timer);\r\n };\r\n }, [stdout]);\r\n\r\n const [state, dispatch] = useReducer(\r\n tuiReducer,\r\n createInitialState(config.model),\r\n );\r\n\r\n const currentCallbacksRef = useRef<(ReturnType<typeof createBridgeCallbacks> & { _stopBatcher?: () => void }) | null>(null);\r\n\r\n const agentRef = useRef(agent);\r\n const todoStoreRef = useRef(todoStore);\r\n const subAgentTrackerRef = useRef(subAgentTracker);\r\n agentRef.current = agent;\r\n todoStoreRef.current = todoStore;\r\n subAgentTrackerRef.current = subAgentTracker;\r\n\r\n // Subscribe to TodoStore changes\r\n useEffect(() => {\r\n return todoStoreRef.current.subscribe((plan) => {\r\n dispatch({ type: 'SET_TODO_PLAN', plan });\r\n });\r\n }, []);\r\n\r\n // Subscribe to SubAgentTracker changes (throttled to reduce re-renders)\r\n useEffect(() => {\r\n let timer: ReturnType<typeof setTimeout> | null = null;\r\n let latest: import('../../core/sub-agent-tracker.js').SubAgentProgress | null = null;\r\n\r\n const unsub = subAgentTrackerRef.current.subscribe((progress) => {\r\n latest = progress;\r\n if (progress === null) {\r\n if (timer) { clearTimeout(timer); timer = null; }\r\n dispatch({ type: 'SET_SUB_AGENT_PROGRESS', progress: null });\r\n return;\r\n }\r\n if (!timer) {\r\n dispatch({ type: 'SET_SUB_AGENT_PROGRESS', progress });\r\n timer = setTimeout(() => {\r\n timer = null;\r\n if (latest) dispatch({ type: 'SET_SUB_AGENT_PROGRESS', progress: latest });\r\n }, 2000);\r\n }\r\n });\r\n\r\n return () => { unsub(); if (timer) clearTimeout(timer); };\r\n }, []);\r\n\r\n // Find active confirm pending\r\n const confirmPending = state.messages.reduce<ConfirmPending | undefined>(\r\n (found, msg) => found || msg.confirmPending,\r\n undefined,\r\n );\r\n\r\n // --- Register structured confirm handler ---\r\n useEffect(() => {\r\n setStructuredConfirmHandler((toolName, params) => {\r\n return new Promise<ConfirmExecutionResult>((resolve) => {\r\n const id = `confirm-${Date.now()}`;\r\n registerConfirmToolId(toolName, id);\r\n dispatch({\r\n type: 'TOOL_CONFIRMING',\r\n id,\r\n name: toolName,\r\n params,\r\n resolve: (result: ConfirmResult) => {\r\n if (result === 'always') {\r\n registry.addAutoApprove(toolName);\r\n resolve({ approved: true });\r\n } else if (result === 'allow') {\r\n resolve({ approved: true });\r\n } else if (result === 'deny') {\r\n resolve({ approved: false });\r\n } else {\r\n resolve({ approved: false, feedback: result.feedback });\r\n }\r\n },\r\n });\r\n });\r\n });\r\n return () => { setStructuredConfirmHandler(null); };\r\n }, [registry]);\r\n\r\n // --- Run agent with a message ---\r\n const runAgent = useCallback(async (text: string) => {\r\n dispatch({ type: 'ADD_USER_MESSAGE', text });\r\n dispatch({ type: 'START_ASSISTANT' });\r\n dispatch({ type: 'SET_RUNNING', running: true });\r\n\r\n const callbacks = createBridgeCallbacks(dispatch);\r\n currentCallbacksRef.current = callbacks as ReturnType<typeof createBridgeCallbacks> & { _stopBatcher?: () => void };\r\n\r\n try {\r\n await agentRef.current.run(text, callbacks);\r\n } catch (err) {\r\n if (!isAbortError(err)) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n dispatch({ type: 'SET_ERROR', error: msg });\r\n }\r\n } finally {\r\n currentCallbacksRef.current = null;\r\n }\r\n\r\n (callbacks as any)._stopBatcher?.();\r\n dispatch({ type: 'FINISH_STREAMING' });\r\n dispatch({ type: 'SET_RUNNING', running: false });\r\n }, []);\r\n\r\n // --- Handle user message submission ---\r\n const handleSubmit = useCallback(async (text: string) => {\r\n if (text.startsWith('/')) {\r\n // Check if it's a user-defined skill first\r\n const parts = text.slice(1).split(/\\s+/);\r\n const skillName = parts[0]!;\r\n const skillArgs = parts.slice(1).join(' ');\r\n const skill = skillRegistry.get(skillName);\r\n\r\n if (skill) {\r\n // Execute skill: expand prompt and send to agent\r\n const expandedPrompt = skillRegistry.expandPrompt(skill, skillArgs);\r\n await runAgent(expandedPrompt);\r\n return;\r\n }\r\n\r\n // Otherwise handle built-in slash commands\r\n handleSlashCommand(text, {\r\n config, agent: agentRef.current, registry, dispatch, setResetKey,\r\n client, todoStore, subAgentTracker, agentRegistry, skillRegistry,\r\n });\r\n return;\r\n }\r\n\r\n await runAgent(text);\r\n }, [config, runAgent]);\r\n\r\n // --- Handle confirm response ---\r\n const handleConfirmResponse = useCallback((result: ConfirmResult) => {\r\n if (confirmPending) {\r\n confirmPending.resolve(result);\r\n dispatch({ type: 'CONFIRM_RESPONDED', id: '' });\r\n const approved = result === 'allow' || result === 'always';\r\n if (approved) {\r\n for (const msg of state.messages) {\r\n for (const block of msg.blocks) {\r\n if (block.type === 'tool' && block.toolCall.status === 'confirming') {\r\n dispatch({ type: 'TOOL_EXECUTING', id: block.toolCall.id, name: block.toolCall.name, params: block.toolCall.params });\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }, [confirmPending, state.messages]);\r\n\r\n // --- Keyboard shortcuts ---\r\n useInput((input, key) => {\r\n if (key.escape) {\r\n if (state.isRunning) {\r\n agentRef.current.interrupt();\r\n currentCallbacksRef.current?._stopBatcher?.();\r\n dispatch({ type: 'SET_RUNNING', running: false });\r\n dispatch({ type: 'FINISH_STREAMING' });\r\n }\r\n return;\r\n }\r\n\r\n if (input === 'c' && key.ctrl) {\r\n if (state.isRunning || confirmPending) {\r\n agentRef.current.interrupt();\r\n currentCallbacksRef.current?._stopBatcher?.();\r\n dispatch({ type: 'CONFIRM_RESPONDED', id: '' });\r\n dispatch({ type: 'SET_RUNNING', running: false });\r\n dispatch({ type: 'FINISH_STREAMING' });\r\n return;\r\n }\r\n }\r\n if (input === 'd' && key.ctrl) {\r\n process.exit(0);\r\n }\r\n });\r\n\r\n return (\r\n <Box key={resetKey} flexDirection=\"column\" paddingLeft={1} paddingRight={1} width=\"100%\">\r\n <ChatArea \r\n messages={state.messages} \r\n modelName={state.modelName} \r\n />\r\n\r\n {state.error && (\r\n <Box borderStyle=\"round\" borderColor=\"#fb4934\" paddingX={1} marginBottom={0}>\r\n <Text color=\"#fb4934\" bold>ERROR: </Text>\r\n <Text color=\"#fb4934\">{state.error}</Text>\r\n </Box>\r\n )}\r\n\r\n {confirmPending && (\r\n <ConfirmPrompt confirm={confirmPending} onRespond={handleConfirmResponse} />\r\n )}\r\n\r\n {state.todoPlan && <TodoPanel plan={state.todoPlan} />}\r\n\r\n <Box marginTop={0}>\r\n <InputArea\r\n onSubmit={handleSubmit}\r\n isRunning={state.isRunning || !!confirmPending}\r\n onExitRequest={() => process.exit(0)}\r\n />\r\n </Box>\r\n\r\n <StatusBar\r\n isRunning={state.isRunning}\r\n modelName={state.modelName}\r\n todoPlan={state.todoPlan}\r\n subAgentProgress={state.subAgentProgress}\r\n />\r\n </Box>\r\n );\r\n}\r\n\r\n// ... rest remains same\r\n","import React from 'react';\r\nimport { render } from 'ink';\r\nimport type { ZenCodeConfig } from '../../config/types.js';\r\nimport { createLLMClient } from '../../llm/client.js';\r\nimport { ToolRegistry } from '../../tools/registry.js';\r\nimport { registerCoreTools } from '../../tools/register.js';\r\nimport { Agent } from '../../core/agent.js';\r\nimport { buildPrompt } from '../../core/prompt/builder.js';\r\nimport { TodoStore } from '../../core/todo-store.js';\r\nimport { SubAgentTracker } from '../../core/sub-agent-tracker.js';\r\nimport { SubAgentConfigRegistry } from '../../core/sub-agents/registry.js';\r\nimport { loadAllAgentConfigs } from '../../core/sub-agents/loader.js';\r\nimport { SkillRegistry } from '../../core/skills/registry.js';\r\nimport { loadAllSkills } from '../../core/skills/loader.js';\r\nimport { createSpawnAgentsTool } from '../../tools/spawn-agents.js';\r\nimport { createTodoTool } from '../../tools/todo.js';\r\nimport { createDispatchTool } from '../../tools/dispatch.js';\r\nimport { App } from './App.js';\r\n\r\ninterface TuiOptions {\r\n config: ZenCodeConfig;\r\n}\r\n\r\n/**\r\n * Start the full-screen TUI using Ink (React for CLI)\r\n */\r\nexport async function startTui(options: TuiOptions): Promise<void> {\r\n const { config } = options;\r\n\r\n // Load sub-agent configs (before buildPrompt so agents layer can be included)\r\n const agentRegistry = new SubAgentConfigRegistry();\r\n for (const agentConfig of loadAllAgentConfigs()) {\r\n agentRegistry.register(agentConfig);\r\n }\r\n\r\n // Build system prompt\r\n const { systemPrompt } = await buildPrompt(config, agentRegistry.list());\r\n\r\n // Register tools\r\n const registry = new ToolRegistry();\r\n registerCoreTools(registry);\r\n registry.setPermissions(config.permissions);\r\n\r\n // Create LLM client\r\n const client = createLLMClient({\r\n apiKey: config.api_key,\r\n baseURL: config.base_url,\r\n model: config.model,\r\n temperature: config.temperature,\r\n maxTokens: config.max_tokens,\r\n });\r\n\r\n // Create stores\r\n const todoStore = new TodoStore();\r\n const subAgentTracker = new SubAgentTracker();\r\n\r\n // Load skills\r\n const skillRegistry = new SkillRegistry();\r\n for (const skill of loadAllSkills()) {\r\n skillRegistry.register(skill);\r\n }\r\n\r\n // Register tools based on feature flags\r\n if (config.features.parallel_agents === 'on') {\r\n registry.register(createSpawnAgentsTool(client, registry, config, subAgentTracker));\r\n }\r\n if (config.features.todo === 'on') {\r\n registry.register(createTodoTool(todoStore));\r\n }\r\n // Register dispatch tool (sub-agent system)\r\n registry.register(createDispatchTool(client, registry, config, agentRegistry, subAgentTracker));\r\n\r\n // Create agent\r\n const agent = new Agent(client, registry, config, systemPrompt);\r\n\r\n // Render the full-screen TUI\r\n const { waitUntilExit } = render(\r\n <App\r\n config={config}\r\n client={client}\r\n agent={agent}\r\n registry={registry}\r\n todoStore={todoStore}\r\n subAgentTracker={subAgentTracker}\r\n agentRegistry={agentRegistry}\r\n skillRegistry={skillRegistry}\r\n />,\r\n {\r\n patchConsole: true,\r\n exitOnCtrlC: false,\r\n },\r\n );\r\n\r\n await waitUntilExit();\r\n}\r\n","import { Command } from 'commander';\r\nimport type { CliOptions } from '../config/loader.js';\r\nimport { loadConfig } from '../config/loader.js';\r\nimport { createLLMClient } from '../llm/client.js';\r\nimport { ToolRegistry } from '../tools/registry.js';\r\nimport { registerCoreTools } from '../tools/register.js';\r\nimport { Agent, type AgentCallbacks } from '../core/agent.js';\r\nimport { buildPrompt } from '../core/prompt/builder.js';\r\nimport { startRepl } from './repl.js';\r\nimport { TodoStore } from '../core/todo-store.js';\r\nimport { SubAgentConfigRegistry } from '../core/sub-agents/registry.js';\r\nimport { loadAllAgentConfigs } from '../core/sub-agents/loader.js';\r\nimport { createSpawnAgentsTool } from '../tools/spawn-agents.js';\r\nimport { createTodoTool } from '../tools/todo.js';\r\nimport { createDispatchTool } from '../tools/dispatch.js';\r\nimport { createThinkFilter } from './tui/bridge.js';\r\nimport { printStream, printToolCall, printToolResult, printError, printInfo } from './ui.js';\r\n\r\nexport { registerCoreTools };\r\n\r\n/**\r\n * 单次执行模式(非交互式)\r\n */\r\nasync function runOnce(prompt: string, config: ReturnType<typeof loadConfig>): Promise<void> {\r\n // Load sub-agent configs (before buildPrompt so agents layer can be included)\r\n const agentRegistry = new SubAgentConfigRegistry();\r\n for (const agentConfig of loadAllAgentConfigs()) {\r\n agentRegistry.register(agentConfig);\r\n }\r\n\r\n const { systemPrompt } = await buildPrompt(config, agentRegistry.list());\r\n const registry = new ToolRegistry();\r\n registerCoreTools(registry);\r\n registry.setPermissions(config.permissions);\r\n\r\n const client = createLLMClient({\r\n apiKey: config.api_key,\r\n baseURL: config.base_url,\r\n model: config.model,\r\n temperature: config.temperature,\r\n maxTokens: config.max_tokens,\r\n });\r\n\r\n // Register tools based on feature flags\r\n const todoStore = new TodoStore();\r\n if (config.features.parallel_agents === 'on') {\r\n registry.register(createSpawnAgentsTool(client, registry, config));\r\n }\r\n if (config.features.todo === 'on') {\r\n registry.register(createTodoTool(todoStore));\r\n }\r\n\r\n registry.register(createDispatchTool(client, registry, config, agentRegistry));\r\n\r\n let isStreaming = false;\r\n const thinkFilter = createThinkFilter();\r\n const callbacks: AgentCallbacks = {\r\n onContent: (text) => {\r\n const filtered = thinkFilter(text);\r\n if (!filtered) return;\r\n if (!isStreaming) {\r\n isStreaming = true;\r\n }\r\n printStream(filtered);\r\n },\r\n onToolExecuting: (name, params) => {\r\n if (isStreaming) {\r\n process.stdout.write('\\n');\r\n isStreaming = false;\r\n }\r\n printToolCall(name, params);\r\n },\r\n onToolResult: (name, result, truncated) => {\r\n printToolResult(name, result, truncated);\r\n },\r\n onError: (err) => {\r\n printError(err.message);\r\n },\r\n };\r\n\r\n try {\r\n const agent = new Agent(client, registry, config, systemPrompt);\r\n await agent.run(prompt, callbacks);\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n printError(msg);\r\n process.exit(1);\r\n }\r\n\r\n if (isStreaming) {\r\n process.stdout.write('\\n');\r\n }\r\n}\r\n\r\n/**\r\n * 创建 CLI 程序\r\n */\r\nexport function createCli(): Command {\r\n const program = new Command();\r\n\r\n program\r\n .name('zencode')\r\n .description('极简 CLI AI 编程工具')\r\n .version('0.4.1')\r\n .option('-m, --model <model>', '指定模型名称')\r\n .option('-k, --api-key <key>', 'API 密钥')\r\n .option('-u, --base-url <url>', 'API 基础 URL')\r\n .option('--simple', '使用简单 REPL 模式(非全屏 TUI)')\r\n .argument('[prompt...]', '直接执行的提示词(非交互式)')\r\n .action(async (promptParts: string[], opts: CliOptions & { simple?: boolean }) => {\r\n const config = loadConfig(opts);\r\n\r\n // 验证 API key\r\n if (!config.api_key) {\r\n printError('未设置 API 密钥。请通过以下方式之一设置:');\r\n printError(' 1. 环境变量 ZENCODE_API_KEY');\r\n printError(' 2. 配置文件 ~/.zencode/config.yaml 中设置 api_key');\r\n printError(' 3. CLI 参数 --api-key');\r\n process.exit(1);\r\n }\r\n\r\n const prompt = promptParts.join(' ');\r\n\r\n if (prompt) {\r\n // 单次执行模式\r\n await runOnce(prompt, config);\r\n } else if (opts.simple) {\r\n // 简单 REPL 模式(旧版)\r\n await startRepl({ config });\r\n } else {\r\n // 全屏 TUI 模式(默认)\r\n const { startTui } = await import('./tui/index.js');\r\n // Clear terminal for a clean start\r\n process.stdout.write('\\x1Bc');\r\n await startTui({ config });\r\n }\r\n });\r\n\r\n return program;\r\n}\r\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\nimport { parse as parseYaml } from 'yaml';\nimport type { ZenCodeConfig } from './types.js';\nimport { DEFAULT_CONFIG } from './defaults.js';\n\n/**\n * 深度合并两个对象,source 中的值覆盖 target 中的值\n */\nfunction deepMerge(target: Record<string, any>, source: Record<string, any>): any {\n const result = { ...target };\n for (const key of Object.keys(source)) {\n const sourceVal = source[key];\n const targetVal = target[key];\n if (\n sourceVal !== undefined &&\n sourceVal !== null &&\n typeof sourceVal === 'object' &&\n !Array.isArray(sourceVal) &&\n typeof targetVal === 'object' &&\n !Array.isArray(targetVal) &&\n targetVal !== null\n ) {\n result[key] = deepMerge(targetVal, sourceVal);\n } else if (sourceVal !== undefined) {\n result[key] = sourceVal;\n }\n }\n return result;\n}\n\n/**\n * 加载 YAML 配置文件,如果不存在返回空对象\n */\nfunction loadYamlFile(filePath: string): Partial<ZenCodeConfig> {\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n return (parseYaml(content) as Partial<ZenCodeConfig>) || {};\n } catch {\n return {};\n }\n}\n\n/**\n * 从环境变量加载配置\n */\nfunction loadEnvConfig(): Partial<ZenCodeConfig> {\n const config: Partial<ZenCodeConfig> = {};\n\n if (process.env['ZENCODE_API_KEY']) {\n config.api_key = process.env['ZENCODE_API_KEY'];\n }\n if (process.env['ZENCODE_MODEL']) {\n config.model = process.env['ZENCODE_MODEL'];\n }\n if (process.env['ZENCODE_BASE_URL']) {\n config.base_url = process.env['ZENCODE_BASE_URL'];\n }\n\n return config;\n}\n\n/**\n * 从 CLI 参数加载配置\n */\nexport interface CliOptions {\n model?: string;\n apiKey?: string;\n baseUrl?: string;\n}\n\nfunction loadCliConfig(opts: CliOptions): Partial<ZenCodeConfig> {\n const config: Partial<ZenCodeConfig> = {};\n\n if (opts.model) config.model = opts.model;\n if (opts.apiKey) config.api_key = opts.apiKey;\n if (opts.baseUrl) config.base_url = opts.baseUrl;\n\n return config;\n}\n\n/**\n * 加载并合并所有配置源\n * 优先级(从低到高):默认值 < 全局配置 < 项目配置 < 环境变量 < CLI参数\n */\nexport function loadConfig(cliOpts: CliOptions = {}): ZenCodeConfig {\n const globalConfigPath = path.join(os.homedir(), '.zencode', 'config.yaml');\n const projectDirConfigPath = path.resolve('.zencode', 'config.yaml');\n const projectFileConfigPath = path.resolve('.zencode.yaml');\n\n let config = { ...DEFAULT_CONFIG };\n config = deepMerge(config, loadYamlFile(globalConfigPath));\n config = deepMerge(config, loadYamlFile(projectDirConfigPath));\n config = deepMerge(config, loadYamlFile(projectFileConfigPath));\n config = deepMerge(config, loadEnvConfig());\n config = deepMerge(config, loadCliConfig(cliOpts));\n\n return config;\n}\n","import type { ZenCodeConfig } from './types.js';\n\nexport const DEFAULT_CONFIG: ZenCodeConfig = {\n model: 'deepseek-chat',\n api_key: '',\n base_url: 'https://api.deepseek.com/v1',\n temperature: 0.7,\n max_tokens: 8192,\n\n features: {\n git: 'auto',\n mcp: 'off',\n planning_layer: 'on',\n parallel_agents: 'on',\n todo: 'on',\n },\n\n permissions: {\n auto_approve: ['read-file', 'glob', 'grep', 'spawn-agents', 'todo', 'dispatch'],\n require_approval: ['write-file', 'edit-file', 'bash', 'git'],\n },\n\n mcp_servers: [],\n prompts: [],\n max_tool_output: 30000,\n};\n","import * as readline from 'node:readline';\r\nimport type { ZenCodeConfig } from '../config/types.js';\r\nimport { createLLMClient, type LLMClient } from '../llm/client.js';\r\nimport { ToolRegistry } from '../tools/registry.js';\r\nimport { Agent, type AgentCallbacks } from '../core/agent.js';\r\nimport { buildPrompt } from '../core/prompt/builder.js';\r\nimport { registerCoreTools } from '../tools/register.js';\r\nimport { setConfirmHandler } from '../tools/permission.js';\r\nimport { TodoStore } from '../core/todo-store.js';\r\nimport { SubAgentConfigRegistry } from '../core/sub-agents/registry.js';\r\nimport { loadAllAgentConfigs } from '../core/sub-agents/loader.js';\r\nimport { SkillRegistry } from '../core/skills/registry.js';\r\nimport { loadAllSkills } from '../core/skills/loader.js';\r\nimport { createSpawnAgentsTool } from '../tools/spawn-agents.js';\r\nimport { createTodoTool } from '../tools/todo.js';\r\nimport { createDispatchTool } from '../tools/dispatch.js';\r\nimport { createThinkFilter } from './tui/bridge.js';\r\nimport {\r\n printWelcome,\r\n printStream,\r\n printToolCall,\r\n printToolResult,\r\n printError,\r\n printInfo,\r\n printSuccess,\r\n printWarning,\r\n} from './ui.js';\r\n\r\ninterface ReplOptions {\r\n config: ZenCodeConfig;\r\n}\r\n\r\n/**\r\n * 处理斜杠命令\r\n */\r\nfunction handleSlashCommand(\r\n input: string,\r\n context: {\r\n config: ZenCodeConfig;\r\n registry: ToolRegistry;\r\n client: LLMClient;\r\n todoStore: TodoStore;\r\n agentRegistry: SubAgentConfigRegistry;\r\n skillRegistry: SkillRegistry;\r\n },\r\n): boolean | 'clear' {\r\n const parts = input.trim().split(/\\s+/);\r\n const command = parts[0];\r\n\r\n switch (command) {\r\n case '/help':\r\n console.log(`\r\n可用命令:\r\n /help 显示此帮助信息\r\n /skills 列出所有可用技能(用户自定义斜杠命令)\r\n /agents 列出所有可用子 Agent\r\n /parallel 切换并行子 Agent 功能 on/off\r\n /todo 切换 todo 计划功能 on/off\r\n /clear 清空对话历史\r\n /info 显示当前配置\r\n /exit 退出\r\n`);\r\n return true;\r\n\r\n case '/skills': {\r\n const skills = context.skillRegistry.list();\r\n if (skills.length === 0) {\r\n printInfo('暂无可用技能。在 ~/.zencode/skills/ 或 .zencode/skills/ 中添加 YAML 文件定义技能。');\r\n } else {\r\n printInfo(`可用技能 (${skills.length}):`);\r\n for (const s of skills) {\r\n printInfo(` /${s.name}: ${s.description}`);\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n case '/agents': {\r\n const agents = context.agentRegistry.list();\r\n if (agents.length === 0) {\r\n printInfo('暂无可用子 Agent');\r\n } else {\r\n printInfo(`可用子 Agent (${agents.length}):`);\r\n for (const a of agents) {\r\n printInfo(` ${a.name}: ${a.description}`);\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n case '/clear':\r\n printSuccess('对话历史已清空');\r\n return 'clear';\r\n\r\n case '/parallel': {\r\n const current = context.config.features.parallel_agents;\r\n const next = current === 'on' ? 'off' : 'on';\r\n context.config.features.parallel_agents = next;\r\n if (next === 'off') {\r\n context.registry.unregister('spawn-agents');\r\n } else if (!context.registry.has('spawn-agents')) {\r\n context.registry.register(\r\n createSpawnAgentsTool(context.client, context.registry, context.config),\r\n );\r\n }\r\n printSuccess(`并行子 Agent 功能已${next === 'on' ? '开启' : '关闭'}`);\r\n return true;\r\n }\r\n\r\n case '/todo': {\r\n const current = context.config.features.todo;\r\n const next = current === 'on' ? 'off' : 'on';\r\n context.config.features.todo = next;\r\n if (next === 'off') {\r\n context.registry.unregister('todo');\r\n } else if (!context.registry.has('todo')) {\r\n context.registry.register(createTodoTool(context.todoStore));\r\n }\r\n printSuccess(`Todo 计划功能已${next === 'on' ? '开启' : '关闭'}`);\r\n return true;\r\n }\r\n\r\n case '/info':\r\n printInfo(`模型: ${context.config.model}`);\r\n printInfo(`基础 URL: ${context.config.base_url}`);\r\n printInfo(`子 Agent: ${context.agentRegistry.listNames().join(', ') || '无'}`);\r\n printInfo(`技能: ${context.skillRegistry.listNames().join(', ') || '无'}`);\r\n return true;\r\n\r\n case '/exit':\r\n process.exit(0);\r\n\r\n default:\r\n printWarning(`未知命令: ${command}。输入 /help 查看帮助。`);\r\n return true;\r\n }\r\n}\r\n\r\n/**\r\n * 启动交互式 REPL\r\n */\r\nexport async function startRepl(options: ReplOptions): Promise<void> {\r\n const { config } = options;\r\n\r\n // Load sub-agent configs (before buildPrompt so agents layer can be included)\r\n const agentRegistry = new SubAgentConfigRegistry();\r\n for (const agentConfig of loadAllAgentConfigs()) {\r\n agentRegistry.register(agentConfig);\r\n }\r\n\r\n // 构建提示词\r\n const { systemPrompt } = await buildPrompt(config, agentRegistry.list());\r\n\r\n // 注册工具\r\n const registry = new ToolRegistry();\r\n registerCoreTools(registry);\r\n registry.setPermissions(config.permissions);\r\n\r\n // 创建 LLM 客户端\r\n const client = createLLMClient({\r\n apiKey: config.api_key,\r\n baseURL: config.base_url,\r\n model: config.model,\r\n temperature: config.temperature,\r\n maxTokens: config.max_tokens,\r\n });\r\n\r\n // 创建 stores 并注册新工具\r\n const todoStore = new TodoStore();\r\n if (config.features.parallel_agents === 'on') {\r\n registry.register(createSpawnAgentsTool(client, registry, config));\r\n }\r\n if (config.features.todo === 'on') {\r\n registry.register(createTodoTool(todoStore));\r\n }\r\n\r\n // Load skills\r\n const skillRegistry = new SkillRegistry();\r\n for (const skill of loadAllSkills()) {\r\n skillRegistry.register(skill);\r\n }\r\n\r\n // Register dispatch tool (sub-agent system)\r\n registry.register(createDispatchTool(client, registry, config, agentRegistry));\r\n\r\n // 创建 Agent\r\n let agent = new Agent(client, registry, config, systemPrompt);\r\n\r\n // 打印欢迎信息\r\n printWelcome(config.model);\r\n\r\n // 创建 readline 接口\r\n const rl = readline.createInterface({\r\n input: process.stdin,\r\n output: process.stdout,\r\n prompt: '> ',\r\n historySize: 100,\r\n });\r\n\r\n // 注入确认处理函数\r\n setConfirmHandler(async (promptText: string): Promise<boolean> => {\r\n return new Promise<boolean>((resolve) => {\r\n process.stdout.write(promptText);\r\n const onData = (data: Buffer) => {\r\n process.stdin.removeListener('data', onData);\r\n process.stdin.pause();\r\n const answer = data.toString().trim().toLowerCase();\r\n resolve(answer === 'y');\r\n };\r\n process.stdin.resume();\r\n process.stdin.once('data', onData);\r\n });\r\n });\r\n\r\n rl.prompt();\r\n\r\n rl.on('line', async (line) => {\r\n const input = line.trim();\r\n if (!input) {\r\n rl.prompt();\r\n return;\r\n }\r\n\r\n // 处理斜杠命令\r\n if (input.startsWith('/')) {\r\n // 先检查是否是用户定义的 skill\r\n const slashParts = input.slice(1).split(/\\s+/);\r\n const skillName = slashParts[0] ?? '';\r\n const skillArgs = slashParts.slice(1).join(' ');\r\n const skill = skillRegistry.get(skillName);\r\n\r\n if (skill) {\r\n // 展开 skill prompt 并发送给主 Agent\r\n const expandedPrompt = skillRegistry.expandPrompt(skill, skillArgs);\r\n rl.pause();\r\n\r\n let isStreaming = false;\r\n const thinkFilter = createThinkFilter();\r\n const callbacks: AgentCallbacks = {\r\n onContent: (text) => {\r\n const filtered = thinkFilter(text);\r\n if (!filtered) return;\r\n if (!isStreaming) {\r\n isStreaming = true;\r\n process.stdout.write('\\n');\r\n }\r\n printStream(filtered);\r\n },\r\n onToolExecuting: (name, params) => {\r\n if (isStreaming) {\r\n process.stdout.write('\\n');\r\n isStreaming = false;\r\n }\r\n printToolCall(name, params);\r\n },\r\n onToolResult: (name, result, truncated) => {\r\n printToolResult(name, result, truncated);\r\n },\r\n onError: (err) => {\r\n if (isStreaming) {\r\n process.stdout.write('\\n');\r\n isStreaming = false;\r\n }\r\n printError(err.message);\r\n },\r\n };\r\n\r\n try {\r\n await agent.run(expandedPrompt, callbacks);\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n printError(msg);\r\n }\r\n\r\n if (isStreaming) {\r\n process.stdout.write('\\n');\r\n }\r\n console.log();\r\n rl.resume();\r\n rl.prompt();\r\n return;\r\n }\r\n\r\n // 内置斜杠命令\r\n const handled = handleSlashCommand(input, {\r\n config,\r\n registry,\r\n client,\r\n todoStore,\r\n agentRegistry,\r\n skillRegistry,\r\n });\r\n if (handled === 'clear') {\r\n // 重建 Agent,清空对话历史\r\n agent = new Agent(client, registry, config, systemPrompt);\r\n rl.prompt();\r\n return;\r\n }\r\n if (handled) {\r\n rl.prompt();\r\n return;\r\n }\r\n }\r\n\r\n // 暂停 REPL readline,防止和确认弹窗抢 stdin\r\n rl.pause();\r\n\r\n // 构建回调\r\n let isStreaming = false;\r\n const thinkFilter = createThinkFilter();\r\n const callbacks: AgentCallbacks = {\r\n onContent: (text) => {\r\n const filtered = thinkFilter(text);\r\n if (!filtered) return;\r\n if (!isStreaming) {\r\n isStreaming = true;\r\n process.stdout.write('\\n');\r\n }\r\n printStream(filtered);\r\n },\r\n onToolExecuting: (name, params) => {\r\n if (isStreaming) {\r\n process.stdout.write('\\n');\r\n isStreaming = false;\r\n }\r\n printToolCall(name, params);\r\n },\r\n onToolResult: (name, result, truncated) => {\r\n printToolResult(name, result, truncated);\r\n },\r\n onError: (err) => {\r\n if (isStreaming) {\r\n process.stdout.write('\\n');\r\n isStreaming = false;\r\n }\r\n printError(err.message);\r\n },\r\n };\r\n\r\n try {\r\n await agent.run(input, callbacks);\r\n } catch (err) {\r\n const msg = err instanceof Error ? err.message : String(err);\r\n printError(msg);\r\n }\r\n\r\n if (isStreaming) {\r\n process.stdout.write('\\n');\r\n }\r\n console.log(); // 空行分隔\r\n\r\n // 恢复 REPL readline\r\n rl.resume();\r\n rl.prompt();\r\n });\r\n\r\n rl.on('close', () => {\r\n console.log('\\n再见!');\r\n process.exit(0);\r\n });\r\n}\r\n","import { createCli } from '../src/cli/index.js';\n\nconst program = createCli();\nprogram.parse();\n"],"mappings":"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","names":["fs","path","fs","path","fs","path","newContent","resolve","fs","path","stat","resolve","fs","path","os","IS_WIN","fs","path","fs","init_registry","fs","path","os","parseYaml","init_registry","fs","path","os","parseYaml","init_loader","id","chalk","markedTerminal","newMessages","ToolCallLine","React","Box","Text","jsx","jsxs","MessageBubble","Box","Text","useStdout","jsx","jsxs","React","useMemo","Box","jsx","jsxs","ChatArea","React","Box","Text","useStdout","jsx","jsxs","placeholder","InputArea","React","useState","Box","Text","jsx","jsxs","StatusBar","useState","Box","Text","useInput","Fragment","jsx","jsxs","React","Box","Text","jsx","jsxs","TodoPanel","useEffect","useRef","useState","Box","Text","useInput","useStdout","jsx","jsxs","resolve","jsx","init_registry","init_loader","init_registry","init_loader","handleSlashCommand","resolve","isStreaming","thinkFilter","callbacks","init_registry","program","startTui"]}