blade-code 0.2.9 → 0.3.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.
package/dist/blade.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{createRequire as uF}from"node:module";var pF=Object.defineProperty;var mF=($)=>$;function gF($,Z){this[$]=mF.bind(null,Z)}var s9=($,Z)=>{for(var Y in Z)pF($,Y,{get:Z[Y],enumerable:!0,configurable:!0,set:gF.bind(Z,Y)})};var b=($,Z)=>()=>($&&(Z=$($=0)),Z);var U$=uF(import.meta.url);var j3;var JX=b(()=>{j3={name:"blade-code",version:"0.2.9",private:!1,description:"🗡️ Blade Code - 智能代码助手命令行工具",type:"module",bin:{blade:"dist/blade.js"},files:["dist","vendor/ripgrep/**","README.md"],scripts:{dev:"node scripts/run-bun.js --watch src/blade.tsx","dev:serve":"node scripts/run-bun.js --watch src/blade.tsx serve --port 4097",build:"rm -rf dist && node scripts/run-bun.js run scripts/build.ts",start:"node scripts/run-bun.js run dist/blade.js",test:"node scripts/test.js","test:all":"vitest run --config vitest.config.ts","test:unit":"node scripts/test.js unit","test:integration":"node scripts/test.js integration","test:cli":"node scripts/test.js cli","test:headless-core":"node scripts/test.js headlessCore","test:e2e":"node scripts/test.js e2e","test:performance":"node scripts/test.js performance","test:snapshot":"node scripts/test.js snapshot","test:security":"node scripts/test.js security","test:coverage":"node scripts/test.js all --coverage","test:watch":"vitest --watch --config vitest.config.ts","test:update-snapshots":"node scripts/test.js snapshot --update",lint:"biome lint src tests","lint:fix":"biome lint --write src tests","type-check":"tsc --noEmit",release:"node scripts/release.js","release:dry":"node scripts/release.js --dry-run","release:major":"node scripts/release.js --major","release:minor":"node scripts/release.js --minor","release:patch":"node scripts/release.js --patch"},keywords:["cli","blade","ai","assistant","agent","llm"],author:"echoVic",license:"MIT",engines:{node:">=20.0.0"},optionalDependencies:{"@vscode/ripgrep":"^1.17.0","bun-pty":"^0.4.8","node-pty":"1.0.0"},dependencies:{"@agentclientprotocol/sdk":"^0.12.0","@ai-sdk/anthropic":"^3.0.7","@ai-sdk/azure":"^3.0.5","@ai-sdk/deepseek":"^2.0.4","@ai-sdk/google":"^3.0.4","@ai-sdk/openai":"^3.0.26","@ai-sdk/openai-compatible":"^2.0.4","@inkjs/ui":"^2.0.0","@modelcontextprotocol/sdk":"^1.17.4",ahooks:"^3.9.6",ai:"^6.0.39","ansi-escapes":"^7.2.0","async-mutex":"^0.5.0",axios:"^1.12.2",chalk:"^5.4.1",diff:"^8.0.2","fast-glob":"^3.3.3","fuse.js":"^7.1.0","gray-matter":"^4.0.3",hono:"^4.7.10",ink:"npm:@jrichman/ink@6.4.10","ink-big-text":"^2.0.0","ink-gradient":"^3.0.0","ink-select-input":"^6.2.0","ink-spinner":"^5.0.0","ink-text-input":"^6.0.0","js-tiktoken":"^1.0.21","lodash-es":"^4.17.21",lowlight:"^3.3.0","lru-cache":"^11.2.4",nanoid:"^5.1.6",open:"^10.1.2",openai:"^6.2.0",picomatch:"^4.0.3",react:"^19.1.1","react-dom":"^19.1.1",semver:"^7.7.3","string-width":"^8.1.0",undici:"^7.16.0","write-file-atomic":"^7.0.0",ws:"^8.18.0",yaml:"^2.8.1",yargs:"^18.0.0",zod:"^3.24.2","zod-to-json-schema":"^3.24.6",zustand:"^5.0.9"},devDependencies:{"@biomejs/biome":"^2.2.4","@types/bun":"^1.3.4","@types/json-schema":"^7.0.15","@types/lodash-es":"^4.17.12","@types/node":"^22.15.24","@types/picomatch":"^4.0.2","@types/react":"^19.1.1","@types/react-dom":"^19.1.1","@types/semver":"^7.7.1","@types/write-file-atomic":"^4.0.3","@types/ws":"^8.5.12","@types/yargs":"^17.0.33","@vitest/coverage-v8":"^3.0.0",jsdom:"^26.0.0",typescript:"^5.9.2",vitest:"^3.0.0"}}});function G1(){return j3.version}function GX(){return j3.name}function qX(){return j3.description}function KX(){return`v${j3.version} © 2025 Blade Code`}var e2=b(()=>{JX()});var WX={};s9(WX,{globalOptions:()=>t9,cliConfig:()=>$4});var t9,$4;var e9=b(()=>{e2();t9={debug:{alias:"d",type:"string",describe:'Enable debug mode with optional category filtering (e.g., "agent,ui" or "!chat,!loop")',group:"Debug Options:"},print:{alias:"p",type:"boolean",describe:"Print response and exit (useful for pipes)",group:"Output Options:"},headless:{type:"boolean",describe:"Run full agent loop without Ink UI and print all events to the terminal",group:"Output Options:"},"output-format":{alias:["outputFormat"],type:"string",choices:["text","json","stream-json","jsonl"],default:"text",describe:"Output format (works with --print and --headless)",group:"Output Options:"},"include-partial-messages":{alias:["includePartialMessages"],type:"boolean",describe:"Include partial message chunks as they arrive",group:"Output Options:"},"input-format":{alias:["inputFormat"],type:"string",choices:["text","stream-json"],default:"text",describe:"Input format",group:"Input Options:"},"replay-user-messages":{alias:["replayUserMessages"],type:"boolean",describe:"Re-emit user messages from stdin",group:"Input Options:"},"allowed-tools":{alias:["allowedTools"],type:"array",string:!0,describe:"Comma or space-separated list of tool names to allow",group:"Security Options:"},"disallowed-tools":{alias:["disallowedTools"],type:"array",string:!0,describe:"Comma or space-separated list of tool names to deny",group:"Security Options:"},"mcp-config":{alias:["mcpConfig"],type:"array",string:!0,describe:"Load MCP servers from JSON files or strings",group:"MCP Options:"},"system-prompt":{alias:["systemPrompt"],type:"string",describe:"System prompt to use for the session (replaces default)",group:"AI Options:"},"append-system-prompt":{alias:["appendSystemPrompt"],type:"string",describe:"Append a system prompt to the default system prompt",group:"AI Options:"},"max-turns":{alias:["maxTurns"],type:"number",describe:"Maximum conversation turns (-1: unlimited, 0: disable chat, N>0: limit to N turns)",group:"AI Options:",default:void 0},"permission-mode":{alias:["permissionMode"],type:"string",choices:["default","autoEdit","yolo","plan"],describe:"Permission mode (default: ask for non-read tools, autoEdit: auto-approve edits, yolo: auto-approve all, plan: reserved)",group:"Security Options:"},yolo:{type:"boolean",describe:"Auto-approve all tools (shortcut for --permission-mode=yolo)",group:"Security Options:"},continue:{alias:"c",type:"boolean",describe:"Continue the most recent conversation",group:"Session Options:"},resume:{alias:"r",describe:"Resume a conversation - provide a session ID or interactively select a conversation to resume",group:"Session Options:",coerce:($)=>{if($===void 0||$===!0||$==="")return"true";return String($)}},"fork-session":{alias:["forkSession"],type:"boolean",describe:"Create a new session ID when resuming",group:"Session Options:"},settings:{type:"string",describe:"Path to a settings JSON file or JSON string",group:"Configuration:"},"add-dir":{alias:["addDir"],type:"array",string:!0,describe:"Additional directories to allow tool access to",group:"Security Options:"},ide:{type:"boolean",describe:"Automatically connect to IDE on startup",group:"Integration:"},acp:{type:"boolean",describe:"Run in ACP (Agent Client Protocol) mode for IDE integration",group:"Integration:"},"strict-mcp-config":{alias:["strictMcpConfig"],type:"boolean",describe:"Only use MCP servers from --mcp-config",group:"MCP Options:"},"session-id":{alias:["sessionId"],type:"string",describe:"Use a specific session ID for the conversation",group:"Session Options:"},agents:{type:"string",describe:"JSON object defining custom agents",group:"AI Options:"},"setting-sources":{alias:["settingSources"],type:"string",describe:"Comma-separated list of setting sources to load",group:"Configuration:"},"plugin-dir":{alias:["pluginDir"],type:"array",string:!0,describe:"Load plugins from specified directories",group:"Plugin Options:"}},$4={scriptName:"blade",usage:"$0 [command] [options]",description:qX(),version:G1(),locale:"en",showHelpOnFail:!0,demandCommand:!1,recommendCommands:!0,strict:!1}});var u0;var H$=b(()=>{((J)=>{J.DEFAULT="default";J.AUTO_EDIT="autoEdit";J.YOLO="yolo";J.PLAN="plan";J.SPEC="spec"})(u0||={})});var E8;var $5=b(()=>{H$();E8={currentModelId:"",models:[],temperature:0,maxContextTokens:128000,maxOutputTokens:void 0,stream:!0,topP:0.9,topK:50,timeout:180000,theme:"dracula",uiTheme:"system",language:"zh-CN",fontSize:14,autoSaveSessions:!0,notifyBuild:!0,notifyErrors:!1,notifySounds:!1,privacyTelemetry:!1,privacyCrash:!0,debug:!1,mcpEnabled:!1,mcpServers:{},permissions:{allow:["Bash(pwd)","Bash(which *)","Bash(whoami)","Bash(hostname)","Bash(uname *)","Bash(date)","Bash(echo *)","Bash(ls *)","Bash(tree *)","Bash(git status)","Bash(git log *)","Bash(git diff *)","Bash(git branch *)","Bash(git show *)","Bash(git remote *)","Bash(npm list *)","Bash(npm view *)","Bash(npm outdated *)","Bash(pnpm list *)","Bash(yarn list *)","Bash(pip list *)","Bash(pip show *)"],ask:["Bash(curl *)","Bash(wget *)","Bash(aria2c *)","Bash(axel *)","Bash(rm -rf *)","Bash(rm -r *)","Bash(rm --recursive *)","Bash(nc *)","Bash(netcat *)","Bash(telnet *)","Bash(ncat *)"],deny:["Read(./.env)","Read(./.env.*)","Bash(rm -rf /)","Bash(rm -rf /*)","Bash(sudo *)","Bash(chmod 777 *)","Bash(bash *)","Bash(sh *)","Bash(zsh *)","Bash(fish *)","Bash(dash *)","Bash(eval *)","Bash(source *)","Bash(mkfs *)","Bash(fdisk *)","Bash(dd *)","Bash(format *)","Bash(parted *)","Bash(open http*)","Bash(open https*)","Bash(xdg-open http*)","Bash(xdg-open https*)"]},permissionMode:"default",hooks:{enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,PreToolUse:[],PostToolUse:[],PostToolUseFailure:[],PermissionRequest:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]},env:{},disableAllHooks:!1,maxTurns:-1}});import{promises as UX}from"fs";import{merge as HX}from"lodash-es";import OX from"os";import T3 from"path";class f${static instance=null;constructor(){}static getInstance(){if(!f$.instance)f$.instance=new f$;return f$.instance}static resetInstance(){f$.instance=null}async initialize(){try{let $=await this.loadConfigFiles(),Z=await this.loadSettingsFiles(),Y={...E8,...$,...Z};if(this.resolveEnvInterpolation(Y),Y.debug)console.log("[ConfigManager] Configuration loaded successfully");return Y}catch($){return console.error("[ConfigManager] Failed to initialize:",$),E8}}async loadConfigFiles(){let $=T3.join(OX.homedir(),".blade","config.json"),Z=T3.join(process.cwd(),".blade","config.json"),Y={},Q=await this.loadJsonFile($);if(Q)Y={...Y,...Q};let X=await this.loadJsonFile(Z);if(X){let J={...Y.mcpServers||{},...X.mcpServers||{}};if(Y={...Y,...X},Object.keys(J).length>0)Y.mcpServers=J}return Y}async loadSettingsFiles(){let $=T3.join(OX.homedir(),".blade","settings.json"),Z=T3.join(process.cwd(),".blade","settings.json"),Y=T3.join(process.cwd(),".blade","settings.local.json"),Q={},X=await this.loadJsonFile($);if(X)Q=this.mergeSettings(Q,X);let J=await this.loadJsonFile(Z);if(J)Q=this.mergeSettings(Q,J);let G=await this.loadJsonFile(Y);if(G)Q=this.mergeSettings(Q,G);return Q}mergeSettings($,Z){let Y=JSON.parse(JSON.stringify($));if(Z.permissions){if(!Y.permissions)Y.permissions={allow:[],ask:[],deny:[]};if(Z.permissions.allow){let Q=[...Y.permissions.allow||[],...Z.permissions.allow];Y.permissions.allow=Array.from(new Set(Q))}if(Z.permissions.ask){let Q=[...Y.permissions.ask||[],...Z.permissions.ask];Y.permissions.ask=Array.from(new Set(Q))}if(Z.permissions.deny){let Q=[...Y.permissions.deny||[],...Z.permissions.deny];Y.permissions.deny=Array.from(new Set(Q))}}if(Z.hooks)Y.hooks=HX({},Y.hooks,Z.hooks);if(Z.env)Y.env=HX({},Y.env,Z.env);if(Z.mcpServers)Y.mcpServers={...Y.mcpServers||{},...Z.mcpServers};if(Z.disableAllHooks!==void 0)Y.disableAllHooks=Z.disableAllHooks;if(Z.permissionMode!==void 0)Y.permissionMode=Z.permissionMode;if(Z.maxTurns!==void 0)Y.maxTurns=Z.maxTurns;return Y}resolveEnvInterpolation($){let Z=/\$\{?([A-Z_][A-Z0-9_]*)(:-([^}]+))?\}?/g,Y=(Q)=>{if(typeof Q==="string")return Q.replace(Z,(X,J,G,q)=>{return process.env[J]||q||X});return Q};for(let[Q,X]of Object.entries($))if(typeof X==="string")$[Q]=Y(X)}async loadJsonFile($){try{if(await this.fileExists($)){let Z=await UX.readFile($,"utf-8");return JSON.parse(Z)}}catch(Z){console.warn(`[ConfigManager] Failed to load ${$}:`,Z)}return null}async fileExists($){try{return await UX.access($),!0}catch{return!1}}validateConfig($){let Z=[];if(!$.models||$.models.length===0)Z.push("没有可用的模型配置");if($.models&&$.models.length>0){if(!$.currentModelId)Z.push("未设置当前模型 ID");else if(!$.models.find((Q)=>Q.id===$.currentModelId))Z.push("当前模型 ID 无效")}if(Z.length>0)throw Error(`配置验证失败:
|
|
2
|
+
import{createRequire as uF}from"node:module";var pF=Object.defineProperty;var mF=($)=>$;function gF($,Z){this[$]=mF.bind(null,Z)}var s5=($,Z)=>{for(var Y in Z)pF($,Y,{get:Z[Y],enumerable:!0,configurable:!0,set:gF.bind(Z,Y)})};var b=($,Z)=>()=>($&&(Z=$($=0)),Z);var U$=uF(import.meta.url);var j3;var JX=b(()=>{j3={name:"blade-code",version:"0.3.0",private:!1,description:"🗡️ Blade Code - 智能代码助手命令行工具",type:"module",bin:{blade:"dist/blade.js"},files:["dist","vendor/ripgrep/**","README.md"],scripts:{dev:"node scripts/run-bun.js --watch src/blade.tsx","dev:serve":"node scripts/run-bun.js --watch src/blade.tsx serve --port 4097",build:"rm -rf dist && node scripts/run-bun.js run scripts/build.ts",start:"node scripts/run-bun.js run dist/blade.js",test:"node scripts/test.js","test:all":"vitest run --config vitest.config.ts","test:unit":"node scripts/test.js unit","test:integration":"node scripts/test.js integration","test:cli":"node scripts/test.js cli","test:headless-core":"node scripts/test.js headlessCore","test:e2e":"node scripts/test.js e2e","test:performance":"node scripts/test.js performance","test:snapshot":"node scripts/test.js snapshot","test:security":"node scripts/test.js security","test:coverage":"node scripts/test.js all --coverage","test:watch":"vitest --watch --config vitest.config.ts","test:update-snapshots":"node scripts/test.js snapshot --update",lint:"biome lint src tests","lint:fix":"biome lint --write src tests","type-check":"tsc --noEmit",release:"node scripts/release.js","release:dry":"node scripts/release.js --dry-run","release:major":"node scripts/release.js --major","release:minor":"node scripts/release.js --minor","release:patch":"node scripts/release.js --patch"},keywords:["cli","blade","ai","assistant","agent","llm"],author:"echoVic",license:"MIT",engines:{node:">=20.0.0"},optionalDependencies:{"@vscode/ripgrep":"^1.17.0","bun-pty":"^0.4.8","node-pty":"1.0.0"},dependencies:{"@agentclientprotocol/sdk":"^0.12.0","@ai-sdk/anthropic":"^3.0.7","@ai-sdk/azure":"^3.0.5","@ai-sdk/deepseek":"^2.0.4","@ai-sdk/google":"^3.0.4","@ai-sdk/openai":"^3.0.26","@ai-sdk/openai-compatible":"^2.0.4","@inkjs/ui":"^2.0.0","@modelcontextprotocol/sdk":"^1.17.4",ahooks:"^3.9.6",ai:"^6.0.39","ansi-escapes":"^7.2.0","async-mutex":"^0.5.0",axios:"^1.12.2",chalk:"^5.4.1",diff:"^8.0.2","fast-glob":"^3.3.3","fuse.js":"^7.1.0","gray-matter":"^4.0.3",hono:"^4.7.10",ink:"npm:@jrichman/ink@6.4.10","ink-big-text":"^2.0.0","ink-gradient":"^3.0.0","ink-select-input":"^6.2.0","ink-spinner":"^5.0.0","ink-text-input":"^6.0.0","js-tiktoken":"^1.0.21","lodash-es":"^4.17.21",lowlight:"^3.3.0","lru-cache":"^11.2.4",nanoid:"^5.1.6",open:"^10.1.2",openai:"^6.2.0",picomatch:"^4.0.3",react:"^19.1.1","react-dom":"^19.1.1",semver:"^7.7.3","string-width":"^8.1.0",undici:"^7.16.0","write-file-atomic":"^7.0.0",ws:"^8.18.0",yaml:"^2.8.1",yargs:"^18.0.0",zod:"^3.24.2","zod-to-json-schema":"^3.24.6",zustand:"^5.0.9"},devDependencies:{"@biomejs/biome":"^2.2.4","@types/bun":"^1.3.4","@types/json-schema":"^7.0.15","@types/lodash-es":"^4.17.12","@types/node":"^22.15.24","@types/picomatch":"^4.0.2","@types/react":"^19.1.1","@types/react-dom":"^19.1.1","@types/semver":"^7.7.1","@types/write-file-atomic":"^4.0.3","@types/ws":"^8.5.12","@types/yargs":"^17.0.33","@vitest/coverage-v8":"^3.0.0",jsdom:"^26.0.0",typescript:"^5.9.2",vitest:"^3.0.0"}}});function G1(){return j3.version}function GX(){return j3.name}function qX(){return j3.description}function KX(){return`v${j3.version} © 2025 Blade Code`}var e2=b(()=>{JX()});var WX={};s5(WX,{globalOptions:()=>t5,cliConfig:()=>$4});var t5,$4;var e5=b(()=>{e2();t5={debug:{alias:"d",type:"string",describe:'Enable debug mode with optional category filtering (e.g., "agent,ui" or "!chat,!loop")',group:"Debug Options:"},print:{alias:"p",type:"boolean",describe:"Print response and exit (useful for pipes)",group:"Output Options:"},headless:{type:"boolean",describe:"Run full agent loop without Ink UI and print all events to the terminal",group:"Output Options:"},"output-format":{alias:["outputFormat"],type:"string",choices:["text","json","stream-json","jsonl"],default:"text",describe:"Output format (works with --print and --headless)",group:"Output Options:"},"include-partial-messages":{alias:["includePartialMessages"],type:"boolean",describe:"Include partial message chunks as they arrive",group:"Output Options:"},"input-format":{alias:["inputFormat"],type:"string",choices:["text","stream-json"],default:"text",describe:"Input format",group:"Input Options:"},"replay-user-messages":{alias:["replayUserMessages"],type:"boolean",describe:"Re-emit user messages from stdin",group:"Input Options:"},"allowed-tools":{alias:["allowedTools"],type:"array",string:!0,describe:"Comma or space-separated list of tool names to allow",group:"Security Options:"},"disallowed-tools":{alias:["disallowedTools"],type:"array",string:!0,describe:"Comma or space-separated list of tool names to deny",group:"Security Options:"},"mcp-config":{alias:["mcpConfig"],type:"array",string:!0,describe:"Load MCP servers from JSON files or strings",group:"MCP Options:"},"system-prompt":{alias:["systemPrompt"],type:"string",describe:"System prompt to use for the session (replaces default)",group:"AI Options:"},"append-system-prompt":{alias:["appendSystemPrompt"],type:"string",describe:"Append a system prompt to the default system prompt",group:"AI Options:"},"max-turns":{alias:["maxTurns"],type:"number",describe:"Maximum conversation turns (-1: unlimited, 0: disable chat, N>0: limit to N turns)",group:"AI Options:",default:void 0},"permission-mode":{alias:["permissionMode"],type:"string",choices:["default","autoEdit","yolo","plan"],describe:"Permission mode (default: ask for non-read tools, autoEdit: auto-approve edits, yolo: auto-approve all, plan: reserved)",group:"Security Options:"},yolo:{type:"boolean",describe:"Auto-approve all tools (shortcut for --permission-mode=yolo)",group:"Security Options:"},continue:{alias:"c",type:"boolean",describe:"Continue the most recent conversation",group:"Session Options:"},resume:{alias:"r",describe:"Resume a conversation - provide a session ID or interactively select a conversation to resume",group:"Session Options:",coerce:($)=>{if($===void 0||$===!0||$==="")return"true";return String($)}},"fork-session":{alias:["forkSession"],type:"boolean",describe:"Create a new session ID when resuming",group:"Session Options:"},settings:{type:"string",describe:"Path to a settings JSON file or JSON string",group:"Configuration:"},"add-dir":{alias:["addDir"],type:"array",string:!0,describe:"Additional directories to allow tool access to",group:"Security Options:"},ide:{type:"boolean",describe:"Automatically connect to IDE on startup",group:"Integration:"},acp:{type:"boolean",describe:"Run in ACP (Agent Client Protocol) mode for IDE integration",group:"Integration:"},"strict-mcp-config":{alias:["strictMcpConfig"],type:"boolean",describe:"Only use MCP servers from --mcp-config",group:"MCP Options:"},"session-id":{alias:["sessionId"],type:"string",describe:"Use a specific session ID for the conversation",group:"Session Options:"},agents:{type:"string",describe:"JSON object defining custom agents",group:"AI Options:"},"setting-sources":{alias:["settingSources"],type:"string",describe:"Comma-separated list of setting sources to load",group:"Configuration:"},"plugin-dir":{alias:["pluginDir"],type:"array",string:!0,describe:"Load plugins from specified directories",group:"Plugin Options:"}},$4={scriptName:"blade",usage:"$0 [command] [options]",description:qX(),version:G1(),locale:"en",showHelpOnFail:!0,demandCommand:!1,recommendCommands:!0,strict:!1}});var u0;var H$=b(()=>{((J)=>{J.DEFAULT="default";J.AUTO_EDIT="autoEdit";J.YOLO="yolo";J.PLAN="plan";J.SPEC="spec"})(u0||={})});var E8;var $9=b(()=>{H$();E8={currentModelId:"",models:[],temperature:0,maxContextTokens:128000,maxOutputTokens:void 0,stream:!0,topP:0.9,topK:50,timeout:180000,theme:"dracula",uiTheme:"system",language:"zh-CN",fontSize:14,autoSaveSessions:!0,notifyBuild:!0,notifyErrors:!1,notifySounds:!1,privacyTelemetry:!1,privacyCrash:!0,debug:!1,mcpEnabled:!1,mcpServers:{},permissions:{allow:["Bash(pwd)","Bash(which *)","Bash(whoami)","Bash(hostname)","Bash(uname *)","Bash(date)","Bash(echo *)","Bash(ls *)","Bash(tree *)","Bash(git status)","Bash(git log *)","Bash(git diff *)","Bash(git branch *)","Bash(git show *)","Bash(git remote *)","Bash(npm list *)","Bash(npm view *)","Bash(npm outdated *)","Bash(pnpm list *)","Bash(yarn list *)","Bash(pip list *)","Bash(pip show *)"],ask:["Bash(curl *)","Bash(wget *)","Bash(aria2c *)","Bash(axel *)","Bash(rm -rf *)","Bash(rm -r *)","Bash(rm --recursive *)","Bash(nc *)","Bash(netcat *)","Bash(telnet *)","Bash(ncat *)"],deny:["Read(./.env)","Read(./.env.*)","Bash(rm -rf /)","Bash(rm -rf /*)","Bash(sudo *)","Bash(chmod 777 *)","Bash(bash *)","Bash(sh *)","Bash(zsh *)","Bash(fish *)","Bash(dash *)","Bash(eval *)","Bash(source *)","Bash(mkfs *)","Bash(fdisk *)","Bash(dd *)","Bash(format *)","Bash(parted *)","Bash(open http*)","Bash(open https*)","Bash(xdg-open http*)","Bash(xdg-open https*)"]},permissionMode:"default",hooks:{enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,PreToolUse:[],PostToolUse:[],PostToolUseFailure:[],PermissionRequest:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]},env:{},disableAllHooks:!1,maxTurns:-1}});import{promises as UX}from"fs";import{merge as HX}from"lodash-es";import OX from"os";import T3 from"path";class f${static instance=null;constructor(){}static getInstance(){if(!f$.instance)f$.instance=new f$;return f$.instance}static resetInstance(){f$.instance=null}async initialize(){try{let $=await this.loadConfigFiles(),Z=await this.loadSettingsFiles(),Y={...E8,...$,...Z};if(this.resolveEnvInterpolation(Y),Y.debug)console.log("[ConfigManager] Configuration loaded successfully");return Y}catch($){return console.error("[ConfigManager] Failed to initialize:",$),E8}}async loadConfigFiles(){let $=T3.join(OX.homedir(),".blade","config.json"),Z=T3.join(process.cwd(),".blade","config.json"),Y={},Q=await this.loadJsonFile($);if(Q)Y={...Y,...Q};let X=await this.loadJsonFile(Z);if(X){let J={...Y.mcpServers||{},...X.mcpServers||{}};if(Y={...Y,...X},Object.keys(J).length>0)Y.mcpServers=J}return Y}async loadSettingsFiles(){let $=T3.join(OX.homedir(),".blade","settings.json"),Z=T3.join(process.cwd(),".blade","settings.json"),Y=T3.join(process.cwd(),".blade","settings.local.json"),Q={},X=await this.loadJsonFile($);if(X)Q=this.mergeSettings(Q,X);let J=await this.loadJsonFile(Z);if(J)Q=this.mergeSettings(Q,J);let G=await this.loadJsonFile(Y);if(G)Q=this.mergeSettings(Q,G);return Q}mergeSettings($,Z){let Y=JSON.parse(JSON.stringify($));if(Z.permissions){if(!Y.permissions)Y.permissions={allow:[],ask:[],deny:[]};if(Z.permissions.allow){let Q=[...Y.permissions.allow||[],...Z.permissions.allow];Y.permissions.allow=Array.from(new Set(Q))}if(Z.permissions.ask){let Q=[...Y.permissions.ask||[],...Z.permissions.ask];Y.permissions.ask=Array.from(new Set(Q))}if(Z.permissions.deny){let Q=[...Y.permissions.deny||[],...Z.permissions.deny];Y.permissions.deny=Array.from(new Set(Q))}}if(Z.hooks)Y.hooks=HX({},Y.hooks,Z.hooks);if(Z.env)Y.env=HX({},Y.env,Z.env);if(Z.mcpServers)Y.mcpServers={...Y.mcpServers||{},...Z.mcpServers};if(Z.disableAllHooks!==void 0)Y.disableAllHooks=Z.disableAllHooks;if(Z.permissionMode!==void 0)Y.permissionMode=Z.permissionMode;if(Z.maxTurns!==void 0)Y.maxTurns=Z.maxTurns;return Y}resolveEnvInterpolation($){let Z=/\$\{?([A-Z_][A-Z0-9_]*)(:-([^}]+))?\}?/g,Y=(Q)=>{if(typeof Q==="string")return Q.replace(Z,(X,J,G,q)=>{return process.env[J]||q||X});return Q};for(let[Q,X]of Object.entries($))if(typeof X==="string")$[Q]=Y(X)}async loadJsonFile($){try{if(await this.fileExists($)){let Z=await UX.readFile($,"utf-8");return JSON.parse(Z)}}catch(Z){console.warn(`[ConfigManager] Failed to load ${$}:`,Z)}return null}async fileExists($){try{return await UX.access($),!0}catch{return!1}}validateConfig($){let Z=[];if(!$.models||$.models.length===0)Z.push("没有可用的模型配置");if($.models&&$.models.length>0){if(!$.currentModelId)Z.push("未设置当前模型 ID");else if(!$.models.find((Q)=>Q.id===$.currentModelId))Z.push("当前模型 ID 无效")}if(Z.length>0)throw Error(`配置验证失败:
|
|
3
3
|
${Z.map((Y)=>` - ${Y}`).join(`
|
|
4
4
|
`)}
|
|
5
5
|
|
|
@@ -22,19 +22,19 @@ ${Z.map((Y)=>` - ${Y}`).join(`
|
|
|
22
22
|
}
|
|
23
23
|
]
|
|
24
24
|
}
|
|
25
|
-
`)}}function
|
|
26
|
-
`)}catch(X){}}class c1{static globalDebugConfig=null;enabled;minLevel;category;constructor($={}){if($.enabled!==void 0)this.enabled=$.enabled;else if(c1.globalDebugConfig!==null)this.enabled=Boolean(c1.globalDebugConfig);else this.enabled=!1;this.minLevel=$.minLevel??0,this.category=$.category??"General"}static setGlobalDebug($){c1.globalDebugConfig=$}static clearGlobalDebug(){c1.globalDebugConfig=null}setEnabled($){this.enabled=$}parseDebugFilter($){if(!$)return{enabled:!1};if($===!0||$==="true"||$==="1")return{enabled:!0};let Z=String($).trim();if(!Z)return{enabled:!0};if(Z.startsWith("!"))return{enabled:!0,filter:{mode:"exclude",categories:Z.split(",").map((X)=>X.trim().replace(/^!/,"")).filter(Boolean)}};return{enabled:!0,filter:{mode:"include",categories:Z.split(",").map((Q)=>Q.trim()).filter(Boolean)}}}shouldLogCategory($){if(!$)return!0;let Z=this.category.toLowerCase();if($.mode==="include")return $.categories.some((Y)=>Z.includes(Y.toLowerCase()));return!$.categories.some((Y)=>Z.includes(Y.toLowerCase()))}shouldLogToConsole($){if(c1.globalDebugConfig!==null){let{enabled:Z,filter:Y}=this.parseDebugFilter(c1.globalDebugConfig);if(!Z)return!1;if($<this.minLevel)return!1;return this.shouldLogCategory(Y)}return this.enabled&&$>=this.minLevel}log($,...Z){let Y=Z.map((Q)=>typeof Q==="object"?JSON.stringify(Q):String(Q)).join(" ");if(eF(this.category,$,Y),this.shouldLogToConsole($)){let Q=X5[$],X=`[${this.category}] [${Q}]`;console.error(X,...Z)}}debug(...$){this.log(0,...$)}info(...$){this.log(1,...$)}warn(...$){this.log(2,...$)}error(...$){this.log(3,...$)}}function p($,Z){return new c1({...Z,category:$})}var X5,Y5=null,_X=null,zX=!1,r0;var Y0=b(()=>{((X)=>{X[X.DEBUG=0]="DEBUG";X[X.INFO=1]="INFO";X[X.WARN=2]="WARN";X[X.ERROR=3]="ERROR"})(X5||={});r0=new c1({category:"General"})});import{Mutex as wX}from"async-mutex";import{merge as $_}from"lodash-es";import{promises as g6}from"node:fs";import AX from"node:os";import Z4 from"node:path";import Z_ from"write-file-atomic";class y2{static instance=null;pendingUpdates=new Map;timers=new Map;fileLocks=new Map;lastSaveError=null;debounceDelay=300;constructor(){}static getInstance(){if(!y2.instance)y2.instance=new y2;return y2.instance}static resetInstance(){if(y2.instance)for(let $ of y2.instance.timers.values())clearTimeout($);y2.instance=null}async save($,Z={}){this.validatePersistableFields($);let Y=this.groupUpdatesByTarget($,Z.scope);if(Z.immediate)await Promise.all(Array.from(Y.entries()).map(([Q,X])=>this.flushTarget(Q,X)));else for(let[Q,X]of Y)this.scheduleSave(Q,X)}async flush(){for(let Z of this.timers.values())clearTimeout(Z);this.timers.clear();let $=Array.from(this.pendingUpdates.entries()).map(([Z,Y])=>this.flushTarget(Z,Y));this.pendingUpdates.clear(),await Promise.all($)}getLastSaveError(){return this.lastSaveError}clearLastSaveError(){this.lastSaveError=null}async appendPermissionRule($,Z={}){let Y=Z.scope??"local",Q=this.resolveFilePath("settings",Y);await this.flushTargetWithModifier(Q,(X)=>{let J=X.permissions??{allow:[],ask:[],deny:[]},G={allow:this.dedupeArray([...J.allow||[],$]),ask:J.ask||[],deny:J.deny||[]};return{...X,permissions:G}})}async appendLocalPermissionRule($,Z={}){await this.appendPermissionRule($,{...Z,scope:"local"})}validatePersistableFields($){for(let Z of Object.keys($)){let Y=I8[Z];if(!Y)throw Error(`Unknown config field: ${Z}`);if(!Y.persistable)throw Error(`Field "${Z}" is non-persistable and cannot be saved to config files. Non-persistable fields are runtime-only and only valid for the current session.`)}}groupUpdatesByTarget($,Z){let Y=new Map;for(let[Q,X]of Object.entries($)){let J=I8[Q];if(!J)continue;let G=Z??J.defaultScope,q=this.resolveFilePath(J.target,G);if(!Y.has(q))Y.set(q,{});Y.get(q)[Q]=X}return Y}resolveFilePath($,Z){if($==="config")return Z==="global"?Z4.join(AX.homedir(),".blade","config.json"):Z4.join(process.cwd(),".blade","config.json");switch(Z){case"local":return Z4.join(process.cwd(),".blade","settings.local.json");case"project":return Z4.join(process.cwd(),".blade","settings.json");case"global":return Z4.join(AX.homedir(),".blade","settings.json");default:return Z4.join(process.cwd(),".blade","settings.local.json")}}scheduleSave($,Z){let Y=this.pendingUpdates.get($)??{},Q=this.mergePendingUpdates(Y,Z);this.pendingUpdates.set($,Q);let X=this.timers.get($);if(X)clearTimeout(X);let J=setTimeout(async()=>{let G=this.pendingUpdates.get($);if(G){this.pendingUpdates.delete($),this.timers.delete($);try{await this.flushTarget($,G),this.lastSaveError=null}catch(q){let K=q instanceof Error?q:Error(String(q));this.lastSaveError=K,bX.error(`Failed to save config to ${$}:`,K.message),bX.error("Stack trace:",K.stack)}}},this.debounceDelay);this.timers.set($,J)}mergePendingUpdates($,Z){let Y={...$};for(let[Q,X]of Object.entries(Z)){let J=I8[Q];if(!J){Y[Q]=X;continue}switch(J.mergeStrategy){case"replace":Y[Q]=X;break;case"append-dedupe":this.applyAppendDedupe(Y,Q,X);break;case"deep-merge":this.applyDeepMerge(Y,Q,X);break}}return Y}async flushTarget($,Z){let Y=this.fileLocks.get($);if(!Y)Y=new wX,this.fileLocks.set($,Y);await Y.runExclusive(async()=>{await this.performWrite($,Z)})}async flushTargetWithModifier($,Z){let Y=this.fileLocks.get($);if(!Y)Y=new wX,this.fileLocks.set($,Y);await Y.runExclusive(async()=>{await g6.mkdir(Z4.dirname($),{recursive:!0,mode:493});let Q={};try{let J=await g6.readFile($,"utf-8");Q=JSON.parse(J)}catch{Q={}}let X=Z(Q);await this.atomicWrite($,X)})}async performWrite($,Z){await g6.mkdir(Z4.dirname($),{recursive:!0,mode:493});let Y={};try{let X=await g6.readFile($,"utf-8");Y=JSON.parse(X)}catch{Y={}}let Q={...Y};for(let[X,J]of Object.entries(Z)){let G=I8[X];if(!G){Q[X]=J;continue}switch(G.mergeStrategy){case"replace":Q[X]=J;break;case"append-dedupe":this.applyAppendDedupe(Q,X,J);break;case"deep-merge":this.applyDeepMerge(Q,X,J);break}}await this.atomicWrite($,Q)}applyAppendDedupe($,Z,Y){if(Z==="permissions"&&typeof Y==="object"&&Y!==null){let Q=$[Z]??{allow:[],ask:[],deny:[]},X=Y;$[Z]={allow:this.dedupeArray([...Q.allow||[],...X.allow||[]]),ask:this.dedupeArray([...Q.ask||[],...X.ask||[]]),deny:this.dedupeArray([...Q.deny||[],...X.deny||[]])}}else if(Array.isArray(Y)){let Q=Array.isArray($[Z])?$[Z]:[];$[Z]=this.dedupeArray([...Q,...Y])}else $[Z]=Y}applyDeepMerge($,Z,Y){if(typeof Y==="object"&&Y!==null&&!Array.isArray(Y)){let Q=typeof $[Z]==="object"&&$[Z]!==null?$[Z]:{};$[Z]=$_({},Q,Y)}else $[Z]=Y}dedupeArray($){return Array.from(new Set($))}async atomicWrite($,Z){await Z_($,JSON.stringify(Z,null,2),{mode:384,encoding:"utf-8"})}}function c$(){return y2.getInstance()}var bX,I8,hj,xj;var VX=b(()=>{Y0();bX=p("Service"),I8={models:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},currentModelId:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},temperature:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},maxContextTokens:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},maxOutputTokens:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},timeout:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},theme:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},uiTheme:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},language:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},debug:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},fontSize:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},autoSaveSessions:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},notifyBuild:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},notifyErrors:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},notifySounds:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},privacyTelemetry:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},privacyCrash:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},permissionMode:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},permissions:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!0},hooks:{target:"settings",defaultScope:"local",mergeStrategy:"deep-merge",persistable:!0},env:{target:"settings",defaultScope:"local",mergeStrategy:"deep-merge",persistable:!0},disableAllHooks:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!0},maxTurns:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!0},mcpServers:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},stream:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},topP:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},topK:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},mcpEnabled:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},systemPrompt:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},appendSystemPrompt:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},initialMessage:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},resumeSessionId:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},forkSession:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},allowedTools:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},disallowedTools:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},mcpConfigPaths:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},strictMcpConfig:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},addDirs:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},outputFormat:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},inputFormat:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},print:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},includePartialMessages:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},replayUserMessages:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},agentsConfig:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},settingSources:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1}},hj=new Set(Object.entries(I8).filter(([$,Z])=>Z.persistable).map(([$])=>$)),xj=new Set(Object.entries(I8).filter(([$,Z])=>!Z.persistable).map(([$])=>$))});var Y4=b(()=>{FX();VX();$5();H$()});var Y_,Q_,X_,J_,G_,q_,K_,W_,U_,H_,O_,F_,__,E2;var J5=b(()=>{Y_={name:"ayu-dark",colors:{primary:"#ffcc66",secondary:"#bae67e",accent:"#73d0ff",success:"#bae67e",warning:"#ffcc66",error:"#ff3333",info:"#73d0ff",light:"#f0f0f0",dark:"#000000",muted:"#5c6773",highlight:"#2d323b",text:{primary:"#e6e1cf",secondary:"#bae67e",muted:"#5c6773",light:"#ffffff"},background:{primary:"#0f1419",secondary:"#14191f",dark:"#000000"},border:{light:"#2d323b",dark:"#000000"},syntax:{comment:"#5c6773",string:"#bae67e",number:"#ffcc66",keyword:"#ff8f40",function:"#73d0ff",variable:"#e6e1cf",operator:"#f29e74",type:"#73d0ff",tag:"#ff8f40",attr:"#ffd580",default:"#e6e1cf"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(0, 0, 0, 0.2)",base:"0 1px 3px 0 rgba(0, 0, 0, 0.3), 0 1px 2px 0 rgba(0, 0, 0, 0.2)",lg:"0 10px 15px -3px rgba(0, 0, 0, 0.3), 0 4px 6px -2px rgba(0, 0, 0, 0.2)"}},Q_={name:"dracula",colors:{primary:"#bd93f9",secondary:"#ffb86c",accent:"#ff79c6",success:"#50fa7b",warning:"#f1fa8c",error:"#ff5555",info:"#8be9fd",light:"#f8f8f2",dark:"#282a36",muted:"#6272a4",highlight:"#44475a",text:{primary:"#f8f8f2",secondary:"#f1fa8c",muted:"#6272a4",light:"#ffffff"},background:{primary:"#282a36",secondary:"#44475a",dark:"#21222c"},border:{light:"#44475a",dark:"#000000"},syntax:{comment:"#6272a4",string:"#f1fa8c",number:"#bd93f9",keyword:"#ff79c6",function:"#50fa7b",variable:"#f8f8f2",operator:"#ff79c6",type:"#8be9fd",tag:"#ff79c6",attr:"#50fa7b",default:"#f8f8f2"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(40, 42, 54, 0.2)",base:"0 1px 3px 0 rgba(40, 42, 54, 0.3), 0 1px 2px 0 rgba(40, 42, 54, 0.2)",lg:"0 10px 15px -3px rgba(40, 42, 54, 0.3), 0 4px 6px -2px rgba(40, 42, 54, 0.2)"}},X_={name:"monokai",colors:{primary:"#66d9ef",secondary:"#a6e22e",accent:"#f92672",success:"#a6e22e",warning:"#e6db74",error:"#f92672",info:"#66d9ef",light:"#f8f8f2",dark:"#272822",muted:"#75715e",highlight:"#3e3d32",text:{primary:"#f8f8f2",secondary:"#e6db74",muted:"#75715e",light:"#ffffff"},background:{primary:"#272822",secondary:"#3e3d32",dark:"#1e1f1c"},border:{light:"#3e3d32",dark:"#000000"},syntax:{comment:"#75715e",string:"#e6db74",number:"#ae81ff",keyword:"#f92672",function:"#a6e22e",variable:"#f8f8f2",operator:"#f92672",type:"#66d9ef",tag:"#f92672",attr:"#a6e22e",default:"#f8f8f2"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(39, 40, 34, 0.2)",base:"0 1px 3px 0 rgba(39, 40, 34, 0.3), 0 1px 2px 0 rgba(39, 40, 34, 0.2)",lg:"0 10px 15px -3px rgba(39, 40, 34, 0.3), 0 4px 6px -2px rgba(39, 40, 34, 0.2)"}},J_={name:"nord",colors:{primary:"#88c0d0",secondary:"#81a1c1",accent:"#b48ead",success:"#a3be8c",warning:"#ebcb8b",error:"#bf616a",info:"#88c0d0",light:"#eceff4",dark:"#2e3440",muted:"#4c566a",highlight:"#434c5e",text:{primary:"#eceff4",secondary:"#d8dee9",muted:"#4c566a",light:"#ffffff"},background:{primary:"#2e3440",secondary:"#3b4252",dark:"#242933"},border:{light:"#434c5e",dark:"#000000"},syntax:{comment:"#616e88",string:"#a3be8c",number:"#b48ead",keyword:"#81a1c1",function:"#88c0d0",variable:"#d8dee9",operator:"#81a1c1",type:"#8fbcbb",tag:"#81a1c1",attr:"#8fbcbb",default:"#eceff4"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(46, 52, 64, 0.2)",base:"0 1px 3px 0 rgba(46, 52, 64, 0.3), 0 1px 2px 0 rgba(46, 52, 64, 0.2)",lg:"0 10px 15px -3px rgba(46, 52, 64, 0.3), 0 4px 6px -2px rgba(46, 52, 64, 0.2)"}},G_={name:"solarized-light",colors:{primary:"#268bd2",secondary:"#2aa198",accent:"#d33682",success:"#859900",warning:"#b58900",error:"#dc322f",info:"#268bd2",light:"#fdf6e3",dark:"#073642",muted:"#93a1a1",highlight:"#eee8d5",text:{primary:"#586e75",secondary:"#657b83",muted:"#93a1a1",light:"#002b36"},background:{primary:"#fdf6e3",secondary:"#eee8d5",dark:"#073642"},border:{light:"#eee8d5",dark:"#073642"},syntax:{comment:"#93a1a1",string:"#2aa198",number:"#d33682",keyword:"#859900",function:"#268bd2",variable:"#657b83",operator:"#859900",type:"#b58900",tag:"#268bd2",attr:"#93a1a1",default:"#657b83"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(253, 246, 227, 0.2)",base:"0 1px 3px 0 rgba(253, 246, 227, 0.3), 0 1px 2px 0 rgba(253, 246, 227, 0.2)",lg:"0 10px 15px -3px rgba(253, 246, 227, 0.3), 0 4px 6px -2px rgba(253, 246, 227, 0.2)"}},q_={name:"solarized-dark",colors:{primary:"#268bd2",secondary:"#2aa198",accent:"#d33682",success:"#859900",warning:"#b58900",error:"#dc322f",info:"#268bd2",light:"#fdf6e3",dark:"#073642",muted:"#586e75",highlight:"#073642",text:{primary:"#839496",secondary:"#93a1a1",muted:"#586e75",light:"#fdf6e3"},background:{primary:"#002b36",secondary:"#073642",dark:"#001f29"},border:{light:"#073642",dark:"#000000"},syntax:{comment:"#586e75",string:"#2aa198",number:"#d33682",keyword:"#859900",function:"#268bd2",variable:"#839496",operator:"#859900",type:"#b58900",tag:"#268bd2",attr:"#93a1a1",default:"#839496"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(0, 43, 54, 0.2)",base:"0 1px 3px 0 rgba(0, 43, 54, 0.3), 0 1px 2px 0 rgba(0, 43, 54, 0.2)",lg:"0 10px 15px -3px rgba(0, 43, 54, 0.3), 0 4px 6px -2px rgba(0, 43, 54, 0.2)"}},K_={name:"tokyo-night",colors:{primary:"#7aa2f7",secondary:"#7dcfff",accent:"#bb9af7",success:"#9ece6a",warning:"#e0af68",error:"#f7768e",info:"#7aa2f7",light:"#c0caf5",dark:"#1a1b26",muted:"#565f89",highlight:"#292e42",text:{primary:"#a9b1d6",secondary:"#c0caf5",muted:"#565f89",light:"#ffffff"},background:{primary:"#1a1b26",secondary:"#292e42",dark:"#16161e"},border:{light:"#292e42",dark:"#000000"},syntax:{comment:"#565f89",string:"#9ece6a",number:"#ff9e64",keyword:"#bb9af7",function:"#7aa2f7",variable:"#c0caf5",operator:"#89ddff",type:"#7dcfff",tag:"#f7768e",attr:"#7aa2f7",default:"#a9b1d6"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(26, 27, 38, 0.2)",base:"0 1px 3px 0 rgba(26, 27, 38, 0.3), 0 1px 2px 0 rgba(26, 27, 38, 0.2)",lg:"0 10px 15px -3px rgba(26, 27, 38, 0.3), 0 4px 6px -2px rgba(26, 27, 38, 0.2)"}},W_={name:"github",colors:{primary:"#0969da",secondary:"#8250df",accent:"#bc4c00",success:"#1a7f37",warning:"#9a6700",error:"#d1242f",info:"#0969da",light:"#f6f8fa",dark:"#24292f",muted:"#6e7781",highlight:"#ddf4ff",text:{primary:"#24292f",secondary:"#57606a",muted:"#6e7781",light:"#ffffff"},background:{primary:"#ffffff",secondary:"#f6f8fa",dark:"#24292f"},border:{light:"#d0d7de",dark:"#24292f"},syntax:{comment:"#6e7781",string:"#0a3069",number:"#0550ae",keyword:"#cf222e",function:"#8250df",variable:"#24292f",operator:"#cf222e",type:"#0550ae",tag:"#116329",attr:"#0550ae",default:"#24292f"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(255, 255, 255, 0.2)",base:"0 1px 3px 0 rgba(255, 255, 255, 0.3), 0 1px 2px 0 rgba(255, 255, 255, 0.2)",lg:"0 10px 15px -3px rgba(255, 255, 255, 0.3), 0 4px 6px -2px rgba(255, 255, 255, 0.2)"}},U_={name:"gruvbox",colors:{primary:"#83a598",secondary:"#8ec07c",accent:"#d3869b",success:"#b8bb26",warning:"#fabd2f",error:"#fb4934",info:"#83a598",light:"#fbf1c7",dark:"#282828",muted:"#928374",highlight:"#3c3836",text:{primary:"#ebdbb2",secondary:"#d5c4a1",muted:"#928374",light:"#ffffff"},background:{primary:"#282828",secondary:"#3c3836",dark:"#1d2021"},border:{light:"#3c3836",dark:"#000000"},syntax:{comment:"#928374",string:"#b8bb26",number:"#d3869b",keyword:"#fb4934",function:"#8ec07c",variable:"#ebdbb2",operator:"#fe8019",type:"#fabd2f",tag:"#fb4934",attr:"#b8bb26",default:"#ebdbb2"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(40, 40, 40, 0.2)",base:"0 1px 3px 0 rgba(40, 40, 40, 0.3), 0 1px 2px 0 rgba(40, 40, 40, 0.2)",lg:"0 10px 15px -3px rgba(40, 40, 40, 0.3), 0 4px 6px -2px rgba(40, 40, 40, 0.2)"}},H_={name:"one-dark",colors:{primary:"#61afef",secondary:"#c678dd",accent:"#e5c07b",success:"#98c379",warning:"#e5c07b",error:"#e06c75",info:"#56b6c2",light:"#abb2bf",dark:"#282c34",muted:"#5c6370",highlight:"#3e4451",text:{primary:"#abb2bf",secondary:"#c6c8d0",muted:"#5c6370",light:"#ffffff"},background:{primary:"#282c34",secondary:"#3e4451",dark:"#21252b"},border:{light:"#3e4451",dark:"#000000"},syntax:{comment:"#5c6370",string:"#98c379",number:"#d19a66",keyword:"#c678dd",function:"#61afef",variable:"#e06c75",operator:"#56b6c2",type:"#e5c07b",tag:"#e06c75",attr:"#d19a66",default:"#abb2bf"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(40, 44, 52, 0.2)",base:"0 1px 3px 0 rgba(40, 44, 52, 0.3), 0 1px 2px 0 rgba(40, 44, 52, 0.2)",lg:"0 10px 15px -3px rgba(40, 44, 52, 0.3), 0 4px 6px -2px rgba(40, 44, 52, 0.2)"}},O_={name:"catppuccin",colors:{primary:"#89b4fa",secondary:"#cba6f7",accent:"#f5c2e7",success:"#a6e3a1",warning:"#f9e2af",error:"#f38ba8",info:"#89dceb",light:"#cdd6f4",dark:"#11111b",muted:"#6c7086",highlight:"#181825",text:{primary:"#cdd6f4",secondary:"#bac2de",muted:"#6c7086",light:"#ffffff"},background:{primary:"#1e1e2e",secondary:"#181825",dark:"#11111b"},border:{light:"#181825",dark:"#000000"},syntax:{comment:"#6c7086",string:"#a6e3a1",number:"#fab387",keyword:"#cba6f7",function:"#89b4fa",variable:"#cdd6f4",operator:"#89dceb",type:"#f5c2e7",tag:"#f38ba8",attr:"#89b4fa",default:"#cdd6f4"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(30, 30, 46, 0.2)",base:"0 1px 3px 0 rgba(30, 30, 46, 0.3), 0 1px 2px 0 rgba(30, 30, 46, 0.2)",lg:"0 10px 15px -3px rgba(30, 30, 46, 0.3), 0 4px 6px -2px rgba(30, 30, 46, 0.2)"}},F_={name:"rose-pine",colors:{primary:"#9ccfd8",secondary:"#c4a7e7",accent:"#f6c177",success:"#31748f",warning:"#f6c177",error:"#eb6f92",info:"#9ccfd8",light:"#e0def4",dark:"#191724",muted:"#6e6a86",highlight:"#1f1d2e",text:{primary:"#e0def4",secondary:"#cecacd",muted:"#6e6a86",light:"#ffffff"},background:{primary:"#191724",secondary:"#1f1d2e",dark:"#12101a"},border:{light:"#1f1d2e",dark:"#000000"},syntax:{comment:"#6e6a86",string:"#9ccfd8",number:"#ea9a97",keyword:"#c4a7e7",function:"#31748f",variable:"#e0def4",operator:"#f6c177",type:"#9ccfd8",tag:"#eb6f92",attr:"#f6c177",default:"#e0def4"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(25, 23, 36, 0.2)",base:"0 1px 3px 0 rgba(25, 23, 36, 0.3), 0 1px 2px 0 rgba(25, 23, 36, 0.2)",lg:"0 10px 15px -3px rgba(25, 23, 36, 0.3), 0 4px 6px -2px rgba(25, 23, 36, 0.2)"}},__={name:"kanagawa",colors:{primary:"#8ba4b0",secondary:"#a292a3",accent:"#c47fd5",success:"#76946a",warning:"#c0a36e",error:"#c34043",info:"#7e9cd8",light:"#dcd7ba",dark:"#1f1f28",muted:"#727169",highlight:"#2a2a37",text:{primary:"#dcd7ba",secondary:"#c8c093",muted:"#727169",light:"#ffffff"},background:{primary:"#1f1f28",secondary:"#2a2a37",dark:"#16161d"},border:{light:"#2a2a37",dark:"#000000"},syntax:{comment:"#727169",string:"#98bb6c",number:"#d27e99",keyword:"#957fb8",function:"#7e9cd8",variable:"#dcd7ba",operator:"#c0a36e",type:"#7aa89f",tag:"#c34043",attr:"#7fb4ca",default:"#dcd7ba"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(31, 31, 40, 0.2)",base:"0 1px 3px 0 rgba(31, 31, 40, 0.3), 0 1px 2px 0 rgba(31, 31, 40, 0.2)",lg:"0 10px 15px -3px rgba(31, 31, 40, 0.3), 0 4px 6px -2px rgba(31, 31, 40, 0.2)"}},E2=[{id:"ayu-dark",label:"Ayu Dark",theme:Y_,tags:["dark","popular"]},{id:"dracula",label:"Dracula",theme:Q_,tags:["dark","popular"]},{id:"monokai",label:"Monokai",theme:X_,tags:["dark","classic"]},{id:"nord",label:"Nord",theme:J_,tags:["dark","minimal"]},{id:"solarized-light",label:"Solarized Light",theme:G_,tags:["light"]},{id:"solarized-dark",label:"Solarized Dark",theme:q_,tags:["dark"]},{id:"tokyo-night",label:"Tokyo Night",theme:K_,tags:["dark","popular"]},{id:"github",label:"GitHub",theme:W_,tags:["light","minimal"]},{id:"gruvbox",label:"Gruvbox",theme:U_,tags:["dark","warm"]},{id:"one-dark",label:"One Dark",theme:H_,tags:["dark","popular"]},{id:"catppuccin",label:"Catppuccin",theme:O_,tags:["dark","pastel"]},{id:"rose-pine",label:"Rose Pine",theme:F_,tags:["dark","elegant"]},{id:"kanagawa",label:"Kanagawa",theme:__,tags:["dark","japanese"]}]});class DX{currentTheme=G5;themes=new Map;constructor(){this.themes.set("default",G5),this.themes.set("dark",z_);for(let $ of E2)this.themes.set($.id,$.theme)}setTheme($){let Z=this.themes.get($);if(Z)this.currentTheme=Z;else throw Error(`Theme '${$}' not found`)}getTheme(){return this.currentTheme}getAvailableThemes(){return Array.from(this.themes.keys())}getCurrentThemeName(){return this.currentTheme.name}getThemeByName($){return this.themes.get($)}hasTheme($){return this.themes.has($)}}var RX,G5,z_,E$;var I2=b(()=>{J5();RX={primary:"#0066cc",secondary:"#6c757d",accent:"#e83e8c",success:"#28a745",warning:"#ffc107",error:"#dc3545",info:"#17a2b8",light:"#f8f9fa",dark:"#343a40",muted:"#6c757d",highlight:"#fff3cd",text:{primary:"#212529",secondary:"#6c757d",muted:"#6c757d",light:"#ffffff"},background:{primary:"#ffffff",secondary:"#f8f9fa",dark:"#343a40"},border:{light:"#dee2e6",dark:"#495057"},syntax:{comment:"#6c757d",string:"#28a745",number:"#e83e8c",keyword:"#007bff",function:"#17a2b8",variable:"#495057",operator:"#ffc107",type:"#007bff",tag:"#dc3545",attr:"#ffc107",default:"#212529"}},G5={name:"default",colors:RX,spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(0, 0, 0, 0.05)",base:"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)",lg:"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"}},z_={...G5,name:"dark",colors:{...RX,text:{primary:"#ffffff",secondary:"#e2e8f0",muted:"#94a3b8",light:"#000000"},background:{primary:"#1e293b",secondary:"#334155",dark:"#0f172a"},border:{light:"#475569",dark:"#64748b"},syntax:{comment:"#94a3b8",string:"#34d399",number:"#f472b6",keyword:"#60a5fa",function:"#06b6d4",variable:"#e2e8f0",operator:"#fbbf24",type:"#60a5fa",tag:"#fb7185",attr:"#fbbf24",default:"#ffffff"}}};E$=new DX});var B_,q5=($)=>({...B_,actions:{setInitializationStatus:(Z)=>{$((Y)=>({app:{...Y.app,initializationStatus:Z}}))},setInitializationError:(Z)=>{$((Y)=>({app:{...Y.app,initializationError:Z}}))},setActiveModal:(Z)=>{$((Y)=>({app:{...Y.app,activeModal:Z}}))},showSessionSelector:(Z)=>{$((Y)=>({app:{...Y.app,activeModal:"sessionSelector",sessionSelectorData:Z}}))},showModelEditWizard:(Z)=>{$((Y)=>({app:{...Y.app,activeModal:"modelEditWizard",modelEditorTarget:Z}}))},closeModal:()=>{$((Z)=>({app:{...Z.app,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null}}))},setTodos:(Z)=>{$((Y)=>({app:{...Y.app,todos:Z}}))},updateTodo:(Z)=>{$((Y)=>({app:{...Y.app,todos:Y.app.todos.map((Q)=>Q.id===Z.id?Z:Q)}}))},setAwaitingSecondCtrlC:(Z)=>{$((Y)=>({app:{...Y.app,awaitingSecondCtrlC:Z}}))},setThinkingModeEnabled:(Z)=>{$((Y)=>({app:{...Y.app,thinkingModeEnabled:Z}}))},toggleThinkingMode:()=>{$((Z)=>({app:{...Z.app,thinkingModeEnabled:!Z.app.thinkingModeEnabled}}))},startSubagentProgress:(Z,Y,Q)=>{$((X)=>({app:{...X.app,subagentProgress:{id:Z,type:Y,description:Q,status:"running",startTime:Date.now()}}}))},updateSubagentTool:(Z)=>{$((Y)=>{if(!Y.app.subagentProgress)return Y;return{app:{...Y.app,subagentProgress:{...Y.app.subagentProgress,currentTool:Z}}}})},completeSubagentProgress:(Z)=>{$((Y)=>{if(!Y.app.subagentProgress)return Y;return{app:{...Y.app,subagentProgress:{...Y.app.subagentProgress,status:Z?"completed":"failed",currentTool:void 0}}}}),setTimeout(()=>{$((Y)=>({app:{...Y.app,subagentProgress:null}}))},1500)}}});var MX=b(()=>{B_={initializationStatus:"idle",initializationError:null,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null,todos:[],awaitingSecondCtrlC:!1,thinkingModeEnabled:!1,subagentProgress:null}});var N_,K5=($,Z)=>({...N_,actions:{setProcessing:(Y)=>{$((Q)=>({command:{...Q.command,isProcessing:Y}}))},createAbortController:()=>{let Y=Z().command.abortController;if(Y&&!Y.signal.aborted)return Y;let Q=new AbortController;return $((X)=>({command:{...X.command,abortController:Q}})),Q},getAbortController:()=>{return Z().command.abortController},clearAbortController:(Y)=>{let Q=Z().command.abortController;if(Y!==void 0&&Q!==Y)return;$((X)=>({command:{...X.command,abortController:null}}))},abort:()=>{let{abortController:Y}=Z().command;if(Y&&!Y.signal.aborted)Y.abort();$((Q)=>({command:{...Q.command,isProcessing:!1,pendingCommands:[]}}))},enqueueCommand:(Y)=>{$((Q)=>({command:{...Q.command,pendingCommands:[...Q.command.pendingCommands,Y]}}))},dequeueCommand:()=>{let{pendingCommands:Y}=Z().command;if(Y.length===0)return;let[Q,...X]=Y;return $((J)=>({command:{...J.command,pendingCommands:X}})),Q},clearQueue:()=>{$((Y)=>({command:{...Y.command,pendingCommands:[]}}))}}});var jX=b(()=>{N_={isProcessing:!1,abortController:null,pendingCommands:[]}});var L_,W5=($)=>({...L_,actions:{setConfig:(Z)=>{$((Y)=>({config:{...Y.config,config:Z}}))},updateConfig:(Z)=>{$((Y)=>{if(!Y.config.config)throw Error(`[ConfigSlice] Config not initialized. Cannot update: ${JSON.stringify(Z)}`);return{config:{...Y.config,config:{...Y.config.config,...Z}}}})}}});var TX=b(()=>{L_={config:null}});var w_,U5=($)=>({...w_,actions:{setFocus:(Z)=>{$((Y)=>({focus:{...Y.focus,currentFocus:Z,previousFocus:Y.focus.currentFocus}}))},restorePreviousFocus:()=>{$((Z)=>({focus:{...Z.focus,currentFocus:Z.focus.previousFocus||"main-input",previousFocus:null}}))}}});var yX=b(()=>{w_={currentFocus:"main-input",previousFocus:null}});function p4($){let Z=[],Y=$.split(/\r?\n/),Q=!1,X=[],J=null,G=0,q=!1,K=[],W=[],U=!1,H=[],O=!0;for(let F=0;F<Y.length;F++){let _=Y[F];if(U){if(_.match(I0.diffEnd)){try{let T=JSON.parse(H.join(`
|
|
25
|
+
`)}}function Z9($,Z={}){let Y={...$};if(Z.debug!==void 0)Y.debug=Z.debug===""?!0:Z.debug;if(Z.yolo===!0)Y.permissionMode="yolo";else if(Z.permissionMode!==void 0)Y.permissionMode=Z.permissionMode;if(Z.maxTurns!==void 0)Y.maxTurns=Z.maxTurns;return Y.systemPrompt=Z.systemPrompt,Y.appendSystemPrompt=Z.appendSystemPrompt,Y.resumeSessionId=Z.sessionId,Y.forkSession=Z.forkSession,Y.allowedTools=Z.allowedTools,Y.disallowedTools=Z.disallowedTools,Y.mcpConfigPaths=Z.mcpConfig,Y.strictMcpConfig=Z.strictMcpConfig,Y.addDirs=Z.addDir,Y.outputFormat=Z.outputFormat,Y.inputFormat=Z.inputFormat,Y.print=Z.print,Y.includePartialMessages=Z.includePartialMessages,Y.replayUserMessages=Z.replayUserMessages,Y.agentsConfig=Z.agents,Y.settingSources=Z.settingSources,Y}var FX=b(()=>{$9();H$()});import{appendFileSync as cF,existsSync as lF,mkdirSync as iF,readdirSync as rF,statSync as BX,unlinkSync as aF}from"node:fs";import nF from"node:os";import Q9 from"node:path";function NX($){if(Y9!==$)Y9=$}async function LX(){}function oF(){if(zX)return _X;zX=!0;try{let $=Q9.join(nF.homedir(),".blade","logs");if(!lF($))iF($,{recursive:!0,mode:493});if(BX($).uid===0&&process.getuid&&process.getuid()!==0)return console.error(""),console.error("❌ 权限错误:~/.blade/logs 目录属于 root 用户"),console.error(""),console.error("这通常是因为您曾经使用 sudo 运行过 blade。"),console.error(""),console.error("解决方法:"),console.error(" sudo chown -R $USER:$USER ~/.blade/"),console.error(""),console.error("然后重新运行 blade(不要使用 sudo)"),console.error(""),null;return sF($,30),_X=$,$}catch($){return console.error("[Logger] 无法创建日志目录:",$),null}}function sF($,Z){try{let Y=rF($),Q=Date.now(),X=Z*24*60*60*1000;for(let J of Y){if(!J.startsWith("blade-")||!J.endsWith(".log")&&!J.endsWith(".jsonl"))continue;let G=Q9.join($,J);try{let q=BX(G);if(Q-q.mtimeMs>X)aF(G)}catch(q){}}}catch(Y){}}function tF(){let $=oF();if(!$)return null;let Z=Y9||"default";return Q9.join($,`blade-${Z}.jsonl`)}function eF($,Z,Y){let Q=tF();if(!Q)return;try{let X={timestamp:new Date().toISOString(),level:X9[Z],category:$,message:Y};cF(Q,JSON.stringify(X)+`
|
|
26
|
+
`)}catch(X){}}class c1{static globalDebugConfig=null;enabled;minLevel;category;constructor($={}){if($.enabled!==void 0)this.enabled=$.enabled;else if(c1.globalDebugConfig!==null)this.enabled=Boolean(c1.globalDebugConfig);else this.enabled=!1;this.minLevel=$.minLevel??0,this.category=$.category??"General"}static setGlobalDebug($){c1.globalDebugConfig=$}static clearGlobalDebug(){c1.globalDebugConfig=null}setEnabled($){this.enabled=$}parseDebugFilter($){if(!$)return{enabled:!1};if($===!0||$==="true"||$==="1")return{enabled:!0};let Z=String($).trim();if(!Z)return{enabled:!0};if(Z.startsWith("!"))return{enabled:!0,filter:{mode:"exclude",categories:Z.split(",").map((X)=>X.trim().replace(/^!/,"")).filter(Boolean)}};return{enabled:!0,filter:{mode:"include",categories:Z.split(",").map((Q)=>Q.trim()).filter(Boolean)}}}shouldLogCategory($){if(!$)return!0;let Z=this.category.toLowerCase();if($.mode==="include")return $.categories.some((Y)=>Z.includes(Y.toLowerCase()));return!$.categories.some((Y)=>Z.includes(Y.toLowerCase()))}shouldLogToConsole($){if(c1.globalDebugConfig!==null){let{enabled:Z,filter:Y}=this.parseDebugFilter(c1.globalDebugConfig);if(!Z)return!1;if($<this.minLevel)return!1;return this.shouldLogCategory(Y)}return this.enabled&&$>=this.minLevel}log($,...Z){let Y=Z.map((Q)=>typeof Q==="object"?JSON.stringify(Q):String(Q)).join(" ");if(eF(this.category,$,Y),this.shouldLogToConsole($)){let Q=X9[$],X=`[${this.category}] [${Q}]`;console.error(X,...Z)}}debug(...$){this.log(0,...$)}info(...$){this.log(1,...$)}warn(...$){this.log(2,...$)}error(...$){this.log(3,...$)}}function p($,Z){return new c1({...Z,category:$})}var X9,Y9=null,_X=null,zX=!1,r0;var Y0=b(()=>{((X)=>{X[X.DEBUG=0]="DEBUG";X[X.INFO=1]="INFO";X[X.WARN=2]="WARN";X[X.ERROR=3]="ERROR"})(X9||={});r0=new c1({category:"General"})});import{Mutex as wX}from"async-mutex";import{merge as $_}from"lodash-es";import{promises as g6}from"node:fs";import AX from"node:os";import Z4 from"node:path";import Z_ from"write-file-atomic";class y2{static instance=null;pendingUpdates=new Map;timers=new Map;fileLocks=new Map;lastSaveError=null;debounceDelay=300;constructor(){}static getInstance(){if(!y2.instance)y2.instance=new y2;return y2.instance}static resetInstance(){if(y2.instance)for(let $ of y2.instance.timers.values())clearTimeout($);y2.instance=null}async save($,Z={}){this.validatePersistableFields($);let Y=this.groupUpdatesByTarget($,Z.scope);if(Z.immediate)await Promise.all(Array.from(Y.entries()).map(([Q,X])=>this.flushTarget(Q,X)));else for(let[Q,X]of Y)this.scheduleSave(Q,X)}async flush(){for(let Z of this.timers.values())clearTimeout(Z);this.timers.clear();let $=Array.from(this.pendingUpdates.entries()).map(([Z,Y])=>this.flushTarget(Z,Y));this.pendingUpdates.clear(),await Promise.all($)}getLastSaveError(){return this.lastSaveError}clearLastSaveError(){this.lastSaveError=null}async appendPermissionRule($,Z={}){let Y=Z.scope??"local",Q=this.resolveFilePath("settings",Y);await this.flushTargetWithModifier(Q,(X)=>{let J=X.permissions??{allow:[],ask:[],deny:[]},G={allow:this.dedupeArray([...J.allow||[],$]),ask:J.ask||[],deny:J.deny||[]};return{...X,permissions:G}})}async appendLocalPermissionRule($,Z={}){await this.appendPermissionRule($,{...Z,scope:"local"})}validatePersistableFields($){for(let Z of Object.keys($)){let Y=I8[Z];if(!Y)throw Error(`Unknown config field: ${Z}`);if(!Y.persistable)throw Error(`Field "${Z}" is non-persistable and cannot be saved to config files. Non-persistable fields are runtime-only and only valid for the current session.`)}}groupUpdatesByTarget($,Z){let Y=new Map;for(let[Q,X]of Object.entries($)){let J=I8[Q];if(!J)continue;let G=Z??J.defaultScope,q=this.resolveFilePath(J.target,G);if(!Y.has(q))Y.set(q,{});Y.get(q)[Q]=X}return Y}resolveFilePath($,Z){if($==="config")return Z==="global"?Z4.join(AX.homedir(),".blade","config.json"):Z4.join(process.cwd(),".blade","config.json");switch(Z){case"local":return Z4.join(process.cwd(),".blade","settings.local.json");case"project":return Z4.join(process.cwd(),".blade","settings.json");case"global":return Z4.join(AX.homedir(),".blade","settings.json");default:return Z4.join(process.cwd(),".blade","settings.local.json")}}scheduleSave($,Z){let Y=this.pendingUpdates.get($)??{},Q=this.mergePendingUpdates(Y,Z);this.pendingUpdates.set($,Q);let X=this.timers.get($);if(X)clearTimeout(X);let J=setTimeout(async()=>{let G=this.pendingUpdates.get($);if(G){this.pendingUpdates.delete($),this.timers.delete($);try{await this.flushTarget($,G),this.lastSaveError=null}catch(q){let K=q instanceof Error?q:Error(String(q));this.lastSaveError=K,bX.error(`Failed to save config to ${$}:`,K.message),bX.error("Stack trace:",K.stack)}}},this.debounceDelay);this.timers.set($,J)}mergePendingUpdates($,Z){let Y={...$};for(let[Q,X]of Object.entries(Z)){let J=I8[Q];if(!J){Y[Q]=X;continue}switch(J.mergeStrategy){case"replace":Y[Q]=X;break;case"append-dedupe":this.applyAppendDedupe(Y,Q,X);break;case"deep-merge":this.applyDeepMerge(Y,Q,X);break}}return Y}async flushTarget($,Z){let Y=this.fileLocks.get($);if(!Y)Y=new wX,this.fileLocks.set($,Y);await Y.runExclusive(async()=>{await this.performWrite($,Z)})}async flushTargetWithModifier($,Z){let Y=this.fileLocks.get($);if(!Y)Y=new wX,this.fileLocks.set($,Y);await Y.runExclusive(async()=>{await g6.mkdir(Z4.dirname($),{recursive:!0,mode:493});let Q={};try{let J=await g6.readFile($,"utf-8");Q=JSON.parse(J)}catch{Q={}}let X=Z(Q);await this.atomicWrite($,X)})}async performWrite($,Z){await g6.mkdir(Z4.dirname($),{recursive:!0,mode:493});let Y={};try{let X=await g6.readFile($,"utf-8");Y=JSON.parse(X)}catch{Y={}}let Q={...Y};for(let[X,J]of Object.entries(Z)){let G=I8[X];if(!G){Q[X]=J;continue}switch(G.mergeStrategy){case"replace":Q[X]=J;break;case"append-dedupe":this.applyAppendDedupe(Q,X,J);break;case"deep-merge":this.applyDeepMerge(Q,X,J);break}}await this.atomicWrite($,Q)}applyAppendDedupe($,Z,Y){if(Z==="permissions"&&typeof Y==="object"&&Y!==null){let Q=$[Z]??{allow:[],ask:[],deny:[]},X=Y;$[Z]={allow:this.dedupeArray([...Q.allow||[],...X.allow||[]]),ask:this.dedupeArray([...Q.ask||[],...X.ask||[]]),deny:this.dedupeArray([...Q.deny||[],...X.deny||[]])}}else if(Array.isArray(Y)){let Q=Array.isArray($[Z])?$[Z]:[];$[Z]=this.dedupeArray([...Q,...Y])}else $[Z]=Y}applyDeepMerge($,Z,Y){if(typeof Y==="object"&&Y!==null&&!Array.isArray(Y)){let Q=typeof $[Z]==="object"&&$[Z]!==null?$[Z]:{};$[Z]=$_({},Q,Y)}else $[Z]=Y}dedupeArray($){return Array.from(new Set($))}async atomicWrite($,Z){await Z_($,JSON.stringify(Z,null,2),{mode:384,encoding:"utf-8"})}}function c$(){return y2.getInstance()}var bX,I8,hj,xj;var VX=b(()=>{Y0();bX=p("Service"),I8={models:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},currentModelId:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},temperature:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},maxContextTokens:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},maxOutputTokens:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},timeout:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},theme:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},uiTheme:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},language:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},debug:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},fontSize:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},autoSaveSessions:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},notifyBuild:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},notifyErrors:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},notifySounds:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},privacyTelemetry:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},privacyCrash:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},permissionMode:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},permissions:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!0},hooks:{target:"settings",defaultScope:"local",mergeStrategy:"deep-merge",persistable:!0},env:{target:"settings",defaultScope:"local",mergeStrategy:"deep-merge",persistable:!0},disableAllHooks:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!0},maxTurns:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!0},mcpServers:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},stream:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},topP:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},topK:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},mcpEnabled:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},systemPrompt:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},appendSystemPrompt:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},initialMessage:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},resumeSessionId:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},forkSession:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},allowedTools:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},disallowedTools:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},mcpConfigPaths:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},strictMcpConfig:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},addDirs:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},outputFormat:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},inputFormat:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},print:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},includePartialMessages:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},replayUserMessages:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},agentsConfig:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},settingSources:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1}},hj=new Set(Object.entries(I8).filter(([$,Z])=>Z.persistable).map(([$])=>$)),xj=new Set(Object.entries(I8).filter(([$,Z])=>!Z.persistable).map(([$])=>$))});var Y4=b(()=>{FX();VX();$9();H$()});var Y_,Q_,X_,J_,G_,q_,K_,W_,U_,H_,O_,F_,__,E2;var J9=b(()=>{Y_={name:"ayu-dark",colors:{primary:"#ffcc66",secondary:"#bae67e",accent:"#73d0ff",success:"#bae67e",warning:"#ffcc66",error:"#ff3333",info:"#73d0ff",light:"#f0f0f0",dark:"#000000",muted:"#5c6773",highlight:"#2d323b",text:{primary:"#e6e1cf",secondary:"#bae67e",muted:"#5c6773",light:"#ffffff"},background:{primary:"#0f1419",secondary:"#14191f",dark:"#000000"},border:{light:"#2d323b",dark:"#000000"},syntax:{comment:"#5c6773",string:"#bae67e",number:"#ffcc66",keyword:"#ff8f40",function:"#73d0ff",variable:"#e6e1cf",operator:"#f29e74",type:"#73d0ff",tag:"#ff8f40",attr:"#ffd580",default:"#e6e1cf"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(0, 0, 0, 0.2)",base:"0 1px 3px 0 rgba(0, 0, 0, 0.3), 0 1px 2px 0 rgba(0, 0, 0, 0.2)",lg:"0 10px 15px -3px rgba(0, 0, 0, 0.3), 0 4px 6px -2px rgba(0, 0, 0, 0.2)"}},Q_={name:"dracula",colors:{primary:"#bd93f9",secondary:"#ffb86c",accent:"#ff79c6",success:"#50fa7b",warning:"#f1fa8c",error:"#ff5555",info:"#8be9fd",light:"#f8f8f2",dark:"#282a36",muted:"#6272a4",highlight:"#44475a",text:{primary:"#f8f8f2",secondary:"#f1fa8c",muted:"#6272a4",light:"#ffffff"},background:{primary:"#282a36",secondary:"#44475a",dark:"#21222c"},border:{light:"#44475a",dark:"#000000"},syntax:{comment:"#6272a4",string:"#f1fa8c",number:"#bd93f9",keyword:"#ff79c6",function:"#50fa7b",variable:"#f8f8f2",operator:"#ff79c6",type:"#8be9fd",tag:"#ff79c6",attr:"#50fa7b",default:"#f8f8f2"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(40, 42, 54, 0.2)",base:"0 1px 3px 0 rgba(40, 42, 54, 0.3), 0 1px 2px 0 rgba(40, 42, 54, 0.2)",lg:"0 10px 15px -3px rgba(40, 42, 54, 0.3), 0 4px 6px -2px rgba(40, 42, 54, 0.2)"}},X_={name:"monokai",colors:{primary:"#66d9ef",secondary:"#a6e22e",accent:"#f92672",success:"#a6e22e",warning:"#e6db74",error:"#f92672",info:"#66d9ef",light:"#f8f8f2",dark:"#272822",muted:"#75715e",highlight:"#3e3d32",text:{primary:"#f8f8f2",secondary:"#e6db74",muted:"#75715e",light:"#ffffff"},background:{primary:"#272822",secondary:"#3e3d32",dark:"#1e1f1c"},border:{light:"#3e3d32",dark:"#000000"},syntax:{comment:"#75715e",string:"#e6db74",number:"#ae81ff",keyword:"#f92672",function:"#a6e22e",variable:"#f8f8f2",operator:"#f92672",type:"#66d9ef",tag:"#f92672",attr:"#a6e22e",default:"#f8f8f2"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(39, 40, 34, 0.2)",base:"0 1px 3px 0 rgba(39, 40, 34, 0.3), 0 1px 2px 0 rgba(39, 40, 34, 0.2)",lg:"0 10px 15px -3px rgba(39, 40, 34, 0.3), 0 4px 6px -2px rgba(39, 40, 34, 0.2)"}},J_={name:"nord",colors:{primary:"#88c0d0",secondary:"#81a1c1",accent:"#b48ead",success:"#a3be8c",warning:"#ebcb8b",error:"#bf616a",info:"#88c0d0",light:"#eceff4",dark:"#2e3440",muted:"#4c566a",highlight:"#434c5e",text:{primary:"#eceff4",secondary:"#d8dee9",muted:"#4c566a",light:"#ffffff"},background:{primary:"#2e3440",secondary:"#3b4252",dark:"#242933"},border:{light:"#434c5e",dark:"#000000"},syntax:{comment:"#616e88",string:"#a3be8c",number:"#b48ead",keyword:"#81a1c1",function:"#88c0d0",variable:"#d8dee9",operator:"#81a1c1",type:"#8fbcbb",tag:"#81a1c1",attr:"#8fbcbb",default:"#eceff4"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(46, 52, 64, 0.2)",base:"0 1px 3px 0 rgba(46, 52, 64, 0.3), 0 1px 2px 0 rgba(46, 52, 64, 0.2)",lg:"0 10px 15px -3px rgba(46, 52, 64, 0.3), 0 4px 6px -2px rgba(46, 52, 64, 0.2)"}},G_={name:"solarized-light",colors:{primary:"#268bd2",secondary:"#2aa198",accent:"#d33682",success:"#859900",warning:"#b58900",error:"#dc322f",info:"#268bd2",light:"#fdf6e3",dark:"#073642",muted:"#93a1a1",highlight:"#eee8d5",text:{primary:"#586e75",secondary:"#657b83",muted:"#93a1a1",light:"#002b36"},background:{primary:"#fdf6e3",secondary:"#eee8d5",dark:"#073642"},border:{light:"#eee8d5",dark:"#073642"},syntax:{comment:"#93a1a1",string:"#2aa198",number:"#d33682",keyword:"#859900",function:"#268bd2",variable:"#657b83",operator:"#859900",type:"#b58900",tag:"#268bd2",attr:"#93a1a1",default:"#657b83"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(253, 246, 227, 0.2)",base:"0 1px 3px 0 rgba(253, 246, 227, 0.3), 0 1px 2px 0 rgba(253, 246, 227, 0.2)",lg:"0 10px 15px -3px rgba(253, 246, 227, 0.3), 0 4px 6px -2px rgba(253, 246, 227, 0.2)"}},q_={name:"solarized-dark",colors:{primary:"#268bd2",secondary:"#2aa198",accent:"#d33682",success:"#859900",warning:"#b58900",error:"#dc322f",info:"#268bd2",light:"#fdf6e3",dark:"#073642",muted:"#586e75",highlight:"#073642",text:{primary:"#839496",secondary:"#93a1a1",muted:"#586e75",light:"#fdf6e3"},background:{primary:"#002b36",secondary:"#073642",dark:"#001f29"},border:{light:"#073642",dark:"#000000"},syntax:{comment:"#586e75",string:"#2aa198",number:"#d33682",keyword:"#859900",function:"#268bd2",variable:"#839496",operator:"#859900",type:"#b58900",tag:"#268bd2",attr:"#93a1a1",default:"#839496"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(0, 43, 54, 0.2)",base:"0 1px 3px 0 rgba(0, 43, 54, 0.3), 0 1px 2px 0 rgba(0, 43, 54, 0.2)",lg:"0 10px 15px -3px rgba(0, 43, 54, 0.3), 0 4px 6px -2px rgba(0, 43, 54, 0.2)"}},K_={name:"tokyo-night",colors:{primary:"#7aa2f7",secondary:"#7dcfff",accent:"#bb9af7",success:"#9ece6a",warning:"#e0af68",error:"#f7768e",info:"#7aa2f7",light:"#c0caf5",dark:"#1a1b26",muted:"#565f89",highlight:"#292e42",text:{primary:"#a9b1d6",secondary:"#c0caf5",muted:"#565f89",light:"#ffffff"},background:{primary:"#1a1b26",secondary:"#292e42",dark:"#16161e"},border:{light:"#292e42",dark:"#000000"},syntax:{comment:"#565f89",string:"#9ece6a",number:"#ff9e64",keyword:"#bb9af7",function:"#7aa2f7",variable:"#c0caf5",operator:"#89ddff",type:"#7dcfff",tag:"#f7768e",attr:"#7aa2f7",default:"#a9b1d6"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(26, 27, 38, 0.2)",base:"0 1px 3px 0 rgba(26, 27, 38, 0.3), 0 1px 2px 0 rgba(26, 27, 38, 0.2)",lg:"0 10px 15px -3px rgba(26, 27, 38, 0.3), 0 4px 6px -2px rgba(26, 27, 38, 0.2)"}},W_={name:"github",colors:{primary:"#0969da",secondary:"#8250df",accent:"#bc4c00",success:"#1a7f37",warning:"#9a6700",error:"#d1242f",info:"#0969da",light:"#f6f8fa",dark:"#24292f",muted:"#6e7781",highlight:"#ddf4ff",text:{primary:"#24292f",secondary:"#57606a",muted:"#6e7781",light:"#ffffff"},background:{primary:"#ffffff",secondary:"#f6f8fa",dark:"#24292f"},border:{light:"#d0d7de",dark:"#24292f"},syntax:{comment:"#6e7781",string:"#0a3069",number:"#0550ae",keyword:"#cf222e",function:"#8250df",variable:"#24292f",operator:"#cf222e",type:"#0550ae",tag:"#116329",attr:"#0550ae",default:"#24292f"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(255, 255, 255, 0.2)",base:"0 1px 3px 0 rgba(255, 255, 255, 0.3), 0 1px 2px 0 rgba(255, 255, 255, 0.2)",lg:"0 10px 15px -3px rgba(255, 255, 255, 0.3), 0 4px 6px -2px rgba(255, 255, 255, 0.2)"}},U_={name:"gruvbox",colors:{primary:"#83a598",secondary:"#8ec07c",accent:"#d3869b",success:"#b8bb26",warning:"#fabd2f",error:"#fb4934",info:"#83a598",light:"#fbf1c7",dark:"#282828",muted:"#928374",highlight:"#3c3836",text:{primary:"#ebdbb2",secondary:"#d5c4a1",muted:"#928374",light:"#ffffff"},background:{primary:"#282828",secondary:"#3c3836",dark:"#1d2021"},border:{light:"#3c3836",dark:"#000000"},syntax:{comment:"#928374",string:"#b8bb26",number:"#d3869b",keyword:"#fb4934",function:"#8ec07c",variable:"#ebdbb2",operator:"#fe8019",type:"#fabd2f",tag:"#fb4934",attr:"#b8bb26",default:"#ebdbb2"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(40, 40, 40, 0.2)",base:"0 1px 3px 0 rgba(40, 40, 40, 0.3), 0 1px 2px 0 rgba(40, 40, 40, 0.2)",lg:"0 10px 15px -3px rgba(40, 40, 40, 0.3), 0 4px 6px -2px rgba(40, 40, 40, 0.2)"}},H_={name:"one-dark",colors:{primary:"#61afef",secondary:"#c678dd",accent:"#e5c07b",success:"#98c379",warning:"#e5c07b",error:"#e06c75",info:"#56b6c2",light:"#abb2bf",dark:"#282c34",muted:"#5c6370",highlight:"#3e4451",text:{primary:"#abb2bf",secondary:"#c6c8d0",muted:"#5c6370",light:"#ffffff"},background:{primary:"#282c34",secondary:"#3e4451",dark:"#21252b"},border:{light:"#3e4451",dark:"#000000"},syntax:{comment:"#5c6370",string:"#98c379",number:"#d19a66",keyword:"#c678dd",function:"#61afef",variable:"#e06c75",operator:"#56b6c2",type:"#e5c07b",tag:"#e06c75",attr:"#d19a66",default:"#abb2bf"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(40, 44, 52, 0.2)",base:"0 1px 3px 0 rgba(40, 44, 52, 0.3), 0 1px 2px 0 rgba(40, 44, 52, 0.2)",lg:"0 10px 15px -3px rgba(40, 44, 52, 0.3), 0 4px 6px -2px rgba(40, 44, 52, 0.2)"}},O_={name:"catppuccin",colors:{primary:"#89b4fa",secondary:"#cba6f7",accent:"#f5c2e7",success:"#a6e3a1",warning:"#f9e2af",error:"#f38ba8",info:"#89dceb",light:"#cdd6f4",dark:"#11111b",muted:"#6c7086",highlight:"#181825",text:{primary:"#cdd6f4",secondary:"#bac2de",muted:"#6c7086",light:"#ffffff"},background:{primary:"#1e1e2e",secondary:"#181825",dark:"#11111b"},border:{light:"#181825",dark:"#000000"},syntax:{comment:"#6c7086",string:"#a6e3a1",number:"#fab387",keyword:"#cba6f7",function:"#89b4fa",variable:"#cdd6f4",operator:"#89dceb",type:"#f5c2e7",tag:"#f38ba8",attr:"#89b4fa",default:"#cdd6f4"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(30, 30, 46, 0.2)",base:"0 1px 3px 0 rgba(30, 30, 46, 0.3), 0 1px 2px 0 rgba(30, 30, 46, 0.2)",lg:"0 10px 15px -3px rgba(30, 30, 46, 0.3), 0 4px 6px -2px rgba(30, 30, 46, 0.2)"}},F_={name:"rose-pine",colors:{primary:"#9ccfd8",secondary:"#c4a7e7",accent:"#f6c177",success:"#31748f",warning:"#f6c177",error:"#eb6f92",info:"#9ccfd8",light:"#e0def4",dark:"#191724",muted:"#6e6a86",highlight:"#1f1d2e",text:{primary:"#e0def4",secondary:"#cecacd",muted:"#6e6a86",light:"#ffffff"},background:{primary:"#191724",secondary:"#1f1d2e",dark:"#12101a"},border:{light:"#1f1d2e",dark:"#000000"},syntax:{comment:"#6e6a86",string:"#9ccfd8",number:"#ea9a97",keyword:"#c4a7e7",function:"#31748f",variable:"#e0def4",operator:"#f6c177",type:"#9ccfd8",tag:"#eb6f92",attr:"#f6c177",default:"#e0def4"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(25, 23, 36, 0.2)",base:"0 1px 3px 0 rgba(25, 23, 36, 0.3), 0 1px 2px 0 rgba(25, 23, 36, 0.2)",lg:"0 10px 15px -3px rgba(25, 23, 36, 0.3), 0 4px 6px -2px rgba(25, 23, 36, 0.2)"}},__={name:"kanagawa",colors:{primary:"#8ba4b0",secondary:"#a292a3",accent:"#c47fd5",success:"#76946a",warning:"#c0a36e",error:"#c34043",info:"#7e9cd8",light:"#dcd7ba",dark:"#1f1f28",muted:"#727169",highlight:"#2a2a37",text:{primary:"#dcd7ba",secondary:"#c8c093",muted:"#727169",light:"#ffffff"},background:{primary:"#1f1f28",secondary:"#2a2a37",dark:"#16161d"},border:{light:"#2a2a37",dark:"#000000"},syntax:{comment:"#727169",string:"#98bb6c",number:"#d27e99",keyword:"#957fb8",function:"#7e9cd8",variable:"#dcd7ba",operator:"#c0a36e",type:"#7aa89f",tag:"#c34043",attr:"#7fb4ca",default:"#dcd7ba"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(31, 31, 40, 0.2)",base:"0 1px 3px 0 rgba(31, 31, 40, 0.3), 0 1px 2px 0 rgba(31, 31, 40, 0.2)",lg:"0 10px 15px -3px rgba(31, 31, 40, 0.3), 0 4px 6px -2px rgba(31, 31, 40, 0.2)"}},E2=[{id:"ayu-dark",label:"Ayu Dark",theme:Y_,tags:["dark","popular"]},{id:"dracula",label:"Dracula",theme:Q_,tags:["dark","popular"]},{id:"monokai",label:"Monokai",theme:X_,tags:["dark","classic"]},{id:"nord",label:"Nord",theme:J_,tags:["dark","minimal"]},{id:"solarized-light",label:"Solarized Light",theme:G_,tags:["light"]},{id:"solarized-dark",label:"Solarized Dark",theme:q_,tags:["dark"]},{id:"tokyo-night",label:"Tokyo Night",theme:K_,tags:["dark","popular"]},{id:"github",label:"GitHub",theme:W_,tags:["light","minimal"]},{id:"gruvbox",label:"Gruvbox",theme:U_,tags:["dark","warm"]},{id:"one-dark",label:"One Dark",theme:H_,tags:["dark","popular"]},{id:"catppuccin",label:"Catppuccin",theme:O_,tags:["dark","pastel"]},{id:"rose-pine",label:"Rose Pine",theme:F_,tags:["dark","elegant"]},{id:"kanagawa",label:"Kanagawa",theme:__,tags:["dark","japanese"]}]});class DX{currentTheme=G9;themes=new Map;constructor(){this.themes.set("default",G9),this.themes.set("dark",z_);for(let $ of E2)this.themes.set($.id,$.theme)}setTheme($){let Z=this.themes.get($);if(Z)this.currentTheme=Z;else throw Error(`Theme '${$}' not found`)}getTheme(){return this.currentTheme}getAvailableThemes(){return Array.from(this.themes.keys())}getCurrentThemeName(){return this.currentTheme.name}getThemeByName($){return this.themes.get($)}hasTheme($){return this.themes.has($)}}var RX,G9,z_,E$;var I2=b(()=>{J9();RX={primary:"#0066cc",secondary:"#6c757d",accent:"#e83e8c",success:"#28a745",warning:"#ffc107",error:"#dc3545",info:"#17a2b8",light:"#f8f9fa",dark:"#343a40",muted:"#6c757d",highlight:"#fff3cd",text:{primary:"#212529",secondary:"#6c757d",muted:"#6c757d",light:"#ffffff"},background:{primary:"#ffffff",secondary:"#f8f9fa",dark:"#343a40"},border:{light:"#dee2e6",dark:"#495057"},syntax:{comment:"#6c757d",string:"#28a745",number:"#e83e8c",keyword:"#007bff",function:"#17a2b8",variable:"#495057",operator:"#ffc107",type:"#007bff",tag:"#dc3545",attr:"#ffc107",default:"#212529"}},G9={name:"default",colors:RX,spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(0, 0, 0, 0.05)",base:"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)",lg:"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"}},z_={...G9,name:"dark",colors:{...RX,text:{primary:"#ffffff",secondary:"#e2e8f0",muted:"#94a3b8",light:"#000000"},background:{primary:"#1e293b",secondary:"#334155",dark:"#0f172a"},border:{light:"#475569",dark:"#64748b"},syntax:{comment:"#94a3b8",string:"#34d399",number:"#f472b6",keyword:"#60a5fa",function:"#06b6d4",variable:"#e2e8f0",operator:"#fbbf24",type:"#60a5fa",tag:"#fb7185",attr:"#fbbf24",default:"#ffffff"}}};E$=new DX});var B_,q9=($)=>({...B_,actions:{setInitializationStatus:(Z)=>{$((Y)=>({app:{...Y.app,initializationStatus:Z}}))},setInitializationError:(Z)=>{$((Y)=>({app:{...Y.app,initializationError:Z}}))},setActiveModal:(Z)=>{$((Y)=>({app:{...Y.app,activeModal:Z}}))},showSessionSelector:(Z)=>{$((Y)=>({app:{...Y.app,activeModal:"sessionSelector",sessionSelectorData:Z}}))},showModelEditWizard:(Z)=>{$((Y)=>({app:{...Y.app,activeModal:"modelEditWizard",modelEditorTarget:Z}}))},closeModal:()=>{$((Z)=>({app:{...Z.app,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null}}))},setTodos:(Z)=>{$((Y)=>({app:{...Y.app,todos:Z}}))},updateTodo:(Z)=>{$((Y)=>({app:{...Y.app,todos:Y.app.todos.map((Q)=>Q.id===Z.id?Z:Q)}}))},setAwaitingSecondCtrlC:(Z)=>{$((Y)=>({app:{...Y.app,awaitingSecondCtrlC:Z}}))},setThinkingModeEnabled:(Z)=>{$((Y)=>({app:{...Y.app,thinkingModeEnabled:Z}}))},toggleThinkingMode:()=>{$((Z)=>({app:{...Z.app,thinkingModeEnabled:!Z.app.thinkingModeEnabled}}))},startSubagentProgress:(Z,Y,Q)=>{$((X)=>({app:{...X.app,subagentProgress:{id:Z,type:Y,description:Q,status:"running",startTime:Date.now()}}}))},updateSubagentTool:(Z)=>{$((Y)=>{if(!Y.app.subagentProgress)return Y;return{app:{...Y.app,subagentProgress:{...Y.app.subagentProgress,currentTool:Z}}}})},completeSubagentProgress:(Z)=>{$((Y)=>{if(!Y.app.subagentProgress)return Y;return{app:{...Y.app,subagentProgress:{...Y.app.subagentProgress,status:Z?"completed":"failed",currentTool:void 0}}}}),setTimeout(()=>{$((Y)=>({app:{...Y.app,subagentProgress:null}}))},1500)}}});var MX=b(()=>{B_={initializationStatus:"idle",initializationError:null,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null,todos:[],awaitingSecondCtrlC:!1,thinkingModeEnabled:!1,subagentProgress:null}});var N_,K9=($,Z)=>({...N_,actions:{setProcessing:(Y)=>{$((Q)=>({command:{...Q.command,isProcessing:Y}}))},createAbortController:()=>{let Y=Z().command.abortController;if(Y&&!Y.signal.aborted)return Y;let Q=new AbortController;return $((X)=>({command:{...X.command,abortController:Q}})),Q},getAbortController:()=>{return Z().command.abortController},clearAbortController:(Y)=>{let Q=Z().command.abortController;if(Y!==void 0&&Q!==Y)return;$((X)=>({command:{...X.command,abortController:null}}))},abort:()=>{let{abortController:Y}=Z().command;if(Y&&!Y.signal.aborted)Y.abort();$((Q)=>({command:{...Q.command,isProcessing:!1,pendingCommands:[]}}))},enqueueCommand:(Y)=>{$((Q)=>({command:{...Q.command,pendingCommands:[...Q.command.pendingCommands,Y]}}))},dequeueCommand:()=>{let{pendingCommands:Y}=Z().command;if(Y.length===0)return;let[Q,...X]=Y;return $((J)=>({command:{...J.command,pendingCommands:X}})),Q},clearQueue:()=>{$((Y)=>({command:{...Y.command,pendingCommands:[]}}))}}});var jX=b(()=>{N_={isProcessing:!1,abortController:null,pendingCommands:[]}});var L_,W9=($)=>({...L_,actions:{setConfig:(Z)=>{$((Y)=>({config:{...Y.config,config:Z}}))},updateConfig:(Z)=>{$((Y)=>{if(!Y.config.config)throw Error(`[ConfigSlice] Config not initialized. Cannot update: ${JSON.stringify(Z)}`);return{config:{...Y.config,config:{...Y.config.config,...Z}}}})}}});var TX=b(()=>{L_={config:null}});var w_,U9=($)=>({...w_,actions:{setFocus:(Z)=>{$((Y)=>({focus:{...Y.focus,currentFocus:Z,previousFocus:Y.focus.currentFocus}}))},restorePreviousFocus:()=>{$((Z)=>({focus:{...Z.focus,currentFocus:Z.focus.previousFocus||"main-input",previousFocus:null}}))}}});var yX=b(()=>{w_={currentFocus:"main-input",previousFocus:null}});function p4($){let Z=[],Y=$.split(/\r?\n/),Q=!1,X=[],J=null,G=0,q=!1,K=[],W=[],U=!1,H=[],O=!0;for(let F=0;F<Y.length;F++){let _=Y[F];if(U){if(_.match(I0.diffEnd)){try{let T=JSON.parse(H.join(`
|
|
27
27
|
`));Z.push({type:"diff",content:"",diffData:{patch:T.patch,startLine:T.startLine,matchLine:T.matchLine}})}catch(T){Z.push({type:"text",content:H.join(`
|
|
28
28
|
`)})}U=!1,H=[],O=!1;continue}H.push(_);continue}if(_.match(I0.diffStart)){U=!0,H=[],O=!1;continue}if(Q){let T=_.match(I0.codeBlock),w=_.trim()==="```";if(T&&T[1])G++,X.push(_);else if(w)if(G>0)G--,X.push(_);else{let v=X.join(`
|
|
29
29
|
`);if(J?.toLowerCase()==="markdown"||J?.toLowerCase()==="md"){let l=p4(v);Z.push(...l)}else Z.push({type:"code",content:v,language:J||void 0});Q=!1,X=[],J=null,G=0,O=!1}else X.push(_);continue}let z=_.match(I0.codeBlock);if(z){Q=!0,J=z[1]||null,G=0,O=!1;continue}let N=_.match(I0.table),B=_.match(I0.tableSeparator);if(N&&!q){if(F+1<Y.length){if(Y[F+1].match(I0.tableSeparator)){q=!0,K=N[1].split("|").map((w)=>w.trim()).filter((w)=>w.length>0),W=[],O=!1;continue}}}if(q&&B)continue;if(q&&N){let T=N[1].split("|").map((w)=>w.trim()).filter((w)=>w.length>0);while(T.length<K.length)T.push("");if(T.length>K.length)T.length=K.length;W.push(T);continue}if(q&&!N){if(K.length>0&&W.length>0)Z.push({type:"table",content:"",tableData:{headers:K,rows:W}});q=!1,K=[],W=[]}let L=_.match(I0.heading);if(L){Z.push({type:"heading",content:L[2],level:L[1].length}),O=!1;continue}let A=_.match(I0.ulItem);if(A){Z.push({type:"list",content:A[3],listType:"ul",marker:A[2],indentation:A[1].length}),O=!1;continue}let R=_.match(I0.olItem);if(R){Z.push({type:"list",content:R[3],listType:"ol",marker:R[2],indentation:R[1].length}),O=!1;continue}if(_.match(I0.hr)){Z.push({type:"hr",content:""}),O=!1;continue}if(_.trim().length===0){if(!O)Z.push({type:"empty",content:""}),O=!0;continue}let M=_.match(I0.commandMessage);if(M){Z.push({type:"command-message",content:M[1]}),O=!1;continue}Z.push({type:"text",content:_}),O=!1}if(Q){let F=X.join(`
|
|
30
|
-
`);if(J?.toLowerCase()==="markdown"||J?.toLowerCase()==="md"){let _=p4(F);Z.push(..._)}else Z.push({type:"code",content:F,language:J||void 0})}if(q&&K.length>0&&W.length>0)Z.push({type:"table",content:"",tableData:{headers:K,rows:W}});while(Z.length>0&&Z[Z.length-1].type==="empty")Z.pop();return Z}var I0;var
|
|
31
|
-
`);if($.codeBlockLang?.toLowerCase()==="markdown"||$.codeBlockLang?.toLowerCase()==="md")Z.push(...p4(Y));else Z.push({type:"code",content:Y,language:$.codeBlockLang||void 0});$.inCodeBlock=!1,$.codeBlockContent=[],$.codeBlockLang=null,$.codeBlockDepth=0,$.lastLineEmpty=!1}function
|
|
30
|
+
`);if(J?.toLowerCase()==="markdown"||J?.toLowerCase()==="md"){let _=p4(F);Z.push(..._)}else Z.push({type:"code",content:F,language:J||void 0})}if(q&&K.length>0&&W.length>0)Z.push({type:"table",content:"",tableData:{headers:K,rows:W}});while(Z.length>0&&Z[Z.length-1].type==="empty")Z.pop();return Z}var I0;var H9=b(()=>{I0={codeBlock:/^```(\w+)?\s*$/,heading:/^ *(#{1,4}) +(.+)/,ulItem:/^([ \t]*)([-*+]) +(.+)/,olItem:/^([ \t]*)(\d+)\. +(.+)/,hr:/^ *([-*_] *){3,} *$/,table:/^\|(.+)\|$/,tableSeparator:/^\|[\s]*:?-+:?[\s]*(\|[\s]*:?-+:?[\s]*)+\|?$/,diffStart:/^<<<DIFF>>>$/,diffEnd:/^<<<\/DIFF>>>$/,commandMessage:/<command-message>(.*?)<\/command-message>/}});function A_(){return{inCodeBlock:!1,codeBlockContent:[],codeBlockLang:null,codeBlockDepth:0,inTable:!1,tableHeaders:[],tableRows:[],inDiff:!1,diffContent:[],lastLineEmpty:!0,pendingTableHeader:null}}function b_($){let Z=P2.get($);if(Z)return Z;let Y={state:A_(),blocks:[],pendingLine:"",finalized:!1};return P2.set($,Y),Y}function EX($){return $.endsWith("\r")?$.slice(0,-1):$}function IX($,Z){if($.tableHeaders.length>0&&$.tableRows.length>0)Z.push({type:"table",content:"",tableData:{headers:$.tableHeaders,rows:$.tableRows}});$.inTable=!1,$.tableHeaders=[],$.tableRows=[]}function PX($,Z){let Y=$.codeBlockContent.join(`
|
|
31
|
+
`);if($.codeBlockLang?.toLowerCase()==="markdown"||$.codeBlockLang?.toLowerCase()==="md")Z.push(...p4(Y));else Z.push({type:"code",content:Y,language:$.codeBlockLang||void 0});$.inCodeBlock=!1,$.codeBlockContent=[],$.codeBlockLang=null,$.codeBlockDepth=0,$.lastLineEmpty=!1}function O9($,Z,Y=!0){let{state:Q,blocks:X}=Z;if(Q.pendingTableHeader!==null){if($.match(I0.tableSeparator)){Q.inTable=!0,Q.tableHeaders=Q.pendingTableHeader.slice(1,-1).split("|").map((F)=>F.trim()).filter((F)=>F.length>0),Q.tableRows=[],Q.pendingTableHeader=null,Q.lastLineEmpty=!1;return}X.push({type:"text",content:Q.pendingTableHeader}),Q.pendingTableHeader=null,Q.lastLineEmpty=!1}if(Q.inDiff){if($.match(I0.diffEnd)){try{let F=JSON.parse(Q.diffContent.join(`
|
|
32
32
|
`));X.push({type:"diff",content:"",diffData:{patch:F.patch,startLine:F.startLine,matchLine:F.matchLine}})}catch(F){X.push({type:"text",content:Q.diffContent.join(`
|
|
33
|
-
`)})}Q.inDiff=!1,Q.diffContent=[],Q.lastLineEmpty=!1;return}Q.diffContent.push($);return}if($.match(I0.diffStart)){Q.inDiff=!0,Q.diffContent=[],Q.lastLineEmpty=!1;return}if(Q.inCodeBlock){let F=$.match(I0.codeBlock),_=$.trim()==="```";if(F&&F[1])Q.codeBlockDepth++,Q.codeBlockContent.push($);else if(_)if(Q.codeBlockDepth>0)Q.codeBlockDepth--,Q.codeBlockContent.push($);else PX(Q,X);else Q.codeBlockContent.push($);return}let J=$.match(I0.codeBlock);if(J){Q.inCodeBlock=!0,Q.codeBlockLang=J[1]||null,Q.codeBlockDepth=0,Q.lastLineEmpty=!1;return}let G=$.match(I0.table),q=$.match(I0.tableSeparator);if(G&&!Q.inTable){Q.pendingTableHeader=$;return}if(Q.inTable&&q)return;if(Q.inTable&&G){let F=G[1].split("|").map((_)=>_.trim()).filter((_)=>_.length>0);while(F.length<Q.tableHeaders.length)F.push("");if(F.length>Q.tableHeaders.length)F.length=Q.tableHeaders.length;Q.tableRows.push(F);return}if(Q.inTable&&!G){if(IX(Q,X),Y){
|
|
33
|
+
`)})}Q.inDiff=!1,Q.diffContent=[],Q.lastLineEmpty=!1;return}Q.diffContent.push($);return}if($.match(I0.diffStart)){Q.inDiff=!0,Q.diffContent=[],Q.lastLineEmpty=!1;return}if(Q.inCodeBlock){let F=$.match(I0.codeBlock),_=$.trim()==="```";if(F&&F[1])Q.codeBlockDepth++,Q.codeBlockContent.push($);else if(_)if(Q.codeBlockDepth>0)Q.codeBlockDepth--,Q.codeBlockContent.push($);else PX(Q,X);else Q.codeBlockContent.push($);return}let J=$.match(I0.codeBlock);if(J){Q.inCodeBlock=!0,Q.codeBlockLang=J[1]||null,Q.codeBlockDepth=0,Q.lastLineEmpty=!1;return}let G=$.match(I0.table),q=$.match(I0.tableSeparator);if(G&&!Q.inTable){Q.pendingTableHeader=$;return}if(Q.inTable&&q)return;if(Q.inTable&&G){let F=G[1].split("|").map((_)=>_.trim()).filter((_)=>_.length>0);while(F.length<Q.tableHeaders.length)F.push("");if(F.length>Q.tableHeaders.length)F.length=Q.tableHeaders.length;Q.tableRows.push(F);return}if(Q.inTable&&!G){if(IX(Q,X),Y){O9($,Z,!1);return}}let K=$.match(I0.heading);if(K){X.push({type:"heading",content:K[2],level:K[1].length}),Q.lastLineEmpty=!1;return}let W=$.match(I0.ulItem);if(W){X.push({type:"list",content:W[3],listType:"ul",marker:W[2],indentation:W[1].length}),Q.lastLineEmpty=!1;return}let U=$.match(I0.olItem);if(U){X.push({type:"list",content:U[3],listType:"ol",marker:U[2],indentation:U[1].length}),Q.lastLineEmpty=!1;return}if($.match(I0.hr)){X.push({type:"hr",content:""}),Q.lastLineEmpty=!1;return}if($.trim().length===0){if(!Q.lastLineEmpty)X.push({type:"empty",content:""}),Q.lastLineEmpty=!0;return}let O=$.match(I0.commandMessage);if(O){X.push({type:"command-message",content:O[1]}),Q.lastLineEmpty=!1;return}X.push({type:"text",content:$}),Q.lastLineEmpty=!1}function F9($,Z){if(!$||!Z)return;let Y=b_($);if(Y.finalized)return;let Q=Y.pendingLine+Z,X=Q.split(`
|
|
34
34
|
`),J=Q.endsWith(`
|
|
35
|
-
`),G=J?X:X.slice(0,-1);Y.pendingLine=J?"":X[X.length-1]??"";for(let q of G)
|
|
36
|
-
`)}),Z.state.inDiff=!1,Z.state.diffContent=[];while(Z.blocks.length>0&&Z.blocks[Z.blocks.length-1].type==="empty")Z.blocks.pop();Z.finalized=!0}function vX($){let Z=P2.get($);if(!Z||!Z.finalized)return null;return Z.blocks}function
|
|
37
|
-
`),F=O.slice(0,-1).map(G),_=G(O[O.length-1]??""),z=q;if(F.length>0){if(z=[...q,...F],z.length>SX){let N=z.length-SX;z=z.slice(N)}}return{session:{...J.session,currentStreamingMessageId:X,currentStreamingLines:z,currentStreamingTail:_,currentStreamingLineCount:W+F.length,currentStreamingVersion:U+1,error:null}}}),X},finalizeStreamingMessage:(Y,Q)=>{let X=D_();$((J)=>{let G=J.session.currentStreamingMessageId,K=X.join("")+(Y||""),W=(J.session.currentThinkingContent||"")+(Q||"");if(K.length>0){let U={id:G||`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:K,timestamp:Date.now(),thinkingContent:W||void 0};return{session:{...J.session,messages:[...J.session.messages,U],currentStreamingMessageId:null,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,currentThinkingContent:null,finalizingStreamingMessageId:U.id}}}return{session:{...J.session,currentStreamingMessageId:null,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,currentThinkingContent:null,finalizingStreamingMessageId:null}}})},clearFinalizingStreamingMessageId:()=>{$((Y)=>({session:{...Y.session,finalizingStreamingMessageId:null}}))}}});var xX=b(()=>{y3();d6=[];hX={inputTokens:0,outputTokens:0,totalTokens:0,maxContextTokens:200000},fX={sessionId:R_(),messages:[],isCompacting:!1,currentCommand:null,error:null,isActive:!0,tokenUsage:{...hX},currentThinkingContent:null,thinkingExpanded:!1,clearCount:0,historyExpanded:!1,expandedMessageCount:100,currentStreamingMessageId:null,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,finalizingStreamingMessageId:null}});var pX,m4,g4,F2,h$,mX;var l1=b(()=>{pX={proposal:"proposal.md",spec:"spec.md",requirements:"requirements.md",design:"design.md",tasks:"tasks.md",meta:".meta.json"},m4={SPECS:"specs",CHANGES:"changes",ARCHIVE:"archive",STEERING:"steering",SPEC_DELTA:"specs"},g4={CONSTITUTION:"constitution.md",PRODUCT:"product.md",TECH:"tech.md",STRUCTURE:"structure.md"},F2={init:["requirements"],requirements:["design","tasks"],design:["tasks"],tasks:["implementation"],implementation:["done","tasks"],done:[]},h$={init:"初始化",requirements:"需求定义",design:"架构设计",tasks:"任务分解",implementation:"实现中",done:"已完成"},mX={init:"proposal",requirements:"requirements",design:"design",tasks:"tasks",implementation:"tasks",done:null}});import{promises as x$}from"node:fs";import*as d0 from"node:path";import{fileURLToPath as M_}from"node:url";import{nanoid as j_}from"nanoid";var T_,y_,gX,u4;var
|
|
35
|
+
`),G=J?X:X.slice(0,-1);Y.pendingLine=J?"":X[X.length-1]??"";for(let q of G)O9(EX(q),Y)}function _9($){let Z=P2.get($);if(!Z||Z.finalized)return;if(Z.pendingLine)O9(EX(Z.pendingLine),Z),Z.pendingLine="";if(Z.state.pendingTableHeader!==null)Z.blocks.push({type:"text",content:Z.state.pendingTableHeader}),Z.state.pendingTableHeader=null;if(Z.state.inCodeBlock)PX(Z.state,Z.blocks);if(Z.state.inTable)IX(Z.state,Z.blocks);if(Z.state.inDiff)Z.blocks.push({type:"text",content:Z.state.diffContent.join(`
|
|
36
|
+
`)}),Z.state.inDiff=!1,Z.state.diffContent=[];while(Z.blocks.length>0&&Z.blocks[Z.blocks.length-1].type==="empty")Z.blocks.pop();Z.finalized=!0}function vX($){let Z=P2.get($);if(!Z||!Z.finalized)return null;return Z.blocks}function z9($){let Z=P2.get($);if(!Z)return null;return Z.blocks}function V_($){let Z=P2.get($);if(!Z)return null;let Y=[],Q=Z.state;if(Q.inDiff)Y.push("<<<DIFF>>>"),Y.push(...Q.diffContent);else if(Q.inCodeBlock){let X=Q.codeBlockLang?`\`\`\`${Q.codeBlockLang}`:"```";Y.push(X),Y.push(...Q.codeBlockContent)}else if(Q.inTable){if(Q.tableHeaders.length>0){Y.push(`| ${Q.tableHeaders.join(" | ")} |`),Y.push(`| ${Q.tableHeaders.map(()=>"---").join(" | ")} |`);for(let X of Q.tableRows)Y.push(`| ${X.join(" | ")} |`)}}else if(Q.pendingTableHeader)Y.push(Q.pendingTableHeader);if(Z.pendingLine)Y.push(Z.pendingLine);return Y.length>0?Y:null}function CX($){let Z=P2.get($);if(!Z)return null;let Y="text";if(Z.state.inDiff)Y="diff";else if(Z.state.inCodeBlock)Y="code";else if(Z.state.inTable||Z.state.pendingTableHeader)Y="table";let Q=V_($);if(!Q||Q.length===0)return null;return{lines:Q,mode:Y}}function kX($){P2.delete($)}function u6(){P2.clear()}var P2;var y3=b(()=>{H9();P2=new Map});import{nanoid as R_}from"nanoid";function D_(){let $=d6;return d6=[],$}var SX=2000,d6,hX,fX,B9=($,Z)=>({...fX,actions:{addMessage:(Y)=>{$((Q)=>({session:{...Q.session,messages:[...Q.session.messages,Y],error:null}}))},addUserMessage:(Y)=>{let Q={id:`user-${Date.now()}-${Math.random()}`,role:"user",content:Y,timestamp:Date.now()};Z().session.actions.addMessage(Q)},addAssistantMessage:(Y,Q)=>{let X={id:`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:Y,timestamp:Date.now(),thinkingContent:Q};Z().session.actions.addMessage(X)},addAssistantMessageAndClearThinking:(Y)=>{let Q=Z().session.currentThinkingContent,X={id:`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:Y,timestamp:Date.now(),thinkingContent:Q||void 0};$((J)=>({session:{...J.session,messages:[...J.session.messages,X],currentThinkingContent:null,error:null}}))},addToolMessage:(Y,Q)=>{let X={id:`tool-${Date.now()}-${Math.random()}`,role:"tool",content:Y,timestamp:Date.now(),metadata:Q};Z().session.actions.addMessage(X)},setCompacting:(Y)=>{$((Q)=>({session:{...Q.session,isCompacting:Y}}))},setCommand:(Y)=>{$((Q)=>({session:{...Q.session,currentCommand:Y}}))},setError:(Y)=>{$((Q)=>({session:{...Q.session,error:Y}}))},clearMessages:()=>{u6(),$((Y)=>({session:{...Y.session,messages:[],error:null,clearCount:Y.session.clearCount+1}}))},resetSession:()=>{u6(),$((Y)=>({session:{...Y.session,...fX,sessionId:Y.session.sessionId,isActive:!0}}))},restoreSession:(Y,Q)=>{u6(),$((X)=>({session:{...X.session,sessionId:Y,messages:Q,error:null,isActive:!0}}))},updateTokenUsage:(Y)=>{$((Q)=>({session:{...Q.session,tokenUsage:{...Q.session.tokenUsage,...Y}}}))},resetTokenUsage:()=>{$((Y)=>({session:{...Y.session,tokenUsage:{...hX}}}))},setCurrentThinkingContent:(Y)=>{if(Z().session.currentThinkingContent===Y)return;$((Q)=>({session:{...Q.session,currentThinkingContent:Y}}))},appendThinkingContent:(Y)=>{$((Q)=>({session:{...Q.session,currentThinkingContent:(Q.session.currentThinkingContent||"")+Y}}))},setThinkingExpanded:(Y)=>{$((Q)=>({session:{...Q.session,thinkingExpanded:Y}}))},toggleThinkingExpanded:()=>{$((Y)=>({session:{...Y.session,thinkingExpanded:!Y.session.thinkingExpanded}}))},setHistoryExpanded:(Y)=>{$((Q)=>({session:{...Q.session,historyExpanded:Y}}))},toggleHistoryExpanded:()=>{$((Y)=>({session:{...Y.session,historyExpanded:!Y.session.historyExpanded}}))},setExpandedMessageCount:(Y)=>{$((Q)=>({session:{...Q.session,expandedMessageCount:Y}}))},incrementClearCount:()=>{$((Y)=>({session:{...Y.session,clearCount:Y.session.clearCount+1}}))},startStreamingAssistantMessage:()=>{let Y=`assistant-${Date.now()}-${Math.random()}`,Q={id:Y,role:"assistant",content:"",timestamp:Date.now()};return d6=[],$((X)=>({session:{...X.session,messages:[...X.session.messages,Q],currentStreamingMessageId:Y,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,error:null}})),Y},appendAssistantContent:(Y)=>{let Q=Z().session.currentStreamingMessageId,X=Q??`assistant-${Date.now()}-${Math.random()}`;return d6.push(Y),$((J)=>{let G=(N)=>N.endsWith("\r")?N.slice(0,-1):N,q=Q?J.session.currentStreamingLines:[],K=Q?J.session.currentStreamingTail:"",W=Q?J.session.currentStreamingLineCount:0,U=Q?J.session.currentStreamingVersion:0,O=(K+Y).split(`
|
|
37
|
+
`),F=O.slice(0,-1).map(G),_=G(O[O.length-1]??""),z=q;if(F.length>0){if(z=[...q,...F],z.length>SX){let N=z.length-SX;z=z.slice(N)}}return{session:{...J.session,currentStreamingMessageId:X,currentStreamingLines:z,currentStreamingTail:_,currentStreamingLineCount:W+F.length,currentStreamingVersion:U+1,error:null}}}),X},finalizeStreamingMessage:(Y,Q)=>{let X=D_();$((J)=>{let G=J.session.currentStreamingMessageId,K=X.join("")+(Y||""),W=(J.session.currentThinkingContent||"")+(Q||"");if(K.length>0){let U={id:G||`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:K,timestamp:Date.now(),thinkingContent:W||void 0};return{session:{...J.session,messages:[...J.session.messages,U],currentStreamingMessageId:null,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,currentThinkingContent:null,finalizingStreamingMessageId:U.id}}}return{session:{...J.session,currentStreamingMessageId:null,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,currentThinkingContent:null,finalizingStreamingMessageId:null}}})},clearFinalizingStreamingMessageId:()=>{$((Y)=>({session:{...Y.session,finalizingStreamingMessageId:null}}))}}});var xX=b(()=>{y3();d6=[];hX={inputTokens:0,outputTokens:0,totalTokens:0,maxContextTokens:200000},fX={sessionId:R_(),messages:[],isCompacting:!1,currentCommand:null,error:null,isActive:!0,tokenUsage:{...hX},currentThinkingContent:null,thinkingExpanded:!1,clearCount:0,historyExpanded:!1,expandedMessageCount:100,currentStreamingMessageId:null,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,finalizingStreamingMessageId:null}});var pX,m4,g4,F2,h$,mX;var l1=b(()=>{pX={proposal:"proposal.md",spec:"spec.md",requirements:"requirements.md",design:"design.md",tasks:"tasks.md",meta:".meta.json"},m4={SPECS:"specs",CHANGES:"changes",ARCHIVE:"archive",STEERING:"steering",SPEC_DELTA:"specs"},g4={CONSTITUTION:"constitution.md",PRODUCT:"product.md",TECH:"tech.md",STRUCTURE:"structure.md"},F2={init:["requirements"],requirements:["design","tasks"],design:["tasks"],tasks:["implementation"],implementation:["done","tasks"],done:[]},h$={init:"初始化",requirements:"需求定义",design:"架构设计",tasks:"任务分解",implementation:"实现中",done:"已完成"},mX={init:"proposal",requirements:"requirements",design:"design",tasks:"tasks",implementation:"tasks",done:null}});import{promises as x$}from"node:fs";import*as d0 from"node:path";import{fileURLToPath as M_}from"node:url";import{nanoid as j_}from"nanoid";var T_,y_,gX,u4;var N9=b(()=>{l1();T_=M_(import.meta.url),y_=d0.dirname(T_),gX=d0.join(y_,"templates");u4=class u4{workspaceRoot;bladeDir;constructor($){this.workspaceRoot=$,this.bladeDir=d0.join($,".blade")}getSpecsDir(){return d0.join(this.bladeDir,m4.SPECS)}getChangesDir(){return d0.join(this.bladeDir,m4.CHANGES)}getArchiveDir(){return d0.join(this.bladeDir,m4.ARCHIVE)}getSteeringDir(){return d0.join(this.bladeDir,m4.STEERING)}getChangePath($){return d0.join(this.getChangesDir(),$)}getChangeFilePath($,Z){return d0.join(this.getChangePath($),pX[Z])}async initializeDirectories(){await x$.mkdir(this.getChangesDir(),{recursive:!0,mode:493})}async createChangeDir($){let Z=this.getChangePath($);return await x$.mkdir(Z,{recursive:!0,mode:493}),await x$.mkdir(d0.join(Z,m4.SPEC_DELTA),{recursive:!0,mode:493}),Z}async readFile($){try{return await x$.readFile($,"utf-8")}catch(Z){if(Z.code==="ENOENT")return null;throw Z}}async writeFile($,Z){let Y=d0.dirname($);await x$.mkdir(Y,{recursive:!0,mode:493}),await x$.writeFile($,Z,"utf-8")}async fileExists($){try{return await x$.access($),!0}catch{return!1}}async dirExists($){try{return(await x$.stat($)).isDirectory()}catch{return!1}}createMetadata($,Z){let Y=new Date().toISOString();return{id:j_(),name:$,description:Z,phase:"init",createdAt:Y,updatedAt:Y,tasks:[]}}async readMetadata($){let Z=this.getChangeFilePath($,"meta"),Y=await this.readFile(Z);if(!Y)return null;try{return JSON.parse(Y)}catch{return null}}async writeMetadata($,Z){let Y=this.getChangeFilePath($,"meta");Z.updatedAt=new Date().toISOString(),await this.writeFile(Y,JSON.stringify(Z,null,2))}async updatePhase($,Z){let Y=await this.readMetadata($);if(!Y)return null;return Y.phase=Z,await this.writeMetadata($,Y),Y}async readSpecFile($,Z){let Y=this.getChangeFilePath($,Z);return this.readFile(Y)}async writeSpecFile($,Z,Y){let Q=this.getChangeFilePath($,Z);await this.writeFile(Q,Y);let X=await this.readMetadata($);if(X)await this.writeMetadata($,X)}async getPhaseContent($,Z){let Y=mX[Z];if(!Y)return null;return this.readSpecFile($,Y)}async readSteeringContext(){let $=this.getSteeringDir(),[Z,Y,Q,X]=await Promise.all([this.readFile(d0.join($,g4.CONSTITUTION)),this.readFile(d0.join($,g4.PRODUCT)),this.readFile(d0.join($,g4.TECH)),this.readFile(d0.join($,g4.STRUCTURE))]);return{constitution:Z||void 0,product:Y||void 0,tech:Q||void 0,structure:X||void 0}}async writeSteeringFile($,Z){let Y=d0.join(this.getSteeringDir(),g4[$]);await this.writeFile(Y,Z)}async hasSteeringDocs(){let $=this.getSteeringDir();if(!await this.dirExists($))return!1;return(await x$.readdir($)).length>0}async listActiveChanges(){let $=this.getChangesDir();if(!await this.dirExists($))return[];return(await x$.readdir($,{withFileTypes:!0})).filter((Y)=>Y.isDirectory()).map((Y)=>Y.name)}async listArchivedChanges(){let $=this.getArchiveDir();if(!await this.dirExists($))return[];return(await x$.readdir($,{withFileTypes:!0})).filter((Y)=>Y.isDirectory()).map((Y)=>Y.name)}async changeExists($){return this.dirExists(this.getChangePath($))}async archiveChange($){let Z=this.getChangePath($),Y=d0.join(this.getArchiveDir(),$);await x$.mkdir(d0.dirname(Y),{recursive:!0,mode:493}),await x$.rename(Z,Y)}async restoreChange($){let Z=d0.join(this.getArchiveDir(),$),Y=this.getChangePath($);await x$.rename(Z,Y)}async listSpecDomains(){let $=this.getSpecsDir();if(!await this.dirExists($))return[];return(await x$.readdir($,{withFileTypes:!0})).filter((Y)=>Y.isDirectory()).map((Y)=>Y.name)}async readAuthorativeSpec($){let Z=d0.join(this.getSpecsDir(),$,"spec.md");return this.readFile(Z)}async writeAuthorativeSpec($,Z){let Y=d0.join(this.getSpecsDir(),$,"spec.md");await this.writeFile(Y,Z)}async mergeSpecDeltas($){let Z=d0.join(this.getChangePath($),m4.SPEC_DELTA);if(!await this.dirExists(Z))return[];let Y=[],Q=await x$.readdir(Z,{withFileTypes:!0});for(let X of Q){if(!X.isDirectory())continue;let J=d0.join(Z,X.name,"spec.md"),G=await this.readFile(J);if(G){let q=await this.readAuthorativeSpec(X.name),K=q?`${q}
|
|
38
38
|
|
|
39
39
|
---
|
|
40
40
|
|
|
@@ -74,7 +74,7 @@ ${Z}
|
|
|
74
74
|
<!-- What needs to be clarified before proceeding? -->
|
|
75
75
|
|
|
76
76
|
1.
|
|
77
|
-
`}}var uX=b(()=>{
|
|
77
|
+
`}}var uX=b(()=>{N9();l1()});var dX,cX,L9=($,Z)=>({...cX,actions:{initialize:async(Y)=>{let Q=I$.getInstance();await Q.initialize(Y);let X=await Q.readSteeringContext();$((J)=>({spec:{...J.spec,workspaceRoot:Y,steeringContext:X}}))},createSpec:async(Y,Q)=>{let J=await I$.getInstance().createSpec(Y,Q);if(J.success&&J.data){let{spec:G,path:q}=J.data,K=Z().spec.recentSpecs.filter((W)=>W!==Y);K.unshift(Y),$((W)=>({spec:{...W.spec,currentSpec:G,specPath:q,isActive:!0,recentSpecs:K.slice(0,10)}}))}return J},loadSpec:async(Y)=>{let X=await I$.getInstance().loadSpec(Y);if(X.success&&X.data){let{spec:J,path:G}=X.data,q=Z().spec.recentSpecs.filter((K)=>K!==Y);q.unshift(Y),$((K)=>({spec:{...K.spec,currentSpec:J,specPath:G,isActive:!0,recentSpecs:q.slice(0,10)}}))}return X},closeSpec:()=>{$((Y)=>({spec:{...Y.spec,currentSpec:null,specPath:null,isActive:!1}}))},exitSpecMode:()=>{Z().spec.actions.closeSpec()},transitionPhase:async(Y)=>{let Q=Z().spec.currentSpec;if(!Q)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let X=I$.getInstance();if(!X.canTransitionPhase(Q.phase,Y))return{success:!1,message:`Cannot transition from "${Q.phase}" to "${Y}"`,error:"INVALID_TRANSITION"};let J=await X.updatePhase(Q.name,Y);if(!J)return{success:!1,message:"Failed to update phase",error:"UPDATE_FAILED"};if($((G)=>({spec:{...G.spec,currentSpec:J}})),Y==="done")try{let{config:G}=Z();if(G.actions)G.actions.updateConfig({permissionMode:"default"});dX.info("Spec 已完成,已自动退出 Spec 模式")}catch(G){dX.error("自动退出 Spec 模式失败:",G)}return{success:!0,message:`Transitioned to "${Y}" phase`,data:{spec:J,phase:Y}}},getAllowedTransitions:()=>{let Y=Z().spec.currentSpec;if(!Y)return[];return F2[Y.phase]},addTask:async(Y,Q,X)=>{let J=Z().spec.currentSpec;if(!J)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let G=I$.getInstance(),q=G.createTask(Y,Q,X),K={...J,tasks:[...J.tasks,q],updatedAt:new Date().toISOString()};return await G.saveMetadata(J.name,K),$((W)=>({spec:{...W.spec,currentSpec:K}})),{success:!0,message:`Task "${Y}" added`,data:{task:q}}},updateTaskStatus:async(Y,Q)=>{let X=Z().spec.currentSpec;if(!X)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let J=X.tasks.find((U)=>U.id===Y);if(!J)return{success:!1,message:`Task "${Y}" not found`,error:"TASK_NOT_FOUND"};let G={...J,status:Q,completedAt:Q==="completed"?new Date().toISOString():J.completedAt},q=X.tasks.map((U)=>U.id===Y?G:U),K={...X,tasks:q,currentTaskId:Q==="in_progress"?Y:X.currentTaskId===Y?void 0:X.currentTaskId,updatedAt:new Date().toISOString()};return await I$.getInstance().saveMetadata(X.name,K),$((U)=>({spec:{...U.spec,currentSpec:K}})),{success:!0,message:`Task status updated to "${Q}"`,data:{task:G}}},getNextTask:()=>{let Y=Z().spec.currentSpec;if(!Y)return null;return I$.getInstance().getNextTask(Y.tasks)},getTaskProgress:()=>{let Y=Z().spec.currentSpec;if(!Y)return{total:0,completed:0,percentage:0};return I$.getInstance().getTaskProgress(Y.tasks)},listSpecs:async(Y)=>{let Q=I$.getInstance(),X=[],J=await Q.listActiveSpecs();for(let G of J){let q=await Q.readSpecMetadata(G);if(!q)continue;if(Y?.phase&&q.phase!==Y.phase)continue;if(Y?.tags&&!Y.tags.some((W)=>q.tags?.includes(W)))continue;if(Y?.query&&!q.name.toLowerCase().includes(Y.query.toLowerCase())&&!q.description.toLowerCase().includes(Y.query.toLowerCase()))continue;let K=Q.getTaskProgress(q.tasks);X.push({name:q.name,description:q.description,phase:q.phase,updatedAt:q.updatedAt,path:Q.getSpecPath(G),isArchived:!1,taskProgress:{total:K.total,completed:K.completed}})}if(Y?.includeArchived){let G=await Q.listArchivedSpecs();for(let q of G)X.push({name:q,description:"(archived)",phase:"done",updatedAt:"",path:`archive/${q}`,isArchived:!0,taskProgress:{total:0,completed:0}})}return X.sort((G,q)=>{if(G.isArchived!==q.isArchived)return G.isArchived?1:-1;return new Date(q.updatedAt).getTime()-new Date(G.updatedAt).getTime()}),X},archiveCurrentSpec:async()=>{let Y=Z().spec.currentSpec;if(!Y)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let X=await I$.getInstance().archiveSpec(Y.name);if(X.success)Z().spec.actions.closeSpec();return X},validateCurrentSpec:async()=>{let Y=Z().spec.currentSpec;if(!Y)return{valid:!1,phase:"init",completeness:{proposal:!1,spec:!1,requirements:!1,design:!1,tasks:!1},issues:[{severity:"error",file:"meta",message:"No active spec"}],suggestions:["Create a new spec with /spec proposal <name>"]};return I$.getInstance().validateSpec(Y)},getSteeringContextString:async()=>{let Y=Z().spec.steeringContext;if(!Y)return null;let Q=[];if(Y.constitution)Q.push(`## Constitution (Project Governance)
|
|
78
78
|
|
|
79
79
|
${Y.constitution}`);if(Y.product)Q.push(`## Product Vision
|
|
80
80
|
|
|
@@ -93,11 +93,11 @@ ${Y.structure}`);return Q.length>0?Q.join(`
|
|
|
93
93
|
`+`请确保:
|
|
94
94
|
`+`1. 配置文件格式正确 (~/.blade/config.json)
|
|
95
95
|
`+`2. 运行 blade 进行首次配置
|
|
96
|
-
`+"3. 配置文件权限正确")}finally{P8=null}})(),P8}var i1,X0=()=>i1.getState(),_0=()=>X0().session.actions,v2=()=>X0().app.actions,rX=()=>X0().session.messages,f0=()=>X0().config.config,P8=null,z2=()=>X0().config.config?.models??[],B2=()=>{let $=f0();if(!$)return;let Z=$.currentModelId;return $.models.find((Q)=>Q.id===Z)??$.models[0]},E3=($)=>{let Z=f0();if(!Z)return;return Z.models.find((Y)=>Y.id===$)},q1=()=>X0().config.config?.mcpServers??{},c6=()=>X0().app.thinkingModeEnabled,A0=()=>({setPermissionMode:async($)=>{X0().config.actions.updateConfig({permissionMode:$})},setTheme:async($,Z={})=>{try{E$.setTheme($)}catch{return}X0().config.actions.updateConfig({theme:$}),await c$().save({theme:$},{scope:"global",...Z})},setLanguage:async($,Z={})=>{X0().config.actions.updateConfig({language:$}),await c$().save({language:$},{scope:"global",...Z})},setDebug:async($,Z={})=>{X0().config.actions.updateConfig({debug:$}),await c$().save({debug:$},{scope:"global",...Z})},setTemperature:async($,Z={})=>{X0().config.actions.updateConfig({temperature:$}),await c$().save({temperature:$},{scope:"global",...Z})},updateConfig:async($,Z={})=>{let Y=f0();if(!Y)throw Error("Config not initialized");let Q={...Y};X0().config.actions.updateConfig($);try{await c$().save($,Z)}catch(X){throw X0().config.actions.setConfig(Q),X}},flush:async()=>{await c$().flush()},appendPermissionAllowRule:async($,Z={})=>{let Y=f0();if(!Y)throw Error("Config not initialized");let Q=Y.permissions?.allow||[];if(!Q.includes($)){let X=[...Q,$];X0().config.actions.updateConfig({permissions:{...Y.permissions,allow:X}})}await c$().appendPermissionRule($,Z)},appendLocalPermissionAllowRule:async($,Z={})=>{let Y=f0();if(!Y)throw Error("Config not initialized");let Q=Y.permissions?.allow||[];if(!Q.includes($)){let X=[...Q,$];X0().config.actions.updateConfig({permissions:{...Y.permissions,allow:X}})}await c$().appendLocalPermissionRule($,Z)},setCurrentModel:async($,Z={})=>{let Y=f0();if(!Y)throw Error("Config not initialized");if(!Y.models.find((X)=>X.id===$))throw Error(`Model not found: ${$}`);X0().config.actions.updateConfig({currentModelId:$}),await c$().save({currentModelId:$},{scope:"global",...Z})},addModel:async($,Z={})=>{let Y=f0();if(!Y)throw Error("Config not initialized");let Q="id"in $?$:{id:I_(),...$},J={models:[...Y.models,Q]};if(Y.models.length===0)J.currentModelId=Q.id;return X0().config.actions.updateConfig(J),await c$().save(J,{scope:"global",...Z}),Q},updateModel:async($,Z,Y={})=>{let Q=f0();if(!Q)throw Error("Config not initialized");let X=Q.models.findIndex((G)=>G.id===$);if(X===-1)throw Error(`Model not found: ${$}`);let J=[...Q.models];J[X]={...J[X],...Z},X0().config.actions.updateConfig({models:J}),await c$().save({models:J},{scope:"global",...Y})},removeModel:async($,Z={})=>{let Y=f0();if(!Y)throw Error("Config not initialized");if(Y.models.length===1)throw Error("Cannot remove the only model");let Q=Y.models.filter((J)=>J.id!==$),X={models:Q};if(Y.currentModelId===$)X.currentModelId=Q[0].id;X0().config.actions.updateConfig(X),await c$().save(X,{scope:"global",...Z})},addMcpServer:async($,Z,Y={})=>{let Q=f0();if(!Q)throw Error("Config not initialized");let J={...Q.mcpServers??{},[$]:Z};X0().config.actions.updateConfig({mcpServers:J}),await c$().save({mcpServers:J},{scope:"project",...Y})},removeMcpServer:async($,Z={})=>{let Y=f0();if(!Y)throw Error("Config not initialized");let X={...Y.mcpServers??{}};delete X[$],X0().config.actions.updateConfig({mcpServers:X}),await c$().save({mcpServers:X},{scope:"project",...Z})}});var b0=b(()=>{Y4();I2();iX();i1=C_()(P_(v_((...$)=>({session:
|
|
96
|
+
`+"3. 配置文件权限正确")}finally{P8=null}})(),P8}var i1,X0=()=>i1.getState(),_0=()=>X0().session.actions,v2=()=>X0().app.actions,rX=()=>X0().session.messages,f0=()=>X0().config.config,P8=null,z2=()=>X0().config.config?.models??[],B2=()=>{let $=f0();if(!$)return;let Z=$.currentModelId;return $.models.find((Q)=>Q.id===Z)??$.models[0]},E3=($)=>{let Z=f0();if(!Z)return;return Z.models.find((Y)=>Y.id===$)},q1=()=>X0().config.config?.mcpServers??{},c6=()=>X0().app.thinkingModeEnabled,A0=()=>({setPermissionMode:async($)=>{X0().config.actions.updateConfig({permissionMode:$})},setTheme:async($,Z={})=>{try{E$.setTheme($)}catch{return}X0().config.actions.updateConfig({theme:$}),await c$().save({theme:$},{scope:"global",...Z})},setLanguage:async($,Z={})=>{X0().config.actions.updateConfig({language:$}),await c$().save({language:$},{scope:"global",...Z})},setDebug:async($,Z={})=>{X0().config.actions.updateConfig({debug:$}),await c$().save({debug:$},{scope:"global",...Z})},setTemperature:async($,Z={})=>{X0().config.actions.updateConfig({temperature:$}),await c$().save({temperature:$},{scope:"global",...Z})},updateConfig:async($,Z={})=>{let Y=f0();if(!Y)throw Error("Config not initialized");let Q={...Y};X0().config.actions.updateConfig($);try{await c$().save($,Z)}catch(X){throw X0().config.actions.setConfig(Q),X}},flush:async()=>{await c$().flush()},appendPermissionAllowRule:async($,Z={})=>{let Y=f0();if(!Y)throw Error("Config not initialized");let Q=Y.permissions?.allow||[];if(!Q.includes($)){let X=[...Q,$];X0().config.actions.updateConfig({permissions:{...Y.permissions,allow:X}})}await c$().appendPermissionRule($,Z)},appendLocalPermissionAllowRule:async($,Z={})=>{let Y=f0();if(!Y)throw Error("Config not initialized");let Q=Y.permissions?.allow||[];if(!Q.includes($)){let X=[...Q,$];X0().config.actions.updateConfig({permissions:{...Y.permissions,allow:X}})}await c$().appendLocalPermissionRule($,Z)},setCurrentModel:async($,Z={})=>{let Y=f0();if(!Y)throw Error("Config not initialized");if(!Y.models.find((X)=>X.id===$))throw Error(`Model not found: ${$}`);X0().config.actions.updateConfig({currentModelId:$}),await c$().save({currentModelId:$},{scope:"global",...Z})},addModel:async($,Z={})=>{let Y=f0();if(!Y)throw Error("Config not initialized");let Q="id"in $?$:{id:I_(),...$},J={models:[...Y.models,Q]};if(Y.models.length===0)J.currentModelId=Q.id;return X0().config.actions.updateConfig(J),await c$().save(J,{scope:"global",...Z}),Q},updateModel:async($,Z,Y={})=>{let Q=f0();if(!Q)throw Error("Config not initialized");let X=Q.models.findIndex((G)=>G.id===$);if(X===-1)throw Error(`Model not found: ${$}`);let J=[...Q.models];J[X]={...J[X],...Z},X0().config.actions.updateConfig({models:J}),await c$().save({models:J},{scope:"global",...Y})},removeModel:async($,Z={})=>{let Y=f0();if(!Y)throw Error("Config not initialized");if(Y.models.length===1)throw Error("Cannot remove the only model");let Q=Y.models.filter((J)=>J.id!==$),X={models:Q};if(Y.currentModelId===$)X.currentModelId=Q[0].id;X0().config.actions.updateConfig(X),await c$().save(X,{scope:"global",...Z})},addMcpServer:async($,Z,Y={})=>{let Q=f0();if(!Q)throw Error("Config not initialized");let J={...Q.mcpServers??{},[$]:Z};X0().config.actions.updateConfig({mcpServers:J}),await c$().save({mcpServers:J},{scope:"project",...Y})},removeMcpServer:async($,Z={})=>{let Y=f0();if(!Y)throw Error("Config not initialized");let X={...Y.mcpServers??{}};delete X[$],X0().config.actions.updateConfig({mcpServers:X}),await c$().save({mcpServers:X},{scope:"project",...Z})}});var b0=b(()=>{Y4();I2();iX();i1=C_()(P_(v_((...$)=>({session:B9(...$),app:q9(...$),config:W9(...$),focus:U9(...$),command:K9(...$),spec:L9(...$)})),{name:"BladeStore",enabled:!0}))});var aX={};s5(aX,{validatePermissions:()=>A9,validateOutput:()=>V9,loadConfiguration:()=>b9});var w9,A9=($)=>{if($.yolo){if($.permissionMode&&$.permissionMode!=="yolo")throw Error("Cannot use both --yolo and --permission-mode with different values");$.permissionMode="yolo"}if(Array.isArray($.allowedTools)&&Array.isArray($.disallowedTools)){let Z=$.allowedTools.filter((Y)=>$.disallowedTools.includes(Y));if(Z.length>0)throw Error(`Tools cannot be both allowed and disallowed: ${Z.join(", ")}`)}},b9=async($)=>{try{let Y=await f$.getInstance().initialize();if(X0().config.actions.setConfig(Y),$.debug)w9.info("[CLI] 配置已加载到 Store")}catch(Z){w9.error("[CLI] ❌ 配置初始化失败",Z instanceof Error?Z.message:Z),console.error(`
|
|
97
97
|
❌ 配置初始化失败
|
|
98
98
|
`),console.error("原因:",Z instanceof Error?Z.message:"未知错误"),console.error(`
|
|
99
99
|
请检查:`),console.error(" 1. 配置文件格式是否正确 (~/.blade/config.json)"),console.error(" 2. 是否需要运行 blade 进行首次配置"),console.error(` 3. 配置文件权限是否正确
|
|
100
|
-
`),process.exit(1)}if($.continue&&$.resume)throw Error("Cannot use both --continue and --resume flags simultaneously")},V5=($)=>{if($.outputFormat&&$.outputFormat!=="text"&&!$.print&&!$.headless)throw Error("--output-format can only be used with --print or --headless");if($.inputFormat==="stream-json"&&$.print)w5.warn("⚠️ Warning: stream-json input format may not work as expected with --print")};var R5=b(()=>{Y4();Y0();b0();w5=p("General")});function M5($,Z){return{...$,...Z,PreToolUse:Z.PreToolUse??$.PreToolUse,PostToolUse:Z.PostToolUse??$.PostToolUse,PostToolUseFailure:Z.PostToolUseFailure??$.PostToolUseFailure,PermissionRequest:Z.PermissionRequest??$.PermissionRequest,UserPromptSubmit:Z.UserPromptSubmit??$.UserPromptSubmit,SessionStart:Z.SessionStart??$.SessionStart,SessionEnd:Z.SessionEnd??$.SessionEnd,Stop:Z.Stop??$.Stop,SubagentStop:Z.SubagentStop??$.SubagentStop,Notification:Z.Notification??$.Notification,Compaction:Z.Compaction??$.Compaction}}function oX(){let $={};if(process.env.BLADE_DISABLE_HOOKS==="true")$.enabled=!1;if(process.env.BLADE_HOOK_TIMEOUT){let Z=parseInt(process.env.BLADE_HOOK_TIMEOUT,10);if(!isNaN(Z)&&Z>0)$.defaultTimeout=Z}return $}var D5;var sX=b(()=>{D5={enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,PreToolUse:[],PostToolUse:[],PostToolUseFailure:[],PermissionRequest:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]}});class j5{executedHooks=new Map;canExecute($,Z){if(!this.executedHooks.has($))this.executedHooks.set($,new Set);if(this.executedHooks.get($).has(Z))return console.warn(`[HookGuard] Hook ${Z} for tool ${$} already executed, skipping`),!1;return!0}markExecuted($,Z){let Y=this.executedHooks.get($);if(Y)Y.add(Z)}cleanup($){this.executedHooks.delete($)}cleanupAll(){this.executedHooks.clear()}}var N2,T5,y5;var v8=b(()=>{((H)=>{H.PreToolUse="PreToolUse";H.PostToolUse="PostToolUse";H.PostToolUseFailure="PostToolUseFailure";H.PermissionRequest="PermissionRequest";H.UserPromptSubmit="UserPromptSubmit";H.SessionStart="SessionStart";H.SessionEnd="SessionEnd";H.Stop="Stop";H.SubagentStop="SubagentStop";H.Notification="Notification";H.Compaction="Compaction"})(N2||={});((Q)=>{Q.Approve="approve";Q.Block="block";Q.Async="async"})(T5||={});((Q)=>{Q.Allow="allow";Q.Deny="deny";Q.Ask="ask"})(y5||={})});import{z as E}from"zod";function tX($){let Z=$z.safeParse($);if(Z.success)return{success:!0,data:Z.data};return{success:!1,error:Z.error}}var a1,S_,f_,h_,x_,p_,m_,g_,u_,d_,c_,l_,dT,i_,r_,a_,n_,o_,s_,t_,e_,$z,Zz,Yz,Qz,E5,Xz,r1,cT;var eX=b(()=>{v8();a1=E.object({hook_event_name:E.nativeEnum(N2),hook_execution_id:E.string(),timestamp:E.string(),project_dir:E.string(),session_id:E.string(),permission_mode:E.enum(["default","autoEdit","yolo","plan"]),_metadata:E.object({blade_version:E.string(),hook_timeout_ms:E.number()}).optional()}),S_=a1.extend({hook_event_name:E.literal("PreToolUse"),tool_name:E.string(),tool_use_id:E.string(),tool_input:E.record(E.unknown())}),f_=a1.extend({hook_event_name:E.literal("PostToolUse"),tool_name:E.string(),tool_use_id:E.string(),tool_input:E.record(E.unknown()),tool_response:E.unknown()}),h_=a1.extend({hook_event_name:E.literal("Stop"),reason:E.string().optional()}),x_=a1.extend({hook_event_name:E.literal("PostToolUseFailure"),tool_name:E.string(),tool_use_id:E.string(),tool_input:E.record(E.unknown()),error:E.string(),error_type:E.string().optional(),is_interrupt:E.boolean(),is_timeout:E.boolean()}),p_=a1.extend({hook_event_name:E.literal("PermissionRequest"),tool_name:E.string(),tool_use_id:E.string(),tool_input:E.record(E.unknown())}),m_=a1.extend({hook_event_name:E.literal("UserPromptSubmit"),user_prompt:E.string(),has_images:E.boolean(),image_count:E.number()}),g_=a1.extend({hook_event_name:E.literal("SessionStart"),is_resume:E.boolean(),resume_session_id:E.string().optional()}),u_=a1.extend({hook_event_name:E.literal("SessionEnd"),reason:E.enum(["user_exit","error","max_turns","idle_timeout","ctrl_c","clear","logout","other"])}),d_=a1.extend({hook_event_name:E.literal("SubagentStop"),agent_type:E.string(),task_description:E.string().optional(),success:E.boolean(),result_summary:E.string().optional(),error:E.string().optional()}),c_=a1.extend({hook_event_name:E.literal("Notification"),notification_type:E.enum(["permission_prompt","idle_prompt","auth_success","elicitation_dialog","info","warning","error"]),title:E.string().optional(),message:E.string()}),l_=a1.extend({hook_event_name:E.literal("Compaction"),trigger:E.enum(["manual","auto"]),messages_before:E.number(),tokens_before:E.number()}),dT=E.discriminatedUnion("hook_event_name",[S_,f_,h_,x_,p_,m_,g_,u_,d_,c_,l_]),i_=E.object({hookEventName:E.literal("PreToolUse"),permissionDecision:E.nativeEnum(y5).optional(),permissionDecisionReason:E.string().optional(),updatedInput:E.record(E.unknown()).optional()}),r_=E.object({hookEventName:E.literal("PostToolUse"),additionalContext:E.string().optional(),updatedOutput:E.unknown().optional()}),a_=E.object({hookEventName:E.literal("Stop"),continue:E.boolean().optional(),continueReason:E.string().optional()}),n_=E.object({hookEventName:E.literal("SubagentStop"),continue:E.boolean().optional(),continueReason:E.string().optional(),additionalContext:E.string().optional()}),o_=E.object({hookEventName:E.literal("PermissionRequest"),permissionDecision:E.enum(["approve","deny","ask"]).optional(),permissionDecisionReason:E.string().optional()}),s_=E.object({hookEventName:E.literal("UserPromptSubmit"),updatedPrompt:E.string().optional(),contextInjection:E.string().optional()}),t_=E.object({hookEventName:E.literal("SessionStart"),env:E.record(E.string()).optional()}),e_=E.object({hookEventName:E.literal("Compaction"),blockCompaction:E.boolean().optional(),blockReason:E.string().optional()}),$z=E.object({decision:E.object({behavior:E.nativeEnum(T5)}).optional(),systemMessage:E.string().optional(),hookSpecificOutput:E.discriminatedUnion("hookEventName",[i_,r_,a_,n_,o_,s_,t_,e_]).optional(),suppressOutput:E.boolean().optional()}),Zz=E.object({type:E.literal("command"),command:E.string(),timeout:E.number().positive().optional(),statusMessage:E.string().optional()}),Yz=E.object({type:E.literal("prompt"),prompt:E.string(),timeout:E.number().positive().optional()}),Qz=E.discriminatedUnion("type",[Zz,Yz]),E5=E.union([E.string(),E.array(E.string())]),Xz=E.object({tools:E5.optional(),paths:E5.optional(),commands:E5.optional()}),r1=E.object({name:E.string().optional(),matcher:Xz.optional(),hooks:E.array(Qz)}),cT=E.object({enabled:E.boolean().optional(),defaultTimeout:E.number().positive().optional(),timeoutBehavior:E.enum(["ignore","deny","ask"]).optional(),failureBehavior:E.enum(["ignore","deny","ask"]).optional(),maxConcurrentHooks:E.number().positive().optional(),PreToolUse:E.array(r1).optional(),PostToolUse:E.array(r1).optional(),PostToolUseFailure:E.array(r1).optional(),PermissionRequest:E.array(r1).optional(),UserPromptSubmit:E.array(r1).optional(),SessionStart:E.array(r1).optional(),SessionEnd:E.array(r1).optional(),Stop:E.array(r1).optional(),SubagentStop:E.array(r1).optional(),Notification:E.array(r1).optional(),Compaction:E.array(r1).optional()})});class I5{parse($,Z,Y){if($.timedOut){let X=Y?.timeoutBehavior||"ignore",J="Hook timeout";if(X==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z}}let Q=this.tryParseJSON($.stdout);if(Q){let X=tX(Q);if(!X.success){let G="error"in X?X.error.message:"Unknown validation error",q=Y?.failureBehavior||"ignore",K=`Invalid hook output JSON: ${G}`;if(q==="deny")return{success:!1,blocking:!0,error:K,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else if(q==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${K}. Continue?`,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else return{success:!1,blocking:!1,warning:K,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z}}let J=X.data;if(J.decision?.behavior==="block")return{success:!1,blocking:!0,error:J.systemMessage||"Hook blocked execution",output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};if(J.decision?.behavior==="async")return{success:!0,output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};return{success:!0,output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z}}return this.parseByExitCode($,Z,Y)}parseByExitCode($,Z,Y){let Q=$.exitCode;switch(Q){case 0:return{success:!0,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};case 2:return{success:!1,blocking:!0,error:$.stderr||$.stdout||"Hook returned exit code 2",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};case 124:{let X=Y?.timeoutBehavior||"ignore",J="Hook timeout";if(X==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z}}default:{let X=Y?.failureBehavior||"ignore",J=$.stderr||$.stdout||`Hook failed with exit code ${Q}`;if(X==="deny")return{success:!1,blocking:!0,error:J,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${J}. Continue?`,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else return{success:!1,blocking:!1,warning:J,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z}}}}tryParseJSON($){try{let Z=$.trim();if(!Z)return null;let Y=Z.match(/^\s*(\{[\s\S]*\})\s*$/);if(!Y)return null;return JSON.parse(Y[1])}catch{return null}}}var $J=b(()=>{eX()});import{spawn as Jz}from"child_process";class P5{content="";maxSize;constructor($){this.maxSize=$}append($){if(this.content.length<this.maxSize){let Z=this.maxSize-this.content.length;this.content+=$.substring(0,Z)}}getContent(){return this.content}isFull(){return this.content.length>=this.maxSize}}class v5{MAX_STDOUT_SIZE=1048576;MAX_STDERR_SIZE=1048576;MAX_INPUT_SIZE=102400;async execute($,Z,Y,Q){let X=JSON.stringify(Z);if(X.length>this.MAX_INPUT_SIZE)throw Error(`Hook input too large: ${X.length} bytes (max ${this.MAX_INPUT_SIZE})`);let J=this.createSafeEnv(Z),G=Jz($,[],{shell:!0,env:J,cwd:Y.projectDir,timeout:Q}),q=new P5(this.MAX_STDOUT_SIZE),K=new P5(this.MAX_STDERR_SIZE);G.stdout.setEncoding("utf8"),G.stderr.setEncoding("utf8"),G.stdout.on("data",(W)=>{q.append(W)}),G.stderr.on("data",(W)=>{K.append(W)});try{G.stdin.write(X),G.stdin.end()}catch(W){throw G.kill("SIGTERM"),Error(`Failed to write hook input: ${W}`)}return new Promise((W,U)=>{let H=!1,O=!1,F=null,_=()=>{if(F&&Y.abortSignal)Y.abortSignal.removeEventListener("abort",F),F=null},z=setTimeout(()=>{H=!0,G.kill("SIGKILL")},Q);if(G.on("close",(N)=>{if(O)return;O=!0,clearTimeout(z),_(),W({stdout:q.getContent(),stderr:K.getContent(),exitCode:H?124:N??1,timedOut:H})}),G.on("error",(N)=>{if(O)return;O=!0,clearTimeout(z),_(),U(N)}),Y.abortSignal)F=()=>{if(O)return;O=!0,clearTimeout(z),_(),G.kill("SIGTERM"),W({stdout:q.getContent(),stderr:"Hook cancelled by abort signal",exitCode:1,timedOut:!1})},Y.abortSignal.addEventListener("abort",F)})}createSafeEnv($){return{BLADE_PROJECT_DIR:$.project_dir,BLADE_SESSION_ID:$.session_id,BLADE_HOOK_EVENT:$.hook_event_name,BLADE_TOOL_NAME:"tool_name"in $?$.tool_name:"",BLADE_TOOL_USE_ID:"tool_use_id"in $?$.tool_use_id:"",PATH:process.env.PATH||"",HOME:process.env.HOME||"",USER:process.env.USER||"",SHELL:process.env.SHELL||"/bin/sh"}}}var ZJ=()=>{};class C5{processExecutor=new v5;outputParser=new I5;async executePreToolHooks($,Z,Y){if($.length===0)return{decision:"allow"};let Q="tool_input"in Z?Z.tool_input:{},X=[];for(let J of $)try{let G={...Z,...Q&&{tool_input:Q}},q=await this.executeHook(J,G,Y);if(!q.success){if(q.blocking)return{decision:"deny",reason:q.error};if(q.needsConfirmation)return{decision:"ask",reason:q.warning||q.error};if(q.warning)X.push(q.warning);continue}let K=q.output?.hookSpecificOutput;if(K&&"permissionDecision"in K){switch(K.permissionDecision){case"deny":return{decision:"deny",reason:K.permissionDecisionReason};case"ask":return{decision:"ask",reason:K.permissionDecisionReason};case"allow":break}if("updatedInput"in K&&K.updatedInput)Q={...Q,...K.updatedInput}}}catch(G){let q=G instanceof Error?G.message:String(G);if(X.push(`Hook failed: ${q}`),Y.config.failureBehavior==="deny")return{decision:"deny",reason:q};else if(Y.config.failureBehavior==="ask")return{decision:"ask",reason:`Hook failed: ${q}. Continue?`}}return{decision:"allow",modifiedInput:Q,warning:X.length>0?X.join(`
|
|
100
|
+
`),process.exit(1)}if($.continue&&$.resume)throw Error("Cannot use both --continue and --resume flags simultaneously")},V9=($)=>{if($.outputFormat&&$.outputFormat!=="text"&&!$.print&&!$.headless)throw Error("--output-format can only be used with --print or --headless");if($.inputFormat==="stream-json"&&$.print)w9.warn("⚠️ Warning: stream-json input format may not work as expected with --print")};var R9=b(()=>{Y4();Y0();b0();w9=p("General")});function M9($,Z){return{...$,...Z,PreToolUse:Z.PreToolUse??$.PreToolUse,PostToolUse:Z.PostToolUse??$.PostToolUse,PostToolUseFailure:Z.PostToolUseFailure??$.PostToolUseFailure,PermissionRequest:Z.PermissionRequest??$.PermissionRequest,UserPromptSubmit:Z.UserPromptSubmit??$.UserPromptSubmit,SessionStart:Z.SessionStart??$.SessionStart,SessionEnd:Z.SessionEnd??$.SessionEnd,Stop:Z.Stop??$.Stop,SubagentStop:Z.SubagentStop??$.SubagentStop,Notification:Z.Notification??$.Notification,Compaction:Z.Compaction??$.Compaction}}function oX(){let $={};if(process.env.BLADE_DISABLE_HOOKS==="true")$.enabled=!1;if(process.env.BLADE_HOOK_TIMEOUT){let Z=parseInt(process.env.BLADE_HOOK_TIMEOUT,10);if(!isNaN(Z)&&Z>0)$.defaultTimeout=Z}return $}var D9;var sX=b(()=>{D9={enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,PreToolUse:[],PostToolUse:[],PostToolUseFailure:[],PermissionRequest:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]}});class j9{executedHooks=new Map;canExecute($,Z){if(!this.executedHooks.has($))this.executedHooks.set($,new Set);if(this.executedHooks.get($).has(Z))return console.warn(`[HookGuard] Hook ${Z} for tool ${$} already executed, skipping`),!1;return!0}markExecuted($,Z){let Y=this.executedHooks.get($);if(Y)Y.add(Z)}cleanup($){this.executedHooks.delete($)}cleanupAll(){this.executedHooks.clear()}}var N2,T9,y9;var v8=b(()=>{((H)=>{H.PreToolUse="PreToolUse";H.PostToolUse="PostToolUse";H.PostToolUseFailure="PostToolUseFailure";H.PermissionRequest="PermissionRequest";H.UserPromptSubmit="UserPromptSubmit";H.SessionStart="SessionStart";H.SessionEnd="SessionEnd";H.Stop="Stop";H.SubagentStop="SubagentStop";H.Notification="Notification";H.Compaction="Compaction"})(N2||={});((Q)=>{Q.Approve="approve";Q.Block="block";Q.Async="async"})(T9||={});((Q)=>{Q.Allow="allow";Q.Deny="deny";Q.Ask="ask"})(y9||={})});import{z as E}from"zod";function tX($){let Z=$z.safeParse($);if(Z.success)return{success:!0,data:Z.data};return{success:!1,error:Z.error}}var a1,S_,f_,h_,x_,p_,m_,g_,u_,d_,c_,l_,dT,i_,r_,a_,n_,o_,s_,t_,e_,$z,Zz,Yz,Qz,E9,Xz,r1,cT;var eX=b(()=>{v8();a1=E.object({hook_event_name:E.nativeEnum(N2),hook_execution_id:E.string(),timestamp:E.string(),project_dir:E.string(),session_id:E.string(),permission_mode:E.enum(["default","autoEdit","yolo","plan"]),_metadata:E.object({blade_version:E.string(),hook_timeout_ms:E.number()}).optional()}),S_=a1.extend({hook_event_name:E.literal("PreToolUse"),tool_name:E.string(),tool_use_id:E.string(),tool_input:E.record(E.unknown())}),f_=a1.extend({hook_event_name:E.literal("PostToolUse"),tool_name:E.string(),tool_use_id:E.string(),tool_input:E.record(E.unknown()),tool_response:E.unknown()}),h_=a1.extend({hook_event_name:E.literal("Stop"),reason:E.string().optional()}),x_=a1.extend({hook_event_name:E.literal("PostToolUseFailure"),tool_name:E.string(),tool_use_id:E.string(),tool_input:E.record(E.unknown()),error:E.string(),error_type:E.string().optional(),is_interrupt:E.boolean(),is_timeout:E.boolean()}),p_=a1.extend({hook_event_name:E.literal("PermissionRequest"),tool_name:E.string(),tool_use_id:E.string(),tool_input:E.record(E.unknown())}),m_=a1.extend({hook_event_name:E.literal("UserPromptSubmit"),user_prompt:E.string(),has_images:E.boolean(),image_count:E.number()}),g_=a1.extend({hook_event_name:E.literal("SessionStart"),is_resume:E.boolean(),resume_session_id:E.string().optional()}),u_=a1.extend({hook_event_name:E.literal("SessionEnd"),reason:E.enum(["user_exit","error","max_turns","idle_timeout","ctrl_c","clear","logout","other"])}),d_=a1.extend({hook_event_name:E.literal("SubagentStop"),agent_type:E.string(),task_description:E.string().optional(),success:E.boolean(),result_summary:E.string().optional(),error:E.string().optional()}),c_=a1.extend({hook_event_name:E.literal("Notification"),notification_type:E.enum(["permission_prompt","idle_prompt","auth_success","elicitation_dialog","info","warning","error"]),title:E.string().optional(),message:E.string()}),l_=a1.extend({hook_event_name:E.literal("Compaction"),trigger:E.enum(["manual","auto"]),messages_before:E.number(),tokens_before:E.number()}),dT=E.discriminatedUnion("hook_event_name",[S_,f_,h_,x_,p_,m_,g_,u_,d_,c_,l_]),i_=E.object({hookEventName:E.literal("PreToolUse"),permissionDecision:E.nativeEnum(y9).optional(),permissionDecisionReason:E.string().optional(),updatedInput:E.record(E.unknown()).optional()}),r_=E.object({hookEventName:E.literal("PostToolUse"),additionalContext:E.string().optional(),updatedOutput:E.unknown().optional()}),a_=E.object({hookEventName:E.literal("Stop"),continue:E.boolean().optional(),continueReason:E.string().optional()}),n_=E.object({hookEventName:E.literal("SubagentStop"),continue:E.boolean().optional(),continueReason:E.string().optional(),additionalContext:E.string().optional()}),o_=E.object({hookEventName:E.literal("PermissionRequest"),permissionDecision:E.enum(["approve","deny","ask"]).optional(),permissionDecisionReason:E.string().optional()}),s_=E.object({hookEventName:E.literal("UserPromptSubmit"),updatedPrompt:E.string().optional(),contextInjection:E.string().optional()}),t_=E.object({hookEventName:E.literal("SessionStart"),env:E.record(E.string()).optional()}),e_=E.object({hookEventName:E.literal("Compaction"),blockCompaction:E.boolean().optional(),blockReason:E.string().optional()}),$z=E.object({decision:E.object({behavior:E.nativeEnum(T9)}).optional(),systemMessage:E.string().optional(),hookSpecificOutput:E.discriminatedUnion("hookEventName",[i_,r_,a_,n_,o_,s_,t_,e_]).optional(),suppressOutput:E.boolean().optional()}),Zz=E.object({type:E.literal("command"),command:E.string(),timeout:E.number().positive().optional(),statusMessage:E.string().optional()}),Yz=E.object({type:E.literal("prompt"),prompt:E.string(),timeout:E.number().positive().optional()}),Qz=E.discriminatedUnion("type",[Zz,Yz]),E9=E.union([E.string(),E.array(E.string())]),Xz=E.object({tools:E9.optional(),paths:E9.optional(),commands:E9.optional()}),r1=E.object({name:E.string().optional(),matcher:Xz.optional(),hooks:E.array(Qz)}),cT=E.object({enabled:E.boolean().optional(),defaultTimeout:E.number().positive().optional(),timeoutBehavior:E.enum(["ignore","deny","ask"]).optional(),failureBehavior:E.enum(["ignore","deny","ask"]).optional(),maxConcurrentHooks:E.number().positive().optional(),PreToolUse:E.array(r1).optional(),PostToolUse:E.array(r1).optional(),PostToolUseFailure:E.array(r1).optional(),PermissionRequest:E.array(r1).optional(),UserPromptSubmit:E.array(r1).optional(),SessionStart:E.array(r1).optional(),SessionEnd:E.array(r1).optional(),Stop:E.array(r1).optional(),SubagentStop:E.array(r1).optional(),Notification:E.array(r1).optional(),Compaction:E.array(r1).optional()})});class I9{parse($,Z,Y){if($.timedOut){let X=Y?.timeoutBehavior||"ignore",J="Hook timeout";if(X==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z}}let Q=this.tryParseJSON($.stdout);if(Q){let X=tX(Q);if(!X.success){let G="error"in X?X.error.message:"Unknown validation error",q=Y?.failureBehavior||"ignore",K=`Invalid hook output JSON: ${G}`;if(q==="deny")return{success:!1,blocking:!0,error:K,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else if(q==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${K}. Continue?`,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else return{success:!1,blocking:!1,warning:K,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z}}let J=X.data;if(J.decision?.behavior==="block")return{success:!1,blocking:!0,error:J.systemMessage||"Hook blocked execution",output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};if(J.decision?.behavior==="async")return{success:!0,output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};return{success:!0,output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z}}return this.parseByExitCode($,Z,Y)}parseByExitCode($,Z,Y){let Q=$.exitCode;switch(Q){case 0:return{success:!0,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};case 2:return{success:!1,blocking:!0,error:$.stderr||$.stdout||"Hook returned exit code 2",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};case 124:{let X=Y?.timeoutBehavior||"ignore",J="Hook timeout";if(X==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z}}default:{let X=Y?.failureBehavior||"ignore",J=$.stderr||$.stdout||`Hook failed with exit code ${Q}`;if(X==="deny")return{success:!1,blocking:!0,error:J,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${J}. Continue?`,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else return{success:!1,blocking:!1,warning:J,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z}}}}tryParseJSON($){try{let Z=$.trim();if(!Z)return null;let Y=Z.match(/^\s*(\{[\s\S]*\})\s*$/);if(!Y)return null;return JSON.parse(Y[1])}catch{return null}}}var $J=b(()=>{eX()});import{spawn as Jz}from"child_process";class P9{content="";maxSize;constructor($){this.maxSize=$}append($){if(this.content.length<this.maxSize){let Z=this.maxSize-this.content.length;this.content+=$.substring(0,Z)}}getContent(){return this.content}isFull(){return this.content.length>=this.maxSize}}class v9{MAX_STDOUT_SIZE=1048576;MAX_STDERR_SIZE=1048576;MAX_INPUT_SIZE=102400;async execute($,Z,Y,Q){let X=JSON.stringify(Z);if(X.length>this.MAX_INPUT_SIZE)throw Error(`Hook input too large: ${X.length} bytes (max ${this.MAX_INPUT_SIZE})`);let J=this.createSafeEnv(Z),G=Jz($,[],{shell:!0,env:J,cwd:Y.projectDir,timeout:Q}),q=new P9(this.MAX_STDOUT_SIZE),K=new P9(this.MAX_STDERR_SIZE);G.stdout.setEncoding("utf8"),G.stderr.setEncoding("utf8"),G.stdout.on("data",(W)=>{q.append(W)}),G.stderr.on("data",(W)=>{K.append(W)});try{G.stdin.write(X),G.stdin.end()}catch(W){throw G.kill("SIGTERM"),Error(`Failed to write hook input: ${W}`)}return new Promise((W,U)=>{let H=!1,O=!1,F=null,_=()=>{if(F&&Y.abortSignal)Y.abortSignal.removeEventListener("abort",F),F=null},z=setTimeout(()=>{H=!0,G.kill("SIGKILL")},Q);if(G.on("close",(N)=>{if(O)return;O=!0,clearTimeout(z),_(),W({stdout:q.getContent(),stderr:K.getContent(),exitCode:H?124:N??1,timedOut:H})}),G.on("error",(N)=>{if(O)return;O=!0,clearTimeout(z),_(),U(N)}),Y.abortSignal)F=()=>{if(O)return;O=!0,clearTimeout(z),_(),G.kill("SIGTERM"),W({stdout:q.getContent(),stderr:"Hook cancelled by abort signal",exitCode:1,timedOut:!1})},Y.abortSignal.addEventListener("abort",F)})}createSafeEnv($){return{BLADE_PROJECT_DIR:$.project_dir,BLADE_SESSION_ID:$.session_id,BLADE_HOOK_EVENT:$.hook_event_name,BLADE_TOOL_NAME:"tool_name"in $?$.tool_name:"",BLADE_TOOL_USE_ID:"tool_use_id"in $?$.tool_use_id:"",PATH:process.env.PATH||"",HOME:process.env.HOME||"",USER:process.env.USER||"",SHELL:process.env.SHELL||"/bin/sh"}}}var ZJ=()=>{};class C9{processExecutor=new v9;outputParser=new I9;async executePreToolHooks($,Z,Y){if($.length===0)return{decision:"allow"};let Q="tool_input"in Z?Z.tool_input:{},X=[];for(let J of $)try{let G={...Z,...Q&&{tool_input:Q}},q=await this.executeHook(J,G,Y);if(!q.success){if(q.blocking)return{decision:"deny",reason:q.error};if(q.needsConfirmation)return{decision:"ask",reason:q.warning||q.error};if(q.warning)X.push(q.warning);continue}let K=q.output?.hookSpecificOutput;if(K&&"permissionDecision"in K){switch(K.permissionDecision){case"deny":return{decision:"deny",reason:K.permissionDecisionReason};case"ask":return{decision:"ask",reason:K.permissionDecisionReason};case"allow":break}if("updatedInput"in K&&K.updatedInput)Q={...Q,...K.updatedInput}}}catch(G){let q=G instanceof Error?G.message:String(G);if(X.push(`Hook failed: ${q}`),Y.config.failureBehavior==="deny")return{decision:"deny",reason:q};else if(Y.config.failureBehavior==="ask")return{decision:"ask",reason:`Hook failed: ${q}. Continue?`}}return{decision:"allow",modifiedInput:Q,warning:X.length>0?X.join(`
|
|
101
101
|
`):void 0}}async executePostToolHooks($,Z,Y){if($.length===0)return{};let Q=Y.config.maxConcurrentHooks||5,X=await this.executeHooksConcurrently($,Z,Y,Q),J=[],G=void 0,q=[];for(let K of X){if(!K.success&&K.warning){q.push(K.warning);continue}let W=K.output?.hookSpecificOutput;if(W&&"additionalContext"in W){if(W.additionalContext)J.push(W.additionalContext);if("updatedOutput"in W&&W.updatedOutput!==void 0)G=W.updatedOutput}}return{additionalContext:J.length>0?J.join(`
|
|
102
102
|
|
|
103
103
|
`):void 0,modifiedOutput:G,warning:q.length>0?q.join(`
|
|
@@ -120,9 +120,9 @@ ${Y.structure}`);return Q.length>0?Q.join(`
|
|
|
120
120
|
`):void 0}}async executeNotificationHooks($,Z,Y){let Q="message"in Z?Z.message:"";if($.length===0)return{suppress:!1,message:Q};let X=[],J=!1,G=Q;for(let q of $)try{let K=await this.executeHook(q,Z,Y);if(!K.success){if(K.warning)X.push(K.warning);continue}if(K.output?.suppressOutput){J=!0;break}if(K.stdout&&K.stdout.trim())G=K.stdout.trim()}catch(K){let W=K instanceof Error?K.message:String(K);X.push(`Hook failed: ${W}`)}return{suppress:J,message:G,warning:X.length>0?X.join(`
|
|
121
121
|
`):void 0}}async executeCompactionHooks($,Z,Y){if($.length===0)return{blockCompaction:!1};let Q=[];for(let X of $)try{let J=await this.executeHook(X,Z,Y);if(!J.success){if(J.warning)Q.push(J.warning);continue}let G=J.output?.hookSpecificOutput;if(G&&"blockCompaction"in G&&G.blockCompaction)return{blockCompaction:!0,blockReason:G.blockReason,warning:Q.length>0?Q.join(`
|
|
122
122
|
`):void 0}}catch(J){let G=J instanceof Error?J.message:String(J);Q.push(`Hook failed: ${G}`)}return{blockCompaction:!1,warning:Q.length>0?Q.join(`
|
|
123
|
-
`):void 0}}async executeHook($,Z,Y){if($.type==="command")return this.executeCommandHook($,Z,Y);throw Error(`Hook type ${$.type} not yet implemented`)}async executeCommandHook($,Z,Y){let Q=($.timeout??Y.config.defaultTimeout??60)*1000;try{let X=await this.processExecutor.execute($.command,Z,Y,Q);return this.outputParser.parse(X,$,{timeoutBehavior:Y.config.timeoutBehavior,failureBehavior:Y.config.failureBehavior})}catch(X){return{success:!1,blocking:!1,error:X instanceof Error?X.message:String(X),hook:$}}}async executeHooksConcurrently($,Z,Y,Q){let X=[],J=new Set;for(let G of $){if(J.size>=Q)await Promise.race(J);let q=this.executeHook(G,Z,Y).catch((W)=>({success:!1,blocking:!1,error:W instanceof Error?W.message:String(W),hook:G})),K=q.then(()=>{J.delete(K)}).catch(()=>{J.delete(K)});J.add(K),X.push(q)}return Promise.all(X)}}var YJ=b(()=>{$J();ZJ();v8()});import k5 from"picomatch";class S5{matches($,Z){if(!$)return!0;if($.tools&&Z.toolName){if(!this.matchTools($.tools,Z))return!1}if($.paths&&Z.filePath){if(!this.matchPaths($.paths,Z.filePath))return!1}if($.commands&&Z.command){if(!this.matchCommands($.commands,Z.command))return!1}return!0}matchTools($,Z){if(Array.isArray($))return $.some((Y)=>this.matchToolWithParams(Y,Z));return this.matchToolWithParams($,Z)}matchPaths($,Z){if(Array.isArray($))return $.some((Q)=>{return k5(Q)(Z)});return k5($)(Z)}matchCommands($,Z){if(Array.isArray($))return $.some((Y)=>this.matchPattern(Z,Y));return this.matchPattern(Z,$)}matchToolWithParams($,Z){let{toolName:Y,command:Q,filePath:X}=Z,J=Gz.exec($);if(!J)return this.matchPattern(Y,$);let[,G,q]=J;if(!this.matchPattern(Y,G))return!1;let K=this.getArgValue(Y,Q,X);if(!K)return!1;return this.matchGlobOrPattern(K,q)}getArgValue($,Z,Y){if($==="Bash"||$==="BashTool")return Z;if(["Read","Edit","Write","Glob","Grep"].includes($))return Y;return Z||Y}matchGlobOrPattern($,Z){if(/[*?[\]{}!]/.test(Z))try{return k5(Z,{bash:!0,dot:!0})($)}catch{}if(Z.endsWith("*")){let Y=Z.slice(0,-1);return $.startsWith(Y)}return $===Z}matchPattern($,Z){if(Z==="*")return!0;if(!Z.includes("|")&&!/[.*+?^${}()|[\]\\]/.test(Z))return $===Z;if(Z.includes("|"))return Z.split("|").map((Q)=>Q.trim()).includes($);try{return new RegExp(Z).test($)}catch{return $===Z}}}var Gz;var QJ=b(()=>{Gz=/^([A-Za-z0-9_|]+)\((.+)\)$/});import{nanoid as n1}from"nanoid";class T0{static instance=null;config=D5;executor=new C5;guard=new j5;matcher=new S5;sessionDisabled=!1;constructor(){}static getInstance(){if(!T0.instance)T0.instance=new T0;return T0.instance}loadConfig($){let Z=M5(D5,$),Y=oX();Z=M5(Z,Y),this.config=Z}isEnabled(){if(!this.config.enabled)return!1;if(this.sessionDisabled)return!1;return!0}disable(){this.sessionDisabled=!0,console.log("[HookManager] Hooks disabled for this session")}enable(){this.sessionDisabled=!1,console.log("[HookManager] Hooks enabled for this session")}getConfig(){return this.config}async reloadConfig(){let $=await import("node:fs/promises"),Z=await import("node:path");try{let Y=Z.join(process.cwd(),".blade","settings.local.json"),Q=await $.readFile(Y,"utf-8"),X=JSON.parse(Q);if(X.hooks)this.loadConfig(X.hooks)}catch{}}async executePreToolHooks($,Z,Y,Q){if(!this.isEnabled())return{decision:"allow"};if(Q.permissionMode==="plan")return{decision:"allow"};if(!this.guard.canExecute(Z,"PreToolUse"))return{decision:"allow"};let X={hook_event_name:"PreToolUse",hook_execution_id:n1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,project_dir:Q.projectDir,session_id:Q.sessionId,permission_mode:Q.permissionMode},J=this.getMatchingHooks("PreToolUse",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(J.length===0)return{decision:"allow"};let G={projectDir:Q.projectDir,sessionId:Q.sessionId,permissionMode:Q.permissionMode,config:this.config,abortSignal:Q.abortSignal};try{let q=await this.executor.executePreToolHooks(J,X,G);if(this.guard.markExecuted(Z,"PreToolUse"),Q.permissionMode==="yolo"){if(q.decision==="deny")return q;return{decision:"allow",modifiedInput:q.modifiedInput,warning:q.warning,reason:q.reason}}return q}catch(q){return console.error("[HookManager] Error executing PreToolUse hooks:",q),{decision:"allow",warning:`Hook execution failed: ${q instanceof Error?q.message:String(q)}`}}}async executePostToolHooks($,Z,Y,Q,X){if(!this.isEnabled())return{};if(X.permissionMode==="plan")return{};if(!this.guard.canExecute(Z,"PostToolUse"))return{};let J={hook_event_name:"PostToolUse",hook_execution_id:n1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,tool_response:Q,project_dir:X.projectDir,session_id:X.sessionId,permission_mode:X.permissionMode},G=this.getMatchingHooks("PostToolUse",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(G.length===0)return{};let q={projectDir:X.projectDir,sessionId:X.sessionId,permissionMode:X.permissionMode,config:this.config,abortSignal:X.abortSignal};try{let K=await this.executor.executePostToolHooks(G,J,q);return this.guard.markExecuted(Z,"PostToolUse"),K}catch(K){return console.error("[HookManager] Error executing PostToolUse hooks:",K),{warning:`Hook execution failed: ${K instanceof Error?K.message:String(K)}`}}finally{this.guard.cleanup(Z)}}async executeStopHooks($){if(!this.isEnabled())return{shouldStop:!0};let Z={hook_event_name:"Stop",hook_execution_id:n1(),timestamp:new Date().toISOString(),project_dir:$.projectDir,session_id:$.sessionId,permission_mode:$.permissionMode,reason:$.reason},Y=this.getMatchingHooks("Stop",{});if(Y.length===0)return{shouldStop:!0};let Q={projectDir:$.projectDir,sessionId:$.sessionId,permissionMode:$.permissionMode,config:this.config,abortSignal:$.abortSignal};try{return await this.executor.executeStopHooks(Y,Z,Q)}catch(X){return console.error("[HookManager] Error executing Stop hooks:",X),{shouldStop:!0,warning:`Hook execution failed: ${X instanceof Error?X.message:String(X)}`}}}async executeSubagentStopHooks($,Z){if(!this.isEnabled())return{shouldStop:!0};let Y={hook_event_name:"SubagentStop",hook_execution_id:n1(),timestamp:new Date().toISOString(),project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode,agent_type:$,task_description:Z.taskDescription,success:Z.success,result_summary:Z.resultSummary,error:Z.error},Q=this.getMatchingHooks("SubagentStop",{});if(Q.length===0)return{shouldStop:!0};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeSubagentStopHooks(Q,Y,X)}catch(J){return console.error("[HookManager] Error executing SubagentStop hooks:",J),{shouldStop:!0,warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executePermissionRequestHooks($,Z,Y,Q){if(!this.isEnabled())return{decision:"ask"};let X={hook_event_name:"PermissionRequest",hook_execution_id:n1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,project_dir:Q.projectDir,session_id:Q.sessionId,permission_mode:Q.permissionMode},J=this.getMatchingHooks("PermissionRequest",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(J.length===0)return{decision:"ask"};let G={projectDir:Q.projectDir,sessionId:Q.sessionId,permissionMode:Q.permissionMode,config:this.config,abortSignal:Q.abortSignal};try{return await this.executor.executePermissionRequestHooks(J,X,G)}catch(q){return console.error("[HookManager] Error executing PermissionRequest hooks:",q),{decision:"ask",warning:`Hook execution failed: ${q instanceof Error?q.message:String(q)}`}}}async executeUserPromptSubmitHooks($,Z){if(!this.isEnabled())return{proceed:!0};let Y={hook_event_name:"UserPromptSubmit",hook_execution_id:n1(),timestamp:new Date().toISOString(),user_prompt:$,has_images:Z.hasImages,image_count:Z.imageCount,project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode},Q=this.getMatchingHooks("UserPromptSubmit",{});if(Q.length===0)return{proceed:!0};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeUserPromptSubmitHooks(Q,Y,X)}catch(J){return console.error("[HookManager] Error executing UserPromptSubmit hooks:",J),{proceed:!0,warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executeSessionStartHooks($){if(!this.isEnabled())return{proceed:!0};let Z={hook_event_name:"SessionStart",hook_execution_id:n1(),timestamp:new Date().toISOString(),project_dir:$.projectDir,session_id:$.sessionId,permission_mode:$.permissionMode,is_resume:$.isResume,resume_session_id:$.resumeSessionId},Y=this.getMatchingHooks("SessionStart",{});if(Y.length===0)return{proceed:!0};let Q={projectDir:$.projectDir,sessionId:$.sessionId,permissionMode:$.permissionMode,config:this.config,abortSignal:$.abortSignal};try{return await this.executor.executeSessionStartHooks(Y,Z,Q)}catch(X){return console.error("[HookManager] Error executing SessionStart hooks:",X),{proceed:!0,warning:`Hook execution failed: ${X instanceof Error?X.message:String(X)}`}}}async executeSessionEndHooks($,Z){if(!this.isEnabled())return{};let Y={hook_event_name:"SessionEnd",hook_execution_id:n1(),timestamp:new Date().toISOString(),project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode,reason:$},Q=this.getMatchingHooks("SessionEnd",{});if(Q.length===0)return{};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeSessionEndHooks(Q,Y,X),{}}catch(J){return console.error("[HookManager] Error executing SessionEnd hooks:",J),{warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executePostToolUseFailureHooks($,Z,Y,Q,X){if(!this.isEnabled())return{};let J={hook_event_name:"PostToolUseFailure",hook_execution_id:n1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,error:Q,error_type:X.errorType,is_interrupt:X.isInterrupt,is_timeout:X.isTimeout,project_dir:X.projectDir,session_id:X.sessionId,permission_mode:X.permissionMode},G=this.getMatchingHooks("PostToolUseFailure",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(G.length===0)return{};let q={projectDir:X.projectDir,sessionId:X.sessionId,permissionMode:X.permissionMode,config:this.config,abortSignal:X.abortSignal};try{return await this.executor.executePostToolUseFailureHooks(G,J,q)}catch(K){return console.error("[HookManager] Error executing PostToolUseFailure hooks:",K),{warning:`Hook execution failed: ${K instanceof Error?K.message:String(K)}`}}}async executeNotificationHooks($,Z,Y){if(!this.isEnabled())return{suppress:!1,message:Z};let Q={hook_event_name:"Notification",hook_execution_id:n1(),timestamp:new Date().toISOString(),project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode,notification_type:$,title:Y.title,message:Z},X=this.getMatchingHooks("Notification",{});if(X.length===0)return{suppress:!1,message:Z};let J={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:this.config,abortSignal:Y.abortSignal};try{return await this.executor.executeNotificationHooks(X,Q,J)}catch(G){return console.error("[HookManager] Error executing Notification hooks:",G),{suppress:!1,message:Z,warning:`Hook execution failed: ${G instanceof Error?G.message:String(G)}`}}}async executeCompactionHooks($,Z){if(!this.isEnabled())return{blockCompaction:!1};let Y={hook_event_name:"Compaction",hook_execution_id:n1(),timestamp:new Date().toISOString(),project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode,trigger:$,messages_before:Z.messagesBefore,tokens_before:Z.tokensBefore},Q=this.getMatchingHooks("Compaction",{});if(Q.length===0)return{blockCompaction:!1};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeCompactionHooks(Q,Y,X)}catch(J){return console.error("[HookManager] Error executing Compaction hooks:",J),{blockCompaction:!1,warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}getMatchingHooks($,Z){let Y=this.config[$]||[],Q=[];for(let X of Y)if(this.matcher.matches(X.matcher,Z))Q.push(...X.hooks);return Q}extractFilePath($){let Z=["file_path","path","filePath","source","target"];for(let Y of Z){let Q=$[Y];if(typeof Q==="string")return Q}return}extractCommand($,Z){if($==="Bash"||$==="BashTool"){let Y=Z.command;if(typeof Y==="string")return Y}return}cleanup(){this.guard.cleanupAll()}}var K1=b(()=>{sX();YJ();QJ();v8()});function f5($){return $==="blade-free-tier"}function h5($){return f5($.apiKey)}var x5=()=>{};var p5,l6,m5,i6,qz,XJ=($)=>{return qz[$]||"openai-compatible"},Kz,JJ=($)=>{return Kz[$]||{}};var C8=b(()=>{p5=["anthropic","openai","deepseek","google-generative-ai","groq","openrouter"],l6={antigravity:{bladeProvider:"antigravity",icon:"\uD83D\uDE80",description:"OAuth 登录使用 Claude/Gemini (需 Code Assist 订阅)"},copilot:{bladeProvider:"copilot",icon:"\uD83D\uDC19",description:"OAuth 登录使用 GPT/Claude/Gemini (需 Copilot 订阅)"}},m5={anthropic:"\uD83E\uDD16",openai:"⚡","google-generative-ai":"✨",deepseek:"\uD83C\uDF0A",groq:"\uD83D\uDE80",openrouter:"\uD83D\uDD00",azure:"☁️",ollama:"\uD83E\uDD99",together:"\uD83E\uDD1D",fireworks:"\uD83C\uDF86",mistral:"\uD83C\uDF00",cohere:"\uD83D\uDD2E",perplexity:"\uD83D\uDD0D",xai:"\uD83C\uDD67",default:"\uD83D\uDD0C"},i6={anthropic:"https://api.anthropic.com",openai:"https://api.openai.com/v1",google:"https://generativelanguage.googleapis.com/v1beta",deepseek:"https://api.deepseek.com/v1",groq:"https://api.groq.com/openai/v1",openrouter:"https://openrouter.ai/api/v1",togetherai:"https://api.together.xyz/v1","fireworks-ai":"https://api.fireworks.ai/inference/v1",mistral:"https://api.mistral.ai/v1",cohere:"https://api.cohere.ai/v1",perplexity:"https://api.perplexity.ai",xai:"https://api.x.ai/v1",cerebras:"https://api.cerebras.ai/v1","novita-ai":"https://api.novita.ai/v3/openai",nvidia:"https://integrate.api.nvidia.com/v1"},qz={anthropic:"anthropic",google:"gemini","google-vertex":"gemini","google-vertex-anthropic":"anthropic",azure:"azure-openai"},Kz={anthropic:{"anthropic-beta":"claude-code-20250219,interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14"},openrouter:{"HTTP-Referer":"https://github.com/anthropics/blade","X-Title":"Blade"},cerebras:{"X-Cerebras-3rd-Party-Integration":"blade"},vercel:{"http-referer":"https://github.com/anthropics/blade","x-title":"blade"},zenmux:{"HTTP-Referer":"https://github.com/anthropics/blade","X-Title":"blade"}}});import{ProxyAgent as Wz,fetch as Uz}from"undici";function Hz(){return process.env.HTTPS_PROXY||process.env.HTTP_PROXY||process.env.https_proxy||process.env.http_proxy}function Oz(){let $=Hz();if($)try{return new Wz($)}catch(Z){console.warn(`[proxyFetch] Invalid proxy URL: ${$}`)}return}async function M$($,Z={}){let{timeout:Y=30000,signal:Q,...X}=Z;if(Q?.aborted)throw new DOMException("The operation was aborted.","AbortError");let J=Oz(),G=new AbortController,q=!1,K=setTimeout(()=>{q=!0,G.abort()},Y),W=()=>G.abort();Q?.addEventListener("abort",W);try{let U={method:X.method,headers:X.headers,body:X.body,signal:G.signal,dispatcher:J};return await Uz($.toString(),U)}catch(U){if(U instanceof Error&&U.name==="AbortError"){if(q)throw Error(`Request timeout after ${Y}ms`);throw U}throw U}finally{clearTimeout(K),Q?.removeEventListener("abort",W)}}var d4=()=>{};var GJ,qJ,I3,P3,v3,r6;var C3=b(()=>{GJ={authorizationUrl:"https://accounts.google.com/o/oauth2/v2/auth",tokenUrl:"https://oauth2.googleapis.com/token",scopes:["https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/userinfo.profile","https://www.googleapis.com/auth/cclog","https://www.googleapis.com/auth/experimentsandconfigs"],clientId:"1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com",clientSecret:"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",redirectPort:51121,redirectPath:"/oauth-callback"},qJ={authorizationUrl:"https://accounts.google.com/o/oauth2/v2/auth",tokenUrl:"https://oauth2.googleapis.com/token",scopes:["https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/userinfo.profile"],clientId:"681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com",clientSecret:"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",redirectPort:45289,redirectPath:"/"},I3={production:"https://cloudcode-pa.googleapis.com",sandbox:"https://daily-cloudcode-pa.sandbox.googleapis.com"},P3={generateContent:"/v1internal:generateContent",streamGenerateContent:"/v1internal:streamGenerateContent",loadCodeAssist:"/v1internal:loadCodeAssist",onboardUser:"/v1internal:onboardUser"},v3={"claude-sonnet-4-5":{id:"claude-sonnet-4-5",name:"Claude Sonnet 4.5",provider:"anthropic",supportsThinking:!1,description:"平衡速度与质量的 Claude 模型"},"claude-sonnet-4-5-thinking":{id:"claude-sonnet-4-5-thinking",name:"Claude Sonnet 4.5 (Thinking)",provider:"anthropic",supportsThinking:!0,description:"支持思维链的 Claude Sonnet"},"claude-opus-4-5-thinking":{id:"claude-opus-4-5-thinking",name:"Claude Opus 4.5 (Thinking)",provider:"anthropic",supportsThinking:!0,description:"最强 Claude 模型,支持思维链"},"gemini-3-pro-high":{id:"gemini-3-pro-high",name:"Gemini 3 Pro (High)",provider:"google",supportsThinking:!1,description:"高质量 Gemini 模型 (Pro)"},"gemini-3-pro-low":{id:"gemini-3-pro-low",name:"Gemini 3 Pro (Low)",provider:"google",supportsThinking:!1,description:"快速 Gemini 模型 (Pro)"},"gemini-3-flash":{id:"gemini-3-flash",name:"Gemini 3 Flash",provider:"google",supportsThinking:!1,description:"超快速 Gemini 模型 (Pro)"},"gpt-oss-120b-medium":{id:"gpt-oss-120b-medium",name:"GPT-OSS 120B Medium",provider:"openai-oss",supportsThinking:!1,description:"OpenAI 开源模型"}},r6={"gemini-2.5-pro":{id:"gemini-2.5-pro",name:"Gemini 2.5 Pro",provider:"google",supportsThinking:!1,description:"最强 Gemini 2.5 模型,1M 上下文"},"gemini-2.5-flash":{id:"gemini-2.5-flash",name:"Gemini 2.5 Flash",provider:"google",supportsThinking:!1,description:"快速 Gemini 2.5 模型"},"gemini-2.5-flash-lite":{id:"gemini-2.5-flash-lite",name:"Gemini 2.5 Flash Lite",provider:"google",supportsThinking:!1,description:"轻量级 Gemini 2.5 模型"}}});import{spawn as Fz}from"child_process";import*as S3 from"crypto";import*as X4 from"fs/promises";import*as WJ from"http";import*as k3 from"path";import{URL as _z}from"url";function KJ($){return $==="gemini-cli"?qJ:GJ}function u5(){let $=process.env.HOME||process.env.USERPROFILE||"";return k3.join($,".blade")}class l${static instance=null;cachedToken=null;constructor(){}static getInstance(){if(!l$.instance)l$.instance=new l$;return l$.instance}async isLoggedIn(){let $=await this.loadToken();if(!$)return!1;let Z=300000;if($.expiresAt&&Date.now()>$.expiresAt-Z){if($.refreshToken)try{return await this.refreshToken(),!0}catch{return!1}return!1}return!0}async login($="antigravity"){let Z=$==="gemini-cli"?"Gemini CLI":"Antigravity";Q4.info(`\uD83D\uDD10 Starting ${Z} OAuth login...`);let Y=KJ($),Q=this.generatePKCEParams(),X=this.buildAuthorizationUrl(Q,Y);console.log(`
|
|
123
|
+
`):void 0}}async executeHook($,Z,Y){if($.type==="command")return this.executeCommandHook($,Z,Y);throw Error(`Hook type ${$.type} not yet implemented`)}async executeCommandHook($,Z,Y){let Q=($.timeout??Y.config.defaultTimeout??60)*1000;try{let X=await this.processExecutor.execute($.command,Z,Y,Q);return this.outputParser.parse(X,$,{timeoutBehavior:Y.config.timeoutBehavior,failureBehavior:Y.config.failureBehavior})}catch(X){return{success:!1,blocking:!1,error:X instanceof Error?X.message:String(X),hook:$}}}async executeHooksConcurrently($,Z,Y,Q){let X=[],J=new Set;for(let G of $){if(J.size>=Q)await Promise.race(J);let q=this.executeHook(G,Z,Y).catch((W)=>({success:!1,blocking:!1,error:W instanceof Error?W.message:String(W),hook:G})),K=q.then(()=>{J.delete(K)}).catch(()=>{J.delete(K)});J.add(K),X.push(q)}return Promise.all(X)}}var YJ=b(()=>{$J();ZJ();v8()});import k9 from"picomatch";class S9{matches($,Z){if(!$)return!0;if($.tools&&Z.toolName){if(!this.matchTools($.tools,Z))return!1}if($.paths&&Z.filePath){if(!this.matchPaths($.paths,Z.filePath))return!1}if($.commands&&Z.command){if(!this.matchCommands($.commands,Z.command))return!1}return!0}matchTools($,Z){if(Array.isArray($))return $.some((Y)=>this.matchToolWithParams(Y,Z));return this.matchToolWithParams($,Z)}matchPaths($,Z){if(Array.isArray($))return $.some((Q)=>{return k9(Q)(Z)});return k9($)(Z)}matchCommands($,Z){if(Array.isArray($))return $.some((Y)=>this.matchPattern(Z,Y));return this.matchPattern(Z,$)}matchToolWithParams($,Z){let{toolName:Y,command:Q,filePath:X}=Z,J=Gz.exec($);if(!J)return this.matchPattern(Y,$);let[,G,q]=J;if(!this.matchPattern(Y,G))return!1;let K=this.getArgValue(Y,Q,X);if(!K)return!1;return this.matchGlobOrPattern(K,q)}getArgValue($,Z,Y){if($==="Bash"||$==="BashTool")return Z;if(["Read","Edit","Write","Glob","Grep"].includes($))return Y;return Z||Y}matchGlobOrPattern($,Z){if(/[*?[\]{}!]/.test(Z))try{return k9(Z,{bash:!0,dot:!0})($)}catch{}if(Z.endsWith("*")){let Y=Z.slice(0,-1);return $.startsWith(Y)}return $===Z}matchPattern($,Z){if(Z==="*")return!0;if(!Z.includes("|")&&!/[.*+?^${}()|[\]\\]/.test(Z))return $===Z;if(Z.includes("|"))return Z.split("|").map((Q)=>Q.trim()).includes($);try{return new RegExp(Z).test($)}catch{return $===Z}}}var Gz;var QJ=b(()=>{Gz=/^([A-Za-z0-9_|]+)\((.+)\)$/});import{nanoid as n1}from"nanoid";class T0{static instance=null;config=D9;executor=new C9;guard=new j9;matcher=new S9;sessionDisabled=!1;constructor(){}static getInstance(){if(!T0.instance)T0.instance=new T0;return T0.instance}loadConfig($){let Z=M9(D9,$),Y=oX();Z=M9(Z,Y),this.config=Z}isEnabled(){if(!this.config.enabled)return!1;if(this.sessionDisabled)return!1;return!0}disable(){this.sessionDisabled=!0,console.log("[HookManager] Hooks disabled for this session")}enable(){this.sessionDisabled=!1,console.log("[HookManager] Hooks enabled for this session")}getConfig(){return this.config}async reloadConfig(){let $=await import("node:fs/promises"),Z=await import("node:path");try{let Y=Z.join(process.cwd(),".blade","settings.local.json"),Q=await $.readFile(Y,"utf-8"),X=JSON.parse(Q);if(X.hooks)this.loadConfig(X.hooks)}catch{}}async executePreToolHooks($,Z,Y,Q){if(!this.isEnabled())return{decision:"allow"};if(Q.permissionMode==="plan")return{decision:"allow"};if(!this.guard.canExecute(Z,"PreToolUse"))return{decision:"allow"};let X={hook_event_name:"PreToolUse",hook_execution_id:n1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,project_dir:Q.projectDir,session_id:Q.sessionId,permission_mode:Q.permissionMode},J=this.getMatchingHooks("PreToolUse",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(J.length===0)return{decision:"allow"};let G={projectDir:Q.projectDir,sessionId:Q.sessionId,permissionMode:Q.permissionMode,config:this.config,abortSignal:Q.abortSignal};try{let q=await this.executor.executePreToolHooks(J,X,G);if(this.guard.markExecuted(Z,"PreToolUse"),Q.permissionMode==="yolo"){if(q.decision==="deny")return q;return{decision:"allow",modifiedInput:q.modifiedInput,warning:q.warning,reason:q.reason}}return q}catch(q){return console.error("[HookManager] Error executing PreToolUse hooks:",q),{decision:"allow",warning:`Hook execution failed: ${q instanceof Error?q.message:String(q)}`}}}async executePostToolHooks($,Z,Y,Q,X){if(!this.isEnabled())return{};if(X.permissionMode==="plan")return{};if(!this.guard.canExecute(Z,"PostToolUse"))return{};let J={hook_event_name:"PostToolUse",hook_execution_id:n1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,tool_response:Q,project_dir:X.projectDir,session_id:X.sessionId,permission_mode:X.permissionMode},G=this.getMatchingHooks("PostToolUse",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(G.length===0)return{};let q={projectDir:X.projectDir,sessionId:X.sessionId,permissionMode:X.permissionMode,config:this.config,abortSignal:X.abortSignal};try{let K=await this.executor.executePostToolHooks(G,J,q);return this.guard.markExecuted(Z,"PostToolUse"),K}catch(K){return console.error("[HookManager] Error executing PostToolUse hooks:",K),{warning:`Hook execution failed: ${K instanceof Error?K.message:String(K)}`}}finally{this.guard.cleanup(Z)}}async executeStopHooks($){if(!this.isEnabled())return{shouldStop:!0};let Z={hook_event_name:"Stop",hook_execution_id:n1(),timestamp:new Date().toISOString(),project_dir:$.projectDir,session_id:$.sessionId,permission_mode:$.permissionMode,reason:$.reason},Y=this.getMatchingHooks("Stop",{});if(Y.length===0)return{shouldStop:!0};let Q={projectDir:$.projectDir,sessionId:$.sessionId,permissionMode:$.permissionMode,config:this.config,abortSignal:$.abortSignal};try{return await this.executor.executeStopHooks(Y,Z,Q)}catch(X){return console.error("[HookManager] Error executing Stop hooks:",X),{shouldStop:!0,warning:`Hook execution failed: ${X instanceof Error?X.message:String(X)}`}}}async executeSubagentStopHooks($,Z){if(!this.isEnabled())return{shouldStop:!0};let Y={hook_event_name:"SubagentStop",hook_execution_id:n1(),timestamp:new Date().toISOString(),project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode,agent_type:$,task_description:Z.taskDescription,success:Z.success,result_summary:Z.resultSummary,error:Z.error},Q=this.getMatchingHooks("SubagentStop",{});if(Q.length===0)return{shouldStop:!0};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeSubagentStopHooks(Q,Y,X)}catch(J){return console.error("[HookManager] Error executing SubagentStop hooks:",J),{shouldStop:!0,warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executePermissionRequestHooks($,Z,Y,Q){if(!this.isEnabled())return{decision:"ask"};let X={hook_event_name:"PermissionRequest",hook_execution_id:n1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,project_dir:Q.projectDir,session_id:Q.sessionId,permission_mode:Q.permissionMode},J=this.getMatchingHooks("PermissionRequest",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(J.length===0)return{decision:"ask"};let G={projectDir:Q.projectDir,sessionId:Q.sessionId,permissionMode:Q.permissionMode,config:this.config,abortSignal:Q.abortSignal};try{return await this.executor.executePermissionRequestHooks(J,X,G)}catch(q){return console.error("[HookManager] Error executing PermissionRequest hooks:",q),{decision:"ask",warning:`Hook execution failed: ${q instanceof Error?q.message:String(q)}`}}}async executeUserPromptSubmitHooks($,Z){if(!this.isEnabled())return{proceed:!0};let Y={hook_event_name:"UserPromptSubmit",hook_execution_id:n1(),timestamp:new Date().toISOString(),user_prompt:$,has_images:Z.hasImages,image_count:Z.imageCount,project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode},Q=this.getMatchingHooks("UserPromptSubmit",{});if(Q.length===0)return{proceed:!0};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeUserPromptSubmitHooks(Q,Y,X)}catch(J){return console.error("[HookManager] Error executing UserPromptSubmit hooks:",J),{proceed:!0,warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executeSessionStartHooks($){if(!this.isEnabled())return{proceed:!0};let Z={hook_event_name:"SessionStart",hook_execution_id:n1(),timestamp:new Date().toISOString(),project_dir:$.projectDir,session_id:$.sessionId,permission_mode:$.permissionMode,is_resume:$.isResume,resume_session_id:$.resumeSessionId},Y=this.getMatchingHooks("SessionStart",{});if(Y.length===0)return{proceed:!0};let Q={projectDir:$.projectDir,sessionId:$.sessionId,permissionMode:$.permissionMode,config:this.config,abortSignal:$.abortSignal};try{return await this.executor.executeSessionStartHooks(Y,Z,Q)}catch(X){return console.error("[HookManager] Error executing SessionStart hooks:",X),{proceed:!0,warning:`Hook execution failed: ${X instanceof Error?X.message:String(X)}`}}}async executeSessionEndHooks($,Z){if(!this.isEnabled())return{};let Y={hook_event_name:"SessionEnd",hook_execution_id:n1(),timestamp:new Date().toISOString(),project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode,reason:$},Q=this.getMatchingHooks("SessionEnd",{});if(Q.length===0)return{};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeSessionEndHooks(Q,Y,X),{}}catch(J){return console.error("[HookManager] Error executing SessionEnd hooks:",J),{warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executePostToolUseFailureHooks($,Z,Y,Q,X){if(!this.isEnabled())return{};let J={hook_event_name:"PostToolUseFailure",hook_execution_id:n1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,error:Q,error_type:X.errorType,is_interrupt:X.isInterrupt,is_timeout:X.isTimeout,project_dir:X.projectDir,session_id:X.sessionId,permission_mode:X.permissionMode},G=this.getMatchingHooks("PostToolUseFailure",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(G.length===0)return{};let q={projectDir:X.projectDir,sessionId:X.sessionId,permissionMode:X.permissionMode,config:this.config,abortSignal:X.abortSignal};try{return await this.executor.executePostToolUseFailureHooks(G,J,q)}catch(K){return console.error("[HookManager] Error executing PostToolUseFailure hooks:",K),{warning:`Hook execution failed: ${K instanceof Error?K.message:String(K)}`}}}async executeNotificationHooks($,Z,Y){if(!this.isEnabled())return{suppress:!1,message:Z};let Q={hook_event_name:"Notification",hook_execution_id:n1(),timestamp:new Date().toISOString(),project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode,notification_type:$,title:Y.title,message:Z},X=this.getMatchingHooks("Notification",{});if(X.length===0)return{suppress:!1,message:Z};let J={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:this.config,abortSignal:Y.abortSignal};try{return await this.executor.executeNotificationHooks(X,Q,J)}catch(G){return console.error("[HookManager] Error executing Notification hooks:",G),{suppress:!1,message:Z,warning:`Hook execution failed: ${G instanceof Error?G.message:String(G)}`}}}async executeCompactionHooks($,Z){if(!this.isEnabled())return{blockCompaction:!1};let Y={hook_event_name:"Compaction",hook_execution_id:n1(),timestamp:new Date().toISOString(),project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode,trigger:$,messages_before:Z.messagesBefore,tokens_before:Z.tokensBefore},Q=this.getMatchingHooks("Compaction",{});if(Q.length===0)return{blockCompaction:!1};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeCompactionHooks(Q,Y,X)}catch(J){return console.error("[HookManager] Error executing Compaction hooks:",J),{blockCompaction:!1,warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}getMatchingHooks($,Z){let Y=this.config[$]||[],Q=[];for(let X of Y)if(this.matcher.matches(X.matcher,Z))Q.push(...X.hooks);return Q}extractFilePath($){let Z=["file_path","path","filePath","source","target"];for(let Y of Z){let Q=$[Y];if(typeof Q==="string")return Q}return}extractCommand($,Z){if($==="Bash"||$==="BashTool"){let Y=Z.command;if(typeof Y==="string")return Y}return}cleanup(){this.guard.cleanupAll()}}var K1=b(()=>{sX();YJ();QJ();v8()});function f9($){return $==="blade-free-tier"}function h9($){return f9($.apiKey)}var x9=()=>{};var p9,l6,m9,i6,qz,XJ=($)=>{return qz[$]||"openai-compatible"},Kz,JJ=($)=>{return Kz[$]||{}};var C8=b(()=>{p9=["anthropic","openai","deepseek","google-generative-ai","groq","openrouter"],l6={antigravity:{bladeProvider:"antigravity",icon:"\uD83D\uDE80",description:"OAuth 登录使用 Claude/Gemini (需 Code Assist 订阅)"},copilot:{bladeProvider:"copilot",icon:"\uD83D\uDC19",description:"OAuth 登录使用 GPT/Claude/Gemini (需 Copilot 订阅)"}},m9={anthropic:"\uD83E\uDD16",openai:"⚡","google-generative-ai":"✨",deepseek:"\uD83C\uDF0A",groq:"\uD83D\uDE80",openrouter:"\uD83D\uDD00",azure:"☁️",ollama:"\uD83E\uDD99",together:"\uD83E\uDD1D",fireworks:"\uD83C\uDF86",mistral:"\uD83C\uDF00",cohere:"\uD83D\uDD2E",perplexity:"\uD83D\uDD0D",xai:"\uD83C\uDD67",default:"\uD83D\uDD0C"},i6={anthropic:"https://api.anthropic.com",openai:"https://api.openai.com/v1",google:"https://generativelanguage.googleapis.com/v1beta",deepseek:"https://api.deepseek.com/v1",groq:"https://api.groq.com/openai/v1",openrouter:"https://openrouter.ai/api/v1",togetherai:"https://api.together.xyz/v1","fireworks-ai":"https://api.fireworks.ai/inference/v1",mistral:"https://api.mistral.ai/v1",cohere:"https://api.cohere.ai/v1",perplexity:"https://api.perplexity.ai",xai:"https://api.x.ai/v1",cerebras:"https://api.cerebras.ai/v1","novita-ai":"https://api.novita.ai/v3/openai",nvidia:"https://integrate.api.nvidia.com/v1"},qz={anthropic:"anthropic",google:"gemini","google-vertex":"gemini","google-vertex-anthropic":"anthropic",azure:"azure-openai"},Kz={anthropic:{"anthropic-beta":"claude-code-20250219,interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14"},openrouter:{"HTTP-Referer":"https://github.com/anthropics/blade","X-Title":"Blade"},cerebras:{"X-Cerebras-3rd-Party-Integration":"blade"},vercel:{"http-referer":"https://github.com/anthropics/blade","x-title":"blade"},zenmux:{"HTTP-Referer":"https://github.com/anthropics/blade","X-Title":"blade"}}});import{ProxyAgent as Wz,fetch as Uz}from"undici";function Hz(){return process.env.HTTPS_PROXY||process.env.HTTP_PROXY||process.env.https_proxy||process.env.http_proxy}function Oz(){let $=Hz();if($)try{return new Wz($)}catch(Z){console.warn(`[proxyFetch] Invalid proxy URL: ${$}`)}return}async function M$($,Z={}){let{timeout:Y=30000,signal:Q,...X}=Z;if(Q?.aborted)throw new DOMException("The operation was aborted.","AbortError");let J=Oz(),G=new AbortController,q=!1,K=setTimeout(()=>{q=!0,G.abort()},Y),W=()=>G.abort();Q?.addEventListener("abort",W);try{let U={method:X.method,headers:X.headers,body:X.body,signal:G.signal,dispatcher:J};return await Uz($.toString(),U)}catch(U){if(U instanceof Error&&U.name==="AbortError"){if(q)throw Error(`Request timeout after ${Y}ms`);throw U}throw U}finally{clearTimeout(K),Q?.removeEventListener("abort",W)}}var d4=()=>{};var GJ,qJ,I3,P3,v3,r6;var C3=b(()=>{GJ={authorizationUrl:"https://accounts.google.com/o/oauth2/v2/auth",tokenUrl:"https://oauth2.googleapis.com/token",scopes:["https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/userinfo.profile","https://www.googleapis.com/auth/cclog","https://www.googleapis.com/auth/experimentsandconfigs"],clientId:"1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com",clientSecret:"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",redirectPort:51121,redirectPath:"/oauth-callback"},qJ={authorizationUrl:"https://accounts.google.com/o/oauth2/v2/auth",tokenUrl:"https://oauth2.googleapis.com/token",scopes:["https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/userinfo.profile"],clientId:"681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com",clientSecret:"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",redirectPort:45289,redirectPath:"/"},I3={production:"https://cloudcode-pa.googleapis.com",sandbox:"https://daily-cloudcode-pa.sandbox.googleapis.com"},P3={generateContent:"/v1internal:generateContent",streamGenerateContent:"/v1internal:streamGenerateContent",loadCodeAssist:"/v1internal:loadCodeAssist",onboardUser:"/v1internal:onboardUser"},v3={"claude-sonnet-4-5":{id:"claude-sonnet-4-5",name:"Claude Sonnet 4.5",provider:"anthropic",supportsThinking:!1,description:"平衡速度与质量的 Claude 模型"},"claude-sonnet-4-5-thinking":{id:"claude-sonnet-4-5-thinking",name:"Claude Sonnet 4.5 (Thinking)",provider:"anthropic",supportsThinking:!0,description:"支持思维链的 Claude Sonnet"},"claude-opus-4-5-thinking":{id:"claude-opus-4-5-thinking",name:"Claude Opus 4.5 (Thinking)",provider:"anthropic",supportsThinking:!0,description:"最强 Claude 模型,支持思维链"},"gemini-3-pro-high":{id:"gemini-3-pro-high",name:"Gemini 3 Pro (High)",provider:"google",supportsThinking:!1,description:"高质量 Gemini 模型 (Pro)"},"gemini-3-pro-low":{id:"gemini-3-pro-low",name:"Gemini 3 Pro (Low)",provider:"google",supportsThinking:!1,description:"快速 Gemini 模型 (Pro)"},"gemini-3-flash":{id:"gemini-3-flash",name:"Gemini 3 Flash",provider:"google",supportsThinking:!1,description:"超快速 Gemini 模型 (Pro)"},"gpt-oss-120b-medium":{id:"gpt-oss-120b-medium",name:"GPT-OSS 120B Medium",provider:"openai-oss",supportsThinking:!1,description:"OpenAI 开源模型"}},r6={"gemini-2.5-pro":{id:"gemini-2.5-pro",name:"Gemini 2.5 Pro",provider:"google",supportsThinking:!1,description:"最强 Gemini 2.5 模型,1M 上下文"},"gemini-2.5-flash":{id:"gemini-2.5-flash",name:"Gemini 2.5 Flash",provider:"google",supportsThinking:!1,description:"快速 Gemini 2.5 模型"},"gemini-2.5-flash-lite":{id:"gemini-2.5-flash-lite",name:"Gemini 2.5 Flash Lite",provider:"google",supportsThinking:!1,description:"轻量级 Gemini 2.5 模型"}}});import{spawn as Fz}from"child_process";import*as S3 from"crypto";import*as X4 from"fs/promises";import*as WJ from"http";import*as k3 from"path";import{URL as _z}from"url";function KJ($){return $==="gemini-cli"?qJ:GJ}function u9(){let $=process.env.HOME||process.env.USERPROFILE||"";return k3.join($,".blade")}class l${static instance=null;cachedToken=null;constructor(){}static getInstance(){if(!l$.instance)l$.instance=new l$;return l$.instance}async isLoggedIn(){let $=await this.loadToken();if(!$)return!1;let Z=300000;if($.expiresAt&&Date.now()>$.expiresAt-Z){if($.refreshToken)try{return await this.refreshToken(),!0}catch{return!1}return!1}return!0}async login($="antigravity"){let Z=$==="gemini-cli"?"Gemini CLI":"Antigravity";Q4.info(`\uD83D\uDD10 Starting ${Z} OAuth login...`);let Y=KJ($),Q=this.generatePKCEParams(),X=this.buildAuthorizationUrl(Q,Y);console.log(`
|
|
124
124
|
\uD83C\uDF10 Opening browser for Google authentication...`),console.log(`
|
|
125
|
-
If the browser does not open automatically, copy and paste this URL:`),console.log(X),console.log("");let J=this.startCallbackServer(Q.state,Y);try{await this.openBrowser(X)}catch(W){Q4.warn("Failed to open browser automatically:",W)}let G=await J;console.log("✅ Authorization code received, exchanging for tokens...");let q=await this.exchangeCodeForToken(G,Q.codeVerifier,Y),K={accessToken:q.access_token,refreshToken:q.refresh_token||"",expiresAt:Date.now()+q.expires_in*1000,tokenType:q.token_type||"Bearer",scope:q.scope,configType:$};await this.saveToken(K),this.cachedToken=K,console.log(`✅ ${Z} login successful!`),Q4.info(`${Z} OAuth login completed`)}async logout(){let $=k3.join(
|
|
125
|
+
If the browser does not open automatically, copy and paste this URL:`),console.log(X),console.log("");let J=this.startCallbackServer(Q.state,Y);try{await this.openBrowser(X)}catch(W){Q4.warn("Failed to open browser automatically:",W)}let G=await J;console.log("✅ Authorization code received, exchanging for tokens...");let q=await this.exchangeCodeForToken(G,Q.codeVerifier,Y),K={accessToken:q.access_token,refreshToken:q.refresh_token||"",expiresAt:Date.now()+q.expires_in*1000,tokenType:q.token_type||"Bearer",scope:q.scope,configType:$};await this.saveToken(K),this.cachedToken=K,console.log(`✅ ${Z} login successful!`),Q4.info(`${Z} OAuth login completed`)}async logout(){let $=k3.join(u9(),g9);try{await X4.unlink($),this.cachedToken=null,console.log("✅ Logged out from Antigravity"),Q4.info("Antigravity logout completed")}catch(Z){if(Z.code!=="ENOENT")throw Z;this.cachedToken=null}}async getAccessToken(){if(this.cachedToken){if(this.cachedToken.expiresAt>Date.now()+300000)return this.cachedToken.accessToken}let $=await this.loadToken();if(!$)throw Error("Not logged in. Please run /login first.");let Z=300000;if($.expiresAt<=Date.now()+Z){if(!$.refreshToken)throw Error("Token expired and no refresh token available. Please run /login again.");return await this.refreshToken(),this.cachedToken.accessToken}return this.cachedToken=$,$.accessToken}async refreshToken(){let $=await this.loadToken();if(!$||!$.refreshToken)throw Error("No refresh token available");let Z=$.configType||"antigravity",Y=KJ(Z),Q=Z==="gemini-cli"?"Gemini CLI":"Antigravity";Q4.info(`\uD83D\uDD04 Refreshing ${Q} access token...`);let X=new URLSearchParams({grant_type:"refresh_token",refresh_token:$.refreshToken,client_id:Y.clientId,client_secret:Y.clientSecret}),J=await M$(Y.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:X.toString()});if(!J.ok){let K=await J.text();throw Q4.error("Token refresh failed:",K),Error(`Token refresh failed: ${J.status}`)}let G=await J.json(),q={accessToken:G.access_token,refreshToken:G.refresh_token||$.refreshToken,expiresAt:Date.now()+G.expires_in*1000,tokenType:G.token_type||"Bearer",scope:G.scope||$.scope,configType:Z};await this.saveToken(q),this.cachedToken=q,Q4.info("✅ Token refreshed successfully")}generatePKCEParams(){let $=S3.randomBytes(32).toString("base64url"),Z=S3.createHash("sha256").update($).digest("base64url"),Y=S3.randomBytes(16).toString("base64url");return{codeVerifier:$,codeChallenge:Z,state:Y}}buildAuthorizationUrl($,Z){let Y=`http://localhost:${Z.redirectPort}${Z.redirectPath}`,Q=new URLSearchParams({client_id:Z.clientId,response_type:"code",redirect_uri:Y,state:$.state,code_challenge:$.codeChallenge,code_challenge_method:"S256",scope:Z.scopes.join(" "),access_type:"offline",prompt:"consent"});return`${Z.authorizationUrl}?${Q.toString()}`}async startCallbackServer($,Z){let{redirectPort:Y,redirectPath:Q}=Z;return new Promise((X,J)=>{let G=null,q=!1,K=()=>{if(G)clearTimeout(G),G=null},W=WJ.createServer((U,H)=>{try{let O=new _z(U.url,`http://localhost:${Y}`);if(O.pathname!==Q){H.writeHead(404),H.end("Not found");return}let F=O.searchParams.get("code"),_=O.searchParams.get("state"),z=O.searchParams.get("error");if(z){if(H.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),H.end(`
|
|
126
126
|
<html>
|
|
127
127
|
<head><title>Authentication Failed</title></head>
|
|
128
128
|
<body style="font-family: system-ui; padding: 40px; text-align: center;">
|
|
@@ -140,16 +140,16 @@ If the browser does not open automatically, copy and paste this URL:`),console.l
|
|
|
140
140
|
<script>setTimeout(() => window.close(), 2000);</script>
|
|
141
141
|
</body>
|
|
142
142
|
</html>
|
|
143
|
-
`),K(),W.close(),!q)q=!0,X(F)}catch(O){if(K(),W.close(),!q)q=!0,J(O)}});W.on("error",(U)=>{if(K(),!q)if(q=!0,U.code==="EADDRINUSE")J(Error(`Port ${Y} is already in use. Please close other applications using this port.`));else J(U)}),W.listen(Y,()=>{Q4.debug(`OAuth callback server listening on port ${Y}`)}),G=setTimeout(()=>{if(W.close(),!q)q=!0,J(Error("OAuth callback timeout (5 minutes)"))},300000)})}async exchangeCodeForToken($,Z,Y){let Q=`http://localhost:${Y.redirectPort}${Y.redirectPath}`,X=new URLSearchParams({grant_type:"authorization_code",code:$,redirect_uri:Q,code_verifier:Z,client_id:Y.clientId,client_secret:Y.clientSecret}),J=await M$(Y.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:X.toString()});if(!J.ok){let G=await J.text();throw Error(`Token exchange failed: ${J.status} - ${G}`)}return await J.json()}async openBrowser($){let Z,Y;if(process.platform==="darwin")Z="open",Y=[$];else if(process.platform==="win32")Z="cmd",Y=["/c","start","",$];else Z="xdg-open",Y=[$];await new Promise((Q,X)=>{let J=Fz(Z,Y,{stdio:"ignore"});J.once("error",X),J.once("close",(G)=>{if(G===0||G===null)Q();else X(Error(`Failed to open browser (exit code ${G})`))})})}async saveToken($){let Z=
|
|
144
|
-
`)}function
|
|
143
|
+
`),K(),W.close(),!q)q=!0,X(F)}catch(O){if(K(),W.close(),!q)q=!0,J(O)}});W.on("error",(U)=>{if(K(),!q)if(q=!0,U.code==="EADDRINUSE")J(Error(`Port ${Y} is already in use. Please close other applications using this port.`));else J(U)}),W.listen(Y,()=>{Q4.debug(`OAuth callback server listening on port ${Y}`)}),G=setTimeout(()=>{if(W.close(),!q)q=!0,J(Error("OAuth callback timeout (5 minutes)"))},300000)})}async exchangeCodeForToken($,Z,Y){let Q=`http://localhost:${Y.redirectPort}${Y.redirectPath}`,X=new URLSearchParams({grant_type:"authorization_code",code:$,redirect_uri:Q,code_verifier:Z,client_id:Y.clientId,client_secret:Y.clientSecret}),J=await M$(Y.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:X.toString()});if(!J.ok){let G=await J.text();throw Error(`Token exchange failed: ${J.status} - ${G}`)}return await J.json()}async openBrowser($){let Z,Y;if(process.platform==="darwin")Z="open",Y=[$];else if(process.platform==="win32")Z="cmd",Y=["/c","start","",$];else Z="xdg-open",Y=[$];await new Promise((Q,X)=>{let J=Fz(Z,Y,{stdio:"ignore"});J.once("error",X),J.once("close",(G)=>{if(G===0||G===null)Q();else X(Error(`Failed to open browser (exit code ${G})`))})})}async saveToken($){let Z=u9();await X4.mkdir(Z,{recursive:!0,mode:493});let Y=k3.join(Z,g9);await X4.writeFile(Y,JSON.stringify($,null,2),{mode:384})}async loadToken(){let $=k3.join(u9(),g9);try{let Z=await X4.readFile($,"utf-8");return JSON.parse(Z)}catch(Z){if(Z.code==="ENOENT")return null;throw Z}}async getStatus(){let $=await this.loadToken();if(!$)return{loggedIn:!1};return{loggedIn:!0,expiresAt:$.expiresAt?new Date($.expiresAt):void 0,configType:$.configType||"antigravity"}}async getConfigType(){let $=await this.loadToken();if(!$)return null;return $.configType||"antigravity"}}var Q4,g9="antigravity-token.json";var f3=b(()=>{Y0();d4();C3();Q4=p("Service")});function UJ($){if($==="antigravity")return{ideType:"ANTIGRAVITY"};return{ideType:"IDE_UNSPECIFIED",platform:"PLATFORM_UNSPECIFIED",pluginType:"GEMINI"}}function a6($){if($==="antigravity")return"antigravity/1.11.3 Darwin/arm64";return"gemini-cli/1.0.0"}function HJ($){let Z=new Set;for(let Y of $)if(Y.role==="assistant"&&Y.tool_calls)for(let Q of Y.tool_calls)Z.add(Q.id);return $.filter((Y)=>{if(Y.role==="tool"){if(!Y.tool_call_id)return!1;return Z.has(Y.tool_call_id)}return!0})}function n6($){if(typeof $==="string")return $;return $.filter((Z)=>Z.type==="text").map((Z)=>Z.text).join(`
|
|
144
|
+
`)}function d9($){let Z=["const","$ref","$defs","$schema","$id","default","examples"],Y={};for(let[Q,X]of Object.entries($)){if(Z.includes(Q)){if(Q==="const")Y.enum=[X];continue}if(X&&typeof X==="object"&&!Array.isArray(X))Y[Q]=d9(X);else if(Array.isArray(X))Y[Q]=X.map((J)=>J&&typeof J==="object"&&!Array.isArray(J)?d9(J):J);else Y[Q]=X}return Y}class c9{config;auth;projectId;userTier;sessionId;configType="antigravity";projectIdInitialized=!1;constructor($){this.config=$,this.auth=l$.getInstance(),this.projectId=void 0,this.sessionId=`session_${Date.now()}_${Math.random().toString(36).slice(2,11)}`,v0.debug("\uD83D\uDE80 [AntigravityChatService] Initializing"),v0.debug("⚙️ [AntigravityChatService] Config:",{model:$.model,temperature:$.temperature,maxOutputTokens:$.maxOutputTokens,sessionId:this.sessionId})}async ensureProjectId(){if(this.projectIdInitialized)return;try{let $=await this.auth.getConfigType();this.configType=$||"antigravity",v0.debug(`\uD83D\uDD04 [AntigravityChatService] Using OAuth config: ${this.configType}`),v0.debug("\uD83D\uDD04 [AntigravityChatService] Setting up user via loadCodeAssist...");let Z=await this.auth.getAccessToken(),Y=await this.callLoadCodeAssist(Z);if(v0.debug("[AntigravityChatService] loadCodeAssist response:",JSON.stringify(Y)),Y.currentTier){if(this.userTier=Y.currentTier.id,Y.cloudaicompanionProject){this.projectId=Y.cloudaicompanionProject,v0.debug(`✅ [AntigravityChatService] User already setup: tier=${this.userTier}, project=${this.projectId}`),this.projectIdInitialized=!0;return}let J=process.env.GOOGLE_CLOUD_PROJECT||process.env.GOOGLE_CLOUD_PROJECT_ID;if(J){this.projectId=J,v0.debug(`✅ [AntigravityChatService] Using env project: ${this.projectId}`),this.projectIdInitialized=!0;return}v0.debug("⚠️ [AntigravityChatService] Has tier but no project, need onboarding...")}let Q=this.getDefaultTier(Y);v0.debug(`\uD83D\uDD04 [AntigravityChatService] Onboarding user with tier: ${Q.id}`);let X=await this.callOnboardUser(Z,Q.id);this.projectId=X.projectId,this.userTier=Q.id,v0.debug(`✅ [AntigravityChatService] User setup complete: tier=${this.userTier}, project=${this.projectId||"(managed)"}`)}catch($){v0.warn("Failed to setup user:",$)}this.projectIdInitialized=!0}async callLoadCodeAssist($){let Z=`${I3.production}${P3.loadCodeAssist}`,Y=UJ(this.configType),Q=a6(this.configType),X=await M$(Z,{method:"POST",headers:{Authorization:`Bearer ${$}`,"Content-Type":"application/json","User-Agent":Q},body:JSON.stringify({metadata:Y})});if(!X.ok){let J=await X.text();throw Error(`loadCodeAssist failed: ${X.status} - ${J}`)}return await X.json()}getDefaultTier($){for(let Z of $.allowedTiers||[])if(Z.isDefault)return{id:Z.id};return{id:"free-tier"}}async callOnboardUser($,Z){let Y=`${I3.production}${P3.onboardUser}`,Q=UJ(this.configType),X=a6(this.configType),J={tierId:Z,metadata:Q};if(Z!=="free-tier"){let K=process.env.GOOGLE_CLOUD_PROJECT||process.env.GOOGLE_CLOUD_PROJECT_ID;if(K)J.cloudaicompanionProject=K,J.metadata={...Q,duetProject:K}}let G=0,q=30;while(G<q){let K=await M$(Y,{method:"POST",headers:{Authorization:`Bearer ${$}`,"Content-Type":"application/json","User-Agent":X},body:JSON.stringify(J)});if(!K.ok){let U=await K.text();throw Error(`onboardUser failed: ${K.status} - ${U}`)}let W=await K.json();if(v0.debug(`[AntigravityChatService] onboardUser attempt ${G+1}:`,JSON.stringify(W)),W.error)throw Error(`onboardUser error: ${W.error.message||W.error.code}`);if(W.done)return{projectId:W.response?.cloudaicompanionProject?.id};v0.debug("[AntigravityChatService] onboardUser not done, waiting 5s..."),await new Promise((U)=>setTimeout(U,5000)),G++}throw Error("onboardUser timeout: LRO did not complete in time")}convertToAntigravityMessages($){let Z=$.find((q)=>q.role==="system"),Y=Z?{parts:[{text:n6(Z.content)}]}:void 0,Q=[],X=$.filter((q)=>q.role!=="system"),J=new Map;for(let q of X)if(q.role==="assistant"&&q.tool_calls){for(let K of q.tool_calls)if(K.type==="function")J.set(K.id,K.function.name)}for(let q of X)if(q.role==="user"){let K=[];if(Array.isArray(q.content)){for(let W of q.content)if(W.type==="text")K.push({text:W.text})}else K.push({text:q.content});Q.push({role:"user",parts:K})}else if(q.role==="assistant"){let K=[],W=n6(q.content);if(W)K.push({text:W});if(q.tool_calls)for(let U of q.tool_calls){if(U.type!=="function")continue;let H={};try{H=JSON.parse(U.function.arguments||"{}")}catch{v0.warn(`Failed to parse tool arguments: ${U.function.arguments}`)}K.push({functionCall:{name:U.function.name,args:H,id:U.id}})}if(K.length>0)Q.push({role:"model",parts:K})}else if(q.role==="tool"){let K=J.get(q.tool_call_id||"");if(K){let W;try{W=JSON.parse(n6(q.content))}catch{W={result:n6(q.content)}}Q.push({role:"user",parts:[{functionResponse:{name:K,id:q.tool_call_id,response:W}}]})}}let G=[];for(let q of Q){let K=G[G.length-1];if(K?.role===q.role)K.parts=[...K.parts,...q.parts];else G.push(q)}if(G.length>0&&G[0].role!=="user")G.unshift({role:"user",parts:[{text:"[Conversation start]"}]});return{systemInstruction:Y,contents:G}}convertToAntigravityTools($){if(!$||$.length===0)return;return[{functionDeclarations:$.map((Y)=>({name:Y.name,description:Y.description,parameters:d9(Y.parameters||{type:"object",properties:{}})}))}]}async makeRequest($,Z,Y){let Q=await this.auth.getAccessToken(),X=`${I3.production}${$}`,J=a6(this.configType),G=await M$(X,{method:"POST",headers:{Authorization:`Bearer ${Q}`,"Content-Type":"application/json","User-Agent":J},body:JSON.stringify(Z),signal:Y});if(!G.ok){let q=await G.text();if(v0.error(`Antigravity API error: ${G.status} - ${q}`),G.status===401)throw Error("Authentication expired. Please run /login again.");if(G.status===403)throw Error("Permission denied. Please check your Google account permissions.");if(G.status===429)throw Error("Rate limit exceeded. Please wait a moment and try again.");throw Error(`Antigravity API error: ${G.status} - ${q}`)}return G}async chat($,Z,Y){let Q=Date.now();v0.debug("\uD83D\uDE80 [AntigravityChatService] Starting chat request"),v0.debug("\uD83D\uDCDD [AntigravityChatService] Messages count:",$.length),await this.ensureProjectId();let X=HJ($);if(X.length<$.length)v0.debug(`Filtered ${$.length-X.length} orphan tool messages`);let{systemInstruction:J,contents:G}=this.convertToAntigravityMessages(X),q=this.convertToAntigravityTools(Z),K=`prompt_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,W={model:this.config.model,project:this.projectId,user_prompt_id:K,request:{contents:G,systemInstruction:J,generationConfig:{...this.config.maxOutputTokens&&{maxOutputTokens:this.config.maxOutputTokens},temperature:this.config.temperature??0.7},tools:q,session_id:this.sessionId}};v0.debug("\uD83D\uDCE4 [AntigravityChatService] Request:",{model:this.config.model,contentsCount:G.length,hasSystemInstruction:!!J,toolsCount:q?.[0]?.functionDeclarations?.length||0});try{let H=await(await this.makeRequest(P3.generateContent,W,Y)).json(),O=Date.now()-Q;v0.debug("\uD83D\uDCE5 [AntigravityChatService] Response received in",O,"ms");let F="",_=[],N=H.response?.candidates?.[0]?.content?.parts||[];for(let A of N)if(A.text)F+=A.text;else if(A.functionCall){let R=A.functionCall;_.push({id:R.id||`call_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,type:"function",function:{name:R.name,arguments:JSON.stringify(R.args||{})}})}let B=H.response?.usageMetadata,L={content:F,toolCalls:_.length>0?_:void 0,usage:{promptTokens:B?.promptTokenCount||0,completionTokens:B?.candidatesTokenCount||0,totalTokens:B?.totalTokenCount||0}};return v0.debug("✅ [AntigravityChatService] Chat completed:",{contentLength:L.content.length,toolCallsCount:L.toolCalls?.length||0,usage:L.usage}),L}catch(U){let H=Date.now()-Q;throw v0.error("❌ [AntigravityChatService] Chat failed after",H,"ms"),v0.error("❌ [AntigravityChatService] Error:",U),U}}async*streamChat($,Z,Y){let Q=Date.now();v0.debug("\uD83D\uDE80 [AntigravityChatService] Starting stream request"),await this.ensureProjectId();let X=HJ($),{systemInstruction:J,contents:G}=this.convertToAntigravityMessages(X),q=this.convertToAntigravityTools(Z),K=`prompt_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,W={model:this.config.model,project:this.projectId,user_prompt_id:K,request:{contents:G,systemInstruction:J,generationConfig:{...this.config.maxOutputTokens&&{maxOutputTokens:this.config.maxOutputTokens},temperature:this.config.temperature??0.7},tools:q,session_id:this.sessionId}};try{let U=await this.auth.getAccessToken(),H=`${I3.production}${P3.streamGenerateContent}?alt=sse`,O=a6(this.configType),F=await M$(H,{method:"POST",headers:{Authorization:`Bearer ${U}`,"Content-Type":"application/json",Accept:"text/event-stream","User-Agent":O},body:JSON.stringify(W),signal:Y});if(!F.ok){let A=await F.text();throw Error(`Antigravity API error: ${F.status} - ${A}`)}let _=F.body?.getReader();if(!_)throw Error("No response body");let z=new TextDecoder,N="",B=0,L=Date.now()-Q;v0.debug("\uD83D\uDCE5 [AntigravityChatService] Stream started in",L,"ms");while(!0){let{done:A,value:R}=await _.read();if(A)break;N+=z.decode(R,{stream:!0});let V=N.split(`
|
|
145
145
|
`);N=V.pop()||"";for(let M of V)if(M.startsWith("data: ")){let T=M.slice(6);if(T==="[DONE]"){yield{finishReason:"stop"};continue}try{let w=JSON.parse(T);if(B++,w.usageMetadata)yield{usage:{promptTokens:w.usageMetadata.promptTokenCount||0,completionTokens:w.usageMetadata.candidatesTokenCount||0,totalTokens:w.usageMetadata.totalTokenCount||0}};let v=w.candidates?.[0],l=v?.content?.parts||[];for(let S of l)if(S.text)yield{content:S.text};else if(S.functionCall){let y=S.functionCall;yield{toolCalls:[{id:y.id||`call_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,type:"function",function:{name:y.name,arguments:JSON.stringify(y.args||{})}}]}}let o=v?.finishReason;if(o)yield{finishReason:o==="STOP"?"stop":o==="MAX_TOKENS"?"length":o.toLowerCase()}}catch(w){v0.debug("Failed to parse SSE data:",T)}}}v0.debug("✅ [AntigravityChatService] Stream completed:",{eventCount:B,duration:Date.now()-Q+"ms"})}catch(U){let H=Date.now()-Q;throw v0.error("❌ [AntigravityChatService] Stream failed after",H,"ms"),v0.error("❌ [AntigravityChatService] Error:",U),U}}getConfig(){return{...this.config}}updateConfig($){v0.debug("\uD83D\uDD04 [AntigravityChatService] Updating configuration"),this.config={...this.config,...$},v0.debug("✅ [AntigravityChatService] Configuration updated")}}var v0;var OJ=b(()=>{Y0();d4();f3();C3();v0=p("Chat")});async function _J($){if($!==FJ)return $;if(o6)return h3.debug("使用缓存的内置 API Key"),o6;try{h3.info("\uD83D\uDD11 正在从代理服务获取内置 API Key...");let Z=await M$(zz,{method:"GET",headers:{Authorization:`Bearer ${FJ}`,"Content-Type":"application/json"},timeout:1e4});if(!Z.ok){let Q=await Z.text();throw Error(`获取 API Key 失败: ${Z.status} - ${Q}`)}let Y=await Z.json();if(!Y.apiKey)throw Error("代理服务返回的数据中没有 apiKey");if(o6=Y.apiKey,h3.info("✅ 成功获取内置 API Key"),Y.message)h3.debug(`提示: ${Y.message}`);return o6}catch(Z){throw h3.error("❌ 获取内置 API Key 失败:",Z),Error(`无法获取内置模型的 API Key: ${Z instanceof Error?Z.message:"未知错误"}
|
|
146
|
-
`+"请检查网络连接或使用自己的 API Key (/config)")}}var h3,zz="https://blade-api-proxy.137844255.workers.dev/v1/get-zhipu-key",FJ="blade-free-tier",o6=null;var zJ=b(()=>{Y0();d4();h3=p("Service")});var c4,x3,s6;var p3=b(()=>{c4={deviceCodeUrl:"https://github.com/login/device/code",tokenUrl:"https://github.com/login/oauth/access_token",clientId:"01ab8ac9400c4e429b23",scope:"user:email",grantType:"urn:ietf:params:oauth:grant-type:device_code"},x3={tokenExchange:"https://api.github.com/copilot_internal/v2/token",chatCompletions:"https://api.githubcopilot.com/chat/completions",models:"https://api.githubcopilot.com/models"},s6={"gpt-5-mini":{id:"gpt-5-mini",name:"GPT-5 Mini",provider:"openai",supportsStreaming:!0,description:"快速高效,适合简单任务"},"grok-code-fast-1":{id:"grok-code-fast-1",name:"Grok Code Fast 1",provider:"xai",supportsStreaming:!0,description:"xAI 快速代码模型"},"claude-haiku-4.5":{id:"claude-haiku-4.5",name:"Claude Haiku 4.5",provider:"anthropic",supportsStreaming:!0,description:"快速智能的 Claude"},"gpt-4.1":{id:"gpt-4.1",name:"GPT-4.1",provider:"openai",supportsStreaming:!0,description:"默认模型,平衡速度与质量"},"gpt-4o":{id:"gpt-4o",name:"GPT-4o",provider:"openai",supportsStreaming:!0,description:"多模态模型,适合日常编码"},"gpt-5":{id:"gpt-5",name:"GPT-5",provider:"openai",supportsStreaming:!0,description:"最新 GPT-5 模型"},"claude-sonnet-4":{id:"claude-sonnet-4",name:"Claude Sonnet 4",provider:"anthropic",supportsStreaming:!0,description:"平衡速度与智能的 Claude"},"claude-sonnet-4.5":{id:"claude-sonnet-4.5",name:"Claude Sonnet 4.5",provider:"anthropic",supportsStreaming:!0,description:"最新 Claude Sonnet"},"claude-opus-4.1":{id:"claude-opus-4.1",name:"Claude Opus 4.1",provider:"anthropic",supportsStreaming:!0,description:"最强 Claude,适合复杂任务"},"gemini-2.5-pro":{id:"gemini-2.5-pro",name:"Gemini 2.5 Pro",provider:"google",supportsStreaming:!0,description:"高级推理和长上下文"},"gemini-3-pro":{id:"gemini-3-pro",name:"Gemini 3 Pro",provider:"google",supportsStreaming:!0,description:"数据分析和多模态"},"gemini-3-flash":{id:"gemini-3-flash",name:"Gemini 3 Flash",provider:"google",supportsStreaming:!0,description:"快速响应模型"}}});import{spawn as Bz}from"child_process";import*as J4 from"fs/promises";import*as g3 from"path";function
|
|
146
|
+
`+"请检查网络连接或使用自己的 API Key (/config)")}}var h3,zz="https://blade-api-proxy.137844255.workers.dev/v1/get-zhipu-key",FJ="blade-free-tier",o6=null;var zJ=b(()=>{Y0();d4();h3=p("Service")});var c4,x3,s6;var p3=b(()=>{c4={deviceCodeUrl:"https://github.com/login/device/code",tokenUrl:"https://github.com/login/oauth/access_token",clientId:"01ab8ac9400c4e429b23",scope:"user:email",grantType:"urn:ietf:params:oauth:grant-type:device_code"},x3={tokenExchange:"https://api.github.com/copilot_internal/v2/token",chatCompletions:"https://api.githubcopilot.com/chat/completions",models:"https://api.githubcopilot.com/models"},s6={"gpt-5-mini":{id:"gpt-5-mini",name:"GPT-5 Mini",provider:"openai",supportsStreaming:!0,description:"快速高效,适合简单任务"},"grok-code-fast-1":{id:"grok-code-fast-1",name:"Grok Code Fast 1",provider:"xai",supportsStreaming:!0,description:"xAI 快速代码模型"},"claude-haiku-4.5":{id:"claude-haiku-4.5",name:"Claude Haiku 4.5",provider:"anthropic",supportsStreaming:!0,description:"快速智能的 Claude"},"gpt-4.1":{id:"gpt-4.1",name:"GPT-4.1",provider:"openai",supportsStreaming:!0,description:"默认模型,平衡速度与质量"},"gpt-4o":{id:"gpt-4o",name:"GPT-4o",provider:"openai",supportsStreaming:!0,description:"多模态模型,适合日常编码"},"gpt-5":{id:"gpt-5",name:"GPT-5",provider:"openai",supportsStreaming:!0,description:"最新 GPT-5 模型"},"claude-sonnet-4":{id:"claude-sonnet-4",name:"Claude Sonnet 4",provider:"anthropic",supportsStreaming:!0,description:"平衡速度与智能的 Claude"},"claude-sonnet-4.5":{id:"claude-sonnet-4.5",name:"Claude Sonnet 4.5",provider:"anthropic",supportsStreaming:!0,description:"最新 Claude Sonnet"},"claude-opus-4.1":{id:"claude-opus-4.1",name:"Claude Opus 4.1",provider:"anthropic",supportsStreaming:!0,description:"最强 Claude,适合复杂任务"},"gemini-2.5-pro":{id:"gemini-2.5-pro",name:"Gemini 2.5 Pro",provider:"google",supportsStreaming:!0,description:"高级推理和长上下文"},"gemini-3-pro":{id:"gemini-3-pro",name:"Gemini 3 Pro",provider:"google",supportsStreaming:!0,description:"数据分析和多模态"},"gemini-3-flash":{id:"gemini-3-flash",name:"Gemini 3 Flash",provider:"google",supportsStreaming:!0,description:"快速响应模型"}}});import{spawn as Bz}from"child_process";import*as J4 from"fs/promises";import*as g3 from"path";function i9(){let $=process.env.HOME||process.env.USERPROFILE||"";return g3.join($,".blade")}class t${static instance=null;cachedToken=null;constructor(){}static getInstance(){if(!t$.instance)t$.instance=new t$;return t$.instance}async isLoggedIn(){let $=await this.loadToken();if(!$)return!1;let Z=300000;if($.copilotExpiresAt&&Date.now()>$.copilotExpiresAt-Z)try{return await this.refreshCopilotToken(),!0}catch{return!1}return!0}async login(){m3.info("\uD83D\uDD10 Starting GitHub Copilot OAuth login..."),console.log(`
|
|
147
147
|
\uD83D\uDD10 开始 GitHub Copilot 认证...`);let $=await this.requestDeviceCode();console.log(`
|
|
148
148
|
\uD83D\uDCCB 请在浏览器中完成授权:`),console.log(` 1. 打开 ${$.verification_uri}`),console.log(` 2. 输入代码: ${$.user_code}`),console.log("");try{await this.openBrowser($.verification_uri),console.log("\uD83C\uDF10 已自动打开浏览器,请输入上面的代码完成授权")}catch{console.log("⚠️ 无法自动打开浏览器,请手动打开上述链接")}console.log(`
|
|
149
|
-
⏳ 等待授权中...`);let Z=await this.pollForAccessToken($.device_code,$.interval,$.expires_in);console.log("✅ GitHub 授权成功!"),console.log("\uD83D\uDD04 正在获取 Copilot token...");let Y=await this.exchangeForCopilotToken(Z),Q={githubToken:Z,copilotToken:Y.token,copilotExpiresAt:Y.expires_at*1000};await this.saveToken(Q),this.cachedToken=Q,console.log("✅ GitHub Copilot 登录成功!"),m3.info("GitHub Copilot OAuth login completed")}async logout(){let $=g3.join(
|
|
149
|
+
⏳ 等待授权中...`);let Z=await this.pollForAccessToken($.device_code,$.interval,$.expires_in);console.log("✅ GitHub 授权成功!"),console.log("\uD83D\uDD04 正在获取 Copilot token...");let Y=await this.exchangeForCopilotToken(Z),Q={githubToken:Z,copilotToken:Y.token,copilotExpiresAt:Y.expires_at*1000};await this.saveToken(Q),this.cachedToken=Q,console.log("✅ GitHub Copilot 登录成功!"),m3.info("GitHub Copilot OAuth login completed")}async logout(){let $=g3.join(i9(),l9);try{await J4.unlink($),this.cachedToken=null,console.log("✅ 已登出 GitHub Copilot"),m3.info("GitHub Copilot logout completed")}catch(Z){if(Z.code!=="ENOENT")throw Z;this.cachedToken=null}}async getCopilotToken(){if(this.cachedToken){if(this.cachedToken.copilotExpiresAt>Date.now()+300000)return this.cachedToken.copilotToken}let $=await this.loadToken();if(!$)throw Error("Not logged in to GitHub Copilot. Please run /login copilot first.");let Z=300000;if($.copilotExpiresAt<=Date.now()+Z)return await this.refreshCopilotToken(),this.cachedToken.copilotToken;return this.cachedToken=$,$.copilotToken}async refreshCopilotToken(){let $=await this.loadToken();if(!$||!$.githubToken)throw Error("No GitHub token available");m3.info("\uD83D\uDD04 Refreshing Copilot token...");let Z=await this.exchangeForCopilotToken($.githubToken),Y={githubToken:$.githubToken,copilotToken:Z.token,copilotExpiresAt:Z.expires_at*1000};await this.saveToken(Y),this.cachedToken=Y,m3.info("✅ Copilot token refreshed successfully")}async requestDeviceCode(){let $=new URLSearchParams({client_id:c4.clientId,scope:c4.scope}),Z=await M$(c4.deviceCodeUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:$.toString()});if(!Z.ok){let Y=await Z.text();throw Error(`Failed to request device code: ${Z.status} - ${Y}`)}return await Z.json()}async pollForAccessToken($,Z,Y){let Q=Date.now(),X=Y*1000;while(Date.now()-Q<X){await this.sleep(Z*1000);let J=new URLSearchParams({client_id:c4.clientId,device_code:$,grant_type:c4.grantType}),q=await(await M$(c4.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:J.toString()})).json();if(q.access_token)return q.access_token;if(q.error==="authorization_pending")continue;if(q.error==="slow_down"){Z+=5;continue}if(q.error==="expired_token")throw Error("Device code expired. Please try again.");if(q.error==="access_denied")throw Error("Authorization denied by user.");if(q.error)throw Error(`OAuth error: ${q.error} - ${q.error_description||""}`)}throw Error("Device code expired. Please try again.")}async exchangeForCopilotToken($){let Z=await M$(x3.tokenExchange,{method:"GET",headers:{Authorization:`token ${$}`,Accept:"application/json","User-Agent":"GitHubCopilotChat/0.22.2024","Editor-Version":"vscode/1.95.0","Editor-Plugin-Version":"copilot-chat/0.22.2024"}});if(!Z.ok){let Y=await Z.text();if(Z.status===401)throw Error("GitHub token is invalid or expired. Please run /login copilot again.");if(Z.status===403)throw Error("No Copilot subscription found. Please ensure you have an active GitHub Copilot subscription.");throw Error(`Failed to exchange for Copilot token: ${Z.status} - ${Y}`)}return await Z.json()}async openBrowser($){let Z,Y;if(process.platform==="darwin")Z="open",Y=[$];else if(process.platform==="win32")Z="cmd",Y=["/c","start","",$];else Z="xdg-open",Y=[$];await new Promise((Q,X)=>{let J=Bz(Z,Y,{stdio:"ignore"});J.once("error",X),J.once("close",(G)=>{if(G===0||G===null)Q();else X(Error(`Failed to open browser (exit code ${G})`))})})}async saveToken($){let Z=i9();await J4.mkdir(Z,{recursive:!0,mode:493});let Y=g3.join(Z,l9);await J4.writeFile(Y,JSON.stringify($,null,2),{mode:384})}async loadToken(){let $=g3.join(i9(),l9);try{let Z=await J4.readFile($,"utf-8");return JSON.parse(Z)}catch(Z){if(Z.code==="ENOENT")return null;throw Z}}async getStatus(){let $=await this.loadToken();if(!$)return{loggedIn:!1};return{loggedIn:!0,expiresAt:$.copilotExpiresAt?new Date($.copilotExpiresAt):void 0}}sleep($){return new Promise((Z)=>setTimeout(Z,$))}}var m3,l9="copilot-token.json";var u3=b(()=>{Y0();d4();p3();m3=p("Service")});import{isPlainObject as t6}from"lodash-es";class r9{config;auth;constructor($){this.config=$,this.auth=t$.getInstance()}getConfig(){return this.config}updateConfig($){this.config={...this.config,...$}}async chat($,Z,Y){let Q=Date.now();T1.debug("\uD83D\uDE80 [CopilotChatService] Starting chat request"),T1.debug(`\uD83D\uDCDD [CopilotChatService] Messages count: ${$.length}`);try{let X=await this.auth.getCopilotToken(),J=this.buildRequest($,Z,!1),G=await this.makeRequest(X,J,Y),q=Date.now()-Q;return T1.debug(`✅ [CopilotChatService] Chat completed in ${q} ms`),this.parseResponse(G)}catch(X){let J=Date.now()-Q;throw T1.error(`❌ [CopilotChatService] Chat failed after ${J} ms`),T1.error(`❌ [CopilotChatService] Error: ${X}`),X}}async*streamChat($,Z,Y){let Q=Date.now();T1.debug("\uD83D\uDE80 [CopilotChatService] Starting stream chat request"),T1.debug(`\uD83D\uDCDD [CopilotChatService] Messages count: ${$.length}`);try{let X=await this.auth.getCopilotToken(),J=this.buildRequest($,Z,!0),G=await M$(x3.chatCompletions,{method:"POST",headers:{Authorization:`Bearer ${X}`,"Content-Type":"application/json",Accept:"text/event-stream","Copilot-Integration-Id":"vscode-chat","Editor-Version":"vscode/1.95.0","Editor-Plugin-Version":"copilot-chat/0.22.2024","User-Agent":"GitHubCopilotChat/0.22.2024"},body:JSON.stringify(J),signal:Y});if(!G.ok){let O=await G.text();throw Error(`Copilot API error: ${G.status} - ${O}`)}if(!G.body)throw Error("No response body");let q=G.body.getReader(),K=new TextDecoder,W="",U=new Map;while(!0){let{done:O,value:F}=await q.read();if(O)break;W+=K.decode(F,{stream:!0});let _=W.split(`
|
|
150
150
|
`);W=_.pop()||"";for(let z of _){if(!z.startsWith("data: "))continue;let N=z.slice(6).trim();if(N==="[DONE]"){if(U.size>0)yield{toolCalls:Array.from(U.values()),finishReason:"tool_calls"};continue}try{let L=JSON.parse(N).choices[0];if(L){let A={};if(L.delta.content)A.content=L.delta.content;if(L.delta.tool_calls)for(let R of L.delta.tool_calls){let V=U.get(R.index);if(V){if(R.function?.arguments)V.function.arguments+=R.function.arguments}else U.set(R.index,{id:R.id||"",type:"function",function:{name:R.function?.name||"",arguments:R.function?.arguments||""}})}if(L.finish_reason)A.finishReason=L.finish_reason;if(A.content||A.finishReason==="stop")yield A}}catch{}}}let H=Date.now()-Q;T1.debug(`✅ [CopilotChatService] Stream completed in ${H} ms`)}catch(X){let J=Date.now()-Q;throw T1.error(`❌ [CopilotChatService] Stream failed after ${J} ms`),T1.error(`❌ [CopilotChatService] Error: ${X}`),X}}sanitizeMessages($){let Z=[],Y=new Set;for(let Q=0;Q<$.length;Q++){let X=$[Q];if(X.role==="assistant"&&X.tool_calls&&X.tool_calls.length>0){let J=[];for(let G of X.tool_calls){let q=!1;for(let K=Q+1;K<$.length;K++){if($[K].role==="tool"&&$[K].tool_call_id===G.id){q=!0;break}if($[K].role==="assistant"||$[K].role==="user")break}if(q)J.push(G.id),Y.add(G.id)}if(J.length>0)Z.push({...X,tool_calls:X.tool_calls.filter((G)=>J.includes(G.id))});else Z.push({role:X.role,content:X.content||"",reasoningContent:X.reasoningContent})}else if(X.role==="tool"){if(X.tool_call_id&&Y.has(X.tool_call_id))Z.push(X)}else Z.push(X)}if(Z.length!==$.length)T1.debug(`[CopilotChatService] Sanitized messages: ${$.length} -> ${Z.length}`);return Z}buildRequest($,Z,Y=!1){let X=this.sanitizeMessages($).map((G)=>{let q;if(typeof G.content==="string")q=G.content;else if(Array.isArray(G.content))q=G.content.filter((W)=>W.type==="text").map((W)=>W.text).join(`
|
|
151
|
-
`);else q=null;let K={role:G.role,content:q};if(G.tool_call_id)K.tool_call_id=G.tool_call_id;if(G.name)K.name=G.name;if(G.tool_calls&&G.tool_calls.length>0)K.tool_calls=G.tool_calls.filter((W)=>W.type==="function"&&("function"in W)).map((W)=>({id:W.id,type:"function",function:{name:W.function.name,arguments:W.function.arguments}}));return K}),J={model:this.config.model,messages:X,stream:Y};if(this.config.temperature!==void 0)J.temperature=this.config.temperature;if(this.config.maxOutputTokens)J.max_tokens=this.config.maxOutputTokens;if(Z&&Z.length>0)J.tools=Z.map((G)=>({type:"function",function:{name:G.name,description:G.description,parameters:this.cleanParameters(G.parameters)}})),J.tool_choice="auto";return J}cleanParameters($){if(!t6($))return{};let Z={};for(let[Y,Q]of Object.entries($)){if(["$ref","const","default"].includes(Y))continue;if(Y==="properties"&&t6(Q)){let X={};for(let[J,G]of Object.entries(Q))X[J]=t6(G)?this.cleanParameters(G):G;Z[Y]=X}else if(Y==="items"&&t6(Q))Z[Y]=this.cleanParameters(Q);else Z[Y]=Q}return Z}async makeRequest($,Z,Y){let Q=await M$(x3.chatCompletions,{method:"POST",headers:{Authorization:`Bearer ${$}`,"Content-Type":"application/json",Accept:"application/json","Copilot-Integration-Id":"vscode-chat","Editor-Version":"vscode/1.95.0","Editor-Plugin-Version":"copilot-chat/0.22.2024","User-Agent":"GitHubCopilotChat/0.22.2024"},body:JSON.stringify(Z),signal:Y});if(!Q.ok){let X=await Q.text();if(T1.error(`Copilot API error: ${Q.status} - ${X}`),Q.status===401)throw Error("Copilot token expired or invalid. Please run /login copilot again.");if(Q.status===403)throw Error("Permission denied. Please ensure you have an active GitHub Copilot subscription.");if(Q.status===429)throw Error("Rate limit exceeded. Please wait and try again.");throw Error(`Copilot API error: ${Q.status} - ${X}`)}return await Q.json()}parseResponse($){let Z=$.choices[0];if(!Z)throw Error("No response from Copilot API");let Y={content:Z.message.content||""};if(Z.message.tool_calls&&Z.message.tool_calls.length>0)Y.toolCalls=Z.message.tool_calls.map((Q)=>({id:Q.id,type:"function",function:{name:Q.function.name,arguments:Q.function.arguments}}));if($.usage)Y.usage={promptTokens:$.usage.prompt_tokens,completionTokens:$.usage.completion_tokens,totalTokens:$.usage.total_tokens};return Y}}var T1;var BJ=b(()=>{Y0();d4();u3();p3();T1=p("Chat")});import{createAnthropic as Nz}from"@ai-sdk/anthropic";import{createAzure as Lz}from"@ai-sdk/azure";import{createDeepSeek as wz}from"@ai-sdk/deepseek";import{createGoogleGenerativeAI as Az}from"@ai-sdk/google";import{createOpenAI as bz}from"@ai-sdk/openai";import{createOpenAICompatible as
|
|
152
|
-
`)}function Mz($,Z={}){try{return JSON.parse($)}catch{return o1.warn("⚠️ [VercelAIChatService] Failed to parse JSON, using fallback",{str:$}),Z}}class
|
|
151
|
+
`);else q=null;let K={role:G.role,content:q};if(G.tool_call_id)K.tool_call_id=G.tool_call_id;if(G.name)K.name=G.name;if(G.tool_calls&&G.tool_calls.length>0)K.tool_calls=G.tool_calls.filter((W)=>W.type==="function"&&("function"in W)).map((W)=>({id:W.id,type:"function",function:{name:W.function.name,arguments:W.function.arguments}}));return K}),J={model:this.config.model,messages:X,stream:Y};if(this.config.temperature!==void 0)J.temperature=this.config.temperature;if(this.config.maxOutputTokens)J.max_tokens=this.config.maxOutputTokens;if(Z&&Z.length>0)J.tools=Z.map((G)=>({type:"function",function:{name:G.name,description:G.description,parameters:this.cleanParameters(G.parameters)}})),J.tool_choice="auto";return J}cleanParameters($){if(!t6($))return{};let Z={};for(let[Y,Q]of Object.entries($)){if(["$ref","const","default"].includes(Y))continue;if(Y==="properties"&&t6(Q)){let X={};for(let[J,G]of Object.entries(Q))X[J]=t6(G)?this.cleanParameters(G):G;Z[Y]=X}else if(Y==="items"&&t6(Q))Z[Y]=this.cleanParameters(Q);else Z[Y]=Q}return Z}async makeRequest($,Z,Y){let Q=await M$(x3.chatCompletions,{method:"POST",headers:{Authorization:`Bearer ${$}`,"Content-Type":"application/json",Accept:"application/json","Copilot-Integration-Id":"vscode-chat","Editor-Version":"vscode/1.95.0","Editor-Plugin-Version":"copilot-chat/0.22.2024","User-Agent":"GitHubCopilotChat/0.22.2024"},body:JSON.stringify(Z),signal:Y});if(!Q.ok){let X=await Q.text();if(T1.error(`Copilot API error: ${Q.status} - ${X}`),Q.status===401)throw Error("Copilot token expired or invalid. Please run /login copilot again.");if(Q.status===403)throw Error("Permission denied. Please ensure you have an active GitHub Copilot subscription.");if(Q.status===429)throw Error("Rate limit exceeded. Please wait and try again.");throw Error(`Copilot API error: ${Q.status} - ${X}`)}return await Q.json()}parseResponse($){let Z=$.choices[0];if(!Z)throw Error("No response from Copilot API");let Y={content:Z.message.content||""};if(Z.message.tool_calls&&Z.message.tool_calls.length>0)Y.toolCalls=Z.message.tool_calls.map((Q)=>({id:Q.id,type:"function",function:{name:Q.function.name,arguments:Q.function.arguments}}));if($.usage)Y.usage={promptTokens:$.usage.prompt_tokens,completionTokens:$.usage.completion_tokens,totalTokens:$.usage.total_tokens};return Y}}var T1;var BJ=b(()=>{Y0();d4();u3();p3();T1=p("Chat")});import{createAnthropic as Nz}from"@ai-sdk/anthropic";import{createAzure as Lz}from"@ai-sdk/azure";import{createDeepSeek as wz}from"@ai-sdk/deepseek";import{createGoogleGenerativeAI as Az}from"@ai-sdk/google";import{createOpenAI as bz}from"@ai-sdk/openai";import{createOpenAICompatible as a9}from"@ai-sdk/openai-compatible";import{generateText as Vz,jsonSchema as Rz,streamText as Dz}from"ai";function NJ($){let Z=new Set;for(let Y of $)if(Y.role==="assistant"&&Y.tool_calls)for(let Q of Y.tool_calls)Z.add(Q.id);return $.filter((Y)=>{if(Y.role==="tool"){if(!Y.tool_call_id)return!1;return Z.has(Y.tool_call_id)}return!0})}function e6($){if(typeof $==="string")return $;return $.filter((Z)=>Z.type==="text").map((Z)=>Z.text).join(`
|
|
152
|
+
`)}function Mz($,Z={}){try{return JSON.parse($)}catch{return o1.warn("⚠️ [VercelAIChatService] Failed to parse JSON, using fallback",{str:$}),Z}}class n9{model;config;constructor($){this.config=$,this.model=this.createModel($),o1.debug("\uD83D\uDE80 [VercelAIChatService] Initialized",{provider:$.provider,model:$.model,providerId:$.providerId})}createModel($){let{provider:Z,apiKey:Y,baseUrl:Q,model:X,customHeaders:J,providerId:G,apiVersion:q}=$;switch(Z){case"openai":return bz({apiKey:Y,baseURL:Q||void 0,headers:J})(X);case"anthropic":return Nz({apiKey:Y,baseURL:Q||void 0,headers:J})(X);case"gemini":{if(Q&&!this.isGeminiOfficialUrl(Q))return a9({name:"gemini",apiKey:Y,baseURL:Q,headers:J})(X);return Az({apiKey:Y,baseURL:Q||void 0})(X)}case"azure-openai":{let K=this.extractAzureResourceName(Q);if(K)return Lz({apiKey:Y,resourceName:K,apiVersion:q||"2024-08-01-preview"})(X);let W=this.buildAzureBaseUrl(Q,X);return a9({name:"azure-openai",apiKey:Y,baseURL:W,headers:{...J,"api-key":Y},queryParams:{"api-version":q||"2024-08-01-preview"}})(X)}default:{if(G==="deepseek")return wz({apiKey:Y,baseURL:Q||void 0,headers:J})(X);return a9({name:G||"custom",apiKey:Y,baseURL:Q,headers:J})(X)}}}extractAzureResourceName($){if(!$)return;let Z=$.match(/https:\/\/([^.]+)\.openai\.azure(?:\.com|\.us|\.cn|\.de)/);return Z?Z[1]:void 0}buildAzureBaseUrl($,Z){if(!$)return"";let Y=$.replace(/\/$/,"").replace(/\?.*$/,"");if(Y.includes("/openai/deployments/"))return Y;return`${Y}/openai/deployments/${Z}`}isGeminiOfficialUrl($){return $.includes("generativelanguage.googleapis.com")||$.includes("aiplatform.googleapis.com")}convertMessages($){let Z=[];for(let Y of $)if(Y.role==="system")if(Array.isArray(Y.content)){let Q=Y.content.find((J)=>J.type==="text"),X={role:"system",content:e6(Y.content)};if(Q?.providerOptions)X.providerOptions=Q.providerOptions;Z.push(X)}else Z.push({role:"system",content:Y.content});else if(Y.role==="user")if(Array.isArray(Y.content)){let Q=Y.content.map((X)=>{if(X.type==="text"){let J={type:"text",text:X.text};if(X.providerOptions)J.providerOptions=X.providerOptions;return J}return{type:"image",image:X.image_url.url}});Z.push({role:"user",content:Q})}else Z.push({role:"user",content:Y.content});else if(Y.role==="assistant")if(Y.tool_calls&&Y.tool_calls.length>0){let Q=Y.tool_calls.map((J)=>{let G=J.function;return{type:"tool-call",toolCallId:J.id,toolName:G?.name||"",input:Mz(G?.arguments||"{}",{})}}),X=e6(Y.content);if(X)Z.push({role:"assistant",content:[{type:"text",text:X},...Q]});else Z.push({role:"assistant",content:Q})}else Z.push({role:"assistant",content:e6(Y.content)});else if(Y.role==="tool")Z.push({role:"tool",content:[{type:"tool-result",toolCallId:Y.tool_call_id,toolName:Y.name||"unknown",output:{type:"text",value:e6(Y.content)}}]});return Z}convertTools($){if(!$||$.length===0)return;let Z={};for(let Y of $)Z[Y.name]={description:Y.description,inputSchema:Rz(Y.parameters)};return Z}convertToolCalls($){return $.map((Z)=>({id:Z.toolCallId,type:"function",function:{name:Z.toolName,arguments:JSON.stringify(Z.args??Z.input??{})}}))}convertUsage($,Z){if(!$)return;let Y=$.promptTokens??0,Q=$.completionTokens??0,X={promptTokens:Y,completionTokens:Q,totalTokens:$.totalTokens??Y+Q};if(Z?.anthropic){if(Z.anthropic.cacheCreationInputTokens!==void 0)X.cacheCreationInputTokens=Z.anthropic.cacheCreationInputTokens;if(Z.anthropic.cacheReadInputTokens!==void 0)X.cacheReadInputTokens=Z.anthropic.cacheReadInputTokens}return X}async chat($,Z,Y){let Q=Date.now();o1.debug("\uD83D\uDE80 [VercelAIChatService] Starting chat request");let X=NJ($),J=this.convertMessages(X),G=this.convertTools(Z);try{let q=await Vz({model:this.model,messages:J,tools:G,maxOutputTokens:this.config.maxOutputTokens,temperature:this.config.temperature??0,abortSignal:Y}),K=Date.now()-Q;o1.debug("\uD83D\uDCE5 [VercelAIChatService] Response received in",K,"ms");let W=q.toolCalls&&q.toolCalls.length>0?this.convertToolCalls(q.toolCalls):void 0,U=Array.isArray(q.reasoning)?q.reasoning.map((H)=>H.text).join(""):void 0;return{content:q.text,reasoningContent:U,toolCalls:W,usage:this.convertUsage(q.usage,q.providerMetadata)}}catch(q){let K=Date.now()-Q;throw o1.error("❌ [VercelAIChatService] Chat failed after",K,"ms"),q}}async*streamChat($,Z,Y){let Q=Date.now();o1.debug("\uD83D\uDE80 [VercelAIChatService] Starting stream request");let X=NJ($),J=this.convertMessages(X),G=this.convertTools(Z);try{let q=Dz({model:this.model,messages:J,tools:G,maxOutputTokens:this.config.maxOutputTokens,temperature:this.config.temperature??0,abortSignal:Y});o1.debug("\uD83D\uDCE5 [VercelAIChatService] Stream started");let K=0;for await(let U of q.fullStream)switch(U.type){case"text-delta":yield{content:U.text??U.textDelta};break;case"reasoning-delta":yield{reasoningContent:U.textDelta};break;case"tool-call":yield{toolCalls:[{index:K++,id:U.toolCallId,type:"function",function:{name:U.toolName,arguments:JSON.stringify(U.args??U.input??{})}}]};break;case"finish":yield{finishReason:U.finishReason,usage:this.convertUsage(U.totalUsage,U.providerMetadata)};break}let W=Date.now()-Q;o1.debug("✅ [VercelAIChatService] Stream completed in",W,"ms")}catch(q){let K=Date.now()-Q;throw o1.error("❌ [VercelAIChatService] Stream failed after",K,"ms"),q}}getConfig(){return{...this.config}}updateConfig($){o1.debug("\uD83D\uDD04 [VercelAIChatService] Updating configuration"),this.config={...this.config,...$},this.model=this.createModel(this.config),o1.debug("✅ [VercelAIChatService] Configuration updated")}}var o1;var LJ=b(()=>{Y0();o1=p("Chat")});async function k8($){let Z=$;if(f9($.apiKey)){wJ.info("\uD83D\uDD11 检测到内置 API Key,正在获取...");let Y=await _J($.apiKey);Z={...$,apiKey:Y}}if(Z.providerId){let Y=JJ(Z.providerId);if(Object.keys(Y).length>0)Z={...Z,customHeaders:{...Y,...Z.customHeaders}},wJ.debug(`\uD83D\uDD27 注入 ${Z.providerId} 特定 headers:`,Object.keys(Y))}return jz(Z)}function jz($){switch($.provider){case"antigravity":return new c9($);case"copilot":return new r9($);default:return new n9($)}}var wJ;var $7=b(()=>{x9();Y0();C8();OJ();zJ();BJ();LJ();wJ=p("Service")});import{readFile as Tz}from"node:fs/promises";import{basename as yz}from"node:path";class Z7{static MAX_FILES=5;static MAX_LINES_PER_FILE=1000;static analyzeFiles($){let Z=new Map;return $.forEach((Q,X)=>{let J=typeof Q.content==="string"?Q.content:(Q.content||[]).filter((q)=>q.type==="text").map((q)=>q.text).join(`
|
|
153
153
|
`);if(this.extractFilePathsFromContent(J).forEach((q)=>{this.updateFileReference(Z,q,X,!1)}),Q.tool_calls&&Array.isArray(Q.tool_calls))Q.tool_calls.forEach((q)=>{let K=this.extractFilePathsFromToolCall(q),W=q.type==="function"&&"function"in q?q.function?.name:"",U=["Write","Edit"].includes(W||"");K.forEach((H)=>{this.updateFileReference(Z,H,X,U)})})}),Array.from(Z.values()).sort((Q,X)=>{if(Q.wasModified!==X.wasModified)return Q.wasModified?-1:1;if(Q.mentions!==X.mentions)return X.mentions-Q.mentions;return X.lastMentioned-Q.lastMentioned}).slice(0,this.MAX_FILES)}static async readFilesContent($){let Z=[];for(let Y of $)try{let Q=await Tz(Y,"utf-8"),X=Q.split(`
|
|
154
154
|
`),J=X.length,G=Q,q=!1,K=J;if(J>this.MAX_LINES_PER_FILE)G=X.slice(0,this.MAX_LINES_PER_FILE).join(`
|
|
155
155
|
`),G+=`
|
|
@@ -234,9 +234,9 @@ An error occurred during compaction. Retained the latest ${X} messages (~30%).
|
|
|
234
234
|
Error: ${U}
|
|
235
235
|
|
|
236
236
|
The conversation can continue, but consider retrying compaction later with /compact.`),F=[O,...q],_=C2.countTokens(F,Z.modelName);return{success:!1,summary:typeof O.content==="string"?O.content:O.content.filter((z)=>z.type==="text").map((z)=>z.text).join(`
|
|
237
|
-
`),preTokens:Y,postTokens:_,filesIncluded:[],compactedMessages:F,boundaryMessage:W,summaryMessage:O,error:U}}}var
|
|
237
|
+
`),preTokens:Y,postTokens:_,filesIncluded:[],compactedMessages:F,boundaryMessage:W,summaryMessage:O,error:U}}}var o9=b(()=>{H$();K1();$7();AJ();Y7()});import{appendFileSync as Ez,mkdirSync as Iz,writeFileSync as Pz}from"node:fs";import vz from"node:os";import RJ from"node:path";function Cz(){if(VJ)return;let $=RJ.dirname(s9);Iz($,{recursive:!0,mode:493}),Pz(s9,`=== Stream Debug Log Started: ${new Date().toISOString()} ===
|
|
238
238
|
`),VJ=!0}function y1($,Z,Y){Cz();let Q=new Date().toISOString(),X=Y?` | ${JSON.stringify(Y)}`:"",J=`[${Q}] [${$}] ${Z}${X}
|
|
239
|
-
`;Ez(
|
|
239
|
+
`;Ez(s9,J)}var s9,VJ=!1;var t9=b(()=>{s9=RJ.join(vz.homedir(),".blade","logs","stream-debug.log")});import kz from"fs/promises";import Sz from"path";async function Q7($){for(let Z of $)try{let Y;if(Z.trim().startsWith("{")){let J=JSON.parse(Z);if(J.name&&J.type){let{name:G,...q}=J;Y={[G]:q}}else Y=J}else{let J=Sz.resolve(process.cwd(),Z),G=await kz.readFile(J,"utf-8"),q=JSON.parse(G);Y=q.mcpServers||q}let X={...q1(),...Y};X0().config.actions.updateConfig({mcpServers:X}),DJ.debug(`✅ Loaded MCP config from CLI: ${Object.keys(Y).join(", ")}`)}catch(Y){DJ.warn(`⚠️ Failed to load MCP config "${Z}":`,Y)}}var DJ;var e9=b(()=>{Y0();b0();DJ=p("General")});function MJ($){return $!==void 0&&typeof $.pattern==="string"&&typeof $.search_path==="string"}function jJ($){return $!==void 0&&$.kind==="edit"&&typeof $.matches_found==="number"}function d3($){return $==="readonly"}var j$=()=>{};class $Z{toolName;params;context;aborted=!1;result;_internal={};constructor($,Z,Y){this.toolName=$;this.params=Z;this.context=Y}shouldAbort(){return this.aborted||(this.context.signal?.aborted??!1)}abort($,Z){this.aborted=!0,this.result={success:!1,llmContent:`Tool execution aborted: ${$||"Unknown reason"}`,displayContent:`执行已中止: ${$||"未知原因"}`,error:{type:"execution_error",message:$||"Execution aborted"},metadata:Z?.shouldExitLoop?{shouldExitLoop:!0}:void 0}}setResult($){this.result=$}getResult(){if(!this.result)throw Error("Tool execution result not set");return this.result}}var ZZ=b(()=>{j$()});var R$=b(()=>{ZZ();j$()});import{isPlainObject as fz}from"lodash-es";function c3($){if($===void 0)return"undefined";if(typeof $==="string")return $;try{let Z=JSON.stringify($);return Z===void 0?String($):Z}catch{return String($)}}function hz($){let{code:Z}=$,Y=$,Q=Y.received;switch(Z){case"invalid_type":{let X=Y.expected;return`类型错误:期望 ${c3(X)},实际收到 ${c3(Q)}`}case"too_small":{let{minimum:X,inclusive:J}=Y,G=typeof Y.type==="string"?Y.type:void 0;if(G==="string"&&typeof X==="number")return`长度不能少于 ${X} 个字符`;if(G==="number"&&typeof X==="number")return`不能小于${J?"等于":""} ${X}`;if(G==="array"&&typeof X==="number")return`数组长度不能少于 ${X}`;return"值太小"}case"too_big":{let{maximum:X,inclusive:J}=Y,G=typeof Y.type==="string"?Y.type:void 0;if(G==="string"&&typeof X==="number")return`长度不能超过 ${X} 个字符`;if(G==="number"&&typeof X==="number")return`不能大于${J?"等于":""} ${X}`;if(G==="array"&&typeof X==="number")return`数组长度不能超过 ${X}`;return"值太大"}case"invalid_string":{let X=Y.validation;if(X==="email")return"必须是有效的电子邮件地址";if(X==="url")return"必须是有效的 URL";if(X==="uuid")return"必须是有效的 UUID";if(fz(X)){let J=X;if(typeof J.includes==="string")return`必须包含 "${J.includes}"`;if(typeof J.startsWith==="string")return`必须以 "${J.startsWith}" 开头`;if(typeof J.endsWith==="string")return`必须以 "${J.endsWith}" 结尾`}return"字符串格式不正确"}case"invalid_enum_value":{let X=Y.options;if(Array.isArray(X))return`必须是以下值之一:${X.map((J)=>c3(J)).join(", ")}`;return"必须是枚举允许的值之一"}case"invalid_literal":{let X=Y.expected;return`必须是字面量值:${c3(X)}`}case"unrecognized_keys":{let X=Y.keys;if(Array.isArray(X))return`包含未知的参数:${X.map((J)=>c3(J)).join(", ")}`;return"包含未知的参数"}case"invalid_union":return"不符合任何有效的类型定义";case"invalid_date":return"必须是有效的日期";case"custom":return $.message||"自定义验证失败";default:return $.message||"验证失败"}}function xz($){let Z=$.issues.map((Q)=>{let X=Q.path.join("."),J=hz(Q),G=Q.received;return{field:X||"root",message:J,value:G}}),Y=Z.length===1?`参数验证失败 [${Z[0].field}]: ${Z[0].message}`:`参数验证失败 (${Z.length} 个错误):
|
|
240
240
|
${Z.map((Q)=>` - ${Q.field}: ${Q.message}`).join(`
|
|
241
241
|
`)}`;return new TJ(Y,Z)}function yJ($,Z){let Y=$.safeParse(Z);if(!Y.success)throw xz(Y.error);return Y.data}var TJ;var EJ=b(()=>{R$();TJ=class TJ extends Error{issues;type;constructor($,Z,Y="validation_error"){super($);this.issues=Z;this.type=Y;this.name="ToolValidationError"}}});import{zodToJsonSchema as pz}from"zod-to-json-schema";function YZ($){return pz($,{target:"jsonSchema7",$refStrategy:"none"})}var IJ=()=>{};class QZ{toolName;params;executeFn;descriptionFn;affectedPathsFn;constructor($,Z,Y,Q,X){this.toolName=$;this.params=Z;this.executeFn=Y;this.descriptionFn=Q;this.affectedPathsFn=X}getDescription(){if(this.descriptionFn)return this.descriptionFn(this.params);return`执行工具: ${this.toolName}`}getAffectedPaths(){if(this.affectedPathsFn)return this.affectedPathsFn(this.params);return[]}async execute($,Z,Y){let Q={signal:$,updateOutput:Z,...Y};return this.executeFn(this.params,Q)}}function s($){return{name:$.name,displayName:$.displayName,kind:$.kind,isReadOnly:$.isReadOnly??d3($.kind),isConcurrencySafe:$.isConcurrencySafe??!0,strict:$.strict??!1,description:$.description,version:$.version||"1.0.0",category:$.category,tags:$.tags||[],getFunctionDeclaration(){let Z=YZ($.schema),Y=$.description.short;if($.description.long)Y+=`
|
|
242
242
|
|
|
@@ -965,7 +965,7 @@ ${Z}
|
|
|
965
965
|
<!-- What needs to be clarified before proceeding? -->
|
|
966
966
|
|
|
967
967
|
1.
|
|
968
|
-
`}calculateTaskProgress($){let Z=$.length,Y=$.filter((Q)=>Q.status==="completed").length;return{total:Z,completed:Y}}}var A7;var I1=b(()=>{H$();Y0();b0();N5();l1();A7=p("Spec")});import*as $2 from"fs/promises";class G4{async readTextFile($){return $2.readFile($,"utf-8")}async writeTextFile($,Z){await $2.writeFile($,Z,"utf-8")}async exists($){try{return await $2.access($),!0}catch{return!1}}async readBinaryFile($){return $2.readFile($)}async stat($){try{let Z=await $2.stat($);return{size:Z.size,isDirectory:Z.isDirectory(),isFile:Z.isFile(),mtime:Z.mtime}}catch{return null}}async mkdir($,Z){await $2.mkdir($,{recursive:Z?.recursive??!1,mode:Z?.mode??493})}}function q4(){return VZ}function b7($){VZ=$}function _G(){VZ=new G4}var VZ;var t4=b(()=>{VZ=new G4});class RZ{connection;sessionId;capabilities;fallback;constructor($,Z,Y,Q=new G4){this.connection=$;this.sessionId=Z;this.capabilities=Y;this.fallback=Q}async readTextFile($){if(!this.capabilities.readTextFile)return B1.debug(`[AcpFileSystem] readTextFile fallback: ${$}`),this.fallback.readTextFile($);try{return B1.debug(`[AcpFileSystem] readTextFile via ACP: ${$}`),(await this.connection.readTextFile({path:$,sessionId:this.sessionId})).content}catch(Z){return B1.warn(`[AcpFileSystem] readTextFile ACP failed, fallback: ${Z}`),this.fallback.readTextFile($)}}async writeTextFile($,Z){if(!this.capabilities.writeTextFile)return B1.debug(`[AcpFileSystem] writeTextFile fallback: ${$}`),this.fallback.writeTextFile($,Z);try{B1.debug(`[AcpFileSystem] writeTextFile via ACP: ${$}`),await this.connection.writeTextFile({path:$,content:Z,sessionId:this.sessionId})}catch(Y){return B1.warn(`[AcpFileSystem] writeTextFile ACP failed, fallback: ${Y}`),this.fallback.writeTextFile($,Z)}}async exists($){if(!this.capabilities.readTextFile)return B1.debug(`[AcpFileSystem] exists fallback to local: ${$}`),this.fallback.exists($);try{return await this.connection.readTextFile({path:$,sessionId:this.sessionId}),B1.debug(`[AcpFileSystem] exists(${$}): true (ACP read success)`),!0}catch(Z){let Y=String(Z).toLowerCase();if(["not found","no such file","enoent","does not exist","file not found","path not found"].some((G)=>Y.includes(G)))return B1.debug(`[AcpFileSystem] exists(${$}): false (ACP: not found)`),!1;let J=AB(Y);return B1.warn(`[AcpFileSystem] exists(${$}): assuming exists due to ${J} error`,{error:String(Z),errorType:J,filePath:$}),!0}}async readBinaryFile($){return B1.debug(`[AcpFileSystem] readBinaryFile fallback: ${$}`),this.fallback.readBinaryFile($)}async stat($){return B1.debug(`[AcpFileSystem] stat fallback: ${$}`),this.fallback.stat($)}async mkdir($,Z){return B1.debug(`[AcpFileSystem] mkdir fallback: ${$}`),this.fallback.mkdir($,Z)}getCapabilities(){return this.capabilities}canReadTextFile(){return this.capabilities.readTextFile??!1}canWriteTextFile(){return this.capabilities.writeTextFile??!1}}function AB($){if($.includes("permission")||$.includes("access denied"))return"permission";if($.includes("timeout")||$.includes("timed out"))return"timeout";if($.includes("binary")||$.includes("encoding"))return"binary";if($.includes("too large")||$.includes("size"))return"size";if($.includes("connection")||$.includes("network"))return"network";return"unknown"}var B1;var zG=b(()=>{Y0();t4();B1=p("Agent")});import{spawn as bB}from"child_process";class DZ{async execute($,Z){return new Promise((Y)=>{let Q=process.platform==="win32"?"cmd.exe":"/bin/bash",X=process.platform==="win32"?["/c",$]:["-c",$],J=bB(Q,X,{cwd:Z?.cwd||process.cwd(),env:{...process.env,...Z?.env},stdio:["pipe","pipe","pipe"]}),G="",q="",K=!1,W=Z?.timeout?setTimeout(()=>{K=!0,J.kill("SIGTERM")},Z.timeout):null,U=null,H=()=>{if(W)clearTimeout(W);if(U&&Z?.signal)Z.signal.removeEventListener("abort",U),U=null};if(Z?.signal)U=()=>{K=!0,J.kill("SIGTERM")},Z.signal.addEventListener("abort",U);J.stdout.on("data",(O)=>{let F=O.toString();G+=F,Z?.onOutput?.(F)}),J.stderr.on("data",(O)=>{let F=O.toString();q+=F,Z?.onOutput?.(F)}),J.on("close",(O)=>{H(),Y({success:O===0&&!K,stdout:G,stderr:q,exitCode:O,error:K?"Command was terminated":void 0})}),J.on("error",(O)=>{H(),Y({success:!1,stdout:G,stderr:q,exitCode:null,error:O.message})})})}isAvailable(){return!0}}class BG{connection;sessionId;fallback;constructor($,Z,Y=new DZ){this.connection=$;this.sessionId=Z;this.fallback=Y}async execute($,Z){try{w2.debug(`[AcpTerminal] Executing command via ACP: ${$}`);let Y=await this.connection.createTerminal({sessionId:this.sessionId,command:$,cwd:Z?.cwd,env:Z?.env?Object.entries(Z.env).map(([W,U])=>({name:W,value:U})):void 0}),Q=0,X=null;if(Z?.onOutput)X=setInterval(async()=>{try{let U=(await Y.currentOutput()).output||"";if(U.length>Q){let H=U.slice(Q);Q=U.length,Z.onOutput?.(H)}}catch{}},100);let J=(W=!1)=>{if(X)clearInterval(X),X=null;(W?Y.kill().then(()=>w2.debug("[AcpTerminal] Killed remote command")).catch(()=>{}).then(()=>Y.release()).catch(()=>{}):Y.release().catch(()=>{})).catch(()=>{})},G=[];if(G.push(Y.waitForExit().then((W)=>({type:"completed",exitCode:W.exitCode??null}))),Z?.timeout)G.push(new Promise((W)=>{setTimeout(()=>W({type:"timeout"}),Z.timeout)}));if(Z?.signal)G.push(new Promise((W)=>{if(Z.signal.aborted)W({type:"aborted"});else Z.signal.addEventListener("abort",()=>W({type:"aborted"}),{once:!0})}));let q=await Promise.race(G),K="";try{if(K=(await Y.currentOutput()).output||"",Z?.onOutput&&K.length>Q)Z.onOutput(K.slice(Q))}catch{}switch(q.type){case"completed":return J(!1),{success:q.exitCode===0,stdout:K,stderr:"",exitCode:q.exitCode};case"timeout":return w2.debug(`[AcpTerminal] Command timed out, killing: ${$}`),J(!0),{success:!1,stdout:K,stderr:"",exitCode:null,error:"Command timed out"};case"aborted":return w2.debug(`[AcpTerminal] Command aborted, killing: ${$}`),J(!0),{success:!1,stdout:K,stderr:"",exitCode:null,error:"Command was aborted"}}}catch(Y){return w2.warn("[AcpTerminal] ACP terminal failed, using fallback:",Y),this.fallback.execute($,Z)}}isAvailable(){return!0}}function NG(){return H0.getInstance().getTerminalService()}function K4(){return H0.getInstance().isAcpMode()}var w2,H0;var g8=b(()=>{Y0();t4();zG();w2=p("Agent");H0=class H0{static sessions=new Map;static currentSessionId=null;constructor(){}static getInstance(){return new H0}static initializeSession($,Z,Y,Q){let X=Y?.fs?new RZ($,Z,Y.fs):new G4;if(Y?.fs)w2.debug(`[AcpServiceContext:${Z}] Using ACP file system service`);let J=new BG($,Z);w2.debug(`[AcpServiceContext:${Z}] Using ACP terminal service`),H0.sessions.set(Z,{fileSystemService:X,terminalService:J,connection:$,clientCapabilities:Y||null,cwd:Q}),H0.currentSessionId=Z,b7(X),w2.debug(`[AcpServiceContext:${Z}] Initialized with capabilities:`,{fs:!!Y?.fs,readTextFile:Y?.fs?.readTextFile,writeTextFile:Y?.fs?.writeTextFile,cwd:Q})}static destroySession($){if(H0.sessions.delete($),H0.currentSessionId===$){let Z=Array.from(H0.sessions.keys());if(H0.currentSessionId=Z[0]||null,!H0.currentSessionId)_G();else{let Y=H0.sessions.get(H0.currentSessionId);if(Y)b7(Y.fileSystemService)}}w2.debug(`[AcpServiceContext:${$}] Session destroyed`)}static getSessionServices($){return H0.sessions.get($)||null}static setCurrentSession($){if(H0.sessions.has($)){H0.currentSessionId=$;let Z=H0.sessions.get($);if(Z)b7(Z.fileSystemService)}}static getCurrentSessionId(){return H0.currentSessionId}initialize($,Z,Y,Q){H0.initializeSession($,Z,Y,Q||process.cwd())}reset(){if(H0.currentSessionId)H0.destroySession(H0.currentSessionId)}isAcpMode(){return H0.currentSessionId!==null}getFileSystemService(){if(H0.currentSessionId){let $=H0.sessions.get(H0.currentSessionId);if($)return $.fileSystemService}return new G4}getTerminalService(){if(H0.currentSessionId){let $=H0.sessions.get(H0.currentSessionId);if($)return $.terminalService}return new DZ}getConnection(){if(H0.currentSessionId){let $=H0.sessions.get(H0.currentSessionId);if($)return $.connection}return null}getSessionId(){return H0.currentSessionId}getClientCapabilities(){if(H0.currentSessionId){let $=H0.sessions.get(H0.currentSessionId);if($)return $.clientCapabilities}return null}async sendToolUpdate($,Z,Y,Q,X){let J=H0.currentSessionId;if(!J)return;let G=H0.sessions.get(J);if(!G)return;try{await G.connection.sessionUpdate({sessionId:J,update:{sessionUpdate:"tool_call",toolCallId:$,status:Z,title:Y,content:Q||[],kind:X||"other"}})}catch(q){w2.warn("[AcpServiceContext] Failed to send tool update:",q)}}}});import{isAbsolute as LG}from"path";import{z as y$}from"zod";var Z$;var W4=b(()=>{Z$={filePath:($)=>y$.string().min(1,"File path is required").refine((Z)=>LG(Z),{message:"Path must be absolute"}).describe($?.description||"Absolute file path"),encoding:()=>y$.enum(["utf8","base64","binary"]).default("utf8").describe("File encoding"),timeout:($=1000,Z=300000,Y=30000)=>y$.number().int("Must be an integer").min($,`Cannot be less than ${$}ms`).max(Z,`Cannot exceed ${Z}ms`).default(Y).describe(`Timeout in milliseconds (default ${Y}ms)`),pattern:($)=>y$.string().min(1,"Pattern is required").describe($?.description||"Regex or glob pattern"),glob:($)=>y$.string().min(1,"Glob pattern is required").describe($?.description||'Glob pattern (e.g., "*.js", "**/*.ts")'),lineNumber:($)=>y$.number().int("Line number must be an integer").min($?.min??0,`Line number cannot be less than ${$?.min??0}`).describe($?.description||"Line number"),lineLimit:($)=>y$.number().int("Line count must be an integer").min($?.min??1,`Line count cannot be less than ${$?.min??1}`).max($?.max??1e4,`Line count cannot exceed ${$?.max??1e4}`).describe($?.description||"Limit on lines to read"),workingDirectory:()=>y$.string().min(1,"Working directory is required").refine(($)=>LG($),{message:"Path must be absolute"}).describe("Absolute working directory"),environment:()=>y$.record(y$.string(),y$.string()).describe("Environment variables (key-value)").optional(),outputMode:($,Z)=>{let Y=y$.enum($);return Z?Y.default(Z):Y},flag:($)=>y$.boolean().default($?.defaultValue??!1).describe($?.description||"Boolean flag"),url:($)=>y$.string().url("Must be a valid URL").describe($?.description||"URL"),port:()=>y$.number().int("Port must be an integer").min(1,"Port cannot be less than 1").max(65535,"Port cannot exceed 65535").describe("Port number"),command:($)=>y$.string().min(1,"Command is required").describe($?.description||"Command to execute"),sessionId:()=>y$.string().min(1,"Session ID is required").uuid("Must be a valid UUID").optional().describe("Session identifier (UUID)"),nonNegativeInt:($)=>y$.number().int("Must be an integer").min(0,"Cannot be negative").describe($?.description||"Non-negative integer"),positiveInt:($)=>y$.number().int("Must be an integer").min(1,"Must be greater than 0").describe($?.description||"Positive integer")}});import*as MZ from"diff";function wG($,Z,Y=4){if($===Z)return null;let Q=MZ.createPatch("file",$,Z,"","",{context:Y}),X=Q.split(`
|
|
968
|
+
`}calculateTaskProgress($){let Z=$.length,Y=$.filter((Q)=>Q.status==="completed").length;return{total:Z,completed:Y}}}var A7;var I1=b(()=>{H$();Y0();b0();N9();l1();A7=p("Spec")});import*as $2 from"fs/promises";class G4{async readTextFile($){return $2.readFile($,"utf-8")}async writeTextFile($,Z){await $2.writeFile($,Z,"utf-8")}async exists($){try{return await $2.access($),!0}catch{return!1}}async readBinaryFile($){return $2.readFile($)}async stat($){try{let Z=await $2.stat($);return{size:Z.size,isDirectory:Z.isDirectory(),isFile:Z.isFile(),mtime:Z.mtime}}catch{return null}}async mkdir($,Z){await $2.mkdir($,{recursive:Z?.recursive??!1,mode:Z?.mode??493})}}function q4(){return VZ}function b7($){VZ=$}function _G(){VZ=new G4}var VZ;var t4=b(()=>{VZ=new G4});class RZ{connection;sessionId;capabilities;fallback;constructor($,Z,Y,Q=new G4){this.connection=$;this.sessionId=Z;this.capabilities=Y;this.fallback=Q}async readTextFile($){if(!this.capabilities.readTextFile)return B1.debug(`[AcpFileSystem] readTextFile fallback: ${$}`),this.fallback.readTextFile($);try{return B1.debug(`[AcpFileSystem] readTextFile via ACP: ${$}`),(await this.connection.readTextFile({path:$,sessionId:this.sessionId})).content}catch(Z){return B1.warn(`[AcpFileSystem] readTextFile ACP failed, fallback: ${Z}`),this.fallback.readTextFile($)}}async writeTextFile($,Z){if(!this.capabilities.writeTextFile)return B1.debug(`[AcpFileSystem] writeTextFile fallback: ${$}`),this.fallback.writeTextFile($,Z);try{B1.debug(`[AcpFileSystem] writeTextFile via ACP: ${$}`),await this.connection.writeTextFile({path:$,content:Z,sessionId:this.sessionId})}catch(Y){return B1.warn(`[AcpFileSystem] writeTextFile ACP failed, fallback: ${Y}`),this.fallback.writeTextFile($,Z)}}async exists($){if(!this.capabilities.readTextFile)return B1.debug(`[AcpFileSystem] exists fallback to local: ${$}`),this.fallback.exists($);try{return await this.connection.readTextFile({path:$,sessionId:this.sessionId}),B1.debug(`[AcpFileSystem] exists(${$}): true (ACP read success)`),!0}catch(Z){let Y=String(Z).toLowerCase();if(["not found","no such file","enoent","does not exist","file not found","path not found"].some((G)=>Y.includes(G)))return B1.debug(`[AcpFileSystem] exists(${$}): false (ACP: not found)`),!1;let J=AB(Y);return B1.warn(`[AcpFileSystem] exists(${$}): assuming exists due to ${J} error`,{error:String(Z),errorType:J,filePath:$}),!0}}async readBinaryFile($){return B1.debug(`[AcpFileSystem] readBinaryFile fallback: ${$}`),this.fallback.readBinaryFile($)}async stat($){return B1.debug(`[AcpFileSystem] stat fallback: ${$}`),this.fallback.stat($)}async mkdir($,Z){return B1.debug(`[AcpFileSystem] mkdir fallback: ${$}`),this.fallback.mkdir($,Z)}getCapabilities(){return this.capabilities}canReadTextFile(){return this.capabilities.readTextFile??!1}canWriteTextFile(){return this.capabilities.writeTextFile??!1}}function AB($){if($.includes("permission")||$.includes("access denied"))return"permission";if($.includes("timeout")||$.includes("timed out"))return"timeout";if($.includes("binary")||$.includes("encoding"))return"binary";if($.includes("too large")||$.includes("size"))return"size";if($.includes("connection")||$.includes("network"))return"network";return"unknown"}var B1;var zG=b(()=>{Y0();t4();B1=p("Agent")});import{spawn as bB}from"child_process";class DZ{async execute($,Z){return new Promise((Y)=>{let Q=process.platform==="win32"?"cmd.exe":"/bin/bash",X=process.platform==="win32"?["/c",$]:["-c",$],J=bB(Q,X,{cwd:Z?.cwd||process.cwd(),env:{...process.env,...Z?.env},stdio:["pipe","pipe","pipe"]}),G="",q="",K=!1,W=Z?.timeout?setTimeout(()=>{K=!0,J.kill("SIGTERM")},Z.timeout):null,U=null,H=()=>{if(W)clearTimeout(W);if(U&&Z?.signal)Z.signal.removeEventListener("abort",U),U=null};if(Z?.signal)U=()=>{K=!0,J.kill("SIGTERM")},Z.signal.addEventListener("abort",U);J.stdout.on("data",(O)=>{let F=O.toString();G+=F,Z?.onOutput?.(F)}),J.stderr.on("data",(O)=>{let F=O.toString();q+=F,Z?.onOutput?.(F)}),J.on("close",(O)=>{H(),Y({success:O===0&&!K,stdout:G,stderr:q,exitCode:O,error:K?"Command was terminated":void 0})}),J.on("error",(O)=>{H(),Y({success:!1,stdout:G,stderr:q,exitCode:null,error:O.message})})})}isAvailable(){return!0}}class BG{connection;sessionId;fallback;constructor($,Z,Y=new DZ){this.connection=$;this.sessionId=Z;this.fallback=Y}async execute($,Z){try{w2.debug(`[AcpTerminal] Executing command via ACP: ${$}`);let Y=await this.connection.createTerminal({sessionId:this.sessionId,command:$,cwd:Z?.cwd,env:Z?.env?Object.entries(Z.env).map(([W,U])=>({name:W,value:U})):void 0}),Q=0,X=null;if(Z?.onOutput)X=setInterval(async()=>{try{let U=(await Y.currentOutput()).output||"";if(U.length>Q){let H=U.slice(Q);Q=U.length,Z.onOutput?.(H)}}catch{}},100);let J=(W=!1)=>{if(X)clearInterval(X),X=null;(W?Y.kill().then(()=>w2.debug("[AcpTerminal] Killed remote command")).catch(()=>{}).then(()=>Y.release()).catch(()=>{}):Y.release().catch(()=>{})).catch(()=>{})},G=[];if(G.push(Y.waitForExit().then((W)=>({type:"completed",exitCode:W.exitCode??null}))),Z?.timeout)G.push(new Promise((W)=>{setTimeout(()=>W({type:"timeout"}),Z.timeout)}));if(Z?.signal)G.push(new Promise((W)=>{if(Z.signal.aborted)W({type:"aborted"});else Z.signal.addEventListener("abort",()=>W({type:"aborted"}),{once:!0})}));let q=await Promise.race(G),K="";try{if(K=(await Y.currentOutput()).output||"",Z?.onOutput&&K.length>Q)Z.onOutput(K.slice(Q))}catch{}switch(q.type){case"completed":return J(!1),{success:q.exitCode===0,stdout:K,stderr:"",exitCode:q.exitCode};case"timeout":return w2.debug(`[AcpTerminal] Command timed out, killing: ${$}`),J(!0),{success:!1,stdout:K,stderr:"",exitCode:null,error:"Command timed out"};case"aborted":return w2.debug(`[AcpTerminal] Command aborted, killing: ${$}`),J(!0),{success:!1,stdout:K,stderr:"",exitCode:null,error:"Command was aborted"}}}catch(Y){return w2.warn("[AcpTerminal] ACP terminal failed, using fallback:",Y),this.fallback.execute($,Z)}}isAvailable(){return!0}}function NG(){return H0.getInstance().getTerminalService()}function K4(){return H0.getInstance().isAcpMode()}var w2,H0;var g8=b(()=>{Y0();t4();zG();w2=p("Agent");H0=class H0{static sessions=new Map;static currentSessionId=null;constructor(){}static getInstance(){return new H0}static initializeSession($,Z,Y,Q){let X=Y?.fs?new RZ($,Z,Y.fs):new G4;if(Y?.fs)w2.debug(`[AcpServiceContext:${Z}] Using ACP file system service`);let J=new BG($,Z);w2.debug(`[AcpServiceContext:${Z}] Using ACP terminal service`),H0.sessions.set(Z,{fileSystemService:X,terminalService:J,connection:$,clientCapabilities:Y||null,cwd:Q}),H0.currentSessionId=Z,b7(X),w2.debug(`[AcpServiceContext:${Z}] Initialized with capabilities:`,{fs:!!Y?.fs,readTextFile:Y?.fs?.readTextFile,writeTextFile:Y?.fs?.writeTextFile,cwd:Q})}static destroySession($){if(H0.sessions.delete($),H0.currentSessionId===$){let Z=Array.from(H0.sessions.keys());if(H0.currentSessionId=Z[0]||null,!H0.currentSessionId)_G();else{let Y=H0.sessions.get(H0.currentSessionId);if(Y)b7(Y.fileSystemService)}}w2.debug(`[AcpServiceContext:${$}] Session destroyed`)}static getSessionServices($){return H0.sessions.get($)||null}static setCurrentSession($){if(H0.sessions.has($)){H0.currentSessionId=$;let Z=H0.sessions.get($);if(Z)b7(Z.fileSystemService)}}static getCurrentSessionId(){return H0.currentSessionId}initialize($,Z,Y,Q){H0.initializeSession($,Z,Y,Q||process.cwd())}reset(){if(H0.currentSessionId)H0.destroySession(H0.currentSessionId)}isAcpMode(){return H0.currentSessionId!==null}getFileSystemService(){if(H0.currentSessionId){let $=H0.sessions.get(H0.currentSessionId);if($)return $.fileSystemService}return new G4}getTerminalService(){if(H0.currentSessionId){let $=H0.sessions.get(H0.currentSessionId);if($)return $.terminalService}return new DZ}getConnection(){if(H0.currentSessionId){let $=H0.sessions.get(H0.currentSessionId);if($)return $.connection}return null}getSessionId(){return H0.currentSessionId}getClientCapabilities(){if(H0.currentSessionId){let $=H0.sessions.get(H0.currentSessionId);if($)return $.clientCapabilities}return null}async sendToolUpdate($,Z,Y,Q,X){let J=H0.currentSessionId;if(!J)return;let G=H0.sessions.get(J);if(!G)return;try{await G.connection.sessionUpdate({sessionId:J,update:{sessionUpdate:"tool_call",toolCallId:$,status:Z,title:Y,content:Q||[],kind:X||"other"}})}catch(q){w2.warn("[AcpServiceContext] Failed to send tool update:",q)}}}});import{isAbsolute as LG}from"path";import{z as y$}from"zod";var Z$;var W4=b(()=>{Z$={filePath:($)=>y$.string().min(1,"File path is required").refine((Z)=>LG(Z),{message:"Path must be absolute"}).describe($?.description||"Absolute file path"),encoding:()=>y$.enum(["utf8","base64","binary"]).default("utf8").describe("File encoding"),timeout:($=1000,Z=300000,Y=30000)=>y$.number().int("Must be an integer").min($,`Cannot be less than ${$}ms`).max(Z,`Cannot exceed ${Z}ms`).default(Y).describe(`Timeout in milliseconds (default ${Y}ms)`),pattern:($)=>y$.string().min(1,"Pattern is required").describe($?.description||"Regex or glob pattern"),glob:($)=>y$.string().min(1,"Glob pattern is required").describe($?.description||'Glob pattern (e.g., "*.js", "**/*.ts")'),lineNumber:($)=>y$.number().int("Line number must be an integer").min($?.min??0,`Line number cannot be less than ${$?.min??0}`).describe($?.description||"Line number"),lineLimit:($)=>y$.number().int("Line count must be an integer").min($?.min??1,`Line count cannot be less than ${$?.min??1}`).max($?.max??1e4,`Line count cannot exceed ${$?.max??1e4}`).describe($?.description||"Limit on lines to read"),workingDirectory:()=>y$.string().min(1,"Working directory is required").refine(($)=>LG($),{message:"Path must be absolute"}).describe("Absolute working directory"),environment:()=>y$.record(y$.string(),y$.string()).describe("Environment variables (key-value)").optional(),outputMode:($,Z)=>{let Y=y$.enum($);return Z?Y.default(Z):Y},flag:($)=>y$.boolean().default($?.defaultValue??!1).describe($?.description||"Boolean flag"),url:($)=>y$.string().url("Must be a valid URL").describe($?.description||"URL"),port:()=>y$.number().int("Port must be an integer").min(1,"Port cannot be less than 1").max(65535,"Port cannot exceed 65535").describe("Port number"),command:($)=>y$.string().min(1,"Command is required").describe($?.description||"Command to execute"),sessionId:()=>y$.string().min(1,"Session ID is required").uuid("Must be a valid UUID").optional().describe("Session identifier (UUID)"),nonNegativeInt:($)=>y$.number().int("Must be an integer").min(0,"Cannot be negative").describe($?.description||"Non-negative integer"),positiveInt:($)=>y$.number().int("Must be an integer").min(1,"Must be greater than 0").describe($?.description||"Positive integer")}});import*as MZ from"diff";function wG($,Z,Y=4){if($===Z)return null;let Q=MZ.createPatch("file",$,Z,"","",{context:Y}),X=Q.split(`
|
|
969
969
|
`),J=1;for(let G of X){let q=G.match(/@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@/);if(q){J=parseInt(q[1],10);break}}return`
|
|
970
970
|
<<<DIFF>>>
|
|
971
971
|
${JSON.stringify({patch:Q,startLine:Math.max(1,J-Y),matchLine:J})}
|
|
@@ -1928,7 +1928,7 @@ ${$.map((Y)=>{let Q=!Y.tools||Y.tools.length===0?"All tools":Y.tools.join(", ");
|
|
|
1928
1928
|
`+` /model add
|
|
1929
1929
|
|
|
1930
1930
|
`+`或运行初始化向导:
|
|
1931
|
-
`+" /init");let Y=f0();if(!Y)throw Error("❌ 配置未初始化,请确保应用已正确启动");f$.getInstance().validateConfig(Y);let Q=new V2(Y,$);return await Q.initialize(),Q}get sessionId(){return this.options.sessionId}getConfig(){return this.config}getChatService(){return this.chatService}getExecutionEngine(){return this.executionEngine}getAttachmentCollector(){return this.attachmentCollector}getCurrentModelId(){return this.currentModelId}getCurrentModelMaxContextTokens(){return this.currentModelMaxContextTokens}async initialize(){if(this.initialized)return;await this.validateSystemPromptConfig(),await this.registerBuiltinTools(),await this.loadSubagents(),await this.discoverSkills(),await this.applyModelConfig(this.resolveModelConfig(this.options.modelId),"\uD83D\uDE80 使用模型:"),this.initialized=!0,Y8.debug(`[SessionRuntime ${this.sessionId}] initialized with ${this.baseRegistry.getAll().length} tools`)}async refresh($){if(!this.initialized){await this.initialize();return}let Z=$.modelId&&$.modelId!=="inherit"?$.modelId:void 0;if(Z&&Z!==this.currentModelId)await this.applyModelConfig(this.resolveModelConfig(Z),"\uD83D\uDD01 切换模型")}createExecutionPipeline($={}){let Z=new F4,Y=$.toolWhitelist?new Set($.toolWhitelist):null;for(let J of this.baseRegistry.getBuiltinTools())if(!Y||Y.has(J.name))Z.register(J);for(let J of this.baseRegistry.getMcpTools())if(!Y||Y.has(J.name))Z.registerMcpTool(J);let Q={...this.config.permissions,...$.permissions},X=$.permissionMode??this.config.permissionMode??"default";return new q6(Z,{permissionConfig:Q,permissionMode:X,approvalStore:this.approvalStore,maxHistorySize:1000})}async dispose(){this.approvalStore.clear(),await this.chatService?.dispose?.(),this.currentModelId=void 0,this.initialized=!1}resolveModelConfig($){let Z=$&&$!=="inherit"?$:void 0,Y=Z?E3(Z):B2();if(!Y)throw Error(`❌ 模型配置未找到: ${Z??"current"}`);return Y}async applyModelConfig($,Z){Y8.debug(`${Z} ${$.name} (${$.model})`);let Y=_4($),Q=c6(),X=Y&&Q;this.currentModelMaxContextTokens=$.maxContextTokens??this.config.maxContextTokens,this.chatService=await k8({provider:$.provider,apiKey:$.apiKey,model:$.model,baseUrl:$.baseUrl,temperature:$.temperature??this.config.temperature,maxContextTokens:this.currentModelMaxContextTokens,maxOutputTokens:$.maxOutputTokens??this.config.maxOutputTokens,timeout:this.config.timeout,supportsThinking:X});let J=this.executionEngine?.getContextManager();this.executionEngine=new U6(this.chatService,J),this.currentModelId=$.id}async validateSystemPromptConfig(){try{await o4({projectPath:process.cwd(),includeEnvironment:!1,language:this.config.language})}catch($){Y8.warn("[SessionRuntime] Failed to validate system prompt configuration:",$)}}async registerBuiltinTools(){let Z=(await f7({sessionId:this.sessionId,configDir:tq.join(sq.homedir(),".blade")})).filter((Y)=>!Y.name.startsWith("mcp__"));this.baseRegistry.registerAll(Z),await this.registerMcpTools()}async registerMcpTools(){try{if(this.options.mcpConfig&&this.options.mcpConfig.length>0)await Q7(this.options.mcpConfig);let $=q1();if(Object.keys($).length===0)return;let Z=k0.getInstance();for(let[Q,X]of Object.entries($))try{await Z.registerServer(Q,X)}catch(J){Y8.warn(`⚠️ MCP server "${Q}" connection failed:`,J)}let Y=await Z.getAvailableTools();for(let Q of Y)this.baseRegistry.registerMcpTool(Q)}catch($){Y8.warn("Failed to register MCP tools:",$)}}async loadSubagents(){if(a0.getAllNames().length>0)return;try{a0.loadFromStandardLocations()}catch($){Y8.warn("Failed to load subagents:",$)}}async discoverSkills(){try{await S2({cwd:process.cwd()})}catch($){Y8.warn("Failed to discover skills:",$)}}}var Y8;var H6=b(()=>{Y4();Y4();Y0();e5();s1();AZ();bZ();$7();t1();b0();EY();BY();NY();K6();MY();z4();Y8=p("Agent")});import B4 from"node:fs";import QL from"node:os";import eq from"node:path";class Q8{static instance=null;sessionsDir;cache=new Map;constructor(){this.sessionsDir=eq.join(QL.homedir(),".blade","agents","sessions"),this.ensureDirectory()}static getInstance(){if(!Q8.instance)Q8.instance=new Q8;return Q8.instance}ensureDirectory(){if(!B4.existsSync(this.sessionsDir))B4.mkdirSync(this.sessionsDir,{recursive:!0,mode:493})}getSessionPath($){let Z=$.replace(/[^a-zA-Z0-9_-]/g,"_");return eq.join(this.sessionsDir,`${Z}.json`)}saveSession($){try{let Z=this.getSessionPath($.id),Y=JSON.stringify($,null,2);B4.writeFileSync(Z,Y,"utf-8"),this.cache.set($.id,$),i8.debug(`Session saved: ${$.id}`)}catch(Z){i8.warn(`Failed to save session ${$.id}:`,Z)}}loadSession($){if(this.cache.has($))return this.cache.get($);try{let Z=this.getSessionPath($);if(!B4.existsSync(Z))return;let Y=B4.readFileSync(Z,"utf-8"),Q=JSON.parse(Y);return this.cache.set($,Q),Q}catch(Z){i8.warn(`Failed to load session ${$}:`,Z);return}}updateSession($,Z){let Y=this.loadSession($);if(!Y)return;let Q={...Y,...Z,lastActiveAt:Date.now()};return this.saveSession(Q),Q}appendMessages($,Z){let Y=this.loadSession($);if(!Y)return;return this.updateSession($,{messages:[...Y.messages,...Z]})}markCompleted($,Z,Y){return this.updateSession($,{status:Z.success?"completed":"failed",result:Z,stats:Y,completedAt:Date.now()})}deleteSession($){try{let Z=this.getSessionPath($);if(B4.existsSync(Z))B4.unlinkSync(Z);return this.cache.delete($),!0}catch(Z){return i8.warn(`Failed to delete session ${$}:`,Z),!1}}listSessions(){try{let $=B4.readdirSync(this.sessionsDir),Z=[];for(let Y of $){if(!Y.endsWith(".json"))continue;let Q=Y.replace(".json",""),X=this.loadSession(Q);if(X)Z.push(X)}return Z.sort((Y,Q)=>Q.lastActiveAt-Y.lastActiveAt)}catch($){return i8.warn("Failed to list sessions:",$),[]}}listRunningSessions(){return this.listSessions().filter(($)=>$.status==="running")}cleanupExpiredSessions($=604800000){let Z=Date.now(),Y=this.listSessions(),Q=0;for(let X of Y){if(X.status==="running")continue;if(Z-X.lastActiveAt>$){if(this.deleteSession(X.id))Q++}}if(Q>0)i8.info(`Cleaned up ${Q} expired agent sessions`);return Q}clearCache(){this.cache.clear()}}var i8;var $K=b(()=>{Y0();i8=p("Agent")});import{nanoid as XL}from"nanoid";class L1{static instance=null;runningAgents=new Map;sessionStore=Q8.getInstance();constructor(){this.cleanupOrphanedSessions()}static getInstance(){if(!L1.instance)L1.instance=new L1;return L1.instance}cleanupOrphanedSessions(){let $=this.sessionStore.listSessions(),Z=Date.now(),Y=1800000;for(let Q of $)if(Q.status==="running"){let X=this.runningAgents.has(Q.id),J=Z-Q.lastActiveAt;if(!X||J>1800000)X8.warn(`Cleaning up orphaned agent session: ${Q.id}`),this.sessionStore.updateSession(Q.id,{status:"failed",result:{success:!1,message:"",error:"Session was orphaned (process restart or timeout)"},completedAt:Z})}}startBackgroundAgent($){let{config:Z,description:Y,prompt:Q,parentSessionId:X,permissionMode:J,agentId:G,existingMessages:q}=$,K=G||XL(),W=new AbortController,U={id:K,subagentType:Z.name,description:Y,prompt:Q,messages:q||[],status:"running",createdAt:Date.now(),lastActiveAt:Date.now(),parentSessionId:X};this.sessionStore.saveSession(U);let H=Date.now(),O=this.executeAgent(K,Z,Q,X,J,W.signal,q);return this.runningAgents.set(K,{id:K,promise:O,abortController:W,startTime:H}),O.finally(()=>{this.runningAgents.delete(K)}),X8.info(`Background agent started: ${K} (${Z.name})`),K}async executeAgent($,Z,Y,Q,X,J,G){let q=Date.now(),K;try{if(J.aborted)throw Error("Agent execution was cancelled");let W=Z.systemPrompt||"",U=Z.model&&Z.model!=="inherit"?Z.model:void 0;K=await V2.create({sessionId:$,modelId:U});let H=await n0.createWithRuntime(K,{sessionId:$,systemPrompt:W,toolWhitelist:Z.tools,modelId:U}),O={messages:G||[],userId:"subagent",sessionId:$,workspaceRoot:process.cwd(),permissionMode:X,subagentInfo:{parentSessionId:Q||"",subagentType:Z.name,isSidechain:!1}},F=await H.runAgenticLoop(Y,O,{signal:J});this.sessionStore.updateSession($,{messages:O.messages});let _=Date.now()-q,z=F.success?{success:!0,message:F.finalMessage||"",agentId:$,stats:{tokens:F.metadata?.tokensUsed||0,toolCalls:F.metadata?.toolCallsCount||0,duration:_}}:{success:!1,message:"",agentId:$,error:F.error?.message||"Unknown error",stats:{duration:_}};return this.sessionStore.markCompleted($,{success:z.success,message:z.message,error:z.error},z.stats),X8.info(`Background agent completed: ${$} (success=${z.success})`),z}catch(W){let U=Date.now()-q,H=W instanceof Error?W.message:String(W);return this.sessionStore.markCompleted($,{success:!1,message:"",error:H},{duration:U}),X8.warn(`Background agent failed: ${$}`,W),{success:!1,message:"",agentId:$,error:H,stats:{duration:U}}}finally{await K?.dispose()}}getAgent($){return this.sessionStore.loadSession($)}isRunning($){return this.runningAgents.has($)}async waitForCompletion($,Z=30000){let Y=this.runningAgents.get($);if(!Y)return this.sessionStore.loadSession($);if(Z>0){let Q=new Promise((J)=>setTimeout(()=>J("timeout"),Z));if(await Promise.race([Y.promise,Q])==="timeout")return this.sessionStore.loadSession($)}else await Y.promise;return this.sessionStore.loadSession($)}resumeAgent($,Z,Y,Q,X){let J=this.sessionStore.loadSession($);if(!J){X8.warn(`Cannot resume agent ${$}: session not found`);return}if(this.isRunning($)){X8.warn(`Cannot resume agent ${$}: still running`);return}return this.startBackgroundAgent({config:Y,description:J.description,prompt:Z,parentSessionId:Q||J.parentSessionId,permissionMode:X,agentId:$,existingMessages:J.messages})}killAgent($){let Z=this.runningAgents.get($);if(!Z){let Y=this.sessionStore.loadSession($);if(Y&&Y.status==="running")this.sessionStore.updateSession($,{status:"cancelled"});return!1}return Z.abortController.abort(),this.sessionStore.updateSession($,{status:"cancelled"}),X8.info(`Background agent cancelled: ${$}`),!0}listAll(){return this.sessionStore.listSessions()}listRunning(){return this.sessionStore.listRunningSessions()}getRunningCount(){return this.runningAgents.size}killAll(){for(let[$]of this.runningAgents)this.killAgent($)}cleanupExpiredSessions($){return this.sessionStore.cleanupExpiredSessions($)}}var X8;var h7=b(()=>{Y0();Q2();H6();$K();X8=p("Agent")});import{nanoid as JL}from"nanoid";class IY{config;constructor($){this.config=$}async execute($){let Z=Date.now(),Y=$.subagentSessionId??JL();try{let Q=this.buildSystemPrompt($),X=this.config.model&&this.config.model!=="inherit"?this.config.model:void 0,J=await n0.create({toolWhitelist:this.config.tools,modelId:X}),G="",q=0,K=0,W={parentSessionId:$.parentSessionId||"",subagentType:this.config.name,isSidechain:!1},U=await J.runAgenticLoop($.prompt,{messages:[],userId:"subagent",sessionId:Y,workspaceRoot:process.cwd(),permissionMode:$.permissionMode,systemPrompt:Q,subagentInfo:W},{onToolStart:$.onToolStart,onToolResult:$.onToolResult?async(O,F)=>{$.onToolResult?.(O,F)}:void 0,onContentDelta:$.onContentDelta,onThinkingDelta:$.onThinkingDelta,onStreamEnd:$.onStreamEnd});if(U.success)G=U.finalMessage||"",q=U.metadata?.toolCallsCount||0,K=U.metadata?.tokensUsed||0;else throw Error(U.error?.message||"Subagent execution failed");let H=Date.now()-Z;return{success:!0,message:G,agentId:Y,stats:{tokens:K,toolCalls:q,duration:H}}}catch(Q){let X=Date.now()-Z;return{success:!1,message:"",agentId:Y,error:Q instanceof Error?Q.message:String(Q),stats:{duration:X}}}}buildSystemPrompt($){return this.config.systemPrompt||""}}var ZK=b(()=>{Q2()});import{EventEmitter as GL}from"events";var r8,P1;var PY=b(()=>{r8=class r8 extends GL{static instance;constructor(){super();this.setMaxListeners(100)}static getInstance(){if(!r8.instance)r8.instance=new r8;return r8.instance}publish($,Z,Y){this.emit("event",{sessionId:$,type:Z,properties:Y})}subscribe($){return this.on("event",$),()=>this.off("event",$)}};P1=r8.getInstance()});import{nanoid as YK}from"nanoid";import{z as J8}from"zod";function qL($){let Z=$.message||"Unknown error";if(Z.includes("Too Many Requests")||Z.includes("429")){let Y=$.cause;if(Y?.responseBody)try{let Q=JSON.parse(Y.responseBody);if(Q.message)return Q.message}catch{}return"API 请求过于频繁,请稍后重试"}if(Z.includes("ECONNREFUSED")||Z.includes("ETIMEDOUT"))return"网络连接失败,请检查网络设置";if(Z.includes("401")||Z.includes("Unauthorized"))return"API 认证失败,请检查 API Key 配置";return Z.split(`
|
|
1931
|
+
`+" /init");let Y=f0();if(!Y)throw Error("❌ 配置未初始化,请确保应用已正确启动");f$.getInstance().validateConfig(Y);let Q=new V2(Y,$);return await Q.initialize(),Q}get sessionId(){return this.options.sessionId}getConfig(){return this.config}getChatService(){return this.chatService}getExecutionEngine(){return this.executionEngine}getAttachmentCollector(){return this.attachmentCollector}getCurrentModelId(){return this.currentModelId}getCurrentModelMaxContextTokens(){return this.currentModelMaxContextTokens}async initialize(){if(this.initialized)return;await this.validateSystemPromptConfig(),await this.registerBuiltinTools(),await this.loadSubagents(),await this.discoverSkills(),await this.applyModelConfig(this.resolveModelConfig(this.options.modelId),"\uD83D\uDE80 使用模型:"),this.initialized=!0,Y8.debug(`[SessionRuntime ${this.sessionId}] initialized with ${this.baseRegistry.getAll().length} tools`)}async refresh($){if(!this.initialized){await this.initialize();return}let Z=$.modelId&&$.modelId!=="inherit"?$.modelId:void 0;if(Z&&Z!==this.currentModelId)await this.applyModelConfig(this.resolveModelConfig(Z),"\uD83D\uDD01 切换模型")}createExecutionPipeline($={}){let Z=new F4,Y=$.toolWhitelist?new Set($.toolWhitelist):null;for(let J of this.baseRegistry.getBuiltinTools())if(!Y||Y.has(J.name))Z.register(J);for(let J of this.baseRegistry.getMcpTools())if(!Y||Y.has(J.name))Z.registerMcpTool(J);let Q={...this.config.permissions,...$.permissions},X=$.permissionMode??this.config.permissionMode??"default";return new q6(Z,{permissionConfig:Q,permissionMode:X,approvalStore:this.approvalStore,maxHistorySize:1000})}async dispose(){this.approvalStore.clear(),await this.chatService?.dispose?.(),this.currentModelId=void 0,this.initialized=!1}resolveModelConfig($){let Z=$&&$!=="inherit"?$:void 0,Y=Z?E3(Z):B2();if(!Y)throw Error(`❌ 模型配置未找到: ${Z??"current"}`);return Y}async applyModelConfig($,Z){Y8.debug(`${Z} ${$.name} (${$.model})`);let Y=_4($),Q=c6(),X=Y&&Q;this.currentModelMaxContextTokens=$.maxContextTokens??this.config.maxContextTokens,this.chatService=await k8({provider:$.provider,apiKey:$.apiKey,model:$.model,baseUrl:$.baseUrl,temperature:$.temperature??this.config.temperature,maxContextTokens:this.currentModelMaxContextTokens,maxOutputTokens:$.maxOutputTokens??this.config.maxOutputTokens,timeout:this.config.timeout,supportsThinking:X});let J=this.executionEngine?.getContextManager();this.executionEngine=new U6(this.chatService,J),this.currentModelId=$.id}async validateSystemPromptConfig(){try{await o4({projectPath:process.cwd(),includeEnvironment:!1,language:this.config.language})}catch($){Y8.warn("[SessionRuntime] Failed to validate system prompt configuration:",$)}}async registerBuiltinTools(){let Z=(await f7({sessionId:this.sessionId,configDir:tq.join(sq.homedir(),".blade")})).filter((Y)=>!Y.name.startsWith("mcp__"));this.baseRegistry.registerAll(Z),await this.registerMcpTools()}async registerMcpTools(){try{if(this.options.mcpConfig&&this.options.mcpConfig.length>0)await Q7(this.options.mcpConfig);let $=q1();if(Object.keys($).length===0)return;let Z=k0.getInstance();for(let[Q,X]of Object.entries($))try{await Z.registerServer(Q,X)}catch(J){Y8.warn(`⚠️ MCP server "${Q}" connection failed:`,J)}let Y=await Z.getAvailableTools();for(let Q of Y)this.baseRegistry.registerMcpTool(Q)}catch($){Y8.warn("Failed to register MCP tools:",$)}}async loadSubagents(){if(a0.getAllNames().length>0)return;try{a0.loadFromStandardLocations()}catch($){Y8.warn("Failed to load subagents:",$)}}async discoverSkills(){try{await S2({cwd:process.cwd()})}catch($){Y8.warn("Failed to discover skills:",$)}}}var Y8;var H6=b(()=>{Y4();Y4();Y0();e9();s1();AZ();bZ();$7();t1();b0();EY();BY();NY();K6();MY();z4();Y8=p("Agent")});import B4 from"node:fs";import QL from"node:os";import eq from"node:path";class Q8{static instance=null;sessionsDir;cache=new Map;constructor(){this.sessionsDir=eq.join(QL.homedir(),".blade","agents","sessions"),this.ensureDirectory()}static getInstance(){if(!Q8.instance)Q8.instance=new Q8;return Q8.instance}ensureDirectory(){if(!B4.existsSync(this.sessionsDir))B4.mkdirSync(this.sessionsDir,{recursive:!0,mode:493})}getSessionPath($){let Z=$.replace(/[^a-zA-Z0-9_-]/g,"_");return eq.join(this.sessionsDir,`${Z}.json`)}saveSession($){try{let Z=this.getSessionPath($.id),Y=JSON.stringify($,null,2);B4.writeFileSync(Z,Y,"utf-8"),this.cache.set($.id,$),i8.debug(`Session saved: ${$.id}`)}catch(Z){i8.warn(`Failed to save session ${$.id}:`,Z)}}loadSession($){if(this.cache.has($))return this.cache.get($);try{let Z=this.getSessionPath($);if(!B4.existsSync(Z))return;let Y=B4.readFileSync(Z,"utf-8"),Q=JSON.parse(Y);return this.cache.set($,Q),Q}catch(Z){i8.warn(`Failed to load session ${$}:`,Z);return}}updateSession($,Z){let Y=this.loadSession($);if(!Y)return;let Q={...Y,...Z,lastActiveAt:Date.now()};return this.saveSession(Q),Q}appendMessages($,Z){let Y=this.loadSession($);if(!Y)return;return this.updateSession($,{messages:[...Y.messages,...Z]})}markCompleted($,Z,Y){return this.updateSession($,{status:Z.success?"completed":"failed",result:Z,stats:Y,completedAt:Date.now()})}deleteSession($){try{let Z=this.getSessionPath($);if(B4.existsSync(Z))B4.unlinkSync(Z);return this.cache.delete($),!0}catch(Z){return i8.warn(`Failed to delete session ${$}:`,Z),!1}}listSessions(){try{let $=B4.readdirSync(this.sessionsDir),Z=[];for(let Y of $){if(!Y.endsWith(".json"))continue;let Q=Y.replace(".json",""),X=this.loadSession(Q);if(X)Z.push(X)}return Z.sort((Y,Q)=>Q.lastActiveAt-Y.lastActiveAt)}catch($){return i8.warn("Failed to list sessions:",$),[]}}listRunningSessions(){return this.listSessions().filter(($)=>$.status==="running")}cleanupExpiredSessions($=604800000){let Z=Date.now(),Y=this.listSessions(),Q=0;for(let X of Y){if(X.status==="running")continue;if(Z-X.lastActiveAt>$){if(this.deleteSession(X.id))Q++}}if(Q>0)i8.info(`Cleaned up ${Q} expired agent sessions`);return Q}clearCache(){this.cache.clear()}}var i8;var $K=b(()=>{Y0();i8=p("Agent")});import{nanoid as XL}from"nanoid";class L1{static instance=null;runningAgents=new Map;sessionStore=Q8.getInstance();constructor(){this.cleanupOrphanedSessions()}static getInstance(){if(!L1.instance)L1.instance=new L1;return L1.instance}cleanupOrphanedSessions(){let $=this.sessionStore.listSessions(),Z=Date.now(),Y=1800000;for(let Q of $)if(Q.status==="running"){let X=this.runningAgents.has(Q.id),J=Z-Q.lastActiveAt;if(!X||J>1800000)X8.warn(`Cleaning up orphaned agent session: ${Q.id}`),this.sessionStore.updateSession(Q.id,{status:"failed",result:{success:!1,message:"",error:"Session was orphaned (process restart or timeout)"},completedAt:Z})}}startBackgroundAgent($){let{config:Z,description:Y,prompt:Q,parentSessionId:X,permissionMode:J,agentId:G,existingMessages:q}=$,K=G||XL(),W=new AbortController,U={id:K,subagentType:Z.name,description:Y,prompt:Q,messages:q||[],status:"running",createdAt:Date.now(),lastActiveAt:Date.now(),parentSessionId:X};this.sessionStore.saveSession(U);let H=Date.now(),O=this.executeAgent(K,Z,Q,X,J,W.signal,q);return this.runningAgents.set(K,{id:K,promise:O,abortController:W,startTime:H}),O.finally(()=>{this.runningAgents.delete(K)}),X8.info(`Background agent started: ${K} (${Z.name})`),K}async executeAgent($,Z,Y,Q,X,J,G){let q=Date.now(),K;try{if(J.aborted)throw Error("Agent execution was cancelled");let W=Z.systemPrompt||"",U=Z.model&&Z.model!=="inherit"?Z.model:void 0;K=await V2.create({sessionId:$,modelId:U});let H=await n0.createWithRuntime(K,{sessionId:$,systemPrompt:W,toolWhitelist:Z.tools,modelId:U}),O={messages:G||[],userId:"subagent",sessionId:$,workspaceRoot:process.cwd(),permissionMode:X,subagentInfo:{parentSessionId:Q||"",subagentType:Z.name,isSidechain:!1}},F=await H.runAgenticLoop(Y,O,{signal:J});this.sessionStore.updateSession($,{messages:O.messages});let _=Date.now()-q,z=F.success?{success:!0,message:F.finalMessage||"",agentId:$,stats:{tokens:F.metadata?.tokensUsed||0,toolCalls:F.metadata?.toolCallsCount||0,duration:_}}:{success:!1,message:"",agentId:$,error:F.error?.message||"Unknown error",stats:{duration:_}};return this.sessionStore.markCompleted($,{success:z.success,message:z.message,error:z.error},z.stats),X8.info(`Background agent completed: ${$} (success=${z.success})`),z}catch(W){let U=Date.now()-q,H=W instanceof Error?W.message:String(W);return this.sessionStore.markCompleted($,{success:!1,message:"",error:H},{duration:U}),X8.warn(`Background agent failed: ${$}`,W),{success:!1,message:"",agentId:$,error:H,stats:{duration:U}}}finally{await K?.dispose()}}getAgent($){return this.sessionStore.loadSession($)}isRunning($){return this.runningAgents.has($)}async waitForCompletion($,Z=30000){let Y=this.runningAgents.get($);if(!Y)return this.sessionStore.loadSession($);if(Z>0){let Q=new Promise((J)=>setTimeout(()=>J("timeout"),Z));if(await Promise.race([Y.promise,Q])==="timeout")return this.sessionStore.loadSession($)}else await Y.promise;return this.sessionStore.loadSession($)}resumeAgent($,Z,Y,Q,X){let J=this.sessionStore.loadSession($);if(!J){X8.warn(`Cannot resume agent ${$}: session not found`);return}if(this.isRunning($)){X8.warn(`Cannot resume agent ${$}: still running`);return}return this.startBackgroundAgent({config:Y,description:J.description,prompt:Z,parentSessionId:Q||J.parentSessionId,permissionMode:X,agentId:$,existingMessages:J.messages})}killAgent($){let Z=this.runningAgents.get($);if(!Z){let Y=this.sessionStore.loadSession($);if(Y&&Y.status==="running")this.sessionStore.updateSession($,{status:"cancelled"});return!1}return Z.abortController.abort(),this.sessionStore.updateSession($,{status:"cancelled"}),X8.info(`Background agent cancelled: ${$}`),!0}listAll(){return this.sessionStore.listSessions()}listRunning(){return this.sessionStore.listRunningSessions()}getRunningCount(){return this.runningAgents.size}killAll(){for(let[$]of this.runningAgents)this.killAgent($)}cleanupExpiredSessions($){return this.sessionStore.cleanupExpiredSessions($)}}var X8;var h7=b(()=>{Y0();Q2();H6();$K();X8=p("Agent")});import{nanoid as JL}from"nanoid";class IY{config;constructor($){this.config=$}async execute($){let Z=Date.now(),Y=$.subagentSessionId??JL();try{let Q=this.buildSystemPrompt($),X=this.config.model&&this.config.model!=="inherit"?this.config.model:void 0,J=await n0.create({toolWhitelist:this.config.tools,modelId:X}),G="",q=0,K=0,W={parentSessionId:$.parentSessionId||"",subagentType:this.config.name,isSidechain:!1},U=await J.runAgenticLoop($.prompt,{messages:[],userId:"subagent",sessionId:Y,workspaceRoot:process.cwd(),permissionMode:$.permissionMode,systemPrompt:Q,subagentInfo:W},{onToolStart:$.onToolStart,onToolResult:$.onToolResult?async(O,F)=>{$.onToolResult?.(O,F)}:void 0,onContentDelta:$.onContentDelta,onThinkingDelta:$.onThinkingDelta,onStreamEnd:$.onStreamEnd});if(U.success)G=U.finalMessage||"",q=U.metadata?.toolCallsCount||0,K=U.metadata?.tokensUsed||0;else throw Error(U.error?.message||"Subagent execution failed");let H=Date.now()-Z;return{success:!0,message:G,agentId:Y,stats:{tokens:K,toolCalls:q,duration:H}}}catch(Q){let X=Date.now()-Z;return{success:!1,message:"",agentId:Y,error:Q instanceof Error?Q.message:String(Q),stats:{duration:X}}}}buildSystemPrompt($){return this.config.systemPrompt||""}}var ZK=b(()=>{Q2()});import{EventEmitter as GL}from"events";var r8,P1;var PY=b(()=>{r8=class r8 extends GL{static instance;constructor(){super();this.setMaxListeners(100)}static getInstance(){if(!r8.instance)r8.instance=new r8;return r8.instance}publish($,Z,Y){this.emit("event",{sessionId:$,type:Z,properties:Y})}subscribe($){return this.on("event",$),()=>this.off("event",$)}};P1=r8.getInstance()});import{nanoid as YK}from"nanoid";import{z as J8}from"zod";function qL($){let Z=$.message||"Unknown error";if(Z.includes("Too Many Requests")||Z.includes("429")){let Y=$.cause;if(Y?.responseBody)try{let Q=JSON.parse(Y.responseBody);if(Q.message)return Q.message}catch{}return"API 请求过于频繁,请稍后重试"}if(Z.includes("ECONNREFUSED")||Z.includes("ETIMEDOUT"))return"网络连接失败,请检查网络设置";if(Z.includes("401")||Z.includes("Unauthorized"))return"API 认证失败,请检查 API Key 配置";return Z.split(`
|
|
1932
1932
|
`)[0]}function KL($){return a0.getAllNames().includes($)}function WL(){let $=a0.getAllNames();return $.length>0?$.join(", "):"none (registry not initialized)"}function UL(){return`
|
|
1933
1933
|
## Task
|
|
1934
1934
|
|
|
@@ -2221,7 +2221,7 @@ Please continue the conversation from where we left it off without asking the us
|
|
|
2221
2221
|
|
|
2222
2222
|
⚠️ Some files could not be loaded:
|
|
2223
2223
|
`,X+=Q.join(`
|
|
2224
|
-
`);return X}}var f,$w=0.1,Zw=8192,Yw=32768;var Q2=b(()=>{Y4();o5();K1();Y0();t5();e5();s1();AZ();bZ();wZ();$7();t1();I1();b0();EY();BY();NY();R$();LZ();K6();MY();z4();f=p("Agent")});import{z as q0}from"zod";function hK($){return qw.safeParse($)}var Xw,Jw,Gw,fK,SK,qw;var pY=b(()=>{Xw=q0.string().min(2,"Plugin name must be at least 2 characters").max(64,"Plugin name must be at most 64 characters").regex(/^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]{1,2}$/,{message:"Plugin name must be lowercase letters, numbers, and hyphens only, starting and ending with alphanumeric"}),Jw=q0.string().regex(/^\d+\.\d+\.\d+(-[\w.]+)?(\+[\w.]+)?$/,{message:"Version must be a valid semantic version (e.g., 1.0.0)"}),Gw=q0.object({name:q0.string().min(1,"Author name is required"),email:q0.string().email().optional(),url:q0.string().url().optional()}),fK=q0.object({name:Xw,description:q0.string().min(1,"Description is required").max(500,"Description must be at most 500 characters"),version:Jw,author:Gw.optional(),license:q0.string().optional(),repository:q0.string().url().optional(),homepage:q0.string().url().optional(),keywords:q0.array(q0.string()).optional(),dependencies:q0.record(q0.string()).optional(),bladeVersion:q0.string().optional()}),SK=q0.object({type:q0.enum(["stdio","sse","http"]),command:q0.string().optional(),args:q0.array(q0.string()).optional(),env:q0.record(q0.string()).optional(),url:q0.string().url().optional(),headers:q0.record(q0.string()).optional(),timeout:q0.number().positive().optional(),oauth:q0.object({enabled:q0.boolean().optional(),clientId:q0.string().optional(),clientSecret:q0.string().optional(),authorizationUrl:q0.string().url().optional(),tokenUrl:q0.string().url().optional(),scopes:q0.array(q0.string()).optional(),redirectUri:q0.string().url().optional()}).optional(),healthCheck:q0.object({enabled:q0.boolean().optional(),interval:q0.number().positive().optional(),timeout:q0.number().positive().optional(),failureThreshold:q0.number().positive().optional()}).optional()}),qw=q0.union([q0.object({mcpServers:q0.record(SK)}),q0.record(SK)])});import*as g7 from"node:fs/promises";import*as xK from"node:path";async function s8($){for(let{dir:Z,source:Y}of Kw){let Q=xK.join($,Z,"plugin.json");try{await g7.access(Q)}catch{continue}try{let X=await g7.readFile(Q,"utf-8"),J=JSON.parse(X),G=fK.safeParse(J);if(!G.success){let q=G.error.issues.map((K)=>`${K.path.join(".")}: ${K.message}`).join("; ");throw Error(`Invalid plugin.json: ${q}`)}return r0.debug(`Parsed plugin manifest from ${Q}`),{manifest:G.data,source:Y,manifestPath:Q}}catch(X){if(X instanceof SyntaxError)throw Error(`Invalid JSON in ${Q}: ${X.message}`);throw X}}return null}async function pK($){try{return await s8($)!==null}catch{return!1}}var Kw;var mY=b(()=>{Y0();pY();Kw=[{dir:".blade-plugin",source:"blade"},{dir:".claude-plugin",source:"claude"}]});import{execSync as mK}from"node:child_process";import*as Z1 from"node:fs/promises";import{homedir as Ww}from"node:os";import*as t8 from"node:path";class gK{userPluginsDir;constructor($){this.userPluginsDir=$||t8.join(Ww(),".blade","plugins")}async install($){try{let Z=this.parseGitUrl($);if(!Z)return{success:!1,error:`Invalid source URL: ${$}`};let Y=this.extractPluginName(Z);if(!Y)return{success:!1,error:`Could not extract plugin name from URL: ${Z}`};await Z1.mkdir(this.userPluginsDir,{recursive:!0,mode:493});let Q=t8.join(this.userPluginsDir,Y);try{return await Z1.access(Q),{success:!1,pluginName:Y,pluginPath:Q,error:`Plugin "${Y}" already exists at ${Q}. Use /plugins uninstall first.`}}catch{}r0.info(`Cloning ${Z} to ${Q}...`);try{mK(`git clone --depth 1 "${Z}" "${Q}"`,{stdio:"pipe",timeout:60000})}catch(J){return{success:!1,pluginName:Y,error:`Failed to clone repository: ${J instanceof Error?J.message:String(J)}`}}if(!await pK(Q))return await Z1.rm(Q,{recursive:!0,force:!0}),{success:!1,pluginName:Y,error:"Invalid plugin: No .blade-plugin/plugin.json or .claude-plugin/plugin.json found"};let X;try{X=await s8(Q)}catch(J){return await Z1.rm(Q,{recursive:!0,force:!0}),{success:!1,pluginName:Y,error:`Invalid plugin manifest: ${J instanceof Error?J.message:String(J)}`}}if(!X)return await Z1.rm(Q,{recursive:!0,force:!0}),{success:!1,pluginName:Y,error:"Invalid plugin manifest: No manifest found"};return r0.info(`Successfully installed plugin: ${X.manifest.name}`),{success:!0,pluginName:X.manifest.name,pluginPath:Q,manifest:X.manifest}}catch(Z){return{success:!1,error:`Installation failed: ${Z instanceof Error?Z.message:String(Z)}`}}}async uninstall($){try{let Z=t8.join(this.userPluginsDir,$);try{await Z1.access(Z)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" not found at ${Z}`}}return await Z1.rm(Z,{recursive:!0,force:!0}),r0.info(`Successfully uninstalled plugin: ${$}`),{success:!0,pluginName:$,pluginPath:Z}}catch(Z){return{success:!1,pluginName:$,error:`Uninstallation failed: ${Z instanceof Error?Z.message:String(Z)}`}}}async listInstalled(){try{return await Z1.access(this.userPluginsDir),(await Z1.readdir(this.userPluginsDir,{withFileTypes:!0})).filter((Z)=>Z.isDirectory()).map((Z)=>Z.name)}catch{return[]}}async update($){try{let Z=t8.join(this.userPluginsDir,$);try{await Z1.access(Z)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" not found at ${Z}`}}let Y=t8.join(Z,".git");try{await Z1.access(Y)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" is not a git repository`}}r0.info(`Updating plugin: ${$}...`);try{mK(`git -C "${Z}" pull --ff-only`,{stdio:"pipe",timeout:60000})}catch(X){return{success:!1,pluginName:$,error:`Failed to update: ${X instanceof Error?X.message:String(X)}`}}let Q;try{Q=await s8(Z)}catch(X){return{success:!1,pluginName:$,error:`Plugin manifest invalid after update: ${X instanceof Error?X.message:String(X)}`}}if(!Q)return{success:!1,pluginName:$,error:"Plugin manifest not found after update"};return r0.info(`Successfully updated plugin: ${Q.manifest.name}`),{success:!0,pluginName:Q.manifest.name,pluginPath:Z,manifest:Q.manifest}}catch(Z){return{success:!1,pluginName:$,error:`Update failed: ${Z instanceof Error?Z.message:String(Z)}`}}}parseGitUrl($){if($.startsWith("https://")||$.startsWith("git@"))return $;if(/^[a-zA-Z0-9_-]+\/[a-zA-Z0-9_.-]+$/.test($))return`https://github.com/${$}.git`;return null}extractPluginName($){let Z=$.match(/\/([a-zA-Z0-9_.-]+?)(?:\.git)?$/);if(Z)return Z[1];let Y=$.match(/:([a-zA-Z0-9_-]+\/)?([a-zA-Z0-9_.-]+?)(?:\.git)?$/);if(Y)return Y[2];return null}}function z6($){if(!gY)gY=new gK($);return gY}var gY=null;var uK=b(()=>{Y0();mY()});function u7($,Z){return`${$}:${Z}`}function dK($,Z){return`${$}__${Z}`}import*as w1 from"node:fs/promises";import{homedir as Uw}from"node:os";import*as w$ from"node:path";import cK from"gray-matter";class d7{async loadPlugin($,Z,Y={}){let Q=await s8($);if(!Q)throw Error(`Not a valid plugin directory: ${$}`);let{manifest:X,source:J}=Q,G=X.name;r0.debug(`Loading plugin "${G}" from ${$}`);let q=Y.skipCommands?[]:await this.loadCommands($,G),K=Y.skipAgents?[]:await this.loadAgents($,G),W=Y.skipSkills?[]:await this.loadSkills($,G),U=Y.skipHooks?void 0:await this.loadHooks($),H=Y.skipMcp?void 0:await this.loadMcpConfig($,G);return r0.debug(`Plugin "${G}" loaded: ${q.length} commands, ${K.length} agents, ${W.length} skills`),{manifest:X,basePath:$,source:Z,manifestSource:J,commands:q,agents:K,skills:W,hooks:U,mcpServers:H,status:"active",loadedAt:new Date}}async loadCommands($,Z){let Y=w$.join($,"commands"),Q=[];if(!await this.dirExists(Y))return Q;let X=await this.scanMarkdownFiles(Y);for(let J of X)try{let G=await this.parseCommandFile(J,Y,Z);if(G)Q.push(G)}catch(G){r0.warn(`Failed to load command from ${J}: ${G instanceof Error?G.message:String(G)}`)}return Q}async parseCommandFile($,Z,Y){let Q=await w1.readFile($,"utf-8"),{data:X,content:J}=cK(Q),q=w$.relative(Z,$).split(w$.sep),K=q.pop();if(!K)return null;let W=K.replace(/\.md$/i,""),U=W;if(q.length>0)U=[...q,W].join("/");let H=u7(Y,U),O=this.normalizeCommandConfig(X);return{originalName:U,namespacedName:H,pluginName:Y,config:O,content:J.trim(),path:$}}normalizeCommandConfig($){return{description:this.asString($.description),allowedTools:this.parseStringArray($["allowed-tools"]),argumentHint:this.asString($["argument-hint"]),model:this.asString($.model),disableModelInvocation:$["disable-model-invocation"]===!0}}async loadAgents($,Z){let Y=w$.join($,"agents"),Q=[];if(!await this.dirExists(Y))return Q;let X=await this.scanMarkdownFiles(Y);for(let J of X)try{let G=await this.parseAgentFile(J,Y,Z);if(G)Q.push(G)}catch(G){r0.warn(`Failed to load agent from ${J}: ${G instanceof Error?G.message:String(G)}`)}return Q}async parseAgentFile($,Z,Y){let Q=await w1.readFile($,"utf-8"),{data:X,content:J}=cK(Q),G=w$.relative(Z,$),q=w$.basename(G,".md"),K=X.name||q,W=u7(Y,K),U={name:W,description:this.asString(X.description)||"",tools:this.parseStringArray(X.tools),color:this.asString(X.color),model:this.asString(X.model),permissionMode:this.asString(X.permissionMode),skills:this.parseStringArray(X.skills),systemPrompt:J.trim(),source:`plugin:${Y}`};return{originalName:K,namespacedName:W,pluginName:Y,config:U,path:$}}async loadSkills($,Z){let Y=w$.join($,"skills"),Q=[];if(!await this.dirExists(Y))return Q;let X=await w1.readdir(Y,{withFileTypes:!0});for(let J of X){if(!J.isDirectory())continue;let G=w$.join(Y,J.name),q=w$.join(G,"SKILL.md");try{let K=await U7(q,"project");if(K.success&&K.content){let W=K.content.metadata.name,U=u7(Z,W);Q.push({originalName:W,namespacedName:U,pluginName:Z,metadata:{...K.content.metadata,name:U},path:G})}}catch(K){r0.warn(`Failed to load skill from ${q}: ${K instanceof Error?K.message:String(K)}`)}}return Q}async loadHooks($){let Z=w$.join($,"hooks","hooks.json");try{let Y=await w1.readFile(Z,"utf-8"),Q=JSON.parse(Y);return Q.hooks||Q}catch{return}}async loadMcpConfig($,Z){let Y=w$.join($,".mcp.json");try{let Q=await w1.readFile(Y,"utf-8"),X=JSON.parse(Q),J=hK(X);if(!J.success){r0.warn(`Invalid .mcp.json in ${$}: ${J.error}`);return}let G="mcpServers"in X?X.mcpServers:X,q={};for(let[K,W]of Object.entries(G)){let U=dK(Z,K);q[U]=W}return q}catch{return}}async scanMarkdownFiles($){let Z=[],Y=async(Q)=>{let X=await w1.readdir(Q,{withFileTypes:!0});for(let J of X){let G=w$.join(Q,J.name);if(J.isDirectory())await Y(G);else if(J.name.endsWith(".md"))Z.push(G)}};return await Y($),Z}async dirExists($){try{return(await w1.stat($)).isDirectory()}catch{return!1}}asString($){if(typeof $==="string"&&$.trim())return $.trim();return}parseStringArray($){if(!$)return;if(Array.isArray($))return $.map((Z)=>String(Z).trim()).filter(Boolean);if(typeof $==="string")return $.split(",").map((Z)=>Z.trim()).filter(Boolean);return}static getPluginDirs($){let Z=Uw();return[{path:w$.join(Z,".claude","plugins"),source:"user",type:"claude"},{path:w$.join(Z,".blade","plugins"),source:"user",type:"blade"},{path:w$.join($,".claude","plugins"),source:"project",type:"claude"},{path:w$.join($,".blade","plugins"),source:"project",type:"blade"}]}async discoverPluginsInDir($,Z){let Y=[],Q=[];try{await w1.access($)}catch{return{plugins:Y,errors:Q}}let X=await w1.readdir($,{withFileTypes:!0});for(let J of X){if(!J.isDirectory())continue;let G=w$.join($,J.name);try{let q=await this.loadPlugin(G,Z);Y.push(q)}catch(q){Q.push({path:G,error:q instanceof Error?q.message:String(q)})}}return{plugins:Y,errors:Q}}}var lK=b(()=>{Y0();_Z();mY();pY()});class q8{static instance=null;plugins=new Map;loader=new d7;initialized=!1;workspaceRoot="";cliPluginDirs=[];constructor(){}static getInstance(){if(!q8.instance)q8.instance=new q8;return q8.instance}static resetInstance(){q8.instance=null}async initialize($,Z=[]){this.workspaceRoot=$,this.cliPluginDirs=Z;let Y=[],Q=[];for(let J of Z)try{let G=await this.loader.loadPlugin(J,"cli");this.plugins.set(G.manifest.name,G),Y.push(G),r0.info(`Loaded CLI plugin: ${G.manifest.name} from ${J}`)}catch(G){Q.push({path:J,error:G instanceof Error?G.message:String(G)}),r0.warn(`Failed to load CLI plugin from ${J}: ${G}`)}let X=d7.getPluginDirs($);for(let{path:J,source:G}of X){let q=await this.loader.discoverPluginsInDir(J,G);for(let K of q.plugins){let W=this.plugins.get(K.manifest.name);if(!W||W.source!=="cli")this.plugins.set(K.manifest.name,K),Y.push(K)}Q.push(...q.errors)}return this.initialized=!0,r0.info(`Plugin system initialized: ${this.plugins.size} plugins loaded`+(Q.length>0?`, ${Q.length} errors`:"")),{plugins:Array.from(this.plugins.values()),errors:Q}}isInitialized(){return this.initialized}getAll(){return Array.from(this.plugins.values())}getActive(){return Array.from(this.plugins.values()).filter(($)=>$.status==="active")}get($){return this.plugins.get($)}has($){return this.plugins.has($)}getBySource(){let $={cli:[],project:[],user:[]};for(let Z of this.plugins.values())$[Z.source].push(Z);return $}getAllCommands(){let $=[];for(let Z of this.plugins.values())if(Z.status==="active")$.push(...Z.commands);return $}getAllSkills(){let $=[];for(let Z of this.plugins.values())if(Z.status==="active")$.push(...Z.skills);return $}getAllAgents(){let $=[];for(let Z of this.plugins.values())if(Z.status==="active")$.push(...Z.agents);return $}findCommand($){for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.commands)if(Q.namespacedName===$)return Q}let Z=[];for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.commands)if(Q.originalName===$)Z.push(Q)}if(Z.length===1)return Z[0];return}findSkill($){for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.skills)if(Q.namespacedName===$)return Q}let Z=[];for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.skills)if(Q.originalName===$)Z.push(Q)}if(Z.length===1)return Z[0];return}findAgent($){for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.agents)if(Q.namespacedName===$)return Q}let Z=[];for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.agents)if(Q.originalName===$)Z.push(Q)}if(Z.length===1)return Z[0];return}hasCommandConflict($){let Z=0;for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.commands)if(Q.originalName===$){if(Z++,Z>1)return!0}}return!1}getCommandProviders($){let Z=[];for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.commands)if(Q.originalName===$){Z.push(Y.manifest.name);break}}return Z}disable($){let Z=this.plugins.get($);if(Z&&Z.status==="active")return Z.status="inactive",r0.info(`Plugin "${$}" disabled`),!0;return!1}enable($){let Z=this.plugins.get($);if(Z&&Z.status==="inactive")return Z.status="active",r0.info(`Plugin "${$}" enabled`),!0;return!1}async refresh(){return r0.info("Refreshing plugin list..."),this.plugins.clear(),this.initialized=!1,this.initialize(this.workspaceRoot,this.cliPluginDirs)}getStats(){let $=0,Z=0,Y=0,Q=0,X=0;for(let J of this.plugins.values())if(J.status==="active")$++,Y+=J.commands.length,Q+=J.skills.length,X+=J.agents.length;else Z++;return{total:this.plugins.size,active:$,inactive:Z,commands:Y,skills:Q,agents:X}}formatPluginList(){if(this.getAll().length===0)return"没有已加载的插件。";let Z=[],Y=this.getBySource();if(Y.cli.length>0){Z.push("## CLI 指定的插件");for(let Q of Y.cli){let X=Q.status==="inactive"?" (禁用)":"";Z.push(`- **${Q.manifest.name}** v${Q.manifest.version}${X}`),Z.push(` ${Q.manifest.description}`)}Z.push("")}if(Y.project.length>0){Z.push("## 项目级插件");for(let Q of Y.project){let X=Q.status==="inactive"?" (禁用)":"";Z.push(`- **${Q.manifest.name}** v${Q.manifest.version}${X}`),Z.push(` ${Q.manifest.description}`)}Z.push("")}if(Y.user.length>0){Z.push("## 用户级插件");for(let Q of Y.user){let X=Q.status==="inactive"?" (禁用)":"";Z.push(`- **${Q.manifest.name}** v${Q.manifest.version}${X}`),Z.push(` ${Q.manifest.description}`)}}return Z.join(`
|
|
2224
|
+
`);return X}}var f,$w=0.1,Zw=8192,Yw=32768;var Q2=b(()=>{Y4();o9();K1();Y0();t9();e9();s1();AZ();bZ();wZ();$7();t1();I1();b0();EY();BY();NY();R$();LZ();K6();MY();z4();f=p("Agent")});import{z as q0}from"zod";function hK($){return qw.safeParse($)}var Xw,Jw,Gw,fK,SK,qw;var pY=b(()=>{Xw=q0.string().min(2,"Plugin name must be at least 2 characters").max(64,"Plugin name must be at most 64 characters").regex(/^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]{1,2}$/,{message:"Plugin name must be lowercase letters, numbers, and hyphens only, starting and ending with alphanumeric"}),Jw=q0.string().regex(/^\d+\.\d+\.\d+(-[\w.]+)?(\+[\w.]+)?$/,{message:"Version must be a valid semantic version (e.g., 1.0.0)"}),Gw=q0.object({name:q0.string().min(1,"Author name is required"),email:q0.string().email().optional(),url:q0.string().url().optional()}),fK=q0.object({name:Xw,description:q0.string().min(1,"Description is required").max(500,"Description must be at most 500 characters"),version:Jw,author:Gw.optional(),license:q0.string().optional(),repository:q0.string().url().optional(),homepage:q0.string().url().optional(),keywords:q0.array(q0.string()).optional(),dependencies:q0.record(q0.string()).optional(),bladeVersion:q0.string().optional()}),SK=q0.object({type:q0.enum(["stdio","sse","http"]),command:q0.string().optional(),args:q0.array(q0.string()).optional(),env:q0.record(q0.string()).optional(),url:q0.string().url().optional(),headers:q0.record(q0.string()).optional(),timeout:q0.number().positive().optional(),oauth:q0.object({enabled:q0.boolean().optional(),clientId:q0.string().optional(),clientSecret:q0.string().optional(),authorizationUrl:q0.string().url().optional(),tokenUrl:q0.string().url().optional(),scopes:q0.array(q0.string()).optional(),redirectUri:q0.string().url().optional()}).optional(),healthCheck:q0.object({enabled:q0.boolean().optional(),interval:q0.number().positive().optional(),timeout:q0.number().positive().optional(),failureThreshold:q0.number().positive().optional()}).optional()}),qw=q0.union([q0.object({mcpServers:q0.record(SK)}),q0.record(SK)])});import*as g7 from"node:fs/promises";import*as xK from"node:path";async function s8($){for(let{dir:Z,source:Y}of Kw){let Q=xK.join($,Z,"plugin.json");try{await g7.access(Q)}catch{continue}try{let X=await g7.readFile(Q,"utf-8"),J=JSON.parse(X),G=fK.safeParse(J);if(!G.success){let q=G.error.issues.map((K)=>`${K.path.join(".")}: ${K.message}`).join("; ");throw Error(`Invalid plugin.json: ${q}`)}return r0.debug(`Parsed plugin manifest from ${Q}`),{manifest:G.data,source:Y,manifestPath:Q}}catch(X){if(X instanceof SyntaxError)throw Error(`Invalid JSON in ${Q}: ${X.message}`);throw X}}return null}async function pK($){try{return await s8($)!==null}catch{return!1}}var Kw;var mY=b(()=>{Y0();pY();Kw=[{dir:".blade-plugin",source:"blade"},{dir:".claude-plugin",source:"claude"}]});import{execSync as mK}from"node:child_process";import*as Z1 from"node:fs/promises";import{homedir as Ww}from"node:os";import*as t8 from"node:path";class gK{userPluginsDir;constructor($){this.userPluginsDir=$||t8.join(Ww(),".blade","plugins")}async install($){try{let Z=this.parseGitUrl($);if(!Z)return{success:!1,error:`Invalid source URL: ${$}`};let Y=this.extractPluginName(Z);if(!Y)return{success:!1,error:`Could not extract plugin name from URL: ${Z}`};await Z1.mkdir(this.userPluginsDir,{recursive:!0,mode:493});let Q=t8.join(this.userPluginsDir,Y);try{return await Z1.access(Q),{success:!1,pluginName:Y,pluginPath:Q,error:`Plugin "${Y}" already exists at ${Q}. Use /plugins uninstall first.`}}catch{}r0.info(`Cloning ${Z} to ${Q}...`);try{mK(`git clone --depth 1 "${Z}" "${Q}"`,{stdio:"pipe",timeout:60000})}catch(J){return{success:!1,pluginName:Y,error:`Failed to clone repository: ${J instanceof Error?J.message:String(J)}`}}if(!await pK(Q))return await Z1.rm(Q,{recursive:!0,force:!0}),{success:!1,pluginName:Y,error:"Invalid plugin: No .blade-plugin/plugin.json or .claude-plugin/plugin.json found"};let X;try{X=await s8(Q)}catch(J){return await Z1.rm(Q,{recursive:!0,force:!0}),{success:!1,pluginName:Y,error:`Invalid plugin manifest: ${J instanceof Error?J.message:String(J)}`}}if(!X)return await Z1.rm(Q,{recursive:!0,force:!0}),{success:!1,pluginName:Y,error:"Invalid plugin manifest: No manifest found"};return r0.info(`Successfully installed plugin: ${X.manifest.name}`),{success:!0,pluginName:X.manifest.name,pluginPath:Q,manifest:X.manifest}}catch(Z){return{success:!1,error:`Installation failed: ${Z instanceof Error?Z.message:String(Z)}`}}}async uninstall($){try{let Z=t8.join(this.userPluginsDir,$);try{await Z1.access(Z)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" not found at ${Z}`}}return await Z1.rm(Z,{recursive:!0,force:!0}),r0.info(`Successfully uninstalled plugin: ${$}`),{success:!0,pluginName:$,pluginPath:Z}}catch(Z){return{success:!1,pluginName:$,error:`Uninstallation failed: ${Z instanceof Error?Z.message:String(Z)}`}}}async listInstalled(){try{return await Z1.access(this.userPluginsDir),(await Z1.readdir(this.userPluginsDir,{withFileTypes:!0})).filter((Z)=>Z.isDirectory()).map((Z)=>Z.name)}catch{return[]}}async update($){try{let Z=t8.join(this.userPluginsDir,$);try{await Z1.access(Z)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" not found at ${Z}`}}let Y=t8.join(Z,".git");try{await Z1.access(Y)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" is not a git repository`}}r0.info(`Updating plugin: ${$}...`);try{mK(`git -C "${Z}" pull --ff-only`,{stdio:"pipe",timeout:60000})}catch(X){return{success:!1,pluginName:$,error:`Failed to update: ${X instanceof Error?X.message:String(X)}`}}let Q;try{Q=await s8(Z)}catch(X){return{success:!1,pluginName:$,error:`Plugin manifest invalid after update: ${X instanceof Error?X.message:String(X)}`}}if(!Q)return{success:!1,pluginName:$,error:"Plugin manifest not found after update"};return r0.info(`Successfully updated plugin: ${Q.manifest.name}`),{success:!0,pluginName:Q.manifest.name,pluginPath:Z,manifest:Q.manifest}}catch(Z){return{success:!1,pluginName:$,error:`Update failed: ${Z instanceof Error?Z.message:String(Z)}`}}}parseGitUrl($){if($.startsWith("https://")||$.startsWith("git@"))return $;if(/^[a-zA-Z0-9_-]+\/[a-zA-Z0-9_.-]+$/.test($))return`https://github.com/${$}.git`;return null}extractPluginName($){let Z=$.match(/\/([a-zA-Z0-9_.-]+?)(?:\.git)?$/);if(Z)return Z[1];let Y=$.match(/:([a-zA-Z0-9_-]+\/)?([a-zA-Z0-9_.-]+?)(?:\.git)?$/);if(Y)return Y[2];return null}}function z6($){if(!gY)gY=new gK($);return gY}var gY=null;var uK=b(()=>{Y0();mY()});function u7($,Z){return`${$}:${Z}`}function dK($,Z){return`${$}__${Z}`}import*as w1 from"node:fs/promises";import{homedir as Uw}from"node:os";import*as w$ from"node:path";import cK from"gray-matter";class d7{async loadPlugin($,Z,Y={}){let Q=await s8($);if(!Q)throw Error(`Not a valid plugin directory: ${$}`);let{manifest:X,source:J}=Q,G=X.name;r0.debug(`Loading plugin "${G}" from ${$}`);let q=Y.skipCommands?[]:await this.loadCommands($,G),K=Y.skipAgents?[]:await this.loadAgents($,G),W=Y.skipSkills?[]:await this.loadSkills($,G),U=Y.skipHooks?void 0:await this.loadHooks($),H=Y.skipMcp?void 0:await this.loadMcpConfig($,G);return r0.debug(`Plugin "${G}" loaded: ${q.length} commands, ${K.length} agents, ${W.length} skills`),{manifest:X,basePath:$,source:Z,manifestSource:J,commands:q,agents:K,skills:W,hooks:U,mcpServers:H,status:"active",loadedAt:new Date}}async loadCommands($,Z){let Y=w$.join($,"commands"),Q=[];if(!await this.dirExists(Y))return Q;let X=await this.scanMarkdownFiles(Y);for(let J of X)try{let G=await this.parseCommandFile(J,Y,Z);if(G)Q.push(G)}catch(G){r0.warn(`Failed to load command from ${J}: ${G instanceof Error?G.message:String(G)}`)}return Q}async parseCommandFile($,Z,Y){let Q=await w1.readFile($,"utf-8"),{data:X,content:J}=cK(Q),q=w$.relative(Z,$).split(w$.sep),K=q.pop();if(!K)return null;let W=K.replace(/\.md$/i,""),U=W;if(q.length>0)U=[...q,W].join("/");let H=u7(Y,U),O=this.normalizeCommandConfig(X);return{originalName:U,namespacedName:H,pluginName:Y,config:O,content:J.trim(),path:$}}normalizeCommandConfig($){return{description:this.asString($.description),allowedTools:this.parseStringArray($["allowed-tools"]),argumentHint:this.asString($["argument-hint"]),model:this.asString($.model),disableModelInvocation:$["disable-model-invocation"]===!0}}async loadAgents($,Z){let Y=w$.join($,"agents"),Q=[];if(!await this.dirExists(Y))return Q;let X=await this.scanMarkdownFiles(Y);for(let J of X)try{let G=await this.parseAgentFile(J,Y,Z);if(G)Q.push(G)}catch(G){r0.warn(`Failed to load agent from ${J}: ${G instanceof Error?G.message:String(G)}`)}return Q}async parseAgentFile($,Z,Y){let Q=await w1.readFile($,"utf-8"),{data:X,content:J}=cK(Q),G=w$.relative(Z,$),q=w$.basename(G,".md"),K=X.name||q,W=u7(Y,K),U={name:W,description:this.asString(X.description)||"",tools:this.parseStringArray(X.tools),color:this.asString(X.color),model:this.asString(X.model),permissionMode:this.asString(X.permissionMode),skills:this.parseStringArray(X.skills),systemPrompt:J.trim(),source:`plugin:${Y}`};return{originalName:K,namespacedName:W,pluginName:Y,config:U,path:$}}async loadSkills($,Z){let Y=w$.join($,"skills"),Q=[];if(!await this.dirExists(Y))return Q;let X=await w1.readdir(Y,{withFileTypes:!0});for(let J of X){if(!J.isDirectory())continue;let G=w$.join(Y,J.name),q=w$.join(G,"SKILL.md");try{let K=await U7(q,"project");if(K.success&&K.content){let W=K.content.metadata.name,U=u7(Z,W);Q.push({originalName:W,namespacedName:U,pluginName:Z,metadata:{...K.content.metadata,name:U},path:G})}}catch(K){r0.warn(`Failed to load skill from ${q}: ${K instanceof Error?K.message:String(K)}`)}}return Q}async loadHooks($){let Z=w$.join($,"hooks","hooks.json");try{let Y=await w1.readFile(Z,"utf-8"),Q=JSON.parse(Y);return Q.hooks||Q}catch{return}}async loadMcpConfig($,Z){let Y=w$.join($,".mcp.json");try{let Q=await w1.readFile(Y,"utf-8"),X=JSON.parse(Q),J=hK(X);if(!J.success){r0.warn(`Invalid .mcp.json in ${$}: ${J.error}`);return}let G="mcpServers"in X?X.mcpServers:X,q={};for(let[K,W]of Object.entries(G)){let U=dK(Z,K);q[U]=W}return q}catch{return}}async scanMarkdownFiles($){let Z=[],Y=async(Q)=>{let X=await w1.readdir(Q,{withFileTypes:!0});for(let J of X){let G=w$.join(Q,J.name);if(J.isDirectory())await Y(G);else if(J.name.endsWith(".md"))Z.push(G)}};return await Y($),Z}async dirExists($){try{return(await w1.stat($)).isDirectory()}catch{return!1}}asString($){if(typeof $==="string"&&$.trim())return $.trim();return}parseStringArray($){if(!$)return;if(Array.isArray($))return $.map((Z)=>String(Z).trim()).filter(Boolean);if(typeof $==="string")return $.split(",").map((Z)=>Z.trim()).filter(Boolean);return}static getPluginDirs($){let Z=Uw();return[{path:w$.join(Z,".claude","plugins"),source:"user",type:"claude"},{path:w$.join(Z,".blade","plugins"),source:"user",type:"blade"},{path:w$.join($,".claude","plugins"),source:"project",type:"claude"},{path:w$.join($,".blade","plugins"),source:"project",type:"blade"}]}async discoverPluginsInDir($,Z){let Y=[],Q=[];try{await w1.access($)}catch{return{plugins:Y,errors:Q}}let X=await w1.readdir($,{withFileTypes:!0});for(let J of X){if(!J.isDirectory())continue;let G=w$.join($,J.name);try{let q=await this.loadPlugin(G,Z);Y.push(q)}catch(q){Q.push({path:G,error:q instanceof Error?q.message:String(q)})}}return{plugins:Y,errors:Q}}}var lK=b(()=>{Y0();_Z();mY();pY()});class q8{static instance=null;plugins=new Map;loader=new d7;initialized=!1;workspaceRoot="";cliPluginDirs=[];constructor(){}static getInstance(){if(!q8.instance)q8.instance=new q8;return q8.instance}static resetInstance(){q8.instance=null}async initialize($,Z=[]){this.workspaceRoot=$,this.cliPluginDirs=Z;let Y=[],Q=[];for(let J of Z)try{let G=await this.loader.loadPlugin(J,"cli");this.plugins.set(G.manifest.name,G),Y.push(G),r0.info(`Loaded CLI plugin: ${G.manifest.name} from ${J}`)}catch(G){Q.push({path:J,error:G instanceof Error?G.message:String(G)}),r0.warn(`Failed to load CLI plugin from ${J}: ${G}`)}let X=d7.getPluginDirs($);for(let{path:J,source:G}of X){let q=await this.loader.discoverPluginsInDir(J,G);for(let K of q.plugins){let W=this.plugins.get(K.manifest.name);if(!W||W.source!=="cli")this.plugins.set(K.manifest.name,K),Y.push(K)}Q.push(...q.errors)}return this.initialized=!0,r0.info(`Plugin system initialized: ${this.plugins.size} plugins loaded`+(Q.length>0?`, ${Q.length} errors`:"")),{plugins:Array.from(this.plugins.values()),errors:Q}}isInitialized(){return this.initialized}getAll(){return Array.from(this.plugins.values())}getActive(){return Array.from(this.plugins.values()).filter(($)=>$.status==="active")}get($){return this.plugins.get($)}has($){return this.plugins.has($)}getBySource(){let $={cli:[],project:[],user:[]};for(let Z of this.plugins.values())$[Z.source].push(Z);return $}getAllCommands(){let $=[];for(let Z of this.plugins.values())if(Z.status==="active")$.push(...Z.commands);return $}getAllSkills(){let $=[];for(let Z of this.plugins.values())if(Z.status==="active")$.push(...Z.skills);return $}getAllAgents(){let $=[];for(let Z of this.plugins.values())if(Z.status==="active")$.push(...Z.agents);return $}findCommand($){for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.commands)if(Q.namespacedName===$)return Q}let Z=[];for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.commands)if(Q.originalName===$)Z.push(Q)}if(Z.length===1)return Z[0];return}findSkill($){for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.skills)if(Q.namespacedName===$)return Q}let Z=[];for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.skills)if(Q.originalName===$)Z.push(Q)}if(Z.length===1)return Z[0];return}findAgent($){for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.agents)if(Q.namespacedName===$)return Q}let Z=[];for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.agents)if(Q.originalName===$)Z.push(Q)}if(Z.length===1)return Z[0];return}hasCommandConflict($){let Z=0;for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.commands)if(Q.originalName===$){if(Z++,Z>1)return!0}}return!1}getCommandProviders($){let Z=[];for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.commands)if(Q.originalName===$){Z.push(Y.manifest.name);break}}return Z}disable($){let Z=this.plugins.get($);if(Z&&Z.status==="active")return Z.status="inactive",r0.info(`Plugin "${$}" disabled`),!0;return!1}enable($){let Z=this.plugins.get($);if(Z&&Z.status==="inactive")return Z.status="active",r0.info(`Plugin "${$}" enabled`),!0;return!1}async refresh(){return r0.info("Refreshing plugin list..."),this.plugins.clear(),this.initialized=!1,this.initialize(this.workspaceRoot,this.cliPluginDirs)}getStats(){let $=0,Z=0,Y=0,Q=0,X=0;for(let J of this.plugins.values())if(J.status==="active")$++,Y+=J.commands.length,Q+=J.skills.length,X+=J.agents.length;else Z++;return{total:this.plugins.size,active:$,inactive:Z,commands:Y,skills:Q,agents:X}}formatPluginList(){if(this.getAll().length===0)return"没有已加载的插件。";let Z=[],Y=this.getBySource();if(Y.cli.length>0){Z.push("## CLI 指定的插件");for(let Q of Y.cli){let X=Q.status==="inactive"?" (禁用)":"";Z.push(`- **${Q.manifest.name}** v${Q.manifest.version}${X}`),Z.push(` ${Q.manifest.description}`)}Z.push("")}if(Y.project.length>0){Z.push("## 项目级插件");for(let Q of Y.project){let X=Q.status==="inactive"?" (禁用)":"";Z.push(`- **${Q.manifest.name}** v${Q.manifest.version}${X}`),Z.push(` ${Q.manifest.description}`)}Z.push("")}if(Y.user.length>0){Z.push("## 用户级插件");for(let Q of Y.user){let X=Q.status==="inactive"?" (禁用)":"";Z.push(`- **${Q.manifest.name}** v${Q.manifest.version}${X}`),Z.push(` ${Q.manifest.description}`)}}return Z.join(`
|
|
2225
2225
|
`)}}function Y1(){return q8.getInstance()}var uY=b(()=>{Y0();lK()});class dY{commandRegistry;hookManager;mcpRegistry;constructor(){this.commandRegistry=D$.getInstance(),this.hookManager=T0.getInstance(),this.mcpRegistry=k0.getInstance()}clearAllPluginResources(){this.commandRegistry.clearPluginCommands(),O$().clearPluginSkills(),a0.clearPluginAgents(),r0.debug("Cleared all plugin resources from subsystems")}async integrateAll(){let Z=Y1().getActive(),Y=[],Q=[],X=0,J=0,G=0,q=0;for(let K of Z){let W=await this.integratePlugin(K);Y.push(W),X+=W.commandsRegistered,J+=W.skillsRegistered,G+=W.agentsRegistered,q+=W.mcpServersRegistered,Q.push(...W.errors)}if(X+J+G>0)r0.info(`Plugin integration complete: ${X} commands, ${J} skills, ${G} agents, ${q} MCP servers`);return{plugins:Y,totalCommands:X,totalSkills:J,totalAgents:G,totalMcpServers:q,errors:Q}}async integratePlugin($){let Z={pluginName:$.manifest.name,commandsRegistered:0,skillsRegistered:0,agentsRegistered:0,hooksRegistered:!1,mcpServersRegistered:0,errors:[]};try{Z.commandsRegistered=this.integrateCommands($)}catch(Y){Z.errors.push(`Failed to integrate commands: ${Y instanceof Error?Y.message:String(Y)}`)}try{Z.skillsRegistered=this.integrateSkills($)}catch(Y){Z.errors.push(`Failed to integrate skills: ${Y instanceof Error?Y.message:String(Y)}`)}try{Z.agentsRegistered=this.integrateAgents($)}catch(Y){Z.errors.push(`Failed to integrate agents: ${Y instanceof Error?Y.message:String(Y)}`)}try{Z.hooksRegistered=this.integrateHooks($)}catch(Y){Z.errors.push(`Failed to integrate hooks: ${Y instanceof Error?Y.message:String(Y)}`)}try{Z.mcpServersRegistered=await this.integrateMcp($)}catch(Y){Z.errors.push(`Failed to integrate MCP servers: ${Y instanceof Error?Y.message:String(Y)}`)}return r0.debug(`Integrated plugin "${$.manifest.name}": ${Z.commandsRegistered} commands, ${Z.skillsRegistered} skills, ${Z.agentsRegistered} agents`),Z}integrateCommands($){let Z=0;for(let Y of $.commands)this.commandRegistry.registerPluginCommand(Y),Z++;return Z}integrateSkills($){let Z=O$(),Y=0;for(let Q of $.skills)Z.registerPluginSkill(Q),Y++;return Y}integrateAgents($){let Z=0;for(let Y of $.agents)a0.register({...Y.config,name:Y.namespacedName}),Z++;return Z}integrateHooks($){if(!$.hooks)return!1;let Z=this.hookManager.getConfig();return this.hookManager.loadConfig({...Z,...$.hooks}),!0}async integrateMcp($){if(!$.mcpServers)return 0;let Z=0;for(let[Y,Q]of Object.entries($.mcpServers))try{await this.mcpRegistry.registerServer(Y,Q),Z++}catch(X){r0.warn(`Failed to register MCP server "${Y}" from plugin "${$.manifest.name}": ${X instanceof Error?X.message:String(X)}`)}return Z}}async function L4(){return new dY().integrateAll()}function c7(){new dY().clearAllPluginResources()}var iK=b(()=>{z4();K1();Y0();s1();t1();QY();uY()});var e8=b(()=>{uK();iK();uY()});function x0($){if($.acp)return{sendMessage:(Z)=>$.acp.sendMessage(`• ${Z}
|
|
2226
2226
|
|
|
2227
2227
|
`),sendToolStart:$.acp.sendToolStart,sendToolResult:$.acp.sendToolResult};return{sendMessage:(Z)=>_0().addAssistantMessage(Z),sendToolStart:void 0,sendToolResult:void 0}}var v1=b(()=>{b0()});import Hw from"node:os";import rK from"node:path";var aK;var nK=b(()=>{z4();v1();aK={name:"agents",description:"Manage agent configurations",fullDescription:"Create, edit, or delete custom subagents. Subagents are specialized agents that Claude can delegate tasks to.",usage:"/agents [list|create|help]",category:"System",examples:["/agents","/agents list","/agents help"],async handler($,Z){let Y=$[0],Q=x0(Z);if(!Y)return{success:!0,message:"show_agents_manager",data:{action:"show_agents_manager"}};if(Y==="list"){let J=a0.getAllNames().map((H)=>a0.getSubagent(H)).filter((H)=>H!==void 0);if(J.length===0){let H=`\uD83D\uDCCB **Agents 管理**
|
|
@@ -2291,7 +2291,7 @@ Please continue the conversation from where we left it off without asking the us
|
|
|
2291
2291
|
• 压缩后: ${O.postTokens.toLocaleString()} tokens
|
|
2292
2292
|
|
|
2293
2293
|
\uD83D\uDCA1 由于压缩过程出现错误,已使用简单截断策略。
|
|
2294
|
-
错误信息: ${O.error}`),{success:!1,message:"compact_fallback",error:O.error,data:{compactedMessages:O.compactedMessages,boundaryMessage:O.boundaryMessage,summaryMessage:O.summaryMessage,preTokens:O.preTokens,postTokens:O.postTokens}}}catch(Q){let X=Q instanceof Error?Q.message:String(Q);return Y.sendMessage(`❌ **压缩失败**: ${X}`),{success:!1,error:X}}}var Fw,oK;var sK=b(()=>{
|
|
2294
|
+
错误信息: ${O.error}`),{success:!1,message:"compact_fallback",error:O.error,data:{compactedMessages:O.compactedMessages,boundaryMessage:O.boundaryMessage,summaryMessage:O.summaryMessage,preTokens:O.preTokens,postTokens:O.postTokens}}}catch(Q){let X=Q instanceof Error?Q.message:String(Q);return Y.sendMessage(`❌ **压缩失败**: ${X}`),{success:!1,error:X}}}var Fw,oK;var sK=b(()=>{o9();DY();Y7();b0();v1();Fw={name:"compact",description:"手动压缩当前会话的上下文",fullDescription:"压缩当前对话历史,生成详细的技术总结,保留最近的消息。压缩后的上下文可以节省 token 使用量,同时保留关键信息。",usage:"/compact",examples:["/compact"],category:"context",handler:Ow},oK=Fw});function eK($){let Z=Math.floor((Date.now()-$.getTime())/1000);if(Z<60)return`${Z}s ago`;let Y=Math.floor(Z/60);if(Y<60)return`${Y}m ago`;let Q=Math.floor(Y/60);if(Q<24)return`${Q}h ago`;return`${Math.floor(Q/24)}d ago`}async function _w($){let Z=k0.getInstance(),Y=q1();if(Object.keys(Y).length===0){$.sendMessage(`\uD83D\uDD0C **MCP 服务器状态**
|
|
2295
2295
|
|
|
2296
2296
|
⚠️ 暂无配置的 MCP 服务器
|
|
2297
2297
|
|
|
@@ -2757,21 +2757,21 @@ ${Y}
|
|
|
2757
2757
|
- \`/tasks clean\` - 清理已完成的 agent 会话`,usage:"/tasks [clean]",category:"system",examples:["/tasks","/tasks clean"],handler:VA},aW=RA});async function DA($,Z){return{success:!0,message:"show_theme_selector",data:{action:"show_theme_selector"}}}var MA,oW;var sW=b(()=>{MA={name:"theme",description:"打开交互式主题选择器",aliases:["themes","style"],usage:"/theme",examples:["/theme"],category:"ui",handler:DA},oW=MA});import jA from"fuse.js";function Y3($){return $.trim().startsWith("/")}function TA($){let Z=$.trim();if(!Z.startsWith("/"))throw Error("不是有效的 slash command");let Y=Z.slice(1).split(/\s+/),Q=Y[0]||"",X=Y.slice(1);return{command:Q,args:X}}function yA($){if(R6[$])return R6[$];for(let Z of Object.values(R6))if(Z.aliases?.includes($))return Z;return}function tW($){let Z=$.argumentHint?`/${$.name} ${$.argumentHint}`:`/${$.name}`;return{name:$.name,description:$.description,fullDescription:`[Skill] ${$.description}${$.whenToUse?`
|
|
2758
2758
|
|
|
2759
2759
|
**When to use:** ${$.whenToUse}`:""}`,usage:Z,category:"skill",examples:[Z],handler:async(Y,Q)=>{return{success:!0,message:`Invoking skill: ${$.name}`,data:{action:"invoke_skill",skillName:$.name,skillArgs:Y.join(" ")}}}}}function EA($){return O$().getUserInvocableSkills().find((Q)=>Q.name===$)}async function IA(){await S2()}async function eW($){return await D$.getInstance().initialize($)}async function Q3($,Z){try{let{command:Y,args:Q}=TA($),X=yA(Y);if(X)return await X.handler(Q,Z);let J=D$.getInstance();if(J.hasCommand(Y)){let W=J.getCommand(Y);if(W){let U=Z.workspaceRoot||process.cwd(),H=await J.executeCommand(Y,{args:Q,workspaceRoot:U,signal:Z.signal});if(H)return{success:!0,message:`执行自定义命令: /${Y}`,data:{action:"invoke_custom_command",commandName:Y,processedContent:H,config:W.config}}}}let q=Y1().findCommand(Y);if(q){let W=Z.workspaceRoot||process.cwd(),U=await J.executePluginCommand(q.namespacedName,{args:Q,workspaceRoot:W,signal:Z.signal});if(U)return{success:!0,message:`执行插件命令: /${q.namespacedName}`,data:{action:"invoke_plugin_command",commandName:q.namespacedName,pluginName:q.pluginName,processedContent:U,config:q.config}}}await IA();let K=EA(Y);if(K)return await tW(K).handler(Q,Z);return{success:!1,error:`未知命令: /${Y}
|
|
2760
|
-
使用 /help 查看可用命令`}}catch(Y){return{success:!1,error:`命令执行失败: ${Y instanceof Error?Y.message:"未知错误"}`}}}function $U(){let $=Object.values(R6),Y=D$.getInstance().getAllCommands().map((q)=>({name:q.name,description:q.config.description||q.content.slice(0,50),usage:q.config.argumentHint?`/${q.name} ${q.config.argumentHint}`:`/${q.name}`,category:"custom",handler:async()=>({success:!0})})),X=Y1().getAllCommands().map((q)=>({name:q.namespacedName,description:q.config.description||q.content.slice(0,50),usage:q.config.argumentHint?`/${q.namespacedName} ${q.config.argumentHint}`:`/${q.namespacedName}`,category:"plugin",handler:async()=>({success:!0})})),G=O$().getUserInvocableSkills().map(tW);return[...$,...Y,...X,...G]}function $
|
|
2760
|
+
使用 /help 查看可用命令`}}catch(Y){return{success:!1,error:`命令执行失败: ${Y instanceof Error?Y.message:"未知错误"}`}}}function $U(){let $=Object.values(R6),Y=D$.getInstance().getAllCommands().map((q)=>({name:q.name,description:q.config.description||q.content.slice(0,50),usage:q.config.argumentHint?`/${q.name} ${q.config.argumentHint}`:`/${q.name}`,category:"custom",handler:async()=>({success:!0})})),X=Y1().getAllCommands().map((q)=>({name:q.namespacedName,description:q.config.description||q.content.slice(0,50),usage:q.config.argumentHint?`/${q.namespacedName} ${q.config.argumentHint}`:`/${q.namespacedName}`,category:"plugin",handler:async()=>({success:!0})})),G=O$().getUserInvocableSkills().map(tW);return[...$,...Y,...X,...G]}function $5($){let Z=($.startsWith("/")?$.slice(1):$).trim(),Y=Object.values(R6).map((F)=>({name:F.name,description:F.description,aliases:F.aliases||[],label:void 0,argumentHint:void 0,isCustom:!1,isSkill:!1,isPlugin:!1})),Q=D$.getInstance(),X=Q.getAllCommands().map((F)=>({name:F.name,description:F.config.description||F.content.slice(0,50),aliases:[],label:Q.getCommandLabel(F),argumentHint:F.config.argumentHint,isCustom:!0,isSkill:!1,isPlugin:!1})),G=Y1().getAllCommands().map((F)=>({name:F.namespacedName,description:F.config.description||F.content.slice(0,50),aliases:[F.originalName],label:`(plugin: ${F.pluginName})`,argumentHint:F.config.argumentHint,isCustom:!1,isSkill:!1,isPlugin:!0})),K=O$().getUserInvocableSkills().map((F)=>({name:F.name,description:F.description,aliases:[],label:"(skill)",argumentHint:F.argumentHint,isCustom:!1,isSkill:!0,isPlugin:!1})),W=[...Y,...X,...G,...K];if(!Z)return W.map((F)=>({command:`/${F.name}`,description:F.label?`${F.description} ${F.label}`:F.description,argumentHint:F.argumentHint,matchScore:50}));return new jA(W,{keys:[{name:"name",weight:3},{name:"aliases",weight:2.5},{name:"description",weight:0.5}],threshold:0.4,includeScore:!0,ignoreLocation:!0,minMatchCharLength:1}).search(Z).map((F)=>{let _=F.score??1,z=Math.round((1-_)*100),N=F.item;return{command:`/${N.name}`,description:N.label?`${N.description} ${N.label}`:N.description,argumentHint:N.argumentHint,matchScore:z}}).filter((F)=>(F.matchScore||0)>=40)}var R6;var W8=b(()=>{e8();t1();FW();C7();VW();DW();vW();SW();hW();pW();gW();cY();dW();lW();nW();sW();R6={...OW,init:kW,theme:oW,permissions:l7,model:mW,git:bW,ide:PW,skills:cW,hooks:RW,login:fW,logout:xW,tasks:aW,plugins:uW}});import{nanoid as sM}from"nanoid";class eQ{id;cwd;connection;clientCapabilities;agent=null;runtime=null;pendingPrompt=null;messages=[];mode="default";sessionApprovals=new Set;constructor($,Z,Y,Q){this.id=$;this.cwd=Z;this.connection=Y;this.clientCapabilities=Q}async initialize(){K$.debug(`[AcpSession ${this.id}] Initializing...`),H0.initializeSession(this.connection,this.id,this.clientCapabilities,this.cwd),K$.debug(`[AcpSession ${this.id}] ACP service context initialized`),this.runtime=await V2.create({sessionId:this.id}),this.agent=await n0.createWithRuntime(this.runtime,{sessionId:this.id}),K$.debug(`[AcpSession ${this.id}] Agent created successfully`)}sendAvailableCommandsDelayed(){K$.debug(`[AcpSession ${this.id}] Scheduling available commands update (500ms delay)`),setTimeout(()=>{this.sendAvailableCommands()},500)}async handleSlashCommand($,Z){try{K$.debug(`[AcpSession ${this.id}] Executing slash command: ${$}`);let Y={cwd:this.cwd,signal:Z,acp:{sendMessage:(J)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:J}})},sendToolStart:(J,G,q)=>{let K=`tool_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,W=this.mapToolKind(q);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:K,status:"in_progress",title:`${J}`,content:[{type:"content",content:{type:"text",text:JSON.stringify(G,null,2)}}],kind:W})},sendToolResult:(J,G)=>{if(G.summary)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:G.summary}})}}},Q=await Q3($,Y),X=Q.content||Q.message;if(X)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:X}});if(Q.error)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`❌ ${Q.error}`}});return{stopReason:Q.success?"end_turn":"cancelled"}}catch(Y){return K$.error(`[AcpSession ${this.id}] Slash command error:`,Y),this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`❌ 命令执行失败: ${Y instanceof Error?Y.message:"未知错误"}`}}),{stopReason:"cancelled"}}}async sendAvailableCommands(){try{let $=$U(),Z=["model","permissions","theme","config","exit","ide"],Q=$.filter((X)=>!Z.includes(X.name)).map((X)=>{let J;if(X.usage){let G=X.usage.replace(/^\/\w+\s*/,"").trim();if(G)J=G}if(X.aliases?.length){let G=`Aliases: ${X.aliases.join(", ")}`;J=J?`${J} | ${G}`:G}return{name:X.name,description:X.description,input:J?{hint:J}:void 0}});K$.info(`[AcpSession ${this.id}] Sending available commands: ${JSON.stringify(Q.map((X)=>X.name))}`),this.sendUpdate({sessionUpdate:"available_commands_update",availableCommands:Q}),K$.info(`[AcpSession ${this.id}] Sent ${Q.length} available commands`)}catch($){K$.error(`[AcpSession ${this.id}] Failed to send available commands:`,$)}}async prompt($){H0.setCurrentSession(this.id),this.pendingPrompt?.abort();let Z=new AbortController;if(this.pendingPrompt=Z,!this.agent)throw Error("Session not initialized");try{let Y=this.resolvePrompt($.prompt);if(K$.debug(`[AcpSession ${this.id}] Received prompt: ${Y.slice(0,100)}...`),Y3(Y))return await this.handleSlashCommand(Y,Z.signal);let Q={sessionId:this.id,userId:"acp-user",workspaceRoot:this.cwd,messages:[...this.messages],signal:Z.signal,permissionMode:this.mapModeToPermissionMode(),confirmationHandler:{requestConfirmation:async(G)=>{return this.requestPermission(G)}}},X={signal:Z.signal,onContent:(G)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:G}})},onThinking:(G)=>{this.sendUpdate({sessionUpdate:"agent_thought_chunk",content:{type:"text",text:G}})},onToolStart:(G,q)=>{let K="function"in G?G.function.name:G.type,W=this.mapToolKind(q);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:G.id,status:"in_progress",title:`Executing ${K}`,content:[],kind:W})},onToolResult:async(G,q)=>{let K=[],W=q.metadata;if(W?.kind==="edit"&&typeof W.file_path==="string"&&typeof W.oldContent==="string"&&(typeof W.newContent==="string"||W.newContent===void 0))K.push({type:"diff",path:W.file_path,oldText:W.oldContent,newText:W.newContent??null});else if(q.displayContent){let O=typeof q.displayContent==="string"?q.displayContent:JSON.stringify(q.displayContent);K.push({type:"content",content:{type:"text",text:O}})}let U="function"in G?G.function.name:G.type,H=q.success?"completed":"failed";this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:G.id,status:H,content:K})},onTodoUpdate:(G)=>{this.sendPlanUpdate(G)}},J=await this.agent.chat(Y,Q,X);if(J)this.messages.push({role:"user",content:Y}),this.messages.push({role:"assistant",content:J});if(Z.signal.aborted)return{stopReason:"cancelled"};return{stopReason:"end_turn"}}catch(Y){if(Z.signal.aborted||Y instanceof Error&&Y.name==="AbortError")return{stopReason:"cancelled"};throw K$.error(`[AcpSession ${this.id}] Prompt error:`,Y),Y}finally{if(this.pendingPrompt===Z)this.pendingPrompt=null}}cancel(){if(K$.info(`[AcpSession ${this.id}] Cancel requested`),this.pendingPrompt)this.pendingPrompt.abort(),this.pendingPrompt=null,K$.info(`[AcpSession ${this.id}] Cancelled successfully`);else K$.warn(`[AcpSession ${this.id}] No pending prompt to cancel`)}async setMode($){let Z=["default","auto-edit","yolo","plan"];this.mode=Z.includes($)?$:"default",K$.info(`[AcpSession ${this.id}] Mode set to: ${this.mode}`),this.sendUpdate({sessionUpdate:"current_mode_update",currentModeId:this.mode})}mapModeToPermissionMode(){switch(this.mode){case"yolo":return"yolo";case"auto-edit":return"autoEdit";case"plan":return"plan";case"default":default:return"default"}}shouldAutoApprove($){switch(this.mode){case"yolo":return!0;case"auto-edit":return $==="readonly"||$==="write";case"plan":return $==="readonly";case"default":default:return!1}}async setModel($){if(K$.info(`[AcpSession ${this.id}] Model set to: ${$}`),this.agent)K$.warn(`[AcpSession ${this.id}] Runtime model switching not yet implemented`)}async destroy(){if(this.cancel(),this.agent)await this.agent.destroy(),this.agent=null;if(this.runtime)await this.runtime.dispose(),this.runtime=null;H0.destroySession(this.id),K$.debug(`[AcpSession ${this.id}] Destroyed`)}resolvePrompt($){let Z=[];for(let Y of $)if(Y.type==="text")Z.push(Y.text);else if(Y.type==="image")Z.push(`[Image: ${Y.mimeType}]`);else if(Y.type==="resource"){let Q=Y.resource;if("text"in Q)Z.push(`<file path="${Q.uri}">
|
|
2761
2761
|
${Q.text}
|
|
2762
2762
|
</file>`)}else if(Y.type==="resource_link")Z.push(`[Resource: ${Y.uri}]`);return Z.join(`
|
|
2763
2763
|
`)}sendUpdate($){let Z={sessionId:this.id,update:$};this.connection.sessionUpdate(Z).catch((Y)=>{K$.warn(`[AcpSession ${this.id}] Failed to send update:`,Y)})}sendPlanUpdate($){let Z=$.map((Y)=>({content:Y.content,priority:Y.priority,status:Y.status}));K$.debug(`[AcpSession ${this.id}] Sending plan update with ${Z.length} entries`),this.sendUpdate({sessionUpdate:"plan",entries:Z})}async requestPermission($){let Z=$.kind?.toLowerCase()||"execute";if(this.shouldAutoApprove(Z))return K$.debug(`[AcpSession ${this.id}] Auto-approving ${Z} in mode: ${this.mode}`),{approved:!0};if(this.mode==="plan"&&(Z==="write"||Z==="execute"))return K$.debug(`[AcpSession ${this.id}] Rejecting ${Z} in plan mode`),{approved:!1,reason:"Write and execute operations are not allowed in Plan mode"};let Y=`${Z}:${$.title||"unknown"}`;if(this.sessionApprovals.has(Y))return K$.debug(`[AcpSession ${this.id}] Using cached approval for: ${Y}`),{approved:!0};try{let Q=sM(),X=[];if($.message)X.push({type:"content",content:{type:"text",text:$.message}});if($.risks&&$.risks.length>0)X.push({type:"content",content:{type:"text",text:`Risks:
|
|
2764
2764
|
- ${$.risks.join(`
|
|
2765
|
-
- `)}`}});let J=this.mapToolKind(Z),G={sessionId:this.id,options:[{optionId:"allow_once",name:"Allow once",kind:"allow_once"},{optionId:"allow_always",name:"Always allow",kind:"allow_always"},{optionId:"reject_once",name:"Deny once",kind:"reject_once"},{optionId:"reject_always",name:"Always deny",kind:"reject_always"}],toolCall:{toolCallId:Q,status:"pending",title:$.title||"Permission Required",content:X,kind:J}},K=(await this.connection.requestPermission(G)).outcome;if(K.outcome==="cancelled")return{approved:!1,reason:"User cancelled the permission request"};let W=K.optionId,U=W==="allow_once"||W==="allow_always";if(W==="allow_always")this.sessionApprovals.add(Y),K$.debug(`[AcpSession ${this.id}] Cached approval for: ${Y}`);return{approved:U,reason:U?void 0:"User denied the operation"}}catch(Q){return K$.warn(`[AcpSession ${this.id}] Permission request failed:`,Q),{approved:!1,reason:"Permission request failed"}}}mapToolKind($){return{readonly:"read",write:"edit",execute:"execute",read:"read",edit:"edit",delete:"delete",move:"move",search:"search",think:"think",fetch:"fetch"}[$||""]||"other"}}var K$;var vF=b(()=>{Q2();H6();H$();Y0();W8();g8();K$=p("Agent")});import{PROTOCOL_VERSION as tM}from"@agentclientprotocol/sdk";import{nanoid as eM}from"nanoid";class $X{connection;sessions=new Map;clientCapabilities;constructor($){this.connection=$}async initialize($){return T2.info("[BladeAgent] Initializing ACP connection"),T2.debug(`[BladeAgent] Client capabilities: ${JSON.stringify($.clientCapabilities)}`),this.clientCapabilities=$.clientCapabilities,{protocolVersion:tM,agentCapabilities:{loadSession:!1,promptCapabilities:{image:!0,audio:!1,embeddedContext:!0},mcpCapabilities:{http:!0,sse:!0}}}}async authenticate($){return}async newSession($){let Z=eM();T2.info(`[BladeAgent] Creating new session: ${Z}`),T2.debug(`[BladeAgent] Session cwd: ${$.cwd||process.cwd()}`);let Y=new eQ(Z,$.cwd||process.cwd(),this.connection,this.clientCapabilities);await Y.initialize(),this.sessions.set(Z,Y),T2.info(`[BladeAgent] Session ${Z} created, scheduling available commands update`),Y.sendAvailableCommandsDelayed();let Q=f0(),X=Q?.models||[],J=Q?.currentModelId||X[0]?.id,G=X.map((K)=>({modelId:K.id,name:K.name||K.id,description:K.provider?`Provider: ${K.provider}`:void 0}));return{sessionId:Z,modes:{availableModes:[{id:"default",name:"Default",description:"Ask for confirmation before all file edits and commands"},{id:"auto-edit",name:"Auto Edit",description:"Auto-approve file edits, ask for shell commands"},{id:"yolo",name:"Full Auto",description:"Auto-approve everything without confirmation"},{id:"plan",name:"Plan Only",description:"Read-only mode, no file changes or commands"}],currentModeId:"default"},models:G.length>0?{availableModels:G,currentModelId:J}:void 0}}async prompt($){let Z=this.sessions.get($.sessionId);if(!Z)throw Error(`Session not found: ${$.sessionId}`);return Z.prompt($)}async cancel($){T2.info(`[BladeAgent] Cancel notification received for session: ${$.sessionId}`);let Z=this.sessions.get($.sessionId);if(Z)T2.info("[BladeAgent] Found session, calling session.cancel()"),Z.cancel();else T2.warn(`[BladeAgent] Session not found for cancel: ${$.sessionId}`)}async setSessionMode($){T2.info(`[BladeAgent] Setting session mode: ${$.modeId}`);let Z=this.sessions.get($.sessionId);if(Z)await Z.setMode($.modeId);return{}}async unstable_setSessionModel($){T2.info(`[BladeAgent] Setting session model: ${$.modelId}`);let Z=this.sessions.get($.sessionId);if(Z)await Z.setModel($.modelId);return{}}async destroy(){for(let $ of this.sessions.values())await $.destroy();this.sessions.clear(),await k0.getInstance().disconnectAll()}}var T2;var CF=b(()=>{Y0();s1();b0();vF();T2=p("Agent")});var kF={};
|
|
2765
|
+
- `)}`}});let J=this.mapToolKind(Z),G={sessionId:this.id,options:[{optionId:"allow_once",name:"Allow once",kind:"allow_once"},{optionId:"allow_always",name:"Always allow",kind:"allow_always"},{optionId:"reject_once",name:"Deny once",kind:"reject_once"},{optionId:"reject_always",name:"Always deny",kind:"reject_always"}],toolCall:{toolCallId:Q,status:"pending",title:$.title||"Permission Required",content:X,kind:J}},K=(await this.connection.requestPermission(G)).outcome;if(K.outcome==="cancelled")return{approved:!1,reason:"User cancelled the permission request"};let W=K.optionId,U=W==="allow_once"||W==="allow_always";if(W==="allow_always")this.sessionApprovals.add(Y),K$.debug(`[AcpSession ${this.id}] Cached approval for: ${Y}`);return{approved:U,reason:U?void 0:"User denied the operation"}}catch(Q){return K$.warn(`[AcpSession ${this.id}] Permission request failed:`,Q),{approved:!1,reason:"Permission request failed"}}}mapToolKind($){return{readonly:"read",write:"edit",execute:"execute",read:"read",edit:"edit",delete:"delete",move:"move",search:"search",think:"think",fetch:"fetch"}[$||""]||"other"}}var K$;var vF=b(()=>{Q2();H6();H$();Y0();W8();g8();K$=p("Agent")});import{PROTOCOL_VERSION as tM}from"@agentclientprotocol/sdk";import{nanoid as eM}from"nanoid";class $X{connection;sessions=new Map;clientCapabilities;constructor($){this.connection=$}async initialize($){return T2.info("[BladeAgent] Initializing ACP connection"),T2.debug(`[BladeAgent] Client capabilities: ${JSON.stringify($.clientCapabilities)}`),this.clientCapabilities=$.clientCapabilities,{protocolVersion:tM,agentCapabilities:{loadSession:!1,promptCapabilities:{image:!0,audio:!1,embeddedContext:!0},mcpCapabilities:{http:!0,sse:!0}}}}async authenticate($){return}async newSession($){let Z=eM();T2.info(`[BladeAgent] Creating new session: ${Z}`),T2.debug(`[BladeAgent] Session cwd: ${$.cwd||process.cwd()}`);let Y=new eQ(Z,$.cwd||process.cwd(),this.connection,this.clientCapabilities);await Y.initialize(),this.sessions.set(Z,Y),T2.info(`[BladeAgent] Session ${Z} created, scheduling available commands update`),Y.sendAvailableCommandsDelayed();let Q=f0(),X=Q?.models||[],J=Q?.currentModelId||X[0]?.id,G=X.map((K)=>({modelId:K.id,name:K.name||K.id,description:K.provider?`Provider: ${K.provider}`:void 0}));return{sessionId:Z,modes:{availableModes:[{id:"default",name:"Default",description:"Ask for confirmation before all file edits and commands"},{id:"auto-edit",name:"Auto Edit",description:"Auto-approve file edits, ask for shell commands"},{id:"yolo",name:"Full Auto",description:"Auto-approve everything without confirmation"},{id:"plan",name:"Plan Only",description:"Read-only mode, no file changes or commands"}],currentModeId:"default"},models:G.length>0?{availableModels:G,currentModelId:J}:void 0}}async prompt($){let Z=this.sessions.get($.sessionId);if(!Z)throw Error(`Session not found: ${$.sessionId}`);return Z.prompt($)}async cancel($){T2.info(`[BladeAgent] Cancel notification received for session: ${$.sessionId}`);let Z=this.sessions.get($.sessionId);if(Z)T2.info("[BladeAgent] Found session, calling session.cancel()"),Z.cancel();else T2.warn(`[BladeAgent] Session not found for cancel: ${$.sessionId}`)}async setSessionMode($){T2.info(`[BladeAgent] Setting session mode: ${$.modeId}`);let Z=this.sessions.get($.sessionId);if(Z)await Z.setMode($.modeId);return{}}async unstable_setSessionModel($){T2.info(`[BladeAgent] Setting session model: ${$.modelId}`);let Z=this.sessions.get($.sessionId);if(Z)await Z.setModel($.modelId);return{}}async destroy(){for(let $ of this.sessions.values())await $.destroy();this.sessions.clear(),await k0.getInstance().disconnectAll()}}var T2;var CF=b(()=>{Y0();s1();b0();vF();T2=p("Agent")});var kF={};s5(kF,{runAcpIntegration:()=>Yj});import{Readable as $j,Writable as Zj}from"node:stream";import*as o5 from"@agentclientprotocol/sdk";async function Yj(){let $=Zj.toWeb(process.stdout),Z=$j.toWeb(process.stdin),Y=o5.ndJsonStream($,Z);await new o5.AgentSideConnection((X)=>new $X(X),Y).closed}var SF=b(()=>{CF()});e5();R9();import{render as Qj}from"ink";import Xj from"react";import Jj from"yargs";import{hideBin as hF}from"yargs/helpers";Y4();var nX={command:"doctor",describe:"Check the health of your Blade installation",handler:async()=>{console.log(`\uD83D\uDD0D Running Blade health check...
|
|
2766
2766
|
`);let $=0;try{await f$.getInstance().initialize(),console.log("✅ Configuration: OK")}catch(Q){console.log("❌ Configuration: FAILED"),console.log(` Error: ${Q instanceof Error?Q.message:"未知错误"}`),$++}let Z=process.version;if(parseInt(Z.slice(1).split(".")[0])>=18)console.log(`✅ Node.js version: ${Z}`);else console.log(`⚠️ Node.js version: ${Z} (recommended: v18+)`),$++;try{let Q=await import("fs/promises"),X=process.cwd();await Q.access(X,(await import("fs")).constants.R_OK|(await import("fs")).constants.W_OK),console.log("✅ File system permissions: OK")}catch(Q){console.log("❌ File system permissions: FAILED"),console.log(" Error: Cannot read/write in current directory"),$++}try{await import("ink"),console.log("✅ Dependencies: OK")}catch(Q){console.log("❌ Dependencies: FAILED"),console.log(" Error: Missing required dependencies"),$++}if(console.log(`
|
|
2767
|
-
\uD83D\uDCCA Health Check Summary:`),$===0)console.log("\uD83C\uDF89 All checks passed! Blade is ready to use.");else console.log(`⚠️ Found ${$} issue(s). Please resolve them for optimal performance.`),process.exit(1)}};Q2();H$();import{z as m$}from"zod";e8();W8();async function
|
|
2767
|
+
\uD83D\uDCCA Health Check Summary:`),$===0)console.log("\uD83C\uDF89 All checks passed! Blade is ready to use.");else console.log(`⚠️ Found ${$} issue(s). Please resolve them for optimal performance.`),process.exit(1)}};Q2();H$();import{z as m$}from"zod";e8();W8();async function Z5(){if((await Y1().initialize(process.cwd(),[])).plugins.length>0)await L4()}async function Y5($){let Z=$.message||$._?.[0];if(typeof Z==="string"&&Z.trim())return Z;let Y=$.stdin??process.stdin;if(!Y.isTTY){let Q=[];for await(let X of Y)Q.push(X);return Buffer.concat(Q).toString("utf-8").trim()}if($.defaultMessage!==void 0)return $.defaultMessage;throw Error("No input provided")}async function Q5($){if(!Y3($))return{mode:"agent",content:$};let Z=await Q3($,{cwd:process.cwd(),workspaceRoot:process.cwd()});if(!Z.success)return{mode:"output",content:`Error: ${Z.error||"未知错误"}`,exitCode:1};let Y=Z.data;if(Y?.action==="invoke_skill"){let{skillName:Q,skillArgs:X}=Y;return{mode:"agent",content:X?`Please use the "${Q}" skill to help me with: ${X}`:`Please use the "${Q}" skill.`}}if(Y?.action==="invoke_custom_command"||Y?.action==="invoke_plugin_command"){let Q=Y.processedContent;return{mode:"agent",content:`# Custom Command: /${Y.commandName}
|
|
2768
2768
|
|
|
2769
2769
|
${Q}`}}return{mode:"output",content:Z.message||"",exitCode:0}}kY();import{z as L0}from"zod";var ZU=1,F1=L0.object({event_version:L0.literal(ZU)}),PA=F1.extend({type:L0.literal("content_delta"),delta:L0.string()}),vA=F1.extend({type:L0.literal("thinking_delta"),delta:L0.string()}),CA=F1.extend({type:L0.literal("thinking"),content:L0.string()}),kA=F1.extend({type:L0.literal("stream_end")}),SA=F1.extend({type:L0.literal("content"),content:L0.string()}),fA=F1.extend({type:L0.literal("tool_start"),tool_name:L0.string(),summary:L0.string()}),hA=F1.extend({type:L0.literal("tool_result"),tool_name:L0.string(),summary:L0.string()}),xA=F1.extend({type:L0.literal("tool_detail"),tool_name:L0.string(),detail:L0.string()}),pA=F1.extend({type:L0.literal("todo_update"),todos:L0.array(m7)}),mA=F1.extend({type:L0.literal("token_usage"),input_tokens:L0.number(),output_tokens:L0.number(),total_tokens:L0.number(),max_context_tokens:L0.number()}),gA=F1.extend({type:L0.literal("compacting"),state:L0.enum(["started","completed"])}),uA=F1.extend({type:L0.literal("turn_limit"),turns_count:L0.number(),action:L0.literal("continue")}),dA=F1.extend({type:L0.literal("output"),content:L0.string(),exit_code:L0.number()}),cA=F1.extend({type:L0.literal("error"),message:L0.string()}),Du=L0.discriminatedUnion("type",[PA,vA,CA,kA,SA,fA,hA,xA,pA,mA,gA,uA,dA,cA]);function YU($,Z){return{event_version:ZU,type:$,...Z}}t7();var lA=m$.enum(["text","jsonl"]),iA=m$.object({headless:m$.boolean().optional(),message:m$.string().optional(),_:m$.array(m$.union([m$.string(),m$.number()])).optional(),model:m$.string().optional(),systemPrompt:m$.string().optional(),appendSystemPrompt:m$.string().optional(),maxTurns:m$.number().int().refine(($)=>$===-1||$>0,{message:"must be -1 or a positive integer"}).optional(),permissionMode:m$.nativeEnum(u0).optional(),mcpConfig:m$.array(m$.string()).optional(),strictMcpConfig:m$.boolean().optional(),sessionId:m$.string().optional(),outputFormat:lA.optional()});class XU{openedThinking=!1;wroteAssistantContent=!1;markAssistantContent(){this.wroteAssistantContent=!0}setThinkingOpened($){this.openedThinking=$}hasOpenThinking(){return this.openedThinking}completeStream(){let $={openedThinking:this.openedThinking,wroteAssistantContent:this.wroteAssistantContent};return this.openedThinking=!1,this.wroteAssistantContent=!1,$}}function rA($){return $.issues.map((Z)=>`${Z.path.join(".")||"options"}: ${Z.message}`).join("; ")}function aA($){let Z=iA.safeParse($);if(!Z.success)throw Error(`Invalid headless options: ${rA(Z.error)}`);return Z.data}function nA($){return $.command("* [message]","Run full agent loop without Ink UI and print events to the terminal",(Z)=>Z.positional("message",{describe:"Message to process",type:"string"}).option("headless",{type:"boolean",describe:"Run full agent loop without Ink UI and print events to the terminal"}).option("model",{describe:"Model ID for this run",type:"string"}).option("system-prompt",{describe:"Replace the default system prompt",type:"string"}).option("append-system-prompt",{describe:"Append a system prompt to the default system prompt",type:"string"}).option("max-turns",{alias:["maxTurns"],describe:"Maximum conversation turns (-1: unlimited, N>0: limit to N turns)",type:"number"}).option("output-format",{alias:["outputFormat"],choices:["text","jsonl"],describe:"Headless output format",type:"string"}),async(Z)=>{if(!Z.headless)return;let Y=await $b(Z);process.exit(Y)})}function X2($,Z=""){$.write(`${Z}
|
|
2770
2770
|
`)}function oA($){return`[todo] [${$.status}] ${$.content}`}function sA(){return{requestConfirmation:async($)=>({approved:!0,reason:"headless-auto-approved",scope:"session"})}}function tA($){if(!($ instanceof Error))return"Unknown error";let Q=$.lastError??$;if(Q.responseBody)try{let G=JSON.parse(Q.responseBody)?.error?.message;if(G)return Q.statusCode?`${G} (HTTP ${Q.statusCode})`:G}catch{}let X=$.message.match(/Last error:\s*(.+)$/);if(X)return X[1];return $.message}function eA($){return $==="jsonl"?"jsonl":"text"}function QU($,Z){let Y=(Q,X)=>{$.stdout.write(`${JSON.stringify(YU(Q,X))}
|
|
2771
2771
|
`)};return{contentDelta(Q){if(Z==="jsonl"){Y("content_delta",{delta:Q});return}$.stdout.write(Q)},thinkingDelta(Q,X){if(Z==="jsonl")return Y("thinking_delta",{delta:Q}),X;if(!X)$.stderr.write("[thinking] ");return $.stderr.write(Q),!0},thinking(Q){if(Z==="jsonl"){Y("thinking",{content:Q});return}X2($.stderr,`[thinking] ${Q}`)},streamEnd(Q,X){if(Z==="jsonl"){Y("stream_end",{});return}if(X)$.stderr.write(`
|
|
2772
2772
|
`);if(Q)$.stdout.write(`
|
|
2773
|
-
`)},content(Q){if(Z==="jsonl"){Y("content",{content:Q});return}X2($.stdout,Q)},toolStart(Q,X){if(Z==="jsonl"){Y("tool_start",{tool_name:Q,summary:X});return}X2($.stderr,`[tool:start] ${X}`)},toolResult(Q,X){if(Z==="jsonl"){Y("tool_result",{tool_name:Q,summary:X});return}X2($.stderr,`[tool:result] ${X}`)},toolDetail(Q,X){if(Z==="jsonl"){Y("tool_detail",{tool_name:Q,detail:X});return}X2($.stderr,X)},todoUpdate(Q){if(Z==="jsonl"){Y("todo_update",{todos:Q});return}for(let X of Q)X2($.stderr,oA(X))},tokenUsage(Q){if(Z==="jsonl"){Y("token_usage",{input_tokens:Q.inputTokens,output_tokens:Q.outputTokens,total_tokens:Q.totalTokens,max_context_tokens:Q.maxContextTokens});return}X2($.stderr,`[tokens] in=${Q.inputTokens} out=${Q.outputTokens} total=${Q.totalTokens} / ${Q.maxContextTokens}`)},compacting(Q){if(Z==="jsonl"){Y("compacting",{state:Q?"started":"completed"});return}X2($.stderr,Q?"[context] compacting started":"[context] compacting completed")},turnLimit(Q){if(Z==="jsonl"){Y("turn_limit",{turns_count:Q,action:"continue"});return}X2($.stderr,`[turn-limit] continuing after ${Q} turns`)},output(Q,X=0){if(Z==="jsonl"){Y("output",{content:Q,exit_code:X});return}X2(X===0?$.stdout:$.stderr,Q)},error(Q){if(Z==="jsonl"){Y("error",{message:Q});return}X2($.stderr,Q)}}}async function $b($,Z={stdout:process.stdout,stderr:process.stderr}){let Y="text",Q=QU(Z,Y),X=new XU;try{let J=aA($);Y=eA(J.outputFormat),Q=QU(Z,Y),await
|
|
2774
|
-
`);return Q.error(`Error: ${tA(J)}`),1}}async function JU(){if(!process.argv.slice(2).includes("--headless"))return!1;let Y=(await import("yargs")).default,{hideBin:Q}=await import("yargs/helpers"),{globalOptions:X}=await Promise.resolve().then(() => (
|
|
2773
|
+
`)},content(Q){if(Z==="jsonl"){Y("content",{content:Q});return}X2($.stdout,Q)},toolStart(Q,X){if(Z==="jsonl"){Y("tool_start",{tool_name:Q,summary:X});return}X2($.stderr,`[tool:start] ${X}`)},toolResult(Q,X){if(Z==="jsonl"){Y("tool_result",{tool_name:Q,summary:X});return}X2($.stderr,`[tool:result] ${X}`)},toolDetail(Q,X){if(Z==="jsonl"){Y("tool_detail",{tool_name:Q,detail:X});return}X2($.stderr,X)},todoUpdate(Q){if(Z==="jsonl"){Y("todo_update",{todos:Q});return}for(let X of Q)X2($.stderr,oA(X))},tokenUsage(Q){if(Z==="jsonl"){Y("token_usage",{input_tokens:Q.inputTokens,output_tokens:Q.outputTokens,total_tokens:Q.totalTokens,max_context_tokens:Q.maxContextTokens});return}X2($.stderr,`[tokens] in=${Q.inputTokens} out=${Q.outputTokens} total=${Q.totalTokens} / ${Q.maxContextTokens}`)},compacting(Q){if(Z==="jsonl"){Y("compacting",{state:Q?"started":"completed"});return}X2($.stderr,Q?"[context] compacting started":"[context] compacting completed")},turnLimit(Q){if(Z==="jsonl"){Y("turn_limit",{turns_count:Q,action:"continue"});return}X2($.stderr,`[turn-limit] continuing after ${Q} turns`)},output(Q,X=0){if(Z==="jsonl"){Y("output",{content:Q,exit_code:X});return}X2(X===0?$.stdout:$.stderr,Q)},error(Q){if(Z==="jsonl"){Y("error",{message:Q});return}X2($.stderr,Q)}}}async function $b($,Z={stdout:process.stdout,stderr:process.stderr}){let Y="text",Q=QU(Z,Y),X=new XU;try{let J=aA($);Y=eA(J.outputFormat),Q=QU(Z,Y),await Z5();let G=await Y5(J),q=await Q5(G);if(q.mode==="output"){if(q.content)Q.output(q.content,q.exitCode??0);return q.exitCode??0}let K=J.permissionMode??"yolo",U={messages:[],userId:"cli-user",sessionId:J.sessionId??`headless-${Date.now()}`,workspaceRoot:process.cwd(),permissionMode:K,confirmationHandler:sA()},H={stream:!0,maxTurns:J.maxTurns,onContentDelta:(F)=>{X.markAssistantContent(),Q.contentDelta(F)},onThinkingDelta:(F)=>{X.setThinkingOpened(Q.thinkingDelta(F,X.hasOpenThinking()))},onThinking:(F)=>{if(!F)return;Q.thinking(F)},onStreamEnd:()=>{let F=X.completeStream();Q.streamEnd(F.wroteAssistantContent,F.openedThinking)},onContent:(F)=>{if(!F.trim())return;Q.content(F),X.markAssistantContent()},onToolStart:(F)=>{if(F.type!=="function")return;if(F.function.name==="TodoWrite")return;try{let _=JSON.parse(F.function.arguments),z=K8(F.function.name,_);Q.toolStart(F.function.name,z)}catch{Q.toolStart(F.function.name,F.function.name)}},onToolResult:async(F,_)=>{if(F.type!=="function")return;let z=_.metadata?.summary;if(z)Q.toolResult(F.function.name,z);if(o7(F.function.name,_)){let N=s7(F.function.name,_)||_.displayContent;if(N)Q.toolDetail(F.function.name,N)}},onTodoUpdate:(F)=>{Q.todoUpdate(F)},onTokenUsage:(F)=>{Q.tokenUsage(F)},onCompacting:(F)=>{Q.compacting(F)},onTurnLimitReached:async(F)=>{return Q.turnLimit(F.turnsCount),{continue:!0,reason:"headless-auto-continue"}}};return await(await n0.create({systemPrompt:J.systemPrompt,appendSystemPrompt:J.appendSystemPrompt,maxTurns:J.maxTurns,modelId:J.model,permissionMode:K,mcpConfig:J.mcpConfig,strictMcpConfig:J.strictMcpConfig})).chat(q.content,U,H),0}catch(J){if(X.hasOpenThinking()&&Y==="text")Z.stderr.write(`
|
|
2774
|
+
`);return Q.error(`Error: ${tA(J)}`),1}}async function JU(){if(!process.argv.slice(2).includes("--headless"))return!1;let Y=(await import("yargs")).default,{hideBin:Q}=await import("yargs/helpers"),{globalOptions:X}=await Promise.resolve().then(() => (e5(),WX)),{loadConfiguration:J,validateOutput:G,validatePermissions:q}=await Promise.resolve().then(() => (R9(),aX)),K=Y(Q(process.argv)).scriptName("blade").strict(!1).options(X).middleware([q,J,G]);return nA(K),await K.parse(),!0}var GU={command:"install [target]",describe:"Install Blade native build. Use [target] to specify version (stable, latest, or specific version)",builder:($)=>{return $.positional("target",{describe:"Version to install",type:"string",default:"stable",choices:["stable","latest"]}).option("force",{type:"boolean",describe:"Force reinstall",default:!1}).example([["$0 install","Install stable version"],["$0 install latest","Install latest version"],["$0 install --force","Force reinstall stable version"]])},handler:async($)=>{console.log(`\uD83D\uDCE6 Installing Blade ${$.target}...`);try{if($.force)console.log("\uD83D\uDD04 Force reinstall enabled");console.log("⬇️ Downloading..."),console.log("\uD83D\uDD27 Installing..."),console.log("✅ Installation completed successfully")}catch(Z){console.error(`❌ Installation failed: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}};s1();l4();b0();import qU from"os";import X5 from"path";function X3($){return typeof $==="string"?$:void 0}function sY($){if(!Array.isArray($))return;let Z=[];for(let Y of $)if(typeof Y==="string")Z.push(Y);else if(Y!=null)Z.push(String(Y));return Z}function Zb(){console.log(`
|
|
2775
2775
|
blade mcp
|
|
2776
2776
|
`),console.log(`管理 MCP 服务器
|
|
2777
2777
|
`),console.log("Commands:"),console.log(" blade mcp add <name> <commandOrUrl> [args...] 添加 MCP 服务器"),console.log(" blade mcp remove <name> 删除 MCP 服务器 [aliases: rm]"),console.log(" blade mcp list 列出所有 MCP 服务器并检查健康状态 [aliases: ls]"),console.log(" blade mcp get <name> 获取服务器详情"),console.log(` blade mcp add-json <name> <json> 从 JSON 字符串添加服务器
|
|
@@ -2780,21 +2780,21 @@ blade mcp
|
|
|
2780
2780
|
`),console.log(`使用 blade mcp <command> --help 查看各子命令的详细帮助
|
|
2781
2781
|
`)}function Yb($){return $.reduce((Z,Y)=>{let[Q,...X]=Y.split("=");return Z[Q]=X.join("="),Z},{})}function Qb($){return $.reduce((Z,Y)=>{let[Q,...X]=Y.split(":");return Z[Q.trim()]=X.join(":").trim(),Z},{})}var Xb={command:"add <name> [commandOrUrl] [args...]",describe:"添加 MCP 服务器",builder:($)=>{return $.positional("name",{type:"string",describe:"服务器名称",demandOption:!0}).positional("commandOrUrl",{type:"string",describe:"stdio: 命令 | http/sse: URL"}).positional("args",{type:"string",array:!0,describe:"stdio 命令参数",default:[]}).option("transport",{alias:"t",choices:["stdio","sse","http"],default:"stdio",describe:"传输类型"}).option("env",{alias:"e",type:"array",describe:"环境变量 (KEY=value)"}).option("header",{alias:"H",type:"array",describe:"HTTP 头 (Key: Value)"}).option("timeout",{type:"number",describe:"超时时间(毫秒)"}).option("global",{alias:"g",type:"boolean",default:!1,describe:"存储到全局配置(~/.blade/config.json)"}).example([["$0 mcp add github -- npx -y @modelcontextprotocol/server-github","Add stdio server (recommended)"],["$0 mcp add github npx @modelcontextprotocol/server-github -e GITHUB_TOKEN=xxx","Add stdio server with env"],['$0 mcp add api --transport http http://localhost:3000 -H "Auth: Bearer token"',"Add HTTP server"]])},handler:async($)=>{try{let{name:Z,commandOrUrl:Y,args:Q,transport:X,env:J,header:G,timeout:q}=$,K=$.global===!0,W=X3(Z),U=X3(Y),H=sY(Q)||[],O=sY(J),F=sY(G),_=typeof q==="number"?q:void 0,z=X==="stdio"||X==="sse"||X==="http"?X:"stdio",N=$["--"];if(Array.isArray(N)&&N.length>0)U=String(N[0]),H=N.slice(1).map((A)=>String(A));if(!W||!U)console.error("❌ 缺少必需参数: name 和 commandOrUrl"),console.log(`
|
|
2782
2782
|
\uD83D\uDCA1 用法:`),console.log(" blade mcp add <name> <command> [args...]"),console.log(" blade mcp add <name> -- <command> [args...]"),console.log(`
|
|
2783
|
-
示例:`),console.log(" blade mcp add github npx -y @modelcontextprotocol/server-github"),console.log(" blade mcp add github -- npx -y @modelcontextprotocol/server-github"),process.exit(1);let B={type:z};if(z==="stdio"){if(B.command=U,B.args=H,O)B.env=Yb(O)}else if(B.url=U,F)B.headers=Qb(F);if(_!==void 0)B.timeout=_;await A0().addMcpServer(W,B,{scope:K?"global":"project"});let L=K?
|
|
2783
|
+
示例:`),console.log(" blade mcp add github npx -y @modelcontextprotocol/server-github"),console.log(" blade mcp add github -- npx -y @modelcontextprotocol/server-github"),process.exit(1);let B={type:z};if(z==="stdio"){if(B.command=U,B.args=H,O)B.env=Yb(O)}else if(B.url=U,F)B.headers=Qb(F);if(_!==void 0)B.timeout=_;await A0().addMcpServer(W,B,{scope:K?"global":"project"});let L=K?X5.join(qU.homedir(),".blade","config.json"):X5.join(process.cwd(),".blade","config.json");console.log(`✅ MCP 服务器 "${W}" 已添加`),console.log(` 配置文件: ${L}`)}catch(Z){console.error(`❌ 添加失败: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}},Jb={command:"remove <name>",describe:"删除 MCP 服务器",aliases:["rm"],builder:($)=>{return $.positional("name",{type:"string",describe:"服务器名称",demandOption:!0}).option("global",{alias:"g",type:"boolean",default:!1,describe:"从全局配置删除(~/.blade/config.json)"}).example([["$0 mcp remove github","Remove the specified MCP server"]])},handler:async($)=>{try{let Z=q1(),Y=$.global===!0,Q=X3($.name);if(!Q)console.error("❌ 缺少必需参数: name"),process.exit(1);if(!Z[Q])console.error(`❌ 服务器 "${Q}" 不存在`),process.exit(1);await A0().removeMcpServer(Q,{scope:Y?"global":"project"}),console.log(`✅ MCP 服务器 "${Q}" 已删除`)}catch(Z){console.error(`❌ 删除失败: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}},Gb={command:"list",describe:"列出所有 MCP 服务器并检查健康状态",aliases:["ls"],handler:async()=>{try{let $=q1();if(console.log(""),Object.keys($).length===0){console.log("暂无配置的 MCP 服务器");return}console.log(`检查 MCP 服务器健康状态...
|
|
2784
2784
|
`);let Z=k0.getInstance(),Y=Object.entries($).map(async([X,J])=>{try{let G=Z.getServerStatus(X);if(!G)await Z.registerServer(X,J),G=Z.getServerStatus(X);else if(G.status==="disconnected")await Z.connectServer(X);return{name:X,config:J,serverInfo:G}}catch(G){return{name:X,config:J,serverInfo:null,error:G}}}),Q=await Promise.all(Y);for(let{name:X,config:J,serverInfo:G,error:q}of Q){let K=G?.status||"disconnected",W=K==="connected"?"✓":"✗",U=K==="connected"?"Connected":"Failed";if(console.log(`${X}: ${J.type==="stdio"?J.command:J.url} - ${W} ${U}`),q&&K!=="connected")console.log(` 错误: ${q instanceof Error?q.message:String(q)}`)}console.log("");for(let{name:X}of Q)try{await Z.unregisterServer(X)}catch(J){}process.exit(0)}catch($){console.error(`❌ 列表获取失败: ${$ instanceof Error?$.message:"未知错误"}`),process.exit(1)}}},qb={command:"get <name>",describe:"获取服务器详情",builder:($)=>{return $.positional("name",{type:"string",describe:"服务器名称",demandOption:!0}).example([["$0 mcp get github","Get details of the specified server"]])},handler:async($)=>{try{let Z=q1(),Y=X3($.name);if(!Y)console.error("❌ 缺少必需参数: name"),process.exit(1);let Q=Z[Y];if(!Q)console.error(`❌ 服务器 "${Y}" 不存在`),process.exit(1);console.log(`
|
|
2785
2785
|
服务器: ${Y}
|
|
2786
|
-
`),console.log(JSON.stringify(Q,null,2))}catch(Z){console.error(`❌ 获取失败: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}},Kb={command:"add-json <name> <json>",describe:"从 JSON 字符串添加服务器",builder:($)=>{return $.positional("name",{type:"string",describe:"服务器名称",demandOption:!0}).positional("json",{type:"string",describe:"JSON 配置字符串",demandOption:!0}).option("global",{alias:"g",type:"boolean",default:!1,describe:"存储到全局配置(~/.blade/config.json)"}).example([[`$0 mcp add-json my-server '{"type":"stdio","command":"npx","args":["-y","@example/server"]}'`,"Add server from JSON string"]])},handler:async($)=>{try{let Z=X3($.json),Y=X3($.name);if(!Z||!Y)throw Error("缺少必需参数: name 或 json");let Q=JSON.parse(Z),X=$.global===!0;if(!Q.type)throw Error('配置必须包含 "type" 字段');await A0().addMcpServer(Y,Q,{scope:X?"global":"project"});let J=X?X9.join(qU.homedir(),".blade","config.json"):X9.join(process.cwd(),".blade","config.json");console.log(`✅ MCP 服务器 "${Y}" 已添加`),console.log(` 配置文件: ${J}`)}catch(Z){console.error(`❌ 添加失败: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}},KU={command:"mcp",describe:"管理 MCP 服务器",builder:($)=>{return $.command(Xb).command(Jb).command(Gb).command(qb).command(Kb).demandCommand(0).help(!1).option("help",{alias:"h",type:"boolean",describe:"显示帮助信息"})},handler:($)=>{let Z=["add","remove","list","ls","get","add-json"];if(!(Array.isArray($._)?$._:[]).some((X)=>typeof X==="string"&&Z.includes(X))||$.help)Zb(),process.exit(0)}};Q2();function Wb($){return $.command("* [message]","Print response and exit (useful for pipes)",(Z)=>{return Z.positional("message",{describe:"Message to process",type:"string"}).option("p",{alias:"print",describe:"Print response and exit (useful for pipes)",type:"boolean"}).option("output-format",{describe:'Output format: "text", "json", "stream-json"',type:"string",default:"text"}).option("include-partial-messages",{describe:"Include partial message chunks as they arrive",type:"boolean"}).option("input-format",{describe:'Input format: "text", "stream-json"',type:"string",default:"text"}).option("model",{describe:"Model for the current session",type:"string"}).option("append-system-prompt",{describe:"Append a system prompt to the default system prompt",type:"string"}).option("system-prompt",{describe:"Replace the default system prompt",type:"string"}).option("max-turns",{alias:["maxTurns"],describe:"Maximum conversation turns (-1: unlimited, N>0: limit to N turns)",type:"number"})},async(Z)=>{if(!Z.print)return;try{await Z9();let Y=await Y9({message:Z.message,_:Z._,defaultMessage:"Hello"}),Q=await Q9(Y);if(Q.mode==="output"){if(Q.content)console.log(Q.content);process.exit(Q.exitCode??0)}let X=Q.content,J=await n0.create({systemPrompt:Z.systemPrompt,appendSystemPrompt:Z.appendSystemPrompt,maxTurns:Z.maxTurns}),G;if(Z.appendSystemPrompt)G=await J.chatWithSystem(Z.appendSystemPrompt,X);else G=await J.chat(X,{messages:[],userId:"cli-user",sessionId:`print-${Date.now()}`,workspaceRoot:process.cwd()});if(Z.outputFormat==="json")console.log(JSON.stringify({response:G,input:X,model:Z.model,timestamp:new Date().toISOString()},null,2));else if(Z.outputFormat==="stream-json")console.log(JSON.stringify({type:"response",content:G}));else console.log(G);process.exit(0)}catch(Y){console.error(`Error: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}})}async function WU(){if(process.argv.slice(2).findIndex((Y)=>Y==="--print"||Y==="-p")===-1)return!1;try{let Y=(await import("yargs")).default,{hideBin:Q}=await import("yargs/helpers"),X=Y(Q(process.argv)).scriptName("blade").strict(!1);return Wb(X),await X.parse(),!0}catch(Y){console.error(`Print mode error: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}import YV from"chalk";var J9={port:{type:"number",describe:"Port to listen on (0 for auto)",default:0},hostname:{type:"string",describe:"Hostname to listen on",default:"127.0.0.1"},cors:{type:"array",describe:"Additional domains to allow for CORS",default:[]}};function G9($){return{port:$.port??0,hostname:$.hostname??"127.0.0.1",cors:$.cors??[]}}import{z as q9}from"zod";class D6 extends Error{code;statusCode;constructor($,Z,Y=500){super(Z);this.code=$;this.statusCode=Y;this.name="BladeServerError"}toObject(){return{error:{code:this.code,message:this.message}}}}class J3 extends D6{constructor($,Z){super("NOT_FOUND",Z?`${$} not found: ${Z}`:`${$} not found`,404)}}class C1 extends D6{constructor($){super("BAD_REQUEST",$,400)}}var lu=q9.object({error:q9.object({code:q9.string(),message:q9.string()})});Y0();e2();import{Hono as lb}from"hono";import{cors as ib}from"hono/cors";import{existsSync as PU,readFileSync as z9}from"node:fs";import{createServer as rb}from"node:http";import{networkInterfaces as ab}from"node:os";import{dirname as nb,extname as ob,join as O8}from"node:path";import{fileURLToPath as sb}from"node:url";import{WebSocketServer as tb}from"ws";Y0();import{Hono as Ub}from"hono";import{z as G3}from"zod";b0();var tY=p("Service"),Hb=G3.object({updates:G3.record(G3.any()),options:G3.object({scope:G3.enum(["local","project","global"]).optional(),immediate:G3.boolean().optional()}).optional()}),UU=()=>{let $=new Ub;return $.get("/",async(Z)=>{try{let Y=f0();return Z.json(Y||{})}catch(Y){return tY.error("[ConfigRoutes] Failed to get config:",Y),Z.json({})}}),$.put("/",async(Z)=>{try{let Y=await Z.req.json(),Q=Hb.safeParse(Y);if(!Q.success)throw new C1("Invalid config update format");let{updates:X,options:J}=Q.data;return await A0().updateConfig(X,J),Z.json({success:!0,updates:X})}catch(Y){throw tY.error("[ConfigRoutes] Failed to update config:",Y),Y}}),$.get("/permissions",async(Z)=>{try{let Y=f0();return Z.json(Y?.permissions||{})}catch(Y){return tY.error("[ConfigRoutes] Failed to get permissions:",Y),Z.json({})}}),$};e2();import{Hono as Ob}from"hono";var HU=()=>{let $=new Ob;return $.get("/health",(Z)=>{return Z.json({healthy:!0,version:G1()})}),$.get("/info",(Z)=>{return Z.json({version:G1(),platform:process.platform,arch:process.arch,nodeVersion:process.version,cwd:process.cwd()})}),$};Y0();s1();l4();b0();import{Hono as Fb}from"hono";var M6=p("Service"),OU=()=>{let $=new Fb;return $.get("/",async(Z)=>{try{let Q=k0.getInstance().getAllServers(),X=Array.from(Q.entries()).map(([J,G])=>({id:J,name:J,status:G.status==="connected"?"connected":G.status==="connecting"?"connecting":G.lastError?"error":"offline",endpoint:G.config.command?`${G.config.command} ${(G.config.args||[]).join(" ")}`.trim():G.config.url||"Unknown",description:`MCP server: ${J}`,tools:G.tools.map((q)=>q.name),connectedAt:G.connectedAt?.toISOString(),error:G.lastError?.message}));return Z.json(X)}catch(Y){return M6.error("[McpRoutes] Failed to get MCP servers:",Y),Z.json([])}}),$.post("/:name/connect",async(Z)=>{try{let Y=Z.req.param("name");return await k0.getInstance().connectServer(Y),Z.json({success:!0})}catch(Y){return M6.error("[McpRoutes] Failed to connect MCP server:",Y),Z.json({success:!1,error:Y.message},500)}}),$.post("/:name/disconnect",async(Z)=>{try{let Y=Z.req.param("name");return await k0.getInstance().disconnectServer(Y),Z.json({success:!0})}catch(Y){return M6.error("[McpRoutes] Failed to disconnect MCP server:",Y),Z.json({success:!1,error:Y.message},500)}}),$.delete("/:name",async(Z)=>{try{let Y=Z.req.param("name");await k0.getInstance().unregisterServer(Y);let X=f0();if(X?.mcpServers){let{[Y]:J,...G}=X.mcpServers;await A0().updateConfig({mcpServers:G})}return Z.json({success:!0})}catch(Y){return M6.error("[McpRoutes] Failed to delete MCP server:",Y),Z.json({success:!1,error:Y.message},500)}}),$.post("/",async(Z)=>{try{let Y=await Z.req.json(),{name:Q,config:X}=Y;if(!Q||!X)return Z.json({success:!1,error:"Missing name or config"},400);await k0.getInstance().registerServer(Q,X);let G=f0();return await A0().updateConfig({mcpServers:{...G?.mcpServers,[Q]:X}}),Z.json({success:!0})}catch(Y){return M6.error("[McpRoutes] Failed to add MCP server:",Y),Z.json({success:!1,error:Y.message},500)}}),$};Y0();b0();import{Hono as _b}from"hono";var K9=p("Service"),FU=()=>{let $=new _b;return $.get("/",async(Z)=>{try{let Y=z2(),Q=B2();return Z.json({configured:Y,current:Q})}catch(Y){return K9.error("[ModelsRoutes] Failed to get models:",Y),Z.json({configured:[],current:null})}}),$.post("/",async(Z)=>{try{let Y=await Z.req.json(),{provider:Q,name:X,model:J,baseUrl:G,apiKey:q}=Y;if(!J)throw new C1("model is required");let K=await A0().addModel({provider:Q||"openai-compatible",name:X||J,model:J,baseUrl:G||void 0,apiKey:q||void 0});return Z.json({success:!0,model:K})}catch(Y){throw K9.error("[ModelsRoutes] Failed to add model:",Y),Y}}),$.put("/:modelId",async(Z)=>{try{let Y=Z.req.param("modelId"),Q=await Z.req.json(),{baseUrl:X,apiKey:J,model:G}=Q;return await A0().updateModel(Y,{baseUrl:X||void 0,apiKey:J||void 0,model:G||void 0}),Z.json({success:!0})}catch(Y){throw K9.error("[ModelsRoutes] Failed to update model:",Y),Y}}),$.delete("/:modelId",async(Z)=>{try{let Y=Z.req.param("modelId");return await A0().removeModel(Y),Z.json({success:!0})}catch(Y){throw K9.error("[ModelsRoutes] Failed to delete model:",Y),Y}}),$};Y0();import{Hono as Mb}from"hono";import{z as J2}from"zod";Q2();H6();H$();Y0();s1();B6();PY();import{Hono as zb}from"hono";import{streamSSE as Bb}from"hono/streaming";import{LRUCache as Nb}from"lru-cache";import{nanoid as j6}from"nanoid";import{z as i$}from"zod";var g$=p("Service"),Lb=i$.object({title:i$.string().optional(),projectPath:i$.string().optional()}),wb=i$.object({content:i$.string(),attachments:i$.array(i$.object({type:i$.enum(["file","image","url"]),path:i$.string().optional(),url:i$.string().optional(),content:i$.string().optional(),mimeType:i$.string().optional(),name:i$.string().optional()})).optional(),permissionMode:i$.enum(["default","autoEdit","plan","spec","yolo"]).optional()}),Ab=i$.object({title:i$.string().optional()}),A1=new Map,U8=new Nb({max:100,ttl:1800000,dispose:($,Z)=>{if($.status==="running"||$.status==="waiting_permission")$.abortController.abort(),g$.debug(`[SessionRoutes] Run ${Z} disposed due to cache eviction`)}}),bb=($)=>{if(!$||typeof $!=="object")return $;let Z={...$},Y=200000;if(typeof Z.oldContent==="string"&&Z.oldContent.length>Y)delete Z.oldContent;if(typeof Z.newContent==="string"&&Z.newContent.length>Y)delete Z.newContent;return Z};function Vb($){if(typeof $==="string")return $;return $.filter((Z)=>Z.type==="text").map((Z)=>Z.text).join(`
|
|
2787
|
-
`)}function Rb($,Z){let Y=(Z??[]).filter((X)=>X.type==="image"&&typeof X.content==="string").map((X)=>({type:"image_url",image_url:{url:X.content}}));if(Y.length===0)return $;let Q=[];if($.trim())Q.push({type:"text",text:$});return Q.push(...Y),Q}var _U=()=>{let $=new zb,Z=new Map;return $.get("/",async(Y)=>{try{let Q=await P$.listSessions(),X=new Set(Q.filter((H)=>H.relationType==="subagent").map((H)=>H.sessionId)),J=Array.from(A1.values()).filter((H)=>!X.has(H.id)&&H.relationType!=="subagent").map((H)=>({sessionId:H.id,projectPath:H.projectPath,title:H.title,parentId:void 0,relationType:void 0,status:void 0,agentType:void 0,model:void 0,messageCount:H.messages.length,firstMessageTime:H.createdAt.toISOString(),lastMessageTime:new Date().toISOString(),hasErrors:!1,isActive:!0})),G=new Set(J.map((H)=>H.sessionId)),q=Q.filter((H)=>!A1.has(H.sessionId)&&!G.has(H.sessionId)&&H.relationType!=="subagent"),K=new Set(G),W=q.filter((H)=>{if(K.has(H.sessionId))return!1;return K.add(H.sessionId),!0}),U=[...J,...W];return Y.json(U)}catch(Q){return g$.error("[SessionRoutes] Failed to list sessions:",Q),Y.json([])}}),$.post("/",async(Y)=>{try{let Q=await Y.req.json(),X=Lb.safeParse(Q);if(!X.success)throw new C1("Invalid request body");let{title:J,projectPath:G}=X.data,q=j6(12),K=G||Y.get("directory")||process.cwd(),W={id:q,projectPath:K,title:J||`Session ${q.slice(0,6)}`,createdAt:new Date,messages:[]};return A1.set(q,W),Y.json({sessionId:q,projectPath:K,title:W.title,parentId:void 0,relationType:void 0,status:void 0,agentType:void 0,model:void 0,messageCount:0,firstMessageTime:W.createdAt.toISOString(),lastMessageTime:W.createdAt.toISOString(),hasErrors:!1})}catch(Q){throw g$.error("[SessionRoutes] Failed to create session:",Q),Q}}),$.get("/:sessionId",async(Y)=>{let Q=Y.req.param("sessionId"),X=A1.get(Q);if(X)return Y.json({sessionId:X.id,projectPath:X.projectPath,title:X.title,messageCount:X.messages.length,firstMessageTime:X.createdAt.toISOString(),lastMessageTime:new Date().toISOString(),hasErrors:!1,isActive:!0});try{let G=(await P$.listSessions()).find((q)=>q.sessionId===Q);if(!G)throw new J3("Session",Q);return Y.json(G)}catch(J){if(J instanceof J3)throw J;throw g$.error("[SessionRoutes] Failed to get session:",J),J}}),$.patch("/:sessionId",async(Y)=>{let Q=Y.req.param("sessionId");try{let X=await Y.req.json(),J=Ab.safeParse(X);if(!J.success)throw new C1("Invalid request body");let{title:G}=J.data,q=A1.get(Q);if(q&&G)q.title=G;return Y.json({success:!0,title:G})}catch(X){throw g$.error("[SessionRoutes] Failed to update session:",X),X}}),$.delete("/:sessionId",async(Y)=>{let Q=Y.req.param("sessionId"),X=A1.get(Q);if(X?.currentRunId){let G=U8.get(X.currentRunId);if(G)G.abortController.abort(),P1.publish(Q,"run.cancelled",{runId:G.id}),U8.delete(X.currentRunId)}try{await P$.deleteSession(Q)}catch(G){g$.warn("[SessionRoutes] Failed to delete session file:",G)}A1.delete(Q);let J=Z.get(Q);if(J){if(await J.dispose(),Z.delete(Q),Z.size===0)await k0.getInstance().disconnectAll()}return Y.json({success:!0})}),$.get("/:sessionId/message",async(Y)=>{let Q=Y.req.param("sessionId");try{let X=await P$.loadSession(Q);return Y.json(X)}catch(X){return g$.error("[SessionRoutes] Failed to get messages:",X),Y.json([])}}),$.get("/:sessionId/events",async(Y)=>{let Q=Y.req.param("sessionId"),X=A1.get(Q);if(!X){let J=Y.get("directory")||process.cwd();X={id:Q,projectPath:J,title:`Session ${Q.slice(0,6)}`,createdAt:new Date,messages:[]},A1.set(Q,X)}return Bb(Y,async(J)=>{await J.writeSSE({data:JSON.stringify({type:"connected",properties:{sessionId:Q,timestamp:Date.now()}})});let q=P1.subscribe((W)=>{if(W.sessionId!==Q)return;J.writeSSE({data:JSON.stringify({type:W.type,properties:{sessionId:W.sessionId,...W.properties}})}).catch(()=>{})}),K=setInterval(()=>{if(!J.aborted)J.writeSSE({data:JSON.stringify({type:"heartbeat",properties:{timestamp:Date.now()}})}).catch(()=>{})},15000);J.onAbort(()=>{clearInterval(K),q()});while(!0)if(await new Promise((W)=>setTimeout(W,1000)),J.aborted)break})}),$.post("/:sessionId/message",async(Y)=>{let Q=Y.req.param("sessionId"),X=await Y.req.json(),J=wb.safeParse(X);if(!J.success)throw new C1("Invalid message format");let{content:G,attachments:q,permissionMode:K}=J.data,W=K||"default",U=Y.get("directory")||process.cwd(),H=Rb(G,q),O=A1.get(Q);if(!O){let N=await P$.loadSession(Q).catch(()=>[]);O={id:Q,projectPath:U,title:`Session ${Q.slice(0,6)}`,createdAt:new Date,messages:N},A1.set(Q,O)}let F=j6(12),_=new AbortController,z={id:F,sessionId:Q,status:"running",abortController:_,createdAt:new Date};return U8.set(F,z),O.currentRunId=F,Db(z,O,H,W,Z).catch((N)=>{g$.error(`[SessionRoutes] Run ${F} failed:`,N)}),Y.json({runId:F,status:"running"},202)}),$.post("/:sessionId/abort",async(Y)=>{let Q=Y.req.param("sessionId"),X=A1.get(Q);if(X?.currentRunId){let J=U8.get(X.currentRunId);if(J)J.abortController.abort(),J.status="cancelled",P1.publish(Q,"run.cancelled",{runId:J.id})}return Y.json({success:!0})}),$.get("/:sessionId/status",async(Y)=>{let Q=Y.req.param("sessionId"),X=A1.get(Q);if(!X?.currentRunId)return Y.json({sessionId:Q,status:"idle"});let J=U8.get(X.currentRunId);return Y.json({sessionId:Q,runId:X.currentRunId,status:J?.status||"idle"})}),$};async function Db($,Z,Y,Q,X){let{abortController:J,sessionId:G,id:q}=$,K=j6(12),W=j6(12),U=(H,O)=>{P1.publish(G,H,O)};try{U("message.created",{messageId:K,role:"user",content:Vb(Y)}),U("session.status",{status:"running"}),U("message.created",{messageId:W,role:"assistant",content:""});let H=X.get(G);if(!H)H=await V2.create({sessionId:G}),X.set(G,H);let O=await n0.createWithRuntime(H,{sessionId:G}),F=async(B)=>{let L=j6(12),A=300000;$.status="waiting_permission";let R=new Promise((M)=>{let T=setTimeout(()=>{g$.warn(`[SessionRoutes] Permission ${L} timed out after 300000ms`),U("permission.timeout",{requestId:L}),M({approved:!1,reason:"timeout"})},300000);$.pendingPermission={permissionId:L,resolve:(w)=>{clearTimeout(T),M(w)},details:B}});U("permission.asked",{requestId:L,toolName:B.toolName,description:B.message,args:B.args,details:B}),g$.info(`[SessionRoutes] Permission request created: ${L}, runId: ${q}`);let V=await R;return g$.info(`[SessionRoutes] Permission response received: ${L}, approved: ${V.approved}`),$.status="running",$.pendingPermission=void 0,V},_={messages:[...Z.messages],userId:"web-user",sessionId:G,workspaceRoot:Z.projectPath,signal:J.signal,permissionMode:Q,confirmationHandler:{requestConfirmation:F}},z={stream:!0,onContentDelta:async(B)=>{U("message.delta",{messageId:W,delta:B})},onThinkingDelta:async(B)=>{U("thinking.delta",{delta:B})},onStreamEnd:async()=>{U("message.complete",{messageId:W}),U("thinking.completed",{})},onToolStart:async(B,L)=>{if(B.type!=="function")return;U("tool.start",{messageId:W,toolName:B.function.name,toolCallId:B.id,arguments:B.function.arguments,toolKind:L})},onToolResult:async(B,L)=>{if(B.type!=="function")return;U("tool.result",{messageId:W,toolName:B.function.name,toolCallId:B.id,success:!L.error,summary:L.metadata?.summary,output:L.displayContent,metadata:bb(L.metadata)})},onTokenUsage:async(B)=>{U("token.usage",B)},onTodoUpdate:async(B)=>{U("todo.updated",{todos:B})}},N=await O.chat(Y,_,z);Z.messages.push({role:"user",content:Y},{role:"assistant",content:N}),$.status="completed",U("session.completed",{runId:q}),U("session.status",{status:"idle"})}catch(H){g$.error("[SessionRoutes] Agent execution error:",H),$.status="failed",U("session.error",{error:H instanceof Error?H.message:"Unknown error"}),U("session.status",{status:"error"})}}function zU($,Z,Y){g$.info(`[SessionRoutes] Looking for permission ${Z} in session ${$}`),g$.info(`[SessionRoutes] Active runs: ${U8.size}`);for(let[Q,X]of U8.entries())if(g$.info(`[SessionRoutes] Checking run ${Q}: sessionId=${X.sessionId}, pendingPermission=${X.pendingPermission?.permissionId}`),X.sessionId===$&&X.pendingPermission?.permissionId===Z)return X.pendingPermission.resolve(Y),g$.info(`[SessionRoutes] Permission ${Z} responded, runId: ${X.id}`),!0;return g$.error(`[SessionRoutes] Permission not found: ${Z}`),!1}var eY=p("Service"),jb=J2.object({approved:J2.boolean(),remember:J2.boolean().optional(),scope:J2.enum(["once","session"]).optional(),targetMode:J2.enum(["default","autoEdit","plan","spec","yolo"]).optional(),feedback:J2.string().optional(),answers:J2.record(J2.union([J2.string(),J2.array(J2.string())])).optional()}),BU=()=>{let $=new Mb;return $.post("/:permissionId",async(Z)=>{let Y=Z.req.param("permissionId"),Q=Z.req.query("sessionId");eY.info(`[PermissionRoutes] Received permission response: permissionId=${Y}, sessionId=${Q}`);try{let X=await Z.req.json(),J=jb.safeParse(X);if(!J.success)throw new C1("Invalid permission response format");let{approved:G,remember:q,scope:K,targetMode:W,feedback:U,answers:H}=J.data;if(!Q)throw new C1("sessionId query parameter is required");if(!zU(Q,Y,{approved:G,reason:U,scope:K,targetMode:W,feedback:U,answers:H}))throw new J3("Permission request",Y);return eY.info(`[PermissionRoutes] Permission ${Y} ${G?"approved":"denied"}`),Z.json({success:!0,approved:G,remember:q})}catch(X){throw eY.error("[PermissionRoutes] Failed to respond to permission:",X),X}}),$};Y0();import{Hono as Eb}from"hono";Y0();C8();var U9=p("Service"),Tb="https://models.dev/api.json",yb=3600000,W9=null,NU=async()=>{if(W9&&Date.now()-W9.timestamp<yb)return W9.data;try{U9.info("\uD83D\uDCE1 Fetching models.dev data...");let $=await fetch(Tb,{headers:{"User-Agent":"Blade-CLI/1.0"}});if(!$.ok)throw Error(`HTTP ${$.status}: ${$.statusText}`);let Z=await $.json();return W9={data:Z,timestamp:Date.now()},U9.info(`✅ Loaded ${Object.keys(Z).length} providers from models.dev`),Z}catch($){throw U9.error("❌ Failed to fetch models.dev data:",$),$}},H9=async()=>{let $=await NU(),Z=[];for(let[Y,Q]of Object.entries($)){let X=Object.keys(Q.models||{}).length;if(X===0)continue;Z.push({id:Y,name:Q.name||Y,icon:m5[Y]||m5.default,description:`${X} 个模型`,isOAuth:!1,envVars:Q.env||[],docUrl:Q.doc,defaultBaseUrl:i6[Y],bladeProvider:XJ(Y)})}return Z.sort((Y,Q)=>{let X=p5.indexOf(Y.id),J=p5.indexOf(Q.id);if(X!==-1&&J!==-1)return X-J;if(X!==-1)return-1;if(J!==-1)return 1;return Y.name.localeCompare(Q.name)})},O9=async($)=>{let Y=(await NU())[$];if(!Y?.models)return U9.warn(`⚠️ No models found for provider: ${$}`),[];return Object.values(Y.models).map((Q)=>({id:Q.id,name:Q.name||Q.id,contextWindow:Q.limit?.context,maxOutput:Q.limit?.output,inputCost:Q.cost?.input,outputCost:Q.cost?.output}))};C8();var LU=p("Service"),wU=()=>{let $=new Eb;return $.get("/",async(Z)=>{try{let Y=await H9(),Q=Object.entries(l6).map(([X,J])=>({id:X,name:X.charAt(0).toUpperCase()+X.slice(1),icon:J.icon,description:J.description,isOAuth:!0,envVars:[],bladeProvider:J.bladeProvider}));return Z.json([...Y,...Q])}catch(Y){return LU.error("[ProviderRoutes] Failed to list providers:",Y),Z.json([])}}),$.get("/:providerId/models",async(Z)=>{let Y=Z.req.param("providerId");try{let Q=await O9(Y);return Z.json(Q)}catch(Q){return LU.error("[ProviderRoutes] Failed to list models:",Q),Z.json([])}}),$};Y0();t1();FZ();import{Hono as Ib}from"hono";import*as A4 from"node:fs/promises";import{homedir as Pb}from"node:os";import*as F9 from"node:path";var H8=p("Service"),$Q=F9.join(Pb(),".blade","skills-config.json");async function AU(){try{let $=await A4.readFile($Q,"utf-8");return JSON.parse($)}catch{return{disabled:[]}}}async function vb($){await A4.mkdir(F9.dirname($Q),{recursive:!0}),await A4.writeFile($Q,JSON.stringify($,null,2))}async function Cb($,Z){let Y=await AU();if(Z)Y.disabled=Y.disabled.filter((Q)=>Q!==$);else if(!Y.disabled.includes($))Y.disabled.push($);await vb(Y)}var q3=null,kb=300000;async function Sb(){if(q3&&Date.now()-q3.timestamp<kb)return q3.data;try{let $=await fetch("https://api.github.com/repos/anthropics/skills/contents/skills",{headers:{Accept:"application/vnd.github.v3+json","User-Agent":"Blade-Skills-Catalog"}});if(!$.ok)return H8.warn(`GitHub API returned ${$.status}`),q3?.data||[];let Z=await $.json(),Y=[];for(let Q of Z){if(Q.type!=="dir")continue;let X=`Official ${Q.name} skill`;try{let J=await fetch(`https://raw.githubusercontent.com/anthropics/skills/main/skills/${Q.name}/SKILL.md`,{headers:{"User-Agent":"Blade-Skills-Catalog"}});if(J.ok){let q=(await J.text()).match(/^#[^\n]*\n+([^\n#]+)/);if(q)X=q[1].trim().slice(0,100)}}catch{}Y.push({name:Q.name,description:X,tag:"Official",author:"Anthropic"})}return q3={data:Y,timestamp:Date.now()},Y}catch($){return H8.warn("Failed to fetch skills catalog from GitHub:",$),q3?.data||[]}}var bU=()=>{let $=new Ib;return $.get("/",async(Z)=>{try{let Y=O$();await Y.initialize();let Q=Y.getAll(),X=await AU(),J=Q.map((G)=>({id:G.name,name:G.name,enabled:!X.disabled.includes(G.name),description:G.description||"",version:G.version||"1.0.0",provider:"Local",location:G.source==="builtin"?"Built-in":G.basePath,capabilities:["prompts"],allowedTools:G.allowedTools||[]}));return Z.json(J)}catch(Y){return H8.error("[SkillsRoutes] Failed to get skills:",Y),Z.json([])}}),$.post("/:name/toggle",async(Z)=>{try{let Y=Z.req.param("name"),Q=await Z.req.json();return await Cb(Y,Q.enabled),Z.json({success:!0,enabled:Q.enabled})}catch(Y){return H8.error("[SkillsRoutes] Failed to toggle skill:",Y),Z.json({success:!1,error:Y.message},500)}}),$.delete("/:name",async(Z)=>{try{let Y=Z.req.param("name"),Q=`${process.env.HOME}/.blade/skills/${Y}`;return await A4.rm(Q,{recursive:!0,force:!0}),await O$().refresh(),Z.json({success:!0})}catch(Y){return H8.error("[SkillsRoutes] Failed to uninstall skill:",Y),Z.json({success:!1,error:Y.message},500)}}),$.post("/install",async(Z)=>{try{let Y=await Z.req.json(),Q=K7(),X=O$(),J=!1;if(Y.source==="catalog"&&Y.name){if(J=await Q.installOfficialSkill(Y.name),!J)return Z.json({success:!1,error:"Failed to install skill from catalog"},500)}else if(Y.source==="repo"&&Y.url){if(J=await Q.installFromRepo(Y.url,Y.name),!J)return Z.json({success:!1,error:"Failed to install skill from repository. Make sure the repo contains a SKILL.md file."},500)}else if(Y.source==="local"&&Y.path){if(J=await Q.installFromLocal(Y.path,Y.name),!J)return Z.json({success:!1,error:"Failed to install skill from local path. Make sure the path exists and contains a SKILL.md file."},500)}else return Z.json({success:!1,error:"Invalid install parameters. Required: source with corresponding url/path/name"},400);return await X.refresh(),Z.json({success:!0})}catch(Y){return H8.error("[SkillsRoutes] Failed to install skill:",Y),Z.json({success:!1,error:Y.message},500)}}),$.get("/catalog",async(Z)=>{try{let Y=await Sb();return Z.json(Y)}catch(Y){return H8.error("[SkillsRoutes] Failed to get catalog:",Y),Z.json([])}}),$};Y0();t4();W8();Q6();import fb from"fast-glob";import{Hono as hb}from"hono";import{execSync as xb}from"node:child_process";import{readdir as pb}from"node:fs/promises";import _9 from"node:path";var T6=p("Service"),mb=($)=>{try{return xb("git rev-parse --abbrev-ref HEAD",{cwd:$,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||null}catch{return null}},gb=[...H1.map(($)=>`${$}/**`),...H1,...d8.map(($)=>`**/${$}`)],ub=new Set(["/theme","/model","/permissions","/mcp","/skills","/exit","/resume","/ide","/login","/logout"]),VU=()=>{let $=new hb;return $.get("/commands",async(Z)=>{try{let Y=Z.req.query("q")||"",Q=$9(Y).filter((X)=>!ub.has(X.command));return Z.json(Q)}catch(Y){return T6.error("[SuggestionsRoutes] Failed to get command suggestions:",Y),Z.json([])}}),$.get("/files",async(Z)=>{try{let Y=Z.req.query("q")||"",Q=Z.get("directory")||process.cwd(),X=Math.min(Number(Z.req.query("limit"))||100,1000),G=(await fb("**/*",{cwd:Q,dot:!1,followSymbolicLinks:!1,onlyFiles:!1,markDirectories:!0,unique:!0,ignore:gb})).map((W)=>W.replace(/\\/g,"/"));if(!Y)return Z.json(G.slice(0,X));let q=Y.toLowerCase(),K=G.filter((W)=>W.toLowerCase().includes(q)).slice(0,X);return Z.json(K)}catch(Y){return T6.error("[SuggestionsRoutes] Failed to get file suggestions:",Y),Z.json([])}}),$.get("/files/tree",async(Z)=>{try{let Y=Z.get("directory")||process.cwd(),Q=Z.req.query("path")||"",X=Q?_9.join(Y,Q):Y,G=(await pb(X,{withFileTypes:!0})).map((W)=>({name:W.name,path:Q?`${Q}/${W.name}`:W.name,type:W.isDirectory()?"dir":"file"}));G.sort((W,U)=>{if(W.type!==U.type)return W.type==="dir"?-1:1;return W.name.localeCompare(U.name)});let q=new Set(H1),K=G.filter((W)=>{let U=W.name;if(U.startsWith("."))return!1;if(q.has(U))return!1;for(let H of d8)if(U.match(new RegExp(H.replace("*",".*"))))return!1;return!0});return Z.json(K)}catch(Y){return T6.error("[SuggestionsRoutes] Failed to get file tree:",Y),Z.json([])}}),$.get("/files/content",async(Z)=>{try{let Y=Z.req.query("path");if(!Y)return Z.json({error:"Missing file path"},400);let Q=Z.get("directory")||process.cwd(),X=_9.resolve(Q,Y),J=_9.relative(Q,X);if(J.startsWith("..")||_9.isAbsolute(J))return Z.json({error:"Invalid file path"},400);let G=q4(),q=await G.stat(X);if(!q?.isFile)return Z.json({error:"File not found"},404);let K=200000,W=await G.readTextFile(X),U=W.length>K;return Z.json({path:Y,content:U?W.slice(0,K):W,truncated:U,size:q.size})}catch(Y){return T6.error("[SuggestionsRoutes] Failed to get file content:",Y),Z.json({error:"Failed to read file"},500)}}),$.get("/git-info",async(Z)=>{try{let Y=Z.get("directory")||process.cwd(),Q=mb(Y);return Z.json({branch:Q})}catch(Y){return T6.error("[SuggestionsRoutes] Failed to get git info:",Y),Z.json({branch:null})}}),$};Y0();import{Hono as db}from"hono";var b4=p("Service"),K3=new Map,RU=2097152,DU=65536;function MU(){return typeof globalThis.Bun<"u"}async function cb($,Z,Y){if(MU()){let{spawn:J}=await import("bun-pty"),G=J($,Z,{name:"xterm-256color",cwd:Y.cwd,env:Y.env});return{pid:G.pid,write:(q)=>G.write(q),resize:(q,K)=>G.resize(q,K),kill:()=>G.kill(),onData:(q)=>G.onData(q),onExit:(q)=>G.onExit(q)}}let X=(await import("node-pty")).spawn($,Z,{name:"xterm-256color",cwd:Y.cwd,env:Y.env,cols:80,rows:24});return{pid:X.pid,write:(J)=>X.write(J),resize:(J,G)=>X.resize(J,G),kill:()=>X.kill(),onData:(J)=>{X.onData(J)},onExit:(J)=>{X.onExit(J)}}}var YQ=void 0,ZQ;if(MU())try{let{createBunWebSocket:$}=await import("hono/bun"),Z=$();ZQ=Z.upgradeWebSocket,YQ=Z.websocket}catch($){b4.warn("[Terminal] Failed to initialize Bun WebSocket support:",$)}async function jU($,Z){let Y=`term-${Date.now()}`;b4.info(`[Terminal] New connection: ${Y}, cwd: ${$}`);let Q=process.platform==="win32"?"powershell.exe":process.env.SHELL||"/bin/zsh",X=Q.endsWith("sh")?["-l"]:[],J=await cb(Q,X,{cwd:$,env:{...process.env,TERM:"xterm-256color",COLORTERM:"truecolor"}}),G={id:Y,process:J,cwd:$,buffer:"",subscribers:new Set};if(K3.set(Y,G),G.subscribers.add(Z),J.onData((q)=>{let K=!1;for(let W of G.subscribers)try{W.send(q),K=!0}catch{G.subscribers.delete(W)}if(K)return;if(G.buffer+=q,G.buffer.length>RU)G.buffer=G.buffer.slice(-RU)}),J.onExit(({exitCode:q})=>{b4.info(`[Terminal] Process exited: ${Y}, code: ${q}`);for(let K of G.subscribers)try{K.close()}catch{}K3.delete(Y)}),G.buffer){let q=G.buffer;G.buffer="";for(let K=0;K<q.length;K+=DU)Z.send(q.slice(K,K+DU))}return{session:G,cleanup:()=>{if(b4.info(`[Terminal] Connection closed: ${Y}`),G.subscribers.delete(Z),G.subscribers.size===0){try{G.process.kill()}catch{}K3.delete(Y)}}}}function TU($,Z){$.on("connection",async(Y,Q)=>{let X=new URL(Q.url||"/",`http://${Q.headers.host}`);if(!X.pathname.endsWith("/terminal/ws")){Y.close();return}let J=X.searchParams.get("cwd")||Z()||process.cwd();try{let{session:G,cleanup:q}=await jU(J,{send:(K)=>Y.send(K),close:()=>Y.close()});Y.on("message",(K)=>{try{G.process.write(String(K))}catch(W){b4.error("[Terminal] Failed to write to PTY:",W)}}),Y.on("close",q),Y.on("error",q)}catch(G){b4.error("[Terminal] Failed to spawn PTY:",G),Y.close()}})}var yU=()=>{let $=new db;if($.get("/status",(Z)=>{let Y=Array.from(K3.values()).map((Q)=>({id:Q.id,cwd:Q.cwd}));return Z.json({active:Y.length,terminals:Y})}),$.post("/kill/:terminalId",(Z)=>{let Y=Z.req.param("terminalId"),Q=K3.get(Y);if(Q){try{Q.process.kill()}catch{}for(let X of Q.subscribers)X.close();return K3.delete(Y),Z.json({success:!0})}return Z.json({success:!1,error:"Terminal not found"},404)}),ZQ)$.get("/ws",ZQ((Z)=>{let Y=Z.req.query("cwd")||Z.get("directory")||process.cwd(),Q;return{async onOpen(X,J){try{Q=await jU(Y,{send:(G)=>J.send(G),close:()=>J.close()})}catch(G){b4.error("[Terminal] Failed to spawn PTY:",G),J.close()}},onMessage(X){if(!Q)return;try{Q.session.process.write(String(X.data))}catch(J){b4.error("[Terminal] Failed to write to PTY:",J)}},onClose(){Q?.cleanup()}}}));else $.get("/ws",(Z)=>{return Z.json({message:"WebSocket endpoint - connect via ws:// protocol",hint:"Use WebSocket client to connect to this endpoint"})});return $};var b1=p("Service"),QQ=[];function eb(){let $=nb(sb(import.meta.url)),Z=[O8($,"web"),O8(process.cwd(),"dist/web"),O8(process.cwd(),"packages/cli/dist/web")];for(let Y of Z){let Q=O8(Y,"index.html");if(PU(Q)){if(z9(Q,"utf-8").includes("/assets/"))return b1.debug(`[Server] Found web dist at: ${Y}`),Y}}return null}function $V(){let $=new lb;$.onError((Y,Q)=>{if(b1.error("[Server] Request error:",Y),Y instanceof D6)return Q.json(Y.toObject(),Y.statusCode);let X=Y instanceof Error?Y.message:String(Y);return Q.json({error:{code:"INTERNAL_ERROR",message:X}},500)}),$.use(async(Y,Q)=>{let X=process.env.BLADE_SERVER_PASSWORD;if(!X)return Q();let J=Y.req.path;if(J==="/"||J.startsWith("/assets/")||J.endsWith(".html")||J.endsWith(".js")||J.endsWith(".css"))return Q();let G=Y.req.header("Authorization");if(!G?.startsWith("Basic "))return Y.header("WWW-Authenticate",'Basic realm="Blade Server"'),Y.json({error:{code:"UNAUTHORIZED",message:"Authentication required"}},401);let q=Buffer.from(G.slice(6),"base64").toString(),[K,W]=q.split(":"),U=process.env.BLADE_SERVER_USERNAME??"blade";if(K!==U||W!==X)return Y.json({error:{code:"UNAUTHORIZED",message:"Invalid credentials"}},401);return Q()}),$.use(async(Y,Q)=>{let X=Y.req.path==="/health"||Y.req.path==="/global/health"||Y.req.path.startsWith("/assets/");if(!X)b1.debug(`[Server] ${Y.req.method} ${Y.req.path}`);let J=Date.now();if(await Q(),!X){let G=Date.now()-J;b1.debug(`[Server] ${Y.req.method} ${Y.req.path} - ${Y.res.status} (${G}ms)`)}}),$.use(ib({origin(Y){if(!Y)return;if(Y.startsWith("http://localhost:"))return Y;if(Y.startsWith("http://127.0.0.1:"))return Y;if(Y==="tauri://localhost"||Y==="http://tauri.localhost")return Y;if(QQ.includes(Y))return Y;return}})),$.use(async(Y,Q)=>{let X=Y.req.query("directory")||Y.req.header("x-blade-directory")||process.cwd();try{X=decodeURIComponent(X)}catch{}return Y.set("directory",X),Q()}),$.route("/global",HU()),$.route("/sessions",_U()),$.route("/configs",UU()),$.route("/permissions",BU()),$.route("/providers",wU()),$.route("/models",FU()),$.route("/suggestions",VU()),$.route("/terminal",yU()),$.route("/mcp",OU()),$.route("/skills",bU()),$.get("/health",(Y)=>{return Y.json({healthy:!0,version:G1()})});let Z=eb();if(Z)b1.info(`[Server] Serving static files from ${Z}`),$.get("/assets/*",(Y)=>{let Q=O8(Z,Y.req.path);if(!PU(Q))return Y.json({error:{code:"NOT_FOUND",message:`File not found: ${Y.req.path}`}},404);let X=z9(Q),J=ob(Q).toLowerCase(),q={".js":"application/javascript",".css":"text/css",".html":"text/html",".json":"application/json",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".ico":"image/x-icon",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".eot":"application/vnd.ms-fontobject"}[J]||"application/octet-stream";return new Response(X,{headers:{"Content-Type":q,"Cache-Control":"public, max-age=31536000, immutable"}})}),$.get("/",(Y)=>{let Q=O8(Z,"index.html"),X=z9(Q,"utf-8");return Y.html(X)}),$.get("*",(Y)=>{let Q=Y.req.path;if(Q.includes("."))return Y.json({error:{code:"NOT_FOUND",message:`File not found: ${Q}`}},404);let X=O8(Z,"index.html"),J=z9(X,"utf-8");return Y.html(J)});else b1.warn('[Server] Web UI not found. Run "cd web && pnpm build" to enable web interface.'),$.get("/",(Y)=>{return Y.json({message:"Blade API Server",version:G1(),webUI:!1,hint:'Web UI not built. Run "cd web && pnpm build" to enable.',endpoints:{health:"/health",sessions:"/sessions",configs:"/configs",permissions:"/permissions",providers:"/providers"}})}),$.all("*",(Y)=>{return Y.json({error:{code:"NOT_FOUND",message:`Route not found: ${Y.req.path}`}},404)});return $}function y6(){let $=ab(),Z=[];for(let Y of Object.keys($)){let Q=$[Y];if(!Q)continue;for(let X of Q){if(X.internal||X.family!=="IPv4")continue;if(X.address.startsWith("172."))continue;Z.push(X.address)}}return Z}function EU(){return typeof globalThis.Bun<"u"}function IU($,Z){let Y=globalThis.Bun,Q=(J)=>{try{return Y.serve({hostname:Z.hostname,port:J,fetch:$.fetch,idleTimeout:0,websocket:YQ})}catch(G){b1.error("Failed to start Bun server:",G);return}},X=Z.port===0?Q(4096)??Q(0):Q(Z.port);if(!X)throw Error(`Failed to start Bun server on port ${Z.port}`);return{url:X.url,port:X.port,hostname:X.hostname,stop:async()=>{X.stop(!0)}}}function ZV($,Z){return new Promise((Y,Q)=>{let X=rb(async(W,U)=>{let H=new URL(W.url||"/",`http://${W.headers.host}`),O=new Headers;for(let[z,N]of Object.entries(W.headers))if(N)if(Array.isArray(N))for(let B of N)O.append(z,B);else O.set(z,N);let F;if(W.method!=="GET"&&W.method!=="HEAD")F=(await new Promise((N)=>{let B=[];W.on("data",(L)=>B.push(L)),W.on("end",()=>N(Buffer.concat(B)))})).toString();let _=new Request(H.toString(),{method:W.method,headers:O,body:F});try{let z=await $.fetch(_);if(U.statusCode=z.status,z.headers.forEach((N,B)=>{U.setHeader(B,N)}),z.body){let N=z.body.getReader(),B=async()=>{let{done:L,value:A}=await N.read();if(L){U.end();return}return U.write(A),B()};await B()}else{let N=await z.text();U.end(N)}}catch(z){b1.error("[Server] Node request error:",z),U.statusCode=500,U.end(JSON.stringify({error:{code:"INTERNAL_ERROR",message:"Internal server error"}}))}}),J=new tb({noServer:!0}),G=process.cwd();TU(J,()=>G),X.on("upgrade",(W,U,H)=>{if(new URL(W.url||"/",`http://${W.headers.host}`).pathname==="/terminal/ws")J.handleUpgrade(W,U,H,(F)=>{J.emit("connection",F,W)});else U.destroy()});let q=(W)=>{return new Promise((U,H)=>{X.once("error",(O)=>{if(O.code==="EADDRINUSE")H(O);else H(O)}),X.listen(W,Z.hostname,()=>{let O=X.address();if(O&&typeof O==="object")U(O.port);else U(W)})})};(async()=>{let W;if(Z.port===0)try{W=await q(4096)}catch{W=await q(0)}else W=await q(Z.port);let U=new URL(`http://${Z.hostname==="0.0.0.0"?"localhost":Z.hostname}:${W}`);Y({url:U,port:W,hostname:Z.hostname,stop:async()=>{return new Promise((H)=>{J.close(()=>{X.close(()=>H())})})}})})().catch(Q)})}var W3;((Tc)=>{let $,Z;function Y(){if(!Z)Z=$V();return Z}Tc.getApp=Y;function Q(G){QQ=G.cors??[];let q=Y();if(EU())$=IU(q,G),b1.info(`[Server] Blade server listening on ${$.url} (Bun runtime)`);else throw Error("Blade web server requires Bun runtime. Please run with Bun: `bun run blade web` or install Bun from https://bun.sh");let K=$;return{url:K.url,port:K.port,hostname:K.hostname,stop:async()=>{if($)await $.stop(),$=void 0,Z=void 0,b1.info("[Server] Blade server stopped")}}}Tc.listen=Q;async function X(G){QQ=G.cors??[];let q=Y();if(EU())$=IU(q,G),b1.info(`[Server] Blade server listening on ${$.url} (Bun runtime)`);else $=await ZV(q,G),b1.info(`[Server] Blade server listening on ${$.url} (Node.js runtime)`);let K=$;return{url:K.url,port:K.port,hostname:K.hostname,stop:async()=>{if($)await $.stop(),$=void 0,Z=void 0,b1.info("[Server] Blade server stopped")}}}Tc.listenAsync=X;function J(){return $!==void 0}Tc.isRunning=J})(W3||={});b0();var vU={command:"serve",describe:"Start a headless Blade server (no browser)",builder:J9,handler:async($)=>{let Z=G9($);if(await _2(),!process.env.BLADE_SERVER_PASSWORD)console.log(YV.yellow("Warning: BLADE_SERVER_PASSWORD is not set; server is unsecured."));let Y=await W3.listenAsync(Z);if(console.log(`Blade server listening on http://${Y.hostname}:${Y.port}`),Z.hostname==="0.0.0.0"){let Q=y6();for(let X of Q)console.log(` Network: http://${X}:${Y.port}`)}await new Promise(()=>{}),await Y.stop()}};import{execSync as WV}from"child_process";d4();import*as F8 from"fs/promises";import*as V4 from"path";import CU from"semver";import{fileURLToPath as QV}from"url";var XQ="blade-code",XV="https://cdn.jsdelivr.net/npm/blade-code@latest/CHANGELOG.md",kU=V4.join(process.env.HOME||process.env.USERPROFILE||".",".blade"),SU=V4.join(kU,"version-cache.json"),JV=3600000,GV=`https://registry.npmjs.org/${XQ}/latest`;async function qV(){try{if(process.env.BLADE_VERSION)return process.env.BLADE_VERSION;let $=QV(import.meta.url),Z=V4.dirname($),Y=[V4.join(Z,"..","..","package.json"),V4.join(Z,"..","package.json"),V4.join(process.cwd(),"package.json")];for(let Q of Y)try{let X=await F8.readFile(Q,"utf-8"),J=JSON.parse(X);if(J.name===XQ&&J.version)return J.version}catch{}return"unknown"}catch{return"unknown"}}async function fU(){try{let $=await F8.readFile(SU,"utf-8"),Z=JSON.parse($);if(Date.now()-Z.checkedAt<JV)return Z;return{...Z,checkedAt:0}}catch{return null}}async function hU($){try{await F8.mkdir(kU,{recursive:!0,mode:493}),await F8.writeFile(SU,JSON.stringify($,null,2))}catch{}}async function KV(){try{let $=await M$(GV,{timeout:5000,headers:{Accept:"application/json"}});if(!$.ok)return null;return(await $.json()).version||null}catch{return null}}async function JQ($=!1){let Z=await qV(),Y=XV;if(Z==="unknown")return{currentVersion:Z,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:Y,error:"Unable to determine current version"};let Q=await fU(),X=Q?.skipUntilVersion,J=null;if(!$&&Q&&Q.checkedAt>0)J=Q.latestVersion;else if(J=await KV(),J)await hU({latestVersion:J,checkedAt:Date.now(),skipUntilVersion:X});if(!J)return{currentVersion:Z,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:Y,error:"Unable to check for updates"};let G=CU.gt(J,Z),q=G;if(G&&X)q=CU.gt(J,X);return{currentVersion:Z,latestVersion:J,hasUpdate:G,shouldPrompt:q,releaseNotesUrl:Y}}async function xU($){let Z=await fU();await hU({latestVersion:Z?.latestVersion||$,checkedAt:Z?.checkedAt||Date.now(),skipUntilVersion:$})}function GQ(){return`npm install -g ${XQ}@latest --registry https://registry.npmjs.org`}async function pU(){let{spawn:$}=await import("child_process");return new Promise((Z)=>{let Y=GQ(),Q=$(Y,{stdio:"inherit",shell:!0});Q.on("close",(X)=>{if(X===0)Z({success:!0,message:"✅ 升级成功!请重新启动 blade。"});else Z({success:!1,message:`❌ 升级失败 (exit code: ${X})`})}),Q.on("error",(X)=>{Z({success:!1,message:`❌ 升级失败: ${X.message}`})})})}async function mU(){try{let $=await JQ();return $.shouldPrompt?$:null}catch{return null}}var gU={command:"update",describe:"Check for updates and install if available",handler:async()=>{console.log("\uD83D\uDD0D Checking for updates...");try{let $=await JQ(!0);if(console.log(`\uD83D\uDCE6 Current version: ${$.currentVersion}`),$.error){console.log(`⚠️ ${$.error}`);return}if($.latestVersion)console.log(`\uD83D\uDCE6 Latest version: ${$.latestVersion}`);if($.hasUpdate&&$.latestVersion){console.log(""),console.log(`\x1B[33m⚠️ Update available: ${$.currentVersion} → ${$.latestVersion}\x1B[0m`),console.log(""),console.log("\uD83D\uDE80 Updating...");try{WV("npm install -g blade-code@latest --registry https://registry.npmjs.org",{stdio:"inherit"}),console.log(""),console.log("✅ Update complete!")}catch(Z){console.error("❌ Update failed. Please run manually:"),console.error(" npm install -g blade-code@latest"),process.exit(1)}}else console.log("✅ You are running the latest version of Blade")}catch($){console.error(`❌ Failed to check for updates: ${$ instanceof Error?$.message:"未知错误"}`),process.exit(1)}}};import G2 from"chalk";import uU from"open";b0();e2();var UV=`
|
|
2786
|
+
`),console.log(JSON.stringify(Q,null,2))}catch(Z){console.error(`❌ 获取失败: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}},Kb={command:"add-json <name> <json>",describe:"从 JSON 字符串添加服务器",builder:($)=>{return $.positional("name",{type:"string",describe:"服务器名称",demandOption:!0}).positional("json",{type:"string",describe:"JSON 配置字符串",demandOption:!0}).option("global",{alias:"g",type:"boolean",default:!1,describe:"存储到全局配置(~/.blade/config.json)"}).example([[`$0 mcp add-json my-server '{"type":"stdio","command":"npx","args":["-y","@example/server"]}'`,"Add server from JSON string"]])},handler:async($)=>{try{let Z=X3($.json),Y=X3($.name);if(!Z||!Y)throw Error("缺少必需参数: name 或 json");let Q=JSON.parse(Z),X=$.global===!0;if(!Q.type)throw Error('配置必须包含 "type" 字段');await A0().addMcpServer(Y,Q,{scope:X?"global":"project"});let J=X?X5.join(qU.homedir(),".blade","config.json"):X5.join(process.cwd(),".blade","config.json");console.log(`✅ MCP 服务器 "${Y}" 已添加`),console.log(` 配置文件: ${J}`)}catch(Z){console.error(`❌ 添加失败: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}},KU={command:"mcp",describe:"管理 MCP 服务器",builder:($)=>{return $.command(Xb).command(Jb).command(Gb).command(qb).command(Kb).demandCommand(0).help(!1).option("help",{alias:"h",type:"boolean",describe:"显示帮助信息"})},handler:($)=>{let Z=["add","remove","list","ls","get","add-json"];if(!(Array.isArray($._)?$._:[]).some((X)=>typeof X==="string"&&Z.includes(X))||$.help)Zb(),process.exit(0)}};Q2();function Wb($){return $.command("* [message]","Print response and exit (useful for pipes)",(Z)=>{return Z.positional("message",{describe:"Message to process",type:"string"}).option("p",{alias:"print",describe:"Print response and exit (useful for pipes)",type:"boolean"}).option("output-format",{describe:'Output format: "text", "json", "stream-json"',type:"string",default:"text"}).option("include-partial-messages",{describe:"Include partial message chunks as they arrive",type:"boolean"}).option("input-format",{describe:'Input format: "text", "stream-json"',type:"string",default:"text"}).option("model",{describe:"Model for the current session",type:"string"}).option("append-system-prompt",{describe:"Append a system prompt to the default system prompt",type:"string"}).option("system-prompt",{describe:"Replace the default system prompt",type:"string"}).option("max-turns",{alias:["maxTurns"],describe:"Maximum conversation turns (-1: unlimited, N>0: limit to N turns)",type:"number"})},async(Z)=>{if(!Z.print)return;try{await Z5();let Y=await Y5({message:Z.message,_:Z._,defaultMessage:"Hello"}),Q=await Q5(Y);if(Q.mode==="output"){if(Q.content)console.log(Q.content);process.exit(Q.exitCode??0)}let X=Q.content,J=await n0.create({systemPrompt:Z.systemPrompt,appendSystemPrompt:Z.appendSystemPrompt,maxTurns:Z.maxTurns}),G;if(Z.appendSystemPrompt)G=await J.chatWithSystem(Z.appendSystemPrompt,X);else G=await J.chat(X,{messages:[],userId:"cli-user",sessionId:`print-${Date.now()}`,workspaceRoot:process.cwd()});if(Z.outputFormat==="json")console.log(JSON.stringify({response:G,input:X,model:Z.model,timestamp:new Date().toISOString()},null,2));else if(Z.outputFormat==="stream-json")console.log(JSON.stringify({type:"response",content:G}));else console.log(G);process.exit(0)}catch(Y){console.error(`Error: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}})}async function WU(){if(process.argv.slice(2).findIndex((Y)=>Y==="--print"||Y==="-p")===-1)return!1;try{let Y=(await import("yargs")).default,{hideBin:Q}=await import("yargs/helpers"),X=Y(Q(process.argv)).scriptName("blade").strict(!1);return Wb(X),await X.parse(),!0}catch(Y){console.error(`Print mode error: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}import YV from"chalk";var J5={port:{type:"number",describe:"Port to listen on (0 for auto)",default:0},hostname:{type:"string",describe:"Hostname to listen on",default:"127.0.0.1"},cors:{type:"array",describe:"Additional domains to allow for CORS",default:[]}};function G5($){return{port:$.port??0,hostname:$.hostname??"127.0.0.1",cors:$.cors??[]}}import{z as q5}from"zod";class D6 extends Error{code;statusCode;constructor($,Z,Y=500){super(Z);this.code=$;this.statusCode=Y;this.name="BladeServerError"}toObject(){return{error:{code:this.code,message:this.message}}}}class J3 extends D6{constructor($,Z){super("NOT_FOUND",Z?`${$} not found: ${Z}`:`${$} not found`,404)}}class C1 extends D6{constructor($){super("BAD_REQUEST",$,400)}}var lu=q5.object({error:q5.object({code:q5.string(),message:q5.string()})});Y0();e2();import{Hono as lb}from"hono";import{cors as ib}from"hono/cors";import{existsSync as PU,readFileSync as z5}from"node:fs";import{createServer as rb}from"node:http";import{networkInterfaces as ab}from"node:os";import{dirname as nb,extname as ob,join as O8}from"node:path";import{fileURLToPath as sb}from"node:url";import{WebSocketServer as tb}from"ws";Y0();import{Hono as Ub}from"hono";import{z as G3}from"zod";b0();var tY=p("Service"),Hb=G3.object({updates:G3.record(G3.any()),options:G3.object({scope:G3.enum(["local","project","global"]).optional(),immediate:G3.boolean().optional()}).optional()}),UU=()=>{let $=new Ub;return $.get("/",async(Z)=>{try{let Y=f0();return Z.json(Y||{})}catch(Y){return tY.error("[ConfigRoutes] Failed to get config:",Y),Z.json({})}}),$.put("/",async(Z)=>{try{let Y=await Z.req.json(),Q=Hb.safeParse(Y);if(!Q.success)throw new C1("Invalid config update format");let{updates:X,options:J}=Q.data;return await A0().updateConfig(X,J),Z.json({success:!0,updates:X})}catch(Y){throw tY.error("[ConfigRoutes] Failed to update config:",Y),Y}}),$.get("/permissions",async(Z)=>{try{let Y=f0();return Z.json(Y?.permissions||{})}catch(Y){return tY.error("[ConfigRoutes] Failed to get permissions:",Y),Z.json({})}}),$};e2();import{Hono as Ob}from"hono";var HU=()=>{let $=new Ob;return $.get("/health",(Z)=>{return Z.json({healthy:!0,version:G1()})}),$.get("/info",(Z)=>{return Z.json({version:G1(),platform:process.platform,arch:process.arch,nodeVersion:process.version,cwd:process.cwd()})}),$};Y0();s1();l4();b0();import{Hono as Fb}from"hono";var M6=p("Service"),OU=()=>{let $=new Fb;return $.get("/",async(Z)=>{try{let Q=k0.getInstance().getAllServers(),X=Array.from(Q.entries()).map(([J,G])=>({id:J,name:J,status:G.status==="connected"?"connected":G.status==="connecting"?"connecting":G.lastError?"error":"offline",endpoint:G.config.command?`${G.config.command} ${(G.config.args||[]).join(" ")}`.trim():G.config.url||"Unknown",description:`MCP server: ${J}`,tools:G.tools.map((q)=>q.name),connectedAt:G.connectedAt?.toISOString(),error:G.lastError?.message}));return Z.json(X)}catch(Y){return M6.error("[McpRoutes] Failed to get MCP servers:",Y),Z.json([])}}),$.post("/:name/connect",async(Z)=>{try{let Y=Z.req.param("name");return await k0.getInstance().connectServer(Y),Z.json({success:!0})}catch(Y){return M6.error("[McpRoutes] Failed to connect MCP server:",Y),Z.json({success:!1,error:Y.message},500)}}),$.post("/:name/disconnect",async(Z)=>{try{let Y=Z.req.param("name");return await k0.getInstance().disconnectServer(Y),Z.json({success:!0})}catch(Y){return M6.error("[McpRoutes] Failed to disconnect MCP server:",Y),Z.json({success:!1,error:Y.message},500)}}),$.delete("/:name",async(Z)=>{try{let Y=Z.req.param("name");await k0.getInstance().unregisterServer(Y);let X=f0();if(X?.mcpServers){let{[Y]:J,...G}=X.mcpServers;await A0().updateConfig({mcpServers:G})}return Z.json({success:!0})}catch(Y){return M6.error("[McpRoutes] Failed to delete MCP server:",Y),Z.json({success:!1,error:Y.message},500)}}),$.post("/",async(Z)=>{try{let Y=await Z.req.json(),{name:Q,config:X}=Y;if(!Q||!X)return Z.json({success:!1,error:"Missing name or config"},400);await k0.getInstance().registerServer(Q,X);let G=f0();return await A0().updateConfig({mcpServers:{...G?.mcpServers,[Q]:X}}),Z.json({success:!0})}catch(Y){return M6.error("[McpRoutes] Failed to add MCP server:",Y),Z.json({success:!1,error:Y.message},500)}}),$};Y0();b0();import{Hono as _b}from"hono";var K5=p("Service"),FU=()=>{let $=new _b;return $.get("/",async(Z)=>{try{let Y=z2(),Q=B2();return Z.json({configured:Y,current:Q})}catch(Y){return K5.error("[ModelsRoutes] Failed to get models:",Y),Z.json({configured:[],current:null})}}),$.post("/",async(Z)=>{try{let Y=await Z.req.json(),{provider:Q,name:X,model:J,baseUrl:G,apiKey:q}=Y;if(!J)throw new C1("model is required");let K=await A0().addModel({provider:Q||"openai-compatible",name:X||J,model:J,baseUrl:G||void 0,apiKey:q||void 0});return Z.json({success:!0,model:K})}catch(Y){throw K5.error("[ModelsRoutes] Failed to add model:",Y),Y}}),$.put("/:modelId",async(Z)=>{try{let Y=Z.req.param("modelId"),Q=await Z.req.json(),{baseUrl:X,apiKey:J,model:G}=Q;return await A0().updateModel(Y,{baseUrl:X||void 0,apiKey:J||void 0,model:G||void 0}),Z.json({success:!0})}catch(Y){throw K5.error("[ModelsRoutes] Failed to update model:",Y),Y}}),$.delete("/:modelId",async(Z)=>{try{let Y=Z.req.param("modelId");return await A0().removeModel(Y),Z.json({success:!0})}catch(Y){throw K5.error("[ModelsRoutes] Failed to delete model:",Y),Y}}),$};Y0();import{Hono as Mb}from"hono";import{z as J2}from"zod";Q2();H6();H$();Y0();s1();B6();PY();import{Hono as zb}from"hono";import{streamSSE as Bb}from"hono/streaming";import{LRUCache as Nb}from"lru-cache";import{nanoid as j6}from"nanoid";import{z as i$}from"zod";var g$=p("Service"),Lb=i$.object({title:i$.string().optional(),projectPath:i$.string().optional()}),wb=i$.object({content:i$.string(),attachments:i$.array(i$.object({type:i$.enum(["file","image","url"]),path:i$.string().optional(),url:i$.string().optional(),content:i$.string().optional(),mimeType:i$.string().optional(),name:i$.string().optional()})).optional(),permissionMode:i$.enum(["default","autoEdit","plan","spec","yolo"]).optional()}),Ab=i$.object({title:i$.string().optional()}),A1=new Map,U8=new Nb({max:100,ttl:1800000,dispose:($,Z)=>{if($.status==="running"||$.status==="waiting_permission")$.abortController.abort(),g$.debug(`[SessionRoutes] Run ${Z} disposed due to cache eviction`)}}),bb=($)=>{if(!$||typeof $!=="object")return $;let Z={...$},Y=200000;if(typeof Z.oldContent==="string"&&Z.oldContent.length>Y)delete Z.oldContent;if(typeof Z.newContent==="string"&&Z.newContent.length>Y)delete Z.newContent;return Z};function Vb($){if(typeof $==="string")return $;return $.filter((Z)=>Z.type==="text").map((Z)=>Z.text).join(`
|
|
2787
|
+
`)}function Rb($,Z){let Y=(Z??[]).filter((X)=>X.type==="image"&&typeof X.content==="string").map((X)=>({type:"image_url",image_url:{url:X.content}}));if(Y.length===0)return $;let Q=[];if($.trim())Q.push({type:"text",text:$});return Q.push(...Y),Q}var _U=()=>{let $=new zb,Z=new Map;return $.get("/",async(Y)=>{try{let Q=await P$.listSessions(),X=new Set(Q.filter((H)=>H.relationType==="subagent").map((H)=>H.sessionId)),J=Array.from(A1.values()).filter((H)=>!X.has(H.id)&&H.relationType!=="subagent").map((H)=>({sessionId:H.id,projectPath:H.projectPath,title:H.title,parentId:void 0,relationType:void 0,status:void 0,agentType:void 0,model:void 0,messageCount:H.messages.length,firstMessageTime:H.createdAt.toISOString(),lastMessageTime:new Date().toISOString(),hasErrors:!1,isActive:!0})),G=new Set(J.map((H)=>H.sessionId)),q=Q.filter((H)=>!A1.has(H.sessionId)&&!G.has(H.sessionId)&&H.relationType!=="subagent"),K=new Set(G),W=q.filter((H)=>{if(K.has(H.sessionId))return!1;return K.add(H.sessionId),!0}),U=[...J,...W];return Y.json(U)}catch(Q){return g$.error("[SessionRoutes] Failed to list sessions:",Q),Y.json([])}}),$.post("/",async(Y)=>{try{let Q=await Y.req.json(),X=Lb.safeParse(Q);if(!X.success)throw new C1("Invalid request body");let{title:J,projectPath:G}=X.data,q=j6(12),K=G||Y.get("directory")||process.cwd(),W={id:q,projectPath:K,title:J||`Session ${q.slice(0,6)}`,createdAt:new Date,messages:[]};return A1.set(q,W),Y.json({sessionId:q,projectPath:K,title:W.title,parentId:void 0,relationType:void 0,status:void 0,agentType:void 0,model:void 0,messageCount:0,firstMessageTime:W.createdAt.toISOString(),lastMessageTime:W.createdAt.toISOString(),hasErrors:!1})}catch(Q){throw g$.error("[SessionRoutes] Failed to create session:",Q),Q}}),$.get("/:sessionId",async(Y)=>{let Q=Y.req.param("sessionId"),X=A1.get(Q);if(X)return Y.json({sessionId:X.id,projectPath:X.projectPath,title:X.title,messageCount:X.messages.length,firstMessageTime:X.createdAt.toISOString(),lastMessageTime:new Date().toISOString(),hasErrors:!1,isActive:!0});try{let G=(await P$.listSessions()).find((q)=>q.sessionId===Q);if(!G)throw new J3("Session",Q);return Y.json(G)}catch(J){if(J instanceof J3)throw J;throw g$.error("[SessionRoutes] Failed to get session:",J),J}}),$.patch("/:sessionId",async(Y)=>{let Q=Y.req.param("sessionId");try{let X=await Y.req.json(),J=Ab.safeParse(X);if(!J.success)throw new C1("Invalid request body");let{title:G}=J.data,q=A1.get(Q);if(q&&G)q.title=G;return Y.json({success:!0,title:G})}catch(X){throw g$.error("[SessionRoutes] Failed to update session:",X),X}}),$.delete("/:sessionId",async(Y)=>{let Q=Y.req.param("sessionId"),X=A1.get(Q);if(X?.currentRunId){let G=U8.get(X.currentRunId);if(G)G.abortController.abort(),P1.publish(Q,"run.cancelled",{runId:G.id}),U8.delete(X.currentRunId)}try{await P$.deleteSession(Q)}catch(G){g$.warn("[SessionRoutes] Failed to delete session file:",G)}A1.delete(Q);let J=Z.get(Q);if(J){if(await J.dispose(),Z.delete(Q),Z.size===0)await k0.getInstance().disconnectAll()}return Y.json({success:!0})}),$.get("/:sessionId/message",async(Y)=>{let Q=Y.req.param("sessionId");try{let X=await P$.loadSession(Q);return Y.json(X)}catch(X){return g$.error("[SessionRoutes] Failed to get messages:",X),Y.json([])}}),$.get("/:sessionId/events",async(Y)=>{let Q=Y.req.param("sessionId"),X=A1.get(Q);if(!X){let J=Y.get("directory")||process.cwd();X={id:Q,projectPath:J,title:`Session ${Q.slice(0,6)}`,createdAt:new Date,messages:[]},A1.set(Q,X)}return Bb(Y,async(J)=>{await J.writeSSE({data:JSON.stringify({type:"connected",properties:{sessionId:Q,timestamp:Date.now()}})});let q=P1.subscribe((W)=>{if(W.sessionId!==Q)return;J.writeSSE({data:JSON.stringify({type:W.type,properties:{sessionId:W.sessionId,...W.properties}})}).catch(()=>{})}),K=setInterval(()=>{if(!J.aborted)J.writeSSE({data:JSON.stringify({type:"heartbeat",properties:{timestamp:Date.now()}})}).catch(()=>{})},15000);J.onAbort(()=>{clearInterval(K),q()});while(!0)if(await new Promise((W)=>setTimeout(W,1000)),J.aborted)break})}),$.post("/:sessionId/message",async(Y)=>{let Q=Y.req.param("sessionId"),X=await Y.req.json(),J=wb.safeParse(X);if(!J.success)throw new C1("Invalid message format");let{content:G,attachments:q,permissionMode:K}=J.data,W=K||"default",U=Y.get("directory")||process.cwd(),H=Rb(G,q),O=A1.get(Q);if(!O){let N=await P$.loadSession(Q).catch(()=>[]);O={id:Q,projectPath:U,title:`Session ${Q.slice(0,6)}`,createdAt:new Date,messages:N},A1.set(Q,O)}let F=j6(12),_=new AbortController,z={id:F,sessionId:Q,status:"running",abortController:_,createdAt:new Date};return U8.set(F,z),O.currentRunId=F,Db(z,O,H,W,Z).catch((N)=>{g$.error(`[SessionRoutes] Run ${F} failed:`,N)}),Y.json({runId:F,status:"running"},202)}),$.post("/:sessionId/abort",async(Y)=>{let Q=Y.req.param("sessionId"),X=A1.get(Q);if(X?.currentRunId){let J=U8.get(X.currentRunId);if(J)J.abortController.abort(),J.status="cancelled",P1.publish(Q,"run.cancelled",{runId:J.id})}return Y.json({success:!0})}),$.get("/:sessionId/status",async(Y)=>{let Q=Y.req.param("sessionId"),X=A1.get(Q);if(!X?.currentRunId)return Y.json({sessionId:Q,status:"idle"});let J=U8.get(X.currentRunId);return Y.json({sessionId:Q,runId:X.currentRunId,status:J?.status||"idle"})}),$};async function Db($,Z,Y,Q,X){let{abortController:J,sessionId:G,id:q}=$,K=j6(12),W=j6(12),U=(H,O)=>{P1.publish(G,H,O)};try{U("message.created",{messageId:K,role:"user",content:Vb(Y)}),U("session.status",{status:"running"}),U("message.created",{messageId:W,role:"assistant",content:""});let H=X.get(G);if(!H)H=await V2.create({sessionId:G}),X.set(G,H);let O=await n0.createWithRuntime(H,{sessionId:G}),F=async(B)=>{let L=j6(12),A=300000;$.status="waiting_permission";let R=new Promise((M)=>{let T=setTimeout(()=>{g$.warn(`[SessionRoutes] Permission ${L} timed out after 300000ms`),U("permission.timeout",{requestId:L}),M({approved:!1,reason:"timeout"})},300000);$.pendingPermission={permissionId:L,resolve:(w)=>{clearTimeout(T),M(w)},details:B}});U("permission.asked",{requestId:L,toolName:B.toolName,description:B.message,args:B.args,details:B}),g$.info(`[SessionRoutes] Permission request created: ${L}, runId: ${q}`);let V=await R;return g$.info(`[SessionRoutes] Permission response received: ${L}, approved: ${V.approved}`),$.status="running",$.pendingPermission=void 0,V},_={messages:[...Z.messages],userId:"web-user",sessionId:G,workspaceRoot:Z.projectPath,signal:J.signal,permissionMode:Q,confirmationHandler:{requestConfirmation:F}},z={stream:!0,onContentDelta:async(B)=>{U("message.delta",{messageId:W,delta:B})},onThinkingDelta:async(B)=>{U("thinking.delta",{delta:B})},onStreamEnd:async()=>{U("message.complete",{messageId:W}),U("thinking.completed",{})},onToolStart:async(B,L)=>{if(B.type!=="function")return;U("tool.start",{messageId:W,toolName:B.function.name,toolCallId:B.id,arguments:B.function.arguments,toolKind:L})},onToolResult:async(B,L)=>{if(B.type!=="function")return;U("tool.result",{messageId:W,toolName:B.function.name,toolCallId:B.id,success:!L.error,summary:L.metadata?.summary,output:L.displayContent,metadata:bb(L.metadata)})},onTokenUsage:async(B)=>{U("token.usage",B)},onTodoUpdate:async(B)=>{U("todo.updated",{todos:B})}},N=await O.chat(Y,_,z);Z.messages.push({role:"user",content:Y},{role:"assistant",content:N}),$.status="completed",U("session.completed",{runId:q}),U("session.status",{status:"idle"})}catch(H){g$.error("[SessionRoutes] Agent execution error:",H),$.status="failed",U("session.error",{error:H instanceof Error?H.message:"Unknown error"}),U("session.status",{status:"error"})}}function zU($,Z,Y){g$.info(`[SessionRoutes] Looking for permission ${Z} in session ${$}`),g$.info(`[SessionRoutes] Active runs: ${U8.size}`);for(let[Q,X]of U8.entries())if(g$.info(`[SessionRoutes] Checking run ${Q}: sessionId=${X.sessionId}, pendingPermission=${X.pendingPermission?.permissionId}`),X.sessionId===$&&X.pendingPermission?.permissionId===Z)return X.pendingPermission.resolve(Y),g$.info(`[SessionRoutes] Permission ${Z} responded, runId: ${X.id}`),!0;return g$.error(`[SessionRoutes] Permission not found: ${Z}`),!1}var eY=p("Service"),jb=J2.object({approved:J2.boolean(),remember:J2.boolean().optional(),scope:J2.enum(["once","session"]).optional(),targetMode:J2.enum(["default","autoEdit","plan","spec","yolo"]).optional(),feedback:J2.string().optional(),answers:J2.record(J2.union([J2.string(),J2.array(J2.string())])).optional()}),BU=()=>{let $=new Mb;return $.post("/:permissionId",async(Z)=>{let Y=Z.req.param("permissionId"),Q=Z.req.query("sessionId");eY.info(`[PermissionRoutes] Received permission response: permissionId=${Y}, sessionId=${Q}`);try{let X=await Z.req.json(),J=jb.safeParse(X);if(!J.success)throw new C1("Invalid permission response format");let{approved:G,remember:q,scope:K,targetMode:W,feedback:U,answers:H}=J.data;if(!Q)throw new C1("sessionId query parameter is required");if(!zU(Q,Y,{approved:G,reason:U,scope:K,targetMode:W,feedback:U,answers:H}))throw new J3("Permission request",Y);return eY.info(`[PermissionRoutes] Permission ${Y} ${G?"approved":"denied"}`),Z.json({success:!0,approved:G,remember:q})}catch(X){throw eY.error("[PermissionRoutes] Failed to respond to permission:",X),X}}),$};Y0();import{Hono as Eb}from"hono";Y0();C8();var U5=p("Service"),Tb="https://models.dev/api.json",yb=3600000,W5=null,NU=async()=>{if(W5&&Date.now()-W5.timestamp<yb)return W5.data;try{U5.info("\uD83D\uDCE1 Fetching models.dev data...");let $=await fetch(Tb,{headers:{"User-Agent":"Blade-CLI/1.0"}});if(!$.ok)throw Error(`HTTP ${$.status}: ${$.statusText}`);let Z=await $.json();return W5={data:Z,timestamp:Date.now()},U5.info(`✅ Loaded ${Object.keys(Z).length} providers from models.dev`),Z}catch($){throw U5.error("❌ Failed to fetch models.dev data:",$),$}},H5=async()=>{let $=await NU(),Z=[];for(let[Y,Q]of Object.entries($)){let X=Object.keys(Q.models||{}).length;if(X===0)continue;Z.push({id:Y,name:Q.name||Y,icon:m9[Y]||m9.default,description:`${X} 个模型`,isOAuth:!1,envVars:Q.env||[],docUrl:Q.doc,defaultBaseUrl:i6[Y],bladeProvider:XJ(Y)})}return Z.sort((Y,Q)=>{let X=p9.indexOf(Y.id),J=p9.indexOf(Q.id);if(X!==-1&&J!==-1)return X-J;if(X!==-1)return-1;if(J!==-1)return 1;return Y.name.localeCompare(Q.name)})},O5=async($)=>{let Y=(await NU())[$];if(!Y?.models)return U5.warn(`⚠️ No models found for provider: ${$}`),[];return Object.values(Y.models).map((Q)=>({id:Q.id,name:Q.name||Q.id,contextWindow:Q.limit?.context,maxOutput:Q.limit?.output,inputCost:Q.cost?.input,outputCost:Q.cost?.output}))};C8();var LU=p("Service"),wU=()=>{let $=new Eb;return $.get("/",async(Z)=>{try{let Y=await H5(),Q=Object.entries(l6).map(([X,J])=>({id:X,name:X.charAt(0).toUpperCase()+X.slice(1),icon:J.icon,description:J.description,isOAuth:!0,envVars:[],bladeProvider:J.bladeProvider}));return Z.json([...Y,...Q])}catch(Y){return LU.error("[ProviderRoutes] Failed to list providers:",Y),Z.json([])}}),$.get("/:providerId/models",async(Z)=>{let Y=Z.req.param("providerId");try{let Q=await O5(Y);return Z.json(Q)}catch(Q){return LU.error("[ProviderRoutes] Failed to list models:",Q),Z.json([])}}),$};Y0();t1();FZ();import{Hono as Ib}from"hono";import*as A4 from"node:fs/promises";import{homedir as Pb}from"node:os";import*as F5 from"node:path";var H8=p("Service"),$Q=F5.join(Pb(),".blade","skills-config.json");async function AU(){try{let $=await A4.readFile($Q,"utf-8");return JSON.parse($)}catch{return{disabled:[]}}}async function vb($){await A4.mkdir(F5.dirname($Q),{recursive:!0}),await A4.writeFile($Q,JSON.stringify($,null,2))}async function Cb($,Z){let Y=await AU();if(Z)Y.disabled=Y.disabled.filter((Q)=>Q!==$);else if(!Y.disabled.includes($))Y.disabled.push($);await vb(Y)}var q3=null,kb=300000;async function Sb(){if(q3&&Date.now()-q3.timestamp<kb)return q3.data;try{let $=await fetch("https://api.github.com/repos/anthropics/skills/contents/skills",{headers:{Accept:"application/vnd.github.v3+json","User-Agent":"Blade-Skills-Catalog"}});if(!$.ok)return H8.warn(`GitHub API returned ${$.status}`),q3?.data||[];let Z=await $.json(),Y=[];for(let Q of Z){if(Q.type!=="dir")continue;let X=`Official ${Q.name} skill`;try{let J=await fetch(`https://raw.githubusercontent.com/anthropics/skills/main/skills/${Q.name}/SKILL.md`,{headers:{"User-Agent":"Blade-Skills-Catalog"}});if(J.ok){let q=(await J.text()).match(/^#[^\n]*\n+([^\n#]+)/);if(q)X=q[1].trim().slice(0,100)}}catch{}Y.push({name:Q.name,description:X,tag:"Official",author:"Anthropic"})}return q3={data:Y,timestamp:Date.now()},Y}catch($){return H8.warn("Failed to fetch skills catalog from GitHub:",$),q3?.data||[]}}var bU=()=>{let $=new Ib;return $.get("/",async(Z)=>{try{let Y=O$();await Y.initialize();let Q=Y.getAll(),X=await AU(),J=Q.map((G)=>({id:G.name,name:G.name,enabled:!X.disabled.includes(G.name),description:G.description||"",version:G.version||"1.0.0",provider:"Local",location:G.source==="builtin"?"Built-in":G.basePath,capabilities:["prompts"],allowedTools:G.allowedTools||[]}));return Z.json(J)}catch(Y){return H8.error("[SkillsRoutes] Failed to get skills:",Y),Z.json([])}}),$.post("/:name/toggle",async(Z)=>{try{let Y=Z.req.param("name"),Q=await Z.req.json();return await Cb(Y,Q.enabled),Z.json({success:!0,enabled:Q.enabled})}catch(Y){return H8.error("[SkillsRoutes] Failed to toggle skill:",Y),Z.json({success:!1,error:Y.message},500)}}),$.delete("/:name",async(Z)=>{try{let Y=Z.req.param("name"),Q=`${process.env.HOME}/.blade/skills/${Y}`;return await A4.rm(Q,{recursive:!0,force:!0}),await O$().refresh(),Z.json({success:!0})}catch(Y){return H8.error("[SkillsRoutes] Failed to uninstall skill:",Y),Z.json({success:!1,error:Y.message},500)}}),$.post("/install",async(Z)=>{try{let Y=await Z.req.json(),Q=K7(),X=O$(),J=!1;if(Y.source==="catalog"&&Y.name){if(J=await Q.installOfficialSkill(Y.name),!J)return Z.json({success:!1,error:"Failed to install skill from catalog"},500)}else if(Y.source==="repo"&&Y.url){if(J=await Q.installFromRepo(Y.url,Y.name),!J)return Z.json({success:!1,error:"Failed to install skill from repository. Make sure the repo contains a SKILL.md file."},500)}else if(Y.source==="local"&&Y.path){if(J=await Q.installFromLocal(Y.path,Y.name),!J)return Z.json({success:!1,error:"Failed to install skill from local path. Make sure the path exists and contains a SKILL.md file."},500)}else return Z.json({success:!1,error:"Invalid install parameters. Required: source with corresponding url/path/name"},400);return await X.refresh(),Z.json({success:!0})}catch(Y){return H8.error("[SkillsRoutes] Failed to install skill:",Y),Z.json({success:!1,error:Y.message},500)}}),$.get("/catalog",async(Z)=>{try{let Y=await Sb();return Z.json(Y)}catch(Y){return H8.error("[SkillsRoutes] Failed to get catalog:",Y),Z.json([])}}),$};Y0();t4();W8();Q6();import fb from"fast-glob";import{Hono as hb}from"hono";import{execSync as xb}from"node:child_process";import{readdir as pb}from"node:fs/promises";import _5 from"node:path";var T6=p("Service"),mb=($)=>{try{return xb("git rev-parse --abbrev-ref HEAD",{cwd:$,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||null}catch{return null}},gb=[...H1.map(($)=>`${$}/**`),...H1,...d8.map(($)=>`**/${$}`)],ub=new Set(["/theme","/model","/permissions","/mcp","/skills","/exit","/resume","/ide","/login","/logout"]),VU=()=>{let $=new hb;return $.get("/commands",async(Z)=>{try{let Y=Z.req.query("q")||"",Q=$5(Y).filter((X)=>!ub.has(X.command));return Z.json(Q)}catch(Y){return T6.error("[SuggestionsRoutes] Failed to get command suggestions:",Y),Z.json([])}}),$.get("/files",async(Z)=>{try{let Y=Z.req.query("q")||"",Q=Z.get("directory")||process.cwd(),X=Math.min(Number(Z.req.query("limit"))||100,1000),G=(await fb("**/*",{cwd:Q,dot:!1,followSymbolicLinks:!1,onlyFiles:!1,markDirectories:!0,unique:!0,ignore:gb})).map((W)=>W.replace(/\\/g,"/"));if(!Y)return Z.json(G.slice(0,X));let q=Y.toLowerCase(),K=G.filter((W)=>W.toLowerCase().includes(q)).slice(0,X);return Z.json(K)}catch(Y){return T6.error("[SuggestionsRoutes] Failed to get file suggestions:",Y),Z.json([])}}),$.get("/files/tree",async(Z)=>{try{let Y=Z.get("directory")||process.cwd(),Q=Z.req.query("path")||"",X=Q?_5.join(Y,Q):Y,G=(await pb(X,{withFileTypes:!0})).map((W)=>({name:W.name,path:Q?`${Q}/${W.name}`:W.name,type:W.isDirectory()?"dir":"file"}));G.sort((W,U)=>{if(W.type!==U.type)return W.type==="dir"?-1:1;return W.name.localeCompare(U.name)});let q=new Set(H1),K=G.filter((W)=>{let U=W.name;if(U.startsWith("."))return!1;if(q.has(U))return!1;for(let H of d8)if(U.match(new RegExp(H.replace("*",".*"))))return!1;return!0});return Z.json(K)}catch(Y){return T6.error("[SuggestionsRoutes] Failed to get file tree:",Y),Z.json([])}}),$.get("/files/content",async(Z)=>{try{let Y=Z.req.query("path");if(!Y)return Z.json({error:"Missing file path"},400);let Q=Z.get("directory")||process.cwd(),X=_5.resolve(Q,Y),J=_5.relative(Q,X);if(J.startsWith("..")||_5.isAbsolute(J))return Z.json({error:"Invalid file path"},400);let G=q4(),q=await G.stat(X);if(!q?.isFile)return Z.json({error:"File not found"},404);let K=200000,W=await G.readTextFile(X),U=W.length>K;return Z.json({path:Y,content:U?W.slice(0,K):W,truncated:U,size:q.size})}catch(Y){return T6.error("[SuggestionsRoutes] Failed to get file content:",Y),Z.json({error:"Failed to read file"},500)}}),$.get("/git-info",async(Z)=>{try{let Y=Z.get("directory")||process.cwd(),Q=mb(Y);return Z.json({branch:Q})}catch(Y){return T6.error("[SuggestionsRoutes] Failed to get git info:",Y),Z.json({branch:null})}}),$};Y0();import{Hono as db}from"hono";var b4=p("Service"),K3=new Map,RU=2097152,DU=65536;function MU(){return typeof globalThis.Bun<"u"}async function cb($,Z,Y){if(MU()){let{spawn:J}=await import("bun-pty"),G=J($,Z,{name:"xterm-256color",cwd:Y.cwd,env:Y.env});return{pid:G.pid,write:(q)=>G.write(q),resize:(q,K)=>G.resize(q,K),kill:()=>G.kill(),onData:(q)=>G.onData(q),onExit:(q)=>G.onExit(q)}}let X=(await import("node-pty")).spawn($,Z,{name:"xterm-256color",cwd:Y.cwd,env:Y.env,cols:80,rows:24});return{pid:X.pid,write:(J)=>X.write(J),resize:(J,G)=>X.resize(J,G),kill:()=>X.kill(),onData:(J)=>{X.onData(J)},onExit:(J)=>{X.onExit(J)}}}var YQ=void 0,ZQ;if(MU())try{let{createBunWebSocket:$}=await import("hono/bun"),Z=$();ZQ=Z.upgradeWebSocket,YQ=Z.websocket}catch($){b4.warn("[Terminal] Failed to initialize Bun WebSocket support:",$)}async function jU($,Z){let Y=`term-${Date.now()}`;b4.info(`[Terminal] New connection: ${Y}, cwd: ${$}`);let Q=process.platform==="win32"?"powershell.exe":process.env.SHELL||"/bin/zsh",X=Q.endsWith("sh")?["-l"]:[],J=await cb(Q,X,{cwd:$,env:{...process.env,TERM:"xterm-256color",COLORTERM:"truecolor"}}),G={id:Y,process:J,cwd:$,buffer:"",subscribers:new Set};if(K3.set(Y,G),G.subscribers.add(Z),J.onData((q)=>{let K=!1;for(let W of G.subscribers)try{W.send(q),K=!0}catch{G.subscribers.delete(W)}if(K)return;if(G.buffer+=q,G.buffer.length>RU)G.buffer=G.buffer.slice(-RU)}),J.onExit(({exitCode:q})=>{b4.info(`[Terminal] Process exited: ${Y}, code: ${q}`);for(let K of G.subscribers)try{K.close()}catch{}K3.delete(Y)}),G.buffer){let q=G.buffer;G.buffer="";for(let K=0;K<q.length;K+=DU)Z.send(q.slice(K,K+DU))}return{session:G,cleanup:()=>{if(b4.info(`[Terminal] Connection closed: ${Y}`),G.subscribers.delete(Z),G.subscribers.size===0){try{G.process.kill()}catch{}K3.delete(Y)}}}}function TU($,Z){$.on("connection",async(Y,Q)=>{let X=new URL(Q.url||"/",`http://${Q.headers.host}`);if(!X.pathname.endsWith("/terminal/ws")){Y.close();return}let J=X.searchParams.get("cwd")||Z()||process.cwd();try{let{session:G,cleanup:q}=await jU(J,{send:(K)=>Y.send(K),close:()=>Y.close()});Y.on("message",(K)=>{try{G.process.write(String(K))}catch(W){b4.error("[Terminal] Failed to write to PTY:",W)}}),Y.on("close",q),Y.on("error",q)}catch(G){b4.error("[Terminal] Failed to spawn PTY:",G),Y.close()}})}var yU=()=>{let $=new db;if($.get("/status",(Z)=>{let Y=Array.from(K3.values()).map((Q)=>({id:Q.id,cwd:Q.cwd}));return Z.json({active:Y.length,terminals:Y})}),$.post("/kill/:terminalId",(Z)=>{let Y=Z.req.param("terminalId"),Q=K3.get(Y);if(Q){try{Q.process.kill()}catch{}for(let X of Q.subscribers)X.close();return K3.delete(Y),Z.json({success:!0})}return Z.json({success:!1,error:"Terminal not found"},404)}),ZQ)$.get("/ws",ZQ((Z)=>{let Y=Z.req.query("cwd")||Z.get("directory")||process.cwd(),Q;return{async onOpen(X,J){try{Q=await jU(Y,{send:(G)=>J.send(G),close:()=>J.close()})}catch(G){b4.error("[Terminal] Failed to spawn PTY:",G),J.close()}},onMessage(X){if(!Q)return;try{Q.session.process.write(String(X.data))}catch(J){b4.error("[Terminal] Failed to write to PTY:",J)}},onClose(){Q?.cleanup()}}}));else $.get("/ws",(Z)=>{return Z.json({message:"WebSocket endpoint - connect via ws:// protocol",hint:"Use WebSocket client to connect to this endpoint"})});return $};var b1=p("Service"),QQ=[];function eb(){let $=nb(sb(import.meta.url)),Z=[O8($,"web"),O8(process.cwd(),"dist/web"),O8(process.cwd(),"packages/cli/dist/web")];for(let Y of Z){let Q=O8(Y,"index.html");if(PU(Q)){if(z5(Q,"utf-8").includes("/assets/"))return b1.debug(`[Server] Found web dist at: ${Y}`),Y}}return null}function $V(){let $=new lb;$.onError((Y,Q)=>{if(b1.error("[Server] Request error:",Y),Y instanceof D6)return Q.json(Y.toObject(),Y.statusCode);let X=Y instanceof Error?Y.message:String(Y);return Q.json({error:{code:"INTERNAL_ERROR",message:X}},500)}),$.use(async(Y,Q)=>{let X=process.env.BLADE_SERVER_PASSWORD;if(!X)return Q();let J=Y.req.path;if(J==="/"||J.startsWith("/assets/")||J.endsWith(".html")||J.endsWith(".js")||J.endsWith(".css"))return Q();let G=Y.req.header("Authorization");if(!G?.startsWith("Basic "))return Y.header("WWW-Authenticate",'Basic realm="Blade Server"'),Y.json({error:{code:"UNAUTHORIZED",message:"Authentication required"}},401);let q=Buffer.from(G.slice(6),"base64").toString(),[K,W]=q.split(":"),U=process.env.BLADE_SERVER_USERNAME??"blade";if(K!==U||W!==X)return Y.json({error:{code:"UNAUTHORIZED",message:"Invalid credentials"}},401);return Q()}),$.use(async(Y,Q)=>{let X=Y.req.path==="/health"||Y.req.path==="/global/health"||Y.req.path.startsWith("/assets/");if(!X)b1.debug(`[Server] ${Y.req.method} ${Y.req.path}`);let J=Date.now();if(await Q(),!X){let G=Date.now()-J;b1.debug(`[Server] ${Y.req.method} ${Y.req.path} - ${Y.res.status} (${G}ms)`)}}),$.use(ib({origin(Y){if(!Y)return;if(Y.startsWith("http://localhost:"))return Y;if(Y.startsWith("http://127.0.0.1:"))return Y;if(Y==="tauri://localhost"||Y==="http://tauri.localhost")return Y;if(QQ.includes(Y))return Y;return}})),$.use(async(Y,Q)=>{let X=Y.req.query("directory")||Y.req.header("x-blade-directory")||process.cwd();try{X=decodeURIComponent(X)}catch{}return Y.set("directory",X),Q()}),$.route("/global",HU()),$.route("/sessions",_U()),$.route("/configs",UU()),$.route("/permissions",BU()),$.route("/providers",wU()),$.route("/models",FU()),$.route("/suggestions",VU()),$.route("/terminal",yU()),$.route("/mcp",OU()),$.route("/skills",bU()),$.get("/health",(Y)=>{return Y.json({healthy:!0,version:G1()})});let Z=eb();if(Z)b1.info(`[Server] Serving static files from ${Z}`),$.get("/assets/*",(Y)=>{let Q=O8(Z,Y.req.path);if(!PU(Q))return Y.json({error:{code:"NOT_FOUND",message:`File not found: ${Y.req.path}`}},404);let X=z5(Q),J=ob(Q).toLowerCase(),q={".js":"application/javascript",".css":"text/css",".html":"text/html",".json":"application/json",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".ico":"image/x-icon",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".eot":"application/vnd.ms-fontobject"}[J]||"application/octet-stream";return new Response(X,{headers:{"Content-Type":q,"Cache-Control":"public, max-age=31536000, immutable"}})}),$.get("/",(Y)=>{let Q=O8(Z,"index.html"),X=z5(Q,"utf-8");return Y.html(X)}),$.get("*",(Y)=>{let Q=Y.req.path;if(Q.includes("."))return Y.json({error:{code:"NOT_FOUND",message:`File not found: ${Q}`}},404);let X=O8(Z,"index.html"),J=z5(X,"utf-8");return Y.html(J)});else b1.warn('[Server] Web UI not found. Run "cd web && pnpm build" to enable web interface.'),$.get("/",(Y)=>{return Y.json({message:"Blade API Server",version:G1(),webUI:!1,hint:'Web UI not built. Run "cd web && pnpm build" to enable.',endpoints:{health:"/health",sessions:"/sessions",configs:"/configs",permissions:"/permissions",providers:"/providers"}})}),$.all("*",(Y)=>{return Y.json({error:{code:"NOT_FOUND",message:`Route not found: ${Y.req.path}`}},404)});return $}function y6(){let $=ab(),Z=[];for(let Y of Object.keys($)){let Q=$[Y];if(!Q)continue;for(let X of Q){if(X.internal||X.family!=="IPv4")continue;if(X.address.startsWith("172."))continue;Z.push(X.address)}}return Z}function EU(){return typeof globalThis.Bun<"u"}function IU($,Z){let Y=globalThis.Bun,Q=(J)=>{try{return Y.serve({hostname:Z.hostname,port:J,fetch:$.fetch,idleTimeout:0,websocket:YQ})}catch(G){b1.error("Failed to start Bun server:",G);return}},X=Z.port===0?Q(4096)??Q(0):Q(Z.port);if(!X)throw Error(`Failed to start Bun server on port ${Z.port}`);return{url:X.url,port:X.port,hostname:X.hostname,stop:async()=>{X.stop(!0)}}}function ZV($,Z){return new Promise((Y,Q)=>{let X=rb(async(W,U)=>{let H=new URL(W.url||"/",`http://${W.headers.host}`),O=new Headers;for(let[z,N]of Object.entries(W.headers))if(N)if(Array.isArray(N))for(let B of N)O.append(z,B);else O.set(z,N);let F;if(W.method!=="GET"&&W.method!=="HEAD")F=(await new Promise((N)=>{let B=[];W.on("data",(L)=>B.push(L)),W.on("end",()=>N(Buffer.concat(B)))})).toString();let _=new Request(H.toString(),{method:W.method,headers:O,body:F});try{let z=await $.fetch(_);if(U.statusCode=z.status,z.headers.forEach((N,B)=>{U.setHeader(B,N)}),z.body){let N=z.body.getReader(),B=async()=>{let{done:L,value:A}=await N.read();if(L){U.end();return}return U.write(A),B()};await B()}else{let N=await z.text();U.end(N)}}catch(z){b1.error("[Server] Node request error:",z),U.statusCode=500,U.end(JSON.stringify({error:{code:"INTERNAL_ERROR",message:"Internal server error"}}))}}),J=new tb({noServer:!0}),G=process.cwd();TU(J,()=>G),X.on("upgrade",(W,U,H)=>{if(new URL(W.url||"/",`http://${W.headers.host}`).pathname==="/terminal/ws")J.handleUpgrade(W,U,H,(F)=>{J.emit("connection",F,W)});else U.destroy()});let q=(W)=>{return new Promise((U,H)=>{X.once("error",(O)=>{if(O.code==="EADDRINUSE")H(O);else H(O)}),X.listen(W,Z.hostname,()=>{let O=X.address();if(O&&typeof O==="object")U(O.port);else U(W)})})};(async()=>{let W;if(Z.port===0)try{W=await q(4096)}catch{W=await q(0)}else W=await q(Z.port);let U=new URL(`http://${Z.hostname==="0.0.0.0"?"localhost":Z.hostname}:${W}`);Y({url:U,port:W,hostname:Z.hostname,stop:async()=>{return new Promise((H)=>{J.close(()=>{X.close(()=>H())})})}})})().catch(Q)})}var W3;((Tc)=>{let $,Z;function Y(){if(!Z)Z=$V();return Z}Tc.getApp=Y;function Q(G){QQ=G.cors??[];let q=Y();if(EU())$=IU(q,G),b1.info(`[Server] Blade server listening on ${$.url} (Bun runtime)`);else throw Error("Blade web server requires Bun runtime. Please run with Bun: `bun run blade web` or install Bun from https://bun.sh");let K=$;return{url:K.url,port:K.port,hostname:K.hostname,stop:async()=>{if($)await $.stop(),$=void 0,Z=void 0,b1.info("[Server] Blade server stopped")}}}Tc.listen=Q;async function X(G){QQ=G.cors??[];let q=Y();if(EU())$=IU(q,G),b1.info(`[Server] Blade server listening on ${$.url} (Bun runtime)`);else $=await ZV(q,G),b1.info(`[Server] Blade server listening on ${$.url} (Node.js runtime)`);let K=$;return{url:K.url,port:K.port,hostname:K.hostname,stop:async()=>{if($)await $.stop(),$=void 0,Z=void 0,b1.info("[Server] Blade server stopped")}}}Tc.listenAsync=X;function J(){return $!==void 0}Tc.isRunning=J})(W3||={});b0();var vU={command:"serve",describe:"Start a headless Blade server (no browser)",builder:J5,handler:async($)=>{let Z=G5($);if(await _2(),!process.env.BLADE_SERVER_PASSWORD)console.log(YV.yellow("Warning: BLADE_SERVER_PASSWORD is not set; server is unsecured."));let Y=await W3.listenAsync(Z);if(console.log(`Blade server listening on http://${Y.hostname}:${Y.port}`),Z.hostname==="0.0.0.0"){let Q=y6();for(let X of Q)console.log(` Network: http://${X}:${Y.port}`)}await new Promise(()=>{}),await Y.stop()}};import{execSync as WV}from"child_process";d4();import*as F8 from"fs/promises";import*as V4 from"path";import CU from"semver";import{fileURLToPath as QV}from"url";var XQ="blade-code",XV="https://cdn.jsdelivr.net/npm/blade-code@latest/CHANGELOG.md",kU=V4.join(process.env.HOME||process.env.USERPROFILE||".",".blade"),SU=V4.join(kU,"version-cache.json"),JV=3600000,GV=`https://registry.npmjs.org/${XQ}/latest`;async function qV(){try{if(process.env.BLADE_VERSION)return process.env.BLADE_VERSION;let $=QV(import.meta.url),Z=V4.dirname($),Y=[V4.join(Z,"..","..","package.json"),V4.join(Z,"..","package.json"),V4.join(process.cwd(),"package.json")];for(let Q of Y)try{let X=await F8.readFile(Q,"utf-8"),J=JSON.parse(X);if(J.name===XQ&&J.version)return J.version}catch{}return"unknown"}catch{return"unknown"}}async function fU(){try{let $=await F8.readFile(SU,"utf-8"),Z=JSON.parse($);if(Date.now()-Z.checkedAt<JV)return Z;return{...Z,checkedAt:0}}catch{return null}}async function hU($){try{await F8.mkdir(kU,{recursive:!0,mode:493}),await F8.writeFile(SU,JSON.stringify($,null,2))}catch{}}async function KV(){try{let $=await M$(GV,{timeout:5000,headers:{Accept:"application/json"}});if(!$.ok)return null;return(await $.json()).version||null}catch{return null}}async function JQ($=!1){let Z=await qV(),Y=XV;if(Z==="unknown")return{currentVersion:Z,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:Y,error:"Unable to determine current version"};let Q=await fU(),X=Q?.skipUntilVersion,J=null;if(!$&&Q&&Q.checkedAt>0)J=Q.latestVersion;else if(J=await KV(),J)await hU({latestVersion:J,checkedAt:Date.now(),skipUntilVersion:X});if(!J)return{currentVersion:Z,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:Y,error:"Unable to check for updates"};let G=CU.gt(J,Z),q=G;if(G&&X)q=CU.gt(J,X);return{currentVersion:Z,latestVersion:J,hasUpdate:G,shouldPrompt:q,releaseNotesUrl:Y}}async function xU($){let Z=await fU();await hU({latestVersion:Z?.latestVersion||$,checkedAt:Z?.checkedAt||Date.now(),skipUntilVersion:$})}function GQ(){return`npm install -g ${XQ}@latest --registry https://registry.npmjs.org`}async function pU(){let{spawn:$}=await import("child_process");return new Promise((Z)=>{let Y=GQ(),Q=$(Y,{stdio:"inherit",shell:!0});Q.on("close",(X)=>{if(X===0)Z({success:!0,message:"✅ 升级成功!请重新启动 blade。"});else Z({success:!1,message:`❌ 升级失败 (exit code: ${X})`})}),Q.on("error",(X)=>{Z({success:!1,message:`❌ 升级失败: ${X.message}`})})})}async function mU(){try{let $=await JQ();return $.shouldPrompt?$:null}catch{return null}}var gU={command:"update",describe:"Check for updates and install if available",handler:async()=>{console.log("\uD83D\uDD0D Checking for updates...");try{let $=await JQ(!0);if(console.log(`\uD83D\uDCE6 Current version: ${$.currentVersion}`),$.error){console.log(`⚠️ ${$.error}`);return}if($.latestVersion)console.log(`\uD83D\uDCE6 Latest version: ${$.latestVersion}`);if($.hasUpdate&&$.latestVersion){console.log(""),console.log(`\x1B[33m⚠️ Update available: ${$.currentVersion} → ${$.latestVersion}\x1B[0m`),console.log(""),console.log("\uD83D\uDE80 Updating...");try{WV("npm install -g blade-code@latest --registry https://registry.npmjs.org",{stdio:"inherit"}),console.log(""),console.log("✅ Update complete!")}catch(Z){console.error("❌ Update failed. Please run manually:"),console.error(" npm install -g blade-code@latest"),process.exit(1)}}else console.log("✅ You are running the latest version of Blade")}catch($){console.error(`❌ Failed to check for updates: ${$ instanceof Error?$.message:"未知错误"}`),process.exit(1)}}};import G2 from"chalk";import uU from"open";b0();e2();var UV=`
|
|
2788
2788
|
____ _ _
|
|
2789
2789
|
| __ )| | __ _ __| | ___
|
|
2790
2790
|
| _ \\| |/ _\` |/ _\` |/ _ \\
|
|
2791
2791
|
| |_) | | (_| | (_| | __/
|
|
2792
2792
|
|____/|_|\\__,_|\\__,_|\\___|
|
|
2793
|
-
`,dU={command:"web",describe:"Start Blade server and open web interface",builder:
|
|
2793
|
+
`,dU={command:"web",describe:"Start Blade server and open web interface",builder:J5,handler:async($)=>{let Z=G5($);if(await _2(),!process.env.BLADE_SERVER_PASSWORD)console.log(G2.yellow("⚠️ BLADE_SERVER_PASSWORD is not set; server is unsecured.")),console.log(G2.gray(` Set this environment variable to enable Basic Auth.
|
|
2794
2794
|
`));let Y=await W3.listenAsync(Z);if(console.log(G2.cyan(UV)),console.log(G2.gray(` v${G1()}
|
|
2795
2795
|
`)),Z.hostname==="0.0.0.0"){let Q=`http://localhost:${Y.port}`;console.log(G2.blue.bold(" Local access: "),G2.white(Q));let X=y6();for(let J of X)console.log(G2.blue.bold(" Network access: "),G2.white(`http://${J}:${Y.port}`));uU(Q).catch(()=>{})}else{let Q=Y.url.toString();console.log(G2.blue.bold(" Web interface: "),G2.white(Q)),uU(Q).catch(()=>{})}console.log(""),console.log(G2.gray(` Press Ctrl+C to stop the server.
|
|
2796
|
-
`)),await new Promise(()=>{}),await Y.stop()}};Y0();H$();K1();Y0();b0();function cU(){process.stdout.write("\x1B[?25h"),process.stdout.write("\x1B[0m")}var R4=p("Service");function HV($){switch($){case"SIGINT":return"ctrl_c";case"esc":return"esc";case"uncaughtException":case"unhandledRejection":return"error";case"SIGTERM":case"normal":default:return"user_exit"}}class U3{static instance=null;cleanupHandlers=[];isShuttingDown=!1;initialized=!1;constructor(){}static getInstance(){if(!U3.instance)U3.instance=new U3;return U3.instance}initialize(){if(this.initialized){R4.debug("[GracefulShutdown] 已初始化,跳过重复初始化");return}if(process.on("uncaughtException",($)=>{this.handleFatalError("uncaughtException",$)}),process.on("unhandledRejection",($)=>{let Z=$ instanceof Error?$:Error(String($));this.handleFatalError("unhandledRejection",Z)}),process.on("SIGTERM",()=>{R4.info("[GracefulShutdown] 收到 SIGTERM 信号"),this.shutdown("SIGTERM",0)}),process.env.BLADE_NON_INTERACTIVE==="true")process.on("SIGINT",()=>{R4.info("[GracefulShutdown] 收到 SIGINT 信号(非交互模式)"),this.shutdown("SIGINT",0)});this.initialized=!0,R4.debug("[GracefulShutdown] 全局错误处理器已初始化")}registerCleanup($){return this.cleanupHandlers.push($),R4.debug(`[GracefulShutdown] 注册清理函数,当前共 ${this.cleanupHandlers.length} 个`),()=>{let Z=this.cleanupHandlers.indexOf($);if(Z!==-1)this.cleanupHandlers.splice(Z,1),R4.debug(`[GracefulShutdown] 取消注册清理函数,剩余 ${this.cleanupHandlers.length} 个`)}}handleFatalError($,Z){if(this.isShuttingDown){console.error(`[GracefulShutdown] 退出过程中发生额外错误 (${$}):`,Z);return}if(console.error(""),console.error("═".repeat(60)),console.error(`\uD83D\uDCA5 发生未捕获的错误 (${$})`),console.error("═".repeat(60)),console.error(""),console.error("错误信息:",Z.message),console.error(""),Z.stack)console.error("堆栈跟踪:"),console.error(Z.stack);console.error(""),console.error("═".repeat(60)),console.error(""),this.shutdown($,1)}async shutdown($,Z=0){if(this.isShuttingDown){R4.debug("[GracefulShutdown] 已在退出过程中,跳过重复退出");return}this.isShuttingDown=!0,R4.info(`[GracefulShutdown] 开始优雅退出 (原因: ${$})`);try{await LX()}catch(X){}try{let X=T0.getInstance();if(X.isEnabled()){let J=X0(),G=J.session?.sessionId||"unknown",q=J.config?.config?.permissionMode||"default";await X.executeSessionEndHooks(HV($),{projectDir:process.cwd(),sessionId:G,permissionMode:q})}}catch(X){console.error("[GracefulShutdown] SessionEnd hooks 执行失败:",X)}let Y=5000,Q=new Promise((X,J)=>{setTimeout(()=>{J(Error(`清理超时 (${Y}ms)`))},Y)});try{let X=this.runCleanupHandlers();await Promise.race([X,Q])}catch(X){console.error("[GracefulShutdown] 清理过程中发生错误:",X)}finally{cU(),setTimeout(()=>{process.exit(Z)},100)}}async runCleanupHandlers(){let $=[...this.cleanupHandlers].reverse();for(let Z of $)try{let Y=Z();if(Y instanceof Promise)await Y}catch(Y){console.error("[GracefulShutdown] 清理函数执行失败:",Y)}}isExiting(){return this.isShuttingDown}reset(){this.isShuttingDown=!1,this.cleanupHandlers=[],this.initialized=!1}}var _8=()=>{return U3.getInstance()},lU=($)=>{return _8().registerCleanup($)},iU=()=>{_8().initialize()},H3=($=0)=>{cU(),process.exit($)};z4();Y4();K1();Y0();s1();e8();import{useMemoizedFn as IF}from"ahooks";import{useEffect as nM,useState as tQ}from"react";t1();W8();b0();c8();H$();Y0();import{useMemoizedFn as X1}from"ahooks";import{Box as f4,useApp as lM}from"ink";import{useEffect as h4,useRef as
|
|
2797
|
-
`)j++;return j},v=T4((I)=>{L.current+=I;let j=L.current;if(w(j)>=5||j.length>=400){M();return}if(!A.current)A.current=setTimeout(M,300)}),l=T4((I)=>{R.current+=I;let j=R.current;if(w(j)>=5||j.length>=400){T();return}if(!V.current)V.current=setTimeout(T,300)}),o=T4(()=>{if(L.current="",A.current)clearTimeout(A.current),A.current=null;if(R.current="",V.current)clearTimeout(V.current),V.current=null});VH(()=>{return()=>{_(),o()}},[_,o]),VH(()=>{if(!K)W.setCurrentThinkingContent(null)},[K,W]);let S=T4(()=>{if(!X)return;M(),T(),H.abort(),U.setTodos([]);let I=X0().session.currentStreamingMessageId;if(I)
|
|
2796
|
+
`)),await new Promise(()=>{}),await Y.stop()}};Y0();H$();K1();Y0();b0();function cU(){process.stdout.write("\x1B[?25h"),process.stdout.write("\x1B[0m")}var R4=p("Service");function HV($){switch($){case"SIGINT":return"ctrl_c";case"esc":return"esc";case"uncaughtException":case"unhandledRejection":return"error";case"SIGTERM":case"normal":default:return"user_exit"}}class U3{static instance=null;cleanupHandlers=[];isShuttingDown=!1;initialized=!1;constructor(){}static getInstance(){if(!U3.instance)U3.instance=new U3;return U3.instance}initialize(){if(this.initialized){R4.debug("[GracefulShutdown] 已初始化,跳过重复初始化");return}if(process.on("uncaughtException",($)=>{this.handleFatalError("uncaughtException",$)}),process.on("unhandledRejection",($)=>{let Z=$ instanceof Error?$:Error(String($));this.handleFatalError("unhandledRejection",Z)}),process.on("SIGTERM",()=>{R4.info("[GracefulShutdown] 收到 SIGTERM 信号"),this.shutdown("SIGTERM",0)}),process.env.BLADE_NON_INTERACTIVE==="true")process.on("SIGINT",()=>{R4.info("[GracefulShutdown] 收到 SIGINT 信号(非交互模式)"),this.shutdown("SIGINT",0)});this.initialized=!0,R4.debug("[GracefulShutdown] 全局错误处理器已初始化")}registerCleanup($){return this.cleanupHandlers.push($),R4.debug(`[GracefulShutdown] 注册清理函数,当前共 ${this.cleanupHandlers.length} 个`),()=>{let Z=this.cleanupHandlers.indexOf($);if(Z!==-1)this.cleanupHandlers.splice(Z,1),R4.debug(`[GracefulShutdown] 取消注册清理函数,剩余 ${this.cleanupHandlers.length} 个`)}}handleFatalError($,Z){if(this.isShuttingDown){console.error(`[GracefulShutdown] 退出过程中发生额外错误 (${$}):`,Z);return}if(console.error(""),console.error("═".repeat(60)),console.error(`\uD83D\uDCA5 发生未捕获的错误 (${$})`),console.error("═".repeat(60)),console.error(""),console.error("错误信息:",Z.message),console.error(""),Z.stack)console.error("堆栈跟踪:"),console.error(Z.stack);console.error(""),console.error("═".repeat(60)),console.error(""),this.shutdown($,1)}async shutdown($,Z=0){if(this.isShuttingDown){R4.debug("[GracefulShutdown] 已在退出过程中,跳过重复退出");return}this.isShuttingDown=!0,R4.info(`[GracefulShutdown] 开始优雅退出 (原因: ${$})`);try{await LX()}catch(X){}try{let X=T0.getInstance();if(X.isEnabled()){let J=X0(),G=J.session?.sessionId||"unknown",q=J.config?.config?.permissionMode||"default";await X.executeSessionEndHooks(HV($),{projectDir:process.cwd(),sessionId:G,permissionMode:q})}}catch(X){console.error("[GracefulShutdown] SessionEnd hooks 执行失败:",X)}let Y=5000,Q=new Promise((X,J)=>{setTimeout(()=>{J(Error(`清理超时 (${Y}ms)`))},Y)});try{let X=this.runCleanupHandlers();await Promise.race([X,Q])}catch(X){console.error("[GracefulShutdown] 清理过程中发生错误:",X)}finally{cU(),setTimeout(()=>{process.exit(Z)},100)}}async runCleanupHandlers(){let $=[...this.cleanupHandlers].reverse();for(let Z of $)try{let Y=Z();if(Y instanceof Promise)await Y}catch(Y){console.error("[GracefulShutdown] 清理函数执行失败:",Y)}}isExiting(){return this.isShuttingDown}reset(){this.isShuttingDown=!1,this.cleanupHandlers=[],this.initialized=!1}}var _8=()=>{return U3.getInstance()},lU=($)=>{return _8().registerCleanup($)},iU=()=>{_8().initialize()},H3=($=0)=>{cU(),process.exit($)};z4();Y4();K1();Y0();s1();e8();import{useMemoizedFn as IF}from"ahooks";import{useEffect as nM,useState as tQ}from"react";t1();W8();b0();c8();H$();Y0();import{useMemoizedFn as X1}from"ahooks";import{Box as f4,useApp as lM}from"ink";import{useEffect as h4,useRef as i5}from"react";B6();I1();I2();import{useShallow as rU}from"zustand/react/shallow";b0();import{useStore as OV}from"zustand";function z0($){return OV(i1,$)}H$();var FV=[],aU=()=>z0(($)=>$.session.sessionId),B5=()=>z0(($)=>$.session.messages),nU=()=>z0(($)=>$.session.clearCount),oU=()=>z0(($)=>$.session.isCompacting),D4=()=>z0(($)=>$.session.actions),sU=()=>z0(($)=>{let{inputTokens:Z,maxContextTokens:Y}=$.session.tokenUsage;if(Y<=0)return 100;let Q=Math.max(0,100-Z/Y*100);return Math.round(Q)}),tU=()=>z0(($)=>$.app.initializationStatus),eU=()=>z0(($)=>$.app.initializationError),N5=()=>z0(($)=>$.app.activeModal),$H=()=>z0(($)=>$.app.todos),ZH=()=>z0(($)=>$.app.modelEditorTarget),YH=()=>z0(($)=>$.app.sessionSelectorData),QH=()=>z0(($)=>$.app.awaitingSecondCtrlC),M4=()=>z0(($)=>$.app.actions),L5=()=>z0(($)=>$.app.initializationStatus==="ready"),XH=()=>z0(($)=>$.app.todos.length>0),O3=()=>z0(($)=>$.config.config?.permissionMode||"default"),JH=()=>z0(($)=>$.config.config?.models??FV),w5=()=>z0(($)=>{let Z=$.config.config;if(!Z)return;let Y=Z.currentModelId;return Z.models.find((X)=>X.id===Y)??Z.models[0]}),GH=()=>z0(($)=>$.config.config?.currentModelId),o0=()=>z0(($)=>{return E$.getTheme()}),qH=()=>z0(($)=>$.config.config?.theme??"default"),_1=()=>z0(($)=>$.focus.currentFocus),KH=()=>z0(($)=>$.focus.actions),j4=()=>z0(($)=>$.command.isProcessing),WH=()=>z0(($)=>$.command.actions),UH=()=>z0(($)=>$.command.pendingCommands),A5=()=>z0(($)=>$.app.thinkingModeEnabled),HH=()=>z0(($)=>$.session.currentThinkingContent),OH=()=>z0(($)=>$.session.thinkingExpanded),FH=()=>z0(($)=>$.session.currentStreamingMessageId),_H=()=>z0(rU(($)=>({lines:$.session.currentStreamingLines,tail:$.session.currentStreamingTail,lineCount:$.session.currentStreamingLineCount,version:$.session.currentStreamingVersion}))),zH=()=>z0(($)=>$.session.finalizingStreamingMessageId),BH=()=>z0(($)=>$.session.historyExpanded),NH=()=>z0(($)=>$.session.expandedMessageCount),LH=()=>z0(rU(($)=>{let Z=$.spec.currentSpec;if(!Z)return{phase:null,completed:0,total:0};let Y=Z.tasks??[],Q=Y.filter((X)=>X.status==="completed").length;return{phase:Z.phase,completed:Q,total:Y.length}}));b0();K1();Y0();t9();import{useMemoizedFn as T4}from"ahooks";import{useEffect as VH,useRef as E6}from"react";W8();b0();y3();t7();Q2();H6();import{useMemoizedFn as wH}from"ahooks";import{useRef as AH}from"react";function bH($){let Z=AH(void 0),Y=AH(void 0),Q=wH(async(J)=>{let G=J?.sessionId??$.sessionId,q=!!J?.modelId&&J.modelId!==$.modelId,K;if(!q&&G){if(Y.current&&Y.current.sessionId!==G)await Y.current.dispose(),Y.current=void 0;if(!Y.current)Y.current=await V2.create({sessionId:G,modelId:J?.modelId??$.modelId});else await Y.current.refresh({modelId:J?.modelId??$.modelId});K=await n0.createWithRuntime(Y.current,{sessionId:G,systemPrompt:J?.systemPrompt??$.systemPrompt,appendSystemPrompt:J?.appendSystemPrompt??$.appendSystemPrompt,maxTurns:J?.maxTurns??$.maxTurns,modelId:J?.modelId??$.modelId})}else K=await n0.create({systemPrompt:J?.systemPrompt??$.systemPrompt,appendSystemPrompt:J?.appendSystemPrompt??$.appendSystemPrompt,maxTurns:J?.maxTurns??$.maxTurns,modelId:J?.modelId??$.modelId});return Z.current=K,K}),X=wH(()=>{if(Z.current)Z.current=void 0});return{agentRef:Z,createAgent:Q,cleanupAgent:X}}var RH=p("UI");function _V($){if(!($ instanceof Error))return"未知错误";let Q=$.lastError??$;if(Q.responseBody)try{let G=JSON.parse(Q.responseBody)?.error?.message;if(G){let q=Q.statusCode?` (HTTP ${Q.statusCode})`:"";return`${G}${q}`}}catch{}let X=$.message.match(/Last error:\s*(.+)$/);if(X)return X[1];return $.message}function zV($,Z,Y,Q){switch($){case"show_theme_selector":return Y.setActiveModal("themeSelector"),!0;case"show_model_selector":return Y.setActiveModal("modelSelector"),!0;case"show_model_add_wizard":return Y.setActiveModal("modelAddWizard"),!0;case"show_permissions_manager":return Y.setActiveModal("permissionsManager"),!0;case"show_agents_manager":return Y.setActiveModal("agentsManager"),!0;case"show_skills_manager":return Y.setActiveModal("skillsManager"),!0;case"show_hooks_manager":return Y.setActiveModal("hooksManager"),!0;case"show_plugins_manager":return Y.setActiveModal("pluginsManager"),!0;case"show_agent_creation_wizard":return Y.setActiveModal("agentCreationWizard"),!0;case"show_session_selector":{let X=Z?.sessions;return Y.showSessionSelector(X),!0}case"clear_screen":return Q.clearMessages(),Q.setError(null),Q.resetTokenUsage(),Y.setTodos([]),!0;case"compact_completed":case"compact_fallback":return Q.resetTokenUsage(),!0;case"exit_application":return H3(0),!0;default:return!1}}function BV($){return typeof $==="object"&&$!==null&&$.action==="invoke_once_model"&&typeof $.modelId==="string"&&typeof $.prompt==="string"}function NV($){return typeof $==="object"&&$!==null&&$.action==="invoke_skill"&&typeof $.skillName==="string"}function LV($){return typeof $==="object"&&$!==null&&$.action==="invoke_custom_command"&&typeof $.commandName==="string"&&typeof $.processedContent==="string"}function wV($){return typeof $==="object"&&$!==null&&$.action==="invoke_plugin_command"&&typeof $.commandName==="string"&&typeof $.processedContent==="string"}function AV($){let{text:Z,images:Y,parts:Q}=$;if(Y.length===0)return Z;let X=[];for(let J of Q)if(J.type==="text")X.push({type:"text",text:J.text});else X.push({type:"image_url",image_url:{url:`data:${J.mimeType};base64,${J.base64}`}});return X}var DH=($,Z,Y,Q)=>{let X=j4(),J=B5(),G=aU(),q=O3(),K=A5(),W=D4(),U=M4(),H=WH(),O=E6(!1),{createAgent:F,cleanupAgent:_}=bH({sessionId:G,systemPrompt:$,appendSystemPrompt:Z,maxTurns:Q}),z=300,N=5,B=400,L=E6(""),A=E6(null),R=E6(""),V=E6(null),M=T4(()=>{if(L.current){let I=L.current,j=W.appendAssistantContent(I);F9(j,I),L.current=""}if(A.current)clearTimeout(A.current),A.current=null}),T=T4(()=>{if(R.current)W.appendThinkingContent(R.current),R.current="";if(V.current)clearTimeout(V.current),V.current=null}),w=(I)=>{let j=0;for(let D of I)if(D===`
|
|
2797
|
+
`)j++;return j},v=T4((I)=>{L.current+=I;let j=L.current;if(w(j)>=5||j.length>=400){M();return}if(!A.current)A.current=setTimeout(M,300)}),l=T4((I)=>{R.current+=I;let j=R.current;if(w(j)>=5||j.length>=400){T();return}if(!V.current)V.current=setTimeout(T,300)}),o=T4(()=>{if(L.current="",A.current)clearTimeout(A.current),A.current=null;if(R.current="",V.current)clearTimeout(V.current),V.current=null});VH(()=>{return()=>{_(),o()}},[_,o]),VH(()=>{if(!K)W.setCurrentThinkingContent(null)},[K,W]);let S=T4(()=>{if(!X)return;M(),T(),H.abort(),U.setTodos([]);let I=X0().session.currentStreamingMessageId;if(I)_9(I);if(W.finalizeStreamingMessage(),!O.current)W.addAssistantMessage("✋ 任务已停止"),O.current=!0}),y=T4(async(I)=>{let{text:j}=I,D=!1,i;try{if(Y3(j)){await _2();let O0=H.createAbortController(),G$={cwd:process.cwd(),signal:O0.signal},F0=await Q3(j,G$);if(F0.message){if(zV(F0.message,F0.data,U,W))return{success:!0}}let O2=!1;if(NV(F0.data)){let{skillName:k$,skillArgs:z1}=F0.data,d1=z1?`Please use the "${k$}" skill to help me with: ${z1}`:`Please use the "${k$}" skill.`;W.addUserMessage(d1),D=!0,O2=!0,I={displayText:d1,text:d1,images:[],parts:[{type:"text",text:d1}]}}if(LV(F0.data)){let{commandName:k$,processedContent:z1}=F0.data;W.addUserMessage(j),D=!0,O2=!0;let d1=`# Custom Command: /${k$}
|
|
2798
2798
|
|
|
2799
2799
|
The user has invoked the custom command "/${k$}". Follow the instructions below to complete the task.
|
|
2800
2800
|
|
|
@@ -2816,7 +2816,7 @@ ${d1}
|
|
|
2816
2816
|
|
|
2817
2817
|
Remember: Follow the above instructions carefully to complete the user's request.`;I={displayText:j,text:m6,images:[],parts:[{type:"text",text:m6}]}}if(BV(F0.data)){let{modelId:k$,prompt:z1}=F0.data;W.addUserMessage(z1),D=!0,O2=!0,i=k$,I={displayText:z1,text:z1,images:[],parts:[{type:"text",text:z1}]}}if(!O2){if(!F0.success&&F0.error)return W.addAssistantMessage(`❌ ${F0.error}`),{success:F0.success,output:F0.message,error:F0.error,metadata:F0.data};let k$=F0.message;if(F0.success&&typeof k$==="string"&&k$.trim()!=="")W.addAssistantMessage(k$);return{success:F0.success,output:F0.message,error:F0.error,metadata:F0.data}}}let g=T0.getInstance(),k=I,e,C=await g.executeUserPromptSubmitHooks(I.text,{projectDir:process.cwd(),sessionId:G,permissionMode:q,hasImages:I.images.length>0,imageCount:I.images.length});if(!C.proceed){if(C.warning)W.addAssistantMessage(`⚠️ ${C.warning}`);return{success:!1,error:"blocked by hook"}}if(C.updatedPrompt)k={...I,text:C.updatedPrompt,displayText:C.updatedPrompt,parts:[{type:"text",text:C.updatedPrompt}]};if(C.contextInjection)e=C.contextInjection;if(!D)W.addUserMessage(k.displayText);let r=AV(k),h=H.createAbortController(),c=await F(i?{modelId:i}:void 0);if(h.signal.aborted)return RH.info("[handleCommandSubmit] Agent 创建期间已被中止"),{success:!1,error:"aborted"};let j0=J.map((O0)=>({role:O0.role,content:O0.content}));if(e)j0.push({role:"system",content:`<user-prompt-submit-hook>
|
|
2818
2818
|
${e}
|
|
2819
|
-
</user-prompt-submit-hook>`});let E0={messages:j0,userId:"cli-user",sessionId:G,workspaceRoot:process.cwd(),signal:h.signal,confirmationHandler:Y,permissionMode:q},g0=0,i0=0,s$=0,M3={stream:!0,onContentDelta:(O0)=>{g0++,i0+=O0.length,y1("useCommandHandler","onContentDelta",{callCount:g0,deltaLen:O0.length,totalLen:i0}),v(O0)},onThinkingDelta:K?(O0)=>{l(O0)}:void 0,onThinking:K?(O0)=>{W.setCurrentThinkingContent(O0)}:void 0,onStreamEnd:()=>{if(y1("useCommandHandler","onStreamEnd",{contentDeltaCallCount:g0,contentDeltaTotalLen:i0,remainingBuffer:L.current.length}),A.current)clearTimeout(A.current),A.current=null;if(V.current)clearTimeout(V.current),V.current=null;let O0=L.current,G$=R.current;L.current="",R.current="";let F0=X0().session.currentStreamingMessageId;if(F0){if(O0)F5(F0,O0);_5(F0)}W.finalizeStreamingMessage(O0,G$)},onContent:(O0)=>{if(s$++,!O0.trim())return;y1("useCommandHandler","onContent (non-stream)",{callCount:s$,contentLen:O0.length}),W.addAssistantMessageAndClearThinking(O0)},onToolStart:(O0)=>{if(O0.type!=="function")return;if(O0.function.name==="TodoWrite")return;try{let G$=JSON.parse(O0.function.arguments),F0=K8(O0.function.name,G$);W.addToolMessage(F0,{toolName:O0.function.name,phase:"start",summary:F0,params:G$})}catch(G$){RH.error("[useCommandHandler] onToolStart error:",G$)}},onToolResult:async(O0,G$)=>{if(O0.type!=="function")return;let F0=G$.metadata?.summary;if(!F0)return;let O2;if(o7(O0.function.name,G$))O2=s7(O0.function.name,G$)||G$.displayContent;W.addToolMessage(F0,{toolName:O0.function.name,phase:"complete",summary:F0,detail:O2})},onTokenUsage:(O0)=>{W.updateTokenUsage(O0)},onCompacting:(O0)=>{if(W.setCompacting(O0),!O0)W.resetTokenUsage()},onTurnLimitReached:Y?async(O0)=>{let G$=await Y.requestConfirmation({type:"maxTurnsExceeded",title:"对话轮次上限",message:`已进行 ${O0.turnsCount} 轮对话。是否继续?`,risks:["继续执行可能导致更长的等待时间","可能产生更多的 API 费用"]});return{continue:G$.approved,reason:G$.reason}}:void 0},t2=await c.chat(r,E0,M3);if(!t2||t2.trim()===""){if(!O.current&&g0===0)return W.addAssistantMessage("⏹ 已取消"),{success:!0,output:"已取消"};return{success:!0,output:t2??""}}return{success:!0,output:t2}}catch(g){if(O.current)return{success:!1,error:"aborted"};let k=_V(g),e=g instanceof Error?g.message:"",C=e.includes("can only concatenate str")||e.includes("image_url")||e.includes("multimodal")||e.includes("vision")||e.includes("does not support images"),r=k;if(C)r="当前模型不支持图片理解功能。请切换到支持视觉能力的模型(如 Claude 4.5、GPT-5.2、Gemini 3 Pro、Qwen3-VL-Plus 等)后重试。";let h={success:!1,error:r};return W.addAssistantMessage(`❌ ${r}`),h}}),m=T4(async(I)=>{if(!I.text.trim()&&I.images.length===0)return;if(X){H.enqueueCommand({displayText:I.displayText,text:I.text,images:I.images,parts:I.parts});return}U.setTodos([]),O.current=!1;let j=H.createAbortController();o(),W.clearFinalizingStreamingMessageId(),H.setProcessing(!0);try{let D=await y(I);if(!D.success&&D.error&&D.error!=="aborted")W.setError(D.error)}catch(D){if(D instanceof Error&&(D.name==="AbortError"||D.message.includes("aborted")));else{let i=D instanceof Error?D.message:"未知错误";W.setError(`执行失败: ${i}`)}}finally{if(H.getAbortController()===j){H.setProcessing(!1),H.clearAbortController(j),W.setCurrentThinkingContent(null);let g=H.dequeueCommand();if(g)setTimeout(()=>m({displayText:g.displayText,text:g.text,images:g.images,parts:g.parts}),100)}}});return{executeCommand:m,handleAbort:S,isProcessing:X}};import{useMemoizedFn as b9}from"ahooks";import{useState as MH}from"react";var jH=()=>{let[$,Z]=MH([]),[Y,Q]=MH(-1),X=b9((K,W)=>{let U={display:K,pasteMappings:W?new Map(W):new Map};Z((H)=>[...H,U]),Q(-1)}),J=b9(()=>{if($.length===0)return null;let K=Y===-1?$.length-1:Math.max(0,Y-1);return Q(K),$[K]||null}),G=b9(()=>{if(Y===-1)return null;let K=Y+1;if(K>=$.length)return Q(-1),null;else return Q(K),$[K]||null}),q=b9(()=>{Q(-1)});return{commandHistory:$,historyIndex:Y,addToHistory:X,getPreviousCommand:J,getNextCommand:G,resetHistoryIndex:q}};import{useMemoizedFn as qQ}from"ahooks";import{useMemo as bV,useRef as TH,useState as VV}from"react";var yH=()=>{let[$,Z]=VV({isVisible:!1,details:null,resolver:null}),Y=TH(null),Q=TH([]),X=qQ((K)=>{Y.current=K,Z({isVisible:Boolean(K),details:K?.details??null,resolver:K?.resolve??null})}),J=qQ((K)=>{return new Promise((W)=>{let U={details:K,resolve:W};if(!Y.current){X(U);return}Q.current.push(U)})}),G=qQ((K)=>{if(Y.current)Y.current.resolve(K);let W=Q.current.shift()??null;X(W)}),q=bV(()=>({requestConfirmation:J}),[J]);return{confirmationState:$,confirmationHandler:q,handleResponse:G}};import{useMemoizedFn as z8}from"ahooks";import{useRef as EH,useState as RV}from"react";var V9="␞",R9="␟";function D9($){return`${V9}PASTE:${$}:`}function KQ(){return R9}var pl=new RegExp(`${V9}PASTE:(\\d+):[\\s\\S]*?${R9}`,"g");function DV($){return $.includes(V9)&&$.includes(R9)}function IH($="",Z=0){let[Y,Q]=RV({value:$,cursorPosition:Z}),X=EH(0),J=EH(new Map),G=z8((F)=>{Q((_)=>({value:F,cursorPosition:_.cursorPosition}));for(let _ of J.current.keys()){let z=D9(_);if(!F.includes(z))J.current.delete(_)}}),q=z8((F)=>{Q((_)=>({..._,cursorPosition:Math.max(0,Math.min(F,_.value.length))}))}),K=z8(()=>{Q({value:"",cursorPosition:0}),J.current.clear()}),W=z8((F)=>{X.current+=1;let _=X.current;return J.current.set(_,{type:"text",data:F}),_}),U=z8((F,_)=>{X.current+=1;let z=X.current;return J.current.set(z,{type:"image",data:F,mimeType:_}),z}),H=z8((F)=>{for(let[_,z]of F)if(J.current.set(_,z),_>=X.current)X.current=_}),O=z8((F)=>{let _=[],z=[];if(!DV(F)){let v=F.trim();if(v)z.push({type:"text",text:v});return{displayText:F,text:F,images:_,parts:z}}let N=new RegExp(`${V9}PASTE:(\\d+):[\\s\\S]*?${R9}`,"g"),B=Array.from(F.matchAll(N)),L=0,A="",R="";for(let v of B){let l=v.index,o=l+v[0].length,S=parseInt(v[1],10),y=J.current.get(S);if(l>L){let m=F.slice(L,l);z.push({type:"text",text:m}),A+=m,R+=m}if(!y)A+=v[0],R+=v[0],z.push({type:"text",text:v[0]});else if(y.type==="text")A+=y.data,R+=y.data,z.push({type:"text",text:y.data});else{let m={id:S,base64:y.data,mimeType:y.mimeType};_.push(m),z.push({type:"image",...m}),R+=`[Image #${S}]`}L=o}if(L<F.length){let v=F.slice(L);z.push({type:"text",text:v}),A+=v,R+=v}let V=[];for(let v of z)if(v.type==="text"&&V.length>0&&V[V.length-1].type==="text")V[V.length-1].text+=v.text;else V.push(v);let M=0,T=V.length;while(M<V.length&&V[M].type==="text"&&V[M].text.trim()==="")M++;while(T>M&&V[T-1].type==="text"&&V[T-1].text.trim()==="")T--;let w=V.slice(M,T);return{displayText:R.trim(),text:A.trim(),images:_,parts:w}});return{value:Y.value,cursorPosition:Y.cursorPosition,setValue:G,setCursorPosition:q,clear:K,pasteMap:J.current,addPasteMapping:W,addImagePasteMapping:U,restorePasteMappings:H,resolveInput:O}}Y0();W8();import{useMemoizedFn as fH}from"ahooks";import{useInput as PV}from"ink";import{useEffect as hH,useRef as xH,useState as OQ}from"react";K6();Q6();import MV from"fast-glob";import jV from"fuse.js";import{useEffect as PH,useMemo as WQ,useState as UQ}from"react";var F3=null,TV=5000;function yV($,Z){let Y=[...$.matchAll(/(?:^|\s)(@(?:"[^"]*"|(?:[^\\ ]|\\ )*))/g)];for(let Q of Y){let X=Q[1],J=Q.index+(Q[0].length-X.length),G=J+X.length;if(Z>=J&&Z<=G){let q=X.slice(1),K=!1;if(q.startsWith('"')){if(K=!0,q=q.slice(1),q.endsWith('"'))q=q.slice(0,-1)}return{hasQuery:!0,query:q,startIndex:J,endIndex:G,quoted:K}}}return{hasQuery:!1,query:"",startIndex:-1,endIndex:-1,quoted:!1}}var EV=[...H1.map(($)=>`${$}/**`),...H1,...d8.map(($)=>`**/${$}`)];function vH($,Z,Y={}){let{cwd:Q=process.cwd(),maxSuggestions:X=15,ignorePatterns:J=EV,debounceDelay:G=300,fuzzyMatch:q=!0}=Y,[K,W]=UQ([]),[U,H]=UQ(!1),[O,F]=UQ(0),_=WQ(()=>JSON.stringify(J),[J]),z=WQ(()=>{if(Z===void 0)return{hasQuery:!1,query:"",startIndex:-1,endIndex:-1,quoted:!1};return yV($,Z)},[$,Z]);PH(()=>{if(!$.includes("@")){W([]),H(!1);return}let B=Date.now();if(F3&&F3.cwd===Q&&F3.ignoreKey===_&&B-F3.timestamp<TV){W(F3.files),H(!1);return}let L=!1,R=setTimeout(async()=>{H(!0);try{let M=(await MV("**/*",{cwd:Q,dot:!1,followSymbolicLinks:!1,onlyFiles:!1,markDirectories:!0,unique:!0,ignore:J})).map((T)=>T.replace(/\\/g,"/"));if(!L)W(M),F3={cwd:Q,ignoreKey:_,files:M,timestamp:B}}catch(V){if(console.error("Failed to load files for @ completion:",V),!L)W([])}finally{if(!L)H(!1)}},G);return()=>{L=!0,clearTimeout(R)}},[$,Q,G,_]);let N=WQ(()=>{if(!z.hasQuery||K.length===0)return[];let B=z.query.toLowerCase();if(B==="")return K.slice(0,X);if(q)return new jV(K,{threshold:0.4,ignoreLocation:!0,minMatchCharLength:1}).search(B).slice(0,X).map((R)=>R.item);return K.filter((L)=>L.toLowerCase().includes(B)).slice(0,X)},[z,K,X,q]);return PH(()=>{F(0)},[N]),{...z,suggestions:N,selectedIndex:O,loading:U}}function IV($,Z=!1){if($.includes(" ")||Z)return`@"${$}"`;return`@${$}`}function HQ($,Z,Y){if(!Z.hasQuery)return{newInput:$,newCursorPos:$.length};let Q=IV(Y,Z.quoted),X=$.slice(0,Z.startIndex),J=$.slice(Z.endIndex),G=X+Q+" "+J,q=Z.startIndex+Q.length+1;return{newInput:G,newCursorPos:q}}import{useMemoizedFn as CH}from"ahooks";import{useEffect as kH,useRef as SH}from"react";b0();var W$=($,Z)=>{let Y=SH(!1),Q=SH(null),X=CH(()=>{if(Q.current)clearTimeout(Q.current);Q.current=setTimeout(()=>{v2().setAwaitingSecondCtrlC(!1),Y.current=!1,Q.current=null},3000)}),J=()=>{_8().shutdown("SIGINT",0)},G=CH(()=>{if(!Y.current){if(Y.current=!0,$&&Z)Z();v2().setAwaitingSecondCtrlC(!0),X()}else{if(Q.current)clearTimeout(Q.current),Q.current=null;v2().setAwaitingSecondCtrlC(!1),J()}});return kH(()=>{if($){if(v2().setAwaitingSecondCtrlC(!1),Y.current=!1,Q.current)clearTimeout(Q.current),Q.current=null}},[$]),kH(()=>{return()=>{if(Q.current)clearTimeout(Q.current)}},[]),G};var M9=p("UI"),pH=($,Z,Y,Q,X,J,G,q,K,W)=>{let H=_1()==="main-input",O=$.value,F=$.setValue,_=$.cursorPosition,z=D4(),N=M4(),B=w9(),L=B?_4(B):!1,[A,R]=OQ(!1),[V,M]=OQ([]),[T,w]=OQ(0),v=vH(O,_,{cwd:process.cwd(),maxSuggestions:10}),l=W$(G||!1,J),o=xH(0),S=500,y=xH(!1);hH(()=>{if(G)y.current=!1},[G]),hH(()=>{if(v.hasQuery&&v.suggestions.length>0){let j=v.suggestions.map((D)=>({command:D,description:KG(D)?`Directory: ${D}`:`File: ${D}`,matchScore:1}));M(j),R(!0),w(0)}else if(O.startsWith("/"))if(O.includes(" "))R(!1),M([]);else{let D=$9(O);M(D),R(D.length>0),w(0)}else R(!1),M([])},[O,v.hasQuery,v.suggestions]);let m=fH(()=>{z.clearMessages(),z.setError(null)}),I=fH(()=>{M9.debug("[DIAG] handleSubmit called:",{input:O,showSuggestions:A});let j=O.trim();if(j){let D=$.resolveInput(j);M9.debug("[DIAG] Submitting command:",{displayText:j,textLength:D.text.length,imageCount:D.images.length}),R(!1),M([]);let i=$.pasteMap.size>0?new Map($.pasteMap):new Map;X(j,i),$.clear(),Z(D),M9.debug("[DIAG] Command submitted to onSubmit callback")}else M9.debug("[DIAG] Empty command, not submitting")});return PV((j,D)=>{if(j==="?"&&!O){K?.(),setTimeout(()=>$.clear(),0);return}if(D.backspace||D.delete||D.leftArrow||D.rightArrow||D.pageUp||D.pageDown||!D.ctrl&&!D.meta&&!D.escape&&!D.tab&&!D.upArrow&&!D.downArrow&&!D.return&&!(j==="?"&&!O))return;if(D.ctrl&&j==="c"||D.meta&&j==="c"||D.ctrl&&j==="d"||D.meta&&j==="d"){l();return}if(D.ctrl&&j==="l"||D.meta&&j==="l"){m();return}if(D.ctrl&&j==="t"||D.meta&&j==="t"){z.toggleThinkingExpanded();return}if(D.ctrl&&j==="o"||D.meta&&j==="o"){z.toggleHistoryExpanded();return}if(D.escape){if(W)K?.();else if(G&&J){if(y.current)return;y.current=!0,J()}else if(A)R(!1),M([]);else if(O){let g=Date.now();if(g-o.current<500)$.clear(),o.current=0;else o.current=g}return}if(D.tab&&D.shift){q?.();return}if(D.tab){if(A&&V.length>0){let g=V[T].command;if(v.hasQuery&&v.suggestions.includes(g)){let{newInput:k,newCursorPos:e}=HQ(O,v,g);F(k),$.setCursorPosition(e)}else{let k=g+" ";F(k),$.setCursorPosition(k.length)}R(!1),M([])}else if(L)N.toggleThinkingMode();return}if(D.return){if(A&&V.length>0){let g=V[T].command;if(v.hasQuery&&v.suggestions.includes(g)){let{newInput:k,newCursorPos:e}=HQ(O,v,g);F(k),$.setCursorPosition(e)}else{let k=g+" ";F(k),$.setCursorPosition(k.length)}R(!1),M([])}else I();return}if(D.upArrow){if(A&&V.length>0){let g=V.length-1;w((k)=>k>0?k-1:g)}else{let g=Y();if(g){if(g.pasteMappings.size>0)$.restorePasteMappings(g.pasteMappings);F(g.display),$.setCursorPosition(g.display.length)}}return}if(D.downArrow){if(A&&V.length>0){let g=V.length-1;w((k)=>k<g?k+1:0)}else{let g=Q();if(g){if(g.pasteMappings.size>0)$.restorePasteMappings(g.pasteMappings);F(g.display),$.setCursorPosition(g.display.length)}}return}},{isActive:H}),{handleSubmit:I,showSuggestions:A,suggestions:V,selectedSuggestionIndex:T}};import fV from"ansi-escapes";import{useStdout as hV}from"ink";import{useCallback as xV,useEffect as pV,useRef as mV}from"react";import{useStdout as vV}from"ink";import{debounce as CV}from"lodash-es";import{useEffect as kV,useState as SV}from"react";function _3($=200){let{stdout:Z}=vV(),[Y,Q]=SV(Z.columns||80);return kV(()=>{let X=CV(()=>{Q(Z.columns||80)},$);return X(),Z.on("resize",X),()=>{Z.off("resize",X),X.cancel()}},[Z,$]),Y}function mH(){let{stdout:$}=hV(),Z=_3(),Y=mV(!0),Q=z0((J)=>J.session.actions.incrementClearCount),X=xV(()=>{if($)$.write(fV.clearTerminal);Q()},[$,Q]);return pV(()=>{if(Y.current){Y.current=!1;return}let J=setTimeout(()=>{X()},300);return()=>{clearTimeout(J)}},[Z,X]),{refreshStatic:X}}Q2();import gH from"node:fs";import gV from"node:os";import FQ from"node:path";import{MultiSelect as uV}from"@inkjs/ui";import{useMemoizedFn as j9}from"ahooks";import{Box as J0,Text as $0,useFocus as dV,useFocusManager as cV,useInput as dH}from"ink";import T9 from"ink-select-input";import lV from"ink-spinner";import I6 from"ink-text-input";import{useEffect as uH,useState as z3}from"react";import{jsxDEV as P}from"react/jsx-dev-runtime";var iV=[{label:"\uD83D\uDD0D Glob - 文件搜索",value:"Glob"},{label:"\uD83D\uDD0E Grep - 内容搜索",value:"Grep"},{label:"\uD83D\uDCD6 Read - 读取文件",value:"Read"},{label:"✍️ Write - 写入文件",value:"Write"},{label:"✏️ Edit - 编辑文件",value:"Edit"},{label:"\uD83D\uDCBB Bash - 执行命令",value:"Bash"},{label:"✅ 所有工具 (不限制)",value:"all"}],rV=[{label:"\uD83D\uDD34 红色 (red)",value:"red"},{label:"\uD83D\uDD35 蓝色 (blue)",value:"blue"},{label:"\uD83D\uDFE2 绿色 (green)",value:"green"},{label:"\uD83D\uDFE1 黄色 (yellow)",value:"yellow"},{label:"\uD83D\uDFE3 紫色 (purple)",value:"purple"},{label:"\uD83D\uDFE0 橙色 (orange)",value:"orange"},{label:"\uD83E\uDE77 粉色 (pink)",value:"pink"},{label:"\uD83E\uDE75 青色 (cyan)",value:"cyan"},{label:"⚪ 不设置颜色",value:"none"}];function aV($){if(!$||$.trim()==="")return"名称不能为空";if(!/^[a-z0-9-]+$/.test($))return"名称只能包含小写字母、数字和连字符";if($.startsWith("-")||$.endsWith("-"))return"名称不能以连字符开头或结尾";return null}function P6({onComplete:$,onCancel:Z,initialConfig:Y}){let[Q,X]=z3(Y?"name":"mode"),[J,G]=z3({name:Y?.name||"",description:Y?.description||"",tools:Y?.tools||[],color:Y?.color,location:Y?.location||"project",systemPrompt:Y?.systemPrompt||""}),[q,K]=z3(""),[W,U]=z3(!1),[H,O]=z3(""),[F,_]=z3(Y?"edit":"manual"),{focus:z}=cV(),B={manual:["mode","name","description","tools","color","location","systemPrompt","confirm"],ai:["mode","aiPrompt","aiGenerating","confirm"],edit:["name","description","tools","color","location","systemPrompt","confirm"]}[F];uH(()=>{if(Q==="name"||Q==="description"||Q==="systemPrompt"||Q==="aiPrompt")return;z(`step-${Q}`)},[Q,z]);let L=j9(()=>{let T=B.indexOf(Q);if(T<B.length-1)X(B[T+1])}),A=j9(()=>{if(H)O("");if(Q==="confirm"&&F==="ai"){X("aiPrompt");return}let T=B.indexOf(Q);if(T>0)X(B[T-1]);else Z()}),R=j9(async()=>{U(!0),O("");try{let T=await n0.create(),w=`你是一个 Subagent 配置生成专家。用户会描述他们想要创建的 agent,你需要根据描述生成一个完整的 agent 配置。
|
|
2819
|
+
</user-prompt-submit-hook>`});let E0={messages:j0,userId:"cli-user",sessionId:G,workspaceRoot:process.cwd(),signal:h.signal,confirmationHandler:Y,permissionMode:q},g0=0,i0=0,s$=0,M3={stream:!0,onContentDelta:(O0)=>{g0++,i0+=O0.length,y1("useCommandHandler","onContentDelta",{callCount:g0,deltaLen:O0.length,totalLen:i0}),v(O0)},onThinkingDelta:K?(O0)=>{l(O0)}:void 0,onThinking:K?(O0)=>{W.setCurrentThinkingContent(O0)}:void 0,onStreamEnd:()=>{if(y1("useCommandHandler","onStreamEnd",{contentDeltaCallCount:g0,contentDeltaTotalLen:i0,remainingBuffer:L.current.length}),A.current)clearTimeout(A.current),A.current=null;if(V.current)clearTimeout(V.current),V.current=null;let O0=L.current,G$=R.current;L.current="",R.current="";let F0=X0().session.currentStreamingMessageId;if(F0){if(O0)F9(F0,O0);_9(F0)}W.finalizeStreamingMessage(O0,G$)},onContent:(O0)=>{if(s$++,!O0.trim())return;y1("useCommandHandler","onContent (non-stream)",{callCount:s$,contentLen:O0.length}),W.addAssistantMessageAndClearThinking(O0)},onToolStart:(O0)=>{if(O0.type!=="function")return;if(O0.function.name==="TodoWrite")return;try{let G$=JSON.parse(O0.function.arguments),F0=K8(O0.function.name,G$);W.addToolMessage(F0,{toolName:O0.function.name,phase:"start",summary:F0,params:G$})}catch(G$){RH.error("[useCommandHandler] onToolStart error:",G$)}},onToolResult:async(O0,G$)=>{if(O0.type!=="function")return;let F0=G$.metadata?.summary;if(!F0)return;let O2;if(o7(O0.function.name,G$))O2=s7(O0.function.name,G$)||G$.displayContent;W.addToolMessage(F0,{toolName:O0.function.name,phase:"complete",summary:F0,detail:O2})},onTokenUsage:(O0)=>{W.updateTokenUsage(O0)},onCompacting:(O0)=>{if(W.setCompacting(O0),!O0)W.resetTokenUsage()},onTurnLimitReached:Y?async(O0)=>{let G$=await Y.requestConfirmation({type:"maxTurnsExceeded",title:"对话轮次上限",message:`已进行 ${O0.turnsCount} 轮对话。是否继续?`,risks:["继续执行可能导致更长的等待时间","可能产生更多的 API 费用"]});return{continue:G$.approved,reason:G$.reason}}:void 0},t2=await c.chat(r,E0,M3);if(!t2||t2.trim()===""){if(!O.current&&g0===0)return W.addAssistantMessage("⏹ 已取消"),{success:!0,output:"已取消"};return{success:!0,output:t2??""}}return{success:!0,output:t2}}catch(g){if(O.current)return{success:!1,error:"aborted"};let k=_V(g),e=g instanceof Error?g.message:"",C=e.includes("can only concatenate str")||e.includes("image_url")||e.includes("multimodal")||e.includes("vision")||e.includes("does not support images"),r=k;if(C)r="当前模型不支持图片理解功能。请切换到支持视觉能力的模型(如 Claude 4.5、GPT-5.2、Gemini 3 Pro、Qwen3-VL-Plus 等)后重试。";let h={success:!1,error:r};return W.addAssistantMessage(`❌ ${r}`),h}}),m=T4(async(I)=>{if(!I.text.trim()&&I.images.length===0)return;if(X){H.enqueueCommand({displayText:I.displayText,text:I.text,images:I.images,parts:I.parts});return}U.setTodos([]),O.current=!1;let j=H.createAbortController();o(),W.clearFinalizingStreamingMessageId(),H.setProcessing(!0);try{let D=await y(I);if(!D.success&&D.error&&D.error!=="aborted")W.setError(D.error)}catch(D){if(D instanceof Error&&(D.name==="AbortError"||D.message.includes("aborted")));else{let i=D instanceof Error?D.message:"未知错误";W.setError(`执行失败: ${i}`)}}finally{if(H.getAbortController()===j){H.setProcessing(!1),H.clearAbortController(j),W.setCurrentThinkingContent(null);let g=H.dequeueCommand();if(g)setTimeout(()=>m({displayText:g.displayText,text:g.text,images:g.images,parts:g.parts}),100)}}});return{executeCommand:m,handleAbort:S,isProcessing:X}};import{useMemoizedFn as b5}from"ahooks";import{useState as MH}from"react";var jH=()=>{let[$,Z]=MH([]),[Y,Q]=MH(-1),X=b5((K,W)=>{let U={display:K,pasteMappings:W?new Map(W):new Map};Z((H)=>[...H,U]),Q(-1)}),J=b5(()=>{if($.length===0)return null;let K=Y===-1?$.length-1:Math.max(0,Y-1);return Q(K),$[K]||null}),G=b5(()=>{if(Y===-1)return null;let K=Y+1;if(K>=$.length)return Q(-1),null;else return Q(K),$[K]||null}),q=b5(()=>{Q(-1)});return{commandHistory:$,historyIndex:Y,addToHistory:X,getPreviousCommand:J,getNextCommand:G,resetHistoryIndex:q}};import{useMemoizedFn as qQ}from"ahooks";import{useMemo as bV,useRef as TH,useState as VV}from"react";var yH=()=>{let[$,Z]=VV({isVisible:!1,details:null,resolver:null}),Y=TH(null),Q=TH([]),X=qQ((K)=>{Y.current=K,Z({isVisible:Boolean(K),details:K?.details??null,resolver:K?.resolve??null})}),J=qQ((K)=>{return new Promise((W)=>{let U={details:K,resolve:W};if(!Y.current){X(U);return}Q.current.push(U)})}),G=qQ((K)=>{if(Y.current)Y.current.resolve(K);let W=Q.current.shift()??null;X(W)}),q=bV(()=>({requestConfirmation:J}),[J]);return{confirmationState:$,confirmationHandler:q,handleResponse:G}};import{useMemoizedFn as z8}from"ahooks";import{useRef as EH,useState as RV}from"react";var V5="␞",R5="␟";function D5($){return`${V5}PASTE:${$}:`}function KQ(){return R5}var pl=new RegExp(`${V5}PASTE:(\\d+):[\\s\\S]*?${R5}`,"g");function DV($){return $.includes(V5)&&$.includes(R5)}function IH($="",Z=0){let[Y,Q]=RV({value:$,cursorPosition:Z}),X=EH(0),J=EH(new Map),G=z8((F)=>{Q((_)=>({value:F,cursorPosition:_.cursorPosition}));for(let _ of J.current.keys()){let z=D5(_);if(!F.includes(z))J.current.delete(_)}}),q=z8((F)=>{Q((_)=>({..._,cursorPosition:Math.max(0,Math.min(F,_.value.length))}))}),K=z8(()=>{Q({value:"",cursorPosition:0}),J.current.clear()}),W=z8((F)=>{X.current+=1;let _=X.current;return J.current.set(_,{type:"text",data:F}),_}),U=z8((F,_)=>{X.current+=1;let z=X.current;return J.current.set(z,{type:"image",data:F,mimeType:_}),z}),H=z8((F)=>{for(let[_,z]of F)if(J.current.set(_,z),_>=X.current)X.current=_}),O=z8((F)=>{let _=[],z=[];if(!DV(F)){let v=F.trim();if(v)z.push({type:"text",text:v});return{displayText:F,text:F,images:_,parts:z}}let N=new RegExp(`${V5}PASTE:(\\d+):[\\s\\S]*?${R5}`,"g"),B=Array.from(F.matchAll(N)),L=0,A="",R="";for(let v of B){let l=v.index,o=l+v[0].length,S=parseInt(v[1],10),y=J.current.get(S);if(l>L){let m=F.slice(L,l);z.push({type:"text",text:m}),A+=m,R+=m}if(!y)A+=v[0],R+=v[0],z.push({type:"text",text:v[0]});else if(y.type==="text")A+=y.data,R+=y.data,z.push({type:"text",text:y.data});else{let m={id:S,base64:y.data,mimeType:y.mimeType};_.push(m),z.push({type:"image",...m}),R+=`[Image #${S}]`}L=o}if(L<F.length){let v=F.slice(L);z.push({type:"text",text:v}),A+=v,R+=v}let V=[];for(let v of z)if(v.type==="text"&&V.length>0&&V[V.length-1].type==="text")V[V.length-1].text+=v.text;else V.push(v);let M=0,T=V.length;while(M<V.length&&V[M].type==="text"&&V[M].text.trim()==="")M++;while(T>M&&V[T-1].type==="text"&&V[T-1].text.trim()==="")T--;let w=V.slice(M,T);return{displayText:R.trim(),text:A.trim(),images:_,parts:w}});return{value:Y.value,cursorPosition:Y.cursorPosition,setValue:G,setCursorPosition:q,clear:K,pasteMap:J.current,addPasteMapping:W,addImagePasteMapping:U,restorePasteMappings:H,resolveInput:O}}Y0();W8();import{useMemoizedFn as fH}from"ahooks";import{useInput as PV}from"ink";import{useEffect as hH,useRef as xH,useState as OQ}from"react";K6();Q6();import MV from"fast-glob";import jV from"fuse.js";import{useEffect as PH,useMemo as WQ,useState as UQ}from"react";var F3=null,TV=5000;function yV($,Z){let Y=[...$.matchAll(/(?:^|\s)(@(?:"[^"]*"|(?:[^\\ ]|\\ )*))/g)];for(let Q of Y){let X=Q[1],J=Q.index+(Q[0].length-X.length),G=J+X.length;if(Z>=J&&Z<=G){let q=X.slice(1),K=!1;if(q.startsWith('"')){if(K=!0,q=q.slice(1),q.endsWith('"'))q=q.slice(0,-1)}return{hasQuery:!0,query:q,startIndex:J,endIndex:G,quoted:K}}}return{hasQuery:!1,query:"",startIndex:-1,endIndex:-1,quoted:!1}}var EV=[...H1.map(($)=>`${$}/**`),...H1,...d8.map(($)=>`**/${$}`)];function vH($,Z,Y={}){let{cwd:Q=process.cwd(),maxSuggestions:X=15,ignorePatterns:J=EV,debounceDelay:G=300,fuzzyMatch:q=!0}=Y,[K,W]=UQ([]),[U,H]=UQ(!1),[O,F]=UQ(0),_=WQ(()=>JSON.stringify(J),[J]),z=WQ(()=>{if(Z===void 0)return{hasQuery:!1,query:"",startIndex:-1,endIndex:-1,quoted:!1};return yV($,Z)},[$,Z]);PH(()=>{if(!$.includes("@")){W([]),H(!1);return}let B=Date.now();if(F3&&F3.cwd===Q&&F3.ignoreKey===_&&B-F3.timestamp<TV){W(F3.files),H(!1);return}let L=!1,R=setTimeout(async()=>{H(!0);try{let M=(await MV("**/*",{cwd:Q,dot:!1,followSymbolicLinks:!1,onlyFiles:!1,markDirectories:!0,unique:!0,ignore:J})).map((T)=>T.replace(/\\/g,"/"));if(!L)W(M),F3={cwd:Q,ignoreKey:_,files:M,timestamp:B}}catch(V){if(console.error("Failed to load files for @ completion:",V),!L)W([])}finally{if(!L)H(!1)}},G);return()=>{L=!0,clearTimeout(R)}},[$,Q,G,_]);let N=WQ(()=>{if(!z.hasQuery||K.length===0)return[];let B=z.query.toLowerCase();if(B==="")return K.slice(0,X);if(q)return new jV(K,{threshold:0.4,ignoreLocation:!0,minMatchCharLength:1}).search(B).slice(0,X).map((R)=>R.item);return K.filter((L)=>L.toLowerCase().includes(B)).slice(0,X)},[z,K,X,q]);return PH(()=>{F(0)},[N]),{...z,suggestions:N,selectedIndex:O,loading:U}}function IV($,Z=!1){if($.includes(" ")||Z)return`@"${$}"`;return`@${$}`}function HQ($,Z,Y){if(!Z.hasQuery)return{newInput:$,newCursorPos:$.length};let Q=IV(Y,Z.quoted),X=$.slice(0,Z.startIndex),J=$.slice(Z.endIndex),G=X+Q+" "+J,q=Z.startIndex+Q.length+1;return{newInput:G,newCursorPos:q}}import{useMemoizedFn as CH}from"ahooks";import{useEffect as kH,useRef as SH}from"react";b0();var W$=($,Z)=>{let Y=SH(!1),Q=SH(null),X=CH(()=>{if(Q.current)clearTimeout(Q.current);Q.current=setTimeout(()=>{v2().setAwaitingSecondCtrlC(!1),Y.current=!1,Q.current=null},3000)}),J=()=>{_8().shutdown("SIGINT",0)},G=CH(()=>{if(!Y.current){if(Y.current=!0,$&&Z)Z();v2().setAwaitingSecondCtrlC(!0),X()}else{if(Q.current)clearTimeout(Q.current),Q.current=null;v2().setAwaitingSecondCtrlC(!1),J()}});return kH(()=>{if($){if(v2().setAwaitingSecondCtrlC(!1),Y.current=!1,Q.current)clearTimeout(Q.current),Q.current=null}},[$]),kH(()=>{return()=>{if(Q.current)clearTimeout(Q.current)}},[]),G};var M5=p("UI"),pH=($,Z,Y,Q,X,J,G,q,K,W)=>{let H=_1()==="main-input",O=$.value,F=$.setValue,_=$.cursorPosition,z=D4(),N=M4(),B=w5(),L=B?_4(B):!1,[A,R]=OQ(!1),[V,M]=OQ([]),[T,w]=OQ(0),v=vH(O,_,{cwd:process.cwd(),maxSuggestions:10}),l=W$(G||!1,J),o=xH(0),S=500,y=xH(!1);hH(()=>{if(G)y.current=!1},[G]),hH(()=>{if(v.hasQuery&&v.suggestions.length>0){let j=v.suggestions.map((D)=>({command:D,description:KG(D)?`Directory: ${D}`:`File: ${D}`,matchScore:1}));M(j),R(!0),w(0)}else if(O.startsWith("/"))if(O.includes(" "))R(!1),M([]);else{let D=$5(O);M(D),R(D.length>0),w(0)}else R(!1),M([])},[O,v.hasQuery,v.suggestions]);let m=fH(()=>{z.clearMessages(),z.setError(null)}),I=fH(()=>{M5.debug("[DIAG] handleSubmit called:",{input:O,showSuggestions:A});let j=O.trim();if(j){let D=$.resolveInput(j);M5.debug("[DIAG] Submitting command:",{displayText:j,textLength:D.text.length,imageCount:D.images.length}),R(!1),M([]);let i=$.pasteMap.size>0?new Map($.pasteMap):new Map;X(j,i),$.clear(),Z(D),M5.debug("[DIAG] Command submitted to onSubmit callback")}else M5.debug("[DIAG] Empty command, not submitting")});return PV((j,D)=>{if(j==="?"&&!O){K?.(),setTimeout(()=>$.clear(),0);return}if(D.backspace||D.delete||D.leftArrow||D.rightArrow||D.pageUp||D.pageDown||!D.ctrl&&!D.meta&&!D.escape&&!D.tab&&!D.upArrow&&!D.downArrow&&!D.return&&!(j==="?"&&!O))return;if(D.ctrl&&j==="c"||D.meta&&j==="c"||D.ctrl&&j==="d"||D.meta&&j==="d"){l();return}if(D.ctrl&&j==="l"||D.meta&&j==="l"){m();return}if(D.ctrl&&j==="t"||D.meta&&j==="t"){z.toggleThinkingExpanded();return}if(D.ctrl&&j==="o"||D.meta&&j==="o"){z.toggleHistoryExpanded();return}if(D.escape){if(W)K?.();else if(G&&J){if(y.current)return;y.current=!0,J()}else if(A)R(!1),M([]);else if(O){let g=Date.now();if(g-o.current<500)$.clear(),o.current=0;else o.current=g}return}if(D.tab&&D.shift){q?.();return}if(D.tab){if(A&&V.length>0){let g=V[T].command;if(v.hasQuery&&v.suggestions.includes(g)){let{newInput:k,newCursorPos:e}=HQ(O,v,g);F(k),$.setCursorPosition(e)}else{let k=g+" ";F(k),$.setCursorPosition(k.length)}R(!1),M([])}else if(L)N.toggleThinkingMode();return}if(D.return){if(A&&V.length>0){let g=V[T].command;if(v.hasQuery&&v.suggestions.includes(g)){let{newInput:k,newCursorPos:e}=HQ(O,v,g);F(k),$.setCursorPosition(e)}else{let k=g+" ";F(k),$.setCursorPosition(k.length)}R(!1),M([])}else I();return}if(D.upArrow){if(A&&V.length>0){let g=V.length-1;w((k)=>k>0?k-1:g)}else{let g=Y();if(g){if(g.pasteMappings.size>0)$.restorePasteMappings(g.pasteMappings);F(g.display),$.setCursorPosition(g.display.length)}}return}if(D.downArrow){if(A&&V.length>0){let g=V.length-1;w((k)=>k<g?k+1:0)}else{let g=Q();if(g){if(g.pasteMappings.size>0)$.restorePasteMappings(g.pasteMappings);F(g.display),$.setCursorPosition(g.display.length)}}return}},{isActive:H}),{handleSubmit:I,showSuggestions:A,suggestions:V,selectedSuggestionIndex:T}};import fV from"ansi-escapes";import{useStdout as hV}from"ink";import{useCallback as xV,useEffect as pV,useRef as mV}from"react";import{useStdout as vV}from"ink";import{debounce as CV}from"lodash-es";import{useEffect as kV,useState as SV}from"react";function _3($=200){let{stdout:Z}=vV(),[Y,Q]=SV(Z.columns||80);return kV(()=>{let X=CV(()=>{Q(Z.columns||80)},$);return X(),Z.on("resize",X),()=>{Z.off("resize",X),X.cancel()}},[Z,$]),Y}function mH(){let{stdout:$}=hV(),Z=_3(),Y=mV(!0),Q=z0((J)=>J.session.actions.incrementClearCount),X=xV(()=>{if($)$.write(fV.clearTerminal);Q()},[$,Q]);return pV(()=>{if(Y.current){Y.current=!1;return}let J=setTimeout(()=>{X()},300);return()=>{clearTimeout(J)}},[Z,X]),{refreshStatic:X}}Q2();import gH from"node:fs";import gV from"node:os";import FQ from"node:path";import{MultiSelect as uV}from"@inkjs/ui";import{useMemoizedFn as j5}from"ahooks";import{Box as J0,Text as $0,useFocus as dV,useFocusManager as cV,useInput as dH}from"ink";import T5 from"ink-select-input";import lV from"ink-spinner";import I6 from"ink-text-input";import{useEffect as uH,useState as z3}from"react";import{jsxDEV as P}from"react/jsx-dev-runtime";var iV=[{label:"\uD83D\uDD0D Glob - 文件搜索",value:"Glob"},{label:"\uD83D\uDD0E Grep - 内容搜索",value:"Grep"},{label:"\uD83D\uDCD6 Read - 读取文件",value:"Read"},{label:"✍️ Write - 写入文件",value:"Write"},{label:"✏️ Edit - 编辑文件",value:"Edit"},{label:"\uD83D\uDCBB Bash - 执行命令",value:"Bash"},{label:"✅ 所有工具 (不限制)",value:"all"}],rV=[{label:"\uD83D\uDD34 红色 (red)",value:"red"},{label:"\uD83D\uDD35 蓝色 (blue)",value:"blue"},{label:"\uD83D\uDFE2 绿色 (green)",value:"green"},{label:"\uD83D\uDFE1 黄色 (yellow)",value:"yellow"},{label:"\uD83D\uDFE3 紫色 (purple)",value:"purple"},{label:"\uD83D\uDFE0 橙色 (orange)",value:"orange"},{label:"\uD83E\uDE77 粉色 (pink)",value:"pink"},{label:"\uD83E\uDE75 青色 (cyan)",value:"cyan"},{label:"⚪ 不设置颜色",value:"none"}];function aV($){if(!$||$.trim()==="")return"名称不能为空";if(!/^[a-z0-9-]+$/.test($))return"名称只能包含小写字母、数字和连字符";if($.startsWith("-")||$.endsWith("-"))return"名称不能以连字符开头或结尾";return null}function P6({onComplete:$,onCancel:Z,initialConfig:Y}){let[Q,X]=z3(Y?"name":"mode"),[J,G]=z3({name:Y?.name||"",description:Y?.description||"",tools:Y?.tools||[],color:Y?.color,location:Y?.location||"project",systemPrompt:Y?.systemPrompt||""}),[q,K]=z3(""),[W,U]=z3(!1),[H,O]=z3(""),[F,_]=z3(Y?"edit":"manual"),{focus:z}=cV(),B={manual:["mode","name","description","tools","color","location","systemPrompt","confirm"],ai:["mode","aiPrompt","aiGenerating","confirm"],edit:["name","description","tools","color","location","systemPrompt","confirm"]}[F];uH(()=>{if(Q==="name"||Q==="description"||Q==="systemPrompt"||Q==="aiPrompt")return;z(`step-${Q}`)},[Q,z]);let L=j5(()=>{let T=B.indexOf(Q);if(T<B.length-1)X(B[T+1])}),A=j5(()=>{if(H)O("");if(Q==="confirm"&&F==="ai"){X("aiPrompt");return}let T=B.indexOf(Q);if(T>0)X(B[T-1]);else Z()}),R=j5(async()=>{U(!0),O("");try{let T=await n0.create(),w=`你是一个 Subagent 配置生成专家。用户会描述他们想要创建的 agent,你需要根据描述生成一个完整的 agent 配置。
|
|
2820
2820
|
|
|
2821
2821
|
## 可用工具列表
|
|
2822
2822
|
|
|
@@ -2890,38 +2890,38 @@ ${e}
|
|
|
2890
2890
|
4. **color**: 选择一个合适的颜色用于 UI 区分
|
|
2891
2891
|
5. **systemPrompt**: 详细说明 agent 的职责、使用的工具、输出格式等,使用 Markdown 格式
|
|
2892
2892
|
|
|
2893
|
-
**重要**:请直接返回 JSON,不要添加任何额外的解释或文字。`,q)).trim(),o=l.match(/```(?:json)?\s*\n([\s\S]*?)\n```/);if(o)l=o[1];let S=JSON.parse(l);if(!S.name||!S.description||!S.systemPrompt)throw Error("Missing required fields: name, description, or systemPrompt");if(!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(S.name))throw Error("Invalid name format. Must be kebab-case (lowercase, numbers, hyphens only)");G({name:S.name,description:S.description,tools:Array.isArray(S.tools)?S.tools:[],color:S.color||"blue",location:"project",systemPrompt:S.systemPrompt}),X("confirm")}catch(T){O(T instanceof Error?T.message:String(T))}finally{U(!1)}});uH(()=>{if(Q==="aiGenerating"&&!W&&!H)R()},[Q,W,H,R]);let V=
|
|
2893
|
+
**重要**:请直接返回 JSON,不要添加任何额外的解释或文字。`,q)).trim(),o=l.match(/```(?:json)?\s*\n([\s\S]*?)\n```/);if(o)l=o[1];let S=JSON.parse(l);if(!S.name||!S.description||!S.systemPrompt)throw Error("Missing required fields: name, description, or systemPrompt");if(!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(S.name))throw Error("Invalid name format. Must be kebab-case (lowercase, numbers, hyphens only)");G({name:S.name,description:S.description,tools:Array.isArray(S.tools)?S.tools:[],color:S.color||"blue",location:"project",systemPrompt:S.systemPrompt}),X("confirm")}catch(T){O(T instanceof Error?T.message:String(T))}finally{U(!1)}});uH(()=>{if(Q==="aiGenerating"&&!W&&!H)R()},[Q,W,H,R]);let V=j5(async()=>{try{let T=J.location==="project"?FQ.join(process.cwd(),".blade","agents"):FQ.join(gV.homedir(),".blade","agents");await gH.promises.mkdir(T,{recursive:!0});let w=["---",`name: ${J.name}`,`description: ${J.description}`];if(J.tools.length>0&&!J.tools.includes("all")){w.push("tools:");for(let o of J.tools)w.push(` - ${o}`)}if(J.color)w.push(`color: ${J.color}`);w.push("---");let v=[w.join(`
|
|
2894
2894
|
`),"",`# ${J.name} Subagent`,"",J.systemPrompt||"你是一个专门的代理,负责执行特定任务。",""].join(`
|
|
2895
|
-
`),l=FQ.join(T,`${J.name}.md`);await gH.promises.writeFile(l,v,"utf-8"),$()}catch(T){console.error("保存配置失败:",T)}}),M=W$(!1,Z);if(dH((T,w)=>{if(w.escape)A();else if(w.ctrl&&T==="c"||w.meta&&T==="c")M()},{isActive:Q!=="tools"}),Q==="mode")return P(J0,{flexDirection:"column",paddingY:1,children:[P(J0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83C\uDFAF 选择创建方式"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{dimColor:!0,children:"你可以手动配置每个细节,或让 AI 根据你的描述自动生成配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(T9,{items:[{label:"\uD83E\uDD16 AI 智能生成 - 根据描述自动生成完整配置",value:"ai"},{label:"✍️ 手动配置 - 逐步配置每个选项",value:"manual"}],onSelect:(T)=>{if(T.value==="ai")_("ai"),X("aiPrompt");else _("manual"),X("name")}},void 0,!1,void 0,this),P(J0,{marginTop:1,children:P($0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 取消"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="aiPrompt")return P(J0,{flexDirection:"column",paddingY:1,children:[P(J0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83E\uDD16 AI 智能生成"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{dimColor:!0,children:'描述你想要创建的 Agent(例如:"一个专门用于代码审查的 agent,能够分析代码质量和潜在bug")'},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:[P($0,{color:"green",children:"描述: "},void 0,!1,void 0,this),P(I6,{value:q,onChange:K,onSubmit:(T)=>{if(!T.trim())return;X("aiGenerating")}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(J0,{children:P($0,{dimColor:!0,children:"按 Enter 开始生成 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="aiGenerating"){if(H)return P(J0,{flexDirection:"column",paddingY:1,children:[P(J0,{marginBottom:1,children:P($0,{bold:!0,color:"red",children:"❌ AI 生成失败"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{color:"red",children:H},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{dimColor:!0,children:"按 ESC 返回修改描述"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return P(J0,{flexDirection:"column",paddingY:1,children:[P(J0,{marginBottom:1,children:P($0,{bold:!0,color:"yellow",children:[P(lV,{type:"dots"},void 0,!1,void 0,this)," AI 正在生成配置..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{dimColor:!0,children:['根据你的描述:"',q,'"']},void 0,!0,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{color:"gray",children:"正在调用 LLM 生成 agent 配置,请稍候..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}if(Q==="name"){let T=F==="edit";return P(J0,{flexDirection:"column",paddingY:1,children:[P(J0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:["\uD83D\uDCDD Step 1/7: ",T?"Agent 名称(不可修改)":"输入 Agent 名称"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{dimColor:!0,children:T?"编辑模式下名称不可修改(修改名称相当于创建新 Agent)":"名称只能包含小写字母、数字和连字符(例如:code-reviewer)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:[P($0,{color:"green",children:"名称: "},void 0,!1,void 0,this),T?P($0,{children:J.name},void 0,!1,void 0,this):P(I6,{value:J.name,onChange:(w)=>G({...J,name:w}),onSubmit:(w)=>{if(aV(w))return;L()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(J0,{children:P($0,{dimColor:!0,children:T?"按 Enter 继续 | ESC 返回":"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this),T&&P(I6,{value:"",onChange:()=>{},onSubmit:L,showCursor:!1},"edit-mode-dummy-input",!1,void 0,this)]},void 0,!0,void 0,this)}if(Q==="description")return P(J0,{flexDirection:"column",paddingY:1,children:[P(J0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83D\uDCDD Step 2/7: 输入描述信息"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{dimColor:!0,children:"简短描述这个 Agent 的用途和使用场景(这将帮助主 Agent 决定何时使用它)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:[P($0,{color:"green",children:"描述: "},void 0,!1,void 0,this),P(I6,{value:J.description,onChange:(T)=>G({...J,description:T}),onSubmit:(T)=>{if(!T.trim())return;L()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(J0,{children:P($0,{dimColor:!0,children:"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="tools")return P(nV,{config:J,setConfig:G,onNext:L,onPrev:A},void 0,!1,void 0,this);if(Q==="color")return P(J0,{flexDirection:"column",paddingY:1,children:[P(J0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83C\uDFA8 Step 4/7: 选择背景颜色"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{dimColor:!0,children:"为 Agent 选择一个颜色标识(用于在 UI 中区分不同的 Agents)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(T9,{items:rV,onSelect:(T)=>{let w=T.value==="none"?void 0:T.value;G({...J,color:w}),L()}},void 0,!1,void 0,this),P(J0,{marginTop:1,children:P($0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="location")return P(J0,{flexDirection:"column",paddingY:1,children:[P(J0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83D\uDCC2 Step 5/7: 选择保存位置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{dimColor:!0,children:"项目级配置仅在当前项目生效,用户级配置全局可用"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(T9,{items:[{label:"\uD83D\uDCC1 项目级 (.blade/agents/) - 仅当前项目",value:"project"},{label:"\uD83C\uDFE0 用户级 (~/.blade/agents/) - 全局可用",value:"user"}],onSelect:(T)=>{G({...J,location:T.value}),L()}},void 0,!1,void 0,this),P(J0,{marginTop:1,children:P($0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="systemPrompt")return P(J0,{flexDirection:"column",paddingY:1,children:[P(J0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83D\uDCAC Step 6/7: 输入系统提示词"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{dimColor:!0,children:"定义 Agent 的行为和职责(可选,留空将使用默认提示)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:[P($0,{color:"green",children:"提示词: "},void 0,!1,void 0,this),P(I6,{value:J.systemPrompt,onChange:(T)=>G({...J,systemPrompt:T}),onSubmit:()=>L()},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(J0,{children:P($0,{dimColor:!0,children:"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="confirm")return P(J0,{flexDirection:"column",paddingY:1,children:[P(J0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"✅ Step 7/7: 确认配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{flexDirection:"column",paddingLeft:2,marginBottom:1,children:[P($0,{children:[P($0,{bold:!0,color:"green",children:["名称:"," "]},void 0,!0,void 0,this),P($0,{children:J.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P($0,{children:[P($0,{bold:!0,color:"green",children:["描述:"," "]},void 0,!0,void 0,this),P($0,{children:J.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P($0,{children:[P($0,{bold:!0,color:"green",children:["工具:"," "]},void 0,!0,void 0,this),P($0,{children:J.tools.includes("all")?"所有工具":J.tools.join(", ")||"所有工具"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P($0,{children:[P($0,{bold:!0,color:"green",children:["颜色:"," "]},void 0,!0,void 0,this),P($0,{children:J.color||"默认"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P($0,{children:[P($0,{bold:!0,color:"green",children:["位置:"," "]},void 0,!0,void 0,this),P($0,{children:J.location==="project"?"项目级":"用户级"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P($0,{children:[P($0,{bold:!0,color:"green",children:["提示词:"," "]},void 0,!0,void 0,this),P($0,{children:J.systemPrompt||"(使用默认)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),P(T9,{items:[{label:"✅ 确认并保存",value:"save"},{label:"⬅️ 返回上一步",value:"back"},{label:"❌ 取消",value:"cancel"}],onSelect:(T)=>{if(T.value==="save")V();else if(T.value==="back")A();else Z()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}function nV({config:$,setConfig:Z,onNext:Y,onPrev:Q}){let{isFocused:X}=dV({id:"step-tools"});dH((G,q)=>{if(q.escape)Q()},{isActive:X});let J=(G)=>{if(G.includes("all"))Z({...$,tools:["all"]});else Z({...$,tools:G});Y()};return P(J0,{flexDirection:"column",paddingY:1,children:[P(J0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83D\uDD27 Step 3/7: 选择可用工具"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{dimColor:!0,children:"方向键导航,空格切换勾选,Enter 确认进入下一步 | ESC 返回上一步"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(uV,{options:iV,defaultValue:$.tools,onSubmit:J},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}z4();import oV from"node:fs";import{useMemoizedFn as N8}from"ahooks";import{Box as s0,Text as Y$,useInput as sV}from"ink";import _Q from"ink-select-input";import{useEffect as tV,useMemo as cH,useState as y9}from"react";import{jsxDEV as t}from"react/jsx-dev-runtime";var zQ=10;function lH({initialMode:$="menu",onComplete:Z,onCancel:Y}){let[Q,X]=y9($),[J,G]=y9(null),[q,K]=y9(0),[W,U]=y9(0),H=N8(()=>{a0.clear(),a0.loadFromStandardLocations(),K((w)=>w+1)}),O=cH(()=>{return a0.getAllSubagents()},[q]),F=Math.ceil(O.length/zQ)||1,_=cH(()=>{let w=W*zQ;return O.slice(w,w+zQ)},[O,W]);tV(()=>{let w=Math.max(0,F-1);if(W>w)U(w)},[F,W]);let z=N8(()=>{if(W<F-1)U((w)=>w+1)}),N=N8(()=>{if(W>0)U((w)=>w-1)}),B=[{key:"list",label:"\uD83D\uDCCB 查看所有 Agents",value:"list"},{key:"create",label:"➕ 创建新 Agent",value:"create"},{key:"edit",label:"✏️ 编辑 Agent",value:"edit"},{key:"delete",label:"\uD83D\uDDD1️ 删除 Agent",value:"delete"},{key:"cancel",label:"❌ 取消",value:"cancel"}],L=N8((w)=>{if(w.value==="cancel"){Y?.();return}X(w.value)}),A=N8((w)=>{if(G(w.value),Q==="edit")X("editWizard");else if(Q==="delete")X("deleteConfirm")}),R=N8(async()=>{if(!J?.configPath)return;try{await oV.promises.unlink(J.configPath),H(),V()}catch(w){console.error("删除失败:",w)}}),V=N8(()=>{X("menu"),G(null)}),M=W$(!1,Y);if(sV((w,v)=>{if(v.escape){if(Q==="menu")Y?.();else if(Q==="list"||Q==="edit"||Q==="delete")U(0),V();else if(Q==="deleteConfirm")V()}else if(v.ctrl&&w==="c"||v.meta&&w==="c")M();else if(Q==="list"){if(v.leftArrow||w==="h")N();else if(v.rightArrow||w==="l")z()}},{isActive:Q!=="create"&&Q!=="editWizard"}),Q==="menu")return t(s0,{flexDirection:"column",paddingY:1,children:[t(s0,{marginBottom:1,children:t(Y$,{bold:!0,color:"cyan",children:"\uD83D\uDCCB Agents 管理"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(_Q,{items:B,onSelect:L},void 0,!1,void 0,this),t(s0,{marginTop:1,children:t(Y$,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 退出"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="list"){if(O.length===0)return t(s0,{flexDirection:"column",paddingY:1,children:[t(s0,{marginBottom:1,children:t(Y$,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(s0,{paddingLeft:2,children:t(Y$,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(s0,{marginTop:1,paddingLeft:2,children:t(Y$,{color:"gray",children:"\uD83D\uDCA1 配置文件位置: .blade/agents/ 或 ~/.blade/agents/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(s0,{marginTop:1,paddingLeft:2,children:t(Y$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return t(s0,{flexDirection:"column",paddingY:1,children:[t(s0,{marginBottom:1,children:[t(Y$,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this),t(Y$,{color:"gray",children:[" (共 ",O.length," 个)"]},void 0,!0,void 0,this),F>1&&t(Y$,{color:"yellow",children:[" ","第 ",W+1,"/",F," 页"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),_.map((w)=>t(s0,{flexDirection:"column",paddingLeft:2,children:[t(s0,{children:t(Y$,{children:[t(Y$,{bold:!0,color:w.color||"white",children:["• ",w.name]},void 0,!0,void 0,this),t(Y$,{color:"gray",children:[" - ",w.description]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),w.tools&&w.tools.length>0&&t(s0,{paddingLeft:2,children:t(Y$,{color:"gray",children:["工具: ",w.tools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),w.configPath&&t(s0,{paddingLeft:2,children:t(Y$,{color:"gray",dimColor:!0,children:w.configPath},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},w.name,!0,void 0,this)),t(s0,{marginTop:1,paddingLeft:2,children:F>1?t(Y$,{dimColor:!0,children:"← → 翻页 | ESC 返回菜单"},void 0,!1,void 0,this):t(Y$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}let T=(w)=>{if(O.length===0)return t(s0,{flexDirection:"column",paddingY:1,children:[t(s0,{marginBottom:1,children:t(Y$,{bold:!0,color:"cyan",children:w},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(s0,{paddingLeft:2,children:t(Y$,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(s0,{marginTop:1,paddingLeft:2,children:t(Y$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);let v=O.map((l)=>({key:l.name,label:`${l.name} - ${l.description}`,value:l}));return t(s0,{flexDirection:"column",paddingY:1,children:[t(s0,{marginBottom:1,children:t(Y$,{bold:!0,color:"cyan",children:w},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(_Q,{items:v,onSelect:A},void 0,!1,void 0,this),t(s0,{marginTop:1,children:t(Y$,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};if(Q==="create")return t(P6,{onComplete:()=>{H(),V()},onCancel:V},void 0,!1,void 0,this);if(Q==="edit")return T("✏️ 编辑 Agent");if(Q==="editWizard"&&J){let w={name:J.name,description:J.description,tools:J.tools||[],color:J.color,location:J.configPath?.includes(".blade/agents")?"project":"user",systemPrompt:J.systemPrompt||""};return t(P6,{initialConfig:w,onComplete:()=>{H(),V()},onCancel:V},void 0,!1,void 0,this)}if(Q==="delete")return T("\uD83D\uDDD1️ 删除 Agent");if(Q==="deleteConfirm"&&J)return t(s0,{flexDirection:"column",paddingY:1,children:[t(s0,{marginBottom:1,children:t(Y$,{bold:!0,color:"red",children:"⚠️ 确认删除"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(s0,{marginBottom:1,paddingLeft:2,children:t(Y$,{children:["你确定要删除 Agent"," ",t(Y$,{bold:!0,color:"yellow",children:J.name},void 0,!1,void 0,this)," ","吗?"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),t(s0,{marginBottom:1,paddingLeft:2,children:t(Y$,{dimColor:!0,children:["文件路径: ",J.configPath]},void 0,!0,void 0,this)},void 0,!1,void 0,this),t(s0,{marginBottom:1,paddingLeft:2,children:t(Y$,{color:"red",children:"此操作无法撤销!"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(_Q,{items:[{label:"\uD83D\uDDD1️ 确认删除",value:"confirm"},{label:"❌ 取消",value:"cancel"}],onSelect:(w)=>{if(w.value==="confirm")R();else V()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}H$();import{Box as B3,Text as Q$}from"ink";import $R from"react";K6();rY();import{useEffect as eV,useState as iH}from"react";function rH($=process.cwd(),Z=5000){let[Y,Q]=iH(null),[X,J]=iH(!0);return eV(()=>{let G=!0,q=async()=>{try{let W=await L6($);if(!G)return;if(!W){Q(null),J(!1);return}let U=await zW($);if(!G)return;Q(U)}catch{if(G)Q(null)}finally{if(G)J(!1)}};q();let K=null;if(Z>0)K=setInterval(q,Z);return()=>{if(G=!1,K)clearInterval(K)}},[$,Z]),{branch:Y,loading:X}}import{jsxDEV as R0,Fragment as E9}from"react/jsx-dev-runtime";var aH=$R.memo(()=>{let $=L9(),Z=O3(),Q=N9()==="shortcuts",X=QH(),{branch:J}=rH(),G=w9(),q=sU(),K=oU(),W=A9(),U=LH(),H=G?_4(G):!1,F=(()=>{if(Z==="default")return null;if(Z==="autoEdit")return R0(Q$,{color:"magenta",children:["▶▶ auto edit on ",R0(Q$,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="plan")return R0(Q$,{color:"cyan",children:["‖ plan mode on ",R0(Q$,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="yolo")return R0(Q$,{color:"red",children:["⚡ yolo mode on ",R0(Q$,{color:"gray",children:"(all tools auto-approved)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="spec"){let{phase:N,completed:B,total:L}=U,A;if(!N)A="init";else if((N==="tasks"||N==="implementation")&&L>0)A=`${N} ${B}/${L}`;else A=N;return R0(Q$,{color:"blue",children:["\uD83D\uDCCB spec: ",A," ",R0(Q$,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}return null})(),_=F!==null,z=[["Enter:发送","Shift+Enter:换行","Esc:中止"],["Shift+Tab:切换模式","↑/↓:历史","Tab:补全"],["Ctrl+A:行首","Ctrl+E:行尾","Ctrl+K:删到尾"],["Ctrl+U:删到首","Ctrl+W:删单词","Ctrl+C:退出"]];return R0(B3,{flexDirection:"row",justifyContent:"space-between",paddingX:2,paddingY:0,children:[Q?R0(B3,{flexDirection:"column",gap:0,children:z.map((N,B)=>R0(B3,{flexDirection:"row",children:[N.map((L,A)=>{let[R,V]=L.split(":");return R0(B3,{flexDirection:"row",width:20,children:[R0(Q$,{color:"yellow",children:R},void 0,!1,void 0,this),R0(Q$,{color:"gray",children:":"},void 0,!1,void 0,this),R0(Q$,{color:"white",children:V},void 0,!1,void 0,this)]},A,!0,void 0,this)}),B===z.length-1&&R0(Q$,{color:"cyan",children:" ? 关闭"},void 0,!1,void 0,this)]},B,!0,void 0,this))},void 0,!1,void 0,this):R0(B3,{flexDirection:"row",gap:1,children:[J&&R0(E9,{children:[R0(Q$,{color:"gray",children:[" ",J]},void 0,!0,void 0,this),R0(Q$,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),F,_&&R0(Q$,{color:"gray",children:"·"},void 0,!1,void 0,this),R0(Q$,{color:"gray",children:"? for shortcuts"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),R0(B3,{flexDirection:"row",gap:1,children:!$?R0(Q$,{color:"red",children:"⚠ API 密钥未配置"},void 0,!1,void 0,this):R0(E9,{children:[H&&R0(E9,{children:[W?R0(Q$,{color:"cyan",children:"Thinking on"},void 0,!1,void 0,this):R0(Q$,{color:"gray",children:"Tab:Thinking"},void 0,!1,void 0,this),R0(Q$,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G&&R0(Q$,{color:"gray",children:G.model},void 0,!1,void 0,this),R0(Q$,{color:"gray",children:"·"},void 0,!1,void 0,this),K?R0(Q$,{color:"yellow",children:"压缩中..."},void 0,!1,void 0,this):R0(Q$,{color:q<20?"red":q<50?"yellow":"gray",children:[q,"%"]},void 0,!0,void 0,this),X&&R0(E9,{children:[R0(Q$,{color:"gray",children:"·"},void 0,!1,void 0,this),R0(Q$,{color:"yellow",children:"再按一次 Ctrl+C 退出"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});import{Box as BQ,Text as NQ}from"ink";import ZR from"react";import{jsxDEV as N3}from"react/jsx-dev-runtime";var nH=ZR.memo(({suggestions:$,selectedIndex:Z,visible:Y,maxDisplay:Q=8})=>{if(!Y||$.length===0)return null;let X=0,J=Math.min(Q,$.length),G=Z>=$.length;if(Z>=Q&&!G)X=Z-Q+1,J=Z+1;let q=$.slice(X,J),K=$.length>Q;return N3(BQ,{flexDirection:"column",paddingX:2,paddingY:0,children:[q.map((W,U)=>{let O=X+U===Z;return N3(BQ,{flexDirection:"row",paddingX:1,gap:2,children:[N3(NQ,{color:O?"cyan":"white",bold:O,children:W.command},void 0,!1,void 0,this),N3(NQ,{color:O?"cyan":"gray",dimColor:!O,children:["- ",W.description]},void 0,!0,void 0,this)]},W.command,!0,void 0,this)}),K&&N3(BQ,{paddingX:1,children:N3(NQ,{color:G?"cyan":"gray",bold:G,dimColor:!G,children:["... and ",$.length-Q," more"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});H$();import{Box as x1,Text as K2,useInput as vR,useStdout as CR}from"ink";import kR from"ink-select-input";import vQ,{useMemo as qO}from"react";import{Box as N0,Text as m0}from"ink";import V8,{useEffect as PQ,useMemo as b8,useRef as GO}from"react";y3();H5();import{Box as P9,Text as g2}from"ink";import{isPlainObject as VQ}from"lodash-es";import{common as GR,createLowlight as qR}from"lowlight";import $O from"react";I2();import{Box as I9,Text as v6}from"ink";import m2,{Fragment as tH}from"react";import YR from"string-width";var oH=new Map,sH=1000;function wQ($){let Z=!0;for(let Q=0;Q<$.length;Q++)if($.charCodeAt(Q)>127){Z=!1;break}if(Z)return $.split("");if($.length<=sH){let Q=oH.get($);if(Q)return Q}let Y=Array.from($);if($.length<=sH)oH.set($,Y);return Y}var LQ=new Map;function p2($){if(/^[\x20-\x7E]*$/.test($))return $.length;if(LQ.has($))return LQ.get($);let Z=YR($);return LQ.set($,Z),Z}import{jsxDEV as L3}from"react/jsx-dev-runtime";var AQ=2,eH=m2.memo(({children:$,maxWidth:Z,maxHeight:Y,overflowDirection:Q="top",additionalHiddenLinesCount:X=0})=>{let J=o0(),G=[],q=Math.max(Math.round(Y??Number.MAX_SAFE_INTEGER),AQ);function K(z){if(!m2.isValidElement(z))return;if(z.type===tH){m2.Children.forEach(z.props.children,K);return}if(z.type===I9){XR(z,Z,G);return}}m2.Children.forEach($,K);let U=G.length>q||X>0?q-1:q,H=U!==void 0?Math.max(0,G.length-U):0,O=H+X,_=(H>0?Q==="top"?G.slice(H):G.slice(0,U):G).map((z,N)=>L3(I9,{children:z.length>0?z.map((B,L)=>L3(v6,{...B.props,children:B.text},L,!1,void 0,this)):L3(v6,{children:" "},void 0,!1,void 0,this)},N,!1,void 0,this));return L3(I9,{flexDirection:"column",width:Z,flexShrink:0,children:[O>0&&Q==="top"&&L3(v6,{color:J.colors.text.muted,dimColor:!0,children:["... ",O," line",O===1?"":"s"," hidden ..."]},void 0,!0,void 0,this),_,O>0&&Q==="bottom"&&L3(v6,{color:J.colors.text.muted,dimColor:!0,children:["... ",O," line",O===1?"":"s"," hidden ..."]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});function QR($){if(!m2.isValidElement($)||$.type!==I9)return{noWrapSegments:[],segments:[]};let Z={noWrapSegments:[],segments:[]},Y=!1;function Q(X,J){if(X===null||X===void 0)return;if(typeof X==="string"||typeof X==="number"){let W=String(X);if(!W)return;let U={text:W,props:J??{}};if(J===void 0||J.wrap==="wrap")Y=!0,Z.segments.push(U);else if(!Y)Z.noWrapSegments.push(U);else Z.segments.push(U);return}if(!m2.isValidElement(X))return;if(X.type===tH){m2.Children.forEach(X.props.children,(W)=>Q(W,J));return}if(X.type!==v6)return;let{children:G,...q}=X.props,K=J===void 0?q:{...J,...q};m2.Children.forEach(G,(W)=>Q(W,K))}return m2.Children.forEach($.props.children,(X)=>Q(X,void 0)),Z}function XR($,Z,Y){let Q=QR($);if(Q.segments.length===0&&Q.noWrapSegments.length===0){Y.push([]);return}let X=0;for(let H of Q.noWrapSegments)X+=p2(H.text);if(Q.segments.length===0){let H=[],O=[];for(let F of Q.noWrapSegments){let _=F.text.split(`
|
|
2895
|
+
`),l=FQ.join(T,`${J.name}.md`);await gH.promises.writeFile(l,v,"utf-8"),$()}catch(T){console.error("保存配置失败:",T)}}),M=W$(!1,Z);if(dH((T,w)=>{if(w.escape)A();else if(w.ctrl&&T==="c"||w.meta&&T==="c")M()},{isActive:Q!=="tools"}),Q==="mode")return P(J0,{flexDirection:"column",paddingY:1,children:[P(J0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83C\uDFAF 选择创建方式"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{dimColor:!0,children:"你可以手动配置每个细节,或让 AI 根据你的描述自动生成配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(T5,{items:[{label:"\uD83E\uDD16 AI 智能生成 - 根据描述自动生成完整配置",value:"ai"},{label:"✍️ 手动配置 - 逐步配置每个选项",value:"manual"}],onSelect:(T)=>{if(T.value==="ai")_("ai"),X("aiPrompt");else _("manual"),X("name")}},void 0,!1,void 0,this),P(J0,{marginTop:1,children:P($0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 取消"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="aiPrompt")return P(J0,{flexDirection:"column",paddingY:1,children:[P(J0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83E\uDD16 AI 智能生成"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{dimColor:!0,children:'描述你想要创建的 Agent(例如:"一个专门用于代码审查的 agent,能够分析代码质量和潜在bug")'},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:[P($0,{color:"green",children:"描述: "},void 0,!1,void 0,this),P(I6,{value:q,onChange:K,onSubmit:(T)=>{if(!T.trim())return;X("aiGenerating")}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(J0,{children:P($0,{dimColor:!0,children:"按 Enter 开始生成 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="aiGenerating"){if(H)return P(J0,{flexDirection:"column",paddingY:1,children:[P(J0,{marginBottom:1,children:P($0,{bold:!0,color:"red",children:"❌ AI 生成失败"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{color:"red",children:H},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{dimColor:!0,children:"按 ESC 返回修改描述"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return P(J0,{flexDirection:"column",paddingY:1,children:[P(J0,{marginBottom:1,children:P($0,{bold:!0,color:"yellow",children:[P(lV,{type:"dots"},void 0,!1,void 0,this)," AI 正在生成配置..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{dimColor:!0,children:['根据你的描述:"',q,'"']},void 0,!0,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{color:"gray",children:"正在调用 LLM 生成 agent 配置,请稍候..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}if(Q==="name"){let T=F==="edit";return P(J0,{flexDirection:"column",paddingY:1,children:[P(J0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:["\uD83D\uDCDD Step 1/7: ",T?"Agent 名称(不可修改)":"输入 Agent 名称"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{dimColor:!0,children:T?"编辑模式下名称不可修改(修改名称相当于创建新 Agent)":"名称只能包含小写字母、数字和连字符(例如:code-reviewer)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:[P($0,{color:"green",children:"名称: "},void 0,!1,void 0,this),T?P($0,{children:J.name},void 0,!1,void 0,this):P(I6,{value:J.name,onChange:(w)=>G({...J,name:w}),onSubmit:(w)=>{if(aV(w))return;L()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(J0,{children:P($0,{dimColor:!0,children:T?"按 Enter 继续 | ESC 返回":"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this),T&&P(I6,{value:"",onChange:()=>{},onSubmit:L,showCursor:!1},"edit-mode-dummy-input",!1,void 0,this)]},void 0,!0,void 0,this)}if(Q==="description")return P(J0,{flexDirection:"column",paddingY:1,children:[P(J0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83D\uDCDD Step 2/7: 输入描述信息"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{dimColor:!0,children:"简短描述这个 Agent 的用途和使用场景(这将帮助主 Agent 决定何时使用它)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:[P($0,{color:"green",children:"描述: "},void 0,!1,void 0,this),P(I6,{value:J.description,onChange:(T)=>G({...J,description:T}),onSubmit:(T)=>{if(!T.trim())return;L()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(J0,{children:P($0,{dimColor:!0,children:"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="tools")return P(nV,{config:J,setConfig:G,onNext:L,onPrev:A},void 0,!1,void 0,this);if(Q==="color")return P(J0,{flexDirection:"column",paddingY:1,children:[P(J0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83C\uDFA8 Step 4/7: 选择背景颜色"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{dimColor:!0,children:"为 Agent 选择一个颜色标识(用于在 UI 中区分不同的 Agents)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(T5,{items:rV,onSelect:(T)=>{let w=T.value==="none"?void 0:T.value;G({...J,color:w}),L()}},void 0,!1,void 0,this),P(J0,{marginTop:1,children:P($0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="location")return P(J0,{flexDirection:"column",paddingY:1,children:[P(J0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83D\uDCC2 Step 5/7: 选择保存位置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{dimColor:!0,children:"项目级配置仅在当前项目生效,用户级配置全局可用"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(T5,{items:[{label:"\uD83D\uDCC1 项目级 (.blade/agents/) - 仅当前项目",value:"project"},{label:"\uD83C\uDFE0 用户级 (~/.blade/agents/) - 全局可用",value:"user"}],onSelect:(T)=>{G({...J,location:T.value}),L()}},void 0,!1,void 0,this),P(J0,{marginTop:1,children:P($0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="systemPrompt")return P(J0,{flexDirection:"column",paddingY:1,children:[P(J0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83D\uDCAC Step 6/7: 输入系统提示词"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{dimColor:!0,children:"定义 Agent 的行为和职责(可选,留空将使用默认提示)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:[P($0,{color:"green",children:"提示词: "},void 0,!1,void 0,this),P(I6,{value:J.systemPrompt,onChange:(T)=>G({...J,systemPrompt:T}),onSubmit:()=>L()},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(J0,{children:P($0,{dimColor:!0,children:"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="confirm")return P(J0,{flexDirection:"column",paddingY:1,children:[P(J0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"✅ Step 7/7: 确认配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{flexDirection:"column",paddingLeft:2,marginBottom:1,children:[P($0,{children:[P($0,{bold:!0,color:"green",children:["名称:"," "]},void 0,!0,void 0,this),P($0,{children:J.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P($0,{children:[P($0,{bold:!0,color:"green",children:["描述:"," "]},void 0,!0,void 0,this),P($0,{children:J.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P($0,{children:[P($0,{bold:!0,color:"green",children:["工具:"," "]},void 0,!0,void 0,this),P($0,{children:J.tools.includes("all")?"所有工具":J.tools.join(", ")||"所有工具"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P($0,{children:[P($0,{bold:!0,color:"green",children:["颜色:"," "]},void 0,!0,void 0,this),P($0,{children:J.color||"默认"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P($0,{children:[P($0,{bold:!0,color:"green",children:["位置:"," "]},void 0,!0,void 0,this),P($0,{children:J.location==="project"?"项目级":"用户级"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P($0,{children:[P($0,{bold:!0,color:"green",children:["提示词:"," "]},void 0,!0,void 0,this),P($0,{children:J.systemPrompt||"(使用默认)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),P(T5,{items:[{label:"✅ 确认并保存",value:"save"},{label:"⬅️ 返回上一步",value:"back"},{label:"❌ 取消",value:"cancel"}],onSelect:(T)=>{if(T.value==="save")V();else if(T.value==="back")A();else Z()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}function nV({config:$,setConfig:Z,onNext:Y,onPrev:Q}){let{isFocused:X}=dV({id:"step-tools"});dH((G,q)=>{if(q.escape)Q()},{isActive:X});let J=(G)=>{if(G.includes("all"))Z({...$,tools:["all"]});else Z({...$,tools:G});Y()};return P(J0,{flexDirection:"column",paddingY:1,children:[P(J0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83D\uDD27 Step 3/7: 选择可用工具"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(J0,{marginBottom:1,children:P($0,{dimColor:!0,children:"方向键导航,空格切换勾选,Enter 确认进入下一步 | ESC 返回上一步"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(uV,{options:iV,defaultValue:$.tools,onSubmit:J},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}z4();import oV from"node:fs";import{useMemoizedFn as N8}from"ahooks";import{Box as s0,Text as Y$,useInput as sV}from"ink";import _Q from"ink-select-input";import{useEffect as tV,useMemo as cH,useState as y5}from"react";import{jsxDEV as t}from"react/jsx-dev-runtime";var zQ=10;function lH({initialMode:$="menu",onComplete:Z,onCancel:Y}){let[Q,X]=y5($),[J,G]=y5(null),[q,K]=y5(0),[W,U]=y5(0),H=N8(()=>{a0.clear(),a0.loadFromStandardLocations(),K((w)=>w+1)}),O=cH(()=>{return a0.getAllSubagents()},[q]),F=Math.ceil(O.length/zQ)||1,_=cH(()=>{let w=W*zQ;return O.slice(w,w+zQ)},[O,W]);tV(()=>{let w=Math.max(0,F-1);if(W>w)U(w)},[F,W]);let z=N8(()=>{if(W<F-1)U((w)=>w+1)}),N=N8(()=>{if(W>0)U((w)=>w-1)}),B=[{key:"list",label:"\uD83D\uDCCB 查看所有 Agents",value:"list"},{key:"create",label:"➕ 创建新 Agent",value:"create"},{key:"edit",label:"✏️ 编辑 Agent",value:"edit"},{key:"delete",label:"\uD83D\uDDD1️ 删除 Agent",value:"delete"},{key:"cancel",label:"❌ 取消",value:"cancel"}],L=N8((w)=>{if(w.value==="cancel"){Y?.();return}X(w.value)}),A=N8((w)=>{if(G(w.value),Q==="edit")X("editWizard");else if(Q==="delete")X("deleteConfirm")}),R=N8(async()=>{if(!J?.configPath)return;try{await oV.promises.unlink(J.configPath),H(),V()}catch(w){console.error("删除失败:",w)}}),V=N8(()=>{X("menu"),G(null)}),M=W$(!1,Y);if(sV((w,v)=>{if(v.escape){if(Q==="menu")Y?.();else if(Q==="list"||Q==="edit"||Q==="delete")U(0),V();else if(Q==="deleteConfirm")V()}else if(v.ctrl&&w==="c"||v.meta&&w==="c")M();else if(Q==="list"){if(v.leftArrow||w==="h")N();else if(v.rightArrow||w==="l")z()}},{isActive:Q!=="create"&&Q!=="editWizard"}),Q==="menu")return t(s0,{flexDirection:"column",paddingY:1,children:[t(s0,{marginBottom:1,children:t(Y$,{bold:!0,color:"cyan",children:"\uD83D\uDCCB Agents 管理"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(_Q,{items:B,onSelect:L},void 0,!1,void 0,this),t(s0,{marginTop:1,children:t(Y$,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 退出"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="list"){if(O.length===0)return t(s0,{flexDirection:"column",paddingY:1,children:[t(s0,{marginBottom:1,children:t(Y$,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(s0,{paddingLeft:2,children:t(Y$,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(s0,{marginTop:1,paddingLeft:2,children:t(Y$,{color:"gray",children:"\uD83D\uDCA1 配置文件位置: .blade/agents/ 或 ~/.blade/agents/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(s0,{marginTop:1,paddingLeft:2,children:t(Y$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return t(s0,{flexDirection:"column",paddingY:1,children:[t(s0,{marginBottom:1,children:[t(Y$,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this),t(Y$,{color:"gray",children:[" (共 ",O.length," 个)"]},void 0,!0,void 0,this),F>1&&t(Y$,{color:"yellow",children:[" ","第 ",W+1,"/",F," 页"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),_.map((w)=>t(s0,{flexDirection:"column",paddingLeft:2,children:[t(s0,{children:t(Y$,{children:[t(Y$,{bold:!0,color:w.color||"white",children:["• ",w.name]},void 0,!0,void 0,this),t(Y$,{color:"gray",children:[" - ",w.description]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),w.tools&&w.tools.length>0&&t(s0,{paddingLeft:2,children:t(Y$,{color:"gray",children:["工具: ",w.tools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),w.configPath&&t(s0,{paddingLeft:2,children:t(Y$,{color:"gray",dimColor:!0,children:w.configPath},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},w.name,!0,void 0,this)),t(s0,{marginTop:1,paddingLeft:2,children:F>1?t(Y$,{dimColor:!0,children:"← → 翻页 | ESC 返回菜单"},void 0,!1,void 0,this):t(Y$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}let T=(w)=>{if(O.length===0)return t(s0,{flexDirection:"column",paddingY:1,children:[t(s0,{marginBottom:1,children:t(Y$,{bold:!0,color:"cyan",children:w},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(s0,{paddingLeft:2,children:t(Y$,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(s0,{marginTop:1,paddingLeft:2,children:t(Y$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);let v=O.map((l)=>({key:l.name,label:`${l.name} - ${l.description}`,value:l}));return t(s0,{flexDirection:"column",paddingY:1,children:[t(s0,{marginBottom:1,children:t(Y$,{bold:!0,color:"cyan",children:w},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(_Q,{items:v,onSelect:A},void 0,!1,void 0,this),t(s0,{marginTop:1,children:t(Y$,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};if(Q==="create")return t(P6,{onComplete:()=>{H(),V()},onCancel:V},void 0,!1,void 0,this);if(Q==="edit")return T("✏️ 编辑 Agent");if(Q==="editWizard"&&J){let w={name:J.name,description:J.description,tools:J.tools||[],color:J.color,location:J.configPath?.includes(".blade/agents")?"project":"user",systemPrompt:J.systemPrompt||""};return t(P6,{initialConfig:w,onComplete:()=>{H(),V()},onCancel:V},void 0,!1,void 0,this)}if(Q==="delete")return T("\uD83D\uDDD1️ 删除 Agent");if(Q==="deleteConfirm"&&J)return t(s0,{flexDirection:"column",paddingY:1,children:[t(s0,{marginBottom:1,children:t(Y$,{bold:!0,color:"red",children:"⚠️ 确认删除"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(s0,{marginBottom:1,paddingLeft:2,children:t(Y$,{children:["你确定要删除 Agent"," ",t(Y$,{bold:!0,color:"yellow",children:J.name},void 0,!1,void 0,this)," ","吗?"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),t(s0,{marginBottom:1,paddingLeft:2,children:t(Y$,{dimColor:!0,children:["文件路径: ",J.configPath]},void 0,!0,void 0,this)},void 0,!1,void 0,this),t(s0,{marginBottom:1,paddingLeft:2,children:t(Y$,{color:"red",children:"此操作无法撤销!"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(_Q,{items:[{label:"\uD83D\uDDD1️ 确认删除",value:"confirm"},{label:"❌ 取消",value:"cancel"}],onSelect:(w)=>{if(w.value==="confirm")R();else V()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}H$();import{Box as B3,Text as Q$}from"ink";import $R from"react";K6();rY();import{useEffect as eV,useState as iH}from"react";function rH($=process.cwd(),Z=5000){let[Y,Q]=iH(null),[X,J]=iH(!0);return eV(()=>{let G=!0,q=async()=>{try{let W=await L6($);if(!G)return;if(!W){Q(null),J(!1);return}let U=await zW($);if(!G)return;Q(U)}catch{if(G)Q(null)}finally{if(G)J(!1)}};q();let K=null;if(Z>0)K=setInterval(q,Z);return()=>{if(G=!1,K)clearInterval(K)}},[$,Z]),{branch:Y,loading:X}}import{jsxDEV as R0,Fragment as E5}from"react/jsx-dev-runtime";var aH=$R.memo(()=>{let $=L5(),Z=O3(),Q=N5()==="shortcuts",X=QH(),{branch:J}=rH(),G=w5(),q=sU(),K=oU(),W=A5(),U=LH(),H=G?_4(G):!1,F=(()=>{if(Z==="default")return null;if(Z==="autoEdit")return R0(Q$,{color:"magenta",children:["▶▶ auto edit on ",R0(Q$,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="plan")return R0(Q$,{color:"cyan",children:["‖ plan mode on ",R0(Q$,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="yolo")return R0(Q$,{color:"red",children:["⚡ yolo mode on ",R0(Q$,{color:"gray",children:"(all tools auto-approved)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="spec"){let{phase:N,completed:B,total:L}=U,A;if(!N)A="init";else if((N==="tasks"||N==="implementation")&&L>0)A=`${N} ${B}/${L}`;else A=N;return R0(Q$,{color:"blue",children:["\uD83D\uDCCB spec: ",A," ",R0(Q$,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}return null})(),_=F!==null,z=[["Enter:发送","Shift+Enter:换行","Esc:中止"],["Shift+Tab:切换模式","↑/↓:历史","Tab:补全"],["Ctrl+A:行首","Ctrl+E:行尾","Ctrl+K:删到尾"],["Ctrl+U:删到首","Ctrl+W:删单词","Ctrl+C:退出"]];return R0(B3,{flexDirection:"row",justifyContent:"space-between",paddingX:2,paddingY:0,children:[Q?R0(B3,{flexDirection:"column",gap:0,children:z.map((N,B)=>R0(B3,{flexDirection:"row",children:[N.map((L,A)=>{let[R,V]=L.split(":");return R0(B3,{flexDirection:"row",width:20,children:[R0(Q$,{color:"yellow",children:R},void 0,!1,void 0,this),R0(Q$,{color:"gray",children:":"},void 0,!1,void 0,this),R0(Q$,{color:"white",children:V},void 0,!1,void 0,this)]},A,!0,void 0,this)}),B===z.length-1&&R0(Q$,{color:"cyan",children:" ? 关闭"},void 0,!1,void 0,this)]},B,!0,void 0,this))},void 0,!1,void 0,this):R0(B3,{flexDirection:"row",gap:1,children:[J&&R0(E5,{children:[R0(Q$,{color:"gray",children:[" ",J]},void 0,!0,void 0,this),R0(Q$,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),F,_&&R0(Q$,{color:"gray",children:"·"},void 0,!1,void 0,this),R0(Q$,{color:"gray",children:"? for shortcuts"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),R0(B3,{flexDirection:"row",gap:1,children:!$?R0(Q$,{color:"red",children:"⚠ API 密钥未配置"},void 0,!1,void 0,this):R0(E5,{children:[H&&R0(E5,{children:[W?R0(Q$,{color:"cyan",children:"Thinking on"},void 0,!1,void 0,this):R0(Q$,{color:"gray",children:"Tab:Thinking"},void 0,!1,void 0,this),R0(Q$,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G&&R0(Q$,{color:"gray",children:G.model},void 0,!1,void 0,this),R0(Q$,{color:"gray",children:"·"},void 0,!1,void 0,this),K?R0(Q$,{color:"yellow",children:"压缩中..."},void 0,!1,void 0,this):R0(Q$,{color:q<20?"red":q<50?"yellow":"gray",children:[q,"%"]},void 0,!0,void 0,this),X&&R0(E5,{children:[R0(Q$,{color:"gray",children:"·"},void 0,!1,void 0,this),R0(Q$,{color:"yellow",children:"再按一次 Ctrl+C 退出"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});import{Box as BQ,Text as NQ}from"ink";import ZR from"react";import{jsxDEV as N3}from"react/jsx-dev-runtime";var nH=ZR.memo(({suggestions:$,selectedIndex:Z,visible:Y,maxDisplay:Q=8})=>{if(!Y||$.length===0)return null;let X=0,J=Math.min(Q,$.length),G=Z>=$.length;if(Z>=Q&&!G)X=Z-Q+1,J=Z+1;let q=$.slice(X,J),K=$.length>Q;return N3(BQ,{flexDirection:"column",paddingX:2,paddingY:0,children:[q.map((W,U)=>{let O=X+U===Z;return N3(BQ,{flexDirection:"row",paddingX:1,gap:2,children:[N3(NQ,{color:O?"cyan":"white",bold:O,children:W.command},void 0,!1,void 0,this),N3(NQ,{color:O?"cyan":"gray",dimColor:!O,children:["- ",W.description]},void 0,!0,void 0,this)]},W.command,!0,void 0,this)}),K&&N3(BQ,{paddingX:1,children:N3(NQ,{color:G?"cyan":"gray",bold:G,dimColor:!G,children:["... and ",$.length-Q," more"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});H$();import{Box as x1,Text as K2,useInput as vR,useStdout as CR}from"ink";import kR from"ink-select-input";import vQ,{useMemo as qO}from"react";import{Box as N0,Text as m0}from"ink";import V8,{useEffect as PQ,useMemo as b8,useRef as GO}from"react";y3();H9();import{Box as P5,Text as g2}from"ink";import{isPlainObject as VQ}from"lodash-es";import{common as GR,createLowlight as qR}from"lowlight";import $O from"react";I2();import{Box as I5,Text as v6}from"ink";import m2,{Fragment as tH}from"react";import YR from"string-width";var oH=new Map,sH=1000;function wQ($){let Z=!0;for(let Q=0;Q<$.length;Q++)if($.charCodeAt(Q)>127){Z=!1;break}if(Z)return $.split("");if($.length<=sH){let Q=oH.get($);if(Q)return Q}let Y=Array.from($);if($.length<=sH)oH.set($,Y);return Y}var LQ=new Map;function p2($){if(/^[\x20-\x7E]*$/.test($))return $.length;if(LQ.has($))return LQ.get($);let Z=YR($);return LQ.set($,Z),Z}import{jsxDEV as L3}from"react/jsx-dev-runtime";var AQ=2,eH=m2.memo(({children:$,maxWidth:Z,maxHeight:Y,overflowDirection:Q="top",additionalHiddenLinesCount:X=0})=>{let J=o0(),G=[],q=Math.max(Math.round(Y??Number.MAX_SAFE_INTEGER),AQ);function K(z){if(!m2.isValidElement(z))return;if(z.type===tH){m2.Children.forEach(z.props.children,K);return}if(z.type===I5){XR(z,Z,G);return}}m2.Children.forEach($,K);let U=G.length>q||X>0?q-1:q,H=U!==void 0?Math.max(0,G.length-U):0,O=H+X,_=(H>0?Q==="top"?G.slice(H):G.slice(0,U):G).map((z,N)=>L3(I5,{children:z.length>0?z.map((B,L)=>L3(v6,{...B.props,children:B.text},L,!1,void 0,this)):L3(v6,{children:" "},void 0,!1,void 0,this)},N,!1,void 0,this));return L3(I5,{flexDirection:"column",width:Z,flexShrink:0,children:[O>0&&Q==="top"&&L3(v6,{color:J.colors.text.muted,dimColor:!0,children:["... ",O," line",O===1?"":"s"," hidden ..."]},void 0,!0,void 0,this),_,O>0&&Q==="bottom"&&L3(v6,{color:J.colors.text.muted,dimColor:!0,children:["... ",O," line",O===1?"":"s"," hidden ..."]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});function QR($){if(!m2.isValidElement($)||$.type!==I5)return{noWrapSegments:[],segments:[]};let Z={noWrapSegments:[],segments:[]},Y=!1;function Q(X,J){if(X===null||X===void 0)return;if(typeof X==="string"||typeof X==="number"){let W=String(X);if(!W)return;let U={text:W,props:J??{}};if(J===void 0||J.wrap==="wrap")Y=!0,Z.segments.push(U);else if(!Y)Z.noWrapSegments.push(U);else Z.segments.push(U);return}if(!m2.isValidElement(X))return;if(X.type===tH){m2.Children.forEach(X.props.children,(W)=>Q(W,J));return}if(X.type!==v6)return;let{children:G,...q}=X.props,K=J===void 0?q:{...J,...q};m2.Children.forEach(G,(W)=>Q(W,K))}return m2.Children.forEach($.props.children,(X)=>Q(X,void 0)),Z}function XR($,Z,Y){let Q=QR($);if(Q.segments.length===0&&Q.noWrapSegments.length===0){Y.push([]);return}let X=0;for(let H of Q.noWrapSegments)X+=p2(H.text);if(Q.segments.length===0){let H=[],O=[];for(let F of Q.noWrapSegments){let _=F.text.split(`
|
|
2896
2896
|
`);for(let z=0;z<_.length;z++){if(z>0)H.push(O),O=[];if(_[z])O.push({text:_[z],props:F.props})}}if(O.length>0)H.push(O);for(let F of H)Y.push(F);return}let J=Z-X;if(J<1){JR(Q.noWrapSegments,Z,Y);return}let G=[],q=[],K=0;function W(){if(G.length===0)G.push([...Q.noWrapSegments,...q]);else if(X>0)G.push([{text:" ".repeat(X),props:{}},...q]);else G.push(q);q=[],K=0}function U(H,O){if(q.length>0&&q[q.length-1].props===O)q[q.length-1].text+=H;else q.push({text:H,props:O})}for(let H of Q.segments){let O=H.text.split(`
|
|
2897
2897
|
`);for(let F=0;F<O.length;F++){if(F>0)W();let z=O[F].split(/(\s+)/);for(let N of z){if(!N)continue;let B=p2(N);if(K+B>J&&K>0){if(W(),/^\s+$/.test(N))continue}if(B>J){let A=wQ(N);while(A.length>0){let R=0,V=0;for(let M of A){let T=p2(M);if(K+V+T>J)break;V+=T,R++}if(R>0){let M=A.slice(0,R).join("");U(M,H.props),K+=p2(M),A=A.slice(R)}if(A.length>0)W()}}else U(N,H.props),K+=B}}if(H.text.endsWith(`
|
|
2898
2898
|
`))W()}if(q.length>0)W();for(let H of G)Y.push(H)}function JR($,Z,Y){let Q=[],X=[],J=0;for(let G of $){let q=G.text.split(`
|
|
2899
|
-
`);for(let K=0;K<q.length;K++){if(K>0)Q.push(X),X=[],J=0;let W=q[K];if(!W)continue;let U=p2(W),H=Math.max(0,Z-p2("…"));if(U<=H&&J===0)X.push({text:W,props:G.props}),J+=U;else{let O=wQ(W),F=J,_=0;for(let N of O){let B=p2(N);if(F+B>H)break;F+=B,_++}let z=O.slice(0,_).join("");if(z)X.push({text:z,props:G.props});X.push({text:"…",props:{}}),J=F+p2("…")}}}if(X.length>0)Q.push(X);if(Q.length===0)Q.push([{text:"…",props:{}}]);for(let G of Q)Y.push(G)}import{jsxDEV as Q1}from"react/jsx-dev-runtime";var bQ=qR(GR),KR=200,L8=new Map;function WR($,Z){let Y=`${Z??"__auto__"}:${$}`,Q=L8.get(Y);if(Q!==void 0)L8.delete(Y),L8.set(Y,Q);return Q}function UR($,Z,Y){let Q=`${Z??"__auto__"}:${$}`;if(L8.size>=KR){let X=L8.keys().next().value;if(X!==void 0)L8.delete(X)}L8.set(Q,Y)}function HR($){return VQ($)&&$.type==="text"&&typeof $.value==="string"}function OR($){return VQ($)&&$.type==="element"}function FR($){return VQ($)&&$.type==="root"&&Array.isArray($.children)}function
|
|
2900
|
-
`),q=0;if(X&&G.length>X){let H=Math.max(X,AQ);if(G.length>H)q=G.length-H,G=G.slice(q)}let K=G.length+q,W=String(K).length+1,U=Math.max(20,Q-4);return Q1(
|
|
2899
|
+
`);for(let K=0;K<q.length;K++){if(K>0)Q.push(X),X=[],J=0;let W=q[K];if(!W)continue;let U=p2(W),H=Math.max(0,Z-p2("…"));if(U<=H&&J===0)X.push({text:W,props:G.props}),J+=U;else{let O=wQ(W),F=J,_=0;for(let N of O){let B=p2(N);if(F+B>H)break;F+=B,_++}let z=O.slice(0,_).join("");if(z)X.push({text:z,props:G.props});X.push({text:"…",props:{}}),J=F+p2("…")}}}if(X.length>0)Q.push(X);if(Q.length===0)Q.push([{text:"…",props:{}}]);for(let G of Q)Y.push(G)}import{jsxDEV as Q1}from"react/jsx-dev-runtime";var bQ=qR(GR),KR=200,L8=new Map;function WR($,Z){let Y=`${Z??"__auto__"}:${$}`,Q=L8.get(Y);if(Q!==void 0)L8.delete(Y),L8.set(Y,Q);return Q}function UR($,Z,Y){let Q=`${Z??"__auto__"}:${$}`;if(L8.size>=KR){let X=L8.keys().next().value;if(X!==void 0)L8.delete(X)}L8.set(Q,Y)}function HR($){return VQ($)&&$.type==="text"&&typeof $.value==="string"}function OR($){return VQ($)&&$.type==="element"}function FR($){return VQ($)&&$.type==="root"&&Array.isArray($.children)}function v5($,Z,Y=0){if(HR($))return Q1(g2,{wrap:"wrap",children:$.value},Y,!1,void 0,this);if(OR($)){let Q=$.properties?.className?.[0]||"",X=Z.default;if(Q.includes("comment"))X=Z.comment;else if(Q.includes("string"))X=Z.string;else if(Q.includes("number"))X=Z.number;else if(Q.includes("keyword"))X=Z.keyword;else if(Q.includes("function"))X=Z.function;else if(Q.includes("variable"))X=Z.variable;else if(Q.includes("operator"))X=Z.operator;else if(Q.includes("type"))X=Z.type;else if(Q.includes("tag"))X=Z.tag;else if(Q.includes("attr"))X=Z.attr;let J=$.children?.map((G,q)=>v5(G,Z,q));return Q1(g2,{color:X,wrap:"wrap",children:J},Y,!1,void 0,this)}if(FR($))return Q1($O.Fragment,{children:$.children.map((Q,X)=>v5(Q,Z,X))},Y,!1,void 0,this);return Q1(g2,{},Y,!1,void 0,this)}function _R($,Z,Y){let Q=Y||E$.getTheme().colors.syntax;try{let X=WR($,Z);if(X)return v5(X,Q);let J;if(!Z||!bQ.registered(Z))J=bQ.highlightAuto($);else J=bQ.highlight(Z,$);let G=J;if(!G.children||G.children.length===0)return Q1(g2,{color:Q.default,wrap:"wrap",children:$},void 0,!1,void 0,this);return UR($,Z,J),v5(J,Q)}catch(X){return Q1(g2,{color:Q.default,wrap:"wrap",children:$},void 0,!1,void 0,this)}}var C5=$O.memo(({content:$,language:Z,showLineNumbers:Y=!0,terminalWidth:Q,availableHeight:X})=>{let J=o0(),G=$.split(`
|
|
2900
|
+
`),q=0;if(X&&G.length>X){let H=Math.max(X,AQ);if(G.length>H)q=G.length-H,G=G.slice(q)}let K=G.length+q,W=String(K).length+1,U=Math.max(20,Q-4);return Q1(P5,{borderStyle:"round",borderColor:J.colors.border.light,paddingX:1,paddingY:0,marginY:1,flexDirection:"column",children:[Z&&Q1(P5,{marginBottom:0,children:Q1(g2,{color:J.colors.text.secondary,children:Z},void 0,!1,void 0,this)},void 0,!1,void 0,this),q>0&&Q1(P5,{marginBottom:0,children:Q1(g2,{color:J.colors.text.muted,dimColor:!0,children:["... ",q," lines hidden ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q1(eH,{maxWidth:U,maxHeight:X,children:G.map((H,O)=>{let F=O+q+1;return Q1(P5,{flexDirection:"row",children:[Y&&Q1(g2,{color:J.colors.text.muted,dimColor:!0,wrap:"truncate",children:[String(F).padStart(W-1," ")," "]},void 0,!0,void 0,this),H.trim()===""?Q1(g2,{wrap:"wrap",children:" "},void 0,!1,void 0,this):_R(H,Z,J.colors.syntax)]},O,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});import{Box as ZO,Text as D2}from"ink";import zR from"react";import{jsxDEV as k1}from"react/jsx-dev-runtime";function BR($){let Z=$.split(`
|
|
2901
2901
|
`),Y=[],Q=0,X=0;for(let J of Z){if(J.startsWith("---")||J.startsWith("+++"))continue;if(J.startsWith("@@")){let G=J.match(/@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@/);if(G)Q=parseInt(G[1],10),X=parseInt(G[3],10);Y.push({type:"header",content:J});continue}if(J.startsWith("-")){Y.push({type:"remove",content:J.substring(1),lineNumber:Q}),Q++;continue}if(J.startsWith("+")){Y.push({type:"add",content:J.substring(1),lineNumber:X}),X++;continue}if(J.startsWith(" ")||J===""){Y.push({type:"context",content:J.substring(1),lineNumber:X}),Q++,X++;continue}}return Y}var RQ=zR.memo(({patch:$,startLine:Z,matchLine:Y,terminalWidth:Q,maxLines:X=20})=>{let J=o0(),G=BR($),K=Math.max(...G.map((F)=>F.lineNumber||0)).toString().length+1,W=G.length,U=W>X,H=U?G.slice(0,X):G,O=W-X;return k1(ZO,{flexDirection:"column",marginTop:1,marginBottom:1,children:[k1(D2,{color:J.colors.muted,children:"─".repeat(Math.max(0,Math.min(60,Q)))},void 0,!1,void 0,this),U&&k1(D2,{color:J.colors.info,children:["\uD83D\uDCCA 显示前 ",X," 行,共 ",W," 行 diff"]},void 0,!0,void 0,this),U&&k1(D2,{color:J.colors.muted,children:"─".repeat(Math.max(0,Math.min(60,Q)))},void 0,!1,void 0,this),H.map((F,_)=>{if(F.type==="header")return k1(D2,{color:J.colors.muted,dimColor:!0,children:F.content},_,!1,void 0,this);let z=F.lineNumber?F.lineNumber.toString().padStart(K," "):" ".repeat(K),N=" ",B,L;if(F.type==="add")N="+",L=J.colors.success,B=void 0;else if(F.type==="remove")N="-",L=J.colors.error,B=void 0;else L=J.colors.text.primary;let A=Math.max(0,Q-K-2),R=F.content;if(R.length>A)R=R.substring(0,A-3)+"...";return k1(D2,{color:L,backgroundColor:B,children:[k1(D2,{dimColor:!0,children:z},void 0,!1,void 0,this),k1(D2,{children:N},void 0,!1,void 0,this),k1(D2,{children:[" ",R]},void 0,!0,void 0,this)]},_,!0,void 0,this)}),U&&k1(ZO,{marginTop:1,children:k1(D2,{color:J.colors.warning,dimColor:!0,children:["⚠️ 已隐藏剩余 ",O," 行 diff(总共 ",W," 行)"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),k1(D2,{color:J.colors.muted,children:"─".repeat(Math.max(0,Math.min(60,Q)))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});import{Text as q2}from"ink";import LR from"react";import NR from"string-width";var w8=($)=>{let Z=$.replace(/\*\*(.*?)\*\*/g,"$1").replace(/\*(.*?)\*/g,"$1").replace(/_(.*?)_/g,"$1").replace(/~~(.*?)~~/g,"$1").replace(/`(.*?)`/g,"$1").replace(/<u>(.*?)<\/u>/g,"$1").replace(/\[(.*?)\]\(.*?\)/g,"$1");return NR(Z)},YO=($,Z,Y="...")=>{if(w8($)<=Z)return $;if(Z<=Y.length)return Y.substring(0,Z);let X=0,J=$.length,G="";while(X<=J){let q=Math.floor((X+J)/2),K=$.substring(0,q);if(w8(K)<=Z-Y.length)G=K,X=q+1;else J=q-1}return G+Y},QO=($)=>{return/[*_~`<[\]https?:]/.test($)};import{jsxDEV as S1,Fragment as AR}from"react/jsx-dev-runtime";var DQ=2,MQ=1,jQ=2;function TQ($,Z){return`inline-${$}-${Z}`}var wR=({text:$})=>{let Z=o0();if(!QO($))return S1(q2,{children:$},void 0,!1,void 0,this);let Y=[],Q=0,X=0,J=0,G=/(\*\*.*?\*\*|\*(?!\s).*?(?<!\s)\*|_(?!\s).*?(?<!\s)_|~~.*?~~|`+[^`]+`+|\[.*?\]\(.*?\)|https?:\/\/\S+)/g,q;while((q=G.exec($))!==null){if(q.index>Q){let H=$.slice(Q,q.index);Y.push(S1(q2,{children:H},TQ("text",X++),!1,void 0,this))}let K=q[0],W=null,U=TQ("match",J++);try{if(K.startsWith("**")&&K.endsWith("**")&&K.length>DQ*2)W=S1(q2,{bold:!0,children:K.slice(DQ,-DQ)},U,!1,void 0,this);else if(K.length>MQ*2&&(K.startsWith("*")&&K.endsWith("*")||K.startsWith("_")&&K.endsWith("_"))){let H=$.substring(q.index-1,q.index),O=$.substring(G.lastIndex,G.lastIndex+1);if(!(/\w/.test(H)||/\w/.test(O)||/[./\\]/.test(H+O)))W=S1(q2,{italic:!0,children:K.slice(MQ,-MQ)},U,!1,void 0,this)}else if(K.startsWith("~~")&&K.endsWith("~~")&&K.length>jQ*2)W=S1(q2,{strikethrough:!0,children:K.slice(jQ,-jQ)},U,!1,void 0,this);else if(K.startsWith("`")&&K.endsWith("`")){let H=K.match(/^(`+)([^`]+)\1$/);if(H&&H[2])W=S1(q2,{color:Z.colors.syntax.keyword,backgroundColor:Z.colors.background.secondary,bold:!0,children:` ${H[2]} `},U,!1,void 0,this)}else if(K.startsWith("[")&&K.includes("](")&&K.endsWith(")")){let H=K.match(/\[(.*?)\]\((.*?)\)/);if(H){let O=H[1],F=H[2];W=S1(q2,{children:[O,S1(q2,{color:Z.colors.info,children:[" (",F,")"]},void 0,!0,void 0,this)]},U,!0,void 0,this)}}else if(K.match(/^https?:\/\//))W=S1(q2,{color:Z.colors.info,children:K},U,!1,void 0,this)}catch(H){console.error("InlineRenderer 解析错误:",K,H),W=null}Y.push(W??S1(q2,{children:K},U,!1,void 0,this)),Q=G.lastIndex}if(Q<$.length){let K=$.slice(Q);Y.push(S1(q2,{children:K},TQ("text",X++),!1,void 0,this))}return S1(AR,{children:Y.filter((K)=>K!==null)},void 0,!1,void 0,this)},f1=LR.memo(wR);import{Box as yQ,Text as XO}from"ink";import bR from"react";import{jsxDEV as w3}from"react/jsx-dev-runtime";var VR=({itemText:$,type:Z,marker:Y,leadingWhitespace:Q=""})=>{let X=Z==="ol"?`${Y}. `:`${Y} `,J=X.length,G=Q.length;return w3(yQ,{paddingLeft:G+1,flexDirection:"row",children:[w3(yQ,{width:J,children:w3(XO,{children:X},void 0,!1,void 0,this)},void 0,!1,void 0,this),w3(yQ,{flexGrow:1,children:w3(XO,{wrap:"wrap",children:w3(f1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},EQ=bR.memo(VR);import{Box as RR,Text as A8}from"ink";import IQ from"react";import{jsxDEV as h1}from"react/jsx-dev-runtime";var JO=IQ.memo(({headers:$,rows:Z,terminalWidth:Y})=>{let Q=o0();if($.length===0||Z.length===0)return null;let X=$.map((O,F)=>{let _=w8(O),z=Math.max(...Z.map((N)=>w8(N[F]||"")));return Math.max(_,z)+2}),J=$.length+1,G=X.reduce((O,F)=>O+F,0)+J,q=G>Y?Y/G:1,K=X.map((O)=>Math.floor(O*q)),W=(O,F,_=!1)=>{let z=Math.max(0,F-2),N=w8(O),B=O;if(N>z)B=YO(O,z);let L=w8(B),A=Math.max(0,z-L);return h1(A8,{children:[_?h1(A8,{bold:!0,color:Q.colors.primary,children:h1(f1,{text:B},void 0,!1,void 0,this)},void 0,!1,void 0,this):h1(f1,{text:B},void 0,!1,void 0,this)," ".repeat(A)]},void 0,!0,void 0,this)},U=(O)=>{let _={top:{left:"┌",middle:"┬",right:"┐",horizontal:"─"},middle:{left:"├",middle:"┼",right:"┤",horizontal:"─"},bottom:{left:"└",middle:"┴",right:"┘",horizontal:"─"}}[O],z=K.map((B)=>_.horizontal.repeat(B)),N=_.left+z.join(_.middle)+_.right;return h1(A8,{color:Q.colors.text.muted,dimColor:!0,children:N},void 0,!1,void 0,this)},H=(O,F=!1)=>{let _=O.map((z,N)=>{let B=K[N]||0;return W(z||"",B,F)});return h1(A8,{children:[h1(A8,{color:Q.colors.text.muted,children:"│ "},void 0,!1,void 0,this),_.map((z,N)=>h1(IQ.Fragment,{children:[z,N<_.length-1&&h1(A8,{color:Q.colors.text.muted,children:" │ "},void 0,!1,void 0,this)]},N,!0,void 0,this)),h1(A8,{color:Q.colors.text.muted,children:" │"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};return h1(RR,{flexDirection:"column",marginY:1,children:[U("top"),H($,!0),U("middle"),Z.map((O,F)=>h1(IQ.Fragment,{children:H(O)},F,!1,void 0,this)),U("bottom")]},void 0,!0,void 0,this)});import{jsxDEV as x}from"react/jsx-dev-runtime";var DR=($,Z,Y)=>{switch($){case"user":return{color:Z.info,prefix:"> "};case"assistant":return{color:Z.success,prefix:"• "};case"system":return{color:Z.warning,prefix:"⚙ "};case"tool":{let Q=Y&&"phase"in Y?Y.phase:void 0;return{color:Z.text.secondary,prefix:Q==="start"?"• ":Q==="complete"?" └ ":" "}}default:return{color:Z.text.primary,prefix:" "}}},MR=V8.memo(({content:$,language:Z,terminalWidth:Y,isPending:Q=!1,availableHeight:X})=>{let J=o0();if(Q&&X!==void 0){let G=$.split(`
|
|
2902
2902
|
`),q=4,K=Math.max(1,X-4);if(G.length>K){let W=G.slice(0,K).join(`
|
|
2903
|
-
`);return x(N0,{flexDirection:"column",flexShrink:0,children:[x(
|
|
2903
|
+
`);return x(N0,{flexDirection:"column",flexShrink:0,children:[x(C5,{content:W,language:Z,showLineNumbers:!0,terminalWidth:Y},void 0,!1,void 0,this),x(m0,{color:J.colors.text.muted,dimColor:!0,children:"... generating more code ..."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}}return x(C5,{content:$,language:Z,showLineNumbers:!0,terminalWidth:Y},void 0,!1,void 0,this)}),jR=V8.memo(({content:$,level:Z})=>{let Y=o0();switch(Z){case 1:return x(m0,{bold:!0,color:Y.colors.primary,children:x(f1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 2:return x(m0,{bold:!0,color:Y.colors.primary,children:x(f1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 3:return x(m0,{bold:!0,color:Y.colors.text.primary,children:x(f1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 4:return x(m0,{italic:!0,color:Y.colors.text.muted,children:x(f1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);default:return x(m0,{children:x(f1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)}}),TR=V8.memo(({terminalWidth:$})=>{let Z=o0(),Y=Math.max(0,Math.min($-4,80));return x(m0,{dimColor:!0,color:Z.colors.text.muted,children:"─".repeat(Y)},void 0,!1,void 0,this)}),yR=V8.memo(({content:$})=>{return x(m0,{wrap:"wrap",children:x(f1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)}),ER=V8.memo(({content:$})=>{let Z=o0();return x(N0,{flexDirection:"row",gap:1,children:[x(m0,{color:Z.colors.info,children:"⏳"},void 0,!1,void 0,this),x(m0,{color:Z.colors.text.muted,italic:!0,children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}),IR=V8.memo(({detail:$,terminalWidth:Z})=>{let Y=o0(),Q=50,X=$.split(`
|
|
2904
2904
|
`);while(X.length>0&&X[0].trim()==="")X.shift();while(X.length>0&&X[X.length-1].trim()==="")X.pop();let J=X.length>50,G=J?X.slice(0,50):X,q=G.join(`
|
|
2905
|
-
`),K=q.includes("<<<DIFF>>>"),W=q.includes("```");if(K){let U=q.match(/<<<DIFF>>>\s*({[\s\S]*?})\s*<<<\/DIFF>>>/);if(U)try{let H=JSON.parse(U[1]);return x(N0,{flexDirection:"column",children:[x(RQ,{patch:H.patch,startLine:H.startLine,matchLine:H.matchLine,terminalWidth:Z},void 0,!1,void 0,this),J&&x(N0,{marginTop:1,children:x(m0,{dimColor:!0,color:Y.colors.text.muted,children:["... 省略 ",X.length-50," 行 ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}catch{}}if(W){let U=q.match(/```(\w+)?\s*\n([\s\S]*?)\n```/);if(U){let H=U[1]||"text",O=U[2];return x(N0,{flexDirection:"column",children:[x(
|
|
2905
|
+
`),K=q.includes("<<<DIFF>>>"),W=q.includes("```");if(K){let U=q.match(/<<<DIFF>>>\s*({[\s\S]*?})\s*<<<\/DIFF>>>/);if(U)try{let H=JSON.parse(U[1]);return x(N0,{flexDirection:"column",children:[x(RQ,{patch:H.patch,startLine:H.startLine,matchLine:H.matchLine,terminalWidth:Z},void 0,!1,void 0,this),J&&x(N0,{marginTop:1,children:x(m0,{dimColor:!0,color:Y.colors.text.muted,children:["... 省略 ",X.length-50," 行 ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}catch{}}if(W){let U=q.match(/```(\w+)?\s*\n([\s\S]*?)\n```/);if(U){let H=U[1]||"text",O=U[2];return x(N0,{flexDirection:"column",children:[x(C5,{content:O,language:H,showLineNumbers:!1,terminalWidth:Z},void 0,!1,void 0,this),J&&x(N0,{marginTop:1,children:x(m0,{dimColor:!0,color:Y.colors.text.muted,children:["... 省略 ",X.length-50," 行 ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}}return x(N0,{flexDirection:"column",children:[G.map((U,H)=>x(m0,{color:Y.colors.text.primary,children:U},H,!1,void 0,this)),J&&x(N0,{marginTop:1,children:x(m0,{dimColor:!0,color:Y.colors.text.muted,children:["... 省略 ",X.length-50," 行 ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});function PR($,Z,Y,Q=80){if(!Y||Z===void 0||Z<=0)return{content:$,isTruncated:!1,hiddenLines:0};let J=Math.max(1,Z-8),G=Math.max(40,Q*0.8),q=J*G;if($.length<=q)return{content:$,isTruncated:!1,hiddenLines:0};let K=Math.floor(q*0.9),W=$.length-K,U=W,H=$.indexOf(`
|
|
2906
2906
|
`,W);if(H!==-1&&H-W<G)U=H+1;let O=$.slice(U),_=($.slice(0,U).match(/\n/g)||[]).length+1;return{content:O,isTruncated:!0,hiddenLines:_}}var R8=V8.memo(({content:$,role:Z,terminalWidth:Y,metadata:Q,isPending:X=!1,availableTerminalHeight:J,hidePrefix:G=!1,noMargin:q=!1,renderPlainTextOnly:K=!1,streamingLines:W,streamingHiddenLines:U,messageId:H,blocksOverride:O,currentLineOverride:F,streamingMode:_="text",renderCodeBlocksAsPlainText:z=!1})=>{let N=o0(),B=O!==void 0,L=b8(()=>DR(Z,N.colors,Q),[Z,N.colors,Q]),{color:A,prefix:R}=L,V=R.length+1,M=b8(()=>{if(!Q||typeof Q!=="object")return null;if(!("subtaskRef"in Q))return null;let k=Q.subtaskRef;if(!k||typeof k!=="object")return null;return k},[Q]),T=Z==="tool"&&Q?.phase==="start",w=!q&&!T,v=b8(()=>{if(!K)return[];return $.split(/\r?\n/)},[$,K]);if(!B&&X){let k=W??$.split(/\r?\n/),e=U??0,C=!1,r=!1,h=!1;if(_!=="text")C=_==="code",r=_==="diff",h=_==="table";return x(N0,{flexDirection:"column",marginBottom:w?1:0,flexShrink:0,children:[e>0&&x(N0,{flexDirection:"row",flexShrink:0,children:[x(N0,{width:V,flexShrink:0},void 0,!1,void 0,this),x(m0,{color:N.colors.text.muted,dimColor:!0,children:["↑ ",e," lines above (streaming...)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),k.map((c,j0)=>{if(_==="text"){if(c.match(I0.codeBlock))C=!C;else if(c.match(I0.diffStart))r=!0;else if(c.match(I0.diffEnd))r=!1;else if(c.match(I0.table))h=!0;else if(h&&!c.match(I0.table))h=!1}let E0=_==="text"&&!C&&!r&&!h,g0=E0?c.match(I0.ulItem):null,i0=E0?c.match(I0.olItem):null,s$=g0??i0;return x(N0,{flexDirection:"row",flexShrink:0,children:[j0===0&&!G?x(N0,{marginRight:1,flexShrink:0,children:x(m0,{color:A,bold:!0,children:R},void 0,!1,void 0,this)},void 0,!1,void 0,this):x(N0,{width:V,flexShrink:0},void 0,!1,void 0,this),x(N0,{flexGrow:1,flexShrink:0,children:s$?x(EQ,{type:g0?"ul":"ol",marker:s$[2],itemText:s$[3],leadingWhitespace:s$[1]},void 0,!1,void 0,this):x(m0,{wrap:"wrap",children:c===""?" ":c},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},j0,!0,void 0,this)})]},void 0,!0,void 0,this)}if(!B&&K)return x(N0,{flexDirection:"column",marginBottom:w?1:0,flexShrink:0,children:v.map((k,e)=>x(N0,{flexDirection:"row",flexShrink:0,children:[e===0&&!G?x(N0,{marginRight:1,flexShrink:0,children:x(m0,{color:A,bold:!0,children:R},void 0,!1,void 0,this)},void 0,!1,void 0,this):x(N0,{width:V,flexShrink:0},void 0,!1,void 0,this),x(N0,{flexGrow:1,flexShrink:0,children:x(m0,{wrap:"wrap",children:k===""?" ":k},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},e,!0,void 0,this))},void 0,!1,void 0,this);let l=GO(null);PQ(()=>{l.current=null},[H]);let o=b8(()=>{if(B)return null;if(!H)return null;return vX(H)},[H,B]);PQ(()=>{if(B)return;if(!o||!H)return;l.current={messageId:H,blocks:o}},[o,H,B]),PQ(()=>{if(B)return;if(!o||!H)return;kX(H)},[o,H,B]);let S=b8(()=>B?{content:$,isTruncated:!1,hiddenLines:0}:PR($,J,X,Y),[$,J,X,Y,B]),{content:y,isTruncated:m,hiddenLines:I}=S;if(!B&&Z==="tool"&&Q&&"detail"in Q){let k=Q;if(k.detail)return x(N0,{flexDirection:"column",marginBottom:q?0:1,children:[x(N0,{flexDirection:"row",children:[x(N0,{marginRight:1,children:x(m0,{color:A,bold:!0,children:R},void 0,!1,void 0,this)},void 0,!1,void 0,this),x(m0,{color:A,children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),x(N0,{marginLeft:R.length+1,children:x(IR,{detail:k.detail,terminalWidth:Y-(R.length+1)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}let{completedContent:j,currentLine:D}=b8(()=>{if(B)return{completedContent:"",currentLine:F??""};if(!X)return{completedContent:y,currentLine:""};let k=y.lastIndexOf(`
|
|
2907
|
-
`);if(k===-1)return{completedContent:"",currentLine:y};return{completedContent:y.slice(0,k+1),currentLine:y.slice(k+1)}},[y,X,B,F]),i=GO({content:"",blocks:[]}),g=b8(()=>{if(B)return O??[];if(o)return o;if(l.current&&l.current.messageId===H)return l.current.blocks;let k=i.current;if(!X||!j.startsWith(k.content)){let h=p4(j);return i.current={content:j,blocks:h},h}if(j===k.content)return k.blocks;let e=j.slice(k.content.length),C=p4(e),r=[...k.blocks,...C];return i.current={content:j,blocks:r},r},[j,X,B,O]);return x(N0,{flexDirection:"column",marginBottom:w?1:0,flexShrink:0,children:[m&&x(N0,{flexDirection:"row",flexShrink:0,children:[x(N0,{width:V,flexShrink:0},void 0,!1,void 0,this),x(m0,{color:N.colors.text.muted,dimColor:!0,children:["↑ ",I," lines above (streaming...)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),g.map((k,e)=>{if(k.type==="empty")return x(N0,{height:1,flexShrink:0},e,!1,void 0,this);return x(N0,{flexDirection:"row",flexShrink:0,children:[e===0&&!G&&x(N0,{marginRight:1,flexShrink:0,children:x(m0,{color:A,bold:!0,children:R},void 0,!1,void 0,this)},void 0,!1,void 0,this),(e>0||G)&&x(N0,{width:V,flexShrink:0},void 0,!1,void 0,this),x(N0,{flexGrow:1,flexShrink:0,children:k.type==="code"?z?x(m0,{wrap:"wrap",children:k.content},void 0,!1,void 0,this):x(MR,{content:k.content,language:k.language,terminalWidth:Y-V,isPending:X,availableHeight:J},void 0,!1,void 0,this):k.type==="table"&&k.tableData?x(JO,{headers:k.tableData.headers,rows:k.tableData.rows,terminalWidth:Y-V},void 0,!1,void 0,this):k.type==="heading"?x(jR,{content:k.content,level:k.level||1},void 0,!1,void 0,this):k.type==="list"?x(EQ,{type:k.listType||"ul",marker:k.marker||"-",itemText:k.content,leadingWhitespace:" ".repeat(k.indentation||0)},void 0,!1,void 0,this):k.type==="hr"?x(TR,{terminalWidth:Y-V},void 0,!1,void 0,this):k.type==="diff"&&k.diffData?x(RQ,{patch:k.diffData.patch,startLine:k.diffData.startLine,matchLine:k.diffData.matchLine,terminalWidth:Y-V},void 0,!1,void 0,this):k.type==="command-message"?x(ER,{content:k.content},void 0,!1,void 0,this):x(yR,{content:k.content},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},e,!0,void 0,this)}),D&&x(N0,{flexDirection:"row",flexShrink:0,children:[g.length===0&&!G?x(N0,{marginRight:1,flexShrink:0,children:x(m0,{color:A,bold:!0,children:R},void 0,!1,void 0,this)},void 0,!1,void 0,this):x(N0,{width:V,flexShrink:0},void 0,!1,void 0,this),x(N0,{flexGrow:1,flexShrink:0,children:x(m0,{wrap:"wrap",children:D},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),M&&x(N0,{flexDirection:"row",flexShrink:0,children:[x(N0,{width:V,flexShrink:0},void 0,!1,void 0,this),x(N0,{flexDirection:"column",flexGrow:1,flexShrink:0,children:[x(m0,{color:N.colors.text.muted,children:["Subtask ",typeof M.agentType==="string"?`@${M.agentType}`:"",typeof M.status==="string"?` · ${M.status}`:""]},void 0,!0,void 0,this),typeof M.summary==="string"&&M.summary.trim()!==""&&x(m0,{wrap:"wrap",children:M.summary},void 0,!1,void 0,this),typeof M.childSessionId==="string"&&x(m0,{color:N.colors.text.muted,children:["Session ",M.childSessionId]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},($,Z)=>{return $.content===Z.content&&$.role===Z.role&&$.terminalWidth===Z.terminalWidth&&$.isPending===Z.isPending&&$.availableTerminalHeight===Z.availableTerminalHeight&&$.hidePrefix===Z.hidePrefix&&$.noMargin===Z.noMargin&&$.renderPlainTextOnly===Z.renderPlainTextOnly&&$.streamingHiddenLines===Z.streamingHiddenLines&&$.streamingLines===Z.streamingLines&&$.messageId===Z.messageId&&$.metadata===Z.metadata&&$.blocksOverride===Z.blocksOverride&&$.currentLineOverride===Z.currentLineOverride&&$.streamingMode===Z.streamingMode&&$.renderCodeBlocksAsPlainText===Z.renderCodeBlocksAsPlainText});import{jsxDEV as t0,Fragment as hR}from"react/jsx-dev-runtime";var SR=vQ.memo(({label:$,isSelected:Z})=>t0(K2,{color:Z?"yellow":void 0,children:$},void 0,!1,void 0,this)),fR=vQ.memo(({details:$,headerColor:Z,isPlanModeExit:Y,isPlanModeEnter:Q,terminalWidth:X})=>t0(hR,{children:[$.title&&t0(x1,{marginBottom:1,children:t0(K2,{bold:!0,children:$.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),t0(x1,{marginBottom:1,children:t0(K2,{children:$.message},void 0,!1,void 0,this)},void 0,!1,void 0,this),($.planContent||$.details)&&t0(x1,{flexDirection:"column",marginBottom:1,borderStyle:"single",borderColor:Z,padding:1,children:[t0(K2,{bold:!0,color:Z,children:Y?"\uD83D\uDCCB Implementation Plan:":Q?"\uD83D\uDCDD Details:":"\uD83D\uDCC4 Operation Details:"},void 0,!1,void 0,this),t0(x1,{marginTop:1,children:t0(R8,{content:$.planContent||$.details||"",role:"assistant",terminalWidth:X-4},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$.risks&&$.risks.length>0&&t0(x1,{flexDirection:"column",marginBottom:1,children:[t0(K2,{color:"red",bold:!0,children:"⚠️ 风险提示:"},void 0,!1,void 0,this),$.risks.map((J,G)=>t0(x1,{marginLeft:2,children:t0(K2,{color:"red",children:["• ",J]},void 0,!0,void 0,this)},G,!1,void 0,this))]},void 0,!0,void 0,this),$.affectedFiles&&$.affectedFiles.length>0&&t0(x1,{flexDirection:"column",marginBottom:1,children:[t0(K2,{color:"yellow",children:"\uD83D\uDCC1 影响的文件:"},void 0,!1,void 0,this),$.affectedFiles.slice(0,3).map((J,G)=>t0(x1,{marginLeft:2,children:t0(K2,{children:["• ",J]},void 0,!0,void 0,this)},G,!1,void 0,this)),$.affectedFiles.length>3&&t0(x1,{marginLeft:2,children:t0(K2,{color:"gray",children:["...还有 ",$.affectedFiles.length-3," 个文件"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)),KO=vQ.memo(({details:$,onResponse:Z})=>{let{stdout:Y}=CR(),Q=Y.columns||80,J=_1()==="confirmation-prompt",G=W$(!1),q=$.type==="exitPlanMode",K=$.type==="enterPlanMode",W=$.type==="maxTurnsExceeded";vR((O,F)=>{if(F.ctrl&&O==="c"||F.meta&&O==="c"){G();return}if(F.escape){Z({approved:!1,reason:"用户取消"});return}let _=O.toLowerCase();if(q){if(_==="y"){Z({approved:!0,targetMode:"autoEdit"});return}if(_==="s"){Z({approved:!0,targetMode:"default"});return}if(_==="n"){Z({approved:!1,reason:"方案需要改进"});return}}else if(K){if(_==="y"){Z({approved:!0});return}if(_==="n"){Z({approved:!1,reason:"用户拒绝进入 Plan 模式"});return}}else if(W){if(_==="y"){Z({approved:!0});return}if(_==="n"){Z({approved:!1,reason:"用户选择停止"});return}}else{if(_==="y"){Z({approved:!0,scope:"once"});return}if(_==="s"){Z({approved:!0,scope:"session"});return}if(_==="n"){Z({approved:!1,reason:"用户拒绝"});return}}},{isActive:J});let U=qO(()=>{if(q)return[{key:"approve-auto",label:"[Y] Yes, execute with auto-edit mode",value:{approved:!0,targetMode:"autoEdit"}},{key:"approve-default",label:"[S] Yes, execute with default mode (ask for each operation)",value:{approved:!0,targetMode:"default"}},{key:"reject",label:"[N] No, keep planning",value:{approved:!1,reason:"方案需要改进"}}];if(K)return[{key:"approve",label:"[Y] Yes, enter Plan mode",value:{approved:!0}},{key:"reject",label:"[N] No, proceed directly",value:{approved:!1,reason:"用户拒绝进入 Plan 模式"}}];if(W)return[{key:"continue",label:"[Y] Yes, continue",value:{approved:!0}},{key:"stop",label:"[N] No, stop here",value:{approved:!1,reason:"用户选择停止"}}];return[{key:"approve-once",label:"[Y] Yes (once only)",value:{approved:!0,scope:"once"}},{key:"approve-session",label:"[S] Yes, remember for this project (Shift+Tab)",value:{approved:!0,scope:"session"}},{key:"reject",label:"[N] No",value:{approved:!1,reason:"用户拒绝"}}]},[q,K,W]),H=qO(()=>{if(q)return{color:"cyan",title:"\uD83D\uDD35 Plan Mode - Review Implementation Plan"};if(K)return{color:"magenta",title:"\uD83D\uDFE3 Enter Plan Mode?"};if(W)return{color:"yellow",title:"⚡ Max Turns Exceeded"};return{color:"yellow",title:"\uD83D\uDD14 Confirmation Required"}},[q,K,W]);return t0(x1,{flexDirection:"column",borderStyle:"round",borderColor:J?H.color:"gray",padding:1,children:[t0(x1,{marginBottom:1,children:t0(K2,{bold:!0,color:H.color,children:H.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),t0(fR,{details:$,headerColor:H.color,isPlanModeExit:q,isPlanModeEnter:K,terminalWidth:Q},void 0,!1,void 0,this),t0(x1,{flexDirection:"column",children:[t0(K2,{color:"gray",children:"使用 ↑ ↓ 选择,回车确认(支持 Y/S/N 快捷键,ESC 取消)"},void 0,!1,void 0,this),t0(kR,{items:U,isFocused:J,itemComponent:SR,onSelect:(O)=>{Z(O.value)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});K1();v8();I2();import{Box as y0,Text as W0,useInput as xR}from"ink";import WO from"ink-text-input";import{useState as u2}from"react";import{jsxDEV as u}from"react/jsx-dev-runtime";var C6=[{action:"add",description:"Add a new hook"},{action:"status",description:"Show hooks status"},{action:"list",description:"List all configured hooks"}],k9=[{location:"local",name:"Project settings (local)",description:"Saved in .blade/settings.local.json"},{location:"project",name:"Project settings",description:"Checked in at .blade/settings.json"},{location:"user",name:"User settings",description:"Saved in at ~/.blade/settings.json"}],S9=[{event:"PreToolUse",description:"Before tool execution"},{event:"PostToolUse",description:"After tool execution"},{event:"PostToolUseFailure",description:"After tool execution fails"},{event:"PermissionRequest",description:"When permission is requested"},{event:"UserPromptSubmit",description:"Before processing user prompt"},{event:"Stop",description:"When Claude stops responding"},{event:"SubagentStop",description:"When subagent stops"},{event:"SessionStart",description:"When session starts"},{event:"SessionEnd",description:"When session ends"},{event:"Notification",description:"When notification is sent"},{event:"Compaction",description:"Before context compaction"}],pR=[`jq -r '.tool_input.file_path | select(endswith(".go"))' | xargs -r gofmt -w`,`jq -r '"\\(.tool_input.command) - \\(.tool_input.description // "No description")"' >> ~/.blade/bash-command-log.txt`,"/usr/local/bin/security_check.sh","python3 ~/hooks/validate_changes.py"],UO=({onClose:$,onSave:Z})=>{let Y=E$.getTheme(),[Q,X]=u2("action"),[J,G]=u2(0),[q,K]=u2(0),[W,U]=u2(0),[H,O]=u2(""),[F,_]=u2(""),[z,N]=u2(null),[B,L]=u2(!1),[A,R]=u2(null),V=C6[J],M=S9[q],T=k9[W],w=()=>{if(A){R(null);return}switch(Q){case"action":$();break;case"event":X("action");break;case"matcher":X("event");break;case"command":X("matcher");break;case"location":X("command");break;case"confirm":X("location");break}};xR((I,j)=>{if(j.escape){w();return}if(Q==="action"){if(j.upArrow)G((D)=>D>0?D-1:C6.length-1);else if(j.downArrow)G((D)=>D<C6.length-1?D+1:0);else if(j.return)v()}else if(Q==="event"){if(j.upArrow)K((D)=>D>0?D-1:S9.length-1);else if(j.downArrow)K((D)=>D<S9.length-1?D+1:0);else if(j.return)X("matcher")}else if(Q==="location"){if(j.upArrow)U((D)=>D>0?D-1:k9.length-1);else if(j.downArrow)U((D)=>D<k9.length-1?D+1:0);else if(j.return)X("confirm")}else if(Q==="confirm"){if(j.return)m()}});let v=()=>{let I=C6[J].action;if(I==="add")X("event");else if(I==="status")l();else if(I==="list")o()},l=()=>{let I=T0.getInstance(),j=I.isEnabled(),D=I.getConfig(),i={};for(let k of Object.values(N2)){let e=D[k];if(e&&Array.isArray(e)){let C=e.reduce((r,h)=>r+(h.hooks?.length||0),0);if(C>0)i[k]=C}}let g=[`Status: ${j?"✅ Enabled":"⏸️ Disabled"}`,""];if(Object.keys(i).length>0){g.push("Configured hooks:");for(let[k,e]of Object.entries(i))g.push(` ${k}: ${e} hook(s)`)}else g.push("No hooks configured");R(g.join(`
|
|
2907
|
+
`);if(k===-1)return{completedContent:"",currentLine:y};return{completedContent:y.slice(0,k+1),currentLine:y.slice(k+1)}},[y,X,B,F]),i=GO({content:"",blocks:[]}),g=b8(()=>{if(B)return O??[];if(o)return o;if(l.current&&l.current.messageId===H)return l.current.blocks;let k=i.current;if(!X||!j.startsWith(k.content)){let h=p4(j);return i.current={content:j,blocks:h},h}if(j===k.content)return k.blocks;let e=j.slice(k.content.length),C=p4(e),r=[...k.blocks,...C];return i.current={content:j,blocks:r},r},[j,X,B,O]);return x(N0,{flexDirection:"column",marginBottom:w?1:0,flexShrink:0,children:[m&&x(N0,{flexDirection:"row",flexShrink:0,children:[x(N0,{width:V,flexShrink:0},void 0,!1,void 0,this),x(m0,{color:N.colors.text.muted,dimColor:!0,children:["↑ ",I," lines above (streaming...)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),g.map((k,e)=>{if(k.type==="empty")return x(N0,{height:1,flexShrink:0},e,!1,void 0,this);return x(N0,{flexDirection:"row",flexShrink:0,children:[e===0&&!G&&x(N0,{marginRight:1,flexShrink:0,children:x(m0,{color:A,bold:!0,children:R},void 0,!1,void 0,this)},void 0,!1,void 0,this),(e>0||G)&&x(N0,{width:V,flexShrink:0},void 0,!1,void 0,this),x(N0,{flexGrow:1,flexShrink:0,children:k.type==="code"?z?x(m0,{wrap:"wrap",children:k.content},void 0,!1,void 0,this):x(MR,{content:k.content,language:k.language,terminalWidth:Y-V,isPending:X,availableHeight:J},void 0,!1,void 0,this):k.type==="table"&&k.tableData?x(JO,{headers:k.tableData.headers,rows:k.tableData.rows,terminalWidth:Y-V},void 0,!1,void 0,this):k.type==="heading"?x(jR,{content:k.content,level:k.level||1},void 0,!1,void 0,this):k.type==="list"?x(EQ,{type:k.listType||"ul",marker:k.marker||"-",itemText:k.content,leadingWhitespace:" ".repeat(k.indentation||0)},void 0,!1,void 0,this):k.type==="hr"?x(TR,{terminalWidth:Y-V},void 0,!1,void 0,this):k.type==="diff"&&k.diffData?x(RQ,{patch:k.diffData.patch,startLine:k.diffData.startLine,matchLine:k.diffData.matchLine,terminalWidth:Y-V},void 0,!1,void 0,this):k.type==="command-message"?x(ER,{content:k.content},void 0,!1,void 0,this):x(yR,{content:k.content},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},e,!0,void 0,this)}),D&&x(N0,{flexDirection:"row",flexShrink:0,children:[g.length===0&&!G?x(N0,{marginRight:1,flexShrink:0,children:x(m0,{color:A,bold:!0,children:R},void 0,!1,void 0,this)},void 0,!1,void 0,this):x(N0,{width:V,flexShrink:0},void 0,!1,void 0,this),x(N0,{flexGrow:1,flexShrink:0,children:x(m0,{wrap:"wrap",children:D},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),M&&x(N0,{flexDirection:"row",flexShrink:0,children:[x(N0,{width:V,flexShrink:0},void 0,!1,void 0,this),x(N0,{flexDirection:"column",flexGrow:1,flexShrink:0,children:[x(m0,{color:N.colors.text.muted,children:["Subtask ",typeof M.agentType==="string"?`@${M.agentType}`:"",typeof M.status==="string"?` · ${M.status}`:""]},void 0,!0,void 0,this),typeof M.summary==="string"&&M.summary.trim()!==""&&x(m0,{wrap:"wrap",children:M.summary},void 0,!1,void 0,this),typeof M.childSessionId==="string"&&x(m0,{color:N.colors.text.muted,children:["Session ",M.childSessionId]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},($,Z)=>{return $.content===Z.content&&$.role===Z.role&&$.terminalWidth===Z.terminalWidth&&$.isPending===Z.isPending&&$.availableTerminalHeight===Z.availableTerminalHeight&&$.hidePrefix===Z.hidePrefix&&$.noMargin===Z.noMargin&&$.renderPlainTextOnly===Z.renderPlainTextOnly&&$.streamingHiddenLines===Z.streamingHiddenLines&&$.streamingLines===Z.streamingLines&&$.messageId===Z.messageId&&$.metadata===Z.metadata&&$.blocksOverride===Z.blocksOverride&&$.currentLineOverride===Z.currentLineOverride&&$.streamingMode===Z.streamingMode&&$.renderCodeBlocksAsPlainText===Z.renderCodeBlocksAsPlainText});import{jsxDEV as t0,Fragment as hR}from"react/jsx-dev-runtime";var SR=vQ.memo(({label:$,isSelected:Z})=>t0(K2,{color:Z?"yellow":void 0,children:$},void 0,!1,void 0,this)),fR=vQ.memo(({details:$,headerColor:Z,isPlanModeExit:Y,isPlanModeEnter:Q,terminalWidth:X})=>t0(hR,{children:[$.title&&t0(x1,{marginBottom:1,children:t0(K2,{bold:!0,children:$.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),t0(x1,{marginBottom:1,children:t0(K2,{children:$.message},void 0,!1,void 0,this)},void 0,!1,void 0,this),($.planContent||$.details)&&t0(x1,{flexDirection:"column",marginBottom:1,borderStyle:"single",borderColor:Z,padding:1,children:[t0(K2,{bold:!0,color:Z,children:Y?"\uD83D\uDCCB Implementation Plan:":Q?"\uD83D\uDCDD Details:":"\uD83D\uDCC4 Operation Details:"},void 0,!1,void 0,this),t0(x1,{marginTop:1,children:t0(R8,{content:$.planContent||$.details||"",role:"assistant",terminalWidth:X-4},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$.risks&&$.risks.length>0&&t0(x1,{flexDirection:"column",marginBottom:1,children:[t0(K2,{color:"red",bold:!0,children:"⚠️ 风险提示:"},void 0,!1,void 0,this),$.risks.map((J,G)=>t0(x1,{marginLeft:2,children:t0(K2,{color:"red",children:["• ",J]},void 0,!0,void 0,this)},G,!1,void 0,this))]},void 0,!0,void 0,this),$.affectedFiles&&$.affectedFiles.length>0&&t0(x1,{flexDirection:"column",marginBottom:1,children:[t0(K2,{color:"yellow",children:"\uD83D\uDCC1 影响的文件:"},void 0,!1,void 0,this),$.affectedFiles.slice(0,3).map((J,G)=>t0(x1,{marginLeft:2,children:t0(K2,{children:["• ",J]},void 0,!0,void 0,this)},G,!1,void 0,this)),$.affectedFiles.length>3&&t0(x1,{marginLeft:2,children:t0(K2,{color:"gray",children:["...还有 ",$.affectedFiles.length-3," 个文件"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)),KO=vQ.memo(({details:$,onResponse:Z})=>{let{stdout:Y}=CR(),Q=Y.columns||80,J=_1()==="confirmation-prompt",G=W$(!1),q=$.type==="exitPlanMode",K=$.type==="enterPlanMode",W=$.type==="maxTurnsExceeded";vR((O,F)=>{if(F.ctrl&&O==="c"||F.meta&&O==="c"){G();return}if(F.escape){Z({approved:!1,reason:"用户取消"});return}let _=O.toLowerCase();if(q){if(_==="y"){Z({approved:!0,targetMode:"autoEdit"});return}if(_==="s"){Z({approved:!0,targetMode:"default"});return}if(_==="n"){Z({approved:!1,reason:"方案需要改进"});return}}else if(K){if(_==="y"){Z({approved:!0});return}if(_==="n"){Z({approved:!1,reason:"用户拒绝进入 Plan 模式"});return}}else if(W){if(_==="y"){Z({approved:!0});return}if(_==="n"){Z({approved:!1,reason:"用户选择停止"});return}}else{if(_==="y"){Z({approved:!0,scope:"once"});return}if(_==="s"){Z({approved:!0,scope:"session"});return}if(_==="n"){Z({approved:!1,reason:"用户拒绝"});return}}},{isActive:J});let U=qO(()=>{if(q)return[{key:"approve-auto",label:"[Y] Yes, execute with auto-edit mode",value:{approved:!0,targetMode:"autoEdit"}},{key:"approve-default",label:"[S] Yes, execute with default mode (ask for each operation)",value:{approved:!0,targetMode:"default"}},{key:"reject",label:"[N] No, keep planning",value:{approved:!1,reason:"方案需要改进"}}];if(K)return[{key:"approve",label:"[Y] Yes, enter Plan mode",value:{approved:!0}},{key:"reject",label:"[N] No, proceed directly",value:{approved:!1,reason:"用户拒绝进入 Plan 模式"}}];if(W)return[{key:"continue",label:"[Y] Yes, continue",value:{approved:!0}},{key:"stop",label:"[N] No, stop here",value:{approved:!1,reason:"用户选择停止"}}];return[{key:"approve-once",label:"[Y] Yes (once only)",value:{approved:!0,scope:"once"}},{key:"approve-session",label:"[S] Yes, remember for this project (Shift+Tab)",value:{approved:!0,scope:"session"}},{key:"reject",label:"[N] No",value:{approved:!1,reason:"用户拒绝"}}]},[q,K,W]),H=qO(()=>{if(q)return{color:"cyan",title:"\uD83D\uDD35 Plan Mode - Review Implementation Plan"};if(K)return{color:"magenta",title:"\uD83D\uDFE3 Enter Plan Mode?"};if(W)return{color:"yellow",title:"⚡ Max Turns Exceeded"};return{color:"yellow",title:"\uD83D\uDD14 Confirmation Required"}},[q,K,W]);return t0(x1,{flexDirection:"column",borderStyle:"round",borderColor:J?H.color:"gray",padding:1,children:[t0(x1,{marginBottom:1,children:t0(K2,{bold:!0,color:H.color,children:H.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),t0(fR,{details:$,headerColor:H.color,isPlanModeExit:q,isPlanModeEnter:K,terminalWidth:Q},void 0,!1,void 0,this),t0(x1,{flexDirection:"column",children:[t0(K2,{color:"gray",children:"使用 ↑ ↓ 选择,回车确认(支持 Y/S/N 快捷键,ESC 取消)"},void 0,!1,void 0,this),t0(kR,{items:U,isFocused:J,itemComponent:SR,onSelect:(O)=>{Z(O.value)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});K1();v8();I2();import{Box as y0,Text as W0,useInput as xR}from"ink";import WO from"ink-text-input";import{useState as u2}from"react";import{jsxDEV as u}from"react/jsx-dev-runtime";var C6=[{action:"add",description:"Add a new hook"},{action:"status",description:"Show hooks status"},{action:"list",description:"List all configured hooks"}],k5=[{location:"local",name:"Project settings (local)",description:"Saved in .blade/settings.local.json"},{location:"project",name:"Project settings",description:"Checked in at .blade/settings.json"},{location:"user",name:"User settings",description:"Saved in at ~/.blade/settings.json"}],S5=[{event:"PreToolUse",description:"Before tool execution"},{event:"PostToolUse",description:"After tool execution"},{event:"PostToolUseFailure",description:"After tool execution fails"},{event:"PermissionRequest",description:"When permission is requested"},{event:"UserPromptSubmit",description:"Before processing user prompt"},{event:"Stop",description:"When Claude stops responding"},{event:"SubagentStop",description:"When subagent stops"},{event:"SessionStart",description:"When session starts"},{event:"SessionEnd",description:"When session ends"},{event:"Notification",description:"When notification is sent"},{event:"Compaction",description:"Before context compaction"}],pR=[`jq -r '.tool_input.file_path | select(endswith(".go"))' | xargs -r gofmt -w`,`jq -r '"\\(.tool_input.command) - \\(.tool_input.description // "No description")"' >> ~/.blade/bash-command-log.txt`,"/usr/local/bin/security_check.sh","python3 ~/hooks/validate_changes.py"],UO=({onClose:$,onSave:Z})=>{let Y=E$.getTheme(),[Q,X]=u2("action"),[J,G]=u2(0),[q,K]=u2(0),[W,U]=u2(0),[H,O]=u2(""),[F,_]=u2(""),[z,N]=u2(null),[B,L]=u2(!1),[A,R]=u2(null),V=C6[J],M=S5[q],T=k5[W],w=()=>{if(A){R(null);return}switch(Q){case"action":$();break;case"event":X("action");break;case"matcher":X("event");break;case"command":X("matcher");break;case"location":X("command");break;case"confirm":X("location");break}};xR((I,j)=>{if(j.escape){w();return}if(Q==="action"){if(j.upArrow)G((D)=>D>0?D-1:C6.length-1);else if(j.downArrow)G((D)=>D<C6.length-1?D+1:0);else if(j.return)v()}else if(Q==="event"){if(j.upArrow)K((D)=>D>0?D-1:S5.length-1);else if(j.downArrow)K((D)=>D<S5.length-1?D+1:0);else if(j.return)X("matcher")}else if(Q==="location"){if(j.upArrow)U((D)=>D>0?D-1:k5.length-1);else if(j.downArrow)U((D)=>D<k5.length-1?D+1:0);else if(j.return)X("confirm")}else if(Q==="confirm"){if(j.return)m()}});let v=()=>{let I=C6[J].action;if(I==="add")X("event");else if(I==="status")l();else if(I==="list")o()},l=()=>{let I=T0.getInstance(),j=I.isEnabled(),D=I.getConfig(),i={};for(let k of Object.values(N2)){let e=D[k];if(e&&Array.isArray(e)){let C=e.reduce((r,h)=>r+(h.hooks?.length||0),0);if(C>0)i[k]=C}}let g=[`Status: ${j?"✅ Enabled":"⏸️ Disabled"}`,""];if(Object.keys(i).length>0){g.push("Configured hooks:");for(let[k,e]of Object.entries(i))g.push(` ${k}: ${e} hook(s)`)}else g.push("No hooks configured");R(g.join(`
|
|
2908
2908
|
`))},o=()=>{let j=T0.getInstance().getConfig(),D=[],i=!1;for(let g of Object.values(N2)){let k=j[g];if(!k||!Array.isArray(k)||k.length===0)continue;i=!0,D.push(`${g}:`);for(let e of k){let C=e.matcher,r="all";if(C?.tools)r=`tools: ${Array.isArray(C.tools)?C.tools.join(", "):C.tools}`;D.push(` [${r}]`);for(let h of e.hooks||[])if(h.type==="command")D.push(` → ${h.command}`)}D.push("")}if(!i)D.push("No hooks configured"),D.push(""),D.push("Configure hooks in .blade/settings.local.json");R(D.join(`
|
|
2909
|
-
`))},S=()=>{X("command")},y=()=>{if(!F.trim()){N("Command cannot be empty");return}N(null),X("location")},m=async()=>{L(!0),N(null);try{let I=T0.getInstance(),j=await import("node:fs/promises"),D=await import("node:path"),i=await import("node:os"),g={matcher:H.trim()?{tools:H.trim()}:{},hooks:[{type:"command",command:F.trim()}]},k;switch(T.location){case"local":k=D.join(process.cwd(),".blade","settings.local.json");break;case"project":k=D.join(process.cwd(),".blade","settings.json");break;case"user":k=D.join(i.homedir(),".blade","settings.json");break}await j.mkdir(D.dirname(k),{recursive:!0});let e={};try{let c=await j.readFile(k,"utf-8");e=JSON.parse(c)}catch{}let C=e.hooks||{},r=C[M.event]||[],h={...C,enabled:!0,[M.event]:[...r,g]};if(e.hooks=h,await j.writeFile(k,JSON.stringify(e,null,2),"utf-8"),await I.reloadConfig(),Z)Z({event:M.event,matcher:H.trim(),command:F.trim()});$()}catch(I){N(`Failed to save hook: ${I instanceof Error?I.message:"Unknown error"}`),L(!1)}};return u(y0,{flexDirection:"column",padding:1,children:[u(y0,{marginBottom:1,children:u(W0,{bold:!0,color:Y.colors.success,children:"Hooks Manager"},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(y0,{marginBottom:1,children:u(W0,{color:Y.colors.warning,children:"⚠ Hooks execute shell commands with your full user permissions. Only use hooks from trusted sources."},void 0,!1,void 0,this)},void 0,!1,void 0,this),A&&u(y0,{flexDirection:"column",marginBottom:1,children:[u(W0,{children:A},void 0,!1,void 0,this),u(y0,{marginTop:1,children:u(W0,{color:Y.colors.muted,children:"Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="action"&&!A&&u(y0,{flexDirection:"column",children:[u(y0,{flexDirection:"column",marginTop:1,children:C6.map((I,j)=>u(y0,{children:[u(W0,{color:j===J?Y.colors.primary:void 0,bold:j===J,children:[j===J?"❯ ":" ",I.action]},void 0,!0,void 0,this),u(W0,{color:Y.colors.muted,children:[" - ",I.description]},void 0,!0,void 0,this)]},I.action,!0,void 0,this))},void 0,!1,void 0,this),u(y0,{marginTop:1,children:u(W0,{color:Y.colors.muted,children:"↑/↓ to select · Enter to continue · Esc to close"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="event"&&u(y0,{flexDirection:"column",children:[u(W0,{bold:!0,children:"Select Event:"},void 0,!1,void 0,this),u(y0,{flexDirection:"column",marginTop:1,children:S9.map((I,j)=>u(y0,{children:[u(W0,{color:j===q?Y.colors.primary:void 0,bold:j===q,children:[j===q?"❯ ":" ",I.event]},void 0,!0,void 0,this),u(W0,{color:Y.colors.muted,children:[" - ",I.description]},void 0,!0,void 0,this)]},I.event,!0,void 0,this))},void 0,!1,void 0,this),u(y0,{marginTop:1,children:u(W0,{color:Y.colors.muted,children:"↑/↓ to select · Enter to continue · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q!=="event"&&u(y0,{marginBottom:1,children:u(W0,{children:["Event:"," ",u(W0,{bold:!0,color:Y.colors.primary,children:M.event},void 0,!1,void 0,this),u(W0,{color:Y.colors.muted,children:[" - ",M.description]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),(Q==="matcher"||Q==="command"||Q==="confirm")&&u(y0,{flexDirection:"column",marginBottom:1,children:[u(W0,{color:Y.colors.muted,children:"Input to command is JSON of tool call arguments."},void 0,!1,void 0,this),u(W0,{color:Y.colors.muted,children:"Exit code 0 - stdout/stderr not shown"},void 0,!1,void 0,this),u(W0,{color:Y.colors.muted,children:"Exit code 2 - show stderr to model and block tool call"},void 0,!1,void 0,this),u(W0,{color:Y.colors.muted,children:"Other exit codes - show stderr to user only but continue with tool call"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="matcher"&&u(y0,{flexDirection:"column",children:[u(y0,{children:[u(W0,{bold:!0,children:"Matcher: "},void 0,!1,void 0,this),u(WO,{value:H,onChange:O,onSubmit:S,placeholder:"e.g., Read, Bash, Edit|Write (empty = all tools)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),u(y0,{marginTop:1,children:u(W0,{color:Y.colors.muted,children:"Tool name pattern (supports | for multiple). Leave empty to match all."},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(y0,{marginTop:1,children:u(W0,{color:Y.colors.muted,children:"Enter to continue · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),(Q==="command"||Q==="confirm")&&u(y0,{marginBottom:1,children:u(W0,{children:["Matcher: ",u(W0,{bold:!0,children:H||"(all tools)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q==="command"&&u(y0,{flexDirection:"column",children:[u(y0,{children:u(W0,{bold:!0,children:"Command: "},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(y0,{borderStyle:"single",borderColor:Y.colors.border.light,paddingX:1,marginTop:1,children:u(WO,{value:F,onChange:_,onSubmit:y,placeholder:"Enter shell command..."},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(y0,{flexDirection:"column",marginTop:1,children:[u(W0,{bold:!0,children:"Examples:"},void 0,!1,void 0,this),pR.map((I,j)=>u(W0,{color:Y.colors.muted,children:["• ",I]},j,!0,void 0,this))]},void 0,!0,void 0,this),u(y0,{marginTop:1,children:u(W0,{color:Y.colors.muted,children:"Enter to continue · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="location"&&u(y0,{flexDirection:"column",children:[u(y0,{flexDirection:"column",borderStyle:"round",borderColor:Y.colors.border.light,paddingX:2,paddingY:1,marginBottom:1,children:[u(W0,{bold:!0,color:Y.colors.primary,children:"Save hook configuration"},void 0,!1,void 0,this),u(W0,{children:" "},void 0,!1,void 0,this),u(W0,{children:[" ","Event: ",M.event," - ",M.description]},void 0,!0,void 0,this),u(W0,{children:[" Matcher: ",H||"(all)"]},void 0,!0,void 0,this),u(W0,{children:[" Command: ",F]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),u(W0,{bold:!0,children:"Where should this hook be saved?"},void 0,!1,void 0,this),u(y0,{flexDirection:"column",marginTop:1,children:k9.map((I,j)=>u(y0,{children:[u(W0,{color:j===W?Y.colors.primary:void 0,bold:j===W,children:[j===W?"❯ ":" ",j+1,". ",I.name]},void 0,!0,void 0,this),u(W0,{color:Y.colors.muted,children:[" ",I.description]},void 0,!0,void 0,this)]},I.location,!0,void 0,this))},void 0,!1,void 0,this),u(y0,{marginTop:1,children:u(W0,{color:Y.colors.muted,children:"Enter to confirm · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="confirm"&&u(y0,{flexDirection:"column",children:[u(y0,{flexDirection:"column",borderStyle:"round",borderColor:Y.colors.success,paddingX:2,paddingY:1,children:[u(W0,{bold:!0,children:["Saving hook to ",T.description,"..."]},void 0,!0,void 0,this),u(W0,{children:" "},void 0,!1,void 0,this),u(W0,{children:["Event: ",M.event]},void 0,!0,void 0,this),u(W0,{children:["Matcher: ",H||"(all tools)"]},void 0,!0,void 0,this),u(W0,{children:["Command: ",F]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),u(y0,{marginTop:1,children:u(W0,{color:Y.colors.muted,children:B?"Saving...":"Enter to confirm · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),z&&u(y0,{marginTop:1,children:u(W0,{color:Y.colors.error,children:["❌ ",z]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{useMemoizedFn as AO}from"ahooks";import{Box as oR,Text as sR}from"ink";import tR from"react";import{useMemoizedFn as cR}from"ahooks";import D8 from"chalk";import{Text as lR,useInput as iR}from"ink";import{useEffect as SQ,useRef as fQ}from"react";var d2={TIMEOUT_MS:100,RAPID_INPUT_THRESHOLD_MS:150,LARGE_INPUT_THRESHOLD:300,MEDIUM_SIZE_MULTI_CHUNK_THRESHOLD:200};import{execSync as A3}from"node:child_process";import{existsSync as mR,readFileSync as CQ}from"node:fs";import{basename as HO,isAbsolute as gR}from"node:path";function OO($){try{let Z=Buffer.from($,"base64");if(Z.length<4)return"image/png";if(Z[0]===137&&Z[1]===80&&Z[2]===78&&Z[3]===71)return"image/png";if(Z[0]===255&&Z[1]===216&&Z[2]===255)return"image/jpeg";if(Z[0]===71&&Z[1]===73&&Z[2]===70)return"image/gif";if(Z[0]===82&&Z[1]===73&&Z[2]===70&&Z[3]===70){if(Z.length>=12&&Z[8]===87&&Z[9]===69&&Z[10]===66&&Z[11]===80)return"image/webp"}return"image/png"}catch{return"image/png"}}function FO(){let $=process.platform,Z={darwin:"/tmp/blade_cli_latest_screenshot.png",linux:"/tmp/blade_cli_latest_screenshot.png",win32:process.env.TEMP?`${process.env.TEMP}\\blade_cli_latest_screenshot.png`:"C:\\Temp\\blade_cli_latest_screenshot.png"},Y={darwin:{checkImage:"osascript -e 'the clipboard as «class PNGf»'",saveImage:(Q)=>`osascript -e 'set png_data to (the clipboard as «class PNGf»)' -e 'set fp to open for access POSIX file "${Q}" with write permission' -e 'write png_data to fp' -e 'close access fp'`,getPath:"osascript -e 'get POSIX path of (the clipboard as «class furl»)'",deleteFile:(Q)=>`rm -f "${Q}"`},linux:{checkImage:'xclip -selection clipboard -t TARGETS -o | grep -E "image/(png|jpeg|jpg|gif|webp)"',saveImage:(Q)=>`xclip -selection clipboard -t image/png -o > "${Q}" || wl-paste --type image/png > "${Q}"`,getPath:"xclip -selection clipboard -t text/plain -o",deleteFile:(Q)=>`rm -f "${Q}"`},win32:{checkImage:'powershell -Command "(Get-Clipboard -Format Image) -ne $null"',saveImage:(Q)=>`powershell -Command "$img = Get-Clipboard -Format Image; if ($img) { $img.Save('${Q.replace(/\\/g,"\\\\")}', [System.Drawing.Imaging.ImageFormat]::Png) }"`,getPath:'powershell -Command "Get-Clipboard"',deleteFile:(Q)=>`del /f "${Q}"`}};return{commands:Y[$]||Y.linux,screenshotPath:Z[$]||Z.linux}}function uR(){let{commands:$}=FO();try{return A3($.getPath,{encoding:"utf-8"}).trim()}catch(Z){return console.error("Failed to get clipboard path:",Z),null}}function _O($){if($.startsWith('"')&&$.endsWith('"')||$.startsWith("'")&&$.endsWith("'"))return $.slice(1,-1);return $}function zO($){if(process.platform==="win32")return $;let Z="__DOUBLE_BACKSLASH__";return $.replace(/\\\\/g,Z).replace(/\\(.)/g,"$1").replace(new RegExp(Z,"g"),"\\")}function kQ($){let Z=_O($.trim()),Y=zO(Z);return/\.(png|jpe?g|gif|webp)$/i.test(Y)}function dR($){let Z=_O($.trim()),Y=zO(Z);if(kQ(Y))return Y;return null}async function BO($){let Z=dR($);if(!Z)return null;let Y;try{if(gR(Z))Y=CQ(Z);else{let G=uR();if(G&&Z===HO(G))Y=CQ(G);else return null}}catch(G){return console.error("Failed to read image file:",G),null}let Q=Y.toString("base64"),X=OO(Q),J=HO(Z);return{path:Z,base64:Q,mediaType:X,filename:J}}async function NO(){let $=process.platform,Z={darwin:"pbpaste",linux:"xclip -selection clipboard -o || wl-paste",win32:'powershell -Command "Get-Clipboard"'},Y=Z[$]||Z.linux;try{return A3(Y,{encoding:"utf-8"})||null}catch{return null}}async function LO(){let{commands:$,screenshotPath:Z}=FO();try{if(A3($.checkImage,{stdio:"ignore"}),A3($.saveImage(Z),{stdio:"ignore"}),!mR(Z))return null;let Q=CQ(Z).toString("base64"),X=OO(Q);return A3($.deleteFile(Z),{stdio:"ignore"}),{base64:Q,mediaType:X}}catch(Y){try{A3($.deleteFile(Z),{stdio:"ignore"})}catch{}return null}}import{jsxDEV as nR}from"react/jsx-dev-runtime";var rR=/\r\n/g,aR=/\r/g;function M8($){if(!$.includes("\r"))return $;return $.replace(rR,`
|
|
2909
|
+
`))},S=()=>{X("command")},y=()=>{if(!F.trim()){N("Command cannot be empty");return}N(null),X("location")},m=async()=>{L(!0),N(null);try{let I=T0.getInstance(),j=await import("node:fs/promises"),D=await import("node:path"),i=await import("node:os"),g={matcher:H.trim()?{tools:H.trim()}:{},hooks:[{type:"command",command:F.trim()}]},k;switch(T.location){case"local":k=D.join(process.cwd(),".blade","settings.local.json");break;case"project":k=D.join(process.cwd(),".blade","settings.json");break;case"user":k=D.join(i.homedir(),".blade","settings.json");break}await j.mkdir(D.dirname(k),{recursive:!0});let e={};try{let c=await j.readFile(k,"utf-8");e=JSON.parse(c)}catch{}let C=e.hooks||{},r=C[M.event]||[],h={...C,enabled:!0,[M.event]:[...r,g]};if(e.hooks=h,await j.writeFile(k,JSON.stringify(e,null,2),"utf-8"),await I.reloadConfig(),Z)Z({event:M.event,matcher:H.trim(),command:F.trim()});$()}catch(I){N(`Failed to save hook: ${I instanceof Error?I.message:"Unknown error"}`),L(!1)}};return u(y0,{flexDirection:"column",padding:1,children:[u(y0,{marginBottom:1,children:u(W0,{bold:!0,color:Y.colors.success,children:"Hooks Manager"},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(y0,{marginBottom:1,children:u(W0,{color:Y.colors.warning,children:"⚠ Hooks execute shell commands with your full user permissions. Only use hooks from trusted sources."},void 0,!1,void 0,this)},void 0,!1,void 0,this),A&&u(y0,{flexDirection:"column",marginBottom:1,children:[u(W0,{children:A},void 0,!1,void 0,this),u(y0,{marginTop:1,children:u(W0,{color:Y.colors.muted,children:"Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="action"&&!A&&u(y0,{flexDirection:"column",children:[u(y0,{flexDirection:"column",marginTop:1,children:C6.map((I,j)=>u(y0,{children:[u(W0,{color:j===J?Y.colors.primary:void 0,bold:j===J,children:[j===J?"❯ ":" ",I.action]},void 0,!0,void 0,this),u(W0,{color:Y.colors.muted,children:[" - ",I.description]},void 0,!0,void 0,this)]},I.action,!0,void 0,this))},void 0,!1,void 0,this),u(y0,{marginTop:1,children:u(W0,{color:Y.colors.muted,children:"↑/↓ to select · Enter to continue · Esc to close"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="event"&&u(y0,{flexDirection:"column",children:[u(W0,{bold:!0,children:"Select Event:"},void 0,!1,void 0,this),u(y0,{flexDirection:"column",marginTop:1,children:S5.map((I,j)=>u(y0,{children:[u(W0,{color:j===q?Y.colors.primary:void 0,bold:j===q,children:[j===q?"❯ ":" ",I.event]},void 0,!0,void 0,this),u(W0,{color:Y.colors.muted,children:[" - ",I.description]},void 0,!0,void 0,this)]},I.event,!0,void 0,this))},void 0,!1,void 0,this),u(y0,{marginTop:1,children:u(W0,{color:Y.colors.muted,children:"↑/↓ to select · Enter to continue · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q!=="event"&&u(y0,{marginBottom:1,children:u(W0,{children:["Event:"," ",u(W0,{bold:!0,color:Y.colors.primary,children:M.event},void 0,!1,void 0,this),u(W0,{color:Y.colors.muted,children:[" - ",M.description]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),(Q==="matcher"||Q==="command"||Q==="confirm")&&u(y0,{flexDirection:"column",marginBottom:1,children:[u(W0,{color:Y.colors.muted,children:"Input to command is JSON of tool call arguments."},void 0,!1,void 0,this),u(W0,{color:Y.colors.muted,children:"Exit code 0 - stdout/stderr not shown"},void 0,!1,void 0,this),u(W0,{color:Y.colors.muted,children:"Exit code 2 - show stderr to model and block tool call"},void 0,!1,void 0,this),u(W0,{color:Y.colors.muted,children:"Other exit codes - show stderr to user only but continue with tool call"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="matcher"&&u(y0,{flexDirection:"column",children:[u(y0,{children:[u(W0,{bold:!0,children:"Matcher: "},void 0,!1,void 0,this),u(WO,{value:H,onChange:O,onSubmit:S,placeholder:"e.g., Read, Bash, Edit|Write (empty = all tools)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),u(y0,{marginTop:1,children:u(W0,{color:Y.colors.muted,children:"Tool name pattern (supports | for multiple). Leave empty to match all."},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(y0,{marginTop:1,children:u(W0,{color:Y.colors.muted,children:"Enter to continue · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),(Q==="command"||Q==="confirm")&&u(y0,{marginBottom:1,children:u(W0,{children:["Matcher: ",u(W0,{bold:!0,children:H||"(all tools)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q==="command"&&u(y0,{flexDirection:"column",children:[u(y0,{children:u(W0,{bold:!0,children:"Command: "},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(y0,{borderStyle:"single",borderColor:Y.colors.border.light,paddingX:1,marginTop:1,children:u(WO,{value:F,onChange:_,onSubmit:y,placeholder:"Enter shell command..."},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(y0,{flexDirection:"column",marginTop:1,children:[u(W0,{bold:!0,children:"Examples:"},void 0,!1,void 0,this),pR.map((I,j)=>u(W0,{color:Y.colors.muted,children:["• ",I]},j,!0,void 0,this))]},void 0,!0,void 0,this),u(y0,{marginTop:1,children:u(W0,{color:Y.colors.muted,children:"Enter to continue · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="location"&&u(y0,{flexDirection:"column",children:[u(y0,{flexDirection:"column",borderStyle:"round",borderColor:Y.colors.border.light,paddingX:2,paddingY:1,marginBottom:1,children:[u(W0,{bold:!0,color:Y.colors.primary,children:"Save hook configuration"},void 0,!1,void 0,this),u(W0,{children:" "},void 0,!1,void 0,this),u(W0,{children:[" ","Event: ",M.event," - ",M.description]},void 0,!0,void 0,this),u(W0,{children:[" Matcher: ",H||"(all)"]},void 0,!0,void 0,this),u(W0,{children:[" Command: ",F]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),u(W0,{bold:!0,children:"Where should this hook be saved?"},void 0,!1,void 0,this),u(y0,{flexDirection:"column",marginTop:1,children:k5.map((I,j)=>u(y0,{children:[u(W0,{color:j===W?Y.colors.primary:void 0,bold:j===W,children:[j===W?"❯ ":" ",j+1,". ",I.name]},void 0,!0,void 0,this),u(W0,{color:Y.colors.muted,children:[" ",I.description]},void 0,!0,void 0,this)]},I.location,!0,void 0,this))},void 0,!1,void 0,this),u(y0,{marginTop:1,children:u(W0,{color:Y.colors.muted,children:"Enter to confirm · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="confirm"&&u(y0,{flexDirection:"column",children:[u(y0,{flexDirection:"column",borderStyle:"round",borderColor:Y.colors.success,paddingX:2,paddingY:1,children:[u(W0,{bold:!0,children:["Saving hook to ",T.description,"..."]},void 0,!0,void 0,this),u(W0,{children:" "},void 0,!1,void 0,this),u(W0,{children:["Event: ",M.event]},void 0,!0,void 0,this),u(W0,{children:["Matcher: ",H||"(all tools)"]},void 0,!0,void 0,this),u(W0,{children:["Command: ",F]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),u(y0,{marginTop:1,children:u(W0,{color:Y.colors.muted,children:B?"Saving...":"Enter to confirm · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),z&&u(y0,{marginTop:1,children:u(W0,{color:Y.colors.error,children:["❌ ",z]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{useMemoizedFn as AO}from"ahooks";import{Box as oR,Text as sR}from"ink";import tR from"react";import{useMemoizedFn as cR}from"ahooks";import D8 from"chalk";import{Text as lR,useInput as iR}from"ink";import{useEffect as SQ,useRef as fQ}from"react";var d2={TIMEOUT_MS:100,RAPID_INPUT_THRESHOLD_MS:150,LARGE_INPUT_THRESHOLD:300,MEDIUM_SIZE_MULTI_CHUNK_THRESHOLD:200};import{execSync as A3}from"node:child_process";import{existsSync as mR,readFileSync as CQ}from"node:fs";import{basename as HO,isAbsolute as gR}from"node:path";function OO($){try{let Z=Buffer.from($,"base64");if(Z.length<4)return"image/png";if(Z[0]===137&&Z[1]===80&&Z[2]===78&&Z[3]===71)return"image/png";if(Z[0]===255&&Z[1]===216&&Z[2]===255)return"image/jpeg";if(Z[0]===71&&Z[1]===73&&Z[2]===70)return"image/gif";if(Z[0]===82&&Z[1]===73&&Z[2]===70&&Z[3]===70){if(Z.length>=12&&Z[8]===87&&Z[9]===69&&Z[10]===66&&Z[11]===80)return"image/webp"}return"image/png"}catch{return"image/png"}}function FO(){let $=process.platform,Z={darwin:"/tmp/blade_cli_latest_screenshot.png",linux:"/tmp/blade_cli_latest_screenshot.png",win32:process.env.TEMP?`${process.env.TEMP}\\blade_cli_latest_screenshot.png`:"C:\\Temp\\blade_cli_latest_screenshot.png"},Y={darwin:{checkImage:"osascript -e 'the clipboard as «class PNGf»'",saveImage:(Q)=>`osascript -e 'set png_data to (the clipboard as «class PNGf»)' -e 'set fp to open for access POSIX file "${Q}" with write permission' -e 'write png_data to fp' -e 'close access fp'`,getPath:"osascript -e 'get POSIX path of (the clipboard as «class furl»)'",deleteFile:(Q)=>`rm -f "${Q}"`},linux:{checkImage:'xclip -selection clipboard -t TARGETS -o | grep -E "image/(png|jpeg|jpg|gif|webp)"',saveImage:(Q)=>`xclip -selection clipboard -t image/png -o > "${Q}" || wl-paste --type image/png > "${Q}"`,getPath:"xclip -selection clipboard -t text/plain -o",deleteFile:(Q)=>`rm -f "${Q}"`},win32:{checkImage:'powershell -Command "(Get-Clipboard -Format Image) -ne $null"',saveImage:(Q)=>`powershell -Command "$img = Get-Clipboard -Format Image; if ($img) { $img.Save('${Q.replace(/\\/g,"\\\\")}', [System.Drawing.Imaging.ImageFormat]::Png) }"`,getPath:'powershell -Command "Get-Clipboard"',deleteFile:(Q)=>`del /f "${Q}"`}};return{commands:Y[$]||Y.linux,screenshotPath:Z[$]||Z.linux}}function uR(){let{commands:$}=FO();try{return A3($.getPath,{encoding:"utf-8"}).trim()}catch(Z){return console.error("Failed to get clipboard path:",Z),null}}function _O($){if($.startsWith('"')&&$.endsWith('"')||$.startsWith("'")&&$.endsWith("'"))return $.slice(1,-1);return $}function zO($){if(process.platform==="win32")return $;let Z="__DOUBLE_BACKSLASH__";return $.replace(/\\\\/g,Z).replace(/\\(.)/g,"$1").replace(new RegExp(Z,"g"),"\\")}function kQ($){let Z=_O($.trim()),Y=zO(Z);return/\.(png|jpe?g|gif|webp)$/i.test(Y)}function dR($){let Z=_O($.trim()),Y=zO(Z);if(kQ(Y))return Y;return null}async function BO($){let Z=dR($);if(!Z)return null;let Y;try{if(gR(Z))Y=CQ(Z);else{let G=uR();if(G&&Z===HO(G))Y=CQ(G);else return null}}catch(G){return console.error("Failed to read image file:",G),null}let Q=Y.toString("base64"),X=OO(Q),J=HO(Z);return{path:Z,base64:Q,mediaType:X,filename:J}}async function NO(){let $=process.platform,Z={darwin:"pbpaste",linux:"xclip -selection clipboard -o || wl-paste",win32:'powershell -Command "Get-Clipboard"'},Y=Z[$]||Z.linux;try{return A3(Y,{encoding:"utf-8"})||null}catch{return null}}async function LO(){let{commands:$,screenshotPath:Z}=FO();try{if(A3($.checkImage,{stdio:"ignore"}),A3($.saveImage(Z),{stdio:"ignore"}),!mR(Z))return null;let Q=CQ(Z).toString("base64"),X=OO(Q);return A3($.deleteFile(Z),{stdio:"ignore"}),{base64:Q,mediaType:X}}catch(Y){try{A3($.deleteFile(Z),{stdio:"ignore"})}catch{}return null}}import{jsxDEV as nR}from"react/jsx-dev-runtime";var rR=/\r\n/g,aR=/\r/g;function M8($){if(!$.includes("\r"))return $;return $.replace(rR,`
|
|
2910
2910
|
`).replace(aR,`
|
|
2911
2911
|
`)}function j8($,Z,Y){let Q=Math.max(0,Math.min(Y,Z.length)),X=Z.slice(0,Q),J=Z.slice(Q);return{newValue:X+$+J,newCursorPosition:Q+$.length}}function wO({value:$,placeholder:Z="",focus:Y=!0,onChange:Q,cursorPosition:X,onChangeCursorPosition:J,onPaste:G,onImagePaste:q,disabledKeys:K=[]}){let W=fQ({chunks:[],timeoutId:null,firstInputTime:null,lastInputTime:null,totalLength:0}),U=fQ($),H=fQ(X);SQ(()=>{U.current=$,H.current=X},[$,X]),SQ(()=>{return()=>{if(W.current.timeoutId)clearTimeout(W.current.timeoutId)}},[]),SQ(()=>{if(X>$.length)J($.length)},[$,X,J]);let O=cR(()=>{let N=W.current;if(N.timeoutId)clearTimeout(N.timeoutId);let B=setTimeout(async()=>{let L=W.current.chunks,A=W.current.totalLength;if(L.length===0)return;let R=M8(L.join(""));W.current={chunks:[],timeoutId:null,firstInputTime:null,lastInputTime:null,totalLength:0};let V=U.current,M=H.current;if(q&&kQ(R))try{let S=await BO(R);if(S){let y=await q(S.base64,S.mediaType,S.filename);if(y?.prompt){let m=M8(y.prompt),{newValue:I,newCursorPosition:j}=j8(m,V,M);Q(I),J(j)}return}}catch(S){console.error("Failed to process image path:",S)}let T=R.includes(`
|
|
2912
2912
|
`),w=A>d2.MEDIUM_SIZE_MULTI_CHUNK_THRESHOLD&&L.length>3;if((A>d2.LARGE_INPUT_THRESHOLD||T||w)&&G){let S=await G(R);if(S?.prompt){let y=M8(S.prompt),{newValue:m,newCursorPosition:I}=j8(y,V,M);Q(m),J(I);return}}let{newValue:l,newCursorPosition:o}=j8(R,V,M);Q(l),J(o)},d2.TIMEOUT_MS);W.current.timeoutId=B});iR((N,B)=>{let L=M8(N);if(K.some((w)=>B[w])||B.ctrl&&N==="c"||B.ctrl&&N==="l"||B.ctrl&&N==="t"||B.ctrl&&N==="o"||B.meta&&N==="l"||B.meta&&N==="t"||B.meta&&N==="o"||B.shift&&B.tab||L==="?"&&$==="")return;let R=Date.now(),V=W.current,M=X,T=$;if(B.leftArrow)M--;else if(B.rightArrow)M++;else if(B.backspace||B.delete){if(N===""){if(X>0)T=$.slice(0,X-1)+$.slice(X,$.length),M--}else if(X<$.length)T=$.slice(0,X)+$.slice(X+1,$.length)}else if(B.ctrl&&L==="a")M=0;else if(B.ctrl&&L==="e")M=$.length;else if(B.ctrl&&L==="k")T=$.slice(0,X);else if(B.ctrl&&L==="u")T=$.slice(X),M=0;else if(B.ctrl&&L==="w"){let v=$.slice(0,X).match(/\s*\S+\s*$/);if(v){let l=v[0].length;T=$.slice(0,X-l)+$.slice(X),M-=l}}else if(B.ctrl&&L==="v"){let w=process.platform==="darwin";(async()=>{if(q){let l=await LO();if(l){let o=await q(l.base64,l.mediaType,"clipboard.png");if(o?.prompt){let S=M8(o.prompt),{newValue:y,newCursorPosition:m}=j8(S,U.current,H.current);Q(y),J(m)}return}}if(w)return;let v=await NO();if(v){let l=M8(v),o=l.includes(`
|
|
2913
2913
|
`),S=l.length>d2.LARGE_INPUT_THRESHOLD;if((o||S)&&G){let I=await G(l);if(I?.prompt){let j=M8(I.prompt),{newValue:D,newCursorPosition:i}=j8(j,U.current,H.current);Q(D),J(i);return}}let{newValue:y,newCursorPosition:m}=j8(l,U.current,H.current);Q(y),J(m)}})().catch(()=>{});return}else if(B.pageUp)M=0;else if(B.pageDown)M=$.length;else if(L===`
|
|
2914
2914
|
`&&(B.shift||B.meta)){let{newValue:w,newCursorPosition:v}=j8(L,$,X);Q(w),J(v);return}else if(!B.ctrl&&!B.meta){if(!V.firstInputTime)V.firstInputTime=R;V.lastInputTime=R;let w=R-(V.firstInputTime||R),v=L.length>d2.LARGE_INPUT_THRESHOLD,l=L.includes(`
|
|
2915
2915
|
`)&&L.length>1,o=w<d2.RAPID_INPUT_THRESHOLD_MS&&V.chunks.length>0,S=w<d2.RAPID_INPUT_THRESHOLD_MS&&L.length>10,y=V.timeoutId!==null;if(G&&(v||l||o||S||y)){V.chunks.push(L),V.totalLength+=L.length,O();return}if(L.length===1&&!V.timeoutId)V.chunks=[],V.firstInputTime=null,V.lastInputTime=null,V.totalLength=0;T=$.slice(0,X)+L+$.slice(X,$.length),M+=L.length}if(M<0)M=0;if(M>T.length)M=T.length;if(T!==$)Q(T);if(M!==X)J(M)},{isActive:Y});let F=Y,_=$,z=Z?D8.grey(Z):void 0;if(F)if(z=Z.length>0?D8.inverse(Z[0])+D8.grey(Z.slice(1)):D8.inverse(" "),$.length===0)_=D8.inverse(" ");else{_="";for(let N=0;N<$.length;N++)if(N===X&&X<$.length)_+=D8.inverse($[N]);else _+=$[N];if(X>=$.length)_+=D8.inverse(" ")}return nR(lR,{children:Z?$.length>0?_:z:_},void 0,!1,void 0,this)}import{jsxDEV as hQ}from"react/jsx-dev-runtime";var bO=tR.memo(({input:$,cursorPosition:Z,onChange:Y,onChangeCursorPosition:Q,onAddPasteMapping:X,onAddImagePasteMapping:J})=>{let q=_1()==="main-input",K=AO((U)=>{let H=U.split(`
|
|
2916
|
-
`).length,O=U.length,F=500,_=10;if(O>500||H>10){let z=X(U),N=U.slice(0,30).replace(/\n/g," "),B=`${O} chars, ${H} lines: ${N}...`;return{prompt:`${
|
|
2916
|
+
`).length,O=U.length,F=500,_=10;if(O>500||H>10){let z=X(U),N=U.slice(0,30).replace(/\n/g," "),B=`${O} chars, ${H} lines: ${N}...`;return{prompt:`${D5(z)}${B}${KQ()}`}}return{}}),W=AO(async(U,H,O)=>{try{let F=J(U,H);return{prompt:`${D5(F)}[Image #${F}]${KQ()}`}}catch(F){return console.error("[Image Paste] Failed to process image:",F),{prompt:`[Image paste failed: ${F instanceof Error?F.message:"Unknown error"}] `}}});return hQ(oR,{flexDirection:"row",width:"100%",paddingX:2,paddingY:0,flexShrink:0,flexGrow:0,overflow:"hidden",borderStyle:"round",borderColor:"gray",children:[hQ(sR,{color:"blue",bold:!0,children:"> "},void 0,!1,void 0,this),hQ(wO,{value:$,cursorPosition:Z,onChange:Y,onChangeCursorPosition:Q,onPaste:K,onImagePaste:W,placeholder:" 输入命令...",focus:q,disabledKeys:["upArrow","downArrow","tab","return","escape"]},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});import{Box as f5,Text as W2}from"ink";import QD,{useEffect as XD,useState as JD}from"react";import{useEffect as YD,useState as MO}from"react";import{useEffect as eR,useState as $D}from"react";var ZD=15000,VO=["炼化代码灵气...","参悟 AST 道法...","推演算法天机...","重铸代码根基...","破解逻辑封印...","凝练类型真元...","铸就函数金丹...","渡劫编译雷劫...","打通模块任督二脉...","修炼 Tree-shaking 神功...","压缩代码乾坤...","布下 Source Map 阵法...","推演 Token 灵数...","炼制 Prompt 仙丹...","调息温度参数...","参透困惑度玄机...","驱动 LLM 灵力...","施展向量搜索术...","构筑 RAG 法阵...","凝聚 Embedding 道果...","勾连向量宝库...","破译函数咒语...","验证 Schema 真意...","封印工具参数...","注入系统道韵...","串联历史因果...","炼化抽象语法树...","破境重构神功...","感悟类型天道...","筑基模块根基...","施展词法轻功...","破解语法阵法...","参悟语义心法...","凝练中间内力...","修炼优化神功...","调息寄存器真气...","运转指令招式...","消除死码杂念...","折叠常量真元...","内联函数身法...","逃逸分析密探...","垃圾回收扫地僧...","标记清除掌法...","分代回收心诀...","增量收功法门...","JIT 即时顿悟...","解读字节码暗器...","V8 引擎神功...","召唤 WASM 傀儡...","开辟虚拟洞府...","丹田分配内存...","掌控栈帧乾坤...","捕获异常剑气...","尾调优化身法...","动态链接飞剑...","建立 TCP 金桥...","三次握手结契...","传送 HTTP 信使...","破译响应符文...","TLS 秘境握手...","验证 SSL 信物...","WebSocket 通灵...","流式传功大法...","gRPC 御剑飞行...","Protobuf 封印术...","GraphQL 问道...","DNS 测算域名...","负载均衡五行阵...","CDN 边缘瞬移...","HTTP/2 分身术...","QUIC 闪现神通...","gzip 缩地成寸...","Brotli 玄冰压缩...","断点续传接续术...","分片上传合璧功...","参研 SQL 真经...","推演查询路径...","索引扫描神识...","全表扫描暴力突破...","执行 JOIN 双修大法...","聚合数据炼丹...","事务提交天地誓...","ACID 四象护法...","乐观锁道心无畏...","悲观锁剑阵守护...","分布式锁万里封禁...","Redis 炼药鼎缓存...","LRU 新陈代谢...","WAL 预写因果簿...","B+ 树平衡阴阳...","LSM 树合璧压缩...","向量宝库搜寻...","余弦相似度测算...","KNN 近邻追踪...","倒排索引翻阅秘籍...","快速排序剑法...","归并排序双刀...","堆排优化内功...","二分查找闪现...","深度优先潜行...","广度优先横扫...","Dijkstra 寻路神算...","A* 天机推演...","动态规划填棋盘...","回溯剑法剪枝...","贪心策略奇谋...","分治递归化身术...","哈希表扩容开天...","红黑树旋转太极...","AVL 树平衡阴阳...","跳表纵身轻功...","Trie 树千头万绪...","布隆过滤天罗地网...","一致性哈希环定乾坤...","最小生成树扎根...","Docker 镜像炼制...","Kubernetes 调兵遣将...","容器结界布阵...","卷挂载空间挪移...","Helm 符箓展开...","CI/CD 流水线作业...","GitHub 门派行动...","代码品鉴术...","漏洞探查密探...","依赖追溯寻根...","蓝绿部署换防...","金丝雀试探...","回滚时光倒流...","健康探查望闻问切...","日志归档藏经阁...","监控预警千里眼...","告警通知飞鸽传书...","性能调优筋骨重塑...","扩容缩容易筋经...","灰度发布声东击西...","React 虚影对决...","组件树调和大法...","Hooks 勾魂术...","useEffect 副作用因果...","Redux 中枢天宫...","Zustand 灵台藏识...","CSS-in-JS 画地为牢...","Tailwind 疾风步...","Webpack 热更换血重生...","Vite 按需凝形...","ESBuild 极速神行...","SWC 闪电炼形...","SSR 天地初开...","Hydration 魂归肉身...","Ink 终端墨宝...","虚拟 DOM 镜花水月...","事件冒泡顺流而上...","状态提升登峰造极...","懒加载厚积薄发...","代码分割庖丁解牛...","SHA-256 炼心咒...","AES-256 玄冰封印...","RSA 阴阳双钥...","JWT 信物令牌...","OAuth 门派授权...","CSRF 防御结界...","XSS 祛邪过滤...","SQL 注入克星...","PBKDF2 淬炼秘钥...","零知识誓言验证...","HTTPS 金钟罩...","签名验证印玺鉴定...","盐值加密炼丹配方...","双因素认证双重认证...","权限控制天条律令...","拜见图灵祖师爷...","冯·诺依曼传道...","Linus 大侠坐镇...","参悟 Rust 生命轮回...","逃离回调地狱轮回...","await 静待天时...","捕获野生 Bug 妖兽...","喂养橡皮鸭灵兽 \uD83E\uDD86...","炼丹调参秘术...","0xDEADBEEF 死亡凝视...","递归无限轮回...","闭包封印记忆...","Promise 未来契约...","async 异步神功...","Generator 分身术...","Proxy 替身傀儡...","Reflect 返照镜...","Symbol 独一无二印记...","WeakMap 过眼云烟...","Iterator 周而复始...","GitHub 武林大会...","Star 点赞声望...","Fork 拜师学艺...","Pull Request 挑战切磋...","Code Review 武功点评...","Issue 悬赏令...","Merge 收徒入门...","Commit 闭关修炼记录...","Branch 分支独辟蹊径...","Tag 里程碑界碑...","Release 出关发布...","License 门规戒律...","README 入门心法...","Documentation 武学秘籍...","Open Source 广纳贤才..."],RO=["Esc - 停止任务 / 隐藏建议 / 双击清空输入","Shift+Tab - 切换模式 (DEFAULT → AUTO_EDIT → PLAN → SPEC)","Tab - 选中建议 / 切换 thinking 模式","↑↓ - 浏览建议或输入历史记录","? - 显示快捷键帮助面板(输入框为空时)","Ctrl+C - 停止任务(双击退出应用)","Ctrl+L - 清屏(清除所有消息)","Ctrl+T - 切换 thinking 内容展开/折叠","Ctrl+O - 切换历史消息展开/折叠","Ctrl+U - 删除从行首到光标的内容","Ctrl+K - 删除从光标到行尾的内容","Shift+Enter - 插入换行(多行输入)","/help - 显示所有可用的 slash commands","/init - 分析项目并生成 BLADE.md 配置","/resume - 恢复历史会话","/compact - 手动压缩当前会话上下文","/theme - 打开交互式主题选择器","/model - 管理和切换模型配置","/model add - 添加新模型配置","/permissions - 管理项目的本地权限规则","/mcp - 显示 MCP 服务器状态和可用工具","/agents - 管理 subagent 配置","/version - 显示版本信息和构建详情","/clear - 清除屏幕内容和对话历史","/status - 显示当前项目配置状态","/context - 可视化当前上下文 Token 使用情况","/git - Git 仓库查询和 AI 辅助","/git review - AI Code Review","/hooks - 管理 Hook 配置","/tasks - 列出所有后台任务","@ 文件路径 - 附加文件到上下文","@dir/ - 附加整个目录","@file.ts:10-20 - 附加指定行范围","Plan 模式 - 先规划后编码(Shift+Tab 切换)","Auto Edit 模式 - 自动批准工具调用","MCP 协议 - 扩展外部工具集成","Subagents - 并行执行子任务","Hooks 系统 - 自定义工具执行流程","Context 压缩 - 自动总结历史对话","Loop 检测 - 防止无限循环","提示:使用 /init 让 AI 理解你的项目结构","提示:Plan 模式适合复杂多步骤任务","提示:Auto Edit 可加速重复性操作","提示:@ 引用可提供更精准的上下文","提示:定期 /compact 节省 token 成本","提示:使用 /permissions 控制工具权限","提示:Shift+Tab 快速切换模式","提示:Esc 可随时中断长时间任务","提示:/resume 继续未完成的对话","提示:/git commit 让 AI 生成 commit message"];function DO($,Z,Y=!1){let[Q,X]=$D("");return eR(()=>{if(Z){X("等待用户确认...");return}if(!$){X("");return}if(Y)return;let J=()=>{if(Math.random()<0.16666666666666666){let W=Math.floor(Math.random()*RO.length);return RO[W]}let K=Math.floor(Math.random()*VO.length);return VO[K]};X(J());let G=setInterval(()=>{X(J())},ZD);return()=>{clearInterval(G)}},[$,Z,Y]),Q}function jO($,Z=!1,Y=!1){let[Q,X]=MO(0),[J,G]=MO(null),q=DO($,Z,Y);return YD(()=>{if(!$){X(0),G(null);return}if(Y)return;if(J===null)G(Date.now());let K=setInterval(()=>{if(J!==null){let W=Math.floor((Date.now()-J)/1000);X(W)}},1000);return()=>{clearInterval(K)}},[$,J,Y]),{currentPhrase:q,elapsedTime:Q}}import{jsxDEV as r$,Fragment as qD}from"react/jsx-dev-runtime";var xQ=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"],GD=80;function TO($){if($<60)return`${$}s`;let Z=Math.floor($/60),Y=$%60;return`${Z}m ${Y}s`}var yO=QD.memo(({message:$,paused:Z=!1})=>{let Y=j4(),Q=L5(),X=Y||!Q,[J,G]=JD(0),q=o0(),W=_3()>=GD,{currentPhrase:U,elapsedTime:H}=jO(X,!1,Z);if(XD(()=>{if(!X||Z){G(0);return}let F=setInterval(()=>{G((_)=>(_+1)%xQ.length)},150);return()=>clearInterval(F)},[X,Z]),!X)return null;let O=U||$||"正在思考中...";if(W)return r$(f5,{paddingX:2,paddingBottom:1,flexDirection:"row",gap:1,children:[r$(W2,{color:q.colors.warning,bold:!0,children:xQ[J]},void 0,!1,void 0,this),r$(W2,{color:q.colors.text.primary,children:O},void 0,!1,void 0,this),H>0&&r$(qD,{children:[r$(W2,{color:q.colors.muted,children:"|"},void 0,!1,void 0,this),r$(W2,{color:q.colors.info,children:["已用时: ",TO(H)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),r$(W2,{color:q.colors.muted,children:"|"},void 0,!1,void 0,this),r$(W2,{color:q.colors.secondary,children:"Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return r$(f5,{paddingX:2,paddingBottom:1,flexDirection:"column",children:[r$(f5,{flexDirection:"row",gap:1,children:[r$(W2,{color:q.colors.warning,bold:!0,children:xQ[J]},void 0,!1,void 0,this),r$(W2,{color:q.colors.text.primary,children:O},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H>0&&r$(f5,{marginLeft:2,flexDirection:"row",gap:1,children:[r$(W2,{color:q.colors.info,children:["已用时: ",TO(H)]},void 0,!0,void 0,this),r$(W2,{color:q.colors.muted,children:"|"},void 0,!1,void 0,this),r$(W2,{color:q.colors.secondary,children:"Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});import lQ from"ansi-escapes";import{Box as E4,Static as gO,useStdout as VD}from"ink";import RD,{useEffect as i2,useMemo as uO,useRef as I4,useState as iQ}from"react";import{useStdout as KD}from"ink";import{debounce as WD}from"lodash-es";import{useEffect as UD,useState as HD}from"react";function EO($=200){let{stdout:Z}=KD(),[Y,Q]=HD(Z.rows||24);return UD(()=>{let X=WD(()=>{Q(Z.rows||24)},$);return X(),Z.on("resize",X),()=>{Z.off("resize",X),X.cancel()}},[Z,$]),Y}y3();I2();import IO from"chalk";import OD from"string-width";var D0={active:!1,renderedLineCount:0,lastRenderedLines:[],terminalWidth:process.stdout.columns||80,terminalHeight:process.stdout.rows||24,prefixIndent:4,isFirstRender:!0},x5="\x1B",pQ=`${x5}[2K`,h5=($)=>$>0?`${x5}[${$}A`:"",PO=`${x5}[?25l`,vO=`${x5}[?25h`;function CO($,Z){D0.active=!0,D0.renderedLineCount=0,D0.lastRenderedLines=[],D0.terminalWidth=$,D0.terminalHeight=Z,D0.isFirstRender=!0}function kO($,Z){D0.terminalWidth=$,D0.terminalHeight=Z}function SO($,Z,Y,Q){if(!D0.active)return;let X=8,J=Math.max(1,D0.terminalHeight-X),G=[],q=E$.getTheme(),K=" ".repeat(D0.prefixIndent);if(Z>0)G.push(`${K}${IO.dim.hex(q.colors.text.muted)(`↑ ${Z} lines above (streaming...)`)}`);let W=$.slice(-J);for(let H=0;H<W.length;H++){let O=W[H],F=K;if(H===0&&!Q&&D0.isFirstRender)F=IO.bold.hex(q.colors.success)("• ")+" ",D0.isFirstRender=!1;let _=D0.terminalWidth-D0.prefixIndent-2,z=O;if(OD(O)>_)z=O.slice(0,_);G.push(`${F}${z}`)}let U=[];if(U.push(PO),D0.renderedLineCount>0)U.push(h5(D0.renderedLineCount)),U.push("\r");for(let H=0;H<G.length;H++){let O=G[H],F=D0.lastRenderedLines[H];if(O!==F)U.push(pQ),U.push(O);if(H<G.length-1)U.push(`
|
|
2917
2917
|
`)}if(G.length<D0.renderedLineCount){for(let O=G.length;O<D0.renderedLineCount;O++)U.push(`
|
|
2918
|
-
`),U.push(pQ);let H=D0.renderedLineCount-G.length;U.push(
|
|
2919
|
-
`);if(D0.renderedLineCount>1)$.push(
|
|
2918
|
+
`),U.push(pQ);let H=D0.renderedLineCount-G.length;U.push(h5(H))}U.push(vO),process.stdout.write(U.join("")),D0.renderedLineCount=G.length,D0.lastRenderedLines=G}function c2(){if(!D0.active)return;if(D0.renderedLineCount>0){let $=[];$.push(PO),$.push(h5(D0.renderedLineCount)),$.push("\r");for(let Z=0;Z<D0.renderedLineCount;Z++)if($.push(pQ),Z<D0.renderedLineCount-1)$.push(`
|
|
2919
|
+
`);if(D0.renderedLineCount>1)$.push(h5(D0.renderedLineCount-1)),$.push("\r");$.push(vO),process.stdout.write($.join(""))}D0.active=!1,D0.renderedLineCount=0,D0.lastRenderedLines=[],D0.isFirstRender=!0}function M2(){return D0.active}import{Box as FD,Text as fO}from"ink";import _D from"react";import{jsxDEV as mQ}from"react/jsx-dev-runtime";var gQ=_D.memo(({collapsedCount:$})=>{let Z=o0();if($<=0)return null;let Y=Z.colors.text.muted;return mQ(FD,{flexDirection:"row",marginBottom:1,children:[mQ(fO,{color:Y,children:["▶ ",$," 条历史消息"]},void 0,!0,void 0,this),mQ(fO,{color:Y,children:" [Ctrl+O 展开]"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});gQ.displayName="CollapsedHistorySummary";e2();import{Box as k6,Text as S6}from"ink";import zD from"ink-big-text";import BD from"ink-gradient";import ND from"react";import{jsxDEV as p1}from"react/jsx-dev-runtime";var hO=ND.memo(()=>{return p1(k6,{flexDirection:"column",paddingX:2,paddingTop:1,paddingBottom:1,children:[p1(k6,{flexDirection:"column",children:p1(BD,{name:"pastel",children:p1(zD,{text:"BLADE",font:"block"},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),p1(k6,{marginBottom:1,children:p1(S6,{color:"white",dimColor:!0,children:KX()},void 0,!1,void 0,this)},void 0,!1,void 0,this),p1(k6,{flexDirection:"column",marginBottom:1,children:[p1(k6,{marginBottom:1,children:p1(S6,{color:"white",bold:!0,children:"使用指南:"},void 0,!1,void 0,this)},void 0,!1,void 0,this),p1(S6,{color:"white",children:"1. 输入问题、编辑文件或运行命令"},void 0,!1,void 0,this),p1(S6,{color:"white",children:"2. 使用 /init 创建项目配置文件"},void 0,!1,void 0,this),p1(S6,{color:"white",children:"3. 输入 /help 查看所有 slash 命令"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});import{Box as uQ,Text as b3}from"ink";import LD,{useMemo as xO}from"react";import{jsxDEV as l2}from"react/jsx-dev-runtime";function wD($,Z=60){if(!$)return"";let Y=$.split(`
|
|
2920
2920
|
`)[0]||"";if(Y.length<=Z)return Y;return`${Y.slice(0,Z)}...`}function AD($){if(!$)return 0;return $.split(`
|
|
2921
|
-
`).length}var dQ=LD.memo(({content:$,isStreaming:Z=!1,isExpanded:Y})=>{let Q=o0(),X=xO(()=>AD($),[$]),J=xO(()=>wD($),[$]),G=Q.colors.info,q=Q.colors.muted;return l2(uQ,{flexDirection:"column",marginBottom:1,children:[l2(uQ,{flexDirection:"row",children:[l2(b3,{color:G,children:Y?"▼":"▶"},void 0,!1,void 0,this),l2(b3,{children:" "},void 0,!1,void 0,this),l2(b3,{color:q,children:["Thinking",Z?"...":` (${X} lines)`]},void 0,!0,void 0,this),!Y&&!Z&&J&&l2(b3,{color:q,children:[" - ",J]},void 0,!0,void 0,this),l2(b3,{color:q,dimColor:!0,children:[" ","[Ctrl+T]"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Y&&$&&l2(uQ,{marginLeft:2,marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,paddingY:0,children:l2(b3,{color:q,children:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});dQ.displayName="ThinkingBlock";import{Box as p9,Text as cQ}from"ink";import pO from"react";import{jsxDEV as y4}from"react/jsx-dev-runtime";var mO=pO.memo(({todos:$,visible:Z=!0,compact:Y=!1})=>{let{colors:Q}=o0();if(!Z||$.length===0)return null;let X={total:$.length,completed:$.filter((J)=>J.status==="completed").length,inProgress:$.filter((J)=>J.status==="in_progress").length};return y4(p9,{flexDirection:"column",borderStyle:"single",borderColor:Q.border.light,paddingX:1,paddingY:Y?0:1,marginBottom:1,children:[y4(p9,{marginBottom:Y?0:1,children:[y4(cQ,{dimColor:!0,children:"Tasks "},void 0,!1,void 0,this),y4(cQ,{color:Q.text.muted,children:[X.completed,"/",X.total]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),y4(p9,{flexDirection:"column",children:$.map((J,G)=>y4(bD,{todo:J,compact:Y},J.id||G,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}),bD=pO.memo(({todo:$,compact:Z})=>{let Y,Q=!1,X;switch($.status){case"completed":Y="✓",Q=!0,X=$.content;break;case"in_progress":Y="▶",Q=!1,X=$.activeForm;break;case"pending":default:Y="○",Q=!0,X=$.content;break}return y4(p9,{paddingY:Z?0:0,children:y4(cQ,{dimColor:Q,children:[Y," ",X]},void 0,!0,void 0,this)},void 0,!1,void 0,this)});import{jsxDEV as v$}from"react/jsx-dev-runtime";var dO=RD.memo(()=>{let $=B9(),Z=FH(),Y=_H(),Q=zH(),X=j4(),J=$H(),G=XH(),q=UH(),K=HH(),W=OH(),U=nU(),H=NH(),O=BH(),F=_3(),_=EO(),{stdout:z}=VD(),N=D4(),[B,L]=iQ(null),[A,R]=iQ([]),[V,M]=iQ(new Set),T=I4(O),w=I4(null),v=I4(0),l=I4(0),o=I4(new Set),S=I4(new Set),y=I4([]),m=I4(null);i2(()=>{if(T.current!==O){if(M2())c2();if(z)z.write(lQ.clearTerminal);N.incrementClearCount(),T.current=O}},[O,z,N]);let I=$,j=Q;i2(()=>{if(!Q||X){m.current=null;return}if(m.current===Q)return;if(m.current=Q,M2())c2();if(z)z.write(lQ.eraseScreen);o.current=new Set,S.current=new Set(I.filter((C)=>C.role==="tool").map((C)=>C.id)),w.current=null,v.current=0,l.current=0,y.current=[],R([]),M(new Set),N.incrementClearCount(),N.clearFinalizingStreamingMessageId()},[Q,X,z,N,I]);let D=Z??Q;i2(()=>{if(M2())c2();w.current=null,v.current=0,l.current=0,o.current=new Set,S.current=new Set(I.filter((C)=>C.role==="tool").map((C)=>C.id)),y.current=[],R([]),M(new Set)},[U]),i2(()=>{if(!D)return;if(w.current===D)return;w.current=D,v.current=0,l.current=0,S.current=new Set(I.filter((C)=>C.role==="tool").map((C)=>C.id)),y.current=[],R([])},[D,I]),i2(()=>{if(!D)return;let C=z5(D);if(!C||C.length<=v.current)return;let r=C.slice(v.current);v.current=C.length;let h=r,c=y.current;if(c.length>0)if(h.some((i0)=>i0.type!=="empty"))h=[...c,...h],y.current=[];else{y.current=[...c,...h];return}let j0=h.length;while(j0>0&&h[j0-1].type==="empty")j0-=1;if(j0!==h.length)y.current=h.slice(j0),h=h.slice(0,j0);if(h.length===0)return;let E0=l.current;l.current+=1;let g0=E0>0;if(M2())c2();M((i0)=>{if(!D||i0.has(D))return i0;let s$=new Set(i0);return s$.add(D),s$}),R((i0)=>[...i0,v$(E4,{flexDirection:"column",children:v$(R8,{content:"",role:"assistant",terminalWidth:F,isPending:!1,hidePrefix:g0,noMargin:!0,blocksOverride:h,renderCodeBlocksAsPlainText:!0},void 0,!1,void 0,this)},`streaming-${D}-${E0}`,!1,void 0,this)])},[D,Y.version,F,U]),i2(()=>{if(!D)return;let C=S.current,r=I.filter((h)=>h.role==="tool"&&!C.has(h.id)&&!o.current.has(h.id));if(r.length===0)return;if(M2())c2();for(let h of r)o.current.add(h.id);R((h)=>[...h,...r.map((c)=>v$(E4,{flexDirection:"column",children:v$(R8,{content:c.content,role:c.role,terminalWidth:F,metadata:c.metadata,isPending:!1,messageId:c.id},void 0,!1,void 0,this)},`streaming-tool-${c.id}`,!1,void 0,this))])},[D,I,F]),i2(()=>{if(!D){if(M2())c2();return}if(!M2())CO(F,_);else kO(F,_);let C=CX(D);if(!C||C.lines.length===0)return;let h=Math.max(1,_-8),c=Math.max(0,C.lines.length-h),j0=C.lines.slice(-h),E0=(z5(D)?.length??0)>0;SO(j0,c,C.mode,E0)},[D,Y.version,_,F]),i2(()=>{if(!D&&M2())c2()},[D]),i2(()=>{if(B===null&&I.length>H){if(L(I.length),M2())c2();if(z)z.write(lQ.clearTerminal);N.incrementClearCount()}},[I.length,H,B,z,N]);let i=uO(()=>{return J.some((C)=>C.status==="pending"||C.status==="in_progress")},[J]),g=O?0:B??0,k=g,e=uO(()=>{let C=[];if(C.push(v$(hO,{},"header",!1,void 0,this)),k>0)C.push(v$(gQ,{collapsedCount:k},"collapsed-summary",!1,void 0,this));for(let r=g;r<I.length;r++){let h=I[r];if(j&&h.id===j)continue;if(h.role==="tool"&&o.current.has(h.id))continue;if(h.role==="assistant"&&V.has(h.id))continue;C.push(v$(E4,{flexDirection:"column",children:v$(R8,{content:h.content,role:h.role,terminalWidth:F,metadata:h.metadata,isPending:!1,messageId:h.id},void 0,!1,void 0,this)},h.id,!1,void 0,this))}return C},[I,g,k,F,j,V]);return v$(E4,{flexDirection:"column",paddingX:2,children:v$(E4,{flexDirection:"column",children:[v$(gO,{items:e,children:(C)=>C},U,!1,void 0,this),K&&v$(E4,{marginBottom:1,children:v$(dQ,{content:K,isStreaming:X,isExpanded:W},void 0,!1,void 0,this)},void 0,!1,void 0,this),A.length>0&&v$(gO,{items:A,children:(C)=>C},`streaming-${U}`,!1,void 0,this),G&&i&&v$(E4,{marginTop:1,children:v$(mO,{todos:J,visible:!0,compact:!1},void 0,!1,void 0,this)},void 0,!1,void 0,this),q.map((C,r)=>v$(E4,{flexDirection:"column",children:v$(R8,{content:C.displayText,role:"user",terminalWidth:F},void 0,!1,void 0,this)},`pending-${r}`,!1,void 0,this))]},void 0,!0,void 0,this)},void 0,!1,void 0,this)});b0();import{useMemoizedFn as a2}from"ahooks";import{Box as d$,Text as A$,useFocusManager as dD,useInput as GF}from"ink";import cD from"ink-text-input";import{useState as v4}from"react";import{Box as r2,Text as V1,useInput as DD}from"ink";import MD from"ink-text-input";import{jsxDEV as F$}from"react/jsx-dev-runtime";var cO=({provider:$,value:Z,onChange:Y,onSubmit:Q,onCancel:X,error:J})=>{DD((q,K)=>{if(K.escape)X()});let G=$.envVars.length>0?$.envVars[0]:null;return F$(r2,{flexDirection:"column",children:[F$(r2,{marginBottom:1,children:F$(V1,{bold:!0,color:"blue",children:"\uD83D\uDD11 Step 2: 输入 API Key"},void 0,!1,void 0,this)},void 0,!1,void 0,this),F$(r2,{marginBottom:1,children:F$(V1,{children:["Provider: ",$.icon," ",F$(V1,{bold:!0,children:$.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),G&&F$(r2,{marginBottom:1,children:F$(V1,{dimColor:!0,children:["\uD83D\uDCA1 环境变量: ",F$(V1,{color:"cyan",children:G},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),$.docUrl&&F$(r2,{marginBottom:1,children:F$(V1,{dimColor:!0,children:["\uD83D\uDCD6 文档: ",F$(V1,{color:"blue",children:$.docUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),F$(r2,{marginBottom:1,children:F$(V1,{dimColor:!0,children:"您的 API 密钥将被安全存储在 ~/.blade/config.json (权限 600)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),F$(r2,{children:[F$(V1,{bold:!0,color:"cyan",children:["▶"," "]},void 0,!0,void 0,this),F$(MD,{value:Z,onChange:Y,onSubmit:Q,placeholder:"sk-...",mask:"*"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J&&F$(r2,{marginTop:1,children:F$(V1,{color:"red",children:["❌ ",J]},void 0,!0,void 0,this)},void 0,!1,void 0,this),F$(r2,{marginTop:1,children:F$(V1,{dimColor:!0,children:["\uD83D\uDCA1 输入完成后按 ",F$(V1,{bold:!0,children:"Enter"},void 0,!1,void 0,this),",",F$(V1,{bold:!0,children:"Esc"},void 0,!1,void 0,this)," 返回"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{useEffect as lO,useState as V3}from"react";C8();var jD={id:"custom-openai-compatible",name:"自定义 OpenAI Compatible",icon:"\uD83D\uDD27",description:"使用自定义 Base URL 和 API Key",isOAuth:!1,envVars:[],bladeProvider:"openai-compatible",isCustom:!0},iO=()=>{let[$,Z]=V3([]),[Y,Q]=V3(!0),[X,J]=V3(null);return lO(()=>{(async()=>{try{let q=await H9(),K=Object.entries(l6).map(([W,U])=>({id:W,name:W==="antigravity"?"Google Antigravity":"GitHub Copilot",icon:U.icon,description:U.description,isOAuth:!0,envVars:[],bladeProvider:U.bladeProvider}));Z([...K,jD,...q])}catch(q){J(q instanceof Error?q.message:"加载 Provider 列表失败")}finally{Q(!1)}})()},[]),{providers:$,isLoading:Y,error:X}},rO=($)=>{let[Z,Y]=V3([]),[Q,X]=V3(!1),[J,G]=V3(null);return lO(()=>{if(!$){Y([]);return}(async()=>{X(!0),G(null);try{let K=await O9($);Y(K)}catch(K){G(K instanceof Error?K.message:"加载模型列表失败")}finally{X(!1)}})()},[$]),{models:Z,isLoading:Q,error:J}};import{Box as U2,Text as m1,useInput as TD}from"ink";import yD from"ink-select-input";import aO from"ink-text-input";import{useMemo as nO,useState as rQ}from"react";import{jsxDEV as e0,Fragment as vD}from"react/jsx-dev-runtime";var ED=({isSelected:$})=>e0(U2,{marginRight:1,children:e0(m1,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),ID=($)=>{let Z=[$.name];if($.contextWindow){let Y=$.contextWindow>=1e6?`${($.contextWindow/1e6).toFixed(1)}M`:$.contextWindow>=1000?`${Math.round($.contextWindow/1000)}K`:`${$.contextWindow}`;Z.push(`[${Y} ctx]`)}if($.inputCost!==void 0&&$.outputCost!==void 0)Z.push(`[$${$.inputCost}/$${$.outputCost}]`);return Z.join(" ")},PD=({isSelected:$,label:Z})=>e0(m1,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),oO=({provider:$,models:Z,isLoading:Y,error:Q,onSelect:X,onCancel:J,initialModel:G})=>{let[q,K]=rQ(""),W=$.isCustom||Z.length===0,[U,H]=rQ(W),[O,F]=rQ(G||"");TD((B,L)=>{if(L.escape){if(U&&!W)H(!1),F(G||"");else if(q)K("");else J();return}if(B==="+"&&!U)H(!0)});let _=nO(()=>{if(!q)return Z;let B=q.toLowerCase();return Z.filter((L)=>L.name.toLowerCase().includes(B)||L.id.toLowerCase().includes(B))},[Z,q]),z=nO(()=>_.map((B)=>({key:B.id,label:ID(B),value:B})),[_]),N=()=>{if(O.trim())X({id:O.trim(),name:O.trim()})};if(Y)return e0(U2,{flexDirection:"column",children:e0(m1,{color:"yellow",children:["⏳ 正在加载 ",$.name," 模型列表..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this);if(Q)return e0(U2,{flexDirection:"column",children:[e0(m1,{color:"red",children:["❌ ",Q]},void 0,!0,void 0,this),e0(m1,{dimColor:!0,children:"按 Esc 返回"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return e0(U2,{flexDirection:"column",children:[e0(U2,{marginBottom:1,children:e0(m1,{bold:!0,color:"blue",children:"\uD83E\uDD16 Step 3: 选择模型"},void 0,!1,void 0,this)},void 0,!1,void 0,this),e0(U2,{marginBottom:1,children:e0(m1,{children:["Provider: ",$.icon," ",e0(m1,{bold:!0,children:$.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),U?e0(U2,{flexDirection:"column",children:[e0(U2,{marginBottom:1,children:e0(m1,{dimColor:!0,children:W?"输入模型名称:":"输入自定义模型名称(按 Esc 返回列表):"},void 0,!1,void 0,this)},void 0,!1,void 0,this),e0(U2,{children:[e0(m1,{bold:!0,color:"cyan",children:"▶ "},void 0,!1,void 0,this),e0(aO,{value:O,onChange:F,onSubmit:N,placeholder:"例如: gpt-4o-mini"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this):e0(vD,{children:[e0(U2,{marginBottom:1,children:[e0(m1,{color:"cyan",children:"\uD83D\uDD0D "},void 0,!1,void 0,this),e0(aO,{value:q,onChange:K,placeholder:`搜索 ${Z.length} 个模型,按 + 自定义...`},void 0,!1,void 0,this)]},void 0,!0,void 0,this),e0(U2,{flexDirection:"column",height:12,children:e0(yD,{items:z,onSelect:(B)=>X(B.value),indicatorComponent:ED,itemComponent:PD,limit:10},void 0,!1,void 0,this)},void 0,!1,void 0,this),_.length===0&&e0(m1,{color:"yellow",children:"未找到匹配的模型,按 + 输入自定义模型名称"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};f3();C3();u3();p3();import{Box as g1,Text as R1,useFocus as tO,useInput as eO}from"ink";import CD from"ink-select-input";import{useEffect as kD,useState as sO}from"react";import{jsxDEV as X$}from"react/jsx-dev-runtime";var $F=({provider:$,onLogin:Z,onCancel:Y,isLoggingIn:Q})=>{let{isFocused:X}=tO({id:"oauth-login"});return eO((J,G)=>{if(Q)return;if(J==="y"||J==="Y")Z();else if(J==="n"||J==="N"||G.escape)Y()},{isActive:X&&!Q}),X$(g1,{flexDirection:"column",children:[X$(g1,{marginBottom:1,children:X$(R1,{bold:!0,color:"yellow",children:[$.icon," 需要登录 ",$.name]},void 0,!0,void 0,this)},void 0,!1,void 0,this),X$(g1,{marginBottom:1,children:X$(R1,{children:$.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),X$(g1,{marginBottom:1,paddingLeft:2,children:X$(R1,{dimColor:!0,children:["您也可以稍后手动执行"," ",X$(R1,{bold:!0,children:$.id==="antigravity"?"/login":"/login copilot"},void 0,!1,void 0,this)," ","命令登录"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),!Q&&X$(g1,{marginTop:1,children:X$(R1,{children:["现在登录? [",X$(R1,{bold:!0,color:"green",children:"Y"},void 0,!1,void 0,this),"/",X$(R1,{bold:!0,color:"red",children:"n"},void 0,!1,void 0,this),"]"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q&&X$(g1,{marginTop:1,children:X$(R1,{color:"yellow",children:"⏳ 正在启动登录流程..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},SD=({isSelected:$})=>X$(g1,{marginRight:1,children:X$(R1,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),fD=({isSelected:$,label:Z})=>X$(R1,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),ZF=({provider:$,onSelect:Z,onCancel:Y})=>{let{isFocused:Q}=tO({id:"oauth-model-select"}),[X,J]=sO([]),[G,q]=sO(!0);kD(()=>{(async()=>{q(!0);try{if($.id==="copilot")J(Object.values(s6));else{let H=await l$.getInstance().getConfigType();J(H==="gemini-cli"?Object.values(r6):Object.values(v3))}}catch{J(Object.values(v3))}finally{q(!1)}})()},[$.id]),eO((W,U)=>{if(U.escape)Y()},{isActive:Q});let K=X.map((W)=>({key:W.id,label:`${W.name} - ${W.description}`,value:{id:W.id,name:W.name}}));if(G)return X$(g1,{flexDirection:"column",children:X$(R1,{color:"yellow",children:["⏳ 加载 ",$.name," 模型列表..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this);return X$(g1,{flexDirection:"column",children:[X$(g1,{marginBottom:1,children:X$(R1,{bold:!0,color:"blue",children:["\uD83E\uDD16 选择 ",$.name," 模型"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),X$(g1,{marginBottom:1,children:X$(R1,{dimColor:!0,children:"从可用模型列表中选择一个"},void 0,!1,void 0,this)},void 0,!1,void 0,this),X$(g1,{flexDirection:"column",height:12,children:X$(CD,{items:K,onSelect:(W)=>Z(W.value),indicatorComponent:SD,itemComponent:fD,limit:10},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},YF=async($)=>{let Z=$==="antigravity"?l$.getInstance():t$.getInstance();try{return await Z.login(),!0}catch{return!1}},QF=async($)=>{let Z=$==="antigravity"?l$.getInstance():t$.getInstance();try{return await Z.isLoggedIn()}catch{return!1}};import{Box as T8,Text as P4,useInput as hD}from"ink";import xD from"ink-select-input";import pD from"ink-text-input";import{useMemo as XF,useState as mD}from"react";import{jsxDEV as u$}from"react/jsx-dev-runtime";var gD=({isSelected:$})=>u$(T8,{marginRight:1,children:u$(P4,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),uD=({isSelected:$,label:Z})=>u$(P4,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),JF=({providers:$,isLoading:Z,error:Y,onSelect:Q,onCancel:X})=>{let[J,G]=mD("");hD((W,U)=>{if(U.escape)if(J)G("");else X()});let q=XF(()=>{if(!J)return $;let W=J.toLowerCase();return $.filter((U)=>U.name.toLowerCase().includes(W)||U.id.toLowerCase().includes(W))},[$,J]),K=XF(()=>q.map((W)=>({key:W.id,label:`${W.icon} ${W.name} - ${W.description}`,value:W})),[q]);if(Z)return u$(T8,{flexDirection:"column",children:u$(P4,{color:"yellow",children:"⏳ 正在加载 Provider 列表..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(Y)return u$(T8,{flexDirection:"column",children:[u$(P4,{color:"red",children:["❌ ",Y]},void 0,!0,void 0,this),u$(P4,{dimColor:!0,children:"按 Esc 返回"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return u$(T8,{flexDirection:"column",children:[u$(T8,{marginBottom:1,children:u$(P4,{bold:!0,color:"blue",children:"\uD83D\uDCE1 Step 1: 选择 API 提供商"},void 0,!1,void 0,this)},void 0,!1,void 0,this),u$(T8,{marginBottom:1,children:[u$(P4,{color:"cyan",children:"\uD83D\uDD0D "},void 0,!1,void 0,this),u$(pD,{value:J,onChange:G,placeholder:`搜索 ${$.length} 个 Provider...`},void 0,!1,void 0,this)]},void 0,!0,void 0,this),u$(T8,{flexDirection:"column",height:12,children:u$(xD,{items:K,onSelect:(W)=>Q(W.value),indicatorComponent:gD,itemComponent:uD,limit:10},void 0,!1,void 0,this)},void 0,!1,void 0,this),q.length===0&&u$(P4,{color:"yellow",children:"未找到匹配的 Provider,按 Esc 清除搜索"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};C8();import{jsxDEV as G0,Fragment as iD}from"react/jsx-dev-runtime";var aQ=({mode:$,initialConfig:Z,modelId:Y,onComplete:Q,onCancel:X})=>{let J=$==="edit",[G,q]=v4("provider"),[K,W]=v4(),[U,H]=v4(J?Z?.apiKey||"":""),[O,F]=v4(J?Z?.baseUrl||"":""),[_]=v4(J?Z?.model||"":""),[z,N]=v4(),[B,L]=v4(!1),[A,R]=v4(!1),{providers:V,isLoading:M,error:T}=iO(),{models:w,isLoading:v,error:l}=rO(K?.isOAuth?void 0:K?.id),o=W$(!1),{focus:S}=dD();GF((c,j0)=>{if(j0.ctrl&&c==="c"||j0.meta&&c==="c")$==="setup"?o():X()});let y=a2((c)=>{let E0={provider:"",apiKey:"",baseUrl:"",model:"",oauthLogin:"oauth-login",oauthModelSelect:"oauth-model-select",confirm:""}[c];if(E0)S(E0)}),m=a2((c)=>{return c.defaultBaseUrl||i6[c.id]||""}),I=a2(async(c)=>{W(c),N(void 0);let j0=m(c);if(!J)F(j0);if(c.isOAuth){let g0=await QF(c.id)?"oauthModelSelect":"oauthLogin";q(g0),y(g0)}else q("apiKey")}),j=a2(()=>{if(!U.trim()){N("API Key 不能为空");return}N(void 0);let c=K?m(K):"";if(K?.isCustom||!c&&!O)q("baseUrl");else q("model")}),D=a2(()=>{if(!O.trim()){N("Base URL 不能为空");return}try{new URL(O)}catch{N("请输入有效的 URL (例如: https://api.example.com/v1)");return}N(void 0),q("model")}),i=a2(async(c)=>{N(void 0),L(!0);try{let j0=O||(K?m(K):""),g0={name:J&&Z?.name?Z.name:`${K?.name||"Model"} - ${c.name}`,provider:K?.bladeProvider||Z?.provider||"openai-compatible",baseUrl:j0,apiKey:K?.isOAuth?"oauth":U,model:c.id,...c.contextWindow&&{maxContextTokens:c.contextWindow},...c.maxOutput&&{maxOutputTokens:c.maxOutput},...K?.id&&{providerId:K.id}};if($==="setup")Q(g0);else if($==="add"){let i0=await A0().addModel(g0);await A0().setCurrentModel(i0.id),Q(g0)}else if($==="edit"&&Y)await A0().updateModel(Y,g0),Q(g0)}catch(j0){N(j0 instanceof Error?j0.message:"保存配置失败"),L(!1)}}),g=a2(async()=>{if(!K)return;R(!0),N(void 0);let c=await YF(K.id);if(R(!1),c)q("oauthModelSelect"),y("oauthModelSelect");else N("登录失败,请重试")}),k=a2(()=>{switch(N(void 0),G){case"apiKey":q("provider");break;case"baseUrl":q("apiKey");break;case"model":{if(!(K?m(K):""))q("baseUrl");else q("apiKey");break}case"oauthLogin":case"oauthModelSelect":q("provider");break}}),e=a2(()=>{q("apiKey")}),C=G==="provider"?1:G==="apiKey"||G==="oauthLogin"?2:G==="baseUrl"?2.5:3,r=3;return G0(d$,{...$==="setup"?{flexDirection:"column",padding:1}:{flexDirection:"column",borderStyle:"round",borderColor:$==="edit"?"yellow":"blue",padding:1},children:[$==="setup"&&G0(iD,{children:[G0(d$,{marginBottom:1,children:G0(A$,{bold:!0,color:"blue",children:"\uD83D\uDE80 欢迎使用 Blade Code"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(d$,{marginBottom:1,children:G0(A$,{children:"AI 驱动的代码助手 - 让我们开始配置您的助手"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(d$,{marginBottom:1,children:[G0(A$,{bold:!0,color:"blue",children:"█".repeat(Math.floor((C-1)/(r-1)*40))},void 0,!1,void 0,this),G0(A$,{dimColor:!0,children:"░".repeat(40-Math.floor((C-1)/(r-1)*40))},void 0,!1,void 0,this),G0(A$,{children:" "},void 0,!1,void 0,this),G0(A$,{bold:!0,color:"cyan",children:[Math.ceil(C),"/",r]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),G0(d$,{marginBottom:1,children:G0(A$,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$!=="setup"&&G0(d$,{justifyContent:"center",marginBottom:1,children:G0(A$,{bold:!0,color:$==="edit"?"yellow":"blue",children:$==="edit"?"编辑模型配置":"添加新模型配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G==="provider"&&G0(JF,{providers:V,isLoading:M,error:T,onSelect:I,onCancel:$==="setup"?()=>{}:X},void 0,!1,void 0,this),G==="apiKey"&&K&&G0(cO,{provider:K,value:U,onChange:H,onSubmit:j,onCancel:k,error:z},void 0,!1,void 0,this),G==="baseUrl"&&K&&G0(lD,{provider:K,value:O,onChange:F,onSubmit:D,onCancel:e,error:z},void 0,!1,void 0,this),G==="model"&&K&&G0(oO,{provider:K,models:w,isLoading:v,error:l,onSelect:i,onCancel:k,initialModel:J?_:void 0},void 0,!1,void 0,this),G==="oauthLogin"&&K&&G0($F,{provider:K,onLogin:g,onCancel:k,isLoggingIn:A},void 0,!1,void 0,this),G==="oauthModelSelect"&&K&&G0(ZF,{provider:K,onSelect:i,onCancel:k},void 0,!1,void 0,this),z&&G!=="apiKey"&&G!=="baseUrl"&&G0(d$,{marginTop:1,borderStyle:"round",borderColor:"red",paddingX:1,children:G0(A$,{color:"red",children:["❌ ",z]},void 0,!0,void 0,this)},void 0,!1,void 0,this),B&&G0(d$,{marginTop:1,children:G0(A$,{color:"yellow",children:"⏳ 正在保存配置..."},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(d$,{marginTop:1,children:G0(A$,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},lD=({provider:$,value:Z,onChange:Y,onSubmit:Q,onCancel:X,error:J})=>{return GF((G,q)=>{if(q.escape)X()}),G0(d$,{flexDirection:"column",children:[G0(d$,{marginBottom:1,children:G0(A$,{bold:!0,color:"blue",children:"\uD83C\uDF10 输入 Base URL"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(d$,{marginBottom:1,children:G0(A$,{children:["Provider: ",$.icon," ",G0(A$,{bold:!0,children:$.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),G0(d$,{marginBottom:1,children:G0(A$,{dimColor:!0,children:"此 Provider 没有默认的 API 端点,请输入完整的 Base URL"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(d$,{marginBottom:1,children:G0(A$,{dimColor:!0,children:"示例: https://api.example.com/v1"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(d$,{children:[G0(A$,{bold:!0,color:"cyan",children:"▶ "},void 0,!1,void 0,this),G0(cD,{value:Z,onChange:Y,onSubmit:Q,placeholder:"https://api.example.com/v1"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J&&G0(d$,{marginTop:1,children:G0(A$,{color:"red",children:["❌ ",J]},void 0,!0,void 0,this)},void 0,!1,void 0,this),G0(d$,{marginTop:1,children:G0(A$,{dimColor:!0,children:["\uD83D\uDCA1 输入完成后按 ",G0(A$,{bold:!0,children:"Enter"},void 0,!1,void 0,this),",",G0(A$,{bold:!0,children:"Esc"},void 0,!1,void 0,this)," 返回"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};x5();import{useMemoizedFn as m9,useMount as rD}from"ahooks";import{Box as D1,Text as S0,useFocus as aD,useFocusManager as nD,useInput as oD}from"ink";import sD from"ink-select-input";import{memo as tD,useMemo as eD,useState as g9}from"react";b0();import{jsxDEV as K0}from"react/jsx-dev-runtime";function $M($){switch($){case"openai-compatible":return"⚡ OpenAI Compatible";case"anthropic":return"\uD83E\uDD16 Anthropic Claude";case"gemini":return"✨ Google Gemini";case"azure-openai":return"☁️ Azure OpenAI";default:return $}}var ZM=({isSelected:$})=>K0(D1,{marginRight:1,children:K0(S0,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),YM=({isSelected:$,label:Z})=>K0(S0,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),qF=tD(({onClose:$,onEdit:Z})=>{let Y=JH(),Q=GH()??"",{isFocused:X}=aD({id:"model-selector"}),J=nD(),[G,q]=g9(""),[K,W]=g9(!1),[U,H]=g9(null),O=W$(!1),[F]=g9(()=>{let M=process.stdout?.columns||80;return Math.max(20,M-8)});rD(()=>{if(J?.focus("model-selector"),Y.length>0)q(Y[0].id)}),oD((M,T)=>{if(K)return;if(T.ctrl&&M==="c"||T.meta&&M==="c"){O();return}if(T.escape){$();return}if(!X)return;if(M==="d"||M==="D"){z();return}if((M==="e"||M==="E")&&Z)N()},{isActive:!0});let _=m9(async(M)=>{if(K)return;let T=M.value;if(T===Q){$();return}W(!0),H(null);try{await A0().setCurrentModel(T),$()}catch(w){H(w.message),W(!1)}}),z=m9(async()=>{if(K||G===Q)return;W(!0),H(null);try{if(await A0().removeModel(G),Y.length<=1)$()}catch(M){H(M.message)}finally{W(!1)}}),N=m9(()=>{if(K||!Z)return;let M=Y.find((T)=>T.id===G);if(!M)return;Z(M)}),B=m9((M)=>{q(M.value)}),L=eD(()=>{return Y.find((M)=>M.id===G)},[Y,G]),A=Y.map((M)=>{let T=M.id===Q?" (当前)":"";return{label:M.name+T,value:M.id}}),R=G===Q;return K0(D1,{flexDirection:"column",borderStyle:"round",borderColor:"gray",padding:1,width:"100%",children:[K0(D1,{flexDirection:"row",justifyContent:"space-between",marginBottom:1,children:[K0(S0,{bold:!0,color:"cyan",children:"模型管理"},void 0,!1,void 0,this),K0(S0,{dimColor:!0,children:[K?"⏳ 处理中...":R?"Enter=关闭 • E=编辑 • Esc=取消":"Enter=切换 • D=删除 • E=编辑 • Esc=取消"," • Ctrl+C=退出"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),K0(D1,{flexDirection:"row",children:[K0(D1,{flexDirection:"column",flexGrow:2,marginRight:2,borderStyle:"single",borderColor:"gray",padding:1,children:[K0(S0,{dimColor:!0,children:["已配置模型 (",Y.length,")"]},void 0,!0,void 0,this),K0(D1,{marginTop:1,children:K0(sD,{items:A,onSelect:_,onHighlight:B,indicatorComponent:ZM,itemComponent:YM},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K0(D1,{flexDirection:"column",flexGrow:3,borderStyle:"single",borderColor:"gray",padding:1,children:[K0(S0,{dimColor:!0,children:"模型详情"},void 0,!1,void 0,this),K0(D1,{marginY:1,children:K0(S0,{color:R?"green":"yellow",children:R?"● 当前使用":"● 可切换"},void 0,!1,void 0,this)},void 0,!1,void 0,this),L?K0(D1,{flexDirection:"column",children:[K0(S0,{children:[K0(S0,{dimColor:!0,children:"名称: "},void 0,!1,void 0,this),K0(S0,{bold:!0,color:"cyan",children:L.name},void 0,!1,void 0,this),h5(L)&&K0(S0,{color:"green",children:" (内置免费)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K0(S0,{children:[K0(S0,{dimColor:!0,children:"Provider: "},void 0,!1,void 0,this),K0(S0,{bold:!0,children:$M(L.provider)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K0(S0,{children:[K0(S0,{dimColor:!0,children:"Model: "},void 0,!1,void 0,this),K0(S0,{bold:!0,children:L.model},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K0(S0,{children:[K0(S0,{dimColor:!0,children:"Base URL: "},void 0,!1,void 0,this),K0(S0,{color:"blueBright",children:L.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L.temperature!==void 0&&K0(S0,{children:[K0(S0,{dimColor:!0,children:"Temperature: "},void 0,!1,void 0,this),K0(S0,{children:L.temperature},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L.maxContextTokens!==void 0&&K0(S0,{children:[K0(S0,{dimColor:!0,children:"Context Window: "},void 0,!1,void 0,this),K0(S0,{children:L.maxContextTokens},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h5(L)&&K0(D1,{marginTop:1,children:K0(S0,{color:"green",dimColor:!0,children:"\uD83D\uDCA1 此模型由 Blade 提供免费额度"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this):K0(S0,{dimColor:!0,children:"请选择一个模型查看详情"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),U&&K0(D1,{marginTop:1,children:K0(S0,{color:"red",children:["❌ ",U]},void 0,!0,void 0,this)},void 0,!1,void 0,this),K0(D1,{justifyContent:"center",marginTop:1,children:K0(S0,{dimColor:!0,children:"─".repeat(F)},void 0,!1,void 0,this)},void 0,!1,void 0,this),K0(D1,{justifyContent:"center",children:K0(S0,{dimColor:!0,children:"提示:D=删除 • E=编辑 • ↑↓=移动 • Enter/ESC=确认"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});import{useMemoizedFn as f6}from"ahooks";import{promises as HF}from"fs";import{Box as M1,Text as q$,useInput as QM}from"ink";import KF from"ink-select-input";import XM from"ink-text-input";import JM from"os";import u9 from"path";import{useEffect as GM,useMemo as d9,useRef as qM,useState as C4}from"react";b0();import{jsxDEV as B0}from"react/jsx-dev-runtime";var h6=[{key:"allow",label:"Allow"},{key:"ask",label:"Ask"},{key:"deny",label:"Deny"},{key:"info",label:"Info"}],KM={allow:"Add a new rule...",ask:"Add a new rule...",deny:"Add a new rule..."},WM={allow:"Allow permission rules",ask:"Ask permission rules",deny:"Deny permission rules"},WF={project:"[项目共享配置]",global:"[用户全局配置]",local:"[本地配置]"},UM=["project","global","local"],HM={allow:[],ask:[],deny:[]},OM={localExists:!1,projectExists:!1,globalExists:!1},UF={allow:[],ask:[],deny:[]};function FM($){let Z=(Q)=>Array.isArray(Q)?Q.filter((X)=>typeof X==="string"):[],Y=$?.permissions??{};return{allow:Z(Y?.allow),ask:Z(Y?.ask),deny:Z(Y?.deny)}}async function _M($){try{let Z=await HF.readFile($,"utf-8"),Y=JSON.parse(Z);return{exists:!0,raw:Y,permissions:FM(Y)}}catch(Z){if(Z.code==="ENOENT")return{exists:!1,raw:{},permissions:{...UF}};return console.warn(`[PermissionsManager] Failed to read ${$}:`,Z),{exists:!0,raw:{},permissions:{...UF}}}}function zM($,Z){let Y=$.padEnd(32," "),Q=Z==="local"?`${WF[Z]} ← 可删除`:WF[Z];return`${Y} ${Q}`}var OF=({onClose:$})=>{let Y=_1()==="permissions-manager",Q=W$(!1),[X,J]=C4(0),G=h6[X].key,[q,K]=C4(HM),[W,U]=C4(OM),[H,O]=C4(!0),[F,_]=C4("list"),[z,N]=C4(""),[B,L]=C4(null),[A,R]=C4(null),V=qM(!1),M=d9(()=>u9.join(process.cwd(),".blade","settings.local.json"),[]),T=d9(()=>u9.join(process.cwd(),".blade","settings.json"),[]),w=d9(()=>u9.join(JM.homedir(),".blade","settings.json"),[]),v=f6(async()=>{O(!0);let r=await Promise.all([{source:"local",path:M},{source:"project",path:T},{source:"global",path:w}].map(async({source:E0,path:g0})=>{let i0=await _M(g0);return{source:E0,path:g0,...i0}})),h={localExists:r.find((E0)=>E0.source==="local")?.exists??!1,projectExists:r.find((E0)=>E0.source==="project")?.exists??!1,globalExists:r.find((E0)=>E0.source==="global")?.exists??!1};U(h);let c={allow:[],ask:[],deny:[]},j0=Object.fromEntries(r.map((E0)=>[E0.source,E0]));["allow","ask","deny"].forEach((E0)=>{UM.forEach((g0)=>{(j0[g0]?.permissions[E0]??[]).forEach((s$,M3)=>{let t2={key:`${g0}:${M3}:${s$}`,rule:s$,source:g0};c[E0].push(t2)})})}),K(c),O(!1)});GM(()=>{v()},[v]);let l=f6(async(C,r)=>{try{let h=u9.join(process.cwd(),".blade","settings.local.json"),c={allow:[],ask:[],deny:[]};try{let E0=await HF.readFile(h,"utf-8"),i0=JSON.parse(E0).permissions||{};c={allow:Array.isArray(i0.allow)?i0.allow:[],ask:Array.isArray(i0.ask)?i0.ask:[],deny:Array.isArray(i0.deny)?i0.deny:[]}}catch(E0){}let j0=r(c);await A0().updateConfig({permissions:j0},{scope:"local",immediate:!0}),await v()}catch(h){throw console.error("[PermissionsManager] 修改权限规则失败:",h),h}});QM((C,r)=>{if(r.ctrl&&C==="c"||r.meta&&C==="c"){Q();return}if(F==="locked"){if(V.current){V.current=!1;return}_("list"),L(null),R(null);return}if(r.escape){if(F==="list"||G==="info")$();else _("list"),N(""),L(null),R(null);return}if(F==="list"){if(r.tab&&r.shift)J((h)=>(h-1+h6.length)%h6.length);else if(r.tab)J((h)=>(h+1)%h6.length);else if(C?.toLowerCase()==="q")$()}},{isActive:Y});let o=f6((C)=>{let r=C.value;if(G==="info")return;if(r.type==="add"){_("add"),N(""),R(null);return}if(r.entry.source!=="local"){_("locked"),V.current=!0,L({tab:G,entry:r.entry}),R({type:"error",text:r.entry.source==="project"?"此规则定义在项目共享配置中,无法在此删除。":"此规则来自用户全局配置,无法在此删除。"});return}_("confirm-delete"),L({tab:G,entry:r.entry}),R(null)}),S=f6(async()=>{if(G==="info")return;let C=z.trim();if(!C){R({type:"error",text:"Permission rule 不能为空"});return}if(q[G].map((h)=>h.rule).includes(C)){R({type:"error",text:"该规则已存在"});return}try{await l(G,(h)=>{let c={allow:[...h.allow],ask:[...h.ask],deny:[...h.deny]};return c[G]=[...new Set([...h[G],C])],c}),_("list"),N(""),R({type:"success",text:"已添加本地权限规则"})}catch(h){R({type:"error",text:`保存失败: ${h instanceof Error?h.message:"未知错误"}`})}}),y=f6(async()=>{if(!B)return;let{tab:C,entry:r}=B;try{await l(C,(h)=>{let c={allow:[...h.allow],ask:[...h.ask],deny:[...h.deny]};return c[C]=h[C].filter((j0)=>j0!==r.rule),c}),_("list"),L(null),R({type:"success",text:"已删除本地权限规则"})}catch(h){R({type:"error",text:`删除失败: ${h instanceof Error?h.message:"未知错误"}`})}}),m=d9(()=>{if(G==="info")return[];let C=G;return[{key:"add-new-rule",label:`› ${KM[C]}`,value:{type:"add"}},...q[C].map((h)=>({key:h.key,label:zM(h.rule,h.source),value:{type:"rule",entry:h}}))]},[G,q]),I=()=>B0(M1,{marginBottom:1,children:h6.map((C,r)=>B0(M1,{marginRight:2,children:B0(q$,{color:r===X?"yellow":"gray",children:["[",C.label,"]"]},void 0,!0,void 0,this)},C.key,!1,void 0,this))},void 0,!1,void 0,this),j=()=>B0(M1,{flexDirection:"column",gap:1,children:[B0(q$,{children:"配置文件优先级(从高到低):"},void 0,!1,void 0,this),B0(M1,{flexDirection:"column",marginLeft:2,children:[B0(q$,{children:["1. .blade/settings.local.json (本地配置,不提交 Git)"," ",W.localExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),B0(q$,{children:["2. .blade/settings.json (项目配置,提交 Git)"," ",W.projectExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),B0(q$,{children:["3. ~/.blade/settings.json (用户全局配置)"," ",W.globalExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),B0(q$,{children:"说明:"},void 0,!1,void 0,this),B0(M1,{flexDirection:"column",marginLeft:2,children:[B0(q$,{children:"- /permissions 命令只管理本地配置 (.blade/settings.local.json)"},void 0,!1,void 0,this),B0(q$,{children:"- 修改全局或项目配置请直接编辑对应文件"},void 0,!1,void 0,this),B0(q$,{children:"- 本地配置不会提交到 Git"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),D=(C)=>B0(M1,{flexDirection:"column",gap:1,children:[B0(q$,{bold:!0,children:WM[C]},void 0,!1,void 0,this),B0(q$,{children:"Permission rules are a tool name, optionally followed by a specifier in parentheses."},void 0,!1,void 0,this),B0(q$,{color:"gray",children:"例如: WebFetch 或 Bash(ls:*)"},void 0,!1,void 0,this),B0(M1,{marginTop:1,children:B0(XM,{value:z,onChange:N,onSubmit:S},void 0,!1,void 0,this)},void 0,!1,void 0,this),B0(q$,{color:"gray",children:"Enter 提交 · Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),i=(C,r)=>B0(M1,{flexDirection:"column",gap:1,children:[B0(q$,{bold:!0,children:["Delete ",C," permission rule?"]},void 0,!0,void 0,this),B0(q$,{children:r.rule},void 0,!1,void 0,this),B0(q$,{color:"gray",children:"From project local settings"},void 0,!1,void 0,this),B0(q$,{children:"Are you sure you want to delete this permission rule?"},void 0,!1,void 0,this),B0(KF,{items:[{label:"Yes",value:"yes"},{label:"No",value:"no"}],onSelect:(h)=>{if(h.value==="yes")y();else _("list"),L(null)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),g=(C)=>B0(M1,{flexDirection:"column",gap:1,children:[B0(q$,{bold:!0,children:"Cannot delete this rule"},void 0,!1,void 0,this),B0(q$,{children:C.rule},void 0,!1,void 0,this),B0(q$,{color:"gray",children:C.source==="project"?"This rule is defined in .blade/settings.json. 请手动编辑该文件以移除规则。":"This rule is defined in ~/.blade/settings.json. 请手动编辑该文件以移除规则。"},void 0,!1,void 0,this),B0(q$,{color:"gray",children:"按任意键继续"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),k=(C)=>B0(KF,{items:m,isFocused:F==="list",onSelect:o},void 0,!1,void 0,this),e=()=>{if(H)return B0(q$,{children:"加载中..."},void 0,!1,void 0,this);if(G==="info")return j();if(F==="add")return D(G);if(F==="confirm-delete"&&B)return i(B.tab,B.entry);if(F==="locked"&&B)return g(B.entry);return k(G)};return B0(M1,{flexDirection:"column",borderStyle:"round",borderColor:Y?"cyan":"gray",padding:1,width:80,children:[B0(q$,{color:"cyan",bold:!0,children:"⚙️ 权限管理器"},void 0,!1,void 0,this),I(),B0(M1,{flexDirection:"column",gap:1,children:e()},void 0,!1,void 0,this),A&&B0(M1,{marginTop:1,children:B0(q$,{color:A.type==="success"?"green":"red",children:A.text},void 0,!1,void 0,this)},void 0,!1,void 0,this),B0(M1,{marginTop:1,children:B0(q$,{color:"gray",children:"Tab 切换视图 · Esc 关闭 · Q 退出"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};e8();import{Box as J$,Text as w0,useInput as BM}from"ink";import{jsxDEV as n}from"react/jsx-dev-runtime";function FF({onCancel:$}){let Z=Y1(),Y=Z.getAll(),Q=Z.getBySource(),X=Z.getStats(),J=W$(!1,$);if(BM((G,q)=>{if(q.escape)$?.();else if(q.ctrl&&G==="c"||q.meta&&G==="c")J()}),Y.length===0)return n(J$,{flexDirection:"column",paddingY:1,children:[n(J$,{marginBottom:1,children:n(w0,{bold:!0,color:"cyan",children:"\uD83D\uDD0C 插件管理器"},void 0,!1,void 0,this)},void 0,!1,void 0,this),n(J$,{paddingLeft:2,children:n(w0,{color:"gray",children:"没有已加载的插件"},void 0,!1,void 0,this)},void 0,!1,void 0,this),n(J$,{marginTop:1,paddingLeft:2,flexDirection:"column",children:[n(w0,{color:"gray",children:"插件目录位置:"},void 0,!1,void 0,this),n(w0,{color:"gray",dimColor:!0,children:[" ","• ~/.blade/plugins/ - 用户级插件"]},void 0,!0,void 0,this),n(w0,{color:"gray",dimColor:!0,children:[" ","• .blade/plugins/ - 项目级插件"]},void 0,!0,void 0,this),n(w0,{color:"gray",dimColor:!0,children:[" ","• --plugin-dir - CLI 指定的插件"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),n(J$,{marginTop:1,paddingLeft:2,children:n(w0,{color:"gray",children:"使用 /plugins install <url> 安装新插件"},void 0,!1,void 0,this)},void 0,!1,void 0,this),n(J$,{marginTop:1,children:n(w0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return n(J$,{flexDirection:"column",paddingY:1,children:[n(J$,{marginBottom:1,children:[n(w0,{bold:!0,color:"cyan",children:"\uD83D\uDD0C 插件管理器"},void 0,!1,void 0,this),n(w0,{color:"gray",children:[" (共 ",X.total," 个插件)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),n(J$,{paddingLeft:2,marginBottom:1,children:n(w0,{color:"gray",children:["启用: ",X.active," | 禁用: ",X.inactive," | 命令: ",X.commands," | 技能:"," ",X.skills," | 代理: ",X.agents]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q.cli.length>0&&n(J$,{flexDirection:"column",marginBottom:1,children:[n(J$,{paddingLeft:1,children:[n(w0,{bold:!0,color:"magenta",children:"CLI 指定"},void 0,!1,void 0,this),n(w0,{color:"gray",children:" (--plugin-dir)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.cli.map((G)=>{let q=G.status==="active"?"✅":"⏸️";return n(J$,{flexDirection:"column",paddingLeft:2,children:[n(w0,{children:[n(w0,{bold:!0,color:"green",children:[q," ",G.manifest.name]},void 0,!0,void 0,this),n(w0,{color:"gray",children:[" v",G.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),n(J$,{paddingLeft:2,children:n(w0,{color:"gray",children:G.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),G.commands.length>0&&n(J$,{paddingLeft:2,children:n(w0,{color:"blue",children:["命令:"," ",G.commands.map((K)=>`/${K.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},G.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.project.length>0&&n(J$,{flexDirection:"column",marginBottom:1,children:[n(J$,{paddingLeft:1,children:[n(w0,{bold:!0,color:"yellow",children:"项目级"},void 0,!1,void 0,this),n(w0,{color:"gray",children:" (.blade/plugins/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.project.map((G)=>{let q=G.status==="active"?"✅":"⏸️";return n(J$,{flexDirection:"column",paddingLeft:2,children:[n(w0,{children:[n(w0,{bold:!0,color:"green",children:[q," ",G.manifest.name]},void 0,!0,void 0,this),n(w0,{color:"gray",children:[" v",G.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),n(J$,{paddingLeft:2,children:n(w0,{color:"gray",children:G.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),G.commands.length>0&&n(J$,{paddingLeft:2,children:n(w0,{color:"blue",children:["命令:"," ",G.commands.map((K)=>`/${K.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},G.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.user.length>0&&n(J$,{flexDirection:"column",marginBottom:1,children:[n(J$,{paddingLeft:1,children:[n(w0,{bold:!0,color:"cyan",children:"用户级"},void 0,!1,void 0,this),n(w0,{color:"gray",children:" (~/.blade/plugins/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.user.map((G)=>{let q=G.status==="active"?"✅":"⏸️";return n(J$,{flexDirection:"column",paddingLeft:2,children:[n(w0,{children:[n(w0,{bold:!0,color:"green",children:[q," ",G.manifest.name]},void 0,!0,void 0,this),n(w0,{color:"gray",children:[" v",G.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),n(J$,{paddingLeft:2,children:n(w0,{color:"gray",children:G.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),G.commands.length>0&&n(J$,{paddingLeft:2,children:n(w0,{color:"blue",children:["命令:"," ",G.commands.map((K)=>`/${K.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},G.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),n(J$,{marginTop:1,paddingLeft:2,flexDirection:"column",children:[n(w0,{color:"gray",children:"可用命令:"},void 0,!1,void 0,this),n(w0,{color:"gray",dimColor:!0,children:[" ","• /plugins list - 列出所有插件"]},void 0,!0,void 0,this),n(w0,{color:"gray",dimColor:!0,children:[" ","• /plugins info <name> - 显示插件详情"]},void 0,!0,void 0,this),n(w0,{color:"gray",dimColor:!0,children:[" ","• /plugins install <url> - 安装插件"]},void 0,!0,void 0,this),n(w0,{color:"gray",dimColor:!0,children:[" ","• /plugins enable/disable <name> - 启用/禁用插件"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),n(J$,{marginTop:1,children:n(w0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}import{Box as a$,Text as n$,useInput as _F,useStdout as NM}from"ink";import LM from"ink-text-input";import nQ,{useCallback as x6,useMemo as wM,useState as k4}from"react";import{jsxDEV as M0}from"react/jsx-dev-runtime";var AM=nQ.memo(({option:$,index:Z,isSelected:Y,isMultiSelect:Q,isHighlighted:X})=>M0(a$,{flexDirection:"column",marginBottom:1,children:[M0(n$,{color:X?"yellow":Y?"green":void 0,bold:X,children:[Q?Y?"● ":"○ ":X?"❯ ":" ",Z+1,". ",$.label]},void 0,!0,void 0,this),M0(a$,{marginLeft:4,children:M0(n$,{color:"gray",children:$.description},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)),bM=nQ.memo(({questions:$,answers:Z})=>M0(a$,{flexDirection:"column",marginBottom:1,children:$.map((Y)=>{let Q=Z[Y.header],X=Array.isArray(Q)?Q.join(", "):Q||"(no answer)";return M0(a$,{marginBottom:1,children:[M0(n$,{backgroundColor:"blue",color:"white",children:[" ",Y.header," "]},void 0,!0,void 0,this),M0(n$,{color:"green",children:[" ",X]},void 0,!0,void 0,this)]},Y.header,!0,void 0,this)})},void 0,!1,void 0,this)),zF=nQ.memo(({questions:$,onComplete:Z,onCancel:Y})=>{let{stdout:Q}=NM(),X=Q.columns||80,G=_1()==="confirmation-prompt",q=W$(!1),[K,W]=k4("answering"),[U,H]=k4(0),[O,F]=k4({}),[_,z]=k4(0),[N,B]=k4([]),[L,A]=k4(!1),[R,V]=k4(""),[M,T]=k4(0),w=$[U],v=wM(()=>{if(!w)return[];return[...w.options.map((I)=>({label:I.label,value:I.label,description:I.description})),{label:"Type something...",value:"__other__",description:"Enter custom response"}]},[w]),l=x6((I)=>{let j={...O,[w.header]:I};if(F(j),U<$.length-1)H(U+1),z(0),B([]),A(!1),V("");else W("submit"),T(0)},[O,w?.header,U,$.length]),o=x6((I)=>{let j=v[I];if(!j)return;if(j.value==="__other__"){A(!0);return}if(w.multiSelect)B((D)=>D.includes(j.value)?D.filter((i)=>i!==j.value):[...D,j.value]);else l(j.value)},[v,w?.multiSelect,l]),S=x6((I)=>{if(I.trim())l(I.trim())},[l]),y=x6(()=>{W("answering"),H(0),z(0),B([]),A(!1)},[]),m=x6(()=>{Z(O)},[O,Z]);if(_F((I,j)=>{if(j.ctrl&&I==="c"||j.meta&&I==="c"){q();return}if(L){if(j.escape)A(!1),V("");return}if(j.escape){Y();return}let D=parseInt(I);if(D>=1&&D<=v.length){o(D-1);return}if(j.upArrow){z((i)=>i>0?i-1:v.length-1);return}if(j.downArrow||j.tab){z((i)=>i<v.length-1?i+1:0);return}if(j.return){if(w.multiSelect&&N.length>0)l(N);else o(_);return}if(I===" "&&w.multiSelect){let i=v[_];if(i&&i.value!=="__other__")B((g)=>g.includes(i.value)?g.filter((k)=>k!==i.value):[...g,i.value]);return}},{isActive:G&&K==="answering"&&!L}),_F((I,j)=>{if(j.ctrl&&I==="c"||j.meta&&I==="c"){q();return}if(j.escape){Y();return}if(j.upArrow||j.downArrow||j.tab){T((D)=>D===0?1:0);return}if(j.return){if(M===0)m();else y();return}if(I.toLowerCase()==="y"){m();return}if(I.toLowerCase()==="e"){y();return}},{isActive:G&&K==="submit"}),K==="submit")return M0(a$,{flexDirection:"column",borderStyle:"round",borderColor:G?"green":"gray",padding:1,width:Math.min(X-4,80),children:[M0(a$,{marginBottom:1,children:M0(n$,{bold:!0,color:"green",children:"✓ Review Your Answers"},void 0,!1,void 0,this)},void 0,!1,void 0,this),M0(bM,{questions:$,answers:O},void 0,!1,void 0,this),M0(a$,{flexDirection:"column",marginTop:1,children:[M0(n$,{color:M===0?"yellow":void 0,bold:M===0,children:[M===0?"❯ ":" ","[Y] Submit answers"]},void 0,!0,void 0,this),M0(n$,{color:M===1?"yellow":void 0,bold:M===1,children:[M===1?"❯ ":" ","[E] Edit answers"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),M0(a$,{marginTop:1,children:M0(n$,{color:"gray",children:"Enter to confirm · ↑↓ to navigate · Y/E for quick select"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(!w)return null;return M0(a$,{flexDirection:"column",borderStyle:"round",borderColor:G?"cyan":"gray",padding:1,width:Math.min(X-4,80),children:[M0(a$,{marginBottom:1,children:[M0(n$,{backgroundColor:"blue",color:"white",children:[" ",w.header," "]},void 0,!0,void 0,this),M0(n$,{children:[" ",w.question]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),L?M0(a$,{flexDirection:"column",marginTop:1,children:[M0(n$,{color:"yellow",children:"Enter your response:"},void 0,!1,void 0,this),M0(a$,{marginTop:1,children:[M0(n$,{color:"cyan",children:"❯ "},void 0,!1,void 0,this),M0(LM,{value:R,onChange:V,onSubmit:S,focus:G},void 0,!1,void 0,this)]},void 0,!0,void 0,this),M0(a$,{marginTop:1,children:M0(n$,{color:"gray",children:"(Press Enter to submit, ESC to go back)"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this):M0(a$,{flexDirection:"column",children:v.map((I,j)=>M0(AM,{option:I,index:j,isSelected:N.includes(I.value),isMultiSelect:w.multiSelect,isHighlighted:_===j},I.value,!1,void 0,this))},void 0,!1,void 0,this),!L&&M0(a$,{marginTop:1,flexDirection:"column",children:[M0(n$,{color:"gray",children:w.multiSelect?"Space to toggle · Enter to confirm · 1-9 for quick select":"Enter to select · ↑↓ or Tab to navigate · 1-9 for quick select"},void 0,!1,void 0,this),w.multiSelect&&N.length>0&&M0(n$,{color:"green",children:["Selected: ",N.join(", ")]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$.length>1&&M0(a$,{marginTop:1,children:M0(n$,{color:"gray",children:["Question ",U+1," of ",$.length]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});B6();import{Box as R3,Text as H2,useInput as VM}from"ink";import RM from"ink-select-input";import{basename as DM}from"node:path";import{useEffect as BF,useMemo as c9,useState as oQ}from"react";import{jsxDEV as C$}from"react/jsx-dev-runtime";function MM($){let Z=new Date($),Q=new Date().getTime()-Z.getTime(),X=Math.floor(Q/86400000);if(X===0)return`今天 ${Z.getHours().toString().padStart(2,"0")}:${Z.getMinutes().toString().padStart(2,"0")}`;if(X===1)return"昨天";if(X<7)return`${X}天前`;return`${Z.getMonth()+1}/${Z.getDate()}`}function jM($){return DM($)}var TM=({isSelected:$})=>C$(R3,{marginRight:1,children:C$(H2,{color:$?"cyan":"gray",children:$?"❯":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),yM=({isSelected:$,label:Z})=>C$(H2,{color:$?"cyan":"white",bold:$,children:Z},void 0,!1,void 0,this),p6=20,NF=({sessions:$,onSelect:Z,onCancel:Y})=>{let[Q,X]=oQ([]),[J,G]=oQ(!1),[q,K]=oQ(0),U=_1()==="session-selector",H=W$(!1);VM((L,A)=>{if(A.ctrl&&L==="c"||A.meta&&L==="c"){H();return}if(A.escape&&Y){Y();return}if(A.leftArrow||L==="h"||L==="H"){if(q>0)K((R)=>R-1);return}if(A.rightArrow||L==="l"||L==="L"){if(q<_-1)K((R)=>R+1);return}},{isActive:U}),BF(()=>{if($){X($);return}(async()=>{G(!0);try{let A=await P$.listSessions();X(A)}catch(A){console.error("[SessionSelector] Failed to load sessions:",A),X([])}finally{G(!1)}})()},[$]);let O=$||Q,F=c9(()=>{return O.map((L)=>{let A=jM(L.projectPath),R=MM(L.lastMessageTime),V=L.gitBranch?` (${L.gitBranch})`:"",M=L.hasErrors?" ⚠️":"",T=L.relationType==="subagent"?" ↳ subagent":"";return{label:`\uD83D\uDCC5 ${R} | ${A}${V} | ${L.messageCount} 条消息${M}${T}`,value:L.sessionId}})},[O]),_=c9(()=>Math.max(1,Math.ceil(F.length/p6)),[F.length]),z=c9(()=>{let L=q*p6;return F.slice(L,L+p6)},[F,q]),N=c9(()=>({start:q*p6+1,end:Math.min((q+1)*p6,F.length)}),[q,F.length]);BF(()=>{K(0)},[O.length]);let B=(L)=>{Z(L.value)};if(J)return C$(R3,{flexDirection:"column",paddingX:2,paddingY:1,children:C$(H2,{children:"⏳ 正在加载会话列表..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(O.length===0)return C$(R3,{flexDirection:"column",paddingX:2,paddingY:1,children:[C$(H2,{color:"yellow",children:"⚠️ 没有找到历史会话"},void 0,!1,void 0,this),C$(H2,{dimColor:!0,children:[`
|
|
2921
|
+
`).length}var dQ=LD.memo(({content:$,isStreaming:Z=!1,isExpanded:Y})=>{let Q=o0(),X=xO(()=>AD($),[$]),J=xO(()=>wD($),[$]),G=Q.colors.info,q=Q.colors.muted;return l2(uQ,{flexDirection:"column",marginBottom:1,children:[l2(uQ,{flexDirection:"row",children:[l2(b3,{color:G,children:Y?"▼":"▶"},void 0,!1,void 0,this),l2(b3,{children:" "},void 0,!1,void 0,this),l2(b3,{color:q,children:["Thinking",Z?"...":` (${X} lines)`]},void 0,!0,void 0,this),!Y&&!Z&&J&&l2(b3,{color:q,children:[" - ",J]},void 0,!0,void 0,this),l2(b3,{color:q,dimColor:!0,children:[" ","[Ctrl+T]"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Y&&$&&l2(uQ,{marginLeft:2,marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,paddingY:0,children:l2(b3,{color:q,children:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});dQ.displayName="ThinkingBlock";import{Box as p5,Text as cQ}from"ink";import pO from"react";import{jsxDEV as y4}from"react/jsx-dev-runtime";var mO=pO.memo(({todos:$,visible:Z=!0,compact:Y=!1})=>{let{colors:Q}=o0();if(!Z||$.length===0)return null;let X={total:$.length,completed:$.filter((J)=>J.status==="completed").length,inProgress:$.filter((J)=>J.status==="in_progress").length};return y4(p5,{flexDirection:"column",borderStyle:"single",borderColor:Q.border.light,paddingX:1,paddingY:Y?0:1,marginBottom:1,children:[y4(p5,{marginBottom:Y?0:1,children:[y4(cQ,{dimColor:!0,children:"Tasks "},void 0,!1,void 0,this),y4(cQ,{color:Q.text.muted,children:[X.completed,"/",X.total]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),y4(p5,{flexDirection:"column",children:$.map((J,G)=>y4(bD,{todo:J,compact:Y},J.id||G,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}),bD=pO.memo(({todo:$,compact:Z})=>{let Y,Q=!1,X;switch($.status){case"completed":Y="✓",Q=!0,X=$.content;break;case"in_progress":Y="▶",Q=!1,X=$.activeForm;break;case"pending":default:Y="○",Q=!0,X=$.content;break}return y4(p5,{paddingY:Z?0:0,children:y4(cQ,{dimColor:Q,children:[Y," ",X]},void 0,!0,void 0,this)},void 0,!1,void 0,this)});import{jsxDEV as v$}from"react/jsx-dev-runtime";var dO=RD.memo(()=>{let $=B5(),Z=FH(),Y=_H(),Q=zH(),X=j4(),J=$H(),G=XH(),q=UH(),K=HH(),W=OH(),U=nU(),H=NH(),O=BH(),F=_3(),_=EO(),{stdout:z}=VD(),N=D4(),[B,L]=iQ(null),[A,R]=iQ([]),[V,M]=iQ(new Set),T=I4(O),w=I4(null),v=I4(0),l=I4(0),o=I4(new Set),S=I4(new Set),y=I4([]),m=I4(null);i2(()=>{if(T.current!==O){if(M2())c2();if(z)z.write(lQ.clearTerminal);N.incrementClearCount(),T.current=O}},[O,z,N]);let I=$,j=Q;i2(()=>{if(!Q||X){m.current=null;return}if(m.current===Q)return;if(m.current=Q,M2())c2();if(z)z.write(lQ.eraseScreen);o.current=new Set,S.current=new Set(I.filter((C)=>C.role==="tool").map((C)=>C.id)),w.current=null,v.current=0,l.current=0,y.current=[],R([]),M(new Set),N.incrementClearCount(),N.clearFinalizingStreamingMessageId()},[Q,X,z,N,I]);let D=Z??Q;i2(()=>{if(M2())c2();w.current=null,v.current=0,l.current=0,o.current=new Set,S.current=new Set(I.filter((C)=>C.role==="tool").map((C)=>C.id)),y.current=[],R([]),M(new Set)},[U]),i2(()=>{if(!D)return;if(w.current===D)return;w.current=D,v.current=0,l.current=0,S.current=new Set(I.filter((C)=>C.role==="tool").map((C)=>C.id)),y.current=[],R([])},[D,I]),i2(()=>{if(!D)return;let C=z9(D);if(!C||C.length<=v.current)return;let r=C.slice(v.current);v.current=C.length;let h=r,c=y.current;if(c.length>0)if(h.some((i0)=>i0.type!=="empty"))h=[...c,...h],y.current=[];else{y.current=[...c,...h];return}let j0=h.length;while(j0>0&&h[j0-1].type==="empty")j0-=1;if(j0!==h.length)y.current=h.slice(j0),h=h.slice(0,j0);if(h.length===0)return;let E0=l.current;l.current+=1;let g0=E0>0;if(M2())c2();M((i0)=>{if(!D||i0.has(D))return i0;let s$=new Set(i0);return s$.add(D),s$}),R((i0)=>[...i0,v$(E4,{flexDirection:"column",children:v$(R8,{content:"",role:"assistant",terminalWidth:F,isPending:!1,hidePrefix:g0,noMargin:!0,blocksOverride:h,renderCodeBlocksAsPlainText:!0},void 0,!1,void 0,this)},`streaming-${D}-${E0}`,!1,void 0,this)])},[D,Y.version,F,U]),i2(()=>{if(!D)return;let C=S.current,r=I.filter((h)=>h.role==="tool"&&!C.has(h.id)&&!o.current.has(h.id));if(r.length===0)return;if(M2())c2();for(let h of r)o.current.add(h.id);R((h)=>[...h,...r.map((c)=>v$(E4,{flexDirection:"column",children:v$(R8,{content:c.content,role:c.role,terminalWidth:F,metadata:c.metadata,isPending:!1,messageId:c.id},void 0,!1,void 0,this)},`streaming-tool-${c.id}`,!1,void 0,this))])},[D,I,F]),i2(()=>{if(!D){if(M2())c2();return}if(!M2())CO(F,_);else kO(F,_);let C=CX(D);if(!C||C.lines.length===0)return;let h=Math.max(1,_-8),c=Math.max(0,C.lines.length-h),j0=C.lines.slice(-h),E0=(z9(D)?.length??0)>0;SO(j0,c,C.mode,E0)},[D,Y.version,_,F]),i2(()=>{if(!D&&M2())c2()},[D]),i2(()=>{if(B===null&&I.length>H){if(L(I.length),M2())c2();if(z)z.write(lQ.clearTerminal);N.incrementClearCount()}},[I.length,H,B,z,N]);let i=uO(()=>{return J.some((C)=>C.status==="pending"||C.status==="in_progress")},[J]),g=O?0:B??0,k=g,e=uO(()=>{let C=[];if(C.push(v$(hO,{},"header",!1,void 0,this)),k>0)C.push(v$(gQ,{collapsedCount:k},"collapsed-summary",!1,void 0,this));for(let r=g;r<I.length;r++){let h=I[r];if(j&&h.id===j)continue;if(h.role==="tool"&&o.current.has(h.id))continue;if(h.role==="assistant"&&V.has(h.id))continue;C.push(v$(E4,{flexDirection:"column",children:v$(R8,{content:h.content,role:h.role,terminalWidth:F,metadata:h.metadata,isPending:!1,messageId:h.id},void 0,!1,void 0,this)},h.id,!1,void 0,this))}return C},[I,g,k,F,j,V]);return v$(E4,{flexDirection:"column",paddingX:2,children:v$(E4,{flexDirection:"column",children:[v$(gO,{items:e,children:(C)=>C},U,!1,void 0,this),K&&v$(E4,{marginBottom:1,children:v$(dQ,{content:K,isStreaming:X,isExpanded:W},void 0,!1,void 0,this)},void 0,!1,void 0,this),A.length>0&&v$(gO,{items:A,children:(C)=>C},`streaming-${U}`,!1,void 0,this),G&&i&&v$(E4,{marginTop:1,children:v$(mO,{todos:J,visible:!0,compact:!1},void 0,!1,void 0,this)},void 0,!1,void 0,this),q.map((C,r)=>v$(E4,{flexDirection:"column",children:v$(R8,{content:C.displayText,role:"user",terminalWidth:F},void 0,!1,void 0,this)},`pending-${r}`,!1,void 0,this))]},void 0,!0,void 0,this)},void 0,!1,void 0,this)});b0();import{useMemoizedFn as a2}from"ahooks";import{Box as d$,Text as A$,useFocusManager as dD,useInput as GF}from"ink";import cD from"ink-text-input";import{useState as v4}from"react";import{Box as r2,Text as V1,useInput as DD}from"ink";import MD from"ink-text-input";import{jsxDEV as F$}from"react/jsx-dev-runtime";var cO=({provider:$,value:Z,onChange:Y,onSubmit:Q,onCancel:X,error:J})=>{DD((q,K)=>{if(K.escape)X()});let G=$.envVars.length>0?$.envVars[0]:null;return F$(r2,{flexDirection:"column",children:[F$(r2,{marginBottom:1,children:F$(V1,{bold:!0,color:"blue",children:"\uD83D\uDD11 Step 2: 输入 API Key"},void 0,!1,void 0,this)},void 0,!1,void 0,this),F$(r2,{marginBottom:1,children:F$(V1,{children:["Provider: ",$.icon," ",F$(V1,{bold:!0,children:$.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),G&&F$(r2,{marginBottom:1,children:F$(V1,{dimColor:!0,children:["\uD83D\uDCA1 环境变量: ",F$(V1,{color:"cyan",children:G},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),$.docUrl&&F$(r2,{marginBottom:1,children:F$(V1,{dimColor:!0,children:["\uD83D\uDCD6 文档: ",F$(V1,{color:"blue",children:$.docUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),F$(r2,{marginBottom:1,children:F$(V1,{dimColor:!0,children:"您的 API 密钥将被安全存储在 ~/.blade/config.json (权限 600)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),F$(r2,{children:[F$(V1,{bold:!0,color:"cyan",children:["▶"," "]},void 0,!0,void 0,this),F$(MD,{value:Z,onChange:Y,onSubmit:Q,placeholder:"sk-...",mask:"*"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J&&F$(r2,{marginTop:1,children:F$(V1,{color:"red",children:["❌ ",J]},void 0,!0,void 0,this)},void 0,!1,void 0,this),F$(r2,{marginTop:1,children:F$(V1,{dimColor:!0,children:["\uD83D\uDCA1 输入完成后按 ",F$(V1,{bold:!0,children:"Enter"},void 0,!1,void 0,this),",",F$(V1,{bold:!0,children:"Esc"},void 0,!1,void 0,this)," 返回"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{useEffect as lO,useState as V3}from"react";C8();var jD={id:"custom-openai-compatible",name:"自定义 OpenAI Compatible",icon:"\uD83D\uDD27",description:"使用自定义 Base URL 和 API Key",isOAuth:!1,envVars:[],bladeProvider:"openai-compatible",isCustom:!0},iO=()=>{let[$,Z]=V3([]),[Y,Q]=V3(!0),[X,J]=V3(null);return lO(()=>{(async()=>{try{let q=await H5(),K=Object.entries(l6).map(([W,U])=>({id:W,name:W==="antigravity"?"Google Antigravity":"GitHub Copilot",icon:U.icon,description:U.description,isOAuth:!0,envVars:[],bladeProvider:U.bladeProvider}));Z([...K,jD,...q])}catch(q){J(q instanceof Error?q.message:"加载 Provider 列表失败")}finally{Q(!1)}})()},[]),{providers:$,isLoading:Y,error:X}},rO=($)=>{let[Z,Y]=V3([]),[Q,X]=V3(!1),[J,G]=V3(null);return lO(()=>{if(!$){Y([]);return}(async()=>{X(!0),G(null);try{let K=await O5($);Y(K)}catch(K){G(K instanceof Error?K.message:"加载模型列表失败")}finally{X(!1)}})()},[$]),{models:Z,isLoading:Q,error:J}};import{Box as U2,Text as m1,useInput as TD}from"ink";import yD from"ink-select-input";import aO from"ink-text-input";import{useMemo as nO,useState as rQ}from"react";import{jsxDEV as e0,Fragment as vD}from"react/jsx-dev-runtime";var ED=({isSelected:$})=>e0(U2,{marginRight:1,children:e0(m1,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),ID=($)=>{let Z=[$.name];if($.contextWindow){let Y=$.contextWindow>=1e6?`${($.contextWindow/1e6).toFixed(1)}M`:$.contextWindow>=1000?`${Math.round($.contextWindow/1000)}K`:`${$.contextWindow}`;Z.push(`[${Y} ctx]`)}if($.inputCost!==void 0&&$.outputCost!==void 0)Z.push(`[$${$.inputCost}/$${$.outputCost}]`);return Z.join(" ")},PD=({isSelected:$,label:Z})=>e0(m1,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),oO=({provider:$,models:Z,isLoading:Y,error:Q,onSelect:X,onCancel:J,initialModel:G})=>{let[q,K]=rQ(""),W=$.isCustom||Z.length===0,[U,H]=rQ(W),[O,F]=rQ(G||"");TD((B,L)=>{if(L.escape){if(U&&!W)H(!1),F(G||"");else if(q)K("");else J();return}if(B==="+"&&!U)H(!0)});let _=nO(()=>{if(!q)return Z;let B=q.toLowerCase();return Z.filter((L)=>L.name.toLowerCase().includes(B)||L.id.toLowerCase().includes(B))},[Z,q]),z=nO(()=>_.map((B)=>({key:B.id,label:ID(B),value:B})),[_]),N=()=>{if(O.trim())X({id:O.trim(),name:O.trim()})};if(Y)return e0(U2,{flexDirection:"column",children:e0(m1,{color:"yellow",children:["⏳ 正在加载 ",$.name," 模型列表..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this);if(Q)return e0(U2,{flexDirection:"column",children:[e0(m1,{color:"red",children:["❌ ",Q]},void 0,!0,void 0,this),e0(m1,{dimColor:!0,children:"按 Esc 返回"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return e0(U2,{flexDirection:"column",children:[e0(U2,{marginBottom:1,children:e0(m1,{bold:!0,color:"blue",children:"\uD83E\uDD16 Step 3: 选择模型"},void 0,!1,void 0,this)},void 0,!1,void 0,this),e0(U2,{marginBottom:1,children:e0(m1,{children:["Provider: ",$.icon," ",e0(m1,{bold:!0,children:$.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),U?e0(U2,{flexDirection:"column",children:[e0(U2,{marginBottom:1,children:e0(m1,{dimColor:!0,children:W?"输入模型名称:":"输入自定义模型名称(按 Esc 返回列表):"},void 0,!1,void 0,this)},void 0,!1,void 0,this),e0(U2,{children:[e0(m1,{bold:!0,color:"cyan",children:"▶ "},void 0,!1,void 0,this),e0(aO,{value:O,onChange:F,onSubmit:N,placeholder:"例如: gpt-4o-mini"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this):e0(vD,{children:[e0(U2,{marginBottom:1,children:[e0(m1,{color:"cyan",children:"\uD83D\uDD0D "},void 0,!1,void 0,this),e0(aO,{value:q,onChange:K,placeholder:`搜索 ${Z.length} 个模型,按 + 自定义...`},void 0,!1,void 0,this)]},void 0,!0,void 0,this),e0(U2,{flexDirection:"column",height:12,children:e0(yD,{items:z,onSelect:(B)=>X(B.value),indicatorComponent:ED,itemComponent:PD,limit:10},void 0,!1,void 0,this)},void 0,!1,void 0,this),_.length===0&&e0(m1,{color:"yellow",children:"未找到匹配的模型,按 + 输入自定义模型名称"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};f3();C3();u3();p3();import{Box as g1,Text as R1,useFocus as tO,useInput as eO}from"ink";import CD from"ink-select-input";import{useEffect as kD,useState as sO}from"react";import{jsxDEV as X$}from"react/jsx-dev-runtime";var $F=({provider:$,onLogin:Z,onCancel:Y,isLoggingIn:Q})=>{let{isFocused:X}=tO({id:"oauth-login"});return eO((J,G)=>{if(Q)return;if(J==="y"||J==="Y")Z();else if(J==="n"||J==="N"||G.escape)Y()},{isActive:X&&!Q}),X$(g1,{flexDirection:"column",children:[X$(g1,{marginBottom:1,children:X$(R1,{bold:!0,color:"yellow",children:[$.icon," 需要登录 ",$.name]},void 0,!0,void 0,this)},void 0,!1,void 0,this),X$(g1,{marginBottom:1,children:X$(R1,{children:$.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),X$(g1,{marginBottom:1,paddingLeft:2,children:X$(R1,{dimColor:!0,children:["您也可以稍后手动执行"," ",X$(R1,{bold:!0,children:$.id==="antigravity"?"/login":"/login copilot"},void 0,!1,void 0,this)," ","命令登录"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),!Q&&X$(g1,{marginTop:1,children:X$(R1,{children:["现在登录? [",X$(R1,{bold:!0,color:"green",children:"Y"},void 0,!1,void 0,this),"/",X$(R1,{bold:!0,color:"red",children:"n"},void 0,!1,void 0,this),"]"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q&&X$(g1,{marginTop:1,children:X$(R1,{color:"yellow",children:"⏳ 正在启动登录流程..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},SD=({isSelected:$})=>X$(g1,{marginRight:1,children:X$(R1,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),fD=({isSelected:$,label:Z})=>X$(R1,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),ZF=({provider:$,onSelect:Z,onCancel:Y})=>{let{isFocused:Q}=tO({id:"oauth-model-select"}),[X,J]=sO([]),[G,q]=sO(!0);kD(()=>{(async()=>{q(!0);try{if($.id==="copilot")J(Object.values(s6));else{let H=await l$.getInstance().getConfigType();J(H==="gemini-cli"?Object.values(r6):Object.values(v3))}}catch{J(Object.values(v3))}finally{q(!1)}})()},[$.id]),eO((W,U)=>{if(U.escape)Y()},{isActive:Q});let K=X.map((W)=>({key:W.id,label:`${W.name} - ${W.description}`,value:{id:W.id,name:W.name}}));if(G)return X$(g1,{flexDirection:"column",children:X$(R1,{color:"yellow",children:["⏳ 加载 ",$.name," 模型列表..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this);return X$(g1,{flexDirection:"column",children:[X$(g1,{marginBottom:1,children:X$(R1,{bold:!0,color:"blue",children:["\uD83E\uDD16 选择 ",$.name," 模型"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),X$(g1,{marginBottom:1,children:X$(R1,{dimColor:!0,children:"从可用模型列表中选择一个"},void 0,!1,void 0,this)},void 0,!1,void 0,this),X$(g1,{flexDirection:"column",height:12,children:X$(CD,{items:K,onSelect:(W)=>Z(W.value),indicatorComponent:SD,itemComponent:fD,limit:10},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},YF=async($)=>{let Z=$==="antigravity"?l$.getInstance():t$.getInstance();try{return await Z.login(),!0}catch{return!1}},QF=async($)=>{let Z=$==="antigravity"?l$.getInstance():t$.getInstance();try{return await Z.isLoggedIn()}catch{return!1}};import{Box as T8,Text as P4,useInput as hD}from"ink";import xD from"ink-select-input";import pD from"ink-text-input";import{useMemo as XF,useState as mD}from"react";import{jsxDEV as u$}from"react/jsx-dev-runtime";var gD=({isSelected:$})=>u$(T8,{marginRight:1,children:u$(P4,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),uD=({isSelected:$,label:Z})=>u$(P4,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),JF=({providers:$,isLoading:Z,error:Y,onSelect:Q,onCancel:X})=>{let[J,G]=mD("");hD((W,U)=>{if(U.escape)if(J)G("");else X()});let q=XF(()=>{if(!J)return $;let W=J.toLowerCase();return $.filter((U)=>U.name.toLowerCase().includes(W)||U.id.toLowerCase().includes(W))},[$,J]),K=XF(()=>q.map((W)=>({key:W.id,label:`${W.icon} ${W.name} - ${W.description}`,value:W})),[q]);if(Z)return u$(T8,{flexDirection:"column",children:u$(P4,{color:"yellow",children:"⏳ 正在加载 Provider 列表..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(Y)return u$(T8,{flexDirection:"column",children:[u$(P4,{color:"red",children:["❌ ",Y]},void 0,!0,void 0,this),u$(P4,{dimColor:!0,children:"按 Esc 返回"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return u$(T8,{flexDirection:"column",children:[u$(T8,{marginBottom:1,children:u$(P4,{bold:!0,color:"blue",children:"\uD83D\uDCE1 Step 1: 选择 API 提供商"},void 0,!1,void 0,this)},void 0,!1,void 0,this),u$(T8,{marginBottom:1,children:[u$(P4,{color:"cyan",children:"\uD83D\uDD0D "},void 0,!1,void 0,this),u$(pD,{value:J,onChange:G,placeholder:`搜索 ${$.length} 个 Provider...`},void 0,!1,void 0,this)]},void 0,!0,void 0,this),u$(T8,{flexDirection:"column",height:12,children:u$(xD,{items:K,onSelect:(W)=>Q(W.value),indicatorComponent:gD,itemComponent:uD,limit:10},void 0,!1,void 0,this)},void 0,!1,void 0,this),q.length===0&&u$(P4,{color:"yellow",children:"未找到匹配的 Provider,按 Esc 清除搜索"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};C8();import{jsxDEV as G0,Fragment as iD}from"react/jsx-dev-runtime";var aQ=({mode:$,initialConfig:Z,modelId:Y,onComplete:Q,onCancel:X})=>{let J=$==="edit",[G,q]=v4("provider"),[K,W]=v4(),[U,H]=v4(J?Z?.apiKey||"":""),[O,F]=v4(J?Z?.baseUrl||"":""),[_]=v4(J?Z?.model||"":""),[z,N]=v4(),[B,L]=v4(!1),[A,R]=v4(!1),{providers:V,isLoading:M,error:T}=iO(),{models:w,isLoading:v,error:l}=rO(K?.isOAuth?void 0:K?.id),o=W$(!1),{focus:S}=dD();GF((c,j0)=>{if(j0.ctrl&&c==="c"||j0.meta&&c==="c")$==="setup"?o():X()});let y=a2((c)=>{let E0={provider:"",apiKey:"",baseUrl:"",model:"",oauthLogin:"oauth-login",oauthModelSelect:"oauth-model-select",confirm:""}[c];if(E0)S(E0)}),m=a2((c)=>{return c.defaultBaseUrl||i6[c.id]||""}),I=a2(async(c)=>{W(c),N(void 0);let j0=m(c);if(!J)F(j0);if(c.isOAuth){let g0=await QF(c.id)?"oauthModelSelect":"oauthLogin";q(g0),y(g0)}else q("apiKey")}),j=a2(()=>{if(!U.trim()){N("API Key 不能为空");return}N(void 0);let c=K?m(K):"";if(K?.isCustom||!c&&!O)q("baseUrl");else q("model")}),D=a2(()=>{if(!O.trim()){N("Base URL 不能为空");return}try{new URL(O)}catch{N("请输入有效的 URL (例如: https://api.example.com/v1)");return}N(void 0),q("model")}),i=a2(async(c)=>{N(void 0),L(!0);try{let j0=O||(K?m(K):""),g0={name:J&&Z?.name?Z.name:`${K?.name||"Model"} - ${c.name}`,provider:K?.bladeProvider||Z?.provider||"openai-compatible",baseUrl:j0,apiKey:K?.isOAuth?"oauth":U,model:c.id,...c.contextWindow&&{maxContextTokens:c.contextWindow},...c.maxOutput&&{maxOutputTokens:c.maxOutput},...K?.id&&{providerId:K.id}};if($==="setup")Q(g0);else if($==="add"){let i0=await A0().addModel(g0);await A0().setCurrentModel(i0.id),Q(g0)}else if($==="edit"&&Y)await A0().updateModel(Y,g0),Q(g0)}catch(j0){N(j0 instanceof Error?j0.message:"保存配置失败"),L(!1)}}),g=a2(async()=>{if(!K)return;R(!0),N(void 0);let c=await YF(K.id);if(R(!1),c)q("oauthModelSelect"),y("oauthModelSelect");else N("登录失败,请重试")}),k=a2(()=>{switch(N(void 0),G){case"apiKey":q("provider");break;case"baseUrl":q("apiKey");break;case"model":{if(!(K?m(K):""))q("baseUrl");else q("apiKey");break}case"oauthLogin":case"oauthModelSelect":q("provider");break}}),e=a2(()=>{q("apiKey")}),C=G==="provider"?1:G==="apiKey"||G==="oauthLogin"?2:G==="baseUrl"?2.5:3,r=3;return G0(d$,{...$==="setup"?{flexDirection:"column",padding:1}:{flexDirection:"column",borderStyle:"round",borderColor:$==="edit"?"yellow":"blue",padding:1},children:[$==="setup"&&G0(iD,{children:[G0(d$,{marginBottom:1,children:G0(A$,{bold:!0,color:"blue",children:"\uD83D\uDE80 欢迎使用 Blade Code"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(d$,{marginBottom:1,children:G0(A$,{children:"AI 驱动的代码助手 - 让我们开始配置您的助手"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(d$,{marginBottom:1,children:[G0(A$,{bold:!0,color:"blue",children:"█".repeat(Math.floor((C-1)/(r-1)*40))},void 0,!1,void 0,this),G0(A$,{dimColor:!0,children:"░".repeat(40-Math.floor((C-1)/(r-1)*40))},void 0,!1,void 0,this),G0(A$,{children:" "},void 0,!1,void 0,this),G0(A$,{bold:!0,color:"cyan",children:[Math.ceil(C),"/",r]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),G0(d$,{marginBottom:1,children:G0(A$,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$!=="setup"&&G0(d$,{justifyContent:"center",marginBottom:1,children:G0(A$,{bold:!0,color:$==="edit"?"yellow":"blue",children:$==="edit"?"编辑模型配置":"添加新模型配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G==="provider"&&G0(JF,{providers:V,isLoading:M,error:T,onSelect:I,onCancel:$==="setup"?()=>{}:X},void 0,!1,void 0,this),G==="apiKey"&&K&&G0(cO,{provider:K,value:U,onChange:H,onSubmit:j,onCancel:k,error:z},void 0,!1,void 0,this),G==="baseUrl"&&K&&G0(lD,{provider:K,value:O,onChange:F,onSubmit:D,onCancel:e,error:z},void 0,!1,void 0,this),G==="model"&&K&&G0(oO,{provider:K,models:w,isLoading:v,error:l,onSelect:i,onCancel:k,initialModel:J?_:void 0},void 0,!1,void 0,this),G==="oauthLogin"&&K&&G0($F,{provider:K,onLogin:g,onCancel:k,isLoggingIn:A},void 0,!1,void 0,this),G==="oauthModelSelect"&&K&&G0(ZF,{provider:K,onSelect:i,onCancel:k},void 0,!1,void 0,this),z&&G!=="apiKey"&&G!=="baseUrl"&&G0(d$,{marginTop:1,borderStyle:"round",borderColor:"red",paddingX:1,children:G0(A$,{color:"red",children:["❌ ",z]},void 0,!0,void 0,this)},void 0,!1,void 0,this),B&&G0(d$,{marginTop:1,children:G0(A$,{color:"yellow",children:"⏳ 正在保存配置..."},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(d$,{marginTop:1,children:G0(A$,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},lD=({provider:$,value:Z,onChange:Y,onSubmit:Q,onCancel:X,error:J})=>{return GF((G,q)=>{if(q.escape)X()}),G0(d$,{flexDirection:"column",children:[G0(d$,{marginBottom:1,children:G0(A$,{bold:!0,color:"blue",children:"\uD83C\uDF10 输入 Base URL"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(d$,{marginBottom:1,children:G0(A$,{children:["Provider: ",$.icon," ",G0(A$,{bold:!0,children:$.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),G0(d$,{marginBottom:1,children:G0(A$,{dimColor:!0,children:"此 Provider 没有默认的 API 端点,请输入完整的 Base URL"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(d$,{marginBottom:1,children:G0(A$,{dimColor:!0,children:"示例: https://api.example.com/v1"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(d$,{children:[G0(A$,{bold:!0,color:"cyan",children:"▶ "},void 0,!1,void 0,this),G0(cD,{value:Z,onChange:Y,onSubmit:Q,placeholder:"https://api.example.com/v1"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J&&G0(d$,{marginTop:1,children:G0(A$,{color:"red",children:["❌ ",J]},void 0,!0,void 0,this)},void 0,!1,void 0,this),G0(d$,{marginTop:1,children:G0(A$,{dimColor:!0,children:["\uD83D\uDCA1 输入完成后按 ",G0(A$,{bold:!0,children:"Enter"},void 0,!1,void 0,this),",",G0(A$,{bold:!0,children:"Esc"},void 0,!1,void 0,this)," 返回"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};x9();import{useMemoizedFn as m5,useMount as rD}from"ahooks";import{Box as D1,Text as S0,useFocus as aD,useFocusManager as nD,useInput as oD}from"ink";import sD from"ink-select-input";import{memo as tD,useMemo as eD,useState as g5}from"react";b0();import{jsxDEV as K0}from"react/jsx-dev-runtime";function $M($){switch($){case"openai-compatible":return"⚡ OpenAI Compatible";case"anthropic":return"\uD83E\uDD16 Anthropic Claude";case"gemini":return"✨ Google Gemini";case"azure-openai":return"☁️ Azure OpenAI";default:return $}}var ZM=({isSelected:$})=>K0(D1,{marginRight:1,children:K0(S0,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),YM=({isSelected:$,label:Z})=>K0(S0,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),qF=tD(({onClose:$,onEdit:Z})=>{let Y=JH(),Q=GH()??"",{isFocused:X}=aD({id:"model-selector"}),J=nD(),[G,q]=g5(""),[K,W]=g5(!1),[U,H]=g5(null),O=W$(!1),[F]=g5(()=>{let M=process.stdout?.columns||80;return Math.max(20,M-8)});rD(()=>{if(J?.focus("model-selector"),Y.length>0)q(Y[0].id)}),oD((M,T)=>{if(K)return;if(T.ctrl&&M==="c"||T.meta&&M==="c"){O();return}if(T.escape){$();return}if(!X)return;if(M==="d"||M==="D"){z();return}if((M==="e"||M==="E")&&Z)N()},{isActive:!0});let _=m5(async(M)=>{if(K)return;let T=M.value;if(T===Q){$();return}W(!0),H(null);try{await A0().setCurrentModel(T),$()}catch(w){H(w.message),W(!1)}}),z=m5(async()=>{if(K||G===Q)return;W(!0),H(null);try{if(await A0().removeModel(G),Y.length<=1)$()}catch(M){H(M.message)}finally{W(!1)}}),N=m5(()=>{if(K||!Z)return;let M=Y.find((T)=>T.id===G);if(!M)return;Z(M)}),B=m5((M)=>{q(M.value)}),L=eD(()=>{return Y.find((M)=>M.id===G)},[Y,G]),A=Y.map((M)=>{let T=M.id===Q?" (当前)":"";return{label:M.name+T,value:M.id}}),R=G===Q;return K0(D1,{flexDirection:"column",borderStyle:"round",borderColor:"gray",padding:1,width:"100%",children:[K0(D1,{flexDirection:"row",justifyContent:"space-between",marginBottom:1,children:[K0(S0,{bold:!0,color:"cyan",children:"模型管理"},void 0,!1,void 0,this),K0(S0,{dimColor:!0,children:[K?"⏳ 处理中...":R?"Enter=关闭 • E=编辑 • Esc=取消":"Enter=切换 • D=删除 • E=编辑 • Esc=取消"," • Ctrl+C=退出"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),K0(D1,{flexDirection:"row",children:[K0(D1,{flexDirection:"column",flexGrow:2,marginRight:2,borderStyle:"single",borderColor:"gray",padding:1,children:[K0(S0,{dimColor:!0,children:["已配置模型 (",Y.length,")"]},void 0,!0,void 0,this),K0(D1,{marginTop:1,children:K0(sD,{items:A,onSelect:_,onHighlight:B,indicatorComponent:ZM,itemComponent:YM},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K0(D1,{flexDirection:"column",flexGrow:3,borderStyle:"single",borderColor:"gray",padding:1,children:[K0(S0,{dimColor:!0,children:"模型详情"},void 0,!1,void 0,this),K0(D1,{marginY:1,children:K0(S0,{color:R?"green":"yellow",children:R?"● 当前使用":"● 可切换"},void 0,!1,void 0,this)},void 0,!1,void 0,this),L?K0(D1,{flexDirection:"column",children:[K0(S0,{children:[K0(S0,{dimColor:!0,children:"名称: "},void 0,!1,void 0,this),K0(S0,{bold:!0,color:"cyan",children:L.name},void 0,!1,void 0,this),h9(L)&&K0(S0,{color:"green",children:" (内置免费)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K0(S0,{children:[K0(S0,{dimColor:!0,children:"Provider: "},void 0,!1,void 0,this),K0(S0,{bold:!0,children:$M(L.provider)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K0(S0,{children:[K0(S0,{dimColor:!0,children:"Model: "},void 0,!1,void 0,this),K0(S0,{bold:!0,children:L.model},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K0(S0,{children:[K0(S0,{dimColor:!0,children:"Base URL: "},void 0,!1,void 0,this),K0(S0,{color:"blueBright",children:L.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L.temperature!==void 0&&K0(S0,{children:[K0(S0,{dimColor:!0,children:"Temperature: "},void 0,!1,void 0,this),K0(S0,{children:L.temperature},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L.maxContextTokens!==void 0&&K0(S0,{children:[K0(S0,{dimColor:!0,children:"Context Window: "},void 0,!1,void 0,this),K0(S0,{children:L.maxContextTokens},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h9(L)&&K0(D1,{marginTop:1,children:K0(S0,{color:"green",dimColor:!0,children:"\uD83D\uDCA1 此模型由 Blade 提供免费额度"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this):K0(S0,{dimColor:!0,children:"请选择一个模型查看详情"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),U&&K0(D1,{marginTop:1,children:K0(S0,{color:"red",children:["❌ ",U]},void 0,!0,void 0,this)},void 0,!1,void 0,this),K0(D1,{justifyContent:"center",marginTop:1,children:K0(S0,{dimColor:!0,children:"─".repeat(F)},void 0,!1,void 0,this)},void 0,!1,void 0,this),K0(D1,{justifyContent:"center",children:K0(S0,{dimColor:!0,children:"提示:D=删除 • E=编辑 • ↑↓=移动 • Enter/ESC=确认"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});import{useMemoizedFn as f6}from"ahooks";import{promises as HF}from"fs";import{Box as M1,Text as q$,useInput as QM}from"ink";import KF from"ink-select-input";import XM from"ink-text-input";import JM from"os";import u5 from"path";import{useEffect as GM,useMemo as d5,useRef as qM,useState as C4}from"react";b0();import{jsxDEV as B0}from"react/jsx-dev-runtime";var h6=[{key:"allow",label:"Allow"},{key:"ask",label:"Ask"},{key:"deny",label:"Deny"},{key:"info",label:"Info"}],KM={allow:"Add a new rule...",ask:"Add a new rule...",deny:"Add a new rule..."},WM={allow:"Allow permission rules",ask:"Ask permission rules",deny:"Deny permission rules"},WF={project:"[项目共享配置]",global:"[用户全局配置]",local:"[本地配置]"},UM=["project","global","local"],HM={allow:[],ask:[],deny:[]},OM={localExists:!1,projectExists:!1,globalExists:!1},UF={allow:[],ask:[],deny:[]};function FM($){let Z=(Q)=>Array.isArray(Q)?Q.filter((X)=>typeof X==="string"):[],Y=$?.permissions??{};return{allow:Z(Y?.allow),ask:Z(Y?.ask),deny:Z(Y?.deny)}}async function _M($){try{let Z=await HF.readFile($,"utf-8"),Y=JSON.parse(Z);return{exists:!0,raw:Y,permissions:FM(Y)}}catch(Z){if(Z.code==="ENOENT")return{exists:!1,raw:{},permissions:{...UF}};return console.warn(`[PermissionsManager] Failed to read ${$}:`,Z),{exists:!0,raw:{},permissions:{...UF}}}}function zM($,Z){let Y=$.padEnd(32," "),Q=Z==="local"?`${WF[Z]} ← 可删除`:WF[Z];return`${Y} ${Q}`}var OF=({onClose:$})=>{let Y=_1()==="permissions-manager",Q=W$(!1),[X,J]=C4(0),G=h6[X].key,[q,K]=C4(HM),[W,U]=C4(OM),[H,O]=C4(!0),[F,_]=C4("list"),[z,N]=C4(""),[B,L]=C4(null),[A,R]=C4(null),V=qM(!1),M=d5(()=>u5.join(process.cwd(),".blade","settings.local.json"),[]),T=d5(()=>u5.join(process.cwd(),".blade","settings.json"),[]),w=d5(()=>u5.join(JM.homedir(),".blade","settings.json"),[]),v=f6(async()=>{O(!0);let r=await Promise.all([{source:"local",path:M},{source:"project",path:T},{source:"global",path:w}].map(async({source:E0,path:g0})=>{let i0=await _M(g0);return{source:E0,path:g0,...i0}})),h={localExists:r.find((E0)=>E0.source==="local")?.exists??!1,projectExists:r.find((E0)=>E0.source==="project")?.exists??!1,globalExists:r.find((E0)=>E0.source==="global")?.exists??!1};U(h);let c={allow:[],ask:[],deny:[]},j0=Object.fromEntries(r.map((E0)=>[E0.source,E0]));["allow","ask","deny"].forEach((E0)=>{UM.forEach((g0)=>{(j0[g0]?.permissions[E0]??[]).forEach((s$,M3)=>{let t2={key:`${g0}:${M3}:${s$}`,rule:s$,source:g0};c[E0].push(t2)})})}),K(c),O(!1)});GM(()=>{v()},[v]);let l=f6(async(C,r)=>{try{let h=u5.join(process.cwd(),".blade","settings.local.json"),c={allow:[],ask:[],deny:[]};try{let E0=await HF.readFile(h,"utf-8"),i0=JSON.parse(E0).permissions||{};c={allow:Array.isArray(i0.allow)?i0.allow:[],ask:Array.isArray(i0.ask)?i0.ask:[],deny:Array.isArray(i0.deny)?i0.deny:[]}}catch(E0){}let j0=r(c);await A0().updateConfig({permissions:j0},{scope:"local",immediate:!0}),await v()}catch(h){throw console.error("[PermissionsManager] 修改权限规则失败:",h),h}});QM((C,r)=>{if(r.ctrl&&C==="c"||r.meta&&C==="c"){Q();return}if(F==="locked"){if(V.current){V.current=!1;return}_("list"),L(null),R(null);return}if(r.escape){if(F==="list"||G==="info")$();else _("list"),N(""),L(null),R(null);return}if(F==="list"){if(r.tab&&r.shift)J((h)=>(h-1+h6.length)%h6.length);else if(r.tab)J((h)=>(h+1)%h6.length);else if(C?.toLowerCase()==="q")$()}},{isActive:Y});let o=f6((C)=>{let r=C.value;if(G==="info")return;if(r.type==="add"){_("add"),N(""),R(null);return}if(r.entry.source!=="local"){_("locked"),V.current=!0,L({tab:G,entry:r.entry}),R({type:"error",text:r.entry.source==="project"?"此规则定义在项目共享配置中,无法在此删除。":"此规则来自用户全局配置,无法在此删除。"});return}_("confirm-delete"),L({tab:G,entry:r.entry}),R(null)}),S=f6(async()=>{if(G==="info")return;let C=z.trim();if(!C){R({type:"error",text:"Permission rule 不能为空"});return}if(q[G].map((h)=>h.rule).includes(C)){R({type:"error",text:"该规则已存在"});return}try{await l(G,(h)=>{let c={allow:[...h.allow],ask:[...h.ask],deny:[...h.deny]};return c[G]=[...new Set([...h[G],C])],c}),_("list"),N(""),R({type:"success",text:"已添加本地权限规则"})}catch(h){R({type:"error",text:`保存失败: ${h instanceof Error?h.message:"未知错误"}`})}}),y=f6(async()=>{if(!B)return;let{tab:C,entry:r}=B;try{await l(C,(h)=>{let c={allow:[...h.allow],ask:[...h.ask],deny:[...h.deny]};return c[C]=h[C].filter((j0)=>j0!==r.rule),c}),_("list"),L(null),R({type:"success",text:"已删除本地权限规则"})}catch(h){R({type:"error",text:`删除失败: ${h instanceof Error?h.message:"未知错误"}`})}}),m=d5(()=>{if(G==="info")return[];let C=G;return[{key:"add-new-rule",label:`› ${KM[C]}`,value:{type:"add"}},...q[C].map((h)=>({key:h.key,label:zM(h.rule,h.source),value:{type:"rule",entry:h}}))]},[G,q]),I=()=>B0(M1,{marginBottom:1,children:h6.map((C,r)=>B0(M1,{marginRight:2,children:B0(q$,{color:r===X?"yellow":"gray",children:["[",C.label,"]"]},void 0,!0,void 0,this)},C.key,!1,void 0,this))},void 0,!1,void 0,this),j=()=>B0(M1,{flexDirection:"column",gap:1,children:[B0(q$,{children:"配置文件优先级(从高到低):"},void 0,!1,void 0,this),B0(M1,{flexDirection:"column",marginLeft:2,children:[B0(q$,{children:["1. .blade/settings.local.json (本地配置,不提交 Git)"," ",W.localExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),B0(q$,{children:["2. .blade/settings.json (项目配置,提交 Git)"," ",W.projectExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),B0(q$,{children:["3. ~/.blade/settings.json (用户全局配置)"," ",W.globalExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),B0(q$,{children:"说明:"},void 0,!1,void 0,this),B0(M1,{flexDirection:"column",marginLeft:2,children:[B0(q$,{children:"- /permissions 命令只管理本地配置 (.blade/settings.local.json)"},void 0,!1,void 0,this),B0(q$,{children:"- 修改全局或项目配置请直接编辑对应文件"},void 0,!1,void 0,this),B0(q$,{children:"- 本地配置不会提交到 Git"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),D=(C)=>B0(M1,{flexDirection:"column",gap:1,children:[B0(q$,{bold:!0,children:WM[C]},void 0,!1,void 0,this),B0(q$,{children:"Permission rules are a tool name, optionally followed by a specifier in parentheses."},void 0,!1,void 0,this),B0(q$,{color:"gray",children:"例如: WebFetch 或 Bash(ls:*)"},void 0,!1,void 0,this),B0(M1,{marginTop:1,children:B0(XM,{value:z,onChange:N,onSubmit:S},void 0,!1,void 0,this)},void 0,!1,void 0,this),B0(q$,{color:"gray",children:"Enter 提交 · Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),i=(C,r)=>B0(M1,{flexDirection:"column",gap:1,children:[B0(q$,{bold:!0,children:["Delete ",C," permission rule?"]},void 0,!0,void 0,this),B0(q$,{children:r.rule},void 0,!1,void 0,this),B0(q$,{color:"gray",children:"From project local settings"},void 0,!1,void 0,this),B0(q$,{children:"Are you sure you want to delete this permission rule?"},void 0,!1,void 0,this),B0(KF,{items:[{label:"Yes",value:"yes"},{label:"No",value:"no"}],onSelect:(h)=>{if(h.value==="yes")y();else _("list"),L(null)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),g=(C)=>B0(M1,{flexDirection:"column",gap:1,children:[B0(q$,{bold:!0,children:"Cannot delete this rule"},void 0,!1,void 0,this),B0(q$,{children:C.rule},void 0,!1,void 0,this),B0(q$,{color:"gray",children:C.source==="project"?"This rule is defined in .blade/settings.json. 请手动编辑该文件以移除规则。":"This rule is defined in ~/.blade/settings.json. 请手动编辑该文件以移除规则。"},void 0,!1,void 0,this),B0(q$,{color:"gray",children:"按任意键继续"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),k=(C)=>B0(KF,{items:m,isFocused:F==="list",onSelect:o},void 0,!1,void 0,this),e=()=>{if(H)return B0(q$,{children:"加载中..."},void 0,!1,void 0,this);if(G==="info")return j();if(F==="add")return D(G);if(F==="confirm-delete"&&B)return i(B.tab,B.entry);if(F==="locked"&&B)return g(B.entry);return k(G)};return B0(M1,{flexDirection:"column",borderStyle:"round",borderColor:Y?"cyan":"gray",padding:1,width:80,children:[B0(q$,{color:"cyan",bold:!0,children:"⚙️ 权限管理器"},void 0,!1,void 0,this),I(),B0(M1,{flexDirection:"column",gap:1,children:e()},void 0,!1,void 0,this),A&&B0(M1,{marginTop:1,children:B0(q$,{color:A.type==="success"?"green":"red",children:A.text},void 0,!1,void 0,this)},void 0,!1,void 0,this),B0(M1,{marginTop:1,children:B0(q$,{color:"gray",children:"Tab 切换视图 · Esc 关闭 · Q 退出"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};e8();import{Box as J$,Text as w0,useInput as BM}from"ink";import{jsxDEV as n}from"react/jsx-dev-runtime";function FF({onCancel:$}){let Z=Y1(),Y=Z.getAll(),Q=Z.getBySource(),X=Z.getStats(),J=W$(!1,$);if(BM((G,q)=>{if(q.escape)$?.();else if(q.ctrl&&G==="c"||q.meta&&G==="c")J()}),Y.length===0)return n(J$,{flexDirection:"column",paddingY:1,children:[n(J$,{marginBottom:1,children:n(w0,{bold:!0,color:"cyan",children:"\uD83D\uDD0C 插件管理器"},void 0,!1,void 0,this)},void 0,!1,void 0,this),n(J$,{paddingLeft:2,children:n(w0,{color:"gray",children:"没有已加载的插件"},void 0,!1,void 0,this)},void 0,!1,void 0,this),n(J$,{marginTop:1,paddingLeft:2,flexDirection:"column",children:[n(w0,{color:"gray",children:"插件目录位置:"},void 0,!1,void 0,this),n(w0,{color:"gray",dimColor:!0,children:[" ","• ~/.blade/plugins/ - 用户级插件"]},void 0,!0,void 0,this),n(w0,{color:"gray",dimColor:!0,children:[" ","• .blade/plugins/ - 项目级插件"]},void 0,!0,void 0,this),n(w0,{color:"gray",dimColor:!0,children:[" ","• --plugin-dir - CLI 指定的插件"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),n(J$,{marginTop:1,paddingLeft:2,children:n(w0,{color:"gray",children:"使用 /plugins install <url> 安装新插件"},void 0,!1,void 0,this)},void 0,!1,void 0,this),n(J$,{marginTop:1,children:n(w0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return n(J$,{flexDirection:"column",paddingY:1,children:[n(J$,{marginBottom:1,children:[n(w0,{bold:!0,color:"cyan",children:"\uD83D\uDD0C 插件管理器"},void 0,!1,void 0,this),n(w0,{color:"gray",children:[" (共 ",X.total," 个插件)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),n(J$,{paddingLeft:2,marginBottom:1,children:n(w0,{color:"gray",children:["启用: ",X.active," | 禁用: ",X.inactive," | 命令: ",X.commands," | 技能:"," ",X.skills," | 代理: ",X.agents]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q.cli.length>0&&n(J$,{flexDirection:"column",marginBottom:1,children:[n(J$,{paddingLeft:1,children:[n(w0,{bold:!0,color:"magenta",children:"CLI 指定"},void 0,!1,void 0,this),n(w0,{color:"gray",children:" (--plugin-dir)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.cli.map((G)=>{let q=G.status==="active"?"✅":"⏸️";return n(J$,{flexDirection:"column",paddingLeft:2,children:[n(w0,{children:[n(w0,{bold:!0,color:"green",children:[q," ",G.manifest.name]},void 0,!0,void 0,this),n(w0,{color:"gray",children:[" v",G.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),n(J$,{paddingLeft:2,children:n(w0,{color:"gray",children:G.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),G.commands.length>0&&n(J$,{paddingLeft:2,children:n(w0,{color:"blue",children:["命令:"," ",G.commands.map((K)=>`/${K.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},G.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.project.length>0&&n(J$,{flexDirection:"column",marginBottom:1,children:[n(J$,{paddingLeft:1,children:[n(w0,{bold:!0,color:"yellow",children:"项目级"},void 0,!1,void 0,this),n(w0,{color:"gray",children:" (.blade/plugins/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.project.map((G)=>{let q=G.status==="active"?"✅":"⏸️";return n(J$,{flexDirection:"column",paddingLeft:2,children:[n(w0,{children:[n(w0,{bold:!0,color:"green",children:[q," ",G.manifest.name]},void 0,!0,void 0,this),n(w0,{color:"gray",children:[" v",G.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),n(J$,{paddingLeft:2,children:n(w0,{color:"gray",children:G.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),G.commands.length>0&&n(J$,{paddingLeft:2,children:n(w0,{color:"blue",children:["命令:"," ",G.commands.map((K)=>`/${K.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},G.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.user.length>0&&n(J$,{flexDirection:"column",marginBottom:1,children:[n(J$,{paddingLeft:1,children:[n(w0,{bold:!0,color:"cyan",children:"用户级"},void 0,!1,void 0,this),n(w0,{color:"gray",children:" (~/.blade/plugins/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.user.map((G)=>{let q=G.status==="active"?"✅":"⏸️";return n(J$,{flexDirection:"column",paddingLeft:2,children:[n(w0,{children:[n(w0,{bold:!0,color:"green",children:[q," ",G.manifest.name]},void 0,!0,void 0,this),n(w0,{color:"gray",children:[" v",G.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),n(J$,{paddingLeft:2,children:n(w0,{color:"gray",children:G.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),G.commands.length>0&&n(J$,{paddingLeft:2,children:n(w0,{color:"blue",children:["命令:"," ",G.commands.map((K)=>`/${K.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},G.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),n(J$,{marginTop:1,paddingLeft:2,flexDirection:"column",children:[n(w0,{color:"gray",children:"可用命令:"},void 0,!1,void 0,this),n(w0,{color:"gray",dimColor:!0,children:[" ","• /plugins list - 列出所有插件"]},void 0,!0,void 0,this),n(w0,{color:"gray",dimColor:!0,children:[" ","• /plugins info <name> - 显示插件详情"]},void 0,!0,void 0,this),n(w0,{color:"gray",dimColor:!0,children:[" ","• /plugins install <url> - 安装插件"]},void 0,!0,void 0,this),n(w0,{color:"gray",dimColor:!0,children:[" ","• /plugins enable/disable <name> - 启用/禁用插件"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),n(J$,{marginTop:1,children:n(w0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}import{Box as a$,Text as n$,useInput as _F,useStdout as NM}from"ink";import LM from"ink-text-input";import nQ,{useCallback as x6,useMemo as wM,useState as k4}from"react";import{jsxDEV as M0}from"react/jsx-dev-runtime";var AM=nQ.memo(({option:$,index:Z,isSelected:Y,isMultiSelect:Q,isHighlighted:X})=>M0(a$,{flexDirection:"column",marginBottom:1,children:[M0(n$,{color:X?"yellow":Y?"green":void 0,bold:X,children:[Q?Y?"● ":"○ ":X?"❯ ":" ",Z+1,". ",$.label]},void 0,!0,void 0,this),M0(a$,{marginLeft:4,children:M0(n$,{color:"gray",children:$.description},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)),bM=nQ.memo(({questions:$,answers:Z})=>M0(a$,{flexDirection:"column",marginBottom:1,children:$.map((Y)=>{let Q=Z[Y.header],X=Array.isArray(Q)?Q.join(", "):Q||"(no answer)";return M0(a$,{marginBottom:1,children:[M0(n$,{backgroundColor:"blue",color:"white",children:[" ",Y.header," "]},void 0,!0,void 0,this),M0(n$,{color:"green",children:[" ",X]},void 0,!0,void 0,this)]},Y.header,!0,void 0,this)})},void 0,!1,void 0,this)),zF=nQ.memo(({questions:$,onComplete:Z,onCancel:Y})=>{let{stdout:Q}=NM(),X=Q.columns||80,G=_1()==="confirmation-prompt",q=W$(!1),[K,W]=k4("answering"),[U,H]=k4(0),[O,F]=k4({}),[_,z]=k4(0),[N,B]=k4([]),[L,A]=k4(!1),[R,V]=k4(""),[M,T]=k4(0),w=$[U],v=wM(()=>{if(!w)return[];return[...w.options.map((I)=>({label:I.label,value:I.label,description:I.description})),{label:"Type something...",value:"__other__",description:"Enter custom response"}]},[w]),l=x6((I)=>{let j={...O,[w.header]:I};if(F(j),U<$.length-1)H(U+1),z(0),B([]),A(!1),V("");else W("submit"),T(0)},[O,w?.header,U,$.length]),o=x6((I)=>{let j=v[I];if(!j)return;if(j.value==="__other__"){A(!0);return}if(w.multiSelect)B((D)=>D.includes(j.value)?D.filter((i)=>i!==j.value):[...D,j.value]);else l(j.value)},[v,w?.multiSelect,l]),S=x6((I)=>{if(I.trim())l(I.trim())},[l]),y=x6(()=>{W("answering"),H(0),z(0),B([]),A(!1)},[]),m=x6(()=>{Z(O)},[O,Z]);if(_F((I,j)=>{if(j.ctrl&&I==="c"||j.meta&&I==="c"){q();return}if(L){if(j.escape)A(!1),V("");return}if(j.escape){Y();return}let D=parseInt(I);if(D>=1&&D<=v.length){o(D-1);return}if(j.upArrow){z((i)=>i>0?i-1:v.length-1);return}if(j.downArrow||j.tab){z((i)=>i<v.length-1?i+1:0);return}if(j.return){if(w.multiSelect&&N.length>0)l(N);else o(_);return}if(I===" "&&w.multiSelect){let i=v[_];if(i&&i.value!=="__other__")B((g)=>g.includes(i.value)?g.filter((k)=>k!==i.value):[...g,i.value]);return}},{isActive:G&&K==="answering"&&!L}),_F((I,j)=>{if(j.ctrl&&I==="c"||j.meta&&I==="c"){q();return}if(j.escape){Y();return}if(j.upArrow||j.downArrow||j.tab){T((D)=>D===0?1:0);return}if(j.return){if(M===0)m();else y();return}if(I.toLowerCase()==="y"){m();return}if(I.toLowerCase()==="e"){y();return}},{isActive:G&&K==="submit"}),K==="submit")return M0(a$,{flexDirection:"column",borderStyle:"round",borderColor:G?"green":"gray",padding:1,width:Math.min(X-4,80),children:[M0(a$,{marginBottom:1,children:M0(n$,{bold:!0,color:"green",children:"✓ Review Your Answers"},void 0,!1,void 0,this)},void 0,!1,void 0,this),M0(bM,{questions:$,answers:O},void 0,!1,void 0,this),M0(a$,{flexDirection:"column",marginTop:1,children:[M0(n$,{color:M===0?"yellow":void 0,bold:M===0,children:[M===0?"❯ ":" ","[Y] Submit answers"]},void 0,!0,void 0,this),M0(n$,{color:M===1?"yellow":void 0,bold:M===1,children:[M===1?"❯ ":" ","[E] Edit answers"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),M0(a$,{marginTop:1,children:M0(n$,{color:"gray",children:"Enter to confirm · ↑↓ to navigate · Y/E for quick select"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(!w)return null;return M0(a$,{flexDirection:"column",borderStyle:"round",borderColor:G?"cyan":"gray",padding:1,width:Math.min(X-4,80),children:[M0(a$,{marginBottom:1,children:[M0(n$,{backgroundColor:"blue",color:"white",children:[" ",w.header," "]},void 0,!0,void 0,this),M0(n$,{children:[" ",w.question]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),L?M0(a$,{flexDirection:"column",marginTop:1,children:[M0(n$,{color:"yellow",children:"Enter your response:"},void 0,!1,void 0,this),M0(a$,{marginTop:1,children:[M0(n$,{color:"cyan",children:"❯ "},void 0,!1,void 0,this),M0(LM,{value:R,onChange:V,onSubmit:S,focus:G},void 0,!1,void 0,this)]},void 0,!0,void 0,this),M0(a$,{marginTop:1,children:M0(n$,{color:"gray",children:"(Press Enter to submit, ESC to go back)"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this):M0(a$,{flexDirection:"column",children:v.map((I,j)=>M0(AM,{option:I,index:j,isSelected:N.includes(I.value),isMultiSelect:w.multiSelect,isHighlighted:_===j},I.value,!1,void 0,this))},void 0,!1,void 0,this),!L&&M0(a$,{marginTop:1,flexDirection:"column",children:[M0(n$,{color:"gray",children:w.multiSelect?"Space to toggle · Enter to confirm · 1-9 for quick select":"Enter to select · ↑↓ or Tab to navigate · 1-9 for quick select"},void 0,!1,void 0,this),w.multiSelect&&N.length>0&&M0(n$,{color:"green",children:["Selected: ",N.join(", ")]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$.length>1&&M0(a$,{marginTop:1,children:M0(n$,{color:"gray",children:["Question ",U+1," of ",$.length]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});B6();import{Box as R3,Text as H2,useInput as VM}from"ink";import RM from"ink-select-input";import{basename as DM}from"node:path";import{useEffect as BF,useMemo as c5,useState as oQ}from"react";import{jsxDEV as C$}from"react/jsx-dev-runtime";function MM($){let Z=new Date($),Q=new Date().getTime()-Z.getTime(),X=Math.floor(Q/86400000);if(X===0)return`今天 ${Z.getHours().toString().padStart(2,"0")}:${Z.getMinutes().toString().padStart(2,"0")}`;if(X===1)return"昨天";if(X<7)return`${X}天前`;return`${Z.getMonth()+1}/${Z.getDate()}`}function jM($){return DM($)}var TM=({isSelected:$})=>C$(R3,{marginRight:1,children:C$(H2,{color:$?"cyan":"gray",children:$?"❯":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),yM=({isSelected:$,label:Z})=>C$(H2,{color:$?"cyan":"white",bold:$,children:Z},void 0,!1,void 0,this),p6=20,NF=({sessions:$,onSelect:Z,onCancel:Y})=>{let[Q,X]=oQ([]),[J,G]=oQ(!1),[q,K]=oQ(0),U=_1()==="session-selector",H=W$(!1);VM((L,A)=>{if(A.ctrl&&L==="c"||A.meta&&L==="c"){H();return}if(A.escape&&Y){Y();return}if(A.leftArrow||L==="h"||L==="H"){if(q>0)K((R)=>R-1);return}if(A.rightArrow||L==="l"||L==="L"){if(q<_-1)K((R)=>R+1);return}},{isActive:U}),BF(()=>{if($){X($);return}(async()=>{G(!0);try{let A=await P$.listSessions();X(A)}catch(A){console.error("[SessionSelector] Failed to load sessions:",A),X([])}finally{G(!1)}})()},[$]);let O=$||Q,F=c5(()=>{return O.map((L)=>{let A=jM(L.projectPath),R=MM(L.lastMessageTime),V=L.gitBranch?` (${L.gitBranch})`:"",M=L.hasErrors?" ⚠️":"",T=L.relationType==="subagent"?" ↳ subagent":"";return{label:`\uD83D\uDCC5 ${R} | ${A}${V} | ${L.messageCount} 条消息${M}${T}`,value:L.sessionId}})},[O]),_=c5(()=>Math.max(1,Math.ceil(F.length/p6)),[F.length]),z=c5(()=>{let L=q*p6;return F.slice(L,L+p6)},[F,q]),N=c5(()=>({start:q*p6+1,end:Math.min((q+1)*p6,F.length)}),[q,F.length]);BF(()=>{K(0)},[O.length]);let B=(L)=>{Z(L.value)};if(J)return C$(R3,{flexDirection:"column",paddingX:2,paddingY:1,children:C$(H2,{children:"⏳ 正在加载会话列表..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(O.length===0)return C$(R3,{flexDirection:"column",paddingX:2,paddingY:1,children:[C$(H2,{color:"yellow",children:"⚠️ 没有找到历史会话"},void 0,!1,void 0,this),C$(H2,{dimColor:!0,children:[`
|
|
2922
2922
|
`,"提示: 开始一次对话后,会话历史将保存到 ~/.blade/projects/"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this);return C$(R3,{flexDirection:"column",paddingX:2,paddingY:1,children:[C$(H2,{bold:!0,color:"cyan",children:"\uD83D\uDCC2 选择要恢复的会话:"},void 0,!1,void 0,this),C$(H2,{dimColor:!0,children:[`
|
|
2923
2923
|
`,"(←→ 翻页 | ↑↓ 选择 | Enter 确认 | Esc 取消)",`
|
|
2924
|
-
`]},void 0,!0,void 0,this),C$(RM,{items:z,onSelect:B,indicatorComponent:TM,itemComponent:yM},void 0,!1,void 0,this),C$(R3,{marginTop:1,flexDirection:"column",children:[C$(H2,{dimColor:!0,children:["第 ",q+1,"/",_," 页 · 共 ",O.length," 个会话 · 显示"," ",N.start,"-",N.end]},void 0,!0,void 0,this),_>1&&C$(R3,{marginTop:1,children:[C$(H2,{color:q>0?"cyan":"gray",children:q>0?"◀ ← 上一页":" "},void 0,!1,void 0,this),C$(H2,{children:" "},void 0,!1,void 0,this),C$(H2,{color:q<_-1?"cyan":"gray",children:q<_-1?"下一页 → ▶":""},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};t1();import{Box as _$,Text as $$,useInput as EM}from"ink";import{jsxDEV as Q0}from"react/jsx-dev-runtime";function LF({onCancel:$}){let Y=O$().getAll(),Q=Y.filter((q)=>q.source==="builtin"),X=Y.filter((q)=>q.source==="user"),J=Y.filter((q)=>q.source==="project"),G=W$(!1,$);if(EM((q,K)=>{if(K.escape)$?.();else if(K.ctrl&&q==="c"||K.meta&&q==="c")G()}),Y.length===0)return Q0(_$,{flexDirection:"column",paddingY:1,children:[Q0(_$,{marginBottom:1,children:Q0($$,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q0(_$,{paddingLeft:2,children:Q0($$,{color:"gray",children:"没有找到任何 Skill"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q0(_$,{marginTop:1,paddingLeft:2,children:Q0($$,{color:"gray",children:"配置文件位置: ~/.blade/skills/ 或 .blade/skills/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q0(_$,{marginTop:1,children:Q0($$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return Q0(_$,{flexDirection:"column",paddingY:1,children:[Q0(_$,{marginBottom:1,children:[Q0($$,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this),Q0($$,{color:"gray",children:[" (找到 ",Y.length," 个)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),J.length>0&&Q0(_$,{flexDirection:"column",marginBottom:1,children:[Q0(_$,{paddingLeft:1,children:[Q0($$,{bold:!0,color:"yellow",children:"项目级"},void 0,!1,void 0,this),Q0($$,{color:"gray",children:" (.blade/skills/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J.map((q)=>{let W=q.description.length>80?`${q.description.substring(0,80)}...`:q.description;return Q0(_$,{flexDirection:"column",paddingLeft:2,children:[Q0($$,{children:[Q0($$,{bold:!0,color:"green",children:["• ",q.name]},void 0,!0,void 0,this),Q0($$,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.allowedTools&&q.allowedTools.length>0&&Q0(_$,{paddingLeft:2,children:Q0($$,{color:"gray",children:["工具: ",q.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q0(_$,{paddingLeft:2,children:Q0($$,{color:"gray",dimColor:!0,children:q.path},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},q.name,!0,void 0,this)})]},void 0,!0,void 0,this),X.length>0&&Q0(_$,{flexDirection:"column",marginBottom:1,children:[Q0(_$,{paddingLeft:1,children:[Q0($$,{bold:!0,color:"yellow",children:"用户级"},void 0,!1,void 0,this),Q0($$,{color:"gray",children:" (~/.blade/skills/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X.map((q)=>{let W=q.description.length>80?`${q.description.substring(0,80)}...`:q.description;return Q0(_$,{flexDirection:"column",paddingLeft:2,children:[Q0($$,{children:[Q0($$,{bold:!0,color:"green",children:["• ",q.name]},void 0,!0,void 0,this),Q0($$,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.allowedTools&&q.allowedTools.length>0&&Q0(_$,{paddingLeft:2,children:Q0($$,{color:"gray",children:["工具: ",q.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q0(_$,{paddingLeft:2,children:Q0($$,{color:"gray",dimColor:!0,children:q.path},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},q.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.length>0&&Q0(_$,{flexDirection:"column",marginBottom:1,children:[Q0(_$,{paddingLeft:1,children:[Q0($$,{bold:!0,color:"cyan",children:"内置"},void 0,!1,void 0,this),Q0($$,{color:"gray",children:" (builtin)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.map((q)=>{let W=q.description.length>80?`${q.description.substring(0,80)}...`:q.description;return Q0(_$,{flexDirection:"column",paddingLeft:2,children:[Q0($$,{children:[Q0($$,{bold:!0,color:"green",children:["• ",q.name]},void 0,!0,void 0,this),Q0($$,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.userInvocable&&Q0(_$,{paddingLeft:2,children:Q0($$,{color:"blue",children:["命令: /",q.name]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},q.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q0(_$,{marginTop:1,children:Q0($$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}I1();l1();import{Box as S4,Text as j1}from"ink";import wF,{useEffect as IM,useState as PM}from"react";import{jsxDEV as z$}from"react/jsx-dev-runtime";var vM={init:"\uD83D\uDCDD",requirements:"\uD83D\uDCCB",design:"\uD83C\uDFA8",tasks:"\uD83D\uDCCC",implementation:"\uD83D\uDD27",done:"✅"},l9=["init","requirements","design","tasks","implementation","done"],CM={pending:"○",in_progress:"◐",completed:"●",blocked:"✕"},kM={pending:"gray",in_progress:"yellow",completed:"green",blocked:"red"},AF=wF.memo(({expanded:$=!1,maxTasks:Z=5})=>{let[Y,Q]=PM(null);if(IM(()=>{let G=c0.getInstance();Q(G.getCurrentSpec());let q=setInterval(()=>{Q(G.getCurrentSpec())},1000);return()=>clearInterval(q)},[]),!Y)return null;let X=l9.indexOf(Y.phase),J=Y.tasks.length>0?Math.round(Y.tasks.filter((G)=>G.status==="completed").length/Y.tasks.length*100):0;return z$(S4,{flexDirection:"column",borderStyle:"round",borderColor:"blue",paddingX:1,marginBottom:1,children:[z$(S4,{flexDirection:"row",justifyContent:"space-between",children:[z$(j1,{color:"blue",bold:!0,children:["\uD83D\uDCCB Spec: ",Y.name]},void 0,!0,void 0,this),z$(j1,{color:"gray",children:[vM[Y.phase]," ",h$[Y.phase]]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),z$(S4,{flexDirection:"row",marginTop:1,children:[l9.map((G,q)=>{let K=q<X,W=q===X;return z$(S4,{flexDirection:"row",children:[z$(j1,{color:K?"green":W?"blue":"gray",children:K?"●":W?"◉":"○"},void 0,!1,void 0,this),q<l9.length-1&&z$(j1,{color:K?"green":"gray",children:"──"},void 0,!1,void 0,this)]},G,!0,void 0,this)}),z$(j1,{color:"gray",children:[" (",J,"%)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),z$(S4,{flexDirection:"row",marginTop:0,children:z$(j1,{color:"gray",dimColor:!0,children:l9.map((G,q)=>{let K=G.slice(0,3).toUpperCase();return q===X?`[${K}]`:` ${K} `}).join("")},void 0,!1,void 0,this)},void 0,!1,void 0,this),$&&Y.tasks.length>0&&z$(S4,{flexDirection:"column",marginTop:1,children:[z$(j1,{color:"gray",dimColor:!0,children:["─── Tasks (",Y.tasks.filter((G)=>G.status==="completed").length,"/",Y.tasks.length,") ───"]},void 0,!0,void 0,this),Y.tasks.slice(0,Z).map((G)=>z$(SM,{task:G,isCurrent:G.id===Y.currentTaskId},G.id,!1,void 0,this)),Y.tasks.length>Z&&z$(j1,{color:"gray",dimColor:!0,children:["... and ",Y.tasks.length-Z," more tasks"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),!$&&Y.currentTaskId&&z$(S4,{flexDirection:"row",marginTop:1,children:[z$(j1,{color:"gray",children:"Current: "},void 0,!1,void 0,this),z$(j1,{color:"yellow",children:Y.tasks.find((G)=>G.id===Y.currentTaskId)?.title||"Unknown"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}),SM=wF.memo(({task:$,isCurrent:Z})=>{let Y=CM[$.status]||"?",Q=kM[$.status]||"gray";return z$(S4,{flexDirection:"row",children:[z$(j1,{color:Q,children:[Y," "]},void 0,!0,void 0,this),z$(j1,{color:Z?"yellow":"white",bold:Z,children:$.title},void 0,!1,void 0,this),$.complexity&&z$(j1,{color:"gray",dimColor:!0,children:[" ","[",$.complexity,"]"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});import{Box as fM,Text as n2}from"ink";import hM,{useEffect as xM,useState as bF}from"react";import{jsxDEV as u1,Fragment as RF}from"react/jsx-dev-runtime";var VF=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];function pM($){let Z=Math.floor($/1000);if(Z<60)return`${Z}s`;let Y=Math.floor(Z/60),Q=Z%60;return`${Y}m ${Q}s`}var DF=hM.memo(()=>{let $=z0((K)=>K.app.subagentProgress),Z=o0(),[Y,Q]=bF(0),[X,J]=bF(0);if(xM(()=>{if(!$||$.status!=="running"){Q(0),J(0);return}let K=setInterval(()=>{Q((U)=>(U+1)%VF.length)},80),W=setInterval(()=>{J(Date.now()-$.startTime)},1000);return()=>{clearInterval(K),clearInterval(W)}},[$]),!$)return null;let G=$.status==="running"?VF[Y]:$.status==="completed"?"✓":"✗",q=$.status==="running"?Z.colors.info:$.status==="completed"?Z.colors.success:Z.colors.error;return u1(fM,{paddingX:2,paddingY:0,flexDirection:"row",gap:1,children:[u1(n2,{color:q,bold:!0,children:G},void 0,!1,void 0,this),u1(n2,{color:Z.colors.muted,children:"Subagent"},void 0,!1,void 0,this),u1(n2,{color:Z.colors.text.primary,bold:!0,children:$.type},void 0,!1,void 0,this),u1(n2,{color:Z.colors.muted,children:"|"},void 0,!1,void 0,this),u1(n2,{color:Z.colors.text.secondary,children:$.description},void 0,!1,void 0,this),$.currentTool&&u1(RF,{children:[u1(n2,{color:Z.colors.muted,children:"|"},void 0,!1,void 0,this),u1(n2,{color:Z.colors.warning,children:$.currentTool},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$.status==="running"&&X>0&&u1(RF,{children:[u1(n2,{color:Z.colors.muted,children:"|"},void 0,!1,void 0,this),u1(n2,{color:Z.colors.info,children:pM(X)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});I2();import{useMemoizedFn as mM}from"ahooks";import{Box as j2,Text as a,useInput as gM}from"ink";import uM from"ink-select-input";import{useState as MF}from"react";b0();J5();I2();import{jsxDEV as d}from"react/jsx-dev-runtime";var jF=E2.map(($)=>({label:$.label,value:$.id})),dM=({theme:$})=>{let{colors:Z}=$;return d(j2,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[d(a,{bold:!0,color:Z.text.primary,children:"代码预览"},void 0,!1,void 0,this),d(a,{children:" "},void 0,!1,void 0,this),d(a,{color:Z.syntax.comment,children:"# function"},void 0,!1,void 0,this),d(a,{children:[d(a,{color:Z.syntax.keyword,children:"def"},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.function,children:"fibonacci"},void 0,!1,void 0,this),d(a,{color:Z.text.primary,children:"("},void 0,!1,void 0,this),d(a,{color:Z.syntax.variable,children:"n"},void 0,!1,void 0,this),d(a,{color:Z.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),d(a,{children:[" ",d(a,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this),d(a,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.operator,children:"="},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.number,children:"0"},void 0,!1,void 0,this),d(a,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.number,children:"1"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),d(a,{children:[" ",d(a,{color:Z.syntax.keyword,children:"for"},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.variable,children:"_"},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.keyword,children:"in"},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.function,children:"range"},void 0,!1,void 0,this),d(a,{color:Z.text.primary,children:"("},void 0,!1,void 0,this),d(a,{color:Z.syntax.variable,children:"n"},void 0,!1,void 0,this),d(a,{color:Z.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),d(a,{children:[" ",d(a,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this),d(a,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.operator,children:"="},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this),d(a,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.operator,children:"+"},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),d(a,{children:[" ",d(a,{color:Z.syntax.keyword,children:"return"},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),d(a,{children:" "},void 0,!1,void 0,this),d(a,{color:Z.error,children:["- print(",d(a,{color:Z.syntax.string,children:'"Hello, "'},void 0,!1,void 0,this)," + name)"]},void 0,!0,void 0,this),d(a,{color:Z.success,children:["+ print(",d(a,{color:Z.syntax.string,children:['f"Hello, ',"{","name","}",'"']},void 0,!0,void 0,this),")"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},cM=({theme:$})=>{let{colors:Z}=$;return d(j2,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[d(a,{children:" "},void 0,!1,void 0,this),d(a,{bold:!0,color:Z.text.primary,children:"颜色配置"},void 0,!1,void 0,this),d(a,{children:" "},void 0,!1,void 0,this),d(a,{children:[d(a,{color:Z.text.muted,children:"Primary: "},void 0,!1,void 0,this),d(a,{color:Z.primary,children:Z.primary},void 0,!1,void 0,this)]},void 0,!0,void 0,this),d(a,{children:[d(a,{color:Z.text.muted,children:"Success: "},void 0,!1,void 0,this),d(a,{color:Z.success,children:Z.success},void 0,!1,void 0,this)]},void 0,!0,void 0,this),d(a,{children:[d(a,{color:Z.text.muted,children:"Error: "},void 0,!1,void 0,this),d(a,{color:Z.error,children:Z.error},void 0,!1,void 0,this)]},void 0,!0,void 0,this),d(a,{children:[d(a,{color:Z.text.muted,children:"Warning: "},void 0,!1,void 0,this),d(a,{color:Z.warning,children:Z.warning},void 0,!1,void 0,this)]},void 0,!0,void 0,this),d(a,{children:[d(a,{color:Z.text.muted,children:"Info: "},void 0,!1,void 0,this),d(a,{color:Z.info,children:Z.info},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},TF=()=>{let $=M4(),Z=E$.getCurrentThemeName(),Y=E2.findIndex((_)=>_.label===Z),Q=Y>=0?E2[Y].theme:E2[0].theme,[X,J]=MF(Q),[G,q]=MF(!1),K=mM(async(_)=>{if(G)return;q(!0);try{await A0().setTheme(_.value),$.closeModal()}catch(z){console.error("❌ 主题切换失败:",z instanceof Error?z.message:z)}finally{q(!1)}}),W=(_)=>{let z=E2.find((N)=>N.id===_.value);if(z)J(z.theme)},H=_1()==="theme-selector",O=W$(!1);gM((_,z)=>{if(z.ctrl&&_==="c"||z.meta&&_==="c"){O();return}if(z.escape&&!G)$.closeModal()},{isActive:H});let F=(_)=>{let{isSelected:z,label:N}=_,L=N===Z?"✓":" ";return d(a,{color:z?X.colors.primary:X.colors.text.primary,children:[L," ",N]},void 0,!0,void 0,this)};return d(j2,{flexDirection:"column",height:"100%",children:[d(j2,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:X.colors.border.light,children:d(a,{bold:!0,color:X.colors.primary,children:"\uD83C\uDFA8 主题选择器"},void 0,!1,void 0,this)},void 0,!1,void 0,this),d(j2,{flexDirection:"row",flexGrow:1,children:[d(j2,{width:"40%",borderStyle:"single",borderColor:X.colors.border.light,paddingX:1,children:d(j2,{flexDirection:"column",children:[d(j2,{paddingTop:1,paddingBottom:1,children:d(a,{bold:!0,color:X.colors.text.primary,children:["可用主题 (",jF.length,")"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),d(uM,{items:jF,initialIndex:Y>=0?Y:0,onSelect:K,onHighlight:W,itemComponent:F},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),d(j2,{width:"60%",flexDirection:"column",borderStyle:"single",borderColor:X.colors.border.light,children:[d(dM,{theme:X},void 0,!1,void 0,this),d(cM,{theme:X},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),d(j2,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:X.colors.border.light,children:d(a,{color:X.colors.text.muted,children:G?"正在保存...":"Enter: 选择主题 | Esc: 取消"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as l0}from"react/jsx-dev-runtime";var J1=p("UI"),yF=({debug:$,continue:Z,...Y})=>{if($)J1.debug("[Debug] BladeInterface props:",{permissionMode:Y.permissionMode,yolo:Y.yolo,maxTurns:Y.maxTurns,continue:Z});let Q=i9(!1),X=i9(!1),J=i9(!1),G=i9(null),q=tU(),K=eU(),W=N9(),U=YH(),H=ZH(),O=M4(),F=D4(),_=KH(),z=O3(),N=j4(),B=qH();h4(()=>{if(E$.getCurrentThemeName()!==B)try{E$.setTheme(B)}catch{}},[B]);let{exit:L}=lM(),A=q==="ready",R=q==="needsSetup",V=q==="idle",{confirmationState:M,confirmationHandler:T,handleResponse:w}=yH(),{executeCommand:v,handleAbort:l}=DH(Y.systemPrompt,Y.appendSystemPrompt,T,Y.maxTurns),{getPreviousCommand:o,getNextCommand:S,addToHistory:y}=jH();mH();let m=IH("",0),I=X1(async()=>{let Z0=z,P0;if(Z0==="default")P0="autoEdit";else if(Z0==="autoEdit")P0="plan";else if(Z0==="plan")P0="spec";else if(Z0==="spec")P0="default";else P0="default";try{if(await A0().setPermissionMode(P0),P0==="spec")try{let b$=c0.getInstance();await b$.initialize(process.cwd());let V$=await b$.listSpecs();if(V$.length>0){let S$=V$[0];await b$.loadSpec(S$.name),F.addAssistantMessage(`\uD83D\uDCCB **已进入 Spec 模式**
|
|
2924
|
+
`]},void 0,!0,void 0,this),C$(RM,{items:z,onSelect:B,indicatorComponent:TM,itemComponent:yM},void 0,!1,void 0,this),C$(R3,{marginTop:1,flexDirection:"column",children:[C$(H2,{dimColor:!0,children:["第 ",q+1,"/",_," 页 · 共 ",O.length," 个会话 · 显示"," ",N.start,"-",N.end]},void 0,!0,void 0,this),_>1&&C$(R3,{marginTop:1,children:[C$(H2,{color:q>0?"cyan":"gray",children:q>0?"◀ ← 上一页":" "},void 0,!1,void 0,this),C$(H2,{children:" "},void 0,!1,void 0,this),C$(H2,{color:q<_-1?"cyan":"gray",children:q<_-1?"下一页 → ▶":""},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};t1();import{Box as _$,Text as $$,useInput as EM}from"ink";import{jsxDEV as Q0}from"react/jsx-dev-runtime";function LF({onCancel:$}){let Y=O$().getAll(),Q=Y.filter((q)=>q.source==="builtin"),X=Y.filter((q)=>q.source==="user"),J=Y.filter((q)=>q.source==="project"),G=W$(!1,$);if(EM((q,K)=>{if(K.escape)$?.();else if(K.ctrl&&q==="c"||K.meta&&q==="c")G()}),Y.length===0)return Q0(_$,{flexDirection:"column",paddingY:1,children:[Q0(_$,{marginBottom:1,children:Q0($$,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q0(_$,{paddingLeft:2,children:Q0($$,{color:"gray",children:"没有找到任何 Skill"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q0(_$,{marginTop:1,paddingLeft:2,children:Q0($$,{color:"gray",children:"配置文件位置: ~/.blade/skills/ 或 .blade/skills/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q0(_$,{marginTop:1,children:Q0($$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return Q0(_$,{flexDirection:"column",paddingY:1,children:[Q0(_$,{marginBottom:1,children:[Q0($$,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this),Q0($$,{color:"gray",children:[" (找到 ",Y.length," 个)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),J.length>0&&Q0(_$,{flexDirection:"column",marginBottom:1,children:[Q0(_$,{paddingLeft:1,children:[Q0($$,{bold:!0,color:"yellow",children:"项目级"},void 0,!1,void 0,this),Q0($$,{color:"gray",children:" (.blade/skills/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J.map((q)=>{let W=q.description.length>80?`${q.description.substring(0,80)}...`:q.description;return Q0(_$,{flexDirection:"column",paddingLeft:2,children:[Q0($$,{children:[Q0($$,{bold:!0,color:"green",children:["• ",q.name]},void 0,!0,void 0,this),Q0($$,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.allowedTools&&q.allowedTools.length>0&&Q0(_$,{paddingLeft:2,children:Q0($$,{color:"gray",children:["工具: ",q.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q0(_$,{paddingLeft:2,children:Q0($$,{color:"gray",dimColor:!0,children:q.path},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},q.name,!0,void 0,this)})]},void 0,!0,void 0,this),X.length>0&&Q0(_$,{flexDirection:"column",marginBottom:1,children:[Q0(_$,{paddingLeft:1,children:[Q0($$,{bold:!0,color:"yellow",children:"用户级"},void 0,!1,void 0,this),Q0($$,{color:"gray",children:" (~/.blade/skills/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X.map((q)=>{let W=q.description.length>80?`${q.description.substring(0,80)}...`:q.description;return Q0(_$,{flexDirection:"column",paddingLeft:2,children:[Q0($$,{children:[Q0($$,{bold:!0,color:"green",children:["• ",q.name]},void 0,!0,void 0,this),Q0($$,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.allowedTools&&q.allowedTools.length>0&&Q0(_$,{paddingLeft:2,children:Q0($$,{color:"gray",children:["工具: ",q.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q0(_$,{paddingLeft:2,children:Q0($$,{color:"gray",dimColor:!0,children:q.path},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},q.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.length>0&&Q0(_$,{flexDirection:"column",marginBottom:1,children:[Q0(_$,{paddingLeft:1,children:[Q0($$,{bold:!0,color:"cyan",children:"内置"},void 0,!1,void 0,this),Q0($$,{color:"gray",children:" (builtin)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.map((q)=>{let W=q.description.length>80?`${q.description.substring(0,80)}...`:q.description;return Q0(_$,{flexDirection:"column",paddingLeft:2,children:[Q0($$,{children:[Q0($$,{bold:!0,color:"green",children:["• ",q.name]},void 0,!0,void 0,this),Q0($$,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.userInvocable&&Q0(_$,{paddingLeft:2,children:Q0($$,{color:"blue",children:["命令: /",q.name]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},q.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q0(_$,{marginTop:1,children:Q0($$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}I1();l1();import{Box as S4,Text as j1}from"ink";import wF,{useEffect as IM,useState as PM}from"react";import{jsxDEV as z$}from"react/jsx-dev-runtime";var vM={init:"\uD83D\uDCDD",requirements:"\uD83D\uDCCB",design:"\uD83C\uDFA8",tasks:"\uD83D\uDCCC",implementation:"\uD83D\uDD27",done:"✅"},l5=["init","requirements","design","tasks","implementation","done"],CM={pending:"○",in_progress:"◐",completed:"●",blocked:"✕"},kM={pending:"gray",in_progress:"yellow",completed:"green",blocked:"red"},AF=wF.memo(({expanded:$=!1,maxTasks:Z=5})=>{let[Y,Q]=PM(null);if(IM(()=>{let G=c0.getInstance();Q(G.getCurrentSpec());let q=setInterval(()=>{Q(G.getCurrentSpec())},1000);return()=>clearInterval(q)},[]),!Y)return null;let X=l5.indexOf(Y.phase),J=Y.tasks.length>0?Math.round(Y.tasks.filter((G)=>G.status==="completed").length/Y.tasks.length*100):0;return z$(S4,{flexDirection:"column",borderStyle:"round",borderColor:"blue",paddingX:1,marginBottom:1,children:[z$(S4,{flexDirection:"row",justifyContent:"space-between",children:[z$(j1,{color:"blue",bold:!0,children:["\uD83D\uDCCB Spec: ",Y.name]},void 0,!0,void 0,this),z$(j1,{color:"gray",children:[vM[Y.phase]," ",h$[Y.phase]]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),z$(S4,{flexDirection:"row",marginTop:1,children:[l5.map((G,q)=>{let K=q<X,W=q===X;return z$(S4,{flexDirection:"row",children:[z$(j1,{color:K?"green":W?"blue":"gray",children:K?"●":W?"◉":"○"},void 0,!1,void 0,this),q<l5.length-1&&z$(j1,{color:K?"green":"gray",children:"──"},void 0,!1,void 0,this)]},G,!0,void 0,this)}),z$(j1,{color:"gray",children:[" (",J,"%)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),z$(S4,{flexDirection:"row",marginTop:0,children:z$(j1,{color:"gray",dimColor:!0,children:l5.map((G,q)=>{let K=G.slice(0,3).toUpperCase();return q===X?`[${K}]`:` ${K} `}).join("")},void 0,!1,void 0,this)},void 0,!1,void 0,this),$&&Y.tasks.length>0&&z$(S4,{flexDirection:"column",marginTop:1,children:[z$(j1,{color:"gray",dimColor:!0,children:["─── Tasks (",Y.tasks.filter((G)=>G.status==="completed").length,"/",Y.tasks.length,") ───"]},void 0,!0,void 0,this),Y.tasks.slice(0,Z).map((G)=>z$(SM,{task:G,isCurrent:G.id===Y.currentTaskId},G.id,!1,void 0,this)),Y.tasks.length>Z&&z$(j1,{color:"gray",dimColor:!0,children:["... and ",Y.tasks.length-Z," more tasks"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),!$&&Y.currentTaskId&&z$(S4,{flexDirection:"row",marginTop:1,children:[z$(j1,{color:"gray",children:"Current: "},void 0,!1,void 0,this),z$(j1,{color:"yellow",children:Y.tasks.find((G)=>G.id===Y.currentTaskId)?.title||"Unknown"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}),SM=wF.memo(({task:$,isCurrent:Z})=>{let Y=CM[$.status]||"?",Q=kM[$.status]||"gray";return z$(S4,{flexDirection:"row",children:[z$(j1,{color:Q,children:[Y," "]},void 0,!0,void 0,this),z$(j1,{color:Z?"yellow":"white",bold:Z,children:$.title},void 0,!1,void 0,this),$.complexity&&z$(j1,{color:"gray",dimColor:!0,children:[" ","[",$.complexity,"]"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});import{Box as fM,Text as n2}from"ink";import hM,{useEffect as xM,useState as bF}from"react";import{jsxDEV as u1,Fragment as RF}from"react/jsx-dev-runtime";var VF=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];function pM($){let Z=Math.floor($/1000);if(Z<60)return`${Z}s`;let Y=Math.floor(Z/60),Q=Z%60;return`${Y}m ${Q}s`}var DF=hM.memo(()=>{let $=z0((K)=>K.app.subagentProgress),Z=o0(),[Y,Q]=bF(0),[X,J]=bF(0);if(xM(()=>{if(!$||$.status!=="running"){Q(0),J(0);return}let K=setInterval(()=>{Q((U)=>(U+1)%VF.length)},80),W=setInterval(()=>{J(Date.now()-$.startTime)},1000);return()=>{clearInterval(K),clearInterval(W)}},[$]),!$)return null;let G=$.status==="running"?VF[Y]:$.status==="completed"?"✓":"✗",q=$.status==="running"?Z.colors.info:$.status==="completed"?Z.colors.success:Z.colors.error;return u1(fM,{paddingX:2,paddingY:0,flexDirection:"row",gap:1,children:[u1(n2,{color:q,bold:!0,children:G},void 0,!1,void 0,this),u1(n2,{color:Z.colors.muted,children:"Subagent"},void 0,!1,void 0,this),u1(n2,{color:Z.colors.text.primary,bold:!0,children:$.type},void 0,!1,void 0,this),u1(n2,{color:Z.colors.muted,children:"|"},void 0,!1,void 0,this),u1(n2,{color:Z.colors.text.secondary,children:$.description},void 0,!1,void 0,this),$.currentTool&&u1(RF,{children:[u1(n2,{color:Z.colors.muted,children:"|"},void 0,!1,void 0,this),u1(n2,{color:Z.colors.warning,children:$.currentTool},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$.status==="running"&&X>0&&u1(RF,{children:[u1(n2,{color:Z.colors.muted,children:"|"},void 0,!1,void 0,this),u1(n2,{color:Z.colors.info,children:pM(X)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});I2();import{useMemoizedFn as mM}from"ahooks";import{Box as j2,Text as a,useInput as gM}from"ink";import uM from"ink-select-input";import{useState as MF}from"react";b0();J9();I2();import{jsxDEV as d}from"react/jsx-dev-runtime";var jF=E2.map(($)=>({label:$.label,value:$.id})),dM=({theme:$})=>{let{colors:Z}=$;return d(j2,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[d(a,{bold:!0,color:Z.text.primary,children:"代码预览"},void 0,!1,void 0,this),d(a,{children:" "},void 0,!1,void 0,this),d(a,{color:Z.syntax.comment,children:"# function"},void 0,!1,void 0,this),d(a,{children:[d(a,{color:Z.syntax.keyword,children:"def"},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.function,children:"fibonacci"},void 0,!1,void 0,this),d(a,{color:Z.text.primary,children:"("},void 0,!1,void 0,this),d(a,{color:Z.syntax.variable,children:"n"},void 0,!1,void 0,this),d(a,{color:Z.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),d(a,{children:[" ",d(a,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this),d(a,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.operator,children:"="},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.number,children:"0"},void 0,!1,void 0,this),d(a,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.number,children:"1"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),d(a,{children:[" ",d(a,{color:Z.syntax.keyword,children:"for"},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.variable,children:"_"},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.keyword,children:"in"},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.function,children:"range"},void 0,!1,void 0,this),d(a,{color:Z.text.primary,children:"("},void 0,!1,void 0,this),d(a,{color:Z.syntax.variable,children:"n"},void 0,!1,void 0,this),d(a,{color:Z.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),d(a,{children:[" ",d(a,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this),d(a,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.operator,children:"="},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this),d(a,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.operator,children:"+"},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),d(a,{children:[" ",d(a,{color:Z.syntax.keyword,children:"return"},void 0,!1,void 0,this)," ",d(a,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),d(a,{children:" "},void 0,!1,void 0,this),d(a,{color:Z.error,children:["- print(",d(a,{color:Z.syntax.string,children:'"Hello, "'},void 0,!1,void 0,this)," + name)"]},void 0,!0,void 0,this),d(a,{color:Z.success,children:["+ print(",d(a,{color:Z.syntax.string,children:['f"Hello, ',"{","name","}",'"']},void 0,!0,void 0,this),")"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},cM=({theme:$})=>{let{colors:Z}=$;return d(j2,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[d(a,{children:" "},void 0,!1,void 0,this),d(a,{bold:!0,color:Z.text.primary,children:"颜色配置"},void 0,!1,void 0,this),d(a,{children:" "},void 0,!1,void 0,this),d(a,{children:[d(a,{color:Z.text.muted,children:"Primary: "},void 0,!1,void 0,this),d(a,{color:Z.primary,children:Z.primary},void 0,!1,void 0,this)]},void 0,!0,void 0,this),d(a,{children:[d(a,{color:Z.text.muted,children:"Success: "},void 0,!1,void 0,this),d(a,{color:Z.success,children:Z.success},void 0,!1,void 0,this)]},void 0,!0,void 0,this),d(a,{children:[d(a,{color:Z.text.muted,children:"Error: "},void 0,!1,void 0,this),d(a,{color:Z.error,children:Z.error},void 0,!1,void 0,this)]},void 0,!0,void 0,this),d(a,{children:[d(a,{color:Z.text.muted,children:"Warning: "},void 0,!1,void 0,this),d(a,{color:Z.warning,children:Z.warning},void 0,!1,void 0,this)]},void 0,!0,void 0,this),d(a,{children:[d(a,{color:Z.text.muted,children:"Info: "},void 0,!1,void 0,this),d(a,{color:Z.info,children:Z.info},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},TF=()=>{let $=M4(),Z=E$.getCurrentThemeName(),Y=E2.findIndex((_)=>_.label===Z),Q=Y>=0?E2[Y].theme:E2[0].theme,[X,J]=MF(Q),[G,q]=MF(!1),K=mM(async(_)=>{if(G)return;q(!0);try{await A0().setTheme(_.value),$.closeModal()}catch(z){console.error("❌ 主题切换失败:",z instanceof Error?z.message:z)}finally{q(!1)}}),W=(_)=>{let z=E2.find((N)=>N.id===_.value);if(z)J(z.theme)},H=_1()==="theme-selector",O=W$(!1);gM((_,z)=>{if(z.ctrl&&_==="c"||z.meta&&_==="c"){O();return}if(z.escape&&!G)$.closeModal()},{isActive:H});let F=(_)=>{let{isSelected:z,label:N}=_,L=N===Z?"✓":" ";return d(a,{color:z?X.colors.primary:X.colors.text.primary,children:[L," ",N]},void 0,!0,void 0,this)};return d(j2,{flexDirection:"column",height:"100%",children:[d(j2,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:X.colors.border.light,children:d(a,{bold:!0,color:X.colors.primary,children:"\uD83C\uDFA8 主题选择器"},void 0,!1,void 0,this)},void 0,!1,void 0,this),d(j2,{flexDirection:"row",flexGrow:1,children:[d(j2,{width:"40%",borderStyle:"single",borderColor:X.colors.border.light,paddingX:1,children:d(j2,{flexDirection:"column",children:[d(j2,{paddingTop:1,paddingBottom:1,children:d(a,{bold:!0,color:X.colors.text.primary,children:["可用主题 (",jF.length,")"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),d(uM,{items:jF,initialIndex:Y>=0?Y:0,onSelect:K,onHighlight:W,itemComponent:F},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),d(j2,{width:"60%",flexDirection:"column",borderStyle:"single",borderColor:X.colors.border.light,children:[d(dM,{theme:X},void 0,!1,void 0,this),d(cM,{theme:X},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),d(j2,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:X.colors.border.light,children:d(a,{color:X.colors.text.muted,children:G?"正在保存...":"Enter: 选择主题 | Esc: 取消"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as l0}from"react/jsx-dev-runtime";var J1=p("UI"),yF=({debug:$,continue:Z,...Y})=>{if($)J1.debug("[Debug] BladeInterface props:",{permissionMode:Y.permissionMode,yolo:Y.yolo,maxTurns:Y.maxTurns,continue:Z});let Q=i5(!1),X=i5(!1),J=i5(!1),G=i5(null),q=tU(),K=eU(),W=N5(),U=YH(),H=ZH(),O=M4(),F=D4(),_=KH(),z=O3(),N=j4(),B=qH();h4(()=>{if(E$.getCurrentThemeName()!==B)try{E$.setTheme(B)}catch{}},[B]);let{exit:L}=lM(),A=q==="ready",R=q==="needsSetup",V=q==="idle",{confirmationState:M,confirmationHandler:T,handleResponse:w}=yH(),{executeCommand:v,handleAbort:l}=DH(Y.systemPrompt,Y.appendSystemPrompt,T,Y.maxTurns),{getPreviousCommand:o,getNextCommand:S,addToHistory:y}=jH();mH();let m=IH("",0),I=X1(async()=>{let Z0=z,P0;if(Z0==="default")P0="autoEdit";else if(Z0==="autoEdit")P0="plan";else if(Z0==="plan")P0="spec";else if(Z0==="spec")P0="default";else P0="default";try{if(await A0().setPermissionMode(P0),P0==="spec")try{let b$=c0.getInstance();await b$.initialize(process.cwd());let V$=await b$.listSpecs();if(V$.length>0){let S$=V$[0];await b$.loadSpec(S$.name),F.addAssistantMessage(`\uD83D\uDCCB **已进入 Spec 模式**
|
|
2925
2925
|
|
|
2926
2926
|
`+`检测到已存在的 Spec: **${S$.name}**
|
|
2927
2927
|
`+`当前阶段: ${S$.phase}
|
|
@@ -2932,6 +2932,6 @@ ${e}
|
|
|
2932
2932
|
`+"`提案 → 需求 → 设计 → 任务 → 实现`\n\n"+'例如:"实现用户认证功能" 或 "添加暗黑模式支持"')}catch(b$){J1.warn("Failed to initialize SpecManager:",b$),F.addAssistantMessage(`\uD83D\uDCCB **已进入 Spec 模式**
|
|
2933
2933
|
|
|
2934
2934
|
`+`请告诉我你想实现什么功能,我会引导你完成整个工作流:
|
|
2935
|
-
`+"`提案 → 需求 → 设计 → 任务 → 实现`\n\n"+'例如:"实现用户认证功能" 或 "添加暗黑模式支持"')}}catch(b$){J1.error("❌ 权限模式切换失败:",b$ instanceof Error?b$.message:b$)}}),j=X1(async(Z0)=>{try{await A0().addModel({name:Z0.name,provider:Z0.provider,apiKey:Z0.apiKey,baseUrl:Z0.baseUrl,model:Z0.model}),O.setInitializationStatus("ready")}catch(P0){J1.error("❌ 初始化配置保存失败:",P0 instanceof Error?P0.message:P0),O.setInitializationStatus("ready")}}),D=X1(()=>{if(W==="shortcuts")O.closeModal();else O.setActiveModal("shortcuts")}),{showSuggestions:i,suggestions:g,selectedSuggestionIndex:k}=pH(m,v,o,S,y,l,N,I,D,W==="shortcuts");h4(()=>{if(m.value&&W==="shortcuts")O.closeModal()},[m.value,W,O]);let e=X1(async()=>{J.current=!0;try{let Z0=await P$.listSessions();if(Z0.length===0){F.addAssistantMessage("没有找到历史会话,开始新对话。");return}let P0=Z0[0],b$=await P$.loadSession(P0.sessionId),V$=b$.map((S$,XX)=>({id:`restored-${Date.now()}-${XX}`,role:S$.role,content:typeof S$.content==="string"?S$.content:JSON.stringify(S$.content),timestamp:Date.now()-(b$.length-XX)*1000,metadata:S$.metadata&&typeof S$.metadata==="object"?S$.metadata:void 0}));F.restoreSession(P0.sessionId,V$)}catch(Z0){J1.error("[BladeInterface] 继续会话失败:",Z0),F.addAssistantMessage("继续会话失败,开始新对话。")}}),C=X1(async()=>{J.current=!0;try{if(typeof Y.resume==="string"&&Y.resume!=="true"){let P0=await P$.loadSession(Y.resume),b$=P0.map((V$,S$)=>({id:`restored-${Date.now()}-${S$}`,role:V$.role,content:typeof V$.content==="string"?V$.content:JSON.stringify(V$.content),timestamp:Date.now()-(P0.length-S$)*1000,metadata:V$.metadata&&typeof V$.metadata==="object"?V$.metadata:void 0}));F.restoreSession(Y.resume,b$);return}let Z0=await P$.listSessions();if(Z0.length===0)J1.error("没有找到历史会话"),H3(1);O.showSessionSelector(Z0)}catch(Z0){J1.error("[BladeInterface] 加载会话失败:",Z0),H3(1)}});h4(()=>{if(Q.current)return;if(Z){Q.current=!0,e();return}if(Y.resume)Q.current=!0,C()},[Z,Y.resume,e,C]);let r=X1(async(Z0)=>{let P0=M.details?.type;if(P0==="enterPlanMode"&&Z0.approved)try{await A0().setPermissionMode("plan"),J1.debug("[BladeInterface] Entered Plan mode")}catch(b$){J1.error("[BladeInterface] Failed to enter Plan mode:",b$)}if(P0==="exitPlanMode"&&Z0.approved)J1.debug("[BladeInterface] ExitPlanMode approved, Store auto-synced");w(Z0)}),h=X1(()=>{F.addAssistantMessage("❌ 设置已取消"),F.addAssistantMessage("Blade 需要 API 配置才能正常工作。"),F.addAssistantMessage("您可以稍后运行 Blade 重新进入设置向导。"),H3(0)}),c=X1(()=>{O.closeModal()}),j0=X1(async(Z0)=>{try{let P0=await P$.loadSession(Z0),b$=P0.map((V$,S$)=>({id:`restored-${Date.now()}-${S$}`,role:V$.role,content:typeof V$.content==="string"?V$.content:JSON.stringify(V$.content),timestamp:Date.now()-(P0.length-S$)*1000,metadata:V$.metadata&&typeof V$.metadata==="object"?V$.metadata:void 0}));F.restoreSession(Z0,b$),O.closeModal()}catch(P0){J1.error("[BladeInterface] Failed to restore session:",P0),O.closeModal()}}),E0=X1(()=>{if(Y.resume)L();else O.closeModal()}),g0=X1((Z0)=>{O.showModelEditWizard(Z0)}),i0=X1((Z0)=>{F.addAssistantMessage(`✅ 已添加模型配置: ${Z0.name},并已切换到该模型`),c()}),s$=X1((Z0)=>{F.addAssistantMessage(`✅ 已更新模型配置: ${Z0.name}`),c()});h4(()=>{if(R){_.setFocus("model-config-wizard");return}if(M.isVisible)_.setFocus("confirmation-prompt");else if(W==="sessionSelector")_.setFocus("session-selector");else if(W==="themeSelector")_.setFocus("theme-selector");else if(W==="modelSelector")_.setFocus("model-selector");else if(W==="modelAddWizard"||W==="modelEditWizard")_.setFocus("model-config-wizard");else if(W==="permissionsManager")_.setFocus("permissions-manager");else if(W==="agentsManager")_.setFocus("agents-manager");else if(W==="agentCreationWizard")_.setFocus("agent-creation-wizard");else if(W==="hooksManager")_.setFocus("hooks-manager");else if(W==="shortcuts")_.setFocus("main-input");else _.setFocus("main-input")},[R,M.isVisible,W,_.setFocus]),h4(()=>{if(!A||J.current)return;if(rX().length>0){J.current=!0;return}J.current=!0,F.addAssistantMessage("请输入您的问题,我将为您提供帮助。")},[A]),h4(()=>{if(!K)return;if(G.current===K)return;if(G.current=K,q==="error")F.addAssistantMessage(`❌ 初始化失败: ${K}`);else F.addAssistantMessage(`❌ ${K}`),F.addAssistantMessage("请重新尝试设置,或检查文件权限")},[K,q,F.addAssistantMessage]);let M3=X1(async(Z0)=>{try{await v({displayText:Z0,text:Z0,images:[],parts:[{type:"text",text:Z0}]})}catch(P0){let b$=P0 instanceof Error?P0.message:"无法发送初始消息";F.addAssistantMessage(`❌ 初始消息发送失败:${b$}`)}});h4(()=>{let Z0=Y.initialMessage?.trim();if(!Z0||X.current||!A||R)return;X.current=!0,y(Z0),M3(Z0)},[Y.initialMessage,A,R,v,y]);let t2=X1(async(Z0)=>{try{await A0().setPermissionMode(Z0)}catch(P0){J1.error("❌ 权限模式初始化失败:",P0 instanceof Error?P0.message:P0)}});if(h4(()=>{let Z0=Y.permissionMode;if($)J1.debug("[Debug] permissionMode from CLI:",Z0),J1.debug("[Debug] current permissionMode:",z);if(!Z0||Z0===z)return;t2(Z0)},[Y.permissionMode,z]),V)return null;if(R)return l0(aQ,{mode:"setup",onComplete:j,onCancel:h},void 0,!1,void 0,this);if($)J1.debug("[Debug] 渲染主界面,条件检查:",{confirmationVisible:M.isVisible,activeModal:W});let O0=W==="modelSelector",G$=H,F0=W==="modelAddWizard"?"add":W==="modelEditWizard"&&G$?"edit":null,O2=O0||Boolean(F0),k$=W==="agentsManager",z1=W==="agentCreationWizard",d1=W==="skillsManager",m6=W==="pluginsManager",xF=G$?{name:G$.name,provider:G$.provider,baseUrl:G$.baseUrl,apiKey:G$.apiKey,model:G$.model}:void 0,YX=M.isVisible&&M.details?M.details.type==="askUserQuestion"&&M.details.questions?l0(zF,{questions:M.details.questions,onComplete:(Z0)=>r({approved:!0,answers:Z0}),onCancel:()=>r({approved:!1})},void 0,!1,void 0,this):l0(KO,{details:M.details,onResponse:r},void 0,!1,void 0,this):W==="themeSelector"?l0(TF,{},void 0,!1,void 0,this):W==="permissionsManager"?l0(OF,{onClose:c},void 0,!1,void 0,this):W==="sessionSelector"?l0(NF,{sessions:U,onSelect:j0,onCancel:E0},void 0,!1,void 0,this):W==="hooksManager"?l0(UO,{onClose:c},void 0,!1,void 0,this):null,QX=Boolean(YX);return l0(f4,{flexDirection:"column",width:"100%",overflow:"hidden",children:[YX,l0(f4,{flexDirection:"column",display:QX?"none":"flex",children:[z==="spec"&&l0(AF,{},void 0,!1,void 0,this),l0(dO,{},void 0,!1,void 0,this),l0(DF,{},void 0,!1,void 0,this),l0(yO,{paused:QX},void 0,!1,void 0,this),l0(bO,{input:m.value,cursorPosition:m.cursorPosition,onChange:m.setValue,onChangeCursorPosition:m.setCursorPosition,onAddPasteMapping:m.addPasteMapping,onAddImagePasteMapping:m.addImagePasteMapping},void 0,!1,void 0,this),O0&&l0(f4,{marginTop:1,paddingX:2,children:l0(qF,{onClose:c,onEdit:g0},void 0,!1,void 0,this)},void 0,!1,void 0,this),F0&&l0(f4,{marginTop:1,paddingX:2,children:l0(aQ,{mode:F0,modelId:G$?.id,initialConfig:F0==="edit"?xF:void 0,onComplete:F0==="edit"?s$:i0,onCancel:c},void 0,!1,void 0,this)},void 0,!1,void 0,this),k$&&l0(f4,{marginTop:1,paddingX:2,children:l0(lH,{onComplete:c,onCancel:c},void 0,!1,void 0,this)},void 0,!1,void 0,this),z1&&l0(f4,{marginTop:1,paddingX:2,children:l0(P6,{onComplete:c,onCancel:c},void 0,!1,void 0,this)},void 0,!1,void 0,this),d1&&l0(f4,{marginTop:1,paddingX:2,children:l0(LF,{onComplete:c,onCancel:c},void 0,!1,void 0,this)},void 0,!1,void 0,this),m6&&l0(f4,{marginTop:1,paddingX:2,children:l0(FF,{onComplete:c,onCancel:c},void 0,!1,void 0,this)},void 0,!1,void 0,this),l0(nH,{suggestions:g,selectedIndex:k,visible:i&&!O2},void 0,!1,void 0,this),l0(aH,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{Box as iM,Text as x4}from"ink";import rM from"react";import{jsxDEV as o2}from"react/jsx-dev-runtime";class r9 extends rM.Component{constructor($){super($);this.state={hasError:!1,error:null,errorInfo:null}}static getDerivedStateFromError($){return{hasError:!0,error:$,errorInfo:null}}componentDidCatch($,Z){this.setState({error:$,errorInfo:Z}),console.error("未捕获的错误:",$,Z)}render(){if(this.state.hasError)return o2(iM,{flexDirection:"column",padding:1,borderStyle:"round",borderColor:"red",children:[o2(x4,{color:"red",children:"\uD83D\uDCA5 应用发生错误"},void 0,!1,void 0,this),o2(x4,{children:" "},void 0,!1,void 0,this),o2(x4,{color:"red",children:this.state.error?.message},void 0,!1,void 0,this),o2(x4,{children:" "},void 0,!1,void 0,this),o2(x4,{color:"gray",children:"错误详情:"},void 0,!1,void 0,this),o2(x4,{color:"gray",children:this.state.error?.stack},void 0,!1,void 0,this),o2(x4,{children:" "},void 0,!1,void 0,this),o2(x4,{color:"yellow",children:"请重启应用或联系开发者"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return this.props.children}}import{Box as y8,Text as s2,useInput as aM}from"ink";import{useState as sQ}from"react";import{jsxDEV as o$}from"react/jsx-dev-runtime";var a9=[{key:"update",label:"Update now",description:`runs \`${GQ()}\``},{key:"skip",label:"Skip",description:""},{key:"skip_until_next",label:"Skip until next version",description:""}],EF=({versionInfo:$,onComplete:Z})=>{let[Y,Q]=sQ(0),[X,J]=sQ(!1),[G,q]=sQ(null);aM((W,U)=>{if(U.ctrl&&W==="c"){_8().shutdown("SIGINT",0);return}if(X||G)return;if(U.upArrow||W==="k")Q((H)=>H>0?H-1:a9.length-1);else if(U.downArrow||W==="j")Q((H)=>H<a9.length-1?H+1:0);else if(U.return)K(a9[Y].key);else if(W==="1")K("update");else if(W==="2")K("skip");else if(W==="3")K("skip_until_next")});let K=async(W)=>{switch(W){case"update":{J(!0);let U=await pU();q(U.message),setTimeout(()=>{_8().shutdown("SIGINT",0)},1500);break}case"skip":Z();break;case"skip_until_next":if($.latestVersion)await xU($.latestVersion);Z();break}};if(G)return o$(y8,{flexDirection:"column",marginY:1,children:o$(s2,{children:G},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(X)return o$(y8,{flexDirection:"column",marginY:1,children:o$(s2,{color:"cyan",children:"Updating..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);return o$(y8,{flexDirection:"column",marginY:1,children:[o$(s2,{color:"yellow",bold:!0,children:["✨ Update available! ",o$(s2,{color:"gray",children:[$.currentVersion," ","→"," ",$.latestVersion]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),o$(y8,{marginTop:1,children:o$(s2,{color:"gray",children:["Release notes:"," ",o$(s2,{color:"cyan",underline:!0,children:$.releaseNotesUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),o$(y8,{flexDirection:"column",marginTop:1,children:a9.map((W,U)=>{let H=U===Y,O=H?"› ":" ",F=`${U+1}. `;return o$(y8,{children:o$(s2,{color:H?"cyan":void 0,children:[O,F,W.label,W.description&&o$(s2,{color:"gray",children:[" (",W.description,")"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},W.key,!1,void 0,this)})},void 0,!1,void 0,this),o$(y8,{marginTop:1,children:o$(s2,{color:"gray",children:"Press enter to continue"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};I2();function D3($){return($ instanceof Error?$.message:String($)).replace(/sk-[a-zA-Z0-9]{32,}/g,"sk-***").replace(/apiKey['":\s]+[a-zA-Z0-9-_]+/gi,"apiKey: ***").replace(/API_KEY['":\s=]+[a-zA-Z0-9-_]+/gi,"API_KEY=***")}import{jsxDEV as n9}from"react/jsx-dev-runtime";function oM($){if(X0().config.actions.setConfig($),$.debug)console.log("[Debug] 模型配置检查通过,准备就绪");v2().setInitializationStatus("ready")}var PF=($)=>{let[Z,Y]=tQ(!1),[Q,X]=tQ(null),[J,G]=tQ(!1),q=IF(async()=>{let W=X0().config.config??E8,U=Z5(W,$);if(oM(U),U.debug)console.error("[Debug] 运行时配置:",U);let H=U.theme;if(H&&E$.hasTheme(H)){if(E$.setTheme(H),$.debug)console.log(`✓ 已加载主题: ${H}`)}try{let O=a0.loadFromStandardLocations();if($.debug&&O>0)console.log(`✓ 已加载 ${O} 个 subagents: ${a0.getAllNames().join(", ")}`)}catch(O){if($.debug)console.warn("⚠️ Subagents 加载失败:",D3(O))}try{let O=T0.getInstance();if(O.loadConfig(U.hooks||{}),$.debug&&U.hooks?.enabled)console.log("✓ Hooks 系统已启用");let F=X0(),_=F.session.sessionId;if(NX(_),O.isEnabled()){let z=F.config.config?.permissionMode||"default",N=!!$.resume,B=await O.executeSessionStartHooks({projectDir:process.cwd(),sessionId:_,permissionMode:z,isResume:N,resumeSessionId:typeof $.resume==="string"?$.resume:void 0});if(B.env){for(let[L,A]of Object.entries(B.env))process.env[L]=A;if($.debug)console.log("✓ SessionStart hooks 注入环境变量:",Object.keys(B.env).join(", "))}if(B.warning&&$.debug)console.warn("⚠️ SessionStart hooks 警告:",B.warning)}}catch(O){if($.debug)console.warn("⚠️ Hooks 初始化失败:",D3(O))}try{let O=await S2();if($.debug&&O.skills.length>0)console.log(`✓ 已加载 ${O.skills.length} 个 skills: ${O.skills.map((F)=>F.name).join(", ")}`);if(O.errors.length>0&&$.debug)for(let F of O.errors)console.warn(`⚠️ Skill 加载错误 (${F.path}): ${F.error}`)}catch(O){if($.debug)console.warn("⚠️ Skills 初始化失败:",D3(O))}try{let O=await eW(process.cwd());if($.debug&&O.commands.length>0)console.log(`✓ 已加载 ${O.commands.length} 个自定义命令: ${O.commands.map((F)=>F.name).join(", ")}`);if(O.errors.length>0&&$.debug)for(let F of O.errors)console.warn(`⚠️ 自定义命令加载错误 (${F.path}): ${F.error}`)}catch(O){if($.debug)console.warn("⚠️ 自定义命令初始化失败:",D3(O))}try{let F=await Y1().initialize(process.cwd(),$.pluginDir||[]);if($.debug&&F.plugins.length>0)console.log(`✓ 已加载 ${F.plugins.length} 个插件: ${F.plugins.map((_)=>_.manifest.name).join(", ")}`);if(F.plugins.length>0){let _=await L4();if($.debug){let{totalCommands:z,totalSkills:N,totalAgents:B,totalMcpServers:L}=_;console.log(` ✓ 已集成: ${z} 命令, ${N} 技能, ${B} 代理, ${L} MCP 服务器`)}}if(F.errors.length>0&&$.debug)for(let _ of F.errors)console.warn(`⚠️ 插件加载错误 (${_.path}): ${_.error}`)}catch(O){if($.debug)console.warn("⚠️ 插件系统初始化失败:",D3(O))}lU(async()=>{p$.getInstance().killAll(),await k0.getInstance().disconnectAll(),T0.getInstance().cleanup()}),Y(!0)}),K=IF(async()=>{if($.versionCheckPromise){let W=await $.versionCheckPromise;if(W){X(W),G(!0);return}}await q()});if(nM(()=>{K()},[]),J&&Q)return n9(r9,{children:n9(EF,{versionInfo:Q,onComplete:()=>{G(!1),q()}},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(!Z)return null;return n9(r9,{children:n9(yF,{...$},void 0,!1,void 0,this)},void 0,!1,void 0,this)};var ZX=hF(process.argv),fF=ZX.indexOf("--debug");if(fF!==-1){let $=ZX[fF+1],Z=$&&!$.startsWith("-")?$:!0;c1.setGlobalDebug(Z)}async function Gj(){if(process.getuid&&process.getuid()===0){let Y=!!process.env.SUDO_USER,Q=!!process.env.BLADE_ALLOW_ROOT;if(Y&&!Q)console.error(""),console.error("❌ 请不要使用 sudo 运行 blade"),console.error(""),console.error("原因:"),console.error(" 使用 sudo 会创建属于 root 的配置文件,"),console.error(" 导致普通用户无法访问。"),console.error(""),console.error("正确用法:"),console.error(" blade # 直接运行,不要加 sudo"),console.error(""),console.error("如果遇到权限错误,请运行:"),console.error(" sudo chown -R $USER:$USER ~/.blade/"),console.error(""),console.error("如果你确实需要以 root 运行(容器/CI),设置环境变量:"),console.error(" BLADE_ALLOW_ROOT=1 blade"),console.error(""),process.exit(1)}iU();let $=mU();if(await JU())return;if(await WU())return;if(ZX.includes("--acp")){let{runAcpIntegration:Y}=await Promise.resolve().then(() => (SF(),kF));await Y();return}let Z=Jj(hF(process.argv)).scriptName($4.scriptName).usage($4.usage).version($4.version).locale($4.locale).showHelpOnFail($4.showHelpOnFail).demandCommand(0,"").recommendCommands().strict($4.strict).parserConfiguration({"populate--":!0}).options(t9).middleware([A5,b5,V5]).command(KU).command(nX).command(gU).command(GU).command(dU).command(vU).completion("completion",!1).help("help","Show help").alias("help","h").alias("version","V").fail((Y,Q,X)=>{if(Q)console.error("\uD83D\uDCA5 An error occurred:"),console.error(Q.message),console.error(`
|
|
2935
|
+
`+"`提案 → 需求 → 设计 → 任务 → 实现`\n\n"+'例如:"实现用户认证功能" 或 "添加暗黑模式支持"')}}catch(b$){J1.error("❌ 权限模式切换失败:",b$ instanceof Error?b$.message:b$)}}),j=X1(async(Z0)=>{try{await A0().addModel({name:Z0.name,provider:Z0.provider,apiKey:Z0.apiKey,baseUrl:Z0.baseUrl,model:Z0.model}),O.setInitializationStatus("ready")}catch(P0){J1.error("❌ 初始化配置保存失败:",P0 instanceof Error?P0.message:P0),O.setInitializationStatus("ready")}}),D=X1(()=>{if(W==="shortcuts")O.closeModal();else O.setActiveModal("shortcuts")}),{showSuggestions:i,suggestions:g,selectedSuggestionIndex:k}=pH(m,v,o,S,y,l,N,I,D,W==="shortcuts");h4(()=>{if(m.value&&W==="shortcuts")O.closeModal()},[m.value,W,O]);let e=X1(async()=>{J.current=!0;try{let Z0=await P$.listSessions();if(Z0.length===0){F.addAssistantMessage("没有找到历史会话,开始新对话。");return}let P0=Z0[0],b$=await P$.loadSession(P0.sessionId),V$=b$.map((S$,XX)=>({id:`restored-${Date.now()}-${XX}`,role:S$.role,content:typeof S$.content==="string"?S$.content:JSON.stringify(S$.content),timestamp:Date.now()-(b$.length-XX)*1000,metadata:S$.metadata&&typeof S$.metadata==="object"?S$.metadata:void 0}));F.restoreSession(P0.sessionId,V$)}catch(Z0){J1.error("[BladeInterface] 继续会话失败:",Z0),F.addAssistantMessage("继续会话失败,开始新对话。")}}),C=X1(async()=>{J.current=!0;try{if(typeof Y.resume==="string"&&Y.resume!=="true"){let P0=await P$.loadSession(Y.resume),b$=P0.map((V$,S$)=>({id:`restored-${Date.now()}-${S$}`,role:V$.role,content:typeof V$.content==="string"?V$.content:JSON.stringify(V$.content),timestamp:Date.now()-(P0.length-S$)*1000,metadata:V$.metadata&&typeof V$.metadata==="object"?V$.metadata:void 0}));F.restoreSession(Y.resume,b$);return}let Z0=await P$.listSessions();if(Z0.length===0)J1.error("没有找到历史会话"),H3(1);O.showSessionSelector(Z0)}catch(Z0){J1.error("[BladeInterface] 加载会话失败:",Z0),H3(1)}});h4(()=>{if(Q.current)return;if(Z){Q.current=!0,e();return}if(Y.resume)Q.current=!0,C()},[Z,Y.resume,e,C]);let r=X1(async(Z0)=>{let P0=M.details?.type;if(P0==="enterPlanMode"&&Z0.approved)try{await A0().setPermissionMode("plan"),J1.debug("[BladeInterface] Entered Plan mode")}catch(b$){J1.error("[BladeInterface] Failed to enter Plan mode:",b$)}if(P0==="exitPlanMode"&&Z0.approved)J1.debug("[BladeInterface] ExitPlanMode approved, Store auto-synced");w(Z0)}),h=X1(()=>{F.addAssistantMessage("❌ 设置已取消"),F.addAssistantMessage("Blade 需要 API 配置才能正常工作。"),F.addAssistantMessage("您可以稍后运行 Blade 重新进入设置向导。"),H3(0)}),c=X1(()=>{O.closeModal()}),j0=X1(async(Z0)=>{try{let P0=await P$.loadSession(Z0),b$=P0.map((V$,S$)=>({id:`restored-${Date.now()}-${S$}`,role:V$.role,content:typeof V$.content==="string"?V$.content:JSON.stringify(V$.content),timestamp:Date.now()-(P0.length-S$)*1000,metadata:V$.metadata&&typeof V$.metadata==="object"?V$.metadata:void 0}));F.restoreSession(Z0,b$),O.closeModal()}catch(P0){J1.error("[BladeInterface] Failed to restore session:",P0),O.closeModal()}}),E0=X1(()=>{if(Y.resume)L();else O.closeModal()}),g0=X1((Z0)=>{O.showModelEditWizard(Z0)}),i0=X1((Z0)=>{F.addAssistantMessage(`✅ 已添加模型配置: ${Z0.name},并已切换到该模型`),c()}),s$=X1((Z0)=>{F.addAssistantMessage(`✅ 已更新模型配置: ${Z0.name}`),c()});h4(()=>{if(R){_.setFocus("model-config-wizard");return}if(M.isVisible)_.setFocus("confirmation-prompt");else if(W==="sessionSelector")_.setFocus("session-selector");else if(W==="themeSelector")_.setFocus("theme-selector");else if(W==="modelSelector")_.setFocus("model-selector");else if(W==="modelAddWizard"||W==="modelEditWizard")_.setFocus("model-config-wizard");else if(W==="permissionsManager")_.setFocus("permissions-manager");else if(W==="agentsManager")_.setFocus("agents-manager");else if(W==="agentCreationWizard")_.setFocus("agent-creation-wizard");else if(W==="hooksManager")_.setFocus("hooks-manager");else if(W==="shortcuts")_.setFocus("main-input");else _.setFocus("main-input")},[R,M.isVisible,W,_.setFocus]),h4(()=>{if(!A||J.current)return;if(rX().length>0){J.current=!0;return}J.current=!0,F.addAssistantMessage("请输入您的问题,我将为您提供帮助。")},[A]),h4(()=>{if(!K)return;if(G.current===K)return;if(G.current=K,q==="error")F.addAssistantMessage(`❌ 初始化失败: ${K}`);else F.addAssistantMessage(`❌ ${K}`),F.addAssistantMessage("请重新尝试设置,或检查文件权限")},[K,q,F.addAssistantMessage]);let M3=X1(async(Z0)=>{try{await v({displayText:Z0,text:Z0,images:[],parts:[{type:"text",text:Z0}]})}catch(P0){let b$=P0 instanceof Error?P0.message:"无法发送初始消息";F.addAssistantMessage(`❌ 初始消息发送失败:${b$}`)}});h4(()=>{let Z0=Y.initialMessage?.trim();if(!Z0||X.current||!A||R)return;X.current=!0,y(Z0),M3(Z0)},[Y.initialMessage,A,R,v,y]);let t2=X1(async(Z0)=>{try{await A0().setPermissionMode(Z0)}catch(P0){J1.error("❌ 权限模式初始化失败:",P0 instanceof Error?P0.message:P0)}});if(h4(()=>{let Z0=Y.permissionMode;if($)J1.debug("[Debug] permissionMode from CLI:",Z0),J1.debug("[Debug] current permissionMode:",z);if(!Z0||Z0===z)return;t2(Z0)},[Y.permissionMode,z]),V)return null;if(R)return l0(aQ,{mode:"setup",onComplete:j,onCancel:h},void 0,!1,void 0,this);if($)J1.debug("[Debug] 渲染主界面,条件检查:",{confirmationVisible:M.isVisible,activeModal:W});let O0=W==="modelSelector",G$=H,F0=W==="modelAddWizard"?"add":W==="modelEditWizard"&&G$?"edit":null,O2=O0||Boolean(F0),k$=W==="agentsManager",z1=W==="agentCreationWizard",d1=W==="skillsManager",m6=W==="pluginsManager",xF=G$?{name:G$.name,provider:G$.provider,baseUrl:G$.baseUrl,apiKey:G$.apiKey,model:G$.model}:void 0,YX=M.isVisible&&M.details?M.details.type==="askUserQuestion"&&M.details.questions?l0(zF,{questions:M.details.questions,onComplete:(Z0)=>r({approved:!0,answers:Z0}),onCancel:()=>r({approved:!1})},void 0,!1,void 0,this):l0(KO,{details:M.details,onResponse:r},void 0,!1,void 0,this):W==="themeSelector"?l0(TF,{},void 0,!1,void 0,this):W==="permissionsManager"?l0(OF,{onClose:c},void 0,!1,void 0,this):W==="sessionSelector"?l0(NF,{sessions:U,onSelect:j0,onCancel:E0},void 0,!1,void 0,this):W==="hooksManager"?l0(UO,{onClose:c},void 0,!1,void 0,this):null,QX=Boolean(YX);return l0(f4,{flexDirection:"column",width:"100%",overflow:"hidden",children:[YX,l0(f4,{flexDirection:"column",display:QX?"none":"flex",children:[z==="spec"&&l0(AF,{},void 0,!1,void 0,this),l0(dO,{},void 0,!1,void 0,this),l0(DF,{},void 0,!1,void 0,this),l0(yO,{paused:QX},void 0,!1,void 0,this),l0(bO,{input:m.value,cursorPosition:m.cursorPosition,onChange:m.setValue,onChangeCursorPosition:m.setCursorPosition,onAddPasteMapping:m.addPasteMapping,onAddImagePasteMapping:m.addImagePasteMapping},void 0,!1,void 0,this),O0&&l0(f4,{marginTop:1,paddingX:2,children:l0(qF,{onClose:c,onEdit:g0},void 0,!1,void 0,this)},void 0,!1,void 0,this),F0&&l0(f4,{marginTop:1,paddingX:2,children:l0(aQ,{mode:F0,modelId:G$?.id,initialConfig:F0==="edit"?xF:void 0,onComplete:F0==="edit"?s$:i0,onCancel:c},void 0,!1,void 0,this)},void 0,!1,void 0,this),k$&&l0(f4,{marginTop:1,paddingX:2,children:l0(lH,{onComplete:c,onCancel:c},void 0,!1,void 0,this)},void 0,!1,void 0,this),z1&&l0(f4,{marginTop:1,paddingX:2,children:l0(P6,{onComplete:c,onCancel:c},void 0,!1,void 0,this)},void 0,!1,void 0,this),d1&&l0(f4,{marginTop:1,paddingX:2,children:l0(LF,{onComplete:c,onCancel:c},void 0,!1,void 0,this)},void 0,!1,void 0,this),m6&&l0(f4,{marginTop:1,paddingX:2,children:l0(FF,{onComplete:c,onCancel:c},void 0,!1,void 0,this)},void 0,!1,void 0,this),l0(nH,{suggestions:g,selectedIndex:k,visible:i&&!O2},void 0,!1,void 0,this),l0(aH,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{Box as iM,Text as x4}from"ink";import rM from"react";import{jsxDEV as o2}from"react/jsx-dev-runtime";class r5 extends rM.Component{constructor($){super($);this.state={hasError:!1,error:null,errorInfo:null}}static getDerivedStateFromError($){return{hasError:!0,error:$,errorInfo:null}}componentDidCatch($,Z){this.setState({error:$,errorInfo:Z}),console.error("未捕获的错误:",$,Z)}render(){if(this.state.hasError)return o2(iM,{flexDirection:"column",padding:1,borderStyle:"round",borderColor:"red",children:[o2(x4,{color:"red",children:"\uD83D\uDCA5 应用发生错误"},void 0,!1,void 0,this),o2(x4,{children:" "},void 0,!1,void 0,this),o2(x4,{color:"red",children:this.state.error?.message},void 0,!1,void 0,this),o2(x4,{children:" "},void 0,!1,void 0,this),o2(x4,{color:"gray",children:"错误详情:"},void 0,!1,void 0,this),o2(x4,{color:"gray",children:this.state.error?.stack},void 0,!1,void 0,this),o2(x4,{children:" "},void 0,!1,void 0,this),o2(x4,{color:"yellow",children:"请重启应用或联系开发者"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return this.props.children}}import{Box as y8,Text as s2,useInput as aM}from"ink";import{useState as sQ}from"react";import{jsxDEV as o$}from"react/jsx-dev-runtime";var a5=[{key:"update",label:"Update now",description:`runs \`${GQ()}\``},{key:"skip",label:"Skip",description:""},{key:"skip_until_next",label:"Skip until next version",description:""}],EF=({versionInfo:$,onComplete:Z})=>{let[Y,Q]=sQ(0),[X,J]=sQ(!1),[G,q]=sQ(null);aM((W,U)=>{if(U.ctrl&&W==="c"){_8().shutdown("SIGINT",0);return}if(X||G)return;if(U.upArrow||W==="k")Q((H)=>H>0?H-1:a5.length-1);else if(U.downArrow||W==="j")Q((H)=>H<a5.length-1?H+1:0);else if(U.return)K(a5[Y].key);else if(W==="1")K("update");else if(W==="2")K("skip");else if(W==="3")K("skip_until_next")});let K=async(W)=>{switch(W){case"update":{J(!0);let U=await pU();q(U.message),setTimeout(()=>{_8().shutdown("SIGINT",0)},1500);break}case"skip":Z();break;case"skip_until_next":if($.latestVersion)await xU($.latestVersion);Z();break}};if(G)return o$(y8,{flexDirection:"column",marginY:1,children:o$(s2,{children:G},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(X)return o$(y8,{flexDirection:"column",marginY:1,children:o$(s2,{color:"cyan",children:"Updating..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);return o$(y8,{flexDirection:"column",marginY:1,children:[o$(s2,{color:"yellow",bold:!0,children:["✨ Update available! ",o$(s2,{color:"gray",children:[$.currentVersion," ","→"," ",$.latestVersion]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),o$(y8,{marginTop:1,children:o$(s2,{color:"gray",children:["Release notes:"," ",o$(s2,{color:"cyan",underline:!0,children:$.releaseNotesUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),o$(y8,{flexDirection:"column",marginTop:1,children:a5.map((W,U)=>{let H=U===Y,O=H?"› ":" ",F=`${U+1}. `;return o$(y8,{children:o$(s2,{color:H?"cyan":void 0,children:[O,F,W.label,W.description&&o$(s2,{color:"gray",children:[" (",W.description,")"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},W.key,!1,void 0,this)})},void 0,!1,void 0,this),o$(y8,{marginTop:1,children:o$(s2,{color:"gray",children:"Press enter to continue"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};I2();function D3($){return($ instanceof Error?$.message:String($)).replace(/sk-[a-zA-Z0-9]{32,}/g,"sk-***").replace(/apiKey['":\s]+[a-zA-Z0-9-_]+/gi,"apiKey: ***").replace(/API_KEY['":\s=]+[a-zA-Z0-9-_]+/gi,"API_KEY=***")}import{jsxDEV as n5}from"react/jsx-dev-runtime";function oM($){if(X0().config.actions.setConfig($),$.debug)console.log("[Debug] 模型配置检查通过,准备就绪");v2().setInitializationStatus("ready")}var PF=($)=>{let[Z,Y]=tQ(!1),[Q,X]=tQ(null),[J,G]=tQ(!1),q=IF(async()=>{let W=X0().config.config??E8,U=Z9(W,$);if(oM(U),U.debug)console.error("[Debug] 运行时配置:",U);let H=U.theme;if(H&&E$.hasTheme(H)){if(E$.setTheme(H),$.debug)console.log(`✓ 已加载主题: ${H}`)}try{let O=a0.loadFromStandardLocations();if($.debug&&O>0)console.log(`✓ 已加载 ${O} 个 subagents: ${a0.getAllNames().join(", ")}`)}catch(O){if($.debug)console.warn("⚠️ Subagents 加载失败:",D3(O))}try{let O=T0.getInstance();if(O.loadConfig(U.hooks||{}),$.debug&&U.hooks?.enabled)console.log("✓ Hooks 系统已启用");let F=X0(),_=F.session.sessionId;if(NX(_),O.isEnabled()){let z=F.config.config?.permissionMode||"default",N=!!$.resume,B=await O.executeSessionStartHooks({projectDir:process.cwd(),sessionId:_,permissionMode:z,isResume:N,resumeSessionId:typeof $.resume==="string"?$.resume:void 0});if(B.env){for(let[L,A]of Object.entries(B.env))process.env[L]=A;if($.debug)console.log("✓ SessionStart hooks 注入环境变量:",Object.keys(B.env).join(", "))}if(B.warning&&$.debug)console.warn("⚠️ SessionStart hooks 警告:",B.warning)}}catch(O){if($.debug)console.warn("⚠️ Hooks 初始化失败:",D3(O))}try{let O=await S2();if($.debug&&O.skills.length>0)console.log(`✓ 已加载 ${O.skills.length} 个 skills: ${O.skills.map((F)=>F.name).join(", ")}`);if(O.errors.length>0&&$.debug)for(let F of O.errors)console.warn(`⚠️ Skill 加载错误 (${F.path}): ${F.error}`)}catch(O){if($.debug)console.warn("⚠️ Skills 初始化失败:",D3(O))}try{let O=await eW(process.cwd());if($.debug&&O.commands.length>0)console.log(`✓ 已加载 ${O.commands.length} 个自定义命令: ${O.commands.map((F)=>F.name).join(", ")}`);if(O.errors.length>0&&$.debug)for(let F of O.errors)console.warn(`⚠️ 自定义命令加载错误 (${F.path}): ${F.error}`)}catch(O){if($.debug)console.warn("⚠️ 自定义命令初始化失败:",D3(O))}try{let F=await Y1().initialize(process.cwd(),$.pluginDir||[]);if($.debug&&F.plugins.length>0)console.log(`✓ 已加载 ${F.plugins.length} 个插件: ${F.plugins.map((_)=>_.manifest.name).join(", ")}`);if(F.plugins.length>0){let _=await L4();if($.debug){let{totalCommands:z,totalSkills:N,totalAgents:B,totalMcpServers:L}=_;console.log(` ✓ 已集成: ${z} 命令, ${N} 技能, ${B} 代理, ${L} MCP 服务器`)}}if(F.errors.length>0&&$.debug)for(let _ of F.errors)console.warn(`⚠️ 插件加载错误 (${_.path}): ${_.error}`)}catch(O){if($.debug)console.warn("⚠️ 插件系统初始化失败:",D3(O))}lU(async()=>{p$.getInstance().killAll(),await k0.getInstance().disconnectAll(),T0.getInstance().cleanup()}),Y(!0)}),K=IF(async()=>{if($.versionCheckPromise){let W=await $.versionCheckPromise;if(W){X(W),G(!0);return}}await q()});if(nM(()=>{K()},[]),J&&Q)return n5(r5,{children:n5(EF,{versionInfo:Q,onComplete:()=>{G(!1),q()}},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(!Z)return null;return n5(r5,{children:n5(yF,{...$},void 0,!1,void 0,this)},void 0,!1,void 0,this)};var ZX=hF(process.argv),fF=ZX.indexOf("--debug");if(fF!==-1){let $=ZX[fF+1],Z=$&&!$.startsWith("-")?$:!0;c1.setGlobalDebug(Z)}async function Gj(){if(process.getuid&&process.getuid()===0){let Y=!!process.env.SUDO_USER,Q=!!process.env.BLADE_ALLOW_ROOT;if(Y&&!Q)console.error(""),console.error("❌ 请不要使用 sudo 运行 blade"),console.error(""),console.error("原因:"),console.error(" 使用 sudo 会创建属于 root 的配置文件,"),console.error(" 导致普通用户无法访问。"),console.error(""),console.error("正确用法:"),console.error(" blade # 直接运行,不要加 sudo"),console.error(""),console.error("如果遇到权限错误,请运行:"),console.error(" sudo chown -R $USER:$USER ~/.blade/"),console.error(""),console.error("如果你确实需要以 root 运行(容器/CI),设置环境变量:"),console.error(" BLADE_ALLOW_ROOT=1 blade"),console.error(""),process.exit(1)}iU();let $=mU();if(await JU())return;if(await WU())return;if(ZX.includes("--acp")){let{runAcpIntegration:Y}=await Promise.resolve().then(() => (SF(),kF));await Y();return}let Z=Jj(hF(process.argv)).scriptName($4.scriptName).usage($4.usage).version($4.version).locale($4.locale).showHelpOnFail($4.showHelpOnFail).demandCommand(0,"").recommendCommands().strict($4.strict).parserConfiguration({"populate--":!0}).options(t5).middleware([A9,b9,V9]).command(KU).command(nX).command(gU).command(GU).command(dU).command(vU).completion("completion",!1).help("help","Show help").alias("help","h").alias("version","V").fail((Y,Q,X)=>{if(Q)console.error("\uD83D\uDCA5 An error occurred:"),console.error(Q.message),console.error(`
|
|
2936
2936
|
Stack trace:`),console.error(Q.stack),process.exit(1);if(Y)console.error("❌ Invalid arguments:"),console.error(Y),console.error(`
|
|
2937
2937
|
\uD83D\uDCA1 Did you mean:`),X.showHelp(),process.exit(1)}).command("$0",!1,()=>{},async(Y)=>{let Q=Y._.slice(1),X=Q.length>0?Q.join(" "):void 0,J={...Y,initialMessage:X,debug:Y.debug,print:Boolean(Y.print),versionCheckPromise:$};delete J._,delete J.$0,delete J.message,Qj(Xj.createElement(PF,J),{patchConsole:!0,exitOnCtrlC:!1,alternateBuffer:!1})});try{await Z.parse()}catch(Y){console.error("❌ Parse error:",Y),process.exit(1)}}if(U$.main==U$.module)Gj().catch(console.error);export{Gj as main};
|