@qxbyte/muse 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.tsx","../src/app.tsx","../src/components/StartupBanner.tsx","../src/components/MessageView.tsx","../src/components/PermissionPrompt.tsx","../src/components/ModelSelector.tsx","../src/components/Selector.tsx","../src/components/SessionSelector.tsx","../src/components/SlashAutocomplete.tsx","../src/components/PermissionModeBar.tsx","../src/permission/index.ts","../src/llm/providers/openai-compatible.ts","../src/log/index.ts","../src/types/index.ts","../src/llm/client.ts","../src/loop/agent.ts","../src/loop/system-prompt.ts","../src/config/loader.ts","../src/config/types.ts","../src/config/_env.ts","../src/config/models.ts","../src/slash/registry.ts","../src/llm/pricing.ts","../src/loop/context.ts","../src/mcp/index.ts","../src/session/jsonl.ts","../src/slash/_format.ts","../src/slash/builtin.ts","../src/tools/registry.ts","../src/tools/builtin/read.ts","../src/tools/types.ts","../src/tools/builtin/write.ts","../src/tools/builtin/edit.ts","../src/tools/builtin/bash.ts","../src/tools/builtin/grep.ts","../src/tools/builtin/glob.ts","../src/tools/builtin/index.ts"],"sourcesContent":["/**\n * CLI 入口。解析 argv → 加载配置 → 启动交互或单次模式。\n */\n\nimport React from \"react\";\nimport { Command } from \"commander\";\nimport { render } from \"ink\";\nimport { App } from \"./app.js\";\nimport { loadSettings } from \"./config/index.js\";\nimport { loadModelsRegistry, findEntry } from \"./config/models.js\";\nimport { createLLMClient, createLLMClientFromModelEntry, setActiveModelEnv } from \"./llm/client.js\";\nimport { ToolRegistry } from \"./tools/registry.js\";\nimport { BUILTIN_TOOLS } from \"./tools/builtin/index.js\";\nimport { PermissionGate } from \"./permission/index.js\";\nimport { Session } from \"./session/jsonl.js\";\nimport { Agent } from \"./loop/agent.js\";\nimport { buildSystemPrompt } from \"./loop/system-prompt.js\";\nimport { MuseError } from \"./types/index.js\";\nimport { log } from \"./log/index.js\";\n\nconst VERSION = \"0.1.0\";\n\nasync function main() {\n const program = new Command();\n\n program\n .name(\"muse\")\n .description(\"A TypeScript agent CLI built around OpenAI-compatible APIs. First-class support for self-hostable and Chinese LLMs.\")\n .version(VERSION, \"-v, --version\", \"print version\");\n\n program\n .argument(\"[prompt...]\", \"one-shot prompt (omit for interactive mode)\")\n .option(\"-m, --model <model>\", \"override model\")\n .option(\"-p, --provider <provider>\", \"override provider\")\n .option(\"--no-banner\", \"skip startup banner\")\n .option(\"--quiet\", \"minimal output (implies --no-banner)\")\n .option(\"--continue\", \"resume last session in this directory\")\n .option(\"--debug\", \"verbose logging\")\n .action(async (promptArgs: string[], opts: CliOptions) => {\n if (opts.debug) log.setLevel(\"debug\");\n\n const cwd = process.cwd();\n const { settings, sources } = await loadSettings(cwd);\n const { registry: modelsRegistry, sources: modelsSources } = await loadModelsRegistry();\n log.debug(\"config loaded\", { settingsSources: sources, modelsSources });\n\n const model = opts.model ?? settings.llm?.model;\n const provider = opts.provider ?? settings.llm?.provider;\n\n let llm;\n let llmProviderName: string;\n let llmModelName: string;\n try {\n // models.json 里找到 settings.llm.model(或 -m)对应的 entry:\n // 注入 apiKey 到 process.env.MUSE_ACTIVE_API_KEY,业务通过 env 读\n const entry = modelsRegistry && model ? findEntry(modelsRegistry, model) : undefined;\n if (entry) {\n setActiveModelEnv(entry);\n llm = createLLMClientFromModelEntry(entry);\n llmProviderName = llm.providerName;\n llmModelName = llm.model;\n } else {\n // 优先级 2:回退到 settings.json 原生 provider/model + providers 配置\n if (!provider || !model) {\n die(\"No model configured. Either define one in ~/.muse/models.json or set llm.provider+llm.model in settings.json.\");\n }\n llm = createLLMClient({ provider, model, providers: settings.providers ?? {} });\n llmProviderName = provider;\n llmModelName = model;\n }\n } catch (err) {\n if (err instanceof MuseError) die(err.message);\n throw err;\n }\n\n const tools = new ToolRegistry();\n tools.registerAll(BUILTIN_TOOLS);\n\n const permissions = new PermissionGate(settings.permissions);\n const session = await Session.create(cwd);\n await session.append({\n type: \"session_start\",\n time: new Date().toISOString(),\n cwd,\n provider: llmProviderName,\n model: llmModelName,\n });\n\n const showBanner = !opts.quiet && opts.banner !== false;\n const lang = settings.ui?.lang ?? \"en\";\n\n // Pipe input → 拼成一次性 prompt\n const pipedInput = await readStdinIfPiped();\n const oneShotPrompt = [...(promptArgs ?? []), pipedInput].filter(Boolean).join(\"\\n\").trim();\n\n if (oneShotPrompt) {\n await runOneShot({ llm, tools, permissions, session, cwd, lang, prompt: oneShotPrompt, quiet: opts.quiet ?? false });\n return;\n }\n\n // Interactive mode\n const { waitUntilExit } = render(\n <App\n llm={llm}\n tools={tools}\n permissions={permissions}\n session={session}\n settings={settings}\n settingsSources={sources}\n modelsRegistry={modelsRegistry}\n modelsSources={modelsSources}\n cwd={cwd}\n lang={lang}\n showBanner={showBanner}\n />,\n );\n await waitUntilExit();\n });\n\n await program.parseAsync(process.argv);\n}\n\ninterface CliOptions {\n model?: string;\n provider?: string;\n banner?: boolean;\n quiet?: boolean;\n continue?: boolean;\n debug?: boolean;\n}\n\nasync function readStdinIfPiped(): Promise<string> {\n if (process.stdin.isTTY) return \"\";\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) chunks.push(chunk as Buffer);\n return Buffer.concat(chunks).toString(\"utf-8\").trim();\n}\n\nasync function runOneShot(opts: {\n llm: ReturnType<typeof createLLMClient>;\n tools: ToolRegistry;\n permissions: PermissionGate;\n session: Session;\n cwd: string;\n lang: \"en\" | \"zh-CN\";\n prompt: string;\n quiet: boolean;\n}): Promise<void> {\n const systemPrompt = buildSystemPrompt({\n cwd: opts.cwd,\n model: opts.llm.model,\n provider: opts.llm.providerName,\n lang: opts.lang,\n toolNames: opts.tools.list().map((t) => t.name),\n });\n const agent = new Agent({\n llm: opts.llm,\n tools: opts.tools,\n permissions: opts.permissions,\n session: opts.session,\n cwd: opts.cwd,\n systemPrompt,\n events: {\n onText: (delta) => process.stdout.write(delta),\n onToolCallStart: (_id, name) => {\n if (!opts.quiet) process.stderr.write(`\\n→ ${name}\\n`);\n },\n onError: (err) => process.stderr.write(`\\n[error] ${err.message}\\n`),\n onPermissionRequest: async (toolName, _args, summary) => {\n // 非交互模式:deny 所有需要 ask 的工具\n if (!opts.quiet) process.stderr.write(`\\n[denied: ${toolName} — ${summary}; run in interactive mode to approve]\\n`);\n return false;\n },\n },\n });\n await agent.runTurn(opts.prompt);\n process.stdout.write(\"\\n\");\n}\n\nfunction die(msg: string): never {\n process.stderr.write(`muse: ${msg}\\n`);\n process.exit(1);\n}\n\nmain().catch((err) => {\n log.error(\"fatal\", { msg: err instanceof Error ? err.message : String(err) });\n process.stderr.write(`muse: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n});\n","/**\n * Ink 根组件:banner + 消息历史 + 输入框 + 流式响应 + slash 命令调度。\n *\n * SlashActions 在这里注入。LLM client / settings / modelsRegistry 都是 mutable state,\n * /models /config reload 通过 setLLM / setSettings / setModelsRegistry 触发 Agent 重建,\n * messages 通过 messagesRef 跨重建保留。\n */\n\nimport React, { useCallback, useEffect, useMemo, useReducer, useRef, useState } from \"react\";\nimport { Box, Text, useApp, useInput, useStdout } from \"ink\";\nimport TextInput from \"ink-text-input\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { pickBanner } from \"./components/StartupBanner.js\";\nimport { MessageView } from \"./components/MessageView.js\";\nimport { PermissionPrompt, type PermissionRequest } from \"./components/PermissionPrompt.js\";\nimport { ModelSelector, type ModelPickerRequest } from \"./components/ModelSelector.js\";\nimport { SessionSelector, type SessionPickerRequest } from \"./components/SessionSelector.js\";\nimport { SlashAutocomplete } from \"./components/SlashAutocomplete.js\";\nimport { PermissionModeBar } from \"./components/PermissionModeBar.js\";\nimport type { LLMClient } from \"./llm/types.js\";\nimport { createLLMClient, createLLMClientFromModelEntry, setActiveModelEnv } from \"./llm/client.js\";\nimport type { ToolRegistry } from \"./tools/registry.js\";\nimport { PermissionGate, type PermissionMode } from \"./permission/index.js\";\nimport { Session, type SessionSummary } from \"./session/jsonl.js\";\nimport { Agent } from \"./loop/agent.js\";\nimport { buildSystemPrompt } from \"./loop/system-prompt.js\";\nimport { loadSettings } from \"./config/index.js\";\nimport { loadModelsRegistry, findEntry, type ModelEntry, type ModelsRegistry } from \"./config/models.js\";\nimport type { Message, TokenUsage } from \"./types/index.js\";\nimport type { Settings } from \"./config/types.js\";\nimport {\n BUILTIN_SLASH_COMMANDS,\n SlashRegistry,\n parseSlash,\n type SlashActions,\n type SlashCommand,\n type SlashCommandResult,\n} from \"./slash/index.js\";\n\nexport interface AppProps {\n llm: LLMClient;\n tools: ToolRegistry;\n permissions: PermissionGate;\n session: Session;\n settings: Settings;\n settingsSources: string[];\n modelsRegistry?: ModelsRegistry;\n modelsSources: string[];\n cwd: string;\n lang: \"en\" | \"zh-CN\";\n showBanner: boolean;\n initialMessages?: Message[];\n}\n\ninterface UIState {\n history: Message[];\n streamingText: string;\n status: \"idle\" | \"streaming\" | \"tool\";\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n}\n\ntype UIAction =\n | { type: \"user_submit\" }\n | { type: \"history_set\"; messages: Message[] }\n | { type: \"stream_delta\"; delta: string }\n | { type: \"stream_reset\" }\n | { type: \"set_status\"; status: UIState[\"status\"] }\n | { type: \"add_usage\"; usage: TokenUsage };\n\nfunction reducer(state: UIState, action: UIAction): UIState {\n switch (action.type) {\n case \"user_submit\":\n return { ...state, streamingText: \"\", status: \"streaming\" };\n case \"history_set\":\n return { ...state, history: action.messages };\n case \"stream_delta\":\n return { ...state, streamingText: state.streamingText + action.delta };\n case \"stream_reset\":\n return { ...state, streamingText: \"\" };\n case \"set_status\":\n return { ...state, status: action.status };\n case \"add_usage\":\n return {\n ...state,\n inputTokens: state.inputTokens + action.usage.inputTokens,\n outputTokens: state.outputTokens + action.usage.outputTokens,\n totalTokens: state.totalTokens + action.usage.totalTokens,\n };\n }\n}\n\nexport function App({\n llm: initialLLM,\n tools,\n permissions: initialPermissions,\n session,\n settings: initialSettings,\n settingsSources: initialSources,\n modelsRegistry: initialModelsRegistry,\n cwd,\n lang,\n showBanner,\n initialMessages,\n}: AppProps) {\n const { exit } = useApp();\n const { stdout } = useStdout();\n const termWidth = stdout?.columns ?? 80;\n\n const [llm, setLLM] = useState<LLMClient>(initialLLM);\n const [permissions, setPermissions] = useState<PermissionGate>(initialPermissions);\n const [settings, setSettings] = useState<Settings>(initialSettings);\n const [settingsSources, setSettingsSources] = useState<string[]>(initialSources);\n const [modelsRegistry, setModelsRegistry] = useState<ModelsRegistry | undefined>(initialModelsRegistry);\n const [mode, setMode] = useState<PermissionMode>(initialPermissions.getMode());\n\n const [state, dispatch] = useReducer(reducer, {\n history: initialMessages ?? [],\n streamingText: \"\",\n status: \"idle\",\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n });\n\n const messagesRef = useRef<Message[]>(initialMessages ?? []);\n\n const [input, setInput] = useState(\"\");\n // inputRemountKey 给 TextInput 做 remount —— ink-text-input 在 value 被外部强制修改时\n // cursor 不会跟随到末尾,bump 一个 key 让组件重挂载,新实例 cursor 默认在 value.length。\n // onChange 用 setInput 不能 bump(每次按键都 remount 会丢 cursor);只有补全 / 清空等\n // \"外部 setValue\" 操作走 commitInput。\n const [inputRemountKey, setInputRemountKey] = useState(0);\n const commitInput = (value: string) => {\n setInput(value);\n setInputRemountKey((k) => k + 1);\n };\n const [pending, setPending] = useState<PermissionRequest | null>(null);\n const [picker, setPicker] = useState<ModelPickerRequest | null>(null);\n const [sessionPicker, setSessionPicker] = useState<SessionPickerRequest | null>(null);\n const [autocompleteIndex, setAutocompleteIndex] = useState(0);\n const agentRef = useRef<Agent | null>(null);\n\n const slash = useMemo(() => {\n const r = new SlashRegistry();\n r.registerAll(BUILTIN_SLASH_COMMANDS);\n return r;\n }, []);\n\n // input.startsWith(\"/\") && 命令名阶段(无空格)→ 显示匹配候选\n const autocomplete = useMemo<{ matches: SlashCommand[]; query: string } | null>(() => {\n if (!input.startsWith(\"/\")) return null;\n const body = input.slice(1);\n if (body.includes(\" \")) return null;\n const query = body.toLowerCase();\n const all = slash.list();\n const matches = query\n ? all.filter(\n (c) =>\n c.name.toLowerCase().includes(query) ||\n c.aliases?.some((a) => a.toLowerCase().includes(query)),\n )\n : all;\n return { matches, query };\n }, [input, slash]);\n\n // 输入变化时把高亮索引夹回合法范围\n useEffect(() => {\n const len = autocomplete?.matches.length ?? 0;\n if (autocompleteIndex >= len) setAutocompleteIndex(0);\n }, [autocomplete, autocompleteIndex]);\n\n useEffect(() => {\n const systemPrompt = buildSystemPrompt({\n cwd,\n model: llm.model,\n provider: llm.providerName,\n lang,\n toolNames: tools.list().map((t) => t.name),\n });\n\n const agent = new Agent({\n llm,\n tools,\n permissions,\n session,\n cwd,\n systemPrompt,\n events: {\n onText: (delta) => dispatch({ type: \"stream_delta\", delta }),\n onToolCallStart: () => dispatch({ type: \"set_status\", status: \"tool\" }),\n onUsage: (usage: TokenUsage) => dispatch({ type: \"add_usage\", usage }),\n onTurnEnd: () => {\n const msgs = [...agent.getMessages()];\n messagesRef.current = msgs;\n dispatch({ type: \"history_set\", messages: msgs });\n dispatch({ type: \"stream_reset\" });\n dispatch({ type: \"set_status\", status: \"idle\" });\n },\n onError: (err) => {\n dispatch({ type: \"stream_delta\", delta: `\\n[error] ${err.message}\\n` });\n dispatch({ type: \"set_status\", status: \"idle\" });\n },\n onPermissionRequest: (toolName, args, summary) =>\n new Promise<boolean>((resolve) => {\n setPending({ toolName, args, summary, resolve });\n }),\n },\n });\n agent.setMessages(messagesRef.current);\n agentRef.current = agent;\n }, [llm, tools, permissions, session, cwd, lang]);\n\n // 键盘:Ctrl+C 全局退出 + Shift+Tab 循环切 permission mode + autocomplete ↑↓ Tab Esc 导航\n useInput(\n (inputKey, key) => {\n if (key.ctrl && inputKey === \"c\") {\n exit();\n return;\n }\n if (key.shift && key.tab) {\n const next = permissions.cycleMode();\n setMode(next);\n return;\n }\n if (!autocomplete || autocomplete.matches.length === 0) return;\n const len = autocomplete.matches.length;\n if (key.upArrow) {\n setAutocompleteIndex((i) => (i - 1 + len) % len);\n } else if (key.downArrow) {\n setAutocompleteIndex((i) => (i + 1) % len);\n } else if (key.tab) {\n const picked = autocomplete.matches[autocompleteIndex];\n if (picked) commitInput(`/${picked.name}`);\n } else if (key.escape) {\n commitInput(\"\");\n }\n },\n { isActive: state.status === \"idle\" && !pending && !picker && !sessionPicker },\n );\n\n const acceptingInput =\n state.status === \"idle\" && pending === null && picker === null && sessionPicker === null;\n\n const actions: SlashActions = useMemo(\n () => ({\n setMessages: (msgs) => {\n messagesRef.current = msgs;\n agentRef.current?.setMessages(msgs);\n dispatch({ type: \"history_set\", messages: msgs });\n },\n pickModel: (items, currentId) =>\n new Promise<ModelEntry | null>((resolve) => {\n setPicker({ items, currentId, resolve });\n }),\n pickSession: (items, currentId) =>\n new Promise<SessionSummary | null>((resolve) => {\n setSessionPicker({ items, currentId, resolve });\n }),\n switchModel: async (modelId) => {\n if (!modelsRegistry) throw new Error(\"No models registry loaded.\");\n const entry = findEntry(modelsRegistry, modelId);\n if (!entry) throw new Error(`Model id \"${modelId}\" not in registry.`);\n setActiveModelEnv(entry);\n const next = createLLMClientFromModelEntry(entry);\n setLLM(next);\n await persistActiveModel(modelId);\n },\n reloadSettings: async () => {\n const { settings: nextSettings, sources } = await loadSettings(cwd);\n const { registry: nextModels } = await loadModelsRegistry();\n setSettings(nextSettings);\n setSettingsSources(sources);\n setPermissions(new PermissionGate(nextSettings.permissions));\n setModelsRegistry(nextModels);\n\n const wantModel = nextSettings.llm?.model;\n if (wantModel && wantModel !== llm.model) {\n try {\n const entry = nextModels ? findEntry(nextModels, wantModel) : undefined;\n if (entry) {\n setActiveModelEnv(entry);\n setLLM(createLLMClientFromModelEntry(entry));\n } else if (nextSettings.llm?.provider) {\n setLLM(\n createLLMClient({\n provider: nextSettings.llm.provider,\n model: wantModel,\n providers: nextSettings.providers ?? {},\n }),\n );\n }\n } catch {\n // 新配置当前不可用(缺 key 等);保留原 LLM 不抛断流\n }\n }\n return { settings: nextSettings, sources };\n },\n }),\n [cwd, modelsRegistry, llm.model],\n );\n\n const handleSubmit = useCallback(\n async (value: string) => {\n const trimmed = value.trim();\n if (!trimmed) return;\n\n // autocomplete 开 + 有候选 + 用户没在精确命名 → 补全到 input,不提交\n if (autocomplete && autocomplete.matches.length > 0) {\n const exact = autocomplete.matches.find(\n (c) => c.name === autocomplete.query || c.aliases?.includes(autocomplete.query),\n );\n if (!exact) {\n const picked = autocomplete.matches[autocompleteIndex] ?? autocomplete.matches[0];\n commitInput(`/${picked.name}`);\n return;\n }\n }\n\n const parsed = parseSlash(trimmed);\n if (parsed) {\n const cmd = slash.get(parsed.name);\n commitInput(\"\");\n if (!cmd) {\n appendAssistantText(`Unknown command: /${parsed.name}. Try /help.`);\n return;\n }\n try {\n const result = await cmd.execute({\n args: parsed.args,\n cwd,\n llm,\n session,\n settings,\n settingsSources,\n modelsRegistry,\n // 用 ref 而非 state.history:命令体可能在 await 期间调 setMessages\n // 改变 messages(如 /resume / /compact),后续 display 必须基于最新值\n history: messagesRef.current,\n tokens: {\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n totalTokens: state.totalTokens,\n },\n listCommands: () => slash.list(),\n actions,\n });\n applySlashResult(result);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n appendAssistantText(`[error] /${parsed.name}: ${msg}`);\n }\n return;\n }\n\n commitInput(\"\");\n dispatch({ type: \"user_submit\" });\n try {\n await agentRef.current?.runTurn(trimmed);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n dispatch({ type: \"stream_delta\", delta: `\\n[error] ${msg}\\n` });\n dispatch({ type: \"set_status\", status: \"idle\" });\n }\n },\n [slash, cwd, llm, session, settings, settingsSources, modelsRegistry, state.inputTokens, state.outputTokens, state.totalTokens, actions, autocomplete, autocompleteIndex],\n );\n\n function appendAssistantText(text: string) {\n const msg: Message = { role: \"assistant\", content: [{ type: \"text\", text }] };\n // 必须读 ref 而非闭包里的 state.history:上游可能刚通过 setMessages 改了历史\n // (/resume 加载 N 条 → applySlashResult 追加\"Resumed...\"),用 state.history\n // 会覆盖刚 load 进来的消息\n const next = [...messagesRef.current, msg];\n messagesRef.current = next;\n dispatch({ type: \"history_set\", messages: next });\n }\n\n function applySlashResult(result: SlashCommandResult) {\n if (result.exit) {\n exit();\n return;\n }\n if (result.display !== undefined) {\n appendAssistantText(result.display);\n }\n }\n\n const banner = !showBanner\n ? null\n : pickBanner(termWidth, { version: \"0.1.0\", model: llm.model, cwd: shortCwd(cwd) });\n\n return (\n <Box flexDirection=\"column\">\n {banner}\n <Box flexDirection=\"column\" marginTop={1}>\n {state.history.map((msg, i) => (\n <MessageView key={i} message={msg} />\n ))}\n {state.streamingText && (\n <Box marginTop={1}>\n <Text>{state.streamingText}</Text>\n </Box>\n )}\n </Box>\n {pending && (\n <PermissionPrompt\n request={{\n ...pending,\n resolve: (ok) => {\n pending.resolve(ok);\n setPending(null);\n },\n }}\n />\n )}\n {picker && (\n <ModelSelector\n request={{\n ...picker,\n resolve: (m) => {\n picker.resolve(m);\n setPicker(null);\n },\n }}\n />\n )}\n {sessionPicker && (\n <SessionSelector\n request={{\n ...sessionPicker,\n resolve: (s) => {\n sessionPicker.resolve(s);\n setSessionPicker(null);\n },\n }}\n />\n )}\n {acceptingInput && (\n <Box flexDirection=\"column\">\n <Box marginTop={1}>\n <Text color=\"cyan\">{\"> \"}</Text>\n <TextInput key={inputRemountKey} value={input} onChange={setInput} onSubmit={handleSubmit} />\n </Box>\n {autocomplete && autocomplete.matches.length > 0 && (\n <SlashAutocomplete matches={autocomplete.matches} index={autocompleteIndex} />\n )}\n </Box>\n )}\n {state.status === \"streaming\" && (\n <Box marginTop={1}>\n <Text dimColor>... (streaming)</Text>\n </Box>\n )}\n {state.status === \"tool\" && (\n <Box marginTop={1}>\n <Text dimColor>... (running tool)</Text>\n </Box>\n )}\n <Box marginTop={1}>\n <PermissionModeBar mode={mode} compact={termWidth < 60} />\n </Box>\n </Box>\n );\n}\n\nfunction shortCwd(cwd: string): string {\n const home = homedir();\n if (cwd === home) return \"~\";\n if (cwd.startsWith(home + \"/\")) return \"~\" + cwd.slice(home.length);\n return cwd;\n}\n\n/**\n * 把当前选中的 model id 写回 ~/.muse/settings.json llm.model。\n *\n * 这是 muse 第一次\"写配置\"。策略:read-modify-write 整文件,pretty-print 2 空格。\n * 不强制 chmod —— settings.json 不放明文 key,敏感数据在 settings.local.json。\n */\nasync function persistActiveModel(modelId: string): Promise<void> {\n const path = join(homedir(), \".muse\", \"settings.json\");\n let current: Record<string, unknown> = {};\n if (existsSync(path)) {\n try {\n current = JSON.parse(await readFile(path, \"utf-8\")) as Record<string, unknown>;\n } catch {\n current = {};\n }\n }\n const llm = (current.llm as Record<string, unknown> | undefined) ?? {};\n const next = { ...current, llm: { ...llm, model: modelId } };\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, JSON.stringify(next, null, 2) + \"\\n\", \"utf-8\");\n}\n","/**\n * 启动 banner(彩虹 MUSE 字母版,无边框)。\n *\n * 4 个字母各 5×5 像素,间距 2 字符,logo 总宽 26 字符 × 高 5 行。\n * M 红 / U 橙 / S 黄 / E 绿(彩虹渐变);✻ 青;v 亮黄;正文白。\n * 无边框,简洁排版,对齐右侧三行信息:✻ Welcome / model / cwd。\n */\n\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\n\n// 每个字母 5 行 × 5 字符宽的像素图。S 顶/底完整 █████ 避免拐弯吐出。\nconst LETTERS = {\n M: [\"█ █\", \"██ ██\", \"█ █ █\", \"█ █\", \"█ █\"],\n U: [\"█ █\", \"█ █\", \"█ █\", \"█ █\", \" ███ \"],\n S: [\"█████\", \"█ \", \" ███ \", \" █\", \"█████\"],\n E: [\"█████\", \"█ \", \"████ \", \"█ \", \"█████\"],\n} as const;\n\nconst COLORS = {\n M: \"#EF4444\",\n U: \"#F97316\",\n S: \"#EAB308\",\n E: \"#22C55E\",\n asterisk: \"#06B6D4\",\n text: \"white\",\n versionAccent: \"#FDE047\",\n} as const;\n\nconst LETTER_GAP = 3; // 字母之间的空格(避免视觉粘连)\nconst LOGO_WIDTH = 5 * 4 + LETTER_GAP * 3; // 29\nconst GAP_WIDTH = 6; // logo 到右侧文字的间距\n\nexport interface StartupBannerProps {\n version: string;\n model: string;\n cwd: string;\n}\n\nfunction LogoLine({ row }: { row: number }) {\n // 用 Box marginLeft 显式控制字母间距:yoga flex 不会\"吃\"空格,比 Text 拼空格稳。\n return (\n <Box flexDirection=\"row\">\n <Box>\n <Text color={COLORS.M}>{LETTERS.M[row]}</Text>\n </Box>\n <Box marginLeft={LETTER_GAP}>\n <Text color={COLORS.U}>{LETTERS.U[row]}</Text>\n </Box>\n <Box marginLeft={LETTER_GAP}>\n <Text color={COLORS.S}>{LETTERS.S[row]}</Text>\n </Box>\n <Box marginLeft={LETTER_GAP}>\n <Text color={COLORS.E}>{LETTERS.E[row]}</Text>\n </Box>\n </Box>\n );\n}\n\nfunction BannerLine({ row, children }: { row: number; children?: React.ReactNode }) {\n return (\n <Box flexDirection=\"row\">\n <Box minWidth={LOGO_WIDTH}>\n <LogoLine row={row} />\n </Box>\n <Box width={GAP_WIDTH} />\n {children ?? null}\n </Box>\n );\n}\n\nexport function StartupBanner({ version, model, cwd }: StartupBannerProps) {\n return (\n <Box flexDirection=\"column\" paddingY={0}>\n <BannerLine row={0} />\n <BannerLine row={1}>\n <Box flexDirection=\"row\">\n <Text color={COLORS.asterisk}>✻</Text>\n <Text color={COLORS.text}>{\" Welcome to Muse \"}</Text>\n <Text color={COLORS.versionAccent}>v{version}</Text>\n </Box>\n </BannerLine>\n <BannerLine row={2}>\n <Text color={COLORS.text}>model: {model}</Text>\n </BannerLine>\n <BannerLine row={3}>\n <Text color={COLORS.text}>cwd: {cwd}</Text>\n </BannerLine>\n <BannerLine row={4} />\n </Box>\n );\n}\n\n/** 紧凑模式:终端窄于 60 列时,省略 logo,仅文字。 */\nexport function CompactBanner({ version, model, cwd }: StartupBannerProps) {\n return (\n <Box flexDirection=\"column\" paddingY={0}>\n <Box flexDirection=\"row\">\n <Text color={COLORS.asterisk}>✻</Text>\n <Text color={COLORS.text}>{\" Welcome to Muse \"}</Text>\n <Text color={COLORS.versionAccent}>v{version}</Text>\n </Box>\n <Text color={COLORS.text}>model: {model}</Text>\n <Text color={COLORS.text}>cwd: {cwd}</Text>\n </Box>\n );\n}\n\n/** 单行模式:终端 < 40 列。 */\nexport function SingleLineBanner({ version, model }: Omit<StartupBannerProps, \"cwd\">) {\n return (\n <Text>\n <Text color={COLORS.text}>Muse </Text>\n <Text color={COLORS.versionAccent}>v{version}</Text>\n <Text color={COLORS.text}> · {model}</Text>\n </Text>\n );\n}\n\nexport function pickBanner(width: number, props: StartupBannerProps): React.ReactElement {\n if (width >= 60) return <StartupBanner {...props} />;\n if (width >= 40) return <CompactBanner {...props} />;\n return <SingleLineBanner version={props.version} model={props.model} />;\n}\n","/**\n * 消息展示组件。区分 user / assistant / tool 三类。\n *\n * Assistant 文本走 marked + marked-terminal,把 markdown 渲染成 ANSI 字符串后交给 Ink Text。\n * 流式中(app.tsx 的 streamingText)保持纯文本,turn 结束后由 history 重渲染替换。\n */\n\nimport React, { useMemo } from \"react\";\nimport { Box, Text } from \"ink\";\nimport { marked } from \"marked\";\n// @ts-expect-error marked-terminal 7.x 无内置 .d.ts;运行时正常\nimport { markedTerminal } from \"marked-terminal\";\nimport type { Message, ContentPart } from \"../types/index.js\";\n\n// 全局注册一次。markedTerminal() 接受样式参数(heading / blockquote / code 等),先用默认值。\nmarked.use(markedTerminal() as Parameters<typeof marked.use>[0]);\n\nfunction renderMarkdown(text: string): string {\n try {\n const out = marked.parse(text) as string;\n // marked 末尾通常带额外换行,去掉以免在 Ink Box 里多一行空白\n return out.replace(/\\n+$/, \"\");\n } catch {\n // 流到一半的 ```code 等会让 parse 抛错,退化到纯文本\n return text;\n }\n}\n\nexport function MessageView({ message }: { message: Message }) {\n switch (message.role) {\n case \"user\":\n return <UserMessage content={typeof message.content === \"string\" ? message.content : flattenText(message.content)} />;\n case \"assistant\":\n return <AssistantMessage content={message.content} />;\n case \"tool\":\n return <ToolResultLine isError={message.isError ?? false} content={message.content} />;\n case \"system\":\n return null;\n }\n}\n\nfunction flattenText(parts: ContentPart[]): string {\n return parts.filter((p): p is { type: \"text\"; text: string } => p.type === \"text\").map((p) => p.text).join(\"\\n\");\n}\n\nfunction UserMessage({ content }: { content: string }) {\n return (\n <Box flexDirection=\"row\" marginTop={1}>\n <Text color=\"cyan\" bold>{\"> \"}</Text>\n <Text>{content}</Text>\n </Box>\n );\n}\n\nfunction AssistantMessage({ content }: { content: ContentPart[] }) {\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n {content.map((part, i) => {\n if (part.type === \"text\") {\n return <AssistantTextPart key={i} text={part.text} />;\n }\n if (part.type === \"tool_use\") {\n return <ToolCallLine key={i} name={part.name} args={part.args} />;\n }\n return null;\n })}\n </Box>\n );\n}\n\nfunction AssistantTextPart({ text }: { text: string }) {\n const rendered = useMemo(() => renderMarkdown(text), [text]);\n return <Text>{rendered}</Text>;\n}\n\nfunction ToolCallLine({ name, args }: { name: string; args: unknown }) {\n const argSummary = formatArgs(args);\n return (\n <Box flexDirection=\"row\" marginTop={1}>\n <Text color=\"yellow\">{\"→ \"}</Text>\n <Text color=\"yellow\" bold>{name}</Text>\n <Text dimColor>({argSummary})</Text>\n </Box>\n );\n}\n\nfunction ToolResultLine({ isError, content }: { isError: boolean; content: string }) {\n const preview = content.length > 200 ? content.slice(0, 200) + \"...\" : content;\n const oneLine = preview.split(\"\\n\")[0];\n return (\n <Box flexDirection=\"row\" marginLeft={2}>\n <Text color={isError ? \"red\" : \"green\"}>{isError ? \"✗ \" : \"✓ \"}</Text>\n <Text dimColor>{oneLine}</Text>\n </Box>\n );\n}\n\nfunction formatArgs(args: unknown): string {\n if (typeof args !== \"object\" || args === null) return String(args);\n const entries = Object.entries(args as Record<string, unknown>);\n if (entries.length === 0) return \"\";\n const parts: string[] = [];\n for (const [k, v] of entries) {\n if (typeof v === \"string\") {\n const truncated = v.length > 40 ? v.slice(0, 40) + \"...\" : v;\n parts.push(`${k}=\"${truncated}\"`);\n } else {\n parts.push(`${k}=${JSON.stringify(v).slice(0, 40)}`);\n }\n }\n return parts.join(\", \");\n}\n","/**\n * 工具调用的权限确认 prompt。\n */\n\nimport React from \"react\";\nimport { Box, Text, useInput } from \"ink\";\n\nexport interface PermissionRequest {\n toolName: string;\n args: unknown;\n summary: string;\n resolve: (approved: boolean) => void;\n}\n\nexport function PermissionPrompt({ request }: { request: PermissionRequest }) {\n useInput((input, key) => {\n if (input === \"y\" || key.return) {\n request.resolve(true);\n } else if (input === \"n\" || key.escape) {\n request.resolve(false);\n }\n });\n\n return (\n <Box flexDirection=\"column\" marginY={1} borderStyle=\"round\" borderColor=\"yellow\" paddingX={1}>\n <Text color=\"yellow\" bold>⏵ Approve {request.toolName}?</Text>\n <Text dimColor>{request.summary}</Text>\n <Box marginTop={1}>\n <Text>(y)es / (n)o / Enter=allow / Esc=reject</Text>\n </Box>\n </Box>\n );\n}\n","/**\n * 模型选择器:用 Selector 骨架实现,提供 model entry 专用行渲染。\n *\n * 由 /models 命令通过 ctx.actions.pickModel(...) 拉起。\n * 接口(ModelPickerRequest)保持稳定,便于 app.tsx 不动 actions.pickModel 调用方。\n */\n\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\nimport { Selector } from \"./Selector.js\";\nimport type { ModelEntry } from \"../config/models.js\";\n\nexport interface ModelPickerRequest {\n items: ModelEntry[];\n currentId?: string;\n resolve: (picked: ModelEntry | null) => void;\n}\n\nexport function ModelSelector({ request }: { request: ModelPickerRequest }) {\n const { items, currentId, resolve } = request;\n const initialIndex = Math.max(\n 0,\n items.findIndex((m) => m.id === currentId),\n );\n const labelWidth = Math.max(...items.map((m) => (m.name ?? m.id).length));\n\n return (\n <Selector\n items={items}\n initialIndex={initialIndex}\n title=\"Select model\"\n hint=\"↑↓ navigate · Enter confirm · Esc cancel\"\n onSubmit={(m) => resolve(m)}\n onCancel={() => resolve(null)}\n renderRow={(m, _focused) => (\n <ModelRow model={m} active={m.id === currentId} labelWidth={labelWidth} />\n )}\n />\n );\n}\n\nfunction ModelRow({\n model,\n active,\n labelWidth,\n}: {\n model: ModelEntry;\n active: boolean;\n labelWidth: number;\n}) {\n const dot = active ? \"●\" : \" \";\n const label = (model.name ?? model.id).padEnd(labelWidth);\n const vendor = model.vendor ? `[${model.vendor}]` : \"\";\n const caps = formatCaps(model);\n\n return (\n <Box flexDirection=\"row\">\n <Text color={active ? \"green\" : undefined}>{dot} </Text>\n <Text>{label}</Text>\n <Text dimColor>{\" \"}{vendor}</Text>\n {caps && <Text dimColor>{\" \"}{caps}</Text>}\n </Box>\n );\n}\n\nfunction formatCaps(m: ModelEntry): string {\n const flags: string[] = [];\n if (m.supportsToolCall === false) flags.push(\"no-tools\");\n if (m.supportsImages) flags.push(\"vision\");\n return flags.length ? flags.join(\" · \") : \"\";\n}\n","/**\n * 通用键盘 selector 骨架:↑↓ 导航 + Enter 确认 + Esc 取消。\n *\n * 行渲染由 renderRow 回调提供;本组件只负责:\n * - 键盘事件\n * - 焦点状态 + 滑动窗口(保证 focused 始终可见)\n * - 紫色 `›` 焦点指针(颜色 #A855F7,对齐用户截图)\n * - 标题 + 提示\n *\n * 当前调用方:ModelSelector / SessionSelector。\n * 第三处再考虑把外层 borderStyle 等做成 prop;暂时硬编码。\n */\n\nimport React, { useState } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\n\nconst POINTER_COLOR = \"#A855F7\";\n\nexport interface SelectorProps<T> {\n items: T[];\n initialIndex?: number;\n title?: string;\n hint?: string;\n maxVisible?: number;\n renderRow: (item: T, focused: boolean) => React.ReactNode;\n onSubmit: (item: T) => void;\n onCancel: () => void;\n}\n\nexport function Selector<T>({\n items,\n initialIndex = 0,\n title,\n hint,\n maxVisible,\n renderRow,\n onSubmit,\n onCancel,\n}: SelectorProps<T>) {\n const safeInitial = Math.max(0, Math.min(initialIndex, items.length - 1));\n const [index, setIndex] = useState(safeInitial);\n\n useInput((_, key) => {\n if (key.upArrow) {\n setIndex((i) => Math.max(0, i - 1));\n } else if (key.downArrow) {\n setIndex((i) => Math.min(items.length - 1, i + 1));\n } else if (key.return) {\n onSubmit(items[index]);\n } else if (key.escape) {\n onCancel();\n }\n });\n\n const len = items.length;\n const window = maxVisible && maxVisible < len ? maxVisible : len;\n const start = Math.max(0, Math.min(index - Math.floor(window / 2), len - window));\n const end = Math.min(len, start + window);\n const visible = items.slice(start, end);\n\n return (\n <Box\n flexDirection=\"column\"\n marginTop={1}\n paddingX={1}\n borderStyle=\"round\"\n borderColor=\"cyan\"\n >\n {(title || hint) && (\n <Box marginBottom={1}>\n {title && <Text bold>{title}</Text>}\n {title && hint && <Text dimColor>{\" \"}</Text>}\n {hint && <Text dimColor>{hint}</Text>}\n </Box>\n )}\n {visible.map((item, i) => {\n const realIndex = start + i;\n const focused = realIndex === index;\n return (\n <Box key={realIndex} flexDirection=\"row\">\n <Text color={POINTER_COLOR} bold>\n {focused ? \"› \" : \" \"}\n </Text>\n {renderRow(item, focused)}\n </Box>\n );\n })}\n {window < len && (\n <Box marginTop={1}>\n <Text dimColor>\n ({start + 1}-{end} / {len})\n </Text>\n </Box>\n )}\n </Box>\n );\n}\n","/**\n * Session 选择器:列出当前 cwd 下的历史会话,键盘选中加载。\n *\n * 由 /resume 命令通过 ctx.actions.pickSession(...) 拉起。\n * 行布局对齐 /resume display 文本版(id8 · time · [N msgs] · preview),\n * 视觉差异:紫色 `›` 箭头 + 边框 + 选中态。\n */\n\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\nimport { Selector } from \"./Selector.js\";\nimport type { SessionSummary } from \"../session/jsonl.js\";\n\nexport interface SessionPickerRequest {\n items: SessionSummary[];\n currentId?: string;\n resolve: (picked: SessionSummary | null) => void;\n}\n\nexport function SessionSelector({ request }: { request: SessionPickerRequest }) {\n const { items, currentId, resolve } = request;\n const initialIndex = Math.max(\n 0,\n items.findIndex((s) => s.id === currentId),\n );\n\n return (\n <Selector\n items={items}\n initialIndex={initialIndex}\n maxVisible={12}\n title=\"Resume session\"\n hint=\"↑↓ navigate · Enter load · Esc cancel\"\n onSubmit={(s) => resolve(s)}\n onCancel={() => resolve(null)}\n renderRow={(s) => <SessionRow session={s} active={s.id === currentId} />}\n />\n );\n}\n\nfunction SessionRow({ session, active }: { session: SessionSummary; active: boolean }) {\n const id8 = session.id.slice(0, 8);\n const time = formatTime(session.createdAt);\n const count = `[${String(session.messageCount).padStart(2)} msgs]`;\n const preview = session.preview ?? \"(empty)\";\n\n return (\n <Box flexDirection=\"row\">\n <Text color={active ? \"green\" : undefined}>{active ? \"● \" : \" \"}</Text>\n <Text>{id8}</Text>\n <Text dimColor>{\" \"}{time}</Text>\n <Text dimColor>{\" \"}{count}</Text>\n <Text>{\" \"}{preview}</Text>\n </Box>\n );\n}\n\nfunction formatTime(iso: string): string {\n const d = new Date(iso);\n if (isNaN(d.getTime())) return iso;\n const pad = (n: number) => String(n).padStart(2, \"0\");\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;\n}\n","/**\n * Slash 命令自动补全 overlay。\n *\n * 触发条件:input.startsWith(\"/\") && !input.includes(\" \")(用户在输入命令名阶段)\n * 进入参数阶段(空格之后)→ overlay 关闭,让用户安静地输入参数\n *\n * 显示:默认色 / + name + dim description\n * focused 行整条命令名变紫色 + bold(不用 inverse 背景条)\n * 超过 maxVisible 行折叠尾部\n *\n * 渲染由 App 控制,本组件是纯展示。\n */\n\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\nimport type { SlashCommand } from \"../slash/index.js\";\n\nexport interface SlashAutocompleteProps {\n matches: SlashCommand[];\n index: number;\n maxVisible?: number;\n}\n\nconst DEFAULT_MAX = 10;\nconst SLASH_COLOR = \"#A855F7\";\n\nexport function SlashAutocomplete({ matches, index, maxVisible = DEFAULT_MAX }: SlashAutocompleteProps) {\n if (matches.length === 0) return null;\n\n // 窗口:保证 focused 始终可见\n const start = Math.max(0, Math.min(index - Math.floor(maxVisible / 2), matches.length - maxVisible));\n const end = Math.min(matches.length, start + maxVisible);\n const visible = matches.slice(start, end);\n\n const nameWidth = Math.max(...matches.map((c) => c.name.length + (c.argsHint ? c.argsHint.length + 1 : 0)));\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n {visible.map((cmd, i) => {\n const realIndex = start + i;\n return (\n <Row key={cmd.name} cmd={cmd} focused={realIndex === index} nameWidth={nameWidth} />\n );\n })}\n {matches.length > visible.length && (\n <Box marginLeft={2}>\n <Text dimColor>\n ↑↓ select · Tab/Enter accept · Esc cancel ({matches.length - visible.length} more)\n </Text>\n </Box>\n )}\n {matches.length <= visible.length && (\n <Box marginLeft={2}>\n <Text dimColor>↑↓ select · Tab/Enter accept · Esc cancel</Text>\n </Box>\n )}\n </Box>\n );\n}\n\nfunction Row({ cmd, focused, nameWidth }: { cmd: SlashCommand; focused: boolean; nameWidth: number }) {\n const head = cmd.argsHint ? `${cmd.name} ${cmd.argsHint}` : cmd.name;\n const padded = head.padEnd(nameWidth);\n // focused 整条命令名变紫色 + bold;非 focused 用默认色\n return (\n <Box flexDirection=\"row\">\n <Text color={focused ? SLASH_COLOR : undefined} bold={focused}>\n {\"/\"}{padded}\n </Text>\n <Text>{\" \"}</Text>\n <Text dimColor>{cmd.description}</Text>\n </Box>\n );\n}\n","/**\n * 权限模式状态栏。固定在 TUI 输入框下方。\n *\n * 设计:见文档库 permission-modes.md §四 状态栏 UI。\n */\n\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\nimport { MODE_LABEL, MODE_COLOR, type PermissionMode } from \"../permission/index.js\";\n\nexport function PermissionModeBar({ mode, compact }: { mode: PermissionMode; compact?: boolean }) {\n const color = MODE_COLOR[mode];\n const label = MODE_LABEL[mode];\n const isBypass = mode === \"bypassPermissions\";\n\n if (compact) {\n const short: Record<PermissionMode, string> = {\n default: \"[default]\",\n acceptEdits: \"[edits]\",\n plan: \"[plan]\",\n bypassPermissions: \"[bypass]\",\n };\n return (\n <Box flexDirection=\"row\">\n <Text color={color} bold={isBypass}>{short[mode]}</Text>\n <Text dimColor>{\" shift+tab\"}</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"row\">\n <Text color={color} bold={isBypass}>{\"▶▶ \"}{label}</Text>\n <Text dimColor>{\" (shift+tab to cycle)\"}</Text>\n </Box>\n );\n}\n","/**\n * 权限模型:三态 allow / ask / deny,叠加 4 档 PermissionMode。\n *\n * 模式匹配(pattern):\n * - \"ToolName\" 精确匹配\n * - \"Bash(<prefix>)\" 匹配 Bash 工具 + 命令前缀\n * - \"Bash(<prefix>:*)\" 通配\n *\n * PermissionMode(详见文档库 permission-modes.md):\n * - default:完全走 settings.permissions 规则\n * - acceptEdits:Edit/Write 自动 allow,其他走 default\n * - plan:只允许 read 类工具,其他全 deny\n * - bypassPermissions:除显式 deny 与 Bash 硬 deny 外全 allow\n *\n * 危险操作(rm -rf / sudo 等)由 Bash 工具内部 HARD_DENY_PATTERNS 兜底,所有模式都不可绕过。\n */\n\nimport type { Permissions } from \"../config/types.js\";\nimport type { PermissionLevel } from \"../tools/types.js\";\n\nexport type Decision = \"allow\" | \"ask\" | \"deny\";\n\nexport type PermissionMode = \"default\" | \"acceptEdits\" | \"plan\" | \"bypassPermissions\";\n\nexport const MODE_CYCLE: readonly PermissionMode[] = [\n \"default\",\n \"acceptEdits\",\n \"plan\",\n \"bypassPermissions\",\n] as const;\n\nexport const MODE_LABEL: Record<PermissionMode, string> = {\n default: \"default permissions on\",\n acceptEdits: \"accept edits on\",\n plan: \"plan mode on\",\n bypassPermissions: \"bypass permissions on\",\n};\n\nexport const MODE_COLOR: Record<PermissionMode, string> = {\n default: \"gray\",\n acceptEdits: \"#EAB308\",\n plan: \"#06B6D4\",\n bypassPermissions: \"#EF4444\",\n};\n\nexport interface PermissionInput {\n toolName: string;\n args: unknown;\n /** Tool 的权限级别;由 Agent loop 从 ToolRegistry 注入。Plan 模式用此区分 read/write。 */\n permission?: PermissionLevel;\n}\n\nexport class PermissionGate {\n private rules: Required<Permissions>;\n private mode: PermissionMode = \"default\";\n\n constructor(rules: Permissions = {}) {\n this.rules = {\n allow: rules.allow ?? [],\n ask: rules.ask ?? [],\n deny: rules.deny ?? [],\n defaultMode: rules.defaultMode ?? \"ask\",\n };\n }\n\n setMode(mode: PermissionMode): void {\n this.mode = mode;\n }\n\n getMode(): PermissionMode {\n return this.mode;\n }\n\n cycleMode(): PermissionMode {\n const i = MODE_CYCLE.indexOf(this.mode);\n this.mode = MODE_CYCLE[(i + 1) % MODE_CYCLE.length];\n return this.mode;\n }\n\n decide(input: PermissionInput): Decision {\n // 用户显式 deny 永远生效,所有模式不可绕过\n if (this.matches(this.rules.deny, input)) return \"deny\";\n\n switch (this.mode) {\n case \"bypassPermissions\":\n return \"allow\";\n\n case \"plan\":\n // 只允许只读工具;写/执行/网络类直接 deny\n return input.permission === \"read\" ? \"allow\" : \"deny\";\n\n case \"acceptEdits\":\n if (input.toolName === \"Edit\" || input.toolName === \"Write\") return \"allow\";\n return this.defaultDecide(input);\n\n case \"default\":\n default:\n return this.defaultDecide(input);\n }\n }\n\n private defaultDecide(input: PermissionInput): Decision {\n if (this.matches(this.rules.allow, input)) return \"allow\";\n if (this.matches(this.rules.ask, input)) return \"ask\";\n switch (this.rules.defaultMode) {\n case \"strict\":\n return \"ask\";\n case \"relaxed\":\n return \"allow\";\n case \"ask\":\n default:\n return \"ask\";\n }\n }\n\n private matches(patterns: string[], input: PermissionInput): boolean {\n for (const pattern of patterns) {\n if (this.matchOne(pattern, input)) return true;\n }\n return false;\n }\n\n private matchOne(pattern: string, input: PermissionInput): boolean {\n // \"ToolName\" 精确匹配\n if (!pattern.includes(\"(\")) {\n return pattern === input.toolName;\n }\n // \"Bash(<prefix>:*)\" 形式\n const m = pattern.match(/^([A-Za-z_][A-Za-z0-9_]*)\\(([^)]*)\\)$/);\n if (!m) return false;\n const [, toolName, sub] = m;\n if (toolName !== input.toolName) return false;\n if (input.toolName === \"Bash\" && typeof input.args === \"object\" && input.args !== null) {\n const cmd = (input.args as { command?: string }).command ?? \"\";\n if (sub.endsWith(\":*\")) {\n const prefix = sub.slice(0, -2);\n return cmd.startsWith(prefix);\n }\n return cmd === sub || cmd.startsWith(sub + \" \");\n }\n return false;\n }\n}\n","/**\n * OpenAI 兼容协议 provider。\n * 覆盖:OpenAI 官方、DeepSeek、Qwen、Moonshot (Kimi)、智谱、OpenRouter、Ollama (其 /v1 endpoint)、自建 vLLM/LocalAI 等。\n *\n * Why 自己包一层而不是直接用 @ai-sdk/openai-compatible:\n * - 抹平 stream 事件差异,统一为本仓库的 LLMEvent 类型\n * - 在 stream 中拼装 tool_call.arguments(OpenAI 流式 tool_call 是分片增量的 JSON 字符串)\n * - 留口子未来插入降级、重试、token 计数估算\n */\n\nimport { createOpenAICompatible } from \"@ai-sdk/openai-compatible\";\nimport { streamText, jsonSchema, tool, type CoreMessage, type ToolSet } from \"ai\";\nimport type {\n LLMClient,\n LLMEvent,\n ModelCapabilities,\n ProviderConfig,\n StreamOptions,\n} from \"../types.js\";\nimport type { Message, AssistantMessage, ToolDefinition } from \"../../types/index.js\";\nimport { log, redactApiKey } from \"../../log/index.js\";\n\ninterface OpenAICompatibleProviderOpts {\n providerName: string;\n baseUrl: string;\n apiKey: string;\n model: string;\n capabilities?: Partial<ModelCapabilities>;\n}\n\nconst DEFAULT_CAPABILITIES: ModelCapabilities = {\n toolCalling: true,\n parallelToolCalls: true,\n vision: false,\n jsonMode: true,\n maxContextWindow: 32_000,\n};\n\nexport class OpenAICompatibleClient implements LLMClient {\n readonly providerName: string;\n readonly model: string;\n readonly capabilities: ModelCapabilities;\n private modelProvider: ReturnType<ReturnType<typeof createOpenAICompatible>>;\n\n constructor(opts: OpenAICompatibleProviderOpts) {\n this.providerName = opts.providerName;\n this.model = opts.model;\n this.capabilities = { ...DEFAULT_CAPABILITIES, ...opts.capabilities };\n\n const provider = createOpenAICompatible({\n name: opts.providerName,\n baseURL: opts.baseUrl,\n apiKey: opts.apiKey,\n });\n this.modelProvider = provider(opts.model);\n\n log.debug(\"LLM provider initialized\", {\n provider: opts.providerName,\n model: opts.model,\n baseUrl: opts.baseUrl,\n apiKey: redactApiKey(opts.apiKey),\n });\n }\n\n async *stream(opts: StreamOptions): AsyncIterable<LLMEvent> {\n const { messages, tools, systemPrompt, temperature, maxTokens, abortSignal } = opts;\n\n const aiMessages = convertMessages(messages, systemPrompt);\n const aiTools = tools ? convertTools(tools) : undefined;\n\n try {\n const result = streamText({\n model: this.modelProvider,\n messages: aiMessages,\n tools: aiTools,\n temperature,\n maxTokens,\n abortSignal,\n });\n\n const seenToolCalls = new Set<string>();\n\n for await (const part of result.fullStream) {\n switch (part.type) {\n case \"text-delta\":\n yield { type: \"text\", delta: part.textDelta };\n break;\n\n case \"tool-call\":\n if (!seenToolCalls.has(part.toolCallId)) {\n seenToolCalls.add(part.toolCallId);\n yield { type: \"tool_call_start\", id: part.toolCallId, name: part.toolName };\n }\n yield {\n type: \"tool_call_complete\",\n id: part.toolCallId,\n name: part.toolName,\n args: part.args,\n };\n break;\n\n case \"finish\":\n yield {\n type: \"finish\",\n reason: mapFinishReason(part.finishReason),\n usage: part.usage\n ? {\n inputTokens: part.usage.promptTokens ?? 0,\n outputTokens: part.usage.completionTokens ?? 0,\n totalTokens: part.usage.totalTokens ?? 0,\n }\n : undefined,\n };\n break;\n\n case \"error\":\n yield { type: \"error\", error: part.error instanceof Error ? part.error : new Error(String(part.error)) };\n break;\n\n default:\n // 忽略其它(如 step-start / step-finish / tool-call-streaming-start 等)\n break;\n }\n }\n } catch (err) {\n yield { type: \"error\", error: err instanceof Error ? err : new Error(String(err)) };\n }\n }\n}\n\n// ---------- helpers ----------\n\nfunction convertMessages(messages: Message[], systemPrompt?: string): CoreMessage[] {\n const result: CoreMessage[] = [];\n if (systemPrompt) {\n result.push({ role: \"system\", content: systemPrompt });\n }\n for (const msg of messages) {\n switch (msg.role) {\n case \"system\":\n result.push({ role: \"system\", content: msg.content });\n break;\n case \"user\":\n if (typeof msg.content === \"string\") {\n result.push({ role: \"user\", content: msg.content });\n } else {\n const text = msg.content\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text)\n .join(\"\\n\");\n result.push({ role: \"user\", content: text });\n }\n break;\n case \"assistant\":\n result.push({ role: \"assistant\", content: convertAssistantContent(msg) });\n break;\n case \"tool\":\n result.push({\n role: \"tool\",\n content: [\n {\n type: \"tool-result\",\n toolCallId: msg.toolUseId,\n toolName: \"_tool\",\n result: msg.content,\n isError: msg.isError ?? false,\n },\n ],\n });\n break;\n }\n }\n return result;\n}\n\ntype AssistantContent = Extract<CoreMessage, { role: \"assistant\" }>[\"content\"];\n\nfunction convertAssistantContent(msg: AssistantMessage): AssistantContent {\n const parts: Array<\n { type: \"text\"; text: string } | { type: \"tool-call\"; toolCallId: string; toolName: string; args: unknown }\n > = [];\n for (const part of msg.content) {\n if (part.type === \"text\") {\n parts.push({ type: \"text\", text: part.text });\n } else if (part.type === \"tool_use\") {\n parts.push({\n type: \"tool-call\",\n toolCallId: part.id,\n toolName: part.name,\n args: part.args,\n });\n }\n }\n // 至少要有一个内容;空数组 SDK 会报错\n if (parts.length === 0) return \"\";\n return parts as AssistantContent;\n}\n\nfunction convertTools(tools: ToolDefinition[]): ToolSet {\n const result: ToolSet = {};\n for (const t of tools) {\n result[t.name] = tool({\n description: t.description,\n parameters: jsonSchema(t.parameters as Parameters<typeof jsonSchema>[0]),\n });\n }\n return result;\n}\n\nfunction mapFinishReason(reason: string | undefined): \"stop\" | \"tool_calls\" | \"length\" | \"content_filter\" | \"error\" | \"unknown\" {\n switch (reason) {\n case \"stop\":\n case \"stop-sequence\":\n return \"stop\";\n case \"tool-calls\":\n case \"tool_calls\":\n return \"tool_calls\";\n case \"length\":\n return \"length\";\n case \"content-filter\":\n case \"content_filter\":\n return \"content_filter\";\n case \"error\":\n return \"error\";\n default:\n return \"unknown\";\n }\n}\n\n// ---------- 预设 provider 工厂 ----------\n\nexport interface PresetConfig {\n baseUrl: string;\n defaultModel: string;\n capabilities?: Partial<ModelCapabilities>;\n}\n\nexport const PRESETS: Record<string, PresetConfig> = {\n openai: {\n baseUrl: \"https://api.openai.com/v1\",\n defaultModel: \"gpt-4o-mini\",\n },\n deepseek: {\n baseUrl: \"https://api.deepseek.com/v1\",\n defaultModel: \"deepseek-chat\",\n capabilities: { maxContextWindow: 128_000 },\n },\n qwen: {\n baseUrl: \"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n defaultModel: \"qwen-plus\",\n capabilities: { maxContextWindow: 128_000 },\n },\n moonshot: {\n baseUrl: \"https://api.moonshot.cn/v1\",\n defaultModel: \"moonshot-v1-32k\",\n capabilities: { maxContextWindow: 32_000 },\n },\n zhipu: {\n baseUrl: \"https://open.bigmodel.cn/api/paas/v4\",\n defaultModel: \"glm-4-flash\",\n capabilities: { maxContextWindow: 128_000 },\n },\n ollama: {\n baseUrl: \"http://localhost:11434/v1\",\n defaultModel: \"llama3.1\",\n capabilities: { maxContextWindow: 8_000 },\n },\n openrouter: {\n baseUrl: \"https://openrouter.ai/api/v1\",\n defaultModel: \"openai/gpt-4o-mini\",\n },\n};\n\nexport function createPresetClient(\n providerName: string,\n config: ProviderConfig,\n model?: string,\n): OpenAICompatibleClient {\n const preset = PRESETS[providerName];\n if (!preset) {\n throw new Error(`Unknown provider preset: ${providerName}. Available: ${Object.keys(PRESETS).join(\", \")}`);\n }\n return new OpenAICompatibleClient({\n providerName,\n baseUrl: (config.baseUrl as string | undefined) ?? preset.baseUrl,\n apiKey: (config.apiKey as string | undefined) ?? \"\",\n model: model ?? preset.defaultModel,\n capabilities: preset.capabilities,\n });\n}\n","/**\n * Logger 包装。第一版用最朴素的 console + 文件追加;后期可替换 pino。\n * Why 不直接用 pino: 简化首版依赖图,等可观测性章节再上 pino。\n */\n\nimport { appendFileSync, mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport type LogLevel = \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\";\n\nconst LEVELS: Record<LogLevel, number> = {\n trace: 10,\n debug: 20,\n info: 30,\n warn: 40,\n error: 50,\n};\n\ninterface LogEntry {\n time: string;\n level: LogLevel;\n msg: string;\n [key: string]: unknown;\n}\n\nclass Logger {\n private level: LogLevel = \"info\";\n private logPath: string;\n private fileEnabled = true;\n\n constructor() {\n const date = new Date().toISOString().slice(0, 10);\n this.logPath = join(homedir(), \".muse\", \"logs\", `${date}.jsonl`);\n try {\n mkdirSync(dirname(this.logPath), { recursive: true });\n } catch {\n this.fileEnabled = false;\n }\n }\n\n setLevel(level: LogLevel) {\n this.level = level;\n }\n\n private write(level: LogLevel, msg: string, extra?: Record<string, unknown>) {\n if (LEVELS[level] < LEVELS[this.level]) return;\n const entry: LogEntry = {\n time: new Date().toISOString(),\n level,\n msg,\n ...extra,\n };\n if (this.fileEnabled) {\n try {\n appendFileSync(this.logPath, JSON.stringify(entry) + \"\\n\");\n } catch {\n // 落盘失败不阻断主流程\n }\n }\n // 仅 warn/error 默认输出到 stderr,避免污染 stdout\n if (level === \"warn\" || level === \"error\") {\n const prefix = level === \"error\" ? \"[error]\" : \"[warn]\";\n process.stderr.write(`${prefix} ${msg}\\n`);\n }\n }\n\n trace(msg: string, extra?: Record<string, unknown>) { this.write(\"trace\", msg, extra); }\n debug(msg: string, extra?: Record<string, unknown>) { this.write(\"debug\", msg, extra); }\n info(msg: string, extra?: Record<string, unknown>) { this.write(\"info\", msg, extra); }\n warn(msg: string, extra?: Record<string, unknown>) { this.write(\"warn\", msg, extra); }\n error(msg: string, extra?: Record<string, unknown>) { this.write(\"error\", msg, extra); }\n}\n\nexport const log = new Logger();\n\n/** API key 脱敏:前 4 后 4,中间打码。 */\nexport function redactApiKey(key: string | undefined): string {\n if (!key) return \"<unset>\";\n if (key.length <= 12) return \"***\";\n return `${key.slice(0, 4)}...${key.slice(-4)}`;\n}\n","/**\n * 全局共享类型。其它模块按需 re-export 子集。\n * Why 集中:避免类型循环依赖。\n */\n\n// ---------- 消息(与 LLM 交互的最小单元)----------\n\nexport type MessageRole = \"system\" | \"user\" | \"assistant\" | \"tool\";\n\nexport interface TextPart {\n type: \"text\";\n text: string;\n}\n\nexport interface ToolUsePart {\n type: \"tool_use\";\n id: string;\n name: string;\n args: unknown;\n}\n\nexport interface ToolResultPart {\n type: \"tool_result\";\n toolUseId: string;\n content: string;\n isError?: boolean;\n}\n\nexport type ContentPart = TextPart | ToolUsePart | ToolResultPart;\n\nexport interface SystemMessage {\n role: \"system\";\n content: string;\n}\n\nexport interface UserMessage {\n role: \"user\";\n content: string | ContentPart[];\n}\n\nexport interface AssistantMessage {\n role: \"assistant\";\n content: ContentPart[];\n}\n\nexport interface ToolMessage {\n role: \"tool\";\n toolUseId: string;\n content: string;\n isError?: boolean;\n}\n\nexport type Message = SystemMessage | UserMessage | AssistantMessage | ToolMessage;\n\n// ---------- LLM 工具定义(暴露给模型)----------\n\nexport interface ToolDefinition {\n name: string;\n description: string;\n parameters: Record<string, unknown>; // JSON Schema\n}\n\n// ---------- Token 用量 ----------\n\nexport interface TokenUsage {\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n}\n\nexport type FinishReason = \"stop\" | \"tool_calls\" | \"length\" | \"content_filter\" | \"error\" | \"unknown\";\n\n// ---------- 错误 ----------\n\nexport class MuseError extends Error {\n constructor(message: string, public readonly code?: string, public readonly cause?: unknown) {\n super(message);\n this.name = \"MuseError\";\n }\n}\n\nexport class ToolError extends MuseError {\n constructor(message: string, public readonly toolName: string, cause?: unknown) {\n super(message, \"TOOL_ERROR\", cause);\n this.name = \"ToolError\";\n }\n}\n\nexport class PermissionDeniedError extends MuseError {\n constructor(public readonly toolName: string, public readonly reason: string) {\n super(`Permission denied for ${toolName}: ${reason}`, \"PERMISSION_DENIED\");\n this.name = \"PermissionDeniedError\";\n }\n}\n","/**\n * LLMClient 工厂:根据配置创建对应 provider 的客户端。\n *\n * 当前只实现 openai-compatible 协议族(覆盖 95% 国产模型 + OpenAI 本身)。\n * Anthropic 走自己的协议,留待 v0.3 加。\n */\n\nimport { createPresetClient, PRESETS, OpenAICompatibleClient } from \"./providers/index.js\";\nimport type { LLMClient, ModelCapabilities, ProviderConfig } from \"./types.js\";\nimport { MuseError } from \"../types/index.js\";\nimport type { ModelEntry } from \"../config/models.js\";\n\nexport interface CreateClientOpts {\n provider: string;\n model: string;\n providers: Record<string, ProviderConfig>;\n}\n\n/**\n * 当前 active model 的 apiKey 注入到此进程 env 字段下。\n *\n * 业务代码(LLM client)只看到 env name,不直接持有 key 副本。\n * /models 切换或启动加载时由 setActiveModelEnv() 写入;从这里读出来给 client。\n */\nexport const ACTIVE_API_KEY_ENV = \"MUSE_ACTIVE_API_KEY\";\n\n/** 把 entry 的 apiKey 注入 process.env,供 createLLMClientFromModelEntry 读取。 */\nexport function setActiveModelEnv(entry: ModelEntry): void {\n if (entry.apiKey) {\n process.env[ACTIVE_API_KEY_ENV] = entry.apiKey;\n } else {\n delete process.env[ACTIVE_API_KEY_ENV];\n }\n}\n\n/**\n * 从用户在 models.json 里定义的 ModelEntry 构造 LLMClient。\n *\n * apiKey 不直接传值——而是从 process.env[ACTIVE_API_KEY_ENV] 读,调用前必须先\n * setActiveModelEnv(entry) 写入。这样业务代码只看到 env name,不直接持有 key。\n *\n * vendor 字段仅用于显示(providerName 显示在 banner / /status)。\n * 当前所有 entry 走 openai-compatible 协议;未来引入其他协议时按 entry.protocol 分流。\n */\nexport function createLLMClientFromModelEntry(entry: ModelEntry): LLMClient {\n const apiKey = process.env[ACTIVE_API_KEY_ENV] ?? \"\";\n if (!apiKey && !entry.baseUrl.includes(\"localhost\")) {\n throw new MuseError(\n `Model \"${entry.id}\" has no apiKey in env ${ACTIVE_API_KEY_ENV}. ` +\n `Check models.json (or models.local.json) and ensure setActiveModelEnv() was called.`,\n \"MISSING_API_KEY\",\n );\n }\n const capabilities: Partial<ModelCapabilities> = {};\n if (entry.supportsToolCall !== undefined) capabilities.toolCalling = entry.supportsToolCall;\n if (entry.supportsImages !== undefined) capabilities.vision = entry.supportsImages;\n if (entry.contextWindow !== undefined) capabilities.maxContextWindow = entry.contextWindow;\n\n return new OpenAICompatibleClient({\n providerName: entry.vendor ?? \"custom\",\n baseUrl: entry.baseUrl,\n apiKey,\n model: entry.id,\n capabilities,\n });\n}\n\nexport function createLLMClient(opts: CreateClientOpts): LLMClient {\n const { provider, model, providers } = opts;\n const config = providers[provider];\n\n if (!config) {\n throw new MuseError(\n `Provider \"${provider}\" is not configured. Add a \"providers.${provider}\" entry to your settings.json.`,\n \"PROVIDER_NOT_CONFIGURED\",\n );\n }\n\n // 预设 provider(含国产模型)\n if (PRESETS[provider]) {\n if (!config.apiKey && provider !== \"ollama\") {\n throw new MuseError(\n `Provider \"${provider}\" requires apiKey. Set it in settings.json or via the corresponding env var.`,\n \"MISSING_API_KEY\",\n );\n }\n return createPresetClient(provider, config, model);\n }\n\n // 自定义 openai-compatible 端点\n if (config.baseUrl) {\n return new OpenAICompatibleClient({\n providerName: provider,\n baseUrl: config.baseUrl as string,\n apiKey: (config.apiKey as string | undefined) ?? \"\",\n model,\n });\n }\n\n throw new MuseError(\n `Unknown provider \"${provider}\". Either use a preset (${Object.keys(PRESETS).join(\", \")}) or set \"baseUrl\" in providers.${provider}.`,\n \"UNKNOWN_PROVIDER\",\n );\n}\n","/**\n * Agent loop:单循环 ReAct。\n *\n * loop:\n * llm.stream(messages, tools)\n * → emit text → 累计 assistant 消息\n * → 收到 tool_call → 累计\n * → finish\n * if no tool_calls: break\n * for each tool_call:\n * check permission → execute → push tool result\n */\n\nimport type { LLMClient, LLMEvent } from \"../llm/types.js\";\nimport type { Message, AssistantMessage, ContentPart, ToolUsePart, TokenUsage } from \"../types/index.js\";\nimport type { ToolRegistry } from \"../tools/registry.js\";\nimport type { ToolContext } from \"../tools/types.js\";\nimport type { PermissionGate, Decision } from \"../permission/index.js\";\nimport type { Session } from \"../session/jsonl.js\";\nimport { log } from \"../log/index.js\";\n\nexport interface AgentEvents {\n onText?: (delta: string) => void;\n onToolCallStart?: (id: string, name: string) => void;\n onToolCallArgs?: (id: string, args: unknown) => void;\n onToolResult?: (id: string, name: string, content: string, isError: boolean, summary?: string) => void;\n onPermissionRequest?: (toolName: string, args: unknown, summary: string) => Promise<boolean>;\n onUsage?: (usage: TokenUsage) => void;\n onError?: (error: Error) => void;\n onTurnEnd?: () => void;\n}\n\nexport interface AgentContext {\n llm: LLMClient;\n tools: ToolRegistry;\n permissions: PermissionGate;\n session: Session;\n cwd: string;\n systemPrompt: string;\n abortSignal?: AbortSignal;\n events?: AgentEvents;\n}\n\nexport class Agent {\n private messages: Message[] = [];\n\n constructor(private ctx: AgentContext) {}\n\n getMessages(): Message[] {\n return this.messages;\n }\n\n setMessages(msgs: Message[]): void {\n this.messages = msgs;\n }\n\n /** 执行一次完整的\"用户输入 → 助手响应(含工具循环) → 等待下一轮输入\"。 */\n async runTurn(userInput: string): Promise<void> {\n const userMessage: Message = { role: \"user\", content: userInput };\n this.messages.push(userMessage);\n await this.ctx.session.append({ type: \"message\", time: new Date().toISOString(), message: userMessage });\n\n // 内部循环:工具调用可能多轮\n while (true) {\n const mode = this.ctx.permissions.getMode();\n const tools = this.ctx.tools.toLLMDefinitions(\n mode === \"plan\" ? (t) => t.permission === \"read\" : undefined,\n );\n const stream = this.ctx.llm.stream({\n messages: this.messages,\n tools,\n systemPrompt: this.ctx.systemPrompt,\n abortSignal: this.ctx.abortSignal,\n });\n\n const assistantParts: ContentPart[] = [];\n const toolCallsToRun: ToolUsePart[] = [];\n let lastError: Error | undefined;\n\n for await (const ev of stream) {\n this.handleEvent(ev, assistantParts, toolCallsToRun, (e) => {\n lastError = e;\n });\n if (lastError) break;\n }\n\n if (lastError) {\n this.ctx.events?.onError?.(lastError);\n log.error(\"agent stream error\", { msg: lastError.message });\n return;\n }\n\n // 把 assistant 消息加入历史\n const assistantMessage: AssistantMessage = { role: \"assistant\", content: assistantParts };\n this.messages.push(assistantMessage);\n await this.ctx.session.append({ type: \"message\", time: new Date().toISOString(), message: assistantMessage });\n\n if (toolCallsToRun.length === 0) {\n this.ctx.events?.onTurnEnd?.();\n return;\n }\n\n // 执行工具调用\n for (const call of toolCallsToRun) {\n await this.runToolCall(call);\n }\n }\n }\n\n private handleEvent(\n ev: LLMEvent,\n assistantParts: ContentPart[],\n toolCallsToRun: ToolUsePart[],\n onError: (e: Error) => void,\n ): void {\n switch (ev.type) {\n case \"text\":\n // 合并到最后一个 text part 或新增\n {\n const last = assistantParts[assistantParts.length - 1];\n if (last && last.type === \"text\") {\n last.text += ev.delta;\n } else {\n assistantParts.push({ type: \"text\", text: ev.delta });\n }\n }\n this.ctx.events?.onText?.(ev.delta);\n break;\n\n case \"tool_call_start\":\n this.ctx.events?.onToolCallStart?.(ev.id, ev.name);\n break;\n\n case \"tool_call_complete\": {\n const callPart: ToolUsePart = { type: \"tool_use\", id: ev.id, name: ev.name, args: ev.args };\n assistantParts.push(callPart);\n toolCallsToRun.push(callPart);\n this.ctx.events?.onToolCallArgs?.(ev.id, ev.args);\n break;\n }\n\n case \"finish\":\n if (ev.usage) {\n this.ctx.events?.onUsage?.(ev.usage);\n this.ctx.session.append({\n type: \"usage\",\n time: new Date().toISOString(),\n usage: ev.usage,\n provider: this.ctx.llm.providerName,\n model: this.ctx.llm.model,\n });\n }\n break;\n\n case \"error\":\n onError(ev.error);\n break;\n }\n }\n\n private async runToolCall(call: ToolUsePart): Promise<void> {\n const tool = this.ctx.tools.get(call.name);\n if (!tool) {\n const result = `Tool \"${call.name}\" is not available.`;\n this.recordToolResult(call.id, call.name, result, true);\n return;\n }\n\n const summary = tool.summarize?.(call.args) ?? `${call.name}(...)`;\n const decision: Decision = this.ctx.permissions.decide({\n toolName: call.name,\n args: call.args,\n permission: tool.permission,\n });\n\n let approved = decision === \"allow\";\n if (decision === \"deny\") {\n const reason =\n this.ctx.permissions.getMode() === \"plan\"\n ? `Denied: you are in plan mode. Only read-only tools are available. Propose changes instead of executing.`\n : `Denied by policy: ${call.name}.`;\n this.recordToolResult(call.id, call.name, reason, true);\n return;\n }\n if (decision === \"ask\") {\n approved = (await this.ctx.events?.onPermissionRequest?.(call.name, call.args, summary)) ?? false;\n if (!approved) {\n this.recordToolResult(call.id, call.name, `User rejected ${call.name}.`, true);\n return;\n }\n }\n\n const toolCtx: ToolContext = {\n cwd: this.ctx.cwd,\n abortSignal: this.ctx.abortSignal,\n askPermission: async () => true, // 已在外层处理\n };\n\n const result = await this.ctx.tools.execute(call.name, call.args, toolCtx);\n this.recordToolResult(call.id, call.name, result.content, result.isError ?? false, result.summary);\n }\n\n private recordToolResult(id: string, name: string, content: string, isError: boolean, summary?: string): void {\n const toolMsg: Message = {\n role: \"tool\",\n toolUseId: id,\n content,\n isError,\n };\n this.messages.push(toolMsg);\n this.ctx.session.append({ type: \"message\", time: new Date().toISOString(), message: toolMsg });\n this.ctx.events?.onToolResult?.(id, name, content, isError, summary);\n }\n}\n","/**\n * System prompt 构造。\n *\n * 简短、命令式:把可用工具与运行时约束直接摆出来给 LLM。\n * 中文输出由 ui.lang 控制;英文为默认。\n */\n\nimport { homedir } from \"node:os\";\n\nexport interface SystemPromptOpts {\n cwd: string;\n model: string;\n provider: string;\n lang?: \"en\" | \"zh-CN\";\n toolNames: string[];\n}\n\nexport function buildSystemPrompt(opts: SystemPromptOpts): string {\n const { cwd, model, provider, lang, toolNames } = opts;\n const home = homedir();\n const displayCwd = cwd.startsWith(home) ? cwd.replace(home, \"~\") : cwd;\n\n const sections: string[] = [];\n\n sections.push(`You are Muse, a CLI coding assistant. You are running on the user's local machine via a terminal interface.`);\n\n sections.push(\n `# Environment\\n` +\n `- Working directory: ${displayCwd}\\n` +\n `- LLM backend: ${provider} (${model})\\n` +\n `- Date: ${new Date().toISOString().slice(0, 10)}`,\n );\n\n sections.push(\n `# Available tools\\n` +\n toolNames.map((n) => `- ${n}`).join(\"\\n\") +\n `\\n\\nPrefer the dedicated tool over Bash when one fits (Read for file reading, Edit for partial updates, Write for new files / full rewrites, Grep for content search, Glob for file lookup).`,\n );\n\n sections.push(\n `# Behavior\\n` +\n `- Be concise. State results, not your thinking. Don't narrate every step.\\n` +\n `- Before editing a file you have not seen, Read it first.\\n` +\n `- For Write/Edit/Bash the user may need to approve — proceed normally; the host will gate dangerous calls.\\n` +\n `- If a command may be destructive (rm -rf, force push, drop table, etc.), warn first and let the user run it manually.\\n` +\n `- When the user asks a question that does not need tools, just answer.`,\n );\n\n if (lang === \"zh-CN\") {\n sections.push(`# Output language\\nReply in Chinese (简体中文) unless the user writes in English.`);\n }\n\n return sections.join(\"\\n\\n\");\n}\n","/**\n * 配置加载:\n * 1. 内置默认值\n * 2. ~/.muse/settings.json\n * 3. <cwd>/.muse/settings.json\n * 4. <cwd>/.muse/settings.local.json\n * 5. 环境变量 (MUSE_*)\n * 6. CLI flags (在 cli.tsx 里覆盖)\n *\n * ${ENV_VAR} 占位符在加载后展开。\n */\n\nimport { readFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport type { z } from \"zod\";\nimport { SettingsSchema, type Settings } from \"./types.js\";\nimport { expandEnvVars } from \"./_env.js\";\nimport { log } from \"../log/index.js\";\n\nfunction formatZodIssues(issues: z.ZodIssue[]): string {\n return issues\n .map((i) => `${i.path.join(\".\") || \"<root>\"}: ${i.message}`)\n .join(\"; \");\n}\n\nconst DEFAULTS: Settings = {\n llm: {\n provider: \"deepseek\",\n model: \"deepseek-chat\",\n },\n providers: {\n deepseek: { apiKey: \"${DEEPSEEK_API_KEY}\" },\n openai: { apiKey: \"${OPENAI_API_KEY}\" },\n qwen: { apiKey: \"${DASHSCOPE_API_KEY}\" },\n moonshot: { apiKey: \"${MOONSHOT_API_KEY}\" },\n zhipu: { apiKey: \"${ZHIPU_API_KEY}\" },\n openrouter: { apiKey: \"${OPENROUTER_API_KEY}\" },\n ollama: { baseUrl: \"http://localhost:11434/v1\" },\n },\n permissions: {\n allow: [\"Read\", \"Grep\", \"Glob\"],\n ask: [\"Write\", \"Edit\", \"Bash\"],\n deny: [],\n defaultMode: \"ask\",\n },\n ui: {\n showBanner: true,\n lang: \"en\",\n },\n};\n\nasync function readJsonIfExists(path: string): Promise<unknown | undefined> {\n if (!existsSync(path)) return undefined;\n try {\n const raw = await readFile(path, \"utf-8\");\n return JSON.parse(raw);\n } catch (err) {\n log.warn(`Failed to parse settings at ${path}: ${err instanceof Error ? err.message : String(err)}`);\n return undefined;\n }\n}\n\n/** 深合并:高优先级覆盖低优先级。对象递归,数组/标量覆盖。 */\nfunction deepMerge<T>(low: T, high: Partial<T>): T {\n if (high == null) return low;\n if (typeof low !== \"object\" || typeof high !== \"object\" || low === null || high === null) {\n return high as T;\n }\n if (Array.isArray(high)) return high as unknown as T;\n const result: Record<string, unknown> = { ...(low as Record<string, unknown>) };\n for (const [k, v] of Object.entries(high)) {\n const existing = (low as Record<string, unknown>)[k];\n if (\n v !== null &&\n typeof v === \"object\" &&\n !Array.isArray(v) &&\n existing !== null &&\n typeof existing === \"object\" &&\n !Array.isArray(existing)\n ) {\n result[k] = deepMerge(existing, v as Record<string, unknown>);\n } else {\n result[k] = v;\n }\n }\n return result as T;\n}\n\nexport interface LoadedSettings {\n settings: Settings;\n sources: string[];\n}\n\nexport async function loadSettings(cwd: string = process.cwd()): Promise<LoadedSettings> {\n const sources: string[] = [\"<defaults>\"];\n let merged: Settings = DEFAULTS;\n\n const candidates = [\n join(homedir(), \".muse\", \"settings.json\"),\n join(cwd, \".muse\", \"settings.json\"),\n join(cwd, \".muse\", \"settings.local.json\"),\n ];\n\n for (const path of candidates) {\n const raw = await readJsonIfExists(path);\n if (raw != null) {\n const parsed = SettingsSchema.safeParse(raw);\n if (parsed.success) {\n merged = deepMerge(merged, parsed.data);\n sources.push(path);\n } else {\n log.warn(`Invalid settings at ${path}: ${formatZodIssues(parsed.error.issues)}`);\n }\n }\n }\n\n // Env overrides for the active LLM\n if (process.env.MUSE_PROVIDER && merged.llm) {\n merged = { ...merged, llm: { ...merged.llm, provider: process.env.MUSE_PROVIDER } };\n sources.push(\"env:MUSE_PROVIDER\");\n }\n if (process.env.MUSE_MODEL && merged.llm) {\n merged = { ...merged, llm: { ...merged.llm, model: process.env.MUSE_MODEL } };\n sources.push(\"env:MUSE_MODEL\");\n }\n\n // 展开 ${ENV_VAR} 占位符\n merged = expandEnvVars(merged) as Settings;\n\n return { settings: merged, sources };\n}\n\nexport { DEFAULTS };\nexport { resolve as resolvePath };\n","/**\n * 配置 schema。对应 ~/.muse/settings.json + .muse/settings.json 的内容。\n */\n\nimport { z } from \"zod\";\n\nexport const ProviderConfigSchema = z.object({\n apiKey: z.string().optional(),\n baseUrl: z.string().optional(),\n extraHeaders: z.record(z.string()).optional(),\n}).passthrough();\n\n// 新设计:model id 由 ~/.muse/models.json 提供,settings.json 只保留 active 选择。\n// provider 字段仅用于\"无 models.json 时的 fallback 路径\"(设计文档 §8 兼容层)。\n// 因此两者都可选——/models 切换只写 model,不写 provider。\nexport const LLMConfigSchema = z.object({\n provider: z.string().optional().describe(\"Fallback provider preset (only used when no models.json entry matches).\"),\n model: z.string().optional().describe(\"Active model id; should match an id in models.json.\"),\n temperature: z.number().min(0).max(2).optional(),\n maxTokens: z.number().int().positive().optional(),\n});\n\nexport const PermissionsSchema = z.object({\n allow: z.array(z.string()).optional(),\n ask: z.array(z.string()).optional(),\n deny: z.array(z.string()).optional(),\n defaultMode: z.enum([\"strict\", \"relaxed\", \"ask\"]).optional(),\n});\n\nexport const UISchema = z.object({\n theme: z.enum([\"dark\", \"light\"]).optional(),\n lang: z.enum([\"en\", \"zh-CN\"]).optional(),\n showBanner: z.boolean().optional(),\n});\n\nexport const SettingsSchema = z.object({\n llm: LLMConfigSchema.optional(),\n providers: z.record(ProviderConfigSchema).optional(),\n permissions: PermissionsSchema.optional(),\n ui: UISchema.optional(),\n mcpServers: z.record(z.unknown()).optional(),\n skills: z.object({\n enabled: z.boolean().optional(),\n disabled: z.array(z.string()).optional(),\n }).optional(),\n}).passthrough();\n\nexport type Settings = z.infer<typeof SettingsSchema>;\nexport type LLMConfig = z.infer<typeof LLMConfigSchema>;\nexport type ProviderConfig = z.infer<typeof ProviderConfigSchema>;\nexport type Permissions = z.infer<typeof PermissionsSchema>;\n","/**\n * ${ENV_VAR} 占位符递归展开。\n *\n * settings.json / models.json 都共用这套机制,避免把明文凭证落到可入 git 的文件。\n * 未定义的 env var → 空字符串(不抛错,让上层校验\"必填字段是否非空\"决定行为)。\n */\n\nconst ENV_PATTERN = /\\$\\{([A-Z_][A-Z0-9_]*)\\}/g;\n\nexport function expandEnvVars(value: unknown): unknown {\n if (typeof value === \"string\") {\n return value.replace(ENV_PATTERN, (_match, name) => process.env[name] ?? \"\");\n }\n if (Array.isArray(value)) {\n return value.map(expandEnvVars);\n }\n if (value && typeof value === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n result[k] = expandEnvVars(v);\n }\n return result;\n }\n return value;\n}\n","/**\n * Models registry:用户级模型库。\n *\n * 位置:~/.muse/models.json (+ ~/.muse/models.local.json 兜底放明文 key)\n *\n * 设计:\n * - models 数组的 id 是**用户起的名字**,不在代码里硬编码;availableModels 决定 /models\n * selector 里显示哪些\n * - apiKey 字段支持 ${ENV_VAR} 占位符(沿用 settings.json 机制)\n * - baseUrl 是基址,SDK 自己拼 /chat/completions;用户填全 endpoint 时自动剥后缀\n * - 优先级 local.json > models.json(同 id 后者覆盖前者;availableModels 取最后非空)\n * - 不存在文件 → 返回 undefined(调用方回退到 settings.json llm 配置)\n */\n\nimport { readFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { z } from \"zod\";\nimport { expandEnvVars } from \"./_env.js\";\nimport { log } from \"../log/index.js\";\n\n/**\n * 内部规整后的 ModelEntry 类型。schema 解析后的对象会通过 normalize 步骤\n * 把 url/baseUrl 合一,最终 baseUrl 保证非空。业务(client / selector)只看本类型。\n */\nexport interface ModelEntry {\n id: string;\n name?: string;\n vendor?: string;\n apiKey?: string;\n baseUrl: string;\n supportsToolCall?: boolean;\n supportsImages?: boolean;\n contextWindow?: number;\n [k: string]: unknown;\n}\n\n/**\n * 输入校验:baseUrl / url 任一非空即可。\n * 用户实际写的 models.json 多用 `url`(OpenAI 兼容协议惯例命名),\n * 我们接受两种别名,normalize 阶段归一。\n */\nexport const ModelEntryInputSchema = z\n .object({\n id: z.string().min(1),\n name: z.string().optional(),\n vendor: z.string().optional(),\n apiKey: z.string().optional(),\n baseUrl: z.string().optional(),\n url: z.string().optional(),\n supportsToolCall: z.boolean().optional(),\n supportsImages: z.boolean().optional(),\n contextWindow: z.number().int().positive().optional(),\n })\n .passthrough()\n .refine((d) => Boolean(d.baseUrl || d.url), {\n message: \"Either 'baseUrl' or 'url' is required\",\n path: [\"baseUrl\"],\n });\n\nexport type ModelEntryInput = z.infer<typeof ModelEntryInputSchema>;\n\nexport const ModelsRegistryInputSchema = z\n .object({\n models: z.array(ModelEntryInputSchema),\n /** 不填 = 全部 models 都进 selector;填了就是 selector 子集(按顺序)。 */\n availableModels: z.array(z.string()).optional(),\n })\n .passthrough();\n\nexport type ModelsRegistryInput = z.infer<typeof ModelsRegistryInputSchema>;\n\n/** Normalize 后的 registry:models[*].baseUrl 保证非空。 */\nexport interface ModelsRegistry {\n models: ModelEntry[];\n availableModels?: string[];\n [k: string]: unknown;\n}\n\nexport interface LoadError {\n path: string;\n message: string;\n}\n\nexport interface LoadedModels {\n registry: ModelsRegistry | undefined;\n sources: string[];\n errors: LoadError[];\n}\n\nconst CANDIDATES = (): string[] => [\n join(homedir(), \".muse\", \"models.json\"),\n join(homedir(), \".muse\", \"models.local.json\"),\n];\n\nexport async function loadModelsRegistry(): Promise<LoadedModels> {\n const sources: string[] = [];\n const errors: LoadError[] = [];\n let merged: ModelsRegistry | undefined;\n\n for (const path of CANDIDATES()) {\n if (!existsSync(path)) continue;\n let raw: unknown;\n try {\n raw = JSON.parse(await readFile(path, \"utf-8\"));\n } catch (err) {\n const msg = `JSON parse error: ${err instanceof Error ? err.message : String(err)}`;\n log.warn(`Failed to parse ${path}: ${msg}`);\n errors.push({ path, message: msg });\n continue;\n }\n const parsed = ModelsRegistryInputSchema.safeParse(raw);\n if (!parsed.success) {\n const msg = formatZodIssues(parsed.error.issues);\n log.warn(`Invalid models registry at ${path}: ${msg}`);\n errors.push({ path, message: msg });\n continue;\n }\n const normalized: ModelsRegistry = {\n ...parsed.data,\n models: parsed.data.models.map(normalizeModelEntry),\n };\n merged = mergeRegistries(merged, normalized);\n sources.push(path);\n }\n\n if (!merged) return { registry: undefined, sources, errors };\n\n const expanded = expandEnvVars(merged) as ModelsRegistry;\n return { registry: expanded, sources, errors };\n}\n\nfunction formatZodIssues(issues: z.ZodIssue[]): string {\n return issues\n .map((i) => `${i.path.join(\".\") || \"<root>\"}: ${i.message}`)\n .join(\"; \");\n}\n\n/** 合并:models 按 id 取后者;availableModels 取后者(非空时)。 */\nfunction mergeRegistries(low: ModelsRegistry | undefined, high: ModelsRegistry): ModelsRegistry {\n if (!low) return high;\n const byId = new Map<string, ModelEntry>();\n for (const m of low.models) byId.set(m.id, m);\n for (const m of high.models) byId.set(m.id, m);\n return {\n ...low,\n ...high,\n models: [...byId.values()],\n availableModels: high.availableModels ?? low.availableModels,\n };\n}\n\n/**\n * 输入归一:url ↔ baseUrl 二选一;剥 trailing `/` 与 `/chat/completions`。\n * 经过校验后 baseUrl/url 至少一个非空(zod refine 保证),输出 baseUrl 必填。\n */\nfunction normalizeModelEntry(entry: ModelEntryInput): ModelEntry {\n let baseUrl = (entry.baseUrl ?? entry.url ?? \"\").replace(/\\/+$/, \"\");\n if (baseUrl.endsWith(\"/chat/completions\")) {\n baseUrl = baseUrl.slice(0, -\"/chat/completions\".length);\n }\n const { url: _url, ...rest } = entry;\n return { ...rest, baseUrl };\n}\n\n// ---------- selector / lookup helpers ----------\n\nexport function findEntry(registry: ModelsRegistry, modelId: string): ModelEntry | undefined {\n return registry.models.find((m) => m.id === modelId);\n}\n\n/** /models selector 里实际显示的条目(availableModels 缺省 = 全部 id)。 */\nexport function visibleEntries(registry: ModelsRegistry): ModelEntry[] {\n if (!registry.availableModels || registry.availableModels.length === 0) {\n return registry.models;\n }\n const result: ModelEntry[] = [];\n for (const id of registry.availableModels) {\n const e = registry.models.find((m) => m.id === id);\n if (e) result.push(e);\n }\n return result;\n}\n","/**\n * Slash 命令注册表与解析器。\n */\n\nimport type { SlashCommand } from \"./types.js\";\n\nexport class SlashRegistry {\n private byName = new Map<string, SlashCommand>();\n private order: SlashCommand[] = [];\n\n register(cmd: SlashCommand): void {\n if (this.byName.has(cmd.name)) {\n throw new Error(`Duplicate slash command: /${cmd.name}`);\n }\n this.byName.set(cmd.name, cmd);\n this.order.push(cmd);\n for (const a of cmd.aliases ?? []) {\n if (!this.byName.has(a)) this.byName.set(a, cmd);\n }\n }\n\n registerAll(cmds: SlashCommand[]): void {\n for (const c of cmds) this.register(c);\n }\n\n get(name: string): SlashCommand | undefined {\n return this.byName.get(name);\n }\n\n list(): SlashCommand[] {\n return [...this.order];\n }\n}\n\nexport interface ParsedSlash {\n name: string;\n args: string;\n}\n\n/** \"/foo bar baz\" → { name: \"foo\", args: \"bar baz\" };非 slash 返回 null。 */\nexport function parseSlash(input: string): ParsedSlash | null {\n const trimmed = input.trim();\n if (!trimmed.startsWith(\"/\") || trimmed.length < 2) return null;\n const body = trimmed.slice(1);\n const space = body.search(/\\s/);\n if (space === -1) return { name: body, args: \"\" };\n return { name: body.slice(0, space), args: body.slice(space + 1).trim() };\n}\n","/**\n * 模型单价表(USD per 1M tokens)。\n *\n * 设计文档:muse-design.md §11.2 Token / 费用统计。\n *\n * 数据来源:各 provider 公开价格页(2026 年初快照)。仅供 /cost 命令展示估算用,\n * 不保证准确性,价格变动用户可在 ~/.muse/settings.json 自定义覆盖(v0.2 起)。\n */\n\nexport interface ModelPricing {\n /** 输入 token 单价(USD per 1M)。 */\n inputPer1M: number;\n /** 输出 token 单价(USD per 1M)。 */\n outputPer1M: number;\n}\n\nconst PRICING: Record<string, Record<string, ModelPricing>> = {\n openai: {\n \"gpt-4o\": { inputPer1M: 2.5, outputPer1M: 10 },\n \"gpt-4o-mini\": { inputPer1M: 0.15, outputPer1M: 0.6 },\n \"gpt-4-turbo\": { inputPer1M: 10, outputPer1M: 30 },\n },\n deepseek: {\n \"deepseek-chat\": { inputPer1M: 0.14, outputPer1M: 0.28 },\n \"deepseek-reasoner\": { inputPer1M: 0.55, outputPer1M: 2.19 },\n },\n qwen: {\n \"qwen-plus\": { inputPer1M: 0.4, outputPer1M: 1.2 },\n \"qwen-max\": { inputPer1M: 2.8, outputPer1M: 8.4 },\n \"qwen-turbo\": { inputPer1M: 0.05, outputPer1M: 0.2 },\n },\n moonshot: {\n \"moonshot-v1-8k\": { inputPer1M: 1.68, outputPer1M: 1.68 },\n \"moonshot-v1-32k\": { inputPer1M: 3.36, outputPer1M: 3.36 },\n \"moonshot-v1-128k\": { inputPer1M: 8.4, outputPer1M: 8.4 },\n },\n zhipu: {\n \"glm-4-flash\": { inputPer1M: 0, outputPer1M: 0 },\n \"glm-4-plus\": { inputPer1M: 7, outputPer1M: 7 },\n },\n ollama: {\n // 本地模型零成本\n },\n};\n\nexport function lookupPricing(provider: string, model: string): ModelPricing | undefined {\n return PRICING[provider]?.[model];\n}\n\nexport function estimateCostUSD(\n provider: string,\n model: string,\n inputTokens: number,\n outputTokens: number,\n): number | undefined {\n const p = lookupPricing(provider, model);\n if (!p) return undefined;\n return (inputTokens / 1_000_000) * p.inputPer1M + (outputTokens / 1_000_000) * p.outputPer1M;\n}\n\n/** 把 USD 金额格式化成人类可读字符串。小于 1 美分用 micro-dollar 显示。 */\nexport function formatUSD(usd: number): string {\n if (usd === 0) return \"$0.00\";\n if (usd < 0.0001) return `<$0.0001`;\n if (usd < 0.01) return `$${usd.toFixed(4)}`;\n return `$${usd.toFixed(4)}`;\n}\n","/**\n * 上下文管理:手动 / 自动压缩对话历史。\n *\n * 设计文档:muse-design.md §5.3 上下文管理。\n *\n * 算法:\n * 1. 找一个安全切割点 cutoff:cutoff 之前是 \"older\",之后是 \"recent\"\n * 2. 安全 = 不破坏 assistant 的 tool_use ↔ 紧随的 tool 消息 配对\n * (在 tool_use 之后但 tool result 之前切,会让 LLM 看到悬挂的 tool_use)\n * 3. older 拼成转录,调 LLM 摘要成一段\n * 4. 摘要包成一条 user message(\"[Previous conversation summary] ...\"),\n * 作为新历史的开头,后接 recent\n *\n * Why user 角色而非 system:\n * - 系统提示 muse 已在 systemPrompt 单独管理;不污染它\n * - 用 user role 让 LLM 自然把它当成\"任务上下文\"继续推理\n */\n\nimport type { LLMClient } from \"../llm/types.js\";\nimport type { Message, AssistantMessage, ContentPart } from \"../types/index.js\";\n\nexport interface CompactOptions {\n llm: LLMClient;\n /** 保留最近 N 条原始消息不压缩。默认 4。 */\n keepRecent?: number;\n abortSignal?: AbortSignal;\n}\n\nexport interface CompactResult {\n newMessages: Message[];\n summary: string;\n originalCount: number;\n newCount: number;\n /** 没有可压缩内容时为 true,messages 原样返回。 */\n noop: boolean;\n}\n\nexport async function compactMessages(\n messages: Message[],\n opts: CompactOptions,\n): Promise<CompactResult> {\n const keepRecent = opts.keepRecent ?? 4;\n const cutoff = findSafeCutoff(messages, keepRecent);\n\n if (cutoff <= 0) {\n return {\n newMessages: messages,\n summary: \"\",\n originalCount: messages.length,\n newCount: messages.length,\n noop: true,\n };\n }\n\n const older = messages.slice(0, cutoff);\n const recent = messages.slice(cutoff);\n const summary = await summarizeConversation(older, opts.llm, opts.abortSignal);\n\n const summaryMessage: Message = {\n role: \"user\",\n content:\n `[Previous conversation summary]\\n\\n${summary}\\n\\n` +\n `[End of summary. The conversation continues below.]`,\n };\n\n const newMessages: Message[] = [summaryMessage, ...recent];\n\n return {\n newMessages,\n summary,\n originalCount: messages.length,\n newCount: newMessages.length,\n noop: false,\n };\n}\n\n/**\n * 从理想切点(messages.length - keepRecent)向前找最近的安全边界。\n * 安全边界 = user 消息(自然 turn 起点),且其之前不存在悬挂的 tool_use。\n *\n * 退化策略:找不到合法切点 → 返回 0(不压缩)。\n */\nexport function findSafeCutoff(messages: Message[], keepRecent: number): number {\n if (messages.length <= keepRecent) return 0;\n const ideal = Math.max(0, messages.length - keepRecent);\n\n for (let i = ideal; i > 0; i--) {\n if (messages[i].role !== \"user\") continue;\n if (hasUnresolvedToolUse(messages.slice(0, i))) continue;\n return i;\n }\n return 0;\n}\n\n/** older 段是否有 assistant.tool_use 但缺对应 tool 消息。 */\nfunction hasUnresolvedToolUse(older: Message[]): boolean {\n const seenToolUseIds = new Set<string>();\n const seenToolResultIds = new Set<string>();\n for (const msg of older) {\n if (msg.role === \"assistant\") {\n for (const part of msg.content) {\n if (part.type === \"tool_use\") seenToolUseIds.add(part.id);\n }\n } else if (msg.role === \"tool\") {\n seenToolResultIds.add(msg.toolUseId);\n }\n }\n for (const id of seenToolUseIds) {\n if (!seenToolResultIds.has(id)) return true;\n }\n return false;\n}\n\nasync function summarizeConversation(\n older: Message[],\n llm: LLMClient,\n abortSignal?: AbortSignal,\n): Promise<string> {\n const transcript = renderTranscript(older);\n const prompt: Message[] = [\n {\n role: \"user\",\n content:\n `Summarize the following conversation in 200-400 words. Focus on:\\n` +\n `1. The user's task and goals\\n` +\n `2. Key decisions and approaches taken\\n` +\n `3. Files or code touched (paths + what changed)\\n` +\n `4. Outstanding questions or pending work\\n\\n` +\n `Be concrete. Do not invent details. Use short bullet points where appropriate.\\n\\n` +\n `--- BEGIN CONVERSATION ---\\n${transcript}\\n--- END CONVERSATION ---`,\n },\n ];\n\n let text = \"\";\n for await (const ev of llm.stream({ messages: prompt, abortSignal })) {\n if (ev.type === \"text\") text += ev.delta;\n else if (ev.type === \"error\") throw ev.error;\n }\n return text.trim() || \"(empty summary)\";\n}\n\nfunction renderTranscript(messages: Message[]): string {\n const lines: string[] = [];\n for (const msg of messages) {\n switch (msg.role) {\n case \"system\":\n lines.push(`[system]\\n${msg.content}\\n`);\n break;\n case \"user\":\n lines.push(`[user]\\n${typeof msg.content === \"string\" ? msg.content : flattenContent(msg.content)}\\n`);\n break;\n case \"assistant\":\n lines.push(`[assistant]\\n${renderAssistant(msg)}\\n`);\n break;\n case \"tool\":\n lines.push(`[tool result${msg.isError ? \" ERROR\" : \"\"}]\\n${msg.content}\\n`);\n break;\n }\n }\n return lines.join(\"\\n\");\n}\n\nfunction renderAssistant(msg: AssistantMessage): string {\n const parts: string[] = [];\n for (const part of msg.content) {\n if (part.type === \"text\") parts.push(part.text);\n else if (part.type === \"tool_use\") {\n parts.push(`<tool_call name=\"${part.name}\" args=${JSON.stringify(part.args)} />`);\n }\n }\n return parts.join(\"\\n\");\n}\n\nfunction flattenContent(parts: ContentPart[]): string {\n return parts\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text)\n .join(\"\\n\");\n}\n","/**\n * MCP 状态查询入口(v0.1 占位,v0.3 真接 SDK)。\n *\n * 当前仅根据 settings.mcpServers 配置返回\"已配置但未连接\"的状态。\n * /mcp 命令读这里;不依赖任何 MCP 运行时。\n */\n\nimport type { Settings } from \"../config/types.js\";\nimport type { MCPServerStatus, MCPServerConfig } from \"./types.js\";\n\nconst NOT_IMPLEMENTED = \"MCP client not implemented (planned for v0.3)\";\n\nexport function getMCPStatus(settings: Settings): MCPServerStatus[] {\n const servers = (settings.mcpServers ?? {}) as Record<string, MCPServerConfig>;\n return Object.entries(servers).map(([name, config]) => ({\n name,\n configured: true,\n connected: false,\n toolCount: 0,\n error: NOT_IMPLEMENTED,\n config,\n }));\n}\n\nexport type { MCPServerStatus, MCPServerConfig } from \"./types.js\";\n","/**\n * Session 持久化:append-only JSONL。\n * 路径:~/.muse/projects/<project-hash>/sessions/<uuid>.jsonl\n *\n * 每行一个事件:消息 / 工具调用 / 工具结果 / 使用统计 / ...\n */\n\nimport { appendFile, mkdir, readdir, readFile, stat } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { createHash, randomUUID } from \"node:crypto\";\nimport type { Message, TokenUsage } from \"../types/index.js\";\nimport { log } from \"../log/index.js\";\n\nexport type SessionEvent =\n | { type: \"session_start\"; time: string; cwd: string; provider: string; model: string }\n | { type: \"message\"; time: string; message: Message }\n | { type: \"usage\"; time: string; usage: TokenUsage; provider: string; model: string }\n | { type: \"session_end\"; time: string; reason: \"user_exit\" | \"error\" };\n\nexport interface SessionMeta {\n id: string;\n cwd: string;\n createdAt: string;\n path: string;\n}\n\nexport interface SessionSummary extends SessionMeta {\n /** 首个 user 消息前 60 字符。 */\n preview?: string;\n messageCount: number;\n}\n\nfunction projectHash(cwd: string): string {\n return createHash(\"sha256\").update(cwd).digest(\"hex\").slice(0, 16);\n}\n\nfunction sessionsDir(cwd: string): string {\n return join(homedir(), \".muse\", \"projects\", projectHash(cwd), \"sessions\");\n}\n\nexport class Session {\n readonly meta: SessionMeta;\n private writeQueue: Promise<void> = Promise.resolve();\n\n private constructor(meta: SessionMeta) {\n this.meta = meta;\n }\n\n static async create(cwd: string): Promise<Session> {\n const id = randomUUID();\n const dir = sessionsDir(cwd);\n await mkdir(dir, { recursive: true });\n const path = join(dir, `${id}.jsonl`);\n const meta: SessionMeta = {\n id,\n cwd,\n createdAt: new Date().toISOString(),\n path,\n };\n log.debug(\"session created\", { id, path });\n return new Session(meta);\n }\n\n static async findLatest(cwd: string): Promise<SessionMeta | undefined> {\n const list = await Session.listAll(cwd, 1);\n return list[0];\n }\n\n static async resolve(cwd: string, idOrPrefix: string): Promise<SessionMeta | undefined> {\n const dir = sessionsDir(cwd);\n if (!existsSync(dir)) return undefined;\n const entries = await readdir(dir);\n const matches = entries.filter((e) => e.endsWith(\".jsonl\") && e.startsWith(idOrPrefix));\n if (matches.length === 0) return undefined;\n if (matches.length > 1) {\n throw new Error(`Ambiguous session id \"${idOrPrefix}\" matches ${matches.length} sessions; use more characters.`);\n }\n const top = matches[0];\n const st = await stat(join(dir, top));\n return {\n id: top.replace(/\\.jsonl$/, \"\"),\n cwd,\n createdAt: st.mtime.toISOString(),\n path: join(dir, top),\n };\n }\n\n /**\n * 按修改时间倒序列出当前 cwd 下的 session,附带 preview 与消息数。\n * 读 preview 需要打开每个文件;调用方通过 limit 控制 IO 量。\n */\n static async listAll(cwd: string, limit?: number): Promise<SessionSummary[]> {\n const dir = sessionsDir(cwd);\n if (!existsSync(dir)) return [];\n const entries = await readdir(dir);\n const files = entries.filter((e) => e.endsWith(\".jsonl\"));\n if (files.length === 0) return [];\n\n const stats = await Promise.all(\n files.map(async (f) => {\n const path = join(dir, f);\n const st = await stat(path);\n return { file: f, path, mtime: st.mtime };\n }),\n );\n stats.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());\n\n const truncated = typeof limit === \"number\" ? stats.slice(0, limit) : stats;\n\n const summaries: SessionSummary[] = [];\n for (const s of truncated) {\n const meta: SessionMeta = {\n id: s.file.replace(/\\.jsonl$/, \"\"),\n cwd,\n createdAt: s.mtime.toISOString(),\n path: s.path,\n };\n const summary = await readSummary(meta);\n summaries.push(summary);\n }\n return summaries;\n }\n\n static async open(meta: SessionMeta): Promise<{ session: Session; events: SessionEvent[] }> {\n const session = new Session(meta);\n const events = await session.readAll();\n return { session, events };\n }\n\n /** 从已加载的 events 重建 messages 数组(按时序)。 */\n static messagesFromEvents(events: SessionEvent[]): Message[] {\n const out: Message[] = [];\n for (const ev of events) {\n if (ev.type === \"message\") out.push(ev.message);\n }\n return out;\n }\n\n async append(event: SessionEvent): Promise<void> {\n const line = JSON.stringify(event) + \"\\n\";\n // 串行写入避免交错\n this.writeQueue = this.writeQueue.then(async () => {\n try {\n await mkdir(dirname(this.meta.path), { recursive: true });\n await appendFile(this.meta.path, line, \"utf-8\");\n } catch (err) {\n log.warn(`session append failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n });\n return this.writeQueue;\n }\n\n async readAll(): Promise<SessionEvent[]> {\n if (!existsSync(this.meta.path)) return [];\n const raw = await readFile(this.meta.path, \"utf-8\");\n const events: SessionEvent[] = [];\n for (const line of raw.split(\"\\n\")) {\n if (!line.trim()) continue;\n try {\n events.push(JSON.parse(line) as SessionEvent);\n } catch {\n // skip corrupt lines\n }\n }\n return events;\n }\n}\n\nasync function readSummary(meta: SessionMeta): Promise<SessionSummary> {\n let events: SessionEvent[] = [];\n try {\n const raw = await readFile(meta.path, \"utf-8\");\n for (const line of raw.split(\"\\n\")) {\n if (!line.trim()) continue;\n try {\n events.push(JSON.parse(line) as SessionEvent);\n } catch {\n // skip\n }\n }\n } catch {\n // unreadable; return minimal summary\n }\n const messages = events.filter((e): e is Extract<SessionEvent, { type: \"message\" }> => e.type === \"message\");\n const firstUser = messages.find((e) => e.message.role === \"user\");\n let preview: string | undefined;\n if (firstUser) {\n const c = firstUser.message.content;\n const text = typeof c === \"string\" ? c : c.map((p) => (p.type === \"text\" ? p.text : \"\")).join(\" \").trim();\n preview = text.slice(0, 60).replace(/\\s+/g, \" \");\n }\n return { ...meta, preview, messageCount: messages.length };\n}\n","/**\n * Slash 命令体共享的格式化 helper。\n *\n * 之所以单独抽:命令文件应该薄、只编排;shortPath / 表格对齐 / flag 解析\n * 被多个命令复用,三处相似就抽(CLAUDE.md 代码风格条款)。\n */\n\nimport { homedir } from \"node:os\";\n\nexport function shortPath(p: string): string {\n const home = homedir();\n if (p === home) return \"~\";\n if (p.startsWith(home + \"/\")) return \"~\" + p.slice(home.length);\n return p;\n}\n\nexport function formatList(list: string[] | undefined): string {\n if (!list || list.length === 0) return \"(none)\";\n return list.join(\", \");\n}\n\n/**\n * 解析 \"--key val --flag pos1 pos2\" 形式。极简,够 v0.1 用:\n * - 不支持 = 形式\n * - 不支持引号转义\n * - bool flag 默认 false,出现即 true\n */\nexport function parseArgs(raw: string): { positional: string[]; flags: Record<string, string | boolean> } {\n const tokens = raw.trim().split(/\\s+/).filter(Boolean);\n const positional: string[] = [];\n const flags: Record<string, string | boolean> = {};\n for (let i = 0; i < tokens.length; i++) {\n const t = tokens[i];\n if (t.startsWith(\"--\")) {\n const key = t.slice(2);\n const next = tokens[i + 1];\n if (next && !next.startsWith(\"--\")) {\n flags[key] = next;\n i++;\n } else {\n flags[key] = true;\n }\n } else {\n positional.push(t);\n }\n }\n return { positional, flags };\n}\n\n/**\n * \"provider/model\" 或 \"model\" 解析。后者沿用当前 provider。\n */\nexport function parseModelSpec(\n spec: string,\n fallbackProvider: string,\n): { provider: string; model: string } {\n const slash = spec.indexOf(\"/\");\n if (slash === -1) return { provider: fallbackProvider, model: spec };\n return { provider: spec.slice(0, slash), model: spec.slice(slash + 1) };\n}\n\n/** \"yyyy-mm-dd hh:mm\" 紧凑时间。 */\nexport function formatTime(iso: string): string {\n const d = new Date(iso);\n if (isNaN(d.getTime())) return iso;\n const pad = (n: number) => String(n).padStart(2, \"0\");\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;\n}\n","/**\n * 内置 slash 命令:/help /clear /compact /model /config /mcp /cost /resume /quit\n *\n * 设计文档:muse-design.md §7.2 表中 9 条全部覆盖。\n *\n * 设计原则:命令体只编排(解析参数 → 调 actions / 领域模块 → 构造 display)。\n * 真正的业务(压缩、列 session、查 MCP)在各自的领域模块里。\n */\n\nimport type { SlashCommand, SlashCommandContext } from \"./types.js\";\nimport { estimateCostUSD, formatUSD, lookupPricing } from \"../llm/pricing.js\";\nimport { redactApiKey } from \"../log/index.js\";\nimport { compactMessages } from \"../loop/context.js\";\nimport { getMCPStatus } from \"../mcp/index.js\";\nimport { Session } from \"../session/jsonl.js\";\nimport { loadModelsRegistry, visibleEntries, type LoadError } from \"../config/models.js\";\nimport { shortPath, formatList, parseArgs, formatTime } from \"./_format.js\";\n\n// ----- /help -----\n\nconst HELP: SlashCommand = {\n name: \"help\",\n description: \"show available slash commands\",\n execute(ctx) {\n const cmds = ctx.listCommands();\n const heads = cmds.map(headOf);\n const width = Math.max(...heads.map((h) => h.length));\n const lines = [\"Built-in commands:\"];\n for (let i = 0; i < cmds.length; i++) {\n const aliasNote = cmds[i].aliases?.length\n ? ` (alias: ${cmds[i].aliases!.map((a) => `/${a}`).join(\", \")})`\n : \"\";\n lines.push(` /${heads[i].padEnd(width)} ${cmds[i].description}${aliasNote}`);\n }\n lines.push(\"\", \"Keys: Ctrl+C exit\");\n return { display: lines.join(\"\\n\") };\n },\n};\n\nfunction headOf(c: SlashCommand): string {\n return c.argsHint ? `${c.name} ${c.argsHint}` : c.name;\n}\n\n// ----- /clear -----\n\nconst CLEAR: SlashCommand = {\n name: \"clear\",\n description: \"clear conversation history\",\n execute(ctx) {\n ctx.actions.setMessages([]);\n return { display: \"(history cleared)\" };\n },\n};\n\n// ----- /quit -----\n\nconst QUIT: SlashCommand = {\n name: \"quit\",\n aliases: [\"exit\"],\n description: \"exit Muse\",\n execute() {\n return { exit: true };\n },\n};\n\n// ----- /cost -----\n\nconst COST: SlashCommand = {\n name: \"cost\",\n description: \"show token usage and estimated cost for this session\",\n execute(ctx) {\n const { tokens, llm } = ctx;\n const pricing = lookupPricing(llm.providerName, llm.model);\n const lines = [\n `Session cost`,\n ` provider/model: ${llm.providerName} / ${llm.model}`,\n ` input tokens: ${tokens.inputTokens.toLocaleString()}`,\n ` output tokens: ${tokens.outputTokens.toLocaleString()}`,\n ` total tokens: ${tokens.totalTokens.toLocaleString()}`,\n ];\n if (pricing) {\n const cost = estimateCostUSD(llm.providerName, llm.model, tokens.inputTokens, tokens.outputTokens) ?? 0;\n lines.push(\n ` price (per 1M): input $${pricing.inputPer1M} / output $${pricing.outputPer1M}`,\n ` estimated cost: ${formatUSD(cost)}`,\n );\n } else {\n lines.push(` estimated cost: (no pricing data for ${llm.providerName}/${llm.model})`);\n }\n return { display: lines.join(\"\\n\") };\n },\n};\n\n// ----- /compact -----\n\nconst COMPACT: SlashCommand = {\n name: \"compact\",\n description: \"summarize older messages to free up context space\",\n argsHint: \"[--keep N]\",\n async execute(ctx) {\n if (ctx.history.length === 0) return { display: \"(empty history; nothing to compact)\" };\n const { flags } = parseArgs(ctx.args);\n const keepRecent = typeof flags.keep === \"string\" ? Math.max(1, parseInt(flags.keep, 10)) : 4;\n if (Number.isNaN(keepRecent)) return { display: `Invalid --keep value: ${flags.keep}` };\n\n const result = await compactMessages(ctx.history, { llm: ctx.llm, keepRecent });\n if (result.noop) {\n return { display: `(history has ${result.originalCount} messages; not enough to compact with --keep ${keepRecent})` };\n }\n ctx.actions.setMessages(result.newMessages);\n const preview = result.summary.length > 240 ? result.summary.slice(0, 240) + \"…\" : result.summary;\n return {\n display:\n `Compacted ${result.originalCount} → ${result.newCount} messages ` +\n `(kept last ${keepRecent}).\\n\\nSummary:\\n${preview}`,\n };\n },\n};\n\n// ----- /models -----\n\nconst MODELS: SlashCommand = {\n name: \"models\",\n description: \"pick a model from ~/.muse/models.json (↑↓ to navigate)\",\n async execute(ctx) {\n // ctx 没拿到 registry 时同步重读一次:可能 muse 启动后用户改了文件\n let registry = ctx.modelsRegistry;\n let errors: LoadError[] = [];\n if (!registry) {\n const r = await loadModelsRegistry();\n registry = r.registry;\n errors = r.errors;\n }\n\n if (!registry) {\n if (errors.length > 0) {\n return { display: renderLoadErrors(errors) };\n }\n return { display: renderEmptyRegistryHint() };\n }\n\n const visible = visibleEntries(registry);\n if (visible.length === 0) {\n return {\n display:\n `models.json has no available models.\\n` +\n `Check that \"availableModels\" lists at least one id present in \"models\".`,\n };\n }\n\n const picked = await ctx.actions.pickModel(visible, ctx.llm.model);\n if (!picked) return { display: \"(cancelled)\" };\n if (picked.id === ctx.llm.model) return { display: `Already on ${picked.id}.` };\n\n try {\n await ctx.actions.switchModel(picked.id);\n return { display: `Switched to ${picked.id}${picked.vendor ? ` (${picked.vendor})` : \"\"}.` };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return { display: `Failed to switch: ${msg}` };\n }\n },\n};\n\nfunction renderLoadErrors(errors: LoadError[]): string {\n return [\n `models.json was found but failed to load:`,\n ``,\n ...errors.flatMap((e) => [` ${shortPath(e.path)}`, ` ${e.message}`]),\n ``,\n `Fix the file above, then run /models again (it re-reads on each call).`,\n `Hint: each entry needs \"id\" and \"baseUrl\" (or \"url\"); \"apiKey\" supports \\${ENV_VAR}.`,\n ].join(\"\\n\");\n}\n\nfunction renderEmptyRegistryHint(): string {\n return [\n `No models registry found.`,\n `Create ~/.muse/models.json with a \"models\" array. Example:`,\n ``,\n `{`,\n ` \"models\": [`,\n ` {`,\n ` \"id\": \"<your-model-id>\",`,\n ` \"vendor\": \"<vendor-name>\",`,\n ` \"baseUrl\": \"https://...\",`,\n ` \"apiKey\": \"\\${YOUR_API_KEY}\",`,\n ` \"supportsToolCall\": true`,\n ` }`,\n ` ],`,\n ` \"availableModels\": [\"<your-model-id>\"]`,\n `}`,\n ``,\n `Then run /models again (no restart needed).`,\n ].join(\"\\n\");\n}\n\n// ----- /config -----\n\nconst CONFIG: SlashCommand = {\n name: \"config\",\n description: \"show / reload configuration (API keys redacted)\",\n argsHint: \"[reload | path]\",\n async execute(ctx) {\n const sub = ctx.args.trim();\n\n if (sub === \"reload\") {\n try {\n const { sources } = await ctx.actions.reloadSettings();\n return { display: `Reloaded from ${sources.length} sources:\\n` + sources.map((s) => ` - ${shortPath(s)}`).join(\"\\n\") };\n } catch (err) {\n return { display: `Reload failed: ${err instanceof Error ? err.message : String(err)}` };\n }\n }\n\n if (sub === \"path\") {\n return { display: renderConfigPaths(ctx) };\n }\n\n if (sub && sub !== \"show\") {\n return { display: `Unknown subcommand: /config ${sub}. Use: /config [show|reload|path]` };\n }\n\n return { display: renderConfigShow(ctx) };\n },\n};\n\nfunction renderConfigShow(ctx: SlashCommandContext): string {\n const s = ctx.settings;\n const lines = [\n `Effective configuration`,\n ` sources:`,\n ...ctx.settingsSources.map((src) => ` - ${shortPath(src)}`),\n ``,\n ` llm:`,\n ` provider: ${s.llm?.provider ?? \"(unset)\"}`,\n ` model: ${s.llm?.model ?? \"(unset)\"}`,\n ];\n if (s.llm?.temperature !== undefined) lines.push(` temperature: ${s.llm.temperature}`);\n if (s.llm?.maxTokens !== undefined) lines.push(` maxTokens: ${s.llm.maxTokens}`);\n\n lines.push(``, ` providers (apiKey redacted):`);\n for (const [name, cfg] of Object.entries(s.providers ?? {})) {\n lines.push(` ${name}: apiKey=${redactApiKey(cfg.apiKey)} baseUrl=${cfg.baseUrl ?? \"(default)\"}`);\n }\n\n lines.push(``, ` permissions:`);\n lines.push(` defaultMode: ${s.permissions?.defaultMode ?? \"ask\"}`);\n lines.push(` allow: ${formatList(s.permissions?.allow)}`);\n lines.push(` ask: ${formatList(s.permissions?.ask)}`);\n lines.push(` deny: ${formatList(s.permissions?.deny)}`);\n\n lines.push(``, ` ui:`);\n lines.push(` lang: ${s.ui?.lang ?? \"(default)\"}`);\n lines.push(` showBanner: ${s.ui?.showBanner ?? true}`);\n\n return lines.join(\"\\n\");\n}\n\nfunction renderConfigPaths(ctx: SlashCommandContext): string {\n const home = process.env.HOME ?? \"~\";\n return [\n `Configuration file paths (high to low precedence):`,\n ` 1. CLI flags / env (MUSE_PROVIDER, MUSE_MODEL, …)`,\n ` 2. ${shortPath(`${ctx.cwd}/.muse/settings.local.json`)} (project, gitignored)`,\n ` 3. ${shortPath(`${ctx.cwd}/.muse/settings.json`)} (project, committable)`,\n ` 4. ${shortPath(`${home}/.muse/settings.json`)} (global)`,\n ` 5. <built-in defaults>`,\n ``,\n `Edit any of the above, then run /config reload (no restart needed).`,\n ].join(\"\\n\");\n}\n\n// ----- /mcp -----\n\nconst MCP: SlashCommand = {\n name: \"mcp\",\n description: \"show MCP server status\",\n execute(ctx) {\n const status = getMCPStatus(ctx.settings);\n if (status.length === 0) {\n return {\n display:\n `No MCP servers configured.\\n` +\n `Add servers under \"mcpServers\" in your settings.json.\\n` +\n `Note: MCP client integration is planned for v0.3; current /mcp only inspects configuration.`,\n };\n }\n const lines = [`MCP servers (${status.length}):`];\n for (const s of status) {\n const indicator = s.connected ? \"●\" : \"○\";\n lines.push(` ${indicator} ${s.name}`);\n lines.push(` configured: ${s.configured}`);\n lines.push(` connected: ${s.connected}${s.error ? ` (${s.error})` : \"\"}`);\n if (s.connected) lines.push(` tools: ${s.toolCount}`);\n if (s.config?.command) lines.push(` command: ${s.config.command}${s.config.args ? \" \" + s.config.args.join(\" \") : \"\"}`);\n if (s.config?.url) lines.push(` url: ${s.config.url}`);\n }\n return { display: lines.join(\"\\n\") };\n },\n};\n\n// ----- /resume -----\n\nconst RESUME: SlashCommand = {\n name: \"resume\",\n description: \"resume a past session (↑↓ to pick, or pass an id-prefix)\",\n argsHint: \"[session-id-prefix]\",\n async execute(ctx) {\n // 带参快捷路径:直接按 id 前缀加载,不弹 selector\n if (ctx.args) {\n let meta;\n try {\n meta = await Session.resolve(ctx.cwd, ctx.args);\n } catch (err) {\n return { display: err instanceof Error ? err.message : String(err) };\n }\n if (!meta) return { display: `No session matches \"${ctx.args}\".` };\n return loadAndReport(meta, ctx);\n }\n\n // 无参:列出近 20 条交给 selector\n const list = await Session.listAll(ctx.cwd, 20);\n if (list.length === 0) return { display: \"No past sessions in this directory.\" };\n\n const picked = await ctx.actions.pickSession(list, ctx.session.meta.id);\n if (!picked) return { display: \"(cancelled)\" };\n if (picked.id === ctx.session.meta.id) return { display: \"Already on this session.\" };\n\n return loadAndReport(picked, ctx);\n },\n};\n\nasync function loadAndReport(\n meta: { id: string; createdAt: string; path: string; cwd: string },\n ctx: import(\"./types.js\").SlashCommandContext,\n): Promise<{ display: string }> {\n const { events } = await Session.open(meta);\n const messages = Session.messagesFromEvents(events);\n ctx.actions.setMessages(messages);\n return {\n display: `Resumed session ${meta.id.slice(0, 8)} (${messages.length} messages from ${formatTime(meta.createdAt)}).`,\n };\n}\n\n// ----- registry -----\n\nexport const BUILTIN_SLASH_COMMANDS: SlashCommand[] = [\n HELP,\n CLEAR,\n COMPACT,\n MODELS,\n CONFIG,\n MCP,\n COST,\n RESUME,\n QUIT,\n];\n","/**\n * 工具注册中心:管理所有可用工具,提供查询、调用、转 LLM-tool-definition 的能力。\n */\n\nimport { z } from \"zod\";\nimport type { AnyTool, ToolContext, ToolExecuteResult } from \"./types.js\";\nimport type { ToolDefinition as LLMToolDefinition } from \"../types/index.js\";\nimport { ToolError } from \"../types/index.js\";\n\n/** zod schema → JSON Schema (subset)。仅覆盖 v0.1 需要的类型。 */\nfunction zodToJsonSchema(schema: z.ZodType<unknown>): Record<string, unknown> {\n const def = (schema as unknown as { _def: { typeName: string } })._def;\n\n if (def.typeName === \"ZodObject\") {\n const shape = (schema as unknown as z.ZodObject<Record<string, z.ZodTypeAny>>).shape;\n const properties: Record<string, unknown> = {};\n const required: string[] = [];\n for (const [key, value] of Object.entries(shape)) {\n properties[key] = zodToJsonSchema(value as z.ZodType<unknown>);\n if (!(value as unknown as { isOptional?: () => boolean }).isOptional?.()) {\n required.push(key);\n }\n }\n return {\n type: \"object\",\n properties,\n ...(required.length > 0 ? { required } : {}),\n additionalProperties: false,\n };\n }\n\n if (def.typeName === \"ZodString\") {\n const d = def as unknown as { description?: string };\n return { type: \"string\", ...(d.description ? { description: d.description } : {}) };\n }\n\n if (def.typeName === \"ZodNumber\") {\n return { type: \"number\" };\n }\n\n if (def.typeName === \"ZodBoolean\") {\n return { type: \"boolean\" };\n }\n\n if (def.typeName === \"ZodArray\") {\n const inner = (def as unknown as { type: z.ZodType<unknown> }).type;\n return { type: \"array\", items: zodToJsonSchema(inner) };\n }\n\n if (def.typeName === \"ZodOptional\" || def.typeName === \"ZodDefault\") {\n const inner = (def as unknown as { innerType: z.ZodType<unknown> }).innerType;\n return zodToJsonSchema(inner);\n }\n\n if (def.typeName === \"ZodEnum\") {\n const values = (def as unknown as { values: string[] }).values;\n return { type: \"string\", enum: values };\n }\n\n if (def.typeName === \"ZodUnion\") {\n const opts = (def as unknown as { options: z.ZodType<unknown>[] }).options;\n return { anyOf: opts.map(zodToJsonSchema) };\n }\n\n // Fallback: 任意类型\n return {};\n}\n\nfunction getDescription(schema: z.ZodType<unknown>): string | undefined {\n return (schema as unknown as { description?: string }).description;\n}\n\nexport class ToolRegistry {\n private tools = new Map<string, AnyTool>();\n\n register(tool: AnyTool): void {\n if (this.tools.has(tool.name)) {\n throw new Error(`Tool \"${tool.name}\" already registered.`);\n }\n this.tools.set(tool.name, tool);\n }\n\n registerAll(tools: AnyTool[]): void {\n for (const tool of tools) this.register(tool);\n }\n\n get(name: string): AnyTool | undefined {\n return this.tools.get(name);\n }\n\n has(name: string): boolean {\n return this.tools.has(name);\n }\n\n list(): AnyTool[] {\n return Array.from(this.tools.values());\n }\n\n /** 转为 LLM 可读的 tool definition 数组。可选 filter(如 plan 模式过滤只读工具)。 */\n toLLMDefinitions(filter?: (tool: AnyTool) => boolean): LLMToolDefinition[] {\n let tools = this.list();\n if (filter) tools = tools.filter(filter);\n return tools.map((t) => {\n const schema = zodToJsonSchema(t.parameters);\n // 顶层描述:从 zod schema 的 .describe 拿\n const desc = getDescription(t.parameters);\n if (desc && typeof schema === \"object\" && schema !== null) {\n (schema as Record<string, unknown>).description = desc;\n }\n return {\n name: t.name,\n description: t.description,\n parameters: schema,\n };\n });\n }\n\n /** 调用工具:校验参数 → 执行。 */\n async execute(name: string, rawArgs: unknown, ctx: ToolContext): Promise<ToolExecuteResult> {\n const tool = this.tools.get(name);\n if (!tool) {\n throw new ToolError(`Tool \"${name}\" not found.`, name);\n }\n const parseResult = tool.parameters.safeParse(rawArgs);\n if (!parseResult.success) {\n return {\n content: `Invalid arguments for ${name}: ${parseResult.error.message}`,\n isError: true,\n };\n }\n try {\n return await tool.execute(parseResult.data, ctx);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return { content: `Tool ${name} threw: ${msg}`, isError: true };\n }\n }\n}\n","/**\n * Read 工具:读取本地文件,支持 offset/limit 分页。\n * 返回带行号的 `cat -n` 格式,方便 LLM 引用具体行做编辑。\n */\n\nimport { readFile, stat } from \"node:fs/promises\";\nimport { resolve, isAbsolute } from \"node:path\";\nimport { z } from \"zod\";\nimport { defineTool } from \"../types.js\";\nimport { ToolError } from \"../../types/index.js\";\n\nconst ReadArgs = z.object({\n file_path: z.string().describe(\"Absolute or cwd-relative path to the file.\"),\n offset: z.number().int().min(0).optional().describe(\"Line offset (0-based).\"),\n limit: z.number().int().positive().optional().describe(\"Max lines to read. Default 2000.\"),\n});\n\nconst DEFAULT_LIMIT = 2000;\nconst MAX_LINE_LENGTH = 2000; // 单行超长时截断\n\nexport const ReadTool = defineTool({\n name: \"Read\",\n description: \"Read a file from the local filesystem. Returns content with 1-indexed line numbers (cat -n format). Use offset/limit for large files.\",\n parameters: ReadArgs,\n permission: \"read\",\n summarize: (args) => `Read(${args.file_path}${args.offset != null ? `, offset=${args.offset}` : \"\"}${args.limit != null ? `, limit=${args.limit}` : \"\"})`,\n async execute(args, ctx) {\n const path = isAbsolute(args.file_path) ? args.file_path : resolve(ctx.cwd, args.file_path);\n\n let info;\n try {\n info = await stat(path);\n } catch (err) {\n throw new ToolError(`File not found: ${path}`, \"Read\", err);\n }\n\n if (!info.isFile()) {\n throw new ToolError(`Not a regular file: ${path}`, \"Read\");\n }\n\n const content = await readFile(path, \"utf-8\");\n const lines = content.split(/\\r?\\n/);\n const offset = args.offset ?? 0;\n const limit = args.limit ?? DEFAULT_LIMIT;\n const slice = lines.slice(offset, offset + limit);\n\n const numbered = slice.map((line, i) => {\n const lineNo = offset + i + 1;\n const truncated = line.length > MAX_LINE_LENGTH ? line.slice(0, MAX_LINE_LENGTH) + \"... [truncated]\" : line;\n return `${String(lineNo).padStart(5, \" \")}\\t${truncated}`;\n });\n\n let result = numbered.join(\"\\n\");\n if (offset + limit < lines.length) {\n result += `\\n... [${lines.length - offset - limit} more lines, use offset=${offset + limit} to read next]`;\n }\n\n return {\n content: result || \"(empty file)\",\n summary: `Read ${slice.length} lines from ${args.file_path}`,\n };\n },\n});\n","/**\n * 工具系统类型。\n * 内置工具与 MCP 工具都遵循同一接口。\n */\n\nimport type { z } from \"zod\";\n\nexport type PermissionLevel = \"read\" | \"write\" | \"execute\" | \"network\";\n\nexport interface ToolContext {\n cwd: string;\n abortSignal?: AbortSignal;\n /** 询问用户对该工具调用的批准。返回 true=允许,false=拒绝。 */\n askPermission: (toolName: string, args: unknown, summary: string) => Promise<boolean>;\n /** 主代理可能想在工具内部发起子任务,预留口子。 */\n invokeSubagent?: (prompt: string) => Promise<string>;\n}\n\nexport interface ToolExecuteResult {\n /** 给 LLM 看的文本结果。 */\n content: string;\n /** 标记为错误:让 LLM 知道需要修复。 */\n isError?: boolean;\n /** 给 TUI 展示的摘要(一行)。 */\n summary?: string;\n}\n\nexport interface ToolDefinition<TArgs = unknown> {\n name: string;\n description: string;\n /** zod schema 用于参数校验 + 自动转 JSON Schema。 */\n parameters: z.ZodType<TArgs>;\n /** 权限级别:UI 与 permission 模块据此决定 ask/allow/deny。 */\n permission: PermissionLevel;\n /** 一行摘要,给 TUI 在 \"→ ToolName(...)\" 之后显示。 */\n summarize?: (args: TArgs) => string;\n /** 实际执行函数。 */\n execute: (args: TArgs, ctx: ToolContext) => Promise<ToolExecuteResult>;\n}\n\n/** 类型擦除后的工具,用于 registry 存储 / 调用。 */\nexport interface AnyTool {\n name: string;\n description: string;\n parameters: z.ZodType<unknown>;\n permission: PermissionLevel;\n summarize?: (args: unknown) => string;\n execute: (args: unknown, ctx: ToolContext) => Promise<ToolExecuteResult>;\n}\n\nexport function defineTool<TArgs>(def: ToolDefinition<TArgs>): AnyTool {\n return {\n name: def.name,\n description: def.description,\n parameters: def.parameters as z.ZodType<unknown>,\n permission: def.permission,\n summarize: def.summarize as ((args: unknown) => string) | undefined,\n execute: def.execute as (args: unknown, ctx: ToolContext) => Promise<ToolExecuteResult>,\n };\n}\n","/**\n * Write 工具:写入文件(创建或覆盖)。\n *\n * 为防误覆盖,约定调用前必须先 Read 过同一路径(除非文件不存在)。\n * 这个约束实际由 LLM 遵守 (prompt 引导);本工具不强制,但记录到日志。\n */\n\nimport { writeFile, mkdir, stat } from \"node:fs/promises\";\nimport { resolve, isAbsolute, dirname } from \"node:path\";\nimport { z } from \"zod\";\nimport { defineTool } from \"../types.js\";\n\nconst WriteArgs = z.object({\n file_path: z.string().describe(\"Absolute or cwd-relative path to the file.\"),\n content: z.string().describe(\"Full content of the file.\"),\n});\n\nexport const WriteTool = defineTool({\n name: \"Write\",\n description: \"Write a complete file to the local filesystem. Creates parent directories if needed. Overwrites existing files — prefer Edit for partial updates.\",\n parameters: WriteArgs,\n permission: \"write\",\n summarize: (args) => `Write(${args.file_path}, ${args.content.length} chars)`,\n async execute(args, ctx) {\n const path = isAbsolute(args.file_path) ? args.file_path : resolve(ctx.cwd, args.file_path);\n\n let existed = false;\n try {\n const info = await stat(path);\n existed = info.isFile();\n } catch {\n // 文件不存在,正常情况\n }\n\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, args.content, \"utf-8\");\n\n return {\n content: existed\n ? `Overwrote ${path} (${args.content.length} bytes).`\n : `Created ${path} (${args.content.length} bytes).`,\n summary: `${existed ? \"Overwrote\" : \"Created\"} ${args.file_path}`,\n };\n },\n});\n","/**\n * Edit 工具:在文件中做精确字符串替换。\n *\n * 必须先 Read 过文件(由调用方/LLM 遵守,不强制校验)。\n * old_string 必须在文件中唯一出现;replace_all=true 时不要求唯一。\n */\n\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { resolve, isAbsolute } from \"node:path\";\nimport { z } from \"zod\";\nimport { defineTool } from \"../types.js\";\nimport { ToolError } from \"../../types/index.js\";\n\nconst EditArgs = z.object({\n file_path: z.string().describe(\"Absolute or cwd-relative path to the file.\"),\n old_string: z.string().describe(\"Exact substring to replace. Must be unique unless replace_all=true.\"),\n new_string: z.string().describe(\"Replacement string.\"),\n replace_all: z.boolean().optional().describe(\"Replace every occurrence. Default false.\"),\n});\n\nexport const EditTool = defineTool({\n name: \"Edit\",\n description: \"Perform an exact string replacement in a file. Old string must be unique unless replace_all=true. Cheaper than Write when only a small part needs to change.\",\n parameters: EditArgs,\n permission: \"write\",\n summarize: (args) => `Edit(${args.file_path})`,\n async execute(args, ctx) {\n const path = isAbsolute(args.file_path) ? args.file_path : resolve(ctx.cwd, args.file_path);\n\n let content: string;\n try {\n content = await readFile(path, \"utf-8\");\n } catch (err) {\n throw new ToolError(`Cannot read ${path}: ${err instanceof Error ? err.message : String(err)}`, \"Edit\", err);\n }\n\n if (args.old_string === args.new_string) {\n return { content: \"old_string is identical to new_string; nothing to do.\", isError: true };\n }\n\n const occurrences = countOccurrences(content, args.old_string);\n if (occurrences === 0) {\n return {\n content: `old_string not found in ${args.file_path}. Did you read the file first? Check whitespace and indentation.`,\n isError: true,\n };\n }\n if (occurrences > 1 && !args.replace_all) {\n return {\n content: `old_string occurs ${occurrences} times in ${args.file_path}. Either expand context to make it unique, or set replace_all=true.`,\n isError: true,\n };\n }\n\n const newContent = args.replace_all\n ? content.split(args.old_string).join(args.new_string)\n : content.replace(args.old_string, args.new_string);\n\n await writeFile(path, newContent, \"utf-8\");\n\n return {\n content: `Edited ${path}: replaced ${args.replace_all ? occurrences : 1} occurrence(s).`,\n summary: `Edited ${args.file_path}`,\n };\n },\n});\n\nfunction countOccurrences(haystack: string, needle: string): number {\n if (needle.length === 0) return 0;\n let count = 0;\n let pos = 0;\n while ((pos = haystack.indexOf(needle, pos)) !== -1) {\n count += 1;\n pos += needle.length;\n }\n return count;\n}\n","/**\n * Bash 工具:执行 shell 命令。\n *\n * 安全:内置 deny 列表(无法 allow 绕过)。\n * 上限:超时 + stdout 截断。\n */\n\nimport { execa } from \"execa\";\nimport { z } from \"zod\";\nimport { defineTool } from \"../types.js\";\n\nconst BashArgs = z.object({\n command: z.string().describe(\"Shell command to run. Will be executed via sh -c.\"),\n timeout: z.number().int().positive().optional().describe(\"Timeout in milliseconds. Default 120000 (2 min). Max 600000.\"),\n description: z.string().optional().describe(\"Brief description (3-10 words) for the UI.\"),\n});\n\nconst DEFAULT_TIMEOUT_MS = 120_000;\nconst MAX_TIMEOUT_MS = 600_000;\nconst MAX_OUTPUT_BYTES = 100_000;\n\n/** 即使在 allow 列表里也强制阻断的危险命令模式。 */\nconst HARD_DENY_PATTERNS: RegExp[] = [\n /\\brm\\s+-rf\\s+\\/(?:\\s|$)/, // rm -rf /\n /\\brm\\s+-rf\\s+~(?:\\/|\\s|$)/, // rm -rf ~ or ~/...\n /\\brm\\s+-rf\\s+\\*/, // rm -rf *\n /\\bdd\\s+.*of=\\/dev\\//, // dd of=/dev/*\n /\\bmkfs\\b/, // mkfs\n /:\\(\\)\\s*\\{\\s*:\\|:&\\s*\\}\\s*;\\s*:/, // fork bomb\n /\\bsudo\\b/, // sudo(v0.1 简单粗暴禁掉)\n /\\bcurl\\s+[^|]*\\|\\s*(?:sh|bash|zsh)/, // curl ... | sh\n /\\bwget\\s+[^|]*\\|\\s*(?:sh|bash|zsh)/, // wget ... | sh\n];\n\nfunction checkDangerous(command: string): { dangerous: true; reason: string } | { dangerous: false } {\n for (const pattern of HARD_DENY_PATTERNS) {\n if (pattern.test(command)) {\n return { dangerous: true, reason: `matches pattern ${pattern}` };\n }\n }\n return { dangerous: false };\n}\n\nexport const BashTool = defineTool({\n name: \"Bash\",\n description: \"Execute a shell command via sh -c. Use for git, file system listings, builds, tests, etc. Avoid interactive commands (prefer non-interactive flags). For file edits use Edit/Write, not sed/echo.\",\n parameters: BashArgs,\n permission: \"execute\",\n summarize: (args) => args.description ?? `Bash: ${args.command.length > 60 ? args.command.slice(0, 60) + \"...\" : args.command}`,\n async execute(args, ctx) {\n const danger = checkDangerous(args.command);\n if (danger.dangerous) {\n return {\n content: `Refused: command blocked by hard deny list (${danger.reason}). If you really need this, ask the user to run it manually.`,\n isError: true,\n };\n }\n\n const timeout = Math.min(args.timeout ?? DEFAULT_TIMEOUT_MS, MAX_TIMEOUT_MS);\n\n try {\n const result = await execa(args.command, {\n shell: \"/bin/sh\",\n cwd: ctx.cwd,\n timeout,\n reject: false,\n stripFinalNewline: false,\n maxBuffer: MAX_OUTPUT_BYTES * 2,\n cancelSignal: ctx.abortSignal,\n });\n\n const stdout = truncate(result.stdout ?? \"\", MAX_OUTPUT_BYTES, \"stdout\");\n const stderr = truncate(result.stderr ?? \"\", MAX_OUTPUT_BYTES, \"stderr\");\n\n const parts: string[] = [];\n if (stdout) parts.push(`<stdout>\\n${stdout}\\n</stdout>`);\n if (stderr) parts.push(`<stderr>\\n${stderr}\\n</stderr>`);\n if (result.timedOut) parts.push(`<timeout>Command exceeded ${timeout}ms.</timeout>`);\n if (result.failed && !result.timedOut) parts.push(`<exit_code>${result.exitCode ?? \"unknown\"}</exit_code>`);\n\n const body = parts.length > 0 ? parts.join(\"\\n\") : \"(no output)\";\n return {\n content: body,\n isError: result.failed,\n summary: result.failed ? `Bash exited ${result.exitCode ?? \"?\"}` : `Bash ok`,\n };\n } catch (err) {\n return {\n content: `Bash threw: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n});\n\nfunction truncate(text: string, max: number, label: string): string {\n if (text.length <= max) return text;\n return text.slice(0, max) + `\\n... [${label} truncated, original ${text.length} bytes]`;\n}\n","/**\n * Grep 工具:基于 ripgrep 包装(若可用),fallback 到 bash grep。\n * v0.1 简单实现:直接调 system rg / grep。\n */\n\nimport { execa } from \"execa\";\nimport { z } from \"zod\";\nimport { defineTool } from \"../types.js\";\n\nconst GrepArgs = z.object({\n pattern: z.string().describe(\"Regex pattern to search for.\"),\n path: z.string().optional().describe(\"File or directory to search in. Default: cwd.\"),\n glob: z.string().optional().describe('Glob filter, e.g. \"*.ts\" or \"src/**/*.tsx\".'),\n output_mode: z.enum([\"content\", \"files_with_matches\", \"count\"]).optional().describe(\"Default: files_with_matches.\"),\n context: z.number().int().min(0).max(50).optional().describe(\"Context lines around each match (use only with output_mode=content).\"),\n case_insensitive: z.boolean().optional(),\n});\n\nlet rgChecked = false;\nlet rgAvailable = false;\n\nasync function checkRipgrep(): Promise<boolean> {\n if (rgChecked) return rgAvailable;\n try {\n await execa(\"rg\", [\"--version\"], { reject: false });\n rgAvailable = true;\n } catch {\n rgAvailable = false;\n }\n rgChecked = true;\n return rgAvailable;\n}\n\nexport const GrepTool = defineTool({\n name: \"Grep\",\n description: \"Search file contents using regex. Prefer this over Bash(grep|find) — handles ignore files & is much faster on large trees.\",\n parameters: GrepArgs,\n permission: \"read\",\n summarize: (args) => `Grep(${args.pattern}${args.path ? `, ${args.path}` : \"\"})`,\n async execute(args, ctx) {\n const hasRg = await checkRipgrep();\n const mode = args.output_mode ?? \"files_with_matches\";\n\n if (hasRg) {\n const cliArgs: string[] = [];\n if (args.case_insensitive) cliArgs.push(\"-i\");\n if (mode === \"files_with_matches\") cliArgs.push(\"-l\");\n else if (mode === \"count\") cliArgs.push(\"-c\");\n else if (args.context != null) cliArgs.push(\"-C\", String(args.context));\n if (args.glob) cliArgs.push(\"--glob\", args.glob);\n cliArgs.push(\"--\", args.pattern, args.path ?? \".\");\n\n const result = await execa(\"rg\", cliArgs, { cwd: ctx.cwd, reject: false, cancelSignal: ctx.abortSignal });\n const out = (result.stdout ?? \"\").trim();\n if (result.exitCode === 0 || result.exitCode === 1) {\n return { content: out || \"(no matches)\", summary: `Grep ${args.pattern}` };\n }\n return { content: `rg failed: ${result.stderr}`, isError: true };\n }\n\n // Fallback: bash grep -r\n const cliArgs = [\"-r\", \"-n\"];\n if (args.case_insensitive) cliArgs.push(\"-i\");\n if (mode === \"files_with_matches\") cliArgs.push(\"-l\");\n else if (mode === \"count\") cliArgs.push(\"-c\");\n cliArgs.push(\"-E\", args.pattern, args.path ?? \".\");\n\n const result = await execa(\"grep\", cliArgs, { cwd: ctx.cwd, reject: false, cancelSignal: ctx.abortSignal });\n const out = (result.stdout ?? \"\").trim();\n if (result.exitCode === 0 || result.exitCode === 1) {\n return { content: out || \"(no matches)\", summary: `Grep ${args.pattern}` };\n }\n return { content: `grep failed: ${result.stderr}`, isError: true };\n },\n});\n","/**\n * Glob 工具:用 fast-glob 列出匹配文件。\n */\n\nimport fg from \"fast-glob\";\nimport { z } from \"zod\";\nimport { defineTool } from \"../types.js\";\n\nconst GlobArgs = z.object({\n pattern: z.string().describe('Glob pattern, e.g. \"src/**/*.ts\" or \"**/*.{md,json}\".'),\n path: z.string().optional().describe(\"Base directory to search from. Default: cwd.\"),\n limit: z.number().int().positive().max(1000).optional().describe(\"Max results. Default 100.\"),\n});\n\nconst DEFAULT_LIMIT = 100;\n\nexport const GlobTool = defineTool({\n name: \"Glob\",\n description: \"Find files by glob pattern. Returns relative paths sorted by modification time (newest first).\",\n parameters: GlobArgs,\n permission: \"read\",\n summarize: (args) => `Glob(${args.pattern}${args.path ? `, ${args.path}` : \"\"})`,\n async execute(args, ctx) {\n const cwd = args.path ?? ctx.cwd;\n const limit = args.limit ?? DEFAULT_LIMIT;\n\n const entries = await fg(args.pattern, {\n cwd,\n onlyFiles: true,\n stats: true,\n dot: false,\n ignore: [\"**/node_modules/**\", \"**/.git/**\", \"**/dist/**\", \"**/.muse/**\"],\n });\n\n // 按 mtime 倒序\n entries.sort((a, b) => {\n const ta = a.stats?.mtime?.getTime() ?? 0;\n const tb = b.stats?.mtime?.getTime() ?? 0;\n return tb - ta;\n });\n\n const truncated = entries.length > limit;\n const paths = entries.slice(0, limit).map((e) => e.path);\n\n let result = paths.join(\"\\n\") || \"(no matches)\";\n if (truncated) {\n result += `\\n... [${entries.length - limit} more, increase limit to see]`;\n }\n return { content: result, summary: `Glob found ${entries.length} file(s)` };\n },\n});\n","import type { AnyTool } from \"../types.js\";\nimport { ReadTool } from \"./read.js\";\nimport { WriteTool } from \"./write.js\";\nimport { EditTool } from \"./edit.js\";\nimport { BashTool } from \"./bash.js\";\nimport { GrepTool } from \"./grep.js\";\nimport { GlobTool } from \"./glob.js\";\n\nexport { ReadTool, WriteTool, EditTool, BashTool, GrepTool, GlobTool };\n\nexport const BUILTIN_TOOLS: AnyTool[] = [\n ReadTool,\n WriteTool,\n EditTool,\n BashTool,\n GrepTool,\n GlobTool,\n];\n"],"mappings":"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","names":["useMemo","useState","Box","Text","useInput","mkdir","readFile","existsSync","homedir","dirname","join","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","Box","Text","Box","Text","useInput","jsx","jsxs","jsx","jsxs","resolve","Box","Text","Box","Text","jsx","jsxs","resolve","Box","Text","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","Box","Text","tool","result","homedir","homedir","join","join","homedir","readFile","existsSync","homedir","join","z","z","join","homedir","existsSync","readFile","formatZodIssues","readFile","existsSync","homedir","dirname","join","join","homedir","existsSync","dirname","readFile","homedir","formatTime","formatTime","jsx","jsxs","useState","useMemo","resolve","useInput","Box","Text","homedir","join","existsSync","readFile","mkdir","dirname","tool","readFile","stat","resolve","z","z","resolve","stat","readFile","writeFile","mkdir","stat","resolve","isAbsolute","dirname","z","z","isAbsolute","resolve","stat","mkdir","dirname","writeFile","readFile","writeFile","resolve","isAbsolute","z","z","isAbsolute","resolve","readFile","writeFile","z","z","execa","z","z","execa","cliArgs","result","out","z","z","DEFAULT_LIMIT","jsx"]}
1
+ {"version":3,"sources":["../src/cli.tsx","../src/app.tsx","../src/components/BgTextInput.tsx","../src/components/StartupBanner.tsx","../src/components/MessageView.tsx","../node_modules/chalk/source/vendor/ansi-styles/index.js","../node_modules/chalk/source/vendor/supports-color/index.js","../node_modules/chalk/source/utilities.js","../node_modules/chalk/source/index.js","../src/components/PermissionPrompt.tsx","../src/components/ModelSelector.tsx","../src/components/Selector.tsx","../src/components/SessionSelector.tsx","../src/components/QuestionPicker.tsx","../src/components/SlashAutocomplete.tsx","../src/components/PermissionModeBar.tsx","../src/permission/index.ts","../src/components/FooterStatus.tsx","../src/components/ProgressBanner.tsx","../src/components/StatusLine.tsx","../src/components/Shimmer.tsx","../src/ui/termTitle.ts","../src/llm/providers/openai-compatible.ts","../src/log/index.ts","../src/types/index.ts","../src/llm/client.ts","../src/loop/todos.ts","../src/loop/agent.ts","../src/loop/system-prompt.ts","../src/loop/memory.ts","../src/config/loader.ts","../src/config/types.ts","../src/config/_env.ts","../src/config/models.ts","../src/slash/registry.ts","../src/llm/pricing.ts","../src/loop/context.ts","../src/mcp/index.ts","../src/session/jsonl.ts","../src/slash/_format.ts","../src/slash/builtin.ts","../src/tools/registry.ts","../src/tools/builtin/read.ts","../src/tools/types.ts","../src/tools/_sensitive.ts","../src/tools/builtin/write.ts","../src/tools/_diff.ts","../src/tools/builtin/edit.ts","../src/tools/builtin/bash.ts","../src/tools/builtin/grep.ts","../src/tools/builtin/glob.ts","../src/tools/builtin/todo.ts","../src/tools/builtin/webfetch.ts","../src/tools/builtin/memory.ts","../src/tools/builtin/ask-user-question.ts","../src/tools/builtin/index.ts"],"sourcesContent":["/**\n * CLI 入口。解析 argv → 加载配置 → 启动交互或单次模式。\n */\n\nimport React from \"react\";\nimport { Command } from \"commander\";\nimport { render } from \"ink\";\nimport { App } from \"./app.js\";\nimport { loadSettings } from \"./config/index.js\";\nimport { loadModelsRegistry, findEntry } from \"./config/models.js\";\nimport { createLLMClient, createLLMClientFromModelEntry, setActiveModelEnv } from \"./llm/client.js\";\nimport { ToolRegistry } from \"./tools/registry.js\";\nimport { BUILTIN_TOOLS } from \"./tools/builtin/index.js\";\nimport { PermissionGate } from \"./permission/index.js\";\nimport { Session } from \"./session/jsonl.js\";\nimport { Agent } from \"./loop/agent.js\";\nimport { buildSystemPrompt } from \"./loop/system-prompt.js\";\nimport { loadMemoryIndex } from \"./loop/memory.js\";\nimport { MuseError } from \"./types/index.js\";\nimport { log } from \"./log/index.js\";\n\nconst VERSION = \"0.1.0\";\n\nasync function main() {\n const program = new Command();\n\n program\n .name(\"muse\")\n .description(\"A TypeScript agent CLI built around OpenAI-compatible APIs. First-class support for self-hostable and Chinese LLMs.\")\n .version(VERSION, \"-v, --version\", \"print version\");\n\n program\n .argument(\"[prompt...]\", \"one-shot prompt (omit for interactive mode)\")\n .option(\"-m, --model <model>\", \"override model\")\n .option(\"-p, --provider <provider>\", \"override provider\")\n .option(\"--no-banner\", \"skip startup banner\")\n .option(\"--quiet\", \"minimal output (implies --no-banner)\")\n .option(\"--continue\", \"resume last session in this directory\")\n .option(\"--mode <mode>\", \"initial permission mode (default|acceptEdits|plan|bypassPermissions)\")\n .option(\"--debug\", \"verbose logging\")\n .action(async (promptArgs: string[], opts: CliOptions) => {\n if (opts.debug) log.setLevel(\"debug\");\n\n const cwd = process.cwd();\n const { settings, sources } = await loadSettings(cwd);\n const { registry: modelsRegistry, sources: modelsSources } = await loadModelsRegistry();\n log.debug(\"config loaded\", { settingsSources: sources, modelsSources });\n\n const model = opts.model ?? settings.llm?.model;\n const provider = opts.provider ?? settings.llm?.provider;\n\n let llm;\n let llmProviderName: string;\n let llmModelName: string;\n try {\n // models.local.json 里找到 settings.llm.model(或 -m)对应的 entry:\n // 注入 apiKey 到 process.env.MUSE_ACTIVE_API_KEY,业务通过 env 读\n const entry = modelsRegistry && model ? findEntry(modelsRegistry, model) : undefined;\n if (entry) {\n setActiveModelEnv(entry);\n llm = createLLMClientFromModelEntry(entry);\n llmProviderName = llm.providerName;\n llmModelName = llm.model;\n } else {\n // 优先级 2:回退到 settings.json 原生 provider/model + providers 配置\n if (!provider || !model) {\n die(\"No model configured. Either define one in ~/.muse/models.local.json or set llm.provider+llm.model in settings.json.\");\n }\n llm = createLLMClient({ provider, model, providers: settings.providers ?? {} });\n llmProviderName = provider;\n llmModelName = model;\n }\n } catch (err) {\n if (err instanceof MuseError) die(err.message);\n throw err;\n }\n\n const tools = new ToolRegistry();\n tools.registerAll(BUILTIN_TOOLS);\n\n const permissions = new PermissionGate(settings.permissions);\n\n // --mode 启动期指定 PermissionMode;后续 Shift+Tab / /mode 仍可切换\n if (opts.mode) {\n const valid = [\"default\", \"acceptEdits\", \"plan\", \"bypassPermissions\"] as const;\n if (!(valid as readonly string[]).includes(opts.mode)) {\n die(`Invalid --mode \"${opts.mode}\". Valid: ${valid.join(\", \")}`);\n }\n permissions.setMode(opts.mode as (typeof valid)[number]);\n }\n\n // --continue: 复用最近一次 session 的 jsonl + messages\n let session: Session;\n let initialMessages: import(\"./types/index.js\").Message[] | undefined;\n if (opts.continue) {\n const latest = await Session.findLatest(cwd);\n if (latest) {\n const opened = await Session.open(latest);\n session = opened.session;\n initialMessages = Session.messagesFromEvents(opened.events);\n log.debug(\"resumed session\", { id: latest.id, messages: initialMessages.length });\n } else {\n session = await Session.create(cwd);\n await session.append({\n type: \"session_start\",\n time: new Date().toISOString(),\n cwd,\n provider: llmProviderName,\n model: llmModelName,\n });\n }\n } else {\n session = await Session.create(cwd);\n await session.append({\n type: \"session_start\",\n time: new Date().toISOString(),\n cwd,\n provider: llmProviderName,\n model: llmModelName,\n });\n }\n\n const showBanner = !opts.quiet && opts.banner !== false;\n const lang = settings.ui?.lang ?? \"en\";\n\n // Pipe input → 拼成一次性 prompt\n const pipedInput = await readStdinIfPiped();\n const oneShotPrompt = [...(promptArgs ?? []), pipedInput].filter(Boolean).join(\"\\n\").trim();\n\n if (oneShotPrompt) {\n await runOneShot({\n llm,\n tools,\n permissions,\n session,\n cwd,\n lang,\n prompt: oneShotPrompt,\n quiet: opts.quiet ?? false,\n initialMessages,\n });\n return;\n }\n\n // Interactive mode\n const { waitUntilExit } = render(\n <App\n llm={llm}\n tools={tools}\n permissions={permissions}\n session={session}\n settings={settings}\n settingsSources={sources}\n modelsRegistry={modelsRegistry}\n modelsSources={modelsSources}\n cwd={cwd}\n lang={lang}\n showBanner={showBanner}\n initialMessages={initialMessages}\n />,\n );\n await waitUntilExit();\n });\n\n await program.parseAsync(process.argv);\n}\n\ninterface CliOptions {\n model?: string;\n provider?: string;\n banner?: boolean;\n quiet?: boolean;\n continue?: boolean;\n mode?: string;\n debug?: boolean;\n}\n\nasync function readStdinIfPiped(): Promise<string> {\n if (process.stdin.isTTY) return \"\";\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) chunks.push(chunk as Buffer);\n return Buffer.concat(chunks).toString(\"utf-8\").trim();\n}\n\nasync function runOneShot(opts: {\n llm: ReturnType<typeof createLLMClient>;\n tools: ToolRegistry;\n permissions: PermissionGate;\n session: Session;\n cwd: string;\n lang: \"en\" | \"zh-CN\";\n prompt: string;\n quiet: boolean;\n initialMessages?: import(\"./types/index.js\").Message[];\n}): Promise<void> {\n const memoryIndex = await loadMemoryIndex(opts.cwd);\n const systemPrompt = buildSystemPrompt({\n cwd: opts.cwd,\n model: opts.llm.model,\n provider: opts.llm.providerName,\n lang: opts.lang,\n toolNames: opts.tools.list().map((t) => t.name),\n memoryIndex,\n });\n const agent = new Agent({\n llm: opts.llm,\n tools: opts.tools,\n permissions: opts.permissions,\n session: opts.session,\n cwd: opts.cwd,\n systemPrompt,\n events: {\n onText: (delta) => process.stdout.write(delta),\n onToolCallStart: (_id, name) => {\n if (!opts.quiet) process.stderr.write(`\\n→ ${name}\\n`);\n },\n onError: (err) => process.stderr.write(`\\n[error] ${err.message}\\n`),\n onPermissionRequest: async (toolName, _args, summary) => {\n // 非交互模式:deny 所有需要 ask 的工具\n if (!opts.quiet) process.stderr.write(`\\n[denied: ${toolName} — ${summary}; run in interactive mode to approve]\\n`);\n return \"no\";\n },\n },\n });\n if (opts.initialMessages?.length) agent.setMessages(opts.initialMessages);\n await agent.runTurn(opts.prompt);\n process.stdout.write(\"\\n\");\n}\n\nfunction die(msg: string): never {\n process.stderr.write(`muse: ${msg}\\n`);\n process.exit(1);\n}\n\nmain().catch((err) => {\n log.error(\"fatal\", { msg: err instanceof Error ? err.message : String(err) });\n process.stderr.write(`muse: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n});\n","/**\n * Ink 根组件:banner + 消息历史 + 输入框 + 流式响应 + slash 命令调度。\n *\n * SlashActions 在这里注入。LLM client / settings / modelsRegistry 都是 mutable state,\n * /models /config reload 通过 setLLM / setSettings / setModelsRegistry 触发 Agent 重建,\n * messages 通过 messagesRef 跨重建保留。\n */\n\nimport React, { useCallback, useEffect, useMemo, useReducer, useRef, useState } from \"react\";\nimport { Box, Text, useApp, useInput, useStdout } from \"ink\";\nimport { BgTextInput } from \"./components/BgTextInput.js\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { basename, dirname, join } from \"node:path\";\nimport { pickBanner } from \"./components/StartupBanner.js\";\nimport { MessageView } from \"./components/MessageView.js\";\nimport { PermissionPrompt, type PermissionRequest } from \"./components/PermissionPrompt.js\";\nimport { ModelSelector, type ModelPickerRequest } from \"./components/ModelSelector.js\";\nimport { SessionSelector, type SessionPickerRequest } from \"./components/SessionSelector.js\";\nimport { QuestionPicker, type QuestionPickerRequest } from \"./components/QuestionPicker.js\";\nimport { SlashAutocomplete } from \"./components/SlashAutocomplete.js\";\nimport { PermissionModeBar } from \"./components/PermissionModeBar.js\";\nimport { FooterStatus } from \"./components/FooterStatus.js\";\nimport { ProgressBanner, type ProgressState } from \"./components/ProgressBanner.js\";\nimport { StatusLine } from \"./components/StatusLine.js\";\nimport { DOT } from \"./components/MessageView.js\";\nimport { setTerminalTitle, resetTerminalTitle } from \"./ui/termTitle.js\";\nimport type { LLMClient } from \"./llm/types.js\";\nimport { createLLMClient, createLLMClientFromModelEntry, setActiveModelEnv } from \"./llm/client.js\";\nimport type { ToolRegistry } from \"./tools/registry.js\";\nimport { PermissionGate, type PermissionMode, type PermissionDecision } from \"./permission/index.js\";\nimport { Session, type SessionSummary } from \"./session/jsonl.js\";\nimport { Agent } from \"./loop/agent.js\";\nimport { buildSystemPrompt } from \"./loop/system-prompt.js\";\nimport { loadMemoryIndex } from \"./loop/memory.js\";\nimport { loadSettings } from \"./config/index.js\";\nimport { loadModelsRegistry, findEntry, type ModelEntry, type ModelsRegistry } from \"./config/models.js\";\nimport type { Message, ToolMessage, TokenUsage } from \"./types/index.js\";\nimport type { Settings } from \"./config/types.js\";\nimport {\n BUILTIN_SLASH_COMMANDS,\n SlashRegistry,\n parseSlash,\n type SlashActions,\n type SlashCommand,\n type SlashCommandResult,\n} from \"./slash/index.js\";\n\nexport interface AppProps {\n llm: LLMClient;\n tools: ToolRegistry;\n permissions: PermissionGate;\n session: Session;\n settings: Settings;\n settingsSources: string[];\n modelsRegistry?: ModelsRegistry;\n modelsSources: string[];\n cwd: string;\n lang: \"en\" | \"zh-CN\";\n showBanner: boolean;\n initialMessages?: Message[];\n}\n\ninterface UIState {\n history: Message[];\n streamingText: string;\n status: \"idle\" | \"streaming\" | \"tool\";\n /** 当前正在跑的工具名(onToolCallStart 设置;下一次 stream_delta 或 turn_end 清空)。 */\n runningTool: string | null;\n /** session 累计 token(/cost 用),不是本轮快照——本轮快照走 turn* 引用 */\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n /** 本轮起点(user_submit 触发时 Date.now()),StatusLine 用;idle 时为 0 */\n turnStartTime: number;\n /** 本轮首次 text-delta 时间,StatusLine 显示 \"thought for\" 用;null 表示还未流出 text */\n turnFirstTextTime: number | null;\n /** 本轮已累计 input tokens(多轮 tool loop 累加) */\n turnInputTokens: number;\n}\n\ntype UIAction =\n | { type: \"user_submit\" }\n | { type: \"history_set\"; messages: Message[] }\n | { type: \"stream_delta\"; delta: string }\n | { type: \"stream_reset\" }\n | { type: \"set_status\"; status: UIState[\"status\"] }\n | { type: \"tool_start\"; name: string }\n | { type: \"add_usage\"; usage: TokenUsage };\n\nfunction reducer(state: UIState, action: UIAction): UIState {\n switch (action.type) {\n case \"user_submit\":\n return {\n ...state,\n streamingText: \"\",\n status: \"streaming\",\n runningTool: null,\n turnStartTime: Date.now(),\n turnFirstTextTime: null,\n turnInputTokens: 0,\n };\n case \"history_set\":\n return { ...state, history: action.messages };\n case \"stream_delta\":\n // 文本流出意味着 LLM 在思考 / 回话——若刚才在 tool 阶段,自然过渡为 streaming\n // 第一次流出时打 turnFirstTextTime 时间戳(\"thought for\" 用),冻结不再变\n return {\n ...state,\n streamingText: state.streamingText + action.delta,\n status: state.status === \"tool\" ? \"streaming\" : state.status,\n runningTool: null,\n turnFirstTextTime: state.turnFirstTextTime ?? Date.now(),\n };\n case \"stream_reset\":\n return { ...state, streamingText: \"\" };\n case \"set_status\":\n return {\n ...state,\n status: action.status,\n runningTool: action.status === \"tool\" ? state.runningTool : null,\n };\n case \"tool_start\":\n return { ...state, status: \"tool\", runningTool: action.name };\n case \"add_usage\":\n return {\n ...state,\n inputTokens: state.inputTokens + action.usage.inputTokens,\n outputTokens: state.outputTokens + action.usage.outputTokens,\n totalTokens: state.totalTokens + action.usage.totalTokens,\n turnInputTokens: state.turnInputTokens + action.usage.inputTokens,\n };\n }\n}\n\nexport function App({\n llm: initialLLM,\n tools,\n permissions: initialPermissions,\n session,\n settings: initialSettings,\n settingsSources: initialSources,\n modelsRegistry: initialModelsRegistry,\n cwd,\n lang,\n showBanner,\n initialMessages,\n}: AppProps) {\n const { exit } = useApp();\n const { stdout } = useStdout();\n const termWidth = stdout?.columns ?? 80;\n\n const [llm, setLLM] = useState<LLMClient>(initialLLM);\n const [permissions, setPermissions] = useState<PermissionGate>(initialPermissions);\n const [settings, setSettings] = useState<Settings>(initialSettings);\n const [settingsSources, setSettingsSources] = useState<string[]>(initialSources);\n const [modelsRegistry, setModelsRegistry] = useState<ModelsRegistry | undefined>(initialModelsRegistry);\n const [mode, setMode] = useState<PermissionMode>(initialPermissions.getMode());\n\n const [state, dispatch] = useReducer(reducer, {\n history: initialMessages ?? [],\n streamingText: \"\",\n status: \"idle\",\n runningTool: null,\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n turnStartTime: 0,\n turnFirstTextTime: null,\n turnInputTokens: 0,\n });\n\n const messagesRef = useRef<Message[]>(initialMessages ?? []);\n\n const [input, setInput] = useState(\"\");\n // inputRemountKey 给 TextInput 做 remount —— ink-text-input 在 value 被外部强制修改时\n // cursor 不会跟随到末尾,bump 一个 key 让组件重挂载,新实例 cursor 默认在 value.length。\n // onChange 用 setInput 不能 bump(每次按键都 remount 会丢 cursor);只有补全 / 清空等\n // \"外部 setValue\" 操作走 commitInput。\n const [inputRemountKey, setInputRemountKey] = useState(0);\n const commitInput = (value: string) => {\n setInput(value);\n setInputRemountKey((k) => k + 1);\n };\n // 粘贴 registry:大段粘贴的原文按 id 存这里,输入框里只显示 [Pasted text #N +M lines]\n // 占位符。提交 / 入队 dequeue 时再用 expandPastes 还原成原文发给 LLM。\n // 用 ref 不用 state——内容只在 onPaste/onSubmit 的瞬时事件里读,不需要触发渲染。\n const pasteRegistryRef = useRef<{ map: Map<number, string>; nextId: number }>({\n map: new Map(),\n nextId: 1,\n });\n const handlePaste = useCallback((chunk: string): string => {\n const reg = pasteRegistryRef.current;\n const id = reg.nextId++;\n reg.map.set(id, chunk);\n const lines = chunk.split(\"\\n\").length;\n return `[Pasted text #${id} +${lines} lines]`;\n }, []);\n\n const [pending, setPending] = useState<PermissionRequest | null>(null);\n const [picker, setPicker] = useState<ModelPickerRequest | null>(null);\n const [sessionPicker, setSessionPicker] = useState<SessionPickerRequest | null>(null);\n const [questionPicker, setQuestionPicker] = useState<QuestionPickerRequest | null>(null);\n const [autocompleteIndex, setAutocompleteIndex] = useState(0);\n const [progress, setProgress] = useState<ProgressState | null>(null);\n const agentRef = useRef<Agent | null>(null);\n\n // 输入队列:模型在跑时用户继续提交的消息暂存在这里,本轮结束 onTurnEnd 自动出队跑下一轮\n // ref 作真相源(同步访问),state 用于触发 UI 重渲染显示队列预览\n const queuedInputsRef = useRef<string[]>([]);\n const [queuedInputs, setQueuedInputs] = useState<string[]>([]);\n const enqueueInput = (text: string) => {\n queuedInputsRef.current.push(text);\n setQueuedInputs([...queuedInputsRef.current]);\n };\n const dequeueInput = (): string | null => {\n if (queuedInputsRef.current.length === 0) return null;\n const front = queuedInputsRef.current.shift()!;\n setQueuedInputs([...queuedInputsRef.current]);\n return front;\n };\n\n // 输入历史:纯用户输入(不含 slash 命令),最旧 → 最新 push 到末尾\n // historyIndex: -1=未导航;0=最新;len-1=最旧\n const inputHistoryRef = useRef<string[]>(extractUserInputs(initialMessages ?? []));\n const historyIndexRef = useRef<number>(-1);\n const savedDraftRef = useRef<string>(\"\");\n\n const slash = useMemo(() => {\n const r = new SlashRegistry();\n r.registerAll(BUILTIN_SLASH_COMMANDS);\n return r;\n }, []);\n\n // input.startsWith(\"/\") && 命令名阶段(无空格)→ 显示匹配候选\n const autocomplete = useMemo<{ matches: SlashCommand[]; query: string } | null>(() => {\n if (!input.startsWith(\"/\")) return null;\n const body = input.slice(1);\n if (body.includes(\" \")) return null;\n const query = body.toLowerCase();\n const all = slash.list();\n const matches = query\n ? all.filter(\n (c) =>\n c.name.toLowerCase().includes(query) ||\n c.aliases?.some((a) => a.toLowerCase().includes(query)),\n )\n : all;\n return { matches, query };\n }, [input, slash]);\n\n // 输入变化时把高亮索引夹回合法范围\n useEffect(() => {\n const len = autocomplete?.matches.length ?? 0;\n if (autocompleteIndex >= len) setAutocompleteIndex(0);\n }, [autocomplete, autocompleteIndex]);\n\n // 终端 tab/window 标题:idle 静态项目名,busy 时旋转 spinner + 工具名。\n // 100ms tick / 10 帧 braille——切到别的窗口也能从 dock 看出 muse 还在跑。\n useEffect(() => {\n const project = basename(cwd) || \"muse\";\n const baseIdle = `muse · ${project}`;\n\n if (state.status === \"idle\") {\n setTerminalTitle(baseIdle);\n return;\n }\n\n const FRAMES = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"];\n let i = 0;\n const id = setInterval(() => {\n const frame = FRAMES[i % FRAMES.length];\n const tail = state.runningTool ? ` · ${state.runningTool}` : \"\";\n setTerminalTitle(`${frame} muse · ${project}${tail}`);\n i++;\n }, 100);\n return () => clearInterval(id);\n }, [state.status, state.runningTool, cwd]);\n\n // 卸载时清标题(避免退出后 tab 留着旧 spinner 字符)\n useEffect(() => {\n return () => resetTerminalTitle();\n }, []);\n\n const [memoryIndex, setMemoryIndex] = useState<string>(\"\");\n useEffect(() => {\n let cancelled = false;\n loadMemoryIndex(cwd).then((idx) => {\n if (!cancelled) setMemoryIndex(idx);\n });\n return () => {\n cancelled = true;\n };\n }, [cwd]);\n\n useEffect(() => {\n const systemPrompt = buildSystemPrompt({\n cwd,\n model: llm.model,\n provider: llm.providerName,\n lang,\n toolNames: tools.list().map((t) => t.name),\n memoryIndex,\n });\n\n const agent = new Agent({\n llm,\n tools,\n permissions,\n session,\n cwd,\n systemPrompt,\n events: {\n onText: (delta) => dispatch({ type: \"stream_delta\", delta }),\n onToolCallStart: (_id, name) => dispatch({ type: \"tool_start\", name }),\n // assistant 流刚结束、这一批 calls 已落到 messages 但 tool 还没开始执行:\n // 立刻同步 history,让所有 ⏺ Tool(...) 调用头一次性显示出来(之前要等第一个\n // result 才能见到任何东西,看起来像\"卡死了\")\n onAssistantTurn: () => {\n const msgs = [...agent.getMessages()];\n messagesRef.current = msgs;\n dispatch({ type: \"history_set\", messages: msgs });\n dispatch({ type: \"stream_reset\" });\n },\n // 每个 tool result 到位就同步:result 立刻挂到对应 ⏺ 调用的 └ 树枝下方\n onToolResult: () => {\n const msgs = [...agent.getMessages()];\n messagesRef.current = msgs;\n dispatch({ type: \"history_set\", messages: msgs });\n dispatch({ type: \"set_status\", status: \"streaming\" });\n },\n onUsage: (usage: TokenUsage) => dispatch({ type: \"add_usage\", usage }),\n onTurnEnd: () => {\n const msgs = [...agent.getMessages()];\n messagesRef.current = msgs;\n dispatch({ type: \"history_set\", messages: msgs });\n dispatch({ type: \"stream_reset\" });\n dispatch({ type: \"set_status\", status: \"idle\" });\n\n // 队列有货:取下一条立刻开新轮(setTimeout 跳出 onTurnEnd 内部递归调栈)\n const next = dequeueInput();\n if (next) {\n setTimeout(() => {\n dispatch({ type: \"user_submit\" });\n // 队列里存的是占位符版本;dequeue 时还原成原文\n const expanded = expandPastes(next, pasteRegistryRef.current.map);\n agent.runTurn(expanded).catch((err) => {\n const m = err instanceof Error ? err.message : String(err);\n dispatch({ type: \"stream_delta\", delta: `\\n[error] ${m}\\n` });\n dispatch({ type: \"set_status\", status: \"idle\" });\n });\n }, 0);\n }\n },\n onError: (err) => {\n dispatch({ type: \"stream_delta\", delta: `\\n[error] ${err.message}\\n` });\n dispatch({ type: \"set_status\", status: \"idle\" });\n },\n onPermissionRequest: (toolName, args, summary) =>\n new Promise<PermissionDecision>((resolve) => {\n setPending({ toolName, args, summary, resolve });\n }),\n onAskQuestions: (questions) =>\n new Promise((resolve) => {\n setQuestionPicker({ questions, resolve });\n }),\n },\n });\n agent.setMessages(messagesRef.current);\n agentRef.current = agent;\n }, [llm, tools, permissions, session, cwd, lang, memoryIndex]);\n\n // 键盘:Ctrl+C 全局退出 + Shift+Tab 循环切 permission mode + autocomplete ↑↓ Tab Esc 导航\n useInput(\n (inputKey, key) => {\n if (key.ctrl && inputKey === \"c\") {\n exit();\n return;\n }\n if (key.shift && key.tab) {\n const next = permissions.cycleMode();\n setMode(next);\n return;\n }\n if (autocomplete && autocomplete.matches.length > 0) {\n const len = autocomplete.matches.length;\n if (key.upArrow) {\n setAutocompleteIndex((i) => (i - 1 + len) % len);\n } else if (key.downArrow) {\n setAutocompleteIndex((i) => (i + 1) % len);\n } else if (key.tab) {\n const picked = autocomplete.matches[autocompleteIndex];\n if (picked) commitInput(`/${picked.name}`);\n } else if (key.escape) {\n commitInput(\"\");\n }\n return;\n }\n\n // autocomplete 关闭时:↑/↓ 翻输入历史\n const hist = inputHistoryRef.current;\n if (key.upArrow && hist.length > 0) {\n const cur = historyIndexRef.current;\n if (cur === -1) savedDraftRef.current = input;\n const next = Math.min(cur + 1, hist.length - 1);\n historyIndexRef.current = next;\n commitInput(hist[hist.length - 1 - next] ?? \"\");\n } else if (key.downArrow) {\n const cur = historyIndexRef.current;\n if (cur === -1) return;\n const next = cur - 1;\n historyIndexRef.current = next;\n if (next === -1) commitInput(savedDraftRef.current);\n else commitInput(hist[hist.length - 1 - next] ?? \"\");\n }\n },\n // 模型在跑时也要响应键盘(让用户能 Ctrl+C / Shift+Tab / autocomplete 导航);\n // 仅模态弹起时让出键盘所有权\n { isActive: !pending && !picker && !sessionPicker && !questionPicker },\n );\n\n // 输入框:picker 类模态弹起时仍保持可见但失焦(\"Chat about this\" 风格),\n // 真正抢键盘的 PermissionPrompt / ModelSelector / SessionSelector 才完全隐藏\n const acceptingInput = pending === null && picker === null && sessionPicker === null && questionPicker === null;\n const inputVisible = pending === null && picker === null && sessionPicker === null;\n const inputPlaceholder = questionPicker ? \"Chat about this\" : undefined;\n\n const actions: SlashActions = useMemo(\n () => ({\n setMessages: (msgs) => {\n messagesRef.current = msgs;\n agentRef.current?.setMessages(msgs);\n dispatch({ type: \"history_set\", messages: msgs });\n },\n pickModel: (items, currentId) =>\n new Promise<ModelEntry | null>((resolve) => {\n setPicker({ items, currentId, resolve });\n }),\n pickSession: (items, currentId) =>\n new Promise<SessionSummary | null>((resolve) => {\n setSessionPicker({ items, currentId, resolve });\n }),\n switchModel: async (modelId) => {\n if (!modelsRegistry) throw new Error(\"No models registry loaded.\");\n const entry = findEntry(modelsRegistry, modelId);\n if (!entry) throw new Error(`Model id \"${modelId}\" not in registry.`);\n setActiveModelEnv(entry);\n const next = createLLMClientFromModelEntry(entry);\n setLLM(next);\n await persistActiveModel(modelId);\n },\n getMode: () => permissions.getMode(),\n setMode: (m) => {\n permissions.setMode(m);\n setMode(m);\n },\n showProgress: (opts) => {\n setProgress({\n title: opts.title,\n tips: opts.tips ?? [],\n getPercent: opts.getPercent ?? (() => 0),\n startTime: Date.now(),\n });\n },\n hideProgress: () => setProgress(null),\n reloadSettings: async () => {\n const { settings: nextSettings, sources } = await loadSettings(cwd);\n const { registry: nextModels } = await loadModelsRegistry();\n setSettings(nextSettings);\n setSettingsSources(sources);\n setPermissions(new PermissionGate(nextSettings.permissions));\n setModelsRegistry(nextModels);\n\n const wantModel = nextSettings.llm?.model;\n if (wantModel && wantModel !== llm.model) {\n try {\n const entry = nextModels ? findEntry(nextModels, wantModel) : undefined;\n if (entry) {\n setActiveModelEnv(entry);\n setLLM(createLLMClientFromModelEntry(entry));\n } else if (nextSettings.llm?.provider) {\n setLLM(\n createLLMClient({\n provider: nextSettings.llm.provider,\n model: wantModel,\n providers: nextSettings.providers ?? {},\n }),\n );\n }\n } catch {\n // 新配置当前不可用(缺 key 等);保留原 LLM 不抛断流\n }\n }\n return { settings: nextSettings, sources };\n },\n }),\n [cwd, modelsRegistry, llm.model, permissions],\n );\n\n const handleSubmit = useCallback(\n async (value: string) => {\n const trimmed = value.trim();\n if (!trimmed) return;\n\n // autocomplete 开 + 有候选 + 用户没在精确命名 → 补全到 input,不提交\n if (autocomplete && autocomplete.matches.length > 0) {\n const exact = autocomplete.matches.find(\n (c) => c.name === autocomplete.query || c.aliases?.includes(autocomplete.query),\n );\n if (!exact) {\n const picked = autocomplete.matches[autocompleteIndex] ?? autocomplete.matches[0];\n commitInput(`/${picked.name}`);\n return;\n }\n }\n\n const parsed = parseSlash(trimmed);\n if (parsed) {\n // 模型在跑时 slash 命令一律拒绝——/clear /compact /resume 会改 messages 与 agent\n // 正在跑的回复冲突;reduce 也无法把 slash 排到队列里执行(会污染 history 时序)。\n // 用户可 Ctrl+C 取消当前轮,或等结束。\n if (state.status !== \"idle\") {\n commitInput(\"\");\n return;\n }\n const cmd = slash.get(parsed.name);\n commitInput(\"\");\n if (!cmd) {\n appendAssistantText(`Unknown command: /${parsed.name}. Try /help.`);\n return;\n }\n try {\n const result = await cmd.execute({\n args: parsed.args,\n cwd,\n llm,\n session,\n settings,\n settingsSources,\n modelsRegistry,\n // 用 ref 而非 state.history:命令体可能在 await 期间调 setMessages\n // 改变 messages(如 /resume / /compact),后续 display 必须基于最新值\n history: messagesRef.current,\n tokens: {\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n totalTokens: state.totalTokens,\n },\n listCommands: () => slash.list(),\n actions,\n });\n applySlashResult(result);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n appendAssistantText(`[error] /${parsed.name}: ${msg}`);\n }\n return;\n }\n\n commitInput(\"\");\n // 推入历史(去重相邻重复),重置游标\n const hist = inputHistoryRef.current;\n if (hist[hist.length - 1] !== trimmed) hist.push(trimmed);\n if (hist.length > 200) hist.shift();\n historyIndexRef.current = -1;\n savedDraftRef.current = \"\";\n\n // 模型在跑 → 入队,等本轮 onTurnEnd 出队继续\n if (state.status !== \"idle\") {\n enqueueInput(trimmed);\n return;\n }\n\n dispatch({ type: \"user_submit\" });\n // 立刻把用户消息塞进可见历史,UX 上\"瞬间出现\"——别等 Agent runTurn 结束才 history_set\n // Agent 内部也会 push 同样的 message,turn 结束时 onTurnEnd 用 agent.getMessages()\n // 同步回来一次就行,不会重复\n const expanded = expandPastes(trimmed, pasteRegistryRef.current.map);\n {\n const userMsg: Message = { role: \"user\", content: expanded };\n const next = [...messagesRef.current, userMsg];\n messagesRef.current = next;\n dispatch({ type: \"history_set\", messages: next });\n }\n try {\n await agentRef.current?.runTurn(expanded);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n dispatch({ type: \"stream_delta\", delta: `\\n[error] ${msg}\\n` });\n dispatch({ type: \"set_status\", status: \"idle\" });\n }\n },\n [slash, cwd, llm, session, settings, settingsSources, modelsRegistry, state.inputTokens, state.outputTokens, state.totalTokens, state.status, actions, autocomplete, autocompleteIndex],\n );\n\n function appendAssistantText(text: string) {\n const msg: Message = { role: \"assistant\", content: [{ type: \"text\", text }] };\n // 必须读 ref 而非闭包里的 state.history:上游可能刚通过 setMessages 改了历史\n // (/resume 加载 N 条 → applySlashResult 追加\"Resumed...\"),用 state.history\n // 会覆盖刚 load 进来的消息\n const next = [...messagesRef.current, msg];\n messagesRef.current = next;\n dispatch({ type: \"history_set\", messages: next });\n }\n\n function applySlashResult(result: SlashCommandResult) {\n if (result.exit) {\n exit();\n return;\n }\n if (result.display !== undefined) {\n appendAssistantText(result.display);\n }\n }\n\n const banner = !showBanner\n ? null\n : pickBanner(termWidth, { version: \"0.1.0\", model: llm.model, cwd: shortCwd(cwd) });\n\n // 配对 tool_use ↔ tool_result:AssistantMessage 把 result 内联渲染在 call 下方(树形);\n // 顶层 history loop 跳过已被内联的 ToolMessage 避免重复\n const { resultsByCallId, inlinedIds } = useMemo(() => {\n const byId = new Map<string, ToolMessage>();\n const used = new Set<string>();\n for (const m of state.history) {\n if (m.role === \"tool\" && m.toolUseId) byId.set(m.toolUseId, m);\n if (m.role === \"assistant\" && Array.isArray(m.content)) {\n for (const p of m.content) {\n if (p.type === \"tool_use\") used.add(p.id);\n }\n }\n }\n return { resultsByCallId: byId, inlinedIds: used };\n }, [state.history]);\n\n return (\n <Box flexDirection=\"column\">\n {banner}\n <Box flexDirection=\"column\" marginTop={1}>\n {state.history.map((msg, i) => {\n if (msg.role === \"tool\" && inlinedIds.has(msg.toolUseId)) return null;\n return <MessageView key={i} message={msg} resultsByCallId={resultsByCallId} />;\n })}\n {state.streamingText && (\n <Box flexDirection=\"row\" marginTop={1}>\n <Text color=\"cyan\">{DOT} </Text>\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text>{state.streamingText}</Text>\n </Box>\n </Box>\n )}\n </Box>\n {pending && (\n <PermissionPrompt\n request={{\n ...pending,\n resolve: (decision) => {\n pending.resolve(decision);\n setPending(null);\n },\n }}\n />\n )}\n {picker && (\n <ModelSelector\n request={{\n ...picker,\n resolve: (m) => {\n picker.resolve(m);\n setPicker(null);\n },\n }}\n />\n )}\n {sessionPicker && (\n <SessionSelector\n request={{\n ...sessionPicker,\n resolve: (s) => {\n sessionPicker.resolve(s);\n setSessionPicker(null);\n },\n }}\n />\n )}\n {questionPicker && (\n <QuestionPicker\n request={{\n questions: questionPicker.questions,\n resolve: (responses) => {\n questionPicker.resolve(responses);\n setQuestionPicker(null);\n },\n }}\n />\n )}\n {state.status !== \"idle\" && (\n <StatusLine\n startTime={state.turnStartTime}\n firstTextTime={state.turnFirstTextTime}\n inputTokens={state.turnInputTokens}\n runningTool={state.runningTool}\n lang={lang}\n />\n )}\n {progress && <ProgressBanner state={progress} />}\n {inputVisible && (\n <Box flexDirection=\"column\">\n {queuedInputs.length > 0 && (\n <Box flexDirection=\"column\" marginLeft={2} marginTop={1}>\n {queuedInputs.map((q, i) => (\n <Text key={i} color=\"yellow\" dimColor>\n {`↳ queued: ${q.length > 60 ? q.slice(0, 60) + \"…\" : q}`}\n </Text>\n ))}\n <Text dimColor>{` (will send after current turn · ${queuedInputs.length} pending)`}</Text>\n </Box>\n )}\n <Box marginTop={1} flexDirection=\"column\">\n <Text backgroundColor=\"#1c1c1c\">\n {\" \".repeat(Math.max(1, termWidth - 1))}\n </Text>\n <Box flexDirection=\"row\">\n <Text backgroundColor=\"#1c1c1c\" color=\"gray\" bold>\n {\" › \"}\n </Text>\n <BgTextInput\n key={inputRemountKey}\n value={input}\n onChange={setInput}\n onSubmit={handleSubmit}\n width={Math.max(10, termWidth - 4)}\n backgroundColor=\"#1c1c1c\"\n isActive={acceptingInput}\n onPaste={handlePaste}\n placeholder={inputPlaceholder}\n />\n </Box>\n <Text backgroundColor=\"#1c1c1c\">\n {\" \".repeat(Math.max(1, termWidth - 1))}\n </Text>\n </Box>\n {autocomplete && autocomplete.matches.length > 0 && (\n <SlashAutocomplete matches={autocomplete.matches} index={autocompleteIndex} />\n )}\n </Box>\n )}\n <Box flexDirection=\"column\">\n <FooterStatus\n sessionId={session.meta.id}\n model={llm.model}\n contextWindow={llm.capabilities.maxContextWindow}\n lastInputTokens={state.turnInputTokens}\n sessionInputTokens={state.inputTokens}\n sessionOutputTokens={state.outputTokens}\n termWidth={termWidth}\n />\n <PermissionModeBar mode={mode} compact={termWidth < 60} />\n </Box>\n </Box>\n );\n}\n\nfunction extractUserInputs(messages: Message[]): string[] {\n const out: string[] = [];\n for (const m of messages) {\n if (m.role !== \"user\") continue;\n const text =\n typeof m.content === \"string\"\n ? m.content\n : m.content\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text)\n .join(\"\\n\");\n // 跳过 /compact 注入的 \"[Previous conversation summary]\" 等系统消息\n if (text.startsWith(\"[Previous conversation summary]\")) continue;\n if (text.trim()) out.push(text);\n }\n return out;\n}\n\n// 占位符格式:[Pasted text #<id> +<lines> lines]——与 Claude Code 对齐\nconst PASTE_PLACEHOLDER_RE = /\\[Pasted text #(\\d+) \\+\\d+ lines\\]/g;\n\nfunction expandPastes(value: string, map: Map<number, string>): string {\n return value.replace(PASTE_PLACEHOLDER_RE, (full, id) => {\n const text = map.get(Number(id));\n return text ?? full;\n });\n}\n\nfunction shortCwd(cwd: string): string {\n const home = homedir();\n if (cwd === home) return \"~\";\n if (cwd.startsWith(home + \"/\")) return \"~\" + cwd.slice(home.length);\n return cwd;\n}\n\n/**\n * 把当前选中的 model id 写回 ~/.muse/settings.json llm.model。\n *\n * 这是 muse 第一次\"写配置\"。策略:read-modify-write 整文件,pretty-print 2 空格。\n * 不强制 chmod —— settings.json 不放明文 key,敏感数据在 settings.local.json。\n */\nasync function persistActiveModel(modelId: string): Promise<void> {\n const path = join(homedir(), \".muse\", \"settings.json\");\n let current: Record<string, unknown> = {};\n if (existsSync(path)) {\n try {\n current = JSON.parse(await readFile(path, \"utf-8\")) as Record<string, unknown>;\n } catch {\n current = {};\n }\n }\n const llm = (current.llm as Record<string, unknown> | undefined) ?? {};\n const next = { ...current, llm: { ...llm, model: modelId } };\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, JSON.stringify(next, null, 2) + \"\\n\", \"utf-8\");\n}\n","/**\n * 自带背景色的轻量输入组件,替换 ink-text-input。\n *\n * Why:Ink 的 Box 不支持 backgroundColor 属性(只有 Text 支持),\n * 而 ink-text-input 输出的 Text 不暴露 bg 注入口。要实现\"整行高亮背景\"\n * 的输入条(对齐 Claude Code 风格),最干净的方式是自己渲染。\n *\n * 实现:单个 Text 节点,padEnd 到 width 让 bg 填满整行。\n * 光标用 inverse 字符表示,超出 width 时做左侧 viewport 裁切常驻光标可见。\n *\n * 终端列宽口径:用 charWidth() 处理 CJK / 全角等 2 列字符,避免内容超 width\n * 时换行(换行让 Ink 渲染高度变化,引起上面内容被顶上去——非常显眼的 bug)。\n *\n * 不支持:多行、IME 复合输入、emoji 代理对的精确光标位置——v0.1 范围。\n */\n\nimport React, { useState, useEffect } from \"react\";\nimport { Text, useInput } from \"ink\";\n\nexport interface BgTextInputProps {\n value: string;\n onChange: (value: string) => void;\n onSubmit?: (value: string) => void;\n /** 主体内容可用宽度(\"› \" 这种前缀外),用于 padEnd 让 bg 填满整行。 */\n width: number;\n /** Tailwind 风 hex 或 Ink 颜色名。 */\n backgroundColor: string;\n /** 前景文字颜色;不传时用终端默认。 */\n color?: string;\n /** 是否启用键盘(弹模态时调用方传 false 让出键盘所有权)。 */\n isActive?: boolean;\n /**\n * 检测到一段疑似粘贴(含换行 或 > 200 字符)时回调;返回的字符串作为实际插入内容\n * 替换原始 chunk。调用方一般注册原文到 paste registry,返回 `[Pasted text #N ...]`\n * 占位符,避免 \\n 进入输入框造成多行渲染。\n */\n onPaste?: (chunk: string) => string;\n /**\n * value 为空时显示的暗淡占位文本——典型场景:弹模态时 isActive=false,\n * 输入框仍可见但失焦,用 placeholder 透出 \"Chat about this\" 之类的提示。\n */\n placeholder?: string;\n}\n\nconst BLINK_MS = 530; // 标准终端 cursor 闪烁周期\nconst PASTE_CHAR_THRESHOLD = 200;\n\nfunction looksLikePaste(input: string): boolean {\n // \\r 也算:macOS Terminal / iTerm 粘贴多段文本时换行常为 \\r 而非 \\n,\n // 落进 value 后 \\r 会被终端解释为回车(光标回行首)→ 后文覆盖前文,看着像\"丢消息\"\n return input.includes(\"\\n\") || input.includes(\"\\r\") || input.length > PASTE_CHAR_THRESHOLD;\n}\n\n// bracketed paste 转义:部分终端把粘贴包成 \\x1b[200~...\\x1b[201~,Ink 不一定剥\nfunction stripBracketedPaste(s: string): string {\n return s.replace(/\\x1b\\[20[01]~/g, \"\");\n}\n\n// 统一换行:\\r\\n → \\n、裸 \\r → \\n\n// 用途:粘贴 chunk 在注册到 registry 前先规范化,避免 \\r 流进 value / 历史 / LLM\nfunction normalizeLineEndings(s: string): string {\n return s.replace(/\\r\\n?/g, \"\\n\");\n}\n\nexport function BgTextInput({\n value,\n onChange,\n onSubmit,\n width,\n backgroundColor,\n color,\n isActive = true,\n onPaste,\n placeholder,\n}: BgTextInputProps) {\n const [cursor, setCursor] = useState(value.length);\n const [blinkOn, setBlinkOn] = useState(true);\n\n useEffect(() => {\n // value 外部改变(commitInput / remount)时把光标移到末尾或夹在合法范围\n setCursor((c) => Math.min(c, value.length));\n }, [value]);\n\n // 光标闪烁:cursor / value 变化时重启 timer 让光标\"常亮\"过编辑动作;\n // isActive=false(模态弹起)时不闪也不显\n useEffect(() => {\n if (!isActive) return;\n setBlinkOn(true);\n const id = setInterval(() => setBlinkOn((b) => !b), BLINK_MS);\n return () => clearInterval(id);\n }, [isActive, cursor, value]);\n\n useInput(\n (input, key) => {\n if (key.return) {\n onSubmit?.(value);\n return;\n }\n if (key.backspace || key.delete) {\n if (cursor === 0) return;\n const next = value.slice(0, cursor - 1) + value.slice(cursor);\n onChange(next);\n setCursor((c) => Math.max(0, c - 1));\n return;\n }\n if (key.leftArrow) {\n setCursor((c) => Math.max(0, c - 1));\n return;\n }\n if (key.rightArrow) {\n setCursor((c) => Math.min(value.length, c + 1));\n return;\n }\n if (key.ctrl && input === \"a\") {\n setCursor(0);\n return;\n }\n if (key.ctrl && input === \"e\") {\n setCursor(value.length);\n return;\n }\n // 不消费 Ctrl+C / Shift+Tab / ↑↓ / Tab / Esc / meta——交给 App 顶层 useInput\n if (key.ctrl || key.shift || key.tab || key.escape || key.upArrow || key.downArrow || key.meta) {\n return;\n }\n // 普通字符(含粘贴):在光标处插入\n if (input && !key.return) {\n // 先剥 bracketed paste 转义,再统一换行符——\\r 不处理会让后续渲染 / LLM 都吃坏\n const cleaned = normalizeLineEndings(stripBracketedPaste(input));\n if (!cleaned) return;\n // 检测疑似粘贴:交给调用方决定要不要替换成占位符\n // 避免 \\n 直接进 value 让 Text 渲染成多行,把输入框撑到看不见前文\n const insertion =\n onPaste && looksLikePaste(cleaned) ? onPaste(cleaned) : cleaned;\n const next = value.slice(0, cursor) + insertion + value.slice(cursor);\n onChange(next);\n setCursor((c) => c + insertion.length);\n }\n },\n { isActive },\n );\n\n // 光标渲染:active + blinkOn 时 inverse 高亮;blinkOff 或 inactive 时\n // 保持背景色不显光标,单元格宽度不变(避免布局抖动)\n const showCursor = isActive && blinkOn;\n\n // 空 value + 有 placeholder → 占位文本模式(暗淡显示,\"Chat about this\" 风格)\n if (value.length === 0 && placeholder) {\n // 留 1 列给光标位\n const maxW = Math.max(0, width - 1);\n let truncated = placeholder;\n while (stringWidth(truncated) > maxW && truncated.length > 0) {\n truncated = truncated.slice(0, -1);\n }\n const usedW = 1 + stringWidth(truncated);\n const padLen = Math.max(0, width - usedW);\n return (\n <Text backgroundColor={backgroundColor} color={color}>\n {showCursor ? (\n <Text backgroundColor=\"blue\" color={color} dimColor>\n {\" \"}\n </Text>\n ) : (\n <Text backgroundColor={backgroundColor} color={color}>\n {\" \"}\n </Text>\n )}\n <Text backgroundColor={backgroundColor} dimColor>\n {truncated}\n </Text>\n {\" \".repeat(padLen)}\n </Text>\n );\n }\n\n // 视口计算:保证整行可视宽度 == width,光标永远可见\n // 显示前把 \\n / \\r 换成 ↵(1 列宽可视符),避免 Ink Text 渲染成真换行 / 回车——\n // 换行会把输入框撑成多行;回车更糟,会让后文覆盖前文看着像\"消息丢了\"\n const displayValue = value.replace(/[\\n\\r]/g, \"↵\");\n const view = computeViewport(displayValue, cursor, width);\n const at = view.atChar;\n const padLen = Math.max(0, width - view.consumedWidth);\n\n return (\n <Text backgroundColor={backgroundColor} color={color}>\n {view.before}\n {showCursor ? (\n <Text backgroundColor=\"blue\" color={color} dimColor>\n {at}\n </Text>\n ) : (\n <Text backgroundColor={backgroundColor} color={color}>\n {at}\n </Text>\n )}\n {view.after}\n {\" \".repeat(padLen)}\n </Text>\n );\n}\n\n// ---------- helpers ----------\n\n/** 估计单字符在终端的列宽:CJK / 全角 = 2,控制符 = 0,其余 = 1。 */\nfunction charWidth(ch: string): number {\n const cp = ch.codePointAt(0);\n if (cp === undefined) return 0;\n if (cp < 0x20 || cp === 0x7f) return 0;\n if (\n (cp >= 0x1100 && cp <= 0x115f) || // Hangul Jamo\n (cp >= 0x2e80 && cp <= 0x303e) || // CJK Radicals\n (cp >= 0x3041 && cp <= 0x33ff) || // Hiragana / Katakana / CJK Symbols\n (cp >= 0x3400 && cp <= 0x4dbf) || // CJK Ext A\n (cp >= 0x4e00 && cp <= 0x9fff) || // CJK Unified\n (cp >= 0xa000 && cp <= 0xa4cf) || // Yi\n (cp >= 0xac00 && cp <= 0xd7a3) || // Hangul Syllables\n (cp >= 0xf900 && cp <= 0xfaff) || // CJK Compat\n (cp >= 0xfe30 && cp <= 0xfe4f) || // CJK Compat Forms\n (cp >= 0xff00 && cp <= 0xff60) || // Fullwidth ASCII / Punctuation\n (cp >= 0xffe0 && cp <= 0xffe6) || // Fullwidth Sign\n (cp >= 0x20000 && cp <= 0x2fffd) // CJK Ext B–F\n ) {\n return 2;\n }\n return 1;\n}\n\nexport function stringWidth(s: string): number {\n let w = 0;\n for (const ch of s) w += charWidth(ch);\n return w;\n}\n\ninterface Viewport {\n before: string;\n atChar: string;\n after: string;\n consumedWidth: number;\n}\n\n/**\n * 计算视口:保证渲染宽度 == width,光标永远在可视范围内。\n * 溢出时从左侧裁掉字符让窗口右沿吃下光标。\n */\nfunction computeViewport(value: string, cursor: number, width: number): Viewport {\n const cursorAtEnd = cursor >= value.length;\n const atChar = cursorAtEnd ? \" \" : value[cursor] ?? \" \";\n const cursorCellW = charWidth(atChar);\n\n // 尝试用全量 [0, cursor) + cursor cell + (cursor+1, end] 渲染\n // 若总宽度 > width,从 before 左侧逐字符裁掉\n let beforeStart = 0;\n while (true) {\n const before = value.slice(beforeStart, cursor);\n const after = cursorAtEnd ? \"\" : value.slice(cursor + 1);\n const total = stringWidth(before) + cursorCellW + stringWidth(after);\n if (total <= width) {\n return { before, atChar, after, consumedWidth: total };\n }\n if (beforeStart >= cursor) {\n // before 已经全裁完仍超:再从 after 尾部裁\n // (cursor 后面有超长内容;少见,但 paste 一大段会触发)\n let after = cursorAtEnd ? \"\" : value.slice(cursor + 1);\n while (after.length > 0 && stringWidth(\"\") + cursorCellW + stringWidth(after) > width) {\n after = after.slice(0, -1);\n }\n return {\n before: \"\",\n atChar,\n after,\n consumedWidth: cursorCellW + stringWidth(after),\n };\n }\n beforeStart++;\n }\n}\n","/**\n * 启动 banner(彩虹 MUSE 字母版,无边框)。\n *\n * 4 个字母各 5×5 像素,间距 2 字符,logo 总宽 26 字符 × 高 5 行。\n * M 红 / U 橙 / S 黄 / E 绿(彩虹渐变);✻ 青;v 亮黄;正文白。\n * 无边框,简洁排版,对齐右侧三行信息:✻ Welcome / model / cwd。\n */\n\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\n\n// 每个字母 5 行 × 5 字符宽的像素图。S 顶/底完整 █████ 避免拐弯吐出。\nconst LETTERS = {\n M: [\"█ █\", \"██ ██\", \"█ █ █\", \"█ █\", \"█ █\"],\n U: [\"█ █\", \"█ █\", \"█ █\", \"█ █\", \" ███ \"],\n S: [\"█████\", \"█ \", \" ███ \", \" █\", \"█████\"],\n E: [\"█████\", \"█ \", \"████ \", \"█ \", \"█████\"],\n} as const;\n\nconst COLORS = {\n M: \"#EF4444\",\n U: \"#F97316\",\n S: \"#EAB308\",\n E: \"#22C55E\",\n asterisk: \"#06B6D4\",\n text: \"white\",\n versionAccent: \"#FDE047\",\n} as const;\n\nconst LETTER_GAP = 3; // 字母之间的空格(避免视觉粘连)\nconst LOGO_WIDTH = 5 * 4 + LETTER_GAP * 3; // 29\nconst GAP_WIDTH = 6; // logo 到右侧文字的间距\n\nexport interface StartupBannerProps {\n version: string;\n model: string;\n cwd: string;\n}\n\nfunction LogoLine({ row }: { row: number }) {\n // 用 Box marginLeft 显式控制字母间距:yoga flex 不会\"吃\"空格,比 Text 拼空格稳。\n return (\n <Box flexDirection=\"row\">\n <Box>\n <Text color={COLORS.M}>{LETTERS.M[row]}</Text>\n </Box>\n <Box marginLeft={LETTER_GAP}>\n <Text color={COLORS.U}>{LETTERS.U[row]}</Text>\n </Box>\n <Box marginLeft={LETTER_GAP}>\n <Text color={COLORS.S}>{LETTERS.S[row]}</Text>\n </Box>\n <Box marginLeft={LETTER_GAP}>\n <Text color={COLORS.E}>{LETTERS.E[row]}</Text>\n </Box>\n </Box>\n );\n}\n\nfunction BannerLine({ row, children }: { row: number; children?: React.ReactNode }) {\n return (\n <Box flexDirection=\"row\">\n <Box minWidth={LOGO_WIDTH}>\n <LogoLine row={row} />\n </Box>\n <Box width={GAP_WIDTH} />\n {children ?? null}\n </Box>\n );\n}\n\nexport function StartupBanner({ version, model, cwd }: StartupBannerProps) {\n return (\n <Box flexDirection=\"column\" paddingY={0}>\n <BannerLine row={0} />\n <BannerLine row={1}>\n <Box flexDirection=\"row\">\n <Text color={COLORS.asterisk}>✻</Text>\n <Text color={COLORS.text}>{\" Welcome to Muse \"}</Text>\n <Text color={COLORS.versionAccent}>v{version}</Text>\n </Box>\n </BannerLine>\n <BannerLine row={2}>\n <Text color={COLORS.text}>model: {model}</Text>\n </BannerLine>\n <BannerLine row={3}>\n <Text color={COLORS.text}>cwd: {cwd}</Text>\n </BannerLine>\n <BannerLine row={4} />\n </Box>\n );\n}\n\n/** 紧凑模式:终端窄于 60 列时,省略 logo,仅文字。 */\nexport function CompactBanner({ version, model, cwd }: StartupBannerProps) {\n return (\n <Box flexDirection=\"column\" paddingY={0}>\n <Box flexDirection=\"row\">\n <Text color={COLORS.asterisk}>✻</Text>\n <Text color={COLORS.text}>{\" Welcome to Muse \"}</Text>\n <Text color={COLORS.versionAccent}>v{version}</Text>\n </Box>\n <Text color={COLORS.text}>model: {model}</Text>\n <Text color={COLORS.text}>cwd: {cwd}</Text>\n </Box>\n );\n}\n\n/** 单行模式:终端 < 40 列。 */\nexport function SingleLineBanner({ version, model }: Omit<StartupBannerProps, \"cwd\">) {\n return (\n <Text>\n <Text color={COLORS.text}>Muse </Text>\n <Text color={COLORS.versionAccent}>v{version}</Text>\n <Text color={COLORS.text}> · {model}</Text>\n </Text>\n );\n}\n\nexport function pickBanner(width: number, props: StartupBannerProps): React.ReactElement {\n if (width >= 60) return <StartupBanner {...props} />;\n if (width >= 40) return <CompactBanner {...props} />;\n return <SingleLineBanner version={props.version} model={props.model} />;\n}\n","/**\n * 消息展示组件。区分 user / assistant / tool 三类。\n *\n * Assistant 文本走 marked + marked-terminal,把 markdown 渲染成 ANSI 字符串后交给 Ink Text。\n * 流式中(app.tsx 的 streamingText)保持纯文本,turn 结束后由 history 重渲染替换。\n */\n\nimport React, { useMemo } from \"react\";\nimport { Box, Text, useStdout } from \"ink\";\nimport chalk from \"chalk\";\nimport { marked } from \"marked\";\n// @ts-expect-error marked-terminal 7.x 无内置 .d.ts;运行时正常\nimport { markedTerminal } from \"marked-terminal\";\nimport type { Message, ContentPart, ToolMessage } from \"../types/index.js\";\nimport type { TodoItem } from \"../tools/builtin/todo.js\";\nimport { stringWidth } from \"./BgTextInput.js\";\n\n// chalk 在 module load 时可能基于 stdout 探测把 level 锁成 0(非 TTY、CI 等场景),\n// 这会让 markedTerminal 的 chalk.bold/italic 全部返回纯文本,**项目背景** 之类原样吐出。\n// Ink 渲染到的目标是 TTY,强制至少 256 色,让 ANSI 码进得了 Text 节点。\nif (chalk.level === 0) chalk.level = 3;\n\n// 全局注册一次。markedTerminal() 接受样式参数(heading / blockquote / code 等),先用默认值。\nmarked.use(markedTerminal() as Parameters<typeof marked.use>[0]);\n\nfunction renderMarkdown(text: string): string {\n try {\n let out = marked.parse(text) as string;\n out = out.replace(/\\n+$/, \"\"); // 末尾换行去掉,免得 Ink Box 多一行空白\n\n // 修 marked-terminal 在 list item 等场景里把 **bold** / *italic* 当文本吐出来\n // 自己用正则补一刀(在 reset 处理之前做,否则 \\x1b[0m 会把 \\x1b[1m 切断)\n out = out.replace(/\\*\\*([^\\n*]+?)\\*\\*/g, (_, body) => `\\x1b[1m${body}\\x1b[22m`);\n out = out.replace(/(?<![*\\\\\\x1b])\\*([^\\n*]+?)\\*(?!\\*)/g, (_, body) => `\\x1b[3m${body}\\x1b[23m`);\n\n // marked-terminal 在每个 block 前后塞 \\x1b[0m 全 reset——这会把外层的\n // chalk.bgHex(用户消息条带)一并清掉,渲染出\"字体处没背景\"的断带。\n // 整体剥掉,让样式 close 各自的 \\x1b[22m / \\x1b[23m / \\x1b[39m 收尾即可。\n out = out.replace(/\\x1b\\[0m/g, \"\");\n\n return out;\n } catch {\n // 流到一半的 ```code 等会让 parse 抛错,退化到纯文本\n return text;\n }\n}\n\nexport function MessageView({\n message,\n resultsByCallId,\n}: {\n message: Message;\n /** 上层(app)按 toolUseId 索引的工具结果映射;AssistantMessage 据此把 result 内联到 call 下方。 */\n resultsByCallId?: Map<string, ToolMessage>;\n}) {\n switch (message.role) {\n case \"user\":\n return <UserMessage content={typeof message.content === \"string\" ? message.content : flattenText(message.content)} />;\n case \"assistant\":\n return <AssistantMessage content={message.content} resultsByCallId={resultsByCallId} />;\n case \"tool\":\n // TodoWrite 的清单已在 tool_use 调用处渲染,结果行多余 → 不重复显示\n if (message.toolName === \"TodoWrite\") return null;\n // 兜底:当结果消息没有匹配的 tool_use(理论上不会发生)独立成一行\n return (\n <ToolResultTree result={message} standalone />\n );\n case \"system\":\n return null;\n }\n}\n\nfunction flattenText(parts: ContentPart[]): string {\n return parts.filter((p): p is { type: \"text\"; text: string } => p.type === \"text\").map((p) => p.text).join(\"\\n\");\n}\n\n/**\n * 行首圆点风格统一 ⏺,颜色按消息类型区分(对齐 Claude Code):\n * user → cyan(输入指示符 \"> \" 保留,不混入圆点风格)\n * assistant → cyan ⏺ 普通对话\n * tool_use → yellow ⏺ 工具调用(一行参数 + 截断)\n * tool result → green ⏺ 执行成功\n * red ⏺ 错误\n * yellowBright⏺ warn(redirect/降级/部分成功)\n *\n * Batch 分组:同一 assistant turn 内的多个 tool_use 直接堆叠(无 marginTop),\n * 不同 turn 间靠 AssistantMessage 的 marginTop={1} 区隔。\n */\nexport const DOT = \"⏺\";\n\n/**\n * 用户消息:和输入框同款灰底条带(对齐 Claude Code)。\n * 多行内容每行都填满 bg,首行带 \"› \" 前缀,后续行用 3 空格缩进保持对齐。\n */\nconst USER_BG = \"#262626\";\n\nfunction UserMessage({ content }: { content: string }) {\n const { stdout } = useStdout();\n const termWidth = stdout?.columns ?? 80;\n const bandWidth = Math.max(1, termWidth - 1);\n const PREFIX = \" › \";\n const PREFIX_W = 3;\n\n // 先整体过 markdown,再按行切;不能先切行再过——会打断列表 / 代码块 / 表格等多行结构\n const rendered = useMemo(() => renderMarkdown(content), [content]);\n const lines = rendered.split(\"\\n\");\n const bg = chalk.bgHex(USER_BG);\n const prefixStyle = chalk.gray.bold;\n // 上下空白行:纯 bg,无文字。让消息条不至于紧贴顶/底文字行\n const padRow = bg(\" \".repeat(bandWidth));\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>{padRow}</Text>\n {lines.map((line, i) => {\n // marked-terminal 的输出含 ANSI 转义;填充宽度要按可见字符算,否则 padLen 偏大\n const visible = stringWidth(stripAnsi(line));\n const padLen = Math.max(0, bandWidth - PREFIX_W - visible);\n const prefix = i === 0 ? PREFIX : \" \";\n // 整行(prefix + content + padding)用 chalk.bgHex 包一层 ANSI bg。\n // 内嵌的 chalk.bold / fg-color 等 ANSI 只 reset fg / attr(\\x1b[22m / \\x1b[39m),\n // 不会 reset bg,所以灰底贯穿整行,不会有\"字体处没背景\"的断带。\n const fullLine = bg(prefixStyle(prefix) + line + \" \".repeat(padLen));\n return <Text key={i}>{fullLine}</Text>;\n })}\n <Text>{padRow}</Text>\n </Box>\n );\n}\n\nconst ANSI_RE = /\\x1b\\[[0-9;]*m/g;\nfunction stripAnsi(s: string): string {\n return s.replace(ANSI_RE, \"\");\n}\n\nfunction AssistantMessage({\n content,\n resultsByCallId,\n}: {\n content: ContentPart[];\n resultsByCallId?: Map<string, ToolMessage>;\n}) {\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n {content.map((part, i) => {\n if (part.type === \"text\") {\n return <AssistantTextPart key={i} text={part.text} />;\n }\n if (part.type === \"tool_use\") {\n if (part.name === \"TodoWrite\") {\n return <TodoList key={i} todos={extractTodos(part.args)} />;\n }\n // 把匹配的工具结果一起渲染:⏺ Tool(args) + └ result\n const result = resultsByCallId?.get(part.id);\n return <ToolCallBlock key={i} name={part.name} args={part.args} result={result} />;\n }\n return null;\n })}\n </Box>\n );\n}\n\nfunction AssistantTextPart({ text }: { text: string }) {\n const rendered = useMemo(() => renderMarkdown(text), [text]);\n return (\n <Box flexDirection=\"row\">\n <Text color=\"cyan\">{DOT} </Text>\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text>{rendered}</Text>\n </Box>\n </Box>\n );\n}\n\nfunction ToolCallLine({ name, args }: { name: string; args: unknown }) {\n const argSummary = formatArgs(args);\n // wrap=\"truncate-end\" 让 args 在终端宽度内一行截断;外层 row 默认占满终端宽度。\n return (\n <Box flexDirection=\"row\">\n <Text color=\"yellow\">{DOT} </Text>\n <Text color=\"yellow\" bold>{name}</Text>\n <Box flexGrow={1} minWidth={0}>\n <Text dimColor wrap=\"truncate-end\">({argSummary})</Text>\n </Box>\n </Box>\n );\n}\n\nfunction extractTodos(args: unknown): TodoItem[] {\n if (typeof args !== \"object\" || args === null) return [];\n const todos = (args as { todos?: unknown }).todos;\n return Array.isArray(todos) ? (todos as TodoItem[]) : [];\n}\n\n// 仿 Claude Code 的 checkbox 清单:完成态打钩 + 删除线,进行中高亮,待办置灰。\nfunction TodoList({ todos }: { todos: TodoItem[] }) {\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Box flexDirection=\"row\">\n <Text color=\"yellow\">{\"→ \"}</Text>\n <Text color=\"yellow\" bold>Todos</Text>\n </Box>\n {todos.map((todo, i) => (\n <TodoRow key={i} todo={todo} />\n ))}\n </Box>\n );\n}\n\nfunction TodoRow({ todo }: { todo: TodoItem }) {\n const label = todo.status === \"in_progress\" && todo.activeForm ? todo.activeForm : todo.content;\n switch (todo.status) {\n case \"completed\":\n return (\n <Box flexDirection=\"row\" marginLeft={2}>\n <Text color=\"green\">{\"☒ \"}</Text>\n <Text dimColor strikethrough>{label}</Text>\n </Box>\n );\n case \"in_progress\":\n return (\n <Box flexDirection=\"row\" marginLeft={2}>\n <Text color=\"cyan\" bold>{\"☐ \"}</Text>\n <Text color=\"cyan\" bold>{label}</Text>\n </Box>\n );\n default:\n return (\n <Box flexDirection=\"row\" marginLeft={2}>\n <Text dimColor>{\"☐ \"}</Text>\n <Text dimColor>{label}</Text>\n </Box>\n );\n }\n}\n\n/**\n * 单个工具的\"调用 + 结果\"块(仿 Claude Code 的 ●Tool(...) + └ result 树形展示)。\n * 结果 region 缩进 2 空格,首行用 └ 树枝角标,颜色按状态。\n */\nfunction ToolCallBlock({\n name,\n args,\n result,\n}: {\n name: string;\n args: unknown;\n result?: ToolMessage;\n}) {\n return (\n <Box flexDirection=\"column\">\n <ToolCallLine name={name} args={args} />\n {result && <ToolResultTree result={result} />}\n </Box>\n );\n}\n\nconst MAX_RESULT_LINES = 5;\n\n/**\n * 工具结果的树形展示:\n * - 有 summary → 一行 summary(带 \"+N lines\" 暗示更多内容)\n * - 无 summary 且 content 短 → 全展开(每行一条)\n * - 无 summary 且 content 长 → 头 MAX_RESULT_LINES 行 + \"(+M more lines)\"\n *\n * standalone 标志:用于兜底(独立成块)的情况——通常不会触发。\n */\nfunction ToolResultTree({ result, standalone = false }: { result: ToolMessage; standalone?: boolean }) {\n const isError = result.isError ?? false;\n const effective: \"success\" | \"error\" | \"warn\" = result.kind ?? (isError ? \"error\" : \"success\");\n const dotColor =\n effective === \"error\" ? \"red\" : effective === \"warn\" ? \"yellowBright\" : \"green\";\n\n // bash 等工具会把 stdout/stderr 包在 <stdout>...</stdout> 里给 LLM 区分通道;\n // UI 里把这种独立行的标签剥掉,让用户直接看到 stdout 内容\n const cleaned = stripWrapperTags(result.content);\n const rawLines = cleaned.split(\"\\n\");\n // 去尾部空行(XML 标签剥离后常剩一行空)\n while (rawLines.length > 0 && rawLines[rawLines.length - 1].trim() === \"\") rawLines.pop();\n // 去头部空行\n while (rawLines.length > 0 && rawLines[0].trim() === \"\") rawLines.shift();\n\n let displayLines: string[];\n let omitted = 0;\n\n if (result.summary) {\n const extra = rawLines.length > 1 ? ` (+${rawLines.length - 1} lines)` : \"\";\n displayLines = [result.summary + extra];\n } else if (rawLines.length === 0) {\n displayLines = [\"(no output)\"];\n } else if (rawLines.length <= MAX_RESULT_LINES) {\n displayLines = rawLines;\n } else {\n displayLines = rawLines.slice(0, MAX_RESULT_LINES);\n omitted = rawLines.length - MAX_RESULT_LINES;\n }\n\n return (\n <Box flexDirection=\"column\" marginLeft={2} marginTop={standalone ? 1 : 0}>\n {displayLines.map((line, i) => (\n <Box key={i} flexDirection=\"row\">\n <Text color={i === 0 ? dotColor : undefined}>{i === 0 ? \"└ \" : \" \"}</Text>\n <Box flexGrow={1} minWidth={0}>\n <Text dimColor wrap=\"truncate-end\">{line || \" \"}</Text>\n </Box>\n </Box>\n ))}\n {omitted > 0 && (\n <Box marginLeft={2}>\n <Text dimColor>{`(+${omitted} more lines)`}</Text>\n </Box>\n )}\n {result.diff && <DiffBlock diff={result.diff} />}\n </Box>\n );\n}\n\n/** bash 工具内容里独立成行的 <stdout>/<stderr>/<timeout>/<exit_code> 包装标签,UI 不展示。 */\nfunction stripWrapperTags(content: string): string {\n return content\n .split(\"\\n\")\n .filter((l) => !/^<\\/?(stdout|stderr|timeout|exit_code)>\\s*$/.test(l.trim()))\n .join(\"\\n\");\n}\n\nfunction DiffBlock({ diff }: { diff: string }) {\n // jsdiff createPatch 头四行:Index / === / --- / +++;省略,只渲染 hunks\n const lines = diff.split(\"\\n\");\n const start = lines.findIndex((l) => l.startsWith(\"@@\"));\n const rendered = start >= 0 ? lines.slice(start) : lines;\n return (\n <Box flexDirection=\"column\" marginLeft={2} marginTop={1}>\n {rendered.map((line, i) => {\n let color: string | undefined;\n let dim = false;\n if (line.startsWith(\"+\")) color = \"green\";\n else if (line.startsWith(\"-\")) color = \"red\";\n else if (line.startsWith(\"@@\")) {\n color = \"cyan\";\n dim = true;\n } else {\n dim = true;\n }\n return (\n <Text key={i} color={color} dimColor={dim}>\n {line || \" \"}\n </Text>\n );\n })}\n </Box>\n );\n}\n\nfunction formatArgs(args: unknown): string {\n if (typeof args !== \"object\" || args === null) return String(args);\n const entries = Object.entries(args as Record<string, unknown>);\n if (entries.length === 0) return \"\";\n const parts: string[] = [];\n for (const [k, v] of entries) {\n if (typeof v === \"string\") {\n const truncated = v.length > 40 ? v.slice(0, 40) + \"...\" : v;\n parts.push(`${k}=\"${truncated}\"`);\n } else {\n parts.push(`${k}=${JSON.stringify(v).slice(0, 40)}`);\n }\n }\n return parts.join(\", \");\n}\n","const ANSI_BACKGROUND_OFFSET = 10;\n\nconst wrapAnsi16 = (offset = 0) => code => `\\u001B[${code + offset}m`;\n\nconst wrapAnsi256 = (offset = 0) => code => `\\u001B[${38 + offset};5;${code}m`;\n\nconst wrapAnsi16m = (offset = 0) => (red, green, blue) => `\\u001B[${38 + offset};2;${red};${green};${blue}m`;\n\nconst styles = {\n\tmodifier: {\n\t\treset: [0, 0],\n\t\t// 21 isn't widely supported and 22 does the same thing\n\t\tbold: [1, 22],\n\t\tdim: [2, 22],\n\t\titalic: [3, 23],\n\t\tunderline: [4, 24],\n\t\toverline: [53, 55],\n\t\tinverse: [7, 27],\n\t\thidden: [8, 28],\n\t\tstrikethrough: [9, 29],\n\t},\n\tcolor: {\n\t\tblack: [30, 39],\n\t\tred: [31, 39],\n\t\tgreen: [32, 39],\n\t\tyellow: [33, 39],\n\t\tblue: [34, 39],\n\t\tmagenta: [35, 39],\n\t\tcyan: [36, 39],\n\t\twhite: [37, 39],\n\n\t\t// Bright color\n\t\tblackBright: [90, 39],\n\t\tgray: [90, 39], // Alias of `blackBright`\n\t\tgrey: [90, 39], // Alias of `blackBright`\n\t\tredBright: [91, 39],\n\t\tgreenBright: [92, 39],\n\t\tyellowBright: [93, 39],\n\t\tblueBright: [94, 39],\n\t\tmagentaBright: [95, 39],\n\t\tcyanBright: [96, 39],\n\t\twhiteBright: [97, 39],\n\t},\n\tbgColor: {\n\t\tbgBlack: [40, 49],\n\t\tbgRed: [41, 49],\n\t\tbgGreen: [42, 49],\n\t\tbgYellow: [43, 49],\n\t\tbgBlue: [44, 49],\n\t\tbgMagenta: [45, 49],\n\t\tbgCyan: [46, 49],\n\t\tbgWhite: [47, 49],\n\n\t\t// Bright color\n\t\tbgBlackBright: [100, 49],\n\t\tbgGray: [100, 49], // Alias of `bgBlackBright`\n\t\tbgGrey: [100, 49], // Alias of `bgBlackBright`\n\t\tbgRedBright: [101, 49],\n\t\tbgGreenBright: [102, 49],\n\t\tbgYellowBright: [103, 49],\n\t\tbgBlueBright: [104, 49],\n\t\tbgMagentaBright: [105, 49],\n\t\tbgCyanBright: [106, 49],\n\t\tbgWhiteBright: [107, 49],\n\t},\n};\n\nexport const modifierNames = Object.keys(styles.modifier);\nexport const foregroundColorNames = Object.keys(styles.color);\nexport const backgroundColorNames = Object.keys(styles.bgColor);\nexport const colorNames = [...foregroundColorNames, ...backgroundColorNames];\n\nfunction assembleStyles() {\n\tconst codes = new Map();\n\n\tfor (const [groupName, group] of Object.entries(styles)) {\n\t\tfor (const [styleName, style] of Object.entries(group)) {\n\t\t\tstyles[styleName] = {\n\t\t\t\topen: `\\u001B[${style[0]}m`,\n\t\t\t\tclose: `\\u001B[${style[1]}m`,\n\t\t\t};\n\n\t\t\tgroup[styleName] = styles[styleName];\n\n\t\t\tcodes.set(style[0], style[1]);\n\t\t}\n\n\t\tObject.defineProperty(styles, groupName, {\n\t\t\tvalue: group,\n\t\t\tenumerable: false,\n\t\t});\n\t}\n\n\tObject.defineProperty(styles, 'codes', {\n\t\tvalue: codes,\n\t\tenumerable: false,\n\t});\n\n\tstyles.color.close = '\\u001B[39m';\n\tstyles.bgColor.close = '\\u001B[49m';\n\n\tstyles.color.ansi = wrapAnsi16();\n\tstyles.color.ansi256 = wrapAnsi256();\n\tstyles.color.ansi16m = wrapAnsi16m();\n\tstyles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);\n\tstyles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);\n\tstyles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);\n\n\t// From https://github.com/Qix-/color-convert/blob/3f0e0d4e92e235796ccb17f6e85c72094a651f49/conversions.js\n\tObject.defineProperties(styles, {\n\t\trgbToAnsi256: {\n\t\t\tvalue(red, green, blue) {\n\t\t\t\t// We use the extended greyscale palette here, with the exception of\n\t\t\t\t// black and white. normal palette only has 4 greyscale shades.\n\t\t\t\tif (red === green && green === blue) {\n\t\t\t\t\tif (red < 8) {\n\t\t\t\t\t\treturn 16;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (red > 248) {\n\t\t\t\t\t\treturn 231;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn Math.round(((red - 8) / 247) * 24) + 232;\n\t\t\t\t}\n\n\t\t\t\treturn 16\n\t\t\t\t\t+ (36 * Math.round(red / 255 * 5))\n\t\t\t\t\t+ (6 * Math.round(green / 255 * 5))\n\t\t\t\t\t+ Math.round(blue / 255 * 5);\n\t\t\t},\n\t\t\tenumerable: false,\n\t\t},\n\t\thexToRgb: {\n\t\t\tvalue(hex) {\n\t\t\t\tconst matches = /[a-f\\d]{6}|[a-f\\d]{3}/i.exec(hex.toString(16));\n\t\t\t\tif (!matches) {\n\t\t\t\t\treturn [0, 0, 0];\n\t\t\t\t}\n\n\t\t\t\tlet [colorString] = matches;\n\n\t\t\t\tif (colorString.length === 3) {\n\t\t\t\t\tcolorString = [...colorString].map(character => character + character).join('');\n\t\t\t\t}\n\n\t\t\t\tconst integer = Number.parseInt(colorString, 16);\n\n\t\t\t\treturn [\n\t\t\t\t\t/* eslint-disable no-bitwise */\n\t\t\t\t\t(integer >> 16) & 0xFF,\n\t\t\t\t\t(integer >> 8) & 0xFF,\n\t\t\t\t\tinteger & 0xFF,\n\t\t\t\t\t/* eslint-enable no-bitwise */\n\t\t\t\t];\n\t\t\t},\n\t\t\tenumerable: false,\n\t\t},\n\t\thexToAnsi256: {\n\t\t\tvalue: hex => styles.rgbToAnsi256(...styles.hexToRgb(hex)),\n\t\t\tenumerable: false,\n\t\t},\n\t\tansi256ToAnsi: {\n\t\t\tvalue(code) {\n\t\t\t\tif (code < 8) {\n\t\t\t\t\treturn 30 + code;\n\t\t\t\t}\n\n\t\t\t\tif (code < 16) {\n\t\t\t\t\treturn 90 + (code - 8);\n\t\t\t\t}\n\n\t\t\t\tlet red;\n\t\t\t\tlet green;\n\t\t\t\tlet blue;\n\n\t\t\t\tif (code >= 232) {\n\t\t\t\t\tred = (((code - 232) * 10) + 8) / 255;\n\t\t\t\t\tgreen = red;\n\t\t\t\t\tblue = red;\n\t\t\t\t} else {\n\t\t\t\t\tcode -= 16;\n\n\t\t\t\t\tconst remainder = code % 36;\n\n\t\t\t\t\tred = Math.floor(code / 36) / 5;\n\t\t\t\t\tgreen = Math.floor(remainder / 6) / 5;\n\t\t\t\t\tblue = (remainder % 6) / 5;\n\t\t\t\t}\n\n\t\t\t\tconst value = Math.max(red, green, blue) * 2;\n\n\t\t\t\tif (value === 0) {\n\t\t\t\t\treturn 30;\n\t\t\t\t}\n\n\t\t\t\t// eslint-disable-next-line no-bitwise\n\t\t\t\tlet result = 30 + ((Math.round(blue) << 2) | (Math.round(green) << 1) | Math.round(red));\n\n\t\t\t\tif (value === 2) {\n\t\t\t\t\tresult += 60;\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\t\t\t},\n\t\t\tenumerable: false,\n\t\t},\n\t\trgbToAnsi: {\n\t\t\tvalue: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),\n\t\t\tenumerable: false,\n\t\t},\n\t\thexToAnsi: {\n\t\t\tvalue: hex => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),\n\t\t\tenumerable: false,\n\t\t},\n\t});\n\n\treturn styles;\n}\n\nconst ansiStyles = assembleStyles();\n\nexport default ansiStyles;\n","import process from 'node:process';\nimport os from 'node:os';\nimport tty from 'node:tty';\n\n// From: https://github.com/sindresorhus/has-flag/blob/main/index.js\n/// function hasFlag(flag, argv = globalThis.Deno?.args ?? process.argv) {\nfunction hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process.argv) {\n\tconst prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');\n\tconst position = argv.indexOf(prefix + flag);\n\tconst terminatorPosition = argv.indexOf('--');\n\treturn position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);\n}\n\nconst {env} = process;\n\nlet flagForceColor;\nif (\n\thasFlag('no-color')\n\t|| hasFlag('no-colors')\n\t|| hasFlag('color=false')\n\t|| hasFlag('color=never')\n) {\n\tflagForceColor = 0;\n} else if (\n\thasFlag('color')\n\t|| hasFlag('colors')\n\t|| hasFlag('color=true')\n\t|| hasFlag('color=always')\n) {\n\tflagForceColor = 1;\n}\n\nfunction envForceColor() {\n\tif ('FORCE_COLOR' in env) {\n\t\tif (env.FORCE_COLOR === 'true') {\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (env.FORCE_COLOR === 'false') {\n\t\t\treturn 0;\n\t\t}\n\n\t\treturn env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);\n\t}\n}\n\nfunction translateLevel(level) {\n\tif (level === 0) {\n\t\treturn false;\n\t}\n\n\treturn {\n\t\tlevel,\n\t\thasBasic: true,\n\t\thas256: level >= 2,\n\t\thas16m: level >= 3,\n\t};\n}\n\nfunction _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) {\n\tconst noFlagForceColor = envForceColor();\n\tif (noFlagForceColor !== undefined) {\n\t\tflagForceColor = noFlagForceColor;\n\t}\n\n\tconst forceColor = sniffFlags ? flagForceColor : noFlagForceColor;\n\n\tif (forceColor === 0) {\n\t\treturn 0;\n\t}\n\n\tif (sniffFlags) {\n\t\tif (hasFlag('color=16m')\n\t\t\t|| hasFlag('color=full')\n\t\t\t|| hasFlag('color=truecolor')) {\n\t\t\treturn 3;\n\t\t}\n\n\t\tif (hasFlag('color=256')) {\n\t\t\treturn 2;\n\t\t}\n\t}\n\n\t// Check for Azure DevOps pipelines.\n\t// Has to be above the `!streamIsTTY` check.\n\tif ('TF_BUILD' in env && 'AGENT_NAME' in env) {\n\t\treturn 1;\n\t}\n\n\tif (haveStream && !streamIsTTY && forceColor === undefined) {\n\t\treturn 0;\n\t}\n\n\tconst min = forceColor || 0;\n\n\tif (env.TERM === 'dumb') {\n\t\treturn min;\n\t}\n\n\tif (process.platform === 'win32') {\n\t\t// Windows 10 build 10586 is the first Windows release that supports 256 colors.\n\t\t// Windows 10 build 14931 is the first release that supports 16m/TrueColor.\n\t\tconst osRelease = os.release().split('.');\n\t\tif (\n\t\t\tNumber(osRelease[0]) >= 10\n\t\t\t&& Number(osRelease[2]) >= 10_586\n\t\t) {\n\t\t\treturn Number(osRelease[2]) >= 14_931 ? 3 : 2;\n\t\t}\n\n\t\treturn 1;\n\t}\n\n\tif ('CI' in env) {\n\t\tif (['GITHUB_ACTIONS', 'GITEA_ACTIONS', 'CIRCLECI'].some(key => key in env)) {\n\t\t\treturn 3;\n\t\t}\n\n\t\tif (['TRAVIS', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {\n\t\t\treturn 1;\n\t\t}\n\n\t\treturn min;\n\t}\n\n\tif ('TEAMCITY_VERSION' in env) {\n\t\treturn /^(9\\.(0*[1-9]\\d*)\\.|\\d{2,}\\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;\n\t}\n\n\tif (env.COLORTERM === 'truecolor') {\n\t\treturn 3;\n\t}\n\n\tif (env.TERM === 'xterm-kitty') {\n\t\treturn 3;\n\t}\n\n\tif (env.TERM === 'xterm-ghostty') {\n\t\treturn 3;\n\t}\n\n\tif (env.TERM === 'wezterm') {\n\t\treturn 3;\n\t}\n\n\tif ('TERM_PROGRAM' in env) {\n\t\tconst version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);\n\n\t\tswitch (env.TERM_PROGRAM) {\n\t\t\tcase 'iTerm.app': {\n\t\t\t\treturn version >= 3 ? 3 : 2;\n\t\t\t}\n\n\t\t\tcase 'Apple_Terminal': {\n\t\t\t\treturn 2;\n\t\t\t}\n\t\t\t// No default\n\t\t}\n\t}\n\n\tif (/-256(color)?$/i.test(env.TERM)) {\n\t\treturn 2;\n\t}\n\n\tif (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {\n\t\treturn 1;\n\t}\n\n\tif ('COLORTERM' in env) {\n\t\treturn 1;\n\t}\n\n\treturn min;\n}\n\nexport function createSupportsColor(stream, options = {}) {\n\tconst level = _supportsColor(stream, {\n\t\tstreamIsTTY: stream && stream.isTTY,\n\t\t...options,\n\t});\n\n\treturn translateLevel(level);\n}\n\nconst supportsColor = {\n\tstdout: createSupportsColor({isTTY: tty.isatty(1)}),\n\tstderr: createSupportsColor({isTTY: tty.isatty(2)}),\n};\n\nexport default supportsColor;\n","// TODO: When targeting Node.js 16, use `String.prototype.replaceAll`.\nexport function stringReplaceAll(string, substring, replacer) {\n\tlet index = string.indexOf(substring);\n\tif (index === -1) {\n\t\treturn string;\n\t}\n\n\tconst substringLength = substring.length;\n\tlet endIndex = 0;\n\tlet returnValue = '';\n\tdo {\n\t\treturnValue += string.slice(endIndex, index) + substring + replacer;\n\t\tendIndex = index + substringLength;\n\t\tindex = string.indexOf(substring, endIndex);\n\t} while (index !== -1);\n\n\treturnValue += string.slice(endIndex);\n\treturn returnValue;\n}\n\nexport function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {\n\tlet endIndex = 0;\n\tlet returnValue = '';\n\tdo {\n\t\tconst gotCR = string[index - 1] === '\\r';\n\t\treturnValue += string.slice(endIndex, (gotCR ? index - 1 : index)) + prefix + (gotCR ? '\\r\\n' : '\\n') + postfix;\n\t\tendIndex = index + 1;\n\t\tindex = string.indexOf('\\n', endIndex);\n\t} while (index !== -1);\n\n\treturnValue += string.slice(endIndex);\n\treturn returnValue;\n}\n","import ansiStyles from '#ansi-styles';\nimport supportsColor from '#supports-color';\nimport { // eslint-disable-line import/order\n\tstringReplaceAll,\n\tstringEncaseCRLFWithFirstIndex,\n} from './utilities.js';\n\nconst {stdout: stdoutColor, stderr: stderrColor} = supportsColor;\n\nconst GENERATOR = Symbol('GENERATOR');\nconst STYLER = Symbol('STYLER');\nconst IS_EMPTY = Symbol('IS_EMPTY');\n\n// `supportsColor.level` → `ansiStyles.color[name]` mapping\nconst levelMapping = [\n\t'ansi',\n\t'ansi',\n\t'ansi256',\n\t'ansi16m',\n];\n\nconst styles = Object.create(null);\n\nconst applyOptions = (object, options = {}) => {\n\tif (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {\n\t\tthrow new Error('The `level` option should be an integer from 0 to 3');\n\t}\n\n\t// Detect level if not set manually\n\tconst colorLevel = stdoutColor ? stdoutColor.level : 0;\n\tobject.level = options.level === undefined ? colorLevel : options.level;\n};\n\nexport class Chalk {\n\tconstructor(options) {\n\t\t// eslint-disable-next-line no-constructor-return\n\t\treturn chalkFactory(options);\n\t}\n}\n\nconst chalkFactory = options => {\n\tconst chalk = (...strings) => strings.join(' ');\n\tapplyOptions(chalk, options);\n\n\tObject.setPrototypeOf(chalk, createChalk.prototype);\n\n\treturn chalk;\n};\n\nfunction createChalk(options) {\n\treturn chalkFactory(options);\n}\n\nObject.setPrototypeOf(createChalk.prototype, Function.prototype);\n\nfor (const [styleName, style] of Object.entries(ansiStyles)) {\n\tstyles[styleName] = {\n\t\tget() {\n\t\t\tconst builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);\n\t\t\tObject.defineProperty(this, styleName, {value: builder});\n\t\t\treturn builder;\n\t\t},\n\t};\n}\n\nstyles.visible = {\n\tget() {\n\t\tconst builder = createBuilder(this, this[STYLER], true);\n\t\tObject.defineProperty(this, 'visible', {value: builder});\n\t\treturn builder;\n\t},\n};\n\nconst getModelAnsi = (model, level, type, ...arguments_) => {\n\tif (model === 'rgb') {\n\t\tif (level === 'ansi16m') {\n\t\t\treturn ansiStyles[type].ansi16m(...arguments_);\n\t\t}\n\n\t\tif (level === 'ansi256') {\n\t\t\treturn ansiStyles[type].ansi256(ansiStyles.rgbToAnsi256(...arguments_));\n\t\t}\n\n\t\treturn ansiStyles[type].ansi(ansiStyles.rgbToAnsi(...arguments_));\n\t}\n\n\tif (model === 'hex') {\n\t\treturn getModelAnsi('rgb', level, type, ...ansiStyles.hexToRgb(...arguments_));\n\t}\n\n\treturn ansiStyles[type][model](...arguments_);\n};\n\nconst usedModels = ['rgb', 'hex', 'ansi256'];\n\nfor (const model of usedModels) {\n\tstyles[model] = {\n\t\tget() {\n\t\t\tconst {level} = this;\n\t\t\treturn function (...arguments_) {\n\t\t\t\tconst styler = createStyler(getModelAnsi(model, levelMapping[level], 'color', ...arguments_), ansiStyles.color.close, this[STYLER]);\n\t\t\t\treturn createBuilder(this, styler, this[IS_EMPTY]);\n\t\t\t};\n\t\t},\n\t};\n\n\tconst bgModel = 'bg' + model[0].toUpperCase() + model.slice(1);\n\tstyles[bgModel] = {\n\t\tget() {\n\t\t\tconst {level} = this;\n\t\t\treturn function (...arguments_) {\n\t\t\t\tconst styler = createStyler(getModelAnsi(model, levelMapping[level], 'bgColor', ...arguments_), ansiStyles.bgColor.close, this[STYLER]);\n\t\t\t\treturn createBuilder(this, styler, this[IS_EMPTY]);\n\t\t\t};\n\t\t},\n\t};\n}\n\nconst proto = Object.defineProperties(() => {}, {\n\t...styles,\n\tlevel: {\n\t\tenumerable: true,\n\t\tget() {\n\t\t\treturn this[GENERATOR].level;\n\t\t},\n\t\tset(level) {\n\t\t\tthis[GENERATOR].level = level;\n\t\t},\n\t},\n});\n\nconst createStyler = (open, close, parent) => {\n\tlet openAll;\n\tlet closeAll;\n\tif (parent === undefined) {\n\t\topenAll = open;\n\t\tcloseAll = close;\n\t} else {\n\t\topenAll = parent.openAll + open;\n\t\tcloseAll = close + parent.closeAll;\n\t}\n\n\treturn {\n\t\topen,\n\t\tclose,\n\t\topenAll,\n\t\tcloseAll,\n\t\tparent,\n\t};\n};\n\nconst createBuilder = (self, _styler, _isEmpty) => {\n\t// Single argument is hot path, implicit coercion is faster than anything\n\t// eslint-disable-next-line no-implicit-coercion\n\tconst builder = (...arguments_) => applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' '));\n\n\t// We alter the prototype because we must return a function, but there is\n\t// no way to create a function with a different prototype\n\tObject.setPrototypeOf(builder, proto);\n\n\tbuilder[GENERATOR] = self;\n\tbuilder[STYLER] = _styler;\n\tbuilder[IS_EMPTY] = _isEmpty;\n\n\treturn builder;\n};\n\nconst applyStyle = (self, string) => {\n\tif (self.level <= 0 || !string) {\n\t\treturn self[IS_EMPTY] ? '' : string;\n\t}\n\n\tlet styler = self[STYLER];\n\n\tif (styler === undefined) {\n\t\treturn string;\n\t}\n\n\tconst {openAll, closeAll} = styler;\n\tif (string.includes('\\u001B')) {\n\t\twhile (styler !== undefined) {\n\t\t\t// Replace any instances already present with a re-opening code\n\t\t\t// otherwise only the part of the string until said closing code\n\t\t\t// will be colored, and the rest will simply be 'plain'.\n\t\t\tstring = stringReplaceAll(string, styler.close, styler.open);\n\n\t\t\tstyler = styler.parent;\n\t\t}\n\t}\n\n\t// We can move both next actions out of loop, because remaining actions in loop won't have\n\t// any/visible effect on parts we add here. Close the styling before a linebreak and reopen\n\t// after next line to fix a bleed issue on macOS: https://github.com/chalk/chalk/pull/92\n\tconst lfIndex = string.indexOf('\\n');\n\tif (lfIndex !== -1) {\n\t\tstring = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);\n\t}\n\n\treturn openAll + string + closeAll;\n};\n\nObject.defineProperties(createChalk.prototype, styles);\n\nconst chalk = createChalk();\nexport const chalkStderr = createChalk({level: stderrColor ? stderrColor.level : 0});\n\nexport {\n\tmodifierNames,\n\tforegroundColorNames,\n\tbackgroundColorNames,\n\tcolorNames,\n\n\t// TODO: Remove these aliases in the next major version\n\tmodifierNames as modifiers,\n\tforegroundColorNames as foregroundColors,\n\tbackgroundColorNames as backgroundColors,\n\tcolorNames as colors,\n} from './vendor/ansi-styles/index.js';\n\nexport {\n\tstdoutColor as supportsColor,\n\tstderrColor as supportsColorStderr,\n};\n\nexport default chalk;\n","/**\n * 工具调用的权限确认 prompt(v2 picker)。\n *\n * ↑/↓ 选择 + Enter 确认;快捷键 y/s/n 与 1/2/3 直接落子;Esc 等价于 no。\n *\n * 三选项:\n * 1. Yes — 本次允许\n * 2. Yes, allow <Tool> for session — 后续该 toolName 在 session 内全部 allow\n * 3. No — 拒绝\n */\n\nimport React, { useState } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\nimport type { PermissionDecision } from \"../permission/index.js\";\n\nexport interface PermissionRequest {\n toolName: string;\n args: unknown;\n summary: string;\n resolve: (decision: PermissionDecision) => void;\n}\n\nconst OPTIONS: { decision: PermissionDecision; labelKey: \"yes\" | \"session\" | \"no\"; shortcut: string }[] = [\n { decision: \"yes\", labelKey: \"yes\", shortcut: \"y\" },\n { decision: \"session_allow\", labelKey: \"session\", shortcut: \"s\" },\n { decision: \"no\", labelKey: \"no\", shortcut: \"n\" },\n];\n\nexport function PermissionPrompt({ request }: { request: PermissionRequest }) {\n const [index, setIndex] = useState(0);\n\n useInput((input, key) => {\n if (key.upArrow) {\n setIndex((i) => (i - 1 + OPTIONS.length) % OPTIONS.length);\n return;\n }\n if (key.downArrow) {\n setIndex((i) => (i + 1) % OPTIONS.length);\n return;\n }\n if (key.return) {\n request.resolve(OPTIONS[index].decision);\n return;\n }\n if (key.escape) {\n request.resolve(\"no\");\n return;\n }\n const lower = input?.toLowerCase?.();\n for (let i = 0; i < OPTIONS.length; i++) {\n const o = OPTIONS[i];\n if (lower === o.shortcut || input === String(i + 1)) {\n request.resolve(o.decision);\n return;\n }\n }\n });\n\n return (\n <Box flexDirection=\"column\" marginY={1} borderStyle=\"round\" borderColor=\"yellow\" paddingX={1}>\n <Text color=\"yellow\" bold>\n ⏵ Approve {request.toolName}?\n </Text>\n <Text dimColor>{request.summary}</Text>\n <Box flexDirection=\"column\" marginTop={1}>\n {OPTIONS.map((o, i) => {\n const focused = i === index;\n const label = labelFor(o.labelKey, request.toolName);\n return (\n <Text key={o.decision} color={focused ? \"cyan\" : undefined} bold={focused}>\n {focused ? \"› \" : \" \"}\n {i + 1}. {label}{\" \"}\n <Text dimColor>({o.shortcut})</Text>\n </Text>\n );\n })}\n </Box>\n <Box marginTop={1}>\n <Text dimColor>↑↓ select · Enter confirm · y/s/n shortcut · Esc=no</Text>\n </Box>\n </Box>\n );\n}\n\nfunction labelFor(key: \"yes\" | \"session\" | \"no\", toolName: string): string {\n switch (key) {\n case \"yes\":\n return \"Yes\";\n case \"session\":\n return `Yes, allow ${toolName} for the rest of this session`;\n case \"no\":\n return \"No\";\n }\n}\n","/**\n * 模型选择器:用 Selector 骨架实现,提供 model entry 专用行渲染。\n *\n * 由 /models 命令通过 ctx.actions.pickModel(...) 拉起。\n * 接口(ModelPickerRequest)保持稳定,便于 app.tsx 不动 actions.pickModel 调用方。\n */\n\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\nimport { Selector } from \"./Selector.js\";\nimport type { ModelEntry } from \"../config/models.js\";\n\nexport interface ModelPickerRequest {\n items: ModelEntry[];\n currentId?: string;\n resolve: (picked: ModelEntry | null) => void;\n}\n\nexport function ModelSelector({ request }: { request: ModelPickerRequest }) {\n const { items, currentId, resolve } = request;\n const initialIndex = Math.max(\n 0,\n items.findIndex((m) => m.id === currentId),\n );\n const labelWidth = Math.max(...items.map((m) => (m.name ?? m.id).length));\n\n return (\n <Selector\n items={items}\n initialIndex={initialIndex}\n title=\"Select model\"\n hint=\"↑↓ navigate · Enter confirm · Esc cancel\"\n onSubmit={(m) => resolve(m)}\n onCancel={() => resolve(null)}\n renderRow={(m, _focused) => (\n <ModelRow model={m} active={m.id === currentId} labelWidth={labelWidth} />\n )}\n />\n );\n}\n\nfunction ModelRow({\n model,\n active,\n labelWidth,\n}: {\n model: ModelEntry;\n active: boolean;\n labelWidth: number;\n}) {\n const dot = active ? \"●\" : \" \";\n const label = (model.name ?? model.id).padEnd(labelWidth);\n const vendor = model.vendor ? `[${model.vendor}]` : \"\";\n const caps = formatCaps(model);\n\n return (\n <Box flexDirection=\"row\">\n <Text color={active ? \"green\" : undefined}>{dot} </Text>\n <Text>{label}</Text>\n <Text dimColor>{\" \"}{vendor}</Text>\n {caps && <Text dimColor>{\" \"}{caps}</Text>}\n </Box>\n );\n}\n\nfunction formatCaps(m: ModelEntry): string {\n const flags: string[] = [];\n if (m.supportsToolCall === false) flags.push(\"no-tools\");\n if (m.supportsImages) flags.push(\"vision\");\n return flags.length ? flags.join(\" · \") : \"\";\n}\n","/**\n * 通用键盘 selector 骨架:↑↓ 导航 + Enter 确认 + Esc 取消。\n *\n * 行渲染由 renderRow 回调提供;本组件只负责:\n * - 键盘事件\n * - 焦点状态 + 滑动窗口(保证 focused 始终可见)\n * - 紫色 `›` 焦点指针(颜色 #A855F7,对齐用户截图)\n * - 标题 + 提示\n *\n * 当前调用方:ModelSelector / SessionSelector。\n * 第三处再考虑把外层 borderStyle 等做成 prop;暂时硬编码。\n */\n\nimport React, { useState } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\n\nconst POINTER_COLOR = \"#A855F7\";\n\nexport interface SelectorProps<T> {\n items: T[];\n initialIndex?: number;\n title?: string;\n hint?: string;\n maxVisible?: number;\n renderRow: (item: T, focused: boolean) => React.ReactNode;\n onSubmit: (item: T) => void;\n onCancel: () => void;\n}\n\nexport function Selector<T>({\n items,\n initialIndex = 0,\n title,\n hint,\n maxVisible,\n renderRow,\n onSubmit,\n onCancel,\n}: SelectorProps<T>) {\n const safeInitial = Math.max(0, Math.min(initialIndex, items.length - 1));\n const [index, setIndex] = useState(safeInitial);\n\n useInput((_, key) => {\n if (key.upArrow) {\n setIndex((i) => Math.max(0, i - 1));\n } else if (key.downArrow) {\n setIndex((i) => Math.min(items.length - 1, i + 1));\n } else if (key.return) {\n onSubmit(items[index]);\n } else if (key.escape) {\n onCancel();\n }\n });\n\n const len = items.length;\n const window = maxVisible && maxVisible < len ? maxVisible : len;\n const start = Math.max(0, Math.min(index - Math.floor(window / 2), len - window));\n const end = Math.min(len, start + window);\n const visible = items.slice(start, end);\n\n return (\n <Box\n flexDirection=\"column\"\n marginTop={1}\n paddingX={1}\n borderStyle=\"round\"\n borderColor=\"cyan\"\n >\n {(title || hint) && (\n <Box marginBottom={1}>\n {title && <Text bold>{title}</Text>}\n {title && hint && <Text dimColor>{\" \"}</Text>}\n {hint && <Text dimColor>{hint}</Text>}\n </Box>\n )}\n {visible.map((item, i) => {\n const realIndex = start + i;\n const focused = realIndex === index;\n return (\n <Box key={realIndex} flexDirection=\"row\">\n <Text color={POINTER_COLOR} bold>\n {focused ? \"› \" : \" \"}\n </Text>\n {renderRow(item, focused)}\n </Box>\n );\n })}\n {window < len && (\n <Box marginTop={1}>\n <Text dimColor>\n ({start + 1}-{end} / {len})\n </Text>\n </Box>\n )}\n </Box>\n );\n}\n","/**\n * Session 选择器:列出当前 cwd 下的历史会话,键盘选中加载。\n *\n * 由 /resume 命令通过 ctx.actions.pickSession(...) 拉起。\n * 行布局对齐 /resume display 文本版(id8 · time · [N msgs] · preview),\n * 视觉差异:紫色 `›` 箭头 + 边框 + 选中态。\n */\n\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\nimport { Selector } from \"./Selector.js\";\nimport type { SessionSummary } from \"../session/jsonl.js\";\n\nexport interface SessionPickerRequest {\n items: SessionSummary[];\n currentId?: string;\n resolve: (picked: SessionSummary | null) => void;\n}\n\nexport function SessionSelector({ request }: { request: SessionPickerRequest }) {\n const { items, currentId, resolve } = request;\n const initialIndex = Math.max(\n 0,\n items.findIndex((s) => s.id === currentId),\n );\n\n return (\n <Selector\n items={items}\n initialIndex={initialIndex}\n maxVisible={12}\n title=\"Resume session\"\n hint=\"↑↓ navigate · Enter load · Esc cancel\"\n onSubmit={(s) => resolve(s)}\n onCancel={() => resolve(null)}\n renderRow={(s) => <SessionRow session={s} active={s.id === currentId} />}\n />\n );\n}\n\nfunction SessionRow({ session, active }: { session: SessionSummary; active: boolean }) {\n const id8 = session.id.slice(0, 8);\n const time = formatTime(session.createdAt);\n const count = `[${String(session.messageCount).padStart(2)} msgs]`;\n const preview = session.preview ?? \"(empty)\";\n\n return (\n <Box flexDirection=\"row\">\n <Text color={active ? \"green\" : undefined}>{active ? \"● \" : \" \"}</Text>\n <Text>{id8}</Text>\n <Text dimColor>{\" \"}{time}</Text>\n <Text dimColor>{\" \"}{count}</Text>\n <Text>{\" \"}{preview}</Text>\n </Box>\n );\n}\n\nfunction formatTime(iso: string): string {\n const d = new Date(iso);\n if (isNaN(d.getTime())) return iso;\n const pad = (n: number) => String(n).padStart(2, \"0\");\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;\n}\n","/**\n * AskUserQuestion UI——完整复刻 Claude Code 的链式选择器。\n *\n * 布局:\n *\n * ─────────────────────────────────────────────────────────────────\n * ← □ Header1 □ Header2 □ Header3 ✔ Submit →\n *\n * Question text?\n *\n * 1. Option A ┌──────────────────────────────┐\n * description │ preview content for the │\n * 2. Option B │ focused option │\n * description │ (multi-line allowed) │\n * └──────────────────────────────┘\n *\n * Notes: press n to add notes\n * ─────────────────────────────────────────────────────────────────\n * Enter to select · ↑/↓ to navigate · n to add notes · Tab to switch questions · Esc to cancel\n *\n * 状态:\n * - 每题独立 optionIndex / selected / notes\n * - notesEditing 切换内联文本编辑器(Enter 保存 / Esc 退出回 picker,不取消整批)\n *\n * 键位:\n * ↑↓ 选项移动\n * ←→ / Tab 题间切换(含 Submit chip)\n * Enter option 上:单选 → 选定 + 跳下一题;多选 → toggle\n * Submit 上 → 提交\n * Space 多选 toggle\n * n 进入 notes 编辑(Enter 保存 / Esc 退出)\n * Esc picker 取消\n *\n * Tab chip 标记:\n * 单选未答 □ / 答了 ✔\n * 多选未选 □ / 选了 N 个 [N]\n * 聚焦 chip 走 FOCUS_BG 背景高亮\n *\n * 单题特化:\n * 单题不渲染 tab bar / Submit chip——单选 Enter 直提交;多选 Submit 行放选项末尾\n */\n\nimport React, { useState } from \"react\";\nimport { Box, Text, useInput } from \"ink\";\nimport type { AskQuestion, AskQuestionResponse } from \"../tools/builtin/ask-user-question.js\";\n\nconst POINTER_COLOR = \"#A855F7\"; // 焦点行指针 + 焦点项 label\nconst FOCUS_BG = \"#5B5598\"; // 聚焦 chip 背景(柔和淡紫)\nconst FOCUS_FG = \"white\";\nconst SUBMIT_COLOR = \"green\";\nconst NOTES_LABEL_COLOR = \"yellow\";\nconst PREVIEW_BORDER = \"gray\";\nconst TAB_GAP = 3;\nconst PREVIEW_MIN_WIDTH = 28;\n\nexport interface QuestionPickerRequest {\n questions: AskQuestion[];\n resolve: (responses: AskQuestionResponse[]) => void;\n}\n\ninterface QState {\n optionIndex: number;\n selected: Set<number>;\n notes: string;\n notesEditing: boolean;\n /** notes 编辑中的草稿——Enter 保存到 notes / Esc 丢弃。 */\n notesDraft: string;\n}\n\nexport function QuestionPicker({ request }: { request: QuestionPickerRequest }) {\n const { questions } = request;\n const N = questions.length;\n const hasTabs = N > 1;\n const submitTabIndex = N;\n\n const [tabIndex, setTabIndex] = useState(0);\n const [states, setStates] = useState<QState[]>(() =>\n questions.map(() => ({\n optionIndex: 0,\n selected: new Set<number>(),\n notes: \"\",\n notesEditing: false,\n notesDraft: \"\",\n })),\n );\n\n const currentQ = tabIndex < N ? questions[tabIndex] : null;\n const isMulti = currentQ?.multiSelect === true;\n const onSubmitChip = hasTabs && tabIndex === submitTabIndex;\n\n // 任意 option 提供了 preview?整个题就走双栏,焦点项的 preview 渲染到右侧\n const anyPreview = !!currentQ?.options.some((o) => o.preview);\n const focusedOpt = currentQ?.options[states[tabIndex]?.optionIndex ?? 0];\n const focusedPreview = anyPreview ? focusedOpt?.preview ?? \"\" : \"\";\n\n const buildResponses = (cancelled: boolean): AskQuestionResponse[] => {\n if (cancelled) return questions.map(() => ({ cancelled: true, selections: [] }));\n return questions.map((q, qi) => ({\n cancelled: false,\n selections: Array.from(states[qi].selected)\n .sort((a, b) => a - b)\n .map((i) => q.options[i].label),\n notes: states[qi].notes,\n }));\n };\n\n const submit = () => request.resolve(buildResponses(false));\n const cancel = () => request.resolve(buildResponses(true));\n\n const updateState = (qi: number, mut: (s: QState) => QState) => {\n setStates((prev) => {\n const next = [...prev];\n next[qi] = mut(prev[qi]);\n return next;\n });\n };\n\n const toggleOption = (qi: number, oi: number) => {\n updateState(qi, (s) => {\n const sel = new Set(s.selected);\n if (sel.has(oi)) sel.delete(oi);\n else sel.add(oi);\n return { ...s, selected: sel };\n });\n };\n\n const selectSingleOption = (qi: number, oi: number) => {\n updateState(qi, (s) => ({ ...s, selected: new Set([oi]) }));\n if (!hasTabs) {\n request.resolve([\n {\n cancelled: false,\n selections: [questions[0].options[oi].label],\n notes: states[0].notes,\n },\n ]);\n return;\n }\n if (qi < N - 1) setTabIndex(qi + 1);\n else setTabIndex(submitTabIndex);\n };\n\n // 单题多选用的 Submit 行(=options.length,options 末尾)\n const singleQMultiSubmitRowIndex = !hasTabs && isMulti ? currentQ!.options.length : -1;\n const optionRowCount =\n !hasTabs && isMulti ? currentQ!.options.length + 1 : currentQ?.options.length ?? 0;\n\n const currentNotesEditing =\n tabIndex < N ? states[tabIndex].notesEditing : false;\n\n useInput((input, key) => {\n // ---------- notes 编辑模式 ----------\n if (currentNotesEditing) {\n if (key.escape) {\n updateState(tabIndex, (s) => ({ ...s, notesEditing: false, notesDraft: \"\" }));\n return;\n }\n if (key.return) {\n updateState(tabIndex, (s) => ({\n ...s,\n notesEditing: false,\n notes: s.notesDraft,\n notesDraft: \"\",\n }));\n return;\n }\n if (key.backspace || key.delete) {\n updateState(tabIndex, (s) => ({\n ...s,\n notesDraft: s.notesDraft.slice(0, -1),\n }));\n return;\n }\n if (key.ctrl || key.tab || key.upArrow || key.downArrow || key.leftArrow || key.rightArrow || key.meta) {\n return;\n }\n if (input) {\n updateState(tabIndex, (s) => ({ ...s, notesDraft: s.notesDraft + input }));\n }\n return;\n }\n\n // ---------- picker 主模式 ----------\n if (key.escape) {\n cancel();\n return;\n }\n\n if (hasTabs && (key.tab || key.leftArrow || key.rightArrow)) {\n if (key.leftArrow || (key.shift && key.tab)) {\n setTabIndex((t) => Math.max(0, t - 1));\n } else {\n setTabIndex((t) => Math.min(submitTabIndex, t + 1));\n }\n return;\n }\n\n if (onSubmitChip) {\n if (key.return) submit();\n return;\n }\n\n const qi = tabIndex;\n const s = states[qi];\n\n if (key.upArrow) {\n updateState(qi, (st) => ({ ...st, optionIndex: Math.max(0, st.optionIndex - 1) }));\n return;\n }\n if (key.downArrow) {\n updateState(qi, (st) => ({\n ...st,\n optionIndex: Math.min(optionRowCount - 1, st.optionIndex + 1),\n }));\n return;\n }\n // n —— 进入 notes 编辑(任何 picker 题都允许,对齐 Claude Code)\n if (input === \"n\" && !key.ctrl && !key.meta) {\n updateState(qi, (st) => ({\n ...st,\n notesEditing: true,\n notesDraft: st.notes,\n }));\n return;\n }\n if (key.return) {\n if (!hasTabs && isMulti && s.optionIndex === singleQMultiSubmitRowIndex) {\n submit();\n return;\n }\n if (isMulti) toggleOption(qi, s.optionIndex);\n else selectSingleOption(qi, s.optionIndex);\n return;\n }\n if (isMulti && input === \" \" && s.optionIndex !== singleQMultiSubmitRowIndex) {\n toggleOption(qi, s.optionIndex);\n }\n });\n\n // ---------- render ----------\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Divider />\n {hasTabs && (\n <Box marginTop={0}>\n <TabBar questions={questions} states={states} tabIndex={tabIndex} />\n </Box>\n )}\n\n {tabIndex < N && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>{questions[tabIndex].question}</Text>\n <Box flexDirection=\"row\" marginTop={1}>\n <Box flexDirection=\"column\" flexGrow={anyPreview ? 0 : 1} flexShrink={0} marginRight={anyPreview ? 2 : 0}>\n <OptionsList\n options={questions[tabIndex].options}\n focusedIndex={states[tabIndex].optionIndex}\n selected={states[tabIndex].selected}\n isMulti={isMulti}\n submitRowIndex={singleQMultiSubmitRowIndex}\n />\n </Box>\n {anyPreview && (\n <Box flexGrow={1} minWidth={PREVIEW_MIN_WIDTH}>\n <PreviewPanel content={focusedPreview} />\n </Box>\n )}\n </Box>\n <NotesLine\n notes={states[tabIndex].notes}\n editing={states[tabIndex].notesEditing}\n draft={states[tabIndex].notesDraft}\n />\n </Box>\n )}\n\n {onSubmitChip && (\n <Box flexDirection=\"column\" marginTop={1}>\n <SubmitPreview questions={questions} states={states} />\n </Box>\n )}\n\n <Divider />\n <Box>\n <Text dimColor>{hintLine(hasTabs, isMulti, currentNotesEditing)}</Text>\n </Box>\n </Box>\n );\n}\n\n// ---------- subcomponents ----------\n\nfunction Divider() {\n // 占满终端宽度的水平细线——用 box 的 borderTop 模拟最简单\n return (\n <Box borderStyle=\"single\" borderTop borderBottom={false} borderLeft={false} borderRight={false} borderColor=\"gray\" />\n );\n}\n\nfunction TabBar({\n questions,\n states,\n tabIndex,\n}: {\n questions: AskQuestion[];\n states: QState[];\n tabIndex: number;\n}) {\n const submitIndex = questions.length;\n const canLeft = tabIndex > 0;\n const canRight = tabIndex < submitIndex;\n return (\n <Box flexDirection=\"row\" flexWrap=\"wrap\">\n <Box marginRight={1}>\n <Text dimColor={!canLeft}>{\"←\"}</Text>\n </Box>\n {questions.map((q, i) => {\n const focused = i === tabIndex;\n const isMulti = q.multiSelect === true;\n const count = states[i].selected.size;\n const answered = count > 0;\n const mark = answered ? (isMulti ? `[${count}]` : \"✔\") : \"□\";\n return (\n <Box key={i} marginRight={TAB_GAP}>\n <Text\n backgroundColor={focused ? FOCUS_BG : undefined}\n color={focused ? FOCUS_FG : undefined}\n bold={focused}\n dimColor={!focused}\n >\n {` ${mark} ${q.header} `}\n </Text>\n </Box>\n );\n })}\n <Box marginRight={1}>\n <Text\n backgroundColor={tabIndex === submitIndex ? FOCUS_BG : undefined}\n color={tabIndex === submitIndex ? FOCUS_FG : SUBMIT_COLOR}\n bold={tabIndex === submitIndex}\n dimColor={tabIndex !== submitIndex}\n >\n {\" ✔ Submit \"}\n </Text>\n </Box>\n <Text dimColor={!canRight}>{\"→\"}</Text>\n </Box>\n );\n}\n\nfunction OptionsList({\n options,\n focusedIndex,\n selected,\n isMulti,\n submitRowIndex,\n}: {\n options: AskQuestion[\"options\"];\n focusedIndex: number;\n selected: Set<number>;\n isMulti: boolean;\n submitRowIndex: number;\n}) {\n return (\n <Box flexDirection=\"column\">\n {options.map((opt, i) => {\n const focused = i === focusedIndex;\n const checked = selected.has(i);\n return (\n <Box key={i} flexDirection=\"column\">\n <Box flexDirection=\"row\">\n <Text color={POINTER_COLOR} bold>\n {focused ? \"› \" : \" \"}\n </Text>\n {isMulti && (\n <Text color={checked ? \"green\" : undefined}>{checked ? \"[x] \" : \"[ ] \"}</Text>\n )}\n <Text dimColor>{`${i + 1}. `}</Text>\n <Text color={focused ? POINTER_COLOR : undefined} bold={focused}>\n {opt.label}\n </Text>\n </Box>\n {opt.description && (\n <Box marginLeft={isMulti ? 6 : 5}>\n <Text dimColor wrap=\"truncate-end\">\n {opt.description}\n </Text>\n </Box>\n )}\n </Box>\n );\n })}\n {submitRowIndex >= 0 && (\n <Box flexDirection=\"row\" marginTop={1}>\n <Text color={POINTER_COLOR} bold>\n {focusedIndex === submitRowIndex ? \"› \" : \" \"}\n </Text>\n <Text\n color={focusedIndex === submitRowIndex ? SUBMIT_COLOR : undefined}\n bold={focusedIndex === submitRowIndex}\n dimColor={focusedIndex !== submitRowIndex}\n >\n {`── Submit (${selected.size} selected)`}\n </Text>\n </Box>\n )}\n </Box>\n );\n}\n\nfunction PreviewPanel({ content }: { content: string }) {\n const lines = content ? content.split(\"\\n\") : [\"(no preview)\"];\n return (\n <Box\n borderStyle=\"round\"\n borderColor={PREVIEW_BORDER}\n flexDirection=\"column\"\n paddingX={1}\n flexGrow={1}\n >\n {lines.map((line, i) => (\n <Text key={i} wrap=\"truncate-end\" dimColor={!content}>\n {line || \" \"}\n </Text>\n ))}\n </Box>\n );\n}\n\nfunction NotesLine({\n notes,\n editing,\n draft,\n}: {\n notes: string;\n editing: boolean;\n draft: string;\n}) {\n if (editing) {\n return (\n <Box marginTop={1} flexDirection=\"row\">\n <Text color={NOTES_LABEL_COLOR} bold>\n {\"Notes: \"}\n </Text>\n <Text>{draft}</Text>\n <Text color={POINTER_COLOR}>{\"▎\"}</Text>\n <Box flexGrow={1} marginLeft={2}>\n <Text dimColor>{\"(Enter to save · Esc to discard)\"}</Text>\n </Box>\n </Box>\n );\n }\n return (\n <Box marginTop={1} flexDirection=\"row\" justifyContent=\"center\">\n <Text color={NOTES_LABEL_COLOR} bold>\n {\"Notes: \"}\n </Text>\n {notes ? (\n <Text>{notes}</Text>\n ) : (\n <Text dimColor>{\"press n to add notes\"}</Text>\n )}\n </Box>\n );\n}\n\nfunction SubmitPreview({\n questions,\n states,\n}: {\n questions: AskQuestion[];\n states: QState[];\n}) {\n return (\n <Box flexDirection=\"column\">\n <Text bold>Review</Text>\n {questions.map((q, qi) => {\n const sel = Array.from(states[qi].selected)\n .sort((a, b) => a - b)\n .map((i) => q.options[i].label);\n const notes = states[qi].notes.trim();\n return (\n <Box key={qi} flexDirection=\"column\" marginLeft={2}>\n <Box flexDirection=\"row\">\n <Text color=\"yellow\">{`${q.header}: `}</Text>\n <Text dimColor={sel.length === 0}>\n {sel.length > 0 ? sel.join(\", \") : \"(no answer)\"}\n </Text>\n </Box>\n {notes && (\n <Box marginLeft={2} flexDirection=\"row\">\n <Text color={NOTES_LABEL_COLOR}>{\"notes: \"}</Text>\n <Text dimColor>{notes}</Text>\n </Box>\n )}\n </Box>\n );\n })}\n </Box>\n );\n}\n\nfunction hintLine(hasTabs: boolean, isMulti: boolean, editingNotes: boolean): string {\n if (editingNotes) {\n return \"Enter to save · Esc to discard · backspace to delete\";\n }\n const parts: string[] = [\"Enter to select\", \"↑/↓ to navigate\", \"n to add notes\"];\n if (hasTabs) parts.push(\"Tab to switch questions\");\n if (isMulti) parts.push(\"Space to toggle\");\n parts.push(\"Esc to cancel\");\n return parts.join(\" · \");\n}\n","/**\n * Slash 命令自动补全 overlay。\n *\n * 触发条件:input.startsWith(\"/\") && !input.includes(\" \")(用户在输入命令名阶段)\n * 进入参数阶段(空格之后)→ overlay 关闭,让用户安静地输入参数\n *\n * 显示:默认色 / + name + dim description\n * focused 行整条命令名变紫色 + bold(不用 inverse 背景条)\n * 超过 maxVisible 行折叠尾部\n *\n * 渲染由 App 控制,本组件是纯展示。\n */\n\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\nimport type { SlashCommand } from \"../slash/index.js\";\n\nexport interface SlashAutocompleteProps {\n matches: SlashCommand[];\n index: number;\n maxVisible?: number;\n}\n\nconst DEFAULT_MAX = 10;\nconst SLASH_COLOR = \"#A855F7\";\n\nexport function SlashAutocomplete({ matches, index, maxVisible = DEFAULT_MAX }: SlashAutocompleteProps) {\n if (matches.length === 0) return null;\n\n // 窗口:保证 focused 始终可见\n const start = Math.max(0, Math.min(index - Math.floor(maxVisible / 2), matches.length - maxVisible));\n const end = Math.min(matches.length, start + maxVisible);\n const visible = matches.slice(start, end);\n\n const nameWidth = Math.max(...matches.map((c) => c.name.length));\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n {visible.map((cmd, i) => {\n const realIndex = start + i;\n return (\n <Row key={cmd.name} cmd={cmd} focused={realIndex === index} nameWidth={nameWidth} />\n );\n })}\n {matches.length > visible.length && (\n <Box marginLeft={2}>\n <Text dimColor>\n ↑↓ select · Tab/Enter accept · Esc cancel ({matches.length - visible.length} more)\n </Text>\n </Box>\n )}\n {matches.length <= visible.length && (\n <Box marginLeft={2}>\n <Text dimColor>↑↓ select · Tab/Enter accept · Esc cancel</Text>\n </Box>\n )}\n </Box>\n );\n}\n\nfunction Row({ cmd, focused, nameWidth }: { cmd: SlashCommand; focused: boolean; nameWidth: number }) {\n const padded = cmd.name.padEnd(nameWidth);\n // focused 整条命令名变紫色 + bold;非 focused 用默认色\n return (\n <Box flexDirection=\"row\">\n <Text color={focused ? SLASH_COLOR : undefined} bold={focused}>\n {\"/\"}{padded}\n </Text>\n <Text>{\" \"}</Text>\n <Text dimColor>{cmd.description}</Text>\n </Box>\n );\n}\n","/**\n * 权限模式状态栏。固定在 TUI 输入框下方。\n *\n * 设计:见文档库 permission-modes.md §四 状态栏 UI。\n */\n\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\nimport { MODE_LABEL, MODE_COLOR, type PermissionMode } from \"../permission/index.js\";\n\nexport function PermissionModeBar({ mode, compact }: { mode: PermissionMode; compact?: boolean }) {\n const color = MODE_COLOR[mode];\n const label = MODE_LABEL[mode];\n const isBypass = mode === \"bypassPermissions\";\n\n if (compact) {\n const short: Record<PermissionMode, string> = {\n default: \"[default]\",\n acceptEdits: \"[edits]\",\n plan: \"[plan]\",\n bypassPermissions: \"[bypass]\",\n };\n return (\n <Box flexDirection=\"row\">\n <Text color={color} bold={isBypass}>{short[mode]}</Text>\n <Text dimColor>{\" shift+tab\"}</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"row\">\n <Text color={color} bold={isBypass}>{\"▸▸ \"}{label}</Text>\n <Text dimColor>{\" (shift+tab to cycle)\"}</Text>\n </Box>\n );\n}\n","/**\n * 权限模型:三态 allow / ask / deny,叠加 4 档 PermissionMode。\n *\n * 模式匹配(pattern):\n * - \"ToolName\" 精确匹配\n * - \"Bash(<prefix>)\" 匹配 Bash 工具 + 命令前缀\n * - \"Bash(<prefix>:*)\" 通配\n *\n * PermissionMode(详见文档库 permission-modes.md):\n * - default:完全走 settings.permissions 规则\n * - acceptEdits:Edit/Write 自动 allow,其他走 default\n * - plan:只允许 read 类工具,其他全 deny\n * - bypassPermissions:除显式 deny 与 Bash 硬 deny 外全 allow\n *\n * 危险操作(rm -rf / sudo 等)由 Bash 工具内部 HARD_DENY_PATTERNS 兜底,所有模式都不可绕过。\n */\n\nimport type { Permissions } from \"../config/types.js\";\nimport type { PermissionLevel } from \"../tools/types.js\";\n\nexport type Decision = \"allow\" | \"ask\" | \"deny\";\n\n/** 用户对 PermissionPrompt 三档选择。 */\nexport type PermissionDecision = \"yes\" | \"session_allow\" | \"no\";\n\nexport type PermissionMode = \"default\" | \"acceptEdits\" | \"plan\" | \"bypassPermissions\";\n\nexport const MODE_CYCLE: readonly PermissionMode[] = [\n \"default\",\n \"acceptEdits\",\n \"plan\",\n \"bypassPermissions\",\n] as const;\n\nexport const MODE_LABEL: Record<PermissionMode, string> = {\n default: \"default permissions on\",\n acceptEdits: \"accept edits on\",\n plan: \"plan mode on\",\n bypassPermissions: \"bypass permissions on\",\n};\n\nexport const MODE_COLOR: Record<PermissionMode, string> = {\n default: \"gray\",\n acceptEdits: \"#EAB308\",\n plan: \"#06B6D4\",\n bypassPermissions: \"#EF4444\",\n};\n\nexport interface PermissionInput {\n toolName: string;\n args: unknown;\n /** Tool 的权限级别;由 Agent loop 从 ToolRegistry 注入。Plan 模式用此区分 read/write。 */\n permission?: PermissionLevel;\n}\n\nexport class PermissionGate {\n private rules: Required<Permissions>;\n private mode: PermissionMode = \"default\";\n /** Session 级 allow:用户在 PermissionPrompt 选 \"yes, for session\" 后填充。 */\n private sessionAllow = new Set<string>();\n\n constructor(rules: Permissions = {}) {\n this.rules = {\n allow: rules.allow ?? [],\n ask: rules.ask ?? [],\n deny: rules.deny ?? [],\n defaultMode: rules.defaultMode ?? \"ask\",\n };\n }\n\n setMode(mode: PermissionMode): void {\n this.mode = mode;\n }\n\n getMode(): PermissionMode {\n return this.mode;\n }\n\n cycleMode(): PermissionMode {\n const i = MODE_CYCLE.indexOf(this.mode);\n this.mode = MODE_CYCLE[(i + 1) % MODE_CYCLE.length];\n return this.mode;\n }\n\n /** 用户在 PermissionPrompt 选 \"yes, allow for session\" 时记下。 */\n allowForSession(toolName: string): void {\n this.sessionAllow.add(toolName);\n }\n\n isSessionAllowed(toolName: string): boolean {\n return this.sessionAllow.has(toolName);\n }\n\n decide(input: PermissionInput): Decision {\n // 用户显式 deny 永远生效,所有模式不可绕过\n if (this.matches(this.rules.deny, input)) return \"deny\";\n // session 级 allow 在 deny 之后、mode 分支之前生效\n if (this.sessionAllow.has(input.toolName)) return \"allow\";\n\n switch (this.mode) {\n case \"bypassPermissions\":\n return \"allow\";\n\n case \"plan\":\n // 只允许只读工具;写/执行/网络类直接 deny\n return input.permission === \"read\" ? \"allow\" : \"deny\";\n\n case \"acceptEdits\":\n if (input.toolName === \"Edit\" || input.toolName === \"Write\") return \"allow\";\n return this.defaultDecide(input);\n\n case \"default\":\n default:\n return this.defaultDecide(input);\n }\n }\n\n private defaultDecide(input: PermissionInput): Decision {\n if (this.matches(this.rules.allow, input)) return \"allow\";\n if (this.matches(this.rules.ask, input)) return \"ask\";\n switch (this.rules.defaultMode) {\n case \"strict\":\n return \"ask\";\n case \"relaxed\":\n return \"allow\";\n case \"ask\":\n default:\n return \"ask\";\n }\n }\n\n private matches(patterns: string[], input: PermissionInput): boolean {\n for (const pattern of patterns) {\n if (this.matchOne(pattern, input)) return true;\n }\n return false;\n }\n\n private matchOne(pattern: string, input: PermissionInput): boolean {\n // \"ToolName\" 精确匹配\n if (!pattern.includes(\"(\")) {\n return pattern === input.toolName;\n }\n // \"Bash(<prefix>:*)\" 形式\n const m = pattern.match(/^([A-Za-z_][A-Za-z0-9_]*)\\(([^)]*)\\)$/);\n if (!m) return false;\n const [, toolName, sub] = m;\n if (toolName !== input.toolName) return false;\n if (input.toolName === \"Bash\" && typeof input.args === \"object\" && input.args !== null) {\n const cmd = (input.args as { command?: string }).command ?? \"\";\n if (sub.endsWith(\":*\")) {\n const prefix = sub.slice(0, -2);\n return cmd.startsWith(prefix);\n }\n return cmd === sub || cmd.startsWith(sub + \" \");\n }\n return false;\n }\n}\n","/**\n * 输入框下方的状态尾栏(对齐 Claude Code 风格)。\n *\n * 信息(从左到右):\n * @<sid8> 当前 session 短 id(首 8 字符;resume 后亦同)\n * <model> 当前模型 id\n * ctx: ████░ NN% 上下文窗口填充率(基于最近一轮 input tokens / maxContextWindow)\n * <in>/<max> 绝对值,便于核对\n * ↑<in> ↓<out> 本会话累计 token(自 app 启动后;/resume 不回灌)\n *\n * 配色(对齐 Claude Code 的 footer):\n * session id → cyan bold (如 Claude Code 的 \"Sync code...\" 标题色)\n * model → magenta (如 Claude Code 的 \"Opus 4.7 (1M context)\" 粉品红)\n * \"ctx:\" → 默认白 (label 不 dim,醒目)\n * 填充进度条 → 主题色:<70% green / 70–89% yellow / ≥90% red(\"快爆\"警告)\n * 百分比 / in/max → dim gray (次要信息)\n * \"│\" → dim gray (分隔符弱化)\n * ↑ 累计 in → green\n * ↓ 累计 out → blueBright\n *\n * 宽度策略:\n * termWidth >= 100 完整版(含累计 token)\n * 60 ≤ width < 100 精简版(去掉 ↑↓ 累计、去掉 in/max)\n * width < 60 极简版(只剩 sid · model · 进度条 NN%)\n */\n\nimport React from \"react\";\nimport { Box, Text } from \"ink\";\n\nconst BAR_TOTAL_WIDE = 10;\nconst BAR_TOTAL_COMPACT = 6;\n\nexport interface FooterStatusProps {\n /** 当前 session id(取首 8 字符显示)。 */\n sessionId: string;\n /** 当前模型 id(如 \"deepseek-chat\")。 */\n model: string;\n /** 模型上下文窗口大小;0/未知时隐藏 ctx 字段。 */\n contextWindow: number;\n /** 最近一轮 input tokens;约等于本轮 prompt 实际占用的上下文。 */\n lastInputTokens: number;\n /** 本会话累计 input tokens。 */\n sessionInputTokens: number;\n /** 本会话累计 output tokens。 */\n sessionOutputTokens: number;\n /** 终端宽度,用于布局降级。 */\n termWidth: number;\n}\n\nexport function FooterStatus({\n sessionId,\n model,\n contextWindow,\n lastInputTokens,\n sessionInputTokens,\n sessionOutputTokens,\n termWidth,\n}: FooterStatusProps) {\n const sid = sessionId.slice(0, 8);\n const hasCtx = contextWindow > 0;\n const pct = hasCtx ? Math.min(100, Math.round((lastInputTokens / contextWindow) * 100)) : 0;\n const ctxColor: \"green\" | \"yellow\" | \"red\" = pct >= 90 ? \"red\" : pct >= 70 ? \"yellow\" : \"green\";\n\n const SEP = <Text dimColor>{\" │ \"}</Text>;\n const SEP_DOT = <Text dimColor>{\" · \"}</Text>;\n\n // 已填部分按阈值上色,未填部分恒 dim gray;0% 时整条灰\n const renderBar = (barW: number): React.ReactNode => {\n const filled = Math.round((pct / 100) * barW);\n const empty = barW - filled;\n return (\n <>\n {filled > 0 && <Text color={ctxColor}>{\"█\".repeat(filled)}</Text>}\n {empty > 0 && <Text dimColor>{\"░\".repeat(empty)}</Text>}\n </>\n );\n };\n\n // <60: 极简\n if (termWidth < 60) {\n return (\n <Box flexDirection=\"row\">\n <Text color=\"cyan\" bold>{sid}</Text>\n {SEP_DOT}\n <Text color=\"magenta\">{model}</Text>\n {hasCtx && (\n <>\n {SEP_DOT}\n {renderBar(BAR_TOTAL_COMPACT)}\n <Text dimColor>{` ${pct}%`}</Text>\n </>\n )}\n </Box>\n );\n }\n\n // 60–100: 精简(无累计 token、无 in/max 绝对值)\n if (termWidth < 100) {\n return (\n <Box flexDirection=\"row\">\n <Text color=\"cyan\" bold>{`@${sid}`}</Text>\n {SEP}\n <Text color=\"magenta\">{model}</Text>\n {hasCtx && (\n <>\n {SEP}\n <Text>{\"ctx: \"}</Text>\n {renderBar(BAR_TOTAL_COMPACT)}\n <Text dimColor>{` ${pct}%`}</Text>\n </>\n )}\n </Box>\n );\n }\n\n // ≥100: 完整\n return (\n <Box flexDirection=\"row\">\n <Text color=\"cyan\" bold>{`@${sid}`}</Text>\n {SEP}\n <Text color=\"magenta\">{model}</Text>\n {hasCtx && (\n <>\n {SEP}\n <Text>{\"ctx: \"}</Text>\n {renderBar(BAR_TOTAL_WIDE)}\n <Text dimColor>{` ${pct}%`}</Text>\n <Text dimColor>{` ${formatTokens(lastInputTokens)}/${formatTokens(contextWindow)}`}</Text>\n </>\n )}\n {SEP}\n <Text>{\"tok: \"}</Text>\n <Text color=\"green\">{`↑${formatTokens(sessionInputTokens)}`}</Text>\n <Text> </Text>\n <Text color=\"blueBright\">{`↓${formatTokens(sessionOutputTokens)}`}</Text>\n </Box>\n );\n}\n\nfunction formatTokens(n: number): string {\n if (n < 1000) return String(n);\n if (n < 10000) return (n / 1000).toFixed(1).replace(/\\.0$/, \"\") + \"k\";\n if (n < 1000000) return Math.round(n / 1000) + \"k\";\n return (n / 1000000).toFixed(1).replace(/\\.0$/, \"\") + \"M\";\n}\n","/**\n * 通用进度横幅:cyan 标签 + 经过秒数 + 进度条 + 旋转 tip。\n *\n * 由 SlashActions.showProgress/hideProgress 控制;目前 /compact 是首个使用者。\n *\n * 视觉对齐 Claude Code 的 /compact 体验:\n * ✦ <Title>... (Ns)\n * ▰▰▰▰▰▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱▱ 24%\n * └ Tip: <rotating>\n */\n\nimport React, { useEffect, useState } from \"react\";\nimport { Box, Text } from \"ink\";\n\nexport interface ProgressState {\n title: string;\n tips: string[];\n /** 0-100;ProgressBanner 自行 clamp 与 floor。 */\n getPercent: () => number;\n startTime: number;\n}\n\nconst BAR_WIDTH = 42;\nconst TICK_MS = 400;\nconst TIP_ROTATE_SEC = 5;\n\nexport function ProgressBanner({ state }: { state: ProgressState }) {\n const [now, setNow] = useState(Date.now());\n useEffect(() => {\n const t = setInterval(() => setNow(Date.now()), TICK_MS);\n return () => clearInterval(t);\n }, []);\n\n const elapsedSec = Math.max(0, Math.floor((now - state.startTime) / 1000));\n const percent = Math.max(0, Math.min(99, Math.floor(state.getPercent())));\n const filled = Math.floor((percent / 100) * BAR_WIDTH);\n const empty = BAR_WIDTH - filled;\n const bar = \"▰\".repeat(filled) + \"▱\".repeat(empty);\n const tip = state.tips.length\n ? state.tips[Math.floor(elapsedSec / TIP_ROTATE_SEC) % state.tips.length]\n : \"\";\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Box>\n <Text color=\"cyan\" bold>✦ </Text>\n <Text color=\"cyan\">{state.title}...</Text>\n <Text dimColor>{` (${elapsedSec}s)`}</Text>\n </Box>\n <Box marginLeft={2}>\n <Text color=\"cyan\">{bar}</Text>\n <Text dimColor>{` ${percent}%`}</Text>\n </Box>\n {tip && (\n <Box marginLeft={2}>\n <Text dimColor>{`└ Tip: ${tip}`}</Text>\n </Box>\n )}\n </Box>\n );\n}\n","/**\n * 处理中的状态行(流式 / 工具执行期间常驻底部)。\n *\n * 两行设计:\n * ● Working… ✨闪烁 (12s · ↑ 1.2k tokens · thought for 4s)\n * ↳ Read(src/foo.ts) ← 仅 runningTool != null 时出现\n *\n * 主线(Working)始终在跑,扫光动画提示 \"活着\"。工具行作为子线路按需呈现。\n * 不接收 status 字段——调用方根据 status !== \"idle\" 决定是否挂载本组件。\n */\n\nimport React, { useEffect, useState } from \"react\";\nimport { Box, Text } from \"ink\";\nimport { Shimmer } from \"./Shimmer.js\";\n\nconst TICK_MS = 400;\n\nexport interface StatusLineProps {\n /** 本轮开始时间(user_submit 触发时 Date.now())。 */\n startTime: number;\n /** 首次 text-delta 时间(\"thought for\" 用);null 表示尚未流出任何 text。 */\n firstTextTime: number | null;\n /** 本轮已累计的 input tokens(usage 事件累加,>0 才显示)。 */\n inputTokens: number;\n /** 工具运行中时的工具名,null 表示不在跑工具。 */\n runningTool: string | null;\n /** UI 语言:影响标签文案。 */\n lang: \"en\" | \"zh-CN\";\n}\n\nexport function StatusLine({ startTime, firstTextTime, inputTokens, runningTool, lang }: StatusLineProps) {\n const [now, setNow] = useState(Date.now());\n useEffect(() => {\n const t = setInterval(() => setNow(Date.now()), TICK_MS);\n return () => clearInterval(t);\n }, []);\n\n const elapsedSec = Math.max(0, Math.floor((now - startTime) / 1000));\n const mainLabel = lang === \"zh-CN\" ? \"工作中\" : \"Working\";\n\n const parts: string[] = [formatDuration(elapsedSec)];\n if (inputTokens > 0) {\n parts.push(`↑ ${formatTokens(inputTokens)} tokens`);\n }\n if (firstTextTime !== null) {\n const thinkSec = Math.max(0, Math.floor((firstTextTime - startTime) / 1000));\n parts.push(\n lang === \"zh-CN\" ? `思考 ${formatDuration(thinkSec)}` : `thought for ${formatDuration(thinkSec)}`,\n );\n }\n\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n <Box flexDirection=\"row\">\n <Text color=\"gray\">● </Text>\n <Shimmer text={mainLabel} />\n <Text dimColor>{` (${parts.join(\" · \")})`}</Text>\n </Box>\n {runningTool && (\n <Box flexDirection=\"row\" marginLeft={2} marginTop={0}>\n <Text dimColor>{\"↳ \"}</Text>\n <Text color=\"cyan\">{runningTool}</Text>\n </Box>\n )}\n </Box>\n );\n}\n\nfunction formatTokens(n: number): string {\n if (n < 1000) return String(n);\n if (n < 10000) return (n / 1000).toFixed(1).replace(/\\.0$/, \"\") + \"k\";\n if (n < 1000000) return Math.round(n / 1000) + \"k\";\n return (n / 1000000).toFixed(1).replace(/\\.0$/, \"\") + \"M\";\n}\n\nfunction formatDuration(sec: number): string {\n if (sec < 60) return `${sec}s`;\n const m = Math.floor(sec / 60);\n const s = sec % 60;\n return s === 0 ? `${m}m` : `${m}m${s}s`;\n}\n","/**\n * 字面闪烁动画:一个明亮窗口从左往右扫过文字,到尾巴后有短暂间隔再从头来。\n *\n * 渲染方式:把 text 拆成单字符 <Text>,按到当前 phase 的距离上色——\n * distance 0 → bright white + bold\n * distance 1 → white\n * 其他 → dim gray\n * 一个 setInterval 推进 phase。\n *\n * 视觉效果:像扫光带掠过 \"Working\" 字样,无 spinner 字符。\n */\n\nimport React, { useEffect, useState } from \"react\";\nimport { Text } from \"ink\";\n\nconst FRAME_MS = 100;\nconst TRAIL = 4; // 扫完最后一个字符后再走几帧再绕回起点,给眼睛留间隔\n\nexport interface ShimmerProps {\n text: string;\n bold?: boolean;\n}\n\nexport function Shimmer({ text, bold = true }: ShimmerProps) {\n const chars = Array.from(text);\n const cycle = chars.length + TRAIL;\n\n const [phase, setPhase] = useState(0);\n useEffect(() => {\n const id = setInterval(() => {\n setPhase((p) => (p + 1) % cycle);\n }, FRAME_MS);\n return () => clearInterval(id);\n }, [cycle]);\n\n return (\n <Text>\n {chars.map((ch, i) => {\n const d = Math.abs(i - phase);\n if (d === 0) {\n return (\n <Text key={i} color=\"white\" bold={bold}>\n {ch}\n </Text>\n );\n }\n if (d === 1) {\n return (\n <Text key={i} color=\"white\">\n {ch}\n </Text>\n );\n }\n return (\n <Text key={i} color=\"gray\" dimColor>\n {ch}\n </Text>\n );\n })}\n </Text>\n );\n}\n","/**\n * 终端标题栏控制(OSC 0/1/2 转义序列)。\n *\n * 用途:在 OS-level tab/window 标题里放一个旋转动画 + 当前状态,\n * 让用户切到别的窗口也能从 dock / taskbar 看出 muse 还在跑(vs 卡死 / 已完成)。\n *\n * 协议:`ESC ] 0 ; <text> BEL` 同时设置 icon name 和 window title——所有主流\n * 终端都认(Terminal.app / iTerm2 / Alacritty / kitty / WezTerm / Windows Terminal)。\n *\n * 安全:非 TTY(管道、CI)和 MUSE_NO_TITLE=1 时静默;title 文本 strip 控制字符\n * 防止注入。\n */\n\nconst ENABLED = (() => {\n if (!process.stdout.isTTY) return false;\n if (process.env.MUSE_NO_TITLE === \"1\") return false;\n return true;\n})();\n\nlet lastTitle = \"\";\n\nfunction sanitize(s: string): string {\n // 删 NUL / BEL / ESC / 其它 C0 控制符——防止用户 cwd 包含恶意字节注入 title\n return s.replace(/[\\x00-\\x1f\\x7f]/g, \"\");\n}\n\n/** 设标题;与上次完全相同时跳过(减少 stdout 写流量)。 */\nexport function setTerminalTitle(title: string): void {\n if (!ENABLED) return;\n const clean = sanitize(title);\n if (clean === lastTitle) return;\n lastTitle = clean;\n process.stdout.write(`\\x1b]0;${clean}\\x07`);\n}\n\n/** 清空标题(让终端用默认值)。在进程退出前调一次。 */\nexport function resetTerminalTitle(): void {\n if (!ENABLED) return;\n lastTitle = \"\";\n process.stdout.write(`\\x1b]0;\\x07`);\n}\n","/**\n * OpenAI 兼容协议 provider。\n * 覆盖:OpenAI 官方、DeepSeek、Qwen、Moonshot (Kimi)、智谱、OpenRouter、Ollama (其 /v1 endpoint)、自建 vLLM/LocalAI 等。\n *\n * Why 自己包一层而不是直接用 @ai-sdk/openai-compatible:\n * - 抹平 stream 事件差异,统一为本仓库的 LLMEvent 类型\n * - 在 stream 中拼装 tool_call.arguments(OpenAI 流式 tool_call 是分片增量的 JSON 字符串)\n * - 留口子未来插入降级、重试、token 计数估算\n */\n\nimport { createOpenAICompatible } from \"@ai-sdk/openai-compatible\";\nimport { streamText, jsonSchema, tool, type CoreMessage, type ToolSet } from \"ai\";\nimport type {\n LLMClient,\n LLMEvent,\n ModelCapabilities,\n ProviderConfig,\n StreamOptions,\n} from \"../types.js\";\nimport type { Message, AssistantMessage, ToolDefinition } from \"../../types/index.js\";\nimport { log, redactApiKey } from \"../../log/index.js\";\n\ninterface OpenAICompatibleProviderOpts {\n providerName: string;\n baseUrl: string;\n apiKey: string;\n model: string;\n capabilities?: Partial<ModelCapabilities>;\n}\n\nconst DEFAULT_CAPABILITIES: ModelCapabilities = {\n toolCalling: true,\n parallelToolCalls: true,\n vision: false,\n jsonMode: true,\n maxContextWindow: 32_000,\n};\n\nexport class OpenAICompatibleClient implements LLMClient {\n readonly providerName: string;\n readonly model: string;\n readonly capabilities: ModelCapabilities;\n private modelProvider: ReturnType<ReturnType<typeof createOpenAICompatible>>;\n\n constructor(opts: OpenAICompatibleProviderOpts) {\n this.providerName = opts.providerName;\n this.model = opts.model;\n this.capabilities = { ...DEFAULT_CAPABILITIES, ...opts.capabilities };\n\n const provider = createOpenAICompatible({\n name: opts.providerName,\n baseURL: opts.baseUrl,\n apiKey: opts.apiKey,\n });\n this.modelProvider = provider(opts.model);\n\n log.debug(\"LLM provider initialized\", {\n provider: opts.providerName,\n model: opts.model,\n baseUrl: opts.baseUrl,\n apiKey: redactApiKey(opts.apiKey),\n });\n }\n\n async *stream(opts: StreamOptions): AsyncIterable<LLMEvent> {\n const { messages, tools, systemPrompt, temperature, maxTokens, abortSignal } = opts;\n\n const aiMessages = convertMessages(messages, systemPrompt);\n const aiTools = tools ? convertTools(tools) : undefined;\n\n // 重试:仅在还没收到任何 chunk 时(连接级错误)退避重试,最多 3 次\n let attempt = 0;\n const maxAttempts = 3;\n let result: ReturnType<typeof streamText> | undefined;\n while (true) {\n try {\n result = streamText({\n model: this.modelProvider,\n messages: aiMessages,\n tools: aiTools,\n temperature,\n maxTokens,\n abortSignal,\n });\n break;\n } catch (err) {\n if (abortSignal?.aborted) {\n yield { type: \"error\", error: err instanceof Error ? err : new Error(String(err)) };\n return;\n }\n if (!isRetryable(err) || attempt >= maxAttempts - 1) {\n yield { type: \"error\", error: err instanceof Error ? err : new Error(String(err)) };\n return;\n }\n const delay = 1000 * Math.pow(2, attempt);\n log.warn(`LLM connect failed (attempt ${attempt + 1}/${maxAttempts}); retrying in ${delay}ms`, {\n msg: err instanceof Error ? err.message : String(err),\n });\n await sleep(delay, abortSignal);\n attempt += 1;\n }\n }\n\n if (!result) {\n yield { type: \"error\", error: new Error(\"Internal: stream result is undefined after retry loop.\") };\n return;\n }\n const stream = result.fullStream;\n\n try {\n const seenToolCalls = new Set<string>();\n\n for await (const part of stream) {\n switch (part.type) {\n case \"text-delta\":\n yield { type: \"text\", delta: part.textDelta };\n break;\n\n case \"tool-call\":\n if (!seenToolCalls.has(part.toolCallId)) {\n seenToolCalls.add(part.toolCallId);\n yield { type: \"tool_call_start\", id: part.toolCallId, name: part.toolName };\n }\n yield {\n type: \"tool_call_complete\",\n id: part.toolCallId,\n name: part.toolName,\n args: part.args,\n };\n break;\n\n case \"finish\":\n yield {\n type: \"finish\",\n reason: mapFinishReason(part.finishReason),\n usage: part.usage\n ? {\n inputTokens: part.usage.promptTokens ?? 0,\n outputTokens: part.usage.completionTokens ?? 0,\n totalTokens: part.usage.totalTokens ?? 0,\n }\n : undefined,\n };\n break;\n\n case \"error\":\n yield { type: \"error\", error: part.error instanceof Error ? part.error : new Error(String(part.error)) };\n break;\n\n default:\n // 忽略其它(如 step-start / step-finish / tool-call-streaming-start 等)\n break;\n }\n }\n } catch (err) {\n yield { type: \"error\", error: err instanceof Error ? err : new Error(String(err)) };\n }\n }\n}\n\n// ---------- helpers ----------\n\nfunction convertMessages(messages: Message[], systemPrompt?: string): CoreMessage[] {\n const result: CoreMessage[] = [];\n if (systemPrompt) {\n result.push({ role: \"system\", content: systemPrompt });\n }\n for (const msg of messages) {\n switch (msg.role) {\n case \"system\":\n result.push({ role: \"system\", content: msg.content });\n break;\n case \"user\":\n if (typeof msg.content === \"string\") {\n result.push({ role: \"user\", content: msg.content });\n } else {\n const text = msg.content\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text)\n .join(\"\\n\");\n result.push({ role: \"user\", content: text });\n }\n break;\n case \"assistant\":\n result.push({ role: \"assistant\", content: convertAssistantContent(msg) });\n break;\n case \"tool\":\n result.push({\n role: \"tool\",\n content: [\n {\n type: \"tool-result\",\n toolCallId: msg.toolUseId,\n toolName: \"_tool\",\n result: msg.content,\n isError: msg.isError ?? false,\n },\n ],\n });\n break;\n }\n }\n return result;\n}\n\ntype AssistantContent = Extract<CoreMessage, { role: \"assistant\" }>[\"content\"];\n\nfunction convertAssistantContent(msg: AssistantMessage): AssistantContent {\n const parts: Array<\n { type: \"text\"; text: string } | { type: \"tool-call\"; toolCallId: string; toolName: string; args: unknown }\n > = [];\n for (const part of msg.content) {\n if (part.type === \"text\") {\n parts.push({ type: \"text\", text: part.text });\n } else if (part.type === \"tool_use\") {\n parts.push({\n type: \"tool-call\",\n toolCallId: part.id,\n toolName: part.name,\n args: part.args,\n });\n }\n }\n // 至少要有一个内容;空数组 SDK 会报错\n if (parts.length === 0) return \"\";\n return parts as AssistantContent;\n}\n\nfunction convertTools(tools: ToolDefinition[]): ToolSet {\n const result: ToolSet = {};\n for (const t of tools) {\n result[t.name] = tool({\n description: t.description,\n parameters: jsonSchema(t.parameters as Parameters<typeof jsonSchema>[0]),\n });\n }\n return result;\n}\n\nfunction isRetryable(err: unknown): boolean {\n if (!(err instanceof Error)) return false;\n const msg = err.message.toLowerCase();\n const code = (err as Error & { code?: string }).code ?? \"\";\n if (\n code === \"ECONNRESET\" ||\n code === \"ETIMEDOUT\" ||\n code === \"ENOTFOUND\" ||\n code === \"ECONNREFUSED\" ||\n code === \"EAI_AGAIN\"\n ) {\n return true;\n }\n if (\n msg.includes(\"fetch failed\") ||\n msg.includes(\"network\") ||\n msg.includes(\"socket hang up\") ||\n msg.includes(\"under maintenance\") ||\n msg.includes(\"rate limit\") ||\n msg.includes(\"429\") ||\n msg.includes(\"502\") ||\n msg.includes(\"503\") ||\n msg.includes(\"504\")\n ) {\n return true;\n }\n return false;\n}\n\nasync function sleep(ms: number, abortSignal?: AbortSignal): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n if (abortSignal?.aborted) return reject(new Error(\"aborted\"));\n const t = setTimeout(() => {\n abortSignal?.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n const onAbort = () => {\n clearTimeout(t);\n abortSignal?.removeEventListener(\"abort\", onAbort);\n reject(new Error(\"aborted\"));\n };\n abortSignal?.addEventListener(\"abort\", onAbort);\n });\n}\n\nfunction mapFinishReason(reason: string | undefined): \"stop\" | \"tool_calls\" | \"length\" | \"content_filter\" | \"error\" | \"unknown\" {\n switch (reason) {\n case \"stop\":\n case \"stop-sequence\":\n return \"stop\";\n case \"tool-calls\":\n case \"tool_calls\":\n return \"tool_calls\";\n case \"length\":\n return \"length\";\n case \"content-filter\":\n case \"content_filter\":\n return \"content_filter\";\n case \"error\":\n return \"error\";\n default:\n return \"unknown\";\n }\n}\n\n// ---------- 预设 provider 工厂 ----------\n\nexport interface PresetConfig {\n baseUrl: string;\n defaultModel: string;\n capabilities?: Partial<ModelCapabilities>;\n}\n\nexport const PRESETS: Record<string, PresetConfig> = {\n openai: {\n baseUrl: \"https://api.openai.com/v1\",\n defaultModel: \"gpt-4o-mini\",\n },\n deepseek: {\n baseUrl: \"https://api.deepseek.com/v1\",\n defaultModel: \"deepseek-chat\",\n capabilities: { maxContextWindow: 128_000 },\n },\n qwen: {\n baseUrl: \"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n defaultModel: \"qwen-plus\",\n capabilities: { maxContextWindow: 128_000 },\n },\n moonshot: {\n baseUrl: \"https://api.moonshot.cn/v1\",\n defaultModel: \"moonshot-v1-32k\",\n capabilities: { maxContextWindow: 32_000 },\n },\n zhipu: {\n baseUrl: \"https://open.bigmodel.cn/api/paas/v4\",\n defaultModel: \"glm-4-flash\",\n capabilities: { maxContextWindow: 128_000 },\n },\n ollama: {\n baseUrl: \"http://localhost:11434/v1\",\n defaultModel: \"llama3.1\",\n capabilities: { maxContextWindow: 8_000 },\n },\n openrouter: {\n baseUrl: \"https://openrouter.ai/api/v1\",\n defaultModel: \"openai/gpt-4o-mini\",\n },\n};\n\nexport function createPresetClient(\n providerName: string,\n config: ProviderConfig,\n model?: string,\n): OpenAICompatibleClient {\n const preset = PRESETS[providerName];\n if (!preset) {\n throw new Error(`Unknown provider preset: ${providerName}. Available: ${Object.keys(PRESETS).join(\", \")}`);\n }\n return new OpenAICompatibleClient({\n providerName,\n baseUrl: (config.baseUrl as string | undefined) ?? preset.baseUrl,\n apiKey: (config.apiKey as string | undefined) ?? \"\",\n model: model ?? preset.defaultModel,\n capabilities: preset.capabilities,\n });\n}\n","/**\n * Logger 包装。第一版用最朴素的 console + 文件追加;后期可替换 pino。\n * Why 不直接用 pino: 简化首版依赖图,等可观测性章节再上 pino。\n */\n\nimport { appendFileSync, mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport type LogLevel = \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\";\n\nconst LEVELS: Record<LogLevel, number> = {\n trace: 10,\n debug: 20,\n info: 30,\n warn: 40,\n error: 50,\n};\n\ninterface LogEntry {\n time: string;\n level: LogLevel;\n msg: string;\n [key: string]: unknown;\n}\n\nclass Logger {\n private level: LogLevel = \"info\";\n private logPath: string;\n private fileEnabled = true;\n\n constructor() {\n const date = new Date().toISOString().slice(0, 10);\n this.logPath = join(homedir(), \".muse\", \"logs\", `${date}.jsonl`);\n try {\n mkdirSync(dirname(this.logPath), { recursive: true });\n } catch {\n this.fileEnabled = false;\n }\n }\n\n setLevel(level: LogLevel) {\n this.level = level;\n }\n\n private write(level: LogLevel, msg: string, extra?: Record<string, unknown>) {\n if (LEVELS[level] < LEVELS[this.level]) return;\n const entry: LogEntry = {\n time: new Date().toISOString(),\n level,\n msg,\n ...extra,\n };\n if (this.fileEnabled) {\n try {\n appendFileSync(this.logPath, JSON.stringify(entry) + \"\\n\");\n } catch {\n // 落盘失败不阻断主流程\n }\n }\n // 仅 warn/error 默认输出到 stderr,避免污染 stdout\n if (level === \"warn\" || level === \"error\") {\n const prefix = level === \"error\" ? \"[error]\" : \"[warn]\";\n process.stderr.write(`${prefix} ${msg}\\n`);\n }\n }\n\n trace(msg: string, extra?: Record<string, unknown>) { this.write(\"trace\", msg, extra); }\n debug(msg: string, extra?: Record<string, unknown>) { this.write(\"debug\", msg, extra); }\n info(msg: string, extra?: Record<string, unknown>) { this.write(\"info\", msg, extra); }\n warn(msg: string, extra?: Record<string, unknown>) { this.write(\"warn\", msg, extra); }\n error(msg: string, extra?: Record<string, unknown>) { this.write(\"error\", msg, extra); }\n}\n\nexport const log = new Logger();\n\n/** API key 脱敏:前 4 后 4,中间打码。 */\nexport function redactApiKey(key: string | undefined): string {\n if (!key) return \"<unset>\";\n if (key.length <= 12) return \"***\";\n return `${key.slice(0, 4)}...${key.slice(-4)}`;\n}\n","/**\n * 全局共享类型。其它模块按需 re-export 子集。\n * Why 集中:避免类型循环依赖。\n */\n\n// ---------- 消息(与 LLM 交互的最小单元)----------\n\nexport type MessageRole = \"system\" | \"user\" | \"assistant\" | \"tool\";\n\nexport interface TextPart {\n type: \"text\";\n text: string;\n}\n\nexport interface ToolUsePart {\n type: \"tool_use\";\n id: string;\n name: string;\n args: unknown;\n}\n\nexport interface ToolResultPart {\n type: \"tool_result\";\n toolUseId: string;\n content: string;\n isError?: boolean;\n}\n\nexport type ContentPart = TextPart | ToolUsePart | ToolResultPart;\n\nexport interface SystemMessage {\n role: \"system\";\n content: string;\n}\n\nexport interface UserMessage {\n role: \"user\";\n content: string | ContentPart[];\n}\n\nexport interface AssistantMessage {\n role: \"assistant\";\n content: ContentPart[];\n}\n\nexport interface ToolMessage {\n role: \"tool\";\n toolUseId: string;\n content: string;\n isError?: boolean;\n /** Unified diff for UI display only (Write/Edit). Not sent to LLM. */\n diff?: string;\n /** UI-only one-line summary; if absent, UI falls back to content first line. */\n summary?: string;\n /** UI-only status dot color: success(green) / error(red) / warn(yellow). Default derived from isError. */\n kind?: \"success\" | \"error\" | \"warn\";\n /** 产生该结果的工具名;UI 据此做工具专属渲染(如 TodoWrite 隐藏结果行)。 */\n toolName?: string;\n}\n\nexport type Message = SystemMessage | UserMessage | AssistantMessage | ToolMessage;\n\n// ---------- LLM 工具定义(暴露给模型)----------\n\nexport interface ToolDefinition {\n name: string;\n description: string;\n parameters: Record<string, unknown>; // JSON Schema\n}\n\n// ---------- Token 用量 ----------\n\nexport interface TokenUsage {\n inputTokens: number;\n outputTokens: number;\n totalTokens: number;\n}\n\nexport type FinishReason = \"stop\" | \"tool_calls\" | \"length\" | \"content_filter\" | \"error\" | \"unknown\";\n\n// ---------- 错误 ----------\n\nexport class MuseError extends Error {\n constructor(message: string, public readonly code?: string, public readonly cause?: unknown) {\n super(message);\n this.name = \"MuseError\";\n }\n}\n\nexport class ToolError extends MuseError {\n constructor(message: string, public readonly toolName: string, cause?: unknown) {\n super(message, \"TOOL_ERROR\", cause);\n this.name = \"ToolError\";\n }\n}\n\nexport class PermissionDeniedError extends MuseError {\n constructor(public readonly toolName: string, public readonly reason: string) {\n super(`Permission denied for ${toolName}: ${reason}`, \"PERMISSION_DENIED\");\n this.name = \"PermissionDeniedError\";\n }\n}\n","/**\n * LLMClient 工厂:根据配置创建对应 provider 的客户端。\n *\n * 当前只实现 openai-compatible 协议族(覆盖 95% 国产模型 + OpenAI 本身)。\n * Anthropic 走自己的协议,留待 v0.3 加。\n */\n\nimport { createPresetClient, PRESETS, OpenAICompatibleClient } from \"./providers/index.js\";\nimport type { LLMClient, ModelCapabilities, ProviderConfig } from \"./types.js\";\nimport { MuseError } from \"../types/index.js\";\nimport type { ModelEntry } from \"../config/models.js\";\n\nexport interface CreateClientOpts {\n provider: string;\n model: string;\n providers: Record<string, ProviderConfig>;\n}\n\n/**\n * 当前 active model 的 apiKey 注入到此进程 env 字段下。\n *\n * 业务代码(LLM client)只看到 env name,不直接持有 key 副本。\n * /models 切换或启动加载时由 setActiveModelEnv() 写入;从这里读出来给 client。\n */\nexport const ACTIVE_API_KEY_ENV = \"MUSE_ACTIVE_API_KEY\";\n\n/** 把 entry 的 apiKey 注入 process.env,供 createLLMClientFromModelEntry 读取。 */\nexport function setActiveModelEnv(entry: ModelEntry): void {\n if (entry.apiKey) {\n process.env[ACTIVE_API_KEY_ENV] = entry.apiKey;\n } else {\n delete process.env[ACTIVE_API_KEY_ENV];\n }\n}\n\n/**\n * 从用户在 models.local.json 里定义的 ModelEntry 构造 LLMClient。\n *\n * apiKey 不直接传值——而是从 process.env[ACTIVE_API_KEY_ENV] 读,调用前必须先\n * setActiveModelEnv(entry) 写入。这样业务代码只看到 env name,不直接持有 key。\n *\n * vendor 字段仅用于显示(providerName 显示在 banner / /status)。\n * 当前所有 entry 走 openai-compatible 协议;未来引入其他协议时按 entry.protocol 分流。\n */\nexport function createLLMClientFromModelEntry(entry: ModelEntry): LLMClient {\n const apiKey = process.env[ACTIVE_API_KEY_ENV] ?? \"\";\n if (!apiKey && !entry.baseUrl.includes(\"localhost\")) {\n throw new MuseError(buildMissingKeyMessage(entry), \"MISSING_API_KEY\");\n }\n const capabilities: Partial<ModelCapabilities> = {};\n if (entry.supportsToolCall !== undefined) capabilities.toolCalling = entry.supportsToolCall;\n if (entry.supportsImages !== undefined) capabilities.vision = entry.supportsImages;\n if (entry.contextWindow !== undefined) capabilities.maxContextWindow = entry.contextWindow;\n\n return new OpenAICompatibleClient({\n providerName: entry.vendor ?? \"custom\",\n baseUrl: entry.baseUrl,\n apiKey,\n model: entry.id,\n capabilities,\n });\n}\n\n/**\n * 用户向报错:当 apiKey 是 ${VAR} 占位符但 VAR 没设时,告诉用户具体缺哪个 env var\n * 和三种修复方式;不是占位符 / 直接缺字段时退化为通用提示。\n */\nfunction buildMissingKeyMessage(entry: ModelEntry): string {\n const envVars = ((entry as { _apiKeyEnvVars?: string[] })._apiKeyEnvVars ?? []).filter(\n (v) => !process.env[v],\n );\n const head = `Model \"${entry.id}\" needs an API key but none was found.`;\n\n if (envVars.length > 0) {\n const list = envVars.map((v) => `$${v}`).join(\", \");\n const fixVar = envVars[0];\n return [\n head,\n ``,\n `Cause: ~/.muse/models.local.json sets apiKey to a placeholder referencing ${list},`,\n ` but the shell environment does not have ${envVars.length > 1 ? \"those variables\" : \"that variable\"} set.`,\n ``,\n `Fix (pick one):`,\n ` 1. Replace the \\${${fixVar}} placeholder in ~/.muse/models.local.json with the literal key`,\n ` (recommended — the file is local-only and never enters git).`,\n ` 2. Export the variable in your shell:`,\n ` export ${fixVar}=<your-key>`,\n ].join(\"\\n\");\n }\n\n return [\n head,\n ``,\n `Edit ~/.muse/models.local.json and set \"apiKey\" on the \"${entry.id}\" entry`,\n `(plain text is fine — the file stays local-only).`,\n ].join(\"\\n\");\n}\n\nexport function createLLMClient(opts: CreateClientOpts): LLMClient {\n const { provider, model, providers } = opts;\n const config = providers[provider];\n\n if (!config) {\n throw new MuseError(\n `Provider \"${provider}\" is not configured. Add a \"providers.${provider}\" entry to your settings.json.`,\n \"PROVIDER_NOT_CONFIGURED\",\n );\n }\n\n // 预设 provider(含国产模型)\n if (PRESETS[provider]) {\n if (!config.apiKey && provider !== \"ollama\") {\n throw new MuseError(\n `Provider \"${provider}\" requires apiKey. Set it in settings.json or via the corresponding env var.`,\n \"MISSING_API_KEY\",\n );\n }\n return createPresetClient(provider, config, model);\n }\n\n // 自定义 openai-compatible 端点\n if (config.baseUrl) {\n return new OpenAICompatibleClient({\n providerName: provider,\n baseUrl: config.baseUrl as string,\n apiKey: (config.apiKey as string | undefined) ?? \"\",\n model,\n });\n }\n\n throw new MuseError(\n `Unknown provider \"${provider}\". Either use a preset (${Object.keys(PRESETS).join(\", \")}) or set \"baseUrl\" in providers.${provider}.`,\n \"UNKNOWN_PROVIDER\",\n );\n}\n","/**\n * Session 内 Todo 清单。\n *\n * 仅存活于单次 muse 进程内,不入 JSONL 持久化(任务清单是 ephemeral 调度状态,\n * 不是对话内容;下次进程恢复 session 时 LLM 应基于历史重建清单)。\n *\n * 工具 TodoWrite 通过 ToolContext.todos 写入;buildSystemPrompt 读出注入下一轮 LLM 的视野。\n */\n\nexport type TodoStatus = \"pending\" | \"in_progress\" | \"completed\";\n\nexport interface Todo {\n content: string;\n status: TodoStatus;\n /** 进行中状态的现在分词式描述,UI 可用作 spinner 文案。 */\n activeForm?: string;\n}\n\nexport class TodoStore {\n private items: Todo[] = [];\n\n list(): Todo[] {\n return this.items.slice();\n }\n\n set(items: Todo[]): void {\n this.items = items.slice();\n }\n\n clear(): void {\n this.items = [];\n }\n\n /** 把当前清单格式化为 system prompt 段落;无任务时返回空串。 */\n toPromptSection(): string {\n if (this.items.length === 0) return \"\";\n const lines = this.items.map((t, i) => {\n const marker = t.status === \"completed\" ? \"[x]\" : t.status === \"in_progress\" ? \"[~]\" : \"[ ]\";\n return ` ${i + 1}. ${marker} ${t.content}`;\n });\n return `# Current todos\\n${lines.join(\"\\n\")}\\n\\nUpdate via TodoWrite as you make progress. Keep exactly one item in_progress at a time.`;\n }\n}\n","/**\n * Agent loop:单循环 ReAct。\n *\n * loop:\n * llm.stream(messages, tools)\n * → emit text → 累计 assistant 消息\n * → 收到 tool_call → 累计\n * → finish\n * if no tool_calls: break\n * for each tool_call:\n * check permission → execute → push tool result\n */\n\nimport type { LLMClient, LLMEvent } from \"../llm/types.js\";\nimport type { Message, AssistantMessage, ContentPart, ToolUsePart, TokenUsage } from \"../types/index.js\";\nimport type { ToolRegistry } from \"../tools/registry.js\";\nimport type { ToolContext } from \"../tools/types.js\";\nimport type { PermissionGate, Decision, PermissionDecision } from \"../permission/index.js\";\nimport type { Session } from \"../session/jsonl.js\";\nimport { TodoStore } from \"./todos.js\";\nimport { log } from \"../log/index.js\";\n\nexport interface AgentEvents {\n onText?: (delta: string) => void;\n onToolCallStart?: (id: string, name: string) => void;\n onToolCallArgs?: (id: string, args: unknown) => void;\n onToolResult?: (id: string, name: string, content: string, isError: boolean, summary?: string) => void;\n onPermissionRequest?: (toolName: string, args: unknown, summary: string) => Promise<PermissionDecision>;\n /** AskUserQuestion 工具调用时触发;resolve 把整批答案数组回填给工具。 */\n onAskQuestions?: (\n questions: import(\"../tools/builtin/ask-user-question.js\").AskQuestion[],\n ) => Promise<import(\"../tools/builtin/ask-user-question.js\").AskQuestionResponse[]>;\n onUsage?: (usage: TokenUsage) => void;\n onError?: (error: Error) => void;\n /**\n * 一段 assistant 流结束、assistantMessage 已 push 进 messages,但工具还没开始执行时触发。\n * 用于 UI 立刻把这一批 tool_use calls 显示出来——避免\"流完 → 第一个 result 到达\"\n * 之间用户面对空屏。turn 直接结束(无 tool calls)的场景不会触发,走 onTurnEnd。\n */\n onAssistantTurn?: () => void;\n onTurnEnd?: () => void;\n}\n\nexport interface AgentContext {\n llm: LLMClient;\n tools: ToolRegistry;\n permissions: PermissionGate;\n session: Session;\n cwd: string;\n systemPrompt: string;\n abortSignal?: AbortSignal;\n events?: AgentEvents;\n}\n\nexport class Agent {\n private messages: Message[] = [];\n readonly todos = new TodoStore();\n\n constructor(private ctx: AgentContext) {}\n\n getMessages(): Message[] {\n return this.messages;\n }\n\n setMessages(msgs: Message[]): void {\n this.messages = msgs;\n }\n\n /** 执行一次完整的\"用户输入 → 助手响应(含工具循环) → 等待下一轮输入\"。 */\n async runTurn(userInput: string): Promise<void> {\n const userMessage: Message = { role: \"user\", content: userInput };\n this.messages.push(userMessage);\n await this.ctx.session.append({ type: \"message\", time: new Date().toISOString(), message: userMessage });\n\n // 内部循环:工具调用可能多轮\n while (true) {\n const mode = this.ctx.permissions.getMode();\n const tools = this.ctx.tools.toLLMDefinitions(\n mode === \"plan\" ? (t) => t.permission === \"read\" : undefined,\n );\n // 每轮把当前 todos 注入 system prompt 末尾,让 LLM 看到自己写的清单\n const todoSection = this.todos.toPromptSection();\n const systemPrompt = todoSection\n ? `${this.ctx.systemPrompt}\\n\\n${todoSection}`\n : this.ctx.systemPrompt;\n const stream = this.ctx.llm.stream({\n messages: this.messages,\n tools,\n systemPrompt,\n abortSignal: this.ctx.abortSignal,\n });\n\n const assistantParts: ContentPart[] = [];\n const toolCallsToRun: ToolUsePart[] = [];\n let lastError: Error | undefined;\n\n for await (const ev of stream) {\n this.handleEvent(ev, assistantParts, toolCallsToRun, (e) => {\n lastError = e;\n });\n if (lastError) break;\n }\n\n if (lastError) {\n this.ctx.events?.onError?.(lastError);\n log.error(\"agent stream error\", { msg: lastError.message });\n return;\n }\n\n // 把 assistant 消息加入历史\n const assistantMessage: AssistantMessage = { role: \"assistant\", content: assistantParts };\n this.messages.push(assistantMessage);\n await this.ctx.session.append({ type: \"message\", time: new Date().toISOString(), message: assistantMessage });\n\n if (toolCallsToRun.length === 0) {\n this.ctx.events?.onTurnEnd?.();\n return;\n }\n\n // 流刚结束、tool 还没跑——给 UI 一个钩子立刻展示这一批 calls\n this.ctx.events?.onAssistantTurn?.();\n\n // 执行工具调用\n for (const call of toolCallsToRun) {\n await this.runToolCall(call);\n }\n }\n }\n\n private handleEvent(\n ev: LLMEvent,\n assistantParts: ContentPart[],\n toolCallsToRun: ToolUsePart[],\n onError: (e: Error) => void,\n ): void {\n switch (ev.type) {\n case \"text\":\n // 合并到最后一个 text part 或新增\n {\n const last = assistantParts[assistantParts.length - 1];\n if (last && last.type === \"text\") {\n last.text += ev.delta;\n } else {\n assistantParts.push({ type: \"text\", text: ev.delta });\n }\n }\n this.ctx.events?.onText?.(ev.delta);\n break;\n\n case \"tool_call_start\":\n this.ctx.events?.onToolCallStart?.(ev.id, ev.name);\n break;\n\n case \"tool_call_complete\": {\n const callPart: ToolUsePart = { type: \"tool_use\", id: ev.id, name: ev.name, args: ev.args };\n assistantParts.push(callPart);\n toolCallsToRun.push(callPart);\n this.ctx.events?.onToolCallArgs?.(ev.id, ev.args);\n break;\n }\n\n case \"finish\":\n if (ev.usage) {\n this.ctx.events?.onUsage?.(ev.usage);\n this.ctx.session.append({\n type: \"usage\",\n time: new Date().toISOString(),\n usage: ev.usage,\n provider: this.ctx.llm.providerName,\n model: this.ctx.llm.model,\n });\n }\n break;\n\n case \"error\":\n onError(ev.error);\n break;\n }\n }\n\n private async runToolCall(call: ToolUsePart): Promise<void> {\n const tool = this.ctx.tools.get(call.name);\n if (!tool) {\n const result = `Tool \"${call.name}\" is not available.`;\n this.recordToolResult(call.id, call.name, result, true);\n return;\n }\n\n const summary = tool.summarize?.(call.args) ?? `${call.name}(...)`;\n const decision: Decision = this.ctx.permissions.decide({\n toolName: call.name,\n args: call.args,\n permission: tool.permission,\n });\n\n let approved = decision === \"allow\";\n if (decision === \"deny\") {\n const reason =\n this.ctx.permissions.getMode() === \"plan\"\n ? `Denied: you are in plan mode. Only read-only tools are available. Propose changes instead of executing.`\n : `Denied by policy: ${call.name}.`;\n this.recordToolResult(call.id, call.name, reason, true);\n return;\n }\n if (decision === \"ask\") {\n const userDecision =\n (await this.ctx.events?.onPermissionRequest?.(call.name, call.args, summary)) ?? \"no\";\n if (userDecision === \"no\") {\n this.recordToolResult(call.id, call.name, `User rejected ${call.name}.`, true);\n return;\n }\n if (userDecision === \"session_allow\") {\n this.ctx.permissions.allowForSession(call.name);\n }\n approved = true;\n }\n\n const toolCtx: ToolContext = {\n cwd: this.ctx.cwd,\n abortSignal: this.ctx.abortSignal,\n askPermission: async () => true, // 已在外层处理\n todos: this.todos,\n askQuestions: this.ctx.events?.onAskQuestions\n ? (qs) => this.ctx.events!.onAskQuestions!(qs)\n : undefined,\n };\n\n const result = await this.ctx.tools.execute(call.name, call.args, toolCtx);\n this.recordToolResult(call.id, call.name, result.content, result.isError ?? false, result.summary, result.diff, result.kind);\n }\n\n private recordToolResult(\n id: string,\n name: string,\n content: string,\n isError: boolean,\n summary?: string,\n diff?: string,\n kind?: \"success\" | \"error\" | \"warn\",\n ): void {\n const toolMsg: Message = {\n role: \"tool\",\n toolUseId: id,\n content,\n isError,\n toolName: name,\n ...(diff ? { diff } : {}),\n ...(summary ? { summary } : {}),\n ...(kind ? { kind } : {}),\n };\n this.messages.push(toolMsg);\n this.ctx.session.append({ type: \"message\", time: new Date().toISOString(), message: toolMsg });\n this.ctx.events?.onToolResult?.(id, name, content, isError, summary);\n }\n}\n","/**\n * System prompt 构造。\n *\n * 简短、命令式:把可用工具与运行时约束直接摆出来给 LLM。\n * 中文输出由 ui.lang 控制;英文为默认。\n */\n\nimport { homedir } from \"node:os\";\n\nexport interface SystemPromptOpts {\n cwd: string;\n model: string;\n provider: string;\n lang?: \"en\" | \"zh-CN\";\n toolNames: string[];\n /** MEMORY.md index 内容(loadMemoryIndex 加载后传入);空串视为无 memory。 */\n memoryIndex?: string;\n}\n\nexport function buildSystemPrompt(opts: SystemPromptOpts): string {\n const { cwd, model, provider, lang, toolNames, memoryIndex } = opts;\n const home = homedir();\n const displayCwd = cwd.startsWith(home) ? cwd.replace(home, \"~\") : cwd;\n\n const sections: string[] = [];\n\n sections.push(`You are Muse, a CLI coding assistant. You are running on the user's local machine via a terminal interface.`);\n\n sections.push(\n `# Environment\\n` +\n `- Working directory: ${displayCwd}\\n` +\n `- LLM backend: ${provider} (${model})\\n` +\n `- Date: ${new Date().toISOString().slice(0, 10)}`,\n );\n\n sections.push(\n `# Available tools\\n` +\n toolNames.map((n) => `- ${n}`).join(\"\\n\") +\n `\\n\\nPrefer the dedicated tool over Bash when one fits (Read for file reading, Edit for partial updates, Write for new files / full rewrites, Grep for content search, Glob for file lookup).`,\n );\n\n sections.push(\n `# Behavior\\n` +\n `- Be concise. State results, not your thinking. Don't narrate every step.\\n` +\n `- Before editing a file you have not seen, Read it first.\\n` +\n `- For Write/Edit/Bash the user may need to approve — proceed normally; the host will gate dangerous calls.\\n` +\n `- If a command may be destructive (rm -rf, force push, drop table, etc.), warn first and let the user run it manually.\\n` +\n `- When the user asks a question that does not need tools, just answer.`,\n );\n\n if (toolNames.includes(\"TodoWrite\")) {\n sections.push(\n `# Task management\\n` +\n `- For non-trivial, multi-step work, use TodoWrite to plan and track progress.\\n` +\n `- Keep exactly one task in_progress; mark a task completed immediately when done.\\n` +\n `- Skip it for trivial single-step requests.`,\n );\n }\n\n if (lang === \"zh-CN\") {\n sections.push(`# Output language\\nReply in Chinese (简体中文) unless the user writes in English.`);\n }\n\n if (memoryIndex && memoryIndex.trim()) {\n sections.push(\n `# Memory (long-term)\\n` +\n `Below is MEMORY.md — your index of persistent facts about the user, project, and prior feedback. ` +\n `Each line points at a file you can MemoryRead. Use MemoryWrite to record new durable knowledge ` +\n `(user role/preferences, validated decisions, project facts, external references). Do NOT save things ` +\n `derivable from the repo or git history.\\n\\n` +\n memoryIndex,\n );\n }\n\n return sections.join(\"\\n\\n\");\n}\n","/**\n * 长期 Memory:跨 session 持久化的小段知识。\n *\n * 路径约定:~/.muse/projects/<projectHash>/memory/\n * - MEMORY.md index(每行 `- [Title](file.md) — one-line hook`)\n * - <name>.md 具体记忆,带 frontmatter\n *\n * MEMORY.md 前 200 行自动注入 system prompt,让 LLM 每轮都看到。\n *\n * 类型:user / feedback / project / reference(对齐 Claude Code)。\n */\n\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { createHash } from \"node:crypto\";\n\nexport type MemoryType = \"user\" | \"feedback\" | \"project\" | \"reference\";\n\nfunction projectHash(cwd: string): string {\n return createHash(\"sha256\").update(cwd).digest(\"hex\").slice(0, 16);\n}\n\nexport function memoryDir(cwd: string): string {\n return join(homedir(), \".muse\", \"projects\", projectHash(cwd), \"memory\");\n}\n\nexport function memoryIndexPath(cwd: string): string {\n return join(memoryDir(cwd), \"MEMORY.md\");\n}\n\nexport function memoryFilePath(cwd: string, name: string): string {\n return join(memoryDir(cwd), `${name}.md`);\n}\n\n/** 加载 MEMORY.md 前 N 行供 system prompt 注入。 */\nexport async function loadMemoryIndex(cwd: string, maxLines = 200): Promise<string> {\n const path = memoryIndexPath(cwd);\n if (!existsSync(path)) return \"\";\n try {\n const raw = await readFile(path, \"utf-8\");\n const lines = raw.split(\"\\n\");\n if (lines.length <= maxLines) return raw.trim();\n return lines.slice(0, maxLines).join(\"\\n\").trim() + `\\n... [truncated; ${lines.length - maxLines} more lines]`;\n } catch {\n return \"\";\n }\n}\n\nexport async function readMemoryFile(cwd: string, name: string): Promise<string> {\n const path = memoryFilePath(cwd, name);\n if (!existsSync(path)) {\n throw new Error(`Memory \"${name}\" does not exist at ${path}.`);\n }\n return readFile(path, \"utf-8\");\n}\n\nexport interface WriteMemoryOpts {\n name: string;\n description: string;\n type: MemoryType;\n body: string;\n}\n\n/**\n * 写一条 memory + 更新 MEMORY.md 索引。\n * - 若文件已存在,整体覆盖\n * - MEMORY.md 行匹配 `- [name](name.md) ` 前缀;存在则替换该行,否则追加\n */\nexport async function writeMemory(cwd: string, opts: WriteMemoryOpts): Promise<{ filePath: string; indexUpdated: boolean }> {\n const dir = memoryDir(cwd);\n await mkdir(dir, { recursive: true });\n\n const filePath = memoryFilePath(cwd, opts.name);\n const frontmatter = [\n \"---\",\n `name: ${opts.name}`,\n `description: ${opts.description.replace(/\\n/g, \" \").trim()}`,\n `metadata:`,\n ` type: ${opts.type}`,\n \"---\",\n ].join(\"\\n\");\n const content = `${frontmatter}\\n\\n${opts.body.trim()}\\n`;\n await writeFile(filePath, content, \"utf-8\");\n\n // 索引更新\n const indexPath = memoryIndexPath(cwd);\n let index = \"\";\n if (existsSync(indexPath)) index = await readFile(indexPath, \"utf-8\");\n const lines = index ? index.split(\"\\n\") : [];\n const linePrefix = `- [${opts.name}](${opts.name}.md)`;\n const newLine = `${linePrefix} — ${opts.description.replace(/\\n/g, \" \").trim()}`;\n const existing = lines.findIndex((l) => l.startsWith(linePrefix));\n let indexUpdated = false;\n if (existing >= 0) {\n if (lines[existing] !== newLine) {\n lines[existing] = newLine;\n indexUpdated = true;\n }\n } else {\n lines.push(newLine);\n indexUpdated = true;\n }\n if (indexUpdated) {\n const out = lines.join(\"\\n\").replace(/\\n{3,}/g, \"\\n\\n\").trimEnd() + \"\\n\";\n await writeFile(indexPath, out, \"utf-8\");\n }\n\n return { filePath, indexUpdated };\n}\n","/**\n * 配置加载:\n * 1. 内置默认值\n * 2. ~/.muse/settings.json\n * 3. <cwd>/.muse/settings.json\n * 4. <cwd>/.muse/settings.local.json\n * 5. 环境变量 (MUSE_*)\n * 6. CLI flags (在 cli.tsx 里覆盖)\n *\n * ${ENV_VAR} 占位符在加载后展开。\n */\n\nimport { readFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport type { z } from \"zod\";\nimport { SettingsSchema, type Settings } from \"./types.js\";\nimport { expandEnvVars } from \"./_env.js\";\nimport { log } from \"../log/index.js\";\n\nfunction formatZodIssues(issues: z.ZodIssue[]): string {\n return issues\n .map((i) => `${i.path.join(\".\") || \"<root>\"}: ${i.message}`)\n .join(\"; \");\n}\n\nconst DEFAULTS: Settings = {\n llm: {\n provider: \"deepseek\",\n model: \"deepseek-chat\",\n },\n providers: {\n deepseek: { apiKey: \"${DEEPSEEK_API_KEY}\" },\n openai: { apiKey: \"${OPENAI_API_KEY}\" },\n qwen: { apiKey: \"${DASHSCOPE_API_KEY}\" },\n moonshot: { apiKey: \"${MOONSHOT_API_KEY}\" },\n zhipu: { apiKey: \"${ZHIPU_API_KEY}\" },\n openrouter: { apiKey: \"${OPENROUTER_API_KEY}\" },\n ollama: { baseUrl: \"http://localhost:11434/v1\" },\n },\n permissions: {\n allow: [\"Read\", \"Grep\", \"Glob\", \"TodoWrite\"],\n ask: [\"Write\", \"Edit\", \"Bash\"],\n deny: [],\n defaultMode: \"ask\",\n },\n ui: {\n showBanner: true,\n lang: \"en\",\n },\n};\n\nasync function readJsonIfExists(path: string): Promise<unknown | undefined> {\n if (!existsSync(path)) return undefined;\n try {\n const raw = await readFile(path, \"utf-8\");\n return JSON.parse(raw);\n } catch (err) {\n log.warn(`Failed to parse settings at ${path}: ${err instanceof Error ? err.message : String(err)}`);\n return undefined;\n }\n}\n\n/** 深合并:高优先级覆盖低优先级。对象递归,数组/标量覆盖。 */\nfunction deepMerge<T>(low: T, high: Partial<T>): T {\n if (high == null) return low;\n if (typeof low !== \"object\" || typeof high !== \"object\" || low === null || high === null) {\n return high as T;\n }\n if (Array.isArray(high)) return high as unknown as T;\n const result: Record<string, unknown> = { ...(low as Record<string, unknown>) };\n for (const [k, v] of Object.entries(high)) {\n const existing = (low as Record<string, unknown>)[k];\n if (\n v !== null &&\n typeof v === \"object\" &&\n !Array.isArray(v) &&\n existing !== null &&\n typeof existing === \"object\" &&\n !Array.isArray(existing)\n ) {\n result[k] = deepMerge(existing, v as Record<string, unknown>);\n } else {\n result[k] = v;\n }\n }\n return result as T;\n}\n\nexport interface LoadedSettings {\n settings: Settings;\n sources: string[];\n}\n\nexport async function loadSettings(cwd: string = process.cwd()): Promise<LoadedSettings> {\n const sources: string[] = [\"<defaults>\"];\n let merged: Settings = DEFAULTS;\n\n const candidates = [\n join(homedir(), \".muse\", \"settings.json\"),\n join(cwd, \".muse\", \"settings.json\"),\n join(cwd, \".muse\", \"settings.local.json\"),\n ];\n\n for (const path of candidates) {\n const raw = await readJsonIfExists(path);\n if (raw != null) {\n const parsed = SettingsSchema.safeParse(raw);\n if (parsed.success) {\n merged = deepMerge(merged, parsed.data);\n sources.push(path);\n } else {\n log.warn(`Invalid settings at ${path}: ${formatZodIssues(parsed.error.issues)}`);\n }\n }\n }\n\n // Env overrides for the active LLM\n if (process.env.MUSE_PROVIDER && merged.llm) {\n merged = { ...merged, llm: { ...merged.llm, provider: process.env.MUSE_PROVIDER } };\n sources.push(\"env:MUSE_PROVIDER\");\n }\n if (process.env.MUSE_MODEL && merged.llm) {\n merged = { ...merged, llm: { ...merged.llm, model: process.env.MUSE_MODEL } };\n sources.push(\"env:MUSE_MODEL\");\n }\n\n // 展开 ${ENV_VAR} 占位符\n merged = expandEnvVars(merged) as Settings;\n\n return { settings: merged, sources };\n}\n\nexport { DEFAULTS };\nexport { resolve as resolvePath };\n","/**\n * 配置 schema。对应 ~/.muse/settings.json + .muse/settings.json 的内容。\n */\n\nimport { z } from \"zod\";\n\nexport const ProviderConfigSchema = z.object({\n apiKey: z.string().optional(),\n baseUrl: z.string().optional(),\n extraHeaders: z.record(z.string()).optional(),\n}).passthrough();\n\n// 新设计:model id 由 ~/.muse/models.local.json 提供,settings.json 只保留 active 选择。\n// provider 字段仅用于\"无 models.local.json 时的 fallback 路径\"(设计文档 §8 兼容层)。\n// 因此两者都可选——/models 切换只写 model,不写 provider。\nexport const LLMConfigSchema = z.object({\n provider: z.string().optional().describe(\"Fallback provider preset (only used when no models.local.json entry matches).\"),\n model: z.string().optional().describe(\"Active model id; should match an id in models.local.json.\"),\n temperature: z.number().min(0).max(2).optional(),\n maxTokens: z.number().int().positive().optional(),\n});\n\nexport const PermissionsSchema = z.object({\n allow: z.array(z.string()).optional(),\n ask: z.array(z.string()).optional(),\n deny: z.array(z.string()).optional(),\n defaultMode: z.enum([\"strict\", \"relaxed\", \"ask\"]).optional(),\n});\n\nexport const UISchema = z.object({\n theme: z.enum([\"dark\", \"light\"]).optional(),\n lang: z.enum([\"en\", \"zh-CN\"]).optional(),\n showBanner: z.boolean().optional(),\n});\n\nexport const SettingsSchema = z.object({\n llm: LLMConfigSchema.optional(),\n providers: z.record(ProviderConfigSchema).optional(),\n permissions: PermissionsSchema.optional(),\n ui: UISchema.optional(),\n mcpServers: z.record(z.unknown()).optional(),\n skills: z.object({\n enabled: z.boolean().optional(),\n disabled: z.array(z.string()).optional(),\n }).optional(),\n}).passthrough();\n\nexport type Settings = z.infer<typeof SettingsSchema>;\nexport type LLMConfig = z.infer<typeof LLMConfigSchema>;\nexport type ProviderConfig = z.infer<typeof ProviderConfigSchema>;\nexport type Permissions = z.infer<typeof PermissionsSchema>;\n","/**\n * ${ENV_VAR} 占位符递归展开。\n *\n * settings.json / models.local.json 都共用这套机制,避免把明文凭证落到可入 git 的文件。\n * 未定义的 env var → 空字符串(不抛错,让上层校验\"必填字段是否非空\"决定行为)。\n */\n\nconst ENV_PATTERN = /\\$\\{([A-Z_][A-Z0-9_]*)\\}/g;\n\nexport function expandEnvVars(value: unknown): unknown {\n if (typeof value === \"string\") {\n return value.replace(ENV_PATTERN, (_match, name) => process.env[name] ?? \"\");\n }\n if (Array.isArray(value)) {\n return value.map(expandEnvVars);\n }\n if (value && typeof value === \"object\") {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n result[k] = expandEnvVars(v);\n }\n return result;\n }\n return value;\n}\n","/**\n * Models registry:用户级模型库。\n *\n * 位置:~/.muse/models.local.json (单文件,本机本地;从不入 git)\n *\n * 设计:\n * - models 数组的 id 是**用户起的名字**,不在代码里硬编码;availableModels 决定 /models\n * selector 里显示哪些\n * - apiKey 字段可以直接写明文(推荐:文件就在本机本地),也支持 ${ENV_VAR} 占位符\n * - baseUrl 是基址,SDK 自己拼 /chat/completions;用户填全 endpoint 时自动剥后缀\n * - 不存在文件 → 返回 undefined(调用方回退到 settings.json llm 配置)\n *\n * Why `.local.json` 单文件而非 `models.json`:\n * muse 0.1.x 早期是双文件(models.json git-tracked + models.local.json 本地兜底),\n * 但实际使用中并没有 \"git-track 一份不含 key 的模板\" 的场景——用户的模型清单本就\n * 是私人物件。为避免新用户被两份文件混淆,合并为单文件,沿用 `.local.json`\n * 后缀作为 \"本机本地,绝不入 git\" 的视觉提示。\n */\n\nimport { readFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { z } from \"zod\";\nimport { expandEnvVars } from \"./_env.js\";\nimport { log } from \"../log/index.js\";\n\n/**\n * 内部规整后的 ModelEntry 类型。schema 解析后的对象会通过 normalize 步骤\n * 把 url/baseUrl 合一,最终 baseUrl 保证非空。业务(client / selector)只看本类型。\n */\nexport interface ModelEntry {\n id: string;\n name?: string;\n vendor?: string;\n apiKey?: string;\n baseUrl: string;\n supportsToolCall?: boolean;\n supportsImages?: boolean;\n contextWindow?: number;\n [k: string]: unknown;\n}\n\n/**\n * 输入校验:baseUrl / url 任一非空即可。\n * 用户实际写的 models.local.json 多用 `url`(OpenAI 兼容协议惯例命名),\n * 我们接受两种别名,normalize 阶段归一。\n */\nexport const ModelEntryInputSchema = z\n .object({\n id: z.string().min(1),\n name: z.string().optional(),\n vendor: z.string().optional(),\n apiKey: z.string().optional(),\n baseUrl: z.string().optional(),\n url: z.string().optional(),\n supportsToolCall: z.boolean().optional(),\n supportsImages: z.boolean().optional(),\n contextWindow: z.number().int().positive().optional(),\n })\n .passthrough()\n .refine((d) => Boolean(d.baseUrl || d.url), {\n message: \"Either 'baseUrl' or 'url' is required\",\n path: [\"baseUrl\"],\n });\n\nexport type ModelEntryInput = z.infer<typeof ModelEntryInputSchema>;\n\nexport const ModelsRegistryInputSchema = z\n .object({\n models: z.array(ModelEntryInputSchema),\n /** 不填 = 全部 models 都进 selector;填了就是 selector 子集(按顺序)。 */\n availableModels: z.array(z.string()).optional(),\n })\n .passthrough();\n\nexport type ModelsRegistryInput = z.infer<typeof ModelsRegistryInputSchema>;\n\n/** Normalize 后的 registry:models[*].baseUrl 保证非空。 */\nexport interface ModelsRegistry {\n models: ModelEntry[];\n availableModels?: string[];\n [k: string]: unknown;\n}\n\nexport interface LoadError {\n path: string;\n message: string;\n}\n\nexport interface LoadedModels {\n registry: ModelsRegistry | undefined;\n sources: string[];\n errors: LoadError[];\n}\n\nexport const MODELS_PATH = (): string => join(homedir(), \".muse\", \"models.local.json\");\n\nexport async function loadModelsRegistry(): Promise<LoadedModels> {\n const sources: string[] = [];\n const errors: LoadError[] = [];\n const path = MODELS_PATH();\n\n if (!existsSync(path)) {\n return { registry: undefined, sources, errors };\n }\n\n let raw: unknown;\n try {\n raw = JSON.parse(await readFile(path, \"utf-8\"));\n } catch (err) {\n const msg = `JSON parse error: ${err instanceof Error ? err.message : String(err)}`;\n log.warn(`Failed to parse ${path}: ${msg}`);\n errors.push({ path, message: msg });\n return { registry: undefined, sources, errors };\n }\n\n const parsed = ModelsRegistryInputSchema.safeParse(raw);\n if (!parsed.success) {\n const msg = formatZodIssues(parsed.error.issues);\n log.warn(`Invalid models registry at ${path}: ${msg}`);\n errors.push({ path, message: msg });\n return { registry: undefined, sources, errors };\n }\n\n const normalized: ModelsRegistry = {\n ...parsed.data,\n models: parsed.data.models.map(normalizeModelEntry),\n };\n sources.push(path);\n const expanded = expandEnvVars(normalized) as ModelsRegistry;\n return { registry: expanded, sources, errors };\n}\n\nfunction formatZodIssues(issues: z.ZodIssue[]): string {\n return issues\n .map((i) => `${i.path.join(\".\") || \"<root>\"}: ${i.message}`)\n .join(\"; \");\n}\n\n/**\n * 输入归一:url ↔ baseUrl 二选一;剥 trailing `/` 与 `/chat/completions`。\n * 经过校验后 baseUrl/url 至少一个非空(zod refine 保证),输出 baseUrl 必填。\n *\n * 同时记录 apiKey 字段里出现的 ${ENV_VAR} 占位符名(_apiKeyEnvVars),让 expand 后\n * apiKey 变空时 client.ts 能给出\"缺哪个 env var\"的精确提示。\n */\nfunction normalizeModelEntry(entry: ModelEntryInput): ModelEntry {\n let baseUrl = (entry.baseUrl ?? entry.url ?? \"\").replace(/\\/+$/, \"\");\n if (baseUrl.endsWith(\"/chat/completions\")) {\n baseUrl = baseUrl.slice(0, -\"/chat/completions\".length);\n }\n const { url: _url, ...rest } = entry;\n const apiKeyEnvVars = entry.apiKey ? extractEnvVars(entry.apiKey) : [];\n return {\n ...rest,\n baseUrl,\n ...(apiKeyEnvVars.length > 0 ? { _apiKeyEnvVars: apiKeyEnvVars } : {}),\n };\n}\n\nconst ENV_PLACEHOLDER = /\\$\\{([A-Z_][A-Z0-9_]*)\\}/g;\nfunction extractEnvVars(s: string): string[] {\n const out: string[] = [];\n let m: RegExpExecArray | null;\n ENV_PLACEHOLDER.lastIndex = 0;\n while ((m = ENV_PLACEHOLDER.exec(s)) !== null) out.push(m[1]);\n return out;\n}\n\n// ---------- selector / lookup helpers ----------\n\nexport function findEntry(registry: ModelsRegistry, modelId: string): ModelEntry | undefined {\n return registry.models.find((m) => m.id === modelId);\n}\n\n/** /models selector 里实际显示的条目(availableModels 缺省 = 全部 id)。 */\nexport function visibleEntries(registry: ModelsRegistry): ModelEntry[] {\n if (!registry.availableModels || registry.availableModels.length === 0) {\n return registry.models;\n }\n const result: ModelEntry[] = [];\n for (const id of registry.availableModels) {\n const e = registry.models.find((m) => m.id === id);\n if (e) result.push(e);\n }\n return result;\n}\n","/**\n * Slash 命令注册表与解析器。\n */\n\nimport type { SlashCommand } from \"./types.js\";\n\nexport class SlashRegistry {\n private byName = new Map<string, SlashCommand>();\n private order: SlashCommand[] = [];\n\n register(cmd: SlashCommand): void {\n if (this.byName.has(cmd.name)) {\n throw new Error(`Duplicate slash command: /${cmd.name}`);\n }\n this.byName.set(cmd.name, cmd);\n this.order.push(cmd);\n for (const a of cmd.aliases ?? []) {\n if (!this.byName.has(a)) this.byName.set(a, cmd);\n }\n }\n\n registerAll(cmds: SlashCommand[]): void {\n for (const c of cmds) this.register(c);\n }\n\n get(name: string): SlashCommand | undefined {\n return this.byName.get(name);\n }\n\n list(): SlashCommand[] {\n return [...this.order];\n }\n}\n\nexport interface ParsedSlash {\n name: string;\n args: string;\n}\n\n/** \"/foo bar baz\" → { name: \"foo\", args: \"bar baz\" };非 slash 返回 null。 */\nexport function parseSlash(input: string): ParsedSlash | null {\n const trimmed = input.trim();\n if (!trimmed.startsWith(\"/\") || trimmed.length < 2) return null;\n const body = trimmed.slice(1);\n const space = body.search(/\\s/);\n if (space === -1) return { name: body, args: \"\" };\n return { name: body.slice(0, space), args: body.slice(space + 1).trim() };\n}\n","/**\n * 模型单价表(USD per 1M tokens)。\n *\n * 设计文档:muse-design.md §11.2 Token / 费用统计。\n *\n * 数据来源:各 provider 公开价格页(2026 年初快照)。仅供 /cost 命令展示估算用,\n * 不保证准确性,价格变动用户可在 ~/.muse/settings.json 自定义覆盖(v0.2 起)。\n */\n\nexport interface ModelPricing {\n /** 输入 token 单价(USD per 1M)。 */\n inputPer1M: number;\n /** 输出 token 单价(USD per 1M)。 */\n outputPer1M: number;\n}\n\nconst PRICING: Record<string, Record<string, ModelPricing>> = {\n openai: {\n \"gpt-4o\": { inputPer1M: 2.5, outputPer1M: 10 },\n \"gpt-4o-mini\": { inputPer1M: 0.15, outputPer1M: 0.6 },\n \"gpt-4-turbo\": { inputPer1M: 10, outputPer1M: 30 },\n },\n deepseek: {\n \"deepseek-chat\": { inputPer1M: 0.14, outputPer1M: 0.28 },\n \"deepseek-reasoner\": { inputPer1M: 0.55, outputPer1M: 2.19 },\n },\n qwen: {\n \"qwen-plus\": { inputPer1M: 0.4, outputPer1M: 1.2 },\n \"qwen-max\": { inputPer1M: 2.8, outputPer1M: 8.4 },\n \"qwen-turbo\": { inputPer1M: 0.05, outputPer1M: 0.2 },\n },\n moonshot: {\n \"moonshot-v1-8k\": { inputPer1M: 1.68, outputPer1M: 1.68 },\n \"moonshot-v1-32k\": { inputPer1M: 3.36, outputPer1M: 3.36 },\n \"moonshot-v1-128k\": { inputPer1M: 8.4, outputPer1M: 8.4 },\n },\n zhipu: {\n \"glm-4-flash\": { inputPer1M: 0, outputPer1M: 0 },\n \"glm-4-plus\": { inputPer1M: 7, outputPer1M: 7 },\n },\n ollama: {\n // 本地模型零成本\n },\n};\n\nexport function lookupPricing(provider: string, model: string): ModelPricing | undefined {\n return PRICING[provider]?.[model];\n}\n\nexport function estimateCostUSD(\n provider: string,\n model: string,\n inputTokens: number,\n outputTokens: number,\n): number | undefined {\n const p = lookupPricing(provider, model);\n if (!p) return undefined;\n return (inputTokens / 1_000_000) * p.inputPer1M + (outputTokens / 1_000_000) * p.outputPer1M;\n}\n\n/** 把 USD 金额格式化成人类可读字符串。小于 1 美分用 micro-dollar 显示。 */\nexport function formatUSD(usd: number): string {\n if (usd === 0) return \"$0.00\";\n if (usd < 0.0001) return `<$0.0001`;\n if (usd < 0.01) return `$${usd.toFixed(4)}`;\n return `$${usd.toFixed(4)}`;\n}\n","/**\n * 上下文管理:手动 / 自动压缩对话历史。\n *\n * 设计文档:muse-design.md §5.3 上下文管理。\n *\n * 算法:\n * 1. 找一个安全切割点 cutoff:cutoff 之前是 \"older\",之后是 \"recent\"\n * 2. 安全 = 不破坏 assistant 的 tool_use ↔ 紧随的 tool 消息 配对\n * (在 tool_use 之后但 tool result 之前切,会让 LLM 看到悬挂的 tool_use)\n * 3. older 拼成转录,调 LLM 摘要成一段\n * 4. 摘要包成一条 user message(\"[Previous conversation summary] ...\"),\n * 作为新历史的开头,后接 recent\n *\n * Why user 角色而非 system:\n * - 系统提示 muse 已在 systemPrompt 单独管理;不污染它\n * - 用 user role 让 LLM 自然把它当成\"任务上下文\"继续推理\n */\n\nimport type { LLMClient } from \"../llm/types.js\";\nimport type { Message, AssistantMessage, ContentPart } from \"../types/index.js\";\n\nexport interface CompactOptions {\n llm: LLMClient;\n /** 保留最近 N 条原始消息不压缩。默认 4。 */\n keepRecent?: number;\n abortSignal?: AbortSignal;\n /** LLM 摘要流式过程中的字符进度回调(每个 text-delta 触发,传累计字符数)。 */\n onProgress?: (charsReceived: number) => void;\n}\n\nexport interface CompactResult {\n newMessages: Message[];\n summary: string;\n originalCount: number;\n newCount: number;\n /** 没有可压缩内容时为 true,messages 原样返回。 */\n noop: boolean;\n}\n\nexport async function compactMessages(\n messages: Message[],\n opts: CompactOptions,\n): Promise<CompactResult> {\n const keepRecent = opts.keepRecent ?? 4;\n const cutoff = findSafeCutoff(messages, keepRecent);\n\n if (cutoff <= 0) {\n return {\n newMessages: messages,\n summary: \"\",\n originalCount: messages.length,\n newCount: messages.length,\n noop: true,\n };\n }\n\n const older = messages.slice(0, cutoff);\n const recent = messages.slice(cutoff);\n const summary = await summarizeConversation(older, opts.llm, opts.abortSignal, opts.onProgress);\n\n const summaryMessage: Message = {\n role: \"user\",\n content:\n `[Previous conversation summary]\\n\\n${summary}\\n\\n` +\n `[End of summary. The conversation continues below.]`,\n };\n\n const newMessages: Message[] = [summaryMessage, ...recent];\n\n return {\n newMessages,\n summary,\n originalCount: messages.length,\n newCount: newMessages.length,\n noop: false,\n };\n}\n\n/**\n * 从理想切点(messages.length - keepRecent)向前找最近的安全边界。\n * 安全边界 = user 消息(自然 turn 起点),且其之前不存在悬挂的 tool_use。\n *\n * 退化策略:找不到合法切点 → 返回 0(不压缩)。\n */\nexport function findSafeCutoff(messages: Message[], keepRecent: number): number {\n if (messages.length <= keepRecent) return 0;\n const ideal = Math.max(0, messages.length - keepRecent);\n\n for (let i = ideal; i > 0; i--) {\n if (messages[i].role !== \"user\") continue;\n if (hasUnresolvedToolUse(messages.slice(0, i))) continue;\n return i;\n }\n return 0;\n}\n\n/** older 段是否有 assistant.tool_use 但缺对应 tool 消息。 */\nfunction hasUnresolvedToolUse(older: Message[]): boolean {\n const seenToolUseIds = new Set<string>();\n const seenToolResultIds = new Set<string>();\n for (const msg of older) {\n if (msg.role === \"assistant\") {\n for (const part of msg.content) {\n if (part.type === \"tool_use\") seenToolUseIds.add(part.id);\n }\n } else if (msg.role === \"tool\") {\n seenToolResultIds.add(msg.toolUseId);\n }\n }\n for (const id of seenToolUseIds) {\n if (!seenToolResultIds.has(id)) return true;\n }\n return false;\n}\n\nasync function summarizeConversation(\n older: Message[],\n llm: LLMClient,\n abortSignal?: AbortSignal,\n onProgress?: (chars: number) => void,\n): Promise<string> {\n const transcript = renderTranscript(older);\n const prompt: Message[] = [\n {\n role: \"user\",\n content:\n `Summarize the following conversation in 200-400 words. Focus on:\\n` +\n `1. The user's task and goals\\n` +\n `2. Key decisions and approaches taken\\n` +\n `3. Files or code touched (paths + what changed)\\n` +\n `4. Outstanding questions or pending work\\n\\n` +\n `Be concrete. Do not invent details. Use short bullet points where appropriate.\\n\\n` +\n `--- BEGIN CONVERSATION ---\\n${transcript}\\n--- END CONVERSATION ---`,\n },\n ];\n\n let text = \"\";\n for await (const ev of llm.stream({ messages: prompt, abortSignal })) {\n if (ev.type === \"text\") {\n text += ev.delta;\n onProgress?.(text.length);\n } else if (ev.type === \"error\") throw ev.error;\n }\n return text.trim() || \"(empty summary)\";\n}\n\nfunction renderTranscript(messages: Message[]): string {\n const lines: string[] = [];\n for (const msg of messages) {\n switch (msg.role) {\n case \"system\":\n lines.push(`[system]\\n${msg.content}\\n`);\n break;\n case \"user\":\n lines.push(`[user]\\n${typeof msg.content === \"string\" ? msg.content : flattenContent(msg.content)}\\n`);\n break;\n case \"assistant\":\n lines.push(`[assistant]\\n${renderAssistant(msg)}\\n`);\n break;\n case \"tool\":\n lines.push(`[tool result${msg.isError ? \" ERROR\" : \"\"}]\\n${msg.content}\\n`);\n break;\n }\n }\n return lines.join(\"\\n\");\n}\n\nfunction renderAssistant(msg: AssistantMessage): string {\n const parts: string[] = [];\n for (const part of msg.content) {\n if (part.type === \"text\") parts.push(part.text);\n else if (part.type === \"tool_use\") {\n parts.push(`<tool_call name=\"${part.name}\" args=${JSON.stringify(part.args)} />`);\n }\n }\n return parts.join(\"\\n\");\n}\n\nfunction flattenContent(parts: ContentPart[]): string {\n return parts\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text)\n .join(\"\\n\");\n}\n","/**\n * MCP 状态查询入口(v0.1 占位,v0.3 真接 SDK)。\n *\n * 当前仅根据 settings.mcpServers 配置返回\"已配置但未连接\"的状态。\n * /mcp 命令读这里;不依赖任何 MCP 运行时。\n */\n\nimport type { Settings } from \"../config/types.js\";\nimport type { MCPServerStatus, MCPServerConfig } from \"./types.js\";\n\nconst NOT_IMPLEMENTED = \"MCP client not implemented (planned for v0.3)\";\n\nexport function getMCPStatus(settings: Settings): MCPServerStatus[] {\n const servers = (settings.mcpServers ?? {}) as Record<string, MCPServerConfig>;\n return Object.entries(servers).map(([name, config]) => ({\n name,\n configured: true,\n connected: false,\n toolCount: 0,\n error: NOT_IMPLEMENTED,\n config,\n }));\n}\n\nexport type { MCPServerStatus, MCPServerConfig } from \"./types.js\";\n","/**\n * Session 持久化:append-only JSONL。\n * 路径:~/.muse/projects/<project-hash>/sessions/<uuid>.jsonl\n *\n * 每行一个事件:消息 / 工具调用 / 工具结果 / 使用统计 / ...\n */\n\nimport { appendFile, mkdir, readdir, readFile, stat } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { createHash, randomUUID } from \"node:crypto\";\nimport type { Message, TokenUsage } from \"../types/index.js\";\nimport { log } from \"../log/index.js\";\n\nexport type SessionEvent =\n | { type: \"session_start\"; time: string; cwd: string; provider: string; model: string }\n | { type: \"message\"; time: string; message: Message }\n | { type: \"usage\"; time: string; usage: TokenUsage; provider: string; model: string }\n | { type: \"session_end\"; time: string; reason: \"user_exit\" | \"error\" };\n\nexport interface SessionMeta {\n id: string;\n cwd: string;\n createdAt: string;\n path: string;\n}\n\nexport interface SessionSummary extends SessionMeta {\n /** 首个 user 消息前 60 字符。 */\n preview?: string;\n messageCount: number;\n}\n\nfunction projectHash(cwd: string): string {\n return createHash(\"sha256\").update(cwd).digest(\"hex\").slice(0, 16);\n}\n\nfunction sessionsDir(cwd: string): string {\n return join(homedir(), \".muse\", \"projects\", projectHash(cwd), \"sessions\");\n}\n\nexport class Session {\n readonly meta: SessionMeta;\n private writeQueue: Promise<void> = Promise.resolve();\n\n private constructor(meta: SessionMeta) {\n this.meta = meta;\n }\n\n static async create(cwd: string): Promise<Session> {\n const id = randomUUID();\n const dir = sessionsDir(cwd);\n await mkdir(dir, { recursive: true });\n const path = join(dir, `${id}.jsonl`);\n const meta: SessionMeta = {\n id,\n cwd,\n createdAt: new Date().toISOString(),\n path,\n };\n log.debug(\"session created\", { id, path });\n return new Session(meta);\n }\n\n static async findLatest(cwd: string): Promise<SessionMeta | undefined> {\n const list = await Session.listAll(cwd, 1);\n return list[0];\n }\n\n static async resolve(cwd: string, idOrPrefix: string): Promise<SessionMeta | undefined> {\n const dir = sessionsDir(cwd);\n if (!existsSync(dir)) return undefined;\n const entries = await readdir(dir);\n const matches = entries.filter((e) => e.endsWith(\".jsonl\") && e.startsWith(idOrPrefix));\n if (matches.length === 0) return undefined;\n if (matches.length > 1) {\n throw new Error(`Ambiguous session id \"${idOrPrefix}\" matches ${matches.length} sessions; use more characters.`);\n }\n const top = matches[0];\n const st = await stat(join(dir, top));\n return {\n id: top.replace(/\\.jsonl$/, \"\"),\n cwd,\n createdAt: st.mtime.toISOString(),\n path: join(dir, top),\n };\n }\n\n /**\n * 按修改时间倒序列出当前 cwd 下的 session,附带 preview 与消息数。\n * 读 preview 需要打开每个文件;调用方通过 limit 控制 IO 量。\n */\n static async listAll(cwd: string, limit?: number): Promise<SessionSummary[]> {\n const dir = sessionsDir(cwd);\n if (!existsSync(dir)) return [];\n const entries = await readdir(dir);\n const files = entries.filter((e) => e.endsWith(\".jsonl\"));\n if (files.length === 0) return [];\n\n const stats = await Promise.all(\n files.map(async (f) => {\n const path = join(dir, f);\n const st = await stat(path);\n return { file: f, path, mtime: st.mtime };\n }),\n );\n stats.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());\n\n const truncated = typeof limit === \"number\" ? stats.slice(0, limit) : stats;\n\n const summaries: SessionSummary[] = [];\n for (const s of truncated) {\n const meta: SessionMeta = {\n id: s.file.replace(/\\.jsonl$/, \"\"),\n cwd,\n createdAt: s.mtime.toISOString(),\n path: s.path,\n };\n const summary = await readSummary(meta);\n summaries.push(summary);\n }\n return summaries;\n }\n\n static async open(meta: SessionMeta): Promise<{ session: Session; events: SessionEvent[] }> {\n const session = new Session(meta);\n const events = await session.readAll();\n return { session, events };\n }\n\n /** 从已加载的 events 重建 messages 数组(按时序)。 */\n static messagesFromEvents(events: SessionEvent[]): Message[] {\n const out: Message[] = [];\n for (const ev of events) {\n if (ev.type === \"message\") out.push(ev.message);\n }\n return out;\n }\n\n async append(event: SessionEvent): Promise<void> {\n const line = JSON.stringify(event) + \"\\n\";\n // 串行写入避免交错\n this.writeQueue = this.writeQueue.then(async () => {\n try {\n await mkdir(dirname(this.meta.path), { recursive: true });\n await appendFile(this.meta.path, line, \"utf-8\");\n } catch (err) {\n log.warn(`session append failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n });\n return this.writeQueue;\n }\n\n async readAll(): Promise<SessionEvent[]> {\n if (!existsSync(this.meta.path)) return [];\n const raw = await readFile(this.meta.path, \"utf-8\");\n const events: SessionEvent[] = [];\n for (const line of raw.split(\"\\n\")) {\n if (!line.trim()) continue;\n try {\n events.push(JSON.parse(line) as SessionEvent);\n } catch {\n // skip corrupt lines\n }\n }\n return events;\n }\n}\n\nasync function readSummary(meta: SessionMeta): Promise<SessionSummary> {\n let events: SessionEvent[] = [];\n try {\n const raw = await readFile(meta.path, \"utf-8\");\n for (const line of raw.split(\"\\n\")) {\n if (!line.trim()) continue;\n try {\n events.push(JSON.parse(line) as SessionEvent);\n } catch {\n // skip\n }\n }\n } catch {\n // unreadable; return minimal summary\n }\n const messages = events.filter((e): e is Extract<SessionEvent, { type: \"message\" }> => e.type === \"message\");\n const firstUser = messages.find((e) => e.message.role === \"user\");\n let preview: string | undefined;\n if (firstUser) {\n const c = firstUser.message.content;\n const text = typeof c === \"string\" ? c : c.map((p) => (p.type === \"text\" ? p.text : \"\")).join(\" \").trim();\n preview = text.slice(0, 60).replace(/\\s+/g, \" \");\n }\n return { ...meta, preview, messageCount: messages.length };\n}\n","/**\n * Slash 命令体共享的格式化 helper。\n *\n * 之所以单独抽:命令文件应该薄、只编排;shortPath / 表格对齐 / flag 解析\n * 被多个命令复用,三处相似就抽(CLAUDE.md 代码风格条款)。\n */\n\nimport { homedir } from \"node:os\";\n\nexport function shortPath(p: string): string {\n const home = homedir();\n if (p === home) return \"~\";\n if (p.startsWith(home + \"/\")) return \"~\" + p.slice(home.length);\n return p;\n}\n\nexport function formatList(list: string[] | undefined): string {\n if (!list || list.length === 0) return \"(none)\";\n return list.join(\", \");\n}\n\n/**\n * 解析 \"--key val --flag pos1 pos2\" 形式。极简,够 v0.1 用:\n * - 不支持 = 形式\n * - 不支持引号转义\n * - bool flag 默认 false,出现即 true\n */\nexport function parseArgs(raw: string): { positional: string[]; flags: Record<string, string | boolean> } {\n const tokens = raw.trim().split(/\\s+/).filter(Boolean);\n const positional: string[] = [];\n const flags: Record<string, string | boolean> = {};\n for (let i = 0; i < tokens.length; i++) {\n const t = tokens[i];\n if (t.startsWith(\"--\")) {\n const key = t.slice(2);\n const next = tokens[i + 1];\n if (next && !next.startsWith(\"--\")) {\n flags[key] = next;\n i++;\n } else {\n flags[key] = true;\n }\n } else {\n positional.push(t);\n }\n }\n return { positional, flags };\n}\n\n/**\n * \"provider/model\" 或 \"model\" 解析。后者沿用当前 provider。\n */\nexport function parseModelSpec(\n spec: string,\n fallbackProvider: string,\n): { provider: string; model: string } {\n const slash = spec.indexOf(\"/\");\n if (slash === -1) return { provider: fallbackProvider, model: spec };\n return { provider: spec.slice(0, slash), model: spec.slice(slash + 1) };\n}\n\n/** \"yyyy-mm-dd hh:mm\" 紧凑时间。 */\nexport function formatTime(iso: string): string {\n const d = new Date(iso);\n if (isNaN(d.getTime())) return iso;\n const pad = (n: number) => String(n).padStart(2, \"0\");\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;\n}\n","/**\n * 内置 slash 命令:/help /clear /compact /model /config /mcp /cost /resume /quit\n *\n * 设计文档:muse-design.md §7.2 表中 9 条全部覆盖。\n *\n * 设计原则:命令体只编排(解析参数 → 调 actions / 领域模块 → 构造 display)。\n * 真正的业务(压缩、列 session、查 MCP)在各自的领域模块里。\n */\n\nimport type { SlashCommand, SlashCommandContext } from \"./types.js\";\nimport { estimateCostUSD, formatUSD, lookupPricing } from \"../llm/pricing.js\";\nimport { redactApiKey } from \"../log/index.js\";\nimport { compactMessages } from \"../loop/context.js\";\nimport { getMCPStatus } from \"../mcp/index.js\";\nimport { Session } from \"../session/jsonl.js\";\nimport { loadModelsRegistry, visibleEntries, type LoadError } from \"../config/models.js\";\nimport { shortPath, formatList, parseArgs, formatTime } from \"./_format.js\";\nimport { MODE_CYCLE, MODE_LABEL, type PermissionMode } from \"../permission/index.js\";\n\n// ----- /help -----\n\nconst HELP: SlashCommand = {\n name: \"help\",\n description: \"show available slash commands\",\n execute(ctx) {\n const cmds = ctx.listCommands();\n const heads = cmds.map(headOf);\n const width = Math.max(...heads.map((h) => h.length));\n const lines = [\"Built-in commands:\"];\n for (let i = 0; i < cmds.length; i++) {\n const aliasNote = cmds[i].aliases?.length\n ? ` (alias: ${cmds[i].aliases!.map((a) => `/${a}`).join(\", \")})`\n : \"\";\n lines.push(` /${heads[i].padEnd(width)} ${cmds[i].description}${aliasNote}`);\n }\n lines.push(\"\", \"Keys: Ctrl+C exit\");\n return { display: lines.join(\"\\n\") };\n },\n};\n\nfunction headOf(c: SlashCommand): string {\n return c.argsHint ? `${c.name} ${c.argsHint}` : c.name;\n}\n\n// ----- /clear -----\n\nconst CLEAR: SlashCommand = {\n name: \"clear\",\n description: \"clear conversation history\",\n execute(ctx) {\n ctx.actions.setMessages([]);\n return { display: \"(history cleared)\" };\n },\n};\n\n// ----- /quit -----\n\nconst QUIT: SlashCommand = {\n name: \"quit\",\n aliases: [\"exit\"],\n description: \"exit Muse\",\n execute() {\n return { exit: true };\n },\n};\n\n// ----- /cost -----\n\nconst COST: SlashCommand = {\n name: \"cost\",\n description: \"show token usage and estimated cost for this session\",\n execute(ctx) {\n const { tokens, llm } = ctx;\n const pricing = lookupPricing(llm.providerName, llm.model);\n const lines = [\n `Session cost`,\n ` provider/model: ${llm.providerName} / ${llm.model}`,\n ` input tokens: ${tokens.inputTokens.toLocaleString()}`,\n ` output tokens: ${tokens.outputTokens.toLocaleString()}`,\n ` total tokens: ${tokens.totalTokens.toLocaleString()}`,\n ];\n if (pricing) {\n const cost = estimateCostUSD(llm.providerName, llm.model, tokens.inputTokens, tokens.outputTokens) ?? 0;\n lines.push(\n ` price (per 1M): input $${pricing.inputPer1M} / output $${pricing.outputPer1M}`,\n ` estimated cost: ${formatUSD(cost)}`,\n );\n } else {\n lines.push(` estimated cost: (no pricing data for ${llm.providerName}/${llm.model})`);\n }\n return { display: lines.join(\"\\n\") };\n },\n};\n\n// ----- /compact -----\n\nconst COMPACT_TIPS = [\n \"Shift+Tab cycles permission modes (default / acceptEdits / plan / bypass)\",\n \"/mode plan drafts changes without executing them\",\n \"/cost shows token usage and estimated spend\",\n \"/resume picks up a previous session in this directory\",\n \"muse --continue resumes the last session on startup\",\n \"MemoryWrite saves persistent knowledge across sessions\",\n \"TodoWrite keeps the model honest on multi-step tasks\",\n \"Pipe to muse: cat bug.log | muse \\\"explain this\\\"\",\n \"Ctrl+C exits immediately; Esc rejects a pending tool\",\n];\n\n// 经验值:muse-design §5.3 提的 200-400 词摘要约 1.2-1.8k 字符\nconst COMPACT_ESTIMATED_CHARS = 1800;\n\nconst COMPACT: SlashCommand = {\n name: \"compact\",\n description: \"summarize older messages to free up context space\",\n argsHint: \"[--keep N]\",\n async execute(ctx) {\n if (ctx.history.length === 0) return { display: \"(empty history; nothing to compact)\" };\n const { flags } = parseArgs(ctx.args);\n const keepRecent = typeof flags.keep === \"string\" ? Math.max(1, parseInt(flags.keep, 10)) : 4;\n if (Number.isNaN(keepRecent)) return { display: `Invalid --keep value: ${flags.keep}` };\n\n // ProgressBanner 每 tick 调 getPercent;用闭包持有的 ref 让 banner 看到最新值\n const progressRef = { chars: 0 };\n ctx.actions.showProgress({\n title: \"Compacting conversation\",\n tips: COMPACT_TIPS,\n getPercent: () => (progressRef.chars / COMPACT_ESTIMATED_CHARS) * 100,\n });\n\n try {\n const result = await compactMessages(ctx.history, {\n llm: ctx.llm,\n keepRecent,\n onProgress: (chars) => {\n progressRef.chars = chars;\n },\n });\n if (result.noop) {\n return { display: `(history has ${result.originalCount} messages; not enough to compact with --keep ${keepRecent})` };\n }\n ctx.actions.setMessages(result.newMessages);\n const preview = result.summary.length > 240 ? result.summary.slice(0, 240) + \"…\" : result.summary;\n return {\n display:\n `Compacted ${result.originalCount} → ${result.newCount} messages ` +\n `(kept last ${keepRecent}).\\n\\nSummary:\\n${preview}`,\n };\n } finally {\n ctx.actions.hideProgress();\n }\n },\n};\n\n// ----- /models -----\n\nconst MODELS: SlashCommand = {\n name: \"models\",\n description: \"pick a model from ~/.muse/models.local.json (↑↓ to navigate)\",\n async execute(ctx) {\n // ctx 没拿到 registry 时同步重读一次:可能 muse 启动后用户改了文件\n let registry = ctx.modelsRegistry;\n let errors: LoadError[] = [];\n if (!registry) {\n const r = await loadModelsRegistry();\n registry = r.registry;\n errors = r.errors;\n }\n\n if (!registry) {\n if (errors.length > 0) {\n return { display: renderLoadErrors(errors) };\n }\n return { display: renderEmptyRegistryHint() };\n }\n\n const visible = visibleEntries(registry);\n if (visible.length === 0) {\n return {\n display:\n `models.local.json has no available models.\\n` +\n `Check that \"availableModels\" lists at least one id present in \"models\".`,\n };\n }\n\n const picked = await ctx.actions.pickModel(visible, ctx.llm.model);\n if (!picked) return { display: \"(cancelled)\" };\n if (picked.id === ctx.llm.model) return { display: `Already on ${picked.id}.` };\n\n try {\n await ctx.actions.switchModel(picked.id);\n return { display: `Switched to ${picked.id}${picked.vendor ? ` (${picked.vendor})` : \"\"}.` };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return { display: `Failed to switch: ${msg}` };\n }\n },\n};\n\nfunction renderLoadErrors(errors: LoadError[]): string {\n return [\n `models.local.json was found but failed to load:`,\n ``,\n ...errors.flatMap((e) => [` ${shortPath(e.path)}`, ` ${e.message}`]),\n ``,\n `Fix the file above, then run /models again (it re-reads on each call).`,\n `Hint: each entry needs \"id\" and \"baseUrl\" (or \"url\"); \"apiKey\" supports \\${ENV_VAR}.`,\n ].join(\"\\n\");\n}\n\nfunction renderEmptyRegistryHint(): string {\n return [\n `No models registry found.`,\n `Create ~/.muse/models.local.json with a \"models\" array. Example:`,\n ``,\n `{`,\n ` \"models\": [`,\n ` {`,\n ` \"id\": \"<your-model-id>\",`,\n ` \"vendor\": \"<vendor-name>\",`,\n ` \"baseUrl\": \"https://...\",`,\n ` \"apiKey\": \"\\${YOUR_API_KEY}\",`,\n ` \"supportsToolCall\": true`,\n ` }`,\n ` ],`,\n ` \"availableModels\": [\"<your-model-id>\"]`,\n `}`,\n ``,\n `Then run /models again (no restart needed).`,\n ].join(\"\\n\");\n}\n\n// ----- /config -----\n\nconst CONFIG: SlashCommand = {\n name: \"config\",\n description: \"show / reload configuration (API keys redacted)\",\n argsHint: \"[reload | path]\",\n async execute(ctx) {\n const sub = ctx.args.trim();\n\n if (sub === \"reload\") {\n try {\n const { sources } = await ctx.actions.reloadSettings();\n return { display: `Reloaded from ${sources.length} sources:\\n` + sources.map((s) => ` - ${shortPath(s)}`).join(\"\\n\") };\n } catch (err) {\n return { display: `Reload failed: ${err instanceof Error ? err.message : String(err)}` };\n }\n }\n\n if (sub === \"path\") {\n return { display: renderConfigPaths(ctx) };\n }\n\n if (sub && sub !== \"show\") {\n return { display: `Unknown subcommand: /config ${sub}. Use: /config [show|reload|path]` };\n }\n\n return { display: renderConfigShow(ctx) };\n },\n};\n\nfunction renderConfigShow(ctx: SlashCommandContext): string {\n const s = ctx.settings;\n const lines = [\n `Effective configuration`,\n ` sources:`,\n ...ctx.settingsSources.map((src) => ` - ${shortPath(src)}`),\n ``,\n ` llm:`,\n ` provider: ${s.llm?.provider ?? \"(unset)\"}`,\n ` model: ${s.llm?.model ?? \"(unset)\"}`,\n ];\n if (s.llm?.temperature !== undefined) lines.push(` temperature: ${s.llm.temperature}`);\n if (s.llm?.maxTokens !== undefined) lines.push(` maxTokens: ${s.llm.maxTokens}`);\n\n lines.push(``, ` providers (apiKey redacted):`);\n for (const [name, cfg] of Object.entries(s.providers ?? {})) {\n lines.push(` ${name}: apiKey=${redactApiKey(cfg.apiKey)} baseUrl=${cfg.baseUrl ?? \"(default)\"}`);\n }\n\n lines.push(``, ` permissions:`);\n lines.push(` defaultMode: ${s.permissions?.defaultMode ?? \"ask\"}`);\n lines.push(` allow: ${formatList(s.permissions?.allow)}`);\n lines.push(` ask: ${formatList(s.permissions?.ask)}`);\n lines.push(` deny: ${formatList(s.permissions?.deny)}`);\n\n lines.push(``, ` ui:`);\n lines.push(` lang: ${s.ui?.lang ?? \"(default)\"}`);\n lines.push(` showBanner: ${s.ui?.showBanner ?? true}`);\n\n return lines.join(\"\\n\");\n}\n\nfunction renderConfigPaths(ctx: SlashCommandContext): string {\n const home = process.env.HOME ?? \"~\";\n return [\n `Configuration file paths (high to low precedence):`,\n ` 1. CLI flags / env (MUSE_PROVIDER, MUSE_MODEL, …)`,\n ` 2. ${shortPath(`${ctx.cwd}/.muse/settings.local.json`)} (project, gitignored)`,\n ` 3. ${shortPath(`${ctx.cwd}/.muse/settings.json`)} (project, committable)`,\n ` 4. ${shortPath(`${home}/.muse/settings.json`)} (global)`,\n ` 5. <built-in defaults>`,\n ``,\n `Edit any of the above, then run /config reload (no restart needed).`,\n ].join(\"\\n\");\n}\n\n// ----- /mcp -----\n\nconst MCP: SlashCommand = {\n name: \"mcp\",\n description: \"show MCP server status\",\n execute(ctx) {\n const status = getMCPStatus(ctx.settings);\n if (status.length === 0) {\n return {\n display:\n `No MCP servers configured.\\n` +\n `Add servers under \"mcpServers\" in your settings.json.\\n` +\n `Note: MCP client integration is planned for v0.3; current /mcp only inspects configuration.`,\n };\n }\n const lines = [`MCP servers (${status.length}):`];\n for (const s of status) {\n const indicator = s.connected ? \"●\" : \"○\";\n lines.push(` ${indicator} ${s.name}`);\n lines.push(` configured: ${s.configured}`);\n lines.push(` connected: ${s.connected}${s.error ? ` (${s.error})` : \"\"}`);\n if (s.connected) lines.push(` tools: ${s.toolCount}`);\n if (s.config?.command) lines.push(` command: ${s.config.command}${s.config.args ? \" \" + s.config.args.join(\" \") : \"\"}`);\n if (s.config?.url) lines.push(` url: ${s.config.url}`);\n }\n return { display: lines.join(\"\\n\") };\n },\n};\n\n// ----- /resume -----\n\nconst RESUME: SlashCommand = {\n name: \"resume\",\n description: \"resume a past session (↑↓ to pick, or pass an id-prefix)\",\n argsHint: \"[session-id-prefix]\",\n async execute(ctx) {\n // 带参快捷路径:直接按 id 前缀加载,不弹 selector\n if (ctx.args) {\n let meta;\n try {\n meta = await Session.resolve(ctx.cwd, ctx.args);\n } catch (err) {\n return { display: err instanceof Error ? err.message : String(err) };\n }\n if (!meta) return { display: `No session matches \"${ctx.args}\".` };\n return loadAndReport(meta, ctx);\n }\n\n // 无参:列出近 20 条交给 selector\n const list = await Session.listAll(ctx.cwd, 20);\n if (list.length === 0) return { display: \"No past sessions in this directory.\" };\n\n const picked = await ctx.actions.pickSession(list, ctx.session.meta.id);\n if (!picked) return { display: \"(cancelled)\" };\n if (picked.id === ctx.session.meta.id) return { display: \"Already on this session.\" };\n\n return loadAndReport(picked, ctx);\n },\n};\n\nasync function loadAndReport(\n meta: { id: string; createdAt: string; path: string; cwd: string },\n ctx: import(\"./types.js\").SlashCommandContext,\n): Promise<{ display: string }> {\n const { events } = await Session.open(meta);\n const messages = Session.messagesFromEvents(events);\n ctx.actions.setMessages(messages);\n return {\n display: `Resumed session ${meta.id.slice(0, 8)} (${messages.length} messages from ${formatTime(meta.createdAt)}).`,\n };\n}\n\n// ----- /mode -----\n\nconst MODE_ALIASES: Record<string, PermissionMode> = {\n default: \"default\",\n normal: \"default\",\n acceptedits: \"acceptEdits\",\n \"accept-edits\": \"acceptEdits\",\n accept: \"acceptEdits\",\n edits: \"acceptEdits\",\n plan: \"plan\",\n bypass: \"bypassPermissions\",\n bypasspermissions: \"bypassPermissions\",\n};\n\nconst MODE_CMD: SlashCommand = {\n name: \"mode\",\n description: \"show or switch the permission mode (alternative to Shift+Tab)\",\n argsHint: \"[default|acceptEdits|plan|bypassPermissions]\",\n execute(ctx) {\n const arg = ctx.args.trim().toLowerCase();\n if (!arg) {\n const cur = ctx.actions.getMode();\n const lines = [`Current permission mode: ${cur} — ${MODE_LABEL[cur]}`, ``, `Available modes:`];\n for (const m of MODE_CYCLE) {\n const marker = m === cur ? \"●\" : \" \";\n lines.push(` ${marker} ${m.padEnd(20)} ${MODE_LABEL[m]}`);\n }\n lines.push(``, `Switch: /mode <name> or Shift+Tab to cycle`);\n return { display: lines.join(\"\\n\") };\n }\n const target = MODE_ALIASES[arg];\n if (!target) {\n return {\n display: `Unknown mode \"${ctx.args.trim()}\". Valid: ${MODE_CYCLE.join(\" | \")}`,\n };\n }\n if (target === ctx.actions.getMode()) return { display: `Already in ${target} mode.` };\n ctx.actions.setMode(target);\n return { display: `Switched to ${target} — ${MODE_LABEL[target]}` };\n },\n};\n\n// ----- registry -----\n\nexport const BUILTIN_SLASH_COMMANDS: SlashCommand[] = [\n HELP,\n CLEAR,\n COMPACT,\n MODELS,\n CONFIG,\n MCP,\n MODE_CMD,\n COST,\n RESUME,\n QUIT,\n];\n","/**\n * 工具注册中心:管理所有可用工具,提供查询、调用、转 LLM-tool-definition 的能力。\n */\n\nimport { z } from \"zod\";\nimport type { AnyTool, ToolContext, ToolExecuteResult } from \"./types.js\";\nimport type { ToolDefinition as LLMToolDefinition } from \"../types/index.js\";\nimport { ToolError } from \"../types/index.js\";\n\n/** zod schema → JSON Schema (subset)。仅覆盖 v0.1 需要的类型。 */\nfunction zodToJsonSchema(schema: z.ZodType<unknown>): Record<string, unknown> {\n const def = (schema as unknown as { _def: { typeName: string } })._def;\n\n if (def.typeName === \"ZodObject\") {\n const shape = (schema as unknown as z.ZodObject<Record<string, z.ZodTypeAny>>).shape;\n const properties: Record<string, unknown> = {};\n const required: string[] = [];\n for (const [key, value] of Object.entries(shape)) {\n properties[key] = zodToJsonSchema(value as z.ZodType<unknown>);\n if (!(value as unknown as { isOptional?: () => boolean }).isOptional?.()) {\n required.push(key);\n }\n }\n return {\n type: \"object\",\n properties,\n ...(required.length > 0 ? { required } : {}),\n additionalProperties: false,\n };\n }\n\n if (def.typeName === \"ZodString\") {\n const d = def as unknown as { description?: string };\n return { type: \"string\", ...(d.description ? { description: d.description } : {}) };\n }\n\n if (def.typeName === \"ZodNumber\") {\n return { type: \"number\" };\n }\n\n if (def.typeName === \"ZodBoolean\") {\n return { type: \"boolean\" };\n }\n\n if (def.typeName === \"ZodArray\") {\n const inner = (def as unknown as { type: z.ZodType<unknown> }).type;\n return { type: \"array\", items: zodToJsonSchema(inner) };\n }\n\n if (def.typeName === \"ZodOptional\" || def.typeName === \"ZodDefault\") {\n const inner = (def as unknown as { innerType: z.ZodType<unknown> }).innerType;\n return zodToJsonSchema(inner);\n }\n\n if (def.typeName === \"ZodEnum\") {\n const values = (def as unknown as { values: string[] }).values;\n return { type: \"string\", enum: values };\n }\n\n if (def.typeName === \"ZodUnion\") {\n const opts = (def as unknown as { options: z.ZodType<unknown>[] }).options;\n return { anyOf: opts.map(zodToJsonSchema) };\n }\n\n // Fallback: 任意类型\n return {};\n}\n\nfunction getDescription(schema: z.ZodType<unknown>): string | undefined {\n return (schema as unknown as { description?: string }).description;\n}\n\nexport class ToolRegistry {\n private tools = new Map<string, AnyTool>();\n\n register(tool: AnyTool): void {\n if (this.tools.has(tool.name)) {\n throw new Error(`Tool \"${tool.name}\" already registered.`);\n }\n this.tools.set(tool.name, tool);\n }\n\n registerAll(tools: AnyTool[]): void {\n for (const tool of tools) this.register(tool);\n }\n\n get(name: string): AnyTool | undefined {\n return this.tools.get(name);\n }\n\n has(name: string): boolean {\n return this.tools.has(name);\n }\n\n list(): AnyTool[] {\n return Array.from(this.tools.values());\n }\n\n /** 转为 LLM 可读的 tool definition 数组。可选 filter(如 plan 模式过滤只读工具)。 */\n toLLMDefinitions(filter?: (tool: AnyTool) => boolean): LLMToolDefinition[] {\n let tools = this.list();\n if (filter) tools = tools.filter(filter);\n return tools.map((t) => {\n const schema = zodToJsonSchema(t.parameters);\n // 顶层描述:从 zod schema 的 .describe 拿\n const desc = getDescription(t.parameters);\n if (desc && typeof schema === \"object\" && schema !== null) {\n (schema as Record<string, unknown>).description = desc;\n }\n return {\n name: t.name,\n description: t.description,\n parameters: schema,\n };\n });\n }\n\n /** 调用工具:校验参数 → 执行。 */\n async execute(name: string, rawArgs: unknown, ctx: ToolContext): Promise<ToolExecuteResult> {\n const tool = this.tools.get(name);\n if (!tool) {\n throw new ToolError(`Tool \"${name}\" not found.`, name);\n }\n const parseResult = tool.parameters.safeParse(rawArgs);\n if (!parseResult.success) {\n return {\n content: `Invalid arguments for ${name}: ${parseResult.error.message}`,\n isError: true,\n };\n }\n try {\n return await tool.execute(parseResult.data, ctx);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n return { content: `Tool ${name} threw: ${msg}`, isError: true };\n }\n }\n}\n","/**\n * Read 工具:读取本地文件,支持 offset/limit 分页。\n * 返回带行号的 `cat -n` 格式,方便 LLM 引用具体行做编辑。\n */\n\nimport { readFile, stat } from \"node:fs/promises\";\nimport { resolve, isAbsolute } from \"node:path\";\nimport { z } from \"zod\";\nimport { defineTool } from \"../types.js\";\nimport { ToolError } from \"../../types/index.js\";\nimport { checkSensitivePath } from \"../_sensitive.js\";\n\nconst ReadArgs = z.object({\n file_path: z.string().describe(\"Absolute or cwd-relative path to the file.\"),\n offset: z.number().int().min(0).optional().describe(\"Line offset (0-based).\"),\n limit: z.number().int().positive().optional().describe(\"Max lines to read. Default 2000.\"),\n});\n\nconst DEFAULT_LIMIT = 2000;\nconst MAX_LINE_LENGTH = 2000; // 单行超长时截断\n\nexport const ReadTool = defineTool({\n name: \"Read\",\n description: \"Read a file from the local filesystem. Returns content with 1-indexed line numbers (cat -n format). Use offset/limit for large files.\",\n parameters: ReadArgs,\n permission: \"read\",\n summarize: (args) => `Read(${args.file_path}${args.offset != null ? `, offset=${args.offset}` : \"\"}${args.limit != null ? `, limit=${args.limit}` : \"\"})`,\n async execute(args, ctx) {\n const path = isAbsolute(args.file_path) ? args.file_path : resolve(ctx.cwd, args.file_path);\n\n const sensitive = checkSensitivePath(path);\n if (sensitive.blocked) {\n return { content: `Refused: ${path} matches sensitive path policy (${sensitive.reason}).`, isError: true };\n }\n\n let info;\n try {\n info = await stat(path);\n } catch (err) {\n throw new ToolError(`File not found: ${path}`, \"Read\", err);\n }\n\n if (!info.isFile()) {\n throw new ToolError(`Not a regular file: ${path}`, \"Read\");\n }\n\n const content = await readFile(path, \"utf-8\");\n const lines = content.split(/\\r?\\n/);\n const offset = args.offset ?? 0;\n const limit = args.limit ?? DEFAULT_LIMIT;\n const slice = lines.slice(offset, offset + limit);\n\n const numbered = slice.map((line, i) => {\n const lineNo = offset + i + 1;\n const truncated = line.length > MAX_LINE_LENGTH ? line.slice(0, MAX_LINE_LENGTH) + \"... [truncated]\" : line;\n return `${String(lineNo).padStart(5, \" \")}\\t${truncated}`;\n });\n\n let result = numbered.join(\"\\n\");\n if (offset + limit < lines.length) {\n result += `\\n... [${lines.length - offset - limit} more lines, use offset=${offset + limit} to read next]`;\n }\n\n return {\n content: result || \"(empty file)\",\n summary: `Read ${slice.length} lines from ${args.file_path}`,\n };\n },\n});\n","/**\n * 工具系统类型。\n * 内置工具与 MCP 工具都遵循同一接口。\n */\n\nimport type { z } from \"zod\";\nimport type { TodoStore } from \"../loop/todos.js\";\nimport type { AskQuestion, AskQuestionResponse } from \"./builtin/ask-user-question.js\";\n\nexport type PermissionLevel = \"read\" | \"write\" | \"execute\" | \"network\";\n\nexport interface ToolContext {\n cwd: string;\n abortSignal?: AbortSignal;\n /** 询问用户对该工具调用的批准。返回 true=允许,false=拒绝。 */\n askPermission: (toolName: string, args: unknown, summary: string) => Promise<boolean>;\n /** 主代理可能想在工具内部发起子任务,预留口子。 */\n invokeSubagent?: (prompt: string) => Promise<string>;\n /** Session 内 todo 清单(TodoWrite 写入;system prompt 读取注入下一轮)。 */\n todos?: TodoStore;\n /**\n * AskUserQuestion 工具用:一次性弹出整批选择题(链式 tab UI)。\n * 返回数组与入参 questions 等长;Esc 取消时所有项 cancelled=true。\n */\n askQuestions?: (questions: AskQuestion[]) => Promise<AskQuestionResponse[]>;\n}\n\nexport interface ToolExecuteResult {\n /** 给 LLM 看的文本结果。 */\n content: string;\n /** 标记为错误:让 LLM 知道需要修复。 */\n isError?: boolean;\n /** 给 TUI 展示的摘要(一行)。 */\n summary?: string;\n /** Unified diff(Write/Edit 等改文件工具填),交给 UI 渲染绿/红行;不进 LLM 上下文。 */\n diff?: string;\n /** 状态点颜色(仅 UI):success 绿 / error 红 / warn 黄。不填则由 isError 推断。 */\n kind?: \"success\" | \"error\" | \"warn\";\n}\n\nexport interface ToolDefinition<TArgs = unknown> {\n name: string;\n description: string;\n /** zod schema 用于参数校验 + 自动转 JSON Schema。 */\n parameters: z.ZodType<TArgs>;\n /** 权限级别:UI 与 permission 模块据此决定 ask/allow/deny。 */\n permission: PermissionLevel;\n /** 一行摘要,给 TUI 在 \"→ ToolName(...)\" 之后显示。 */\n summarize?: (args: TArgs) => string;\n /** 实际执行函数。 */\n execute: (args: TArgs, ctx: ToolContext) => Promise<ToolExecuteResult>;\n}\n\n/** 类型擦除后的工具,用于 registry 存储 / 调用。 */\nexport interface AnyTool {\n name: string;\n description: string;\n parameters: z.ZodType<unknown>;\n permission: PermissionLevel;\n summarize?: (args: unknown) => string;\n execute: (args: unknown, ctx: ToolContext) => Promise<ToolExecuteResult>;\n}\n\nexport function defineTool<TArgs>(def: ToolDefinition<TArgs>): AnyTool {\n return {\n name: def.name,\n description: def.description,\n parameters: def.parameters as z.ZodType<unknown>,\n permission: def.permission,\n summarize: def.summarize as ((args: unknown) => string) | undefined,\n execute: def.execute as (args: unknown, ctx: ToolContext) => Promise<ToolExecuteResult>,\n };\n}\n","/**\n * 敏感文件路径默认 deny。设计文档 §12.3。\n *\n * 工具层做硬拦截(不通过 PermissionGate)。即使 settings.permissions.allow 加了 Read/Write,\n * 这层也兜底;用户要绕过必须在 PermissionGate 之外显式同意(v1.0 才考虑)。\n *\n * 规则:\n * - ~/.ssh (SSH 私钥 / known_hosts)\n * - ~/.aws (AWS 凭证)\n * - ~/.gnupg (GPG 私钥)\n * - ~/.kube/config (集群 token)\n * - .env / .env.* (任何位置的环境文件)\n * - id_rsa / id_ed25519 等私钥文件名\n */\n\nimport { homedir } from \"node:os\";\nimport { basename, resolve } from \"node:path\";\n\nconst HOME = homedir();\nconst SENSITIVE_DIRS = [\n resolve(HOME, \".ssh\"),\n resolve(HOME, \".aws\"),\n resolve(HOME, \".gnupg\"),\n resolve(HOME, \".config\", \"gh\"),\n];\nconst SENSITIVE_FILES = [\n resolve(HOME, \".kube\", \"config\"),\n resolve(HOME, \".netrc\"),\n resolve(HOME, \".pypirc\"),\n];\nconst SENSITIVE_BASENAMES = new Set([\n \"id_rsa\",\n \"id_ed25519\",\n \"id_ecdsa\",\n \"id_dsa\",\n]);\nconst ENV_PATTERN = /(?:^|\\/)\\.env(\\..+)?$/;\n\nexport interface SensitiveCheck {\n blocked: boolean;\n reason?: string;\n}\n\nexport function checkSensitivePath(path: string): SensitiveCheck {\n const abs = resolve(path);\n for (const dir of SENSITIVE_DIRS) {\n if (abs === dir || abs.startsWith(dir + \"/\")) {\n return { blocked: true, reason: `sensitive directory ${dir.replace(HOME, \"~\")}` };\n }\n }\n for (const f of SENSITIVE_FILES) {\n if (abs === f) return { blocked: true, reason: `sensitive file ${f.replace(HOME, \"~\")}` };\n }\n const base = basename(abs);\n if (SENSITIVE_BASENAMES.has(base)) {\n return { blocked: true, reason: `private key filename ${base}` };\n }\n if (ENV_PATTERN.test(abs)) {\n return { blocked: true, reason: `.env file (may contain secrets)` };\n }\n return { blocked: false };\n}\n","/**\n * Write 工具:写入文件(创建或覆盖)。\n *\n * 为防误覆盖,约定调用前必须先 Read 过同一路径(除非文件不存在)。\n * 这个约束实际由 LLM 遵守 (prompt 引导);本工具不强制,但记录到日志。\n */\n\nimport { readFile, writeFile, mkdir, stat } from \"node:fs/promises\";\nimport { resolve, isAbsolute, dirname } from \"node:path\";\nimport { z } from \"zod\";\nimport { defineTool } from \"../types.js\";\nimport { makeUnifiedDiff } from \"../_diff.js\";\nimport { checkSensitivePath } from \"../_sensitive.js\";\n\nconst WriteArgs = z.object({\n file_path: z.string().describe(\"Absolute or cwd-relative path to the file.\"),\n content: z.string().describe(\"Full content of the file.\"),\n});\n\nexport const WriteTool = defineTool({\n name: \"Write\",\n description: \"Write a complete file to the local filesystem. Creates parent directories if needed. Overwrites existing files — prefer Edit for partial updates.\",\n parameters: WriteArgs,\n permission: \"write\",\n summarize: (args) => `Write(${args.file_path}, ${args.content.length} chars)`,\n async execute(args, ctx) {\n const path = isAbsolute(args.file_path) ? args.file_path : resolve(ctx.cwd, args.file_path);\n\n const sensitive = checkSensitivePath(path);\n if (sensitive.blocked) {\n return { content: `Refused: ${path} matches sensitive path policy (${sensitive.reason}).`, isError: true };\n }\n\n let existed = false;\n let oldContent = \"\";\n try {\n const info = await stat(path);\n existed = info.isFile();\n if (existed) oldContent = await readFile(path, \"utf-8\");\n } catch {\n // 文件不存在,正常情况\n }\n\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, args.content, \"utf-8\");\n\n const diff = makeUnifiedDiff(args.file_path, oldContent, args.content);\n\n return {\n content: existed\n ? `Overwrote ${path} (${args.content.length} bytes).`\n : `Created ${path} (${args.content.length} bytes).`,\n summary: `${existed ? \"Overwrote\" : \"Created\"} ${args.file_path}`,\n diff: diff || undefined,\n };\n },\n});\n","/**\n * 文件改动 → unified diff(jsdiff),仅给 UI 渲染用,不进 LLM 上下文。\n *\n * 上下文行数 3(GNU diff 默认);新文件 / 整体覆盖时呈现为全 + 行。\n */\n\nimport { createPatch } from \"diff\";\n\nconst MAX_DIFF_LINES = 200;\n\nexport function makeUnifiedDiff(filePath: string, oldContent: string, newContent: string): string {\n if (oldContent === newContent) return \"\";\n const patch = createPatch(filePath, oldContent, newContent, \"before\", \"after\", { context: 3 });\n return truncate(patch);\n}\n\nfunction truncate(diff: string): string {\n const lines = diff.split(\"\\n\");\n if (lines.length <= MAX_DIFF_LINES) return diff;\n return lines.slice(0, MAX_DIFF_LINES).join(\"\\n\") + `\\n... [${lines.length - MAX_DIFF_LINES} more diff lines truncated]`;\n}\n","/**\n * Edit 工具:在文件中做精确字符串替换。\n *\n * 必须先 Read 过文件(由调用方/LLM 遵守,不强制校验)。\n * old_string 必须在文件中唯一出现;replace_all=true 时不要求唯一。\n */\n\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { resolve, isAbsolute } from \"node:path\";\nimport { z } from \"zod\";\nimport { defineTool } from \"../types.js\";\nimport { ToolError } from \"../../types/index.js\";\nimport { makeUnifiedDiff } from \"../_diff.js\";\nimport { checkSensitivePath } from \"../_sensitive.js\";\n\nconst EditArgs = z.object({\n file_path: z.string().describe(\"Absolute or cwd-relative path to the file.\"),\n old_string: z.string().describe(\"Exact substring to replace. Must be unique unless replace_all=true.\"),\n new_string: z.string().describe(\"Replacement string.\"),\n replace_all: z.boolean().optional().describe(\"Replace every occurrence. Default false.\"),\n});\n\nexport const EditTool = defineTool({\n name: \"Edit\",\n description: \"Perform an exact string replacement in a file. Old string must be unique unless replace_all=true. Cheaper than Write when only a small part needs to change.\",\n parameters: EditArgs,\n permission: \"write\",\n summarize: (args) => `Edit(${args.file_path})`,\n async execute(args, ctx) {\n const path = isAbsolute(args.file_path) ? args.file_path : resolve(ctx.cwd, args.file_path);\n\n const sensitive = checkSensitivePath(path);\n if (sensitive.blocked) {\n return { content: `Refused: ${path} matches sensitive path policy (${sensitive.reason}).`, isError: true };\n }\n\n let content: string;\n try {\n content = await readFile(path, \"utf-8\");\n } catch (err) {\n throw new ToolError(`Cannot read ${path}: ${err instanceof Error ? err.message : String(err)}`, \"Edit\", err);\n }\n\n if (args.old_string === args.new_string) {\n return { content: \"old_string is identical to new_string; nothing to do.\", isError: true };\n }\n\n const occurrences = countOccurrences(content, args.old_string);\n if (occurrences === 0) {\n return {\n content: `old_string not found in ${args.file_path}. Did you read the file first? Check whitespace and indentation.`,\n isError: true,\n };\n }\n if (occurrences > 1 && !args.replace_all) {\n return {\n content: `old_string occurs ${occurrences} times in ${args.file_path}. Either expand context to make it unique, or set replace_all=true.`,\n isError: true,\n };\n }\n\n const newContent = args.replace_all\n ? content.split(args.old_string).join(args.new_string)\n : content.replace(args.old_string, args.new_string);\n\n await writeFile(path, newContent, \"utf-8\");\n\n const diff = makeUnifiedDiff(args.file_path, content, newContent);\n\n return {\n content: `Edited ${path}: replaced ${args.replace_all ? occurrences : 1} occurrence(s).`,\n summary: `Edited ${args.file_path}`,\n diff: diff || undefined,\n };\n },\n});\n\nfunction countOccurrences(haystack: string, needle: string): number {\n if (needle.length === 0) return 0;\n let count = 0;\n let pos = 0;\n while ((pos = haystack.indexOf(needle, pos)) !== -1) {\n count += 1;\n pos += needle.length;\n }\n return count;\n}\n","/**\n * Bash 工具:执行 shell 命令。\n *\n * 安全:内置 deny 列表(无法 allow 绕过)。\n * 上限:超时 + stdout 截断。\n */\n\nimport { execa } from \"execa\";\nimport { z } from \"zod\";\nimport { defineTool } from \"../types.js\";\n\nconst BashArgs = z.object({\n command: z.string().describe(\"Shell command to run. Will be executed via sh -c.\"),\n timeout: z.number().int().positive().optional().describe(\"Timeout in milliseconds. Default 120000 (2 min). Max 600000.\"),\n description: z.string().optional().describe(\"Brief description (3-10 words) for the UI.\"),\n});\n\nconst DEFAULT_TIMEOUT_MS = 120_000;\nconst MAX_TIMEOUT_MS = 600_000;\nconst MAX_OUTPUT_BYTES = 100_000;\n\n/** 即使在 allow 列表里也强制阻断的危险命令模式。 */\nconst HARD_DENY_PATTERNS: RegExp[] = [\n /\\brm\\s+-rf\\s+\\/(?:\\s|$)/, // rm -rf /\n /\\brm\\s+-rf\\s+~(?:\\/|\\s|$)/, // rm -rf ~ or ~/...\n /\\brm\\s+-rf\\s+\\*/, // rm -rf *\n /\\bdd\\s+.*of=\\/dev\\//, // dd of=/dev/*\n /\\bmkfs\\b/, // mkfs\n /:\\(\\)\\s*\\{\\s*:\\|:&\\s*\\}\\s*;\\s*:/, // fork bomb\n /\\bsudo\\b/, // sudo(v0.1 简单粗暴禁掉)\n /\\bcurl\\s+[^|]*\\|\\s*(?:sh|bash|zsh)/, // curl ... | sh\n /\\bwget\\s+[^|]*\\|\\s*(?:sh|bash|zsh)/, // wget ... | sh\n];\n\nfunction checkDangerous(command: string): { dangerous: true; reason: string } | { dangerous: false } {\n for (const pattern of HARD_DENY_PATTERNS) {\n if (pattern.test(command)) {\n return { dangerous: true, reason: `matches pattern ${pattern}` };\n }\n }\n return { dangerous: false };\n}\n\nexport const BashTool = defineTool({\n name: \"Bash\",\n description: \"Execute a shell command via sh -c. Use for git, file system listings, builds, tests, etc. Avoid interactive commands (prefer non-interactive flags). For file edits use Edit/Write, not sed/echo.\",\n parameters: BashArgs,\n permission: \"execute\",\n summarize: (args) => args.description ?? `Bash: ${args.command.length > 60 ? args.command.slice(0, 60) + \"...\" : args.command}`,\n async execute(args, ctx) {\n const danger = checkDangerous(args.command);\n if (danger.dangerous) {\n return {\n content: `Refused: command blocked by hard deny list (${danger.reason}). If you really need this, ask the user to run it manually.`,\n isError: true,\n };\n }\n\n const timeout = Math.min(args.timeout ?? DEFAULT_TIMEOUT_MS, MAX_TIMEOUT_MS);\n\n try {\n const result = await execa(args.command, {\n shell: \"/bin/sh\",\n cwd: ctx.cwd,\n timeout,\n reject: false,\n stripFinalNewline: false,\n maxBuffer: MAX_OUTPUT_BYTES * 2,\n cancelSignal: ctx.abortSignal,\n });\n\n const stdout = truncate(result.stdout ?? \"\", MAX_OUTPUT_BYTES, \"stdout\");\n const stderr = truncate(result.stderr ?? \"\", MAX_OUTPUT_BYTES, \"stderr\");\n\n const parts: string[] = [];\n if (stdout) parts.push(`<stdout>\\n${stdout}\\n</stdout>`);\n if (stderr) parts.push(`<stderr>\\n${stderr}\\n</stderr>`);\n if (result.timedOut) parts.push(`<timeout>Command exceeded ${timeout}ms.</timeout>`);\n if (result.failed && !result.timedOut) parts.push(`<exit_code>${result.exitCode ?? \"unknown\"}</exit_code>`);\n\n const body = parts.length > 0 ? parts.join(\"\\n\") : \"(no output)\";\n return {\n content: body,\n isError: result.failed,\n summary: result.failed ? `Bash exited ${result.exitCode ?? \"?\"}` : `Bash ok`,\n };\n } catch (err) {\n return {\n content: `Bash threw: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n});\n\nfunction truncate(text: string, max: number, label: string): string {\n if (text.length <= max) return text;\n return text.slice(0, max) + `\\n... [${label} truncated, original ${text.length} bytes]`;\n}\n","/**\n * Grep 工具:基于 ripgrep 包装(若可用),fallback 到 bash grep。\n * v0.1 简单实现:直接调 system rg / grep。\n */\n\nimport { execa } from \"execa\";\nimport { z } from \"zod\";\nimport { defineTool } from \"../types.js\";\n\nconst GrepArgs = z.object({\n pattern: z.string().describe(\"Regex pattern to search for.\"),\n path: z.string().optional().describe(\"File or directory to search in. Default: cwd.\"),\n glob: z.string().optional().describe('Glob filter, e.g. \"*.ts\" or \"src/**/*.tsx\".'),\n output_mode: z.enum([\"content\", \"files_with_matches\", \"count\"]).optional().describe(\"Default: files_with_matches.\"),\n context: z.number().int().min(0).max(50).optional().describe(\"Context lines around each match (use only with output_mode=content).\"),\n case_insensitive: z.boolean().optional(),\n});\n\nlet rgChecked = false;\nlet rgAvailable = false;\n\nasync function checkRipgrep(): Promise<boolean> {\n if (rgChecked) return rgAvailable;\n try {\n await execa(\"rg\", [\"--version\"], { reject: false });\n rgAvailable = true;\n } catch {\n rgAvailable = false;\n }\n rgChecked = true;\n return rgAvailable;\n}\n\nexport const GrepTool = defineTool({\n name: \"Grep\",\n description: \"Search file contents using regex. Prefer this over Bash(grep|find) — handles ignore files & is much faster on large trees.\",\n parameters: GrepArgs,\n permission: \"read\",\n summarize: (args) => `Grep(${args.pattern}${args.path ? `, ${args.path}` : \"\"})`,\n async execute(args, ctx) {\n const hasRg = await checkRipgrep();\n const mode = args.output_mode ?? \"files_with_matches\";\n\n if (hasRg) {\n const cliArgs: string[] = [];\n if (args.case_insensitive) cliArgs.push(\"-i\");\n if (mode === \"files_with_matches\") cliArgs.push(\"-l\");\n else if (mode === \"count\") cliArgs.push(\"-c\");\n else if (args.context != null) cliArgs.push(\"-C\", String(args.context));\n if (args.glob) cliArgs.push(\"--glob\", args.glob);\n cliArgs.push(\"--\", args.pattern, args.path ?? \".\");\n\n const result = await execa(\"rg\", cliArgs, { cwd: ctx.cwd, reject: false, cancelSignal: ctx.abortSignal });\n const out = (result.stdout ?? \"\").trim();\n if (result.exitCode === 0 || result.exitCode === 1) {\n return { content: out || \"(no matches)\", summary: `Grep ${args.pattern}` };\n }\n return { content: `rg failed: ${result.stderr}`, isError: true };\n }\n\n // Fallback: bash grep -r\n const cliArgs = [\"-r\", \"-n\"];\n if (args.case_insensitive) cliArgs.push(\"-i\");\n if (mode === \"files_with_matches\") cliArgs.push(\"-l\");\n else if (mode === \"count\") cliArgs.push(\"-c\");\n cliArgs.push(\"-E\", args.pattern, args.path ?? \".\");\n\n const result = await execa(\"grep\", cliArgs, { cwd: ctx.cwd, reject: false, cancelSignal: ctx.abortSignal });\n const out = (result.stdout ?? \"\").trim();\n if (result.exitCode === 0 || result.exitCode === 1) {\n return { content: out || \"(no matches)\", summary: `Grep ${args.pattern}` };\n }\n return { content: `grep failed: ${result.stderr}`, isError: true };\n },\n});\n","/**\n * Glob 工具:用 fast-glob 列出匹配文件。\n */\n\nimport fg from \"fast-glob\";\nimport { z } from \"zod\";\nimport { defineTool } from \"../types.js\";\n\nconst GlobArgs = z.object({\n pattern: z.string().describe('Glob pattern, e.g. \"src/**/*.ts\" or \"**/*.{md,json}\".'),\n path: z.string().optional().describe(\"Base directory to search from. Default: cwd.\"),\n limit: z.number().int().positive().max(1000).optional().describe(\"Max results. Default 100.\"),\n});\n\nconst DEFAULT_LIMIT = 100;\n\nexport const GlobTool = defineTool({\n name: \"Glob\",\n description: \"Find files by glob pattern. Returns relative paths sorted by modification time (newest first).\",\n parameters: GlobArgs,\n permission: \"read\",\n summarize: (args) => `Glob(${args.pattern}${args.path ? `, ${args.path}` : \"\"})`,\n async execute(args, ctx) {\n const cwd = args.path ?? ctx.cwd;\n const limit = args.limit ?? DEFAULT_LIMIT;\n\n const entries = await fg(args.pattern, {\n cwd,\n onlyFiles: true,\n stats: true,\n dot: false,\n ignore: [\"**/node_modules/**\", \"**/.git/**\", \"**/dist/**\", \"**/.muse/**\"],\n });\n\n // 按 mtime 倒序\n entries.sort((a, b) => {\n const ta = a.stats?.mtime?.getTime() ?? 0;\n const tb = b.stats?.mtime?.getTime() ?? 0;\n return tb - ta;\n });\n\n const truncated = entries.length > limit;\n const paths = entries.slice(0, limit).map((e) => e.path);\n\n let result = paths.join(\"\\n\") || \"(no matches)\";\n if (truncated) {\n result += `\\n... [${entries.length - limit} more, increase limit to see]`;\n }\n return { content: result, summary: `Glob found ${entries.length} file(s)` };\n },\n});\n","/**\n * TodoWrite 工具:维护 session 内任务清单。\n *\n * 把完整 todos 数组替换进 ctx.todos。约定:一次只一个 in_progress;完成立即标 completed\n * 不要批;任务尽量原子。MessageView 会读 args.todos 渲染 checkbox 清单。\n */\n\nimport { z } from \"zod\";\nimport { defineTool } from \"../types.js\";\n\nexport type TodoStatus = \"pending\" | \"in_progress\" | \"completed\";\n\nexport interface TodoItem {\n content: string;\n status: TodoStatus;\n activeForm?: string;\n}\n\nconst TodoSchema = z.object({\n content: z.string().describe(\"Imperative one-line task description (e.g. 'Run the test suite').\"),\n status: z.enum([\"pending\", \"in_progress\", \"completed\"]).describe(\"Current status.\"),\n activeForm: z.string().optional().describe(\"Present-continuous form for the spinner (e.g. 'Running the test suite').\"),\n});\n\nconst TodoWriteArgs = z.object({\n todos: z.array(TodoSchema).describe(\"Full list. Replaces the current store.\"),\n});\n\nexport const TodoWriteTool = defineTool({\n name: \"TodoWrite\",\n description:\n \"Maintain a structured task list for the current session. Pass the FULL list every call (it replaces the store). \" +\n \"Mark exactly one task in_progress at a time; mark completed immediately when done; do not batch completions. \" +\n \"Use when the task has 3+ distinct steps or is non-trivial. Skip for single trivial actions.\",\n parameters: TodoWriteArgs,\n permission: \"read\",\n summarize: (args) => `TodoWrite(${args.todos.length} items)`,\n async execute(args, ctx) {\n if (!ctx.todos) {\n return {\n content: \"TodoWrite is unavailable: this agent run has no todo store. (Internal bug; tell the user.)\",\n isError: true,\n };\n }\n ctx.todos.set(args.todos);\n const summary = args.todos\n .map((t, i) => `${i + 1}. ${t.status === \"completed\" ? \"[x]\" : t.status === \"in_progress\" ? \"[~]\" : \"[ ]\"} ${t.content}`)\n .join(\"\\n\");\n return {\n content: `Updated todos (${args.todos.length} items):\\n${summary}`,\n summary: `Todos: ${args.todos.filter((t) => t.status === \"completed\").length}/${args.todos.length} done`,\n };\n },\n});\n","/**\n * WebFetch 工具:抓 URL → 文本 / 简易 markdown。\n *\n * 安全:\n * - 拒绝本机回环 / 链接本地 / 私有网段(SSRF 防护)\n * - http → https 自动升级\n * - 30s 超时;最大 1MB 响应体\n *\n * 输出:以 HTML 解析时 strip 标签后近似 markdown;非 HTML 直接返回文本(截断)。\n *\n * 不引入 turndown:v0.1 用 minimal regex 转换,够 LLM 阅读;\n * 后续如需精细 markdown(保留 link / list 嵌套),再换专门库。\n */\n\nimport { z } from \"zod\";\nimport { defineTool } from \"../types.js\";\n\nconst WebFetchArgs = z.object({\n url: z.string().describe(\"Fully-qualified URL. http will be upgraded to https.\"),\n prompt: z\n .string()\n .optional()\n .describe(\n \"What information to look for. The host returns the page content; the LLM should then read it to answer the prompt.\",\n ),\n});\n\nconst MAX_RESPONSE_BYTES = 1_000_000;\nconst FETCH_TIMEOUT_MS = 30_000;\n\nconst PRIVATE_HOST_PATTERNS: RegExp[] = [\n /^localhost$/i,\n /^127\\./,\n /^0\\.0\\.0\\.0$/,\n /^169\\.254\\./,\n /^10\\./,\n /^192\\.168\\./,\n /^172\\.(1[6-9]|2[0-9]|3[0-1])\\./,\n /^::1$/,\n /^fc[0-9a-f]{2}:/i,\n /^fe80:/i,\n];\n\nfunction isPrivateHost(hostname: string): boolean {\n return PRIVATE_HOST_PATTERNS.some((p) => p.test(hostname));\n}\n\nexport const WebFetchTool = defineTool({\n name: \"WebFetch\",\n description:\n \"Fetch a URL and return its textual content (HTML stripped to a markdown-ish form). \" +\n \"Use for reading documentation, blog posts, or API specs. Private/loopback hosts are blocked. \" +\n \"If the URL redirects to a different host, the redirect target is returned for you to re-fetch.\",\n parameters: WebFetchArgs,\n permission: \"network\",\n summarize: (args) => `WebFetch(${args.url})`,\n async execute(args, ctx) {\n let target: URL;\n try {\n target = new URL(args.url);\n } catch {\n return { content: `Invalid URL: ${args.url}`, isError: true };\n }\n if (target.protocol === \"http:\") {\n target.protocol = \"https:\";\n }\n if (target.protocol !== \"https:\") {\n return { content: `Refused: only http(s) URLs are allowed.`, isError: true };\n }\n if (isPrivateHost(target.hostname)) {\n return { content: `Refused: ${target.hostname} is a private/loopback host (SSRF guard).`, isError: true };\n }\n\n const controller = new AbortController();\n const onAbort = () => controller.abort();\n ctx.abortSignal?.addEventListener(\"abort\", onAbort);\n const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);\n\n try {\n const resp = await fetch(target.toString(), {\n redirect: \"manual\",\n signal: controller.signal,\n headers: { \"user-agent\": \"muse-cli/0.1\" },\n });\n\n // 跨主机 redirect → 提示重试,不自动跟随\n if (resp.status >= 300 && resp.status < 400) {\n const loc = resp.headers.get(\"location\");\n if (loc) {\n try {\n const redirectURL = new URL(loc, target);\n if (redirectURL.hostname !== target.hostname) {\n return {\n content: `Redirect to a different host: ${redirectURL.toString()}\\nRe-fetch the new URL explicitly if you trust it.`,\n summary: `Redirect to a different host: ${redirectURL.toString()}`,\n kind: \"warn\",\n };\n }\n // 同 host redirect 也提示一下,让 LLM 决定是否跟\n return {\n content: `Redirect (same host): ${redirectURL.toString()}\\nRe-fetch the new URL to continue.`,\n summary: `Redirect → ${redirectURL.pathname}`,\n kind: \"warn\",\n };\n } catch {\n return { content: `Redirect with unparseable location: ${loc}`, isError: true };\n }\n }\n }\n\n if (!resp.ok) {\n return { content: `HTTP ${resp.status} ${resp.statusText} for ${target.toString()}`, isError: true };\n }\n\n const contentType = resp.headers.get(\"content-type\") ?? \"\";\n const reader = resp.body?.getReader();\n if (!reader) return { content: `Empty response body.`, isError: true };\n\n const chunks: Uint8Array[] = [];\n let total = 0;\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n if (value) {\n total += value.byteLength;\n if (total > MAX_RESPONSE_BYTES) {\n await reader.cancel();\n chunks.push(value.slice(0, value.byteLength - (total - MAX_RESPONSE_BYTES)));\n break;\n }\n chunks.push(value);\n }\n }\n const body = new TextDecoder(\"utf-8\", { fatal: false }).decode(Buffer.concat(chunks.map((c) => Buffer.from(c))));\n\n let processed = body;\n if (/^text\\/html|application\\/xhtml/i.test(contentType)) {\n processed = htmlToText(body);\n }\n\n const summary = args.prompt\n ? `# WebFetch result for: ${args.prompt}`\n : `Fetched ${target.hostname} (${total} bytes${total >= MAX_RESPONSE_BYTES ? \", truncated\" : \"\"})`;\n const truncated = processed.length > 200_000 ? processed.slice(0, 200_000) + \"\\n\\n... [truncated]\" : processed;\n const preface = args.prompt ? `# WebFetch result for: ${args.prompt}\\n\\nSource: ${target.toString()}\\n\\n` : `Source: ${target.toString()}\\n\\n`;\n return { content: preface + truncated, summary };\n } catch (err) {\n if ((err as Error).name === \"AbortError\") {\n return { content: `WebFetch aborted (timeout or user cancel).`, isError: true };\n }\n return { content: `WebFetch failed: ${err instanceof Error ? err.message : String(err)}`, isError: true };\n } finally {\n clearTimeout(timer);\n ctx.abortSignal?.removeEventListener(\"abort\", onAbort);\n }\n },\n});\n\n/**\n * 极简 HTML → 文本:删 script/style,保留段落 / 列表 / 标题 / 链接。\n * 不追求精确——给 LLM 看的近似版本即可。\n */\nexport function htmlToText(html: string): string {\n let s = html;\n // 删 script / style / svg / noscript\n s = s.replace(/<(script|style|svg|noscript)\\b[^>]*>[\\s\\S]*?<\\/\\1>/gi, \"\");\n // 注释\n s = s.replace(/<!--[\\s\\S]*?-->/g, \"\");\n // 标题\n s = s.replace(/<h([1-6])\\b[^>]*>([\\s\\S]*?)<\\/h\\1>/gi, (_m, lvl: string, txt: string) => {\n return `\\n\\n${\"#\".repeat(parseInt(lvl, 10))} ${stripTags(txt).trim()}\\n\\n`;\n });\n // a 链接\n s = s.replace(/<a\\b[^>]*href=[\"']([^\"']+)[\"'][^>]*>([\\s\\S]*?)<\\/a>/gi, (_m, href: string, txt: string) => {\n const label = stripTags(txt).trim();\n return label ? `[${label}](${href})` : href;\n });\n // 列表项\n s = s.replace(/<li\\b[^>]*>([\\s\\S]*?)<\\/li>/gi, (_m, txt: string) => `\\n- ${stripTags(txt).trim()}`);\n // 段落 / 块级\n s = s.replace(/<(p|div|section|article|header|footer|main|aside|nav|pre|blockquote|br|hr)\\b[^>]*>/gi, \"\\n\");\n s = s.replace(/<\\/(p|div|section|article|header|footer|main|aside|nav|pre|blockquote)>/gi, \"\\n\");\n // code 行内\n s = s.replace(/<code\\b[^>]*>([\\s\\S]*?)<\\/code>/gi, (_m, txt: string) => `\\`${stripTags(txt)}\\``);\n // 删剩余标签\n s = stripTags(s);\n // entity 简版\n s = s\n .replace(/&nbsp;/g, \" \")\n .replace(/&amp;/g, \"&\")\n .replace(/&lt;/g, \"<\")\n .replace(/&gt;/g, \">\")\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\");\n // 合并多空行\n s = s.replace(/\\n{3,}/g, \"\\n\\n\").trim();\n return s;\n}\n\nfunction stripTags(s: string): string {\n return s.replace(/<[^>]+>/g, \"\");\n}\n","/**\n * MemoryWrite / MemoryRead 工具:长期 memory 操作。\n *\n * Memory 设计与 Claude Code 对齐:四种类型(user / feedback / project / reference),\n * 文件路径在 ~/.muse/projects/<hash>/memory/,MEMORY.md 索引注入到 system prompt。\n *\n * 由 ctx.cwd 决定项目身份;切目录后 memory 自动隔离。\n */\n\nimport { z } from \"zod\";\nimport { defineTool } from \"../types.js\";\nimport { readMemoryFile, writeMemory, type MemoryType } from \"../../loop/memory.js\";\n\nconst TYPES: [MemoryType, ...MemoryType[]] = [\"user\", \"feedback\", \"project\", \"reference\"];\n\nconst MemoryWriteArgs = z.object({\n name: z\n .string()\n .regex(/^[a-z0-9][a-z0-9-_]*$/i, \"must be a kebab- or snake-style slug\")\n .describe(\"Short kebab/snake slug; used as filename (<name>.md) and index key.\"),\n description: z\n .string()\n .describe(\"One-line summary used in MEMORY.md index (decides future relevance).\"),\n type: z.enum(TYPES).describe(\"user | feedback | project | reference\"),\n body: z.string().describe(\"Memory content (markdown). For feedback/project, lead with the rule/fact then **Why:** and **How to apply:** lines.\"),\n});\n\nexport const MemoryWriteTool = defineTool({\n name: \"MemoryWrite\",\n description:\n \"Save a long-term memory file under ~/.muse/projects/<hash>/memory/<name>.md and update MEMORY.md index. \" +\n \"Use for: user role/preferences, validated approach decisions (feedback), project facts (auto-convert relative dates), external system references. \" +\n \"Do NOT save: code patterns derivable from the repo, git history, fix recipes, ephemeral task state.\",\n parameters: MemoryWriteArgs,\n permission: \"write\",\n summarize: (args) => `MemoryWrite(${args.name}, type=${args.type})`,\n async execute(args, ctx) {\n const { filePath, indexUpdated } = await writeMemory(ctx.cwd, {\n name: args.name,\n description: args.description,\n type: args.type as MemoryType,\n body: args.body,\n });\n return {\n content: `Saved memory \"${args.name}\" (${args.type}) → ${filePath}${indexUpdated ? \"\\nMEMORY.md updated.\" : \"\"}`,\n summary: `MemoryWrite ${args.name}`,\n };\n },\n});\n\nconst MemoryReadArgs = z.object({\n name: z.string().describe(\"Memory slug to read (no .md extension).\"),\n});\n\nexport const MemoryReadTool = defineTool({\n name: \"MemoryRead\",\n description:\n \"Read a specific long-term memory file by name. Use after seeing it referenced in MEMORY.md (which is auto-injected into the system prompt).\",\n parameters: MemoryReadArgs,\n permission: \"read\",\n summarize: (args) => `MemoryRead(${args.name})`,\n async execute(args, ctx) {\n try {\n const content = await readMemoryFile(ctx.cwd, args.name);\n return { content, summary: `MemoryRead ${args.name}` };\n } catch (err) {\n return { content: err instanceof Error ? err.message : String(err), isError: true };\n }\n },\n});\n","/**\n * AskUserQuestion 工具:在 agent loop 内同步弹出选择题让用户作答。\n *\n * 流程:tool.execute → ctx.askQuestion(req) → App 渲染 QuestionPicker → 用户 ↑↓ 选 + Enter\n * → resolve 把结果传回 → tool 把答案拼成文本喂给 LLM。Esc 取消会返回 cancelled=true。\n *\n * 一次调用可塞多个 questions(仿 Claude Code),逐题展示,任一题 Esc 视为整批取消。\n *\n * 注意:tool 本身不调任何外部资源,permission 用 read(不弹权限确认)。\n */\n\nimport { z } from \"zod\";\nimport { defineTool } from \"../types.js\";\n\nexport const AskQuestionOptionSchema = z.object({\n label: z.string().min(1).describe(\"Option text shown to the user. Concise (1-5 words).\"),\n description: z\n .string()\n .optional()\n .describe(\"Optional one-line explanation of what this option means.\"),\n preview: z\n .string()\n .optional()\n .describe(\n \"Optional rich preview rendered in a right-side panel when this option is focused. \" +\n \"Use for code/diagram/config snippets that help compare options visually. \" +\n \"Multi-line text supported.\",\n ),\n});\n\nexport const AskQuestionSchema = z.object({\n question: z.string().min(1).describe(\"Full question text (end with ?).\"),\n header: z\n .string()\n .min(1)\n .max(16)\n .describe(\"Very short label (chip), max 12 chars. E.g. 'Auth method'.\"),\n options: z\n .array(AskQuestionOptionSchema)\n .min(2)\n .max(4)\n .describe(\"2-4 options. Mutually exclusive unless multiSelect=true.\"),\n multiSelect: z\n .boolean()\n .optional()\n .describe(\"Allow multiple selections. Default false.\"),\n});\n\nexport type AskQuestion = z.infer<typeof AskQuestionSchema>;\nexport type AskQuestionOption = z.infer<typeof AskQuestionOptionSchema>;\n\nexport interface AskQuestionResponse {\n cancelled: boolean;\n /** 单选:单元素数组;多选:所选 label 列表。cancelled=true 时为空。 */\n selections: string[];\n /** 用户对该题用 'n' 添加的自由备注。空字符串表示未填。 */\n notes?: string;\n}\n\nconst AskUserQuestionArgs = z.object({\n questions: z\n .array(AskQuestionSchema)\n .min(1)\n .max(4)\n .describe(\"1-4 questions to ask the user sequentially.\"),\n});\n\nexport const AskUserQuestionTool = defineTool({\n name: \"AskUserQuestion\",\n description:\n \"Ask the user one or more multiple-choice questions when their input is needed to proceed. \" +\n \"Each question has 2-4 options. Use multiSelect=true for non-mutually-exclusive choices. \" +\n \"Prefer this over plain-text questions when the answer space is bounded. \" +\n \"If the user presses Esc, the entire batch is treated as cancelled.\",\n parameters: AskUserQuestionArgs,\n permission: \"read\",\n summarize: (args) =>\n `AskUserQuestion(${args.questions.length} question${args.questions.length === 1 ? \"\" : \"s\"})`,\n async execute(args, ctx) {\n if (!ctx.askQuestions) {\n return {\n content:\n \"AskUserQuestion is unavailable: this agent run has no question handler. \" +\n \"(Internal bug; tell the user.)\",\n isError: true,\n };\n }\n\n const responses = await ctx.askQuestions(args.questions);\n // Esc 取消时所有项 cancelled=true(UI 一次性返回整批)\n if (responses.length > 0 && responses[0].cancelled) {\n return {\n content: \"User cancelled (Esc). No answers were collected.\",\n isError: false,\n };\n }\n\n const blocks = args.questions.map((q, qi) => {\n const r = responses[qi];\n const sel = r?.selections ?? [];\n const ans = sel.length === 0 ? \"(no answer)\" : sel.join(\", \");\n const notes = r?.notes?.trim();\n return notes ? `Q: ${q.question}\\nA: ${ans}\\nNotes: ${notes}` : `Q: ${q.question}\\nA: ${ans}`;\n });\n\n return {\n content: blocks.join(\"\\n\\n\"),\n summary: `Asked ${args.questions.length} question${args.questions.length === 1 ? \"\" : \"s\"}`,\n };\n },\n});\n","import type { AnyTool } from \"../types.js\";\nimport { ReadTool } from \"./read.js\";\nimport { WriteTool } from \"./write.js\";\nimport { EditTool } from \"./edit.js\";\nimport { BashTool } from \"./bash.js\";\nimport { GrepTool } from \"./grep.js\";\nimport { GlobTool } from \"./glob.js\";\nimport { TodoWriteTool } from \"./todo.js\";\nimport { WebFetchTool } from \"./webfetch.js\";\nimport { MemoryReadTool, MemoryWriteTool } from \"./memory.js\";\nimport { AskUserQuestionTool } from \"./ask-user-question.js\";\n\nexport {\n ReadTool,\n WriteTool,\n EditTool,\n BashTool,\n GrepTool,\n GlobTool,\n TodoWriteTool,\n WebFetchTool,\n MemoryReadTool,\n MemoryWriteTool,\n AskUserQuestionTool,\n};\n\nexport const BUILTIN_TOOLS: AnyTool[] = [\n ReadTool,\n WriteTool,\n EditTool,\n BashTool,\n GrepTool,\n GlobTool,\n TodoWriteTool,\n WebFetchTool,\n MemoryReadTool,\n MemoryWriteTool,\n AskUserQuestionTool,\n];\n"],"mappings":"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","names":["useEffect","useMemo","useState","Box","Text","useInput","useStdout","padLen","after","mkdir","readFile","writeFile","existsSync","homedir","dirname","join","Text","jsx","jsxs","Box","Text","process","styles","chalk","styles","jsx","jsxs","Box","Text","useState","Box","Text","useInput","jsx","jsxs","Box","Text","useState","Box","Text","useInput","jsx","jsxs","jsx","jsxs","resolve","Box","Text","Box","Text","jsx","jsxs","resolve","Box","Text","useState","Box","Text","useInput","jsx","jsxs","POINTER_COLOR","s","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","Box","Text","Box","Text","jsx","jsxs","useEffect","useState","Box","Text","jsx","jsxs","useEffect","useState","Box","Text","useEffect","useState","Text","jsx","jsx","jsxs","TICK_MS","useState","useEffect","formatTokens","Box","Text","resolve","tool","result","homedir","homedir","join","readFile","existsSync","homedir","join","existsSync","readFile","join","homedir","readFile","existsSync","homedir","join","z","z","join","homedir","existsSync","readFile","formatZodIssues","mkdir","readFile","existsSync","homedir","dirname","join","createHash","projectHash","createHash","join","homedir","mkdir","existsSync","dirname","readFile","homedir","formatTime","formatTime","jsx","jsxs","useStdout","useState","useMemo","useEffect","resolve","useInput","Box","Text","homedir","join","existsSync","readFile","mkdir","dirname","writeFile","tool","readFile","stat","resolve","z","homedir","basename","resolve","ENV_PATTERN","z","resolve","stat","readFile","readFile","writeFile","mkdir","stat","resolve","isAbsolute","dirname","z","z","isAbsolute","resolve","stat","readFile","mkdir","dirname","writeFile","readFile","writeFile","resolve","isAbsolute","z","z","isAbsolute","resolve","readFile","writeFile","z","z","truncate","execa","z","z","execa","cliArgs","result","out","z","z","DEFAULT_LIMIT","z","z","z","z","z","z","z","z","jsx"]}