blade-code 0.0.39 → 0.0.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/dist/blade.js +356 -354
  3. package/package.json +4 -1
package/dist/blade.js CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import{createRequire as Fq}from"node:module";var Gq=Object.create;var{getPrototypeOf:Kq,defineProperty:A9,getOwnPropertyNames:Uq}=Object;var Wq=Object.prototype.hasOwnProperty;var q0=($,Y,Z)=>{Z=$!=null?Gq(Kq($)):{};let X=Y||!$||!$.__esModule?A9(Z,"default",{value:$,enumerable:!0}):Z;for(let Q of Uq($))if(!Wq.call(X,Q))A9(X,Q,{get:()=>$[Q],enumerable:!0});return X};var Oq=($,Y)=>{for(var Z in Y)A9($,Z,{get:Y[Z],enumerable:!0,configurable:!0,set:(X)=>Y[Z]=()=>X})};var b=($,Y)=>()=>($&&(Y=$($=0)),Y);var c1=Fq(import.meta.url);var Z6;var v3=b(()=>{Z6={name:"blade-code",version:"0.0.39",private:!1,description:"🗡️ Blade Code - 智能代码助手命令行工具",type:"module",bin:{blade:"dist/blade.js"},files:["dist","bin","vendor/ripgrep/**","config.env.example","README.md","CHANGELOG.md"],scripts:{dev:"bun --watch src/blade.tsx",build:"rm -rf dist && bun run scripts/build.ts",start:"bun 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:coverage":"node scripts/test.js all --coverage","test:unit:coverage":"node scripts/test.js unit --coverage","test:integration:coverage":"node scripts/test.js integration --coverage","test:cli:coverage":"node scripts/test.js cli --coverage","test:watch":"vitest --watch --config vitest.config.ts","test:unit:watch":"vitest --watch --config vitest.config.ts --project unit","test:integration:watch":"vitest --watch --config vitest.config.ts --project integration","test:cli:watch":"vitest --watch --config vitest.config.ts --project cli","test:debug":"node scripts/test.js all --debug","test:verbose":"node scripts/test.js all --verbose","test:ci":"vitest run --config vitest.config.ts --coverage --reporter=verbose","test:performance":'vitest --testNamePattern="performance" --verbose',lint:"biome lint src tests","lint:fix":"biome lint --write src tests",format:"biome format --write src tests","format:check":"biome format src tests",check:"biome check src tests","check:fix":"biome check --write src tests","type-check":"tsc --noEmit","check:full":"npm run type-check && npm run lint && npm run format:check && npm run test:ci","security:audit":"pnpm audit","security:test":"bash scripts/run-security-tests.sh","vendor:ripgrep":"node scripts/download-ripgrep.js","vendor:ripgrep:clean":"rm -rf vendor/ripgrep/darwin-* vendor/ripgrep/linux-* vendor/ripgrep/win32-*",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",clean:"rm -rf dist node_modules/.cache coverage",prepare:"bun run build",preflight:"npm run clean && pnpm install && npm run format && npm run lint && npm run build && npm run type-check && npm run test:ci"},keywords:["cli","blade","ai","assistant","agent","llm","tool","qwen","volcengine","smart-tools","code-review","documentation","git-tools"],author:"echoVic",license:"MIT",repository:{type:"git",url:"git+https://github.com/echoVic/blade-code.git"},homepage:"https://github.com/echoVic/blade-code",bugs:{url:"https://github.com/echoVic/blade-doc/issues"},engines:{node:">=16.0.0"},devDependencies:{"@biomejs/biome":"^2.2.4","@testing-library/react":"^16.2.0","@testing-library/user-event":"^14.5.0","@types/bun":"^1.3.4","@types/diff":"^8.0.0","@types/inquirer":"^9.0.8","@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.12","@types/react-dom":"^19.1.9","@types/semver":"^7.7.1","@types/uuid":"^10.0.0","@types/write-file-atomic":"^4.0.3","@types/ws":"^8.5.12","@types/yargs":"^17.0.33","@vitest/coverage-v8":"^3.0.0",execa:"^9.6.0",jsdom:"^26.0.0","ts-node":"^10.9.2",typescript:"^5.9.2",vitest:"^3.0.0"},optionalDependencies:{"@vscode/ripgrep":"^1.17.0"},dependencies:{"@agentclientprotocol/sdk":"^0.12.0","@inkjs/ui":"^2.0.0","@modelcontextprotocol/sdk":"^1.17.4",ahooks:"^3.9.5","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","fullscreen-ink":"^0.1.0","fuse.js":"^7.1.0",glob:"^11.0.3","gray-matter":"^4.0.3",ink:"npm:@jrichman/ink@6.4.6","ink-big-text":"^2.0.0","ink-gradient":"^3.0.0","ink-progress-bar":"^3.0.0","ink-select-input":"^6.2.0","ink-spinner":"^5.0.0","ink-text-input":"^6.0.0",inquirer:"^12.6.3","js-tiktoken":"^1.0.21","lodash-es":"^4.17.21",lowlight:"^3.3.0","lru-cache":"^11.2.4",nanoid:"^5.1.6",openai:"^6.2.0",picomatch:"^4.0.3",pino:"^10.1.0","pino-pretty":"^13.1.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"}}});function O$(){return Z6.version}function E3(){return Z6.name}function P3(){return Z6.description}function T3(){return`v${Z6.version} © 2025 Blade Code`}var X6=b(()=>{v3()});var s1=()=>{};var F$;var b9=b(()=>{s1();F$={currentModelId:"",models:[],temperature:0,maxContextTokens:128000,maxOutputTokens:32768,stream:!0,topP:0.9,topK:50,timeout:180000,theme:"GitHub",language:"zh-CN",fontSize:14,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 i6}from"fs";import{merge as S3}from"lodash-es";import C3 from"os";import H$ from"path";class G0{static instance=null;constructor(){}static getInstance(){if(!G0.instance)G0.instance=new G0;return G0.instance}static resetInstance(){G0.instance=null}async initialize(){try{let $=await this.loadConfigFiles(),Y=await this.loadSettingsFiles(),Z={...F$,...$,...Y};if(this.resolveEnvInterpolation(Z),await this.ensureGitIgnore(Z.debug),Z.debug)console.log("[ConfigManager] Configuration loaded successfully");return Z}catch($){return console.error("[ConfigManager] Failed to initialize:",$),F$}}async loadConfigFiles(){let $=H$.join(C3.homedir(),".blade","config.json"),Y=H$.join(process.cwd(),".blade","config.json"),Z={},X=await this.loadJsonFile($);if(X)Z={...Z,...X};let Q=await this.loadJsonFile(Y);if(Q){let J={...Z.mcpServers||{},...Q.mcpServers||{}};if(Z={...Z,...Q},Object.keys(J).length>0)Z.mcpServers=J}return Z}async loadSettingsFiles(){let $=H$.join(C3.homedir(),".blade","settings.json"),Y=H$.join(process.cwd(),".blade","settings.json"),Z=H$.join(process.cwd(),".blade","settings.local.json"),X={},Q=await this.loadJsonFile($);if(Q)X=this.mergeSettings(X,Q);let J=await this.loadJsonFile(Y);if(J)X=this.mergeSettings(X,J);let q=await this.loadJsonFile(Z);if(q)X=this.mergeSettings(X,q);return X}mergeSettings($,Y){let Z=JSON.parse(JSON.stringify($));if(Y.permissions){if(!Z.permissions)Z.permissions={allow:[],ask:[],deny:[]};if(Y.permissions.allow){let X=[...Z.permissions.allow||[],...Y.permissions.allow];Z.permissions.allow=Array.from(new Set(X))}if(Y.permissions.ask){let X=[...Z.permissions.ask||[],...Y.permissions.ask];Z.permissions.ask=Array.from(new Set(X))}if(Y.permissions.deny){let X=[...Z.permissions.deny||[],...Y.permissions.deny];Z.permissions.deny=Array.from(new Set(X))}}if(Y.hooks)Z.hooks=S3({},Z.hooks,Y.hooks);if(Y.env)Z.env=S3({},Z.env,Y.env);if(Y.mcpServers)Z.mcpServers={...Z.mcpServers||{},...Y.mcpServers};if(Y.disableAllHooks!==void 0)Z.disableAllHooks=Y.disableAllHooks;if(Y.permissionMode!==void 0)Z.permissionMode=Y.permissionMode;if(Y.maxTurns!==void 0)Z.maxTurns=Y.maxTurns;return Z}resolveEnvInterpolation($){let Y=/\$\{?([A-Z_][A-Z0-9_]*)(:-([^}]+))?\}?/g,Z=(X)=>{if(typeof X==="string")return X.replace(Y,(Q,J,q,G)=>{return process.env[J]||G||Q});return X};for(let[X,Q]of Object.entries($))if(typeof Q==="string")$[X]=Z(Q)}async ensureGitIgnore($){let Y=H$.join(process.cwd(),".gitignore"),Z=".blade/settings.local.json";try{let X="";if(await this.fileExists(Y))X=await i6.readFile(Y,"utf-8");if(!X.includes(".blade/settings.local.json")){let Q=X.trim()+`
2
+ import{createRequire as Pq}from"node:module";var Mq=Object.create;var{getPrototypeOf:jq,defineProperty:V8,getOwnPropertyNames:yq}=Object;var Eq=Object.prototype.hasOwnProperty;var U0=($,Y,Z)=>{Z=$!=null?Mq(jq($)):{};let X=Y||!$||!$.__esModule?V8(Z,"default",{value:$,enumerable:!0}):Z;for(let Q of yq($))if(!Eq.call(X,Q))V8(X,Q,{get:()=>$[Q],enumerable:!0});return X};var vq=($,Y)=>{for(var Z in Y)V8($,Z,{get:Y[Z],enumerable:!0,configurable:!0,set:(X)=>Y[Z]=()=>X})};var b=($,Y)=>()=>($&&(Y=$($=0)),Y);var r1=Pq(import.meta.url);var J6;var x3=b(()=>{J6={name:"blade-code",version:"0.0.40",private:!1,description:"🗡️ Blade Code - 智能代码助手命令行工具",type:"module",bin:{blade:"dist/blade.js"},files:["dist","bin","vendor/ripgrep/**","config.env.example","README.md","CHANGELOG.md"],scripts:{dev:"bun --watch src/blade.tsx",build:"rm -rf dist && bun run scripts/build.ts",start:"bun 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:coverage":"node scripts/test.js all --coverage","test:unit:coverage":"node scripts/test.js unit --coverage","test:integration:coverage":"node scripts/test.js integration --coverage","test:cli:coverage":"node scripts/test.js cli --coverage","test:watch":"vitest --watch --config vitest.config.ts","test:unit:watch":"vitest --watch --config vitest.config.ts --project unit","test:integration:watch":"vitest --watch --config vitest.config.ts --project integration","test:cli:watch":"vitest --watch --config vitest.config.ts --project cli","test:debug":"node scripts/test.js all --debug","test:verbose":"node scripts/test.js all --verbose","test:ci":"vitest run --config vitest.config.ts --coverage --reporter=verbose","test:performance":'vitest --testNamePattern="performance" --verbose',lint:"biome lint src tests","lint:fix":"biome lint --write src tests",format:"biome format --write src tests","format:check":"biome format src tests",check:"biome check src tests","check:fix":"biome check --write src tests","type-check":"tsc --noEmit","check:full":"npm run type-check && npm run lint && npm run format:check && npm run test:ci","security:audit":"pnpm audit","security:test":"bash scripts/run-security-tests.sh","vendor:ripgrep":"node scripts/download-ripgrep.js","vendor:ripgrep:clean":"rm -rf vendor/ripgrep/darwin-* vendor/ripgrep/linux-* vendor/ripgrep/win32-*",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",clean:"rm -rf dist node_modules/.cache coverage",prepare:"bun run build",preflight:"npm run clean && pnpm install && npm run format && npm run lint && npm run build && npm run type-check && npm run test:ci"},keywords:["cli","blade","ai","assistant","agent","llm","tool","qwen","volcengine","smart-tools","code-review","documentation","git-tools"],author:"echoVic",license:"MIT",repository:{type:"git",url:"git+https://github.com/echoVic/blade-code.git"},homepage:"https://github.com/echoVic/blade-code",bugs:{url:"https://github.com/echoVic/blade-doc/issues"},engines:{node:">=16.0.0"},devDependencies:{"@biomejs/biome":"^2.2.4","@testing-library/react":"^16.2.0","@testing-library/user-event":"^14.5.0","@types/bun":"^1.3.4","@types/diff":"^8.0.0","@types/inquirer":"^9.0.8","@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.12","@types/react-dom":"^19.1.9","@types/semver":"^7.7.1","@types/uuid":"^10.0.0","@types/write-file-atomic":"^4.0.3","@types/ws":"^8.5.12","@types/yargs":"^17.0.33","@vitest/coverage-v8":"^3.0.0",execa:"^9.6.0",jsdom:"^26.0.0","ts-node":"^10.9.2",typescript:"^5.9.2",vitest:"^3.0.0"},optionalDependencies:{"@vscode/ripgrep":"^1.17.0"},dependencies:{"@agentclientprotocol/sdk":"^0.12.0","@anthropic-ai/sdk":"^0.71.2","@azure/identity":"^4.13.0","@google/genai":"^1.34.0","@inkjs/ui":"^2.0.0","@modelcontextprotocol/sdk":"^1.17.4",ahooks:"^3.9.5","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","fullscreen-ink":"^0.1.0","fuse.js":"^7.1.0",glob:"^11.0.3","gray-matter":"^4.0.3",ink:"npm:@jrichman/ink@6.4.6","ink-big-text":"^2.0.0","ink-gradient":"^3.0.0","ink-progress-bar":"^3.0.0","ink-select-input":"^6.2.0","ink-spinner":"^5.0.0","ink-text-input":"^6.0.0",inquirer:"^12.6.3","js-tiktoken":"^1.0.21","lodash-es":"^4.17.21",lowlight:"^3.3.0","lru-cache":"^11.2.4",nanoid:"^5.1.6",openai:"^6.2.0",picomatch:"^4.0.3",pino:"^10.1.0","pino-pretty":"^13.1.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"}}});function z$(){return J6.version}function p3(){return J6.name}function u3(){return J6.description}function g3(){return`v${J6.version} © 2025 Blade Code`}var q6=b(()=>{x3()});var $0=()=>{};var N$;var D8=b(()=>{$0();N$={currentModelId:"",models:[],temperature:0,maxContextTokens:128000,maxOutputTokens:32768,stream:!0,topP:0.9,topK:50,timeout:180000,theme:"GitHub",language:"zh-CN",fontSize:14,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 n6}from"fs";import{merge as m3}from"lodash-es";import c3 from"os";import B$ from"path";class W0{static instance=null;constructor(){}static getInstance(){if(!W0.instance)W0.instance=new W0;return W0.instance}static resetInstance(){W0.instance=null}async initialize(){try{let $=await this.loadConfigFiles(),Y=await this.loadSettingsFiles(),Z={...N$,...$,...Y};if(this.resolveEnvInterpolation(Z),await this.ensureGitIgnore(Z.debug),Z.debug)console.log("[ConfigManager] Configuration loaded successfully");return Z}catch($){return console.error("[ConfigManager] Failed to initialize:",$),N$}}async loadConfigFiles(){let $=B$.join(c3.homedir(),".blade","config.json"),Y=B$.join(process.cwd(),".blade","config.json"),Z={},X=await this.loadJsonFile($);if(X)Z={...Z,...X};let Q=await this.loadJsonFile(Y);if(Q){let J={...Z.mcpServers||{},...Q.mcpServers||{}};if(Z={...Z,...Q},Object.keys(J).length>0)Z.mcpServers=J}return Z}async loadSettingsFiles(){let $=B$.join(c3.homedir(),".blade","settings.json"),Y=B$.join(process.cwd(),".blade","settings.json"),Z=B$.join(process.cwd(),".blade","settings.local.json"),X={},Q=await this.loadJsonFile($);if(Q)X=this.mergeSettings(X,Q);let J=await this.loadJsonFile(Y);if(J)X=this.mergeSettings(X,J);let q=await this.loadJsonFile(Z);if(q)X=this.mergeSettings(X,q);return X}mergeSettings($,Y){let Z=JSON.parse(JSON.stringify($));if(Y.permissions){if(!Z.permissions)Z.permissions={allow:[],ask:[],deny:[]};if(Y.permissions.allow){let X=[...Z.permissions.allow||[],...Y.permissions.allow];Z.permissions.allow=Array.from(new Set(X))}if(Y.permissions.ask){let X=[...Z.permissions.ask||[],...Y.permissions.ask];Z.permissions.ask=Array.from(new Set(X))}if(Y.permissions.deny){let X=[...Z.permissions.deny||[],...Y.permissions.deny];Z.permissions.deny=Array.from(new Set(X))}}if(Y.hooks)Z.hooks=m3({},Z.hooks,Y.hooks);if(Y.env)Z.env=m3({},Z.env,Y.env);if(Y.mcpServers)Z.mcpServers={...Z.mcpServers||{},...Y.mcpServers};if(Y.disableAllHooks!==void 0)Z.disableAllHooks=Y.disableAllHooks;if(Y.permissionMode!==void 0)Z.permissionMode=Y.permissionMode;if(Y.maxTurns!==void 0)Z.maxTurns=Y.maxTurns;return Z}resolveEnvInterpolation($){let Y=/\$\{?([A-Z_][A-Z0-9_]*)(:-([^}]+))?\}?/g,Z=(X)=>{if(typeof X==="string")return X.replace(Y,(Q,J,q,K)=>{return process.env[J]||K||Q});return X};for(let[X,Q]of Object.entries($))if(typeof Q==="string")$[X]=Z(Q)}async ensureGitIgnore($){let Y=B$.join(process.cwd(),".gitignore"),Z=".blade/settings.local.json";try{let X="";if(await this.fileExists(Y))X=await n6.readFile(Y,"utf-8");if(!X.includes(".blade/settings.local.json")){let Q=X.trim()+`
3
3
 
4
4
  # Blade local settings
5
5
  .blade/settings.local.json
6
- `;if(await i6.writeFile(Y,Q,"utf-8"),$)console.log("[ConfigManager] Added .blade/settings.local.json to .gitignore")}}catch(X){}}async loadJsonFile($){try{if(await this.fileExists($)){let Y=await i6.readFile($,"utf-8");return JSON.parse(Y)}}catch(Y){console.warn(`[ConfigManager] Failed to load ${$}:`,Y)}return null}async fileExists($){try{return await i6.access($),!0}catch{return!1}}validateConfig($){let Y=[];if(!$.models||$.models.length===0)Y.push("没有可用的模型配置");if($.models&&$.models.length>0){if(!$.currentModelId)Y.push("未设置当前模型 ID");else if(!$.models.find((X)=>X.id===$.currentModelId))Y.push("当前模型 ID 无效")}if(Y.length>0)throw Error(`配置验证失败:
6
+ `;if(await n6.writeFile(Y,Q,"utf-8"),$)console.log("[ConfigManager] Added .blade/settings.local.json to .gitignore")}}catch(X){}}async loadJsonFile($){try{if(await this.fileExists($)){let Y=await n6.readFile($,"utf-8");return JSON.parse(Y)}}catch(Y){console.warn(`[ConfigManager] Failed to load ${$}:`,Y)}return null}async fileExists($){try{return await n6.access($),!0}catch{return!1}}validateConfig($){let Y=[];if(!$.models||$.models.length===0)Y.push("没有可用的模型配置");if($.models&&$.models.length>0){if(!$.currentModelId)Y.push("未设置当前模型 ID");else if(!$.models.find((X)=>X.id===$.currentModelId))Y.push("当前模型 ID 无效")}if(Y.length>0)throw Error(`配置验证失败:
7
7
  ${Y.map((Z)=>` - ${Z}`).join(`
8
8
  `)}
9
9
 
@@ -26,16 +26,16 @@ ${Y.map((Z)=>` - ${Z}`).join(`
26
26
  }
27
27
  ]
28
28
  }
29
- `)}}function R9($,Y={}){let Z={...$};if(Y.fallbackModel!==void 0)Z.fallbackModel=Y.fallbackModel;if(Y.debug!==void 0)Z.debug=Y.debug===""?!0:Y.debug;if(Y.yolo===!0)Z.permissionMode="yolo";else if(Y.permissionMode!==void 0)Z.permissionMode=Y.permissionMode;if(Y.maxTurns!==void 0)Z.maxTurns=Y.maxTurns;return Z.systemPrompt=Y.systemPrompt,Z.appendSystemPrompt=Y.appendSystemPrompt,Z.resumeSessionId=Y.sessionId,Z.forkSession=Y.forkSession,Z.allowedTools=Y.allowedTools,Z.disallowedTools=Y.disallowedTools,Z.mcpConfigPaths=Y.mcpConfig,Z.strictMcpConfig=Y.strictMcpConfig,Z.addDirs=Y.addDir,Z.outputFormat=Y.outputFormat,Z.inputFormat=Y.inputFormat,Z.print=Y.print,Z.includePartialMessages=Y.includePartialMessages,Z.replayUserMessages=Y.replayUserMessages,Z.agentsConfig=Y.agents,Z.settingSources=Y.settingSources,Z}var f3=b(()=>{b9();s1()});import{promises as _q}from"node:fs";import zq from"node:os";import h3 from"node:path";import Nq from"pino";async function Lq(){let $=h3.join(zq.homedir(),".blade","logs");return await _q.mkdir($,{recursive:!0}),h3.join($,"blade.log")}async function wq(){if(Q6)return Q6;if(J6)return J6;return J6=(async()=>{let $=await Lq();return Q6=Nq({level:"debug",transport:{target:"pino/file",options:{destination:$}}}),Q6})(),J6}function x3(){Q6=null,J6=null}class S0{static globalDebugConfig=null;enabled;minLevel;category;pinoLogger=null;constructor($={}){if($.enabled!==void 0)this.enabled=$.enabled;else if(S0.globalDebugConfig!==null)this.enabled=Boolean(S0.globalDebugConfig);else this.enabled=!1;this.minLevel=$.minLevel??0,this.category=$.category??"General",this.initPino()}async initPino(){try{let $=await wq();this.pinoLogger=$.child({category:this.category})}catch($){console.error("[Logger] Failed to initialize pino:",$)}}static setGlobalDebug($){S0.globalDebugConfig=$,x3()}static clearGlobalDebug(){S0.globalDebugConfig=null,x3()}setEnabled($){this.enabled=$}parseDebugFilter($){if(!$)return{enabled:!1};if($===!0||$==="true"||$==="1")return{enabled:!0};let Y=String($).trim();if(!Y)return{enabled:!0};if(Y.startsWith("!"))return{enabled:!0,filter:{mode:"exclude",categories:Y.split(",").map((Q)=>Q.trim().replace(/^!/,"")).filter(Boolean)}};return{enabled:!0,filter:{mode:"include",categories:Y.split(",").map((X)=>X.trim()).filter(Boolean)}}}shouldLogCategory($){if(!$)return!0;let Y=this.category.toLowerCase();if($.mode==="include")return $.categories.some((Z)=>Y.includes(Z.toLowerCase()));return!$.categories.some((Z)=>Y.includes(Z.toLowerCase()))}shouldLogToConsole($){if(S0.globalDebugConfig!==null){let{enabled:Y,filter:Z}=this.parseDebugFilter(S0.globalDebugConfig);if(!Y)return!1;if($<this.minLevel)return!1;return this.shouldLogCategory(Z)}return this.enabled&&$>=this.minLevel}log($,...Y){let Z=Y.map((X)=>typeof X==="object"?JSON.stringify(X):String(X)).join(" ");if(this.pinoLogger){let X=Bq[$];this.pinoLogger[X](Z)}if(this.shouldLogToConsole($)){let X=p3[$],Q=`[${this.category}] [${X}]`;console.error(Q,...Y)}}debug(...$){this.log(0,...$)}info(...$){this.log(1,...$)}warn(...$){this.log(2,...$)}error(...$){this.log(3,...$)}}function n($,Y){return new S0({...Y,category:$})}var p3,Bq,Q6=null,J6=null,Xz;var V1=b(()=>{((Q)=>{Q[Q.DEBUG=0]="DEBUG";Q[Q.INFO=1]="INFO";Q[Q.WARN=2]="WARN";Q[Q.ERROR=3]="ERROR"})(p3||={});Bq={[0]:"debug",[1]:"info",[2]:"warn",[3]:"error"};Xz=new S0({category:"General"})});import{Mutex as g3}from"async-mutex";import{merge as Aq}from"lodash-es";import{promises as a6}from"node:fs";import u3 from"node:os";import I2 from"node:path";import bq from"write-file-atomic";class F2{static instance=null;pendingUpdates=new Map;timers=new Map;fileLocks=new Map;lastSaveError=null;debounceDelay=300;constructor(){}static getInstance(){if(!F2.instance)F2.instance=new F2;return F2.instance}static resetInstance(){if(F2.instance)for(let $ of F2.instance.timers.values())clearTimeout($);F2.instance=null}async save($,Y={}){this.validatePersistableFields($);let Z=this.groupUpdatesByTarget($,Y.scope);if(Y.immediate)await Promise.all(Array.from(Z.entries()).map(([X,Q])=>this.flushTarget(X,Q)));else for(let[X,Q]of Z)this.scheduleSave(X,Q)}async flush(){for(let Y of this.timers.values())clearTimeout(Y);this.timers.clear();let $=Array.from(this.pendingUpdates.entries()).map(([Y,Z])=>this.flushTarget(Y,Z));this.pendingUpdates.clear(),await Promise.all($)}getLastSaveError(){return this.lastSaveError}clearLastSaveError(){this.lastSaveError=null}async appendPermissionRule($,Y={}){let Z=Y.scope??"local",X=this.resolveFilePath("settings",Z);await this.flushTargetWithModifier(X,(Q)=>{let J=Q.permissions??{allow:[],ask:[],deny:[]},q={allow:this.dedupeArray([...J.allow||[],$]),ask:J.ask||[],deny:J.deny||[]};return{...Q,permissions:q}})}async appendLocalPermissionRule($,Y={}){await this.appendPermissionRule($,{...Y,scope:"local"})}validatePersistableFields($){for(let Y of Object.keys($)){let Z=M2[Y];if(!Z)throw Error(`Unknown config field: ${Y}`);if(!Z.persistable)throw Error(`Field "${Y}" is non-persistable and cannot be saved to config files. Non-persistable fields are runtime-only and only valid for the current session.`)}}groupUpdatesByTarget($,Y){let Z=new Map;for(let[X,Q]of Object.entries($)){let J=M2[X];if(!J)continue;let q=Y??J.defaultScope,G=this.resolveFilePath(J.target,q);if(!Z.has(G))Z.set(G,{});Z.get(G)[X]=Q}return Z}resolveFilePath($,Y){if($==="config")return Y==="global"?I2.join(u3.homedir(),".blade","config.json"):I2.join(process.cwd(),".blade","config.json");switch(Y){case"local":return I2.join(process.cwd(),".blade","settings.local.json");case"project":return I2.join(process.cwd(),".blade","settings.json");case"global":return I2.join(u3.homedir(),".blade","settings.json");default:return I2.join(process.cwd(),".blade","settings.local.json")}}scheduleSave($,Y){let Z=this.pendingUpdates.get($)??{},X=this.mergePendingUpdates(Z,Y);this.pendingUpdates.set($,X);let Q=this.timers.get($);if(Q)clearTimeout(Q);let J=setTimeout(async()=>{let q=this.pendingUpdates.get($);if(q){this.pendingUpdates.delete($),this.timers.delete($);try{await this.flushTarget($,q),this.lastSaveError=null}catch(G){let K=G instanceof Error?G:Error(String(G));this.lastSaveError=K,m3.error(`Failed to save config to ${$}:`,K.message),m3.error("Stack trace:",K.stack)}}},this.debounceDelay);this.timers.set($,J)}mergePendingUpdates($,Y){let Z={...$};for(let[X,Q]of Object.entries(Y)){let J=M2[X];if(!J){Z[X]=Q;continue}switch(J.mergeStrategy){case"replace":Z[X]=Q;break;case"append-dedupe":this.applyAppendDedupe(Z,X,Q);break;case"deep-merge":this.applyDeepMerge(Z,X,Q);break}}return Z}async flushTarget($,Y){let Z=this.fileLocks.get($);if(!Z)Z=new g3,this.fileLocks.set($,Z);await Z.runExclusive(async()=>{await this.performWrite($,Y)})}async flushTargetWithModifier($,Y){let Z=this.fileLocks.get($);if(!Z)Z=new g3,this.fileLocks.set($,Z);await Z.runExclusive(async()=>{await a6.mkdir(I2.dirname($),{recursive:!0});let X={};try{let J=await a6.readFile($,"utf-8");X=JSON.parse(J)}catch{X={}}let Q=Y(X);await this.atomicWrite($,Q)})}async performWrite($,Y){await a6.mkdir(I2.dirname($),{recursive:!0});let Z={};try{let Q=await a6.readFile($,"utf-8");Z=JSON.parse(Q)}catch{Z={}}let X={...Z};for(let[Q,J]of Object.entries(Y)){let q=M2[Q];if(!q){X[Q]=J;continue}switch(q.mergeStrategy){case"replace":X[Q]=J;break;case"append-dedupe":this.applyAppendDedupe(X,Q,J);break;case"deep-merge":this.applyDeepMerge(X,Q,J);break}}await this.atomicWrite($,X)}applyAppendDedupe($,Y,Z){if(Y==="permissions"&&typeof Z==="object"&&Z!==null){let X=$[Y]??{allow:[],ask:[],deny:[]},Q=Z;$[Y]={allow:this.dedupeArray([...X.allow||[],...Q.allow||[]]),ask:this.dedupeArray([...X.ask||[],...Q.ask||[]]),deny:this.dedupeArray([...X.deny||[],...Q.deny||[]])}}else if(Array.isArray(Z)){let X=Array.isArray($[Y])?$[Y]:[];$[Y]=this.dedupeArray([...X,...Z])}else $[Y]=Z}applyDeepMerge($,Y,Z){if(typeof Z==="object"&&Z!==null&&!Array.isArray(Z)){let X=typeof $[Y]==="object"&&$[Y]!==null?$[Y]:{};$[Y]=Aq({},X,Z)}else $[Y]=Z}dedupeArray($){return Array.from(new Set($))}async atomicWrite($,Y){await bq($,JSON.stringify(Y,null,2),{mode:384,encoding:"utf-8"})}}function t1(){return F2.getInstance()}var m3,M2,Fz,Hz,_z,zz;var d3=b(()=>{V1();m3=n("Service"),M2={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},language:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},debug:{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:"project",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},fontSize:{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},fallbackModel:{target:"config",defaultScope:"global",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}},Fz=new Set(Object.entries(M2).filter(([$,Y])=>Y.persistable).map(([$])=>$)),Hz=new Set(Object.entries(M2).filter(([$,Y])=>!Y.persistable).map(([$])=>$)),_z=new Set(Object.entries(M2).filter(([$,Y])=>Y.target==="config").map(([$])=>$)),zz=new Set(Object.entries(M2).filter(([$,Y])=>Y.target==="settings").map(([$])=>$))});import q6 from"picomatch";class i2{config;constructor($){this.config=$}check($){let Y=i2.buildSignature($),Z=this.matchRules(Y,this.config.deny);if(Z)return{result:"deny",matchedRule:Z.rule,matchType:Z.type,reason:`工具调用被拒绝规则阻止: ${Z.rule}`};let X=this.matchRules(Y,this.config.allow);if(X)return{result:"allow",matchedRule:X.rule,matchType:X.type,reason:`工具调用符合允许规则: ${X.rule}`};let Q=this.matchRules(Y,this.config.ask);if(Q)return{result:"ask",matchedRule:Q.rule,matchType:Q.type,reason:`工具调用需要用户确认: ${Q.rule}`};return{result:"ask",reason:"工具调用未匹配任何规则,默认需要确认"}}static buildSignature($){let{toolName:Y,params:Z,tool:X}=$;try{if(X?.extractSignatureContent){let Q=X.extractSignatureContent(Z);return Q?`${Y}(${Q})`:Y}return Y}catch(Q){return console.warn(`Failed to build signature for ${Y}:`,Q instanceof Error?Q.message:Q),Y}}static abstractPattern($){let{toolName:Y,params:Z,tool:X}=$;try{if(X?.abstractPermissionRule){let Q=X.abstractPermissionRule(Z);if(Q==="")return"";return Q?`${Y}(${Q})`:Y}return Y}catch(Q){return console.warn(`Failed to abstract pattern for ${Y}:`,Q instanceof Error?Q.message:Q),Y}}matchRules($,Y){for(let Z of Y){let X=this.matchRule($,Z);if(X)return{rule:Z,type:X}}return null}matchRule($,Y){if($===Y)return"exact";if(Y==="*"||Y==="**")return"wildcard";let Z=this.extractToolName($),X=this.extractToolName(Y);if(!Z||!X)return null;if(X.includes("*")){if(!q6.isMatch(Z,X,{dot:!0,bash:!0}))return null}else if(Z!==X)return null;if(Y===X)return"prefix";if(Y.includes("*")){let Q=this.extractParams($),J=this.extractParams(Y);if(J==="*"||J==="**")return"wildcard";if(this.matchParams(Q,J))return J.includes("**")?"glob":"wildcard";if(q6.isMatch($,Y,{dot:!0,bash:!0}))return Y.includes("**")?"glob":"wildcard"}return null}extractParams($){let Y=$.match(/\(([\s\S]*)\)$/);return Y?Y[1]:""}matchParams($,Y){if(!$||!Y)return!1;let Z=this.parseParamPairs($),X=this.parseParamPairs(Y),Q=Object.keys(X).length>0,J=Object.keys(Z).length>0;if(Q!==J)return!1;if(!Q&&!J){if(Y==="*"||Y==="**")return!0;if(Y.includes("*")||Y.includes("{")||Y.includes("?"))return q6.isMatch($,Y,{dot:!0,bash:!0});return $===Y}for(let[q,G]of Object.entries(X)){let K=Z[q];if(K===void 0)return!1;if(G.includes("*")||G.includes("{")||G.includes("?")){if(G==="*"||G==="**")continue;if(!q6.isMatch(K,G,{dot:!0,bash:!0}))return!1}else if(K!==G)return!1}return!0}parseParamPairs($){let Y={},Z=this.smartSplit($,",");for(let X of Z){let Q=this.findTopLevelDelimiter(X,":");if(Q>0){let J=X.slice(0,Q).trim(),q=X.slice(Q+1).trim();Y[J]=q}}return Y}smartSplit($,Y){let Z=[],X="",Q=0,J=0,q=0,G=!1,K="",W=!1;for(let O=0;O<$.length;O++){let U=$[O];if(W){X+=U,W=!1;continue}if(U==="\\"){X+=U,W=!0;continue}if(!G&&U==="{")Q++;else if(!G&&U==="}")Q--;else if(!G&&U==="(")J++;else if(!G&&U===")")J--;else if(!G&&U==="[")q++;else if(!G&&U==="]")q--;if((U==='"'||U==="'")&&!G){G=!0,K=U,X+=U;continue}else if(G&&U===K){G=!1,K="",X+=U;continue}if(U===Y&&Q===0&&J===0&&q===0&&!G)Z.push(X.trim()),X="";else X+=U}if(X)Z.push(X.trim());return Z}findTopLevelDelimiter($,Y){let Z=0,X=0,Q=0,J=!1,q="",G=!1;for(let K=0;K<$.length;K++){let W=$[K];if(G){G=!1;continue}if(W==="\\"){G=!0;continue}if(!J&&W==="{")Z++;else if(!J&&W==="}")Z--;else if(!J&&W==="(")X++;else if(!J&&W===")")X--;else if(!J&&W==="[")Q++;else if(!J&&W==="]")Q--;if((W==='"'||W==="'")&&!J){J=!0,q=W;continue}else if(J&&W===q){J=!1,q="";continue}if(W===Y&&Z===0&&X===0&&Q===0&&!J)return K}return-1}extractToolName($){let Y=$.match(/^([A-Za-z0-9_]+)(\(|$)/);return Y?Y[1]:null}isAllowed($){return this.check($).result==="allow"}isDenied($){return this.check($).result==="deny"}needsConfirmation($){return this.check($).result==="ask"}updateConfig($){if($.allow)this.config.allow=[...this.config.allow,...$.allow];if($.ask)this.config.ask=[...this.config.ask,...$.ask];if($.deny)this.config.deny=[...this.config.deny,...$.deny]}replaceConfig($){this.config={...$}}getConfig(){return{...this.config}}}var V9=()=>{};var _$=b(()=>{f3();d3();b9();V9();s1()});var Vq,Dq,Iq,Mq,jq,yq,vq,Eq,Pq,Tq,kq,Sq,Cq,r0;var D9=b(()=>{Vq={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)"}},Dq={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)"}},Iq={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)"}},Mq={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)"}},jq={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)"}},yq={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)"}},vq={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)"}},Eq={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)"}},Pq={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)"}},Tq={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)"}},kq={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)"}},Sq={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)"}},Cq={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)"}},r0=[{id:"ayu-dark",label:"Ayu Dark",theme:Vq,tags:["dark","popular"]},{id:"dracula",label:"Dracula",theme:Dq,tags:["dark","popular"]},{id:"monokai",label:"Monokai",theme:Iq,tags:["dark","classic"]},{id:"nord",label:"Nord",theme:Mq,tags:["dark","minimal"]},{id:"solarized-light",label:"Solarized Light",theme:jq,tags:["light"]},{id:"solarized-dark",label:"Solarized Dark",theme:yq,tags:["dark"]},{id:"tokyo-night",label:"Tokyo Night",theme:vq,tags:["dark","popular"]},{id:"github",label:"GitHub",theme:Eq,tags:["light","minimal"]},{id:"gruvbox",label:"Gruvbox",theme:Pq,tags:["dark","warm"]},{id:"one-dark",label:"One Dark",theme:Tq,tags:["dark","popular"]},{id:"catppuccin",label:"Catppuccin",theme:kq,tags:["dark","pastel"]},{id:"rose-pine",label:"Rose Pine",theme:Sq,tags:["dark","elegant"]},{id:"kanagawa",label:"Kanagawa",theme:Cq,tags:["dark","japanese"]}]});function r6($){if(!$||typeof $!=="object")return!1;if(!$.name||typeof $.name!=="string")return!1;if(!$.colors||typeof $.colors!=="object")return!1;let Y=["primary","secondary","accent","success","warning","error","info","light","dark","muted","highlight"];for(let J of Y)if(!$.colors[J]||typeof $.colors[J]!=="string")return!1;if(!$.colors.text||typeof $.colors.text!=="object")return!1;if(!$.colors.background||typeof $.colors.background!=="object")return!1;if(!$.colors.border||typeof $.colors.border!=="object")return!1;let Z=["primary","secondary","muted","light"],X=["primary","secondary","dark"],Q=["light","dark"];for(let J of Z)if(!$.colors.text[J]||typeof $.colors.text[J]!=="string")return!1;for(let J of X)if(!$.colors.background[J]||typeof $.colors.background[J]!=="string")return!1;for(let J of Q)if(!$.colors.border[J]||typeof $.colors.border[J]!=="string")return!1;if(!$.spacing||typeof $.spacing!=="object")return!1;if(!$.typography||typeof $.typography!=="object")return!1;if(!$.borderRadius||typeof $.borderRadius!=="object")return!1;if(!$.boxShadow||typeof $.boxShadow!=="object")return!1;return!0}class I9{currentTheme=n6;themes=new Map;constructor(){this.themes.set("default",n6),this.themes.set("dark",l3);for(let $ of r0)this.themes.set($.id,$.theme)}setTheme($){let Y=this.themes.get($);if(Y)this.currentTheme=Y;else throw Error(`Theme '${$}' not found`)}getTheme(){return this.currentTheme}addTheme($,Y){if(!r6(Y))throw Error(`Invalid theme configuration for '${$}'`);this.themes.set($,Y)}getAvailableThemes(){return Array.from(this.themes.keys())}getCurrentThemeName(){return this.currentTheme.name}getThemeByName($){return this.themes.get($)}removeTheme($){if($==="default"||$==="dark"||r0.some((Z)=>Z.id===$))throw Error(`Cannot remove built-in theme '${$}'`);this.themes.delete($)}hasTheme($){return this.themes.has($)}validateTheme($){return r6($)}}var c3,n6,l3,j1;var H2=b(()=>{D9();c3={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"}},n6={name:"default",colors:c3,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)"}},l3={...n6,name:"dark",colors:{...c3,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"}}};j1=new I9});var fq,M9=($)=>({...fq,actions:{setInitializationStatus:(Y)=>{$((Z)=>({app:{...Z.app,initializationStatus:Y}}))},setInitializationError:(Y)=>{$((Z)=>({app:{...Z.app,initializationError:Y}}))},setActiveModal:(Y)=>{$((Z)=>({app:{...Z.app,activeModal:Y}}))},showSessionSelector:(Y)=>{$((Z)=>({app:{...Z.app,activeModal:"sessionSelector",sessionSelectorData:Y}}))},showModelEditWizard:(Y)=>{$((Z)=>({app:{...Z.app,activeModal:"modelEditWizard",modelEditorTarget:Y}}))},closeModal:()=>{$((Y)=>({app:{...Y.app,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null}}))},setTodos:(Y)=>{$((Z)=>({app:{...Z.app,todos:Y}}))},updateTodo:(Y)=>{$((Z)=>({app:{...Z.app,todos:Z.app.todos.map((X)=>X.id===Y.id?Y:X)}}))},setAwaitingSecondCtrlC:(Y)=>{$((Z)=>({app:{...Z.app,awaitingSecondCtrlC:Y}}))},setThinkingModeEnabled:(Y)=>{$((Z)=>({app:{...Z.app,thinkingModeEnabled:Y}}))},toggleThinkingMode:()=>{$((Y)=>({app:{...Y.app,thinkingModeEnabled:!Y.app.thinkingModeEnabled}}))}}});var i3=b(()=>{fq={initializationStatus:"idle",initializationError:null,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null,todos:[],awaitingSecondCtrlC:!1,thinkingModeEnabled:!1}});var hq,j9=($,Y)=>({...hq,actions:{setProcessing:(Z)=>{$((X)=>({command:{...X.command,isProcessing:Z}}))},createAbortController:()=>{let Z=Y().command.abortController;if(Z&&!Z.signal.aborted)return Z;let X=new AbortController;return $((Q)=>({command:{...Q.command,abortController:X}})),X},clearAbortController:()=>{$((Z)=>({command:{...Z.command,abortController:null}}))},abort:()=>{let{abortController:Z}=Y().command;if(Z&&!Z.signal.aborted)Z.abort();$((X)=>({command:{...X.command,isProcessing:!1,pendingCommands:[]}}))},enqueueCommand:(Z)=>{$((X)=>({command:{...X.command,pendingCommands:[...X.command.pendingCommands,Z]}}))},dequeueCommand:()=>{let{pendingCommands:Z}=Y().command;if(Z.length===0)return;let[X,...Q]=Z;return $((J)=>({command:{...J.command,pendingCommands:Q}})),X},clearQueue:()=>{$((Z)=>({command:{...Z.command,pendingCommands:[]}}))}}});var a3=b(()=>{hq={isProcessing:!1,abortController:null,pendingCommands:[]}});var xq,y9=($)=>({...xq,actions:{setConfig:(Y)=>{$((Z)=>({config:{...Z.config,config:Y}}))},updateConfig:(Y)=>{$((Z)=>{if(!Z.config.config)throw Error(`[ConfigSlice] Config not initialized. Cannot update: ${JSON.stringify(Y)}`);return{config:{...Z.config,config:{...Z.config.config,...Y}}}})}}});var r3=b(()=>{xq={config:null}});var pq,v9=($)=>({...pq,actions:{setFocus:(Y)=>{$((Z)=>({focus:{...Z.focus,currentFocus:Y,previousFocus:Z.focus.currentFocus}}))},restorePreviousFocus:()=>{$((Y)=>({focus:{...Y.focus,currentFocus:Y.focus.previousFocus||"main-input",previousFocus:null}}))}}});var n3=b(()=>{pq={currentFocus:"main-input",previousFocus:null}});import{nanoid as gq}from"nanoid";var s3,o3,E9=($,Y)=>({...o3,actions:{addMessage:(Z)=>{$((X)=>({session:{...X.session,messages:[...X.session.messages,Z],error:null}}))},addUserMessage:(Z)=>{let X={id:`user-${Date.now()}-${Math.random()}`,role:"user",content:Z,timestamp:Date.now()};Y().session.actions.addMessage(X)},addAssistantMessage:(Z,X)=>{let Q={id:`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:Z,timestamp:Date.now(),thinkingContent:X};Y().session.actions.addMessage(Q)},addAssistantMessageAndClearThinking:(Z)=>{let X=Y().session.currentThinkingContent,Q={id:`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:Z,timestamp:Date.now(),thinkingContent:X||void 0};$((J)=>({session:{...J.session,messages:[...J.session.messages,Q],currentThinkingContent:null,error:null}}))},addToolMessage:(Z,X)=>{let Q={id:`tool-${Date.now()}-${Math.random()}`,role:"tool",content:Z,timestamp:Date.now(),metadata:X};Y().session.actions.addMessage(Q)},setCompacting:(Z)=>{$((X)=>({session:{...X.session,isCompacting:Z}}))},setCommand:(Z)=>{$((X)=>({session:{...X.session,currentCommand:Z}}))},setError:(Z)=>{$((X)=>({session:{...X.session,error:Z}}))},clearMessages:()=>{$((Z)=>({session:{...Z.session,messages:[],error:null,clearCount:Z.session.clearCount+1}}))},resetSession:()=>{$((Z)=>({session:{...Z.session,...o3,sessionId:Z.session.sessionId,isActive:!0}}))},restoreSession:(Z,X)=>{$((Q)=>({session:{...Q.session,sessionId:Z,messages:X,error:null,isActive:!0}}))},updateTokenUsage:(Z)=>{$((X)=>({session:{...X.session,tokenUsage:{...X.session.tokenUsage,...Z}}}))},resetTokenUsage:()=>{$((Z)=>({session:{...Z.session,tokenUsage:{...s3}}}))},setCurrentThinkingContent:(Z)=>{$((X)=>({session:{...X.session,currentThinkingContent:Z}}))},appendThinkingContent:(Z)=>{$((X)=>({session:{...X.session,currentThinkingContent:(X.session.currentThinkingContent||"")+Z}}))},setThinkingExpanded:(Z)=>{$((X)=>({session:{...X.session,thinkingExpanded:Z}}))},toggleThinkingExpanded:()=>{$((Z)=>({session:{...Z.session,thinkingExpanded:!Z.session.thinkingExpanded}}))},setHistoryExpanded:(Z)=>{$((X)=>({session:{...X.session,historyExpanded:Z}}))},toggleHistoryExpanded:()=>{$((Z)=>({session:{...Z.session,historyExpanded:!Z.session.historyExpanded}}))},setExpandedMessageCount:(Z)=>{$((X)=>({session:{...X.session,expandedMessageCount:Z}}))},incrementClearCount:()=>{$((Z)=>({session:{...Z.session,clearCount:Z.session.clearCount+1}}))}}});var t3=b(()=>{s3={inputTokens:0,outputTokens:0,totalTokens:0,maxContextTokens:200000},o3={sessionId:gq(),messages:[],isCompacting:!1,currentCommand:null,error:null,isActive:!0,tokenUsage:{...s3},currentThinkingContent:null,thinkingExpanded:!1,clearCount:0,historyExpanded:!1,expandedMessageCount:30}});var e3=b(()=>{i3();a3();r3();n3();t3()});import{nanoid as uq}from"nanoid";import{devtools as mq,subscribeWithSelector as dq}from"zustand/middleware";import{createStore as cq}from"zustand/vanilla";async function o6(){if(C1()!==null)return;if(z$)return z$;return z$=(async()=>{try{let Z=await G0.getInstance().initialize();e().config.actions.setConfig(Z)}catch(Y){throw z$=null,Error(`❌ Store 未初始化且无法自动初始化
29
+ `)}}function I8($,Y={}){let Z={...$};if(Y.fallbackModel!==void 0)Z.fallbackModel=Y.fallbackModel;if(Y.debug!==void 0)Z.debug=Y.debug===""?!0:Y.debug;if(Y.yolo===!0)Z.permissionMode="yolo";else if(Y.permissionMode!==void 0)Z.permissionMode=Y.permissionMode;if(Y.maxTurns!==void 0)Z.maxTurns=Y.maxTurns;return Z.systemPrompt=Y.systemPrompt,Z.appendSystemPrompt=Y.appendSystemPrompt,Z.resumeSessionId=Y.sessionId,Z.forkSession=Y.forkSession,Z.allowedTools=Y.allowedTools,Z.disallowedTools=Y.disallowedTools,Z.mcpConfigPaths=Y.mcpConfig,Z.strictMcpConfig=Y.strictMcpConfig,Z.addDirs=Y.addDir,Z.outputFormat=Y.outputFormat,Z.inputFormat=Y.inputFormat,Z.print=Y.print,Z.includePartialMessages=Y.includePartialMessages,Z.replayUserMessages=Y.replayUserMessages,Z.agentsConfig=Y.agents,Z.settingSources=Y.settingSources,Z}var l3=b(()=>{D8();$0()});import{promises as Sq}from"node:fs";import kq from"node:os";import i3 from"node:path";import Cq from"pino";async function hq(){let $=i3.join(kq.homedir(),".blade","logs");return await Sq.mkdir($,{recursive:!0}),i3.join($,"blade.log")}async function xq(){if(K6)return K6;if(G6)return G6;return G6=(async()=>{let $=await hq();return K6=Cq({level:"debug",transport:{target:"pino/file",options:{destination:$}}}),K6})(),G6}function r3(){K6=null,G6=null}class h0{static globalDebugConfig=null;enabled;minLevel;category;pinoLogger=null;constructor($={}){if($.enabled!==void 0)this.enabled=$.enabled;else if(h0.globalDebugConfig!==null)this.enabled=Boolean(h0.globalDebugConfig);else this.enabled=!1;this.minLevel=$.minLevel??0,this.category=$.category??"General",this.initPino()}async initPino(){try{let $=await xq();this.pinoLogger=$.child({category:this.category})}catch($){console.error("[Logger] Failed to initialize pino:",$)}}static setGlobalDebug($){h0.globalDebugConfig=$,r3()}static clearGlobalDebug(){h0.globalDebugConfig=null,r3()}setEnabled($){this.enabled=$}parseDebugFilter($){if(!$)return{enabled:!1};if($===!0||$==="true"||$==="1")return{enabled:!0};let Y=String($).trim();if(!Y)return{enabled:!0};if(Y.startsWith("!"))return{enabled:!0,filter:{mode:"exclude",categories:Y.split(",").map((Q)=>Q.trim().replace(/^!/,"")).filter(Boolean)}};return{enabled:!0,filter:{mode:"include",categories:Y.split(",").map((X)=>X.trim()).filter(Boolean)}}}shouldLogCategory($){if(!$)return!0;let Y=this.category.toLowerCase();if($.mode==="include")return $.categories.some((Z)=>Y.includes(Z.toLowerCase()));return!$.categories.some((Z)=>Y.includes(Z.toLowerCase()))}shouldLogToConsole($){if(h0.globalDebugConfig!==null){let{enabled:Y,filter:Z}=this.parseDebugFilter(h0.globalDebugConfig);if(!Y)return!1;if($<this.minLevel)return!1;return this.shouldLogCategory(Z)}return this.enabled&&$>=this.minLevel}log($,...Y){let Z=Y.map((X)=>typeof X==="object"?JSON.stringify(X):String(X)).join(" ");if(this.pinoLogger){let X=fq[$];this.pinoLogger[X](Z)}if(this.shouldLogToConsole($)){let X=a3[$],Q=`[${this.category}] [${X}]`;console.error(Q,...Y)}}debug(...$){this.log(0,...$)}info(...$){this.log(1,...$)}warn(...$){this.log(2,...$)}error(...$){this.log(3,...$)}}function c($,Y){return new h0({...Y,category:$})}var a3,fq,K6=null,G6=null,IN;var w1=b(()=>{((Q)=>{Q[Q.DEBUG=0]="DEBUG";Q[Q.INFO=1]="INFO";Q[Q.WARN=2]="WARN";Q[Q.ERROR=3]="ERROR"})(a3||={});fq={[0]:"debug",[1]:"info",[2]:"warn",[3]:"error"};IN=new h0({category:"General"})});import{Mutex as n3}from"async-mutex";import{merge as pq}from"lodash-es";import{promises as o6}from"node:fs";import o3 from"node:os";import y2 from"node:path";import uq from"write-file-atomic";class N2{static instance=null;pendingUpdates=new Map;timers=new Map;fileLocks=new Map;lastSaveError=null;debounceDelay=300;constructor(){}static getInstance(){if(!N2.instance)N2.instance=new N2;return N2.instance}static resetInstance(){if(N2.instance)for(let $ of N2.instance.timers.values())clearTimeout($);N2.instance=null}async save($,Y={}){this.validatePersistableFields($);let Z=this.groupUpdatesByTarget($,Y.scope);if(Y.immediate)await Promise.all(Array.from(Z.entries()).map(([X,Q])=>this.flushTarget(X,Q)));else for(let[X,Q]of Z)this.scheduleSave(X,Q)}async flush(){for(let Y of this.timers.values())clearTimeout(Y);this.timers.clear();let $=Array.from(this.pendingUpdates.entries()).map(([Y,Z])=>this.flushTarget(Y,Z));this.pendingUpdates.clear(),await Promise.all($)}getLastSaveError(){return this.lastSaveError}clearLastSaveError(){this.lastSaveError=null}async appendPermissionRule($,Y={}){let Z=Y.scope??"local",X=this.resolveFilePath("settings",Z);await this.flushTargetWithModifier(X,(Q)=>{let J=Q.permissions??{allow:[],ask:[],deny:[]},q={allow:this.dedupeArray([...J.allow||[],$]),ask:J.ask||[],deny:J.deny||[]};return{...Q,permissions:q}})}async appendLocalPermissionRule($,Y={}){await this.appendPermissionRule($,{...Y,scope:"local"})}validatePersistableFields($){for(let Y of Object.keys($)){let Z=E2[Y];if(!Z)throw Error(`Unknown config field: ${Y}`);if(!Z.persistable)throw Error(`Field "${Y}" is non-persistable and cannot be saved to config files. Non-persistable fields are runtime-only and only valid for the current session.`)}}groupUpdatesByTarget($,Y){let Z=new Map;for(let[X,Q]of Object.entries($)){let J=E2[X];if(!J)continue;let q=Y??J.defaultScope,K=this.resolveFilePath(J.target,q);if(!Z.has(K))Z.set(K,{});Z.get(K)[X]=Q}return Z}resolveFilePath($,Y){if($==="config")return Y==="global"?y2.join(o3.homedir(),".blade","config.json"):y2.join(process.cwd(),".blade","config.json");switch(Y){case"local":return y2.join(process.cwd(),".blade","settings.local.json");case"project":return y2.join(process.cwd(),".blade","settings.json");case"global":return y2.join(o3.homedir(),".blade","settings.json");default:return y2.join(process.cwd(),".blade","settings.local.json")}}scheduleSave($,Y){let Z=this.pendingUpdates.get($)??{},X=this.mergePendingUpdates(Z,Y);this.pendingUpdates.set($,X);let Q=this.timers.get($);if(Q)clearTimeout(Q);let J=setTimeout(async()=>{let q=this.pendingUpdates.get($);if(q){this.pendingUpdates.delete($),this.timers.delete($);try{await this.flushTarget($,q),this.lastSaveError=null}catch(K){let G=K instanceof Error?K:Error(String(K));this.lastSaveError=G,s3.error(`Failed to save config to ${$}:`,G.message),s3.error("Stack trace:",G.stack)}}},this.debounceDelay);this.timers.set($,J)}mergePendingUpdates($,Y){let Z={...$};for(let[X,Q]of Object.entries(Y)){let J=E2[X];if(!J){Z[X]=Q;continue}switch(J.mergeStrategy){case"replace":Z[X]=Q;break;case"append-dedupe":this.applyAppendDedupe(Z,X,Q);break;case"deep-merge":this.applyDeepMerge(Z,X,Q);break}}return Z}async flushTarget($,Y){let Z=this.fileLocks.get($);if(!Z)Z=new n3,this.fileLocks.set($,Z);await Z.runExclusive(async()=>{await this.performWrite($,Y)})}async flushTargetWithModifier($,Y){let Z=this.fileLocks.get($);if(!Z)Z=new n3,this.fileLocks.set($,Z);await Z.runExclusive(async()=>{await o6.mkdir(y2.dirname($),{recursive:!0});let X={};try{let J=await o6.readFile($,"utf-8");X=JSON.parse(J)}catch{X={}}let Q=Y(X);await this.atomicWrite($,Q)})}async performWrite($,Y){await o6.mkdir(y2.dirname($),{recursive:!0});let Z={};try{let Q=await o6.readFile($,"utf-8");Z=JSON.parse(Q)}catch{Z={}}let X={...Z};for(let[Q,J]of Object.entries(Y)){let q=E2[Q];if(!q){X[Q]=J;continue}switch(q.mergeStrategy){case"replace":X[Q]=J;break;case"append-dedupe":this.applyAppendDedupe(X,Q,J);break;case"deep-merge":this.applyDeepMerge(X,Q,J);break}}await this.atomicWrite($,X)}applyAppendDedupe($,Y,Z){if(Y==="permissions"&&typeof Z==="object"&&Z!==null){let X=$[Y]??{allow:[],ask:[],deny:[]},Q=Z;$[Y]={allow:this.dedupeArray([...X.allow||[],...Q.allow||[]]),ask:this.dedupeArray([...X.ask||[],...Q.ask||[]]),deny:this.dedupeArray([...X.deny||[],...Q.deny||[]])}}else if(Array.isArray(Z)){let X=Array.isArray($[Y])?$[Y]:[];$[Y]=this.dedupeArray([...X,...Z])}else $[Y]=Z}applyDeepMerge($,Y,Z){if(typeof Z==="object"&&Z!==null&&!Array.isArray(Z)){let X=typeof $[Y]==="object"&&$[Y]!==null?$[Y]:{};$[Y]=pq({},X,Z)}else $[Y]=Z}dedupeArray($){return Array.from(new Set($))}async atomicWrite($,Y){await uq($,JSON.stringify(Y,null,2),{mode:384,encoding:"utf-8"})}}function Y0(){return N2.getInstance()}var s3,E2,kN,CN,fN,hN;var t3=b(()=>{w1();s3=c("Service"),E2={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},language:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},debug:{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:"project",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},fontSize:{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},fallbackModel:{target:"config",defaultScope:"global",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}},kN=new Set(Object.entries(E2).filter(([$,Y])=>Y.persistable).map(([$])=>$)),CN=new Set(Object.entries(E2).filter(([$,Y])=>!Y.persistable).map(([$])=>$)),fN=new Set(Object.entries(E2).filter(([$,Y])=>Y.target==="config").map(([$])=>$)),hN=new Set(Object.entries(E2).filter(([$,Y])=>Y.target==="settings").map(([$])=>$))});import U6 from"picomatch";class n2{config;constructor($){this.config=$}check($){let Y=n2.buildSignature($),Z=this.matchRules(Y,this.config.deny);if(Z)return{result:"deny",matchedRule:Z.rule,matchType:Z.type,reason:`工具调用被拒绝规则阻止: ${Z.rule}`};let X=this.matchRules(Y,this.config.allow);if(X)return{result:"allow",matchedRule:X.rule,matchType:X.type,reason:`工具调用符合允许规则: ${X.rule}`};let Q=this.matchRules(Y,this.config.ask);if(Q)return{result:"ask",matchedRule:Q.rule,matchType:Q.type,reason:`工具调用需要用户确认: ${Q.rule}`};return{result:"ask",reason:"工具调用未匹配任何规则,默认需要确认"}}static buildSignature($){let{toolName:Y,params:Z,tool:X}=$;try{if(X?.extractSignatureContent){let Q=X.extractSignatureContent(Z);return Q?`${Y}(${Q})`:Y}return Y}catch(Q){return console.warn(`Failed to build signature for ${Y}:`,Q instanceof Error?Q.message:Q),Y}}static abstractPattern($){let{toolName:Y,params:Z,tool:X}=$;try{if(X?.abstractPermissionRule){let Q=X.abstractPermissionRule(Z);if(Q==="")return"";return Q?`${Y}(${Q})`:Y}return Y}catch(Q){return console.warn(`Failed to abstract pattern for ${Y}:`,Q instanceof Error?Q.message:Q),Y}}matchRules($,Y){for(let Z of Y){let X=this.matchRule($,Z);if(X)return{rule:Z,type:X}}return null}matchRule($,Y){if($===Y)return"exact";if(Y==="*"||Y==="**")return"wildcard";let Z=this.extractToolName($),X=this.extractToolName(Y);if(!Z||!X)return null;if(X.includes("*")){if(!U6.isMatch(Z,X,{dot:!0,bash:!0}))return null}else if(Z!==X)return null;if(Y===X)return"prefix";if(Y.includes("*")){let Q=this.extractParams($),J=this.extractParams(Y);if(J==="*"||J==="**")return"wildcard";if(this.matchParams(Q,J))return J.includes("**")?"glob":"wildcard";if(U6.isMatch($,Y,{dot:!0,bash:!0}))return Y.includes("**")?"glob":"wildcard"}return null}extractParams($){let Y=$.match(/\(([\s\S]*)\)$/);return Y?Y[1]:""}matchParams($,Y){if(!$||!Y)return!1;let Z=this.parseParamPairs($),X=this.parseParamPairs(Y),Q=Object.keys(X).length>0,J=Object.keys(Z).length>0;if(Q!==J)return!1;if(!Q&&!J){if(Y==="*"||Y==="**")return!0;if(Y.includes("*")||Y.includes("{")||Y.includes("?"))return U6.isMatch($,Y,{dot:!0,bash:!0});return $===Y}for(let[q,K]of Object.entries(X)){let G=Z[q];if(G===void 0)return!1;if(K.includes("*")||K.includes("{")||K.includes("?")){if(K==="*"||K==="**")continue;if(!U6.isMatch(G,K,{dot:!0,bash:!0}))return!1}else if(G!==K)return!1}return!0}parseParamPairs($){let Y={},Z=this.smartSplit($,",");for(let X of Z){let Q=this.findTopLevelDelimiter(X,":");if(Q>0){let J=X.slice(0,Q).trim(),q=X.slice(Q+1).trim();Y[J]=q}}return Y}smartSplit($,Y){let Z=[],X="",Q=0,J=0,q=0,K=!1,G="",U=!1;for(let O=0;O<$.length;O++){let W=$[O];if(U){X+=W,U=!1;continue}if(W==="\\"){X+=W,U=!0;continue}if(!K&&W==="{")Q++;else if(!K&&W==="}")Q--;else if(!K&&W==="(")J++;else if(!K&&W===")")J--;else if(!K&&W==="[")q++;else if(!K&&W==="]")q--;if((W==='"'||W==="'")&&!K){K=!0,G=W,X+=W;continue}else if(K&&W===G){K=!1,G="",X+=W;continue}if(W===Y&&Q===0&&J===0&&q===0&&!K)Z.push(X.trim()),X="";else X+=W}if(X)Z.push(X.trim());return Z}findTopLevelDelimiter($,Y){let Z=0,X=0,Q=0,J=!1,q="",K=!1;for(let G=0;G<$.length;G++){let U=$[G];if(K){K=!1;continue}if(U==="\\"){K=!0;continue}if(!J&&U==="{")Z++;else if(!J&&U==="}")Z--;else if(!J&&U==="(")X++;else if(!J&&U===")")X--;else if(!J&&U==="[")Q++;else if(!J&&U==="]")Q--;if((U==='"'||U==="'")&&!J){J=!0,q=U;continue}else if(J&&U===q){J=!1,q="";continue}if(U===Y&&Z===0&&X===0&&Q===0&&!J)return G}return-1}extractToolName($){let Y=$.match(/^([A-Za-z0-9_]+)(\(|$)/);return Y?Y[1]:null}isAllowed($){return this.check($).result==="allow"}isDenied($){return this.check($).result==="deny"}needsConfirmation($){return this.check($).result==="ask"}updateConfig($){if($.allow)this.config.allow=[...this.config.allow,...$.allow];if($.ask)this.config.ask=[...this.config.ask,...$.ask];if($.deny)this.config.deny=[...this.config.deny,...$.deny]}replaceConfig($){this.config={...$}}getConfig(){return{...this.config}}}var M8=()=>{};var _$=b(()=>{l3();t3();D8();M8();$0()});var dq,mq,cq,lq,iq,rq,aq,nq,oq,sq,tq,eq,$K,s0;var j8=b(()=>{dq={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)"}},mq={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)"}},cq={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)"}},lq={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)"}},iq={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)"}},rq={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)"}},aq={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)"}},nq={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)"}},oq={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)"}},sq={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)"}},tq={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)"}},eq={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)"}},$K={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)"}},s0=[{id:"ayu-dark",label:"Ayu Dark",theme:dq,tags:["dark","popular"]},{id:"dracula",label:"Dracula",theme:mq,tags:["dark","popular"]},{id:"monokai",label:"Monokai",theme:cq,tags:["dark","classic"]},{id:"nord",label:"Nord",theme:lq,tags:["dark","minimal"]},{id:"solarized-light",label:"Solarized Light",theme:iq,tags:["light"]},{id:"solarized-dark",label:"Solarized Dark",theme:rq,tags:["dark"]},{id:"tokyo-night",label:"Tokyo Night",theme:aq,tags:["dark","popular"]},{id:"github",label:"GitHub",theme:nq,tags:["light","minimal"]},{id:"gruvbox",label:"Gruvbox",theme:oq,tags:["dark","warm"]},{id:"one-dark",label:"One Dark",theme:sq,tags:["dark","popular"]},{id:"catppuccin",label:"Catppuccin",theme:tq,tags:["dark","pastel"]},{id:"rose-pine",label:"Rose Pine",theme:eq,tags:["dark","elegant"]},{id:"kanagawa",label:"Kanagawa",theme:$K,tags:["dark","japanese"]}]});function s6($){if(!$||typeof $!=="object")return!1;if(!$.name||typeof $.name!=="string")return!1;if(!$.colors||typeof $.colors!=="object")return!1;let Y=["primary","secondary","accent","success","warning","error","info","light","dark","muted","highlight"];for(let J of Y)if(!$.colors[J]||typeof $.colors[J]!=="string")return!1;if(!$.colors.text||typeof $.colors.text!=="object")return!1;if(!$.colors.background||typeof $.colors.background!=="object")return!1;if(!$.colors.border||typeof $.colors.border!=="object")return!1;let Z=["primary","secondary","muted","light"],X=["primary","secondary","dark"],Q=["light","dark"];for(let J of Z)if(!$.colors.text[J]||typeof $.colors.text[J]!=="string")return!1;for(let J of X)if(!$.colors.background[J]||typeof $.colors.background[J]!=="string")return!1;for(let J of Q)if(!$.colors.border[J]||typeof $.colors.border[J]!=="string")return!1;if(!$.spacing||typeof $.spacing!=="object")return!1;if(!$.typography||typeof $.typography!=="object")return!1;if(!$.borderRadius||typeof $.borderRadius!=="object")return!1;if(!$.boxShadow||typeof $.boxShadow!=="object")return!1;return!0}class y8{currentTheme=t6;themes=new Map;constructor(){this.themes.set("default",t6),this.themes.set("dark",$5);for(let $ of s0)this.themes.set($.id,$.theme)}setTheme($){let Y=this.themes.get($);if(Y)this.currentTheme=Y;else throw Error(`Theme '${$}' not found`)}getTheme(){return this.currentTheme}addTheme($,Y){if(!s6(Y))throw Error(`Invalid theme configuration for '${$}'`);this.themes.set($,Y)}getAvailableThemes(){return Array.from(this.themes.keys())}getCurrentThemeName(){return this.currentTheme.name}getThemeByName($){return this.themes.get($)}removeTheme($){if($==="default"||$==="dark"||s0.some((Z)=>Z.id===$))throw Error(`Cannot remove built-in theme '${$}'`);this.themes.delete($)}hasTheme($){return this.themes.has($)}validateTheme($){return s6($)}}var e3,t6,$5,P1;var B2=b(()=>{j8();e3={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"}},t6={name:"default",colors:e3,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)"}},$5={...t6,name:"dark",colors:{...e3,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"}}};P1=new y8});var YK,E8=($)=>({...YK,actions:{setInitializationStatus:(Y)=>{$((Z)=>({app:{...Z.app,initializationStatus:Y}}))},setInitializationError:(Y)=>{$((Z)=>({app:{...Z.app,initializationError:Y}}))},setActiveModal:(Y)=>{$((Z)=>({app:{...Z.app,activeModal:Y}}))},showSessionSelector:(Y)=>{$((Z)=>({app:{...Z.app,activeModal:"sessionSelector",sessionSelectorData:Y}}))},showModelEditWizard:(Y)=>{$((Z)=>({app:{...Z.app,activeModal:"modelEditWizard",modelEditorTarget:Y}}))},closeModal:()=>{$((Y)=>({app:{...Y.app,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null}}))},setTodos:(Y)=>{$((Z)=>({app:{...Z.app,todos:Y}}))},updateTodo:(Y)=>{$((Z)=>({app:{...Z.app,todos:Z.app.todos.map((X)=>X.id===Y.id?Y:X)}}))},setAwaitingSecondCtrlC:(Y)=>{$((Z)=>({app:{...Z.app,awaitingSecondCtrlC:Y}}))},setThinkingModeEnabled:(Y)=>{$((Z)=>({app:{...Z.app,thinkingModeEnabled:Y}}))},toggleThinkingMode:()=>{$((Y)=>({app:{...Y.app,thinkingModeEnabled:!Y.app.thinkingModeEnabled}}))}}});var Y5=b(()=>{YK={initializationStatus:"idle",initializationError:null,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null,todos:[],awaitingSecondCtrlC:!1,thinkingModeEnabled:!1}});var ZK,v8=($,Y)=>({...ZK,actions:{setProcessing:(Z)=>{$((X)=>({command:{...X.command,isProcessing:Z}}))},createAbortController:()=>{let Z=Y().command.abortController;if(Z&&!Z.signal.aborted)return Z;let X=new AbortController;return $((Q)=>({command:{...Q.command,abortController:X}})),X},clearAbortController:()=>{$((Z)=>({command:{...Z.command,abortController:null}}))},abort:()=>{let{abortController:Z}=Y().command;if(Z&&!Z.signal.aborted)Z.abort();$((X)=>({command:{...X.command,isProcessing:!1,pendingCommands:[]}}))},enqueueCommand:(Z)=>{$((X)=>({command:{...X.command,pendingCommands:[...X.command.pendingCommands,Z]}}))},dequeueCommand:()=>{let{pendingCommands:Z}=Y().command;if(Z.length===0)return;let[X,...Q]=Z;return $((J)=>({command:{...J.command,pendingCommands:Q}})),X},clearQueue:()=>{$((Z)=>({command:{...Z.command,pendingCommands:[]}}))}}});var Z5=b(()=>{ZK={isProcessing:!1,abortController:null,pendingCommands:[]}});var XK,P8=($)=>({...XK,actions:{setConfig:(Y)=>{$((Z)=>({config:{...Z.config,config:Y}}))},updateConfig:(Y)=>{$((Z)=>{if(!Z.config.config)throw Error(`[ConfigSlice] Config not initialized. Cannot update: ${JSON.stringify(Y)}`);return{config:{...Z.config,config:{...Z.config.config,...Y}}}})}}});var X5=b(()=>{XK={config:null}});var QK,T8=($)=>({...QK,actions:{setFocus:(Y)=>{$((Z)=>({focus:{...Z.focus,currentFocus:Y,previousFocus:Z.focus.currentFocus}}))},restorePreviousFocus:()=>{$((Y)=>({focus:{...Y.focus,currentFocus:Y.focus.previousFocus||"main-input",previousFocus:null}}))}}});var Q5=b(()=>{QK={currentFocus:"main-input",previousFocus:null}});import{nanoid as JK}from"nanoid";var q5,J5,S8=($,Y)=>({...J5,actions:{addMessage:(Z)=>{$((X)=>({session:{...X.session,messages:[...X.session.messages,Z],error:null}}))},addUserMessage:(Z)=>{let X={id:`user-${Date.now()}-${Math.random()}`,role:"user",content:Z,timestamp:Date.now()};Y().session.actions.addMessage(X)},addAssistantMessage:(Z,X)=>{let Q={id:`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:Z,timestamp:Date.now(),thinkingContent:X};Y().session.actions.addMessage(Q)},addAssistantMessageAndClearThinking:(Z)=>{let X=Y().session.currentThinkingContent,Q={id:`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:Z,timestamp:Date.now(),thinkingContent:X||void 0};$((J)=>({session:{...J.session,messages:[...J.session.messages,Q],currentThinkingContent:null,error:null}}))},addToolMessage:(Z,X)=>{let Q={id:`tool-${Date.now()}-${Math.random()}`,role:"tool",content:Z,timestamp:Date.now(),metadata:X};Y().session.actions.addMessage(Q)},setCompacting:(Z)=>{$((X)=>({session:{...X.session,isCompacting:Z}}))},setCommand:(Z)=>{$((X)=>({session:{...X.session,currentCommand:Z}}))},setError:(Z)=>{$((X)=>({session:{...X.session,error:Z}}))},clearMessages:()=>{$((Z)=>({session:{...Z.session,messages:[],error:null,clearCount:Z.session.clearCount+1}}))},resetSession:()=>{$((Z)=>({session:{...Z.session,...J5,sessionId:Z.session.sessionId,isActive:!0}}))},restoreSession:(Z,X)=>{$((Q)=>({session:{...Q.session,sessionId:Z,messages:X,error:null,isActive:!0}}))},updateTokenUsage:(Z)=>{$((X)=>({session:{...X.session,tokenUsage:{...X.session.tokenUsage,...Z}}}))},resetTokenUsage:()=>{$((Z)=>({session:{...Z.session,tokenUsage:{...q5}}}))},setCurrentThinkingContent:(Z)=>{$((X)=>({session:{...X.session,currentThinkingContent:Z}}))},appendThinkingContent:(Z)=>{$((X)=>({session:{...X.session,currentThinkingContent:(X.session.currentThinkingContent||"")+Z}}))},setThinkingExpanded:(Z)=>{$((X)=>({session:{...X.session,thinkingExpanded:Z}}))},toggleThinkingExpanded:()=>{$((Z)=>({session:{...Z.session,thinkingExpanded:!Z.session.thinkingExpanded}}))},setHistoryExpanded:(Z)=>{$((X)=>({session:{...X.session,historyExpanded:Z}}))},toggleHistoryExpanded:()=>{$((Z)=>({session:{...Z.session,historyExpanded:!Z.session.historyExpanded}}))},setExpandedMessageCount:(Z)=>{$((X)=>({session:{...X.session,expandedMessageCount:Z}}))},incrementClearCount:()=>{$((Z)=>({session:{...Z.session,clearCount:Z.session.clearCount+1}}))}}});var K5=b(()=>{q5={inputTokens:0,outputTokens:0,totalTokens:0,maxContextTokens:200000},J5={sessionId:JK(),messages:[],isCompacting:!1,currentCommand:null,error:null,isActive:!0,tokenUsage:{...q5},currentThinkingContent:null,thinkingExpanded:!1,clearCount:0,historyExpanded:!1,expandedMessageCount:30}});var G5=b(()=>{Y5();Z5();X5();Q5();K5()});import{nanoid as qK}from"nanoid";import{devtools as KK,subscribeWithSelector as GK}from"zustand/middleware";import{createStore as UK}from"zustand/vanilla";async function e6(){if(x1()!==null)return;if(L$)return L$;return L$=(async()=>{try{let Z=await W0.getInstance().initialize();$1().config.actions.setConfig(Z)}catch(Y){throw L$=null,Error(`❌ Store 未初始化且无法自动初始化
30
30
 
31
31
  `+`原因: ${Y instanceof Error?Y.message:"未知错误"}
32
32
 
33
33
  `+`请确保:
34
34
  `+`1. 配置文件格式正确 (~/.blade/config.json)
35
35
  `+`2. 运行 blade 进行首次配置
36
- `+"3. 配置文件权限正确")}finally{z$=null}})(),z$}var G6,e=()=>G6.getState(),lq,_0=()=>e().session.actions,C0=()=>e().app.actions,$5=()=>e().session.messages,C1=()=>e().config.config,z$=null,K6=()=>e().config.config?.models??[],N$=()=>{let $=C1();if(!$)return;let Y=$.currentModelId;return $.models.find((X)=>X.id===Y)??$.models[0]},A0=()=>e().config.config?.mcpServers??{},A1=()=>({setPermissionMode:async($)=>{e().config.actions.updateConfig({permissionMode:$})},setTheme:async($,Y={})=>{try{j1.setTheme($)}catch{return}e().config.actions.updateConfig({theme:$}),await t1().save({theme:$},{scope:"global",...Y})},setLanguage:async($,Y={})=>{e().config.actions.updateConfig({language:$}),await t1().save({language:$},{scope:"global",...Y})},setDebug:async($,Y={})=>{e().config.actions.updateConfig({debug:$}),await t1().save({debug:$},{scope:"global",...Y})},setTemperature:async($,Y={})=>{e().config.actions.updateConfig({temperature:$}),await t1().save({temperature:$},{scope:"global",...Y})},updateConfig:async($,Y={})=>{let Z=C1();if(!Z)throw Error("Config not initialized");let X={...Z};e().config.actions.updateConfig($);try{await t1().save($,Y)}catch(Q){throw e().config.actions.setConfig(X),Q}},flush:async()=>{await t1().flush()},appendPermissionAllowRule:async($,Y={})=>{let Z=C1();if(!Z)throw Error("Config not initialized");let X=Z.permissions?.allow||[];if(!X.includes($)){let Q=[...X,$];e().config.actions.updateConfig({permissions:{...Z.permissions,allow:Q}})}await t1().appendPermissionRule($,Y)},appendLocalPermissionAllowRule:async($,Y={})=>{let Z=C1();if(!Z)throw Error("Config not initialized");let X=Z.permissions?.allow||[];if(!X.includes($)){let Q=[...X,$];e().config.actions.updateConfig({permissions:{...Z.permissions,allow:Q}})}await t1().appendLocalPermissionRule($,Y)},setCurrentModel:async($,Y={})=>{let Z=C1();if(!Z)throw Error("Config not initialized");if(!Z.models.find((Q)=>Q.id===$))throw Error(`Model not found: ${$}`);e().config.actions.updateConfig({currentModelId:$}),await t1().save({currentModelId:$},{scope:"global",...Y})},addModel:async($,Y={})=>{let Z=C1();if(!Z)throw Error("Config not initialized");let X="id"in $?$:{id:uq(),...$},J={models:[...Z.models,X]};if(Z.models.length===0)J.currentModelId=X.id;return e().config.actions.updateConfig(J),await t1().save(J,{scope:"global",...Y}),X},updateModel:async($,Y,Z={})=>{let X=C1();if(!X)throw Error("Config not initialized");let Q=X.models.findIndex((q)=>q.id===$);if(Q===-1)throw Error(`Model not found: ${$}`);let J=[...X.models];J[Q]={...J[Q],...Y},e().config.actions.updateConfig({models:J}),await t1().save({models:J},{scope:"global",...Z})},removeModel:async($,Y={})=>{let Z=C1();if(!Z)throw Error("Config not initialized");if(Z.models.length===1)throw Error("Cannot remove the only model");let X=Z.models.filter((J)=>J.id!==$),Q={models:X};if(Z.currentModelId===$)Q.currentModelId=X[0].id;e().config.actions.updateConfig(Q),await t1().save(Q,{scope:"global",...Y})},addMcpServer:async($,Y,Z={})=>{let X=C1();if(!X)throw Error("Config not initialized");let J={...X.mcpServers??{},[$]:Y};e().config.actions.updateConfig({mcpServers:J}),await t1().save({mcpServers:J},{scope:"project",...Z})},removeMcpServer:async($,Y={})=>{let Z=C1();if(!Z)throw Error("Config not initialized");let Q={...Z.mcpServers??{}};delete Q[$],e().config.actions.updateConfig({mcpServers:Q}),await t1().save({mcpServers:Q},{scope:"project",...Y})}});var N1=b(()=>{_$();H2();e3();G6=cq()(mq(dq((...$)=>({session:E9(...$),app:M9(...$),config:y9(...$),focus:v9(...$),command:j9(...$)})),{name:"BladeStore",enabled:!0})),lq=G6.subscribe});function U6($){return $==="readonly"}var n0=()=>{};class T9{toolName;params;context;aborted=!1;result;_internal={};constructor($,Y,Z){this.toolName=$;this.params=Y;this.context=Z}shouldAbort(){return this.aborted||(this.context.signal?.aborted??!1)}abort($,Y){this.aborted=!0,this.result={success:!1,llmContent:`Tool execution aborted: ${$||"Unknown reason"}`,displayContent:`执行已中止: ${$||"未知原因"}`,error:{type:"execution_error",message:$||"Execution aborted"},metadata:Y?.shouldExitLoop?{shouldExitLoop:!0}:void 0}}setResult($){this.result=$}getResult(){if(!this.result)throw Error("Tool execution result not set");return this.result}}var k9=b(()=>{n0()});var e1=b(()=>{k9();n0()});function iq($){let{code:Y}=$,Z=$.received;switch(Y){case"invalid_type":return`类型错误:期望 ${$.expected},实际收到 ${Z}`;case"too_small":{let{minimum:X,inclusive:Q}=$;if($.type==="string")return`长度不能少于 ${X} 个字符`;if($.type==="number")return`不能小于${Q?"等于":""} ${X}`;if($.type==="array")return`数组长度不能少于 ${X}`;return"值太小"}case"too_big":{let{maximum:X,inclusive:Q}=$;if($.type==="string")return`长度不能超过 ${X} 个字符`;if($.type==="number")return`不能大于${Q?"等于":""} ${X}`;if($.type==="array")return`数组长度不能超过 ${X}`;return"值太大"}case"invalid_string":{let X=$.validation;if(X==="email")return"必须是有效的电子邮件地址";if(X==="url")return"必须是有效的 URL";if(X==="uuid")return"必须是有效的 UUID";if(typeof X==="object"&&X.includes)return`必须包含 "${X.includes}"`;if(typeof X==="object"&&X.startsWith)return`必须以 "${X.startsWith}" 开头`;if(typeof X==="object"&&X.endsWith)return`必须以 "${X.endsWith}" 结尾`;return"字符串格式不正确"}case"invalid_enum_value":return`必须是以下值之一:${$.options.join(", ")}`;case"invalid_literal":return`必须是字面量值:${$.expected}`;case"unrecognized_keys":return`包含未知的参数:${$.keys.join(", ")}`;case"invalid_union":return"不符合任何有效的类型定义";case"invalid_date":return"必须是有效的日期";case"custom":return $.message||"自定义验证失败";default:return $.message||"验证失败"}}function aq($){let Y=$.issues.map((X)=>{let Q=X.path.join("."),J=iq(X),q=X.received;return{field:Q||"root",message:J,value:q}}),Z=Y.length===1?`参数验证失败 [${Y[0].field}]: ${Y[0].message}`:`参数验证失败 (${Y.length} 个错误):
36
+ `+"3. 配置文件权限正确")}finally{L$=null}})(),L$}var W6,$1=()=>W6.getState(),WK,_0=()=>$1().session.actions,x0=()=>$1().app.actions,U5=()=>$1().session.messages,x1=()=>$1().config.config,L$=null,O6=()=>$1().config.config?.models??[],w$=()=>{let $=x1();if(!$)return;let Y=$.currentModelId;return $.models.find((X)=>X.id===Y)??$.models[0]},V0=()=>$1().config.config?.mcpServers??{},D1=()=>({setPermissionMode:async($)=>{$1().config.actions.updateConfig({permissionMode:$})},setTheme:async($,Y={})=>{try{P1.setTheme($)}catch{return}$1().config.actions.updateConfig({theme:$}),await Y0().save({theme:$},{scope:"global",...Y})},setLanguage:async($,Y={})=>{$1().config.actions.updateConfig({language:$}),await Y0().save({language:$},{scope:"global",...Y})},setDebug:async($,Y={})=>{$1().config.actions.updateConfig({debug:$}),await Y0().save({debug:$},{scope:"global",...Y})},setTemperature:async($,Y={})=>{$1().config.actions.updateConfig({temperature:$}),await Y0().save({temperature:$},{scope:"global",...Y})},updateConfig:async($,Y={})=>{let Z=x1();if(!Z)throw Error("Config not initialized");let X={...Z};$1().config.actions.updateConfig($);try{await Y0().save($,Y)}catch(Q){throw $1().config.actions.setConfig(X),Q}},flush:async()=>{await Y0().flush()},appendPermissionAllowRule:async($,Y={})=>{let Z=x1();if(!Z)throw Error("Config not initialized");let X=Z.permissions?.allow||[];if(!X.includes($)){let Q=[...X,$];$1().config.actions.updateConfig({permissions:{...Z.permissions,allow:Q}})}await Y0().appendPermissionRule($,Y)},appendLocalPermissionAllowRule:async($,Y={})=>{let Z=x1();if(!Z)throw Error("Config not initialized");let X=Z.permissions?.allow||[];if(!X.includes($)){let Q=[...X,$];$1().config.actions.updateConfig({permissions:{...Z.permissions,allow:Q}})}await Y0().appendLocalPermissionRule($,Y)},setCurrentModel:async($,Y={})=>{let Z=x1();if(!Z)throw Error("Config not initialized");if(!Z.models.find((Q)=>Q.id===$))throw Error(`Model not found: ${$}`);$1().config.actions.updateConfig({currentModelId:$}),await Y0().save({currentModelId:$},{scope:"global",...Y})},addModel:async($,Y={})=>{let Z=x1();if(!Z)throw Error("Config not initialized");let X="id"in $?$:{id:qK(),...$},J={models:[...Z.models,X]};if(Z.models.length===0)J.currentModelId=X.id;return $1().config.actions.updateConfig(J),await Y0().save(J,{scope:"global",...Y}),X},updateModel:async($,Y,Z={})=>{let X=x1();if(!X)throw Error("Config not initialized");let Q=X.models.findIndex((q)=>q.id===$);if(Q===-1)throw Error(`Model not found: ${$}`);let J=[...X.models];J[Q]={...J[Q],...Y},$1().config.actions.updateConfig({models:J}),await Y0().save({models:J},{scope:"global",...Z})},removeModel:async($,Y={})=>{let Z=x1();if(!Z)throw Error("Config not initialized");if(Z.models.length===1)throw Error("Cannot remove the only model");let X=Z.models.filter((J)=>J.id!==$),Q={models:X};if(Z.currentModelId===$)Q.currentModelId=X[0].id;$1().config.actions.updateConfig(Q),await Y0().save(Q,{scope:"global",...Y})},addMcpServer:async($,Y,Z={})=>{let X=x1();if(!X)throw Error("Config not initialized");let J={...X.mcpServers??{},[$]:Y};$1().config.actions.updateConfig({mcpServers:J}),await Y0().save({mcpServers:J},{scope:"project",...Z})},removeMcpServer:async($,Y={})=>{let Z=x1();if(!Z)throw Error("Config not initialized");let Q={...Z.mcpServers??{}};delete Q[$],$1().config.actions.updateConfig({mcpServers:Q}),await Y0().save({mcpServers:Q},{scope:"project",...Y})}});var A1=b(()=>{_$();B2();G5();W6=UK()(KK(GK((...$)=>({session:S8(...$),app:E8(...$),config:P8(...$),focus:T8(...$),command:v8(...$)})),{name:"BladeStore",enabled:!0})),WK=W6.subscribe});function F6($){return $==="readonly"}var t0=()=>{};class C8{toolName;params;context;aborted=!1;result;_internal={};constructor($,Y,Z){this.toolName=$;this.params=Y;this.context=Z}shouldAbort(){return this.aborted||(this.context.signal?.aborted??!1)}abort($,Y){this.aborted=!0,this.result={success:!1,llmContent:`Tool execution aborted: ${$||"Unknown reason"}`,displayContent:`执行已中止: ${$||"未知原因"}`,error:{type:"execution_error",message:$||"Execution aborted"},metadata:Y?.shouldExitLoop?{shouldExitLoop:!0}:void 0}}setResult($){this.result=$}getResult(){if(!this.result)throw Error("Tool execution result not set");return this.result}}var f8=b(()=>{t0()});var Z0=b(()=>{f8();t0()});function OK($){let{code:Y}=$,Z=$.received;switch(Y){case"invalid_type":return`类型错误:期望 ${$.expected},实际收到 ${Z}`;case"too_small":{let{minimum:X,inclusive:Q}=$;if($.type==="string")return`长度不能少于 ${X} 个字符`;if($.type==="number")return`不能小于${Q?"等于":""} ${X}`;if($.type==="array")return`数组长度不能少于 ${X}`;return"值太小"}case"too_big":{let{maximum:X,inclusive:Q}=$;if($.type==="string")return`长度不能超过 ${X} 个字符`;if($.type==="number")return`不能大于${Q?"等于":""} ${X}`;if($.type==="array")return`数组长度不能超过 ${X}`;return"值太大"}case"invalid_string":{let X=$.validation;if(X==="email")return"必须是有效的电子邮件地址";if(X==="url")return"必须是有效的 URL";if(X==="uuid")return"必须是有效的 UUID";if(typeof X==="object"&&X.includes)return`必须包含 "${X.includes}"`;if(typeof X==="object"&&X.startsWith)return`必须以 "${X.startsWith}" 开头`;if(typeof X==="object"&&X.endsWith)return`必须以 "${X.endsWith}" 结尾`;return"字符串格式不正确"}case"invalid_enum_value":return`必须是以下值之一:${$.options.join(", ")}`;case"invalid_literal":return`必须是字面量值:${$.expected}`;case"unrecognized_keys":return`包含未知的参数:${$.keys.join(", ")}`;case"invalid_union":return"不符合任何有效的类型定义";case"invalid_date":return"必须是有效的日期";case"custom":return $.message||"自定义验证失败";default:return $.message||"验证失败"}}function FK($){let Y=$.issues.map((X)=>{let Q=X.path.join("."),J=OK(X),q=X.received;return{field:Q||"root",message:J,value:q}}),Z=Y.length===1?`参数验证失败 [${Y[0].field}]: ${Y[0].message}`:`参数验证失败 (${Y.length} 个错误):
37
37
  ${Y.map((X)=>` - ${X.field}: ${X.message}`).join(`
38
- `)}`;return new q5(Z,Y)}function G5($,Y){let Z=$.safeParse(Y);if(!Z.success)throw aq(Z.error);return Z.data}var q5;var K5=b(()=>{e1();q5=class q5 extends Error{issues;type;constructor($,Y,Z="validation_error"){super($);this.issues=Y;this.type=Z;this.name="ToolValidationError"}}});import{zodToJsonSchema as rq}from"zod-to-json-schema";function S9($){return rq($,{target:"jsonSchema7",$refStrategy:"none"})}var U5=()=>{};class C9{toolName;params;executeFn;descriptionFn;affectedPathsFn;constructor($,Y,Z,X,Q){this.toolName=$;this.params=Y;this.executeFn=Z;this.descriptionFn=X;this.affectedPathsFn=Q}getDescription(){if(this.descriptionFn)return this.descriptionFn(this.params);return`执行工具: ${this.toolName}`}getAffectedPaths(){if(this.affectedPathsFn)return this.affectedPathsFn(this.params);return[]}async execute($,Y,Z){let X={signal:$,updateOutput:Y,...Z};return this.executeFn(this.params,X)}}function U1($){return{name:$.name,displayName:$.displayName,kind:$.kind,isReadOnly:$.isReadOnly??U6($.kind),isConcurrencySafe:$.isConcurrencySafe??!0,strict:$.strict??!1,description:$.description,version:$.version||"1.0.0",category:$.category,tags:$.tags||[],getFunctionDeclaration(){let Y=S9($.schema),Z=$.description.short;if($.description.long)Z+=`
38
+ `)}`;return new N5(Z,Y)}function B5($,Y){let Z=$.safeParse(Y);if(!Z.success)throw FK(Z.error);return Z.data}var N5;var _5=b(()=>{Z0();N5=class N5 extends Error{issues;type;constructor($,Y,Z="validation_error"){super($);this.issues=Y;this.type=Z;this.name="ToolValidationError"}}});import{zodToJsonSchema as HK}from"zod-to-json-schema";function h8($){return HK($,{target:"jsonSchema7",$refStrategy:"none"})}var L5=()=>{};class x8{toolName;params;executeFn;descriptionFn;affectedPathsFn;constructor($,Y,Z,X,Q){this.toolName=$;this.params=Y;this.executeFn=Z;this.descriptionFn=X;this.affectedPathsFn=Q}getDescription(){if(this.descriptionFn)return this.descriptionFn(this.params);return`执行工具: ${this.toolName}`}getAffectedPaths(){if(this.affectedPathsFn)return this.affectedPathsFn(this.params);return[]}async execute($,Y,Z){let X={signal:$,updateOutput:Y,...Z};return this.executeFn(this.params,X)}}function U1($){return{name:$.name,displayName:$.displayName,kind:$.kind,isReadOnly:$.isReadOnly??F6($.kind),isConcurrencySafe:$.isConcurrencySafe??!0,strict:$.strict??!1,description:$.description,version:$.version||"1.0.0",category:$.category,tags:$.tags||[],getFunctionDeclaration(){let Y=h8($.schema),Z=$.description.short;if($.description.long)Z+=`
39
39
 
40
40
  ${$.description.long}`;if($.description.usageNotes&&$.description.usageNotes.length>0)Z+=`
41
41
 
@@ -45,20 +45,20 @@ ${$.description.usageNotes.map((X)=>`- ${X}`).join(`
45
45
 
46
46
  Important:
47
47
  ${$.description.important.map((X)=>`⚠️ ${X}`).join(`
48
- `)}`;return{name:$.name,description:Z,parameters:Y}},getMetadata(){return{name:$.name,displayName:$.displayName,kind:$.kind,version:$.version||"1.0.0",category:$.category,tags:$.tags||[],description:$.description,schema:S9($.schema)}},build(Y){let Z=G5($.schema,Y);return new C9($.name,Z,$.execute)},async execute(Y,Z){return this.build(Y).execute(Z||new AbortController().signal)},extractSignatureContent:$.extractSignatureContent?(Y)=>$.extractSignatureContent(Y):void 0,abstractPermissionRule:$.abstractPermissionRule?(Y)=>$.abstractPermissionRule(Y):void 0}}var g1=b(()=>{n0();K5();U5()});import{z as b0}from"zod";function s6($,Y,Z,X){let Q;try{Q=W6(Z.inputSchema)}catch(q){console.warn(`[createMcpTool] Schema 转换失败,使用降级 schema: ${Z.name}`,q),Q=b0.any()}let J=X||Z.name;return U1({name:J,displayName:`${Y}: ${Z.name}`,kind:"execute",schema:Q,description:{short:Z.description||`MCP Tool: ${Z.name}`,important:[`From MCP server: ${Y}`,"Executes external tools; user confirmation required"]},category:"MCP tool",tags:["mcp","external",Y],async execute(q,G){try{let K=await $.callTool(Z.name,q),W="",O="";if(K.content&&Array.isArray(K.content)){for(let U of K.content)if(U.type==="text"&&U.text)W+=U.text,O+=U.text;else if(U.type==="image")O+=`[图片: ${U.mimeType||"unknown"}]
49
- `,W+=`[image: ${U.mimeType||"unknown"}]
50
- `;else if(U.type==="resource")O+=`[资源: ${U.mimeType||"unknown"}]
51
- `,W+=`[resource: ${U.mimeType||"unknown"}]
52
- `}if(K.isError)return{success:!1,llmContent:W||"MCP tool execution failed",displayContent:`❌ ${O||"MCP工具执行失败"}`,error:{type:"execution_error",message:W||"MCP tool execution failed"}};return{success:!0,llmContent:W||"Execution succeeded",displayContent:`✅ MCP工具 ${Z.name} 执行成功
53
- ${O}`,metadata:{serverName:Y,toolName:Z.name,mcpResult:K}}}catch(K){return{success:!1,llmContent:`MCP tool execution failed: ${K.message}`,displayContent:`❌ ${K.message}`,error:{type:"execution_error",message:K.message}}}}})}function W6($){if($.type==="object"||$.properties){let Y={},Z=$.required||[];if($.properties){for(let[X,Q]of Object.entries($.properties))if(typeof Q==="object"&&Q!==null){let J=W6(Q);if(!Z.includes(X))J=J.optional();Y[X]=J}}return b0.object(Y)}if($.type==="array"&&$.items){if(typeof $.items==="object"&&!Array.isArray($.items)&&$.items!==null)return b0.array(W6($.items));return b0.array(b0.any())}if($.type==="string"){let Y=b0.string();if($.minLength!==void 0)Y=Y.min($.minLength);if($.maxLength!==void 0)Y=Y.max($.maxLength);if($.pattern)Y=Y.regex(new RegExp($.pattern));if($.enum)return b0.enum($.enum);return Y}if($.type==="number"||$.type==="integer"){let Y=b0.number();if($.minimum!==void 0)Y=Y.min($.minimum);if($.maximum!==void 0)Y=Y.max($.maximum);return Y}if($.type==="boolean")return b0.boolean();if($.oneOf&&$.oneOf.length>0){let Y=$.oneOf.filter((Z)=>typeof Z==="object"&&Z!==null).map((Z)=>W6(Z));if(Y.length>=2)return b0.union(Y)}if($.anyOf&&$.anyOf.length>0){let Y=$.anyOf.filter((Z)=>typeof Z==="object"&&Z!==null).map((Z)=>W6(Z));if(Y.length>=2)return b0.union(Y)}return b0.any()}var W5=b(()=>{g1();e1()});import{promises as f9}from"fs";import nq from"os";import h9 from"path";class t6{tokenFilePath;constructor(){let $=nq.homedir(),Y=h9.join($,".blade");this.tokenFilePath=h9.join(Y,"mcp-oauth-tokens.json")}async ensureConfigDir(){let $=h9.dirname(this.tokenFilePath);try{await f9.mkdir($,{recursive:!0})}catch(Y){}}async loadAllCredentials(){let $=new Map;try{let Y=await f9.readFile(this.tokenFilePath,"utf-8"),Z=JSON.parse(Y);for(let X of Z)$.set(X.serverName,X)}catch(Y){if(Y.code!=="ENOENT")console.warn("[OAuthTokenStorage] 加载令牌失败:",Y)}return $}async saveAllCredentials($){await this.ensureConfigDir();let Y=Array.from($.values());await f9.writeFile(this.tokenFilePath,JSON.stringify(Y,null,2),{mode:384})}async saveToken($,Y,Z,X){let Q=await this.loadAllCredentials(),J={serverName:$,token:Y,clientId:Z,tokenUrl:X,updatedAt:Date.now()};Q.set($,J),await this.saveAllCredentials(Q)}async getCredentials($){return(await this.loadAllCredentials()).get($)||null}async deleteCredentials($){let Y=await this.loadAllCredentials();Y.delete($),await this.saveAllCredentials(Y)}async listServers(){let $=await this.loadAllCredentials();return Array.from($.keys())}isTokenExpired($){if(!$.expiresAt)return!1;let Y=300000;return Date.now()>=$.expiresAt-Y}}var x9=()=>{};import*as F6 from"crypto";import*as H5 from"http";import{spawn as oq}from"child_process";import{URL as O5}from"url";class e6{tokenStorage;constructor($=new t6){this.tokenStorage=$}generatePKCEParams(){let $=F6.randomBytes(32).toString("base64url"),Y=F6.createHash("sha256").update($).digest("base64url"),Z=F6.randomBytes(16).toString("base64url");return{codeVerifier:$,codeChallenge:Y,state:Z}}buildAuthorizationUrl($,Y){let Z=$.redirectUri||`http://localhost:${O6}${p9}`,X=new URLSearchParams({client_id:$.clientId,response_type:"code",redirect_uri:Z,state:Y.state,code_challenge:Y.codeChallenge,code_challenge_method:"S256"});if($.scopes&&$.scopes.length>0)X.append("scope",$.scopes.join(" "));let Q=new O5($.authorizationUrl);return X.forEach((J,q)=>{Q.searchParams.append(q,J)}),Q.toString()}async startCallbackServer($){return new Promise((Y,Z)=>{let X=H5.createServer((Q,J)=>{try{let q=new O5(Q.url,`http://localhost:${O6}`);if(q.pathname!==p9){J.writeHead(404),J.end("Not found");return}let G=q.searchParams.get("code"),K=q.searchParams.get("state"),W=q.searchParams.get("error");if(W){J.writeHead(F5,{"Content-Type":"text/html"}),J.end(`
48
+ `)}`;return{name:$.name,description:Z,parameters:Y}},getMetadata(){return{name:$.name,displayName:$.displayName,kind:$.kind,version:$.version||"1.0.0",category:$.category,tags:$.tags||[],description:$.description,schema:h8($.schema)}},build(Y){let Z=B5($.schema,Y);return new x8($.name,Z,$.execute)},async execute(Y,Z){return this.build(Y).execute(Z||new AbortController().signal)},extractSignatureContent:$.extractSignatureContent?(Y)=>$.extractSignatureContent(Y):void 0,abstractPermissionRule:$.abstractPermissionRule?(Y)=>$.abstractPermissionRule(Y):void 0}}var m1=b(()=>{t0();_5();L5()});import{z as D0}from"zod";function $4($,Y,Z,X){let Q;try{Q=H6(Z.inputSchema)}catch(q){console.warn(`[createMcpTool] Schema 转换失败,使用降级 schema: ${Z.name}`,q),Q=D0.any()}let J=X||Z.name;return U1({name:J,displayName:`${Y}: ${Z.name}`,kind:"execute",schema:Q,description:{short:Z.description||`MCP Tool: ${Z.name}`,important:[`From MCP server: ${Y}`,"Executes external tools; user confirmation required"]},category:"MCP tool",tags:["mcp","external",Y],async execute(q,K){try{let G=await $.callTool(Z.name,q),U="",O="";if(G.content&&Array.isArray(G.content)){for(let W of G.content)if(W.type==="text"&&W.text)U+=W.text,O+=W.text;else if(W.type==="image")O+=`[图片: ${W.mimeType||"unknown"}]
49
+ `,U+=`[image: ${W.mimeType||"unknown"}]
50
+ `;else if(W.type==="resource")O+=`[资源: ${W.mimeType||"unknown"}]
51
+ `,U+=`[resource: ${W.mimeType||"unknown"}]
52
+ `}if(G.isError)return{success:!1,llmContent:U||"MCP tool execution failed",displayContent:`❌ ${O||"MCP工具执行失败"}`,error:{type:"execution_error",message:U||"MCP tool execution failed"}};return{success:!0,llmContent:U||"Execution succeeded",displayContent:`✅ MCP工具 ${Z.name} 执行成功
53
+ ${O}`,metadata:{serverName:Y,toolName:Z.name,mcpResult:G}}}catch(G){return{success:!1,llmContent:`MCP tool execution failed: ${G.message}`,displayContent:`❌ ${G.message}`,error:{type:"execution_error",message:G.message}}}}})}function H6($){if($.type==="object"||$.properties){let Y={},Z=$.required||[];if($.properties){for(let[X,Q]of Object.entries($.properties))if(typeof Q==="object"&&Q!==null){let J=H6(Q);if(!Z.includes(X))J=J.optional();Y[X]=J}}return D0.object(Y)}if($.type==="array"&&$.items){if(typeof $.items==="object"&&!Array.isArray($.items)&&$.items!==null)return D0.array(H6($.items));return D0.array(D0.any())}if($.type==="string"){let Y=D0.string();if($.minLength!==void 0)Y=Y.min($.minLength);if($.maxLength!==void 0)Y=Y.max($.maxLength);if($.pattern)Y=Y.regex(new RegExp($.pattern));if($.enum)return D0.enum($.enum);return Y}if($.type==="number"||$.type==="integer"){let Y=D0.number();if($.minimum!==void 0)Y=Y.min($.minimum);if($.maximum!==void 0)Y=Y.max($.maximum);return Y}if($.type==="boolean")return D0.boolean();if($.oneOf&&$.oneOf.length>0){let Y=$.oneOf.filter((Z)=>typeof Z==="object"&&Z!==null).map((Z)=>H6(Z));if(Y.length>=2)return D0.union(Y)}if($.anyOf&&$.anyOf.length>0){let Y=$.anyOf.filter((Z)=>typeof Z==="object"&&Z!==null).map((Z)=>H6(Z));if(Y.length>=2)return D0.union(Y)}return D0.any()}var w5=b(()=>{m1();Z0()});import{promises as p8}from"fs";import zK from"os";import u8 from"path";class Y4{tokenFilePath;constructor(){let $=zK.homedir(),Y=u8.join($,".blade");this.tokenFilePath=u8.join(Y,"mcp-oauth-tokens.json")}async ensureConfigDir(){let $=u8.dirname(this.tokenFilePath);try{await p8.mkdir($,{recursive:!0})}catch{}}async loadAllCredentials(){let $=new Map;try{let Y=await p8.readFile(this.tokenFilePath,"utf-8"),Z=JSON.parse(Y);for(let X of Z)$.set(X.serverName,X)}catch(Y){if(Y.code!=="ENOENT")console.warn("[OAuthTokenStorage] 加载令牌失败:",Y)}return $}async saveAllCredentials($){await this.ensureConfigDir();let Y=Array.from($.values());await p8.writeFile(this.tokenFilePath,JSON.stringify(Y,null,2),{mode:384})}async saveToken($,Y,Z,X){let Q=await this.loadAllCredentials(),J={serverName:$,token:Y,clientId:Z,tokenUrl:X,updatedAt:Date.now()};Q.set($,J),await this.saveAllCredentials(Q)}async getCredentials($){return(await this.loadAllCredentials()).get($)||null}async deleteCredentials($){let Y=await this.loadAllCredentials();Y.delete($),await this.saveAllCredentials(Y)}async listServers(){let $=await this.loadAllCredentials();return Array.from($.keys())}isTokenExpired($){if(!$.expiresAt)return!1;let Y=300000;return Date.now()>=$.expiresAt-Y}}var g8=()=>{};import*as N6 from"crypto";import*as R5 from"http";import{spawn as NK}from"child_process";import{URL as A5}from"url";class Z4{tokenStorage;constructor($=new Y4){this.tokenStorage=$}generatePKCEParams(){let $=N6.randomBytes(32).toString("base64url"),Y=N6.createHash("sha256").update($).digest("base64url"),Z=N6.randomBytes(16).toString("base64url");return{codeVerifier:$,codeChallenge:Y,state:Z}}buildAuthorizationUrl($,Y){let Z=$.redirectUri||`http://localhost:${z6}${d8}`,X=new URLSearchParams({client_id:$.clientId,response_type:"code",redirect_uri:Z,state:Y.state,code_challenge:Y.codeChallenge,code_challenge_method:"S256"});if($.scopes&&$.scopes.length>0)X.append("scope",$.scopes.join(" "));let Q=new A5($.authorizationUrl);return X.forEach((J,q)=>{Q.searchParams.append(q,J)}),Q.toString()}async startCallbackServer($){return new Promise((Y,Z)=>{let X=R5.createServer((Q,J)=>{try{let q=new A5(Q.url,`http://localhost:${z6}`);if(q.pathname!==d8){J.writeHead(404),J.end("Not found");return}let K=q.searchParams.get("code"),G=q.searchParams.get("state"),U=q.searchParams.get("error");if(U){J.writeHead(b5,{"Content-Type":"text/html"}),J.end(`
54
54
  <html>
55
55
  <body>
56
56
  <h1>Authentication Failed</h1>
57
- <p>Error: ${W}</p>
57
+ <p>Error: ${U}</p>
58
58
  <p>You can close this window.</p>
59
59
  </body>
60
60
  </html>
61
- `),X.close(),Z(Error(`OAuth error: ${W}`));return}if(!G||!K){J.writeHead(400),J.end("Missing code or state parameter");return}if(K!==$){J.writeHead(400),J.end("Invalid state parameter"),X.close(),Z(Error("State mismatch - possible CSRF attack"));return}J.writeHead(F5,{"Content-Type":"text/html"}),J.end(`
61
+ `),X.close(),Z(Error(`OAuth error: ${U}`));return}if(!K||!G){J.writeHead(400),J.end("Missing code or state parameter");return}if(G!==$){J.writeHead(400),J.end("Invalid state parameter"),X.close(),Z(Error("State mismatch - possible CSRF attack"));return}J.writeHead(b5,{"Content-Type":"text/html"}),J.end(`
62
62
  <html>
63
63
  <body>
64
64
  <h1>Authentication Successful!</h1>
@@ -66,51 +66,53 @@ ${O}`,metadata:{serverName:Y,toolName:Z.name,mcpResult:K}}}catch(K){return{succe
66
66
  <script>window.close();</script>
67
67
  </body>
68
68
  </html>
69
- `),X.close(),Y(G)}catch(q){X.close(),Z(q)}});X.on("error",Z),X.listen(O6,()=>{console.log(`[OAuth] Callback server listening on port ${O6}`)}),setTimeout(()=>{X.close(),Z(Error("OAuth callback timeout"))},300000)})}async exchangeCodeForToken($,Y,Z){let X=$.redirectUri||`http://localhost:${O6}${p9}`,Q=new URLSearchParams({grant_type:"authorization_code",code:Y,redirect_uri:X,code_verifier:Z,client_id:$.clientId});if($.clientSecret)Q.append("client_secret",$.clientSecret);let J=await fetch($.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:Q.toString()});if(!J.ok){let q=await J.text();throw Error(`Token exchange failed: ${J.status} - ${q}`)}return await J.json()}async refreshAccessToken($,Y){let Z=new URLSearchParams({grant_type:"refresh_token",refresh_token:Y,client_id:$.clientId});if($.clientSecret)Z.append("client_secret",$.clientSecret);if($.scopes&&$.scopes.length>0)Z.append("scope",$.scopes.join(" "));let X=await fetch($.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:Z.toString()});if(!X.ok){let Q=await X.text();throw Error(`Token refresh failed: ${X.status} - ${Q}`)}return await X.json()}async authenticate($,Y){if(!Y.clientId||!Y.authorizationUrl||!Y.tokenUrl)throw Error("Missing required OAuth configuration");let Z=this.generatePKCEParams(),X=this.buildAuthorizationUrl(Y,Z);console.log(`
69
+ `),X.close(),Y(K)}catch(q){X.close(),Z(q)}});X.on("error",Z),X.listen(z6,()=>{console.log(`[OAuth] Callback server listening on port ${z6}`)}),setTimeout(()=>{X.close(),Z(Error("OAuth callback timeout"))},300000)})}async exchangeCodeForToken($,Y,Z){let X=$.redirectUri||`http://localhost:${z6}${d8}`,Q=new URLSearchParams({grant_type:"authorization_code",code:Y,redirect_uri:X,code_verifier:Z,client_id:$.clientId});if($.clientSecret)Q.append("client_secret",$.clientSecret);let J=await fetch($.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:Q.toString()});if(!J.ok){let q=await J.text();throw Error(`Token exchange failed: ${J.status} - ${q}`)}return await J.json()}async refreshAccessToken($,Y){let Z=new URLSearchParams({grant_type:"refresh_token",refresh_token:Y,client_id:$.clientId});if($.clientSecret)Z.append("client_secret",$.clientSecret);if($.scopes&&$.scopes.length>0)Z.append("scope",$.scopes.join(" "));let X=await fetch($.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:Z.toString()});if(!X.ok){let Q=await X.text();throw Error(`Token refresh failed: ${X.status} - ${Q}`)}return await X.json()}async authenticate($,Y){if(!Y.clientId||!Y.authorizationUrl||!Y.tokenUrl)throw Error("Missing required OAuth configuration");let Z=this.generatePKCEParams(),X=this.buildAuthorizationUrl(Y,Z);console.log(`
70
70
  [OAuth] Opening browser for authentication...`),console.log(`
71
- If the browser does not open automatically, copy and paste this URL:`),console.log(X),console.log("");let Q=this.startCallbackServer(Z.state);try{await this.openAuthorizationUrl(X)}catch(K){console.warn("[OAuth] Failed to open browser automatically:",K)}let J=await Q;console.log("[OAuth] Authorization code received, exchanging for tokens...");let q=await this.exchangeCodeForToken(Y,J,Z.codeVerifier),G={accessToken:q.access_token,tokenType:q.token_type||"Bearer",refreshToken:q.refresh_token,scope:q.scope};if(q.expires_in)G.expiresAt=Date.now()+q.expires_in*1000;return await this.tokenStorage.saveToken($,G,Y.clientId,Y.tokenUrl),console.log("[OAuth] Authentication successful! Token saved."),G}async openAuthorizationUrl($){let{command:Y,args:Z}=this.getBrowserCommand($);await new Promise((X,Q)=>{let J=oq(Y,Z,{stdio:"ignore"});J.once("error",Q),J.once("close",(q)=>{if(q===0||q===null)X();else Q(Error(`Failed to open browser (exit code ${q})`))})})}getBrowserCommand($){if(process.platform==="darwin")return{command:"open",args:[$]};if(process.platform==="win32")return{command:"cmd",args:["/c","start","",$]};return{command:"xdg-open",args:[$]}}async getValidToken($,Y){let Z=await this.tokenStorage.getCredentials($);if(!Z)return null;let{token:X}=Z;if(!this.tokenStorage.isTokenExpired(X))return X.accessToken;if(X.refreshToken&&Y.clientId&&Z.tokenUrl)try{console.log(`[OAuth] Refreshing expired token for server: ${$}`);let Q=await this.refreshAccessToken(Y,X.refreshToken),J={accessToken:Q.access_token,tokenType:Q.token_type,refreshToken:Q.refresh_token||X.refreshToken,scope:Q.scope||X.scope};if(Q.expires_in)J.expiresAt=Date.now()+Q.expires_in*1000;return await this.tokenStorage.saveToken($,J,Y.clientId,Z.tokenUrl),J.accessToken}catch(Q){console.error("[OAuth] Failed to refresh token:",Q),await this.tokenStorage.deleteCredentials($)}return null}}var O6=7777,p9="/oauth/callback",F5=200;var _5=b(()=>{x9()});var z5=b(()=>{_5();x9()});var B$=()=>{};import{EventEmitter as sq}from"events";var g9;var N5=b(()=>{B$();g9=class g9 extends sq{client;config;checkTimer=null;isChecking=!1;consecutiveFailures=0;lastCheckTime=0;currentStatus="healthy";constructor($,Y={}){super();this.client=$,this.config={interval:Y.interval??30000,timeout:Y.timeout??1e4,enabled:Y.enabled??!1,failureThreshold:Y.failureThreshold??3}}start(){if(this.checkTimer){console.warn("[HealthMonitor] 健康监控已在运行");return}if(!this.config.enabled){console.log("[HealthMonitor] 健康监控未启用");return}console.log(`[HealthMonitor] 启动健康监控(间隔: ${this.config.interval}ms)`),this.scheduleNextCheck()}stop(){if(this.checkTimer)clearTimeout(this.checkTimer),this.checkTimer=null,console.log("[HealthMonitor] 停止健康监控")}scheduleNextCheck(){this.checkTimer=setTimeout(async()=>{await this.performHealthCheck(),this.scheduleNextCheck()},this.config.interval)}async performHealthCheck(){if(this.isChecking)return console.warn("[HealthMonitor] 上一次检查仍在进行中"),this.getLastResult();this.isChecking=!0,this.lastCheckTime=Date.now(),this.setStatus("checking");try{let $=this.client.connectionStatus;if($==="connected"){await this.pingServer(),this.consecutiveFailures=0,this.setStatus("healthy");let Y={status:"healthy",timestamp:Date.now(),consecutiveFailures:0};return this.emit("healthCheck",Y),Y}else throw Error(`连接状态异常: ${$}`)}catch($){this.consecutiveFailures++;let Y=$;console.warn(`[HealthMonitor] 健康检查失败(${this.consecutiveFailures}/${this.config.failureThreshold}):`,Y.message);let Z;if(this.consecutiveFailures>=this.config.failureThreshold)Z="unhealthy",this.emit("unhealthy",this.consecutiveFailures,Y),console.log("[HealthMonitor] 达到失败阈值,触发重连..."),this.triggerReconnection().catch((Q)=>{console.error("[HealthMonitor] 重连失败:",Q)});else Z="degraded";this.setStatus(Z);let X={status:Z,timestamp:Date.now(),consecutiveFailures:this.consecutiveFailures,lastError:Y};return this.emit("healthCheck",X),X}finally{this.isChecking=!1}}async pingServer(){let $=new Promise((Z,X)=>{setTimeout(()=>X(Error("Health check timeout")),this.config.timeout)}),Y=(async()=>{if(this.client.availableTools.length===0){if(!this.client.server)throw Error("Server info not available")}})();await Promise.race([Y,$])}async triggerReconnection(){try{await this.client.disconnect(),await new Promise(($)=>setTimeout($,1000)),await this.client.connect(),console.log("[HealthMonitor] 重连成功"),this.consecutiveFailures=0,this.setStatus("healthy"),this.emit("reconnected")}catch($){throw console.error("[HealthMonitor] 重连失败:",$),$}}setStatus($){if(this.currentStatus!==$){let Y=this.currentStatus;this.currentStatus=$,this.emit("statusChanged",$,Y)}}getStatus(){return this.currentStatus}getLastResult(){return{status:this.currentStatus,timestamp:this.lastCheckTime,consecutiveFailures:this.consecutiveFailures}}getStatistics(){return{status:this.currentStatus,consecutiveFailures:this.consecutiveFailures,lastCheckTime:this.lastCheckTime,isChecking:this.isChecking,config:this.config}}async checkNow(){return this.performHealthCheck()}resetFailureCount(){if(this.consecutiveFailures=0,this.currentStatus!=="checking")this.setStatus("healthy")}}});import{Client as tq}from"@modelcontextprotocol/sdk/client/index.js";import{SSEClientTransport as eq}from"@modelcontextprotocol/sdk/client/sse.js";import{StdioClientTransport as $G}from"@modelcontextprotocol/sdk/client/stdio.js";import{EventEmitter as YG}from"events";function B5($){if(!($ instanceof Error))return{type:"unknown",isRetryable:!1,originalError:Error(String($))};let Y=$.message.toLowerCase();if(["command not found","no such file","permission denied","invalid configuration","malformed","syntax error"].some((Q)=>Y.includes(Q)))return{type:"config_error",isRetryable:!1,originalError:$};if(Y.includes("unauthorized")||Y.includes("401")||Y.includes("authentication failed"))return{type:"auth_error",isRetryable:!1,originalError:$};if(["timeout","connection refused","network error","temporary","try again","rate limit","too many requests","service unavailable","socket hang up","econnreset","enotfound","econnrefused","etimedout","503","429"].some((Q)=>Y.includes(Q)))return{type:"network_temporary",isRetryable:!0,originalError:$};return{type:"unknown",isRetryable:!0,originalError:$}}var u9;var L5=b(()=>{X6();z5();N5();B$();u9=class u9 extends YG{config;status="disconnected";sdkClient=null;tools=new Map;serverInfo=null;reconnectAttempts=0;MAX_RECONNECT_ATTEMPTS=5;reconnectTimer=null;isManualDisconnect=!1;oauthProvider=null;serverName;healthMonitor=null;constructor($,Y,Z){super();this.config=$;if(this.serverName=Y||"default",$.oauth?.enabled)this.oauthProvider=new e6;if(Z?.enabled)this.healthMonitor=new g9(this,Z),this.healthMonitor.on("unhealthy",(X,Q)=>{this.emit("unhealthy",X,Q)}),this.healthMonitor.on("reconnected",()=>{this.emit("healthMonitorReconnected")})}get connectionStatus(){return this.status}get availableTools(){return Array.from(this.tools.values())}get server(){return this.serverInfo}get healthCheck(){return this.healthMonitor}async connect(){return this.connectWithRetry(3,1000)}async connectWithRetry($=3,Y=1000){if(this.status!=="disconnected")throw Error("客户端已连接或正在连接中");let Z=null;for(let X=1;X<=$;X++)try{await this.doConnect(),this.reconnectAttempts=0;return}catch(Q){Z=Q;let J=B5(Q);if(!J.isRetryable)throw console.error("[McpClient] 检测到永久性错误,放弃重试:",J.type),Q;if(X<$){let q=Y*Math.pow(2,X-1);console.warn(`[McpClient] 连接失败(${X}/${$}),${q}ms 后重试...`),await new Promise((G)=>setTimeout(G,q))}}throw Z||Error("连接失败")}async doConnect(){try{this.setStatus("connecting"),this.sdkClient=new tq({name:E3(),version:O$()},{capabilities:{roots:{listChanged:!0},sampling:{}}}),this.sdkClient.onclose=()=>{this.handleUnexpectedClose()};let $=await this.createTransport();await this.sdkClient.connect($);let Y=this.sdkClient.getServerVersion();if(this.serverInfo={name:Y?.name||"Unknown",version:Y?.version||"0.0.0"},await this.loadTools(),this.setStatus("connected"),this.emit("connected",this.serverInfo),this.healthMonitor)this.healthMonitor.start()}catch($){throw this.setStatus("error"),this.emit("error",$),$}}handleUnexpectedClose(){if(this.isManualDisconnect)return;if(this.status==="connected")console.warn("[McpClient] 检测到意外断连,准备重连..."),this.setStatus("error"),this.emit("error",Error("MCP服务器连接意外关闭")),this.scheduleReconnect()}scheduleReconnect(){if(this.reconnectTimer)clearTimeout(this.reconnectTimer),this.reconnectTimer=null;if(this.reconnectAttempts>=this.MAX_RECONNECT_ATTEMPTS){console.error("[McpClient] 达到最大重连次数,放弃重连"),this.emit("reconnectFailed");return}let $=Math.min(1000*Math.pow(2,this.reconnectAttempts),30000);this.reconnectAttempts++,console.log(`[McpClient] 将在 ${$}ms 后进行第 ${this.reconnectAttempts} 次重连...`),this.reconnectTimer=setTimeout(async()=>{try{if(this.sdkClient){try{await this.sdkClient.close()}catch{}this.sdkClient=null}this.setStatus("disconnected"),await this.doConnect(),console.log("[McpClient] 重连成功"),this.reconnectAttempts=0,this.emit("reconnected")}catch(Y){if(console.error("[McpClient] 重连失败:",Y),B5(Y).isRetryable)this.scheduleReconnect();else console.error("[McpClient] 检测到永久性错误,停止重连"),this.emit("reconnectFailed")}},$)}async disconnect(){if(this.isManualDisconnect=!0,this.healthMonitor)this.healthMonitor.stop();if(this.reconnectTimer)clearTimeout(this.reconnectTimer),this.reconnectTimer=null;if(this.sdkClient){try{await this.sdkClient.close()}catch($){console.warn("[McpClient] 断开连接时出错:",$)}this.sdkClient=null}this.tools.clear(),this.serverInfo=null,this.reconnectAttempts=0,this.setStatus("disconnected"),this.emit("disconnected"),this.isManualDisconnect=!1}async callTool($,Y={}){if(!this.sdkClient)throw Error("客户端未连接到服务器");if(!this.tools.has($))throw Error(`工具 "${$}" 不存在`);try{return await this.sdkClient.callTool({name:$,arguments:Y})}catch(Z){throw console.error(`[McpClient] 调用工具 "${$}" 失败:`,Z),Z}}async createTransport(){let{type:$,command:Y,args:Z,env:X,url:Q,headers:J,oauth:q}=this.config,G={...J};if(q?.enabled&&this.oauthProvider&&($==="sse"||$==="http"))try{let K=await this.oauthProvider.getValidToken(this.serverName,q);if(!K){console.log(`[McpClient] 服务器 "${this.serverName}" 需要 OAuth 认证`);let W=await this.oauthProvider.authenticate(this.serverName,q);G.Authorization=`Bearer ${W.accessToken}`}else G.Authorization=`Bearer ${K}`}catch(K){throw console.error("[McpClient] OAuth 认证失败:",K),Error(`OAuth 认证失败: ${K instanceof Error?K.message:String(K)}`)}if($==="stdio"){if(!Y)throw Error("stdio 传输需要 command 参数");let K={};for(let[W,O]of Object.entries(process.env))if(O!==void 0)K[W]=O;return new $G({command:Y,args:Z||[],env:{...K,...X},stderr:"ignore"})}else if($==="sse"){if(!Q)throw Error("sse 传输需要 url 参数");return new eq(new URL(Q),{requestInit:{headers:G}})}else if($==="http"){if(!Q)throw Error("http 传输需要 url 参数");let{StreamableHTTPClientTransport:K}=await import("@modelcontextprotocol/sdk/client/streamableHttp.js");return new K(new URL(Q),{requestInit:{headers:G}})}throw Error(`不支持的传输类型: ${$}`)}async loadTools(){if(!this.sdkClient)return;try{let $=await this.sdkClient.listTools();if(this.tools.clear(),$.tools)for(let Y of $.tools)this.tools.set(Y.name,Y);this.emit("toolsUpdated",this.availableTools)}catch($){throw console.error("[McpClient] 加载工具失败:",$),$}}setStatus($){let Y=this.status;this.status=$,this.emit("statusChanged",$,Y)}async initialize(){return this.connect()}async destroy(){return this.disconnect()}async connectToServer($){return this.connect()}async disconnectFromServer($){return this.disconnect()}async listResources($){if(!this.sdkClient)return[];try{return(await this.sdkClient.listResources()).resources||[]}catch{return[]}}async listTools($){return this.availableTools}async readResource($,Y){if(!this.sdkClient)throw Error("客户端未连接");return(await this.sdkClient.readResource({uri:$})).contents?.[0]||{uri:$,text:""}}}});import{EventEmitter as ZG}from"events";var n1;var L$=b(()=>{W5();L5();B$();n1=class n1 extends ZG{static instance=null;servers=new Map;isDiscovering=!1;constructor(){super()}static getInstance(){if(!n1.instance)n1.instance=new n1;return n1.instance}async registerServer($,Y){if(this.servers.has($))throw Error(`MCP服务器 "${$}" 已经注册`);let Z=new u9(Y,$,Y.healthCheck),X={config:Y,client:Z,status:"disconnected",tools:[]};this.setupClientEventHandlers(Z,X,$),this.servers.set($,X),this.emit("serverRegistered",$,X);try{await this.connectServer($)}catch(Q){console.warn(`MCP服务器 "${$}" 连接失败:`,Q)}}async unregisterServer($){let Y=this.servers.get($);if(!Y)return;try{await Y.client.disconnect()}catch(Z){console.warn(`断开MCP服务器 "${$}" 时出错:`,Z)}this.servers.delete($),this.emit("serverUnregistered",$)}async connectServer($){let Y=this.servers.get($);if(!Y)throw Error(`MCP服务器 "${$}" 未注册`);if(Y.status==="connected")return;try{Y.status="connecting",await Y.client.connect(),Y.connectedAt=new Date,Y.lastError=void 0,Y.tools=Y.client.availableTools}catch(Z){throw Y.lastError=Z,Y.status="error",Z}}async disconnectServer($){let Y=this.servers.get($);if(!Y)return;await Y.client.disconnect(),Y.connectedAt=void 0}async getAvailableTools(){let $=[],Y=new Map;for(let[Z,X]of this.servers)if(X.status==="connected")for(let Q of X.tools){let J=Y.get(Q.name)||0;Y.set(Q.name,J+1)}for(let[Z,X]of this.servers)if(X.status==="connected")for(let Q of X.tools){let q=(Y.get(Q.name)||0)>1?`${Z}__${Q.name}`:Q.name,G=s6(X.client,Z,Q,q);$.push(G)}return $}async findTool($){for(let[Y,Z]of this.servers)if(Z.status==="connected"){let X=Z.tools.find((Q)=>Q.name===$);if(X)return s6(Z.client,Y,X)}return null}getToolsByServer($){let Y=this.servers.get($);if(!Y||Y.status!=="connected")return[];return Y.tools.map((Z)=>s6(Y.client,$,Z))}getServerStatus($){return this.servers.get($)||null}getAllServers(){return new Map(this.servers)}async refreshAllTools(){let $=[];for(let[Y,Z]of this.servers)if(Z.status==="connected")$.push(this.refreshServerTools(Y));await Promise.allSettled($)}async refreshServerTools($){let Y=this.servers.get($);if(!Y||Y.status!=="connected")return;try{let Z=Y.client.availableTools,X=Y.tools.length;Y.tools=Z,this.emit("toolsUpdated",$,Z,X)}catch(Z){console.warn(`刷新服务器 "${$}" 工具列表失败:`,Z)}}setupClientEventHandlers($,Y,Z){$.on("connected",(X)=>{Y.status="connected",Y.connectedAt=new Date,Y.tools=$.availableTools,this.emit("serverConnected",Z,X)}),$.on("disconnected",()=>{Y.status="disconnected",Y.connectedAt=void 0,Y.tools=[],this.emit("serverDisconnected",Z)}),$.on("error",(X)=>{Y.status="error",Y.lastError=X,this.emit("serverError",Z,X)}),$.on("toolsUpdated",(X)=>{let Q=Y.tools.length;Y.tools=X,this.emit("toolsUpdated",Z,X,Q)}),$.on("statusChanged",(X,Q)=>{Y.status=X,this.emit("serverStatusChanged",Z,X,Q)})}async discoverServers(){if(this.isDiscovering)return Array.from(this.servers.values());this.isDiscovering=!0,this.emit("discoveryStarted");try{return Array.from(this.servers.values())}finally{this.isDiscovering=!1,this.emit("discoveryCompleted")}}async registerServers($){let Y=Object.entries($).map(([Z,X])=>this.registerServer(Z,X).catch((Q)=>{return console.warn(`注册MCP服务器 "${Z}" 失败:`,Q),Q}));await Promise.allSettled(Y)}getStatistics(){let $=0,Y=0,Z=0;for(let X of this.servers.values())if(X.status==="connected")$++,Y+=X.tools.length;else if(X.status==="error")Z++;return{totalServers:this.servers.size,connectedServers:$,errorServers:Z,totalTools:Y,isDiscovering:this.isDiscovering}}async disconnectAll(){let $=[];for(let[Y,Z]of this.servers)if(Z.status==="connected")$.push(Z.client.disconnect().catch((X)=>{console.warn(`断开 MCP 服务器 "${Y}" 时出错:`,X)}));await Promise.allSettled($),this.servers.clear()}}});function d9($,Y){return{...$,...Y,PreToolUse:Y.PreToolUse??$.PreToolUse,PostToolUse:Y.PostToolUse??$.PostToolUse,PostToolUseFailure:Y.PostToolUseFailure??$.PostToolUseFailure,PermissionRequest:Y.PermissionRequest??$.PermissionRequest,UserPromptSubmit:Y.UserPromptSubmit??$.UserPromptSubmit,SessionStart:Y.SessionStart??$.SessionStart,SessionEnd:Y.SessionEnd??$.SessionEnd,Stop:Y.Stop??$.Stop,SubagentStop:Y.SubagentStop??$.SubagentStop,Notification:Y.Notification??$.Notification,Compaction:Y.Compaction??$.Compaction}}function b5(){let $={};if(process.env.BLADE_DISABLE_HOOKS==="true")$.enabled=!1;if(process.env.BLADE_HOOK_TIMEOUT){let Y=parseInt(process.env.BLADE_HOOK_TIMEOUT,10);if(!isNaN(Y)&&Y>0)$.defaultTimeout=Y}return $}var m9;var R5=b(()=>{m9={enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,PreToolUse:[],PostToolUse:[],PostToolUseFailure:[],PermissionRequest:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]}});class c9{executedHooks=new Map;canExecute($,Y){if(!this.executedHooks.has($))this.executedHooks.set($,new Set);if(this.executedHooks.get($).has(Y))return console.warn(`[HookGuard] Hook ${Y} for tool ${$} already executed, skipping`),!1;return!0}markExecuted($,Y){let Z=this.executedHooks.get($);if(Z)Z.add(Y)}cleanup($){this.executedHooks.delete($)}cleanupAll(){this.executedHooks.clear()}}var o0,l9,i9;var w$=b(()=>{((U)=>{U.PreToolUse="PreToolUse";U.PostToolUse="PostToolUse";U.PostToolUseFailure="PostToolUseFailure";U.PermissionRequest="PermissionRequest";U.UserPromptSubmit="UserPromptSubmit";U.SessionStart="SessionStart";U.SessionEnd="SessionEnd";U.Stop="Stop";U.SubagentStop="SubagentStop";U.Notification="Notification";U.Compaction="Compaction"})(o0||={});((X)=>{X.Approve="approve";X.Block="block";X.Async="async"})(l9||={});((X)=>{X.Allow="allow";X.Deny="deny";X.Ask="ask"})(i9||={})});import{z as V}from"zod";function V5($){let Y=PG.safeParse($);if(Y.success)return{success:!0,data:Y.data};return{success:!1,error:Y.error}}var h0,FG,HG,_G,zG,NG,BG,LG,wG,AG,bG,RG,UB,VG,DG,IG,MG,jG,yG,vG,EG,PG,TG,kG,SG,a9,CG,f0,WB;var D5=b(()=>{w$();h0=V.object({hook_event_name:V.nativeEnum(o0),hook_execution_id:V.string(),timestamp:V.string(),project_dir:V.string(),session_id:V.string(),permission_mode:V.enum(["default","autoEdit","yolo","plan"]),_metadata:V.object({blade_version:V.string(),hook_timeout_ms:V.number()}).optional()}),FG=h0.extend({hook_event_name:V.literal("PreToolUse"),tool_name:V.string(),tool_use_id:V.string(),tool_input:V.record(V.unknown())}),HG=h0.extend({hook_event_name:V.literal("PostToolUse"),tool_name:V.string(),tool_use_id:V.string(),tool_input:V.record(V.unknown()),tool_response:V.unknown()}),_G=h0.extend({hook_event_name:V.literal("Stop"),reason:V.string().optional()}),zG=h0.extend({hook_event_name:V.literal("PostToolUseFailure"),tool_name:V.string(),tool_use_id:V.string(),tool_input:V.record(V.unknown()),error:V.string(),error_type:V.string().optional(),is_interrupt:V.boolean(),is_timeout:V.boolean()}),NG=h0.extend({hook_event_name:V.literal("PermissionRequest"),tool_name:V.string(),tool_use_id:V.string(),tool_input:V.record(V.unknown())}),BG=h0.extend({hook_event_name:V.literal("UserPromptSubmit"),user_prompt:V.string(),has_images:V.boolean(),image_count:V.number()}),LG=h0.extend({hook_event_name:V.literal("SessionStart"),is_resume:V.boolean(),resume_session_id:V.string().optional()}),wG=h0.extend({hook_event_name:V.literal("SessionEnd"),reason:V.enum(["user_exit","error","max_turns","idle_timeout","ctrl_c","clear","logout","other"])}),AG=h0.extend({hook_event_name:V.literal("SubagentStop"),agent_type:V.string(),task_description:V.string().optional(),success:V.boolean(),result_summary:V.string().optional(),error:V.string().optional()}),bG=h0.extend({hook_event_name:V.literal("Notification"),notification_type:V.enum(["permission_prompt","idle_prompt","auth_success","elicitation_dialog","info","warning","error"]),title:V.string().optional(),message:V.string()}),RG=h0.extend({hook_event_name:V.literal("Compaction"),trigger:V.enum(["manual","auto"]),messages_before:V.number(),tokens_before:V.number()}),UB=V.discriminatedUnion("hook_event_name",[FG,HG,_G,zG,NG,BG,LG,wG,AG,bG,RG]),VG=V.object({hookEventName:V.literal("PreToolUse"),permissionDecision:V.nativeEnum(i9).optional(),permissionDecisionReason:V.string().optional(),updatedInput:V.record(V.unknown()).optional()}),DG=V.object({hookEventName:V.literal("PostToolUse"),additionalContext:V.string().optional(),updatedOutput:V.unknown().optional()}),IG=V.object({hookEventName:V.literal("Stop"),continue:V.boolean().optional(),continueReason:V.string().optional()}),MG=V.object({hookEventName:V.literal("SubagentStop"),continue:V.boolean().optional(),continueReason:V.string().optional(),additionalContext:V.string().optional()}),jG=V.object({hookEventName:V.literal("PermissionRequest"),permissionDecision:V.enum(["approve","deny","ask"]).optional(),permissionDecisionReason:V.string().optional()}),yG=V.object({hookEventName:V.literal("UserPromptSubmit"),updatedPrompt:V.string().optional(),contextInjection:V.string().optional()}),vG=V.object({hookEventName:V.literal("SessionStart"),env:V.record(V.string()).optional()}),EG=V.object({hookEventName:V.literal("Compaction"),blockCompaction:V.boolean().optional(),blockReason:V.string().optional()}),PG=V.object({decision:V.object({behavior:V.nativeEnum(l9)}).optional(),systemMessage:V.string().optional(),hookSpecificOutput:V.discriminatedUnion("hookEventName",[VG,DG,IG,MG,jG,yG,vG,EG]).optional(),suppressOutput:V.boolean().optional()}),TG=V.object({type:V.literal("command"),command:V.string(),timeout:V.number().positive().optional(),statusMessage:V.string().optional()}),kG=V.object({type:V.literal("prompt"),prompt:V.string(),timeout:V.number().positive().optional()}),SG=V.discriminatedUnion("type",[TG,kG]),a9=V.union([V.string(),V.array(V.string())]),CG=V.object({tools:a9.optional(),paths:a9.optional(),commands:a9.optional()}),f0=V.object({name:V.string().optional(),matcher:CG.optional(),hooks:V.array(SG)}),WB=V.object({enabled:V.boolean().optional(),defaultTimeout:V.number().positive().optional(),timeoutBehavior:V.enum(["ignore","deny","ask"]).optional(),failureBehavior:V.enum(["ignore","deny","ask"]).optional(),maxConcurrentHooks:V.number().positive().optional(),PreToolUse:V.array(f0).optional(),PostToolUse:V.array(f0).optional(),PostToolUseFailure:V.array(f0).optional(),PermissionRequest:V.array(f0).optional(),UserPromptSubmit:V.array(f0).optional(),SessionStart:V.array(f0).optional(),SessionEnd:V.array(f0).optional(),Stop:V.array(f0).optional(),SubagentStop:V.array(f0).optional(),Notification:V.array(f0).optional(),Compaction:V.array(f0).optional()})});class r9{parse($,Y,Z){if($.timedOut){let Q=Z?.timeoutBehavior||"ignore",J="Hook timeout";if(Q==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Y};else if(Q==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Y};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Y}}let X=this.tryParseJSON($.stdout);if(X){let Q=V5(X);if(!Q.success){let q="error"in Q?Q.error.message:"Unknown validation error",G=Z?.failureBehavior||"ignore",K=`Invalid hook output JSON: ${q}`;if(G==="deny")return{success:!1,blocking:!0,error:K,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Y};else if(G==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${K}. Continue?`,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Y};else return{success:!1,blocking:!1,warning:K,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Y}}let J=Q.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:Y};if(J.decision?.behavior==="async")return{success:!0,output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Y};return{success:!0,output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Y}}return this.parseByExitCode($,Y,Z)}parseByExitCode($,Y,Z){let X=$.exitCode;switch(X){case 0:return{success:!0,stdout:$.stdout,stderr:$.stderr,exitCode:X,hook:Y};case 2:return{success:!1,blocking:!0,error:$.stderr||$.stdout||"Hook returned exit code 2",stdout:$.stdout,stderr:$.stderr,exitCode:X,hook:Y};case 124:{let Q=Z?.timeoutBehavior||"ignore",J="Hook timeout";if(Q==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:X,hook:Y};else if(Q==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:$.stdout,stderr:$.stderr,exitCode:X,hook:Y};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:X,hook:Y}}default:{let Q=Z?.failureBehavior||"ignore",J=$.stderr||$.stdout||`Hook failed with exit code ${X}`;if(Q==="deny")return{success:!1,blocking:!0,error:J,stdout:$.stdout,stderr:$.stderr,exitCode:X,hook:Y};else if(Q==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${J}. Continue?`,stdout:$.stdout,stderr:$.stderr,exitCode:X,hook:Y};else return{success:!1,blocking:!1,warning:J,stdout:$.stdout,stderr:$.stderr,exitCode:X,hook:Y}}}}tryParseJSON($){try{let Y=$.trim();if(!Y)return null;let Z=Y.match(/^\s*(\{[\s\S]*\})\s*$/);if(!Z)return null;return JSON.parse(Z[1])}catch{return null}}}var I5=b(()=>{D5()});import{spawn as fG}from"child_process";class n9{content="";maxSize;constructor($){this.maxSize=$}append($){if(this.content.length<this.maxSize){let Y=this.maxSize-this.content.length;this.content+=$.substring(0,Y)}}getContent(){return this.content}isFull(){return this.content.length>=this.maxSize}}class o9{MAX_STDOUT_SIZE=1048576;MAX_STDERR_SIZE=1048576;MAX_INPUT_SIZE=102400;async execute($,Y,Z,X){let Q=JSON.stringify(Y);if(Q.length>this.MAX_INPUT_SIZE)throw Error(`Hook input too large: ${Q.length} bytes (max ${this.MAX_INPUT_SIZE})`);let J=this.createSafeEnv(Y),q=fG($,[],{shell:!0,env:J,cwd:Z.projectDir,timeout:X}),G=new n9(this.MAX_STDOUT_SIZE),K=new n9(this.MAX_STDERR_SIZE);q.stdout.setEncoding("utf8"),q.stderr.setEncoding("utf8"),q.stdout.on("data",(W)=>{G.append(W)}),q.stderr.on("data",(W)=>{K.append(W)});try{q.stdin.write(Q),q.stdin.end()}catch(W){throw q.kill("SIGTERM"),Error(`Failed to write hook input: ${W}`)}return new Promise((W,O)=>{let U=!1,F=!1,H=null,_=()=>{if(H&&Z.abortSignal)Z.abortSignal.removeEventListener("abort",H),H=null},z=setTimeout(()=>{U=!0,q.kill("SIGKILL")},X);if(q.on("close",(L)=>{if(F)return;F=!0,clearTimeout(z),_(),W({stdout:G.getContent(),stderr:K.getContent(),exitCode:U?124:L??1,timedOut:U})}),q.on("error",(L)=>{if(F)return;F=!0,clearTimeout(z),_(),O(L)}),Z.abortSignal)H=()=>{if(F)return;F=!0,clearTimeout(z),_(),q.kill("SIGTERM"),W({stdout:G.getContent(),stderr:"Hook cancelled by abort signal",exitCode:1,timedOut:!1})},Z.abortSignal.addEventListener("abort",H)})}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 M5=()=>{};class s9{processExecutor=new o9;outputParser=new r9;async executePreToolHooks($,Y,Z){if($.length===0)return{decision:"allow"};let X="tool_input"in Y?Y.tool_input:{},Q=[];for(let J of $)try{let q={...Y,...X&&{tool_input:X}},G=await this.executeHook(J,q,Z);if(!G.success){if(G.blocking)return{decision:"deny",reason:G.error};if(G.needsConfirmation)return{decision:"ask",reason:G.warning||G.error};if(G.warning)Q.push(G.warning);continue}let K=G.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)X={...X,...K.updatedInput}}}catch(q){let G=q instanceof Error?q.message:String(q);if(Q.push(`Hook failed: ${G}`),Z.config.failureBehavior==="deny")return{decision:"deny",reason:G};else if(Z.config.failureBehavior==="ask")return{decision:"ask",reason:`Hook failed: ${G}. Continue?`}}return{decision:"allow",modifiedInput:X,warning:Q.length>0?Q.join(`
72
- `):void 0}}async executePostToolHooks($,Y,Z){if($.length===0)return{};let X=Z.config.maxConcurrentHooks||5,Q=await this.executeHooksConcurrently($,Y,Z,X),J=[],q=void 0,G=[];for(let K of Q){if(!K.success&&K.warning){G.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)q=W.updatedOutput}}return{additionalContext:J.length>0?J.join(`
71
+ If the browser does not open automatically, copy and paste this URL:`),console.log(X),console.log("");let Q=this.startCallbackServer(Z.state);try{await this.openAuthorizationUrl(X)}catch(G){console.warn("[OAuth] Failed to open browser automatically:",G)}let J=await Q;console.log("[OAuth] Authorization code received, exchanging for tokens...");let q=await this.exchangeCodeForToken(Y,J,Z.codeVerifier),K={accessToken:q.access_token,tokenType:q.token_type||"Bearer",refreshToken:q.refresh_token,scope:q.scope};if(q.expires_in)K.expiresAt=Date.now()+q.expires_in*1000;return await this.tokenStorage.saveToken($,K,Y.clientId,Y.tokenUrl),console.log("[OAuth] Authentication successful! Token saved."),K}async openAuthorizationUrl($){let{command:Y,args:Z}=this.getBrowserCommand($);await new Promise((X,Q)=>{let J=NK(Y,Z,{stdio:"ignore"});J.once("error",Q),J.once("close",(q)=>{if(q===0||q===null)X();else Q(Error(`Failed to open browser (exit code ${q})`))})})}getBrowserCommand($){if(process.platform==="darwin")return{command:"open",args:[$]};if(process.platform==="win32")return{command:"cmd",args:["/c","start","",$]};return{command:"xdg-open",args:[$]}}async getValidToken($,Y){let Z=await this.tokenStorage.getCredentials($);if(!Z)return null;let{token:X}=Z;if(!this.tokenStorage.isTokenExpired(X))return X.accessToken;if(X.refreshToken&&Y.clientId&&Z.tokenUrl)try{console.log(`[OAuth] Refreshing expired token for server: ${$}`);let Q=await this.refreshAccessToken(Y,X.refreshToken),J={accessToken:Q.access_token,tokenType:Q.token_type,refreshToken:Q.refresh_token||X.refreshToken,scope:Q.scope||X.scope};if(Q.expires_in)J.expiresAt=Date.now()+Q.expires_in*1000;return await this.tokenStorage.saveToken($,J,Y.clientId,Z.tokenUrl),J.accessToken}catch(Q){console.error("[OAuth] Failed to refresh token:",Q),await this.tokenStorage.deleteCredentials($)}return null}}var z6=7777,d8="/oauth/callback",b5=200;var V5=b(()=>{g8()});var D5=b(()=>{V5();g8()});var A$=()=>{};import{EventEmitter as BK}from"events";var m8;var I5=b(()=>{A$();m8=class m8 extends BK{client;config;checkTimer=null;isChecking=!1;consecutiveFailures=0;lastCheckTime=0;currentStatus="healthy";constructor($,Y={}){super();this.client=$,this.config={interval:Y.interval??30000,timeout:Y.timeout??1e4,enabled:Y.enabled??!1,failureThreshold:Y.failureThreshold??3}}start(){if(this.checkTimer){console.warn("[HealthMonitor] 健康监控已在运行");return}if(!this.config.enabled){console.log("[HealthMonitor] 健康监控未启用");return}console.log(`[HealthMonitor] 启动健康监控(间隔: ${this.config.interval}ms)`),this.scheduleNextCheck()}stop(){if(this.checkTimer)clearTimeout(this.checkTimer),this.checkTimer=null,console.log("[HealthMonitor] 停止健康监控")}scheduleNextCheck(){this.checkTimer=setTimeout(async()=>{await this.performHealthCheck(),this.scheduleNextCheck()},this.config.interval)}async performHealthCheck(){if(this.isChecking)return console.warn("[HealthMonitor] 上一次检查仍在进行中"),this.getLastResult();this.isChecking=!0,this.lastCheckTime=Date.now(),this.setStatus("checking");try{let $=this.client.connectionStatus;if($==="connected"){await this.pingServer(),this.consecutiveFailures=0,this.setStatus("healthy");let Y={status:"healthy",timestamp:Date.now(),consecutiveFailures:0};return this.emit("healthCheck",Y),Y}else throw Error(`连接状态异常: ${$}`)}catch($){this.consecutiveFailures++;let Y=$;console.warn(`[HealthMonitor] 健康检查失败(${this.consecutiveFailures}/${this.config.failureThreshold}):`,Y.message);let Z;if(this.consecutiveFailures>=this.config.failureThreshold)Z="unhealthy",this.emit("unhealthy",this.consecutiveFailures,Y),console.log("[HealthMonitor] 达到失败阈值,触发重连..."),this.triggerReconnection().catch((Q)=>{console.error("[HealthMonitor] 重连失败:",Q)});else Z="degraded";this.setStatus(Z);let X={status:Z,timestamp:Date.now(),consecutiveFailures:this.consecutiveFailures,lastError:Y};return this.emit("healthCheck",X),X}finally{this.isChecking=!1}}async pingServer(){let $=new Promise((Z,X)=>{setTimeout(()=>X(Error("Health check timeout")),this.config.timeout)}),Y=(async()=>{if(this.client.availableTools.length===0){if(!this.client.server)throw Error("Server info not available")}})();await Promise.race([Y,$])}async triggerReconnection(){try{await this.client.disconnect(),await new Promise(($)=>setTimeout($,1000)),await this.client.connect(),console.log("[HealthMonitor] 重连成功"),this.consecutiveFailures=0,this.setStatus("healthy"),this.emit("reconnected")}catch($){throw console.error("[HealthMonitor] 重连失败:",$),$}}setStatus($){if(this.currentStatus!==$){let Y=this.currentStatus;this.currentStatus=$,this.emit("statusChanged",$,Y)}}getStatus(){return this.currentStatus}getLastResult(){return{status:this.currentStatus,timestamp:this.lastCheckTime,consecutiveFailures:this.consecutiveFailures}}getStatistics(){return{status:this.currentStatus,consecutiveFailures:this.consecutiveFailures,lastCheckTime:this.lastCheckTime,isChecking:this.isChecking,config:this.config}}async checkNow(){return this.performHealthCheck()}resetFailureCount(){if(this.consecutiveFailures=0,this.currentStatus!=="checking")this.setStatus("healthy")}}});import{Client as _K}from"@modelcontextprotocol/sdk/client/index.js";import{SSEClientTransport as LK}from"@modelcontextprotocol/sdk/client/sse.js";import{StdioClientTransport as wK}from"@modelcontextprotocol/sdk/client/stdio.js";import{EventEmitter as AK}from"events";function M5($){if(!($ instanceof Error))return{type:"unknown",isRetryable:!1,originalError:Error(String($))};let Y=$.message.toLowerCase();if(["command not found","no such file","permission denied","invalid configuration","malformed","syntax error"].some((Q)=>Y.includes(Q)))return{type:"config_error",isRetryable:!1,originalError:$};if(Y.includes("unauthorized")||Y.includes("401")||Y.includes("authentication failed"))return{type:"auth_error",isRetryable:!1,originalError:$};if(["timeout","connection refused","network error","temporary","try again","rate limit","too many requests","service unavailable","socket hang up","econnreset","enotfound","econnrefused","etimedout","503","429"].some((Q)=>Y.includes(Q)))return{type:"network_temporary",isRetryable:!0,originalError:$};return{type:"unknown",isRetryable:!0,originalError:$}}var c8;var j5=b(()=>{q6();D5();I5();A$();c8=class c8 extends AK{config;status="disconnected";sdkClient=null;tools=new Map;serverInfo=null;reconnectAttempts=0;MAX_RECONNECT_ATTEMPTS=5;reconnectTimer=null;isManualDisconnect=!1;oauthProvider=null;serverName;healthMonitor=null;constructor($,Y,Z){super();this.config=$;if(this.serverName=Y||"default",$.oauth?.enabled)this.oauthProvider=new Z4;if(Z?.enabled)this.healthMonitor=new m8(this,Z),this.healthMonitor.on("unhealthy",(X,Q)=>{this.emit("unhealthy",X,Q)}),this.healthMonitor.on("reconnected",()=>{this.emit("healthMonitorReconnected")})}get connectionStatus(){return this.status}get availableTools(){return Array.from(this.tools.values())}get server(){return this.serverInfo}get healthCheck(){return this.healthMonitor}async connect(){return this.connectWithRetry(3,1000)}async connectWithRetry($=3,Y=1000){if(this.status!=="disconnected")throw Error("客户端已连接或正在连接中");let Z=null;for(let X=1;X<=$;X++)try{await this.doConnect(),this.reconnectAttempts=0;return}catch(Q){Z=Q;let J=M5(Q);if(!J.isRetryable)throw console.error("[McpClient] 检测到永久性错误,放弃重试:",J.type),Q;if(X<$){let q=Y*Math.pow(2,X-1);console.warn(`[McpClient] 连接失败(${X}/${$}),${q}ms 后重试...`),await new Promise((K)=>setTimeout(K,q))}}throw Z||Error("连接失败")}async doConnect(){try{this.setStatus("connecting"),this.sdkClient=new _K({name:p3(),version:z$()},{capabilities:{roots:{listChanged:!0},sampling:{}}}),this.sdkClient.onclose=()=>{this.handleUnexpectedClose()};let $=await this.createTransport();await this.sdkClient.connect($);let Y=this.sdkClient.getServerVersion();if(this.serverInfo={name:Y?.name||"Unknown",version:Y?.version||"0.0.0"},await this.loadTools(),this.setStatus("connected"),this.emit("connected",this.serverInfo),this.healthMonitor)this.healthMonitor.start()}catch($){throw this.setStatus("error"),this.emit("error",$),$}}handleUnexpectedClose(){if(this.isManualDisconnect)return;if(this.status==="connected")console.warn("[McpClient] 检测到意外断连,准备重连..."),this.setStatus("error"),this.emit("error",Error("MCP服务器连接意外关闭")),this.scheduleReconnect()}scheduleReconnect(){if(this.reconnectTimer)clearTimeout(this.reconnectTimer),this.reconnectTimer=null;if(this.reconnectAttempts>=this.MAX_RECONNECT_ATTEMPTS){console.error("[McpClient] 达到最大重连次数,放弃重连"),this.emit("reconnectFailed");return}let $=Math.min(1000*Math.pow(2,this.reconnectAttempts),30000);this.reconnectAttempts++,console.log(`[McpClient] 将在 ${$}ms 后进行第 ${this.reconnectAttempts} 次重连...`),this.reconnectTimer=setTimeout(async()=>{try{if(this.sdkClient){try{await this.sdkClient.close()}catch{}this.sdkClient=null}this.setStatus("disconnected"),await this.doConnect(),console.log("[McpClient] 重连成功"),this.reconnectAttempts=0,this.emit("reconnected")}catch(Y){if(console.error("[McpClient] 重连失败:",Y),M5(Y).isRetryable)this.scheduleReconnect();else console.error("[McpClient] 检测到永久性错误,停止重连"),this.emit("reconnectFailed")}},$)}async disconnect(){if(this.isManualDisconnect=!0,this.healthMonitor)this.healthMonitor.stop();if(this.reconnectTimer)clearTimeout(this.reconnectTimer),this.reconnectTimer=null;if(this.sdkClient){try{await this.sdkClient.close()}catch($){console.warn("[McpClient] 断开连接时出错:",$)}this.sdkClient=null}this.tools.clear(),this.serverInfo=null,this.reconnectAttempts=0,this.setStatus("disconnected"),this.emit("disconnected"),this.isManualDisconnect=!1}async callTool($,Y={}){if(!this.sdkClient)throw Error("客户端未连接到服务器");if(!this.tools.has($))throw Error(`工具 "${$}" 不存在`);try{return await this.sdkClient.callTool({name:$,arguments:Y})}catch(Z){throw console.error(`[McpClient] 调用工具 "${$}" 失败:`,Z),Z}}async createTransport(){let{type:$,command:Y,args:Z,env:X,url:Q,headers:J,oauth:q}=this.config,K={...J};if(q?.enabled&&this.oauthProvider&&($==="sse"||$==="http"))try{let G=await this.oauthProvider.getValidToken(this.serverName,q);if(!G){console.log(`[McpClient] 服务器 "${this.serverName}" 需要 OAuth 认证`);let U=await this.oauthProvider.authenticate(this.serverName,q);K.Authorization=`Bearer ${U.accessToken}`}else K.Authorization=`Bearer ${G}`}catch(G){throw console.error("[McpClient] OAuth 认证失败:",G),Error(`OAuth 认证失败: ${G instanceof Error?G.message:String(G)}`)}if($==="stdio"){if(!Y)throw Error("stdio 传输需要 command 参数");let G={};for(let[U,O]of Object.entries(process.env))if(O!==void 0)G[U]=O;return new wK({command:Y,args:Z||[],env:{...G,...X},stderr:"ignore"})}else if($==="sse"){if(!Q)throw Error("sse 传输需要 url 参数");return new LK(new URL(Q),{requestInit:{headers:K}})}else if($==="http"){if(!Q)throw Error("http 传输需要 url 参数");let{StreamableHTTPClientTransport:G}=await import("@modelcontextprotocol/sdk/client/streamableHttp.js");return new G(new URL(Q),{requestInit:{headers:K}})}throw Error(`不支持的传输类型: ${$}`)}async loadTools(){if(!this.sdkClient)return;try{let $=await this.sdkClient.listTools();if(this.tools.clear(),$.tools)for(let Y of $.tools)this.tools.set(Y.name,Y);this.emit("toolsUpdated",this.availableTools)}catch($){throw console.error("[McpClient] 加载工具失败:",$),$}}setStatus($){let Y=this.status;this.status=$,this.emit("statusChanged",$,Y)}async initialize(){return this.connect()}async destroy(){return this.disconnect()}async connectToServer($){return this.connect()}async disconnectFromServer($){return this.disconnect()}async listResources($){if(!this.sdkClient)return[];try{return(await this.sdkClient.listResources()).resources||[]}catch{return[]}}async listTools($){return this.availableTools}async readResource($,Y){if(!this.sdkClient)throw Error("客户端未连接");return(await this.sdkClient.readResource({uri:$})).contents?.[0]||{uri:$,text:""}}}});import{EventEmitter as bK}from"events";var t1;var b$=b(()=>{w5();j5();A$();t1=class t1 extends bK{static instance=null;servers=new Map;isDiscovering=!1;constructor(){super()}static getInstance(){if(!t1.instance)t1.instance=new t1;return t1.instance}async registerServer($,Y){if(this.servers.has($))throw Error(`MCP服务器 "${$}" 已经注册`);let Z=new c8(Y,$,Y.healthCheck),X={config:Y,client:Z,status:"disconnected",tools:[]};this.setupClientEventHandlers(Z,X,$),this.servers.set($,X),this.emit("serverRegistered",$,X);try{await this.connectServer($)}catch(Q){console.warn(`MCP服务器 "${$}" 连接失败:`,Q)}}async unregisterServer($){let Y=this.servers.get($);if(!Y)return;try{await Y.client.disconnect()}catch(Z){console.warn(`断开MCP服务器 "${$}" 时出错:`,Z)}this.servers.delete($),this.emit("serverUnregistered",$)}async connectServer($){let Y=this.servers.get($);if(!Y)throw Error(`MCP服务器 "${$}" 未注册`);if(Y.status==="connected")return;try{Y.status="connecting",await Y.client.connect(),Y.connectedAt=new Date,Y.lastError=void 0,Y.tools=Y.client.availableTools}catch(Z){throw Y.lastError=Z,Y.status="error",Z}}async disconnectServer($){let Y=this.servers.get($);if(!Y)return;await Y.client.disconnect(),Y.connectedAt=void 0}async getAvailableTools(){let $=[],Y=new Map;for(let[Z,X]of this.servers)if(X.status==="connected")for(let Q of X.tools){let J=Y.get(Q.name)||0;Y.set(Q.name,J+1)}for(let[Z,X]of this.servers)if(X.status==="connected")for(let Q of X.tools){let q=(Y.get(Q.name)||0)>1?`${Z}__${Q.name}`:Q.name,K=$4(X.client,Z,Q,q);$.push(K)}return $}async findTool($){for(let[Y,Z]of this.servers)if(Z.status==="connected"){let X=Z.tools.find((Q)=>Q.name===$);if(X)return $4(Z.client,Y,X)}return null}getToolsByServer($){let Y=this.servers.get($);if(!Y||Y.status!=="connected")return[];return Y.tools.map((Z)=>$4(Y.client,$,Z))}getServerStatus($){return this.servers.get($)||null}getAllServers(){return new Map(this.servers)}async refreshAllTools(){let $=[];for(let[Y,Z]of this.servers)if(Z.status==="connected")$.push(this.refreshServerTools(Y));await Promise.allSettled($)}async refreshServerTools($){let Y=this.servers.get($);if(!Y||Y.status!=="connected")return;try{let Z=Y.client.availableTools,X=Y.tools.length;Y.tools=Z,this.emit("toolsUpdated",$,Z,X)}catch(Z){console.warn(`刷新服务器 "${$}" 工具列表失败:`,Z)}}setupClientEventHandlers($,Y,Z){$.on("connected",(X)=>{Y.status="connected",Y.connectedAt=new Date,Y.tools=$.availableTools,this.emit("serverConnected",Z,X)}),$.on("disconnected",()=>{Y.status="disconnected",Y.connectedAt=void 0,Y.tools=[],this.emit("serverDisconnected",Z)}),$.on("error",(X)=>{Y.status="error",Y.lastError=X,this.emit("serverError",Z,X)}),$.on("toolsUpdated",(X)=>{let Q=Y.tools.length;Y.tools=X,this.emit("toolsUpdated",Z,X,Q)}),$.on("statusChanged",(X,Q)=>{Y.status=X,this.emit("serverStatusChanged",Z,X,Q)})}async discoverServers(){if(this.isDiscovering)return Array.from(this.servers.values());this.isDiscovering=!0,this.emit("discoveryStarted");try{return Array.from(this.servers.values())}finally{this.isDiscovering=!1,this.emit("discoveryCompleted")}}async registerServers($){let Y=Object.entries($).map(([Z,X])=>this.registerServer(Z,X).catch((Q)=>{return console.warn(`注册MCP服务器 "${Z}" 失败:`,Q),Q}));await Promise.allSettled(Y)}getStatistics(){let $=0,Y=0,Z=0;for(let X of this.servers.values())if(X.status==="connected")$++,Y+=X.tools.length;else if(X.status==="error")Z++;return{totalServers:this.servers.size,connectedServers:$,errorServers:Z,totalTools:Y,isDiscovering:this.isDiscovering}}async disconnectAll(){let $=[];for(let[Y,Z]of this.servers)if(Z.status==="connected")$.push(Z.client.disconnect().catch((X)=>{console.warn(`断开 MCP 服务器 "${Y}" 时出错:`,X)}));await Promise.allSettled($),this.servers.clear()}}});function i8($,Y){return{...$,...Y,PreToolUse:Y.PreToolUse??$.PreToolUse,PostToolUse:Y.PostToolUse??$.PostToolUse,PostToolUseFailure:Y.PostToolUseFailure??$.PostToolUseFailure,PermissionRequest:Y.PermissionRequest??$.PermissionRequest,UserPromptSubmit:Y.UserPromptSubmit??$.UserPromptSubmit,SessionStart:Y.SessionStart??$.SessionStart,SessionEnd:Y.SessionEnd??$.SessionEnd,Stop:Y.Stop??$.Stop,SubagentStop:Y.SubagentStop??$.SubagentStop,Notification:Y.Notification??$.Notification,Compaction:Y.Compaction??$.Compaction}}function v5(){let $={};if(process.env.BLADE_DISABLE_HOOKS==="true")$.enabled=!1;if(process.env.BLADE_HOOK_TIMEOUT){let Y=parseInt(process.env.BLADE_HOOK_TIMEOUT,10);if(!isNaN(Y)&&Y>0)$.defaultTimeout=Y}return $}var l8;var P5=b(()=>{l8={enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,PreToolUse:[],PostToolUse:[],PostToolUseFailure:[],PermissionRequest:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]}});class r8{executedHooks=new Map;canExecute($,Y){if(!this.executedHooks.has($))this.executedHooks.set($,new Set);if(this.executedHooks.get($).has(Y))return console.warn(`[HookGuard] Hook ${Y} for tool ${$} already executed, skipping`),!1;return!0}markExecuted($,Y){let Z=this.executedHooks.get($);if(Z)Z.add(Y)}cleanup($){this.executedHooks.delete($)}cleanupAll(){this.executedHooks.clear()}}var e0,a8,n8;var R$=b(()=>{((W)=>{W.PreToolUse="PreToolUse";W.PostToolUse="PostToolUse";W.PostToolUseFailure="PostToolUseFailure";W.PermissionRequest="PermissionRequest";W.UserPromptSubmit="UserPromptSubmit";W.SessionStart="SessionStart";W.SessionEnd="SessionEnd";W.Stop="Stop";W.SubagentStop="SubagentStop";W.Notification="Notification";W.Compaction="Compaction"})(e0||={});((X)=>{X.Approve="approve";X.Block="block";X.Async="async"})(a8||={});((X)=>{X.Allow="allow";X.Deny="deny";X.Ask="ask"})(n8||={})});import{z as V}from"zod";function T5($){let Y=oK.safeParse($);if(Y.success)return{success:!0,data:Y.data};return{success:!1,error:Y.error}}var u0,PK,TK,SK,kK,CK,fK,hK,xK,pK,uK,gK,P_,dK,mK,cK,lK,iK,rK,aK,nK,oK,sK,tK,eK,o8,$G,p0,T_;var S5=b(()=>{R$();u0=V.object({hook_event_name:V.nativeEnum(e0),hook_execution_id:V.string(),timestamp:V.string(),project_dir:V.string(),session_id:V.string(),permission_mode:V.enum(["default","autoEdit","yolo","plan"]),_metadata:V.object({blade_version:V.string(),hook_timeout_ms:V.number()}).optional()}),PK=u0.extend({hook_event_name:V.literal("PreToolUse"),tool_name:V.string(),tool_use_id:V.string(),tool_input:V.record(V.unknown())}),TK=u0.extend({hook_event_name:V.literal("PostToolUse"),tool_name:V.string(),tool_use_id:V.string(),tool_input:V.record(V.unknown()),tool_response:V.unknown()}),SK=u0.extend({hook_event_name:V.literal("Stop"),reason:V.string().optional()}),kK=u0.extend({hook_event_name:V.literal("PostToolUseFailure"),tool_name:V.string(),tool_use_id:V.string(),tool_input:V.record(V.unknown()),error:V.string(),error_type:V.string().optional(),is_interrupt:V.boolean(),is_timeout:V.boolean()}),CK=u0.extend({hook_event_name:V.literal("PermissionRequest"),tool_name:V.string(),tool_use_id:V.string(),tool_input:V.record(V.unknown())}),fK=u0.extend({hook_event_name:V.literal("UserPromptSubmit"),user_prompt:V.string(),has_images:V.boolean(),image_count:V.number()}),hK=u0.extend({hook_event_name:V.literal("SessionStart"),is_resume:V.boolean(),resume_session_id:V.string().optional()}),xK=u0.extend({hook_event_name:V.literal("SessionEnd"),reason:V.enum(["user_exit","error","max_turns","idle_timeout","ctrl_c","clear","logout","other"])}),pK=u0.extend({hook_event_name:V.literal("SubagentStop"),agent_type:V.string(),task_description:V.string().optional(),success:V.boolean(),result_summary:V.string().optional(),error:V.string().optional()}),uK=u0.extend({hook_event_name:V.literal("Notification"),notification_type:V.enum(["permission_prompt","idle_prompt","auth_success","elicitation_dialog","info","warning","error"]),title:V.string().optional(),message:V.string()}),gK=u0.extend({hook_event_name:V.literal("Compaction"),trigger:V.enum(["manual","auto"]),messages_before:V.number(),tokens_before:V.number()}),P_=V.discriminatedUnion("hook_event_name",[PK,TK,SK,kK,CK,fK,hK,xK,pK,uK,gK]),dK=V.object({hookEventName:V.literal("PreToolUse"),permissionDecision:V.nativeEnum(n8).optional(),permissionDecisionReason:V.string().optional(),updatedInput:V.record(V.unknown()).optional()}),mK=V.object({hookEventName:V.literal("PostToolUse"),additionalContext:V.string().optional(),updatedOutput:V.unknown().optional()}),cK=V.object({hookEventName:V.literal("Stop"),continue:V.boolean().optional(),continueReason:V.string().optional()}),lK=V.object({hookEventName:V.literal("SubagentStop"),continue:V.boolean().optional(),continueReason:V.string().optional(),additionalContext:V.string().optional()}),iK=V.object({hookEventName:V.literal("PermissionRequest"),permissionDecision:V.enum(["approve","deny","ask"]).optional(),permissionDecisionReason:V.string().optional()}),rK=V.object({hookEventName:V.literal("UserPromptSubmit"),updatedPrompt:V.string().optional(),contextInjection:V.string().optional()}),aK=V.object({hookEventName:V.literal("SessionStart"),env:V.record(V.string()).optional()}),nK=V.object({hookEventName:V.literal("Compaction"),blockCompaction:V.boolean().optional(),blockReason:V.string().optional()}),oK=V.object({decision:V.object({behavior:V.nativeEnum(a8)}).optional(),systemMessage:V.string().optional(),hookSpecificOutput:V.discriminatedUnion("hookEventName",[dK,mK,cK,lK,iK,rK,aK,nK]).optional(),suppressOutput:V.boolean().optional()}),sK=V.object({type:V.literal("command"),command:V.string(),timeout:V.number().positive().optional(),statusMessage:V.string().optional()}),tK=V.object({type:V.literal("prompt"),prompt:V.string(),timeout:V.number().positive().optional()}),eK=V.discriminatedUnion("type",[sK,tK]),o8=V.union([V.string(),V.array(V.string())]),$G=V.object({tools:o8.optional(),paths:o8.optional(),commands:o8.optional()}),p0=V.object({name:V.string().optional(),matcher:$G.optional(),hooks:V.array(eK)}),T_=V.object({enabled:V.boolean().optional(),defaultTimeout:V.number().positive().optional(),timeoutBehavior:V.enum(["ignore","deny","ask"]).optional(),failureBehavior:V.enum(["ignore","deny","ask"]).optional(),maxConcurrentHooks:V.number().positive().optional(),PreToolUse:V.array(p0).optional(),PostToolUse:V.array(p0).optional(),PostToolUseFailure:V.array(p0).optional(),PermissionRequest:V.array(p0).optional(),UserPromptSubmit:V.array(p0).optional(),SessionStart:V.array(p0).optional(),SessionEnd:V.array(p0).optional(),Stop:V.array(p0).optional(),SubagentStop:V.array(p0).optional(),Notification:V.array(p0).optional(),Compaction:V.array(p0).optional()})});class s8{parse($,Y,Z){if($.timedOut){let Q=Z?.timeoutBehavior||"ignore",J="Hook timeout";if(Q==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Y};else if(Q==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Y};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Y}}let X=this.tryParseJSON($.stdout);if(X){let Q=T5(X);if(!Q.success){let q="error"in Q?Q.error.message:"Unknown validation error",K=Z?.failureBehavior||"ignore",G=`Invalid hook output JSON: ${q}`;if(K==="deny")return{success:!1,blocking:!0,error:G,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Y};else if(K==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${G}. Continue?`,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Y};else return{success:!1,blocking:!1,warning:G,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Y}}let J=Q.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:Y};if(J.decision?.behavior==="async")return{success:!0,output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Y};return{success:!0,output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Y}}return this.parseByExitCode($,Y,Z)}parseByExitCode($,Y,Z){let X=$.exitCode;switch(X){case 0:return{success:!0,stdout:$.stdout,stderr:$.stderr,exitCode:X,hook:Y};case 2:return{success:!1,blocking:!0,error:$.stderr||$.stdout||"Hook returned exit code 2",stdout:$.stdout,stderr:$.stderr,exitCode:X,hook:Y};case 124:{let Q=Z?.timeoutBehavior||"ignore",J="Hook timeout";if(Q==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:X,hook:Y};else if(Q==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:$.stdout,stderr:$.stderr,exitCode:X,hook:Y};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:X,hook:Y}}default:{let Q=Z?.failureBehavior||"ignore",J=$.stderr||$.stdout||`Hook failed with exit code ${X}`;if(Q==="deny")return{success:!1,blocking:!0,error:J,stdout:$.stdout,stderr:$.stderr,exitCode:X,hook:Y};else if(Q==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${J}. Continue?`,stdout:$.stdout,stderr:$.stderr,exitCode:X,hook:Y};else return{success:!1,blocking:!1,warning:J,stdout:$.stdout,stderr:$.stderr,exitCode:X,hook:Y}}}}tryParseJSON($){try{let Y=$.trim();if(!Y)return null;let Z=Y.match(/^\s*(\{[\s\S]*\})\s*$/);if(!Z)return null;return JSON.parse(Z[1])}catch{return null}}}var k5=b(()=>{S5()});import{spawn as YG}from"child_process";class t8{content="";maxSize;constructor($){this.maxSize=$}append($){if(this.content.length<this.maxSize){let Y=this.maxSize-this.content.length;this.content+=$.substring(0,Y)}}getContent(){return this.content}isFull(){return this.content.length>=this.maxSize}}class e8{MAX_STDOUT_SIZE=1048576;MAX_STDERR_SIZE=1048576;MAX_INPUT_SIZE=102400;async execute($,Y,Z,X){let Q=JSON.stringify(Y);if(Q.length>this.MAX_INPUT_SIZE)throw Error(`Hook input too large: ${Q.length} bytes (max ${this.MAX_INPUT_SIZE})`);let J=this.createSafeEnv(Y),q=YG($,[],{shell:!0,env:J,cwd:Z.projectDir,timeout:X}),K=new t8(this.MAX_STDOUT_SIZE),G=new t8(this.MAX_STDERR_SIZE);q.stdout.setEncoding("utf8"),q.stderr.setEncoding("utf8"),q.stdout.on("data",(U)=>{K.append(U)}),q.stderr.on("data",(U)=>{G.append(U)});try{q.stdin.write(Q),q.stdin.end()}catch(U){throw q.kill("SIGTERM"),Error(`Failed to write hook input: ${U}`)}return new Promise((U,O)=>{let W=!1,F=!1,H=null,z=()=>{if(H&&Z.abortSignal)Z.abortSignal.removeEventListener("abort",H),H=null},N=setTimeout(()=>{W=!0,q.kill("SIGKILL")},X);if(q.on("close",(L)=>{if(F)return;F=!0,clearTimeout(N),z(),U({stdout:K.getContent(),stderr:G.getContent(),exitCode:W?124:L??1,timedOut:W})}),q.on("error",(L)=>{if(F)return;F=!0,clearTimeout(N),z(),O(L)}),Z.abortSignal)H=()=>{if(F)return;F=!0,clearTimeout(N),z(),q.kill("SIGTERM"),U({stdout:K.getContent(),stderr:"Hook cancelled by abort signal",exitCode:1,timedOut:!1})},Z.abortSignal.addEventListener("abort",H)})}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 C5=()=>{};class $9{processExecutor=new e8;outputParser=new s8;async executePreToolHooks($,Y,Z){if($.length===0)return{decision:"allow"};let X="tool_input"in Y?Y.tool_input:{},Q=[];for(let J of $)try{let q={...Y,...X&&{tool_input:X}},K=await this.executeHook(J,q,Z);if(!K.success){if(K.blocking)return{decision:"deny",reason:K.error};if(K.needsConfirmation)return{decision:"ask",reason:K.warning||K.error};if(K.warning)Q.push(K.warning);continue}let G=K.output?.hookSpecificOutput;if(G&&"permissionDecision"in G){switch(G.permissionDecision){case"deny":return{decision:"deny",reason:G.permissionDecisionReason};case"ask":return{decision:"ask",reason:G.permissionDecisionReason};case"allow":break}if("updatedInput"in G&&G.updatedInput)X={...X,...G.updatedInput}}}catch(q){let K=q instanceof Error?q.message:String(q);if(Q.push(`Hook failed: ${K}`),Z.config.failureBehavior==="deny")return{decision:"deny",reason:K};else if(Z.config.failureBehavior==="ask")return{decision:"ask",reason:`Hook failed: ${K}. Continue?`}}return{decision:"allow",modifiedInput:X,warning:Q.length>0?Q.join(`
72
+ `):void 0}}async executePostToolHooks($,Y,Z){if($.length===0)return{};let X=Z.config.maxConcurrentHooks||5,Q=await this.executeHooksConcurrently($,Y,Z,X),J=[],q=void 0,K=[];for(let G of Q){if(!G.success&&G.warning){K.push(G.warning);continue}let U=G.output?.hookSpecificOutput;if(U&&"additionalContext"in U){if(U.additionalContext)J.push(U.additionalContext);if("updatedOutput"in U&&U.updatedOutput!==void 0)q=U.updatedOutput}}return{additionalContext:J.length>0?J.join(`
73
73
 
74
- `):void 0,modifiedOutput:q,warning:G.length>0?G.join(`
74
+ `):void 0,modifiedOutput:q,warning:K.length>0?K.join(`
75
75
  `):void 0}}async executeStopHooks($,Y,Z){if($.length===0)return{shouldStop:!0};let X=[];for(let Q of $)try{let J=await this.executeHook(Q,Y,Z);if(!J.success){if(J.warning)X.push(J.warning);continue}let q=J.output?.hookSpecificOutput;if(q&&"continue"in q&&q.continue===!1)return{shouldStop:!1,continueReason:q.continueReason,warning:X.length>0?X.join(`
76
76
  `):void 0}}catch(J){let q=J instanceof Error?J.message:String(J);X.push(`Hook failed: ${q}`)}return{shouldStop:!0,warning:X.length>0?X.join(`
77
- `):void 0}}async executeSubagentStopHooks($,Y,Z){if($.length===0)return{shouldStop:!0};let X=[],Q=[];for(let J of $)try{let q=await this.executeHook(J,Y,Z);if(!q.success){if(q.warning)X.push(q.warning);continue}let G=q.output?.hookSpecificOutput;if(G&&"continue"in G){if(G.continue===!1)return{shouldStop:!1,continueReason:G.continueReason,warning:X.length>0?X.join(`
78
- `):void 0};if("additionalContext"in G&&G.additionalContext)Q.push(G.additionalContext)}}catch(q){let G=q instanceof Error?q.message:String(q);X.push(`Hook failed: ${G}`)}return{shouldStop:!0,additionalContext:Q.length>0?Q.join(`
77
+ `):void 0}}async executeSubagentStopHooks($,Y,Z){if($.length===0)return{shouldStop:!0};let X=[],Q=[];for(let J of $)try{let q=await this.executeHook(J,Y,Z);if(!q.success){if(q.warning)X.push(q.warning);continue}let K=q.output?.hookSpecificOutput;if(K&&"continue"in K){if(K.continue===!1)return{shouldStop:!1,continueReason:K.continueReason,warning:X.length>0?X.join(`
78
+ `):void 0};if("additionalContext"in K&&K.additionalContext)Q.push(K.additionalContext)}}catch(q){let K=q instanceof Error?q.message:String(q);X.push(`Hook failed: ${K}`)}return{shouldStop:!0,additionalContext:Q.length>0?Q.join(`
79
79
 
80
80
  `):void 0,warning:X.length>0?X.join(`
81
- `):void 0}}async executePermissionRequestHooks($,Y,Z){if($.length===0)return{decision:"ask"};let X=[];for(let Q of $)try{let J=await this.executeHook(Q,Y,Z);if(!J.success){if(J.warning)X.push(J.warning);continue}let q=J.output?.hookSpecificOutput;if(q&&"permissionDecision"in q){let G=q.permissionDecision;if(G==="approve"||G==="deny")return{decision:G,reason:q.permissionDecisionReason,warning:X.length>0?X.join(`
81
+ `):void 0}}async executePermissionRequestHooks($,Y,Z){if($.length===0)return{decision:"ask"};let X=[];for(let Q of $)try{let J=await this.executeHook(Q,Y,Z);if(!J.success){if(J.warning)X.push(J.warning);continue}let q=J.output?.hookSpecificOutput;if(q&&"permissionDecision"in q){let K=q.permissionDecision;if(K==="approve"||K==="deny")return{decision:K,reason:q.permissionDecisionReason,warning:X.length>0?X.join(`
82
82
  `):void 0}}}catch(J){let q=J instanceof Error?J.message:String(J);X.push(`Hook failed: ${q}`)}return{decision:"ask",warning:X.length>0?X.join(`
83
- `):void 0}}async executeUserPromptSubmitHooks($,Y,Z){if($.length===0)return{proceed:!0};let X=[],Q=[],J;for(let q of $)try{let G=await this.executeHook(q,Y,Z);if(!G.success){if(G.blocking)return{proceed:!1,warning:G.error};if(G.warning)X.push(G.warning);continue}if(G.stdout&&G.stdout.trim())Q.push(G.stdout.trim());let K=G.output?.hookSpecificOutput;if(K&&"updatedPrompt"in K){if(K.updatedPrompt)J=K.updatedPrompt;if(K.contextInjection)Q.push(K.contextInjection)}}catch(G){let K=G instanceof Error?G.message:String(G);X.push(`Hook failed: ${K}`)}return{proceed:!0,updatedPrompt:J,contextInjection:Q.length>0?Q.join(`
83
+ `):void 0}}async executeUserPromptSubmitHooks($,Y,Z){if($.length===0)return{proceed:!0};let X=[],Q=[],J;for(let q of $)try{let K=await this.executeHook(q,Y,Z);if(!K.success){if(K.blocking)return{proceed:!1,warning:K.error};if(K.warning)X.push(K.warning);continue}if(K.stdout&&K.stdout.trim())Q.push(K.stdout.trim());let G=K.output?.hookSpecificOutput;if(G&&"updatedPrompt"in G){if(G.updatedPrompt)J=G.updatedPrompt;if(G.contextInjection)Q.push(G.contextInjection)}}catch(K){let G=K instanceof Error?K.message:String(K);X.push(`Hook failed: ${G}`)}return{proceed:!0,updatedPrompt:J,contextInjection:Q.length>0?Q.join(`
84
84
 
85
85
  `):void 0,warning:X.length>0?X.join(`
86
- `):void 0}}async executeSessionStartHooks($,Y,Z){if($.length===0)return{proceed:!0};let X=[],Q={};for(let J of $)try{let q=await this.executeHook(J,Y,Z);if(!q.success){if(q.blocking)return{proceed:!1,warning:q.error};if(q.warning)X.push(q.warning);continue}let G=q.output?.hookSpecificOutput;if(G&&"env"in G&&G.env)Object.assign(Q,G.env)}catch(q){let G=q instanceof Error?q.message:String(q);X.push(`Hook failed: ${G}`)}return{proceed:!0,env:Object.keys(Q).length>0?Q:void 0,warning:X.length>0?X.join(`
86
+ `):void 0}}async executeSessionStartHooks($,Y,Z){if($.length===0)return{proceed:!0};let X=[],Q={};for(let J of $)try{let q=await this.executeHook(J,Y,Z);if(!q.success){if(q.blocking)return{proceed:!1,warning:q.error};if(q.warning)X.push(q.warning);continue}let K=q.output?.hookSpecificOutput;if(K&&"env"in K&&K.env)Object.assign(Q,K.env)}catch(q){let K=q instanceof Error?q.message:String(q);X.push(`Hook failed: ${K}`)}return{proceed:!0,env:Object.keys(Q).length>0?Q:void 0,warning:X.length>0?X.join(`
87
87
  `):void 0}}async executeSessionEndHooks($,Y,Z){if($.length===0)return{};let X=[],Q=Z.config.maxConcurrentHooks||5,J=await this.executeHooksConcurrently($,Y,Z,Q);for(let q of J)if(!q.success&&q.warning)X.push(q.warning);return{warning:X.length>0?X.join(`
88
- `):void 0}}async executePostToolUseFailureHooks($,Y,Z){if($.length===0)return{};let X=[],Q=[],J=Z.config.maxConcurrentHooks||5,q=await this.executeHooksConcurrently($,Y,Z,J);for(let G of q){if(!G.success&&G.warning){X.push(G.warning);continue}if(G.stdout&&G.stdout.trim())Q.push(G.stdout.trim())}return{additionalContext:Q.length>0?Q.join(`
88
+ `):void 0}}async executePostToolUseFailureHooks($,Y,Z){if($.length===0)return{};let X=[],Q=[],J=Z.config.maxConcurrentHooks||5,q=await this.executeHooksConcurrently($,Y,Z,J);for(let K of q){if(!K.success&&K.warning){X.push(K.warning);continue}if(K.stdout&&K.stdout.trim())Q.push(K.stdout.trim())}return{additionalContext:Q.length>0?Q.join(`
89
89
 
90
90
  `):void 0,warning:X.length>0?X.join(`
91
- `):void 0}}async executeNotificationHooks($,Y,Z){let X="message"in Y?Y.message:"";if($.length===0)return{suppress:!1,message:X};let Q=[],J=!1,q=X;for(let G of $)try{let K=await this.executeHook(G,Y,Z);if(!K.success){if(K.warning)Q.push(K.warning);continue}if(K.output?.suppressOutput){J=!0;break}if(K.stdout&&K.stdout.trim())q=K.stdout.trim()}catch(K){let W=K instanceof Error?K.message:String(K);Q.push(`Hook failed: ${W}`)}return{suppress:J,message:q,warning:Q.length>0?Q.join(`
91
+ `):void 0}}async executeNotificationHooks($,Y,Z){let X="message"in Y?Y.message:"";if($.length===0)return{suppress:!1,message:X};let Q=[],J=!1,q=X;for(let K of $)try{let G=await this.executeHook(K,Y,Z);if(!G.success){if(G.warning)Q.push(G.warning);continue}if(G.output?.suppressOutput){J=!0;break}if(G.stdout&&G.stdout.trim())q=G.stdout.trim()}catch(G){let U=G instanceof Error?G.message:String(G);Q.push(`Hook failed: ${U}`)}return{suppress:J,message:q,warning:Q.length>0?Q.join(`
92
92
  `):void 0}}async executeCompactionHooks($,Y,Z){if($.length===0)return{blockCompaction:!1};let X=[];for(let Q of $)try{let J=await this.executeHook(Q,Y,Z);if(!J.success){if(J.warning)X.push(J.warning);continue}let q=J.output?.hookSpecificOutput;if(q&&"blockCompaction"in q&&q.blockCompaction)return{blockCompaction:!0,blockReason:q.blockReason,warning:X.length>0?X.join(`
93
93
  `):void 0}}catch(J){let q=J instanceof Error?J.message:String(J);X.push(`Hook failed: ${q}`)}return{blockCompaction:!1,warning:X.length>0?X.join(`
94
- `):void 0}}async executeHook($,Y,Z){if($.type==="command")return this.executeCommandHook($,Y,Z);throw Error(`Hook type ${$.type} not yet implemented`)}async executeCommandHook($,Y,Z){let X=($.timeout??Z.config.defaultTimeout??60)*1000;try{let Q=await this.processExecutor.execute($.command,Y,Z,X);return this.outputParser.parse(Q,$,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch(Q){return{success:!1,blocking:!1,error:Q instanceof Error?Q.message:String(Q),hook:$}}}async executeHooksConcurrently($,Y,Z,X){let Q=[],J=new Set;for(let q of $){if(J.size>=X)await Promise.race(J);let G=this.executeHook(q,Y,Z).catch((W)=>({success:!1,blocking:!1,error:W instanceof Error?W.message:String(W),hook:q})),K=G.then(()=>{J.delete(K)}).catch(()=>{J.delete(K)});J.add(K),Q.push(G)}return Promise.all(Q)}}var j5=b(()=>{I5();M5();w$()});import t9 from"picomatch";class e9{matches($,Y){if(!$)return!0;if($.tools&&Y.toolName){if(!this.matchTools($.tools,Y))return!1}if($.paths&&Y.filePath){if(!this.matchPaths($.paths,Y.filePath))return!1}if($.commands&&Y.command){if(!this.matchCommands($.commands,Y.command))return!1}return!0}matchTools($,Y){if(Array.isArray($))return $.some((Z)=>this.matchToolWithParams(Z,Y));return this.matchToolWithParams($,Y)}matchPaths($,Y){if(Array.isArray($))return $.some((X)=>{return t9(X)(Y)});return t9($)(Y)}matchCommands($,Y){if(Array.isArray($))return $.some((Z)=>this.matchPattern(Y,Z));return this.matchPattern(Y,$)}matchToolWithParams($,Y){let{toolName:Z,command:X,filePath:Q}=Y,J=hG.exec($);if(!J)return this.matchPattern(Z,$);let[,q,G]=J;if(!this.matchPattern(Z,q))return!1;let K=this.getArgValue(Z,X,Q);if(!K)return!1;return this.matchGlobOrPattern(K,G)}getArgValue($,Y,Z){if($==="Bash"||$==="BashTool")return Y;if(["Read","Edit","Write","Glob","Grep"].includes($))return Z;return Y||Z}matchGlobOrPattern($,Y){if(/[*?[\]{}!]/.test(Y))try{return t9(Y,{bash:!0,dot:!0})($)}catch{}if(Y.endsWith("*")){let Z=Y.slice(0,-1);return $.startsWith(Z)}return $===Y}matchPattern($,Y){if(Y==="*")return!0;if(!Y.includes("|")&&!/[.*+?^${}()|[\]\\]/.test(Y))return $===Y;if(Y.includes("|"))return Y.split("|").map((X)=>X.trim()).includes($);try{return new RegExp(Y).test($)}catch{return $===Y}}}var hG;var y5=b(()=>{hG=/^([A-Za-z0-9_|]+)\((.+)\)$/});import{nanoid as x0}from"nanoid";class H1{static instance=null;config=m9;executor=new s9;guard=new c9;matcher=new e9;sessionDisabled=!1;constructor(){}static getInstance(){if(!H1.instance)H1.instance=new H1;return H1.instance}loadConfig($){let Y=d9(m9,$),Z=b5();Y=d9(Y,Z),this.config=Y}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"),Y=await import("node:path");try{let Z=Y.join(process.cwd(),".blade","settings.local.json"),X=await $.readFile(Z,"utf-8"),Q=JSON.parse(X);if(Q.hooks)this.loadConfig(Q.hooks)}catch{}}async executePreToolHooks($,Y,Z,X){if(!this.isEnabled())return{decision:"allow"};if(X.permissionMode==="plan")return{decision:"allow"};if(!this.guard.canExecute(Y,"PreToolUse"))return{decision:"allow"};let Q={hook_event_name:"PreToolUse",hook_execution_id:x0(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Y,tool_input:Z,project_dir:X.projectDir,session_id:X.sessionId,permission_mode:X.permissionMode},J=this.getMatchingHooks("PreToolUse",{toolName:$,filePath:this.extractFilePath(Z),command:this.extractCommand($,Z)});if(J.length===0)return{decision:"allow"};let q={projectDir:X.projectDir,sessionId:X.sessionId,permissionMode:X.permissionMode,config:this.config,abortSignal:X.abortSignal};try{let G=await this.executor.executePreToolHooks(J,Q,q);if(this.guard.markExecuted(Y,"PreToolUse"),X.permissionMode==="yolo"){if(G.decision==="deny")return G;return{decision:"allow",modifiedInput:G.modifiedInput,warning:G.warning,reason:G.reason}}return G}catch(G){return console.error("[HookManager] Error executing PreToolUse hooks:",G),{decision:"allow",warning:`Hook execution failed: ${G instanceof Error?G.message:String(G)}`}}}async executePostToolHooks($,Y,Z,X,Q){if(!this.isEnabled())return{};if(Q.permissionMode==="plan")return{};if(!this.guard.canExecute(Y,"PostToolUse"))return{};let J={hook_event_name:"PostToolUse",hook_execution_id:x0(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Y,tool_input:Z,tool_response:X,project_dir:Q.projectDir,session_id:Q.sessionId,permission_mode:Q.permissionMode},q=this.getMatchingHooks("PostToolUse",{toolName:$,filePath:this.extractFilePath(Z),command:this.extractCommand($,Z)});if(q.length===0)return{};let G={projectDir:Q.projectDir,sessionId:Q.sessionId,permissionMode:Q.permissionMode,config:this.config,abortSignal:Q.abortSignal};try{let K=await this.executor.executePostToolHooks(q,J,G);return this.guard.markExecuted(Y,"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(Y)}}async executeStopHooks($){if(!this.isEnabled())return{shouldStop:!0};let Y={hook_event_name:"Stop",hook_execution_id:x0(),timestamp:new Date().toISOString(),project_dir:$.projectDir,session_id:$.sessionId,permission_mode:$.permissionMode,reason:$.reason},Z=this.getMatchingHooks("Stop",{});if(Z.length===0)return{shouldStop:!0};let X={projectDir:$.projectDir,sessionId:$.sessionId,permissionMode:$.permissionMode,config:this.config,abortSignal:$.abortSignal};try{return await this.executor.executeStopHooks(Z,Y,X)}catch(Q){return console.error("[HookManager] Error executing Stop hooks:",Q),{shouldStop:!0,warning:`Hook execution failed: ${Q instanceof Error?Q.message:String(Q)}`}}}async executeSubagentStopHooks($,Y){if(!this.isEnabled())return{shouldStop:!0};let Z={hook_event_name:"SubagentStop",hook_execution_id:x0(),timestamp:new Date().toISOString(),project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode,agent_type:$,task_description:Y.taskDescription,success:Y.success,result_summary:Y.resultSummary,error:Y.error},X=this.getMatchingHooks("SubagentStop",{});if(X.length===0)return{shouldStop:!0};let Q={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:this.config,abortSignal:Y.abortSignal};try{return await this.executor.executeSubagentStopHooks(X,Z,Q)}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($,Y,Z,X){if(!this.isEnabled())return{decision:"ask"};let Q={hook_event_name:"PermissionRequest",hook_execution_id:x0(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Y,tool_input:Z,project_dir:X.projectDir,session_id:X.sessionId,permission_mode:X.permissionMode},J=this.getMatchingHooks("PermissionRequest",{toolName:$,filePath:this.extractFilePath(Z),command:this.extractCommand($,Z)});if(J.length===0)return{decision:"ask"};let q={projectDir:X.projectDir,sessionId:X.sessionId,permissionMode:X.permissionMode,config:this.config,abortSignal:X.abortSignal};try{return await this.executor.executePermissionRequestHooks(J,Q,q)}catch(G){return console.error("[HookManager] Error executing PermissionRequest hooks:",G),{decision:"ask",warning:`Hook execution failed: ${G instanceof Error?G.message:String(G)}`}}}async executeUserPromptSubmitHooks($,Y){if(!this.isEnabled())return{proceed:!0};let Z={hook_event_name:"UserPromptSubmit",hook_execution_id:x0(),timestamp:new Date().toISOString(),user_prompt:$,has_images:Y.hasImages,image_count:Y.imageCount,project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode},X=this.getMatchingHooks("UserPromptSubmit",{});if(X.length===0)return{proceed:!0};let Q={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:this.config,abortSignal:Y.abortSignal};try{return await this.executor.executeUserPromptSubmitHooks(X,Z,Q)}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 Y={hook_event_name:"SessionStart",hook_execution_id:x0(),timestamp:new Date().toISOString(),project_dir:$.projectDir,session_id:$.sessionId,permission_mode:$.permissionMode,is_resume:$.isResume,resume_session_id:$.resumeSessionId},Z=this.getMatchingHooks("SessionStart",{});if(Z.length===0)return{proceed:!0};let X={projectDir:$.projectDir,sessionId:$.sessionId,permissionMode:$.permissionMode,config:this.config,abortSignal:$.abortSignal};try{return await this.executor.executeSessionStartHooks(Z,Y,X)}catch(Q){return console.error("[HookManager] Error executing SessionStart hooks:",Q),{proceed:!0,warning:`Hook execution failed: ${Q instanceof Error?Q.message:String(Q)}`}}}async executeSessionEndHooks($,Y){if(!this.isEnabled())return{};let Z={hook_event_name:"SessionEnd",hook_execution_id:x0(),timestamp:new Date().toISOString(),project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode,reason:$},X=this.getMatchingHooks("SessionEnd",{});if(X.length===0)return{};let Q={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:this.config,abortSignal:Y.abortSignal};try{return await this.executor.executeSessionEndHooks(X,Z,Q),{}}catch(J){return console.error("[HookManager] Error executing SessionEnd hooks:",J),{warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executePostToolUseFailureHooks($,Y,Z,X,Q){if(!this.isEnabled())return{};let J={hook_event_name:"PostToolUseFailure",hook_execution_id:x0(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Y,tool_input:Z,error:X,error_type:Q.errorType,is_interrupt:Q.isInterrupt,is_timeout:Q.isTimeout,project_dir:Q.projectDir,session_id:Q.sessionId,permission_mode:Q.permissionMode},q=this.getMatchingHooks("PostToolUseFailure",{toolName:$,filePath:this.extractFilePath(Z),command:this.extractCommand($,Z)});if(q.length===0)return{};let G={projectDir:Q.projectDir,sessionId:Q.sessionId,permissionMode:Q.permissionMode,config:this.config,abortSignal:Q.abortSignal};try{return await this.executor.executePostToolUseFailureHooks(q,J,G)}catch(K){return console.error("[HookManager] Error executing PostToolUseFailure hooks:",K),{warning:`Hook execution failed: ${K instanceof Error?K.message:String(K)}`}}}async executeNotificationHooks($,Y,Z){if(!this.isEnabled())return{suppress:!1,message:Y};let X={hook_event_name:"Notification",hook_execution_id:x0(),timestamp:new Date().toISOString(),project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode,notification_type:$,title:Z.title,message:Y},Q=this.getMatchingHooks("Notification",{});if(Q.length===0)return{suppress:!1,message:Y};let J={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeNotificationHooks(Q,X,J)}catch(q){return console.error("[HookManager] Error executing Notification hooks:",q),{suppress:!1,message:Y,warning:`Hook execution failed: ${q instanceof Error?q.message:String(q)}`}}}async executeCompactionHooks($,Y){if(!this.isEnabled())return{blockCompaction:!1};let Z={hook_event_name:"Compaction",hook_execution_id:x0(),timestamp:new Date().toISOString(),project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode,trigger:$,messages_before:Y.messagesBefore,tokens_before:Y.tokensBefore},X=this.getMatchingHooks("Compaction",{});if(X.length===0)return{blockCompaction:!1};let Q={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:this.config,abortSignal:Y.abortSignal};try{return await this.executor.executeCompactionHooks(X,Z,Q)}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($,Y){let Z=this.config[$]||[],X=[];for(let Q of Z)if(this.matcher.matches(Q.matcher,Y))X.push(...Q.hooks);return X}extractFilePath($){let Y=["file_path","path","filePath","source","target"];for(let Z of Y){let X=$[Z];if(typeof X==="string")return X}return}extractCommand($,Y){if($==="Bash"||$==="BashTool"){let Z=Y.command;if(typeof Z==="string")return Z}return}cleanup(){this.guard.cleanupAll()}}var z0=b(()=>{R5();j5();y5();w$()});import{randomUUID as xG}from"node:crypto";import pG from"openai";function gG(){return xG().replace(/-/g,"")+"01"}function v5($){return $.toLowerCase().includes("gemini")}function Z4($){if(!$||typeof $!=="object")return $;if(Array.isArray($))return $.map(Z4);let Y={};for(let[Z,X]of Object.entries($)){if(Z==="$schema"||Z==="additionalProperties")continue;Y[Z]=Z4(X)}return Y}function E5($){let Y=new Map;for(let J=0;J<$.length;J++){let q=$[J];if(q.role==="assistant"&&q.tool_calls)for(let G of q.tool_calls)Y.set(G.id,J)}let Z=new Set;for(let J of $)if(J.role==="tool"&&J.tool_call_id)Z.add(J.tool_call_id);let X=[];for(let J of Y.keys())if(!Z.has(J))X.push(J);let Q=[];for(let J of $)if(J.role==="tool"){if(J.tool_call_id&&Y.has(J.tool_call_id))Q.push(J)}else if(Q.push(J),J.role==="assistant"&&J.tool_calls){for(let q of J.tool_calls)if(X.includes(q.id))Q.push({role:"tool",content:"[Result lost due to context compression]",tool_call_id:q.id})}if(X.length>0)W1.debug(`\uD83D\uDD27 [GptOpenaiPlatformChatService] Gemini 修复:补充 ${X.length} 个缺失的 tool results`);return Q}class $8{config;constructor($){if(W1.debug("\uD83D\uDE80 [GptOpenaiPlatformChatService] Initializing"),W1.debug("⚙️ [GptOpenaiPlatformChatService] Config:",{model:$.model,baseUrl:$.baseUrl,apiVersion:$.apiVersion,temperature:$.temperature,maxContextTokens:$.maxContextTokens,timeout:$.timeout,hasApiKey:!!$.apiKey}),!$.baseUrl)throw W1.error("❌ [GptOpenaiPlatformChatService] baseUrl is required"),Error("baseUrl is required in ChatConfig");if(!$.apiKey)throw W1.error("❌ [GptOpenaiPlatformChatService] apiKey is required"),Error("apiKey is required in ChatConfig");if(!$.model)throw W1.error("❌ [GptOpenaiPlatformChatService] model is required"),Error("model is required in ChatConfig");this.config=$,W1.debug("✅ [GptOpenaiPlatformChatService] Initialized successfully")}createClient(){let $=gG();W1.debug("\uD83D\uDD11 [GptOpenaiPlatformChatService] Generated logid:",$);let Y={},Z={"api-key":this.config.apiKey,"x-tt-logid":$};if(this.config.apiVersion)Y["api-version"]=this.config.apiVersion;return new pG({apiKey:this.config.apiKey,baseURL:this.config.baseUrl,timeout:this.config.timeout??180000,maxRetries:3,defaultQuery:Y,defaultHeaders:Z})}async chat($,Y,Z){let X=Date.now();W1.debug("\uD83D\uDE80 [GptOpenaiPlatformChatService] Starting chat request"),W1.debug("\uD83D\uDCDD [GptOpenaiPlatformChatService] Messages count:",$.length);let Q=this.createClient(),J=v5(this.config.model),G=(J?E5($):$).map((O)=>{if(O.role==="tool")return{role:"tool",content:typeof O.content==="string"?O.content:O.content.filter((F)=>F.type==="text").map((F)=>F.text).join(`
94
+ `):void 0}}async executeHook($,Y,Z){if($.type==="command")return this.executeCommandHook($,Y,Z);throw Error(`Hook type ${$.type} not yet implemented`)}async executeCommandHook($,Y,Z){let X=($.timeout??Z.config.defaultTimeout??60)*1000;try{let Q=await this.processExecutor.execute($.command,Y,Z,X);return this.outputParser.parse(Q,$,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch(Q){return{success:!1,blocking:!1,error:Q instanceof Error?Q.message:String(Q),hook:$}}}async executeHooksConcurrently($,Y,Z,X){let Q=[],J=new Set;for(let q of $){if(J.size>=X)await Promise.race(J);let K=this.executeHook(q,Y,Z).catch((U)=>({success:!1,blocking:!1,error:U instanceof Error?U.message:String(U),hook:q})),G=K.then(()=>{J.delete(G)}).catch(()=>{J.delete(G)});J.add(G),Q.push(K)}return Promise.all(Q)}}var f5=b(()=>{k5();C5();R$()});import Y9 from"picomatch";class Z9{matches($,Y){if(!$)return!0;if($.tools&&Y.toolName){if(!this.matchTools($.tools,Y))return!1}if($.paths&&Y.filePath){if(!this.matchPaths($.paths,Y.filePath))return!1}if($.commands&&Y.command){if(!this.matchCommands($.commands,Y.command))return!1}return!0}matchTools($,Y){if(Array.isArray($))return $.some((Z)=>this.matchToolWithParams(Z,Y));return this.matchToolWithParams($,Y)}matchPaths($,Y){if(Array.isArray($))return $.some((X)=>{return Y9(X)(Y)});return Y9($)(Y)}matchCommands($,Y){if(Array.isArray($))return $.some((Z)=>this.matchPattern(Y,Z));return this.matchPattern(Y,$)}matchToolWithParams($,Y){let{toolName:Z,command:X,filePath:Q}=Y,J=ZG.exec($);if(!J)return this.matchPattern(Z,$);let[,q,K]=J;if(!this.matchPattern(Z,q))return!1;let G=this.getArgValue(Z,X,Q);if(!G)return!1;return this.matchGlobOrPattern(G,K)}getArgValue($,Y,Z){if($==="Bash"||$==="BashTool")return Y;if(["Read","Edit","Write","Glob","Grep"].includes($))return Z;return Y||Z}matchGlobOrPattern($,Y){if(/[*?[\]{}!]/.test(Y))try{return Y9(Y,{bash:!0,dot:!0})($)}catch{}if(Y.endsWith("*")){let Z=Y.slice(0,-1);return $.startsWith(Z)}return $===Y}matchPattern($,Y){if(Y==="*")return!0;if(!Y.includes("|")&&!/[.*+?^${}()|[\]\\]/.test(Y))return $===Y;if(Y.includes("|"))return Y.split("|").map((X)=>X.trim()).includes($);try{return new RegExp(Y).test($)}catch{return $===Y}}}var ZG;var h5=b(()=>{ZG=/^([A-Za-z0-9_|]+)\((.+)\)$/});import{nanoid as g0}from"nanoid";class H1{static instance=null;config=l8;executor=new $9;guard=new r8;matcher=new Z9;sessionDisabled=!1;constructor(){}static getInstance(){if(!H1.instance)H1.instance=new H1;return H1.instance}loadConfig($){let Y=i8(l8,$),Z=v5();Y=i8(Y,Z),this.config=Y}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"),Y=await import("node:path");try{let Z=Y.join(process.cwd(),".blade","settings.local.json"),X=await $.readFile(Z,"utf-8"),Q=JSON.parse(X);if(Q.hooks)this.loadConfig(Q.hooks)}catch{}}async executePreToolHooks($,Y,Z,X){if(!this.isEnabled())return{decision:"allow"};if(X.permissionMode==="plan")return{decision:"allow"};if(!this.guard.canExecute(Y,"PreToolUse"))return{decision:"allow"};let Q={hook_event_name:"PreToolUse",hook_execution_id:g0(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Y,tool_input:Z,project_dir:X.projectDir,session_id:X.sessionId,permission_mode:X.permissionMode},J=this.getMatchingHooks("PreToolUse",{toolName:$,filePath:this.extractFilePath(Z),command:this.extractCommand($,Z)});if(J.length===0)return{decision:"allow"};let q={projectDir:X.projectDir,sessionId:X.sessionId,permissionMode:X.permissionMode,config:this.config,abortSignal:X.abortSignal};try{let K=await this.executor.executePreToolHooks(J,Q,q);if(this.guard.markExecuted(Y,"PreToolUse"),X.permissionMode==="yolo"){if(K.decision==="deny")return K;return{decision:"allow",modifiedInput:K.modifiedInput,warning:K.warning,reason:K.reason}}return K}catch(K){return console.error("[HookManager] Error executing PreToolUse hooks:",K),{decision:"allow",warning:`Hook execution failed: ${K instanceof Error?K.message:String(K)}`}}}async executePostToolHooks($,Y,Z,X,Q){if(!this.isEnabled())return{};if(Q.permissionMode==="plan")return{};if(!this.guard.canExecute(Y,"PostToolUse"))return{};let J={hook_event_name:"PostToolUse",hook_execution_id:g0(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Y,tool_input:Z,tool_response:X,project_dir:Q.projectDir,session_id:Q.sessionId,permission_mode:Q.permissionMode},q=this.getMatchingHooks("PostToolUse",{toolName:$,filePath:this.extractFilePath(Z),command:this.extractCommand($,Z)});if(q.length===0)return{};let K={projectDir:Q.projectDir,sessionId:Q.sessionId,permissionMode:Q.permissionMode,config:this.config,abortSignal:Q.abortSignal};try{let G=await this.executor.executePostToolHooks(q,J,K);return this.guard.markExecuted(Y,"PostToolUse"),G}catch(G){return console.error("[HookManager] Error executing PostToolUse hooks:",G),{warning:`Hook execution failed: ${G instanceof Error?G.message:String(G)}`}}finally{this.guard.cleanup(Y)}}async executeStopHooks($){if(!this.isEnabled())return{shouldStop:!0};let Y={hook_event_name:"Stop",hook_execution_id:g0(),timestamp:new Date().toISOString(),project_dir:$.projectDir,session_id:$.sessionId,permission_mode:$.permissionMode,reason:$.reason},Z=this.getMatchingHooks("Stop",{});if(Z.length===0)return{shouldStop:!0};let X={projectDir:$.projectDir,sessionId:$.sessionId,permissionMode:$.permissionMode,config:this.config,abortSignal:$.abortSignal};try{return await this.executor.executeStopHooks(Z,Y,X)}catch(Q){return console.error("[HookManager] Error executing Stop hooks:",Q),{shouldStop:!0,warning:`Hook execution failed: ${Q instanceof Error?Q.message:String(Q)}`}}}async executeSubagentStopHooks($,Y){if(!this.isEnabled())return{shouldStop:!0};let Z={hook_event_name:"SubagentStop",hook_execution_id:g0(),timestamp:new Date().toISOString(),project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode,agent_type:$,task_description:Y.taskDescription,success:Y.success,result_summary:Y.resultSummary,error:Y.error},X=this.getMatchingHooks("SubagentStop",{});if(X.length===0)return{shouldStop:!0};let Q={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:this.config,abortSignal:Y.abortSignal};try{return await this.executor.executeSubagentStopHooks(X,Z,Q)}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($,Y,Z,X){if(!this.isEnabled())return{decision:"ask"};let Q={hook_event_name:"PermissionRequest",hook_execution_id:g0(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Y,tool_input:Z,project_dir:X.projectDir,session_id:X.sessionId,permission_mode:X.permissionMode},J=this.getMatchingHooks("PermissionRequest",{toolName:$,filePath:this.extractFilePath(Z),command:this.extractCommand($,Z)});if(J.length===0)return{decision:"ask"};let q={projectDir:X.projectDir,sessionId:X.sessionId,permissionMode:X.permissionMode,config:this.config,abortSignal:X.abortSignal};try{return await this.executor.executePermissionRequestHooks(J,Q,q)}catch(K){return console.error("[HookManager] Error executing PermissionRequest hooks:",K),{decision:"ask",warning:`Hook execution failed: ${K instanceof Error?K.message:String(K)}`}}}async executeUserPromptSubmitHooks($,Y){if(!this.isEnabled())return{proceed:!0};let Z={hook_event_name:"UserPromptSubmit",hook_execution_id:g0(),timestamp:new Date().toISOString(),user_prompt:$,has_images:Y.hasImages,image_count:Y.imageCount,project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode},X=this.getMatchingHooks("UserPromptSubmit",{});if(X.length===0)return{proceed:!0};let Q={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:this.config,abortSignal:Y.abortSignal};try{return await this.executor.executeUserPromptSubmitHooks(X,Z,Q)}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 Y={hook_event_name:"SessionStart",hook_execution_id:g0(),timestamp:new Date().toISOString(),project_dir:$.projectDir,session_id:$.sessionId,permission_mode:$.permissionMode,is_resume:$.isResume,resume_session_id:$.resumeSessionId},Z=this.getMatchingHooks("SessionStart",{});if(Z.length===0)return{proceed:!0};let X={projectDir:$.projectDir,sessionId:$.sessionId,permissionMode:$.permissionMode,config:this.config,abortSignal:$.abortSignal};try{return await this.executor.executeSessionStartHooks(Z,Y,X)}catch(Q){return console.error("[HookManager] Error executing SessionStart hooks:",Q),{proceed:!0,warning:`Hook execution failed: ${Q instanceof Error?Q.message:String(Q)}`}}}async executeSessionEndHooks($,Y){if(!this.isEnabled())return{};let Z={hook_event_name:"SessionEnd",hook_execution_id:g0(),timestamp:new Date().toISOString(),project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode,reason:$},X=this.getMatchingHooks("SessionEnd",{});if(X.length===0)return{};let Q={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:this.config,abortSignal:Y.abortSignal};try{return await this.executor.executeSessionEndHooks(X,Z,Q),{}}catch(J){return console.error("[HookManager] Error executing SessionEnd hooks:",J),{warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executePostToolUseFailureHooks($,Y,Z,X,Q){if(!this.isEnabled())return{};let J={hook_event_name:"PostToolUseFailure",hook_execution_id:g0(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Y,tool_input:Z,error:X,error_type:Q.errorType,is_interrupt:Q.isInterrupt,is_timeout:Q.isTimeout,project_dir:Q.projectDir,session_id:Q.sessionId,permission_mode:Q.permissionMode},q=this.getMatchingHooks("PostToolUseFailure",{toolName:$,filePath:this.extractFilePath(Z),command:this.extractCommand($,Z)});if(q.length===0)return{};let K={projectDir:Q.projectDir,sessionId:Q.sessionId,permissionMode:Q.permissionMode,config:this.config,abortSignal:Q.abortSignal};try{return await this.executor.executePostToolUseFailureHooks(q,J,K)}catch(G){return console.error("[HookManager] Error executing PostToolUseFailure hooks:",G),{warning:`Hook execution failed: ${G instanceof Error?G.message:String(G)}`}}}async executeNotificationHooks($,Y,Z){if(!this.isEnabled())return{suppress:!1,message:Y};let X={hook_event_name:"Notification",hook_execution_id:g0(),timestamp:new Date().toISOString(),project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode,notification_type:$,title:Z.title,message:Y},Q=this.getMatchingHooks("Notification",{});if(Q.length===0)return{suppress:!1,message:Y};let J={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeNotificationHooks(Q,X,J)}catch(q){return console.error("[HookManager] Error executing Notification hooks:",q),{suppress:!1,message:Y,warning:`Hook execution failed: ${q instanceof Error?q.message:String(q)}`}}}async executeCompactionHooks($,Y){if(!this.isEnabled())return{blockCompaction:!1};let Z={hook_event_name:"Compaction",hook_execution_id:g0(),timestamp:new Date().toISOString(),project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode,trigger:$,messages_before:Y.messagesBefore,tokens_before:Y.tokensBefore},X=this.getMatchingHooks("Compaction",{});if(X.length===0)return{blockCompaction:!1};let Q={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:this.config,abortSignal:Y.abortSignal};try{return await this.executor.executeCompactionHooks(X,Z,Q)}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($,Y){let Z=this.config[$]||[],X=[];for(let Q of Z)if(this.matcher.matches(Q.matcher,Y))X.push(...Q.hooks);return X}extractFilePath($){let Y=["file_path","path","filePath","source","target"];for(let Z of Y){let X=$[Z];if(typeof X==="string")return X}return}extractCommand($,Y){if($==="Bash"||$==="BashTool"){let Z=Y.command;if(typeof Z==="string")return Z}return}cleanup(){this.guard.cleanupAll()}}var L0=b(()=>{P5();f5();h5();R$()});import x5 from"@anthropic-ai/sdk";function XG($){if($.startsWith("data:")){let Y=$.match(/^data:([^;,]+)/);if(Y){let Z=Y[1];if(Z==="image/jpeg"||Z==="image/png"||Z==="image/gif"||Z==="image/webp")return Z}}return"image/png"}function QG($){if($.startsWith("data:")){let Y=$.indexOf(",");if(Y!==-1)return $.slice(Y+1)}return $}function p5($){let Y=new Set;for(let Z of $)if(Z.role==="assistant"&&Z.tool_calls)for(let X of Z.tool_calls)Y.add(X.id);return $.filter((Z)=>{if(Z.role==="tool"){if(!Z.tool_call_id)return!1;return Y.has(Z.tool_call_id)}return!0})}function X9($){if(typeof $==="string")return $;return $.filter((Y)=>Y.type==="text").map((Y)=>Y.text).join(`
95
+ `)}class Q9{client;config;constructor($){if(this.config=$,z1.debug("\uD83D\uDE80 [AnthropicChatService] Initializing"),z1.debug("⚙️ [AnthropicChatService] Config:",{model:$.model,baseUrl:$.baseUrl,temperature:$.temperature,maxContextTokens:$.maxContextTokens,timeout:$.timeout,hasApiKey:!!$.apiKey}),!$.apiKey)throw z1.error("❌ [AnthropicChatService] apiKey is required"),Error("apiKey is required in ChatConfig");if(!$.model)throw z1.error("❌ [AnthropicChatService] model is required"),Error("model is required in ChatConfig");this.client=new x5({apiKey:$.apiKey,baseURL:$.baseUrl||void 0,timeout:$.timeout??180000,maxRetries:3}),z1.debug("✅ [AnthropicChatService] Initialized successfully")}convertToAnthropicMessages($){let Y=$.find((q)=>q.role==="system"),Z=Y?X9(Y.content):void 0,X=[],Q=$.filter((q)=>q.role!=="system");for(let q=0;q<Q.length;q++){let K=Q[q];if(K.role==="assistant"){let G=[],U=X9(K.content);if(U)G.push({type:"text",text:U});if(K.tool_calls)for(let O of K.tool_calls){if(O.type!=="function")continue;let W={};try{W=JSON.parse(O.function.arguments||"{}")}catch{z1.warn(`⚠️ [AnthropicChatService] Failed to parse tool arguments: ${O.function.arguments}`)}G.push({type:"tool_use",id:O.id,name:O.function.name,input:W})}if(G.length>0)X.push({role:"assistant",content:G})}else if(K.role==="tool"){let G={type:"tool_result",tool_use_id:K.tool_call_id,content:X9(K.content)},U=X[X.length-1];if(U?.role==="user"&&Array.isArray(U.content))U.content.push(G);else X.push({role:"user",content:[G]})}else if(K.role==="user")if(Array.isArray(K.content)){let G=[];for(let U of K.content)if(U.type==="text")G.push({type:"text",text:U.text});else if(U.type==="image_url"){let O=U.image_url.url;G.push({type:"image",source:{type:"base64",media_type:XG(O),data:QG(O)}})}X.push({role:"user",content:G})}else X.push({role:"user",content:K.content})}if(X.length>0&&X[0].role!=="user")X.unshift({role:"user",content:"[System initialized]"});let J=[];for(let q of X){let K=J[J.length-1];if(K?.role===q.role){if(typeof K.content==="string"&&typeof q.content==="string")K.content=`${K.content}
96
+
97
+ ${q.content}`;else if(Array.isArray(K.content)&&Array.isArray(q.content))K.content=[...K.content,...q.content];else if(typeof K.content==="string"&&Array.isArray(q.content))K.content=[{type:"text",text:K.content},...q.content];else if(Array.isArray(K.content)&&typeof q.content==="string")K.content.push({type:"text",text:q.content})}else J.push(q)}return{system:Z,messages:J}}convertToAnthropicTools($){if(!$||$.length===0)return;return $.map((Y)=>({name:Y.name,description:Y.description,input_schema:Y.parameters}))}parseAnthropicResponse($,Y){let Z="",X=[];for(let Q of $)if(Q.type==="text")Z+=Q.text;else if(Q.type==="tool_use")X.push({id:Q.id,type:"function",function:{name:Q.name,arguments:JSON.stringify(Q.input)}});return{content:Z,toolCalls:X.length>0?X:void 0,usage:{promptTokens:Y.input_tokens,completionTokens:Y.output_tokens,totalTokens:Y.input_tokens+Y.output_tokens}}}async chat($,Y,Z){let X=Date.now();z1.debug("\uD83D\uDE80 [AnthropicChatService] Starting chat request"),z1.debug("\uD83D\uDCDD [AnthropicChatService] Messages count:",$.length);let Q=p5($);if(Q.length<$.length)z1.debug(`\uD83D\uDD27 [AnthropicChatService] 过滤掉 ${$.length-Q.length} 条孤儿 tool 消息`);let{system:J,messages:q}=this.convertToAnthropicMessages(Q),K=this.convertToAnthropicTools(Y);z1.debug("\uD83D\uDD27 [AnthropicChatService] Tools count:",K?.length||0),z1.debug("\uD83D\uDCE4 [AnthropicChatService] Request params:",{model:this.config.model,messagesCount:q.length,hasSystem:!!J,toolsCount:K?.length||0,max_tokens:this.config.maxOutputTokens??4096,temperature:this.config.temperature??0});try{let G=await this.client.messages.create({model:this.config.model,max_tokens:this.config.maxOutputTokens??4096,system:J,messages:q,tools:K,temperature:this.config.temperature??0},{signal:Z}),U=Date.now()-X;z1.debug("\uD83D\uDCE5 [AnthropicChatService] Response received in",U,"ms"),z1.debug("\uD83D\uDCCA [AnthropicChatService] Response:",{stopReason:G.stop_reason,contentBlocksCount:G.content.length,usage:G.usage});let O=this.parseAnthropicResponse(G.content,G.usage);return z1.debug("✅ [AnthropicChatService] Chat completed successfully"),z1.debug("\uD83D\uDCCA [AnthropicChatService] Final response:",{contentLength:O.content.length,toolCallsCount:O.toolCalls?.length||0,usage:O.usage}),O}catch(G){let U=Date.now()-X;throw z1.error("❌ [AnthropicChatService] Chat request failed after",U,"ms"),z1.error("❌ [AnthropicChatService] Error details:",G),G}}async*streamChat($,Y,Z){let X=Date.now();z1.debug("\uD83D\uDE80 [AnthropicChatService] Starting stream request"),z1.debug("\uD83D\uDCDD [AnthropicChatService] Messages count:",$.length);let Q=p5($);if(Q.length<$.length)z1.debug(`\uD83D\uDD27 [AnthropicChatService] 过滤掉 ${$.length-Q.length} 条孤儿 tool 消息`);let{system:J,messages:q}=this.convertToAnthropicMessages(Q),K=this.convertToAnthropicTools(Y);z1.debug("\uD83D\uDD27 [AnthropicChatService] Stream tools count:",K?.length||0),z1.debug("\uD83D\uDCE4 [AnthropicChatService] Stream request params:",{model:this.config.model,messagesCount:q.length,hasSystem:!!J,toolsCount:K?.length||0,max_tokens:this.config.maxOutputTokens??4096,temperature:this.config.temperature??0});try{let G=await this.client.messages.create({model:this.config.model,max_tokens:this.config.maxOutputTokens??4096,system:J,messages:q,tools:K,temperature:this.config.temperature??0,stream:!0},{signal:Z}),U=Date.now()-X;z1.debug("\uD83D\uDCE5 [AnthropicChatService] Stream started in",U,"ms");let O=new Map,W=0,F="",H=!1;for await(let z of G)if(W++,z.type==="content_block_start"){if(z.content_block.type==="tool_use")O.set(z.index,{id:z.content_block.id,name:z.content_block.name,arguments:""}),H=!0,z1.debug(`\uD83D\uDD27 [AnthropicChatService] Tool use started: ${z.content_block.name}`)}else if(z.type==="content_block_delta"){if(z.delta.type==="text_delta")F+=z.delta.text,yield{content:z.delta.text};else if(z.delta.type==="input_json_delta"){let N=O.get(z.index);if(N)N.arguments+=z.delta.partial_json}}else if(z.type==="content_block_stop"){let N=O.get(z.index);if(N&&N.id)z1.debug(`\uD83D\uDD27 [AnthropicChatService] Tool use completed: ${N.name}`),yield{toolCalls:[{id:N.id,type:"function",function:{name:N.name,arguments:N.arguments}}]}}else if(z.type==="message_delta"){let N=z.delta.stop_reason;if(N){z1.debug("\uD83C\uDFC1 [AnthropicChatService] Stream finished:",N),z1.debug("\uD83D\uDCCA [AnthropicChatService] Stream summary:",{totalEvents:W,totalContentLength:F.length,hadToolCalls:H,duration:Date.now()-X+"ms"});let L;if(N==="end_turn")L="stop";else if(N==="tool_use")L="tool_calls";else if(N==="max_tokens")L="length";else L=N;yield{finishReason:L}}}z1.debug("✅ [AnthropicChatService] Stream completed successfully")}catch(G){let U=Date.now()-X;throw z1.error("❌ [AnthropicChatService] Stream request failed after",U,"ms"),z1.error("❌ [AnthropicChatService] Stream error details:",G),G}}getConfig(){return{...this.config}}updateConfig($){z1.debug("\uD83D\uDD04 [AnthropicChatService] Updating configuration"),this.config={...this.config,...$},this.client=new x5({apiKey:this.config.apiKey,baseURL:this.config.baseUrl||void 0,timeout:this.config.timeout??180000,maxRetries:3}),z1.debug("✅ [AnthropicChatService] Configuration updated successfully")}}var z1;var u5=b(()=>{w1();z1=c("Chat")});import{AzureOpenAI as g5}from"openai";function d5($){let Y=new Set;for(let Z of $)if(Z.role==="assistant"&&Z.tool_calls)for(let X of Z.tool_calls)Y.add(X.id);return $.filter((Z)=>{if(Z.role==="tool"){if(!Z.tool_call_id)return!1;return Y.has(Z.tool_call_id)}return!0})}class J9{client;config;constructor($){if(this.config=$,N1.debug("\uD83D\uDE80 [AzureOpenAIChatService] Initializing"),N1.debug("⚙️ [AzureOpenAIChatService] Config:",{model:$.model,baseUrl:$.baseUrl,temperature:$.temperature,maxContextTokens:$.maxContextTokens,timeout:$.timeout,apiVersion:$.apiVersion,hasApiKey:!!$.apiKey}),!$.apiKey)throw N1.error("❌ [AzureOpenAIChatService] apiKey is required"),Error("apiKey is required in ChatConfig");if(!$.baseUrl)throw N1.error("❌ [AzureOpenAIChatService] baseUrl is required"),Error("baseUrl is required in ChatConfig");if(!$.model)throw N1.error("❌ [AzureOpenAIChatService] model (deployment) is required"),Error("model (deployment) is required in ChatConfig");this.client=new g5({apiKey:$.apiKey,endpoint:$.baseUrl,apiVersion:$.apiVersion||"2024-08-01-preview",timeout:$.timeout??180000,maxRetries:3}),N1.debug("✅ [AzureOpenAIChatService] Initialized successfully")}convertToOpenAIMessages($){return $.map((Y)=>{if(Y.role==="tool")return{role:"tool",content:typeof Y.content==="string"?Y.content:Y.content.filter((X)=>X.type==="text").map((X)=>X.text).join(`
98
+ `),tool_call_id:Y.tool_call_id};if(Y.role==="assistant"&&Y.tool_calls)return{role:"assistant",content:(typeof Y.content==="string"?Y.content:Y.content.filter((X)=>X.type==="text").map((X)=>X.text).join(`
99
+ `))||null,tool_calls:Y.tool_calls};if(Y.role==="user"&&Array.isArray(Y.content))return{role:"user",content:Y.content.map((Z)=>{if(Z.type==="text")return{type:"text",text:Z.text};return{type:"image_url",image_url:{url:Z.image_url.url}}})};return{role:Y.role,content:typeof Y.content==="string"?Y.content:Y.content.filter((Z)=>Z.type==="text").map((Z)=>Z.text).join(`
100
+ `)}})}convertToOpenAITools($){return $?.map((Y)=>({type:"function",function:{name:Y.name,description:Y.description,parameters:Y.parameters}}))}async chat($,Y,Z){let X=Date.now();N1.debug("\uD83D\uDE80 [AzureOpenAIChatService] Starting chat request"),N1.debug("\uD83D\uDCDD [AzureOpenAIChatService] Messages count:",$.length);let Q=d5($);if(Q.length<$.length)N1.debug(`\uD83D\uDD27 [AzureOpenAIChatService] 过滤掉 ${$.length-Q.length} 条孤儿 tool 消息`);let J=this.convertToOpenAIMessages(Q),q=this.convertToOpenAITools(Y);N1.debug("\uD83D\uDD27 [AzureOpenAIChatService] Tools count:",q?.length||0);let K={model:this.config.model,messages:J,tools:q,tool_choice:q&&q.length>0?"auto":void 0,max_tokens:this.config.maxOutputTokens??32768,temperature:this.config.temperature??0};N1.debug("\uD83D\uDCE4 [AzureOpenAIChatService] Request params:",{model:K.model,messagesCount:K.messages.length,toolsCount:K.tools?.length||0,max_tokens:K.max_tokens,temperature:K.temperature});try{let G=await this.client.chat.completions.create(K,{signal:Z}),U=Date.now()-X;if(N1.debug("\uD83D\uDCE5 [AzureOpenAIChatService] Response received in",U,"ms"),!G||!G.choices||G.choices.length===0)throw Error("Invalid API response: missing choices");let O=G.choices[0];if(!O)throw Error("No completion choice returned");let W=O.message.tool_calls?.filter((H)=>H.type==="function"),F={content:O.message.content||"",toolCalls:W,usage:{promptTokens:G.usage?.prompt_tokens||0,completionTokens:G.usage?.completion_tokens||0,totalTokens:G.usage?.total_tokens||0}};return N1.debug("✅ [AzureOpenAIChatService] Chat completed successfully"),N1.debug("\uD83D\uDCCA [AzureOpenAIChatService] Final response:",{contentLength:F.content.length,toolCallsCount:F.toolCalls?.length||0,usage:F.usage}),F}catch(G){let U=Date.now()-X;throw N1.error("❌ [AzureOpenAIChatService] Chat request failed after",U,"ms"),N1.error("❌ [AzureOpenAIChatService] Error details:",G),G}}async*streamChat($,Y,Z){let X=Date.now();N1.debug("\uD83D\uDE80 [AzureOpenAIChatService] Starting stream request"),N1.debug("\uD83D\uDCDD [AzureOpenAIChatService] Messages count:",$.length);let Q=d5($);if(Q.length<$.length)N1.debug(`\uD83D\uDD27 [AzureOpenAIChatService] 过滤掉 ${$.length-Q.length} 条孤儿 tool 消息`);let J=this.convertToOpenAIMessages(Q),q=this.convertToOpenAITools(Y);N1.debug("\uD83D\uDD27 [AzureOpenAIChatService] Stream tools count:",q?.length||0);let K={model:this.config.model,messages:J,tools:q,tool_choice:q&&q.length>0?"auto":void 0,max_tokens:this.config.maxOutputTokens??32768,temperature:this.config.temperature??0,stream:!0};N1.debug("\uD83D\uDCE4 [AzureOpenAIChatService] Stream request params:",{model:K.model,messagesCount:K.messages.length,toolsCount:K.tools?.length||0,max_tokens:K.max_tokens,temperature:K.temperature});try{let G=await this.client.chat.completions.create(K,{signal:Z}),U=Date.now()-X;N1.debug("\uD83D\uDCE5 [AzureOpenAIChatService] Stream started in",U,"ms");let O=0,W="",F=!1;for await(let H of G){if(O++,!H||!H.choices||!Array.isArray(H.choices)){N1.warn("⚠️ [AzureOpenAIChatService] Invalid chunk format in stream",O);continue}let z=H.choices[0]?.delta;if(!z){N1.warn("⚠️ [AzureOpenAIChatService] Empty delta in chunk",O);continue}if(z.content)W+=z.content;if(z.tool_calls&&!F)F=!0,N1.debug("\uD83D\uDD27 [AzureOpenAIChatService] Tool calls detected in stream");let N=H.choices[0]?.finish_reason;if(N)N1.debug("\uD83C\uDFC1 [AzureOpenAIChatService] Stream finished with reason:",N),N1.debug("\uD83D\uDCCA [AzureOpenAIChatService] Stream summary:",{totalChunks:O,totalContentLength:W.length,hadToolCalls:F,duration:Date.now()-X+"ms"});yield{content:z.content||void 0,toolCalls:z.tool_calls,finishReason:N||void 0}}N1.debug("✅ [AzureOpenAIChatService] Stream completed successfully")}catch(G){let U=Date.now()-X;throw N1.error("❌ [AzureOpenAIChatService] Stream request failed after",U,"ms"),N1.error("❌ [AzureOpenAIChatService] Stream error details:",G),G}}getConfig(){return{...this.config}}updateConfig($){N1.debug("\uD83D\uDD04 [AzureOpenAIChatService] Updating configuration"),this.config={...this.config,...$},this.client=new g5({apiKey:this.config.apiKey,endpoint:this.config.baseUrl,apiVersion:this.config.apiVersion||"2024-08-01-preview",timeout:this.config.timeout??180000,maxRetries:3}),N1.debug("✅ [AzureOpenAIChatService] Configuration updated successfully")}}var N1;var m5=b(()=>{w1();N1=c("Chat")});import{GoogleGenAI as c5}from"@google/genai";function l5($){let Y=new Set;for(let Z of $)if(Z.role==="assistant"&&Z.tool_calls)for(let X of Z.tool_calls)Y.add(X.id);return $.filter((Z)=>{if(Z.role==="tool"){if(!Z.tool_call_id)return!1;return Y.has(Z.tool_call_id)}return!0})}function q9($){if(typeof $==="string")return $;return $.filter((Y)=>Y.type==="text").map((Y)=>Y.text).join(`
101
+ `)}function K9($){let Y={};for(let[Z,X]of Object.entries($)){if(Z==="$schema"||Z==="additionalProperties")continue;if(X&&typeof X==="object"&&!Array.isArray(X))Y[Z]=K9(X);else if(Array.isArray(X))Y[Z]=X.map((Q)=>Q&&typeof Q==="object"&&!Array.isArray(Q)?K9(Q):Q);else Y[Z]=X}return Y}class G9{client;config;constructor($){if(this.config=$,_1.debug("\uD83D\uDE80 [GeminiChatService] Initializing"),_1.debug("⚙️ [GeminiChatService] Config:",{model:$.model,baseUrl:$.baseUrl,temperature:$.temperature,maxContextTokens:$.maxContextTokens,timeout:$.timeout,hasApiKey:!!$.apiKey}),!$.apiKey)throw _1.error("❌ [GeminiChatService] apiKey is required"),Error("apiKey is required in ChatConfig");if(!$.model)throw _1.error("❌ [GeminiChatService] model is required"),Error("model is required in ChatConfig");this.client=new c5({apiKey:$.apiKey}),_1.debug("✅ [GeminiChatService] Initialized successfully")}convertToGeminiMessages($){let Y=$.find((K)=>K.role==="system"),Z=Y?q9(Y.content):void 0,X=[],Q=$.filter((K)=>K.role!=="system"),J=new Map;for(let K of Q)if(K.role==="assistant"&&K.tool_calls){for(let G of K.tool_calls)if(G.type==="function")J.set(G.id,G.function.name)}for(let K of Q)if(K.role==="user"){let G=[];if(Array.isArray(K.content)){for(let U of K.content)if(U.type==="text")G.push({text:U.text});else if(U.type==="image_url"){let O=U.image_url.url;if(O.startsWith("data:")){let W=O.match(/^data:([^;,]+);base64,(.+)$/);if(W)G.push({inlineData:{mimeType:W[1],data:W[2]}})}else G.push({text:`[Image: ${O}]`})}}else G.push({text:K.content});X.push({role:"user",parts:G})}else if(K.role==="assistant"){let G=[],U=q9(K.content);if(U)G.push({text:U});if(K.tool_calls)for(let O of K.tool_calls){if(O.type!=="function")continue;let W={};try{W=JSON.parse(O.function.arguments||"{}")}catch{_1.warn(`⚠️ [GeminiChatService] Failed to parse tool arguments: ${O.function.arguments}`)}G.push({functionCall:{name:O.function.name,args:W}})}if(G.length>0)X.push({role:"model",parts:G})}else if(K.role==="tool"){let G=J.get(K.tool_call_id||"");if(G)X.push({role:"user",parts:[{functionResponse:{name:G,response:{result:q9(K.content)}}}]})}let q=[];for(let K of X){let G=q[q.length-1];if(G?.role===K.role){let U=G.parts||[],O=K.parts||[];G.parts=[...U,...O]}else q.push(K)}if(q.length>0&&q[0].role!=="user")q.unshift({role:"user",parts:[{text:"[Conversation start]"}]});return{systemInstruction:Z,contents:q}}convertToGeminiTools($){if(!$||$.length===0)return;return[{functionDeclarations:$.map((Z)=>({name:Z.name,description:Z.description,parameters:K9(Z.parameters||{type:"object",properties:{}})}))}]}async chat($,Y,Z){let X=Date.now();_1.debug("\uD83D\uDE80 [GeminiChatService] Starting chat request"),_1.debug("\uD83D\uDCDD [GeminiChatService] Messages count:",$.length);let Q=l5($);if(Q.length<$.length)_1.debug(`\uD83D\uDD27 [GeminiChatService] 过滤掉 ${$.length-Q.length} 条孤儿 tool 消息`);let{systemInstruction:J,contents:q}=this.convertToGeminiMessages(Q),K=this.convertToGeminiTools(Y);_1.debug("\uD83D\uDD27 [GeminiChatService] Tools count:",K?.[0]?.functionDeclarations?.length||0),_1.debug("\uD83D\uDCE4 [GeminiChatService] Request params:",{model:this.config.model,contentsCount:q.length,hasSystemInstruction:!!J,toolsCount:K?.[0]?.functionDeclarations?.length||0,maxOutputTokens:this.config.maxOutputTokens??4096,temperature:this.config.temperature??0});try{let G=await this.client.models.generateContent({model:this.config.model,contents:q,config:{systemInstruction:J||void 0,maxOutputTokens:this.config.maxOutputTokens??4096,temperature:this.config.temperature??0,tools:K}}),U=Date.now()-X;_1.debug("\uD83D\uDCE5 [GeminiChatService] Response received in",U,"ms");let O="",W=[],H=G.candidates?.[0]?.content?.parts||[];for(let L of H)if("text"in L&&L.text)O+=L.text;else if("functionCall"in L&&L.functionCall){let B=L.functionCall;W.push({id:`call_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,type:"function",function:{name:B.name||"",arguments:JSON.stringify(B.args||{})}})}let z=G.usageMetadata,N={content:O,toolCalls:W.length>0?W:void 0,usage:{promptTokens:z?.promptTokenCount||0,completionTokens:z?.candidatesTokenCount||0,totalTokens:z?.totalTokenCount||0}};return _1.debug("✅ [GeminiChatService] Chat completed successfully"),_1.debug("\uD83D\uDCCA [GeminiChatService] Final response:",{contentLength:N.content.length,toolCallsCount:N.toolCalls?.length||0,usage:N.usage}),N}catch(G){let U=Date.now()-X;throw _1.error("❌ [GeminiChatService] Chat request failed after",U,"ms"),_1.error("❌ [GeminiChatService] Error details:",G),G}}async*streamChat($,Y,Z){let X=Date.now();_1.debug("\uD83D\uDE80 [GeminiChatService] Starting stream request"),_1.debug("\uD83D\uDCDD [GeminiChatService] Messages count:",$.length);let Q=l5($);if(Q.length<$.length)_1.debug(`\uD83D\uDD27 [GeminiChatService] 过滤掉 ${$.length-Q.length} 条孤儿 tool 消息`);let{systemInstruction:J,contents:q}=this.convertToGeminiMessages(Q),K=this.convertToGeminiTools(Y);_1.debug("\uD83D\uDD27 [GeminiChatService] Stream tools count:",K?.[0]?.functionDeclarations?.length||0),_1.debug("\uD83D\uDCE4 [GeminiChatService] Stream request params:",{model:this.config.model,contentsCount:q.length,hasSystemInstruction:!!J,toolsCount:K?.[0]?.functionDeclarations?.length||0,maxOutputTokens:this.config.maxOutputTokens??4096,temperature:this.config.temperature??0});try{let G=await this.client.models.generateContentStream({model:this.config.model,contents:q,config:{systemInstruction:J||void 0,maxOutputTokens:this.config.maxOutputTokens??4096,temperature:this.config.temperature??0,tools:K}}),U=Date.now()-X;_1.debug("\uD83D\uDCE5 [GeminiChatService] Stream started in",U,"ms");let O=0,W="",F=!1;for await(let H of G){O++;let z=H.candidates?.[0],N=z?.content?.parts||[];for(let B of N)if("text"in B&&B.text)W+=B.text,yield{content:B.text};else if("functionCall"in B&&B.functionCall){F=!0;let _=B.functionCall;yield{toolCalls:[{id:`call_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,type:"function",function:{name:_.name||"",arguments:JSON.stringify(_.args||{})}}]}}let L=z?.finishReason;if(L){_1.debug("\uD83C\uDFC1 [GeminiChatService] Stream finished:",L),_1.debug("\uD83D\uDCCA [GeminiChatService] Stream summary:",{totalEvents:O,totalContentLength:W.length,hadToolCalls:F,duration:Date.now()-X+"ms"});let B;if(L==="STOP")B="stop";else if(L==="MAX_TOKENS")B="length";else B=L.toLowerCase();yield{finishReason:B}}}_1.debug("✅ [GeminiChatService] Stream completed successfully")}catch(G){let U=Date.now()-X;throw _1.error("❌ [GeminiChatService] Stream request failed after",U,"ms"),_1.error("❌ [GeminiChatService] Stream error details:",G),G}}getConfig(){return{...this.config}}updateConfig($){_1.debug("\uD83D\uDD04 [GeminiChatService] Updating configuration"),this.config={...this.config,...$},this.client=new c5({apiKey:this.config.apiKey}),_1.debug("✅ [GeminiChatService] Configuration updated successfully")}}var _1;var i5=b(()=>{w1();_1=c("Chat")});import{randomUUID as JG}from"node:crypto";import qG from"openai";function KG(){return JG().replace(/-/g,"")+"01"}function r5($){return $.toLowerCase().includes("gemini")}function J4($){if(!$||typeof $!=="object")return $;if(Array.isArray($))return $.map(J4);let Y={};for(let[Z,X]of Object.entries($)){if(Z==="$schema"||Z==="additionalProperties")continue;Y[Z]=J4(X)}return Y}function a5($){let Y=new Map;for(let J=0;J<$.length;J++){let q=$[J];if(q.role==="assistant"&&q.tool_calls)for(let K of q.tool_calls)Y.set(K.id,J)}let Z=new Set;for(let J of $)if(J.role==="tool"&&J.tool_call_id)Z.add(J.tool_call_id);let X=[];for(let J of Y.keys())if(!Z.has(J))X.push(J);let Q=[];for(let J of $)if(J.role==="tool"){if(J.tool_call_id&&Y.has(J.tool_call_id))Q.push(J)}else if(Q.push(J),J.role==="assistant"&&J.tool_calls){for(let q of J.tool_calls)if(X.includes(q.id))Q.push({role:"tool",content:"[Result lost due to context compression]",tool_call_id:q.id})}if(X.length>0)W1.debug(`\uD83D\uDD27 [GptOpenaiPlatformChatService] Gemini 修复:补充 ${X.length} 个缺失的 tool results`);return Q}class U9{config;constructor($){if(W1.debug("\uD83D\uDE80 [GptOpenaiPlatformChatService] Initializing"),W1.debug("⚙️ [GptOpenaiPlatformChatService] Config:",{model:$.model,baseUrl:$.baseUrl,apiVersion:$.apiVersion,temperature:$.temperature,maxContextTokens:$.maxContextTokens,timeout:$.timeout,hasApiKey:!!$.apiKey}),!$.baseUrl)throw W1.error("❌ [GptOpenaiPlatformChatService] baseUrl is required"),Error("baseUrl is required in ChatConfig");if(!$.apiKey)throw W1.error("❌ [GptOpenaiPlatformChatService] apiKey is required"),Error("apiKey is required in ChatConfig");if(!$.model)throw W1.error("❌ [GptOpenaiPlatformChatService] model is required"),Error("model is required in ChatConfig");this.config=$,W1.debug("✅ [GptOpenaiPlatformChatService] Initialized successfully")}createClient(){let $=KG();W1.debug("\uD83D\uDD11 [GptOpenaiPlatformChatService] Generated logid:",$);let Y={},Z={"api-key":this.config.apiKey,"x-tt-logid":$};if(this.config.apiVersion)Y["api-version"]=this.config.apiVersion;return new qG({apiKey:this.config.apiKey,baseURL:this.config.baseUrl,timeout:this.config.timeout??180000,maxRetries:3,defaultQuery:Y,defaultHeaders:Z})}async chat($,Y,Z){let X=Date.now();W1.debug("\uD83D\uDE80 [GptOpenaiPlatformChatService] Starting chat request"),W1.debug("\uD83D\uDCDD [GptOpenaiPlatformChatService] Messages count:",$.length);let Q=this.createClient(),J=r5(this.config.model),K=(J?a5($):$).map((O)=>{if(O.role==="tool")return{role:"tool",content:typeof O.content==="string"?O.content:O.content.filter((F)=>F.type==="text").map((F)=>F.text).join(`
95
102
  `),tool_call_id:O.tool_call_id};if(O.role==="assistant"&&O.tool_calls)return{role:"assistant",content:(typeof O.content==="string"?O.content:O.content?.filter((F)=>F.type==="text").map((F)=>F.text).join(`
96
- `))||null,tool_calls:O.tool_calls};if(O.role==="user"&&Array.isArray(O.content))return{role:"user",content:O.content.map((U)=>{if(U.type==="text")return{type:"text",text:U.text};return{type:"image_url",image_url:{url:U.image_url.url}}})};return{role:O.role,content:typeof O.content==="string"?O.content:O.content.filter((U)=>U.type==="text").map((U)=>U.text).join(`
97
- `)}}),K=Y?.map((O)=>({type:"function",function:{name:O.name,description:O.description,parameters:J?Z4(O.parameters):O.parameters}}));W1.debug("\uD83D\uDD27 [GptOpenaiPlatformChatService] Tools count:",K?.length||0);let W={model:this.config.model,messages:G,tools:K,tool_choice:K&&K.length>0?"auto":void 0,max_tokens:this.config.maxOutputTokens??32768,temperature:this.config.temperature??0};W1.debug("\uD83D\uDCE4 [GptOpenaiPlatformChatService] Request params:",{model:W.model,messagesCount:W.messages.length,toolsCount:W.tools?.length||0,tool_choice:W.tool_choice,max_tokens:W.max_tokens,temperature:W.temperature});try{let O=await Q.chat.completions.create(W,{signal:Z}),U=Date.now()-X;if(W1.debug("\uD83D\uDCE5 [GptOpenaiPlatformChatService] Response received in",U,"ms"),!O)throw W1.error("❌ [GptOpenaiPlatformChatService] API returned null/undefined response"),Error("API returned null/undefined response");if(!O.choices||!Array.isArray(O.choices))throw W1.error("❌ [GptOpenaiPlatformChatService] Invalid API response format - missing choices array"),Error(`Invalid API response: missing choices array. Response: ${JSON.stringify(O)}`);if(O.choices.length===0)throw W1.error("❌ [GptOpenaiPlatformChatService] API returned empty choices array"),Error("API returned empty choices array");let F=O.choices[0];if(!F)throw W1.error("❌ [GptOpenaiPlatformChatService] No completion choice returned"),Error("No completion choice returned");W1.debug("\uD83D\uDCDD [GptOpenaiPlatformChatService] Response choice:",{finishReason:F.finish_reason,contentLength:F.message.content?.length||0,hasToolCalls:!!F.message.tool_calls,toolCallsCount:F.message.tool_calls?.length||0});let H=F.message.tool_calls?.filter((N)=>N.type==="function"),z=F.message.reasoning_content||void 0,L=O.usage,B={content:F.message.content||"",reasoningContent:z,toolCalls:H,usage:{promptTokens:O.usage?.prompt_tokens||0,completionTokens:O.usage?.completion_tokens||0,totalTokens:O.usage?.total_tokens||0,reasoningTokens:L?.reasoning_tokens}};return W1.debug("✅ [GptOpenaiPlatformChatService] Chat completed successfully"),B}catch(O){let U=Date.now()-X;throw W1.error("❌ [GptOpenaiPlatformChatService] Chat request failed after",U,"ms"),W1.error("❌ [GptOpenaiPlatformChatService] Error details:",O),O}}async*streamChat($,Y,Z){let X=Date.now();W1.debug("\uD83D\uDE80 [GptOpenaiPlatformChatService] Starting stream request"),W1.debug("\uD83D\uDCDD [GptOpenaiPlatformChatService] Messages count:",$.length);let Q=this.createClient(),J=v5(this.config.model),G=(J?E5($):$).map((O)=>{if(O.role==="tool")return{role:"tool",content:typeof O.content==="string"?O.content:O.content.filter((F)=>F.type==="text").map((F)=>F.text).join(`
103
+ `))||null,tool_calls:O.tool_calls};if(O.role==="user"&&Array.isArray(O.content))return{role:"user",content:O.content.map((W)=>{if(W.type==="text")return{type:"text",text:W.text};return{type:"image_url",image_url:{url:W.image_url.url}}})};return{role:O.role,content:typeof O.content==="string"?O.content:O.content.filter((W)=>W.type==="text").map((W)=>W.text).join(`
104
+ `)}}),G=Y?.map((O)=>({type:"function",function:{name:O.name,description:O.description,parameters:J?J4(O.parameters):O.parameters}}));W1.debug("\uD83D\uDD27 [GptOpenaiPlatformChatService] Tools count:",G?.length||0);let U={model:this.config.model,messages:K,tools:G,tool_choice:G&&G.length>0?"auto":void 0,max_tokens:this.config.maxOutputTokens??32768,temperature:this.config.temperature??0};W1.debug("\uD83D\uDCE4 [GptOpenaiPlatformChatService] Request params:",{model:U.model,messagesCount:U.messages.length,toolsCount:U.tools?.length||0,tool_choice:U.tool_choice,max_tokens:U.max_tokens,temperature:U.temperature});try{let O=await Q.chat.completions.create(U,{signal:Z}),W=Date.now()-X;if(W1.debug("\uD83D\uDCE5 [GptOpenaiPlatformChatService] Response received in",W,"ms"),!O)throw W1.error("❌ [GptOpenaiPlatformChatService] API returned null/undefined response"),Error("API returned null/undefined response");if(!O.choices||!Array.isArray(O.choices))throw W1.error("❌ [GptOpenaiPlatformChatService] Invalid API response format - missing choices array"),Error(`Invalid API response: missing choices array. Response: ${JSON.stringify(O)}`);if(O.choices.length===0)throw W1.error("❌ [GptOpenaiPlatformChatService] API returned empty choices array"),Error("API returned empty choices array");let F=O.choices[0];if(!F)throw W1.error("❌ [GptOpenaiPlatformChatService] No completion choice returned"),Error("No completion choice returned");W1.debug("\uD83D\uDCDD [GptOpenaiPlatformChatService] Response choice:",{finishReason:F.finish_reason,contentLength:F.message.content?.length||0,hasToolCalls:!!F.message.tool_calls,toolCallsCount:F.message.tool_calls?.length||0});let H=F.message.tool_calls?.filter((_)=>_.type==="function"),N=F.message.reasoning_content||void 0,L=O.usage,B={content:F.message.content||"",reasoningContent:N,toolCalls:H,usage:{promptTokens:O.usage?.prompt_tokens||0,completionTokens:O.usage?.completion_tokens||0,totalTokens:O.usage?.total_tokens||0,reasoningTokens:L?.reasoning_tokens}};return W1.debug("✅ [GptOpenaiPlatformChatService] Chat completed successfully"),B}catch(O){let W=Date.now()-X;throw W1.error("❌ [GptOpenaiPlatformChatService] Chat request failed after",W,"ms"),W1.error("❌ [GptOpenaiPlatformChatService] Error details:",O),O}}async*streamChat($,Y,Z){let X=Date.now();W1.debug("\uD83D\uDE80 [GptOpenaiPlatformChatService] Starting stream request"),W1.debug("\uD83D\uDCDD [GptOpenaiPlatformChatService] Messages count:",$.length);let Q=this.createClient(),J=r5(this.config.model),K=(J?a5($):$).map((O)=>{if(O.role==="tool")return{role:"tool",content:typeof O.content==="string"?O.content:O.content.filter((F)=>F.type==="text").map((F)=>F.text).join(`
98
105
  `),tool_call_id:O.tool_call_id};if(O.role==="assistant"&&O.tool_calls)return{role:"assistant",content:(typeof O.content==="string"?O.content:O.content?.filter((F)=>F.type==="text").map((F)=>F.text).join(`
99
- `))||null,tool_calls:O.tool_calls};if(O.role==="user"&&Array.isArray(O.content))return{role:"user",content:O.content.map((U)=>{if(U.type==="text")return{type:"text",text:U.text};return{type:"image_url",image_url:{url:U.image_url.url}}})};return{role:O.role,content:typeof O.content==="string"?O.content:O.content.filter((U)=>U.type==="text").map((U)=>U.text).join(`
100
- `)}}),K=Y?.map((O)=>({type:"function",function:{name:O.name,description:O.description,parameters:J?Z4(O.parameters):O.parameters}})),W={model:this.config.model,messages:G,tools:K,tool_choice:K&&K.length>0?"auto":"none",max_tokens:this.config.maxOutputTokens??32768,temperature:this.config.temperature??0,stream:!0};W1.debug("\uD83D\uDCE4 [GptOpenaiPlatformChatService] Stream request params:",{model:W.model,messagesCount:W.messages.length,toolsCount:W.tools?.length||0});try{let O=await Q.chat.completions.create(W,{signal:Z}),U=Date.now()-X;W1.debug("\uD83D\uDCE5 [GptOpenaiPlatformChatService] Stream started in",U,"ms");let F=0,H="",_="",z=!1;for await(let L of O){if(F++,!L||!L.choices||!Array.isArray(L.choices)){W1.warn("⚠️ [GptOpenaiPlatformChatService] Invalid chunk format in stream",F);continue}let B=L.choices[0]?.delta;if(!B)continue;let N=B;if(B.content)H+=B.content;if(N.reasoning_content)_+=N.reasoning_content;if(B.tool_calls&&!z)z=!0,W1.debug("\uD83D\uDD27 [GptOpenaiPlatformChatService] Tool calls detected in stream");let I=L.choices[0]?.finish_reason;if(I)W1.debug("\uD83C\uDFC1 [GptOpenaiPlatformChatService] Stream finished with reason:",I),W1.debug("\uD83D\uDCCA [GptOpenaiPlatformChatService] Stream summary:",{totalChunks:F,totalContentLength:H.length,totalReasoningContentLength:_.length,hadToolCalls:z,duration:Date.now()-X+"ms"});yield{content:B.content||void 0,reasoningContent:N.reasoning_content||void 0,toolCalls:B.tool_calls,finishReason:I||void 0}}W1.debug("✅ [GptOpenaiPlatformChatService] Stream completed successfully")}catch(O){let U=Date.now()-X;throw W1.error("❌ [GptOpenaiPlatformChatService] Stream request failed after",U,"ms"),W1.error("❌ [GptOpenaiPlatformChatService] Stream error details:",O),O}}getConfig(){return{...this.config}}updateConfig($){W1.debug("\uD83D\uDD04 [GptOpenaiPlatformChatService] Updating configuration"),this.config={...this.config,...$},W1.debug("✅ [GptOpenaiPlatformChatService] Configuration updated successfully")}}var W1;var P5=b(()=>{V1();W1=n("Chat")});import T5 from"openai";function uG($){for(let Y of S5){let Z=$[Y];if(Z)return{content:Z,fieldName:Y}}return}function k5($){let Y=new Set;for(let Z of $)if(Z.role==="assistant"&&Z.tool_calls)for(let X of Z.tool_calls)Y.add(X.id);return $.filter((Z)=>{if(Z.role==="tool"){if(!Z.tool_call_id)return!1;return Y.has(Z.tool_call_id)}return!0})}class X4{config;client;detectedReasoningFieldName=null;convertToOpenAIMessages($){return $.map((Y)=>{if(Y.role==="tool")return{role:"tool",content:typeof Y.content==="string"?Y.content:Y.content.filter((X)=>X.type==="text").map((X)=>X.text).join(`
106
+ `))||null,tool_calls:O.tool_calls};if(O.role==="user"&&Array.isArray(O.content))return{role:"user",content:O.content.map((W)=>{if(W.type==="text")return{type:"text",text:W.text};return{type:"image_url",image_url:{url:W.image_url.url}}})};return{role:O.role,content:typeof O.content==="string"?O.content:O.content.filter((W)=>W.type==="text").map((W)=>W.text).join(`
107
+ `)}}),G=Y?.map((O)=>({type:"function",function:{name:O.name,description:O.description,parameters:J?J4(O.parameters):O.parameters}})),U={model:this.config.model,messages:K,tools:G,tool_choice:G&&G.length>0?"auto":"none",max_tokens:this.config.maxOutputTokens??32768,temperature:this.config.temperature??0,stream:!0};W1.debug("\uD83D\uDCE4 [GptOpenaiPlatformChatService] Stream request params:",{model:U.model,messagesCount:U.messages.length,toolsCount:U.tools?.length||0});try{let O=await Q.chat.completions.create(U,{signal:Z}),W=Date.now()-X;W1.debug("\uD83D\uDCE5 [GptOpenaiPlatformChatService] Stream started in",W,"ms");let F=0,H="",z="",N=!1;for await(let L of O){if(F++,!L||!L.choices||!Array.isArray(L.choices)){W1.warn("⚠️ [GptOpenaiPlatformChatService] Invalid chunk format in stream",F);continue}let B=L.choices[0]?.delta;if(!B)continue;let _=B;if(B.content)H+=B.content;if(_.reasoning_content)z+=_.reasoning_content;if(B.tool_calls&&!N)N=!0,W1.debug("\uD83D\uDD27 [GptOpenaiPlatformChatService] Tool calls detected in stream");let I=L.choices[0]?.finish_reason;if(I)W1.debug("\uD83C\uDFC1 [GptOpenaiPlatformChatService] Stream finished with reason:",I),W1.debug("\uD83D\uDCCA [GptOpenaiPlatformChatService] Stream summary:",{totalChunks:F,totalContentLength:H.length,totalReasoningContentLength:z.length,hadToolCalls:N,duration:Date.now()-X+"ms"});yield{content:B.content||void 0,reasoningContent:_.reasoning_content||void 0,toolCalls:B.tool_calls,finishReason:I||void 0}}W1.debug("✅ [GptOpenaiPlatformChatService] Stream completed successfully")}catch(O){let W=Date.now()-X;throw W1.error("❌ [GptOpenaiPlatformChatService] Stream request failed after",W,"ms"),W1.error("❌ [GptOpenaiPlatformChatService] Stream error details:",O),O}}getConfig(){return{...this.config}}updateConfig($){W1.debug("\uD83D\uDD04 [GptOpenaiPlatformChatService] Updating configuration"),this.config={...this.config,...$},W1.debug("✅ [GptOpenaiPlatformChatService] Configuration updated successfully")}}var W1;var n5=b(()=>{w1();W1=c("Chat")});import o5 from"openai";function GG($){for(let Y of t5){let Z=$[Y];if(Z)return{content:Z,fieldName:Y}}return}function s5($){let Y=new Set;for(let Z of $)if(Z.role==="assistant"&&Z.tool_calls)for(let X of Z.tool_calls)Y.add(X.id);return $.filter((Z)=>{if(Z.role==="tool"){if(!Z.tool_call_id)return!1;return Y.has(Z.tool_call_id)}return!0})}class q4{config;client;detectedReasoningFieldName=null;convertToOpenAIMessages($){return $.map((Y)=>{if(Y.role==="tool")return{role:"tool",content:typeof Y.content==="string"?Y.content:Y.content.filter((X)=>X.type==="text").map((X)=>X.text).join(`
101
108
  `),tool_call_id:Y.tool_call_id};if(Y.role==="assistant"&&Y.tool_calls){let X={role:"assistant",content:(typeof Y.content==="string"?Y.content:Y.content.filter((Q)=>Q.type==="text").map((Q)=>Q.text).join(`
102
- `))||null,tool_calls:Y.tool_calls};if(this.config.supportsThinking){let Q="reasoningContent"in Y&&Y.reasoningContent?Y.reasoningContent:"";if(this.detectedReasoningFieldName)X[this.detectedReasoningFieldName]=Q;else for(let J of S5)X[J]=Q}return X}if(Y.role==="user"&&Array.isArray(Y.content))return{role:"user",content:Y.content.map((Z)=>{if(Z.type==="text")return{type:"text",text:Z.text};return{type:"image_url",image_url:{url:Z.image_url.url}}})};return{role:Y.role,content:typeof Y.content==="string"?Y.content:Y.content.filter((Z)=>Z.type==="text").map((Z)=>Z.text).join(`
103
- `)}})}convertToOpenAITools($){return $?.map((Y)=>({type:"function",function:{name:Y.name,description:Y.description,parameters:Y.parameters}}))}extractAndDetectReasoning($){let Y=uG($);if(Y){if(!this.detectedReasoningFieldName)this.detectedReasoningFieldName=Y.fieldName,i.debug(`\uD83E\uDDE0 [ChatService] Detected reasoning field: ${Y.fieldName}`);return Y.content}return}constructor($){this.config=$;if(i.debug("\uD83D\uDE80 [ChatService] Initializing ChatService"),i.debug("⚙️ [ChatService] Config:",{model:$.model,baseUrl:$.baseUrl,temperature:$.temperature,maxContextTokens:$.maxContextTokens,timeout:$.timeout,hasApiKey:!!$.apiKey}),!$.baseUrl)throw i.error("❌ [ChatService] baseUrl is required in ChatConfig"),Error("baseUrl is required in ChatConfig");if(!$.apiKey)throw i.error("❌ [ChatService] apiKey is required in ChatConfig"),Error("apiKey is required in ChatConfig");if(!$.model)throw i.error("❌ [ChatService] model is required in ChatConfig"),Error("model is required in ChatConfig");this.client=new T5({apiKey:$.apiKey,baseURL:$.baseUrl,timeout:$.timeout??180000,maxRetries:3}),i.debug("✅ [ChatService] ChatService initialized successfully")}async chat($,Y,Z){let X=Date.now();i.debug("\uD83D\uDE80 [ChatService] Starting chat request"),i.debug("\uD83D\uDCDD [ChatService] Messages count:",$.length);let Q=k5($);if(Q.length<$.length)i.debug(`\uD83D\uDD27 [ChatService] 过滤掉 ${$.length-Q.length} 条孤儿 tool 消息`);i.debug("\uD83D\uDCDD [ChatService] Messages preview:",Q.map((K)=>({role:K.role,contentLength:typeof K.content==="string"?K.content.length:K.content.length,isMultimodal:Array.isArray(K.content)})));let J=this.convertToOpenAIMessages(Q),q=this.convertToOpenAITools(Y);if(i.debug("\uD83D\uDD27 [ChatService] Tools count:",q?.length||0),q&&q.length>0)i.debug("\uD83D\uDD27 [ChatService] Available tools:",q.map((K)=>K.type==="function"?K.function.name:"unknown"));let G={model:this.config.model,messages:J,tools:q,tool_choice:q&&q.length>0?"auto":void 0,max_tokens:this.config.maxOutputTokens??32768,temperature:this.config.temperature??0};i.debug("\uD83D\uDCE4 [ChatService] Request params:",{model:G.model,messagesCount:G.messages.length,toolsCount:G.tools?.length||0,tool_choice:G.tool_choice,max_tokens:G.max_tokens,temperature:G.temperature});try{let K=await this.client.chat.completions.create(G,{signal:Z}),W=Date.now()-X;if(i.debug("\uD83D\uDCE5 [ChatService] Response received in",W,"ms"),!K)throw i.error("❌ [ChatService] API returned null/undefined response"),Error("API returned null/undefined response");if(!K.choices||!Array.isArray(K.choices))throw i.error("❌ [ChatService] Invalid API response format - missing choices array"),i.error("❌ [ChatService] Response object:",JSON.stringify(K,null,2)),Error(`Invalid API response: missing choices array. Response: ${JSON.stringify(K)}`);if(K.choices.length===0)throw i.error("❌ [ChatService] API returned empty choices array"),Error("API returned empty choices array");i.debug("\uD83D\uDCCA [ChatService] Response usage:",K.usage),i.debug("\uD83D\uDCCA [ChatService] Response choices count:",K.choices.length);let O=K.choices[0];if(!O)throw i.error("❌ [ChatService] No completion choice returned"),Error("No completion choice returned");if(i.debug("\uD83D\uDCDD [ChatService] Response choice:",{finishReason:O.finish_reason,contentLength:O.message.content?.length||0,hasToolCalls:!!O.message.tool_calls,toolCallsCount:O.message.tool_calls?.length||0}),O.message.tool_calls)i.debug("\uD83D\uDD27 [ChatService] Tool calls:",O.message.tool_calls.map((L)=>({id:L.id,type:L.type,functionName:L.type==="function"?L.function?.name:"unknown",functionArgsLength:L.type==="function"?L.function?.arguments?.length||0:0})));let U=O.message.tool_calls?.filter((L)=>L.type==="function"),F=O.message,H=this.extractAndDetectReasoning(F);if(this.config.supportsThinking)i.debug("\uD83E\uDDE0 [ChatService] Thinking model response:",{reasoningContentLength:H?.length||0,detectedFieldName:this.detectedReasoningFieldName,messageKeys:Object.keys(O.message)});let _=K.usage,z={content:O.message.content||"",reasoningContent:H,toolCalls:U,usage:{promptTokens:K.usage?.prompt_tokens||0,completionTokens:K.usage?.completion_tokens||0,totalTokens:K.usage?.total_tokens||0,reasoningTokens:_?.reasoning_tokens}};return i.debug("✅ [ChatService] Chat completed successfully"),i.debug("\uD83D\uDCCA [ChatService] Final response:",{contentLength:z.content.length,toolCallsCount:z.toolCalls?.length||0,usage:z.usage}),z}catch(K){let W=Date.now()-X;throw i.error("❌ [ChatService] Chat request failed after",W,"ms"),i.error("❌ [ChatService] Error details:",K),K}}async*streamChat($,Y,Z){let X=Date.now();i.debug("\uD83D\uDE80 [ChatService] Starting chat stream request"),i.debug("\uD83D\uDCDD [ChatService] Messages count:",$.length);let Q=k5($);if(Q.length<$.length)i.debug(`\uD83D\uDD27 [ChatService] 过滤掉 ${$.length-Q.length} 条孤儿 tool 消息`);i.debug("\uD83D\uDCDD [ChatService] Messages preview:",Q.map((K)=>({role:K.role,contentLength:typeof K.content==="string"?K.content.length:K.content.length,isMultimodal:Array.isArray(K.content)})));let J=this.convertToOpenAIMessages(Q),q=this.convertToOpenAITools(Y);if(i.debug("\uD83D\uDD27 [ChatService] Stream tools count:",q?.length||0),q&&q.length>0)i.debug("\uD83D\uDD27 [ChatService] Stream available tools:",q.map((K)=>K.type==="function"?K.function.name:"unknown"));let G={model:this.config.model,messages:J,tools:q,tool_choice:q&&q.length>0?"auto":"none",max_tokens:this.config.maxOutputTokens??32768,temperature:this.config.temperature??0,stream:!0};i.debug("\uD83D\uDCE4 [ChatService] Stream request params:",{model:G.model,messagesCount:G.messages.length,toolsCount:G.tools?.length||0,tool_choice:G.tool_choice,max_tokens:G.max_tokens,temperature:G.temperature,stream:G.stream});try{let K=await this.client.chat.completions.create(G,{signal:Z}),W=Date.now()-X;i.debug("\uD83D\uDCE5 [ChatService] Stream started in",W,"ms");let O=0,U="",F="",H=!1;for await(let _ of K){if(O++,!_||!_.choices||!Array.isArray(_.choices)){i.warn("⚠️ [ChatService] Invalid chunk format in stream",O);continue}let z=_.choices[0]?.delta;if(!z){i.warn("⚠️ [ChatService] Empty delta in chunk",O);continue}let L=z,B=this.extractAndDetectReasoning(L);if(z.content)U+=z.content;if(B)F+=B;if(z.tool_calls&&!H)H=!0,i.debug("\uD83D\uDD27 [ChatService] Tool calls detected in stream");let N=_.choices[0]?.finish_reason;if(N)i.debug("\uD83C\uDFC1 [ChatService] Stream finished with reason:",N),i.debug("\uD83D\uDCCA [ChatService] Stream summary:",{totalChunks:O,totalContentLength:U.length,totalReasoningContentLength:F.length,hadToolCalls:H,duration:Date.now()-X+"ms"});yield{content:z.content||void 0,reasoningContent:B,toolCalls:z.tool_calls,finishReason:N||void 0}}i.debug("✅ [ChatService] Stream completed successfully")}catch(K){let W=Date.now()-X;throw i.error("❌ [ChatService] Stream request failed after",W,"ms"),i.error("❌ [ChatService] Stream error details:",K),K}}getConfig(){return{...this.config}}updateConfig($){i.debug("\uD83D\uDD04 [ChatService] Updating configuration"),i.debug("\uD83D\uDD04 [ChatService] New config:",{model:$.model,baseUrl:$.baseUrl,temperature:$.temperature,maxContextTokens:$.maxContextTokens,timeout:$.timeout,hasApiKey:!!$.apiKey});let Y={...this.config};if(this.config={...this.config,...$},Y.baseUrl!==this.config.baseUrl)this.detectedReasoningFieldName=null,i.debug("\uD83D\uDD04 [ChatService] Reset detectedReasoningFieldName due to baseUrl change");this.client=new T5({apiKey:this.config.apiKey,baseURL:this.config.baseUrl,timeout:this.config.timeout??180000,maxRetries:2}),i.debug("✅ [ChatService] Configuration updated successfully"),i.debug("\uD83D\uDCCA [ChatService] Config changes:",{modelChanged:Y.model!==this.config.model,baseUrlChanged:Y.baseUrl!==this.config.baseUrl,temperatureChanged:Y.temperature!==this.config.temperature,maxContextTokensChanged:Y.maxContextTokens!==this.config.maxContextTokens,timeoutChanged:Y.timeout!==this.config.timeout,apiKeyChanged:Y.apiKey!==this.config.apiKey})}}var i,S5;var C5=b(()=>{V1();i=n("Chat"),S5=["reasoning_content","reasoning","reasoningContent","thinking_content"]});function Q4($){switch($.provider){case"openai-compatible":return new X4($);case"gpt-openai-platform":return new $8($);case"anthropic":throw Error(`❌ Anthropic provider 暂未实现
104
-
105
- `+`请使用 "openai-compatible" 提供商,或者:
106
- `+`1. 等待官方实现
107
- `+`2. 贡献代码实现此功能: https://github.com/echoVic/blade-code
108
- `);default:return mG.warn(`⚠️ 未知的 provider: ${$.provider}, 回退到 openai-compatible`),new X4($)}}var mG;var Y8=b(()=>{V1();P5();C5();mG=n("Service")});import{readFile as dG}from"node:fs/promises";class J4{static MAX_FILES=5;static MAX_LINES_PER_FILE=1000;static analyzeFiles($){let Y=new Map;return $.forEach((X,Q)=>{let J=typeof X.content==="string"?X.content:(X.content||[]).filter((G)=>G.type==="text").map((G)=>G.text).join(`
109
- `);if(this.extractFilePathsFromContent(J).forEach((G)=>{this.updateFileReference(Y,G,Q,!1)}),X.tool_calls&&Array.isArray(X.tool_calls))X.tool_calls.forEach((G)=>{let K=this.extractFilePathsFromToolCall(G),W=G.type==="function"&&"function"in G?G.function?.name:"",O=["Write","Edit"].includes(W||"");K.forEach((U)=>{this.updateFileReference(Y,U,Q,O)})})}),Array.from(Y.values()).sort((X,Q)=>{if(X.wasModified!==Q.wasModified)return X.wasModified?-1:1;if(X.mentions!==Q.mentions)return Q.mentions-X.mentions;return Q.lastMentioned-X.lastMentioned}).slice(0,this.MAX_FILES)}static async readFilesContent($){let Y=[];for(let Z of $)try{let X=await dG(Z,"utf-8"),Q=X.split(`
110
- `),J=Q.length,q=X,G=!1,K=J;if(J>this.MAX_LINES_PER_FILE)q=Q.slice(0,this.MAX_LINES_PER_FILE).join(`
109
+ `))||null,tool_calls:Y.tool_calls};if(this.config.supportsThinking){let Q="reasoningContent"in Y&&Y.reasoningContent?Y.reasoningContent:"";if(this.detectedReasoningFieldName)X[this.detectedReasoningFieldName]=Q;else for(let J of t5)X[J]=Q}return X}if(Y.role==="user"&&Array.isArray(Y.content))return{role:"user",content:Y.content.map((Z)=>{if(Z.type==="text")return{type:"text",text:Z.text};return{type:"image_url",image_url:{url:Z.image_url.url}}})};return{role:Y.role,content:typeof Y.content==="string"?Y.content:Y.content.filter((Z)=>Z.type==="text").map((Z)=>Z.text).join(`
110
+ `)}})}convertToOpenAITools($){return $?.map((Y)=>({type:"function",function:{name:Y.name,description:Y.description,parameters:Y.parameters}}))}extractAndDetectReasoning($){let Y=GG($);if(Y){if(!this.detectedReasoningFieldName)this.detectedReasoningFieldName=Y.fieldName,a.debug(`\uD83E\uDDE0 [ChatService] Detected reasoning field: ${Y.fieldName}`);return Y.content}return}constructor($){this.config=$;if(a.debug("\uD83D\uDE80 [ChatService] Initializing ChatService"),a.debug("⚙️ [ChatService] Config:",{model:$.model,baseUrl:$.baseUrl,temperature:$.temperature,maxContextTokens:$.maxContextTokens,timeout:$.timeout,hasApiKey:!!$.apiKey}),!$.baseUrl)throw a.error("❌ [ChatService] baseUrl is required in ChatConfig"),Error("baseUrl is required in ChatConfig");if(!$.apiKey)throw a.error("❌ [ChatService] apiKey is required in ChatConfig"),Error("apiKey is required in ChatConfig");if(!$.model)throw a.error("❌ [ChatService] model is required in ChatConfig"),Error("model is required in ChatConfig");this.client=new o5({apiKey:$.apiKey,baseURL:$.baseUrl,timeout:$.timeout??180000,maxRetries:3}),a.debug("✅ [ChatService] ChatService initialized successfully")}async chat($,Y,Z){let X=Date.now();a.debug("\uD83D\uDE80 [ChatService] Starting chat request"),a.debug("\uD83D\uDCDD [ChatService] Messages count:",$.length);let Q=s5($);if(Q.length<$.length)a.debug(`\uD83D\uDD27 [ChatService] 过滤掉 ${$.length-Q.length} 条孤儿 tool 消息`);a.debug("\uD83D\uDCDD [ChatService] Messages preview:",Q.map((G)=>({role:G.role,contentLength:typeof G.content==="string"?G.content.length:G.content.length,isMultimodal:Array.isArray(G.content)})));let J=this.convertToOpenAIMessages(Q),q=this.convertToOpenAITools(Y);if(a.debug("\uD83D\uDD27 [ChatService] Tools count:",q?.length||0),q&&q.length>0)a.debug("\uD83D\uDD27 [ChatService] Available tools:",q.map((G)=>G.type==="function"?G.function.name:"unknown"));let K={model:this.config.model,messages:J,tools:q,tool_choice:q&&q.length>0?"auto":void 0,max_tokens:this.config.maxOutputTokens??32768,temperature:this.config.temperature??0};a.debug("\uD83D\uDCE4 [ChatService] Request params:",{model:K.model,messagesCount:K.messages.length,toolsCount:K.tools?.length||0,tool_choice:K.tool_choice,max_tokens:K.max_tokens,temperature:K.temperature});try{let G=await this.client.chat.completions.create(K,{signal:Z}),U=Date.now()-X;if(a.debug("\uD83D\uDCE5 [ChatService] Response received in",U,"ms"),!G)throw a.error("❌ [ChatService] API returned null/undefined response"),Error("API returned null/undefined response");if(!G.choices||!Array.isArray(G.choices))throw a.error("❌ [ChatService] Invalid API response format - missing choices array"),a.error("❌ [ChatService] Response object:",JSON.stringify(G,null,2)),Error(`Invalid API response: missing choices array. Response: ${JSON.stringify(G)}`);if(G.choices.length===0)throw a.error("❌ [ChatService] API returned empty choices array"),Error("API returned empty choices array");a.debug("\uD83D\uDCCA [ChatService] Response usage:",G.usage),a.debug("\uD83D\uDCCA [ChatService] Response choices count:",G.choices.length);let O=G.choices[0];if(!O)throw a.error("❌ [ChatService] No completion choice returned"),Error("No completion choice returned");if(a.debug("\uD83D\uDCDD [ChatService] Response choice:",{finishReason:O.finish_reason,contentLength:O.message.content?.length||0,hasToolCalls:!!O.message.tool_calls,toolCallsCount:O.message.tool_calls?.length||0}),O.message.tool_calls)a.debug("\uD83D\uDD27 [ChatService] Tool calls:",O.message.tool_calls.map((L)=>({id:L.id,type:L.type,functionName:L.type==="function"?L.function?.name:"unknown",functionArgsLength:L.type==="function"?L.function?.arguments?.length||0:0})));let W=O.message.tool_calls?.filter((L)=>L.type==="function"),F=O.message,H=this.extractAndDetectReasoning(F);if(this.config.supportsThinking)a.debug("\uD83E\uDDE0 [ChatService] Thinking model response:",{reasoningContentLength:H?.length||0,detectedFieldName:this.detectedReasoningFieldName,messageKeys:Object.keys(O.message)});let z=G.usage,N={content:O.message.content||"",reasoningContent:H,toolCalls:W,usage:{promptTokens:G.usage?.prompt_tokens||0,completionTokens:G.usage?.completion_tokens||0,totalTokens:G.usage?.total_tokens||0,reasoningTokens:z?.reasoning_tokens}};return a.debug("✅ [ChatService] Chat completed successfully"),a.debug("\uD83D\uDCCA [ChatService] Final response:",{contentLength:N.content.length,toolCallsCount:N.toolCalls?.length||0,usage:N.usage}),N}catch(G){let U=Date.now()-X;throw a.error("❌ [ChatService] Chat request failed after",U,"ms"),a.error("❌ [ChatService] Error details:",G),G}}async*streamChat($,Y,Z){let X=Date.now();a.debug("\uD83D\uDE80 [ChatService] Starting chat stream request"),a.debug("\uD83D\uDCDD [ChatService] Messages count:",$.length);let Q=s5($);if(Q.length<$.length)a.debug(`\uD83D\uDD27 [ChatService] 过滤掉 ${$.length-Q.length} 条孤儿 tool 消息`);a.debug("\uD83D\uDCDD [ChatService] Messages preview:",Q.map((G)=>({role:G.role,contentLength:typeof G.content==="string"?G.content.length:G.content.length,isMultimodal:Array.isArray(G.content)})));let J=this.convertToOpenAIMessages(Q),q=this.convertToOpenAITools(Y);if(a.debug("\uD83D\uDD27 [ChatService] Stream tools count:",q?.length||0),q&&q.length>0)a.debug("\uD83D\uDD27 [ChatService] Stream available tools:",q.map((G)=>G.type==="function"?G.function.name:"unknown"));let K={model:this.config.model,messages:J,tools:q,tool_choice:q&&q.length>0?"auto":"none",max_tokens:this.config.maxOutputTokens??32768,temperature:this.config.temperature??0,stream:!0};a.debug("\uD83D\uDCE4 [ChatService] Stream request params:",{model:K.model,messagesCount:K.messages.length,toolsCount:K.tools?.length||0,tool_choice:K.tool_choice,max_tokens:K.max_tokens,temperature:K.temperature,stream:K.stream});try{let G=await this.client.chat.completions.create(K,{signal:Z}),U=Date.now()-X;a.debug("\uD83D\uDCE5 [ChatService] Stream started in",U,"ms");let O=0,W="",F="",H=!1;for await(let z of G){if(O++,!z||!z.choices||!Array.isArray(z.choices)){a.warn("⚠️ [ChatService] Invalid chunk format in stream",O);continue}let N=z.choices[0]?.delta;if(!N){a.warn("⚠️ [ChatService] Empty delta in chunk",O);continue}let L=N,B=this.extractAndDetectReasoning(L);if(N.content)W+=N.content;if(B)F+=B;if(N.tool_calls&&!H)H=!0,a.debug("\uD83D\uDD27 [ChatService] Tool calls detected in stream");let _=z.choices[0]?.finish_reason;if(_)a.debug("\uD83C\uDFC1 [ChatService] Stream finished with reason:",_),a.debug("\uD83D\uDCCA [ChatService] Stream summary:",{totalChunks:O,totalContentLength:W.length,totalReasoningContentLength:F.length,hadToolCalls:H,duration:Date.now()-X+"ms"});yield{content:N.content||void 0,reasoningContent:B,toolCalls:N.tool_calls,finishReason:_||void 0}}a.debug("✅ [ChatService] Stream completed successfully")}catch(G){let U=Date.now()-X;throw a.error("❌ [ChatService] Stream request failed after",U,"ms"),a.error("❌ [ChatService] Stream error details:",G),G}}getConfig(){return{...this.config}}updateConfig($){a.debug("\uD83D\uDD04 [ChatService] Updating configuration"),a.debug("\uD83D\uDD04 [ChatService] New config:",{model:$.model,baseUrl:$.baseUrl,temperature:$.temperature,maxContextTokens:$.maxContextTokens,timeout:$.timeout,hasApiKey:!!$.apiKey});let Y={...this.config};if(this.config={...this.config,...$},Y.baseUrl!==this.config.baseUrl)this.detectedReasoningFieldName=null,a.debug("\uD83D\uDD04 [ChatService] Reset detectedReasoningFieldName due to baseUrl change");this.client=new o5({apiKey:this.config.apiKey,baseURL:this.config.baseUrl,timeout:this.config.timeout??180000,maxRetries:2}),a.debug("✅ [ChatService] Configuration updated successfully"),a.debug("\uD83D\uDCCA [ChatService] Config changes:",{modelChanged:Y.model!==this.config.model,baseUrlChanged:Y.baseUrl!==this.config.baseUrl,temperatureChanged:Y.temperature!==this.config.temperature,maxContextTokensChanged:Y.maxContextTokens!==this.config.maxContextTokens,timeoutChanged:Y.timeout!==this.config.timeout,apiKeyChanged:Y.apiKey!==this.config.apiKey})}}var a,t5;var e5=b(()=>{w1();a=c("Chat"),t5=["reasoning_content","reasoning","reasoningContent","thinking_content"]});function K4($){switch($.provider){case"openai-compatible":return new q4($);case"anthropic":return new Q9($);case"gemini":return new G9($);case"azure-openai":return new J9($);case"gpt-openai-platform":return new U9($);default:return UG.warn(`⚠️ 未知的 provider: ${$.provider}, 回退到 openai-compatible`),new q4($)}}var UG;var W9=b(()=>{w1();u5();m5();i5();n5();e5();UG=c("Service")});import{readFile as WG}from"node:fs/promises";class G4{static MAX_FILES=5;static MAX_LINES_PER_FILE=1000;static analyzeFiles($){let Y=new Map;return $.forEach((X,Q)=>{let J=typeof X.content==="string"?X.content:(X.content||[]).filter((K)=>K.type==="text").map((K)=>K.text).join(`
111
+ `);if(this.extractFilePathsFromContent(J).forEach((K)=>{this.updateFileReference(Y,K,Q,!1)}),X.tool_calls&&Array.isArray(X.tool_calls))X.tool_calls.forEach((K)=>{let G=this.extractFilePathsFromToolCall(K),U=K.type==="function"&&"function"in K?K.function?.name:"",O=["Write","Edit"].includes(U||"");G.forEach((W)=>{this.updateFileReference(Y,W,Q,O)})})}),Array.from(Y.values()).sort((X,Q)=>{if(X.wasModified!==Q.wasModified)return X.wasModified?-1:1;if(X.mentions!==Q.mentions)return Q.mentions-X.mentions;return Q.lastMentioned-X.lastMentioned}).slice(0,this.MAX_FILES)}static async readFilesContent($){let Y=[];for(let Z of $)try{let X=await WG(Z,"utf-8"),Q=X.split(`
112
+ `),J=Q.length,q=X,K=!1,G=J;if(J>this.MAX_LINES_PER_FILE)q=Q.slice(0,this.MAX_LINES_PER_FILE).join(`
111
113
  `),q+=`
112
114
 
113
- ... (truncated ${J-this.MAX_LINES_PER_FILE} lines)`,G=!0,K=this.MAX_LINES_PER_FILE;Y.push({path:Z,content:q,truncated:G,lines:J,includedLines:K})}catch(X){console.warn(`[FileAnalyzer] 无法读取文件: ${Z}`,X)}return Y}static extractFilePathsFromContent($){let Y=new Set,Z=/```(?:\w+)?\s*\n?([\s\S]*?)```/g,X=Array.from($.matchAll(Z));for(let J of X){let q=J[1];this.extractPathsFromText(q).forEach((K)=>Y.add(K))}return this.extractPathsFromText($).forEach((J)=>Y.add(J)),Array.from(Y)}static extractPathsFromText($){let Y=[],Z=[/(?:src|tests?|docs?|lib|config|scripts?|bin|utils?|components?|services?|hooks?)\/[\w\-/.]+\.[\w]+/g,/(?:package|tsconfig|vite\.config|webpack\.config|next\.config|babel\.config)\.[\w]+/g,/(?:\.\.?\/|\/)[a-zA-Z0-9\-_/.]+\.[\w]+/g];for(let X of Z){let Q=Array.from($.matchAll(X));for(let J of Q){let q=J[0];if(q=q.replace(/[,。;:!?""''()【】《》]$/g,""),q=q.replace(/[,.;:!?"'()[\]<>]$/g,""),this.isValidFilePath(q))Y.push(q)}}return Y}static extractFilePathsFromToolCall($){let Y=[];try{let Z=$.function?.name,X=typeof $.function?.arguments==="string"?JSON.parse($.function.arguments):$.function?.arguments||{};if(["Read","Write","Edit","Glob","Grep","NotebookEdit","mcp__github__get_file_contents","mcp__github__create_or_update_file"].includes(Z)){let J=["file_path","path","notebook_path","filePath"];for(let q of J)if(X[q]&&typeof X[q]==="string")Y.push(X[q])}}catch(Z){}return Y}static updateFileReference($,Y,Z,X){let Q=$.get(Y);if(Q)Q.mentions++,Q.lastMentioned=Z,Q.wasModified=Q.wasModified||X;else $.set(Y,{path:Y,mentions:1,lastMentioned:Z,wasModified:X})}static isValidFilePath($){if(!$.includes("/"))return!1;let Y=$.split("/"),Z=Y[Y.length-1];if(!Z.includes("."))return!1;let X=["ts","tsx","js","jsx","json","md","py","java","go","rs","c","cpp","h","css","scss","html","xml","yaml","yml","toml","sh","bash","sql","graphql","vue","svelte"],Q=Z.split(".").pop()?.toLowerCase();if(!Q||!X.includes(Q))return!1;return!0}}var f5=()=>{};import{encodingForModel as h5}from"js-tiktoken";var _2;var q4=b(()=>{_2=class _2{static encodingCache=new Map;static countTokens($,Y){let Z=this.getEncoding(Y),X=0;for(let Q of $){if(X+=4,Q.role)X+=Z.encode(Q.role).length;if(Q.content)if(typeof Q.content==="string")X+=Z.encode(Q.content).length;else X+=Z.encode(JSON.stringify(Q.content)).length;if(Q.tool_calls&&Array.isArray(Q.tool_calls))X+=this.countToolCallTokens(Q.tool_calls,Z);if(Q.name)X+=Z.encode(Q.name).length}return X}static getTokenLimit($){return $}static shouldCompact($,Y,Z,X=0.8){let Q=this.countTokens($,Y),J=Math.floor(Z*X);return Q>=J}static getEncoding($){if(!this.encodingCache.has($))try{let Y=h5($);this.encodingCache.set($,Y)}catch{try{let Y=h5("gpt-4");this.encodingCache.set($,Y)}catch{console.warn(`[TokenCounter] 无法为模型 ${$} 获取 encoding,使用粗略估算`),this.encodingCache.set($,{encode:(Y)=>{return Array(Math.ceil(Y.length/4))}})}}return this.encodingCache.get($)}static countToolCallTokens($,Y){let Z=0;for(let X of $){if(Z+=4,X.function?.name)Z+=Y.encode(X.function.name).length;if(X.function?.arguments){let Q=typeof X.function.arguments==="string"?X.function.arguments:JSON.stringify(X.function.arguments);Z+=Y.encode(Q).length}if(X.id)Z+=Y.encode(X.id).length}return Z}static clearCache(){this.encodingCache.clear()}static estimateTokens($){let Y=($.match(/[\u4e00-\u9fa5]/g)||[]).length,Z=$.length-Y;return Math.ceil(Y/1.5+Z/4)}}});import{nanoid as A$}from"nanoid";class b${static THRESHOLD_PERCENT=0.8;static RETAIN_PERCENT=0.2;static FALLBACK_RETAIN_PERCENT=0.3;static async compact($,Y){let Z=Y.actualPreTokens??_2.countTokens($,Y.modelName),X=Y.actualPreTokens?"actual (from LLM usage)":"estimated";console.log(`[CompactionService] preTokens source: ${X}`);try{let J=await H1.getInstance().executeCompactionHooks(Y.trigger,{projectDir:process.cwd(),sessionId:Y.sessionId||"unknown",permissionMode:Y.permissionMode||"default",messagesBefore:$.length,tokensBefore:Z});if(J.blockCompaction)return console.log(`[CompactionService] Compaction hook 阻止压缩: ${J.blockReason||"(无原因)"}`),{success:!1,summary:"",preTokens:Z,postTokens:Z,filesIncluded:[],compactedMessages:$,boundaryMessage:{role:"system",content:""},summaryMessage:{role:"user",content:""},error:J.blockReason||"Compaction blocked by hook"};if(J.warning)console.warn(`[CompactionService] Compaction hook warning: ${J.warning}`)}catch(Q){console.warn("[CompactionService] Compaction hook execution failed:",Q)}try{console.log("[CompactionService] 开始压缩,消息数:",$.length),console.log("[CompactionService] 压缩前 tokens:",Z);let J=J4.analyzeFiles($).map((N)=>N.path);console.log("[CompactionService] 提取重点文件:",J);let q=await J4.readFilesContent(J);console.log("[CompactionService] 成功读取文件:",q.length);let G=await this.generateSummary($,q,Y);console.log("[CompactionService] 生成总结,长度:",G.length);let K=Math.ceil($.length*this.RETAIN_PERCENT),W=$.slice(-K),O=new Set;for(let N of W)if(N.role==="assistant"&&N.tool_calls)for(let I of N.tool_calls)O.add(I.id);let U=W.filter((N)=>{if(N.role==="tool"&&N.tool_call_id)return O.has(N.tool_call_id);return!0});console.log("[CompactionService] 保留消息数:",K),console.log("[CompactionService] 过滤后保留消息数:",U.length);let F=A$(),H=this.createBoundaryMessage(F,Y.trigger,Z),_=A$(),z=this.createSummaryMessage(_,G),L=[z,...U],B=_2.countTokens(L,Y.modelName);return console.log("[CompactionService] 压缩完成!"),console.log("[CompactionService] Token 变化:",Z,"→",B,`(-${((1-B/Z)*100).toFixed(1)}%)`),{success:!0,summary:G,preTokens:Z,postTokens:B,filesIncluded:J,compactedMessages:L,boundaryMessage:H,summaryMessage:z}}catch(Q){return console.error("[CompactionService] 压缩失败,使用降级策略",Q),this.fallbackCompact($,Y,Z,Q)}}static async generateSummary($,Y,Z){let X=this.buildCompactionPrompt($,Y);console.log("[CompactionService] 使用压缩模型:",Z.modelName);let q=(await Q4({apiKey:Z.apiKey||process.env.BLADE_API_KEY||"",baseUrl:Z.baseURL||process.env.BLADE_BASE_URL||"https://api.openai.com/v1",model:Z.modelName,temperature:0.3,maxOutputTokens:8000,timeout:60000,provider:"openai-compatible"}).chat([{role:"user",content:X}])).content||"",G=q.match(/<summary>([\s\S]*?)<\/summary>/);if(!G)return console.warn("[CompactionService] 总结格式不正确,使用完整响应"),q;return G[1].trim()}static buildCompactionPrompt($,Y){let Z=$.map((J,q)=>{let G=J.role||"unknown",K=typeof J.content==="string"?J.content:JSON.stringify(J.content),W=5000,O=K.length>5000?K.substring(0,5000)+"...":K;return`[${q+1}] ${G}: ${O}`}).join(`
115
+ ... (truncated ${J-this.MAX_LINES_PER_FILE} lines)`,K=!0,G=this.MAX_LINES_PER_FILE;Y.push({path:Z,content:q,truncated:K,lines:J,includedLines:G})}catch(X){console.warn(`[FileAnalyzer] 无法读取文件: ${Z}`,X)}return Y}static extractFilePathsFromContent($){let Y=new Set,Z=/```(?:\w+)?\s*\n?([\s\S]*?)```/g,X=Array.from($.matchAll(Z));for(let J of X){let q=J[1];this.extractPathsFromText(q).forEach((G)=>Y.add(G))}return this.extractPathsFromText($).forEach((J)=>Y.add(J)),Array.from(Y)}static extractPathsFromText($){let Y=[],Z=[/(?:src|tests?|docs?|lib|config|scripts?|bin|utils?|components?|services?|hooks?)\/[\w\-/.]+\.[\w]+/g,/(?:package|tsconfig|vite\.config|webpack\.config|next\.config|babel\.config)\.[\w]+/g,/(?:\.\.?\/|\/)[a-zA-Z0-9\-_/.]+\.[\w]+/g];for(let X of Z){let Q=Array.from($.matchAll(X));for(let J of Q){let q=J[0];if(q=q.replace(/[,。;:!?""''()【】《》]$/g,""),q=q.replace(/[,.;:!?"'()[\]<>]$/g,""),this.isValidFilePath(q))Y.push(q)}}return Y}static extractFilePathsFromToolCall($){let Y=[];try{let Z=$.function?.name,X=typeof $.function?.arguments==="string"?JSON.parse($.function.arguments):$.function?.arguments||{};if(["Read","Write","Edit","Glob","Grep","NotebookEdit","mcp__github__get_file_contents","mcp__github__create_or_update_file"].includes(Z)){let J=["file_path","path","notebook_path","filePath"];for(let q of J)if(X[q]&&typeof X[q]==="string")Y.push(X[q])}}catch(Z){}return Y}static updateFileReference($,Y,Z,X){let Q=$.get(Y);if(Q)Q.mentions++,Q.lastMentioned=Z,Q.wasModified=Q.wasModified||X;else $.set(Y,{path:Y,mentions:1,lastMentioned:Z,wasModified:X})}static isValidFilePath($){if(!$.includes("/"))return!1;let Y=$.split("/"),Z=Y[Y.length-1];if(!Z.includes("."))return!1;let X=["ts","tsx","js","jsx","json","md","py","java","go","rs","c","cpp","h","css","scss","html","xml","yaml","yml","toml","sh","bash","sql","graphql","vue","svelte"],Q=Z.split(".").pop()?.toLowerCase();if(!Q||!X.includes(Q))return!1;return!0}}var $Y=()=>{};import{encodingForModel as YY}from"js-tiktoken";var _2;var U4=b(()=>{_2=class _2{static encodingCache=new Map;static countTokens($,Y){let Z=this.getEncoding(Y),X=0;for(let Q of $){if(X+=4,Q.role)X+=Z.encode(Q.role).length;if(Q.content)if(typeof Q.content==="string")X+=Z.encode(Q.content).length;else X+=Z.encode(JSON.stringify(Q.content)).length;if(Q.tool_calls&&Array.isArray(Q.tool_calls))X+=this.countToolCallTokens(Q.tool_calls,Z);if(Q.name)X+=Z.encode(Q.name).length}return X}static getTokenLimit($){return $}static shouldCompact($,Y,Z,X=0.8){let Q=this.countTokens($,Y),J=Math.floor(Z*X);return Q>=J}static getEncoding($){if(!this.encodingCache.has($))try{let Y=YY($);this.encodingCache.set($,Y)}catch{try{let Y=YY("gpt-4");this.encodingCache.set($,Y)}catch{console.warn(`[TokenCounter] 无法为模型 ${$} 获取 encoding,使用粗略估算`),this.encodingCache.set($,{encode:(Y)=>{return Array(Math.ceil(Y.length/4))}})}}return this.encodingCache.get($)}static countToolCallTokens($,Y){let Z=0;for(let X of $){if(Z+=4,X.function?.name)Z+=Y.encode(X.function.name).length;if(X.function?.arguments){let Q=typeof X.function.arguments==="string"?X.function.arguments:JSON.stringify(X.function.arguments);Z+=Y.encode(Q).length}if(X.id)Z+=Y.encode(X.id).length}return Z}static clearCache(){this.encodingCache.clear()}static estimateTokens($){let Y=($.match(/[\u4e00-\u9fa5]/g)||[]).length,Z=$.length-Y;return Math.ceil(Y/1.5+Z/4)}}});import{nanoid as V$}from"nanoid";class D${static THRESHOLD_PERCENT=0.8;static RETAIN_PERCENT=0.2;static FALLBACK_RETAIN_PERCENT=0.3;static async compact($,Y){let Z=Y.actualPreTokens??_2.countTokens($,Y.modelName),X=Y.actualPreTokens?"actual (from LLM usage)":"estimated";console.log(`[CompactionService] preTokens source: ${X}`);try{let J=await H1.getInstance().executeCompactionHooks(Y.trigger,{projectDir:process.cwd(),sessionId:Y.sessionId||"unknown",permissionMode:Y.permissionMode||"default",messagesBefore:$.length,tokensBefore:Z});if(J.blockCompaction)return console.log(`[CompactionService] Compaction hook 阻止压缩: ${J.blockReason||"(无原因)"}`),{success:!1,summary:"",preTokens:Z,postTokens:Z,filesIncluded:[],compactedMessages:$,boundaryMessage:{role:"system",content:""},summaryMessage:{role:"user",content:""},error:J.blockReason||"Compaction blocked by hook"};if(J.warning)console.warn(`[CompactionService] Compaction hook warning: ${J.warning}`)}catch(Q){console.warn("[CompactionService] Compaction hook execution failed:",Q)}try{console.log("[CompactionService] 开始压缩,消息数:",$.length),console.log("[CompactionService] 压缩前 tokens:",Z);let J=G4.analyzeFiles($).map((_)=>_.path);console.log("[CompactionService] 提取重点文件:",J);let q=await G4.readFilesContent(J);console.log("[CompactionService] 成功读取文件:",q.length);let K=await this.generateSummary($,q,Y);console.log("[CompactionService] 生成总结,长度:",K.length);let G=Math.ceil($.length*this.RETAIN_PERCENT),U=$.slice(-G),O=new Set;for(let _ of U)if(_.role==="assistant"&&_.tool_calls)for(let I of _.tool_calls)O.add(I.id);let W=U.filter((_)=>{if(_.role==="tool"&&_.tool_call_id)return O.has(_.tool_call_id);return!0});console.log("[CompactionService] 保留消息数:",G),console.log("[CompactionService] 过滤后保留消息数:",W.length);let F=V$(),H=this.createBoundaryMessage(F,Y.trigger,Z),z=V$(),N=this.createSummaryMessage(z,K),L=[N,...W],B=_2.countTokens(L,Y.modelName);return console.log("[CompactionService] 压缩完成!"),console.log("[CompactionService] Token 变化:",Z,"→",B,`(-${((1-B/Z)*100).toFixed(1)}%)`),{success:!0,summary:K,preTokens:Z,postTokens:B,filesIncluded:J,compactedMessages:L,boundaryMessage:H,summaryMessage:N}}catch(Q){return console.error("[CompactionService] 压缩失败,使用降级策略",Q),this.fallbackCompact($,Y,Z,Q)}}static async generateSummary($,Y,Z){let X=this.buildCompactionPrompt($,Y);console.log("[CompactionService] 使用压缩模型:",Z.modelName);let q=(await K4({apiKey:Z.apiKey||process.env.BLADE_API_KEY||"",baseUrl:Z.baseURL||process.env.BLADE_BASE_URL||"https://api.openai.com/v1",model:Z.modelName,temperature:0.3,maxOutputTokens:8000,timeout:60000,provider:"openai-compatible"}).chat([{role:"user",content:X}])).content||"",K=q.match(/<summary>([\s\S]*?)<\/summary>/);if(!K)return console.warn("[CompactionService] 总结格式不正确,使用完整响应"),q;return K[1].trim()}static buildCompactionPrompt($,Y){let Z=$.map((J,q)=>{let K=J.role||"unknown",G=typeof J.content==="string"?J.content:JSON.stringify(J.content),U=5000,O=G.length>5000?G.substring(0,5000)+"...":G;return`[${q+1}] ${K}: ${O}`}).join(`
114
116
 
115
117
  `),X=Y.map((J)=>{return`### ${J.path}
116
118
  \`\`\`
@@ -183,14 +185,14 @@ ${Y.length>0?`## Important Files
183
185
 
184
186
  ${X}`:""}
185
187
 
186
- Please provide your summary following the structure specified above, with both <analysis> and <summary> sections.`}static createBoundaryMessage($,Y,Z){return{id:A$(),role:"system",content:"Conversation compacted",metadata:{type:"system",subtype:"compact_boundary",parentId:$,compactMetadata:{trigger:Y,preTokens:Z}}}}static createSummaryMessage($,Y){return{id:A$(),role:"user",content:Y,metadata:{parentId:$,isCompactSummary:!0}}}static fallbackCompact($,Y,Z,X){let Q=Math.ceil($.length*this.FALLBACK_RETAIN_PERCENT),J=$.slice(-Q),q=new Set;for(let z of J)if(z.role==="assistant"&&z.tool_calls)for(let L of z.tool_calls)q.add(L.id);let G=J.filter((z)=>{if(z.role==="tool"&&z.tool_call_id)return q.has(z.tool_call_id);return!0}),K=A$(),W=this.createBoundaryMessage(K,Y.trigger,Z),O=X instanceof Error?X.message:String(X),U=A$(),F=this.createSummaryMessage(U,`[Automatic compaction failed; using fallback]
188
+ Please provide your summary following the structure specified above, with both <analysis> and <summary> sections.`}static createBoundaryMessage($,Y,Z){return{id:V$(),role:"system",content:"Conversation compacted",metadata:{type:"system",subtype:"compact_boundary",parentId:$,compactMetadata:{trigger:Y,preTokens:Z}}}}static createSummaryMessage($,Y){return{id:V$(),role:"user",content:Y,metadata:{parentId:$,isCompactSummary:!0}}}static fallbackCompact($,Y,Z,X){let Q=Math.ceil($.length*this.FALLBACK_RETAIN_PERCENT),J=$.slice(-Q),q=new Set;for(let N of J)if(N.role==="assistant"&&N.tool_calls)for(let L of N.tool_calls)q.add(L.id);let K=J.filter((N)=>{if(N.role==="tool"&&N.tool_call_id)return q.has(N.tool_call_id);return!0}),G=V$(),U=this.createBoundaryMessage(G,Y.trigger,Z),O=X instanceof Error?X.message:String(X),W=V$(),F=this.createSummaryMessage(W,`[Automatic compaction failed; using fallback]
187
189
 
188
190
  An error occurred during compaction. Retained the latest ${Q} messages (~30%).
189
191
 
190
192
  Error: ${O}
191
193
 
192
- The conversation can continue, but consider retrying compaction later with /compact.`),H=[F,...G],_=_2.countTokens(H,Y.modelName);return{success:!1,summary:typeof F.content==="string"?F.content:F.content.filter((z)=>z.type==="text").map((z)=>z.text).join(`
193
- `),preTokens:Z,postTokens:_,filesIncluded:[],compactedMessages:H,boundaryMessage:W,summaryMessage:F,error:O}}}var Z8=b(()=>{s1();z0();Y8();f5();q4()});import cG from"fs/promises";import lG from"path";async function p5($){for(let Y of $)try{let Z;if(Y.trim().startsWith("{")){let J=JSON.parse(Y);if(J.name&&J.type){let{name:q,...G}=J;Z={[q]:G}}else Z=J}else{let J=lG.resolve(process.cwd(),Y),q=await cG.readFile(J,"utf-8"),G=JSON.parse(q);Z=G.mcpServers||G}let Q={...A0(),...Z};e().config.actions.updateConfig({mcpServers:Q}),x5.debug(`✅ Loaded MCP config from CLI: ${Object.keys(Z).join(", ")}`)}catch(Z){x5.warn(`⚠️ Failed to load MCP config "${Y}":`,Z)}}var x5;var g5=b(()=>{V1();N1();x5=n("General")});function u5(){return{metadata:G4,instructions:`# Skill Creator
194
+ The conversation can continue, but consider retrying compaction later with /compact.`),H=[F,...K],z=_2.countTokens(H,Y.modelName);return{success:!1,summary:typeof F.content==="string"?F.content:F.content.filter((N)=>N.type==="text").map((N)=>N.text).join(`
195
+ `),preTokens:Z,postTokens:z,filesIncluded:[],compactedMessages:H,boundaryMessage:U,summaryMessage:F,error:O}}}var O9=b(()=>{$0();L0();W9();$Y();U4()});import OG from"fs/promises";import FG from"path";async function XY($){for(let Y of $)try{let Z;if(Y.trim().startsWith("{")){let J=JSON.parse(Y);if(J.name&&J.type){let{name:q,...K}=J;Z={[q]:K}}else Z=J}else{let J=FG.resolve(process.cwd(),Y),q=await OG.readFile(J,"utf-8"),K=JSON.parse(q);Z=K.mcpServers||K}let Q={...V0(),...Z};$1().config.actions.updateConfig({mcpServers:Q}),ZY.debug(`✅ Loaded MCP config from CLI: ${Object.keys(Z).join(", ")}`)}catch(Z){ZY.warn(`⚠️ Failed to load MCP config "${Y}":`,Z)}}var ZY;var QY=b(()=>{w1();A1();ZY=c("General")});function JY(){return{metadata:W4,instructions:`# Skill Creator
194
196
 
195
197
  帮助用户创建新的 Blade Skills。
196
198
 
@@ -373,10 +375,10 @@ user-invocable: true
373
375
  <footer>
374
376
  \`\`\`
375
377
  \`\`\`
376
- `}}var G4;var m5=b(()=>{G4={name:"skill-creator",description:"Create new Skills interactively. Use when the user wants to create a new Skill, define a custom workflow, or add a specialized capability to Blade.",allowedTools:["Read","Write","Glob","Bash","AskUserQuestion"],version:"1.0.0",argumentHint:void 0,userInvocable:!0,disableModelInvocation:!1,model:void 0,whenToUse:"User wants to create a new skill, define a custom workflow, or add a specialized capability.",path:"builtin://skill-creator",basePath:"",source:"builtin"}});import{exec as iG}from"node:child_process";import*as f1 from"node:fs/promises";import{homedir as aG}from"node:os";import*as p0 from"node:path";import{promisify as rG}from"node:util";class q8{skillsDir;constructor($){this.skillsDir=$||p0.join(aG(),".blade","skills")}async isInstalled($){let Y=p0.join(this.skillsDir,$,"SKILL.md");try{return await f1.access(Y),!0}catch{return!1}}async isGitAvailable(){try{return await X8("git --version"),!0}catch{return!1}}async installOfficialSkill($){let{url:Y,branch:Z}=Q8,X=p0.join(this.skillsDir,$),Q=p0.join(this.skillsDir,`.tmp-${$}-${Date.now()}`);try{if(!await this.isGitAvailable())return s0.warn("Git not available, skipping skill installation"),!1;s0.info(`Installing official skill: ${$}...`),await f1.mkdir(this.skillsDir,{recursive:!0}),await X8(`git clone --depth 1 --branch ${Z} --single-branch ${Y} "${Q}"`,{timeout:30000});let J=p0.join(Q,"skills",$);try{await f1.access(J)}catch{return s0.warn(`Skill ${$} not found in official repository`),await f1.rm(Q,{recursive:!0,force:!0}),!1}try{await f1.rm(X,{recursive:!0,force:!0})}catch{}return await f1.cp(J,X,{recursive:!0}),await f1.rm(Q,{recursive:!0,force:!0}),s0.info(`Successfully installed: ${$}`),!0}catch(J){try{await f1.rm(Q,{recursive:!0,force:!0})}catch{}return s0.warn(`Failed to install ${$}: ${J instanceof Error?J.message:"Unknown error"}`),!1}}async ensureDefaultSkillsInstalled(){await f1.mkdir(this.skillsDir,{recursive:!0});for(let $ of Q8.defaultSkills)if(!await this.isInstalled($))await this.installOfficialSkill($)}async installAllOfficialSkills(){let{url:$,branch:Y}=Q8,Z=p0.join(this.skillsDir,`.tmp-all-${Date.now()}`),X=[],Q=[];try{if(!await this.isGitAvailable())return s0.warn("Git not available, skipping skill installation"),{installed:X,failed:Q};await f1.mkdir(this.skillsDir,{recursive:!0}),s0.info("Cloning official skills repository..."),await X8(`git clone --depth 1 --branch ${Y} --single-branch ${$} "${Z}"`,{timeout:60000});let J=p0.join(Z,"skills"),q=await f1.readdir(J,{withFileTypes:!0});for(let G of q){if(!G.isDirectory())continue;let K=G.name,W=p0.join(J,K),O=p0.join(this.skillsDir,K);try{await f1.access(p0.join(W,"SKILL.md")),await f1.rm(O,{recursive:!0,force:!0}),await f1.cp(W,O,{recursive:!0}),s0.info(`Installed: ${K}`),X.push(K)}catch(U){s0.warn(`Failed to install ${K}`),Q.push(K)}}await f1.rm(Z,{recursive:!0,force:!0})}catch(J){try{await f1.rm(Z,{recursive:!0,force:!0})}catch{}s0.warn(`Failed to install skills: ${J instanceof Error?J.message:"Unknown error"}`)}return{installed:X,failed:Q}}}function G8($){if(!J8)J8=new q8($);return J8}var X8,s0,Q8,J8=null;var K8=b(()=>{V1();X8=rG(iG),s0=n("General"),Q8={url:"https://github.com/anthropics/skills.git",branch:"main",defaultSkills:["skill-creator"]}});import*as H6 from"node:fs/promises";import*as K4 from"node:path";import{parse as nG}from"yaml";function tG($){if(!$)return;if(typeof $==="string")return $.split(",").map((Y)=>Y.trim()).filter(Boolean);if(Array.isArray($))return $.map((Y)=>String(Y).trim()).filter(Boolean);return}function c5($){if($===void 0)return;if(typeof $==="boolean")return $;if(typeof $==="string"){let Y=$.toLowerCase().trim();if(Y==="true"||Y==="yes"||Y==="1")return!0;if(Y==="false"||Y==="no"||Y==="0")return!1}return}function eG($,Y){if(!$.name)return{valid:!1,error:"Missing required field: name"};if(!sG.test($.name))return{valid:!1,error:`Invalid name "${$.name}": must be lowercase letters, numbers, and hyphens only, 1-64 characters`};if(!$.description)return{valid:!1,error:"Missing required field: description"};if($.description.length>d5)return{valid:!1,error:`Description too long: ${$.description.length} characters (max ${d5})`};let Z;if($.model)Z=$.model==="inherit"?"inherit":$.model;return{valid:!0,metadata:{name:$.name,description:$.description.trim(),allowedTools:tG($["allowed-tools"]),version:$.version,argumentHint:$["argument-hint"]?.trim(),userInvocable:c5($["user-invocable"]),disableModelInvocation:c5($["disable-model-invocation"]),model:Z,whenToUse:$.when_to_use?.trim()}}}function U8($,Y,Z){let X=$.match(oG);if(!X)return{success:!1,error:"Invalid SKILL.md format: missing YAML frontmatter (must start with ---)"};let[,Q,J]=X,q;try{q=nG(Q)}catch(W){return{success:!1,error:`Failed to parse YAML frontmatter: ${W instanceof Error?W.message:String(W)}`}}let G=eG(q,Y);if(!G.valid)return{success:!1,error:G.error};let K=K4.dirname(Y);return{success:!0,content:{metadata:{...G.metadata,path:Y,basePath:K,source:Z},instructions:J.trim()}}}async function W8($,Y){try{let Z=await H6.readFile($,"utf-8");return U8(Z,$,Y)}catch(Z){if(Z.code==="ENOENT")return{success:!1,error:`File not found: ${$}`};return{success:!1,error:`Failed to read file: ${Z instanceof Error?Z.message:String(Z)}`}}}async function O8($){try{let Y=await H6.readFile($.path,"utf-8"),Z=U8(Y,$.path,$.source);return Z.success?Z.content:null}catch{return null}}async function F8($){try{return await H6.access(K4.join($,"SKILL.md")),!0}catch{return!1}}var oG,sG,d5=1024;var H8=b(()=>{oG=/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/,sG=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]?$/});import*as W4 from"node:fs/promises";import{homedir as l5}from"node:os";import*as t0 from"node:path";class O4{skills=new Map;config;initialized=!1;constructor($){this.config={...$K,...$}}static getInstance($){if(!U4)U4=new O4($);return U4}static resetInstance(){U4=null}async initialize(){if(this.initialized)return{skills:Array.from(this.skills.values()),errors:[]};let $=[],Y=[];try{await G8(this.config.userSkillsDir).ensureDefaultSkillsInstalled()}catch(K){$.push({path:"SkillInstaller",error:`Failed to install default skills: ${K instanceof Error?K.message:"Unknown error"}`})}this.loadBuiltinSkills();let Z=await this.scanDirectory(this.config.claudeUserSkillsDir,"user");Y.push(...Z.skills),$.push(...Z.errors);let X=await this.scanDirectory(this.config.userSkillsDir,"user");Y.push(...X.skills),$.push(...X.errors);let Q=t0.isAbsolute(this.config.claudeProjectSkillsDir)?this.config.claudeProjectSkillsDir:t0.join(this.config.cwd,this.config.claudeProjectSkillsDir),J=await this.scanDirectory(Q,"project");Y.push(...J.skills),$.push(...J.errors);let q=t0.isAbsolute(this.config.projectSkillsDir)?this.config.projectSkillsDir:t0.join(this.config.cwd,this.config.projectSkillsDir),G=await this.scanDirectory(q,"project");Y.push(...G.skills),$.push(...G.errors);for(let K of Y)this.skills.set(K.name,K);return this.initialized=!0,{skills:Array.from(this.skills.values()),errors:$}}loadBuiltinSkills(){this.skills.set(G4.name,G4)}async scanDirectory($,Y){let Z=[],X=[];try{await W4.access($)}catch{return{skills:Z,errors:X}}try{let Q=await W4.readdir($,{withFileTypes:!0});for(let J of Q){if(!J.isDirectory())continue;let q=t0.join($,J.name),G=t0.join(q,"SKILL.md");if(!await F8(q))continue;let K=await W8(G,Y);if(K.success&&K.content)Z.push(K.content.metadata);else X.push({path:G,error:K.error||"Unknown error"})}}catch(Q){X.push({path:$,error:`Failed to scan directory: ${Q instanceof Error?Q.message:String(Q)}`})}return{skills:Z,errors:X}}getAll(){return Array.from(this.skills.values())}get($){return this.skills.get($)}has($){return this.skills.has($)}async loadContent($){let Y=this.skills.get($);if(!Y)return null;if(Y.source==="builtin")return this.loadBuiltinContent($);return O8(Y)}loadBuiltinContent($){switch($){case"skill-creator":return u5();default:return null}}getModelInvocableSkills(){return Array.from(this.skills.values()).filter(($)=>!$.disableModelInvocation)}getUserInvocableSkills(){return Array.from(this.skills.values()).filter(($)=>$.userInvocable===!0)}generateAvailableSkillsList(){let $=this.getModelInvocableSkills();if($.length===0)return"";let Y=[];for(let Z of $){let X=Z.description.length>100?`${Z.description.substring(0,97)}...`:Z.description,Q=Z.argumentHint?`${Z.name} ${Z.argumentHint}`:Z.name;Y.push(`- ${Q}: ${X}`)}return Y.join(`
377
- `)}get size(){return this.skills.size}async refresh(){return this.skills.clear(),this.initialized=!1,this.initialize()}}function $0($){return O4.getInstance($)}async function a2($){return $0($).initialize()}var $K,U4=null;var _8=b(()=>{m5();K8();H8();$K={userSkillsDir:t0.join(l5(),".blade","skills"),projectSkillsDir:".blade/skills",claudeUserSkillsDir:t0.join(l5(),".claude","skills"),claudeProjectSkillsDir:".claude/skills",cwd:process.cwd()}});function z8($){let Z=$0().generateAvailableSkillsList();if(!Z)return $;return $.map((X)=>{if(X.name!==YK)return X;let Q=X.description.replace(ZK,`<available_skills>
378
+ `}}var W4;var qY=b(()=>{W4={name:"skill-creator",description:"Create new Skills interactively. Use when the user wants to create a new Skill, define a custom workflow, or add a specialized capability to Blade.",allowedTools:["Read","Write","Glob","Bash","AskUserQuestion"],version:"1.0.0",argumentHint:void 0,userInvocable:!0,disableModelInvocation:!1,model:void 0,whenToUse:"User wants to create a new skill, define a custom workflow, or add a specialized capability.",path:"builtin://skill-creator",basePath:"",source:"builtin"}});import{exec as HG}from"node:child_process";import*as p1 from"node:fs/promises";import{homedir as zG}from"node:os";import*as d0 from"node:path";import{promisify as NG}from"node:util";class N9{skillsDir;constructor($){this.skillsDir=$||d0.join(zG(),".blade","skills")}async isInstalled($){let Y=d0.join(this.skillsDir,$,"SKILL.md");try{return await p1.access(Y),!0}catch{return!1}}async isGitAvailable(){try{return await F9("git --version"),!0}catch{return!1}}async installOfficialSkill($){let{url:Y,branch:Z}=H9,X=d0.join(this.skillsDir,$),Q=d0.join(this.skillsDir,`.tmp-${$}-${Date.now()}`);try{if(!await this.isGitAvailable())return $2.warn("Git not available, skipping skill installation"),!1;$2.info(`Installing official skill: ${$}...`),await p1.mkdir(this.skillsDir,{recursive:!0}),await F9(`git clone --depth 1 --branch ${Z} --single-branch ${Y} "${Q}"`,{timeout:30000});let J=d0.join(Q,"skills",$);try{await p1.access(J)}catch{return $2.warn(`Skill ${$} not found in official repository`),await p1.rm(Q,{recursive:!0,force:!0}),!1}try{await p1.rm(X,{recursive:!0,force:!0})}catch{}return await p1.cp(J,X,{recursive:!0}),await p1.rm(Q,{recursive:!0,force:!0}),$2.info(`Successfully installed: ${$}`),!0}catch(J){try{await p1.rm(Q,{recursive:!0,force:!0})}catch{}return $2.warn(`Failed to install ${$}: ${J instanceof Error?J.message:"Unknown error"}`),!1}}async ensureDefaultSkillsInstalled(){await p1.mkdir(this.skillsDir,{recursive:!0});for(let $ of H9.defaultSkills)if(!await this.isInstalled($))await this.installOfficialSkill($)}async installAllOfficialSkills(){let{url:$,branch:Y}=H9,Z=d0.join(this.skillsDir,`.tmp-all-${Date.now()}`),X=[],Q=[];try{if(!await this.isGitAvailable())return $2.warn("Git not available, skipping skill installation"),{installed:X,failed:Q};await p1.mkdir(this.skillsDir,{recursive:!0}),$2.info("Cloning official skills repository..."),await F9(`git clone --depth 1 --branch ${Y} --single-branch ${$} "${Z}"`,{timeout:60000});let J=d0.join(Z,"skills"),q=await p1.readdir(J,{withFileTypes:!0});for(let K of q){if(!K.isDirectory())continue;let G=K.name,U=d0.join(J,G),O=d0.join(this.skillsDir,G);try{await p1.access(d0.join(U,"SKILL.md")),await p1.rm(O,{recursive:!0,force:!0}),await p1.cp(U,O,{recursive:!0}),$2.info(`Installed: ${G}`),X.push(G)}catch(W){$2.warn(`Failed to install ${G}`),Q.push(G)}}await p1.rm(Z,{recursive:!0,force:!0})}catch(J){try{await p1.rm(Z,{recursive:!0,force:!0})}catch{}$2.warn(`Failed to install skills: ${J instanceof Error?J.message:"Unknown error"}`)}return{installed:X,failed:Q}}}function B9($){if(!z9)z9=new N9($);return z9}var F9,$2,H9,z9=null;var _9=b(()=>{w1();F9=NG(HG),$2=c("General"),H9={url:"https://github.com/anthropics/skills.git",branch:"main",defaultSkills:["skill-creator"]}});import*as B6 from"node:fs/promises";import*as O4 from"node:path";import{parse as BG}from"yaml";function wG($){if(!$)return;if(typeof $==="string")return $.split(",").map((Y)=>Y.trim()).filter(Boolean);if(Array.isArray($))return $.map((Y)=>String(Y).trim()).filter(Boolean);return}function GY($){if($===void 0)return;if(typeof $==="boolean")return $;if(typeof $==="string"){let Y=$.toLowerCase().trim();if(Y==="true"||Y==="yes"||Y==="1")return!0;if(Y==="false"||Y==="no"||Y==="0")return!1}return}function AG($,Y){if(!$.name)return{valid:!1,error:"Missing required field: name"};if(!LG.test($.name))return{valid:!1,error:`Invalid name "${$.name}": must be lowercase letters, numbers, and hyphens only, 1-64 characters`};if(!$.description)return{valid:!1,error:"Missing required field: description"};if($.description.length>KY)return{valid:!1,error:`Description too long: ${$.description.length} characters (max ${KY})`};let Z;if($.model)Z=$.model==="inherit"?"inherit":$.model;return{valid:!0,metadata:{name:$.name,description:$.description.trim(),allowedTools:wG($["allowed-tools"]),version:$.version,argumentHint:$["argument-hint"]?.trim(),userInvocable:GY($["user-invocable"]),disableModelInvocation:GY($["disable-model-invocation"]),model:Z,whenToUse:$.when_to_use?.trim()}}}function L9($,Y,Z){let X=$.match(_G);if(!X)return{success:!1,error:"Invalid SKILL.md format: missing YAML frontmatter (must start with ---)"};let[,Q,J]=X,q;try{q=BG(Q)}catch(U){return{success:!1,error:`Failed to parse YAML frontmatter: ${U instanceof Error?U.message:String(U)}`}}let K=AG(q,Y);if(!K.valid)return{success:!1,error:K.error};let G=O4.dirname(Y);return{success:!0,content:{metadata:{...K.metadata,path:Y,basePath:G,source:Z},instructions:J.trim()}}}async function w9($,Y){try{let Z=await B6.readFile($,"utf-8");return L9(Z,$,Y)}catch(Z){if(Z.code==="ENOENT")return{success:!1,error:`File not found: ${$}`};return{success:!1,error:`Failed to read file: ${Z instanceof Error?Z.message:String(Z)}`}}}async function A9($){try{let Y=await B6.readFile($.path,"utf-8"),Z=L9(Y,$.path,$.source);return Z.success?Z.content:null}catch{return null}}async function b9($){try{return await B6.access(O4.join($,"SKILL.md")),!0}catch{return!1}}var _G,LG,KY=1024;var R9=b(()=>{_G=/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/,LG=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]?$/});import*as H4 from"node:fs/promises";import{homedir as UY}from"node:os";import*as Y2 from"node:path";class z4{skills=new Map;config;initialized=!1;constructor($){this.config={...bG,...$}}static getInstance($){if(!F4)F4=new z4($);return F4}static resetInstance(){F4=null}async initialize(){if(this.initialized)return{skills:Array.from(this.skills.values()),errors:[]};let $=[],Y=[];try{await B9(this.config.userSkillsDir).ensureDefaultSkillsInstalled()}catch(G){$.push({path:"SkillInstaller",error:`Failed to install default skills: ${G instanceof Error?G.message:"Unknown error"}`})}this.loadBuiltinSkills();let Z=await this.scanDirectory(this.config.claudeUserSkillsDir,"user");Y.push(...Z.skills),$.push(...Z.errors);let X=await this.scanDirectory(this.config.userSkillsDir,"user");Y.push(...X.skills),$.push(...X.errors);let Q=Y2.isAbsolute(this.config.claudeProjectSkillsDir)?this.config.claudeProjectSkillsDir:Y2.join(this.config.cwd,this.config.claudeProjectSkillsDir),J=await this.scanDirectory(Q,"project");Y.push(...J.skills),$.push(...J.errors);let q=Y2.isAbsolute(this.config.projectSkillsDir)?this.config.projectSkillsDir:Y2.join(this.config.cwd,this.config.projectSkillsDir),K=await this.scanDirectory(q,"project");Y.push(...K.skills),$.push(...K.errors);for(let G of Y)this.skills.set(G.name,G);return this.initialized=!0,{skills:Array.from(this.skills.values()),errors:$}}loadBuiltinSkills(){this.skills.set(W4.name,W4)}async scanDirectory($,Y){let Z=[],X=[];try{await H4.access($)}catch{return{skills:Z,errors:X}}try{let Q=await H4.readdir($,{withFileTypes:!0});for(let J of Q){if(!J.isDirectory())continue;let q=Y2.join($,J.name),K=Y2.join(q,"SKILL.md");if(!await b9(q))continue;let G=await w9(K,Y);if(G.success&&G.content)Z.push(G.content.metadata);else X.push({path:K,error:G.error||"Unknown error"})}}catch(Q){X.push({path:$,error:`Failed to scan directory: ${Q instanceof Error?Q.message:String(Q)}`})}return{skills:Z,errors:X}}getAll(){return Array.from(this.skills.values())}get($){return this.skills.get($)}has($){return this.skills.has($)}async loadContent($){let Y=this.skills.get($);if(!Y)return null;if(Y.source==="builtin")return this.loadBuiltinContent($);return A9(Y)}loadBuiltinContent($){switch($){case"skill-creator":return JY();default:return null}}getModelInvocableSkills(){return Array.from(this.skills.values()).filter(($)=>!$.disableModelInvocation)}getUserInvocableSkills(){return Array.from(this.skills.values()).filter(($)=>$.userInvocable===!0)}generateAvailableSkillsList(){let $=this.getModelInvocableSkills();if($.length===0)return"";let Y=[];for(let Z of $){let X=Z.description.length>100?`${Z.description.substring(0,97)}...`:Z.description,Q=Z.argumentHint?`${Z.name} ${Z.argumentHint}`:Z.name;Y.push(`- ${Q}: ${X}`)}return Y.join(`
379
+ `)}get size(){return this.skills.size}async refresh(){return this.skills.clear(),this.initialized=!1,this.initialize()}}function X0($){return z4.getInstance($)}async function o2($){return X0($).initialize()}var bG,F4=null;var V9=b(()=>{qY();_9();R9();bG={userSkillsDir:Y2.join(UY(),".blade","skills"),projectSkillsDir:".blade/skills",claudeUserSkillsDir:Y2.join(UY(),".claude","skills"),claudeProjectSkillsDir:".claude/skills",cwd:process.cwd()}});function D9($){let Z=X0().generateAvailableSkillsList();if(!Z)return $;return $.map((X)=>{if(X.name!==RG)return X;let Q=X.description.replace(VG,`<available_skills>
378
380
  ${Z}
379
- </available_skills>`);if(Q===X.description)return X;return{...X,description:Q}})}var YK="Skill",ZK;var i5=b(()=>{_8();ZK=/<available_skills>\s*<\/available_skills>/});var j2=b(()=>{_8();H8();i5();K8()});import{execSync as XK}from"child_process";import*as V$ from"os";import*as R$ from"path";function QK(){let $=process.cwd(),Y=JK($);return{workingDirectory:$,projectRoot:Y,platform:`${V$.platform()} (${V$.arch()})`,nodeVersion:process.version,currentDate:new Date().toISOString().split("T")[0],homeDirectory:V$.homedir()}}function F4(){let $=QK();return`# Environment Context
381
+ </available_skills>`);if(Q===X.description)return X;return{...X,description:Q}})}var RG="Skill",VG;var WY=b(()=>{V9();VG=/<available_skills>\s*<\/available_skills>/});var v2=b(()=>{V9();R9();WY();_9()});import{execSync as DG}from"child_process";import*as M$ from"os";import*as I$ from"path";function IG(){let $=process.cwd(),Y=MG($);return{workingDirectory:$,projectRoot:Y,platform:`${M$.platform()} (${M$.arch()})`,nodeVersion:process.version,currentDate:new Date().toISOString().split("T")[0],homeDirectory:M$.homedir()}}function N4(){let $=IG();return`# Environment Context
380
382
 
381
383
  ## Working Directory
382
384
  **Current**: \`${$.workingDirectory}\`
@@ -394,9 +396,9 @@ When using file tools (read, write, edit), provide **absolute paths**:
394
396
  - ❌ Incorrect: \`/package.json\` (root directory)
395
397
  - ❌ Incorrect: \`package.json\` (relative path without context)
396
398
 
397
- **Always use** \`${$.workingDirectory}/\` as the base for file paths.`}function JK($){let Y=$;while(Y!==R$.dirname(Y)){if(a5(R$.join(Y,".git")))return Y;if(a5(R$.join(Y,"package.json")))return Y;Y=R$.dirname(Y)}return $}function a5($){try{return XK(`test -e "${$}"`,{stdio:"ignore"}),!0}catch{return!1}}var N8=()=>{};function _6($){return`<system-reminder>Plan mode is active. You MUST NOT make any file changes or run non-readonly tools. Research only, then call ExitPlanMode with your plan.</system-reminder>
399
+ **Always use** \`${$.workingDirectory}/\` as the base for file paths.`}function MG($){let Y=$;while(Y!==I$.dirname(Y)){if(OY(I$.join(Y,".git")))return Y;if(OY(I$.join(Y,"package.json")))return Y;Y=I$.dirname(Y)}return $}function OY($){try{return DG(`test -e "${$}"`,{stdio:"ignore"}),!0}catch{return!1}}var I9=()=>{};function _6($){return`<system-reminder>Plan mode is active. You MUST NOT make any file changes or run non-readonly tools. Research only, then call ExitPlanMode with your plan.</system-reminder>
398
400
 
399
- `+$}var B8=`You are Blade Code, an interactive CLI tool that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.
401
+ `+$}var M9=`You are Blade Code, an interactive CLI tool that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.
400
402
 
401
403
  IMPORTANT: Assist with authorized security testing, defensive security, CTF challenges, and educational contexts. Refuse requests for destructive techniques, DoS attacks, mass targeting, supply chain compromise, or detection evasion for malicious purposes. Dual-use security tools (C2 frameworks, credential testing, exploit development) require clear authorization context: pentesting engagements, CTF competitions, security research, or defensive use cases.
402
404
  IMPORTANT: You must NEVER generate or guess URLs for the user unless you are confident that the URLs are for helping the user with programming. You may use URLs provided by the user in their messages or local files.
@@ -554,7 +556,7 @@ assistant: Clients are marked as failed in the \`connectToServer\` function in s
554
556
  </example>
555
557
 
556
558
  # Language Requirement
557
- IMPORTANT: Always respond in Chinese (Simplified Chinese). Translate all your responses to Chinese before sending them to the user.`,L8=`You are in **PLAN MODE** - a read-only research phase for designing implementation plans.
559
+ IMPORTANT: Always respond in Chinese (Simplified Chinese). Translate all your responses to Chinese before sending them to the user.`,j9=`You are in **PLAN MODE** - a read-only research phase for designing implementation plans.
558
560
 
559
561
  ## Core Objective
560
562
 
@@ -594,77 +596,77 @@ Your plan should include:
594
596
  3. **Steps** - Detailed implementation steps with file paths
595
597
  4. **Testing** - How to verify changes
596
598
  5. **Risks** - Potential issues and mitigations
597
- `;var w8=()=>{};import{promises as r5}from"fs";import qK from"path";async function H4($={}){let{projectPath:Y,replaceDefault:Z,append:X,mode:Q,includeEnvironment:J=!0}=$,q=[],G=[];if(J){let U=F4();if(U)q.push(U),G.push({name:"environment",loaded:!0,length:U.length})}let K=Q==="plan",W=K?L8:Z??B8;if(q.push(W),G.push({name:K?"plan_mode_prompt":Z?"replace_default":"default",loaded:!0,length:W.length}),Y){let U=await UK(Y);if(U)q.push(U),G.push({name:"blade_md",loaded:!0,length:U.length});else G.push({name:"blade_md",loaded:!1})}if(X?.trim())q.push(X.trim()),G.push({name:"append",loaded:!0,length:X.trim().length});let O=q.join(`
599
+ `;var y9=()=>{};import{promises as FY}from"fs";import jG from"path";async function B4($={}){let{projectPath:Y,replaceDefault:Z,append:X,mode:Q,includeEnvironment:J=!0}=$,q=[],K=[];if(J){let W=N4();if(W)q.push(W),K.push({name:"environment",loaded:!0,length:W.length})}let G=Q==="plan",U=G?j9:Z??M9;if(q.push(U),K.push({name:G?"plan_mode_prompt":Z?"replace_default":"default",loaded:!0,length:U.length}),Y){let W=await vG(Y);if(W)q.push(W),K.push({name:"blade_md",loaded:!0,length:W.length});else K.push({name:"blade_md",loaded:!1})}if(X?.trim())q.push(X.trim()),K.push({name:"append",loaded:!0,length:X.trim().length});let O=q.join(`
598
600
 
599
601
  ---
600
602
 
601
- `);return O=KK(O),{prompt:O,sources:G}}function KK($){let Z=$0().generateAvailableSkillsList();if(!Z)return $;return $.replace(GK,`<available_skills>
603
+ `);return O=EG(O),{prompt:O,sources:K}}function EG($){let Z=X0().generateAvailableSkillsList();if(!Z)return $;return $.replace(yG,`<available_skills>
602
604
  ${Z}
603
- </available_skills>`)}async function UK($){let Y=qK.join($,"BLADE.md");try{return(await r5.readFile(Y,"utf-8")).trim()||null}catch{return null}}var GK;var n5=b(()=>{s1();j2();N8();w8();GK=/<available_skills>\s*<\/available_skills>/});var o5=b(()=>{n5();w8()});import*as _4 from"fs/promises";import*as U0 from"path";class z4{static normalize($,Y){let Z=U0.isAbsolute($)?$:U0.resolve(Y,$),X=U0.normalize(Z),Q=U0.normalize(Y);if(!X.startsWith(Q))throw new r2(`Path outside workspace: ${$} (resolved to ${X}, workspace: ${Q})`,"PATH_OUTSIDE_WORKSPACE");return X}static checkRestricted($){let Y=$.split(U0.sep);for(let Z of s5)if(Y.includes(Z))throw new r2(`Access denied: "${Z}" is a protected directory`,"RESTRICTED_PATH")}static checkTraversal($){if($.includes(".."))throw new r2(`Path traversal not allowed: ${$}`,"PATH_TRAVERSAL")}static async validatePath($,Y){this.checkTraversal($);let Z=this.normalize($,Y);this.checkRestricted(Z);try{await _4.access(Z)}catch(X){throw new r2(`Path not found: ${$}`,"PATH_NOT_FOUND")}return Z}static async resolveSymlink($,Y){try{let Z=await _4.realpath($),X=U0.normalize(Y);if(!Z.startsWith(X))throw new r2(`Symlink points outside workspace: ${$} -> ${Z}`,"SYMLINK_OUTSIDE_WORKSPACE");return Z}catch(Z){if(Z instanceof r2)throw Z;return $}}static getRelativePath($,Y){return U0.relative(Y,$)}static isWithinWorkspace($,Y){let Z=U0.normalize($),X=U0.normalize(Y);return Z.startsWith(X)}static isRestricted($){let Y=$.split(U0.sep);return s5.some((Z)=>Y.includes(Z))}}var s5,r2;var t5=b(()=>{s5=[".git",".claude","node_modules",".env",".env.local",".env.production",".env.development",".env.test"];r2=class r2 extends Error{code;constructor($,Y){super($);this.code=Y;this.name="PathSecurityError"}}});var N4;var e5=b(()=>{N4=class N4{static PATTERN=/@"([^"]+)"|@([^\s]+)/g;static LINE_RANGE_PATTERN=/#L(\d+)(?:-(\d+))?$/;static GLOB_PATTERN=/[*?[\]]/;static extract($){let Y=[],Z;this.PATTERN.lastIndex=0;while((Z=this.PATTERN.exec($))!==null){let X=Z[0],Q=Z[1]||Z[2],J=this.parseLineRange(Q);if(J)Q=Q.replace(this.LINE_RANGE_PATTERN,"");let q=this.GLOB_PATTERN.test(Q);Y.push({raw:X,path:Q.trim(),lineRange:J,startIndex:Z.index,endIndex:Z.index+X.length,isGlob:q})}return Y}static parseLineRange($){let Y=$.match(this.LINE_RANGE_PATTERN);if(!Y)return;let Z=parseInt(Y[1],10),X=Y[2]?parseInt(Y[2],10):void 0;return{start:Z,end:X}}static hasAtMentions($){return $.includes("@")}static isValidPath($){if(!$||$.trim().length===0)return!1;let Y=["<",">","|","\x00"];for(let Z of Y)if($.includes(Z))return!1;return!0}static removeAtMentions($){return this.PATTERN.lastIndex=0,$.replace(this.PATTERN,"")}}});import $Y from"fast-glob";import*as D$ from"fs/promises";import*as YY from"path";class A8{fileCache=new Map;options;constructor($){this.options={maxFileSize:1048576,maxLines:2000,maxTokens:32000,...$},g0.debug("AttachmentCollector initialized",{maxFileSize:this.options.maxFileSize,maxLines:this.options.maxLines})}async collect($){if(!N4.hasAtMentions($))return[];let Y=N4.extract($);if(Y.length===0)return[];g0.debug(`Found ${Y.length} @ mentions`);let Z=Y.map((Q)=>this.processOne(Q));return(await Promise.allSettled(Z)).map((Q,J)=>{if(Q.status==="fulfilled")return Q.value;else{let q=Y[J],G=Q.reason instanceof Error?Q.reason.message:String(Q.reason);return g0.warn(`Failed to process @${q.path}:`,G),{type:"error",path:q.path,content:"",error:G}}})}async processOne($){if($.isGlob)return g0.debug(`Processing glob pattern: ${$.path}`),await this.processGlob($.path);let Y=await z4.validatePath($.path,this.options.cwd),Z=await z4.resolveSymlink(Y,this.options.cwd);if((await D$.stat(Z)).isDirectory())return g0.debug(`Processing directory: ${$.path}`),await this.renderDirectoryTree(Z,$.path);return g0.debug(`Processing file: ${$.path}`,{lineRange:$.lineRange}),await this.readFile(Z,$.path,$.lineRange)}async readFile($,Y,Z){let X=this.fileCache.get($);if(X&&Date.now()-X.timestamp<60000)return g0.debug(`Cache hit: ${Y}`),this.formatFileAttachment(Y,X.content,Z);let Q=await D$.stat($);if(Q.size>this.options.maxFileSize)throw Error(`File too large: ${Math.round(Q.size/1024/1024)}MB (max ${Math.round(this.options.maxFileSize/1024/1024)}MB)`);let J;try{J=await D$.readFile($,"utf-8")}catch(q){throw Error(`Cannot read file as text: ${Y}. It may be a binary file.`)}return this.fileCache.set($,{content:J,timestamp:Date.now()}),this.formatFileAttachment(Y,J,Z)}formatFileAttachment($,Y,Z){let X=Y.split(`
604
- `),Q=Y,J=!1,q=Z;if(Z){let G=Math.max(0,Z.start-1),K=Z.end?Z.end:Z.start;if(G>=X.length)throw Error(`Line range start (${Z.start}) exceeds file length (${X.length} lines)`);let W=Math.min(K,X.length);Q=X.slice(G,W).join(`
605
- `);let O=Array.from({length:W-G},(F,H)=>G+H+1);Q=Q.split(`
605
+ </available_skills>`)}async function vG($){let Y=jG.join($,"BLADE.md");try{return(await FY.readFile(Y,"utf-8")).trim()||null}catch{return null}}var yG;var HY=b(()=>{$0();v2();I9();y9();yG=/<available_skills>\s*<\/available_skills>/});var zY=b(()=>{HY();y9()});import*as _4 from"fs/promises";import*as F0 from"path";class L4{static normalize($,Y){let Z=F0.isAbsolute($)?$:F0.resolve(Y,$),X=F0.normalize(Z),Q=F0.normalize(Y);if(!X.startsWith(Q))throw new s2(`Path outside workspace: ${$} (resolved to ${X}, workspace: ${Q})`,"PATH_OUTSIDE_WORKSPACE");return X}static checkRestricted($){let Y=$.split(F0.sep);for(let Z of NY)if(Y.includes(Z))throw new s2(`Access denied: "${Z}" is a protected directory`,"RESTRICTED_PATH")}static checkTraversal($){if($.includes(".."))throw new s2(`Path traversal not allowed: ${$}`,"PATH_TRAVERSAL")}static async validatePath($,Y){this.checkTraversal($);let Z=this.normalize($,Y);this.checkRestricted(Z);try{await _4.access(Z)}catch(X){throw new s2(`Path not found: ${$}`,"PATH_NOT_FOUND")}return Z}static async resolveSymlink($,Y){try{let Z=await _4.realpath($),X=F0.normalize(Y);if(!Z.startsWith(X))throw new s2(`Symlink points outside workspace: ${$} -> ${Z}`,"SYMLINK_OUTSIDE_WORKSPACE");return Z}catch(Z){if(Z instanceof s2)throw Z;return $}}static getRelativePath($,Y){return F0.relative(Y,$)}static isWithinWorkspace($,Y){let Z=F0.normalize($),X=F0.normalize(Y);return Z.startsWith(X)}static isRestricted($){let Y=$.split(F0.sep);return NY.some((Z)=>Y.includes(Z))}}var NY,s2;var BY=b(()=>{NY=[".git",".claude","node_modules",".env",".env.local",".env.production",".env.development",".env.test"];s2=class s2 extends Error{code;constructor($,Y){super($);this.code=Y;this.name="PathSecurityError"}}});var w4;var _Y=b(()=>{w4=class w4{static PATTERN=/@"([^"]+)"|@([^\s]+)/g;static LINE_RANGE_PATTERN=/#L(\d+)(?:-(\d+))?$/;static GLOB_PATTERN=/[*?[\]]/;static extract($){let Y=[],Z;this.PATTERN.lastIndex=0;while((Z=this.PATTERN.exec($))!==null){let X=Z[0],Q=Z[1]||Z[2],J=this.parseLineRange(Q);if(J)Q=Q.replace(this.LINE_RANGE_PATTERN,"");let q=this.GLOB_PATTERN.test(Q);Y.push({raw:X,path:Q.trim(),lineRange:J,startIndex:Z.index,endIndex:Z.index+X.length,isGlob:q})}return Y}static parseLineRange($){let Y=$.match(this.LINE_RANGE_PATTERN);if(!Y)return;let Z=parseInt(Y[1],10),X=Y[2]?parseInt(Y[2],10):void 0;return{start:Z,end:X}}static hasAtMentions($){return $.includes("@")}static isValidPath($){if(!$||$.trim().length===0)return!1;let Y=["<",">","|","\x00"];for(let Z of Y)if($.includes(Z))return!1;return!0}static removeAtMentions($){return this.PATTERN.lastIndex=0,$.replace(this.PATTERN,"")}}});import LY from"fast-glob";import*as j$ from"fs/promises";import*as wY from"path";class E9{fileCache=new Map;options;constructor($){this.options={maxFileSize:1048576,maxLines:2000,maxTokens:32000,...$},m0.debug("AttachmentCollector initialized",{maxFileSize:this.options.maxFileSize,maxLines:this.options.maxLines})}async collect($){if(!w4.hasAtMentions($))return[];let Y=w4.extract($);if(Y.length===0)return[];m0.debug(`Found ${Y.length} @ mentions`);let Z=Y.map((Q)=>this.processOne(Q));return(await Promise.allSettled(Z)).map((Q,J)=>{if(Q.status==="fulfilled")return Q.value;else{let q=Y[J],K=Q.reason instanceof Error?Q.reason.message:String(Q.reason);return m0.warn(`Failed to process @${q.path}:`,K),{type:"error",path:q.path,content:"",error:K}}})}async processOne($){if($.isGlob)return m0.debug(`Processing glob pattern: ${$.path}`),await this.processGlob($.path);let Y=await L4.validatePath($.path,this.options.cwd),Z=await L4.resolveSymlink(Y,this.options.cwd);if((await j$.stat(Z)).isDirectory())return m0.debug(`Processing directory: ${$.path}`),await this.renderDirectoryTree(Z,$.path);return m0.debug(`Processing file: ${$.path}`,{lineRange:$.lineRange}),await this.readFile(Z,$.path,$.lineRange)}async readFile($,Y,Z){let X=this.fileCache.get($);if(X&&Date.now()-X.timestamp<60000)return m0.debug(`Cache hit: ${Y}`),this.formatFileAttachment(Y,X.content,Z);let Q=await j$.stat($);if(Q.size>this.options.maxFileSize)throw Error(`File too large: ${Math.round(Q.size/1024/1024)}MB (max ${Math.round(this.options.maxFileSize/1024/1024)}MB)`);let J;try{J=await j$.readFile($,"utf-8")}catch(q){throw Error(`Cannot read file as text: ${Y}. It may be a binary file.`)}return this.fileCache.set($,{content:J,timestamp:Date.now()}),this.formatFileAttachment(Y,J,Z)}formatFileAttachment($,Y,Z){let X=Y.split(`
606
+ `),Q=Y,J=!1,q=Z;if(Z){let K=Math.max(0,Z.start-1),G=Z.end?Z.end:Z.start;if(K>=X.length)throw Error(`Line range start (${Z.start}) exceeds file length (${X.length} lines)`);let U=Math.min(G,X.length);Q=X.slice(K,U).join(`
607
+ `);let O=Array.from({length:U-K},(F,H)=>K+H+1);Q=Q.split(`
606
608
  `).map((F,H)=>`${O[H]}: ${F}`).join(`
607
- `),q={start:Z.start,end:W}}else if(X.length>this.options.maxLines)Q=X.slice(0,this.options.maxLines).join(`
609
+ `),q={start:Z.start,end:U}}else if(X.length>this.options.maxLines)Q=X.slice(0,this.options.maxLines).join(`
608
610
  `),Q+=`
609
611
 
610
- [... truncated ${X.length-this.options.maxLines} lines ...]`,J=!0;return{type:"file",path:$,content:Q,metadata:{size:Y.length,lines:X.length,truncated:J,lineRange:q}}}async renderDirectoryTree($,Y){let Z=await $Y("**/*",{cwd:$,dot:!1,followSymbolicLinks:!1,onlyFiles:!0,unique:!0,ignore:["node_modules/**",".git/**","dist/**","build/**",".next/**",".cache/**","coverage/**"]});if(Z.length===0)return{type:"directory",path:Y,content:"(empty directory)"};g0.debug(`Found ${Z.length} files in directory: ${Y}`);let X=this.buildFileTree(Z),Q=this.printTree(X,Y),J=500,q=Z.length>J?`
612
+ [... truncated ${X.length-this.options.maxLines} lines ...]`,J=!0;return{type:"file",path:$,content:Q,metadata:{size:Y.length,lines:X.length,truncated:J,lineRange:q}}}async renderDirectoryTree($,Y){let Z=await LY("**/*",{cwd:$,dot:!1,followSymbolicLinks:!1,onlyFiles:!0,unique:!0,ignore:["node_modules/**",".git/**","dist/**","build/**",".next/**",".cache/**","coverage/**"]});if(Z.length===0)return{type:"directory",path:Y,content:"(empty directory)"};m0.debug(`Found ${Z.length} files in directory: ${Y}`);let X=this.buildFileTree(Z),Q=this.printTree(X,Y),J=500,q=Z.length>J?`
611
613
 
612
- [... and ${Z.length-J} more files]`:"";return{type:"directory",path:Y,content:Q+q,metadata:{lines:Z.length,truncated:Z.length>J}}}buildFileTree($){let Y=new Map;for(let Z of $){let X=Z.split("/"),Q=Y;for(let J=0;J<X.length;J++){let q=X[J],G=J===X.length-1;if(!Q.has(q))Q.set(q,G?null:new Map);if(!G)Q=Q.get(q)}}return Y}printTree($,Y,Z="",X=!0){let Q=[];if(Z==="")Q.push(`${Y}/`);let J=Array.from($.entries()).sort((q,G)=>{let K=q[1]instanceof Map,W=G[1]instanceof Map;if(K!==W)return W?1:-1;return q[0].localeCompare(G[0])});return J.forEach(([q,G],K)=>{let W=K===J.length-1,O=W?"└── ":"├── ",U=G instanceof Map;if(Q.push(`${Z}${O}${q}${U?"/":""}`),U&&G.size>0){let F=Z+(W?" ":"│ ");Q.push(this.printTree(G,"",F,W))}}),Q.filter((q)=>q).join(`
613
- `)}async processGlob($){let Y=await $Y($,{cwd:this.options.cwd,dot:!1,followSymbolicLinks:!1,onlyFiles:!0,unique:!0,ignore:["node_modules/**",".git/**","dist/**","build/**",".next/**",".cache/**","coverage/**"]});if(Y.length===0)return{type:"error",path:$,content:"",error:`No files matched pattern: ${$}`};g0.debug(`Glob pattern "${$}" matched ${Y.length} files`);let Z=30,X=Y.slice(0,Z),J=(await Promise.allSettled(X.map(async(W)=>{let O=YY.join(this.options.cwd,W);try{let U=await D$.readFile(O,"utf-8"),F=U.split(`
614
- `),H=200,_=U,z=!1;if(F.length>200)_=F.slice(0,200).join(`
615
- `),_+=`
614
+ [... and ${Z.length-J} more files]`:"";return{type:"directory",path:Y,content:Q+q,metadata:{lines:Z.length,truncated:Z.length>J}}}buildFileTree($){let Y=new Map;for(let Z of $){let X=Z.split("/"),Q=Y;for(let J=0;J<X.length;J++){let q=X[J],K=J===X.length-1;if(!Q.has(q))Q.set(q,K?null:new Map);if(!K)Q=Q.get(q)}}return Y}printTree($,Y,Z="",X=!0){let Q=[];if(Z==="")Q.push(`${Y}/`);let J=Array.from($.entries()).sort((q,K)=>{let G=q[1]instanceof Map,U=K[1]instanceof Map;if(G!==U)return U?1:-1;return q[0].localeCompare(K[0])});return J.forEach(([q,K],G)=>{let U=G===J.length-1,O=U?"└── ":"├── ",W=K instanceof Map;if(Q.push(`${Z}${O}${q}${W?"/":""}`),W&&K.size>0){let F=Z+(U?" ":"│ ");Q.push(this.printTree(K,"",F,U))}}),Q.filter((q)=>q).join(`
615
+ `)}async processGlob($){let Y=await LY($,{cwd:this.options.cwd,dot:!1,followSymbolicLinks:!1,onlyFiles:!0,unique:!0,ignore:["node_modules/**",".git/**","dist/**","build/**",".next/**",".cache/**","coverage/**"]});if(Y.length===0)return{type:"error",path:$,content:"",error:`No files matched pattern: ${$}`};m0.debug(`Glob pattern "${$}" matched ${Y.length} files`);let Z=30,X=Y.slice(0,Z),J=(await Promise.allSettled(X.map(async(U)=>{let O=wY.join(this.options.cwd,U);try{let W=await j$.readFile(O,"utf-8"),F=W.split(`
616
+ `),H=200,z=W,N=!1;if(F.length>200)z=F.slice(0,200).join(`
617
+ `),z+=`
616
618
 
617
- [... truncated ${F.length-200} lines ...]`,z=!0;return{path:W,content:_,lines:F.length,truncated:z}}catch(U){return{path:W,content:`[Error: ${U instanceof Error?U.message:"unknown error"}]`,lines:0,truncated:!1}}}))).map((W)=>W.status==="fulfilled"?W.value:null).filter((W)=>W!==null),G=J.map((W)=>`--- ${W.path} (${W.lines} lines${W.truncated?", truncated":""}) ---
618
- ${W.content}`).join(`
619
+ [... truncated ${F.length-200} lines ...]`,N=!0;return{path:U,content:z,lines:F.length,truncated:N}}catch(W){return{path:U,content:`[Error: ${W instanceof Error?W.message:"unknown error"}]`,lines:0,truncated:!1}}}))).map((U)=>U.status==="fulfilled"?U.value:null).filter((U)=>U!==null),K=J.map((U)=>`--- ${U.path} (${U.lines} lines${U.truncated?", truncated":""}) ---
620
+ ${U.content}`).join(`
619
621
 
620
- `),K=Y.length>Z?`
622
+ `),G=Y.length>Z?`
621
623
 
622
- [... and ${Y.length-Z} more files matched]`:"";return{type:"file",path:$,content:G+K,metadata:{lines:J.reduce((W,O)=>W+O.lines,0),truncated:Y.length>Z||J.some((W)=>W.truncated)}}}clearExpiredCache(){let $=Date.now(),Y=0;for(let[Z,X]of this.fileCache.entries())if($-X.timestamp>60000)this.fileCache.delete(Z),Y++;if(Y>0)g0.debug(`Cleared ${Y} expired cache entries`)}clearCache(){this.fileCache.clear(),g0.debug("Cleared all cache")}getCacheStats(){return{size:this.fileCache.size,keys:Array.from(this.fileCache.keys())}}}var g0;var ZY=b(()=>{V1();t5();e5();g0=n("Prompts")});import*as u0 from"fs/promises";class y2{async readTextFile($){return u0.readFile($,"utf-8")}async writeTextFile($,Y){await u0.writeFile($,Y,"utf-8")}async exists($){try{return await u0.access($),!0}catch{return!1}}async readBinaryFile($){return u0.readFile($)}async stat($){try{let Y=await u0.stat($);return{size:Y.size,isDirectory:Y.isDirectory(),isFile:Y.isFile(),mtime:Y.mtime}}catch{return null}}async mkdir($,Y){await u0.mkdir($,{recursive:Y?.recursive??!1})}}function I$(){return b8}function B4($){b8=$}function XY(){b8=new y2}var b8;var M$=b(()=>{b8=new y2});class R8{connection;sessionId;capabilities;fallback;constructor($,Y,Z,X=new y2){this.connection=$;this.sessionId=Y;this.capabilities=Z;this.fallback=X}async readTextFile($){if(!this.capabilities.readTextFile)return N0.debug(`[AcpFileSystem] readTextFile fallback: ${$}`),this.fallback.readTextFile($);try{return N0.debug(`[AcpFileSystem] readTextFile via ACP: ${$}`),(await this.connection.readTextFile({path:$,sessionId:this.sessionId})).content}catch(Y){return N0.warn(`[AcpFileSystem] readTextFile ACP failed, fallback: ${Y}`),this.fallback.readTextFile($)}}async writeTextFile($,Y){if(!this.capabilities.writeTextFile)return N0.debug(`[AcpFileSystem] writeTextFile fallback: ${$}`),this.fallback.writeTextFile($,Y);try{N0.debug(`[AcpFileSystem] writeTextFile via ACP: ${$}`),await this.connection.writeTextFile({path:$,content:Y,sessionId:this.sessionId})}catch(Z){return N0.warn(`[AcpFileSystem] writeTextFile ACP failed, fallback: ${Z}`),this.fallback.writeTextFile($,Y)}}async exists($){if(!this.capabilities.readTextFile)return N0.debug(`[AcpFileSystem] exists fallback to local: ${$}`),this.fallback.exists($);try{return await this.connection.readTextFile({path:$,sessionId:this.sessionId}),N0.debug(`[AcpFileSystem] exists(${$}): true (ACP read success)`),!0}catch(Y){let Z=String(Y).toLowerCase();if(["not found","no such file","enoent","does not exist","file not found","path not found"].some((q)=>Z.includes(q)))return N0.debug(`[AcpFileSystem] exists(${$}): false (ACP: not found)`),!1;let J=WK(Z);return N0.warn(`[AcpFileSystem] exists(${$}): assuming exists due to ${J} error`,{error:String(Y),errorType:J,filePath:$}),!0}}async readBinaryFile($){return N0.debug(`[AcpFileSystem] readBinaryFile fallback: ${$}`),this.fallback.readBinaryFile($)}async stat($){return N0.debug(`[AcpFileSystem] stat fallback: ${$}`),this.fallback.stat($)}async mkdir($,Y){return N0.debug(`[AcpFileSystem] mkdir fallback: ${$}`),this.fallback.mkdir($,Y)}getCapabilities(){return this.capabilities}canReadTextFile(){return this.capabilities.readTextFile??!1}canWriteTextFile(){return this.capabilities.writeTextFile??!1}}function WK($){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 N0;var QY=b(()=>{V1();M$();N0=n("Agent")});import{spawn as OK}from"child_process";class V8{async execute($,Y){return new Promise((Z)=>{let X=process.platform==="win32"?"cmd.exe":"/bin/bash",Q=process.platform==="win32"?["/c",$]:["-c",$],J=OK(X,Q,{cwd:Y?.cwd||process.cwd(),env:{...process.env,...Y?.env},stdio:["pipe","pipe","pipe"]}),q="",G="",K=!1,W=Y?.timeout?setTimeout(()=>{K=!0,J.kill("SIGTERM")},Y.timeout):null,O=null,U=()=>{if(W)clearTimeout(W);if(O&&Y?.signal)Y.signal.removeEventListener("abort",O),O=null};if(Y?.signal)O=()=>{K=!0,J.kill("SIGTERM")},Y.signal.addEventListener("abort",O);J.stdout.on("data",(F)=>{let H=F.toString();q+=H,Y?.onOutput?.(H)}),J.stderr.on("data",(F)=>{let H=F.toString();G+=H,Y?.onOutput?.(H)}),J.on("close",(F)=>{U(),Z({success:F===0&&!K,stdout:q,stderr:G,exitCode:F,error:K?"Command was terminated":void 0})}),J.on("error",(F)=>{U(),Z({success:!1,stdout:q,stderr:G,exitCode:null,error:F.message})})})}isAvailable(){return!0}}class JY{connection;sessionId;fallback;constructor($,Y,Z=new V8){this.connection=$;this.sessionId=Y;this.fallback=Z}async execute($,Y){try{e0.debug(`[AcpTerminal] Executing command via ACP: ${$}`);let Z=await this.connection.createTerminal({sessionId:this.sessionId,command:$,cwd:Y?.cwd,env:Y?.env?Object.entries(Y.env).map(([W,O])=>({name:W,value:O})):void 0}),X=0,Q=null;if(Y?.onOutput)Q=setInterval(async()=>{try{let O=(await Z.currentOutput()).output||"";if(O.length>X){let U=O.slice(X);X=O.length,Y.onOutput?.(U)}}catch{}},100);let J=(W=!1)=>{if(Q)clearInterval(Q),Q=null;(W?Z.kill().then(()=>e0.debug("[AcpTerminal] Killed remote command")).catch(()=>{}).then(()=>Z.release()).catch(()=>{}):Z.release().catch(()=>{})).catch(()=>{})},q=[];if(q.push(Z.waitForExit().then((W)=>({type:"completed",exitCode:W.exitCode??null}))),Y?.timeout)q.push(new Promise((W)=>{setTimeout(()=>W({type:"timeout"}),Y.timeout)}));if(Y?.signal)q.push(new Promise((W)=>{if(Y.signal.aborted)W({type:"aborted"});else Y.signal.addEventListener("abort",()=>W({type:"aborted"}),{once:!0})}));let G=await Promise.race(q),K="";try{if(K=(await Z.currentOutput()).output||"",Y?.onOutput&&K.length>X)Y.onOutput(K.slice(X))}catch{}switch(G.type){case"completed":return J(!1),{success:G.exitCode===0,stdout:K,stderr:"",exitCode:G.exitCode};case"timeout":return e0.debug(`[AcpTerminal] Command timed out, killing: ${$}`),J(!0),{success:!1,stdout:K,stderr:"",exitCode:null,error:"Command timed out"};case"aborted":return e0.debug(`[AcpTerminal] Command aborted, killing: ${$}`),J(!0),{success:!1,stdout:K,stderr:"",exitCode:null,error:"Command was aborted"}}}catch(Z){return e0.warn("[AcpTerminal] ACP terminal failed, using fallback:",Z),this.fallback.execute($,Y)}}isAvailable(){return!0}}function qY(){return X1.getInstance().getTerminalService()}function v2(){return X1.getInstance().isAcpMode()}var e0,X1;var j$=b(()=>{V1();M$();QY();e0=n("Agent");X1=class X1{static sessions=new Map;static currentSessionId=null;constructor(){}static getInstance(){return new X1}static initializeSession($,Y,Z,X){let Q=Z?.fs?new R8($,Y,Z.fs):new y2;if(Z?.fs)e0.debug(`[AcpServiceContext:${Y}] Using ACP file system service`);let J=new JY($,Y);e0.debug(`[AcpServiceContext:${Y}] Using ACP terminal service`),X1.sessions.set(Y,{fileSystemService:Q,terminalService:J,connection:$,clientCapabilities:Z||null,cwd:X}),X1.currentSessionId=Y,B4(Q),e0.debug(`[AcpServiceContext:${Y}] Initialized with capabilities:`,{fs:!!Z?.fs,readTextFile:Z?.fs?.readTextFile,writeTextFile:Z?.fs?.writeTextFile,cwd:X})}static destroySession($){if(X1.sessions.delete($),X1.currentSessionId===$){let Y=Array.from(X1.sessions.keys());if(X1.currentSessionId=Y[0]||null,!X1.currentSessionId)XY();else{let Z=X1.sessions.get(X1.currentSessionId);if(Z)B4(Z.fileSystemService)}}e0.debug(`[AcpServiceContext:${$}] Session destroyed`)}static getSessionServices($){return X1.sessions.get($)||null}static setCurrentSession($){if(X1.sessions.has($)){X1.currentSessionId=$;let Y=X1.sessions.get($);if(Y)B4(Y.fileSystemService)}}static getCurrentSessionId(){return X1.currentSessionId}initialize($,Y,Z,X){X1.initializeSession($,Y,Z,X||process.cwd())}reset(){if(X1.currentSessionId)X1.destroySession(X1.currentSessionId)}isAcpMode(){return X1.currentSessionId!==null}getFileSystemService(){if(X1.currentSessionId){let $=X1.sessions.get(X1.currentSessionId);if($)return $.fileSystemService}return new y2}getTerminalService(){if(X1.currentSessionId){let $=X1.sessions.get(X1.currentSessionId);if($)return $.terminalService}return new V8}getConnection(){if(X1.currentSessionId){let $=X1.sessions.get(X1.currentSessionId);if($)return $.connection}return null}getSessionId(){return X1.currentSessionId}getClientCapabilities(){if(X1.currentSessionId){let $=X1.sessions.get(X1.currentSessionId);if($)return $.clientCapabilities}return null}async sendToolUpdate($,Y,Z,X,Q){let J=X1.currentSessionId;if(!J)return;let q=X1.sessions.get(J);if(!q)return;try{await q.connection.sessionUpdate({sessionId:J,update:{sessionUpdate:"tool_call",toolCallId:$,status:Y,title:Z,content:X||[],kind:Q||"other"}})}catch(G){e0.warn("[AcpServiceContext] Failed to send tool update:",G)}}}});import{isAbsolute as GY}from"path";import{z as u1}from"zod";var b1;var E2=b(()=>{b1={filePath:($)=>u1.string().min(1,"File path is required").refine((Y)=>GY(Y),{message:"Path must be absolute"}).describe($?.description||"Absolute file path"),encoding:()=>u1.enum(["utf8","base64","binary"]).default("utf8").describe("File encoding"),timeout:($=1000,Y=300000,Z=30000)=>u1.number().int("Must be an integer").min($,`Cannot be less than ${$}ms`).max(Y,`Cannot exceed ${Y}ms`).default(Z).describe(`Timeout in milliseconds (default ${Z}ms)`),pattern:($)=>u1.string().min(1,"Pattern is required").describe($?.description||"Regex or glob pattern"),glob:($)=>u1.string().min(1,"Glob pattern is required").describe($?.description||'Glob pattern (e.g., "*.js", "**/*.ts")'),lineNumber:($)=>u1.number().int("Line number must be an integer").min($?.min??0,`Line number cannot be less than ${$?.min??0}`).describe($?.description||"Line number"),lineLimit:($)=>u1.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:()=>u1.string().min(1,"Working directory is required").refine(($)=>GY($),{message:"Path must be absolute"}).describe("Absolute working directory"),environment:()=>u1.record(u1.string(),u1.string()).describe("Environment variables (key-value)").optional(),outputMode:($,Y)=>{let Z=u1.enum($);return Y?Z.default(Y):Z},flag:($)=>u1.boolean().default($?.defaultValue??!1).describe($?.description||"Boolean flag"),url:($)=>u1.string().url("Must be a valid URL").describe($?.description||"URL"),port:()=>u1.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:($)=>u1.string().min(1,"Command is required").describe($?.description||"Command to execute"),sessionId:()=>u1.string().min(1,"Session ID is required").uuid("Must be a valid UUID").optional().describe("Session identifier (UUID)"),nonNegativeInt:($)=>u1.number().int("Must be an integer").min(0,"Cannot be negative").describe($?.description||"Non-negative integer"),positiveInt:($)=>u1.number().int("Must be an integer").min(1,"Must be greater than 0").describe($?.description||"Positive integer")}});import*as D8 from"diff";function KY($,Y,Z=4){if($===Y)return null;let X=D8.createPatch("file",$,Y,"","",{context:Z}),Q=X.split(`
623
- `),J=1;for(let q of Q){let G=q.match(/@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@/);if(G){J=parseInt(G[1],10);break}}return`
624
+ [... and ${Y.length-Z} more files matched]`:"";return{type:"file",path:$,content:K+G,metadata:{lines:J.reduce((U,O)=>U+O.lines,0),truncated:Y.length>Z||J.some((U)=>U.truncated)}}}clearExpiredCache(){let $=Date.now(),Y=0;for(let[Z,X]of this.fileCache.entries())if($-X.timestamp>60000)this.fileCache.delete(Z),Y++;if(Y>0)m0.debug(`Cleared ${Y} expired cache entries`)}clearCache(){this.fileCache.clear(),m0.debug("Cleared all cache")}getCacheStats(){return{size:this.fileCache.size,keys:Array.from(this.fileCache.keys())}}}var m0;var AY=b(()=>{w1();BY();_Y();m0=c("Prompts")});import*as c0 from"fs/promises";class P2{async readTextFile($){return c0.readFile($,"utf-8")}async writeTextFile($,Y){await c0.writeFile($,Y,"utf-8")}async exists($){try{return await c0.access($),!0}catch{return!1}}async readBinaryFile($){return c0.readFile($)}async stat($){try{let Y=await c0.stat($);return{size:Y.size,isDirectory:Y.isDirectory(),isFile:Y.isFile(),mtime:Y.mtime}}catch{return null}}async mkdir($,Y){await c0.mkdir($,{recursive:Y?.recursive??!1})}}function y$(){return v9}function A4($){v9=$}function bY(){v9=new P2}var v9;var E$=b(()=>{v9=new P2});class P9{connection;sessionId;capabilities;fallback;constructor($,Y,Z,X=new P2){this.connection=$;this.sessionId=Y;this.capabilities=Z;this.fallback=X}async readTextFile($){if(!this.capabilities.readTextFile)return w0.debug(`[AcpFileSystem] readTextFile fallback: ${$}`),this.fallback.readTextFile($);try{return w0.debug(`[AcpFileSystem] readTextFile via ACP: ${$}`),(await this.connection.readTextFile({path:$,sessionId:this.sessionId})).content}catch(Y){return w0.warn(`[AcpFileSystem] readTextFile ACP failed, fallback: ${Y}`),this.fallback.readTextFile($)}}async writeTextFile($,Y){if(!this.capabilities.writeTextFile)return w0.debug(`[AcpFileSystem] writeTextFile fallback: ${$}`),this.fallback.writeTextFile($,Y);try{w0.debug(`[AcpFileSystem] writeTextFile via ACP: ${$}`),await this.connection.writeTextFile({path:$,content:Y,sessionId:this.sessionId})}catch(Z){return w0.warn(`[AcpFileSystem] writeTextFile ACP failed, fallback: ${Z}`),this.fallback.writeTextFile($,Y)}}async exists($){if(!this.capabilities.readTextFile)return w0.debug(`[AcpFileSystem] exists fallback to local: ${$}`),this.fallback.exists($);try{return await this.connection.readTextFile({path:$,sessionId:this.sessionId}),w0.debug(`[AcpFileSystem] exists(${$}): true (ACP read success)`),!0}catch(Y){let Z=String(Y).toLowerCase();if(["not found","no such file","enoent","does not exist","file not found","path not found"].some((q)=>Z.includes(q)))return w0.debug(`[AcpFileSystem] exists(${$}): false (ACP: not found)`),!1;let J=PG(Z);return w0.warn(`[AcpFileSystem] exists(${$}): assuming exists due to ${J} error`,{error:String(Y),errorType:J,filePath:$}),!0}}async readBinaryFile($){return w0.debug(`[AcpFileSystem] readBinaryFile fallback: ${$}`),this.fallback.readBinaryFile($)}async stat($){return w0.debug(`[AcpFileSystem] stat fallback: ${$}`),this.fallback.stat($)}async mkdir($,Y){return w0.debug(`[AcpFileSystem] mkdir fallback: ${$}`),this.fallback.mkdir($,Y)}getCapabilities(){return this.capabilities}canReadTextFile(){return this.capabilities.readTextFile??!1}canWriteTextFile(){return this.capabilities.writeTextFile??!1}}function PG($){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 w0;var RY=b(()=>{w1();E$();w0=c("Agent")});import{spawn as TG}from"child_process";class T9{async execute($,Y){return new Promise((Z)=>{let X=process.platform==="win32"?"cmd.exe":"/bin/bash",Q=process.platform==="win32"?["/c",$]:["-c",$],J=TG(X,Q,{cwd:Y?.cwd||process.cwd(),env:{...process.env,...Y?.env},stdio:["pipe","pipe","pipe"]}),q="",K="",G=!1,U=Y?.timeout?setTimeout(()=>{G=!0,J.kill("SIGTERM")},Y.timeout):null,O=null,W=()=>{if(U)clearTimeout(U);if(O&&Y?.signal)Y.signal.removeEventListener("abort",O),O=null};if(Y?.signal)O=()=>{G=!0,J.kill("SIGTERM")},Y.signal.addEventListener("abort",O);J.stdout.on("data",(F)=>{let H=F.toString();q+=H,Y?.onOutput?.(H)}),J.stderr.on("data",(F)=>{let H=F.toString();K+=H,Y?.onOutput?.(H)}),J.on("close",(F)=>{W(),Z({success:F===0&&!G,stdout:q,stderr:K,exitCode:F,error:G?"Command was terminated":void 0})}),J.on("error",(F)=>{W(),Z({success:!1,stdout:q,stderr:K,exitCode:null,error:F.message})})})}isAvailable(){return!0}}class VY{connection;sessionId;fallback;constructor($,Y,Z=new T9){this.connection=$;this.sessionId=Y;this.fallback=Z}async execute($,Y){try{Z2.debug(`[AcpTerminal] Executing command via ACP: ${$}`);let Z=await this.connection.createTerminal({sessionId:this.sessionId,command:$,cwd:Y?.cwd,env:Y?.env?Object.entries(Y.env).map(([U,O])=>({name:U,value:O})):void 0}),X=0,Q=null;if(Y?.onOutput)Q=setInterval(async()=>{try{let O=(await Z.currentOutput()).output||"";if(O.length>X){let W=O.slice(X);X=O.length,Y.onOutput?.(W)}}catch{}},100);let J=(U=!1)=>{if(Q)clearInterval(Q),Q=null;(U?Z.kill().then(()=>Z2.debug("[AcpTerminal] Killed remote command")).catch(()=>{}).then(()=>Z.release()).catch(()=>{}):Z.release().catch(()=>{})).catch(()=>{})},q=[];if(q.push(Z.waitForExit().then((U)=>({type:"completed",exitCode:U.exitCode??null}))),Y?.timeout)q.push(new Promise((U)=>{setTimeout(()=>U({type:"timeout"}),Y.timeout)}));if(Y?.signal)q.push(new Promise((U)=>{if(Y.signal.aborted)U({type:"aborted"});else Y.signal.addEventListener("abort",()=>U({type:"aborted"}),{once:!0})}));let K=await Promise.race(q),G="";try{if(G=(await Z.currentOutput()).output||"",Y?.onOutput&&G.length>X)Y.onOutput(G.slice(X))}catch{}switch(K.type){case"completed":return J(!1),{success:K.exitCode===0,stdout:G,stderr:"",exitCode:K.exitCode};case"timeout":return Z2.debug(`[AcpTerminal] Command timed out, killing: ${$}`),J(!0),{success:!1,stdout:G,stderr:"",exitCode:null,error:"Command timed out"};case"aborted":return Z2.debug(`[AcpTerminal] Command aborted, killing: ${$}`),J(!0),{success:!1,stdout:G,stderr:"",exitCode:null,error:"Command was aborted"}}}catch(Z){return Z2.warn("[AcpTerminal] ACP terminal failed, using fallback:",Z),this.fallback.execute($,Y)}}isAvailable(){return!0}}function DY(){return X1.getInstance().getTerminalService()}function T2(){return X1.getInstance().isAcpMode()}var Z2,X1;var v$=b(()=>{w1();E$();RY();Z2=c("Agent");X1=class X1{static sessions=new Map;static currentSessionId=null;constructor(){}static getInstance(){return new X1}static initializeSession($,Y,Z,X){let Q=Z?.fs?new P9($,Y,Z.fs):new P2;if(Z?.fs)Z2.debug(`[AcpServiceContext:${Y}] Using ACP file system service`);let J=new VY($,Y);Z2.debug(`[AcpServiceContext:${Y}] Using ACP terminal service`),X1.sessions.set(Y,{fileSystemService:Q,terminalService:J,connection:$,clientCapabilities:Z||null,cwd:X}),X1.currentSessionId=Y,A4(Q),Z2.debug(`[AcpServiceContext:${Y}] Initialized with capabilities:`,{fs:!!Z?.fs,readTextFile:Z?.fs?.readTextFile,writeTextFile:Z?.fs?.writeTextFile,cwd:X})}static destroySession($){if(X1.sessions.delete($),X1.currentSessionId===$){let Y=Array.from(X1.sessions.keys());if(X1.currentSessionId=Y[0]||null,!X1.currentSessionId)bY();else{let Z=X1.sessions.get(X1.currentSessionId);if(Z)A4(Z.fileSystemService)}}Z2.debug(`[AcpServiceContext:${$}] Session destroyed`)}static getSessionServices($){return X1.sessions.get($)||null}static setCurrentSession($){if(X1.sessions.has($)){X1.currentSessionId=$;let Y=X1.sessions.get($);if(Y)A4(Y.fileSystemService)}}static getCurrentSessionId(){return X1.currentSessionId}initialize($,Y,Z,X){X1.initializeSession($,Y,Z,X||process.cwd())}reset(){if(X1.currentSessionId)X1.destroySession(X1.currentSessionId)}isAcpMode(){return X1.currentSessionId!==null}getFileSystemService(){if(X1.currentSessionId){let $=X1.sessions.get(X1.currentSessionId);if($)return $.fileSystemService}return new P2}getTerminalService(){if(X1.currentSessionId){let $=X1.sessions.get(X1.currentSessionId);if($)return $.terminalService}return new T9}getConnection(){if(X1.currentSessionId){let $=X1.sessions.get(X1.currentSessionId);if($)return $.connection}return null}getSessionId(){return X1.currentSessionId}getClientCapabilities(){if(X1.currentSessionId){let $=X1.sessions.get(X1.currentSessionId);if($)return $.clientCapabilities}return null}async sendToolUpdate($,Y,Z,X,Q){let J=X1.currentSessionId;if(!J)return;let q=X1.sessions.get(J);if(!q)return;try{await q.connection.sessionUpdate({sessionId:J,update:{sessionUpdate:"tool_call",toolCallId:$,status:Y,title:Z,content:X||[],kind:Q||"other"}})}catch(K){Z2.warn("[AcpServiceContext] Failed to send tool update:",K)}}}});import{isAbsolute as IY}from"path";import{z as c1}from"zod";var I1;var S2=b(()=>{I1={filePath:($)=>c1.string().min(1,"File path is required").refine((Y)=>IY(Y),{message:"Path must be absolute"}).describe($?.description||"Absolute file path"),encoding:()=>c1.enum(["utf8","base64","binary"]).default("utf8").describe("File encoding"),timeout:($=1000,Y=300000,Z=30000)=>c1.number().int("Must be an integer").min($,`Cannot be less than ${$}ms`).max(Y,`Cannot exceed ${Y}ms`).default(Z).describe(`Timeout in milliseconds (default ${Z}ms)`),pattern:($)=>c1.string().min(1,"Pattern is required").describe($?.description||"Regex or glob pattern"),glob:($)=>c1.string().min(1,"Glob pattern is required").describe($?.description||'Glob pattern (e.g., "*.js", "**/*.ts")'),lineNumber:($)=>c1.number().int("Line number must be an integer").min($?.min??0,`Line number cannot be less than ${$?.min??0}`).describe($?.description||"Line number"),lineLimit:($)=>c1.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:()=>c1.string().min(1,"Working directory is required").refine(($)=>IY($),{message:"Path must be absolute"}).describe("Absolute working directory"),environment:()=>c1.record(c1.string(),c1.string()).describe("Environment variables (key-value)").optional(),outputMode:($,Y)=>{let Z=c1.enum($);return Y?Z.default(Y):Z},flag:($)=>c1.boolean().default($?.defaultValue??!1).describe($?.description||"Boolean flag"),url:($)=>c1.string().url("Must be a valid URL").describe($?.description||"URL"),port:()=>c1.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:($)=>c1.string().min(1,"Command is required").describe($?.description||"Command to execute"),sessionId:()=>c1.string().min(1,"Session ID is required").uuid("Must be a valid UUID").optional().describe("Session identifier (UUID)"),nonNegativeInt:($)=>c1.number().int("Must be an integer").min(0,"Cannot be negative").describe($?.description||"Non-negative integer"),positiveInt:($)=>c1.number().int("Must be an integer").min(1,"Must be greater than 0").describe($?.description||"Positive integer")}});import*as S9 from"diff";function MY($,Y,Z=4){if($===Y)return null;let X=S9.createPatch("file",$,Y,"","",{context:Z}),Q=X.split(`
625
+ `),J=1;for(let q of Q){let K=q.match(/@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@/);if(K){J=parseInt(K[1],10);break}}return`
624
626
  <<<DIFF>>>
625
627
  ${JSON.stringify({patch:X,startLine:Math.max(1,J-Z),matchLine:J})}
626
628
  <<</DIFF>>>
627
- `}function UY($,Y,Z,X,Q=4){let J=$.indexOf(Z);if(J===-1)return null;let G=$.substring(0,J).split(`
628
- `).length-1,K=$.split(`
629
- `),W=Y.split(`
629
+ `}function jY($,Y,Z,X,Q=4){let J=$.indexOf(Z);if(J===-1)return null;let K=$.substring(0,J).split(`
630
+ `).length-1,G=$.split(`
631
+ `),U=Y.split(`
630
632
  `),O=Z.split(`
631
- `),U=X.split(`
632
- `),F=Math.max(0,G-Q),H=Math.min(K.length,G+O.length+Q),_=Math.min(W.length,G+U.length+Q),z=K.slice(F,H).join(`
633
- `),L=W.slice(F,_).join(`
634
- `),B=D8.createPatch("file",z,L,"","",{context:Q});return`
633
+ `),W=X.split(`
634
+ `),F=Math.max(0,K-Q),H=Math.min(G.length,K+O.length+Q),z=Math.min(U.length,K+W.length+Q),N=G.slice(F,H).join(`
635
+ `),L=U.slice(F,z).join(`
636
+ `),B=S9.createPatch("file",N,L,"","",{context:Q});return`
635
637
  <<<DIFF>>>
636
- ${JSON.stringify({patch:B,startLine:F+1,matchLine:G+1})}
638
+ ${JSON.stringify({patch:B,startLine:F+1,matchLine:K+1})}
637
639
  <<</DIFF>>>
638
- `}var I8=()=>{};function WY($){return $.replace(/\\+(n|t|r|'|"|`|\\|\n)/g,(Y,Z)=>{switch(Z){case"n":return`
640
+ `}var k9=()=>{};function yY($){return $.replace(/\\+(n|t|r|'|"|`|\\|\n)/g,(Y,Z)=>{switch(Z){case"n":return`
639
641
  `;case"t":return"\t";case"r":return"\r";case"'":return"'";case'"':return'"';case"`":return"`";case"\\":return"\\";case`
640
642
  `:return`
641
- `;default:return Y}})}function OY($,Y){let Z=Y.split(`
642
- `);if(Z.length===1)return null;let Q=Z[0].match(/^(\s+)/);if(!Q)return null;let J=Q[1],G=Z.map((W)=>{if(W.startsWith(J))return W.slice(J.length);return W}).join(`
643
- `),K=$.split(`
644
- `);for(let W=0;W<=K.length-Z.length;W++){let O=K[W].match(/^(\s+)/),U=O?O[1]:"",F=K.slice(W,W+Z.length);if(F.map((z)=>{if(z.startsWith(U))return z.slice(U.length);return z}).join(`
645
- `)===G)return F.join(`
646
- `)}return null}var FY=()=>{};import{promises as L4}from"node:fs";class O0{static instance=null;accessedFiles=new Map;constructor(){}static getInstance(){if(!O0.instance)O0.instance=new O0;return O0.instance}async recordFileRead($,Y){try{let Z=await L4.stat($),X={filePath:$,accessTime:Date.now(),mtime:Z.mtimeMs,sessionId:Y,lastOperation:"read"};this.accessedFiles.set($,X),z6.debug(`记录文件读取: ${$}`)}catch(Z){z6.warn(`记录文件读取失败: ${$}`,Z)}}async recordFileEdit($,Y,Z="edit"){try{let X=await L4.stat($),Q={filePath:$,accessTime:Date.now(),mtime:X.mtimeMs,sessionId:Y,lastOperation:Z};this.accessedFiles.set($,Q),z6.debug(`记录文件${Z==="edit"?"编辑":"写入"}: ${$}`)}catch(X){z6.warn(`记录文件${Z==="edit"?"编辑":"写入"}失败: ${$}`,X)}}hasFileBeenRead($,Y){let Z=this.accessedFiles.get($);if(!Z)return!1;if(Y&&Z.sessionId!==Y)return!1;return!0}async checkFileModification($){let Y=this.accessedFiles.get($);if(!Y)return{modified:!1,message:"文件未被跟踪"};try{let Z=await L4.stat($);if(Math.abs(Z.mtimeMs-Y.mtime)>1)return{modified:!0,message:`文件在访问后被修改(访问时间: ${new Date(Y.accessTime).toISOString()}, 当前修改时间: ${Z.mtime.toISOString()})`};return{modified:!1}}catch(Z){if(Z.code==="ENOENT")return{modified:!0,message:"文件已被删除"};return{modified:!1,message:`无法检查文件状态: ${Z.message}`}}}async checkExternalModification($){let Y=this.accessedFiles.get($);if(!Y)return{isExternal:!1,message:"文件未被跟踪"};try{let Z=await L4.stat($);if(Z.mtimeMs-Y.mtime>2000)return{isExternal:!0,message:`文件在 ${new Date(Y.accessTime).toISOString()} (${Y.lastOperation}) 之后被外部程序修改(当前修改时间: ${Z.mtime.toISOString()})`};return{isExternal:!1}}catch(Z){if(Z.code==="ENOENT")return{isExternal:!0,message:"文件已被删除"};return z6.warn(`检查文件外部修改失败: ${$}`,Z),{isExternal:!1,message:`无法检查文件状态: ${Z.message}`}}}getFileRecord($){return this.accessedFiles.get($)}clearFileRecord($){this.accessedFiles.delete($)}clearAll(){this.accessedFiles.clear()}clearSession($){for(let[Y,Z]of this.accessedFiles.entries())if(Z.sessionId===$)this.accessedFiles.delete(Y)}getTrackedFiles(){return Array.from(this.accessedFiles.keys())}getTrackedFileCount(){return this.accessedFiles.size}static resetInstance(){O0.instance=null}}var z6;var w4=b(()=>{V1();z6=n("Tool")});import{execSync as FK}from"node:child_process";import*as M8 from"node:os";import*as n2 from"node:path";function HK($){return n2.resolve($).replace(/\//g,"-")}function HY($){if($.startsWith("-"))return"/"+$.slice(1).replace(/-/g,"/");return $.replace(/-/g,"/")}function N6($){let Y=M8.homedir(),Z=HK($);return n2.join(Y,".blade","projects",Z)}function R0($,Y){return n2.join(N6($),`${Y}.jsonl`)}function y$($){try{return FK("git rev-parse --abbrev-ref HEAD",{cwd:$,encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()||void 0}catch{return}}function o2(){return n2.join(M8.homedir(),".blade")}async function _Y(){let{readdir:$}=await import("node:fs/promises");try{let Y=n2.join(o2(),"projects");return(await $(Y,{withFileTypes:!0})).filter((X)=>X.isDirectory()).map((X)=>X.name)}catch{return[]}}var B6=()=>{};import*as zY from"node:crypto";import{promises as $2}from"node:fs";import*as s2 from"node:path";class L6{sessionId;enableCheckpoints;maxSnapshots;snapshotDir;trackedFileBackups=new Map;snapshots=[];constructor($){this.sessionId=$.sessionId,this.enableCheckpoints=$.enableCheckpoints??!0,this.maxSnapshots=$.maxSnapshots??10;let Y=o2();this.snapshotDir=s2.join(Y,"file-history",this.sessionId)}async initialize(){if(!this.enableCheckpoints)return;try{await $2.mkdir(this.snapshotDir,{recursive:!0}),console.log(`[SnapshotManager] 初始化快照目录: ${this.snapshotDir}`)}catch($){throw console.warn("[SnapshotManager] 创建快照目录失败:",$),$}}async createSnapshot($,Y){if(!this.enableCheckpoints)return console.log("[SnapshotManager] 检查点已禁用,跳过快照创建"),{backupFileName:"",version:0,backupTime:new Date};try{await $2.access($)}catch{return console.warn(`[SnapshotManager] 文件不存在,跳过快照: ${$}`),{backupFileName:"",version:0,backupTime:new Date}}let Z=this.trackedFileBackups.get($),X=Z?Z.version+1:1,Q=this.generateFileHash($,X),J=s2.join(this.snapshotDir,`${Q}@v${X}`);try{let q=await $2.readFile($,{encoding:"utf-8"});await $2.writeFile(J,q,{encoding:"utf-8"});let G={backupFileName:Q,version:X,backupTime:new Date};return this.trackedFileBackups.set($,G),this.snapshots.push({messageId:Y,backupFileName:Q,timestamp:new Date,filePath:$}),console.log(`[SnapshotManager] 创建快照: ${$} -> ${Q}@v${X}`),await this.cleanupOldSnapshots($),G}catch(q){throw console.error(`[SnapshotManager] 创建快照失败: ${$}`,q),q}}async restoreSnapshot($,Y){let Z=this.snapshots.slice().reverse().find((J)=>J.messageId===Y&&J.filePath===$);if(!Z)throw Error(`未找到快照: messageId=${Y}, filePath=${$}`);let X=this.trackedFileBackups.get($);if(!X)throw Error(`未找到文件追踪信息: ${$}`);let Q=s2.join(this.snapshotDir,`${Z.backupFileName}@v${X.version}`);try{let J=await $2.readFile(Q,{encoding:"utf-8"});await $2.writeFile($,J,{encoding:"utf-8"}),console.log(`[SnapshotManager] 恢复快照: ${$} <- ${Z.backupFileName}@v${X.version}`)}catch(J){throw console.error(`[SnapshotManager] 恢复快照失败: ${$}`,J),J}}async listSnapshots($){return this.snapshots.filter((Y)=>Y.filePath===$)}async cleanupOldSnapshots($){let Y=this.snapshots.filter((Q)=>Q.filePath===$);if(Y.length<=this.maxSnapshots)return;let X=Y.sort((Q,J)=>Q.timestamp.getTime()-J.timestamp.getTime()).slice(0,Y.length-this.maxSnapshots);for(let Q of X){let J=this.trackedFileBackups.get(Q.filePath);if(!J)continue;let q=s2.join(this.snapshotDir,`${Q.backupFileName}@v${J.version}`);try{await $2.unlink(q),console.log(`[SnapshotManager] 删除旧快照: ${q}`)}catch(K){console.warn(`[SnapshotManager] 删除快照失败: ${q}`,K)}let G=this.snapshots.indexOf(Q);if(G>-1)this.snapshots.splice(G,1)}}async cleanup($=0){try{let Y=await $2.readdir(this.snapshotDir);if(Y.length<=$)return;let Z=await Promise.all(Y.map(async(Q)=>{let J=s2.join(this.snapshotDir,Q),q=await $2.stat(J);return{file:Q,mtime:q.mtime.getTime()}}));Z.sort((Q,J)=>J.mtime-Q.mtime);let X=Z.slice($);for(let{file:Q}of X){let J=s2.join(this.snapshotDir,Q);await $2.unlink(J),console.log(`[SnapshotManager] 清理快照: ${J}`)}}catch(Y){console.warn("[SnapshotManager] 清理快照失败:",Y)}}generateFileHash($,Y){let Z=zY.createHash("md5");return Z.update(`${$}:${Y}`),Z.digest("hex").substring(0,16)}getSnapshotDir(){return this.snapshotDir}getSessionId(){return this.sessionId}getTrackedFileCount(){return this.trackedFileBackups.size}getSnapshotCount(){return this.snapshots.length}}var j8=b(()=>{B6()});import{extname as _K}from"path";import{z as A4}from"zod";function NY($){return $.replaceAll("‘","'").replaceAll("’","'").replaceAll("“",'"').replaceAll("”",'"')}function zK($,Y){if($.includes(Y))return{matched:Y,strategy:"exact"};let Z=NY(Y),Q=NY($).indexOf(Z);if(Q!==-1)return{matched:$.substring(Q,Q+Y.length),strategy:"normalize_quotes"};let J=WY(Y);if(J!==Y&&$.includes(J))return{matched:J,strategy:"unescape"};let q=OY($,Y);if(q)return{matched:q,strategy:"flexible"};return{matched:null,strategy:"failed"}}function NK($,Y){if(Y.length===0)return[];let Z=[],X=$.indexOf(Y);while(X!==-1)Z.push(X),X=$.indexOf(Y,X+Y.length);return Z}function BK($,Y){let{file_path:Z,matches_found:X,replacements_made:Q,replace_all:J,size_diff:q}=$,G=`✅ 成功编辑文件: ${Z}`;if(G+=`
647
- \uD83D\uDCDD 替换了 ${Q} 个匹配项`,!J&&X>1)G+=` (共找到 ${X} 个匹配项)`;if(q!==0){let K=q>0?`增加${q}`:`减少${Math.abs(q)}`;G+=`
648
- \uD83D\uDCCA 文件大小${K}个字符`}if(Y)G+=Y;return G}function LK($,Y,Z){let X=$.split(`
649
- `),Q=X.length,J=wK($,Y,3),q=0,G=Math.min(20,Q);if(J.length>0){let H=J[0];q=Math.max(0,H.lineNumber-10),G=Math.min(Q,H.lineNumber+10)}let W=X.slice(q,G).map((H,_)=>{return` ${(q+_+1).toString().padStart(4)}: ${H}`}).join(`
643
+ `;default:return Y}})}function EY($,Y){let Z=Y.split(`
644
+ `);if(Z.length===1)return null;let Q=Z[0].match(/^(\s+)/);if(!Q)return null;let J=Q[1],K=Z.map((U)=>{if(U.startsWith(J))return U.slice(J.length);return U}).join(`
645
+ `),G=$.split(`
646
+ `);for(let U=0;U<=G.length-Z.length;U++){let O=G[U].match(/^(\s+)/),W=O?O[1]:"",F=G.slice(U,U+Z.length);if(F.map((N)=>{if(N.startsWith(W))return N.slice(W.length);return N}).join(`
647
+ `)===K)return F.join(`
648
+ `)}return null}var vY=()=>{};import{promises as b4}from"node:fs";class z0{static instance=null;accessedFiles=new Map;constructor(){}static getInstance(){if(!z0.instance)z0.instance=new z0;return z0.instance}async recordFileRead($,Y){try{let Z=await b4.stat($),X={filePath:$,accessTime:Date.now(),mtime:Z.mtimeMs,sessionId:Y,lastOperation:"read"};this.accessedFiles.set($,X),L6.debug(`记录文件读取: ${$}`)}catch(Z){L6.warn(`记录文件读取失败: ${$}`,Z)}}async recordFileEdit($,Y,Z="edit"){try{let X=await b4.stat($),Q={filePath:$,accessTime:Date.now(),mtime:X.mtimeMs,sessionId:Y,lastOperation:Z};this.accessedFiles.set($,Q),L6.debug(`记录文件${Z==="edit"?"编辑":"写入"}: ${$}`)}catch(X){L6.warn(`记录文件${Z==="edit"?"编辑":"写入"}失败: ${$}`,X)}}hasFileBeenRead($,Y){let Z=this.accessedFiles.get($);if(!Z)return!1;if(Y&&Z.sessionId!==Y)return!1;return!0}async checkFileModification($){let Y=this.accessedFiles.get($);if(!Y)return{modified:!1,message:"文件未被跟踪"};try{let Z=await b4.stat($);if(Math.abs(Z.mtimeMs-Y.mtime)>1)return{modified:!0,message:`文件在访问后被修改(访问时间: ${new Date(Y.accessTime).toISOString()}, 当前修改时间: ${Z.mtime.toISOString()})`};return{modified:!1}}catch(Z){if(Z.code==="ENOENT")return{modified:!0,message:"文件已被删除"};return{modified:!1,message:`无法检查文件状态: ${Z.message}`}}}async checkExternalModification($){let Y=this.accessedFiles.get($);if(!Y)return{isExternal:!1,message:"文件未被跟踪"};try{let Z=await b4.stat($);if(Z.mtimeMs-Y.mtime>2000)return{isExternal:!0,message:`文件在 ${new Date(Y.accessTime).toISOString()} (${Y.lastOperation}) 之后被外部程序修改(当前修改时间: ${Z.mtime.toISOString()})`};return{isExternal:!1}}catch(Z){if(Z.code==="ENOENT")return{isExternal:!0,message:"文件已被删除"};return L6.warn(`检查文件外部修改失败: ${$}`,Z),{isExternal:!1,message:`无法检查文件状态: ${Z.message}`}}}getFileRecord($){return this.accessedFiles.get($)}clearFileRecord($){this.accessedFiles.delete($)}clearAll(){this.accessedFiles.clear()}clearSession($){for(let[Y,Z]of this.accessedFiles.entries())if(Z.sessionId===$)this.accessedFiles.delete(Y)}getTrackedFiles(){return Array.from(this.accessedFiles.keys())}getTrackedFileCount(){return this.accessedFiles.size}static resetInstance(){z0.instance=null}}var L6;var R4=b(()=>{w1();L6=c("Tool")});import{execSync as SG}from"node:child_process";import*as C9 from"node:os";import*as t2 from"node:path";function kG($){return t2.resolve($).replace(/\//g,"-")}function PY($){if($.startsWith("-"))return"/"+$.slice(1).replace(/-/g,"/");return $.replace(/-/g,"/")}function w6($){let Y=C9.homedir(),Z=kG($);return t2.join(Y,".blade","projects",Z)}function I0($,Y){return t2.join(w6($),`${Y}.jsonl`)}function P$($){try{return SG("git rev-parse --abbrev-ref HEAD",{cwd:$,encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()||void 0}catch{return}}function e2(){return t2.join(C9.homedir(),".blade")}async function TY(){let{readdir:$}=await import("node:fs/promises");try{let Y=t2.join(e2(),"projects");return(await $(Y,{withFileTypes:!0})).filter((X)=>X.isDirectory()).map((X)=>X.name)}catch{return[]}}var A6=()=>{};import*as SY from"node:crypto";import{promises as X2}from"node:fs";import*as $$ from"node:path";class b6{sessionId;enableCheckpoints;maxSnapshots;snapshotDir;trackedFileBackups=new Map;snapshots=[];constructor($){this.sessionId=$.sessionId,this.enableCheckpoints=$.enableCheckpoints??!0,this.maxSnapshots=$.maxSnapshots??10;let Y=e2();this.snapshotDir=$$.join(Y,"file-history",this.sessionId)}async initialize(){if(!this.enableCheckpoints)return;try{await X2.mkdir(this.snapshotDir,{recursive:!0}),console.log(`[SnapshotManager] 初始化快照目录: ${this.snapshotDir}`)}catch($){throw console.warn("[SnapshotManager] 创建快照目录失败:",$),$}}async createSnapshot($,Y){if(!this.enableCheckpoints)return console.log("[SnapshotManager] 检查点已禁用,跳过快照创建"),{backupFileName:"",version:0,backupTime:new Date};try{await X2.access($)}catch{return console.warn(`[SnapshotManager] 文件不存在,跳过快照: ${$}`),{backupFileName:"",version:0,backupTime:new Date}}let Z=this.trackedFileBackups.get($),X=Z?Z.version+1:1,Q=this.generateFileHash($,X),J=$$.join(this.snapshotDir,`${Q}@v${X}`);try{let q=await X2.readFile($,{encoding:"utf-8"});await X2.writeFile(J,q,{encoding:"utf-8"});let K={backupFileName:Q,version:X,backupTime:new Date};return this.trackedFileBackups.set($,K),this.snapshots.push({messageId:Y,backupFileName:Q,timestamp:new Date,filePath:$}),console.log(`[SnapshotManager] 创建快照: ${$} -> ${Q}@v${X}`),await this.cleanupOldSnapshots($),K}catch(q){throw console.error(`[SnapshotManager] 创建快照失败: ${$}`,q),q}}async restoreSnapshot($,Y){let Z=this.snapshots.slice().reverse().find((J)=>J.messageId===Y&&J.filePath===$);if(!Z)throw Error(`未找到快照: messageId=${Y}, filePath=${$}`);let X=this.trackedFileBackups.get($);if(!X)throw Error(`未找到文件追踪信息: ${$}`);let Q=$$.join(this.snapshotDir,`${Z.backupFileName}@v${X.version}`);try{let J=await X2.readFile(Q,{encoding:"utf-8"});await X2.writeFile($,J,{encoding:"utf-8"}),console.log(`[SnapshotManager] 恢复快照: ${$} <- ${Z.backupFileName}@v${X.version}`)}catch(J){throw console.error(`[SnapshotManager] 恢复快照失败: ${$}`,J),J}}async listSnapshots($){return this.snapshots.filter((Y)=>Y.filePath===$)}async cleanupOldSnapshots($){let Y=this.snapshots.filter((Q)=>Q.filePath===$);if(Y.length<=this.maxSnapshots)return;let X=Y.sort((Q,J)=>Q.timestamp.getTime()-J.timestamp.getTime()).slice(0,Y.length-this.maxSnapshots);for(let Q of X){let J=this.trackedFileBackups.get(Q.filePath);if(!J)continue;let q=$$.join(this.snapshotDir,`${Q.backupFileName}@v${J.version}`);try{await X2.unlink(q),console.log(`[SnapshotManager] 删除旧快照: ${q}`)}catch(G){console.warn(`[SnapshotManager] 删除快照失败: ${q}`,G)}let K=this.snapshots.indexOf(Q);if(K>-1)this.snapshots.splice(K,1)}}async cleanup($=0){try{let Y=await X2.readdir(this.snapshotDir);if(Y.length<=$)return;let Z=await Promise.all(Y.map(async(Q)=>{let J=$$.join(this.snapshotDir,Q),q=await X2.stat(J);return{file:Q,mtime:q.mtime.getTime()}}));Z.sort((Q,J)=>J.mtime-Q.mtime);let X=Z.slice($);for(let{file:Q}of X){let J=$$.join(this.snapshotDir,Q);await X2.unlink(J),console.log(`[SnapshotManager] 清理快照: ${J}`)}}catch(Y){console.warn("[SnapshotManager] 清理快照失败:",Y)}}generateFileHash($,Y){let Z=SY.createHash("md5");return Z.update(`${$}:${Y}`),Z.digest("hex").substring(0,16)}getSnapshotDir(){return this.snapshotDir}getSessionId(){return this.sessionId}getTrackedFileCount(){return this.trackedFileBackups.size}getSnapshotCount(){return this.snapshots.length}}var f9=b(()=>{A6()});import{extname as CG}from"path";import{z as V4}from"zod";function kY($){return $.replaceAll("‘","'").replaceAll("’","'").replaceAll("“",'"').replaceAll("”",'"')}function fG($,Y){if($.includes(Y))return{matched:Y,strategy:"exact"};let Z=kY(Y),Q=kY($).indexOf(Z);if(Q!==-1)return{matched:$.substring(Q,Q+Y.length),strategy:"normalize_quotes"};let J=yY(Y);if(J!==Y&&$.includes(J))return{matched:J,strategy:"unescape"};let q=EY($,Y);if(q)return{matched:q,strategy:"flexible"};return{matched:null,strategy:"failed"}}function hG($,Y){if(Y.length===0)return[];let Z=[],X=$.indexOf(Y);while(X!==-1)Z.push(X),X=$.indexOf(Y,X+Y.length);return Z}function xG($,Y){let{file_path:Z,matches_found:X,replacements_made:Q,replace_all:J,size_diff:q}=$,K=`✅ 成功编辑文件: ${Z}`;if(K+=`
649
+ \uD83D\uDCDD 替换了 ${Q} 个匹配项`,!J&&X>1)K+=` (共找到 ${X} 个匹配项)`;if(q!==0){let G=q>0?`增加${q}`:`减少${Math.abs(q)}`;K+=`
650
+ \uD83D\uDCCA 文件大小${G}个字符`}if(Y)K+=Y;return K}function pG($,Y,Z){let X=$.split(`
651
+ `),Q=X.length,J=uG($,Y,3),q=0,K=Math.min(20,Q);if(J.length>0){let H=J[0];q=Math.max(0,H.lineNumber-10),K=Math.min(Q,H.lineNumber+10)}let U=X.slice(q,K).map((H,z)=>{return` ${(q+z+1).toString().padStart(4)}: ${H}`}).join(`
650
652
  `),O=`String not found in file.
651
653
 
652
654
  File: ${Z}
653
655
  Total lines: ${Q}
654
656
 
655
- `,U=Y.length>300?Y.substring(0,300)+`
657
+ `,W=Y.length>300?Y.substring(0,300)+`
656
658
  ... (truncated)`:Y;if(O+=`You tried to match:
657
- ${U}
658
-
659
- `,J.length>0)O+=`File content around possible matches (lines ${q+1}-${G}):
660
659
  ${W}
661
660
 
662
- `;else O+=`File content preview (lines ${q+1}-${G}):
663
- ${W}
661
+ `,J.length>0)O+=`File content around possible matches (lines ${q+1}-${K}):
662
+ ${U}
663
+
664
+ `;else O+=`File content preview (lines ${q+1}-${K}):
665
+ ${U}
664
666
 
665
667
  `;if(J.length>0)O+=`Possible similar matches found:
666
- `,J.forEach((H,_)=>{let z=H.text.length>100?H.text.substring(0,100)+"...":H.text;O+=` ${_+1}. Line ${H.lineNumber} (similarity: ${Math.round(H.similarity*100)}%)
667
- ${z.replace(/\n/g,"\\n")}
668
+ `,J.forEach((H,z)=>{let N=H.text.length>100?H.text.substring(0,100)+"...":H.text;O+=` ${z+1}. Line ${H.lineNumber} (similarity: ${Math.round(H.similarity*100)}%)
669
+ ${N.replace(/\n/g,"\\n")}
668
670
  `}),O+=`
669
671
  `;O+=`Recovery suggestions:
670
672
  1. Use the Read tool to verify the current file content
@@ -682,20 +684,20 @@ Common issues:
682
684
  搜索字符串长度: ${Y.length} 字符
683
685
  `;if(J.length>0)F+=`
684
686
  \uD83D\uDCA1 找到 ${J.length} 个相似匹配项:
685
- `,J.forEach((H,_)=>{F+=` ${_+1}. 第 ${H.lineNumber} 行 (相似度: ${Math.round(H.similarity*100)}%)
687
+ `,J.forEach((H,z)=>{F+=` ${z+1}. 第 ${H.lineNumber} 行 (相似度: ${Math.round(H.similarity*100)}%)
686
688
  `});else F+=`
687
689
  ⚠️ 未找到相似的匹配项
688
690
  `;return F+=`
689
- \uD83D\uDCC4 文件内容摘录 (${q+1}-${G} 行):
690
- ${W}
691
+ \uD83D\uDCC4 文件内容摘录 (${q+1}-${K} 行):
692
+ ${U}
691
693
  `,F+=`
692
694
  \uD83D\uDD27 建议:
693
695
  `,F+=` 1. 使用 Read 工具重新读取文件
694
696
  `,F+=` 2. 检查空格、换行符、引号是否完全匹配
695
- `,F+=" 3. 提供更多上下文代码确保唯一性",{llmContent:O,displayContent:F,metadata:{searchStringLength:Y.length,fuzzyMatches:J.map((H)=>({line:H.lineNumber,similarity:H.similarity,preview:H.text.substring(0,100)})),excerptRange:[q+1,G],totalLines:Q}}}function wK($,Y,Z=3){let X=$.split(`
697
+ `,F+=" 3. 提供更多上下文代码确保唯一性",{llmContent:O,displayContent:F,metadata:{searchStringLength:Y.length,fuzzyMatches:J.map((H)=>({line:H.lineNumber,similarity:H.similarity,preview:H.text.substring(0,100)})),excerptRange:[q+1,K],totalLines:Q}}}function uG($,Y,Z=3){let X=$.split(`
696
698
  `),Q=Y.split(`
697
- `);if(Q.length===1)return X.map((K,W)=>({text:K,lineNumber:W+1,similarity:BY(Y.trim(),K.trim())})).filter((K)=>K.similarity>0.5).sort((K,W)=>W.similarity-K.similarity).slice(0,Z);let J=Q.length,q=[];for(let G=0;G<=X.length-J;G++){let K=X.slice(G,G+J).join(`
698
- `),W=BY(Y,K);if(W>0.5)q.push({text:K,lineNumber:G+1,similarity:W})}return q.sort((G,K)=>K.similarity-G.similarity).slice(0,Z)}function BY($,Y){let Z=(F)=>F.trim().replace(/\s+/g," ").replace(/[\u201c\u201d"]/g,'"').replace(/[\u2018\u2019']/g,"'"),X=Z($),Q=Z(Y);if(X===Q)return 1;let J=X.length,q=Q.length;if(J===0)return q===0?1:0;if(q===0)return 0;let G=200,K=X.substring(0,G),W=Q.substring(0,G),O=AK(K,W),U=Math.max(K.length,W.length);return 1-O/U}function AK($,Y){let Z=$.length,X=Y.length,Q=Array(Z+1).fill(null).map(()=>Array(X+1).fill(0));for(let J=0;J<=Z;J++)Q[J][0]=J;for(let J=0;J<=X;J++)Q[0][J]=J;for(let J=1;J<=Z;J++)for(let q=1;q<=X;q++){let G=$[J-1]===Y[q-1]?0:1;Q[J][q]=Math.min(Q[J-1][q]+1,Q[J][q-1]+1,Q[J-1][q-1]+G)}return Q[Z][X]}var y8;var LY=b(()=>{j$();M$();g1();e1();E2();I8();FY();w4();j8();y8=U1({name:"Edit",displayName:"File Edit",kind:"write",strict:!0,isConcurrencySafe:!1,schema:A4.object({file_path:b1.filePath({description:"Absolute path of the file to edit"}),old_string:A4.string().min(1,"old_string cannot be empty").describe("String to replace"),new_string:A4.string().describe("Replacement string (can be empty)"),replace_all:A4.boolean().default(!1).describe("Replace all matches (default: first only)")}),description:{short:"Performs exact string replacements in files",long:"Performs exact string replacements in files.",usageNotes:["You must use your Read tool at least once in the conversation before editing. This tool will error if you attempt an edit without reading the file.","When editing text from Read tool output, ensure you preserve the exact indentation (tabs/spaces) as it appears AFTER the line number prefix. The line number prefix format is: spaces + line number + tab. Everything after that tab is the actual file content to match. Never include any part of the line number prefix in the old_string or new_string.","ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.","Only use emojis if the user explicitly requests it. Avoid adding emojis to files unless asked.","The edit will FAIL if old_string is not unique in the file. Either provide a larger string with more surrounding context to make it unique or use replace_all to change every instance of old_string.","Use replace_all for replacing and renaming strings across the file. This parameter is useful if you want to rename a variable for instance."]},async execute($,Y){let{file_path:Z,old_string:X,new_string:Q,replace_all:J}=$,{updateOutput:q,sessionId:G,messageId:K}=Y,W=Y.signal??new AbortController().signal;try{q?.("Starting to read file...");let O=I$(),U=v2(),F;try{if(U)q?.("通过 IDE 读取文件...");F=await O.readTextFile(Z)}catch(R){if(R.code==="ENOENT"||R.message?.includes("not found"))return{success:!1,llmContent:`File not found: ${Z}`,displayContent:`❌ 文件不存在: ${Z}`,error:{type:"execution_error",message:"文件不存在"}};throw R}if(W.throwIfAborted(),G){let R=O0.getInstance();if(!R.hasFileBeenRead(Z,G))return{success:!1,llmContent:"You must use your Read tool at least once in the conversation before editing. This tool will error if you attempt an edit without reading the file.",displayContent:`❌ 编辑失败:必须先使用 Read 工具读取文件
699
+ `);if(Q.length===1)return X.map((G,U)=>({text:G,lineNumber:U+1,similarity:CY(Y.trim(),G.trim())})).filter((G)=>G.similarity>0.5).sort((G,U)=>U.similarity-G.similarity).slice(0,Z);let J=Q.length,q=[];for(let K=0;K<=X.length-J;K++){let G=X.slice(K,K+J).join(`
700
+ `),U=CY(Y,G);if(U>0.5)q.push({text:G,lineNumber:K+1,similarity:U})}return q.sort((K,G)=>G.similarity-K.similarity).slice(0,Z)}function CY($,Y){let Z=(F)=>F.trim().replace(/\s+/g," ").replace(/[\u201c\u201d"]/g,'"').replace(/[\u2018\u2019']/g,"'"),X=Z($),Q=Z(Y);if(X===Q)return 1;let J=X.length,q=Q.length;if(J===0)return q===0?1:0;if(q===0)return 0;let K=200,G=X.substring(0,K),U=Q.substring(0,K),O=gG(G,U),W=Math.max(G.length,U.length);return 1-O/W}function gG($,Y){let Z=$.length,X=Y.length,Q=Array(Z+1).fill(null).map(()=>Array(X+1).fill(0));for(let J=0;J<=Z;J++)Q[J][0]=J;for(let J=0;J<=X;J++)Q[0][J]=J;for(let J=1;J<=Z;J++)for(let q=1;q<=X;q++){let K=$[J-1]===Y[q-1]?0:1;Q[J][q]=Math.min(Q[J-1][q]+1,Q[J][q-1]+1,Q[J-1][q-1]+K)}return Q[Z][X]}var h9;var fY=b(()=>{v$();E$();m1();Z0();S2();k9();vY();R4();f9();h9=U1({name:"Edit",displayName:"File Edit",kind:"write",strict:!0,isConcurrencySafe:!1,schema:V4.object({file_path:I1.filePath({description:"Absolute path of the file to edit"}),old_string:V4.string().min(1,"old_string cannot be empty").describe("String to replace"),new_string:V4.string().describe("Replacement string (can be empty)"),replace_all:V4.boolean().default(!1).describe("Replace all matches (default: first only)")}),description:{short:"Performs exact string replacements in files",long:"Performs exact string replacements in files.",usageNotes:["You must use your Read tool at least once in the conversation before editing. This tool will error if you attempt an edit without reading the file.","When editing text from Read tool output, ensure you preserve the exact indentation (tabs/spaces) as it appears AFTER the line number prefix. The line number prefix format is: spaces + line number + tab. Everything after that tab is the actual file content to match. Never include any part of the line number prefix in the old_string or new_string.","ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.","Only use emojis if the user explicitly requests it. Avoid adding emojis to files unless asked.","The edit will FAIL if old_string is not unique in the file. Either provide a larger string with more surrounding context to make it unique or use replace_all to change every instance of old_string.","Use replace_all for replacing and renaming strings across the file. This parameter is useful if you want to rename a variable for instance."]},async execute($,Y){let{file_path:Z,old_string:X,new_string:Q,replace_all:J}=$,{updateOutput:q,sessionId:K,messageId:G}=Y,U=Y.signal??new AbortController().signal;try{q?.("Starting to read file...");let O=y$(),W=T2(),F;try{if(W)q?.("通过 IDE 读取文件...");F=await O.readTextFile(Z)}catch(R){if(R.code==="ENOENT"||R.message?.includes("not found"))return{success:!1,llmContent:`File not found: ${Z}`,displayContent:`❌ 文件不存在: ${Z}`,error:{type:"execution_error",message:"文件不存在"}};throw R}if(U.throwIfAborted(),K){let R=z0.getInstance();if(!R.hasFileBeenRead(Z,K))return{success:!1,llmContent:"You must use your Read tool at least once in the conversation before editing. This tool will error if you attempt an edit without reading the file.",displayContent:`❌ 编辑失败:必须先使用 Read 工具读取文件
699
701
 
700
702
  请先用 Read 工具查看文件内容,再进行编辑。`,error:{type:"validation_error",message:"File not read before edit"}};let E=await R.checkExternalModification(Z);if(E.isExternal)return{success:!1,llmContent:`The file has been modified by an external program since you last read it. You must use the Read tool again to see the current content before editing.
701
703
 
@@ -703,27 +705,27 @@ Details: ${E.message}`,displayContent:`❌ 编辑失败:文件已被外部程
703
705
 
704
706
  ${E.message}
705
707
 
706
- \uD83D\uDCA1 请重新使用 Read 工具读取最新内容后再编辑`,error:{type:"validation_error",message:"File modified externally",details:{externalModification:E.message}}}}if(G&&K)try{let R=new L6({sessionId:G});await R.initialize(),await R.createSnapshot(Z,K)}catch(R){console.warn("[EditTool] 创建快照失败:",R)}if(X===Q)return{success:!1,llmContent:"New string is identical; no replacement needed",displayContent:"⚠️ 新字符串与旧字符串相同,无需进行替换",error:{type:"validation_error",message:"新旧字符串相同"}};let H=zK(F,X);if(!H.matched){let R=LK(F,X,Z);return{success:!1,llmContent:R.llmContent,displayContent:R.displayContent,error:{type:"execution_error",message:"未找到匹配内容",details:R.metadata}}}let _=H.matched;if(H.strategy!=="exact")console.log(`[SmartEdit] 使用策略: ${H.strategy}`);let z=NK(F,_);if(z.length>1&&!J){let R=F.split(`
707
- `),E=0,x=[];for(let C=0;C<R.length;C++){let Y1=R[C],k=E,S=E+Y1.length;for(let y of z)if(y>=k&&y<S){let v1=Math.max(0,C-1),m=Math.min(R.length-1,C+1),_1=R.slice(v1,m+1).map((g)=>g.trim()).join(" ").slice(0,80);x.push({line:C+1,column:y-k+1,context:_1})}E=S+1}let r=[`⚠️ EDIT PAUSED: old_string matches ${z.length} locations (must be unique).`,"","**Matches found at:**",...x.map((C,Y1)=>` ${Y1+1}. Line ${C.line}`),"","**Action Required:** Add 3-5 lines of surrounding context to make old_string unique.","","**Tips for quick success:**","• Include the function/class name that wraps the target code","• Add 2-3 lines before and after the target","• Include unique comments or variable names nearby",`• Or use replace_all=true to change all ${z.length} occurrences`,"","\uD83E\uDD16 **Auto-retry expected** - This usually resolves in 1-2 attempts."].join(`
708
- `),j=["⚠️ 编辑暂停:需要更精确的定位","",`在文件中找到 ${z.length} 处相似代码:`,...x.map((C,Y1)=>` • 第 ${C.line} 行 (匹配 ${Y1+1}/${z.length})`),"","AI 正在自动调整,添加更多上下文以精确定位...","通常需要 1-2 次尝试即可成功","","\uD83D\uDCA1 如果多次失败,可能需要:"," • 包含函数/类名等独特标识符"," • 添加目标代码前后 3-5 行完整上下文",` • 或使用 replace_all=true 同时替换所有 ${z.length} 处匹配`].join(`
709
- `);return{success:!1,llmContent:r,displayContent:j,error:{type:"validation_error",message:"old_string is not unique",details:{matches:x.map((C)=>({line:C.line,column:C.column})),count:z.length}}}}else q?.(`找到 ${z.length} 个匹配项,开始替换...`);let L,B;if(J)L=F.split(_).join(Q),B=z.length;else{let R=F.indexOf(_);L=F.substring(0,R)+Q+F.substring(R+_.length),B=1}if(W.throwIfAborted(),U)q?.("通过 IDE 写入文件...");if(await O.writeTextFile(Z,L),G)await O0.getInstance().recordFileEdit(Z,G,"edit");let N=await O.stat(Z),I=UY(F,L,_,Q,4),M=Z.split("/").pop()||Z,A=B===1?`替换 1 处匹配到 ${M}`:`替换 ${B} 处匹配到 ${M}`,D={file_path:Z,matches_found:z.length,replacements_made:B,replace_all:J,old_string_length:X.length,new_string_length:Q.length,original_size:F.length,new_size:L.length,size_diff:L.length-F.length,last_modified:N?.mtime instanceof Date?N.mtime.toISOString():void 0,snapshot_created:!!(G&&K),session_id:G,message_id:K,diff_snippet:I,summary:A,kind:"edit",oldContent:F,newContent:L},w=BK(D,I);return{success:!0,llmContent:{file_path:Z,replacements:B,total_matches:z.length},displayContent:w,metadata:D}}catch(O){if(O.name==="AbortError")return{success:!1,llmContent:"File edit aborted",displayContent:"⚠️ 文件编辑被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`File edit failed: ${O.message}`,displayContent:`❌ 编辑文件失败: ${O.message}`,error:{type:"execution_error",message:O.message,details:O}}}},version:"2.0.0",category:"文件操作",tags:["file","edit","replace","modify"],extractSignatureContent:($)=>$.file_path,abstractPermissionRule:($)=>{let Y=_K($.file_path);return Y?`**/*${Y}`:"**/*"}})});import{extname as wY}from"path";import{z as bK}from"zod";function RK($){return[".txt",".md",".js",".ts",".jsx",".tsx",".json",".xml",".html",".htm",".css",".scss",".sass",".less",".yml",".yaml",".toml",".ini",".cfg",".py",".rb",".php",".java",".cpp",".c",".h",".hpp",".rs",".go",".sh",".bash",".zsh",".fish",".ps1",".bat",".cmd",".sql",".graphql",".vue",".svelte",".astro",".dockerfile",".gitignore",".env"].includes($)||$===""}function VK($){return[".jpg",".jpeg",".png",".gif",".bmp",".svg",".ico",".webp",".mp3",".wav",".mp4",".avi",".mov",".wmv",".flv",".webm",".pdf",".doc",".docx",".xls",".xlsx",".ppt",".pptx",".zip",".tar",".gz",".rar",".7z",".exe",".dll",".so",".ttf",".otf",".woff",".woff2",".eot"].includes($)}function DK($,Y){let Z=`✅ 成功读取文件: ${$}`;if(Y.file_size!==void 0)Z+=` (${IK(Y.file_size)})`;if(Y.lines_read!==void 0)Z+=`
708
+ \uD83D\uDCA1 请重新使用 Read 工具读取最新内容后再编辑`,error:{type:"validation_error",message:"File modified externally",details:{externalModification:E.message}}}}if(K&&G)try{let R=new b6({sessionId:K});await R.initialize(),await R.createSnapshot(Z,G)}catch(R){console.warn("[EditTool] 创建快照失败:",R)}if(X===Q)return{success:!1,llmContent:"New string is identical; no replacement needed",displayContent:"⚠️ 新字符串与旧字符串相同,无需进行替换",error:{type:"validation_error",message:"新旧字符串相同"}};let H=fG(F,X);if(!H.matched){let R=pG(F,X,Z);return{success:!1,llmContent:R.llmContent,displayContent:R.displayContent,error:{type:"execution_error",message:"未找到匹配内容",details:R.metadata}}}let z=H.matched;if(H.strategy!=="exact")console.log(`[SmartEdit] 使用策略: ${H.strategy}`);let N=hG(F,z);if(N.length>1&&!J){let R=F.split(`
709
+ `),E=0,x=[];for(let k=0;k<R.length;k++){let n=R[k],T=E,C=E+n.length;for(let j of N)if(j>=T&&j<C){let S1=Math.max(0,k-1),d=Math.min(R.length-1,k+1),B1=R.slice(S1,d+1).map((g)=>g.trim()).join(" ").slice(0,80);x.push({line:k+1,column:j-T+1,context:B1})}E=C+1}let r=[`⚠️ EDIT PAUSED: old_string matches ${N.length} locations (must be unique).`,"","**Matches found at:**",...x.map((k,n)=>` ${n+1}. Line ${k.line}`),"","**Action Required:** Add 3-5 lines of surrounding context to make old_string unique.","","**Tips for quick success:**","• Include the function/class name that wraps the target code","• Add 2-3 lines before and after the target","• Include unique comments or variable names nearby",`• Or use replace_all=true to change all ${N.length} occurrences`,"","\uD83E\uDD16 **Auto-retry expected** - This usually resolves in 1-2 attempts."].join(`
710
+ `),P=["⚠️ 编辑暂停:需要更精确的定位","",`在文件中找到 ${N.length} 处相似代码:`,...x.map((k,n)=>` • 第 ${k.line} 行 (匹配 ${n+1}/${N.length})`),"","AI 正在自动调整,添加更多上下文以精确定位...","通常需要 1-2 次尝试即可成功","","\uD83D\uDCA1 如果多次失败,可能需要:"," • 包含函数/类名等独特标识符"," • 添加目标代码前后 3-5 行完整上下文",` • 或使用 replace_all=true 同时替换所有 ${N.length} 处匹配`].join(`
711
+ `);return{success:!1,llmContent:r,displayContent:P,error:{type:"validation_error",message:"old_string is not unique",details:{matches:x.map((k)=>({line:k.line,column:k.column})),count:N.length}}}}else q?.(`找到 ${N.length} 个匹配项,开始替换...`);let L,B;if(J)L=F.split(z).join(Q),B=N.length;else{let R=F.indexOf(z);L=F.substring(0,R)+Q+F.substring(R+z.length),B=1}if(U.throwIfAborted(),W)q?.("通过 IDE 写入文件...");if(await O.writeTextFile(Z,L),K)await z0.getInstance().recordFileEdit(Z,K,"edit");let _=await O.stat(Z),I=jY(F,L,z,Q,4),M=Z.split("/").pop()||Z,A=B===1?`替换 1 处匹配到 ${M}`:`替换 ${B} 处匹配到 ${M}`,D={file_path:Z,matches_found:N.length,replacements_made:B,replace_all:J,old_string_length:X.length,new_string_length:Q.length,original_size:F.length,new_size:L.length,size_diff:L.length-F.length,last_modified:_?.mtime instanceof Date?_.mtime.toISOString():void 0,snapshot_created:!!(K&&G),session_id:K,message_id:G,diff_snippet:I,summary:A,kind:"edit",oldContent:F,newContent:L},w=xG(D,I);return{success:!0,llmContent:{file_path:Z,replacements:B,total_matches:N.length},displayContent:w,metadata:D}}catch(O){if(O.name==="AbortError")return{success:!1,llmContent:"File edit aborted",displayContent:"⚠️ 文件编辑被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`File edit failed: ${O.message}`,displayContent:`❌ 编辑文件失败: ${O.message}`,error:{type:"execution_error",message:O.message,details:O}}}},version:"2.0.0",category:"文件操作",tags:["file","edit","replace","modify"],extractSignatureContent:($)=>$.file_path,abstractPermissionRule:($)=>{let Y=CG($.file_path);return Y?`**/*${Y}`:"**/*"}})});import{extname as hY}from"path";import{z as dG}from"zod";function mG($){return[".txt",".md",".js",".ts",".jsx",".tsx",".json",".xml",".html",".htm",".css",".scss",".sass",".less",".yml",".yaml",".toml",".ini",".cfg",".py",".rb",".php",".java",".cpp",".c",".h",".hpp",".rs",".go",".sh",".bash",".zsh",".fish",".ps1",".bat",".cmd",".sql",".graphql",".vue",".svelte",".astro",".dockerfile",".gitignore",".env"].includes($)||$===""}function cG($){return[".jpg",".jpeg",".png",".gif",".bmp",".svg",".ico",".webp",".mp3",".wav",".mp4",".avi",".mov",".wmv",".flv",".webm",".pdf",".doc",".docx",".xls",".xlsx",".ppt",".pptx",".zip",".tar",".gz",".rar",".7z",".exe",".dll",".so",".ttf",".otf",".woff",".woff2",".eot"].includes($)}function lG($,Y){let Z=`✅ 成功读取文件: ${$}`;if(Y.file_size!==void 0)Z+=` (${iG(Y.file_size)})`;if(Y.lines_read!==void 0)Z+=`
710
712
  \uD83D\uDCC4 读取了 ${Y.lines_read} 行 (第${Y.start_line}-${Y.end_line}行,共${Y.total_lines}行)`;if(Y.is_binary)Z+=`
711
- \uD83D\uDD10 文件以 base64 编码显示`;return Z}function IK($){let Y=["B","KB","MB","GB"],Z=$,X=0;while(Z>=1024&&X<Y.length-1)Z/=1024,X++;return`${Z.toFixed(1)}${Y[X]}`}var v8;var AY=b(()=>{j$();M$();g1();e1();E2();w4();v8=U1({name:"Read",displayName:"File Read",kind:"readonly",schema:bK.object({file_path:b1.filePath({description:"File path to read (must be absolute)"}),offset:b1.lineNumber({description:"Starting line number (0-based, text files only)"}).optional(),limit:b1.lineLimit({description:"Number of lines to read (text files only)"}).optional(),encoding:b1.encoding()}),description:{short:"Read files from the local filesystem",long:"Reads a file from the local filesystem. You can access any file directly by using this tool. Assume this tool is able to read all files on the machine. If the User provides a path to a file assume that path is valid. It is okay to read a file that does not exist; an error will be returned.",usageNotes:["The file_path parameter must be an absolute path, not a relative path","By default, it reads up to 2000 lines starting from the beginning of the file","You can optionally specify a line offset and limit (especially handy for long files), but it's recommended to read the whole file by not providing these parameters","Any lines longer than 2000 characters will be truncated","Results are returned using cat -n format, with line numbers starting at 1","This tool allows reading images (eg PNG, JPG, etc). When reading an image file the contents are presented visually as this is a multimodal LLM.","This tool can read PDF files (.pdf). PDFs are processed page by page, extracting both text and visual content for analysis.","This tool can read Jupyter notebooks (.ipynb files) and returns all cells with their outputs, combining code, text, and visualizations.","This tool can only read files, not directories. To read a directory, use an ls command via the Bash tool.","You can call multiple tools in a single response. It is always better to speculatively read multiple potentially useful files in parallel.","You will regularly be asked to read screenshots. If the user provides a path to a screenshot, ALWAYS use this tool to view the file at the path. This tool will work with all temporary file paths.","If you read a file that exists but has empty contents you will receive a system reminder warning in place of file contents."],examples:[{description:"Read the entire file (recommended)",params:{file_path:"/path/to/file.ts"}},{description:"Read the first 100 lines",params:{file_path:"/path/to/file.txt",limit:100}},{description:"Read 100 lines starting at line 50 (large file)",params:{file_path:"/path/to/large-file.log",offset:50,limit:100}}],important:["file_path must be absolute","Prefer reading the entire file (omit offset and limit)","Use offset/limit only for very large files","Line numbers start at 1 (cat -n format)"]},async execute($,Y){let{file_path:Z,offset:X,limit:Q,encoding:J="utf8"}=$,{updateOutput:q,sessionId:G}=Y,K=Y.signal??new AbortController().signal;try{q?.("Starting file read...");let W=I$(),O=v2();try{if(!await W.exists(Z))throw Error("File not found")}catch(A){return{success:!1,llmContent:`File not found: ${Z}`,displayContent:`❌ 文件不存在: ${Z}`,error:{type:"execution_error",message:`File not found: ${Z}`}}}if(K.throwIfAborted(),G)await O0.getInstance().recordFileRead(Z,G);let U=await W.stat(Z);if(U?.isDirectory)return{success:!1,llmContent:`Cannot read a directory: ${Z}`,displayContent:`❌ 无法读取目录: ${Z}`,error:{type:"execution_error",message:"Target is a directory, not a file"}};let F=wY(Z).toLowerCase(),H=RK(F),_=VK(F),z,L={file_path:Z,file_size:U?.size,file_type:F,last_modified:U?.mtime instanceof Date?U.mtime.toISOString():void 0,encoding:J,acp_mode:O};if(_&&J==="utf8"){if(O)q?.("⚠️ 二进制文件通过本地读取(ACP 不支持)..."),L.acp_fallback=!0;else q?.("检测到二进制文件,使用 base64 编码...");z=(await W.readBinaryFile(Z)).toString("base64"),L.encoding="base64",L.is_binary=!0}else if(H){if(O)q?.("通过 IDE 读取文件...");z=await W.readTextFile(Z)}else{if(O)L.acp_fallback=!0;let A=await W.readBinaryFile(Z);if(J==="base64")z=A.toString("base64");else if(J==="binary")z=A.toString("binary");else z=A.toString("utf8")}if(K.throwIfAborted(),(X!==void 0||Q!==void 0)&&J==="utf8"&&H){let A=z.split(`
712
- `),D=X||0,w=Q!==void 0?D+Q:A.length,R=A.slice(D,w);z=R.map((E,x)=>{let r=D+x+1,j=E.length>2000?`${E.substring(0,2000)}...`:E;return`${r.toString().padStart(6)}→${j}`}).join(`
713
- `),L.lines_read=R.length,L.total_lines=A.length,L.start_line=D+1,L.end_line=Math.min(w,A.length)}let B=Z.split("/").pop()||Z,N=L.lines_read||L.total_lines,I=N?`读取 ${N} 行从 ${B}`:`读取 ${B}`;L.summary=I;let M=DK(Z,L);return{success:!0,llmContent:z,displayContent:M,metadata:L}}catch(W){if(W.name==="AbortError")return{success:!1,llmContent:"File read aborted",displayContent:"⚠️ 文件读取被用户中止",error:{type:"execution_error",message:"Operation aborted"}};return{success:!1,llmContent:`File read failed: ${W.message}`,displayContent:`❌ 读取文件失败: ${W.message}`,error:{type:"execution_error",message:W.message,details:W}}}},version:"2.0.0",category:"文件操作",tags:["file","io","read"],extractSignatureContent:($)=>$.file_path,abstractPermissionRule:($)=>{let Y=wY($.file_path);return Y?`**/*${Y}`:"**/*"}})});import{promises as MK}from"fs";import{dirname as jK,extname as bY}from"path";import{z as E8}from"zod";function yK($,Y,Z,X){let Q=`✅ 成功写入文件: ${$}`;if(Y.file_size!==void 0)Q+=` (${RY(Y.file_size)})`;if(Y.snapshot_created)Q+=`
713
+ \uD83D\uDD10 文件以 base64 编码显示`;return Z}function iG($){let Y=["B","KB","MB","GB"],Z=$,X=0;while(Z>=1024&&X<Y.length-1)Z/=1024,X++;return`${Z.toFixed(1)}${Y[X]}`}var x9;var xY=b(()=>{v$();E$();m1();Z0();S2();R4();x9=U1({name:"Read",displayName:"File Read",kind:"readonly",schema:dG.object({file_path:I1.filePath({description:"File path to read (must be absolute)"}),offset:I1.lineNumber({description:"Starting line number (0-based, text files only)"}).optional(),limit:I1.lineLimit({description:"Number of lines to read (text files only)"}).optional(),encoding:I1.encoding()}),description:{short:"Read files from the local filesystem",long:"Reads a file from the local filesystem. You can access any file directly by using this tool. Assume this tool is able to read all files on the machine. If the User provides a path to a file assume that path is valid. It is okay to read a file that does not exist; an error will be returned.",usageNotes:["The file_path parameter must be an absolute path, not a relative path","By default, it reads up to 2000 lines starting from the beginning of the file","You can optionally specify a line offset and limit (especially handy for long files), but it's recommended to read the whole file by not providing these parameters","Any lines longer than 2000 characters will be truncated","Results are returned using cat -n format, with line numbers starting at 1","This tool allows reading images (eg PNG, JPG, etc). When reading an image file the contents are presented visually as this is a multimodal LLM.","This tool can read PDF files (.pdf). PDFs are processed page by page, extracting both text and visual content for analysis.","This tool can read Jupyter notebooks (.ipynb files) and returns all cells with their outputs, combining code, text, and visualizations.","This tool can only read files, not directories. To read a directory, use an ls command via the Bash tool.","You can call multiple tools in a single response. It is always better to speculatively read multiple potentially useful files in parallel.","You will regularly be asked to read screenshots. If the user provides a path to a screenshot, ALWAYS use this tool to view the file at the path. This tool will work with all temporary file paths.","If you read a file that exists but has empty contents you will receive a system reminder warning in place of file contents."],examples:[{description:"Read the entire file (recommended)",params:{file_path:"/path/to/file.ts"}},{description:"Read the first 100 lines",params:{file_path:"/path/to/file.txt",limit:100}},{description:"Read 100 lines starting at line 50 (large file)",params:{file_path:"/path/to/large-file.log",offset:50,limit:100}}],important:["file_path must be absolute","Prefer reading the entire file (omit offset and limit)","Use offset/limit only for very large files","Line numbers start at 1 (cat -n format)"]},async execute($,Y){let{file_path:Z,offset:X,limit:Q,encoding:J="utf8"}=$,{updateOutput:q,sessionId:K}=Y,G=Y.signal??new AbortController().signal;try{q?.("Starting file read...");let U=y$(),O=T2();try{if(!await U.exists(Z))throw Error("File not found")}catch(A){return{success:!1,llmContent:`File not found: ${Z}`,displayContent:`❌ 文件不存在: ${Z}`,error:{type:"execution_error",message:`File not found: ${Z}`}}}if(G.throwIfAborted(),K)await z0.getInstance().recordFileRead(Z,K);let W=await U.stat(Z);if(W?.isDirectory)return{success:!1,llmContent:`Cannot read a directory: ${Z}`,displayContent:`❌ 无法读取目录: ${Z}`,error:{type:"execution_error",message:"Target is a directory, not a file"}};let F=hY(Z).toLowerCase(),H=mG(F),z=cG(F),N,L={file_path:Z,file_size:W?.size,file_type:F,last_modified:W?.mtime instanceof Date?W.mtime.toISOString():void 0,encoding:J,acp_mode:O};if(z&&J==="utf8"){if(O)q?.("⚠️ 二进制文件通过本地读取(ACP 不支持)..."),L.acp_fallback=!0;else q?.("检测到二进制文件,使用 base64 编码...");N=(await U.readBinaryFile(Z)).toString("base64"),L.encoding="base64",L.is_binary=!0}else if(H){if(O)q?.("通过 IDE 读取文件...");N=await U.readTextFile(Z)}else{if(O)L.acp_fallback=!0;let A=await U.readBinaryFile(Z);if(J==="base64")N=A.toString("base64");else if(J==="binary")N=A.toString("binary");else N=A.toString("utf8")}if(G.throwIfAborted(),(X!==void 0||Q!==void 0)&&J==="utf8"&&H){let A=N.split(`
714
+ `),D=X||0,w=Q!==void 0?D+Q:A.length,R=A.slice(D,w);N=R.map((E,x)=>{let r=D+x+1,P=E.length>2000?`${E.substring(0,2000)}...`:E;return`${r.toString().padStart(6)}→${P}`}).join(`
715
+ `),L.lines_read=R.length,L.total_lines=A.length,L.start_line=D+1,L.end_line=Math.min(w,A.length)}let B=Z.split("/").pop()||Z,_=L.lines_read||L.total_lines,I=_?`读取 ${_} 行从 ${B}`:`读取 ${B}`;L.summary=I;let M=lG(Z,L);return{success:!0,llmContent:N,displayContent:M,metadata:L}}catch(U){if(U.name==="AbortError")return{success:!1,llmContent:"File read aborted",displayContent:"⚠️ 文件读取被用户中止",error:{type:"execution_error",message:"Operation aborted"}};return{success:!1,llmContent:`File read failed: ${U.message}`,displayContent:`❌ 读取文件失败: ${U.message}`,error:{type:"execution_error",message:U.message,details:U}}}},version:"2.0.0",category:"文件操作",tags:["file","io","read"],extractSignatureContent:($)=>$.file_path,abstractPermissionRule:($)=>{let Y=hY($.file_path);return Y?`**/*${Y}`:"**/*"}})});import{promises as rG}from"fs";import{dirname as aG,extname as pY}from"path";import{z as p9}from"zod";function nG($,Y,Z,X){let Q=`✅ 成功写入文件: ${$}`;if(Y.file_size!==void 0)Q+=` (${uY(Y.file_size)})`;if(Y.snapshot_created)Q+=`
714
716
  \uD83D\uDCF8 已创建快照 (可回滚)`;if(Y.encoding!=="utf8")Q+=`
715
- \uD83D\uDD10 使用编码: ${Y.encoding}`;if(X)Q+=X;if(Z&&Y.encoding==="utf8"&&!X){let J=vK($,Z);if(J)Q+=`
717
+ \uD83D\uDD10 使用编码: ${Y.encoding}`;if(X)Q+=X;if(Z&&Y.encoding==="utf8"&&!X){let J=oG($,Z);if(J)Q+=`
716
718
 
717
- `+J}return Q}function vK($,Y){let Z=bY($).toLowerCase(),Q={".ts":"typescript",".tsx":"tsx",".js":"javascript",".jsx":"jsx",".py":"python",".go":"go",".rs":"rust",".java":"java",".c":"c",".cpp":"cpp",".h":"c",".hpp":"cpp",".cs":"csharp",".rb":"ruby",".php":"php",".swift":"swift",".kt":"kotlin",".scala":"scala",".sh":"bash",".bash":"bash",".zsh":"zsh",".json":"json",".yaml":"yaml",".yml":"yaml",".toml":"toml",".xml":"xml",".html":"html",".css":"css",".scss":"scss",".sass":"sass",".less":"less",".md":"markdown",".sql":"sql",".graphql":"graphql",".proto":"protobuf"}[Z]||"",J=100,q=5000,G=Y,K=!1,W=Y.split(`
718
- `);if(W.length>100)G=W.slice(0,100).join(`
719
- `),K=!0;if(G.length>5000)G=G.substring(0,5000),K=!0;let O=`\uD83D\uDCC4 文件内容:
719
+ `+J}return Q}function oG($,Y){let Z=pY($).toLowerCase(),Q={".ts":"typescript",".tsx":"tsx",".js":"javascript",".jsx":"jsx",".py":"python",".go":"go",".rs":"rust",".java":"java",".c":"c",".cpp":"cpp",".h":"c",".hpp":"cpp",".cs":"csharp",".rb":"ruby",".php":"php",".swift":"swift",".kt":"kotlin",".scala":"scala",".sh":"bash",".bash":"bash",".zsh":"zsh",".json":"json",".yaml":"yaml",".yml":"yaml",".toml":"toml",".xml":"xml",".html":"html",".css":"css",".scss":"scss",".sass":"sass",".less":"less",".md":"markdown",".sql":"sql",".graphql":"graphql",".proto":"protobuf"}[Z]||"",J=100,q=5000,K=Y,G=!1,U=Y.split(`
720
+ `);if(U.length>100)K=U.slice(0,100).join(`
721
+ `),G=!0;if(K.length>5000)K=K.substring(0,5000),G=!0;let O=`\uD83D\uDCC4 文件内容:
720
722
 
721
723
  `;if(O+="```"+Q+`
722
- `,O+=G,!G.endsWith(`
724
+ `,O+=K,!K.endsWith(`
723
725
  `))O+=`
724
- `;if(O+="```",K)O+=`
726
+ `;if(O+="```",G)O+=`
725
727
 
726
- ⚠️ 内容已截断(完整文件共 ${W.length} 行,${Y.length} 字符)`;return O}function RY($){let Y=["B","KB","MB","GB"],Z=$,X=0;while(Z>=1024&&X<Y.length-1)Z/=1024,X++;return`${Z.toFixed(1)}${Y[X]}`}var P8;var VY=b(()=>{j$();M$();g1();e1();E2();I8();w4();j8();P8=U1({name:"Write",displayName:"File Write",kind:"write",strict:!0,isConcurrencySafe:!1,schema:E8.object({file_path:b1.filePath({description:"Absolute file path to write"}),content:E8.string().describe("Content to write"),encoding:b1.encoding(),create_directories:E8.boolean().default(!0).describe("Automatically create missing parent directories")}),description:{short:"Writes a file to the local filesystem",long:"Writes a file to the local filesystem.",usageNotes:["This tool will overwrite the existing file if there is one at the provided path.","If this is an existing file, you MUST use the Read tool first to read the file's contents. This tool will fail if you did not read the file first.","ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.","NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User.","Only use emojis if the user explicitly requests it. Avoid writing emojis to files unless asked."]},async execute($,Y){let{file_path:Z,content:X,encoding:Q,create_directories:J}=$,{updateOutput:q,sessionId:G,messageId:K}=Y,W=Y.signal??new AbortController().signal;try{q?.("开始写入文件...");let O=I$(),U=v2();if(J){let A=jK(Z);try{await O.mkdir(A,{recursive:!0})}catch(D){if(D.code!=="EEXIST")throw D}}W.throwIfAborted();let F=!1,H=null;try{if(F=await O.exists(Z),F&&Q==="utf8")try{H=await O.readTextFile(Z)}catch(A){console.warn("[WriteTool] 读取旧文件内容失败:",A)}}catch{}if(F&&G){let A=O0.getInstance();if(!A.hasFileBeenRead(Z,G))return{success:!1,llmContent:"If this is an existing file, you MUST use the Read tool first to read the file's contents. This tool will fail if you did not read the file first.",displayContent:`❌ 写入失败:必须先使用 Read 工具读取文件
728
+ ⚠️ 内容已截断(完整文件共 ${U.length} 行,${Y.length} 字符)`;return O}function uY($){let Y=["B","KB","MB","GB"],Z=$,X=0;while(Z>=1024&&X<Y.length-1)Z/=1024,X++;return`${Z.toFixed(1)}${Y[X]}`}var u9;var gY=b(()=>{v$();E$();m1();Z0();S2();k9();R4();f9();u9=U1({name:"Write",displayName:"File Write",kind:"write",strict:!0,isConcurrencySafe:!1,schema:p9.object({file_path:I1.filePath({description:"Absolute file path to write"}),content:p9.string().describe("Content to write"),encoding:I1.encoding(),create_directories:p9.boolean().default(!0).describe("Automatically create missing parent directories")}),description:{short:"Writes a file to the local filesystem",long:"Writes a file to the local filesystem.",usageNotes:["This tool will overwrite the existing file if there is one at the provided path.","If this is an existing file, you MUST use the Read tool first to read the file's contents. This tool will fail if you did not read the file first.","ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.","NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User.","Only use emojis if the user explicitly requests it. Avoid writing emojis to files unless asked."]},async execute($,Y){let{file_path:Z,content:X,encoding:Q,create_directories:J}=$,{updateOutput:q,sessionId:K,messageId:G}=Y,U=Y.signal??new AbortController().signal;try{q?.("开始写入文件...");let O=y$(),W=T2();if(J){let A=aG(Z);try{await O.mkdir(A,{recursive:!0})}catch(D){if(D.code!=="EEXIST")throw D}}U.throwIfAborted();let F=!1,H=null;try{if(F=await O.exists(Z),F&&Q==="utf8")try{H=await O.readTextFile(Z)}catch(A){console.warn("[WriteTool] 读取旧文件内容失败:",A)}}catch{}if(F&&K){let A=z0.getInstance();if(!A.hasFileBeenRead(Z,K))return{success:!1,llmContent:"If this is an existing file, you MUST use the Read tool first to read the file's contents. This tool will fail if you did not read the file first.",displayContent:`❌ 写入失败:必须先使用 Read 工具读取文件
727
729
 
728
730
  文件 ${Z} 已存在,请先用 Read 工具查看其内容。`,error:{type:"validation_error",message:"File not read before write"}};let D=await A.checkExternalModification(Z);if(D.isExternal)return{success:!1,llmContent:`The file has been modified by an external program since you last read it. You must use the Read tool again to see the current content before writing.
729
731
 
@@ -731,18 +733,18 @@ Details: ${D.message}`,displayContent:`❌ 写入失败:文件已被外部程
731
733
 
732
734
  ${D.message}
733
735
 
734
- \uD83D\uDCA1 请重新使用 Read 工具读取最新内容后再写入`,error:{type:"validation_error",message:"File modified externally",details:{externalModification:D.message}}}}let _=!1;if(F&&G&&K)try{let A=new L6({sessionId:G});await A.initialize(),await A.createSnapshot(Z,K),_=!0}catch(A){console.warn("[WriteTool] 创建快照失败:",A)}if(W.throwIfAborted(),Q==="utf8"){if(U)q?.("通过 IDE 写入文件...");await O.writeTextFile(Z,X)}else{if(U)return{success:!1,llmContent:"Binary file writes are not supported in ACP mode. The IDE only supports text file operations. Please use encoding='utf8' for text files, or ask the user to write the file manually.",displayContent:`❌ ACP 模式不支持二进制文件写入
736
+ \uD83D\uDCA1 请重新使用 Read 工具读取最新内容后再写入`,error:{type:"validation_error",message:"File modified externally",details:{externalModification:D.message}}}}let z=!1;if(F&&K&&G)try{let A=new b6({sessionId:K});await A.initialize(),await A.createSnapshot(Z,G),z=!0}catch(A){console.warn("[WriteTool] 创建快照失败:",A)}if(U.throwIfAborted(),Q==="utf8"){if(W)q?.("通过 IDE 写入文件...");await O.writeTextFile(Z,X)}else{if(W)return{success:!1,llmContent:"Binary file writes are not supported in ACP mode. The IDE only supports text file operations. Please use encoding='utf8' for text files, or ask the user to write the file manually.",displayContent:`❌ ACP 模式不支持二进制文件写入
735
737
 
736
738
  当前通过 IDE 执行文件操作,但 IDE 仅支持文本文件。
737
739
 
738
740
  \uD83D\uDCA1 建议:
739
741
  • 如果是文本文件,使用 encoding='utf8'
740
- • 如果必须写入二进制文件,请在本地终端执行`,error:{type:"validation_error",message:"Binary writes not supported in ACP mode"}};let A;if(Q==="base64")A=Buffer.from(X,"base64");else if(Q==="binary")A=Buffer.from(X,"binary");else A=Buffer.from(X,"utf8");await MK.writeFile(Z,A)}if(G)await O0.getInstance().recordFileEdit(Z,G,"write");W.throwIfAborted();let z=await O.stat(Z),L=Q==="utf8"?X.split(`
741
- `).length:0,B=Z.split("/").pop()||Z,N=null;if(H&&Q==="utf8"&&H!==X){if(H.length<1048576&&X.length<1048576)N=KY(H,X,4)}let I={file_path:Z,content_size:X.length,file_size:z?.size,encoding:Q,created_directories:J,snapshot_created:_,session_id:G,message_id:K,last_modified:z?.mtime instanceof Date?z.mtime.toISOString():void 0,has_diff:!!N,summary:Q==="utf8"?`写入 ${L} 行到 ${B}`:`写入 ${z?.size?RY(z.size):"unknown"} 到 ${B}`,kind:"edit",oldContent:H||"",newContent:Q==="utf8"?X:void 0},M=yK(Z,I,X,N);return{success:!0,llmContent:{file_path:Z,size:z?.size,modified:z?.mtime instanceof Date?z.mtime.toISOString():void 0},displayContent:M,metadata:I}}catch(O){if(O.name==="AbortError")return{success:!1,llmContent:"File write aborted",displayContent:"⚠️ 文件写入被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`File write failed: ${O.message}`,displayContent:`❌ 写入文件失败: ${O.message}`,error:{type:"execution_error",message:O.message,details:O}}}},version:"2.0.0",category:"文件操作",tags:["file","io","write","create"],extractSignatureContent:($)=>$.file_path,abstractPermissionRule:($)=>{let Y=bY($.file_path);return Y?`**/*${Y}`:"**/*"}})});var DY=b(()=>{LY();AY();VY()});import*as b4 from"fs/promises";import{z as v$}from"zod";var T8;var IY=b(()=>{g1();n0();T8=U1({name:"NotebookEdit",displayName:"Notebook Edit",kind:"write",schema:v$.object({notebook_path:v$.string().describe("The absolute path to the Jupyter notebook file to edit (must be absolute, not relative)"),cell_id:v$.string().optional().describe("The ID of the cell to edit. When inserting a new cell, the new cell will be inserted after the cell with this ID, or at the beginning if not specified."),new_source:v$.string().describe("The new source for the cell"),cell_type:v$.enum(["code","markdown"]).optional().describe("The type of the cell (code or markdown). If not specified, it defaults to the current cell type. If using edit_mode=insert, this is required."),edit_mode:v$.enum(["replace","insert","delete"]).optional().default("replace").describe("The type of edit to make (replace, insert, delete). Defaults to replace.")}),description:{short:"Completely replaces the contents of a specific cell in a Jupyter notebook",long:"Completely replaces the contents of a specific cell in a Jupyter notebook (.ipynb file) with new source. Jupyter notebooks are interactive documents that combine code, text, and visualizations, commonly used for data analysis and scientific computing. The notebook_path parameter must be an absolute path, not a relative path. The cell_number is 0-indexed. Use edit_mode=insert to add a new cell at the index specified by cell_number. Use edit_mode=delete to delete the cell at the index specified by cell_number."},async execute($,Y){let{notebook_path:Z,cell_id:X,new_source:Q,cell_type:J,edit_mode:q="replace"}=$;try{let G=await b4.readFile(Z,"utf-8"),K=JSON.parse(G);if(!K.cells||!Array.isArray(K.cells))return{success:!1,llmContent:"Invalid notebook format: no cells array found",displayContent:"Invalid notebook format",error:{type:"validation_error",message:"Invalid notebook format"}};let W=-1;if(X){if(W=K.cells.findIndex((U)=>U.id===X),W===-1&&q!=="insert")return{success:!1,llmContent:`Cell with ID "${X}" not found`,displayContent:"Cell not found",error:{type:"validation_error",message:`Cell ID "${X}" not found`}}}switch(q){case"replace":{if(W===-1)return{success:!1,llmContent:"Cell ID required for replace operation",displayContent:"Cell ID required",error:{type:"validation_error",message:"Cell ID required for replace"}};let U=K.cells[W];if(U.source=Q.split(`
742
- `).map((F,H,_)=>H<_.length-1?F+`
743
- `:F),J)U.cell_type=J;break}case"insert":{if(!J)return{success:!1,llmContent:"cell_type is required for insert operation",displayContent:"cell_type required",error:{type:"validation_error",message:"cell_type required for insert"}};let U={cell_type:J,source:Q.split(`
744
- `).map((H,_,z)=>_<z.length-1?H+`
745
- `:H),metadata:{},...J==="code"?{execution_count:null,outputs:[]}:{}},F=W===-1?0:W+1;K.cells.splice(F,0,U);break}case"delete":{if(W===-1)return{success:!1,llmContent:"Cell ID required for delete operation",displayContent:"Cell ID required",error:{type:"validation_error",message:"Cell ID required for delete"}};K.cells.splice(W,1);break}}await b4.writeFile(Z,JSON.stringify(K,null,2));let O=q==="replace"?"replaced":q==="insert"?"inserted":"deleted";return{success:!0,llmContent:`Successfully ${O} cell in ${Z}`,displayContent:`Cell ${O} in notebook`,metadata:{notebook_path:Z,edit_mode:q,cell_id:X}}}catch(G){let K=G instanceof Error?G.message:"Unknown error";return{success:!1,llmContent:`Failed to edit notebook: ${K}`,displayContent:"Notebook edit failed",error:{type:"execution_error",message:K}}}}})});var MY=b(()=>{IY()});import{z as EK}from"zod";var k8;var jY=b(()=>{g1();n0();k8=U1({name:"EnterPlanMode",displayName:"Enter Plan Mode",kind:"readonly",schema:EK.object({}),description:{short:"Use this tool to enter plan mode for complex tasks requiring careful planning",long:`Use this tool when you encounter a complex task that requires careful planning and exploration before implementation. This tool transitions you into plan mode where you can thoroughly explore the codebase and design an implementation approach.
742
+ • 如果必须写入二进制文件,请在本地终端执行`,error:{type:"validation_error",message:"Binary writes not supported in ACP mode"}};let A;if(Q==="base64")A=Buffer.from(X,"base64");else if(Q==="binary")A=Buffer.from(X,"binary");else A=Buffer.from(X,"utf8");await rG.writeFile(Z,A)}if(K)await z0.getInstance().recordFileEdit(Z,K,"write");U.throwIfAborted();let N=await O.stat(Z),L=Q==="utf8"?X.split(`
743
+ `).length:0,B=Z.split("/").pop()||Z,_=null;if(H&&Q==="utf8"&&H!==X){if(H.length<1048576&&X.length<1048576)_=MY(H,X,4)}let I={file_path:Z,content_size:X.length,file_size:N?.size,encoding:Q,created_directories:J,snapshot_created:z,session_id:K,message_id:G,last_modified:N?.mtime instanceof Date?N.mtime.toISOString():void 0,has_diff:!!_,summary:Q==="utf8"?`写入 ${L} 行到 ${B}`:`写入 ${N?.size?uY(N.size):"unknown"} 到 ${B}`,kind:"edit",oldContent:H||"",newContent:Q==="utf8"?X:void 0},M=nG(Z,I,X,_);return{success:!0,llmContent:{file_path:Z,size:N?.size,modified:N?.mtime instanceof Date?N.mtime.toISOString():void 0},displayContent:M,metadata:I}}catch(O){if(O.name==="AbortError")return{success:!1,llmContent:"File write aborted",displayContent:"⚠️ 文件写入被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`File write failed: ${O.message}`,displayContent:`❌ 写入文件失败: ${O.message}`,error:{type:"execution_error",message:O.message,details:O}}}},version:"2.0.0",category:"文件操作",tags:["file","io","write","create"],extractSignatureContent:($)=>$.file_path,abstractPermissionRule:($)=>{let Y=pY($.file_path);return Y?`**/*${Y}`:"**/*"}})});var dY=b(()=>{fY();xY();gY()});import*as D4 from"fs/promises";import{z as T$}from"zod";var g9;var mY=b(()=>{m1();t0();g9=U1({name:"NotebookEdit",displayName:"Notebook Edit",kind:"write",schema:T$.object({notebook_path:T$.string().describe("The absolute path to the Jupyter notebook file to edit (must be absolute, not relative)"),cell_id:T$.string().optional().describe("The ID of the cell to edit. When inserting a new cell, the new cell will be inserted after the cell with this ID, or at the beginning if not specified."),new_source:T$.string().describe("The new source for the cell"),cell_type:T$.enum(["code","markdown"]).optional().describe("The type of the cell (code or markdown). If not specified, it defaults to the current cell type. If using edit_mode=insert, this is required."),edit_mode:T$.enum(["replace","insert","delete"]).optional().default("replace").describe("The type of edit to make (replace, insert, delete). Defaults to replace.")}),description:{short:"Completely replaces the contents of a specific cell in a Jupyter notebook",long:"Completely replaces the contents of a specific cell in a Jupyter notebook (.ipynb file) with new source. Jupyter notebooks are interactive documents that combine code, text, and visualizations, commonly used for data analysis and scientific computing. The notebook_path parameter must be an absolute path, not a relative path. The cell_number is 0-indexed. Use edit_mode=insert to add a new cell at the index specified by cell_number. Use edit_mode=delete to delete the cell at the index specified by cell_number."},async execute($,Y){let{notebook_path:Z,cell_id:X,new_source:Q,cell_type:J,edit_mode:q="replace"}=$;try{let K=await D4.readFile(Z,"utf-8"),G=JSON.parse(K);if(!G.cells||!Array.isArray(G.cells))return{success:!1,llmContent:"Invalid notebook format: no cells array found",displayContent:"Invalid notebook format",error:{type:"validation_error",message:"Invalid notebook format"}};let U=-1;if(X){if(U=G.cells.findIndex((W)=>W.id===X),U===-1&&q!=="insert")return{success:!1,llmContent:`Cell with ID "${X}" not found`,displayContent:"Cell not found",error:{type:"validation_error",message:`Cell ID "${X}" not found`}}}switch(q){case"replace":{if(U===-1)return{success:!1,llmContent:"Cell ID required for replace operation",displayContent:"Cell ID required",error:{type:"validation_error",message:"Cell ID required for replace"}};let W=G.cells[U];if(W.source=Q.split(`
744
+ `).map((F,H,z)=>H<z.length-1?F+`
745
+ `:F),J)W.cell_type=J;break}case"insert":{if(!J)return{success:!1,llmContent:"cell_type is required for insert operation",displayContent:"cell_type required",error:{type:"validation_error",message:"cell_type required for insert"}};let W={cell_type:J,source:Q.split(`
746
+ `).map((H,z,N)=>z<N.length-1?H+`
747
+ `:H),metadata:{},...J==="code"?{execution_count:null,outputs:[]}:{}},F=U===-1?0:U+1;G.cells.splice(F,0,W);break}case"delete":{if(U===-1)return{success:!1,llmContent:"Cell ID required for delete operation",displayContent:"Cell ID required",error:{type:"validation_error",message:"Cell ID required for delete"}};G.cells.splice(U,1);break}}await D4.writeFile(Z,JSON.stringify(G,null,2));let O=q==="replace"?"replaced":q==="insert"?"inserted":"deleted";return{success:!0,llmContent:`Successfully ${O} cell in ${Z}`,displayContent:`Cell ${O} in notebook`,metadata:{notebook_path:Z,edit_mode:q,cell_id:X}}}catch(K){let G=K instanceof Error?K.message:"Unknown error";return{success:!1,llmContent:`Failed to edit notebook: ${G}`,displayContent:"Notebook edit failed",error:{type:"execution_error",message:G}}}}})});var cY=b(()=>{mY()});import{z as sG}from"zod";var d9;var lY=b(()=>{m1();t0();d9=U1({name:"EnterPlanMode",displayName:"Enter Plan Mode",kind:"readonly",schema:sG.object({}),description:{short:"Use this tool to enter plan mode for complex tasks requiring careful planning",long:`Use this tool when you encounter a complex task that requires careful planning and exploration before implementation. This tool transitions you into plan mode where you can thoroughly explore the codebase and design an implementation approach.
746
748
 
747
749
  ## When to Use This Tool
748
750
 
@@ -834,7 +836,7 @@ Begin your research now.`,displayContent:"✅ Entering Plan mode",metadata:{appr
834
836
 
835
837
  `+"Proceed with the task directly without planning phase. You can still use search tools to understand the codebase as needed, but implement the solution directly.",displayContent:"⚠️ Plan mode declined, proceeding directly",metadata:{approved:!1,enterPlanMode:!1}}}catch(Z){return{success:!1,llmContent:`Confirmation flow error: ${Z instanceof Error?Z.message:"Unknown error"}`,displayContent:"❌ Failed to request confirmation",error:{type:"execution_error",message:"Confirmation flow error"}}}return{success:!0,llmContent:`Plan mode requested but no interactive confirmation available.
836
838
 
837
- Proceeding with research phase. Use read-only tools to explore the codebase, then call ExitPlanMode with your implementation plan when ready.`,displayContent:"Plan mode (non-interactive)",metadata:{approved:null,enterPlanMode:!0}}}})});import{z as yY}from"zod";import{promises as vY}from"node:fs";import*as S8 from"node:path";import{homedir as PK}from"node:os";var C8;var EY=b(()=>{g1();n0();C8=U1({name:"ExitPlanMode",displayName:"Exit Plan Mode",kind:"readonly",schema:yY.object({plan:yY.string().describe("The complete implementation plan in markdown format")}),description:{short:"Use this tool when you are in plan mode and have finished creating your plan and are ready for user approval",long:`Use this tool when you are in plan mode and have finished creating your implementation plan and are ready for user approval.
839
+ Proceeding with research phase. Use read-only tools to explore the codebase, then call ExitPlanMode with your implementation plan when ready.`,displayContent:"Plan mode (non-interactive)",metadata:{approved:null,enterPlanMode:!0}}}})});import{z as iY}from"zod";import{promises as rY}from"node:fs";import*as m9 from"node:path";import{homedir as tG}from"node:os";var c9;var aY=b(()=>{m1();t0();c9=U1({name:"ExitPlanMode",displayName:"Exit Plan Mode",kind:"readonly",schema:iY.object({plan:iY.string().describe("The complete implementation plan in markdown format")}),description:{short:"Use this tool when you are in plan mode and have finished creating your plan and are ready for user approval",long:`Use this tool when you are in plan mode and have finished creating your implementation plan and are ready for user approval.
838
840
 
839
841
  ## \uD83D\uDEA8 PREREQUISITES (MUST be satisfied before calling)
840
842
 
@@ -869,7 +871,7 @@ Before using this tool, ensure your plan is clear and unambiguous. If there are
869
871
  1. Initial task: "Search for and understand the implementation of vim mode in the codebase" - Do not use the exit plan mode tool because you are not planning the implementation steps of a task.
870
872
  2. Initial task: "Help me implement yank mode for vim" - Use the exit plan mode tool after you have finished planning the implementation steps of the task.
871
873
  3. Initial task: "Add a new feature to handle user authentication" - If unsure about auth method (OAuth, JWT, etc.), use AskUserQuestion first, then use exit plan mode tool after clarifying the approach.
872
- `},async execute($,Y){let Z=$.plan||"";if(Z&&Y.sessionId)try{let X=S8.join(PK(),".blade","plans");await vY.mkdir(X,{recursive:!0});let Q=S8.join(X,`plan_${Y.sessionId}.md`);await vY.writeFile(Q,Z,"utf-8")}catch(X){console.warn("Failed to save plan file:",X)}if(Y.confirmationHandler)try{let X=await Y.confirmationHandler.requestConfirmation({type:"exitPlanMode",message:`The assistant has finished planning and is ready for your review.
874
+ `},async execute($,Y){let Z=$.plan||"";if(Z&&Y.sessionId)try{let X=m9.join(tG(),".blade","plans");await rY.mkdir(X,{recursive:!0});let Q=m9.join(X,`plan_${Y.sessionId}.md`);await rY.writeFile(Q,Z,"utf-8")}catch(X){console.warn("Failed to save plan file:",X)}if(Y.confirmationHandler)try{let X=await Y.confirmationHandler.requestConfirmation({type:"exitPlanMode",message:`The assistant has finished planning and is ready for your review.
873
875
 
874
876
  `+`⚠️ Before approving, please verify:
875
877
  `+`1. The assistant has written a detailed plan to the plan file
@@ -882,40 +884,40 @@ please reject and ask for a proper plan.`,details:"After approval, the assistant
882
884
  `+(X.feedback||"No specific feedback provided.")+`
883
885
 
884
886
  The agent has stopped and control is returned to the user. The user can now provide additional information or clarification.`,displayContent:"⚠️ 方案被拒绝,等待用户补充信息",metadata:{approved:!1,shouldExitLoop:!0,feedback:X.feedback,awaitingUserInput:!0}}}catch(X){return{success:!1,llmContent:`Confirmation flow error: ${X instanceof Error?X.message:"Unknown error"}`,displayContent:"❌ Confirmation failed",error:{type:"execution_error",message:"Confirmation flow error"}}}return{success:!0,llmContent:`✅ Plan mode exit requested. No interactive confirmation available.
885
- `+"Proceeding with implementation.",displayContent:"Plan mode exit (non-interactive)",metadata:{approved:null}}}})});var PY=b(()=>{jY();EY()});import TK from"fast-glob";import{LRUCache as kK}from"lru-cache";import{existsSync as SK,readFileSync as CK}from"node:fs";import{readFile as fK}from"node:fs/promises";import{dirname as hK,join as kY}from"node:path";import w6 from"picomatch";function xK($){if(!SK($))return{patterns:[],negatePatterns:[]};try{let Y=CK($,"utf-8"),Z=[],X=[];for(let Q of Y.split(`
886
- `)){let J=Q.trim();if(!J||J.startsWith("#"))continue;if(J.startsWith("!"))X.push(J.slice(1));else Z.push(J)}return{patterns:Z,negatePatterns:X}}catch(Y){return console.warn(`Failed to read .gitignore: ${Y}`),{patterns:[],negatePatterns:[]}}}async function pK($,Y){let Z=[...Y2.map((K)=>`${K}/**`),...Y?.scanIgnore??[]],X=`${$}|${Z.join(",")}`,Q=TY.get(X);if(Q)return Q;let J=await TK("**/.gitignore",{cwd:$,dot:!0,onlyFiles:!0,followSymbolicLinks:!1,unique:!0,ignore:Z});J.sort((K,W)=>K.split("/").length-W.split("/").length);let q=[];for(let K of J){let W=hK(K).replace(/\\/g,"/"),O=W==="."?"":W,F=(await fK(kY($,K),"utf-8")).split(`
887
- `);for(let H of F){let _=H.trim();if(!_||_.startsWith("#"))continue;let z=_.startsWith("!"),B=(z?_.slice(1):_).trim();if(!B)continue;let N="";if(B.startsWith("/")){let I=B.slice(1).replace(/\\/g,"/");if(N=(O?O+"/":"")+I,q.push({type:z?"negate":"ignore",pattern:N}),B.endsWith("/")){let M=N+"**";q.push({type:z?"negate":"ignore",pattern:M});let A=N.replace(/\/$/,"");if(A!==N)q.push({type:z?"negate":"ignore",pattern:A})}}else{let I=B.replace(/\\/g,"/");if(I.includes("/")){if(N=(O?O+"/":"")+I,q.push({type:z?"negate":"ignore",pattern:N}),I.endsWith("/")){let M=N+"**";q.push({type:z?"negate":"ignore",pattern:M});let A=N.replace(/\/$/,"");if(A!==N)q.push({type:z?"negate":"ignore",pattern:A})}}else N=(O?O+"/**/":"**/")+I,q.push({type:z?"negate":"ignore",pattern:N})}}}let G=Y?.cacheTTL??30000;return TY.set(X,q,{ttl:G}),q}class R4{orderedRules=[];ignorePatterns=[];negatePatterns=[];constructor($={}){this.initialize($)}static async create($={}){let Y=new R4({...$,useGitignore:!1}),{cwd:Z=process.cwd(),useGitignore:X=!0,gitignoreScanMode:Q="root",customScanIgnore:J=[],cacheTTL:q}=$;if(X&&Q==="recursive"){let G=await pK(Z,{scanIgnore:J,cacheTTL:q});for(let K of G)if(Y.orderedRules.push({type:K.type,matcher:w6(K.pattern,{dot:!0})}),K.type==="ignore")Y.ignorePatterns.push(K.pattern);else Y.negatePatterns.push(K.pattern)}return Y}initialize($){let{cwd:Y=process.cwd(),useGitignore:Z=!0,useDefaults:X=!0,customPatterns:Q=[]}=$,J=[],q=[];if(X){let G=[...Y2.map((K)=>`${K}/**`),...Y2,...f8];J.push(...G);for(let K of G)this.orderedRules.push({type:"ignore",matcher:w6(K,{dot:!0})})}if(Z){let G=kY(Y,".gitignore"),{patterns:K,negatePatterns:W}=xK(G);for(let O of K)this.orderedRules.push({type:"ignore",matcher:w6(O,{dot:!0})}),J.push(O);for(let O of W)this.orderedRules.push({type:"negate",matcher:w6(O,{dot:!0})}),q.push(O)}J.push(...Q);for(let G of Q)this.orderedRules.push({type:"ignore",matcher:w6(G,{dot:!0})});this.ignorePatterns=J,this.negatePatterns=q}shouldIgnore($){let Y=$.replace(/\\/g,"/"),Z=void 0;for(let X of this.orderedRules)if(X.matcher(Y))Z=X.type==="ignore";return Z===!0}shouldIgnoreDirectory($){let Y=$.replace(/\\/g,"/");return this.shouldIgnore(Y)||this.shouldIgnore(`${Y}/`)}filter($){return $.filter((Y)=>!this.shouldIgnore(Y))}getIgnorePatterns(){return this.ignorePatterns}getNegatePatterns(){return this.negatePatterns}}var Y2,f8,TY;var V4=b(()=>{Y2=["node_modules",".git","dist","build","out",".next",".nuxt",".cache",".parcel-cache","coverage",".nyc_output",".idea",".vscode",".vs","bower_components","jspm_packages"],f8=["*.log","npm-debug.log*","yarn-debug.log*","pnpm-debug.log*","*.lock","package-lock.json","yarn.lock","pnpm-lock.yaml","*.tmp","*.temp","*.swp","*.bak","*~",".DS_Store","Thumbs.db","*.pid","*.seed"];TY=new kK({max:100,ttl:30000,updateAgeOnGet:!0})});import gK from"fast-glob";import{stat as uK}from"node:fs/promises";import{join as mK,resolve as dK}from"path";import{z as D4}from"zod";function h8($){let Y=Error($);return Y.name="AbortError",Y}async function cK($,Y,Z,X){let Q=X.getIgnorePatterns(),J=[],q=!1;return await new Promise((G,K)=>{if(Z.signal.aborted){K(h8("文件搜索被用户中止"));return}let W=gK.stream(Y,{cwd:$,dot:!0,followSymbolicLinks:!1,unique:!0,caseSensitiveMatch:Z.caseSensitive,objectMode:!0,stats:!0,onlyFiles:!Z.includeDirectories,ignore:Q}),O=!1,U=null,F=()=>{if(U){if(Z.signal.removeEventListener)Z.signal.removeEventListener("abort",U);else if("onabort"in Z.signal)Z.signal.onabort=null;U=null}},H=()=>{if(!O)O=!0,q=!0,W.destroy(),F(),G({matches:J,wasTruncated:q})},_=(z)=>{if(Z.signal.aborted){if(!O)O=!0,W.destroy(h8("文件搜索被用户中止"));return}if(J.length>=Z.maxResults){H();return}let L=z.path.replace(/\\/g,"/"),B=mK($,L);if(X.shouldIgnore(L))return;let N=z.stats?z.stats.isDirectory():!1;if(N&&X.shouldIgnoreDirectory(L))return;let I=z.stats&&z.stats.isFile()?z.stats.size:void 0,M=z.stats?z.stats.mtime.toISOString():void 0;if(J.push({path:B,relative_path:L,is_directory:N,size:I,modified:M}),J.length>=Z.maxResults)H()};if(W.on("data",_),U=()=>{if(!O)O=!0,F(),W.destroy(h8("文件搜索被用户中止"))},Z.signal.addEventListener)Z.signal.addEventListener("abort",U);else if("onabort"in Z.signal)Z.signal.onabort=U;W.once("error",(z)=>{if(!O)O=!0,F(),K(z)}),W.once("end",()=>{if(!O)O=!0,F(),G({matches:J,wasTruncated:q})})})}function lK($){return $.sort((Y,Z)=>{if(Y.is_directory!==Z.is_directory)return Y.is_directory?1:-1;if(Y.modified&&Z.modified)return new Date(Z.modified).getTime()-new Date(Y.modified).getTime();return Y.relative_path.localeCompare(Z.relative_path)})}function iK($){let{search_path:Y,pattern:Z,total_matches:X,returned_matches:Q,truncated:J}=$,q;if(J)q=`✅ 在 ${Y} 中找到至少 ${X} 个匹配 "${Z}" 的文件(已截断)`,q+=`
888
- \uD83D\uDCCB 显示前 ${Q} 个结果`;else q=`✅ 在 ${Y} 中找到 ${X} 个匹配 "${Z}" 的文件`;return q}var x8;var SY=b(()=>{V4();g1();e1();E2();x8=U1({name:"Glob",displayName:"File Pattern Match",kind:"readonly",schema:D4.object({pattern:b1.glob({description:"Glob pattern string (supports *, ?, ** wildcards)"}),path:D4.string().optional().describe("Search path (optional, defaults to cwd)"),max_results:b1.positiveInt({description:"Maximum number of results"}).max(1000,"At most 1000 results can be returned").default(100),include_directories:D4.boolean().default(!1).describe("Include directories in results"),case_sensitive:D4.boolean().default(!1).describe("Case sensitive matching")}),description:{short:"Fast file pattern matching tool that works with any codebase size",long:'Fast file pattern matching tool that works with any codebase size. Supports glob patterns like "**/*.js" or "src/**/*.ts". Returns matching file paths sorted by modification time.',usageNotes:["Use this tool when you need to find files by name patterns","When you are doing an open ended search that may require multiple rounds of globbing and grepping, use the Agent tool instead","You can call multiple tools in a single response. It is always better to speculatively perform multiple searches in parallel if they are potentially useful."]},async execute($,Y){let{pattern:Z,path:X=process.cwd(),max_results:Q,include_directories:J,case_sensitive:q}=$,{updateOutput:G}=Y,K=Y.signal??new AbortController().signal;try{G?.(`Searching in ${X} for pattern "${Z}"...`);let W=dK(X);try{if(!(await uK(W)).isDirectory())return{success:!1,llmContent:`Search path must be a directory: ${W}`,displayContent:`❌ 搜索路径必须是目录: ${W}`,error:{type:"validation_error",message:"搜索路径必须是目录"}}}catch(B){if(B.code==="ENOENT")return{success:!1,llmContent:`Search path does not exist: ${W}`,displayContent:`❌ 搜索路径不存在: ${W}`,error:{type:"execution_error",message:"搜索路径不存在"}};throw B}K.throwIfAborted();let O=await R4.create({cwd:W,useGitignore:!0,useDefaults:!0,gitignoreScanMode:"recursive",customScanIgnore:[],cacheTTL:30000}),{matches:U,wasTruncated:F}=await cK(W,Z,{maxResults:Q,includeDirectories:J,caseSensitive:q,signal:K},O),H=lK(U),_={search_path:W,pattern:Z,total_matches:U.length,returned_matches:U.length,max_results:Q,include_directories:J,case_sensitive:q,truncated:F},z=iK(_),L;if(H.length>0)L=`${F?`Found at least ${H.length} file(s) matching "${Z}" (truncated)`:`Found ${H.length} file(s) matching "${Z}"`}:
887
+ `+"Proceeding with implementation.",displayContent:"Plan mode exit (non-interactive)",metadata:{approved:null}}}})});var nY=b(()=>{lY();aY()});import eG from"fast-glob";import{LRUCache as $U}from"lru-cache";import{existsSync as YU,readFileSync as ZU}from"node:fs";import{readFile as XU}from"node:fs/promises";import{dirname as QU,join as sY}from"node:path";import R6 from"picomatch";function JU($){if(!YU($))return{patterns:[],negatePatterns:[]};try{let Y=ZU($,"utf-8"),Z=[],X=[];for(let Q of Y.split(`
888
+ `)){let J=Q.trim();if(!J||J.startsWith("#"))continue;if(J.startsWith("!"))X.push(J.slice(1));else Z.push(J)}return{patterns:Z,negatePatterns:X}}catch(Y){return console.warn(`Failed to read .gitignore: ${Y}`),{patterns:[],negatePatterns:[]}}}async function qU($,Y){let Z=[...Q2.map((G)=>`${G}/**`),...Y?.scanIgnore??[]],X=`${$}|${Z.join(",")}`,Q=oY.get(X);if(Q)return Q;let J=await eG("**/.gitignore",{cwd:$,dot:!0,onlyFiles:!0,followSymbolicLinks:!1,unique:!0,ignore:Z});J.sort((G,U)=>G.split("/").length-U.split("/").length);let q=[];for(let G of J){let U=QU(G).replace(/\\/g,"/"),O=U==="."?"":U,F=(await XU(sY($,G),"utf-8")).split(`
889
+ `);for(let H of F){let z=H.trim();if(!z||z.startsWith("#"))continue;let N=z.startsWith("!"),B=(N?z.slice(1):z).trim();if(!B)continue;let _="";if(B.startsWith("/")){let I=B.slice(1).replace(/\\/g,"/");if(_=(O?O+"/":"")+I,q.push({type:N?"negate":"ignore",pattern:_}),B.endsWith("/")){let M=_+"**";q.push({type:N?"negate":"ignore",pattern:M});let A=_.replace(/\/$/,"");if(A!==_)q.push({type:N?"negate":"ignore",pattern:A})}}else{let I=B.replace(/\\/g,"/");if(I.includes("/")){if(_=(O?O+"/":"")+I,q.push({type:N?"negate":"ignore",pattern:_}),I.endsWith("/")){let M=_+"**";q.push({type:N?"negate":"ignore",pattern:M});let A=_.replace(/\/$/,"");if(A!==_)q.push({type:N?"negate":"ignore",pattern:A})}}else _=(O?O+"/**/":"**/")+I,q.push({type:N?"negate":"ignore",pattern:_})}}}let K=Y?.cacheTTL??30000;return oY.set(X,q,{ttl:K}),q}class I4{orderedRules=[];ignorePatterns=[];negatePatterns=[];constructor($={}){this.initialize($)}static async create($={}){let Y=new I4({...$,useGitignore:!1}),{cwd:Z=process.cwd(),useGitignore:X=!0,gitignoreScanMode:Q="root",customScanIgnore:J=[],cacheTTL:q}=$;if(X&&Q==="recursive"){let K=await qU(Z,{scanIgnore:J,cacheTTL:q});for(let G of K)if(Y.orderedRules.push({type:G.type,matcher:R6(G.pattern,{dot:!0})}),G.type==="ignore")Y.ignorePatterns.push(G.pattern);else Y.negatePatterns.push(G.pattern)}return Y}initialize($){let{cwd:Y=process.cwd(),useGitignore:Z=!0,useDefaults:X=!0,customPatterns:Q=[]}=$,J=[],q=[];if(X){let K=[...Q2.map((G)=>`${G}/**`),...Q2,...l9];J.push(...K);for(let G of K)this.orderedRules.push({type:"ignore",matcher:R6(G,{dot:!0})})}if(Z){let K=sY(Y,".gitignore"),{patterns:G,negatePatterns:U}=JU(K);for(let O of G)this.orderedRules.push({type:"ignore",matcher:R6(O,{dot:!0})}),J.push(O);for(let O of U)this.orderedRules.push({type:"negate",matcher:R6(O,{dot:!0})}),q.push(O)}J.push(...Q);for(let K of Q)this.orderedRules.push({type:"ignore",matcher:R6(K,{dot:!0})});this.ignorePatterns=J,this.negatePatterns=q}shouldIgnore($){let Y=$.replace(/\\/g,"/"),Z=void 0;for(let X of this.orderedRules)if(X.matcher(Y))Z=X.type==="ignore";return Z===!0}shouldIgnoreDirectory($){let Y=$.replace(/\\/g,"/");return this.shouldIgnore(Y)||this.shouldIgnore(`${Y}/`)}filter($){return $.filter((Y)=>!this.shouldIgnore(Y))}getIgnorePatterns(){return this.ignorePatterns}getNegatePatterns(){return this.negatePatterns}}var Q2,l9,oY;var M4=b(()=>{Q2=["node_modules",".git","dist","build","out",".next",".nuxt",".cache",".parcel-cache","coverage",".nyc_output",".idea",".vscode",".vs","bower_components","jspm_packages"],l9=["*.log","npm-debug.log*","yarn-debug.log*","pnpm-debug.log*","*.lock","package-lock.json","yarn.lock","pnpm-lock.yaml","*.tmp","*.temp","*.swp","*.bak","*~",".DS_Store","Thumbs.db","*.pid","*.seed"];oY=new $U({max:100,ttl:30000,updateAgeOnGet:!0})});import KU from"fast-glob";import{stat as GU}from"node:fs/promises";import{join as UU,resolve as WU}from"path";import{z as j4}from"zod";function i9($){let Y=Error($);return Y.name="AbortError",Y}async function OU($,Y,Z,X){let Q=X.getIgnorePatterns(),J=[],q=!1;return await new Promise((K,G)=>{if(Z.signal.aborted){G(i9("文件搜索被用户中止"));return}let U=KU.stream(Y,{cwd:$,dot:!0,followSymbolicLinks:!1,unique:!0,caseSensitiveMatch:Z.caseSensitive,objectMode:!0,stats:!0,onlyFiles:!Z.includeDirectories,ignore:Q}),O=!1,W=null,F=()=>{if(W){if(Z.signal.removeEventListener)Z.signal.removeEventListener("abort",W);else if("onabort"in Z.signal)Z.signal.onabort=null;W=null}},H=()=>{if(!O)O=!0,q=!0,U.destroy(),F(),K({matches:J,wasTruncated:q})},z=(N)=>{if(Z.signal.aborted){if(!O)O=!0,U.destroy(i9("文件搜索被用户中止"));return}if(J.length>=Z.maxResults){H();return}let L=N.path.replace(/\\/g,"/"),B=UU($,L);if(X.shouldIgnore(L))return;let _=N.stats?N.stats.isDirectory():!1;if(_&&X.shouldIgnoreDirectory(L))return;let I=N.stats&&N.stats.isFile()?N.stats.size:void 0,M=N.stats?N.stats.mtime.toISOString():void 0;if(J.push({path:B,relative_path:L,is_directory:_,size:I,modified:M}),J.length>=Z.maxResults)H()};if(U.on("data",z),W=()=>{if(!O)O=!0,F(),U.destroy(i9("文件搜索被用户中止"))},Z.signal.addEventListener)Z.signal.addEventListener("abort",W);else if("onabort"in Z.signal)Z.signal.onabort=W;U.once("error",(N)=>{if(!O)O=!0,F(),G(N)}),U.once("end",()=>{if(!O)O=!0,F(),K({matches:J,wasTruncated:q})})})}function FU($){return $.sort((Y,Z)=>{if(Y.is_directory!==Z.is_directory)return Y.is_directory?1:-1;if(Y.modified&&Z.modified)return new Date(Z.modified).getTime()-new Date(Y.modified).getTime();return Y.relative_path.localeCompare(Z.relative_path)})}function HU($){let{search_path:Y,pattern:Z,total_matches:X,returned_matches:Q,truncated:J}=$,q;if(J)q=`✅ 在 ${Y} 中找到至少 ${X} 个匹配 "${Z}" 的文件(已截断)`,q+=`
890
+ \uD83D\uDCCB 显示前 ${Q} 个结果`;else q=`✅ 在 ${Y} 中找到 ${X} 个匹配 "${Z}" 的文件`;return q}var r9;var tY=b(()=>{M4();m1();Z0();S2();r9=U1({name:"Glob",displayName:"File Pattern Match",kind:"readonly",schema:j4.object({pattern:I1.glob({description:"Glob pattern string (supports *, ?, ** wildcards)"}),path:j4.string().optional().describe("Search path (optional, defaults to cwd)"),max_results:I1.positiveInt({description:"Maximum number of results"}).max(1000,"At most 1000 results can be returned").default(100),include_directories:j4.boolean().default(!1).describe("Include directories in results"),case_sensitive:j4.boolean().default(!1).describe("Case sensitive matching")}),description:{short:"Fast file pattern matching tool that works with any codebase size",long:'Fast file pattern matching tool that works with any codebase size. Supports glob patterns like "**/*.js" or "src/**/*.ts". Returns matching file paths sorted by modification time.',usageNotes:["Use this tool when you need to find files by name patterns","When you are doing an open ended search that may require multiple rounds of globbing and grepping, use the Agent tool instead","You can call multiple tools in a single response. It is always better to speculatively perform multiple searches in parallel if they are potentially useful."]},async execute($,Y){let{pattern:Z,path:X=process.cwd(),max_results:Q,include_directories:J,case_sensitive:q}=$,{updateOutput:K}=Y,G=Y.signal??new AbortController().signal;try{K?.(`Searching in ${X} for pattern "${Z}"...`);let U=WU(X);try{if(!(await GU(U)).isDirectory())return{success:!1,llmContent:`Search path must be a directory: ${U}`,displayContent:`❌ 搜索路径必须是目录: ${U}`,error:{type:"validation_error",message:"搜索路径必须是目录"}}}catch(B){if(B.code==="ENOENT")return{success:!1,llmContent:`Search path does not exist: ${U}`,displayContent:`❌ 搜索路径不存在: ${U}`,error:{type:"execution_error",message:"搜索路径不存在"}};throw B}G.throwIfAborted();let O=await I4.create({cwd:U,useGitignore:!0,useDefaults:!0,gitignoreScanMode:"recursive",customScanIgnore:[],cacheTTL:30000}),{matches:W,wasTruncated:F}=await OU(U,Z,{maxResults:Q,includeDirectories:J,caseSensitive:q,signal:G},O),H=FU(W),z={search_path:U,pattern:Z,total_matches:W.length,returned_matches:W.length,max_results:Q,include_directories:J,case_sensitive:q,truncated:F},N=HU(z),L;if(H.length>0)L=`${F?`Found at least ${H.length} file(s) matching "${Z}" (truncated)`:`Found ${H.length} file(s) matching "${Z}"`}:
889
891
 
890
- `+H.map((N)=>`- ${N.relative_path}`).join(`
892
+ `+H.map((_)=>`- ${_.relative_path}`).join(`
891
893
  `)+`
892
894
 
893
- Use the relative_path values above for Read/Edit operations.`;else L=`No files found matching "${Z}"`;return{success:!0,llmContent:L,displayContent:z,metadata:{..._,matches:H}}}catch(W){if(W.name==="AbortError")return{success:!1,llmContent:"File search aborted",displayContent:"⚠️ 文件搜索被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`Search failed: ${W.message}`,displayContent:`❌ 搜索失败: ${W.message}`,error:{type:"execution_error",message:W.message,details:W}}}},version:"2.0.0",category:"搜索工具",tags:["file","search","glob","pattern","wildcard"],extractSignatureContent:($)=>$.pattern,abstractPermissionRule:()=>"*"})});import{execSync as p8,spawn as g8}from"child_process";import{existsSync as I4}from"fs";import{readdir as aK,readFile as rK}from"fs/promises";import{join as CY,relative as nK}from"path";import oK from"picomatch";import{z as P2}from"zod";function sK(){let{platform:$,arch:Y}=process,Z={"darwin-arm64":"darwin-arm64/rg","darwin-x64":"darwin-x64/rg","linux-arm64":"linux-arm64/rg","linux-x64":"linux-x64/rg","win32-x64":"win32-x64/rg.exe"},X=`${$}-${Y}`,Q=Z[X];if(!Q)return null;let J=CY(process.cwd(),"vendor","ripgrep",Q);if(I4(J))return J;try{let q=new URL("../../../../vendor/ripgrep/"+Q,import.meta.url).pathname;if(I4(q))return q}catch{}return null}function fY(){try{let Y=process.platform==="win32"?"where rg":"command -v rg 2>/dev/null || which rg 2>/dev/null",Z=p8(Y,{encoding:"utf8",stdio:["pipe","pipe","ignore"]}).split(/\r?\n/)[0].trim();if(Z)return Z}catch{}let $=sK();if($&&I4($))return $;try{let Y=c1("@vscode/ripgrep");if(Y?.rgPath&&I4(Y.rgPath))return Y.rgPath}catch{}return null}async function tK($){try{return p8("git rev-parse --git-dir",{cwd:$,stdio:"ignore"}),!0}catch{return!1}}function eK(){try{return p8("grep --version",{stdio:"ignore"}),!0}catch{return!1}}async function $U($,Y,Z,X){let Q=fY();if(!Q)throw Error("ripgrep not available");return new Promise((J,q)=>{let G=g8(Q,$,{stdio:["pipe","pipe","pipe"]}),K="",W="";G.stdout.on("data",(U)=>{K+=U.toString()}),G.stderr.on("data",(U)=>{W+=U.toString()}),G.on("close",(U)=>{J({stdout:K,stderr:W,exitCode:U||0})}),G.on("error",(U)=>{q(U)});let O=()=>{G.kill("SIGTERM"),q(Error("搜索被用户中止"))};Z.addEventListener("abort",O),G.on("close",()=>{Z.removeEventListener("abort",O)})})}async function YU($,Y,Z,X){let Q=["grep","-n"];if(Z.caseInsensitive)Q.push("-i");if(Z.contextLines!==void 0)Q.push(`-C${Z.contextLines}`);if(Q.push("-e",$),Z.glob)Q.push("--",Z.glob);return new Promise((J,q)=>{let G=g8("git",Q,{cwd:Y,stdio:["pipe","pipe","pipe"]}),K="",W="";G.stdout.on("data",(U)=>{K+=U.toString()}),G.stderr.on("data",(U)=>{W+=U.toString()}),G.on("close",(U)=>{J({stdout:K,stderr:W,exitCode:U||0})}),G.on("error",(U)=>{q(U)});let O=()=>{G.kill("SIGTERM"),q(Error("搜索被用户中止"))};X.addEventListener("abort",O),G.on("close",()=>{X.removeEventListener("abort",O)})})}async function ZU($,Y,Z,X){let Q=["-rn"];if(Z.caseInsensitive)Q.push("-i");if(Z.contextLines!==void 0)Q.push(`-C${Z.contextLines}`);for(let J of Y2)Q.push("--exclude-dir="+J.replace(/^\./,""));return Q.push("-e",$,Y),new Promise((J,q)=>{let G=g8("grep",Q,{stdio:["pipe","pipe","pipe"]}),K="",W="";G.stdout.on("data",(U)=>{K+=U.toString()}),G.stderr.on("data",(U)=>{W+=U.toString()}),G.on("close",(U)=>{J({stdout:K,stderr:W,exitCode:U||0})}),G.on("error",(U)=>{q(U)});let O=()=>{G.kill("SIGTERM"),q(Error("搜索被用户中止"))};X.addEventListener("abort",O),G.on("close",()=>{X.removeEventListener("abort",O)})})}async function XU($,Y,Z,X){let Q=[],J=new RegExp($,Z.caseInsensitive?"gi":"g"),q=await QU(Y,X),G=0;for(let K of q){if(X.throwIfAborted(),hY(K))continue;if(Z.glob&&!JU(K,Z.glob))continue;try{(await rK(K,"utf-8")).split(`
894
- `).forEach((U,F)=>{if(J.test(U))Q.push({file_path:nK(Y,K),line_number:F+1,content:U})}),G++}catch(W){continue}}return{matches:Q,totalFiles:G}}async function QU($,Y){let Z=[];async function X(Q){Y.throwIfAborted();try{let J=await aK(Q,{withFileTypes:!0});for(let q of J){Y.throwIfAborted();let G=CY(Q,q.name);if(q.isDirectory()){if(!hY(G))await X(G)}else if(q.isFile())Z.push(G)}}catch(J){}}return await X($),Z}function hY($){for(let Y of Y2)if($.includes(Y))return!0;return!1}function JU($,Y){return oK(Y)($)}function qU($){let Y=[];if($.case_insensitive)Y.push("-i");if($.multiline)Y.push("-U","--multiline-dotall");switch($.output_mode){case"files_with_matches":Y.push("-l");break;case"count":Y.push("-c");break;case"content":if($.line_numbers)Y.push("-n");break}if($.context!==void 0&&$.output_mode==="content")Y.push("-C",$.context.toString());else{if($.context_before!==void 0&&$.output_mode==="content")Y.push("-B",$.context_before.toString());if($.context_after!==void 0&&$.output_mode==="content")Y.push("-A",$.context_after.toString())}if($.type)Y.push("--type",$.type);for(let Z of Y2)Y.push("--glob",`!${Z}/**`);if($.glob)Y.push("--glob",$.glob);if($.head_limit!==void 0){let Z=($.offset??0)+$.head_limit;Y.push("-m",Z.toString())}return Y.push($.pattern),Y.push($.path),Y}function GU($,Y){if(!$.trim())return[];let Z=$.trim().split(`
895
- `),X=[];switch(Y){case"files_with_matches":return Z.map((Q)=>({file_path:Q.trim()}));case"count":return Z.map((Q)=>{let[J,q]=Q.split(":");return{file_path:J,count:parseInt(q,10)}});case"content":for(let Q of Z){let J=KU(Q);if(J)X.push(J)}return X;default:return[]}}function KU($){let Y=$.indexOf(":");if(Y===-1)return null;let Z=$.substring(0,Y),X=$.substring(Y+1),Q=X.indexOf(":");if(Q!==-1&&/^\d+$/.test(X.substring(0,Q))){let J=parseInt(X.substring(0,Q),10),q=X.substring(Q+1);return{file_path:Z,line_number:J,content:q}}else return{file_path:Z,content:X}}function UU($){let{search_pattern:Y,search_path:Z,output_mode:X,total_matches:Q,strategy:J}=$,q=`✅ 在 ${Z} 中搜索 "${Y}"`;if(J)q+=`
895
+ Use the relative_path values above for Read/Edit operations.`;else L=`No files found matching "${Z}"`;return{success:!0,llmContent:L,displayContent:N,metadata:{...z,matches:H}}}catch(U){if(U.name==="AbortError")return{success:!1,llmContent:"File search aborted",displayContent:"⚠️ 文件搜索被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`Search failed: ${U.message}`,displayContent:`❌ 搜索失败: ${U.message}`,error:{type:"execution_error",message:U.message,details:U}}}},version:"2.0.0",category:"搜索工具",tags:["file","search","glob","pattern","wildcard"],extractSignatureContent:($)=>$.pattern,abstractPermissionRule:()=>"*"})});import{execSync as a9,spawn as n9}from"child_process";import{existsSync as y4}from"fs";import{readdir as zU,readFile as NU}from"fs/promises";import{join as eY,relative as BU}from"path";import _U from"picomatch";import{z as k2}from"zod";function LU(){let{platform:$,arch:Y}=process,Z={"darwin-arm64":"darwin-arm64/rg","darwin-x64":"darwin-x64/rg","linux-arm64":"linux-arm64/rg","linux-x64":"linux-x64/rg","win32-x64":"win32-x64/rg.exe"},X=`${$}-${Y}`,Q=Z[X];if(!Q)return null;let J=eY(process.cwd(),"vendor","ripgrep",Q);if(y4(J))return J;try{let q=new URL("../../../../vendor/ripgrep/"+Q,import.meta.url).pathname;if(y4(q))return q}catch{}return null}function $Z(){try{let Y=process.platform==="win32"?"where rg":"command -v rg 2>/dev/null || which rg 2>/dev/null",Z=a9(Y,{encoding:"utf8",stdio:["pipe","pipe","ignore"]}).split(/\r?\n/)[0].trim();if(Z)return Z}catch{}let $=LU();if($&&y4($))return $;try{let Y=r1("@vscode/ripgrep");if(Y?.rgPath&&y4(Y.rgPath))return Y.rgPath}catch{}return null}async function wU($){try{return a9("git rev-parse --git-dir",{cwd:$,stdio:"ignore"}),!0}catch{return!1}}function AU(){try{return a9("grep --version",{stdio:"ignore"}),!0}catch{return!1}}async function bU($,Y,Z,X){let Q=$Z();if(!Q)throw Error("ripgrep not available");return new Promise((J,q)=>{let K=n9(Q,$,{stdio:["pipe","pipe","pipe"]}),G="",U="";K.stdout.on("data",(W)=>{G+=W.toString()}),K.stderr.on("data",(W)=>{U+=W.toString()}),K.on("close",(W)=>{J({stdout:G,stderr:U,exitCode:W||0})}),K.on("error",(W)=>{q(W)});let O=()=>{K.kill("SIGTERM"),q(Error("搜索被用户中止"))};Z.addEventListener("abort",O),K.on("close",()=>{Z.removeEventListener("abort",O)})})}async function RU($,Y,Z,X){let Q=["grep","-n"];if(Z.caseInsensitive)Q.push("-i");if(Z.contextLines!==void 0)Q.push(`-C${Z.contextLines}`);if(Q.push("-e",$),Z.glob)Q.push("--",Z.glob);return new Promise((J,q)=>{let K=n9("git",Q,{cwd:Y,stdio:["pipe","pipe","pipe"]}),G="",U="";K.stdout.on("data",(W)=>{G+=W.toString()}),K.stderr.on("data",(W)=>{U+=W.toString()}),K.on("close",(W)=>{J({stdout:G,stderr:U,exitCode:W||0})}),K.on("error",(W)=>{q(W)});let O=()=>{K.kill("SIGTERM"),q(Error("搜索被用户中止"))};X.addEventListener("abort",O),K.on("close",()=>{X.removeEventListener("abort",O)})})}async function VU($,Y,Z,X){let Q=["-rn"];if(Z.caseInsensitive)Q.push("-i");if(Z.contextLines!==void 0)Q.push(`-C${Z.contextLines}`);for(let J of Q2)Q.push("--exclude-dir="+J.replace(/^\./,""));return Q.push("-e",$,Y),new Promise((J,q)=>{let K=n9("grep",Q,{stdio:["pipe","pipe","pipe"]}),G="",U="";K.stdout.on("data",(W)=>{G+=W.toString()}),K.stderr.on("data",(W)=>{U+=W.toString()}),K.on("close",(W)=>{J({stdout:G,stderr:U,exitCode:W||0})}),K.on("error",(W)=>{q(W)});let O=()=>{K.kill("SIGTERM"),q(Error("搜索被用户中止"))};X.addEventListener("abort",O),K.on("close",()=>{X.removeEventListener("abort",O)})})}async function DU($,Y,Z,X){let Q=[],J=new RegExp($,Z.caseInsensitive?"gi":"g"),q=await IU(Y,X),K=0;for(let G of q){if(X.throwIfAborted(),YZ(G))continue;if(Z.glob&&!MU(G,Z.glob))continue;try{(await NU(G,"utf-8")).split(`
896
+ `).forEach((W,F)=>{if(J.test(W))Q.push({file_path:BU(Y,G),line_number:F+1,content:W})}),K++}catch(U){continue}}return{matches:Q,totalFiles:K}}async function IU($,Y){let Z=[];async function X(Q){Y.throwIfAborted();try{let J=await zU(Q,{withFileTypes:!0});for(let q of J){Y.throwIfAborted();let K=eY(Q,q.name);if(q.isDirectory()){if(!YZ(K))await X(K)}else if(q.isFile())Z.push(K)}}catch(J){}}return await X($),Z}function YZ($){for(let Y of Q2)if($.includes(Y))return!0;return!1}function MU($,Y){return _U(Y)($)}function jU($){let Y=[];if($.case_insensitive)Y.push("-i");if($.multiline)Y.push("-U","--multiline-dotall");switch($.output_mode){case"files_with_matches":Y.push("-l");break;case"count":Y.push("-c");break;case"content":if($.line_numbers)Y.push("-n");break}if($.context!==void 0&&$.output_mode==="content")Y.push("-C",$.context.toString());else{if($.context_before!==void 0&&$.output_mode==="content")Y.push("-B",$.context_before.toString());if($.context_after!==void 0&&$.output_mode==="content")Y.push("-A",$.context_after.toString())}if($.type)Y.push("--type",$.type);for(let Z of Q2)Y.push("--glob",`!${Z}/**`);if($.glob)Y.push("--glob",$.glob);if($.head_limit!==void 0){let Z=($.offset??0)+$.head_limit;Y.push("-m",Z.toString())}return Y.push($.pattern),Y.push($.path),Y}function yU($,Y){if(!$.trim())return[];let Z=$.trim().split(`
897
+ `),X=[];switch(Y){case"files_with_matches":return Z.map((Q)=>({file_path:Q.trim()}));case"count":return Z.map((Q)=>{let[J,q]=Q.split(":");return{file_path:J,count:parseInt(q,10)}});case"content":for(let Q of Z){let J=EU(Q);if(J)X.push(J)}return X;default:return[]}}function EU($){let Y=$.indexOf(":");if(Y===-1)return null;let Z=$.substring(0,Y),X=$.substring(Y+1),Q=X.indexOf(":");if(Q!==-1&&/^\d+$/.test(X.substring(0,Q))){let J=parseInt(X.substring(0,Q),10),q=X.substring(Q+1);return{file_path:Z,line_number:J,content:q}}else return{file_path:Z,content:X}}function vU($){let{search_pattern:Y,search_path:Z,output_mode:X,total_matches:Q,strategy:J}=$,q=`✅ 在 ${Z} 中搜索 "${Y}"`;if(J)q+=`
896
898
  \uD83D\uDD27 使用策略: ${J}`;switch(X){case"files_with_matches":q+=`
897
899
  \uD83D\uDCC1 找到 ${Q} 个包含匹配内容的文件`;break;case"count":q+=`
898
900
  \uD83D\uDD22 统计了 ${Q} 个文件的匹配数量`;break;case"content":q+=`
899
- \uD83D\uDCDD 找到 ${Q} 个匹配行`;break}return q}var u8;var xY=b(()=>{V4();g1();e1();E2();u8=U1({name:"Grep",displayName:"内容搜索",kind:"readonly",schema:P2.object({pattern:b1.pattern({description:"The regular expression pattern to search for in file contents"}),path:P2.string().optional().describe("File or directory to search in (rg PATH). Defaults to current working directory"),glob:P2.string().optional().describe('Glob pattern to filter files (e.g. "*.js", "*.{ts,tsx}") - maps to rg --glob'),type:P2.string().optional().describe("File type to search (rg --type). Common types: js, py, rust, go, java, etc. More efficient than include for standard file types"),output_mode:P2.enum(["content","files_with_matches","count"]).default("files_with_matches").describe('Output mode: "content" shows matching lines (supports -A/-B/-C context, -n line numbers, head_limit), "files_with_matches" shows file paths (supports head_limit), "count" shows match counts (supports head_limit). Defaults to "files_with_matches"'),"-i":P2.boolean().optional().describe("Case insensitive search (rg -i)"),"-n":P2.boolean().default(!0).describe('Show line numbers in output (rg -n). Requires output_mode: "content", ignored otherwise. Defaults to true'),"-B":b1.nonNegativeInt().optional().describe('Number of lines to show before each match (rg -B). Requires output_mode: "content", ignored otherwise'),"-A":b1.nonNegativeInt().optional().describe('Number of lines to show after each match (rg -A). Requires output_mode: "content", ignored otherwise'),"-C":b1.nonNegativeInt().optional().describe('Number of lines to show before and after each match (rg -C). Requires output_mode: "content", ignored otherwise'),head_limit:b1.positiveInt().optional().describe('Limit output to first N lines/entries, equivalent to "| head -N". Works across all output modes: content (limits output lines), files_with_matches (limits file paths), count (limits count entries). Defaults based on "cap" experiment value: 0 (unlimited), 20, or 100'),offset:b1.nonNegativeInt().optional().describe('Skip first N lines/entries before applying head_limit, equivalent to "| tail -n +N | head -N". Works across all output modes. Defaults to 0'),multiline:P2.boolean().default(!1).describe("Enable multiline mode where . matches newlines and patterns can span lines (rg -U --multiline-dotall). Default: false")}),description:{short:"A powerful search tool built on ripgrep",long:'A powerful search tool built on ripgrep\n\n Usage:\n - ALWAYS use Grep for search tasks. NEVER invoke `grep` or `rg` as a Bash command. The Grep tool has been optimized for correct permissions and access.\n - Supports full regex syntax (e.g., "log.*Error", "function\\s+\\w+")\n - Filter files with glob parameter (e.g., "*.js", "**/*.tsx") or type parameter (e.g., "js", "py", "rust")\n - Output modes: "content" shows matching lines, "files_with_matches" shows only file paths (default), "count" shows match counts\n - Use Task tool for open-ended searches requiring multiple rounds\n - Pattern syntax: Uses ripgrep (not grep) - literal braces need escaping (use `interface\\{\\}` to find `interface{}` in Go code)\n - Multiline matching: By default patterns match within single lines only. For cross-line patterns like `struct \\{[\\s\\S]*?field`, use `multiline: true`\n'},async execute($,Y){let{pattern:Z,path:X=process.cwd(),glob:Q,type:J,output_mode:q,"-i":G,"-n":K=!0,"-B":W,"-A":O,"-C":U,head_limit:F,offset:H,multiline:_}=$,{updateOutput:z}=Y,L=Y.signal??new AbortController().signal;try{z?.(`使用智能搜索策略查找模式 "${Z}"...`);let B=null,N="ripgrep",I=[],M=fY();if(M)try{z?.(`\uD83D\uDE80 使用 ripgrep (${M})`);let R=qU({pattern:Z,path:X,glob:Q,type:J,output_mode:q,case_insensitive:G??!1,line_numbers:K,context_before:W,context_after:O,context:U,head_limit:F,offset:H,multiline:_??!1});B=await $U(R,q,L,z),N="ripgrep"}catch(R){z?.("⚠️ ripgrep 失败,尝试降级策略..."),B=null}if(!B&&await tK(X))try{z?.("\uD83D\uDCE6 使用 git grep"),B=await YU(Z,X,{caseInsensitive:G??!1,glob:Q,contextLines:U},L),N="git-grep"}catch(R){z?.("⚠️ git grep 失败,继续尝试其他策略..."),B=null}if(!B&&eK())try{z?.("\uD83D\uDD27 使用系统 grep"),B=await ZU(Z,X,{caseInsensitive:G??!1,contextLines:U},L),N="system-grep"}catch(R){z?.("⚠️ 系统 grep 失败,使用纯 JavaScript 实现..."),B=null}if(!B)z?.("\uD83D\uDCA1 使用纯 JavaScript 搜索实现"),I=(await XU(Z,X,{caseInsensitive:G??!1,glob:Q,multiline:_??!1},L)).matches,N="fallback",B={stdout:"",stderr:"",exitCode:0};else I=GU(B.stdout,q);let A=I.length;if(H!==void 0&&H>0)I=I.slice(H);if(F!==void 0&&I.length>F)I=I.slice(0,F);let D={search_pattern:Z,search_path:X,output_mode:q,case_insensitive:G??!1,total_matches:I.length,original_total:A,offset:H,head_limit:F,strategy:N,exit_code:B?.exitCode};if(B&&B.exitCode!==0&&B.stderr)return{success:!1,llmContent:`Search execution failed: ${B.stderr}`,displayContent:`❌ 搜索执行失败: ${B.stderr}`,error:{type:"execution_error",message:B.stderr}};let w=UU(D);return{success:!0,llmContent:I,displayContent:w,metadata:D}}catch(B){if(B.name==="AbortError")return{success:!1,llmContent:"Search aborted",displayContent:"⚠️ 搜索被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`Search failed: ${B.message}`,displayContent:`❌ 搜索失败: ${B.message}`,error:{type:"execution_error",message:B.message,details:B}}}},version:"3.0.0",category:"搜索工具",tags:["search","grep","ripgrep","regex","text","fallback"],extractSignatureContent:($)=>$.pattern,abstractPermissionRule:()=>"*"})});var pY=b(()=>{SY();xY()});import{spawn as WU}from"child_process";import{randomUUID as OU}from"crypto";class F0{static instance=null;processes=new Map;static getInstance(){if(!F0.instance)F0.instance=new F0;return F0.instance}startBackgroundProcess($){let Y=`bash_${OU()}`,Z={};for(let[J,q]of Object.entries({...process.env,...$.env,BLADE_CLI:"1"}))if(q!==void 0)Z[J]=q;let X=WU("bash",["-c",$.command],{cwd:$.cwd||process.cwd(),env:Z,stdio:["ignore","pipe","pipe"]}),Q={id:Y,command:$.command,sessionId:$.sessionId,cwd:$.cwd,env:$.env,process:X,pid:X.pid,status:"running",startTime:Date.now(),pendingStdout:"",pendingStderr:""};return X.stdout?.setEncoding("utf8"),X.stderr?.setEncoding("utf8"),X.stdout?.on("data",(J)=>{Q.pendingStdout+=J.toString()}),X.stderr?.on("data",(J)=>{Q.pendingStderr+=J.toString()}),X.on("close",(J,q)=>{Q.status=Q.status==="killed"?"killed":"exited",Q.exitCode=J,Q.signal=q,Q.endTime=Date.now(),Q.process=void 0}),X.on("error",(J)=>{Q.status="error",Q.errorMessage=J.message,Q.endTime=Date.now(),Q.process=void 0,Q.pendingStderr+=`
900
- [error] ${J.message}`}),this.processes.set(Y,Q),Q}consumeOutput($){let Y=this.processes.get($);if(!Y)return;let Z={id:Y.id,command:Y.command,status:Y.status,stdout:Y.pendingStdout,stderr:Y.pendingStderr,exitCode:Y.exitCode,signal:Y.signal,pid:Y.pid,startedAt:Y.startTime,endedAt:Y.endTime,errorMessage:Y.errorMessage};return Y.pendingStdout="",Y.pendingStderr="",Z}getProcess($){return this.processes.get($)}kill($){let Y=this.processes.get($);if(!Y)return;if(Y.status!=="running"||!Y.process)return{success:!1,alreadyExited:!0,status:Y.status,pid:Y.pid,exitCode:Y.exitCode,signal:Y.signal};if(!Y.process.kill("SIGTERM"))return{success:!1,alreadyExited:!1,status:Y.status,pid:Y.pid,exitCode:Y.exitCode,signal:Y.signal};return Y.status="killed",Y.endTime=Date.now(),Y.process=void 0,{success:!0,alreadyExited:!1,status:Y.status,pid:Y.pid,exitCode:Y.exitCode,signal:Y.signal}}killAll(){for(let[$,Y]of this.processes)if(Y.status==="running"&&Y.process)try{Y.process.kill("SIGTERM"),Y.status="killed",Y.endTime=Date.now(),Y.process=void 0}catch{}this.processes.clear()}}var E$=()=>{};import{spawn as FU}from"child_process";import{randomUUID as HU}from"crypto";import{z as m8}from"zod";function _U($,Y,Z){let Q=F0.getInstance().startBackgroundProcess({command:$,sessionId:HU(),cwd:Y||process.cwd(),env:Z}),q=`后台启动命令: ${$.length>30?`${$.substring(0,30)}...`:$}`,G={command:$,background:!0,pid:Q.pid,bash_id:Q.id,shell_id:Q.id,message:"命令已在后台启动",summary:q},K=`✅ 命令已在后台启动
901
+ \uD83D\uDCDD 找到 ${Q} 个匹配行`;break}return q}var o9;var ZZ=b(()=>{M4();m1();Z0();S2();o9=U1({name:"Grep",displayName:"内容搜索",kind:"readonly",schema:k2.object({pattern:I1.pattern({description:"The regular expression pattern to search for in file contents"}),path:k2.string().optional().describe("File or directory to search in (rg PATH). Defaults to current working directory"),glob:k2.string().optional().describe('Glob pattern to filter files (e.g. "*.js", "*.{ts,tsx}") - maps to rg --glob'),type:k2.string().optional().describe("File type to search (rg --type). Common types: js, py, rust, go, java, etc. More efficient than include for standard file types"),output_mode:k2.enum(["content","files_with_matches","count"]).default("files_with_matches").describe('Output mode: "content" shows matching lines (supports -A/-B/-C context, -n line numbers, head_limit), "files_with_matches" shows file paths (supports head_limit), "count" shows match counts (supports head_limit). Defaults to "files_with_matches"'),"-i":k2.boolean().optional().describe("Case insensitive search (rg -i)"),"-n":k2.boolean().default(!0).describe('Show line numbers in output (rg -n). Requires output_mode: "content", ignored otherwise. Defaults to true'),"-B":I1.nonNegativeInt().optional().describe('Number of lines to show before each match (rg -B). Requires output_mode: "content", ignored otherwise'),"-A":I1.nonNegativeInt().optional().describe('Number of lines to show after each match (rg -A). Requires output_mode: "content", ignored otherwise'),"-C":I1.nonNegativeInt().optional().describe('Number of lines to show before and after each match (rg -C). Requires output_mode: "content", ignored otherwise'),head_limit:I1.positiveInt().optional().describe('Limit output to first N lines/entries, equivalent to "| head -N". Works across all output modes: content (limits output lines), files_with_matches (limits file paths), count (limits count entries). Defaults based on "cap" experiment value: 0 (unlimited), 20, or 100'),offset:I1.nonNegativeInt().optional().describe('Skip first N lines/entries before applying head_limit, equivalent to "| tail -n +N | head -N". Works across all output modes. Defaults to 0'),multiline:k2.boolean().default(!1).describe("Enable multiline mode where . matches newlines and patterns can span lines (rg -U --multiline-dotall). Default: false")}),description:{short:"A powerful search tool built on ripgrep",long:'A powerful search tool built on ripgrep\n\n Usage:\n - ALWAYS use Grep for search tasks. NEVER invoke `grep` or `rg` as a Bash command. The Grep tool has been optimized for correct permissions and access.\n - Supports full regex syntax (e.g., "log.*Error", "function\\s+\\w+")\n - Filter files with glob parameter (e.g., "*.js", "**/*.tsx") or type parameter (e.g., "js", "py", "rust")\n - Output modes: "content" shows matching lines, "files_with_matches" shows only file paths (default), "count" shows match counts\n - Use Task tool for open-ended searches requiring multiple rounds\n - Pattern syntax: Uses ripgrep (not grep) - literal braces need escaping (use `interface\\{\\}` to find `interface{}` in Go code)\n - Multiline matching: By default patterns match within single lines only. For cross-line patterns like `struct \\{[\\s\\S]*?field`, use `multiline: true`\n'},async execute($,Y){let{pattern:Z,path:X=process.cwd(),glob:Q,type:J,output_mode:q,"-i":K,"-n":G=!0,"-B":U,"-A":O,"-C":W,head_limit:F,offset:H,multiline:z}=$,{updateOutput:N}=Y,L=Y.signal??new AbortController().signal;try{N?.(`使用智能搜索策略查找模式 "${Z}"...`);let B=null,_="ripgrep",I=[],M=$Z();if(M)try{N?.(`\uD83D\uDE80 使用 ripgrep (${M})`);let R=jU({pattern:Z,path:X,glob:Q,type:J,output_mode:q,case_insensitive:K??!1,line_numbers:G,context_before:U,context_after:O,context:W,head_limit:F,offset:H,multiline:z??!1});B=await bU(R,q,L,N),_="ripgrep"}catch(R){N?.("⚠️ ripgrep 失败,尝试降级策略..."),B=null}if(!B&&await wU(X))try{N?.("\uD83D\uDCE6 使用 git grep"),B=await RU(Z,X,{caseInsensitive:K??!1,glob:Q,contextLines:W},L),_="git-grep"}catch(R){N?.("⚠️ git grep 失败,继续尝试其他策略..."),B=null}if(!B&&AU())try{N?.("\uD83D\uDD27 使用系统 grep"),B=await VU(Z,X,{caseInsensitive:K??!1,contextLines:W},L),_="system-grep"}catch(R){N?.("⚠️ 系统 grep 失败,使用纯 JavaScript 实现..."),B=null}if(!B)N?.("\uD83D\uDCA1 使用纯 JavaScript 搜索实现"),I=(await DU(Z,X,{caseInsensitive:K??!1,glob:Q,multiline:z??!1},L)).matches,_="fallback",B={stdout:"",stderr:"",exitCode:0};else I=yU(B.stdout,q);let A=I.length;if(H!==void 0&&H>0)I=I.slice(H);if(F!==void 0&&I.length>F)I=I.slice(0,F);let D={search_pattern:Z,search_path:X,output_mode:q,case_insensitive:K??!1,total_matches:I.length,original_total:A,offset:H,head_limit:F,strategy:_,exit_code:B?.exitCode};if(B&&B.exitCode!==0&&B.stderr)return{success:!1,llmContent:`Search execution failed: ${B.stderr}`,displayContent:`❌ 搜索执行失败: ${B.stderr}`,error:{type:"execution_error",message:B.stderr}};let w=vU(D);return{success:!0,llmContent:I,displayContent:w,metadata:D}}catch(B){if(B.name==="AbortError")return{success:!1,llmContent:"Search aborted",displayContent:"⚠️ 搜索被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`Search failed: ${B.message}`,displayContent:`❌ 搜索失败: ${B.message}`,error:{type:"execution_error",message:B.message,details:B}}}},version:"3.0.0",category:"搜索工具",tags:["search","grep","ripgrep","regex","text","fallback"],extractSignatureContent:($)=>$.pattern,abstractPermissionRule:()=>"*"})});var XZ=b(()=>{tY();ZZ()});import{spawn as PU}from"child_process";import{randomUUID as TU}from"crypto";class N0{static instance=null;processes=new Map;static getInstance(){if(!N0.instance)N0.instance=new N0;return N0.instance}startBackgroundProcess($){let Y=`bash_${TU()}`,Z={};for(let[J,q]of Object.entries({...process.env,...$.env,BLADE_CLI:"1"}))if(q!==void 0)Z[J]=q;let X=PU("bash",["-c",$.command],{cwd:$.cwd||process.cwd(),env:Z,stdio:["ignore","pipe","pipe"]}),Q={id:Y,command:$.command,sessionId:$.sessionId,cwd:$.cwd,env:$.env,process:X,pid:X.pid,status:"running",startTime:Date.now(),pendingStdout:"",pendingStderr:""};return X.stdout?.setEncoding("utf8"),X.stderr?.setEncoding("utf8"),X.stdout?.on("data",(J)=>{Q.pendingStdout+=J.toString()}),X.stderr?.on("data",(J)=>{Q.pendingStderr+=J.toString()}),X.on("close",(J,q)=>{Q.status=Q.status==="killed"?"killed":"exited",Q.exitCode=J,Q.signal=q,Q.endTime=Date.now(),Q.process=void 0}),X.on("error",(J)=>{Q.status="error",Q.errorMessage=J.message,Q.endTime=Date.now(),Q.process=void 0,Q.pendingStderr+=`
902
+ [error] ${J.message}`}),this.processes.set(Y,Q),Q}consumeOutput($){let Y=this.processes.get($);if(!Y)return;let Z={id:Y.id,command:Y.command,status:Y.status,stdout:Y.pendingStdout,stderr:Y.pendingStderr,exitCode:Y.exitCode,signal:Y.signal,pid:Y.pid,startedAt:Y.startTime,endedAt:Y.endTime,errorMessage:Y.errorMessage};return Y.pendingStdout="",Y.pendingStderr="",Z}getProcess($){return this.processes.get($)}kill($){let Y=this.processes.get($);if(!Y)return;if(Y.status!=="running"||!Y.process)return{success:!1,alreadyExited:!0,status:Y.status,pid:Y.pid,exitCode:Y.exitCode,signal:Y.signal};if(!Y.process.kill("SIGTERM"))return{success:!1,alreadyExited:!1,status:Y.status,pid:Y.pid,exitCode:Y.exitCode,signal:Y.signal};return Y.status="killed",Y.endTime=Date.now(),Y.process=void 0,{success:!0,alreadyExited:!1,status:Y.status,pid:Y.pid,exitCode:Y.exitCode,signal:Y.signal}}killAll(){for(let[$,Y]of this.processes)if(Y.status==="running"&&Y.process)try{Y.process.kill("SIGTERM"),Y.status="killed",Y.endTime=Date.now(),Y.process=void 0}catch{}this.processes.clear()}}var S$=()=>{};import{spawn as SU}from"child_process";import{randomUUID as kU}from"crypto";import{z as s9}from"zod";function CU($,Y,Z){let Q=N0.getInstance().startBackgroundProcess({command:$,sessionId:kU(),cwd:Y||process.cwd(),env:Z}),q=`后台启动命令: ${$.length>30?`${$.substring(0,30)}...`:$}`,K={command:$,background:!0,pid:Q.pid,bash_id:Q.id,shell_id:Q.id,message:"命令已在后台启动",summary:q},G=`✅ 命令已在后台启动
901
903
  `+`\uD83C\uDD94 进程 ID: ${Q.pid}
902
904
  `+`\uD83D\uDCA1 Bash ID: ${Q.id}
903
- `+"⚠️ 使用 BashOutput/KillShell 管理后台进程";return{success:!0,llmContent:{command:$,background:!0,pid:Q.pid,bash_id:Q.id,shell_id:Q.id},displayContent:K,metadata:G}}async function zU($,Y,Z,X,Q,J){let q=Date.now();try{let K=await qY().execute($,{cwd:Y||process.cwd(),env:Z,timeout:X,signal:Q,onOutput:(_)=>{J?.(_)}}),W=Date.now()-q;if(Q.aborted||K.error==="Command was aborted"||K.error==="Command was terminated")return{success:!1,llmContent:"Command execution aborted by user",displayContent:`⚠️ 命令执行被用户中止
904
- 输出: ${K.stdout}
905
- 错误: ${K.stderr}`,error:{type:"execution_error",message:"操作被中止"},metadata:{command:$,aborted:!0,stdout:K.stdout,stderr:K.stderr,execution_time:W}};if(K.error==="Command timed out")return{success:!1,llmContent:`Command execution timed out (${X}ms)`,displayContent:`⏱️ 命令执行超时 (${X}ms)
906
- 输出: ${K.stdout}
907
- 错误: ${K.stderr}`,error:{type:"timeout_error",message:"命令执行超时"},metadata:{command:$,timeout:!0,stdout:K.stdout,stderr:K.stderr,execution_time:W}};let O=$.length>30?`${$.substring(0,30)}...`:$,U=K.exitCode===0?`执行命令成功 (${W}ms): ${O}`:`执行命令完成 (退出码 ${K.exitCode}, ${W}ms): ${O}`,F={command:$,execution_time:W,exit_code:K.exitCode,stdout_length:K.stdout.length,stderr_length:K.stderr.length,has_stderr:K.stderr.length>0,acp_mode:!0,summary:U},H=gY({stdout:K.stdout,stderr:K.stderr,command:$,execution_time:W,exit_code:K.exitCode,signal:null});return{success:K.success,llmContent:{stdout:K.stdout.trim(),stderr:K.stderr.trim(),execution_time:W,exit_code:K.exitCode},displayContent:H,metadata:F}}catch(G){let K=Date.now()-q;return{success:!1,llmContent:`Command execution failed: ${G.message}`,displayContent:`❌ 命令执行失败: ${G.message}`,error:{type:"execution_error",message:G.message,details:G},metadata:{command:$,execution_time:K,error:G.message}}}}async function NU($,Y,Z,X,Q,J){return new Promise((q)=>{let G=Date.now(),K="",W="",O=!1,U=FU("bash",["-c",$],{cwd:Y||process.cwd(),env:{...process.env,...Z,BLADE_CLI:"1"},stdio:["pipe","pipe","pipe"]});U.stdout.on("data",(_)=>{K+=_.toString()}),U.stderr.on("data",(_)=>{W+=_.toString()});let F=setTimeout(()=>{O=!0,U.kill("SIGTERM"),setTimeout(()=>{if(!U.killed)U.kill("SIGKILL")},1000)},X),H=()=>{U.kill("SIGTERM"),clearTimeout(F)};if(Q.addEventListener)Q.addEventListener("abort",H);else if("onabort"in Q)Q.onabort=H;U.on("close",(_,z)=>{if(clearTimeout(F),Q.removeEventListener)Q.removeEventListener("abort",H);else if("onabort"in Q)Q.onabort=null;let L=Date.now()-G;if(O){q({success:!1,llmContent:`Command execution timed out (${X}ms)`,displayContent:`⏱️ 命令执行超时 (${X}ms)
908
- 输出: ${K}
909
- 错误: ${W}`,error:{type:"timeout_error",message:"命令执行超时"},metadata:{command:$,timeout:!0,stdout:K,stderr:W,execution_time:L}});return}if(Q.aborted){q({success:!1,llmContent:"Command execution aborted by user",displayContent:`⚠️ 命令执行被用户中止
910
- 输出: ${K}
911
- 错误: ${W}`,error:{type:"execution_error",message:"操作被中止"},metadata:{command:$,aborted:!0,stdout:K,stderr:W,execution_time:L}});return}let B=$.length>30?`${$.substring(0,30)}...`:$,N=_===0?`执行命令成功 (${L}ms): ${B}`:`执行命令完成 (退出码 ${_}, ${L}ms): ${B}`,I={command:$,execution_time:L,exit_code:_,signal:z,stdout_length:K.length,stderr_length:W.length,has_stderr:W.length>0,summary:N},M=gY({stdout:K,stderr:W,command:$,execution_time:L,exit_code:_,signal:z});q({success:!0,llmContent:{stdout:K.trim(),stderr:W.trim(),execution_time:L,exit_code:_,signal:z},displayContent:M,metadata:I})}),U.on("error",(_)=>{if(clearTimeout(F),Q.removeEventListener)Q.removeEventListener("abort",H);else if("onabort"in Q)Q.onabort=null;q({success:!1,llmContent:`Command execution failed: ${_.message}`,displayContent:`❌ 命令执行失败: ${_.message}`,error:{type:"execution_error",message:_.message,details:_}})})})}function gY($){let{stdout:Y,stderr:Z,command:X,execution_time:Q,exit_code:J,signal:q}=$,G=`✅ Bash 命令执行完成: ${X}`;if(G+=`
912
- ⏱️ 执行时间: ${Q}ms`,G+=`
913
- \uD83D\uDCCA 退出码: ${J??"N/A"}`,q)G+=`
914
- ⚡ 信号: ${q}`;if(Y&&Y.trim())G+=`
905
+ `+"⚠️ 使用 BashOutput/KillShell 管理后台进程";return{success:!0,llmContent:{command:$,background:!0,pid:Q.pid,bash_id:Q.id,shell_id:Q.id},displayContent:G,metadata:K}}async function fU($,Y,Z,X,Q,J){let q=Date.now();try{let G=await DY().execute($,{cwd:Y||process.cwd(),env:Z,timeout:X,signal:Q,onOutput:(z)=>{J?.(z)}}),U=Date.now()-q;if(Q.aborted||G.error==="Command was aborted"||G.error==="Command was terminated")return{success:!1,llmContent:"Command execution aborted by user",displayContent:`⚠️ 命令执行被用户中止
906
+ 输出: ${G.stdout}
907
+ 错误: ${G.stderr}`,error:{type:"execution_error",message:"操作被中止"},metadata:{command:$,aborted:!0,stdout:G.stdout,stderr:G.stderr,execution_time:U}};if(G.error==="Command timed out")return{success:!1,llmContent:`Command execution timed out (${X}ms)`,displayContent:`⏱️ 命令执行超时 (${X}ms)
908
+ 输出: ${G.stdout}
909
+ 错误: ${G.stderr}`,error:{type:"timeout_error",message:"命令执行超时"},metadata:{command:$,timeout:!0,stdout:G.stdout,stderr:G.stderr,execution_time:U}};let O=$.length>30?`${$.substring(0,30)}...`:$,W=G.exitCode===0?`执行命令成功 (${U}ms): ${O}`:`执行命令完成 (退出码 ${G.exitCode}, ${U}ms): ${O}`,F={command:$,execution_time:U,exit_code:G.exitCode,stdout_length:G.stdout.length,stderr_length:G.stderr.length,has_stderr:G.stderr.length>0,acp_mode:!0,summary:W},H=QZ({stdout:G.stdout,stderr:G.stderr,command:$,execution_time:U,exit_code:G.exitCode,signal:null});return{success:G.success,llmContent:{stdout:G.stdout.trim(),stderr:G.stderr.trim(),execution_time:U,exit_code:G.exitCode},displayContent:H,metadata:F}}catch(K){let G=Date.now()-q;return{success:!1,llmContent:`Command execution failed: ${K.message}`,displayContent:`❌ 命令执行失败: ${K.message}`,error:{type:"execution_error",message:K.message,details:K},metadata:{command:$,execution_time:G,error:K.message}}}}async function hU($,Y,Z,X,Q,J){return new Promise((q)=>{let K=Date.now(),G="",U="",O=!1,W=SU("bash",["-c",$],{cwd:Y||process.cwd(),env:{...process.env,...Z,BLADE_CLI:"1"},stdio:["pipe","pipe","pipe"]});W.stdout.on("data",(z)=>{G+=z.toString()}),W.stderr.on("data",(z)=>{U+=z.toString()});let F=setTimeout(()=>{O=!0,W.kill("SIGTERM"),setTimeout(()=>{if(!W.killed)W.kill("SIGKILL")},1000)},X),H=()=>{W.kill("SIGTERM"),clearTimeout(F)};if(Q.addEventListener)Q.addEventListener("abort",H);else if("onabort"in Q)Q.onabort=H;W.on("close",(z,N)=>{if(clearTimeout(F),Q.removeEventListener)Q.removeEventListener("abort",H);else if("onabort"in Q)Q.onabort=null;let L=Date.now()-K;if(O){q({success:!1,llmContent:`Command execution timed out (${X}ms)`,displayContent:`⏱️ 命令执行超时 (${X}ms)
910
+ 输出: ${G}
911
+ 错误: ${U}`,error:{type:"timeout_error",message:"命令执行超时"},metadata:{command:$,timeout:!0,stdout:G,stderr:U,execution_time:L}});return}if(Q.aborted){q({success:!1,llmContent:"Command execution aborted by user",displayContent:`⚠️ 命令执行被用户中止
912
+ 输出: ${G}
913
+ 错误: ${U}`,error:{type:"execution_error",message:"操作被中止"},metadata:{command:$,aborted:!0,stdout:G,stderr:U,execution_time:L}});return}let B=$.length>30?`${$.substring(0,30)}...`:$,_=z===0?`执行命令成功 (${L}ms): ${B}`:`执行命令完成 (退出码 ${z}, ${L}ms): ${B}`,I={command:$,execution_time:L,exit_code:z,signal:N,stdout_length:G.length,stderr_length:U.length,has_stderr:U.length>0,summary:_},M=QZ({stdout:G,stderr:U,command:$,execution_time:L,exit_code:z,signal:N});q({success:!0,llmContent:{stdout:G.trim(),stderr:U.trim(),execution_time:L,exit_code:z,signal:N},displayContent:M,metadata:I})}),W.on("error",(z)=>{if(clearTimeout(F),Q.removeEventListener)Q.removeEventListener("abort",H);else if("onabort"in Q)Q.onabort=null;q({success:!1,llmContent:`Command execution failed: ${z.message}`,displayContent:`❌ 命令执行失败: ${z.message}`,error:{type:"execution_error",message:z.message,details:z}})})})}function QZ($){let{stdout:Y,stderr:Z,command:X,execution_time:Q,exit_code:J,signal:q}=$,K=`✅ Bash 命令执行完成: ${X}`;if(K+=`
914
+ ⏱️ 执行时间: ${Q}ms`,K+=`
915
+ \uD83D\uDCCA 退出码: ${J??"N/A"}`,q)K+=`
916
+ ⚡ 信号: ${q}`;if(Y&&Y.trim())K+=`
915
917
  \uD83D\uDCE4 输出:
916
- ${Y.trim()}`;if(Z&&Z.trim())G+=`
918
+ ${Y.trim()}`;if(Z&&Z.trim())K+=`
917
919
  ⚠️ 错误输出:
918
- ${Z.trim()}`;return G}var d8;var uY=b(()=>{j$();g1();e1();E2();E$();d8=U1({name:"Bash",displayName:"Bash Command",kind:"execute",schema:m8.object({command:b1.command({description:"Bash command to execute"}),timeout:b1.timeout(1000,300000,30000),cwd:m8.string().optional().describe("Working directory (optional; applies only to this command). To persist, use cd"),env:b1.environment(),run_in_background:m8.boolean().default(!1).describe("Run in background (suitable for long-running commands)")}),description:{short:"Execute bash commands in a persistent shell session with optional timeout",long:`Executes bash commands with proper handling and security measures.
920
+ ${Z.trim()}`;return K}var t9;var JZ=b(()=>{v$();m1();Z0();S2();S$();t9=U1({name:"Bash",displayName:"Bash Command",kind:"execute",schema:s9.object({command:I1.command({description:"Bash command to execute"}),timeout:I1.timeout(1000,300000,30000),cwd:s9.string().optional().describe("Working directory (optional; applies only to this command). To persist, use cd"),env:I1.environment(),run_in_background:s9.boolean().default(!1).describe("Run in background (suitable for long-running commands)")}),description:{short:"Execute bash commands in a persistent shell session with optional timeout",long:`Executes bash commands with proper handling and security measures.
919
921
 
920
922
  IMPORTANT: This tool is for terminal operations like git, npm, docker, etc. DO NOT use it for file operations (reading, writing, editing, searching, finding files) - use the specialized tools for this instead.
921
923
 
@@ -931,16 +933,16 @@ Before executing commands:
931
933
  * cd "/Users/name/My Documents" (correct)
932
934
  * cd /Users/name/My Documents (incorrect - will fail)
933
935
  * python "/path/with spaces/script.py" (correct)
934
- * python /path/with spaces/script.py (incorrect - will fail)`,usageNotes:["The command argument is required","You can specify an optional timeout in milliseconds (up to 600000ms / 10 minutes). If not specified, commands will timeout after 30000ms (30 seconds)","It is very helpful if you write a clear, concise description of what this command does in 5-10 words","If the output exceeds 30000 characters, output will be truncated before being returned to you",'You can use the run_in_background parameter to run the command in the background, which allows you to continue working while the command runs. You can monitor the output using the BashOutput tool. You do not need to use "&" at the end of the command when using this parameter',"Avoid using Bash with the find, grep, cat, head, tail, sed, awk, or echo commands, unless explicitly instructed or when these commands are truly necessary for the task. Instead, always prefer using the dedicated tools for these commands:"," - File search: Use Glob (NOT find or ls)"," - Content search: Use Grep (NOT grep or rg)"," - Read files: Use Read (NOT cat/head/tail)"," - Edit files: Use Edit (NOT sed/awk)"," - Write files: Use Write (NOT echo >/cat <<EOF)"," - Communication: Output text directly (NOT echo/printf)","When issuing multiple commands:",' - If the commands are independent and can run in parallel, make multiple Bash tool calls in a single message. For example, if you need to run "git status" and "git diff", send a single message with two Bash tool calls in parallel',' - If the commands depend on each other and must run sequentially, use a single Bash call with "&&" to chain them together (e.g., git add . && git commit -m "message" && git push). For instance, if one operation must complete before another starts (like mkdir before cp, Write before Bash for git operations, or git add before git commit), run these operations sequentially instead',` - Use ";" only when you need to run commands sequentially but don't care if earlier commands fail`," - DO NOT use newlines to separate commands (newlines are ok in quoted strings)","Try to maintain your current working directory throughout the session by using absolute paths and avoiding usage of cd. You may use cd if the User explicitly requests it"," Good example: pytest /foo/bar/tests"," Bad example: cd /foo/bar && pytest tests"],examples:[{description:"Run a simple command",params:{command:"ls -la",description:"List files in current directory"}},{description:"Temporarily change working directory (this command only)",params:{command:"npm install",cwd:"/path/to/project",description:"Install package dependencies"}},{description:"Persistently change working directory",params:{command:"cd /path/to/project && npm install",description:"Change directory and install dependencies"}},{description:"Run a long-running command in background",params:{command:"npm run dev",run_in_background:!0,description:"Start development server in background"}},{description:"Run multiple independent commands in parallel",params:{command:"git status",description:"Show working tree status"}}],important:["Committing changes with git:"," - Only create commits when requested by the user. If unclear, ask first"," - Git Safety Protocol:"," * NEVER update the git config"," * NEVER run destructive/irreversible git commands (like push --force, hard reset, etc) unless the user explicitly requests them"," * NEVER skip hooks (--no-verify, --no-gpg-sign, etc) unless the user explicitly requests it"," * NEVER run force push to main/master, warn the user if they request it"," * Avoid git commit --amend. ONLY use --amend when either (1) user explicitly requested amend OR (2) adding edits from pre-commit hook",' * Before amending: ALWAYS check authorship (git log -1 --format="%an %ae")'," * NEVER commit changes unless the user explicitly asks you to"," - When creating commits:"," 1. Run git status, git diff, and git log in parallel to understand changes",' 2. Analyze staged changes and draft a concise commit message (1-2 sentences) focusing on "why" rather than "what"'," 3. Add relevant untracked files, create the commit, and run git status to verify"," 4. Always pass commit message via HEREDOC format"," - DO NOT push to remote repository unless explicitly requested"," - NEVER use git commands with the -i flag (no interactive input supported)"," - If no changes to commit, do not create an empty commit","Creating pull requests:"," - Use the gh command for ALL GitHub-related tasks"," - When creating a PR:"," 1. Run git status, git diff, and git log in parallel to understand branch changes"," 2. Analyze all commits (not just the latest) and draft a PR summary"," 3. Create new branch if needed, push with -u flag, and create PR using gh pr create with HEREDOC body format"," - Return the PR URL when done","Other important notes:"," - Dangerous commands (rm -rf, sudo, etc.) require user confirmation"," - Background commands require manual termination using KillShell"," - NEVER use find, grep, cat, sed, etc. — use dedicated tools instead"]},async execute($,Y){let{command:Z,timeout:X=30000,cwd:Q,env:J,run_in_background:q=!1}=$,{updateOutput:G}=Y,K=Y.signal??new AbortController().signal;try{if(G?.(`Executing Bash command: ${Z}`),q)return _U(Z,Q,J);if(v2())return G?.("通过 IDE 终端执行命令..."),zU(Z,Q,J,X,K,G);else return NU(Z,Q,J,X,K,G)}catch(W){let O=W;if(O.name==="AbortError")return{success:!1,llmContent:"Command execution aborted",displayContent:"⚠️ 命令执行被用户中止",error:{type:"execution_error",message:"Operation aborted"}};return{success:!1,llmContent:`Command execution failed: ${O.message}`,displayContent:`❌ 命令执行失败: ${O.message}`,error:{type:"execution_error",message:O.message,details:O}}}},version:"2.0.0",category:"命令工具",tags:["bash","shell","non-interactive","event-driven"],extractSignatureContent:($)=>{return $.command.trim()},abstractPermissionRule:($)=>{let Z=$.command.trim().split(/\s+/);if(Z.length===1)return Z[0];if(["run","exec","test","start","build","dev"].includes(Z[1])){if(Z.length===2)return`${Z[0]} ${Z[1]}`;return`${Z[0]} ${Z[1]} *`}if(Z.length===2)return`${Z[0]} ${Z[1]}`;return`${Z[0]} ${Z[1]} *`}})});import{z as c8}from"zod";function BU($,Y){let Z=mY($.stdout).filter((Q)=>{if(!Y)return!0;return Y.lastIndex=0,Y.test(Q)}),X=mY($.stderr).filter((Q)=>{if(!Y)return!0;return Y.lastIndex=0,Y.test(Q)});return{stdoutLines:Z,stderrLines:X}}function mY($){if(!$)return[];return $.replace(/\r\n/g,`
936
+ * python /path/with spaces/script.py (incorrect - will fail)`,usageNotes:["The command argument is required","You can specify an optional timeout in milliseconds (up to 600000ms / 10 minutes). If not specified, commands will timeout after 30000ms (30 seconds)","It is very helpful if you write a clear, concise description of what this command does in 5-10 words","If the output exceeds 30000 characters, output will be truncated before being returned to you",'You can use the run_in_background parameter to run the command in the background, which allows you to continue working while the command runs. You can monitor the output using the BashOutput tool. You do not need to use "&" at the end of the command when using this parameter',"Avoid using Bash with the find, grep, cat, head, tail, sed, awk, or echo commands, unless explicitly instructed or when these commands are truly necessary for the task. Instead, always prefer using the dedicated tools for these commands:"," - File search: Use Glob (NOT find or ls)"," - Content search: Use Grep (NOT grep or rg)"," - Read files: Use Read (NOT cat/head/tail)"," - Edit files: Use Edit (NOT sed/awk)"," - Write files: Use Write (NOT echo >/cat <<EOF)"," - Communication: Output text directly (NOT echo/printf)","When issuing multiple commands:",' - If the commands are independent and can run in parallel, make multiple Bash tool calls in a single message. For example, if you need to run "git status" and "git diff", send a single message with two Bash tool calls in parallel',' - If the commands depend on each other and must run sequentially, use a single Bash call with "&&" to chain them together (e.g., git add . && git commit -m "message" && git push). For instance, if one operation must complete before another starts (like mkdir before cp, Write before Bash for git operations, or git add before git commit), run these operations sequentially instead',` - Use ";" only when you need to run commands sequentially but don't care if earlier commands fail`," - DO NOT use newlines to separate commands (newlines are ok in quoted strings)","Try to maintain your current working directory throughout the session by using absolute paths and avoiding usage of cd. You may use cd if the User explicitly requests it"," Good example: pytest /foo/bar/tests"," Bad example: cd /foo/bar && pytest tests"],examples:[{description:"Run a simple command",params:{command:"ls -la",description:"List files in current directory"}},{description:"Temporarily change working directory (this command only)",params:{command:"npm install",cwd:"/path/to/project",description:"Install package dependencies"}},{description:"Persistently change working directory",params:{command:"cd /path/to/project && npm install",description:"Change directory and install dependencies"}},{description:"Run a long-running command in background",params:{command:"npm run dev",run_in_background:!0,description:"Start development server in background"}},{description:"Run multiple independent commands in parallel",params:{command:"git status",description:"Show working tree status"}}],important:["Committing changes with git:"," - Only create commits when requested by the user. If unclear, ask first"," - Git Safety Protocol:"," * NEVER update the git config"," * NEVER run destructive/irreversible git commands (like push --force, hard reset, etc) unless the user explicitly requests them"," * NEVER skip hooks (--no-verify, --no-gpg-sign, etc) unless the user explicitly requests it"," * NEVER run force push to main/master, warn the user if they request it"," * Avoid git commit --amend. ONLY use --amend when either (1) user explicitly requested amend OR (2) adding edits from pre-commit hook",' * Before amending: ALWAYS check authorship (git log -1 --format="%an %ae")'," * NEVER commit changes unless the user explicitly asks you to"," - When creating commits:"," 1. Run git status, git diff, and git log in parallel to understand changes",' 2. Analyze staged changes and draft a concise commit message (1-2 sentences) focusing on "why" rather than "what"'," 3. Add relevant untracked files, create the commit, and run git status to verify"," 4. Always pass commit message via HEREDOC format"," - DO NOT push to remote repository unless explicitly requested"," - NEVER use git commands with the -i flag (no interactive input supported)"," - If no changes to commit, do not create an empty commit","Creating pull requests:"," - Use the gh command for ALL GitHub-related tasks"," - When creating a PR:"," 1. Run git status, git diff, and git log in parallel to understand branch changes"," 2. Analyze all commits (not just the latest) and draft a PR summary"," 3. Create new branch if needed, push with -u flag, and create PR using gh pr create with HEREDOC body format"," - Return the PR URL when done","Other important notes:"," - Dangerous commands (rm -rf, sudo, etc.) require user confirmation"," - Background commands require manual termination using KillShell"," - NEVER use find, grep, cat, sed, etc. — use dedicated tools instead"]},async execute($,Y){let{command:Z,timeout:X=30000,cwd:Q,env:J,run_in_background:q=!1}=$,{updateOutput:K}=Y,G=Y.signal??new AbortController().signal;try{if(K?.(`Executing Bash command: ${Z}`),q)return CU(Z,Q,J);if(T2())return K?.("通过 IDE 终端执行命令..."),fU(Z,Q,J,X,G,K);else return hU(Z,Q,J,X,G,K)}catch(U){let O=U;if(O.name==="AbortError")return{success:!1,llmContent:"Command execution aborted",displayContent:"⚠️ 命令执行被用户中止",error:{type:"execution_error",message:"Operation aborted"}};return{success:!1,llmContent:`Command execution failed: ${O.message}`,displayContent:`❌ 命令执行失败: ${O.message}`,error:{type:"execution_error",message:O.message,details:O}}}},version:"2.0.0",category:"命令工具",tags:["bash","shell","non-interactive","event-driven"],extractSignatureContent:($)=>{return $.command.trim()},abstractPermissionRule:($)=>{let Z=$.command.trim().split(/\s+/);if(Z.length===1)return Z[0];if(["run","exec","test","start","build","dev"].includes(Z[1])){if(Z.length===2)return`${Z[0]} ${Z[1]}`;return`${Z[0]} ${Z[1]} *`}if(Z.length===2)return`${Z[0]} ${Z[1]}`;return`${Z[0]} ${Z[1]} *`}})});import{z as e9}from"zod";function xU($,Y){let Z=qZ($.stdout).filter((Q)=>{if(!Y)return!0;return Y.lastIndex=0,Y.test(Q)}),X=qZ($.stderr).filter((Q)=>{if(!Y)return!0;return Y.lastIndex=0,Y.test(Q)});return{stdoutLines:Z,stderrLines:X}}function qZ($){if(!$)return[];return $.replace(/\r\n/g,`
935
937
  `).split(`
936
- `)}function LU($,Y,Z){let Q=`${$.status==="running"?"⏳":$.status==="exited"?"✅":$.status==="killed"?"✂️":"⚠️"} BashOutput(${$.id}) - 状态: ${$.status}`;if(Q+=`
938
+ `)}function pU($,Y,Z){let Q=`${$.status==="running"?"⏳":$.status==="exited"?"✅":$.status==="killed"?"✂️":"⚠️"} BashOutput(${$.id}) - 状态: ${$.status}`;if(Q+=`
937
939
  命令: ${$.command}`,$.pid)Q+=`
938
940
  PID: ${$.pid}`;if($.exitCode!==void 0&&$.exitCode!==null)Q+=`
939
941
  退出码: ${$.exitCode}`;if($.signal)Q+=`
940
942
  信号: ${$.signal}`;if(Y===0&&Z===0)Q+=`
941
943
  无新的输出`;else Q+=`
942
944
  stdout 行数: ${Y}`,Q+=`
943
- stderr 行数: ${Z}`;return Q}var l8;var dY=b(()=>{g1();e1();E$();l8=U1({name:"BashOutput",displayName:"后台命令输出",kind:"readonly",schema:c8.object({bash_id:c8.string().min(1).describe("Background bash session ID"),filter:c8.string().optional().describe("Optional regex filter: only return matching lines; non-matching lines are discarded")}),description:{short:"Retrieves output from a running or completed background bash shell",long:`
945
+ stderr 行数: ${Z}`;return Q}var $7;var KZ=b(()=>{m1();Z0();S$();$7=U1({name:"BashOutput",displayName:"后台命令输出",kind:"readonly",schema:e9.object({bash_id:e9.string().min(1).describe("Background bash session ID"),filter:e9.string().optional().describe("Optional regex filter: only return matching lines; non-matching lines are discarded")}),description:{short:"Retrieves output from a running or completed background bash shell",long:`
944
946
  - Retrieves output from a running or completed background bash shell
945
947
  - Takes a shell_id parameter identifying the shell
946
948
  - Always returns only new output since the last check
@@ -948,17 +950,17 @@ stderr 行数: ${Z}`;return Q}var l8;var dY=b(()=>{g1();e1();E$();l8=U1({name:"B
948
950
  - Supports optional regex filtering to show only lines matching a pattern
949
951
  - Use this tool when you need to monitor or check the output of a long-running shell
950
952
  - Shell IDs can be found using the /tasks command
951
- `},async execute($,Y){let Z=F0.getInstance(),X;if($.filter)try{X=new RegExp($.filter)}catch(W){return{success:!1,llmContent:`Invalid regular expression: ${$.filter}
953
+ `},async execute($,Y){let Z=N0.getInstance(),X;if($.filter)try{X=new RegExp($.filter)}catch(U){return{success:!1,llmContent:`Invalid regular expression: ${$.filter}
952
954
 
953
955
  \uD83D\uDCA1 Output was not consumed; you can retry`,displayContent:`❌ 无效的正则表达式: ${$.filter}
954
956
 
955
- \uD83D\uDCA1 输出未被消费,可重新尝试`,error:{type:"validation_error",message:W.message}}}let Q=Z.consumeOutput($.bash_id);if(!Q)return{success:!1,llmContent:`Bash session not found: ${$.bash_id}`,displayContent:`❌ 未找到 Bash 会话: ${$.bash_id}`,error:{type:"execution_error",message:"Bash 会话不存在或已清理"}};let{stdoutLines:J,stderrLines:q}=BU(Q,X),G={bash_id:Q.id,status:Q.status,command:Q.command,pid:Q.pid,exit_code:Q.exitCode,signal:Q.signal,started_at:new Date(Q.startedAt).toISOString(),finished_at:Q.endedAt?new Date(Q.endedAt).toISOString():void 0,stdout:J,stderr:q},K=LU(Q,J.length,q.length);return{success:!0,llmContent:G,displayContent:K,metadata:G}},version:"1.0.0",category:"命令工具",tags:["bash","shell","monitor"],extractSignatureContent:($)=>$.bash_id,abstractPermissionRule:()=>"*"})});import{z as cY}from"zod";var i8;var lY=b(()=>{g1();e1();E$();i8=U1({name:"KillShell",displayName:"终止后台 Shell",kind:"execute",schema:cY.object({shell_id:cY.string().min(1).describe("Background Shell ID to terminate")}),description:{short:"Kills a running background bash shell by its ID",long:`
957
+ \uD83D\uDCA1 输出未被消费,可重新尝试`,error:{type:"validation_error",message:U.message}}}let Q=Z.consumeOutput($.bash_id);if(!Q)return{success:!1,llmContent:`Bash session not found: ${$.bash_id}`,displayContent:`❌ 未找到 Bash 会话: ${$.bash_id}`,error:{type:"execution_error",message:"Bash 会话不存在或已清理"}};let{stdoutLines:J,stderrLines:q}=xU(Q,X),K={bash_id:Q.id,status:Q.status,command:Q.command,pid:Q.pid,exit_code:Q.exitCode,signal:Q.signal,started_at:new Date(Q.startedAt).toISOString(),finished_at:Q.endedAt?new Date(Q.endedAt).toISOString():void 0,stdout:J,stderr:q},G=pU(Q,J.length,q.length);return{success:!0,llmContent:K,displayContent:G,metadata:K}},version:"1.0.0",category:"命令工具",tags:["bash","shell","monitor"],extractSignatureContent:($)=>$.bash_id,abstractPermissionRule:()=>"*"})});import{z as GZ}from"zod";var Y7;var UZ=b(()=>{m1();Z0();S$();Y7=U1({name:"KillShell",displayName:"终止后台 Shell",kind:"execute",schema:GZ.object({shell_id:GZ.string().min(1).describe("Background Shell ID to terminate")}),description:{short:"Kills a running background bash shell by its ID",long:`
956
958
  - Kills a running background bash shell by its ID
957
959
  - Takes a shell_id parameter identifying the shell to kill
958
960
  - Returns a success or failure status
959
961
  - Use this tool when you need to terminate a long-running shell
960
962
  - Shell IDs can be found using the /tasks command
961
- `},async execute($,Y){let X=F0.getInstance().kill($.shell_id);if(!X)return{success:!1,llmContent:`Shell not found: ${$.shell_id}`,displayContent:`❌ 未找到 Shell: ${$.shell_id}`,error:{type:"execution_error",message:"Shell ID 不存在或已清理"}};if(!X.success&&!X.alreadyExited)return{success:!1,llmContent:`Failed to terminate Shell: ${$.shell_id}`,displayContent:`❌ 无法终止 Shell (${$.shell_id})`,error:{type:"execution_error",message:"发送终止信号失败"},metadata:X};let Q=X.alreadyExited?`Shell ${$.shell_id} 已经处于 ${X.status} 状态`:`已向 Shell ${$.shell_id} 发送终止信号`;return{success:!0,llmContent:{shell_id:$.shell_id,status:X.status,already_exited:X.alreadyExited,pid:X.pid,exit_code:X.exitCode,signal:X.signal},displayContent:X.alreadyExited?`ℹ️ ${Q}`:`✂️ ${Q}`,metadata:X}},version:"1.0.0",category:"命令工具",tags:["bash","shell","terminate"],extractSignatureContent:($)=>$.shell_id,abstractPermissionRule:()=>"*"})});var iY=b(()=>{E$();uY();dY();lY()});import{z as a8}from"zod";function wU($,Y,Z){return`# Skill: ${$}
963
+ `},async execute($,Y){let X=N0.getInstance().kill($.shell_id);if(!X)return{success:!1,llmContent:`Shell not found: ${$.shell_id}`,displayContent:`❌ 未找到 Shell: ${$.shell_id}`,error:{type:"execution_error",message:"Shell ID 不存在或已清理"}};if(!X.success&&!X.alreadyExited)return{success:!1,llmContent:`Failed to terminate Shell: ${$.shell_id}`,displayContent:`❌ 无法终止 Shell (${$.shell_id})`,error:{type:"execution_error",message:"发送终止信号失败"},metadata:X};let Q=X.alreadyExited?`Shell ${$.shell_id} 已经处于 ${X.status} 状态`:`已向 Shell ${$.shell_id} 发送终止信号`;return{success:!0,llmContent:{shell_id:$.shell_id,status:X.status,already_exited:X.alreadyExited,pid:X.pid,exit_code:X.exitCode,signal:X.signal},displayContent:X.alreadyExited?`ℹ️ ${Q}`:`✂️ ${Q}`,metadata:X}},version:"1.0.0",category:"命令工具",tags:["bash","shell","terminate"],extractSignatureContent:($)=>$.shell_id,abstractPermissionRule:()=>"*"})});var WZ=b(()=>{S$();JZ();KZ();UZ()});import{z as Z7}from"zod";function uU($,Y,Z){return`# Skill: ${$}
962
964
 
963
965
  You are now operating in the "${$}" skill mode. Follow the instructions below to complete the task.
964
966
 
@@ -971,7 +973,7 @@ ${Y}
971
973
 
972
974
  ---
973
975
 
974
- Remember: Follow the above instructions carefully to complete the user's request.`}var r8;var aY=b(()=>{j2();g1();n0();r8=U1({name:"Skill",displayName:"Skill",kind:"execute",schema:a8.object({skill:a8.string().describe('The skill name. E.g., "commit-message" or "code-review"'),args:a8.string().optional().describe("Optional arguments for the skill")}),description:{short:"Execute a skill within the main conversation",long:`Execute a skill within the main conversation
976
+ Remember: Follow the above instructions carefully to complete the user's request.`}var X7;var OZ=b(()=>{v2();m1();t0();X7=U1({name:"Skill",displayName:"Skill",kind:"execute",schema:Z7.object({skill:Z7.string().describe('The skill name. E.g., "commit-message" or "code-review"'),args:Z7.string().optional().describe("Optional arguments for the skill")}),description:{short:"Execute a skill within the main conversation",long:`Execute a skill within the main conversation
975
977
 
976
978
  <skills_instructions>
977
979
  When users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge.
@@ -990,19 +992,19 @@ Important:
990
992
  <available_skills>
991
993
 
992
994
  </available_skills>
993
- `},async execute($,Y){let{skill:Z}=$,X=$0();if(!X.has(Z))return{success:!1,llmContent:`Skill "${Z}" not found. Available skills: ${X.getAll().map((q)=>q.name).join(", ")||"none"}`,displayContent:`❌ Skill "${Z}" not found`,error:{type:"validation_error",message:`Skill "${Z}" is not registered`}};let Q=await X.loadContent(Z);if(!Q)return{success:!1,llmContent:`Failed to load skill "${Z}" content`,displayContent:`❌ Failed to load skill "${Z}"`,error:{type:"execution_error",message:`Could not read SKILL.md for "${Z}"`}};return{success:!0,llmContent:wU(Q.metadata.name,Q.instructions,Q.metadata.basePath),displayContent:`<command-message>The "${Z}" skill is loading</command-message>`,metadata:{skillName:Z,basePath:Q.metadata.basePath,version:Q.metadata.version,allowedTools:Q.metadata.allowedTools}}}})});import{execSync as AU}from"node:child_process";import rY from"node:fs";import nY from"node:path";class M4{async execute($,Y){let Z=$.content;if(Y.signal?.aborted)throw Error("Command execution aborted");return Z=this.interpolateArgs(Z,Y.args),Z=await this.executeBashEmbeds(Z,Y),Z=await this.resolveFileReferences(Z,Y.workspaceRoot),Z}interpolateArgs($,Y){$=$.replace(/\$ARGUMENTS/g,Y.join(" "));for(let Z=9;Z>=1;Z--){let X=`$${Z}`,Q=Y[Z-1]??"";$=$.split(X).join(Q)}return $}async executeBashEmbeds($,Y){let Z=/!`([^`]+)`/g,X=[];for(let J of $.matchAll(Z))X.push({match:J[0],command:J[1]});let Q=$;for(let{match:J,command:q}of X){if(Y.signal?.aborted){Q=Q.replace(J,"[Execution aborted]");continue}try{let G=AU(q,{cwd:Y.workspaceRoot,encoding:"utf-8",timeout:30000,maxBuffer:1048576,stdio:["pipe","pipe","pipe"]}).trim();Q=Q.replace(J,G)}catch(G){let K=G instanceof Error?G.message:String(G);Q=Q.replace(J,`[Error executing '${q}': ${K}]`)}}return Q}async resolveFileReferences($,Y){let Z=/@([\w./-]+(?:\/[\w./-]+|\.[\w]+))/g,X=[];for(let J of $.matchAll(Z))X.push({match:J[0],relativePath:J[1]});let Q=$;for(let{match:J,relativePath:q}of X){let G=nY.resolve(Y,q);try{if(rY.statSync(G).isFile()){let W=rY.readFileSync(G,"utf-8"),U=`\`\`\`${nY.extname(q).slice(1)||"text"}
994
- ${W}
995
- \`\`\``;Q=Q.replace(J,U)}}catch{}}return Q}hasDynamicContent($){return{hasArgs:/\$ARGUMENTS|\$\d/.test($),hasBashEmbeds:/!`[^`]+`/.test($),hasFileRefs:/@[\w./-]+(?:\/[\w./-]+|\.[\w]+)/.test($)}}}var n8=()=>{};import bU from"gray-matter";import RU from"node:fs";import oY from"node:path";class j4{parse($,Y,Z,X){try{let Q=RU.readFileSync($,"utf-8"),{data:J,content:q}=bU(Q),{name:G,namespace:K}=this.extractNameAndNamespace($,Y);if(!G)return null;return{name:G,namespace:K,config:this.normalizeConfig(J),content:q.trim(),path:$,source:Z,sourceDir:X}}catch(Q){return console.error(`Failed to parse command file: ${$}`,Q),null}}normalizeConfig($){return{description:this.asString($.description),allowedTools:this.parseAllowedTools($["allowed-tools"]),argumentHint:this.asString($["argument-hint"]),model:this.asString($.model),disableModelInvocation:$["disable-model-invocation"]===!0}}asString($){if(typeof $==="string"&&$.trim())return $.trim();return}parseAllowedTools($){if(!$)return;if(Array.isArray($))return $.map((Y)=>String(Y).trim()).filter(Boolean);if(typeof $==="string")return $.split(",").map((Y)=>Y.trim()).filter(Boolean);return}extractNameAndNamespace($,Y){let X=oY.relative(Y,$).split(oY.sep),Q=X.pop();if(!Q)return{name:""};let J=Q.replace(/\.md$/i,""),q=X.length>0?X.join("/"):void 0;return{name:J,namespace:q}}validateConfig($){let Y=[];if($.model&&!this.isValidModelId($.model))Y.push(`Invalid model ID: ${$.model}`);return Y}isValidModelId($){return $.length>0&&$.length<200}}var o8=()=>{};import s8 from"node:fs";import sY from"node:os";import z2 from"node:path";class y4{parser=new j4;async discover($){let Y=[],Z=[],X=[],Q=this.getSearchDirs($);for(let J of Q){if(!s8.existsSync(J.path))continue;Z.push(J.path);try{let q=await this.scanDirectory(J.path);for(let G of q)try{let K=this.parser.parse(G,J.path,J.source,J.sourceDir);if(K)Y.push(K)}catch(K){X.push({path:G,error:K instanceof Error?K.message:String(K)})}}catch(q){X.push({path:J.path,error:q instanceof Error?q.message:String(q)})}}return{commands:Y,scannedDirs:Z,errors:X}}getSearchDirs($){let Y=sY.homedir();return[{path:z2.join(Y,".blade","commands"),source:"user",sourceDir:"blade"},{path:z2.join(Y,".claude","commands"),source:"user",sourceDir:"claude"},{path:z2.join($,".blade","commands"),source:"project",sourceDir:"blade"},{path:z2.join($,".claude","commands"),source:"project",sourceDir:"claude"}]}async scanDirectory($){let Y=[],Z=async(X)=>{let Q=await s8.promises.readdir(X,{withFileTypes:!0});for(let J of Q){let q=z2.join(X,J.name);if(J.isDirectory())await Z(q);else if(J.isFile()&&J.name.endsWith(".md"))Y.push(q)}};return await Z($),Y}async hasCommands($){let Y=this.getSearchDirs($);for(let Z of Y){if(!s8.existsSync(Z.path))continue;if((await this.scanDirectory(Z.path)).length>0)return!0}return!1}getCommandDirs($){let Y=sY.homedir();return{projectBlade:z2.join($,".blade","commands"),projectClaude:z2.join($,".claude","commands"),userBlade:z2.join(Y,".blade","commands"),userClaude:z2.join(Y,".claude","commands")}}}var t8=b(()=>{o8()});class i1{static instance;commands=new Map;loader=new y4;executor=new M4;initialized=!1;workspaceRoot="";lastDiscoveryResult=null;static getInstance(){if(!i1.instance)i1.instance=new i1;return i1.instance}static resetInstance(){i1.instance=new i1}constructor(){}async initialize($){this.workspaceRoot=$;let Y=await this.loader.discover($);this.lastDiscoveryResult=Y,this.commands.clear();for(let Z of Y.commands)this.commands.set(Z.name,Z);return this.initialized=!0,Y}async refresh(){if(!this.workspaceRoot)throw Error("Registry not initialized. Call initialize() first.");return this.initialize(this.workspaceRoot)}isInitialized(){return this.initialized}getCommand($){return this.commands.get($)}hasCommand($){return this.commands.has($)}getAllCommands(){return Array.from(this.commands.values())}getCommandCount(){return this.commands.size}getModelInvocableCommands(){return this.getAllCommands().filter(($)=>$.config.description&&!$.config.disableModelInvocation)}async executeCommand($,Y){let Z=this.getCommand($);if(!Z)return null;return this.executor.execute(Z,Y)}getCommandLabel($){let Y=$.source==="project"?"project":"user";if($.namespace)return`(${Y}:${$.namespace})`;return`(${Y})`}getCommandDisplayName($){let Y=[`/${$.name}`];if($.config.argumentHint)Y.push($.config.argumentHint);if($.config.description)Y.push("-",$.config.description);return Y.push(this.getCommandLabel($)),Y.join(" ")}getCommandsBySource(){let $=[],Y=[];for(let Z of this.commands.values())if(Z.source==="project")$.push(Z);else Y.push(Z);return{project:$,user:Y}}getLastDiscoveryResult(){return this.lastDiscoveryResult}getCommandDirs(){if(!this.workspaceRoot)return null;return this.loader.getCommandDirs(this.workspaceRoot)}generateCommandListDescription($=15000){let Y=this.getModelInvocableCommands(),Z=Y.length;if(Z===0)return{text:"No custom commands available.",includedCount:0,totalCount:0};let X=`Available custom commands:
995
+ `},async execute($,Y){let{skill:Z}=$,X=X0();if(!X.has(Z))return{success:!1,llmContent:`Skill "${Z}" not found. Available skills: ${X.getAll().map((q)=>q.name).join(", ")||"none"}`,displayContent:`❌ Skill "${Z}" not found`,error:{type:"validation_error",message:`Skill "${Z}" is not registered`}};let Q=await X.loadContent(Z);if(!Q)return{success:!1,llmContent:`Failed to load skill "${Z}" content`,displayContent:`❌ Failed to load skill "${Z}"`,error:{type:"execution_error",message:`Could not read SKILL.md for "${Z}"`}};return{success:!0,llmContent:uU(Q.metadata.name,Q.instructions,Q.metadata.basePath),displayContent:`<command-message>The "${Z}" skill is loading</command-message>`,metadata:{skillName:Z,basePath:Q.metadata.basePath,version:Q.metadata.version,allowedTools:Q.metadata.allowedTools}}}})});import{execSync as gU}from"node:child_process";import FZ from"node:fs";import HZ from"node:path";class E4{async execute($,Y){let Z=$.content;if(Y.signal?.aborted)throw Error("Command execution aborted");return Z=this.interpolateArgs(Z,Y.args),Z=await this.executeBashEmbeds(Z,Y),Z=await this.resolveFileReferences(Z,Y.workspaceRoot),Z}interpolateArgs($,Y){$=$.replace(/\$ARGUMENTS/g,Y.join(" "));for(let Z=9;Z>=1;Z--){let X=`$${Z}`,Q=Y[Z-1]??"";$=$.split(X).join(Q)}return $}async executeBashEmbeds($,Y){let Z=/!`([^`]+)`/g,X=[];for(let J of $.matchAll(Z))X.push({match:J[0],command:J[1]});let Q=$;for(let{match:J,command:q}of X){if(Y.signal?.aborted){Q=Q.replace(J,"[Execution aborted]");continue}try{let K=gU(q,{cwd:Y.workspaceRoot,encoding:"utf-8",timeout:30000,maxBuffer:1048576,stdio:["pipe","pipe","pipe"]}).trim();Q=Q.replace(J,K)}catch(K){let G=K instanceof Error?K.message:String(K);Q=Q.replace(J,`[Error executing '${q}': ${G}]`)}}return Q}async resolveFileReferences($,Y){let Z=/@([\w./-]+(?:\/[\w./-]+|\.[\w]+))/g,X=[];for(let J of $.matchAll(Z))X.push({match:J[0],relativePath:J[1]});let Q=$;for(let{match:J,relativePath:q}of X){let K=HZ.resolve(Y,q);try{if(FZ.statSync(K).isFile()){let U=FZ.readFileSync(K,"utf-8"),W=`\`\`\`${HZ.extname(q).slice(1)||"text"}
996
+ ${U}
997
+ \`\`\``;Q=Q.replace(J,W)}}catch{}}return Q}hasDynamicContent($){return{hasArgs:/\$ARGUMENTS|\$\d/.test($),hasBashEmbeds:/!`[^`]+`/.test($),hasFileRefs:/@[\w./-]+(?:\/[\w./-]+|\.[\w]+)/.test($)}}}var Q7=()=>{};import dU from"gray-matter";import mU from"node:fs";import zZ from"node:path";class v4{parse($,Y,Z,X){try{let Q=mU.readFileSync($,"utf-8"),{data:J,content:q}=dU(Q),{name:K,namespace:G}=this.extractNameAndNamespace($,Y);if(!K)return null;return{name:K,namespace:G,config:this.normalizeConfig(J),content:q.trim(),path:$,source:Z,sourceDir:X}}catch(Q){return console.error(`Failed to parse command file: ${$}`,Q),null}}normalizeConfig($){return{description:this.asString($.description),allowedTools:this.parseAllowedTools($["allowed-tools"]),argumentHint:this.asString($["argument-hint"]),model:this.asString($.model),disableModelInvocation:$["disable-model-invocation"]===!0}}asString($){if(typeof $==="string"&&$.trim())return $.trim();return}parseAllowedTools($){if(!$)return;if(Array.isArray($))return $.map((Y)=>String(Y).trim()).filter(Boolean);if(typeof $==="string")return $.split(",").map((Y)=>Y.trim()).filter(Boolean);return}extractNameAndNamespace($,Y){let X=zZ.relative(Y,$).split(zZ.sep),Q=X.pop();if(!Q)return{name:""};let J=Q.replace(/\.md$/i,""),q=X.length>0?X.join("/"):void 0;return{name:J,namespace:q}}validateConfig($){let Y=[];if($.model&&!this.isValidModelId($.model))Y.push(`Invalid model ID: ${$.model}`);return Y}isValidModelId($){return $.length>0&&$.length<200}}var J7=()=>{};import q7 from"node:fs";import NZ from"node:os";import L2 from"node:path";class P4{parser=new v4;async discover($){let Y=[],Z=[],X=[],Q=this.getSearchDirs($);for(let J of Q){if(!q7.existsSync(J.path))continue;Z.push(J.path);try{let q=await this.scanDirectory(J.path);for(let K of q)try{let G=this.parser.parse(K,J.path,J.source,J.sourceDir);if(G)Y.push(G)}catch(G){X.push({path:K,error:G instanceof Error?G.message:String(G)})}}catch(q){X.push({path:J.path,error:q instanceof Error?q.message:String(q)})}}return{commands:Y,scannedDirs:Z,errors:X}}getSearchDirs($){let Y=NZ.homedir();return[{path:L2.join(Y,".blade","commands"),source:"user",sourceDir:"blade"},{path:L2.join(Y,".claude","commands"),source:"user",sourceDir:"claude"},{path:L2.join($,".blade","commands"),source:"project",sourceDir:"blade"},{path:L2.join($,".claude","commands"),source:"project",sourceDir:"claude"}]}async scanDirectory($){let Y=[],Z=async(X)=>{let Q=await q7.promises.readdir(X,{withFileTypes:!0});for(let J of Q){let q=L2.join(X,J.name);if(J.isDirectory())await Z(q);else if(J.isFile()&&J.name.endsWith(".md"))Y.push(q)}};return await Z($),Y}async hasCommands($){let Y=this.getSearchDirs($);for(let Z of Y){if(!q7.existsSync(Z.path))continue;if((await this.scanDirectory(Z.path)).length>0)return!0}return!1}getCommandDirs($){let Y=NZ.homedir();return{projectBlade:L2.join($,".blade","commands"),projectClaude:L2.join($,".claude","commands"),userBlade:L2.join(Y,".blade","commands"),userClaude:L2.join(Y,".claude","commands")}}}var K7=b(()=>{J7()});class n1{static instance;commands=new Map;loader=new P4;executor=new E4;initialized=!1;workspaceRoot="";lastDiscoveryResult=null;static getInstance(){if(!n1.instance)n1.instance=new n1;return n1.instance}static resetInstance(){n1.instance=new n1}constructor(){}async initialize($){this.workspaceRoot=$;let Y=await this.loader.discover($);this.lastDiscoveryResult=Y,this.commands.clear();for(let Z of Y.commands)this.commands.set(Z.name,Z);return this.initialized=!0,Y}async refresh(){if(!this.workspaceRoot)throw Error("Registry not initialized. Call initialize() first.");return this.initialize(this.workspaceRoot)}isInitialized(){return this.initialized}getCommand($){return this.commands.get($)}hasCommand($){return this.commands.has($)}getAllCommands(){return Array.from(this.commands.values())}getCommandCount(){return this.commands.size}getModelInvocableCommands(){return this.getAllCommands().filter(($)=>$.config.description&&!$.config.disableModelInvocation)}async executeCommand($,Y){let Z=this.getCommand($);if(!Z)return null;return this.executor.execute(Z,Y)}getCommandLabel($){let Y=$.source==="project"?"project":"user";if($.namespace)return`(${Y}:${$.namespace})`;return`(${Y})`}getCommandDisplayName($){let Y=[`/${$.name}`];if($.config.argumentHint)Y.push($.config.argumentHint);if($.config.description)Y.push("-",$.config.description);return Y.push(this.getCommandLabel($)),Y.join(" ")}getCommandsBySource(){let $=[],Y=[];for(let Z of this.commands.values())if(Z.source==="project")$.push(Z);else Y.push(Z);return{project:$,user:Y}}getLastDiscoveryResult(){return this.lastDiscoveryResult}getCommandDirs(){if(!this.workspaceRoot)return null;return this.loader.getCommandDirs(this.workspaceRoot)}generateCommandListDescription($=15000){let Y=this.getModelInvocableCommands(),Z=Y.length;if(Z===0)return{text:"No custom commands available.",includedCount:0,totalCount:0};let X=`Available custom commands:
996
998
 
997
- `,Q=X.length,J=0;for(let q of Y){let G=this.getCommandLabel(q),K=q.config.argumentHint?` ${q.config.argumentHint}`:"",W=`- /${q.name}${K}: ${q.config.description} ${G}
998
- `;if(Q+W.length>$)break;X+=W,Q+=W.length,J++}if(J<Z)X+=`
999
- (${J} of ${Z} commands shown due to character budget)`;return{text:X,includedCount:J,totalCount:Z}}}var tY=b(()=>{n8();t8()});var v4=b(()=>{n8();t8();o8();tY()});import{z as e8}from"zod";function DU(){let $=i1.getInstance();if(!$.isInitialized())return`
1000
- (Custom commands not yet initialized)`;let{text:Y,totalCount:Z}=$.generateCommandListDescription(VU);if(Z===0)return`
999
+ `,Q=X.length,J=0;for(let q of Y){let K=this.getCommandLabel(q),G=q.config.argumentHint?` ${q.config.argumentHint}`:"",U=`- /${q.name}${G}: ${q.config.description} ${K}
1000
+ `;if(Q+U.length>$)break;X+=U,Q+=U.length,J++}if(J<Z)X+=`
1001
+ (${J} of ${Z} commands shown due to character budget)`;return{text:X,includedCount:J,totalCount:Z}}}var BZ=b(()=>{Q7();K7()});var T4=b(()=>{Q7();K7();J7();BZ()});import{z as G7}from"zod";function lU(){let $=n1.getInstance();if(!$.isInitialized())return`
1002
+ (Custom commands not yet initialized)`;let{text:Y,totalCount:Z}=$.generateCommandListDescription(cU);if(Z===0)return`
1001
1003
  (No custom commands available)`;return`
1002
1004
 
1003
1005
  <available_commands>
1004
1006
  ${Y}
1005
- </available_commands>`}function IU($,Y,Z){let X=`# Custom Command: /${$}
1007
+ </available_commands>`}function iU($,Y,Z){let X=`# Custom Command: /${$}
1006
1008
 
1007
1009
  The user has invoked the custom command "/${$}". Follow the instructions below to complete the task.
1008
1010
 
@@ -1017,7 +1019,7 @@ ${Y}
1017
1019
 
1018
1020
  ---
1019
1021
 
1020
- Remember: Follow the above instructions carefully to complete the user's request.`,X}var VU,$7;var eY=b(()=>{v4();g1();n0();VU=Number.parseInt(process.env.SLASH_COMMAND_TOOL_CHAR_BUDGET||"15000",10);$7=U1({name:"SlashCommand",displayName:"Slash Command",kind:"execute",schema:e8.object({command:e8.string().describe('The command name without the leading slash, e.g., "review-pr" or "commit"'),arguments:e8.string().optional().describe('Arguments to pass to the command, e.g., "123" or "fix bug"')}),description:{short:"Execute a custom slash command within the main conversation",long:`Execute a custom slash command within the main conversation
1022
+ Remember: Follow the above instructions carefully to complete the user's request.`,X}var cU,U7;var _Z=b(()=>{T4();m1();t0();cU=Number.parseInt(process.env.SLASH_COMMAND_TOOL_CHAR_BUDGET||"15000",10);U7=U1({name:"SlashCommand",displayName:"Slash Command",kind:"execute",schema:G7.object({command:G7.string().describe('The command name without the leading slash, e.g., "review-pr" or "commit"'),arguments:G7.string().optional().describe('Arguments to pass to the command, e.g., "123" or "fix bug"')}),description:{short:"Execute a custom slash command within the main conversation",long:`Execute a custom slash command within the main conversation
1021
1023
 
1022
1024
  How slash commands work:
1023
1025
  When you use this tool, the command's content (from .blade/commands/ or .claude/commands/) will be processed and returned. The content may include:
@@ -1040,14 +1042,14 @@ Notes:
1040
1042
  - Only custom slash commands with descriptions are listed in Available Commands
1041
1043
  - Commands with \`disable-model-invocation: true\` cannot be invoked by this tool
1042
1044
  - If a command is not listed, ask the user to check the slash command file
1043
- ${DU()}`},async execute($,Y){let{command:Z,arguments:X}=$,Q=i1.getInstance();if(!Q.isInitialized())return{success:!1,llmContent:"Custom command system not initialized. Please wait for the application to fully initialize.",displayContent:"❌ Custom command system not initialized",error:{type:"execution_error",message:"CustomCommandRegistry not initialized"}};let J=Q.getCommand(Z);if(!J){let G=Q.getModelInvocableCommands().map((K)=>`/${K.name}`).join(", ");return{success:!1,llmContent:`Command "/${Z}" not found. Available commands: ${G||"none"}`,displayContent:`❌ Command "/${Z}" not found`,error:{type:"validation_error",message:`Command "/${Z}" is not registered`}}}if(J.config.disableModelInvocation)return{success:!1,llmContent:`Command "/${Z}" has disabled model invocation. This command can only be executed by the user directly.`,displayContent:`❌ Command "/${Z}" disabled for AI`,error:{type:"permission_denied",message:`Command "/${Z}" has disable-model-invocation: true`}};if(!J.config.description)return{success:!1,llmContent:`Command "/${Z}" does not have a description and cannot be invoked by AI. Add a description in the command's frontmatter to enable AI invocation.`,displayContent:`❌ Command "/${Z}" has no description`,error:{type:"validation_error",message:`Command "/${Z}" missing description for AI invocation`}};let q=X?X.split(/\s+/).filter(Boolean):[];try{let G=await Q.executeCommand(Z,{args:q,workspaceRoot:process.cwd()});if(!G)return{success:!1,llmContent:`Failed to execute command "/${Z}"`,displayContent:`❌ Failed to execute "/${Z}"`,error:{type:"execution_error",message:"Command execution returned null"}};return{success:!0,llmContent:IU(J.name,G,J.config),displayContent:`<command-message>/${Z} is running...</command-message>`,metadata:{commandName:Z,allowedTools:J.config.allowedTools,model:J.config.model,source:J.source,namespace:J.namespace}}}catch(G){let K=G instanceof Error?G.message:String(G);return{success:!1,llmContent:`Error executing command "/${Z}": ${K}`,displayContent:`❌ Error executing "/${Z}"`,error:{type:"execution_error",message:K}}}}})});var $Z=b(()=>{aY();eY()});class Y7{config;constructor($){this.config=$}async execute($){let Y=Date.now();try{let Z=this.buildSystemPrompt($),X=await m1.create({systemPrompt:Z,toolWhitelist:this.config.tools}),Q=[{role:"user",content:$.prompt}],J="",q=0,G=0,K=await X.runAgenticLoop($.prompt,{messages:[],userId:"subagent",sessionId:$.parentSessionId||`subagent_${Date.now()}`,workspaceRoot:process.cwd(),permissionMode:$.permissionMode});if(K.success)J=K.finalMessage||"",q=K.metadata?.toolCallsCount||0,G=K.metadata?.tokensUsed||0;else throw Error(K.error?.message||"Subagent execution failed");let W=Date.now()-Y;return{success:!0,message:J,stats:{tokens:G,toolCalls:q,duration:W}}}catch(Z){let X=Date.now()-Y;return{success:!1,message:"",error:Z instanceof Error?Z.message:String(Z),stats:{duration:X}}}}buildSystemPrompt($){return this.config.systemPrompt||""}}var YZ=b(()=>{T2()});import Z7 from"node:fs";import MU from"node:os";import X7 from"node:path";import jU from"yaml";class ZZ{subagents=new Map;register($){if(this.subagents.has($.name))throw Error(`Subagent '${$.name}' already registered`);this.subagents.set($.name,$)}getSubagent($){return this.subagents.get($)}getAllNames(){return Array.from(this.subagents.keys())}getAllSubagents(){return Array.from(this.subagents.values())}getDescriptionsForPrompt(){let $=this.getAllSubagents();if($.length===0)return"No subagents available.";return`Available subagent types and the tools they have access to:
1045
+ ${lU()}`},async execute($,Y){let{command:Z,arguments:X}=$,Q=n1.getInstance();if(!Q.isInitialized())return{success:!1,llmContent:"Custom command system not initialized. Please wait for the application to fully initialize.",displayContent:"❌ Custom command system not initialized",error:{type:"execution_error",message:"CustomCommandRegistry not initialized"}};let J=Q.getCommand(Z);if(!J){let K=Q.getModelInvocableCommands().map((G)=>`/${G.name}`).join(", ");return{success:!1,llmContent:`Command "/${Z}" not found. Available commands: ${K||"none"}`,displayContent:`❌ Command "/${Z}" not found`,error:{type:"validation_error",message:`Command "/${Z}" is not registered`}}}if(J.config.disableModelInvocation)return{success:!1,llmContent:`Command "/${Z}" has disabled model invocation. This command can only be executed by the user directly.`,displayContent:`❌ Command "/${Z}" disabled for AI`,error:{type:"permission_denied",message:`Command "/${Z}" has disable-model-invocation: true`}};if(!J.config.description)return{success:!1,llmContent:`Command "/${Z}" does not have a description and cannot be invoked by AI. Add a description in the command's frontmatter to enable AI invocation.`,displayContent:`❌ Command "/${Z}" has no description`,error:{type:"validation_error",message:`Command "/${Z}" missing description for AI invocation`}};let q=X?X.split(/\s+/).filter(Boolean):[];try{let K=await Q.executeCommand(Z,{args:q,workspaceRoot:process.cwd()});if(!K)return{success:!1,llmContent:`Failed to execute command "/${Z}"`,displayContent:`❌ Failed to execute "/${Z}"`,error:{type:"execution_error",message:"Command execution returned null"}};return{success:!0,llmContent:iU(J.name,K,J.config),displayContent:`<command-message>/${Z} is running...</command-message>`,metadata:{commandName:Z,allowedTools:J.config.allowedTools,model:J.config.model,source:J.source,namespace:J.namespace}}}catch(K){let G=K instanceof Error?K.message:String(K);return{success:!1,llmContent:`Error executing command "/${Z}": ${G}`,displayContent:`❌ Error executing "/${Z}"`,error:{type:"execution_error",message:G}}}}})});var LZ=b(()=>{OZ();_Z()});class W7{config;constructor($){this.config=$}async execute($){let Y=Date.now();try{let Z=this.buildSystemPrompt($),X=await l1.create({systemPrompt:Z,toolWhitelist:this.config.tools}),Q=[{role:"user",content:$.prompt}],J="",q=0,K=0,G=await X.runAgenticLoop($.prompt,{messages:[],userId:"subagent",sessionId:$.parentSessionId||`subagent_${Date.now()}`,workspaceRoot:process.cwd(),permissionMode:$.permissionMode});if(G.success)J=G.finalMessage||"",q=G.metadata?.toolCallsCount||0,K=G.metadata?.tokensUsed||0;else throw Error(G.error?.message||"Subagent execution failed");let U=Date.now()-Y;return{success:!0,message:J,stats:{tokens:K,toolCalls:q,duration:U}}}catch(Z){let X=Date.now()-Y;return{success:!1,message:"",error:Z instanceof Error?Z.message:String(Z),stats:{duration:X}}}}buildSystemPrompt($){return this.config.systemPrompt||""}}var wZ=b(()=>{C2()});import O7 from"node:fs";import rU from"node:os";import F7 from"node:path";import aU from"yaml";class AZ{subagents=new Map;register($){if(this.subagents.has($.name))throw Error(`Subagent '${$.name}' already registered`);this.subagents.set($.name,$)}getSubagent($){return this.subagents.get($)}getAllNames(){return Array.from(this.subagents.keys())}getAllSubagents(){return Array.from(this.subagents.values())}getDescriptionsForPrompt(){let $=this.getAllSubagents();if($.length===0)return"No subagents available.";return`Available subagent types and the tools they have access to:
1044
1046
  ${$.map((Z)=>{let X=`- ${Z.name}: ${Z.description}`;if(Z.tools&&Z.tools.length>0)X+=` (Tools: ${Z.tools.join(", ")})`;return X}).join(`
1045
- `)}`}loadFromDirectory($){if(!Z7.existsSync($))return;let Y=Z7.readdirSync($);for(let Z of Y){if(!Z.endsWith(".md"))continue;let X=X7.join($,Z);try{let Q=this.parseConfigFile(X);this.register(Q)}catch(Q){yU.warn(`Failed to load subagent config from ${X}:`,Q)}}}parseConfigFile($){let Z=Z7.readFileSync($,"utf-8").match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);if(!Z)throw Error(`No YAML frontmatter found in ${$}`);let[,X,Q]=Z,J=jU.parse(X);if(!J.name||!J.description)throw Error(`Missing required fields (name, description) in ${$}`);let q=Q.trim();return{name:J.name,description:J.description,systemPrompt:q,tools:J.tools,configPath:$}}loadFromStandardLocations(){let $=X7.join(MU.homedir(),".blade","agents");this.loadFromDirectory($);let Y=X7.join(process.cwd(),".blade","agents");return this.loadFromDirectory(Y),this.getAllNames().length}clear(){this.subagents.clear()}}var yU,x1;var P$=b(()=>{V1();yU=n("Agent");x1=new ZZ});import{z as E4}from"zod";function vU(){let $=x1.getAllNames();if($.length===0)return["Explore"];return $}var Q7;var XZ=b(()=>{YZ();P$();s1();z0();g1();e1();Q7=U1({name:"Task",displayName:"Subagent Scheduler",kind:"readonly",isReadOnly:!0,schema:E4.object({subagent_type:E4.enum(vU()).describe('Subagent type to use (e.g., "Explore", "Plan")'),description:E4.string().min(3).max(100).describe("Short task description (3-5 words)"),prompt:E4.string().min(10).describe("Detailed task instructions")}),description:{short:"Launch a specialized agent to handle complex, multi-step tasks autonomously",long:`
1047
+ `)}`}loadFromDirectory($){if(!O7.existsSync($))return;let Y=O7.readdirSync($);for(let Z of Y){if(!Z.endsWith(".md"))continue;let X=F7.join($,Z);try{let Q=this.parseConfigFile(X);this.register(Q)}catch(Q){nU.warn(`Failed to load subagent config from ${X}:`,Q)}}}parseConfigFile($){let Z=O7.readFileSync($,"utf-8").match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);if(!Z)throw Error(`No YAML frontmatter found in ${$}`);let[,X,Q]=Z,J=aU.parse(X);if(!J.name||!J.description)throw Error(`Missing required fields (name, description) in ${$}`);let q=Q.trim();return{name:J.name,description:J.description,systemPrompt:q,tools:J.tools,configPath:$}}loadFromStandardLocations(){let $=F7.join(rU.homedir(),".blade","agents");this.loadFromDirectory($);let Y=F7.join(process.cwd(),".blade","agents");return this.loadFromDirectory(Y),this.getAllNames().length}clear(){this.subagents.clear()}}var nU,g1;var k$=b(()=>{w1();nU=c("Agent");g1=new AZ});import{z as S4}from"zod";function oU(){let $=g1.getAllNames();if($.length===0)return["Explore"];return $}var H7;var bZ=b(()=>{wZ();k$();$0();L0();m1();Z0();H7=U1({name:"Task",displayName:"Subagent Scheduler",kind:"readonly",isReadOnly:!0,schema:S4.object({subagent_type:S4.enum(oU()).describe('Subagent type to use (e.g., "Explore", "Plan")'),description:S4.string().min(3).max(100).describe("Short task description (3-5 words)"),prompt:S4.string().min(10).describe("Detailed task instructions")}),description:{short:"Launch a specialized agent to handle complex, multi-step tasks autonomously",long:`
1046
1048
  Launch a specialized agent to handle complex, multi-step tasks autonomously.
1047
1049
 
1048
1050
  The Task tool launches specialized agents (subprocesses) that autonomously handle complex tasks. Each agent type has specific capabilities and tools available to it.
1049
1051
 
1050
- ${x1.getDescriptionsForPrompt()}
1052
+ ${g1.getDescriptionsForPrompt()}
1051
1053
 
1052
1054
  **How to use the Task tool:**
1053
1055
  - Set subagent_type to ANY agent name from the list above (e.g., 'Explore', 'Plan', 'code-reviewer', etc.)
@@ -1068,28 +1070,28 @@ ${x1.getDescriptionsForPrompt()}
1068
1070
  - Clearly tell the agent whether you expect it to write code or just to do research (search, file reads, web fetches, etc.), since it is not aware of the user's intent
1069
1071
  - If the agent description mentions that it should be used proactively, then you should try your best to use it without the user having to ask for it first. Use your judgement.
1070
1072
  - If the user specifies that they want you to run agents "in parallel", you MUST send a single message with multiple Task tool use content blocks.
1071
- `.trim(),usageNotes:["subagent_type is required - choose from available agent types",'description should be 3-5 words (e.g., "Explore error handling")',"prompt should contain a highly detailed task description and specify exactly what information to return","Launch multiple agents concurrently when possible for better performance"],examples:[{description:"Explore codebase for API endpoints",params:{subagent_type:"Explore",description:"Find API endpoints",prompt:"Search the codebase for all API endpoint definitions. Look for route handlers, REST endpoints, and GraphQL resolvers. Return a structured list with file paths, endpoint URLs, HTTP methods, and descriptions."}},{description:"Plan authentication feature",params:{subagent_type:"Plan",description:"Plan user auth",prompt:"Create a detailed implementation plan for adding user authentication to this project. Analyze the existing architecture, then provide step-by-step instructions including: 1) Database schema changes 2) API routes to create 3) Frontend components needed 4) Security considerations 5) Testing strategy. Be specific about file names and code locations."}}]},async execute($,Y){let{subagent_type:Z,description:X,prompt:Q}=$,{updateOutput:J}=Y;try{let q=x1.getAllNames();console.log(`[Task] subagentRegistry 状态: registered=${q.length}, names=[${q.join(", ")}], looking for="${Z}"`);let G=x1.getSubagent(Z);if(!G)return{success:!1,llmContent:`Unknown subagent type: ${Z}. Available types: ${q.join(", ")||"none"}`,displayContent:`❌ 未知的 subagent 类型: ${Z}
1073
+ `.trim(),usageNotes:["subagent_type is required - choose from available agent types",'description should be 3-5 words (e.g., "Explore error handling")',"prompt should contain a highly detailed task description and specify exactly what information to return","Launch multiple agents concurrently when possible for better performance"],examples:[{description:"Explore codebase for API endpoints",params:{subagent_type:"Explore",description:"Find API endpoints",prompt:"Search the codebase for all API endpoint definitions. Look for route handlers, REST endpoints, and GraphQL resolvers. Return a structured list with file paths, endpoint URLs, HTTP methods, and descriptions."}},{description:"Plan authentication feature",params:{subagent_type:"Plan",description:"Plan user auth",prompt:"Create a detailed implementation plan for adding user authentication to this project. Analyze the existing architecture, then provide step-by-step instructions including: 1) Database schema changes 2) API routes to create 3) Frontend components needed 4) Security considerations 5) Testing strategy. Be specific about file names and code locations."}}]},async execute($,Y){let{subagent_type:Z,description:X,prompt:Q}=$,{updateOutput:J}=Y;try{let q=g1.getAllNames();console.log(`[Task] subagentRegistry 状态: registered=${q.length}, names=[${q.join(", ")}], looking for="${Z}"`);let K=g1.getSubagent(Z);if(!K)return{success:!1,llmContent:`Unknown subagent type: ${Z}. Available types: ${q.join(", ")||"none"}`,displayContent:`❌ 未知的 subagent 类型: ${Z}
1072
1074
 
1073
- 可用类型: ${q.join(", ")||"无"}`,error:{type:"execution_error",message:`Unknown subagent type: ${Z}`}};J?.(`\uD83D\uDE80 启动 ${Z} subagent: ${X}`);let K=new Y7(G),W={prompt:Q,parentSessionId:Y.sessionId,permissionMode:Y.permissionMode};J?.("⚙️ 执行任务中...");let O=Date.now(),U=await K.execute(W),F=Date.now()-O;try{let _=await H1.getInstance().executeSubagentStopHooks(Z,{projectDir:process.cwd(),sessionId:Y.sessionId||"unknown",permissionMode:Y.permissionMode||"default",taskDescription:X,success:U.success,resultSummary:U.message.slice(0,500),error:U.error});if(!_.shouldStop&&_.continueReason){console.log(`[Task] SubagentStop hook 阻止停止,继续执行: ${_.continueReason}`);let z={prompt:_.continueReason,parentSessionId:Y.sessionId,permissionMode:Y.permissionMode},L=Date.now();U=await K.execute(z),F+=Date.now()-L}if(_.warning)console.warn(`[Task] SubagentStop hook warning: ${_.warning}`)}catch(H){console.warn("[Task] SubagentStop hook execution failed:",H)}if(U.success){let H=U.message.length>1000?U.message.slice(0,1000)+`
1074
- ...(截断)`:U.message;return{success:!0,llmContent:U.message,displayContent:`✅ Subagent 任务完成
1075
+ 可用类型: ${q.join(", ")||"无"}`,error:{type:"execution_error",message:`Unknown subagent type: ${Z}`}};J?.(`\uD83D\uDE80 启动 ${Z} subagent: ${X}`);let G=new W7(K),U={prompt:Q,parentSessionId:Y.sessionId,permissionMode:Y.permissionMode};J?.("⚙️ 执行任务中...");let O=Date.now(),W=await G.execute(U),F=Date.now()-O;try{let z=await H1.getInstance().executeSubagentStopHooks(Z,{projectDir:process.cwd(),sessionId:Y.sessionId||"unknown",permissionMode:Y.permissionMode||"default",taskDescription:X,success:W.success,resultSummary:W.message.slice(0,500),error:W.error});if(!z.shouldStop&&z.continueReason){console.log(`[Task] SubagentStop hook 阻止停止,继续执行: ${z.continueReason}`);let N={prompt:z.continueReason,parentSessionId:Y.sessionId,permissionMode:Y.permissionMode},L=Date.now();W=await G.execute(N),F+=Date.now()-L}if(z.warning)console.warn(`[Task] SubagentStop hook warning: ${z.warning}`)}catch(H){console.warn("[Task] SubagentStop hook execution failed:",H)}if(W.success){let H=W.message.length>1000?W.message.slice(0,1000)+`
1076
+ ...(截断)`:W.message;return{success:!0,llmContent:W.message,displayContent:`✅ Subagent 任务完成
1075
1077
 
1076
1078
  `+`类型: ${Z}
1077
1079
  `+`任务: ${X}
1078
1080
  `+`耗时: ${F}ms
1079
- `+`工具调用: ${U.stats?.toolCalls||0} 次
1080
- `+`Token: ${U.stats?.tokens||0}
1081
+ `+`工具调用: ${W.stats?.toolCalls||0} 次
1082
+ `+`Token: ${W.stats?.tokens||0}
1081
1083
 
1082
1084
  `+`结果:
1083
- ${H}`,metadata:{subagent_type:Z,description:X,duration:F,stats:U.stats}}}else return{success:!1,llmContent:`Subagent execution failed: ${U.error}`,displayContent:`⚠️ Subagent 任务失败
1085
+ ${H}`,metadata:{subagent_type:Z,description:X,duration:F,stats:W.stats}}}else return{success:!1,llmContent:`Subagent execution failed: ${W.error}`,displayContent:`⚠️ Subagent 任务失败
1084
1086
 
1085
1087
  `+`类型: ${Z}
1086
1088
  `+`任务: ${X}
1087
1089
  `+`耗时: ${F}ms
1088
- `+`错误: ${U.error}`,error:{type:"execution_error",message:U.error||"Unknown error"}}}catch(q){let G=q;return{success:!1,llmContent:`Subagent execution error: ${G.message}`,displayContent:`❌ Subagent 执行异常
1090
+ `+`错误: ${W.error}`,error:{type:"execution_error",message:W.error||"Unknown error"}}}catch(q){let K=q;return{success:!1,llmContent:`Subagent execution error: ${K.message}`,displayContent:`❌ Subagent 执行异常
1089
1091
 
1090
- ${G.message}
1092
+ ${K.message}
1091
1093
 
1092
- ${G.stack||""}`,error:{type:"execution_error",message:G.message,details:q}}}},version:"4.0.0",category:"Subagent",tags:["task","subagent","delegation","explore","plan"],extractSignatureContent:($)=>`${$.subagent_type}:${$.description}`,abstractPermissionRule:()=>""})});var QZ=b(()=>{XZ()});import{randomUUID as EU}from"crypto";import*as T$ from"fs/promises";import*as P4 from"path";var k2;var J7=b(()=>{k2=class k2{static instances=new Map;todos=[];filePath;loaded=!1;constructor($,Y){this.filePath=P4.join(Y,"todos",`${$}-agent-${$}.json`)}static getInstance($,Y){let Z=`${$}-${Y}`;if(!k2.instances.has(Z))k2.instances.set(Z,new k2($,Y));return k2.instances.get(Z)}validate($){if($.filter((Z)=>Z.status==="in_progress").length>1)return{valid:!1,error:"同时只能有一个任务处于 in_progress 状态"};return{valid:!0}}async updateTodos($){await this.ensureLoaded();let Y=new Date().toISOString(),Z=$.map((Q)=>{let J=Q,q=this.todos.find((G)=>G.id===J.id||G.content===Q.content);return{...Q,id:J.id||q?.id||EU(),priority:Q.priority||q?.priority||"medium",createdAt:q?.createdAt||Y,startedAt:Q.status==="in_progress"&&!q?.startedAt?Y:q?.startedAt,completedAt:Q.status==="completed"&&!q?.completedAt?Y:q?.completedAt}}),X=this.validate(Z);if(!X.valid)throw Error(X.error);this.todos=Z,await this.saveTodos()}getSortedTodos(){let $={completed:0,in_progress:1,pending:2},Y={high:0,medium:1,low:2};return[...this.todos].sort((Z,X)=>{let Q=$[Z.status]-$[X.status];if(Q!==0)return Q;return Y[Z.priority]-Y[X.priority]})}getTodos(){return this.getSortedTodos()}async ensureLoaded(){if(!this.loaded)await this.loadTodos(),this.loaded=!0}async loadTodos(){try{let $=await T$.readFile(this.filePath,"utf-8");this.todos=JSON.parse($)}catch($){if($.code==="ENOENT")this.todos=[];else console.warn("加载 TODO 列表失败:",$),this.todos=[]}}async saveTodos(){try{await T$.mkdir(P4.dirname(this.filePath),{recursive:!0}),await T$.writeFile(this.filePath,JSON.stringify(this.todos,null,2),"utf-8")}catch($){throw console.error("保存 TODO 列表失败:",$),$}}}});import{z as k$}from"zod";var JZ;var qZ=b(()=>{JZ=k$.object({id:k$.string().optional(),content:k$.string().min(1,"Content cannot be empty"),status:k$.enum(["pending","in_progress","completed"]),activeForm:k$.string().min(1,"ActiveForm cannot be empty"),priority:k$.enum(["high","medium","low"]).default("medium")})});import{z as GZ}from"zod";function q7($){let{sessionId:Y,configDir:Z}=$;return U1({name:"TodoWrite",displayName:"Todo Write",kind:"readonly",schema:GZ.object({todos:GZ.array(JZ).min(1,"At least one task is required")}),description:{short:"Use this tool to create and manage a structured task list for your current coding session",long:`Use this tool to create and manage a structured task list for your current coding session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
1094
+ ${K.stack||""}`,error:{type:"execution_error",message:K.message,details:q}}}},version:"4.0.0",category:"Subagent",tags:["task","subagent","delegation","explore","plan"],extractSignatureContent:($)=>`${$.subagent_type}:${$.description}`,abstractPermissionRule:()=>""})});var RZ=b(()=>{bZ()});import{randomUUID as sU}from"crypto";import*as C$ from"fs/promises";import*as k4 from"path";var f2;var z7=b(()=>{f2=class f2{static instances=new Map;todos=[];filePath;loaded=!1;constructor($,Y){this.filePath=k4.join(Y,"todos",`${$}-agent-${$}.json`)}static getInstance($,Y){let Z=`${$}-${Y}`;if(!f2.instances.has(Z))f2.instances.set(Z,new f2($,Y));return f2.instances.get(Z)}validate($){if($.filter((Z)=>Z.status==="in_progress").length>1)return{valid:!1,error:"同时只能有一个任务处于 in_progress 状态"};return{valid:!0}}async updateTodos($){await this.ensureLoaded();let Y=new Date().toISOString(),Z=$.map((Q)=>{let J=Q,q=this.todos.find((K)=>K.id===J.id||K.content===Q.content);return{...Q,id:J.id||q?.id||sU(),priority:Q.priority||q?.priority||"medium",createdAt:q?.createdAt||Y,startedAt:Q.status==="in_progress"&&!q?.startedAt?Y:q?.startedAt,completedAt:Q.status==="completed"&&!q?.completedAt?Y:q?.completedAt}}),X=this.validate(Z);if(!X.valid)throw Error(X.error);this.todos=Z,await this.saveTodos()}getSortedTodos(){let $={completed:0,in_progress:1,pending:2},Y={high:0,medium:1,low:2};return[...this.todos].sort((Z,X)=>{let Q=$[Z.status]-$[X.status];if(Q!==0)return Q;return Y[Z.priority]-Y[X.priority]})}getTodos(){return this.getSortedTodos()}async ensureLoaded(){if(!this.loaded)await this.loadTodos(),this.loaded=!0}async loadTodos(){try{let $=await C$.readFile(this.filePath,"utf-8");this.todos=JSON.parse($)}catch($){if($.code==="ENOENT")this.todos=[];else console.warn("加载 TODO 列表失败:",$),this.todos=[]}}async saveTodos(){try{await C$.mkdir(k4.dirname(this.filePath),{recursive:!0}),await C$.writeFile(this.filePath,JSON.stringify(this.todos,null,2),"utf-8")}catch($){throw console.error("保存 TODO 列表失败:",$),$}}}});import{z as f$}from"zod";var VZ;var DZ=b(()=>{VZ=f$.object({id:f$.string().optional(),content:f$.string().min(1,"Content cannot be empty"),status:f$.enum(["pending","in_progress","completed"]),activeForm:f$.string().min(1,"ActiveForm cannot be empty"),priority:f$.enum(["high","medium","low"]).default("medium")})});import{z as IZ}from"zod";function N7($){let{sessionId:Y,configDir:Z}=$;return U1({name:"TodoWrite",displayName:"Todo Write",kind:"readonly",schema:IZ.object({todos:IZ.array(VZ).min(1,"At least one task is required")}),description:{short:"Use this tool to create and manage a structured task list for your current coding session",long:`Use this tool to create and manage a structured task list for your current coding session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
1093
1095
  It also helps the user understand the progress of the task and overall progress of their requests.
1094
1096
 
1095
1097
  ## When to Use This Tool
@@ -1150,16 +1152,16 @@ NOTE that you should not use this tool if there is only one trivial task to do.
1150
1152
  - activeForm: "Fixing authentication bug"
1151
1153
 
1152
1154
  When in doubt, use this tool. Being proactive with task management demonstrates attentiveness and ensures you complete all requirements successfully.
1153
- `},async execute(X,Q){let{todos:J}=X,{updateOutput:q}=Q;try{let G=Q.sessionId||Y,K=k2.getInstance(G,Z);q?.("Updating TODO list..."),await K.updateTodos(J);let W=K.getTodos(),O=PU(W),U=TU(W,O);return q?.(`✅ TODO list updated (${O.completed}/${O.total} completed)`),{success:!0,llmContent:{todos:W,stats:O},displayContent:U,metadata:{stats:O}}}catch(G){return{success:!1,llmContent:`Update failed: ${G.message}`,displayContent:`❌ 更新 TODO 列表失败: ${G.message}`,error:{type:"execution_error",message:G.message,details:G}}}},version:"1.0.0",category:"TODO tools",tags:["todo","task","management","planning"],extractSignatureContent:(X)=>`${X.todos.length} todos`,abstractPermissionRule:()=>"*"})}function PU($){return{total:$.length,completed:$.filter((Y)=>Y.status==="completed").length,inProgress:$.filter((Y)=>Y.status==="in_progress").length,pending:$.filter((Y)=>Y.status==="pending").length}}function TU($,Y){let Z=[],X=Y.total>0?Math.round(Y.completed/Y.total*100):0;if(Z.push(`\uD83D\uDCCB TODO 列表 (${Y.completed}/${Y.total} 完成,${X}%)`),Z.push(""),$.length===0)return Z.push(" (暂无任务)"),Z.join(`
1154
- `);for(let Q of $){let J=Q.status==="completed"?"☑":"☐",q=`(P${Q.priority==="high"?0:Q.priority==="medium"?1:2})`,G=Q.status==="in_progress"?" ⚡":"",K=Q.status==="completed"?"~~":"";Z.push(` ${J} ${q} ${K}${Q.content}${K}${G}`)}return Z.join(`
1155
- `)}var KZ=b(()=>{g1();e1();J7();qZ()});var UZ=b(()=>{J7();KZ()});import{z as N2}from"zod";async function kU($){let{url:Y,method:Z,headers:X,body:Q,timeout:J,follow_redirects:q,max_redirects:G,signal:K}=$,W={"User-Agent":"Blade-AI/1.0",...X},O=Y,U=Z,F=Q,H=0,_=[];while(!0){let z={...W};if(F&&U!=="GET"&&U!=="HEAD"&&!pU(z,"content-type"))z["Content-Type"]="application/json";let L=await fU(O,{method:U,headers:z,body:F&&U!=="GET"&&U!=="HEAD"?F:void 0,redirect:"manual"},J,K),B=L.headers.get("location"),N=L.status>=300&&L.status<400,I=q&&N&&B&&H<G;if(N&&q&&!B)throw Error(`收到状态码 ${L.status} 但响应缺少 Location 头`);if(N&&q&&H>=G)throw Error(`超过最大重定向次数 (${G})`);if(I&&B){H++;let D=hU(B,O);if(_.push(`${L.status} → ${D}`),L.status===303||(L.status===301||L.status===302)&&U!=="GET"&&U!=="HEAD")U="GET",F=void 0;O=D;continue}let M=await L.text(),A=xU(L.headers);return{status:L.status,status_text:L.statusText,headers:A,body:M,url:L.url||O,redirected:H>0,redirect_count:H,redirect_chain:_,content_type:A["content-type"],response_time:0}}}function WZ($,Y,Z){let{url:X,method:Q,status:J,response_time:q,content_length:G}=Y,K=Z?`❌ ${Q} ${X} - ${J} ${$.status_text}`:`✅ ${Q} ${X} - ${J} ${$.status_text}`;if(K+=`
1156
- 响应时间: ${q}ms`,K+=`
1157
- 内容长度: ${G} 字节`,Y.content_type)K+=`
1158
- Content-Type: ${Y.content_type}`;if($.redirected&&Y.final_url&&Y.final_url!==X){if(K+=`
1159
- 最终URL: ${Y.final_url}`,Y.redirect_count)K+=`
1160
- 重定向次数: ${Y.redirect_count}`}let W=SU($.body,$.content_type);if(W)K+=`
1155
+ `},async execute(X,Q){let{todos:J}=X,{updateOutput:q}=Q;try{let K=Q.sessionId||Y,G=f2.getInstance(K,Z);q?.("Updating TODO list..."),await G.updateTodos(J);let U=G.getTodos(),O=tU(U),W=eU(U,O);return q?.(`✅ TODO list updated (${O.completed}/${O.total} completed)`),{success:!0,llmContent:{todos:U,stats:O},displayContent:W,metadata:{stats:O}}}catch(K){return{success:!1,llmContent:`Update failed: ${K.message}`,displayContent:`❌ 更新 TODO 列表失败: ${K.message}`,error:{type:"execution_error",message:K.message,details:K}}}},version:"1.0.0",category:"TODO tools",tags:["todo","task","management","planning"],extractSignatureContent:(X)=>`${X.todos.length} todos`,abstractPermissionRule:()=>"*"})}function tU($){return{total:$.length,completed:$.filter((Y)=>Y.status==="completed").length,inProgress:$.filter((Y)=>Y.status==="in_progress").length,pending:$.filter((Y)=>Y.status==="pending").length}}function eU($,Y){let Z=[],X=Y.total>0?Math.round(Y.completed/Y.total*100):0;if(Z.push(`\uD83D\uDCCB TODO 列表 (${Y.completed}/${Y.total} 完成,${X}%)`),Z.push(""),$.length===0)return Z.push(" (暂无任务)"),Z.join(`
1156
+ `);for(let Q of $){let J=Q.status==="completed"?"☑":"☐",q=`(P${Q.priority==="high"?0:Q.priority==="medium"?1:2})`,K=Q.status==="in_progress"?" ⚡":"",G=Q.status==="completed"?"~~":"";Z.push(` ${J} ${q} ${G}${Q.content}${G}${K}`)}return Z.join(`
1157
+ `)}var MZ=b(()=>{m1();Z0();z7();DZ()});var jZ=b(()=>{z7();MZ()});import{z as w2}from"zod";async function $W($){let{url:Y,method:Z,headers:X,body:Q,timeout:J,follow_redirects:q,max_redirects:K,signal:G}=$,U={"User-Agent":"Blade-AI/1.0",...X},O=Y,W=Z,F=Q,H=0,z=[];while(!0){let N={...U};if(F&&W!=="GET"&&W!=="HEAD"&&!qW(N,"content-type"))N["Content-Type"]="application/json";let L=await XW(O,{method:W,headers:N,body:F&&W!=="GET"&&W!=="HEAD"?F:void 0,redirect:"manual"},J,G),B=L.headers.get("location"),_=L.status>=300&&L.status<400,I=q&&_&&B&&H<K;if(_&&q&&!B)throw Error(`收到状态码 ${L.status} 但响应缺少 Location 头`);if(_&&q&&H>=K)throw Error(`超过最大重定向次数 (${K})`);if(I&&B){H++;let D=QW(B,O);if(z.push(`${L.status} → ${D}`),L.status===303||(L.status===301||L.status===302)&&W!=="GET"&&W!=="HEAD")W="GET",F=void 0;O=D;continue}let M=await L.text(),A=JW(L.headers);return{status:L.status,status_text:L.statusText,headers:A,body:M,url:L.url||O,redirected:H>0,redirect_count:H,redirect_chain:z,content_type:A["content-type"],response_time:0}}}function yZ($,Y,Z){let{url:X,method:Q,status:J,response_time:q,content_length:K}=Y,G=Z?`❌ ${Q} ${X} - ${J} ${$.status_text}`:`✅ ${Q} ${X} - ${J} ${$.status_text}`;if(G+=`
1158
+ 响应时间: ${q}ms`,G+=`
1159
+ 内容长度: ${K} 字节`,Y.content_type)G+=`
1160
+ Content-Type: ${Y.content_type}`;if($.redirected&&Y.final_url&&Y.final_url!==X){if(G+=`
1161
+ 最终URL: ${Y.final_url}`,Y.redirect_count)G+=`
1162
+ 重定向次数: ${Y.redirect_count}`}let U=YW($.body,$.content_type);if(U)G+=`
1161
1163
  响应内容:
1162
- ${W}`;return K}function SU($,Y){if(!$)return"(空响应)";if(CU(Y,$))return"[binary content omitted]";let Z=$.trim();if(!Z)return"(仅包含空白字符)";return Z.length>800?`${Z.slice(0,800)}...`:Z}function CU($,Y){if($){let Q=$.toLowerCase();if(["image/","audio/","video/","application/pdf","application/zip","application/octet-stream"].some((q)=>Q.startsWith(q)))return!0}if(!Y)return!1;let Z=0,X=Math.min(Y.length,200);for(let Q=0;Q<X;Q++){let J=Y.charCodeAt(Q);if(J===9||J===10||J===13)continue;if(J<32||J>126)Z++}return Z/(X||1)>0.3}async function fU($,Y,Z,X){let Q=new AbortController,J=setTimeout(()=>Q.abort(),Z),q=()=>Q.abort();X?.addEventListener("abort",q);try{return await fetch($,{...Y,signal:Q.signal})}catch(G){if(G.name==="AbortError")throw G.message="请求被中止或超时",G;throw G}finally{clearTimeout(J),X?.removeEventListener("abort",q)}}function hU($,Y){try{return new URL($,Y).toString()}catch{return $}}function xU($){let Y={};return $.forEach((Z,X)=>{Y[X.toLowerCase()]=Z}),Y}function pU($,Y){let Z=Y.toLowerCase();return Object.keys($).some((X)=>X.toLowerCase()===Z)}var G7;var OZ=b(()=>{g1();e1();E2();G7=U1({name:"WebFetch",displayName:"Web Fetch",kind:"readonly",schema:N2.object({url:N2.string().url().describe("URL to request"),method:N2.enum(["GET","POST","PUT","DELETE","HEAD"]).default("GET").describe("HTTP method"),headers:N2.record(N2.string()).optional().describe("Request headers (optional)"),body:N2.string().optional().describe("Request body (optional)"),timeout:b1.timeout(1000,120000,30000),follow_redirects:N2.boolean().default(!0).describe("Follow redirects"),max_redirects:N2.number().int().min(0).max(10).default(5).describe("Maximum redirect hops"),return_headers:N2.boolean().default(!1).describe("Return response headers")}),description:{short:"Fetches content from a specified URL and processes it using an AI model",long:`
1164
+ ${U}`;return G}function YW($,Y){if(!$)return"(空响应)";if(ZW(Y,$))return"[binary content omitted]";let Z=$.trim();if(!Z)return"(仅包含空白字符)";return Z.length>800?`${Z.slice(0,800)}...`:Z}function ZW($,Y){if($){let Q=$.toLowerCase();if(["image/","audio/","video/","application/pdf","application/zip","application/octet-stream"].some((q)=>Q.startsWith(q)))return!0}if(!Y)return!1;let Z=0,X=Math.min(Y.length,200);for(let Q=0;Q<X;Q++){let J=Y.charCodeAt(Q);if(J===9||J===10||J===13)continue;if(J<32||J>126)Z++}return Z/(X||1)>0.3}async function XW($,Y,Z,X){let Q=new AbortController,J=setTimeout(()=>Q.abort(),Z),q=()=>Q.abort();X?.addEventListener("abort",q);try{return await fetch($,{...Y,signal:Q.signal})}catch(K){if(K.name==="AbortError")throw K.message="请求被中止或超时",K;throw K}finally{clearTimeout(J),X?.removeEventListener("abort",q)}}function QW($,Y){try{return new URL($,Y).toString()}catch{return $}}function JW($){let Y={};return $.forEach((Z,X)=>{Y[X.toLowerCase()]=Z}),Y}function qW($,Y){let Z=Y.toLowerCase();return Object.keys($).some((X)=>X.toLowerCase()===Z)}var B7;var EZ=b(()=>{m1();Z0();S2();B7=U1({name:"WebFetch",displayName:"Web Fetch",kind:"readonly",schema:w2.object({url:w2.string().url().describe("URL to request"),method:w2.enum(["GET","POST","PUT","DELETE","HEAD"]).default("GET").describe("HTTP method"),headers:w2.record(w2.string()).optional().describe("Request headers (optional)"),body:w2.string().optional().describe("Request body (optional)"),timeout:I1.timeout(1000,120000,30000),follow_redirects:w2.boolean().default(!0).describe("Follow redirects"),max_redirects:w2.number().int().min(0).max(10).default(5).describe("Maximum redirect hops"),return_headers:w2.boolean().default(!1).describe("Return response headers")}),description:{short:"Fetches content from a specified URL and processes it using an AI model",long:`
1163
1165
  - Fetches content from a specified URL and processes it using an AI model
1164
1166
  - Takes a URL and a prompt as input
1165
1167
  - Fetches the URL content, converts HTML to markdown
@@ -1176,12 +1178,12 @@ Usage notes:
1176
1178
  - Results may be summarized if the content is very large
1177
1179
  - Includes a self-cleaning 15-minute cache for faster responses when repeatedly accessing the same URL
1178
1180
  - When a URL redirects to a different host, the tool will inform you and provide the redirect URL in a special format. You should then make a new WebFetch request with the redirect URL to fetch the content.
1179
- `},async execute($,Y){let{url:Z,method:X="GET",headers:Q={},body:J,timeout:q=30000,follow_redirects:G=!0,max_redirects:K=5,return_headers:W=!1}=$,{updateOutput:O}=Y,U=Y.signal??new AbortController().signal;try{O?.(`发送 ${X} 请求到: ${Z}`);let F=Date.now(),H=await kU({url:Z,method:X,headers:Q,body:J,timeout:q,follow_redirects:G,max_redirects:K,signal:U}),_=Date.now()-F;if(H.response_time=_,!W)delete H.headers;let z={url:Z,method:X,status:H.status,response_time:_,content_length:Buffer.byteLength(H.body||"","utf8"),redirected:H.redirected||!1,redirect_count:H.redirect_count??0,final_url:H.url,content_type:H.content_type,redirect_chain:H.redirect_chain};if(H.status>=400)return{success:!1,llmContent:`HTTP error ${H.status}: ${H.status_text}`,displayContent:WZ(H,z,!0),error:{type:"execution_error",message:`HTTP error ${H.status}: ${H.status_text}`,details:{...z,response_body:H.body}},metadata:z};return{success:!0,llmContent:H,displayContent:WZ(H,z,!1),metadata:z}}catch(F){if(F.name==="AbortError")return{success:!1,llmContent:"Request aborted",displayContent:"⚠️ 请求被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`Network request failed: ${F.message}`,displayContent:`❌ 网络请求失败: ${F.message}`,error:{type:"execution_error",message:F.message,details:F}}}},version:"2.0.0",category:"网络工具",tags:["web","http","fetch","request","api"],extractSignatureContent:($)=>{try{return`domain:${new URL($.url).hostname}`}catch{return $.url}},abstractPermissionRule:($)=>{try{return`domain:${new URL($.url).hostname}`}catch{return"*"}}})});function gU($){return $.replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#39;/g,"'")}function FZ($){let Y=gU($).trim();if(!Y.includes(" - "))return{title:Y,snippet:Y};let[Z,...X]=Y.split(" - "),Q=Z.trim(),J=X.join(" - ").trim()||Y;return{title:Q,snippet:J}}function K7($){try{let Y=new URL($),Z=Y.pathname==="/"?"":Y.pathname;return`${Y.hostname}${Z}`}catch{return $}}function U7($){try{return new URL($).hostname.toLowerCase()}catch{return""}}function uU($){if(!$.FirstURL||!$.Text)return null;let{title:Y,snippet:Z}=FZ($.Text);return{title:Y,snippet:Z,url:$.FirstURL,display_url:K7($.FirstURL),source:U7($.FirstURL)}}function HZ($){let Y=[];for(let Z of $){if(Z.Topics&&Z.Topics.length>0){Y.push(...HZ(Z.Topics));continue}if(Z.FirstURL&&Z.Text){let{title:X,snippet:Q}=FZ(Z.Text);Y.push({title:X,snippet:Q,url:Z.FirstURL,display_url:K7(Z.FirstURL),source:U7(Z.FirstURL)})}}return Y}function mU($){let Y=$,Z=(Y.Results??[]).map((Q)=>uU(Q)).filter((Q)=>Q!==null),X=HZ(Y.RelatedTopics??[]);return[...Z,...X]}function cU($){let Y=$,Z=[];for(let X of Y.results??[]){if(!X.url||!X.title)continue;Z.push({title:X.title,snippet:X.content||X.title,url:X.url,display_url:K7(X.url),source:U7(X.url)})}return Z}function lU($){return{name:`SearXNG(${(()=>{try{return new URL($).hostname}catch{return $}})()})`,endpoint:$,buildUrl:(Z)=>{let X=new URL(`${$}/search`);return X.searchParams.set("q",Z),X.searchParams.set("format","json"),X.searchParams.set("categories","general"),X.toString()},parseResponse:cU,getHeaders:()=>({Accept:"application/json","User-Agent":"Blade-AI-WebSearch/1.0"})}}function zZ(){return[dU,..._Z.map(lU)]}function NZ(){return 1+_Z.length}var dU,_Z;var BZ=b(()=>{dU={name:"DuckDuckGo",endpoint:"https://duckduckgo.com/",buildUrl:($)=>{let Y=new URL("https://duckduckgo.com/");return Y.searchParams.set("q",$),Y.searchParams.set("format","json"),Y.searchParams.set("no_html","1"),Y.searchParams.set("skip_disambig","1"),Y.searchParams.set("t","blade-code"),Y.searchParams.set("kl","us-en"),Y.toString()},parseResponse:mU,getHeaders:()=>({Accept:"application/json, text/plain;q=0.9","User-Agent":"Blade-AI-WebSearch/1.0"})};_Z=["https://searx.be","https://search.ononoki.org","https://searx.tiekoetter.com","https://searx.work"]});import{ProxyAgent as iU,fetch as aU}from"undici";import{z as S$}from"zod";function oU(){let $=process.env.HTTPS_PROXY||process.env.HTTP_PROXY||process.env.https_proxy||process.env.http_proxy;if($)try{return new iU($)}catch(Y){console.warn(`Invalid proxy URL: ${$}`)}return}async function sU($,Y,Z,X,Q){let J=new AbortController,q=setTimeout(()=>J.abort(),Z),G=()=>J.abort();X?.addEventListener("abort",G);try{return await aU($,{...Y,signal:J.signal,dispatcher:Q})}catch(K){if(K.name==="AbortError")throw Error("搜索请求超时或被中止");throw K}finally{clearTimeout(q),X?.removeEventListener("abort",G)}}async function tU($,Y,Z,X,Q,J){let q=null;for(let G=0;G<A6.maxRetries;G++)try{return await sU($,Y,Z,X,Q)}catch(K){if(q=K,X?.aborted)throw K;if(G<A6.maxRetries-1){let W=Math.min(A6.baseDelay*Math.pow(2,G),A6.maxDelay);J?.(`⏳ 请求失败,${W/1000}s 后重试 (${G+1}/${A6.maxRetries})...`),await new Promise((O)=>setTimeout(O,W))}}throw q}async function eU($,Y,Z,X,Q,J){let q=$.buildUrl(Y),G=await tU(q,{headers:$.getHeaders()},Z,X,Q,J);if(!G.ok)throw Error(`HTTP ${G.status}`);let K=await G.text(),W;try{W=JSON.parse(K)}catch{throw Error("Failed to parse search result JSON")}return{results:$.parseResponse(W),providerName:$.name}}async function $W($,Y,Z,X){let Q=zZ(),J=oU(),q=[];for(let G=0;G<Q.length;G++){let K=Q[G];if(Z?.aborted)throw Error("搜索被用户中止");try{return X?.(`\uD83D\uDD0E 使用 ${K.name} 搜索...`),await eU(K,$,Y,Z,J,X)}catch(W){let O=`${K.name}: ${W.message}`;if(q.push(O),X?.(`⚠️ ${O}`),G===Q.length-1)throw Error(`所有搜索提供商都失败了:
1181
+ `},async execute($,Y){let{url:Z,method:X="GET",headers:Q={},body:J,timeout:q=30000,follow_redirects:K=!0,max_redirects:G=5,return_headers:U=!1}=$,{updateOutput:O}=Y,W=Y.signal??new AbortController().signal;try{O?.(`发送 ${X} 请求到: ${Z}`);let F=Date.now(),H=await $W({url:Z,method:X,headers:Q,body:J,timeout:q,follow_redirects:K,max_redirects:G,signal:W}),z=Date.now()-F;if(H.response_time=z,!U)delete H.headers;let N={url:Z,method:X,status:H.status,response_time:z,content_length:Buffer.byteLength(H.body||"","utf8"),redirected:H.redirected||!1,redirect_count:H.redirect_count??0,final_url:H.url,content_type:H.content_type,redirect_chain:H.redirect_chain};if(H.status>=400)return{success:!1,llmContent:`HTTP error ${H.status}: ${H.status_text}`,displayContent:yZ(H,N,!0),error:{type:"execution_error",message:`HTTP error ${H.status}: ${H.status_text}`,details:{...N,response_body:H.body}},metadata:N};return{success:!0,llmContent:H,displayContent:yZ(H,N,!1),metadata:N}}catch(F){if(F.name==="AbortError")return{success:!1,llmContent:"Request aborted",displayContent:"⚠️ 请求被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`Network request failed: ${F.message}`,displayContent:`❌ 网络请求失败: ${F.message}`,error:{type:"execution_error",message:F.message,details:F}}}},version:"2.0.0",category:"网络工具",tags:["web","http","fetch","request","api"],extractSignatureContent:($)=>{try{return`domain:${new URL($.url).hostname}`}catch{return $.url}},abstractPermissionRule:($)=>{try{return`domain:${new URL($.url).hostname}`}catch{return"*"}}})});function KW($){return $.replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#39;/g,"'")}function vZ($){let Y=KW($).trim();if(!Y.includes(" - "))return{title:Y,snippet:Y};let[Z,...X]=Y.split(" - "),Q=Z.trim(),J=X.join(" - ").trim()||Y;return{title:Q,snippet:J}}function _7($){try{let Y=new URL($),Z=Y.pathname==="/"?"":Y.pathname;return`${Y.hostname}${Z}`}catch{return $}}function L7($){try{return new URL($).hostname.toLowerCase()}catch{return""}}function GW($){if(!$.FirstURL||!$.Text)return null;let{title:Y,snippet:Z}=vZ($.Text);return{title:Y,snippet:Z,url:$.FirstURL,display_url:_7($.FirstURL),source:L7($.FirstURL)}}function PZ($){let Y=[];for(let Z of $){if(Z.Topics&&Z.Topics.length>0){Y.push(...PZ(Z.Topics));continue}if(Z.FirstURL&&Z.Text){let{title:X,snippet:Q}=vZ(Z.Text);Y.push({title:X,snippet:Q,url:Z.FirstURL,display_url:_7(Z.FirstURL),source:L7(Z.FirstURL)})}}return Y}function UW($){let Y=$,Z=(Y.Results??[]).map((Q)=>GW(Q)).filter((Q)=>Q!==null),X=PZ(Y.RelatedTopics??[]);return[...Z,...X]}function OW($){let Y=$,Z=[];for(let X of Y.results??[]){if(!X.url||!X.title)continue;Z.push({title:X.title,snippet:X.content||X.title,url:X.url,display_url:_7(X.url),source:L7(X.url)})}return Z}function FW($){return{name:`SearXNG(${(()=>{try{return new URL($).hostname}catch{return $}})()})`,endpoint:$,buildUrl:(Z)=>{let X=new URL(`${$}/search`);return X.searchParams.set("q",Z),X.searchParams.set("format","json"),X.searchParams.set("categories","general"),X.toString()},parseResponse:OW,getHeaders:()=>({Accept:"application/json","User-Agent":"Blade-AI-WebSearch/1.0"})}}function SZ(){return[WW,...TZ.map(FW)]}function kZ(){return 1+TZ.length}var WW,TZ;var CZ=b(()=>{WW={name:"DuckDuckGo",endpoint:"https://duckduckgo.com/",buildUrl:($)=>{let Y=new URL("https://duckduckgo.com/");return Y.searchParams.set("q",$),Y.searchParams.set("format","json"),Y.searchParams.set("no_html","1"),Y.searchParams.set("skip_disambig","1"),Y.searchParams.set("t","blade-code"),Y.searchParams.set("kl","us-en"),Y.toString()},parseResponse:UW,getHeaders:()=>({Accept:"application/json, text/plain;q=0.9","User-Agent":"Blade-AI-WebSearch/1.0"})};TZ=["https://searx.be","https://search.ononoki.org","https://searx.tiekoetter.com","https://searx.work"]});import{ProxyAgent as HW,fetch as zW}from"undici";import{z as h$}from"zod";function _W(){let $=process.env.HTTPS_PROXY||process.env.HTTP_PROXY||process.env.https_proxy||process.env.http_proxy;if($)try{return new HW($)}catch(Y){console.warn(`Invalid proxy URL: ${$}`)}return}async function LW($,Y,Z,X,Q){let J=new AbortController,q=setTimeout(()=>J.abort(),Z),K=()=>J.abort();X?.addEventListener("abort",K);try{return await zW($,{...Y,signal:J.signal,dispatcher:Q})}catch(G){if(G.name==="AbortError")throw Error("搜索请求超时或被中止");throw G}finally{clearTimeout(q),X?.removeEventListener("abort",K)}}async function wW($,Y,Z,X,Q,J){let q=null;for(let K=0;K<V6.maxRetries;K++)try{return await LW($,Y,Z,X,Q)}catch(G){if(q=G,X?.aborted)throw G;if(K<V6.maxRetries-1){let U=Math.min(V6.baseDelay*Math.pow(2,K),V6.maxDelay);J?.(`⏳ 请求失败,${U/1000}s 后重试 (${K+1}/${V6.maxRetries})...`),await new Promise((O)=>setTimeout(O,U))}}throw q}async function AW($,Y,Z,X,Q,J){let q=$.buildUrl(Y),K=await wW(q,{headers:$.getHeaders()},Z,X,Q,J);if(!K.ok)throw Error(`HTTP ${K.status}`);let G=await K.text(),U;try{U=JSON.parse(G)}catch{throw Error("Failed to parse search result JSON")}return{results:$.parseResponse(U),providerName:$.name}}async function bW($,Y,Z,X){let Q=SZ(),J=_W(),q=[];for(let K=0;K<Q.length;K++){let G=Q[K];if(Z?.aborted)throw Error("搜索被用户中止");try{return X?.(`\uD83D\uDD0E 使用 ${G.name} 搜索...`),await AW(G,$,Y,Z,J,X)}catch(U){let O=`${G.name}: ${U.message}`;if(q.push(O),X?.(`⚠️ ${O}`),K===Q.length-1)throw Error(`所有搜索提供商都失败了:
1180
1182
  ${q.join(`
1181
- `)}`)}}throw Error("No search providers available")}function YW($){try{return new URL($).hostname.toLowerCase()}catch{return null}}function ZW($){return $.trim().toLowerCase()}function LZ($){if(!$||$.length===0)return[];return $.map(ZW).filter(Boolean)}function wZ($,Y){return $===Y||$.endsWith(`.${Y}`)}function XW($,Y,Z){return $.filter((X)=>{let Q=YW(X.url);if(!Q)return!1;if(Z.length>0&&Z.some((J)=>wZ(Q,J)))return!1;if(Y.length>0&&!Y.some((J)=>wZ(Q,J)))return!1;return!0})}function QW($,Y,Z,X){let Q=`\uD83D\uDD0E WebSearch("${$}") via ${X} - 返回 ${Y.length}/${Z} 条结果`,J=Y.map((q,G)=>`${G+1}. ${q.title}
1183
+ `)}`)}}throw Error("No search providers available")}function RW($){try{return new URL($).hostname.toLowerCase()}catch{return null}}function VW($){return $.trim().toLowerCase()}function fZ($){if(!$||$.length===0)return[];return $.map(VW).filter(Boolean)}function hZ($,Y){return $===Y||$.endsWith(`.${Y}`)}function DW($,Y,Z){return $.filter((X)=>{let Q=RW(X.url);if(!Q)return!1;if(Z.length>0&&Z.some((J)=>hZ(Q,J)))return!1;if(Y.length>0&&!Y.some((J)=>hZ(Q,J)))return!1;return!0})}function IW($,Y,Z,X){let Q=`\uD83D\uDD0E WebSearch("${$}") via ${X} - 返回 ${Y.length}/${Z} 条结果`,J=Y.map((q,K)=>`${K+1}. ${q.title}
1182
1184
  ${q.display_url}
1183
1185
  ${q.snippet}`);return[Q,...J].join(`
1184
- `)}function JW($){let Y=$.trim().toLowerCase();return Y.length>80?Y.slice(0,80):Y}var rU=15000,nU=8,A6,W7;var AZ=b(()=>{g1();e1();BZ();A6={maxRetries:3,baseDelay:1000,maxDelay:8000};W7=U1({name:"WebSearch",displayName:"Web Search",kind:"readonly",schema:S$.object({query:S$.string().min(2,"Search query must be at least 2 characters").describe("Search query"),allowed_domains:S$.array(S$.string().min(1)).optional().describe("Return results only from these domains (optional)"),blocked_domains:S$.array(S$.string().min(1)).optional().describe("Exclude results from these domains (optional)")}),description:{short:"Search the web and use the results to inform responses",long:`
1186
+ `)}function MW($){let Y=$.trim().toLowerCase();return Y.length>80?Y.slice(0,80):Y}var NW=15000,BW=8,V6,w7;var xZ=b(()=>{m1();Z0();CZ();V6={maxRetries:3,baseDelay:1000,maxDelay:8000};w7=U1({name:"WebSearch",displayName:"Web Search",kind:"readonly",schema:h$.object({query:h$.string().min(2,"Search query must be at least 2 characters").describe("Search query"),allowed_domains:h$.array(h$.string().min(1)).optional().describe("Return results only from these domains (optional)"),blocked_domains:h$.array(h$.string().min(1)).optional().describe("Exclude results from these domains (optional)")}),description:{short:"Search the web and use the results to inform responses",long:`
1185
1187
  - Search the web and use the results to inform responses
1186
1188
  - Provides up-to-date information for current events and recent data
1187
1189
  - Returns search result information formatted as search result blocks, including links as markdown hyperlinks
@@ -1209,22 +1211,22 @@ Usage notes:
1209
1211
  IMPORTANT - Use the correct year in search queries:
1210
1212
  - You MUST use the current year when searching for recent information, documentation, or current events.
1211
1213
  - Example: If the user asks for "latest React docs", search for "React documentation 2025", NOT "React documentation 2024"
1212
- `},async execute($,Y){let{query:Z}=$,X=LZ($.allowed_domains),Q=LZ($.blocked_domains),{updateOutput:J}=Y,q=Y.signal??new AbortController().signal;J?.(`\uD83D\uDD0E Searching: "${Z}" (${NZ()} providers available)`);try{let{results:G,providerName:K}=await $W(Z,rU,q,J),W=XW(G,X,Q),O=W.slice(0,nU),U={query:Z,results:O,provider:K,total_results:W.length,fetched_at:new Date().toISOString()},F={query:Z,provider:K,fetched_at:U.fetched_at,total_results:W.length,returned_results:O.length,allowed_domains:X,blocked_domains:Q};if(O.length===0)return{success:!0,llmContent:U,displayContent:`\uD83D\uDD0D WebSearch("${Z}") via ${K} - 未找到匹配结果`,metadata:F};return{success:!0,llmContent:U,displayContent:QW(Z,O,W.length,K),metadata:F}}catch(G){return{success:!1,llmContent:`WebSearch call failed: ${G.message}`,displayContent:`❌ WebSearch 调用失败: ${G.message}`,error:{type:"execution_error",message:G.message,details:{query:Z,allowedDomains:X,blockedDomains:Q}}}}},version:"2.0.0",category:"网络工具",tags:["web","search","internet","news"],extractSignatureContent:($)=>`search:${JW($.query)}`,abstractPermissionRule:()=>"search:*"})});var bZ=b(()=>{OZ();AZ()});import*as RZ from"os";import*as VZ from"path";async function qW(){try{return await n1.getInstance().getAvailableTools()}catch($){return console.warn("MCP协议工具加载失败:",$),[]}}async function DZ($){let Y=$?.sessionId||`session_${Date.now()}`,Z=$?.configDir||VZ.join(RZ.homedir(),".blade"),X=[v8,y8,P8,T8,x8,u8,d8,l8,i8,G7,W7,Q7,q7({sessionId:Y,configDir:Z}),k8,C8,r8,$7],Q=await qW();return[...X,...Q]}var IZ=b(()=>{L$();DY();MY();PY();pY();iY();$Z();QZ();UZ();bZ()});import{nanoid as GW}from"nanoid";class O7{name="hook";hookManager;constructor(){this.hookManager=H1.getInstance()}async process($){if(!this.hookManager.isEnabled())return;let Y=$._internal.tool;if(!Y)return;try{let Z=$.context.messageId||`tool_${GW()}`;$._internal.hookToolUseId=Z;let X=$.context.workspaceRoot||process.cwd(),Q=await this.hookManager.executePreToolHooks(Y.name,Z,$.params,{projectDir:X,sessionId:$.context.sessionId||"unknown",permissionMode:$.context.permissionMode||"default"});if(Q.decision==="deny"){$.abort(Q.reason||"Hook blocked execution");return}if(Q.decision==="ask"){$._internal.needsConfirmation=!0,$._internal.confirmationReason=Q.reason||"Hook requires confirmation";return}if(Q.modifiedInput){let J={...$.params,...Q.modifiedInput};if(Y.build)try{Y.build(J),$.params=J}catch(q){$.abort(`Hook modified parameters are invalid: ${q instanceof Error?q.message:String(q)}`);return}}if(Q.warning)console.warn(`[Hook Warning] ${Q.warning}`)}catch(Z){console.error("[HookStage] Error executing hooks:",Z)}}}var MZ=b(()=>{z0()});import{nanoid as KW}from"nanoid";class F7{name="post-hook";hookManager;constructor(){this.hookManager=H1.getInstance()}async process($){if(!this.hookManager.isEnabled())return;let Y=$._internal.tool;if(!Y)return;let Z=$.getResult();if(!Z)return;try{let X=$._internal.hookToolUseId||$.context.messageId||`tool_${KW()}`,Q=$.context.workspaceRoot||process.cwd(),J=await this.hookManager.executePostToolHooks(Y.name,X,$.params,Z,{projectDir:Q,sessionId:$.context.sessionId||"unknown",permissionMode:$.context.permissionMode||"default"});if(J.additionalContext){let q=Z.llmContent||Z.displayContent||"";Z.llmContent=`${q}
1214
+ `},async execute($,Y){let{query:Z}=$,X=fZ($.allowed_domains),Q=fZ($.blocked_domains),{updateOutput:J}=Y,q=Y.signal??new AbortController().signal;J?.(`\uD83D\uDD0E Searching: "${Z}" (${kZ()} providers available)`);try{let{results:K,providerName:G}=await bW(Z,NW,q,J),U=DW(K,X,Q),O=U.slice(0,BW),W={query:Z,results:O,provider:G,total_results:U.length,fetched_at:new Date().toISOString()},F={query:Z,provider:G,fetched_at:W.fetched_at,total_results:U.length,returned_results:O.length,allowed_domains:X,blocked_domains:Q};if(O.length===0)return{success:!0,llmContent:W,displayContent:`\uD83D\uDD0D WebSearch("${Z}") via ${G} - 未找到匹配结果`,metadata:F};return{success:!0,llmContent:W,displayContent:IW(Z,O,U.length,G),metadata:F}}catch(K){return{success:!1,llmContent:`WebSearch call failed: ${K.message}`,displayContent:`❌ WebSearch 调用失败: ${K.message}`,error:{type:"execution_error",message:K.message,details:{query:Z,allowedDomains:X,blockedDomains:Q}}}}},version:"2.0.0",category:"网络工具",tags:["web","search","internet","news"],extractSignatureContent:($)=>`search:${MW($.query)}`,abstractPermissionRule:()=>"search:*"})});var pZ=b(()=>{EZ();xZ()});import*as uZ from"os";import*as gZ from"path";async function jW(){try{return await t1.getInstance().getAvailableTools()}catch($){return console.warn("MCP协议工具加载失败:",$),[]}}async function dZ($){let Y=$?.sessionId||`session_${Date.now()}`,Z=$?.configDir||gZ.join(uZ.homedir(),".blade"),X=[x9,h9,u9,g9,r9,o9,t9,$7,Y7,B7,w7,H7,N7({sessionId:Y,configDir:Z}),d9,c9,X7,U7],Q=await jW();return[...X,...Q]}var mZ=b(()=>{b$();dY();cY();nY();XZ();WZ();LZ();RZ();jZ();pZ()});import{nanoid as yW}from"nanoid";class A7{name="hook";hookManager;constructor(){this.hookManager=H1.getInstance()}async process($){if(!this.hookManager.isEnabled())return;let Y=$._internal.tool;if(!Y)return;try{let Z=$.context.messageId||`tool_${yW()}`;$._internal.hookToolUseId=Z;let X=$.context.workspaceRoot||process.cwd(),Q=await this.hookManager.executePreToolHooks(Y.name,Z,$.params,{projectDir:X,sessionId:$.context.sessionId||"unknown",permissionMode:$.context.permissionMode||"default"});if(Q.decision==="deny"){$.abort(Q.reason||"Hook blocked execution");return}if(Q.decision==="ask"){$._internal.needsConfirmation=!0,$._internal.confirmationReason=Q.reason||"Hook requires confirmation";return}if(Q.modifiedInput){let J={...$.params,...Q.modifiedInput};if(Y.build)try{Y.build(J),$.params=J}catch(q){$.abort(`Hook modified parameters are invalid: ${q instanceof Error?q.message:String(q)}`);return}}if(Q.warning)console.warn(`[Hook Warning] ${Q.warning}`)}catch(Z){console.error("[HookStage] Error executing hooks:",Z)}}}var cZ=b(()=>{L0()});import{nanoid as EW}from"nanoid";class b7{name="post-hook";hookManager;constructor(){this.hookManager=H1.getInstance()}async process($){if(!this.hookManager.isEnabled())return;let Y=$._internal.tool;if(!Y)return;let Z=$.getResult();if(!Z)return;try{let X=$._internal.hookToolUseId||$.context.messageId||`tool_${EW()}`,Q=$.context.workspaceRoot||process.cwd(),J=await this.hookManager.executePostToolHooks(Y.name,X,$.params,Z,{projectDir:Q,sessionId:$.context.sessionId||"unknown",permissionMode:$.context.permissionMode||"default"});if(J.additionalContext){let q=Z.llmContent||Z.displayContent||"";Z.llmContent=`${q}
1213
1215
 
1214
1216
  ---
1215
1217
  **Hook Context:**
1216
- ${J.additionalContext}`}if(J.modifiedOutput!==void 0){let q=J.modifiedOutput;if(typeof q==="object"&&q!==null)Object.assign(Z,q)}if(J.warning)console.warn(`[PostToolUseHook Warning] ${J.warning}`)}catch(X){console.error("[PostToolUseHookStage] Error executing post-tool hooks:",X)}}}var jZ=b(()=>{z0()});class S2{static instance=null;locks=new Map;constructor(){}static getInstance(){if(!S2.instance)S2.instance=new S2;return S2.instance}async acquireLock($,Y){let Z=this.locks.get($);if(Z)try{await Z}catch{}let X=this.executeWithLock($,Y);return this.locks.set($,X.then(()=>{return})),X}async executeWithLock($,Y){H7.debug(`获取文件锁: ${$}`);try{let Z=await Y();return H7.debug(`释放文件锁: ${$}`),Z}catch(Z){throw H7.debug(`操作失败,释放文件锁: ${$}`),Z}}isLocked($){return this.locks.has($)}clearLock($){this.locks.delete($)}clearAll(){this.locks.clear()}getLockedFiles(){return Array.from(this.locks.keys())}getLockedFileCount(){return this.locks.size}static resetInstance(){S2.instance=null}}var H7;var yZ=b(()=>{V1();H7=n("Execution")});import UW from"node:os";import _7 from"node:path";var z7;var vZ=b(()=>{z7=class z7{static SENSITIVE_PATTERNS=[{pattern:/^\.?id_rsa$/i,level:"high",description:"SSH 私钥"},{pattern:/^\.?id_ed25519$/i,level:"high",description:"SSH Ed25519 私钥"},{pattern:/^\.?id_ecdsa$/i,level:"high",description:"SSH ECDSA 私钥"},{pattern:/\.pem$/i,level:"high",description:"PEM 格式私钥"},{pattern:/\.key$/i,level:"high",description:"密钥文件"},{pattern:/\.p12$/i,level:"high",description:"PKCS#12 证书"},{pattern:/\.pfx$/i,level:"high",description:"PFX 证书"},{pattern:/^\.?keystore$/i,level:"high",description:"Java Keystore"},{pattern:/^\.?pgpass$/i,level:"high",description:"PostgreSQL 密码文件"},{pattern:/^\.?my\.cnf$/i,level:"high",description:"MySQL 配置文件(可能含密码)"},{pattern:/credentials\.json$/i,level:"high",description:"Google Cloud 凭证"},{pattern:/^\.?aws[\\/]credentials$/i,level:"high",description:"AWS 凭证"},{pattern:/^\.?gcp[\\/]credentials$/i,level:"high",description:"GCP 凭证"},{pattern:/^\.?azure[\\/]credentials$/i,level:"high",description:"Azure 凭证"},{pattern:/^service-account.*\.json$/i,level:"high",description:"服务账号密钥"},{pattern:/^\.env$/i,level:"medium",description:"环境变量文件"},{pattern:/^\.env\./i,level:"medium",description:"环境变量文件(带环境后缀)"},{pattern:/^\.?npmrc$/i,level:"medium",description:"npm 配置文件(可能含 token)"},{pattern:/^\.?pypirc$/i,level:"medium",description:"PyPI 配置文件(可能含密码)"},{pattern:/^\.?dockercfg$/i,level:"medium",description:"Docker 配置文件"},{pattern:/^\.?docker[\\/]config\.json$/i,level:"medium",description:"Docker 配置文件"},{pattern:/^\.?netrc$/i,level:"medium",description:"FTP/HTTP 认证文件"},{pattern:/^\.?git-credentials$/i,level:"medium",description:"Git 凭证文件"},{pattern:/^config\.toml$/i,level:"medium",description:"配置文件(可能含敏感信息)"},{pattern:/^secrets\./i,level:"medium",description:"密钥配置文件"},{pattern:/\.sqlite$/i,level:"low",description:"SQLite 数据库"},{pattern:/\.db$/i,level:"low",description:"数据库文件"},{pattern:/\.sql$/i,level:"low",description:"SQL 文件(可能含敏感数据)"}];static SENSITIVE_PATHS=[{path:/\.ssh[\\/]/i,level:"high",description:"SSH 配置目录"},{path:/\.aws[\\/]/i,level:"high",description:"AWS 配置目录"},{path:/\.config[\\/]gcloud[\\/]/i,level:"high",description:"Google Cloud 配置目录"},{path:/\.kube[\\/]/i,level:"high",description:"Kubernetes 配置目录"}];static check($){let Y=this.normalizePath($),Z=_7.basename(Y);for(let X of this.SENSITIVE_PATTERNS)if(this.matchPattern(Z,X.pattern))return{isSensitive:!0,level:X.level,matchedPattern:X.pattern instanceof RegExp?X.pattern.source:X.pattern,reason:X.description};for(let X of this.SENSITIVE_PATHS)if(this.matchPattern(Y,X.path))return{isSensitive:!0,level:X.level,matchedPattern:X.path instanceof RegExp?X.path.source:X.path,reason:X.description};return{isSensitive:!1}}static checkMultiple($){let Y=new Map;for(let Z of $)Y.set(Z,this.check(Z));return Y}static filterSensitive($,Y="low"){let Z={["high"]:3,["medium"]:2,["low"]:1},X=Z[Y];return $.map((Q)=>({path:Q,result:this.check(Q)})).filter(({result:Q})=>Q.isSensitive&&Q.level&&Z[Q.level]>=X)}static normalizePath($){if($.startsWith("~/")||$==="~")return _7.join(UW.homedir(),$.slice(1));return _7.resolve($)}static matchPattern($,Y){if(Y instanceof RegExp)return Y.test($);let Z=Y.replace(/\*/g,".*");return new RegExp(`^${Z}$`,"i").test($)}static getSensitivePatterns(){return[...this.SENSITIVE_PATTERNS]}static getSensitivePaths(){return[...this.SENSITIVE_PATHS]}}});class N7{registry;name="discovery";constructor($){this.registry=$}async process($){let Y=this.registry.get($.toolName);if(!Y){$.abort(`Tool "${$.toolName}" not found`);return}$._internal.tool=Y}}class B7{name="permission";permissionChecker;sessionApprovals;defaultPermissionMode;constructor($,Y,Z){this.permissionChecker=new i2($),this.sessionApprovals=Y,this.defaultPermissionMode=Z}getPermissionChecker(){return this.permissionChecker}async process($){let Y=$._internal.tool;if(!Y){$.abort("Discovery stage failed; cannot perform permission check");return}try{let Z=Y.build($.params),X=Z.getAffectedPaths(),Q={toolName:Y.name,params:$.params,affectedPaths:X,tool:Y},J=i2.buildSignature(Q);$._internal.permissionSignature=J;let q=this.permissionChecker.check(Q),G=$.context.permissionMode||this.defaultPermissionMode;switch(q=this.applyModeOverrides(Y.kind,q,G),q.result){case"deny":$.abort(q.reason||`Tool invocation "${Y.name}" was denied by permission rules: ${q.matchedRule}`);return;case"ask":if(this.sessionApprovals.has(J))q={result:"allow",matchedRule:"remembered:session",reason:"User already allowed this operation in this session"};else $._internal.needsConfirmation=!0,$._internal.confirmationReason=q.reason||"User confirmation required";break;case"allow":break}if(X.length>0){let K=["/etc/","/sys/","/proc/","/dev/","/boot/","/root/","C:\\Windows\\System32","C:\\Program Files","C:\\ProgramData"],W=X.filter((U)=>{if(U.includes(".."))return!0;return K.some((F)=>U.includes(F))});if(W.length>0){$.abort(`Access to dangerous system paths denied: ${W.join(", ")}`);return}let O=z7.filterSensitive(X,"medium");if(O.length>0){let U=O.map(({path:H,result:_})=>`${H} (${_.level}: ${_.reason})`);if(O.filter(({result:H})=>H.level==="high").length>0&&q.result!=="allow"){$.abort(`Access to highly sensitive files denied:
1217
- ${U.join(`
1218
+ ${J.additionalContext}`}if(J.modifiedOutput!==void 0){let q=J.modifiedOutput;if(typeof q==="object"&&q!==null)Object.assign(Z,q)}if(J.warning)console.warn(`[PostToolUseHook Warning] ${J.warning}`)}catch(X){console.error("[PostToolUseHookStage] Error executing post-tool hooks:",X)}}}var lZ=b(()=>{L0()});class h2{static instance=null;locks=new Map;constructor(){}static getInstance(){if(!h2.instance)h2.instance=new h2;return h2.instance}async acquireLock($,Y){let Z=this.locks.get($);if(Z)try{await Z}catch{}let X=this.executeWithLock($,Y);return this.locks.set($,X.then(()=>{return})),X}async executeWithLock($,Y){R7.debug(`获取文件锁: ${$}`);try{let Z=await Y();return R7.debug(`释放文件锁: ${$}`),Z}catch(Z){throw R7.debug(`操作失败,释放文件锁: ${$}`),Z}}isLocked($){return this.locks.has($)}clearLock($){this.locks.delete($)}clearAll(){this.locks.clear()}getLockedFiles(){return Array.from(this.locks.keys())}getLockedFileCount(){return this.locks.size}static resetInstance(){h2.instance=null}}var R7;var iZ=b(()=>{w1();R7=c("Execution")});import vW from"node:os";import V7 from"node:path";var D7;var rZ=b(()=>{D7=class D7{static SENSITIVE_PATTERNS=[{pattern:/^\.?id_rsa$/i,level:"high",description:"SSH 私钥"},{pattern:/^\.?id_ed25519$/i,level:"high",description:"SSH Ed25519 私钥"},{pattern:/^\.?id_ecdsa$/i,level:"high",description:"SSH ECDSA 私钥"},{pattern:/\.pem$/i,level:"high",description:"PEM 格式私钥"},{pattern:/\.key$/i,level:"high",description:"密钥文件"},{pattern:/\.p12$/i,level:"high",description:"PKCS#12 证书"},{pattern:/\.pfx$/i,level:"high",description:"PFX 证书"},{pattern:/^\.?keystore$/i,level:"high",description:"Java Keystore"},{pattern:/^\.?pgpass$/i,level:"high",description:"PostgreSQL 密码文件"},{pattern:/^\.?my\.cnf$/i,level:"high",description:"MySQL 配置文件(可能含密码)"},{pattern:/credentials\.json$/i,level:"high",description:"Google Cloud 凭证"},{pattern:/^\.?aws[\\/]credentials$/i,level:"high",description:"AWS 凭证"},{pattern:/^\.?gcp[\\/]credentials$/i,level:"high",description:"GCP 凭证"},{pattern:/^\.?azure[\\/]credentials$/i,level:"high",description:"Azure 凭证"},{pattern:/^service-account.*\.json$/i,level:"high",description:"服务账号密钥"},{pattern:/^\.env$/i,level:"medium",description:"环境变量文件"},{pattern:/^\.env\./i,level:"medium",description:"环境变量文件(带环境后缀)"},{pattern:/^\.?npmrc$/i,level:"medium",description:"npm 配置文件(可能含 token)"},{pattern:/^\.?pypirc$/i,level:"medium",description:"PyPI 配置文件(可能含密码)"},{pattern:/^\.?dockercfg$/i,level:"medium",description:"Docker 配置文件"},{pattern:/^\.?docker[\\/]config\.json$/i,level:"medium",description:"Docker 配置文件"},{pattern:/^\.?netrc$/i,level:"medium",description:"FTP/HTTP 认证文件"},{pattern:/^\.?git-credentials$/i,level:"medium",description:"Git 凭证文件"},{pattern:/^config\.toml$/i,level:"medium",description:"配置文件(可能含敏感信息)"},{pattern:/^secrets\./i,level:"medium",description:"密钥配置文件"},{pattern:/\.sqlite$/i,level:"low",description:"SQLite 数据库"},{pattern:/\.db$/i,level:"low",description:"数据库文件"},{pattern:/\.sql$/i,level:"low",description:"SQL 文件(可能含敏感数据)"}];static SENSITIVE_PATHS=[{path:/\.ssh[\\/]/i,level:"high",description:"SSH 配置目录"},{path:/\.aws[\\/]/i,level:"high",description:"AWS 配置目录"},{path:/\.config[\\/]gcloud[\\/]/i,level:"high",description:"Google Cloud 配置目录"},{path:/\.kube[\\/]/i,level:"high",description:"Kubernetes 配置目录"}];static check($){let Y=this.normalizePath($),Z=V7.basename(Y);for(let X of this.SENSITIVE_PATTERNS)if(this.matchPattern(Z,X.pattern))return{isSensitive:!0,level:X.level,matchedPattern:X.pattern instanceof RegExp?X.pattern.source:X.pattern,reason:X.description};for(let X of this.SENSITIVE_PATHS)if(this.matchPattern(Y,X.path))return{isSensitive:!0,level:X.level,matchedPattern:X.path instanceof RegExp?X.path.source:X.path,reason:X.description};return{isSensitive:!1}}static checkMultiple($){let Y=new Map;for(let Z of $)Y.set(Z,this.check(Z));return Y}static filterSensitive($,Y="low"){let Z={["high"]:3,["medium"]:2,["low"]:1},X=Z[Y];return $.map((Q)=>({path:Q,result:this.check(Q)})).filter(({result:Q})=>Q.isSensitive&&Q.level&&Z[Q.level]>=X)}static normalizePath($){if($.startsWith("~/")||$==="~")return V7.join(vW.homedir(),$.slice(1));return V7.resolve($)}static matchPattern($,Y){if(Y instanceof RegExp)return Y.test($);let Z=Y.replace(/\*/g,".*");return new RegExp(`^${Z}$`,"i").test($)}static getSensitivePatterns(){return[...this.SENSITIVE_PATTERNS]}static getSensitivePaths(){return[...this.SENSITIVE_PATHS]}}});class I7{registry;name="discovery";constructor($){this.registry=$}async process($){let Y=this.registry.get($.toolName);if(!Y){$.abort(`Tool "${$.toolName}" not found`);return}$._internal.tool=Y}}class M7{name="permission";permissionChecker;sessionApprovals;defaultPermissionMode;constructor($,Y,Z){this.permissionChecker=new n2($),this.sessionApprovals=Y,this.defaultPermissionMode=Z}getPermissionChecker(){return this.permissionChecker}async process($){let Y=$._internal.tool;if(!Y){$.abort("Discovery stage failed; cannot perform permission check");return}try{let Z=Y.build($.params),X=Z.getAffectedPaths(),Q={toolName:Y.name,params:$.params,affectedPaths:X,tool:Y},J=n2.buildSignature(Q);$._internal.permissionSignature=J;let q=this.permissionChecker.check(Q),K=$.context.permissionMode||this.defaultPermissionMode;switch(q=this.applyModeOverrides(Y.kind,q,K),q.result){case"deny":$.abort(q.reason||`Tool invocation "${Y.name}" was denied by permission rules: ${q.matchedRule}`);return;case"ask":if(this.sessionApprovals.has(J))q={result:"allow",matchedRule:"remembered:session",reason:"User already allowed this operation in this session"};else $._internal.needsConfirmation=!0,$._internal.confirmationReason=q.reason||"User confirmation required";break;case"allow":break}if(X.length>0){let G=["/etc/","/sys/","/proc/","/dev/","/boot/","/root/","C:\\Windows\\System32","C:\\Program Files","C:\\ProgramData"],U=X.filter((W)=>{if(W.includes(".."))return!0;return G.some((F)=>W.includes(F))});if(U.length>0){$.abort(`Access to dangerous system paths denied: ${U.join(", ")}`);return}let O=D7.filterSensitive(X,"medium");if(O.length>0){let W=O.map(({path:H,result:z})=>`${H} (${z.level}: ${z.reason})`);if(O.filter(({result:H})=>H.level==="high").length>0&&q.result!=="allow"){$.abort(`Access to highly sensitive files denied:
1219
+ ${W.join(`
1218
1220
  `)}
1219
1221
 
1220
1222
  If access is required, add an explicit allow rule in permissions.`);return}if(q.result==="allow"&&O.length>0)$._internal.confirmationReason=`Sensitive file access detected:
1221
- ${U.join(`
1223
+ ${W.join(`
1222
1224
  `)}
1223
1225
 
1224
- Confirm to proceed?`,$._internal.needsConfirmation=!0}}$._internal.invocation=Z,$._internal.permissionCheckResult=q}catch(Z){$.abort(`Permission check failed: ${Z.message}`)}}applyModeOverrides($,Y,Z){if(Z==="yolo")return{result:"allow",matchedRule:"mode:yolo",reason:"YOLO mode: automatically approve all tool invocations"};if(Z==="plan"){if(!U6($))return{result:"deny",matchedRule:"mode:plan",reason:"Plan mode: modification tools are blocked; only read-only tools are allowed (Read/Glob/Grep/WebFetch/WebSearch/Task)"}}if(Y.result==="deny")return Y;if(Y.result==="allow")return Y;if(U6($))return{result:"allow",matchedRule:`mode:${Z}:readonly`,reason:"Read-only tools do not require confirmation"};if(Z==="autoEdit"&&$==="write")return{result:"allow",matchedRule:"mode:autoEdit:write",reason:"AUTO_EDIT mode: automatically approve write tools"};return Y}}class L7{sessionApprovals;name="confirmation";permissionChecker;constructor($,Y){this.sessionApprovals=$;this.permissionChecker=Y}async process($){let{tool:Y,invocation:Z,needsConfirmation:X,confirmationReason:Q,permissionCheckResult:J}=$._internal;if(!Y||!Z){$.abort("Pre-confirmation stage failed; cannot request user approval");return}if(!X)return;try{let q=Y.extractSignatureContent?Y.extractSignatureContent($.params):Y.name,G=H1.getInstance();if(G.isEnabled()){let O=await G.executePermissionRequestHooks(Y.name,$.context.sessionId||"unknown",$.params,{projectDir:process.cwd(),sessionId:$.context.sessionId||"unknown",permissionMode:$.context.permissionMode||"default"});switch(O.decision){case"approve":C2.debug(`PermissionRequest hook 自动批准: ${Y.name}`);return;case"deny":$.abort(O.reason||`PermissionRequest hook denied: ${Y.name}`,{shouldExitLoop:!0});return;case"ask":default:break}}let K={title:`权限确认: ${q}`,message:Q||"此操作需要用户确认",kind:Y.kind,details:this.generatePreviewForTool(Y.name,$.params),risks:this.extractRisksFromPermissionCheck(Y,$.params,J),affectedFiles:Z.getAffectedPaths()||[]};if(C2.warn(`工具 "${Y.name}" 需要用户确认: ${K.title}`),C2.warn(`详情: ${K.message}`),K.risks&&K.risks.length>0)C2.warn(`风险: ${K.risks.join(", ")}`);let W=$.context.confirmationHandler;if(W){let O=await W.requestConfirmation(K);if(!O.approved){$.abort(`User rejected execution: ${O.reason||"No reason provided"}`,{shouldExitLoop:!0});return}if((O.scope||"once")==="session"&&$._internal.permissionSignature){let F=$._internal.permissionSignature;this.sessionApprovals.add(F);let H={toolName:Y.name,params:$.params,affectedPaths:Z.getAffectedPaths()||[],tool:Y};await this.persistSessionApproval(F,H)}}else C2.warn("⚠️ No ConfirmationHandler; auto-approving tool execution (non-interactive environment only)")}catch(q){$.abort(`User confirmation failed: ${q.message}`)}}async persistSessionApproval($,Y){try{let Z=i2.abstractPattern(Y);C2.debug(`保存权限规则: "${Z}"`),await A1().appendLocalPermissionAllowRule(Z,{immediate:!0});let X=C1();if(X?.permissions)C2.debug("同步权限配置到 PermissionChecker:",X.permissions),this.permissionChecker.replaceConfig(X.permissions)}catch(Z){C2.warn(`Failed to persist permission rule "${$}": ${Z instanceof Error?Z.message:"Unknown error"}`)}}generatePreviewForTool($,Y){switch($){case"Edit":{let{old_string:Z,new_string:X}=Y;if(!Z&&!X)return;let Q=20,J=(q)=>{let G=q.split(`
1225
- `);if(G.length<=Q)return q;return`${G.slice(0,Q).join(`
1226
+ Confirm to proceed?`,$._internal.needsConfirmation=!0}}$._internal.invocation=Z,$._internal.permissionCheckResult=q}catch(Z){$.abort(`Permission check failed: ${Z.message}`)}}applyModeOverrides($,Y,Z){if(Z==="yolo")return{result:"allow",matchedRule:"mode:yolo",reason:"YOLO mode: automatically approve all tool invocations"};if(Z==="plan"){if(!F6($))return{result:"deny",matchedRule:"mode:plan",reason:"Plan mode: modification tools are blocked; only read-only tools are allowed (Read/Glob/Grep/WebFetch/WebSearch/Task)"}}if(Y.result==="deny")return Y;if(Y.result==="allow")return Y;if(F6($))return{result:"allow",matchedRule:`mode:${Z}:readonly`,reason:"Read-only tools do not require confirmation"};if(Z==="autoEdit"&&$==="write")return{result:"allow",matchedRule:"mode:autoEdit:write",reason:"AUTO_EDIT mode: automatically approve write tools"};return Y}}class j7{sessionApprovals;name="confirmation";permissionChecker;constructor($,Y){this.sessionApprovals=$;this.permissionChecker=Y}async process($){let{tool:Y,invocation:Z,needsConfirmation:X,confirmationReason:Q,permissionCheckResult:J}=$._internal;if(!Y||!Z){$.abort("Pre-confirmation stage failed; cannot request user approval");return}if(!X)return;try{let q=Y.extractSignatureContent?Y.extractSignatureContent($.params):Y.name,K=H1.getInstance();if(K.isEnabled()){let O=await K.executePermissionRequestHooks(Y.name,$.context.sessionId||"unknown",$.params,{projectDir:process.cwd(),sessionId:$.context.sessionId||"unknown",permissionMode:$.context.permissionMode||"default"});switch(O.decision){case"approve":x2.debug(`PermissionRequest hook 自动批准: ${Y.name}`);return;case"deny":$.abort(O.reason||`PermissionRequest hook denied: ${Y.name}`,{shouldExitLoop:!0});return;case"ask":default:break}}let G={title:`权限确认: ${q}`,message:Q||"此操作需要用户确认",kind:Y.kind,details:this.generatePreviewForTool(Y.name,$.params),risks:this.extractRisksFromPermissionCheck(Y,$.params,J),affectedFiles:Z.getAffectedPaths()||[]};if(x2.warn(`工具 "${Y.name}" 需要用户确认: ${G.title}`),x2.warn(`详情: ${G.message}`),G.risks&&G.risks.length>0)x2.warn(`风险: ${G.risks.join(", ")}`);let U=$.context.confirmationHandler;if(U){let O=await U.requestConfirmation(G);if(!O.approved){$.abort(`User rejected execution: ${O.reason||"No reason provided"}`,{shouldExitLoop:!0});return}if((O.scope||"once")==="session"&&$._internal.permissionSignature){let F=$._internal.permissionSignature;this.sessionApprovals.add(F);let H={toolName:Y.name,params:$.params,affectedPaths:Z.getAffectedPaths()||[],tool:Y};await this.persistSessionApproval(F,H)}}else x2.warn("⚠️ No ConfirmationHandler; auto-approving tool execution (non-interactive environment only)")}catch(q){$.abort(`User confirmation failed: ${q.message}`)}}async persistSessionApproval($,Y){try{let Z=n2.abstractPattern(Y);x2.debug(`保存权限规则: "${Z}"`),await D1().appendLocalPermissionAllowRule(Z,{immediate:!0});let X=x1();if(X?.permissions)x2.debug("同步权限配置到 PermissionChecker:",X.permissions),this.permissionChecker.replaceConfig(X.permissions)}catch(Z){x2.warn(`Failed to persist permission rule "${$}": ${Z instanceof Error?Z.message:"Unknown error"}`)}}generatePreviewForTool($,Y){switch($){case"Edit":{let{old_string:Z,new_string:X}=Y;if(!Z&&!X)return;let Q=20,J=(q)=>{let K=q.split(`
1227
+ `);if(K.length<=Q)return q;return`${K.slice(0,Q).join(`
1226
1228
  `)}
1227
- ... (还有 ${G.length-Q} 行)`};return`**变更前:**
1229
+ ... (还有 ${K.length-Q} 行)`};return`**变更前:**
1228
1230
  \`\`\`
1229
1231
  ${J(Z||"(空)")}
1230
1232
  \`\`\`
@@ -1242,57 +1244,57 @@ ${Z}
1242
1244
  ${q}
1243
1245
  \`\`\`
1244
1246
 
1245
- ... (还有 ${J.length-Q} 行)`}case"Bash":case"Shell":return;default:return}}extractRisksFromPermissionCheck($,Y,Z){let X=[];if(Z?.reason)X.push(Z.reason);if($.name==="Bash"){let Q=Y.command||"",J=Q.trim().split(/\s+/)[0];if(J==="cat"||J==="head"||J==="tail")X.push(`\uD83D\uDCA1 建议使用 Read 工具代替 ${J} 命令(性能更好,支持大文件分页)`);else if(J==="grep"||J==="rg")X.push("\uD83D\uDCA1 建议使用 Grep 工具代替 grep/rg 命令(支持更强大的过滤和上下文)");else if(J==="find")X.push("\uD83D\uDCA1 建议使用 Glob 工具代替 find 命令(更快,支持 glob 模式)");else if(J==="sed"||J==="awk")X.push(`\uD83D\uDCA1 建议使用 Edit 工具代替 ${J} 命令(更安全,支持预览和回滚)`);if(Q.includes("rm"))X.push("⚠️ 此命令可能删除文件");if(Q.includes("sudo"))X.push("⚠️ 此命令需要管理员权限");if(Q.includes("git push"))X.push("⚠️ 此命令将推送代码到远程仓库")}else if($.name==="Write"||$.name==="Edit")X.push("此操作将修改文件内容");else if($.name==="Delete")X.push("此操作将永久删除文件");return X}}class w7{name="execution";async process($){let Y=$._internal.invocation;if(!Y){$.abort("Pre-execution stage failed; cannot run tool");return}try{let Z=await Y.execute($.context.signal,$.context.onProgress,$.context);$.setResult(Z)}catch(Z){$.abort(`Tool execution failed: ${Z.message}`)}}}class A7{name="formatting";async process($){try{let Y=$.getResult();if(!Y.llmContent)Y.llmContent="Execution completed";if(!Y.displayContent)Y.displayContent=Y.success?"执行成功":"执行失败";if(!Y.metadata)Y.metadata={};Y.metadata.executionId=$.context.sessionId,Y.metadata.toolName=$.toolName,Y.metadata.timestamp=Date.now(),$.setResult(Y)}catch(Y){$.abort(`Result formatting failed: ${Y.message}`)}}}var C2;var EZ=b(()=>{V9();s1();z0();V1();N1();e1();vZ();C2=n("Execution")});import{EventEmitter as WW}from"events";var b7;var PZ=b(()=>{s1();z0();MZ();jZ();k9();n0();yZ();EZ();b7=class b7 extends WW{registry;stages;executionHistory=[];maxHistorySize;sessionApprovals=new Set;constructor($,Y={}){super();this.registry=$;this.maxHistorySize=Y.maxHistorySize||1000;let Z=Y.permissionConfig||{allow:[],ask:[],deny:[]},X=Y.permissionMode??"default",Q=new B7(Z,this.sessionApprovals,X);this.stages=[new N7(this.registry),Q,new O7,new L7(this.sessionApprovals,Q.getPermissionChecker()),new w7,new F7,new A7]}async execute($,Y,Z){let X=Date.now(),Q=this.generateExecutionId(),J=new T9($,Y,{...Z,sessionId:Z.sessionId||Q});this.emit("executionStarted",{executionId:Q,toolName:$,params:Y,context:Z,timestamp:X});let q=this.registry.get($),G=q&&!q.isConcurrencySafe,K=G&&Y.file_path?String(Y.file_path):null;if(G&&K)return S2.getInstance().acquireLock(K,()=>this.executeWithPipeline(J,Q,X));return this.executeWithPipeline(J,Q,X)}async executeWithPipeline($,Y,Z){try{for(let J of this.stages){if($.context.signal?.aborted){$.abort("任务已被用户中止");break}if(this.emit("stageStarted",{executionId:Y,stageName:J.name,timestamp:Date.now()}),await J.process($),this.emit("stageCompleted",{executionId:Y,stageName:J.name,timestamp:Date.now()}),$.shouldAbort())break}let X=$.getResult(),Q=Date.now();return this.addToHistory({executionId:Y,toolName:$.toolName,params:$.params,result:X,startTime:Z,endTime:Q,context:$.context}),this.emit("executionCompleted",{executionId:Y,toolName:$.toolName,result:X,duration:Q-Z,timestamp:Q}),X}catch(X){let Q=Date.now(),J=X.message?.includes("timeout")||X.name==="TimeoutError",q={success:!1,llmContent:`Tool execution failed: ${X.message}`,displayContent:`错误: ${X.message}`,error:{type:"execution_error",message:X.message}};try{let K=await H1.getInstance().executePostToolUseFailureHooks($.toolName,`tool_use_${Y}`,$.params,X.message,{projectDir:process.cwd(),sessionId:$.context.sessionId||"unknown",permissionMode:$.context.permissionMode||"default",isInterrupt:!1,isTimeout:J,abortSignal:$.context.signal});if(K.additionalContext)q={...q,llmContent:`${q.llmContent}
1247
+ ... (还有 ${J.length-Q} 行)`}case"Bash":case"Shell":return;default:return}}extractRisksFromPermissionCheck($,Y,Z){let X=[];if(Z?.reason)X.push(Z.reason);if($.name==="Bash"){let Q=Y.command||"",J=Q.trim().split(/\s+/)[0];if(J==="cat"||J==="head"||J==="tail")X.push(`\uD83D\uDCA1 建议使用 Read 工具代替 ${J} 命令(性能更好,支持大文件分页)`);else if(J==="grep"||J==="rg")X.push("\uD83D\uDCA1 建议使用 Grep 工具代替 grep/rg 命令(支持更强大的过滤和上下文)");else if(J==="find")X.push("\uD83D\uDCA1 建议使用 Glob 工具代替 find 命令(更快,支持 glob 模式)");else if(J==="sed"||J==="awk")X.push(`\uD83D\uDCA1 建议使用 Edit 工具代替 ${J} 命令(更安全,支持预览和回滚)`);if(Q.includes("rm"))X.push("⚠️ 此命令可能删除文件");if(Q.includes("sudo"))X.push("⚠️ 此命令需要管理员权限");if(Q.includes("git push"))X.push("⚠️ 此命令将推送代码到远程仓库")}else if($.name==="Write"||$.name==="Edit")X.push("此操作将修改文件内容");else if($.name==="Delete")X.push("此操作将永久删除文件");return X}}class y7{name="execution";async process($){let Y=$._internal.invocation;if(!Y){$.abort("Pre-execution stage failed; cannot run tool");return}try{let Z=await Y.execute($.context.signal,$.context.onProgress,$.context);$.setResult(Z)}catch(Z){$.abort(`Tool execution failed: ${Z.message}`)}}}class E7{name="formatting";async process($){try{let Y=$.getResult();if(!Y.llmContent)Y.llmContent="Execution completed";if(!Y.displayContent)Y.displayContent=Y.success?"执行成功":"执行失败";if(!Y.metadata)Y.metadata={};Y.metadata.executionId=$.context.sessionId,Y.metadata.toolName=$.toolName,Y.metadata.timestamp=Date.now(),$.setResult(Y)}catch(Y){$.abort(`Result formatting failed: ${Y.message}`)}}}var x2;var aZ=b(()=>{M8();$0();L0();w1();A1();Z0();rZ();x2=c("Execution")});import{EventEmitter as PW}from"events";var v7;var nZ=b(()=>{$0();L0();cZ();lZ();f8();t0();iZ();aZ();v7=class v7 extends PW{registry;stages;executionHistory=[];maxHistorySize;sessionApprovals=new Set;constructor($,Y={}){super();this.registry=$;this.maxHistorySize=Y.maxHistorySize||1000;let Z=Y.permissionConfig||{allow:[],ask:[],deny:[]},X=Y.permissionMode??"default",Q=new M7(Z,this.sessionApprovals,X);this.stages=[new I7(this.registry),Q,new A7,new j7(this.sessionApprovals,Q.getPermissionChecker()),new y7,new b7,new E7]}async execute($,Y,Z){let X=Date.now(),Q=this.generateExecutionId(),J=new C8($,Y,{...Z,sessionId:Z.sessionId||Q});this.emit("executionStarted",{executionId:Q,toolName:$,params:Y,context:Z,timestamp:X});let q=this.registry.get($),K=q&&!q.isConcurrencySafe,G=K&&Y.file_path?String(Y.file_path):null;if(K&&G)return h2.getInstance().acquireLock(G,()=>this.executeWithPipeline(J,Q,X));return this.executeWithPipeline(J,Q,X)}async executeWithPipeline($,Y,Z){try{for(let J of this.stages){if($.context.signal?.aborted){$.abort("任务已被用户中止");break}if(this.emit("stageStarted",{executionId:Y,stageName:J.name,timestamp:Date.now()}),await J.process($),this.emit("stageCompleted",{executionId:Y,stageName:J.name,timestamp:Date.now()}),$.shouldAbort())break}let X=$.getResult(),Q=Date.now();return this.addToHistory({executionId:Y,toolName:$.toolName,params:$.params,result:X,startTime:Z,endTime:Q,context:$.context}),this.emit("executionCompleted",{executionId:Y,toolName:$.toolName,result:X,duration:Q-Z,timestamp:Q}),X}catch(X){let Q=Date.now(),J=X.message?.includes("timeout")||X.name==="TimeoutError",q={success:!1,llmContent:`Tool execution failed: ${X.message}`,displayContent:`错误: ${X.message}`,error:{type:"execution_error",message:X.message}};try{let G=await H1.getInstance().executePostToolUseFailureHooks($.toolName,`tool_use_${Y}`,$.params,X.message,{projectDir:process.cwd(),sessionId:$.context.sessionId||"unknown",permissionMode:$.context.permissionMode||"default",isInterrupt:!1,isTimeout:J,abortSignal:$.context.signal});if(G.additionalContext)q={...q,llmContent:`${q.llmContent}
1246
1248
 
1247
- ${K.additionalContext}`};if(K.warning)console.warn(`[ExecutionPipeline] PostToolUseFailure hook warning: ${K.warning}`)}catch(G){console.warn("[ExecutionPipeline] PostToolUseFailure hook execution failed:",G)}return this.addToHistory({executionId:Y,toolName:$.toolName,params:$.params,result:q,startTime:Z,endTime:Q,context:$.context}),this.emit("executionFailed",{executionId:Y,toolName:$.toolName,error:X,duration:Q-Z,timestamp:Q}),q}}async executeAll($){let Y=$.map((Z)=>this.execute(Z.toolName,Z.params,Z.context));return Promise.all(Y)}async executeParallel($,Y=5){let Z=[],X=[];for(let Q=0;Q<$.length;Q++){let J=$[Q],q=this.execute(J.toolName,J.params,J.context);if(X.push(q),X.length>=Y||Q===$.length-1){let G=await Promise.all(X);Z.push(...G),X.length=0}}return Z}getExecutionHistory($){let Y=[...this.executionHistory];return $?Y.slice(-$):Y}clearHistory(){this.executionHistory=[],this.emit("historyClear",{timestamp:Date.now()})}getStats(){let $={totalExecutions:this.executionHistory.length,successfulExecutions:0,failedExecutions:0,averageDuration:0,toolUsage:new Map,recentExecutions:this.executionHistory.slice(-10)},Y=0;for(let Z of this.executionHistory){if(Z.result.success)$.successfulExecutions++;else $.failedExecutions++;let X=Z.endTime-Z.startTime;Y+=X;let Q=$.toolUsage.get(Z.toolName)||0;$.toolUsage.set(Z.toolName,Q+1)}return $.averageDuration=$.totalExecutions>0?Y/$.totalExecutions:0,$}addStage($,Y=-1){if(Y===-1){let Z=this.stages.findIndex((X)=>X.name==="execution");this.stages.splice(Z,0,$)}else this.stages.splice(Y,0,$);this.emit("stageAdded",{stageName:$.name,position:Y,timestamp:Date.now()})}removeStage($){let Y=this.stages.findIndex((Z)=>Z.name===$);if(Y===-1)return!1;return this.stages.splice(Y,1),this.emit("stageRemoved",{stageName:$,timestamp:Date.now()}),!0}getStages(){return[...this.stages]}getRegistry(){return this.registry}generateExecutionId(){return`exec_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}addToHistory($){if(this.executionHistory.push($),this.executionHistory.length>this.maxHistorySize)this.executionHistory=this.executionHistory.slice(-this.maxHistorySize)}}});import{EventEmitter as OW}from"events";var R7;var TZ=b(()=>{s1();R7=class R7 extends OW{tools=new Map;mcpTools=new Map;categories=new Map;tags=new Map;constructor(){super()}register($){if(this.tools.has($.name))throw Error(`工具 '${$.name}' 已注册`);this.tools.set($.name,$),this.updateIndexes($),this.emit("toolRegistered",{type:"builtin",tool:$,timestamp:Date.now()})}registerAll($){let Y=[];for(let Z of $)try{this.register(Z)}catch(X){Y.push(`${Z.name}: ${X.message}`)}if(Y.length>0)throw Error(`批量注册失败: ${Y.join(", ")}`)}unregister($){let Y=this.tools.get($);if(!Y)return!1;return this.tools.delete($),this.removeFromIndexes(Y),this.emit("toolUnregistered",{type:"builtin",toolName:$,timestamp:Date.now()}),!0}get($){return this.tools.get($)||this.mcpTools.get($)}has($){return this.tools.has($)||this.mcpTools.has($)}getAll(){return[...Array.from(this.tools.values()),...Array.from(this.mcpTools.values())]}getBuiltinTools(){return Array.from(this.tools.values())}getMcpTools(){return Array.from(this.mcpTools.values())}getByCategory($){let Y=this.categories.get($);if(!Y)return[];return Array.from(Y).map((Z)=>this.get(Z)).filter((Z)=>Z!==void 0)}getByTag($){let Y=this.tags.get($);if(!Y)return[];return Array.from(Y).map((Z)=>this.get(Z)).filter((Z)=>Z!==void 0)}search($){let Y=$.toLowerCase();return this.getAll().filter((Z)=>{let X=typeof Z.description==="string"?Z.description:Z.description.short;return Z.name.toLowerCase().includes(Y)||X.toLowerCase().includes(Y)||Z.displayName.toLowerCase().includes(Y)||Z.category&&Z.category.toLowerCase().includes(Y)||Z.tags.some((Q)=>Q.toLowerCase().includes(Y))})}getFunctionDeclarations(){return this.getAll().map(($)=>$.getFunctionDeclaration())}getReadOnlyFunctionDeclarations(){return this.getAll().filter(($)=>$.isReadOnly).map(($)=>$.getFunctionDeclaration())}getFunctionDeclarationsByMode($){if($==="plan")return this.getReadOnlyFunctionDeclarations();return this.getFunctionDeclarations()}getReadOnlyTools(){return this.getAll().filter(($)=>$.isReadOnly)}getCategories(){return Array.from(this.categories.keys())}getTags(){return Array.from(this.tags.keys())}getStats(){return{totalTools:this.tools.size+this.mcpTools.size,builtinTools:this.tools.size,mcpTools:this.mcpTools.size,categories:this.categories.size,tags:this.tags.size,toolsByCategory:Object.fromEntries(Array.from(this.categories.entries()).map(([$,Y])=>[$,Y.size]))}}registerMcpTool($){if(this.mcpTools.has($.name))this.mcpTools.delete($.name);this.mcpTools.set($.name,$),this.updateIndexes($),this.emit("toolRegistered",{type:"mcp",tool:$,timestamp:Date.now()})}removeMcpTools($){let Y=0,Z=`mcp__${$}__`;for(let[X,Q]of this.mcpTools.entries())if(X.startsWith(Z))this.mcpTools.delete(X),this.removeFromIndexes(Q),Y++,this.emit("toolUnregistered",{type:"mcp",toolName:X,serverName:$,timestamp:Date.now()});return Y}updateIndexes($){if($.category){if(!this.categories.has($.category))this.categories.set($.category,new Set);this.categories.get($.category).add($.name)}for(let Y of $.tags){if(!this.tags.has(Y))this.tags.set(Y,new Set);this.tags.get(Y).add($.name)}}removeFromIndexes($){if($.category){let Y=this.categories.get($.category);if(Y){if(Y.delete($.name),Y.size===0)this.categories.delete($.category)}}for(let Y of $.tags){let Z=this.tags.get(Y);if(Z){if(Z.delete($.name),Z.size===0)this.tags.delete(Y)}}}}});function HW($){return FW.some((Y)=>Y.test($))}function _W($){if($.supportsThinking!==void 0)return{supportsThinking:$.supportsThinking,thinkingBudget:$.thinkingBudget};return{supportsThinking:HW($.model),thinkingBudget:void 0}}function C$($){return _W($).supportsThinking}var FW;var T4=b(()=>{FW=[/deepseek.*r1/i,/deepseek.*reasoner/i,/o1-preview/i,/o1-mini/i,/o1/i,/qwen.*qwq/i,/qwen.*think/i,/kimi.*k1/i,/moonshot.*think/i,/k1-32k/i,/doubao.*think/i,/doubao.*pro.*think/i,/claude.*opus.*4/i]});class V7{maxSummaryLength;keyPointsLimit;recentMessagesLimit;constructor($=500,Y=10,Z=20){this.maxSummaryLength=$,this.keyPointsLimit=Y,this.recentMessagesLimit=Z}async compress($){let Y=$.layers.conversation.messages,Z=$.layers.tool.recentCalls,X=Y.filter((U)=>U.role==="system"),Q=Y.filter((U)=>U.role!=="system"),J=this.getRecentMessages(Q),q=Q.slice(0,-this.recentMessagesLimit),G=await this.generateSummary(q),K=this.extractKeyPoints(q,Z),W=this.generateToolSummary(Z),O=this.estimateTokenCount(G,K,J,W);return{summary:G,keyPoints:K,recentMessages:[...X,...J],toolSummary:W,tokenCount:O}}getRecentMessages($){return $.slice(-this.recentMessagesLimit)}async generateSummary($){if($.length===0)return"";let Y=new Set,Z=new Set,X=new Set;for(let J of $){let q=J.content.toLowerCase();["关于","讨论","问题","项目","功能","需求"].forEach((O)=>{if(q.includes(O)){let U=this.extractContext(q,O,50);if(U)Y.add(U)}}),["创建","删除","修改","更新","实现","开发"].forEach((O)=>{if(q.includes(O)){let U=this.extractContext(q,O,30);if(U)Z.add(U)}}),["决定","选择","确定","采用","使用"].forEach((O)=>{if(q.includes(O)){let U=this.extractContext(q,O,40);if(U)X.add(U)}})}let Q=`对话涉及 ${$.length} 条消息。`;if(Y.size>0)Q+=` 主要讨论:${Array.from(Y).slice(0,3).join("、")}。`;if(Z.size>0)Q+=` 执行操作:${Array.from(Z).slice(0,3).join("、")}。`;if(X.size>0)Q+=` 关键决策:${Array.from(X).slice(0,2).join("、")}。`;return Q.length>this.maxSummaryLength?Q.substring(0,this.maxSummaryLength)+"...":Q}extractKeyPoints($,Y){let Z=new Set;for(let Q of $)if(Q.role==="user")this.extractQuestions(Q.content).forEach((G)=>Z.add(`用户问题:${G}`)),this.extractRequests(Q.content).forEach((G)=>Z.add(`用户请求:${G}`));else if(Q.role==="assistant")this.extractSolutions(Q.content).forEach((q)=>Z.add(`解决方案:${q}`));return this.summarizeToolUsage(Y).forEach((Q)=>Z.add(`工具使用:${Q}`)),Array.from(Z).slice(0,this.keyPointsLimit)}generateToolSummary($){if($.length===0)return"";let Y=new Map,Z=Date.now()-600000;for(let Q of $){let J=Y.get(Q.name)||{count:0,success:0,recent:0};if(J.count++,Q.status==="success")J.success++;if(Q.timestamp>Z)J.recent++;Y.set(Q.name,J)}let X=[];for(let[Q,J]of Array.from(Y.entries())){let q=Math.round(J.success/J.count*100);X.push(`${Q}(${J.count}次,成功率${q}%)`)}return`工具调用:${X.join("、")}`}estimateTokenCount($,Y,Z,X){let Q=$.length+Y.join(" ").length;if(X)Q+=X.length;for(let J of Z)Q+=J.content.length;return Math.ceil(Q/4)}extractContext($,Y,Z){let X=$.indexOf(Y);if(X===-1)return null;let Q=Math.max(0,X-Z/2),J=Math.min($.length,X+Z/2);return $.substring(Q,J).trim()}extractQuestions($){let Y=[],Z=["?","?","如何","怎么","什么","为什么"],X=$.split(/[。!.!]/);for(let Q of X)if(Z.some((J)=>Q.includes(J))){let J=Q.trim();if(J.length>5&&J.length<100)Y.push(J)}return Y.slice(0,3)}extractRequests($){let Y=[],Z=["请","帮我","需要","想要","希望","能否"],X=$.split(/[。!.!]/);for(let Q of X)if(Z.some((J)=>Q.includes(J))){let J=Q.trim();if(J.length>5&&J.length<100)Y.push(J)}return Y.slice(0,3)}extractSolutions($){let Y=[],Z=["可以","建议","推荐","应该","最好","解决方案"],X=$.split(/[。!.!]/);for(let Q of X)if(Z.some((J)=>Q.includes(J))){let J=Q.trim();if(J.length>10&&J.length<150)Y.push(J)}return Y.slice(0,3)}summarizeToolUsage($){let Y=[],Z=$.filter((X)=>Date.now()-X.timestamp<1800000);if(Z.length>0){let X=new Map;Z.forEach((Q)=>{let J=X.get(Q.name)||[];J.push(Q),X.set(Q.name,J)});for(let[Q,J]of Array.from(X.entries())){let q=J.filter((G)=>G.status==="success").length;Y.push(`${Q}(${J.length}次,${q}成功)`)}}return Y.slice(0,5)}shouldCompress($,Y){return this.estimateCurrentTokens($)>Y*0.8}estimateCurrentTokens($){let Z=$.layers.conversation.messages.reduce((X,Q)=>X+Q.content.length,0);return Math.ceil(Z/4)}}class t2{defaultOptions;constructor($){this.defaultOptions={maxTokens:32000,maxMessages:50,timeWindow:86400000,priority:1,includeTools:!0,includeWorkspace:!0,...$}}filter($,Y){let Z={...this.defaultOptions,...Y},X={layers:{system:$.layers.system,session:$.layers.session,conversation:this.filterConversation($.layers.conversation,Z),tool:Z.includeTools?this.filterTools($.layers.tool,Z):{recentCalls:[],toolStates:{},dependencies:{}},workspace:Z.includeWorkspace?$.layers.workspace:{currentFiles:[],recentFiles:[],environment:{}}},metadata:{...$.metadata,lastUpdated:Date.now()}};return X.metadata.totalTokens=this.estimateTokens(X),X}filterConversation($,Y){let Z=[...$.messages];if(Y.timeWindow>0){let X=Date.now()-Y.timeWindow;Z=Z.filter((Q)=>Q.timestamp>=X||Q.role==="system")}if(Y.priority>1)Z=this.filterByPriority(Z,Y.priority);if(Y.maxMessages>0)Z=this.limitMessages(Z,Y.maxMessages);if(Y.maxTokens>0)Z=this.limitByTokens(Z,Y.maxTokens);return{messages:Z,summary:$.summary,topics:this.updateTopics(Z,$.topics),lastActivity:$.lastActivity}}filterTools($,Y){let Z=[...$.recentCalls];if(Y.timeWindow>0){let K=Date.now()-Y.timeWindow;Z=Z.filter((W)=>W.timestamp>=K)}let X=Z.filter((K)=>K.status==="success"),Q=Z.filter((K)=>K.status==="error"),J=Math.min(20,X.length),q=Math.min(10,Q.length);return{recentCalls:[...X.slice(-J),...Q.slice(-q)].sort((K,W)=>K.timestamp-W.timestamp),toolStates:$.toolStates,dependencies:$.dependencies}}filterByPriority($,Y){return $.filter((Z)=>{if(Z.role==="system")return!0;return this.calculateMessagePriority(Z)>=Y})}calculateMessagePriority($){let Y=1;if($.role==="system")Y+=3;else if($.role==="assistant")Y+=1;let Z=$.content.toLowerCase();if(["错误","警告","重要","关键","问题","解决"].some((J)=>Z.includes(J)))Y+=2;if(Z.includes("```")||Z.includes("function")||Z.includes("class"))Y+=1;let Q=(Date.now()-$.timestamp)/3600000;if(Q<1)Y+=2;else if(Q<6)Y+=1;return Y}limitMessages($,Y){if($.length<=Y)return $;let Z=$.filter((q)=>q.role==="system"),X=$.filter((q)=>q.role!=="system"),Q=Y-Z.length,J=Q>0?X.slice(-Q):[];return[...Z,...J].sort((q,G)=>q.timestamp-G.timestamp)}limitByTokens($,Y){if(Y<=0)return $;let Z=0,X=[];for(let Q=$.length-1;Q>=0;Q--){let J=$[Q],q=this.estimateMessageTokens(J);if(J.role==="system")if(Z+q<=Y)X.unshift(J),Z+=q;else{let G=this.compressMessage(J,Y-Z);X.unshift(G),Z+=this.estimateMessageTokens(G)}else if(Z+q<=Y)X.unshift(J),Z+=q;else break}return X.sort((Q,J)=>Q.timestamp-J.timestamp)}estimateMessageTokens($){return Math.ceil($.content.length/4)}compressMessage($,Y){let Z=Y*4;if($.content.length<=Z)return $;let X=$.content.substring(0,Z-3)+"...";return{...$,content:X,metadata:{...$.metadata,compressed:!0,originalLength:$.content.length}}}updateTopics($,Y){let Z=new Set(Y);for(let X of $)this.extractTopicsFromMessage(X).forEach((J)=>Z.add(J));return Array.from(Z).slice(0,10)}extractTopicsFromMessage($){let Y=$.content.toLowerCase(),Z=[];return["项目","功能","模块","组件","服务","接口","数据库","前端","后端","算法","架构","设计"].forEach((Q)=>{if(Y.includes(Q))Z.push(Q)}),Z}estimateTokens($){let Y=0;for(let X of $.layers.conversation.messages)Y+=this.estimateMessageTokens(X);let Z=JSON.stringify($.layers.system);if(Y+=Math.ceil(Z.length/4),$.layers.tool.recentCalls.length>0){let X=JSON.stringify($.layers.tool);Y+=Math.ceil(X.length/8)}return Y}static createPresets(){return{lightweight:new t2({maxTokens:1000,maxMessages:10,timeWindow:7200000,includeTools:!1,includeWorkspace:!1}),standard:new t2({maxTokens:4000,maxMessages:30,timeWindow:43200000,includeTools:!0,includeWorkspace:!0}),comprehensive:new t2({maxTokens:8000,maxMessages:100,timeWindow:86400000,includeTools:!0,includeWorkspace:!0}),debug:new t2({maxTokens:2000,maxMessages:20,timeWindow:21600000,priority:2,includeTools:!0,includeWorkspace:!1})}}}class D7{cache=new Map;maxSize;defaultTTL;constructor($=100,Y=300000){this.maxSize=$,this.defaultTTL=Y}set($,Y,Z){let X=Date.now(),Q={data:Y,timestamp:X,accessCount:0,lastAccess:X,ttl:Z||this.defaultTTL};if(this.cache.size>=this.maxSize&&!this.cache.has($))this.evictLeastUsed();this.cache.set($,Q)}get($){let Y=this.cache.get($);if(!Y)return null;let Z=Date.now();if(Z-Y.timestamp>Y.ttl)return this.cache.delete($),null;return Y.accessCount++,Y.lastAccess=Z,Y.data}has($){let Y=this.cache.get($);if(!Y)return!1;if(Date.now()-Y.timestamp>Y.ttl)return this.cache.delete($),!1;return!0}delete($){return this.cache.delete($)}clear(){this.cache.clear()}size(){return this.cleanExpired(),this.cache.size}cacheMessageSummary($,Y,Z){let X=`summary:${$}:${Y.length}`;this.set(X,{summary:Z,messageCount:Y.length,lastMessage:Y[Y.length-1]?.timestamp||0},600000)}getMessageSummary($,Y){let Z=`summary:${$}:${Y}`;return this.get(Z)}cacheToolResult($,Y,Z){let X=this.hashInput(Y),Q=`tool:${$}:${X}`;this.set(Q,Z,1800000)}getToolResult($,Y){let Z=this.hashInput(Y),X=`tool:${$}:${Z}`;return this.get(X)}cacheCompressedContext($,Y){let Z=`compressed:${$}`;this.set(Z,Y,900000)}getCompressedContext($){let Y=`compressed:${$}`;return this.get(Y)}getStats(){this.cleanExpired();let $=0,Y=0,Z=[];for(let[X,Q]of Array.from(this.cache.entries()))$+=Q.accessCount,Y+=this.estimateItemSize(Q),Z.push({key:X,accessCount:Q.accessCount,lastAccess:Q.lastAccess});return Z.sort((X,Q)=>Q.accessCount-X.accessCount),{size:this.cache.size,maxSize:this.maxSize,hitRate:$>0?$/($+this.cache.size):0,memoryUsage:Y,topKeys:Z.slice(0,10)}}cleanExpired(){let $=Date.now(),Y=[];for(let[Z,X]of Array.from(this.cache.entries()))if($-X.timestamp>X.ttl)Y.push(Z);Y.forEach((Z)=>this.cache.delete(Z))}evictLeastUsed(){let $=null,Y=1/0,Z=Date.now();for(let[X,Q]of Array.from(this.cache.entries())){let J=1/(Z-Q.lastAccess+1),q=Q.accessCount,G=J*q;if(G<Y)Y=G,$=X}if($)this.cache.delete($)}hashInput($){let Y=JSON.stringify($),Z=0;for(let X=0;X<Y.length;X++){let Q=Y.charCodeAt(X);Z=(Z<<5)-Z+Q,Z=Z&Z}return Math.abs(Z).toString(36)}estimateItemSize($){try{return JSON.stringify($).length*2}catch{return 1000}}setTTL($,Y){let Z=this.cache.get($);if(Z)return Z.ttl=Y,Z.timestamp=Date.now(),!0;return!1}getRemainingTTL($){let Y=this.cache.get($);if(!Y)return-1;let Z=Y.ttl-(Date.now()-Y.timestamp);return Math.max(0,Z)}warmup($){$.forEach(({key:Y,value:Z,ttl:X})=>{this.set(Y,Z,X)})}}class I7{contextData=null;maxSize;accessLog=new Map;constructor($=1000){this.maxSize=$}setContext($){this.contextData={...$},this.contextData.metadata.lastUpdated=Date.now(),this.recordAccess("context")}getContext(){if(this.contextData)this.recordAccess("context");return this.contextData}addMessage($){if(!this.contextData)throw Error("上下文数据未初始化");this.contextData.layers.conversation.messages.push($),this.contextData.layers.conversation.lastActivity=Date.now(),this.contextData.metadata.lastUpdated=Date.now(),this.enforceMemoryLimit(),this.recordAccess("messages")}getRecentMessages($=10){if(!this.contextData)return[];let Y=this.contextData.layers.conversation.messages;return this.recordAccess("messages"),Y.slice(-$)}addToolCall($){if(!this.contextData)throw Error("上下文数据未初始化");if(this.contextData.layers.tool.recentCalls.push($),this.contextData.metadata.lastUpdated=Date.now(),this.contextData.layers.tool.recentCalls.length>50)this.contextData.layers.tool.recentCalls=this.contextData.layers.tool.recentCalls.slice(-25);this.recordAccess("tools")}updateToolState($,Y){if(!this.contextData)throw Error("上下文数据未初始化");this.contextData.layers.tool.toolStates[$]=Y,this.contextData.metadata.lastUpdated=Date.now(),this.recordAccess("tools")}getToolState($){if(!this.contextData)return null;return this.recordAccess("tools"),this.contextData.layers.tool.toolStates[$]}updateWorkspace($){if(!this.contextData)throw Error("上下文数据未初始化");Object.assign(this.contextData.layers.workspace,$),this.contextData.metadata.lastUpdated=Date.now(),this.recordAccess("workspace")}clear(){this.contextData=null,this.accessLog.clear()}getMemoryInfo(){if(!this.contextData)return{hasData:!1,messageCount:0,toolCallCount:0,lastUpdated:null};return{hasData:!0,messageCount:this.contextData.layers.conversation.messages.length,toolCallCount:this.contextData.layers.tool.recentCalls.length,lastUpdated:this.contextData.metadata.lastUpdated}}recordAccess($){this.accessLog.set($,Date.now())}enforceMemoryLimit(){if(!this.contextData)return;let $=this.contextData.layers.conversation.messages;if($.length>this.maxSize){let Y=Math.floor(this.maxSize*0.8);this.contextData.layers.conversation.messages=$.slice(-Y)}}getMemoryUsage(){if(!this.contextData)return 0;return JSON.stringify(this.contextData).length}}import*as k4 from"node:fs";import{createReadStream as zW}from"node:fs";import*as W0 from"node:fs/promises";import*as M7 from"node:path";import{createInterface as NW}from"node:readline";class m0{filePath;constructor($){this.filePath=$}async append($){try{await W0.mkdir(M7.dirname(this.filePath),{recursive:!0});let Y=JSON.stringify($)+`
1248
- `;await W0.appendFile(this.filePath,Y,"utf-8")}catch(Y){throw console.error(`[JSONLStore] 追加写入失败: ${this.filePath}`,Y),Y}}async appendBatch($){try{await W0.mkdir(M7.dirname(this.filePath),{recursive:!0});let Y=$.map((Z)=>JSON.stringify(Z)).join(`
1249
+ ${G.additionalContext}`};if(G.warning)console.warn(`[ExecutionPipeline] PostToolUseFailure hook warning: ${G.warning}`)}catch(K){console.warn("[ExecutionPipeline] PostToolUseFailure hook execution failed:",K)}return this.addToHistory({executionId:Y,toolName:$.toolName,params:$.params,result:q,startTime:Z,endTime:Q,context:$.context}),this.emit("executionFailed",{executionId:Y,toolName:$.toolName,error:X,duration:Q-Z,timestamp:Q}),q}}async executeAll($){let Y=$.map((Z)=>this.execute(Z.toolName,Z.params,Z.context));return Promise.all(Y)}async executeParallel($,Y=5){let Z=[],X=[];for(let Q=0;Q<$.length;Q++){let J=$[Q],q=this.execute(J.toolName,J.params,J.context);if(X.push(q),X.length>=Y||Q===$.length-1){let K=await Promise.all(X);Z.push(...K),X.length=0}}return Z}getExecutionHistory($){let Y=[...this.executionHistory];return $?Y.slice(-$):Y}clearHistory(){this.executionHistory=[],this.emit("historyClear",{timestamp:Date.now()})}getStats(){let $={totalExecutions:this.executionHistory.length,successfulExecutions:0,failedExecutions:0,averageDuration:0,toolUsage:new Map,recentExecutions:this.executionHistory.slice(-10)},Y=0;for(let Z of this.executionHistory){if(Z.result.success)$.successfulExecutions++;else $.failedExecutions++;let X=Z.endTime-Z.startTime;Y+=X;let Q=$.toolUsage.get(Z.toolName)||0;$.toolUsage.set(Z.toolName,Q+1)}return $.averageDuration=$.totalExecutions>0?Y/$.totalExecutions:0,$}addStage($,Y=-1){if(Y===-1){let Z=this.stages.findIndex((X)=>X.name==="execution");this.stages.splice(Z,0,$)}else this.stages.splice(Y,0,$);this.emit("stageAdded",{stageName:$.name,position:Y,timestamp:Date.now()})}removeStage($){let Y=this.stages.findIndex((Z)=>Z.name===$);if(Y===-1)return!1;return this.stages.splice(Y,1),this.emit("stageRemoved",{stageName:$,timestamp:Date.now()}),!0}getStages(){return[...this.stages]}getRegistry(){return this.registry}generateExecutionId(){return`exec_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}addToHistory($){if(this.executionHistory.push($),this.executionHistory.length>this.maxHistorySize)this.executionHistory=this.executionHistory.slice(-this.maxHistorySize)}}});import{EventEmitter as TW}from"events";var P7;var oZ=b(()=>{$0();P7=class P7 extends TW{tools=new Map;mcpTools=new Map;categories=new Map;tags=new Map;constructor(){super()}register($){if(this.tools.has($.name))throw Error(`工具 '${$.name}' 已注册`);this.tools.set($.name,$),this.updateIndexes($),this.emit("toolRegistered",{type:"builtin",tool:$,timestamp:Date.now()})}registerAll($){let Y=[];for(let Z of $)try{this.register(Z)}catch(X){Y.push(`${Z.name}: ${X.message}`)}if(Y.length>0)throw Error(`批量注册失败: ${Y.join(", ")}`)}unregister($){let Y=this.tools.get($);if(!Y)return!1;return this.tools.delete($),this.removeFromIndexes(Y),this.emit("toolUnregistered",{type:"builtin",toolName:$,timestamp:Date.now()}),!0}get($){return this.tools.get($)||this.mcpTools.get($)}has($){return this.tools.has($)||this.mcpTools.has($)}getAll(){return[...Array.from(this.tools.values()),...Array.from(this.mcpTools.values())]}getBuiltinTools(){return Array.from(this.tools.values())}getMcpTools(){return Array.from(this.mcpTools.values())}getByCategory($){let Y=this.categories.get($);if(!Y)return[];return Array.from(Y).map((Z)=>this.get(Z)).filter((Z)=>Z!==void 0)}getByTag($){let Y=this.tags.get($);if(!Y)return[];return Array.from(Y).map((Z)=>this.get(Z)).filter((Z)=>Z!==void 0)}search($){let Y=$.toLowerCase();return this.getAll().filter((Z)=>{let X=typeof Z.description==="string"?Z.description:Z.description.short;return Z.name.toLowerCase().includes(Y)||X.toLowerCase().includes(Y)||Z.displayName.toLowerCase().includes(Y)||Z.category&&Z.category.toLowerCase().includes(Y)||Z.tags.some((Q)=>Q.toLowerCase().includes(Y))})}getFunctionDeclarations(){return this.getAll().map(($)=>$.getFunctionDeclaration())}getReadOnlyFunctionDeclarations(){return this.getAll().filter(($)=>$.isReadOnly).map(($)=>$.getFunctionDeclaration())}getFunctionDeclarationsByMode($){if($==="plan")return this.getReadOnlyFunctionDeclarations();return this.getFunctionDeclarations()}getReadOnlyTools(){return this.getAll().filter(($)=>$.isReadOnly)}getCategories(){return Array.from(this.categories.keys())}getTags(){return Array.from(this.tags.keys())}getStats(){return{totalTools:this.tools.size+this.mcpTools.size,builtinTools:this.tools.size,mcpTools:this.mcpTools.size,categories:this.categories.size,tags:this.tags.size,toolsByCategory:Object.fromEntries(Array.from(this.categories.entries()).map(([$,Y])=>[$,Y.size]))}}registerMcpTool($){if(this.mcpTools.has($.name))this.mcpTools.delete($.name);this.mcpTools.set($.name,$),this.updateIndexes($),this.emit("toolRegistered",{type:"mcp",tool:$,timestamp:Date.now()})}removeMcpTools($){let Y=0,Z=`mcp__${$}__`;for(let[X,Q]of this.mcpTools.entries())if(X.startsWith(Z))this.mcpTools.delete(X),this.removeFromIndexes(Q),Y++,this.emit("toolUnregistered",{type:"mcp",toolName:X,serverName:$,timestamp:Date.now()});return Y}updateIndexes($){if($.category){if(!this.categories.has($.category))this.categories.set($.category,new Set);this.categories.get($.category).add($.name)}for(let Y of $.tags){if(!this.tags.has(Y))this.tags.set(Y,new Set);this.tags.get(Y).add($.name)}}removeFromIndexes($){if($.category){let Y=this.categories.get($.category);if(Y){if(Y.delete($.name),Y.size===0)this.categories.delete($.category)}}for(let Y of $.tags){let Z=this.tags.get(Y);if(Z){if(Z.delete($.name),Z.size===0)this.tags.delete(Y)}}}}});function kW($){return SW.some((Y)=>Y.test($))}function CW($){if($.supportsThinking!==void 0)return{supportsThinking:$.supportsThinking,thinkingBudget:$.thinkingBudget};return{supportsThinking:kW($.model),thinkingBudget:void 0}}function x$($){return CW($).supportsThinking}var SW;var C4=b(()=>{SW=[/deepseek.*r1/i,/deepseek.*reasoner/i,/o1-preview/i,/o1-mini/i,/o1/i,/qwen.*qwq/i,/qwen.*think/i,/kimi.*k1/i,/moonshot.*think/i,/k1-32k/i,/doubao.*think/i,/doubao.*pro.*think/i,/claude.*opus.*4/i]});class T7{maxSummaryLength;keyPointsLimit;recentMessagesLimit;constructor($=500,Y=10,Z=20){this.maxSummaryLength=$,this.keyPointsLimit=Y,this.recentMessagesLimit=Z}async compress($){let Y=$.layers.conversation.messages,Z=$.layers.tool.recentCalls,X=Y.filter((W)=>W.role==="system"),Q=Y.filter((W)=>W.role!=="system"),J=this.getRecentMessages(Q),q=Q.slice(0,-this.recentMessagesLimit),K=await this.generateSummary(q),G=this.extractKeyPoints(q,Z),U=this.generateToolSummary(Z),O=this.estimateTokenCount(K,G,J,U);return{summary:K,keyPoints:G,recentMessages:[...X,...J],toolSummary:U,tokenCount:O}}getRecentMessages($){return $.slice(-this.recentMessagesLimit)}async generateSummary($){if($.length===0)return"";let Y=new Set,Z=new Set,X=new Set;for(let J of $){let q=J.content.toLowerCase();["关于","讨论","问题","项目","功能","需求"].forEach((O)=>{if(q.includes(O)){let W=this.extractContext(q,O,50);if(W)Y.add(W)}}),["创建","删除","修改","更新","实现","开发"].forEach((O)=>{if(q.includes(O)){let W=this.extractContext(q,O,30);if(W)Z.add(W)}}),["决定","选择","确定","采用","使用"].forEach((O)=>{if(q.includes(O)){let W=this.extractContext(q,O,40);if(W)X.add(W)}})}let Q=`对话涉及 ${$.length} 条消息。`;if(Y.size>0)Q+=` 主要讨论:${Array.from(Y).slice(0,3).join("、")}。`;if(Z.size>0)Q+=` 执行操作:${Array.from(Z).slice(0,3).join("、")}。`;if(X.size>0)Q+=` 关键决策:${Array.from(X).slice(0,2).join("、")}。`;return Q.length>this.maxSummaryLength?Q.substring(0,this.maxSummaryLength)+"...":Q}extractKeyPoints($,Y){let Z=new Set;for(let Q of $)if(Q.role==="user")this.extractQuestions(Q.content).forEach((K)=>Z.add(`用户问题:${K}`)),this.extractRequests(Q.content).forEach((K)=>Z.add(`用户请求:${K}`));else if(Q.role==="assistant")this.extractSolutions(Q.content).forEach((q)=>Z.add(`解决方案:${q}`));return this.summarizeToolUsage(Y).forEach((Q)=>Z.add(`工具使用:${Q}`)),Array.from(Z).slice(0,this.keyPointsLimit)}generateToolSummary($){if($.length===0)return"";let Y=new Map,Z=Date.now()-600000;for(let Q of $){let J=Y.get(Q.name)||{count:0,success:0,recent:0};if(J.count++,Q.status==="success")J.success++;if(Q.timestamp>Z)J.recent++;Y.set(Q.name,J)}let X=[];for(let[Q,J]of Array.from(Y.entries())){let q=Math.round(J.success/J.count*100);X.push(`${Q}(${J.count}次,成功率${q}%)`)}return`工具调用:${X.join("、")}`}estimateTokenCount($,Y,Z,X){let Q=$.length+Y.join(" ").length;if(X)Q+=X.length;for(let J of Z)Q+=J.content.length;return Math.ceil(Q/4)}extractContext($,Y,Z){let X=$.indexOf(Y);if(X===-1)return null;let Q=Math.max(0,X-Z/2),J=Math.min($.length,X+Z/2);return $.substring(Q,J).trim()}extractQuestions($){let Y=[],Z=["?","?","如何","怎么","什么","为什么"],X=$.split(/[。!.!]/);for(let Q of X)if(Z.some((J)=>Q.includes(J))){let J=Q.trim();if(J.length>5&&J.length<100)Y.push(J)}return Y.slice(0,3)}extractRequests($){let Y=[],Z=["请","帮我","需要","想要","希望","能否"],X=$.split(/[。!.!]/);for(let Q of X)if(Z.some((J)=>Q.includes(J))){let J=Q.trim();if(J.length>5&&J.length<100)Y.push(J)}return Y.slice(0,3)}extractSolutions($){let Y=[],Z=["可以","建议","推荐","应该","最好","解决方案"],X=$.split(/[。!.!]/);for(let Q of X)if(Z.some((J)=>Q.includes(J))){let J=Q.trim();if(J.length>10&&J.length<150)Y.push(J)}return Y.slice(0,3)}summarizeToolUsage($){let Y=[],Z=$.filter((X)=>Date.now()-X.timestamp<1800000);if(Z.length>0){let X=new Map;Z.forEach((Q)=>{let J=X.get(Q.name)||[];J.push(Q),X.set(Q.name,J)});for(let[Q,J]of Array.from(X.entries())){let q=J.filter((K)=>K.status==="success").length;Y.push(`${Q}(${J.length}次,${q}成功)`)}}return Y.slice(0,5)}shouldCompress($,Y){return this.estimateCurrentTokens($)>Y*0.8}estimateCurrentTokens($){let Z=$.layers.conversation.messages.reduce((X,Q)=>X+Q.content.length,0);return Math.ceil(Z/4)}}class Y${defaultOptions;constructor($){this.defaultOptions={maxTokens:32000,maxMessages:50,timeWindow:86400000,priority:1,includeTools:!0,includeWorkspace:!0,...$}}filter($,Y){let Z={...this.defaultOptions,...Y},X={layers:{system:$.layers.system,session:$.layers.session,conversation:this.filterConversation($.layers.conversation,Z),tool:Z.includeTools?this.filterTools($.layers.tool,Z):{recentCalls:[],toolStates:{},dependencies:{}},workspace:Z.includeWorkspace?$.layers.workspace:{currentFiles:[],recentFiles:[],environment:{}}},metadata:{...$.metadata,lastUpdated:Date.now()}};return X.metadata.totalTokens=this.estimateTokens(X),X}filterConversation($,Y){let Z=[...$.messages];if(Y.timeWindow>0){let X=Date.now()-Y.timeWindow;Z=Z.filter((Q)=>Q.timestamp>=X||Q.role==="system")}if(Y.priority>1)Z=this.filterByPriority(Z,Y.priority);if(Y.maxMessages>0)Z=this.limitMessages(Z,Y.maxMessages);if(Y.maxTokens>0)Z=this.limitByTokens(Z,Y.maxTokens);return{messages:Z,summary:$.summary,topics:this.updateTopics(Z,$.topics),lastActivity:$.lastActivity}}filterTools($,Y){let Z=[...$.recentCalls];if(Y.timeWindow>0){let G=Date.now()-Y.timeWindow;Z=Z.filter((U)=>U.timestamp>=G)}let X=Z.filter((G)=>G.status==="success"),Q=Z.filter((G)=>G.status==="error"),J=Math.min(20,X.length),q=Math.min(10,Q.length);return{recentCalls:[...X.slice(-J),...Q.slice(-q)].sort((G,U)=>G.timestamp-U.timestamp),toolStates:$.toolStates,dependencies:$.dependencies}}filterByPriority($,Y){return $.filter((Z)=>{if(Z.role==="system")return!0;return this.calculateMessagePriority(Z)>=Y})}calculateMessagePriority($){let Y=1;if($.role==="system")Y+=3;else if($.role==="assistant")Y+=1;let Z=$.content.toLowerCase();if(["错误","警告","重要","关键","问题","解决"].some((J)=>Z.includes(J)))Y+=2;if(Z.includes("```")||Z.includes("function")||Z.includes("class"))Y+=1;let Q=(Date.now()-$.timestamp)/3600000;if(Q<1)Y+=2;else if(Q<6)Y+=1;return Y}limitMessages($,Y){if($.length<=Y)return $;let Z=$.filter((q)=>q.role==="system"),X=$.filter((q)=>q.role!=="system"),Q=Y-Z.length,J=Q>0?X.slice(-Q):[];return[...Z,...J].sort((q,K)=>q.timestamp-K.timestamp)}limitByTokens($,Y){if(Y<=0)return $;let Z=0,X=[];for(let Q=$.length-1;Q>=0;Q--){let J=$[Q],q=this.estimateMessageTokens(J);if(J.role==="system")if(Z+q<=Y)X.unshift(J),Z+=q;else{let K=this.compressMessage(J,Y-Z);X.unshift(K),Z+=this.estimateMessageTokens(K)}else if(Z+q<=Y)X.unshift(J),Z+=q;else break}return X.sort((Q,J)=>Q.timestamp-J.timestamp)}estimateMessageTokens($){return Math.ceil($.content.length/4)}compressMessage($,Y){let Z=Y*4;if($.content.length<=Z)return $;let X=$.content.substring(0,Z-3)+"...";return{...$,content:X,metadata:{...$.metadata,compressed:!0,originalLength:$.content.length}}}updateTopics($,Y){let Z=new Set(Y);for(let X of $)this.extractTopicsFromMessage(X).forEach((J)=>Z.add(J));return Array.from(Z).slice(0,10)}extractTopicsFromMessage($){let Y=$.content.toLowerCase(),Z=[];return["项目","功能","模块","组件","服务","接口","数据库","前端","后端","算法","架构","设计"].forEach((Q)=>{if(Y.includes(Q))Z.push(Q)}),Z}estimateTokens($){let Y=0;for(let X of $.layers.conversation.messages)Y+=this.estimateMessageTokens(X);let Z=JSON.stringify($.layers.system);if(Y+=Math.ceil(Z.length/4),$.layers.tool.recentCalls.length>0){let X=JSON.stringify($.layers.tool);Y+=Math.ceil(X.length/8)}return Y}static createPresets(){return{lightweight:new Y$({maxTokens:1000,maxMessages:10,timeWindow:7200000,includeTools:!1,includeWorkspace:!1}),standard:new Y$({maxTokens:4000,maxMessages:30,timeWindow:43200000,includeTools:!0,includeWorkspace:!0}),comprehensive:new Y$({maxTokens:8000,maxMessages:100,timeWindow:86400000,includeTools:!0,includeWorkspace:!0}),debug:new Y$({maxTokens:2000,maxMessages:20,timeWindow:21600000,priority:2,includeTools:!0,includeWorkspace:!1})}}}class S7{cache=new Map;maxSize;defaultTTL;constructor($=100,Y=300000){this.maxSize=$,this.defaultTTL=Y}set($,Y,Z){let X=Date.now(),Q={data:Y,timestamp:X,accessCount:0,lastAccess:X,ttl:Z||this.defaultTTL};if(this.cache.size>=this.maxSize&&!this.cache.has($))this.evictLeastUsed();this.cache.set($,Q)}get($){let Y=this.cache.get($);if(!Y)return null;let Z=Date.now();if(Z-Y.timestamp>Y.ttl)return this.cache.delete($),null;return Y.accessCount++,Y.lastAccess=Z,Y.data}has($){let Y=this.cache.get($);if(!Y)return!1;if(Date.now()-Y.timestamp>Y.ttl)return this.cache.delete($),!1;return!0}delete($){return this.cache.delete($)}clear(){this.cache.clear()}size(){return this.cleanExpired(),this.cache.size}cacheMessageSummary($,Y,Z){let X=`summary:${$}:${Y.length}`;this.set(X,{summary:Z,messageCount:Y.length,lastMessage:Y[Y.length-1]?.timestamp||0},600000)}getMessageSummary($,Y){let Z=`summary:${$}:${Y}`;return this.get(Z)}cacheToolResult($,Y,Z){let X=this.hashInput(Y),Q=`tool:${$}:${X}`;this.set(Q,Z,1800000)}getToolResult($,Y){let Z=this.hashInput(Y),X=`tool:${$}:${Z}`;return this.get(X)}cacheCompressedContext($,Y){let Z=`compressed:${$}`;this.set(Z,Y,900000)}getCompressedContext($){let Y=`compressed:${$}`;return this.get(Y)}getStats(){this.cleanExpired();let $=0,Y=0,Z=[];for(let[X,Q]of Array.from(this.cache.entries()))$+=Q.accessCount,Y+=this.estimateItemSize(Q),Z.push({key:X,accessCount:Q.accessCount,lastAccess:Q.lastAccess});return Z.sort((X,Q)=>Q.accessCount-X.accessCount),{size:this.cache.size,maxSize:this.maxSize,hitRate:$>0?$/($+this.cache.size):0,memoryUsage:Y,topKeys:Z.slice(0,10)}}cleanExpired(){let $=Date.now(),Y=[];for(let[Z,X]of Array.from(this.cache.entries()))if($-X.timestamp>X.ttl)Y.push(Z);Y.forEach((Z)=>this.cache.delete(Z))}evictLeastUsed(){let $=null,Y=1/0,Z=Date.now();for(let[X,Q]of Array.from(this.cache.entries())){let J=1/(Z-Q.lastAccess+1),q=Q.accessCount,K=J*q;if(K<Y)Y=K,$=X}if($)this.cache.delete($)}hashInput($){let Y=JSON.stringify($),Z=0;for(let X=0;X<Y.length;X++){let Q=Y.charCodeAt(X);Z=(Z<<5)-Z+Q,Z=Z&Z}return Math.abs(Z).toString(36)}estimateItemSize($){try{return JSON.stringify($).length*2}catch{return 1000}}setTTL($,Y){let Z=this.cache.get($);if(Z)return Z.ttl=Y,Z.timestamp=Date.now(),!0;return!1}getRemainingTTL($){let Y=this.cache.get($);if(!Y)return-1;let Z=Y.ttl-(Date.now()-Y.timestamp);return Math.max(0,Z)}warmup($){$.forEach(({key:Y,value:Z,ttl:X})=>{this.set(Y,Z,X)})}}class k7{contextData=null;maxSize;accessLog=new Map;constructor($=1000){this.maxSize=$}setContext($){this.contextData={...$},this.contextData.metadata.lastUpdated=Date.now(),this.recordAccess("context")}getContext(){if(this.contextData)this.recordAccess("context");return this.contextData}addMessage($){if(!this.contextData)throw Error("上下文数据未初始化");this.contextData.layers.conversation.messages.push($),this.contextData.layers.conversation.lastActivity=Date.now(),this.contextData.metadata.lastUpdated=Date.now(),this.enforceMemoryLimit(),this.recordAccess("messages")}getRecentMessages($=10){if(!this.contextData)return[];let Y=this.contextData.layers.conversation.messages;return this.recordAccess("messages"),Y.slice(-$)}addToolCall($){if(!this.contextData)throw Error("上下文数据未初始化");if(this.contextData.layers.tool.recentCalls.push($),this.contextData.metadata.lastUpdated=Date.now(),this.contextData.layers.tool.recentCalls.length>50)this.contextData.layers.tool.recentCalls=this.contextData.layers.tool.recentCalls.slice(-25);this.recordAccess("tools")}updateToolState($,Y){if(!this.contextData)throw Error("上下文数据未初始化");this.contextData.layers.tool.toolStates[$]=Y,this.contextData.metadata.lastUpdated=Date.now(),this.recordAccess("tools")}getToolState($){if(!this.contextData)return null;return this.recordAccess("tools"),this.contextData.layers.tool.toolStates[$]}updateWorkspace($){if(!this.contextData)throw Error("上下文数据未初始化");Object.assign(this.contextData.layers.workspace,$),this.contextData.metadata.lastUpdated=Date.now(),this.recordAccess("workspace")}clear(){this.contextData=null,this.accessLog.clear()}getMemoryInfo(){if(!this.contextData)return{hasData:!1,messageCount:0,toolCallCount:0,lastUpdated:null};return{hasData:!0,messageCount:this.contextData.layers.conversation.messages.length,toolCallCount:this.contextData.layers.tool.recentCalls.length,lastUpdated:this.contextData.metadata.lastUpdated}}recordAccess($){this.accessLog.set($,Date.now())}enforceMemoryLimit(){if(!this.contextData)return;let $=this.contextData.layers.conversation.messages;if($.length>this.maxSize){let Y=Math.floor(this.maxSize*0.8);this.contextData.layers.conversation.messages=$.slice(-Y)}}getMemoryUsage(){if(!this.contextData)return 0;return JSON.stringify(this.contextData).length}}import*as f4 from"node:fs";import{createReadStream as fW}from"node:fs";import*as H0 from"node:fs/promises";import*as C7 from"node:path";import{createInterface as hW}from"node:readline";class l0{filePath;constructor($){this.filePath=$}async append($){try{await H0.mkdir(C7.dirname(this.filePath),{recursive:!0});let Y=JSON.stringify($)+`
1250
+ `;await H0.appendFile(this.filePath,Y,"utf-8")}catch(Y){throw console.error(`[JSONLStore] 追加写入失败: ${this.filePath}`,Y),Y}}async appendBatch($){try{await H0.mkdir(C7.dirname(this.filePath),{recursive:!0});let Y=$.map((Z)=>JSON.stringify(Z)).join(`
1249
1251
  `)+`
1250
- `;await W0.appendFile(this.filePath,Y,"utf-8")}catch(Y){throw console.error(`[JSONLStore] 批量追加写入失败: ${this.filePath}`,Y),Y}}async readAll(){try{if(!k4.existsSync(this.filePath))return[];let Y=(await W0.readFile(this.filePath,"utf-8")).split(`
1251
- `).filter((X)=>X.trim().length>0),Z=[];for(let X of Y)try{Z.push(JSON.parse(X))}catch(Q){console.warn(`[JSONLStore] 解析 JSON 行失败: ${X}`,Q)}return Z}catch($){return console.error(`[JSONLStore] 读取文件失败: ${this.filePath}`,$),[]}}async readStream($){return new Promise((Y,Z)=>{if(!k4.existsSync(this.filePath)){Y();return}let X=zW(this.filePath,"utf-8"),Q=NW({input:X,crlfDelay:Number.POSITIVE_INFINITY});Q.on("line",async(J)=>{let q=J.trim();if(q.length===0)return;try{let G=JSON.parse(q);await $(G)}catch(G){console.warn(`[JSONLStore] 解析 JSON 行失败: ${q}`,G)}}),Q.on("close",()=>Y()),Q.on("error",Z),X.on("error",Z)})}async filter($){let Y=[];return await this.readStream((Z)=>{if($(Z))Y.push(Z)}),Y}async readLast($){return(await this.readAll()).slice(-$)}async getStats(){try{if(!k4.existsSync(this.filePath))return{exists:!1,size:0,lineCount:0};let $=await W0.stat(this.filePath),Z=(await W0.readFile(this.filePath,"utf-8")).split(`
1252
- `).filter((X)=>X.trim().length>0).length;return{exists:!0,size:$.size,lineCount:Z}}catch($){return console.error(`[JSONLStore] 获取统计信息失败: ${this.filePath}`,$),{exists:!1,size:0,lineCount:0}}}async exists(){try{return await W0.access(this.filePath),!0}catch{return!1}}async delete(){try{if(await this.exists())await W0.unlink(this.filePath)}catch($){throw console.error(`[JSONLStore] 删除文件失败: ${this.filePath}`,$),$}}getFilePath(){return this.filePath}}var kZ=()=>{};import{nanoid as f$}from"nanoid";import*as B2 from"node:fs/promises";import*as SZ from"node:path";class j7{projectPath;maxSessions;version;constructor($=process.cwd(),Y=100,Z="0.0.10"){this.projectPath=$,this.maxSessions=Y,this.version=Z}async initialize(){try{let $=N6(this.projectPath);await B2.mkdir($,{recursive:!0}),console.log(`[PersistentStore] 初始化存储目录: ${$}`)}catch($){console.warn("[PersistentStore] 无法创建持久化存储目录:",$)}}async saveMessage($,Y,Z,X=null,Q){try{let J=R0(this.projectPath,$),q=new m0(J),G={uuid:f$(),parentUuid:X,sessionId:$,timestamp:new Date().toISOString(),type:Y==="user"?"user":Y==="assistant"?"assistant":Y==="tool"?"tool_result":"system",cwd:this.projectPath,gitBranch:y$(this.projectPath),version:this.version,message:{role:Y,content:Z,...Q||{}}};return await q.append(G),G.uuid}catch(J){throw console.error(`[PersistentStore] 保存消息失败 (session: ${$}):`,J),J}}async saveToolUse($,Y,Z,X=null){try{let Q=R0(this.projectPath,$),J=new m0(Q),q={uuid:f$(),parentUuid:X,sessionId:$,timestamp:new Date().toISOString(),type:"tool_use",cwd:this.projectPath,gitBranch:y$(this.projectPath),version:this.version,message:{role:"assistant",content:""},tool:{id:f$(),name:Y,input:Z}};return await J.append(q),q.uuid}catch(Q){throw console.error(`[PersistentStore] 保存工具调用失败 (session: ${$}):`,Q),Q}}async saveToolResult($,Y,Z,X=null,Q){try{let J=R0(this.projectPath,$),q=new m0(J),G={uuid:f$(),parentUuid:X,sessionId:$,timestamp:new Date().toISOString(),type:"tool_result",cwd:this.projectPath,gitBranch:y$(this.projectPath),version:this.version,message:{role:"assistant",content:""},toolResult:{id:Y,output:Z,error:Q}};return await q.append(G),G.uuid}catch(J){throw console.error(`[PersistentStore] 保存工具结果失败 (session: ${$}):`,J),J}}async saveCompaction($,Y,Z,X=null){try{let Q=R0(this.projectPath,$),J=new m0(Q),q={uuid:f$(),parentUuid:X,sessionId:$,timestamp:new Date().toISOString(),type:"system",subtype:"compact_boundary",cwd:this.projectPath,gitBranch:y$(this.projectPath),version:this.version,message:{role:"system",content:"=== 上下文压缩边界 ==="},compactMetadata:Z};await J.append(q),console.log("[PersistentStore] 保存压缩边界标记");let G={uuid:f$(),parentUuid:q.uuid,logicalParentUuid:X??void 0,sessionId:$,timestamp:new Date().toISOString(),type:"user",isCompactSummary:!0,cwd:this.projectPath,gitBranch:y$(this.projectPath),version:this.version,message:{role:"user",content:Y},compactMetadata:Z};return await J.append(G),console.log("[PersistentStore] 保存压缩总结消息"),G.uuid}catch(Q){throw console.error(`[PersistentStore] 保存压缩失败 (session: ${$}):`,Q),Q}}async saveContext($,Y){try{let{conversation:Z}=Y.layers;for(let X of Z.messages)await this.saveMessage($,X.role,X.content,null)}catch(Z){console.warn(`[PersistentStore] 保存上下文失败 (session: ${$}):`,Z)}}async saveSession($,Y){console.warn("[PersistentStore] saveSession 方法已废弃,请使用 saveMessage")}async saveConversation($,Y){console.warn("[PersistentStore] saveConversation 方法已废弃,请使用 saveMessage")}async loadSession($){try{let Y=R0(this.projectPath,$),X=await new m0(Y).readAll();if(X.length===0)return null;let Q=X[0];return{sessionId:$,userId:void 0,preferences:{},configuration:{},startTime:new Date(Q.timestamp).getTime()}}catch{return null}}async loadConversation($){try{let Y=R0(this.projectPath,$),X=await new m0(Y).readAll();if(X.length===0)return null;let Q=X.filter((G)=>["user","assistant","system"].includes(G.type)).map((G)=>({id:G.uuid,role:G.message.role,content:G.message.content,timestamp:new Date(G.timestamp).getTime()})),J=X[X.length-1],q=new Date(J.timestamp).getTime();return{messages:Q,topics:[],lastActivity:q}}catch{return null}}async listSessions(){try{let $=N6(this.projectPath);return(await B2.readdir($)).filter((Z)=>Z.endsWith(".jsonl")).map((Z)=>Z.replace(".jsonl","")).sort()}catch{return[]}}async getSessionSummary($){try{let Y=R0(this.projectPath,$),Z=new m0(Y);if(!(await Z.getStats()).exists)return null;let Q=await Z.readAll();if(Q.length===0)return null;let J=Q[Q.length-1];return{sessionId:$,lastActivity:new Date(J.timestamp).getTime(),messageCount:Q.filter((q)=>["user","assistant"].includes(q.type)).length,topics:[]}}catch{return null}}async deleteSession($){try{let Y=R0(this.projectPath,$);await new m0(Y).delete()}catch(Y){console.warn(`[PersistentStore] 删除会话失败 (session: ${$}):`,Y)}}async cleanupOldSessions(){try{let $=await this.listSessions();if($.length<=this.maxSessions)return;let X=(await Promise.all($.map((Q)=>this.getSessionSummary(Q)))).filter((Q)=>Q!==null).sort((Q,J)=>J.lastActivity-Q.lastActivity).slice(this.maxSessions).map((Q)=>Q.sessionId);await Promise.all(X.map((Q)=>this.deleteSession(Q))),console.log(`[PersistentStore] 已清理 ${X.length} 个旧会话`)}catch($){console.error("[PersistentStore] 清理旧会话失败:",$)}}async getStorageStats(){try{let $=await this.listSessions(),Y=0;for(let Z of $){let X=R0(this.projectPath,Z),J=await new m0(X).getStats();Y+=J.size}return{totalSessions:$.length,totalSize:Y,projectPath:this.projectPath}}catch{return{totalSessions:0,totalSize:0,projectPath:this.projectPath}}}async checkStorageHealth(){try{let $=N6(this.projectPath);await B2.mkdir($,{recursive:!0});let Y=SZ.join($,".health-check");return await B2.writeFile(Y,"test","utf-8"),await B2.unlink(Y),{isAvailable:!0,canWrite:!0}}catch($){return{isAvailable:!1,canWrite:!1,error:$ instanceof Error?$.message:String($)}}}static async listAllProjects(){return _Y()}}var CZ=b(()=>{kZ();B6()});import*as hZ from"crypto";import{nanoid as fZ}from"nanoid";class b6{memory;persistent;cache;compressor;filter;options;currentSessionId=null;initialized=!1;constructor($={}){let Y=$.storage?.persistentPath||o2();this.options={storage:{maxMemorySize:1000,persistentPath:Y,cacheSize:100,compressionEnabled:!0,...$.storage},defaultFilter:{maxTokens:32000,maxMessages:50,timeWindow:86400000,...$.defaultFilter},compressionThreshold:$.compressionThreshold||6000,enableVectorSearch:$.enableVectorSearch||!1},this.memory=new I7(this.options.storage.maxMemorySize),this.persistent=new j7(process.cwd(),100),this.cache=new D7(this.options.storage.cacheSize,300000),this.compressor=new V7,this.filter=new t2(this.options.defaultFilter)}async initialize(){if(this.initialized)return;try{if(await this.persistent.initialize(),!(await this.persistent.checkStorageHealth()).isAvailable)console.warn("警告:持久化存储不可用,将仅使用内存存储");this.initialized=!0,console.log("上下文管理器初始化完成")}catch($){throw console.error("上下文管理器初始化失败:",$),$}}async createSession($,Y={},Z={}){let X=Z.sessionId||this.generateSessionId(),Q=Date.now(),J={layers:{system:await this.createSystemContext(),session:{sessionId:X,userId:$,preferences:Y,configuration:Z,startTime:Q},conversation:{messages:[],topics:[],lastActivity:Q},tool:{recentCalls:[],toolStates:{},dependencies:{}},workspace:await this.createWorkspaceContext()},metadata:{totalTokens:0,priority:1,lastUpdated:Q}};return this.memory.setContext(J),await this.persistent.saveContext(X,J),this.currentSessionId=X,console.log(`新会话已创建: ${X}`),X}async loadSession($){try{let Y=this.memory.getContext();if(!Y||Y.layers.session.sessionId!==$){let[Z,X]=await Promise.all([this.persistent.loadSession($),this.persistent.loadConversation($)]);if(!Z||!X)return!1;Y={layers:{system:await this.createSystemContext(),session:Z,conversation:X,tool:{recentCalls:[],toolStates:{},dependencies:{}},workspace:await this.createWorkspaceContext()},metadata:{totalTokens:0,priority:1,lastUpdated:Date.now()}},this.memory.setContext(Y)}return this.currentSessionId=$,console.log(`会话已加载: ${$}`),!0}catch(Y){return console.error("加载会话失败:",Y),!1}}async addMessage($,Y,Z){if(!this.currentSessionId)throw Error("没有活动会话");let X={id:this.generateMessageId(),role:$,content:Y,timestamp:Date.now(),metadata:Z};this.memory.addMessage(X);let Q=this.memory.getContext();if(Q&&this.shouldCompress(Q))await this.compressCurrentContext();this.saveCurrentSessionAsync()}async addToolCall($){if(!this.currentSessionId)throw Error("没有活动会话");if(this.memory.addToolCall($),$.status==="success"&&$.output)this.cache.cacheToolResult($.name,$.input,$.output);this.saveCurrentSessionAsync()}async saveMessage($,Y,Z,X=null,Q){return this.persistent.saveMessage($,Y,Z,X,Q)}async saveToolUse($,Y,Z,X=null){return this.persistent.saveToolUse($,Y,Z,X)}async saveToolResult($,Y,Z,X=null,Q){return this.persistent.saveToolResult($,Y,Z,X,Q)}async saveCompaction($,Y,Z,X=null){return this.persistent.saveCompaction($,Y,Z,X)}updateToolState($,Y){if(!this.currentSessionId)throw Error("没有活动会话");this.memory.updateToolState($,Y)}updateWorkspace($){if(!this.currentSessionId)throw Error("没有活动会话");this.memory.updateWorkspace($)}async getFormattedContext($){let Y=this.memory.getContext();if(!Y)throw Error("没有可用的上下文数据");let Z=this.filter.filter(Y,$),X=this.shouldCompress(Z),Q;if(X){let J=this.hashContext(Z);if(Q=this.cache.getCompressedContext(J),!Q)Q=await this.compressor.compress(Z),this.cache.cacheCompressedContext(J,Q)}return{context:Z,compressed:Q,tokenCount:Q?Q.tokenCount:Z.metadata.totalTokens}}async searchSessions($,Y=10){let Z=await this.persistent.listSessions(),X=[];for(let Q of Z){let J=await this.persistent.getSessionSummary(Q);if(J){let q=this.calculateRelevance($,J.topics);if(q>0)X.push({sessionId:Q,summary:`${J.messageCount}条消息,主题:${J.topics.join("、")}`,lastActivity:J.lastActivity,relevanceScore:q})}}return X.sort((Q,J)=>J.relevanceScore-Q.relevanceScore).slice(0,Y)}getCachedToolResult($,Y){return this.cache.getToolResult($,Y)}async getStats(){let[$,Y,Z]=await Promise.all([Promise.resolve(this.memory.getMemoryInfo()),Promise.resolve(this.cache.getStats()),this.persistent.getStorageStats()]);return{currentSession:this.currentSessionId,memory:$,cache:Y,storage:Z}}async cleanup(){if(this.currentSessionId)await this.saveCurrentSession();this.memory.clear(),this.cache.clear(),await this.persistent.cleanupOldSessions(),this.currentSessionId=null,console.log("上下文管理器资源清理完成")}generateSessionId(){return fZ()}generateMessageId(){return fZ()}async createSystemContext(){return{role:"AI助手",capabilities:["对话","工具调用","代码生成","文档分析"],tools:["文件操作","Git操作","代码分析"],version:"1.0.0"}}async createWorkspaceContext(){try{let $=process.cwd();return{projectPath:$,currentFiles:[],recentFiles:[],environment:{nodeVersion:process.version,platform:process.platform,cwd:$}}}catch($){return{currentFiles:[],recentFiles:[],environment:{}}}}shouldCompress($){return $.metadata.totalTokens>this.options.compressionThreshold}async compressCurrentContext(){let $=this.memory.getContext();if(!$)return;let Y=await this.compressor.compress($);$.layers.conversation.summary=Y.summary,this.memory.setContext($)}async saveCurrentSession(){if(!this.currentSessionId)return;let $=this.memory.getContext();if($)await this.persistent.saveContext(this.currentSessionId,$)}saveCurrentSessionAsync(){this.saveCurrentSession().catch(($)=>{console.warn("异步保存会话失败:",$)})}hashContext($){let Y=JSON.stringify({messageCount:$.layers.conversation.messages.length,lastMessage:$.layers.conversation.messages[$.layers.conversation.messages.length-1]?.id,toolCallCount:$.layers.tool.recentCalls.length});return hZ.createHash("md5").update(Y).digest("hex")}calculateRelevance($,Y){let Z=$.toLowerCase(),X=0;for(let Q of Y)if(Z.includes(Q.toLowerCase())||Q.toLowerCase().includes(Z))X+=1;return X}}var y7=b(()=>{CZ();B6()});class v7{chatService;contextManager;memoryAdapter;constructor($,Y){this.chatService=$,this.contextManager=Y||new b6,this.memoryAdapter=this.createMemoryAdapter()}createMemoryAdapter(){let $=[];return{getMessages:()=>[...$],addMessage:(Y)=>{$.push(Y)},clearContext:()=>{$.length=0},getContextSize:()=>$.length}}getContextManager(){return this.contextManager}getMemoryAdapter(){return this.memoryAdapter}async executeSimpleTask($){let Y=[{role:"user",content:$.prompt}],Z=await this.chatService.chat(Y);return{taskId:$.id,content:Z.content,metadata:{executionMode:"simple",taskType:$.type}}}async executeParallelTask($){let Y=this.decomposeTask($),Z=await Promise.all(Y.map(async(Q)=>{try{return{success:!0,result:await this.executeSimpleTask(Q)}}catch(J){return{success:!1,error:J instanceof Error?J.message:"执行失败",taskId:Q.id}}})),X=this.combineSubTaskResults(Z);return{taskId:$.id,content:X,metadata:{executionMode:"parallel",taskType:$.type,subTaskCount:Y.length,failedSubTasks:Z.filter((Q)=>!Q.success).length}}}async executeSteeringTask($){let Y=await this.generateExecutionSteps($),Z="",X={};for(let Q=0;Q<Y.length;Q++){let J=Y[Q];try{let q=await this.executeStep(J,$);Z+=q.content+`
1252
+ `;await H0.appendFile(this.filePath,Y,"utf-8")}catch(Y){throw console.error(`[JSONLStore] 批量追加写入失败: ${this.filePath}`,Y),Y}}async readAll(){try{if(!f4.existsSync(this.filePath))return[];let Y=(await H0.readFile(this.filePath,"utf-8")).split(`
1253
+ `).filter((X)=>X.trim().length>0),Z=[];for(let X of Y)try{Z.push(JSON.parse(X))}catch(Q){console.warn(`[JSONLStore] 解析 JSON 行失败: ${X}`,Q)}return Z}catch($){return console.error(`[JSONLStore] 读取文件失败: ${this.filePath}`,$),[]}}async readStream($){return new Promise((Y,Z)=>{if(!f4.existsSync(this.filePath)){Y();return}let X=fW(this.filePath,"utf-8"),Q=hW({input:X,crlfDelay:Number.POSITIVE_INFINITY});Q.on("line",async(J)=>{let q=J.trim();if(q.length===0)return;try{let K=JSON.parse(q);await $(K)}catch(K){console.warn(`[JSONLStore] 解析 JSON 行失败: ${q}`,K)}}),Q.on("close",()=>Y()),Q.on("error",Z),X.on("error",Z)})}async filter($){let Y=[];return await this.readStream((Z)=>{if($(Z))Y.push(Z)}),Y}async readLast($){return(await this.readAll()).slice(-$)}async getStats(){try{if(!f4.existsSync(this.filePath))return{exists:!1,size:0,lineCount:0};let $=await H0.stat(this.filePath),Z=(await H0.readFile(this.filePath,"utf-8")).split(`
1254
+ `).filter((X)=>X.trim().length>0).length;return{exists:!0,size:$.size,lineCount:Z}}catch($){return console.error(`[JSONLStore] 获取统计信息失败: ${this.filePath}`,$),{exists:!1,size:0,lineCount:0}}}async exists(){try{return await H0.access(this.filePath),!0}catch{return!1}}async delete(){try{if(await this.exists())await H0.unlink(this.filePath)}catch($){throw console.error(`[JSONLStore] 删除文件失败: ${this.filePath}`,$),$}}getFilePath(){return this.filePath}}var sZ=()=>{};import{nanoid as p$}from"nanoid";import*as A2 from"node:fs/promises";import*as tZ from"node:path";class f7{projectPath;maxSessions;version;constructor($=process.cwd(),Y=100,Z="0.0.10"){this.projectPath=$,this.maxSessions=Y,this.version=Z}async initialize(){try{let $=w6(this.projectPath);await A2.mkdir($,{recursive:!0}),console.log(`[PersistentStore] 初始化存储目录: ${$}`)}catch($){console.warn("[PersistentStore] 无法创建持久化存储目录:",$)}}async saveMessage($,Y,Z,X=null,Q){try{let J=I0(this.projectPath,$),q=new l0(J),K={uuid:p$(),parentUuid:X,sessionId:$,timestamp:new Date().toISOString(),type:Y==="user"?"user":Y==="assistant"?"assistant":Y==="tool"?"tool_result":"system",cwd:this.projectPath,gitBranch:P$(this.projectPath),version:this.version,message:{role:Y,content:Z,...Q||{}}};return await q.append(K),K.uuid}catch(J){throw console.error(`[PersistentStore] 保存消息失败 (session: ${$}):`,J),J}}async saveToolUse($,Y,Z,X=null){try{let Q=I0(this.projectPath,$),J=new l0(Q),q={uuid:p$(),parentUuid:X,sessionId:$,timestamp:new Date().toISOString(),type:"tool_use",cwd:this.projectPath,gitBranch:P$(this.projectPath),version:this.version,message:{role:"assistant",content:""},tool:{id:p$(),name:Y,input:Z}};return await J.append(q),q.uuid}catch(Q){throw console.error(`[PersistentStore] 保存工具调用失败 (session: ${$}):`,Q),Q}}async saveToolResult($,Y,Z,X=null,Q){try{let J=I0(this.projectPath,$),q=new l0(J),K={uuid:p$(),parentUuid:X,sessionId:$,timestamp:new Date().toISOString(),type:"tool_result",cwd:this.projectPath,gitBranch:P$(this.projectPath),version:this.version,message:{role:"assistant",content:""},toolResult:{id:Y,output:Z,error:Q}};return await q.append(K),K.uuid}catch(J){throw console.error(`[PersistentStore] 保存工具结果失败 (session: ${$}):`,J),J}}async saveCompaction($,Y,Z,X=null){try{let Q=I0(this.projectPath,$),J=new l0(Q),q={uuid:p$(),parentUuid:X,sessionId:$,timestamp:new Date().toISOString(),type:"system",subtype:"compact_boundary",cwd:this.projectPath,gitBranch:P$(this.projectPath),version:this.version,message:{role:"system",content:"=== 上下文压缩边界 ==="},compactMetadata:Z};await J.append(q),console.log("[PersistentStore] 保存压缩边界标记");let K={uuid:p$(),parentUuid:q.uuid,logicalParentUuid:X??void 0,sessionId:$,timestamp:new Date().toISOString(),type:"user",isCompactSummary:!0,cwd:this.projectPath,gitBranch:P$(this.projectPath),version:this.version,message:{role:"user",content:Y},compactMetadata:Z};return await J.append(K),console.log("[PersistentStore] 保存压缩总结消息"),K.uuid}catch(Q){throw console.error(`[PersistentStore] 保存压缩失败 (session: ${$}):`,Q),Q}}async saveContext($,Y){try{let{conversation:Z}=Y.layers;for(let X of Z.messages)await this.saveMessage($,X.role,X.content,null)}catch(Z){console.warn(`[PersistentStore] 保存上下文失败 (session: ${$}):`,Z)}}async saveSession($,Y){console.warn("[PersistentStore] saveSession 方法已废弃,请使用 saveMessage")}async saveConversation($,Y){console.warn("[PersistentStore] saveConversation 方法已废弃,请使用 saveMessage")}async loadSession($){try{let Y=I0(this.projectPath,$),X=await new l0(Y).readAll();if(X.length===0)return null;let Q=X[0];return{sessionId:$,userId:void 0,preferences:{},configuration:{},startTime:new Date(Q.timestamp).getTime()}}catch{return null}}async loadConversation($){try{let Y=I0(this.projectPath,$),X=await new l0(Y).readAll();if(X.length===0)return null;let Q=X.filter((K)=>["user","assistant","system"].includes(K.type)).map((K)=>({id:K.uuid,role:K.message.role,content:K.message.content,timestamp:new Date(K.timestamp).getTime()})),J=X[X.length-1],q=new Date(J.timestamp).getTime();return{messages:Q,topics:[],lastActivity:q}}catch{return null}}async listSessions(){try{let $=w6(this.projectPath);return(await A2.readdir($)).filter((Z)=>Z.endsWith(".jsonl")).map((Z)=>Z.replace(".jsonl","")).sort()}catch{return[]}}async getSessionSummary($){try{let Y=I0(this.projectPath,$),Z=new l0(Y);if(!(await Z.getStats()).exists)return null;let Q=await Z.readAll();if(Q.length===0)return null;let J=Q[Q.length-1];return{sessionId:$,lastActivity:new Date(J.timestamp).getTime(),messageCount:Q.filter((q)=>["user","assistant"].includes(q.type)).length,topics:[]}}catch{return null}}async deleteSession($){try{let Y=I0(this.projectPath,$);await new l0(Y).delete()}catch(Y){console.warn(`[PersistentStore] 删除会话失败 (session: ${$}):`,Y)}}async cleanupOldSessions(){try{let $=await this.listSessions();if($.length<=this.maxSessions)return;let X=(await Promise.all($.map((Q)=>this.getSessionSummary(Q)))).filter((Q)=>Q!==null).sort((Q,J)=>J.lastActivity-Q.lastActivity).slice(this.maxSessions).map((Q)=>Q.sessionId);await Promise.all(X.map((Q)=>this.deleteSession(Q))),console.log(`[PersistentStore] 已清理 ${X.length} 个旧会话`)}catch($){console.error("[PersistentStore] 清理旧会话失败:",$)}}async getStorageStats(){try{let $=await this.listSessions(),Y=0;for(let Z of $){let X=I0(this.projectPath,Z),J=await new l0(X).getStats();Y+=J.size}return{totalSessions:$.length,totalSize:Y,projectPath:this.projectPath}}catch{return{totalSessions:0,totalSize:0,projectPath:this.projectPath}}}async checkStorageHealth(){try{let $=w6(this.projectPath);await A2.mkdir($,{recursive:!0});let Y=tZ.join($,".health-check");return await A2.writeFile(Y,"test","utf-8"),await A2.unlink(Y),{isAvailable:!0,canWrite:!0}}catch($){return{isAvailable:!1,canWrite:!1,error:$ instanceof Error?$.message:String($)}}}static async listAllProjects(){return TY()}}var eZ=b(()=>{sZ();A6()});import*as YX from"crypto";import{nanoid as $X}from"nanoid";class D6{memory;persistent;cache;compressor;filter;options;currentSessionId=null;initialized=!1;constructor($={}){let Y=$.storage?.persistentPath||e2();this.options={storage:{maxMemorySize:1000,persistentPath:Y,cacheSize:100,compressionEnabled:!0,...$.storage},defaultFilter:{maxTokens:32000,maxMessages:50,timeWindow:86400000,...$.defaultFilter},compressionThreshold:$.compressionThreshold||6000,enableVectorSearch:$.enableVectorSearch||!1},this.memory=new k7(this.options.storage.maxMemorySize),this.persistent=new f7(process.cwd(),100),this.cache=new S7(this.options.storage.cacheSize,300000),this.compressor=new T7,this.filter=new Y$(this.options.defaultFilter)}async initialize(){if(this.initialized)return;try{if(await this.persistent.initialize(),!(await this.persistent.checkStorageHealth()).isAvailable)console.warn("警告:持久化存储不可用,将仅使用内存存储");this.initialized=!0,console.log("上下文管理器初始化完成")}catch($){throw console.error("上下文管理器初始化失败:",$),$}}async createSession($,Y={},Z={}){let X=Z.sessionId||this.generateSessionId(),Q=Date.now(),J={layers:{system:await this.createSystemContext(),session:{sessionId:X,userId:$,preferences:Y,configuration:Z,startTime:Q},conversation:{messages:[],topics:[],lastActivity:Q},tool:{recentCalls:[],toolStates:{},dependencies:{}},workspace:await this.createWorkspaceContext()},metadata:{totalTokens:0,priority:1,lastUpdated:Q}};return this.memory.setContext(J),await this.persistent.saveContext(X,J),this.currentSessionId=X,console.log(`新会话已创建: ${X}`),X}async loadSession($){try{let Y=this.memory.getContext();if(!Y||Y.layers.session.sessionId!==$){let[Z,X]=await Promise.all([this.persistent.loadSession($),this.persistent.loadConversation($)]);if(!Z||!X)return!1;Y={layers:{system:await this.createSystemContext(),session:Z,conversation:X,tool:{recentCalls:[],toolStates:{},dependencies:{}},workspace:await this.createWorkspaceContext()},metadata:{totalTokens:0,priority:1,lastUpdated:Date.now()}},this.memory.setContext(Y)}return this.currentSessionId=$,console.log(`会话已加载: ${$}`),!0}catch(Y){return console.error("加载会话失败:",Y),!1}}async addMessage($,Y,Z){if(!this.currentSessionId)throw Error("没有活动会话");let X={id:this.generateMessageId(),role:$,content:Y,timestamp:Date.now(),metadata:Z};this.memory.addMessage(X);let Q=this.memory.getContext();if(Q&&this.shouldCompress(Q))await this.compressCurrentContext();this.saveCurrentSessionAsync()}async addToolCall($){if(!this.currentSessionId)throw Error("没有活动会话");if(this.memory.addToolCall($),$.status==="success"&&$.output)this.cache.cacheToolResult($.name,$.input,$.output);this.saveCurrentSessionAsync()}async saveMessage($,Y,Z,X=null,Q){return this.persistent.saveMessage($,Y,Z,X,Q)}async saveToolUse($,Y,Z,X=null){return this.persistent.saveToolUse($,Y,Z,X)}async saveToolResult($,Y,Z,X=null,Q){return this.persistent.saveToolResult($,Y,Z,X,Q)}async saveCompaction($,Y,Z,X=null){return this.persistent.saveCompaction($,Y,Z,X)}updateToolState($,Y){if(!this.currentSessionId)throw Error("没有活动会话");this.memory.updateToolState($,Y)}updateWorkspace($){if(!this.currentSessionId)throw Error("没有活动会话");this.memory.updateWorkspace($)}async getFormattedContext($){let Y=this.memory.getContext();if(!Y)throw Error("没有可用的上下文数据");let Z=this.filter.filter(Y,$),X=this.shouldCompress(Z),Q;if(X){let J=this.hashContext(Z);if(Q=this.cache.getCompressedContext(J),!Q)Q=await this.compressor.compress(Z),this.cache.cacheCompressedContext(J,Q)}return{context:Z,compressed:Q,tokenCount:Q?Q.tokenCount:Z.metadata.totalTokens}}async searchSessions($,Y=10){let Z=await this.persistent.listSessions(),X=[];for(let Q of Z){let J=await this.persistent.getSessionSummary(Q);if(J){let q=this.calculateRelevance($,J.topics);if(q>0)X.push({sessionId:Q,summary:`${J.messageCount}条消息,主题:${J.topics.join("、")}`,lastActivity:J.lastActivity,relevanceScore:q})}}return X.sort((Q,J)=>J.relevanceScore-Q.relevanceScore).slice(0,Y)}getCachedToolResult($,Y){return this.cache.getToolResult($,Y)}async getStats(){let[$,Y,Z]=await Promise.all([Promise.resolve(this.memory.getMemoryInfo()),Promise.resolve(this.cache.getStats()),this.persistent.getStorageStats()]);return{currentSession:this.currentSessionId,memory:$,cache:Y,storage:Z}}async cleanup(){if(this.currentSessionId)await this.saveCurrentSession();this.memory.clear(),this.cache.clear(),await this.persistent.cleanupOldSessions(),this.currentSessionId=null,console.log("上下文管理器资源清理完成")}generateSessionId(){return $X()}generateMessageId(){return $X()}async createSystemContext(){return{role:"AI助手",capabilities:["对话","工具调用","代码生成","文档分析"],tools:["文件操作","Git操作","代码分析"],version:"1.0.0"}}async createWorkspaceContext(){try{let $=process.cwd();return{projectPath:$,currentFiles:[],recentFiles:[],environment:{nodeVersion:process.version,platform:process.platform,cwd:$}}}catch($){return{currentFiles:[],recentFiles:[],environment:{}}}}shouldCompress($){return $.metadata.totalTokens>this.options.compressionThreshold}async compressCurrentContext(){let $=this.memory.getContext();if(!$)return;let Y=await this.compressor.compress($);$.layers.conversation.summary=Y.summary,this.memory.setContext($)}async saveCurrentSession(){if(!this.currentSessionId)return;let $=this.memory.getContext();if($)await this.persistent.saveContext(this.currentSessionId,$)}saveCurrentSessionAsync(){this.saveCurrentSession().catch(($)=>{console.warn("异步保存会话失败:",$)})}hashContext($){let Y=JSON.stringify({messageCount:$.layers.conversation.messages.length,lastMessage:$.layers.conversation.messages[$.layers.conversation.messages.length-1]?.id,toolCallCount:$.layers.tool.recentCalls.length});return YX.createHash("md5").update(Y).digest("hex")}calculateRelevance($,Y){let Z=$.toLowerCase(),X=0;for(let Q of Y)if(Z.includes(Q.toLowerCase())||Q.toLowerCase().includes(Z))X+=1;return X}}var h7=b(()=>{eZ();A6()});class x7{chatService;contextManager;memoryAdapter;constructor($,Y){this.chatService=$,this.contextManager=Y||new D6,this.memoryAdapter=this.createMemoryAdapter()}createMemoryAdapter(){let $=[];return{getMessages:()=>[...$],addMessage:(Y)=>{$.push(Y)},clearContext:()=>{$.length=0},getContextSize:()=>$.length}}getContextManager(){return this.contextManager}getMemoryAdapter(){return this.memoryAdapter}async executeSimpleTask($){let Y=[{role:"user",content:$.prompt}],Z=await this.chatService.chat(Y);return{taskId:$.id,content:Z.content,metadata:{executionMode:"simple",taskType:$.type}}}async executeParallelTask($){let Y=this.decomposeTask($),Z=await Promise.all(Y.map(async(Q)=>{try{return{success:!0,result:await this.executeSimpleTask(Q)}}catch(J){return{success:!1,error:J instanceof Error?J.message:"执行失败",taskId:Q.id}}})),X=this.combineSubTaskResults(Z);return{taskId:$.id,content:X,metadata:{executionMode:"parallel",taskType:$.type,subTaskCount:Y.length,failedSubTasks:Z.filter((Q)=>!Q.success).length}}}async executeSteeringTask($){let Y=await this.generateExecutionSteps($),Z="",X={};for(let Q=0;Q<Y.length;Q++){let J=Y[Q];try{let q=await this.executeStep(J,$);Z+=q.content+`
1253
1255
 
1254
1256
  `,X[`step_${Q}_type`]=J.type,X[`step_${Q}_result`]=q}catch(q){throw Error(`步骤 ${J.id} 执行失败: ${q instanceof Error?q.message:"未知错误"}`)}}return{taskId:$.id,content:Z.trim(),metadata:{executionMode:"steering",taskType:$.type,steps:Y.length,...X}}}decomposeTask($){return[{...$,id:`${$.id}_sub1`,prompt:`${$.prompt} (子任务1: 分析和规划)`},{...$,id:`${$.id}_sub2`,prompt:`${$.prompt} (子任务2: 执行和验证)`}]}async generateExecutionSteps($){return[{id:`${$.id}_step1`,type:"llm",description:"理解任务要求和约束",status:"pending"},{id:`${$.id}_step2`,type:"tool",description:"准备执行环境和工具",status:"pending"},{id:`${$.id}_step3`,type:"llm",description:"执行任务并生成结果",status:"pending"}]}async executeStep($,Y){switch($.type){case"llm":return this.executeLlmStep($,Y);case"tool":return this.executeToolStep($,Y);default:throw Error(`未知的步骤类型: ${$.type}`)}}async executeLlmStep($,Y){let Z=`Step: ${$.description}
1255
1257
  Task: ${Y.prompt}`;return{content:(await this.chatService.chat([{role:"user",content:Z}])).content,stepId:$.id}}async executeToolStep($,Y){return{content:`Tool step completed: ${$.description}`,stepId:$.id}}combineSubTaskResults($){return $.filter((Y)=>Y.success).map((Y)=>Y.result?.content||Y.content||"").join(`
1256
1258
 
1257
- `)}}var xZ=b(()=>{y7()});import*as pZ from"os";import*as gZ from"path";class m1{config;runtimeOptions;isInitialized=!1;activeTask;executionPipeline;systemPrompt;chatService;executionEngine;attachmentCollector;activeSkillContext;constructor($,Y={},Z){this.config=$,this.runtimeOptions=Y,this.executionPipeline=Z||this.createDefaultPipeline()}createDefaultPipeline(){let $=new R7,Y={...this.config.permissions,...this.runtimeOptions.permissions},Z=this.runtimeOptions.permissionMode??this.config.permissionMode??"default";return new b7($,{permissionConfig:Y,permissionMode:Z,maxHistorySize:1000})}static async create($={}){if(await o6(),K6().length===0)throw Error(`❌ 没有可用的模型配置
1259
+ `)}}var ZX=b(()=>{h7()});import*as XX from"os";import*as QX from"path";class l1{config;runtimeOptions;isInitialized=!1;activeTask;executionPipeline;systemPrompt;chatService;executionEngine;attachmentCollector;activeSkillContext;constructor($,Y={},Z){this.config=$,this.runtimeOptions=Y,this.executionPipeline=Z||this.createDefaultPipeline()}createDefaultPipeline(){let $=new P7,Y={...this.config.permissions,...this.runtimeOptions.permissions},Z=this.runtimeOptions.permissionMode??this.config.permissionMode??"default";return new v7($,{permissionConfig:Y,permissionMode:Z,maxHistorySize:1000})}static async create($={}){if(await e6(),O6().length===0)throw Error(`❌ 没有可用的模型配置
1258
1260
 
1259
1261
  `+`请先使用以下命令添加模型:
1260
1262
  `+` /model add
1261
1263
 
1262
1264
  `+`或运行初始化向导:
1263
- `+" /init");let Z=C1();if(!Z)throw Error("❌ 配置未初始化,请确保应用已正确启动");G0.getInstance().validateConfig(Z);let Q=new m1(Z,$);if(await Q.initialize(),$.toolWhitelist&&$.toolWhitelist.length>0)Q.applyToolWhitelist($.toolWhitelist);return Q}async initialize(){if(this.isInitialized)return;try{this.log("初始化Agent..."),await this.initializeSystemPrompt(),await this.registerBuiltinTools(),await this.loadSubagents(),await this.discoverSkills();let $=N$();if(!$)throw Error("❌ 当前模型配置未找到");this.log(`\uD83D\uDE80 使用模型: ${$.name} (${$.model})`);let Y=C$($);if(Y)this.log("\uD83E\uDDE0 检测到 Thinking 模型,启用 reasoning_content 支持");this.chatService=Q4({provider:$.provider,apiKey:$.apiKey,model:$.model,baseUrl:$.baseUrl,temperature:$.temperature??this.config.temperature,maxContextTokens:$.maxContextTokens??this.config.maxContextTokens,maxOutputTokens:$.maxOutputTokens??this.config.maxOutputTokens,timeout:this.config.timeout,supportsThinking:Y}),this.executionEngine=new v7(this.chatService),this.attachmentCollector=new A8({cwd:process.cwd(),maxFileSize:1048576,maxLines:2000,maxTokens:32000}),this.isInitialized=!0,this.log(`Agent初始化完成,已加载 ${this.executionPipeline.getRegistry().getAll().length} 个工具`)}catch($){throw this.error("Agent初始化失败",$),$}}async executeTask($){if(!this.isInitialized)throw Error("Agent未初始化");this.activeTask=$;try{this.log(`开始执行任务: ${$.id}`);let Y;if($.type==="parallel")Y=await this.executionEngine.executeParallelTask($);else if($.type==="steering")Y=await this.executionEngine.executeSteeringTask($);else Y=await this.executionEngine.executeSimpleTask($);return this.activeTask=void 0,this.log(`任务执行完成: ${$.id}`),Y}catch(Y){throw this.activeTask=void 0,this.error(`任务执行失败: ${$.id}`,Y),Y}}async chat($,Y,Z){if(!this.isInitialized)throw Error("Agent未初始化");let X=await this.processAtMentionsForContent($);if(Y){let G={signal:Y.signal,...Z},K=Y.permissionMode==="plan"?await this.runPlanLoop(X,Y,G):await this.runLoop(X,Y,G);if(!K.success){if(K.error?.type==="aborted"||K.metadata?.shouldExitLoop)return"";throw Error(K.error?.message||"执行失败")}if(K.metadata?.targetMode&&Y.permissionMode==="plan"){let W=K.metadata.targetMode,O=K.metadata.planContent;T.debug(`\uD83D\uDD04 Plan 模式已批准,切换到 ${W} 模式并重新执行`),await A1().setPermissionMode(W),T.debug(`✅ 权限模式已更新: ${W}`);let U={...Y,permissionMode:W},F=X;if(O){let H=`
1265
+ `+" /init");let Z=x1();if(!Z)throw Error("❌ 配置未初始化,请确保应用已正确启动");W0.getInstance().validateConfig(Z);let Q=new l1(Z,$);if(await Q.initialize(),$.toolWhitelist&&$.toolWhitelist.length>0)Q.applyToolWhitelist($.toolWhitelist);return Q}async initialize(){if(this.isInitialized)return;try{this.log("初始化Agent..."),await this.initializeSystemPrompt(),await this.registerBuiltinTools(),await this.loadSubagents(),await this.discoverSkills();let $=w$();if(!$)throw Error("❌ 当前模型配置未找到");this.log(`\uD83D\uDE80 使用模型: ${$.name} (${$.model})`);let Y=x$($);if(Y)this.log("\uD83E\uDDE0 检测到 Thinking 模型,启用 reasoning_content 支持");this.chatService=K4({provider:$.provider,apiKey:$.apiKey,model:$.model,baseUrl:$.baseUrl,temperature:$.temperature??this.config.temperature,maxContextTokens:$.maxContextTokens??this.config.maxContextTokens,maxOutputTokens:$.maxOutputTokens??this.config.maxOutputTokens,timeout:this.config.timeout,supportsThinking:Y}),this.executionEngine=new x7(this.chatService),this.attachmentCollector=new E9({cwd:process.cwd(),maxFileSize:1048576,maxLines:2000,maxTokens:32000}),this.isInitialized=!0,this.log(`Agent初始化完成,已加载 ${this.executionPipeline.getRegistry().getAll().length} 个工具`)}catch($){throw this.error("Agent初始化失败",$),$}}async executeTask($){if(!this.isInitialized)throw Error("Agent未初始化");this.activeTask=$;try{this.log(`开始执行任务: ${$.id}`);let Y;if($.type==="parallel")Y=await this.executionEngine.executeParallelTask($);else if($.type==="steering")Y=await this.executionEngine.executeSteeringTask($);else Y=await this.executionEngine.executeSimpleTask($);return this.activeTask=void 0,this.log(`任务执行完成: ${$.id}`),Y}catch(Y){throw this.activeTask=void 0,this.error(`任务执行失败: ${$.id}`,Y),Y}}async chat($,Y,Z){if(!this.isInitialized)throw Error("Agent未初始化");let X=await this.processAtMentionsForContent($);if(Y){let K={signal:Y.signal,...Z},G=Y.permissionMode==="plan"?await this.runPlanLoop(X,Y,K):await this.runLoop(X,Y,K);if(!G.success){if(G.error?.type==="aborted"||G.metadata?.shouldExitLoop)return"";throw Error(G.error?.message||"执行失败")}if(G.metadata?.targetMode&&Y.permissionMode==="plan"){let U=G.metadata.targetMode,O=G.metadata.planContent;S.debug(`\uD83D\uDD04 Plan 模式已批准,切换到 ${U} 模式并重新执行`),await D1().setPermissionMode(U),S.debug(`✅ 权限模式已更新: ${U}`);let W={...Y,permissionMode:U},F=X;if(O){let H=`
1264
1266
 
1265
1267
  <approved-plan>
1266
1268
  ${O}
1267
1269
  </approved-plan>
1268
1270
 
1269
- IMPORTANT: Execute according to the approved plan above. Follow the steps exactly as specified.`;if(typeof X==="string")F=X+H;else F=[...X,{type:"text",text:H}];T.debug(`\uD83D\uDCCB 已将 plan 内容注入到消息中 (${O.length} 字符)`)}return this.runLoop(F,U,G).then((H)=>{if(!H.success)throw Error(H.error?.message||"执行失败");return H.finalMessage||""})}return K.finalMessage||""}let Q=typeof X==="string"?X:X.filter((G)=>G.type==="text").map((G)=>G.text).join(`
1270
- `),J={id:this.generateTaskId(),type:"simple",prompt:Q};return(await this.executeTask(J)).content}async runPlanLoop($,Y,Z){T.debug("\uD83D\uDD35 Processing Plan mode message...");let{prompt:X}=await H4({projectPath:process.cwd(),mode:"plan",includeEnvironment:!0}),Q;if(typeof $==="string")Q=_6($);else{let J=$.filter((q)=>q.type==="text");if(J.length>0){let q=J[0];Q=$.map((G)=>G===q?{type:"text",text:_6(q.text)}:G)}else Q=[{type:"text",text:_6("")},...$]}return this.executeLoop(Q,Y,Z,X)}async runLoop($,Y,Z){T.debug("\uD83D\uDCAC Processing enhanced chat message...");let X=F4(),Q=this.systemPrompt?`${X}
1271
+ IMPORTANT: Execute according to the approved plan above. Follow the steps exactly as specified.`;if(typeof X==="string")F=X+H;else F=[...X,{type:"text",text:H}];S.debug(`\uD83D\uDCCB 已将 plan 内容注入到消息中 (${O.length} 字符)`)}return this.runLoop(F,W,K).then((H)=>{if(!H.success)throw Error(H.error?.message||"执行失败");return H.finalMessage||""})}return G.finalMessage||""}let Q=typeof X==="string"?X:X.filter((K)=>K.type==="text").map((K)=>K.text).join(`
1272
+ `),J={id:this.generateTaskId(),type:"simple",prompt:Q};return(await this.executeTask(J)).content}async runPlanLoop($,Y,Z){S.debug("\uD83D\uDD35 Processing Plan mode message...");let{prompt:X}=await B4({projectPath:process.cwd(),mode:"plan",includeEnvironment:!0}),Q;if(typeof $==="string")Q=_6($);else{let J=$.filter((q)=>q.type==="text");if(J.length>0){let q=J[0];Q=$.map((K)=>K===q?{type:"text",text:_6(q.text)}:K)}else Q=[{type:"text",text:_6("")},...$]}return this.executeLoop(Q,Y,Z,X)}async runLoop($,Y,Z){S.debug("\uD83D\uDCAC Processing enhanced chat message...");let X=N4(),Q=this.systemPrompt?`${X}
1271
1273
 
1272
1274
  ---
1273
1275
 
1274
- ${this.systemPrompt}`:X;return this.executeLoop($,Y,Z,Q)}async executeLoop($,Y,Z,X){if(!this.isInitialized)throw Error("Agent未初始化");let Q=Date.now();try{let J=this.executionPipeline.getRegistry(),q=Y.permissionMode,G=J.getFunctionDeclarationsByMode(q);G=z8(G);let K=this.applySkillToolRestrictions(G);if(q==="plan"){let A=J.getReadOnlyTools();T.debug(`\uD83D\uDD12 Plan mode: 使用只读工具 (${A.length} 个): ${A.map((D)=>D.name).join(", ")}`)}let O=Y.messages.length===0||!Y.messages.some((A)=>A.role==="system"),U=[];if(O&&X)U.push({role:"system",content:X});U.push(...Y.messages,{role:"user",content:$});let F=null;try{let A=this.executionEngine?.getContextManager(),D=typeof $==="string"?$:$.filter((w)=>w.type==="text").map((w)=>w.text).join(`
1275
- `);if(A&&Y.sessionId&&D.trim()!=="")F=await A.saveMessage(Y.sessionId,"user",D);else if(D.trim()==="")T.debug("[Agent] 跳过保存空用户消息")}catch(A){T.warn("[Agent] 保存用户消息失败:",A)}let H=100,_=Y.permissionMode==="yolo",z=this.runtimeOptions.maxTurns??Z?.maxTurns??this.config.maxTurns??-1;if(z===0)return{success:!1,error:{type:"chat_disabled",message:`对话功能已被禁用 (maxTurns=0)。如需启用,请调整配置:
1276
+ ${this.systemPrompt}`:X;return this.executeLoop($,Y,Z,Q)}async executeLoop($,Y,Z,X){if(!this.isInitialized)throw Error("Agent未初始化");let Q=Date.now();try{let J=this.executionPipeline.getRegistry(),q=Y.permissionMode,K=J.getFunctionDeclarationsByMode(q);K=D9(K);let G=this.applySkillToolRestrictions(K);if(q==="plan"){let A=J.getReadOnlyTools();S.debug(`\uD83D\uDD12 Plan mode: 使用只读工具 (${A.length} 个): ${A.map((D)=>D.name).join(", ")}`)}let O=Y.messages.length===0||!Y.messages.some((A)=>A.role==="system"),W=[];if(O&&X)W.push({role:"system",content:X});W.push(...Y.messages,{role:"user",content:$});let F=null;try{let A=this.executionEngine?.getContextManager(),D=typeof $==="string"?$:$.filter((w)=>w.type==="text").map((w)=>w.text).join(`
1277
+ `);if(A&&Y.sessionId&&D.trim()!=="")F=await A.saveMessage(Y.sessionId,"user",D);else if(D.trim()==="")S.debug("[Agent] 跳过保存空用户消息")}catch(A){S.warn("[Agent] 保存用户消息失败:",A)}let H=100,z=Y.permissionMode==="yolo",N=this.runtimeOptions.maxTurns??Z?.maxTurns??this.config.maxTurns??-1;if(N===0)return{success:!1,error:{type:"chat_disabled",message:`对话功能已被禁用 (maxTurns=0)。如需启用,请调整配置:
1276
1278
  `+` • CLI 参数: blade --max-turns -1
1277
1279
  `+` • 配置文件: ~/.blade/config.json 中设置 "maxTurns": -1
1278
- `+" • 环境变量: export BLADE_MAX_TURNS=-1"},metadata:{turnsCount:0,toolCallsCount:0,duration:0}};let L=z===-1?H:Math.min(z,H);if(this.config.debug)T.debug(`[MaxTurns] runtimeOptions: ${this.runtimeOptions.maxTurns}, options: ${Z?.maxTurns}, config: ${this.config.maxTurns}, 最终: ${z} → ${L}, YOLO: ${_}`);let B=0,N=[],I=0,M;while(!0){if(Z?.signal?.aborted)return{success:!1,error:{type:"aborted",message:"任务已被用户中止"},metadata:{turnsCount:B,toolCallsCount:N.length,duration:Date.now()-Q}};let A=Y.messages.length;if(await this.checkAndCompactInLoop(Y,B,M,Z?.onCompacting)){T.debug(`[Agent] [轮次 ${B}] 检测到压缩发生,重建 messages 数组 (${A} → ${Y.messages.length} 条历史消息)`);let R=O&&X?1:0,E=R+A,x=U.slice(0,R),r=U.slice(E);U.length=0,U.push(...x,...Y.messages,...r),T.debug(`[Agent] [轮次 ${B}] messages 重建完成: ${x.length} system + ${Y.messages.length} 历史 + ${r.length} 新增 = ${U.length} 总计`)}if(B++,T.debug(`\uD83D\uDD04 [轮次 ${B}/${L}] 调用 LLM...`),Z?.signal?.aborted)return{success:!1,error:{type:"aborted",message:"任务已被用户中止"},metadata:{turnsCount:B-1,toolCallsCount:N.length,duration:Date.now()-Q}};Z?.onTurnStart?.({turn:B,maxTurns:L}),T.debug(`
1279
- ========== 发送给 LLM ==========`),T.debug("轮次:",B+1),T.debug("消息数量:",U.length),T.debug("最后 3 条消息:"),U.slice(-3).forEach((R,E)=>{if(T.debug(` [${E}] ${R.role}:`,typeof R.content==="string"?R.content.substring(0,100)+(R.content.length>100?"...":""):JSON.stringify(R.content).substring(0,100)),R.tool_calls)T.debug(" tool_calls:",R.tool_calls.map((x)=>("function"in x)?x.function.name:x.type).join(", "))}),T.debug("可用工具数量:",K.length),T.debug(`================================
1280
- `);let w=await this.chatService.chat(U,K,Z?.signal);if(w.usage){if(w.usage.totalTokens)I+=w.usage.totalTokens;if(M=w.usage.promptTokens,T.debug(`[Agent] LLM usage: prompt=${M}, completion=${w.usage.completionTokens}, total=${w.usage.totalTokens}`),Z?.onTokenUsage)Z.onTokenUsage({inputTokens:w.usage.promptTokens??0,outputTokens:w.usage.completionTokens??0,totalTokens:I,maxContextTokens:this.config.maxContextTokens})}if(Z?.signal?.aborted)return{success:!1,error:{type:"aborted",message:"任务已被用户中止"},metadata:{turnsCount:B-1,toolCallsCount:N.length,duration:Date.now()-Q}};if(T.debug(`
1281
- ========== LLM 返回 ==========`),T.debug("Content:",w.content),T.debug("Tool Calls:",JSON.stringify(w.toolCalls,null,2)),T.debug("当前权限模式:",Y.permissionMode),T.debug(`================================
1282
- `),w.reasoningContent&&Z?.onThinking&&!Z.signal?.aborted)Z.onThinking(w.reasoningContent);if(w.content&&w.content.trim()&&Z?.onContent&&!Z.signal?.aborted)Z.onContent(w.content);if(!w.toolCalls||w.toolCalls.length===0){let R=[/:\s*$/,/:\s*$/,/\.\.\.\s*$/,/让我(先|来|开始|查看|检查|修复)/,/Let me (first|start|check|look|fix)/i],E=w.content||"",x=R.some((C)=>C.test(E)),r="请执行你提到的操作,不要只是描述。",j=U.slice(-10).filter((C)=>C.role==="user"&&C.content==="请执行你提到的操作,不要只是描述。").length;if(x&&j<2){T.debug(`⚠️ 检测到意图未完成(重试 ${j+1}/2): "${E.slice(-50)}"`),U.push({role:"user",content:"请执行你提到的操作,不要只是描述。"});continue}T.debug("✅ 任务完成 - LLM 未请求工具调用");try{let Y1=await H1.getInstance().executeStopHooks({projectDir:process.cwd(),sessionId:Y.sessionId,permissionMode:Y.permissionMode,reason:w.content,abortSignal:Z?.signal});if(!Y1.shouldStop){T.debug(`\uD83D\uDD04 Stop hook 阻止停止,继续执行: ${Y1.continueReason||"(无原因)"}`);let k=Y1.continueReason?`
1280
+ `+" • 环境变量: export BLADE_MAX_TURNS=-1"},metadata:{turnsCount:0,toolCallsCount:0,duration:0}};let L=N===-1?H:Math.min(N,H);if(this.config.debug)S.debug(`[MaxTurns] runtimeOptions: ${this.runtimeOptions.maxTurns}, options: ${Z?.maxTurns}, config: ${this.config.maxTurns}, 最终: ${N} → ${L}, YOLO: ${z}`);let B=0,_=[],I=0,M;while(!0){if(Z?.signal?.aborted)return{success:!1,error:{type:"aborted",message:"任务已被用户中止"},metadata:{turnsCount:B,toolCallsCount:_.length,duration:Date.now()-Q}};let A=Y.messages.length;if(await this.checkAndCompactInLoop(Y,B,M,Z?.onCompacting)){S.debug(`[Agent] [轮次 ${B}] 检测到压缩发生,重建 messages 数组 (${A} → ${Y.messages.length} 条历史消息)`);let R=O&&X?1:0,E=R+A,x=W.slice(0,R),r=W.slice(E);W.length=0,W.push(...x,...Y.messages,...r),S.debug(`[Agent] [轮次 ${B}] messages 重建完成: ${x.length} system + ${Y.messages.length} 历史 + ${r.length} 新增 = ${W.length} 总计`)}if(B++,S.debug(`\uD83D\uDD04 [轮次 ${B}/${L}] 调用 LLM...`),Z?.signal?.aborted)return{success:!1,error:{type:"aborted",message:"任务已被用户中止"},metadata:{turnsCount:B-1,toolCallsCount:_.length,duration:Date.now()-Q}};Z?.onTurnStart?.({turn:B,maxTurns:L}),S.debug(`
1281
+ ========== 发送给 LLM ==========`),S.debug("轮次:",B+1),S.debug("消息数量:",W.length),S.debug("最后 3 条消息:"),W.slice(-3).forEach((R,E)=>{if(S.debug(` [${E}] ${R.role}:`,typeof R.content==="string"?R.content.substring(0,100)+(R.content.length>100?"...":""):JSON.stringify(R.content).substring(0,100)),R.tool_calls)S.debug(" tool_calls:",R.tool_calls.map((x)=>("function"in x)?x.function.name:x.type).join(", "))}),S.debug("可用工具数量:",G.length),S.debug(`================================
1282
+ `);let w=await this.chatService.chat(W,G,Z?.signal);if(w.usage){if(w.usage.totalTokens)I+=w.usage.totalTokens;if(M=w.usage.promptTokens,S.debug(`[Agent] LLM usage: prompt=${M}, completion=${w.usage.completionTokens}, total=${w.usage.totalTokens}`),Z?.onTokenUsage)Z.onTokenUsage({inputTokens:w.usage.promptTokens??0,outputTokens:w.usage.completionTokens??0,totalTokens:I,maxContextTokens:this.config.maxContextTokens})}if(Z?.signal?.aborted)return{success:!1,error:{type:"aborted",message:"任务已被用户中止"},metadata:{turnsCount:B-1,toolCallsCount:_.length,duration:Date.now()-Q}};if(S.debug(`
1283
+ ========== LLM 返回 ==========`),S.debug("Content:",w.content),S.debug("Tool Calls:",JSON.stringify(w.toolCalls,null,2)),S.debug("当前权限模式:",Y.permissionMode),S.debug(`================================
1284
+ `),w.reasoningContent&&Z?.onThinking&&!Z.signal?.aborted)Z.onThinking(w.reasoningContent);if(w.content&&w.content.trim()&&Z?.onContent&&!Z.signal?.aborted)Z.onContent(w.content);if(!w.toolCalls||w.toolCalls.length===0){let R=[/:\s*$/,/:\s*$/,/\.\.\.\s*$/,/让我(先|来|开始|查看|检查|修复)/,/Let me (first|start|check|look|fix)/i],E=w.content||"",x=R.some((k)=>k.test(E)),r="请执行你提到的操作,不要只是描述。",P=W.slice(-10).filter((k)=>k.role==="user"&&k.content==="请执行你提到的操作,不要只是描述。").length;if(x&&P<2){S.debug(`⚠️ 检测到意图未完成(重试 ${P+1}/2): "${E.slice(-50)}"`),W.push({role:"user",content:"请执行你提到的操作,不要只是描述。"});continue}S.debug("✅ 任务完成 - LLM 未请求工具调用");try{let n=await H1.getInstance().executeStopHooks({projectDir:process.cwd(),sessionId:Y.sessionId,permissionMode:Y.permissionMode,reason:w.content,abortSignal:Z?.signal});if(!n.shouldStop){S.debug(`\uD83D\uDD04 Stop hook 阻止停止,继续执行: ${n.continueReason||"(无原因)"}`);let T=n.continueReason?`
1283
1285
 
1284
1286
  <system-reminder>
1285
- ${Y1.continueReason}
1287
+ ${n.continueReason}
1286
1288
  </system-reminder>`:`
1287
1289
 
1288
1290
  <system-reminder>
1289
1291
  Please continue the conversation from where we left it off without asking the user any further questions. Continue with the last task that you were asked to work on.
1290
- </system-reminder>`;U.push({role:"user",content:k});continue}if(Y1.warning)T.warn(`[Agent] Stop hook warning: ${Y1.warning}`)}catch(C){T.warn("[Agent] Stop hook execution failed:",C)}try{let C=this.executionEngine?.getContextManager();if(C&&Y.sessionId&&w.content)if(w.content.trim()!=="")F=await C.saveMessage(Y.sessionId,"assistant",w.content,F);else T.debug("[Agent] 跳过保存空响应(任务完成时)")}catch(C){T.warn("[Agent] 保存助手消息失败:",C)}return{success:!0,finalMessage:w.content,metadata:{turnsCount:B,toolCallsCount:N.length,duration:Date.now()-Q,tokensUsed:I}}}U.push({role:"assistant",content:w.content||"",reasoningContent:w.reasoningContent,tool_calls:w.toolCalls});try{let R=this.executionEngine?.getContextManager();if(R&&Y.sessionId&&w.content)if(w.content.trim()!=="")F=await R.saveMessage(Y.sessionId,"assistant",w.content,F);else T.debug("[Agent] 跳过保存空响应(工具调用时)")}catch(R){T.warn("[Agent] 保存助手工具调用消息失败:",R)}for(let R of w.toolCalls){if(R.type!=="function")continue;if(Z?.signal?.aborted)return T.info(`[Agent] Aborting before tool ${R.function.name} due to signal.aborted=true`),{success:!1,error:{type:"aborted",message:"任务已被用户中止"},metadata:{turnsCount:B,toolCallsCount:N.length,duration:Date.now()-Q}};try{if(Z?.onToolStart&&!Z.signal?.aborted){let S=this.executionPipeline.getRegistry().get(R.function.name)?.kind;Z.onToolStart(R,S)}let E=JSON.parse(R.function.arguments);if(E.todos&&typeof E.todos==="string")try{E.todos=JSON.parse(E.todos),this.log("[Agent] 自动修复了字符串化的 todos 参数")}catch{this.error("[Agent] todos 参数格式异常,将由验证层处理")}let x=null;try{let k=this.executionEngine?.getContextManager();if(k&&Y.sessionId)x=await k.saveToolUse(Y.sessionId,R.function.name,E,F)}catch(k){T.warn("[Agent] 保存工具调用失败:",k)}let r=Z?.signal;if(!r)T.error("[Agent] Missing signal in tool execution, this should not happen");T.debug("[Agent] Passing confirmationHandler to ExecutionPipeline.execute:",{toolName:R.function.name,hasHandler:!!Y.confirmationHandler,hasMethod:!!Y.confirmationHandler?.requestConfirmation,methodType:typeof Y.confirmationHandler?.requestConfirmation});let j=await this.executionPipeline.execute(R.function.name,E,{sessionId:Y.sessionId,userId:Y.userId||"default",workspaceRoot:Y.workspaceRoot||process.cwd(),signal:r,confirmationHandler:Y.confirmationHandler,permissionMode:Y.permissionMode});if(N.push(j),T.debug(`
1291
- ========== 工具执行结果 ==========`),T.debug("工具名称:",R.function.name),T.debug("成功:",j.success),T.debug("LLM Content:",j.llmContent),T.debug("Display Content:",j.displayContent),j.error)T.debug("错误:",j.error);if(T.debug(`==================================
1292
- `),j.metadata?.shouldExitLoop){T.debug("\uD83D\uDEAA 检测到退出循环标记,结束 Agent 循环");let k=typeof j.llmContent==="string"?j.llmContent:"循环已退出";return{success:j.success,finalMessage:k,metadata:{turnsCount:B,toolCallsCount:N.length,duration:Date.now()-Q,shouldExitLoop:!0,targetMode:j.metadata.targetMode}}}if(Z?.onToolResult&&!Z.signal?.aborted){T.debug("[Agent] Calling onToolResult:",{toolName:R.function.name,hasCallback:!0,resultSuccess:j.success,resultKeys:Object.keys(j),hasMetadata:!!j.metadata,metadataKeys:j.metadata?Object.keys(j.metadata):[],hasSummary:!!j.metadata?.summary,summary:j.metadata?.summary});try{await Z.onToolResult(R,j),T.debug("[Agent] onToolResult callback completed successfully")}catch(k){T.error("[Agent] onToolResult callback error:",k)}}else T.debug("[Agent] No onToolResult callback provided");try{let k=this.executionEngine?.getContextManager();if(k&&Y.sessionId)F=await k.saveToolResult(Y.sessionId,R.id,j.success?j.llmContent:void 0,x,j.success?void 0:j.error?.message)}catch(k){T.warn("[Agent] 保存工具结果失败:",k)}if(R.function.name==="TodoWrite"&&j.success&&j.llmContent){let k=typeof j.llmContent==="object"?j.llmContent:{},y=Array.isArray(k)?k:k.todos||[];C0().setTodos(y),Z?.onTodoUpdate?.(y)}if(R.function.name==="Skill"&&j.success&&j.metadata){let k=j.metadata;if(k.skillName)this.activeSkillContext={skillName:k.skillName,allowedTools:k.allowedTools,basePath:k.basePath||""},T.debug(`\uD83C\uDFAF Skill "${this.activeSkillContext.skillName}" activated`+(this.activeSkillContext.allowedTools?` with allowed tools: ${this.activeSkillContext.allowedTools.join(", ")}`:""))}let C=j.success?j.llmContent||j.displayContent||"":j.error?.message||"执行失败";if(typeof C==="object"&&C!==null)C=JSON.stringify(C,null,2);let Y1=typeof C==="string"?C:JSON.stringify(C);U.push({role:"tool",tool_call_id:R.id,name:R.function.name,content:Y1})}catch(E){T.error(`Tool execution failed for ${R.function.name}:`,E),U.push({role:"tool",tool_call_id:R.id,name:R.function.name,content:`Execution failed: ${E instanceof Error?E.message:"Unknown error"}`})}}if(Z?.signal?.aborted)return{success:!1,error:{type:"aborted",message:"任务已被用户中止"},metadata:{turnsCount:B,toolCallsCount:N.length,duration:Date.now()-Q}};if(B>=L&&!_){if(T.info(`⚠️ 达到轮次上限 ${L} 轮,等待用户确认...`),Z?.onTurnLimitReached){let R=await Z.onTurnLimitReached({turnsCount:B});if(R?.continue){T.info("✅ 用户选择继续,压缩上下文...");try{let E=this.chatService.getConfig(),x=await b$.compact(Y.messages,{trigger:"auto",modelName:E.model,maxContextTokens:E.maxContextTokens??this.config.maxContextTokens,apiKey:E.apiKey,baseURL:E.baseUrl,actualPreTokens:M});Y.messages=x.compactedMessages;let r=U.find((C)=>C.role==="system");if(U.length=0,r)U.push(r);U.push(...Y.messages);let j={role:"user",content:`This session is being continued from a previous conversation. The conversation is summarized above.
1292
+ </system-reminder>`;W.push({role:"user",content:T});continue}if(n.warning)S.warn(`[Agent] Stop hook warning: ${n.warning}`)}catch(k){S.warn("[Agent] Stop hook execution failed:",k)}try{let k=this.executionEngine?.getContextManager();if(k&&Y.sessionId&&w.content)if(w.content.trim()!=="")F=await k.saveMessage(Y.sessionId,"assistant",w.content,F);else S.debug("[Agent] 跳过保存空响应(任务完成时)")}catch(k){S.warn("[Agent] 保存助手消息失败:",k)}return{success:!0,finalMessage:w.content,metadata:{turnsCount:B,toolCallsCount:_.length,duration:Date.now()-Q,tokensUsed:I}}}W.push({role:"assistant",content:w.content||"",reasoningContent:w.reasoningContent,tool_calls:w.toolCalls});try{let R=this.executionEngine?.getContextManager();if(R&&Y.sessionId&&w.content)if(w.content.trim()!=="")F=await R.saveMessage(Y.sessionId,"assistant",w.content,F);else S.debug("[Agent] 跳过保存空响应(工具调用时)")}catch(R){S.warn("[Agent] 保存助手工具调用消息失败:",R)}for(let R of w.toolCalls){if(R.type!=="function")continue;if(Z?.signal?.aborted)return S.info(`[Agent] Aborting before tool ${R.function.name} due to signal.aborted=true`),{success:!1,error:{type:"aborted",message:"任务已被用户中止"},metadata:{turnsCount:B,toolCallsCount:_.length,duration:Date.now()-Q}};try{if(Z?.onToolStart&&!Z.signal?.aborted){let C=this.executionPipeline.getRegistry().get(R.function.name)?.kind;Z.onToolStart(R,C)}let E=JSON.parse(R.function.arguments);if(E.todos&&typeof E.todos==="string")try{E.todos=JSON.parse(E.todos),this.log("[Agent] 自动修复了字符串化的 todos 参数")}catch{this.error("[Agent] todos 参数格式异常,将由验证层处理")}let x=null;try{let T=this.executionEngine?.getContextManager();if(T&&Y.sessionId)x=await T.saveToolUse(Y.sessionId,R.function.name,E,F)}catch(T){S.warn("[Agent] 保存工具调用失败:",T)}let r=Z?.signal;if(!r)S.error("[Agent] Missing signal in tool execution, this should not happen");S.debug("[Agent] Passing confirmationHandler to ExecutionPipeline.execute:",{toolName:R.function.name,hasHandler:!!Y.confirmationHandler,hasMethod:!!Y.confirmationHandler?.requestConfirmation,methodType:typeof Y.confirmationHandler?.requestConfirmation});let P=await this.executionPipeline.execute(R.function.name,E,{sessionId:Y.sessionId,userId:Y.userId||"default",workspaceRoot:Y.workspaceRoot||process.cwd(),signal:r,confirmationHandler:Y.confirmationHandler,permissionMode:Y.permissionMode});if(_.push(P),S.debug(`
1293
+ ========== 工具执行结果 ==========`),S.debug("工具名称:",R.function.name),S.debug("成功:",P.success),S.debug("LLM Content:",P.llmContent),S.debug("Display Content:",P.displayContent),P.error)S.debug("错误:",P.error);if(S.debug(`==================================
1294
+ `),P.metadata?.shouldExitLoop){S.debug("\uD83D\uDEAA 检测到退出循环标记,结束 Agent 循环");let T=typeof P.llmContent==="string"?P.llmContent:"循环已退出";return{success:P.success,finalMessage:T,metadata:{turnsCount:B,toolCallsCount:_.length,duration:Date.now()-Q,shouldExitLoop:!0,targetMode:P.metadata.targetMode}}}if(Z?.onToolResult&&!Z.signal?.aborted){S.debug("[Agent] Calling onToolResult:",{toolName:R.function.name,hasCallback:!0,resultSuccess:P.success,resultKeys:Object.keys(P),hasMetadata:!!P.metadata,metadataKeys:P.metadata?Object.keys(P.metadata):[],hasSummary:!!P.metadata?.summary,summary:P.metadata?.summary});try{await Z.onToolResult(R,P),S.debug("[Agent] onToolResult callback completed successfully")}catch(T){S.error("[Agent] onToolResult callback error:",T)}}else S.debug("[Agent] No onToolResult callback provided");try{let T=this.executionEngine?.getContextManager();if(T&&Y.sessionId)F=await T.saveToolResult(Y.sessionId,R.id,P.success?P.llmContent:void 0,x,P.success?void 0:P.error?.message)}catch(T){S.warn("[Agent] 保存工具结果失败:",T)}if(R.function.name==="TodoWrite"&&P.success&&P.llmContent){let T=typeof P.llmContent==="object"?P.llmContent:{},j=Array.isArray(T)?T:T.todos||[];x0().setTodos(j),Z?.onTodoUpdate?.(j)}if(R.function.name==="Skill"&&P.success&&P.metadata){let T=P.metadata;if(T.skillName)this.activeSkillContext={skillName:T.skillName,allowedTools:T.allowedTools,basePath:T.basePath||""},S.debug(`\uD83C\uDFAF Skill "${this.activeSkillContext.skillName}" activated`+(this.activeSkillContext.allowedTools?` with allowed tools: ${this.activeSkillContext.allowedTools.join(", ")}`:""))}let k=P.success?P.llmContent||P.displayContent||"":P.error?.message||"执行失败";if(typeof k==="object"&&k!==null)k=JSON.stringify(k,null,2);let n=typeof k==="string"?k:JSON.stringify(k);W.push({role:"tool",tool_call_id:R.id,name:R.function.name,content:n})}catch(E){S.error(`Tool execution failed for ${R.function.name}:`,E),W.push({role:"tool",tool_call_id:R.id,name:R.function.name,content:`Execution failed: ${E instanceof Error?E.message:"Unknown error"}`})}}if(Z?.signal?.aborted)return{success:!1,error:{type:"aborted",message:"任务已被用户中止"},metadata:{turnsCount:B,toolCallsCount:_.length,duration:Date.now()-Q}};if(B>=L&&!z){if(S.info(`⚠️ 达到轮次上限 ${L} 轮,等待用户确认...`),Z?.onTurnLimitReached){let R=await Z.onTurnLimitReached({turnsCount:B});if(R?.continue){S.info("✅ 用户选择继续,压缩上下文...");try{let E=this.chatService.getConfig(),x=await D$.compact(Y.messages,{trigger:"auto",modelName:E.model,maxContextTokens:E.maxContextTokens??this.config.maxContextTokens,apiKey:E.apiKey,baseURL:E.baseUrl,actualPreTokens:M});Y.messages=x.compactedMessages;let r=W.find((k)=>k.role==="system");if(W.length=0,r)W.push(r);W.push(...Y.messages);let P={role:"user",content:`This session is being continued from a previous conversation. The conversation is summarized above.
1293
1295
 
1294
- Please continue the conversation from where we left it off without asking the user any further questions. Continue with the last task that you were asked to work on.`};U.push(j),Y.messages.push(j);try{let C=this.executionEngine?.getContextManager();if(C&&Y.sessionId)await C.saveCompaction(Y.sessionId,x.summary,{trigger:"auto",preTokens:x.preTokens,postTokens:x.postTokens,filesIncluded:x.filesIncluded},null)}catch(C){T.warn("[Agent] 保存压缩数据失败:",C)}T.info(`✅ 上下文已压缩 (${x.preTokens} → ${x.postTokens} tokens),重置轮次计数`)}catch(E){T.error("[Agent] 压缩失败,使用降级策略:",E);let x=U.find((j)=>j.role==="system"),r=U.slice(-80);if(U.length=0,x&&!r.some((j)=>j.role==="system"))U.push(x);U.push(...r),Y.messages=U.filter((j)=>j.role!=="system"),T.warn(`⚠️ 降级压缩完成,保留 ${U.length} 条消息`)}B=0;continue}return{success:!0,finalMessage:R?.reason||"已达到对话轮次上限,用户选择停止",metadata:{turnsCount:B,toolCallsCount:N.length,duration:Date.now()-Q,tokensUsed:I}}}return{success:!1,error:{type:"max_turns_exceeded",message:`已达到轮次上限 (${L} 轮)。使用 --permission-mode yolo 跳过此限制。`},metadata:{turnsCount:B,toolCallsCount:N.length,duration:Date.now()-Q,tokensUsed:I}}}}}catch(J){if(J instanceof Error&&(J.name==="AbortError"||J.message.includes("aborted")))return{success:!1,error:{type:"aborted",message:"任务已被用户中止"},metadata:{turnsCount:0,toolCallsCount:0,duration:Date.now()-Q}};return T.error("Enhanced chat processing error:",J),{success:!1,error:{type:"api_error",message:`处理消息时发生错误: ${J instanceof Error?J.message:"未知错误"}`,details:J},metadata:{turnsCount:0,toolCallsCount:0,duration:Date.now()-Q}}}}async runAgenticLoop($,Y,Z){if(!this.isInitialized)throw Error("Agent未初始化");let X={messages:Y.messages,userId:Y.userId||"subagent",sessionId:Y.sessionId||`subagent_${Date.now()}`,workspaceRoot:Y.workspaceRoot||process.cwd(),signal:Y.signal,confirmationHandler:Y.confirmationHandler};return await this.runLoop($,X,Z)}async chatWithSystem($,Y){if(!this.isInitialized)throw Error("Agent未初始化");let Z=[{role:"system",content:$},{role:"user",content:Y}];return(await this.chatService.chat(Z)).content}getActiveTask(){return this.activeTask}getChatService(){return this.chatService}getContextManager(){return this.executionEngine?.getContextManager()}getStats(){return{initialized:this.isInitialized,activeTask:this.activeTask?.id,components:{chatService:this.chatService?"ready":"not_loaded",executionEngine:this.executionEngine?"ready":"not_loaded"}}}getAvailableTools(){return this.executionPipeline?this.executionPipeline.getRegistry().getAll():[]}getToolRegistry(){return this.executionPipeline.getRegistry()}applyToolWhitelist($){let Y=this.executionPipeline.getRegistry(),X=Y.getAll().filter((Q)=>!$.includes(Q.name));for(let Q of X)Y.unregister(Q.name);T.debug(`\uD83D\uDD12 Applied tool whitelist: ${$.join(", ")} (removed ${X.length} tools)`)}getToolStats(){let $=this.getAvailableTools(),Y=new Map;return $.forEach((Z)=>{let X=Y.get(Z.kind)||0;Y.set(Z.kind,X+1)}),{totalTools:$.length,toolsByKind:Object.fromEntries(Y),toolNames:$.map((Z)=>Z.name)}}async destroy(){this.log("销毁Agent...");try{this.isInitialized=!1,this.log("Agent已销毁")}catch($){throw this.error("Agent销毁失败",$),$}}generateTaskId(){return`task_${Date.now()}_${Math.random().toString(36).substring(2,9)}`}log($,Y){T.debug(`[MainAgent] ${$}`,Y||"")}error($,Y){T.error(`[MainAgent] ${$}`,Y||"")}async initializeSystemPrompt(){try{let $=this.runtimeOptions.systemPrompt,Y=this.runtimeOptions.appendSystemPrompt,Z=await H4({projectPath:process.cwd(),replaceDefault:$,append:Y,includeEnvironment:!1});if(this.systemPrompt=Z.prompt,this.systemPrompt)this.log("系统提示已加载"),T.debug(`[SystemPrompt] 加载来源: ${Z.sources.filter((X)=>X.loaded).map((X)=>X.name).join(", ")}`)}catch($){this.error("初始化系统提示失败",$)}}getSystemPrompt(){return this.systemPrompt}async checkAndCompactInLoop($,Y,Z,X){if(Z===void 0)return T.debug(`[Agent] [轮次 ${Y}] 压缩检查: 跳过(无历史 usage 数据)`),!1;let Q=this.chatService.getConfig(),J=Q.model,q=Q.maxContextTokens??this.config.maxContextTokens,G=Q.maxOutputTokens??this.config.maxOutputTokens,K=q-G,W=Math.floor(K*0.8);if(T.debug(`[Agent] [轮次 ${Y}] 压缩检查:`,{promptTokens:Z,maxContextTokens:q,maxOutputTokens:G,availableForInput:K,threshold:W,shouldCompact:Z>=W}),Z<W)return!1;let O=Y===0?"[Agent] 触发自动压缩":`[Agent] [轮次 ${Y}] 触发循环内自动压缩`;T.debug(O),X?.(!0);try{let U=await b$.compact($.messages,{trigger:"auto",modelName:J,maxContextTokens:q,apiKey:Q.apiKey,baseURL:Q.baseUrl,actualPreTokens:Z});if(U.success)$.messages=U.compactedMessages,T.debug(`[Agent] [轮次 ${Y}] 压缩完成: ${U.preTokens} → ${U.postTokens} tokens (-${((1-U.postTokens/U.preTokens)*100).toFixed(1)}%)`);else $.messages=U.compactedMessages,T.warn(`[Agent] [轮次 ${Y}] 压缩使用降级策略: ${U.preTokens} → ${U.postTokens} tokens`);try{let F=this.executionEngine?.getContextManager();if(F&&$.sessionId)await F.saveCompaction($.sessionId,U.summary,{trigger:"auto",preTokens:U.preTokens,postTokens:U.postTokens,filesIncluded:U.filesIncluded},null),T.debug(`[Agent] [轮次 ${Y}] 压缩数据已保存到 JSONL`)}catch(F){T.warn(`[Agent] [轮次 ${Y}] 保存压缩数据失败:`,F)}return X?.(!1),!0}catch(U){return X?.(!1),T.error(`[Agent] [轮次 ${Y}] 压缩失败,继续执行`,U),!1}}async registerBuiltinTools(){try{let $=await DZ({sessionId:"default",configDir:gZ.join(pZ.homedir(),".blade")});T.debug(`\uD83D\uDCE6 Registering ${$.length} builtin tools...`),this.executionPipeline.getRegistry().registerAll($);let Y=this.executionPipeline.getRegistry().getAll().length;T.debug(`✅ Builtin tools registered: ${Y} tools`),T.debug(`[Tools] ${this.executionPipeline.getRegistry().getAll().map((Z)=>Z.name).join(", ")}`),await this.registerMcpTools()}catch($){throw T.error("Failed to register builtin tools:",$),$}}async registerMcpTools(){try{if(this.runtimeOptions.mcpConfig&&this.runtimeOptions.mcpConfig.length>0)await p5(this.runtimeOptions.mcpConfig);let $=A0();if(Object.keys($).length===0){T.debug("\uD83D\uDCE6 No MCP servers configured");return}let Y=n1.getInstance();for(let[X,Q]of Object.entries($))try{T.debug(`\uD83D\uDD0C Connecting to MCP server: ${X}`),await Y.registerServer(X,Q),T.debug(`✅ MCP server "${X}" connected`)}catch(J){T.warn(`⚠️ MCP server "${X}" connection failed:`,J)}let Z=await Y.getAvailableTools();if(Z.length>0)this.executionPipeline.getRegistry().registerAll(Z),T.debug(`✅ Registered ${Z.length} MCP tools`),T.debug(`[MCP Tools] ${Z.map((X)=>X.name).join(", ")}`)}catch($){T.warn("Failed to register MCP tools:",$)}}async loadSubagents(){if(x1.getAllNames().length>0){T.debug(`\uD83D\uDCE6 Subagents already loaded: ${x1.getAllNames().join(", ")}`);return}try{let $=x1.loadFromStandardLocations();if($>0)T.debug(`✅ Loaded ${$} subagents: ${x1.getAllNames().join(", ")}`);else T.debug("\uD83D\uDCE6 No subagents configured")}catch($){T.warn("Failed to load subagents:",$)}}async discoverSkills(){try{let $=await a2({cwd:process.cwd()});if($.skills.length>0)T.debug(`✅ Discovered ${$.skills.length} skills: ${$.skills.map((Y)=>Y.name).join(", ")}`);else T.debug("\uD83D\uDCE6 No skills configured");for(let Y of $.errors)T.warn(`⚠️ Skill loading error at ${Y.path}: ${Y.error}`)}catch($){T.warn("Failed to discover skills:",$)}}applySkillToolRestrictions($){if(!this.activeSkillContext?.allowedTools)return $;let Y=this.activeSkillContext.allowedTools;T.debug(`\uD83D\uDD12 Applying Skill tool restrictions: ${Y.join(", ")}`);let Z=$.filter((X)=>{return Y.some((Q)=>{if(Q===X.name)return!0;let J=Q.match(/^(\w+)\(.*\)$/);if(J&&J[1]===X.name)return!0;return!1})});return T.debug(`\uD83D\uDD12 Filtered tools: ${Z.map((X)=>X.name).join(", ")} (${Z.length}/${$.length})`),Z}clearSkillContext(){if(this.activeSkillContext)T.debug(`\uD83C\uDFAF Skill "${this.activeSkillContext.skillName}" deactivated`),this.activeSkillContext=void 0}async processAtMentionsForContent($){if(!this.attachmentCollector)return $;if(typeof $==="string")return this.processAtMentions($);let Y=[];for(let X of $)if(X.type==="text")Y.push(X.text);if(Y.length===0)return $;let Z=Y.join(`
1295
- `);try{let X=await this.attachmentCollector.collect(Z);if(X.length===0)return $;T.debug(`✅ Processed ${X.length} @ file mentions in multimodal message`);let Q=this.buildAttachmentText(X);if(!Q)return $;return[...$,{type:"text",text:Q}]}catch(X){return T.error("Failed to process @ mentions in multimodal message:",X),$}}buildAttachmentText($){let Y=[],Z=[];for(let Q of $)if(Q.type==="file"){let J=Q.metadata?.lineRange?` (lines ${Q.metadata.lineRange.start}${Q.metadata.lineRange.end?`-${Q.metadata.lineRange.end}`:""})`:"";Y.push(`<file path="${Q.path}"${J?` range="${J}"`:""}>`,Q.content,"</file>")}else if(Q.type==="directory")Y.push(`<directory path="${Q.path}">`,Q.content,"</directory>");else if(Q.type==="error")Z.push(`- @${Q.path}: ${Q.error}`);let X="";if(Y.length>0)X+=`
1296
+ Please continue the conversation from where we left it off without asking the user any further questions. Continue with the last task that you were asked to work on.`};W.push(P),Y.messages.push(P);try{let k=this.executionEngine?.getContextManager();if(k&&Y.sessionId)await k.saveCompaction(Y.sessionId,x.summary,{trigger:"auto",preTokens:x.preTokens,postTokens:x.postTokens,filesIncluded:x.filesIncluded},null)}catch(k){S.warn("[Agent] 保存压缩数据失败:",k)}S.info(`✅ 上下文已压缩 (${x.preTokens} → ${x.postTokens} tokens),重置轮次计数`)}catch(E){S.error("[Agent] 压缩失败,使用降级策略:",E);let x=W.find((P)=>P.role==="system"),r=W.slice(-80);if(W.length=0,x&&!r.some((P)=>P.role==="system"))W.push(x);W.push(...r),Y.messages=W.filter((P)=>P.role!=="system"),S.warn(`⚠️ 降级压缩完成,保留 ${W.length} 条消息`)}B=0;continue}return{success:!0,finalMessage:R?.reason||"已达到对话轮次上限,用户选择停止",metadata:{turnsCount:B,toolCallsCount:_.length,duration:Date.now()-Q,tokensUsed:I}}}return{success:!1,error:{type:"max_turns_exceeded",message:`已达到轮次上限 (${L} 轮)。使用 --permission-mode yolo 跳过此限制。`},metadata:{turnsCount:B,toolCallsCount:_.length,duration:Date.now()-Q,tokensUsed:I}}}}}catch(J){if(J instanceof Error&&(J.name==="AbortError"||J.message.includes("aborted")))return{success:!1,error:{type:"aborted",message:"任务已被用户中止"},metadata:{turnsCount:0,toolCallsCount:0,duration:Date.now()-Q}};return S.error("Enhanced chat processing error:",J),{success:!1,error:{type:"api_error",message:`处理消息时发生错误: ${J instanceof Error?J.message:"未知错误"}`,details:J},metadata:{turnsCount:0,toolCallsCount:0,duration:Date.now()-Q}}}}async runAgenticLoop($,Y,Z){if(!this.isInitialized)throw Error("Agent未初始化");let X={messages:Y.messages,userId:Y.userId||"subagent",sessionId:Y.sessionId||`subagent_${Date.now()}`,workspaceRoot:Y.workspaceRoot||process.cwd(),signal:Y.signal,confirmationHandler:Y.confirmationHandler};return await this.runLoop($,X,Z)}async chatWithSystem($,Y){if(!this.isInitialized)throw Error("Agent未初始化");let Z=[{role:"system",content:$},{role:"user",content:Y}];return(await this.chatService.chat(Z)).content}getActiveTask(){return this.activeTask}getChatService(){return this.chatService}getContextManager(){return this.executionEngine?.getContextManager()}getStats(){return{initialized:this.isInitialized,activeTask:this.activeTask?.id,components:{chatService:this.chatService?"ready":"not_loaded",executionEngine:this.executionEngine?"ready":"not_loaded"}}}getAvailableTools(){return this.executionPipeline?this.executionPipeline.getRegistry().getAll():[]}getToolRegistry(){return this.executionPipeline.getRegistry()}applyToolWhitelist($){let Y=this.executionPipeline.getRegistry(),X=Y.getAll().filter((Q)=>!$.includes(Q.name));for(let Q of X)Y.unregister(Q.name);S.debug(`\uD83D\uDD12 Applied tool whitelist: ${$.join(", ")} (removed ${X.length} tools)`)}getToolStats(){let $=this.getAvailableTools(),Y=new Map;return $.forEach((Z)=>{let X=Y.get(Z.kind)||0;Y.set(Z.kind,X+1)}),{totalTools:$.length,toolsByKind:Object.fromEntries(Y),toolNames:$.map((Z)=>Z.name)}}async destroy(){this.log("销毁Agent...");try{this.isInitialized=!1,this.log("Agent已销毁")}catch($){throw this.error("Agent销毁失败",$),$}}generateTaskId(){return`task_${Date.now()}_${Math.random().toString(36).substring(2,9)}`}log($,Y){S.debug(`[MainAgent] ${$}`,Y||"")}error($,Y){S.error(`[MainAgent] ${$}`,Y||"")}async initializeSystemPrompt(){try{let $=this.runtimeOptions.systemPrompt,Y=this.runtimeOptions.appendSystemPrompt,Z=await B4({projectPath:process.cwd(),replaceDefault:$,append:Y,includeEnvironment:!1});if(this.systemPrompt=Z.prompt,this.systemPrompt)this.log("系统提示已加载"),S.debug(`[SystemPrompt] 加载来源: ${Z.sources.filter((X)=>X.loaded).map((X)=>X.name).join(", ")}`)}catch($){this.error("初始化系统提示失败",$)}}getSystemPrompt(){return this.systemPrompt}async checkAndCompactInLoop($,Y,Z,X){if(Z===void 0)return S.debug(`[Agent] [轮次 ${Y}] 压缩检查: 跳过(无历史 usage 数据)`),!1;let Q=this.chatService.getConfig(),J=Q.model,q=Q.maxContextTokens??this.config.maxContextTokens,K=Q.maxOutputTokens??this.config.maxOutputTokens,G=q-K,U=Math.floor(G*0.8);if(S.debug(`[Agent] [轮次 ${Y}] 压缩检查:`,{promptTokens:Z,maxContextTokens:q,maxOutputTokens:K,availableForInput:G,threshold:U,shouldCompact:Z>=U}),Z<U)return!1;let O=Y===0?"[Agent] 触发自动压缩":`[Agent] [轮次 ${Y}] 触发循环内自动压缩`;S.debug(O),X?.(!0);try{let W=await D$.compact($.messages,{trigger:"auto",modelName:J,maxContextTokens:q,apiKey:Q.apiKey,baseURL:Q.baseUrl,actualPreTokens:Z});if(W.success)$.messages=W.compactedMessages,S.debug(`[Agent] [轮次 ${Y}] 压缩完成: ${W.preTokens} → ${W.postTokens} tokens (-${((1-W.postTokens/W.preTokens)*100).toFixed(1)}%)`);else $.messages=W.compactedMessages,S.warn(`[Agent] [轮次 ${Y}] 压缩使用降级策略: ${W.preTokens} → ${W.postTokens} tokens`);try{let F=this.executionEngine?.getContextManager();if(F&&$.sessionId)await F.saveCompaction($.sessionId,W.summary,{trigger:"auto",preTokens:W.preTokens,postTokens:W.postTokens,filesIncluded:W.filesIncluded},null),S.debug(`[Agent] [轮次 ${Y}] 压缩数据已保存到 JSONL`)}catch(F){S.warn(`[Agent] [轮次 ${Y}] 保存压缩数据失败:`,F)}return X?.(!1),!0}catch(W){return X?.(!1),S.error(`[Agent] [轮次 ${Y}] 压缩失败,继续执行`,W),!1}}async registerBuiltinTools(){try{let $=await dZ({sessionId:"default",configDir:QX.join(XX.homedir(),".blade")});S.debug(`\uD83D\uDCE6 Registering ${$.length} builtin tools...`),this.executionPipeline.getRegistry().registerAll($);let Y=this.executionPipeline.getRegistry().getAll().length;S.debug(`✅ Builtin tools registered: ${Y} tools`),S.debug(`[Tools] ${this.executionPipeline.getRegistry().getAll().map((Z)=>Z.name).join(", ")}`),await this.registerMcpTools()}catch($){throw S.error("Failed to register builtin tools:",$),$}}async registerMcpTools(){try{if(this.runtimeOptions.mcpConfig&&this.runtimeOptions.mcpConfig.length>0)await XY(this.runtimeOptions.mcpConfig);let $=V0();if(Object.keys($).length===0){S.debug("\uD83D\uDCE6 No MCP servers configured");return}let Y=t1.getInstance();for(let[X,Q]of Object.entries($))try{S.debug(`\uD83D\uDD0C Connecting to MCP server: ${X}`),await Y.registerServer(X,Q),S.debug(`✅ MCP server "${X}" connected`)}catch(J){S.warn(`⚠️ MCP server "${X}" connection failed:`,J)}let Z=await Y.getAvailableTools();if(Z.length>0)this.executionPipeline.getRegistry().registerAll(Z),S.debug(`✅ Registered ${Z.length} MCP tools`),S.debug(`[MCP Tools] ${Z.map((X)=>X.name).join(", ")}`)}catch($){S.warn("Failed to register MCP tools:",$)}}async loadSubagents(){if(g1.getAllNames().length>0){S.debug(`\uD83D\uDCE6 Subagents already loaded: ${g1.getAllNames().join(", ")}`);return}try{let $=g1.loadFromStandardLocations();if($>0)S.debug(`✅ Loaded ${$} subagents: ${g1.getAllNames().join(", ")}`);else S.debug("\uD83D\uDCE6 No subagents configured")}catch($){S.warn("Failed to load subagents:",$)}}async discoverSkills(){try{let $=await o2({cwd:process.cwd()});if($.skills.length>0)S.debug(`✅ Discovered ${$.skills.length} skills: ${$.skills.map((Y)=>Y.name).join(", ")}`);else S.debug("\uD83D\uDCE6 No skills configured");for(let Y of $.errors)S.warn(`⚠️ Skill loading error at ${Y.path}: ${Y.error}`)}catch($){S.warn("Failed to discover skills:",$)}}applySkillToolRestrictions($){if(!this.activeSkillContext?.allowedTools)return $;let Y=this.activeSkillContext.allowedTools;S.debug(`\uD83D\uDD12 Applying Skill tool restrictions: ${Y.join(", ")}`);let Z=$.filter((X)=>{return Y.some((Q)=>{if(Q===X.name)return!0;let J=Q.match(/^(\w+)\(.*\)$/);if(J&&J[1]===X.name)return!0;return!1})});return S.debug(`\uD83D\uDD12 Filtered tools: ${Z.map((X)=>X.name).join(", ")} (${Z.length}/${$.length})`),Z}clearSkillContext(){if(this.activeSkillContext)S.debug(`\uD83C\uDFAF Skill "${this.activeSkillContext.skillName}" deactivated`),this.activeSkillContext=void 0}async processAtMentionsForContent($){if(!this.attachmentCollector)return $;if(typeof $==="string")return this.processAtMentions($);let Y=[];for(let X of $)if(X.type==="text")Y.push(X.text);if(Y.length===0)return $;let Z=Y.join(`
1297
+ `);try{let X=await this.attachmentCollector.collect(Z);if(X.length===0)return $;S.debug(`✅ Processed ${X.length} @ file mentions in multimodal message`);let Q=this.buildAttachmentText(X);if(!Q)return $;return[...$,{type:"text",text:Q}]}catch(X){return S.error("Failed to process @ mentions in multimodal message:",X),$}}buildAttachmentText($){let Y=[],Z=[];for(let Q of $)if(Q.type==="file"){let J=Q.metadata?.lineRange?` (lines ${Q.metadata.lineRange.start}${Q.metadata.lineRange.end?`-${Q.metadata.lineRange.end}`:""})`:"";Y.push(`<file path="${Q.path}"${J?` range="${J}"`:""}>`,Q.content,"</file>")}else if(Q.type==="directory")Y.push(`<directory path="${Q.path}">`,Q.content,"</directory>");else if(Q.type==="error")Z.push(`- @${Q.path}: ${Q.error}`);let X="";if(Y.length>0)X+=`
1296
1298
 
1297
1299
  <system-reminder>
1298
1300
  `,X+=`The following files were mentioned with @ syntax:
@@ -1303,7 +1305,7 @@ Please continue the conversation from where we left it off without asking the us
1303
1305
 
1304
1306
  ⚠️ Some files could not be loaded:
1305
1307
  `,X+=Z.join(`
1306
- `);return X}async processAtMentions($){if(!this.attachmentCollector)return $;try{let Y=await this.attachmentCollector.collect($);if(Y.length===0)return $;return T.debug(`✅ Processed ${Y.length} @ file mentions`),this.appendAttachments($,Y)}catch(Y){return T.error("Failed to process @ mentions:",Y),$}}appendAttachments($,Y){let Z=[],X=[];for(let J of Y)if(J.type==="file"){let q=J.metadata?.lineRange?` (lines ${J.metadata.lineRange.start}${J.metadata.lineRange.end?`-${J.metadata.lineRange.end}`:""})`:"";Z.push(`<file path="${J.path}"${q?` range="${q}"`:""}>`,J.content,"</file>")}else if(J.type==="directory")Z.push(`<directory path="${J.path}">`,J.content,"</directory>");else if(J.type==="error")X.push(`- @${J.path}: ${J.error}`);let Q=$;if(Z.length>0)Q+=`
1308
+ `);return X}async processAtMentions($){if(!this.attachmentCollector)return $;try{let Y=await this.attachmentCollector.collect($);if(Y.length===0)return $;return S.debug(`✅ Processed ${Y.length} @ file mentions`),this.appendAttachments($,Y)}catch(Y){return S.error("Failed to process @ mentions:",Y),$}}appendAttachments($,Y){let Z=[],X=[];for(let J of Y)if(J.type==="file"){let q=J.metadata?.lineRange?` (lines ${J.metadata.lineRange.start}${J.metadata.lineRange.end?`-${J.metadata.lineRange.end}`:""})`:"";Z.push(`<file path="${J.path}"${q?` range="${q}"`:""}>`,J.content,"</file>")}else if(J.type==="directory")Z.push(`<directory path="${J.path}">`,J.content,"</directory>");else if(J.type==="error")X.push(`- @${J.path}: ${J.error}`);let Q=$;if(Z.length>0)Q+=`
1307
1309
 
1308
1310
  <system-reminder>
1309
1311
  `,Q+=`The following files were mentioned with @ syntax:
@@ -1314,30 +1316,30 @@ Please continue the conversation from where we left it off without asking the us
1314
1316
 
1315
1317
  ⚠️ Some files could not be loaded:
1316
1318
  `,Q+=X.join(`
1317
- `);return Q}}var T;var T2=b(()=>{_$();Z8();z0();V1();g5();L$();o5();ZY();Y8();j2();N1();IZ();PZ();TZ();N8();T4();xZ();P$();T=n("Agent")});function T1($){if($.acp)return{sendMessage:(Y)=>$.acp.sendMessage(`• ${Y}
1319
+ `);return Q}}var S;var C2=b(()=>{_$();O9();L0();w1();QY();b$();zY();AY();W9();v2();A1();mZ();nZ();oZ();I9();C4();ZX();k$();S=c("Agent")});function C1($){if($.acp)return{sendMessage:(Y)=>$.acp.sendMessage(`• ${Y}
1318
1320
 
1319
- `),sendToolStart:$.acp.sendToolStart,sendToolResult:$.acp.sendToolResult};return{sendMessage:(Y)=>_0().addAssistantMessage(Y),sendToolStart:void 0,sendToolResult:void 0}}var h2=b(()=>{N1()});import MW from"node:os";import $X from"node:path";var YX;var ZX=b(()=>{P$();h2();YX={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($,Y){let Z=$[0],X=T1(Y);if(!Z)return{success:!0,message:"show_agents_manager",data:{action:"show_agents_manager"}};if(Z==="list"){let J=x1.getAllNames().map((U)=>x1.getSubagent(U)).filter((U)=>U!==void 0);if(J.length===0){let U=`\uD83D\uDCCB **Agents 管理**
1321
+ `),sendToolStart:$.acp.sendToolStart,sendToolResult:$.acp.sendToolResult};return{sendMessage:(Y)=>_0().addAssistantMessage(Y),sendToolStart:void 0,sendToolResult:void 0}}var u2=b(()=>{A1()});import rW from"node:os";import LX from"node:path";var wX;var AX=b(()=>{k$();u2();wX={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($,Y){let Z=$[0],X=C1(Y);if(!Z)return{success:!0,message:"show_agents_manager",data:{action:"show_agents_manager"}};if(Z==="list"){let J=g1.getAllNames().map((W)=>g1.getSubagent(W)).filter((W)=>W!==void 0);if(J.length===0){let W=`\uD83D\uDCCB **Agents 管理**
1320
1322
 
1321
1323
  `+`❌ 没有找到任何 agent 配置
1322
1324
 
1323
1325
  `+`**配置文件位置:**
1324
- `+"- 项目级: `.blade/agents/`\n"+"- 用户级: `~/.blade/agents/`\n\n"+"\uD83D\uDCA1 使用 `/agents` 打开管理对话框";return X.sendMessage(U),{success:!0,message:"No agents found"}}let q=$X.join(process.cwd(),".blade","agents"),G=$X.join(MW.homedir(),".blade","agents"),K=J.filter((U)=>U.configPath?.startsWith(q)),W=J.filter((U)=>U.configPath?.startsWith(G)),O=`\uD83D\uDCCB **Agents 管理**
1326
+ `+"- 项目级: `.blade/agents/`\n"+"- 用户级: `~/.blade/agents/`\n\n"+"\uD83D\uDCA1 使用 `/agents` 打开管理对话框";return X.sendMessage(W),{success:!0,message:"No agents found"}}let q=LX.join(process.cwd(),".blade","agents"),K=LX.join(rW.homedir(),".blade","agents"),G=J.filter((W)=>W.configPath?.startsWith(q)),U=J.filter((W)=>W.configPath?.startsWith(K)),O=`\uD83D\uDCCB **Agents 管理**
1325
1327
 
1326
1328
  找到 **${J.length}** 个 agent:
1327
1329
 
1328
- `;if(K.length>0){O+=`**项目级** (.blade/agents/):
1329
- `;for(let U of K){if(O+=`
1330
- • **${U.name}**
1331
- `,O+=` ${U.description}
1332
- `,U.tools&&U.tools.length>0)O+=` 工具: ${U.tools.join(", ")}
1333
- `;if(U.color)O+=` 颜色: ${U.color}
1330
+ `;if(G.length>0){O+=`**项目级** (.blade/agents/):
1331
+ `;for(let W of G){if(O+=`
1332
+ • **${W.name}**
1333
+ `,O+=` ${W.description}
1334
+ `,W.tools&&W.tools.length>0)O+=` 工具: ${W.tools.join(", ")}
1335
+ `;if(W.color)O+=` 颜色: ${W.color}
1334
1336
  `}O+=`
1335
- `}if(W.length>0){O+=`**用户级** (~/.blade/agents/):
1336
- `;for(let U of W){if(O+=`
1337
- • **${U.name}**
1338
- `,O+=` ${U.description}
1339
- `,U.tools&&U.tools.length>0)O+=` 工具: ${U.tools.join(", ")}
1340
- `;if(U.color)O+=` 颜色: ${U.color}
1337
+ `}if(U.length>0){O+=`**用户级** (~/.blade/agents/):
1338
+ `;for(let W of U){if(O+=`
1339
+ • **${W.name}**
1340
+ `,O+=` ${W.description}
1341
+ `,W.tools&&W.tools.length>0)O+=` 工具: ${W.tools.join(", ")}
1342
+ `;if(W.color)O+=` 颜色: ${W.color}
1341
1343
  `}O+=`
1342
1344
  `}return O+="\n\uD83D\uDCA1 使用 `/agents` 打开管理对话框",X.sendMessage(O),{success:!0,message:`Listed ${J.length} agents`}}if(Z==="help"){let J=`\uD83D\uDCCB **Agents 管理帮助**
1343
1345
 
@@ -1361,20 +1363,20 @@ Please continue the conversation from where we left it off without asking the us
1361
1363
  `+"- 项目级 (`.blade/agents/`) - 最高优先级\n"+"- 用户级 (`~/.blade/agents/`) - 较低优先级\n\n"+`**可用工具:**
1362
1364
  `+"- `Glob` - 文件搜索\n"+"- `Grep` - 内容搜索\n"+"- `Read` - 读取文件\n"+"- `Write` - 写入文件\n"+"- `Edit` - 编辑文件\n"+"- `Bash` - 执行命令\n"+"- 省略 `tools` 字段 = 继承所有工具\n\n"+"\uD83D\uDCA1 **提示:** 创建文件后,重启 Blade 使配置生效";return X.sendMessage(J),{success:!0,message:"Help displayed"}}if(Z==="create")return{success:!0,message:"show_agent_creation_wizard",data:{action:"show_agent_creation_wizard"}};let Q=`❌ 未知子命令: \`${Z}\`
1363
1365
 
1364
- `+"使用 `/agents help` 查看可用命令";return X.sendMessage(Q),{success:!1,error:`Unknown subcommand: ${Z}`}}}});async function jW($,Y){let Z=T1(Y);try{let X=C1(),Q=N$();if(!X||!Q)return{success:!1,error:"配置未初始化"};let J=e().session,q=J.messages,G=J.sessionId;if(!q||q.length===0)return Z.sendMessage("⚠️ 当前会话没有消息,无需压缩"),{success:!1,error:"没有消息需要压缩"};let K=q.map((H)=>({role:H.role,content:H.content})),W=_2.countTokens(K,Q.model),O=Q.maxContextTokens??X.maxContextTokens,U=(W/O*100).toFixed(1);if(Z.sendMessage(`\uD83D\uDCCA **当前上下文统计**
1365
- • 消息数量: ${K.length}
1366
- • Token 数量: ${W.toLocaleString()}
1366
+ `+"使用 `/agents help` 查看可用命令";return X.sendMessage(Q),{success:!1,error:`Unknown subcommand: ${Z}`}}}});async function aW($,Y){let Z=C1(Y);try{let X=x1(),Q=w$();if(!X||!Q)return{success:!1,error:"配置未初始化"};let J=$1().session,q=J.messages,K=J.sessionId;if(!q||q.length===0)return Z.sendMessage("⚠️ 当前会话没有消息,无需压缩"),{success:!1,error:"没有消息需要压缩"};let G=q.map((H)=>({role:H.role,content:H.content})),U=_2.countTokens(G,Q.model),O=Q.maxContextTokens??X.maxContextTokens,W=(U/O*100).toFixed(1);if(Z.sendMessage(`\uD83D\uDCCA **当前上下文统计**
1367
+ • 消息数量: ${G.length}
1368
+ • Token 数量: ${U.toLocaleString()}
1367
1369
  • Token 限制: ${O.toLocaleString()}
1368
- • 使用率: ${U}%`),W<O*0.5)return Z.sendMessage(`\uD83D\uDCA1 提示: 当前 token 使用率较低(${U}%),可以暂时不压缩。
1369
- 系统会在达到 80% 时自动触发压缩。`),{success:!0,message:"无需压缩"};Z.sendMessage("⏳ **正在压缩上下文...**");let F=await b$.compact(K,{trigger:"manual",modelName:Q.model,maxContextTokens:O,apiKey:Q.apiKey,baseURL:Q.baseUrl});if(F.success){try{if(G)await new b6().saveCompaction(G,F.summary,{trigger:"manual",preTokens:F.preTokens,postTokens:F.postTokens,filesIncluded:F.filesIncluded},null),console.log("[/compact] 压缩数据已保存到 JSONL")}catch(_){console.warn("[/compact] 保存压缩数据失败:",_)}let H=`✅ **压缩完成!**
1370
+ • 使用率: ${W}%`),U<O*0.5)return Z.sendMessage(`\uD83D\uDCA1 提示: 当前 token 使用率较低(${W}%),可以暂时不压缩。
1371
+ 系统会在达到 80% 时自动触发压缩。`),{success:!0,message:"无需压缩"};Z.sendMessage("⏳ **正在压缩上下文...**");let F=await D$.compact(G,{trigger:"manual",modelName:Q.model,maxContextTokens:O,apiKey:Q.apiKey,baseURL:Q.baseUrl});if(F.success){try{if(K)await new D6().saveCompaction(K,F.summary,{trigger:"manual",preTokens:F.preTokens,postTokens:F.postTokens,filesIncluded:F.filesIncluded},null),console.log("[/compact] 压缩数据已保存到 JSONL")}catch(z){console.warn("[/compact] 保存压缩数据失败:",z)}let H=`✅ **压缩完成!**
1370
1372
 
1371
1373
  \uD83D\uDCC9 **Token 变化**
1372
1374
  • 压缩前: ${F.preTokens.toLocaleString()} tokens
1373
1375
  • 压缩后: ${F.postTokens.toLocaleString()} tokens
1374
1376
  • 压缩率: ${((1-F.postTokens/F.preTokens)*100).toFixed(1)}%`;if(F.filesIncluded.length>0)H+=`
1375
1377
 
1376
- \uD83D\uDCC1 **包含文件** (${F.filesIncluded.length})`,F.filesIncluded.forEach((_,z)=>{H+=`
1377
- ${z+1}. ${_}`});return H+=`
1378
+ \uD83D\uDCC1 **包含文件** (${F.filesIncluded.length})`,F.filesIncluded.forEach((z,N)=>{H+=`
1379
+ ${N+1}. ${z}`});return H+=`
1378
1380
 
1379
1381
  \uD83D\uDCA1 对话历史已压缩,但完整记录仍保存在会话文件中。`,Z.sendMessage(H),{success:!0,message:"compact_completed",data:{compactedMessages:F.compactedMessages,boundaryMessage:F.boundaryMessage,summaryMessage:F.summaryMessage,preTokens:F.preTokens,postTokens:F.postTokens,filesIncluded:F.filesIncluded}}}else return Z.sendMessage(`⚠️ **压缩使用降级策略**
1380
1382
 
@@ -1383,32 +1385,32 @@ Please continue the conversation from where we left it off without asking the us
1383
1385
  • 压缩后: ${F.postTokens.toLocaleString()} tokens
1384
1386
 
1385
1387
  \uD83D\uDCA1 由于压缩过程出现错误,已使用简单截断策略。
1386
- 错误信息: ${F.error}`),{success:!1,message:"compact_fallback",error:F.error,data:{compactedMessages:F.compactedMessages,boundaryMessage:F.boundaryMessage,summaryMessage:F.summaryMessage,preTokens:F.preTokens,postTokens:F.postTokens}}}catch(X){let Q=X instanceof Error?X.message:String(X);return Z.sendMessage(`❌ **压缩失败**: ${Q}`),{success:!1,error:Q}}}var yW,XX;var QX=b(()=>{Z8();y7();q4();N1();h2();yW={name:"compact",description:"手动压缩当前会话的上下文",fullDescription:"压缩当前对话历史,生成详细的技术总结,保留最近的消息。压缩后的上下文可以节省 token 使用量,同时保留关键信息。",usage:"/compact",examples:["/compact"],category:"context",handler:jW},XX=yW});function qX($){let Y=Math.floor((Date.now()-$.getTime())/1000);if(Y<60)return`${Y}s ago`;let Z=Math.floor(Y/60);if(Z<60)return`${Z}m ago`;let X=Math.floor(Z/60);if(X<24)return`${X}h ago`;return`${Math.floor(X/24)}d ago`}async function vW($){let Y=n1.getInstance(),Z=A0();if(Object.keys(Z).length===0){$.sendMessage(`\uD83D\uDD0C **MCP 服务器状态**
1388
+ 错误信息: ${F.error}`),{success:!1,message:"compact_fallback",error:F.error,data:{compactedMessages:F.compactedMessages,boundaryMessage:F.boundaryMessage,summaryMessage:F.summaryMessage,preTokens:F.preTokens,postTokens:F.postTokens}}}catch(X){let Q=X instanceof Error?X.message:String(X);return Z.sendMessage(`❌ **压缩失败**: ${Q}`),{success:!1,error:Q}}}var nW,bX;var RX=b(()=>{O9();h7();U4();A1();u2();nW={name:"compact",description:"手动压缩当前会话的上下文",fullDescription:"压缩当前对话历史,生成详细的技术总结,保留最近的消息。压缩后的上下文可以节省 token 使用量,同时保留关键信息。",usage:"/compact",examples:["/compact"],category:"context",handler:aW},bX=nW});function DX($){let Y=Math.floor((Date.now()-$.getTime())/1000);if(Y<60)return`${Y}s ago`;let Z=Math.floor(Y/60);if(Z<60)return`${Z}m ago`;let X=Math.floor(Z/60);if(X<24)return`${X}h ago`;return`${Math.floor(X/24)}d ago`}async function oW($){let Y=t1.getInstance(),Z=V0();if(Object.keys(Z).length===0){$.sendMessage(`\uD83D\uDD0C **MCP 服务器状态**
1387
1389
 
1388
1390
  ⚠️ 暂无配置的 MCP 服务器
1389
1391
 
1390
- \uD83D\uDCA1 使用 \`blade mcp add\` 命令添加 MCP 服务器`);return}$.sendMessage("\uD83D\uDD0D 正在检查 MCP 服务器状态...");let X=Object.entries(Z).map(async([Q,J])=>{try{let q=Y.getServerStatus(Q);if(!q)await Y.registerServer(Q,J),q=Y.getServerStatus(Q);else if(q.status==="disconnected")await Y.connectServer(Q);return{name:Q,config:J,serverInfo:Y.getServerStatus(Q)}}catch(q){return{name:Q,config:J,serverInfo:null,error:q}}});await Promise.all(X),EW($,Y.getAllServers())}function EW($,Y){let Z=`\uD83D\uDD0C **MCP 服务器状态**
1392
+ \uD83D\uDCA1 使用 \`blade mcp add\` 命令添加 MCP 服务器`);return}$.sendMessage("\uD83D\uDD0D 正在检查 MCP 服务器状态...");let X=Object.entries(Z).map(async([Q,J])=>{try{let q=Y.getServerStatus(Q);if(!q)await Y.registerServer(Q,J),q=Y.getServerStatus(Q);else if(q.status==="disconnected")await Y.connectServer(Q);return{name:Q,config:J,serverInfo:Y.getServerStatus(Q)}}catch(q){return{name:Q,config:J,serverInfo:null,error:q}}});await Promise.all(X),sW($,Y.getAllServers())}function sW($,Y){let Z=`\uD83D\uDD0C **MCP 服务器状态**
1391
1393
 
1392
- `,X=0,Q=0,J=0;for(let[q,G]of Y){let{config:K,status:W,connectedAt:O,lastError:U,tools:F}=G,H=W==="connected"?"✓":"✗",_=W==="connected"?"Connected":"Disconnected";if(W==="connected")X++,J+=F.length;else Q++;if(Z+=`\uD83D\uDCE6 **${q}**
1393
- `,Z+=` 状态: ${H} ${_}
1394
- `,Z+=` 类型: ${K.type}
1395
- `,K.type==="stdio")Z+=` 命令: ${K.command}${K.args?.length?" "+K.args.join(" "):""}
1396
- `;else Z+=` URL: ${K.url}
1394
+ `,X=0,Q=0,J=0;for(let[q,K]of Y){let{config:G,status:U,connectedAt:O,lastError:W,tools:F}=K,H=U==="connected"?"✓":"✗",z=U==="connected"?"Connected":"Disconnected";if(U==="connected")X++,J+=F.length;else Q++;if(Z+=`\uD83D\uDCE6 **${q}**
1395
+ `,Z+=` 状态: ${H} ${z}
1396
+ `,Z+=` 类型: ${G.type}
1397
+ `,G.type==="stdio")Z+=` 命令: ${G.command}${G.args?.length?" "+G.args.join(" "):""}
1398
+ `;else Z+=` URL: ${G.url}
1397
1399
  `;if(Z+=` 工具: ${F.length} 个
1398
- `,O&&W==="connected")Z+=` 连接时间: ${qX(O)}
1399
- `;if(U&&W!=="connected")Z+=` 错误: ${U.message}
1400
+ `,O&&U==="connected")Z+=` 连接时间: ${DX(O)}
1401
+ `;if(W&&U!=="connected")Z+=` 错误: ${W.message}
1400
1402
  `;Z+=`
1401
1403
  `}Z+=`**总计:**
1402
1404
  `,Z+=`- 服务器: ${Y.size} 个 (${X} 连接, ${Q} 断开)
1403
1405
  `,Z+=`- 可用工具: ${J} 个
1404
1406
 
1405
- `,Z+="\uD83D\uDCA1 使用 `/mcp <server-name>` 查看详细信息\n",Z+="\uD83D\uDCA1 使用 `/mcp tools` 查看所有工具",$.sendMessage(Z)}async function PW($,Y){let Z=n1.getInstance(),Q=A0()[Y];if(!Q){$.sendMessage(`❌ 服务器 "${Y}" 不存在
1407
+ `,Z+="\uD83D\uDCA1 使用 `/mcp <server-name>` 查看详细信息\n",Z+="\uD83D\uDCA1 使用 `/mcp tools` 查看所有工具",$.sendMessage(Z)}async function tW($,Y){let Z=t1.getInstance(),Q=V0()[Y];if(!Q){$.sendMessage(`❌ 服务器 "${Y}" 不存在
1406
1408
 
1407
- \uD83D\uDCA1 使用 \`/mcp\` 查看所有可用服务器`);return}try{let J=Z.getServerStatus(Y);if(!J)$.sendMessage(`\uD83D\uDD0D 正在连接 ${Y}...`),await Z.registerServer(Y,Q),J=Z.getServerStatus(Y);else if(J.status==="disconnected")$.sendMessage(`\uD83D\uDD0D 正在重新连接 ${Y}...`),await Z.connectServer(Y),J=Z.getServerStatus(Y);if(J)TW($,Y,J);else JX($,Y,Q)}catch(J){JX($,Y,Q),$.sendMessage(`
1408
- ⚠️ 连接失败: ${J instanceof Error?J.message:"未知错误"}`)}}function TW($,Y,Z){let{config:X,status:Q,connectedAt:J,lastError:q,tools:G}=Z,K=Q==="connected"?"✓":"✗",W=Q==="connected"?"Connected":"Disconnected",O=`\uD83D\uDCE6 **${Y}**
1409
+ \uD83D\uDCA1 使用 \`/mcp\` 查看所有可用服务器`);return}try{let J=Z.getServerStatus(Y);if(!J)$.sendMessage(`\uD83D\uDD0D 正在连接 ${Y}...`),await Z.registerServer(Y,Q),J=Z.getServerStatus(Y);else if(J.status==="disconnected")$.sendMessage(`\uD83D\uDD0D 正在重新连接 ${Y}...`),await Z.connectServer(Y),J=Z.getServerStatus(Y);if(J)eW($,Y,J);else VX($,Y,Q)}catch(J){VX($,Y,Q),$.sendMessage(`
1410
+ ⚠️ 连接失败: ${J instanceof Error?J.message:"未知错误"}`)}}function eW($,Y,Z){let{config:X,status:Q,connectedAt:J,lastError:q,tools:K}=Z,G=Q==="connected"?"✓":"✗",U=Q==="connected"?"Connected":"Disconnected",O=`\uD83D\uDCE6 **${Y}**
1409
1411
 
1410
1412
  `;if(O+=`**连接状态:**
1411
- `,O+=` ${K} ${W}`,J&&Q==="connected")O+=` (连接于 ${qX(J)})`;if(O+=`
1413
+ `,O+=` ${G} ${U}`,J&&Q==="connected")O+=` (连接于 ${DX(J)})`;if(O+=`
1412
1414
 
1413
1415
  `,O+=`**配置信息:**
1414
1416
  `,O+=` 类型: ${X.type}
@@ -1419,14 +1421,14 @@ Please continue the conversation from where we left it off without asking the us
1419
1421
  `,X.headers&&Object.keys(X.headers).length>0)O+=` Headers: ${Object.keys(X.headers).length} 个
1420
1422
  `;if(X.timeout)O+=` 超时: ${X.timeout}ms
1421
1423
  `;if(O+=`
1422
- `,Q==="connected")if(O+=`**可用工具 (${G.length}):**
1423
- `,G.length===0)O+=` (无)
1424
- `;else for(let U of G){if(O+=` • ${U.name}`,U.description)O+=` - ${U.description}`;O+=`
1424
+ `,Q==="connected")if(O+=`**可用工具 (${K.length}):**
1425
+ `,K.length===0)O+=` (无)
1426
+ `;else for(let W of K){if(O+=` • ${W.name}`,W.description)O+=` - ${W.description}`;O+=`
1425
1427
  `}else O+=`**工具:**
1426
1428
  ⚠️ 服务器未连接,无法获取工具列表
1427
1429
  `;if(q)O+=`
1428
1430
  **错误信息:**
1429
- `,O+=` ${q.message}`;$.sendMessage(O)}function JX($,Y,Z){let X=`\uD83D\uDCE6 **${Y}**
1431
+ `,O+=` ${q.message}`;$.sendMessage(O)}function VX($,Y,Z){let X=`\uD83D\uDCE6 **${Y}**
1430
1432
 
1431
1433
  `;if(X+=`**连接状态:**
1432
1434
  `,X+=` ⏸️ 未启动 (等待 Agent 连接)
@@ -1440,24 +1442,24 @@ Please continue the conversation from where we left it off without asking the us
1440
1442
  `,Z.headers&&Object.keys(Z.headers).length>0)X+=` Headers: ${Object.keys(Z.headers).join(", ")}
1441
1443
  `;if(Z.timeout)X+=` 超时: ${Z.timeout}ms
1442
1444
  `;X+=`
1443
- \uD83D\uDCA1 服务器将在 Agent 启动时自动连接`,$.sendMessage(X)}async function kW($){let Y=n1.getInstance(),Z=A0();if(Object.keys(Z).length===0){$.sendMessage(`\uD83D\uDD27 **可用的 MCP 工具**
1445
+ \uD83D\uDCA1 服务器将在 Agent 启动时自动连接`,$.sendMessage(X)}async function $O($){let Y=t1.getInstance(),Z=V0();if(Object.keys(Z).length===0){$.sendMessage(`\uD83D\uDD27 **可用的 MCP 工具**
1444
1446
 
1445
1447
  ⚠️ 暂无配置的 MCP 服务器
1446
1448
 
1447
- \uD83D\uDCA1 使用 \`blade mcp add\` 命令添加 MCP 服务器`);return}$.sendMessage("\uD83D\uDD0D 正在检查 MCP 服务器并获取工具列表...");let X=Object.entries(Z).map(async([G,K])=>{try{let W=Y.getServerStatus(G);if(!W)await Y.registerServer(G,K),W=Y.getServerStatus(G);else if(W.status==="disconnected")await Y.connectServer(G);return{name:G,config:K,serverInfo:Y.getServerStatus(G)}}catch(W){return{name:G,config:K,serverInfo:null,error:W}}});await Promise.all(X);let Q=Y.getAllServers(),J=`\uD83D\uDD27 **可用的 MCP 工具**
1449
+ \uD83D\uDCA1 使用 \`blade mcp add\` 命令添加 MCP 服务器`);return}$.sendMessage("\uD83D\uDD0D 正在检查 MCP 服务器并获取工具列表...");let X=Object.entries(Z).map(async([K,G])=>{try{let U=Y.getServerStatus(K);if(!U)await Y.registerServer(K,G),U=Y.getServerStatus(K);else if(U.status==="disconnected")await Y.connectServer(K);return{name:K,config:G,serverInfo:Y.getServerStatus(K)}}catch(U){return{name:K,config:G,serverInfo:null,error:U}}});await Promise.all(X);let Q=Y.getAllServers(),J=`\uD83D\uDD27 **可用的 MCP 工具**
1448
1450
 
1449
- `,q=0;for(let[G,K]of Q){let{status:W,tools:O}=K;if(J+=`**${G} (${O.length} 个工具):**
1450
- `,W!=="connected"){J+=` ⚠️ 服务器未连接
1451
+ `,q=0;for(let[K,G]of Q){let{status:U,tools:O}=G;if(J+=`**${K} (${O.length} 个工具):**
1452
+ `,U!=="connected"){J+=` ⚠️ 服务器未连接
1451
1453
 
1452
1454
  `;continue}if(O.length===0){J+=` (无)
1453
1455
 
1454
- `;continue}q+=O.length;for(let U of O){if(J+=` • ${U.name}`,U.description){let F=U.description.length>60?U.description.substring(0,57)+"...":U.description;J+=` - ${F}`}J+=`
1456
+ `;continue}q+=O.length;for(let W of O){if(J+=` • ${W.name}`,W.description){let F=W.description.length>60?W.description.substring(0,57)+"...":W.description;J+=` - ${F}`}J+=`
1455
1457
  `}J+=`
1456
- `}J+=`**总计:** ${q} 个工具可用`,$.sendMessage(J)}var SW,GX;var KX=b(()=>{L$();B$();N1();h2();SW={name:"mcp",description:"Display MCP server status and available tools",fullDescription:"显示 MCP 服务器状态、连接信息和可用工具列表",usage:"/mcp [server-name | tools]",category:"MCP",examples:["/mcp - 显示所有服务器概览","/mcp chrome-devtools - 显示特定服务器详情","/mcp tools - 显示所有可用工具"],async handler($,Y){let Z=T1(Y);try{if(console.log("[MCP Command] Received args:",$),$.length===0)return await vW(Z),{success:!0,message:"MCP 服务器概览已显示"};let X=$[0];if(console.log("[MCP Command] Subcommand:",X),X==="tools")return await kW(Z),{success:!0,message:"MCP 工具列表已显示"};return await PW(Z,X),{success:!0,message:`服务器 "${X}" 详情已显示`}}catch(X){return{success:!1,error:`显示 MCP 信息失败: ${X instanceof Error?X.message:"未知错误"}`}}}},GX=SW});async function CW($,Y){return{success:!0,message:"show_permissions_editor",data:{action:"show_permissions_editor"}}}var fW,S4;var k7=b(()=>{fW={name:"permissions",description:"管理项目的本地权限规则",fullDescription:"打开权限管理器,管理 .blade/settings.local.json 中的权限规则",usage:"/permissions",aliases:["perm"],category:"ui",handler:CW},S4=fW});import{readdir as UX,readFile as WX}from"node:fs/promises";import*as C4 from"node:path";class X2{static async listSessions(){let $=[],Y=C4.join(o2(),"projects");try{let Z=await UX(Y,{withFileTypes:!0});for(let X of Z){if(!X.isDirectory())continue;let Q=C4.join(Y,X.name),J=HY(X.name),G=(await UX(Q)).filter((K)=>K.endsWith(".jsonl"));for(let K of G){let W=C4.join(Q,K),O=K.replace(".jsonl","");try{let U=await this.extractMetadata(W,O,J);$.push(U)}catch(U){Y$.warn(`[SessionService] 跳过损坏的会话文件: ${W}`,U)}}}return $.sort((X,Q)=>new Date(Q.lastMessageTime).getTime()-new Date(X.lastMessageTime).getTime()),$}catch(Z){return Y$.error("[SessionService] 列出会话失败:",Z),[]}}static async extractMetadata($,Y,Z){let Q=(await WX($,"utf-8")).trim().split(`
1457
- `).filter((K)=>K.trim());if(Q.length===0)throw Error("空的 JSONL 文件");let J=JSON.parse(Q[0]),q=JSON.parse(Q[Q.length-1]),G=Q.some((K)=>{try{let W=JSON.parse(K);return W.type==="tool_result"&&W.toolResult?.error}catch{return!1}});return{sessionId:Y,projectPath:Z,gitBranch:J.gitBranch,messageCount:Q.length,firstMessageTime:J.timestamp,lastMessageTime:q.timestamp,hasErrors:G,filePath:$}}static async loadSession($,Y){try{if(Y){let Q=this.getSessionFilePath(Y,$);return await this.loadSessionFromFile(Q)}let X=(await this.listSessions()).find((Q)=>Q.sessionId===$);if(!X)throw Error(`未找到会话: ${$}`);return await this.loadSessionFromFile(X.filePath)}catch(Z){throw Y$.error(`[SessionService] 加载会话失败 (${$}):`,Z),Z}}static async loadSessionFromFile($){let X=(await WX($,"utf-8")).trim().split(`
1458
- `).filter((Q)=>Q.trim()).map((Q)=>JSON.parse(Q));return this.convertJSONLToMessages(X)}static convertJSONLToMessages($){let Y=[],Z=-1;for(let Q=$.length-1;Q>=0;Q--)if($[Q].subtype==="compact_boundary"){Z=Q,Y$.debug(`[SessionService] 检测到压缩边界 at index ${Q}`);break}let X=Z>=0?Z:0;for(let Q=X;Q<$.length;Q++){let J=$[Q];if(J.subtype==="compact_boundary"){Y$.debug("[SessionService] 跳过 compact_boundary 消息");continue}switch(J.type){case"user":case"assistant":case"system":{let q={role:J.message.role,content:typeof J.message.content==="string"?J.message.content:JSON.stringify(J.message.content)};if(J.isCompactSummary)Y$.debug("[SessionService] 加载压缩总结消息");Y.push(q);break}case"tool_result":if(J.toolResult){let q=J.toolResult.error?`Error: ${J.toolResult.error}`:typeof J.toolResult.output==="string"?J.toolResult.output:JSON.stringify(J.toolResult.output);Y.push({role:"tool",content:q,tool_call_id:J.toolResult.id,name:J.tool?.name})}break;case"tool_use":break;default:break}}if(Z>=0)Y$.debug(`[SessionService] 会话已压缩,跳过前 ${Z} 条历史,加载 ${Y.length} 条消息`);return Y}static getSessionFilePath($,Y){return R0($,Y)}}var Y$;var f4=b(()=>{B6();V1();Y$=n("Service")});var hW,OX;var FX=b(()=>{f4();N1();h2();hW={name:"resume",description:"Resume a conversation",fullDescription:"恢复历史会话。可以指定 sessionId 直接恢复,或不带参数打开会话选择器",usage:"/resume [sessionId]",aliases:["r"],category:"Session",examples:["/resume - 打开会话选择器","/resume abc123xyz - 直接恢复指定的会话"],async handler($,Y){let Z=T1(Y),X=_0().restoreSession;if($.length>0){let Q=$[0];try{let J=await X2.loadSession(Q);if(J.length===0)return Z.sendMessage(`❌ 会话 \`${Q}\` 为空或无法加载`),{success:!1,error:"会话为空"};let q=J.filter((G)=>G.role!=="tool").map((G,K)=>({id:`restored-${Date.now()}-${K}`,role:G.role,content:typeof G.content==="string"?G.content:JSON.stringify(G.content),timestamp:Date.now()-(J.length-K)*1000}));return X(Q,q),Z.sendMessage(`✅ 已恢复会话 \`${Q}\`
1458
+ `}J+=`**总计:** ${q} 个工具可用`,$.sendMessage(J)}var YO,IX;var MX=b(()=>{b$();A$();A1();u2();YO={name:"mcp",description:"Display MCP server status and available tools",fullDescription:"显示 MCP 服务器状态、连接信息和可用工具列表",usage:"/mcp [server-name | tools]",category:"MCP",examples:["/mcp - 显示所有服务器概览","/mcp chrome-devtools - 显示特定服务器详情","/mcp tools - 显示所有可用工具"],async handler($,Y){let Z=C1(Y);try{if(console.log("[MCP Command] Received args:",$),$.length===0)return await oW(Z),{success:!0,message:"MCP 服务器概览已显示"};let X=$[0];if(console.log("[MCP Command] Subcommand:",X),X==="tools")return await $O(Z),{success:!0,message:"MCP 工具列表已显示"};return await tW(Z,X),{success:!0,message:`服务器 "${X}" 详情已显示`}}catch(X){return{success:!1,error:`显示 MCP 信息失败: ${X instanceof Error?X.message:"未知错误"}`}}}},IX=YO});async function ZO($,Y){return{success:!0,message:"show_permissions_editor",data:{action:"show_permissions_editor"}}}var XO,h4;var d7=b(()=>{XO={name:"permissions",description:"管理项目的本地权限规则",fullDescription:"打开权限管理器,管理 .blade/settings.local.json 中的权限规则",usage:"/permissions",aliases:["perm"],category:"ui",handler:ZO},h4=XO});import{readdir as jX,readFile as yX}from"node:fs/promises";import*as x4 from"node:path";class q2{static async listSessions(){let $=[],Y=x4.join(e2(),"projects");try{let Z=await jX(Y,{withFileTypes:!0});for(let X of Z){if(!X.isDirectory())continue;let Q=x4.join(Y,X.name),J=PY(X.name),K=(await jX(Q)).filter((G)=>G.endsWith(".jsonl"));for(let G of K){let U=x4.join(Q,G),O=G.replace(".jsonl","");try{let W=await this.extractMetadata(U,O,J);$.push(W)}catch(W){Q$.warn(`[SessionService] 跳过损坏的会话文件: ${U}`,W)}}}return $.sort((X,Q)=>new Date(Q.lastMessageTime).getTime()-new Date(X.lastMessageTime).getTime()),$}catch(Z){return Q$.error("[SessionService] 列出会话失败:",Z),[]}}static async extractMetadata($,Y,Z){let Q=(await yX($,"utf-8")).trim().split(`
1459
+ `).filter((G)=>G.trim());if(Q.length===0)throw Error("空的 JSONL 文件");let J=JSON.parse(Q[0]),q=JSON.parse(Q[Q.length-1]),K=Q.some((G)=>{try{let U=JSON.parse(G);return U.type==="tool_result"&&U.toolResult?.error}catch{return!1}});return{sessionId:Y,projectPath:Z,gitBranch:J.gitBranch,messageCount:Q.length,firstMessageTime:J.timestamp,lastMessageTime:q.timestamp,hasErrors:K,filePath:$}}static async loadSession($,Y){try{if(Y){let Q=this.getSessionFilePath(Y,$);return await this.loadSessionFromFile(Q)}let X=(await this.listSessions()).find((Q)=>Q.sessionId===$);if(!X)throw Error(`未找到会话: ${$}`);return await this.loadSessionFromFile(X.filePath)}catch(Z){throw Q$.error(`[SessionService] 加载会话失败 (${$}):`,Z),Z}}static async loadSessionFromFile($){let X=(await yX($,"utf-8")).trim().split(`
1460
+ `).filter((Q)=>Q.trim()).map((Q)=>JSON.parse(Q));return this.convertJSONLToMessages(X)}static convertJSONLToMessages($){let Y=[],Z=-1;for(let Q=$.length-1;Q>=0;Q--)if($[Q].subtype==="compact_boundary"){Z=Q,Q$.debug(`[SessionService] 检测到压缩边界 at index ${Q}`);break}let X=Z>=0?Z:0;for(let Q=X;Q<$.length;Q++){let J=$[Q];if(J.subtype==="compact_boundary"){Q$.debug("[SessionService] 跳过 compact_boundary 消息");continue}switch(J.type){case"user":case"assistant":case"system":{let q={role:J.message.role,content:typeof J.message.content==="string"?J.message.content:JSON.stringify(J.message.content)};if(J.isCompactSummary)Q$.debug("[SessionService] 加载压缩总结消息");Y.push(q);break}case"tool_result":if(J.toolResult){let q=J.toolResult.error?`Error: ${J.toolResult.error}`:typeof J.toolResult.output==="string"?J.toolResult.output:JSON.stringify(J.toolResult.output);Y.push({role:"tool",content:q,tool_call_id:J.toolResult.id,name:J.tool?.name})}break;case"tool_use":break;default:break}}if(Z>=0)Q$.debug(`[SessionService] 会话已压缩,跳过前 ${Z} 条历史,加载 ${Y.length} 条消息`);return Y}static getSessionFilePath($,Y){return I0($,Y)}}var Q$;var p4=b(()=>{A6();w1();Q$=c("Service")});var QO,EX;var vX=b(()=>{p4();A1();u2();QO={name:"resume",description:"Resume a conversation",fullDescription:"恢复历史会话。可以指定 sessionId 直接恢复,或不带参数打开会话选择器",usage:"/resume [sessionId]",aliases:["r"],category:"Session",examples:["/resume - 打开会话选择器","/resume abc123xyz - 直接恢复指定的会话"],async handler($,Y){let Z=C1(Y),X=_0().restoreSession;if($.length>0){let Q=$[0];try{let J=await q2.loadSession(Q);if(J.length===0)return Z.sendMessage(`❌ 会话 \`${Q}\` 为空或无法加载`),{success:!1,error:"会话为空"};let q=J.filter((K)=>K.role!=="tool").map((K,G)=>({id:`restored-${Date.now()}-${G}`,role:K.role,content:typeof K.content==="string"?K.content:JSON.stringify(K.content),timestamp:Date.now()-(J.length-G)*1000}));return X(Q,q),Z.sendMessage(`✅ 已恢复会话 \`${Q}\`
1459
1461
 
1460
- 共 ${q.length} 条消息已加载,可以继续对话`),{success:!0,message:"session_restored",data:{sessionId:Q,messageCount:q.length}}}catch(J){let q=J instanceof Error?J.message:"未知错误";return Z.sendMessage(`❌ 加载会话失败: ${q}`),{success:!1,error:`加载会话失败: ${q}`}}}try{let Q=await X2.listSessions();if(Q.length===0)return Z.sendMessage("\uD83D\uDCED **没有找到历史会话**\n\n开始一次对话后,会话历史将自动保存到 `~/.blade/projects/`"),{success:!0,message:"没有可用会话"};return{success:!0,message:"show_session_selector",data:{sessions:Q}}}catch(Q){let J=Q instanceof Error?Q.message:"未知错误";return Z.sendMessage(`❌ 获取会话列表失败: ${J}`),{success:!1,error:`获取会话列表失败: ${J}`}}}},OX=hW});import HX from"node:fs/promises";import _X from"node:path";var xW,pW,gW,uW,mW,dW,zX;var NX=b(()=>{q4();N1();X6();ZX();QX();v4();KX();k7();FX();h2();xW={name:"help",description:"Show all available slash commands",fullDescription:"显示所有可用的 slash commands 及其使用方法",usage:"/help",aliases:["h"],async handler($,Y){let Z=T1(Y),X=`\uD83D\uDD27 **可用的 Slash Commands:**
1462
+ 共 ${q.length} 条消息已加载,可以继续对话`),{success:!0,message:"session_restored",data:{sessionId:Q,messageCount:q.length}}}catch(J){let q=J instanceof Error?J.message:"未知错误";return Z.sendMessage(`❌ 加载会话失败: ${q}`),{success:!1,error:`加载会话失败: ${q}`}}}try{let Q=await q2.listSessions();if(Q.length===0)return Z.sendMessage("\uD83D\uDCED **没有找到历史会话**\n\n开始一次对话后,会话历史将自动保存到 `~/.blade/projects/`"),{success:!0,message:"没有可用会话"};return{success:!0,message:"show_session_selector",data:{sessions:Q}}}catch(Q){let J=Q instanceof Error?Q.message:"未知错误";return Z.sendMessage(`❌ 获取会话列表失败: ${J}`),{success:!1,error:`获取会话列表失败: ${J}`}}}},EX=QO});import PX from"node:fs/promises";import TX from"node:path";var JO,qO,KO,GO,UO,WO,SX;var kX=b(()=>{U4();A1();q6();AX();RX();T4();MX();d7();vX();u2();JO={name:"help",description:"Show all available slash commands",fullDescription:"显示所有可用的 slash commands 及其使用方法",usage:"/help",aliases:["h"],async handler($,Y){let Z=C1(Y),X=`\uD83D\uDD27 **可用的 Slash Commands:**
1461
1463
 
1462
1464
  **/init** - 分析当前项目并生成 BLADE.md 配置文件
1463
1465
  **/git** - Git 仓库查询和 AI 辅助 (status/log/diff/review/commit)
@@ -1469,22 +1471,22 @@ Please continue the conversation from where we left it off without asking the us
1469
1471
  **/compact** - 手动压缩上下文,生成总结并节省 token
1470
1472
  **/version** - 显示 Blade Code 版本信息
1471
1473
  **/status** - 显示当前配置状态
1472
- **/permissions** - 管理本地权限规则`,Q=i1.getInstance();if(Q.isInitialized()){if(Q.getAllCommands().length>0){X+=`
1474
+ **/permissions** - 管理本地权限规则`,Q=n1.getInstance();if(Q.isInitialized()){if(Q.getAllCommands().length>0){X+=`
1473
1475
 
1474
1476
  \uD83D\uDCC1 **自定义命令:**
1475
- `;let{project:q,user:G}=Q.getCommandsBySource();if(q.length>0){X+=`
1477
+ `;let{project:q,user:K}=Q.getCommandsBySource();if(q.length>0){X+=`
1476
1478
  **项目命令** (.blade/commands/):
1477
- `;for(let K of q){let W=K.config.argumentHint?` ${K.config.argumentHint}`:"",O=K.config.description||"(无描述)",U=K.namespace?` (${K.namespace})`:"";X+=`**/${K.name}**${W} - ${O}${U}
1478
- `}}if(G.length>0){X+=`
1479
+ `;for(let G of q){let U=G.config.argumentHint?` ${G.config.argumentHint}`:"",O=G.config.description||"(无描述)",W=G.namespace?` (${G.namespace})`:"";X+=`**/${G.name}**${U} - ${O}${W}
1480
+ `}}if(K.length>0){X+=`
1479
1481
  **用户命令** (~/.blade/commands/):
1480
- `;for(let K of G){let W=K.config.argumentHint?` ${K.config.argumentHint}`:"",O=K.config.description||"(无描述)",U=K.namespace?` (${K.namespace})`:"";X+=`**/${K.name}**${W} - ${O}${U}
1482
+ `;for(let G of K){let U=G.config.argumentHint?` ${G.config.argumentHint}`:"",O=G.config.description||"(无描述)",W=G.namespace?` (${G.namespace})`:"";X+=`**/${G.name}**${U} - ${O}${W}
1481
1483
  `}}}}return X+=`
1482
1484
 
1483
1485
  \uD83D\uDCA1 **使用提示:**
1484
1486
  - 在命令前加上 \`/\` 即可执行 slash command
1485
1487
  - 普通消息会发送给 AI 助手处理
1486
1488
  - 按 Ctrl+C 退出程序
1487
- - 按 Ctrl+L 快速清屏`,Z.sendMessage(X),{success:!0,message:"帮助信息已显示"}}},pW={name:"clear",description:"Clear conversation history and free up context",fullDescription:"清除屏幕内容和对话历史",usage:"/clear",aliases:["cls"],async handler($,Y){return{success:!0,message:"clear_screen"}}},gW={name:"version",description:"Show Blade Code version information",fullDescription:"显示 Blade Code 版本信息和构建详情",usage:"/version",aliases:["v"],async handler($,Y){let Z=T1(Y),Q=`\uD83D\uDDE1️ **Blade Code v${O$()}**
1489
+ - 按 Ctrl+L 快速清屏`,Z.sendMessage(X),{success:!0,message:"帮助信息已显示"}}},qO={name:"clear",description:"Clear conversation history and free up context",fullDescription:"清除屏幕内容和对话历史",usage:"/clear",aliases:["cls"],async handler($,Y){return{success:!0,message:"clear_screen"}}},KO={name:"version",description:"Show Blade Code version information",fullDescription:"显示 Blade Code 版本信息和构建详情",usage:"/version",aliases:["v"],async handler($,Y){let Z=C1(Y),Q=`\uD83D\uDDE1️ **Blade Code v${z$()}**
1488
1490
 
1489
1491
  **构建信息:**
1490
1492
  - Node.js: ${process.version}
@@ -1495,11 +1497,11 @@ Please continue the conversation from where we left it off without asking the us
1495
1497
  - \uD83E\uDD16 智能 AI 对话
1496
1498
  - \uD83D\uDD27 项目自动分析
1497
1499
  - \uD83D\uDCDD 自定义系统提示
1498
- - \uD83C\uDFAF 多工具集成支持`;return Z.sendMessage(Q),{success:!0,message:"版本信息已显示"}}},uW={name:"status",description:"Show current configuration status",fullDescription:"显示当前项目配置状态和环境信息",usage:"/status",async handler($,Y){let Z=T1(Y),{cwd:X}=Y;try{let Q=_X.join(X,"BLADE.md"),J=await HX.access(Q).then(()=>!0).catch(()=>!1),q=_X.join(X,"package.json"),G="未知项目",K="未知类型";try{let O=await HX.readFile(q,"utf-8"),U=JSON.parse(O);G=U.name||"未知项目";let F={...U.dependencies,...U.devDependencies};if(F.react)K="React 项目";else if(F.vue)K="Vue 项目";else if(F.next)K="Next.js 项目";else if(F.express)K="Express 项目";else K="Node.js 项目"}catch{}let W=`\uD83D\uDCCA **当前状态**
1500
+ - \uD83C\uDFAF 多工具集成支持`;return Z.sendMessage(Q),{success:!0,message:"版本信息已显示"}}},GO={name:"status",description:"Show current configuration status",fullDescription:"显示当前项目配置状态和环境信息",usage:"/status",async handler($,Y){let Z=C1(Y),{cwd:X}=Y;try{let Q=TX.join(X,"BLADE.md"),J=await PX.access(Q).then(()=>!0).catch(()=>!1),q=TX.join(X,"package.json"),K="未知项目",G="未知类型";try{let O=await PX.readFile(q,"utf-8"),W=JSON.parse(O);K=W.name||"未知项目";let F={...W.dependencies,...W.devDependencies};if(F.react)G="React 项目";else if(F.vue)G="Vue 项目";else if(F.next)G="Next.js 项目";else if(F.express)G="Express 项目";else G="Node.js 项目"}catch{}let U=`\uD83D\uDCCA **当前状态**
1499
1501
 
1500
1502
  **项目信息:**
1501
- - 名称: ${G}
1502
- - 类型: ${K}
1503
+ - 名称: ${K}
1504
+ - 类型: ${G}
1503
1505
  - 路径: ${X}
1504
1506
 
1505
1507
  **配置状态:**
@@ -1509,22 +1511,22 @@ Please continue the conversation from where we left it off without asking the us
1509
1511
  - 工作目录: ${process.cwd()}
1510
1512
  - Node.js: ${process.version}
1511
1513
 
1512
- ${!J?"\n\uD83D\uDCA1 **建议:** 运行 `/init` 命令来创建项目配置文件":""}`;return Z.sendMessage(W),{success:!0,message:"状态信息已显示"}}catch(Q){return{success:!1,error:`获取状态信息失败: ${Q instanceof Error?Q.message:"未知错误"}`}}}},mW={name:"exit",description:"Exit the REPL",fullDescription:"退出 Blade Code 命令行界面",usage:"/exit",aliases:["quit","q"],async handler($,Y){return{success:!0,message:"exit_application"}}},dW={name:"context",description:"Visualize current context usage as a colored grid",fullDescription:"可视化显示当前上下文使用情况",usage:"/context",async handler($,Y){let Z=T1(Y),X=C1(),Q=N$(),q=e().session.messages||[],G=q.map((L)=>({role:L.role,content:L.content})),K=Q?.model||"gpt-4",W=G.length>0?_2.countTokens(G,K):0,O=Q?.maxContextTokens??X?.maxContextTokens??128000,U=O>0?(W/O*100).toFixed(1):"0",F=(100-parseFloat(U)).toFixed(1),H=parseFloat(U),_;if(H<50)_="\uD83D\uDFE2 正常";else if(H<80)_="\uD83D\uDFE1 中等";else _="\uD83D\uDD34 高负载";let z=`\uD83D\uDCCA **上下文使用情况**
1514
+ ${!J?"\n\uD83D\uDCA1 **建议:** 运行 `/init` 命令来创建项目配置文件":""}`;return Z.sendMessage(U),{success:!0,message:"状态信息已显示"}}catch(Q){return{success:!1,error:`获取状态信息失败: ${Q instanceof Error?Q.message:"未知错误"}`}}}},UO={name:"exit",description:"Exit the REPL",fullDescription:"退出 Blade Code 命令行界面",usage:"/exit",aliases:["quit","q"],async handler($,Y){return{success:!0,message:"exit_application"}}},WO={name:"context",description:"Visualize current context usage as a colored grid",fullDescription:"可视化显示当前上下文使用情况",usage:"/context",async handler($,Y){let Z=C1(Y),X=x1(),Q=w$(),q=$1().session.messages||[],K=q.map((L)=>({role:L.role,content:L.content})),G=Q?.model||"gpt-4",U=K.length>0?_2.countTokens(K,G):0,O=Q?.maxContextTokens??X?.maxContextTokens??128000,W=O>0?(U/O*100).toFixed(1):"0",F=(100-parseFloat(W)).toFixed(1),H=parseFloat(W),z;if(H<50)z="\uD83D\uDFE2 正常";else if(H<80)z="\uD83D\uDFE1 中等";else z="\uD83D\uDD34 高负载";let N=`\uD83D\uDCCA **上下文使用情况**
1513
1515
 
1514
1516
  **当前会话:**
1515
1517
  - 消息数量: ${q.length}
1516
- - Token 使用: ${W.toLocaleString()} / ${O.toLocaleString()}
1517
- - 使用率: ${U}%
1518
+ - Token 使用: ${U.toLocaleString()} / ${O.toLocaleString()}
1519
+ - 使用率: ${W}%
1518
1520
  - 剩余容量: ${F}%
1519
1521
 
1520
1522
  **模型信息:**
1521
1523
  - 模型: ${Q?.model||"未配置"}
1522
1524
  - 上下文窗口: ${O.toLocaleString()} tokens
1523
1525
 
1524
- **状态:** ${_}
1526
+ **状态:** ${z}
1525
1527
 
1526
- \uD83D\uDCA1 使用 \`/compact\` 可手动压缩上下文`;return Z.sendMessage(z),{success:!0,message:"上下文信息已显示"}}},zX={help:xW,clear:pW,version:gW,status:uW,exit:mW,context:dW,permissions:S4,resume:OX,compact:XX,mcp:GX,agents:YX}});import{execFile as BX,spawn as cW}from"child_process";import{promisify as lW}from"util";async function R6($,Y){return new Promise((Z)=>{BX("git",Y,{cwd:$,maxBuffer:10485760},(X,Q,J)=>{Z({code:X?X.code||1:0,stdout:Q||"",stderr:J||""})})})}async function iW($,Y){let{code:Z}=await R6($,Y);return Z===0}async function Q2($,Y){let{stdout:Z}=await R6($,Y);return Z.trim()}async function V6($){return iW($,["rev-parse","--is-inside-work-tree"])}async function h4($){return(await Q2($,["status","--porcelain"])).length>0}async function LX($){return Q2($,["branch","--show-current"])}async function x4($,Y=10){return Q2($,["log","-n",String(Y),"--pretty=format:%s"])}async function S7($){let{code:Y,stderr:Z}=await R6($,["add","."]);if(Y!==0){let X=Z||"Unknown error";if(X.includes("fatal: pathspec"))throw Error("Failed to stage files: Invalid file path or pattern");throw Error(`Failed to stage files: ${X}`)}}async function wX($,Y,Z=!1,X){let Q=["commit","-m",Y];if(Z)Q.push("--no-verify");if(!X){let{code:J,stderr:q}=await R6($,Q);if(J!==0)throw Error(q||"Commit failed");return}return new Promise((J,q)=>{let G=cW("git",Q,{cwd:$}),K="",W=(F,H,_)=>{let L=(_+F.toString()).split(`
1527
- `),B=L.pop()||"";for(let N of L)if(N.trim())X(N,H);return B},O="",U="";G.stdout?.on("data",(F)=>{O=W(F,"stdout",O)}),G.stderr?.on("data",(F)=>{K+=F.toString(),U=W(F,"stderr",U)}),G.on("error",(F)=>{q(F)}),G.on("close",(F)=>{if(O.trim())X(O,"stdout");if(U.trim())X(U,"stderr");if(F===0)J();else q(Error(K||"Commit failed"))})})}async function AX($){let{cwd:Y}=$;if(!await V6(Y))return null;let[Z,X,Q,J,q]=await Promise.all([Q2(Y,["branch","--show-current"]),Q2(Y,["rev-parse","--abbrev-ref","origin/HEAD"]).then((K)=>K.replace("origin/","")).catch(()=>"main"),Q2(Y,["status","--short"]),Q2(Y,["log","--oneline","-n","5"]),Q2(Y,["config","user.email"])]),G=q?await Q2(Y,["log","--author",q,"--oneline","-n","5"]):"";return{branch:Z,mainBranch:X,status:Q,log:J,author:q,authorLog:G}}function bX($){if(!$)return null;return`
1528
+ \uD83D\uDCA1 使用 \`/compact\` 可手动压缩上下文`;return Z.sendMessage(N),{success:!0,message:"上下文信息已显示"}}},SX={help:JO,clear:qO,version:KO,status:GO,exit:UO,context:WO,permissions:h4,resume:EX,compact:bX,mcp:IX,agents:wX}});import{execFile as CX,spawn as OO}from"child_process";import{promisify as FO}from"util";async function I6($,Y){return new Promise((Z)=>{CX("git",Y,{cwd:$,maxBuffer:10485760},(X,Q,J)=>{Z({code:X?X.code||1:0,stdout:Q||"",stderr:J||""})})})}async function HO($,Y){let{code:Z}=await I6($,Y);return Z===0}async function K2($,Y){let{stdout:Z}=await I6($,Y);return Z.trim()}async function M6($){return HO($,["rev-parse","--is-inside-work-tree"])}async function u4($){return(await K2($,["status","--porcelain"])).length>0}async function fX($){return K2($,["branch","--show-current"])}async function g4($,Y=10){return K2($,["log","-n",String(Y),"--pretty=format:%s"])}async function m7($){let{code:Y,stderr:Z}=await I6($,["add","."]);if(Y!==0){let X=Z||"Unknown error";if(X.includes("fatal: pathspec"))throw Error("Failed to stage files: Invalid file path or pattern");throw Error(`Failed to stage files: ${X}`)}}async function hX($,Y,Z=!1,X){let Q=["commit","-m",Y];if(Z)Q.push("--no-verify");if(!X){let{code:J,stderr:q}=await I6($,Q);if(J!==0)throw Error(q||"Commit failed");return}return new Promise((J,q)=>{let K=OO("git",Q,{cwd:$}),G="",U=(F,H,z)=>{let L=(z+F.toString()).split(`
1529
+ `),B=L.pop()||"";for(let _ of L)if(_.trim())X(_,H);return B},O="",W="";K.stdout?.on("data",(F)=>{O=U(F,"stdout",O)}),K.stderr?.on("data",(F)=>{G+=F.toString(),W=U(F,"stderr",W)}),K.on("error",(F)=>{q(F)}),K.on("close",(F)=>{if(O.trim())X(O,"stdout");if(W.trim())X(W,"stderr");if(F===0)J();else q(Error(G||"Commit failed"))})})}async function xX($){let{cwd:Y}=$;if(!await M6(Y))return null;let[Z,X,Q,J,q]=await Promise.all([K2(Y,["branch","--show-current"]),K2(Y,["rev-parse","--abbrev-ref","origin/HEAD"]).then((G)=>G.replace("origin/","")).catch(()=>"main"),K2(Y,["status","--short"]),K2(Y,["log","--oneline","-n","5"]),K2(Y,["config","user.email"])]),K=q?await K2(Y,["log","--author",q,"--oneline","-n","5"]):"";return{branch:Z,mainBranch:X,status:Q,log:J,author:q,authorLog:K}}function pX($){if(!$)return null;return`
1528
1530
  Git repository status (snapshot at conversation start):
1529
1531
  Current branch: ${$.branch}
1530
1532
  Main branch (target for PRs): ${$.mainBranch}
@@ -1537,14 +1539,14 @@ ${$.log||"(no commits)"}
1537
1539
 
1538
1540
  Your recent commits:
1539
1541
  ${$.authorLog||"(no recent commits)"}
1540
- `.trim()}async function D6($){return Q2($,["diff","--cached","--name-status"])}async function I6($){let Z=["diff","--cached","--",...[":!pnpm-lock.yaml",":!package-lock.json",":!yarn.lock",":!*.min.js",":!*.bundle.js",":!dist/**",":!build/**",":!*.gz",":!*.zip",":!*.tar",":!*.tgz",":!*.woff",":!*.woff2",":!*.ttf",":!*.png",":!*.jpg",":!*.jpeg",":!*.gif",":!*.ico",":!*.svg",":!*.pdf"]],{code:X,stdout:Q,stderr:J}=await R6($,Z);if(X!==0){let G=J||"Unknown error";if(G.includes("bad revision"))throw Error("Failed to get staged diff: Invalid Git revision or corrupt repository");if(G.includes("fatal: not a git repository"))throw Error("Not a Git repository");throw Error(`Failed to get staged diff: ${G}`)}let q=102400;if(Q.length>q)return Q.substring(0,q)+`
1542
+ `.trim()}async function j6($){return K2($,["diff","--cached","--name-status"])}async function y6($){let Z=["diff","--cached","--",...[":!pnpm-lock.yaml",":!package-lock.json",":!yarn.lock",":!*.min.js",":!*.bundle.js",":!dist/**",":!build/**",":!*.gz",":!*.zip",":!*.tar",":!*.tgz",":!*.woff",":!*.woff2",":!*.ttf",":!*.png",":!*.jpg",":!*.jpeg",":!*.gif",":!*.ico",":!*.svg",":!*.pdf"]],{code:X,stdout:Q,stderr:J}=await I6($,Z);if(X!==0){let K=J||"Unknown error";if(K.includes("bad revision"))throw Error("Failed to get staged diff: Invalid Git revision or corrupt repository");if(K.includes("fatal: not a git repository"))throw Error("Not a Git repository");throw Error(`Failed to get staged diff: ${K}`)}let q=102400;if(Q.length>q)return Q.substring(0,q)+`
1541
1543
 
1542
- [Diff truncated due to size. Total diff size: `+(Q.length/1024).toFixed(2)+"KB]";return Q}var DI;var C7=b(()=>{DI=lW(BX)});async function RX($){let Y=T1($),Z=await AX({cwd:$.cwd});if(!Z)return{success:!1,error:"无法获取 Git 状态"};let X=bX(Z);if(X)Y.sendMessage(`\`\`\`
1544
+ [Diff truncated due to size. Total diff size: `+(Q.length/1024).toFixed(2)+"KB]";return Q}var QM;var c7=b(()=>{QM=FO(CX)});async function uX($){let Y=C1($),Z=await xX({cwd:$.cwd});if(!Z)return{success:!1,error:"无法获取 Git 状态"};let X=pX(Z);if(X)Y.sendMessage(`\`\`\`
1543
1545
  ${X}
1544
- \`\`\``);else Y.sendMessage("\uD83D\uDCED 无法获取 Git 状态信息");return{success:!0}}async function rW($,Y){let Z=T1($),X=Math.min(Math.max(parseInt(Y||"5",10)||5,1),50),Q=await x4($.cwd,X);if(!Q)Z.sendMessage("\uD83D\uDCED 暂无提交记录");else Z.sendMessage(`**最近 ${X} 条提交:**
1546
+ \`\`\``);else Y.sendMessage("\uD83D\uDCED 无法获取 Git 状态信息");return{success:!0}}async function NO($,Y){let Z=C1($),X=Math.min(Math.max(parseInt(Y||"5",10)||5,1),50),Q=await g4($.cwd,X);if(!Q)Z.sendMessage("\uD83D\uDCED 暂无提交记录");else Z.sendMessage(`**最近 ${X} 条提交:**
1545
1547
  \`\`\`
1546
1548
  ${Q}
1547
- \`\`\``);return{success:!0}}async function nW($){let Y=T1($),{cwd:Z}=$,X=await D6(Z);if(!X)return Y.sendMessage("\uD83D\uDCED 暂存区为空,没有待提交的改动"),{success:!0};let Q=await I6(Z),J=`**暂存文件:**
1549
+ \`\`\``);return{success:!0}}async function BO($){let Y=C1($),{cwd:Z}=$,X=await j6(Z);if(!X)return Y.sendMessage("\uD83D\uDCED 暂存区为空,没有待提交的改动"),{success:!0};let Q=await y6(Z),J=`**暂存文件:**
1548
1550
  \`\`\`
1549
1551
  ${X}
1550
1552
  \`\`\`
@@ -1552,7 +1554,7 @@ ${X}
1552
1554
  **Diff:**
1553
1555
  \`\`\`diff
1554
1556
  ${Q||"(无差异)"}
1555
- \`\`\``;return Y.sendMessage(J),{success:!0}}async function oW($){let Y=T1($),{cwd:Z,signal:X}=$;if(!await h4(Z))return Y.sendMessage("\uD83D\uDCED 没有未提交的改动,无需 Review"),{success:!0};Y.sendMessage("\uD83D\uDD0D 正在分析代码改动...");let Q=await D6(Z),J=await I6(Z);if(!J&&!Q)return Y.sendMessage("\uD83D\uDCA1 请先使用 `git add` 暂存要 Review 的文件"),{success:!0};let q=await m1.create();if(X?.aborted)return{success:!1,message:"操作已取消"};let G=e().session.sessionId,K=`请对以下 Git 改动进行 Code Review。
1557
+ \`\`\``;return Y.sendMessage(J),{success:!0}}async function _O($){let Y=C1($),{cwd:Z,signal:X}=$;if(!await u4(Z))return Y.sendMessage("\uD83D\uDCED 没有未提交的改动,无需 Review"),{success:!0};Y.sendMessage("\uD83D\uDD0D 正在分析代码改动...");let Q=await j6(Z),J=await y6(Z);if(!J&&!Q)return Y.sendMessage("\uD83D\uDCA1 请先使用 `git add` 暂存要 Review 的文件"),{success:!0};let q=await l1.create();if(X?.aborted)return{success:!1,message:"操作已取消"};let K=$1().session.sessionId,G=`请对以下 Git 改动进行 Code Review。
1556
1558
 
1557
1559
  **暂存文件:**
1558
1560
  ${Q||"(无)"}
@@ -1568,19 +1570,19 @@ ${J||"(无差异)"}
1568
1570
  3. **潜在问题**:指出可能的 bug、安全问题或性能问题
1569
1571
  4. **改进建议**:具体的代码改进建议
1570
1572
 
1571
- 如果改动很好,也请说明优点。保持简洁专业。`,W=await q.chat(K,{messages:[],userId:"cli-user",sessionId:G||"git-review",workspaceRoot:Z,signal:X});return Y.sendMessage(W),{success:!0}}async function sW($){let Y=T1($),{cwd:Z,signal:X}=$;if(!await h4(Z))return Y.sendMessage("\uD83D\uDCED 没有未提交的改动"),{success:!0};Y.sendMessage("\uD83D\uDCE6 暂存所有改动..."),await S7(Z);let Q=await D6(Z),J=await I6(Z);if(!Q)return Y.sendMessage("\uD83D\uDCED 没有需要提交的改动"),{success:!0};Y.sendMessage("\uD83E\uDD16 正在生成 commit message...");let q=await x4(Z,5),G=await m1.create();if(X?.aborted)return{success:!1,message:"操作已取消"};let K=e().session.sessionId,W=VX(Q,J,q),U=(await G.chat(W,{messages:[],userId:"cli-user",sessionId:K||"git-pre-commit",workspaceRoot:Z,signal:X})).replace(/^```\w*\n?/,"").replace(/\n?```$/,"").trim();return Y.sendMessage(`**生成的 Commit Message:**
1573
+ 如果改动很好,也请说明优点。保持简洁专业。`,U=await q.chat(G,{messages:[],userId:"cli-user",sessionId:K||"git-review",workspaceRoot:Z,signal:X});return Y.sendMessage(U),{success:!0}}async function LO($){let Y=C1($),{cwd:Z,signal:X}=$;if(!await u4(Z))return Y.sendMessage("\uD83D\uDCED 没有未提交的改动"),{success:!0};Y.sendMessage("\uD83D\uDCE6 暂存所有改动..."),await m7(Z);let Q=await j6(Z),J=await y6(Z);if(!Q)return Y.sendMessage("\uD83D\uDCED 没有需要提交的改动"),{success:!0};Y.sendMessage("\uD83E\uDD16 正在生成 commit message...");let q=await g4(Z,5),K=await l1.create();if(X?.aborted)return{success:!1,message:"操作已取消"};let G=$1().session.sessionId,U=gX(Q,J,q),W=(await K.chat(U,{messages:[],userId:"cli-user",sessionId:G||"git-pre-commit",workspaceRoot:Z,signal:X})).replace(/^```\w*\n?/,"").replace(/\n?```$/,"").trim();return Y.sendMessage(`**生成的 Commit Message:**
1572
1574
  \`\`\`
1573
- ${U}
1575
+ ${W}
1574
1576
  \`\`\`
1575
1577
 
1576
1578
  \uD83D\uDCA1 使用以下命令提交:
1577
1579
  \`\`\`bash
1578
- git commit -m "${U.split(`
1580
+ git commit -m "${W.split(`
1579
1581
  `)[0]}"
1580
- \`\`\``),{success:!0}}async function tW($){let Y=T1($),{cwd:Z,signal:X}=$;if(!await h4(Z))return Y.sendMessage("\uD83D\uDCED 没有未提交的改动"),{success:!0};Y.sendMessage("\uD83D\uDCE6 暂存所有改动..."),await S7(Z);let Q=await D6(Z),J=await I6(Z);if(!Q)return Y.sendMessage("\uD83D\uDCED 没有需要提交的改动"),{success:!0};Y.sendMessage("\uD83E\uDD16 正在生成 commit message...");let q=await x4(Z,5),G=await m1.create();if(X?.aborted)return{success:!1,message:"操作已取消"};let K=e().session.sessionId,W=VX(Q,J,q),U=(await G.chat(W,{messages:[],userId:"cli-user",sessionId:K||"git-commit",workspaceRoot:Z,signal:X})).replace(/^```\w*\n?/,"").replace(/\n?```$/,"").trim();Y.sendMessage(`**生成的 Commit Message:**
1582
+ \`\`\``),{success:!0}}async function wO($){let Y=C1($),{cwd:Z,signal:X}=$;if(!await u4(Z))return Y.sendMessage("\uD83D\uDCED 没有未提交的改动"),{success:!0};Y.sendMessage("\uD83D\uDCE6 暂存所有改动..."),await m7(Z);let Q=await j6(Z),J=await y6(Z);if(!Q)return Y.sendMessage("\uD83D\uDCED 没有需要提交的改动"),{success:!0};Y.sendMessage("\uD83E\uDD16 正在生成 commit message...");let q=await g4(Z,5),K=await l1.create();if(X?.aborted)return{success:!1,message:"操作已取消"};let G=$1().session.sessionId,U=gX(Q,J,q),W=(await K.chat(U,{messages:[],userId:"cli-user",sessionId:G||"git-commit",workspaceRoot:Z,signal:X})).replace(/^```\w*\n?/,"").replace(/\n?```$/,"").trim();Y.sendMessage(`**生成的 Commit Message:**
1581
1583
  \`\`\`
1582
- ${U}
1583
- \`\`\``);try{await wX(Z,U),Y.sendMessage("✅ 提交成功!")}catch(F){let H=F instanceof Error?F.message:"未知错误";return Y.sendMessage(`❌ 提交失败: ${H}`),{success:!1,error:H}}return{success:!0}}function VX($,Y,Z){let X=Z&&Z.trim().length>0;return`请根据以下 Git 改动生成一条 commit message。
1584
+ ${W}
1585
+ \`\`\``);try{await hX(Z,W),Y.sendMessage("✅ 提交成功!")}catch(F){let H=F instanceof Error?F.message:"未知错误";return Y.sendMessage(`❌ 提交失败: ${H}`),{success:!1,error:H}}return{success:!0}}function gX($,Y,Z){let X=Z&&Z.trim().length>0;return`请根据以下 Git 改动生成一条 commit message。
1584
1586
 
1585
1587
  **暂存文件:**
1586
1588
  ${$}
@@ -1601,9 +1603,9 @@ ${Z}
1601
1603
  1. ${X?"严格模仿历史提交的语言和格式风格":"使用英文,遵循 Conventional Commits 格式(feat:, fix:, docs:, refactor:, chore: 等)"}
1602
1604
  2. 第一行简明扼要,不超过 72 字符
1603
1605
  3. 如有必要,可添加空行后的详细说明
1604
- 4. 只输出 commit message 内容,不要其他解释或代码块标记`}var aW,DX;var IX=b(()=>{T2();N1();C7();h2();aW={name:"git",description:"Git 仓库查询和 AI 辅助",usage:"/git [status|log|diff|review|commit|pre-commit]",aliases:["g"],examples:["/git","/git status","/git log 10","/git review","/git commit","/git pre-commit"],async handler($,Y){let{cwd:Z}=Y,X=$[0]?.toLowerCase();if(!await V6(Z))return{success:!1,error:"❌ 当前目录不在 Git 仓库中"};try{switch(X){case"status":case"s":return RX(Y);case"log":case"l":return rW(Y,$[1]);case"diff":case"d":return nW(Y);case"review":case"r":return oW(Y);case"commit":case"c":return tW(Y);case"pre-commit":case"pc":return sW(Y);default:return RX(Y)}}catch(Q){return{success:!1,error:`Git 命令失败: ${Q instanceof Error?Q.message:"未知错误"}`}}}};DX=aW});function $O($){let Y=$.isEnabled(),Z=$.getConfig(),X={};for(let J of Object.values(o0)){let q=Z[J];if(q&&Array.isArray(q)){let G=q.reduce((K,W)=>K+(W.hooks?.length||0),0);if(G>0)X[J]=G}}let Q=["## Hooks 状态","",`**状态**: ${Y?"✅ 启用":"⏸️ 禁用"}`,""];if(Object.keys(X).length>0){Q.push("**已配置的 Hooks**:"),Q.push("");for(let[J,q]of Object.entries(X))Q.push(`- ${J}: ${q} 个 hook`)}else Q.push("*没有配置任何 hooks*");return Q.push(""),Q.push("---"),Q.push("使用 `/hooks list` 查看详细配置"),Q.push("使用 `/hooks enable` 或 `/hooks disable` 切换状态"),_0().addAssistantMessage(Q.join(`
1605
- `)),{success:!0,message:"Hooks status displayed"}}function YO($){let Y=$.getConfig(),Z=["## Hooks 配置详情",""],X=!1;for(let Q of Object.values(o0)){let J=Y[Q];if(!J||!Array.isArray(J)||J.length===0)continue;X=!0,Z.push(`### ${Q}`),Z.push("");for(let q=0;q<J.length;q++){let G=J[q],K=G.name||`Matcher ${q+1}`,W=G.matcher,O="所有";if(W){let U=[];if(W.tools){let F=Array.isArray(W.tools)?W.tools.join(", "):W.tools;U.push(`工具: ${F}`)}if(W.paths){let F=Array.isArray(W.paths)?W.paths.join(", "):W.paths;U.push(`路径: ${F}`)}if(W.commands){let F=Array.isArray(W.commands)?W.commands.join(", "):W.commands;U.push(`命令: ${F}`)}if(U.length>0)O=U.join("; ")}Z.push(`**${K}** (匹配: ${O})`);for(let U of G.hooks||[])if(U.type==="command")Z.push(` - \`${U.command}\``);else if(U.type==="prompt"){let F=U.prompt.slice(0,50)+(U.prompt.length>50?"...":"");Z.push(` - [prompt] ${F}`)}Z.push("")}}if(!X)Z.push("*没有配置任何 hooks*"),Z.push(""),Z.push("在 `.blade/settings.local.json` 或 `~/.blade/settings.json` 中配置 hooks。");return _0().addAssistantMessage(Z.join(`
1606
- `)),{success:!0,message:"Hooks config listed"}}var eW,MX;var jX=b(()=>{z0();w$();N1();eW={name:"hooks",description:"Manage hook configurations for tool events",fullDescription:`管理 Hook 配置,查看当前启用的 hooks 和执行统计。
1606
+ 4. 只输出 commit message 内容,不要其他解释或代码块标记`}var zO,dX;var mX=b(()=>{C2();A1();c7();u2();zO={name:"git",description:"Git 仓库查询和 AI 辅助",usage:"/git [status|log|diff|review|commit|pre-commit]",aliases:["g"],examples:["/git","/git status","/git log 10","/git review","/git commit","/git pre-commit"],async handler($,Y){let{cwd:Z}=Y,X=$[0]?.toLowerCase();if(!await M6(Z))return{success:!1,error:"❌ 当前目录不在 Git 仓库中"};try{switch(X){case"status":case"s":return uX(Y);case"log":case"l":return NO(Y,$[1]);case"diff":case"d":return BO(Y);case"review":case"r":return _O(Y);case"commit":case"c":return wO(Y);case"pre-commit":case"pc":return LO(Y);default:return uX(Y)}}catch(Q){return{success:!1,error:`Git 命令失败: ${Q instanceof Error?Q.message:"未知错误"}`}}}};dX=zO});function bO($){let Y=$.isEnabled(),Z=$.getConfig(),X={};for(let J of Object.values(e0)){let q=Z[J];if(q&&Array.isArray(q)){let K=q.reduce((G,U)=>G+(U.hooks?.length||0),0);if(K>0)X[J]=K}}let Q=["## Hooks 状态","",`**状态**: ${Y?"✅ 启用":"⏸️ 禁用"}`,""];if(Object.keys(X).length>0){Q.push("**已配置的 Hooks**:"),Q.push("");for(let[J,q]of Object.entries(X))Q.push(`- ${J}: ${q} 个 hook`)}else Q.push("*没有配置任何 hooks*");return Q.push(""),Q.push("---"),Q.push("使用 `/hooks list` 查看详细配置"),Q.push("使用 `/hooks enable` 或 `/hooks disable` 切换状态"),_0().addAssistantMessage(Q.join(`
1607
+ `)),{success:!0,message:"Hooks status displayed"}}function RO($){let Y=$.getConfig(),Z=["## Hooks 配置详情",""],X=!1;for(let Q of Object.values(e0)){let J=Y[Q];if(!J||!Array.isArray(J)||J.length===0)continue;X=!0,Z.push(`### ${Q}`),Z.push("");for(let q=0;q<J.length;q++){let K=J[q],G=K.name||`Matcher ${q+1}`,U=K.matcher,O="所有";if(U){let W=[];if(U.tools){let F=Array.isArray(U.tools)?U.tools.join(", "):U.tools;W.push(`工具: ${F}`)}if(U.paths){let F=Array.isArray(U.paths)?U.paths.join(", "):U.paths;W.push(`路径: ${F}`)}if(U.commands){let F=Array.isArray(U.commands)?U.commands.join(", "):U.commands;W.push(`命令: ${F}`)}if(W.length>0)O=W.join("; ")}Z.push(`**${G}** (匹配: ${O})`);for(let W of K.hooks||[])if(W.type==="command")Z.push(` - \`${W.command}\``);else if(W.type==="prompt"){let F=W.prompt.slice(0,50)+(W.prompt.length>50?"...":"");Z.push(` - [prompt] ${F}`)}Z.push("")}}if(!X)Z.push("*没有配置任何 hooks*"),Z.push(""),Z.push("在 `.blade/settings.local.json` 或 `~/.blade/settings.json` 中配置 hooks。");return _0().addAssistantMessage(Z.join(`
1608
+ `)),{success:!0,message:"Hooks config listed"}}var AO,cX;var lX=b(()=>{L0();R$();A1();AO={name:"hooks",description:"Manage hook configurations for tool events",fullDescription:`管理 Hook 配置,查看当前启用的 hooks 和执行统计。
1607
1609
 
1608
1610
  子命令:
1609
1611
  /hooks - 打开交互式 hooks 管理界面(添加新 hook)
@@ -1611,14 +1613,14 @@ ${Z}
1611
1613
  /hooks status - 显示 hooks 启用状态和统计
1612
1614
  /hooks enable - 启用当前会话的 hooks
1613
1615
  /hooks disable - 禁用当前会话的 hooks
1614
- /hooks list - 列出所有配置的 hooks`,usage:"/hooks [add|status|enable|disable|list]",category:"system",examples:["/hooks","/hooks add","/hooks status","/hooks enable","/hooks disable","/hooks list"],handler:async($,Y)=>{let Z=$[0]?.toLowerCase()||"",X=H1.getInstance();switch(Z){case"":case"add":return{success:!0,message:"show_hooks_manager",data:{action:"show_hooks_manager"}};case"status":return $O(X);case"enable":return X.enable(),_0().addAssistantMessage("✅ Hooks 已启用(当前会话)"),{success:!0,message:"Hooks enabled"};case"disable":return X.disable(),_0().addAssistantMessage("⏸️ Hooks 已禁用(当前会话)"),{success:!0,message:"Hooks disabled"};case"list":return YO(X);default:return _0().addAssistantMessage(`❌ 未知子命令: ${Z}
1615
- 使用 /hooks 查看帮助`),{success:!1,error:`Unknown subcommand: ${Z}`}}}};MX=eW});import{exec as ZO}from"child_process";import{promisify as XO}from"util";class f7{static async detectIde(){let $=process.env.TERM_PROGRAM,Y=process.env.VSCODE_INJECTION,Z=process.env.VSCODE_IPC_HOOK;if($==="vscode"||Y||Z)return await this.detectVsCode();let X=await this.detectVsCode();if(X)return X;return null}static async detectVsCode(){try{let{stdout:$}=await yX("code --version"),Z=$.trim().split(`
1616
- `)[0]||"unknown",X=[];try{let{stdout:Q}=await yX("code --list-extensions");X=Q.trim().split(`
1617
- `).filter(Boolean)}catch{}return{name:"VS Code",version:Z,extensions:X}}catch{return null}}static isRunningInIdeTerminal(){let $=process.env.TERM_PROGRAM,Y=process.env.VSCODE_INJECTION,Z=process.env.VSCODE_IPC_HOOK;return $==="vscode"||!!Y||!!Z}}var yX;var vX=b(()=>{yX=XO(ZO)});import{exec as QO}from"child_process";import{promisify as JO}from"util";class M6{static async getInstalledIdes(){let $=[],Y=await this.checkVsCode();if(Y)$.push(Y);let Z=await this.checkVsCodeInsiders();if(Z)$.push(Z);let X=await this.checkCursor();if(X)$.push(X);return $}static async isIdeInstalled($){switch($){case"vscode":return await this.checkVsCode()!==null;case"vscode-insiders":return await this.checkVsCodeInsiders()!==null;case"cursor":return await this.checkCursor()!==null;default:return!1}}static async installExtension($){let Y;switch($){case"vscode":Y="code --install-extension blade-code.blade-code";break;case"vscode-insiders":Y="code-insiders --install-extension blade-code.blade-code";break;case"cursor":Y="cursor --install-extension blade-code.blade-code";break;default:return{success:!1,message:"不支持的 IDE: "+$}}try{return await p4(Y),{success:!0,message:"扩展安装成功"}}catch(Z){return{success:!1,message:"安装失败: "+(Z instanceof Error?Z.message:"未知错误")}}}static async checkVsCode(){try{let{stdout:$}=await p4("code --version");return{id:"vscode",name:"VS Code",version:$.trim().split(`
1618
- `)[0]||"unknown"}}catch{return null}}static async checkVsCodeInsiders(){try{let{stdout:$}=await p4("code-insiders --version");return{id:"vscode-insiders",name:"VS Code Insiders",version:$.trim().split(`
1619
- `)[0]||"unknown"}}catch{return null}}static async checkCursor(){try{let{stdout:$}=await p4("cursor --version");return{id:"cursor",name:"Cursor",version:$.trim().split(`
1620
- `)[0]||"unknown"}}catch{return null}}}var p4;var EX=b(()=>{p4=JO(QO)});import{existsSync as qO,readFileSync as GO}from"fs";import{homedir as KO}from"os";import{join as UO}from"path";function WO(){switch(p$){case"connected":return{type:"info",content:`\uD83D\uDFE2 已连接到 ${h7||"IDE"} (端口: ${x7})`};case"connecting":return{type:"info",content:"\uD83D\uDFE1 正在连接..."};default:return{type:"error",content:"\uD83D\uDD34 未连接到 IDE"}}}function TX(){try{if(qO(PX)){let $=GO(PX,"utf-8");return JSON.parse($)}}catch{}return null}function kX(){let $=process.env.BLADE_IDE_PORT;if($)return parseInt($,10);let Y=TX();if(Y)return Y.port;return null}async function OO(){let $=[],Y=WO();$.push(Y.content),$.push(""),$.push("\uD83D\uDCE6 已安装的 IDE:");let Z=await M6.getInstalledIdes();if(Z.length===0)$.push(" (未检测到支持的 IDE)");else for(let q of Z)$.push(` • ${q.name} ${q.version}`);$.push("");let X=await f7.detectIde();if(X){if($.push(`\uD83D\uDDA5️ 当前环境: ${X.name} ${X.version}`),X.extensions.length>0)$.push(` 已安装扩展: ${X.extensions.length} 个`)}let Q=kX(),J=TX();if(Q){if($.push(`\uD83D\uDD0C IDE 端口: ${Q}`),J&&J.workspaceFolders.length>0)$.push(` 工作区: ${J.workspaceFolders[0]}`)}else $.push(""),$.push("\uD83D\uDCA1 提示: 在 VS Code 中安装 Blade Code 插件后,运行 /ide connect 连接");return $.join(`
1621
- `)}async function FO(){let $=kX();if(!$)return`❌ 未检测到 IDE 端口
1616
+ /hooks list - 列出所有配置的 hooks`,usage:"/hooks [add|status|enable|disable|list]",category:"system",examples:["/hooks","/hooks add","/hooks status","/hooks enable","/hooks disable","/hooks list"],handler:async($,Y)=>{let Z=$[0]?.toLowerCase()||"",X=H1.getInstance();switch(Z){case"":case"add":return{success:!0,message:"show_hooks_manager",data:{action:"show_hooks_manager"}};case"status":return bO(X);case"enable":return X.enable(),_0().addAssistantMessage("✅ Hooks 已启用(当前会话)"),{success:!0,message:"Hooks enabled"};case"disable":return X.disable(),_0().addAssistantMessage("⏸️ Hooks 已禁用(当前会话)"),{success:!0,message:"Hooks disabled"};case"list":return RO(X);default:return _0().addAssistantMessage(`❌ 未知子命令: ${Z}
1617
+ 使用 /hooks 查看帮助`),{success:!1,error:`Unknown subcommand: ${Z}`}}}};cX=AO});import{exec as VO}from"child_process";import{promisify as DO}from"util";class l7{static async detectIde(){let $=process.env.TERM_PROGRAM,Y=process.env.VSCODE_INJECTION,Z=process.env.VSCODE_IPC_HOOK;if($==="vscode"||Y||Z)return await this.detectVsCode();let X=await this.detectVsCode();if(X)return X;return null}static async detectVsCode(){try{let{stdout:$}=await iX("code --version"),Z=$.trim().split(`
1618
+ `)[0]||"unknown",X=[];try{let{stdout:Q}=await iX("code --list-extensions");X=Q.trim().split(`
1619
+ `).filter(Boolean)}catch{}return{name:"VS Code",version:Z,extensions:X}}catch{return null}}static isRunningInIdeTerminal(){let $=process.env.TERM_PROGRAM,Y=process.env.VSCODE_INJECTION,Z=process.env.VSCODE_IPC_HOOK;return $==="vscode"||!!Y||!!Z}}var iX;var rX=b(()=>{iX=DO(VO)});import{exec as IO}from"child_process";import{promisify as MO}from"util";class E6{static async getInstalledIdes(){let $=[],Y=await this.checkVsCode();if(Y)$.push(Y);let Z=await this.checkVsCodeInsiders();if(Z)$.push(Z);let X=await this.checkCursor();if(X)$.push(X);return $}static async isIdeInstalled($){switch($){case"vscode":return await this.checkVsCode()!==null;case"vscode-insiders":return await this.checkVsCodeInsiders()!==null;case"cursor":return await this.checkCursor()!==null;default:return!1}}static async installExtension($){let Y;switch($){case"vscode":Y="code --install-extension blade-code.blade-code";break;case"vscode-insiders":Y="code-insiders --install-extension blade-code.blade-code";break;case"cursor":Y="cursor --install-extension blade-code.blade-code";break;default:return{success:!1,message:"不支持的 IDE: "+$}}try{return await d4(Y),{success:!0,message:"扩展安装成功"}}catch(Z){return{success:!1,message:"安装失败: "+(Z instanceof Error?Z.message:"未知错误")}}}static async checkVsCode(){try{let{stdout:$}=await d4("code --version");return{id:"vscode",name:"VS Code",version:$.trim().split(`
1620
+ `)[0]||"unknown"}}catch{return null}}static async checkVsCodeInsiders(){try{let{stdout:$}=await d4("code-insiders --version");return{id:"vscode-insiders",name:"VS Code Insiders",version:$.trim().split(`
1621
+ `)[0]||"unknown"}}catch{return null}}static async checkCursor(){try{let{stdout:$}=await d4("cursor --version");return{id:"cursor",name:"Cursor",version:$.trim().split(`
1622
+ `)[0]||"unknown"}}catch{return null}}}var d4;var aX=b(()=>{d4=MO(IO)});import{existsSync as jO,readFileSync as yO}from"fs";import{homedir as EO}from"os";import{join as vO}from"path";function PO(){switch(d$){case"connected":return{type:"info",content:`\uD83D\uDFE2 已连接到 ${i7||"IDE"} (端口: ${r7})`};case"connecting":return{type:"info",content:"\uD83D\uDFE1 正在连接..."};default:return{type:"error",content:"\uD83D\uDD34 未连接到 IDE"}}}function oX(){try{if(jO(nX)){let $=yO(nX,"utf-8");return JSON.parse($)}}catch{}return null}function sX(){let $=process.env.BLADE_IDE_PORT;if($)return parseInt($,10);let Y=oX();if(Y)return Y.port;return null}async function TO(){let $=[],Y=PO();$.push(Y.content),$.push(""),$.push("\uD83D\uDCE6 已安装的 IDE:");let Z=await E6.getInstalledIdes();if(Z.length===0)$.push(" (未检测到支持的 IDE)");else for(let q of Z)$.push(` • ${q.name} ${q.version}`);$.push("");let X=await l7.detectIde();if(X){if($.push(`\uD83D\uDDA5️ 当前环境: ${X.name} ${X.version}`),X.extensions.length>0)$.push(` 已安装扩展: ${X.extensions.length} 个`)}let Q=sX(),J=oX();if(Q){if($.push(`\uD83D\uDD0C IDE 端口: ${Q}`),J&&J.workspaceFolders.length>0)$.push(` 工作区: ${J.workspaceFolders[0]}`)}else $.push(""),$.push("\uD83D\uDCA1 提示: 在 VS Code 中安装 Blade Code 插件后,运行 /ide connect 连接");return $.join(`
1623
+ `)}async function SO(){let $=sX();if(!$)return`❌ 未检测到 IDE 端口
1622
1624
 
1623
1625
  请确保:
1624
1626
  1. 已在 VS Code 中安装 Blade Code 插件
@@ -1626,25 +1628,25 @@ ${Z}
1626
1628
  3. 在 VS Code 终端中运行 blade
1627
1629
 
1628
1630
  或手动设置端口:
1629
- export BLADE_IDE_PORT=9527`;p$="connecting";try{let Z=new(await import("ws")).default(`ws://127.0.0.1:${$}`);return await new Promise((X,Q)=>{let J=setTimeout(()=>{Z.close(),Q(Error("连接超时"))},5000);Z.on("open",()=>{clearTimeout(J),p$="connected",x7=$,h7="VS Code",Z.close(),X()}),Z.on("error",(q)=>{clearTimeout(J),Q(q)})}),`✅ 成功连接到 IDE (端口: ${$})
1631
+ export BLADE_IDE_PORT=9527`;d$="connecting";try{let Z=new(await import("ws")).default(`ws://127.0.0.1:${$}`);return await new Promise((X,Q)=>{let J=setTimeout(()=>{Z.close(),Q(Error("连接超时"))},5000);Z.on("open",()=>{clearTimeout(J),d$="connected",r7=$,i7="VS Code",Z.close(),X()}),Z.on("error",(q)=>{clearTimeout(J),Q(q)})}),`✅ 成功连接到 IDE (端口: ${$})
1630
1632
 
1631
1633
  现在可以使用以下功能:
1632
1634
  • 在 IDE 中打开文件
1633
1635
  • 获取当前选中的代码
1634
- • 查看打开的编辑器列表`}catch(Y){return p$="disconnected",`❌ 连接失败: ${Y instanceof Error?Y.message:"未知错误"}
1636
+ • 查看打开的编辑器列表`}catch(Y){return d$="disconnected",`❌ 连接失败: ${Y instanceof Error?Y.message:"未知错误"}
1635
1637
 
1636
1638
  请检查:
1637
1639
  1. VS Code 插件是否正在运行
1638
1640
  2. 端口 ${$} 是否正确
1639
- 3. 防火墙设置`}}async function HO(){let $=[];if($.push("\uD83D\uDCE6 安装 Blade Code VS Code 插件"),$.push(""),!await M6.isIdeInstalled("vscode"))return $.push("❌ 未检测到 VS Code"),$.push(""),$.push("请先安装 VS Code:"),$.push(" https://code.visualstudio.com/"),$.join(`
1641
+ 3. 防火墙设置`}}async function kO(){let $=[];if($.push("\uD83D\uDCE6 安装 Blade Code VS Code 插件"),$.push(""),!await E6.isIdeInstalled("vscode"))return $.push("❌ 未检测到 VS Code"),$.push(""),$.push("请先安装 VS Code:"),$.push(" https://code.visualstudio.com/"),$.join(`
1640
1642
  `);return $.push("✅ 检测到 VS Code"),$.push(""),$.push("安装方式:"),$.push(""),$.push("从 VSIX 文件安装:"),$.push(" 1. 下载插件: https://github.com/anthropics/blade-code/releases"),$.push(" 2. 运行: code --install-extension blade-code-x.x.x.vsix"),$.push(""),$.push("或从源码构建:"),$.push(" cd vscode-extension && pnpm install && pnpm run package"),$.push(" code --install-extension blade-code-0.0.1.vsix"),$.push(""),$.push("安装完成后,在 VS Code 终端中运行 blade 即可自动连接"),$.join(`
1641
- `)}async function _O(){if(p$==="disconnected")return"⚠️ 当前未连接到任何 IDE";return p$="disconnected",h7=null,x7=null,"✅ 已断开与 IDE 的连接"}var PX,p$="disconnected",h7=null,x7=null,zO,SX;var CX=b(()=>{vX();EX();PX=UO(KO(),".blade","ide-port");zO={name:"ide",aliases:[],description:"Manage IDE integrations and show status",usage:"/ide [status|connect|install|disconnect]",category:"system",async handler($,Y){let Z=($[0]||"").toLowerCase(),X;switch(Z){case"":case"status":X=await OO();break;case"connect":X=await FO();break;case"install":X=await HO();break;case"disconnect":X=await _O();break;default:X=`未知的子命令: ${Z}
1643
+ `)}async function CO(){if(d$==="disconnected")return"⚠️ 当前未连接到任何 IDE";return d$="disconnected",i7=null,r7=null,"✅ 已断开与 IDE 的连接"}var nX,d$="disconnected",i7=null,r7=null,fO,tX;var eX=b(()=>{rX();aX();nX=vO(EO(),".blade","ide-port");fO={name:"ide",aliases:[],description:"Manage IDE integrations and show status",usage:"/ide [status|connect|install|disconnect]",category:"system",async handler($,Y){let Z=($[0]||"").toLowerCase(),X;switch(Z){case"":case"status":X=await TO();break;case"connect":X=await SO();break;case"install":X=await kO();break;case"disconnect":X=await CO();break;default:X=`未知的子命令: ${Z}
1642
1644
 
1643
1645
  可用命令:
1644
1646
  /ide status - 显示连接状态
1645
1647
  /ide connect - 连接到 IDE
1646
1648
  /ide install - 安装 VS Code 插件
1647
- /ide disconnect - 断开连接`}return{success:!0,message:X}}},SX=zO});function j6($,Y){switch($){case"Write":return`Write(${Y.file_path||"file"})`;case"Edit":return`Edit(${Y.file_path||"file"})`;case"Read":return`Read(${Y.file_path||"file"})`;case"Bash":{let Z=Y.command;return`Bash(${Z?Z.substring(0,50):"command"}${Z&&Z.length>50?"...":""})`}case"Glob":return`Glob(${Y.pattern||"*"})`;case"Grep":{let{pattern:Z,path:X}=Y;if(X)return`Grep("${Z}" in ${X})`;return`Grep("${Z}")`}case"WebFetch":{let Z=Y.url;if(Z)try{return`WebFetch(${new URL(Z).hostname})`}catch{return`WebFetch(${Z.substring(0,30)}${Z.length>30?"...":""})`}return"WebFetch(url)"}case"WebSearch":return`WebSearch("${Y.query||"query"}")`;case"TodoWrite":return`TodoWrite(${Y.todos?.length||0} items)`;case"UndoEdit":return`UndoEdit(${Y.file_path||"file"})`;case"Skill":{let{skill:Z,args:X}=Y;if(X)return`Skill(${Z}: "${X.substring(0,30)}${X.length>30?"...":""}")`;return`Skill(${Z||"skill"})`}case"Task":{let{description:Z,subagent_type:X}=Y;if(Z)return`Task(${X||"agent"}: ${Z})`;return`Task(${X||"agent"})`}default:return`${$}()`}}function fX($,Y){if(!Y?.displayContent)return!1;switch($){case"Write":return(Y.metadata?.file_size||0)<1e4;case"Edit":return!0;case"Bash":return(Y.metadata?.stdout_length||0)<1000;case"Read":case"TodoWrite":return!1;default:return!1}}import{promises as y6}from"fs";import*as hX from"path";var g$,NO,xX;var pX=b(()=>{T2();V1();N1();h2();g$=n("Agent"),NO={name:"init",description:"分析当前项目并生成 BLADE.md 配置文件",usage:"/init",async handler($,Y){try{let{cwd:Z,signal:X}=Y,Q=T1(Y),J=(H)=>{Q.sendMessage(`${H}`)},q=e().session.sessionId,G=hX.join(Z,"BLADE.md"),K=!1,W=!1;try{if(K=(await y6.stat(G)).isFile(),K)W=(await y6.readFile(G,"utf-8")).trim().length===0}catch{K=!1}if(K&&!W){Q.sendMessage("⚠️ BLADE.md 已存在。"),Q.sendMessage("\uD83D\uDCA1 正在分析现有文件并提供改进建议...");let H=await m1.create();if(X?.aborted)return{success:!1,message:"操作已取消"};let _=`Please analyze the existing BLADE.md file and provide improvement suggestions.
1649
+ /ide disconnect - 断开连接`}return{success:!0,message:X}}},tX=fO});function v6($,Y){switch($){case"Write":return`Write(${Y.file_path||"file"})`;case"Edit":return`Edit(${Y.file_path||"file"})`;case"Read":return`Read(${Y.file_path||"file"})`;case"Bash":{let Z=Y.command;return`Bash(${Z?Z.substring(0,50):"command"}${Z&&Z.length>50?"...":""})`}case"Glob":return`Glob(${Y.pattern||"*"})`;case"Grep":{let{pattern:Z,path:X}=Y;if(X)return`Grep("${Z}" in ${X})`;return`Grep("${Z}")`}case"WebFetch":{let Z=Y.url;if(Z)try{return`WebFetch(${new URL(Z).hostname})`}catch{return`WebFetch(${Z.substring(0,30)}${Z.length>30?"...":""})`}return"WebFetch(url)"}case"WebSearch":return`WebSearch("${Y.query||"query"}")`;case"TodoWrite":return`TodoWrite(${Y.todos?.length||0} items)`;case"UndoEdit":return`UndoEdit(${Y.file_path||"file"})`;case"Skill":{let{skill:Z,args:X}=Y;if(X)return`Skill(${Z}: "${X.substring(0,30)}${X.length>30?"...":""}")`;return`Skill(${Z||"skill"})`}case"Task":{let{description:Z,subagent_type:X}=Y;if(Z)return`Task(${X||"agent"}: ${Z})`;return`Task(${X||"agent"})`}default:return`${$}()`}}function $Q($,Y){if(!Y?.displayContent)return!1;switch($){case"Write":return(Y.metadata?.file_size||0)<1e4;case"Edit":return!0;case"Bash":return(Y.metadata?.stdout_length||0)<1000;case"Read":case"TodoWrite":return!1;default:return!1}}import{promises as P6}from"fs";import*as YQ from"path";var m$,hO,ZQ;var XQ=b(()=>{C2();w1();A1();u2();m$=c("Agent"),hO={name:"init",description:"分析当前项目并生成 BLADE.md 配置文件",usage:"/init",async handler($,Y){try{let{cwd:Z,signal:X}=Y,Q=C1(Y),J=(H)=>{Q.sendMessage(`${H}`)},q=$1().session.sessionId,K=YQ.join(Z,"BLADE.md"),G=!1,U=!1;try{if(G=(await P6.stat(K)).isFile(),G)U=(await P6.readFile(K,"utf-8")).trim().length===0}catch{G=!1}if(G&&!U){Q.sendMessage("⚠️ BLADE.md 已存在。"),Q.sendMessage("\uD83D\uDCA1 正在分析现有文件并提供改进建议...");let H=await l1.create();if(X?.aborted)return{success:!1,message:"操作已取消"};let z=`Please analyze the existing BLADE.md file and provide improvement suggestions.
1648
1650
 
1649
1651
  **Important**:
1650
1652
  - After each step, briefly describe what you found before proceeding
@@ -1655,7 +1657,7 @@ ${Z}
1655
1657
 
1656
1658
  **Step-by-step process:**
1657
1659
 
1658
- 1. Read the current BLADE.md file at ${G} and summarize its current structure
1660
+ 1. Read the current BLADE.md file at ${K} and summarize its current structure
1659
1661
 
1660
1662
  2. Read package.json and note:
1661
1663
  - Any new scripts or commands not documented
@@ -1684,7 +1686,7 @@ ${Z}
1684
1686
  - 具体的改进建议(附带示例)
1685
1687
  - 如果需要重大修改,提供完整的改进版本内容
1686
1688
 
1687
- **Final output**: Return your analysis and suggestions as plain text. Do NOT use Write tool.`;g$.info(`[/init] Starting agent.chat, signal.aborted: ${X?.aborted}`);let z=await H.chat(_,{messages:[],userId:"cli-user",sessionId:q||"init-session",workspaceRoot:Z,signal:X},{onToolStart:(L)=>{if(L.type!=="function")return;try{let B=JSON.parse(L.function.arguments),N=j6(L.function.name,B);J(N)}catch{}},onToolResult:async(L,B)=>{if(L.type!=="function")return;if(B?.metadata?.summary)J(B.metadata.summary)}});if(g$.info(`[/init] agent.chat completed, signal.aborted: ${X?.aborted}`),X?.aborted)return g$.info("[/init] Returning cancelled after agent.chat"),{success:!1,message:"操作已取消"};return Q.sendMessage(z),{success:!0,message:"✅ 分析完成"}}if(W)Q.sendMessage("⚠️ 检测到空的 BLADE.md 文件,将重新生成...");Q.sendMessage("\uD83D\uDD0D 正在分析项目结构...");let O=await m1.create();if(X?.aborted)return{success:!1,message:"操作已取消"};let U=`Please analyze this codebase and generate BLADE.md content.
1689
+ **Final output**: Return your analysis and suggestions as plain text. Do NOT use Write tool.`;m$.info(`[/init] Starting agent.chat, signal.aborted: ${X?.aborted}`);let N=await H.chat(z,{messages:[],userId:"cli-user",sessionId:q||"init-session",workspaceRoot:Z,signal:X},{onToolStart:(L)=>{if(L.type!=="function")return;try{let B=JSON.parse(L.function.arguments),_=v6(L.function.name,B);J(_)}catch{}},onToolResult:async(L,B)=>{if(L.type!=="function")return;if(B?.metadata?.summary)J(B.metadata.summary)}});if(m$.info(`[/init] agent.chat completed, signal.aborted: ${X?.aborted}`),X?.aborted)return m$.info("[/init] Returning cancelled after agent.chat"),{success:!1,message:"操作已取消"};return Q.sendMessage(N),{success:!0,message:"✅ 分析完成"}}if(U)Q.sendMessage("⚠️ 检测到空的 BLADE.md 文件,将重新生成...");Q.sendMessage("\uD83D\uDD0D 正在分析项目结构...");let O=await l1.create();if(X?.aborted)return{success:!1,message:"操作已取消"};let W=`Please analyze this codebase and generate BLADE.md content.
1688
1690
 
1689
1691
  **Important**: After each step, briefly describe what you found before proceeding.
1690
1692
 
@@ -1731,7 +1733,7 @@ ${Z}
1731
1733
  - Focus on non-obvious insights
1732
1734
  - Be concise but comprehensive for complex projects
1733
1735
 
1734
- **Final output**: Return ONLY the complete BLADE.md content (markdown format), ready to be written to the file.`;g$.info(`[/init] Starting agent.chat for new BLADE.md, signal.aborted: ${X?.aborted}`);let F=await O.chat(U,{messages:[],userId:"cli-user",sessionId:q||"init-session",workspaceRoot:Z,signal:X},{onToolStart:(H)=>{if(H.type!=="function")return;try{let _=JSON.parse(H.function.arguments),z=j6(H.function.name,_);J(z)}catch{}},onToolResult:async(H,_)=>{if(H.type!=="function")return;if(_?.metadata?.summary)J(_.metadata.summary)}});if(g$.info(`[/init] agent.chat completed for new BLADE.md, signal.aborted: ${X?.aborted}`),X?.aborted)return g$.info("[/init] Returning cancelled after agent.chat (new BLADE.md)"),{success:!1,message:"操作已取消"};if(!F||F.trim().length===0)throw Error("Agent 未能生成有效的 BLADE.md 内容");return Q.sendMessage("✨ 正在写入 BLADE.md..."),await y6.writeFile(G,F,"utf-8"),{success:!0,message:"✅ 已成功生成 BLADE.md 文件"}}catch(Z){return{success:!1,error:`初始化失败: ${Z instanceof Error?Z.message:"未知错误"}`}}}},xX=NO});var BO,gX;var uX=b(()=>{N1();BO={name:"model",description:"管理和切换模型配置",usage:"/model [子命令] [参数]",fullDescription:`
1736
+ **Final output**: Return ONLY the complete BLADE.md content (markdown format), ready to be written to the file.`;m$.info(`[/init] Starting agent.chat for new BLADE.md, signal.aborted: ${X?.aborted}`);let F=await O.chat(W,{messages:[],userId:"cli-user",sessionId:q||"init-session",workspaceRoot:Z,signal:X},{onToolStart:(H)=>{if(H.type!=="function")return;try{let z=JSON.parse(H.function.arguments),N=v6(H.function.name,z);J(N)}catch{}},onToolResult:async(H,z)=>{if(H.type!=="function")return;if(z?.metadata?.summary)J(z.metadata.summary)}});if(m$.info(`[/init] agent.chat completed for new BLADE.md, signal.aborted: ${X?.aborted}`),X?.aborted)return m$.info("[/init] Returning cancelled after agent.chat (new BLADE.md)"),{success:!1,message:"操作已取消"};if(!F||F.trim().length===0)throw Error("Agent 未能生成有效的 BLADE.md 内容");return Q.sendMessage("✨ 正在写入 BLADE.md..."),await P6.writeFile(K,F,"utf-8"),{success:!0,message:"✅ 已成功生成 BLADE.md 文件"}}catch(Z){return{success:!1,error:`初始化失败: ${Z instanceof Error?Z.message:"未知错误"}`}}}},ZQ=hO});var xO,QQ;var JQ=b(()=>{A1();xO={name:"model",description:"管理和切换模型配置",usage:"/model [子命令] [参数]",fullDescription:`
1735
1737
  管理和切换模型配置
1736
1738
 
1737
1739
  子命令:
@@ -1743,49 +1745,49 @@ ${Z}
1743
1745
  /model # 显示模型选择器
1744
1746
  /model add # 添加新模型
1745
1747
  /model remove 千问 # 删除名称包含"千问"的模型
1746
- `,async handler($,Y){let Z=$[0];if(!Z){if(K6().length===0)return{success:!1,message:`❌ 没有可用的模型配置
1748
+ `,async handler($,Y){let Z=$[0];if(!Z){if(O6().length===0)return{success:!1,message:`❌ 没有可用的模型配置
1747
1749
 
1748
1750
  使用 /model add 添加模型`};return{success:!0,message:"show_model_selector",data:{action:"show_model_selector"}}}switch(Z){case"add":return{success:!0,message:"show_model_add_wizard",data:{action:"show_model_add_wizard",mode:"add"}};case"remove":{let X=$.slice(1).join(" ");if(!X)return{success:!1,message:`❌ 请指定要删除的模型名称
1749
- 用法: /model remove <名称>`};let J=K6().find((q)=>q.name.toLowerCase().includes(X.toLowerCase()));if(!J)return{success:!1,message:`❌ 未找到匹配的模型配置: ${X}`};try{return await A1().removeModel(J.id),{success:!0,message:`✅ 已删除模型配置: ${J.name}`}}catch(q){return{success:!1,message:`❌ ${q.message}`}}}default:return{success:!1,message:`❌ 未知的子命令: ${Z}
1750
- 使用 /model 查看可用操作`}}}},gX=BO});var LO,mX;var dX=b(()=>{j2();N1();LO={name:"skills",description:"查看所有可用的 Skills",fullDescription:"显示所有已发现的 Skills 及其详细信息,包括名称、描述、来源和允许的工具。",usage:"/skills",category:"system",examples:["/skills"],handler:async($,Y)=>{try{return await $0().refresh(),{success:!0,message:"show_skills_manager",data:{action:"show_skills_manager"}}}catch(Z){let X=`获取 Skills 失败: ${Z instanceof Error?Z.message:"未知错误"}`;return _0().addAssistantMessage(X),{success:!1,error:X}}}},mX=LO});async function wO($,Y){return{success:!0,message:"show_theme_selector",data:{action:"show_theme_selector"}}}var AO,cX;var lX=b(()=>{AO={name:"theme",description:"打开交互式主题选择器",aliases:["themes","style"],usage:"/theme",examples:["/theme"],category:"ui",handler:wO},cX=AO});import bO from"fuse.js";function g4($){return $.trim().startsWith("/")}function RO($){let Y=$.trim();if(!Y.startsWith("/"))throw Error("不是有效的 slash command");let Z=Y.slice(1).split(/\s+/),X=Z[0]||"",Q=Z.slice(1);return{command:X,args:Q}}function VO($){if(v6[$])return v6[$];for(let Y of Object.values(v6))if(Y.aliases?.includes($))return Y;return}function iX($){let Y=$.argumentHint?`/${$.name} ${$.argumentHint}`:`/${$.name}`;return{name:$.name,description:$.description,fullDescription:`[Skill] ${$.description}${$.whenToUse?`
1751
+ 用法: /model remove <名称>`};let J=O6().find((q)=>q.name.toLowerCase().includes(X.toLowerCase()));if(!J)return{success:!1,message:`❌ 未找到匹配的模型配置: ${X}`};try{return await D1().removeModel(J.id),{success:!0,message:`✅ 已删除模型配置: ${J.name}`}}catch(q){return{success:!1,message:`❌ ${q.message}`}}}default:return{success:!1,message:`❌ 未知的子命令: ${Z}
1752
+ 使用 /model 查看可用操作`}}}},QQ=xO});var pO,qQ;var KQ=b(()=>{v2();A1();pO={name:"skills",description:"查看所有可用的 Skills",fullDescription:"显示所有已发现的 Skills 及其详细信息,包括名称、描述、来源和允许的工具。",usage:"/skills",category:"system",examples:["/skills"],handler:async($,Y)=>{try{return await X0().refresh(),{success:!0,message:"show_skills_manager",data:{action:"show_skills_manager"}}}catch(Z){let X=`获取 Skills 失败: ${Z instanceof Error?Z.message:"未知错误"}`;return _0().addAssistantMessage(X),{success:!1,error:X}}}},qQ=pO});async function uO($,Y){return{success:!0,message:"show_theme_selector",data:{action:"show_theme_selector"}}}var gO,GQ;var UQ=b(()=>{gO={name:"theme",description:"打开交互式主题选择器",aliases:["themes","style"],usage:"/theme",examples:["/theme"],category:"ui",handler:uO},GQ=gO});import dO from"fuse.js";function m4($){return $.trim().startsWith("/")}function mO($){let Y=$.trim();if(!Y.startsWith("/"))throw Error("不是有效的 slash command");let Z=Y.slice(1).split(/\s+/),X=Z[0]||"",Q=Z.slice(1);return{command:X,args:Q}}function cO($){if(T6[$])return T6[$];for(let Y of Object.values(T6))if(Y.aliases?.includes($))return Y;return}function WQ($){let Y=$.argumentHint?`/${$.name} ${$.argumentHint}`:`/${$.name}`;return{name:$.name,description:$.description,fullDescription:`[Skill] ${$.description}${$.whenToUse?`
1751
1753
 
1752
- **When to use:** ${$.whenToUse}`:""}`,usage:Y,category:"skill",examples:[Y],handler:async(Z,X)=>{return{success:!0,message:`Invoking skill: ${$.name}`,data:{action:"invoke_skill",skillName:$.name,skillArgs:Z.join(" ")}}}}}function DO($){return $0().getUserInvocableSkills().find((X)=>X.name===$)}async function IO(){await a2()}async function aX($){return await i1.getInstance().initialize($)}async function u4($,Y){try{let{command:Z,args:X}=RO($),Q=VO(Z);if(Q)return await Q.handler(X,Y);let J=i1.getInstance();if(J.hasCommand(Z)){let G=J.getCommand(Z);if(G){let K=Y.workspaceRoot||process.cwd(),W=await J.executeCommand(Z,{args:X,workspaceRoot:K,signal:Y.signal});if(W)return{success:!0,message:`执行自定义命令: /${Z}`,data:{action:"invoke_custom_command",commandName:Z,processedContent:W,config:G.config}}}}await IO();let q=DO(Z);if(q)return await iX(q).handler(X,Y);return{success:!1,error:`未知命令: /${Z}
1753
- 使用 /help 查看可用命令`}}catch(Z){return{success:!1,error:`命令执行失败: ${Z instanceof Error?Z.message:"未知错误"}`}}}function rX(){let $=Object.values(v6),Z=i1.getInstance().getAllCommands().map((J)=>({name:J.name,description:J.config.description||J.content.slice(0,50),usage:J.config.argumentHint?`/${J.name} ${J.config.argumentHint}`:`/${J.name}`,category:"custom",handler:async()=>({success:!0})})),Q=$0().getUserInvocableSkills().map(iX);return[...$,...Z,...Q]}function nX($){let Y=($.startsWith("/")?$.slice(1):$).trim(),Z=Object.values(v6).map((U)=>({name:U.name,description:U.description,aliases:U.aliases||[],label:void 0,argumentHint:void 0,isCustom:!1,isSkill:!1})),X=i1.getInstance(),Q=X.getAllCommands().map((U)=>({name:U.name,description:U.config.description||U.content.slice(0,50),aliases:[],label:X.getCommandLabel(U),argumentHint:U.config.argumentHint,isCustom:!0,isSkill:!1})),q=$0().getUserInvocableSkills().map((U)=>({name:U.name,description:U.description,aliases:[],label:"(skill)",argumentHint:U.argumentHint,isCustom:!1,isSkill:!0})),G=[...Z,...Q,...q];if(!Y)return G.map((U)=>({command:`/${U.name}`,description:U.label?`${U.description} ${U.label}`:U.description,argumentHint:U.argumentHint,matchScore:50}));return new bO(G,{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(Y).map((U)=>{let F=U.score??1,H=Math.round((1-F)*100),_=U.item;return{command:`/${_.name}`,description:_.label?`${_.description} ${_.label}`:_.description,argumentHint:_.argumentHint,matchScore:H}}).filter((U)=>(U.matchScore||0)>=40)}var v6;var E6=b(()=>{j2();NX();v4();IX();jX();CX();pX();uX();k7();dX();lX();v6={...zX,init:xX,theme:cX,permissions:S4,model:gX,git:DX,ide:SX,skills:mX,hooks:MX}});import{nanoid as V_}from"nanoid";class D3{id;cwd;connection;clientCapabilities;agent=null;pendingPrompt=null;messages=[];mode="default";sessionApprovals=new Set;constructor($,Y,Z,X){this.id=$;this.cwd=Y;this.connection=Z;this.clientCapabilities=X}async initialize(){M1.debug(`[AcpSession ${this.id}] Initializing...`),X1.initializeSession(this.connection,this.id,this.clientCapabilities,this.cwd),M1.debug(`[AcpSession ${this.id}] ACP service context initialized`),this.agent=await m1.create({}),M1.debug(`[AcpSession ${this.id}] Agent created successfully`)}sendAvailableCommandsDelayed(){M1.debug(`[AcpSession ${this.id}] Scheduling available commands update (500ms delay)`),setTimeout(()=>{this.sendAvailableCommands()},500)}async handleSlashCommand($,Y){try{M1.debug(`[AcpSession ${this.id}] Executing slash command: ${$}`);let Z={cwd:this.cwd,signal:Y,acp:{sendMessage:(J)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:J}})},sendToolStart:(J,q,G)=>{let K=`tool_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,W=this.mapToolKind(G);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:K,status:"in_progress",title:`${J}`,content:[{type:"content",content:{type:"text",text:JSON.stringify(q,null,2)}}],kind:W})},sendToolResult:(J,q)=>{if(q.summary)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:q.summary}})}}},X=await u4($,Z),Q=X.content||X.message;if(Q)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:Q}});if(X.error)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`❌ ${X.error}`}});return{stopReason:X.success?"end_turn":"cancelled"}}catch(Z){return M1.error(`[AcpSession ${this.id}] Slash command error:`,Z),this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`❌ 命令执行失败: ${Z instanceof Error?Z.message:"未知错误"}`}}),{stopReason:"cancelled"}}}async sendAvailableCommands(){try{let $=rX(),Y=["model","permissions","theme","config","exit","ide"],X=$.filter((Q)=>!Y.includes(Q.name)).map((Q)=>{let J;if(Q.usage){let q=Q.usage.replace(/^\/\w+\s*/,"").trim();if(q)J=q}if(Q.aliases?.length){let q=`Aliases: ${Q.aliases.join(", ")}`;J=J?`${J} | ${q}`:q}return{name:Q.name,description:Q.description,input:J?{hint:J}:void 0}});M1.info(`[AcpSession ${this.id}] Sending available commands: ${JSON.stringify(X.map((Q)=>Q.name))}`),this.sendUpdate({sessionUpdate:"available_commands_update",availableCommands:X}),M1.info(`[AcpSession ${this.id}] Sent ${X.length} available commands`)}catch($){M1.error(`[AcpSession ${this.id}] Failed to send available commands:`,$)}}async prompt($){X1.setCurrentSession(this.id),this.pendingPrompt?.abort();let Y=new AbortController;if(this.pendingPrompt=Y,!this.agent)throw Error("Session not initialized");try{let Z=this.resolvePrompt($.prompt);if(M1.debug(`[AcpSession ${this.id}] Received prompt: ${Z.slice(0,100)}...`),g4(Z))return await this.handleSlashCommand(Z,Y.signal);let X={sessionId:this.id,userId:"acp-user",workspaceRoot:this.cwd,messages:[...this.messages],signal:Y.signal,permissionMode:this.mapModeToPermissionMode(),confirmationHandler:{requestConfirmation:async(q)=>{return this.requestPermission(q)}}},Q={signal:Y.signal,onContent:(q)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:q}})},onThinking:(q)=>{this.sendUpdate({sessionUpdate:"agent_thought_chunk",content:{type:"text",text:q}})},onToolStart:(q,G)=>{let K="function"in q?q.function.name:q.type,W=this.mapToolKind(G);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:q.id,status:"in_progress",title:`Executing ${K}`,content:[],kind:W})},onToolResult:async(q,G)=>{let K=[],W=G.metadata;if(W?.kind==="edit"&&W?.file_path&&W?.oldContent!==void 0&&W?.newContent!==void 0)K.push({type:"diff",path:W.file_path,oldText:W.oldContent,newText:W.newContent});else if(G.displayContent){let F=typeof G.displayContent==="string"?G.displayContent:JSON.stringify(G.displayContent);K.push({type:"content",content:{type:"text",text:F}})}let O="function"in q?q.function.name:q.type,U=G.success?"completed":"failed";this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:q.id,status:U,content:K})},onTodoUpdate:(q)=>{this.sendPlanUpdate(q)}},J=await this.agent.chat(Z,X,Q);if(J)this.messages.push({role:"user",content:Z}),this.messages.push({role:"assistant",content:J});if(Y.signal.aborted)return{stopReason:"cancelled"};return{stopReason:"end_turn"}}catch(Z){if(Y.signal.aborted||Z instanceof Error&&Z.name==="AbortError")return{stopReason:"cancelled"};throw M1.error(`[AcpSession ${this.id}] Prompt error:`,Z),Z}finally{if(this.pendingPrompt===Y)this.pendingPrompt=null}}cancel(){if(M1.info(`[AcpSession ${this.id}] Cancel requested`),this.pendingPrompt)this.pendingPrompt.abort(),this.pendingPrompt=null,M1.info(`[AcpSession ${this.id}] Cancelled successfully`);else M1.warn(`[AcpSession ${this.id}] No pending prompt to cancel`)}async setMode($){let Y=["default","auto-edit","yolo","plan"];this.mode=Y.includes($)?$:"default",M1.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(M1.info(`[AcpSession ${this.id}] Model set to: ${$}`),this.agent)M1.warn(`[AcpSession ${this.id}] Runtime model switching not yet implemented`)}async destroy(){if(this.cancel(),this.agent)await this.agent.destroy(),this.agent=null;X1.destroySession(this.id),M1.debug(`[AcpSession ${this.id}] Destroyed`)}resolvePrompt($){let Y=[];for(let Z of $)if(Z.type==="text")Y.push(Z.text);else if(Z.type==="image")Y.push(`[Image: ${Z.mimeType}]`);else if(Z.type==="resource"){let X=Z.resource;if("text"in X)Y.push(`<file path="${X.uri}">
1754
+ **When to use:** ${$.whenToUse}`:""}`,usage:Y,category:"skill",examples:[Y],handler:async(Z,X)=>{return{success:!0,message:`Invoking skill: ${$.name}`,data:{action:"invoke_skill",skillName:$.name,skillArgs:Z.join(" ")}}}}}function lO($){return X0().getUserInvocableSkills().find((X)=>X.name===$)}async function iO(){await o2()}async function OQ($){return await n1.getInstance().initialize($)}async function c4($,Y){try{let{command:Z,args:X}=mO($),Q=cO(Z);if(Q)return await Q.handler(X,Y);let J=n1.getInstance();if(J.hasCommand(Z)){let K=J.getCommand(Z);if(K){let G=Y.workspaceRoot||process.cwd(),U=await J.executeCommand(Z,{args:X,workspaceRoot:G,signal:Y.signal});if(U)return{success:!0,message:`执行自定义命令: /${Z}`,data:{action:"invoke_custom_command",commandName:Z,processedContent:U,config:K.config}}}}await iO();let q=lO(Z);if(q)return await WQ(q).handler(X,Y);return{success:!1,error:`未知命令: /${Z}
1755
+ 使用 /help 查看可用命令`}}catch(Z){return{success:!1,error:`命令执行失败: ${Z instanceof Error?Z.message:"未知错误"}`}}}function FQ(){let $=Object.values(T6),Z=n1.getInstance().getAllCommands().map((J)=>({name:J.name,description:J.config.description||J.content.slice(0,50),usage:J.config.argumentHint?`/${J.name} ${J.config.argumentHint}`:`/${J.name}`,category:"custom",handler:async()=>({success:!0})})),Q=X0().getUserInvocableSkills().map(WQ);return[...$,...Z,...Q]}function HQ($){let Y=($.startsWith("/")?$.slice(1):$).trim(),Z=Object.values(T6).map((W)=>({name:W.name,description:W.description,aliases:W.aliases||[],label:void 0,argumentHint:void 0,isCustom:!1,isSkill:!1})),X=n1.getInstance(),Q=X.getAllCommands().map((W)=>({name:W.name,description:W.config.description||W.content.slice(0,50),aliases:[],label:X.getCommandLabel(W),argumentHint:W.config.argumentHint,isCustom:!0,isSkill:!1})),q=X0().getUserInvocableSkills().map((W)=>({name:W.name,description:W.description,aliases:[],label:"(skill)",argumentHint:W.argumentHint,isCustom:!1,isSkill:!0})),K=[...Z,...Q,...q];if(!Y)return K.map((W)=>({command:`/${W.name}`,description:W.label?`${W.description} ${W.label}`:W.description,argumentHint:W.argumentHint,matchScore:50}));return new dO(K,{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(Y).map((W)=>{let F=W.score??1,H=Math.round((1-F)*100),z=W.item;return{command:`/${z.name}`,description:z.label?`${z.description} ${z.label}`:z.description,argumentHint:z.argumentHint,matchScore:H}}).filter((W)=>(W.matchScore||0)>=40)}var T6;var S6=b(()=>{v2();kX();T4();mX();lX();eX();XQ();JQ();d7();KQ();UQ();T6={...SX,init:ZQ,theme:GQ,permissions:h4,model:QQ,git:dX,ide:tX,skills:qQ,hooks:cX}});import{nanoid as lz}from"nanoid";class S3{id;cwd;connection;clientCapabilities;agent=null;pendingPrompt=null;messages=[];mode="default";sessionApprovals=new Set;constructor($,Y,Z,X){this.id=$;this.cwd=Y;this.connection=Z;this.clientCapabilities=X}async initialize(){v1.debug(`[AcpSession ${this.id}] Initializing...`),X1.initializeSession(this.connection,this.id,this.clientCapabilities,this.cwd),v1.debug(`[AcpSession ${this.id}] ACP service context initialized`),this.agent=await l1.create({}),v1.debug(`[AcpSession ${this.id}] Agent created successfully`)}sendAvailableCommandsDelayed(){v1.debug(`[AcpSession ${this.id}] Scheduling available commands update (500ms delay)`),setTimeout(()=>{this.sendAvailableCommands()},500)}async handleSlashCommand($,Y){try{v1.debug(`[AcpSession ${this.id}] Executing slash command: ${$}`);let Z={cwd:this.cwd,signal:Y,acp:{sendMessage:(J)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:J}})},sendToolStart:(J,q,K)=>{let G=`tool_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,U=this.mapToolKind(K);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:G,status:"in_progress",title:`${J}`,content:[{type:"content",content:{type:"text",text:JSON.stringify(q,null,2)}}],kind:U})},sendToolResult:(J,q)=>{if(q.summary)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:q.summary}})}}},X=await c4($,Z),Q=X.content||X.message;if(Q)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:Q}});if(X.error)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`❌ ${X.error}`}});return{stopReason:X.success?"end_turn":"cancelled"}}catch(Z){return v1.error(`[AcpSession ${this.id}] Slash command error:`,Z),this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`❌ 命令执行失败: ${Z instanceof Error?Z.message:"未知错误"}`}}),{stopReason:"cancelled"}}}async sendAvailableCommands(){try{let $=FQ(),Y=["model","permissions","theme","config","exit","ide"],X=$.filter((Q)=>!Y.includes(Q.name)).map((Q)=>{let J;if(Q.usage){let q=Q.usage.replace(/^\/\w+\s*/,"").trim();if(q)J=q}if(Q.aliases?.length){let q=`Aliases: ${Q.aliases.join(", ")}`;J=J?`${J} | ${q}`:q}return{name:Q.name,description:Q.description,input:J?{hint:J}:void 0}});v1.info(`[AcpSession ${this.id}] Sending available commands: ${JSON.stringify(X.map((Q)=>Q.name))}`),this.sendUpdate({sessionUpdate:"available_commands_update",availableCommands:X}),v1.info(`[AcpSession ${this.id}] Sent ${X.length} available commands`)}catch($){v1.error(`[AcpSession ${this.id}] Failed to send available commands:`,$)}}async prompt($){X1.setCurrentSession(this.id),this.pendingPrompt?.abort();let Y=new AbortController;if(this.pendingPrompt=Y,!this.agent)throw Error("Session not initialized");try{let Z=this.resolvePrompt($.prompt);if(v1.debug(`[AcpSession ${this.id}] Received prompt: ${Z.slice(0,100)}...`),m4(Z))return await this.handleSlashCommand(Z,Y.signal);let X={sessionId:this.id,userId:"acp-user",workspaceRoot:this.cwd,messages:[...this.messages],signal:Y.signal,permissionMode:this.mapModeToPermissionMode(),confirmationHandler:{requestConfirmation:async(q)=>{return this.requestPermission(q)}}},Q={signal:Y.signal,onContent:(q)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:q}})},onThinking:(q)=>{this.sendUpdate({sessionUpdate:"agent_thought_chunk",content:{type:"text",text:q}})},onToolStart:(q,K)=>{let G="function"in q?q.function.name:q.type,U=this.mapToolKind(K);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:q.id,status:"in_progress",title:`Executing ${G}`,content:[],kind:U})},onToolResult:async(q,K)=>{let G=[],U=K.metadata;if(U?.kind==="edit"&&U?.file_path&&U?.oldContent!==void 0&&U?.newContent!==void 0)G.push({type:"diff",path:U.file_path,oldText:U.oldContent,newText:U.newContent});else if(K.displayContent){let F=typeof K.displayContent==="string"?K.displayContent:JSON.stringify(K.displayContent);G.push({type:"content",content:{type:"text",text:F}})}let O="function"in q?q.function.name:q.type,W=K.success?"completed":"failed";this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:q.id,status:W,content:G})},onTodoUpdate:(q)=>{this.sendPlanUpdate(q)}},J=await this.agent.chat(Z,X,Q);if(J)this.messages.push({role:"user",content:Z}),this.messages.push({role:"assistant",content:J});if(Y.signal.aborted)return{stopReason:"cancelled"};return{stopReason:"end_turn"}}catch(Z){if(Y.signal.aborted||Z instanceof Error&&Z.name==="AbortError")return{stopReason:"cancelled"};throw v1.error(`[AcpSession ${this.id}] Prompt error:`,Z),Z}finally{if(this.pendingPrompt===Y)this.pendingPrompt=null}}cancel(){if(v1.info(`[AcpSession ${this.id}] Cancel requested`),this.pendingPrompt)this.pendingPrompt.abort(),this.pendingPrompt=null,v1.info(`[AcpSession ${this.id}] Cancelled successfully`);else v1.warn(`[AcpSession ${this.id}] No pending prompt to cancel`)}async setMode($){let Y=["default","auto-edit","yolo","plan"];this.mode=Y.includes($)?$:"default",v1.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(v1.info(`[AcpSession ${this.id}] Model set to: ${$}`),this.agent)v1.warn(`[AcpSession ${this.id}] Runtime model switching not yet implemented`)}async destroy(){if(this.cancel(),this.agent)await this.agent.destroy(),this.agent=null;X1.destroySession(this.id),v1.debug(`[AcpSession ${this.id}] Destroyed`)}resolvePrompt($){let Y=[];for(let Z of $)if(Z.type==="text")Y.push(Z.text);else if(Z.type==="image")Y.push(`[Image: ${Z.mimeType}]`);else if(Z.type==="resource"){let X=Z.resource;if("text"in X)Y.push(`<file path="${X.uri}">
1754
1756
  ${X.text}
1755
1757
  </file>`)}else if(Z.type==="resource_link")Y.push(`[Resource: ${Z.uri}]`);return Y.join(`
1756
- `)}sendUpdate($){let Y={sessionId:this.id,update:$};this.connection.sessionUpdate(Y).catch((Z)=>{M1.warn(`[AcpSession ${this.id}] Failed to send update:`,Z)})}sendPlanUpdate($){let Y=$.map((Z)=>({content:Z.content,priority:Z.priority,status:Z.status}));M1.debug(`[AcpSession ${this.id}] Sending plan update with ${Y.length} entries`),this.sendUpdate({sessionUpdate:"plan",entries:Y})}async requestPermission($){let Y=$.kind?.toLowerCase()||"execute";if(this.shouldAutoApprove(Y))return M1.debug(`[AcpSession ${this.id}] Auto-approving ${Y} in mode: ${this.mode}`),{approved:!0};if(this.mode==="plan"&&(Y==="write"||Y==="execute"))return M1.debug(`[AcpSession ${this.id}] Rejecting ${Y} in plan mode`),{approved:!1,reason:"Write and execute operations are not allowed in Plan mode"};let Z=`${Y}:${$.title||"unknown"}`;if(this.sessionApprovals.has(Z))return M1.debug(`[AcpSession ${this.id}] Using cached approval for: ${Z}`),{approved:!0};try{let X=V_(),Q=[];if($.message)Q.push({type:"content",content:{type:"text",text:$.message}});if($.risks&&$.risks.length>0)Q.push({type:"content",content:{type:"text",text:`Risks:
1758
+ `)}sendUpdate($){let Y={sessionId:this.id,update:$};this.connection.sessionUpdate(Y).catch((Z)=>{v1.warn(`[AcpSession ${this.id}] Failed to send update:`,Z)})}sendPlanUpdate($){let Y=$.map((Z)=>({content:Z.content,priority:Z.priority,status:Z.status}));v1.debug(`[AcpSession ${this.id}] Sending plan update with ${Y.length} entries`),this.sendUpdate({sessionUpdate:"plan",entries:Y})}async requestPermission($){let Y=$.kind?.toLowerCase()||"execute";if(this.shouldAutoApprove(Y))return v1.debug(`[AcpSession ${this.id}] Auto-approving ${Y} in mode: ${this.mode}`),{approved:!0};if(this.mode==="plan"&&(Y==="write"||Y==="execute"))return v1.debug(`[AcpSession ${this.id}] Rejecting ${Y} in plan mode`),{approved:!1,reason:"Write and execute operations are not allowed in Plan mode"};let Z=`${Y}:${$.title||"unknown"}`;if(this.sessionApprovals.has(Z))return v1.debug(`[AcpSession ${this.id}] Using cached approval for: ${Z}`),{approved:!0};try{let X=lz(),Q=[];if($.message)Q.push({type:"content",content:{type:"text",text:$.message}});if($.risks&&$.risks.length>0)Q.push({type:"content",content:{type:"text",text:`Risks:
1757
1759
  - ${$.risks.join(`
1758
- - `)}`}});let J=this.mapToolKind(Y),q={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:X,status:"pending",title:$.title||"Permission Required",content:Q,kind:J}},K=(await this.connection.requestPermission(q)).outcome;if(K.outcome==="cancelled")return{approved:!1,reason:"User cancelled the permission request"};let W=K.optionId,O=W==="allow_once"||W==="allow_always";if(W==="allow_always")this.sessionApprovals.add(Z),M1.debug(`[AcpSession ${this.id}] Cached approval for: ${Z}`);return{approved:O,reason:O?void 0:"User denied the operation"}}catch(X){return M1.warn(`[AcpSession ${this.id}] Permission request failed:`,X),{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 M1;var oJ=b(()=>{T2();s1();V1();E6();j$();M1=n("Agent")});import{PROTOCOL_VERSION as D_}from"@agentclientprotocol/sdk";import{nanoid as I_}from"nanoid";class I3{connection;sessions=new Map;clientCapabilities;constructor($){this.connection=$}async initialize($){return U2.info("[BladeAgent] Initializing ACP connection"),U2.debug(`[BladeAgent] Client capabilities: ${JSON.stringify($.clientCapabilities)}`),this.clientCapabilities=$.clientCapabilities,{protocolVersion:D_,agentCapabilities:{loadSession:!1,promptCapabilities:{image:!0,audio:!1,embeddedContext:!0},mcpCapabilities:{http:!0,sse:!0}}}}async authenticate($){return}async newSession($){let Y=I_();U2.info(`[BladeAgent] Creating new session: ${Y}`),U2.debug(`[BladeAgent] Session cwd: ${$.cwd||process.cwd()}`);let Z=new D3(Y,$.cwd||process.cwd(),this.connection,this.clientCapabilities);await Z.initialize(),this.sessions.set(Y,Z),U2.info(`[BladeAgent] Session ${Y} created, scheduling available commands update`),Z.sendAvailableCommandsDelayed();let X=C1(),Q=X?.models||[],J=X?.currentModelId||Q[0]?.id,q=Q.map((K)=>({modelId:K.id,name:K.name||K.id,description:K.provider?`Provider: ${K.provider}`:void 0}));return{sessionId:Y,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:q.length>0?{availableModels:q,currentModelId:J}:void 0}}async prompt($){let Y=this.sessions.get($.sessionId);if(!Y)throw Error(`Session not found: ${$.sessionId}`);return Y.prompt($)}async cancel($){U2.info(`[BladeAgent] Cancel notification received for session: ${$.sessionId}`);let Y=this.sessions.get($.sessionId);if(Y)U2.info("[BladeAgent] Found session, calling session.cancel()"),Y.cancel();else U2.warn(`[BladeAgent] Session not found for cancel: ${$.sessionId}`)}async setSessionMode($){U2.info(`[BladeAgent] Setting session mode: ${$.modeId}`);let Y=this.sessions.get($.sessionId);if(Y)await Y.setMode($.modeId);return{}}async unstable_setSessionModel($){U2.info(`[BladeAgent] Setting session model: ${$.modelId}`);let Y=this.sessions.get($.sessionId);if(Y)await Y.setModel($.modelId);return{}}async destroy(){for(let $ of this.sessions.values())await $.destroy();this.sessions.clear()}}var U2;var sJ=b(()=>{V1();N1();oJ();U2=n("Agent")});var tJ={};Oq(tJ,{runAcpIntegration:()=>y_});import*as w9 from"@agentclientprotocol/sdk";import{Readable as M_,Writable as j_}from"node:stream";async function y_(){let $=j_.toWeb(process.stdout),Y=M_.toWeb(process.stdin),Z=w9.ndJsonStream($,Y);await new w9.AgentSideConnection((Q)=>new I3(Q),Z).closed}var eJ=b(()=>{sJ()});import{render as v_}from"ink";import E_ from"react";import P_ from"yargs";import{hideBin as Yq}from"yargs/helpers";X6();var k3={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:"},"output-format":{alias:["outputFormat"],type:"string",choices:["text","json","stream-json"],default:"text",describe:"Output format (only works with --print)",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:"},model:{type:"string",describe:"Model for the current session",group:"AI Options:"},"fallback-model":{alias:["fallbackModel"],type:"string",describe:"Enable automatic fallback to specified model",group:"AI 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:"}},l2={scriptName:"blade",usage:"$0 [command] [options]",description:P3(),version:O$(),locale:"en",showHelpOnFail:!0,demandCommand:!1,recommendCommands:!0,strict:!1};_$();V1();N1();var P9=n("General"),Y5=($)=>{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 Y=$.allowedTools.filter((Z)=>$.disallowedTools.includes(Z));if(Y.length>0)throw Error(`Tools cannot be both allowed and disallowed: ${Y.join(", ")}`)}},Z5=async($)=>{try{let Z=await G0.getInstance().initialize();if(e().config.actions.setConfig(Z),$.debug)P9.info("[CLI] 配置已加载到 Store")}catch(Y){P9.error("[CLI] ❌ 配置初始化失败",Y instanceof Error?Y.message:Y),console.error(`
1760
+ - `)}`}});let J=this.mapToolKind(Y),q={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:X,status:"pending",title:$.title||"Permission Required",content:Q,kind:J}},G=(await this.connection.requestPermission(q)).outcome;if(G.outcome==="cancelled")return{approved:!1,reason:"User cancelled the permission request"};let U=G.optionId,O=U==="allow_once"||U==="allow_always";if(U==="allow_always")this.sessionApprovals.add(Z),v1.debug(`[AcpSession ${this.id}] Cached approval for: ${Z}`);return{approved:O,reason:O?void 0:"User denied the operation"}}catch(X){return v1.warn(`[AcpSession ${this.id}] Permission request failed:`,X),{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 v1;var Nq=b(()=>{C2();$0();w1();S6();v$();v1=c("Agent")});import{PROTOCOL_VERSION as iz}from"@agentclientprotocol/sdk";import{nanoid as rz}from"nanoid";class k3{connection;sessions=new Map;clientCapabilities;constructor($){this.connection=$}async initialize($){return F2.info("[BladeAgent] Initializing ACP connection"),F2.debug(`[BladeAgent] Client capabilities: ${JSON.stringify($.clientCapabilities)}`),this.clientCapabilities=$.clientCapabilities,{protocolVersion:iz,agentCapabilities:{loadSession:!1,promptCapabilities:{image:!0,audio:!1,embeddedContext:!0},mcpCapabilities:{http:!0,sse:!0}}}}async authenticate($){return}async newSession($){let Y=rz();F2.info(`[BladeAgent] Creating new session: ${Y}`),F2.debug(`[BladeAgent] Session cwd: ${$.cwd||process.cwd()}`);let Z=new S3(Y,$.cwd||process.cwd(),this.connection,this.clientCapabilities);await Z.initialize(),this.sessions.set(Y,Z),F2.info(`[BladeAgent] Session ${Y} created, scheduling available commands update`),Z.sendAvailableCommandsDelayed();let X=x1(),Q=X?.models||[],J=X?.currentModelId||Q[0]?.id,q=Q.map((G)=>({modelId:G.id,name:G.name||G.id,description:G.provider?`Provider: ${G.provider}`:void 0}));return{sessionId:Y,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:q.length>0?{availableModels:q,currentModelId:J}:void 0}}async prompt($){let Y=this.sessions.get($.sessionId);if(!Y)throw Error(`Session not found: ${$.sessionId}`);return Y.prompt($)}async cancel($){F2.info(`[BladeAgent] Cancel notification received for session: ${$.sessionId}`);let Y=this.sessions.get($.sessionId);if(Y)F2.info("[BladeAgent] Found session, calling session.cancel()"),Y.cancel();else F2.warn(`[BladeAgent] Session not found for cancel: ${$.sessionId}`)}async setSessionMode($){F2.info(`[BladeAgent] Setting session mode: ${$.modeId}`);let Y=this.sessions.get($.sessionId);if(Y)await Y.setMode($.modeId);return{}}async unstable_setSessionModel($){F2.info(`[BladeAgent] Setting session model: ${$.modelId}`);let Y=this.sessions.get($.sessionId);if(Y)await Y.setModel($.modelId);return{}}async destroy(){for(let $ of this.sessions.values())await $.destroy();this.sessions.clear()}}var F2;var Bq=b(()=>{w1();A1();Nq();F2=c("Agent")});var _q={};vq(_q,{runAcpIntegration:()=>oz});import*as R8 from"@agentclientprotocol/sdk";import{Readable as az,Writable as nz}from"node:stream";async function oz(){let $=nz.toWeb(process.stdout),Y=az.toWeb(process.stdin),Z=R8.ndJsonStream($,Y);await new R8.AgentSideConnection((Q)=>new k3(Q),Z).closed}var Lq=b(()=>{Bq()});import{render as sz}from"ink";import tz from"react";import ez from"yargs";import{hideBin as Aq}from"yargs/helpers";q6();var d3={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:"},"output-format":{alias:["outputFormat"],type:"string",choices:["text","json","stream-json"],default:"text",describe:"Output format (only works with --print)",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:"},model:{type:"string",describe:"Model for the current session",group:"AI Options:"},"fallback-model":{alias:["fallbackModel"],type:"string",describe:"Enable automatic fallback to specified model",group:"AI 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:"}},a2={scriptName:"blade",usage:"$0 [command] [options]",description:u3(),version:z$(),locale:"en",showHelpOnFail:!0,demandCommand:!1,recommendCommands:!0,strict:!1};_$();w1();A1();var k8=c("General"),W5=($)=>{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 Y=$.allowedTools.filter((Z)=>$.disallowedTools.includes(Z));if(Y.length>0)throw Error(`Tools cannot be both allowed and disallowed: ${Y.join(", ")}`)}},O5=async($)=>{try{let Z=await W0.getInstance().initialize();if($1().config.actions.setConfig(Z),$.debug)k8.info("[CLI] 配置已加载到 Store")}catch(Y){k8.error("[CLI] ❌ 配置初始化失败",Y instanceof Error?Y.message:Y),console.error(`
1759
1761
  ❌ 配置初始化失败
1760
1762
  `),console.error("原因:",Y instanceof Error?Y.message:"未知错误"),console.error(`
1761
1763
  请检查:`),console.error(" 1. 配置文件格式是否正确 (~/.blade/config.json)"),console.error(" 2. 是否需要运行 blade 进行首次配置"),console.error(` 3. 配置文件权限是否正确
1762
- `),process.exit(1)}if($.continue&&$.resume)throw Error("Cannot use both --continue and --resume flags simultaneously")},X5=($)=>{if($.outputFormat&&$.outputFormat!=="text"&&!$.print)throw Error("--output-format can only be used with --print flag");if($.inputFormat==="stream-json"&&$.print)P9.warn("⚠️ Warning: stream-json input format may not work as expected with --print")};_$();var Q5={command:"doctor",describe:"Check the health of your Blade installation",handler:async()=>{console.log(`\uD83D\uDD0D Running Blade health check...
1763
- `);let $=0;try{await G0.getInstance().initialize(),console.log("✅ Configuration: OK")}catch(X){console.log("❌ Configuration: FAILED"),console.log(` Error: ${X instanceof Error?X.message:"未知错误"}`),$++}let Y=process.version;if(parseInt(Y.slice(1).split(".")[0])>=18)console.log(`✅ Node.js version: ${Y}`);else console.log(`⚠️ Node.js version: ${Y} (recommended: v18+)`),$++;try{let X=await import("fs/promises"),Q=process.cwd();await X.access(Q,(await import("fs")).constants.R_OK|(await import("fs")).constants.W_OK),console.log("✅ File system permissions: OK")}catch(X){console.log("❌ File system permissions: FAILED"),console.log(" Error: Cannot read/write in current directory"),$++}try{await import("ink"),console.log("✅ Dependencies: OK")}catch(X){console.log("❌ Dependencies: FAILED"),console.log(" Error: Missing required dependencies"),$++}if(console.log(`
1764
- \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)}};var J5={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(Y){console.error(`❌ Installation failed: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}};L$();B$();N1();import w5 from"os";import Y4 from"path";function XG(){console.log(`
1764
+ `),process.exit(1)}if($.continue&&$.resume)throw Error("Cannot use both --continue and --resume flags simultaneously")},F5=($)=>{if($.outputFormat&&$.outputFormat!=="text"&&!$.print)throw Error("--output-format can only be used with --print flag");if($.inputFormat==="stream-json"&&$.print)k8.warn("⚠️ Warning: stream-json input format may not work as expected with --print")};_$();var H5={command:"doctor",describe:"Check the health of your Blade installation",handler:async()=>{console.log(`\uD83D\uDD0D Running Blade health check...
1765
+ `);let $=0;try{await W0.getInstance().initialize(),console.log("✅ Configuration: OK")}catch(X){console.log("❌ Configuration: FAILED"),console.log(` Error: ${X instanceof Error?X.message:"未知错误"}`),$++}let Y=process.version;if(parseInt(Y.slice(1).split(".")[0])>=18)console.log(`✅ Node.js version: ${Y}`);else console.log(`⚠️ Node.js version: ${Y} (recommended: v18+)`),$++;try{let X=await import("fs/promises"),Q=process.cwd();await X.access(Q,(await import("fs")).constants.R_OK|(await import("fs")).constants.W_OK),console.log("✅ File system permissions: OK")}catch(X){console.log("❌ File system permissions: FAILED"),console.log(" Error: Cannot read/write in current directory"),$++}try{await import("ink"),console.log("✅ Dependencies: OK")}catch(X){console.log("❌ Dependencies: FAILED"),console.log(" Error: Missing required dependencies"),$++}if(console.log(`
1766
+ \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)}};var z5={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(Y){console.error(`❌ Installation failed: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}};b$();A$();A1();import y5 from"os";import Q4 from"path";function RK(){console.log(`
1765
1767
  blade mcp
1766
1768
  `),console.log(`管理 MCP 服务器
1767
1769
  `),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 字符串添加服务器
1768
1770
  `),console.log("Options:"),console.log(` -h, --help 显示帮助信息 [boolean]
1769
1771
  `),console.log("Examples:"),console.log(" blade mcp list"),console.log(" blade mcp add github npx -y @modelcontextprotocol/server-github"),console.log(" blade mcp add api --transport http http://localhost:3000"),console.log(` blade mcp remove github
1770
1772
  `),console.log(`使用 blade mcp <command> --help 查看各子命令的详细帮助
1771
- `)}function QG($){return $.reduce((Y,Z)=>{let[X,...Q]=Z.split("=");return Y[X]=Q.join("="),Y},{})}function JG($){return $.reduce((Y,Z)=>{let[X,...Q]=Z.split(":");return Y[X.trim()]=Q.join(":").trim(),Y},{})}var qG={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:Y,commandOrUrl:Z,args:X,transport:Q,env:J,header:q,timeout:G}=$,K=$.global===!0;if($["--"]&&$["--"].length>0)Z=$["--"][0],X=$["--"].slice(1);if(!Y||!Z)console.error("❌ 缺少必需参数: name 和 commandOrUrl"),console.log(`
1773
+ `)}function VK($){return $.reduce((Y,Z)=>{let[X,...Q]=Z.split("=");return Y[X]=Q.join("="),Y},{})}function DK($){return $.reduce((Y,Z)=>{let[X,...Q]=Z.split(":");return Y[X.trim()]=Q.join(":").trim(),Y},{})}var IK={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:Y,commandOrUrl:Z,args:X,transport:Q,env:J,header:q,timeout:K}=$,G=$.global===!0;if($["--"]&&$["--"].length>0)Z=$["--"][0],X=$["--"].slice(1);if(!Y||!Z)console.error("❌ 缺少必需参数: name 和 commandOrUrl"),console.log(`
1772
1774
  \uD83D\uDCA1 用法:`),console.log(" blade mcp add <name> <command> [args...]"),console.log(" blade mcp add <name> -- <command> [args...]"),console.log(`
1773
- 示例:`),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 W={type:Q};if(Q==="stdio"){if(W.command=Z,W.args=X||[],J&&Array.isArray(J))W.env=QG(J)}else if(W.url=Z,q&&Array.isArray(q))W.headers=JG(q);if(G)W.timeout=G;await A1().addMcpServer(Y,W,{scope:K?"global":"project"});let O=K?Y4.join(w5.homedir(),".blade","config.json"):Y4.join(process.cwd(),".blade","config.json");console.log(`✅ MCP 服务器 "${Y}" 已添加`),console.log(` 配置文件: ${O}`)}catch(Y){console.error(`❌ 添加失败: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}},GG={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 Y=A0(),Z=$.global===!0;if(!Y[$.name])console.error(`❌ 服务器 "${$.name}" 不存在`),process.exit(1);await A1().removeMcpServer($.name,{scope:Z?"global":"project"}),console.log(`✅ MCP 服务器 "${$.name}" 已删除`)}catch(Y){console.error(`❌ 删除失败: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}},KG={command:"list",describe:"列出所有 MCP 服务器并检查健康状态",aliases:["ls"],handler:async()=>{try{let $=A0();if(console.log(""),Object.keys($).length===0){console.log("暂无配置的 MCP 服务器");return}console.log(`检查 MCP 服务器健康状态...
1774
- `);let Y=n1.getInstance(),Z=Object.entries($).map(async([Q,J])=>{try{let q=Y.getServerStatus(Q);if(!q)await Y.registerServer(Q,J),q=Y.getServerStatus(Q);else if(q.status==="disconnected")await Y.connectServer(Q);return{name:Q,config:J,serverInfo:q}}catch(q){return{name:Q,config:J,serverInfo:null,error:q}}}),X=await Promise.all(Z);for(let{name:Q,config:J,serverInfo:q,error:G}of X){let K=q?.status||"disconnected",W=K==="connected"?"✓":"✗",O=K==="connected"?"Connected":"Failed";if(console.log(`${Q}: ${J.type==="stdio"?J.command:J.url} - ${W} ${O}`),G&&K!=="connected")console.log(` 错误: ${G instanceof Error?G.message:String(G)}`)}console.log("");for(let{name:Q}of X)try{await Y.unregisterServer(Q)}catch(J){}process.exit(0)}catch($){console.error(`❌ 列表获取失败: ${$ instanceof Error?$.message:"未知错误"}`),process.exit(1)}}},UG={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=A0()[$.name];if(!Z)console.error(`❌ 服务器 "${$.name}" 不存在`),process.exit(1);console.log(`
1775
+ 示例:`),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 U={type:Q};if(Q==="stdio"){if(U.command=Z,U.args=X||[],J&&Array.isArray(J))U.env=VK(J)}else if(U.url=Z,q&&Array.isArray(q))U.headers=DK(q);if(K)U.timeout=K;await D1().addMcpServer(Y,U,{scope:G?"global":"project"});let O=G?Q4.join(y5.homedir(),".blade","config.json"):Q4.join(process.cwd(),".blade","config.json");console.log(`✅ MCP 服务器 "${Y}" 已添加`),console.log(` 配置文件: ${O}`)}catch(Y){console.error(`❌ 添加失败: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}},MK={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 Y=V0(),Z=$.global===!0;if(!Y[$.name])console.error(`❌ 服务器 "${$.name}" 不存在`),process.exit(1);await D1().removeMcpServer($.name,{scope:Z?"global":"project"}),console.log(`✅ MCP 服务器 "${$.name}" 已删除`)}catch(Y){console.error(`❌ 删除失败: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}},jK={command:"list",describe:"列出所有 MCP 服务器并检查健康状态",aliases:["ls"],handler:async()=>{try{let $=V0();if(console.log(""),Object.keys($).length===0){console.log("暂无配置的 MCP 服务器");return}console.log(`检查 MCP 服务器健康状态...
1776
+ `);let Y=t1.getInstance(),Z=Object.entries($).map(async([Q,J])=>{try{let q=Y.getServerStatus(Q);if(!q)await Y.registerServer(Q,J),q=Y.getServerStatus(Q);else if(q.status==="disconnected")await Y.connectServer(Q);return{name:Q,config:J,serverInfo:q}}catch(q){return{name:Q,config:J,serverInfo:null,error:q}}}),X=await Promise.all(Z);for(let{name:Q,config:J,serverInfo:q,error:K}of X){let G=q?.status||"disconnected",U=G==="connected"?"✓":"✗",O=G==="connected"?"Connected":"Failed";if(console.log(`${Q}: ${J.type==="stdio"?J.command:J.url} - ${U} ${O}`),K&&G!=="connected")console.log(` 错误: ${K instanceof Error?K.message:String(K)}`)}console.log("");for(let{name:Q}of X)try{await Y.unregisterServer(Q)}catch(J){}process.exit(0)}catch($){console.error(`❌ 列表获取失败: ${$ instanceof Error?$.message:"未知错误"}`),process.exit(1)}}},yK={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=V0()[$.name];if(!Z)console.error(`❌ 服务器 "${$.name}" 不存在`),process.exit(1);console.log(`
1775
1777
  服务器: ${$.name}
1776
- `),console.log(JSON.stringify(Z,null,2))}catch(Y){console.error(`❌ 获取失败: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}},WG={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 Y=JSON.parse($.json),Z=$.global===!0;if(!Y.type)throw Error('配置必须包含 "type" 字段');await A1().addMcpServer($.name,Y,{scope:Z?"global":"project"});let X=Z?Y4.join(w5.homedir(),".blade","config.json"):Y4.join(process.cwd(),".blade","config.json");console.log(`✅ MCP 服务器 "${$.name}" 已添加`),console.log(` 配置文件: ${X}`)}catch(Y){console.error(`❌ 添加失败: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}},A5={command:"mcp",describe:"管理 MCP 服务器",builder:($)=>{return $.command(qG).command(GG).command(KG).command(UG).command(WG).demandCommand(0).help(!1).option("help",{alias:"h",type:"boolean",describe:"显示帮助信息"})},handler:($)=>{let Y=["add","remove","list","ls","get","add-json"];if(!$._.some((X)=>Y.includes(X))||$.help)XG(),process.exit(0)}};T2();function BW($){return $.command("* [message]","Print response and exit (useful for pipes)",(Y)=>{return Y.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(Y)=>{if(!Y.print)return;try{let Z=await m1.create({systemPrompt:Y.systemPrompt,appendSystemPrompt:Y.appendSystemPrompt,maxTurns:Y.maxTurns}),X="",Q=Y._?.[0];if(Q&&typeof Q==="string")X=Q;else if(!process.stdin.isTTY){let q=[];for await(let G of process.stdin)q.push(G);X=Buffer.concat(q).toString("utf-8").trim()}else X="Hello";let J;if(Y.appendSystemPrompt)J=await Z.chatWithSystem(Y.appendSystemPrompt,X);else J=await Z.chat(X,{messages:[],userId:"cli-user",sessionId:`print-${Date.now()}`,workspaceRoot:process.cwd()});if(Y.outputFormat==="json")console.log(JSON.stringify({response:J,input:X,model:Y.model,timestamp:new Date().toISOString()},null,2));else if(Y.outputFormat==="stream-json")console.log(JSON.stringify({type:"response",content:J}));else console.log(J);process.exit(0)}catch(Z){console.error(`Error: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}})}async function uZ(){if(process.argv.slice(2).findIndex((Z)=>Z==="--print"||Z==="-p")===-1)return!1;try{let Z=(await import("yargs")).default,{hideBin:X}=await import("yargs/helpers"),Q=Z(X(process.argv)).scriptName("blade").strict(!1);return BW(Q),await Q.parse(),!0}catch(Z){console.error(`Print mode error: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}import{execSync as DW}from"child_process";import*as e2 from"fs/promises";import*as f2 from"path";import mZ from"semver";import{fileURLToPath as LW}from"url";var E7="blade-code",wW="https://cdn.jsdelivr.net/npm/blade-code@latest/CHANGELOG.md",dZ=f2.join(process.env.HOME||process.env.USERPROFILE||".",".blade"),cZ=f2.join(dZ,"version-cache.json"),AW=3600000,bW=`https://registry.npmjs.org/${E7}/latest`;async function RW(){try{if(process.env.BLADE_VERSION)return process.env.BLADE_VERSION;let $=LW(import.meta.url),Y=f2.dirname($),Z=[f2.join(Y,"..","..","package.json"),f2.join(Y,"..","package.json"),f2.join(process.cwd(),"package.json")];for(let X of Z)try{let Q=await e2.readFile(X,"utf-8"),J=JSON.parse(Q);if(J.name===E7&&J.version)return J.version}catch{}return"unknown"}catch{return"unknown"}}async function lZ(){try{let $=await e2.readFile(cZ,"utf-8"),Y=JSON.parse($);if(Date.now()-Y.checkedAt<AW)return Y;return{...Y,checkedAt:0}}catch{return null}}async function iZ($){try{await e2.mkdir(dZ,{recursive:!0}),await e2.writeFile(cZ,JSON.stringify($,null,2))}catch{}}async function VW(){try{let $=new AbortController,Y=setTimeout(()=>$.abort(),5000),Z=await fetch(bW,{signal:$.signal,headers:{Accept:"application/json"}});if(clearTimeout(Y),!Z.ok)return null;return(await Z.json()).version||null}catch{return null}}async function P7($=!1){let Y=await RW(),Z=wW;if(Y==="unknown")return{currentVersion:Y,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:Z,error:"Unable to determine current version"};let X=await lZ(),Q=X?.skipUntilVersion,J=null;if(!$&&X&&X.checkedAt>0)J=X.latestVersion;else if(J=await VW(),J)await iZ({latestVersion:J,checkedAt:Date.now(),skipUntilVersion:Q});if(!J)return{currentVersion:Y,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:Z,error:"Unable to check for updates"};let q=mZ.gt(J,Y),G=q;if(q&&Q)G=mZ.gt(J,Q);return{currentVersion:Y,latestVersion:J,hasUpdate:q,shouldPrompt:G,releaseNotesUrl:Z}}async function aZ($){let Y=await lZ();await iZ({latestVersion:Y?.latestVersion||$,checkedAt:Y?.checkedAt||Date.now(),skipUntilVersion:$})}function T7(){return`npm install -g ${E7}@latest`}async function rZ(){let{spawn:$}=await import("child_process");return new Promise((Y)=>{let Z=T7(),X=$(Z,{stdio:"inherit",shell:!0});X.on("close",(Q)=>{if(Q===0)Y({success:!0,message:"✅ 升级成功!请重新启动 blade。"});else Y({success:!1,message:`❌ 升级失败 (exit code: ${Q})`})}),X.on("error",(Q)=>{Y({success:!1,message:`❌ 升级失败: ${Q.message}`})})})}async function nZ(){try{let $=await P7();return $.shouldPrompt?$:null}catch{return null}}var oZ={command:"update",describe:"Check for updates and install if available",handler:async()=>{console.log("\uD83D\uDD0D Checking for updates...");try{let $=await P7(!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{DW("npm install -g blade-code@latest --registry https://registry.npmjs.org",{stdio:"inherit"}),console.log(""),console.log("✅ Update complete!")}catch(Y){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)}}};V1();s1();z0();V1();N1();function sZ(){process.stdout.write("\x1B[?25h"),process.stdout.write("\x1B[0m")}var Z2=n("Service");function IW($){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 h${static instance=null;cleanupHandlers=[];isShuttingDown=!1;initialized=!1;constructor(){}static getInstance(){if(!h$.instance)h$.instance=new h$;return h$.instance}initialize(){if(this.initialized){Z2.debug("[GracefulShutdown] 已初始化,跳过重复初始化");return}if(process.on("uncaughtException",($)=>{this.handleFatalError("uncaughtException",$)}),process.on("unhandledRejection",($)=>{let Y=$ instanceof Error?$:Error(String($));this.handleFatalError("unhandledRejection",Y)}),process.on("SIGTERM",()=>{Z2.info("[GracefulShutdown] 收到 SIGTERM 信号"),this.shutdown("SIGTERM",0)}),process.env.BLADE_NON_INTERACTIVE==="true")process.on("SIGINT",()=>{Z2.info("[GracefulShutdown] 收到 SIGINT 信号(非交互模式)"),this.shutdown("SIGINT",0)});this.initialized=!0,Z2.debug("[GracefulShutdown] 全局错误处理器已初始化")}registerCleanup($){return this.cleanupHandlers.push($),Z2.debug(`[GracefulShutdown] 注册清理函数,当前共 ${this.cleanupHandlers.length} 个`),()=>{let Y=this.cleanupHandlers.indexOf($);if(Y!==-1)this.cleanupHandlers.splice(Y,1),Z2.debug(`[GracefulShutdown] 取消注册清理函数,剩余 ${this.cleanupHandlers.length} 个`)}}handleFatalError($,Y){if(this.isShuttingDown){console.error(`[GracefulShutdown] 退出过程中发生额外错误 (${$}):`,Y);return}if(console.error(""),console.error("═".repeat(60)),console.error(`\uD83D\uDCA5 发生未捕获的错误 (${$})`),console.error("═".repeat(60)),console.error(""),console.error("错误信息:",Y.message),console.error(""),Y.stack)console.error("堆栈跟踪:"),console.error(Y.stack);console.error(""),console.error("═".repeat(60)),console.error(""),this.shutdown($,1)}async shutdown($,Y=0){if(this.isShuttingDown){Z2.debug("[GracefulShutdown] 已在退出过程中,跳过重复退出");return}this.isShuttingDown=!0,Z2.info(`[GracefulShutdown] 开始优雅退出 (原因: ${$})`);try{let Q=H1.getInstance();if(Q.isEnabled()){let J=e(),q=J.session?.sessionId||"unknown",G=J.config?.config?.permissionMode||"default";await Q.executeSessionEndHooks(IW($),{projectDir:process.cwd(),sessionId:q,permissionMode:G})}}catch(Q){Z2.debug("[GracefulShutdown] SessionEnd hooks 执行失败:",Q)}let Z=5000,X=new Promise((Q,J)=>{setTimeout(()=>{J(Error(`清理超时 (${Z}ms)`))},Z)});try{let Q=this.runCleanupHandlers();await Promise.race([Q,X]),Z2.info("[GracefulShutdown] 所有清理函数执行完成")}catch(Q){console.error("[GracefulShutdown] 清理过程中发生错误:",Q)}finally{sZ(),setTimeout(()=>{process.exit(Y)},100)}}async runCleanupHandlers(){let $=[...this.cleanupHandlers].reverse();for(let Y of $)try{let Z=Y();if(Z instanceof Promise)await Z}catch(Z){console.error("[GracefulShutdown] 清理函数执行失败:",Z)}}isExiting(){return this.isShuttingDown}reset(){this.isShuttingDown=!1,this.cleanupHandlers=[],this.initialized=!1}}var $$=()=>{return h$.getInstance()},tZ=($)=>{return $$().registerCleanup($)},eZ=()=>{$$().initialize()};var x$=($=0)=>{sZ(),process.exit($)};P$();_$();z0();L$();import{useMemoizedFn as rJ}from"ahooks";import{useEffect as b_,useState as V3}from"react";j2();E6();N1();E$();s1();V1();import{useMemoizedFn as H0}from"ahooks";import{Box as K$,useApp as B_}from"ink";import{useEffect as U$,useRef as z9}from"react";f4();H2();import{useShallow as EM}from"zustand/react/shallow";N1();N1();import{useStore as MO}from"zustand";function O1($){return MO(G6,$)}s1();var jO=[],oX=()=>O1(($)=>$.session.sessionId),m4=()=>O1(($)=>$.session.messages),sX=()=>O1(($)=>$.session.clearCount),tX=()=>O1(($)=>$.session.isCompacting);var u$=()=>O1(($)=>$.session.actions);var eX=()=>O1(($)=>{let{inputTokens:Y,maxContextTokens:Z}=$.session.tokenUsage;if(Z<=0)return 100;let X=Math.max(0,100-Y/Z*100);return Math.round(X)});var $Q=()=>O1(($)=>$.app.initializationStatus),YQ=()=>O1(($)=>$.app.initializationError),d4=()=>O1(($)=>$.app.activeModal),ZQ=()=>O1(($)=>$.app.todos),XQ=()=>O1(($)=>$.app.modelEditorTarget),QQ=()=>O1(($)=>$.app.sessionSelectorData),JQ=()=>O1(($)=>$.app.awaitingSecondCtrlC),x2=()=>O1(($)=>$.app.actions),c4=()=>O1(($)=>$.app.initializationStatus==="ready");var qQ=()=>O1(($)=>$.app.todos.length>0);var m$=()=>O1(($)=>$.config.config?.permissionMode||"default"),GQ=()=>O1(($)=>$.config.config?.models??jO),l4=()=>O1(($)=>{let Y=$.config.config;if(!Y)return;let Z=Y.currentModelId;return Y.models.find((Q)=>Q.id===Z)??Y.models[0]}),KQ=()=>O1(($)=>$.config.config?.currentModelId);var k1=()=>O1(($)=>{let Y=$.config.config?.theme??"default";if(j1.getCurrentThemeName()!==Y)try{j1.setTheme(Y)}catch{}return j1.getTheme()});var V0=()=>O1(($)=>$.focus.currentFocus);var UQ=()=>O1(($)=>$.focus.actions);var J2=()=>O1(($)=>$.command.isProcessing);var WQ=()=>O1(($)=>$.command.actions),OQ=()=>O1(($)=>$.command.pendingCommands);var FQ=()=>O1(($)=>$.app.thinkingModeEnabled),HQ=()=>O1(($)=>$.session.currentThinkingContent),_Q=()=>O1(($)=>$.session.thinkingExpanded),zQ=()=>O1(($)=>$.session.historyExpanded),NQ=()=>O1(($)=>$.session.expandedMessageCount);N1();z0();V1();import{useMemoizedFn as p7}from"ahooks";import{useEffect as vO,useRef as EO}from"react";E6();N1();T2();import{useMemoizedFn as BQ}from"ahooks";import{useRef as yO}from"react";function LQ($){let Y=yO(void 0),Z=BQ(async()=>{let Q=await m1.create({systemPrompt:$.systemPrompt,appendSystemPrompt:$.appendSystemPrompt,maxTurns:$.maxTurns});return Y.current=Q,Q}),X=BQ(()=>{if(Y.current)Y.current=void 0});return{agentRef:Y,createAgent:Z,cleanupAgent:X}}var wQ=n("UI");function PO($,Y,Z,X){switch($){case"show_theme_selector":return Z.setActiveModal("themeSelector"),!0;case"show_model_selector":return Z.setActiveModal("modelSelector"),!0;case"show_model_add_wizard":return Z.setActiveModal("modelAddWizard"),!0;case"show_permissions_manager":return Z.setActiveModal("permissionsManager"),!0;case"show_agents_manager":return Z.setActiveModal("agentsManager"),!0;case"show_skills_manager":return Z.setActiveModal("skillsManager"),!0;case"show_hooks_manager":return Z.setActiveModal("hooksManager"),!0;case"show_agent_creation_wizard":return Z.setActiveModal("agentCreationWizard"),!0;case"show_session_selector":{let Q=Y?.sessions;return Z.showSessionSelector(Q),!0}case"clear_screen":return X.clearMessages(),X.setError(null),X.resetTokenUsage(),Z.setTodos([]),!0;case"compact_completed":case"compact_fallback":return X.resetTokenUsage(),!0;case"exit_application":return x$(0),!0;default:return!1}}function TO($){return typeof $==="object"&&$!==null&&$.action==="invoke_skill"&&typeof $.skillName==="string"}function kO($){return typeof $==="object"&&$!==null&&$.action==="invoke_custom_command"&&typeof $.commandName==="string"&&typeof $.processedContent==="string"}function SO($){let{text:Y,images:Z,parts:X}=$;if(Z.length===0)return Y;let Q=[];for(let J of X)if(J.type==="text")Q.push({type:"text",text:J.text});else Q.push({type:"image_url",image_url:{url:`data:${J.mimeType};base64,${J.base64}`}});return Q}var AQ=($,Y,Z,X)=>{let Q=J2(),J=m4(),q=oX(),G=m$(),K=u$(),W=x2(),O=WQ(),U=EO(!1),{createAgent:F,cleanupAgent:H}=LQ({systemPrompt:$,appendSystemPrompt:Y,maxTurns:X});vO(()=>{return()=>{H()}},[H]);let _=p7(()=>{if(!Q)return;if(O.abort(),W.setTodos([]),!U.current)K.addAssistantMessage("✋ 任务已停止"),U.current=!0}),z=p7(async(B)=>{let{text:N}=B,I=!1;try{if(g4(N)){await o6();let k=O.createAbortController(),S={cwd:process.cwd(),signal:k.signal},y=await u4(N,S);if(y.message){if(PO(y.message,y.data,W,K))return{success:!0}}let v1=!1;if(TO(y.data)){let{skillName:m,skillArgs:t}=y.data,_1=t?`Please use the "${m}" skill to help me with: ${t}`:`Please use the "${m}" skill.`;K.addUserMessage(_1),I=!0,v1=!0,B={displayText:_1,text:_1,images:[],parts:[{type:"text",text:_1}]}}if(kO(y.data)){let{commandName:m,processedContent:t}=y.data;K.addUserMessage(N),I=!0,v1=!0;let _1=`# Custom Command: /${m}
1778
+ `),console.log(JSON.stringify(Z,null,2))}catch(Y){console.error(`❌ 获取失败: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}},EK={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 Y=JSON.parse($.json),Z=$.global===!0;if(!Y.type)throw Error('配置必须包含 "type" 字段');await D1().addMcpServer($.name,Y,{scope:Z?"global":"project"});let X=Z?Q4.join(y5.homedir(),".blade","config.json"):Q4.join(process.cwd(),".blade","config.json");console.log(`✅ MCP 服务器 "${$.name}" 已添加`),console.log(` 配置文件: ${X}`)}catch(Y){console.error(`❌ 添加失败: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}},E5={command:"mcp",describe:"管理 MCP 服务器",builder:($)=>{return $.command(IK).command(MK).command(jK).command(yK).command(EK).demandCommand(0).help(!1).option("help",{alias:"h",type:"boolean",describe:"显示帮助信息"})},handler:($)=>{let Y=["add","remove","list","ls","get","add-json"];if(!$._.some((X)=>Y.includes(X))||$.help)RK(),process.exit(0)}};C2();function xW($){return $.command("* [message]","Print response and exit (useful for pipes)",(Y)=>{return Y.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(Y)=>{if(!Y.print)return;try{let Z=await l1.create({systemPrompt:Y.systemPrompt,appendSystemPrompt:Y.appendSystemPrompt,maxTurns:Y.maxTurns}),X="",Q=Y._?.[0];if(Q&&typeof Q==="string")X=Q;else if(!process.stdin.isTTY){let q=[];for await(let K of process.stdin)q.push(K);X=Buffer.concat(q).toString("utf-8").trim()}else X="Hello";let J;if(Y.appendSystemPrompt)J=await Z.chatWithSystem(Y.appendSystemPrompt,X);else J=await Z.chat(X,{messages:[],userId:"cli-user",sessionId:`print-${Date.now()}`,workspaceRoot:process.cwd()});if(Y.outputFormat==="json")console.log(JSON.stringify({response:J,input:X,model:Y.model,timestamp:new Date().toISOString()},null,2));else if(Y.outputFormat==="stream-json")console.log(JSON.stringify({type:"response",content:J}));else console.log(J);process.exit(0)}catch(Z){console.error(`Error: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}})}async function JX(){if(process.argv.slice(2).findIndex((Z)=>Z==="--print"||Z==="-p")===-1)return!1;try{let Z=(await import("yargs")).default,{hideBin:X}=await import("yargs/helpers"),Q=Z(X(process.argv)).scriptName("blade").strict(!1);return xW(Q),await Q.parse(),!0}catch(Z){console.error(`Print mode error: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}import{execSync as lW}from"child_process";import*as Z$ from"fs/promises";import*as p2 from"path";import qX from"semver";import{fileURLToPath as pW}from"url";var p7="blade-code",uW="https://cdn.jsdelivr.net/npm/blade-code@latest/CHANGELOG.md",KX=p2.join(process.env.HOME||process.env.USERPROFILE||".",".blade"),GX=p2.join(KX,"version-cache.json"),gW=3600000,dW=`https://registry.npmjs.org/${p7}/latest`;async function mW(){try{if(process.env.BLADE_VERSION)return process.env.BLADE_VERSION;let $=pW(import.meta.url),Y=p2.dirname($),Z=[p2.join(Y,"..","..","package.json"),p2.join(Y,"..","package.json"),p2.join(process.cwd(),"package.json")];for(let X of Z)try{let Q=await Z$.readFile(X,"utf-8"),J=JSON.parse(Q);if(J.name===p7&&J.version)return J.version}catch{}return"unknown"}catch{return"unknown"}}async function UX(){try{let $=await Z$.readFile(GX,"utf-8"),Y=JSON.parse($);if(Date.now()-Y.checkedAt<gW)return Y;return{...Y,checkedAt:0}}catch{return null}}async function WX($){try{await Z$.mkdir(KX,{recursive:!0}),await Z$.writeFile(GX,JSON.stringify($,null,2))}catch{}}async function cW(){try{let $=new AbortController,Y=setTimeout(()=>$.abort(),5000),Z=await fetch(dW,{signal:$.signal,headers:{Accept:"application/json"}});if(clearTimeout(Y),!Z.ok)return null;return(await Z.json()).version||null}catch{return null}}async function u7($=!1){let Y=await mW(),Z=uW;if(Y==="unknown")return{currentVersion:Y,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:Z,error:"Unable to determine current version"};let X=await UX(),Q=X?.skipUntilVersion,J=null;if(!$&&X&&X.checkedAt>0)J=X.latestVersion;else if(J=await cW(),J)await WX({latestVersion:J,checkedAt:Date.now(),skipUntilVersion:Q});if(!J)return{currentVersion:Y,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:Z,error:"Unable to check for updates"};let q=qX.gt(J,Y),K=q;if(q&&Q)K=qX.gt(J,Q);return{currentVersion:Y,latestVersion:J,hasUpdate:q,shouldPrompt:K,releaseNotesUrl:Z}}async function OX($){let Y=await UX();await WX({latestVersion:Y?.latestVersion||$,checkedAt:Y?.checkedAt||Date.now(),skipUntilVersion:$})}function g7(){return`npm install -g ${p7}@latest`}async function FX(){let{spawn:$}=await import("child_process");return new Promise((Y)=>{let Z=g7(),X=$(Z,{stdio:"inherit",shell:!0});X.on("close",(Q)=>{if(Q===0)Y({success:!0,message:"✅ 升级成功!请重新启动 blade。"});else Y({success:!1,message:`❌ 升级失败 (exit code: ${Q})`})}),X.on("error",(Q)=>{Y({success:!1,message:`❌ 升级失败: ${Q.message}`})})})}async function HX(){try{let $=await u7();return $.shouldPrompt?$:null}catch{return null}}var zX={command:"update",describe:"Check for updates and install if available",handler:async()=>{console.log("\uD83D\uDD0D Checking for updates...");try{let $=await u7(!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{lW("npm install -g blade-code@latest --registry https://registry.npmjs.org",{stdio:"inherit"}),console.log(""),console.log("✅ Update complete!")}catch(Y){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)}}};w1();$0();L0();w1();A1();function NX(){process.stdout.write("\x1B[?25h"),process.stdout.write("\x1B[0m")}var J2=c("Service");function iW($){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 u${static instance=null;cleanupHandlers=[];isShuttingDown=!1;initialized=!1;constructor(){}static getInstance(){if(!u$.instance)u$.instance=new u$;return u$.instance}initialize(){if(this.initialized){J2.debug("[GracefulShutdown] 已初始化,跳过重复初始化");return}if(process.on("uncaughtException",($)=>{this.handleFatalError("uncaughtException",$)}),process.on("unhandledRejection",($)=>{let Y=$ instanceof Error?$:Error(String($));this.handleFatalError("unhandledRejection",Y)}),process.on("SIGTERM",()=>{J2.info("[GracefulShutdown] 收到 SIGTERM 信号"),this.shutdown("SIGTERM",0)}),process.env.BLADE_NON_INTERACTIVE==="true")process.on("SIGINT",()=>{J2.info("[GracefulShutdown] 收到 SIGINT 信号(非交互模式)"),this.shutdown("SIGINT",0)});this.initialized=!0,J2.debug("[GracefulShutdown] 全局错误处理器已初始化")}registerCleanup($){return this.cleanupHandlers.push($),J2.debug(`[GracefulShutdown] 注册清理函数,当前共 ${this.cleanupHandlers.length} 个`),()=>{let Y=this.cleanupHandlers.indexOf($);if(Y!==-1)this.cleanupHandlers.splice(Y,1),J2.debug(`[GracefulShutdown] 取消注册清理函数,剩余 ${this.cleanupHandlers.length} 个`)}}handleFatalError($,Y){if(this.isShuttingDown){console.error(`[GracefulShutdown] 退出过程中发生额外错误 (${$}):`,Y);return}if(console.error(""),console.error("═".repeat(60)),console.error(`\uD83D\uDCA5 发生未捕获的错误 (${$})`),console.error("═".repeat(60)),console.error(""),console.error("错误信息:",Y.message),console.error(""),Y.stack)console.error("堆栈跟踪:"),console.error(Y.stack);console.error(""),console.error("═".repeat(60)),console.error(""),this.shutdown($,1)}async shutdown($,Y=0){if(this.isShuttingDown){J2.debug("[GracefulShutdown] 已在退出过程中,跳过重复退出");return}this.isShuttingDown=!0,J2.info(`[GracefulShutdown] 开始优雅退出 (原因: ${$})`);try{let Q=H1.getInstance();if(Q.isEnabled()){let J=$1(),q=J.session?.sessionId||"unknown",K=J.config?.config?.permissionMode||"default";await Q.executeSessionEndHooks(iW($),{projectDir:process.cwd(),sessionId:q,permissionMode:K})}}catch(Q){J2.debug("[GracefulShutdown] SessionEnd hooks 执行失败:",Q)}let Z=5000,X=new Promise((Q,J)=>{setTimeout(()=>{J(Error(`清理超时 (${Z}ms)`))},Z)});try{let Q=this.runCleanupHandlers();await Promise.race([Q,X]),J2.info("[GracefulShutdown] 所有清理函数执行完成")}catch(Q){console.error("[GracefulShutdown] 清理过程中发生错误:",Q)}finally{NX(),setTimeout(()=>{process.exit(Y)},100)}}async runCleanupHandlers(){let $=[...this.cleanupHandlers].reverse();for(let Y of $)try{let Z=Y();if(Z instanceof Promise)await Z}catch(Z){console.error("[GracefulShutdown] 清理函数执行失败:",Z)}}isExiting(){return this.isShuttingDown}reset(){this.isShuttingDown=!1,this.cleanupHandlers=[],this.initialized=!1}}var X$=()=>{return u$.getInstance()},BX=($)=>{return X$().registerCleanup($)},_X=()=>{X$().initialize()};var g$=($=0)=>{NX(),process.exit($)};k$();_$();L0();b$();import{useMemoizedFn as Hq}from"ahooks";import{useEffect as mz,useState as T3}from"react";v2();S6();A1();S$();$0();w1();import{useMemoizedFn as B0}from"ahooks";import{Box as O$,useApp as pz}from"ink";import{useEffect as F$,useRef as L8}from"react";p4();B2();import{useShallow as Wj}from"zustand/react/shallow";A1();A1();import{useStore as rO}from"zustand";function O1($){return rO(W6,$)}$0();var aO=[],zQ=()=>O1(($)=>$.session.sessionId),l4=()=>O1(($)=>$.session.messages),NQ=()=>O1(($)=>$.session.clearCount),BQ=()=>O1(($)=>$.session.isCompacting);var c$=()=>O1(($)=>$.session.actions);var _Q=()=>O1(($)=>{let{inputTokens:Y,maxContextTokens:Z}=$.session.tokenUsage;if(Z<=0)return 100;let X=Math.max(0,100-Y/Z*100);return Math.round(X)});var LQ=()=>O1(($)=>$.app.initializationStatus),wQ=()=>O1(($)=>$.app.initializationError),i4=()=>O1(($)=>$.app.activeModal),AQ=()=>O1(($)=>$.app.todos),bQ=()=>O1(($)=>$.app.modelEditorTarget),RQ=()=>O1(($)=>$.app.sessionSelectorData),VQ=()=>O1(($)=>$.app.awaitingSecondCtrlC),g2=()=>O1(($)=>$.app.actions),r4=()=>O1(($)=>$.app.initializationStatus==="ready");var DQ=()=>O1(($)=>$.app.todos.length>0);var l$=()=>O1(($)=>$.config.config?.permissionMode||"default"),IQ=()=>O1(($)=>$.config.config?.models??aO),a4=()=>O1(($)=>{let Y=$.config.config;if(!Y)return;let Z=Y.currentModelId;return Y.models.find((Q)=>Q.id===Z)??Y.models[0]}),MQ=()=>O1(($)=>$.config.config?.currentModelId);var f1=()=>O1(($)=>{let Y=$.config.config?.theme??"default";if(P1.getCurrentThemeName()!==Y)try{P1.setTheme(Y)}catch{}return P1.getTheme()});var M0=()=>O1(($)=>$.focus.currentFocus);var jQ=()=>O1(($)=>$.focus.actions);var G2=()=>O1(($)=>$.command.isProcessing);var yQ=()=>O1(($)=>$.command.actions),EQ=()=>O1(($)=>$.command.pendingCommands);var vQ=()=>O1(($)=>$.app.thinkingModeEnabled),PQ=()=>O1(($)=>$.session.currentThinkingContent),TQ=()=>O1(($)=>$.session.thinkingExpanded),SQ=()=>O1(($)=>$.session.historyExpanded),kQ=()=>O1(($)=>$.session.expandedMessageCount);A1();L0();w1();import{useMemoizedFn as a7}from"ahooks";import{useEffect as oO,useRef as sO}from"react";S6();A1();C2();import{useMemoizedFn as CQ}from"ahooks";import{useRef as nO}from"react";function fQ($){let Y=nO(void 0),Z=CQ(async()=>{let Q=await l1.create({systemPrompt:$.systemPrompt,appendSystemPrompt:$.appendSystemPrompt,maxTurns:$.maxTurns});return Y.current=Q,Q}),X=CQ(()=>{if(Y.current)Y.current=void 0});return{agentRef:Y,createAgent:Z,cleanupAgent:X}}var hQ=c("UI");function tO($,Y,Z,X){switch($){case"show_theme_selector":return Z.setActiveModal("themeSelector"),!0;case"show_model_selector":return Z.setActiveModal("modelSelector"),!0;case"show_model_add_wizard":return Z.setActiveModal("modelAddWizard"),!0;case"show_permissions_manager":return Z.setActiveModal("permissionsManager"),!0;case"show_agents_manager":return Z.setActiveModal("agentsManager"),!0;case"show_skills_manager":return Z.setActiveModal("skillsManager"),!0;case"show_hooks_manager":return Z.setActiveModal("hooksManager"),!0;case"show_agent_creation_wizard":return Z.setActiveModal("agentCreationWizard"),!0;case"show_session_selector":{let Q=Y?.sessions;return Z.showSessionSelector(Q),!0}case"clear_screen":return X.clearMessages(),X.setError(null),X.resetTokenUsage(),Z.setTodos([]),!0;case"compact_completed":case"compact_fallback":return X.resetTokenUsage(),!0;case"exit_application":return g$(0),!0;default:return!1}}function eO($){return typeof $==="object"&&$!==null&&$.action==="invoke_skill"&&typeof $.skillName==="string"}function $F($){return typeof $==="object"&&$!==null&&$.action==="invoke_custom_command"&&typeof $.commandName==="string"&&typeof $.processedContent==="string"}function YF($){let{text:Y,images:Z,parts:X}=$;if(Z.length===0)return Y;let Q=[];for(let J of X)if(J.type==="text")Q.push({type:"text",text:J.text});else Q.push({type:"image_url",image_url:{url:`data:${J.mimeType};base64,${J.base64}`}});return Q}var xQ=($,Y,Z,X)=>{let Q=G2(),J=l4(),q=zQ(),K=l$(),G=c$(),U=g2(),O=yQ(),W=sO(!1),{createAgent:F,cleanupAgent:H}=fQ({systemPrompt:$,appendSystemPrompt:Y,maxTurns:X});oO(()=>{return()=>{H()}},[H]);let z=a7(()=>{if(!Q)return;if(O.abort(),U.setTodos([]),!W.current)G.addAssistantMessage("✋ 任务已停止"),W.current=!0}),N=a7(async(B)=>{let{text:_}=B,I=!1;try{if(m4(_)){await e6();let T=O.createAbortController(),C={cwd:process.cwd(),signal:T.signal},j=await c4(_,C);if(j.message){if(tO(j.message,j.data,U,G))return{success:!0}}let S1=!1;if(eO(j.data)){let{skillName:d,skillArgs:e}=j.data,B1=e?`Please use the "${d}" skill to help me with: ${e}`:`Please use the "${d}" skill.`;G.addUserMessage(B1),I=!0,S1=!0,B={displayText:B1,text:B1,images:[],parts:[{type:"text",text:B1}]}}if($F(j.data)){let{commandName:d,processedContent:e}=j.data;G.addUserMessage(_),I=!0,S1=!0;let B1=`# Custom Command: /${d}
1777
1779
 
1778
- The user has invoked the custom command "/${m}". Follow the instructions below to complete the task.
1780
+ The user has invoked the custom command "/${d}". Follow the instructions below to complete the task.
1779
1781
 
1780
1782
  ---
1781
1783
 
1782
- ${t}
1784
+ ${e}
1783
1785
 
1784
1786
  ---
1785
1787
 
1786
- Remember: Follow the above instructions carefully to complete the user's request.`;B={displayText:N,text:_1,images:[],parts:[{type:"text",text:_1}]}}if(!v1){if(!y.success&&y.error)return K.addAssistantMessage(`❌ ${y.error}`),{success:y.success,output:y.message,error:y.error,metadata:y.data};let m=y.message;if(y.success&&typeof m==="string"&&m.trim()!=="")K.addAssistantMessage(m);return{success:y.success,output:y.message,error:y.error,metadata:y.data}}}let M=H1.getInstance(),A=B,D,w=await M.executeUserPromptSubmitHooks(B.text,{projectDir:process.cwd(),sessionId:q,permissionMode:G,hasImages:B.images.length>0,imageCount:B.images.length});if(!w.proceed){if(w.warning)K.addAssistantMessage(`⚠️ ${w.warning}`);return{success:!1,error:"blocked by hook"}}if(w.updatedPrompt)A={...B,text:w.updatedPrompt,displayText:w.updatedPrompt,parts:[{type:"text",text:w.updatedPrompt}]};if(w.contextInjection)D=w.contextInjection;if(!I)K.addUserMessage(A.displayText);let R=SO(A),E=O.createAbortController(),x=await F();if(E.signal.aborted)return wQ.info("[handleCommandSubmit] Agent 创建期间已被中止"),{success:!1,error:"aborted"};let r=J.map((k)=>({role:k.role,content:k.content}));if(D)r.push({role:"system",content:`<user-prompt-submit-hook>
1788
+ Remember: Follow the above instructions carefully to complete the user's request.`;B={displayText:_,text:B1,images:[],parts:[{type:"text",text:B1}]}}if(!S1){if(!j.success&&j.error)return G.addAssistantMessage(`❌ ${j.error}`),{success:j.success,output:j.message,error:j.error,metadata:j.data};let d=j.message;if(j.success&&typeof d==="string"&&d.trim()!=="")G.addAssistantMessage(d);return{success:j.success,output:j.message,error:j.error,metadata:j.data}}}let M=H1.getInstance(),A=B,D,w=await M.executeUserPromptSubmitHooks(B.text,{projectDir:process.cwd(),sessionId:q,permissionMode:K,hasImages:B.images.length>0,imageCount:B.images.length});if(!w.proceed){if(w.warning)G.addAssistantMessage(`⚠️ ${w.warning}`);return{success:!1,error:"blocked by hook"}}if(w.updatedPrompt)A={...B,text:w.updatedPrompt,displayText:w.updatedPrompt,parts:[{type:"text",text:w.updatedPrompt}]};if(w.contextInjection)D=w.contextInjection;if(!I)G.addUserMessage(A.displayText);let R=YF(A),E=O.createAbortController(),x=await F();if(E.signal.aborted)return hQ.info("[handleCommandSubmit] Agent 创建期间已被中止"),{success:!1,error:"aborted"};let r=J.map((T)=>({role:T.role,content:T.content}));if(D)r.push({role:"system",content:`<user-prompt-submit-hook>
1787
1789
  ${D}
1788
- </user-prompt-submit-hook>`});let j={messages:r,userId:"cli-user",sessionId:q,workspaceRoot:process.cwd(),signal:E.signal,confirmationHandler:Z,permissionMode:G},C={onThinking:(k)=>{K.setCurrentThinkingContent(k)},onContent:(k)=>{if(k.trim())K.addAssistantMessageAndClearThinking(k)},onToolStart:(k)=>{if(k.type!=="function")return;if(k.function.name==="TodoWrite")return;try{let S=JSON.parse(k.function.arguments),y=j6(k.function.name,S);K.addToolMessage(y,{toolName:k.function.name,phase:"start",summary:y,params:S})}catch(S){wQ.error("[useCommandHandler] onToolStart error:",S)}},onToolResult:async(k,S)=>{if(k.type!=="function")return;if(!S?.metadata?.summary)return;let y=fX(k.function.name,S)?S.displayContent:void 0;K.addToolMessage(S.metadata.summary,{toolName:k.function.name,phase:"complete",summary:S.metadata.summary,detail:y})},onTokenUsage:(k)=>{K.updateTokenUsage(k)},onCompacting:(k)=>{if(K.setCompacting(k),!k)K.resetTokenUsage()},onTurnLimitReached:Z?async(k)=>{let S=await Z.requestConfirmation({type:"maxTurnsExceeded",title:"对话轮次上限",message:`已进行 ${k.turnsCount} 轮对话。是否继续?`,risks:["继续执行可能导致更长的等待时间","可能产生更多的 API 费用"]});return{continue:S.approved,reason:S.reason}}:void 0},Y1=await x.chat(R,j,C);if(!Y1||Y1.trim()===""){if(!U.current)K.addAssistantMessage("⏹ 已取消");return{success:!0,output:"已取消"}}return{success:!0,output:Y1}}catch(M){if(U.current)return{success:!1,error:"aborted"};let A=M instanceof Error?M.message:"未知错误",D=A.includes("can only concatenate str")||A.includes("image_url")||A.includes("multimodal")||A.includes("vision")||A.includes("does not support images"),w=A;if(D)w="当前模型不支持图片理解功能。请切换到支持视觉能力的模型(如 Claude 4.5、GPT-5.2、Gemini 3 Pro、Qwen3-VL-Plus 等)后重试。";let R={success:!1,error:w};return K.addAssistantMessage(`❌ ${w}`),R}}),L=p7(async(B)=>{if(!B.text.trim()&&B.images.length===0)return;if(Q){O.enqueueCommand({displayText:B.displayText,text:B.text,images:B.images,parts:B.parts});return}W.setTodos([]),U.current=!1,O.setProcessing(!0);try{let N=await z(B);if(!N.success&&N.error&&N.error!=="aborted")K.setError(N.error)}catch(N){if(N instanceof Error&&(N.name==="AbortError"||N.message.includes("aborted")));else{let I=N instanceof Error?N.message:"未知错误";K.setError(`执行失败: ${I}`)}}finally{O.setProcessing(!1),O.clearAbortController(),K.setCurrentThinkingContent(null);let N=O.dequeueCommand();if(N)setTimeout(()=>L({displayText:N.displayText,text:N.text,images:N.images,parts:N.parts}),100)}});return{executeCommand:L,handleAbort:_,isProcessing:Q}};import{useMemoizedFn as i4}from"ahooks";import{useState as bQ}from"react";var RQ=()=>{let[$,Y]=bQ([]),[Z,X]=bQ(-1),Q=i4((K,W)=>{let O={display:K,pasteMappings:W?new Map(W):new Map};Y((U)=>[...U,O]),X(-1)}),J=i4(()=>{if($.length===0)return null;let K=Z===-1?$.length-1:Math.max(0,Z-1);return X(K),$[K]||null}),q=i4(()=>{if(Z===-1)return null;let K=Z+1;if(K>=$.length)return X(-1),null;else return X(K),$[K]||null}),G=i4(()=>{X(-1)});return{commandHistory:$,historyIndex:Z,addToHistory:Q,getPreviousCommand:J,getNextCommand:q,resetHistoryIndex:G}};import{useMemoizedFn as VQ}from"ahooks";import{useMemo as CO,useState as fO}from"react";var DQ=()=>{let[$,Y]=fO({isVisible:!1,details:null,resolver:null}),Z=VQ((J)=>{return new Promise((q)=>{Y({isVisible:!0,details:J,resolver:q})})}),X=VQ((J)=>{if($.resolver)$.resolver(J);Y({isVisible:!1,details:null,resolver:null})}),Q=CO(()=>({requestConfirmation:Z}),[Z]);return{confirmationState:$,confirmationHandler:Q,handleResponse:X}};import{useMemoizedFn as Z$}from"ahooks";import{useRef as IQ,useState as hO}from"react";var a4="␞",r4="␟";function n4($){return`${a4}PASTE:${$}:`}function g7(){return r4}var Qj=new RegExp(`${a4}PASTE:(\\d+):[\\s\\S]*?${r4}`,"g");function xO($){return $.includes(a4)&&$.includes(r4)}function MQ($="",Y=0){let[Z,X]=hO({value:$,cursorPosition:Y}),Q=IQ(0),J=IQ(new Map),q=Z$((H)=>{X((_)=>({value:H,cursorPosition:_.cursorPosition}));for(let _ of J.current.keys()){let z=n4(_);if(!H.includes(z))J.current.delete(_)}}),G=Z$((H)=>{X((_)=>({..._,cursorPosition:Math.max(0,Math.min(H,_.value.length))}))}),K=Z$(()=>{X({value:"",cursorPosition:0}),J.current.clear()}),W=Z$((H)=>{Q.current+=1;let _=Q.current;return J.current.set(_,{type:"text",data:H}),_}),O=Z$((H,_)=>{Q.current+=1;let z=Q.current;return J.current.set(z,{type:"image",data:H,mimeType:_}),z}),U=Z$((H)=>{for(let[_,z]of H)if(J.current.set(_,z),_>=Q.current)Q.current=_}),F=Z$((H)=>{let _=[],z=[];if(!xO(H)){let E=H.trim();if(E)z.push({type:"text",text:E});return{displayText:H,text:H,images:_,parts:z}}let L=new RegExp(`${a4}PASTE:(\\d+):[\\s\\S]*?${r4}`,"g"),B=Array.from(H.matchAll(L)),N=0,I="",M="";for(let E of B){let x=E.index,r=x+E[0].length,j=parseInt(E[1],10),C=J.current.get(j);if(x>N){let Y1=H.slice(N,x);z.push({type:"text",text:Y1}),I+=Y1,M+=Y1}if(!C)I+=E[0],M+=E[0],z.push({type:"text",text:E[0]});else if(C.type==="text")I+=C.data,M+=C.data,z.push({type:"text",text:C.data});else{let Y1={id:j,base64:C.data,mimeType:C.mimeType};_.push(Y1),z.push({type:"image",...Y1}),M+=`[Image #${j}]`}N=r}if(N<H.length){let E=H.slice(N);z.push({type:"text",text:E}),I+=E,M+=E}let A=[];for(let E of z)if(E.type==="text"&&A.length>0&&A[A.length-1].type==="text")A[A.length-1].text+=E.text;else A.push(E);let D=0,w=A.length;while(D<A.length&&A[D].type==="text"&&A[D].text.trim()==="")D++;while(w>D&&A[w-1].type==="text"&&A[w-1].text.trim()==="")w--;let R=A.slice(D,w);return{displayText:M.trim(),text:I.trim(),images:_,parts:R}});return{value:Z.value,cursorPosition:Z.cursorPosition,setValue:q,setCursorPosition:G,clear:K,pasteMap:J.current,addPasteMapping:W,addImagePasteMapping:O,restorePasteMappings:U,resolveInput:F}}V1();E6();import{useMemoizedFn as TQ}from"ahooks";import{useInput as lO}from"ink";import{useEffect as kQ,useRef as SQ,useState as c7}from"react";T4();V4();import{useMemoizedFn as Gj}from"ahooks";import pO from"fast-glob";import gO from"fuse.js";import{useEffect as jQ,useMemo as u7,useState as m7}from"react";var d$=null,uO=5000;function mO($,Y){let Z=[...$.matchAll(/(?:^|\s)(@(?:"[^"]*"|(?:[^\\ ]|\\ )*))/g)];for(let X of Z){let Q=X[1],J=X.index+(X[0].length-Q.length),q=J+Q.length;if(Y>=J&&Y<=q){let G=Q.slice(1),K=!1;if(G.startsWith('"')){if(K=!0,G=G.slice(1),G.endsWith('"'))G=G.slice(0,-1)}return{hasQuery:!0,query:G,startIndex:J,endIndex:q,quoted:K}}}return{hasQuery:!1,query:"",startIndex:-1,endIndex:-1,quoted:!1}}var dO=[...Y2.map(($)=>`${$}/**`),...Y2,...f8.map(($)=>`**/${$}`)];function yQ($,Y,Z={}){let{cwd:X=process.cwd(),maxSuggestions:Q=15,ignorePatterns:J=dO,debounceDelay:q=300,fuzzyMatch:G=!0}=Z,[K,W]=m7([]),[O,U]=m7(!1),[F,H]=m7(0),_=u7(()=>JSON.stringify(J),[J]),z=u7(()=>{if(Y===void 0)return{hasQuery:!1,query:"",startIndex:-1,endIndex:-1,quoted:!1};return mO($,Y)},[$,Y]);jQ(()=>{if(!$.includes("@")){W([]),U(!1);return}let B=Date.now();if(d$&&d$.cwd===X&&d$.ignoreKey===_&&B-d$.timestamp<uO){W(d$.files),U(!1);return}let N=!1,M=setTimeout(async()=>{U(!0);try{let D=(await pO("**/*",{cwd:X,dot:!1,followSymbolicLinks:!1,onlyFiles:!1,markDirectories:!0,unique:!0,ignore:J})).map((w)=>w.replace(/\\/g,"/"));if(!N)W(D),d$={cwd:X,ignoreKey:_,files:D,timestamp:B}}catch(A){if(console.error("Failed to load files for @ completion:",A),!N)W([])}finally{if(!N)U(!1)}},q);return()=>{N=!0,clearTimeout(M)}},[$,X,q,_]);let L=u7(()=>{if(!z.hasQuery||K.length===0)return[];let B=z.query.toLowerCase();if(B==="")return K.slice(0,Q);if(G)return new gO(K,{threshold:0.4,ignoreLocation:!0,minMatchCharLength:1}).search(B).slice(0,Q).map((M)=>M.item);return K.filter((N)=>N.toLowerCase().includes(B)).slice(0,Q)},[z,K,Q,G]);return jQ(()=>{H(0)},[L]),{...z,suggestions:L,selectedIndex:F,loading:O}}function cO($,Y=!1){if($.includes(" ")||Y)return`@"${$}"`;return`@${$}`}function d7($,Y,Z){if(!Y.hasQuery)return{newInput:$,newCursorPos:$.length};let X=cO(Z,Y.quoted),Q=$.slice(0,Y.startIndex),J=$.slice(Y.endIndex),q=Q+X+" "+J,G=Y.startIndex+X.length+1;return{newInput:q,newCursorPos:G}}import{useMemoizedFn as vQ}from"ahooks";import{useEffect as EQ,useRef as PQ}from"react";N1();var p1=($,Y)=>{let Z=PQ(!1),X=PQ(null),Q=vQ(()=>{if(X.current)clearTimeout(X.current);X.current=setTimeout(()=>{C0().setAwaitingSecondCtrlC(!1),Z.current=!1,X.current=null},3000)}),J=()=>{$$().shutdown("SIGINT",0)},q=vQ(()=>{if(!Z.current){if(Z.current=!0,$&&Y)Y();C0().setAwaitingSecondCtrlC(!0),Q()}else{if(X.current)clearTimeout(X.current),X.current=null;C0().setAwaitingSecondCtrlC(!1),J()}});return EQ(()=>{if($){if(C0().setAwaitingSecondCtrlC(!1),Z.current=!1,X.current)clearTimeout(X.current),X.current=null}},[$]),EQ(()=>{return()=>{if(X.current)clearTimeout(X.current)}},[]),q};var o4=n("UI"),CQ=($,Y,Z,X,Q,J,q,G,K,W)=>{let U=V0()==="main-input",F=$.value,H=$.setValue,_=$.cursorPosition,z=u$(),L=x2(),B=l4(),N=B?C$(B):!1,[I,M]=c7(!1),[A,D]=c7([]),[w,R]=c7(0),E=yQ(F,_,{cwd:process.cwd(),maxSuggestions:10}),x=p1(q||!1,J),r=SQ(0),j=500,C=SQ(!1);kQ(()=>{if(q)C.current=!1},[q]),kQ(()=>{if(E.hasQuery&&E.suggestions.length>0){let S=E.suggestions.map((y)=>({command:y,description:y.endsWith("/")?`Directory: ${y}`:`File: ${y}`,matchScore:1}));D(S),M(!0),R(0)}else if(F.startsWith("/"))if(F.includes(" "))M(!1),D([]);else{let y=nX(F);D(y),M(y.length>0),R(0)}else M(!1),D([])},[F,E.hasQuery,E.suggestions]);let Y1=TQ(()=>{z.clearMessages(),z.setError(null)}),k=TQ(()=>{o4.debug("[DIAG] handleSubmit called:",{input:F,showSuggestions:I});let S=F.trim();if(S){let y=$.resolveInput(S);o4.debug("[DIAG] Submitting command:",{displayText:S,textLength:y.text.length,imageCount:y.images.length}),M(!1),D([]);let v1=$.pasteMap.size>0?new Map($.pasteMap):new Map;Q(S,v1),$.clear(),Y(y),o4.debug("[DIAG] Command submitted to onSubmit callback")}else o4.debug("[DIAG] Empty command, not submitting")});return lO((S,y)=>{if(S==="?"&&!F){K?.(),setTimeout(()=>$.clear(),0);return}if(y.backspace||y.delete||y.leftArrow||y.rightArrow||y.pageUp||y.pageDown||!y.ctrl&&!y.meta&&!y.escape&&!y.tab&&!y.upArrow&&!y.downArrow&&!y.return&&!(S==="?"&&!F))return;if(y.ctrl&&S==="c"||y.meta&&S==="c"||y.ctrl&&S==="d"||y.meta&&S==="d"){x();return}if(y.ctrl&&S==="l"||y.meta&&S==="l"){Y1();return}if(y.ctrl&&S==="t"||y.meta&&S==="t"){z.toggleThinkingExpanded();return}if(y.ctrl&&S==="o"||y.meta&&S==="o"){z.toggleHistoryExpanded();return}if(y.escape){if(W)K?.();else if(q&&J){if(C.current)return;C.current=!0,J()}else if(I)M(!1),D([]);else if(F){let m=Date.now();if(m-r.current<500)$.clear(),r.current=0;else r.current=m}return}if(y.tab&&y.shift){G?.();return}if(y.tab){if(I&&A.length>0){let m=A[w].command;if(E.hasQuery&&E.suggestions.includes(m)){let{newInput:t,newCursorPos:_1}=d7(F,E,m);H(t),$.setCursorPosition(_1)}else{let t=m+" ";H(t),$.setCursorPosition(t.length)}M(!1),D([])}else if(N)L.toggleThinkingMode();return}if(y.return){if(I&&A.length>0){let m=A[w].command;if(E.hasQuery&&E.suggestions.includes(m)){let{newInput:t,newCursorPos:_1}=d7(F,E,m);H(t),$.setCursorPosition(_1)}else{let t=m+" ";H(t),$.setCursorPosition(t.length)}M(!1),D([])}else k();return}if(y.upArrow){if(I&&A.length>0){let m=A.length-1;R((t)=>t>0?t-1:m)}else{let m=Z();if(m){if(m.pasteMappings.size>0)$.restorePasteMappings(m.pasteMappings);H(m.display),$.setCursorPosition(m.display.length)}}return}if(y.downArrow){if(I&&A.length>0){let m=A.length-1;R((t)=>t<m?t+1:0)}else{let m=X();if(m){if(m.pasteMappings.size>0)$.restorePasteMappings(m.pasteMappings);H(m.display),$.setCursorPosition(m.display.length)}}return}},{isActive:U}),{handleSubmit:k,showSuggestions:I,suggestions:A,selectedSuggestionIndex:w}};import oO from"ansi-escapes";import{useStdout as sO}from"ink";import{useCallback as tO,useEffect as eO,useRef as $F}from"react";import{useEffect as iO,useState as aO}from"react";import{useStdout as rO}from"ink";import{debounce as nO}from"lodash-es";function p2($=200){let{stdout:Y}=rO(),[Z,X]=aO(Y.columns||80);return iO(()=>{let Q=nO(()=>{X(Y.columns||80)},$);return Q(),Y.on("resize",Q),()=>{Y.off("resize",Q),Q.cancel()}},[Y,$]),Z}function fQ(){let{stdout:$}=sO(),Y=p2(),Z=$F(!0),X=O1((J)=>J.session.actions.incrementClearCount),Q=tO(()=>{if($)$.write(oO.clearTerminal);X()},[$,X]);return eO(()=>{if(Z.current){Z.current=!1;return}let J=setTimeout(()=>{Q()},300);return()=>{clearTimeout(J)}},[Y,Q]),{refreshStatic:Q}}T2();import{MultiSelect as YF}from"@inkjs/ui";import{useMemoizedFn as s4}from"ahooks";import{Box as o,Text as d,useFocus as ZF,useFocusManager as XF,useInput as pQ}from"ink";import t4 from"ink-select-input";import QF from"ink-spinner";import P6 from"ink-text-input";import hQ from"node:fs";import JF from"node:os";import l7 from"node:path";import{useEffect as xQ,useState as l$}from"react";import{jsxDEV as v}from"react/jsx-dev-runtime";var qF=[{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"}],GF=[{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 KF($){if(!$||$.trim()==="")return"名称不能为空";if(!/^[a-z0-9-]+$/.test($))return"名称只能包含小写字母、数字和连字符";if($.startsWith("-")||$.endsWith("-"))return"名称不能以连字符开头或结尾";return null}function T6({onComplete:$,onCancel:Y,initialConfig:Z}){let[X,Q]=l$(Z?"name":"mode"),[J,q]=l$({name:Z?.name||"",description:Z?.description||"",tools:Z?.tools||[],color:Z?.color,location:Z?.location||"project",systemPrompt:Z?.systemPrompt||""}),[G,K]=l$(""),[W,O]=l$(!1),[U,F]=l$(""),[H,_]=l$(Z?"edit":"manual"),{focus:z}=XF(),B={manual:["mode","name","description","tools","color","location","systemPrompt","confirm"],ai:["mode","aiPrompt","aiGenerating","confirm"],edit:["name","description","tools","color","location","systemPrompt","confirm"]}[H];xQ(()=>{if(X==="name"||X==="description"||X==="systemPrompt"||X==="aiPrompt")return;z(`step-${X}`)},[X,z]);let N=s4(()=>{let w=B.indexOf(X);if(w<B.length-1)Q(B[w+1])}),I=s4(()=>{if(U)F("");if(X==="confirm"&&H==="ai"){Q("aiPrompt");return}let w=B.indexOf(X);if(w>0)Q(B[w-1]);else Y()}),M=s4(async()=>{O(!0),F("");try{let w=await m1.create(),R=`你是一个 Subagent 配置生成专家。用户会描述他们想要创建的 agent,你需要根据描述生成一个完整的 agent 配置。
1790
+ </user-prompt-submit-hook>`});let P={messages:r,userId:"cli-user",sessionId:q,workspaceRoot:process.cwd(),signal:E.signal,confirmationHandler:Z,permissionMode:K},k={onThinking:(T)=>{G.setCurrentThinkingContent(T)},onContent:(T)=>{if(T.trim())G.addAssistantMessageAndClearThinking(T)},onToolStart:(T)=>{if(T.type!=="function")return;if(T.function.name==="TodoWrite")return;try{let C=JSON.parse(T.function.arguments),j=v6(T.function.name,C);G.addToolMessage(j,{toolName:T.function.name,phase:"start",summary:j,params:C})}catch(C){hQ.error("[useCommandHandler] onToolStart error:",C)}},onToolResult:async(T,C)=>{if(T.type!=="function")return;if(!C?.metadata?.summary)return;let j=$Q(T.function.name,C)?C.displayContent:void 0;G.addToolMessage(C.metadata.summary,{toolName:T.function.name,phase:"complete",summary:C.metadata.summary,detail:j})},onTokenUsage:(T)=>{G.updateTokenUsage(T)},onCompacting:(T)=>{if(G.setCompacting(T),!T)G.resetTokenUsage()},onTurnLimitReached:Z?async(T)=>{let C=await Z.requestConfirmation({type:"maxTurnsExceeded",title:"对话轮次上限",message:`已进行 ${T.turnsCount} 轮对话。是否继续?`,risks:["继续执行可能导致更长的等待时间","可能产生更多的 API 费用"]});return{continue:C.approved,reason:C.reason}}:void 0},n=await x.chat(R,P,k);if(!n||n.trim()===""){if(!W.current)G.addAssistantMessage("⏹ 已取消");return{success:!0,output:"已取消"}}return{success:!0,output:n}}catch(M){if(W.current)return{success:!1,error:"aborted"};let A=M instanceof Error?M.message:"未知错误",D=A.includes("can only concatenate str")||A.includes("image_url")||A.includes("multimodal")||A.includes("vision")||A.includes("does not support images"),w=A;if(D)w="当前模型不支持图片理解功能。请切换到支持视觉能力的模型(如 Claude 4.5、GPT-5.2、Gemini 3 Pro、Qwen3-VL-Plus 等)后重试。";let R={success:!1,error:w};return G.addAssistantMessage(`❌ ${w}`),R}}),L=a7(async(B)=>{if(!B.text.trim()&&B.images.length===0)return;if(Q){O.enqueueCommand({displayText:B.displayText,text:B.text,images:B.images,parts:B.parts});return}U.setTodos([]),W.current=!1,O.setProcessing(!0);try{let _=await N(B);if(!_.success&&_.error&&_.error!=="aborted")G.setError(_.error)}catch(_){if(_ instanceof Error&&(_.name==="AbortError"||_.message.includes("aborted")));else{let I=_ instanceof Error?_.message:"未知错误";G.setError(`执行失败: ${I}`)}}finally{O.setProcessing(!1),O.clearAbortController(),G.setCurrentThinkingContent(null);let _=O.dequeueCommand();if(_)setTimeout(()=>L({displayText:_.displayText,text:_.text,images:_.images,parts:_.parts}),100)}});return{executeCommand:L,handleAbort:z,isProcessing:Q}};import{useMemoizedFn as n4}from"ahooks";import{useState as pQ}from"react";var uQ=()=>{let[$,Y]=pQ([]),[Z,X]=pQ(-1),Q=n4((G,U)=>{let O={display:G,pasteMappings:U?new Map(U):new Map};Y((W)=>[...W,O]),X(-1)}),J=n4(()=>{if($.length===0)return null;let G=Z===-1?$.length-1:Math.max(0,Z-1);return X(G),$[G]||null}),q=n4(()=>{if(Z===-1)return null;let G=Z+1;if(G>=$.length)return X(-1),null;else return X(G),$[G]||null}),K=n4(()=>{X(-1)});return{commandHistory:$,historyIndex:Z,addToHistory:Q,getPreviousCommand:J,getNextCommand:q,resetHistoryIndex:K}};import{useMemoizedFn as gQ}from"ahooks";import{useMemo as ZF,useState as XF}from"react";var dQ=()=>{let[$,Y]=XF({isVisible:!1,details:null,resolver:null}),Z=gQ((J)=>{return new Promise((q)=>{Y({isVisible:!0,details:J,resolver:q})})}),X=gQ((J)=>{if($.resolver)$.resolver(J);Y({isVisible:!1,details:null,resolver:null})}),Q=ZF(()=>({requestConfirmation:Z}),[Z]);return{confirmationState:$,confirmationHandler:Q,handleResponse:X}};import{useMemoizedFn as J$}from"ahooks";import{useRef as mQ,useState as QF}from"react";var o4="␞",s4="␟";function t4($){return`${o4}PASTE:${$}:`}function n7(){return s4}var xj=new RegExp(`${o4}PASTE:(\\d+):[\\s\\S]*?${s4}`,"g");function JF($){return $.includes(o4)&&$.includes(s4)}function cQ($="",Y=0){let[Z,X]=QF({value:$,cursorPosition:Y}),Q=mQ(0),J=mQ(new Map),q=J$((H)=>{X((z)=>({value:H,cursorPosition:z.cursorPosition}));for(let z of J.current.keys()){let N=t4(z);if(!H.includes(N))J.current.delete(z)}}),K=J$((H)=>{X((z)=>({...z,cursorPosition:Math.max(0,Math.min(H,z.value.length))}))}),G=J$(()=>{X({value:"",cursorPosition:0}),J.current.clear()}),U=J$((H)=>{Q.current+=1;let z=Q.current;return J.current.set(z,{type:"text",data:H}),z}),O=J$((H,z)=>{Q.current+=1;let N=Q.current;return J.current.set(N,{type:"image",data:H,mimeType:z}),N}),W=J$((H)=>{for(let[z,N]of H)if(J.current.set(z,N),z>=Q.current)Q.current=z}),F=J$((H)=>{let z=[],N=[];if(!JF(H)){let E=H.trim();if(E)N.push({type:"text",text:E});return{displayText:H,text:H,images:z,parts:N}}let L=new RegExp(`${o4}PASTE:(\\d+):[\\s\\S]*?${s4}`,"g"),B=Array.from(H.matchAll(L)),_=0,I="",M="";for(let E of B){let x=E.index,r=x+E[0].length,P=parseInt(E[1],10),k=J.current.get(P);if(x>_){let n=H.slice(_,x);N.push({type:"text",text:n}),I+=n,M+=n}if(!k)I+=E[0],M+=E[0],N.push({type:"text",text:E[0]});else if(k.type==="text")I+=k.data,M+=k.data,N.push({type:"text",text:k.data});else{let n={id:P,base64:k.data,mimeType:k.mimeType};z.push(n),N.push({type:"image",...n}),M+=`[Image #${P}]`}_=r}if(_<H.length){let E=H.slice(_);N.push({type:"text",text:E}),I+=E,M+=E}let A=[];for(let E of N)if(E.type==="text"&&A.length>0&&A[A.length-1].type==="text")A[A.length-1].text+=E.text;else A.push(E);let D=0,w=A.length;while(D<A.length&&A[D].type==="text"&&A[D].text.trim()==="")D++;while(w>D&&A[w-1].type==="text"&&A[w-1].text.trim()==="")w--;let R=A.slice(D,w);return{displayText:M.trim(),text:I.trim(),images:z,parts:R}});return{value:Z.value,cursorPosition:Z.cursorPosition,setValue:q,setCursorPosition:K,clear:G,pasteMap:J.current,addPasteMapping:U,addImagePasteMapping:O,restorePasteMappings:W,resolveInput:F}}w1();S6();import{useMemoizedFn as oQ}from"ahooks";import{useInput as FF}from"ink";import{useEffect as sQ,useRef as tQ,useState as e7}from"react";C4();M4();import{useMemoizedFn as gj}from"ahooks";import qF from"fast-glob";import KF from"fuse.js";import{useEffect as lQ,useMemo as o7,useState as s7}from"react";var i$=null,GF=5000;function UF($,Y){let Z=[...$.matchAll(/(?:^|\s)(@(?:"[^"]*"|(?:[^\\ ]|\\ )*))/g)];for(let X of Z){let Q=X[1],J=X.index+(X[0].length-Q.length),q=J+Q.length;if(Y>=J&&Y<=q){let K=Q.slice(1),G=!1;if(K.startsWith('"')){if(G=!0,K=K.slice(1),K.endsWith('"'))K=K.slice(0,-1)}return{hasQuery:!0,query:K,startIndex:J,endIndex:q,quoted:G}}}return{hasQuery:!1,query:"",startIndex:-1,endIndex:-1,quoted:!1}}var WF=[...Q2.map(($)=>`${$}/**`),...Q2,...l9.map(($)=>`**/${$}`)];function iQ($,Y,Z={}){let{cwd:X=process.cwd(),maxSuggestions:Q=15,ignorePatterns:J=WF,debounceDelay:q=300,fuzzyMatch:K=!0}=Z,[G,U]=s7([]),[O,W]=s7(!1),[F,H]=s7(0),z=o7(()=>JSON.stringify(J),[J]),N=o7(()=>{if(Y===void 0)return{hasQuery:!1,query:"",startIndex:-1,endIndex:-1,quoted:!1};return UF($,Y)},[$,Y]);lQ(()=>{if(!$.includes("@")){U([]),W(!1);return}let B=Date.now();if(i$&&i$.cwd===X&&i$.ignoreKey===z&&B-i$.timestamp<GF){U(i$.files),W(!1);return}let _=!1,M=setTimeout(async()=>{W(!0);try{let D=(await qF("**/*",{cwd:X,dot:!1,followSymbolicLinks:!1,onlyFiles:!1,markDirectories:!0,unique:!0,ignore:J})).map((w)=>w.replace(/\\/g,"/"));if(!_)U(D),i$={cwd:X,ignoreKey:z,files:D,timestamp:B}}catch(A){if(console.error("Failed to load files for @ completion:",A),!_)U([])}finally{if(!_)W(!1)}},q);return()=>{_=!0,clearTimeout(M)}},[$,X,q,z]);let L=o7(()=>{if(!N.hasQuery||G.length===0)return[];let B=N.query.toLowerCase();if(B==="")return G.slice(0,Q);if(K)return new KF(G,{threshold:0.4,ignoreLocation:!0,minMatchCharLength:1}).search(B).slice(0,Q).map((M)=>M.item);return G.filter((_)=>_.toLowerCase().includes(B)).slice(0,Q)},[N,G,Q,K]);return lQ(()=>{H(0)},[L]),{...N,suggestions:L,selectedIndex:F,loading:O}}function OF($,Y=!1){if($.includes(" ")||Y)return`@"${$}"`;return`@${$}`}function t7($,Y,Z){if(!Y.hasQuery)return{newInput:$,newCursorPos:$.length};let X=OF(Z,Y.quoted),Q=$.slice(0,Y.startIndex),J=$.slice(Y.endIndex),q=Q+X+" "+J,K=Y.startIndex+X.length+1;return{newInput:q,newCursorPos:K}}import{useMemoizedFn as rQ}from"ahooks";import{useEffect as aQ,useRef as nQ}from"react";A1();var d1=($,Y)=>{let Z=nQ(!1),X=nQ(null),Q=rQ(()=>{if(X.current)clearTimeout(X.current);X.current=setTimeout(()=>{x0().setAwaitingSecondCtrlC(!1),Z.current=!1,X.current=null},3000)}),J=()=>{X$().shutdown("SIGINT",0)},q=rQ(()=>{if(!Z.current){if(Z.current=!0,$&&Y)Y();x0().setAwaitingSecondCtrlC(!0),Q()}else{if(X.current)clearTimeout(X.current),X.current=null;x0().setAwaitingSecondCtrlC(!1),J()}});return aQ(()=>{if($){if(x0().setAwaitingSecondCtrlC(!1),Z.current=!1,X.current)clearTimeout(X.current),X.current=null}},[$]),aQ(()=>{return()=>{if(X.current)clearTimeout(X.current)}},[]),q};var e4=c("UI"),eQ=($,Y,Z,X,Q,J,q,K,G,U)=>{let W=M0()==="main-input",F=$.value,H=$.setValue,z=$.cursorPosition,N=c$(),L=g2(),B=a4(),_=B?x$(B):!1,[I,M]=e7(!1),[A,D]=e7([]),[w,R]=e7(0),E=iQ(F,z,{cwd:process.cwd(),maxSuggestions:10}),x=d1(q||!1,J),r=tQ(0),P=500,k=tQ(!1);sQ(()=>{if(q)k.current=!1},[q]),sQ(()=>{if(E.hasQuery&&E.suggestions.length>0){let C=E.suggestions.map((j)=>({command:j,description:j.endsWith("/")?`Directory: ${j}`:`File: ${j}`,matchScore:1}));D(C),M(!0),R(0)}else if(F.startsWith("/"))if(F.includes(" "))M(!1),D([]);else{let j=HQ(F);D(j),M(j.length>0),R(0)}else M(!1),D([])},[F,E.hasQuery,E.suggestions]);let n=oQ(()=>{N.clearMessages(),N.setError(null)}),T=oQ(()=>{e4.debug("[DIAG] handleSubmit called:",{input:F,showSuggestions:I});let C=F.trim();if(C){let j=$.resolveInput(C);e4.debug("[DIAG] Submitting command:",{displayText:C,textLength:j.text.length,imageCount:j.images.length}),M(!1),D([]);let S1=$.pasteMap.size>0?new Map($.pasteMap):new Map;Q(C,S1),$.clear(),Y(j),e4.debug("[DIAG] Command submitted to onSubmit callback")}else e4.debug("[DIAG] Empty command, not submitting")});return FF((C,j)=>{if(C==="?"&&!F){G?.(),setTimeout(()=>$.clear(),0);return}if(j.backspace||j.delete||j.leftArrow||j.rightArrow||j.pageUp||j.pageDown||!j.ctrl&&!j.meta&&!j.escape&&!j.tab&&!j.upArrow&&!j.downArrow&&!j.return&&!(C==="?"&&!F))return;if(j.ctrl&&C==="c"||j.meta&&C==="c"||j.ctrl&&C==="d"||j.meta&&C==="d"){x();return}if(j.ctrl&&C==="l"||j.meta&&C==="l"){n();return}if(j.ctrl&&C==="t"||j.meta&&C==="t"){N.toggleThinkingExpanded();return}if(j.ctrl&&C==="o"||j.meta&&C==="o"){N.toggleHistoryExpanded();return}if(j.escape){if(U)G?.();else if(q&&J){if(k.current)return;k.current=!0,J()}else if(I)M(!1),D([]);else if(F){let d=Date.now();if(d-r.current<500)$.clear(),r.current=0;else r.current=d}return}if(j.tab&&j.shift){K?.();return}if(j.tab){if(I&&A.length>0){let d=A[w].command;if(E.hasQuery&&E.suggestions.includes(d)){let{newInput:e,newCursorPos:B1}=t7(F,E,d);H(e),$.setCursorPosition(B1)}else{let e=d+" ";H(e),$.setCursorPosition(e.length)}M(!1),D([])}else if(_)L.toggleThinkingMode();return}if(j.return){if(I&&A.length>0){let d=A[w].command;if(E.hasQuery&&E.suggestions.includes(d)){let{newInput:e,newCursorPos:B1}=t7(F,E,d);H(e),$.setCursorPosition(B1)}else{let e=d+" ";H(e),$.setCursorPosition(e.length)}M(!1),D([])}else T();return}if(j.upArrow){if(I&&A.length>0){let d=A.length-1;R((e)=>e>0?e-1:d)}else{let d=Z();if(d){if(d.pasteMappings.size>0)$.restorePasteMappings(d.pasteMappings);H(d.display),$.setCursorPosition(d.display.length)}}return}if(j.downArrow){if(I&&A.length>0){let d=A.length-1;R((e)=>e<d?e+1:0)}else{let d=X();if(d){if(d.pasteMappings.size>0)$.restorePasteMappings(d.pasteMappings);H(d.display),$.setCursorPosition(d.display.length)}}return}},{isActive:W}),{handleSubmit:T,showSuggestions:I,suggestions:A,selectedSuggestionIndex:w}};import _F from"ansi-escapes";import{useStdout as LF}from"ink";import{useCallback as wF,useEffect as AF,useRef as bF}from"react";import{useEffect as HF,useState as zF}from"react";import{useStdout as NF}from"ink";import{debounce as BF}from"lodash-es";function d2($=200){let{stdout:Y}=NF(),[Z,X]=zF(Y.columns||80);return HF(()=>{let Q=BF(()=>{X(Y.columns||80)},$);return Q(),Y.on("resize",Q),()=>{Y.off("resize",Q),Q.cancel()}},[Y,$]),Z}function $J(){let{stdout:$}=LF(),Y=d2(),Z=bF(!0),X=O1((J)=>J.session.actions.incrementClearCount),Q=wF(()=>{if($)$.write(_F.clearTerminal);X()},[$,X]);return AF(()=>{if(Z.current){Z.current=!1;return}let J=setTimeout(()=>{Q()},300);return()=>{clearTimeout(J)}},[Y,Q]),{refreshStatic:Q}}C2();import{MultiSelect as RF}from"@inkjs/ui";import{useMemoizedFn as $8}from"ahooks";import{Box as s,Text as m,useFocus as VF,useFocusManager as DF,useInput as XJ}from"ink";import Y8 from"ink-select-input";import IF from"ink-spinner";import k6 from"ink-text-input";import YJ from"node:fs";import MF from"node:os";import $3 from"node:path";import{useEffect as ZJ,useState as a$}from"react";import{jsxDEV as y}from"react/jsx-dev-runtime";var jF=[{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"}],yF=[{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 EF($){if(!$||$.trim()==="")return"名称不能为空";if(!/^[a-z0-9-]+$/.test($))return"名称只能包含小写字母、数字和连字符";if($.startsWith("-")||$.endsWith("-"))return"名称不能以连字符开头或结尾";return null}function C6({onComplete:$,onCancel:Y,initialConfig:Z}){let[X,Q]=a$(Z?"name":"mode"),[J,q]=a$({name:Z?.name||"",description:Z?.description||"",tools:Z?.tools||[],color:Z?.color,location:Z?.location||"project",systemPrompt:Z?.systemPrompt||""}),[K,G]=a$(""),[U,O]=a$(!1),[W,F]=a$(""),[H,z]=a$(Z?"edit":"manual"),{focus:N}=DF(),B={manual:["mode","name","description","tools","color","location","systemPrompt","confirm"],ai:["mode","aiPrompt","aiGenerating","confirm"],edit:["name","description","tools","color","location","systemPrompt","confirm"]}[H];ZJ(()=>{if(X==="name"||X==="description"||X==="systemPrompt"||X==="aiPrompt")return;N(`step-${X}`)},[X,N]);let _=$8(()=>{let w=B.indexOf(X);if(w<B.length-1)Q(B[w+1])}),I=$8(()=>{if(W)F("");if(X==="confirm"&&H==="ai"){Q("aiPrompt");return}let w=B.indexOf(X);if(w>0)Q(B[w-1]);else Y()}),M=$8(async()=>{O(!0),F("");try{let w=await l1.create(),R=`你是一个 Subagent 配置生成专家。用户会描述他们想要创建的 agent,你需要根据描述生成一个完整的 agent 配置。
1789
1791
 
1790
1792
  ## 可用工具列表
1791
1793
 
@@ -1859,35 +1861,35 @@ ${D}
1859
1861
  4. **color**: 选择一个合适的颜色用于 UI 区分
1860
1862
  5. **systemPrompt**: 详细说明 agent 的职责、使用的工具、输出格式等,使用 Markdown 格式
1861
1863
 
1862
- **重要**:请直接返回 JSON,不要添加任何额外的解释或文字。`,G)).trim(),r=x.match(/```(?:json)?\s*\n([\s\S]*?)\n```/);if(r)x=r[1];let j=JSON.parse(x);if(!j.name||!j.description||!j.systemPrompt)throw Error("Missing required fields: name, description, or systemPrompt");if(!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(j.name))throw Error("Invalid name format. Must be kebab-case (lowercase, numbers, hyphens only)");q({name:j.name,description:j.description,tools:Array.isArray(j.tools)?j.tools:[],color:j.color||"blue",location:"project",systemPrompt:j.systemPrompt}),Q("confirm")}catch(w){F(w instanceof Error?w.message:String(w))}finally{O(!1)}});xQ(()=>{if(X==="aiGenerating"&&!W&&!U)M()},[X,W,U,M]);let A=s4(async()=>{try{let w=J.location==="project"?l7.join(process.cwd(),".blade","agents"):l7.join(JF.homedir(),".blade","agents");await hQ.promises.mkdir(w,{recursive:!0});let R=["---",`name: ${J.name}`,`description: ${J.description}`];if(J.tools.length>0&&!J.tools.includes("all")){R.push("tools:");for(let r of J.tools)R.push(` - ${r}`)}if(J.color)R.push(`color: ${J.color}`);R.push("---");let E=[R.join(`
1864
+ **重要**:请直接返回 JSON,不要添加任何额外的解释或文字。`,K)).trim(),r=x.match(/```(?:json)?\s*\n([\s\S]*?)\n```/);if(r)x=r[1];let P=JSON.parse(x);if(!P.name||!P.description||!P.systemPrompt)throw Error("Missing required fields: name, description, or systemPrompt");if(!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(P.name))throw Error("Invalid name format. Must be kebab-case (lowercase, numbers, hyphens only)");q({name:P.name,description:P.description,tools:Array.isArray(P.tools)?P.tools:[],color:P.color||"blue",location:"project",systemPrompt:P.systemPrompt}),Q("confirm")}catch(w){F(w instanceof Error?w.message:String(w))}finally{O(!1)}});ZJ(()=>{if(X==="aiGenerating"&&!U&&!W)M()},[X,U,W,M]);let A=$8(async()=>{try{let w=J.location==="project"?$3.join(process.cwd(),".blade","agents"):$3.join(MF.homedir(),".blade","agents");await YJ.promises.mkdir(w,{recursive:!0});let R=["---",`name: ${J.name}`,`description: ${J.description}`];if(J.tools.length>0&&!J.tools.includes("all")){R.push("tools:");for(let r of J.tools)R.push(` - ${r}`)}if(J.color)R.push(`color: ${J.color}`);R.push("---");let E=[R.join(`
1863
1865
  `),"",`# ${J.name} Subagent`,"",J.systemPrompt||"你是一个专门的代理,负责执行特定任务。",""].join(`
1864
- `),x=l7.join(w,`${J.name}.md`);await hQ.promises.writeFile(x,E,"utf-8"),$()}catch(w){console.error("保存配置失败:",w)}}),D=p1(!1,Y);if(pQ((w,R)=>{if(R.escape)I();else if(R.ctrl&&w==="c"||R.meta&&w==="c")D()},{isActive:X!=="tools"}),X==="mode")return v(o,{flexDirection:"column",paddingY:1,children:[v(o,{marginBottom:1,children:v(d,{bold:!0,color:"cyan",children:"\uD83C\uDFAF 选择创建方式"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(o,{marginBottom:1,children:v(d,{dimColor:!0,children:"你可以手动配置每个细节,或让 AI 根据你的描述自动生成配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(t4,{items:[{label:"\uD83E\uDD16 AI 智能生成 - 根据描述自动生成完整配置",value:"ai"},{label:"✍️ 手动配置 - 逐步配置每个选项",value:"manual"}],onSelect:(w)=>{if(w.value==="ai")_("ai"),Q("aiPrompt");else _("manual"),Q("name")}},void 0,!1,void 0,this),v(o,{marginTop:1,children:v(d,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 取消"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(X==="aiPrompt")return v(o,{flexDirection:"column",paddingY:1,children:[v(o,{marginBottom:1,children:v(d,{bold:!0,color:"cyan",children:"\uD83E\uDD16 AI 智能生成"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(o,{marginBottom:1,children:v(d,{dimColor:!0,children:'描述你想要创建的 Agent(例如:"一个专门用于代码审查的 agent,能够分析代码质量和潜在bug")'},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(o,{marginBottom:1,children:[v(d,{color:"green",children:"描述: "},void 0,!1,void 0,this),v(P6,{value:G,onChange:K,onSubmit:(w)=>{if(!w.trim())return;Q("aiGenerating")}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v(o,{children:v(d,{dimColor:!0,children:"按 Enter 开始生成 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(X==="aiGenerating"){if(U)return v(o,{flexDirection:"column",paddingY:1,children:[v(o,{marginBottom:1,children:v(d,{bold:!0,color:"red",children:"❌ AI 生成失败"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(o,{marginBottom:1,children:v(d,{color:"red",children:U},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(o,{marginBottom:1,children:v(d,{dimColor:!0,children:"按 ESC 返回修改描述"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return v(o,{flexDirection:"column",paddingY:1,children:[v(o,{marginBottom:1,children:v(d,{bold:!0,color:"yellow",children:[v(QF,{type:"dots"},void 0,!1,void 0,this)," AI 正在生成配置..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this),v(o,{marginBottom:1,children:v(d,{dimColor:!0,children:['根据你的描述:"',G,'"']},void 0,!0,void 0,this)},void 0,!1,void 0,this),v(o,{marginBottom:1,children:v(d,{color:"gray",children:"正在调用 LLM 生成 agent 配置,请稍候..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}if(X==="name"){let w=H==="edit";return v(o,{flexDirection:"column",paddingY:1,children:[v(o,{marginBottom:1,children:v(d,{bold:!0,color:"cyan",children:["\uD83D\uDCDD Step 1/7: ",w?"Agent 名称(不可修改)":"输入 Agent 名称"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),v(o,{marginBottom:1,children:v(d,{dimColor:!0,children:w?"编辑模式下名称不可修改(修改名称相当于创建新 Agent)":"名称只能包含小写字母、数字和连字符(例如:code-reviewer)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(o,{marginBottom:1,children:[v(d,{color:"green",children:"名称: "},void 0,!1,void 0,this),w?v(d,{children:J.name},void 0,!1,void 0,this):v(P6,{value:J.name,onChange:(R)=>q({...J,name:R}),onSubmit:(R)=>{if(KF(R))return;N()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v(o,{children:v(d,{dimColor:!0,children:w?"按 Enter 继续 | ESC 返回":"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&v(P6,{value:"",onChange:()=>{},onSubmit:N,showCursor:!1},"edit-mode-dummy-input",!1,void 0,this)]},void 0,!0,void 0,this)}if(X==="description")return v(o,{flexDirection:"column",paddingY:1,children:[v(o,{marginBottom:1,children:v(d,{bold:!0,color:"cyan",children:"\uD83D\uDCDD Step 2/7: 输入描述信息"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(o,{marginBottom:1,children:v(d,{dimColor:!0,children:"简短描述这个 Agent 的用途和使用场景(这将帮助主 Agent 决定何时使用它)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(o,{marginBottom:1,children:[v(d,{color:"green",children:"描述: "},void 0,!1,void 0,this),v(P6,{value:J.description,onChange:(w)=>q({...J,description:w}),onSubmit:(w)=>{if(!w.trim())return;N()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v(o,{children:v(d,{dimColor:!0,children:"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(X==="tools")return v(UF,{config:J,setConfig:q,onNext:N,onPrev:I},void 0,!1,void 0,this);if(X==="color")return v(o,{flexDirection:"column",paddingY:1,children:[v(o,{marginBottom:1,children:v(d,{bold:!0,color:"cyan",children:"\uD83C\uDFA8 Step 4/7: 选择背景颜色"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(o,{marginBottom:1,children:v(d,{dimColor:!0,children:"为 Agent 选择一个颜色标识(用于在 UI 中区分不同的 Agents)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(t4,{items:GF,onSelect:(w)=>{let R=w.value==="none"?void 0:w.value;q({...J,color:R}),N()}},void 0,!1,void 0,this),v(o,{marginTop:1,children:v(d,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(X==="location")return v(o,{flexDirection:"column",paddingY:1,children:[v(o,{marginBottom:1,children:v(d,{bold:!0,color:"cyan",children:"\uD83D\uDCC2 Step 5/7: 选择保存位置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(o,{marginBottom:1,children:v(d,{dimColor:!0,children:"项目级配置仅在当前项目生效,用户级配置全局可用"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(t4,{items:[{label:"\uD83D\uDCC1 项目级 (.blade/agents/) - 仅当前项目",value:"project"},{label:"\uD83C\uDFE0 用户级 (~/.blade/agents/) - 全局可用",value:"user"}],onSelect:(w)=>{q({...J,location:w.value}),N()}},void 0,!1,void 0,this),v(o,{marginTop:1,children:v(d,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(X==="systemPrompt")return v(o,{flexDirection:"column",paddingY:1,children:[v(o,{marginBottom:1,children:v(d,{bold:!0,color:"cyan",children:"\uD83D\uDCAC Step 6/7: 输入系统提示词"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(o,{marginBottom:1,children:v(d,{dimColor:!0,children:"定义 Agent 的行为和职责(可选,留空将使用默认提示)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(o,{marginBottom:1,children:[v(d,{color:"green",children:"提示词: "},void 0,!1,void 0,this),v(P6,{value:J.systemPrompt,onChange:(w)=>q({...J,systemPrompt:w}),onSubmit:()=>N()},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v(o,{children:v(d,{dimColor:!0,children:"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(X==="confirm")return v(o,{flexDirection:"column",paddingY:1,children:[v(o,{marginBottom:1,children:v(d,{bold:!0,color:"cyan",children:"✅ Step 7/7: 确认配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(o,{flexDirection:"column",paddingLeft:2,marginBottom:1,children:[v(d,{children:[v(d,{bold:!0,color:"green",children:["名称:"," "]},void 0,!0,void 0,this),v(d,{children:J.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v(d,{children:[v(d,{bold:!0,color:"green",children:["描述:"," "]},void 0,!0,void 0,this),v(d,{children:J.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v(d,{children:[v(d,{bold:!0,color:"green",children:["工具:"," "]},void 0,!0,void 0,this),v(d,{children:J.tools.includes("all")?"所有工具":J.tools.join(", ")||"所有工具"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v(d,{children:[v(d,{bold:!0,color:"green",children:["颜色:"," "]},void 0,!0,void 0,this),v(d,{children:J.color||"默认"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v(d,{children:[v(d,{bold:!0,color:"green",children:["位置:"," "]},void 0,!0,void 0,this),v(d,{children:J.location==="project"?"项目级":"用户级"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v(d,{children:[v(d,{bold:!0,color:"green",children:["提示词:"," "]},void 0,!0,void 0,this),v(d,{children:J.systemPrompt||"(使用默认)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),v(t4,{items:[{label:"✅ 确认并保存",value:"save"},{label:"⬅️ 返回上一步",value:"back"},{label:"❌ 取消",value:"cancel"}],onSelect:(w)=>{if(w.value==="save")A();else if(w.value==="back")I();else Y()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}function UF({config:$,setConfig:Y,onNext:Z,onPrev:X}){let{isFocused:Q}=ZF({id:"step-tools"});pQ((q,G)=>{if(G.escape)X()},{isActive:Q});let J=(q)=>{if(q.includes("all"))Y({...$,tools:["all"]});else Y({...$,tools:q});Z()};return v(o,{flexDirection:"column",paddingY:1,children:[v(o,{marginBottom:1,children:v(d,{bold:!0,color:"cyan",children:"\uD83D\uDD27 Step 3/7: 选择可用工具"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(o,{marginBottom:1,children:v(d,{dimColor:!0,children:"方向键导航,空格切换勾选,Enter 确认进入下一步 | ESC 返回上一步"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(YF,{options:qF,defaultValue:$.tools,onSubmit:J},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}P$();import{useMemoizedFn as k6}from"ahooks";import{Box as B1,Text as y1,useInput as WF}from"ink";import i7 from"ink-select-input";import OF from"node:fs";import{useMemo as FF,useState as a7}from"react";import{jsxDEV as u}from"react/jsx-dev-runtime";function gQ({initialMode:$="menu",onComplete:Y,onCancel:Z}){let[X,Q]=a7($),[J,q]=a7(null),[G,K]=a7(0),W=k6(()=>{x1.clear(),x1.loadFromStandardLocations(),K((N)=>N+1)}),O=FF(()=>{return x1.getAllSubagents()},[G]),U=[{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"}],F=k6((N)=>{if(N.value==="cancel"){Z?.();return}Q(N.value)}),H=k6((N)=>{if(q(N.value),X==="edit")Q("editWizard");else if(X==="delete")Q("deleteConfirm")}),_=k6(async()=>{if(!J?.configPath)return;try{await OF.promises.unlink(J.configPath),W(),z()}catch(N){console.error("删除失败:",N)}}),z=k6(()=>{Q("menu"),q(null)}),L=p1(!1,Z);if(WF((N,I)=>{if(I.escape){if(X==="menu")Z?.();else if(X==="list"||X==="edit"||X==="delete")z();else if(X==="deleteConfirm")z()}else if(I.ctrl&&N==="c"||I.meta&&N==="c")L()},{isActive:X!=="create"&&X!=="editWizard"}),X==="menu")return u(B1,{flexDirection:"column",paddingY:1,children:[u(B1,{marginBottom:1,children:u(y1,{bold:!0,color:"cyan",children:"\uD83D\uDCCB Agents 管理"},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(i7,{items:U,onSelect:F},void 0,!1,void 0,this),u(B1,{marginTop:1,children:u(y1,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 退出"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(X==="list"){if(O.length===0)return u(B1,{flexDirection:"column",paddingY:1,children:[u(B1,{marginBottom:1,children:u(y1,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(B1,{paddingLeft:2,children:u(y1,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(B1,{marginTop:1,paddingLeft:2,children:u(y1,{color:"gray",children:"\uD83D\uDCA1 配置文件位置: .blade/agents/ 或 ~/.blade/agents/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(B1,{marginTop:1,paddingLeft:2,children:u(y1,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return u(B1,{flexDirection:"column",paddingY:1,children:[u(B1,{marginBottom:1,children:[u(y1,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this),u(y1,{color:"gray",children:[" (找到 ",O.length," 个)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),O.map((N)=>u(B1,{flexDirection:"column",paddingLeft:2,children:[u(B1,{children:u(y1,{children:[u(y1,{bold:!0,color:N.color||"white",children:["• ",N.name]},void 0,!0,void 0,this),u(y1,{color:"gray",children:[" - ",N.description]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),N.tools&&N.tools.length>0&&u(B1,{paddingLeft:2,children:u(y1,{color:"gray",children:["工具: ",N.tools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),N.configPath&&u(B1,{paddingLeft:2,children:u(y1,{color:"gray",dimColor:!0,children:N.configPath},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},N.name,!0,void 0,this)),u(B1,{marginTop:1,paddingLeft:2,children:u(y1,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}let B=(N)=>{if(O.length===0)return u(B1,{flexDirection:"column",paddingY:1,children:[u(B1,{marginBottom:1,children:u(y1,{bold:!0,color:"cyan",children:N},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(B1,{paddingLeft:2,children:u(y1,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(B1,{marginTop:1,paddingLeft:2,children:u(y1,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);let I=O.map((M)=>({key:M.name,label:`${M.name} - ${M.description}`,value:M}));return u(B1,{flexDirection:"column",paddingY:1,children:[u(B1,{marginBottom:1,children:u(y1,{bold:!0,color:"cyan",children:N},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(i7,{items:I,onSelect:H},void 0,!1,void 0,this),u(B1,{marginTop:1,children:u(y1,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};if(X==="create")return u(T6,{onComplete:()=>{W(),z()},onCancel:z},void 0,!1,void 0,this);if(X==="edit")return B("✏️ 编辑 Agent");if(X==="editWizard"&&J){let N={name:J.name,description:J.description,tools:J.tools||[],color:J.color,location:J.configPath?.includes(".blade/agents")?"project":"user",systemPrompt:J.systemPrompt||""};return u(T6,{initialConfig:N,onComplete:()=>{W(),z()},onCancel:z},void 0,!1,void 0,this)}if(X==="delete")return B("\uD83D\uDDD1️ 删除 Agent");if(X==="deleteConfirm"&&J)return u(B1,{flexDirection:"column",paddingY:1,children:[u(B1,{marginBottom:1,children:u(y1,{bold:!0,color:"red",children:"⚠️ 确认删除"},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(B1,{marginBottom:1,paddingLeft:2,children:u(y1,{children:["你确定要删除 Agent"," ",u(y1,{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),u(B1,{marginBottom:1,paddingLeft:2,children:u(y1,{dimColor:!0,children:["文件路径: ",J.configPath]},void 0,!0,void 0,this)},void 0,!1,void 0,this),u(B1,{marginBottom:1,paddingLeft:2,children:u(y1,{color:"red",children:"此操作无法撤销!"},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(i7,{items:[{label:"\uD83D\uDDD1️ 确认删除",value:"confirm"},{label:"❌ 取消",value:"cancel"}],onSelect:(N)=>{if(N.value==="confirm")_();else z()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}s1();import{Box as i$,Text as R1}from"ink";import _F from"react";T4();C7();import{useEffect as HF,useState as uQ}from"react";function mQ($=process.cwd(),Y=5000){let[Z,X]=uQ(null),[Q,J]=uQ(!0);return HF(()=>{let q=!0,G=async()=>{try{let W=await V6($);if(!q)return;if(!W){X(null),J(!1);return}let O=await LX($);if(!q)return;X(O)}catch{if(q)X(null)}finally{if(q)J(!1)}};G();let K=null;if(Y>0)K=setInterval(G,Y);return()=>{if(q=!1,K)clearInterval(K)}},[$,Y]),{branch:Z,loading:Q}}import{jsxDEV as G1,Fragment as S6}from"react/jsx-dev-runtime";var dQ=_F.memo(()=>{let $=c4(),Y=J2(),Z=m$(),Q=d4()==="shortcuts",J=JQ(),{branch:q}=mQ(),G=l4(),K=eX(),W=tX(),O=FQ(),U=G?C$(G):!1,H=(()=>{if(Z==="default")return null;if(Z==="autoEdit")return G1(R1,{color:"magenta",children:["▶▶ auto edit on ",G1(R1,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="plan")return G1(R1,{color:"cyan",children:["‖ plan mode on ",G1(R1,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="yolo")return G1(R1,{color:"red",children:["⚡ yolo mode on ",G1(R1,{color:"gray",children:"(all tools auto-approved)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null})(),_=H!==null,z=[["Enter:发送","Shift+Enter:换行","Esc:中止"],["Shift+Tab:切换模式","↑/↓:历史","Tab:补全"],["Ctrl+A:行首","Ctrl+E:行尾","Ctrl+K:删到尾"],["Ctrl+U:删到首","Ctrl+W:删单词","Ctrl+C:退出"]];return G1(i$,{flexDirection:"row",justifyContent:"space-between",paddingX:2,paddingY:0,children:[Q?G1(i$,{flexDirection:"column",gap:0,children:z.map((L,B)=>G1(i$,{flexDirection:"row",children:[L.map((N,I)=>{let[M,A]=N.split(":");return G1(i$,{flexDirection:"row",width:20,children:[G1(R1,{color:"yellow",children:M},void 0,!1,void 0,this),G1(R1,{color:"gray",children:":"},void 0,!1,void 0,this),G1(R1,{color:"white",children:A},void 0,!1,void 0,this)]},I,!0,void 0,this)}),B===z.length-1&&G1(R1,{color:"cyan",children:" ? 关闭"},void 0,!1,void 0,this)]},B,!0,void 0,this))},void 0,!1,void 0,this):G1(i$,{flexDirection:"row",gap:1,children:[q&&G1(S6,{children:[G1(R1,{color:"gray",children:[" ",q]},void 0,!0,void 0,this),G1(R1,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H,_&&G1(R1,{color:"gray",children:"·"},void 0,!1,void 0,this),G1(R1,{color:"gray",children:"? for shortcuts"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G1(i$,{flexDirection:"row",gap:1,children:!$?G1(R1,{color:"red",children:"⚠ API 密钥未配置"},void 0,!1,void 0,this):G1(S6,{children:[U&&G1(S6,{children:[O?G1(R1,{color:"cyan",children:"Thinking on"},void 0,!1,void 0,this):G1(R1,{color:"gray",children:"Tab:Thinking"},void 0,!1,void 0,this),G1(R1,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G&&G1(R1,{color:"gray",children:G.model},void 0,!1,void 0,this),G1(R1,{color:"gray",children:"·"},void 0,!1,void 0,this),W?G1(R1,{color:"yellow",children:"压缩中..."},void 0,!1,void 0,this):G1(R1,{color:K<20?"red":K<50?"yellow":"gray",children:[K,"%"]},void 0,!0,void 0,this),Y&&G1(S6,{children:[G1(R1,{color:"gray",children:"·"},void 0,!1,void 0,this),G1(R1,{color:"yellow",children:"Processing..."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J&&G1(S6,{children:[G1(R1,{color:"gray",children:"·"},void 0,!1,void 0,this),G1(R1,{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 r7,Text as n7}from"ink";import zF from"react";import{jsxDEV as a$}from"react/jsx-dev-runtime";var cQ=zF.memo(({suggestions:$,selectedIndex:Y,visible:Z,maxDisplay:X=8})=>{if(!Z||$.length===0)return null;let Q=0,J=Math.min(X,$.length),q=Y>=$.length;if(Y>=X&&!q)Q=Y-X+1,J=Y+1;let G=$.slice(Q,J),K=$.length>X;return a$(r7,{flexDirection:"column",paddingX:2,paddingY:0,children:[G.map((W,O)=>{let F=Q+O===Y;return a$(r7,{flexDirection:"row",paddingX:1,gap:2,children:[a$(n7,{color:F?"cyan":"white",bold:F,children:W.command},void 0,!1,void 0,this),a$(n7,{color:F?"cyan":"gray",dimColor:!F,children:["- ",W.description]},void 0,!0,void 0,this)]},W.command,!0,void 0,this)}),K&&a$(r7,{paddingX:1,children:a$(n7,{color:q?"cyan":"gray",bold:q,dimColor:!q,children:["... and ",$.length-X," more"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});s1();import{Box as v0,Text as c0,useInput as pF}from"ink";import gF from"ink-select-input";import ZJ,{useMemo as uF}from"react";import{Box as o1,Text as Z0}from"ink";import Z9 from"react";import{Box as $9,Text as q2}from"ink";import{common as AF,createLowlight as bF}from"lowlight";import nQ from"react";H2();import{Box as e4,Text as C6}from"ink";import w2,{Fragment as aQ}from"react";import NF from"string-width";var lQ=new Map,iQ=1000;function s7($){let Y=!0;for(let X=0;X<$.length;X++)if($.charCodeAt(X)>127){Y=!1;break}if(Y)return $.split("");if($.length<=iQ){let X=lQ.get($);if(X)return X}let Z=Array.from($);if($.length<=iQ)lQ.set($,Z);return Z}var o7=new Map;function L2($){if(/^[\x20-\x7E]*$/.test($))return $.length;if(o7.has($))return o7.get($);let Y=NF($);return o7.set($,Y),Y}import{jsxDEV as r$}from"react/jsx-dev-runtime";var t7=2,rQ=w2.memo(({children:$,maxWidth:Y,maxHeight:Z,overflowDirection:X="top",additionalHiddenLinesCount:Q=0})=>{let J=k1(),q=[],G=Math.max(Math.round(Z??Number.MAX_SAFE_INTEGER),t7);function K(z){if(!w2.isValidElement(z))return;if(z.type===aQ){w2.Children.forEach(z.props.children,K);return}if(z.type===e4){LF(z,Y,q);return}}w2.Children.forEach($,K);let O=q.length>G||Q>0?G-1:G,U=O!==void 0?Math.max(0,q.length-O):0,F=U+Q,_=(U>0?X==="top"?q.slice(U):q.slice(0,O):q).map((z,L)=>r$(e4,{children:z.length>0?z.map((B,N)=>r$(C6,{...B.props,children:B.text},N,!1,void 0,this)):r$(C6,{children:" "},void 0,!1,void 0,this)},L,!1,void 0,this));return r$(e4,{flexDirection:"column",width:Y,flexShrink:0,children:[F>0&&X==="top"&&r$(C6,{color:J.colors.text.muted,dimColor:!0,children:["... ",F," line",F===1?"":"s"," hidden ..."]},void 0,!0,void 0,this),_,F>0&&X==="bottom"&&r$(C6,{color:J.colors.text.muted,dimColor:!0,children:["... ",F," line",F===1?"":"s"," hidden ..."]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});function BF($){if(!w2.isValidElement($)||$.type!==e4)return{noWrapSegments:[],segments:[]};let Y={noWrapSegments:[],segments:[]},Z=!1;function X(Q,J){if(Q===null||Q===void 0)return;if(typeof Q==="string"||typeof Q==="number"){let W=String(Q);if(!W)return;let O={text:W,props:J??{}};if(J===void 0||J.wrap==="wrap")Z=!0,Y.segments.push(O);else if(!Z)Y.noWrapSegments.push(O);else Y.segments.push(O);return}if(!w2.isValidElement(Q))return;if(Q.type===aQ){w2.Children.forEach(Q.props.children,(W)=>X(W,J));return}if(Q.type!==C6)return;let{children:q,...G}=Q.props,K=J===void 0?G:{...J,...G};w2.Children.forEach(q,(W)=>X(W,K))}return w2.Children.forEach($.props.children,(Q)=>X(Q,void 0)),Y}function LF($,Y,Z){let X=BF($);if(X.segments.length===0&&X.noWrapSegments.length===0){Z.push([]);return}let Q=0;for(let U of X.noWrapSegments)Q+=L2(U.text);if(X.segments.length===0){let U=[],F=[];for(let H of X.noWrapSegments){let _=H.text.split(`
1865
- `);for(let z=0;z<_.length;z++){if(z>0)U.push(F),F=[];if(_[z])F.push({text:_[z],props:H.props})}}if(F.length>0)U.push(F);for(let H of U)Z.push(H);return}let J=Y-Q;if(J<1){wF(X.noWrapSegments,Y,Z);return}let q=[],G=[],K=0;function W(){if(q.length===0)q.push([...X.noWrapSegments,...G]);else if(Q>0)q.push([{text:" ".repeat(Q),props:{}},...G]);else q.push(G);G=[],K=0}function O(U,F){if(G.length>0&&G[G.length-1].props===F)G[G.length-1].text+=U;else G.push({text:U,props:F})}for(let U of X.segments){let F=U.text.split(`
1866
- `);for(let H=0;H<F.length;H++){if(H>0)W();let z=F[H].split(/(\s+)/);for(let L of z){if(!L)continue;let B=L2(L);if(K+B>J&&K>0){if(W(),/^\s+$/.test(L))continue}if(B>J){let I=s7(L);while(I.length>0){let M=0,A=0;for(let D of I){let w=L2(D);if(K+A+w>J)break;A+=w,M++}if(M>0){let D=I.slice(0,M).join("");O(D,U.props),K+=L2(D),I=I.slice(M)}if(I.length>0)W()}}else O(L,U.props),K+=B}}if(U.text.endsWith(`
1867
- `))W()}if(G.length>0)W();for(let U of q)Z.push(U)}function wF($,Y,Z){let X=[],Q=[],J=0;for(let q of $){let G=q.text.split(`
1868
- `);for(let K=0;K<G.length;K++){if(K>0)X.push(Q),Q=[],J=0;let W=G[K];if(!W)continue;let O=L2(W),U=Math.max(0,Y-L2("…"));if(O<=U&&J===0)Q.push({text:W,props:q.props}),J+=O;else{let F=s7(W),H=J,_=0;for(let L of F){let B=L2(L);if(H+B>U)break;H+=B,_++}let z=F.slice(0,_).join("");if(z)Q.push({text:z,props:q.props});Q.push({text:"…",props:{}}),J=H+L2("…")}}}if(Q.length>0)X.push(Q);if(X.length===0)X.push([{text:"…",props:{}}]);for(let q of X)Z.push(q)}import{jsxDEV as Y0}from"react/jsx-dev-runtime";var e7=bF(AF);function Y9($,Y,Z=0){if($.type==="text")return Y0(q2,{wrap:"wrap",children:$.value},Z,!1,void 0,this);if($.type==="element"){let X=$.properties?.className?.[0]||"",Q=Y.default;if(X.includes("comment"))Q=Y.comment;else if(X.includes("string"))Q=Y.string;else if(X.includes("number"))Q=Y.number;else if(X.includes("keyword"))Q=Y.keyword;else if(X.includes("function"))Q=Y.function;else if(X.includes("variable"))Q=Y.variable;else if(X.includes("operator"))Q=Y.operator;else if(X.includes("type"))Q=Y.type;else if(X.includes("tag"))Q=Y.tag;else if(X.includes("attr"))Q=Y.attr;let J=$.children?.map((q,G)=>Y9(q,Y,G));return Y0(q2,{color:Q,wrap:"wrap",children:J},Z,!1,void 0,this)}if($.type==="root"&&$.children)return Y0(nQ.Fragment,{children:$.children.map((X,Q)=>Y9(X,Y,Q))},Z,!1,void 0,this);return Y0(q2,{},Z,!1,void 0,this)}function RF($,Y,Z){let X=Z||j1.getTheme().colors.syntax;try{if(!Y||!e7.registered(Y)){let J=e7.highlightAuto($);if(!J.children||J.children.length===0)return Y0(q2,{color:X.default,wrap:"wrap",children:$},void 0,!1,void 0,this);return Y9(J,X)}let Q=e7.highlight(Y,$);if(!Q.children||Q.children.length===0)return Y0(q2,{color:X.default,wrap:"wrap",children:$},void 0,!1,void 0,this);return Y9(Q,X)}catch(Q){return Y0(q2,{color:X.default,wrap:"wrap",children:$},void 0,!1,void 0,this)}}var $3=nQ.memo(({content:$,language:Y,showLineNumbers:Z=!0,terminalWidth:X,availableHeight:Q})=>{let J=k1(),q=$.split(`
1869
- `),G=0;if(Q&&q.length>Q){let U=Math.max(Q,t7);if(q.length>U)G=q.length-U,q=q.slice(G)}let K=q.length+G,W=String(K).length+1,O=Math.max(20,X-4);return Y0($9,{borderStyle:"round",borderColor:J.colors.border.light,paddingX:1,paddingY:0,marginY:1,flexDirection:"column",children:[Y&&Y0($9,{marginBottom:0,children:Y0(q2,{color:J.colors.text.secondary,children:Y},void 0,!1,void 0,this)},void 0,!1,void 0,this),G>0&&Y0($9,{marginBottom:0,children:Y0(q2,{color:J.colors.text.muted,dimColor:!0,children:["... ",G," lines hidden ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Y0(rQ,{maxWidth:O,maxHeight:Q,children:q.map((U,F)=>{let H=F+G+1;return Y0($9,{flexDirection:"row",children:[Z&&Y0(q2,{color:J.colors.text.muted,dimColor:!0,wrap:"truncate",children:[String(H).padStart(W-1," ")," "]},void 0,!0,void 0,this),U.trim()===""?Y0(q2,{wrap:"wrap",children:" "},void 0,!1,void 0,this):RF(U,Y,J.colors.syntax)]},F,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});import{Box as oQ,Text as G2}from"ink";import{jsxDEV as D0}from"react/jsx-dev-runtime";function VF($){let Y=$.split(`
1870
- `),Z=[],X=0,Q=0;for(let J of Y){if(J.startsWith("---")||J.startsWith("+++"))continue;if(J.startsWith("@@")){let q=J.match(/@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@/);if(q)X=parseInt(q[1],10),Q=parseInt(q[3],10);Z.push({type:"header",content:J});continue}if(J.startsWith("-")){Z.push({type:"remove",content:J.substring(1),lineNumber:X}),X++;continue}if(J.startsWith("+")){Z.push({type:"add",content:J.substring(1),lineNumber:Q}),Q++;continue}if(J.startsWith(" ")||J===""){Z.push({type:"context",content:J.substring(1),lineNumber:Q}),X++,Q++;continue}}return Z}var Y3=({patch:$,startLine:Y,matchLine:Z,terminalWidth:X,maxLines:Q=20})=>{let J=k1(),q=VF($),K=Math.max(...q.map((H)=>H.lineNumber||0)).toString().length+1,W=q.length,O=W>Q,U=O?q.slice(0,Q):q,F=W-Q;return D0(oQ,{flexDirection:"column",marginTop:1,marginBottom:1,children:[D0(G2,{color:J.colors.muted,children:"─".repeat(Math.max(0,Math.min(60,X)))},void 0,!1,void 0,this),O&&D0(G2,{color:J.colors.info,children:["\uD83D\uDCCA 显示前 ",Q," 行,共 ",W," 行 diff"]},void 0,!0,void 0,this),O&&D0(G2,{color:J.colors.muted,children:"─".repeat(Math.max(0,Math.min(60,X)))},void 0,!1,void 0,this),U.map((H,_)=>{if(H.type==="header")return D0(G2,{color:J.colors.muted,dimColor:!0,children:H.content},_,!1,void 0,this);let z=H.lineNumber?H.lineNumber.toString().padStart(K," "):" ".repeat(K),L=" ",B,N;if(H.type==="add")L="+",N=J.colors.success,B=void 0;else if(H.type==="remove")L="-",N=J.colors.error,B=void 0;else N=J.colors.text.primary;let I=Math.max(0,X-K-2),M=H.content;if(M.length>I)M=M.substring(0,I-3)+"...";return D0(G2,{color:N,backgroundColor:B,children:[D0(G2,{dimColor:!0,children:z},void 0,!1,void 0,this),D0(G2,{children:L},void 0,!1,void 0,this),D0(G2,{children:[" ",M]},void 0,!0,void 0,this)]},_,!0,void 0,this)}),O&&D0(oQ,{marginTop:1,children:D0(G2,{color:J.colors.warning,dimColor:!0,children:["⚠️ 已隐藏剩余 ",F," 行 diff(总共 ",W," 行)"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),D0(G2,{color:J.colors.muted,children:"─".repeat(Math.max(0,Math.min(60,X)))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{Text as d0}from"ink";import IF from"react";import DF from"string-width";var X$=($)=>{let Y=$.replace(/\*\*(.*?)\*\*/g,"$1").replace(/\*(.*?)\*/g,"$1").replace(/_(.*?)_/g,"$1").replace(/~~(.*?)~~/g,"$1").replace(/`(.*?)`/g,"$1").replace(/<u>(.*?)<\/u>/g,"$1").replace(/\[(.*?)\]\(.*?\)/g,"$1");return DF(Y)},sQ=($,Y,Z="...")=>{if(X$($)<=Y)return $;if(Y<=Z.length)return Z.substring(0,Y);let Q=0,J=$.length,q="";while(Q<=J){let G=Math.floor((Q+J)/2),K=$.substring(0,G);if(X$(K)<=Y-Z.length)q=K,Q=G+1;else J=G-1}return q+Z},tQ=($)=>{return/[*_~`<[\]https?:]/.test($)};import{jsxDEV as I0,Fragment as jF}from"react/jsx-dev-runtime";var Z3=2,X3=1,Q3=2;function J3($,Y){return`${$.slice(0,20).replace(/[^a-zA-Z0-9]/g,"")}-${$.length}-${Y}`}var MF=({text:$})=>{let Y=k1();if(!tQ($))return I0(d0,{children:$},void 0,!1,void 0,this);let Z=[],X=0,Q=0,J=0,q=/(\*\*.*?\*\*|\*(?!\s).*?(?<!\s)\*|_(?!\s).*?(?<!\s)_|~~.*?~~|`+[^`]+`+|\[.*?\]\(.*?\)|https?:\/\/\S+)/g,G;while((G=q.exec($))!==null){if(G.index>X){let U=$.slice(X,G.index);Z.push(I0(d0,{children:U},J3(U,Q++),!1,void 0,this))}let K=G[0],W=null,O=J3(K,J++);try{if(K.startsWith("**")&&K.endsWith("**")&&K.length>Z3*2)W=I0(d0,{bold:!0,children:K.slice(Z3,-Z3)},O,!1,void 0,this);else if(K.length>X3*2&&(K.startsWith("*")&&K.endsWith("*")||K.startsWith("_")&&K.endsWith("_"))){let U=$.substring(G.index-1,G.index),F=$.substring(q.lastIndex,q.lastIndex+1);if(!(/\w/.test(U)||/\w/.test(F)||/[./\\]/.test(U+F)))W=I0(d0,{italic:!0,children:K.slice(X3,-X3)},O,!1,void 0,this)}else if(K.startsWith("~~")&&K.endsWith("~~")&&K.length>Q3*2)W=I0(d0,{strikethrough:!0,children:K.slice(Q3,-Q3)},O,!1,void 0,this);else if(K.startsWith("`")&&K.endsWith("`")){let U=K.match(/^(`+)([^`]+)\1$/);if(U&&U[2])W=I0(d0,{color:Y.colors.syntax.keyword,backgroundColor:Y.colors.background.secondary,bold:!0,children:` ${U[2]} `},O,!1,void 0,this)}else if(K.startsWith("[")&&K.includes("](")&&K.endsWith(")")){let U=K.match(/\[(.*?)\]\((.*?)\)/);if(U){let F=U[1],H=U[2];W=I0(d0,{children:[F,I0(d0,{color:Y.colors.info,children:[" (",H,")"]},void 0,!0,void 0,this)]},O,!0,void 0,this)}}else if(K.match(/^https?:\/\//))W=I0(d0,{color:Y.colors.info,children:K},O,!1,void 0,this)}catch(U){console.error("InlineRenderer 解析错误:",K,U),W=null}Z.push(W??I0(d0,{children:K},O,!1,void 0,this)),X=q.lastIndex}if(X<$.length){let K=$.slice(X);Z.push(I0(d0,{children:K},J3(K,Q++),!1,void 0,this))}return I0(jF,{children:Z.filter((K)=>K!==null)},void 0,!1,void 0,this)},M0=IF.memo(MF);import{Box as q3,Text as eQ}from"ink";import yF from"react";import{jsxDEV as n$}from"react/jsx-dev-runtime";var vF=({itemText:$,type:Y,marker:Z,leadingWhitespace:X=""})=>{let Q=Y==="ol"?`${Z}. `:`${Z} `,J=Q.length,q=X.length;return n$(q3,{paddingLeft:q+1,flexDirection:"row",children:[n$(q3,{width:J,children:n$(eQ,{children:Q},void 0,!1,void 0,this)},void 0,!1,void 0,this),n$(q3,{flexGrow:1,children:n$(eQ,{wrap:"wrap",children:n$(M0,{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)},$J=yF.memo(vF);import{Box as EF,Text as Q$}from"ink";import G3 from"react";import{jsxDEV as j0}from"react/jsx-dev-runtime";var YJ=G3.memo(({headers:$,rows:Y,terminalWidth:Z})=>{let X=k1();if($.length===0||Y.length===0)return null;let Q=$.map((F,H)=>{let _=X$(F),z=Math.max(...Y.map((L)=>X$(L[H]||"")));return Math.max(_,z)+2}),J=$.length+1,q=Q.reduce((F,H)=>F+H,0)+J,G=q>Z?Z/q:1,K=Q.map((F)=>Math.floor(F*G)),W=(F,H,_=!1)=>{let z=Math.max(0,H-2),L=X$(F),B=F;if(L>z)B=sQ(F,z);let N=X$(B),I=Math.max(0,z-N);return j0(Q$,{children:[_?j0(Q$,{bold:!0,color:X.colors.primary,children:j0(M0,{text:B},void 0,!1,void 0,this)},void 0,!1,void 0,this):j0(M0,{text:B},void 0,!1,void 0,this)," ".repeat(I)]},void 0,!0,void 0,this)},O=(F)=>{let _={top:{left:"┌",middle:"┬",right:"┐",horizontal:"─"},middle:{left:"├",middle:"┼",right:"┤",horizontal:"─"},bottom:{left:"└",middle:"┴",right:"┘",horizontal:"─"}}[F],z=K.map((B)=>_.horizontal.repeat(B)),L=_.left+z.join(_.middle)+_.right;return j0(Q$,{color:X.colors.text.muted,dimColor:!0,children:L},void 0,!1,void 0,this)},U=(F,H=!1)=>{let _=F.map((z,L)=>{let B=K[L]||0;return W(z||"",B,H)});return j0(Q$,{children:[j0(Q$,{color:X.colors.text.muted,children:"│ "},void 0,!1,void 0,this),_.map((z,L)=>j0(G3.Fragment,{children:[z,L<_.length-1&&j0(Q$,{color:X.colors.text.muted,children:" │ "},void 0,!1,void 0,this)]},L,!0,void 0,this)),j0(Q$,{color:X.colors.text.muted,children:" │"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};return j0(EF,{flexDirection:"column",marginY:1,children:[O("top"),U($,!0),O("middle"),Y.map((F,H)=>j0(G3.Fragment,{children:U(F)},H,!1,void 0,this)),O("bottom")]},void 0,!0,void 0,this)});import{jsxDEV as c}from"react/jsx-dev-runtime";var PF=($,Y,Z)=>{switch($){case"user":return{color:Y.info,prefix:"> "};case"assistant":return{color:Y.success,prefix:"• "};case"system":return{color:Y.warning,prefix:"⚙ "};case"tool":{let X=Z&&"phase"in Z?Z.phase:void 0;return{color:Y.text.secondary,prefix:X==="start"?"• ":X==="complete"?" └ ":" "}}default:return{color:Y.text.primary,prefix:" "}}},y0={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 K3($){let Y=[],Z=$.split(/\r?\n/),X=!1,Q=[],J=null,q=0,G=!1,K=[],W=[],O=!1,U=[],F=!0;for(let H=0;H<Z.length;H++){let _=Z[H];if(O){if(_.match(y0.diffEnd)){try{let w=JSON.parse(U.join(`
1871
- `));Y.push({type:"diff",content:"",diffData:{patch:w.patch,startLine:w.startLine,matchLine:w.matchLine}})}catch(w){Y.push({type:"text",content:U.join(`
1872
- `)})}O=!1,U=[],F=!1;continue}U.push(_);continue}if(_.match(y0.diffStart)){O=!0,U=[],F=!1;continue}if(X){let w=_.match(y0.codeBlock),R=_.trim()==="```";if(w&&w[1])q++,Q.push(_);else if(R)if(q>0)q--,Q.push(_);else{let E=Q.join(`
1873
- `);if(J?.toLowerCase()==="markdown"||J?.toLowerCase()==="md"){let x=K3(E);Y.push(...x)}else Y.push({type:"code",content:E,language:J||void 0});X=!1,Q=[],J=null,q=0,F=!1}else Q.push(_);continue}let z=_.match(y0.codeBlock);if(z){X=!0,J=z[1]||null,q=0,F=!1;continue}let L=_.match(y0.table),B=_.match(y0.tableSeparator);if(L&&!G){if(H+1<Z.length){if(Z[H+1].match(y0.tableSeparator)){G=!0,K=L[1].split("|").map((R)=>R.trim()).filter((R)=>R.length>0),W=[],F=!1;continue}}}if(G&&B)continue;if(G&&L){let w=L[1].split("|").map((R)=>R.trim()).filter((R)=>R.length>0);while(w.length<K.length)w.push("");if(w.length>K.length)w.length=K.length;W.push(w);continue}if(G&&!L){if(K.length>0&&W.length>0)Y.push({type:"table",content:"",tableData:{headers:K,rows:W}});G=!1,K=[],W=[]}let N=_.match(y0.heading);if(N){Y.push({type:"heading",content:N[2],level:N[1].length}),F=!1;continue}let I=_.match(y0.ulItem);if(I){Y.push({type:"list",content:I[3],listType:"ul",marker:I[2],indentation:I[1].length}),F=!1;continue}let M=_.match(y0.olItem);if(M){Y.push({type:"list",content:M[3],listType:"ol",marker:M[2],indentation:M[1].length}),F=!1;continue}if(_.match(y0.hr)){Y.push({type:"hr",content:""}),F=!1;continue}if(_.trim().length===0){if(!F)Y.push({type:"empty",content:""}),F=!0;continue}let D=_.match(y0.commandMessage);if(D){Y.push({type:"command-message",content:D[1]}),F=!1;continue}Y.push({type:"text",content:_}),F=!1}if(X){let H=Q.join(`
1874
- `);if(J?.toLowerCase()==="markdown"||J?.toLowerCase()==="md"){let _=K3(H);Y.push(..._)}else Y.push({type:"code",content:H,language:J||void 0})}if(G&&K.length>0&&W.length>0)Y.push({type:"table",content:"",tableData:{headers:K,rows:W}});return Y}var TF=({content:$,language:Y,terminalWidth:Z})=>{return c($3,{content:$,language:Y,showLineNumbers:!0,terminalWidth:Z},void 0,!1,void 0,this)},kF=({content:$,level:Y})=>{let Z=k1();switch(Y){case 1:return c(Z0,{bold:!0,color:Z.colors.primary,children:c(M0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 2:return c(Z0,{bold:!0,color:Z.colors.primary,children:c(M0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 3:return c(Z0,{bold:!0,color:Z.colors.text.primary,children:c(M0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 4:return c(Z0,{italic:!0,color:Z.colors.text.muted,children:c(M0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);default:return c(Z0,{children:c(M0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)}},SF=({terminalWidth:$})=>{let Y=k1(),Z=Math.max(0,Math.min($-4,80));return c(Z0,{dimColor:!0,color:Y.colors.text.muted,children:"─".repeat(Z)},void 0,!1,void 0,this)},CF=({content:$})=>{return c(Z0,{wrap:"wrap",children:c(M0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)},fF=({content:$})=>{let Y=k1();return c(o1,{flexDirection:"row",gap:1,children:[c(Z0,{color:Y.colors.info,children:"⏳"},void 0,!1,void 0,this),c(Z0,{color:Y.colors.text.muted,italic:!0,children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},hF=Z9.memo(({detail:$,terminalWidth:Y})=>{let Z=k1(),X=50,Q=$.split(`
1875
- `),J=Q.length>50,q=J?Q.slice(0,50):Q,G=q.join(`
1876
- `),K=G.includes("<<<DIFF>>>"),W=G.includes("```");if(K){let O=G.match(/<<<DIFF>>>\s*({[\s\S]*?})\s*<<<\/DIFF>>>/);if(O)try{let U=JSON.parse(O[1]);return c(o1,{flexDirection:"column",children:[c(Y3,{patch:U.patch,startLine:U.startLine,matchLine:U.matchLine,terminalWidth:Y},void 0,!1,void 0,this),J&&c(o1,{marginTop:1,children:c(Z0,{dimColor:!0,color:Z.colors.text.muted,children:["... 省略 ",Q.length-50," 行 ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}catch{}}if(W){let O=G.match(/```(\w+)?\s*\n([\s\S]*?)\n```/);if(O){let U=O[1]||"text",F=O[2];return c(o1,{flexDirection:"column",children:[c($3,{content:F,language:U,showLineNumbers:!1,terminalWidth:Y},void 0,!1,void 0,this),J&&c(o1,{marginTop:1,children:c(Z0,{dimColor:!0,color:Z.colors.text.muted,children:["... 省略 ",Q.length-50," 行 ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}}return c(o1,{flexDirection:"column",children:[q.map((O,U)=>c(Z0,{color:Z.colors.text.primary,children:O},U,!1,void 0,this)),J&&c(o1,{marginTop:1,children:c(Z0,{dimColor:!0,color:Z.colors.text.muted,children:["... 省略 ",Q.length-50," 行 ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});function xF($,Y){if($===Y)return!0;if(!$||!Y)return $===Y;return $.toolName===Y.toolName&&$.phase===Y.phase&&$.summary===Y.summary}var f6=Z9.memo(({content:$,role:Y,terminalWidth:Z,metadata:X,isPending:Q=!1})=>{let J=k1(),q=Z9.useMemo(()=>PF(Y,J.colors,X),[Y,J.colors,X]),{color:G,prefix:K}=q;if(Y==="tool"&&X&&"detail"in X){let O=X;if(O.detail)return c(o1,{flexDirection:"column",marginBottom:1,children:[c(o1,{flexDirection:"row",children:[c(o1,{marginRight:1,children:c(Z0,{color:G,bold:!0,children:K},void 0,!1,void 0,this)},void 0,!1,void 0,this),c(Z0,{color:G,children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),c(o1,{marginLeft:K.length+1,marginTop:1,children:c(hF,{detail:O.detail,terminalWidth:Z-(K.length+1)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}let W=Z9.useMemo(()=>K3($),[$]);return c(o1,{flexDirection:"column",marginBottom:1,children:W.map((O,U)=>{if(O.type==="empty")return c(o1,{height:1},U,!1,void 0,this);return c(o1,{flexDirection:"row",children:[U===0&&c(o1,{marginRight:1,children:c(Z0,{color:G,bold:!0,children:K},void 0,!1,void 0,this)},void 0,!1,void 0,this),U>0&&c(o1,{width:K.length+1},void 0,!1,void 0,this),c(o1,{flexGrow:1,children:O.type==="code"?c(TF,{content:O.content,language:O.language,terminalWidth:Z-(K.length+1)},void 0,!1,void 0,this):O.type==="table"&&O.tableData?c(YJ,{headers:O.tableData.headers,rows:O.tableData.rows,terminalWidth:Z-(K.length+1)},void 0,!1,void 0,this):O.type==="heading"?c(kF,{content:O.content,level:O.level||1},void 0,!1,void 0,this):O.type==="list"?c($J,{type:O.listType||"ul",marker:O.marker||"-",itemText:O.content,leadingWhitespace:" ".repeat(O.indentation||0)},void 0,!1,void 0,this):O.type==="hr"?c(SF,{terminalWidth:Z-(K.length+1)},void 0,!1,void 0,this):O.type==="diff"&&O.diffData?c(Y3,{patch:O.diffData.patch,startLine:O.diffData.startLine,matchLine:O.diffData.matchLine,terminalWidth:Z-(K.length+1)},void 0,!1,void 0,this):O.type==="command-message"?c(fF,{content:O.content},void 0,!1,void 0,this):c(CF,{content:O.content},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},U,!0,void 0,this)})},void 0,!1,void 0,this)},($,Y)=>{return $.content===Y.content&&$.role===Y.role&&$.terminalWidth===Y.terminalWidth&&$.isPending===Y.isPending&&xF($.metadata,Y.metadata)});import{jsxDEV as D1}from"react/jsx-dev-runtime";var mF=ZJ.memo(({label:$,isSelected:Y})=>D1(c0,{color:Y?"yellow":void 0,children:$},void 0,!1,void 0,this)),XJ=ZJ.memo(({details:$,onResponse:Y})=>{let Z=p2(),Q=V0()==="confirmation-prompt",J=p1(!1),q=$.type==="exitPlanMode",G=$.type==="enterPlanMode",K=$.type==="maxTurnsExceeded";pF((F,H)=>{if(H.ctrl&&F==="c"||H.meta&&F==="c"){J();return}if(H.escape){Y({approved:!1,reason:"用户取消"});return}let _=F.toLowerCase();if(q){if(_==="y"){Y({approved:!0,targetMode:"autoEdit"});return}if(_==="s"){Y({approved:!0,targetMode:"default"});return}if(_==="n"){Y({approved:!1,reason:"方案需要改进"});return}}else if(G){if(_==="y"){Y({approved:!0});return}if(_==="n"){Y({approved:!1,reason:"用户拒绝进入 Plan 模式"});return}}else if(K){if(_==="y"){Y({approved:!0});return}if(_==="n"){Y({approved:!1,reason:"用户选择停止"});return}}else{if(_==="y"){Y({approved:!0,scope:"once"});return}if(_==="s"){Y({approved:!0,scope:"session"});return}if(_==="n"){Y({approved:!1,reason:"用户拒绝"});return}}},{isActive:Q});let W=uF(()=>{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(G)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(K)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,G,K]),U=(()=>{if(q)return{color:"cyan",title:"\uD83D\uDD35 Plan Mode - Review Implementation Plan"};if(G)return{color:"magenta",title:"\uD83D\uDFE3 Enter Plan Mode?"};if(K)return{color:"yellow",title:"⚡ Max Turns Exceeded"};return{color:"yellow",title:"\uD83D\uDD14 Confirmation Required"}})();return D1(v0,{flexDirection:"column",borderStyle:"round",borderColor:Q?U.color:"gray",padding:1,children:[D1(v0,{marginBottom:1,children:D1(c0,{bold:!0,color:U.color,children:U.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),$.title&&D1(v0,{marginBottom:1,children:D1(c0,{bold:!0,children:$.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),D1(v0,{marginBottom:1,children:D1(c0,{children:$.message},void 0,!1,void 0,this)},void 0,!1,void 0,this),($.planContent||$.details)&&D1(v0,{flexDirection:"column",marginBottom:1,borderStyle:"single",borderColor:U.color,padding:1,children:[D1(c0,{bold:!0,color:U.color,children:q?"\uD83D\uDCCB Implementation Plan:":G?"\uD83D\uDCDD Details:":"\uD83D\uDCC4 Operation Details:"},void 0,!1,void 0,this),D1(v0,{marginTop:1,children:D1(f6,{content:$.planContent||$.details||"",role:"assistant",terminalWidth:Z-4},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$.risks&&$.risks.length>0&&D1(v0,{flexDirection:"column",marginBottom:1,children:[D1(c0,{color:"red",bold:!0,children:"⚠️ 风险提示:"},void 0,!1,void 0,this),$.risks.map((F,H)=>D1(v0,{marginLeft:2,children:D1(c0,{color:"red",children:["• ",F]},void 0,!0,void 0,this)},H,!1,void 0,this))]},void 0,!0,void 0,this),$.affectedFiles&&$.affectedFiles.length>0&&D1(v0,{flexDirection:"column",marginBottom:1,children:[D1(c0,{color:"yellow",children:"\uD83D\uDCC1 影响的文件:"},void 0,!1,void 0,this),$.affectedFiles.slice(0,3).map((F,H)=>D1(v0,{marginLeft:2,children:D1(c0,{children:["• ",F]},void 0,!0,void 0,this)},H,!1,void 0,this)),$.affectedFiles.length>3&&D1(v0,{marginLeft:2,children:D1(c0,{color:"gray",children:["...还有 ",$.affectedFiles.length-3," 个文件"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D1(v0,{flexDirection:"column",children:[D1(c0,{color:"gray",children:"使用 ↑ ↓ 选择,回车确认(支持 Y/S/N 快捷键,ESC 取消)"},void 0,!1,void 0,this),D1(gF,{items:W,isFocused:Q,itemComponent:mF,onSelect:(F)=>{Y(F.value)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});z0();w$();H2();import{Box as F1,Text as $1,useInput as dF}from"ink";import QJ from"ink-text-input";import{useState as A2}from"react";import{jsxDEV as f}from"react/jsx-dev-runtime";var h6=[{action:"add",description:"Add a new hook"},{action:"status",description:"Show hooks status"},{action:"list",description:"List all configured hooks"}],X9=[{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"}],Q9=[{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"}],cF=[`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"],JJ=({onClose:$,onSave:Y})=>{let Z=j1.getTheme(),[X,Q]=A2("action"),[J,q]=A2(0),[G,K]=A2(0),[W,O]=A2(0),[U,F]=A2(""),[H,_]=A2(""),[z,L]=A2(null),[B,N]=A2(!1),[I,M]=A2(null),A=h6[J],D=Q9[G],w=X9[W],R=()=>{if(I){M(null);return}switch(X){case"action":$();break;case"event":Q("action");break;case"matcher":Q("event");break;case"command":Q("matcher");break;case"location":Q("command");break;case"confirm":Q("location");break}};dF((k,S)=>{if(S.escape){R();return}if(X==="action"){if(S.upArrow)q((y)=>y>0?y-1:h6.length-1);else if(S.downArrow)q((y)=>y<h6.length-1?y+1:0);else if(S.return)E()}else if(X==="event"){if(S.upArrow)K((y)=>y>0?y-1:Q9.length-1);else if(S.downArrow)K((y)=>y<Q9.length-1?y+1:0);else if(S.return)Q("matcher")}else if(X==="location"){if(S.upArrow)O((y)=>y>0?y-1:X9.length-1);else if(S.downArrow)O((y)=>y<X9.length-1?y+1:0);else if(S.return)Q("confirm")}else if(X==="confirm"){if(S.return)Y1()}});let E=()=>{let k=h6[J].action;if(k==="add")Q("event");else if(k==="status")x();else if(k==="list")r()},x=()=>{let k=H1.getInstance(),S=k.isEnabled(),y=k.getConfig(),v1={};for(let t of Object.values(o0)){let _1=y[t];if(_1&&Array.isArray(_1)){let g=_1.reduce((K1,s)=>K1+(s.hooks?.length||0),0);if(g>0)v1[t]=g}}let m=[`Status: ${S?"✅ Enabled":"⏸️ Disabled"}`,""];if(Object.keys(v1).length>0){m.push("Configured hooks:");for(let[t,_1]of Object.entries(v1))m.push(` ${t}: ${_1} hook(s)`)}else m.push("No hooks configured");M(m.join(`
1877
- `))},r=()=>{let S=H1.getInstance().getConfig(),y=[],v1=!1;for(let m of Object.values(o0)){let t=S[m];if(!t||!Array.isArray(t)||t.length===0)continue;v1=!0,y.push(`${m}:`);for(let _1 of t){let g=_1.matcher,K1="all";if(g?.tools)K1=`tools: ${Array.isArray(g.tools)?g.tools.join(", "):g.tools}`;y.push(` [${K1}]`);for(let s of _1.hooks||[])if(s.type==="command")y.push(` → ${s.command}`)}y.push("")}if(!v1)y.push("No hooks configured"),y.push(""),y.push("Configure hooks in .blade/settings.local.json");M(y.join(`
1878
- `))},j=()=>{Q("command")},C=()=>{if(!H.trim()){L("Command cannot be empty");return}L(null),Q("location")},Y1=async()=>{N(!0),L(null);try{let k=H1.getInstance(),S=await import("node:fs/promises"),y=await import("node:path"),v1=await import("node:os"),m={matcher:U.trim()?{tools:U.trim()}:{},hooks:[{type:"command",command:H.trim()}]},t;switch(w.location){case"local":t=y.join(process.cwd(),".blade","settings.local.json");break;case"project":t=y.join(process.cwd(),".blade","settings.json");break;case"user":t=y.join(v1.homedir(),".blade","settings.json");break}await S.mkdir(y.dirname(t),{recursive:!0});let _1={};try{let J0=await S.readFile(t,"utf-8");_1=JSON.parse(J0)}catch{}let g=_1.hooks||{},K1=g[D.event]||[],s={...g,enabled:!0,[D.event]:[...K1,m]};if(_1.hooks=s,await S.writeFile(t,JSON.stringify(_1,null,2),"utf-8"),await k.reloadConfig(),Y)Y({event:D.event,matcher:U.trim(),command:H.trim()});$()}catch(k){L(`Failed to save hook: ${k instanceof Error?k.message:"Unknown error"}`),N(!1)}};return f(F1,{flexDirection:"column",padding:1,children:[f(F1,{marginBottom:1,children:f($1,{bold:!0,color:Z.colors.success,children:"Hooks Manager"},void 0,!1,void 0,this)},void 0,!1,void 0,this),f(F1,{marginBottom:1,children:f($1,{color:Z.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),I&&f(F1,{flexDirection:"column",marginBottom:1,children:[f($1,{children:I},void 0,!1,void 0,this),f(F1,{marginTop:1,children:f($1,{color:Z.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),X==="action"&&!I&&f(F1,{flexDirection:"column",children:[f(F1,{flexDirection:"column",marginTop:1,children:h6.map((k,S)=>f(F1,{children:[f($1,{color:S===J?Z.colors.primary:void 0,bold:S===J,children:[S===J?"❯ ":" ",k.action]},void 0,!0,void 0,this),f($1,{color:Z.colors.muted,children:[" - ",k.description]},void 0,!0,void 0,this)]},k.action,!0,void 0,this))},void 0,!1,void 0,this),f(F1,{marginTop:1,children:f($1,{color:Z.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),X==="event"&&f(F1,{flexDirection:"column",children:[f($1,{bold:!0,children:"Select Event:"},void 0,!1,void 0,this),f(F1,{flexDirection:"column",marginTop:1,children:Q9.map((k,S)=>f(F1,{children:[f($1,{color:S===G?Z.colors.primary:void 0,bold:S===G,children:[S===G?"❯ ":" ",k.event]},void 0,!0,void 0,this),f($1,{color:Z.colors.muted,children:[" - ",k.description]},void 0,!0,void 0,this)]},k.event,!0,void 0,this))},void 0,!1,void 0,this),f(F1,{marginTop:1,children:f($1,{color:Z.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),X!=="event"&&f(F1,{marginBottom:1,children:f($1,{children:["Event:"," ",f($1,{bold:!0,color:Z.colors.primary,children:D.event},void 0,!1,void 0,this),f($1,{color:Z.colors.muted,children:[" - ",D.description]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),(X==="matcher"||X==="command"||X==="confirm")&&f(F1,{flexDirection:"column",marginBottom:1,children:[f($1,{color:Z.colors.muted,children:"Input to command is JSON of tool call arguments."},void 0,!1,void 0,this),f($1,{color:Z.colors.muted,children:"Exit code 0 - stdout/stderr not shown"},void 0,!1,void 0,this),f($1,{color:Z.colors.muted,children:"Exit code 2 - show stderr to model and block tool call"},void 0,!1,void 0,this),f($1,{color:Z.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),X==="matcher"&&f(F1,{flexDirection:"column",children:[f(F1,{children:[f($1,{bold:!0,children:"Matcher: "},void 0,!1,void 0,this),f(QJ,{value:U,onChange:F,onSubmit:j,placeholder:"e.g., Read, Bash, Edit|Write (empty = all tools)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f(F1,{marginTop:1,children:f($1,{color:Z.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),f(F1,{marginTop:1,children:f($1,{color:Z.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),(X==="command"||X==="confirm")&&f(F1,{marginBottom:1,children:f($1,{children:["Matcher: ",f($1,{bold:!0,children:U||"(all tools)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),X==="command"&&f(F1,{flexDirection:"column",children:[f(F1,{children:f($1,{bold:!0,children:"Command: "},void 0,!1,void 0,this)},void 0,!1,void 0,this),f(F1,{borderStyle:"single",borderColor:Z.colors.border.light,paddingX:1,marginTop:1,children:f(QJ,{value:H,onChange:_,onSubmit:C,placeholder:"Enter shell command..."},void 0,!1,void 0,this)},void 0,!1,void 0,this),f(F1,{flexDirection:"column",marginTop:1,children:[f($1,{bold:!0,children:"Examples:"},void 0,!1,void 0,this),cF.map((k,S)=>f($1,{color:Z.colors.muted,children:["• ",k]},S,!0,void 0,this))]},void 0,!0,void 0,this),f(F1,{marginTop:1,children:f($1,{color:Z.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),X==="location"&&f(F1,{flexDirection:"column",children:[f(F1,{flexDirection:"column",borderStyle:"round",borderColor:Z.colors.border.light,paddingX:2,paddingY:1,marginBottom:1,children:[f($1,{bold:!0,color:Z.colors.primary,children:"Save hook configuration"},void 0,!1,void 0,this),f($1,{children:" "},void 0,!1,void 0,this),f($1,{children:[" Event: ",D.event," - ",D.description]},void 0,!0,void 0,this),f($1,{children:[" Matcher: ",U||"(all)"]},void 0,!0,void 0,this),f($1,{children:[" Command: ",H]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),f($1,{bold:!0,children:"Where should this hook be saved?"},void 0,!1,void 0,this),f(F1,{flexDirection:"column",marginTop:1,children:X9.map((k,S)=>f(F1,{children:[f($1,{color:S===W?Z.colors.primary:void 0,bold:S===W,children:[S===W?"❯ ":" ",S+1,". ",k.name]},void 0,!0,void 0,this),f($1,{color:Z.colors.muted,children:[" ",k.description]},void 0,!0,void 0,this)]},k.location,!0,void 0,this))},void 0,!1,void 0,this),f(F1,{marginTop:1,children:f($1,{color:Z.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),X==="confirm"&&f(F1,{flexDirection:"column",children:[f(F1,{flexDirection:"column",borderStyle:"round",borderColor:Z.colors.success,paddingX:2,paddingY:1,children:[f($1,{bold:!0,children:["Saving hook to ",w.description,"..."]},void 0,!0,void 0,this),f($1,{children:" "},void 0,!1,void 0,this),f($1,{children:["Event: ",D.event]},void 0,!0,void 0,this),f($1,{children:["Matcher: ",U||"(all tools)"]},void 0,!0,void 0,this),f($1,{children:["Command: ",H]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),f(F1,{marginTop:1,children:f($1,{color:Z.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&&f(F1,{marginTop:1,children:f($1,{color:Z.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 zJ}from"ahooks";import{Box as ZH,Text as XH}from"ink";import QH from"react";import{useMemoizedFn as oF}from"ahooks";import J$ from"chalk";import{Text as sF,useInput as tF}from"ink";import{useEffect as O3,useRef as F3}from"react";var b2={TIMEOUT_MS:100,RAPID_INPUT_THRESHOLD_MS:150,LARGE_INPUT_THRESHOLD:300,MEDIUM_SIZE_MULTI_CHUNK_THRESHOLD:200};import{execSync as o$}from"node:child_process";import{existsSync as lF,readFileSync as U3}from"node:fs";import{basename as qJ,isAbsolute as iF}from"node:path";function aF(){let $=process.platform,Y={darwin:"No image found in clipboard. Use Cmd + Ctrl + Shift + 4 to copy a screenshot to clipboard.",win32:"No image found in clipboard. Use Print Screen to copy a screenshot to clipboard.",linux:"No image found in clipboard. Use appropriate screenshot tool to copy a screenshot to clipboard."};return Y[$]||Y.linux}var cv=aF();function GJ($){try{let Y=Buffer.from($,"base64");if(Y.length<4)return"image/png";if(Y[0]===137&&Y[1]===80&&Y[2]===78&&Y[3]===71)return"image/png";if(Y[0]===255&&Y[1]===216&&Y[2]===255)return"image/jpeg";if(Y[0]===71&&Y[1]===73&&Y[2]===70)return"image/gif";if(Y[0]===82&&Y[1]===73&&Y[2]===70&&Y[3]===70){if(Y.length>=12&&Y[8]===87&&Y[9]===69&&Y[10]===66&&Y[11]===80)return"image/webp"}return"image/png"}catch{return"image/png"}}function KJ(){let $=process.platform,Y={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"},Z={darwin:{checkImage:"osascript -e 'the clipboard as «class PNGf»'",saveImage:(X)=>`osascript -e 'set png_data to (the clipboard as «class PNGf»)' -e 'set fp to open for access POSIX file "${X}" 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:(X)=>`rm -f "${X}"`},linux:{checkImage:'xclip -selection clipboard -t TARGETS -o | grep -E "image/(png|jpeg|jpg|gif|webp)"',saveImage:(X)=>`xclip -selection clipboard -t image/png -o > "${X}" || wl-paste --type image/png > "${X}"`,getPath:"xclip -selection clipboard -t text/plain -o",deleteFile:(X)=>`rm -f "${X}"`},win32:{checkImage:'powershell -Command "(Get-Clipboard -Format Image) -ne $null"',saveImage:(X)=>`powershell -Command "$img = Get-Clipboard -Format Image; if ($img) { $img.Save('${X.replace(/\\/g,"\\\\")}', [System.Drawing.Imaging.ImageFormat]::Png) }"`,getPath:'powershell -Command "Get-Clipboard"',deleteFile:(X)=>`del /f "${X}"`}};return{commands:Z[$]||Z.linux,screenshotPath:Y[$]||Y.linux}}function rF(){let{commands:$}=KJ();try{return o$($.getPath,{encoding:"utf-8"}).trim()}catch(Y){return console.error("Failed to get clipboard path:",Y),null}}function UJ($){if($.startsWith('"')&&$.endsWith('"')||$.startsWith("'")&&$.endsWith("'"))return $.slice(1,-1);return $}function WJ($){if(process.platform==="win32")return $;let Y="__DOUBLE_BACKSLASH__";return $.replace(/\\\\/g,Y).replace(/\\(.)/g,"$1").replace(new RegExp(Y,"g"),"\\")}function W3($){let Y=UJ($.trim()),Z=WJ(Y);return/\.(png|jpe?g|gif|webp)$/i.test(Z)}function nF($){let Y=UJ($.trim()),Z=WJ(Y);if(W3(Z))return Z;return null}async function OJ($){let Y=nF($);if(!Y)return null;let Z;try{if(iF(Y))Z=U3(Y);else{let q=rF();if(q&&Y===qJ(q))Z=U3(q);else return null}}catch(q){return console.error("Failed to read image file:",q),null}let X=Z.toString("base64"),Q=GJ(X),J=qJ(Y);return{path:Y,base64:X,mediaType:Q,filename:J}}async function FJ(){let $=process.platform,Y={darwin:"pbpaste",linux:"xclip -selection clipboard -o || wl-paste",win32:'powershell -Command "Get-Clipboard"'},Z=Y[$]||Y.linux;try{return o$(Z,{encoding:"utf-8"})||null}catch{return null}}async function HJ(){let{commands:$,screenshotPath:Y}=KJ();try{if(o$($.checkImage,{stdio:"ignore"}),o$($.saveImage(Y),{stdio:"ignore"}),!lF(Y))return null;let X=U3(Y).toString("base64"),Q=GJ(X);return o$($.deleteFile(Y),{stdio:"ignore"}),{base64:X,mediaType:Q}}catch(Z){try{o$($.deleteFile(Y),{stdio:"ignore"})}catch{}return null}}import{jsxDEV as YH}from"react/jsx-dev-runtime";var eF=/\r\n/g,$H=/\r/g;function q$($){if(!$.includes("\r"))return $;return $.replace(eF,`
1879
- `).replace($H,`
1880
- `)}function G$($,Y,Z){let X=Math.max(0,Math.min(Z,Y.length)),Q=Y.slice(0,X),J=Y.slice(X);return{newValue:Q+$+J,newCursorPosition:X+$.length}}function _J({value:$,placeholder:Y="",focus:Z=!0,onChange:X,cursorPosition:Q,onChangeCursorPosition:J,onPaste:q,onImagePaste:G,disabledKeys:K=[]}){let W=F3({chunks:[],timeoutId:null,firstInputTime:null,lastInputTime:null,totalLength:0}),O=F3($),U=F3(Q);O3(()=>{O.current=$,U.current=Q},[$,Q]),O3(()=>{return()=>{if(W.current.timeoutId)clearTimeout(W.current.timeoutId)}},[]),O3(()=>{if(Q>$.length)J($.length)},[$,Q,J]);let F=oF(()=>{let L=W.current;if(L.timeoutId)clearTimeout(L.timeoutId);let B=setTimeout(async()=>{let N=W.current.chunks,I=W.current.totalLength;if(N.length===0)return;let M=q$(N.join(""));W.current={chunks:[],timeoutId:null,firstInputTime:null,lastInputTime:null,totalLength:0};let A=O.current,D=U.current;if(G&&W3(M))try{let j=await OJ(M);if(j){let C=await G(j.base64,j.mediaType,j.filename);if(C?.prompt){let Y1=q$(C.prompt),{newValue:k,newCursorPosition:S}=G$(Y1,A,D);X(k),J(S)}return}}catch(j){console.error("Failed to process image path:",j)}let w=M.includes(`
1881
- `),R=I>b2.MEDIUM_SIZE_MULTI_CHUNK_THRESHOLD&&N.length>3;if((I>b2.LARGE_INPUT_THRESHOLD||w||R)&&q){let j=await q(M);if(j?.prompt){let C=q$(j.prompt),{newValue:Y1,newCursorPosition:k}=G$(C,A,D);X(Y1),J(k);return}}let{newValue:x,newCursorPosition:r}=G$(M,A,D);X(x),J(r)},b2.TIMEOUT_MS);W.current.timeoutId=B});tF((L,B)=>{let N=q$(L);if(K.some((R)=>B[R])||B.ctrl&&L==="c"||B.shift&&B.tab||N==="?"&&$==="")return;let M=Date.now(),A=W.current,D=Q,w=$;if(B.leftArrow)D--;else if(B.rightArrow)D++;else if(B.backspace||B.delete){if(L===""){if(Q>0)w=$.slice(0,Q-1)+$.slice(Q,$.length),D--}else if(Q<$.length)w=$.slice(0,Q)+$.slice(Q+1,$.length)}else if(B.ctrl&&N==="a")D=0;else if(B.ctrl&&N==="e")D=$.length;else if(B.ctrl&&N==="k")w=$.slice(0,Q);else if(B.ctrl&&N==="u")w=$.slice(Q),D=0;else if(B.ctrl&&N==="w"){let E=$.slice(0,Q).match(/\s*\S+\s*$/);if(E){let x=E[0].length;w=$.slice(0,Q-x)+$.slice(Q),D-=x}}else if(B.ctrl&&N==="v"){let R=process.platform==="darwin";(async()=>{if(G){let x=await HJ();if(x){let r=await G(x.base64,x.mediaType,"clipboard.png");if(r?.prompt){let j=q$(r.prompt),{newValue:C,newCursorPosition:Y1}=G$(j,O.current,U.current);X(C),J(Y1)}return}}if(R)return;let E=await FJ();if(E){let x=q$(E),r=x.includes(`
1882
- `),j=x.length>b2.LARGE_INPUT_THRESHOLD;if((r||j)&&q){let k=await q(x);if(k?.prompt){let S=q$(k.prompt),{newValue:y,newCursorPosition:v1}=G$(S,O.current,U.current);X(y),J(v1);return}}let{newValue:C,newCursorPosition:Y1}=G$(x,O.current,U.current);X(C),J(Y1)}})().catch(()=>{});return}else if(B.pageUp)D=0;else if(B.pageDown)D=$.length;else if(N===`
1883
- `&&(B.shift||B.meta)){let{newValue:R,newCursorPosition:E}=G$(N,$,Q);X(R),J(E);return}else if(!B.ctrl&&!B.meta){if(!A.firstInputTime)A.firstInputTime=M;A.lastInputTime=M;let R=M-(A.firstInputTime||M),E=N.length>b2.LARGE_INPUT_THRESHOLD,x=N.includes(`
1884
- `)&&N.length>1,r=R<b2.RAPID_INPUT_THRESHOLD_MS&&A.chunks.length>0,j=R<b2.RAPID_INPUT_THRESHOLD_MS&&N.length>10,C=A.timeoutId!==null;if(q&&(E||x||r||j||C)){A.chunks.push(N),A.totalLength+=N.length,F();return}if(N.length===1&&!A.timeoutId)A.chunks=[],A.firstInputTime=null,A.lastInputTime=null,A.totalLength=0;w=$.slice(0,Q)+N+$.slice(Q,$.length),D+=N.length}if(D<0)D=0;if(D>w.length)D=w.length;if(w!==$)X(w);if(D!==Q)J(D)},{isActive:Z});let H=Z,_=$,z=Y?J$.grey(Y):void 0;if(H)if(z=Y.length>0?J$.inverse(Y[0])+J$.grey(Y.slice(1)):J$.inverse(" "),$.length===0)_=J$.inverse(" ");else{_="";for(let L=0;L<$.length;L++)if(L===Q&&Q<$.length)_+=J$.inverse($[L]);else _+=$[L];if(Q>=$.length)_+=J$.inverse(" ")}return YH(sF,{children:Y?$.length>0?_:z:_},void 0,!1,void 0,this)}import{jsxDEV as H3}from"react/jsx-dev-runtime";var NJ=QH.memo(({input:$,cursorPosition:Y,onChange:Z,onChangeCursorPosition:X,onAddPasteMapping:Q,onAddImagePasteMapping:J})=>{let G=V0()==="main-input",K=zJ((O)=>{let U=O.split(`
1885
- `).length,F=O.length,H=500,_=10;if(F>500||U>10){let z=Q(O),L=O.slice(0,30).replace(/\n/g," "),B=`${F} chars, ${U} lines: ${L}...`;return{prompt:`${n4(z)}${B}${g7()}`}}return{}}),W=zJ(async(O,U,F)=>{try{let H=J(O,U);return{prompt:`${n4(H)}[Image #${H}]${g7()}`}}catch(H){return console.error("[Image Paste] Failed to process image:",H),{prompt:`[Image paste failed: ${H instanceof Error?H.message:"Unknown error"}] `}}});return H3(ZH,{flexDirection:"row",width:"100%",paddingX:2,paddingY:0,flexShrink:0,flexGrow:0,overflow:"hidden",borderStyle:"round",borderColor:"gray",children:[H3(XH,{color:"blue",bold:!0,children:"> "},void 0,!1,void 0,this),H3(_J,{value:$,cursorPosition:Y,onChange:Z,onChangeCursorPosition:X,onPaste:K,onImagePaste:W,placeholder:" 输入命令...",focus:G,disabledKeys:["upArrow","downArrow","tab","return","escape"]},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});import{Box as J9,Text as l0}from"ink";import UH,{useEffect as WH,useState as OH}from"react";import{useEffect as KH,useState as AJ}from"react";import{useEffect as JH,useState as qH}from"react";var GH=15000,BJ=["炼化代码灵气...","参悟 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 广纳贤才..."],LJ=["Esc - 立即停止当前任务","Shift+Tab - 切换权限模式 (default/auto_edit/plan)","Tab - 智能补全斜杠命令","↑↓ - 浏览输入历史记录","双击 Esc - 快速清空输入框","Ctrl+C - 强制终止程序","Ctrl+L - 清屏(保留历史)","Ctrl+R - 反向搜索历史","Ctrl+U - 清空当前行","/help - 查看完整帮助文档","/init - 生成 BLADE.md 项目配置","/resume - 恢复历史会话","/compact - 手动压缩上下文(节省 token)","/theme - 打开主题选择器","/config - 打开配置面板","/model - 管理与切换模型配置","/permissions - 管理工具权限规则","/mcp - 查看 MCP 服务器状态","/agents - 管理 Subagent 配置","/version - 显示版本信息","/clear - 清除屏幕内容","/status - 显示当前项目配置状态","/context - 可视化当前上下文使用情况","/cost - 显示会话成本统计","/exit - 退出 REPL","@ 文件路径 - 附加文件到上下文","@dir/ - 附加整个目录","@file.ts:10-20 - 附加指定行范围","Plan 模式 - 先规划后编码(/plan)","Auto Edit 模式 - 自动批准工具调用","MCP 协议 - 扩展外部工具集成","Subagents - 并行执行子任务","Hooks 系统 - 自定义工具执行流程","Context 压缩 - 自动总结历史对话","Loop 检测 - 防止无限循环","提示:使用 /init 让 AI 理解你的项目结构","提示:Plan 模式适合复杂多步骤任务","提示:Auto Edit 可加速重复性操作","提示:@ 引用可提供更精准的上下文","提示:定期 /compact 节省 token 成本","提示:使用 /permissions 控制工具权限","提示:Shift+Tab 快速切换模式","提示:Esc 可随时中断长时间任务","提示:/resume 继续未完成的对话","提示:/export 保存重要对话记录"];function wJ($,Y,Z=!1){let[X,Q]=qH("");return JH(()=>{if(Y){Q("等待用户确认...");return}if(!$){Q("");return}if(Z)return;let J=()=>{if(Math.random()<0.16666666666666666){let W=Math.floor(Math.random()*LJ.length);return LJ[W]}let K=Math.floor(Math.random()*BJ.length);return BJ[K]};Q(J());let q=setInterval(()=>{Q(J())},GH);return()=>{clearInterval(q)}},[$,Y,Z]),X}function bJ($,Y=!1,Z=!1){let[X,Q]=AJ(0),[J,q]=AJ(null),G=wJ($,Y,Z);return KH(()=>{if(!$){Q(0),q(null);return}if(Z)return;if(J===null)q(Date.now());let K=setInterval(()=>{if(J!==null){let W=Math.floor((Date.now()-J)/1000);Q(W)}},1000);return()=>{clearInterval(K)}},[$,J,Z]),{currentPhrase:G,elapsedTime:X}}import{jsxDEV as X0,Fragment as HH}from"react/jsx-dev-runtime";var _3=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"],FH=80;function RJ($){if($<60)return`${$}s`;let Y=Math.floor($/60),Z=$%60;return`${Y}m ${Z}s`}var VJ=UH.memo(({message:$,paused:Y=!1})=>{let Z=J2(),X=c4(),Q=Z||!X,[J,q]=OH(0),G=k1(),W=p2()>=FH,{currentPhrase:O,elapsedTime:U}=bJ(Q,!1,Y);if(WH(()=>{if(!Q||Y){q(0);return}let H=setInterval(()=>{q((_)=>(_+1)%_3.length)},80);return()=>clearInterval(H)},[Q,Y]),!Q)return null;let F=O||$||"正在思考中...";if(W)return X0(J9,{paddingX:2,paddingBottom:1,flexDirection:"row",gap:1,children:[X0(l0,{color:G.colors.warning,bold:!0,children:_3[J]},void 0,!1,void 0,this),X0(l0,{color:G.colors.text.primary,children:F},void 0,!1,void 0,this),U>0&&X0(HH,{children:[X0(l0,{color:G.colors.muted,children:"|"},void 0,!1,void 0,this),X0(l0,{color:G.colors.info,children:["已用时: ",RJ(U)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),X0(l0,{color:G.colors.muted,children:"|"},void 0,!1,void 0,this),X0(l0,{color:G.colors.secondary,children:"Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return X0(J9,{paddingX:2,paddingBottom:1,flexDirection:"column",children:[X0(J9,{flexDirection:"row",gap:1,children:[X0(l0,{color:G.colors.warning,bold:!0,children:_3[J]},void 0,!1,void 0,this),X0(l0,{color:G.colors.text.primary,children:F},void 0,!1,void 0,this)]},void 0,!0,void 0,this),U>0&&X0(J9,{marginLeft:2,flexDirection:"row",gap:1,children:[X0(l0,{color:G.colors.info,children:["已用时: ",RJ(U)]},void 0,!0,void 0,this),X0(l0,{color:G.colors.muted,children:"|"},void 0,!1,void 0,this),X0(l0,{color:G.colors.secondary,children:"Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});import DH from"ansi-escapes";import{Box as t$,Static as IH,useStdout as MH}from"ink";import EJ,{useEffect as PJ,useMemo as g6,useRef as jH}from"react";import{Box as _H,Text as DJ}from"ink";import zH from"react";import{jsxDEV as z3}from"react/jsx-dev-runtime";var N3=zH.memo(({collapsedCount:$})=>{let Y=k1();if($<=0)return null;let Z=Y.colors.text.muted;return z3(_H,{flexDirection:"row",marginBottom:1,children:[z3(DJ,{color:Z,children:["▶ ",$," 条历史消息"]},void 0,!0,void 0,this),z3(DJ,{color:Z,children:" [Ctrl+O 展开]"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});N3.displayName="CollapsedHistorySummary";X6();import{Box as x6,Text as p6}from"ink";import NH from"ink-big-text";import BH from"ink-gradient";import LH from"react";import{jsxDEV as E0}from"react/jsx-dev-runtime";var IJ=LH.memo(()=>{return E0(x6,{flexDirection:"column",paddingX:2,paddingTop:1,paddingBottom:1,children:[E0(x6,{flexDirection:"column",children:E0(BH,{name:"pastel",children:E0(NH,{text:"BLADE",font:"block"},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),E0(x6,{marginBottom:1,children:E0(p6,{color:"white",dimColor:!0,children:T3()},void 0,!1,void 0,this)},void 0,!1,void 0,this),E0(x6,{flexDirection:"column",marginBottom:1,children:[E0(x6,{marginBottom:1,children:E0(p6,{color:"white",bold:!0,children:"使用指南:"},void 0,!1,void 0,this)},void 0,!1,void 0,this),E0(p6,{color:"white",children:"1. 输入问题、编辑文件或运行命令"},void 0,!1,void 0,this),E0(p6,{color:"white",children:"2. 使用 /init 创建项目配置文件"},void 0,!1,void 0,this),E0(p6,{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 B3,Text as s$}from"ink";import wH,{useMemo as MJ}from"react";import{jsxDEV as R2}from"react/jsx-dev-runtime";function AH($,Y=60){if(!$)return"";let Z=$.split(`
1886
- `)[0]||"";if(Z.length<=Y)return Z;return`${Z.slice(0,Y)}...`}function bH($){if(!$)return 0;return $.split(`
1887
- `).length}var L3=wH.memo(({content:$,isStreaming:Y=!1,isExpanded:Z})=>{let X=k1(),Q=MJ(()=>bH($),[$]),J=MJ(()=>AH($),[$]),q=X.colors.info,G=X.colors.muted;return R2(B3,{flexDirection:"column",marginBottom:1,children:[R2(B3,{flexDirection:"row",children:[R2(s$,{color:q,children:Z?"▼":"▶"},void 0,!1,void 0,this),R2(s$,{children:" "},void 0,!1,void 0,this),R2(s$,{color:G,children:["Thinking",Y?"...":` (${Q} lines)`]},void 0,!0,void 0,this),!Z&&!Y&&J&&R2(s$,{color:G,children:[" - ",J]},void 0,!0,void 0,this),R2(s$,{color:G,dimColor:!0,children:[" ","[Ctrl+T]"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Z&&$&&R2(B3,{marginLeft:2,marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,paddingY:0,children:R2(s$,{color:G,children:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});L3.displayName="ThinkingBlock";import{Box as q9,Text as w3}from"ink";H2();import{useState as jJ}from"react";function RH(){let[$,Y]=jJ(j1.getTheme()),[Z,X]=jJ(j1.getCurrentThemeName()),Q=(K)=>{try{j1.setTheme(K),Y(j1.getTheme()),X(K)}catch(W){console.error("Failed to change theme:",W)}},J=j1.getAvailableThemes();return{theme:$,themeName:Z,changeTheme:Q,availableThemes:J,hasTheme:(K)=>j1.hasTheme(K),getThemeByName:(K)=>j1.getThemeByName(K),colors:$.colors,spacing:$.spacing,typography:$.typography}}function yJ(){let{colors:$}=RH();return $}import{jsxDEV as g2}from"react/jsx-dev-runtime";var vJ=({todos:$,visible:Y=!0,compact:Z=!1})=>{let X=yJ();if(!Y||$.length===0)return null;let Q={total:$.length,completed:$.filter((J)=>J.status==="completed").length,inProgress:$.filter((J)=>J.status==="in_progress").length};return g2(q9,{flexDirection:"column",borderStyle:"single",borderColor:X.border.light,paddingX:1,paddingY:Z?0:1,marginBottom:1,children:[g2(q9,{marginBottom:Z?0:1,children:[g2(w3,{dimColor:!0,children:"Tasks "},void 0,!1,void 0,this),g2(w3,{color:X.text.muted,children:[Q.completed,"/",Q.total]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),g2(q9,{flexDirection:"column",children:$.map((J,q)=>g2(VH,{todo:J,compact:Z},J.id||q,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},VH=({todo:$,compact:Y})=>{let Z,X=!1,Q;switch($.status){case"completed":Z="✓",X=!0,Q=$.content;break;case"in_progress":Z="▶",X=!1,Q=$.activeForm;break;case"pending":default:Z="○",X=!0,Q=$.content;break}return g2(q9,{paddingY:Y?0:0,children:g2(w3,{dimColor:X,children:[Z," ",Q]},void 0,!0,void 0,this)},void 0,!1,void 0,this)};import{jsxDEV as B0}from"react/jsx-dev-runtime";var TJ=EJ.memo(()=>{let $=m4(),Y=J2(),Z=ZQ(),X=qQ(),Q=OQ(),J=HQ(),q=_Q(),G=sX(),K=NQ(),W=zQ(),O=p2(),{stdout:U}=MH(),F=EJ.useRef(0),H=jH(W);PJ(()=>{F.current=0},[G]),PJ(()=>{if(H.current!==W){if(U)U.write(DH.clearTerminal);F.current=0,H.current=W}},[W,U]);let{completedMessages:_,streamingMessage:z}=g6(()=>{let A=$.length>0?$[$.length-1]:null,D=Y&&A&&A.role==="assistant",w=Math.max(F.current,D?$.length-1:$.length);F.current=w;let R=$.slice(0,w),E=w<$.length?$[w]:null;return{completedMessages:R,streamingMessage:E}},[$,Y]),L=g6(()=>{return Z.some((A)=>A.status==="pending"||A.status==="in_progress")},[Z]),B=g6(()=>{if(W)return 0;return Math.max(0,$.length-K)},[$.length,K,W]),N=(A,D=!1)=>B0(t$,{flexDirection:"column",children:B0(f6,{content:A.content,role:A.role,terminalWidth:O,metadata:A.metadata,isPending:D},void 0,!1,void 0,this)},A.id,!1,void 0,this),I=g6(()=>{return Math.min(B,_.length)},[B,_.length]),M=g6(()=>{let A=[];if(A.push(B0(IJ,{},"header",!1,void 0,this)),I>0)A.push(B0(N3,{collapsedCount:I},"collapsed-summary",!1,void 0,this));return _.forEach((D,w)=>{if(w>=B)A.push(N(D))}),A},[_,O,B,I]);return B0(t$,{flexDirection:"column",flexGrow:1,paddingX:2,children:B0(t$,{flexDirection:"column",flexGrow:1,children:[B0(IH,{items:M,children:(A)=>A},`${G}-${W}`,!1,void 0,this),J&&B0(t$,{marginBottom:1,children:B0(L3,{content:J,isStreaming:Y,isExpanded:q},void 0,!1,void 0,this)},void 0,!1,void 0,this),z&&N(z,!0),X&&L&&B0(t$,{marginTop:1,children:B0(vJ,{todos:Z,visible:!0,compact:!1},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q.map((A,D)=>B0(t$,{flexDirection:"column",children:B0(f6,{content:A.displayText,role:"user",terminalWidth:O},void 0,!1,void 0,this)},`pending-${D}`,!1,void 0,this))]},void 0,!0,void 0,this)},void 0,!1,void 0,this)});N1();import{Box as q1,Text as l,useFocus as kJ,useFocusManager as yH,useInput as U9}from"ink";import vH from"ink-select-input";import EH from"ink-text-input";import{useEffect as PH,useState as u6}from"react";import{jsxDEV as P,Fragment as K9}from"react/jsx-dev-runtime";var TH=({isSelected:$})=>P(q1,{marginRight:1,children:P(l,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),kH=({isSelected:$,label:Y})=>P(l,{bold:$,color:$?"yellow":void 0,children:Y},void 0,!1,void 0,this);function SH($){switch($){case"openai-compatible":return"⚡ OpenAI Compatible";case"gpt-openai-platform":return"\uD83D\uDD37 GPT OpenAI Platform";case"anthropic":return"\uD83E\uDD16 Anthropic";default:return $}}var CH=({onSelect:$,onCancel:Y,initialProvider:Z})=>{let{isFocused:X}=kJ({id:"provider-step"});U9((q,G)=>{if(G.escape)Y()},{isActive:X});let Q=[{label:"⚡ OpenAI Compatible - 兼容 OpenAI API 的服务 (千问/豆包/DeepSeek等)",value:"openai-compatible"},{label:"\uD83D\uDD37 GPT OpenAI Platform - 字节跳动 GPT 平台 (内部)",value:"gpt-openai-platform"},{label:"\uD83E\uDD16 Anthropic Claude API - Claude 官方 API",value:"anthropic"}],J=Z?Math.max(0,Q.findIndex((q)=>q.value===Z)):0;return P(q1,{flexDirection:"column",marginBottom:1,children:[P(q1,{marginBottom:1,children:P(l,{bold:!0,color:"blue",children:"\uD83D\uDCE1 Step 2: 选择 API 提供商"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q1,{marginBottom:1,children:P(l,{children:"根据您使用的 LLM 服务选择对应的 API 类型"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q1,{marginBottom:1,children:P(vH,{items:Q,onSelect:(q)=>$(q.value),indicatorComponent:TH,itemComponent:kH,initialIndex:J},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},G9=({stepNumber:$,icon:Y,title:Z,description:X,hint:Q,examples:J,value:q,placeholder:G,mask:K,previousValue:W,onChange:O,onSubmit:U,onCancel:F})=>{return U9((H,_)=>{if(_.escape)F()},{isActive:!0}),P(q1,{flexDirection:"column",marginBottom:1,children:[P(q1,{marginBottom:1,children:P(l,{bold:!0,color:"blue",children:[Y," Step ",$,": ",Z]},void 0,!0,void 0,this)},void 0,!1,void 0,this),P(q1,{marginBottom:1,children:P(l,{children:X},void 0,!1,void 0,this)},void 0,!1,void 0,this),W&&P(q1,{marginBottom:1,children:P(l,{color:"green",children:["✓ ",W]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q&&P(q1,{marginBottom:1,children:P(l,{dimColor:!0,children:Q},void 0,!1,void 0,this)},void 0,!1,void 0,this),J&&J.length>0&&P(K9,{children:[P(q1,{marginBottom:1,children:P(l,{dimColor:!0,children:"常见示例:"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q1,{marginBottom:1,paddingLeft:2,children:P(l,{dimColor:!0,children:J.join(`
1888
- `)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(q1,{children:[P(l,{bold:!0,color:"cyan",children:["▶"," "]},void 0,!0,void 0,this),P(EH,{value:q,onChange:O,onSubmit:U,placeholder:G,mask:K},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},fH=({mode:$,config:Y,isSaving:Z,onConfirm:X,onBack:Q,onCancel:J})=>{let{isFocused:q}=kJ({id:"confirm-step"});return U9((G,K)=>{if(Z)return;if(G==="y"||G==="Y")X();else if(G==="n"||G==="N")Q();else if(K.escape)J()},{isActive:q&&!Z}),P(q1,{flexDirection:"column",marginBottom:1,children:[P(q1,{marginBottom:1,children:P(l,{bold:!0,color:$==="edit"?"yellow":"blue",children:$==="edit"?"\uD83D\uDCBE 确认修改":"✅ Step 6: 确认配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q1,{marginBottom:1,children:P(l,{children:$==="edit"?"请确认修改内容,保存后将立即生效。":"请确认以下配置信息:"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q1,{flexDirection:"column",marginBottom:1,paddingLeft:2,children:[P(q1,{marginBottom:1,children:[P(l,{dimColor:!0,children:"名称: "},void 0,!1,void 0,this),P(l,{bold:!0,color:"cyan",children:Y.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(q1,{marginBottom:1,children:[P(l,{dimColor:!0,children:"Provider: "},void 0,!1,void 0,this),P(l,{bold:!0,color:"cyan",children:SH(Y.provider)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(q1,{marginBottom:1,children:[P(l,{dimColor:!0,children:"Base URL: "},void 0,!1,void 0,this),P(l,{bold:!0,color:"blue",children:Y.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(q1,{marginBottom:1,children:[P(l,{dimColor:!0,children:"API Key: "},void 0,!1,void 0,this),P(l,{bold:!0,color:"yellow",children:[Y.apiKey?.slice(0,8),"*".repeat(Math.min(32,(Y.apiKey?.length||0)-8))]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),P(q1,{children:[P(l,{dimColor:!0,children:"Model: "},void 0,!1,void 0,this),P(l,{bold:!0,color:"cyan",children:Y.model},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),!Z&&P(q1,{marginTop:1,children:P(l,{children:[$==="edit"?"保存修改? ":"确认保存配置? ","[",P(l,{bold:!0,color:"green",children:"Y"},void 0,!1,void 0,this),"/",P(l,{bold:!0,color:"red",children:"n"},void 0,!1,void 0,this),"]"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Z&&P(q1,{children:P(l,{color:"yellow",children:"⏳ 正在保存配置到 ~/.blade/config.json..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},A3=({mode:$,initialConfig:Y,modelId:Z,onComplete:X,onCancel:Q})=>{let J=$==="edit",[q,G]=u6("name"),[K,W]=u6(()=>J&&Y?{...Y}:{}),[O,U]=u6(J&&Y?Y.name:""),[F,H]=u6(!1),[_,z]=u6(null),L=p1(!1);U9((j,C)=>{if(C.ctrl&&j==="c"||C.meta&&j==="c")if($==="setup")L();else Q()},{isActive:!0});let{focus:B}=yH();PH(()=>{if(q==="provider")B("provider-step");else if(q==="confirm")B("confirm-step")},[q,B]);let N=()=>{if(!O.trim()){z("配置名称不能为空");return}W({...K,name:O}),U(""),z(null),G("provider")},I=(j)=>{W({...K,provider:j});let C=J?K.baseUrl??Y?.baseUrl??"":"";U(C),G("baseUrl")},M=()=>{if(!O.trim()){z("Base URL 不能为空");return}try{new URL(O)}catch{z("请输入有效的 URL (例如: https://api.openai.com/v1)");return}W({...K,baseUrl:O});let j=J?K.apiKey??Y?.apiKey??"":"";U(j),z(null),G("apiKey")},A=()=>{if(!O.trim()){z("API Key 不能为空");return}W({...K,apiKey:O});let j=J?K.model??Y?.model??"":"";U(j),z(null),G("model")},D=()=>{if(!O.trim()){z("Model 不能为空");return}W({...K,model:O}),U(""),z(null),G("confirm")},w=async()=>{H(!0),z(null);try{let j={name:K.name,provider:K.provider,baseUrl:K.baseUrl,apiKey:K.apiKey,model:K.model};if($==="setup")X(j);else if($==="add"){let C=await A1().addModel(j);await A1().setCurrentModel(C.id),X(j)}else{if(!Z)throw Error("未提供模型 ID,无法编辑");await A1().updateModel(Z,j),X(j)}}catch(j){z(j instanceof Error?j.message:"配置失败"),H(!1)}},R=()=>{switch(z(null),U(""),q){case"provider":U(K.name||""),G("name");break;case"baseUrl":G("provider");break;case"apiKey":U(K.baseUrl||""),G("baseUrl");break;case"model":G("apiKey");break;case"confirm":U(K.model||""),G("model");break}},E=q==="name"?1:q==="provider"?2:q==="baseUrl"?3:q==="apiKey"?4:q==="model"?5:6,x=Math.floor((E-1)/5*40);return P(q1,{...$==="setup"?{flexDirection:"column",padding:1}:$==="add"?{flexDirection:"column",borderStyle:"round",borderColor:"blue",padding:1}:{flexDirection:"column",borderStyle:"round",borderColor:"yellow",padding:1},children:[$==="setup"?P(K9,{children:[P(q1,{marginBottom:1,children:P(l,{bold:!0,color:"blue",children:"\uD83D\uDE80 欢迎使用 Blade Code"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q1,{marginBottom:1,children:P(l,{children:"AI 驱动的代码助手 - 让我们开始配置您的助手"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q1,{marginBottom:1,children:[P(l,{bold:!0,color:"blue",children:"█".repeat(x)},void 0,!1,void 0,this),P(l,{dimColor:!0,children:"░".repeat(40-x)},void 0,!1,void 0,this),P(l,{children:" "},void 0,!1,void 0,this),P(l,{bold:!0,color:"cyan",children:[E,"/6"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),P(q1,{marginBottom:1,children:P(l,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this):$==="add"?P(K9,{children:[P(q1,{justifyContent:"center",marginBottom:1,children:P(l,{bold:!0,color:"blue",children:"添加新模型配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q1,{marginBottom:1,children:P(l,{children:["步骤: ",E,"/6"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this):P(K9,{children:[P(q1,{justifyContent:"center",marginBottom:1,children:P(l,{bold:!0,color:"yellow",children:"编辑模型配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q1,{marginBottom:1,children:P(l,{children:["步骤: ",E,"/6"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),q==="name"&&P(G9,{stepNumber:1,icon:"\uD83D\uDCDD",title:"配置名称",description:"给这个模型配置起一个易于识别的名称",value:O,placeholder:"例如: 千问工作账号",onChange:U,onSubmit:N,onCancel:Q},void 0,!1,void 0,this),q==="provider"&&P(CH,{onSelect:I,onCancel:Q,initialProvider:K.provider},void 0,!1,void 0,this),q==="baseUrl"&&P(G9,{stepNumber:3,icon:"\uD83C\uDF10",title:"配置 Base URL",description:"输入您的 API 端点地址(完整的 URL 包含协议)",examples:["• OpenAI: https://api.openai.com/v1","• 千问: https://dashscope.aliyuncs.com/compatible-mode/v1","• 豆包: https://ark.cn-beijing.volces.com/api/v3","• DeepSeek: https://api.deepseek.com/v1"],value:O,placeholder:"https://api.example.com/v1",onChange:U,onSubmit:M,onCancel:Q},void 0,!1,void 0,this),q==="apiKey"&&P(G9,{stepNumber:4,icon:"\uD83D\uDD11",title:"输入 API Key",description:"您的 API 密钥将被安全存储在 ~/.blade/config.json (权限 600)",hint:"\uD83D\uDCA1 提示: 输入时字符会被隐藏,支持粘贴 (Ctrl+V / Cmd+V)",previousValue:K.baseUrl?`✓ 当前 Base URL: ${K.baseUrl}`:void 0,value:O,placeholder:"sk-...",mask:"*",onChange:U,onSubmit:A,onCancel:Q},void 0,!1,void 0,this),q==="model"&&P(G9,{stepNumber:5,icon:"\uD83E\uDD16",title:"选择模型",description:"输入您想使用的模型名称(请参考您的 API 提供商文档)",examples:["• OpenAI: gpt-5, gpt-5-mini, gpt-5-nano","• Claude: claude-sonnet-4.5, claude-opus-4.1","• 千问: qwen3-max, qwen3-235b, qwen3-32b","• DeepSeek: deepseek-v3.1, deepseek-r1-0528","• 豆包: doubao-seed-1.6, doubao-seed-1.6-flash"],value:O,placeholder:"例如: gpt-5",onChange:U,onSubmit:D,onCancel:Q},void 0,!1,void 0,this),q==="confirm"&&P(fH,{mode:$,config:K,isSaving:F,onConfirm:w,onBack:R,onCancel:Q},void 0,!1,void 0,this),_&&P(q1,{marginTop:1,borderStyle:"round",borderColor:"red",paddingX:1,children:P(l,{color:"red",children:["❌ ",_]},void 0,!0,void 0,this)},void 0,!1,void 0,this),P(q1,{marginTop:1,children:P(l,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this),!F&&q==="provider"&&P(q1,{marginTop:1,children:P(l,{dimColor:!0,children:["\uD83D\uDCA1 使用 ",P(l,{bold:!0,children:"↑/↓"},void 0,!1,void 0,this)," 键选择,",P(l,{bold:!0,children:"Enter"},void 0,!1,void 0,this)," 确认,",P(l,{bold:!0,children:"Esc"},void 0,!1,void 0,this)," 取消"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),!F&&q!=="confirm"&&q!=="provider"&&P(q1,{marginTop:1,children:P(l,{dimColor:!0,children:["\uD83D\uDCA1 输入完成后按 ",P(l,{bold:!0,children:"Enter"},void 0,!1,void 0,this),",",P(l,{bold:!0,children:"Ctrl+C"},void 0,!1,void 0,this)," 退出"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),!F&&q==="confirm"&&P(q1,{marginTop:1,children:P(l,{dimColor:!0,children:["\uD83D\uDCA1 按"," ",P(l,{bold:!0,color:"green",children:"Y"},void 0,!1,void 0,this)," ","保存,",P(l,{bold:!0,color:"red",children:"N"},void 0,!1,void 0,this)," ","返回修改,",P(l,{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{useMemoizedFn as W9,useMount as hH}from"ahooks";import{Box as P0,Text as z1,useFocus as xH,useFocusManager as pH,useInput as gH}from"ink";import uH from"ink-select-input";import{memo as mH,useMemo as dH,useState as O9}from"react";N1();import{jsxDEV as Q1}from"react/jsx-dev-runtime";var cH=({isSelected:$})=>Q1(P0,{marginRight:1,children:Q1(z1,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),lH=({isSelected:$,label:Y})=>Q1(z1,{bold:$,color:$?"yellow":void 0,children:Y},void 0,!1,void 0,this),SJ=mH(({onClose:$,onEdit:Y})=>{let Z=GQ(),X=KQ()??"",{isFocused:Q}=xH({id:"model-selector"}),J=pH(),[q,G]=O9(""),[K,W]=O9(!1),[O,U]=O9(null),F=p1(!1),[H]=O9(()=>{let D=process.stdout?.columns||80;return Math.max(20,D-8)});hH(()=>{if(J?.focus("model-selector"),Z.length>0)G(Z[0].id)}),gH((D,w)=>{if(K)return;if(w.ctrl&&D==="c"||w.meta&&D==="c"){F();return}if(w.escape){$();return}if(!Q)return;if(D==="d"||D==="D"){z();return}if((D==="e"||D==="E")&&Y)L()},{isActive:!0});let _=W9(async(D)=>{if(K)return;let w=D.value;if(w===X){$();return}W(!0),U(null);try{await A1().setCurrentModel(w),$()}catch(R){U(R.message),W(!1)}}),z=W9(async()=>{if(K||q===X)return;W(!0),U(null);try{if(await A1().removeModel(q),Z.length<=1)$()}catch(D){U(D.message)}finally{W(!1)}}),L=W9(()=>{if(K||!Y)return;let D=Z.find((w)=>w.id===q);if(!D)return;Y(D)}),B=W9((D)=>{G(D.value)}),N=dH(()=>{return Z.find((D)=>D.id===q)},[Z,q]),I=Z.map((D)=>({label:D.name+(D.id===X?" (当前)":""),value:D.id})),M=q===X;return Q1(P0,{flexDirection:"column",borderStyle:"round",borderColor:"gray",padding:1,width:"100%",children:[Q1(P0,{flexDirection:"row",justifyContent:"space-between",marginBottom:1,children:[Q1(z1,{bold:!0,color:"cyan",children:"模型管理"},void 0,!1,void 0,this),Q1(z1,{dimColor:!0,children:[K?"⏳ 处理中...":M?"Enter=关闭 • E=编辑 • Esc=取消":"Enter=切换 • D=删除 • E=编辑 • Esc=取消"," • Ctrl+C=退出"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q1(P0,{flexDirection:"row",children:[Q1(P0,{flexDirection:"column",flexGrow:2,marginRight:2,borderStyle:"single",borderColor:"gray",padding:1,children:[Q1(z1,{dimColor:!0,children:["已配置模型 (",Z.length,")"]},void 0,!0,void 0,this),Q1(P0,{marginTop:1,children:Q1(uH,{items:I,onSelect:_,onHighlight:B,indicatorComponent:cH,itemComponent:lH},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1(P0,{flexDirection:"column",flexGrow:3,borderStyle:"single",borderColor:"gray",padding:1,children:[Q1(z1,{dimColor:!0,children:"模型详情"},void 0,!1,void 0,this),Q1(P0,{marginY:1,children:Q1(z1,{color:M?"green":"yellow",children:M?"● 当前使用":"● 可切换"},void 0,!1,void 0,this)},void 0,!1,void 0,this),N?Q1(P0,{flexDirection:"column",children:[Q1(z1,{children:[Q1(z1,{dimColor:!0,children:"名称: "},void 0,!1,void 0,this),Q1(z1,{bold:!0,color:"cyan",children:N.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1(z1,{children:[Q1(z1,{dimColor:!0,children:"Provider: "},void 0,!1,void 0,this),Q1(z1,{bold:!0,children:N.provider},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1(z1,{children:[Q1(z1,{dimColor:!0,children:"Model: "},void 0,!1,void 0,this),Q1(z1,{bold:!0,children:N.model},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1(z1,{children:[Q1(z1,{dimColor:!0,children:"Base URL: "},void 0,!1,void 0,this),Q1(z1,{color:"blueBright",children:N.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),N.temperature!==void 0&&Q1(z1,{children:[Q1(z1,{dimColor:!0,children:"Temperature: "},void 0,!1,void 0,this),Q1(z1,{children:N.temperature},void 0,!1,void 0,this)]},void 0,!0,void 0,this),N.maxContextTokens!==void 0&&Q1(z1,{children:[Q1(z1,{dimColor:!0,children:"Context Window: "},void 0,!1,void 0,this),Q1(z1,{children:N.maxContextTokens},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this):Q1(z1,{dimColor:!0,children:"请选择一个模型查看详情"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),O&&Q1(P0,{marginTop:1,children:Q1(z1,{color:"red",children:["❌ ",O]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q1(P0,{justifyContent:"center",marginTop:1,children:Q1(z1,{dimColor:!0,children:"─".repeat(H)},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q1(P0,{justifyContent:"center",children:Q1(z1,{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 m6}from"ahooks";import{promises as xJ}from"fs";import{Box as L0,Text as I1,useInput as iH}from"ink";import CJ from"ink-select-input";import aH from"ink-text-input";import rH from"os";import F9 from"path";import{useEffect as nH,useMemo as H9,useRef as oH,useState as u2}from"react";N1();import{jsxDEV as J1}from"react/jsx-dev-runtime";var d6=[{key:"allow",label:"Allow"},{key:"ask",label:"Ask"},{key:"deny",label:"Deny"},{key:"info",label:"Info"}],sH={allow:"Add a new rule...",ask:"Add a new rule...",deny:"Add a new rule..."},tH={allow:"Allow permission rules",ask:"Ask permission rules",deny:"Deny permission rules"},fJ={project:"[项目共享配置]",global:"[用户全局配置]",local:"[本地配置]"},eH=["project","global","local"],$_={allow:[],ask:[],deny:[]},Y_={localExists:!1,projectExists:!1,globalExists:!1},hJ={allow:[],ask:[],deny:[]};function Z_($){let Y=(X)=>Array.isArray(X)?X.filter((Q)=>typeof Q==="string"):[],Z=$?.permissions??{};return{allow:Y(Z?.allow),ask:Y(Z?.ask),deny:Y(Z?.deny)}}async function X_($){try{let Y=await xJ.readFile($,"utf-8"),Z=JSON.parse(Y);return{exists:!0,raw:Z,permissions:Z_(Z)}}catch(Y){if(Y.code==="ENOENT")return{exists:!1,raw:{},permissions:{...hJ}};return console.warn(`[PermissionsManager] Failed to read ${$}:`,Y),{exists:!0,raw:{},permissions:{...hJ}}}}function Q_($,Y){let Z=$.padEnd(32," "),X=Y==="local"?`${fJ[Y]} ← 可删除`:fJ[Y];return`${Z} ${X}`}var pJ=({onClose:$})=>{let Z=V0()==="permissions-manager",X=p1(!1),[Q,J]=u2(0),q=d6[Q].key,[G,K]=u2($_),[W,O]=u2(Y_),[U,F]=u2(!0),[H,_]=u2("list"),[z,L]=u2(""),[B,N]=u2(null),[I,M]=u2(null),A=oH(!1),D=H9(()=>F9.join(process.cwd(),".blade","settings.local.json"),[]),w=H9(()=>F9.join(process.cwd(),".blade","settings.json"),[]),R=H9(()=>F9.join(rH.homedir(),".blade","settings.json"),[]),E=m6(async()=>{F(!0);let g=[{source:"local",path:D},{source:"project",path:w},{source:"global",path:R}],K1=await Promise.all(g.map(async({source:d1,path:W2})=>{let T0=await X_(W2);return{source:d1,path:W2,...T0}})),s={localExists:K1.find((d1)=>d1.source==="local")?.exists??!1,projectExists:K1.find((d1)=>d1.source==="project")?.exists??!1,globalExists:K1.find((d1)=>d1.source==="global")?.exists??!1};O(s);let J0={allow:[],ask:[],deny:[]},d2=Object.fromEntries(K1.map((d1)=>[d1.source,d1]));["allow","ask","deny"].forEach((d1)=>{eH.forEach((W2)=>{(d2[W2]?.permissions[d1]??[]).forEach(($6,a0)=>{let c2={key:`${W2}:${a0}:${$6}`,rule:$6,source:W2};J0[d1].push(c2)})})}),K(J0),F(!1)});nH(()=>{E()},[E]);let x=m6(async(g,K1)=>{try{let s=F9.join(process.cwd(),".blade","settings.local.json"),J0={allow:[],ask:[],deny:[]};try{let d1=await xJ.readFile(s,"utf-8"),T0=JSON.parse(d1).permissions||{};J0={allow:Array.isArray(T0.allow)?T0.allow:[],ask:Array.isArray(T0.ask)?T0.ask:[],deny:Array.isArray(T0.deny)?T0.deny:[]}}catch(d1){}let d2=K1(J0);await A1().updateConfig({permissions:d2},{scope:"local",immediate:!0}),await E()}catch(s){throw console.error("[PermissionsManager] 修改权限规则失败:",s),s}});iH((g,K1)=>{if(K1.ctrl&&g==="c"||K1.meta&&g==="c"){X();return}if(H==="locked"){if(A.current){A.current=!1;return}_("list"),N(null),M(null);return}if(K1.escape){if(H==="list"||q==="info")$();else _("list"),L(""),N(null),M(null);return}if(H==="list"){if(K1.tab&&K1.shift)J((s)=>(s-1+d6.length)%d6.length);else if(K1.tab)J((s)=>(s+1)%d6.length);else if(g?.toLowerCase()==="q")$()}},{isActive:Z});let r=m6((g)=>{let K1=g.value;if(q==="info")return;if(K1.type==="add"){_("add"),L(""),M(null);return}if(K1.entry.source!=="local"){_("locked"),A.current=!0,N({tab:q,entry:K1.entry}),M({type:"error",text:K1.entry.source==="project"?"此规则定义在项目共享配置中,无法在此删除。":"此规则来自用户全局配置,无法在此删除。"});return}_("confirm-delete"),N({tab:q,entry:K1.entry}),M(null)}),j=m6(async()=>{if(q==="info")return;let g=z.trim();if(!g){M({type:"error",text:"Permission rule 不能为空"});return}if(G[q].map((s)=>s.rule).includes(g)){M({type:"error",text:"该规则已存在"});return}try{await x(q,(s)=>{let J0={allow:[...s.allow],ask:[...s.ask],deny:[...s.deny]};return J0[q]=[...new Set([...s[q],g])],J0}),_("list"),L(""),M({type:"success",text:"已添加本地权限规则"})}catch(s){M({type:"error",text:`保存失败: ${s instanceof Error?s.message:"未知错误"}`})}}),C=m6(async()=>{if(!B)return;let{tab:g,entry:K1}=B;try{await x(g,(s)=>{let J0={allow:[...s.allow],ask:[...s.ask],deny:[...s.deny]};return J0[g]=s[g].filter((d2)=>d2!==K1.rule),J0}),_("list"),N(null),M({type:"success",text:"已删除本地权限规则"})}catch(s){M({type:"error",text:`删除失败: ${s instanceof Error?s.message:"未知错误"}`})}}),Y1=H9(()=>{if(q==="info")return[];let g=q;return[{key:"add-new-rule",label:`› ${sH[g]}`,value:{type:"add"}},...G[g].map((s)=>({key:s.key,label:Q_(s.rule,s.source),value:{type:"rule",entry:s}}))]},[q,G]),k=()=>J1(L0,{marginBottom:1,children:d6.map((g,K1)=>J1(L0,{marginRight:2,children:J1(I1,{color:K1===Q?"yellow":"gray",children:["[",g.label,"]"]},void 0,!0,void 0,this)},g.key,!1,void 0,this))},void 0,!1,void 0,this),S=()=>J1(L0,{flexDirection:"column",gap:1,children:[J1(I1,{children:"配置文件优先级(从高到低):"},void 0,!1,void 0,this),J1(L0,{flexDirection:"column",marginLeft:2,children:[J1(I1,{children:["1. .blade/settings.local.json (本地配置,不提交 Git)"," ",W.localExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),J1(I1,{children:["2. .blade/settings.json (项目配置,提交 Git)"," ",W.projectExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),J1(I1,{children:["3. ~/.blade/settings.json (用户全局配置)"," ",W.globalExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),J1(I1,{children:"说明:"},void 0,!1,void 0,this),J1(L0,{flexDirection:"column",marginLeft:2,children:[J1(I1,{children:"- /permissions 命令只管理本地配置 (.blade/settings.local.json)"},void 0,!1,void 0,this),J1(I1,{children:"- 修改全局或项目配置请直接编辑对应文件"},void 0,!1,void 0,this),J1(I1,{children:"- 本地配置不会提交到 Git"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),y=(g)=>J1(L0,{flexDirection:"column",gap:1,children:[J1(I1,{bold:!0,children:tH[g]},void 0,!1,void 0,this),J1(I1,{children:"Permission rules are a tool name, optionally followed by a specifier in parentheses."},void 0,!1,void 0,this),J1(I1,{color:"gray",children:"例如: WebFetch 或 Bash(ls:*)"},void 0,!1,void 0,this),J1(L0,{marginTop:1,children:J1(aH,{value:z,onChange:L,onSubmit:j},void 0,!1,void 0,this)},void 0,!1,void 0,this),J1(I1,{color:"gray",children:"Enter 提交 · Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v1=(g,K1)=>J1(L0,{flexDirection:"column",gap:1,children:[J1(I1,{bold:!0,children:["Delete ",g," permission rule?"]},void 0,!0,void 0,this),J1(I1,{children:K1.rule},void 0,!1,void 0,this),J1(I1,{color:"gray",children:"From project local settings"},void 0,!1,void 0,this),J1(I1,{children:"Are you sure you want to delete this permission rule?"},void 0,!1,void 0,this),J1(CJ,{items:[{label:"Yes",value:"yes"},{label:"No",value:"no"}],onSelect:(s)=>{if(s.value==="yes")C();else _("list"),N(null)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m=(g)=>J1(L0,{flexDirection:"column",gap:1,children:[J1(I1,{bold:!0,children:"Cannot delete this rule"},void 0,!1,void 0,this),J1(I1,{children:g.rule},void 0,!1,void 0,this),J1(I1,{color:"gray",children:g.source==="project"?"This rule is defined in .blade/settings.json. 请手动编辑该文件以移除规则。":"This rule is defined in ~/.blade/settings.json. 请手动编辑该文件以移除规则。"},void 0,!1,void 0,this),J1(I1,{color:"gray",children:"按任意键继续"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),t=(g)=>J1(CJ,{items:Y1,isFocused:H==="list",onSelect:r},void 0,!1,void 0,this),_1=()=>{if(U)return J1(I1,{children:"加载中..."},void 0,!1,void 0,this);if(q==="info")return S();if(H==="add")return y(q);if(H==="confirm-delete"&&B)return v1(B.tab,B.entry);if(H==="locked"&&B)return m(B.entry);return t(q)};return J1(L0,{flexDirection:"column",borderStyle:"round",borderColor:Z?"cyan":"gray",padding:1,width:80,children:[J1(I1,{color:"cyan",bold:!0,children:"⚙️ 权限管理器"},void 0,!1,void 0,this),k(),J1(L0,{flexDirection:"column",gap:1,children:_1()},void 0,!1,void 0,this),I&&J1(L0,{marginTop:1,children:J1(I1,{color:I.type==="success"?"green":"red",children:I.text},void 0,!1,void 0,this)},void 0,!1,void 0,this),J1(L0,{marginTop:1,children:J1(I1,{color:"gray",children:"Tab 切换视图 · Esc 关闭 · Q 退出"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};f4();import{Box as e$,Text as i0,useInput as J_}from"ink";import q_ from"ink-select-input";import{useEffect as gJ,useMemo as _9,useState as b3}from"react";import{jsxDEV as a1}from"react/jsx-dev-runtime";function G_($){let Y=new Date($),X=new Date().getTime()-Y.getTime(),Q=Math.floor(X/86400000);if(Q===0)return`今天 ${Y.getHours().toString().padStart(2,"0")}:${Y.getMinutes().toString().padStart(2,"0")}`;if(Q===1)return"昨天";if(Q<7)return`${Q}天前`;return`${Y.getMonth()+1}/${Y.getDate()}`}function K_($){let Y=$.split("/");return Y[Y.length-1]||$}var U_=({isSelected:$})=>a1(e$,{marginRight:1,children:a1(i0,{color:$?"cyan":"gray",children:$?"❯":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),W_=({isSelected:$,label:Y})=>a1(i0,{color:$?"cyan":"white",bold:$,children:Y},void 0,!1,void 0,this),c6=20,uJ=({sessions:$,onSelect:Y,onCancel:Z})=>{let[X,Q]=b3([]),[J,q]=b3(!1),[G,K]=b3(0),O=V0()==="session-selector",U=p1(!1);J_((N,I)=>{if(I.ctrl&&N==="c"||I.meta&&N==="c"){U();return}if(I.escape&&Z){Z();return}if(I.leftArrow||N==="h"||N==="H"){if(G>0)K((M)=>M-1);return}if(I.rightArrow||N==="l"||N==="L"){if(G<_-1)K((M)=>M+1);return}},{isActive:O}),gJ(()=>{if($){Q($);return}(async()=>{q(!0);try{let I=await X2.listSessions();Q(I)}catch(I){console.error("[SessionSelector] Failed to load sessions:",I),Q([])}finally{q(!1)}})()},[$]);let F=$||X,H=_9(()=>{return F.map((N)=>{let I=K_(N.projectPath),M=G_(N.lastMessageTime),A=N.gitBranch?` (${N.gitBranch})`:"",D=N.hasErrors?" ⚠️":"";return{label:`\uD83D\uDCC5 ${M} | ${I}${A} | ${N.messageCount} 条消息${D}`,value:N.sessionId}})},[F]),_=_9(()=>Math.max(1,Math.ceil(H.length/c6)),[H.length]),z=_9(()=>{let N=G*c6;return H.slice(N,N+c6)},[H,G]),L=_9(()=>({start:G*c6+1,end:Math.min((G+1)*c6,H.length)}),[G,H.length]);gJ(()=>{K(0)},[F.length]);let B=(N)=>{Y(N.value)};if(J)return a1(e$,{flexDirection:"column",paddingX:2,paddingY:1,children:a1(i0,{children:"⏳ 正在加载会话列表..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(F.length===0)return a1(e$,{flexDirection:"column",paddingX:2,paddingY:1,children:[a1(i0,{color:"yellow",children:"⚠️ 没有找到历史会话"},void 0,!1,void 0,this),a1(i0,{dimColor:!0,children:[`
1889
- `,"提示: 开始一次对话后,会话历史将保存到 ~/.blade/projects/"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this);return a1(e$,{flexDirection:"column",paddingX:2,paddingY:1,children:[a1(i0,{bold:!0,color:"cyan",children:"\uD83D\uDCC2 选择要恢复的会话:"},void 0,!1,void 0,this),a1(i0,{dimColor:!0,children:[`
1866
+ `),x=$3.join(w,`${J.name}.md`);await YJ.promises.writeFile(x,E,"utf-8"),$()}catch(w){console.error("保存配置失败:",w)}}),D=d1(!1,Y);if(XJ((w,R)=>{if(R.escape)I();else if(R.ctrl&&w==="c"||R.meta&&w==="c")D()},{isActive:X!=="tools"}),X==="mode")return y(s,{flexDirection:"column",paddingY:1,children:[y(s,{marginBottom:1,children:y(m,{bold:!0,color:"cyan",children:"\uD83C\uDFAF 选择创建方式"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y(s,{marginBottom:1,children:y(m,{dimColor:!0,children:"你可以手动配置每个细节,或让 AI 根据你的描述自动生成配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y(Y8,{items:[{label:"\uD83E\uDD16 AI 智能生成 - 根据描述自动生成完整配置",value:"ai"},{label:"✍️ 手动配置 - 逐步配置每个选项",value:"manual"}],onSelect:(w)=>{if(w.value==="ai")z("ai"),Q("aiPrompt");else z("manual"),Q("name")}},void 0,!1,void 0,this),y(s,{marginTop:1,children:y(m,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 取消"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(X==="aiPrompt")return y(s,{flexDirection:"column",paddingY:1,children:[y(s,{marginBottom:1,children:y(m,{bold:!0,color:"cyan",children:"\uD83E\uDD16 AI 智能生成"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y(s,{marginBottom:1,children:y(m,{dimColor:!0,children:'描述你想要创建的 Agent(例如:"一个专门用于代码审查的 agent,能够分析代码质量和潜在bug")'},void 0,!1,void 0,this)},void 0,!1,void 0,this),y(s,{marginBottom:1,children:[y(m,{color:"green",children:"描述: "},void 0,!1,void 0,this),y(k6,{value:K,onChange:G,onSubmit:(w)=>{if(!w.trim())return;Q("aiGenerating")}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),y(s,{children:y(m,{dimColor:!0,children:"按 Enter 开始生成 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(X==="aiGenerating"){if(W)return y(s,{flexDirection:"column",paddingY:1,children:[y(s,{marginBottom:1,children:y(m,{bold:!0,color:"red",children:"❌ AI 生成失败"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y(s,{marginBottom:1,children:y(m,{color:"red",children:W},void 0,!1,void 0,this)},void 0,!1,void 0,this),y(s,{marginBottom:1,children:y(m,{dimColor:!0,children:"按 ESC 返回修改描述"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return y(s,{flexDirection:"column",paddingY:1,children:[y(s,{marginBottom:1,children:y(m,{bold:!0,color:"yellow",children:[y(IF,{type:"dots"},void 0,!1,void 0,this)," AI 正在生成配置..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this),y(s,{marginBottom:1,children:y(m,{dimColor:!0,children:['根据你的描述:"',K,'"']},void 0,!0,void 0,this)},void 0,!1,void 0,this),y(s,{marginBottom:1,children:y(m,{color:"gray",children:"正在调用 LLM 生成 agent 配置,请稍候..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}if(X==="name"){let w=H==="edit";return y(s,{flexDirection:"column",paddingY:1,children:[y(s,{marginBottom:1,children:y(m,{bold:!0,color:"cyan",children:["\uD83D\uDCDD Step 1/7: ",w?"Agent 名称(不可修改)":"输入 Agent 名称"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),y(s,{marginBottom:1,children:y(m,{dimColor:!0,children:w?"编辑模式下名称不可修改(修改名称相当于创建新 Agent)":"名称只能包含小写字母、数字和连字符(例如:code-reviewer)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y(s,{marginBottom:1,children:[y(m,{color:"green",children:"名称: "},void 0,!1,void 0,this),w?y(m,{children:J.name},void 0,!1,void 0,this):y(k6,{value:J.name,onChange:(R)=>q({...J,name:R}),onSubmit:(R)=>{if(EF(R))return;_()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),y(s,{children:y(m,{dimColor:!0,children:w?"按 Enter 继续 | ESC 返回":"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this),w&&y(k6,{value:"",onChange:()=>{},onSubmit:_,showCursor:!1},"edit-mode-dummy-input",!1,void 0,this)]},void 0,!0,void 0,this)}if(X==="description")return y(s,{flexDirection:"column",paddingY:1,children:[y(s,{marginBottom:1,children:y(m,{bold:!0,color:"cyan",children:"\uD83D\uDCDD Step 2/7: 输入描述信息"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y(s,{marginBottom:1,children:y(m,{dimColor:!0,children:"简短描述这个 Agent 的用途和使用场景(这将帮助主 Agent 决定何时使用它)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y(s,{marginBottom:1,children:[y(m,{color:"green",children:"描述: "},void 0,!1,void 0,this),y(k6,{value:J.description,onChange:(w)=>q({...J,description:w}),onSubmit:(w)=>{if(!w.trim())return;_()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),y(s,{children:y(m,{dimColor:!0,children:"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(X==="tools")return y(vF,{config:J,setConfig:q,onNext:_,onPrev:I},void 0,!1,void 0,this);if(X==="color")return y(s,{flexDirection:"column",paddingY:1,children:[y(s,{marginBottom:1,children:y(m,{bold:!0,color:"cyan",children:"\uD83C\uDFA8 Step 4/7: 选择背景颜色"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y(s,{marginBottom:1,children:y(m,{dimColor:!0,children:"为 Agent 选择一个颜色标识(用于在 UI 中区分不同的 Agents)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y(Y8,{items:yF,onSelect:(w)=>{let R=w.value==="none"?void 0:w.value;q({...J,color:R}),_()}},void 0,!1,void 0,this),y(s,{marginTop:1,children:y(m,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(X==="location")return y(s,{flexDirection:"column",paddingY:1,children:[y(s,{marginBottom:1,children:y(m,{bold:!0,color:"cyan",children:"\uD83D\uDCC2 Step 5/7: 选择保存位置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y(s,{marginBottom:1,children:y(m,{dimColor:!0,children:"项目级配置仅在当前项目生效,用户级配置全局可用"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y(Y8,{items:[{label:"\uD83D\uDCC1 项目级 (.blade/agents/) - 仅当前项目",value:"project"},{label:"\uD83C\uDFE0 用户级 (~/.blade/agents/) - 全局可用",value:"user"}],onSelect:(w)=>{q({...J,location:w.value}),_()}},void 0,!1,void 0,this),y(s,{marginTop:1,children:y(m,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(X==="systemPrompt")return y(s,{flexDirection:"column",paddingY:1,children:[y(s,{marginBottom:1,children:y(m,{bold:!0,color:"cyan",children:"\uD83D\uDCAC Step 6/7: 输入系统提示词"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y(s,{marginBottom:1,children:y(m,{dimColor:!0,children:"定义 Agent 的行为和职责(可选,留空将使用默认提示)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y(s,{marginBottom:1,children:[y(m,{color:"green",children:"提示词: "},void 0,!1,void 0,this),y(k6,{value:J.systemPrompt,onChange:(w)=>q({...J,systemPrompt:w}),onSubmit:()=>_()},void 0,!1,void 0,this)]},void 0,!0,void 0,this),y(s,{children:y(m,{dimColor:!0,children:"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(X==="confirm")return y(s,{flexDirection:"column",paddingY:1,children:[y(s,{marginBottom:1,children:y(m,{bold:!0,color:"cyan",children:"✅ Step 7/7: 确认配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y(s,{flexDirection:"column",paddingLeft:2,marginBottom:1,children:[y(m,{children:[y(m,{bold:!0,color:"green",children:["名称:"," "]},void 0,!0,void 0,this),y(m,{children:J.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),y(m,{children:[y(m,{bold:!0,color:"green",children:["描述:"," "]},void 0,!0,void 0,this),y(m,{children:J.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),y(m,{children:[y(m,{bold:!0,color:"green",children:["工具:"," "]},void 0,!0,void 0,this),y(m,{children:J.tools.includes("all")?"所有工具":J.tools.join(", ")||"所有工具"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),y(m,{children:[y(m,{bold:!0,color:"green",children:["颜色:"," "]},void 0,!0,void 0,this),y(m,{children:J.color||"默认"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),y(m,{children:[y(m,{bold:!0,color:"green",children:["位置:"," "]},void 0,!0,void 0,this),y(m,{children:J.location==="project"?"项目级":"用户级"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),y(m,{children:[y(m,{bold:!0,color:"green",children:["提示词:"," "]},void 0,!0,void 0,this),y(m,{children:J.systemPrompt||"(使用默认)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),y(Y8,{items:[{label:"✅ 确认并保存",value:"save"},{label:"⬅️ 返回上一步",value:"back"},{label:"❌ 取消",value:"cancel"}],onSelect:(w)=>{if(w.value==="save")A();else if(w.value==="back")I();else Y()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}function vF({config:$,setConfig:Y,onNext:Z,onPrev:X}){let{isFocused:Q}=VF({id:"step-tools"});XJ((q,K)=>{if(K.escape)X()},{isActive:Q});let J=(q)=>{if(q.includes("all"))Y({...$,tools:["all"]});else Y({...$,tools:q});Z()};return y(s,{flexDirection:"column",paddingY:1,children:[y(s,{marginBottom:1,children:y(m,{bold:!0,color:"cyan",children:"\uD83D\uDD27 Step 3/7: 选择可用工具"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y(s,{marginBottom:1,children:y(m,{dimColor:!0,children:"方向键导航,空格切换勾选,Enter 确认进入下一步 | ESC 返回上一步"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y(RF,{options:jF,defaultValue:$.tools,onSubmit:J},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}k$();import{useMemoizedFn as f6}from"ahooks";import{Box as b1,Text as T1,useInput as PF}from"ink";import Y3 from"ink-select-input";import TF from"node:fs";import{useMemo as SF,useState as Z3}from"react";import{jsxDEV as u}from"react/jsx-dev-runtime";function QJ({initialMode:$="menu",onComplete:Y,onCancel:Z}){let[X,Q]=Z3($),[J,q]=Z3(null),[K,G]=Z3(0),U=f6(()=>{g1.clear(),g1.loadFromStandardLocations(),G((_)=>_+1)}),O=SF(()=>{return g1.getAllSubagents()},[K]),W=[{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"}],F=f6((_)=>{if(_.value==="cancel"){Z?.();return}Q(_.value)}),H=f6((_)=>{if(q(_.value),X==="edit")Q("editWizard");else if(X==="delete")Q("deleteConfirm")}),z=f6(async()=>{if(!J?.configPath)return;try{await TF.promises.unlink(J.configPath),U(),N()}catch(_){console.error("删除失败:",_)}}),N=f6(()=>{Q("menu"),q(null)}),L=d1(!1,Z);if(PF((_,I)=>{if(I.escape){if(X==="menu")Z?.();else if(X==="list"||X==="edit"||X==="delete")N();else if(X==="deleteConfirm")N()}else if(I.ctrl&&_==="c"||I.meta&&_==="c")L()},{isActive:X!=="create"&&X!=="editWizard"}),X==="menu")return u(b1,{flexDirection:"column",paddingY:1,children:[u(b1,{marginBottom:1,children:u(T1,{bold:!0,color:"cyan",children:"\uD83D\uDCCB Agents 管理"},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(Y3,{items:W,onSelect:F},void 0,!1,void 0,this),u(b1,{marginTop:1,children:u(T1,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 退出"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(X==="list"){if(O.length===0)return u(b1,{flexDirection:"column",paddingY:1,children:[u(b1,{marginBottom:1,children:u(T1,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(b1,{paddingLeft:2,children:u(T1,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(b1,{marginTop:1,paddingLeft:2,children:u(T1,{color:"gray",children:"\uD83D\uDCA1 配置文件位置: .blade/agents/ 或 ~/.blade/agents/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(b1,{marginTop:1,paddingLeft:2,children:u(T1,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return u(b1,{flexDirection:"column",paddingY:1,children:[u(b1,{marginBottom:1,children:[u(T1,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this),u(T1,{color:"gray",children:[" (找到 ",O.length," 个)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),O.map((_)=>u(b1,{flexDirection:"column",paddingLeft:2,children:[u(b1,{children:u(T1,{children:[u(T1,{bold:!0,color:_.color||"white",children:["• ",_.name]},void 0,!0,void 0,this),u(T1,{color:"gray",children:[" - ",_.description]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),_.tools&&_.tools.length>0&&u(b1,{paddingLeft:2,children:u(T1,{color:"gray",children:["工具: ",_.tools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),_.configPath&&u(b1,{paddingLeft:2,children:u(T1,{color:"gray",dimColor:!0,children:_.configPath},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},_.name,!0,void 0,this)),u(b1,{marginTop:1,paddingLeft:2,children:u(T1,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}let B=(_)=>{if(O.length===0)return u(b1,{flexDirection:"column",paddingY:1,children:[u(b1,{marginBottom:1,children:u(T1,{bold:!0,color:"cyan",children:_},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(b1,{paddingLeft:2,children:u(T1,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(b1,{marginTop:1,paddingLeft:2,children:u(T1,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);let I=O.map((M)=>({key:M.name,label:`${M.name} - ${M.description}`,value:M}));return u(b1,{flexDirection:"column",paddingY:1,children:[u(b1,{marginBottom:1,children:u(T1,{bold:!0,color:"cyan",children:_},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(Y3,{items:I,onSelect:H},void 0,!1,void 0,this),u(b1,{marginTop:1,children:u(T1,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};if(X==="create")return u(C6,{onComplete:()=>{U(),N()},onCancel:N},void 0,!1,void 0,this);if(X==="edit")return B("✏️ 编辑 Agent");if(X==="editWizard"&&J){let _={name:J.name,description:J.description,tools:J.tools||[],color:J.color,location:J.configPath?.includes(".blade/agents")?"project":"user",systemPrompt:J.systemPrompt||""};return u(C6,{initialConfig:_,onComplete:()=>{U(),N()},onCancel:N},void 0,!1,void 0,this)}if(X==="delete")return B("\uD83D\uDDD1️ 删除 Agent");if(X==="deleteConfirm"&&J)return u(b1,{flexDirection:"column",paddingY:1,children:[u(b1,{marginBottom:1,children:u(T1,{bold:!0,color:"red",children:"⚠️ 确认删除"},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(b1,{marginBottom:1,paddingLeft:2,children:u(T1,{children:["你确定要删除 Agent"," ",u(T1,{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),u(b1,{marginBottom:1,paddingLeft:2,children:u(T1,{dimColor:!0,children:["文件路径: ",J.configPath]},void 0,!0,void 0,this)},void 0,!1,void 0,this),u(b1,{marginBottom:1,paddingLeft:2,children:u(T1,{color:"red",children:"此操作无法撤销!"},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(Y3,{items:[{label:"\uD83D\uDDD1️ 确认删除",value:"confirm"},{label:"❌ 取消",value:"cancel"}],onSelect:(_)=>{if(_.value==="confirm")z();else N()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}$0();import{Box as n$,Text as M1}from"ink";import CF from"react";C4();c7();import{useEffect as kF,useState as JJ}from"react";function qJ($=process.cwd(),Y=5000){let[Z,X]=JJ(null),[Q,J]=JJ(!0);return kF(()=>{let q=!0,K=async()=>{try{let U=await M6($);if(!q)return;if(!U){X(null),J(!1);return}let O=await fX($);if(!q)return;X(O)}catch{if(q)X(null)}finally{if(q)J(!1)}};K();let G=null;if(Y>0)G=setInterval(K,Y);return()=>{if(q=!1,G)clearInterval(G)}},[$,Y]),{branch:Z,loading:Q}}import{jsxDEV as K1,Fragment as h6}from"react/jsx-dev-runtime";var KJ=CF.memo(()=>{let $=r4(),Y=G2(),Z=l$(),Q=i4()==="shortcuts",J=VQ(),{branch:q}=qJ(),K=a4(),G=_Q(),U=BQ(),O=vQ(),W=K?x$(K):!1,H=(()=>{if(Z==="default")return null;if(Z==="autoEdit")return K1(M1,{color:"magenta",children:["▶▶ auto edit on ",K1(M1,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="plan")return K1(M1,{color:"cyan",children:["‖ plan mode on ",K1(M1,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="yolo")return K1(M1,{color:"red",children:["⚡ yolo mode on ",K1(M1,{color:"gray",children:"(all tools auto-approved)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null})(),z=H!==null,N=[["Enter:发送","Shift+Enter:换行","Esc:中止"],["Shift+Tab:切换模式","↑/↓:历史","Tab:补全"],["Ctrl+A:行首","Ctrl+E:行尾","Ctrl+K:删到尾"],["Ctrl+U:删到首","Ctrl+W:删单词","Ctrl+C:退出"]];return K1(n$,{flexDirection:"row",justifyContent:"space-between",paddingX:2,paddingY:0,children:[Q?K1(n$,{flexDirection:"column",gap:0,children:N.map((L,B)=>K1(n$,{flexDirection:"row",children:[L.map((_,I)=>{let[M,A]=_.split(":");return K1(n$,{flexDirection:"row",width:20,children:[K1(M1,{color:"yellow",children:M},void 0,!1,void 0,this),K1(M1,{color:"gray",children:":"},void 0,!1,void 0,this),K1(M1,{color:"white",children:A},void 0,!1,void 0,this)]},I,!0,void 0,this)}),B===N.length-1&&K1(M1,{color:"cyan",children:" ? 关闭"},void 0,!1,void 0,this)]},B,!0,void 0,this))},void 0,!1,void 0,this):K1(n$,{flexDirection:"row",gap:1,children:[q&&K1(h6,{children:[K1(M1,{color:"gray",children:[" ",q]},void 0,!0,void 0,this),K1(M1,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H,z&&K1(M1,{color:"gray",children:"·"},void 0,!1,void 0,this),K1(M1,{color:"gray",children:"? for shortcuts"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K1(n$,{flexDirection:"row",gap:1,children:!$?K1(M1,{color:"red",children:"⚠ API 密钥未配置"},void 0,!1,void 0,this):K1(h6,{children:[W&&K1(h6,{children:[O?K1(M1,{color:"cyan",children:"Thinking on"},void 0,!1,void 0,this):K1(M1,{color:"gray",children:"Tab:Thinking"},void 0,!1,void 0,this),K1(M1,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K&&K1(M1,{color:"gray",children:K.model},void 0,!1,void 0,this),K1(M1,{color:"gray",children:"·"},void 0,!1,void 0,this),U?K1(M1,{color:"yellow",children:"压缩中..."},void 0,!1,void 0,this):K1(M1,{color:G<20?"red":G<50?"yellow":"gray",children:[G,"%"]},void 0,!0,void 0,this),Y&&K1(h6,{children:[K1(M1,{color:"gray",children:"·"},void 0,!1,void 0,this),K1(M1,{color:"yellow",children:"Processing..."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J&&K1(h6,{children:[K1(M1,{color:"gray",children:"·"},void 0,!1,void 0,this),K1(M1,{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 X3,Text as Q3}from"ink";import fF from"react";import{jsxDEV as o$}from"react/jsx-dev-runtime";var GJ=fF.memo(({suggestions:$,selectedIndex:Y,visible:Z,maxDisplay:X=8})=>{if(!Z||$.length===0)return null;let Q=0,J=Math.min(X,$.length),q=Y>=$.length;if(Y>=X&&!q)Q=Y-X+1,J=Y+1;let K=$.slice(Q,J),G=$.length>X;return o$(X3,{flexDirection:"column",paddingX:2,paddingY:0,children:[K.map((U,O)=>{let F=Q+O===Y;return o$(X3,{flexDirection:"row",paddingX:1,gap:2,children:[o$(Q3,{color:F?"cyan":"white",bold:F,children:U.command},void 0,!1,void 0,this),o$(Q3,{color:F?"cyan":"gray",dimColor:!F,children:["- ",U.description]},void 0,!0,void 0,this)]},U.command,!0,void 0,this)}),G&&o$(X3,{paddingX:1,children:o$(Q3,{color:q?"cyan":"gray",bold:q,dimColor:!q,children:["... and ",$.length-X," more"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});$0();import{Box as T0,Text as r0,useInput as qH}from"ink";import KH from"ink-select-input";import AJ,{useMemo as GH}from"react";import{Box as e1,Text as J0}from"ink";import J8 from"react";import{Box as X8,Text as U2}from"ink";import{common as gF,createLowlight as dF}from"lowlight";import HJ from"react";B2();import{Box as Z8,Text as x6}from"ink";import R2,{Fragment as OJ}from"react";import hF from"string-width";var UJ=new Map,WJ=1000;function q3($){let Y=!0;for(let X=0;X<$.length;X++)if($.charCodeAt(X)>127){Y=!1;break}if(Y)return $.split("");if($.length<=WJ){let X=UJ.get($);if(X)return X}let Z=Array.from($);if($.length<=WJ)UJ.set($,Z);return Z}var J3=new Map;function b2($){if(/^[\x20-\x7E]*$/.test($))return $.length;if(J3.has($))return J3.get($);let Y=hF($);return J3.set($,Y),Y}import{jsxDEV as s$}from"react/jsx-dev-runtime";var K3=2,FJ=R2.memo(({children:$,maxWidth:Y,maxHeight:Z,overflowDirection:X="top",additionalHiddenLinesCount:Q=0})=>{let J=f1(),q=[],K=Math.max(Math.round(Z??Number.MAX_SAFE_INTEGER),K3);function G(N){if(!R2.isValidElement(N))return;if(N.type===OJ){R2.Children.forEach(N.props.children,G);return}if(N.type===Z8){pF(N,Y,q);return}}R2.Children.forEach($,G);let O=q.length>K||Q>0?K-1:K,W=O!==void 0?Math.max(0,q.length-O):0,F=W+Q,z=(W>0?X==="top"?q.slice(W):q.slice(0,O):q).map((N,L)=>s$(Z8,{children:N.length>0?N.map((B,_)=>s$(x6,{...B.props,children:B.text},_,!1,void 0,this)):s$(x6,{children:" "},void 0,!1,void 0,this)},L,!1,void 0,this));return s$(Z8,{flexDirection:"column",width:Y,flexShrink:0,children:[F>0&&X==="top"&&s$(x6,{color:J.colors.text.muted,dimColor:!0,children:["... ",F," line",F===1?"":"s"," hidden ..."]},void 0,!0,void 0,this),z,F>0&&X==="bottom"&&s$(x6,{color:J.colors.text.muted,dimColor:!0,children:["... ",F," line",F===1?"":"s"," hidden ..."]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});function xF($){if(!R2.isValidElement($)||$.type!==Z8)return{noWrapSegments:[],segments:[]};let Y={noWrapSegments:[],segments:[]},Z=!1;function X(Q,J){if(Q===null||Q===void 0)return;if(typeof Q==="string"||typeof Q==="number"){let U=String(Q);if(!U)return;let O={text:U,props:J??{}};if(J===void 0||J.wrap==="wrap")Z=!0,Y.segments.push(O);else if(!Z)Y.noWrapSegments.push(O);else Y.segments.push(O);return}if(!R2.isValidElement(Q))return;if(Q.type===OJ){R2.Children.forEach(Q.props.children,(U)=>X(U,J));return}if(Q.type!==x6)return;let{children:q,...K}=Q.props,G=J===void 0?K:{...J,...K};R2.Children.forEach(q,(U)=>X(U,G))}return R2.Children.forEach($.props.children,(Q)=>X(Q,void 0)),Y}function pF($,Y,Z){let X=xF($);if(X.segments.length===0&&X.noWrapSegments.length===0){Z.push([]);return}let Q=0;for(let W of X.noWrapSegments)Q+=b2(W.text);if(X.segments.length===0){let W=[],F=[];for(let H of X.noWrapSegments){let z=H.text.split(`
1867
+ `);for(let N=0;N<z.length;N++){if(N>0)W.push(F),F=[];if(z[N])F.push({text:z[N],props:H.props})}}if(F.length>0)W.push(F);for(let H of W)Z.push(H);return}let J=Y-Q;if(J<1){uF(X.noWrapSegments,Y,Z);return}let q=[],K=[],G=0;function U(){if(q.length===0)q.push([...X.noWrapSegments,...K]);else if(Q>0)q.push([{text:" ".repeat(Q),props:{}},...K]);else q.push(K);K=[],G=0}function O(W,F){if(K.length>0&&K[K.length-1].props===F)K[K.length-1].text+=W;else K.push({text:W,props:F})}for(let W of X.segments){let F=W.text.split(`
1868
+ `);for(let H=0;H<F.length;H++){if(H>0)U();let N=F[H].split(/(\s+)/);for(let L of N){if(!L)continue;let B=b2(L);if(G+B>J&&G>0){if(U(),/^\s+$/.test(L))continue}if(B>J){let I=q3(L);while(I.length>0){let M=0,A=0;for(let D of I){let w=b2(D);if(G+A+w>J)break;A+=w,M++}if(M>0){let D=I.slice(0,M).join("");O(D,W.props),G+=b2(D),I=I.slice(M)}if(I.length>0)U()}}else O(L,W.props),G+=B}}if(W.text.endsWith(`
1869
+ `))U()}if(K.length>0)U();for(let W of q)Z.push(W)}function uF($,Y,Z){let X=[],Q=[],J=0;for(let q of $){let K=q.text.split(`
1870
+ `);for(let G=0;G<K.length;G++){if(G>0)X.push(Q),Q=[],J=0;let U=K[G];if(!U)continue;let O=b2(U),W=Math.max(0,Y-b2("…"));if(O<=W&&J===0)Q.push({text:U,props:q.props}),J+=O;else{let F=q3(U),H=J,z=0;for(let L of F){let B=b2(L);if(H+B>W)break;H+=B,z++}let N=F.slice(0,z).join("");if(N)Q.push({text:N,props:q.props});Q.push({text:"…",props:{}}),J=H+b2("…")}}}if(Q.length>0)X.push(Q);if(X.length===0)X.push([{text:"…",props:{}}]);for(let q of X)Z.push(q)}import{jsxDEV as Q0}from"react/jsx-dev-runtime";var G3=dF(gF);function Q8($,Y,Z=0){if($.type==="text")return Q0(U2,{wrap:"wrap",children:$.value},Z,!1,void 0,this);if($.type==="element"){let X=$.properties?.className?.[0]||"",Q=Y.default;if(X.includes("comment"))Q=Y.comment;else if(X.includes("string"))Q=Y.string;else if(X.includes("number"))Q=Y.number;else if(X.includes("keyword"))Q=Y.keyword;else if(X.includes("function"))Q=Y.function;else if(X.includes("variable"))Q=Y.variable;else if(X.includes("operator"))Q=Y.operator;else if(X.includes("type"))Q=Y.type;else if(X.includes("tag"))Q=Y.tag;else if(X.includes("attr"))Q=Y.attr;let J=$.children?.map((q,K)=>Q8(q,Y,K));return Q0(U2,{color:Q,wrap:"wrap",children:J},Z,!1,void 0,this)}if($.type==="root"&&$.children)return Q0(HJ.Fragment,{children:$.children.map((X,Q)=>Q8(X,Y,Q))},Z,!1,void 0,this);return Q0(U2,{},Z,!1,void 0,this)}function mF($,Y,Z){let X=Z||P1.getTheme().colors.syntax;try{if(!Y||!G3.registered(Y)){let J=G3.highlightAuto($);if(!J.children||J.children.length===0)return Q0(U2,{color:X.default,wrap:"wrap",children:$},void 0,!1,void 0,this);return Q8(J,X)}let Q=G3.highlight(Y,$);if(!Q.children||Q.children.length===0)return Q0(U2,{color:X.default,wrap:"wrap",children:$},void 0,!1,void 0,this);return Q8(Q,X)}catch(Q){return Q0(U2,{color:X.default,wrap:"wrap",children:$},void 0,!1,void 0,this)}}var U3=HJ.memo(({content:$,language:Y,showLineNumbers:Z=!0,terminalWidth:X,availableHeight:Q})=>{let J=f1(),q=$.split(`
1871
+ `),K=0;if(Q&&q.length>Q){let W=Math.max(Q,K3);if(q.length>W)K=q.length-W,q=q.slice(K)}let G=q.length+K,U=String(G).length+1,O=Math.max(20,X-4);return Q0(X8,{borderStyle:"round",borderColor:J.colors.border.light,paddingX:1,paddingY:0,marginY:1,flexDirection:"column",children:[Y&&Q0(X8,{marginBottom:0,children:Q0(U2,{color:J.colors.text.secondary,children:Y},void 0,!1,void 0,this)},void 0,!1,void 0,this),K>0&&Q0(X8,{marginBottom:0,children:Q0(U2,{color:J.colors.text.muted,dimColor:!0,children:["... ",K," lines hidden ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q0(FJ,{maxWidth:O,maxHeight:Q,children:q.map((W,F)=>{let H=F+K+1;return Q0(X8,{flexDirection:"row",children:[Z&&Q0(U2,{color:J.colors.text.muted,dimColor:!0,wrap:"truncate",children:[String(H).padStart(U-1," ")," "]},void 0,!0,void 0,this),W.trim()===""?Q0(U2,{wrap:"wrap",children:" "},void 0,!1,void 0,this):mF(W,Y,J.colors.syntax)]},F,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});import{Box as zJ,Text as W2}from"ink";import{jsxDEV as j0}from"react/jsx-dev-runtime";function cF($){let Y=$.split(`
1872
+ `),Z=[],X=0,Q=0;for(let J of Y){if(J.startsWith("---")||J.startsWith("+++"))continue;if(J.startsWith("@@")){let q=J.match(/@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@/);if(q)X=parseInt(q[1],10),Q=parseInt(q[3],10);Z.push({type:"header",content:J});continue}if(J.startsWith("-")){Z.push({type:"remove",content:J.substring(1),lineNumber:X}),X++;continue}if(J.startsWith("+")){Z.push({type:"add",content:J.substring(1),lineNumber:Q}),Q++;continue}if(J.startsWith(" ")||J===""){Z.push({type:"context",content:J.substring(1),lineNumber:Q}),X++,Q++;continue}}return Z}var W3=({patch:$,startLine:Y,matchLine:Z,terminalWidth:X,maxLines:Q=20})=>{let J=f1(),q=cF($),G=Math.max(...q.map((H)=>H.lineNumber||0)).toString().length+1,U=q.length,O=U>Q,W=O?q.slice(0,Q):q,F=U-Q;return j0(zJ,{flexDirection:"column",marginTop:1,marginBottom:1,children:[j0(W2,{color:J.colors.muted,children:"─".repeat(Math.max(0,Math.min(60,X)))},void 0,!1,void 0,this),O&&j0(W2,{color:J.colors.info,children:["\uD83D\uDCCA 显示前 ",Q," 行,共 ",U," 行 diff"]},void 0,!0,void 0,this),O&&j0(W2,{color:J.colors.muted,children:"─".repeat(Math.max(0,Math.min(60,X)))},void 0,!1,void 0,this),W.map((H,z)=>{if(H.type==="header")return j0(W2,{color:J.colors.muted,dimColor:!0,children:H.content},z,!1,void 0,this);let N=H.lineNumber?H.lineNumber.toString().padStart(G," "):" ".repeat(G),L=" ",B,_;if(H.type==="add")L="+",_=J.colors.success,B=void 0;else if(H.type==="remove")L="-",_=J.colors.error,B=void 0;else _=J.colors.text.primary;let I=Math.max(0,X-G-2),M=H.content;if(M.length>I)M=M.substring(0,I-3)+"...";return j0(W2,{color:_,backgroundColor:B,children:[j0(W2,{dimColor:!0,children:N},void 0,!1,void 0,this),j0(W2,{children:L},void 0,!1,void 0,this),j0(W2,{children:[" ",M]},void 0,!0,void 0,this)]},z,!0,void 0,this)}),O&&j0(zJ,{marginTop:1,children:j0(W2,{color:J.colors.warning,dimColor:!0,children:["⚠️ 已隐藏剩余 ",F," 行 diff(总共 ",U," 行)"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),j0(W2,{color:J.colors.muted,children:"─".repeat(Math.max(0,Math.min(60,X)))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{Text as i0}from"ink";import iF from"react";import lF from"string-width";var q$=($)=>{let Y=$.replace(/\*\*(.*?)\*\*/g,"$1").replace(/\*(.*?)\*/g,"$1").replace(/_(.*?)_/g,"$1").replace(/~~(.*?)~~/g,"$1").replace(/`(.*?)`/g,"$1").replace(/<u>(.*?)<\/u>/g,"$1").replace(/\[(.*?)\]\(.*?\)/g,"$1");return lF(Y)},NJ=($,Y,Z="...")=>{if(q$($)<=Y)return $;if(Y<=Z.length)return Z.substring(0,Y);let Q=0,J=$.length,q="";while(Q<=J){let K=Math.floor((Q+J)/2),G=$.substring(0,K);if(q$(G)<=Y-Z.length)q=G,Q=K+1;else J=K-1}return q+Z},BJ=($)=>{return/[*_~`<[\]https?:]/.test($)};import{jsxDEV as y0,Fragment as aF}from"react/jsx-dev-runtime";var O3=2,F3=1,H3=2;function z3($,Y){return`${$.slice(0,20).replace(/[^a-zA-Z0-9]/g,"")}-${$.length}-${Y}`}var rF=({text:$})=>{let Y=f1();if(!BJ($))return y0(i0,{children:$},void 0,!1,void 0,this);let Z=[],X=0,Q=0,J=0,q=/(\*\*.*?\*\*|\*(?!\s).*?(?<!\s)\*|_(?!\s).*?(?<!\s)_|~~.*?~~|`+[^`]+`+|\[.*?\]\(.*?\)|https?:\/\/\S+)/g,K;while((K=q.exec($))!==null){if(K.index>X){let W=$.slice(X,K.index);Z.push(y0(i0,{children:W},z3(W,Q++),!1,void 0,this))}let G=K[0],U=null,O=z3(G,J++);try{if(G.startsWith("**")&&G.endsWith("**")&&G.length>O3*2)U=y0(i0,{bold:!0,children:G.slice(O3,-O3)},O,!1,void 0,this);else if(G.length>F3*2&&(G.startsWith("*")&&G.endsWith("*")||G.startsWith("_")&&G.endsWith("_"))){let W=$.substring(K.index-1,K.index),F=$.substring(q.lastIndex,q.lastIndex+1);if(!(/\w/.test(W)||/\w/.test(F)||/[./\\]/.test(W+F)))U=y0(i0,{italic:!0,children:G.slice(F3,-F3)},O,!1,void 0,this)}else if(G.startsWith("~~")&&G.endsWith("~~")&&G.length>H3*2)U=y0(i0,{strikethrough:!0,children:G.slice(H3,-H3)},O,!1,void 0,this);else if(G.startsWith("`")&&G.endsWith("`")){let W=G.match(/^(`+)([^`]+)\1$/);if(W&&W[2])U=y0(i0,{color:Y.colors.syntax.keyword,backgroundColor:Y.colors.background.secondary,bold:!0,children:` ${W[2]} `},O,!1,void 0,this)}else if(G.startsWith("[")&&G.includes("](")&&G.endsWith(")")){let W=G.match(/\[(.*?)\]\((.*?)\)/);if(W){let F=W[1],H=W[2];U=y0(i0,{children:[F,y0(i0,{color:Y.colors.info,children:[" (",H,")"]},void 0,!0,void 0,this)]},O,!0,void 0,this)}}else if(G.match(/^https?:\/\//))U=y0(i0,{color:Y.colors.info,children:G},O,!1,void 0,this)}catch(W){console.error("InlineRenderer 解析错误:",G,W),U=null}Z.push(U??y0(i0,{children:G},O,!1,void 0,this)),X=q.lastIndex}if(X<$.length){let G=$.slice(X);Z.push(y0(i0,{children:G},z3(G,Q++),!1,void 0,this))}return y0(aF,{children:Z.filter((G)=>G!==null)},void 0,!1,void 0,this)},E0=iF.memo(rF);import{Box as N3,Text as _J}from"ink";import nF from"react";import{jsxDEV as t$}from"react/jsx-dev-runtime";var oF=({itemText:$,type:Y,marker:Z,leadingWhitespace:X=""})=>{let Q=Y==="ol"?`${Z}. `:`${Z} `,J=Q.length,q=X.length;return t$(N3,{paddingLeft:q+1,flexDirection:"row",children:[t$(N3,{width:J,children:t$(_J,{children:Q},void 0,!1,void 0,this)},void 0,!1,void 0,this),t$(N3,{flexGrow:1,children:t$(_J,{wrap:"wrap",children:t$(E0,{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)},LJ=nF.memo(oF);import{Box as sF,Text as K$}from"ink";import B3 from"react";import{jsxDEV as v0}from"react/jsx-dev-runtime";var wJ=B3.memo(({headers:$,rows:Y,terminalWidth:Z})=>{let X=f1();if($.length===0||Y.length===0)return null;let Q=$.map((F,H)=>{let z=q$(F),N=Math.max(...Y.map((L)=>q$(L[H]||"")));return Math.max(z,N)+2}),J=$.length+1,q=Q.reduce((F,H)=>F+H,0)+J,K=q>Z?Z/q:1,G=Q.map((F)=>Math.floor(F*K)),U=(F,H,z=!1)=>{let N=Math.max(0,H-2),L=q$(F),B=F;if(L>N)B=NJ(F,N);let _=q$(B),I=Math.max(0,N-_);return v0(K$,{children:[z?v0(K$,{bold:!0,color:X.colors.primary,children:v0(E0,{text:B},void 0,!1,void 0,this)},void 0,!1,void 0,this):v0(E0,{text:B},void 0,!1,void 0,this)," ".repeat(I)]},void 0,!0,void 0,this)},O=(F)=>{let z={top:{left:"┌",middle:"┬",right:"┐",horizontal:"─"},middle:{left:"├",middle:"┼",right:"┤",horizontal:"─"},bottom:{left:"└",middle:"┴",right:"┘",horizontal:"─"}}[F],N=G.map((B)=>z.horizontal.repeat(B)),L=z.left+N.join(z.middle)+z.right;return v0(K$,{color:X.colors.text.muted,dimColor:!0,children:L},void 0,!1,void 0,this)},W=(F,H=!1)=>{let z=F.map((N,L)=>{let B=G[L]||0;return U(N||"",B,H)});return v0(K$,{children:[v0(K$,{color:X.colors.text.muted,children:"│ "},void 0,!1,void 0,this),z.map((N,L)=>v0(B3.Fragment,{children:[N,L<z.length-1&&v0(K$,{color:X.colors.text.muted,children:" │ "},void 0,!1,void 0,this)]},L,!0,void 0,this)),v0(K$,{color:X.colors.text.muted,children:" │"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};return v0(sF,{flexDirection:"column",marginY:1,children:[O("top"),W($,!0),O("middle"),Y.map((F,H)=>v0(B3.Fragment,{children:W(F)},H,!1,void 0,this)),O("bottom")]},void 0,!0,void 0,this)});import{jsxDEV as l}from"react/jsx-dev-runtime";var tF=($,Y,Z)=>{switch($){case"user":return{color:Y.info,prefix:"> "};case"assistant":return{color:Y.success,prefix:"• "};case"system":return{color:Y.warning,prefix:"⚙ "};case"tool":{let X=Z&&"phase"in Z?Z.phase:void 0;return{color:Y.text.secondary,prefix:X==="start"?"• ":X==="complete"?" └ ":" "}}default:return{color:Y.text.primary,prefix:" "}}},P0={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 _3($){let Y=[],Z=$.split(/\r?\n/),X=!1,Q=[],J=null,q=0,K=!1,G=[],U=[],O=!1,W=[],F=!0;for(let H=0;H<Z.length;H++){let z=Z[H];if(O){if(z.match(P0.diffEnd)){try{let w=JSON.parse(W.join(`
1873
+ `));Y.push({type:"diff",content:"",diffData:{patch:w.patch,startLine:w.startLine,matchLine:w.matchLine}})}catch(w){Y.push({type:"text",content:W.join(`
1874
+ `)})}O=!1,W=[],F=!1;continue}W.push(z);continue}if(z.match(P0.diffStart)){O=!0,W=[],F=!1;continue}if(X){let w=z.match(P0.codeBlock),R=z.trim()==="```";if(w&&w[1])q++,Q.push(z);else if(R)if(q>0)q--,Q.push(z);else{let E=Q.join(`
1875
+ `);if(J?.toLowerCase()==="markdown"||J?.toLowerCase()==="md"){let x=_3(E);Y.push(...x)}else Y.push({type:"code",content:E,language:J||void 0});X=!1,Q=[],J=null,q=0,F=!1}else Q.push(z);continue}let N=z.match(P0.codeBlock);if(N){X=!0,J=N[1]||null,q=0,F=!1;continue}let L=z.match(P0.table),B=z.match(P0.tableSeparator);if(L&&!K){if(H+1<Z.length){if(Z[H+1].match(P0.tableSeparator)){K=!0,G=L[1].split("|").map((R)=>R.trim()).filter((R)=>R.length>0),U=[],F=!1;continue}}}if(K&&B)continue;if(K&&L){let w=L[1].split("|").map((R)=>R.trim()).filter((R)=>R.length>0);while(w.length<G.length)w.push("");if(w.length>G.length)w.length=G.length;U.push(w);continue}if(K&&!L){if(G.length>0&&U.length>0)Y.push({type:"table",content:"",tableData:{headers:G,rows:U}});K=!1,G=[],U=[]}let _=z.match(P0.heading);if(_){Y.push({type:"heading",content:_[2],level:_[1].length}),F=!1;continue}let I=z.match(P0.ulItem);if(I){Y.push({type:"list",content:I[3],listType:"ul",marker:I[2],indentation:I[1].length}),F=!1;continue}let M=z.match(P0.olItem);if(M){Y.push({type:"list",content:M[3],listType:"ol",marker:M[2],indentation:M[1].length}),F=!1;continue}if(z.match(P0.hr)){Y.push({type:"hr",content:""}),F=!1;continue}if(z.trim().length===0){if(!F)Y.push({type:"empty",content:""}),F=!0;continue}let D=z.match(P0.commandMessage);if(D){Y.push({type:"command-message",content:D[1]}),F=!1;continue}Y.push({type:"text",content:z}),F=!1}if(X){let H=Q.join(`
1876
+ `);if(J?.toLowerCase()==="markdown"||J?.toLowerCase()==="md"){let z=_3(H);Y.push(...z)}else Y.push({type:"code",content:H,language:J||void 0})}if(K&&G.length>0&&U.length>0)Y.push({type:"table",content:"",tableData:{headers:G,rows:U}});return Y}var eF=({content:$,language:Y,terminalWidth:Z})=>{return l(U3,{content:$,language:Y,showLineNumbers:!0,terminalWidth:Z},void 0,!1,void 0,this)},$H=({content:$,level:Y})=>{let Z=f1();switch(Y){case 1:return l(J0,{bold:!0,color:Z.colors.primary,children:l(E0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 2:return l(J0,{bold:!0,color:Z.colors.primary,children:l(E0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 3:return l(J0,{bold:!0,color:Z.colors.text.primary,children:l(E0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 4:return l(J0,{italic:!0,color:Z.colors.text.muted,children:l(E0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);default:return l(J0,{children:l(E0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)}},YH=({terminalWidth:$})=>{let Y=f1(),Z=Math.max(0,Math.min($-4,80));return l(J0,{dimColor:!0,color:Y.colors.text.muted,children:"─".repeat(Z)},void 0,!1,void 0,this)},ZH=({content:$})=>{return l(J0,{wrap:"wrap",children:l(E0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)},XH=({content:$})=>{let Y=f1();return l(e1,{flexDirection:"row",gap:1,children:[l(J0,{color:Y.colors.info,children:"⏳"},void 0,!1,void 0,this),l(J0,{color:Y.colors.text.muted,italic:!0,children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},QH=J8.memo(({detail:$,terminalWidth:Y})=>{let Z=f1(),X=50,Q=$.split(`
1877
+ `),J=Q.length>50,q=J?Q.slice(0,50):Q,K=q.join(`
1878
+ `),G=K.includes("<<<DIFF>>>"),U=K.includes("```");if(G){let O=K.match(/<<<DIFF>>>\s*({[\s\S]*?})\s*<<<\/DIFF>>>/);if(O)try{let W=JSON.parse(O[1]);return l(e1,{flexDirection:"column",children:[l(W3,{patch:W.patch,startLine:W.startLine,matchLine:W.matchLine,terminalWidth:Y},void 0,!1,void 0,this),J&&l(e1,{marginTop:1,children:l(J0,{dimColor:!0,color:Z.colors.text.muted,children:["... 省略 ",Q.length-50," 行 ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}catch{}}if(U){let O=K.match(/```(\w+)?\s*\n([\s\S]*?)\n```/);if(O){let W=O[1]||"text",F=O[2];return l(e1,{flexDirection:"column",children:[l(U3,{content:F,language:W,showLineNumbers:!1,terminalWidth:Y},void 0,!1,void 0,this),J&&l(e1,{marginTop:1,children:l(J0,{dimColor:!0,color:Z.colors.text.muted,children:["... 省略 ",Q.length-50," 行 ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}}return l(e1,{flexDirection:"column",children:[q.map((O,W)=>l(J0,{color:Z.colors.text.primary,children:O},W,!1,void 0,this)),J&&l(e1,{marginTop:1,children:l(J0,{dimColor:!0,color:Z.colors.text.muted,children:["... 省略 ",Q.length-50," 行 ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});function JH($,Y){if($===Y)return!0;if(!$||!Y)return $===Y;return $.toolName===Y.toolName&&$.phase===Y.phase&&$.summary===Y.summary}var p6=J8.memo(({content:$,role:Y,terminalWidth:Z,metadata:X,isPending:Q=!1})=>{let J=f1(),q=J8.useMemo(()=>tF(Y,J.colors,X),[Y,J.colors,X]),{color:K,prefix:G}=q;if(Y==="tool"&&X&&"detail"in X){let O=X;if(O.detail)return l(e1,{flexDirection:"column",marginBottom:1,children:[l(e1,{flexDirection:"row",children:[l(e1,{marginRight:1,children:l(J0,{color:K,bold:!0,children:G},void 0,!1,void 0,this)},void 0,!1,void 0,this),l(J0,{color:K,children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),l(e1,{marginLeft:G.length+1,marginTop:1,children:l(QH,{detail:O.detail,terminalWidth:Z-(G.length+1)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}let U=J8.useMemo(()=>_3($),[$]);return l(e1,{flexDirection:"column",marginBottom:1,children:U.map((O,W)=>{if(O.type==="empty")return l(e1,{height:1},W,!1,void 0,this);return l(e1,{flexDirection:"row",children:[W===0&&l(e1,{marginRight:1,children:l(J0,{color:K,bold:!0,children:G},void 0,!1,void 0,this)},void 0,!1,void 0,this),W>0&&l(e1,{width:G.length+1},void 0,!1,void 0,this),l(e1,{flexGrow:1,children:O.type==="code"?l(eF,{content:O.content,language:O.language,terminalWidth:Z-(G.length+1)},void 0,!1,void 0,this):O.type==="table"&&O.tableData?l(wJ,{headers:O.tableData.headers,rows:O.tableData.rows,terminalWidth:Z-(G.length+1)},void 0,!1,void 0,this):O.type==="heading"?l($H,{content:O.content,level:O.level||1},void 0,!1,void 0,this):O.type==="list"?l(LJ,{type:O.listType||"ul",marker:O.marker||"-",itemText:O.content,leadingWhitespace:" ".repeat(O.indentation||0)},void 0,!1,void 0,this):O.type==="hr"?l(YH,{terminalWidth:Z-(G.length+1)},void 0,!1,void 0,this):O.type==="diff"&&O.diffData?l(W3,{patch:O.diffData.patch,startLine:O.diffData.startLine,matchLine:O.diffData.matchLine,terminalWidth:Z-(G.length+1)},void 0,!1,void 0,this):O.type==="command-message"?l(XH,{content:O.content},void 0,!1,void 0,this):l(ZH,{content:O.content},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},W,!0,void 0,this)})},void 0,!1,void 0,this)},($,Y)=>{return $.content===Y.content&&$.role===Y.role&&$.terminalWidth===Y.terminalWidth&&$.isPending===Y.isPending&&JH($.metadata,Y.metadata)});import{jsxDEV as y1}from"react/jsx-dev-runtime";var UH=AJ.memo(({label:$,isSelected:Y})=>y1(r0,{color:Y?"yellow":void 0,children:$},void 0,!1,void 0,this)),bJ=AJ.memo(({details:$,onResponse:Y})=>{let Z=d2(),Q=M0()==="confirmation-prompt",J=d1(!1),q=$.type==="exitPlanMode",K=$.type==="enterPlanMode",G=$.type==="maxTurnsExceeded";qH((F,H)=>{if(H.ctrl&&F==="c"||H.meta&&F==="c"){J();return}if(H.escape){Y({approved:!1,reason:"用户取消"});return}let z=F.toLowerCase();if(q){if(z==="y"){Y({approved:!0,targetMode:"autoEdit"});return}if(z==="s"){Y({approved:!0,targetMode:"default"});return}if(z==="n"){Y({approved:!1,reason:"方案需要改进"});return}}else if(K){if(z==="y"){Y({approved:!0});return}if(z==="n"){Y({approved:!1,reason:"用户拒绝进入 Plan 模式"});return}}else if(G){if(z==="y"){Y({approved:!0});return}if(z==="n"){Y({approved:!1,reason:"用户选择停止"});return}}else{if(z==="y"){Y({approved:!0,scope:"once"});return}if(z==="s"){Y({approved:!0,scope:"session"});return}if(z==="n"){Y({approved:!1,reason:"用户拒绝"});return}}},{isActive:Q});let U=GH(()=>{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(G)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,G]),W=(()=>{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(G)return{color:"yellow",title:"⚡ Max Turns Exceeded"};return{color:"yellow",title:"\uD83D\uDD14 Confirmation Required"}})();return y1(T0,{flexDirection:"column",borderStyle:"round",borderColor:Q?W.color:"gray",padding:1,children:[y1(T0,{marginBottom:1,children:y1(r0,{bold:!0,color:W.color,children:W.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),$.title&&y1(T0,{marginBottom:1,children:y1(r0,{bold:!0,children:$.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),y1(T0,{marginBottom:1,children:y1(r0,{children:$.message},void 0,!1,void 0,this)},void 0,!1,void 0,this),($.planContent||$.details)&&y1(T0,{flexDirection:"column",marginBottom:1,borderStyle:"single",borderColor:W.color,padding:1,children:[y1(r0,{bold:!0,color:W.color,children:q?"\uD83D\uDCCB Implementation Plan:":K?"\uD83D\uDCDD Details:":"\uD83D\uDCC4 Operation Details:"},void 0,!1,void 0,this),y1(T0,{marginTop:1,children:y1(p6,{content:$.planContent||$.details||"",role:"assistant",terminalWidth:Z-4},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$.risks&&$.risks.length>0&&y1(T0,{flexDirection:"column",marginBottom:1,children:[y1(r0,{color:"red",bold:!0,children:"⚠️ 风险提示:"},void 0,!1,void 0,this),$.risks.map((F,H)=>y1(T0,{marginLeft:2,children:y1(r0,{color:"red",children:["• ",F]},void 0,!0,void 0,this)},H,!1,void 0,this))]},void 0,!0,void 0,this),$.affectedFiles&&$.affectedFiles.length>0&&y1(T0,{flexDirection:"column",marginBottom:1,children:[y1(r0,{color:"yellow",children:"\uD83D\uDCC1 影响的文件:"},void 0,!1,void 0,this),$.affectedFiles.slice(0,3).map((F,H)=>y1(T0,{marginLeft:2,children:y1(r0,{children:["• ",F]},void 0,!0,void 0,this)},H,!1,void 0,this)),$.affectedFiles.length>3&&y1(T0,{marginLeft:2,children:y1(r0,{color:"gray",children:["...还有 ",$.affectedFiles.length-3," 个文件"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),y1(T0,{flexDirection:"column",children:[y1(r0,{color:"gray",children:"使用 ↑ ↓ 选择,回车确认(支持 Y/S/N 快捷键,ESC 取消)"},void 0,!1,void 0,this),y1(KH,{items:U,isFocused:Q,itemComponent:UH,onSelect:(F)=>{Y(F.value)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});L0();R$();B2();import{Box as F1,Text as Y1,useInput as WH}from"ink";import RJ from"ink-text-input";import{useState as V2}from"react";import{jsxDEV as f}from"react/jsx-dev-runtime";var u6=[{action:"add",description:"Add a new hook"},{action:"status",description:"Show hooks status"},{action:"list",description:"List all configured hooks"}],q8=[{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"}],K8=[{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"}],OH=[`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"],VJ=({onClose:$,onSave:Y})=>{let Z=P1.getTheme(),[X,Q]=V2("action"),[J,q]=V2(0),[K,G]=V2(0),[U,O]=V2(0),[W,F]=V2(""),[H,z]=V2(""),[N,L]=V2(null),[B,_]=V2(!1),[I,M]=V2(null),A=u6[J],D=K8[K],w=q8[U],R=()=>{if(I){M(null);return}switch(X){case"action":$();break;case"event":Q("action");break;case"matcher":Q("event");break;case"command":Q("matcher");break;case"location":Q("command");break;case"confirm":Q("location");break}};WH((T,C)=>{if(C.escape){R();return}if(X==="action"){if(C.upArrow)q((j)=>j>0?j-1:u6.length-1);else if(C.downArrow)q((j)=>j<u6.length-1?j+1:0);else if(C.return)E()}else if(X==="event"){if(C.upArrow)G((j)=>j>0?j-1:K8.length-1);else if(C.downArrow)G((j)=>j<K8.length-1?j+1:0);else if(C.return)Q("matcher")}else if(X==="location"){if(C.upArrow)O((j)=>j>0?j-1:q8.length-1);else if(C.downArrow)O((j)=>j<q8.length-1?j+1:0);else if(C.return)Q("confirm")}else if(X==="confirm"){if(C.return)n()}});let E=()=>{let T=u6[J].action;if(T==="add")Q("event");else if(T==="status")x();else if(T==="list")r()},x=()=>{let T=H1.getInstance(),C=T.isEnabled(),j=T.getConfig(),S1={};for(let e of Object.values(e0)){let B1=j[e];if(B1&&Array.isArray(B1)){let g=B1.reduce((G1,t)=>G1+(t.hooks?.length||0),0);if(g>0)S1[e]=g}}let d=[`Status: ${C?"✅ Enabled":"⏸️ Disabled"}`,""];if(Object.keys(S1).length>0){d.push("Configured hooks:");for(let[e,B1]of Object.entries(S1))d.push(` ${e}: ${B1} hook(s)`)}else d.push("No hooks configured");M(d.join(`
1879
+ `))},r=()=>{let C=H1.getInstance().getConfig(),j=[],S1=!1;for(let d of Object.values(e0)){let e=C[d];if(!e||!Array.isArray(e)||e.length===0)continue;S1=!0,j.push(`${d}:`);for(let B1 of e){let g=B1.matcher,G1="all";if(g?.tools)G1=`tools: ${Array.isArray(g.tools)?g.tools.join(", "):g.tools}`;j.push(` [${G1}]`);for(let t of B1.hooks||[])if(t.type==="command")j.push(` → ${t.command}`)}j.push("")}if(!S1)j.push("No hooks configured"),j.push(""),j.push("Configure hooks in .blade/settings.local.json");M(j.join(`
1880
+ `))},P=()=>{Q("command")},k=()=>{if(!H.trim()){L("Command cannot be empty");return}L(null),Q("location")},n=async()=>{_(!0),L(null);try{let T=H1.getInstance(),C=await import("node:fs/promises"),j=await import("node:path"),S1=await import("node:os"),d={matcher:W.trim()?{tools:W.trim()}:{},hooks:[{type:"command",command:H.trim()}]},e;switch(w.location){case"local":e=j.join(process.cwd(),".blade","settings.local.json");break;case"project":e=j.join(process.cwd(),".blade","settings.json");break;case"user":e=j.join(S1.homedir(),".blade","settings.json");break}await C.mkdir(j.dirname(e),{recursive:!0});let B1={};try{let G0=await C.readFile(e,"utf-8");B1=JSON.parse(G0)}catch{}let g=B1.hooks||{},G1=g[D.event]||[],t={...g,enabled:!0,[D.event]:[...G1,d]};if(B1.hooks=t,await C.writeFile(e,JSON.stringify(B1,null,2),"utf-8"),await T.reloadConfig(),Y)Y({event:D.event,matcher:W.trim(),command:H.trim()});$()}catch(T){L(`Failed to save hook: ${T instanceof Error?T.message:"Unknown error"}`),_(!1)}};return f(F1,{flexDirection:"column",padding:1,children:[f(F1,{marginBottom:1,children:f(Y1,{bold:!0,color:Z.colors.success,children:"Hooks Manager"},void 0,!1,void 0,this)},void 0,!1,void 0,this),f(F1,{marginBottom:1,children:f(Y1,{color:Z.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),I&&f(F1,{flexDirection:"column",marginBottom:1,children:[f(Y1,{children:I},void 0,!1,void 0,this),f(F1,{marginTop:1,children:f(Y1,{color:Z.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),X==="action"&&!I&&f(F1,{flexDirection:"column",children:[f(F1,{flexDirection:"column",marginTop:1,children:u6.map((T,C)=>f(F1,{children:[f(Y1,{color:C===J?Z.colors.primary:void 0,bold:C===J,children:[C===J?"❯ ":" ",T.action]},void 0,!0,void 0,this),f(Y1,{color:Z.colors.muted,children:[" - ",T.description]},void 0,!0,void 0,this)]},T.action,!0,void 0,this))},void 0,!1,void 0,this),f(F1,{marginTop:1,children:f(Y1,{color:Z.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),X==="event"&&f(F1,{flexDirection:"column",children:[f(Y1,{bold:!0,children:"Select Event:"},void 0,!1,void 0,this),f(F1,{flexDirection:"column",marginTop:1,children:K8.map((T,C)=>f(F1,{children:[f(Y1,{color:C===K?Z.colors.primary:void 0,bold:C===K,children:[C===K?"❯ ":" ",T.event]},void 0,!0,void 0,this),f(Y1,{color:Z.colors.muted,children:[" - ",T.description]},void 0,!0,void 0,this)]},T.event,!0,void 0,this))},void 0,!1,void 0,this),f(F1,{marginTop:1,children:f(Y1,{color:Z.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),X!=="event"&&f(F1,{marginBottom:1,children:f(Y1,{children:["Event:"," ",f(Y1,{bold:!0,color:Z.colors.primary,children:D.event},void 0,!1,void 0,this),f(Y1,{color:Z.colors.muted,children:[" - ",D.description]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),(X==="matcher"||X==="command"||X==="confirm")&&f(F1,{flexDirection:"column",marginBottom:1,children:[f(Y1,{color:Z.colors.muted,children:"Input to command is JSON of tool call arguments."},void 0,!1,void 0,this),f(Y1,{color:Z.colors.muted,children:"Exit code 0 - stdout/stderr not shown"},void 0,!1,void 0,this),f(Y1,{color:Z.colors.muted,children:"Exit code 2 - show stderr to model and block tool call"},void 0,!1,void 0,this),f(Y1,{color:Z.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),X==="matcher"&&f(F1,{flexDirection:"column",children:[f(F1,{children:[f(Y1,{bold:!0,children:"Matcher: "},void 0,!1,void 0,this),f(RJ,{value:W,onChange:F,onSubmit:P,placeholder:"e.g., Read, Bash, Edit|Write (empty = all tools)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f(F1,{marginTop:1,children:f(Y1,{color:Z.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),f(F1,{marginTop:1,children:f(Y1,{color:Z.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),(X==="command"||X==="confirm")&&f(F1,{marginBottom:1,children:f(Y1,{children:["Matcher: ",f(Y1,{bold:!0,children:W||"(all tools)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),X==="command"&&f(F1,{flexDirection:"column",children:[f(F1,{children:f(Y1,{bold:!0,children:"Command: "},void 0,!1,void 0,this)},void 0,!1,void 0,this),f(F1,{borderStyle:"single",borderColor:Z.colors.border.light,paddingX:1,marginTop:1,children:f(RJ,{value:H,onChange:z,onSubmit:k,placeholder:"Enter shell command..."},void 0,!1,void 0,this)},void 0,!1,void 0,this),f(F1,{flexDirection:"column",marginTop:1,children:[f(Y1,{bold:!0,children:"Examples:"},void 0,!1,void 0,this),OH.map((T,C)=>f(Y1,{color:Z.colors.muted,children:["• ",T]},C,!0,void 0,this))]},void 0,!0,void 0,this),f(F1,{marginTop:1,children:f(Y1,{color:Z.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),X==="location"&&f(F1,{flexDirection:"column",children:[f(F1,{flexDirection:"column",borderStyle:"round",borderColor:Z.colors.border.light,paddingX:2,paddingY:1,marginBottom:1,children:[f(Y1,{bold:!0,color:Z.colors.primary,children:"Save hook configuration"},void 0,!1,void 0,this),f(Y1,{children:" "},void 0,!1,void 0,this),f(Y1,{children:[" Event: ",D.event," - ",D.description]},void 0,!0,void 0,this),f(Y1,{children:[" Matcher: ",W||"(all)"]},void 0,!0,void 0,this),f(Y1,{children:[" Command: ",H]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),f(Y1,{bold:!0,children:"Where should this hook be saved?"},void 0,!1,void 0,this),f(F1,{flexDirection:"column",marginTop:1,children:q8.map((T,C)=>f(F1,{children:[f(Y1,{color:C===U?Z.colors.primary:void 0,bold:C===U,children:[C===U?"❯ ":" ",C+1,". ",T.name]},void 0,!0,void 0,this),f(Y1,{color:Z.colors.muted,children:[" ",T.description]},void 0,!0,void 0,this)]},T.location,!0,void 0,this))},void 0,!1,void 0,this),f(F1,{marginTop:1,children:f(Y1,{color:Z.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),X==="confirm"&&f(F1,{flexDirection:"column",children:[f(F1,{flexDirection:"column",borderStyle:"round",borderColor:Z.colors.success,paddingX:2,paddingY:1,children:[f(Y1,{bold:!0,children:["Saving hook to ",w.description,"..."]},void 0,!0,void 0,this),f(Y1,{children:" "},void 0,!1,void 0,this),f(Y1,{children:["Event: ",D.event]},void 0,!0,void 0,this),f(Y1,{children:["Matcher: ",W||"(all tools)"]},void 0,!0,void 0,this),f(Y1,{children:["Command: ",H]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),f(F1,{marginTop:1,children:f(Y1,{color:Z.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),N&&f(F1,{marginTop:1,children:f(Y1,{color:Z.colors.error,children:["❌ ",N]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{useMemoizedFn as SJ}from"ahooks";import{Box as VH,Text as DH}from"ink";import IH from"react";import{useMemoizedFn as _H}from"ahooks";import G$ from"chalk";import{Text as LH,useInput as wH}from"ink";import{useEffect as A3,useRef as b3}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 e$}from"node:child_process";import{existsSync as FH,readFileSync as L3}from"node:fs";import{basename as DJ,isAbsolute as HH}from"node:path";function zH(){let $=process.platform,Y={darwin:"No image found in clipboard. Use Cmd + Ctrl + Shift + 4 to copy a screenshot to clipboard.",win32:"No image found in clipboard. Use Print Screen to copy a screenshot to clipboard.",linux:"No image found in clipboard. Use appropriate screenshot tool to copy a screenshot to clipboard."};return Y[$]||Y.linux}var Dv=zH();function IJ($){try{let Y=Buffer.from($,"base64");if(Y.length<4)return"image/png";if(Y[0]===137&&Y[1]===80&&Y[2]===78&&Y[3]===71)return"image/png";if(Y[0]===255&&Y[1]===216&&Y[2]===255)return"image/jpeg";if(Y[0]===71&&Y[1]===73&&Y[2]===70)return"image/gif";if(Y[0]===82&&Y[1]===73&&Y[2]===70&&Y[3]===70){if(Y.length>=12&&Y[8]===87&&Y[9]===69&&Y[10]===66&&Y[11]===80)return"image/webp"}return"image/png"}catch{return"image/png"}}function MJ(){let $=process.platform,Y={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"},Z={darwin:{checkImage:"osascript -e 'the clipboard as «class PNGf»'",saveImage:(X)=>`osascript -e 'set png_data to (the clipboard as «class PNGf»)' -e 'set fp to open for access POSIX file "${X}" 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:(X)=>`rm -f "${X}"`},linux:{checkImage:'xclip -selection clipboard -t TARGETS -o | grep -E "image/(png|jpeg|jpg|gif|webp)"',saveImage:(X)=>`xclip -selection clipboard -t image/png -o > "${X}" || wl-paste --type image/png > "${X}"`,getPath:"xclip -selection clipboard -t text/plain -o",deleteFile:(X)=>`rm -f "${X}"`},win32:{checkImage:'powershell -Command "(Get-Clipboard -Format Image) -ne $null"',saveImage:(X)=>`powershell -Command "$img = Get-Clipboard -Format Image; if ($img) { $img.Save('${X.replace(/\\/g,"\\\\")}', [System.Drawing.Imaging.ImageFormat]::Png) }"`,getPath:'powershell -Command "Get-Clipboard"',deleteFile:(X)=>`del /f "${X}"`}};return{commands:Z[$]||Z.linux,screenshotPath:Y[$]||Y.linux}}function NH(){let{commands:$}=MJ();try{return e$($.getPath,{encoding:"utf-8"}).trim()}catch(Y){return console.error("Failed to get clipboard path:",Y),null}}function jJ($){if($.startsWith('"')&&$.endsWith('"')||$.startsWith("'")&&$.endsWith("'"))return $.slice(1,-1);return $}function yJ($){if(process.platform==="win32")return $;let Y="__DOUBLE_BACKSLASH__";return $.replace(/\\\\/g,Y).replace(/\\(.)/g,"$1").replace(new RegExp(Y,"g"),"\\")}function w3($){let Y=jJ($.trim()),Z=yJ(Y);return/\.(png|jpe?g|gif|webp)$/i.test(Z)}function BH($){let Y=jJ($.trim()),Z=yJ(Y);if(w3(Z))return Z;return null}async function EJ($){let Y=BH($);if(!Y)return null;let Z;try{if(HH(Y))Z=L3(Y);else{let q=NH();if(q&&Y===DJ(q))Z=L3(q);else return null}}catch(q){return console.error("Failed to read image file:",q),null}let X=Z.toString("base64"),Q=IJ(X),J=DJ(Y);return{path:Y,base64:X,mediaType:Q,filename:J}}async function vJ(){let $=process.platform,Y={darwin:"pbpaste",linux:"xclip -selection clipboard -o || wl-paste",win32:'powershell -Command "Get-Clipboard"'},Z=Y[$]||Y.linux;try{return e$(Z,{encoding:"utf-8"})||null}catch{return null}}async function PJ(){let{commands:$,screenshotPath:Y}=MJ();try{if(e$($.checkImage,{stdio:"ignore"}),e$($.saveImage(Y),{stdio:"ignore"}),!FH(Y))return null;let X=L3(Y).toString("base64"),Q=IJ(X);return e$($.deleteFile(Y),{stdio:"ignore"}),{base64:X,mediaType:Q}}catch(Z){try{e$($.deleteFile(Y),{stdio:"ignore"})}catch{}return null}}import{jsxDEV as RH}from"react/jsx-dev-runtime";var AH=/\r\n/g,bH=/\r/g;function U$($){if(!$.includes("\r"))return $;return $.replace(AH,`
1881
+ `).replace(bH,`
1882
+ `)}function W$($,Y,Z){let X=Math.max(0,Math.min(Z,Y.length)),Q=Y.slice(0,X),J=Y.slice(X);return{newValue:Q+$+J,newCursorPosition:X+$.length}}function TJ({value:$,placeholder:Y="",focus:Z=!0,onChange:X,cursorPosition:Q,onChangeCursorPosition:J,onPaste:q,onImagePaste:K,disabledKeys:G=[]}){let U=b3({chunks:[],timeoutId:null,firstInputTime:null,lastInputTime:null,totalLength:0}),O=b3($),W=b3(Q);A3(()=>{O.current=$,W.current=Q},[$,Q]),A3(()=>{return()=>{if(U.current.timeoutId)clearTimeout(U.current.timeoutId)}},[]),A3(()=>{if(Q>$.length)J($.length)},[$,Q,J]);let F=_H(()=>{let L=U.current;if(L.timeoutId)clearTimeout(L.timeoutId);let B=setTimeout(async()=>{let _=U.current.chunks,I=U.current.totalLength;if(_.length===0)return;let M=U$(_.join(""));U.current={chunks:[],timeoutId:null,firstInputTime:null,lastInputTime:null,totalLength:0};let A=O.current,D=W.current;if(K&&w3(M))try{let P=await EJ(M);if(P){let k=await K(P.base64,P.mediaType,P.filename);if(k?.prompt){let n=U$(k.prompt),{newValue:T,newCursorPosition:C}=W$(n,A,D);X(T),J(C)}return}}catch(P){console.error("Failed to process image path:",P)}let w=M.includes(`
1883
+ `),R=I>D2.MEDIUM_SIZE_MULTI_CHUNK_THRESHOLD&&_.length>3;if((I>D2.LARGE_INPUT_THRESHOLD||w||R)&&q){let P=await q(M);if(P?.prompt){let k=U$(P.prompt),{newValue:n,newCursorPosition:T}=W$(k,A,D);X(n),J(T);return}}let{newValue:x,newCursorPosition:r}=W$(M,A,D);X(x),J(r)},D2.TIMEOUT_MS);U.current.timeoutId=B});wH((L,B)=>{let _=U$(L);if(G.some((R)=>B[R])||B.ctrl&&L==="c"||B.ctrl&&L==="l"||B.ctrl&&L==="t"||B.ctrl&&L==="o"||B.meta&&L==="l"||B.meta&&L==="t"||B.meta&&L==="o"||B.shift&&B.tab||_==="?"&&$==="")return;let M=Date.now(),A=U.current,D=Q,w=$;if(B.leftArrow)D--;else if(B.rightArrow)D++;else if(B.backspace||B.delete){if(L===""){if(Q>0)w=$.slice(0,Q-1)+$.slice(Q,$.length),D--}else if(Q<$.length)w=$.slice(0,Q)+$.slice(Q+1,$.length)}else if(B.ctrl&&_==="a")D=0;else if(B.ctrl&&_==="e")D=$.length;else if(B.ctrl&&_==="k")w=$.slice(0,Q);else if(B.ctrl&&_==="u")w=$.slice(Q),D=0;else if(B.ctrl&&_==="w"){let E=$.slice(0,Q).match(/\s*\S+\s*$/);if(E){let x=E[0].length;w=$.slice(0,Q-x)+$.slice(Q),D-=x}}else if(B.ctrl&&_==="v"){let R=process.platform==="darwin";(async()=>{if(K){let x=await PJ();if(x){let r=await K(x.base64,x.mediaType,"clipboard.png");if(r?.prompt){let P=U$(r.prompt),{newValue:k,newCursorPosition:n}=W$(P,O.current,W.current);X(k),J(n)}return}}if(R)return;let E=await vJ();if(E){let x=U$(E),r=x.includes(`
1884
+ `),P=x.length>D2.LARGE_INPUT_THRESHOLD;if((r||P)&&q){let T=await q(x);if(T?.prompt){let C=U$(T.prompt),{newValue:j,newCursorPosition:S1}=W$(C,O.current,W.current);X(j),J(S1);return}}let{newValue:k,newCursorPosition:n}=W$(x,O.current,W.current);X(k),J(n)}})().catch(()=>{});return}else if(B.pageUp)D=0;else if(B.pageDown)D=$.length;else if(_===`
1885
+ `&&(B.shift||B.meta)){let{newValue:R,newCursorPosition:E}=W$(_,$,Q);X(R),J(E);return}else if(!B.ctrl&&!B.meta){if(!A.firstInputTime)A.firstInputTime=M;A.lastInputTime=M;let R=M-(A.firstInputTime||M),E=_.length>D2.LARGE_INPUT_THRESHOLD,x=_.includes(`
1886
+ `)&&_.length>1,r=R<D2.RAPID_INPUT_THRESHOLD_MS&&A.chunks.length>0,P=R<D2.RAPID_INPUT_THRESHOLD_MS&&_.length>10,k=A.timeoutId!==null;if(q&&(E||x||r||P||k)){A.chunks.push(_),A.totalLength+=_.length,F();return}if(_.length===1&&!A.timeoutId)A.chunks=[],A.firstInputTime=null,A.lastInputTime=null,A.totalLength=0;w=$.slice(0,Q)+_+$.slice(Q,$.length),D+=_.length}if(D<0)D=0;if(D>w.length)D=w.length;if(w!==$)X(w);if(D!==Q)J(D)},{isActive:Z});let H=Z,z=$,N=Y?G$.grey(Y):void 0;if(H)if(N=Y.length>0?G$.inverse(Y[0])+G$.grey(Y.slice(1)):G$.inverse(" "),$.length===0)z=G$.inverse(" ");else{z="";for(let L=0;L<$.length;L++)if(L===Q&&Q<$.length)z+=G$.inverse($[L]);else z+=$[L];if(Q>=$.length)z+=G$.inverse(" ")}return RH(LH,{children:Y?$.length>0?z:N:z},void 0,!1,void 0,this)}import{jsxDEV as R3}from"react/jsx-dev-runtime";var kJ=IH.memo(({input:$,cursorPosition:Y,onChange:Z,onChangeCursorPosition:X,onAddPasteMapping:Q,onAddImagePasteMapping:J})=>{let K=M0()==="main-input",G=SJ((O)=>{let W=O.split(`
1887
+ `).length,F=O.length,H=500,z=10;if(F>500||W>10){let N=Q(O),L=O.slice(0,30).replace(/\n/g," "),B=`${F} chars, ${W} lines: ${L}...`;return{prompt:`${t4(N)}${B}${n7()}`}}return{}}),U=SJ(async(O,W,F)=>{try{let H=J(O,W);return{prompt:`${t4(H)}[Image #${H}]${n7()}`}}catch(H){return console.error("[Image Paste] Failed to process image:",H),{prompt:`[Image paste failed: ${H instanceof Error?H.message:"Unknown error"}] `}}});return R3(VH,{flexDirection:"row",width:"100%",paddingX:2,paddingY:0,flexShrink:0,flexGrow:0,overflow:"hidden",borderStyle:"round",borderColor:"gray",children:[R3(DH,{color:"blue",bold:!0,children:"> "},void 0,!1,void 0,this),R3(TJ,{value:$,cursorPosition:Y,onChange:Z,onChangeCursorPosition:X,onPaste:G,onImagePaste:U,placeholder:" 输入命令...",focus:K,disabledKeys:["upArrow","downArrow","tab","return","escape"]},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});import{Box as G8,Text as a0}from"ink";import vH,{useEffect as PH,useState as TH}from"react";import{useEffect as EH,useState as xJ}from"react";import{useEffect as MH,useState as jH}from"react";var yH=15000,CJ=["炼化代码灵气...","参悟 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 广纳贤才..."],fJ=["Esc - 立即停止当前任务","Shift+Tab - 切换权限模式 (default/auto_edit/plan)","Tab - 智能补全斜杠命令","↑↓ - 浏览输入历史记录","双击 Esc - 快速清空输入框","Ctrl+C - 强制终止程序","Ctrl+L - 清屏(保留历史)","Ctrl+R - 反向搜索历史","Ctrl+U - 清空当前行","/help - 查看完整帮助文档","/init - 生成 BLADE.md 项目配置","/resume - 恢复历史会话","/compact - 手动压缩上下文(节省 token)","/theme - 打开主题选择器","/config - 打开配置面板","/model - 管理与切换模型配置","/permissions - 管理工具权限规则","/mcp - 查看 MCP 服务器状态","/agents - 管理 Subagent 配置","/version - 显示版本信息","/clear - 清除屏幕内容","/status - 显示当前项目配置状态","/context - 可视化当前上下文使用情况","/cost - 显示会话成本统计","/exit - 退出 REPL","@ 文件路径 - 附加文件到上下文","@dir/ - 附加整个目录","@file.ts:10-20 - 附加指定行范围","Plan 模式 - 先规划后编码(/plan)","Auto Edit 模式 - 自动批准工具调用","MCP 协议 - 扩展外部工具集成","Subagents - 并行执行子任务","Hooks 系统 - 自定义工具执行流程","Context 压缩 - 自动总结历史对话","Loop 检测 - 防止无限循环","提示:使用 /init 让 AI 理解你的项目结构","提示:Plan 模式适合复杂多步骤任务","提示:Auto Edit 可加速重复性操作","提示:@ 引用可提供更精准的上下文","提示:定期 /compact 节省 token 成本","提示:使用 /permissions 控制工具权限","提示:Shift+Tab 快速切换模式","提示:Esc 可随时中断长时间任务","提示:/resume 继续未完成的对话","提示:/export 保存重要对话记录"];function hJ($,Y,Z=!1){let[X,Q]=jH("");return MH(()=>{if(Y){Q("等待用户确认...");return}if(!$){Q("");return}if(Z)return;let J=()=>{if(Math.random()<0.16666666666666666){let U=Math.floor(Math.random()*fJ.length);return fJ[U]}let G=Math.floor(Math.random()*CJ.length);return CJ[G]};Q(J());let q=setInterval(()=>{Q(J())},yH);return()=>{clearInterval(q)}},[$,Y,Z]),X}function pJ($,Y=!1,Z=!1){let[X,Q]=xJ(0),[J,q]=xJ(null),K=hJ($,Y,Z);return EH(()=>{if(!$){Q(0),q(null);return}if(Z)return;if(J===null)q(Date.now());let G=setInterval(()=>{if(J!==null){let U=Math.floor((Date.now()-J)/1000);Q(U)}},1000);return()=>{clearInterval(G)}},[$,J,Z]),{currentPhrase:K,elapsedTime:X}}import{jsxDEV as q0,Fragment as kH}from"react/jsx-dev-runtime";var V3=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"],SH=80;function uJ($){if($<60)return`${$}s`;let Y=Math.floor($/60),Z=$%60;return`${Y}m ${Z}s`}var gJ=vH.memo(({message:$,paused:Y=!1})=>{let Z=G2(),X=r4(),Q=Z||!X,[J,q]=TH(0),K=f1(),U=d2()>=SH,{currentPhrase:O,elapsedTime:W}=pJ(Q,!1,Y);if(PH(()=>{if(!Q||Y){q(0);return}let H=setInterval(()=>{q((z)=>(z+1)%V3.length)},80);return()=>clearInterval(H)},[Q,Y]),!Q)return null;let F=O||$||"正在思考中...";if(U)return q0(G8,{paddingX:2,paddingBottom:1,flexDirection:"row",gap:1,children:[q0(a0,{color:K.colors.warning,bold:!0,children:V3[J]},void 0,!1,void 0,this),q0(a0,{color:K.colors.text.primary,children:F},void 0,!1,void 0,this),W>0&&q0(kH,{children:[q0(a0,{color:K.colors.muted,children:"|"},void 0,!1,void 0,this),q0(a0,{color:K.colors.info,children:["已用时: ",uJ(W)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q0(a0,{color:K.colors.muted,children:"|"},void 0,!1,void 0,this),q0(a0,{color:K.colors.secondary,children:"Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return q0(G8,{paddingX:2,paddingBottom:1,flexDirection:"column",children:[q0(G8,{flexDirection:"row",gap:1,children:[q0(a0,{color:K.colors.warning,bold:!0,children:V3[J]},void 0,!1,void 0,this),q0(a0,{color:K.colors.text.primary,children:F},void 0,!1,void 0,this)]},void 0,!0,void 0,this),W>0&&q0(G8,{marginLeft:2,flexDirection:"row",gap:1,children:[q0(a0,{color:K.colors.info,children:["已用时: ",uJ(W)]},void 0,!0,void 0,this),q0(a0,{color:K.colors.muted,children:"|"},void 0,!1,void 0,this),q0(a0,{color:K.colors.secondary,children:"Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});import lH from"ansi-escapes";import{Box as Y6,Static as iH,useStdout as rH}from"ink";import aJ,{useEffect as nJ,useMemo as m6,useRef as aH}from"react";import{Box as CH,Text as dJ}from"ink";import fH from"react";import{jsxDEV as D3}from"react/jsx-dev-runtime";var I3=fH.memo(({collapsedCount:$})=>{let Y=f1();if($<=0)return null;let Z=Y.colors.text.muted;return D3(CH,{flexDirection:"row",marginBottom:1,children:[D3(dJ,{color:Z,children:["▶ ",$," 条历史消息"]},void 0,!0,void 0,this),D3(dJ,{color:Z,children:" [Ctrl+O 展开]"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});I3.displayName="CollapsedHistorySummary";q6();import{Box as g6,Text as d6}from"ink";import hH from"ink-big-text";import xH from"ink-gradient";import pH from"react";import{jsxDEV as S0}from"react/jsx-dev-runtime";var mJ=pH.memo(()=>{return S0(g6,{flexDirection:"column",paddingX:2,paddingTop:1,paddingBottom:1,children:[S0(g6,{flexDirection:"column",children:S0(xH,{name:"pastel",children:S0(hH,{text:"BLADE",font:"block"},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),S0(g6,{marginBottom:1,children:S0(d6,{color:"white",dimColor:!0,children:g3()},void 0,!1,void 0,this)},void 0,!1,void 0,this),S0(g6,{flexDirection:"column",marginBottom:1,children:[S0(g6,{marginBottom:1,children:S0(d6,{color:"white",bold:!0,children:"使用指南:"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S0(d6,{color:"white",children:"1. 输入问题、编辑文件或运行命令"},void 0,!1,void 0,this),S0(d6,{color:"white",children:"2. 使用 /init 创建项目配置文件"},void 0,!1,void 0,this),S0(d6,{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 M3,Text as $6}from"ink";import uH,{useMemo as cJ}from"react";import{jsxDEV as I2}from"react/jsx-dev-runtime";function gH($,Y=60){if(!$)return"";let Z=$.split(`
1888
+ `)[0]||"";if(Z.length<=Y)return Z;return`${Z.slice(0,Y)}...`}function dH($){if(!$)return 0;return $.split(`
1889
+ `).length}var j3=uH.memo(({content:$,isStreaming:Y=!1,isExpanded:Z})=>{let X=f1(),Q=cJ(()=>dH($),[$]),J=cJ(()=>gH($),[$]),q=X.colors.info,K=X.colors.muted;return I2(M3,{flexDirection:"column",marginBottom:1,children:[I2(M3,{flexDirection:"row",children:[I2($6,{color:q,children:Z?"▼":"▶"},void 0,!1,void 0,this),I2($6,{children:" "},void 0,!1,void 0,this),I2($6,{color:K,children:["Thinking",Y?"...":` (${Q} lines)`]},void 0,!0,void 0,this),!Z&&!Y&&J&&I2($6,{color:K,children:[" - ",J]},void 0,!0,void 0,this),I2($6,{color:K,dimColor:!0,children:[" ","[Ctrl+T]"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Z&&$&&I2(M3,{marginLeft:2,marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,paddingY:0,children:I2($6,{color:K,children:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});j3.displayName="ThinkingBlock";import{Box as U8,Text as y3}from"ink";B2();import{useState as lJ}from"react";function mH(){let[$,Y]=lJ(P1.getTheme()),[Z,X]=lJ(P1.getCurrentThemeName()),Q=(G)=>{try{P1.setTheme(G),Y(P1.getTheme()),X(G)}catch(U){console.error("Failed to change theme:",U)}},J=P1.getAvailableThemes();return{theme:$,themeName:Z,changeTheme:Q,availableThemes:J,hasTheme:(G)=>P1.hasTheme(G),getThemeByName:(G)=>P1.getThemeByName(G),colors:$.colors,spacing:$.spacing,typography:$.typography}}function iJ(){let{colors:$}=mH();return $}import{jsxDEV as m2}from"react/jsx-dev-runtime";var rJ=({todos:$,visible:Y=!0,compact:Z=!1})=>{let X=iJ();if(!Y||$.length===0)return null;let Q={total:$.length,completed:$.filter((J)=>J.status==="completed").length,inProgress:$.filter((J)=>J.status==="in_progress").length};return m2(U8,{flexDirection:"column",borderStyle:"single",borderColor:X.border.light,paddingX:1,paddingY:Z?0:1,marginBottom:1,children:[m2(U8,{marginBottom:Z?0:1,children:[m2(y3,{dimColor:!0,children:"Tasks "},void 0,!1,void 0,this),m2(y3,{color:X.text.muted,children:[Q.completed,"/",Q.total]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),m2(U8,{flexDirection:"column",children:$.map((J,q)=>m2(cH,{todo:J,compact:Z},J.id||q,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},cH=({todo:$,compact:Y})=>{let Z,X=!1,Q;switch($.status){case"completed":Z="✓",X=!0,Q=$.content;break;case"in_progress":Z="▶",X=!1,Q=$.activeForm;break;case"pending":default:Z="○",X=!0,Q=$.content;break}return m2(U8,{paddingY:Y?0:0,children:m2(y3,{dimColor:X,children:[Z," ",Q]},void 0,!0,void 0,this)},void 0,!1,void 0,this)};import{jsxDEV as A0}from"react/jsx-dev-runtime";var oJ=aJ.memo(()=>{let $=l4(),Y=G2(),Z=AQ(),X=DQ(),Q=EQ(),J=PQ(),q=TQ(),K=NQ(),G=kQ(),U=SQ(),O=d2(),{stdout:W}=rH(),F=aJ.useRef(0),H=aH(U);nJ(()=>{F.current=0},[K]),nJ(()=>{if(H.current!==U){if(W)W.write(lH.clearTerminal);F.current=0,H.current=U}},[U,W]);let{completedMessages:z,streamingMessage:N}=m6(()=>{let A=$.length>0?$[$.length-1]:null,D=Y&&A&&A.role==="assistant",w=Math.max(F.current,D?$.length-1:$.length);F.current=w;let R=$.slice(0,w),E=w<$.length?$[w]:null;return{completedMessages:R,streamingMessage:E}},[$,Y]),L=m6(()=>{return Z.some((A)=>A.status==="pending"||A.status==="in_progress")},[Z]),B=m6(()=>{if(U)return 0;return Math.max(0,$.length-G)},[$.length,G,U]),_=(A,D=!1)=>A0(Y6,{flexDirection:"column",children:A0(p6,{content:A.content,role:A.role,terminalWidth:O,metadata:A.metadata,isPending:D},void 0,!1,void 0,this)},A.id,!1,void 0,this),I=m6(()=>{return Math.min(B,z.length)},[B,z.length]),M=m6(()=>{let A=[];if(A.push(A0(mJ,{},"header",!1,void 0,this)),I>0)A.push(A0(I3,{collapsedCount:I},"collapsed-summary",!1,void 0,this));return z.forEach((D,w)=>{if(w>=B)A.push(_(D))}),A},[z,O,B,I]);return A0(Y6,{flexDirection:"column",flexGrow:1,paddingX:2,children:A0(Y6,{flexDirection:"column",flexGrow:1,children:[A0(iH,{items:M,children:(A)=>A},`${K}-${U}`,!1,void 0,this),J&&A0(Y6,{marginBottom:1,children:A0(j3,{content:J,isStreaming:Y,isExpanded:q},void 0,!1,void 0,this)},void 0,!1,void 0,this),N&&_(N,!0),X&&L&&A0(Y6,{marginTop:1,children:A0(rJ,{todos:Z,visible:!0,compact:!1},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q.map((A,D)=>A0(Y6,{flexDirection:"column",children:A0(p6,{content:A.displayText,role:"user",terminalWidth:O},void 0,!1,void 0,this)},`pending-${D}`,!1,void 0,this))]},void 0,!0,void 0,this)},void 0,!1,void 0,this)});A1();import{Box as q1,Text as i,useFocus as tJ,useFocusManager as nH,useInput as F8}from"ink";import oH from"ink-select-input";import sH from"ink-text-input";import{useEffect as tH,useState as c6}from"react";import{jsxDEV as v,Fragment as O8}from"react/jsx-dev-runtime";var eH=({isSelected:$})=>v(q1,{marginRight:1,children:v(i,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),$z=({isSelected:$,label:Y})=>v(i,{bold:$,color:$?"yellow":void 0,children:Y},void 0,!1,void 0,this);function Yz($){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";case"gpt-openai-platform":return"\uD83D\uDD37 GPT OpenAI Platform";default:return $}}function sJ($){switch($){case"anthropic":return"https://api.anthropic.com";case"gemini":return"https://generativelanguage.googleapis.com/v1beta";default:return null}}var Zz=({onSelect:$,onCancel:Y,initialProvider:Z})=>{let{isFocused:X}=tJ({id:"provider-step"});F8((q,K)=>{if(K.escape)Y()},{isActive:X});let Q=[{label:"⚡ OpenAI Compatible - 兼容 OpenAI API 的服务 (千问/豆包/DeepSeek/Ollama等)",value:"openai-compatible"},{label:"\uD83E\uDD16 Anthropic Claude - Claude 官方 API",value:"anthropic"},{label:"✨ Google Gemini - Gemini 官方 API",value:"gemini"},{label:"☁️ Azure OpenAI - 微软 Azure OpenAI 服务",value:"azure-openai"},{label:"\uD83D\uDD37 GPT OpenAI Platform - 字节跳动 GPT 平台 (内部)",value:"gpt-openai-platform"}],J=Z?Math.max(0,Q.findIndex((q)=>q.value===Z)):0;return v(q1,{flexDirection:"column",marginBottom:1,children:[v(q1,{marginBottom:1,children:v(i,{bold:!0,color:"blue",children:"\uD83D\uDCE1 Step 1: 选择 API 提供商"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(q1,{marginBottom:1,children:v(i,{children:"根据您使用的 LLM 服务选择对应的 API 类型"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(q1,{marginBottom:1,children:v(oH,{items:Q,onSelect:(q)=>$(q.value),indicatorComponent:eH,itemComponent:$z,initialIndex:J},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},W8=({stepNumber:$,icon:Y,title:Z,description:X,hint:Q,examples:J,value:q,placeholder:K,mask:G,previousValue:U,onChange:O,onSubmit:W,onCancel:F})=>{return F8((H,z)=>{if(z.escape)F()},{isActive:!0}),v(q1,{flexDirection:"column",marginBottom:1,children:[v(q1,{marginBottom:1,children:v(i,{bold:!0,color:"blue",children:[Y," Step ",$,": ",Z]},void 0,!0,void 0,this)},void 0,!1,void 0,this),v(q1,{marginBottom:1,children:v(i,{children:X},void 0,!1,void 0,this)},void 0,!1,void 0,this),U&&v(q1,{marginBottom:1,children:v(i,{color:"green",children:["✓ ",U]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q&&v(q1,{marginBottom:1,children:v(i,{dimColor:!0,children:Q},void 0,!1,void 0,this)},void 0,!1,void 0,this),J&&J.length>0&&v(O8,{children:[v(q1,{marginBottom:1,children:v(i,{dimColor:!0,children:"常见示例:"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(q1,{marginBottom:1,paddingLeft:2,children:v(i,{dimColor:!0,children:J.join(`
1890
+ `)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v(q1,{children:[v(i,{bold:!0,color:"cyan",children:["▶"," "]},void 0,!0,void 0,this),v(sH,{value:q,onChange:O,onSubmit:W,placeholder:K,mask:G},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},Xz=({mode:$,config:Y,isSaving:Z,stepNumber:X,onConfirm:Q,onBack:J,onCancel:q})=>{let{isFocused:K}=tJ({id:"confirm-step"});return F8((G,U)=>{if(Z)return;if(G==="y"||G==="Y")Q();else if(G==="n"||G==="N")J();else if(U.escape)q()},{isActive:K&&!Z}),v(q1,{flexDirection:"column",marginBottom:1,children:[v(q1,{marginBottom:1,children:v(i,{bold:!0,color:$==="edit"?"yellow":"blue",children:$==="edit"?"\uD83D\uDCBE 确认修改":`✅ Step ${X}: 确认配置`},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(q1,{marginBottom:1,children:v(i,{children:$==="edit"?"请确认修改内容,保存后将立即生效。":"请确认以下配置信息:"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(q1,{flexDirection:"column",marginBottom:1,paddingLeft:2,children:[v(q1,{marginBottom:1,children:[v(i,{dimColor:!0,children:"名称: "},void 0,!1,void 0,this),v(i,{bold:!0,color:"cyan",children:Y.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v(q1,{marginBottom:1,children:[v(i,{dimColor:!0,children:"Provider: "},void 0,!1,void 0,this),v(i,{bold:!0,color:"cyan",children:Yz(Y.provider)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v(q1,{marginBottom:1,children:[v(i,{dimColor:!0,children:"Base URL: "},void 0,!1,void 0,this),v(i,{bold:!0,color:"blue",children:Y.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v(q1,{marginBottom:1,children:[v(i,{dimColor:!0,children:"API Key: "},void 0,!1,void 0,this),v(i,{bold:!0,color:"yellow",children:[Y.apiKey?.slice(0,8),"*".repeat(Math.min(32,(Y.apiKey?.length||0)-8))]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),v(q1,{children:[v(i,{dimColor:!0,children:"Model: "},void 0,!1,void 0,this),v(i,{bold:!0,color:"cyan",children:Y.model},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),!Z&&v(q1,{marginTop:1,children:v(i,{children:[$==="edit"?"保存修改? ":"确认保存配置? ","[",v(i,{bold:!0,color:"green",children:"Y"},void 0,!1,void 0,this),"/",v(i,{bold:!0,color:"red",children:"n"},void 0,!1,void 0,this),"]"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Z&&v(q1,{children:v(i,{color:"yellow",children:"⏳ 正在保存配置到 ~/.blade/config.json..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},E3=({mode:$,initialConfig:Y,modelId:Z,onComplete:X,onCancel:Q})=>{let J=$==="edit",[q,K]=c6("provider"),[G,U]=c6(()=>J&&Y?{...Y}:{}),[O,W]=c6(""),[F,H]=c6(!1),[z,N]=c6(null),L=d1(!1);F8((k,n)=>{if(n.ctrl&&k==="c"||n.meta&&k==="c")if($==="setup")L();else Q()},{isActive:!0});let{focus:B}=nH();tH(()=>{if(q==="provider")B("provider-step");else if(q==="confirm")B("confirm-step")},[q,B]);let _=()=>{if(!O.trim()){N("配置名称不能为空");return}U({...G,name:O}),W(""),N(null),K("confirm")},I=(k)=>{U({...G,provider:k});let n=sJ(k),T=J?G.baseUrl??Y?.baseUrl??"":n??"";W(T),K("baseUrl")},M=()=>{if(!O.trim()){N("Base URL 不能为空");return}try{new URL(O)}catch{N("请输入有效的 URL (例如: https://api.openai.com/v1)");return}U({...G,baseUrl:O});let k=J?G.apiKey??Y?.apiKey??"":"";W(k),N(null),K("apiKey")},A=()=>{if(!O.trim()){N("API Key 不能为空");return}U({...G,apiKey:O});let k=J?G.model??Y?.model??"":"";W(k),N(null),K("model")},D=()=>{if(!O.trim()){N("Model 不能为空");return}U({...G,model:O});let k=J?G.name??Y?.name??"":"";W(k),N(null),K("name")},w=async()=>{H(!0),N(null);try{let k={name:G.name,provider:G.provider,baseUrl:G.baseUrl,apiKey:G.apiKey,model:G.model};if($==="setup")X(k);else if($==="add"){let n=await D1().addModel(k);await D1().setCurrentModel(n.id),X(k)}else{if(!Z)throw Error("未提供模型 ID,无法编辑");await D1().updateModel(Z,k),X(k)}}catch(k){N(k instanceof Error?k.message:"配置失败"),H(!1)}},R=()=>{switch(N(null),W(""),q){case"provider":Q();break;case"baseUrl":K("provider");break;case"apiKey":W(G.baseUrl||""),K("baseUrl");break;case"model":K("apiKey");break;case"name":W(G.model||""),K("model");break;case"confirm":W(G.name||""),K("name");break}},E=6,x=q==="provider"?1:q==="baseUrl"?2:q==="apiKey"?3:q==="model"?4:q==="name"?5:6,r=Math.floor((x-1)/(E-1)*40);return v(q1,{...$==="setup"?{flexDirection:"column",padding:1}:$==="add"?{flexDirection:"column",borderStyle:"round",borderColor:"blue",padding:1}:{flexDirection:"column",borderStyle:"round",borderColor:"yellow",padding:1},children:[$==="setup"?v(O8,{children:[v(q1,{marginBottom:1,children:v(i,{bold:!0,color:"blue",children:"\uD83D\uDE80 欢迎使用 Blade Code"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(q1,{marginBottom:1,children:v(i,{children:"AI 驱动的代码助手 - 让我们开始配置您的助手"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(q1,{marginBottom:1,children:[v(i,{bold:!0,color:"blue",children:"█".repeat(r)},void 0,!1,void 0,this),v(i,{dimColor:!0,children:"░".repeat(40-r)},void 0,!1,void 0,this),v(i,{children:" "},void 0,!1,void 0,this),v(i,{bold:!0,color:"cyan",children:[x,"/",E]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),v(q1,{marginBottom:1,children:v(i,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this):$==="add"?v(O8,{children:[v(q1,{justifyContent:"center",marginBottom:1,children:v(i,{bold:!0,color:"blue",children:"添加新模型配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(q1,{marginBottom:1,children:v(i,{children:["步骤: ",x,"/",E]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this):v(O8,{children:[v(q1,{justifyContent:"center",marginBottom:1,children:v(i,{bold:!0,color:"yellow",children:"编辑模型配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v(q1,{marginBottom:1,children:v(i,{children:["步骤: ",x,"/",E]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),q==="name"&&v(W8,{stepNumber:5,icon:"\uD83D\uDCDD",title:"配置名称",description:"给这个模型配置起一个易于识别的名称(可选,用于区分多个配置)",value:O,placeholder:"例如: 千问工作账号",onChange:W,onSubmit:_,onCancel:Q},void 0,!1,void 0,this),q==="provider"&&v(Zz,{onSelect:I,onCancel:Q,initialProvider:G.provider},void 0,!1,void 0,this),q==="baseUrl"&&v(W8,{stepNumber:2,icon:"\uD83C\uDF10",title:"配置 Base URL",description:"输入您的 API 端点地址(完整的 URL 包含协议)",hint:G.provider&&sJ(G.provider)?"\uD83D\uDCA1 已预填充官方 URL,直接回车使用。如需代理服务(如 OpenRouter),请修改。":void 0,examples:["• OpenAI: https://api.openai.com/v1","• Anthropic: https://api.anthropic.com","• Gemini: https://generativelanguage.googleapis.com/v1beta","• Azure: https://{resource}.openai.azure.com","• 代理: https://openrouter.ai/api/v1"],value:O,placeholder:"https://api.example.com/v1",onChange:W,onSubmit:M,onCancel:Q},void 0,!1,void 0,this),q==="apiKey"&&v(W8,{stepNumber:3,icon:"\uD83D\uDD11",title:"输入 API Key",description:"您的 API 密钥将被安全存储在 ~/.blade/config.json (权限 600)",hint:"\uD83D\uDCA1 提示: 输入时字符会被隐藏,支持粘贴 (Ctrl+V / Cmd+V)",previousValue:G.baseUrl?`✓ Base URL: ${G.baseUrl}`:void 0,value:O,placeholder:"sk-...",mask:"*",onChange:W,onSubmit:A,onCancel:Q},void 0,!1,void 0,this),q==="model"&&v(W8,{stepNumber:4,icon:"\uD83E\uDD16",title:"选择模型",description:"输入您想使用的模型名称(请参考您的 API 提供商文档)",examples:["• OpenAI: gpt-4o, gpt-4o-mini, o1-preview","• Claude: claude-sonnet-4-20250514, claude-opus-4-20250514","• Gemini: gemini-2.5-pro, gemini-2.5-flash","• Azure: {deployment-name}","• 千问: qwen3-max, qwen3-235b, qwen3-32b","• DeepSeek: deepseek-v3.1, deepseek-r1-0528"],value:O,placeholder:"例如: gpt-5",onChange:W,onSubmit:D,onCancel:Q},void 0,!1,void 0,this),q==="confirm"&&v(Xz,{mode:$,config:G,isSaving:F,stepNumber:E,onConfirm:w,onBack:R,onCancel:Q},void 0,!1,void 0,this),z&&v(q1,{marginTop:1,borderStyle:"round",borderColor:"red",paddingX:1,children:v(i,{color:"red",children:["❌ ",z]},void 0,!0,void 0,this)},void 0,!1,void 0,this),v(q1,{marginTop:1,children:v(i,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this),!F&&q==="provider"&&v(q1,{marginTop:1,children:v(i,{dimColor:!0,children:["\uD83D\uDCA1 使用 ",v(i,{bold:!0,children:"↑/↓"},void 0,!1,void 0,this)," 键选择,",v(i,{bold:!0,children:"Enter"},void 0,!1,void 0,this)," 确认,",v(i,{bold:!0,children:"Esc"},void 0,!1,void 0,this)," 取消"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),!F&&q!=="confirm"&&q!=="provider"&&v(q1,{marginTop:1,children:v(i,{dimColor:!0,children:["\uD83D\uDCA1 输入完成后按 ",v(i,{bold:!0,children:"Enter"},void 0,!1,void 0,this),",",v(i,{bold:!0,children:"Ctrl+C"},void 0,!1,void 0,this)," 退出"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),!F&&q==="confirm"&&v(q1,{marginTop:1,children:v(i,{dimColor:!0,children:["\uD83D\uDCA1 按"," ",v(i,{bold:!0,color:"green",children:"Y"},void 0,!1,void 0,this)," ","保存,",v(i,{bold:!0,color:"red",children:"N"},void 0,!1,void 0,this)," ","返回修改,",v(i,{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{useMemoizedFn as H8,useMount as Qz}from"ahooks";import{Box as k0,Text as L1,useFocus as Jz,useFocusManager as qz,useInput as Kz}from"ink";import Gz from"ink-select-input";import{memo as Uz,useMemo as Wz,useState as z8}from"react";A1();import{jsxDEV as Q1}from"react/jsx-dev-runtime";function Oz($){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";case"gpt-openai-platform":return"\uD83D\uDD37 GPT OpenAI Platform";default:return $}}var Fz=({isSelected:$})=>Q1(k0,{marginRight:1,children:Q1(L1,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),Hz=({isSelected:$,label:Y})=>Q1(L1,{bold:$,color:$?"yellow":void 0,children:Y},void 0,!1,void 0,this),eJ=Uz(({onClose:$,onEdit:Y})=>{let Z=IQ(),X=MQ()??"",{isFocused:Q}=Jz({id:"model-selector"}),J=qz(),[q,K]=z8(""),[G,U]=z8(!1),[O,W]=z8(null),F=d1(!1),[H]=z8(()=>{let D=process.stdout?.columns||80;return Math.max(20,D-8)});Qz(()=>{if(J?.focus("model-selector"),Z.length>0)K(Z[0].id)}),Kz((D,w)=>{if(G)return;if(w.ctrl&&D==="c"||w.meta&&D==="c"){F();return}if(w.escape){$();return}if(!Q)return;if(D==="d"||D==="D"){N();return}if((D==="e"||D==="E")&&Y)L()},{isActive:!0});let z=H8(async(D)=>{if(G)return;let w=D.value;if(w===X){$();return}U(!0),W(null);try{await D1().setCurrentModel(w),$()}catch(R){W(R.message),U(!1)}}),N=H8(async()=>{if(G||q===X)return;U(!0),W(null);try{if(await D1().removeModel(q),Z.length<=1)$()}catch(D){W(D.message)}finally{U(!1)}}),L=H8(()=>{if(G||!Y)return;let D=Z.find((w)=>w.id===q);if(!D)return;Y(D)}),B=H8((D)=>{K(D.value)}),_=Wz(()=>{return Z.find((D)=>D.id===q)},[Z,q]),I=Z.map((D)=>({label:D.name+(D.id===X?" (当前)":""),value:D.id})),M=q===X;return Q1(k0,{flexDirection:"column",borderStyle:"round",borderColor:"gray",padding:1,width:"100%",children:[Q1(k0,{flexDirection:"row",justifyContent:"space-between",marginBottom:1,children:[Q1(L1,{bold:!0,color:"cyan",children:"模型管理"},void 0,!1,void 0,this),Q1(L1,{dimColor:!0,children:[G?"⏳ 处理中...":M?"Enter=关闭 • E=编辑 • Esc=取消":"Enter=切换 • D=删除 • E=编辑 • Esc=取消"," • Ctrl+C=退出"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q1(k0,{flexDirection:"row",children:[Q1(k0,{flexDirection:"column",flexGrow:2,marginRight:2,borderStyle:"single",borderColor:"gray",padding:1,children:[Q1(L1,{dimColor:!0,children:["已配置模型 (",Z.length,")"]},void 0,!0,void 0,this),Q1(k0,{marginTop:1,children:Q1(Gz,{items:I,onSelect:z,onHighlight:B,indicatorComponent:Fz,itemComponent:Hz},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1(k0,{flexDirection:"column",flexGrow:3,borderStyle:"single",borderColor:"gray",padding:1,children:[Q1(L1,{dimColor:!0,children:"模型详情"},void 0,!1,void 0,this),Q1(k0,{marginY:1,children:Q1(L1,{color:M?"green":"yellow",children:M?"● 当前使用":"● 可切换"},void 0,!1,void 0,this)},void 0,!1,void 0,this),_?Q1(k0,{flexDirection:"column",children:[Q1(L1,{children:[Q1(L1,{dimColor:!0,children:"名称: "},void 0,!1,void 0,this),Q1(L1,{bold:!0,color:"cyan",children:_.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1(L1,{children:[Q1(L1,{dimColor:!0,children:"Provider: "},void 0,!1,void 0,this),Q1(L1,{bold:!0,children:Oz(_.provider)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1(L1,{children:[Q1(L1,{dimColor:!0,children:"Model: "},void 0,!1,void 0,this),Q1(L1,{bold:!0,children:_.model},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q1(L1,{children:[Q1(L1,{dimColor:!0,children:"Base URL: "},void 0,!1,void 0,this),Q1(L1,{color:"blueBright",children:_.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),_.temperature!==void 0&&Q1(L1,{children:[Q1(L1,{dimColor:!0,children:"Temperature: "},void 0,!1,void 0,this),Q1(L1,{children:_.temperature},void 0,!1,void 0,this)]},void 0,!0,void 0,this),_.maxContextTokens!==void 0&&Q1(L1,{children:[Q1(L1,{dimColor:!0,children:"Context Window: "},void 0,!1,void 0,this),Q1(L1,{children:_.maxContextTokens},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this):Q1(L1,{dimColor:!0,children:"请选择一个模型查看详情"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),O&&Q1(k0,{marginTop:1,children:Q1(L1,{color:"red",children:["❌ ",O]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q1(k0,{justifyContent:"center",marginTop:1,children:Q1(L1,{dimColor:!0,children:"─".repeat(H)},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q1(k0,{justifyContent:"center",children:Q1(L1,{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 l6}from"ahooks";import{promises as Xq}from"fs";import{Box as b0,Text as E1,useInput as zz}from"ink";import $q from"ink-select-input";import Nz from"ink-text-input";import Bz from"os";import N8 from"path";import{useEffect as _z,useMemo as B8,useRef as Lz,useState as c2}from"react";A1();import{jsxDEV as J1}from"react/jsx-dev-runtime";var i6=[{key:"allow",label:"Allow"},{key:"ask",label:"Ask"},{key:"deny",label:"Deny"},{key:"info",label:"Info"}],wz={allow:"Add a new rule...",ask:"Add a new rule...",deny:"Add a new rule..."},Az={allow:"Allow permission rules",ask:"Ask permission rules",deny:"Deny permission rules"},Yq={project:"[项目共享配置]",global:"[用户全局配置]",local:"[本地配置]"},bz=["project","global","local"],Rz={allow:[],ask:[],deny:[]},Vz={localExists:!1,projectExists:!1,globalExists:!1},Zq={allow:[],ask:[],deny:[]};function Dz($){let Y=(X)=>Array.isArray(X)?X.filter((Q)=>typeof Q==="string"):[],Z=$?.permissions??{};return{allow:Y(Z?.allow),ask:Y(Z?.ask),deny:Y(Z?.deny)}}async function Iz($){try{let Y=await Xq.readFile($,"utf-8"),Z=JSON.parse(Y);return{exists:!0,raw:Z,permissions:Dz(Z)}}catch(Y){if(Y.code==="ENOENT")return{exists:!1,raw:{},permissions:{...Zq}};return console.warn(`[PermissionsManager] Failed to read ${$}:`,Y),{exists:!0,raw:{},permissions:{...Zq}}}}function Mz($,Y){let Z=$.padEnd(32," "),X=Y==="local"?`${Yq[Y]} ← 可删除`:Yq[Y];return`${Z} ${X}`}var Qq=({onClose:$})=>{let Z=M0()==="permissions-manager",X=d1(!1),[Q,J]=c2(0),q=i6[Q].key,[K,G]=c2(Rz),[U,O]=c2(Vz),[W,F]=c2(!0),[H,z]=c2("list"),[N,L]=c2(""),[B,_]=c2(null),[I,M]=c2(null),A=Lz(!1),D=B8(()=>N8.join(process.cwd(),".blade","settings.local.json"),[]),w=B8(()=>N8.join(process.cwd(),".blade","settings.json"),[]),R=B8(()=>N8.join(Bz.homedir(),".blade","settings.json"),[]),E=l6(async()=>{F(!0);let G1=await Promise.all([{source:"local",path:D},{source:"project",path:w},{source:"global",path:R}].map(async({source:i1,path:H2})=>{let C0=await Iz(H2);return{source:i1,path:H2,...C0}})),t={localExists:G1.find((i1)=>i1.source==="local")?.exists??!1,projectExists:G1.find((i1)=>i1.source==="project")?.exists??!1,globalExists:G1.find((i1)=>i1.source==="global")?.exists??!1};O(t);let G0={allow:[],ask:[],deny:[]},i2=Object.fromEntries(G1.map((i1)=>[i1.source,i1]));["allow","ask","deny"].forEach((i1)=>{bz.forEach((H2)=>{(i2[H2]?.permissions[i1]??[]).forEach((X6,o0)=>{let r2={key:`${H2}:${o0}:${X6}`,rule:X6,source:H2};G0[i1].push(r2)})})}),G(G0),F(!1)});_z(()=>{E()},[E]);let x=l6(async(g,G1)=>{try{let t=N8.join(process.cwd(),".blade","settings.local.json"),G0={allow:[],ask:[],deny:[]};try{let i1=await Xq.readFile(t,"utf-8"),C0=JSON.parse(i1).permissions||{};G0={allow:Array.isArray(C0.allow)?C0.allow:[],ask:Array.isArray(C0.ask)?C0.ask:[],deny:Array.isArray(C0.deny)?C0.deny:[]}}catch(i1){}let i2=G1(G0);await D1().updateConfig({permissions:i2},{scope:"local",immediate:!0}),await E()}catch(t){throw console.error("[PermissionsManager] 修改权限规则失败:",t),t}});zz((g,G1)=>{if(G1.ctrl&&g==="c"||G1.meta&&g==="c"){X();return}if(H==="locked"){if(A.current){A.current=!1;return}z("list"),_(null),M(null);return}if(G1.escape){if(H==="list"||q==="info")$();else z("list"),L(""),_(null),M(null);return}if(H==="list"){if(G1.tab&&G1.shift)J((t)=>(t-1+i6.length)%i6.length);else if(G1.tab)J((t)=>(t+1)%i6.length);else if(g?.toLowerCase()==="q")$()}},{isActive:Z});let r=l6((g)=>{let G1=g.value;if(q==="info")return;if(G1.type==="add"){z("add"),L(""),M(null);return}if(G1.entry.source!=="local"){z("locked"),A.current=!0,_({tab:q,entry:G1.entry}),M({type:"error",text:G1.entry.source==="project"?"此规则定义在项目共享配置中,无法在此删除。":"此规则来自用户全局配置,无法在此删除。"});return}z("confirm-delete"),_({tab:q,entry:G1.entry}),M(null)}),P=l6(async()=>{if(q==="info")return;let g=N.trim();if(!g){M({type:"error",text:"Permission rule 不能为空"});return}if(K[q].map((t)=>t.rule).includes(g)){M({type:"error",text:"该规则已存在"});return}try{await x(q,(t)=>{let G0={allow:[...t.allow],ask:[...t.ask],deny:[...t.deny]};return G0[q]=[...new Set([...t[q],g])],G0}),z("list"),L(""),M({type:"success",text:"已添加本地权限规则"})}catch(t){M({type:"error",text:`保存失败: ${t instanceof Error?t.message:"未知错误"}`})}}),k=l6(async()=>{if(!B)return;let{tab:g,entry:G1}=B;try{await x(g,(t)=>{let G0={allow:[...t.allow],ask:[...t.ask],deny:[...t.deny]};return G0[g]=t[g].filter((i2)=>i2!==G1.rule),G0}),z("list"),_(null),M({type:"success",text:"已删除本地权限规则"})}catch(t){M({type:"error",text:`删除失败: ${t instanceof Error?t.message:"未知错误"}`})}}),n=B8(()=>{if(q==="info")return[];let g=q;return[{key:"add-new-rule",label:`› ${wz[g]}`,value:{type:"add"}},...K[g].map((t)=>({key:t.key,label:Mz(t.rule,t.source),value:{type:"rule",entry:t}}))]},[q,K]),T=()=>J1(b0,{marginBottom:1,children:i6.map((g,G1)=>J1(b0,{marginRight:2,children:J1(E1,{color:G1===Q?"yellow":"gray",children:["[",g.label,"]"]},void 0,!0,void 0,this)},g.key,!1,void 0,this))},void 0,!1,void 0,this),C=()=>J1(b0,{flexDirection:"column",gap:1,children:[J1(E1,{children:"配置文件优先级(从高到低):"},void 0,!1,void 0,this),J1(b0,{flexDirection:"column",marginLeft:2,children:[J1(E1,{children:["1. .blade/settings.local.json (本地配置,不提交 Git)"," ",U.localExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),J1(E1,{children:["2. .blade/settings.json (项目配置,提交 Git)"," ",U.projectExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),J1(E1,{children:["3. ~/.blade/settings.json (用户全局配置)"," ",U.globalExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),J1(E1,{children:"说明:"},void 0,!1,void 0,this),J1(b0,{flexDirection:"column",marginLeft:2,children:[J1(E1,{children:"- /permissions 命令只管理本地配置 (.blade/settings.local.json)"},void 0,!1,void 0,this),J1(E1,{children:"- 修改全局或项目配置请直接编辑对应文件"},void 0,!1,void 0,this),J1(E1,{children:"- 本地配置不会提交到 Git"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),j=(g)=>J1(b0,{flexDirection:"column",gap:1,children:[J1(E1,{bold:!0,children:Az[g]},void 0,!1,void 0,this),J1(E1,{children:"Permission rules are a tool name, optionally followed by a specifier in parentheses."},void 0,!1,void 0,this),J1(E1,{color:"gray",children:"例如: WebFetch 或 Bash(ls:*)"},void 0,!1,void 0,this),J1(b0,{marginTop:1,children:J1(Nz,{value:N,onChange:L,onSubmit:P},void 0,!1,void 0,this)},void 0,!1,void 0,this),J1(E1,{color:"gray",children:"Enter 提交 · Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),S1=(g,G1)=>J1(b0,{flexDirection:"column",gap:1,children:[J1(E1,{bold:!0,children:["Delete ",g," permission rule?"]},void 0,!0,void 0,this),J1(E1,{children:G1.rule},void 0,!1,void 0,this),J1(E1,{color:"gray",children:"From project local settings"},void 0,!1,void 0,this),J1(E1,{children:"Are you sure you want to delete this permission rule?"},void 0,!1,void 0,this),J1($q,{items:[{label:"Yes",value:"yes"},{label:"No",value:"no"}],onSelect:(t)=>{if(t.value==="yes")k();else z("list"),_(null)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),d=(g)=>J1(b0,{flexDirection:"column",gap:1,children:[J1(E1,{bold:!0,children:"Cannot delete this rule"},void 0,!1,void 0,this),J1(E1,{children:g.rule},void 0,!1,void 0,this),J1(E1,{color:"gray",children:g.source==="project"?"This rule is defined in .blade/settings.json. 请手动编辑该文件以移除规则。":"This rule is defined in ~/.blade/settings.json. 请手动编辑该文件以移除规则。"},void 0,!1,void 0,this),J1(E1,{color:"gray",children:"按任意键继续"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),e=(g)=>J1($q,{items:n,isFocused:H==="list",onSelect:r},void 0,!1,void 0,this),B1=()=>{if(W)return J1(E1,{children:"加载中..."},void 0,!1,void 0,this);if(q==="info")return C();if(H==="add")return j(q);if(H==="confirm-delete"&&B)return S1(B.tab,B.entry);if(H==="locked"&&B)return d(B.entry);return e(q)};return J1(b0,{flexDirection:"column",borderStyle:"round",borderColor:Z?"cyan":"gray",padding:1,width:80,children:[J1(E1,{color:"cyan",bold:!0,children:"⚙️ 权限管理器"},void 0,!1,void 0,this),T(),J1(b0,{flexDirection:"column",gap:1,children:B1()},void 0,!1,void 0,this),I&&J1(b0,{marginTop:1,children:J1(E1,{color:I.type==="success"?"green":"red",children:I.text},void 0,!1,void 0,this)},void 0,!1,void 0,this),J1(b0,{marginTop:1,children:J1(E1,{color:"gray",children:"Tab 切换视图 · Esc 关闭 · Q 退出"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};p4();import{Box as Z6,Text as n0,useInput as jz}from"ink";import yz from"ink-select-input";import{useEffect as Jq,useMemo as _8,useState as v3}from"react";import{jsxDEV as o1}from"react/jsx-dev-runtime";function Ez($){let Y=new Date($),X=new Date().getTime()-Y.getTime(),Q=Math.floor(X/86400000);if(Q===0)return`今天 ${Y.getHours().toString().padStart(2,"0")}:${Y.getMinutes().toString().padStart(2,"0")}`;if(Q===1)return"昨天";if(Q<7)return`${Q}天前`;return`${Y.getMonth()+1}/${Y.getDate()}`}function vz($){let Y=$.split("/");return Y[Y.length-1]||$}var Pz=({isSelected:$})=>o1(Z6,{marginRight:1,children:o1(n0,{color:$?"cyan":"gray",children:$?"❯":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),Tz=({isSelected:$,label:Y})=>o1(n0,{color:$?"cyan":"white",bold:$,children:Y},void 0,!1,void 0,this),r6=20,qq=({sessions:$,onSelect:Y,onCancel:Z})=>{let[X,Q]=v3([]),[J,q]=v3(!1),[K,G]=v3(0),O=M0()==="session-selector",W=d1(!1);jz((_,I)=>{if(I.ctrl&&_==="c"||I.meta&&_==="c"){W();return}if(I.escape&&Z){Z();return}if(I.leftArrow||_==="h"||_==="H"){if(K>0)G((M)=>M-1);return}if(I.rightArrow||_==="l"||_==="L"){if(K<z-1)G((M)=>M+1);return}},{isActive:O}),Jq(()=>{if($){Q($);return}(async()=>{q(!0);try{let I=await q2.listSessions();Q(I)}catch(I){console.error("[SessionSelector] Failed to load sessions:",I),Q([])}finally{q(!1)}})()},[$]);let F=$||X,H=_8(()=>{return F.map((_)=>{let I=vz(_.projectPath),M=Ez(_.lastMessageTime),A=_.gitBranch?` (${_.gitBranch})`:"",D=_.hasErrors?" ⚠️":"";return{label:`\uD83D\uDCC5 ${M} | ${I}${A} | ${_.messageCount} 条消息${D}`,value:_.sessionId}})},[F]),z=_8(()=>Math.max(1,Math.ceil(H.length/r6)),[H.length]),N=_8(()=>{let _=K*r6;return H.slice(_,_+r6)},[H,K]),L=_8(()=>({start:K*r6+1,end:Math.min((K+1)*r6,H.length)}),[K,H.length]);Jq(()=>{G(0)},[F.length]);let B=(_)=>{Y(_.value)};if(J)return o1(Z6,{flexDirection:"column",paddingX:2,paddingY:1,children:o1(n0,{children:"⏳ 正在加载会话列表..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(F.length===0)return o1(Z6,{flexDirection:"column",paddingX:2,paddingY:1,children:[o1(n0,{color:"yellow",children:"⚠️ 没有找到历史会话"},void 0,!1,void 0,this),o1(n0,{dimColor:!0,children:[`
1891
+ `,"提示: 开始一次对话后,会话历史将保存到 ~/.blade/projects/"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this);return o1(Z6,{flexDirection:"column",paddingX:2,paddingY:1,children:[o1(n0,{bold:!0,color:"cyan",children:"\uD83D\uDCC2 选择要恢复的会话:"},void 0,!1,void 0,this),o1(n0,{dimColor:!0,children:[`
1890
1892
  `,"(←→ 翻页 | ↑↓ 选择 | Enter 确认 | Esc 取消)",`
1891
- `]},void 0,!0,void 0,this),a1(q_,{items:z,onSelect:B,indicatorComponent:U_,itemComponent:W_},void 0,!1,void 0,this),a1(e$,{marginTop:1,flexDirection:"column",children:[a1(i0,{dimColor:!0,children:["第 ",G+1,"/",_," 页 · 共 ",F.length," 个会话 · 显示"," ",L.start,"-",L.end]},void 0,!0,void 0,this),_>1&&a1(e$,{marginTop:1,children:[a1(i0,{color:G>0?"cyan":"gray",children:G>0?"◀ ← 上一页":" "},void 0,!1,void 0,this),a1(i0,{children:" "},void 0,!1,void 0,this),a1(i0,{color:G<_-1?"cyan":"gray",children:G<_-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)};j2();import{Box as S1,Text as L1,useInput as O_}from"ink";import{jsxDEV as a}from"react/jsx-dev-runtime";function mJ({onCancel:$}){let Z=$0().getAll(),X=Z.filter((G)=>G.source==="builtin"),Q=Z.filter((G)=>G.source==="user"),J=Z.filter((G)=>G.source==="project"),q=p1(!1,$);if(O_((G,K)=>{if(K.escape)$?.();else if(K.ctrl&&G==="c"||K.meta&&G==="c")q()}),Z.length===0)return a(S1,{flexDirection:"column",paddingY:1,children:[a(S1,{marginBottom:1,children:a(L1,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this)},void 0,!1,void 0,this),a(S1,{paddingLeft:2,children:a(L1,{color:"gray",children:"没有找到任何 Skill"},void 0,!1,void 0,this)},void 0,!1,void 0,this),a(S1,{marginTop:1,paddingLeft:2,children:a(L1,{color:"gray",children:"配置文件位置: ~/.blade/skills/ 或 .blade/skills/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),a(S1,{marginTop:1,children:a(L1,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return a(S1,{flexDirection:"column",paddingY:1,children:[a(S1,{marginBottom:1,children:[a(L1,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this),a(L1,{color:"gray",children:[" (找到 ",Z.length," 个)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),J.length>0&&a(S1,{flexDirection:"column",marginBottom:1,children:[a(S1,{paddingLeft:1,children:[a(L1,{bold:!0,color:"yellow",children:"项目级"},void 0,!1,void 0,this),a(L1,{color:"gray",children:" (.blade/skills/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J.map((G)=>{let W=G.description.length>80?`${G.description.substring(0,80)}...`:G.description;return a(S1,{flexDirection:"column",paddingLeft:2,children:[a(L1,{children:[a(L1,{bold:!0,color:"green",children:["• ",G.name]},void 0,!0,void 0,this),a(L1,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),G.allowedTools&&G.allowedTools.length>0&&a(S1,{paddingLeft:2,children:a(L1,{color:"gray",children:["工具: ",G.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),a(S1,{paddingLeft:2,children:a(L1,{color:"gray",dimColor:!0,children:G.path},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},G.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.length>0&&a(S1,{flexDirection:"column",marginBottom:1,children:[a(S1,{paddingLeft:1,children:[a(L1,{bold:!0,color:"yellow",children:"用户级"},void 0,!1,void 0,this),a(L1,{color:"gray",children:" (~/.blade/skills/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.map((G)=>{let W=G.description.length>80?`${G.description.substring(0,80)}...`:G.description;return a(S1,{flexDirection:"column",paddingLeft:2,children:[a(L1,{children:[a(L1,{bold:!0,color:"green",children:["• ",G.name]},void 0,!0,void 0,this),a(L1,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),G.allowedTools&&G.allowedTools.length>0&&a(S1,{paddingLeft:2,children:a(L1,{color:"gray",children:["工具: ",G.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),a(S1,{paddingLeft:2,children:a(L1,{color:"gray",dimColor:!0,children:G.path},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},G.name,!0,void 0,this)})]},void 0,!0,void 0,this),X.length>0&&a(S1,{flexDirection:"column",marginBottom:1,children:[a(S1,{paddingLeft:1,children:[a(L1,{bold:!0,color:"cyan",children:"内置"},void 0,!1,void 0,this),a(L1,{color:"gray",children:" (builtin)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X.map((G)=>{let W=G.description.length>80?`${G.description.substring(0,80)}...`:G.description;return a(S1,{flexDirection:"column",paddingLeft:2,children:[a(L1,{children:[a(L1,{bold:!0,color:"green",children:["• ",G.name]},void 0,!0,void 0,this),a(L1,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),G.userInvocable&&a(S1,{paddingLeft:2,children:a(L1,{color:"blue",children:["命令: /",G.name]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},G.name,!0,void 0,this)})]},void 0,!0,void 0,this),a(S1,{marginTop:1,children:a(L1,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}import{useMemoizedFn as F_}from"ahooks";import{Box as K2,Text as p,useInput as H_}from"ink";import __ from"ink-select-input";import{useState as dJ}from"react";N1();D9();H2();H2();import{jsxDEV as h}from"react/jsx-dev-runtime";var cJ=r0.map(($)=>({label:$.label,value:$.id})),z_=({theme:$})=>{let{colors:Y}=$;return h(K2,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[h(p,{bold:!0,color:Y.text.primary,children:"代码预览"},void 0,!1,void 0,this),h(p,{children:" "},void 0,!1,void 0,this),h(p,{color:Y.syntax.comment,children:"# function"},void 0,!1,void 0,this),h(p,{children:[h(p,{color:Y.syntax.keyword,children:"def"},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.function,children:"fibonacci"},void 0,!1,void 0,this),h(p,{color:Y.text.primary,children:"("},void 0,!1,void 0,this),h(p,{color:Y.syntax.variable,children:"n"},void 0,!1,void 0,this),h(p,{color:Y.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h(p,{children:[" ",h(p,{color:Y.syntax.variable,children:"a"},void 0,!1,void 0,this),h(p,{color:Y.syntax.operator,children:","},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.operator,children:"="},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.number,children:"0"},void 0,!1,void 0,this),h(p,{color:Y.syntax.operator,children:","},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.number,children:"1"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h(p,{children:[" ",h(p,{color:Y.syntax.keyword,children:"for"},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.variable,children:"_"},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.keyword,children:"in"},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.function,children:"range"},void 0,!1,void 0,this),h(p,{color:Y.text.primary,children:"("},void 0,!1,void 0,this),h(p,{color:Y.syntax.variable,children:"n"},void 0,!1,void 0,this),h(p,{color:Y.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h(p,{children:[" ",h(p,{color:Y.syntax.variable,children:"a"},void 0,!1,void 0,this),h(p,{color:Y.syntax.operator,children:","},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.operator,children:"="},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.variable,children:"b"},void 0,!1,void 0,this),h(p,{color:Y.syntax.operator,children:","},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.variable,children:"a"},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.operator,children:"+"},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.variable,children:"b"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h(p,{children:[" ",h(p,{color:Y.syntax.keyword,children:"return"},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.variable,children:"a"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h(p,{children:" "},void 0,!1,void 0,this),h(p,{color:Y.error,children:["- print(",h(p,{color:Y.syntax.string,children:'"Hello, "'},void 0,!1,void 0,this)," + name)"]},void 0,!0,void 0,this),h(p,{color:Y.success,children:["+ print(",h(p,{color:Y.syntax.string,children:['f"Hello, ',"{","name","}",'"']},void 0,!0,void 0,this),")"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},N_=({theme:$})=>{let{colors:Y}=$;return h(K2,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[h(p,{children:" "},void 0,!1,void 0,this),h(p,{bold:!0,color:Y.text.primary,children:"颜色配置"},void 0,!1,void 0,this),h(p,{children:" "},void 0,!1,void 0,this),h(p,{children:[h(p,{color:Y.text.muted,children:"Primary: "},void 0,!1,void 0,this),h(p,{color:Y.primary,children:Y.primary},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h(p,{children:[h(p,{color:Y.text.muted,children:"Success: "},void 0,!1,void 0,this),h(p,{color:Y.success,children:Y.success},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h(p,{children:[h(p,{color:Y.text.muted,children:"Error: "},void 0,!1,void 0,this),h(p,{color:Y.error,children:Y.error},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h(p,{children:[h(p,{color:Y.text.muted,children:"Warning: "},void 0,!1,void 0,this),h(p,{color:Y.warning,children:Y.warning},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h(p,{children:[h(p,{color:Y.text.muted,children:"Info: "},void 0,!1,void 0,this),h(p,{color:Y.info,children:Y.info},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},lJ=()=>{let $=x2(),Y=j1.getCurrentThemeName(),Z=r0.findIndex((_)=>_.label===Y),X=Z>=0?r0[Z].theme:r0[0].theme,[Q,J]=dJ(X),[q,G]=dJ(!1),K=F_(async(_)=>{if(q)return;G(!0);try{await A1().setTheme(_.value),$.closeModal()}catch(z){console.error("❌ 主题切换失败:",z instanceof Error?z.message:z)}finally{G(!1)}}),W=(_)=>{let z=r0.find((L)=>L.id===_.value);if(z)J(z.theme)},U=V0()==="theme-selector",F=p1(!1);H_((_,z)=>{if(z.ctrl&&_==="c"||z.meta&&_==="c"){F();return}if(z.escape&&!q)$.closeModal()},{isActive:U});let H=(_)=>{let{isSelected:z,label:L}=_,N=L===Y?"✓":" ";return h(p,{color:z?Q.colors.primary:Q.colors.text.primary,children:[N," ",L]},void 0,!0,void 0,this)};return h(K2,{flexDirection:"column",height:"100%",children:[h(K2,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:Q.colors.border.light,children:h(p,{bold:!0,color:Q.colors.primary,children:"\uD83C\uDFA8 主题选择器"},void 0,!1,void 0,this)},void 0,!1,void 0,this),h(K2,{flexDirection:"row",flexGrow:1,children:[h(K2,{width:"40%",borderStyle:"single",borderColor:Q.colors.border.light,paddingX:1,children:h(K2,{flexDirection:"column",children:[h(K2,{paddingTop:1,paddingBottom:1,children:h(p,{bold:!0,color:Q.colors.text.primary,children:["可用主题 (",cJ.length,")"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),h(__,{items:cJ,initialIndex:Z>=0?Z:0,onSelect:K,onHighlight:W,itemComponent:H},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),h(K2,{width:"60%",flexDirection:"column",borderStyle:"single",borderColor:Q.colors.border.light,children:[h(z_,{theme:Q},void 0,!1,void 0,this),h(N_,{theme:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),h(K2,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:Q.colors.border.light,children:h(p,{color:Q.colors.text.muted,children:q?"正在保存...":"Enter: 选择主题 | Esc: 取消"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as E1}from"react/jsx-dev-runtime";var w0=n("UI"),iJ=({debug:$,...Y})=>{if($)w0.debug("[Debug] BladeInterface props:",{permissionMode:Y.permissionMode,yolo:Y.yolo,maxTurns:Y.maxTurns});let Z=z9(!1),X=z9(!1),Q=z9(!1),J=z9(null),q=$Q(),G=YQ(),K=d4(),W=QQ(),O=XQ(),U=x2(),F=u$(),H=UQ(),_=m$(),z=J2(),{exit:L}=B_(),B=q==="ready",N=q==="needsSetup",I=q==="idle",{confirmationState:M,confirmationHandler:A,handleResponse:D}=DQ(),{executeCommand:w,handleAbort:R}=AQ(Y.systemPrompt,Y.appendSystemPrompt,A,Y.maxTurns),{getPreviousCommand:E,getNextCommand:x,addToHistory:r}=RQ();fQ();let j=MQ("",0),C=H0(async()=>{let Z1=_,w1;if(Z1==="default")w1="autoEdit";else if(Z1==="autoEdit")w1="plan";else w1="default";try{await A1().setPermissionMode(w1)}catch(k0){w0.error("❌ 权限模式切换失败:",k0 instanceof Error?k0.message:k0)}}),Y1=H0(async(Z1)=>{try{await A1().addModel({name:Z1.name,provider:Z1.provider,apiKey:Z1.apiKey,baseUrl:Z1.baseUrl,model:Z1.model}),U.setInitializationStatus("ready")}catch(w1){w0.error("❌ 初始化配置保存失败:",w1 instanceof Error?w1.message:w1),U.setInitializationStatus("ready")}}),k=H0(()=>{if(K==="shortcuts")U.closeModal();else U.setActiveModal("shortcuts")}),{showSuggestions:S,suggestions:y,selectedSuggestionIndex:v1}=CQ(j,w,E,x,r,R,z,C,k,K==="shortcuts");U$(()=>{if(j.value&&K==="shortcuts")U.closeModal()},[j.value,K,U]);let m=H0(async()=>{try{if(typeof Y.resume==="string"&&Y.resume!=="true"){let w1=await X2.loadSession(Y.resume),k0=w1.map((O2,Y6)=>({id:`restored-${Date.now()}-${Y6}`,role:O2.role,content:typeof O2.content==="string"?O2.content:JSON.stringify(O2.content),timestamp:Date.now()-(w1.length-Y6)*1000}));F.restoreSession(Y.resume,k0);return}let Z1=await X2.listSessions();if(Z1.length===0)w0.error("没有找到历史会话"),x$(1);U.showSessionSelector(Z1)}catch(Z1){w0.error("[BladeInterface] 加载会话失败:",Z1),x$(1)}});U$(()=>{if(Z.current)return;if(!Y.resume)return;Z.current=!0,m()},[Y.resume,m]);let t=H0(async(Z1)=>{let w1=M.details?.type;if(w1==="enterPlanMode"&&Z1.approved)try{await A1().setPermissionMode("plan"),w0.debug("[BladeInterface] Entered Plan mode")}catch(k0){w0.error("[BladeInterface] Failed to enter Plan mode:",k0)}if(w1==="exitPlanMode"&&Z1.approved)w0.debug("[BladeInterface] ExitPlanMode approved, Store auto-synced");D(Z1)}),_1=H0(()=>{F.addAssistantMessage("❌ 设置已取消"),F.addAssistantMessage("Blade 需要 API 配置才能正常工作。"),F.addAssistantMessage("您可以稍后运行 Blade 重新进入设置向导。"),x$(0)}),g=H0(()=>{U.closeModal()}),K1=H0(async(Z1)=>{try{let w1=await X2.loadSession(Z1),k0=w1.map((O2,Y6)=>({id:`restored-${Date.now()}-${Y6}`,role:O2.role,content:typeof O2.content==="string"?O2.content:JSON.stringify(O2.content),timestamp:Date.now()-(w1.length-Y6)*1000}));F.restoreSession(Z1,k0),U.closeModal()}catch(w1){w0.error("[BladeInterface] Failed to restore session:",w1),U.closeModal()}}),s=H0(()=>{if(Y.resume)L();else U.closeModal()}),J0=H0((Z1)=>{U.showModelEditWizard(Z1)}),d2=H0((Z1)=>{F.addAssistantMessage(`✅ 已添加模型配置: ${Z1.name},并已切换到该模型`),g()}),d1=H0((Z1)=>{F.addAssistantMessage(`✅ 已更新模型配置: ${Z1.name}`),g()});U$(()=>{if(N){H.setFocus("model-config-wizard");return}if(M.isVisible)H.setFocus("confirmation-prompt");else if(K==="sessionSelector")H.setFocus("session-selector");else if(K==="themeSelector")H.setFocus("theme-selector");else if(K==="modelSelector")H.setFocus("model-selector");else if(K==="modelAddWizard"||K==="modelEditWizard")H.setFocus("model-config-wizard");else if(K==="permissionsManager")H.setFocus("permissions-manager");else if(K==="agentsManager")H.setFocus("agents-manager");else if(K==="agentCreationWizard")H.setFocus("agent-creation-wizard");else if(K==="hooksManager")H.setFocus("hooks-manager");else if(K==="shortcuts")H.setFocus("main-input");else H.setFocus("main-input")},[N,M.isVisible,K,H.setFocus]),U$(()=>{if(!B||Q.current)return;if($5().length>0){Q.current=!0;return}Q.current=!0,F.addAssistantMessage("请输入您的问题,我将为您提供帮助。")},[B]),U$(()=>{if(!G)return;if(J.current===G)return;if(J.current=G,q==="error")F.addAssistantMessage(`❌ 初始化失败: ${G}`);else F.addAssistantMessage(`❌ ${G}`),F.addAssistantMessage("请重新尝试设置,或检查文件权限")},[G,q,F.addAssistantMessage]);let W2=H0(async(Z1)=>{try{await w({displayText:Z1,text:Z1,images:[],parts:[{type:"text",text:Z1}]})}catch(w1){let k0=w1 instanceof Error?w1.message:"无法发送初始消息";F.addAssistantMessage(`❌ 初始消息发送失败:${k0}`)}});U$(()=>{let Z1=Y.initialMessage?.trim();if(!Z1||X.current||!B||N)return;X.current=!0,r(Z1),W2(Z1)},[Y.initialMessage,B,N,w,r]);let T0=H0(async(Z1)=>{try{await A1().setPermissionMode(Z1)}catch(w1){w0.error("❌ 权限模式初始化失败:",w1 instanceof Error?w1.message:w1)}});if(U$(()=>{let Z1=Y.permissionMode;if($)w0.debug("[Debug] permissionMode from CLI:",Z1),w0.debug("[Debug] current permissionMode:",_);if(!Z1||Z1===_)return;T0(Z1)},[Y.permissionMode,_]),I)return null;if(N)return E1(A3,{mode:"setup",onComplete:Y1,onCancel:_1},void 0,!1,void 0,this);if($)w0.debug("[Debug] 渲染主界面,条件检查:",{confirmationVisible:M.isVisible,activeModal:K});let $6=K==="modelSelector",a0=O,c2=K==="modelAddWizard"?"add":K==="modelEditWizard"&&a0?"edit":null,Zq=$6||Boolean(c2),Xq=K==="agentsManager",Qq=K==="agentCreationWizard",Jq=K==="skillsManager",qq=a0?{name:a0.name,provider:a0.provider,baseUrl:a0.baseUrl,apiKey:a0.apiKey,model:a0.model}:void 0,j3=M.isVisible&&M.details?E1(XJ,{details:M.details,onResponse:t},void 0,!1,void 0,this):K==="themeSelector"?E1(lJ,{},void 0,!1,void 0,this):K==="permissionsManager"?E1(pJ,{onClose:g},void 0,!1,void 0,this):K==="sessionSelector"?E1(uJ,{sessions:W,onSelect:K1,onCancel:s},void 0,!1,void 0,this):K==="hooksManager"?E1(JJ,{onClose:g},void 0,!1,void 0,this):null,y3=Boolean(j3);return E1(K$,{flexDirection:"column",width:"100%",overflow:"hidden",children:[j3,E1(K$,{flexDirection:"column",display:y3?"none":"flex",children:[E1(TJ,{},void 0,!1,void 0,this),E1(VJ,{paused:y3},void 0,!1,void 0,this),E1(NJ,{input:j.value,cursorPosition:j.cursorPosition,onChange:j.setValue,onChangeCursorPosition:j.setCursorPosition,onAddPasteMapping:j.addPasteMapping,onAddImagePasteMapping:j.addImagePasteMapping},void 0,!1,void 0,this),$6&&E1(K$,{marginTop:1,paddingX:2,children:E1(SJ,{onClose:g,onEdit:J0},void 0,!1,void 0,this)},void 0,!1,void 0,this),c2&&E1(K$,{marginTop:1,paddingX:2,children:E1(A3,{mode:c2,modelId:a0?.id,initialConfig:c2==="edit"?qq:void 0,onComplete:c2==="edit"?d1:d2,onCancel:g},void 0,!1,void 0,this)},void 0,!1,void 0,this),Xq&&E1(K$,{marginTop:1,paddingX:2,children:E1(gQ,{onComplete:g,onCancel:g},void 0,!1,void 0,this)},void 0,!1,void 0,this),Qq&&E1(K$,{marginTop:1,paddingX:2,children:E1(T6,{onComplete:g,onCancel:g},void 0,!1,void 0,this)},void 0,!1,void 0,this),Jq&&E1(K$,{marginTop:1,paddingX:2,children:E1(mJ,{onComplete:g,onCancel:g},void 0,!1,void 0,this)},void 0,!1,void 0,this),E1(cQ,{suggestions:y,selectedIndex:v1,visible:S&&!Zq},void 0,!1,void 0,this),E1(dQ,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{Box as L_,Text as m2}from"ink";import w_ from"react";import{jsxDEV as V2}from"react/jsx-dev-runtime";class N9 extends w_.Component{constructor($){super($);this.state={hasError:!1,error:null,errorInfo:null}}static getDerivedStateFromError($){return{hasError:!0,error:$,errorInfo:null}}componentDidCatch($,Y){this.setState({error:$,errorInfo:Y}),console.error("未捕获的错误:",$,Y)}render(){if(this.state.hasError)return V2(L_,{flexDirection:"column",padding:1,borderStyle:"round",borderColor:"red",children:[V2(m2,{color:"red",children:"\uD83D\uDCA5 应用发生错误"},void 0,!1,void 0,this),V2(m2,{children:" "},void 0,!1,void 0,this),V2(m2,{color:"red",children:this.state.error?.message},void 0,!1,void 0,this),V2(m2,{children:" "},void 0,!1,void 0,this),V2(m2,{color:"gray",children:"错误详情:"},void 0,!1,void 0,this),V2(m2,{color:"gray",children:this.state.error?.stack},void 0,!1,void 0,this),V2(m2,{children:" "},void 0,!1,void 0,this),V2(m2,{color:"yellow",children:"请重启应用或联系开发者"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return this.props.children}}import{Box as W$,Text as D2,useInput as A_}from"ink";import{useState as R3}from"react";import{jsxDEV as Q0}from"react/jsx-dev-runtime";var B9=[{key:"update",label:"Update now",description:`runs \`${T7()}\``},{key:"skip",label:"Skip",description:""},{key:"skip_until_next",label:"Skip until next version",description:""}],aJ=({versionInfo:$,onComplete:Y})=>{let[Z,X]=R3(0),[Q,J]=R3(!1),[q,G]=R3(null);A_((W,O)=>{if(O.ctrl&&W==="c"){$$().shutdown("SIGINT",0);return}if(Q||q)return;if(O.upArrow||W==="k")X((U)=>U>0?U-1:B9.length-1);else if(O.downArrow||W==="j")X((U)=>U<B9.length-1?U+1:0);else if(O.return)K(B9[Z].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 O=await rZ();G(O.message),setTimeout(()=>{$$().shutdown("SIGINT",0)},1500);break}case"skip":Y();break;case"skip_until_next":if($.latestVersion)await aZ($.latestVersion);Y();break}};if(q)return Q0(W$,{flexDirection:"column",marginY:1,children:Q0(D2,{children:q},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(Q)return Q0(W$,{flexDirection:"column",marginY:1,children:Q0(D2,{color:"cyan",children:"Updating..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);return Q0(W$,{flexDirection:"column",marginY:1,children:[Q0(D2,{color:"yellow",bold:!0,children:["✨ Update available! ",Q0(D2,{color:"gray",children:[$.currentVersion," ","→"," ",$.latestVersion]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Q0(W$,{marginTop:1,children:Q0(D2,{color:"gray",children:["Release notes:"," ",Q0(D2,{color:"cyan",underline:!0,children:$.releaseNotesUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q0(W$,{flexDirection:"column",marginTop:1,children:B9.map((W,O)=>{let U=O===Z,F=U?"› ":" ",H=`${O+1}. `;return Q0(W$,{children:Q0(D2,{color:U?"cyan":void 0,children:[F,H,W.label,W.description&&Q0(D2,{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),Q0(W$,{marginTop:1,children:Q0(D2,{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)};H2();function l6($){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 L9}from"react/jsx-dev-runtime";function R_($){if(e().config.actions.setConfig($),!$.models||$.models.length===0){if($.debug)console.log("[Debug] 未检测到模型配置,进入设置向导");C0().setInitializationStatus("needsSetup");return}if($.debug)console.log("[Debug] 模型配置检查通过,准备就绪");C0().setInitializationStatus("ready")}var nJ=($)=>{let[Y,Z]=V3(!1),[X,Q]=V3(null),[J,q]=V3(!1),G=rJ(async()=>{let W=e().config.config??F$,O=R9(W,$);if(R_(O),O.debug)console.error("[Debug] 运行时配置:",O);let U=O.theme;if(U&&j1.hasTheme(U)){if(j1.setTheme(U),$.debug)console.log(`✓ 已加载主题: ${U}`)}try{let F=x1.loadFromStandardLocations();if($.debug&&F>0)console.log(`✓ 已加载 ${F} 个 subagents: ${x1.getAllNames().join(", ")}`)}catch(F){if($.debug)console.warn("⚠️ Subagents 加载失败:",l6(F))}try{let F=H1.getInstance();if(F.loadConfig(O.hooks||{}),$.debug&&O.hooks?.enabled)console.log("✓ Hooks 系统已启用");if(F.isEnabled()){let H=e(),_=H.session.sessionId,z=H.config.config?.permissionMode||"default",L=!!$.resume,B=await F.executeSessionStartHooks({projectDir:process.cwd(),sessionId:_,permissionMode:z,isResume:L,resumeSessionId:typeof $.resume==="string"?$.resume:void 0});if(B.env){for(let[N,I]of Object.entries(B.env))process.env[N]=I;if($.debug)console.log("✓ SessionStart hooks 注入环境变量:",Object.keys(B.env).join(", "))}if(B.warning&&$.debug)console.warn("⚠️ SessionStart hooks 警告:",B.warning)}}catch(F){if($.debug)console.warn("⚠️ Hooks 初始化失败:",l6(F))}try{let F=await a2();if($.debug&&F.skills.length>0)console.log(`✓ 已加载 ${F.skills.length} 个 skills: ${F.skills.map((H)=>H.name).join(", ")}`);if(F.errors.length>0&&$.debug)for(let H of F.errors)console.warn(`⚠️ Skill 加载错误 (${H.path}): ${H.error}`)}catch(F){if($.debug)console.warn("⚠️ Skills 初始化失败:",l6(F))}try{let F=await aX(process.cwd());if($.debug&&F.commands.length>0)console.log(`✓ 已加载 ${F.commands.length} 个自定义命令: ${F.commands.map((H)=>H.name).join(", ")}`);if(F.errors.length>0&&$.debug)for(let H of F.errors)console.warn(`⚠️ 自定义命令加载错误 (${H.path}): ${H.error}`)}catch(F){if($.debug)console.warn("⚠️ 自定义命令初始化失败:",l6(F))}tZ(async()=>{F0.getInstance().killAll(),await n1.getInstance().disconnectAll(),H1.getInstance().cleanup()}),Z(!0)}),K=rJ(async()=>{if($.versionCheckPromise){let W=await $.versionCheckPromise;if(W){Q(W),q(!0);return}}await G()});if(b_(()=>{K()},[]),J&&X)return L9(N9,{children:L9(aJ,{versionInfo:X,onComplete:()=>{q(!1),G()}},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(!Y)return null;return L9(N9,{children:L9(iJ,{...$},void 0,!1,void 0,this)},void 0,!1,void 0,this)};var M3=Yq(process.argv),$q=M3.indexOf("--debug");if($q!==-1){let $=M3[$q+1],Y=$&&!$.startsWith("-")?$:!0;S0.setGlobalDebug(Y)}async function T_(){eZ();let $=nZ();if(await uZ())return;if(M3.includes("--acp")){let{runAcpIntegration:Z}=await Promise.resolve().then(() => (eJ(),tJ));await Z();return}let Y=P_(Yq(process.argv)).scriptName(l2.scriptName).usage(l2.usage).version(l2.version).locale(l2.locale).showHelpOnFail(l2.showHelpOnFail).demandCommand(0,"").recommendCommands().strict(l2.strict).parserConfiguration({"populate--":!0}).options(k3).middleware([Y5,Z5,X5]).command(A5).command(Q5).command(oZ).command(J5).completion("completion",!1).help("help","Show help").alias("help","h").alias("version","V").fail((Z,X,Q)=>{if(X)console.error("\uD83D\uDCA5 An error occurred:"),console.error(X.message),console.error(`
1893
+ `]},void 0,!0,void 0,this),o1(yz,{items:N,onSelect:B,indicatorComponent:Pz,itemComponent:Tz},void 0,!1,void 0,this),o1(Z6,{marginTop:1,flexDirection:"column",children:[o1(n0,{dimColor:!0,children:["第 ",K+1,"/",z," 页 · 共 ",F.length," 个会话 · 显示"," ",L.start,"-",L.end]},void 0,!0,void 0,this),z>1&&o1(Z6,{marginTop:1,children:[o1(n0,{color:K>0?"cyan":"gray",children:K>0?"◀ ← 上一页":" "},void 0,!1,void 0,this),o1(n0,{children:" "},void 0,!1,void 0,this),o1(n0,{color:K<z-1?"cyan":"gray",children:K<z-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)};v2();import{Box as h1,Text as R1,useInput as Sz}from"ink";import{jsxDEV as o}from"react/jsx-dev-runtime";function Kq({onCancel:$}){let Z=X0().getAll(),X=Z.filter((K)=>K.source==="builtin"),Q=Z.filter((K)=>K.source==="user"),J=Z.filter((K)=>K.source==="project"),q=d1(!1,$);if(Sz((K,G)=>{if(G.escape)$?.();else if(G.ctrl&&K==="c"||G.meta&&K==="c")q()}),Z.length===0)return o(h1,{flexDirection:"column",paddingY:1,children:[o(h1,{marginBottom:1,children:o(R1,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(h1,{paddingLeft:2,children:o(R1,{color:"gray",children:"没有找到任何 Skill"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(h1,{marginTop:1,paddingLeft:2,children:o(R1,{color:"gray",children:"配置文件位置: ~/.blade/skills/ 或 .blade/skills/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(h1,{marginTop:1,children:o(R1,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return o(h1,{flexDirection:"column",paddingY:1,children:[o(h1,{marginBottom:1,children:[o(R1,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this),o(R1,{color:"gray",children:[" (找到 ",Z.length," 个)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),J.length>0&&o(h1,{flexDirection:"column",marginBottom:1,children:[o(h1,{paddingLeft:1,children:[o(R1,{bold:!0,color:"yellow",children:"项目级"},void 0,!1,void 0,this),o(R1,{color:"gray",children:" (.blade/skills/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J.map((K)=>{let U=K.description.length>80?`${K.description.substring(0,80)}...`:K.description;return o(h1,{flexDirection:"column",paddingLeft:2,children:[o(R1,{children:[o(R1,{bold:!0,color:"green",children:["• ",K.name]},void 0,!0,void 0,this),o(R1,{color:"gray",children:[" - ",U]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),K.allowedTools&&K.allowedTools.length>0&&o(h1,{paddingLeft:2,children:o(R1,{color:"gray",children:["工具: ",K.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),o(h1,{paddingLeft:2,children:o(R1,{color:"gray",dimColor:!0,children:K.path},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},K.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.length>0&&o(h1,{flexDirection:"column",marginBottom:1,children:[o(h1,{paddingLeft:1,children:[o(R1,{bold:!0,color:"yellow",children:"用户级"},void 0,!1,void 0,this),o(R1,{color:"gray",children:" (~/.blade/skills/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.map((K)=>{let U=K.description.length>80?`${K.description.substring(0,80)}...`:K.description;return o(h1,{flexDirection:"column",paddingLeft:2,children:[o(R1,{children:[o(R1,{bold:!0,color:"green",children:["• ",K.name]},void 0,!0,void 0,this),o(R1,{color:"gray",children:[" - ",U]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),K.allowedTools&&K.allowedTools.length>0&&o(h1,{paddingLeft:2,children:o(R1,{color:"gray",children:["工具: ",K.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),o(h1,{paddingLeft:2,children:o(R1,{color:"gray",dimColor:!0,children:K.path},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},K.name,!0,void 0,this)})]},void 0,!0,void 0,this),X.length>0&&o(h1,{flexDirection:"column",marginBottom:1,children:[o(h1,{paddingLeft:1,children:[o(R1,{bold:!0,color:"cyan",children:"内置"},void 0,!1,void 0,this),o(R1,{color:"gray",children:" (builtin)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X.map((K)=>{let U=K.description.length>80?`${K.description.substring(0,80)}...`:K.description;return o(h1,{flexDirection:"column",paddingLeft:2,children:[o(R1,{children:[o(R1,{bold:!0,color:"green",children:["• ",K.name]},void 0,!0,void 0,this),o(R1,{color:"gray",children:[" - ",U]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),K.userInvocable&&o(h1,{paddingLeft:2,children:o(R1,{color:"blue",children:["命令: /",K.name]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},K.name,!0,void 0,this)})]},void 0,!0,void 0,this),o(h1,{marginTop:1,children:o(R1,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}import{useMemoizedFn as kz}from"ahooks";import{Box as O2,Text as p,useInput as Cz}from"ink";import fz from"ink-select-input";import{useState as Gq}from"react";A1();j8();B2();B2();import{jsxDEV as h}from"react/jsx-dev-runtime";var Uq=s0.map(($)=>({label:$.label,value:$.id})),hz=({theme:$})=>{let{colors:Y}=$;return h(O2,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[h(p,{bold:!0,color:Y.text.primary,children:"代码预览"},void 0,!1,void 0,this),h(p,{children:" "},void 0,!1,void 0,this),h(p,{color:Y.syntax.comment,children:"# function"},void 0,!1,void 0,this),h(p,{children:[h(p,{color:Y.syntax.keyword,children:"def"},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.function,children:"fibonacci"},void 0,!1,void 0,this),h(p,{color:Y.text.primary,children:"("},void 0,!1,void 0,this),h(p,{color:Y.syntax.variable,children:"n"},void 0,!1,void 0,this),h(p,{color:Y.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h(p,{children:[" ",h(p,{color:Y.syntax.variable,children:"a"},void 0,!1,void 0,this),h(p,{color:Y.syntax.operator,children:","},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.operator,children:"="},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.number,children:"0"},void 0,!1,void 0,this),h(p,{color:Y.syntax.operator,children:","},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.number,children:"1"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h(p,{children:[" ",h(p,{color:Y.syntax.keyword,children:"for"},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.variable,children:"_"},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.keyword,children:"in"},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.function,children:"range"},void 0,!1,void 0,this),h(p,{color:Y.text.primary,children:"("},void 0,!1,void 0,this),h(p,{color:Y.syntax.variable,children:"n"},void 0,!1,void 0,this),h(p,{color:Y.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h(p,{children:[" ",h(p,{color:Y.syntax.variable,children:"a"},void 0,!1,void 0,this),h(p,{color:Y.syntax.operator,children:","},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.operator,children:"="},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.variable,children:"b"},void 0,!1,void 0,this),h(p,{color:Y.syntax.operator,children:","},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.variable,children:"a"},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.operator,children:"+"},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.variable,children:"b"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h(p,{children:[" ",h(p,{color:Y.syntax.keyword,children:"return"},void 0,!1,void 0,this)," ",h(p,{color:Y.syntax.variable,children:"a"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h(p,{children:" "},void 0,!1,void 0,this),h(p,{color:Y.error,children:["- print(",h(p,{color:Y.syntax.string,children:'"Hello, "'},void 0,!1,void 0,this)," + name)"]},void 0,!0,void 0,this),h(p,{color:Y.success,children:["+ print(",h(p,{color:Y.syntax.string,children:['f"Hello, ',"{","name","}",'"']},void 0,!0,void 0,this),")"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},xz=({theme:$})=>{let{colors:Y}=$;return h(O2,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[h(p,{children:" "},void 0,!1,void 0,this),h(p,{bold:!0,color:Y.text.primary,children:"颜色配置"},void 0,!1,void 0,this),h(p,{children:" "},void 0,!1,void 0,this),h(p,{children:[h(p,{color:Y.text.muted,children:"Primary: "},void 0,!1,void 0,this),h(p,{color:Y.primary,children:Y.primary},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h(p,{children:[h(p,{color:Y.text.muted,children:"Success: "},void 0,!1,void 0,this),h(p,{color:Y.success,children:Y.success},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h(p,{children:[h(p,{color:Y.text.muted,children:"Error: "},void 0,!1,void 0,this),h(p,{color:Y.error,children:Y.error},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h(p,{children:[h(p,{color:Y.text.muted,children:"Warning: "},void 0,!1,void 0,this),h(p,{color:Y.warning,children:Y.warning},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h(p,{children:[h(p,{color:Y.text.muted,children:"Info: "},void 0,!1,void 0,this),h(p,{color:Y.info,children:Y.info},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},Wq=()=>{let $=g2(),Y=P1.getCurrentThemeName(),Z=s0.findIndex((z)=>z.label===Y),X=Z>=0?s0[Z].theme:s0[0].theme,[Q,J]=Gq(X),[q,K]=Gq(!1),G=kz(async(z)=>{if(q)return;K(!0);try{await D1().setTheme(z.value),$.closeModal()}catch(N){console.error("❌ 主题切换失败:",N instanceof Error?N.message:N)}finally{K(!1)}}),U=(z)=>{let N=s0.find((L)=>L.id===z.value);if(N)J(N.theme)},W=M0()==="theme-selector",F=d1(!1);Cz((z,N)=>{if(N.ctrl&&z==="c"||N.meta&&z==="c"){F();return}if(N.escape&&!q)$.closeModal()},{isActive:W});let H=(z)=>{let{isSelected:N,label:L}=z,_=L===Y?"✓":" ";return h(p,{color:N?Q.colors.primary:Q.colors.text.primary,children:[_," ",L]},void 0,!0,void 0,this)};return h(O2,{flexDirection:"column",height:"100%",children:[h(O2,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:Q.colors.border.light,children:h(p,{bold:!0,color:Q.colors.primary,children:"\uD83C\uDFA8 主题选择器"},void 0,!1,void 0,this)},void 0,!1,void 0,this),h(O2,{flexDirection:"row",flexGrow:1,children:[h(O2,{width:"40%",borderStyle:"single",borderColor:Q.colors.border.light,paddingX:1,children:h(O2,{flexDirection:"column",children:[h(O2,{paddingTop:1,paddingBottom:1,children:h(p,{bold:!0,color:Q.colors.text.primary,children:["可用主题 (",Uq.length,")"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),h(fz,{items:Uq,initialIndex:Z>=0?Z:0,onSelect:G,onHighlight:U,itemComponent:H},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),h(O2,{width:"60%",flexDirection:"column",borderStyle:"single",borderColor:Q.colors.border.light,children:[h(hz,{theme:Q},void 0,!1,void 0,this),h(xz,{theme:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),h(O2,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:Q.colors.border.light,children:h(p,{color:Q.colors.text.muted,children:q?"正在保存...":"Enter: 选择主题 | Esc: 取消"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as k1}from"react/jsx-dev-runtime";var R0=c("UI"),Oq=({debug:$,...Y})=>{if($)R0.debug("[Debug] BladeInterface props:",{permissionMode:Y.permissionMode,yolo:Y.yolo,maxTurns:Y.maxTurns});let Z=L8(!1),X=L8(!1),Q=L8(!1),J=L8(null),q=LQ(),K=wQ(),G=i4(),U=RQ(),O=bQ(),W=g2(),F=c$(),H=jQ(),z=l$(),N=G2(),{exit:L}=pz(),B=q==="ready",_=q==="needsSetup",I=q==="idle",{confirmationState:M,confirmationHandler:A,handleResponse:D}=dQ(),{executeCommand:w,handleAbort:R}=xQ(Y.systemPrompt,Y.appendSystemPrompt,A,Y.maxTurns),{getPreviousCommand:E,getNextCommand:x,addToHistory:r}=uQ();$J();let P=cQ("",0),k=B0(async()=>{let Z1=z,V1;if(Z1==="default")V1="autoEdit";else if(Z1==="autoEdit")V1="plan";else V1="default";try{await D1().setPermissionMode(V1)}catch(f0){R0.error("❌ 权限模式切换失败:",f0 instanceof Error?f0.message:f0)}}),n=B0(async(Z1)=>{try{await D1().addModel({name:Z1.name,provider:Z1.provider,apiKey:Z1.apiKey,baseUrl:Z1.baseUrl,model:Z1.model}),W.setInitializationStatus("ready")}catch(V1){R0.error("❌ 初始化配置保存失败:",V1 instanceof Error?V1.message:V1),W.setInitializationStatus("ready")}}),T=B0(()=>{if(G==="shortcuts")W.closeModal();else W.setActiveModal("shortcuts")}),{showSuggestions:C,suggestions:j,selectedSuggestionIndex:S1}=eQ(P,w,E,x,r,R,N,k,T,G==="shortcuts");F$(()=>{if(P.value&&G==="shortcuts")W.closeModal()},[P.value,G,W]);let d=B0(async()=>{try{if(typeof Y.resume==="string"&&Y.resume!=="true"){let V1=await q2.loadSession(Y.resume),f0=V1.map((z2,Q6)=>({id:`restored-${Date.now()}-${Q6}`,role:z2.role,content:typeof z2.content==="string"?z2.content:JSON.stringify(z2.content),timestamp:Date.now()-(V1.length-Q6)*1000}));F.restoreSession(Y.resume,f0);return}let Z1=await q2.listSessions();if(Z1.length===0)R0.error("没有找到历史会话"),g$(1);W.showSessionSelector(Z1)}catch(Z1){R0.error("[BladeInterface] 加载会话失败:",Z1),g$(1)}});F$(()=>{if(Z.current)return;if(!Y.resume)return;Z.current=!0,d()},[Y.resume,d]);let e=B0(async(Z1)=>{let V1=M.details?.type;if(V1==="enterPlanMode"&&Z1.approved)try{await D1().setPermissionMode("plan"),R0.debug("[BladeInterface] Entered Plan mode")}catch(f0){R0.error("[BladeInterface] Failed to enter Plan mode:",f0)}if(V1==="exitPlanMode"&&Z1.approved)R0.debug("[BladeInterface] ExitPlanMode approved, Store auto-synced");D(Z1)}),B1=B0(()=>{F.addAssistantMessage("❌ 设置已取消"),F.addAssistantMessage("Blade 需要 API 配置才能正常工作。"),F.addAssistantMessage("您可以稍后运行 Blade 重新进入设置向导。"),g$(0)}),g=B0(()=>{W.closeModal()}),G1=B0(async(Z1)=>{try{let V1=await q2.loadSession(Z1),f0=V1.map((z2,Q6)=>({id:`restored-${Date.now()}-${Q6}`,role:z2.role,content:typeof z2.content==="string"?z2.content:JSON.stringify(z2.content),timestamp:Date.now()-(V1.length-Q6)*1000}));F.restoreSession(Z1,f0),W.closeModal()}catch(V1){R0.error("[BladeInterface] Failed to restore session:",V1),W.closeModal()}}),t=B0(()=>{if(Y.resume)L();else W.closeModal()}),G0=B0((Z1)=>{W.showModelEditWizard(Z1)}),i2=B0((Z1)=>{F.addAssistantMessage(`✅ 已添加模型配置: ${Z1.name},并已切换到该模型`),g()}),i1=B0((Z1)=>{F.addAssistantMessage(`✅ 已更新模型配置: ${Z1.name}`),g()});F$(()=>{if(_){H.setFocus("model-config-wizard");return}if(M.isVisible)H.setFocus("confirmation-prompt");else if(G==="sessionSelector")H.setFocus("session-selector");else if(G==="themeSelector")H.setFocus("theme-selector");else if(G==="modelSelector")H.setFocus("model-selector");else if(G==="modelAddWizard"||G==="modelEditWizard")H.setFocus("model-config-wizard");else if(G==="permissionsManager")H.setFocus("permissions-manager");else if(G==="agentsManager")H.setFocus("agents-manager");else if(G==="agentCreationWizard")H.setFocus("agent-creation-wizard");else if(G==="hooksManager")H.setFocus("hooks-manager");else if(G==="shortcuts")H.setFocus("main-input");else H.setFocus("main-input")},[_,M.isVisible,G,H.setFocus]),F$(()=>{if(!B||Q.current)return;if(U5().length>0){Q.current=!0;return}Q.current=!0,F.addAssistantMessage("请输入您的问题,我将为您提供帮助。")},[B]),F$(()=>{if(!K)return;if(J.current===K)return;if(J.current=K,q==="error")F.addAssistantMessage(`❌ 初始化失败: ${K}`);else F.addAssistantMessage(`❌ ${K}`),F.addAssistantMessage("请重新尝试设置,或检查文件权限")},[K,q,F.addAssistantMessage]);let H2=B0(async(Z1)=>{try{await w({displayText:Z1,text:Z1,images:[],parts:[{type:"text",text:Z1}]})}catch(V1){let f0=V1 instanceof Error?V1.message:"无法发送初始消息";F.addAssistantMessage(`❌ 初始消息发送失败:${f0}`)}});F$(()=>{let Z1=Y.initialMessage?.trim();if(!Z1||X.current||!B||_)return;X.current=!0,r(Z1),H2(Z1)},[Y.initialMessage,B,_,w,r]);let C0=B0(async(Z1)=>{try{await D1().setPermissionMode(Z1)}catch(V1){R0.error("❌ 权限模式初始化失败:",V1 instanceof Error?V1.message:V1)}});if(F$(()=>{let Z1=Y.permissionMode;if($)R0.debug("[Debug] permissionMode from CLI:",Z1),R0.debug("[Debug] current permissionMode:",z);if(!Z1||Z1===z)return;C0(Z1)},[Y.permissionMode,z]),I)return null;if(_)return k1(E3,{mode:"setup",onComplete:n,onCancel:B1},void 0,!1,void 0,this);if($)R0.debug("[Debug] 渲染主界面,条件检查:",{confirmationVisible:M.isVisible,activeModal:G});let X6=G==="modelSelector",o0=O,r2=G==="modelAddWizard"?"add":G==="modelEditWizard"&&o0?"edit":null,bq=X6||Boolean(r2),Rq=G==="agentsManager",Vq=G==="agentCreationWizard",Dq=G==="skillsManager",Iq=o0?{name:o0.name,provider:o0.provider,baseUrl:o0.baseUrl,apiKey:o0.apiKey,model:o0.model}:void 0,f3=M.isVisible&&M.details?k1(bJ,{details:M.details,onResponse:e},void 0,!1,void 0,this):G==="themeSelector"?k1(Wq,{},void 0,!1,void 0,this):G==="permissionsManager"?k1(Qq,{onClose:g},void 0,!1,void 0,this):G==="sessionSelector"?k1(qq,{sessions:U,onSelect:G1,onCancel:t},void 0,!1,void 0,this):G==="hooksManager"?k1(VJ,{onClose:g},void 0,!1,void 0,this):null,h3=Boolean(f3);return k1(O$,{flexDirection:"column",width:"100%",overflow:"hidden",children:[f3,k1(O$,{flexDirection:"column",display:h3?"none":"flex",children:[k1(oJ,{},void 0,!1,void 0,this),k1(gJ,{paused:h3},void 0,!1,void 0,this),k1(kJ,{input:P.value,cursorPosition:P.cursorPosition,onChange:P.setValue,onChangeCursorPosition:P.setCursorPosition,onAddPasteMapping:P.addPasteMapping,onAddImagePasteMapping:P.addImagePasteMapping},void 0,!1,void 0,this),X6&&k1(O$,{marginTop:1,paddingX:2,children:k1(eJ,{onClose:g,onEdit:G0},void 0,!1,void 0,this)},void 0,!1,void 0,this),r2&&k1(O$,{marginTop:1,paddingX:2,children:k1(E3,{mode:r2,modelId:o0?.id,initialConfig:r2==="edit"?Iq:void 0,onComplete:r2==="edit"?i1:i2,onCancel:g},void 0,!1,void 0,this)},void 0,!1,void 0,this),Rq&&k1(O$,{marginTop:1,paddingX:2,children:k1(QJ,{onComplete:g,onCancel:g},void 0,!1,void 0,this)},void 0,!1,void 0,this),Vq&&k1(O$,{marginTop:1,paddingX:2,children:k1(C6,{onComplete:g,onCancel:g},void 0,!1,void 0,this)},void 0,!1,void 0,this),Dq&&k1(O$,{marginTop:1,paddingX:2,children:k1(Kq,{onComplete:g,onCancel:g},void 0,!1,void 0,this)},void 0,!1,void 0,this),k1(GJ,{suggestions:j,selectedIndex:S1,visible:C&&!bq},void 0,!1,void 0,this),k1(KJ,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{Box as uz,Text as l2}from"ink";import gz from"react";import{jsxDEV as M2}from"react/jsx-dev-runtime";class w8 extends gz.Component{constructor($){super($);this.state={hasError:!1,error:null,errorInfo:null}}static getDerivedStateFromError($){return{hasError:!0,error:$,errorInfo:null}}componentDidCatch($,Y){this.setState({error:$,errorInfo:Y}),console.error("未捕获的错误:",$,Y)}render(){if(this.state.hasError)return M2(uz,{flexDirection:"column",padding:1,borderStyle:"round",borderColor:"red",children:[M2(l2,{color:"red",children:"\uD83D\uDCA5 应用发生错误"},void 0,!1,void 0,this),M2(l2,{children:" "},void 0,!1,void 0,this),M2(l2,{color:"red",children:this.state.error?.message},void 0,!1,void 0,this),M2(l2,{children:" "},void 0,!1,void 0,this),M2(l2,{color:"gray",children:"错误详情:"},void 0,!1,void 0,this),M2(l2,{color:"gray",children:this.state.error?.stack},void 0,!1,void 0,this),M2(l2,{children:" "},void 0,!1,void 0,this),M2(l2,{color:"yellow",children:"请重启应用或联系开发者"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return this.props.children}}import{Box as H$,Text as j2,useInput as dz}from"ink";import{useState as P3}from"react";import{jsxDEV as K0}from"react/jsx-dev-runtime";var A8=[{key:"update",label:"Update now",description:`runs \`${g7()}\``},{key:"skip",label:"Skip",description:""},{key:"skip_until_next",label:"Skip until next version",description:""}],Fq=({versionInfo:$,onComplete:Y})=>{let[Z,X]=P3(0),[Q,J]=P3(!1),[q,K]=P3(null);dz((U,O)=>{if(O.ctrl&&U==="c"){X$().shutdown("SIGINT",0);return}if(Q||q)return;if(O.upArrow||U==="k")X((W)=>W>0?W-1:A8.length-1);else if(O.downArrow||U==="j")X((W)=>W<A8.length-1?W+1:0);else if(O.return)G(A8[Z].key);else if(U==="1")G("update");else if(U==="2")G("skip");else if(U==="3")G("skip_until_next")});let G=async(U)=>{switch(U){case"update":{J(!0);let O=await FX();K(O.message),setTimeout(()=>{X$().shutdown("SIGINT",0)},1500);break}case"skip":Y();break;case"skip_until_next":if($.latestVersion)await OX($.latestVersion);Y();break}};if(q)return K0(H$,{flexDirection:"column",marginY:1,children:K0(j2,{children:q},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(Q)return K0(H$,{flexDirection:"column",marginY:1,children:K0(j2,{color:"cyan",children:"Updating..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);return K0(H$,{flexDirection:"column",marginY:1,children:[K0(j2,{color:"yellow",bold:!0,children:["✨ Update available! ",K0(j2,{color:"gray",children:[$.currentVersion," ","→"," ",$.latestVersion]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),K0(H$,{marginTop:1,children:K0(j2,{color:"gray",children:["Release notes:"," ",K0(j2,{color:"cyan",underline:!0,children:$.releaseNotesUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),K0(H$,{flexDirection:"column",marginTop:1,children:A8.map((U,O)=>{let W=O===Z,F=W?"› ":" ",H=`${O+1}. `;return K0(H$,{children:K0(j2,{color:W?"cyan":void 0,children:[F,H,U.label,U.description&&K0(j2,{color:"gray",children:[" (",U.description,")"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},U.key,!1,void 0,this)})},void 0,!1,void 0,this),K0(H$,{marginTop:1,children:K0(j2,{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)};B2();function a6($){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 b8}from"react/jsx-dev-runtime";function cz($){if($1().config.actions.setConfig($),!$.models||$.models.length===0){if($.debug)console.log("[Debug] 未检测到模型配置,进入设置向导");x0().setInitializationStatus("needsSetup");return}if($.debug)console.log("[Debug] 模型配置检查通过,准备就绪");x0().setInitializationStatus("ready")}var zq=($)=>{let[Y,Z]=T3(!1),[X,Q]=T3(null),[J,q]=T3(!1),K=Hq(async()=>{let U=$1().config.config??N$,O=I8(U,$);if(cz(O),O.debug)console.error("[Debug] 运行时配置:",O);let W=O.theme;if(W&&P1.hasTheme(W)){if(P1.setTheme(W),$.debug)console.log(`✓ 已加载主题: ${W}`)}try{let F=g1.loadFromStandardLocations();if($.debug&&F>0)console.log(`✓ 已加载 ${F} 个 subagents: ${g1.getAllNames().join(", ")}`)}catch(F){if($.debug)console.warn("⚠️ Subagents 加载失败:",a6(F))}try{let F=H1.getInstance();if(F.loadConfig(O.hooks||{}),$.debug&&O.hooks?.enabled)console.log("✓ Hooks 系统已启用");if(F.isEnabled()){let H=$1(),z=H.session.sessionId,N=H.config.config?.permissionMode||"default",L=!!$.resume,B=await F.executeSessionStartHooks({projectDir:process.cwd(),sessionId:z,permissionMode:N,isResume:L,resumeSessionId:typeof $.resume==="string"?$.resume:void 0});if(B.env){for(let[_,I]of Object.entries(B.env))process.env[_]=I;if($.debug)console.log("✓ SessionStart hooks 注入环境变量:",Object.keys(B.env).join(", "))}if(B.warning&&$.debug)console.warn("⚠️ SessionStart hooks 警告:",B.warning)}}catch(F){if($.debug)console.warn("⚠️ Hooks 初始化失败:",a6(F))}try{let F=await o2();if($.debug&&F.skills.length>0)console.log(`✓ 已加载 ${F.skills.length} 个 skills: ${F.skills.map((H)=>H.name).join(", ")}`);if(F.errors.length>0&&$.debug)for(let H of F.errors)console.warn(`⚠️ Skill 加载错误 (${H.path}): ${H.error}`)}catch(F){if($.debug)console.warn("⚠️ Skills 初始化失败:",a6(F))}try{let F=await OQ(process.cwd());if($.debug&&F.commands.length>0)console.log(`✓ 已加载 ${F.commands.length} 个自定义命令: ${F.commands.map((H)=>H.name).join(", ")}`);if(F.errors.length>0&&$.debug)for(let H of F.errors)console.warn(`⚠️ 自定义命令加载错误 (${H.path}): ${H.error}`)}catch(F){if($.debug)console.warn("⚠️ 自定义命令初始化失败:",a6(F))}BX(async()=>{N0.getInstance().killAll(),await t1.getInstance().disconnectAll(),H1.getInstance().cleanup()}),Z(!0)}),G=Hq(async()=>{if($.versionCheckPromise){let U=await $.versionCheckPromise;if(U){Q(U),q(!0);return}}await K()});if(mz(()=>{G()},[]),J&&X)return b8(w8,{children:b8(Fq,{versionInfo:X,onComplete:()=>{q(!1),K()}},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(!Y)return null;return b8(w8,{children:b8(Oq,{...$},void 0,!1,void 0,this)},void 0,!1,void 0,this)};var C3=Aq(process.argv),wq=C3.indexOf("--debug");if(wq!==-1){let $=C3[wq+1],Y=$&&!$.startsWith("-")?$:!0;h0.setGlobalDebug(Y)}async function $N(){_X();let $=HX();if(await JX())return;if(C3.includes("--acp")){let{runAcpIntegration:Z}=await Promise.resolve().then(() => (Lq(),_q));await Z();return}let Y=ez(Aq(process.argv)).scriptName(a2.scriptName).usage(a2.usage).version(a2.version).locale(a2.locale).showHelpOnFail(a2.showHelpOnFail).demandCommand(0,"").recommendCommands().strict(a2.strict).parserConfiguration({"populate--":!0}).options(d3).middleware([W5,O5,F5]).command(E5).command(H5).command(zX).command(z5).completion("completion",!1).help("help","Show help").alias("help","h").alias("version","V").fail((Z,X,Q)=>{if(X)console.error("\uD83D\uDCA5 An error occurred:"),console.error(X.message),console.error(`
1892
1894
  Stack trace:`),console.error(X.stack),process.exit(1);if(Z)console.error("❌ Invalid arguments:"),console.error(Z),console.error(`
1893
- \uD83D\uDCA1 Did you mean:`),Q.showHelp(),process.exit(1)}).command("$0",!1,()=>{},async(Z)=>{let X=Z._.slice(1),Q=X.length>0?X.join(" "):void 0,J={...Z,initialMessage:Q,debug:Z.debug,print:Boolean(Z.print),versionCheckPromise:$};delete J._,delete J.$0,delete J.message,v_(E_.createElement(nJ,J),{patchConsole:!0,exitOnCtrlC:!1,alternateBuffer:!1})});try{await Y.parse()}catch(Z){console.error("❌ Parse error:",Z),process.exit(1)}}if(c1.main==c1.module)T_().catch(console.error);export{T_ as main};
1895
+ \uD83D\uDCA1 Did you mean:`),Q.showHelp(),process.exit(1)}).command("$0",!1,()=>{},async(Z)=>{let X=Z._.slice(1),Q=X.length>0?X.join(" "):void 0,J={...Z,initialMessage:Q,debug:Z.debug,print:Boolean(Z.print),versionCheckPromise:$};delete J._,delete J.$0,delete J.message,sz(tz.createElement(zq,J),{patchConsole:!0,exitOnCtrlC:!1,alternateBuffer:!1})});try{await Y.parse()}catch(Z){console.error("❌ Parse error:",Z),process.exit(1)}}if(r1.main==r1.module)$N().catch(console.error);export{$N as main};