xuanzhu 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.
Files changed (37) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +424 -0
  3. package/bin/xzh.js +3 -0
  4. package/dist/cli.js +5602 -0
  5. package/dist/cli.js.map +7 -0
  6. package/dist/skills/aws/SKILL.md +70 -0
  7. package/dist/skills/datadog/SKILL.md +261 -0
  8. package/dist/skills/elasticsearch/SKILL.md +88 -0
  9. package/dist/skills/elasticsearch/install.sh +91 -0
  10. package/dist/skills/email/SKILL.md +63 -0
  11. package/dist/skills/github/SKILL.md +69 -0
  12. package/dist/skills/gitlab/SKILL.md +68 -0
  13. package/dist/skills/gitlab/install.sh +74 -0
  14. package/dist/skills/gmail/README.md +139 -0
  15. package/dist/skills/gmail/SECURITY.md +552 -0
  16. package/dist/skills/gmail/SETUP.md +258 -0
  17. package/dist/skills/gmail/activate-gmail-cli.sh +15 -0
  18. package/dist/skills/gmail/generate-hashes.sh +82 -0
  19. package/dist/skills/gmail/gmail-cli-secure.py +599 -0
  20. package/dist/skills/gmail/install.sh +313 -0
  21. package/dist/skills/gmail/requirements.txt +38 -0
  22. package/dist/skills/gmail/skill.md +225 -0
  23. package/dist/skills/jira/SKILL.md +68 -0
  24. package/dist/skills/kubernetes/SKILL.md +70 -0
  25. package/dist/skills/linear/SKILL.md +48 -0
  26. package/dist/skills/mongodb/SKILL.md +53 -0
  27. package/dist/skills/mysql/SKILL.md +71 -0
  28. package/dist/skills/mysql/install.sh +74 -0
  29. package/dist/skills/officecli/SKILL.md +429 -0
  30. package/dist/skills/playwright/SKILL.md +171 -0
  31. package/dist/skills/postgres/SKILL.md +44 -0
  32. package/dist/skills/postgres/install.sh +73 -0
  33. package/dist/skills/redis/SKILL.md +58 -0
  34. package/dist/skills/redis/install.sh +39 -0
  35. package/dist/skills/sentry/SKILL.md +59 -0
  36. package/dist/skills/telegram/SKILL.md +151 -0
  37. package/package.json +46 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/cli/index.ts", "../src/config/store.ts", "../src/utils/paths.ts", "../src/llm/anthropic.ts", "../src/llm/http.ts", "../src/llm/gemini.ts", "../src/llm/openai-compat.ts", "../src/llm/index.ts", "../src/tui/app.ts", "../src/tools/bash.ts", "../src/tools/filesystem.ts", "../src/workspace/index.ts", "../src/tools/memory.ts", "../src/skills/index.ts", "../src/skills/dependencies.ts", "../src/skills/installer.ts", "../src/tools/skills.ts", "../src/tools/index.ts", "../src/core/prompt.ts", "../src/core/agent.ts", "../src/utils/ansi.ts", "../src/tui/markdown.ts", "../src/tui/terminal.ts", "../src/cli/commands/config.ts", "../src/cli/prompt.ts", "../src/cli/commands/model.ts", "../src/cli/commands/setup.ts"],
4
+ "sourcesContent": ["import * as fs from \"fs\";\nimport * as path from \"path\";\nimport {\n configExists,\n DEFAULT_MODEL_WEIGHT,\n effectiveModels,\n loadConfig,\n pickModel,\n resetModelWeights,\n saveConfig,\n} from \"../config/store\";\nimport {\n createProvider,\n findProvider,\n validateModelEntry,\n validateProviderConfig,\n} from \"../llm\";\nimport { friendlyError } from \"../llm/http\";\nimport { TuiApp } from \"../tui/app\";\nimport { ansi } from \"../utils/ansi\";\nimport {\n expandHome,\n getConfigDir,\n getConfigPath,\n migrateLegacyConfigDir,\n} from \"../utils/paths\";\nimport { configCommand } from \"./commands/config\";\nimport { modelCommand } from \"./commands/model\";\nimport { setupCommand } from \"./commands/setup\";\n\nconst VERSION = \"0.1.0\";\n\n// \u5F53\u8F93\u51FA\u7BA1\u9053\u88AB\u63D0\u524D\u5173\u95ED\uFF08\u4F8B\u5982 `xzh config | head`\uFF09\u65F6\u4F18\u96C5\u9000\u51FA\uFF0C\u907F\u514D\u629B EPIPE \u5806\u6808\nprocess.stdout.on(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EPIPE\") process.exit(0);\n});\nprocess.stderr.on(\"error\", () => undefined);\n\nasync function main(): Promise<void> {\n // \u65E7\u5168\u5C40\u76EE\u5F55\u4E00\u6B21\u6027\u8FC1\u79FB\uFF08~/.xuanzhu \u2192 ~/.xzh\uFF09\u3002\n // \u5FC5\u987B\u5728\u4EFB\u4F55\u914D\u7F6E\u8BFB\u5199\u4E4B\u524D\u6267\u884C\uFF0C\u5426\u5219\u4F1A\u8BFB\u5230\u7A7A\u914D\u7F6E\u800C\u4E22\u5931\u7528\u6237\u7684 provider \u8BBE\u7F6E\u3002\n const migrated = migrateLegacyConfigDir();\n if (migrated.migrated) {\n process.stdout.write(\n `${ansi.gray}\u5DF2\u5C06\u5168\u5C40\u76EE\u5F55\u8FC1\u79FB\u81F3 ${getConfigDir()}` +\n `${migrated.from ? `\uFF08\u539F ${migrated.from}\uFF09` : \"\"}${ansi.reset}\\n`,\n );\n }\n\n const argv = process.argv.slice(2);\n\n // \u5168\u5C40\u5F00\u5173\uFF1A--intent \u672C\u6B21\u542F\u52A8\u542F\u7528\u610F\u56FE\u5206\u6790\uFF0C--no-intent \u5F3A\u5236\u5173\u95ED\u3002\n // \u4EC5\u4F5C\u7528\u4E8E\u672C\u6B21\u8FD0\u884C\uFF0C\u4E0D\u5199\u56DE\u914D\u7F6E\u6587\u4EF6\uFF08\u754C\u9762\u5185 /intent \u624D\u4F1A\u6301\u4E45\u5316\uFF09\u3002\n let intentOverride: boolean | undefined;\n if (argv.includes(\"--intent\")) intentOverride = true;\n else if (argv.includes(\"--no-intent\")) intentOverride = false;\n\n const args = argv.filter(\n (arg) => arg !== \"--intent\" && arg !== \"--no-intent\",\n );\n const command = args[0];\n\n switch (command) {\n case undefined:\n await startChat(undefined, intentOverride);\n return;\n case \"model\":\n await modelCommand(args.slice(1));\n return;\n case \"config\":\n await configCommand(args.slice(1));\n return;\n case \"setup\":\n await setupCommand();\n return;\n case \"help\":\n case \"-h\":\n case \"--help\":\n printHelp();\n return;\n case \"version\":\n case \"-v\":\n case \"--version\":\n process.stdout.write(`\u7384\u732A xzh v${VERSION}\\n`);\n return;\n default: {\n if (command.startsWith(\"-\")) {\n printHelp();\n return;\n }\n\n // \u4F4D\u7F6E\u53C2\u6570\uFF1A\u4F5C\u4E3A\u9879\u76EE\u76EE\u5F55\u542F\u52A8\uFF0C\u4F8B\u5982 `xzh /home`\u3001`xzh .`\n const dir = resolveDirectory(command);\n if (dir) {\n await startChat(dir, intentOverride);\n return;\n }\n if (looksLikePath(command)) {\n process.stdout.write(\n `${ansi.red}\u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u4E0D\u662F\u76EE\u5F55\uFF1A${command}${ansi.reset}\\n`,\n );\n process.exitCode = 1;\n return;\n }\n\n process.stdout.write(\n `${ansi.red}\u672A\u77E5\u547D\u4EE4\uFF1A${command}${ansi.reset}\\n` +\n `${ansi.gray}\u8FD0\u884C ${ansi.reset}xzh --help${ansi.gray} \u67E5\u770B\u7528\u6CD5\uFF0C` +\n `\u6216\u8FD0\u884C ${ansi.reset}xzh <\u76EE\u5F55>${ansi.gray} \u6307\u5B9A\u9879\u76EE\u76EE\u5F55\u3002${ansi.reset}\\n`,\n );\n process.exitCode = 1;\n }\n }\n}\n\n/** \u5224\u65AD\u53C2\u6570\u662F\u5426\"\u770B\u8D77\u6765\u50CF\u8DEF\u5F84\"\uFF0C\u7528\u4E8E\u533A\u5206\u672A\u77E5\u547D\u4EE4\u4E0E\u9519\u8BEF\u8DEF\u5F84 */\nfunction looksLikePath(input: string): boolean {\n return (\n input.startsWith(\"/\") ||\n input.startsWith(\"~\") ||\n input.startsWith(\"./\") ||\n input.startsWith(\"../\") ||\n input === \".\" ||\n input === \"..\"\n );\n}\n\n/** \u5C06\u8F93\u5165\u89E3\u6790\u4E3A\u5DF2\u5B58\u5728\u7684\u76EE\u5F55\u7EDD\u5BF9\u8DEF\u5F84\uFF1B\u4E0D\u662F\u76EE\u5F55\u5219\u8FD4\u56DE null */\nfunction resolveDirectory(input: string): string | null {\n const expanded = expandHome(input);\n const target = path.isAbsolute(expanded)\n ? expanded\n : path.resolve(process.cwd(), expanded);\n try {\n if (fs.existsSync(target) && fs.statSync(target).isDirectory()) {\n return fs.realpathSync(target);\n }\n } catch {\n // \u6309\u4E0D\u5B58\u5728\u5904\u7406\n }\n return null;\n}\n\nasync function startChat(\n cwd?: string,\n intentOverride?: boolean,\n): Promise<void> {\n if (!process.stdin.isTTY || !process.stdout.isTTY) {\n process.stdout.write(\n `${ansi.red}\u7384\u732A\u9700\u8981\u4EA4\u4E92\u5F0F\u7EC8\u7AEF\uFF08TTY\uFF09\u3002${ansi.reset}\\n` +\n `${ansi.gray}\u8BF7\u5728\u771F\u5B9E\u7EC8\u7AEF\u4E2D\u8FD0\u884C xzh\u3002${ansi.reset}\\n`,\n );\n process.exitCode = 1;\n return;\n }\n\n const config = loadConfig();\n\n // \u6743\u91CD\u5168\u90E8\u8017\u5C3D\uFF08\u4F8B\u5982\u624B\u5DE5\u6539\u574F\u914D\u7F6E\uFF09\u65F6\uFF0C\u542F\u52A8\u5373\u91CD\u7F6E\u5E76\u63D0\u793A\n const configured = effectiveModels(config);\n if (configured.length > 0 && configured.every((entry) => entry.weight <= 0)) {\n resetModelWeights(config);\n saveConfig(config);\n process.stdout.write(\n `${ansi.yellow}\u26A0 \u6240\u6709\u6A21\u578B\u6743\u91CD\u5747\u4E3A 0\uFF0C\u5DF2\u91CD\u7F6E\u4E3A ${DEFAULT_MODEL_WEIGHT}\u3002${ansi.reset}\\n`,\n );\n }\n\n // \u4F18\u5148\u52A0\u8F7D\u6743\u91CD\u6700\u9AD8\u7684\u6A21\u578B\n const active = pickModel(config);\n if (!active) {\n process.stdout.write(\n configured.length === 0\n ? `${ansi.yellow}\u5C1A\u672A\u914D\u7F6E\u4EFB\u4F55\u6A21\u578B\u3002${ansi.reset}\\n` +\n `${ansi.gray}\u8BF7\u5148\u8FD0\u884C ${ansi.reset}xzh model add <provider> <model>${ansi.gray} \u6DFB\u52A0\u6A21\u578B\u3002${ansi.reset}\\n`\n : `${ansi.red}\u6CA1\u6709\u53EF\u7528\u7684\u6A21\u578B\uFF08\u5168\u90E8\u6743\u91CD\u4E3A 0\uFF09\u3002${ansi.reset}\\n` +\n `${ansi.gray}\u8FD0\u884C ${ansi.reset}xzh model${ansi.gray} \u67E5\u770B\u4E0E\u7BA1\u7406\u6A21\u578B\u3002${ansi.reset}\\n`,\n );\n process.exitCode = 1;\n return;\n }\n\n // \u5F53\u524D\u6A21\u578B\u5FC5\u987B\u53EF\u7528\uFF0C\u5426\u5219\u65E0\u6CD5\u542F\u52A8\n const activeProblems = validateModelEntry(config, active);\n if (activeProblems.length > 0) {\n process.stdout.write(`${ansi.yellow}\u26A0 \u5F53\u524D\u6A21\u578B\u4E0D\u53EF\u7528\uFF1A${ansi.reset}\\n`);\n for (const problem of activeProblems) {\n process.stdout.write(` ${ansi.gray}\u00B7${ansi.reset} ${problem}\\n`);\n }\n if (!configExists()) {\n process.stdout.write(\n `\\n${ansi.gray}\u63D0\u793A\uFF1A\u8FD0\u884C ${ansi.reset}xzh model${ansi.gray} \u5B8C\u6210\u521D\u59CB\u5316\u914D\u7F6E\u3002${ansi.reset}\\n`,\n );\n } else {\n process.stdout.write(`\\n${ansi.gray}\u914D\u7F6E\u6587\u4EF6\uFF1A${getConfigPath()}${ansi.reset}\\n`);\n }\n process.exitCode = 1;\n return;\n }\n\n // \u5176\u4ED6\u6A21\u578B\u7684\u95EE\u9898\u53EA\u63D0\u9192\uFF0C\u4E0D\u963B\u6B62\u542F\u52A8\uFF08\u5B83\u4EEC\u4F1A\u5728\u964D\u7EA7\u65F6\u88AB\u8DF3\u8FC7\uFF09\n const otherProblems = validateProviderConfig(config).filter(\n (problem) => !activeProblems.includes(problem),\n );\n if (otherProblems.length > 0) {\n process.stdout.write(\n `${ansi.yellow}\u26A0 ${otherProblems.length} \u4E2A\u5907\u7528\u6A21\u578B\u6682\u4E0D\u53EF\u7528\uFF08\u4E0D\u5F71\u54CD\u672C\u6B21\u542F\u52A8\uFF09\uFF1A${ansi.reset}\\n`,\n );\n for (const problem of otherProblems) {\n process.stdout.write(` ${ansi.gray}\u00B7${ansi.reset} ${problem}\\n`);\n }\n }\n\n const meta = findProvider(active.provider);\n const provider = createProvider(config, active);\n\n const app = new TuiApp({\n provider,\n config,\n cwd: cwd ?? process.cwd(),\n providerLabel: meta?.label ?? active.provider,\n model: active.model,\n modelWeight: active.weight,\n activeModel: active,\n intentEnabled:\n intentOverride !== undefined\n ? intentOverride\n : config.intent?.enabled === true,\n autoApprove: config.autoApprove,\n });\n\n await app.start();\n}\n\nfunction printHelp(): void {\n const help = `\n${ansi.brightMagenta}${ansi.bold}\u7384\u732A XuanZhu${ansi.reset} ${ansi.gray}v${VERSION} \u2014\u2014 \u4E13\u4E3A\u7EC8\u7AEF\u6253\u9020\u7684 AI \u7F16\u7801 Agent${ansi.reset}\n\n${ansi.bold}\u7528\u6CD5${ansi.reset}\n ${ansi.green}xzh${ansi.reset} \u5728\u5F53\u524D\u76EE\u5F55\u542F\u52A8\u4EA4\u4E92\u5F0F\u7EC8\u7AEF\u754C\u9762\n ${ansi.green}xzh <\u76EE\u5F55>${ansi.reset} \u5728\u6307\u5B9A\u9879\u76EE\u76EE\u5F55\u542F\u52A8\uFF0C\u4F8B\u5982 ${ansi.gray}xzh /home${ansi.reset}\n ${ansi.green}xzh --intent${ansi.reset} \u672C\u6B21\u542F\u52A8\u542F\u7528\u610F\u56FE\u5206\u6790\uFF08\u9ED8\u8BA4\u5173\u95ED\uFF09\n ${ansi.green}xzh --no-intent${ansi.reset} \u672C\u6B21\u542F\u52A8\u5F3A\u5236\u5173\u95ED\u610F\u56FE\u5206\u6790\n ${ansi.green}xzh model${ansi.reset} \u4EA4\u4E92\u5F0F\u7BA1\u7406\u591A\u6A21\u578B\uFF08\u65B0\u589E / \u5220\u9664 / \u8C03\u6574\u6743\u91CD / \u67E5\u770B\u5168\u90E8\uFF09\n ${ansi.green}xzh model list${ansi.reset} \u5217\u51FA\u5DF2\u914D\u7F6E\u7684\u6A21\u578B\u4E0E\u6743\u91CD\n ${ansi.green}xzh model all${ansi.reset} \u5217\u51FA\u6240\u6709\u5185\u7F6E\u53EF\u7528\u7684\u6A21\u578B\n ${ansi.green}xzh model add <provider> <model> [\u6743\u91CD]${ansi.reset}\n \u65B0\u589E\u6A21\u578B\uFF08\u9ED8\u8BA4\u6743\u91CD ${DEFAULT_MODEL_WEIGHT}\uFF09\n ${ansi.green}xzh model remove <id|\u5E8F\u53F7>${ansi.reset} \u5220\u9664\u6A21\u578B\n ${ansi.green}xzh model weight <id|\u5E8F\u53F7> <\u6743\u91CD>${ansi.reset}\n \u8C03\u6574\u6A21\u578B\u7684\u8C03\u7528\u6743\u91CD\n ${ansi.green}xzh config${ansi.reset} \u67E5\u770B\u5F53\u524D\u914D\u7F6E\uFF08API Key \u8131\u654F\uFF09\n ${ansi.green}xzh config edit${ansi.reset} \u4F7F\u7528 nano \u7F16\u8F91\u914D\u7F6E\u6587\u4EF6\n ${ansi.green}xzh config path${ansi.reset} \u6253\u5370\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84\n ${ansi.green}xzh config init${ansi.reset} \u751F\u6210\u9ED8\u8BA4\u914D\u7F6E\u6587\u4EF6\n ${ansi.green}xzh setup${ansi.reset} \u68C0\u67E5\u5E76\u81EA\u52A8\u5B89\u88C5\u6280\u80FD\u4F9D\u8D56\uFF08playwright / officecli \u7B49\uFF09\n ${ansi.green}xzh --help${ansi.reset} \u663E\u793A\u672C\u5E2E\u52A9\n ${ansi.green}xzh --version${ansi.reset} \u663E\u793A\u7248\u672C\n\n${ansi.bold}\u652F\u6301\u7684 Provider${ansi.reset}\n deepseek \u00B7 anthropic \u00B7 openai \u00B7 gemini \u00B7 glm \u00B7 qwen \u00B7 groq \u00B7 ollama \u00B7 custom\n\n${ansi.bold}\u914D\u7F6E${ansi.reset}\n \u914D\u7F6E\u6587\u4EF6\uFF1A${ansi.gray}${getConfigPath()}${ansi.reset}\n API Key \u4E5F\u53EF\u901A\u8FC7\u73AF\u5883\u53D8\u91CF\u63D0\u4F9B\uFF08\u5982 DEEPSEEK_API_KEY / ANTHROPIC_API_KEY\uFF09\u3002\n\n${ansi.bold}\u610F\u56FE\u5206\u6790${ansi.reset}\n \u9ED8\u8BA4\u5173\u95ED\u3002\u542F\u7528\u540E\uFF08${ansi.gray}xzh --intent${ansi.reset} \u6216\u914D\u7F6E\u4E2D ${ansi.gray}intent.enabled${ansi.reset}\uFF0C\n \u4E5F\u53EF\u5728\u754C\u9762\u5185\u7528 ${ansi.gray}/intent on${ansi.reset}\uFF09\uFF0C\u6BCF\u6761\u6D88\u606F\u4F1A\u5148\u7528\u6A21\u677F\u5305\u88F9\u5E76\u8BF7\u6C42\u4E00\u6B21\u6A21\u578B\uFF0C\n \u8FD4\u56DE\u7684\u5206\u6790\u7ED3\u679C\u4F5C\u4E3A\u672C\u6B21\u8F93\u5165\u4EA4\u7ED9\u4E3B\u6D41\u7A0B\u3002\u6A21\u677F\u53EF\u5728\u914D\u7F6E ${ansi.gray}intent.prompt${ansi.reset} \u4E2D\u81EA\u5B9A\u4E49\u3002\n\n${ansi.bold}\u591A\u6A21\u578B\u4E0E\u6743\u91CD${ansi.reset}\n \u542F\u52A8\u65F6\u4F18\u5148\u4F7F\u7528\u6743\u91CD\u6700\u9AD8\u7684\u6A21\u578B\uFF1B\u8C03\u7528\u5931\u8D25\u65F6\u8BE5\u6A21\u578B\u6743\u91CD -1\uFF0C\u5E76\u81EA\u52A8\u5207\u6362\u5230\u4E0B\u4E00\u4E2A\u53EF\u7528\u6A21\u578B\uFF1B\n \u5F53\u6240\u6709\u6A21\u578B\u6743\u91CD\u8017\u5C3D\u65F6\u4F1A\u5728\u7EC8\u7AEF\u8B66\u544A\uFF0C\u5E76\u628A\u5168\u90E8\u6743\u91CD\u91CD\u7F6E\u4E3A ${DEFAULT_MODEL_WEIGHT}\u3002\n\n${ansi.bold}\u754C\u9762\u5185\u5FEB\u6377\u952E${ansi.reset}\n Enter \u63D0\u4EA4 \u00B7 Ctrl+J \u6362\u884C \u00B7 \u2191/\u2193 \u5386\u53F2 \u00B7 PgUp/PgDn \u6EDA\u52A8\n Ctrl+C \u4E2D\u65AD\u4EFB\u52A1/\u9000\u51FA \u00B7 Ctrl+L \u6E05\u5C4F \u00B7 \u8F93\u5165 /help \u67E5\u770B\u5185\u7F6E\u547D\u4EE4\n \u5207\u6362\u9879\u76EE\u76EE\u5F55\uFF1A\u5728\u754C\u9762\u4E2D\u8F93\u5165 ${ansi.green}/switch <\u76EE\u5F55>${ansi.reset}\n`;\n process.stdout.write(help);\n}\n\nmain().catch((err) => {\n process.stdout.write(\n `\\n${ansi.red}\u7384\u732A\u8FD0\u884C\u51FA\u9519\uFF1A${friendlyError(err)}${ansi.reset}\\n`,\n );\n process.exit(1);\n});\n", "import * as fs from \"fs\";\nimport { ensureDir, getConfigDir, getConfigPath } from \"../utils/paths\";\n\n/** \u5355\u4E2A Provider \u7684\u914D\u7F6E */\nexport interface ProviderSettings {\n apiKey?: string;\n baseUrl?: string;\n model?: string;\n}\n\n/** \u5355\u4E2A\u6A21\u578B\u7684\u8C03\u7528\u6743\u91CD\u9ED8\u8BA4\u503C */\nexport const DEFAULT_MODEL_WEIGHT = 10;\n\n/** \u591A\u6A21\u578B\u5217\u8868\u4E2D\u7684\u4E00\u9879 */\nexport interface ModelEntry {\n /** \u552F\u4E00\u6807\u8BC6\uFF1A`<provider>/<model>` */\n id: string;\n provider: string;\n model: string;\n /**\n * \u8C03\u7528\u6743\u91CD\uFF1A\u8D8A\u9AD8\u8D8A\u4F18\u5148\u3002\n * - \u542F\u52A8\u65F6\u9009\u62E9\u6743\u91CD\u6700\u9AD8\u7684\u6A21\u578B\n * - \u8C03\u7528\u5931\u8D25\u65F6 -1\uFF1B\u964D\u5230 0 \u8868\u793A\u8BE5\u6A21\u578B\u6682\u4E0D\u53EF\u7528\n * - \u6240\u6709\u6A21\u578B\u90FD\u4E3A 0 \u65F6\u89C6\u4E3A\u300C\u5168\u90E8\u8017\u5C3D\u300D\uFF0C\u4F1A\u88AB\u91CD\u7F6E\u56DE\u9ED8\u8BA4\u6743\u91CD\n */\n weight: number;\n /** \u53EF\u9009\uFF1A\u4EC5\u5BF9\u8BE5\u6A21\u578B\u751F\u6548\u7684 API Key\uFF08\u5426\u5219\u6CBF\u7528 providers[provider].apiKey\uFF09 */\n apiKey?: string;\n /** \u53EF\u9009\uFF1A\u4EC5\u5BF9\u8BE5\u6A21\u578B\u751F\u6548\u7684 baseUrl */\n baseUrl?: string;\n /**\n * \u662F\u5426\u300C\u56E0\u8C03\u7528\u5931\u8D25\u88AB\u964D\u8FC7\u6743\u300D\u3002\n * \u7528\u4E8E\u628A\u300C\u5931\u8D25\u964D\u5230 0\u300D\u4E0E\u300C\u7528\u6237\u4E3B\u52A8\u8BBE\u4E3A 0\uFF08\u6682\u4E0D\u4F7F\u7528\uFF09\u300D\u533A\u5206\u5F00\uFF1A\n * \u53EA\u6709\u524D\u8005\u624D\u53C2\u4E0E\u300C\u5168\u90E8\u8017\u5C3D \u2192 \u91CD\u7F6E\u300D\u7684\u5224\u5B9A\uFF0C\u5426\u5219\u7528\u6237\u663E\u5F0F\u7981\u7528\u4F1A\u88AB\u9759\u9ED8\u63A8\u7FFB\u3002\n * \u7528\u6237\u624B\u52A8\u8BBE\u7F6E\u6743\u91CD\u540E\u4F1A\u6E05\u9664\u8BE5\u6807\u8BB0\u3002\n */\n decayed?: boolean;\n}\n\n/** \u610F\u56FE\u5206\u6790\u8BBE\u7F6E */\nexport interface IntentSettings {\n /**\n * \u662F\u5426\u542F\u7528\u610F\u56FE\u5206\u6790\uFF08**\u9ED8\u8BA4\u5173\u95ED**\uFF09\u3002\n * \u542F\u7528\u540E\uFF1A\u6BCF\u6761\u7528\u6237\u6D88\u606F\u90FD\u4F1A\u5148\u7528\u6A21\u677F\u5305\u88F9\u3001\u5411\u6A21\u578B\u53D1\u8D77\u4E00\u6B21**\u72EC\u7ACB\u8BF7\u6C42**\uFF0C\n * \u8FD4\u56DE\u7684\u5185\u5BB9\u518D\u4F5C\u4E3A\u672C\u8F6E\u7684\u7528\u6237\u8F93\u5165\u4EA4\u7ED9\u4E3B\u6D41\u7A0B\u5904\u7406\u3002\n */\n enabled: boolean;\n /**\n * \u610F\u56FE\u5206\u6790\u63D0\u793A\u8BCD\u6A21\u677F\u3002\u7528\u5360\u4F4D\u7B26 `{{'\u7528\u6237\u53D1\u9001\u8FC7\u6765\u7684\u6D88\u606F'}}` \u6807\u8BB0\u7528\u6237\u6D88\u606F\u7684\u4F4D\u7F6E\uFF1B\n * \u7701\u7565\u65F6\u4F7F\u7528 DEFAULT_INTENT_PROMPT\u3002\n */\n prompt?: string;\n}\n\n/** \u610F\u56FE\u5206\u6790\u6A21\u677F\u4E2D\u7684\u7528\u6237\u6D88\u606F\u5360\u4F4D\u7B26 */\nexport const INTENT_PLACEHOLDER = \"{{'\u7528\u6237\u53D1\u9001\u8FC7\u6765\u7684\u6D88\u606F'}}\";\n\n/** \u610F\u56FE\u5206\u6790\u9ED8\u8BA4\u63D0\u793A\u8BCD\u6A21\u677F */\nexport const DEFAULT_INTENT_PROMPT =\n \"\u8BF7\u5206\u6790\u4E0B\u9762\u6D88\u606F\u7684\u610F\u56FE\uFF0C\u4EE5\u7B2C\u4E00\u4EBA\u79F0\u8F93\u51FA\u4E09\u6BB5\uFF1A\u3010\u6838\u5FC3\u610F\u56FE\u3011\u4E00\u53E5\u8BDD\u603B\u7ED3\uFF1B\" +\n \"\u3010\u9700\u6C42\u62C6\u89E3\u3011\u9010\u6761\u5217\u51FA\u660E\u786E\u9700\u6C42\uFF1B\u3010\u9690\u6027\u610F\u56FE\u3011\u6F5C\u5728\u8BC9\u6C42\u3002\u4E0D\u8981\u589E\u52A0\u539F\u6587\u4E0D\u5B58\u5728\u4FE1\u606F\u3002 \" +\n `\u6D88\u606F\uFF1A ${INTENT_PLACEHOLDER}`;\n\n/**\n * \u7528\u6A21\u677F\u5305\u88F9\u7528\u6237\u6D88\u606F\u3002\n * \u6A21\u677F\u542B\u5360\u4F4D\u7B26\u65F6\u66FF\u6362\u5360\u4F4D\u7B26\uFF1B\u542B\u5176\u5B83 `{{\u2026}}` \u5F62\u5F0F\u65F6\u66FF\u6362\u7B2C\u4E00\u4E2A\uFF1B\n * \u5B8C\u5168\u6CA1\u6709\u5360\u4F4D\u7B26\u65F6\u5728\u672B\u5C3E\u8FFD\u52A0\u300C\u6D88\u606F\uFF1A<\u5185\u5BB9>\u300D\u3002\n */\nexport function buildIntentPrompt(template: string, message: string): string {\n // \u4E00\u5F8B\u4F7F\u7528\u51FD\u6570\u5F62\u5F0F\u66FF\u6362\uFF1A\u5B57\u7B26\u4E32\u5F62\u5F0F\u4F1A\u628A message \u91CC\u7684 `$&`\u3001`$'`\u3001`$1` \u7B49\n // \u5F53\u4F5C\u53CD\u5411\u5F15\u7528\u5C55\u5F00\uFF0C\u6C61\u67D3\u610F\u56FE\u5206\u6790\u8BF7\u6C42\u7684\u5185\u5BB9\u3002\n if (template.includes(INTENT_PLACEHOLDER)) {\n return template.replace(INTENT_PLACEHOLDER, () => message);\n }\n const generic = /\\{\\{\\s*[^{}]*\\s*\\}\\}/;\n if (generic.test(template)) {\n return template.replace(generic, () => message);\n }\n return `${template}\\n\u6D88\u606F\uFF1A${message}`;\n}\n\n/** \u7384\u732A\u4E3B\u914D\u7F6E */\nexport interface XuanZhuConfig {\n version: number;\n /** \u5F53\u524D\u4F7F\u7528\u7684 provider \u6807\u8BC6\uFF08\u89C1 src/llm/index.ts PROVIDERS\uFF09 */\n provider: string;\n /** \u5F53\u524D\u4F7F\u7528\u7684\u6A21\u578B\u540D */\n model: string;\n /**\n * \u591A\u6A21\u578B\u5217\u8868\uFF08\u652F\u6301\u6743\u91CD\u4E0E\u964D\u7EA7\uFF09\u3002\n * \u4E3A\u7A7A\u65F6\u56DE\u9000\u5230 provider/model \u5355\u6A21\u578B\u914D\u7F6E\uFF0C\u4EE5\u517C\u5BB9\u65E7\u7248\u672C\u914D\u7F6E\u6587\u4EF6\u3002\n */\n models: ModelEntry[];\n /** \u610F\u56FE\u5206\u6790\u8BBE\u7F6E\uFF08\u9ED8\u8BA4\u5173\u95ED\uFF09 */\n intent: IntentSettings;\n /** \u5404 provider \u7684\u72EC\u7ACB\u914D\u7F6E */\n providers: Record<string, ProviderSettings>;\n /** \u5355\u8F6E\u4EFB\u52A1\u5185\u5DE5\u5177\u8C03\u7528\u7684\u6700\u5927\u8F6E\u6570 */\n maxToolRounds: number;\n /**\n * \u662F\u5426\u81EA\u52A8\u6279\u51C6\u5DE5\u5177\u8C03\u7528\u3002\n * true\uFF08\u9ED8\u8BA4\uFF09\uFF1A\u6240\u6709\u5DE5\u5177\uFF08\u542B\u5199\u6587\u4EF6\u3001\u6267\u884C\u547D\u4EE4\uFF09\u5747\u4E0D\u518D\u8BE2\u95EE\uFF0C\u76F4\u63A5\u6267\u884C\uFF1B\n * false\uFF1A\u5199\u6587\u4EF6 / \u7F16\u8F91\u6587\u4EF6 / \u6267\u884C\u547D\u4EE4\u524D\u9700\u7528\u6237\u786E\u8BA4\u3002\n */\n autoApprove: boolean;\n /** \u91C7\u6837\u6E29\u5EA6 */\n temperature: number;\n /** \u8FFD\u52A0\u5230\u7CFB\u7EDF\u63D0\u793A\u8BCD\u7684\u989D\u5916\u5185\u5BB9 */\n systemPromptExtra?: string;\n}\n\nexport const CONFIG_VERSION = 1;\n\nexport const DEFAULT_CONFIG: XuanZhuConfig = {\n version: CONFIG_VERSION,\n provider: \"deepseek\",\n model: \"deepseek-chat\",\n models: [],\n intent: { enabled: false },\n providers: {},\n maxToolRounds: 40,\n autoApprove: true,\n temperature: 0.2,\n};\n\n/** \u8BFB\u53D6\u914D\u7F6E\uFF1B\u4E0D\u5B58\u5728\u65F6\u8FD4\u56DE\u9ED8\u8BA4\u914D\u7F6E\uFF08\u4E0D\u5199\u76D8\uFF09 */\nexport function loadConfig(): XuanZhuConfig {\n const file = getConfigPath();\n try {\n if (!fs.existsSync(file)) {\n // \u6CA1\u6709\u914D\u7F6E\u6587\u4EF6\u65F6\u4E0D\u8FD4\u56DE DEFAULT_CONFIG \u91CC\u7684 provider / model \u5360\u4F4D\u503C\uFF1A\n // \u5B83\u4EEC\u662F\"\u9ED8\u8BA4\u793A\u4F8B\"\u800C\u975E\u7528\u6237\u914D\u7F6E\u8FC7\u7684\u6A21\u578B\uFF0C\u5426\u5219 effectiveModels() \u7684\u517C\u5BB9\u56DE\u9000\n // \u4F1A\u628A deepseek/deepseek-chat \u5F53\u6210\u4E00\u4E2A\u5DF2\u914D\u7F6E\u6A21\u578B\u7269\u5316\u8FDB models\u3002\n return { ...DEFAULT_CONFIG, provider: \"\", model: \"\", models: [] };\n }\n const raw = fs.readFileSync(file, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<XuanZhuConfig>;\n return mergeConfig(parsed);\n } catch (err) {\n throw new Error(\n `\u8BFB\u53D6\u914D\u7F6E\u5931\u8D25\uFF08${file}\uFF09\uFF1A${err instanceof Error ? err.message : String(err)}`,\n );\n }\n}\n\nfunction mergeConfig(partial: Partial<XuanZhuConfig>): XuanZhuConfig {\n const models = Array.isArray(partial.models)\n ? partial.models\n .filter(\n (entry): entry is ModelEntry =>\n Boolean(entry) &&\n typeof entry.provider === \"string\" &&\n typeof entry.model === \"string\",\n )\n .map((entry) => ({\n ...entry,\n id: entry.id || modelId(entry.provider, entry.model),\n weight:\n typeof entry.weight === \"number\" && Number.isFinite(entry.weight)\n ? entry.weight\n : DEFAULT_MODEL_WEIGHT,\n }))\n : DEFAULT_CONFIG.models;\n\n return {\n ...DEFAULT_CONFIG,\n ...partial,\n models,\n intent: {\n // \u4E25\u683C\u5E03\u5C14\uFF1A\u7F3A\u7701\u4E00\u5F8B\u89C6\u4E3A\u5173\u95ED\n enabled: partial.intent?.enabled === true,\n ...(partial.intent?.prompt ? { prompt: partial.intent.prompt } : {}),\n },\n providers: { ...DEFAULT_CONFIG.providers, ...(partial.providers ?? {}) },\n maxToolRounds: partial.maxToolRounds ?? DEFAULT_CONFIG.maxToolRounds,\n autoApprove: partial.autoApprove ?? DEFAULT_CONFIG.autoApprove,\n temperature: partial.temperature ?? DEFAULT_CONFIG.temperature,\n };\n}\n\n/** \u4FDD\u5B58\u914D\u7F6E\u5230 ~/.xzh/config.json\uFF08\u6743\u9650 600\uFF09 */\nexport function saveConfig(config: XuanZhuConfig): void {\n ensureDir(getConfigDir());\n const file = getConfigPath();\n const data = JSON.stringify(config, null, 2) + \"\\n\";\n\n // \u539F\u5B50\u5199\uFF1A\u5148\u5199\u540C\u76EE\u5F55\u4E34\u65F6\u6587\u4EF6\u518D rename\u3002\n // \u76F4\u63A5\u8986\u76D6\u539F\u6587\u4EF6\u65F6\uFF0C\u82E5\u8FDB\u7A0B\u5728\u5199\u76D8\u9014\u4E2D\u88AB\u4E2D\u65AD\uFF08Ctrl+C / \u5D29\u6E83\uFF09\uFF0C\n // \u4F1A\u7559\u4E0B\u534A\u622A JSON\uFF0C\u4E0B\u6B21 loadConfig \u76F4\u63A5\u629B\u300C\u8BFB\u53D6\u914D\u7F6E\u5931\u8D25\u300D\u5BFC\u81F4\u7384\u732A\u65E0\u6CD5\u542F\u52A8\u3002\n const tmp = `${file}.${process.pid}.tmp`;\n fs.writeFileSync(tmp, data, { mode: 0o600 });\n try {\n fs.chmodSync(tmp, 0o600);\n } catch {\n // \u67D0\u4E9B\u6587\u4EF6\u7CFB\u7EDF\u4E0D\u652F\u6301 chmod\uFF0C\u5FFD\u7565\n }\n fs.renameSync(tmp, file);\n\n try {\n fs.chmodSync(file, 0o600);\n } catch {\n // \u67D0\u4E9B\u6587\u4EF6\u7CFB\u7EDF\u4E0D\u652F\u6301 chmod\uFF0C\u5FFD\u7565\n }\n}\n\n/** \u914D\u7F6E\u662F\u5426\u5DF2\u5B58\u5728 */\nexport function configExists(): boolean {\n return fs.existsSync(getConfigPath());\n}\n\n/** \u5BF9 apiKey \u505A\u8131\u654F\uFF0C\u7528\u4E8E\u5C55\u793A */\nexport function maskKey(key?: string): string {\n if (!key) return \"(\u672A\u8BBE\u7F6E)\";\n if (key.length <= 8) return \"****\";\n return `${key.slice(0, 4)}...${key.slice(-4)}`;\n}\n\n/** \u751F\u6210\u7528\u4E8E xzh config \u5C55\u793A\u7684\u8131\u654F\u526F\u672C */\nexport function redactConfig(config: XuanZhuConfig): unknown {\n const providers: Record<string, unknown> = {};\n for (const [name, settings] of Object.entries(config.providers)) {\n providers[name] = {\n ...settings,\n apiKey: maskKey(settings.apiKey),\n };\n }\n return {\n version: config.version,\n provider: config.provider,\n model: config.model,\n models: effectiveModels(config).map((entry) => ({\n id: entry.id,\n weight: entry.weight,\n ...(entry.baseUrl ? { baseUrl: entry.baseUrl } : {}),\n ...(entry.apiKey ? { apiKey: maskKey(entry.apiKey) } : {}),\n })),\n intent: {\n enabled: config.intent?.enabled === true,\n ...(config.intent?.prompt ? { prompt: config.intent.prompt } : {}),\n },\n temperature: config.temperature,\n maxToolRounds: config.maxToolRounds,\n autoApprove: config.autoApprove,\n systemPromptExtra: config.systemPromptExtra ?? \"\",\n providers,\n };\n}\n\n// ------------------------------------------------------------ \u591A\u6A21\u578B\u4E0E\u6743\u91CD\n\n/** \u6A21\u578B\u552F\u4E00\u6807\u8BC6\uFF1A`<provider>/<model>` */\nexport function modelId(provider: string, model: string): string {\n return `${provider}/${model}`;\n}\n\n/**\n * \u751F\u6548\u7684\u6A21\u578B\u5217\u8868\uFF1A\n * - `config.models` \u975E\u7A7A\u65F6\u76F4\u63A5\u4F7F\u7528\uFF1B\n * - \u5426\u5219\u628A\u65E7\u7684\u5355\u6A21\u578B\u914D\u7F6E\uFF08provider / model\uFF09\u89C6\u4E3A\u4E00\u4E2A\u9ED8\u8BA4\u6743\u91CD\u7684\u6A21\u578B\uFF0C\n * \u4EE5\u517C\u5BB9\u5386\u53F2\u914D\u7F6E\u6587\u4EF6\u3002\n */\nexport function effectiveModels(config: XuanZhuConfig): ModelEntry[] {\n if (config.models && config.models.length > 0) {\n return config.models.map((entry) => ({ ...entry }));\n }\n const provider = config.provider;\n const model = config.providers[provider]?.model || config.model;\n if (provider && model) {\n return [\n {\n id: modelId(provider, model),\n provider,\n model,\n weight: DEFAULT_MODEL_WEIGHT,\n },\n ];\n }\n return [];\n}\n\n/** \u53EF\u7528\u6A21\u578B\uFF08\u6743\u91CD > 0\uFF09\uFF0C\u6309\u6743\u91CD\u4ECE\u9AD8\u5230\u4F4E\u6392\u5E8F\uFF08\u540C\u6743\u91CD\u4FDD\u6301\u914D\u7F6E\u987A\u5E8F\uFF09 */\nexport function rankedModels(config: XuanZhuConfig): ModelEntry[] {\n return effectiveModels(config)\n .filter((entry) => entry.weight > 0)\n .sort((a, b) => b.weight - a.weight);\n}\n\n/**\n * \u5F53\u524D\u5E94\u4F7F\u7528\u7684\u6A21\u578B\uFF1A\u6743\u91CD\u6700\u9AD8\u8005\uFF1B\u6CA1\u6709\u53EF\u7528\u6A21\u578B\u65F6\u8FD4\u56DE null\u3002\n * \u4F20\u5165 `exclude` \u53EF\u8DF3\u8FC7\u6307\u5B9A\u6A21\u578B\uFF08\u7528\u4E8E\u300C\u540C\u4E00\u6B21\u8BF7\u6C42\u5185\u4E0D\u91CD\u590D\u5C1D\u8BD5\u540C\u4E00\u4E2A\u6A21\u578B\u300D\uFF09\u3002\n */\nexport function pickModel(\n config: XuanZhuConfig,\n exclude?: Iterable<string>,\n): ModelEntry | null {\n const skip = new Set(exclude ?? []);\n return rankedModels(config).find((entry) => !skip.has(entry.id)) ?? null;\n}\n\n/**\n * \u5C31\u5730\u7269\u5316\u6A21\u578B\u5217\u8868\uFF08\u628A\u517C\u5BB9\u7528\u7684\u5355\u6A21\u578B\u914D\u7F6E\u5199\u56DE models \u6570\u7EC4\uFF09\u3002\n *\n * \u6CE8\u610F\uFF1A\u4E00\u65E6\u4FEE\u6539\u4E86 config.provider / config.model\uFF0C\u517C\u5BB9\u56DE\u9000\u5C31\u4F1A\u53D6\u5230\u65B0\u503C\uFF0C\n * \u56E0\u6B64\u4EFB\u4F55\u300C\u5148\u6539 provider/model\u3001\u518D\u64CD\u4F5C models\u300D\u7684\u6D41\u7A0B\u90FD\u5FC5\u987B\u5148\u8C03\u7528\u672C\u51FD\u6570\u3002\n */\nexport function materializeModels(config: XuanZhuConfig): ModelEntry[] {\n if (!config.models || config.models.length === 0) {\n config.models = effectiveModels(config);\n }\n return config.models;\n}\n\nexport interface DecayResult {\n /** \u76EE\u6807\u6A21\u578B\u7684 id */\n id: string;\n /** \u964D\u6743\u540E\u7684\u6743\u91CD\uFF08\u89E6\u53D1\u91CD\u7F6E\u65F6\u4E3A 0\uFF09 */\n weight: number;\n /** \u662F\u5426\u56E0\u300C\u6240\u6709\u6A21\u578B\u6743\u91CD\u8017\u5C3D\u300D\u800C\u89E6\u53D1\u5168\u5C40\u91CD\u7F6E */\n reset: boolean;\n}\n\n/**\n * \u6A21\u578B\u8C03\u7528\u5931\u8D25\uFF1A\u6743\u91CD -1\uFF08\u6700\u4F4E 0\uFF09\u3002\n * \u5F53\u6240\u6709\u5DF2\u914D\u7F6E\u6A21\u578B\u7684\u6743\u91CD\u90FD\u53D8\u6210 0 \u65F6\uFF0C\u628A\u5168\u90E8\u6743\u91CD\u91CD\u7F6E\u56DE\u9ED8\u8BA4\u503C\uFF0C\u5E76\u8FD4\u56DE `reset: true`\u3002\n */\nexport function decayModelWeight(\n config: XuanZhuConfig,\n id: string,\n): DecayResult | null {\n const models = materializeModels(config);\n const target = models.find((entry) => entry.id === id);\n if (!target) return null;\n\n target.weight = Math.max(0, target.weight - 1);\n target.decayed = true;\n const decayedWeight = target.weight;\n\n // \u53EA\u6709\u300C\u56E0\u5931\u8D25\u964D\u6743\u8FC7\u300D\u7684\u6A21\u578B\u5168\u90E8\u5F52\u96F6\u624D\u7B97\u8017\u5C3D\uFF1A\n // \u7528\u6237\u4E3B\u52A8\u8BBE\u4E3A 0\uFF08\u6682\u4E0D\u4F7F\u7528\uFF09\u7684\u6A21\u578B\u4E0D\u53C2\u4E0E\u5224\u5B9A\uFF0C\u4E5F\u4E0D\u4F1A\u88AB\u91CD\u7F6E\u590D\u6D3B\u3002\n const failed = models.filter((entry) => entry.decayed === true);\n if (failed.length > 0 && failed.every((entry) => entry.weight <= 0)) {\n for (const entry of failed) {\n entry.weight = DEFAULT_MODEL_WEIGHT;\n entry.decayed = false;\n }\n return { id, weight: 0, reset: true };\n }\n return { id, weight: decayedWeight, reset: false };\n}\n\n/** \u628A\u5168\u90E8\u6A21\u578B\u6743\u91CD\u91CD\u7F6E\u4E3A\u9ED8\u8BA4\u503C\uFF08\u5E76\u6E05\u9664\u5931\u8D25\u964D\u6743\u6807\u8BB0\uFF09 */\nexport function resetModelWeights(config: XuanZhuConfig): void {\n for (const entry of materializeModels(config)) {\n entry.weight = DEFAULT_MODEL_WEIGHT;\n entry.decayed = false;\n }\n}\n\n/** \u65B0\u589E\u6A21\u578B\uFF08\u5DF2\u5B58\u5728\u5219\u6309\u9700\u66F4\u65B0\u6743\u91CD\u4E0E\u8986\u76D6\u9879\uFF09\uFF1B\u8FD4\u56DE\u8BE5\u6761\u76EE */\nexport function upsertModel(\n config: XuanZhuConfig,\n input: {\n provider: string;\n model: string;\n weight?: number;\n apiKey?: string;\n baseUrl?: string;\n },\n): ModelEntry {\n const models = materializeModels(config);\n const id = modelId(input.provider, input.model);\n const hasWeight =\n typeof input.weight === \"number\" && Number.isFinite(input.weight);\n const existing = models.find((entry) => entry.id === id);\n\n if (existing) {\n if (hasWeight) {\n existing.weight = Math.max(0, Math.floor(input.weight!));\n existing.decayed = false;\n }\n if (input.apiKey) existing.apiKey = input.apiKey;\n if (input.baseUrl) existing.baseUrl = input.baseUrl;\n return existing;\n }\n\n const created: ModelEntry = {\n id,\n provider: input.provider,\n model: input.model,\n weight: hasWeight ? Math.max(0, Math.floor(input.weight!)) : DEFAULT_MODEL_WEIGHT,\n ...(input.apiKey ? { apiKey: input.apiKey } : {}),\n ...(input.baseUrl ? { baseUrl: input.baseUrl } : {}),\n };\n models.push(created);\n return created;\n}\n\n/** \u6309 id / \u6A21\u578B\u540D / \u5E8F\u53F7\uFF08\u4ECE 1 \u8D77\uFF09\u5B9A\u4F4D\u6A21\u578B\u4E0B\u6807\uFF1B\u672A\u627E\u5230\u8FD4\u56DE -1 */\nexport function findModelIndex(models: ModelEntry[], key: string): number {\n const byId = models.findIndex((entry) => entry.id === key);\n if (byId >= 0) return byId;\n const byModel = models.findIndex((entry) => entry.model === key);\n if (byModel >= 0) return byModel;\n const index = Number.parseInt(key, 10);\n if (!Number.isNaN(index) && index >= 1 && index <= models.length) {\n return index - 1;\n }\n return -1;\n}\n\n/** \u5220\u9664\u6A21\u578B\uFF1B\u672A\u627E\u5230\u8FD4\u56DE null */\nexport function removeModel(\n config: XuanZhuConfig,\n key: string,\n): ModelEntry | null {\n const models = materializeModels(config);\n const index = findModelIndex(models, key);\n if (index < 0) return null;\n const [removed] = models.splice(index, 1);\n return removed ?? null;\n}\n\n/** \u8BBE\u7F6E\u6307\u5B9A\u6A21\u578B\u7684\u6743\u91CD\uFF1B\u672A\u627E\u5230\u8FD4\u56DE null */\nexport function setModelWeight(\n config: XuanZhuConfig,\n key: string,\n weight: number,\n): ModelEntry | null {\n const models = materializeModels(config);\n const index = findModelIndex(models, key);\n if (index < 0) return null;\n models[index].weight = Math.max(0, Math.floor(weight));\n // \u7528\u6237\u663E\u5F0F\u63A5\u7BA1\u8BE5\u6A21\u578B\u7684\u6743\u91CD\u540E\uFF0C\u4E0D\u518D\u628A\u5B83\u89C6\u4E3A\u300C\u5931\u8D25\u964D\u6743\u300D\u7684\u4EA7\u7269\n models[index].decayed = false;\n return models[index];\n}\n", "import * as fs from \"fs\";\nimport * as os from \"os\";\nimport * as path from \"path\";\n\n/**\n * \u7384\u732A\u7684\u5168\u5C40\u76EE\u5F55\uFF1A~/.xzh\n *\n * \u8FD9\u91CC\u53EA\u5B58**\u5168\u5C40\u901A\u7528**\u7684\u5185\u5BB9\uFF1A`config.json`\uFF08\u552F\u4E00\u7684\u6A21\u578B\u914D\u7F6E\uFF09\u4E0E `skills/`\uFF08\u7528\u6237\u81EA\u5B9A\u4E49\u6280\u80FD\uFF09\u3002\n * \u4E0E\u5177\u4F53\u9879\u76EE\u76F8\u5173\u7684\u6570\u636E\u4E00\u5F8B\u653E\u5728\u9879\u76EE\u76EE\u5F55\u4E0B\u7684 `.xuanzhu/`\uFF08\u89C1 src/workspace/index.ts\uFF09\uFF1A\n * \u9879\u76EE\u8BB0\u5FC6\u6309\u5929\u5206\u5B58\u4E8E `<\u9879\u76EE>/.xuanzhu/memory/YYYY-MM-DD.md`\uFF0C\u957F\u671F\u8BB0\u5FC6\u5728 `MEMORY.md`\u3002\n *\n * \u5168\u5C40\u4E0E\u9879\u76EE\u804C\u8D23\u5206\u79BB\uFF0C\u4E14**\u76EE\u5F55\u540D\u4E0D\u540C**\uFF08`~/.xzh` vs `<\u9879\u76EE>/.xuanzhu`\uFF09\uFF0C\n * \u56E0\u6B64\u4E0D\u5B58\u5728\u628A $HOME \u5F53\u9879\u76EE\u8DEF\u5F84\u65F6\u4E24\u8005\u4E92\u76F8\u8986\u76D6\u7684\u95EE\u9898\u3002\n */\nexport function getConfigDir(): string {\n return path.join(os.homedir(), \".xzh\");\n}\n\n/** \u65E7\u7248\u5168\u5C40\u76EE\u5F55\uFF1A~/.xuanzhu\uFF08v0.1.0 \u53CA\u66F4\u65E9\u4F7F\u7528\uFF0C\u4EC5\u4F9B\u8FC1\u79FB\u68C0\u6D4B\uFF09 */\nexport function getLegacyConfigDir(): string {\n return path.join(os.homedir(), \".xuanzhu\");\n}\n\n/** \u4E3B\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84\uFF1A~/.xzh/config.json */\nexport function getConfigPath(): string {\n return path.join(getConfigDir(), \"config.json\");\n}\n\n/** \u5185\u7F6E\u6280\u80FD\u76EE\u5F55\uFF08\u968F\u5206\u53D1\u5305\uFF0C\u6253\u5305\u540E\u4F4D\u4E8E dist/skills\uFF09 */\nexport function getBuiltinSkillsDir(): string {\n return path.join(__dirname, \"skills\");\n}\n\n/** \u7528\u6237\u81EA\u5B9A\u4E49\u6280\u80FD\u76EE\u5F55\uFF1A~/.xzh/skills */\nexport function getUserSkillsDir(): string {\n return path.join(getConfigDir(), \"skills\");\n}\n\n/**\n * \u65E7\u5168\u5C40\u76EE\u5F55\u8FC1\u79FB\uFF1A`~/.xuanzhu` \u2192 `~/.xzh`\u3002\n *\n * \u53EA\u5728**\u65B0\u76EE\u5F55\u4E0D\u5B58\u5728\u4E14\u65E7\u76EE\u5F55\u5B58\u5728**\u65F6\u6267\u884C\u4E00\u6B21\uFF0C\u907F\u514D\u8986\u76D6\u5DF2\u6709\u6570\u636E\u3002\n * \u5148\u5C1D\u8BD5 rename\uFF08\u540C\u5206\u533A\u65F6\u77AC\u95F4\u5B8C\u6210\uFF09\uFF0C\u5931\u8D25\u5219\u9000\u5316\u4E3A\u300C\u590D\u5236 + \u5220\u9664\u300D\u3002\n * \u8FC1\u79FB\u5931\u8D25\u4E0D\u5F71\u54CD\u542F\u52A8\uFF0C\u56E0\u6B64\u8FD9\u91CC\u541E\u6389\u5F02\u5E38\uFF0C\u4EC5\u901A\u8FC7\u8FD4\u56DE\u503C\u544A\u77E5\u8C03\u7528\u65B9\u7528\u4E8E\u63D0\u793A\u3002\n */\nexport function migrateLegacyConfigDir(): {\n migrated: boolean;\n from?: string;\n to?: string;\n} {\n const from = getLegacyConfigDir();\n const to = getConfigDir();\n if (path.resolve(from) === path.resolve(to)) return { migrated: false };\n\n try {\n if (fs.existsSync(to) || !fs.existsSync(from)) return { migrated: false };\n } catch {\n return { migrated: false };\n }\n\n try {\n fs.renameSync(from, to);\n } catch {\n try {\n fs.cpSync(from, to, { recursive: true });\n fs.rmSync(from, { recursive: true, force: true });\n } catch {\n return { migrated: false };\n }\n }\n\n return { migrated: true, from, to };\n}\n\nexport function ensureDir(dir: string): void {\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n}\n\n/** \u5C06 ~ \u5C55\u5F00\u4E3A home \u76EE\u5F55 */\nexport function expandHome(input: string): string {\n if (!input) return input;\n if (input === \"~\") return os.homedir();\n if (input.startsWith(\"~/\") || input.startsWith(\"~\\\\\")) {\n return path.join(os.homedir(), input.slice(2));\n }\n return input;\n}\n", "import Anthropic from \"@anthropic-ai/sdk\";\nimport type {\n ContentBlockParam,\n MessageParam,\n Tool,\n} from \"@anthropic-ai/sdk/resources/messages\";\nimport { delay, isRetryableError } from \"./http\";\nimport type {\n ChatMessage,\n ChatOptions,\n LLMProvider,\n StreamChunk,\n ToolSpec,\n Usage,\n} from \"./types\";\n\nexport interface AnthropicConfig {\n id: string;\n apiKey: string;\n baseUrl?: string;\n model: string;\n maxTokens?: number;\n}\n\nconst MAX_ATTEMPTS = 3;\n\n/** Anthropic Claude Provider\uFF08\u6D41\u5F0F + tool_use\uFF0C\u542B\u77AC\u65F6\u9519\u8BEF\u91CD\u8BD5\uFF09 */\nexport class AnthropicProvider implements LLMProvider {\n public readonly id: string;\n public readonly model: string;\n private readonly client: Anthropic;\n private readonly maxTokens: number;\n\n constructor(config: AnthropicConfig) {\n this.id = config.id;\n this.model = config.model;\n this.maxTokens = config.maxTokens ?? 8192;\n this.client = new Anthropic({\n apiKey: config.apiKey,\n baseURL: config.baseUrl,\n maxRetries: 0, // \u7531\u672C Provider \u7EDF\u4E00\u63A7\u5236\u91CD\u8BD5\uFF0C\u907F\u514D\u91CD\u590D\n });\n }\n\n async *chat(options: ChatOptions): AsyncIterable<StreamChunk> {\n let lastError: unknown;\n\n for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {\n let emitted = false;\n try {\n yield* this.streamOnce(options, () => {\n emitted = true;\n });\n return;\n } catch (error) {\n lastError = error;\n if (\n emitted ||\n options.signal?.aborted ||\n attempt >= MAX_ATTEMPTS ||\n !isRetryableError(error)\n ) {\n throw error;\n }\n options.onRetry?.(\n attempt,\n MAX_ATTEMPTS,\n error instanceof Error ? error : new Error(String(error)),\n );\n await delay(attempt * 600);\n }\n }\n\n throw lastError;\n }\n\n private async *streamOnce(\n options: ChatOptions,\n markEmitted: () => void,\n ): AsyncIterable<StreamChunk> {\n const { system, messages } = toAnthropicMessages(options.messages);\n const tools: Tool[] | undefined =\n options.tools.length > 0\n ? options.tools.map(\n (tool: ToolSpec): Tool => ({\n name: tool.name,\n description: tool.description,\n input_schema: tool.parameters as Tool[\"input_schema\"],\n }),\n )\n : undefined;\n\n const stream = await this.client.messages.create(\n {\n model: this.model,\n max_tokens: this.maxTokens,\n system: system || undefined,\n messages,\n tools,\n temperature: options.temperature,\n stream: true,\n },\n { signal: options.signal },\n );\n\n const blocks = new Map<number, { id: string; name: string; json: string }>();\n let usage: Usage | undefined;\n let stopReason: string | undefined;\n let sawToolCall = false;\n\n for await (const event of stream) {\n switch (event.type) {\n case \"message_start\": {\n const input = event.message?.usage?.input_tokens;\n if (typeof input === \"number\") usage = { inputTokens: input };\n break;\n }\n case \"content_block_start\": {\n const block = event.content_block;\n if (block.type === \"tool_use\") {\n sawToolCall = true;\n blocks.set(event.index, {\n id: block.id,\n name: block.name,\n json: \"\",\n });\n }\n break;\n }\n case \"content_block_delta\": {\n const delta = event.delta;\n if (delta.type === \"text_delta\" && delta.text) {\n markEmitted();\n yield { type: \"text\", text: delta.text };\n } else if (delta.type === \"input_json_delta\") {\n const buf = blocks.get(event.index);\n if (buf) buf.json += delta.partial_json ?? \"\";\n } else if (delta.type === \"thinking_delta\") {\n const thinking = (delta as { thinking?: string }).thinking;\n if (thinking) {\n markEmitted();\n yield { type: \"reasoning\", text: thinking };\n }\n }\n break;\n }\n case \"message_delta\": {\n if (event.delta?.stop_reason) stopReason = event.delta.stop_reason;\n const output = event.usage?.output_tokens;\n if (typeof output === \"number\") {\n usage = { ...(usage ?? {}), outputTokens: output };\n }\n break;\n }\n default:\n break;\n }\n }\n\n for (const buf of blocks.values()) {\n if (!buf.name) continue;\n markEmitted();\n yield {\n type: \"tool_call\",\n toolCall: {\n id: buf.id,\n name: buf.name,\n arguments: buf.json || \"{}\",\n },\n };\n }\n\n if (sawToolCall) markEmitted();\n yield {\n type: \"done\",\n finishReason: sawToolCall ? \"tool_calls\" : stopReason,\n usage,\n };\n }\n}\n\nfunction toAnthropicMessages(messages: ChatMessage[]): {\n system: string;\n messages: MessageParam[];\n} {\n const systemParts: string[] = [];\n const result: MessageParam[] = [];\n\n for (const message of messages) {\n if (message.role === \"system\") {\n systemParts.push(message.content);\n continue;\n }\n\n if (message.role === \"user\") {\n result.push({ role: \"user\", content: message.content });\n continue;\n }\n\n if (message.role === \"assistant\") {\n if (message.toolCalls && message.toolCalls.length > 0) {\n const blocks: ContentBlockParam[] = [];\n if (message.content) {\n blocks.push({ type: \"text\", text: message.content });\n }\n for (const call of message.toolCalls) {\n blocks.push({\n type: \"tool_use\",\n id: call.id,\n name: call.name,\n input: safeParse(call.arguments),\n });\n }\n result.push({ role: \"assistant\", content: blocks });\n } else {\n result.push({ role: \"assistant\", content: message.content });\n }\n continue;\n }\n\n if (message.role === \"tool\") {\n const block: ContentBlockParam = {\n type: \"tool_result\",\n tool_use_id: message.toolCallId ?? \"\",\n content: message.content,\n };\n const last = result[result.length - 1];\n if (\n last &&\n last.role === \"user\" &&\n Array.isArray(last.content) &&\n last.content.every((b) => b.type === \"tool_result\")\n ) {\n (last.content as ContentBlockParam[]).push(block);\n } else {\n result.push({ role: \"user\", content: [block] });\n }\n }\n }\n\n return {\n system: systemParts.join(\"\\n\\n\"),\n messages: normalizeMessages(result),\n };\n}\n\n/** \u628A\u6D88\u606F\u5185\u5BB9\u89C4\u6574\u4E3A content block \u6570\u7EC4 */\nfunction toBlocks(content: MessageParam[\"content\"]): ContentBlockParam[] {\n if (typeof content === \"string\") return [{ type: \"text\", text: content }];\n return content;\n}\n\n/**\n * Anthropic \u8981\u6C42 messages \u4E25\u683C user/assistant \u4EA4\u66FF\u3001\u4E14\u5FC5\u987B\u4EE5 user \u5F00\u5934\uFF0C\n * \u5426\u5219\u76F4\u63A5 400\uFF08`messages: roles must alternate`\uFF09\u3002\u4EE5\u4E0B\u4E24\u79CD\u60C5\u51B5\u4F1A\u4EA7\u751F\u975E\u6CD5\u5E8F\u5217\uFF1A\n * 1. \u4E0A\u4E00\u8F6E\u8BF7\u6C42\u5931\u8D25\uFF1A\u5386\u53F2\u91CC\u4F1A\u51FA\u73B0\u8FDE\u7EED\u4E24\u6761 user\uFF08\u6A21\u578B\u6CA1\u6765\u5F97\u53CA\u56DE\u590D\uFF09\uFF1B\n * 2. \u5386\u53F2\u88C1\u526A\uFF08trimHistory\uFF09\u540E\u53EF\u80FD\u4EE5 assistant \u5F00\u5934\u3002\n * \u8FD9\u91CC\u7EDF\u4E00\u5F52\u4E00\u5316\uFF1A\u5408\u5E76\u76F8\u90BB\u540C role \u7684 user \u6D88\u606F\uFF0C\u5E76\u4E22\u5F03\u5F00\u5934\u7684 assistant\u3002\n */\nfunction normalizeMessages(messages: MessageParam[]): MessageParam[] {\n const merged: MessageParam[] = [];\n\n for (const message of messages) {\n const last = merged[merged.length - 1];\n if (last && last.role === message.role) {\n if (message.role === \"user\") {\n merged[merged.length - 1] = {\n role: \"user\",\n content: [...toBlocks(last.content), ...toBlocks(message.content)],\n };\n } else {\n // \u76F8\u90BB assistant\uFF1A\u4FDD\u7559\u540E\u4E00\u6761\uFF0C\u907F\u514D\u63D2\u5165\u7A7A\u7684\u6587\u672C\u5757\n merged[merged.length - 1] = message;\n }\n continue;\n }\n merged.push(message);\n }\n\n while (merged.length > 0 && merged[0].role !== \"user\") {\n merged.shift();\n }\n\n return merged;\n}\n\nfunction safeParse(json: string): Record<string, unknown> {\n try {\n const parsed = JSON.parse(json || \"{}\");\n return typeof parsed === \"object\" && parsed !== null ? parsed : {};\n } catch {\n return {};\n }\n}\n", "import * as http from \"http\";\nimport * as https from \"https\";\n\n/**\n * \u521B\u5EFA\u4E0D\u4F7F\u7528\u8FDE\u63A5\u590D\u7528\u7684 HTTP Agent\u3002\n *\n * \u80CC\u666F\uFF1Aopenai SDK\uFF08node-fetch + agentkeepalive\uFF09\u9ED8\u8BA4\u521B\u5EFA\u4E00\u4E2A\u5168\u5C40\u5171\u4EAB\u3001\n * `keepAlive: true`\u3001`timeout: 5 \u5206\u949F` \u7684\u8FDE\u63A5\u6C60\u3002\u5F53\u7F51\u7EDC\u8DEF\u5F84\u4E0A\u5B58\u5728\u4EE3\u7406\n * \uFF08\u5982\u672C\u5730 Clash / V2Ray\uFF09\u6216\u670D\u52A1\u7AEF\u5728\u7A7A\u95F2\u65F6\u5173\u95ED\u957F\u8FDE\u63A5\u540E\uFF0C\u5BA2\u6237\u7AEF\u590D\u7528\u8FD9\u4E2A\n * \u5DF2\u7ECF\"\u534A\u5173\u95ED\"\u7684 socket\uFF0C\u5C31\u4F1A\u5728\u8BFB\u53D6\u54CD\u5E94\u6D41\u65F6\u629B\u51FA `Premature close`\n * \uFF08Node \u7684 ERR_STREAM_PREMATURE_CLOSE\uFF09\u3002\n *\n * \u7981\u7528 keep-alive \u540E\u6BCF\u6B21\u8BF7\u6C42\u91CD\u5EFA\u8FDE\u63A5\uFF0C\u5F7B\u5E95\u89C4\u907F\u8BE5\u95EE\u9898\u3002\n */\nexport function createNonPoolingAgent(\n targetUrl: string,\n): http.Agent | https.Agent {\n const isHttps = !/^http:\\/\\//i.test(targetUrl);\n const options: http.AgentOptions = { keepAlive: false };\n return isHttps ? new https.Agent(options) : new http.Agent(options);\n}\n\nconst RETRYABLE_CODES = new Set([\n \"ECONNRESET\",\n \"ECONNREFUSED\",\n \"ECONNABORTED\",\n \"ETIMEDOUT\",\n \"EPIPE\",\n \"ENOTFOUND\",\n \"EAI_AGAIN\",\n \"UND_ERR_SOCKET\",\n \"UND_ERR_CONNECT_TIMEOUT\",\n \"ERR_STREAM_PREMATURE_CLOSE\",\n]);\n\nconst RETRYABLE_KEYWORDS = [\n \"premature close\",\n \"socket hang up\",\n \"other side closed\",\n \"fetch failed\",\n \"network error\",\n \"connection error\",\n \"connection reset\",\n \"terminated\",\n \"timeout\",\n];\n\n/**\n * \u5B89\u5168\u5730\u628A\u672A\u77E5\u503C\u8BFB\u4E3A\u5B57\u7B26\u4E32\u3002\n * \u81EA\u5B9A\u4E49\u7AEF\u70B9\uFF08\u5982 llama.cpp / LM Studio / \u5404\u7C7B\u4EE3\u7406\uFF09\u8FD4\u56DE\u7684\u9519\u8BEF\u4F53\u91CC\n * `code` / `status` \u53EF\u80FD\u662F\u6570\u5B57\uFF0C\u76F4\u63A5 `.toUpperCase()` \u4F1A\u629B TypeError\uFF0C\n * \u4ECE\u800C\u628A\u771F\u6B63\u7684\u9519\u8BEF\u539F\u56E0\u63A9\u76D6\u6210 \"xxx is not a function\"\u3002\n */\nfunction asString(value: unknown): string {\n if (typeof value === \"string\") return value;\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n return \"\";\n}\n\n/** \u5B89\u5168\u5730\u628A\u672A\u77E5\u503C\u8BFB\u4E3A HTTP \u72B6\u6001\u7801\uFF08\u517C\u5BB9\u6570\u5B57 / \u6570\u5B57\u5B57\u7B26\u4E32\uFF09 */\nfunction asStatus(value: unknown): number | undefined {\n if (typeof value === \"number\" && Number.isFinite(value)) return value;\n if (typeof value === \"string\") {\n const parsed = Number.parseInt(value, 10);\n if (!Number.isNaN(parsed)) return parsed;\n }\n return undefined;\n}\n\n/** \u5C3D\u53EF\u80FD\u4ECE\u5404\u79CD\u9519\u8BEF\u7ED3\u6784\u91CC\u53D6\u51FA\u53EF\u8BFB\u7684\u539F\u59CB\u4FE1\u606F */\nfunction extractRawMessage(error: unknown): string {\n const err = error as { message?: unknown; error?: unknown; cause?: unknown };\n const direct = asString(err?.message);\n if (direct) return direct;\n\n // OpenAI SDK \u6709\u65F6\u628A\u670D\u52A1\u7AEF\u8FD4\u56DE\u4F53\u6302\u5728 error.error \u4E0A\n const nested = err?.error as { message?: unknown } | undefined;\n const nestedMessage = asString(nested?.message);\n if (nestedMessage) return nestedMessage;\n\n const cause = err?.cause as { message?: unknown } | undefined;\n const causeMessage = asString(cause?.message);\n if (causeMessage) return causeMessage;\n\n if (error instanceof Error && error.message) return error.message;\n try {\n const json = JSON.stringify(error);\n if (json && json !== \"{}\") return json;\n } catch {\n // \u5FFD\u7565\u5E8F\u5217\u5316\u5931\u8D25\n }\n const text = String(error);\n return text === \"[object Object]\" ? \"\u672A\u77E5\u9519\u8BEF\uFF08\u65E0\u6CD5\u89E3\u6790\u9519\u8BEF\u8BE6\u60C5\uFF09\" : text;\n}\n\n/** \u5224\u65AD\u9519\u8BEF\u662F\u5426\u4E3A\u53EF\u91CD\u8BD5\u7684\u77AC\u65F6\u7F51\u7EDC\u9519\u8BEF */\nexport function isRetryableError(error: unknown): boolean {\n const err = error as {\n message?: unknown;\n code?: unknown;\n status?: unknown;\n };\n\n const status = asStatus(err?.status);\n if (status !== undefined) {\n if (status === 408 || status === 409 || status === 429) return true;\n if (status >= 500 && status <= 599) return true;\n if (status >= 400 && status < 500) return false;\n }\n\n const code = asString(err?.code).toUpperCase();\n if (code && RETRYABLE_CODES.has(code)) return true;\n\n // undici / fetch \u4F1A\u628A\u771F\u6B63\u7684\u539F\u56E0\u6302\u5728 cause \u4E0A\uFF08\u5982 ECONNREFUSED\u3001ENOTFOUND\uFF09\uFF0C\n // \u53EA\u770B\u9876\u5C42\u4F1A\u628A\u8FD9\u4E9B\u5F53\u6210\u666E\u901A\u5931\u8D25\u5904\u7406\u3002\n const cause = (err as { cause?: { code?: unknown; message?: unknown } })?.cause;\n const causeCode = asString(cause?.code).toUpperCase();\n if (causeCode && RETRYABLE_CODES.has(causeCode)) return true;\n\n const message = (\n asString(err?.message) ||\n asString(cause?.message) ||\n String(error)\n ).toLowerCase();\n return RETRYABLE_KEYWORDS.some((keyword) => message.includes(keyword));\n}\n\n/** \u628A\u5E95\u5C42\u9519\u8BEF\u8F6C\u6362\u4E3A\u5BF9\u7528\u6237\u53CB\u597D\u7684\u4E2D\u6587\u63D0\u793A */\nexport function friendlyError(error: unknown): string {\n const err = error as {\n message?: unknown;\n code?: unknown;\n status?: unknown;\n };\n const raw = extractRawMessage(error);\n const lower = raw.toLowerCase();\n const code = asString(err?.code).toUpperCase();\n const status = asStatus(err?.status);\n\n if (lower.includes(\"premature close\")) {\n return (\n \"\u8FDE\u63A5\u88AB\u63D0\u524D\u5173\u95ED\uFF08Premature close\uFF09\uFF1A\u7F51\u7EDC\u6216\u4EE3\u7406\u4E2D\u65AD\u4E86\u54CD\u5E94\u6D41\u3002\\n\" +\n \"\u7384\u732A\u5DF2\u81EA\u52A8\u91CD\u8BD5\uFF1B\u82E5\u4ECD\u9891\u7E41\u51FA\u73B0\uFF0C\u901A\u5E38\u662F\u4EE3\u7406/\u7F51\u7EDC\u4E0D\u7A33\u5B9A\u5BFC\u81F4\uFF0C\u53EF\u68C0\u67E5\u4EE3\u7406\u6216\u7A0D\u540E\u518D\u8BD5\u3002\"\n );\n }\n if (code === \"ECONNRESET\" || lower.includes(\"socket hang up\")) {\n return \"\u8FDE\u63A5\u88AB\u5BF9\u7AEF\u91CD\u7F6E\uFF08ECONNRESET\uFF09\uFF1A\u7F51\u7EDC\u6216\u4EE3\u7406\u4E2D\u65AD\u4E86\u8FDE\u63A5\uFF0C\u8BF7\u91CD\u8BD5\u3002\";\n }\n if (code === \"ETIMEDOUT\" || lower.includes(\"timed out\")) {\n return \"\u8BF7\u6C42\u8D85\u65F6\uFF1A\u7F51\u7EDC\u8F83\u6162\u6216\u6A21\u578B\u670D\u52A1\u672A\u54CD\u5E94\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002\";\n }\n if (code === \"ENOTFOUND\" || code === \"EAI_AGAIN\") {\n return \"\u65E0\u6CD5\u89E3\u6790\u670D\u52A1\u5730\u5740\uFF1A\u8BF7\u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5\u4E0E\u4EE3\u7406\u8BBE\u7F6E\uFF08DNS \u53EF\u80FD\u88AB\u62E6\u622A\uFF09\u3002\";\n }\n if (code === \"ECONNREFUSED\") {\n return \"\u8FDE\u63A5\u88AB\u62D2\u7EDD\uFF1A\u76EE\u6807\u5730\u5740\u6216\u7AEF\u53E3\u4E0D\u53EF\u8FBE\uFF0C\u8BF7\u68C0\u67E5 baseUrl \u4E0E\u4EE3\u7406\u8BBE\u7F6E\u3002\";\n }\n if (\n status === 401 ||\n lower.includes(\"unauthorized\") ||\n lower.includes(\"invalid api key\") ||\n lower.includes(\"authentication\")\n ) {\n return \"\u8BA4\u8BC1\u5931\u8D25\uFF1AAPI Key \u65E0\u6548\u6216\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u8FD0\u884C `xzh model` \u91CD\u65B0\u914D\u7F6E\u3002\";\n }\n if (status === 403) {\n return \"\u8BBF\u95EE\u88AB\u62D2\u7EDD\uFF08403\uFF09\uFF1A\u8BF7\u68C0\u67E5 API Key \u6743\u9650\u6216\u670D\u52A1\u5546\u533A\u57DF\u9650\u5236\u3002\";\n }\n if (\n status === 402 ||\n lower.includes(\"insufficient\") ||\n lower.includes(\"balance\")\n ) {\n return \"\u8D26\u6237\u989D\u5EA6\u4E0D\u8DB3\uFF1A\u8BF7\u68C0\u67E5\u670D\u52A1\u5546\u4F59\u989D\u6216\u914D\u989D\u3002\";\n }\n if (status === 429 || lower.includes(\"rate limit\")) {\n return \"\u8BF7\u6C42\u8FC7\u4E8E\u9891\u7E41\uFF08\u9650\u6D41\uFF09\uFF1A\u8BF7\u7A0D\u540E\u518D\u8BD5\u3002\";\n }\n // \u670D\u52A1\u7AEF\u8D44\u6E90\u7C7B\u9519\u8BEF\uFF08\u663E\u5B58 / \u5185\u5B58\u4E0D\u8DB3\uFF09\u2014\u2014llama.cpp\u3001LM Studio \u7B49\u672C\u5730\u540E\u7AEF\u5E38\u89C1\u3002\n // \u660E\u786E\u6807\u6CE8\u6765\u6E90\u4E0E\u5904\u7406\u65B9\u5411\uFF0C\u907F\u514D\u7528\u6237\u8BEF\u4EE5\u4E3A\u662F\u7384\u732A\uFF08\u5BA2\u6237\u7AEF\uFF09\u7684\u95EE\u9898\u3002\n if (\n /out\\s*of\\s*(device\\s*)?memory|outofdevicememory|outofmemory|vk::|cuda.*error|hip.*error|cannot allocate|insufficient memory/i.test(\n raw,\n )\n ) {\n return (\n `${raw}\\n` +\n \"\u4EE5\u4E0A\u662F\u6A21\u578B\u670D\u52A1\u7AEF\uFF08llama.cpp / LM Studio \u7B49\uFF09\u62A5\u51FA\u7684\u8D44\u6E90\u9519\u8BEF\uFF1A\u663E\u5B58\u6216\u5185\u5B58\u4E0D\u8DB3\uFF0C\u4E0E\u7384\u732A\u65E0\u5173\u3002\\n\" +\n \"\u53EF\u5C1D\u8BD5\uFF1A\u51CF\u5C0F\u4E0A\u4E0B\u6587\u957F\u5EA6\uFF08llama.cpp \u7684 -c\uFF0C\u4F8B\u5982 -c 8192\uFF09\u3001\u964D\u4F4E KV cache \u7CBE\u5EA6\\n\" +\n \"\uFF08--cache-type-k q8_0 --cache-type-v q8_0\uFF09\u3001\u51CF\u5C11 GPU \u5378\u8F7D\u5C42\u6570\uFF08-ngl\uFF09\u3001\\n\" +\n \"\u6362\u66F4\u5C0F\u7684\u6A21\u578B / \u91CF\u5316\uFF0C\u6216\u5148\u91CA\u653E\u88AB\u5176\u4ED6\u8FDB\u7A0B\u5360\u7528\u7684\u663E\u5B58\u3002\\n\" +\n \"\u4FEE\u597D\u670D\u52A1\u7AEF\u540E\u53EF\u7528 `xzh model reset` \u628A\u88AB\u964D\u6389\u7684\u6743\u91CD\u6062\u590D\u4E3A\u9ED8\u8BA4\u503C\u3002\"\n );\n }\n if (typeof status === \"number\" && status >= 500) {\n return `\u6A21\u578B\u670D\u52A1\u7AEF\u9519\u8BEF\uFF08HTTP ${status}\uFF09\uFF1A\u670D\u52A1\u6682\u65F6\u4E0D\u53EF\u7528\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002`;\n }\n if (status === 400) {\n // \u53BB\u6389 SDK \u62FC\u5728 message \u524D\u7684\u91CD\u590D\u72B6\u6001\u7801\n const detail = raw.replace(/^4\\d\\d\\s*/, \"\");\n const hint = /model/i.test(detail)\n ? \"\\n\u63D0\u793A\uFF1A\u591A\u534A\u662F\u6A21\u578B\u540D\u4E0D\u88AB\u8BE5\u7AEF\u70B9\u652F\u6301\u3002\u53EF\u7528 `curl <baseUrl>/models` \u67E5\u770B\u7AEF\u70B9\u652F\u6301\u7684\u6A21\u578B id\uFF0C\" +\n \"\u518D\u7528 `xzh model weight <id> 10` \u540E\u7684 `xzh model` \u66F4\u6B63\u6A21\u578B\u540D\u3002\"\n : \"\";\n return `\u8BF7\u6C42\u88AB\u62D2\u7EDD\uFF08HTTP 400\uFF09\uFF1A${detail}${hint}`;\n }\n if (lower.includes(\"fetch failed\") || lower.includes(\"network\")) {\n return `\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25\uFF1A${raw}`;\n }\n return raw;\n}\n\nexport function delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n", "import {\n GoogleGenerativeAI,\n SchemaType,\n type Content,\n type FunctionDeclaration,\n type FunctionDeclarationSchema,\n type Part,\n type Tool,\n} from \"@google/generative-ai\";\nimport { delay, isRetryableError } from \"./http\";\nimport type {\n ChatMessage,\n ChatOptions,\n JsonSchema,\n LLMProvider,\n StreamChunk,\n Usage,\n} from \"./types\";\n\nexport interface GeminiConfig {\n id: string;\n apiKey: string;\n baseUrl?: string;\n model: string;\n}\n\nconst MAX_ATTEMPTS = 3;\n\n/** Google Gemini Provider\uFF08\u6D41\u5F0F + function calling\uFF0C\u542B\u77AC\u65F6\u9519\u8BEF\u91CD\u8BD5\uFF09 */\nexport class GeminiProvider implements LLMProvider {\n public readonly id: string;\n public readonly model: string;\n private readonly apiKey: string;\n /** \u81EA\u5B9A\u4E49\u7AEF\u70B9\uFF08\u4EE3\u7406 / \u81EA\u5EFA\u7F51\u5173\uFF09\uFF1B\u6B64\u524D\u88AB\u8BFB\u53D6\u4F46\u4ECE\u672A\u4F20\u7ED9 SDK\uFF0C\u914D\u7F6E\u9759\u9ED8\u5931\u6548 */\n private readonly baseUrl?: string;\n\n constructor(config: GeminiConfig) {\n this.id = config.id;\n this.model = config.model;\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl;\n }\n\n async *chat(options: ChatOptions): AsyncIterable<StreamChunk> {\n let lastError: unknown;\n\n for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {\n let emitted = false;\n try {\n yield* this.streamOnce(options, () => {\n emitted = true;\n });\n return;\n } catch (error) {\n lastError = error;\n if (\n emitted ||\n options.signal?.aborted ||\n attempt >= MAX_ATTEMPTS ||\n !isRetryableError(error)\n ) {\n throw error;\n }\n options.onRetry?.(\n attempt,\n MAX_ATTEMPTS,\n error instanceof Error ? error : new Error(String(error)),\n );\n await delay(attempt * 600);\n }\n }\n\n throw lastError;\n }\n\n private async *streamOnce(\n options: ChatOptions,\n markEmitted: () => void,\n ): AsyncIterable<StreamChunk> {\n const genAI = new GoogleGenerativeAI(this.apiKey);\n const { system, contents } = toGeminiContents(options.messages);\n const tools: Tool[] | undefined =\n options.tools.length > 0\n ? [{ functionDeclarations: options.tools.map(toFunctionDeclaration) }]\n : undefined;\n\n const model = genAI.getGenerativeModel(\n {\n model: this.model,\n systemInstruction: system || undefined,\n tools,\n generationConfig: {\n temperature: options.temperature,\n },\n },\n // \u4F20\u5165 requestOptions\uFF1A\u8BA9\u914D\u7F6E\u7684 baseUrl \u4E0E\u4E2D\u65AD\u4FE1\u53F7\u771F\u6B63\u751F\u6548\n {\n ...(this.baseUrl ? { baseUrl: this.baseUrl } : {}),\n ...(options.signal ? { signal: options.signal } : {}),\n },\n );\n\n const result = await model.generateContentStream({ contents });\n\n let usage: Usage | undefined;\n let sawToolCall = false;\n let callIndex = 0;\n\n for await (const chunk of result.stream) {\n // SDK \u4E0D\u4E00\u5B9A\u628A signal \u4F20\u5230\u6D41\u6D88\u8D39\u5C42\uFF0C\u8FD9\u91CC\u515C\u5E95\uFF1A\u4E2D\u65AD\u540E\u7ACB\u5373\u505C\u6B62\u8BFB\u53D6\n if (options.signal?.aborted) break;\n const text = safeText(chunk);\n if (text) {\n markEmitted();\n yield { type: \"text\", text };\n }\n\n const calls = safeFunctionCalls(chunk);\n for (const call of calls) {\n sawToolCall = true;\n markEmitted();\n yield {\n type: \"tool_call\",\n toolCall: {\n id: `gemini_call_${Date.now()}_${callIndex++}`,\n name: call.name,\n arguments: JSON.stringify(call.args ?? {}),\n },\n };\n }\n\n const meta = chunk.usageMetadata;\n if (meta) {\n usage = {\n inputTokens: meta.promptTokenCount,\n outputTokens: meta.candidatesTokenCount,\n };\n }\n }\n\n if (sawToolCall) markEmitted();\n yield {\n type: \"done\",\n finishReason: sawToolCall ? \"tool_calls\" : \"stop\",\n usage,\n };\n }\n}\n\ninterface GeminiFunctionCall {\n name: string;\n args: Record<string, unknown>;\n}\n\nfunction safeText(chunk: unknown): string {\n try {\n return (chunk as { text: () => string }).text() ?? \"\";\n } catch {\n return \"\";\n }\n}\n\nfunction safeFunctionCalls(chunk: unknown): GeminiFunctionCall[] {\n try {\n const calls = (\n chunk as { functionCalls?: () => GeminiFunctionCall[] }\n ).functionCalls?.();\n return calls ?? [];\n } catch {\n return [];\n }\n}\n\nfunction toGeminiContents(messages: ChatMessage[]): {\n system: string;\n contents: Content[];\n} {\n const systemParts: string[] = [];\n const contents: Content[] = [];\n\n for (const message of messages) {\n if (message.role === \"system\") {\n systemParts.push(message.content);\n continue;\n }\n\n if (message.role === \"user\") {\n contents.push({ role: \"user\", parts: [{ text: message.content }] });\n continue;\n }\n\n if (message.role === \"assistant\") {\n const parts: Part[] = [];\n if (message.content) parts.push({ text: message.content });\n for (const call of message.toolCalls ?? []) {\n parts.push({\n functionCall: {\n name: call.name,\n args: safeParse(call.arguments),\n },\n });\n }\n if (parts.length > 0) contents.push({ role: \"model\", parts });\n continue;\n }\n\n if (message.role === \"tool\") {\n const response: Part = {\n functionResponse: {\n name: message.name ?? \"unknown\",\n response: { result: message.content },\n },\n };\n const last = contents[contents.length - 1];\n if (\n last &&\n last.role === \"user\" &&\n last.parts?.some((p) => \"functionResponse\" in p)\n ) {\n last.parts.push(response);\n } else {\n contents.push({ role: \"user\", parts: [response] });\n }\n }\n }\n\n return {\n system: systemParts.join(\"\\n\\n\"),\n contents: normalizeContents(contents),\n };\n}\n\n/**\n * \u5408\u5E76\u76F8\u90BB\u7684\u540C role \u6D88\u606F\u3002\n * \u5386\u53F2\u88C1\u526A\u540E\u53EF\u80FD\u4EE5 model \u5F00\u5934\uFF0C\u4E0A\u4E00\u8F6E\u8BF7\u6C42\u5931\u8D25\u65F6\u4E5F\u53EF\u80FD\u7559\u4E0B\u8FDE\u7EED\u4E24\u6761 user \u2014\u2014\n * Gemini \u8981\u6C42 user / model \u4EA4\u66FF\uFF0C\u8FD9\u7C7B\u5E8F\u5217\u4F1A\u88AB\u5224\u4E3A\u975E\u6CD5\u8BF7\u6C42\u3002\n */\nfunction normalizeContents(contents: Content[]): Content[] {\n const merged: Content[] = [];\n for (const content of contents) {\n const last = merged[merged.length - 1];\n if (last && last.role === content.role) {\n last.parts = [...(last.parts ?? []), ...(content.parts ?? [])];\n continue;\n }\n merged.push({ role: content.role, parts: [...(content.parts ?? [])] });\n }\n while (merged.length > 0 && merged[0].role !== \"user\") {\n merged.shift();\n }\n return merged;\n}\n\nfunction toFunctionDeclaration(tool: {\n name: string;\n description: string;\n parameters: JsonSchema;\n}): FunctionDeclaration {\n return {\n name: tool.name,\n description: tool.description,\n parameters: toGeminiSchema(\n tool.parameters,\n ) as unknown as FunctionDeclarationSchema,\n };\n}\n\nfunction toGeminiSchema(schema: JsonSchema): Record<string, unknown> {\n const result: Record<string, unknown> = {\n type: normalizeType(schema.type),\n };\n if (schema.description) result.description = schema.description;\n if (schema.enum) result.enum = schema.enum;\n if (schema.required) result.required = schema.required;\n if (schema.items) result.items = toGeminiSchema(schema.items);\n if (schema.properties) {\n const props: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(schema.properties)) {\n props[key] = toGeminiSchema(value);\n }\n result.properties = props;\n }\n return result;\n}\n\nfunction normalizeType(type: string): SchemaType {\n switch (type.toLowerCase()) {\n case \"string\":\n return SchemaType.STRING;\n case \"number\":\n return SchemaType.NUMBER;\n case \"integer\":\n return SchemaType.INTEGER;\n case \"boolean\":\n return SchemaType.BOOLEAN;\n case \"array\":\n return SchemaType.ARRAY;\n default:\n return SchemaType.OBJECT;\n }\n}\n\nfunction safeParse(json: string): Record<string, unknown> {\n try {\n const parsed = JSON.parse(json || \"{}\");\n return typeof parsed === \"object\" && parsed !== null ? parsed : {};\n } catch {\n return {};\n }\n}\n", "import OpenAI from \"openai\";\nimport type {\n ChatCompletionMessageParam,\n ChatCompletionTool,\n} from \"openai/resources/chat/completions\";\nimport { createNonPoolingAgent, delay, isRetryableError } from \"./http\";\nimport type {\n ChatOptions,\n ChatMessage,\n LLMProvider,\n StreamChunk,\n ToolCall,\n ToolSpec,\n Usage,\n} from \"./types\";\n\nexport interface OpenAICompatConfig {\n id: string;\n apiKey: string;\n baseUrl?: string;\n model: string;\n}\n\nconst MAX_ATTEMPTS = 3;\n\n/**\n * OpenAI \u517C\u5BB9\u534F\u8BAE Provider\u3002\n * \u9002\u7528\u4E8E OpenAI / DeepSeek / GLM / Qwen / Groq / Ollama / \u4EFB\u610F\u517C\u5BB9\u7AEF\u70B9\u3002\n *\n * \u9488\u5BF9 \"Premature close\" \u7684\u5904\u7406\uFF1A\n * 1. \u4F7F\u7528 `keepAlive: false` \u7684 Agent\uFF0C\u907F\u514D\u590D\u7528\u5DF2\u88AB\u5173\u95ED\u7684\u957F\u8FDE\u63A5\uFF1B\n * 2. \u4E0D\u5728\u8BF7\u6C42\u4E2D\u5F3A\u5236\u53D1\u9001 `stream_options`\uFF08\u90E8\u5206\u517C\u5BB9\u7AEF\u70B9\u4E0D\u652F\u6301\u4F1A\u5BFC\u81F4\u8FDE\u63A5\u5F02\u5E38\uFF09\uFF1B\n * 3. \u5728\u5C1A\u672A\u4EA7\u751F\u4EFB\u4F55\u8F93\u51FA\u524D\uFF0C\u5BF9\u77AC\u65F6\u7F51\u7EDC\u9519\u8BEF\u81EA\u52A8\u91CD\u8BD5\u3002\n */\nexport class OpenAICompatProvider implements LLMProvider {\n public readonly id: string;\n public readonly model: string;\n private readonly client: OpenAI;\n\n constructor(config: OpenAICompatConfig) {\n this.id = config.id;\n this.model = config.model;\n const targetUrl = config.baseUrl || \"https://api.openai.com/v1\";\n this.client = new OpenAI({\n apiKey: config.apiKey || \"not-needed\",\n baseURL: config.baseUrl,\n httpAgent: createNonPoolingAgent(targetUrl),\n });\n }\n\n async *chat(options: ChatOptions): AsyncIterable<StreamChunk> {\n let lastError: unknown;\n\n for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {\n // emitted \u6807\u8BB0\uFF1A\u4E00\u65E6\u5411\u8C03\u7528\u65B9\u8F93\u51FA\u4E86\u5185\u5BB9\uFF0C\u5C31\u4E0D\u518D\u91CD\u8BD5\uFF0C\u907F\u514D\u91CD\u590D\u8F93\u51FA\n let emitted = false;\n\n try {\n yield* this.streamOnce(options, () => {\n emitted = true;\n });\n return;\n } catch (error) {\n lastError = error;\n if (\n emitted ||\n options.signal?.aborted ||\n attempt >= MAX_ATTEMPTS ||\n !isRetryableError(error)\n ) {\n throw error;\n }\n options.onRetry?.(\n attempt,\n MAX_ATTEMPTS,\n error instanceof Error ? error : new Error(String(error)),\n );\n await delay(attempt * 600);\n }\n }\n\n throw lastError;\n }\n\n private async *streamOnce(\n options: ChatOptions,\n markEmitted: () => void,\n ): AsyncIterable<StreamChunk> {\n const messages = options.messages.map(toOpenAIMessage);\n const tools: ChatCompletionTool[] | undefined =\n options.tools.length > 0\n ? options.tools.map(toOpenAITool)\n : undefined;\n\n const stream = await this.client.chat.completions.create(\n {\n model: this.model,\n messages,\n tools,\n temperature: options.temperature,\n stream: true,\n },\n { signal: options.signal },\n );\n\n // \u6D41\u5F0F tool_calls \u9700\u8981\u6309 index \u5206\u7247\u7D2F\u52A0\n const buffers = new Map<\n number,\n { id: string; name: string; args: string }\n >();\n let finishReason: string | undefined;\n let usage: Usage | undefined;\n let sawToolCall = false;\n\n for await (const chunk of stream) {\n if (chunk.usage) {\n usage = {\n inputTokens: chunk.usage.prompt_tokens,\n outputTokens: chunk.usage.completion_tokens,\n };\n }\n\n const choice = chunk.choices?.[0];\n if (!choice) continue;\n\n const delta = choice.delta as Record<string, unknown> | undefined;\n if (delta) {\n const text = delta.content;\n if (typeof text === \"string\" && text.length > 0) {\n markEmitted();\n yield { type: \"text\", text };\n }\n\n const reasoning = delta.reasoning_content;\n if (typeof reasoning === \"string\" && reasoning.length > 0) {\n markEmitted();\n yield { type: \"reasoning\", text: reasoning };\n }\n\n const toolCalls = delta.tool_calls as\n | Array<{\n index?: number;\n id?: string;\n function?: { name?: string; arguments?: string };\n }>\n | undefined;\n if (toolCalls) {\n sawToolCall = true;\n for (const tc of toolCalls) {\n const index = tc.index ?? 0;\n const buf = buffers.get(index) ?? { id: \"\", name: \"\", args: \"\" };\n if (tc.id) buf.id = tc.id;\n if (tc.function?.name) buf.name += tc.function.name;\n if (tc.function?.arguments) buf.args += tc.function.arguments;\n buffers.set(index, buf);\n }\n }\n }\n\n if (choice.finish_reason) {\n finishReason = choice.finish_reason;\n }\n }\n\n for (const [index, buf] of buffers) {\n if (!buf.name) continue;\n const call: ToolCall = {\n id: buf.id || `call_${Date.now()}_${index}`,\n name: buf.name,\n arguments: buf.args || \"{}\",\n };\n markEmitted();\n yield { type: \"tool_call\", toolCall: call };\n }\n\n if (sawToolCall) markEmitted();\n yield {\n type: \"done\",\n finishReason: sawToolCall ? \"tool_calls\" : finishReason,\n usage,\n };\n }\n}\n\nfunction toOpenAIMessage(message: ChatMessage): ChatCompletionMessageParam {\n switch (message.role) {\n case \"system\":\n return { role: \"system\", content: message.content };\n case \"user\":\n return { role: \"user\", content: message.content };\n case \"assistant\": {\n if (message.toolCalls && message.toolCalls.length > 0) {\n return {\n role: \"assistant\",\n content: message.content || null,\n tool_calls: message.toolCalls.map((call) => ({\n id: call.id,\n type: \"function\" as const,\n function: { name: call.name, arguments: call.arguments },\n })),\n };\n }\n return { role: \"assistant\", content: message.content };\n }\n case \"tool\":\n return {\n role: \"tool\",\n content: message.content,\n tool_call_id: message.toolCallId ?? \"\",\n };\n default:\n return { role: \"user\", content: message.content };\n }\n}\n\nfunction toOpenAITool(tool: ToolSpec): ChatCompletionTool {\n return {\n type: \"function\",\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters as Record<string, unknown>,\n },\n };\n}\n", "import {\n effectiveModels,\n type ModelEntry,\n type XuanZhuConfig,\n} from \"../config/store\";\nimport { AnthropicProvider } from \"./anthropic\";\nimport { GeminiProvider } from \"./gemini\";\nimport { OpenAICompatProvider } from \"./openai-compat\";\nimport type { LLMProvider } from \"./types\";\n\nexport * from \"./types\";\nexport { friendlyError, isRetryableError } from \"./http\";\n\nexport type ProviderKind = \"openai\" | \"anthropic\" | \"gemini\";\n\nexport interface ProviderMeta {\n id: string;\n label: string;\n kind: ProviderKind;\n defaultBaseUrl?: string;\n defaultModel: string;\n /** \u4F9B `xzh model` \u5C55\u793A\u7684\u53EF\u9009\u6A21\u578B\u5217\u8868 */\n models: string[];\n requiresApiKey: boolean;\n /** \u4ECE\u54EA\u4E2A\u73AF\u5883\u53D8\u91CF\u8BFB\u53D6 API Key */\n envKey: string;\n apiKeyHint?: string;\n /** \u662F\u5426\u9700\u8981\u7528\u6237\u624B\u586B baseUrl\uFF08\u5982\u81EA\u5B9A\u4E49\u7AEF\u70B9\uFF09 */\n requiresBaseUrl?: boolean;\n}\n\nexport const PROVIDERS: ProviderMeta[] = [\n {\n id: \"deepseek\",\n label: \"DeepSeek \u6DF1\u5EA6\u6C42\u7D22\",\n kind: \"openai\",\n defaultBaseUrl: \"https://api.deepseek.com/v1\",\n defaultModel: \"deepseek-chat\",\n models: [\"deepseek-chat\", \"deepseek-reasoner\"],\n requiresApiKey: true,\n envKey: \"DEEPSEEK_API_KEY\",\n apiKeyHint: \"sk-...\",\n },\n {\n id: \"anthropic\",\n label: \"Anthropic Claude\",\n kind: \"anthropic\",\n defaultModel: \"claude-sonnet-4-5\",\n models: [\n \"claude-sonnet-4-5\",\n \"claude-opus-4-1\",\n \"claude-3-5-haiku-latest\",\n ],\n requiresApiKey: true,\n envKey: \"ANTHROPIC_API_KEY\",\n apiKeyHint: \"sk-ant-...\",\n },\n {\n id: \"openai\",\n label: \"OpenAI\",\n kind: \"openai\",\n defaultBaseUrl: \"https://api.openai.com/v1\",\n defaultModel: \"gpt-4o\",\n models: [\"gpt-4o\", \"gpt-4o-mini\", \"o4-mini\"],\n requiresApiKey: true,\n envKey: \"OPENAI_API_KEY\",\n apiKeyHint: \"sk-...\",\n },\n {\n id: \"gemini\",\n label: \"Google Gemini\",\n kind: \"gemini\",\n defaultModel: \"gemini-2.0-flash\",\n models: [\"gemini-2.0-flash\", \"gemini-2.5-pro\", \"gemini-2.5-flash\"],\n requiresApiKey: true,\n envKey: \"GEMINI_API_KEY\",\n apiKeyHint: \"AIza...\",\n },\n {\n id: \"glm\",\n label: \"\u667A\u8C31 GLM\",\n kind: \"openai\",\n defaultBaseUrl: \"https://open.bigmodel.cn/api/paas/v4\",\n defaultModel: \"glm-4-plus\",\n models: [\"glm-4-plus\", \"glm-4-air\", \"glm-4-flash\"],\n requiresApiKey: true,\n envKey: \"GLM_API_KEY\",\n },\n {\n id: \"qwen\",\n label: \"\u901A\u4E49\u5343\u95EE Qwen\",\n kind: \"openai\",\n defaultBaseUrl: \"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n defaultModel: \"qwen-max\",\n models: [\"qwen-max\", \"qwen-plus\", \"qwen2.5-coder-32b-instruct\"],\n requiresApiKey: true,\n envKey: \"DASHSCOPE_API_KEY\",\n },\n {\n id: \"groq\",\n label: \"Groq\",\n kind: \"openai\",\n defaultBaseUrl: \"https://api.groq.com/openai/v1\",\n defaultModel: \"llama-3.3-70b-versatile\",\n models: [\"llama-3.3-70b-versatile\", \"qwen-2.5-coder-32b\"],\n requiresApiKey: true,\n envKey: \"GROQ_API_KEY\",\n apiKeyHint: \"gsk_...\",\n },\n {\n id: \"ollama\",\n label: \"Ollama\uFF08\u672C\u5730\uFF09\",\n kind: \"openai\",\n defaultBaseUrl: \"http://localhost:11434/v1\",\n defaultModel: \"qwen2.5-coder\",\n models: [\"qwen2.5-coder\", \"llama3.1\", \"deepseek-coder-v2\"],\n requiresApiKey: false,\n envKey: \"OLLAMA_API_KEY\",\n },\n {\n id: \"custom\",\n label: \"\u81EA\u5B9A\u4E49\uFF08OpenAI \u517C\u5BB9\u7AEF\u70B9\uFF09\",\n kind: \"openai\",\n defaultModel: \"\",\n models: [],\n requiresApiKey: false,\n requiresBaseUrl: true,\n envKey: \"XUANZHU_API_KEY\",\n },\n];\n\nexport function findProvider(id: string): ProviderMeta | undefined {\n return PROVIDERS.find((p) => p.id === id);\n}\n\nexport function resolveApiKey(meta: ProviderMeta, apiKey?: string): string {\n return apiKey || (meta.envKey ? process.env[meta.envKey] ?? \"\" : \"\");\n}\n\nexport function resolveBaseUrl(\n meta: ProviderMeta,\n baseUrl?: string,\n): string | undefined {\n return baseUrl || meta.defaultBaseUrl;\n}\n\n/** \u6821\u9A8C\u5355\u4E2A\u6A21\u578B\u6761\u76EE\u662F\u5426\u53EF\u7528\u4E8E\u8BF7\u6C42\uFF0C\u8FD4\u56DE\u95EE\u9898\u5217\u8868 */\nexport function validateModelEntry(\n config: XuanZhuConfig,\n entry: ModelEntry,\n): string[] {\n const problems: string[] = [];\n const meta = findProvider(entry.provider);\n if (!meta) {\n return [`\u6A21\u578B ${entry.id} \u4F7F\u7528\u4E86\u672A\u77E5 provider\uFF1A${entry.provider}`];\n }\n const settings = config.providers[entry.provider] ?? {};\n if (\n meta.requiresApiKey &&\n !resolveApiKey(meta, entry.apiKey ?? settings.apiKey)\n ) {\n problems.push(\n `\u6A21\u578B ${entry.id} \u7F3A\u5C11 API Key\uFF0C\u8BF7\u8FD0\u884C \\`xzh model\\` \u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF ${meta.envKey}`,\n );\n }\n if (\n meta.requiresBaseUrl &&\n !resolveBaseUrl(meta, entry.baseUrl ?? settings.baseUrl)\n ) {\n problems.push(`\u6A21\u578B ${entry.id} \u9700\u8981\u914D\u7F6E baseUrl`);\n }\n if (!entry.model) {\n problems.push(`\u6A21\u578B ${entry.id} \u672A\u6307\u5B9A\u6A21\u578B\u540D`);\n }\n return problems;\n}\n\n/** \u6821\u9A8C\u5168\u90E8\u5DF2\u914D\u7F6E\u6A21\u578B\uFF0C\u8FD4\u56DE\u95EE\u9898\u5217\u8868\uFF08\u7528\u4E8E\u6574\u4F53\u4F53\u68C0\u4E0E\u63D0\u793A\uFF09 */\nexport function validateProviderConfig(config: XuanZhuConfig): string[] {\n const models = effectiveModels(config);\n if (models.length === 0) {\n return [\"\u5C1A\u672A\u914D\u7F6E\u4EFB\u4F55\u6A21\u578B\uFF0C\u8BF7\u8FD0\u884C `xzh model add` \u6DFB\u52A0\"];\n }\n return models.flatMap((entry) => validateModelEntry(config, entry));\n}\n\n/**\n * \u6839\u636E\u914D\u7F6E\u521B\u5EFA Provider \u5B9E\u4F8B\u3002\n * \u4F20\u5165 `entry` \u65F6\u6309\u8BE5\u6A21\u578B\u6761\u76EE\u521B\u5EFA\uFF08\u591A\u6A21\u578B / \u964D\u7EA7\u5207\u6362\u573A\u666F\uFF09\uFF1B\n * \u5426\u5219\u6CBF\u7528 config.provider \u4E0E config.model\uFF08\u5355\u6A21\u578B\u517C\u5BB9\u8DEF\u5F84\uFF09\u3002\n */\nexport function createProvider(\n config: XuanZhuConfig,\n entry?: ModelEntry,\n): LLMProvider {\n const providerId = entry?.provider ?? config.provider;\n const meta = findProvider(providerId);\n if (!meta) {\n throw new Error(`\u672A\u77E5\u7684 provider\uFF1A${providerId}`);\n }\n const settings = config.providers[providerId] ?? {};\n const apiKey = resolveApiKey(meta, entry?.apiKey ?? settings.apiKey);\n const baseUrl = resolveBaseUrl(meta, entry?.baseUrl ?? settings.baseUrl);\n const model =\n entry?.model || settings.model || config.model || meta.defaultModel;\n\n // \u81EA\u5B9A\u4E49\u7AEF\u70B9\u5FC5\u987B\u6821\u9A8C baseUrl\uFF1A\u5426\u5219 OpenAICompatProvider \u4F1A\u9759\u9ED8\u56DE\u9000\u5230\n // https://api.openai.com/v1\uFF0C\u628A\u8BF7\u6C42\u53D1\u5230\u9519\u8BEF\u7684\u670D\u52A1\u4E0A\uFF08\u964D\u7EA7\u5207\u6362\u65F6\u540C\u6837\u8981\u62E6\u4F4F\uFF09\u3002\n if (meta.requiresBaseUrl && !baseUrl) {\n throw new Error(\n `provider \"${meta.label}\" \u9700\u8981\u914D\u7F6E API \u7AEF\u70B9 baseUrl\u3002\u8FD0\u884C \\`xzh model\\` \u8865\u9F50\u540E\u518D\u8BD5\u3002`,\n );\n }\n if (meta.requiresApiKey && !apiKey) {\n throw new Error(\n `provider \"${meta.label}\" \u7F3A\u5C11 API Key\u3002\u8FD0\u884C \\`xzh model\\` \u8FDB\u884C\u914D\u7F6E\uFF0C\u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF ${meta.envKey}\u3002`,\n );\n }\n if (!model) {\n throw new Error(`provider \"${meta.label}\" \u672A\u6307\u5B9A\u6A21\u578B\u3002\u8FD0\u884C \\`xzh model\\` \u9009\u62E9\u6A21\u578B\u3002`);\n }\n\n switch (meta.kind) {\n case \"anthropic\":\n return new AnthropicProvider({ id: meta.id, apiKey, baseUrl, model });\n case \"gemini\":\n return new GeminiProvider({ id: meta.id, apiKey, baseUrl, model });\n case \"openai\":\n default:\n return new OpenAICompatProvider({\n id: meta.id,\n apiKey,\n baseUrl,\n model,\n });\n }\n}\n", "import * as fs from \"fs\";\nimport * as path from \"path\";\nimport { Agent, type AgentEvents } from \"../core/agent\";\nimport {\n effectiveModels,\n saveConfig,\n type ModelEntry,\n type XuanZhuConfig,\n} from \"../config/store\";\nimport { findProvider } from \"../llm\";\nimport { friendlyError } from \"../llm/http\";\nimport type { LLMProvider, ToolCall } from \"../llm/types\";\nimport type { ExecuteToolResult } from \"../tools\";\nimport type { ConfirmRequest } from \"../tools/types\";\nimport { expandHome } from \"../utils/paths\";\nimport { ensureProjectDir } from \"../workspace\";\nimport {\n ansi,\n cursor,\n padEnd,\n screen,\n textWidth,\n truncate,\n wrapText,\n} from \"../utils/ansi\";\nimport { MarkdownRenderer } from \"./markdown\";\nimport { completeTermInput, ShellPanel } from \"./terminal\";\n\nexport interface TuiAppOptions {\n provider: LLMProvider;\n config: XuanZhuConfig;\n cwd: string;\n providerLabel: string;\n model: string;\n /** \u5F53\u524D\u6A21\u578B\u7684\u8C03\u7528\u6743\u91CD\uFF08\u591A\u6A21\u578B\u6743\u91CD\u673A\u5236\uFF09 */\n modelWeight?: number;\n /** \u542F\u52A8\u65F6\u9009\u4E2D\u7684\u6A21\u578B\u6761\u76EE\uFF0C\u4EA4\u7531 Agent \u505A\u5931\u8D25\u964D\u7EA7\u5207\u6362 */\n activeModel?: ModelEntry | null;\n /**\n * \u662F\u5426\u542F\u7528\u610F\u56FE\u5206\u6790\u3002\u7F3A\u7701\u65F6\u8BFB\u53D6\u914D\u7F6E\u4E2D\u7684 `intent.enabled`\uFF1B\n * CLI \u7684 `--intent` / `--no-intent` \u4F1A\u5728\u6B64\u7ED9\u51FA\u663E\u5F0F\u8986\u76D6\u503C\uFF08\u4E0D\u5199\u56DE\u914D\u7F6E\uFF09\u3002\n */\n intentEnabled?: boolean;\n autoApprove: boolean;\n}\n\ninterface PendingConfirm {\n request: ConfirmRequest;\n resolve: (approved: boolean) => void;\n selected: boolean;\n}\n\ninterface InputLayout {\n lines: string[];\n cursorRow: number;\n cursorCol: number;\n}\n\n/** \u7384\u732A\u5168\u5C4F\u7EC8\u7AEF\u754C\u9762 */\nexport class TuiApp {\n private readonly options: TuiAppOptions;\n private readonly agent: Agent;\n private readonly markdown = new MarkdownRenderer();\n private cwd: string;\n\n /** \u5F53\u524D\u6A21\u578B\uFF08\u53EF\u80FD\u56E0\u5931\u8D25\u964D\u7EA7\u800C\u5207\u6362\uFF09 */\n private modelProviderLabel: string;\n private modelLabel: string;\n private modelWeight?: number;\n\n private lines: string[] = [];\n private input = \"\";\n private inputCursor = 0;\n private scrollOffset = 0;\n private statusText = \"\u5C31\u7EEA\";\n private statusDetail = \"\";\n private busy = false;\n private exited = false;\n private autoApprove: boolean;\n /** \u662F\u5426\u542F\u7528\u610F\u56FE\u5206\u6790\uFF08\u754C\u9762\u5185\u7528 /intent \u5207\u6362\u5E76\u5199\u56DE\u914D\u7F6E\uFF09 */\n private intentEnabled: boolean;\n\n private history: string[] = [];\n private historyIndex = -1;\n\n private pendingConfirm?: PendingConfirm;\n private abortController?: AbortController;\n private keyBuffer = \"\";\n private escTimer?: NodeJS.Timeout;\n private projectDirCreated?: string;\n private needsRender = false;\n private streamingPreview = \"\";\n private termVisible = true;\n private termFocus = false;\n private termScroll = 0;\n private lastLeftWidth = 0;\n /** \u4E0A\u6B21\u6E32\u67D3\u7684\u7269\u7406\u884C\u6570\uFF0C\u7528\u4E8E\u300C\u89C6\u53E3\u951A\u5B9A\u300D\uFF08\u89C1 render\uFF09 */\n private lastPhysicalCount = 0;\n private lastTermPhysicalCount = 0;\n\n /** \u7EC8\u7AEF\u9762\u677F\u7684\u8F93\u5165\u884C\uFF08\u4E0E\u5DE6\u4FA7\u5BF9\u8BDD\u8F93\u5165\u76F8\u4E92\u72EC\u7ACB\uFF09 */\n private termInput = \"\";\n private termInputCursor = 0;\n private termHistory: string[] = [];\n private termHistoryIndex = -1;\n private readonly term: ShellPanel;\n\n private readonly onData = (chunk: string) => this.handleData(chunk);\n private readonly onResize = () => {\n // \u7528 -1 \u8868\u793A\u300C\u672C\u6B21\u6E32\u67D3\u8DF3\u8FC7\u89C6\u53E3\u951A\u5B9A\u300D\u3002\n // \u4E0D\u80FD\u6E05\u96F6\u8BA1\u6570\uFF1A\u951A\u5B9A\u903B\u8F91\u662F\u300Ccount > lastCount \u65F6\u628A\u5DEE\u503C\u8865\u8FDB scrollOffset\u300D\uFF0C\n // \u6E05\u96F6\u4F1A\u8BA9\u4E0B\u4E00\u6B21\u6E32\u67D3\u8BEF\u5224\u4E3A\u65B0\u589E\u4E86\u5168\u90E8\u884C\uFF0C\u628A\u5DF2\u4E0A\u7FFB\u7684\u89C6\u53E3\u4E00\u8DEF\u63A8\u5230\u6700\u9876\u90E8\u3002\n this.lastPhysicalCount = -1;\n this.lastTermPhysicalCount = -1;\n this.scheduleRender();\n };\n\n constructor(options: TuiAppOptions) {\n this.options = options;\n this.cwd = options.cwd;\n this.autoApprove = options.autoApprove;\n this.intentEnabled =\n options.intentEnabled ?? options.config.intent?.enabled === true;\n // \u540C\u6B65\u5230\u914D\u7F6E\u5BF9\u8C61\uFF08\u5185\u5B58\u4E2D\uFF09\uFF1AAgent \u8BFB\u53D6\u7684\u662F config.intent.enabled\u3002\n // CLI \u7684 --intent / --no-intent \u53EA\u5728\u6B64\u8986\u76D6\u672C\u6B21\u8FD0\u884C\uFF0C\u4E0D\u4F1A\u5199\u56DE\u78C1\u76D8\u3002\n options.config.intent = {\n ...(options.config.intent ?? { enabled: false }),\n enabled: this.intentEnabled,\n };\n this.modelProviderLabel = options.providerLabel;\n this.modelLabel = options.model;\n this.modelWeight = options.modelWeight;\n this.term = new ShellPanel(options.cwd, () => this.scheduleRender());\n\n // \u9996\u6B21\u8FD0\u884C\u65F6\u521D\u59CB\u5316\u9879\u76EE\u76EE\u5F55\uFF08<\u9879\u76EE>/.xuanzhu\uFF09\n const project = ensureProjectDir(options.cwd);\n if (project.created) {\n this.projectDirCreated = project.paths.dir;\n }\n const events: AgentEvents = {\n onText: (delta) => this.handleTextDelta(delta),\n onReasoning: () => undefined,\n onToolStart: (call) => this.handleToolStart(call),\n onToolEnd: (call, result) => this.handleToolEnd(call, result),\n onStatus: (status, detail) => {\n this.statusText = status;\n this.statusDetail = detail ?? \"\";\n this.scheduleRender();\n },\n onNotice: (message) => this.handleNotice(message),\n onIntent: (analysis, original) => this.handleIntent(analysis, original),\n onModelChange: (info) => this.handleModelChange(info),\n confirm: (request) => this.requestConfirm(request),\n };\n this.agent = new Agent(\n options.provider,\n options.config,\n options.cwd,\n events,\n options.activeModel,\n );\n }\n\n async start(): Promise<void> {\n this.enterTerminal();\n if (this.projectDirCreated) {\n this.lines.push(\n `${ansi.green}\u2713 \u5DF2\u521D\u59CB\u5316\u9879\u76EE\u76EE\u5F55 ${this.projectDirCreated}${ansi.reset}`,\n );\n this.lines.push(\n `${ansi.gray} \u00B7 memory/ \u9879\u76EE\u8BB0\u5FC6\uFF08\u7384\u732A\u5199\u5165\uFF0C\u8DE8\u4F1A\u8BDD\u590D\u7528\uFF09${ansi.reset}`,\n );\n this.lines.push(\n `${ansi.gray} \u00B7 rules.md \u9879\u76EE\u89C4\u5219\uFF08\u5185\u5BB9\u6CE8\u5165\u7CFB\u7EDF\u63D0\u793A\u8BCD\uFF09${ansi.reset}`,\n );\n this.lines.push(\"\");\n }\n this.scheduleRender();\n await new Promise<void>((resolve) => {\n this.resolveExit = resolve;\n });\n }\n\n private resolveExit?: () => void;\n\n // ---------------------------------------------------------------- \u7EC8\u7AEF\u63A7\u5236\n\n private enterTerminal(): void {\n process.stdout.write(\n screen.enterAlt +\n cursor.hide +\n // \u5173\u95ED\u81EA\u52A8\u6362\u884C\uFF1A\u5373\u4F7F\u67D0\u884C\u7565\u8D85\u5BBD\u4E5F\u4E0D\u4F1A\u6298\u884C\u5E76\u63A8\u52A8\u6574\u5C4F\u6EDA\u52A8\n \"\\x1b[?7l\" +\n // \u542F\u7528\u9F20\u6807\u4E0A\u62A5\uFF08\u542B\u6EDA\u8F6E\uFF09\uFF0C\u5E76\u91C7\u7528 SGR \u6269\u5C55\u5750\u6807\n \"\\x1b[?1000h\\x1b[?1006h\" +\n // \u8BF7\u6C42\u4E0A\u62A5\u5E26\u4FEE\u9970\u952E\u7684 Enter \u7B49\u6309\u952E\uFF08xterm modifyOtherKeys level 2\uFF09\uFF1A\n // \u591A\u6570\u7EC8\u7AEF\u9ED8\u8BA4\u628A Shift+Enter \u4E0E Enter \u7F16\u6210\u540C\u4E00\u4E2A `\\r`\uFF0C\u65E0\u6CD5\u533A\u5206\n this.extendedKeyRequest(),\n );\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(true);\n }\n process.stdin.resume();\n process.stdin.setEncoding(\"utf8\");\n process.stdin.on(\"data\", this.onData);\n process.stdout.on(\"resize\", this.onResize);\n }\n\n private exitTerminal(): void {\n if (this.escTimer) {\n clearTimeout(this.escTimer);\n this.escTimer = undefined;\n }\n process.stdin.off(\"data\", this.onData);\n process.stdout.off(\"resize\", this.onResize);\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n }\n process.stdin.pause();\n process.stdout.write(\n // \u5173\u95ED\u9F20\u6807\u4E0A\u62A5\u3001\u6062\u590D\u81EA\u52A8\u6362\u884C\uFF0C\u5E76\u628A modifyOtherKeys \u8FD8\u539F\u4E3A\u7EC8\u7AEF\u521D\u59CB\u8BBE\u7F6E\uFF0C\u518D\u9000\u51FA\u5907\u7528\u5C4F\u5E55\n \"\\x1b[>4m\" +\n \"\\x1b[?1000l\\x1b[?1006l\\x1b[?7h\" +\n ansi.reset +\n cursor.show +\n screen.exitAlt,\n );\n }\n\n /**\n * \u8BF7\u6C42\u7EC8\u7AEF\u4E0A\u62A5\u300C\u4FEE\u9970\u952E + Enter\u300D(`\\x1b[>4;2m` = xterm modifyOtherKeys level 2)\u3002\n *\n * kitty / Ghostty \u628A\u8FD9\u6761 xterm \u517C\u5BB9\u5E8F\u5217\u6620\u5C04\u5230\u81EA\u5BB6\u7684 progressive enhancement \u534F\u8BAE\u4E0A\n * \uFF08level 2 \u7B49\u4EF7\u4E8E\u300C\u6240\u6709\u6309\u952E\u90FD\u7528\u8F6C\u4E49\u7801\u4E0A\u62A5\u300D\uFF0C\u8FDE\u666E\u901A\u5B57\u6BCD\u90FD\u4F1A\u53D8\u6210 `CSI <code>u`\uFF09\uFF0C\n * \u542F\u7528\u540E\u53CD\u800C\u4F1A\u7834\u574F\u8F93\u5165\uFF0C\u56E0\u6B64\u8FD9\u4E24\u7C7B\u7EC8\u7AEF\u8DF3\u8FC7\u2014\u2014\u9700\u8981 Shift+Enter \u65F6\u8BF7\u5728\u7EC8\u7AEF\u4FA7\u914D\u7F6E\u3002\n * \u4E0D\u8BC6\u522B\u8BE5\u5E8F\u5217\u7684\u7EC8\u7AEF\uFF08\u5982 xterm.js\uFF09\u4F1A\u76F4\u63A5\u5FFD\u7565\uFF0C\u65E0\u526F\u4F5C\u7528\u3002\n */\n private extendedKeyRequest(): string {\n const term = process.env.TERM ?? \"\";\n const program = process.env.TERM_PROGRAM ?? \"\";\n if (process.env.KITTY_WINDOW_ID) return \"\";\n if (/kitty|ghostty/i.test(term) || /kitty|ghostty/i.test(program)) {\n return \"\";\n }\n return \"\\x1b[>4;2m\";\n }\n\n private shutdown(): void {\n if (this.exited) return;\n this.exited = true;\n // \u53F3\u4FA7\u7EC8\u7AEF\u91CC\u7684\u547D\u4EE4\u4EE5 detached \u72EC\u7ACB\u8FDB\u7A0B\u7EC4\u8FD0\u884C\uFF0C\u4E0D\u4E3B\u52A8\u7EC8\u6B62\u4F1A\u6210\u4E3A\u5B64\u513F\u8FDB\u7A0B\n this.term.dispose();\n this.exitTerminal();\n this.resolveExit?.();\n }\n\n // ------------------------------------------------------------------ \u4E8B\u4EF6\u6D41\n\n private handleTextDelta(delta: string): void {\n const completed = this.markdown.push(delta);\n if (completed.length > 0) {\n this.lines.push(...completed);\n }\n this.streamingPreview = this.markdown.peek();\n this.scheduleRender();\n }\n\n private handleToolStart(call: ToolCall): void {\n const summary = summarizeToolCall(call);\n this.lines.push(`${ansi.magenta}\u23FA${ansi.reset} ${ansi.bold}${call.name}${ansi.reset} ${ansi.gray}${summary}${ansi.reset}`);\n this.statusText = `\u6267\u884C ${call.name}`;\n this.scheduleRender();\n }\n\n private handleToolEnd(_call: ToolCall, result: ExecuteToolResult): void {\n const preview = (result.summary ?? (result.ok ? \"\u5B8C\u6210\" : \"\u5931\u8D25\")).slice(0, 60);\n const mark = result.denied\n ? `${ansi.yellow}\u23BF \u5DF2\u62D2\u7EDD${ansi.reset}`\n : result.ok\n ? `${ansi.green}\u23BF ${preview}${ansi.reset}`\n : `${ansi.red}\u23BF ${preview}${ansi.reset}`;\n this.lines.push(` ${mark}`);\n this.statusText = \"\u601D\u8003\u4E2D\";\n this.scheduleRender();\n }\n\n /** \u628A\u5DE5\u5177\u5185\u90E8\u65E5\u5FD7\u8FFD\u52A0\u5230\u8F93\u51FA\u533A */\n private handleNotice(message: string): void {\n for (const line of message.split(\"\\n\")) {\n if (line.trim().length > 0) {\n this.lines.push(`${ansi.gray} ${line}${ansi.reset}`);\n }\n }\n this.scheduleRender();\n }\n\n /** \u610F\u56FE\u5206\u6790\u5B8C\u6210\uFF1A\u5C55\u793A\u5206\u6790\u7ED3\u679C\uFF08\u5B83\u5C06\u88AB\u7528\u4F5C\u672C\u6B21\u8F93\u5165\uFF09 */\n private handleIntent(analysis: string, original: string): void {\n const MAX_LINES = 14;\n const rows = analysis\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0);\n\n this.lines.push(`${ansi.gray}\u2301 \u610F\u56FE\u5206\u6790\u7ED3\u679C\uFF08\u5C06\u4F5C\u4E3A\u672C\u6B21\u8F93\u5165\uFF09${ansi.reset}`);\n for (const line of rows.slice(0, MAX_LINES)) {\n this.lines.push(`${ansi.gray} ${line}${ansi.reset}`);\n }\n if (rows.length > MAX_LINES) {\n this.lines.push(\n `${ansi.gray} \u2026\uFF08\u5171 ${rows.length} \u884C\uFF0C\u5B8C\u6574\u5185\u5BB9\u5DF2\u4F5C\u4E3A\u8F93\u5165\u53D1\u9001\uFF09${ansi.reset}`,\n );\n }\n this.lines.push(\n `${ansi.gray} \u539F\u59CB\u6D88\u606F\uFF1A${truncate(original.replace(/\\s+/g, \" \"), 60)}${ansi.reset}`,\n );\n this.scheduleRender();\n }\n\n /** \u6A21\u578B\u964D\u7EA7\u5207\u6362 / \u6743\u91CD\u8017\u5C3D\u91CD\u7F6E\u540E\u7684\u754C\u9762\u66F4\u65B0 */\n private handleModelChange(info: {\n provider: string;\n model: string;\n weight: number;\n reason: string;\n }): void {\n this.modelProviderLabel =\n findProvider(info.provider)?.label ?? info.provider;\n this.modelLabel = info.model;\n this.modelWeight = info.weight;\n // \u53EA\u6709\u771F\u6B63\u53D1\u751F\u300C\u5207\u6362\u300D\u624D\u5728\u8F93\u51FA\u533A\u63D0\u793A\uFF1B\u7EAF\u964D\u6743\u4EC5\u66F4\u65B0\u72B6\u6001\u680F\uFF0C\u907F\u514D\u5237\u5C4F\n if (info.reason !== \"\u8C03\u7528\u5931\u8D25\u964D\u6743\") {\n this.lines.push(\n `${ansi.yellow}\u21C4 \u6A21\u578B\u5DF2\u5207\u6362\u4E3A ${info.provider}/${info.model}\uFF08\u6743\u91CD ${info.weight}\uFF09${ansi.reset}`,\n );\n }\n this.scheduleRender();\n }\n\n private requestConfirm(request: ConfirmRequest): Promise<boolean> {\n return new Promise<boolean>((resolve) => {\n this.pendingConfirm = { request, resolve, selected: true };\n this.scheduleRender();\n });\n }\n\n // ------------------------------------------------------------------ \u8F93\u5165\n\n private handleData(chunk: string): void {\n this.keyBuffer += chunk;\n this.drainKeys();\n }\n\n /**\n * \u4F9D\u6B21\u53D6\u51FA\u5E76\u5904\u7406\u6309\u952E\u3002\n *\n * \u8F6C\u4E49\u5E8F\u5217\uFF08\u65B9\u5411\u952E\u3001PgUp \u7B49\uFF09\u53EF\u80FD\u88AB\u7EC8\u7AEF\u5206\u7247\u9001\u8FBE\uFF08\u4F8B\u5982\u5148\u5230 \"\\x1b\"\uFF0C\u518D\u5230 \"[A\"\uFF09\u3002\n * \u9047\u5230\u4E0D\u5B8C\u6574\u7684\u5E8F\u5217\u524D\u7F00\u65F6\u5148\u7B49\u5F85\u540E\u7EED\u5B57\u8282\uFF0C\u8D85\u65F6\u540E\u518D\u5224\u5B9A\uFF1A\n * - \u786E\u5B9E\u53EA\u662F\u5355\u72EC\u7684 ESC \u2192 \u4F5C\u4E3A ESC \u5904\u7406\uFF1B\n * - \u5176\u4ED6\u4E0D\u5B8C\u6574\u5E8F\u5217 \u2192 \u76F4\u63A5\u4E22\u5F03\uFF0C\u907F\u514D\u6B8B\u7559\u5B57\u7B26\u88AB\u5F53\u4F5C\u8F93\u5165\u63D2\u5165\u3002\n */\n private drainKeys(): void {\n for (;;) {\n const key = this.readKey();\n if (key === null) {\n if (this.keyBuffer.startsWith(\"\\x1b\")) {\n if (this.escTimer) clearTimeout(this.escTimer);\n this.escTimer = setTimeout(() => {\n this.escTimer = undefined;\n const pending = this.keyBuffer;\n this.keyBuffer = \"\";\n if (pending === \"\\x1b\") {\n this.handleKey(\"\\x1b\");\n }\n }, 40);\n }\n return;\n }\n if (this.escTimer) {\n clearTimeout(this.escTimer);\n this.escTimer = undefined;\n }\n this.handleKey(key);\n if (this.exited) return;\n }\n }\n\n private readKey(): string | null {\n const buf = this.keyBuffer;\n if (buf.length === 0) return null;\n if (buf[0] === \"\\x1b\") {\n // \u5B8C\u6574 CSI \u5E8F\u5217\uFF08final byte \u4F4D\u4E8E 0x40\u20130x7E\uFF09\n const csi = /^\\x1b\\[[0-9:;<=>?]*[@-~]/.exec(buf);\n if (csi) {\n this.keyBuffer = buf.slice(csi[0].length);\n return csi[0];\n }\n // \u5B8C\u6574 SS3 \u5E8F\u5217\uFF08\u5982 \\x1bOA\uFF09\n const ss3 = /^\\x1bO[A-Za-z]/.exec(buf);\n if (ss3) {\n this.keyBuffer = buf.slice(ss3[0].length);\n return ss3[0];\n }\n // \u4ECD\u662F\u5E8F\u5217\u524D\u7F00\uFF08\\x1b / \\x1b[ / \\x1b[1;5 \u7B49\uFF09\uFF1A\u7B49\u5F85\u540E\u7EED\u5B57\u8282\n if (/^\\x1b\\[?[0-9:;<=>?]*$/.test(buf)) return null;\n // ESC + \u5355\u4E2A\u975E\u5E8F\u5217\u5B57\u7B26\n if (buf.length >= 2) {\n this.keyBuffer = buf.slice(2);\n return buf.slice(0, 2);\n }\n return null;\n }\n const cp = buf.codePointAt(0);\n if (cp === undefined) return null;\n const char = String.fromCodePoint(cp);\n this.keyBuffer = buf.slice(char.length);\n return char;\n }\n\n private handleKey(rawKey: string): void {\n // \u5F52\u4E00\u5316\u7EC8\u7AEF\u7684\u6269\u5C55\u6309\u952E\u5E8F\u5217\uFF08Ctrl/Shift+Enter\u3001modifyOtherKeys \u4E0B\u7684 Ctrl+\u5B57\u6BCD\u7B49\uFF09\n const key = normalizeKey(rawKey);\n if (this.pendingConfirm) {\n this.handleConfirmKey(key);\n return;\n }\n\n // \u9F20\u6807\u4E8B\u4EF6\uFF1A\u5DE6\u952E\u70B9\u51FB\u5207\u6362\u7126\u70B9\uFF0C\u6EDA\u8F6E\u6EDA\u52A8\u6240\u5728\u680F\n const mouse = /^\\x1b\\[<(\\d+);(\\d+);(\\d+)([Mm])$/.exec(key);\n if (mouse) {\n this.handleMouse(mouse);\n return;\n }\n\n // Shift+Tab\uFF1A\u5728\u300C\u5BF9\u8BDD\u8F93\u5165\u300D\u4E0E\u300C\u53F3\u4FA7\u7EC8\u7AEF\u300D\u4E4B\u95F4\u5207\u6362\u7126\u70B9\n if (key === \"\\x1b[Z\") {\n this.toggleFocus();\n return;\n }\n\n if (this.termFocus) {\n this.handleTermKey(key);\n return;\n }\n\n switch (key) {\n case \"\\x03\": // Ctrl+C\n if (this.busy) {\n this.abortController?.abort();\n this.statusText = \"\u4E2D\u65AD\u4E2D\u2026\";\n this.scheduleRender();\n } else if (this.input.length > 0) {\n this.input = \"\";\n this.inputCursor = 0;\n this.scheduleRender();\n } else {\n this.shutdown();\n }\n return;\n case \"\\x04\": // Ctrl+D\uFF1A\u672C\u8F6E\u5BF9\u8BDD\u6B63\u5728\u8FDB\u884C\u65F6\u7ED3\u675F\u5B83\uFF1B\u4EFB\u4F55\u60C5\u51B5\u4E0B\u90FD\u4E0D\u9000\u51FA\u754C\u9762\n if (this.busy) {\n this.abortController?.abort();\n this.statusText = \"\u4E2D\u65AD\u4E2D\u2026\";\n this.scheduleRender();\n }\n return;\n case \"\\r\": // Enter\n void this.submit();\n return;\n case \"\\x0a\": // Ctrl+J \u6362\u884C\n this.insertText(\"\\n\");\n return;\n case \"\\x7f\":\n case \"\\b\":\n this.backspace();\n return;\n case \"\\x01\": // Ctrl+A\n this.inputCursor = 0;\n this.scheduleRender();\n return;\n case \"\\x05\": // Ctrl+E\n this.inputCursor = this.input.length;\n this.scheduleRender();\n return;\n case \"\\x0c\": // Ctrl+L\n this.lines = [];\n this.scrollOffset = 0;\n this.scheduleRender();\n return;\n case \"\\x1b[A\": // Up\n this.navigateHistory(-1);\n return;\n case \"\\x1b[B\": // Down\n this.navigateHistory(1);\n return;\n case \"\\x1b[C\": // Right\n this.moveCursor(1);\n return;\n case \"\\x1b[D\": // Left\n this.moveCursor(-1);\n return;\n case \"\\x1b[5~\": // PageUp\uFF1A\u5411\u4E0A\u7FFB\u9875\n this.scrollBy(5);\n return;\n case \"\\x1b[6~\": // PageDown\uFF1A\u5411\u4E0B\u7FFB\u9875\n this.scrollBy(-5);\n return;\n case \"\\x1b[1;2A\": // Shift+Up\uFF1A\u9010\u884C\u4E0A\u7FFB\n this.scrollBy(1);\n return;\n case \"\\x1b[1;2B\": // Shift+Down\uFF1A\u9010\u884C\u4E0B\u7FFB\n this.scrollBy(-1);\n return;\n case \"\\x1b[H\": // Home\uFF1A\u8DF3\u5230\u6700\u65E9\u7684\u5386\u53F2\n case \"\\x1b[1~\":\n case \"\\x1b[7~\":\n this.scrollToTop();\n return;\n case \"\\x1b[F\": // End\uFF1A\u56DE\u5230\u6700\u65B0\n case \"\\x1b[4~\":\n case \"\\x1b[8~\":\n this.scrollToBottom();\n return;\n default:\n if (key.charCodeAt(0) >= 0x20) {\n this.insertText(key);\n }\n }\n }\n\n /** \u9F20\u6807\uFF1A\u6EDA\u8F6E\u6EDA\u52A8\u6307\u9488\u6240\u5728\u680F\uFF0C\u5DE6\u952E\u70B9\u51FB\u5207\u6362\u7126\u70B9 */\n private handleMouse(match: RegExpExecArray): void {\n const button = Number(match[1]);\n const column = Number(match[2]);\n const pressed = match[4] === \"M\";\n const termWidth = this.resolveTermWidth(process.stdout.columns || 80);\n const inTerm =\n this.lastLeftWidth > 0 &&\n termWidth > 0 &&\n column > this.lastLeftWidth + 1;\n\n // \u6EDA\u8F6E\u5FC5\u987B\u5148\u4E8E\u300C\u5DE6\u952E\u5355\u51FB\u300D\u5224\u65AD\uFF1A\n // \u6EDA\u8F6E\u7684\u6309\u94AE\u7801\u4E3A 64(\u4E0A\u7FFB)/65(\u4E0B\u7FFB)\uFF0C\u5176\u4F4E\u4F4D\u4E0E\u5DE6\u952E\u540C\u4E3A 0\uFF0C\n // \u82E5\u5148\u5224 (button & 3) === 0\uFF0C\u4E0A\u7FFB\u4F1A\u88AB\u8BEF\u5224\u6210\u70B9\u51FB\u800C\u76F4\u63A5\u8FD4\u56DE\uFF0C\n // \u7ED3\u679C\u5C31\u662F\u300C\u53EA\u80FD\u5F80\u4E0B\u3001\u6C38\u8FDC\u56DE\u4E0D\u5230\u5386\u53F2\u300D\u3002\n if (pressed && (button & 64) === 64) {\n const upwards = (button & 1) === 0;\n const delta = upwards ? 3 : -3;\n if (inTerm) {\n this.scrollTermBy(delta);\n } else {\n this.scrollBy(delta);\n }\n return;\n }\n\n // \u5DE6\u952E\u6309\u4E0B\uFF08\u6392\u9664\u62D6\u62FD\u7684\u79FB\u52A8\u6807\u5FD7\u4F4D\uFF09\uFF1A\u7126\u70B9\u8DDF\u968F\u9F20\u6807\u70B9\u51FB\u7684\u680F\u76EE\n if (pressed && (button & 3) === 0 && (button & 32) === 0) {\n if (inTerm !== this.termFocus) {\n this.termFocus = inTerm;\n this.scheduleRender();\n }\n }\n }\n\n /** Shift+Tab\uFF1A\u5728\u5BF9\u8BDD\u8F93\u5165\u4E0E\u53F3\u4FA7\u7EC8\u7AEF\u4E4B\u95F4\u5207\u6362\u7126\u70B9 */\n private toggleFocus(): void {\n if (!this.termVisible) {\n this.lines.push(\n `${ansi.gray}\u7EC8\u7AEF\u9762\u677F\u5DF2\u9690\u85CF\uFF0C\u8F93\u5165 /term \u53EF\u91CD\u65B0\u663E\u793A\u3002${ansi.reset}`,\n );\n this.scheduleRender();\n return;\n }\n this.termFocus = !this.termFocus;\n this.scheduleRender();\n }\n\n /** \u7EC8\u7AEF\u9762\u677F\u805A\u7126\u65F6\u7684\u6309\u952E\u5904\u7406 */\n private handleTermKey(key: string): void {\n switch (key) {\n case \"\\x04\": // Ctrl+D\uFF1A\u76F4\u63A5\u4E2D\u65AD\u6B63\u5728\u8FD0\u884C\u7684\u547D\u4EE4\uFF08\u4EFB\u4F55\u60C5\u51B5\u4E0B\u90FD\u4E0D\u4F1A\u9000\u51FA\u7384\u732A\uFF09\n if (this.term.isRunning()) {\n this.term.interrupt();\n this.scheduleRender();\n }\n return;\n case \"\\x03\": // Ctrl+C\uFF1A\u4E2D\u65AD\u547D\u4EE4 / \u6E05\u7A7A\u8F93\u5165 / \u56DE\u5230\u5BF9\u8BDD\n if (this.term.isRunning()) {\n this.term.interrupt();\n } else if (this.termInput.length > 0) {\n this.termInput = \"\";\n this.termInputCursor = 0;\n } else {\n this.termFocus = false;\n }\n this.scheduleRender();\n return;\n case \"\\r\":\n this.submitTermCommand();\n return;\n case \"\\t\": // Tab\uFF1A\u547D\u4EE4\u540D / \u8DEF\u5F84\u8865\u5168\n this.applyTermCompletion();\n return;\n case \"\\x7f\":\n case \"\\b\":\n this.termBackspace();\n return;\n case \"\\x01\":\n this.termInputCursor = 0;\n this.scheduleRender();\n return;\n case \"\\x05\":\n this.termInputCursor = this.termInput.length;\n this.scheduleRender();\n return;\n case \"\\x0c\": // Ctrl+L\uFF1A\u6E05\u7A7A\u7EC8\u7AEF\u8F93\u51FA\n this.term.clear();\n this.scrollTermToBottom();\n return;\n case \"\\x1b[A\":\n this.navigateTermHistory(-1);\n return;\n case \"\\x1b[B\":\n this.navigateTermHistory(1);\n return;\n case \"\\x1b[C\":\n this.termInputCursor = Math.min(\n this.termInput.length,\n this.termInputCursor + 1,\n );\n this.scheduleRender();\n return;\n case \"\\x1b[D\":\n this.termInputCursor = Math.max(0, this.termInputCursor - 1);\n this.scheduleRender();\n return;\n case \"\\x1b[5~\": // PageUp\uFF1A\u5411\u4E0A\u7FFB\u9875\n this.scrollTermBy(5);\n return;\n case \"\\x1b[6~\": // PageDown\uFF1A\u5411\u4E0B\u7FFB\u9875\n this.scrollTermBy(-5);\n return;\n case \"\\x1b[1;2A\": // Shift+Up\uFF1A\u9010\u884C\u4E0A\u7FFB\n this.scrollTermBy(1);\n return;\n case \"\\x1b[1;2B\": // Shift+Down\uFF1A\u9010\u884C\u4E0B\u7FFB\n this.scrollTermBy(-1);\n return;\n case \"\\x1b[H\": // Home\uFF1A\u8DF3\u5230\u6700\u65E9\u7684\u8F93\u51FA\n case \"\\x1b[1~\":\n case \"\\x1b[7~\":\n this.scrollTermToTop();\n return;\n case \"\\x1b[F\": // End\uFF1A\u56DE\u5230\u6700\u65B0\u8F93\u51FA\n case \"\\x1b[4~\":\n case \"\\x1b[8~\":\n this.scrollTermToBottom();\n return;\n default:\n if (key.charCodeAt(0) >= 0x20) {\n this.termInput =\n this.termInput.slice(0, this.termInputCursor) +\n key +\n this.termInput.slice(this.termInputCursor);\n this.termInputCursor += key.length;\n this.termScroll = 0;\n this.scheduleRender();\n }\n }\n }\n\n private termBackspace(): void {\n if (this.termInputCursor <= 0) return;\n let start = this.termInputCursor - 1;\n const code = this.termInput.charCodeAt(start);\n if (code >= 0xdc00 && code <= 0xdfff && start > 0) start -= 1;\n this.termInput =\n this.termInput.slice(0, start) + this.termInput.slice(this.termInputCursor);\n this.termInputCursor = start;\n this.scheduleRender();\n }\n\n private navigateTermHistory(direction: number): void {\n if (this.termHistory.length === 0) return;\n if (this.termHistoryIndex === -1) {\n this.termHistoryIndex = this.termHistory.length;\n }\n this.termHistoryIndex += direction;\n if (this.termHistoryIndex < 0) this.termHistoryIndex = 0;\n if (this.termHistoryIndex >= this.termHistory.length) {\n this.termHistoryIndex = -1;\n this.termInput = \"\";\n this.termInputCursor = 0;\n } else {\n this.termInput = this.termHistory[this.termHistoryIndex];\n this.termInputCursor = this.termInput.length;\n }\n this.scheduleRender();\n }\n\n private submitTermCommand(): void {\n const command = this.termInput.trim();\n if (!command) return;\n this.termInput = \"\";\n this.termInputCursor = 0;\n this.termScroll = 0;\n this.termHistory.push(command);\n this.termHistoryIndex = -1;\n this.term.run(command);\n this.scheduleRender();\n }\n\n /** Tab \u8865\u5168\uFF1A\u547D\u4EE4\u4F4D\u7F6E\u8865 PATH \u4E2D\u7684\u547D\u4EE4\uFF0C\u53C2\u6570\u4F4D\u7F6E\u8865\u6587\u4EF6\u8DEF\u5F84 */\n private applyTermCompletion(): void {\n const result = completeTermInput(\n this.term.getCwd(),\n this.termInput,\n this.termInputCursor,\n );\n if (!result) return;\n\n if (result.candidates.length > 0) {\n // \u5DF2\u6709\u591A\u4E2A\u5019\u9009\u4E14\u65E0\u6CD5\u7EE7\u7EED\u8865\u5168\uFF1A\u5217\u51FA\u5019\u9009\uFF08\u8FC7\u591A\u65F6\u622A\u65AD\uFF0C\u907F\u514D\u5237\u5C4F\uFF09\n const MAX_SHOWN = 24;\n const shown = result.candidates.slice(0, MAX_SHOWN);\n const more =\n result.candidates.length > shown.length\n ? ` \u2026\uFF08\u5171 ${result.candidates.length} \u9879\uFF09`\n : \"\";\n this.term.notice(\n `${ansi.gray}${shown.join(\" \")}${more}${ansi.reset}`,\n );\n } else {\n this.termInput = result.line;\n this.termInputCursor = result.cursor;\n this.termScroll = 0;\n }\n this.scheduleRender();\n }\n\n private handleConfirmKey(key: string): void {\n const pending = this.pendingConfirm;\n if (!pending) return;\n switch (key) {\n case \"y\":\n case \"Y\":\n case \"\\r\":\n this.resolveConfirm(true);\n return;\n case \"\\x04\": // Ctrl+D\uFF1A\u62D2\u7EDD\u8BE5\u64CD\u4F5C\u5E76\u7ACB\u5373\u7EC8\u6B62\u5F53\u524D\u5BF9\u8BDD\n this.abortController?.abort();\n this.resolveConfirm(false);\n return;\n case \"n\":\n case \"N\":\n case \"\\x1b\":\n case \"\\x03\":\n this.resolveConfirm(false);\n return;\n case \"\\x1b[C\":\n case \"\\x1b[D\":\n case \"\\t\":\n pending.selected = !pending.selected;\n this.scheduleRender();\n return;\n default:\n return;\n }\n }\n\n private resolveConfirm(approved: boolean): void {\n const pending = this.pendingConfirm;\n if (!pending) return;\n this.pendingConfirm = undefined;\n const label = approved ? \"\u5DF2\u5141\u8BB8\" : \"\u5DF2\u62D2\u7EDD\";\n this.lines.push(` ${approved ? ansi.green : ansi.yellow}${label}${ansi.reset}`);\n pending.resolve(approved);\n this.scheduleRender();\n }\n\n private insertText(text: string): void {\n this.input =\n this.input.slice(0, this.inputCursor) +\n text +\n this.input.slice(this.inputCursor);\n this.inputCursor += text.length;\n this.scrollOffset = 0;\n this.scheduleRender();\n }\n\n private backspace(): void {\n if (this.inputCursor <= 0) return;\n // \u5904\u7406\u4EE3\u7406\u5BF9\n let start = this.inputCursor - 1;\n const code = this.input.charCodeAt(start);\n if (code >= 0xdc00 && code <= 0xdfff && start > 0) {\n start -= 1;\n }\n this.input = this.input.slice(0, start) + this.input.slice(this.inputCursor);\n this.inputCursor = start;\n this.scheduleRender();\n }\n\n private moveCursor(delta: number): void {\n const next = this.inputCursor + delta;\n this.inputCursor = Math.max(0, Math.min(this.input.length, next));\n this.scheduleRender();\n }\n\n private navigateHistory(direction: number): void {\n if (this.history.length === 0) return;\n if (this.historyIndex === -1) {\n this.historyIndex = this.history.length;\n }\n this.historyIndex += direction;\n if (this.historyIndex < 0) this.historyIndex = 0;\n if (this.historyIndex >= this.history.length) {\n this.historyIndex = -1;\n this.input = \"\";\n this.inputCursor = 0;\n } else {\n this.input = this.history[this.historyIndex];\n this.inputCursor = this.input.length;\n }\n this.scheduleRender();\n }\n\n /** \u6EDA\u52A8\u5DE6\u4FA7\u5BF9\u8BDD\u533A\uFF1Adelta > 0 \u8868\u793A\u5411\u66F4\u65E9\u7684\u5386\u53F2\u6EDA\u52A8\uFF08\u504F\u79FB\u91CF\u6309\u300C\u8DDD\u5E95\u90E8\u884C\u6570\u300D\u8BA1\uFF09 */\n private scrollBy(delta: number): void {\n this.setScrollOffset(this.scrollOffset + delta);\n }\n\n /** \u8BBE\u7F6E\u5DE6\u680F\u6EDA\u52A8\u504F\u79FB\uFF08\u4E0A\u9650\u7531\u6E32\u67D3\u65F6\u6309\u5B9E\u9645\u884C\u6570\u6536\u655B\uFF09 */\n private setScrollOffset(offset: number): void {\n this.scrollOffset = Math.max(0, Math.round(offset));\n this.scheduleRender();\n }\n\n /** \u5DE6\u680F\u8DF3\u5230\u6700\u65E9\u7684\u5386\u53F2\uFF08\u4E0A\u9650\u7531\u6E32\u67D3\u65F6\u6536\u655B\u5230\u5B9E\u9645\u53EF\u6EDA\u52A8\u884C\u6570\uFF09 */\n private scrollToTop(): void {\n this.setScrollOffset(Number.MAX_SAFE_INTEGER);\n }\n\n private scrollToBottom(): void {\n this.setScrollOffset(0);\n }\n\n /** \u6EDA\u52A8\u53F3\u4FA7\u7EC8\u7AEF\u8F93\u51FA\uFF1Adelta > 0 \u8868\u793A\u5411\u66F4\u65E9\u7684\u8F93\u51FA\u6EDA\u52A8 */\n private scrollTermBy(delta: number): void {\n this.termScroll = Math.max(0, Math.round(this.termScroll + delta));\n this.scheduleRender();\n }\n\n private scrollTermToTop(): void {\n this.termScroll = Number.MAX_SAFE_INTEGER;\n this.scheduleRender();\n }\n\n private scrollTermToBottom(): void {\n this.termScroll = 0;\n this.scheduleRender();\n }\n\n // ------------------------------------------------------------------ \u63D0\u4EA4\n\n private async submit(): Promise<void> {\n if (this.busy) return;\n const text = this.input.trim();\n if (!text) return;\n\n this.input = \"\";\n this.inputCursor = 0;\n this.scrollOffset = 0;\n this.history.push(text);\n this.historyIndex = -1;\n\n if (text.startsWith(\"/\")) {\n this.handleCommand(text);\n return;\n }\n\n // \u7528\u6237\u8F93\u5165\uFF1A\u7EFF\u5E95\u5757\u6807\u8BB0 + \u4EAE\u7EFF\u52A0\u7C97\u6B63\u6587\uFF0C\u4FBF\u4E8E\u5728\u5386\u53F2\u8BB0\u5F55\u4E2D\u4E00\u773C\u5B9A\u4F4D\n const badge = `${ansi.bgGreen}${ansi.black}${ansi.bold} \u276F ${ansi.reset}`;\n const [firstLine, ...restLines] = text.split(\"\\n\");\n this.lines.push(\n `${badge} ${ansi.brightGreen}${ansi.bold}${firstLine}${ansi.reset}`,\n );\n for (const line of restLines) {\n this.lines.push(\n `${ansi.brightGreen}${ansi.bold}\u2502${ansi.reset} ${ansi.brightGreen}${line}${ansi.reset}`,\n );\n }\n this.lines.push(\"\");\n\n this.busy = true;\n this.statusText = \"\u601D\u8003\u4E2D\";\n this.statusDetail = \"\";\n this.abortController = new AbortController();\n this.scheduleRender();\n\n // \u5FEB\u7167\u672C\u6B21\u8BF7\u6C42\u4F7F\u7528\u7684\u6A21\u578B\uFF1Arun \u5185\u90E8\u53EF\u80FD\u56E0\u5931\u8D25\u800C\u964D\u6743\u6216\u5207\u6362\u6A21\u578B\uFF0C\n // \u51FA\u9519\u65F6\u5E94\u62A5\u544A\u300C\u5B9E\u9645\u53D1\u8D77\u8BF7\u6C42\u65F6\u300D\u7528\u7684\u6A21\u578B\uFF0C\u5426\u5219\u4F1A\u628A\u65E7\u6A21\u578B\u7684\u9519\u8BEF\u5F52\u5230\u65B0\u6A21\u578B\u5934\u4E0A\u3002\n const requestModel = { label: this.modelLabel, weight: this.modelWeight };\n\n try {\n await this.agent.run(text, this.abortController.signal);\n } catch (err) {\n const [first, ...rest] = friendlyError(err).split(\"\\n\");\n this.lines.push(`${ansi.red}\u2717 ${first}${ansi.reset}`);\n for (const extra of rest) {\n this.lines.push(`${ansi.gray} ${extra}${ansi.reset}`);\n }\n // \u9644\u4E0A\u672C\u6B21\u8BF7\u6C42\u5B9E\u9645\u4F7F\u7528\u7684\u6A21\u578B\u4E0E\u6743\u91CD\uFF08\u7528\u5FEB\u7167\uFF0C\u907F\u514D\u88AB\u964D\u7EA7\u5207\u6362\u540E\u7684\u503C\u8986\u76D6\uFF09\n const weightText =\n requestModel.weight !== undefined ? `\uFF08\u6743\u91CD ${requestModel.weight}\uFF09` : \"\";\n this.lines.push(\n `${ansi.gray} \u672C\u6B21\u8BF7\u6C42\u4F7F\u7528\u7684\u6A21\u578B\uFF1A${this.modelProviderLabel} / ${requestModel.label}${weightText}${ansi.reset}`,\n );\n } finally {\n const tail = this.markdown.flush();\n if (tail.length > 0) this.lines.push(...tail);\n this.streamingPreview = \"\";\n this.lines.push(\"\");\n this.busy = false;\n this.abortController = undefined;\n this.statusText = \"\u5C31\u7EEA\";\n this.scheduleRender();\n }\n }\n\n private handleCommand(text: string): void {\n const [command, ...rest] = text.slice(1).split(/\\s+/);\n const arg = rest.join(\" \");\n switch (command) {\n case \"help\":\n case \"h\":\n this.printHelp();\n break;\n case \"clear\":\n this.lines = [];\n break;\n case \"reset\":\n this.agent.reset();\n this.lines.push(`${ansi.gray}\u4F1A\u8BDD\u5DF2\u91CD\u7F6E\u3002${ansi.reset}`);\n break;\n case \"exit\":\n case \"quit\":\n case \"q\":\n this.shutdown();\n return;\n case \"cwd\":\n this.lines.push(`${ansi.gray}${this.cwd}${ansi.reset}`);\n break;\n case \"switch\": {\n if (!arg) {\n this.lines.push(`${ansi.gray}\u5F53\u524D\u76EE\u5F55\uFF1A${this.cwd}${ansi.reset}`);\n this.lines.push(`${ansi.gray}\u7528\u6CD5\uFF1A/switch <\u76EE\u5F55\u8DEF\u5F84>${ansi.reset}`);\n } else {\n this.switchDirectory(arg);\n }\n break;\n }\n case \"term\": {\n if (arg === \"clear\") {\n this.term.clear();\n } else if (arg === \"focus\") {\n this.termVisible = true;\n this.termFocus = true;\n } else {\n this.termVisible = !this.termVisible;\n if (!this.termVisible) this.termFocus = false;\n this.lines.push(\n `${ansi.gray}\u7EC8\u7AEF\u9762\u677F\uFF1A${this.termVisible ? \"\u663E\u793A\" : \"\u9690\u85CF\"}\uFF08Shift+Tab \u6216\u9F20\u6807\u70B9\u51FB\u5207\u6362\u7126\u70B9\uFF09${ansi.reset}`,\n );\n }\n break;\n }\n case \"auto\": {\n const next =\n arg === \"on\" ? true : arg === \"off\" ? false : !this.autoApprove;\n this.autoApprove = next;\n this.options.config.autoApprove = next;\n try {\n saveConfig(this.options.config);\n } catch (err) {\n this.lines.push(\n `${ansi.yellow}\u26A0 \u914D\u7F6E\u4FDD\u5B58\u5931\u8D25\uFF1A${err instanceof Error ? err.message : String(err)}${ansi.reset}`,\n );\n }\n this.lines.push(\n next\n ? `${ansi.gray}\u81EA\u52A8\u6279\u51C6\uFF1A${ansi.brightYellow}\u5F00${ansi.reset}${ansi.gray} \u2014\u2014 \u6240\u6709\u5DE5\u5177\uFF08\u542B\u5199\u6587\u4EF6\u3001\u6267\u884C\u547D\u4EE4\uFF09\u5C06\u76F4\u63A5\u6267\u884C\uFF0C\u4E0D\u518D\u8BE2\u95EE\uFF1B\u5DF2\u5199\u5165\u914D\u7F6E\u3002${ansi.reset}`\n : `${ansi.gray}\u81EA\u52A8\u6279\u51C6\uFF1A\u5173 \u2014\u2014 \u5199\u6587\u4EF6 / \u7F16\u8F91\u6587\u4EF6 / \u6267\u884C\u547D\u4EE4\u524D\u4F1A\u8BF7\u6C42\u786E\u8BA4\uFF1B\u5DF2\u5199\u5165\u914D\u7F6E\u3002${ansi.reset}`,\n );\n break;\n }\n case \"intent\": {\n const next =\n arg === \"on\" ? true : arg === \"off\" ? false : !this.intentEnabled;\n this.intentEnabled = next;\n this.options.config.intent = {\n ...(this.options.config.intent ?? { enabled: false }),\n enabled: next,\n };\n try {\n saveConfig(this.options.config);\n } catch (err) {\n this.lines.push(\n `${ansi.yellow}\u26A0 \u914D\u7F6E\u4FDD\u5B58\u5931\u8D25\uFF1A${err instanceof Error ? err.message : String(err)}${ansi.reset}`,\n );\n }\n this.lines.push(\n next\n ? `${ansi.gray}\u610F\u56FE\u5206\u6790\uFF1A${ansi.brightGreen}\u5F00${ansi.reset}${ansi.gray} \u2014\u2014 \u6BCF\u6761\u6D88\u606F\u4F1A\u5148\u7528\u6A21\u677F\u5305\u88F9\u5E76\u8BF7\u6C42\u6A21\u578B\uFF0C\u8FD4\u56DE\u7684\u5206\u6790\u7ED3\u679C\u4F5C\u4E3A\u672C\u6B21\u8F93\u5165\uFF1B\u5DF2\u5199\u5165\u914D\u7F6E\u3002${ansi.reset}`\n : `${ansi.gray}\u610F\u56FE\u5206\u6790\uFF1A\u5173 \u2014\u2014 \u76F4\u63A5\u4F7F\u7528\u4F60\u8F93\u5165\u7684\u5185\u5BB9\uFF1B\u5DF2\u5199\u5165\u914D\u7F6E\u3002${ansi.reset}`,\n );\n break;\n }\n case \"model\": {\n const entries = effectiveModels(this.options.config).sort(\n (a, b) => b.weight - a.weight,\n );\n const weightText =\n this.modelWeight !== undefined ? `\uFF08\u6743\u91CD ${this.modelWeight}\uFF09` : \"\";\n this.lines.push(\n `${ansi.gray}\u5F53\u524D\u6A21\u578B\uFF1A${ansi.reset}${this.modelProviderLabel} / ${this.modelLabel}${ansi.gray}${weightText}${ansi.reset}`,\n );\n if (entries.length > 0) {\n this.lines.push(`${ansi.gray}\u5DF2\u914D\u7F6E\u6A21\u578B\uFF08\u6309\u6743\u91CD\u964D\u5E8F\uFF09\uFF1A${ansi.reset}`);\n for (const entry of entries) {\n const current = entry.model === this.modelLabel ? \" \u2190 \u5F53\u524D\" : \"\";\n this.lines.push(\n `${ansi.gray} \u00B7 ${entry.id}\u3000\u6743\u91CD ${entry.weight}${current}${ansi.reset}`,\n );\n }\n }\n this.lines.push(\n `${ansi.gray}\u7BA1\u7406\u6A21\u578B\uFF08\u65B0\u589E / \u5220\u9664 / \u8C03\u6574\u6743\u91CD\uFF09\uFF1A${ansi.reset}xzh model${ansi.reset}`,\n );\n break;\n }\n default:\n this.lines.push(`${ansi.yellow}\u672A\u77E5\u547D\u4EE4\uFF1A/${command}\uFF0C\u8F93\u5165 /help \u67E5\u770B\u5E2E\u52A9\u3002${ansi.reset}`);\n }\n this.scheduleRender();\n }\n\n /** \u5207\u6362\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF08/switch\uFF09 */\n private switchDirectory(input: string): void {\n const expanded = expandHome(input.trim());\n const target = path.isAbsolute(expanded)\n ? expanded\n : path.resolve(this.cwd, expanded);\n\n if (!fs.existsSync(target)) {\n this.lines.push(`${ansi.red}\u2717 \u76EE\u5F55\u4E0D\u5B58\u5728\uFF1A${target}${ansi.reset}`);\n this.scheduleRender();\n return;\n }\n if (!fs.statSync(target).isDirectory()) {\n this.lines.push(`${ansi.red}\u2717 \u4E0D\u662F\u76EE\u5F55\uFF1A${target}${ansi.reset}`);\n this.scheduleRender();\n return;\n }\n\n let resolved = target;\n try {\n resolved = fs.realpathSync(target);\n } catch {\n // \u4FDD\u7559\u539F\u59CB\u8DEF\u5F84\n }\n\n this.cwd = resolved;\n // \u76EE\u6807\u76EE\u5F55\u82E5\u5C1A\u65E0\u9879\u76EE\u76EE\u5F55\uFF0C\u5C31\u5730\u521D\u59CB\u5316\uFF08.xuanzhu \u53EA\u5C5E\u4E8E\u5F53\u524D\u9879\u76EE\u8DEF\u5F84\uFF0C\u4E0D\u505A\u5411\u4E0A\u67E5\u627E\uFF09\n const project = ensureProjectDir(resolved);\n this.agent.setCwd(resolved);\n this.term.setCwd(resolved);\n this.termScroll = 0;\n this.lines.push(`${ansi.green}\u2713 \u5DF2\u5207\u6362\u9879\u76EE\u76EE\u5F55\uFF1A${resolved}${ansi.reset}`);\n if (project.created) {\n this.lines.push(\n `${ansi.gray} \u5DF2\u521D\u59CB\u5316\u9879\u76EE\u76EE\u5F55 ${project.paths.dir}\uFF08memory/ \u8BB0\u5FC6 \u00B7 rules.md \u89C4\u5219\uFF09${ansi.reset}`,\n );\n }\n this.lines.push(\n `${ansi.gray} \u540E\u7EED\u6587\u4EF6\u4E0E\u547D\u4EE4\u64CD\u4F5C\u5C06\u57FA\u4E8E\u8BE5\u76EE\u5F55\uFF1B\u5BF9\u8BDD\u4E0A\u4E0B\u6587\u5DF2\u4FDD\u7559\uFF08\u53EF\u7528 /reset \u6E05\u7A7A\uFF09\u3002${ansi.reset}`,\n );\n this.scheduleRender();\n }\n\n private printHelp(): void {\n const help = [\n `${ansi.bold}\u7384\u732A \u5185\u7F6E\u547D\u4EE4${ansi.reset}`,\n ` /help \u663E\u793A\u672C\u5E2E\u52A9`,\n ` /clear \u6E05\u7A7A\u5C4F\u5E55`,\n ` /reset \u91CD\u7F6E\u5BF9\u8BDD\u4E0A\u4E0B\u6587`,\n ` /cwd \u663E\u793A\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55`,\n ` /switch <\u76EE\u5F55> \u5207\u6362\u5F53\u524D\u5BF9\u8BDD\u7684\u9879\u76EE\u76EE\u5F55`,\n ` /term \u663E\u793A/\u9690\u85CF\u53F3\u4FA7\u7EC8\u7AEF\u9762\u677F\uFF08/term clear \u6E05\u7A7A\u8F93\u51FA\uFF09`,\n ` /model \u663E\u793A\u5F53\u524D\u6A21\u578B\u4E0E\u6743\u91CD\u3001\u5DF2\u914D\u7F6E\u6A21\u578B\u5217\u8868`,\n ` /auto [on|off] \u5207\u6362\u81EA\u52A8\u6279\u51C6\uFF08on\uFF1A\u6240\u6709\u5DE5\u5177\u76F4\u63A5\u6267\u884C\uFF0C\u5199\u5165\u914D\u7F6E\uFF09`,\n ` /intent [on|off] \u5207\u6362\u610F\u56FE\u5206\u6790\uFF08on\uFF1A\u6BCF\u6761\u6D88\u606F\u5148\u505A\u610F\u56FE\u5206\u6790\u518D\u5904\u7406\uFF0C\u5199\u5165\u914D\u7F6E\uFF09`,\n ` /exit \u9000\u51FA\u7384\u732A`,\n `${ansi.bold}\u5FEB\u6377\u952E${ansi.reset}`,\n ` Enter \u63D0\u4EA4 \u00B7 Ctrl+Enter / Shift+Enter \u6362\u884C\uFF08Ctrl+J \u4EA6\u53EF\uFF09`,\n ` \u2191/\u2193 \u5386\u53F2 \u00B7 Ctrl+A/Ctrl+E \u884C\u9996/\u884C\u5C3E \u00B7 PgUp/PgDn \u7FFB\u9875 \u00B7 Shift+\u2191/\u2193 \u9010\u884C`,\n ` Home/End \u8DF3\u5230\u6700\u65E9/\u6700\u65B0`,\n ` \u9F20\u6807\u6EDA\u8F6E\u6309\u6307\u9488\u6240\u5728\u680F\u6EDA\u52A8\uFF08\u5DE6\u680F\u5BF9\u8BDD / \u53F3\u680F\u7EC8\u7AEF\uFF09\uFF0C\u6EDA\u52A8\u65F6\u72B6\u6001\u680F\u663E\u793A \u2191N`,\n ` Shift+Tab \u5207\u6362\u7126\u70B9\uFF08\u5BF9\u8BDD \u21C4 \u53F3\u4FA7\u7EC8\u7AEF\uFF09\u00B7 \u9F20\u6807\u70B9\u51FB\u4EA6\u53EF`,\n ` Ctrl+C \u4E2D\u65AD\u4EFB\u52A1 / \u6E05\u7A7A\u8F93\u5165 / \u9000\u51FA\uFF08\u7A7A\u95F2\u4E14\u8F93\u5165\u4E3A\u7A7A\u65F6\u9000\u51FA\uFF09`,\n ` Ctrl+D \u7ED3\u675F\u672C\u8F6E\u6B63\u5728\u8FDB\u884C\u7684\u5BF9\u8BDD \u00B7 \u4EFB\u4F55\u60C5\u51B5\u4E0B\u90FD\u4E0D\u4F1A\u9000\u51FA\u7384\u732A`,\n ` Ctrl+L \u6E05\u5C4F`,\n ` \u6CE8\uFF1A\u591A\u6570 IDE \u5185\u7F6E\u7EC8\u7AEF\uFF08\u542B VS Code / CodeBuddy\uFF09\u9ED8\u8BA4\u628A Ctrl/Shift+Enter \u7F16\u6210\u4E0E Enter`,\n ` \u76F8\u540C\u7684\u5B57\u8282\uFF0C\u9700\u5728 IDE \u91CC\u628A\u8FD9\u4E24\u4E2A\u952E\u7ED1\u5B9A\u4E3A\u53D1\u9001 ESC[13;5u / ESC[13;2u\uFF08\u89C1 README\uFF09\u3002`,\n `${ansi.bold}\u53F3\u4FA7\u7EC8\u7AEF${ansi.reset}`,\n ` Enter \u6267\u884C\u547D\u4EE4 \u00B7 \u2191/\u2193 \u547D\u4EE4\u5386\u53F2 \u00B7 Ctrl+C / Ctrl+D \u4E2D\u65AD\u8FD0\u884C\u4E2D\u7684\u547D\u4EE4 \u00B7 Ctrl+L \u6E05\u7A7A`,\n ` PgUp/PgDn / Shift+\u2191\u2193 / Home/End \u56DE\u770B\u5386\u53F2\u8F93\u51FA\uFF08\u6EDA\u52A8\u4E0D\u5F71\u54CD\u6B63\u5728\u8FD0\u884C\u7684\u547D\u4EE4\uFF09`,\n ` \u547D\u4EE4\u5728\u5F53\u524D\u9879\u76EE\u76EE\u5F55\u4E0B\u6267\u884C\uFF1Bcd \u751F\u6548\uFF08\u9762\u677F\u81EA\u884C\u7EF4\u62A4\u5DE5\u4F5C\u76EE\u5F55\uFF09`,\n ];\n this.lines.push(...help.map((line) => `${ansi.gray}${line}${ansi.reset}`));\n this.lines.push(\"\");\n }\n\n /**\n * \u9876\u90E8\u56FA\u5B9A\u5934\u90E8\uFF08\u59CB\u7EC8\u663E\u793A\uFF0C\u4E0D\u53C2\u4E0E\u5BF9\u8BDD\u6EDA\u52A8\uFF09\u3002\n *\n * \u4FE1\u606F\u884C\u4E0E\u672B\u5C3E\u5206\u9694\u7EBF\u5206\u5F00\u8FD4\u56DE\uFF1A\u5206\u9694\u7EBF\u662F\u300C\u9876\u90E8\u4FE1\u606F\u533A\u300D\u4E0E\u300C\u5BF9\u8BDD\u533A\u300D\u7684\u5206\u754C\uFF0C\n * \u9AD8\u5EA6\u53D7\u9650\u65F6\u5FC5\u987B\u4FDD\u7559\uFF08\u89C1 render \u7684\u5934\u90E8\u88C1\u526A\uFF09\uFF0C\u6545\u4E0D\u80FD\u88AB\u4E00\u8D77\u88C1\u6389\u3002\n */\n private buildHeaderLines(width: number): { info: string[]; divider: string } {\n const weightText =\n this.modelWeight !== undefined ? ` \u00B7 \u6743\u91CD ${this.modelWeight}` : \"\";\n const modelText = truncate(\n `${this.modelProviderLabel} / ${this.modelLabel}${weightText}`,\n Math.max(10, width - 8),\n );\n const dirText = truncate(this.cwd, Math.max(10, width - 8));\n const divider = `${ansi.gray}${\"\u2500\".repeat(Math.max(0, width))}${ansi.reset}`;\n const info = [\n `${ansi.brightMagenta}${ansi.bold} \u7384\u732A XuanZhu${ansi.reset} ${ansi.gray}v0.1.0 \u00B7 \u7EC8\u7AEF AI \u7F16\u7801 Agent${ansi.reset}`,\n `${ansi.gray} \u6A21\u578B\uFF1A${ansi.reset}${modelText}${ansi.reset}`,\n `${ansi.gray} \u76EE\u5F55\uFF1A${ansi.reset}${dirText}${ansi.reset}`,\n `${ansi.gray} \u8F93\u5165 ${ansi.reset}${ansi.brightGreen}/help${ansi.reset}${ansi.gray} \u67E5\u770B\u547D\u4EE4\u4E0E\u5FEB\u6377\u952E${ansi.reset}`,\n `${ansi.gray} ${ansi.reset}Ctrl+D${ansi.gray} \u7ED3\u675F\u672C\u8F6E\u5BF9\u8BDD\uFF08\u4E0D\u9000\u51FA\uFF09\u00B7 ${ansi.reset}Ctrl+C${ansi.gray} \u4E2D\u65AD/\u6E05\u7A7A/\u9000\u51FA${ansi.reset}`,\n `${ansi.gray} ${ansi.reset}Shift+Tab${ansi.gray} \u5207\u7EC8\u7AEF \u00B7 ${ansi.reset}PgUp${ansi.gray}/\u6EDA\u8F6E\u56DE\u770B\u5386\u53F2${ansi.reset}`,\n ];\n return { info, divider };\n }\n\n // ------------------------------------------------------------------ \u6E32\u67D3\n\n private scheduleRender(): void {\n if (this.needsRender || this.exited) return;\n this.needsRender = true;\n setTimeout(() => {\n this.needsRender = false;\n this.render();\n }, 16);\n }\n\n private render(): void {\n if (this.exited) return;\n const columns = Math.max(40, process.stdout.columns || 80);\n const rows = Math.max(8, process.stdout.rows || 24);\n\n // \u5206\u680F\u5E03\u5C40\uFF1A\u5DE6\u4FA7\uFF08\u5934\u90E8 / \u5BF9\u8BDD / \u8F93\u5165\uFF09+ \u5206\u9694\u7EBF + \u53F3\u4FA7\u7EC8\u7AEF\u9762\u677F\uFF0C\u5E95\u90E8\u72B6\u6001\u680F\u6A2A\u8DE8\u5168\u5BBD\n const termWidth = this.resolveTermWidth(columns);\n const leftWidth =\n termWidth > 0 ? Math.max(20, columns - termWidth - 1) : columns;\n this.lastLeftWidth = leftWidth;\n\n const inputBlock = this.pendingConfirm\n ? this.layoutConfirm(leftWidth)\n : this.layoutInput(leftWidth);\n const inputRows = inputBlock.lines.length;\n const statusRows = 1;\n\n // \u56FA\u5B9A\u5934\u90E8\uFF1A\u59CB\u7EC8\u663E\u793A\uFF0C\u9AD8\u5EA6\u4E0D\u8D85\u8FC7\u7EC8\u7AEF\u9AD8\u5EA6\u7684 1/3\u3002\n // \u9AD8\u5EA6\u4E0D\u8DB3\u65F6\u4ECE\u4FE1\u606F\u884C\u5F00\u59CB\u88C1\u526A\uFF08\u4FDD\u7559\u6700\u4E0A\u9762\u7684\u54C1\u724C\u884C\uFF09\uFF0C\u4F46\u672B\u5C3E\u5206\u9694\u7EBF**\u5FC5\u987B**\u4FDD\u7559\uFF0C\n // \u5426\u5219\u300C\u9876\u90E8\u4FE1\u606F\u533A\u300D\u4E0E\u300C\u5BF9\u8BDD\u533A\u300D\u4E4B\u95F4\u6CA1\u6709\u5206\u754C\u7EBF\u3002\n const header = this.buildHeaderLines(leftWidth);\n const maxHeaderRows = Math.max(1, Math.floor(rows / 3));\n const infoRows = Math.min(\n header.info.length,\n Math.max(0, maxHeaderRows - 1),\n );\n const headerLines = [...header.info.slice(0, infoRows), header.divider];\n const headerRows = headerLines.length;\n const outputRows = Math.max(3, rows - headerRows - inputRows - statusRows);\n\n // \u6EDA\u52A8\uFF1AscrollOffset \u8868\u793A\u300C\u89C6\u53E3\u5E95\u90E8\u8DDD\u6700\u65B0\u884C\u7684\u7269\u7406\u884C\u6570\u300D\uFF0C0 \u5373\u8DDF\u968F\u6700\u65B0\u8F93\u51FA\u3002\n const allLines = this.physicalLines(leftWidth);\n const count = allLines.length;\n // \u89C6\u53E3\u951A\u5B9A\uFF1A\u5DF2\u4E0A\u7FFB\u65F6\u65B0\u5230\u8FBE\u7684\u884C\u4E0D\u5E94\u628A\u6B63\u5728\u9605\u8BFB\u7684\u5386\u53F2\u9876\u8D70\uFF0C\n // \u6545\u628A\u504F\u79FB\u91CF\u540C\u6B65\u589E\u52A0\u65B0\u589E\u7684\u7269\u7406\u884C\u6570\uFF08\u7B49\u4E8E\u628A\u89C6\u53E3\u56FA\u5B9A\u5728\u539F\u4F4D\u7F6E\uFF09\u3002\n if (\n this.lastPhysicalCount >= 0 &&\n this.scrollOffset > 0 &&\n count > this.lastPhysicalCount\n ) {\n this.scrollOffset += count - this.lastPhysicalCount;\n }\n this.lastPhysicalCount = count;\n const maxScroll = Math.max(0, count - outputRows);\n if (this.scrollOffset > maxScroll) this.scrollOffset = maxScroll;\n const end = count - this.scrollOffset;\n const start = Math.max(0, end - outputRows);\n const visible = allLines.slice(start, end);\n while (visible.length < outputRows) visible.unshift(\"\");\n\n const bodyRows = rows - 1;\n const panel =\n termWidth > 0\n ? this.buildTermPanel(termWidth, bodyRows)\n : { rows: [] as string[], cursorRow: 0, cursorCol: 0 };\n\n const inputStart = headerRows + outputRows;\n\n let out = cursor.hide;\n for (let i = 0; i < bodyRows; i++) {\n let left: string;\n if (i < headerRows) {\n left = headerLines[i];\n } else if (i < headerRows + outputRows) {\n left = visible[i - headerRows];\n } else if (i < inputStart + inputRows) {\n left = inputBlock.lines[i - inputStart];\n } else {\n left = \"\";\n }\n\n out += cursor.to(i + 1, 1) + \"\\x1b[2K\";\n if (termWidth > 0) {\n out +=\n padEnd(truncate(left, leftWidth), leftWidth) +\n `${ansi.gray}\u2502${ansi.reset}` +\n truncate(panel.rows[i] ?? \"\", termWidth);\n } else {\n out += left;\n }\n }\n\n out += cursor.to(rows, 1) + \"\\x1b[2K\" + this.renderStatus(columns);\n\n if (this.pendingConfirm) {\n out += cursor.hide;\n } else if (this.termFocus && termWidth > 0 && panel.cursorRow > 0) {\n // \u7126\u70B9\u5728\u53F3\u4FA7\u7EC8\u7AEF\uFF1A\u5149\u6807\u5B9A\u4F4D\u5230\u7EC8\u7AEF\u8F93\u5165\u884C\uFF08\u9762\u677F\u4ECE leftWidth+2 \u5217\u5F00\u59CB\uFF09\n const row = panel.cursorRow;\n const col = Math.min(columns, leftWidth + 1 + panel.cursorCol);\n out += cursor.to(row, col) + cursor.show;\n } else {\n const row = inputStart + inputBlock.cursorRow + 1;\n const col = Math.min(leftWidth, inputBlock.cursorCol + 1);\n out += cursor.to(row, col) + cursor.show;\n }\n\n process.stdout.write(out);\n }\n\n /** \u53F3\u4FA7\u7EC8\u7AEF\u9762\u677F\u5BBD\u5EA6\uFF080 \u8868\u793A\u4E0D\u663E\u793A\uFF1A\u624B\u52A8\u9690\u85CF\u6216\u7EC8\u7AEF\u8FC7\u7A84\uFF09 */\n private resolveTermWidth(columns: number): number {\n if (!this.termVisible || columns < 80) return 0;\n return Math.min(64, Math.max(32, Math.floor(columns * 0.4)));\n }\n\n /**\n * \u751F\u6210\u53F3\u4FA7\u7EC8\u7AEF\u9762\u677F\uFF1A\u6807\u9898\uFF08\u5DE5\u4F5C\u76EE\u5F55 + \u8FD0\u884C\u72B6\u6001\uFF09\u3001\u8F93\u51FA\u533A\uFF08\u53EF\u6EDA\u52A8\uFF09\u3001\u8F93\u5165\u884C\u3002\n * cursorRow / cursorCol \u4E3A\u9762\u677F\u5185 1-based \u5750\u6807\uFF0C\u4F9B\u805A\u7126\u65F6\u5B9A\u4F4D\u5149\u6807\u3002\n */\n private buildTermPanel(\n width: number,\n height: number,\n ): { rows: string[]; cursorRow: number; cursorCol: number } {\n if (width <= 0 || height <= 0) {\n return { rows: [], cursorRow: 0, cursorCol: 0 };\n }\n\n const rows: string[] = [];\n const running = this.term.isRunning();\n\n // \u6807\u9898\u884C\uFF1A\u7EC8\u7AEF\u6807\u8BC6 + \u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55 + \u8FD0\u884C\u72B6\u6001\n const label = this.termFocus\n ? `${ansi.bgBlue}${ansi.brightWhite} \u7EC8\u7AEF ${ansi.reset}`\n : `${ansi.gray} \u7EC8\u7AEF ${ansi.reset}`;\n const status = running ? `${ansi.brightYellow} \u25CF \u8FD0\u884C\u4E2D${ansi.reset}` : \"\";\n const room = Math.max(6, width - 9 - (running ? 5 : 0));\n rows.push(\n `${label}${ansi.gray}${truncate(this.term.getCwd(), room)}${ansi.reset}${status}`,\n );\n\n // \u8F93\u51FA\u533A\uFF08\u7269\u7406\u884C\uFF0C\u6309\u9AD8\u5EA6\u88C1\u5207\uFF0C\u652F\u6301\u6EDA\u52A8\uFF09\n const outputHeight = Math.max(1, height - 3);\n const physical: string[] = [];\n for (const line of this.term.visibleLines()) {\n physical.push(...wrapText(line, width));\n }\n // \u89C6\u53E3\u951A\u5B9A\uFF1A\u4E0E\u5DE6\u680F\u540C\u7406\uFF0C\u547D\u4EE4\u6301\u7EED\u8F93\u51FA\u65F6\u4FDD\u6301\u7528\u6237\u6B63\u5728\u67E5\u770B\u7684\u5386\u53F2\u4E0D\u52A8\n if (\n this.lastTermPhysicalCount >= 0 &&\n this.termScroll > 0 &&\n physical.length > this.lastTermPhysicalCount\n ) {\n this.termScroll += physical.length - this.lastTermPhysicalCount;\n }\n this.lastTermPhysicalCount = physical.length;\n const maxScroll = Math.max(0, physical.length - outputHeight);\n if (this.termScroll > maxScroll) this.termScroll = maxScroll;\n const end = physical.length - this.termScroll;\n const start = Math.max(0, end - outputHeight);\n const slice = physical.slice(start, end);\n while (slice.length < outputHeight) slice.unshift(\"\");\n rows.push(...slice);\n\n // \u5206\u9694\u7EBF + \u8F93\u5165\u884C\uFF08\u8D85\u5BBD\u65F6\u4ECE\u5DE6\u4FA7\u6EDA\u52A8\uFF0C\u4FDD\u8BC1\u5149\u6807\u53EF\u89C1\uFF09\n rows.push(`${ansi.gray}${\"\u2500\".repeat(width)}${ansi.reset}`);\n const promptWidth = 2;\n const avail = Math.max(1, width - promptWidth);\n let text = this.termInput;\n let cursorWidth = textWidth(text.slice(0, this.termInputCursor));\n while (cursorWidth > avail && text.length > 0) {\n text = text.slice(1);\n cursorWidth = textWidth(text.slice(0, this.termInputCursor));\n }\n const prompt = this.termFocus\n ? `${ansi.brightCyan}\u276F${ansi.reset} `\n : `${ansi.gray}\u276F${ansi.reset} `;\n rows.push(truncate(`${prompt}${text}`, width));\n\n const cursorRow = rows.length;\n const cursorCol = Math.min(width, promptWidth + cursorWidth + 1);\n\n while (rows.length < height) rows.push(\"\");\n return { rows: rows.slice(0, height), cursorRow, cursorCol };\n }\n\n private physicalLines(width: number): string[] {\n const result: string[] = [];\n for (const line of this.lines) {\n result.push(...wrapText(line, width));\n }\n if (this.streamingPreview) {\n result.push(...wrapText(this.streamingPreview, width));\n }\n return result;\n }\n\n private renderStatus(width: number): string {\n const left = ` \u7384\u732A `;\n const autoMark = this.autoApprove ? \"\u26A1auto \u00B7 \" : \"\";\n const intentMark = this.intentEnabled ? \"\u2301intent \u00B7 \" : \"\";\n const focusMark = this.termVisible\n ? this.termFocus\n ? \"\u7EC8\u7AEF\u25B8 \"\n : \"\u5BF9\u8BDD\u25B8 \"\n : \"\";\n const weightMark =\n this.modelWeight !== undefined ? ` w${this.modelWeight}` : \"\";\n // \u6EDA\u52A8\u6307\u793A\uFF1A\u504F\u79FB\u91CF > 0 \u65F6\u63D0\u793A\u5DF2\u4E0A\u7FFB\u7684\u884C\u6570\uFF0C\u4FBF\u4E8E\u53D1\u73B0\u300C\u6709\u5386\u53F2\u53EF\u56DE\u770B / \u9700\u6309 End \u56DE\u5230\u6700\u65B0\u300D\n const scrollMark =\n this.scrollOffset > 0\n ? `${ansi.brightYellow}\u2191${this.scrollOffset}${ansi.reset}${ansi.bgBlue} `\n : \"\";\n const termScrollMark =\n this.termScroll > 0\n ? `${ansi.brightYellow}\u21E1${this.termScroll}${ansi.reset}${ansi.bgBlue} `\n : \"\";\n const right = ` ${autoMark}${intentMark}${focusMark}${scrollMark}${termScrollMark}${this.modelLabel}${weightMark} \u2502 ${this.statusText}${this.statusDetail ? \" \u00B7 \" + this.statusDetail : \"\"} `;\n const middle = ` ${this.cwd} `;\n const elapsed = this.busy ? `${ansi.brightYellow}\u25CF \u8FD0\u884C\u4E2D${ansi.reset}${ansi.bgBlue}` : \"\";\n // elapsed \u7684\u663E\u793A\u5BBD\u5EA6\u5FC5\u987B\u8BA1\u5165\u4FDD\u7559\u5BBD\u5EA6\uFF0C\u5426\u5219 busy \u65F6\u72B6\u6001\u680F\u5FC5\u7136\u8D85\u5BBD\u5E76\u8D70\u515C\u5E95\u622A\u65AD\n const reserved =\n textWidth(left) + textWidth(right) + textWidth(elapsed) + 6;\n let text = `${ansi.bgBlue}${ansi.brightWhite}${left}${ansi.reset}${ansi.bgBlue}${ansi.brightWhite}${elapsed}${ansi.bgBlue}${ansi.gray}${truncate(middle, Math.max(0, width - reserved))}${ansi.bgBlue}${ansi.brightWhite}${right}${ansi.reset}`;\n const visible = textWidth(text);\n if (visible < width) {\n text += `${ansi.bgBlue}${\" \".repeat(width - visible)}${ansi.reset}`;\n } else if (visible > width) {\n // \u515C\u5E95\uFF1A\u4EFB\u4F55\u5BBD\u5EA6\u8BA1\u7B97\u8BEF\u5DEE\u90FD\u4E0D\u5141\u8BB8\u72B6\u6001\u680F\u8D85\u51FA\u7EC8\u7AEF\u5BBD\u5EA6\uFF08\u5426\u5219\u4F1A\u6298\u884C\u5E76\u63A8\u52A8\u6574\u5C4F\u6EDA\u52A8\uFF09\n text = `${truncate(text, width)}${ansi.reset}`;\n }\n return text;\n }\n\n private layoutInput(width: number): InputLayout {\n const promptFirst = \"\u276F \";\n const promptRest = \" \";\n const maxRows = Math.max(1, Math.floor((process.stdout.rows || 24) / 2) - 1);\n const chars = Array.from(this.input);\n\n // \u8BA1\u7B97\u5149\u6807\u6240\u5728\u7684 code point \u7D22\u5F15\n let cursorCp = 0;\n {\n let count = 0;\n cursorCp = chars.length;\n for (let i = 0; i < chars.length; i++) {\n if (count >= this.inputCursor) {\n cursorCp = i;\n break;\n }\n count += chars[i].length;\n }\n }\n\n const physLines: string[] = [];\n let current = promptFirst;\n let currentWidth = textWidth(promptFirst);\n let cursorRow = 0;\n let cursorCol = currentWidth;\n\n for (let i = 0; i < chars.length; i++) {\n const ch = chars[i];\n if (ch === \"\\n\") {\n physLines.push(current);\n current = promptRest;\n currentWidth = textWidth(promptRest);\n if (i === cursorCp) {\n cursorRow = physLines.length;\n cursorCol = currentWidth;\n }\n continue;\n }\n const w = textWidth(ch);\n if (currentWidth + w > width) {\n physLines.push(current);\n current = promptRest;\n currentWidth = textWidth(promptRest);\n }\n if (i === cursorCp) {\n cursorRow = physLines.length;\n cursorCol = currentWidth;\n }\n current += ch;\n currentWidth += w;\n }\n if (cursorCp >= chars.length) {\n cursorRow = physLines.length;\n cursorCol = currentWidth;\n }\n physLines.push(current);\n\n if (physLines.length > maxRows) {\n const start = Math.max(0, cursorRow - maxRows + 1);\n return {\n lines: physLines.slice(start, start + maxRows),\n cursorRow: cursorRow - start,\n cursorCol,\n };\n }\n return { lines: physLines, cursorRow, cursorCol };\n }\n\n private layoutConfirm(width: number): InputLayout {\n const pending = this.pendingConfirm!;\n const { request } = pending;\n const lines: string[] = [];\n const danger = request.danger;\n lines.push(\n `${danger ? ansi.brightRed : ansi.brightYellow}\u26A0 ${request.title}${ansi.reset}`,\n );\n const detailLines = request.detail.split(\"\\n\").slice(0, 12);\n for (const detail of detailLines) {\n for (const wrapped of wrapText(`${ansi.gray}${detail}${ansi.reset}`, width - 4)) {\n lines.push(` ${wrapped}`);\n }\n }\n const allow = pending.selected\n ? `${ansi.inverse}${ansi.green} \u5141\u8BB8 ${ansi.reset}`\n : `${ansi.gray} \u5141\u8BB8 ${ansi.reset}`;\n const deny = !pending.selected\n ? `${ansi.inverse}${ansi.yellow} \u62D2\u7EDD ${ansi.reset}`\n : `${ansi.gray} \u62D2\u7EDD ${ansi.reset}`;\n lines.push(` ${allow} ${deny} ${ansi.gray}\u2190 \u2192 \u5207\u6362 \u00B7 Enter \u786E\u8BA4 \u00B7 y/n \u5FEB\u6377${ansi.reset}`);\n return { lines, cursorRow: 0, cursorCol: 0 };\n }\n}\n\n// ------------------------------------------------------------ \u6269\u5C55\u6309\u952E\u5F52\u4E00\u5316\n\n/** \u4FEE\u9970\u4F4D\uFF08kitty \u952E\u76D8\u534F\u8BAE\u4E0E xterm \u4E00\u81F4\uFF1A\u53C2\u6570\u503C = 1 + \u4F4D\u63A9\u7801\uFF09 */\nconst MOD_SHIFT = 1;\nconst MOD_ALT = 2;\nconst MOD_CTRL = 4;\n\n/** \u628A\u300CCtrl + \u5B57\u6BCD/\u7B26\u53F7\u300D\u8FD8\u539F\u4E3A\u5BF9\u5E94\u7684\u63A7\u5236\u5B57\u7B26\uFF1B\u65E0\u6CD5\u8FD8\u539F\u65F6\u8FD4\u56DE null */\nfunction controlCharFrom(code: number, mods: number): string | null {\n if ((mods & MOD_CTRL) === 0) return null;\n const lower = code >= 65 && code <= 90 ? code + 32 : code;\n if (lower >= 97 && lower <= 122) return String.fromCharCode(lower - 96);\n switch (code) {\n case 32: // Ctrl+Space\n case 64: // Ctrl+@\n return \"\\x00\";\n case 91:\n return \"\\x1b\";\n case 92:\n return \"\\x1c\";\n case 93:\n return \"\\x1d\";\n case 94:\n return \"\\x1e\";\n case 95: // Ctrl+_\n case 47: // Ctrl+/\n return \"\\x1f\";\n default:\n return null;\n }\n}\n\n/** \u300C\u952E\u7801 + \u4FEE\u9970\u4F4D\u300D\u2192 \u672C\u5E94\u7528\u7684\u6309\u952E\u8BED\u4E49\uFF1B\u65E0\u6CD5\u6620\u5C04\u65F6\u8FD4\u56DE null\uFF08\u539F\u6837\u4E22\u5F03\uFF09 */\nfunction normalizeModifiedKey(code: number, mods: number): string | null {\n const modified = (mods & (MOD_SHIFT | MOD_CTRL | MOD_ALT)) !== 0;\n switch (code) {\n case 13: // Enter\uFF1A\u5E26\u4FEE\u9970\u952E \u2192 \u6362\u884C\uFF1B\u88F8 Enter \u2192 \u63D0\u4EA4\n return modified ? \"\\n\" : \"\\r\";\n case 9: // Tab\uFF1AShift+Tab \u2192 \u5207\u6362\u7126\u70B9\n return modified && (mods & MOD_CTRL) === 0 ? \"\\x1b[Z\" : \"\\t\";\n case 8: // \u9000\u683C\uFF1ACtrl/Alt+\u9000\u683C\u4E00\u5E76\u6309\u5220\u9664\u5904\u7406\n case 127:\n return \"\\x7f\";\n default:\n return controlCharFrom(code, mods);\n }\n}\n\n/**\n * \u5F52\u4E00\u5316\u300C\u4FEE\u9970\u952E + Enter / Tab\u300D\u7B49\u7EC8\u7AEF\u6269\u5C55\u5E8F\u5217\u3002\n *\n * Enter \u7CFB\u6309\u952E\u5728\u5404\u7EC8\u7AEF\u4E0B\u7684\u7F16\u7801\u5B8C\u5168\u4E0D\u540C\uFF0C\u8FD9\u91CC\u7EDF\u4E00\u6210\u672C\u5E94\u7528\u65E2\u6709\u8BED\u4E49\n * \uFF08`\\r` \u63D0\u4EA4\u3001`\\n` \u6362\u884C\u3001`\\x1b[Z` \u5207\u6362\u7126\u70B9\uFF09\uFF1A\n * - `ESC CR`\uFF1Alegacy \u7EC8\u7AEF\u7684 Ctrl+Enter\uFF08xterm \u7CFB\u540C\u65F6\u7528\u5B83\u8868\u793A Alt+Enter\uFF09\uFF1B\n * - `CSI 13 ; <mod> u`\uFF1Akitty \u952E\u76D8\u534F\u8BAE\uFF08report-all-keys \u6A21\u5F0F\uFF09\u4E0B\u7684 Shift / Ctrl+Enter\uFF1B\n * - `CSI 27 ; <mod> ; 13 ~`\uFF1Axterm `modifyOtherKeys` \u4E0B\u7684 Shift / Ctrl+Enter\u3002\n *\n * \u53E6\u5916\uFF0C\u5904\u4E8E\u4E0A\u62A5\u6A21\u5F0F\u7684\u7EC8\u7AEF\u4F1A\u628A Ctrl+\u5B57\u6BCD\u4E5F\u6539\u6210\u8F6C\u4E49\u7801\uFF0C\u8FD9\u91CC\u4E00\u5E76\u8FD8\u539F\u6210\u63A7\u5236\u5B57\u7B26\uFF0C\n * \u4FDD\u8BC1 Ctrl+C / Ctrl+A / Ctrl+E / Ctrl+J / Ctrl+L \u7B49\u65E2\u6709\u5FEB\u6377\u952E\u4E0D\u53D7\u5F71\u54CD\u3002\n */\nfunction normalizeKey(key: string): string {\n // ESC + Enter\uFF1A\u90E8\u5206\u7EC8\u7AEF\uFF08Ctrl+Enter / Alt+Enter\uFF09\u6CBF\u7528\u8BE5\u4F20\u7EDF\u7F16\u7801\n if (key === \"\\x1b\\r\" || key === \"\\x1b\\n\") return \"\\n\";\n\n // kitty \u952E\u76D8\u534F\u8BAE / CSI u\uFF1ACSI <code>[:<alternate>] [;<mod>] u\n const csiU = /^\\x1b\\[(\\d+)(?::\\d+)?(?:;(\\d+))?u$/.exec(key);\n if (csiU) {\n const mods = csiU[2] ? Number(csiU[2]) - 1 : 0;\n return normalizeModifiedKey(Number(csiU[1]), mods) ?? key;\n }\n\n // xterm modifyOtherKeys\uFF1ACSI 27 ; <mod> [; <code>] ~\uFF08\u7701\u7565\u952E\u7801\u4EE3\u8868 ESC\uFF09\n const xtMod = /^\\x1b\\[27;(\\d+)(?:;(\\d+))?~$/.exec(key);\n if (xtMod) {\n const mods = Number(xtMod[1]) - 1;\n const code = xtMod[2] ? Number(xtMod[2]) : 27;\n return normalizeModifiedKey(code, mods) ?? key;\n }\n\n return key;\n}\n\nfunction summarizeToolCall(call: ToolCall): string {\n let args: Record<string, unknown> = {};\n try {\n const parsed = JSON.parse(call.arguments || \"{}\");\n if (typeof parsed === \"object\" && parsed !== null) {\n args = parsed as Record<string, unknown>;\n }\n } catch {\n return truncate(call.arguments, 60);\n }\n const pick = (key: string): string | undefined => {\n const value = args[key];\n return typeof value === \"string\" ? value : undefined;\n };\n const detail =\n pick(\"path\") ??\n pick(\"pattern\") ??\n pick(\"command\") ??\n pick(\"dirPath\") ??\n \"\";\n return truncate(detail.replace(/\\s+/g, \" \"), 80);\n}\n", "import { spawn } from \"child_process\";\nimport * as path from \"path\";\nimport { expandHome } from \"../utils/paths\";\nimport type { ToolDefinition, ToolResult } from \"./types\";\n\nconst MAX_OUTPUT = 30000;\nconst DEFAULT_TIMEOUT = 120_000;\nconst MAX_TIMEOUT = 600_000;\n\ninterface RunResult {\n stdout: string;\n stderr: string;\n code: number | null;\n timedOut: boolean;\n aborted: boolean;\n}\n\n/** \u7EC8\u6B62\u540E\u7B49\u5F85\u7BA1\u9053\u51B2\u5237 / \u5F3A\u6740\u515C\u5E95\u7684\u65F6\u95F4 */\nconst KILL_GRACE_MS = 1500;\n\n/**\n * \u5728\u5B50\u8FDB\u7A0B\u4E2D\u6267\u884C\u547D\u4EE4\u3002\n *\n * \u4E09\u4E2A\u5FC5\u987B\u5904\u7406\u7684\u70B9\uFF1A\n * 1. **\u53EF\u4E2D\u65AD**\uFF1A\u76D1\u542C `ctx.signal`\uFF0Cabort \u65F6\u6574\u7EC4\u7EC8\u6B62\uFF08\u6B64\u524D\u5B8C\u5168\u5FFD\u7565\u4E2D\u65AD\uFF0C\n * \u7528\u6237 Ctrl+C \u540E\u547D\u4EE4\u4ECD\u4F1A\u8DD1\u5B8C\uFF0C\u957F\u547D\u4EE4\u7B49\u540C\u65E0\u6CD5\u4E2D\u65AD\uFF09\u3002\n * 2. **\u6574\u7EC4\u7EC8\u6B62**\uFF1A\u4EE5 `detached: true` \u542F\u52A8\u6210\u4E3A\u72EC\u7ACB\u8FDB\u7A0B\u7EC4\uFF0C\u7528 `process.kill(-pid)`\n * \u6740\u6389 shell \u53CA\u5176\u6D3E\u751F\u7684\u5168\u90E8\u5B50\u8FDB\u7A0B\uFF0C\u907F\u514D\u7559\u4E0B\u5B64\u513F\u3002\n * 3. **\u4E0D\u4F1A\u6C38\u4E45\u6302\u8D77**\uFF1A`close` \u4E8B\u4EF6\u8981\u7B49\u6240\u6709 stdio\uFF08\u542B\u5B59\u8FDB\u7A0B\u7EE7\u627F\u7684\u7BA1\u9053\uFF09\u5173\u95ED\u624D\u89E6\u53D1\uFF0C\n * \u7BA1\u9053/\u540E\u53F0\u8FDB\u7A0B\u573A\u666F\u4E0B\u53EF\u80FD\u6C38\u4E0D\u89E6\u53D1\u3002\u56E0\u6B64\u7528 `exit` \u4E8B\u4EF6 + \u77ED\u5EF6\u8FDF\u515C\u5E95 resolve\u3002\n */\nfunction runCommand(\n command: string,\n cwd: string,\n timeoutMs: number,\n signal?: AbortSignal,\n): Promise<RunResult> {\n return new Promise((resolve) => {\n if (signal?.aborted) {\n resolve({\n stdout: \"\",\n stderr: \"\u547D\u4EE4\u5DF2\u88AB\u4E2D\u65AD\uFF08\u5728\u6267\u884C\u524D\uFF09\u3002\",\n code: null,\n timedOut: false,\n aborted: true,\n });\n return;\n }\n\n const isWindows = process.platform === \"win32\";\n const shell = isWindows ? \"cmd.exe\" : process.env.SHELL || \"bash\";\n const args = isWindows ? [\"/d\", \"/s\", \"/c\", command] : [\"-lc\", command];\n\n const child = spawn(shell, args, {\n cwd,\n env: process.env,\n windowsHide: true,\n // \u72EC\u7ACB\u8FDB\u7A0B\u7EC4\uFF1A\u8D85\u65F6\u6216\u4E2D\u65AD\u65F6\u53EF\u4EE5\u6574\u7EC4\u7EC8\u6B62\n detached: !isWindows,\n });\n\n let stdout = \"\";\n let stderr = \"\";\n let timedOut = false;\n let aborted = false;\n let settled = false;\n let idleTimer: NodeJS.Timeout | undefined;\n\n const killGroup = (sig: NodeJS.Signals): void => {\n const pid = child.pid;\n if (pid === undefined) return;\n try {\n process.kill(-pid, sig); // \u8D1F\u53F7\u8868\u793A\u8FDB\u7A0B\u7EC4\n } catch {\n try {\n child.kill(sig);\n } catch {\n // \u8FDB\u7A0B\u53EF\u80FD\u5DF2\u9000\u51FA\n }\n }\n };\n\n const finish = (code: number | null): void => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n if (idleTimer) clearTimeout(idleTimer);\n signal?.removeEventListener(\"abort\", onAbort);\n resolve({ stdout, stderr, code, timedOut, aborted });\n };\n\n /** \u7EC8\u6B62\u540E\u82E5 close \u8FDF\u8FDF\u4E0D\u6765\uFF0C\u515C\u5E95 resolve\uFF0C\u907F\u514D\u6574\u4E2A Agent/TUI \u5361\u6B7B */\n const forceFinishSoon = (): void => {\n if (idleTimer) clearTimeout(idleTimer);\n idleTimer = setTimeout(() => finish(null), KILL_GRACE_MS);\n };\n\n const onAbort = (): void => {\n aborted = true;\n killGroup(\"SIGKILL\");\n forceFinishSoon();\n };\n\n const timer = setTimeout(() => {\n timedOut = true;\n killGroup(\"SIGKILL\");\n forceFinishSoon();\n }, timeoutMs);\n\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n child.stdout?.on(\"data\", (data: Buffer) => {\n if (stdout.length < MAX_OUTPUT) stdout += data.toString();\n });\n child.stderr?.on(\"data\", (data: Buffer) => {\n if (stderr.length < MAX_OUTPUT) stderr += data.toString();\n });\n child.on(\"error\", (err) => {\n stderr += String(err);\n finish(-1);\n });\n // exit \u5148\u4E8E close \u89E6\u53D1\uFF1B\u7ED9\u5B83\u4E00\u4E2A\u5F88\u77ED\u7684\u7A97\u53E3\u51B2\u5237\u7BA1\u9053\u540E\u5C31\u7ED3\u675F\uFF0C\n // \u4E0D\u518D\u65E0\u9650\u7B49\u5F85\u53EF\u80FD\u6C38\u4E0D\u89E6\u53D1\u7684 close\u3002\n child.on(\"exit\", (code) => {\n if (idleTimer) clearTimeout(idleTimer);\n idleTimer = setTimeout(() => finish(code), 120);\n });\n child.on(\"close\", (code) => finish(code));\n });\n}\n\nexport const bashTool: ToolDefinition = {\n name: \"bash\",\n description:\n \"\u5728\u7EC8\u7AEF\u4E2D\u6267\u884C shell \u547D\u4EE4\u5E76\u8FD4\u56DE\u8F93\u51FA\u3002\u9002\u7528\u4E8E\u8FD0\u884C\u6D4B\u8BD5\u3001\u6784\u5EFA\u3001\u5B89\u88C5\u4F9D\u8D56\u3001git \u64CD\u4F5C\u7B49\u3002\" +\n \"\u547D\u4EE4\u5728\u975E\u4EA4\u4E92\u5F0F shell \u4E2D\u6267\u884C\uFF0C\u957F\u65F6\u95F4\u8FD0\u884C\u7684\u547D\u4EE4\u8BF7\u8BBE\u7F6E timeout\u3002\",\n requiresConfirmation: true,\n danger: true,\n parameters: {\n type: \"object\",\n properties: {\n command: { type: \"string\", description: \"\u8981\u6267\u884C\u7684 shell \u547D\u4EE4\" },\n timeout: {\n type: \"integer\",\n description: \"\u8D85\u65F6\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF0C\u9ED8\u8BA4 120000\uFF0C\u6700\u5927 600000\uFF09\",\n },\n cwd: {\n type: \"string\",\n description: \"\u547D\u4EE4\u6267\u884C\u76EE\u5F55\uFF08\u53EF\u9009\uFF0C\u9ED8\u8BA4\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF09\",\n },\n },\n required: [\"command\"],\n },\n async execute(args, ctx): Promise<ToolResult> {\n const command = typeof args.command === \"string\" ? args.command : \"\";\n if (!command.trim()) {\n return { ok: false, content: \"\u9519\u8BEF\uFF1Acommand \u4E0D\u80FD\u4E3A\u7A7A\" };\n }\n\n let cwd = ctx.cwd;\n if (typeof args.cwd === \"string\" && args.cwd) {\n const expanded = expandHome(args.cwd);\n cwd = path.isAbsolute(expanded) ? expanded : path.resolve(ctx.cwd, expanded);\n }\n\n const rawTimeout =\n typeof args.timeout === \"number\" ? args.timeout : DEFAULT_TIMEOUT;\n const timeout = Math.min(Math.max(1000, rawTimeout), MAX_TIMEOUT);\n\n const result = await runCommand(command, cwd, timeout, ctx.signal);\n\n const parts: string[] = [];\n if (result.stdout.trim()) parts.push(result.stdout.trimEnd());\n if (result.stderr.trim()) {\n parts.push(`[stderr]\\n${result.stderr.trimEnd()}`);\n }\n if (result.aborted) {\n parts.push(\"[\u4E2D\u65AD] \u547D\u4EE4\u5DF2\u88AB\u7528\u6237\u4E2D\u65AD\uFF0C\u5176\u8FDB\u7A0B\u7EC4\u5DF2\u7EC8\u6B62\u3002\");\n }\n if (result.timedOut) {\n parts.push(`[\u8B66\u544A] \u547D\u4EE4\u5728 ${timeout}ms \u540E\u8D85\u65F6\u5E76\u88AB\u7EC8\u6B62\u3002`);\n }\n parts.push(`[\u9000\u51FA\u7801] ${result.code ?? \"\u672A\u77E5\"}`);\n\n const output = parts.join(\"\\n\\n\");\n return {\n ok: result.code === 0 && !result.timedOut && !result.aborted,\n content: output.slice(0, MAX_OUTPUT),\n summary: result.aborted\n ? \"\u5DF2\u4E2D\u65AD\"\n : result.timedOut\n ? \"\u8D85\u65F6\"\n : result.code === 0\n ? \"\u6267\u884C\u6210\u529F\"\n : `\u9000\u51FA\u7801 ${result.code}`,\n };\n },\n};\n", "import * as fs from \"fs\";\nimport * as path from \"path\";\nimport { expandHome } from \"../utils/paths\";\nimport type { ToolDefinition, ToolResult } from \"./types\";\n\nconst MAX_READ_LINES = 2000;\nconst MAX_FILE_BYTES = 2 * 1024 * 1024; // 2MB\nconst MAX_GLOB_RESULTS = 200;\nconst MAX_GREP_RESULTS = 200;\nconst MAX_GREP_FILE_BYTES = 1024 * 1024; // 1MB\n\nconst IGNORED_DIRS = new Set([\n \".git\",\n \"node_modules\",\n \"dist\",\n \"build\",\n \"out\",\n \".next\",\n \".nuxt\",\n \".cache\",\n \"coverage\",\n \".venv\",\n \"venv\",\n \"__pycache__\",\n \".idea\",\n \".vscode-test\",\n]);\n\nfunction resolvePath(input: string, cwd: string): string {\n const expanded = expandHome(input);\n return path.isAbsolute(expanded) ? expanded : path.resolve(cwd, expanded);\n}\n\nfunction asString(value: unknown, fallback = \"\"): string {\n return typeof value === \"string\" ? value : fallback;\n}\n\nfunction asNumber(value: unknown, fallback: number): number {\n return typeof value === \"number\" && Number.isFinite(value) ? value : fallback;\n}\n\nfunction isBinaryBuffer(buffer: Buffer): boolean {\n const sample = buffer.subarray(0, 8000);\n return sample.includes(0);\n}\n\n/** read_file */\nexport const readFileTool: ToolDefinition = {\n name: \"read_file\",\n description:\n \"\u8BFB\u53D6\u6587\u672C\u6587\u4EF6\u5185\u5BB9\uFF0C\u8FD4\u56DE\u5E26\u884C\u53F7\u7684\u6587\u672C\u3002\u652F\u6301\u901A\u8FC7 offset/limit \u8BFB\u53D6\u6307\u5B9A\u884C\u8303\u56F4\u3002\" +\n \"\u5728\u4FEE\u6539\u6587\u4EF6\u524D\u5E94\u5148\u8BFB\u53D6\u786E\u8BA4\u5185\u5BB9\u3002\",\n parameters: {\n type: \"object\",\n properties: {\n path: { type: \"string\", description: \"\u6587\u4EF6\u8DEF\u5F84\uFF08\u7EDD\u5BF9\u6216\u76F8\u5BF9\u5F53\u524D\u76EE\u5F55\uFF09\" },\n offset: {\n type: \"integer\",\n description: \"\u8D77\u59CB\u884C\u53F7\uFF08\u4ECE 1 \u5F00\u59CB\uFF0C\u53EF\u9009\uFF09\",\n },\n limit: {\n type: \"integer\",\n description: `\u6700\u591A\u8BFB\u53D6\u7684\u884C\u6570\uFF08\u9ED8\u8BA4 ${MAX_READ_LINES}\uFF09`,\n },\n },\n required: [\"path\"],\n },\n async execute(args, ctx): Promise<ToolResult> {\n const target = resolvePath(asString(args.path), ctx.cwd);\n if (!fs.existsSync(target)) {\n return { ok: false, content: `\u9519\u8BEF\uFF1A\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${target}` };\n }\n const stat = fs.statSync(target);\n if (stat.isDirectory()) {\n return { ok: false, content: `\u9519\u8BEF\uFF1A${target} \u662F\u4E00\u4E2A\u76EE\u5F55\uFF0C\u8BF7\u4F7F\u7528 list_dir` };\n }\n if (stat.size > MAX_FILE_BYTES) {\n return {\n ok: false,\n content: `\u9519\u8BEF\uFF1A\u6587\u4EF6\u8FC7\u5927\uFF08${(stat.size / 1024 / 1024).toFixed(1)}MB\uFF09\uFF0C\u8D85\u51FA 2MB \u9650\u5236`,\n };\n }\n\n const buffer = fs.readFileSync(target);\n if (isBinaryBuffer(buffer)) {\n return { ok: false, content: `\u9519\u8BEF\uFF1A${target} \u662F\u4E8C\u8FDB\u5236\u6587\u4EF6\uFF0C\u65E0\u6CD5\u4F5C\u4E3A\u6587\u672C\u8BFB\u53D6` };\n }\n\n const allLines = buffer.toString(\"utf8\").split(\"\\n\");\n const offset = Math.max(1, asNumber(args.offset, 1));\n const limit = Math.max(1, asNumber(args.limit, MAX_READ_LINES));\n const slice = allLines.slice(offset - 1, offset - 1 + limit);\n\n const body = slice\n .map((line, index) => {\n const lineNo = offset + index;\n return `${String(lineNo).padStart(6, \" \")}| ${line}`;\n })\n .join(\"\\n\");\n\n const truncated =\n offset - 1 + limit < allLines.length\n ? `\\n\u2026\uFF08\u6587\u4EF6\u5171 ${allLines.length} \u884C\uFF0C\u5DF2\u622A\u65AD\uFF09`\n : \"\";\n\n return {\n ok: true,\n content: body + truncated,\n summary: `\u8BFB\u53D6 ${slice.length} \u884C`,\n };\n },\n};\n\n/** write_file */\nexport const writeFileTool: ToolDefinition = {\n name: \"write_file\",\n description:\n \"\u5199\u5165\uFF08\u8986\u76D6\uFF09\u6587\u4EF6\u3002\u4F1A\u521B\u5EFA\u7F3A\u5931\u7684\u7236\u76EE\u5F55\u3002\u8BF7\u8C28\u614E\u4F7F\u7528\uFF0C\u4F18\u5148\u4F7F\u7528 edit_file \u505A\u5C40\u90E8\u4FEE\u6539\u3002\",\n requiresConfirmation: true,\n parameters: {\n type: \"object\",\n properties: {\n path: { type: \"string\", description: \"\u6587\u4EF6\u8DEF\u5F84\" },\n content: { type: \"string\", description: \"\u8981\u5199\u5165\u7684\u5B8C\u6574\u6587\u4EF6\u5185\u5BB9\" },\n },\n required: [\"path\", \"content\"],\n },\n async execute(args, ctx): Promise<ToolResult> {\n const target = resolvePath(asString(args.path), ctx.cwd);\n const content = asString(args.content);\n try {\n fs.mkdirSync(path.dirname(target), { recursive: true });\n fs.writeFileSync(target, content, \"utf8\");\n return {\n ok: true,\n content: `\u5DF2\u5199\u5165 ${target}\uFF08${content.length} \u5B57\u7B26\uFF09`,\n summary: \"\u5199\u5165\u6210\u529F\",\n };\n } catch (err) {\n return {\n ok: false,\n content: `\u5199\u5165\u5931\u8D25\uFF1A${err instanceof Error ? err.message : String(err)}`,\n };\n }\n },\n};\n\n/** edit_file */\nexport const editFileTool: ToolDefinition = {\n name: \"edit_file\",\n description:\n \"\u7CBE\u786E\u66FF\u6362\u6587\u4EF6\u4E2D\u7684\u6587\u672C\u3002\u5C06 search \u6307\u5B9A\u7684\u6587\u672C\u66FF\u6362\u4E3A replace\u3002\" +\n \"search \u5FC5\u987B\u4E0E\u6587\u4EF6\u5185\u5BB9\u5B8C\u5168\u4E00\u81F4\uFF08\u542B\u7F29\u8FDB\uFF09\uFF1B\u82E5 search \u5339\u914D\u5230\u591A\u5904\u5219\u9ED8\u8BA4\u62D2\u7EDD\u6267\u884C\uFF0C\" +\n \"\u9700\u63D0\u4F9B\u66F4\u7CBE\u786E\u7684 search \u6216\u8BBE\u7F6E replace_all \u4E3A true\u3002\",\n requiresConfirmation: true,\n parameters: {\n type: \"object\",\n properties: {\n path: { type: \"string\", description: \"\u6587\u4EF6\u8DEF\u5F84\" },\n search: { type: \"string\", description: \"\u8981\u88AB\u66FF\u6362\u7684\u539F\u6587\uFF08\u9700\u7CBE\u786E\u5339\u914D\uFF09\" },\n replace: { type: \"string\", description: \"\u66FF\u6362\u540E\u7684\u65B0\u6587\u672C\" },\n replace_all: {\n type: \"boolean\",\n description: \"\u662F\u5426\u66FF\u6362\u6240\u6709\u5339\u914D\u9879\uFF08\u9ED8\u8BA4 false\uFF09\",\n },\n },\n required: [\"path\", \"search\", \"replace\"],\n },\n async execute(args, ctx): Promise<ToolResult> {\n const target = resolvePath(asString(args.path), ctx.cwd);\n if (!fs.existsSync(target)) {\n return { ok: false, content: `\u9519\u8BEF\uFF1A\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${target}` };\n }\n const search = asString(args.search);\n const replace = asString(args.replace);\n const replaceAll = args.replace_all === true;\n\n if (!search) {\n return { ok: false, content: \"\u9519\u8BEF\uFF1Asearch \u4E0D\u80FD\u4E3A\u7A7A\" };\n }\n\n const original = fs.readFileSync(target, \"utf8\");\n if (!original.includes(search)) {\n return {\n ok: false,\n content: `\u9519\u8BEF\uFF1A\u5728 ${target} \u4E2D\u672A\u627E\u5230\u5339\u914D\u6587\u672C\u3002\u8BF7\u5148\u7528 read_file \u786E\u8BA4\u5185\u5BB9\uFF08\u6CE8\u610F\u7F29\u8FDB\u4E0E\u6362\u884C\u9700\u5B8C\u5168\u4E00\u81F4\uFF09\u3002`,\n };\n }\n\n const occurrences = original.split(search).length - 1;\n\n // \u591A\u5904\u5339\u914D\u65F6\u9ED8\u8BA4\u62D2\u7EDD\u6267\u884C\uFF1A\u9759\u9ED8\u66FF\u6362\u300C\u7B2C\u4E00\u5904\u300D\u6781\u6613\u6539\u9519\u4F4D\u7F6E\n //\uFF08\u4F8B\u5982 search \u53EA\u5199\u4E86 `\"` \u5C31\u4F1A\u7834\u574F\u914D\u7F6E\u6587\u4EF6\uFF09\uFF0C\u5FC5\u987B\u8BA9\u8C03\u7528\u65B9\u7ED9\u51FA\u66F4\u7CBE\u786E\u7684 search\n // \u6216\u663E\u5F0F\u58F0\u660E replace_all\u3002\n if (occurrences > 1 && !replaceAll) {\n return {\n ok: false,\n content:\n `\u9519\u8BEF\uFF1Asearch \u5728 ${target} \u4E2D\u51FA\u73B0 ${occurrences} \u5904\uFF0C\u4E3A\u907F\u514D\u8BEF\u6539\u672A\u6267\u884C\u3002\\n` +\n \"\u8BF7\u63D0\u4F9B\u66F4\u7CBE\u786E\u7684 search\uFF08\u5E26\u4E0A\u524D\u540E\u6587\uFF09\uFF0C\u6216\u663E\u5F0F\u8BBE\u7F6E replace_all: true \u4EE5\u66FF\u6362\u5168\u90E8\u5339\u914D\u3002\",\n };\n }\n\n // \u7528\u51FD\u6570\u5F62\u5F0F\u66FF\u6362\uFF1A\u5B57\u7B26\u4E32\u5F62\u5F0F\u7684 replace \u4F1A\u628A\u66FF\u6362\u6587\u672C\u91CC\u7684 `$&`\u3001`$'`\u3001`$1` \u7B49\n // \u5F53\u6210\u53CD\u5411\u5F15\u7528\u5C55\u5F00\uFF0C\u542B `$` \u7684\u5185\u5BB9\uFF08\u6A21\u677F\u5B57\u7B26\u4E32\u3001shell \u53D8\u91CF\u3001\u6B63\u5219\uFF09\u4F1A\u88AB\u6084\u6084\u6539\u5199\u3002\n const updated = replaceAll\n ? original.split(search).join(replace)\n : original.replace(search, () => replace);\n\n fs.writeFileSync(target, updated, \"utf8\");\n return {\n ok: true,\n content: `\u5DF2\u66F4\u65B0 ${target}\uFF08\u66FF\u6362 ${replaceAll ? occurrences : 1} \u5904\uFF09`,\n summary: `\u66FF\u6362 ${replaceAll ? occurrences : 1} \u5904`,\n };\n },\n};\n\n/** list_dir */\nexport const listDirTool: ToolDefinition = {\n name: \"list_dir\",\n description: \"\u5217\u51FA\u76EE\u5F55\u4E2D\u7684\u6587\u4EF6\u4E0E\u5B50\u76EE\u5F55\u3002\u7701\u7565 path \u65F6\u5217\u51FA\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u3002\",\n parameters: {\n type: \"object\",\n properties: {\n path: { type: \"string\", description: \"\u76EE\u5F55\u8DEF\u5F84\uFF08\u53EF\u9009\uFF09\" },\n },\n required: [],\n },\n async execute(args, ctx): Promise<ToolResult> {\n const target = args.path\n ? resolvePath(asString(args.path), ctx.cwd)\n : ctx.cwd;\n if (!fs.existsSync(target)) {\n return { ok: false, content: `\u9519\u8BEF\uFF1A\u76EE\u5F55\u4E0D\u5B58\u5728\uFF1A${target}` };\n }\n if (!fs.statSync(target).isDirectory()) {\n return { ok: false, content: `\u9519\u8BEF\uFF1A${target} \u4E0D\u662F\u76EE\u5F55` };\n }\n\n const entries = fs\n .readdirSync(target, { withFileTypes: true })\n .filter((entry) => !IGNORED_DIRS.has(entry.name))\n .sort((a, b) => {\n if (a.isDirectory() !== b.isDirectory()) return a.isDirectory() ? -1 : 1;\n return a.name.localeCompare(b.name);\n });\n\n const formatted = entries.map((entry) => {\n const suffix = entry.isDirectory() ? \"/\" : \"\";\n return `${entry.isDirectory() ? \"DIR \" : \"FILE\"} ${entry.name}${suffix}`;\n });\n\n return {\n ok: true,\n content: `${target}\\n${formatted.join(\"\\n\") || \"(\u7A7A\u76EE\u5F55)\"}`,\n summary: `${entries.length} \u9879`,\n };\n },\n};\n\n/** glob */\nexport const globTool: ToolDefinition = {\n name: \"glob\",\n description:\n \"\u6309\u901A\u914D\u7B26\u67E5\u627E\u6587\u4EF6\uFF0C\u652F\u6301 **\u3001*\u3001? \u8BED\u6CD5\u3002\u4F8B\u5982 'src/**/*.ts'\u3002\u8FD4\u56DE\u5339\u914D\u7684\u6587\u4EF6\u8DEF\u5F84\u3002\",\n parameters: {\n type: \"object\",\n properties: {\n pattern: { type: \"string\", description: \"glob \u6A21\u5F0F\uFF0C\u5982 '**/*.ts'\" },\n path: { type: \"string\", description: \"\u641C\u7D22\u8D77\u59CB\u76EE\u5F55\uFF08\u53EF\u9009\uFF0C\u9ED8\u8BA4\u5F53\u524D\u76EE\u5F55\uFF09\" },\n },\n required: [\"pattern\"],\n },\n async execute(args, ctx): Promise<ToolResult> {\n const pattern = asString(args.pattern);\n if (!pattern) return { ok: false, content: \"\u9519\u8BEF\uFF1Apattern \u4E0D\u80FD\u4E3A\u7A7A\" };\n const root = args.path ? resolvePath(asString(args.path), ctx.cwd) : ctx.cwd;\n const matcher = globToRegExp(pattern);\n const matches: string[] = [];\n\n walk(root, (filePath) => {\n if (matches.length >= MAX_GLOB_RESULTS) return;\n const relative = path.relative(root, filePath).split(path.sep).join(\"/\");\n if (matcher.test(relative)) matches.push(relative);\n });\n\n if (matches.length === 0) {\n return { ok: true, content: \"\u672A\u627E\u5230\u5339\u914D\u7684\u6587\u4EF6\u3002\" };\n }\n const truncated =\n matches.length >= MAX_GLOB_RESULTS\n ? `\\n\u2026\uFF08\u5DF2\u8FBE ${MAX_GLOB_RESULTS} \u6761\u4E0A\u9650\uFF09`\n : \"\";\n return {\n ok: true,\n content: matches.join(\"\\n\") + truncated,\n summary: `${matches.length} \u4E2A\u6587\u4EF6`,\n };\n },\n};\n\n/** grep */\nexport const grepTool: ToolDefinition = {\n name: \"grep\",\n description:\n \"\u5728\u6587\u4EF6\u4E2D\u6309\u6B63\u5219\u8868\u8FBE\u5F0F\u641C\u7D22\u6587\u672C\u5185\u5BB9\u3002\u8FD4\u56DE \u6587\u4EF6:\u884C\u53F7:\u5185\u5BB9\u3002\u53EF\u901A\u8FC7 include \u9650\u5B9A\u6587\u4EF6\u7C7B\u578B\uFF08\u5982 '*.ts'\uFF09\u3002\",\n parameters: {\n type: \"object\",\n properties: {\n pattern: { type: \"string\", description: \"\u6B63\u5219\u8868\u8FBE\u5F0F\" },\n path: { type: \"string\", description: \"\u641C\u7D22\u76EE\u5F55\uFF08\u53EF\u9009\uFF0C\u9ED8\u8BA4\u5F53\u524D\u76EE\u5F55\uFF09\" },\n include: {\n type: \"string\",\n description: \"\u6587\u4EF6\u540D\u901A\u914D\u7B26\u8FC7\u6EE4\uFF0C\u5982 '*.ts'\uFF08\u53EF\u9009\uFF09\",\n },\n },\n required: [\"pattern\"],\n },\n async execute(args, ctx): Promise<ToolResult> {\n const patternText = asString(args.pattern);\n if (!patternText) return { ok: false, content: \"\u9519\u8BEF\uFF1Apattern \u4E0D\u80FD\u4E3A\u7A7A\" };\n\n let regex: RegExp;\n try {\n regex = new RegExp(patternText);\n } catch (err) {\n return {\n ok: false,\n content: `\u9519\u8BEF\uFF1A\u65E0\u6548\u7684\u6B63\u5219\u8868\u8FBE\u5F0F\uFF1A${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n const root = args.path ? resolvePath(asString(args.path), ctx.cwd) : ctx.cwd;\n const include = args.include ? globToRegExp(asString(args.include)) : null;\n const results: string[] = [];\n\n walk(root, (filePath) => {\n if (results.length >= MAX_GREP_RESULTS) return;\n const relative = path.relative(root, filePath).split(path.sep).join(\"/\");\n if (include && !include.test(relative) && !include.test(path.basename(filePath))) {\n return;\n }\n let stat: fs.Stats;\n try {\n stat = fs.statSync(filePath);\n } catch {\n return;\n }\n if (stat.size > MAX_GREP_FILE_BYTES || stat.size === 0) return;\n\n let buffer: Buffer;\n try {\n buffer = fs.readFileSync(filePath);\n } catch {\n return;\n }\n if (isBinaryBuffer(buffer)) return;\n\n const lines = buffer.toString(\"utf8\").split(\"\\n\");\n for (let i = 0; i < lines.length; i++) {\n if (results.length >= MAX_GREP_RESULTS) return;\n if (regex.test(lines[i])) {\n results.push(`${relative}:${i + 1}: ${lines[i].trim().slice(0, 300)}`);\n }\n }\n });\n\n if (results.length === 0) {\n return { ok: true, content: \"\u672A\u627E\u5230\u5339\u914D\u5185\u5BB9\u3002\" };\n }\n const truncated =\n results.length >= MAX_GREP_RESULTS\n ? `\\n\u2026\uFF08\u5DF2\u8FBE ${MAX_GREP_RESULTS} \u6761\u4E0A\u9650\uFF09`\n : \"\";\n return {\n ok: true,\n content: results.join(\"\\n\") + truncated,\n summary: `${results.length} \u6761\u5339\u914D`,\n };\n },\n};\n\nfunction walk(root: string, onFile: (filePath: string) => void): void {\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(root, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n if (IGNORED_DIRS.has(entry.name)) continue;\n const full = path.join(root, entry.name);\n if (entry.isDirectory()) {\n walk(full, onFile);\n } else if (entry.isFile() || entry.isSymbolicLink()) {\n onFile(full);\n }\n }\n}\n\n/** \u5C06 glob \u6A21\u5F0F\u7F16\u8BD1\u4E3A\u6B63\u5219\u8868\u8FBE\u5F0F */\nexport function globToRegExp(pattern: string): RegExp {\n let regex = \"\";\n const normalized = pattern.split(path.sep).join(\"/\");\n for (let i = 0; i < normalized.length; i++) {\n const ch = normalized[i];\n if (ch === \"*\") {\n if (normalized[i + 1] === \"*\") {\n // ** \u8DE8\u76EE\u5F55\u5339\u914D\n i++;\n if (normalized[i + 1] === \"/\") {\n i++;\n regex += \"(?:.*/)?\";\n } else {\n regex += \".*\";\n }\n } else {\n regex += \"[^/]*\";\n }\n } else if (ch === \"?\") {\n regex += \"[^/]\";\n } else if (ch === \"{\") {\n const close = normalized.indexOf(\"}\", i);\n if (close !== -1) {\n const options = normalized\n .slice(i + 1, close)\n .split(\",\")\n .map(escapeRegExp)\n .join(\"|\");\n regex += `(?:${options})`;\n i = close;\n } else {\n regex += \"\\\\{\";\n }\n } else {\n regex += escapeRegExp(ch);\n }\n }\n return new RegExp(`^${regex}$`);\n}\n\nfunction escapeRegExp(text: string): string {\n return text.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n", "import * as fs from \"fs\";\nimport * as path from \"path\";\n\n/**\n * \u9879\u76EE\u7EA7\u76EE\u5F55\uFF08\u5BF9\u5E94 CodeBuddy \u7684 `.codebuddy`\uFF09\u3002\n *\n * <cwd>/.xuanzhu/\n * \u251C\u2500\u2500 memory/ \u9879\u76EE\u7EA7\u8BB0\u5FC6\n * \u2502 \u251C\u2500\u2500 MEMORY.md \u957F\u671F\u8BB0\u5FC6\uFF08\u6301\u7EED\u7EF4\u62A4\uFF09\n * \u2502 \u2514\u2500\u2500 YYYY-MM-DD.md \u6BCF\u65E5\u8BB0\u5F55\uFF08\u6309\u5929\u5206\u5B58\uFF0C\u8FFD\u52A0\uFF09\n * \u2514\u2500\u2500 rules.md \u9879\u76EE\u89C4\u5219\uFF08\u5185\u5BB9\u6CE8\u5165\u7CFB\u7EDF\u63D0\u793A\u8BCD\uFF09\n *\n * \u4F4D\u7F6E\u7EA6\u5B9A\uFF08\u91CD\u8981\uFF09\uFF1A`.xuanzhu` **\u59CB\u7EC8**\u4F4D\u4E8E\u7528\u6237\u5F53\u524D\u6307\u5B9A\u7684\u9879\u76EE\u8DEF\u5F84\uFF08cwd\uFF09\u4E4B\u4E0B\uFF0C\n * **\u4E0D\u505A\u4EFB\u4F55\u5411\u4E0A\u67E5\u627E**\u3002\u5373\u5728 /a/b/c \u5DE5\u4F5C\u65F6\u53EA\u4F7F\u7528 /a/b/c/.xuanzhu \u2014\u2014\n * \u5373\u4F7F /a \u6216 /a/b \u4E0B\u5DF2\u5B58\u5728 .xuanzhu \u4E5F\u4E0D\u590D\u7528\uFF1B\u8BB0\u5FC6\u4E0E\u89C4\u5219\u4E25\u683C\u5F52\u5C5E\u5F53\u524D\u9879\u76EE\u8DEF\u5F84\u3002\n * \u6CA1\u6709\u5219\u81EA\u52A8\u521B\u5EFA\uFF08\u89C1 ensureProjectDir\uFF09\u3002\n *\n * \u4E0E\u5168\u5C40\u76EE\u5F55\u7684\u5206\u5DE5\uFF1A\n * - `~/.xzh`\uFF1A**\u5168\u5C40\u901A\u7528**\u5185\u5BB9\uFF0C\u53EA\u6709\u4E00\u4EFD \u2014\u2014 config.json\uFF08\u6A21\u578B\u914D\u7F6E\uFF09+ skills/\u3002\n * - `<\u9879\u76EE>/.xuanzhu`\uFF1A**\u968F\u9879\u76EE\u8D70**\u7684\u5185\u5BB9 \u2014\u2014 \u6309\u5929\u5206\u5B58\u7684\u8BB0\u5F55 + \u9879\u76EE\u957F\u671F\u8BB0\u5FC6 + \u89C4\u5219\u3002\n * \u4E24\u8005\u76EE\u5F55\u540D\u4E0D\u540C\u3001\u804C\u8D23\u5206\u79BB\uFF0C\u6280\u80FD\u4E0E CLI \u4E00\u5F8B\u4E0D\u653E\u8FDB\u9879\u76EE\u76EE\u5F55\u3002\n */\n\nexport const PROJECT_DIR_NAME = \".xuanzhu\";\nconst LONG_TERM_FILE = \"MEMORY.md\";\n\nexport interface ProjectPaths {\n /** \u9879\u76EE\u6839\u76EE\u5F55\uFF08\u5373\u4F20\u5165\u7684 cwd\uFF0C.xuanzhu \u5C31\u5EFA\u5728\u8FD9\u4E00\u5C42\uFF09 */\n root: string;\n /** <root>/.xuanzhu */\n dir: string;\n /** <root>/.xuanzhu/memory */\n memoryDir: string;\n /** <root>/.xuanzhu/memory/MEMORY.md */\n longTermFile: string;\n /** <root>/.xuanzhu/rules.md */\n rulesFile: string;\n}\n\nconst RULES_TEMPLATE = `# \u9879\u76EE\u89C4\u5219\n\n> \u672C\u6587\u4EF6\u5185\u5BB9\u4F1A\u4F5C\u4E3A\u300C\u9879\u76EE\u7EA7\u6307\u4EE4\u300D\u8FFD\u52A0\u5230\u7384\u732A\u7684\u7CFB\u7EDF\u63D0\u793A\u8BCD\u4E2D\uFF0C\u7528\u4E8E\u7EA6\u5B9A\u672C\u9879\u76EE\u7684\n> \u7F16\u7801\u89C4\u8303\u3001\u76EE\u5F55\u7ED3\u6784\u3001\u6784\u5EFA\u4E0E\u6D4B\u8BD5\u547D\u4EE4\u7B49\u3002\u7559\u7A7A\u6216\u5220\u9664\u672C\u6587\u4EF6\u5373\u8868\u793A\u4E0D\u4F7F\u7528\u9879\u76EE\u89C4\u5219\u3002\n\n## \u7EA6\u5B9A\uFF08\u8BF7\u6309\u9879\u76EE\u5B9E\u9645\u60C5\u51B5\u4FEE\u6539\uFF09\n\n- \u8BED\u8A00 / \u6846\u67B6\uFF1A\n- \u5305\u7BA1\u7406\u5668\uFF1A\n- \u5B89\u88C5\u4F9D\u8D56\uFF1A\n- \u8FD0\u884C\u6D4B\u8BD5\uFF1A\n- \u4EE3\u7801\u98CE\u683C\uFF1A\n`;\n\nfunction buildPaths(root: string): ProjectPaths {\n const dir = path.join(root, PROJECT_DIR_NAME);\n const memoryDir = path.join(dir, \"memory\");\n return {\n root,\n dir,\n memoryDir,\n longTermFile: path.join(memoryDir, LONG_TERM_FILE),\n rulesFile: path.join(dir, \"rules.md\"),\n };\n}\n\n/**\n * \u9879\u76EE\u76EE\u5F55\u8DEF\u5F84\uFF1A**\u56FA\u5B9A**\u4E3A cwd \u4E0B\u7684 `.xuanzhu`\uFF0C\u4E0D\u505A\u4EFB\u4F55\u5411\u4E0A\u67E5\u627E\u3002\n * \u76EE\u5F55\u672C\u8EAB\u53EF\u80FD\u5C1A\u672A\u521B\u5EFA\uFF0C\u7531 ensureProjectDir() \u8D1F\u8D23\u5EFA\u7ACB\u3002\n */\nexport function resolveProjectPaths(cwd: string): ProjectPaths {\n return buildPaths(path.resolve(cwd));\n}\n\n/** \u786E\u4FDD\u9879\u76EE\u76EE\u5F55\u5B58\u5728\uFF08\u8BB0\u5FC6\u76EE\u5F55 + \u89C4\u5219\u6A21\u677F\uFF09\uFF1B\u8FD4\u56DE\u662F\u5426\u672C\u6B21\u65B0\u5EFA */\nexport function ensureProjectDir(cwd: string): {\n paths: ProjectPaths;\n created: boolean;\n} {\n const paths = resolveProjectPaths(cwd);\n if (fs.existsSync(paths.dir)) {\n fs.mkdirSync(paths.memoryDir, { recursive: true });\n return { paths, created: false };\n }\n try {\n fs.mkdirSync(paths.memoryDir, { recursive: true });\n fs.writeFileSync(paths.rulesFile, RULES_TEMPLATE, \"utf8\");\n return { paths, created: true };\n } catch {\n return { paths, created: false };\n }\n}\n\n/** \u8BFB\u53D6\u9879\u76EE\u89C4\u5219\uFF08\u4E0D\u5B58\u5728\u6216\u4E3A\u7A7A\u65F6\u8FD4\u56DE null\uFF09 */\nexport function loadProjectRules(cwd: string): string | null {\n const { rulesFile } = resolveProjectPaths(cwd);\n try {\n if (!fs.existsSync(rulesFile)) return null;\n const content = fs.readFileSync(rulesFile, \"utf8\").trim();\n return content || null;\n } catch {\n return null;\n }\n}\n\n/** \u5F53\u65E5\u65E5\u5FD7\u6587\u4EF6\u8DEF\u5F84\uFF1A<\u9879\u76EE>/.xuanzhu/memory/YYYY-MM-DD.md */\nexport function dailyMemoryFile(cwd: string, date = new Date()): string {\n const stamp = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, \"0\")}-${String(date.getDate()).padStart(2, \"0\")}`;\n return path.join(resolveProjectPaths(cwd).memoryDir, `${stamp}.md`);\n}\n\nexport interface ProjectMemory {\n /** \u957F\u671F\u8BB0\u5FC6\uFF08MEMORY.md\uFF09\u5185\u5BB9 */\n longTerm: string;\n /** \u6700\u8FD1\u4E00\u6B21\u6BCF\u65E5\u65E5\u5FD7\u7684\u6587\u4EF6\u540D\u4E0E\u5185\u5BB9 */\n recentDailyName: string;\n recentDaily: string;\n}\n\n/** \u8BFB\u53D6\u9879\u76EE\u8BB0\u5FC6\uFF1A\u957F\u671F\u8BB0\u5FC6 + \u6700\u8FD1\u7684\u6BCF\u65E5\u65E5\u5FD7 */\nexport function readProjectMemory(cwd: string): ProjectMemory {\n const paths = resolveProjectPaths(cwd);\n let longTerm = \"\";\n let recentDaily = \"\";\n let recentDailyName = \"\";\n\n try {\n if (fs.existsSync(paths.longTermFile)) {\n longTerm = fs.readFileSync(paths.longTermFile, \"utf8\").trim();\n }\n } catch {\n // \u5FFD\u7565\n }\n\n try {\n if (fs.existsSync(paths.memoryDir)) {\n const daily = fs\n .readdirSync(paths.memoryDir)\n .filter((name) => /^\\d{4}-\\d{2}-\\d{2}\\.md$/.test(name))\n .sort()\n .reverse();\n if (daily.length > 0) {\n recentDailyName = daily[0];\n recentDaily = fs\n .readFileSync(path.join(paths.memoryDir, daily[0]), \"utf8\")\n .trim();\n }\n }\n } catch {\n // \u5FFD\u7565\n }\n\n return { longTerm, recentDailyName, recentDaily };\n}\n\nexport type MemoryScope = \"long\" | \"daily\";\n\n/** \u8FFD\u52A0\u5199\u5165\u9879\u76EE\u8BB0\u5FC6\uFF0C\u8FD4\u56DE\u5199\u5165\u7684\u6587\u4EF6\u8DEF\u5F84 */\nexport function appendMemory(\n cwd: string,\n content: string,\n scope: MemoryScope,\n): string {\n const paths = resolveProjectPaths(cwd);\n fs.mkdirSync(paths.memoryDir, { recursive: true });\n\n const target =\n scope === \"long\" ? paths.longTermFile : dailyMemoryFile(cwd);\n const stamp = new Date().toISOString().replace(\"T\", \" \").slice(0, 16);\n\n const block = `\\n\\n## ${stamp}\\n\\n${content.trim()}\\n`;\n\n if (!fs.existsSync(target)) {\n const title = scope === \"long\" ? \"# \u9879\u76EE\u957F\u671F\u8BB0\u5FC6\\n\" : \"# \u6BCF\u65E5\u8BB0\u5F55\\n\";\n fs.writeFileSync(target, `${title}${block}`, \"utf8\");\n } else {\n fs.appendFileSync(target, block, \"utf8\");\n }\n\n return target;\n}\n", "import {\n appendMemory,\n readProjectMemory,\n resolveProjectPaths,\n} from \"../workspace\";\nimport type { ToolDefinition, ToolResult } from \"./types\";\n\nconst MAX_DISPLAY = 12_000;\n\n/** memory_read \u2014\u2014 \u8BFB\u53D6\u9879\u76EE\u8BB0\u5FC6 */\nexport const memoryReadTool: ToolDefinition = {\n name: \"memory_read\",\n description:\n \"\u8BFB\u53D6\u5F53\u524D\u9879\u76EE\u7684\u8BB0\u5FC6\uFF08\u5B58\u653E\u5728 <\u9879\u76EE>/.xuanzhu/memory/\uFF09\uFF1A\u5305\u542B\u957F\u671F\u8BB0\u5FC6 MEMORY.md \u4E0E\u6700\u8FD1\u4E00\u4EFD\u6BCF\u65E5\u65E5\u5FD7\u3002\" +\n \"\u5728\u5F00\u59CB\u5904\u7406\u9700\u8981\u9879\u76EE\u80CC\u666F\u7684\u4EFB\u52A1\u524D\u8C03\u7528\u5B83\uFF0C\u53EF\u4EE5\u4E86\u89E3\u6B64\u524D\u79EF\u7D2F\u7684\u7EA6\u5B9A\u4E0E\u7ED3\u8BBA\u3002\",\n parameters: {\n type: \"object\",\n properties: {},\n required: [],\n },\n async execute(_args, ctx): Promise<ToolResult> {\n const memory = readProjectMemory(ctx.cwd);\n const paths = resolveProjectPaths(ctx.cwd);\n\n if (!memory.longTerm && !memory.recentDaily) {\n return {\n ok: true,\n content: `\u9879\u76EE\u8BB0\u5FC6\u4E3A\u7A7A\uFF08\u76EE\u5F55\uFF1A${paths.memoryDir}\uFF09\u3002`,\n summary: \"\u6682\u65E0\u8BB0\u5FC6\",\n };\n }\n\n const parts: string[] = [];\n if (memory.longTerm) {\n parts.push(`## \u957F\u671F\u8BB0\u5FC6\uFF08MEMORY.md\uFF09\\n\\n${memory.longTerm}`);\n }\n if (memory.recentDaily) {\n parts.push(`## \u6700\u8FD1\u65E5\u5FD7\uFF08${memory.recentDailyName}\uFF09\\n\\n${memory.recentDaily}`);\n }\n\n const content = parts.join(\"\\n\\n---\\n\\n\");\n return {\n ok: true,\n content:\n content.length > MAX_DISPLAY\n ? `${content.slice(0, MAX_DISPLAY)}\\n\\n\u2026\uFF08\u5185\u5BB9\u8FC7\u957F\uFF0C\u5DF2\u622A\u65AD\uFF09`\n : content,\n summary: \"\u5DF2\u8BFB\u53D6\u9879\u76EE\u8BB0\u5FC6\",\n };\n },\n};\n\n/** memory_write \u2014\u2014 \u5199\u5165\u9879\u76EE\u8BB0\u5FC6 */\nexport const memoryWriteTool: ToolDefinition = {\n name: \"memory_write\",\n description:\n \"\u628A\u503C\u5F97\u8DE8\u4F1A\u8BDD\u4FDD\u7559\u7684\u4FE1\u606F\u5199\u5165\u9879\u76EE\u8BB0\u5FC6\uFF08<\u9879\u76EE>/.xuanzhu/memory/\uFF09\u3002\" +\n \"\u5728\u5B8C\u6210\u5B9E\u8D28\u5DE5\u4F5C\uFF08\u5B9E\u73B0\u529F\u80FD\u3001\u4FEE\u590D\u7F3A\u9677\u3001\u786E\u5B9A\u6280\u672F\u65B9\u6848\u3001\u7EA6\u5B9A\u9879\u76EE\u89C4\u8303\uFF09\u540E\u8C03\u7528\uFF0C\u4EE5\u4FBF\u540E\u7EED\u4F1A\u8BDD\u590D\u7528\u3002\" +\n \"scope=daily \u8FFD\u52A0\u5230\u5F53\u65E5\u65E5\u5FD7\uFF08\u9ED8\u8BA4\uFF0C\u9002\u5408\u8FC7\u7A0B\u8BB0\u5F55\uFF09\uFF1Bscope=long \u8FFD\u52A0\u5230\u957F\u671F\u8BB0\u5FC6 MEMORY.md\uFF08\u9002\u5408\u7A33\u5B9A\u7684\u7ED3\u8BBA\u4E0E\u7EA6\u5B9A\uFF09\u3002\" +\n \"\u8BF7\u5199\u7B80\u6D01\u7684\u4E8B\u5B9E\u6027\u5185\u5BB9\uFF0C\u4E0D\u8981\u8BB0\u5F55\u77AC\u65F6\u4FE1\u606F\uFF08\u4E34\u65F6\u8DEF\u5F84\u3001\u5DE5\u5177\u62A5\u9519\u7B49\uFF09\u3002\",\n parameters: {\n type: \"object\",\n properties: {\n content: {\n type: \"string\",\n description: \"\u8981\u8BB0\u5F55\u7684\u5185\u5BB9\uFF08Markdown\uFF0C\u5EFA\u8BAE\u7B80\u6D01\u3001\u5206\u70B9\uFF09\",\n },\n scope: {\n type: \"string\",\n enum: [\"daily\", \"long\"],\n description: \"daily=\u5F53\u65E5\u65E5\u5FD7\uFF08\u9ED8\u8BA4\uFF09\uFF1Blong=\u957F\u671F\u8BB0\u5FC6 MEMORY.md\",\n },\n },\n required: [\"content\"],\n },\n async execute(args, ctx): Promise<ToolResult> {\n const content = typeof args.content === \"string\" ? args.content.trim() : \"\";\n if (!content) {\n return { ok: false, content: \"\u9519\u8BEF\uFF1Acontent \u4E0D\u80FD\u4E3A\u7A7A\u3002\" };\n }\n const scope = args.scope === \"long\" ? \"long\" : \"daily\";\n\n try {\n const file = appendMemory(ctx.cwd, content, scope);\n const label = scope === \"long\" ? \"\u957F\u671F\u8BB0\u5FC6\" : \"\u5F53\u65E5\u65E5\u5FD7\";\n return {\n ok: true,\n content: `\u5DF2\u5199\u5165${label}\uFF1A${file}\\n\\n\uFF08\u8BB0\u5FC6\u76EE\u5F55\uFF1A${resolveProjectPaths(ctx.cwd).memoryDir}\uFF09`,\n summary: `\u5DF2\u5199\u5165${label}`,\n };\n } catch (err) {\n return {\n ok: false,\n content: `\u5199\u5165\u8BB0\u5FC6\u5931\u8D25\uFF1A${err instanceof Error ? err.message : String(err)}\\n\uFF08\u76EE\u6807\u76EE\u5F55\uFF1A${resolveProjectPaths(ctx.cwd).memoryDir}\uFF09`,\n };\n }\n },\n};\n", "import * as fs from \"fs\";\nimport * as path from \"path\";\nimport { getBuiltinSkillsDir, getUserSkillsDir } from \"../utils/paths\";\n\n/**\n * \u7384\u732A\u6280\u80FD\u7CFB\u7EDF\u3002\n *\n * \u6280\u80FD = \u4E00\u4E2A\u5305\u542B `SKILL.md` \u7684\u76EE\u5F55\uFF0C\u7528\u4E8E\u6307\u5BFC\u6A21\u578B\u4F7F\u7528\u67D0\u4E2A\u5916\u90E8 CLI \u5DE5\u5177\n * \uFF08\u5982 playwright-cli\u3001officecli\u3001gh \u7B49\uFF09\u3002\u6A21\u578B\u901A\u8FC7 `list_skills` \u53D1\u73B0\u6280\u80FD\u3001\n * \u7528 `load_skill` \u52A0\u8F7D\u5B8C\u6574\u6307\u5357\uFF0C\u518D\u501F\u52A9 `bash` \u5DE5\u5177\u6267\u884C\u5BF9\u5E94\u547D\u4EE4\u3002\n *\n * \u6280\u80FD\u6765\u6E90\u5206\u4E24\u7EA7\uFF08\u5168\u5C40\u901A\u7528\uFF09\uFF0C\u4F18\u5148\u7EA7\u4ECE\u9AD8\u5230\u4F4E\uFF0C\u540C\u540D\u65F6\u9AD8\u4F18\u5148\u7EA7\u8986\u76D6\uFF1A\n * 1. \u7528\u6237\uFF1A~/.xzh/skills\n * 2. \u5185\u7F6E\uFF1A<\u5B89\u88C5\u76EE\u5F55>/skills\uFF08\u6253\u5305\u540E\u4E3A dist/skills\uFF09\n */\n\nexport type SkillSource = \"builtin\" | \"user\";\n\nexport interface SkillInfo {\n name: string;\n description: string;\n /** \u6280\u80FD\u76EE\u5F55 */\n dir: string;\n /** SKILL.md \u7EDD\u5BF9\u8DEF\u5F84 */\n file: string;\n source: SkillSource;\n}\n\nconst SKILL_FILENAME = \"SKILL.md\";\nconst MAX_SKILL_CHARS = 80_000;\n\ninterface Frontmatter {\n name?: string;\n description?: string;\n}\n\nfunction stripQuotes(value: string): string {\n return value.replace(/^[\"']|[\"']$/g, \"\").trim();\n}\n\n/** \u89E3\u6790 SKILL.md \u7684 YAML frontmatter\uFF08\u4EC5\u63D0\u53D6 name \u4E0E description\uFF09 */\nexport function parseFrontmatter(content: string): {\n meta: Frontmatter;\n body: string;\n} {\n const match = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n?/.exec(content);\n if (!match) return { meta: {}, body: content };\n\n const raw = match[1];\n const body = content.slice(match[0].length);\n\n const nameLine = /^name:\\s*(.+)$/m.exec(raw)?.[1];\n const name = nameLine ? stripQuotes(nameLine) : undefined;\n\n return { meta: { name, description: extractDescription(raw) }, body };\n}\n\n/** \u652F\u6301\u5355\u884C\u4E0E YAML \u5757\uFF08> / |\uFF09\u4E24\u79CD description \u5199\u6CD5 */\nfunction extractDescription(raw: string): string {\n const inline = /^description:\\s*(.*)$/m.exec(raw)?.[1]?.trim();\n if (inline && inline !== \">\" && inline !== \"|\" && inline !== \">-\" && inline !== \"|-\") {\n return stripQuotes(inline);\n }\n const block = /^description:\\s*[>|]-?\\s*\\n((?:[ \\t]+\\S.*\\n?)+)/m.exec(raw)?.[1];\n return block ? block.replace(/\\s+/g, \" \").trim() : \"\";\n}\n\n/** \u67E5\u627E\u6280\u80FD\u5B9A\u4E49\u6587\u4EF6\uFF0C\u517C\u5BB9 SKILL.md / skill.md \u4E24\u79CD\u547D\u540D */\nfunction findSkillFile(dir: string): string | null {\n const primary = path.join(dir, SKILL_FILENAME);\n if (fs.existsSync(primary)) return primary;\n try {\n const match = fs\n .readdirSync(dir)\n .find((name) => name.toLowerCase() === SKILL_FILENAME.toLowerCase());\n return match ? path.join(dir, match) : null;\n } catch {\n return null;\n }\n}\n\nfunction scanDir(\n root: string,\n source: SkillSource,\n found: Map<string, SkillInfo>,\n): void {\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(root, { withFileTypes: true });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const dir = path.join(root, entry.name);\n const file = findSkillFile(dir);\n if (!file) continue;\n\n let content: string;\n try {\n content = fs.readFileSync(file, \"utf8\");\n } catch {\n continue;\n }\n\n const { meta } = parseFrontmatter(content);\n const name = (meta.name || entry.name).trim();\n if (!name) continue;\n\n // \u540E\u626B\u63CF\u7684\u6765\u6E90\u8986\u76D6\u540C\u540D\u6280\u80FD\uFF08\u8C03\u7528\u987A\u5E8F\u5373\u4F18\u5148\u7EA7\uFF09\n found.set(name, {\n name,\n description: meta.description ?? \"\",\n dir,\n file,\n source,\n });\n }\n}\n\n/** \u53D1\u73B0\u5168\u90E8\u53EF\u7528\u6280\u80FD\uFF08\u540C\u540D\u65F6\u7528\u6237\u6280\u80FD\u8986\u76D6\u5185\u7F6E\u6280\u80FD\uFF09 */\nexport function discoverSkills(): SkillInfo[] {\n const found = new Map<string, SkillInfo>();\n scanDir(getBuiltinSkillsDir(), \"builtin\", found);\n scanDir(getUserSkillsDir(), \"user\", found);\n return [...found.values()].sort((a, b) => a.name.localeCompare(b.name));\n}\n\n/** \u6309\u540D\u79F0\u67E5\u627E\u6280\u80FD\uFF08\u5927\u5C0F\u5199\u4E0D\u654F\u611F\uFF09 */\nexport function findSkill(name: string): SkillInfo | undefined {\n const normalized = name.trim().toLowerCase();\n if (!normalized) return undefined;\n return discoverSkills().find(\n (skill) => skill.name.toLowerCase() === normalized,\n );\n}\n\n/** \u8BFB\u53D6\u6280\u80FD\u7684\u5B8C\u6574\u6307\u5357\u5185\u5BB9 */\nexport function loadSkillContent(skill: SkillInfo): string {\n const content = fs.readFileSync(skill.file, \"utf8\");\n if (content.length <= MAX_SKILL_CHARS) return content;\n return `${content.slice(0, MAX_SKILL_CHARS)}\\n\\n\u2026\uFF08\u6280\u80FD\u5185\u5BB9\u8FC7\u957F\uFF0C\u5DF2\u622A\u65AD\uFF09`;\n}\n", "/**\n * \u6280\u80FD\u7684\u5916\u90E8\u4F9D\u8D56\u58F0\u660E\u3002\n *\n * \u6280\u80FD\u662F\u4E00\u4EFD CLI \u4F7F\u7528\u6307\u5357\uFF1B\u8FD9\u4E9B CLI \u7531\u7384\u732A\u8D1F\u8D23\u68C0\u6D4B\u4E0E\u81EA\u52A8\u5B89\u88C5\uFF0C\n * \u4F7F\u7528\u6237\u5B89\u88C5\u7384\u732A\u540E\u65E0\u9700\u518D\u5355\u72EC\u5B89\u88C5\u5BF9\u5E94\u5DE5\u5177\u3002\n */\n\nexport type Platform = \"linux\" | \"darwin\" | \"win32\";\n\nexport interface SkillRequirement {\n /** \u4EBA\u7C7B\u53EF\u8BFB\u540D\u79F0 */\n name: string;\n /** \u68C0\u6D4B\u547D\u4EE4\uFF1A\u9000\u51FA\u7801\u4E3A 0 \u89C6\u4E3A\u5DF2\u5B89\u88C5 */\n check: string;\n /** \u5404\u5E73\u53F0\u7684\u5B89\u88C5\u547D\u4EE4 */\n install: Partial<Record<Platform, string>>;\n /** \u5B89\u88C5\u6210\u529F\u540E\u7684\u8865\u5145\u547D\u4EE4\uFF08\u4F8B\u5982\u4E0B\u8F7D\u6D4F\u89C8\u5668\u5185\u6838\uFF09 */\n postInstall?: Partial<Record<Platform, string>>;\n}\n\nexport function currentPlatform(): Platform {\n if (process.platform === \"darwin\") return \"darwin\";\n if (process.platform === \"win32\") return \"win32\";\n return \"linux\";\n}\n\nconst NPM_PLAYWRIGHT_CLI = \"npm install -g @playwright/cli@latest\";\nconst PLAYWRIGHT_BROWSER = \"npx --yes playwright@latest install chromium\";\n\nconst OFFICECLI_INSTALL = {\n linux: \"curl -fsSL https://d.officecli.ai/install.sh | bash\",\n darwin: \"curl -fsSL https://d.officecli.ai/install.sh | bash\",\n win32:\n 'powershell -NoProfile -Command \"irm https://d.officecli.ai/install.ps1 | iex\"',\n};\n\n/** \u5185\u7F6E\u6280\u80FD\u7684\u4F9D\u8D56\u6E05\u5355\uFF08\u6280\u80FD\u540D \u2192 \u4F9D\u8D56\u5217\u8868\uFF09 */\nexport const SKILL_REQUIREMENTS: Record<string, SkillRequirement[]> = {\n playwright: [\n {\n name: \"Playwright CLI\uFF08playwright-cli\uFF09\",\n check: \"playwright-cli --version\",\n install: {\n linux: NPM_PLAYWRIGHT_CLI,\n darwin: NPM_PLAYWRIGHT_CLI,\n win32: NPM_PLAYWRIGHT_CLI,\n },\n postInstall: {\n linux: PLAYWRIGHT_BROWSER,\n darwin: PLAYWRIGHT_BROWSER,\n win32: PLAYWRIGHT_BROWSER,\n },\n },\n ],\n officecli: [\n {\n name: \"OfficeCLI\uFF08officecli\uFF09\",\n check: \"officecli --version\",\n install: OFFICECLI_INSTALL,\n },\n ],\n};\n\n/** \u53D6\u5F97\u67D0\u6280\u80FD\u58F0\u660E\u7684\u4F9D\u8D56\uFF1B\u672A\u58F0\u660E\u5219\u8FD4\u56DE\u7A7A\u6570\u7EC4 */\nexport function getSkillRequirements(skillName: string): SkillRequirement[] {\n return SKILL_REQUIREMENTS[skillName.trim().toLowerCase()] ?? [];\n}\n\n/** \u5168\u90E8\u58F0\u660E\u4E86\u4F9D\u8D56\u7684\u6280\u80FD\u540D */\nexport function skillsWithRequirements(): string[] {\n return Object.keys(SKILL_REQUIREMENTS);\n}\n", "import { spawn } from \"child_process\";\nimport {\n currentPlatform,\n getSkillRequirements,\n type Platform,\n type SkillRequirement,\n} from \"./dependencies\";\n\nconst CHECK_TIMEOUT = 15_000;\nconst INSTALL_TIMEOUT = 900_000;\nconst MAX_OUTPUT = 20_000;\n\nexport interface CommandResult {\n ok: boolean;\n output: string;\n timedOut: boolean;\n}\n\n/** \u4EE5\u975E\u4EA4\u4E92\u65B9\u5F0F\u6267\u884C shell \u547D\u4EE4 */\nexport function runShell(\n command: string,\n timeout: number,\n signal?: AbortSignal,\n): Promise<CommandResult> {\n return new Promise((resolve) => {\n const isWindows = process.platform === \"win32\";\n const shell = isWindows ? \"cmd.exe\" : process.env.SHELL || \"bash\";\n const args = isWindows ? [\"/d\", \"/s\", \"/c\", command] : [\"-lc\", command];\n\n const child = spawn(shell, args, {\n env: process.env,\n windowsHide: true,\n });\n\n let output = \"\";\n let timedOut = false;\n let settled = false;\n\n const append = (data: Buffer) => {\n if (output.length < MAX_OUTPUT) output += data.toString();\n };\n\n const finish = (result: CommandResult) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n signal?.removeEventListener(\"abort\", onAbort);\n resolve(result);\n };\n\n const timer = setTimeout(() => {\n timedOut = true;\n try {\n child.kill(\"SIGKILL\");\n } catch {\n // \u5FFD\u7565\n }\n }, timeout);\n\n const onAbort = () => {\n try {\n child.kill(\"SIGKILL\");\n } catch {\n // \u5FFD\u7565\n }\n finish({ ok: false, output: output + \"\\n[\u5DF2\u53D6\u6D88]\", timedOut: false });\n };\n\n if (signal) {\n if (signal.aborted) {\n onAbort();\n return;\n }\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n\n child.stdout?.on(\"data\", append);\n child.stderr?.on(\"data\", append);\n child.on(\"error\", (err) => {\n finish({ ok: false, output: output + String(err), timedOut });\n });\n child.on(\"close\", (code) => {\n finish({\n ok: code === 0 && !timedOut,\n output: timedOut ? `${output}\\n[\u6267\u884C\u8D85\u65F6 ${timeout}ms]` : output,\n timedOut,\n });\n });\n });\n}\n\n/** \u68C0\u6D4B\u67D0\u4F9D\u8D56\u662F\u5426\u5DF2\u5B89\u88C5 */\nexport async function isRequirementMet(\n requirement: SkillRequirement,\n signal?: AbortSignal,\n): Promise<boolean> {\n const result = await runShell(requirement.check, CHECK_TIMEOUT, signal);\n return result.ok;\n}\n\nexport interface InstallResult {\n ok: boolean;\n log: string;\n}\n\n/** \u5B89\u88C5\u5355\u4E2A\u4F9D\u8D56\uFF08\u542B postInstall \u4E0E\u5B89\u88C5\u540E\u590D\u6838\uFF09 */\nexport async function installRequirement(\n requirement: SkillRequirement,\n platform: Platform = currentPlatform(),\n signal?: AbortSignal,\n onOutput?: (message: string) => void,\n): Promise<InstallResult> {\n const installCommand = requirement.install[platform];\n if (!installCommand) {\n return {\n ok: false,\n log: `\u5F53\u524D\u5E73\u53F0\uFF08${platform}\uFF09\u6CA1\u6709\u53EF\u7528\u7684\u81EA\u52A8\u5B89\u88C5\u547D\u4EE4\u3002`,\n };\n }\n\n const logs: string[] = [];\n const emit = (line: string) => {\n const trimmed = line.trim();\n if (!trimmed) return;\n logs.push(trimmed);\n onOutput?.(trimmed);\n };\n\n emit(`$ ${installCommand}`);\n const install = await runShell(installCommand, INSTALL_TIMEOUT, signal);\n for (const line of tailLines(install.output, 12)) emit(line);\n if (!install.ok) {\n return { ok: false, log: logs.join(\"\\n\") };\n }\n\n const postCommand = requirement.postInstall?.[platform];\n if (postCommand) {\n emit(`$ ${postCommand}`);\n const post = await runShell(postCommand, INSTALL_TIMEOUT, signal);\n for (const line of tailLines(post.output, 12)) emit(line);\n if (!post.ok) {\n return { ok: false, log: logs.join(\"\\n\") };\n }\n }\n\n const verified = await isRequirementMet(requirement, signal);\n if (!verified) {\n emit(\n `\u26A0 \u5B89\u88C5\u547D\u4EE4\u5DF2\u6267\u884C\uFF0C\u4F46 \u201C${requirement.check}\u201D \u4ECD\u672A\u901A\u8FC7\uFF1B\u53EF\u80FD\u662F PATH \u5C1A\u672A\u5237\u65B0\uFF0C\u8BF7\u91CD\u65B0\u6253\u5F00\u7EC8\u7AEF\u540E\u518D\u8BD5\u3002`,\n );\n return { ok: false, log: logs.join(\"\\n\") };\n }\n\n emit(`\u2713 ${requirement.name} \u5DF2\u5C31\u7EEA`);\n return { ok: true, log: logs.join(\"\\n\") };\n}\n\nexport interface SkillDependencyReport {\n installed: string[];\n skipped: string[];\n failed: string[];\n}\n\nexport interface EnsureOptions {\n platform?: Platform;\n signal?: AbortSignal;\n /** \u5B9E\u65F6\u8F93\u51FA\u5B89\u88C5\u65E5\u5FD7 */\n onOutput?: (message: string) => void;\n /** \u5B89\u88C5\u524D\u786E\u8BA4\uFF08\u8FD4\u56DE false \u5219\u8DF3\u8FC7\uFF09 */\n confirm?: (\n requirement: SkillRequirement,\n command: string,\n ) => Promise<boolean>;\n}\n\n/** \u786E\u4FDD\u67D0\u6280\u80FD\u7684\u4F9D\u8D56\u5747\u5DF2\u5B89\u88C5 */\nexport async function ensureSkillRequirements(\n skillName: string,\n options: EnsureOptions = {},\n): Promise<SkillDependencyReport> {\n const platform = options.platform ?? currentPlatform();\n const report: SkillDependencyReport = {\n installed: [],\n skipped: [],\n failed: [],\n };\n\n for (const requirement of getSkillRequirements(skillName)) {\n if (await isRequirementMet(requirement, options.signal)) continue;\n\n const command = requirement.install[platform];\n if (!command) {\n report.skipped.push(`${requirement.name}\uFF08\u5F53\u524D\u5E73\u53F0\u65E0\u81EA\u52A8\u5B89\u88C5\u547D\u4EE4\uFF09`);\n continue;\n }\n\n const approved = options.confirm\n ? await options.confirm(requirement, command)\n : false;\n if (!approved) {\n report.skipped.push(`${requirement.name}`);\n continue;\n }\n\n options.onOutput?.(`\u6B63\u5728\u5B89\u88C5 ${requirement.name} \u2026\uFF08\u53EF\u80FD\u9700\u8981\u6570\u5206\u949F\uFF09`);\n const result = await installRequirement(\n requirement,\n platform,\n options.signal,\n options.onOutput,\n );\n\n if (result.ok) {\n report.installed.push(requirement.name);\n } else {\n const tail = result.log.split(\"\\n\").slice(-2).join(\" \");\n report.failed.push(`${requirement.name} \u2192 ${tail}`);\n }\n }\n\n return report;\n}\n\nfunction tailLines(text: string, count: number): string[] {\n const lines = text\n .split(\"\\n\")\n .map((line) => line.trimEnd())\n .filter((line) => line.trim().length > 0);\n return lines.slice(-count);\n}\n", "import { discoverSkills, findSkill, loadSkillContent } from \"../skills\";\nimport { getSkillRequirements } from \"../skills/dependencies\";\nimport { ensureSkillRequirements } from \"../skills/installer\";\nimport type { ToolDefinition, ToolResult } from \"./types\";\n\n/** list_skills \u2014\u2014 \u5217\u51FA\u53EF\u7528\u6280\u80FD */\nexport const listSkillsTool: ToolDefinition = {\n name: \"list_skills\",\n description:\n \"\u5217\u51FA\u7384\u732A\u5F53\u524D\u53EF\u7528\u7684\u5168\u90E8\u6280\u80FD\uFF08\u540D\u79F0\u4E0E\u7528\u9014\uFF09\u3002\" +\n \"\u6280\u80FD\u662F\u4E00\u4EFD\u6307\u5BFC\u4F60\u4F7F\u7528\u7279\u5B9A\u5916\u90E8 CLI \u5DE5\u5177\u7684\u6307\u5357\u3002\" +\n \"\u5F53\u4EFB\u52A1\u53EF\u80FD\u6D89\u53CA\u67D0\u4E2A\u9886\u57DF\uFF08\u6D4F\u89C8\u5668\u81EA\u52A8\u5316\u3001Office \u6587\u6863\u3001GitHub\u3001\u6570\u636E\u5E93\u7B49\uFF09\u65F6\uFF0C\u5148\u8C03\u7528\u672C\u5DE5\u5177\u67E5\u770B\u662F\u5426\u6709\u5BF9\u5E94\u6280\u80FD\u3002\",\n parameters: {\n type: \"object\",\n properties: {},\n required: [],\n },\n async execute(_args, _ctx): Promise<ToolResult> {\n const skills = discoverSkills();\n if (skills.length === 0) {\n return { ok: true, content: \"\u5F53\u524D\u6CA1\u6709\u53EF\u7528\u6280\u80FD\u3002\" };\n }\n const lines = skills.map((skill) => {\n const mark = skill.source === \"user\" ? \"\uFF08\u7528\u6237\uFF09\" : \"\";\n return `- ${skill.name}${mark}\uFF1A${skill.description || \"\uFF08\u65E0\u63CF\u8FF0\uFF09\"}`;\n });\n return {\n ok: true,\n content: `\u53EF\u7528\u6280\u80FD\uFF08${skills.length} \u4E2A\uFF09\uFF1A\\n${lines.join(\"\\n\")}`,\n summary: `${skills.length} \u4E2A\u6280\u80FD`,\n };\n },\n};\n\n/** load_skill \u2014\u2014 \u52A0\u8F7D\u6280\u80FD\u6307\u5357\uFF0C\u5E76\u786E\u4FDD\u5176\u5916\u90E8\u4F9D\u8D56\u5DF2\u5B89\u88C5 */\nexport const loadSkillTool: ToolDefinition = {\n name: \"load_skill\",\n description:\n \"\u52A0\u8F7D\u6307\u5B9A\u6280\u80FD\u7684\u5B8C\u6574\u6307\u5357\uFF08SKILL.md \u5168\u6587\uFF09\uFF0C\u968F\u540E\u8BF7\u4E25\u683C\u6309\u6307\u5357\u4E2D\u7684\u6B65\u9AA4\u4E0E\u547D\u4EE4\u64CD\u4F5C\u3002\" +\n \"\u82E5\u8BE5\u6280\u80FD\u4F9D\u8D56\u7684\u5916\u90E8\u547D\u4EE4\u5C1A\u672A\u5B89\u88C5\uFF0C\u7384\u732A\u4F1A\u81EA\u52A8\u5B89\u88C5\uFF08\u53EF\u80FD\u9700\u8981\u7528\u6237\u786E\u8BA4\u4E00\u6B21\uFF09\u3002\" +\n \"\u6307\u5357\u5728\u672C\u6B21\u5BF9\u8BDD\u4E2D\u6301\u7EED\u6709\u6548\uFF0C\u540C\u4E00\u4E2A\u6280\u80FD\u65E0\u9700\u91CD\u590D\u52A0\u8F7D\u3002\",\n parameters: {\n type: \"object\",\n properties: {\n name: {\n type: \"string\",\n description: \"\u6280\u80FD\u540D\u79F0\uFF0C\u4F8B\u5982 playwright\u3001officecli\",\n },\n },\n required: [\"name\"],\n },\n async execute(args, ctx): Promise<ToolResult> {\n const name = typeof args.name === \"string\" ? args.name : \"\";\n if (!name.trim()) {\n return { ok: false, content: \"\u9519\u8BEF\uFF1A\u7F3A\u5C11\u6280\u80FD\u540D\u79F0\u53C2\u6570 name\u3002\" };\n }\n\n const skill = findSkill(name);\n if (!skill) {\n const available = discoverSkills()\n .map((item) => item.name)\n .join(\", \");\n return {\n ok: false,\n content: `\u672A\u627E\u5230\u6280\u80FD \"${name}\"\u3002\u53EF\u7528\u6280\u80FD\uFF1A${available || \"\uFF08\u65E0\uFF09\"}\u3002\u53EF\u5148\u8C03\u7528 list_skills \u67E5\u770B\u3002`,\n };\n }\n\n // \u4F9D\u8D56\u68C0\u67E5\u4E0E\u81EA\u52A8\u5B89\u88C5\n const notes: string[] = [];\n if (getSkillRequirements(skill.name).length > 0) {\n const report = await ensureSkillRequirements(skill.name, {\n signal: ctx.signal,\n onOutput: (line) => ctx.emit?.(line),\n confirm: async (requirement, command) => {\n if (ctx.autoApprove) return true;\n if (!ctx.confirm) return false;\n return ctx.confirm({\n tool: \"load_skill\",\n title: `\u5B89\u88C5\u6280\u80FD\u4F9D\u8D56\uFF1A${requirement.name}`,\n detail:\n `\u6280\u80FD\u300C${skill.name}\u300D\u9700\u8981\u8BE5\u547D\u4EE4\uFF0C\u662F\u5426\u73B0\u5728\u81EA\u52A8\u5B89\u88C5\uFF1F\\n\\n${command}`,\n danger: true,\n });\n },\n });\n\n for (const item of report.installed) notes.push(`\u2713 \u5DF2\u5B89\u88C5\u5E76\u9A8C\u8BC1\uFF1A${item}`);\n for (const item of report.skipped) notes.push(`\u26A0 \u672A\u5B89\u88C5\uFF08\u5DF2\u8DF3\u8FC7\uFF09\uFF1A${item}`);\n for (const item of report.failed) notes.push(`\u2717 \u5B89\u88C5\u5931\u8D25\uFF1A${item}`);\n }\n\n const content = loadSkillContent(skill);\n const noteBlock =\n notes.length > 0\n ? `> \u4F9D\u8D56\u5904\u7406\uFF1A\\n${notes.map((note) => `> ${note}`).join(\"\\n\")}\\n\\n`\n : \"\";\n const installedCount = notes.filter((note) => note.startsWith(\"\u2713\")).length;\n\n return {\n ok: true,\n content: `# \u6280\u80FD\uFF1A${skill.name}\\n\\n${noteBlock}${content}`,\n summary:\n installedCount > 0\n ? `\u5DF2\u52A0\u8F7D ${skill.name}\uFF08\u5B89\u88C5 ${installedCount} \u9879\u4F9D\u8D56\uFF09`\n : `\u5DF2\u52A0\u8F7D\u6280\u80FD ${skill.name}`,\n };\n },\n};\n", "import type { ToolSpec } from \"../llm/types\";\nimport { bashTool } from \"./bash\";\nimport {\n editFileTool,\n globTool,\n grepTool,\n listDirTool,\n readFileTool,\n writeFileTool,\n} from \"./filesystem\";\nimport { memoryReadTool, memoryWriteTool } from \"./memory\";\nimport { listSkillsTool, loadSkillTool } from \"./skills\";\nimport type { ToolContext, ToolDefinition, ToolResult } from \"./types\";\n\nexport * from \"./types\";\n\n/** \u7384\u732A\u5185\u7F6E\u5DE5\u5177\u96C6\u5408 */\nexport const TOOLS: ToolDefinition[] = [\n listSkillsTool,\n loadSkillTool,\n memoryReadTool,\n memoryWriteTool,\n readFileTool,\n listDirTool,\n globTool,\n grepTool,\n writeFileTool,\n editFileTool,\n bashTool,\n];\n\nexport function findTool(name: string): ToolDefinition | undefined {\n return TOOLS.find((tool) => tool.name === name);\n}\n\n/** \u8F6C\u6362\u4E3A LLM \u6240\u9700\u7684\u5DE5\u5177\u58F0\u660E */\nexport function getToolSpecs(): ToolSpec[] {\n return TOOLS.map((tool) => ({\n name: tool.name,\n description: tool.description,\n parameters: tool.parameters,\n }));\n}\n\nexport interface ExecuteToolResult extends ToolResult {\n /** \u662F\u5426\u56E0\u7528\u6237\u62D2\u7EDD\u800C\u672A\u6267\u884C */\n denied?: boolean;\n}\n\n/** \u6267\u884C\u6307\u5B9A\u5DE5\u5177\uFF1B\u53C2\u6570\u4E3A JSON \u5B57\u7B26\u4E32 */\nexport async function executeTool(\n name: string,\n argsJson: string,\n ctx: ToolContext,\n): Promise<ExecuteToolResult> {\n const tool = findTool(name);\n if (!tool) {\n return { ok: false, content: `\u9519\u8BEF\uFF1A\u672A\u77E5\u5DE5\u5177 \"${name}\"` };\n }\n\n let args: Record<string, unknown> = {};\n if (argsJson && argsJson.trim()) {\n try {\n const parsed = JSON.parse(argsJson);\n // \u6392\u9664\u6570\u7EC4\uFF1A\u5426\u5219 `[1,2]` \u4F1A\u88AB\u5F53\u6210\u53C2\u6570\u5BF9\u8C61\uFF0C\u6240\u6709\u5C5E\u6027\u53D6\u503C\u90FD\u662F undefined\n if (typeof parsed === \"object\" && parsed !== null && !Array.isArray(parsed)) {\n args = parsed as Record<string, unknown>;\n }\n } catch (err) {\n return {\n ok: false,\n content: `\u9519\u8BEF\uFF1A\u5DE5\u5177\u53C2\u6570\u4E0D\u662F\u5408\u6CD5 JSON\uFF1A${err instanceof Error ? err.message : String(err)}`,\n };\n }\n }\n\n // \u53C2\u6570\u6821\u9A8C\uFF1A\u672A\u77E5\u53C2\u6570\u4E0E\u7F3A\u5931\u7684\u5FC5\u586B\u53C2\u6570\u90FD\u76F4\u63A5\u62A5\u9519\u3002\n // \u5426\u5219\u300C\u53C2\u6570\u540D\u5199\u9519\u300D\u4F1A\u88AB\u9759\u9ED8\u5FFD\u7565\u5E76\u6309\u9ED8\u8BA4\u503C\u6267\u884C\u2014\u2014\u4F8B\u5982\u628A list_dir \u7684 path \u5199\u6210\n // dirPath \u65F6\u4F1A\u6084\u6084\u5217\u51FA\u5F53\u524D\u76EE\u5F55\uFF0C\u8BA9\u8C03\u7528\u65B9\u8BEF\u4EE5\u4E3A\u5217\u7684\u662F\u76EE\u6807\u76EE\u5F55\u3002\n const schema = tool.parameters as {\n properties?: Record<string, unknown>;\n required?: string[];\n };\n const properties = schema.properties ?? {};\n const required = Array.isArray(schema.required) ? schema.required : [];\n\n const unknown = Object.keys(args).filter((key) => !(key in properties));\n if (unknown.length > 0) {\n const available = Object.keys(properties);\n return {\n ok: false,\n content:\n `\u9519\u8BEF\uFF1A${name} \u6536\u5230\u672A\u77E5\u53C2\u6570 ${unknown.map((k) => `\"${k}\"`).join(\"\u3001\")}\u3002` +\n `\u53EF\u7528\u53C2\u6570\uFF1A${available.length > 0 ? available.map((k) => `\"${k}\"`).join(\"\u3001\") : \"\uFF08\u65E0\uFF09\"}`,\n };\n }\n\n const missing = required.filter(\n (key) => args[key] === undefined || args[key] === null,\n );\n if (missing.length > 0) {\n return {\n ok: false,\n content: `\u9519\u8BEF\uFF1A${name} \u7F3A\u5C11\u5FC5\u586B\u53C2\u6570 ${missing.map((k) => `\"${k}\"`).join(\"\u3001\")}\u3002`,\n };\n }\n\n try {\n return await tool.execute(args, ctx);\n } catch (err) {\n return {\n ok: false,\n content: `\u5DE5\u5177\u6267\u884C\u5F02\u5E38\uFF1A${err instanceof Error ? err.message : String(err)}`,\n };\n }\n}\n", "/** \u6784\u5EFA\u7384\u732A\u7684\u7CFB\u7EDF\u63D0\u793A\u8BCD */\nexport function buildSystemPrompt(\n cwd: string,\n extra?: string,\n projectRules?: string | null,\n projectMemory?: { longTerm: string; recentDaily: string } | null,\n): string {\n const base = `\u4F60\u662F\u300C\u7384\u732A\u300D\uFF08XuanZhu\uFF09\uFF0C\u4E00\u6B3E\u8FD0\u884C\u5728\u7EC8\u7AEF\u4E2D\u7684 AI \u7F16\u7801 Agent\u3002\n\n\u4F60\u7684\u5DE5\u4F5C\u76EE\u5F55\uFF1A${cwd}\n\n## \u6838\u5FC3\u539F\u5219\n1. \u5148\u7406\u89E3\u518D\u52A8\u624B\uFF1A\u4FEE\u6539\u6587\u4EF6\u524D\u5148\u7528 read_file \u8BFB\u53D6\u786E\u8BA4\u5185\u5BB9\uFF0C\u4E0D\u8981\u51ED\u731C\u6D4B\u4FEE\u6539\u3002\n2. \u7CBE\u51C6\u7F16\u8F91\uFF1A\u4F18\u5148\u4F7F\u7528 edit_file \u505A\u5C40\u90E8\u66FF\u6362\uFF0C\u907F\u514D\u7528 write_file \u8986\u76D6\u6574\u4E2A\u6587\u4EF6\u3002\n3. \u4E3B\u52A8\u9A8C\u8BC1\uFF1A\u5B8C\u6210\u4EE3\u7801\u4FEE\u6539\u540E\uFF0C\u5C3D\u91CF\u4F7F\u7528 bash \u8FD0\u884C\u6D4B\u8BD5\u3001\u6784\u5EFA\u6216\u7C7B\u578B\u68C0\u67E5\u6765\u9A8C\u8BC1\u7ED3\u679C\u3002\n4. \u7B80\u6D01\u6C9F\u901A\uFF1A\u7528\u4E2D\u6587\u56DE\u590D\uFF0C\u76F4\u63A5\u7ED9\u51FA\u7ED3\u8BBA\u4E0E\u5173\u952E\u4FE1\u606F\uFF0C\u907F\u514D\u5197\u957F\u5BA2\u5957\u3002\n5. \u5DE5\u5177\u4F18\u5148\uFF1A\u9700\u8981\u67E5\u627E\u6587\u4EF6\u7528 glob\uFF0C\u641C\u7D22\u5185\u5BB9\u7528 grep\uFF0C\u4E0D\u8981\u9760\u731C\u8DEF\u5F84\u3002\n\n## \u5DE5\u5177\u4F7F\u7528\u89C4\u8303\n- read_file\uFF1A\u8BFB\u53D6\u6587\u4EF6\uFF08\u5E26\u884C\u53F7\uFF09\uFF0C\u4FEE\u6539\u524D\u5FC5\u8BFB\n- list_dir\uFF1A\u67E5\u770B\u76EE\u5F55\u7ED3\u6784\n- glob\uFF1A\u6309\u6A21\u5F0F\u67E5\u627E\u6587\u4EF6\uFF0C\u5982 \"src/**/*.ts\"\n- grep\uFF1A\u7528\u6B63\u5219\u641C\u7D22\u6587\u4EF6\u5185\u5BB9\n- write_file\uFF1A\u8986\u76D6\u5199\u5165\u6574\u4E2A\u6587\u4EF6\uFF08\u5371\u9669\uFF0C\u9700\u786E\u8BA4\uFF09\n- edit_file\uFF1A\u7CBE\u786E\u66FF\u6362\u6587\u672C\uFF08\u5371\u9669\uFF0C\u9700\u786E\u8BA4\uFF09\n- bash\uFF1A\u6267\u884C shell \u547D\u4EE4\uFF08\u5371\u9669\uFF0C\u9700\u786E\u8BA4\uFF09\n\n## \u6280\u80FD\uFF08Skills\uFF09\n\u7384\u732A\u5185\u7F6E\u82E5\u5E72\u6280\u80FD\uFF0C\u6BCF\u4E2A\u6280\u80FD\u662F\u4E00\u4EFD\u6307\u5BFC\u4F60\u4F7F\u7528\u7279\u5B9A\u5916\u90E8 CLI \u5DE5\u5177\u7684\u6307\u5357\n\uFF08\u5982 playwright \u6D4F\u89C8\u5668\u81EA\u52A8\u5316\u3001officecli \u6587\u6863\u5904\u7406\uFF09\u3002\n- \u5F53\u4EFB\u52A1\u6D89\u53CA\u67D0\u4E2A\u9886\u57DF\u65F6\uFF0C\u5148\u8C03\u7528 list_skills \u67E5\u770B\u53EF\u7528\u6280\u80FD\uFF0C\u518D\u7528 load_skill <name> \u52A0\u8F7D\u5B8C\u6574\u6307\u5357\u3002\n- \u52A0\u8F7D\u540E\u4E25\u683C\u6309\u6307\u5357\u4E2D\u7684\u547D\u4EE4\u4E0E\u6B65\u9AA4\u64CD\u4F5C\uFF1B\u6307\u5357\u5728\u672C\u6B21\u5BF9\u8BDD\u4E2D\u6301\u7EED\u6709\u6548\uFF0C\u540C\u4E00\u4E2A\u6280\u80FD\u65E0\u9700\u91CD\u590D\u52A0\u8F7D\u3002\n- \u82E5\u6307\u5357\u4F9D\u8D56\u7684 CLI \u672A\u5B89\u88C5\uFF0C\u6309\u6307\u5357\u4E2D\u7684\u5B89\u88C5\u8BF4\u660E\u5148\u5B89\u88C5\uFF0C\u4E0D\u8981\u51ED\u7A7A\u731C\u6D4B\u53C2\u6570\u3002\n\n## \u8F93\u51FA\u98CE\u683C\n- \u6D89\u53CA\u4EE3\u7801\u65F6\u4F7F\u7528 Markdown \u4EE3\u7801\u5757\u5E76\u6807\u6CE8\u8BED\u8A00\u3002\n- \u5B8C\u6210\u4EFB\u52A1\u540E\u7B80\u8981\u8BF4\u660E\u6539\u4E86\u4EC0\u4E48\u3001\u63A5\u4E0B\u6765\u53EF\u4EE5\u505A\u4EC0\u4E48\u3002\n- \u82E5\u4EFB\u52A1\u65E0\u6CD5\u5B8C\u6210\uFF0C\u8BF4\u660E\u539F\u56E0\u548C\u6240\u9700\u4FE1\u606F\u3002`;\n\n let result = base;\n\n if (projectRules && projectRules.trim()) {\n result += `\\n\\n## \u9879\u76EE\u89C4\u5219\uFF08\u6765\u81EA\u9879\u76EE\u6839 .xuanzhu/rules.md\uFF0C\u8BF7\u4F18\u5148\u9075\u5B88\uFF09\\n${projectRules.trim()}`;\n }\n\n result += buildMemorySection(projectMemory);\n\n if (extra && extra.trim()) {\n result += `\\n\\n## \u9644\u52A0\u6307\u4EE4\\n${extra.trim()}`;\n }\n\n return result;\n}\n\nconst MEMORY_EXCERPT_CHARS = 1500;\n\n/** \u751F\u6210\u300C\u9879\u76EE\u8BB0\u5FC6\u300D\u6BB5\u843D\uFF1A\u8BF4\u660E\u8BB0\u5FC6\u5DE5\u5177\u7528\u6CD5\uFF0C\u5E76\u9644\u4E0A\u957F\u671F\u8BB0\u5FC6\u8282\u9009 */\nfunction buildMemorySection(\n memory?: { longTerm: string; recentDaily: string } | null,\n): string {\n let section =\n \"\\n\\n## \u9879\u76EE\u8BB0\u5FC6\\n\" +\n \"\u672C\u9879\u76EE\u5728 `.xuanzhu/memory/` \u4E2D\u4FDD\u5B58\u8DE8\u4F1A\u8BDD\u8BB0\u5FC6\uFF08\u957F\u671F\u8BB0\u5FC6 MEMORY.md + \u6BCF\u65E5\u65E5\u5FD7\uFF09\u3002\\n\" +\n \"- \u5904\u7406\u9700\u8981\u9879\u76EE\u80CC\u666F\u7684\u4EFB\u52A1\u524D\uFF0C\u53EF\u8C03\u7528 `memory_read` \u4E86\u89E3\u6B64\u524D\u79EF\u7D2F\u7684\u7ED3\u8BBA\u4E0E\u7EA6\u5B9A\u3002\\n\" +\n \"- \u5B8C\u6210\u5B9E\u8D28\u5DE5\u4F5C\u540E\uFF0C\u8C03\u7528 `memory_write` \u8BB0\u5F55\u503C\u5F97\u8DE8\u4F1A\u8BDD\u4FDD\u7559\u7684\u4FE1\u606F\u3002\";\n\n const longTerm = memory?.longTerm?.trim();\n if (longTerm) {\n const excerpt =\n longTerm.length > MEMORY_EXCERPT_CHARS\n ? `${longTerm.slice(0, MEMORY_EXCERPT_CHARS)}\\n\u2026\uFF08\u5DF2\u622A\u65AD\uFF0C\u53EF\u7528 memory_read \u67E5\u770B\u5B8C\u6574\u5185\u5BB9\uFF09`\n : longTerm;\n section += `\\n\\n### \u73B0\u6709\u957F\u671F\u8BB0\u5FC6\uFF08\u8282\u9009\uFF09\\n${excerpt}`;\n }\n\n return section;\n}\n", "import {\n buildIntentPrompt,\n decayModelWeight,\n DEFAULT_INTENT_PROMPT,\n DEFAULT_MODEL_WEIGHT,\n pickModel,\n saveConfig,\n type ModelEntry,\n type XuanZhuConfig,\n} from \"../config/store\";\nimport { createProvider } from \"../llm\";\nimport { friendlyError } from \"../llm/http\";\nimport type { ChatMessage, LLMProvider, ToolCall } from \"../llm/types\";\nimport { executeTool, findTool, getToolSpecs, type ExecuteToolResult } from \"../tools\";\nimport type { ConfirmRequest, ToolContext } from \"../tools/types\";\nimport { loadProjectRules, readProjectMemory } from \"../workspace\";\nimport { buildSystemPrompt } from \"./prompt\";\n\nexport interface AgentEvents {\n /** \u6A21\u578B\u8F93\u51FA\u7684\u6B63\u6587\u589E\u91CF */\n onText: (delta: string) => void;\n /** \u6A21\u578B\u7684\u601D\u8003\u589E\u91CF\uFF08\u90E8\u5206\u6A21\u578B\u652F\u6301\uFF09 */\n onReasoning?: (delta: string) => void;\n /** \u5F00\u59CB\u6267\u884C\u67D0\u4E2A\u5DE5\u5177 */\n onToolStart: (call: ToolCall) => void;\n /** \u5DE5\u5177\u6267\u884C\u7ED3\u675F */\n onToolEnd: (call: ToolCall, result: ExecuteToolResult) => void;\n /** \u72B6\u6001\u53D8\u5316\uFF08\u601D\u8003\u4E2D / \u8C03\u7528\u5DE5\u5177\u7B49\uFF09 */\n onStatus: (status: string, detail?: string) => void;\n /** \u5411\u8F93\u51FA\u533A\u63A8\u9001\u4FE1\u606F\uFF08\u5DE5\u5177\u5185\u90E8\u65E5\u5FD7\u7B49\uFF09 */\n onNotice?: (message: string) => void;\n /** \u610F\u56FE\u5206\u6790\u5B8C\u6210\uFF08analysis \u4E3A\u5206\u6790\u7ED3\u679C\uFF0Coriginal \u4E3A\u7528\u6237\u539F\u59CB\u6D88\u606F\uFF09 */\n onIntent?: (analysis: string, original: string) => void;\n /** \u5F53\u524D\u4F7F\u7528\u7684\u6A21\u578B\u53D1\u751F\u53D8\u5316\uFF08\u5931\u8D25\u964D\u7EA7 / \u6743\u91CD\u8017\u5C3D\u91CD\u7F6E\uFF09 */\n onModelChange?: (info: {\n provider: string;\n model: string;\n weight: number;\n reason: string;\n }) => void;\n /** \u8BF7\u6C42\u7528\u6237\u786E\u8BA4\u5371\u9669\u64CD\u4F5C */\n confirm: (request: ConfirmRequest) => Promise<boolean>;\n}\n\nconst MAX_HISTORY_MESSAGES = 60;\n/** \u5355\u6B21\u8BF7\u6C42\u5185\u56E0\u6A21\u578B\u8C03\u7528\u5931\u8D25\u800C\u5207\u6362\u6A21\u578B\u7684\u6700\u5927\u6B21\u6570 */\nconst MAX_MODEL_SWITCHES = 3;\n\nexport class Agent {\n private provider: LLMProvider;\n private readonly config: XuanZhuConfig;\n private cwd: string;\n private readonly events: AgentEvents;\n private systemPrompt: string;\n private history: ChatMessage[] = [];\n /** \u5F53\u524D\u4F7F\u7528\u7684\u6A21\u578B\u6761\u76EE\uFF08\u591A\u6A21\u578B\u6743\u91CD\u673A\u5236\uFF09 */\n private activeModel: ModelEntry | null;\n\n constructor(\n provider: LLMProvider,\n config: XuanZhuConfig,\n cwd: string,\n events: AgentEvents,\n activeModel?: ModelEntry | null,\n ) {\n this.provider = provider;\n this.config = config;\n this.cwd = cwd;\n this.events = events;\n this.activeModel = activeModel ?? pickModel(config);\n this.systemPrompt = this.composeSystemPrompt();\n }\n\n /** \u5F53\u524D\u4F7F\u7528\u7684\u6A21\u578B\uFF08\u542B\u6743\u91CD\uFF09 */\n getActiveModel(): ModelEntry | null {\n return this.activeModel;\n }\n\n /** \u7EC4\u5408\u7CFB\u7EDF\u63D0\u793A\u8BCD\uFF08\u542B\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u4E0B\u7684\u9879\u76EE\u89C4\u5219\u4E0E\u9879\u76EE\u8BB0\u5FC6\uFF09 */\n private composeSystemPrompt(): string {\n return buildSystemPrompt(\n this.cwd,\n this.config.systemPromptExtra,\n loadProjectRules(this.cwd),\n readProjectMemory(this.cwd),\n );\n }\n\n get messages(): ChatMessage[] {\n return this.history;\n }\n\n reset(): void {\n this.history = [];\n }\n\n get messageCount(): number {\n return this.history.length;\n }\n\n /** \u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55 */\n getCwd(): string {\n return this.cwd;\n }\n\n /** \u5207\u6362\u5DE5\u4F5C\u76EE\u5F55\uFF1A\u66F4\u65B0\u5DE5\u5177\u4E0A\u4E0B\u6587\u3001\u9879\u76EE\u89C4\u5219\u4E0E\u7CFB\u7EDF\u63D0\u793A\u8BCD\uFF08\u4FDD\u7559\u5BF9\u8BDD\u5386\u53F2\uFF09 */\n setCwd(cwd: string): void {\n this.cwd = cwd;\n this.systemPrompt = this.composeSystemPrompt();\n }\n\n /** \u6267\u884C\u4E00\u6B21\u7528\u6237\u8BF7\u6C42\uFF08\u542B\u591A\u8F6E\u5DE5\u5177\u8C03\u7528\uFF09\uFF0C\u76F4\u5230\u6A21\u578B\u7ED9\u51FA\u6700\u7EC8\u7B54\u590D */\n async run(userInput: string, signal?: AbortSignal): Promise<void> {\n let content = userInput;\n\n // \u610F\u56FE\u5206\u6790\uFF08\u9ED8\u8BA4\u5173\u95ED\uFF0C\u7531\u914D\u7F6E / --intent \u63A7\u5236\uFF09\uFF1A\n // \u5148\u53D1\u8D77\u4E00\u6B21\u72EC\u7ACB\u8BF7\u6C42\u628A\u7528\u6237\u6D88\u606F\u6539\u5199\u4E3A\u610F\u56FE\u5206\u6790\u7ED3\u679C\uFF0C\u518D\u4EE5\u5B83\u4F5C\u4E3A\u672C\u8F6E\u8F93\u5165\u3002\n if (this.config.intent?.enabled) {\n this.events.onStatus(\"\u5206\u6790\u610F\u56FE\u4E2D\");\n const analysis = await this.analyzeIntent(userInput, signal);\n if (signal?.aborted) {\n this.events.onStatus(\"\u5DF2\u4E2D\u65AD\");\n return;\n }\n if (analysis) {\n content = analysis;\n this.events.onIntent?.(analysis, userInput);\n } else {\n this.events.onNotice?.(\"\u610F\u56FE\u5206\u6790\u672A\u8FD4\u56DE\u5185\u5BB9\uFF0C\u5DF2\u6309\u539F\u59CB\u8F93\u5165\u7EE7\u7EED\u3002\");\n }\n }\n\n // \u672C\u8F6E\u8D77\u70B9\u3002\u4E2D\u65AD\u6216\u51FA\u9519\u65F6\u628A\u5386\u53F2\u6574\u4F53\u56DE\u6EDA\u5230\u8FD9\u91CC\uFF0C\u4FDD\u8BC1\u5386\u53F2\u4E2D\u6C38\u4E0D\u6B8B\u7559\n // \u300C\u5B64\u7ACB user\u300D\u6216\u300Cassistant \u58F0\u660E\u7684 tool_calls \u591A\u4E8E tool \u7ED3\u679C\u300D\u8FD9\u7C7B\u65AD\u88C2\u7ED3\u6784 \u2014\u2014\n // \u5B83\u4EEC\u4F1A\u8BA9 OpenAI / Anthropic / Gemini \u5728\u4E0B\u4E00\u6B21\u8BF7\u6C42\u65F6\u76F4\u63A5\u8FD4\u56DE 400\uFF0C\n // \u7528\u6237\u53EA\u80FD\u9760 /reset \u624D\u80FD\u6062\u590D\u3002\n this.trimHistory();\n let start = this.history.length;\n this.history.push({ role: \"user\", content });\n\n // maxToolRounds \u4E3A 0 / \u8D1F\u6570\u65F6\u4E0D\u81F3\u4E8E\u4E00\u6B21\u90FD\u4E0D\u6267\u884C\uFF08\u90A3\u6837\u7528\u6237\u53EA\u4F1A\u770B\u5230\u300C\u5DF2\u8FBE\u4E0A\u9650\u300D\u800C\u65E0\u4EFB\u4F55\u56DE\u590D\uFF09\n const maxRounds = Math.max(1, Math.floor(this.config.maxToolRounds) || 1);\n\n /** \u4E2D\u65AD\u6536\u5C3E\uFF1A\u56DE\u6EDA\u672C\u8F6E\u5E76\u9759\u9ED8\u7ED3\u675F\uFF08Ctrl+C \u4E0D\u5E94\u88AB\u6E32\u67D3\u6210\u9519\u8BEF\uFF09 */\n const abortRollback = (): void => {\n this.history.length = Math.min(start, this.history.length);\n this.events.onStatus(\"\u5DF2\u4E2D\u65AD\");\n };\n\n try {\n for (let round = 0; round < maxRounds; round++) {\n if (signal?.aborted) {\n abortRollback();\n return;\n }\n\n // \u6BCF\u8F6E\u90FD\u88C1\u526A\uFF08\u8FD4\u56DE\u88AB\u88C1\u6389\u7684\u6761\u6570\uFF0C\u636E\u6B64\u6821\u6B63\u672C\u8F6E\u8D77\u70B9\uFF09\uFF1A\n // \u5355\u8F6E\u5185\u591A\u8F6E\u5DE5\u5177\u8C03\u7528\u4F1A\u8BA9\u5386\u53F2\u6301\u7EED\u589E\u957F\uFF0C\u53EA\u5728\u6700\u7EC8\u7B54\u590D\u5904\u88C1\u526A\u4E0D\u8DB3\u4EE5\u7EA6\u675F\u957F\u5EA6\u3002\n start -= this.trimHistory();\n\n this.events.onStatus(\"\u601D\u8003\u4E2D\", `\u7B2C ${round + 1} \u8F6E`);\n\n const { text, toolCalls } = await this.streamAssistant(signal);\n\n // streamAssistant \u5728\u4E2D\u65AD\u65F6\u53EF\u80FD\u300C\u6B63\u5E38\u8FD4\u56DE\u300D\u90E8\u5206\u5185\u5BB9\uFF1A\n // \u6B64\u65F6\u4E0D\u80FD\u628A\u534A\u622A assistant \u843D\u5E93\uFF0C\u4E5F\u4E0D\u8BE5\u7EE7\u7EED\u6267\u884C\u5DE5\u5177\n if (signal?.aborted) {\n abortRollback();\n return;\n }\n\n this.history.push({\n role: \"assistant\",\n content: text,\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n });\n\n if (toolCalls.length === 0) {\n this.events.onStatus(\"\u5C31\u7EEA\");\n this.trimHistory();\n return;\n }\n\n for (const call of toolCalls) {\n const result = await this.runTool(call, signal);\n this.history.push({\n role: \"tool\",\n content: result.content,\n toolCallId: call.id,\n name: call.name,\n });\n this.events.onToolEnd(call, result);\n if (signal?.aborted) {\n abortRollback();\n return;\n }\n }\n }\n\n this.events.onStatus(\n \"\u5DF2\u8FBE\u5DE5\u5177\u8C03\u7528\u4E0A\u9650\",\n `\u6700\u591A ${this.config.maxToolRounds} \u8F6E`,\n );\n } catch (err) {\n // \u771F\u9519\u8BEF\u540C\u6837\u8981\u56DE\u6EDA\uFF1A\u5426\u5219\u5386\u53F2\u4F1A\u505C\u5728\u300C\u5B64\u7ACB user\u300D\u6216\u65AD\u88C2\u7684 assistant/tool \u7EC4\u5408\u4E0A\n this.history.length = Math.min(start, this.history.length);\n if (signal?.aborted) {\n // \u4E2D\u65AD\u4E5F\u53EF\u80FD\u4EE5\u5F02\u5E38\u5F62\u5F0F\u5230\u8FBE\uFF08provider \u5728 abort \u65F6 reject\uFF09\n this.events.onStatus(\"\u5DF2\u4E2D\u65AD\");\n return;\n }\n throw err;\n }\n }\n\n /**\n * \u72EC\u7ACB\u7684\u610F\u56FE\u5206\u6790\u8BF7\u6C42\u3002\n *\n * \u7528\u914D\u7F6E\u4E2D\u7684\u6A21\u677F\u5305\u88F9\u7528\u6237\u6D88\u606F\uFF08\u9ED8\u8BA4\u6A21\u677F\u672B\u5C3E\u5373\u300C\u6D88\u606F\uFF1A<\u5185\u5BB9>\u300D\uFF09\uFF0C\u5411\u6A21\u578B\u8BF7\u6C42\u4E00\u6B21\uFF0C\n * \u8FD4\u56DE\u7684\u6B63\u6587\u4F5C\u4E3A\u540E\u7EED\u4E3B\u6D41\u7A0B\u7684\u8F93\u5165\u3002\u8981\u70B9\uFF1A\n * - \u4E0D\u643A\u5E26\u5DE5\u5177\u58F0\u660E\uFF08\u53EA\u662F\u6539\u5199\u8F93\u5165\uFF0C\u4E0D\u9700\u8981\u5DE5\u5177\uFF0C\u4E5F\u7701 token\uFF09\uFF1B\n * - \u4E0D\u5199\u5165\u5BF9\u8BDD\u5386\u53F2\uFF0C\u4FDD\u6301\u4E3B\u6D41\u7A0B\u4E0A\u4E0B\u6587\u5E72\u51C0\uFF1B\n * - \u5931\u8D25\u6216\u8FD4\u56DE\u4E3A\u7A7A\u65F6\u8FD4\u56DE null\uFF0C\u8C03\u7528\u65B9\u56DE\u9000\u5230\u539F\u59CB\u8F93\u5165\uFF1B\n * - **\u4E0D\u8BA1\u5165\u6A21\u578B\u964D\u6743**\uFF1A\u5B83\u662F\u8F85\u52A9\u8BF7\u6C42\uFF0C\u907F\u514D\u4E0E\u4E3B\u8BF7\u6C42\u91CD\u590D\u964D\u6743\u3002\n */\n private async analyzeIntent(\n userInput: string,\n signal?: AbortSignal,\n ): Promise<string | null> {\n const template =\n this.config.intent?.prompt?.trim() || DEFAULT_INTENT_PROMPT;\n const prompt = buildIntentPrompt(template, userInput);\n let text = \"\";\n\n try {\n const stream = this.provider.chat({\n messages: [{ role: \"user\", content: prompt }],\n // \u7A7A\u7684\u5DE5\u5177\u58F0\u660E\uFF1A\u5404 Provider \u4F1A\u636E\u6B64\u8DF3\u8FC7 tools \u5B57\u6BB5\n tools: [],\n temperature: this.config.temperature,\n signal,\n });\n for await (const chunk of stream) {\n if (chunk.type === \"text\") text += chunk.text;\n }\n } catch (err) {\n if (signal?.aborted) return null;\n this.events.onNotice?.(\n `\u610F\u56FE\u5206\u6790\u8BF7\u6C42\u5931\u8D25\uFF08${friendlyError(err).split(\"\\n\")[0]}\uFF09\uFF0C\u5DF2\u6309\u539F\u59CB\u8F93\u5165\u7EE7\u7EED\u3002`,\n );\n return null;\n }\n\n const trimmed = text.trim();\n return trimmed.length > 0 ? trimmed : null;\n }\n\n private async streamAssistant(\n signal?: AbortSignal,\n attempt = 0,\n tried: Set<string> = new Set(),\n ): Promise<{ text: string; toolCalls: ToolCall[] }> {\n // \u8BB0\u5F55\u672C\u6B21\u8BF7\u6C42\u5DF2\u7ECF\u7528\u8FC7\u7684\u6A21\u578B\uFF0C\u964D\u7EA7\u65F6\u4E0D\u518D\u91CD\u590D\u5C1D\u8BD5\u540C\u4E00\u4E2A\n if (this.activeModel) tried.add(this.activeModel.id);\n\n const messages: ChatMessage[] = [\n { role: \"system\", content: this.systemPrompt },\n ...this.history,\n ];\n\n let text = \"\";\n const toolCalls: ToolCall[] = [];\n // \u662F\u5426\u5DF2\u7ECF\u4EA7\u51FA\u8FC7\u5185\u5BB9\uFF1A\u5DF2\u4EA7\u51FA\u65F6\u4E0D\u518D\u6362\u6A21\u578B\u91CD\u8BD5\uFF0C\u907F\u514D\u91CD\u590D\u8F93\u51FA\n let produced = false;\n\n try {\n const stream = this.provider.chat({\n messages,\n tools: getToolSpecs(),\n temperature: this.config.temperature,\n signal,\n onRetry: (retryAttempt, maxAttempts, error) => {\n this.events.onStatus(\n `\u7F51\u7EDC\u4E2D\u65AD\uFF0C\u6B63\u5728\u91CD\u8BD5 (${retryAttempt}/${maxAttempts})`,\n friendlyError(error).split(\"\\n\")[0],\n );\n },\n });\n\n for await (const chunk of stream) {\n if (signal?.aborted) break;\n produced = true;\n switch (chunk.type) {\n case \"text\":\n text += chunk.text;\n this.events.onText(chunk.text);\n break;\n case \"reasoning\":\n this.events.onReasoning?.(chunk.text);\n break;\n case \"tool_call\":\n toolCalls.push(chunk.toolCall);\n break;\n case \"done\":\n break;\n }\n }\n\n return { text, toolCalls };\n } catch (err) {\n // \u7528\u6237\u4E3B\u52A8\u4E2D\u65AD\u4E0D\u7B97\u6A21\u578B\u5931\u8D25\uFF0C\u4E0D\u964D\u6743\n if (signal?.aborted) throw err;\n\n // \u5DF2\u7ECF\u4EA7\u51FA\u5185\u5BB9\u65F6\u672C\u8F6E\u5FC5\u7136\u5931\u8D25\uFF1A\u4ECD\u7136\u6309\u89C4\u5219\u964D\u6743\u5E76\u5199\u76D8\uFF0C\u4F46\u4E0D\u518D\u5207\u6362\u6A21\u578B\n // \uFF08\u5207\u6362\u53EA\u4F1A\u8BA9\u300C\u5F53\u524D\u6A21\u578B\u300D\u4E0E\u5B9E\u9645\u51FA\u9519\u7684\u6A21\u578B\u4E0D\u4E00\u81F4\uFF0C\u4E14\u91CD\u8BD5\u4F1A\u9020\u6210\u91CD\u590D\u8F93\u51FA\uFF09\u3002\n const switched = this.handleModelFailure(err, tried, !produced);\n if (switched && attempt < MAX_MODEL_SWITCHES) {\n return this.streamAssistant(signal, attempt + 1, tried);\n }\n throw err;\n }\n }\n\n /**\n * \u6A21\u578B\u8C03\u7528\u5931\u8D25\u7684\u5904\u7406\uFF1A\u5F53\u524D\u6A21\u578B\u6743\u91CD -1\uFF0C\u5E76\u9009\u51FA\u6743\u91CD\u6700\u9AD8\u7684\u53EF\u7528\u6A21\u578B\u3002\n *\n * - \u4ECD\u6709\u53EF\u7528\u6A21\u578B\uFF08\u4E14\u4E0E\u5F53\u524D\u4E0D\u540C\uFF09\u2192 \u5207\u6362\u5E76\u8FD4\u56DE true\uFF0C\u8C03\u7528\u65B9\u4F1A\u91CD\u8BD5\n * - \u5168\u90E8\u6A21\u578B\u6743\u91CD\u8017\u5C3D \u2192 \u91CD\u7F6E\u5168\u90E8\u6743\u91CD\u4E3A\u9ED8\u8BA4\u503C\uFF0C\u8FD4\u56DE true\n * - \u65E0\u6A21\u578B\u6761\u76EE\uFF08\u7406\u8BBA\u4E0A\u4E0D\u4F1A\u53D1\u751F\uFF09\u6216\u5207\u6362\u5931\u8D25 \u2192 \u8FD4\u56DE false\n */\n private handleModelFailure(\n error: unknown,\n tried: Set<string>,\n allowSwitch = true,\n ): boolean {\n const current = this.activeModel;\n if (!current) return false;\n\n const reason = friendlyError(error).split(\"\\n\")[0];\n const result = decayModelWeight(this.config, current.id);\n if (!result) return false;\n\n this.persistConfig();\n\n if (result.reset) {\n this.events.onNotice?.(\n `\u26A0 \u6A21\u578B ${current.id} \u8C03\u7528\u5931\u8D25\uFF08${reason}\uFF09\uFF1B\u6240\u6709\u6A21\u578B\u6743\u91CD\u5747\u5DF2\u8017\u5C3D\uFF0C` +\n `\u5DF2\u628A\u5168\u90E8\u6743\u91CD\u91CD\u7F6E\u4E3A ${DEFAULT_MODEL_WEIGHT}\u3002`,\n );\n this.events.onStatus(\"\u6743\u91CD\u5DF2\u91CD\u7F6E\");\n } else {\n this.events.onNotice?.(\n `\u26A0 \u6A21\u578B ${current.id} \u8C03\u7528\u5931\u8D25\uFF08${reason}\uFF09\uFF0C\u6743\u91CD\u964D\u4E3A ${result.weight}\u3002`,\n );\n }\n\n // \u5373\u4F7F\u4E0D\u518D\u5207\u6362\u6A21\u578B\uFF0C\u4E5F\u8981\u628A\u65B0\u6743\u91CD\u540C\u6B65\u7ED9\u754C\u9762\uFF1A\n // \u5426\u5219\u72B6\u6001\u680F\u4E0E\u968F\u540E\u6253\u5370\u7684\u9519\u8BEF\u4FE1\u606F\u4F1A\u957F\u671F\u663E\u793A\u65E7\u6743\u91CD\uFF0C\u8BEF\u5BFC\u8BCA\u65AD\u3002\n this.events.onModelChange?.({\n provider: current.provider,\n model: current.model,\n weight: result.reset ? DEFAULT_MODEL_WEIGHT : result.weight,\n reason: \"\u8C03\u7528\u5931\u8D25\u964D\u6743\",\n });\n\n // \u4E0D\u5141\u8BB8\u5207\u6362\u65F6\u5230\u6B64\u4E3A\u6B62\uFF08\u5DF2\u4EA7\u51FA\u5185\u5BB9\uFF0C\u672C\u8F6E\u5FC5\u5B9A\u5931\u8D25\uFF09\n if (!allowSwitch) return false;\n\n // \u8DF3\u8FC7\u672C\u6B21\u8BF7\u6C42\u5DF2\u7ECF\u7528\u8FC7\u7684\u6A21\u578B\uFF1A\u82E5\u6CA1\u6709\u300C\u53E6\u4E00\u4E2A\u300D\u6A21\u578B\u53EF\u7528\uFF0C\u5C31\u4E0D\u518D\u91CD\u8BD5\u3002\n // \u5355\u6A21\u578B\uFF08\u6216\u6743\u91CD\u8017\u5C3D\u91CD\u7F6E\u540E\u4ECD\u662F\u5B83\u81EA\u5DF1\uFF09\u65F6\u7528\u5B8C\u5168\u76F8\u540C\u7684\u53C2\u6570\u91CD\u8BD5\u5FC5\u7136\u518D\u6B21\u5931\u8D25\uFF0C\n // \u4F8B\u5982\u8BA4\u8BC1\u5931\u8D25\u3001\u6A21\u578B\u540D\u4E0D\u5B58\u5728\u3001baseUrl \u9519\u8BEF\u7B49\u914D\u7F6E\u7C7B\u95EE\u9898\u2014\u2014\n // \u91CD\u8BD5\u53EA\u4F1A\u767D\u767D\u6D88\u8017\u6743\u91CD\u5E76\u8BA9\u7528\u6237\u957F\u65F6\u95F4\u7B49\u5F85\u3002\n const next = pickModel(this.config, tried);\n if (!next || next.id === current.id) {\n if (next) this.activeModel = next;\n return false;\n }\n\n try {\n this.provider = createProvider(this.config, next);\n this.activeModel = next;\n this.events.onNotice?.(\n `\u21BB \u5DF2\u5207\u6362\u5230\u6A21\u578B ${next.id}\uFF08\u6743\u91CD ${next.weight}\uFF09\u91CD\u8BD5\u3002`,\n );\n this.events.onModelChange?.({\n provider: next.provider,\n model: next.model,\n weight: next.weight,\n reason: \"\u8C03\u7528\u5931\u8D25\u964D\u7EA7\",\n });\n return true;\n } catch (err) {\n this.events.onNotice?.(`\u5207\u6362\u6A21\u578B\u5931\u8D25\uFF1A${friendlyError(err)}`);\n return false;\n }\n }\n\n /** \u628A\u6743\u91CD\u53D8\u5316\u5199\u56DE\u914D\u7F6E\u6587\u4EF6\uFF1B\u5199\u76D8\u5931\u8D25\u4E0D\u5F71\u54CD\u5F53\u524D\u4F1A\u8BDD */\n private persistConfig(): void {\n try {\n saveConfig(this.config);\n } catch {\n // \u5FFD\u7565\uFF1A\u5185\u5B58\u4E2D\u7684\u6743\u91CD\u4ECD\u7136\u751F\u6548\n }\n }\n\n private async runTool(\n call: ToolCall,\n signal?: AbortSignal,\n ): Promise<ExecuteToolResult> {\n const tool = findTool(call.name);\n if (!tool) {\n return { ok: false, content: `\u9519\u8BEF\uFF1A\u672A\u77E5\u5DE5\u5177 \"${call.name}\"` };\n }\n\n // autoApprove \u5F00\u542F\u65F6\u5168\u90E8\u653E\u884C\uFF08\u5305\u62EC\u5199\u6587\u4EF6\u4E0E\u6267\u884C\u547D\u4EE4\uFF09\n const needsConfirm =\n Boolean(tool.requiresConfirmation) && !this.config.autoApprove;\n\n if (needsConfirm) {\n let argsPreview = call.arguments;\n try {\n argsPreview = JSON.stringify(JSON.parse(call.arguments), null, 2);\n } catch {\n // \u4FDD\u7559\u539F\u59CB\u5B57\u7B26\u4E32\n }\n const approved = await this.events.confirm({\n tool: call.name,\n title: `\u6267\u884C\u5DE5\u5177\uFF1A${call.name}`,\n detail: argsPreview,\n danger: Boolean(tool.danger),\n });\n if (!approved) {\n return { ok: false, denied: true, content: \"\u7528\u6237\u62D2\u7EDD\u4E86\u6B64\u64CD\u4F5C\u3002\" };\n }\n }\n\n if (signal?.aborted) {\n return { ok: false, content: \"\u64CD\u4F5C\u5DF2\u88AB\u4E2D\u65AD\u3002\" };\n }\n\n this.events.onToolStart(call);\n\n const ctx: ToolContext = {\n cwd: this.cwd,\n autoApprove: this.config.autoApprove,\n emit: (message) => this.events.onNotice?.(message),\n confirm: (request) => this.events.confirm(request),\n signal,\n };\n\n return executeTool(call.name, call.arguments, ctx);\n }\n\n /**\n * \u63A7\u5236\u5386\u53F2\u957F\u5EA6\uFF0C\u907F\u514D\u4E0A\u4E0B\u6587\u65E0\u9650\u589E\u957F\u3002\n * \u8FD4\u56DE\u88AB\u88C1\u6389\u7684\u6761\u6570\uFF1A\u8C03\u7528\u65B9\u9700\u8981\u636E\u6B64\u6821\u6B63\u300C\u672C\u8F6E\u8D77\u70B9\u300D\u4E0B\u6807\uFF08\u4E2D\u65AD/\u51FA\u9519\u65F6\u6309\u5B83\u56DE\u6EDA\uFF09\u3002\n */\n private trimHistory(): number {\n if (this.history.length <= MAX_HISTORY_MESSAGES) return 0;\n const keep = this.history.slice(-MAX_HISTORY_MESSAGES);\n // \u786E\u4FDD\u5F00\u5934\u4E0D\u662F\u5B64\u7ACB\u7684 tool \u6D88\u606F\uFF08\u5FC5\u987B\u7D27\u8DDF\u5176 assistant \u6D88\u606F\uFF09\n while (keep.length > 0 && keep[0].role === \"tool\") {\n keep.shift();\n }\n const removed = this.history.length - keep.length;\n this.history = keep;\n return removed;\n }\n}\n", "/**\n * \u8F7B\u91CF ANSI \u7EC8\u7AEF\u5DE5\u5177\uFF1A\u989C\u8272\u3001\u6837\u5F0F\u3001\u6587\u672C\u5BBD\u5EA6\u4E0E\u6298\u884C\u3002\n * \u4E0D\u4F9D\u8D56\u4EFB\u4F55\u7B2C\u4E09\u65B9\u5E93\uFF0C\u4FDD\u8BC1 TUI \u5728\u4EFB\u4F55 Node \u73AF\u5883\u53EF\u7528\u3002\n */\n\nconst ESC = \"\\x1b[\";\n\nexport const ansi = {\n reset: `${ESC}0m`,\n bold: `${ESC}1m`,\n dim: `${ESC}2m`,\n italic: `${ESC}3m`,\n underline: `${ESC}4m`,\n inverse: `${ESC}7m`,\n // \u524D\u666F\u8272\n black: `${ESC}30m`,\n red: `${ESC}31m`,\n green: `${ESC}32m`,\n yellow: `${ESC}33m`,\n blue: `${ESC}34m`,\n magenta: `${ESC}35m`,\n cyan: `${ESC}36m`,\n white: `${ESC}37m`,\n gray: `${ESC}90m`,\n brightRed: `${ESC}91m`,\n brightGreen: `${ESC}92m`,\n brightYellow: `${ESC}93m`,\n brightBlue: `${ESC}94m`,\n brightMagenta: `${ESC}95m`,\n brightCyan: `${ESC}96m`,\n brightWhite: `${ESC}97m`,\n // \u80CC\u666F\u8272\n bgRed: `${ESC}41m`,\n bgGreen: `${ESC}42m`,\n bgYellow: `${ESC}43m`,\n bgBlue: `${ESC}44m`,\n bgMagenta: `${ESC}45m`,\n bgCyan: `${ESC}46m`,\n bgGray: `${ESC}100m`,\n};\n\nexport const cursor = {\n hide: `${ESC}?25l`,\n show: `${ESC}?25h`,\n up: (n = 1) => `${ESC}${n}A`,\n down: (n = 1) => `${ESC}${n}B`,\n right: (n = 1) => `${ESC}${n}C`,\n left: (n = 1) => `${ESC}${n}D`,\n to: (row: number, col: number) => `${ESC}${row};${col}H`,\n col: (col: number) => `${ESC}${col}G`,\n clearLine: `${ESC}2K`,\n clearToEnd: `${ESC}0K`,\n clearScreen: `${ESC}2J`,\n};\n\nexport const screen = {\n enterAlt: `${ESC}?1049h`,\n exitAlt: `${ESC}?1049l`,\n save: `${ESC}s`,\n restore: `${ESC}u`,\n};\n\n/** \u5224\u65AD\u7801\u70B9\u662F\u5426\u4E3A\u5168\u89D2\uFF08\u5360 2 \u5217\uFF09 */\nfunction isWideCodePoint(cp: number): boolean {\n return (\n (cp >= 0x1100 && cp <= 0x115f) || // Hangul Jamo\n (cp >= 0x2e80 && cp <= 0x303e) || // CJK Radicals / Kangxi\n (cp >= 0x3041 && cp <= 0x33ff) || // Hiragana..CJK Symbols\n (cp >= 0x3400 && cp <= 0x4dbf) || // CJK Ext A\n (cp >= 0x4e00 && cp <= 0x9fff) || // CJK Unified\n (cp >= 0xa000 && cp <= 0xa4cf) || // Yi\n (cp >= 0xac00 && cp <= 0xd7a3) || // Hangul Syllables\n (cp >= 0xf900 && cp <= 0xfaff) || // CJK Compat\n (cp >= 0xfe30 && cp <= 0xfe4f) || // CJK Compat Forms\n (cp >= 0xff00 && cp <= 0xff60) || // Fullwidth Forms\n (cp >= 0xffe0 && cp <= 0xffe6) || // Fullwidth Signs\n (cp >= 0x1f300 && cp <= 0x1faff) || // Emoji\n (cp >= 0x20000 && cp <= 0x3fffd) // CJK Ext B+\n );\n}\n\n/** \u8BA1\u7B97\u5B57\u7B26\u4E32\u5728\u7EC8\u7AEF\u4E2D\u7684\u663E\u793A\u5BBD\u5EA6\uFF08\u5FFD\u7565 ANSI \u8F6C\u4E49\u5E8F\u5217\uFF09 */\nexport function textWidth(text: string): number {\n let width = 0;\n for (let i = 0; i < text.length; i++) {\n const code = text.codePointAt(i);\n if (code === undefined) continue;\n if (code === 0x1b) {\n // \u8DF3\u8FC7 ANSI \u5E8F\u5217 ESC[...m\n const match = /^\\x1b\\[[0-9;?]*[A-Za-z]/.exec(text.slice(i));\n if (match) {\n i += match[0].length - 1;\n continue;\n }\n }\n if (code > 0xffff) i++; // \u4EE3\u7406\u5BF9\n if (code < 32) continue; // \u63A7\u5236\u5B57\u7B26\n width += isWideCodePoint(code) ? 2 : 1;\n }\n return width;\n}\n\n/**\n * \u6309\u663E\u793A\u5BBD\u5EA6\u6298\u884C\u3002\u4FDD\u7559 ANSI \u989C\u8272\u72B6\u6001\uFF08\u7B80\u5355\u5904\u7406\uFF1A\u5728\u6298\u884C\u5904\u91CD\u7F6E\u5E76\u5EF6\u7EED\uFF09\u3002\n */\nexport function wrapText(text: string, maxWidth: number): string[] {\n const lines: string[] = [];\n for (const raw of text.split(\"\\n\")) {\n if (raw === \"\") {\n lines.push(\"\");\n continue;\n }\n let current = \"\";\n let width = 0;\n // \u9010 token\uFF08ANSI \u5E8F\u5217\u89C6\u4E3A\u6574\u4F53\uFF09\u3002\n // \u4F7F\u7528 u \u6A21\u5F0F\u8BA9 `.` \u5339\u914D\u5B8C\u6574\u7801\u70B9\uFF0C\u907F\u514D emoji \u7B49\u4EE3\u7406\u5BF9\u88AB\u62C6\u5230\u4E24\u884C\u4E4B\u95F4\u3002\n const tokens = raw.match(/\\x1b\\[[0-9;?]*[A-Za-z]|./gu) ?? [];\n for (const token of tokens) {\n const tokenWidth = textWidth(token);\n if (width + tokenWidth > maxWidth && current !== \"\") {\n lines.push(current);\n current = \"\";\n width = 0;\n }\n current += token;\n width += tokenWidth;\n }\n lines.push(current);\n }\n return lines;\n}\n\n/**\n * \u622A\u65AD\u5B57\u7B26\u4E32\u5230\u6307\u5B9A\u663E\u793A\u5BBD\u5EA6\uFF0C\u8D85\u51FA\u90E8\u5206\u4EE5\u7701\u7565\u53F7\u7ED3\u5C3E\u3002\n *\n * \u6309 token\uFF08ANSI \u5E8F\u5217\u89C6\u4E3A\u6574\u4F53\uFF09\u8FED\u4EE3\uFF0C\u800C\u4E0D\u662F\u9010\u5B57\u7B26\uFF1A\n * - \u9010\u5B57\u7B26\u65F6 `textWidth(\"[31m\" \u7684\u5355\u4E2A\u5B57\u7B26)` \u4F1A\u628A\u8F6C\u4E49\u53C2\u6570\u5F53\u6210\u53EF\u89C1\u5BBD\u5EA6\uFF0C\u5BFC\u81F4\u63D0\u524D\u622A\u65AD\uFF1B\n * - \u66F4\u7CDF\u7684\u662F `break` \u53EF\u80FD\u843D\u5728\u5E8F\u5217\u5185\u90E8\uFF0C\u4EA7\u51FA\u672A\u7EC8\u6B62\u7684 CSI\uFF08\u5982 `\\x1b[44`\uFF09\uFF0C\n * \u7EC8\u7AEF\u4F1A\u7EE7\u7EED\u541E\u6389\u540E\u7EED\u5B57\u8282\u76F4\u5230\u9047\u5230\u7EC8\u6B62\u7B26\uFF0C\u6574\u884C\u4E32\u7801\u3002\n * \u672B\u5C3E\u8865 `reset`\uFF0C\u907F\u514D\u88AB\u622A\u65AD\u7684\u989C\u8272\u6CC4\u6F0F\u5230\u540E\u7EED\u5185\u5BB9\u3002\n */\nexport function truncate(text: string, maxWidth: number): string {\n if (textWidth(text) <= maxWidth) return text;\n const tokens = text.match(/\\x1b\\[[0-9;?]*[A-Za-z]|[\\s\\S]/gu) ?? [];\n let result = \"\";\n let width = 0;\n const limit = Math.max(0, maxWidth - 1); // \u9884\u7559\u7701\u7565\u53F7\u5360\u4F4D\n for (const token of tokens) {\n const w = textWidth(token);\n if (width + w > limit) break;\n result += token;\n width += w;\n }\n return `${result}${ansi.reset}\u2026`;\n}\n\n/** \u7528\u7A7A\u683C\u586B\u5145\u5230\u6307\u5B9A\u663E\u793A\u5BBD\u5EA6\uFF08\u5DE6\u5BF9\u9F50\uFF09 */\nexport function padEnd(text: string, targetWidth: number): string {\n const w = textWidth(text);\n return text + \" \".repeat(Math.max(0, targetWidth - w));\n}\n", "import { ansi } from \"../utils/ansi\";\n\n/**\n * \u6D41\u5F0F Markdown \u6E32\u67D3\u5668\uFF1A\u628A\u6A21\u578B\u8F93\u51FA\u7684\u589E\u91CF\u6587\u672C\u6309\u884C\u8F6C\u6362\u4E3A\u5E26 ANSI \u989C\u8272\u7684\u884C\uFF0C\n * \u5E76\u8DDF\u8E2A\u4EE3\u7801\u5757\u72B6\u6001\uFF08\u8DE8 chunk \u4FDD\u6301\u6B63\u786E\uFF09\u3002\n */\nexport class MarkdownRenderer {\n private buffer = \"\";\n private inCodeBlock = false;\n private codeLang = \"\";\n\n /** \u8FFD\u52A0\u589E\u91CF\u6587\u672C\uFF0C\u8FD4\u56DE\u65B0\u4EA7\u751F\u7684\u3001\u5DF2\u5B8C\u6210\u6E32\u67D3\u7684\u884C */\n push(text: string): string[] {\n this.buffer += text;\n const lines: string[] = [];\n let newlineIndex = this.buffer.indexOf(\"\\n\");\n while (newlineIndex !== -1) {\n const line = this.buffer.slice(0, newlineIndex);\n this.buffer = this.buffer.slice(newlineIndex + 1);\n lines.push(this.renderLine(line));\n newlineIndex = this.buffer.indexOf(\"\\n\");\n }\n return lines;\n }\n\n /** \u7AA5\u89C6\u5F53\u524D\u5C1A\u672A\u5B8C\u6210\u7684\u884C\uFF08\u7528\u4E8E\u6D41\u5F0F\u5B9E\u65F6\u663E\u793A\uFF0C\u4E0D\u6539\u53D8\u72B6\u6001\uFF09 */\n peek(): string {\n if (!this.buffer) return \"\";\n if (this.inCodeBlock) return `${ansi.cyan}${this.buffer}${ansi.reset}`;\n return this.buffer;\n }\n\n /**\n * \u51B2\u5237\u672A\u5B8C\u6210\u7684\u6700\u540E\u4E00\u884C\uFF08\u6D41\u7ED3\u675F\u65F6\u8C03\u7528\uFF09\u3002\n *\n * \u65E0\u8BBA\u6709\u65E0\u6B8B\u4F59\u5185\u5BB9\u90FD\u5FC5\u987B\u590D\u4F4D\u4EE3\u7801\u5757\u72B6\u6001\uFF1A\u82E5\u67D0\u8F6E\u8F93\u51FA\u5728\u4EE3\u7801\u5757\u4E2D\u9014\u7ED3\u675F\n * \uFF08\u88AB\u4E2D\u65AD / \u88AB\u622A\u65AD / \u7ED3\u5C3E\u6CA1\u6709\u95ED\u5408 ```\uFF09\uFF0C`inCodeBlock` \u4F1A\u6B8B\u7559\u4E3A true\uFF0C\n * \u5BFC\u81F4\u4E0B\u4E00\u8F6E\u5168\u90E8\u5185\u5BB9\u88AB\u6E32\u67D3\u6210\u9752\u8272\u4EE3\u7801\u3001\u4E14\u4E0B\u4E00\u4E2A ``` \u88AB\u5F53\u6210\u95ED\u5408\u800C\u975E\u5F00\u542F\u3002\n */\n flush(): string[] {\n if (this.buffer.length === 0) {\n this.inCodeBlock = false;\n this.codeLang = \"\";\n return [];\n }\n const line = this.buffer;\n this.buffer = \"\";\n const rendered = this.renderLine(line);\n this.inCodeBlock = false;\n this.codeLang = \"\";\n return [rendered];\n }\n\n private renderLine(rawLine: string): string {\n const line = rawLine.replace(/\\r$/, \"\");\n const trimmed = line.trimStart();\n\n // \u4EE3\u7801\u5757\u56F4\u680F\n if (trimmed.startsWith(\"```\")) {\n if (!this.inCodeBlock) {\n this.inCodeBlock = true;\n this.codeLang = trimmed.slice(3).trim();\n const label = this.codeLang ? ` ${this.codeLang} ` : \"\";\n return `${ansi.gray}\u250C\u2500${label}${\"\u2500\".repeat(Math.max(0, 6 - label.length))}${ansi.reset}`;\n }\n this.inCodeBlock = false;\n this.codeLang = \"\";\n return `${ansi.gray}\u2514\u2500\u2500${ansi.reset}`;\n }\n\n if (this.inCodeBlock) {\n return `${ansi.cyan}${line}${ansi.reset}`;\n }\n\n // \u6807\u9898\n const heading = /^(#{1,6})\\s+(.*)$/.exec(trimmed);\n if (heading) {\n const text = heading[2];\n const level = heading[1].length;\n if (level <= 2) return `${ansi.bold}${ansi.brightWhite}${text}${ansi.reset}`;\n return `${ansi.bold}${text}${ansi.reset}`;\n }\n\n // \u5F15\u7528\n if (trimmed.startsWith(\"> \")) {\n return `${ansi.gray}\u2502 ${trimmed.slice(2)}${ansi.reset}`;\n }\n\n // \u5217\u8868\n const list = /^(\\s*)([-*+]|\\d+\\.)\\s+(.*)$/.exec(line);\n if (list) {\n return `${list[1]}${ansi.blue}${list[2]}${ansi.reset} ${list[3]}`;\n }\n\n // \u5206\u9694\u7EBF\n if (/^(-{3,}|\\*{3,}|_{3,})$/.test(trimmed)) {\n return `${ansi.gray}${\"\u2500\".repeat(20)}${ansi.reset}`;\n }\n\n return this.renderInline(line);\n }\n\n /** \u5904\u7406\u884C\u5185\u7684 **\u7C97\u4F53**\u3001`\u4EE3\u7801`\u3001\u884C\u5185\u94FE\u63A5 */\n private renderInline(line: string): string {\n let result = line;\n // \u884C\u5185\u4EE3\u7801\n result = result.replace(\n /`([^`]+)`/g,\n (_match, code: string) => `${ansi.cyan}${code}${ansi.reset}`,\n );\n // \u7C97\u4F53\n result = result.replace(\n /\\*\\*([^*]+)\\*\\*/g,\n (_match, text: string) => `${ansi.bold}${text}${ansi.reset}`,\n );\n // \u5269\u4F59\u659C\u4F53\u6807\u8BB0\u53BB\u9664\n result = result.replace(/(^|\\s)\\*([^*\\s][^*]*)\\*(?=\\s|$)/g, \"$1$2\");\n return result;\n }\n}\n", "import { spawn, type ChildProcess } from \"child_process\";\nimport * as fs from \"fs\";\nimport * as os from \"os\";\nimport * as path from \"path\";\nimport { ansi } from \"../utils/ansi\";\n\n/** \u9762\u677F\u4FDD\u7559\u7684\u6700\u5927\u884C\u6570\uFF08\u9632\u6B62\u957F\u4EFB\u52A1\u8F93\u51FA\u6491\u7206\u5185\u5B58\uFF09 */\nconst MAX_LINES = 2000;\n/** \u5355\u884C\u672A\u7ED3\u675F\u5185\u5BB9\u7684\u6700\u5927\u957F\u5EA6\uFF08\u9632\u6B62\u65E0\u6362\u884C\u8F93\u51FA\u6491\u7206\u5185\u5B58\uFF09 */\nconst MAX_PARTIAL = 8192;\n/** \u4E2D\u65AD\u540E\u5F3A\u5236\u6740\u6B7B\u7684\u7B49\u5F85\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09 */\nconst KILL_GRACE_MS = 1200;\n\n/**\n * \u53F3\u4FA7\u7EC8\u7AEF\u9762\u677F\uFF1A\u5728\u9879\u76EE\u76EE\u5F55\u4E0B\u6267\u884C shell \u547D\u4EE4\u5E76\u6536\u96C6\u8F93\u51FA\u3002\n *\n * \u5B9E\u73B0\u8BF4\u660E\uFF1A\u4E3A\u652F\u6301\u53EF\u9760\u4E2D\u65AD\uFF08Ctrl+C\uFF09\u4E14\u4E0D\u5F15\u5165\u539F\u751F\u4F9D\u8D56\uFF0C\u6BCF\u6761\u547D\u4EE4\u4F7F\u7528\u72EC\u7ACB\u7684\n * `spawn(shell, [\"-c\", cmd])`\uFF0C\u800C\u4E0D\u662F\u6301\u4E45 PTY\u3002\u56E0\u6B64\uFF1A\n * - \u4E0D\u652F\u6301 vim / htop / less \u8FD9\u7C7B\u9700\u8981 TTY \u7684\u5168\u5C4F\u4EA4\u4E92\u7A0B\u5E8F\uFF1B\n * - `export` \u7684\u73AF\u5883\u53D8\u91CF\u4E0D\u4F1A\u8DE8\u547D\u4EE4\u4FDD\u7559\uFF1B\n * - `cd` \u7531\u672C\u7C7B\u7EF4\u62A4\uFF08\u89C1 handleCd\uFF09\uFF0C\u4F7F\u9762\u677F\u5177\u5907\"\u5F53\u524D\u76EE\u5F55\"\u8BED\u4E49\u3002\n */\nexport class ShellPanel {\n private lines: string[] = [];\n /** \u5C1A\u672A\u9047\u5230\u6362\u884C\u7684\u5F53\u524D\u884C\uFF08\u8FDB\u5EA6\u8F93\u51FA\u4F1A\u53CD\u590D\u8986\u76D6\u5B83\uFF09 */\n private partial = \"\";\n private running?: ChildProcess;\n private killTimer?: NodeJS.Timeout;\n private cwd: string;\n private readonly onChange: () => void;\n\n /**\n * ANSI \u89E3\u6790\u72B6\u6001\u3002\u5FC5\u987B\u662F**\u5B9E\u4F8B\u5B57\u6BB5**\uFF1A\u8F93\u51FA\u4EE5\u7BA1\u9053\u5206\u7247\u5230\u8FBE\u65F6\uFF0C\n * \u4E00\u4E2A\u8F6C\u4E49\u5E8F\u5217\u53EF\u80FD\u88AB\u5207\u6210\u4E24\u5757\uFF08\u5982 `\\x1b[3` + `1m`\uFF09\uFF0C\n * \u82E5\u6BCF\u5757\u90FD\u4ECE \"text\" \u72B6\u6001\u91CD\u65B0\u5F00\u59CB\uFF0C\u540E\u534A\u622A\u4F1A\u4F5C\u4E3A\u666E\u901A\u6587\u672C\u5199\u5165\u8F93\u51FA\u884C\u3002\n */\n private parseState: \"text\" | \"esc\" | \"csi\" | \"osc\" = \"text\";\n private parseSeq = \"\";\n\n constructor(cwd: string, onChange: () => void) {\n this.cwd = cwd;\n this.onChange = onChange;\n this.pushLine(`${ansi.gray}\u7EC8\u7AEF\u5C31\u7EEA \u00B7 \u547D\u4EE4\u5728\u5F53\u524D\u9879\u76EE\u76EE\u5F55\u4E0B\u6267\u884C${ansi.reset}`);\n }\n\n getCwd(): string {\n return this.cwd;\n }\n\n isRunning(): boolean {\n return this.running !== undefined;\n }\n\n /** \u5207\u6362\u9879\u76EE\u76EE\u5F55\uFF08/switch \u65F6\u8C03\u7528\uFF09 */\n setCwd(cwd: string): void {\n this.cwd = cwd;\n this.pushLine(`${ansi.gray}\u2500\u2500 \u5DE5\u4F5C\u76EE\u5F55\u5DF2\u5207\u6362\uFF1A${cwd}${ansi.reset}`);\n this.onChange();\n }\n\n clear(): void {\n this.lines = [];\n this.partial = \"\";\n this.onChange();\n }\n\n /** \u5411\u8F93\u51FA\u533A\u8FFD\u52A0\u63D0\u793A\u6587\u672C\uFF08\u7528\u4E8E\u5C55\u793A\u8865\u5168\u5019\u9009\u7B49\uFF09 */\n notice(text: string): void {\n this.pushLine(text);\n this.onChange();\n }\n\n /** \u9762\u677F\u53EF\u89C6\u884C\uFF08\u542B\u5C1A\u672A\u7ED3\u675F\u7684\u5F53\u524D\u884C\uFF09 */\n visibleLines(): string[] {\n return this.partial ? [...this.lines, this.partial] : this.lines;\n }\n\n /** \u6267\u884C\u4E00\u6761\u547D\u4EE4 */\n run(command: string): void {\n const cmd = command.trim();\n if (!cmd) return;\n if (this.running) {\n this.pushLine(`${ansi.yellow}\u26A0 \u4E0A\u4E00\u6761\u547D\u4EE4\u4ECD\u5728\u8FD0\u884C\uFF0C\u8BF7\u5148 Ctrl+C \u4E2D\u65AD${ansi.reset}`);\n this.onChange();\n return;\n }\n\n // \u5185\u7F6E\u5904\u7406\uFF1A\u6E05\u5C4F\u4E0E\u76EE\u5F55\u5207\u6362\n if (cmd === \"clear\" || cmd === \"cls\") {\n this.clear();\n return;\n }\n if (this.handleCd(cmd)) return;\n\n this.flushPartial();\n this.pushLine(\n `${ansi.brightGreen}\u276F${ansi.reset} ${ansi.bold}${cmd}${ansi.reset}`,\n );\n\n const shell = process.env.SHELL || \"/bin/bash\";\n let child: ChildProcess;\n try {\n child = spawn(shell, [\"-c\", cmd], {\n cwd: this.cwd,\n env: {\n ...process.env,\n TERM: \"xterm-256color\",\n // \u8BA9\u652F\u6301\u7684\u7A0B\u5E8F\u5728\u7BA1\u9053\u4E0B\u4ECD\u8F93\u51FA\u989C\u8272\n CLICOLOR_FORCE: \"1\",\n FORCE_COLOR: \"1\",\n },\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n // \u72EC\u7ACB\u8FDB\u7A0B\u7EC4\uFF1A\u4E2D\u65AD\u65F6\u53EF\u4EE5\u5411\u6574\u7EC4\u53D1\u4FE1\u53F7\uFF0C\u907F\u514D\u7559\u4E0B\u5B64\u513F\u8FDB\u7A0B\n detached: true,\n });\n } catch (err) {\n this.pushLine(\n `${ansi.red}\u2717 \u542F\u52A8\u5931\u8D25\uFF1A${err instanceof Error ? err.message : String(err)}${ansi.reset}`,\n );\n this.onChange();\n return;\n }\n\n this.running = child;\n const feed = (data: Buffer): void => this.feed(data.toString(\"utf8\"));\n child.stdout?.on(\"data\", feed);\n child.stderr?.on(\"data\", feed);\n\n child.on(\"error\", (err) => {\n this.flushPartial();\n this.pushLine(`${ansi.red}\u2717 \u6267\u884C\u51FA\u9519\uFF1A${err.message}${ansi.reset}`);\n this.running = undefined;\n this.onChange();\n });\n\n child.on(\"close\", (code, signal) => {\n this.flushPartial();\n if (signal) {\n this.pushLine(`${ansi.yellow}\u23F9 \u5DF2\u4E2D\u65AD\uFF08${signal}\uFF09${ansi.reset}`);\n } else if (code === 0) {\n this.pushLine(`${ansi.gray}\u2713 \u5B8C\u6210${ansi.reset}`);\n } else {\n this.pushLine(`${ansi.red}\u2717 \u9000\u51FA\u7801 ${code}${ansi.reset}`);\n }\n this.running = undefined;\n this.onChange();\n });\n\n this.onChange();\n }\n\n /** \u4E2D\u65AD\u6B63\u5728\u8FD0\u884C\u7684\u547D\u4EE4\uFF08\u5148 SIGINT\uFF0C\u8D85\u65F6\u540E SIGKILL \u6574\u7EC4\uFF09 */\n interrupt(): void {\n const child = this.running;\n if (!child || child.pid === undefined) return;\n const pid = child.pid;\n const signalGroup = (sig: NodeJS.Signals): void => {\n try {\n process.kill(-pid, sig);\n } catch {\n try {\n child.kill(sig);\n } catch {\n // \u8FDB\u7A0B\u53EF\u80FD\u5DF2\u9000\u51FA\n }\n }\n };\n signalGroup(\"SIGINT\");\n if (this.killTimer) clearTimeout(this.killTimer);\n this.killTimer = setTimeout(() => {\n this.killTimer = undefined;\n if (this.running === child) signalGroup(\"SIGKILL\");\n }, KILL_GRACE_MS);\n }\n\n /**\n * \u91CA\u653E\u8D44\u6E90\uFF1A\u7EC8\u6B62\u4ECD\u5728\u8FD0\u884C\u7684\u547D\u4EE4\u5E76\u6E05\u7406\u5B9A\u65F6\u5668\u3002\n * \u547D\u4EE4\u4EE5 `detached` \u72EC\u7ACB\u8FDB\u7A0B\u7EC4\u542F\u52A8\uFF0C\u82E5\u4E0D\u5728\u9000\u51FA\u65F6\u7EC8\u6B62\uFF0C\u7236\u8FDB\u7A0B\u7ED3\u675F\u540E\u5B83\u4F1A\u6210\u4E3A\u5B64\u513F\u3002\n */\n dispose(): void {\n if (this.killTimer) {\n clearTimeout(this.killTimer);\n this.killTimer = undefined;\n }\n const child = this.running;\n this.running = undefined;\n if (!child || child.pid === undefined) return;\n try {\n process.kill(-child.pid, \"SIGKILL\");\n } catch {\n try {\n child.kill(\"SIGKILL\");\n } catch {\n // \u8FDB\u7A0B\u53EF\u80FD\u5DF2\u9000\u51FA\n }\n }\n }\n\n // ------------------------------------------------------------ \u5185\u90E8\u5B9E\u73B0\n\n /** \u5904\u7406 `cd`\uFF08\u81EA\u884C\u7EF4\u62A4\u5DE5\u4F5C\u76EE\u5F55\uFF0C\u56E0\u4E3A\u6BCF\u6761\u547D\u4EE4\u662F\u72EC\u7ACB\u8FDB\u7A0B\uFF09 */\n private handleCd(command: string): boolean {\n const match = /^cd(?:\\s+([\\s\\S]*))?$/.exec(command);\n if (!match) return false;\n const raw = (match[1] ?? \"\").trim().replace(/^['\"]|['\"]$/g, \"\");\n\n let next: string;\n if (!raw || raw === \"~\") {\n next = os.homedir();\n } else {\n const expanded = raw.startsWith(\"~/\")\n ? path.join(os.homedir(), raw.slice(2))\n : raw;\n next = path.isAbsolute(expanded)\n ? expanded\n : path.resolve(this.cwd, expanded);\n }\n\n try {\n if (!fs.statSync(next).isDirectory()) {\n this.pushLine(`${ansi.red}cd: \u4E0D\u662F\u76EE\u5F55\uFF1A${next}${ansi.reset}`);\n this.onChange();\n return true;\n }\n } catch {\n this.pushLine(`${ansi.red}cd: \u76EE\u5F55\u4E0D\u5B58\u5728\uFF1A${next}${ansi.reset}`);\n this.onChange();\n return true;\n }\n\n this.cwd = next;\n this.flushPartial();\n this.pushLine(`${ansi.gray}cd ${this.cwd}${ansi.reset}`);\n this.onChange();\n return true;\n }\n\n /**\n * \u6D88\u8D39\u4E00\u6BB5\u8F93\u51FA\uFF1A\n * - \u6309\u884C\u62C6\u5206\uFF0C`\\r` \u89C6\u4E3A\u56DE\u5230\u884C\u9996\uFF08\u8986\u76D6\u5F53\u524D\u884C\uFF0C\u7528\u4E8E\u8FDB\u5EA6\u6761\uFF09\uFF1B\n * - \u4FDD\u7559 SGR \u989C\u8272\u5E8F\u5217\uFF08`\\x1b[\u2026m`\uFF09\uFF0C\u4E22\u5F03\u5149\u6807\u79FB\u52A8\u7B49\u5176\u4ED6\u63A7\u5236\u5E8F\u5217\uFF0C\n * \u5426\u5219\u5B50\u8FDB\u7A0B\u7684\u7EC8\u7AEF\u63A7\u5236\u4F1A\u7834\u574F\u672C\u5E94\u7528\u7684\u6574\u5C4F\u6E32\u67D3\u3002\n */\n private feed(text: string): void {\n const data = text.replace(/\\r\\n/g, \"\\n\");\n let buffer = this.partial;\n // \u8DE8 chunk \u4FDD\u6301\u89E3\u6790\u72B6\u6001\uFF08\u89C1 parseState \u5B57\u6BB5\u8BF4\u660E\uFF09\n let state = this.parseState;\n let seq = this.parseSeq;\n\n for (const ch of data) {\n if (state === \"osc\") {\n // OSC \u4EE5 BEL \u6216 ST(\\x1b\\\\) \u7ED3\u675F\uFF0C\u5185\u5BB9\u6574\u4F53\u4E22\u5F03\n if (ch === \"\\x07\") state = \"text\";\n else if (ch === \"\\\\\" && seq.endsWith(\"\\x1b\")) state = \"text\";\n seq += ch;\n continue;\n }\n if (state === \"esc\") {\n if (ch === \"[\") {\n state = \"csi\";\n seq = \"\\x1b[\";\n continue;\n }\n if (ch === \"]\") {\n state = \"osc\";\n seq = \"\\x1b]\";\n continue;\n }\n state = \"text\"; // \u5176\u4ED6\u4E24\u5B57\u8282\u5E8F\u5217\uFF1A\u4E22\u5F03\n continue;\n }\n if (state === \"csi\") {\n seq += ch;\n if (ch >= \"@\" && ch <= \"~\") {\n // \u7EC8\u6B62\u5B57\u8282\uFF1A\u4EC5\u4FDD\u7559\u989C\u8272 / \u6837\u5F0F\uFF08SGR\uFF09\n if (ch === \"m\") buffer += seq;\n state = \"text\";\n }\n continue;\n }\n\n if (ch === \"\\x1b\") {\n state = \"esc\";\n seq = \"\\x1b\";\n continue;\n }\n if (ch === \"\\r\") {\n buffer = \"\";\n continue;\n }\n if (ch === \"\\n\") {\n this.pushLine(buffer);\n buffer = \"\";\n continue;\n }\n if (ch === \"\\x07\" || ch === \"\\x08\") continue; // \u8702\u9E23 / \u9000\u683C\n buffer += ch;\n }\n\n // \u65E0\u6362\u884C\u7684\u8D85\u957F\u8F93\u51FA\uFF08\u5982 `tr -d '\\n'`\uFF09\u4F1A\u8BA9 partial \u65E0\u754C\u589E\u957F\uFF0C\n // \u884C\u6570\u4E0A\u9650\u5BF9\u5B83\u65E0\u6548\uFF1B\u8D85\u8FC7\u9608\u503C\u5C31\u5F53\u4F5C\u4E00\u6574\u884C\u6536\u4E0B\u3002\n if (buffer.length > MAX_PARTIAL) {\n this.pushLine(buffer);\n buffer = \"\";\n }\n\n this.parseState = state;\n this.parseSeq = seq;\n this.partial = buffer;\n this.onChange();\n }\n\n private pushLine(line: string): void {\n this.lines.push(line);\n if (this.lines.length > MAX_LINES) {\n this.lines.splice(0, this.lines.length - MAX_LINES);\n }\n }\n\n private flushPartial(): void {\n if (!this.partial) return;\n this.pushLine(this.partial);\n this.partial = \"\";\n }\n}\n\n// -------------------------------------------------------------------- \u8865\u5168\n\n/**\n * \u53F3\u4FA7\u7EC8\u7AEF\u6BCF\u6761\u547D\u4EE4\u72EC\u7ACB\u6267\u884C\uFF08\u975E\u6301\u4E45 shell\uFF09\uFF0C\u56E0\u6B64 shell \u81EA\u8EAB\u7684 Tab \u8865\u5168\u4E0D\u53EF\u7528\uFF0C\n * \u8FD9\u91CC\u5728\u5BA2\u6237\u7AEF\u5B9E\u73B0\u4E00\u4EFD\u7B49\u4EF7\u7684\u8865\u5168\uFF1A\u547D\u4EE4\u4F4D\u7F6E\u8865 PATH \u4E2D\u7684\u53EF\u6267\u884C\u540D\uFF0C\u53C2\u6570\u4F4D\u7F6E\u8865\u6587\u4EF6\u8DEF\u5F84\u3002\n */\n\n/** \u53C2\u4E0E\u8865\u5168\u7684\u5185\u5EFA\u547D\u4EE4\uFF08\u4E0D\u5B58\u5728\u4E8E PATH\uFF09 */\nconst BUILTINS = [\n \"alias\",\n \"cd\",\n \"clear\",\n \"cls\",\n \"echo\",\n \"exit\",\n \"export\",\n \"false\",\n \"history\",\n \"pwd\",\n \"set\",\n \"source\",\n \"true\",\n \"type\",\n \"unalias\",\n \"unset\",\n \"which\",\n];\n\n/** PATH \u4E2D\u7684\u547D\u4EE4\u540D + \u5185\u5EFA\u547D\u4EE4\uFF08\u9996\u6B21\u626B\u63CF\u540E\u7F13\u5B58\uFF0C\u907F\u514D\u6BCF\u6B21 Tab \u90FD\u904D\u5386\u78C1\u76D8\uFF09 */\nlet commandCache: string[] | null = null;\n\nfunction allCommands(): string[] {\n if (commandCache) return commandCache;\n const names = new Set<string>(BUILTINS);\n for (const dir of (process.env.PATH ?? \"\").split(path.delimiter)) {\n if (!dir) continue;\n let entries: string[];\n try {\n entries = fs.readdirSync(dir);\n } catch {\n continue;\n }\n for (const name of entries) names.add(name);\n }\n commandCache = [...names].sort();\n return commandCache;\n}\n\nfunction commonPrefix(values: string[]): string {\n if (values.length === 0) return \"\";\n let prefix = values[0];\n for (const value of values.slice(1)) {\n let i = 0;\n while (i < prefix.length && i < value.length && prefix[i] === value[i]) i++;\n prefix = prefix.slice(0, i);\n if (!prefix) break;\n }\n return prefix;\n}\n\n/** \u628A\u7528\u6237\u8F93\u5165\u7684\u76EE\u5F55\u7247\u6BB5\uFF08\u53EF\u80FD\u662F\u76F8\u5BF9\u8DEF\u5F84 / \u7EDD\u5BF9\u8DEF\u5F84 / ~\uFF09\u89E3\u6790\u4E3A\u7EDD\u5BF9\u8DEF\u5F84 */\nfunction resolveDir(cwd: string, dirPart: string): string {\n if (!dirPart) return cwd;\n if (dirPart === \"~\" || dirPart.startsWith(\"~/\")) {\n return path.join(os.homedir(), dirPart.slice(1));\n }\n return path.isAbsolute(dirPart) ? dirPart : path.resolve(cwd, dirPart);\n}\n\ninterface PathScan {\n /** \u7528\u6237\u8F93\u5165\u4E2D\u300C\u76EE\u5F55\u90E8\u5206\u300D\uFF08\u4FDD\u7559\u539F\u6837\uFF0C\u7528\u4E8E\u56DE\u586B\uFF0C\u542B\u7ED3\u5C3E /\uFF09 */\n dirPart: string;\n /** \u5F85\u8865\u5168\u7684\u6587\u4EF6\u540D\u524D\u7F00 */\n base: string;\n /** \u5019\u9009\u6761\u76EE\uFF08\u76EE\u5F55\u4EE5 / \u7ED3\u5C3E\uFF09 */\n names: string[];\n}\n\n/** \u5224\u5B9A\u6761\u76EE\u662F\u5426\u4E3A\u76EE\u5F55\uFF1A\u7B26\u53F7\u94FE\u63A5\u8981\u89E3\u6790\u771F\u5B9E\u7C7B\u578B\uFF08Dirent.isDirectory() \u5BF9\u94FE\u63A5\u8FD4\u56DE false\uFF09 */\nfunction isDirectoryEntry(entry: fs.Dirent, dir: string): boolean {\n if (entry.isDirectory()) return true;\n if (!entry.isSymbolicLink()) return false;\n try {\n return fs.statSync(path.join(dir, entry.name)).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction scanPath(cwd: string, word: string, dirOnly: boolean): PathScan {\n const slash = word.lastIndexOf(\"/\");\n const dirPart = slash >= 0 ? word.slice(0, slash + 1) : \"\";\n const base = word.slice(slash + 1);\n\n const dir = resolveDir(cwd, dirPart);\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return { dirPart, base, names: [] };\n }\n\n const names = entries\n .filter((entry) => {\n if (dirOnly && !isDirectoryEntry(entry, dir)) return false;\n // \u9664\u975E\u7528\u6237\u663E\u5F0F\u8F93\u5165 . \u5F00\u5934\uFF0C\u5426\u5219\u4E0D\u63D0\u793A\u9690\u85CF\u9879\n if (entry.name.startsWith(\".\") && !base.startsWith(\".\")) return false;\n return entry.name.startsWith(base);\n })\n .map((entry) => entry.name + (isDirectoryEntry(entry, dir) ? \"/\" : \"\"))\n .sort();\n\n return { dirPart, base, names };\n}\n\nexport interface TermCompletion {\n /** \u8865\u5168\u540E\u7684\u6574\u884C\u8F93\u5165 */\n line: string;\n /** \u8865\u5168\u540E\u7684\u5149\u6807\u4F4D\u7F6E */\n cursor: number;\n /** \u4E0D\u4E3A\u7A7A\u65F6\u8868\u793A\u65E0\u6CD5\u7EE7\u7EED\u8865\u5168\uFF0C\u5E94\u628A\u8FD9\u4E9B\u5019\u9009\u5C55\u793A\u7ED9\u7528\u6237 */\n candidates: string[];\n}\n\n/**\n * \u8BA1\u7B97 Tab \u8865\u5168\u7ED3\u679C\u3002\n * - \u552F\u4E00\u5019\u9009\uFF1A\u76F4\u63A5\u8865\u5168\uFF08\u76EE\u5F55\u8865 `/`\uFF0C\u547D\u4EE4/\u6587\u4EF6\u540E\u8865\u7A7A\u683C\uFF09\n * - \u591A\u5019\u9009\uFF1A\u5148\u8865\u516C\u5171\u524D\u7F00\uFF1B\u82E5\u5DF2\u65E0\u6CD5\u6269\u5C55\u5219\u8FD4\u56DE\u5019\u9009\u5217\u8868\u4F9B\u5C55\u793A\n * - \u65E0\u5019\u9009\uFF1A\u8FD4\u56DE null\n */\nexport function completeTermInput(\n cwd: string,\n line: string,\n cursor: number,\n): TermCompletion | null {\n const rawBefore = line.slice(0, cursor);\n // \u5C3E\u90E8\u7A7A\u767D\uFF1A\u56DE\u9000\u5230\u4E0A\u4E00\u4E2A\u672A\u5B8C\u6210\u7684\u8BCD\uFF08\u4E0E shell \u7684 Tab \u884C\u4E3A\u4E00\u81F4\uFF0C\n // \u5426\u5219 `cat src/tui/ ` \u4F1A\u88AB\u5F53\u6210\"\u8865\u5168\u5F53\u524D\u76EE\u5F55\"\uFF09\n const before = rawBefore.replace(/\\s+$/, \"\");\n\n const wordStart = before.lastIndexOf(\" \") + 1;\n let word = before.slice(wordStart);\n const head = before.slice(0, wordStart);\n\n // `VAR=path` \u5F62\u5F0F\uFF1A\u53EA\u8865\u5168 `=` \u4E4B\u540E\u7684\u90E8\u5206\n let assignPrefix = \"\";\n const eq = word.lastIndexOf(\"=\");\n if (eq >= 0 && /^[A-Za-z_][A-Za-z0-9_]*$/.test(word.slice(0, eq))) {\n assignPrefix = word.slice(0, eq + 1);\n word = word.slice(eq + 1);\n }\n\n // \u5F15\u53F7\u5305\u88F9\u7684\u8DEF\u5F84\uFF08`cat \"src/tu`\uFF09\u2014\u2014 \u5265\u79BB\u5F15\u53F7\u53C2\u4E0E\u8865\u5168\uFF0C\u56DE\u586B\u65F6\u518D\u8865\u4E0A\n let quote = \"\";\n if (word.startsWith('\"') || word.startsWith(\"'\")) {\n quote = word[0];\n word = word.slice(1);\n }\n\n // \u663E\u5F0F\u8DEF\u5F84\uFF08./ ../ / ~ \u5F00\u5934\uFF09\u5373\u4F7F\u5728\u547D\u4EE4\u4F4D\u7F6E\u4E5F\u6309\u8DEF\u5F84\u8865\u5168\n const looksLikePath =\n word.startsWith(\"./\") ||\n word.startsWith(\"../\") ||\n word.startsWith(\"/\") ||\n word.startsWith(\"~\");\n const isCommand =\n head.trim().length === 0 && !looksLikePath && assignPrefix.length === 0;\n\n const wrap = (value: string): string => `${assignPrefix}${quote}${value}`;\n\n let dirPart = \"\";\n let names: string[];\n if (isCommand) {\n names = allCommands().filter((name) => name.startsWith(word));\n } else {\n // `cd` \u53EA\u8865\u76EE\u5F55\n const firstWord = head.trim().split(/\\s+/)[0] ?? \"\";\n const scan = scanPath(cwd, word, firstWord === \"cd\");\n dirPart = scan.dirPart;\n names = scan.names;\n }\n\n if (names.length === 0) return null;\n\n // \u552F\u4E00\u5019\u9009\uFF1A\u76F4\u63A5\u8865\u5168\n if (names.length === 1) {\n const completed = dirPart + names[0];\n const isDir = completed.endsWith(\"/\");\n const closed = quote && !isDir ? quote : \"\";\n const suffix = isDir ? \"\" : \" \";\n const nextBefore = head + wrap(completed) + closed + suffix;\n return {\n line: nextBefore + line.slice(cursor),\n cursor: nextBefore.length,\n candidates: [],\n };\n }\n\n // \u591A\u5019\u9009\uFF1A\u5C3D\u91CF\u8865\u516C\u5171\u524D\u7F00\n const base = isCommand ? word : word.slice(dirPart.length);\n const common = commonPrefix(names);\n if (common.length > base.length) {\n const nextBefore = head + wrap(dirPart + common);\n return {\n line: nextBefore + line.slice(cursor),\n cursor: nextBefore.length,\n candidates: [],\n };\n }\n\n // \u5DF2\u65E0\u6CD5\u7EE7\u7EED\u8865\u5168\uFF1A\u5C55\u793A\u5019\u9009\n return {\n line,\n cursor,\n candidates: names.map((name) => wrap(dirPart + name)),\n };\n}\n", "import { spawnSync } from \"child_process\";\nimport * as fs from \"fs\";\nimport {\n configExists,\n DEFAULT_CONFIG,\n loadConfig,\n redactConfig,\n saveConfig,\n} from \"../../config/store\";\nimport { ansi } from \"../../utils/ansi\";\nimport { ensureDir, getConfigDir, getConfigPath } from \"../../utils/paths\";\n\n/**\n * `xzh config` \u67E5\u770B\u914D\u7F6E\uFF08\u8131\u654F\uFF09\n * `xzh config edit` \u4F7F\u7528 nano \u7F16\u8F91\u914D\u7F6E\u6587\u4EF6\n * `xzh config path` \u6253\u5370\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84\n * `xzh config init` \u751F\u6210\u9ED8\u8BA4\u914D\u7F6E\u6587\u4EF6\n */\nexport async function configCommand(args: string[]): Promise<void> {\n const sub = args[0];\n\n switch (sub) {\n case \"edit\":\n return openInEditor();\n case \"path\":\n process.stdout.write(`${getConfigPath()}\\n`);\n return;\n case \"init\": {\n ensureDir(getConfigDir());\n if (configExists()) {\n process.stdout.write(\n `${ansi.yellow}\u914D\u7F6E\u6587\u4EF6\u5DF2\u5B58\u5728\uFF1A${getConfigPath()}${ansi.reset}\\n`,\n );\n return;\n }\n saveConfig({ ...DEFAULT_CONFIG });\n process.stdout.write(`${ansi.green}\u2713 \u5DF2\u751F\u6210\u9ED8\u8BA4\u914D\u7F6E\uFF1A${getConfigPath()}${ansi.reset}\\n`);\n return;\n }\n case undefined:\n return showConfig();\n default:\n process.stdout.write(\n `${ansi.red}\u672A\u77E5\u5B50\u547D\u4EE4\uFF1A${sub}${ansi.reset}\\n` +\n `${ansi.gray}\u7528\u6CD5\uFF1Axzh config [edit|path|init]${ansi.reset}\\n`,\n );\n process.exitCode = 1;\n return;\n }\n}\n\nfunction showConfig(): void {\n if (!configExists()) {\n process.stdout.write(\n `${ansi.yellow}\u5C1A\u672A\u521B\u5EFA\u914D\u7F6E\u6587\u4EF6\u3002${ansi.reset}\\n` +\n `${ansi.gray}\u8FD0\u884C ${ansi.reset}xzh model${ansi.gray} \u8FDB\u884C\u914D\u7F6E\uFF0C\u6216\u8FD0\u884C ${ansi.reset}xzh config init${ansi.gray} \u751F\u6210\u9ED8\u8BA4\u914D\u7F6E\u3002${ansi.reset}\\n`,\n );\n return;\n }\n const config = loadConfig();\n const redacted = redactConfig(config);\n process.stdout.write(`${ansi.bold}\u7384\u732A\u914D\u7F6E${ansi.reset} ${ansi.gray}(${getConfigPath()})${ansi.reset}\\n\\n`);\n process.stdout.write(JSON.stringify(redacted, null, 2) + \"\\n\");\n process.stdout.write(\n `\\n${ansi.gray}\u63D0\u793A\uFF1AAPI Key \u5DF2\u8131\u654F\u663E\u793A\uFF1B\u4F7F\u7528 ${ansi.reset}xzh config edit${ansi.gray} \u7F16\u8F91\u5B8C\u6574\u914D\u7F6E\u3002${ansi.reset}\\n`,\n );\n}\n\nfunction openInEditor(): void {\n ensureDir(getConfigDir());\n const file = getConfigPath();\n if (!fs.existsSync(file)) {\n saveConfig({ ...DEFAULT_CONFIG });\n }\n\n // \u4F18\u5148\u4F7F\u7528 nano\uFF08\u7528\u6237\u65E2\u5B9A\u7EA6\u5B9A\uFF09\uFF0C\u5176\u6B21 EDITOR / vi\n const candidates = [\n process.env.XUANZHU_EDITOR,\n \"nano\",\n process.env.EDITOR,\n \"vi\",\n \"vim\",\n \"code --wait\",\n ].filter((value): value is string => Boolean(value));\n\n for (const candidate of candidates) {\n const [command, ...rest] = candidate.split(\" \");\n const result = spawnSync(command, [...rest, file], { stdio: \"inherit\" });\n if (result.error) {\n const code = (result.error as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\") continue;\n process.stdout.write(\n `${ansi.red}\u7F16\u8F91\u5668\u542F\u52A8\u5931\u8D25\uFF1A${result.error.message}${ansi.reset}\\n`,\n );\n return;\n }\n return;\n }\n\n process.stdout.write(\n `${ansi.yellow}\u672A\u627E\u5230\u53EF\u7528\u7684\u6587\u672C\u7F16\u8F91\u5668\uFF0C\u8BF7\u624B\u52A8\u7F16\u8F91\uFF1A${file}${ansi.reset}\\n`,\n );\n}\n", "import * as readline from \"readline/promises\";\nimport { ansi } from \"../utils/ansi\";\n\nexport interface SelectOption<T> {\n label: string;\n value: T;\n hint?: string;\n}\n\n/** \u8BFB\u53D6\u4E00\u884C\u6587\u672C\u8F93\u5165 */\nexport async function promptInput(\n label: string,\n defaultValue?: string,\n): Promise<string> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n try {\n const suffix = defaultValue ? ` ${ansi.gray}(${defaultValue})${ansi.reset}` : \"\";\n // \u975E\u4EA4\u4E92\u73AF\u5883\uFF08stdin \u63D0\u524D\u7ED3\u675F\uFF09\u65F6\u56DE\u843D\u4E3A\u9ED8\u8BA4\u503C\uFF0C\u907F\u514D\u9759\u9ED8\u6302\u8D77\n const answer = await Promise.race([\n rl.question(`${label}${suffix}: `),\n new Promise<string>((resolve) => rl.once(\"close\", () => resolve(\"\"))),\n ]);\n const trimmed = answer.trim();\n return trimmed || defaultValue || \"\";\n } finally {\n rl.close();\n }\n}\n\n/** \u4ECE\u5217\u8868\u4E2D\u9009\u62E9\u4E00\u9879\uFF08\u8F93\u5165\u7F16\u53F7\uFF09 */\nexport async function promptSelect<T>(\n label: string,\n options: SelectOption<T>[],\n defaultIndex = 0,\n): Promise<T> {\n process.stdout.write(`\\n${ansi.bold}${label}${ansi.reset}\\n`);\n options.forEach((option, index) => {\n const marker = index === defaultIndex ? `${ansi.brightGreen}\u276F${ansi.reset}` : \" \";\n const hint = option.hint ? ` ${ansi.gray}${option.hint}${ansi.reset}` : \"\";\n process.stdout.write(` ${marker} ${index + 1}. ${option.label}${hint}\\n`);\n });\n\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n try {\n const answer = await rl.question(\n `${ansi.gray}\u8BF7\u8F93\u5165\u7F16\u53F7 [${defaultIndex + 1}]: ${ansi.reset}`,\n );\n const trimmed = answer.trim();\n if (!trimmed) return options[defaultIndex].value;\n const index = Number.parseInt(trimmed, 10) - 1;\n if (Number.isNaN(index) || index < 0 || index >= options.length) {\n process.stdout.write(`${ansi.yellow}\u65E0\u6548\u7F16\u53F7\uFF0C\u4F7F\u7528\u9ED8\u8BA4\u9009\u9879\u3002${ansi.reset}\\n`);\n return options[defaultIndex].value;\n }\n return options[index].value;\n } finally {\n rl.close();\n }\n}\n\n/** \u8BE2\u95EE\u662F\u5426\uFF08y/N\uFF09 */\nexport async function promptConfirm(\n label: string,\n defaultValue = false,\n): Promise<boolean> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n try {\n const hint = defaultValue ? \"[Y/n]\" : \"[y/N]\";\n const answer = await rl.question(`${label} ${hint} `);\n const trimmed = answer.trim().toLowerCase();\n if (!trimmed) return defaultValue;\n return trimmed === \"y\" || trimmed === \"yes\";\n } finally {\n rl.close();\n }\n}\n", "import {\n DEFAULT_MODEL_WEIGHT,\n effectiveModels,\n loadConfig,\n materializeModels,\n modelId,\n pickModel,\n removeModel,\n resetModelWeights,\n saveConfig,\n setModelWeight,\n upsertModel,\n type ModelEntry,\n type XuanZhuConfig,\n} from \"../../config/store\";\nimport { findProvider, PROVIDERS, resolveApiKey } from \"../../llm\";\nimport { ansi } from \"../../utils/ansi\";\nimport { getConfigPath } from \"../../utils/paths\";\nimport { promptInput, promptSelect } from \"../prompt\";\n\n/**\n * `xzh model` \u4EA4\u4E92\u5F0F\u7BA1\u7406\u591A\u4E2A\u6A21\u578B\uFF08\u65B0\u589E / \u5220\u9664 / \u8C03\u6574\u6743\u91CD / \u67E5\u770B\u5168\u90E8\uFF09\n * `xzh model list` \u5217\u51FA**\u5DF2\u914D\u7F6E**\u7684\u6A21\u578B\u4E0E\u6743\u91CD\n * `xzh model all` \u5217\u51FA**\u6240\u6709\u5185\u7F6E\u53EF\u7528**\u7684\u6A21\u578B\uFF08\u6309\u670D\u52A1\u5546\u5206\u7EC4\uFF09\n * `xzh model add <provider> <model> [\u6743\u91CD]`\n * `xzh model remove <id|\u5E8F\u53F7>` \u5220\u9664\u6A21\u578B\n * `xzh model weight <id|\u5E8F\u53F7> <\u6743\u91CD>`\n *\n * \u517C\u5BB9\u65E7\u7528\u6CD5\uFF1A`xzh model <provider> [model]` \u7B49\u4EF7\u4E8E `add`\u3002\n */\nexport async function modelCommand(args: string[]): Promise<void> {\n const sub = args[0];\n\n switch (sub) {\n case undefined:\n return interactiveMenu();\n case \"list\":\n case \"ls\":\n return listModels();\n case \"all\":\n case \"available\":\n case \"providers\":\n return listAvailableModels();\n case \"add\":\n return addModel(args.slice(1));\n case \"remove\":\n case \"rm\":\n case \"delete\":\n return removeModelCommand(args.slice(1));\n case \"weight\":\n case \"w\":\n return setWeightCommand(args.slice(1));\n case \"reset\":\n return resetWeights();\n case \"help\":\n case \"-h\":\n case \"--help\":\n return printModelHelp();\n default:\n // \u65E7\u7528\u6CD5\uFF1Axzh model <provider> [model]\n return addModel(args);\n }\n}\n\n// ------------------------------------------------------------------ \u5B50\u547D\u4EE4\n\n/** \u65B0\u589E\u6A21\u578B\uFF08provider / model \u7F3A\u7701\u65F6\u4EA4\u4E92\u9009\u62E9\uFF09 */\nasync function addModel(args: string[]): Promise<void> {\n const config = loadConfig();\n // \u5148\u7269\u5316\u6A21\u578B\u5217\u8868\uFF1A\u4E0B\u9762\u4F1A\u6539\u5199 config.provider / config.model\uFF0C\n // \u82E5\u4E0D\u5148\u56FA\u5B9A\uFF0C\u517C\u5BB9\u56DE\u9000\u4F1A\u628A\u300C\u65B0\u6A21\u578B\u540D\u300D\u5F53\u6210\u5DF2\u6709\u5217\u8868\uFF0C\u5BFC\u81F4\u65E7\u6A21\u578B\u88AB\u8986\u76D6\u4E22\u5931\u3002\n const existingModels = materializeModels(config);\n\n const providerId = args[0] ?? (await chooseProvider());\n const meta = findProvider(providerId);\n if (!meta) {\n process.stdout.write(\n `${ansi.red}\u672A\u77E5\u7684 provider\uFF1A${providerId}${ansi.reset}\\n` +\n `${ansi.gray}\u53EF\u7528\uFF1A${PROVIDERS.map((p) => p.id).join(\", \")}${ansi.reset}\\n`,\n );\n process.exitCode = 1;\n return;\n }\n\n const model = args[1] ?? (await chooseModel(meta.id, meta.models, config));\n const weightText = args[2];\n let weight: number | undefined;\n if (weightText !== undefined) {\n // \u4E25\u683C\u89E3\u6790\uFF1A`parseInt(\"5abc\")` \u4F1A\u5F97\u5230 5\uFF0C\u9759\u9ED8\u63A5\u53D7\u660E\u663E\u9519\u8BEF\u7684\u8F93\u5165\n const parsed = /^\\d+$/.test(weightText.trim())\n ? Number.parseInt(weightText.trim(), 10)\n : Number.NaN;\n if (Number.isNaN(parsed) || parsed < 0) {\n process.stdout.write(\n `${ansi.red}\u6743\u91CD\u5FC5\u987B\u662F \u2265 0 \u7684\u6574\u6570\uFF1A${weightText}${ansi.reset}\\n`,\n );\n process.exitCode = 1;\n return;\n }\n weight = parsed;\n }\n\n const baseUrl = await chooseBaseUrl(meta.id, meta.requiresBaseUrl === true, config);\n const apiKey = await chooseApiKey(meta.id, meta.envKey, config);\n\n // provider \u7EA7\u8BBE\u7F6E\uFF08API Key / baseUrl / \u6700\u8FD1\u4F7F\u7528\u7684 model\uFF09\n config.providers = {\n ...config.providers,\n [meta.id]: {\n ...(config.providers[meta.id] ?? {}),\n model,\n ...(baseUrl ? { baseUrl } : {}),\n ...(apiKey ? { apiKey } : {}),\n },\n };\n config.provider = meta.id;\n config.model = model;\n\n const existed = existingModels.some(\n (entry) => entry.id === modelId(meta.id, model),\n );\n const entry = upsertModel(config, {\n provider: meta.id,\n model,\n weight,\n ...(baseUrl ? { baseUrl } : {}),\n ...(apiKey ? { apiKey } : {}),\n });\n\n saveConfig(config);\n\n process.stdout.write(\n `\\n${ansi.green}\u2713 ${existed ? \"\u5DF2\u66F4\u65B0\" : \"\u5DF2\u65B0\u589E\"}\u6A21\u578B${ansi.reset} ${ansi.bold}${entry.id}${ansi.reset}\\n` +\n ` ${ansi.gray}provider\uFF1A${ansi.reset}${meta.label}\\n` +\n ` ${ansi.gray}model \uFF1A${ansi.reset}${entry.model}\\n` +\n ` ${ansi.gray}\u6743\u91CD \uFF1A${ansi.reset}${entry.weight}\\n` +\n (baseUrl ? ` ${ansi.gray}baseUrl \uFF1A${ansi.reset}${baseUrl}\\n` : \"\") +\n ` ${ansi.gray}\u914D\u7F6E\u6587\u4EF6\uFF1A${ansi.reset}${getConfigPath()}\\n`,\n );\n printActiveHint(config);\n}\n\n/** \u5220\u9664\u6A21\u578B */\nasync function removeModelCommand(args: string[]): Promise<void> {\n const config = loadConfig();\n const models = effectiveModels(config);\n if (models.length === 0) {\n process.stdout.write(`${ansi.yellow}\u5C1A\u672A\u914D\u7F6E\u4EFB\u4F55\u6A21\u578B\u3002${ansi.reset}\\n`);\n return;\n }\n\n const key = args[0] ?? (await chooseFromList(models, \"\u9009\u62E9\u8981\u5220\u9664\u7684\u6A21\u578B\uFF1A\"));\n const id = resolveModelKey(config, key);\n const removed = id ? removeModel(config, id) : null;\n if (!removed) {\n process.stdout.write(\n `${ansi.red}\u672A\u627E\u5230\u6A21\u578B\uFF1A${key}${ansi.reset}\\n` +\n `${ansi.gray}\u63D0\u793A\uFF1A\u53EF\u4F7F\u7528 ${ansi.reset}xzh model list${ansi.gray} \u67E5\u770B id \u4E0E\u5E8F\u53F7\u3002${ansi.reset}\\n`,\n );\n process.exitCode = 1;\n return;\n }\n\n syncActiveFields(config);\n saveConfig(config);\n\n process.stdout.write(\n `\\n${ansi.green}\u2713 \u5DF2\u5220\u9664\u6A21\u578B${ansi.reset} ${removed.id}\\n`,\n );\n printActiveHint(config);\n}\n\n/** \u8C03\u6574\u6A21\u578B\u6743\u91CD */\nasync function setWeightCommand(args: string[]): Promise<void> {\n const config = loadConfig();\n let models = effectiveModels(config);\n if (models.length === 0) {\n process.stdout.write(`${ansi.yellow}\u5C1A\u672A\u914D\u7F6E\u4EFB\u4F55\u6A21\u578B\u3002${ansi.reset}\\n`);\n return;\n }\n\n const key = args[0] ?? (await chooseFromList(models, \"\u9009\u62E9\u8981\u8C03\u6574\u6743\u91CD\u7684\u6A21\u578B\uFF1A\"));\n const id = resolveModelKey(config, key);\n const target = id ? models.find((entry) => entry.id === id) : undefined;\n if (!target) {\n process.stdout.write(\n `${ansi.red}\u672A\u627E\u5230\u6A21\u578B\uFF1A${key}${ansi.reset}\\n` +\n `${ansi.gray}\u63D0\u793A\uFF1A\u53EF\u4F7F\u7528 ${ansi.reset}xzh model list${ansi.gray} \u67E5\u770B id \u4E0E\u5E8F\u53F7\u3002${ansi.reset}\\n`,\n );\n process.exitCode = 1;\n return;\n }\n\n const input =\n args[1] ??\n (await promptInput(\n `\u8BF7\u8F93\u5165 ${target.id} \u7684\u65B0\u6743\u91CD\uFF080 \u8868\u793A\u6682\u4E0D\u4F7F\u7528\uFF09`,\n String(target.weight),\n ));\n const weight = Number.parseInt(input, 10);\n if (Number.isNaN(weight) || weight < 0) {\n process.stdout.write(\n `${ansi.red}\u6743\u91CD\u5FC5\u987B\u662F \u2265 0 \u7684\u6574\u6570\uFF1A${input}${ansi.reset}\\n`,\n );\n process.exitCode = 1;\n return;\n }\n\n const updated = setModelWeight(config, target.id, weight);\n if (!updated) {\n process.stdout.write(`${ansi.red}\u8BBE\u7F6E\u5931\u8D25\uFF1A${target.id}${ansi.reset}\\n`);\n process.exitCode = 1;\n return;\n }\n\n syncActiveFields(config);\n saveConfig(config);\n\n process.stdout.write(\n `\\n${ansi.green}\u2713 \u5DF2\u66F4\u65B0\u6743\u91CD${ansi.reset} ${updated.id} \u2192 ${updated.weight}\\n`,\n );\n printActiveHint(config);\n}\n\n/** \u628A\u5168\u90E8\u6A21\u578B\u6743\u91CD\u6062\u590D\u4E3A\u9ED8\u8BA4\u503C */\nfunction resetWeights(): void {\n const config = loadConfig();\n const models = effectiveModels(config);\n if (models.length === 0) {\n process.stdout.write(`${ansi.yellow}\u5C1A\u672A\u914D\u7F6E\u4EFB\u4F55\u6A21\u578B\u3002${ansi.reset}\\n`);\n return;\n }\n resetModelWeights(config);\n syncActiveFields(config);\n saveConfig(config);\n process.stdout.write(\n `${ansi.green}\u2713 \u5DF2\u628A ${models.length} \u4E2A\u6A21\u578B\u7684\u6743\u91CD\u91CD\u7F6E\u4E3A ${DEFAULT_MODEL_WEIGHT}\u3002${ansi.reset}\\n`,\n );\n}\n\n/** \u6253\u5370\u5DF2\u914D\u7F6E\u7684\u6A21\u578B\u5217\u8868 */\nfunction listModels(): void {\n const config = loadConfig();\n printModelTable(config);\n}\n\n/** \u6253\u5370\u6240\u6709\u5185\u7F6E\u53EF\u7528\u7684\u6A21\u578B\uFF08\u6309\u670D\u52A1\u5546\u5206\u7EC4\uFF09\uFF0C\u5E76\u6807\u6CE8\u54EA\u4E9B\u5DF2\u52A0\u5165\u914D\u7F6E */\nfunction listAvailableModels(): void {\n const config = loadConfig();\n const configured = new Set(effectiveModels(config).map((entry) => entry.id));\n const total = PROVIDERS.reduce((sum, provider) => sum + provider.models.length, 0);\n\n process.stdout.write(\n `\\n${ansi.bold}\u6240\u6709\u53EF\u7528\u6A21\u578B${ansi.reset}` +\n `${ansi.gray}\uFF08${PROVIDERS.length} \u4E2A\u670D\u52A1\u5546\uFF0C\u5171 ${total} \u4E2A\u5185\u7F6E\u6A21\u578B\uFF09${ansi.reset}\\n`,\n );\n\n for (const provider of PROVIDERS) {\n const hasKey =\n config.providers[provider.id] !== undefined\n ? ` ${ansi.gray}\u00B7 \u5DF2\u586B\u5199 Key${ansi.reset}`\n : \"\";\n process.stdout.write(\n `\\n ${ansi.bold}${provider.label}${ansi.reset} ` +\n `${ansi.gray}(${provider.id})${ansi.reset}${hasKey}\\n`,\n );\n\n if (provider.models.length === 0) {\n process.stdout.write(\n ` ${ansi.gray}\u65E0\u5185\u7F6E\u5217\u8868\uFF0C\u9700\u624B\u52A8\u8F93\u5165\u6A21\u578B\u540D` +\n `${provider.requiresBaseUrl ? \"\uFF08\u81EA\u5B9A\u4E49\u7AEF\u70B9\uFF09\" : \"\"}${ansi.reset}\\n`,\n );\n continue;\n }\n\n for (const model of provider.models) {\n const id = modelId(provider.id, model);\n const isConfigured = configured.has(id);\n const marker = isConfigured ? `${ansi.brightGreen}\u276F${ansi.reset}` : \" \";\n const tags: string[] = [];\n if (model === provider.defaultModel) tags.push(\"\u9ED8\u8BA4\");\n if (isConfigured) tags.push(\"\u5DF2\u914D\u7F6E\");\n const suffix =\n tags.length > 0 ? ` ${ansi.gray}\u2190 ${tags.join(\" \u00B7 \")}${ansi.reset}` : \"\";\n process.stdout.write(` ${marker} ${model}${suffix}\\n`);\n }\n }\n\n // \u5DF2\u914D\u7F6E\u3001\u4F46\u4E0D\u5728\u4EFB\u4F55\u5185\u7F6E\u5217\u8868\u91CC\u7684\u6A21\u578B\uFF08\u5178\u578B\u662F\u81EA\u5B9A\u4E49\u7AEF\u70B9\uFF09\uFF0C\n // \u5355\u72EC\u5217\u51FA\u6765\uFF0C\u907F\u514D\u300C\u660E\u660E\u914D\u7F6E\u8FC7\u5374\u5728\u8FD9\u91CC\u770B\u4E0D\u5230\u300D\u3002\n const listedIds = new Set(\n PROVIDERS.flatMap((provider) =>\n provider.models.map((model) => modelId(provider.id, model)),\n ),\n );\n const extra = effectiveModels(config).filter(\n (entry) => !listedIds.has(entry.id),\n );\n if (extra.length > 0) {\n process.stdout.write(\n `\\n ${ansi.bold}\u5DF2\u914D\u7F6E\u7684\u81EA\u5B9A\u4E49\u6A21\u578B${ansi.reset}` +\n `${ansi.gray}\uFF08\u4E0D\u5728\u4E0A\u9762\u7684\u5185\u7F6E\u5217\u8868\u4E2D\uFF09${ansi.reset}\\n`,\n );\n for (const entry of extra) {\n process.stdout.write(\n ` ${ansi.brightGreen}\u276F${ansi.reset} ${entry.id} ` +\n `${ansi.gray}\u2190 \u6743\u91CD ${entry.weight}${ansi.reset}\\n`,\n );\n }\n }\n\n process.stdout.write(\n `\\n${ansi.gray}\u276F \u8868\u793A\u5DF2\u52A0\u5165\u914D\u7F6E\u3002\u6DFB\u52A0\u6A21\u578B\uFF1A${ansi.reset}` +\n `${ansi.brightGreen}xzh model add <provider> <model>${ansi.reset}\\n` +\n `${ansi.gray}\u67E5\u770B\u5DF2\u914D\u7F6E\u7684\u6A21\u578B\u4E0E\u6743\u91CD\uFF1A${ansi.reset}xzh model list\\n`,\n );\n}\n\n// ------------------------------------------------------------------ \u4EA4\u4E92\u83DC\u5355\n\nasync function interactiveMenu(): Promise<void> {\n for (;;) {\n const config = loadConfig();\n printModelTable(config);\n\n const action = await promptSelect(\n \"\u8BF7\u9009\u62E9\u64CD\u4F5C\uFF1A\",\n [\n { label: \"\u65B0\u589E\u6A21\u578B\", value: \"add\", hint: \"add\" },\n { label: \"\u67E5\u770B\u6240\u6709\u53EF\u7528\u6A21\u578B\", value: \"all\", hint: \"all\" },\n { label: \"\u5220\u9664\u6A21\u578B\", value: \"remove\", hint: \"remove\" },\n { label: \"\u8C03\u6574\u8C03\u7528\u6743\u91CD\", value: \"weight\", hint: \"weight\" },\n {\n label: `\u6062\u590D\u5168\u90E8\u6743\u91CD\u4E3A ${DEFAULT_MODEL_WEIGHT}`,\n value: \"reset\",\n hint: \"reset\",\n },\n { label: \"\u9000\u51FA\", value: \"exit\" },\n ],\n 0,\n );\n\n switch (action) {\n case \"add\":\n await addModel([]);\n break;\n case \"all\":\n listAvailableModels();\n break;\n case \"remove\":\n await removeModelCommand([]);\n break;\n case \"weight\":\n await setWeightCommand([]);\n break;\n case \"reset\":\n resetWeights();\n break;\n default:\n process.stdout.write(`\\n${ansi.gray}\u5DF2\u9000\u51FA\u6A21\u578B\u7BA1\u7406\u3002${ansi.reset}\\n`);\n return;\n }\n }\n}\n\n// ------------------------------------------------------------------ \u5C55\u793A\n\nfunction printModelTable(config: XuanZhuConfig): void {\n const models = effectiveModels(config);\n const active = pickModel(config);\n\n process.stdout.write(\n `\\n${ansi.bold}\u7384\u732A\u6A21\u578B\u5217\u8868${ansi.reset} ${ansi.gray}(${getConfigPath()})${ansi.reset}\\n`,\n );\n\n if (models.length === 0) {\n process.stdout.write(\n ` ${ansi.yellow}\u5C1A\u672A\u914D\u7F6E\u4EFB\u4F55\u6A21\u578B\u3002${ansi.reset}\\n` +\n ` ${ansi.gray}\u8FD0\u884C ${ansi.reset}xzh model add <provider> <model>${ansi.gray} \u6DFB\u52A0\u3002${ansi.reset}\\n`,\n );\n return;\n }\n\n const sorted = models.slice().sort((a, b) => b.weight - a.weight);\n sorted.forEach((entry, index) => {\n const isActive = active !== null && entry.id === active.id;\n const marker = isActive ? `${ansi.brightGreen}\u276F${ansi.reset}` : \" \";\n const weightColor =\n entry.weight <= 0\n ? ansi.red\n : entry.weight < DEFAULT_MODEL_WEIGHT\n ? ansi.yellow\n : ansi.green;\n const suffix = isActive ? ` ${ansi.gray}\u2190 \u5F53\u524D\u4F7F\u7528${ansi.reset}` : \"\";\n process.stdout.write(\n ` ${marker} ${index + 1}. ${entry.id.padEnd(36)} ${ansi.gray}\u6743\u91CD${ansi.reset} ${weightColor}${String(entry.weight).padStart(3)}${ansi.reset}${suffix}\\n`,\n );\n });\n\n process.stdout.write(\n `${ansi.gray} \u6743\u91CD\u8D8A\u9AD8\u8D8A\u4F18\u5148\uFF1B\u8C03\u7528\u5931\u8D25 -1\uFF0C\u5168\u90E8\u4E3A 0 \u65F6\u81EA\u52A8\u91CD\u7F6E\u4E3A ${DEFAULT_MODEL_WEIGHT}\u3002${ansi.reset}\\n`,\n );\n}\n\nfunction printActiveHint(config: XuanZhuConfig): void {\n const active = pickModel(config);\n if (active) {\n process.stdout.write(\n `${ansi.gray}\u4E0B\u6B21\u542F\u52A8\u5C06\u4F7F\u7528\u6743\u91CD\u6700\u9AD8\u7684\u6A21\u578B\uFF1A${ansi.reset}${ansi.bold}${active.id}${ansi.reset} ${ansi.gray}(\u6743\u91CD ${active.weight})${ansi.reset}\\n`,\n );\n } else {\n process.stdout.write(\n `${ansi.yellow}\u26A0 \u5F53\u524D\u6240\u6709\u6A21\u578B\u6743\u91CD\u5747\u4E3A 0\uFF0C\u4E0B\u6B21\u542F\u52A8\u4F1A\u81EA\u52A8\u91CD\u7F6E\u4E3A ${DEFAULT_MODEL_WEIGHT}\u3002${ansi.reset}\\n`,\n );\n }\n process.stdout.write(`\\n\u8FD0\u884C ${ansi.brightGreen}xzh${ansi.reset} \u5F00\u59CB\u4F7F\u7528\u3002\\n`);\n}\n\nfunction printModelHelp(): void {\n process.stdout.write(\n `\\n${ansi.bold}xzh model \u2014\u2014 \u591A\u6A21\u578B\u7BA1\u7406${ansi.reset}\\n` +\n ` ${ansi.green}xzh model${ansi.reset} \u4EA4\u4E92\u5F0F\u83DC\u5355\\n` +\n ` ${ansi.green}xzh model list${ansi.reset} \u5217\u51FA\u5DF2\u914D\u7F6E\u7684\u6A21\u578B\u4E0E\u6743\u91CD\\n` +\n ` ${ansi.green}xzh model all${ansi.reset} \u5217\u51FA\u6240\u6709\u5185\u7F6E\u53EF\u7528\u6A21\u578B\\n` +\n ` ${ansi.green}xzh model add <provider> <model> [\u6743\u91CD]${ansi.reset} \u65B0\u589E\u6A21\u578B\uFF08\u9ED8\u8BA4\u6743\u91CD ${DEFAULT_MODEL_WEIGHT}\uFF09\\n` +\n ` ${ansi.green}xzh model remove <id|\u5E8F\u53F7>${ansi.reset} \u5220\u9664\u6A21\u578B\\n` +\n ` ${ansi.green}xzh model weight <id|\u5E8F\u53F7> <\u6743\u91CD>${ansi.reset} \u8C03\u6574\u6743\u91CD\\n` +\n ` ${ansi.green}xzh model reset${ansi.reset} \u6062\u590D\u5168\u90E8\u6743\u91CD\u4E3A ${DEFAULT_MODEL_WEIGHT}\\n\\n` +\n `${ansi.bold}\u6743\u91CD\u673A\u5236${ansi.reset}\\n` +\n ` \u542F\u52A8\u65F6\u4F18\u5148\u52A0\u8F7D\u6743\u91CD\u6700\u9AD8\u7684\u6A21\u578B\uFF1B\u8C03\u7528\u5931\u8D25\u65F6\u8BE5\u6A21\u578B\u6743\u91CD -1\uFF0C\u5E76\u81EA\u52A8\u5207\u6362\u5230\u4E0B\u4E00\u4E2A\u53EF\u7528\u6A21\u578B\uFF1B\\n` +\n ` \u5F53\u6240\u6709\u6A21\u578B\u6743\u91CD\u90FD\u4E3A 0 \u65F6\uFF0C\u4F1A\u5728\u7EC8\u7AEF\u8B66\u544A\u5E76\u628A\u5168\u90E8\u6743\u91CD\u91CD\u7F6E\u4E3A ${DEFAULT_MODEL_WEIGHT}\u3002\\n\\n` +\n `${ansi.gray}\u53EF\u7528 provider\uFF1A${PROVIDERS.map((p) => p.id).join(\", \")}${ansi.reset}\\n`,\n );\n}\n\n// ------------------------------------------------------------------ \u4EA4\u4E92\u9009\u62E9\n\n/** \u628A\u5F53\u524D\u751F\u6548\u7684\u6A21\u578B\u540C\u6B65\u56DE config.provider / config.model\uFF08\u4F9B\u5355\u6A21\u578B\u517C\u5BB9\u8DEF\u5F84\u4F7F\u7528\uFF09 */\nfunction syncActiveFields(config: XuanZhuConfig): void {\n const active = pickModel(config) ?? effectiveModels(config)[0];\n if (active) {\n config.provider = active.provider;\n config.model = active.model;\n return;\n }\n // \u5DF2\u65E0\u4EFB\u4F55\u6A21\u578B\uFF1A\u6E05\u7A7A\u517C\u5BB9\u5B57\u6BB5\uFF0C\u5426\u5219 effectiveModels \u4F1A\u56DE\u9000\u5230\u521A\u88AB\u5220\u9664\u7684\u6A21\u578B\n config.provider = \"\";\n config.model = \"\";\n}\n\nasync function chooseProvider(): Promise<string> {\n return promptSelect(\n \"\u9009\u62E9 AI \u670D\u52A1\u5546\uFF1A\",\n PROVIDERS.map((provider) => ({\n label: provider.label,\n value: provider.id,\n hint: provider.id,\n })),\n 0,\n );\n}\n\nasync function chooseModel(\n providerId: string,\n models: string[],\n config: XuanZhuConfig,\n): Promise<string> {\n const current = config.providers[providerId]?.model;\n if (models.length > 0) {\n const options = [\n ...models.map((model) => ({ label: model, value: model })),\n { label: \"\u624B\u52A8\u8F93\u5165\u6A21\u578B\u540D\", value: \"__custom__\" },\n ];\n const defaultIndex = current ? Math.max(0, models.indexOf(current)) : 0;\n const selected = await promptSelect(\n `\u9009\u62E9\u6A21\u578B\uFF08${providerId}\uFF09\uFF1A`,\n options,\n defaultIndex,\n );\n if (selected !== \"__custom__\") return selected;\n }\n const input = await promptInput(\"\u8BF7\u8F93\u5165\u6A21\u578B\u540D\u79F0\", current);\n return input;\n}\n\nasync function chooseBaseUrl(\n providerId: string,\n required: boolean,\n config: XuanZhuConfig,\n): Promise<string> {\n const current = config.providers[providerId]?.baseUrl;\n if (!required) return current ?? \"\";\n const input = await promptInput(\"\u8BF7\u8F93\u5165 API \u7AEF\u70B9 baseUrl\", current);\n return input;\n}\n\nasync function chooseApiKey(\n providerId: string,\n envKey: string,\n config: XuanZhuConfig,\n): Promise<string> {\n const meta = findProvider(providerId);\n const existing = config.providers[providerId]?.apiKey;\n if (!meta?.requiresApiKey) {\n return existing ?? \"\";\n }\n if (resolveApiKey(meta, existing)) {\n process.stdout.write(\n `${ansi.gray}\u5DF2\u68C0\u6D4B\u5230 API Key\uFF08${envKey} \u6216\u914D\u7F6E\u4E2D\uFF09\uFF0C\u76F4\u63A5\u56DE\u8F66\u4FDD\u7559\u3002${ansi.reset}\\n`,\n );\n }\n const input = await promptInput(\"\u8BF7\u8F93\u5165 API Key\", existing ?? \"\");\n return input;\n}\n\n/**\n * \u628A\u7528\u6237\u8F93\u5165\uFF08id / \u6A21\u578B\u540D / \u5E8F\u53F7\uFF09\u89E3\u6790\u4E3A\u6A21\u578B id\u3002\n * \u5E8F\u53F7\u7684\u987A\u5E8F\u4E0E `xzh model list` \u7684\u5C55\u793A\u4FDD\u6301\u4E00\u81F4\uFF08\u6309\u6743\u91CD\u964D\u5E8F\uFF09\u3002\n */\nfunction resolveModelKey(config: XuanZhuConfig, key: string): string | null {\n const models = effectiveModels(config);\n const byId = models.find((entry) => entry.id === key);\n if (byId) return byId.id;\n const byModel = models.find((entry) => entry.model === key);\n if (byModel) return byModel.id;\n if (/^\\d+$/.test(key.trim())) {\n const sorted = models.slice().sort((a, b) => b.weight - a.weight);\n const index = Number.parseInt(key, 10);\n if (index >= 1 && index <= sorted.length) return sorted[index - 1].id;\n }\n return null;\n}\n\nasync function chooseFromList(\n models: ModelEntry[],\n label: string,\n): Promise<string> {\n const sorted = models.slice().sort((a, b) => b.weight - a.weight);\n return promptSelect(\n label,\n sorted.map((entry) => ({\n label: `${entry.id} \u6743\u91CD ${entry.weight}`,\n value: entry.id,\n })),\n 0,\n );\n}\n", "import {\n getSkillRequirements,\n skillsWithRequirements,\n currentPlatform,\n} from \"../../skills/dependencies\";\nimport { installRequirement, isRequirementMet } from \"../../skills/installer\";\nimport { ansi } from \"../../utils/ansi\";\nimport { promptConfirm } from \"../prompt\";\n\n/**\n * `xzh setup` \u2014\u2014 \u68C0\u67E5\u5E76\u81EA\u52A8\u5B89\u88C5\u5185\u7F6E\u6280\u80FD\u6240\u9700\u7684\u5916\u90E8 CLI\u3002\n * \u4F7F\u5B89\u88C5\u7384\u732A\u540E\u65E0\u9700\u518D\u5355\u72EC\u5B89\u88C5\u8FD9\u4E9B\u5DE5\u5177\u3002\n */\nexport async function setupCommand(): Promise<void> {\n const platform = currentPlatform();\n process.stdout.write(\n `\\n${ansi.bold}\u7384\u732A\u6280\u80FD\u4F9D\u8D56\u68C0\u67E5${ansi.reset} ${ansi.gray}(\u5E73\u53F0\uFF1A${platform})${ansi.reset}\\n\\n`,\n );\n\n const installedNow: string[] = [];\n const failed: string[] = [];\n const skipped: string[] = [];\n let checked = 0;\n\n for (const skillName of skillsWithRequirements()) {\n for (const requirement of getSkillRequirements(skillName)) {\n checked++;\n if (await isRequirementMet(requirement)) {\n process.stdout.write(\n `${ansi.green}\u2713${ansi.reset} ${requirement.name} ${ansi.gray}\u5DF2\u5B89\u88C5${ansi.reset}\\n`,\n );\n continue;\n }\n\n const command = requirement.install[platform];\n if (!command) {\n process.stdout.write(\n `${ansi.yellow}\u26A0${ansi.reset} ${requirement.name} ${ansi.gray}\u5F53\u524D\u5E73\u53F0\u65E0\u81EA\u52A8\u5B89\u88C5\u547D\u4EE4${ansi.reset}\\n`,\n );\n skipped.push(requirement.name);\n continue;\n }\n\n process.stdout.write(\n `\\n${ansi.yellow}\u25CF${ansi.reset} ${ansi.bold}${requirement.name}${ansi.reset} ${ansi.gray}\u672A\u5B89\u88C5${ansi.reset}\\n` +\n ` ${ansi.gray}\u6240\u5C5E\u6280\u80FD\uFF1A${skillName}${ansi.reset}\\n` +\n ` ${ansi.gray}\u5B89\u88C5\u547D\u4EE4\uFF1A${ansi.reset}${command}\\n`,\n );\n\n const approved = await promptConfirm(\" \u662F\u5426\u73B0\u5728\u5B89\u88C5\uFF1F\", true);\n if (!approved) {\n skipped.push(requirement.name);\n continue;\n }\n\n const result = await installRequirement(\n requirement,\n platform,\n undefined,\n (line) => process.stdout.write(`${ansi.gray} ${line}${ansi.reset}\\n`),\n );\n\n if (result.ok) {\n process.stdout.write(`${ansi.green} \u2713 ${requirement.name} \u5B89\u88C5\u5B8C\u6210${ansi.reset}\\n`);\n installedNow.push(requirement.name);\n } else {\n process.stdout.write(`${ansi.red} \u2717 ${requirement.name} \u5B89\u88C5\u5931\u8D25${ansi.reset}\\n`);\n failed.push(requirement.name);\n }\n }\n }\n\n process.stdout.write(`\\n${ansi.bold}\u7ED3\u679C${ansi.reset}\\n`);\n if (installedNow.length > 0) {\n process.stdout.write(\n ` ${ansi.green}\u5DF2\u5B89\u88C5 ${installedNow.length} \u9879${ansi.reset}\uFF1A${installedNow.join(\"\u3001\")}\\n`,\n );\n }\n if (skipped.length > 0) {\n process.stdout.write(\n ` ${ansi.yellow}\u5DF2\u8DF3\u8FC7 ${skipped.length} \u9879${ansi.reset}\uFF1A${skipped.join(\"\u3001\")}\\n`,\n );\n }\n if (failed.length > 0) {\n process.stdout.write(\n ` ${ansi.red}\u5931\u8D25 ${failed.length} \u9879${ansi.reset}\uFF1A${failed.join(\"\u3001\")}\\n`,\n );\n }\n if (checked === 0) {\n process.stdout.write(` ${ansi.gray}\u6CA1\u6709\u58F0\u660E\u5916\u90E8\u4F9D\u8D56\u7684\u5185\u7F6E\u6280\u80FD\u3002${ansi.reset}\\n`);\n } else if (installedNow.length === 0 && skipped.length === 0 && failed.length === 0) {\n process.stdout.write(` ${ansi.green}\u6240\u6709\u6280\u80FD\u4F9D\u8D56\u5747\u5DF2\u5C31\u7EEA\u3002${ansi.reset}\\n`);\n }\n process.stdout.write(\"\\n\");\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["fs", "path", "fs", "resolve", "Anthropic", "MAX_ATTEMPTS", "safeParse", "MAX_ATTEMPTS", "OpenAI", "fs", "path", "path", "resolve", "fs", "path", "asString", "relative", "fs", "path", "fs", "path", "import_child_process", "MAX_OUTPUT", "resolve", "Agent", "import_child_process", "fs", "os", "path", "KILL_GRACE_MS", "cursor", "looksLikePath", "Agent", "resolve", "MAX_LINES", "import_child_process", "fs", "resolve", "entry"]
7
+ }