@qxbyte/muse 0.1.0

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.
@@ -0,0 +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 Claude Code-style agent CLI. Provider-agnostic. First-class support for Chinese / self-hostable 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 * 无边框,Claude Code 风格简洁排版。\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 * 风格对齐 Claude Code:简短、命令式、把可用工具与约束摆出来。\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 * 设计对齐 Claude Code:返回带行号的 `cat -n` 格式。\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"]}