blade-code 0.0.36 → 0.0.37

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 +16 -0
  2. package/dist/blade.js +236 -228
  3. package/package.json +1 -1
package/dist/blade.js CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import{createRequire as GJ}from"node:module";var XJ=Object.create;var{getPrototypeOf:QJ,defineProperty:x$,getOwnPropertyNames:g7,getOwnPropertyDescriptor:JJ}=Object,m7=Object.prototype.hasOwnProperty;var S0=($,Y,Z)=>{Z=$!=null?XJ(QJ($)):{};let X=Y||!$||!$.__esModule?x$(Z,"default",{value:$,enumerable:!0}):Z;for(let Q of g7($))if(!m7.call(X,Q))x$(X,Q,{get:()=>$[Q],enumerable:!0});return X},p7=new WeakMap,qJ=($)=>{var Y=p7.get($),Z;if(Y)return Y;if(Y=x$({},"__esModule",{value:!0}),$&&typeof $==="object"||typeof $==="function")g7($).map((X)=>!m7.call(Y,X)&&x$(Y,X,{get:()=>$[X],enumerable:!(Z=JJ($,X))||Z.enumerable}));return p7.set($,Y),Y};var d7=($,Y)=>{for(var Z in Y)x$($,Z,{get:Y[Z],enumerable:!0,configurable:!0,set:(X)=>Y[Z]=()=>X})};var R=($,Y)=>()=>($&&(Y=$($=0)),Y);var x1=GJ(import.meta.url);var p$;var u7=R(()=>{p$={name:"blade-code",version:"0.0.36",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",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 a2(){return p$.version}function c7(){return p$.name}function l7(){return p$.description}function i7(){return`v${p$.version} © 2025 Blade Code`}var g$=R(()=>{u7()});var Y0=()=>{};var n2;var a4=R(()=>{Y0();n2={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:[],Stop:[]},env:{},disableAllHooks:!1,maxTurns:-1}});import{promises as V6}from"fs";import{merge as a7}from"lodash-es";import n7 from"os";import o2 from"path";class r1{static instance=null;constructor(){}static getInstance(){if(!r1.instance)r1.instance=new r1;return r1.instance}static resetInstance(){r1.instance=null}async initialize(){try{let $=await this.loadConfigFiles(),Y=await this.loadSettingsFiles(),Z={...n2,...$,...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:",$),n2}}async loadConfigFiles(){let $=o2.join(n7.homedir(),".blade","config.json"),Y=o2.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 $=o2.join(n7.homedir(),".blade","settings.json"),Y=o2.join(process.cwd(),".blade","settings.json"),Z=o2.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=a7({},Z.hooks,Y.hooks);if(Y.env)Z.env=a7({},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=o2.join(process.cwd(),".gitignore"),Z=".blade/settings.local.json";try{let X="";if(await this.fileExists(Y))X=await V6.readFile(Y,"utf-8");if(!X.includes(".blade/settings.local.json")){let Q=X.trim()+`
2
+ import{createRequire as VJ}from"node:module";var wJ=Object.create;var{getPrototypeOf:LJ,defineProperty:e4,getOwnPropertyNames:AJ}=Object;var bJ=Object.prototype.hasOwnProperty;var h0=($,Y,Z)=>{Z=$!=null?wJ(LJ($)):{};let X=Y||!$||!$.__esModule?e4(Z,"default",{value:$,enumerable:!0}):Z;for(let Q of AJ($))if(!bJ.call(X,Q))e4(X,Q,{get:()=>$[Q],enumerable:!0});return X};var RJ=($,Y)=>{for(var Z in Y)e4($,Z,{get:Y[Z],enumerable:!0,configurable:!0,set:(X)=>Y[Z]=()=>X})};var b=($,Y)=>()=>($&&(Y=$($=0)),Y);var X0=VJ(import.meta.url);var d$;var $5=b(()=>{d$={name:"blade-code",version:"0.0.37",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",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 t2(){return d$.version}function Y5(){return d$.name}function Z5(){return d$.description}function X5(){return`v${d$.version} © 2025 Blade Code`}var u$=b(()=>{$5()});var Q0=()=>{};var e2;var $8=b(()=>{Q0();e2={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:[],Stop:[]},env:{},disableAllHooks:!1,maxTurns:-1}});import{promises as v6}from"fs";import{merge as J5}from"lodash-es";import q5 from"os";import $$ from"path";class n1{static instance=null;constructor(){}static getInstance(){if(!n1.instance)n1.instance=new n1;return n1.instance}static resetInstance(){n1.instance=null}async initialize(){try{let $=await this.loadConfigFiles(),Y=await this.loadSettingsFiles(),Z={...e2,...$,...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:",$),e2}}async loadConfigFiles(){let $=$$.join(q5.homedir(),".blade","config.json"),Y=$$.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 $=$$.join(q5.homedir(),".blade","settings.json"),Y=$$.join(process.cwd(),".blade","settings.json"),Z=$$.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=J5({},Z.hooks,Y.hooks);if(Y.env)Z.env=J5({},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=$$.join(process.cwd(),".gitignore"),Z=".blade/settings.local.json";try{let X="";if(await this.fileExists(Y))X=await v6.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 V6.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 V6.readFile($,"utf-8");return JSON.parse(Y)}}catch(Y){console.warn(`[ConfigManager] Failed to load ${$}:`,Y)}return null}async fileExists($){try{return await V6.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 v6.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 v6.readFile($,"utf-8");return JSON.parse(Y)}}catch(Y){console.warn(`[ConfigManager] Failed to load ${$}:`,Y)}return null}async fileExists($){try{return await v6.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 n4($,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 o7=R(()=>{a4();Y0()});import{promises as WJ}from"node:fs";import UJ from"node:os";import s7 from"node:path";import HJ from"pino";async function FJ(){let $=s7.join(UJ.homedir(),".blade","logs");return await WJ.mkdir($,{recursive:!0}),s7.join($,"blade.log")}async function zJ(){if(m$)return m$;if(d$)return d$;return d$=(async()=>{let $=await FJ();return m$=HJ({level:"debug",transport:{target:"pino/file",options:{destination:$}}}),m$})(),d$}function t7(){m$=null,d$=null}class b0{static globalDebugConfig=null;enabled;minLevel;category;pinoLogger=null;constructor($={}){if($.enabled!==void 0)this.enabled=$.enabled;else if(b0.globalDebugConfig!==null)this.enabled=Boolean(b0.globalDebugConfig);else this.enabled=!1;this.minLevel=$.minLevel??0,this.category=$.category??"General",this.initPino()}async initPino(){try{let $=await zJ();this.pinoLogger=$.child({category:this.category})}catch($){console.error("[Logger] Failed to initialize pino:",$)}}static setGlobalDebug($){b0.globalDebugConfig=$,t7()}static clearGlobalDebug(){b0.globalDebugConfig=null,t7()}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(b0.globalDebugConfig!==null){let{enabled:Y,filter:Z}=this.parseDebugFilter(b0.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=OJ[$];this.pinoLogger[X](Z)}if(this.shouldLogToConsole($)){let X=e7[$],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 i($,Y){return new b0({...Y,category:$})}var e7,OJ,m$=null,d$=null,NF;var A1=R(()=>{((Q)=>{Q[Q.DEBUG=0]="DEBUG";Q[Q.INFO=1]="INFO";Q[Q.WARN=2]="WARN";Q[Q.ERROR=3]="ERROR"})(e7||={});OJ={[0]:"debug",[1]:"info",[2]:"warn",[3]:"error"};NF=new b0({category:"General"})});import{Mutex as $5}from"async-mutex";import{merge as _J}from"lodash-es";import{promises as D6}from"node:fs";import Y5 from"node:os";import q2 from"node:path";import NJ from"write-file-atomic";class s0{static instance=null;pendingUpdates=new Map;timers=new Map;fileLocks=new Map;lastSaveError=null;debounceDelay=300;constructor(){}static getInstance(){if(!s0.instance)s0.instance=new s0;return s0.instance}static resetInstance(){if(s0.instance)for(let $ of s0.instance.timers.values())clearTimeout($);s0.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=G2[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=G2[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"?q2.join(Y5.homedir(),".blade","config.json"):q2.join(process.cwd(),".blade","config.json");switch(Y){case"local":return q2.join(process.cwd(),".blade","settings.local.json");case"project":return q2.join(process.cwd(),".blade","settings.json");case"global":return q2.join(Y5.homedir(),".blade","settings.json");default:return q2.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,Z5.error(`Failed to save config to ${$}:`,K.message),Z5.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=G2[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 $5,this.fileLocks.set($,Z);await Z.runExclusive(async()=>{await this.performWrite($,Y)})}async flushTargetWithModifier($,Y){let Z=this.fileLocks.get($);if(!Z)Z=new $5,this.fileLocks.set($,Z);await Z.runExclusive(async()=>{await D6.mkdir(q2.dirname($),{recursive:!0});let X={};try{let J=await D6.readFile($,"utf-8");X=JSON.parse(J)}catch{X={}}let Q=Y(X);await this.atomicWrite($,Q)})}async performWrite($,Y){await D6.mkdir(q2.dirname($),{recursive:!0});let Z={};try{let Q=await D6.readFile($,"utf-8");Z=JSON.parse(Q)}catch{Z={}}let X={...Z};for(let[Q,J]of Object.entries(Y)){let q=G2[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]=_J({},X,Z)}else $[Y]=Z}dedupeArray($){return Array.from(new Set($))}async atomicWrite($,Y){await NJ($,JSON.stringify(Y,null,2),{mode:384,encoding:"utf-8"})}}function m1(){return s0.getInstance()}var Z5,G2,IF,MF,jF,vF;var X5=R(()=>{A1();Z5=i("Service"),G2={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}},IF=new Set(Object.entries(G2).filter(([$,Y])=>Y.persistable).map(([$])=>$)),MF=new Set(Object.entries(G2).filter(([$,Y])=>!Y.persistable).map(([$])=>$)),jF=new Set(Object.entries(G2).filter(([$,Y])=>Y.target==="config").map(([$])=>$)),vF=new Set(Object.entries(G2).filter(([$,Y])=>Y.target==="settings").map(([$])=>$))});import u$ from"picomatch";class j2{config;constructor($){this.config=$}check($){let Y=j2.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(!u$.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(u$.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 u$.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(!u$.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 U=0;U<$.length;U++){let H=$[U];if(W){X+=H,W=!1;continue}if(H==="\\"){X+=H,W=!0;continue}if(!G&&H==="{")Q++;else if(!G&&H==="}")Q--;else if(!G&&H==="(")J++;else if(!G&&H===")")J--;else if(!G&&H==="[")q++;else if(!G&&H==="]")q--;if((H==='"'||H==="'")&&!G){G=!0,K=H,X+=H;continue}else if(G&&H===K){G=!1,K="",X+=H;continue}if(H===Y&&Q===0&&J===0&&q===0&&!G)Z.push(X.trim()),X="";else X+=H}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 o4=()=>{};var s2=R(()=>{o7();X5();a4();o4();Y0()});var LJ,s4=($)=>({...LJ,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 Q5=R(()=>{LJ={initializationStatus:"idle",initializationError:null,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null,todos:[],awaitingSecondCtrlC:!1,thinkingModeEnabled:!1}});var wJ,t4=($,Y)=>({...wJ,actions:{setProcessing:(Z)=>{$((X)=>({command:{...X.command,isProcessing:Z}}))},createAbortController:()=>{let Z=new AbortController;return $((X)=>({command:{...X.command,abortController:Z}})),Z},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,abortController:null,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 J5=R(()=>{wJ={isProcessing:!1,abortController:null,pendingCommands:[]}});var AJ,e4=($)=>({...AJ,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 q5=R(()=>{AJ={config:null}});var bJ,$8=($)=>({...bJ,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 G5=R(()=>{bJ={currentFocus:"main-input",previousFocus:null}});import{nanoid as RJ}from"nanoid";var W5,K5,Y8=($,Y)=>({...K5,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)},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,...K5,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:{...W5}}}))},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 U5=R(()=>{W5={inputTokens:0,outputTokens:0,totalTokens:0,maxContextTokens:200000},K5={sessionId:RJ(),messages:[],isCompacting:!1,currentCommand:null,error:null,isActive:!0,tokenUsage:{...W5},currentThinkingContent:null,thinkingExpanded:!1,clearCount:0,historyExpanded:!1,expandedMessageCount:30}});var H5=R(()=>{Q5();J5();q5();G5();U5()});import{nanoid as VJ}from"nanoid";import{devtools as DJ,subscribeWithSelector as IJ}from"zustand/middleware";import{createStore as MJ}from"zustand/vanilla";async function I6(){if(v1()!==null)return;if(t2)return t2;return t2=(async()=>{try{let Z=await r1.getInstance().initialize();e().config.actions.setConfig(Z)}catch(Y){throw t2=null,Error(`❌ Store 未初始化且无法自动初始化
29
+ `)}}function Y8($,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 G5=b(()=>{$8();Q0()});import{promises as IJ}from"node:fs";import MJ from"node:os";import K5 from"node:path";import jJ from"pino";async function yJ(){let $=K5.join(MJ.homedir(),".blade","logs");return await IJ.mkdir($,{recursive:!0}),K5.join($,"blade.log")}async function EJ(){if(c$)return c$;if(l$)return l$;return l$=(async()=>{let $=await yJ();return c$=jJ({level:"debug",transport:{target:"pino/file",options:{destination:$}}}),c$})(),l$}function W5(){c$=null,l$=null}class I0{static globalDebugConfig=null;enabled;minLevel;category;pinoLogger=null;constructor($={}){if($.enabled!==void 0)this.enabled=$.enabled;else if(I0.globalDebugConfig!==null)this.enabled=Boolean(I0.globalDebugConfig);else this.enabled=!1;this.minLevel=$.minLevel??0,this.category=$.category??"General",this.initPino()}async initPino(){try{let $=await EJ();this.pinoLogger=$.child({category:this.category})}catch($){console.error("[Logger] Failed to initialize pino:",$)}}static setGlobalDebug($){I0.globalDebugConfig=$,W5()}static clearGlobalDebug(){I0.globalDebugConfig=null,W5()}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(I0.globalDebugConfig!==null){let{enabled:Y,filter:Z}=this.parseDebugFilter(I0.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=vJ[$];this.pinoLogger[X](Z)}if(this.shouldLogToConsole($)){let X=U5[$],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 I0({...Y,category:$})}var U5,vJ,c$=null,l$=null,xF;var B1=b(()=>{((Q)=>{Q[Q.DEBUG=0]="DEBUG";Q[Q.INFO=1]="INFO";Q[Q.WARN=2]="WARN";Q[Q.ERROR=3]="ERROR"})(U5||={});vJ={[0]:"debug",[1]:"info",[2]:"warn",[3]:"error"};xF=new I0({category:"General"})});import{Mutex as H5}from"async-mutex";import{merge as kJ}from"lodash-es";import{promises as y6}from"node:fs";import O5 from"node:os";import U2 from"node:path";import PJ from"write-file-atomic";class Y2{static instance=null;pendingUpdates=new Map;timers=new Map;fileLocks=new Map;lastSaveError=null;debounceDelay=300;constructor(){}static getInstance(){if(!Y2.instance)Y2.instance=new Y2;return Y2.instance}static resetInstance(){if(Y2.instance)for(let $ of Y2.instance.timers.values())clearTimeout($);Y2.instance=null}async save($,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=H2[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=H2[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"?U2.join(O5.homedir(),".blade","config.json"):U2.join(process.cwd(),".blade","config.json");switch(Y){case"local":return U2.join(process.cwd(),".blade","settings.local.json");case"project":return U2.join(process.cwd(),".blade","settings.json");case"global":return U2.join(O5.homedir(),".blade","settings.json");default:return U2.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,F5.error(`Failed to save config to ${$}:`,K.message),F5.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=H2[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 H5,this.fileLocks.set($,Z);await Z.runExclusive(async()=>{await this.performWrite($,Y)})}async flushTargetWithModifier($,Y){let Z=this.fileLocks.get($);if(!Z)Z=new H5,this.fileLocks.set($,Z);await Z.runExclusive(async()=>{await y6.mkdir(U2.dirname($),{recursive:!0});let X={};try{let J=await y6.readFile($,"utf-8");X=JSON.parse(J)}catch{X={}}let Q=Y(X);await this.atomicWrite($,Q)})}async performWrite($,Y){await y6.mkdir(U2.dirname($),{recursive:!0});let Z={};try{let Q=await y6.readFile($,"utf-8");Z=JSON.parse(Q)}catch{Z={}}let X={...Z};for(let[Q,J]of Object.entries(Y)){let q=H2[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]=kJ({},X,Z)}else $[Y]=Z}dedupeArray($){return Array.from(new Set($))}async atomicWrite($,Y){await PJ($,JSON.stringify(Y,null,2),{mode:384,encoding:"utf-8"})}}function u1(){return Y2.getInstance()}var F5,H2,rF,aF,nF,oF;var z5=b(()=>{B1();F5=c("Service"),H2={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}},rF=new Set(Object.entries(H2).filter(([$,Y])=>Y.persistable).map(([$])=>$)),aF=new Set(Object.entries(H2).filter(([$,Y])=>!Y.persistable).map(([$])=>$)),nF=new Set(Object.entries(H2).filter(([$,Y])=>Y.target==="config").map(([$])=>$)),oF=new Set(Object.entries(H2).filter(([$,Y])=>Y.target==="settings").map(([$])=>$))});import i$ from"picomatch";class k2{config;constructor($){this.config=$}check($){let Y=k2.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(!i$.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(i$.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 i$.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(!i$.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 U=0;U<$.length;U++){let H=$[U];if(W){X+=H,W=!1;continue}if(H==="\\"){X+=H,W=!0;continue}if(!G&&H==="{")Q++;else if(!G&&H==="}")Q--;else if(!G&&H==="(")J++;else if(!G&&H===")")J--;else if(!G&&H==="[")q++;else if(!G&&H==="]")q--;if((H==='"'||H==="'")&&!G){G=!0,K=H,X+=H;continue}else if(G&&H===K){G=!1,K="",X+=H;continue}if(H===Y&&Q===0&&J===0&&q===0&&!G)Z.push(X.trim()),X="";else X+=H}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 Z8=()=>{};var Y$=b(()=>{G5();z5();$8();Z8();Q0()});var SJ,CJ,fJ,hJ,xJ,pJ,gJ,mJ,dJ,uJ,cJ,lJ,iJ,x0;var X8=b(()=>{SJ={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)"}},CJ={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)"}},fJ={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)"}},hJ={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)"}},xJ={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)"}},pJ={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)"}},gJ={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)"}},mJ={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)"}},dJ={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)"}},uJ={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)"}},cJ={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)"}},lJ={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)"}},iJ={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)"}},x0=[{id:"ayu-dark",label:"Ayu Dark",theme:SJ,tags:["dark","popular"]},{id:"dracula",label:"Dracula",theme:CJ,tags:["dark","popular"]},{id:"monokai",label:"Monokai",theme:fJ,tags:["dark","classic"]},{id:"nord",label:"Nord",theme:hJ,tags:["dark","minimal"]},{id:"solarized-light",label:"Solarized Light",theme:xJ,tags:["light"]},{id:"solarized-dark",label:"Solarized Dark",theme:pJ,tags:["dark"]},{id:"tokyo-night",label:"Tokyo Night",theme:gJ,tags:["dark","popular"]},{id:"github",label:"GitHub",theme:mJ,tags:["light","minimal"]},{id:"gruvbox",label:"Gruvbox",theme:dJ,tags:["dark","warm"]},{id:"one-dark",label:"One Dark",theme:uJ,tags:["dark","popular"]},{id:"catppuccin",label:"Catppuccin",theme:cJ,tags:["dark","pastel"]},{id:"rose-pine",label:"Rose Pine",theme:lJ,tags:["dark","elegant"]},{id:"kanagawa",label:"Kanagawa",theme:iJ,tags:["dark","japanese"]}]});function E6($){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 Q8{currentTheme=k6;themes=new Map;constructor(){this.themes.set("default",k6),this.themes.set("dark",N5);for(let $ of x0)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(!E6(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"||x0.some((Z)=>Z.id===$))throw Error(`Cannot remove built-in theme '${$}'`);this.themes.delete($)}hasTheme($){return this.themes.has($)}validateTheme($){return E6($)}}var _5,k6,N5,V1;var O2=b(()=>{X8();_5={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"}},k6={name:"default",colors:_5,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)"}},N5={...k6,name:"dark",colors:{..._5,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"}}};V1=new Q8});var rJ,J8=($)=>({...rJ,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 B5=b(()=>{rJ={initializationStatus:"idle",initializationError:null,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null,todos:[],awaitingSecondCtrlC:!1,thinkingModeEnabled:!1}});var aJ,q8=($,Y)=>({...aJ,actions:{setProcessing:(Z)=>{$((X)=>({command:{...X.command,isProcessing:Z}}))},createAbortController:()=>{let Z=new AbortController;return $((X)=>({command:{...X.command,abortController:Z}})),Z},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,abortController:null,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 w5=b(()=>{aJ={isProcessing:!1,abortController:null,pendingCommands:[]}});var nJ,G8=($)=>({...nJ,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 L5=b(()=>{nJ={config:null}});var oJ,K8=($)=>({...oJ,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 A5=b(()=>{oJ={currentFocus:"main-input",previousFocus:null}});import{nanoid as sJ}from"nanoid";var R5,b5,W8=($,Y)=>({...b5,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,...b5,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:{...R5}}}))},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 V5=b(()=>{R5={inputTokens:0,outputTokens:0,totalTokens:0,maxContextTokens:200000},b5={sessionId:sJ(),messages:[],isCompacting:!1,currentCommand:null,error:null,isActive:!0,tokenUsage:{...R5},currentThinkingContent:null,thinkingExpanded:!1,clearCount:0,historyExpanded:!1,expandedMessageCount:30}});var D5=b(()=>{B5();w5();L5();A5();V5()});import{nanoid as tJ}from"nanoid";import{devtools as eJ,subscribeWithSelector as $q}from"zustand/middleware";import{createStore as Yq}from"zustand/vanilla";async function P6(){if(v1()!==null)return;if(Z$)return Z$;return Z$=(async()=>{try{let Z=await n1.getInstance().initialize();e().config.actions.setConfig(Z)}catch(Y){throw Z$=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{t2=null}})(),t2}var c$,e=()=>c$.getState(),jJ,v2=()=>e().session.actions,R0=()=>e().app.actions,O5=()=>e().session.messages,v1=()=>e().config.config,t2=null,l$=()=>e().config.config?.models??[],e2=()=>{let $=v1();if(!$)return;let Y=$.currentModelId;return $.models.find((X)=>X.id===Y)??$.models[0]},K0=()=>e().config.config?.mcpServers??{},z1=()=>({setPermissionMode:async($)=>{e().config.actions.updateConfig({permissionMode:$})},setTheme:async($,Y={})=>{e().config.actions.updateConfig({theme:$}),await m1().save({theme:$},{scope:"global",...Y})},setLanguage:async($,Y={})=>{e().config.actions.updateConfig({language:$}),await m1().save({language:$},{scope:"global",...Y})},setDebug:async($,Y={})=>{e().config.actions.updateConfig({debug:$}),await m1().save({debug:$},{scope:"global",...Y})},setTemperature:async($,Y={})=>{e().config.actions.updateConfig({temperature:$}),await m1().save({temperature:$},{scope:"global",...Y})},updateConfig:async($,Y={})=>{let Z=v1();if(!Z)throw Error("Config not initialized");let X={...Z};e().config.actions.updateConfig($);try{await m1().save($,Y)}catch(Q){throw e().config.actions.setConfig(X),Q}},flush:async()=>{await m1().flush()},appendPermissionAllowRule:async($,Y={})=>{let Z=v1();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 m1().appendPermissionRule($,Y)},appendLocalPermissionAllowRule:async($,Y={})=>{let Z=v1();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 m1().appendLocalPermissionRule($,Y)},setCurrentModel:async($,Y={})=>{let Z=v1();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 m1().save({currentModelId:$},{scope:"global",...Y})},addModel:async($,Y={})=>{let Z=v1();if(!Z)throw Error("Config not initialized");let X="id"in $?$:{id:VJ(),...$},J={models:[...Z.models,X]};if(Z.models.length===0)J.currentModelId=X.id;return e().config.actions.updateConfig(J),await m1().save(J,{scope:"global",...Y}),X},updateModel:async($,Y,Z={})=>{let X=v1();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 m1().save({models:J},{scope:"global",...Z})},removeModel:async($,Y={})=>{let Z=v1();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 m1().save(Q,{scope:"global",...Y})},addMcpServer:async($,Y,Z={})=>{let X=v1();if(!X)throw Error("Config not initialized");let J={...X.mcpServers??{},[$]:Y};e().config.actions.updateConfig({mcpServers:J}),await m1().save({mcpServers:J},{scope:"project",...Z})},removeMcpServer:async($,Y={})=>{let Z=v1();if(!Z)throw Error("Config not initialized");let Q={...Z.mcpServers??{}};delete Q[$],e().config.actions.updateConfig({mcpServers:Q}),await m1().save({mcpServers:Q},{scope:"project",...Y})}});var _1=R(()=>{s2();H5();c$=MJ()(DJ(IJ((...$)=>({session:Y8(...$),app:s4(...$),config:e4(...$),focus:$8(...$),command:t4(...$)})),{name:"BladeStore",enabled:!0})),jJ=c$.subscribe});function i$($){return $==="readonly"}var C0=()=>{};class X8{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 Q8=R(()=>{C0()});var d1=R(()=>{Q8();C0()});function vJ($){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 yJ($){let Y=$.issues.map((X)=>{let Q=X.path.join("."),J=vJ(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{Z$=null}})(),Z$}var r$,e=()=>r$.getState(),Zq,P2=()=>e().session.actions,M0=()=>e().app.actions,I5=()=>e().session.messages,v1=()=>e().config.config,Z$=null,a$=()=>e().config.config?.models??[],X$=()=>{let $=v1();if(!$)return;let Y=$.currentModelId;return $.models.find((X)=>X.id===Y)??$.models[0]},U0=()=>e().config.config?.mcpServers??{},F1=()=>({setPermissionMode:async($)=>{e().config.actions.updateConfig({permissionMode:$})},setTheme:async($,Y={})=>{try{V1.setTheme($)}catch{return}e().config.actions.updateConfig({theme:$}),await u1().save({theme:$},{scope:"global",...Y})},setLanguage:async($,Y={})=>{e().config.actions.updateConfig({language:$}),await u1().save({language:$},{scope:"global",...Y})},setDebug:async($,Y={})=>{e().config.actions.updateConfig({debug:$}),await u1().save({debug:$},{scope:"global",...Y})},setTemperature:async($,Y={})=>{e().config.actions.updateConfig({temperature:$}),await u1().save({temperature:$},{scope:"global",...Y})},updateConfig:async($,Y={})=>{let Z=v1();if(!Z)throw Error("Config not initialized");let X={...Z};e().config.actions.updateConfig($);try{await u1().save($,Y)}catch(Q){throw e().config.actions.setConfig(X),Q}},flush:async()=>{await u1().flush()},appendPermissionAllowRule:async($,Y={})=>{let Z=v1();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 u1().appendPermissionRule($,Y)},appendLocalPermissionAllowRule:async($,Y={})=>{let Z=v1();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 u1().appendLocalPermissionRule($,Y)},setCurrentModel:async($,Y={})=>{let Z=v1();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 u1().save({currentModelId:$},{scope:"global",...Y})},addModel:async($,Y={})=>{let Z=v1();if(!Z)throw Error("Config not initialized");let X="id"in $?$:{id:tJ(),...$},J={models:[...Z.models,X]};if(Z.models.length===0)J.currentModelId=X.id;return e().config.actions.updateConfig(J),await u1().save(J,{scope:"global",...Y}),X},updateModel:async($,Y,Z={})=>{let X=v1();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 u1().save({models:J},{scope:"global",...Z})},removeModel:async($,Y={})=>{let Z=v1();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 u1().save(Q,{scope:"global",...Y})},addMcpServer:async($,Y,Z={})=>{let X=v1();if(!X)throw Error("Config not initialized");let J={...X.mcpServers??{},[$]:Y};e().config.actions.updateConfig({mcpServers:J}),await u1().save({mcpServers:J},{scope:"project",...Z})},removeMcpServer:async($,Y={})=>{let Z=v1();if(!Z)throw Error("Config not initialized");let Q={...Z.mcpServers??{}};delete Q[$],e().config.actions.updateConfig({mcpServers:Q}),await u1().save({mcpServers:Q},{scope:"project",...Y})}});var z1=b(()=>{Y$();O2();D5();r$=Yq()(eJ($q((...$)=>({session:W8(...$),app:J8(...$),config:G8(...$),focus:K8(...$),command:q8(...$)})),{name:"BladeStore",enabled:!0})),Zq=r$.subscribe});function n$($){return $==="readonly"}var p0=()=>{};class H8{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 O8=b(()=>{p0()});var c1=b(()=>{O8();p0()});function Xq($){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 Qq($){let Y=$.issues.map((X)=>{let Q=X.path.join("."),J=Xq(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 L5(Z,Y)}function w5($,Y){let Z=$.safeParse(Y);if(!Z.success)throw yJ(Z.error);return Z.data}var L5;var A5=R(()=>{d1();L5=class L5 extends Error{issues;type;constructor($,Y,Z="validation_error"){super($);this.issues=Y;this.type=Z;this.name="ToolValidationError"}}});import{zodToJsonSchema as EJ}from"zod-to-json-schema";function J8($){return EJ($,{target:"jsonSchema7",$refStrategy:"none"})}var b5=()=>{};class q8{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 Q1($){return{name:$.name,displayName:$.displayName,kind:$.kind,isReadOnly:$.isReadOnly??i$($.kind),isConcurrencySafe:$.isConcurrencySafe??!0,strict:$.strict??!1,description:$.description,version:$.version||"1.0.0",category:$.category,tags:$.tags||[],getFunctionDeclaration(){let Y=J8($.schema),Z=$.description.short;if($.description.long)Z+=`
38
+ `)}`;return new k5(Z,Y)}function P5($,Y){let Z=$.safeParse(Y);if(!Z.success)throw Qq(Z.error);return Z.data}var k5;var T5=b(()=>{c1();k5=class k5 extends Error{issues;type;constructor($,Y,Z="validation_error"){super($);this.issues=Y;this.type=Z;this.name="ToolValidationError"}}});import{zodToJsonSchema as Jq}from"zod-to-json-schema";function F8($){return Jq($,{target:"jsonSchema7",$refStrategy:"none"})}var S5=()=>{};class z8{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 Q1($){return{name:$.name,displayName:$.displayName,kind:$.kind,isReadOnly:$.isReadOnly??n$($.kind),isConcurrencySafe:$.isConcurrencySafe??!0,strict:$.strict??!1,description:$.description,version:$.version||"1.0.0",category:$.category,tags:$.tags||[],getFunctionDeclaration(){let Y=F8($.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,12 +45,12 @@ ${$.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:J8($.schema)}},build(Y){let Z=w5($.schema,Y);return new q8($.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 P1=R(()=>{C0();A5();b5()});import{z as W0}from"zod";function M6($,Y,Z,X){let Q;try{Q=r$(Z.inputSchema)}catch(q){console.warn(`[createMcpTool] Schema 转换失败,使用降级 schema: ${Z.name}`,q),Q=W0.any()}let J=X||Z.name;return Q1({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="",U="";if(K.content&&Array.isArray(K.content)){for(let H of K.content)if(H.type==="text"&&H.text)W+=H.text,U+=H.text;else if(H.type==="image")U+=`[图片: ${H.mimeType||"unknown"}]
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:F8($.schema)}},build(Y){let Z=P5($.schema,Y);return new z8($.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 S1=b(()=>{p0();T5();S5()});import{z as H0}from"zod";function T6($,Y,Z,X){let Q;try{Q=o$(Z.inputSchema)}catch(q){console.warn(`[createMcpTool] Schema 转换失败,使用降级 schema: ${Z.name}`,q),Q=H0.any()}let J=X||Z.name;return Q1({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="",U="";if(K.content&&Array.isArray(K.content)){for(let H of K.content)if(H.type==="text"&&H.text)W+=H.text,U+=H.text;else if(H.type==="image")U+=`[图片: ${H.mimeType||"unknown"}]
49
49
  `,W+=`[image: ${H.mimeType||"unknown"}]
50
50
  `;else if(H.type==="resource")U+=`[资源: ${H.mimeType||"unknown"}]
51
51
  `,W+=`[resource: ${H.mimeType||"unknown"}]
52
52
  `}if(K.isError)return{success:!1,llmContent:W||"MCP tool execution failed",displayContent:`❌ ${U||"MCP工具执行失败"}`,error:{type:"execution_error",message:W||"MCP tool execution failed"}};return{success:!0,llmContent:W||"Execution succeeded",displayContent:`✅ MCP工具 ${Z.name} 执行成功
53
- ${U}`,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 r$($){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=r$(Q);if(!Z.includes(X))J=J.optional();Y[X]=J}}return W0.object(Y)}if($.type==="array"&&$.items){if(typeof $.items==="object"&&!Array.isArray($.items)&&$.items!==null)return W0.array(r$($.items));return W0.array(W0.any())}if($.type==="string"){let Y=W0.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 W0.enum($.enum);return Y}if($.type==="number"||$.type==="integer"){let Y=W0.number();if($.minimum!==void 0)Y=Y.min($.minimum);if($.maximum!==void 0)Y=Y.max($.maximum);return Y}if($.type==="boolean")return W0.boolean();if($.oneOf&&$.oneOf.length>0){let Y=$.oneOf.filter((Z)=>typeof Z==="object"&&Z!==null).map((Z)=>r$(Z));if(Y.length>=2)return W0.union(Y)}if($.anyOf&&$.anyOf.length>0){let Y=$.anyOf.filter((Z)=>typeof Z==="object"&&Z!==null).map((Z)=>r$(Z));if(Y.length>=2)return W0.union(Y)}return W0.any()}var R5=R(()=>{P1();d1()});import{promises as G8}from"fs";import kJ from"os";import K8 from"path";class j6{tokenFilePath;constructor(){let $=kJ.homedir(),Y=K8.join($,".blade");this.tokenFilePath=K8.join(Y,"mcp-oauth-tokens.json")}async ensureConfigDir(){let $=K8.dirname(this.tokenFilePath);try{await G8.mkdir($,{recursive:!0})}catch(Y){}}async loadAllCredentials(){let $=new Map;try{let Y=await G8.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 G8.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 W8=()=>{};import*as n$ from"crypto";import*as I5 from"http";import{spawn as PJ}from"child_process";import{URL as V5}from"url";class v6{tokenStorage;constructor($=new j6){this.tokenStorage=$}generatePKCEParams(){let $=n$.randomBytes(32).toString("base64url"),Y=n$.createHash("sha256").update($).digest("base64url"),Z=n$.randomBytes(16).toString("base64url");return{codeVerifier:$,codeChallenge:Y,state:Z}}buildAuthorizationUrl($,Y){let Z=$.redirectUri||`http://localhost:${a$}${U8}`,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 V5($.authorizationUrl);return X.forEach((J,q)=>{Q.searchParams.append(q,J)}),Q.toString()}async startCallbackServer($){return new Promise((Y,Z)=>{let X=I5.createServer((Q,J)=>{try{let q=new V5(Q.url,`http://localhost:${a$}`);if(q.pathname!==U8){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(D5,{"Content-Type":"text/html"}),J.end(`
53
+ ${U}`,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 o$($){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=o$(Q);if(!Z.includes(X))J=J.optional();Y[X]=J}}return H0.object(Y)}if($.type==="array"&&$.items){if(typeof $.items==="object"&&!Array.isArray($.items)&&$.items!==null)return H0.array(o$($.items));return H0.array(H0.any())}if($.type==="string"){let Y=H0.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 H0.enum($.enum);return Y}if($.type==="number"||$.type==="integer"){let Y=H0.number();if($.minimum!==void 0)Y=Y.min($.minimum);if($.maximum!==void 0)Y=Y.max($.maximum);return Y}if($.type==="boolean")return H0.boolean();if($.oneOf&&$.oneOf.length>0){let Y=$.oneOf.filter((Z)=>typeof Z==="object"&&Z!==null).map((Z)=>o$(Z));if(Y.length>=2)return H0.union(Y)}if($.anyOf&&$.anyOf.length>0){let Y=$.anyOf.filter((Z)=>typeof Z==="object"&&Z!==null).map((Z)=>o$(Z));if(Y.length>=2)return H0.union(Y)}return H0.any()}var C5=b(()=>{S1();c1()});import{promises as _8}from"fs";import qq from"os";import N8 from"path";class S6{tokenFilePath;constructor(){let $=qq.homedir(),Y=N8.join($,".blade");this.tokenFilePath=N8.join(Y,"mcp-oauth-tokens.json")}async ensureConfigDir(){let $=N8.dirname(this.tokenFilePath);try{await _8.mkdir($,{recursive:!0})}catch(Y){}}async loadAllCredentials(){let $=new Map;try{let Y=await _8.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 _8.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 B8=()=>{};import*as t$ from"crypto";import*as x5 from"http";import{spawn as Gq}from"child_process";import{URL as f5}from"url";class C6{tokenStorage;constructor($=new S6){this.tokenStorage=$}generatePKCEParams(){let $=t$.randomBytes(32).toString("base64url"),Y=t$.createHash("sha256").update($).digest("base64url"),Z=t$.randomBytes(16).toString("base64url");return{codeVerifier:$,codeChallenge:Y,state:Z}}buildAuthorizationUrl($,Y){let Z=$.redirectUri||`http://localhost:${s$}${w8}`,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 f5($.authorizationUrl);return X.forEach((J,q)=>{Q.searchParams.append(q,J)}),Q.toString()}async startCallbackServer($){return new Promise((Y,Z)=>{let X=x5.createServer((Q,J)=>{try{let q=new f5(Q.url,`http://localhost:${s$}`);if(q.pathname!==w8){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(h5,{"Content-Type":"text/html"}),J.end(`
54
54
  <html>
55
55
  <body>
56
56
  <h1>Authentication Failed</h1>
@@ -58,7 +58,7 @@ ${U}`,metadata:{serverName:Y,toolName:Z.name,mcpResult:K}}}catch(K){return{succe
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(D5,{"Content-Type":"text/html"}),J.end(`
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(h5,{"Content-Type":"text/html"}),J.end(`
62
62
  <html>
63
63
  <body>
64
64
  <h1>Authentication Successful!</h1>
@@ -66,28 +66,28 @@ ${U}`,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(a$,()=>{console.log(`[OAuth] Callback server listening on port ${a$}`)}),setTimeout(()=>{X.close(),Z(Error("OAuth callback timeout"))},300000)})}async exchangeCodeForToken($,Y,Z){let X=$.redirectUri||`http://localhost:${a$}${U8}`,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(G)}catch(q){X.close(),Z(q)}});X.on("error",Z),X.listen(s$,()=>{console.log(`[OAuth] Callback server listening on port ${s$}`)}),setTimeout(()=>{X.close(),Z(Error("OAuth callback timeout"))},300000)})}async exchangeCodeForToken($,Y,Z){let X=$.redirectUri||`http://localhost:${s$}${w8}`,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=PJ(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 a$=7777,U8="/oauth/callback",D5=200;var M5=R(()=>{W8()});var j5=R(()=>{M5();W8()});var $$=()=>{};import{EventEmitter as TJ}from"events";var H8;var v5=R(()=>{$$();H8=class H8 extends TJ{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 SJ}from"@modelcontextprotocol/sdk/client/index.js";import{SSEClientTransport as CJ}from"@modelcontextprotocol/sdk/client/sse.js";import{StdioClientTransport as fJ}from"@modelcontextprotocol/sdk/client/stdio.js";import{EventEmitter as hJ}from"events";function y5($){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 O8;var E5=R(()=>{g$();j5();v5();$$();O8=class O8 extends hJ{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 v6;if(Z?.enabled)this.healthMonitor=new H8(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=y5(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 SJ({name:c7(),version:a2()},{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),y5(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,U]of Object.entries(process.env))if(U!==void 0)K[W]=U;return new fJ({command:Y,args:Z||[],env:{...K,...X},stderr:"ignore"})}else if($==="sse"){if(!Q)throw Error("sse 传输需要 url 参数");return new CJ(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 xJ}from"events";var p1;var Y$=R(()=>{R5();E5();$$();p1=class p1 extends xJ{static instance=null;servers=new Map;isDiscovering=!1;constructor(){super()}static getInstance(){if(!p1.instance)p1.instance=new p1;return p1.instance}async registerServer($,Y){if(this.servers.has($))throw Error(`MCP服务器 "${$}" 已经注册`);let Z=new O8(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=M6(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 M6(Z.client,Y,X)}return null}getToolsByServer($){let Y=this.servers.get($);if(!Y||Y.status!=="connected")return[];return Y.tools.map((Z)=>M6(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()}}});import{randomUUID as rJ}from"node:crypto";import aJ from"openai";function nJ(){return rJ().replace(/-/g,"")+"01"}function T5($){return $.toLowerCase().includes("gemini")}function k6($){if(!$||typeof $!=="object")return $;if(Array.isArray($))return $.map(k6);let Y={};for(let[Z,X]of Object.entries($)){if(Z==="$schema"||Z==="additionalProperties")continue;Y[Z]=k6(X)}return Y}function S5($){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)q1.debug(`\uD83D\uDD27 [GptOpenaiPlatformChatService] Gemini 修复:补充 ${X.length} 个缺失的 tool results`);return Q}class F8{config;constructor($){if(q1.debug("\uD83D\uDE80 [GptOpenaiPlatformChatService] Initializing"),q1.debug("⚙️ [GptOpenaiPlatformChatService] Config:",{model:$.model,baseUrl:$.baseUrl,apiVersion:$.apiVersion,temperature:$.temperature,maxContextTokens:$.maxContextTokens,timeout:$.timeout,hasApiKey:!!$.apiKey}),!$.baseUrl)throw q1.error("❌ [GptOpenaiPlatformChatService] baseUrl is required"),Error("baseUrl is required in ChatConfig");if(!$.apiKey)throw q1.error("❌ [GptOpenaiPlatformChatService] apiKey is required"),Error("apiKey is required in ChatConfig");if(!$.model)throw q1.error("❌ [GptOpenaiPlatformChatService] model is required"),Error("model is required in ChatConfig");this.config=$,q1.debug("✅ [GptOpenaiPlatformChatService] Initialized successfully")}createClient(){let $=nJ();q1.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 aJ({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();q1.debug("\uD83D\uDE80 [GptOpenaiPlatformChatService] Starting chat request"),q1.debug("\uD83D\uDCDD [GptOpenaiPlatformChatService] Messages count:",$.length);let Q=this.createClient(),J=T5(this.config.model),G=(J?S5($):$).map((U)=>{if(U.role==="tool")return{role:"tool",content:typeof U.content==="string"?U.content:U.content.filter((O)=>O.type==="text").map((O)=>O.text).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(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=Gq(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 s$=7777,w8="/oauth/callback",h5=200;var p5=b(()=>{B8()});var g5=b(()=>{p5();B8()});var Q$=()=>{};import{EventEmitter as Kq}from"events";var L8;var m5=b(()=>{Q$();L8=class L8 extends Kq{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 Wq}from"@modelcontextprotocol/sdk/client/index.js";import{SSEClientTransport as Uq}from"@modelcontextprotocol/sdk/client/sse.js";import{StdioClientTransport as Hq}from"@modelcontextprotocol/sdk/client/stdio.js";import{EventEmitter as Oq}from"events";function d5($){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 A8;var u5=b(()=>{u$();g5();m5();Q$();A8=class A8 extends Oq{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 C6;if(Z?.enabled)this.healthMonitor=new L8(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=d5(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 Wq({name:Y5(),version:t2()},{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),d5(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,U]of Object.entries(process.env))if(U!==void 0)K[W]=U;return new Hq({command:Y,args:Z||[],env:{...K,...X},stderr:"ignore"})}else if($==="sse"){if(!Q)throw Error("sse 传输需要 url 参数");return new Uq(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 Fq}from"events";var g1;var J$=b(()=>{C5();u5();Q$();g1=class g1 extends Fq{static instance=null;servers=new Map;isDiscovering=!1;constructor(){super()}static getInstance(){if(!g1.instance)g1.instance=new g1;return g1.instance}async registerServer($,Y){if(this.servers.has($))throw Error(`MCP服务器 "${$}" 已经注册`);let Z=new A8(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=T6(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 T6(Z.client,Y,X)}return null}getToolsByServer($){let Y=this.servers.get($);if(!Y||Y.status!=="connected")return[];return Y.tools.map((Z)=>T6(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()}}});import{randomUUID as Rq}from"node:crypto";import Vq from"openai";function Dq(){return Rq().replace(/-/g,"")+"01"}function i5($){return $.toLowerCase().includes("gemini")}function x6($){if(!$||typeof $!=="object")return $;if(Array.isArray($))return $.map(x6);let Y={};for(let[Z,X]of Object.entries($)){if(Z==="$schema"||Z==="additionalProperties")continue;Y[Z]=x6(X)}return Y}function r5($){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)J1.debug(`\uD83D\uDD27 [GptOpenaiPlatformChatService] Gemini 修复:补充 ${X.length} 个缺失的 tool results`);return Q}class b8{config;constructor($){if(J1.debug("\uD83D\uDE80 [GptOpenaiPlatformChatService] Initializing"),J1.debug("⚙️ [GptOpenaiPlatformChatService] Config:",{model:$.model,baseUrl:$.baseUrl,apiVersion:$.apiVersion,temperature:$.temperature,maxContextTokens:$.maxContextTokens,timeout:$.timeout,hasApiKey:!!$.apiKey}),!$.baseUrl)throw J1.error("❌ [GptOpenaiPlatformChatService] baseUrl is required"),Error("baseUrl is required in ChatConfig");if(!$.apiKey)throw J1.error("❌ [GptOpenaiPlatformChatService] apiKey is required"),Error("apiKey is required in ChatConfig");if(!$.model)throw J1.error("❌ [GptOpenaiPlatformChatService] model is required"),Error("model is required in ChatConfig");this.config=$,J1.debug("✅ [GptOpenaiPlatformChatService] Initialized successfully")}createClient(){let $=Dq();J1.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 Vq({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();J1.debug("\uD83D\uDE80 [GptOpenaiPlatformChatService] Starting chat request"),J1.debug("\uD83D\uDCDD [GptOpenaiPlatformChatService] Messages count:",$.length);let Q=this.createClient(),J=i5(this.config.model),G=(J?r5($):$).map((U)=>{if(U.role==="tool")return{role:"tool",content:typeof U.content==="string"?U.content:U.content.filter((O)=>O.type==="text").map((O)=>O.text).join(`
72
72
  `),tool_call_id:U.tool_call_id};if(U.role==="assistant"&&U.tool_calls)return{role:"assistant",content:(typeof U.content==="string"?U.content:U.content?.filter((O)=>O.type==="text").map((O)=>O.text).join(`
73
73
  `))||null,tool_calls:U.tool_calls};if(U.role==="user"&&Array.isArray(U.content))return{role:"user",content:U.content.map((H)=>{if(H.type==="text")return{type:"text",text:H.text};return{type:"image_url",image_url:{url:H.image_url.url}}})};return{role:U.role,content:typeof U.content==="string"?U.content:U.content.filter((H)=>H.type==="text").map((H)=>H.text).join(`
74
- `)}}),K=Y?.map((U)=>({type:"function",function:{name:U.name,description:U.description,parameters:J?k6(U.parameters):U.parameters}}));q1.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};q1.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 U=await Q.chat.completions.create(W,{signal:Z}),H=Date.now()-X;if(q1.debug("\uD83D\uDCE5 [GptOpenaiPlatformChatService] Response received in",H,"ms"),!U)throw q1.error("❌ [GptOpenaiPlatformChatService] API returned null/undefined response"),Error("API returned null/undefined response");if(!U.choices||!Array.isArray(U.choices))throw q1.error("❌ [GptOpenaiPlatformChatService] Invalid API response format - missing choices array"),Error(`Invalid API response: missing choices array. Response: ${JSON.stringify(U)}`);if(U.choices.length===0)throw q1.error("❌ [GptOpenaiPlatformChatService] API returned empty choices array"),Error("API returned empty choices array");let O=U.choices[0];if(!O)throw q1.error("❌ [GptOpenaiPlatformChatService] No completion choice returned"),Error("No completion choice returned");q1.debug("\uD83D\uDCDD [GptOpenaiPlatformChatService] Response choice:",{finishReason:O.finish_reason,contentLength:O.message.content?.length||0,hasToolCalls:!!O.message.tool_calls,toolCallsCount:O.message.tool_calls?.length||0});let F=O.message.tool_calls?.filter((_)=>_.type==="function"),z=O.message.reasoning_content||void 0,L=U.usage,B={content:O.message.content||"",reasoningContent:z,toolCalls:F,usage:{promptTokens:U.usage?.prompt_tokens||0,completionTokens:U.usage?.completion_tokens||0,totalTokens:U.usage?.total_tokens||0,reasoningTokens:L?.reasoning_tokens}};return q1.debug("✅ [GptOpenaiPlatformChatService] Chat completed successfully"),B}catch(U){let H=Date.now()-X;throw q1.error("❌ [GptOpenaiPlatformChatService] Chat request failed after",H,"ms"),q1.error("❌ [GptOpenaiPlatformChatService] Error details:",U),U}}async*streamChat($,Y,Z){let X=Date.now();q1.debug("\uD83D\uDE80 [GptOpenaiPlatformChatService] Starting stream request"),q1.debug("\uD83D\uDCDD [GptOpenaiPlatformChatService] Messages count:",$.length);let Q=this.createClient(),J=T5(this.config.model),G=(J?S5($):$).map((U)=>{if(U.role==="tool")return{role:"tool",content:typeof U.content==="string"?U.content:U.content.filter((O)=>O.type==="text").map((O)=>O.text).join(`
74
+ `)}}),K=Y?.map((U)=>({type:"function",function:{name:U.name,description:U.description,parameters:J?x6(U.parameters):U.parameters}}));J1.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};J1.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 U=await Q.chat.completions.create(W,{signal:Z}),H=Date.now()-X;if(J1.debug("\uD83D\uDCE5 [GptOpenaiPlatformChatService] Response received in",H,"ms"),!U)throw J1.error("❌ [GptOpenaiPlatformChatService] API returned null/undefined response"),Error("API returned null/undefined response");if(!U.choices||!Array.isArray(U.choices))throw J1.error("❌ [GptOpenaiPlatformChatService] Invalid API response format - missing choices array"),Error(`Invalid API response: missing choices array. Response: ${JSON.stringify(U)}`);if(U.choices.length===0)throw J1.error("❌ [GptOpenaiPlatformChatService] API returned empty choices array"),Error("API returned empty choices array");let O=U.choices[0];if(!O)throw J1.error("❌ [GptOpenaiPlatformChatService] No completion choice returned"),Error("No completion choice returned");J1.debug("\uD83D\uDCDD [GptOpenaiPlatformChatService] Response choice:",{finishReason:O.finish_reason,contentLength:O.message.content?.length||0,hasToolCalls:!!O.message.tool_calls,toolCallsCount:O.message.tool_calls?.length||0});let F=O.message.tool_calls?.filter((N)=>N.type==="function"),_=O.message.reasoning_content||void 0,w=U.usage,B={content:O.message.content||"",reasoningContent:_,toolCalls:F,usage:{promptTokens:U.usage?.prompt_tokens||0,completionTokens:U.usage?.completion_tokens||0,totalTokens:U.usage?.total_tokens||0,reasoningTokens:w?.reasoning_tokens}};return J1.debug("✅ [GptOpenaiPlatformChatService] Chat completed successfully"),B}catch(U){let H=Date.now()-X;throw J1.error("❌ [GptOpenaiPlatformChatService] Chat request failed after",H,"ms"),J1.error("❌ [GptOpenaiPlatformChatService] Error details:",U),U}}async*streamChat($,Y,Z){let X=Date.now();J1.debug("\uD83D\uDE80 [GptOpenaiPlatformChatService] Starting stream request"),J1.debug("\uD83D\uDCDD [GptOpenaiPlatformChatService] Messages count:",$.length);let Q=this.createClient(),J=i5(this.config.model),G=(J?r5($):$).map((U)=>{if(U.role==="tool")return{role:"tool",content:typeof U.content==="string"?U.content:U.content.filter((O)=>O.type==="text").map((O)=>O.text).join(`
75
75
  `),tool_call_id:U.tool_call_id};if(U.role==="assistant"&&U.tool_calls)return{role:"assistant",content:(typeof U.content==="string"?U.content:U.content?.filter((O)=>O.type==="text").map((O)=>O.text).join(`
76
76
  `))||null,tool_calls:U.tool_calls};if(U.role==="user"&&Array.isArray(U.content))return{role:"user",content:U.content.map((H)=>{if(H.type==="text")return{type:"text",text:H.text};return{type:"image_url",image_url:{url:H.image_url.url}}})};return{role:U.role,content:typeof U.content==="string"?U.content:U.content.filter((H)=>H.type==="text").map((H)=>H.text).join(`
77
- `)}}),K=Y?.map((U)=>({type:"function",function:{name:U.name,description:U.description,parameters:J?k6(U.parameters):U.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};q1.debug("\uD83D\uDCE4 [GptOpenaiPlatformChatService] Stream request params:",{model:W.model,messagesCount:W.messages.length,toolsCount:W.tools?.length||0});try{let U=await Q.chat.completions.create(W,{signal:Z}),H=Date.now()-X;q1.debug("\uD83D\uDCE5 [GptOpenaiPlatformChatService] Stream started in",H,"ms");let O=0,F="",N="",z=!1;for await(let L of U){if(O++,!L||!L.choices||!Array.isArray(L.choices)){q1.warn("⚠️ [GptOpenaiPlatformChatService] Invalid chunk format in stream",O);continue}let B=L.choices[0]?.delta;if(!B)continue;let _=B;if(B.content)F+=B.content;if(_.reasoning_content)N+=_.reasoning_content;if(B.tool_calls&&!z)z=!0,q1.debug("\uD83D\uDD27 [GptOpenaiPlatformChatService] Tool calls detected in stream");let b=L.choices[0]?.finish_reason;if(b)q1.debug("\uD83C\uDFC1 [GptOpenaiPlatformChatService] Stream finished with reason:",b),q1.debug("\uD83D\uDCCA [GptOpenaiPlatformChatService] Stream summary:",{totalChunks:O,totalContentLength:F.length,totalReasoningContentLength:N.length,hadToolCalls:z,duration:Date.now()-X+"ms"});yield{content:B.content||void 0,reasoningContent:_.reasoning_content||void 0,toolCalls:B.tool_calls,finishReason:b||void 0}}q1.debug("✅ [GptOpenaiPlatformChatService] Stream completed successfully")}catch(U){let H=Date.now()-X;throw q1.error("❌ [GptOpenaiPlatformChatService] Stream request failed after",H,"ms"),q1.error("❌ [GptOpenaiPlatformChatService] Stream error details:",U),U}}getConfig(){return{...this.config}}updateConfig($){q1.debug("\uD83D\uDD04 [GptOpenaiPlatformChatService] Updating configuration"),this.config={...this.config,...$},q1.debug("✅ [GptOpenaiPlatformChatService] Configuration updated successfully")}}var q1;var C5=R(()=>{A1();q1=i("Chat")});import f5 from"openai";function oJ($){for(let Y of x5){let Z=$[Y];if(Z)return{content:Z,fieldName:Y}}return}function h5($){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 P6{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(`
77
+ `)}}),K=Y?.map((U)=>({type:"function",function:{name:U.name,description:U.description,parameters:J?x6(U.parameters):U.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};J1.debug("\uD83D\uDCE4 [GptOpenaiPlatformChatService] Stream request params:",{model:W.model,messagesCount:W.messages.length,toolsCount:W.tools?.length||0});try{let U=await Q.chat.completions.create(W,{signal:Z}),H=Date.now()-X;J1.debug("\uD83D\uDCE5 [GptOpenaiPlatformChatService] Stream started in",H,"ms");let O=0,F="",z="",_=!1;for await(let w of U){if(O++,!w||!w.choices||!Array.isArray(w.choices)){J1.warn("⚠️ [GptOpenaiPlatformChatService] Invalid chunk format in stream",O);continue}let B=w.choices[0]?.delta;if(!B)continue;let N=B;if(B.content)F+=B.content;if(N.reasoning_content)z+=N.reasoning_content;if(B.tool_calls&&!_)_=!0,J1.debug("\uD83D\uDD27 [GptOpenaiPlatformChatService] Tool calls detected in stream");let I=w.choices[0]?.finish_reason;if(I)J1.debug("\uD83C\uDFC1 [GptOpenaiPlatformChatService] Stream finished with reason:",I),J1.debug("\uD83D\uDCCA [GptOpenaiPlatformChatService] Stream summary:",{totalChunks:O,totalContentLength:F.length,totalReasoningContentLength:z.length,hadToolCalls:_,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}}J1.debug("✅ [GptOpenaiPlatformChatService] Stream completed successfully")}catch(U){let H=Date.now()-X;throw J1.error("❌ [GptOpenaiPlatformChatService] Stream request failed after",H,"ms"),J1.error("❌ [GptOpenaiPlatformChatService] Stream error details:",U),U}}getConfig(){return{...this.config}}updateConfig($){J1.debug("\uD83D\uDD04 [GptOpenaiPlatformChatService] Updating configuration"),this.config={...this.config,...$},J1.debug("✅ [GptOpenaiPlatformChatService] Configuration updated successfully")}}var J1;var a5=b(()=>{B1();J1=c("Chat")});import n5 from"openai";function Iq($){for(let Y of s5){let Z=$[Y];if(Z)return{content:Z,fieldName:Y}}return}function o5($){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 p6{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(`
78
78
  `),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(`
79
- `))||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 x5)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(`
80
- `)}})}convertToOpenAITools($){return $?.map((Y)=>({type:"function",function:{name:Y.name,description:Y.description,parameters:Y.parameters}}))}extractAndDetectReasoning($){let Y=oJ($);if(Y){if(!this.detectedReasoningFieldName)this.detectedReasoningFieldName=Y.fieldName,m.debug(`\uD83E\uDDE0 [ChatService] Detected reasoning field: ${Y.fieldName}`);return Y.content}return}constructor($){this.config=$;if(m.debug("\uD83D\uDE80 [ChatService] Initializing ChatService"),m.debug("⚙️ [ChatService] Config:",{model:$.model,baseUrl:$.baseUrl,temperature:$.temperature,maxContextTokens:$.maxContextTokens,timeout:$.timeout,hasApiKey:!!$.apiKey}),!$.baseUrl)throw m.error("❌ [ChatService] baseUrl is required in ChatConfig"),Error("baseUrl is required in ChatConfig");if(!$.apiKey)throw m.error("❌ [ChatService] apiKey is required in ChatConfig"),Error("apiKey is required in ChatConfig");if(!$.model)throw m.error("❌ [ChatService] model is required in ChatConfig"),Error("model is required in ChatConfig");this.client=new f5({apiKey:$.apiKey,baseURL:$.baseUrl,timeout:$.timeout??180000,maxRetries:3}),m.debug("✅ [ChatService] ChatService initialized successfully")}async chat($,Y,Z){let X=Date.now();m.debug("\uD83D\uDE80 [ChatService] Starting chat request"),m.debug("\uD83D\uDCDD [ChatService] Messages count:",$.length);let Q=h5($);if(Q.length<$.length)m.debug(`\uD83D\uDD27 [ChatService] 过滤掉 ${$.length-Q.length} 条孤儿 tool 消息`);m.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(m.debug("\uD83D\uDD27 [ChatService] Tools count:",q?.length||0),q&&q.length>0)m.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};m.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(m.debug("\uD83D\uDCE5 [ChatService] Response received in",W,"ms"),!K)throw m.error("❌ [ChatService] API returned null/undefined response"),Error("API returned null/undefined response");if(!K.choices||!Array.isArray(K.choices))throw m.error("❌ [ChatService] Invalid API response format - missing choices array"),m.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 m.error("❌ [ChatService] API returned empty choices array"),Error("API returned empty choices array");m.debug("\uD83D\uDCCA [ChatService] Response usage:",K.usage),m.debug("\uD83D\uDCCA [ChatService] Response choices count:",K.choices.length);let U=K.choices[0];if(!U)throw m.error("❌ [ChatService] No completion choice returned"),Error("No completion choice returned");if(m.debug("\uD83D\uDCDD [ChatService] Response choice:",{finishReason:U.finish_reason,contentLength:U.message.content?.length||0,hasToolCalls:!!U.message.tool_calls,toolCallsCount:U.message.tool_calls?.length||0}),U.message.tool_calls)m.debug("\uD83D\uDD27 [ChatService] Tool calls:",U.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 H=U.message.tool_calls?.filter((L)=>L.type==="function"),O=U.message,F=this.extractAndDetectReasoning(O);if(this.config.supportsThinking)m.debug("\uD83E\uDDE0 [ChatService] Thinking model response:",{reasoningContentLength:F?.length||0,detectedFieldName:this.detectedReasoningFieldName,messageKeys:Object.keys(U.message)});let N=K.usage,z={content:U.message.content||"",reasoningContent:F,toolCalls:H,usage:{promptTokens:K.usage?.prompt_tokens||0,completionTokens:K.usage?.completion_tokens||0,totalTokens:K.usage?.total_tokens||0,reasoningTokens:N?.reasoning_tokens}};return m.debug("✅ [ChatService] Chat completed successfully"),m.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 m.error("❌ [ChatService] Chat request failed after",W,"ms"),m.error("❌ [ChatService] Error details:",K),K}}async*streamChat($,Y,Z){let X=Date.now();m.debug("\uD83D\uDE80 [ChatService] Starting chat stream request"),m.debug("\uD83D\uDCDD [ChatService] Messages count:",$.length);let Q=h5($);if(Q.length<$.length)m.debug(`\uD83D\uDD27 [ChatService] 过滤掉 ${$.length-Q.length} 条孤儿 tool 消息`);m.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(m.debug("\uD83D\uDD27 [ChatService] Stream tools count:",q?.length||0),q&&q.length>0)m.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};m.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;m.debug("\uD83D\uDCE5 [ChatService] Stream started in",W,"ms");let U=0,H="",O="",F=!1;for await(let N of K){if(U++,!N||!N.choices||!Array.isArray(N.choices)){m.warn("⚠️ [ChatService] Invalid chunk format in stream",U);continue}let z=N.choices[0]?.delta;if(!z){m.warn("⚠️ [ChatService] Empty delta in chunk",U);continue}let L=z,B=this.extractAndDetectReasoning(L);if(z.content)H+=z.content;if(B)O+=B;if(z.tool_calls&&!F)F=!0,m.debug("\uD83D\uDD27 [ChatService] Tool calls detected in stream");let _=N.choices[0]?.finish_reason;if(_)m.debug("\uD83C\uDFC1 [ChatService] Stream finished with reason:",_),m.debug("\uD83D\uDCCA [ChatService] Stream summary:",{totalChunks:U,totalContentLength:H.length,totalReasoningContentLength:O.length,hadToolCalls:F,duration:Date.now()-X+"ms"});yield{content:z.content||void 0,reasoningContent:B,toolCalls:z.tool_calls,finishReason:_||void 0}}m.debug("✅ [ChatService] Stream completed successfully")}catch(K){let W=Date.now()-X;throw m.error("❌ [ChatService] Stream request failed after",W,"ms"),m.error("❌ [ChatService] Stream error details:",K),K}}getConfig(){return{...this.config}}updateConfig($){m.debug("\uD83D\uDD04 [ChatService] Updating configuration"),m.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,m.debug("\uD83D\uDD04 [ChatService] Reset detectedReasoningFieldName due to baseUrl change");this.client=new f5({apiKey:this.config.apiKey,baseURL:this.config.baseUrl,timeout:this.config.timeout??180000,maxRetries:2}),m.debug("✅ [ChatService] Configuration updated successfully"),m.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 m,x5;var p5=R(()=>{A1();m=i("Chat"),x5=["reasoning_content","reasoning","reasoningContent","thinking_content"]});function T6($){switch($.provider){case"openai-compatible":return new P6($);case"gpt-openai-platform":return new F8($);case"anthropic":throw Error(`❌ Anthropic provider 暂未实现
79
+ `))||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(`
80
+ `)}})}convertToOpenAITools($){return $?.map((Y)=>({type:"function",function:{name:Y.name,description:Y.description,parameters:Y.parameters}}))}extractAndDetectReasoning($){let Y=Iq($);if(Y){if(!this.detectedReasoningFieldName)this.detectedReasoningFieldName=Y.fieldName,d.debug(`\uD83E\uDDE0 [ChatService] Detected reasoning field: ${Y.fieldName}`);return Y.content}return}constructor($){this.config=$;if(d.debug("\uD83D\uDE80 [ChatService] Initializing ChatService"),d.debug("⚙️ [ChatService] Config:",{model:$.model,baseUrl:$.baseUrl,temperature:$.temperature,maxContextTokens:$.maxContextTokens,timeout:$.timeout,hasApiKey:!!$.apiKey}),!$.baseUrl)throw d.error("❌ [ChatService] baseUrl is required in ChatConfig"),Error("baseUrl is required in ChatConfig");if(!$.apiKey)throw d.error("❌ [ChatService] apiKey is required in ChatConfig"),Error("apiKey is required in ChatConfig");if(!$.model)throw d.error("❌ [ChatService] model is required in ChatConfig"),Error("model is required in ChatConfig");this.client=new n5({apiKey:$.apiKey,baseURL:$.baseUrl,timeout:$.timeout??180000,maxRetries:3}),d.debug("✅ [ChatService] ChatService initialized successfully")}async chat($,Y,Z){let X=Date.now();d.debug("\uD83D\uDE80 [ChatService] Starting chat request"),d.debug("\uD83D\uDCDD [ChatService] Messages count:",$.length);let Q=o5($);if(Q.length<$.length)d.debug(`\uD83D\uDD27 [ChatService] 过滤掉 ${$.length-Q.length} 条孤儿 tool 消息`);d.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(d.debug("\uD83D\uDD27 [ChatService] Tools count:",q?.length||0),q&&q.length>0)d.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};d.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(d.debug("\uD83D\uDCE5 [ChatService] Response received in",W,"ms"),!K)throw d.error("❌ [ChatService] API returned null/undefined response"),Error("API returned null/undefined response");if(!K.choices||!Array.isArray(K.choices))throw d.error("❌ [ChatService] Invalid API response format - missing choices array"),d.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 d.error("❌ [ChatService] API returned empty choices array"),Error("API returned empty choices array");d.debug("\uD83D\uDCCA [ChatService] Response usage:",K.usage),d.debug("\uD83D\uDCCA [ChatService] Response choices count:",K.choices.length);let U=K.choices[0];if(!U)throw d.error("❌ [ChatService] No completion choice returned"),Error("No completion choice returned");if(d.debug("\uD83D\uDCDD [ChatService] Response choice:",{finishReason:U.finish_reason,contentLength:U.message.content?.length||0,hasToolCalls:!!U.message.tool_calls,toolCallsCount:U.message.tool_calls?.length||0}),U.message.tool_calls)d.debug("\uD83D\uDD27 [ChatService] Tool calls:",U.message.tool_calls.map((w)=>({id:w.id,type:w.type,functionName:w.type==="function"?w.function?.name:"unknown",functionArgsLength:w.type==="function"?w.function?.arguments?.length||0:0})));let H=U.message.tool_calls?.filter((w)=>w.type==="function"),O=U.message,F=this.extractAndDetectReasoning(O);if(this.config.supportsThinking)d.debug("\uD83E\uDDE0 [ChatService] Thinking model response:",{reasoningContentLength:F?.length||0,detectedFieldName:this.detectedReasoningFieldName,messageKeys:Object.keys(U.message)});let z=K.usage,_={content:U.message.content||"",reasoningContent:F,toolCalls:H,usage:{promptTokens:K.usage?.prompt_tokens||0,completionTokens:K.usage?.completion_tokens||0,totalTokens:K.usage?.total_tokens||0,reasoningTokens:z?.reasoning_tokens}};return d.debug("✅ [ChatService] Chat completed successfully"),d.debug("\uD83D\uDCCA [ChatService] Final response:",{contentLength:_.content.length,toolCallsCount:_.toolCalls?.length||0,usage:_.usage}),_}catch(K){let W=Date.now()-X;throw d.error("❌ [ChatService] Chat request failed after",W,"ms"),d.error("❌ [ChatService] Error details:",K),K}}async*streamChat($,Y,Z){let X=Date.now();d.debug("\uD83D\uDE80 [ChatService] Starting chat stream request"),d.debug("\uD83D\uDCDD [ChatService] Messages count:",$.length);let Q=o5($);if(Q.length<$.length)d.debug(`\uD83D\uDD27 [ChatService] 过滤掉 ${$.length-Q.length} 条孤儿 tool 消息`);d.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(d.debug("\uD83D\uDD27 [ChatService] Stream tools count:",q?.length||0),q&&q.length>0)d.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};d.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;d.debug("\uD83D\uDCE5 [ChatService] Stream started in",W,"ms");let U=0,H="",O="",F=!1;for await(let z of K){if(U++,!z||!z.choices||!Array.isArray(z.choices)){d.warn("⚠️ [ChatService] Invalid chunk format in stream",U);continue}let _=z.choices[0]?.delta;if(!_){d.warn("⚠️ [ChatService] Empty delta in chunk",U);continue}let w=_,B=this.extractAndDetectReasoning(w);if(_.content)H+=_.content;if(B)O+=B;if(_.tool_calls&&!F)F=!0,d.debug("\uD83D\uDD27 [ChatService] Tool calls detected in stream");let N=z.choices[0]?.finish_reason;if(N)d.debug("\uD83C\uDFC1 [ChatService] Stream finished with reason:",N),d.debug("\uD83D\uDCCA [ChatService] Stream summary:",{totalChunks:U,totalContentLength:H.length,totalReasoningContentLength:O.length,hadToolCalls:F,duration:Date.now()-X+"ms"});yield{content:_.content||void 0,reasoningContent:B,toolCalls:_.tool_calls,finishReason:N||void 0}}d.debug("✅ [ChatService] Stream completed successfully")}catch(K){let W=Date.now()-X;throw d.error("❌ [ChatService] Stream request failed after",W,"ms"),d.error("❌ [ChatService] Stream error details:",K),K}}getConfig(){return{...this.config}}updateConfig($){d.debug("\uD83D\uDD04 [ChatService] Updating configuration"),d.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,d.debug("\uD83D\uDD04 [ChatService] Reset detectedReasoningFieldName due to baseUrl change");this.client=new n5({apiKey:this.config.apiKey,baseURL:this.config.baseUrl,timeout:this.config.timeout??180000,maxRetries:2}),d.debug("✅ [ChatService] Configuration updated successfully"),d.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 d,s5;var t5=b(()=>{B1();d=c("Chat"),s5=["reasoning_content","reasoning","reasoningContent","thinking_content"]});function g6($){switch($.provider){case"openai-compatible":return new p6($);case"gpt-openai-platform":return new b8($);case"anthropic":throw Error(`❌ Anthropic provider 暂未实现
81
81
 
82
82
  `+`请使用 "openai-compatible" 提供商,或者:
83
83
  `+`1. 等待官方实现
84
84
  `+`2. 贡献代码实现此功能: https://github.com/echoVic/blade-code
85
- `);default:return sJ.warn(`⚠️ 未知的 provider: ${$.provider}, 回退到 openai-compatible`),new P6($)}}var sJ;var z8=R(()=>{A1();C5();p5();sJ=i("Service")});import{readFile as tJ}from"node:fs/promises";class S6{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(`
86
- `);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:"",U=["Write","Edit"].includes(W||"");K.forEach((H)=>{this.updateFileReference(Y,H,Q,U)})})}),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 tJ(Z,"utf-8"),Q=X.split(`
85
+ `);default:return Mq.warn(`⚠️ 未知的 provider: ${$.provider}, 回退到 openai-compatible`),new p6($)}}var Mq;var R8=b(()=>{B1();a5();t5();Mq=c("Service")});import{readFile as jq}from"node:fs/promises";class m6{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(`
86
+ `);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:"",U=["Write","Edit"].includes(W||"");K.forEach((H)=>{this.updateFileReference(Y,H,Q,U)})})}),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 jq(Z,"utf-8"),Q=X.split(`
87
87
  `),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(`
88
88
  `),q+=`
89
89
 
90
- ... (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 g5=()=>{};import{encodingForModel as m5}from"js-tiktoken";var t0;var C6=R(()=>{t0=class t0{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=m5($);this.encodingCache.set($,Y)}catch{try{let Y=m5("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 Z$}from"nanoid";class X${static THRESHOLD_PERCENT=0.8;static RETAIN_PERCENT=0.2;static FALLBACK_RETAIN_PERCENT=0.3;static async compact($,Y){let Z=Y.actualPreTokens??t0.countTokens($,Y.modelName),X=Y.actualPreTokens?"actual (from LLM usage)":"estimated";console.log(`[CompactionService] preTokens source: ${X}`);try{console.log("[CompactionService] 开始压缩,消息数:",$.length),console.log("[CompactionService] 压缩前 tokens:",Z);let J=S6.analyzeFiles($).map((_)=>_.path);console.log("[CompactionService] 提取重点文件:",J);let q=await S6.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),U=new Set;for(let _ of W)if(_.role==="assistant"&&_.tool_calls)for(let b of _.tool_calls)U.add(b.id);let H=W.filter((_)=>{if(_.role==="tool"&&_.tool_call_id)return U.has(_.tool_call_id);return!0});console.log("[CompactionService] 保留消息数:",K),console.log("[CompactionService] 过滤后保留消息数:",H.length);let O=Z$(),F=this.createBoundaryMessage(O,Y.trigger,Z),N=Z$(),z=this.createSummaryMessage(N,G),L=[z,...H],B=t0.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:F,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 T6({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,U=K.length>5000?K.substring(0,5000)+"...":K;return`[${q+1}] ${G}: ${U}`}).join(`
90
+ ... (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 e5=()=>{};import{encodingForModel as $3}from"js-tiktoken";var Z2;var d6=b(()=>{Z2=class Z2{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=$3($);this.encodingCache.set($,Y)}catch{try{let Y=$3("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 q$}from"nanoid";class G${static THRESHOLD_PERCENT=0.8;static RETAIN_PERCENT=0.2;static FALLBACK_RETAIN_PERCENT=0.3;static async compact($,Y){let Z=Y.actualPreTokens??Z2.countTokens($,Y.modelName),X=Y.actualPreTokens?"actual (from LLM usage)":"estimated";console.log(`[CompactionService] preTokens source: ${X}`);try{console.log("[CompactionService] 开始压缩,消息数:",$.length),console.log("[CompactionService] 压缩前 tokens:",Z);let J=m6.analyzeFiles($).map((N)=>N.path);console.log("[CompactionService] 提取重点文件:",J);let q=await m6.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),U=new Set;for(let N of W)if(N.role==="assistant"&&N.tool_calls)for(let I of N.tool_calls)U.add(I.id);let H=W.filter((N)=>{if(N.role==="tool"&&N.tool_call_id)return U.has(N.tool_call_id);return!0});console.log("[CompactionService] 保留消息数:",K),console.log("[CompactionService] 过滤后保留消息数:",H.length);let O=q$(),F=this.createBoundaryMessage(O,Y.trigger,Z),z=q$(),_=this.createSummaryMessage(z,G),w=[_,...H],B=Z2.countTokens(w,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:w,boundaryMessage:F,summaryMessage:_}}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 g6({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,U=K.length>5000?K.substring(0,5000)+"...":K;return`[${q+1}] ${G}: ${U}`}).join(`
91
91
 
92
92
  `),X=Y.map((J)=>{return`### ${J.path}
93
93
  \`\`\`
@@ -160,14 +160,14 @@ ${Y.length>0?`## Important Files
160
160
 
161
161
  ${X}`:""}
162
162
 
163
- Please provide your summary following the structure specified above, with both <analysis> and <summary> sections.`}static createBoundaryMessage($,Y,Z){return{id:Z$(),role:"system",content:"Conversation compacted",metadata:{type:"system",subtype:"compact_boundary",parentId:$,compactMetadata:{trigger:Y,preTokens:Z}}}}static createSummaryMessage($,Y){return{id:Z$(),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=Z$(),W=this.createBoundaryMessage(K,Y.trigger,Z),U=X instanceof Error?X.message:String(X),H=Z$(),O=this.createSummaryMessage(H,`[Automatic compaction failed; using fallback]
163
+ Please provide your summary following the structure specified above, with both <analysis> and <summary> sections.`}static createBoundaryMessage($,Y,Z){return{id:q$(),role:"system",content:"Conversation compacted",metadata:{type:"system",subtype:"compact_boundary",parentId:$,compactMetadata:{trigger:Y,preTokens:Z}}}}static createSummaryMessage($,Y){return{id:q$(),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 _ of J)if(_.role==="assistant"&&_.tool_calls)for(let w of _.tool_calls)q.add(w.id);let G=J.filter((_)=>{if(_.role==="tool"&&_.tool_call_id)return q.has(_.tool_call_id);return!0}),K=q$(),W=this.createBoundaryMessage(K,Y.trigger,Z),U=X instanceof Error?X.message:String(X),H=q$(),O=this.createSummaryMessage(H,`[Automatic compaction failed; using fallback]
164
164
 
165
165
  An error occurred during compaction. Retained the latest ${Q} messages (~30%).
166
166
 
167
167
  Error: ${U}
168
168
 
169
- The conversation can continue, but consider retrying compaction later with /compact.`),F=[O,...G],N=t0.countTokens(F,Y.modelName);return{success:!1,summary:typeof O.content==="string"?O.content:O.content.filter((z)=>z.type==="text").map((z)=>z.text).join(`
170
- `),preTokens:Z,postTokens:N,filesIncluded:[],compactedMessages:F,boundaryMessage:W,summaryMessage:O,error:U}}}var _8=R(()=>{z8();g5();C6()});import eJ from"fs/promises";import $q from"path";async function u5($){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=$q.resolve(process.cwd(),Y),q=await eJ.readFile(J,"utf-8"),G=JSON.parse(q);Z=G.mcpServers||G}let Q={...K0(),...Z};e().config.actions.updateConfig({mcpServers:Q}),d5.debug(`✅ Loaded MCP config from CLI: ${Object.keys(Z).join(", ")}`)}catch(Z){d5.warn(`⚠️ Failed to load MCP config "${Y}":`,Z)}}var d5;var c5=R(()=>{A1();_1();d5=i("General")});function l5(){return{metadata:f6,instructions:`# Skill Creator
169
+ The conversation can continue, but consider retrying compaction later with /compact.`),F=[O,...G],z=Z2.countTokens(F,Y.modelName);return{success:!1,summary:typeof O.content==="string"?O.content:O.content.filter((_)=>_.type==="text").map((_)=>_.text).join(`
170
+ `),preTokens:Z,postTokens:z,filesIncluded:[],compactedMessages:F,boundaryMessage:W,summaryMessage:O,error:U}}}var V8=b(()=>{R8();e5();d6()});import vq from"fs/promises";import yq from"path";async function Z3($){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=yq.resolve(process.cwd(),Y),q=await vq.readFile(J,"utf-8"),G=JSON.parse(q);Z=G.mcpServers||G}let Q={...U0(),...Z};e().config.actions.updateConfig({mcpServers:Q}),Y3.debug(`✅ Loaded MCP config from CLI: ${Object.keys(Z).join(", ")}`)}catch(Z){Y3.warn(`⚠️ Failed to load MCP config "${Y}":`,Z)}}var Y3;var X3=b(()=>{B1();z1();Y3=c("General")});function Q3(){return{metadata:u6,instructions:`# Skill Creator
171
171
 
172
172
  帮助用户创建新的 Blade Skills。
173
173
 
@@ -207,15 +207,20 @@ The conversation can continue, but consider retrying compaction later with /comp
207
207
  ### 3. 确认保存位置
208
208
 
209
209
  询问用户希望将 Skill 保存到:
210
- - **项目级** (\`.blade/skills/\`): 与团队共享,通过 git 同步
210
+ - **项目级** (\`.blade/skills/\`): 与团队共享,通过 git 同步(**默认推荐**)
211
211
  - **用户级** (\`~/.blade/skills/\`): 个人使用,跨项目可用
212
212
 
213
+ 如果用户没有明确指定,默认使用 **项目级** (\`.blade/skills/\`)。
214
+
213
215
  ### 4. 生成文件
214
216
 
217
+ **重要:直接使用 Write 工具创建文件,不要使用外部脚本。**
218
+
215
219
  使用 Write 工具创建 SKILL.md 文件:
216
220
 
217
221
  \`\`\`
218
- {location}/.blade/skills/{name}/SKILL.md
222
+ .blade/skills/{name}/SKILL.md # 项目级(默认)
223
+ ~/.blade/skills/{name}/SKILL.md # 用户级
219
224
  \`\`\`
220
225
 
221
226
  文件格式:
@@ -240,13 +245,16 @@ user-invocable: true # 如果需要 /skill-name 命令
240
245
  {使用示例}
241
246
  \`\`\`
242
247
 
243
- ### 5. 验证
248
+ ### 5. 刷新并验证
249
+
250
+ 创建完成后,**必须提示用户执行 \`/skills\` 命令刷新 Skills 列表**,否则新创建的 Skill 不会立即生效。
244
251
 
252
+ 验证步骤:
245
253
  - 检查目录和文件是否创建成功
254
+ - **重要**:告诉用户执行 \`/skills\` 刷新列表
246
255
  - 提示用户可以通过以下方式使用新 Skill:
247
256
  - AI 自动调用(如果未禁用)
248
257
  - \`/skill-name\` 命令(如果启用了 user-invocable)
249
- - 执行 \`/skills\` 查看所有 Skills
250
258
 
251
259
  ## Best Practices
252
260
 
@@ -342,10 +350,10 @@ user-invocable: true
342
350
  <footer>
343
351
  \`\`\`
344
352
  \`\`\`
345
- `}}var f6;var i5=R(()=>{f6={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*as o$ from"node:fs/promises";import*as h6 from"node:path";import{parse as Yq}from"yaml";function Qq($){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 a5($){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 Jq($,Y){if(!$.name)return{valid:!1,error:"Missing required field: name"};if(!Xq.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>r5)return{valid:!1,error:`Description too long: ${$.description.length} characters (max ${r5})`};let Z;if($.model)Z=$.model==="inherit"?"inherit":$.model;return{valid:!0,metadata:{name:$.name,description:$.description.trim(),allowedTools:Qq($["allowed-tools"]),version:$.version,argumentHint:$["argument-hint"]?.trim(),userInvocable:a5($["user-invocable"]),disableModelInvocation:a5($["disable-model-invocation"]),model:Z,whenToUse:$.when_to_use?.trim()}}}function N8($,Y,Z){let X=$.match(Zq);if(!X)return{success:!1,error:"Invalid SKILL.md format: missing YAML frontmatter (must start with ---)"};let[,Q,J]=X,q;try{q=Yq(Q)}catch(W){return{success:!1,error:`Failed to parse YAML frontmatter: ${W instanceof Error?W.message:String(W)}`}}let G=Jq(q,Y);if(!G.valid)return{success:!1,error:G.error};let K=h6.dirname(Y);return{success:!0,content:{metadata:{...G.metadata,path:Y,basePath:K,source:Z},instructions:J.trim()}}}async function B8($,Y){try{let Z=await o$.readFile($,"utf-8");return N8(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 L8($){try{let Y=await o$.readFile($.path,"utf-8"),Z=N8(Y,$.path,$.source);return Z.success?Z.content:null}catch{return null}}async function w8($){try{return await o$.access(h6.join($,"SKILL.md")),!0}catch{return!1}}var Zq,Xq,r5=1024;var A8=R(()=>{Zq=/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/,Xq=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]?$/});import*as p6 from"node:fs/promises";import*as f0 from"node:path";import{homedir as n5}from"node:os";class g6{skills=new Map;config;initialized=!1;constructor($){this.config={...qq,...$}}static getInstance($){if(!x6)x6=new g6($);return x6}static resetInstance(){x6=null}async initialize(){if(this.initialized)return{skills:Array.from(this.skills.values()),errors:[]};let $=[],Y=[];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=f0.isAbsolute(this.config.claudeProjectSkillsDir)?this.config.claudeProjectSkillsDir:f0.join(this.config.cwd,this.config.claudeProjectSkillsDir),J=await this.scanDirectory(Q,"project");Y.push(...J.skills),$.push(...J.errors);let q=f0.isAbsolute(this.config.projectSkillsDir)?this.config.projectSkillsDir:f0.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(f6.name,f6)}async scanDirectory($,Y){let Z=[],X=[];try{await p6.access($)}catch{return{skills:Z,errors:X}}try{let Q=await p6.readdir($,{withFileTypes:!0});for(let J of Q){if(!J.isDirectory())continue;let q=f0.join($,J.name),G=f0.join(q,"SKILL.md");if(!await w8(q))continue;let K=await B8(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 L8(Y)}loadBuiltinContent($){switch($){case"skill-creator":return l5();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(`
346
- `)}get size(){return this.skills.size}async refresh(){return this.skills.clear(),this.initialized=!1,this.initialize()}}function u1($){return g6.getInstance($)}async function y2($){return u1($).initialize()}var qq,x6=null;var b8=R(()=>{i5();A8();qq={userSkillsDir:f0.join(n5(),".blade","skills"),projectSkillsDir:".blade/skills",claudeUserSkillsDir:f0.join(n5(),".claude","skills"),claudeProjectSkillsDir:".claude/skills",cwd:process.cwd()}});function R8($){let Z=u1().generateAvailableSkillsList();if(!Z)return $;return $.map((X)=>{if(X.name!==Gq)return X;let Q=X.description.replace(Kq,`<available_skills>
353
+ `}}var u6;var J3=b(()=>{u6={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 Eq}from"node:child_process";import*as y1 from"node:fs/promises";import{homedir as kq}from"node:os";import*as j0 from"node:path";import{promisify as Pq}from"node:util";class j8{skillsDir;constructor($){this.skillsDir=$||j0.join(kq(),".blade","skills")}async isInstalled($){let Y=j0.join(this.skillsDir,$,"SKILL.md");try{return await y1.access(Y),!0}catch{return!1}}async isGitAvailable(){try{return await D8("git --version"),!0}catch{return!1}}async installOfficialSkill($){let{url:Y,branch:Z}=I8,X=j0.join(this.skillsDir,$),Q=j0.join(this.skillsDir,`.tmp-${$}-${Date.now()}`);try{if(!await this.isGitAvailable())return g0.warn("Git not available, skipping skill installation"),!1;g0.info(`Installing official skill: ${$}...`),await y1.mkdir(this.skillsDir,{recursive:!0}),await D8(`git clone --depth 1 --branch ${Z} --single-branch ${Y} "${Q}"`,{timeout:30000});let J=j0.join(Q,"skills",$);try{await y1.access(J)}catch{return g0.warn(`Skill ${$} not found in official repository`),await y1.rm(Q,{recursive:!0,force:!0}),!1}try{await y1.rm(X,{recursive:!0,force:!0})}catch{}return await y1.cp(J,X,{recursive:!0}),await y1.rm(Q,{recursive:!0,force:!0}),g0.info(`Successfully installed: ${$}`),!0}catch(J){try{await y1.rm(Q,{recursive:!0,force:!0})}catch{}return g0.warn(`Failed to install ${$}: ${J instanceof Error?J.message:"Unknown error"}`),!1}}async ensureDefaultSkillsInstalled(){await y1.mkdir(this.skillsDir,{recursive:!0});for(let $ of I8.defaultSkills)if(!await this.isInstalled($))await this.installOfficialSkill($)}async installAllOfficialSkills(){let{url:$,branch:Y}=I8,Z=j0.join(this.skillsDir,`.tmp-all-${Date.now()}`),X=[],Q=[];try{if(!await this.isGitAvailable())return g0.warn("Git not available, skipping skill installation"),{installed:X,failed:Q};await y1.mkdir(this.skillsDir,{recursive:!0}),g0.info("Cloning official skills repository..."),await D8(`git clone --depth 1 --branch ${Y} --single-branch ${$} "${Z}"`,{timeout:60000});let J=j0.join(Z,"skills"),q=await y1.readdir(J,{withFileTypes:!0});for(let G of q){if(!G.isDirectory())continue;let K=G.name,W=j0.join(J,K),U=j0.join(this.skillsDir,K);try{await y1.access(j0.join(W,"SKILL.md")),await y1.rm(U,{recursive:!0,force:!0}),await y1.cp(W,U,{recursive:!0}),g0.info(`Installed: ${K}`),X.push(K)}catch(H){g0.warn(`Failed to install ${K}`),Q.push(K)}}await y1.rm(Z,{recursive:!0,force:!0})}catch(J){try{await y1.rm(Z,{recursive:!0,force:!0})}catch{}g0.warn(`Failed to install skills: ${J instanceof Error?J.message:"Unknown error"}`)}return{installed:X,failed:Q}}}function v8($){if(!M8)M8=new j8($);return M8}var D8,g0,I8,M8=null;var y8=b(()=>{B1();D8=Pq(Eq),g0=c("General"),I8={url:"https://github.com/anthropics/skills.git",branch:"main",defaultSkills:["skill-creator"]}});import*as e$ from"node:fs/promises";import*as c6 from"node:path";import{parse as Tq}from"yaml";function fq($){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 G3($){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 hq($,Y){if(!$.name)return{valid:!1,error:"Missing required field: name"};if(!Cq.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>q3)return{valid:!1,error:`Description too long: ${$.description.length} characters (max ${q3})`};let Z;if($.model)Z=$.model==="inherit"?"inherit":$.model;return{valid:!0,metadata:{name:$.name,description:$.description.trim(),allowedTools:fq($["allowed-tools"]),version:$.version,argumentHint:$["argument-hint"]?.trim(),userInvocable:G3($["user-invocable"]),disableModelInvocation:G3($["disable-model-invocation"]),model:Z,whenToUse:$.when_to_use?.trim()}}}function E8($,Y,Z){let X=$.match(Sq);if(!X)return{success:!1,error:"Invalid SKILL.md format: missing YAML frontmatter (must start with ---)"};let[,Q,J]=X,q;try{q=Tq(Q)}catch(W){return{success:!1,error:`Failed to parse YAML frontmatter: ${W instanceof Error?W.message:String(W)}`}}let G=hq(q,Y);if(!G.valid)return{success:!1,error:G.error};let K=c6.dirname(Y);return{success:!0,content:{metadata:{...G.metadata,path:Y,basePath:K,source:Z},instructions:J.trim()}}}async function k8($,Y){try{let Z=await e$.readFile($,"utf-8");return E8(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 P8($){try{let Y=await e$.readFile($.path,"utf-8"),Z=E8(Y,$.path,$.source);return Z.success?Z.content:null}catch{return null}}async function T8($){try{return await e$.access(c6.join($,"SKILL.md")),!0}catch{return!1}}var Sq,Cq,q3=1024;var S8=b(()=>{Sq=/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/,Cq=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]?$/});import*as i6 from"node:fs/promises";import{homedir as K3}from"node:os";import*as m0 from"node:path";class r6{skills=new Map;config;initialized=!1;constructor($){this.config={...xq,...$}}static getInstance($){if(!l6)l6=new r6($);return l6}static resetInstance(){l6=null}async initialize(){if(this.initialized)return{skills:Array.from(this.skills.values()),errors:[]};let $=[],Y=[];try{await v8(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=m0.isAbsolute(this.config.claudeProjectSkillsDir)?this.config.claudeProjectSkillsDir:m0.join(this.config.cwd,this.config.claudeProjectSkillsDir),J=await this.scanDirectory(Q,"project");Y.push(...J.skills),$.push(...J.errors);let q=m0.isAbsolute(this.config.projectSkillsDir)?this.config.projectSkillsDir:m0.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(u6.name,u6)}async scanDirectory($,Y){let Z=[],X=[];try{await i6.access($)}catch{return{skills:Z,errors:X}}try{let Q=await i6.readdir($,{withFileTypes:!0});for(let J of Q){if(!J.isDirectory())continue;let q=m0.join($,J.name),G=m0.join(q,"SKILL.md");if(!await T8(q))continue;let K=await k8(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 P8(Y)}loadBuiltinContent($){switch($){case"skill-creator":return Q3();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(`
354
+ `)}get size(){return this.skills.size}async refresh(){return this.skills.clear(),this.initialized=!1,this.initialize()}}function l1($){return r6.getInstance($)}async function T2($){return l1($).initialize()}var xq,l6=null;var C8=b(()=>{J3();y8();S8();xq={userSkillsDir:m0.join(K3(),".blade","skills"),projectSkillsDir:".blade/skills",claudeUserSkillsDir:m0.join(K3(),".claude","skills"),claudeProjectSkillsDir:".claude/skills",cwd:process.cwd()}});function f8($){let Z=l1().generateAvailableSkillsList();if(!Z)return $;return $.map((X)=>{if(X.name!==pq)return X;let Q=X.description.replace(gq,`<available_skills>
347
355
  ${Z}
348
- </available_skills>`);if(Q===X.description)return X;return{...X,description:Q}})}var Gq="Skill",Kq;var o5=R(()=>{b8();Kq=/<available_skills>\s*<\/available_skills>/});var K2=R(()=>{b8();A8();o5()});import{execSync as Wq}from"child_process";import*as J$ from"os";import*as Q$ from"path";function Uq(){let $=process.cwd(),Y=Hq($);return{workingDirectory:$,projectRoot:Y,platform:`${J$.platform()} (${J$.arch()})`,nodeVersion:process.version,currentDate:new Date().toISOString().split("T")[0],homeDirectory:J$.homedir()}}function m6(){let $=Uq();return`# Environment Context
356
+ </available_skills>`);if(Q===X.description)return X;return{...X,description:Q}})}var pq="Skill",gq;var W3=b(()=>{C8();gq=/<available_skills>\s*<\/available_skills>/});var F2=b(()=>{C8();S8();W3();y8()});import{execSync as mq}from"child_process";import*as W$ from"os";import*as K$ from"path";function dq(){let $=process.cwd(),Y=uq($);return{workingDirectory:$,projectRoot:Y,platform:`${W$.platform()} (${W$.arch()})`,nodeVersion:process.version,currentDate:new Date().toISOString().split("T")[0],homeDirectory:W$.homedir()}}function a6(){let $=dq();return`# Environment Context
349
357
 
350
358
  ## Working Directory
351
359
  **Current**: \`${$.workingDirectory}\`
@@ -363,9 +371,9 @@ When using file tools (read, write, edit), provide **absolute paths**:
363
371
  - ❌ Incorrect: \`/package.json\` (root directory)
364
372
  - ❌ Incorrect: \`package.json\` (relative path without context)
365
373
 
366
- **Always use** \`${$.workingDirectory}/\` as the base for file paths.`}function Hq($){let Y=$;while(Y!==Q$.dirname(Y)){if(s5(Q$.join(Y,".git")))return Y;if(s5(Q$.join(Y,"package.json")))return Y;Y=Q$.dirname(Y)}return $}function s5($){try{return Wq(`test -e "${$}"`,{stdio:"ignore"}),!0}catch{return!1}}var V8=()=>{};function s$($){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>
374
+ **Always use** \`${$.workingDirectory}/\` as the base for file paths.`}function uq($){let Y=$;while(Y!==K$.dirname(Y)){if(U3(K$.join(Y,".git")))return Y;if(U3(K$.join(Y,"package.json")))return Y;Y=K$.dirname(Y)}return $}function U3($){try{return mq(`test -e "${$}"`,{stdio:"ignore"}),!0}catch{return!1}}var h8=()=>{};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>
367
375
 
368
- `+$}var D8=`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.
376
+ `+$}var x8=`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.
369
377
 
370
378
  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.
371
379
  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.
@@ -523,7 +531,7 @@ assistant: Clients are marked as failed in the \`connectToServer\` function in s
523
531
  </example>
524
532
 
525
533
  # Language Requirement
526
- IMPORTANT: Always respond in Chinese (Simplified Chinese). Translate all your responses to Chinese before sending them to the user.`,I8=`You are in **PLAN MODE** - a read-only research phase for designing implementation plans.
534
+ IMPORTANT: Always respond in Chinese (Simplified Chinese). Translate all your responses to Chinese before sending them to the user.`,p8=`You are in **PLAN MODE** - a read-only research phase for designing implementation plans.
527
535
 
528
536
  ## Core Objective
529
537
 
@@ -563,59 +571,59 @@ Your plan should include:
563
571
  3. **Steps** - Detailed implementation steps with file paths
564
572
  4. **Testing** - How to verify changes
565
573
  5. **Risks** - Potential issues and mitigations
566
- `;var M8=()=>{};import{promises as t5}from"fs";import Oq from"path";async function d6($={}){let{projectPath:Y,replaceDefault:Z,append:X,mode:Q,includeEnvironment:J=!0}=$,q=[],G=[];if(J){let H=m6();if(H)q.push(H),G.push({name:"environment",loaded:!0,length:H.length})}let K=Q==="plan",W=K?I8:Z??D8;if(q.push(W),G.push({name:K?"plan_mode_prompt":Z?"replace_default":"default",loaded:!0,length:W.length}),Y){let H=await _q(Y);if(H)q.push(H),G.push({name:"blade_md",loaded:!0,length:H.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 U=q.join(`
574
+ `;var g8=()=>{};import{promises as H3}from"fs";import cq from"path";async function n6($={}){let{projectPath:Y,replaceDefault:Z,append:X,mode:Q,includeEnvironment:J=!0}=$,q=[],G=[];if(J){let H=a6();if(H)q.push(H),G.push({name:"environment",loaded:!0,length:H.length})}let K=Q==="plan",W=K?p8:Z??x8;if(q.push(W),G.push({name:K?"plan_mode_prompt":Z?"replace_default":"default",loaded:!0,length:W.length}),Y){let H=await rq(Y);if(H)q.push(H),G.push({name:"blade_md",loaded:!0,length:H.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 U=q.join(`
567
575
 
568
576
  ---
569
577
 
570
- `);return U=zq(U),{prompt:U,sources:G}}function zq($){let Z=u1().generateAvailableSkillsList();if(!Z)return $;return $.replace(Fq,`<available_skills>
578
+ `);return U=iq(U),{prompt:U,sources:G}}function iq($){let Z=l1().generateAvailableSkillsList();if(!Z)return $;return $.replace(lq,`<available_skills>
571
579
  ${Z}
572
- </available_skills>`)}async function _q($){let Y=Oq.join($,"BLADE.md");try{return(await t5.readFile(Y,"utf-8")).trim()||null}catch{return null}}var Fq;var e5=R(()=>{Y0();K2();V8();M8();Fq=/<available_skills>\s*<\/available_skills>/});var $3=R(()=>{e5();M8()});import*as u6 from"fs/promises";import*as a1 from"path";class c6{static normalize($,Y){let Z=a1.isAbsolute($)?$:a1.resolve(Y,$),X=a1.normalize(Z),Q=a1.normalize(Y);if(!X.startsWith(Q))throw new E2(`Path outside workspace: ${$} (resolved to ${X}, workspace: ${Q})`,"PATH_OUTSIDE_WORKSPACE");return X}static checkRestricted($){let Y=$.split(a1.sep);for(let Z of Y3)if(Y.includes(Z))throw new E2(`Access denied: "${Z}" is a protected directory`,"RESTRICTED_PATH")}static checkTraversal($){if($.includes(".."))throw new E2(`Path traversal not allowed: ${$}`,"PATH_TRAVERSAL")}static async validatePath($,Y){this.checkTraversal($);let Z=this.normalize($,Y);this.checkRestricted(Z);try{await u6.access(Z)}catch(X){throw new E2(`Path not found: ${$}`,"PATH_NOT_FOUND")}return Z}static async resolveSymlink($,Y){try{let Z=await u6.realpath($),X=a1.normalize(Y);if(!Z.startsWith(X))throw new E2(`Symlink points outside workspace: ${$} -> ${Z}`,"SYMLINK_OUTSIDE_WORKSPACE");return Z}catch(Z){if(Z instanceof E2)throw Z;return $}}static getRelativePath($,Y){return a1.relative(Y,$)}static isWithinWorkspace($,Y){let Z=a1.normalize($),X=a1.normalize(Y);return Z.startsWith(X)}static isRestricted($){let Y=$.split(a1.sep);return Y3.some((Z)=>Y.includes(Z))}}var Y3,E2;var Z3=R(()=>{Y3=[".git",".claude","node_modules",".env",".env.local",".env.production",".env.development",".env.test"];E2=class E2 extends Error{code;constructor($,Y){super($);this.code=Y;this.name="PathSecurityError"}}});var l6;var X3=R(()=>{l6=class l6{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 Q3 from"fast-glob";import*as q$ from"fs/promises";import*as J3 from"path";class j8{fileCache=new Map;options;constructor($){this.options={maxFileSize:1048576,maxLines:2000,maxTokens:32000,...$},V0.debug("AttachmentCollector initialized",{maxFileSize:this.options.maxFileSize,maxLines:this.options.maxLines})}async collect($){if(!l6.hasAtMentions($))return[];let Y=l6.extract($);if(Y.length===0)return[];V0.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 V0.warn(`Failed to process @${q.path}:`,G),{type:"error",path:q.path,content:"",error:G}}})}async processOne($){if($.isGlob)return V0.debug(`Processing glob pattern: ${$.path}`),await this.processGlob($.path);let Y=await c6.validatePath($.path,this.options.cwd),Z=await c6.resolveSymlink(Y,this.options.cwd);if((await q$.stat(Z)).isDirectory())return V0.debug(`Processing directory: ${$.path}`),await this.renderDirectoryTree(Z,$.path);return V0.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 V0.debug(`Cache hit: ${Y}`),this.formatFileAttachment(Y,X.content,Z);let Q=await q$.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 q$.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(`
580
+ </available_skills>`)}async function rq($){let Y=cq.join($,"BLADE.md");try{return(await H3.readFile(Y,"utf-8")).trim()||null}catch{return null}}var lq;var O3=b(()=>{Q0();F2();h8();g8();lq=/<available_skills>\s*<\/available_skills>/});var F3=b(()=>{O3();g8()});import*as o6 from"fs/promises";import*as s1 from"path";class s6{static normalize($,Y){let Z=s1.isAbsolute($)?$:s1.resolve(Y,$),X=s1.normalize(Z),Q=s1.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(s1.sep);for(let Z of z3)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 o6.access(Z)}catch(X){throw new S2(`Path not found: ${$}`,"PATH_NOT_FOUND")}return Z}static async resolveSymlink($,Y){try{let Z=await o6.realpath($),X=s1.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 s1.relative(Y,$)}static isWithinWorkspace($,Y){let Z=s1.normalize($),X=s1.normalize(Y);return Z.startsWith(X)}static isRestricted($){let Y=$.split(s1.sep);return z3.some((Z)=>Y.includes(Z))}}var z3,S2;var _3=b(()=>{z3=[".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 t6;var N3=b(()=>{t6=class t6{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 B3 from"fast-glob";import*as U$ from"fs/promises";import*as w3 from"path";class m8{fileCache=new Map;options;constructor($){this.options={maxFileSize:1048576,maxLines:2000,maxTokens:32000,...$},v0.debug("AttachmentCollector initialized",{maxFileSize:this.options.maxFileSize,maxLines:this.options.maxLines})}async collect($){if(!t6.hasAtMentions($))return[];let Y=t6.extract($);if(Y.length===0)return[];v0.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 v0.warn(`Failed to process @${q.path}:`,G),{type:"error",path:q.path,content:"",error:G}}})}async processOne($){if($.isGlob)return v0.debug(`Processing glob pattern: ${$.path}`),await this.processGlob($.path);let Y=await s6.validatePath($.path,this.options.cwd),Z=await s6.resolveSymlink(Y,this.options.cwd);if((await U$.stat(Z)).isDirectory())return v0.debug(`Processing directory: ${$.path}`),await this.renderDirectoryTree(Z,$.path);return v0.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 v0.debug(`Cache hit: ${Y}`),this.formatFileAttachment(Y,X.content,Z);let Q=await U$.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 U$.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(`
573
581
  `),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(`
574
582
  `);let U=Array.from({length:W-G},(O,F)=>G+F+1);Q=Q.split(`
575
583
  `).map((O,F)=>`${U[F]}: ${O}`).join(`
576
584
  `),q={start:Z.start,end:W}}else if(X.length>this.options.maxLines)Q=X.slice(0,this.options.maxLines).join(`
577
585
  `),Q+=`
578
586
 
579
- [... 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 Q3("**/*",{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)"};V0.debug(`Found ${Z.length} files in directory: ${Y}`);let X=this.buildFileTree(Z),Q=this.printTree(X,Y),J=500,q=Z.length>J?`
587
+ [... 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 B3("**/*",{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)"};v0.debug(`Found ${Z.length} files in directory: ${Y}`);let X=this.buildFileTree(Z),Q=this.printTree(X,Y),J=500,q=Z.length>J?`
580
588
 
581
589
  [... 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,U=W?"└── ":"├── ",H=G instanceof Map;if(Q.push(`${Z}${U}${q}${H?"/":""}`),H&&G.size>0){let O=Z+(W?" ":"│ ");Q.push(this.printTree(G,"",O,W))}}),Q.filter((q)=>q).join(`
582
- `)}async processGlob($){let Y=await Q3($,{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: ${$}`};V0.debug(`Glob pattern "${$}" matched ${Y.length} files`);let Z=30,X=Y.slice(0,Z),J=(await Promise.allSettled(X.map(async(W)=>{let U=J3.join(this.options.cwd,W);try{let H=await q$.readFile(U,"utf-8"),O=H.split(`
583
- `),F=200,N=H,z=!1;if(O.length>200)N=O.slice(0,200).join(`
584
- `),N+=`
590
+ `)}async processGlob($){let Y=await B3($,{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: ${$}`};v0.debug(`Glob pattern "${$}" matched ${Y.length} files`);let Z=30,X=Y.slice(0,Z),J=(await Promise.allSettled(X.map(async(W)=>{let U=w3.join(this.options.cwd,W);try{let H=await U$.readFile(U,"utf-8"),O=H.split(`
591
+ `),F=200,z=H,_=!1;if(O.length>200)z=O.slice(0,200).join(`
592
+ `),z+=`
585
593
 
586
- [... truncated ${O.length-200} lines ...]`,z=!0;return{path:W,content:N,lines:O.length,truncated:z}}catch(H){return{path:W,content:`[Error: ${H instanceof Error?H.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":""}) ---
594
+ [... truncated ${O.length-200} lines ...]`,_=!0;return{path:W,content:z,lines:O.length,truncated:_}}catch(H){return{path:W,content:`[Error: ${H instanceof Error?H.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":""}) ---
587
595
  ${W.content}`).join(`
588
596
 
589
597
  `),K=Y.length>Z?`
590
598
 
591
- [... and ${Y.length-Z} more files matched]`:"";return{type:"file",path:$,content:G+K,metadata:{lines:J.reduce((W,U)=>W+U.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)V0.debug(`Cleared ${Y} expired cache entries`)}clearCache(){this.fileCache.clear(),V0.debug("Cleared all cache")}getCacheStats(){return{size:this.fileCache.size,keys:Array.from(this.fileCache.keys())}}}var V0;var q3=R(()=>{A1();Z3();X3();V0=i("Prompts")});import*as D0 from"fs/promises";class W2{async readTextFile($){return D0.readFile($,"utf-8")}async writeTextFile($,Y){await D0.writeFile($,Y,"utf-8")}async exists($){try{return await D0.access($),!0}catch{return!1}}async readBinaryFile($){return D0.readFile($)}async stat($){try{let Y=await D0.stat($);return{size:Y.size,isDirectory:Y.isDirectory(),isFile:Y.isFile(),mtime:Y.mtime}}catch{return null}}async mkdir($,Y){await D0.mkdir($,{recursive:Y?.recursive??!1})}}function G$(){return v8}function i6($){v8=$}function G3(){v8=new W2}var v8;var K$=R(()=>{v8=new W2});class y8{connection;sessionId;capabilities;fallback;constructor($,Y,Z,X=new W2){this.connection=$;this.sessionId=Y;this.capabilities=Z;this.fallback=X}async readTextFile($){if(!this.capabilities.readTextFile)return Q0.debug(`[AcpFileSystem] readTextFile fallback: ${$}`),this.fallback.readTextFile($);try{return Q0.debug(`[AcpFileSystem] readTextFile via ACP: ${$}`),(await this.connection.readTextFile({path:$,sessionId:this.sessionId})).content}catch(Y){return Q0.warn(`[AcpFileSystem] readTextFile ACP failed, fallback: ${Y}`),this.fallback.readTextFile($)}}async writeTextFile($,Y){if(!this.capabilities.writeTextFile)return Q0.debug(`[AcpFileSystem] writeTextFile fallback: ${$}`),this.fallback.writeTextFile($,Y);try{Q0.debug(`[AcpFileSystem] writeTextFile via ACP: ${$}`),await this.connection.writeTextFile({path:$,content:Y,sessionId:this.sessionId})}catch(Z){return Q0.warn(`[AcpFileSystem] writeTextFile ACP failed, fallback: ${Z}`),this.fallback.writeTextFile($,Y)}}async exists($){if(!this.capabilities.readTextFile)return Q0.debug(`[AcpFileSystem] exists fallback to local: ${$}`),this.fallback.exists($);try{return await this.connection.readTextFile({path:$,sessionId:this.sessionId}),Q0.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 Q0.debug(`[AcpFileSystem] exists(${$}): false (ACP: not found)`),!1;let J=Nq(Z);return Q0.warn(`[AcpFileSystem] exists(${$}): assuming exists due to ${J} error`,{error:String(Y),errorType:J,filePath:$}),!0}}async readBinaryFile($){return Q0.debug(`[AcpFileSystem] readBinaryFile fallback: ${$}`),this.fallback.readBinaryFile($)}async stat($){return Q0.debug(`[AcpFileSystem] stat fallback: ${$}`),this.fallback.stat($)}async mkdir($,Y){return Q0.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 Nq($){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 Q0;var K3=R(()=>{A1();K$();Q0=i("Agent")});import{spawn as Bq}from"child_process";class E8{async execute($,Y){return new Promise((Z)=>{let X=process.platform==="win32"?"cmd.exe":"/bin/bash",Q=process.platform==="win32"?["/c",$]:["-c",$],J=Bq(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;if(Y?.signal)Y.signal.addEventListener("abort",()=>{K=!0,J.kill("SIGTERM")});J.stdout.on("data",(U)=>{let H=U.toString();q+=H,Y?.onOutput?.(H)}),J.stderr.on("data",(U)=>{let H=U.toString();G+=H,Y?.onOutput?.(H)}),J.on("close",(U)=>{if(W)clearTimeout(W);Z({success:U===0&&!K,stdout:q,stderr:G,exitCode:U,error:K?"Command was terminated":void 0})}),J.on("error",(U)=>{if(W)clearTimeout(W);Z({success:!1,stdout:q,stderr:G,exitCode:null,error:U.message})})})}isAvailable(){return!0}}class W3{connection;sessionId;fallback;constructor($,Y,Z=new E8){this.connection=$;this.sessionId=Y;this.fallback=Z}async execute($,Y){try{h0.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,U])=>({name:W,value:U})):void 0}),X=0,Q=null;if(Y?.onOutput)Q=setInterval(async()=>{try{let U=(await Z.currentOutput()).output||"";if(U.length>X){let H=U.slice(X);X=U.length,Y.onOutput?.(H)}}catch{}},100);let J=(W=!1)=>{if(Q)clearInterval(Q),Q=null;(W?Z.kill().then(()=>h0.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 h0.debug(`[AcpTerminal] Command timed out, killing: ${$}`),J(!0),{success:!1,stdout:K,stderr:"",exitCode:null,error:"Command timed out"};case"aborted":return h0.debug(`[AcpTerminal] Command aborted, killing: ${$}`),J(!0),{success:!1,stdout:K,stderr:"",exitCode:null,error:"Command was aborted"}}}catch(Z){return h0.warn("[AcpTerminal] ACP terminal failed, using fallback:",Z),this.fallback.execute($,Y)}}isAvailable(){return!0}}function U3(){return n.getInstance().getTerminalService()}function U2(){return n.getInstance().isAcpMode()}var h0,n;var W$=R(()=>{A1();K$();K3();h0=i("Agent");n=class n{static sessions=new Map;static currentSessionId=null;constructor(){}static getInstance(){return new n}static initializeSession($,Y,Z,X){let Q=Z?.fs?new y8($,Y,Z.fs):new W2;if(Z?.fs)h0.debug(`[AcpServiceContext:${Y}] Using ACP file system service`);let J=new W3($,Y);h0.debug(`[AcpServiceContext:${Y}] Using ACP terminal service`),n.sessions.set(Y,{fileSystemService:Q,terminalService:J,connection:$,clientCapabilities:Z||null,cwd:X}),n.currentSessionId=Y,i6(Q),h0.debug(`[AcpServiceContext:${Y}] Initialized with capabilities:`,{fs:!!Z?.fs,readTextFile:Z?.fs?.readTextFile,writeTextFile:Z?.fs?.writeTextFile,cwd:X})}static destroySession($){if(n.sessions.delete($),n.currentSessionId===$){let Y=Array.from(n.sessions.keys());if(n.currentSessionId=Y[0]||null,!n.currentSessionId)G3();else{let Z=n.sessions.get(n.currentSessionId);if(Z)i6(Z.fileSystemService)}}h0.debug(`[AcpServiceContext:${$}] Session destroyed`)}static getSessionServices($){return n.sessions.get($)||null}static setCurrentSession($){if(n.sessions.has($)){n.currentSessionId=$;let Y=n.sessions.get($);if(Y)i6(Y.fileSystemService)}}static getCurrentSessionId(){return n.currentSessionId}initialize($,Y,Z,X){n.initializeSession($,Y,Z,X||process.cwd())}reset(){if(n.currentSessionId)n.destroySession(n.currentSessionId)}isAcpMode(){return n.currentSessionId!==null}getFileSystemService(){if(n.currentSessionId){let $=n.sessions.get(n.currentSessionId);if($)return $.fileSystemService}return new W2}getTerminalService(){if(n.currentSessionId){let $=n.sessions.get(n.currentSessionId);if($)return $.terminalService}return new E8}getConnection(){if(n.currentSessionId){let $=n.sessions.get(n.currentSessionId);if($)return $.connection}return null}getSessionId(){return n.currentSessionId}getClientCapabilities(){if(n.currentSessionId){let $=n.sessions.get(n.currentSessionId);if($)return $.clientCapabilities}return null}async sendToolUpdate($,Y,Z,X,Q){let J=n.currentSessionId;if(!J)return;let q=n.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){h0.warn("[AcpServiceContext] Failed to send tool update:",G)}}}});import{isAbsolute as H3}from"path";import{z as T1}from"zod";var N1;var H2=R(()=>{N1={filePath:($)=>T1.string().min(1,"File path is required").refine((Y)=>H3(Y),{message:"Path must be absolute"}).describe($?.description||"Absolute file path"),encoding:()=>T1.enum(["utf8","base64","binary"]).default("utf8").describe("File encoding"),timeout:($=1000,Y=300000,Z=30000)=>T1.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:($)=>T1.string().min(1,"Pattern is required").describe($?.description||"Regex or glob pattern"),glob:($)=>T1.string().min(1,"Glob pattern is required").describe($?.description||'Glob pattern (e.g., "*.js", "**/*.ts")'),lineNumber:($)=>T1.number().int("Line number must be an integer").min($?.min??0,`Line number cannot be less than ${$?.min??0}`).describe($?.description||"Line number"),lineLimit:($)=>T1.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:()=>T1.string().min(1,"Working directory is required").refine(($)=>H3($),{message:"Path must be absolute"}).describe("Absolute working directory"),environment:()=>T1.record(T1.string(),T1.string()).describe("Environment variables (key-value)").optional(),outputMode:($,Y)=>{let Z=T1.enum($);return Y?Z.default(Y):Z},flag:($)=>T1.boolean().default($?.defaultValue??!1).describe($?.description||"Boolean flag"),url:($)=>T1.string().url("Must be a valid URL").describe($?.description||"URL"),port:()=>T1.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:($)=>T1.string().min(1,"Command is required").describe($?.description||"Command to execute"),sessionId:()=>T1.string().min(1,"Session ID is required").uuid("Must be a valid UUID").optional().describe("Session identifier (UUID)"),nonNegativeInt:($)=>T1.number().int("Must be an integer").min(0,"Cannot be negative").describe($?.description||"Non-negative integer"),positiveInt:($)=>T1.number().int("Must be an integer").min(1,"Must be greater than 0").describe($?.description||"Positive integer")}});import*as k8 from"diff";function O3($,Y,Z=4){if($===Y)return null;let X=k8.createPatch("file",$,Y,"","",{context:Z}),Q=X.split(`
599
+ [... and ${Y.length-Z} more files matched]`:"";return{type:"file",path:$,content:G+K,metadata:{lines:J.reduce((W,U)=>W+U.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)v0.debug(`Cleared ${Y} expired cache entries`)}clearCache(){this.fileCache.clear(),v0.debug("Cleared all cache")}getCacheStats(){return{size:this.fileCache.size,keys:Array.from(this.fileCache.keys())}}}var v0;var L3=b(()=>{B1();_3();N3();v0=c("Prompts")});import*as y0 from"fs/promises";class z2{async readTextFile($){return y0.readFile($,"utf-8")}async writeTextFile($,Y){await y0.writeFile($,Y,"utf-8")}async exists($){try{return await y0.access($),!0}catch{return!1}}async readBinaryFile($){return y0.readFile($)}async stat($){try{let Y=await y0.stat($);return{size:Y.size,isDirectory:Y.isDirectory(),isFile:Y.isFile(),mtime:Y.mtime}}catch{return null}}async mkdir($,Y){await y0.mkdir($,{recursive:Y?.recursive??!1})}}function H$(){return d8}function e6($){d8=$}function A3(){d8=new z2}var d8;var O$=b(()=>{d8=new z2});class u8{connection;sessionId;capabilities;fallback;constructor($,Y,Z,X=new z2){this.connection=$;this.sessionId=Y;this.capabilities=Z;this.fallback=X}async readTextFile($){if(!this.capabilities.readTextFile)return q0.debug(`[AcpFileSystem] readTextFile fallback: ${$}`),this.fallback.readTextFile($);try{return q0.debug(`[AcpFileSystem] readTextFile via ACP: ${$}`),(await this.connection.readTextFile({path:$,sessionId:this.sessionId})).content}catch(Y){return q0.warn(`[AcpFileSystem] readTextFile ACP failed, fallback: ${Y}`),this.fallback.readTextFile($)}}async writeTextFile($,Y){if(!this.capabilities.writeTextFile)return q0.debug(`[AcpFileSystem] writeTextFile fallback: ${$}`),this.fallback.writeTextFile($,Y);try{q0.debug(`[AcpFileSystem] writeTextFile via ACP: ${$}`),await this.connection.writeTextFile({path:$,content:Y,sessionId:this.sessionId})}catch(Z){return q0.warn(`[AcpFileSystem] writeTextFile ACP failed, fallback: ${Z}`),this.fallback.writeTextFile($,Y)}}async exists($){if(!this.capabilities.readTextFile)return q0.debug(`[AcpFileSystem] exists fallback to local: ${$}`),this.fallback.exists($);try{return await this.connection.readTextFile({path:$,sessionId:this.sessionId}),q0.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 q0.debug(`[AcpFileSystem] exists(${$}): false (ACP: not found)`),!1;let J=aq(Z);return q0.warn(`[AcpFileSystem] exists(${$}): assuming exists due to ${J} error`,{error:String(Y),errorType:J,filePath:$}),!0}}async readBinaryFile($){return q0.debug(`[AcpFileSystem] readBinaryFile fallback: ${$}`),this.fallback.readBinaryFile($)}async stat($){return q0.debug(`[AcpFileSystem] stat fallback: ${$}`),this.fallback.stat($)}async mkdir($,Y){return q0.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 aq($){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 q0;var b3=b(()=>{B1();O$();q0=c("Agent")});import{spawn as nq}from"child_process";class c8{async execute($,Y){return new Promise((Z)=>{let X=process.platform==="win32"?"cmd.exe":"/bin/bash",Q=process.platform==="win32"?["/c",$]:["-c",$],J=nq(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;if(Y?.signal)Y.signal.addEventListener("abort",()=>{K=!0,J.kill("SIGTERM")});J.stdout.on("data",(U)=>{let H=U.toString();q+=H,Y?.onOutput?.(H)}),J.stderr.on("data",(U)=>{let H=U.toString();G+=H,Y?.onOutput?.(H)}),J.on("close",(U)=>{if(W)clearTimeout(W);Z({success:U===0&&!K,stdout:q,stderr:G,exitCode:U,error:K?"Command was terminated":void 0})}),J.on("error",(U)=>{if(W)clearTimeout(W);Z({success:!1,stdout:q,stderr:G,exitCode:null,error:U.message})})})}isAvailable(){return!0}}class R3{connection;sessionId;fallback;constructor($,Y,Z=new c8){this.connection=$;this.sessionId=Y;this.fallback=Z}async execute($,Y){try{d0.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,U])=>({name:W,value:U})):void 0}),X=0,Q=null;if(Y?.onOutput)Q=setInterval(async()=>{try{let U=(await Z.currentOutput()).output||"";if(U.length>X){let H=U.slice(X);X=U.length,Y.onOutput?.(H)}}catch{}},100);let J=(W=!1)=>{if(Q)clearInterval(Q),Q=null;(W?Z.kill().then(()=>d0.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 d0.debug(`[AcpTerminal] Command timed out, killing: ${$}`),J(!0),{success:!1,stdout:K,stderr:"",exitCode:null,error:"Command timed out"};case"aborted":return d0.debug(`[AcpTerminal] Command aborted, killing: ${$}`),J(!0),{success:!1,stdout:K,stderr:"",exitCode:null,error:"Command was aborted"}}}catch(Z){return d0.warn("[AcpTerminal] ACP terminal failed, using fallback:",Z),this.fallback.execute($,Y)}}isAvailable(){return!0}}function V3(){return n.getInstance().getTerminalService()}function _2(){return n.getInstance().isAcpMode()}var d0,n;var F$=b(()=>{B1();O$();b3();d0=c("Agent");n=class n{static sessions=new Map;static currentSessionId=null;constructor(){}static getInstance(){return new n}static initializeSession($,Y,Z,X){let Q=Z?.fs?new u8($,Y,Z.fs):new z2;if(Z?.fs)d0.debug(`[AcpServiceContext:${Y}] Using ACP file system service`);let J=new R3($,Y);d0.debug(`[AcpServiceContext:${Y}] Using ACP terminal service`),n.sessions.set(Y,{fileSystemService:Q,terminalService:J,connection:$,clientCapabilities:Z||null,cwd:X}),n.currentSessionId=Y,e6(Q),d0.debug(`[AcpServiceContext:${Y}] Initialized with capabilities:`,{fs:!!Z?.fs,readTextFile:Z?.fs?.readTextFile,writeTextFile:Z?.fs?.writeTextFile,cwd:X})}static destroySession($){if(n.sessions.delete($),n.currentSessionId===$){let Y=Array.from(n.sessions.keys());if(n.currentSessionId=Y[0]||null,!n.currentSessionId)A3();else{let Z=n.sessions.get(n.currentSessionId);if(Z)e6(Z.fileSystemService)}}d0.debug(`[AcpServiceContext:${$}] Session destroyed`)}static getSessionServices($){return n.sessions.get($)||null}static setCurrentSession($){if(n.sessions.has($)){n.currentSessionId=$;let Y=n.sessions.get($);if(Y)e6(Y.fileSystemService)}}static getCurrentSessionId(){return n.currentSessionId}initialize($,Y,Z,X){n.initializeSession($,Y,Z,X||process.cwd())}reset(){if(n.currentSessionId)n.destroySession(n.currentSessionId)}isAcpMode(){return n.currentSessionId!==null}getFileSystemService(){if(n.currentSessionId){let $=n.sessions.get(n.currentSessionId);if($)return $.fileSystemService}return new z2}getTerminalService(){if(n.currentSessionId){let $=n.sessions.get(n.currentSessionId);if($)return $.terminalService}return new c8}getConnection(){if(n.currentSessionId){let $=n.sessions.get(n.currentSessionId);if($)return $.connection}return null}getSessionId(){return n.currentSessionId}getClientCapabilities(){if(n.currentSessionId){let $=n.sessions.get(n.currentSessionId);if($)return $.clientCapabilities}return null}async sendToolUpdate($,Y,Z,X,Q){let J=n.currentSessionId;if(!J)return;let q=n.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){d0.warn("[AcpServiceContext] Failed to send tool update:",G)}}}});import{isAbsolute as D3}from"path";import{z as C1}from"zod";var _1;var N2=b(()=>{_1={filePath:($)=>C1.string().min(1,"File path is required").refine((Y)=>D3(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(($)=>D3($),{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 l8 from"diff";function I3($,Y,Z=4){if($===Y)return null;let X=l8.createPatch("file",$,Y,"","",{context:Z}),Q=X.split(`
592
600
  `),J=1;for(let q of Q){let G=q.match(/@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@/);if(G){J=parseInt(G[1],10);break}}return`
593
601
  <<<DIFF>>>
594
602
  ${JSON.stringify({patch:X,startLine:Math.max(1,J-Z),matchLine:J})}
595
603
  <<</DIFF>>>
596
- `}function F3($,Y,Z,X,Q=4){let J=$.indexOf(Z);if(J===-1)return null;let G=$.substring(0,J).split(`
604
+ `}function M3($,Y,Z,X,Q=4){let J=$.indexOf(Z);if(J===-1)return null;let G=$.substring(0,J).split(`
597
605
  `).length-1,K=$.split(`
598
606
  `),W=Y.split(`
599
607
  `),U=Z.split(`
600
608
  `),H=X.split(`
601
- `),O=Math.max(0,G-Q),F=Math.min(K.length,G+U.length+Q),N=Math.min(W.length,G+H.length+Q),z=K.slice(O,F).join(`
602
- `),L=W.slice(O,N).join(`
603
- `),B=k8.createPatch("file",z,L,"","",{context:Q});return`
609
+ `),O=Math.max(0,G-Q),F=Math.min(K.length,G+U.length+Q),z=Math.min(W.length,G+H.length+Q),_=K.slice(O,F).join(`
610
+ `),w=W.slice(O,z).join(`
611
+ `),B=l8.createPatch("file",_,w,"","",{context:Q});return`
604
612
  <<<DIFF>>>
605
613
  ${JSON.stringify({patch:B,startLine:O+1,matchLine:G+1})}
606
614
  <<</DIFF>>>
607
- `}var P8=()=>{};function z3($){return $.replace(/\\+(n|t|r|'|"|`|\\|\n)/g,(Y,Z)=>{switch(Z){case"n":return`
615
+ `}var i8=()=>{};function j3($){return $.replace(/\\+(n|t|r|'|"|`|\\|\n)/g,(Y,Z)=>{switch(Z){case"n":return`
608
616
  `;case"t":return"\t";case"r":return"\r";case"'":return"'";case'"':return'"';case"`":return"`";case"\\":return"\\";case`
609
617
  `:return`
610
- `;default:return Y}})}function _3($,Y){let Z=Y.split(`
618
+ `;default:return Y}})}function v3($,Y){let Z=Y.split(`
611
619
  `);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(`
612
620
  `),K=$.split(`
613
- `);for(let W=0;W<=K.length-Z.length;W++){let U=K[W].match(/^(\s+)/),H=U?U[1]:"",O=K.slice(W,W+Z.length);if(O.map((z)=>{if(z.startsWith(H))return z.slice(H.length);return z}).join(`
621
+ `);for(let W=0;W<=K.length-Z.length;W++){let U=K[W].match(/^(\s+)/),H=U?U[1]:"",O=K.slice(W,W+Z.length);if(O.map((_)=>{if(_.startsWith(H))return _.slice(H.length);return _}).join(`
614
622
  `)===G)return O.join(`
615
- `)}return null}var N3=()=>{};import{promises as r6}from"node:fs";class o1{static instance=null;accessedFiles=new Map;constructor(){}static getInstance(){if(!o1.instance)o1.instance=new o1;return o1.instance}async recordFileRead($,Y){try{let Z=await r6.stat($),X={filePath:$,accessTime:Date.now(),mtime:Z.mtimeMs,sessionId:Y,lastOperation:"read"};this.accessedFiles.set($,X),t$.debug(`记录文件读取: ${$}`)}catch(Z){t$.warn(`记录文件读取失败: ${$}`,Z)}}async recordFileEdit($,Y,Z="edit"){try{let X=await r6.stat($),Q={filePath:$,accessTime:Date.now(),mtime:X.mtimeMs,sessionId:Y,lastOperation:Z};this.accessedFiles.set($,Q),t$.debug(`记录文件${Z==="edit"?"编辑":"写入"}: ${$}`)}catch(X){t$.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 r6.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 r6.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 t$.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(){o1.instance=null}}var t$;var a6=R(()=>{A1();t$=i("Tool")});var L3={};d7(L3,{unescapeProjectPath:()=>S8,listProjectDirectories:()=>C8,getSessionFilePath:()=>I0,getProjectStoragePath:()=>U$,getBladeStorageRoot:()=>O2,escapeProjectPath:()=>B3,detectGitBranch:()=>P2});import{execSync as Lq}from"node:child_process";import*as T8 from"node:os";import*as k2 from"node:path";function B3($){return k2.resolve($).replace(/\//g,"-")}function S8($){if($.startsWith("-"))return"/"+$.slice(1).replace(/-/g,"/");return $.replace(/-/g,"/")}function U$($){let Y=T8.homedir(),Z=B3($);return k2.join(Y,".blade","projects",Z)}function I0($,Y){return k2.join(U$($),`${Y}.jsonl`)}function P2($){try{return Lq("git rev-parse --abbrev-ref HEAD",{cwd:$,encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()||void 0}catch{return}}function O2(){return k2.join(T8.homedir(),".blade")}async function C8(){let{readdir:$}=await import("node:fs/promises");try{let Y=k2.join(O2(),"projects");return(await $(Y,{withFileTypes:!0})).filter((X)=>X.isDirectory()).map((X)=>X.name)}catch{return[]}}var H$=()=>{};import*as w3 from"node:crypto";import{promises as x0}from"node:fs";import*as T2 from"node:path";class e${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=T2.join(Y,"file-history",this.sessionId)}async initialize(){if(!this.enableCheckpoints)return;try{await x0.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 x0.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=T2.join(this.snapshotDir,`${Q}@v${X}`);try{let q=await x0.readFile($,{encoding:"utf-8"});await x0.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=T2.join(this.snapshotDir,`${Z.backupFileName}@v${X.version}`);try{let J=await x0.readFile(Q,{encoding:"utf-8"});await x0.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=T2.join(this.snapshotDir,`${Q.backupFileName}@v${J.version}`);try{await x0.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 x0.readdir(this.snapshotDir);if(Y.length<=$)return;let Z=await Promise.all(Y.map(async(Q)=>{let J=T2.join(this.snapshotDir,Q),q=await x0.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=T2.join(this.snapshotDir,Q);await x0.unlink(J),console.log(`[SnapshotManager] 清理快照: ${J}`)}}catch(Y){console.warn("[SnapshotManager] 清理快照失败:",Y)}}generateFileHash($,Y){let Z=w3.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 f8=R(()=>{H$()});import{extname as wq}from"path";import{z as n6}from"zod";function A3($){return $.replaceAll("‘","'").replaceAll("’","'").replaceAll("“",'"').replaceAll("”",'"')}function Aq($,Y){if($.includes(Y))return{matched:Y,strategy:"exact"};let Z=A3(Y),Q=A3($).indexOf(Z);if(Q!==-1)return{matched:$.substring(Q,Q+Y.length),strategy:"normalize_quotes"};let J=z3(Y);if(J!==Y&&$.includes(J))return{matched:J,strategy:"unescape"};let q=_3($,Y);if(q)return{matched:q,strategy:"flexible"};return{matched:null,strategy:"failed"}}function bq($,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 Rq($,Y){let{file_path:Z,matches_found:X,replacements_made:Q,replace_all:J,size_diff:q}=$,G=`✅ 成功编辑文件: ${Z}`;if(G+=`
623
+ `)}return null}var y3=()=>{};import{promises as $4}from"node:fs";class e1{static instance=null;accessedFiles=new Map;constructor(){}static getInstance(){if(!e1.instance)e1.instance=new e1;return e1.instance}async recordFileRead($,Y){try{let Z=await $4.stat($),X={filePath:$,accessTime:Date.now(),mtime:Z.mtimeMs,sessionId:Y,lastOperation:"read"};this.accessedFiles.set($,X),Y6.debug(`记录文件读取: ${$}`)}catch(Z){Y6.warn(`记录文件读取失败: ${$}`,Z)}}async recordFileEdit($,Y,Z="edit"){try{let X=await $4.stat($),Q={filePath:$,accessTime:Date.now(),mtime:X.mtimeMs,sessionId:Y,lastOperation:Z};this.accessedFiles.set($,Q),Y6.debug(`记录文件${Z==="edit"?"编辑":"写入"}: ${$}`)}catch(X){Y6.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 $4.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 $4.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 Y6.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(){e1.instance=null}}var Y6;var Y4=b(()=>{B1();Y6=c("Tool")});import{execSync as oq}from"node:child_process";import*as r8 from"node:os";import*as C2 from"node:path";function sq($){return C2.resolve($).replace(/\//g,"-")}function E3($){if($.startsWith("-"))return"/"+$.slice(1).replace(/-/g,"/");return $.replace(/-/g,"/")}function Z6($){let Y=r8.homedir(),Z=sq($);return C2.join(Y,".blade","projects",Z)}function O0($,Y){return C2.join(Z6($),`${Y}.jsonl`)}function z$($){try{return oq("git rev-parse --abbrev-ref HEAD",{cwd:$,encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()||void 0}catch{return}}function f2(){return C2.join(r8.homedir(),".blade")}async function k3(){let{readdir:$}=await import("node:fs/promises");try{let Y=C2.join(f2(),"projects");return(await $(Y,{withFileTypes:!0})).filter((X)=>X.isDirectory()).map((X)=>X.name)}catch{return[]}}var X6=()=>{};import*as P3 from"node:crypto";import{promises as u0}from"node:fs";import*as h2 from"node:path";class Q6{sessionId;enableCheckpoints;maxSnapshots;snapshotDir;trackedFileBackups=new Map;snapshots=[];constructor($){this.sessionId=$.sessionId,this.enableCheckpoints=$.enableCheckpoints??!0,this.maxSnapshots=$.maxSnapshots??10;let Y=f2();this.snapshotDir=h2.join(Y,"file-history",this.sessionId)}async initialize(){if(!this.enableCheckpoints)return;try{await u0.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 u0.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=h2.join(this.snapshotDir,`${Q}@v${X}`);try{let q=await u0.readFile($,{encoding:"utf-8"});await u0.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=h2.join(this.snapshotDir,`${Z.backupFileName}@v${X.version}`);try{let J=await u0.readFile(Q,{encoding:"utf-8"});await u0.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=h2.join(this.snapshotDir,`${Q.backupFileName}@v${J.version}`);try{await u0.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 u0.readdir(this.snapshotDir);if(Y.length<=$)return;let Z=await Promise.all(Y.map(async(Q)=>{let J=h2.join(this.snapshotDir,Q),q=await u0.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=h2.join(this.snapshotDir,Q);await u0.unlink(J),console.log(`[SnapshotManager] 清理快照: ${J}`)}}catch(Y){console.warn("[SnapshotManager] 清理快照失败:",Y)}}generateFileHash($,Y){let Z=P3.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 a8=b(()=>{X6()});import{extname as tq}from"path";import{z as Z4}from"zod";function T3($){return $.replaceAll("‘","'").replaceAll("’","'").replaceAll("“",'"').replaceAll("”",'"')}function eq($,Y){if($.includes(Y))return{matched:Y,strategy:"exact"};let Z=T3(Y),Q=T3($).indexOf(Z);if(Q!==-1)return{matched:$.substring(Q,Q+Y.length),strategy:"normalize_quotes"};let J=j3(Y);if(J!==Y&&$.includes(J))return{matched:J,strategy:"unescape"};let q=v3($,Y);if(q)return{matched:q,strategy:"flexible"};return{matched:null,strategy:"failed"}}function $G($,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 YG($,Y){let{file_path:Z,matches_found:X,replacements_made:Q,replace_all:J,size_diff:q}=$,G=`✅ 成功编辑文件: ${Z}`;if(G+=`
616
624
  \uD83D\uDCDD 替换了 ${Q} 个匹配项`,!J&&X>1)G+=` (共找到 ${X} 个匹配项)`;if(q!==0){let K=q>0?`增加${q}`:`减少${Math.abs(q)}`;G+=`
617
- \uD83D\uDCCA 文件大小${K}个字符`}if(Y)G+=Y;return G}function Vq($,Y,Z){let X=$.split(`
618
- `),Q=X.length,J=Dq($,Y,3),q=0,G=Math.min(20,Q);if(J.length>0){let F=J[0];q=Math.max(0,F.lineNumber-10),G=Math.min(Q,F.lineNumber+10)}let W=X.slice(q,G).map((F,N)=>{return` ${(q+N+1).toString().padStart(4)}: ${F}`}).join(`
625
+ \uD83D\uDCCA 文件大小${K}个字符`}if(Y)G+=Y;return G}function ZG($,Y,Z){let X=$.split(`
626
+ `),Q=X.length,J=XG($,Y,3),q=0,G=Math.min(20,Q);if(J.length>0){let F=J[0];q=Math.max(0,F.lineNumber-10),G=Math.min(Q,F.lineNumber+10)}let W=X.slice(q,G).map((F,z)=>{return` ${(q+z+1).toString().padStart(4)}: ${F}`}).join(`
619
627
  `),U=`String not found in file.
620
628
 
621
629
  File: ${Z}
@@ -632,8 +640,8 @@ ${W}
632
640
  ${W}
633
641
 
634
642
  `;if(J.length>0)U+=`Possible similar matches found:
635
- `,J.forEach((F,N)=>{let z=F.text.length>100?F.text.substring(0,100)+"...":F.text;U+=` ${N+1}. Line ${F.lineNumber} (similarity: ${Math.round(F.similarity*100)}%)
636
- ${z.replace(/\n/g,"\\n")}
643
+ `,J.forEach((F,z)=>{let _=F.text.length>100?F.text.substring(0,100)+"...":F.text;U+=` ${z+1}. Line ${F.lineNumber} (similarity: ${Math.round(F.similarity*100)}%)
644
+ ${_.replace(/\n/g,"\\n")}
637
645
  `}),U+=`
638
646
  `;U+=`Recovery suggestions:
639
647
  1. Use the Read tool to verify the current file content
@@ -651,7 +659,7 @@ Common issues:
651
659
  搜索字符串长度: ${Y.length} 字符
652
660
  `;if(J.length>0)O+=`
653
661
  \uD83D\uDCA1 找到 ${J.length} 个相似匹配项:
654
- `,J.forEach((F,N)=>{O+=` ${N+1}. 第 ${F.lineNumber} 行 (相似度: ${Math.round(F.similarity*100)}%)
662
+ `,J.forEach((F,z)=>{O+=` ${z+1}. 第 ${F.lineNumber} 行 (相似度: ${Math.round(F.similarity*100)}%)
655
663
  `});else O+=`
656
664
  ⚠️ 未找到相似的匹配项
657
665
  `;return O+=`
@@ -661,29 +669,29 @@ ${W}
661
669
  \uD83D\uDD27 建议:
662
670
  `,O+=` 1. 使用 Read 工具重新读取文件
663
671
  `,O+=` 2. 检查空格、换行符、引号是否完全匹配
664
- `,O+=" 3. 提供更多上下文代码确保唯一性",{llmContent:U,displayContent:O,metadata:{searchStringLength:Y.length,fuzzyMatches:J.map((F)=>({line:F.lineNumber,similarity:F.similarity,preview:F.text.substring(0,100)})),excerptRange:[q+1,G],totalLines:Q}}}function Dq($,Y,Z=3){let X=$.split(`
672
+ `,O+=" 3. 提供更多上下文代码确保唯一性",{llmContent:U,displayContent:O,metadata:{searchStringLength:Y.length,fuzzyMatches:J.map((F)=>({line:F.lineNumber,similarity:F.similarity,preview:F.text.substring(0,100)})),excerptRange:[q+1,G],totalLines:Q}}}function XG($,Y,Z=3){let X=$.split(`
665
673
  `),Q=Y.split(`
666
- `);if(Q.length===1)return X.map((K,W)=>({text:K,lineNumber:W+1,similarity:b3(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(`
667
- `),W=b3(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 b3($,Y){let Z=(O)=>O.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),U=Iq(K,W),H=Math.max(K.length,W.length);return 1-U/H}function Iq($,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 h8;var R3=R(()=>{W$();K$();P1();d1();H2();P8();N3();a6();f8();h8=Q1({name:"Edit",displayName:"File Edit",kind:"write",strict:!0,isConcurrencySafe:!1,schema:n6.object({file_path:N1.filePath({description:"Absolute path of the file to edit"}),old_string:n6.string().min(1,"old_string cannot be empty").describe("String to replace"),new_string:n6.string().describe("Replacement string (can be empty)"),replace_all:n6.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 U=G$(),H=U2(),O;try{if(H)q?.("通过 IDE 读取文件...");O=await U.readTextFile(Z)}catch(D){if(D.code==="ENOENT"||D.message?.includes("not found"))return{success:!1,llmContent:`File not found: ${Z}`,displayContent:`❌ 文件不存在: ${Z}`,error:{type:"execution_error",message:"文件不存在"}};throw D}if(W.throwIfAborted(),G){let D=o1.getInstance();if(!D.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 工具读取文件
674
+ `);if(Q.length===1)return X.map((K,W)=>({text:K,lineNumber:W+1,similarity:S3(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(`
675
+ `),W=S3(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 S3($,Y){let Z=(O)=>O.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),U=QG(K,W),H=Math.max(K.length,W.length);return 1-U/H}function QG($,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 n8;var C3=b(()=>{F$();O$();S1();c1();N2();i8();y3();Y4();a8();n8=Q1({name:"Edit",displayName:"File Edit",kind:"write",strict:!0,isConcurrencySafe:!1,schema:Z4.object({file_path:_1.filePath({description:"Absolute path of the file to edit"}),old_string:Z4.string().min(1,"old_string cannot be empty").describe("String to replace"),new_string:Z4.string().describe("Replacement string (can be empty)"),replace_all:Z4.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 U=H$(),H=_2(),O;try{if(H)q?.("通过 IDE 读取文件...");O=await U.readTextFile(Z)}catch(V){if(V.code==="ENOENT"||V.message?.includes("not found"))return{success:!1,llmContent:`File not found: ${Z}`,displayContent:`❌ 文件不存在: ${Z}`,error:{type:"execution_error",message:"文件不存在"}};throw V}if(W.throwIfAborted(),G){let V=e1.getInstance();if(!V.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 工具读取文件
668
676
 
669
- 请先用 Read 工具查看文件内容,再进行编辑。`,error:{type:"validation_error",message:"File not read before edit"}};let y=await D.checkExternalModification(Z);if(y.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.
677
+ 请先用 Read 工具查看文件内容,再进行编辑。`,error:{type:"validation_error",message:"File not read before edit"}};let v=await V.checkExternalModification(Z);if(v.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.
670
678
 
671
- Details: ${y.message}`,displayContent:`❌ 编辑失败:文件已被外部程序修改
679
+ Details: ${v.message}`,displayContent:`❌ 编辑失败:文件已被外部程序修改
672
680
 
673
- ${y.message}
681
+ ${v.message}
674
682
 
675
- \uD83D\uDCA1 请重新使用 Read 工具读取最新内容后再编辑`,error:{type:"validation_error",message:"File modified externally",details:{externalModification:y.message}}}}if(G&&K)try{let D=new e$({sessionId:G});await D.initialize(),await D.createSnapshot(Z,K)}catch(D){console.warn("[EditTool] 创建快照失败:",D)}if(X===Q)return{success:!1,llmContent:"New string is identical; no replacement needed",displayContent:"⚠️ 新字符串与旧字符串相同,无需进行替换",error:{type:"validation_error",message:"新旧字符串相同"}};let F=Aq(O,X);if(!F.matched){let D=Vq(O,X,Z);return{success:!1,llmContent:D.llmContent,displayContent:D.displayContent,error:{type:"execution_error",message:"未找到匹配内容",details:D.metadata}}}let N=F.matched;if(F.strategy!=="exact")console.log(`[SmartEdit] 使用策略: ${F.strategy}`);let z=bq(O,N);if(z.length>1&&!J){let D=O.split(`
676
- `),y=0,k=[];for(let T=0;T<D.length;T++){let Y1=D[T],r=y,t=y+Y1.length;for(let p of z)if(p>=r&&p<t){let P0=Math.max(0,T-1),G1=Math.min(D.length-1,T+1),a0=D.slice(P0,G1+1).map((l)=>l.trim()).join(" ").slice(0,80);k.push({line:T+1,column:p-r+1,context:a0})}y=t+1}let f=[`⚠️ EDIT PAUSED: old_string matches ${z.length} locations (must be unique).`,"","**Matches found at:**",...k.map((T,Y1)=>` ${Y1+1}. Line ${T.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(`
677
- `),A=["⚠️ 编辑暂停:需要更精确的定位","",`在文件中找到 ${z.length} 处相似代码:`,...k.map((T,Y1)=>` • 第 ${T.line} 行 (匹配 ${Y1+1}/${z.length})`),"","AI 正在自动调整,添加更多上下文以精确定位...","通常需要 1-2 次尝试即可成功","","\uD83D\uDCA1 如果多次失败,可能需要:"," • 包含函数/类名等独特标识符"," • 添加目标代码前后 3-5 行完整上下文",` • 或使用 replace_all=true 同时替换所有 ${z.length} 处匹配`].join(`
678
- `);return{success:!1,llmContent:f,displayContent:A,error:{type:"validation_error",message:"old_string is not unique",details:{matches:k.map((T)=>({line:T.line,column:T.column})),count:z.length}}}}else q?.(`找到 ${z.length} 个匹配项,开始替换...`);let L,B;if(J)L=O.split(N).join(Q),B=z.length;else{let D=O.indexOf(N);L=O.substring(0,D)+Q+O.substring(D+N.length),B=1}if(W.throwIfAborted(),H)q?.("通过 IDE 写入文件...");if(await U.writeTextFile(Z,L),G)await o1.getInstance().recordFileEdit(Z,G,"edit");let _=await U.stat(Z),b=F3(O,L,N,Q,4),I=Z.split("/").pop()||Z,w=B===1?`替换 1 处匹配到 ${I}`:`替换 ${B} 处匹配到 ${I}`,M={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:O.length,new_size:L.length,size_diff:L.length-O.length,last_modified:_?.mtime instanceof Date?_.mtime.toISOString():void 0,snapshot_created:!!(G&&K),session_id:G,message_id:K,diff_snippet:b,summary:w,kind:"edit",oldContent:O,newContent:L},V=Rq(M,b);return{success:!0,llmContent:{file_path:Z,replacements:B,total_matches:z.length},displayContent:V,metadata:M}}catch(U){if(U.name==="AbortError")return{success:!1,llmContent:"File edit aborted",displayContent:"⚠️ 文件编辑被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`File edit failed: ${U.message}`,displayContent:`❌ 编辑文件失败: ${U.message}`,error:{type:"execution_error",message:U.message,details:U}}}},version:"2.0.0",category:"文件操作",tags:["file","edit","replace","modify"],extractSignatureContent:($)=>$.file_path,abstractPermissionRule:($)=>{let Y=wq($.file_path);return Y?`**/*${Y}`:"**/*"}})});import{extname as V3}from"path";import{z as Mq}from"zod";function jq($){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 vq($){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 yq($,Y){let Z=`✅ 成功读取文件: ${$}`;if(Y.file_size!==void 0)Z+=` (${Eq(Y.file_size)})`;if(Y.lines_read!==void 0)Z+=`
683
+ \uD83D\uDCA1 请重新使用 Read 工具读取最新内容后再编辑`,error:{type:"validation_error",message:"File modified externally",details:{externalModification:v.message}}}}if(G&&K)try{let V=new Q6({sessionId:G});await V.initialize(),await V.createSnapshot(Z,K)}catch(V){console.warn("[EditTool] 创建快照失败:",V)}if(X===Q)return{success:!1,llmContent:"New string is identical; no replacement needed",displayContent:"⚠️ 新字符串与旧字符串相同,无需进行替换",error:{type:"validation_error",message:"新旧字符串相同"}};let F=eq(O,X);if(!F.matched){let V=ZG(O,X,Z);return{success:!1,llmContent:V.llmContent,displayContent:V.displayContent,error:{type:"execution_error",message:"未找到匹配内容",details:V.metadata}}}let z=F.matched;if(F.strategy!=="exact")console.log(`[SmartEdit] 使用策略: ${F.strategy}`);let _=$G(O,z);if(_.length>1&&!J){let V=O.split(`
684
+ `),v=0,k=[];for(let T=0;T<V.length;T++){let Y1=V[T],r=v,t=v+Y1.length;for(let p of _)if(p>=r&&p<t){let C0=Math.max(0,T-1),G1=Math.min(V.length-1,T+1),t0=V.slice(C0,G1+1).map((i)=>i.trim()).join(" ").slice(0,80);k.push({line:T+1,column:p-r+1,context:t0})}v=t+1}let f=[`⚠️ EDIT PAUSED: old_string matches ${_.length} locations (must be unique).`,"","**Matches found at:**",...k.map((T,Y1)=>` ${Y1+1}. Line ${T.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 ${_.length} occurrences`,"","\uD83E\uDD16 **Auto-retry expected** - This usually resolves in 1-2 attempts."].join(`
685
+ `),R=["⚠️ 编辑暂停:需要更精确的定位","",`在文件中找到 ${_.length} 处相似代码:`,...k.map((T,Y1)=>` • 第 ${T.line} 行 (匹配 ${Y1+1}/${_.length})`),"","AI 正在自动调整,添加更多上下文以精确定位...","通常需要 1-2 次尝试即可成功","","\uD83D\uDCA1 如果多次失败,可能需要:"," • 包含函数/类名等独特标识符"," • 添加目标代码前后 3-5 行完整上下文",` • 或使用 replace_all=true 同时替换所有 ${_.length} 处匹配`].join(`
686
+ `);return{success:!1,llmContent:f,displayContent:R,error:{type:"validation_error",message:"old_string is not unique",details:{matches:k.map((T)=>({line:T.line,column:T.column})),count:_.length}}}}else q?.(`找到 ${_.length} 个匹配项,开始替换...`);let w,B;if(J)w=O.split(z).join(Q),B=_.length;else{let V=O.indexOf(z);w=O.substring(0,V)+Q+O.substring(V+z.length),B=1}if(W.throwIfAborted(),H)q?.("通过 IDE 写入文件...");if(await U.writeTextFile(Z,w),G)await e1.getInstance().recordFileEdit(Z,G,"edit");let N=await U.stat(Z),I=M3(O,w,z,Q,4),M=Z.split("/").pop()||Z,A=B===1?`替换 1 处匹配到 ${M}`:`替换 ${B} 处匹配到 ${M}`,D={file_path:Z,matches_found:_.length,replacements_made:B,replace_all:J,old_string_length:X.length,new_string_length:Q.length,original_size:O.length,new_size:w.length,size_diff:w.length-O.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:O,newContent:w},L=YG(D,I);return{success:!0,llmContent:{file_path:Z,replacements:B,total_matches:_.length},displayContent:L,metadata:D}}catch(U){if(U.name==="AbortError")return{success:!1,llmContent:"File edit aborted",displayContent:"⚠️ 文件编辑被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`File edit failed: ${U.message}`,displayContent:`❌ 编辑文件失败: ${U.message}`,error:{type:"execution_error",message:U.message,details:U}}}},version:"2.0.0",category:"文件操作",tags:["file","edit","replace","modify"],extractSignatureContent:($)=>$.file_path,abstractPermissionRule:($)=>{let Y=tq($.file_path);return Y?`**/*${Y}`:"**/*"}})});import{extname as f3}from"path";import{z as JG}from"zod";function qG($){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 GG($){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 KG($,Y){let Z=`✅ 成功读取文件: ${$}`;if(Y.file_size!==void 0)Z+=` (${WG(Y.file_size)})`;if(Y.lines_read!==void 0)Z+=`
679
687
  \uD83D\uDCC4 读取了 ${Y.lines_read} 行 (第${Y.start_line}-${Y.end_line}行,共${Y.total_lines}行)`;if(Y.is_binary)Z+=`
680
- \uD83D\uDD10 文件以 base64 编码显示`;return Z}function Eq($){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 x8;var D3=R(()=>{W$();K$();P1();d1();H2();a6();x8=Q1({name:"Read",displayName:"File Read",kind:"readonly",schema:Mq.object({file_path:N1.filePath({description:"File path to read (must be absolute)"}),offset:N1.lineNumber({description:"Starting line number (0-based, text files only)"}).optional(),limit:N1.lineLimit({description:"Number of lines to read (text files only)"}).optional(),encoding:N1.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=G$(),U=U2();try{if(!await W.exists(Z))throw Error("File not found")}catch(w){return{success:!1,llmContent:`File not found: ${Z}`,displayContent:`❌ 文件不存在: ${Z}`,error:{type:"execution_error",message:`File not found: ${Z}`}}}if(K.throwIfAborted(),G)await o1.getInstance().recordFileRead(Z,G);let H=await W.stat(Z);if(H?.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 O=V3(Z).toLowerCase(),F=jq(O),N=vq(O),z,L={file_path:Z,file_size:H?.size,file_type:O,last_modified:H?.mtime instanceof Date?H.mtime.toISOString():void 0,encoding:J,acp_mode:U};if(N&&J==="utf8"){if(U)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(F){if(U)q?.("通过 IDE 读取文件...");z=await W.readTextFile(Z)}else{if(U)L.acp_fallback=!0;let w=await W.readBinaryFile(Z);if(J==="base64")z=w.toString("base64");else if(J==="binary")z=w.toString("binary");else z=w.toString("utf8")}if(K.throwIfAborted(),(X!==void 0||Q!==void 0)&&J==="utf8"&&F){let w=z.split(`
681
- `),M=X||0,V=Q!==void 0?M+Q:w.length,D=w.slice(M,V);z=D.map((y,k)=>{let f=M+k+1,A=y.length>2000?`${y.substring(0,2000)}...`:y;return`${f.toString().padStart(6)}→${A}`}).join(`
682
- `),L.lines_read=D.length,L.total_lines=w.length,L.start_line=M+1,L.end_line=Math.min(V,w.length)}let B=Z.split("/").pop()||Z,_=L.lines_read||L.total_lines,b=_?`读取 ${_} 行从 ${B}`:`读取 ${B}`;L.summary=b;let I=yq(Z,L);return{success:!0,llmContent:z,displayContent:I,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=V3($.file_path);return Y?`**/*${Y}`:"**/*"}})});import{promises as kq}from"fs";import{dirname as Pq,extname as I3}from"path";import{z as p8}from"zod";function Tq($,Y,Z,X){let Q=`✅ 成功写入文件: ${$}`;if(Y.file_size!==void 0)Q+=` (${M3(Y.file_size)})`;if(Y.snapshot_created)Q+=`
688
+ \uD83D\uDD10 文件以 base64 编码显示`;return Z}function WG($){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 o8;var h3=b(()=>{F$();O$();S1();c1();N2();Y4();o8=Q1({name:"Read",displayName:"File Read",kind:"readonly",schema:JG.object({file_path:_1.filePath({description:"File path to read (must be absolute)"}),offset:_1.lineNumber({description:"Starting line number (0-based, text files only)"}).optional(),limit:_1.lineLimit({description:"Number of lines to read (text files only)"}).optional(),encoding:_1.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=H$(),U=_2();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 e1.getInstance().recordFileRead(Z,G);let H=await W.stat(Z);if(H?.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 O=f3(Z).toLowerCase(),F=qG(O),z=GG(O),_,w={file_path:Z,file_size:H?.size,file_type:O,last_modified:H?.mtime instanceof Date?H.mtime.toISOString():void 0,encoding:J,acp_mode:U};if(z&&J==="utf8"){if(U)q?.("⚠️ 二进制文件通过本地读取(ACP 不支持)..."),w.acp_fallback=!0;else q?.("检测到二进制文件,使用 base64 编码...");_=(await W.readBinaryFile(Z)).toString("base64"),w.encoding="base64",w.is_binary=!0}else if(F){if(U)q?.("通过 IDE 读取文件...");_=await W.readTextFile(Z)}else{if(U)w.acp_fallback=!0;let A=await W.readBinaryFile(Z);if(J==="base64")_=A.toString("base64");else if(J==="binary")_=A.toString("binary");else _=A.toString("utf8")}if(K.throwIfAborted(),(X!==void 0||Q!==void 0)&&J==="utf8"&&F){let A=_.split(`
689
+ `),D=X||0,L=Q!==void 0?D+Q:A.length,V=A.slice(D,L);_=V.map((v,k)=>{let f=D+k+1,R=v.length>2000?`${v.substring(0,2000)}...`:v;return`${f.toString().padStart(6)}→${R}`}).join(`
690
+ `),w.lines_read=V.length,w.total_lines=A.length,w.start_line=D+1,w.end_line=Math.min(L,A.length)}let B=Z.split("/").pop()||Z,N=w.lines_read||w.total_lines,I=N?`读取 ${N} 行从 ${B}`:`读取 ${B}`;w.summary=I;let M=KG(Z,w);return{success:!0,llmContent:_,displayContent:M,metadata:w}}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=f3($.file_path);return Y?`**/*${Y}`:"**/*"}})});import{promises as UG}from"fs";import{dirname as HG,extname as x3}from"path";import{z as s8}from"zod";function OG($,Y,Z,X){let Q=`✅ 成功写入文件: ${$}`;if(Y.file_size!==void 0)Q+=` (${p3(Y.file_size)})`;if(Y.snapshot_created)Q+=`
683
691
  \uD83D\uDCF8 已创建快照 (可回滚)`;if(Y.encoding!=="utf8")Q+=`
684
- \uD83D\uDD10 使用编码: ${Y.encoding}`;if(X)Q+=X;if(Z&&Y.encoding==="utf8"&&!X){let J=Sq($,Z);if(J)Q+=`
692
+ \uD83D\uDD10 使用编码: ${Y.encoding}`;if(X)Q+=X;if(Z&&Y.encoding==="utf8"&&!X){let J=FG($,Z);if(J)Q+=`
685
693
 
686
- `+J}return Q}function Sq($,Y){let Z=I3($).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(`
694
+ `+J}return Q}function FG($,Y){let Z=x3($).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(`
687
695
  `);if(W.length>100)G=W.slice(0,100).join(`
688
696
  `),K=!0;if(G.length>5000)G=G.substring(0,5000),K=!0;let U=`\uD83D\uDCC4 文件内容:
689
697
 
@@ -692,26 +700,26 @@ ${y.message}
692
700
  `))U+=`
693
701
  `;if(U+="```",K)U+=`
694
702
 
695
- ⚠️ 内容已截断(完整文件共 ${W.length} 行,${Y.length} 字符)`;return U}function M3($){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 g8;var j3=R(()=>{W$();K$();P1();d1();H2();P8();a6();f8();g8=Q1({name:"Write",displayName:"File Write",kind:"write",strict:!0,isConcurrencySafe:!1,schema:p8.object({file_path:N1.filePath({description:"Absolute file path to write"}),content:p8.string().describe("Content to write"),encoding:N1.encoding(),create_directories:p8.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 U=G$(),H=U2();if(J){let w=Pq(Z);try{await U.mkdir(w,{recursive:!0})}catch(M){if(M.code!=="EEXIST")throw M}}W.throwIfAborted();let O=!1,F=null;try{if(O=await U.exists(Z),O&&Q==="utf8")try{F=await U.readTextFile(Z)}catch(w){console.warn("[WriteTool] 读取旧文件内容失败:",w)}}catch{}if(O&&G){let w=o1.getInstance();if(!w.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 工具读取文件
703
+ ⚠️ 内容已截断(完整文件共 ${W.length} 行,${Y.length} 字符)`;return U}function p3($){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 t8;var g3=b(()=>{F$();O$();S1();c1();N2();i8();Y4();a8();t8=Q1({name:"Write",displayName:"File Write",kind:"write",strict:!0,isConcurrencySafe:!1,schema:s8.object({file_path:_1.filePath({description:"Absolute file path to write"}),content:s8.string().describe("Content to write"),encoding:_1.encoding(),create_directories:s8.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 U=H$(),H=_2();if(J){let A=HG(Z);try{await U.mkdir(A,{recursive:!0})}catch(D){if(D.code!=="EEXIST")throw D}}W.throwIfAborted();let O=!1,F=null;try{if(O=await U.exists(Z),O&&Q==="utf8")try{F=await U.readTextFile(Z)}catch(A){console.warn("[WriteTool] 读取旧文件内容失败:",A)}}catch{}if(O&&G){let A=e1.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 工具读取文件
696
704
 
697
- 文件 ${Z} 已存在,请先用 Read 工具查看其内容。`,error:{type:"validation_error",message:"File not read before write"}};let M=await w.checkExternalModification(Z);if(M.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.
705
+ 文件 ${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.
698
706
 
699
- Details: ${M.message}`,displayContent:`❌ 写入失败:文件已被外部程序修改
707
+ Details: ${D.message}`,displayContent:`❌ 写入失败:文件已被外部程序修改
700
708
 
701
- ${M.message}
709
+ ${D.message}
702
710
 
703
- \uD83D\uDCA1 请重新使用 Read 工具读取最新内容后再写入`,error:{type:"validation_error",message:"File modified externally",details:{externalModification:M.message}}}}let N=!1;if(O&&G&&K)try{let w=new e$({sessionId:G});await w.initialize(),await w.createSnapshot(Z,K),N=!0}catch(w){console.warn("[WriteTool] 创建快照失败:",w)}if(W.throwIfAborted(),Q==="utf8"){if(H)q?.("通过 IDE 写入文件...");await U.writeTextFile(Z,X)}else{if(H)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 模式不支持二进制文件写入
711
+ \uD83D\uDCA1 请重新使用 Read 工具读取最新内容后再写入`,error:{type:"validation_error",message:"File modified externally",details:{externalModification:D.message}}}}let z=!1;if(O&&G&&K)try{let A=new Q6({sessionId:G});await A.initialize(),await A.createSnapshot(Z,K),z=!0}catch(A){console.warn("[WriteTool] 创建快照失败:",A)}if(W.throwIfAborted(),Q==="utf8"){if(H)q?.("通过 IDE 写入文件...");await U.writeTextFile(Z,X)}else{if(H)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 模式不支持二进制文件写入
704
712
 
705
713
  当前通过 IDE 执行文件操作,但 IDE 仅支持文本文件。
706
714
 
707
715
  \uD83D\uDCA1 建议:
708
716
  • 如果是文本文件,使用 encoding='utf8'
709
- • 如果必须写入二进制文件,请在本地终端执行`,error:{type:"validation_error",message:"Binary writes not supported in ACP mode"}};let w;if(Q==="base64")w=Buffer.from(X,"base64");else if(Q==="binary")w=Buffer.from(X,"binary");else w=Buffer.from(X,"utf8");await kq.writeFile(Z,w)}if(G)await o1.getInstance().recordFileEdit(Z,G,"write");W.throwIfAborted();let z=await U.stat(Z),L=Q==="utf8"?X.split(`
710
- `).length:0,B=Z.split("/").pop()||Z,_=null;if(F&&Q==="utf8"&&F!==X){if(F.length<1048576&&X.length<1048576)_=O3(F,X,4)}let b={file_path:Z,content_size:X.length,file_size:z?.size,encoding:Q,created_directories:J,snapshot_created:N,session_id:G,message_id:K,last_modified:z?.mtime instanceof Date?z.mtime.toISOString():void 0,has_diff:!!_,summary:Q==="utf8"?`写入 ${L} 行到 ${B}`:`写入 ${z?.size?M3(z.size):"unknown"} 到 ${B}`,kind:"edit",oldContent:F||"",newContent:Q==="utf8"?X:void 0},I=Tq(Z,b,X,_);return{success:!0,llmContent:{file_path:Z,size:z?.size,modified:z?.mtime instanceof Date?z.mtime.toISOString():void 0},displayContent:I,metadata:b}}catch(U){if(U.name==="AbortError")return{success:!1,llmContent:"File write aborted",displayContent:"⚠️ 文件写入被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`File write failed: ${U.message}`,displayContent:`❌ 写入文件失败: ${U.message}`,error:{type:"execution_error",message:U.message,details:U}}}},version:"2.0.0",category:"文件操作",tags:["file","io","write","create"],extractSignatureContent:($)=>$.file_path,abstractPermissionRule:($)=>{let Y=I3($.file_path);return Y?`**/*${Y}`:"**/*"}})});var v3=R(()=>{R3();D3();j3()});import*as o6 from"fs/promises";import{z as O$}from"zod";var m8;var y3=R(()=>{P1();C0();m8=Q1({name:"NotebookEdit",displayName:"Notebook Edit",kind:"write",schema:O$.object({notebook_path:O$.string().describe("The absolute path to the Jupyter notebook file to edit (must be absolute, not relative)"),cell_id:O$.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:O$.string().describe("The new source for the cell"),cell_type:O$.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:O$.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 o6.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((H)=>H.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 H=K.cells[W];if(H.source=Q.split(`
711
- `).map((O,F,N)=>F<N.length-1?O+`
717
+ • 如果必须写入二进制文件,请在本地终端执行`,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 UG.writeFile(Z,A)}if(G)await e1.getInstance().recordFileEdit(Z,G,"write");W.throwIfAborted();let _=await U.stat(Z),w=Q==="utf8"?X.split(`
718
+ `).length:0,B=Z.split("/").pop()||Z,N=null;if(F&&Q==="utf8"&&F!==X){if(F.length<1048576&&X.length<1048576)N=I3(F,X,4)}let I={file_path:Z,content_size:X.length,file_size:_?.size,encoding:Q,created_directories:J,snapshot_created:z,session_id:G,message_id:K,last_modified:_?.mtime instanceof Date?_.mtime.toISOString():void 0,has_diff:!!N,summary:Q==="utf8"?`写入 ${w} 行到 ${B}`:`写入 ${_?.size?p3(_.size):"unknown"} 到 ${B}`,kind:"edit",oldContent:F||"",newContent:Q==="utf8"?X:void 0},M=OG(Z,I,X,N);return{success:!0,llmContent:{file_path:Z,size:_?.size,modified:_?.mtime instanceof Date?_.mtime.toISOString():void 0},displayContent:M,metadata:I}}catch(U){if(U.name==="AbortError")return{success:!1,llmContent:"File write aborted",displayContent:"⚠️ 文件写入被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`File write failed: ${U.message}`,displayContent:`❌ 写入文件失败: ${U.message}`,error:{type:"execution_error",message:U.message,details:U}}}},version:"2.0.0",category:"文件操作",tags:["file","io","write","create"],extractSignatureContent:($)=>$.file_path,abstractPermissionRule:($)=>{let Y=x3($.file_path);return Y?`**/*${Y}`:"**/*"}})});var m3=b(()=>{C3();h3();g3()});import*as X4 from"fs/promises";import{z as _$}from"zod";var e8;var d3=b(()=>{S1();p0();e8=Q1({name:"NotebookEdit",displayName:"Notebook Edit",kind:"write",schema:_$.object({notebook_path:_$.string().describe("The absolute path to the Jupyter notebook file to edit (must be absolute, not relative)"),cell_id:_$.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:_$.string().describe("The new source for the cell"),cell_type:_$.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:_$.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 X4.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((H)=>H.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 H=K.cells[W];if(H.source=Q.split(`
719
+ `).map((O,F,z)=>F<z.length-1?O+`
712
720
  `:O),J)H.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 H={cell_type:J,source:Q.split(`
713
- `).map((F,N,z)=>N<z.length-1?F+`
714
- `:F),metadata:{},...J==="code"?{execution_count:null,outputs:[]}:{}},O=W===-1?0:W+1;K.cells.splice(O,0,H);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 o6.writeFile(Z,JSON.stringify(K,null,2));let U=q==="replace"?"replaced":q==="insert"?"inserted":"deleted";return{success:!0,llmContent:`Successfully ${U} cell in ${Z}`,displayContent:`Cell ${U} 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 E3=R(()=>{y3()});import{z as Cq}from"zod";var d8;var k3=R(()=>{P1();C0();d8=Q1({name:"EnterPlanMode",displayName:"Enter Plan Mode",kind:"readonly",schema:Cq.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.
721
+ `).map((F,z,_)=>z<_.length-1?F+`
722
+ `:F),metadata:{},...J==="code"?{execution_count:null,outputs:[]}:{}},O=W===-1?0:W+1;K.cells.splice(O,0,H);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 X4.writeFile(Z,JSON.stringify(K,null,2));let U=q==="replace"?"replaced":q==="insert"?"inserted":"deleted";return{success:!0,llmContent:`Successfully ${U} cell in ${Z}`,displayContent:`Cell ${U} 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 u3=b(()=>{d3()});import{z as zG}from"zod";var $9;var c3=b(()=>{S1();p0();$9=Q1({name:"EnterPlanMode",displayName:"Enter Plan Mode",kind:"readonly",schema:zG.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.
715
723
 
716
724
  ## When to Use This Tool
717
725
 
@@ -803,7 +811,7 @@ Begin your research now.`,displayContent:"✅ Entering Plan mode",metadata:{appr
803
811
 
804
812
  `+"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.
805
813
 
806
- 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 P3}from"zod";import{promises as T3}from"node:fs";import*as u8 from"node:path";import{homedir as fq}from"node:os";var c8;var S3=R(()=>{P1();C0();c8=Q1({name:"ExitPlanMode",displayName:"Exit Plan Mode",kind:"readonly",schema:P3.object({plan:P3.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.
814
+ 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 l3}from"zod";import{promises as i3}from"node:fs";import*as Y9 from"node:path";import{homedir as _G}from"node:os";var Z9;var r3=b(()=>{S1();p0();Z9=Q1({name:"ExitPlanMode",displayName:"Exit Plan Mode",kind:"readonly",schema:l3.object({plan:l3.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.
807
815
 
808
816
  ## \uD83D\uDEA8 PREREQUISITES (MUST be satisfied before calling)
809
817
 
@@ -838,7 +846,7 @@ Before using this tool, ensure your plan is clear and unambiguous. If there are
838
846
  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.
839
847
  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.
840
848
  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.
841
- `},async execute($,Y){let Z=$.plan||"";if(Z&&Y.sessionId)try{let X=u8.join(fq(),".blade","plans");await T3.mkdir(X,{recursive:!0});let Q=u8.join(X,`plan_${Y.sessionId}.md`);await T3.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.
849
+ `},async execute($,Y){let Z=$.plan||"";if(Z&&Y.sessionId)try{let X=Y9.join(_G(),".blade","plans");await i3.mkdir(X,{recursive:!0});let Q=Y9.join(X,`plan_${Y.sessionId}.md`);await i3.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.
842
850
 
843
851
  `+`⚠️ Before approving, please verify:
844
852
  `+`1. The assistant has written a detailed plan to the plan file
@@ -851,40 +859,40 @@ please reject and ask for a proper plan.`,details:"After approval, the assistant
851
859
  `+(X.feedback||"No specific feedback provided.")+`
852
860
 
853
861
  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.
854
- `+"Proceeding with implementation.",displayContent:"Plan mode exit (non-interactive)",metadata:{approved:null}}}})});var C3=R(()=>{k3();S3()});import hq from"fast-glob";import{LRUCache as xq}from"lru-cache";import{existsSync as pq,readFileSync as gq}from"node:fs";import{readFile as mq}from"node:fs/promises";import{dirname as dq,join as h3}from"node:path";import $6 from"picomatch";function uq($){if(!pq($))return{patterns:[],negatePatterns:[]};try{let Y=gq($,"utf-8"),Z=[],X=[];for(let Q of Y.split(`
855
- `)){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 cq($,Y){let Z=[...p0.map((K)=>`${K}/**`),...Y?.scanIgnore??[]],X=`${$}|${Z.join(",")}`,Q=f3.get(X);if(Q)return Q;let J=await hq("**/.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=dq(K).replace(/\\/g,"/"),U=W==="."?"":W,O=(await mq(h3($,K),"utf-8")).split(`
856
- `);for(let F of O){let N=F.trim();if(!N||N.startsWith("#"))continue;let z=N.startsWith("!"),B=(z?N.slice(1):N).trim();if(!B)continue;let _="";if(B.startsWith("/")){let b=B.slice(1).replace(/\\/g,"/");if(_=(U?U+"/":"")+b,q.push({type:z?"negate":"ignore",pattern:_}),B.endsWith("/")){let I=_+"**";q.push({type:z?"negate":"ignore",pattern:I});let w=_.replace(/\/$/,"");if(w!==_)q.push({type:z?"negate":"ignore",pattern:w})}}else{let b=B.replace(/\\/g,"/");if(b.includes("/")){if(_=(U?U+"/":"")+b,q.push({type:z?"negate":"ignore",pattern:_}),b.endsWith("/")){let I=_+"**";q.push({type:z?"negate":"ignore",pattern:I});let w=_.replace(/\/$/,"");if(w!==_)q.push({type:z?"negate":"ignore",pattern:w})}}else _=(U?U+"/**/":"**/")+b,q.push({type:z?"negate":"ignore",pattern:_})}}}let G=Y?.cacheTTL??30000;return f3.set(X,q,{ttl:G}),q}class s6{orderedRules=[];ignorePatterns=[];negatePatterns=[];constructor($={}){this.initialize($)}static async create($={}){let Y=new s6({...$,useGitignore:!1}),{cwd:Z=process.cwd(),useGitignore:X=!0,gitignoreScanMode:Q="root",customScanIgnore:J=[],cacheTTL:q}=$;if(X&&Q==="recursive"){let G=await cq(Z,{scanIgnore:J,cacheTTL:q});for(let K of G)if(Y.orderedRules.push({type:K.type,matcher:$6(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=[...p0.map((K)=>`${K}/**`),...p0,...l8];J.push(...G);for(let K of G)this.orderedRules.push({type:"ignore",matcher:$6(K,{dot:!0})})}if(Z){let G=h3(Y,".gitignore"),{patterns:K,negatePatterns:W}=uq(G);for(let U of K)this.orderedRules.push({type:"ignore",matcher:$6(U,{dot:!0})}),J.push(U);for(let U of W)this.orderedRules.push({type:"negate",matcher:$6(U,{dot:!0})}),q.push(U)}J.push(...Q);for(let G of Q)this.orderedRules.push({type:"ignore",matcher:$6(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 p0,l8,f3;var t6=R(()=>{p0=["node_modules",".git","dist","build","out",".next",".nuxt",".cache",".parcel-cache","coverage",".nyc_output",".idea",".vscode",".vs","bower_components","jspm_packages"],l8=["*.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"];f3=new xq({max:100,ttl:30000,updateAgeOnGet:!0})});import lq from"fast-glob";import{stat as iq}from"node:fs/promises";import{join as rq,resolve as aq}from"path";import{z as e6}from"zod";function i8($){let Y=Error($);return Y.name="AbortError",Y}async function nq($,Y,Z,X){let Q=X.getIgnorePatterns(),J=[],q=!1;return await new Promise((G,K)=>{if(Z.signal.aborted){K(i8("文件搜索被用户中止"));return}let W=lq.stream(Y,{cwd:$,dot:!0,followSymbolicLinks:!1,unique:!0,caseSensitiveMatch:Z.caseSensitive,objectMode:!0,stats:!0,onlyFiles:!Z.includeDirectories,ignore:Q}),U=!1,H=null,O=()=>{if(H){if(Z.signal.removeEventListener)Z.signal.removeEventListener("abort",H);else if("onabort"in Z.signal)Z.signal.onabort=null;H=null}},F=()=>{if(!U)U=!0,q=!0,W.destroy(),O(),G({matches:J,wasTruncated:q})},N=(z)=>{if(Z.signal.aborted){if(!U)U=!0,W.destroy(i8("文件搜索被用户中止"));return}if(J.length>=Z.maxResults){F();return}let L=z.path.replace(/\\/g,"/"),B=rq($,L);if(X.shouldIgnore(L))return;let _=z.stats?z.stats.isDirectory():!1;if(_&&X.shouldIgnoreDirectory(L))return;let b=z.stats&&z.stats.isFile()?z.stats.size:void 0,I=z.stats?z.stats.mtime.toISOString():void 0;if(J.push({path:B,relative_path:L,is_directory:_,size:b,modified:I}),J.length>=Z.maxResults)F()};if(W.on("data",N),H=()=>{if(!U)U=!0,O(),W.destroy(i8("文件搜索被用户中止"))},Z.signal.addEventListener)Z.signal.addEventListener("abort",H);else if("onabort"in Z.signal)Z.signal.onabort=H;W.once("error",(z)=>{if(!U)U=!0,O(),K(z)}),W.once("end",()=>{if(!U)U=!0,O(),G({matches:J,wasTruncated:q})})})}function oq($){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 sq($){let{search_path:Y,pattern:Z,total_matches:X,returned_matches:Q,truncated:J}=$,q;if(J)q=`✅ 在 ${Y} 中找到至少 ${X} 个匹配 "${Z}" 的文件(已截断)`,q+=`
857
- \uD83D\uDCCB 显示前 ${Q} 个结果`;else q=`✅ 在 ${Y} 中找到 ${X} 个匹配 "${Z}" 的文件`;return q}var r8;var x3=R(()=>{t6();P1();d1();H2();r8=Q1({name:"Glob",displayName:"File Pattern Match",kind:"readonly",schema:e6.object({pattern:N1.glob({description:"Glob pattern string (supports *, ?, ** wildcards)"}),path:e6.string().optional().describe("Search path (optional, defaults to cwd)"),max_results:N1.positiveInt({description:"Maximum number of results"}).max(1000,"At most 1000 results can be returned").default(100),include_directories:e6.boolean().default(!1).describe("Include directories in results"),case_sensitive:e6.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=aq(X);try{if(!(await iq(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 U=await s6.create({cwd:W,useGitignore:!0,useDefaults:!0,gitignoreScanMode:"recursive",customScanIgnore:[],cacheTTL:30000}),{matches:H,wasTruncated:O}=await nq(W,Z,{maxResults:Q,includeDirectories:J,caseSensitive:q,signal:K},U),F=oq(H),N={search_path:W,pattern:Z,total_matches:H.length,returned_matches:H.length,max_results:Q,include_directories:J,case_sensitive:q,truncated:O},z=sq(N),L;if(F.length>0)L=`${O?`Found at least ${F.length} file(s) matching "${Z}" (truncated)`:`Found ${F.length} file(s) matching "${Z}"`}:
862
+ `+"Proceeding with implementation.",displayContent:"Plan mode exit (non-interactive)",metadata:{approved:null}}}})});var a3=b(()=>{c3();r3()});import NG from"fast-glob";import{LRUCache as BG}from"lru-cache";import{existsSync as wG,readFileSync as LG}from"node:fs";import{readFile as AG}from"node:fs/promises";import{dirname as bG,join as o3}from"node:path";import J6 from"picomatch";function RG($){if(!wG($))return{patterns:[],negatePatterns:[]};try{let Y=LG($,"utf-8"),Z=[],X=[];for(let Q of Y.split(`
863
+ `)){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 VG($,Y){let Z=[...c0.map((K)=>`${K}/**`),...Y?.scanIgnore??[]],X=`${$}|${Z.join(",")}`,Q=n3.get(X);if(Q)return Q;let J=await NG("**/.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=bG(K).replace(/\\/g,"/"),U=W==="."?"":W,O=(await AG(o3($,K),"utf-8")).split(`
864
+ `);for(let F of O){let z=F.trim();if(!z||z.startsWith("#"))continue;let _=z.startsWith("!"),B=(_?z.slice(1):z).trim();if(!B)continue;let N="";if(B.startsWith("/")){let I=B.slice(1).replace(/\\/g,"/");if(N=(U?U+"/":"")+I,q.push({type:_?"negate":"ignore",pattern:N}),B.endsWith("/")){let M=N+"**";q.push({type:_?"negate":"ignore",pattern:M});let A=N.replace(/\/$/,"");if(A!==N)q.push({type:_?"negate":"ignore",pattern:A})}}else{let I=B.replace(/\\/g,"/");if(I.includes("/")){if(N=(U?U+"/":"")+I,q.push({type:_?"negate":"ignore",pattern:N}),I.endsWith("/")){let M=N+"**";q.push({type:_?"negate":"ignore",pattern:M});let A=N.replace(/\/$/,"");if(A!==N)q.push({type:_?"negate":"ignore",pattern:A})}}else N=(U?U+"/**/":"**/")+I,q.push({type:_?"negate":"ignore",pattern:N})}}}let G=Y?.cacheTTL??30000;return n3.set(X,q,{ttl:G}),q}class Q4{orderedRules=[];ignorePatterns=[];negatePatterns=[];constructor($={}){this.initialize($)}static async create($={}){let Y=new Q4({...$,useGitignore:!1}),{cwd:Z=process.cwd(),useGitignore:X=!0,gitignoreScanMode:Q="root",customScanIgnore:J=[],cacheTTL:q}=$;if(X&&Q==="recursive"){let G=await VG(Z,{scanIgnore:J,cacheTTL:q});for(let K of G)if(Y.orderedRules.push({type:K.type,matcher:J6(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=[...c0.map((K)=>`${K}/**`),...c0,...X9];J.push(...G);for(let K of G)this.orderedRules.push({type:"ignore",matcher:J6(K,{dot:!0})})}if(Z){let G=o3(Y,".gitignore"),{patterns:K,negatePatterns:W}=RG(G);for(let U of K)this.orderedRules.push({type:"ignore",matcher:J6(U,{dot:!0})}),J.push(U);for(let U of W)this.orderedRules.push({type:"negate",matcher:J6(U,{dot:!0})}),q.push(U)}J.push(...Q);for(let G of Q)this.orderedRules.push({type:"ignore",matcher:J6(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 c0,X9,n3;var J4=b(()=>{c0=["node_modules",".git","dist","build","out",".next",".nuxt",".cache",".parcel-cache","coverage",".nyc_output",".idea",".vscode",".vs","bower_components","jspm_packages"],X9=["*.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"];n3=new BG({max:100,ttl:30000,updateAgeOnGet:!0})});import DG from"fast-glob";import{stat as IG}from"node:fs/promises";import{join as MG,resolve as jG}from"path";import{z as q4}from"zod";function Q9($){let Y=Error($);return Y.name="AbortError",Y}async function vG($,Y,Z,X){let Q=X.getIgnorePatterns(),J=[],q=!1;return await new Promise((G,K)=>{if(Z.signal.aborted){K(Q9("文件搜索被用户中止"));return}let W=DG.stream(Y,{cwd:$,dot:!0,followSymbolicLinks:!1,unique:!0,caseSensitiveMatch:Z.caseSensitive,objectMode:!0,stats:!0,onlyFiles:!Z.includeDirectories,ignore:Q}),U=!1,H=null,O=()=>{if(H){if(Z.signal.removeEventListener)Z.signal.removeEventListener("abort",H);else if("onabort"in Z.signal)Z.signal.onabort=null;H=null}},F=()=>{if(!U)U=!0,q=!0,W.destroy(),O(),G({matches:J,wasTruncated:q})},z=(_)=>{if(Z.signal.aborted){if(!U)U=!0,W.destroy(Q9("文件搜索被用户中止"));return}if(J.length>=Z.maxResults){F();return}let w=_.path.replace(/\\/g,"/"),B=MG($,w);if(X.shouldIgnore(w))return;let N=_.stats?_.stats.isDirectory():!1;if(N&&X.shouldIgnoreDirectory(w))return;let I=_.stats&&_.stats.isFile()?_.stats.size:void 0,M=_.stats?_.stats.mtime.toISOString():void 0;if(J.push({path:B,relative_path:w,is_directory:N,size:I,modified:M}),J.length>=Z.maxResults)F()};if(W.on("data",z),H=()=>{if(!U)U=!0,O(),W.destroy(Q9("文件搜索被用户中止"))},Z.signal.addEventListener)Z.signal.addEventListener("abort",H);else if("onabort"in Z.signal)Z.signal.onabort=H;W.once("error",(_)=>{if(!U)U=!0,O(),K(_)}),W.once("end",()=>{if(!U)U=!0,O(),G({matches:J,wasTruncated:q})})})}function yG($){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 EG($){let{search_path:Y,pattern:Z,total_matches:X,returned_matches:Q,truncated:J}=$,q;if(J)q=`✅ 在 ${Y} 中找到至少 ${X} 个匹配 "${Z}" 的文件(已截断)`,q+=`
865
+ \uD83D\uDCCB 显示前 ${Q} 个结果`;else q=`✅ 在 ${Y} 中找到 ${X} 个匹配 "${Z}" 的文件`;return q}var J9;var s3=b(()=>{J4();S1();c1();N2();J9=Q1({name:"Glob",displayName:"File Pattern Match",kind:"readonly",schema:q4.object({pattern:_1.glob({description:"Glob pattern string (supports *, ?, ** wildcards)"}),path:q4.string().optional().describe("Search path (optional, defaults to cwd)"),max_results:_1.positiveInt({description:"Maximum number of results"}).max(1000,"At most 1000 results can be returned").default(100),include_directories:q4.boolean().default(!1).describe("Include directories in results"),case_sensitive:q4.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=jG(X);try{if(!(await IG(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 U=await Q4.create({cwd:W,useGitignore:!0,useDefaults:!0,gitignoreScanMode:"recursive",customScanIgnore:[],cacheTTL:30000}),{matches:H,wasTruncated:O}=await vG(W,Z,{maxResults:Q,includeDirectories:J,caseSensitive:q,signal:K},U),F=yG(H),z={search_path:W,pattern:Z,total_matches:H.length,returned_matches:H.length,max_results:Q,include_directories:J,case_sensitive:q,truncated:O},_=EG(z),w;if(F.length>0)w=`${O?`Found at least ${F.length} file(s) matching "${Z}" (truncated)`:`Found ${F.length} file(s) matching "${Z}"`}:
858
866
 
859
- `+F.map((_)=>`- ${_.relative_path}`).join(`
867
+ `+F.map((N)=>`- ${N.relative_path}`).join(`
860
868
  `)+`
861
869
 
862
- 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:{...N,matches:F}}}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 a8,spawn as n8}from"child_process";import{existsSync as $4}from"fs";import{readdir as tq,readFile as eq}from"fs/promises";import{join as p3,relative as $G}from"path";import YG from"picomatch";import{z as F2}from"zod";function ZG(){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=p3(process.cwd(),"vendor","ripgrep",Q);if($4(J))return J;try{let q=new URL("../../../../vendor/ripgrep/"+Q,import.meta.url).pathname;if($4(q))return q}catch{}return null}function g3(){try{let Y=process.platform==="win32"?"where rg":"command -v rg 2>/dev/null || which rg 2>/dev/null",Z=a8(Y,{encoding:"utf8",stdio:["pipe","pipe","ignore"]}).split(/\r?\n/)[0].trim();if(Z)return Z}catch{}let $=ZG();if($&&$4($))return $;try{let Y=x1("@vscode/ripgrep");if(Y?.rgPath&&$4(Y.rgPath))return Y.rgPath}catch{}return null}async function XG($){try{return a8("git rev-parse --git-dir",{cwd:$,stdio:"ignore"}),!0}catch{return!1}}function QG(){try{return a8("grep --version",{stdio:"ignore"}),!0}catch{return!1}}async function JG($,Y,Z,X){let Q=g3();if(!Q)throw Error("ripgrep not available");return new Promise((J,q)=>{let G=n8(Q,$,{stdio:["pipe","pipe","pipe"]}),K="",W="";G.stdout.on("data",(H)=>{K+=H.toString()}),G.stderr.on("data",(H)=>{W+=H.toString()}),G.on("close",(H)=>{J({stdout:K,stderr:W,exitCode:H||0})}),G.on("error",(H)=>{q(H)});let U=()=>{G.kill("SIGTERM"),q(Error("搜索被用户中止"))};Z.addEventListener("abort",U),G.on("close",()=>{Z.removeEventListener("abort",U)})})}async function qG($,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=n8("git",Q,{cwd:Y,stdio:["pipe","pipe","pipe"]}),K="",W="";G.stdout.on("data",(H)=>{K+=H.toString()}),G.stderr.on("data",(H)=>{W+=H.toString()}),G.on("close",(H)=>{J({stdout:K,stderr:W,exitCode:H||0})}),G.on("error",(H)=>{q(H)});let U=()=>{G.kill("SIGTERM"),q(Error("搜索被用户中止"))};X.addEventListener("abort",U),G.on("close",()=>{X.removeEventListener("abort",U)})})}async function GG($,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 p0)Q.push("--exclude-dir="+J.replace(/^\./,""));return Q.push("-e",$,Y),new Promise((J,q)=>{let G=n8("grep",Q,{stdio:["pipe","pipe","pipe"]}),K="",W="";G.stdout.on("data",(H)=>{K+=H.toString()}),G.stderr.on("data",(H)=>{W+=H.toString()}),G.on("close",(H)=>{J({stdout:K,stderr:W,exitCode:H||0})}),G.on("error",(H)=>{q(H)});let U=()=>{G.kill("SIGTERM"),q(Error("搜索被用户中止"))};X.addEventListener("abort",U),G.on("close",()=>{X.removeEventListener("abort",U)})})}async function KG($,Y,Z,X){let Q=[],J=new RegExp($,Z.caseInsensitive?"gi":"g"),q=await WG(Y,X),G=0;for(let K of q){if(X.throwIfAborted(),m3(K))continue;if(Z.glob&&!UG(K,Z.glob))continue;try{(await eq(K,"utf-8")).split(`
863
- `).forEach((H,O)=>{if(J.test(H))Q.push({file_path:$G(Y,K),line_number:O+1,content:H})}),G++}catch(W){continue}}return{matches:Q,totalFiles:G}}async function WG($,Y){let Z=[];async function X(Q){Y.throwIfAborted();try{let J=await tq(Q,{withFileTypes:!0});for(let q of J){Y.throwIfAborted();let G=p3(Q,q.name);if(q.isDirectory()){if(!m3(G))await X(G)}else if(q.isFile())Z.push(G)}}catch(J){}}return await X($),Z}function m3($){for(let Y of p0)if($.includes(Y))return!0;return!1}function UG($,Y){return YG(Y)($)}function HG($){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 p0)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 OG($,Y){if(!$.trim())return[];let Z=$.trim().split(`
864
- `),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=FG(Q);if(J)X.push(J)}return X;default:return[]}}function FG($){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 zG($){let{search_pattern:Y,search_path:Z,output_mode:X,total_matches:Q,strategy:J}=$,q=`✅ 在 ${Z} 中搜索 "${Y}"`;if(J)q+=`
870
+ Use the relative_path values above for Read/Edit operations.`;else w=`No files found matching "${Z}"`;return{success:!0,llmContent:w,displayContent:_,metadata:{...z,matches:F}}}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 q9,spawn as G9}from"child_process";import{existsSync as G4}from"fs";import{readdir as kG,readFile as PG}from"fs/promises";import{join as t3,relative as TG}from"path";import SG from"picomatch";import{z as B2}from"zod";function CG(){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=t3(process.cwd(),"vendor","ripgrep",Q);if(G4(J))return J;try{let q=new URL("../../../../vendor/ripgrep/"+Q,import.meta.url).pathname;if(G4(q))return q}catch{}return null}function e3(){try{let Y=process.platform==="win32"?"where rg":"command -v rg 2>/dev/null || which rg 2>/dev/null",Z=q9(Y,{encoding:"utf8",stdio:["pipe","pipe","ignore"]}).split(/\r?\n/)[0].trim();if(Z)return Z}catch{}let $=CG();if($&&G4($))return $;try{let Y=X0("@vscode/ripgrep");if(Y?.rgPath&&G4(Y.rgPath))return Y.rgPath}catch{}return null}async function fG($){try{return q9("git rev-parse --git-dir",{cwd:$,stdio:"ignore"}),!0}catch{return!1}}function hG(){try{return q9("grep --version",{stdio:"ignore"}),!0}catch{return!1}}async function xG($,Y,Z,X){let Q=e3();if(!Q)throw Error("ripgrep not available");return new Promise((J,q)=>{let G=G9(Q,$,{stdio:["pipe","pipe","pipe"]}),K="",W="";G.stdout.on("data",(H)=>{K+=H.toString()}),G.stderr.on("data",(H)=>{W+=H.toString()}),G.on("close",(H)=>{J({stdout:K,stderr:W,exitCode:H||0})}),G.on("error",(H)=>{q(H)});let U=()=>{G.kill("SIGTERM"),q(Error("搜索被用户中止"))};Z.addEventListener("abort",U),G.on("close",()=>{Z.removeEventListener("abort",U)})})}async function pG($,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=G9("git",Q,{cwd:Y,stdio:["pipe","pipe","pipe"]}),K="",W="";G.stdout.on("data",(H)=>{K+=H.toString()}),G.stderr.on("data",(H)=>{W+=H.toString()}),G.on("close",(H)=>{J({stdout:K,stderr:W,exitCode:H||0})}),G.on("error",(H)=>{q(H)});let U=()=>{G.kill("SIGTERM"),q(Error("搜索被用户中止"))};X.addEventListener("abort",U),G.on("close",()=>{X.removeEventListener("abort",U)})})}async function gG($,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 c0)Q.push("--exclude-dir="+J.replace(/^\./,""));return Q.push("-e",$,Y),new Promise((J,q)=>{let G=G9("grep",Q,{stdio:["pipe","pipe","pipe"]}),K="",W="";G.stdout.on("data",(H)=>{K+=H.toString()}),G.stderr.on("data",(H)=>{W+=H.toString()}),G.on("close",(H)=>{J({stdout:K,stderr:W,exitCode:H||0})}),G.on("error",(H)=>{q(H)});let U=()=>{G.kill("SIGTERM"),q(Error("搜索被用户中止"))};X.addEventListener("abort",U),G.on("close",()=>{X.removeEventListener("abort",U)})})}async function mG($,Y,Z,X){let Q=[],J=new RegExp($,Z.caseInsensitive?"gi":"g"),q=await dG(Y,X),G=0;for(let K of q){if(X.throwIfAborted(),$Y(K))continue;if(Z.glob&&!uG(K,Z.glob))continue;try{(await PG(K,"utf-8")).split(`
871
+ `).forEach((H,O)=>{if(J.test(H))Q.push({file_path:TG(Y,K),line_number:O+1,content:H})}),G++}catch(W){continue}}return{matches:Q,totalFiles:G}}async function dG($,Y){let Z=[];async function X(Q){Y.throwIfAborted();try{let J=await kG(Q,{withFileTypes:!0});for(let q of J){Y.throwIfAborted();let G=t3(Q,q.name);if(q.isDirectory()){if(!$Y(G))await X(G)}else if(q.isFile())Z.push(G)}}catch(J){}}return await X($),Z}function $Y($){for(let Y of c0)if($.includes(Y))return!0;return!1}function uG($,Y){return SG(Y)($)}function cG($){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 c0)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 lG($,Y){if(!$.trim())return[];let Z=$.trim().split(`
872
+ `),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=iG(Q);if(J)X.push(J)}return X;default:return[]}}function iG($){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 rG($){let{search_pattern:Y,search_path:Z,output_mode:X,total_matches:Q,strategy:J}=$,q=`✅ 在 ${Z} 中搜索 "${Y}"`;if(J)q+=`
865
873
  \uD83D\uDD27 使用策略: ${J}`;switch(X){case"files_with_matches":q+=`
866
874
  \uD83D\uDCC1 找到 ${Q} 个包含匹配内容的文件`;break;case"count":q+=`
867
875
  \uD83D\uDD22 统计了 ${Q} 个文件的匹配数量`;break;case"content":q+=`
868
- \uD83D\uDCDD 找到 ${Q} 个匹配行`;break}return q}var o8;var d3=R(()=>{t6();P1();d1();H2();o8=Q1({name:"Grep",displayName:"内容搜索",kind:"readonly",schema:F2.object({pattern:N1.pattern({description:"The regular expression pattern to search for in file contents"}),path:F2.string().optional().describe("File or directory to search in (rg PATH). Defaults to current working directory"),glob:F2.string().optional().describe('Glob pattern to filter files (e.g. "*.js", "*.{ts,tsx}") - maps to rg --glob'),type:F2.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:F2.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":F2.boolean().optional().describe("Case insensitive search (rg -i)"),"-n":F2.boolean().default(!0).describe('Show line numbers in output (rg -n). Requires output_mode: "content", ignored otherwise. Defaults to true'),"-B":N1.nonNegativeInt().optional().describe('Number of lines to show before each match (rg -B). Requires output_mode: "content", ignored otherwise'),"-A":N1.nonNegativeInt().optional().describe('Number of lines to show after each match (rg -A). Requires output_mode: "content", ignored otherwise'),"-C":N1.nonNegativeInt().optional().describe('Number of lines to show before and after each match (rg -C). Requires output_mode: "content", ignored otherwise'),head_limit:N1.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:N1.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:F2.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":U,"-C":H,head_limit:O,offset:F,multiline:N}=$,{updateOutput:z}=Y,L=Y.signal??new AbortController().signal;try{z?.(`使用智能搜索策略查找模式 "${Z}"...`);let B=null,_="ripgrep",b=[],I=g3();if(I)try{z?.(`\uD83D\uDE80 使用 ripgrep (${I})`);let D=HG({pattern:Z,path:X,glob:Q,type:J,output_mode:q,case_insensitive:G??!1,line_numbers:K,context_before:W,context_after:U,context:H,head_limit:O,offset:F,multiline:N??!1});B=await JG(D,q,L,z),_="ripgrep"}catch(D){z?.("⚠️ ripgrep 失败,尝试降级策略..."),B=null}if(!B&&await XG(X))try{z?.("\uD83D\uDCE6 使用 git grep"),B=await qG(Z,X,{caseInsensitive:G??!1,glob:Q,contextLines:H},L),_="git-grep"}catch(D){z?.("⚠️ git grep 失败,继续尝试其他策略..."),B=null}if(!B&&QG())try{z?.("\uD83D\uDD27 使用系统 grep"),B=await GG(Z,X,{caseInsensitive:G??!1,contextLines:H},L),_="system-grep"}catch(D){z?.("⚠️ 系统 grep 失败,使用纯 JavaScript 实现..."),B=null}if(!B)z?.("\uD83D\uDCA1 使用纯 JavaScript 搜索实现"),b=(await KG(Z,X,{caseInsensitive:G??!1,glob:Q,multiline:N??!1},L)).matches,_="fallback",B={stdout:"",stderr:"",exitCode:0};else b=OG(B.stdout,q);let w=b.length;if(F!==void 0&&F>0)b=b.slice(F);if(O!==void 0&&b.length>O)b=b.slice(0,O);let M={search_pattern:Z,search_path:X,output_mode:q,case_insensitive:G??!1,total_matches:b.length,original_total:w,offset:F,head_limit:O,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 V=zG(M);return{success:!0,llmContent:b,displayContent:V,metadata:M}}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 u3=R(()=>{x3();d3()});import{spawn as _G}from"child_process";import{randomUUID as NG}from"crypto";class s1{static instance=null;processes=new Map;static getInstance(){if(!s1.instance)s1.instance=new s1;return s1.instance}startBackgroundProcess($){let Y=`bash_${NG()}`,Z={};for(let[J,q]of Object.entries({...process.env,...$.env,BLADE_CLI:"1"}))if(q!==void 0)Z[J]=q;let X=_G("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+=`
869
- [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 F$=()=>{};import{spawn as BG}from"child_process";import{randomUUID as LG}from"crypto";import{z as s8}from"zod";function wG($,Y,Z){let Q=s1.getInstance().startBackgroundProcess({command:$,sessionId:LG(),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=`✅ 命令已在后台启动
876
+ \uD83D\uDCDD 找到 ${Q} 个匹配行`;break}return q}var K9;var YY=b(()=>{J4();S1();c1();N2();K9=Q1({name:"Grep",displayName:"内容搜索",kind:"readonly",schema:B2.object({pattern:_1.pattern({description:"The regular expression pattern to search for in file contents"}),path:B2.string().optional().describe("File or directory to search in (rg PATH). Defaults to current working directory"),glob:B2.string().optional().describe('Glob pattern to filter files (e.g. "*.js", "*.{ts,tsx}") - maps to rg --glob'),type:B2.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:B2.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":B2.boolean().optional().describe("Case insensitive search (rg -i)"),"-n":B2.boolean().default(!0).describe('Show line numbers in output (rg -n). Requires output_mode: "content", ignored otherwise. Defaults to true'),"-B":_1.nonNegativeInt().optional().describe('Number of lines to show before each match (rg -B). Requires output_mode: "content", ignored otherwise'),"-A":_1.nonNegativeInt().optional().describe('Number of lines to show after each match (rg -A). Requires output_mode: "content", ignored otherwise'),"-C":_1.nonNegativeInt().optional().describe('Number of lines to show before and after each match (rg -C). Requires output_mode: "content", ignored otherwise'),head_limit:_1.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:_1.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:B2.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":U,"-C":H,head_limit:O,offset:F,multiline:z}=$,{updateOutput:_}=Y,w=Y.signal??new AbortController().signal;try{_?.(`使用智能搜索策略查找模式 "${Z}"...`);let B=null,N="ripgrep",I=[],M=e3();if(M)try{_?.(`\uD83D\uDE80 使用 ripgrep (${M})`);let V=cG({pattern:Z,path:X,glob:Q,type:J,output_mode:q,case_insensitive:G??!1,line_numbers:K,context_before:W,context_after:U,context:H,head_limit:O,offset:F,multiline:z??!1});B=await xG(V,q,w,_),N="ripgrep"}catch(V){_?.("⚠️ ripgrep 失败,尝试降级策略..."),B=null}if(!B&&await fG(X))try{_?.("\uD83D\uDCE6 使用 git grep"),B=await pG(Z,X,{caseInsensitive:G??!1,glob:Q,contextLines:H},w),N="git-grep"}catch(V){_?.("⚠️ git grep 失败,继续尝试其他策略..."),B=null}if(!B&&hG())try{_?.("\uD83D\uDD27 使用系统 grep"),B=await gG(Z,X,{caseInsensitive:G??!1,contextLines:H},w),N="system-grep"}catch(V){_?.("⚠️ 系统 grep 失败,使用纯 JavaScript 实现..."),B=null}if(!B)_?.("\uD83D\uDCA1 使用纯 JavaScript 搜索实现"),I=(await mG(Z,X,{caseInsensitive:G??!1,glob:Q,multiline:z??!1},w)).matches,N="fallback",B={stdout:"",stderr:"",exitCode:0};else I=lG(B.stdout,q);let A=I.length;if(F!==void 0&&F>0)I=I.slice(F);if(O!==void 0&&I.length>O)I=I.slice(0,O);let D={search_pattern:Z,search_path:X,output_mode:q,case_insensitive:G??!1,total_matches:I.length,original_total:A,offset:F,head_limit:O,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 L=rG(D);return{success:!0,llmContent:I,displayContent:L,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 ZY=b(()=>{s3();YY()});import{spawn as aG}from"child_process";import{randomUUID as nG}from"crypto";class $0{static instance=null;processes=new Map;static getInstance(){if(!$0.instance)$0.instance=new $0;return $0.instance}startBackgroundProcess($){let Y=`bash_${nG()}`,Z={};for(let[J,q]of Object.entries({...process.env,...$.env,BLADE_CLI:"1"}))if(q!==void 0)Z[J]=q;let X=aG("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+=`
877
+ [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 N$=()=>{};import{spawn as oG}from"child_process";import{randomUUID as sG}from"crypto";import{z as W9}from"zod";function tG($,Y,Z){let Q=$0.getInstance().startBackgroundProcess({command:$,sessionId:sG(),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=`✅ 命令已在后台启动
870
878
  `+`\uD83C\uDD94 进程 ID: ${Q.pid}
871
879
  `+`\uD83D\uDCA1 Bash ID: ${Q.id}
872
- `+"⚠️ 使用 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 AG($,Y,Z,X,Q,J){let q=Date.now();try{let K=await U3().execute($,{cwd:Y||process.cwd(),env:Z,timeout:X,signal:Q,onOutput:(N)=>{J?.(N)}}),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:`⚠️ 命令执行被用户中止
880
+ `+"⚠️ 使用 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 eG($,Y,Z,X,Q,J){let q=Date.now();try{let K=await V3().execute($,{cwd:Y||process.cwd(),env:Z,timeout:X,signal:Q,onOutput:(z)=>{J?.(z)}}),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:`⚠️ 命令执行被用户中止
873
881
  输出: ${K.stdout}
874
882
  错误: ${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)
875
883
  输出: ${K.stdout}
876
- 错误: ${K.stderr}`,error:{type:"timeout_error",message:"命令执行超时"},metadata:{command:$,timeout:!0,stdout:K.stdout,stderr:K.stderr,execution_time:W}};let U=$.length>30?`${$.substring(0,30)}...`:$,H=K.exitCode===0?`执行命令成功 (${W}ms): ${U}`:`执行命令完成 (退出码 ${K.exitCode}, ${W}ms): ${U}`,O={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:H},F=c3({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:F,metadata:O}}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 bG($,Y,Z,X,Q,J){return new Promise((q)=>{let G=Date.now(),K="",W="",U=!1,H=BG("bash",["-c",$],{cwd:Y||process.cwd(),env:{...process.env,...Z,BLADE_CLI:"1"},stdio:["pipe","pipe","pipe"]});H.stdout.on("data",(N)=>{K+=N.toString()}),H.stderr.on("data",(N)=>{W+=N.toString()});let O=setTimeout(()=>{U=!0,H.kill("SIGTERM"),setTimeout(()=>{if(!H.killed)H.kill("SIGKILL")},1000)},X),F=()=>{H.kill("SIGTERM"),clearTimeout(O)};if(Q.addEventListener)Q.addEventListener("abort",F);else if("onabort"in Q)Q.onabort=F;H.on("close",(N,z)=>{if(clearTimeout(O),Q.removeEventListener)Q.removeEventListener("abort",F);else if("onabort"in Q)Q.onabort=null;let L=Date.now()-G;if(U){q({success:!1,llmContent:`Command execution timed out (${X}ms)`,displayContent:`⏱️ 命令执行超时 (${X}ms)
884
+ 错误: ${K.stderr}`,error:{type:"timeout_error",message:"命令执行超时"},metadata:{command:$,timeout:!0,stdout:K.stdout,stderr:K.stderr,execution_time:W}};let U=$.length>30?`${$.substring(0,30)}...`:$,H=K.exitCode===0?`执行命令成功 (${W}ms): ${U}`:`执行命令完成 (退出码 ${K.exitCode}, ${W}ms): ${U}`,O={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:H},F=XY({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:F,metadata:O}}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 $K($,Y,Z,X,Q,J){return new Promise((q)=>{let G=Date.now(),K="",W="",U=!1,H=oG("bash",["-c",$],{cwd:Y||process.cwd(),env:{...process.env,...Z,BLADE_CLI:"1"},stdio:["pipe","pipe","pipe"]});H.stdout.on("data",(z)=>{K+=z.toString()}),H.stderr.on("data",(z)=>{W+=z.toString()});let O=setTimeout(()=>{U=!0,H.kill("SIGTERM"),setTimeout(()=>{if(!H.killed)H.kill("SIGKILL")},1000)},X),F=()=>{H.kill("SIGTERM"),clearTimeout(O)};if(Q.addEventListener)Q.addEventListener("abort",F);else if("onabort"in Q)Q.onabort=F;H.on("close",(z,_)=>{if(clearTimeout(O),Q.removeEventListener)Q.removeEventListener("abort",F);else if("onabort"in Q)Q.onabort=null;let w=Date.now()-G;if(U){q({success:!1,llmContent:`Command execution timed out (${X}ms)`,displayContent:`⏱️ 命令执行超时 (${X}ms)
877
885
  输出: ${K}
878
- 错误: ${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:`⚠️ 命令执行被用户中止
886
+ 错误: ${W}`,error:{type:"timeout_error",message:"命令执行超时"},metadata:{command:$,timeout:!0,stdout:K,stderr:W,execution_time:w}});return}if(Q.aborted){q({success:!1,llmContent:"Command execution aborted by user",displayContent:`⚠️ 命令执行被用户中止
879
887
  输出: ${K}
880
- 错误: ${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}`:`执行命令完成 (退出码 ${N}, ${L}ms): ${B}`,b={command:$,execution_time:L,exit_code:N,signal:z,stdout_length:K.length,stderr_length:W.length,has_stderr:W.length>0,summary:_},I=c3({stdout:K,stderr:W,command:$,execution_time:L,exit_code:N,signal:z});q({success:!0,llmContent:{stdout:K.trim(),stderr:W.trim(),execution_time:L,exit_code:N,signal:z},displayContent:I,metadata:b})}),H.on("error",(N)=>{if(clearTimeout(O),Q.removeEventListener)Q.removeEventListener("abort",F);else if("onabort"in Q)Q.onabort=null;q({success:!1,llmContent:`Command execution failed: ${N.message}`,displayContent:`❌ 命令执行失败: ${N.message}`,error:{type:"execution_error",message:N.message,details:N}})})})}function c3($){let{stdout:Y,stderr:Z,command:X,execution_time:Q,exit_code:J,signal:q}=$,G=`✅ Bash 命令执行完成: ${X}`;if(G+=`
888
+ 错误: ${W}`,error:{type:"execution_error",message:"操作被中止"},metadata:{command:$,aborted:!0,stdout:K,stderr:W,execution_time:w}});return}let B=$.length>30?`${$.substring(0,30)}...`:$,N=z===0?`执行命令成功 (${w}ms): ${B}`:`执行命令完成 (退出码 ${z}, ${w}ms): ${B}`,I={command:$,execution_time:w,exit_code:z,signal:_,stdout_length:K.length,stderr_length:W.length,has_stderr:W.length>0,summary:N},M=XY({stdout:K,stderr:W,command:$,execution_time:w,exit_code:z,signal:_});q({success:!0,llmContent:{stdout:K.trim(),stderr:W.trim(),execution_time:w,exit_code:z,signal:_},displayContent:M,metadata:I})}),H.on("error",(z)=>{if(clearTimeout(O),Q.removeEventListener)Q.removeEventListener("abort",F);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 XY($){let{stdout:Y,stderr:Z,command:X,execution_time:Q,exit_code:J,signal:q}=$,G=`✅ Bash 命令执行完成: ${X}`;if(G+=`
881
889
  ⏱️ 执行时间: ${Q}ms`,G+=`
882
890
  \uD83D\uDCCA 退出码: ${J??"N/A"}`,q)G+=`
883
891
  ⚡ 信号: ${q}`;if(Y&&Y.trim())G+=`
884
892
  \uD83D\uDCE4 输出:
885
893
  ${Y.trim()}`;if(Z&&Z.trim())G+=`
886
894
  ⚠️ 错误输出:
887
- ${Z.trim()}`;return G}var t8;var l3=R(()=>{W$();P1();d1();H2();F$();t8=Q1({name:"Bash",displayName:"Bash Command",kind:"execute",schema:s8.object({command:N1.command({description:"Bash command to execute"}),timeout:N1.timeout(1000,300000,30000),cwd:s8.string().optional().describe("Working directory (optional; applies only to this command). To persist, use cd"),env:N1.environment(),run_in_background:s8.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.
895
+ ${Z.trim()}`;return G}var U9;var QY=b(()=>{F$();S1();c1();N2();N$();U9=Q1({name:"Bash",displayName:"Bash Command",kind:"execute",schema:W9.object({command:_1.command({description:"Bash command to execute"}),timeout:_1.timeout(1000,300000,30000),cwd:W9.string().optional().describe("Working directory (optional; applies only to this command). To persist, use cd"),env:_1.environment(),run_in_background:W9.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.
888
896
 
889
897
  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.
890
898
 
@@ -900,16 +908,16 @@ Before executing commands:
900
908
  * cd "/Users/name/My Documents" (correct)
901
909
  * cd /Users/name/My Documents (incorrect - will fail)
902
910
  * python "/path/with spaces/script.py" (correct)
903
- * 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 wG(Z,Q,J);if(U2())return G?.("通过 IDE 终端执行命令..."),AG(Z,Q,J,X,K,G);else return bG(Z,Q,J,X,K,G)}catch(W){let U=W;if(U.name==="AbortError")return{success:!1,llmContent:"Command execution aborted",displayContent:"⚠️ 命令执行被用户中止",error:{type:"execution_error",message:"Operation aborted"}};return{success:!1,llmContent:`Command execution failed: ${U.message}`,displayContent:`❌ 命令执行失败: ${U.message}`,error:{type:"execution_error",message:U.message,details:U}}}},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 e8}from"zod";function RG($,Y){let Z=i3($.stdout).filter((Q)=>{if(!Y)return!0;return Y.lastIndex=0,Y.test(Q)}),X=i3($.stderr).filter((Q)=>{if(!Y)return!0;return Y.lastIndex=0,Y.test(Q)});return{stdoutLines:Z,stderrLines:X}}function i3($){if(!$)return[];return $.replace(/\r\n/g,`
911
+ * 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 tG(Z,Q,J);if(_2())return G?.("通过 IDE 终端执行命令..."),eG(Z,Q,J,X,K,G);else return $K(Z,Q,J,X,K,G)}catch(W){let U=W;if(U.name==="AbortError")return{success:!1,llmContent:"Command execution aborted",displayContent:"⚠️ 命令执行被用户中止",error:{type:"execution_error",message:"Operation aborted"}};return{success:!1,llmContent:`Command execution failed: ${U.message}`,displayContent:`❌ 命令执行失败: ${U.message}`,error:{type:"execution_error",message:U.message,details:U}}}},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 H9}from"zod";function YK($,Y){let Z=JY($.stdout).filter((Q)=>{if(!Y)return!0;return Y.lastIndex=0,Y.test(Q)}),X=JY($.stderr).filter((Q)=>{if(!Y)return!0;return Y.lastIndex=0,Y.test(Q)});return{stdoutLines:Z,stderrLines:X}}function JY($){if(!$)return[];return $.replace(/\r\n/g,`
904
912
  `).split(`
905
- `)}function VG($,Y,Z){let Q=`${$.status==="running"?"⏳":$.status==="exited"?"✅":$.status==="killed"?"✂️":"⚠️"} BashOutput(${$.id}) - 状态: ${$.status}`;if(Q+=`
913
+ `)}function ZK($,Y,Z){let Q=`${$.status==="running"?"⏳":$.status==="exited"?"✅":$.status==="killed"?"✂️":"⚠️"} BashOutput(${$.id}) - 状态: ${$.status}`;if(Q+=`
906
914
  命令: ${$.command}`,$.pid)Q+=`
907
915
  PID: ${$.pid}`;if($.exitCode!==void 0&&$.exitCode!==null)Q+=`
908
916
  退出码: ${$.exitCode}`;if($.signal)Q+=`
909
917
  信号: ${$.signal}`;if(Y===0&&Z===0)Q+=`
910
918
  无新的输出`;else Q+=`
911
919
  stdout 行数: ${Y}`,Q+=`
912
- stderr 行数: ${Z}`;return Q}var $9;var r3=R(()=>{P1();d1();F$();$9=Q1({name:"BashOutput",displayName:"后台命令输出",kind:"readonly",schema:e8.object({bash_id:e8.string().min(1).describe("Background bash session ID"),filter:e8.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:`
920
+ stderr 行数: ${Z}`;return Q}var O9;var qY=b(()=>{S1();c1();N$();O9=Q1({name:"BashOutput",displayName:"后台命令输出",kind:"readonly",schema:H9.object({bash_id:H9.string().min(1).describe("Background bash session ID"),filter:H9.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:`
913
921
  - Retrieves output from a running or completed background bash shell
914
922
  - Takes a shell_id parameter identifying the shell
915
923
  - Always returns only new output since the last check
@@ -917,17 +925,17 @@ stderr 行数: ${Z}`;return Q}var $9;var r3=R(()=>{P1();d1();F$();$9=Q1({name:"B
917
925
  - Supports optional regex filtering to show only lines matching a pattern
918
926
  - Use this tool when you need to monitor or check the output of a long-running shell
919
927
  - Shell IDs can be found using the /tasks command
920
- `},async execute($,Y){let Z=s1.getInstance(),X;if($.filter)try{X=new RegExp($.filter)}catch(W){return{success:!1,llmContent:`Invalid regular expression: ${$.filter}
928
+ `},async execute($,Y){let Z=$0.getInstance(),X;if($.filter)try{X=new RegExp($.filter)}catch(W){return{success:!1,llmContent:`Invalid regular expression: ${$.filter}
921
929
 
922
930
  \uD83D\uDCA1 Output was not consumed; you can retry`,displayContent:`❌ 无效的正则表达式: ${$.filter}
923
931
 
924
- \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}=RG(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=VG(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 a3}from"zod";var Y9;var n3=R(()=>{P1();d1();F$();Y9=Q1({name:"KillShell",displayName:"终止后台 Shell",kind:"execute",schema:a3.object({shell_id:a3.string().min(1).describe("Background Shell ID to terminate")}),description:{short:"Kills a running background bash shell by its ID",long:`
932
+ \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}=YK(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=ZK(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 GY}from"zod";var F9;var KY=b(()=>{S1();c1();N$();F9=Q1({name:"KillShell",displayName:"终止后台 Shell",kind:"execute",schema:GY.object({shell_id:GY.string().min(1).describe("Background Shell ID to terminate")}),description:{short:"Kills a running background bash shell by its ID",long:`
925
933
  - Kills a running background bash shell by its ID
926
934
  - Takes a shell_id parameter identifying the shell to kill
927
935
  - Returns a success or failure status
928
936
  - Use this tool when you need to terminate a long-running shell
929
937
  - Shell IDs can be found using the /tasks command
930
- `},async execute($,Y){let X=s1.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 o3=R(()=>{F$();l3();r3();n3()});import{z as Z9}from"zod";function DG($,Y,Z){return`# Skill: ${$}
938
+ `},async execute($,Y){let X=$0.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 WY=b(()=>{N$();QY();qY();KY()});import{z as z9}from"zod";function XK($,Y,Z){return`# Skill: ${$}
931
939
 
932
940
  You are now operating in the "${$}" skill mode. Follow the instructions below to complete the task.
933
941
 
@@ -940,7 +948,7 @@ ${Y}
940
948
 
941
949
  ---
942
950
 
943
- Remember: Follow the above instructions carefully to complete the user's request.`}var X9;var s3=R(()=>{K2();P1();C0();X9=Q1({name:"Skill",displayName:"Skill",kind:"execute",schema:Z9.object({skill:Z9.string().describe('The skill name. E.g., "commit-message" or "code-review"'),args:Z9.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
951
+ Remember: Follow the above instructions carefully to complete the user's request.`}var _9;var UY=b(()=>{F2();S1();p0();_9=Q1({name:"Skill",displayName:"Skill",kind:"execute",schema:z9.object({skill:z9.string().describe('The skill name. E.g., "commit-message" or "code-review"'),args:z9.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
944
952
 
945
953
  <skills_instructions>
946
954
  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.
@@ -959,7 +967,7 @@ Important:
959
967
  <available_skills>
960
968
 
961
969
  </available_skills>
962
- `},async execute($,Y){let{skill:Z}=$,X=u1();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:DG(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{z as t3}from"zod";var Q9;var e3=R(()=>{P1();C0();Q9=Q1({name:"SlashCommand",displayName:"Slash Command",kind:"execute",schema:t3.object({command:t3.string().describe('The slash command to execute with its arguments, e.g., "/review-pr 123"')}),description:{short:"Execute a slash command within the main conversation",long:`Execute a slash command within the main conversation
970
+ `},async execute($,Y){let{skill:Z}=$,X=l1();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:XK(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{z as HY}from"zod";var N9;var OY=b(()=>{S1();p0();N9=Q1({name:"SlashCommand",displayName:"Slash Command",kind:"execute",schema:HY.object({command:HY.string().describe('The slash command to execute with its arguments, e.g., "/review-pr 123"')}),description:{short:"Execute a slash command within the main conversation",long:`Execute a slash command within the main conversation
963
971
 
964
972
  How slash commands work:
965
973
  When you use this tool or when a user types a slash command, you will see <command-message>{name} is running...</command-message> followed by the expanded prompt. For example, if .claude/commands/foo.md contains "Print today's date", then /foo expands to that prompt in the next message.
@@ -977,14 +985,14 @@ Notes:
977
985
  - When a user requests multiple slash commands, execute each one sequentially and check for <command-message>{name} is running...</command-message> to verify each has been processed
978
986
  - Do not invoke a command that is already running. For example, if you see <command-message>foo is running...</command-message>, do NOT use this tool with "/foo" - process the expanded prompt in the following message
979
987
  - Only custom slash commands with descriptions are listed in Available Commands. If a user's command is not listed, ask them to check the slash command file and consult the docs.
980
- `},async execute($,Y){let{command:Z}=$;return{success:!1,llmContent:`Slash command system not yet implemented. The command "${Z}" could not be executed.`,displayContent:"Slash command system not available",error:{type:"execution_error",message:"Slash command handler not configured"}}}})});var $Y=R(()=>{s3();e3()});class J9{config;constructor($){this.config=$}async execute($){let Y=Date.now();try{let Z=this.buildSystemPrompt($),X=await S1.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 YY=R(()=>{z2()});import q9 from"node:fs";import IG from"node:path";import MG from"yaml";class ZY{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:
988
+ `},async execute($,Y){let{command:Z}=$;return{success:!1,llmContent:`Slash command system not yet implemented. The command "${Z}" could not be executed.`,displayContent:"Slash command system not available",error:{type:"execution_error",message:"Slash command handler not configured"}}}})});var FY=b(()=>{UY();OY()});class B9{config;constructor($){this.config=$}async execute($){let Y=Date.now();try{let Z=this.buildSystemPrompt($),X=await f1.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 zY=b(()=>{w2()});import w9 from"node:fs";import QK from"node:os";import L9 from"node:path";import JK from"yaml";class _Y{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:
981
989
  ${$.map((Z)=>{let X=`- ${Z.name}: ${Z.description}`;if(Z.tools&&Z.tools.length>0)X+=` (Tools: ${Z.tools.join(", ")})`;return X}).join(`
982
- `)}`}loadFromDirectory($){if(!q9.existsSync($))return;let Y=q9.readdirSync($);for(let Z of Y){if(!Z.endsWith(".md"))continue;let X=IG.join($,Z);try{let Q=this.parseConfigFile(X);this.register(Q)}catch(Q){jG.warn(`Failed to load subagent config from ${X}:`,Q)}}}parseConfigFile($){let Z=q9.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=MG.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 $=x1("node:os"),Y=x1("node:path"),Z=Y.join($.homedir(),".blade","agents");this.loadFromDirectory(Z);let X=Y.join(process.cwd(),".blade","agents");return this.loadFromDirectory(X),this.getAllNames().length}clear(){this.subagents.clear()}}var jG,E1;var z$=R(()=>{A1();jG=i("Agent");E1=new ZY});import{z as Y4}from"zod";function vG(){let $=E1.getAllNames();if($.length===0)return["Explore"];return $}var G9;var XY=R(()=>{YY();z$();P1();d1();G9=Q1({name:"Task",displayName:"Subagent Scheduler",kind:"readonly",isReadOnly:!0,schema:Y4.object({subagent_type:Y4.enum(vG()).describe('Subagent type to use (e.g., "Explore", "Plan")'),description:Y4.string().min(3).max(100).describe("Short task description (3-5 words)"),prompt:Y4.string().min(10).describe("Detailed task instructions")}),description:{short:"Launch a specialized agent to handle complex, multi-step tasks autonomously",long:`
990
+ `)}`}loadFromDirectory($){if(!w9.existsSync($))return;let Y=w9.readdirSync($);for(let Z of Y){if(!Z.endsWith(".md"))continue;let X=L9.join($,Z);try{let Q=this.parseConfigFile(X);this.register(Q)}catch(Q){qK.warn(`Failed to load subagent config from ${X}:`,Q)}}}parseConfigFile($){let Z=w9.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=JK.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 $=L9.join(QK.homedir(),".blade","agents");this.loadFromDirectory($);let Y=L9.join(process.cwd(),".blade","agents");return this.loadFromDirectory(Y),this.getAllNames().length}clear(){this.subagents.clear()}}var qK,k1;var B$=b(()=>{B1();qK=c("Agent");k1=new _Y});import{z as K4}from"zod";function GK(){let $=k1.getAllNames();if($.length===0)return["Explore"];return $}var A9;var NY=b(()=>{zY();B$();S1();c1();A9=Q1({name:"Task",displayName:"Subagent Scheduler",kind:"readonly",isReadOnly:!0,schema:K4.object({subagent_type:K4.enum(GK()).describe('Subagent type to use (e.g., "Explore", "Plan")'),description:K4.string().min(3).max(100).describe("Short task description (3-5 words)"),prompt:K4.string().min(10).describe("Detailed task instructions")}),description:{short:"Launch a specialized agent to handle complex, multi-step tasks autonomously",long:`
983
991
  Launch a specialized agent to handle complex, multi-step tasks autonomously.
984
992
 
985
993
  The Task tool launches specialized agents (subprocesses) that autonomously handle complex tasks. Each agent type has specific capabilities and tools available to it.
986
994
 
987
- ${E1.getDescriptionsForPrompt()}
995
+ ${k1.getDescriptionsForPrompt()}
988
996
 
989
997
  **How to use the Task tool:**
990
998
  - Set subagent_type to ANY agent name from the list above (e.g., 'Explore', 'Plan', 'code-reviewer', etc.)
@@ -1005,9 +1013,9 @@ ${E1.getDescriptionsForPrompt()}
1005
1013
  - 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
1006
1014
  - 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.
1007
1015
  - 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.
1008
- `.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=E1.getAllNames();console.log(`[Task] subagentRegistry 状态: registered=${q.length}, names=[${q.join(", ")}], looking for="${Z}"`);let G=E1.getSubagent(Z);if(!G)return{success:!1,llmContent:`Unknown subagent type: ${Z}. Available types: ${q.join(", ")||"none"}`,displayContent:`❌ 未知的 subagent 类型: ${Z}
1016
+ `.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=k1.getAllNames();console.log(`[Task] subagentRegistry 状态: registered=${q.length}, names=[${q.join(", ")}], looking for="${Z}"`);let G=k1.getSubagent(Z);if(!G)return{success:!1,llmContent:`Unknown subagent type: ${Z}. Available types: ${q.join(", ")||"none"}`,displayContent:`❌ 未知的 subagent 类型: ${Z}
1009
1017
 
1010
- 可用类型: ${q.join(", ")||"无"}`,error:{type:"execution_error",message:`Unknown subagent type: ${Z}`}};J?.(`\uD83D\uDE80 启动 ${Z} subagent: ${X}`);let K=new J9(G),W={prompt:Q,parentSessionId:Y.sessionId,permissionMode:Y.permissionMode};J?.("⚙️ 执行任务中...");let U=Date.now(),H=await K.execute(W),O=Date.now()-U;if(H.success){let F=H.message.length>1000?H.message.slice(0,1000)+`
1018
+ 可用类型: ${q.join(", ")||"无"}`,error:{type:"execution_error",message:`Unknown subagent type: ${Z}`}};J?.(`\uD83D\uDE80 启动 ${Z} subagent: ${X}`);let K=new B9(G),W={prompt:Q,parentSessionId:Y.sessionId,permissionMode:Y.permissionMode};J?.("⚙️ 执行任务中...");let U=Date.now(),H=await K.execute(W),O=Date.now()-U;if(H.success){let F=H.message.length>1000?H.message.slice(0,1000)+`
1011
1019
  ...(截断)`:H.message;return{success:!0,llmContent:H.message,displayContent:`✅ Subagent 任务完成
1012
1020
 
1013
1021
  `+`类型: ${Z}
@@ -1026,7 +1034,7 @@ ${F}`,metadata:{subagent_type:Z,description:X,duration:O,stats:H.stats}}}else re
1026
1034
 
1027
1035
  ${G.message}
1028
1036
 
1029
- ${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 QY=R(()=>{XY()});import{randomUUID as yG}from"crypto";import*as _$ from"fs/promises";import*as Z4 from"path";var _2;var K9=R(()=>{_2=class _2{static instances=new Map;todos=[];filePath;loaded=!1;constructor($,Y){this.filePath=Z4.join(Y,"todos",`${$}-agent-${$}.json`)}static getInstance($,Y){let Z=`${$}-${Y}`;if(!_2.instances.has(Z))_2.instances.set(Z,new _2($,Y));return _2.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||yG(),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 _$.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 _$.mkdir(Z4.dirname(this.filePath),{recursive:!0}),await _$.writeFile(this.filePath,JSON.stringify(this.todos,null,2),"utf-8")}catch($){throw console.error("保存 TODO 列表失败:",$),$}}}});import{z as N$}from"zod";var JY;var qY=R(()=>{JY=N$.object({id:N$.string().optional(),content:N$.string().min(1,"Content cannot be empty"),status:N$.enum(["pending","in_progress","completed"]),activeForm:N$.string().min(1,"ActiveForm cannot be empty"),priority:N$.enum(["high","medium","low"]).default("medium")})});import{z as GY}from"zod";function W9($){let{sessionId:Y,configDir:Z}=$;return Q1({name:"TodoWrite",displayName:"Todo Write",kind:"readonly",schema:GY.object({todos:GY.array(JY).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.
1037
+ ${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 BY=b(()=>{NY()});import{randomUUID as KK}from"crypto";import*as w$ from"fs/promises";import*as W4 from"path";var L2;var b9=b(()=>{L2=class L2{static instances=new Map;todos=[];filePath;loaded=!1;constructor($,Y){this.filePath=W4.join(Y,"todos",`${$}-agent-${$}.json`)}static getInstance($,Y){let Z=`${$}-${Y}`;if(!L2.instances.has(Z))L2.instances.set(Z,new L2($,Y));return L2.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||KK(),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 w$.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 w$.mkdir(W4.dirname(this.filePath),{recursive:!0}),await w$.writeFile(this.filePath,JSON.stringify(this.todos,null,2),"utf-8")}catch($){throw console.error("保存 TODO 列表失败:",$),$}}}});import{z as L$}from"zod";var wY;var LY=b(()=>{wY=L$.object({id:L$.string().optional(),content:L$.string().min(1,"Content cannot be empty"),status:L$.enum(["pending","in_progress","completed"]),activeForm:L$.string().min(1,"ActiveForm cannot be empty"),priority:L$.enum(["high","medium","low"]).default("medium")})});import{z as AY}from"zod";function R9($){let{sessionId:Y,configDir:Z}=$;return Q1({name:"TodoWrite",displayName:"Todo Write",kind:"readonly",schema:AY.object({todos:AY.array(wY).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.
1030
1038
  It also helps the user understand the progress of the task and overall progress of their requests.
1031
1039
 
1032
1040
  ## When to Use This Tool
@@ -1087,16 +1095,16 @@ NOTE that you should not use this tool if there is only one trivial task to do.
1087
1095
  - activeForm: "Fixing authentication bug"
1088
1096
 
1089
1097
  When in doubt, use this tool. Being proactive with task management demonstrates attentiveness and ensures you complete all requirements successfully.
1090
- `},async execute(X,Q){let{todos:J}=X,{updateOutput:q}=Q;try{let G=Q.sessionId||Y,K=_2.getInstance(G,Z);q?.("Updating TODO list..."),await K.updateTodos(J);let W=K.getTodos(),U=EG(W),H=kG(W,U);return q?.(`✅ TODO list updated (${U.completed}/${U.total} completed)`),{success:!0,llmContent:{todos:W,stats:U},displayContent:H,metadata:{stats:U}}}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 EG($){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 kG($,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(`
1098
+ `},async execute(X,Q){let{todos:J}=X,{updateOutput:q}=Q;try{let G=Q.sessionId||Y,K=L2.getInstance(G,Z);q?.("Updating TODO list..."),await K.updateTodos(J);let W=K.getTodos(),U=WK(W),H=UK(W,U);return q?.(`✅ TODO list updated (${U.completed}/${U.total} completed)`),{success:!0,llmContent:{todos:W,stats:U},displayContent:H,metadata:{stats:U}}}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 WK($){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 UK($,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(`
1091
1099
  `);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(`
1092
- `)}var KY=R(()=>{P1();d1();K9();qY()});var WY=R(()=>{K9();KY()});import{z as e0}from"zod";async function PG($){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},U=Y,H=Z,O=Q,F=0,N=[];while(!0){let z={...W};if(O&&H!=="GET"&&H!=="HEAD"&&!xG(z,"content-type"))z["Content-Type"]="application/json";let L=await CG(U,{method:H,headers:z,body:O&&H!=="GET"&&H!=="HEAD"?O:void 0,redirect:"manual"},J,K),B=L.headers.get("location"),_=L.status>=300&&L.status<400,b=q&&_&&B&&F<G;if(_&&q&&!B)throw Error(`收到状态码 ${L.status} 但响应缺少 Location 头`);if(_&&q&&F>=G)throw Error(`超过最大重定向次数 (${G})`);if(b&&B){F++;let M=fG(B,U);if(N.push(`${L.status} → ${M}`),L.status===303||(L.status===301||L.status===302)&&H!=="GET"&&H!=="HEAD")H="GET",O=void 0;U=M;continue}let I=await L.text(),w=hG(L.headers);return{status:L.status,status_text:L.statusText,headers:w,body:I,url:L.url||U,redirected:F>0,redirect_count:F,redirect_chain:N,content_type:w["content-type"],response_time:0}}}function UY($,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+=`
1100
+ `)}var bY=b(()=>{S1();c1();b9();LY()});var RY=b(()=>{b9();bY()});import{z as X2}from"zod";async function HK($){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},U=Y,H=Z,O=Q,F=0,z=[];while(!0){let _={...W};if(O&&H!=="GET"&&H!=="HEAD"&&!BK(_,"content-type"))_["Content-Type"]="application/json";let w=await zK(U,{method:H,headers:_,body:O&&H!=="GET"&&H!=="HEAD"?O:void 0,redirect:"manual"},J,K),B=w.headers.get("location"),N=w.status>=300&&w.status<400,I=q&&N&&B&&F<G;if(N&&q&&!B)throw Error(`收到状态码 ${w.status} 但响应缺少 Location 头`);if(N&&q&&F>=G)throw Error(`超过最大重定向次数 (${G})`);if(I&&B){F++;let D=_K(B,U);if(z.push(`${w.status} → ${D}`),w.status===303||(w.status===301||w.status===302)&&H!=="GET"&&H!=="HEAD")H="GET",O=void 0;U=D;continue}let M=await w.text(),A=NK(w.headers);return{status:w.status,status_text:w.statusText,headers:A,body:M,url:w.url||U,redirected:F>0,redirect_count:F,redirect_chain:z,content_type:A["content-type"],response_time:0}}}function VY($,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+=`
1093
1101
  响应时间: ${q}ms`,K+=`
1094
1102
  内容长度: ${G} 字节`,Y.content_type)K+=`
1095
1103
  Content-Type: ${Y.content_type}`;if($.redirected&&Y.final_url&&Y.final_url!==X){if(K+=`
1096
1104
  最终URL: ${Y.final_url}`,Y.redirect_count)K+=`
1097
- 重定向次数: ${Y.redirect_count}`}let W=TG($.body,$.content_type);if(W)K+=`
1105
+ 重定向次数: ${Y.redirect_count}`}let W=OK($.body,$.content_type);if(W)K+=`
1098
1106
  响应内容:
1099
- ${W}`;return K}function TG($,Y){if(!$)return"(空响应)";if(SG(Y,$))return"[binary content omitted]";let Z=$.trim();if(!Z)return"(仅包含空白字符)";return Z.length>800?`${Z.slice(0,800)}...`:Z}function SG($,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 CG($,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 fG($,Y){try{return new URL($,Y).toString()}catch{return $}}function hG($){let Y={};return $.forEach((Z,X)=>{Y[X.toLowerCase()]=Z}),Y}function xG($,Y){let Z=Y.toLowerCase();return Object.keys($).some((X)=>X.toLowerCase()===Z)}var U9;var HY=R(()=>{P1();d1();H2();U9=Q1({name:"WebFetch",displayName:"Web Fetch",kind:"readonly",schema:e0.object({url:e0.string().url().describe("URL to request"),method:e0.enum(["GET","POST","PUT","DELETE","HEAD"]).default("GET").describe("HTTP method"),headers:e0.record(e0.string()).optional().describe("Request headers (optional)"),body:e0.string().optional().describe("Request body (optional)"),timeout:N1.timeout(1000,120000,30000),follow_redirects:e0.boolean().default(!0).describe("Follow redirects"),max_redirects:e0.number().int().min(0).max(10).default(5).describe("Maximum redirect hops"),return_headers:e0.boolean().default(!1).describe("Return response headers")}),description:{short:"Fetches content from a specified URL and processes it using an AI model",long:`
1107
+ ${W}`;return K}function OK($,Y){if(!$)return"(空响应)";if(FK(Y,$))return"[binary content omitted]";let Z=$.trim();if(!Z)return"(仅包含空白字符)";return Z.length>800?`${Z.slice(0,800)}...`:Z}function FK($,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 zK($,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 _K($,Y){try{return new URL($,Y).toString()}catch{return $}}function NK($){let Y={};return $.forEach((Z,X)=>{Y[X.toLowerCase()]=Z}),Y}function BK($,Y){let Z=Y.toLowerCase();return Object.keys($).some((X)=>X.toLowerCase()===Z)}var V9;var DY=b(()=>{S1();c1();N2();V9=Q1({name:"WebFetch",displayName:"Web Fetch",kind:"readonly",schema:X2.object({url:X2.string().url().describe("URL to request"),method:X2.enum(["GET","POST","PUT","DELETE","HEAD"]).default("GET").describe("HTTP method"),headers:X2.record(X2.string()).optional().describe("Request headers (optional)"),body:X2.string().optional().describe("Request body (optional)"),timeout:_1.timeout(1000,120000,30000),follow_redirects:X2.boolean().default(!0).describe("Follow redirects"),max_redirects:X2.number().int().min(0).max(10).default(5).describe("Maximum redirect hops"),return_headers:X2.boolean().default(!1).describe("Return response headers")}),description:{short:"Fetches content from a specified URL and processes it using an AI model",long:`
1100
1108
  - Fetches content from a specified URL and processes it using an AI model
1101
1109
  - Takes a URL and a prompt as input
1102
1110
  - Fetches the URL content, converts HTML to markdown
@@ -1113,12 +1121,12 @@ Usage notes:
1113
1121
  - Results may be summarized if the content is very large
1114
1122
  - Includes a self-cleaning 15-minute cache for faster responses when repeatedly accessing the same URL
1115
1123
  - 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.
1116
- `},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:U}=Y,H=Y.signal??new AbortController().signal;try{U?.(`发送 ${X} 请求到: ${Z}`);let O=Date.now(),F=await PG({url:Z,method:X,headers:Q,body:J,timeout:q,follow_redirects:G,max_redirects:K,signal:H}),N=Date.now()-O;if(F.response_time=N,!W)delete F.headers;let z={url:Z,method:X,status:F.status,response_time:N,content_length:Buffer.byteLength(F.body||"","utf8"),redirected:F.redirected||!1,redirect_count:F.redirect_count??0,final_url:F.url,content_type:F.content_type,redirect_chain:F.redirect_chain};if(F.status>=400)return{success:!1,llmContent:`HTTP error ${F.status}: ${F.status_text}`,displayContent:UY(F,z,!0),error:{type:"execution_error",message:`HTTP error ${F.status}: ${F.status_text}`,details:{...z,response_body:F.body}},metadata:z};return{success:!0,llmContent:F,displayContent:UY(F,z,!1),metadata:z}}catch(O){if(O.name==="AbortError")return{success:!1,llmContent:"Request aborted",displayContent:"⚠️ 请求被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`Network request failed: ${O.message}`,displayContent:`❌ 网络请求失败: ${O.message}`,error:{type:"execution_error",message:O.message,details:O}}}},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 pG($){return $.replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#39;/g,"'")}function OY($){let Y=pG($).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 H9($){try{let Y=new URL($),Z=Y.pathname==="/"?"":Y.pathname;return`${Y.hostname}${Z}`}catch{return $}}function O9($){try{return new URL($).hostname.toLowerCase()}catch{return""}}function gG($){if(!$.FirstURL||!$.Text)return null;let{title:Y,snippet:Z}=OY($.Text);return{title:Y,snippet:Z,url:$.FirstURL,display_url:H9($.FirstURL),source:O9($.FirstURL)}}function FY($){let Y=[];for(let Z of $){if(Z.Topics&&Z.Topics.length>0){Y.push(...FY(Z.Topics));continue}if(Z.FirstURL&&Z.Text){let{title:X,snippet:Q}=OY(Z.Text);Y.push({title:X,snippet:Q,url:Z.FirstURL,display_url:H9(Z.FirstURL),source:O9(Z.FirstURL)})}}return Y}function mG($){let Y=$,Z=(Y.Results??[]).map((Q)=>gG(Q)).filter((Q)=>Q!==null),X=FY(Y.RelatedTopics??[]);return[...Z,...X]}function uG($){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:H9(X.url),source:O9(X.url)})}return Z}function cG($){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:uG,getHeaders:()=>({Accept:"application/json","User-Agent":"Blade-AI-WebSearch/1.0"})}}function _Y(){return[dG,...zY.map(cG)]}function NY(){return 1+zY.length}var dG,zY;var BY=R(()=>{dG={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:mG,getHeaders:()=>({Accept:"application/json, text/plain;q=0.9","User-Agent":"Blade-AI-WebSearch/1.0"})};zY=["https://searx.be","https://search.ononoki.org","https://searx.tiekoetter.com","https://searx.work"]});import{ProxyAgent as lG,fetch as iG}from"undici";import{z as B$}from"zod";function nG(){let $=process.env.HTTPS_PROXY||process.env.HTTP_PROXY||process.env.https_proxy||process.env.http_proxy;if($)try{return new lG($)}catch(Y){console.warn(`Invalid proxy URL: ${$}`)}return}async function oG($,Y,Z,X,Q){let J=new AbortController,q=setTimeout(()=>J.abort(),Z),G=()=>J.abort();X?.addEventListener("abort",G);try{return await iG($,{...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 sG($,Y,Z,X,Q,J){let q=null;for(let G=0;G<Y6.maxRetries;G++)try{return await oG($,Y,Z,X,Q)}catch(K){if(q=K,X?.aborted)throw K;if(G<Y6.maxRetries-1){let W=Math.min(Y6.baseDelay*Math.pow(2,G),Y6.maxDelay);J?.(`⏳ 请求失败,${W/1000}s 后重试 (${G+1}/${Y6.maxRetries})...`),await new Promise((U)=>setTimeout(U,W))}}throw q}async function tG($,Y,Z,X,Q,J){let q=$.buildUrl(Y),G=await sG(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 eG($,Y,Z,X){let Q=_Y(),J=nG(),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 tG(K,$,Y,Z,J,X)}catch(W){let U=`${K.name}: ${W.message}`;if(q.push(U),X?.(`⚠️ ${U}`),G===Q.length-1)throw Error(`所有搜索提供商都失败了:
1124
+ `},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:U}=Y,H=Y.signal??new AbortController().signal;try{U?.(`发送 ${X} 请求到: ${Z}`);let O=Date.now(),F=await HK({url:Z,method:X,headers:Q,body:J,timeout:q,follow_redirects:G,max_redirects:K,signal:H}),z=Date.now()-O;if(F.response_time=z,!W)delete F.headers;let _={url:Z,method:X,status:F.status,response_time:z,content_length:Buffer.byteLength(F.body||"","utf8"),redirected:F.redirected||!1,redirect_count:F.redirect_count??0,final_url:F.url,content_type:F.content_type,redirect_chain:F.redirect_chain};if(F.status>=400)return{success:!1,llmContent:`HTTP error ${F.status}: ${F.status_text}`,displayContent:VY(F,_,!0),error:{type:"execution_error",message:`HTTP error ${F.status}: ${F.status_text}`,details:{..._,response_body:F.body}},metadata:_};return{success:!0,llmContent:F,displayContent:VY(F,_,!1),metadata:_}}catch(O){if(O.name==="AbortError")return{success:!1,llmContent:"Request aborted",displayContent:"⚠️ 请求被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`Network request failed: ${O.message}`,displayContent:`❌ 网络请求失败: ${O.message}`,error:{type:"execution_error",message:O.message,details:O}}}},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 wK($){return $.replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#39;/g,"'")}function IY($){let Y=wK($).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 D9($){try{let Y=new URL($),Z=Y.pathname==="/"?"":Y.pathname;return`${Y.hostname}${Z}`}catch{return $}}function I9($){try{return new URL($).hostname.toLowerCase()}catch{return""}}function LK($){if(!$.FirstURL||!$.Text)return null;let{title:Y,snippet:Z}=IY($.Text);return{title:Y,snippet:Z,url:$.FirstURL,display_url:D9($.FirstURL),source:I9($.FirstURL)}}function MY($){let Y=[];for(let Z of $){if(Z.Topics&&Z.Topics.length>0){Y.push(...MY(Z.Topics));continue}if(Z.FirstURL&&Z.Text){let{title:X,snippet:Q}=IY(Z.Text);Y.push({title:X,snippet:Q,url:Z.FirstURL,display_url:D9(Z.FirstURL),source:I9(Z.FirstURL)})}}return Y}function AK($){let Y=$,Z=(Y.Results??[]).map((Q)=>LK(Q)).filter((Q)=>Q!==null),X=MY(Y.RelatedTopics??[]);return[...Z,...X]}function RK($){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:D9(X.url),source:I9(X.url)})}return Z}function VK($){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:RK,getHeaders:()=>({Accept:"application/json","User-Agent":"Blade-AI-WebSearch/1.0"})}}function vY(){return[bK,...jY.map(VK)]}function yY(){return 1+jY.length}var bK,jY;var EY=b(()=>{bK={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:AK,getHeaders:()=>({Accept:"application/json, text/plain;q=0.9","User-Agent":"Blade-AI-WebSearch/1.0"})};jY=["https://searx.be","https://search.ononoki.org","https://searx.tiekoetter.com","https://searx.work"]});import{ProxyAgent as DK,fetch as IK}from"undici";import{z as A$}from"zod";function vK(){let $=process.env.HTTPS_PROXY||process.env.HTTP_PROXY||process.env.https_proxy||process.env.http_proxy;if($)try{return new DK($)}catch(Y){console.warn(`Invalid proxy URL: ${$}`)}return}async function yK($,Y,Z,X,Q){let J=new AbortController,q=setTimeout(()=>J.abort(),Z),G=()=>J.abort();X?.addEventListener("abort",G);try{return await IK($,{...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 EK($,Y,Z,X,Q,J){let q=null;for(let G=0;G<q6.maxRetries;G++)try{return await yK($,Y,Z,X,Q)}catch(K){if(q=K,X?.aborted)throw K;if(G<q6.maxRetries-1){let W=Math.min(q6.baseDelay*Math.pow(2,G),q6.maxDelay);J?.(`⏳ 请求失败,${W/1000}s 后重试 (${G+1}/${q6.maxRetries})...`),await new Promise((U)=>setTimeout(U,W))}}throw q}async function kK($,Y,Z,X,Q,J){let q=$.buildUrl(Y),G=await EK(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 PK($,Y,Z,X){let Q=vY(),J=vK(),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 kK(K,$,Y,Z,J,X)}catch(W){let U=`${K.name}: ${W.message}`;if(q.push(U),X?.(`⚠️ ${U}`),G===Q.length-1)throw Error(`所有搜索提供商都失败了:
1117
1125
  ${q.join(`
1118
- `)}`)}}throw Error("No search providers available")}function $K($){try{return new URL($).hostname.toLowerCase()}catch{return null}}function YK($){return $.trim().toLowerCase()}function LY($){if(!$||$.length===0)return[];return $.map(YK).filter(Boolean)}function wY($,Y){return $===Y||$.endsWith(`.${Y}`)}function ZK($,Y,Z){return $.filter((X)=>{let Q=$K(X.url);if(!Q)return!1;if(Z.length>0&&Z.some((J)=>wY(Q,J)))return!1;if(Y.length>0&&!Y.some((J)=>wY(Q,J)))return!1;return!0})}function XK($,Y,Z,X){let Q=`\uD83D\uDD0E WebSearch("${$}") via ${X} - 返回 ${Y.length}/${Z} 条结果`,J=Y.map((q,G)=>`${G+1}. ${q.title}
1126
+ `)}`)}}throw Error("No search providers available")}function TK($){try{return new URL($).hostname.toLowerCase()}catch{return null}}function SK($){return $.trim().toLowerCase()}function kY($){if(!$||$.length===0)return[];return $.map(SK).filter(Boolean)}function PY($,Y){return $===Y||$.endsWith(`.${Y}`)}function CK($,Y,Z){return $.filter((X)=>{let Q=TK(X.url);if(!Q)return!1;if(Z.length>0&&Z.some((J)=>PY(Q,J)))return!1;if(Y.length>0&&!Y.some((J)=>PY(Q,J)))return!1;return!0})}function fK($,Y,Z,X){let Q=`\uD83D\uDD0E WebSearch("${$}") via ${X} - 返回 ${Y.length}/${Z} 条结果`,J=Y.map((q,G)=>`${G+1}. ${q.title}
1119
1127
  ${q.display_url}
1120
1128
  ${q.snippet}`);return[Q,...J].join(`
1121
- `)}function QK($){let Y=$.trim().toLowerCase();return Y.length>80?Y.slice(0,80):Y}var rG=15000,aG=8,Y6,F9;var AY=R(()=>{P1();d1();BY();Y6={maxRetries:3,baseDelay:1000,maxDelay:8000};F9=Q1({name:"WebSearch",displayName:"Web Search",kind:"readonly",schema:B$.object({query:B$.string().min(2,"Search query must be at least 2 characters").describe("Search query"),allowed_domains:B$.array(B$.string().min(1)).optional().describe("Return results only from these domains (optional)"),blocked_domains:B$.array(B$.string().min(1)).optional().describe("Exclude results from these domains (optional)")}),description:{short:"Search the web and use the results to inform responses",long:`
1129
+ `)}function hK($){let Y=$.trim().toLowerCase();return Y.length>80?Y.slice(0,80):Y}var MK=15000,jK=8,q6,M9;var TY=b(()=>{S1();c1();EY();q6={maxRetries:3,baseDelay:1000,maxDelay:8000};M9=Q1({name:"WebSearch",displayName:"Web Search",kind:"readonly",schema:A$.object({query:A$.string().min(2,"Search query must be at least 2 characters").describe("Search query"),allowed_domains:A$.array(A$.string().min(1)).optional().describe("Return results only from these domains (optional)"),blocked_domains:A$.array(A$.string().min(1)).optional().describe("Exclude results from these domains (optional)")}),description:{short:"Search the web and use the results to inform responses",long:`
1122
1130
  - Search the web and use the results to inform responses
1123
1131
  - Provides up-to-date information for current events and recent data
1124
1132
  - Returns search result information formatted as search result blocks, including links as markdown hyperlinks
@@ -1146,15 +1154,15 @@ Usage notes:
1146
1154
  IMPORTANT - Use the correct year in search queries:
1147
1155
  - You MUST use the current year when searching for recent information, documentation, or current events.
1148
1156
  - Example: If the user asks for "latest React docs", search for "React documentation 2025", NOT "React documentation 2024"
1149
- `},async execute($,Y){let{query:Z}=$,X=LY($.allowed_domains),Q=LY($.blocked_domains),{updateOutput:J}=Y,q=Y.signal??new AbortController().signal;J?.(`\uD83D\uDD0E Searching: "${Z}" (${NY()} providers available)`);try{let{results:G,providerName:K}=await eG(Z,rG,q,J),W=ZK(G,X,Q),U=W.slice(0,aG),H={query:Z,results:U,provider:K,total_results:W.length,fetched_at:new Date().toISOString()},O={query:Z,provider:K,fetched_at:H.fetched_at,total_results:W.length,returned_results:U.length,allowed_domains:X,blocked_domains:Q};if(U.length===0)return{success:!0,llmContent:H,displayContent:`\uD83D\uDD0D WebSearch("${Z}") via ${K} - 未找到匹配结果`,metadata:O};return{success:!0,llmContent:H,displayContent:XK(Z,U,W.length,K),metadata:O}}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:${QK($.query)}`,abstractPermissionRule:()=>"search:*"})});var bY=R(()=>{HY();AY()});import*as RY from"os";import*as VY from"path";async function JK(){try{return await p1.getInstance().getAvailableTools()}catch($){return console.warn("MCP协议工具加载失败:",$),[]}}async function DY($){let Y=$?.sessionId||`session_${Date.now()}`,Z=$?.configDir||VY.join(RY.homedir(),".blade"),X=[x8,h8,g8,m8,r8,o8,t8,$9,Y9,U9,F9,G9,W9({sessionId:Y,configDir:Z}),d8,c8,X9,Q9],Q=await JK();return[...X,...Q]}var IY=R(()=>{Y$();v3();E3();C3();u3();o3();$Y();QY();WY();bY()});var X4,z9,_9;var Q4=R(()=>{((X)=>{X.PreToolUse="PreToolUse";X.PostToolUse="PostToolUse";X.Stop="Stop"})(X4||={});((X)=>{X.Approve="approve";X.Block="block";X.Async="async"})(z9||={});((X)=>{X.Allow="allow";X.Deny="deny";X.Ask="ask"})(_9||={})});function B9($,Y){return{...$,...Y,PreToolUse:Y.PreToolUse??$.PreToolUse,PostToolUse:Y.PostToolUse??$.PostToolUse,Stop:Y.Stop??$.Stop}}function MY(){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 N9;var jY=R(()=>{N9={enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,PreToolUse:[],PostToolUse:[],Stop:[]}});import{spawn as qK}from"child_process";class L9{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 w9{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=qK($,[],{shell:!0,env:J,cwd:Z.projectDir,timeout:X}),G=new L9(this.MAX_STDOUT_SIZE),K=new L9(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,U)=>{let H=!1,O=setTimeout(()=>{H=!0,q.kill("SIGKILL")},X);if(q.on("close",(F)=>{clearTimeout(O),W({stdout:G.getContent(),stderr:K.getContent(),exitCode:H?124:F??1,timedOut:H})}),q.on("error",(F)=>{clearTimeout(O),U(F)}),Z.abortSignal)Z.abortSignal.addEventListener("abort",()=>{clearTimeout(O),q.kill("SIGTERM"),W({stdout:G.getContent(),stderr:"Hook cancelled by abort signal",exitCode:1,timedOut:!1})})})}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 vY=()=>{};import{z as S}from"zod";function yY($){let Y=FK.safeParse($);if(Y.success)return{success:!0,data:Y.data};return{success:!1,error:Y.error}}var b9,KK,WK,UK,WA,HK,OK,FK,zK,_K,NK,BK,A9,UA;var EY=R(()=>{Q4();b9=S.object({hook_event_name:S.nativeEnum(X4),hook_execution_id:S.string(),timestamp:S.string(),project_dir:S.string(),session_id:S.string(),permission_mode:S.enum(["default","autoEdit","yolo","plan"]),_metadata:S.object({blade_version:S.string(),hook_timeout_ms:S.number()}).optional()}),KK=b9.extend({hook_event_name:S.literal("PreToolUse"),tool_name:S.string(),tool_use_id:S.string(),tool_input:S.record(S.unknown())}),WK=b9.extend({hook_event_name:S.literal("PostToolUse"),tool_name:S.string(),tool_use_id:S.string(),tool_input:S.record(S.unknown()),tool_response:S.unknown()}),UK=b9.extend({hook_event_name:S.literal("Stop"),reason:S.string().optional()}),WA=S.discriminatedUnion("hook_event_name",[KK,WK,UK]),HK=S.object({hookEventName:S.literal("PreToolUse"),permissionDecision:S.nativeEnum(_9).optional(),permissionDecisionReason:S.string().optional(),updatedInput:S.record(S.unknown()).optional()}),OK=S.object({hookEventName:S.literal("PostToolUse"),additionalContext:S.string().optional(),updatedOutput:S.unknown().optional()}),FK=S.object({decision:S.object({behavior:S.nativeEnum(z9)}).optional(),systemMessage:S.string().optional(),hookSpecificOutput:S.discriminatedUnion("hookEventName",[HK,OK]).optional(),suppressOutput:S.boolean().optional()}),zK=S.object({type:S.literal("command"),command:S.string(),timeout:S.number().positive().optional(),statusMessage:S.string().optional()}),_K=S.object({type:S.literal("prompt"),prompt:S.string(),timeout:S.number().positive().optional()}),NK=S.discriminatedUnion("type",[zK,_K]),BK=S.object({tools:S.string().optional(),paths:S.string().optional(),commands:S.string().optional()}),A9=S.object({name:S.string().optional(),matcher:BK.optional(),hooks:S.array(NK)}),UA=S.object({enabled:S.boolean().optional(),defaultTimeout:S.number().positive().optional(),timeoutBehavior:S.enum(["ignore","deny","ask"]).optional(),failureBehavior:S.enum(["ignore","deny","ask"]).optional(),maxConcurrentHooks:S.number().positive().optional(),PreToolUse:S.array(A9).optional(),PostToolUse:S.array(A9).optional(),Stop:S.array(A9).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=yY(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 kY=R(()=>{EY()});class V9{processExecutor=new w9;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(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(`
1157
+ `},async execute($,Y){let{query:Z}=$,X=kY($.allowed_domains),Q=kY($.blocked_domains),{updateOutput:J}=Y,q=Y.signal??new AbortController().signal;J?.(`\uD83D\uDD0E Searching: "${Z}" (${yY()} providers available)`);try{let{results:G,providerName:K}=await PK(Z,MK,q,J),W=CK(G,X,Q),U=W.slice(0,jK),H={query:Z,results:U,provider:K,total_results:W.length,fetched_at:new Date().toISOString()},O={query:Z,provider:K,fetched_at:H.fetched_at,total_results:W.length,returned_results:U.length,allowed_domains:X,blocked_domains:Q};if(U.length===0)return{success:!0,llmContent:H,displayContent:`\uD83D\uDD0D WebSearch("${Z}") via ${K} - 未找到匹配结果`,metadata:O};return{success:!0,llmContent:H,displayContent:fK(Z,U,W.length,K),metadata:O}}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:${hK($.query)}`,abstractPermissionRule:()=>"search:*"})});var SY=b(()=>{DY();TY()});import*as CY from"os";import*as fY from"path";async function xK(){try{return await g1.getInstance().getAvailableTools()}catch($){return console.warn("MCP协议工具加载失败:",$),[]}}async function hY($){let Y=$?.sessionId||`session_${Date.now()}`,Z=$?.configDir||fY.join(CY.homedir(),".blade"),X=[o8,n8,t8,e8,J9,K9,U9,O9,F9,V9,M9,A9,R9({sessionId:Y,configDir:Z}),$9,Z9,_9,N9],Q=await xK();return[...X,...Q]}var xY=b(()=>{J$();m3();u3();a3();ZY();WY();FY();BY();RY();SY()});var U4,j9,v9;var H4=b(()=>{((X)=>{X.PreToolUse="PreToolUse";X.PostToolUse="PostToolUse";X.Stop="Stop"})(U4||={});((X)=>{X.Approve="approve";X.Block="block";X.Async="async"})(j9||={});((X)=>{X.Allow="allow";X.Deny="deny";X.Ask="ask"})(v9||={})});function E9($,Y){return{...$,...Y,PreToolUse:Y.PreToolUse??$.PreToolUse,PostToolUse:Y.PostToolUse??$.PostToolUse,Stop:Y.Stop??$.Stop}}function pY(){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 y9;var gY=b(()=>{y9={enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,PreToolUse:[],PostToolUse:[],Stop:[]}});import{spawn as pK}from"child_process";class k9{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 P9{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=pK($,[],{shell:!0,env:J,cwd:Z.projectDir,timeout:X}),G=new k9(this.MAX_STDOUT_SIZE),K=new k9(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,U)=>{let H=!1,O=setTimeout(()=>{H=!0,q.kill("SIGKILL")},X);if(q.on("close",(F)=>{clearTimeout(O),W({stdout:G.getContent(),stderr:K.getContent(),exitCode:H?124:F??1,timedOut:H})}),q.on("error",(F)=>{clearTimeout(O),U(F)}),Z.abortSignal)Z.abortSignal.addEventListener("abort",()=>{clearTimeout(O),q.kill("SIGTERM"),W({stdout:G.getContent(),stderr:"Hook cancelled by abort signal",exitCode:1,timedOut:!1})})})}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 mY=()=>{};import{z as S}from"zod";function dY($){let Y=iK.safeParse($);if(Y.success)return{success:!0,data:Y.data};return{success:!1,error:Y.error}}var S9,mK,dK,uK,rA,cK,lK,iK,rK,aK,nK,oK,T9,aA;var uY=b(()=>{H4();S9=S.object({hook_event_name:S.nativeEnum(U4),hook_execution_id:S.string(),timestamp:S.string(),project_dir:S.string(),session_id:S.string(),permission_mode:S.enum(["default","autoEdit","yolo","plan"]),_metadata:S.object({blade_version:S.string(),hook_timeout_ms:S.number()}).optional()}),mK=S9.extend({hook_event_name:S.literal("PreToolUse"),tool_name:S.string(),tool_use_id:S.string(),tool_input:S.record(S.unknown())}),dK=S9.extend({hook_event_name:S.literal("PostToolUse"),tool_name:S.string(),tool_use_id:S.string(),tool_input:S.record(S.unknown()),tool_response:S.unknown()}),uK=S9.extend({hook_event_name:S.literal("Stop"),reason:S.string().optional()}),rA=S.discriminatedUnion("hook_event_name",[mK,dK,uK]),cK=S.object({hookEventName:S.literal("PreToolUse"),permissionDecision:S.nativeEnum(v9).optional(),permissionDecisionReason:S.string().optional(),updatedInput:S.record(S.unknown()).optional()}),lK=S.object({hookEventName:S.literal("PostToolUse"),additionalContext:S.string().optional(),updatedOutput:S.unknown().optional()}),iK=S.object({decision:S.object({behavior:S.nativeEnum(j9)}).optional(),systemMessage:S.string().optional(),hookSpecificOutput:S.discriminatedUnion("hookEventName",[cK,lK]).optional(),suppressOutput:S.boolean().optional()}),rK=S.object({type:S.literal("command"),command:S.string(),timeout:S.number().positive().optional(),statusMessage:S.string().optional()}),aK=S.object({type:S.literal("prompt"),prompt:S.string(),timeout:S.number().positive().optional()}),nK=S.discriminatedUnion("type",[rK,aK]),oK=S.object({tools:S.string().optional(),paths:S.string().optional(),commands:S.string().optional()}),T9=S.object({name:S.string().optional(),matcher:oK.optional(),hooks:S.array(nK)}),aA=S.object({enabled:S.boolean().optional(),defaultTimeout:S.number().positive().optional(),timeoutBehavior:S.enum(["ignore","deny","ask"]).optional(),failureBehavior:S.enum(["ignore","deny","ask"]).optional(),maxConcurrentHooks:S.number().positive().optional(),PreToolUse:S.array(T9).optional(),PostToolUse:S.array(T9).optional(),Stop:S.array(T9).optional()})});class C9{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=dY(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 cY=b(()=>{uY()});class f9{processExecutor=new P9;outputParser=new C9;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(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(`
1150
1158
  `):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(W.updatedOutput!==void 0)q=W.updatedOutput}}return{additionalContext:J.length>0?J.join(`
1151
1159
 
1152
1160
  `):void 0,modifiedOutput:q,warning:G.length>0?G.join(`
1153
- `):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 PY=R(()=>{Q4();vY();kY()});class D9{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()}}import LK from"picomatch";class I9{matches($,Y){if(!$)return!0;if($.tools&&Y.toolName){if(!this.matchPattern(Y.toolName,$.tools))return!1}if($.paths&&Y.filePath){if(!LK($.paths)(Y.filePath))return!1}if($.commands&&Y.command){if(!this.matchPattern(Y.command,$.commands))return!1}return!0}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 TY=()=>{};import{nanoid as SY}from"nanoid";class U0{static instance=null;config=N9;executor=new V9;guard=new D9;matcher=new I9;sessionDisabled=!1;constructor(){}static getInstance(){if(!U0.instance)U0.instance=new U0;return U0.instance}loadConfig($){let Y=B9(N9,$),Z=MY();Y=B9(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")}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:SY(),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:SY(),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)}}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 J4=R(()=>{Q4();jY();PY();TY()});import{nanoid as wK}from"nanoid";class M9{name="hook";hookManager;constructor(){this.hookManager=U0.getInstance()}async process($){if(!this.hookManager.isEnabled())return;let Y=$._internal.tool;if(!Y)return;try{let Z=$.context.messageId||`tool_${wK()}`;$._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 CY=R(()=>{J4()});import{nanoid as AK}from"nanoid";class j9{name="post-hook";hookManager;constructor(){this.hookManager=U0.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_${AK()}`,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}
1161
+ `):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 lY=b(()=>{H4();mY();cY()});class h9{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()}}import sK from"picomatch";class x9{matches($,Y){if(!$)return!0;if($.tools&&Y.toolName){if(!this.matchPattern(Y.toolName,$.tools))return!1}if($.paths&&Y.filePath){if(!sK($.paths)(Y.filePath))return!1}if($.commands&&Y.command){if(!this.matchPattern(Y.command,$.commands))return!1}return!0}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 iY=()=>{};import{nanoid as rY}from"nanoid";class F0{static instance=null;config=y9;executor=new f9;guard=new h9;matcher=new x9;sessionDisabled=!1;constructor(){}static getInstance(){if(!F0.instance)F0.instance=new F0;return F0.instance}loadConfig($){let Y=E9(y9,$),Z=pY();Y=E9(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")}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:rY(),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:rY(),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)}}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 O4=b(()=>{H4();gY();lY();iY()});import{nanoid as tK}from"nanoid";class p9{name="hook";hookManager;constructor(){this.hookManager=F0.getInstance()}async process($){if(!this.hookManager.isEnabled())return;let Y=$._internal.tool;if(!Y)return;try{let Z=$.context.messageId||`tool_${tK()}`;$._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 aY=b(()=>{O4()});import{nanoid as eK}from"nanoid";class g9{name="post-hook";hookManager;constructor(){this.hookManager=F0.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_${eK()}`,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}
1154
1162
 
1155
1163
  ---
1156
1164
  **Hook Context:**
1157
- ${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 fY=R(()=>{J4()});class N2{static instance=null;locks=new Map;constructor(){}static getInstance(){if(!N2.instance)N2.instance=new N2;return N2.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){v9.debug(`获取文件锁: ${$}`);try{let Z=await Y();return v9.debug(`释放文件锁: ${$}`),Z}catch(Z){throw v9.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(){N2.instance=null}}var v9;var hY=R(()=>{A1();v9=i("Execution")});import bK from"node:os";import y9 from"node:path";var E9;var xY=R(()=>{E9=class E9{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=y9.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 y9.join(bK.homedir(),$.slice(1));return y9.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 k9{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 P9{name="permission";permissionChecker;sessionApprovals;defaultPermissionMode;constructor($,Y,Z){this.permissionChecker=new j2($),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=j2.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((H)=>{if(H.includes(".."))return!0;return K.some((O)=>H.includes(O))});if(W.length>0){$.abort(`Access to dangerous system paths denied: ${W.join(", ")}`);return}let U=E9.filterSensitive(X,"medium");if(U.length>0){let H=U.map(({path:F,result:N})=>`${F} (${N.level}: ${N.reason})`);if(U.filter(({result:F})=>F.level==="high").length>0&&q.result!=="allow"){$.abort(`Access to highly sensitive files denied:
1165
+ ${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 nY=b(()=>{O4()});class A2{static instance=null;locks=new Map;constructor(){}static getInstance(){if(!A2.instance)A2.instance=new A2;return A2.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){m9.debug(`获取文件锁: ${$}`);try{let Z=await Y();return m9.debug(`释放文件锁: ${$}`),Z}catch(Z){throw m9.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(){A2.instance=null}}var m9;var oY=b(()=>{B1();m9=c("Execution")});import $W from"node:os";import d9 from"node:path";var u9;var sY=b(()=>{u9=class u9{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=d9.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 d9.join($W.homedir(),$.slice(1));return d9.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 c9{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 l9{name="permission";permissionChecker;sessionApprovals;defaultPermissionMode;constructor($,Y,Z){this.permissionChecker=new k2($),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=k2.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((H)=>{if(H.includes(".."))return!0;return K.some((O)=>H.includes(O))});if(W.length>0){$.abort(`Access to dangerous system paths denied: ${W.join(", ")}`);return}let U=u9.filterSensitive(X,"medium");if(U.length>0){let H=U.map(({path:F,result:z})=>`${F} (${z.level}: ${z.reason})`);if(U.filter(({result:F})=>F.level==="high").length>0&&q.result!=="allow"){$.abort(`Access to highly sensitive files denied:
1158
1166
  ${H.join(`
1159
1167
  `)}
1160
1168
 
@@ -1162,7 +1170,7 @@ If access is required, add an explicit allow rule in permissions.`);return}if(q.
1162
1170
  ${H.join(`
1163
1171
  `)}
1164
1172
 
1165
- 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(!i$($))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(i$($))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 T9{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 G={title:`权限确认: ${Y.extractSignatureContent?Y.extractSignatureContent($.params):Y.name}`,message:Q||"此操作需要用户确认",kind:Y.kind,details:this.generatePreviewForTool(Y.name,$.params),risks:this.extractRisksFromPermissionCheck(Y,$.params,J),affectedFiles:Z.getAffectedPaths()||[]};if(S2.warn(`工具 "${Y.name}" 需要用户确认: ${G.title}`),S2.warn(`详情: ${G.message}`),G.risks&&G.risks.length>0)S2.warn(`风险: ${G.risks.join(", ")}`);let K=$.context.confirmationHandler;if(K){let W=await K.requestConfirmation(G);if(!W.approved){$.abort(`User rejected execution: ${W.reason||"No reason provided"}`,{shouldExitLoop:!0});return}if((W.scope||"once")==="session"&&$._internal.permissionSignature){let H=$._internal.permissionSignature;this.sessionApprovals.add(H);let O={toolName:Y.name,params:$.params,affectedPaths:Z.getAffectedPaths()||[],tool:Y};await this.persistSessionApproval(H,O)}}else S2.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=j2.abstractPattern(Y);S2.debug(`保存权限规则: "${Z}"`),await z1().appendLocalPermissionAllowRule(Z,{immediate:!0});let X=v1();if(X?.permissions)S2.debug("同步权限配置到 PermissionChecker:",X.permissions),this.permissionChecker.replaceConfig(X.permissions)}catch(Z){S2.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(`
1173
+ 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(!n$($))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(n$($))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 i9{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 G={title:`权限确认: ${Y.extractSignatureContent?Y.extractSignatureContent($.params):Y.name}`,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 K=$.context.confirmationHandler;if(K){let W=await K.requestConfirmation(G);if(!W.approved){$.abort(`User rejected execution: ${W.reason||"No reason provided"}`,{shouldExitLoop:!0});return}if((W.scope||"once")==="session"&&$._internal.permissionSignature){let H=$._internal.permissionSignature;this.sessionApprovals.add(H);let O={toolName:Y.name,params:$.params,affectedPaths:Z.getAffectedPaths()||[],tool:Y};await this.persistSessionApproval(H,O)}}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=k2.abstractPattern(Y);x2.debug(`保存权限规则: "${Z}"`),await F1().appendLocalPermissionAllowRule(Z,{immediate:!0});let X=v1();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 G=q.split(`
1166
1174
  `);if(G.length<=Q)return q;return`${G.slice(0,Q).join(`
1167
1175
  `)}
1168
1176
  ... (还有 ${G.length-Q} 行)`};return`**变更前:**
@@ -1183,46 +1191,46 @@ ${Z}
1183
1191
  ${q}
1184
1192
  \`\`\`
1185
1193
 
1186
- ... (还有 ${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 S9{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 C9{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 S2;var pY=R(()=>{o4();Y0();A1();_1();d1();xY();S2=i("Execution")});import{EventEmitter as RK}from"events";var f9;var gY=R(()=>{Y0();CY();fY();Q8();C0();hY();pY();f9=class f9 extends RK{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 P9(Z,this.sessionApprovals,X);this.stages=[new k9(this.registry),Q,new M9,new T9(this.sessionApprovals,Q.getPermissionChecker()),new S9,new j9,new C9]}async execute($,Y,Z){let X=Date.now(),Q=this.generateExecutionId(),J=new X8($,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 N2.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={success:!1,llmContent:`Tool execution failed: ${X.message}`,displayContent:`错误: ${X.message}`,error:{type:"execution_error",message:X.message}},J=Date.now();return this.addToHistory({executionId:Y,toolName:$.toolName,params:$.params,result:Q,startTime:Z,endTime:J,context:$.context}),this.emit("executionFailed",{executionId:Y,toolName:$.toolName,error:X,duration:J-Z,timestamp:J}),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 VK}from"events";var h9;var mY=R(()=>{Y0();h9=class h9 extends VK{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 IK($){return DK.some((Y)=>Y.test($))}function MK($){if($.supportsThinking!==void 0)return{supportsThinking:$.supportsThinking,thinkingBudget:$.thinkingBudget};return{supportsThinking:IK($.model),thinkingBudget:void 0}}function L$($){return MK($).supportsThinking}var DK;var q4=R(()=>{DK=[/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 x9{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((H)=>H.role==="system"),Q=Y.filter((H)=>H.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),U=this.estimateTokenCount(G,K,J,W);return{summary:G,keyPoints:K,recentMessages:[...X,...J],toolSummary:W,tokenCount:U}}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((U)=>{if(q.includes(U)){let H=this.extractContext(q,U,50);if(H)Y.add(H)}}),["创建","删除","修改","更新","实现","开发"].forEach((U)=>{if(q.includes(U)){let H=this.extractContext(q,U,30);if(H)Z.add(H)}}),["决定","选择","确定","采用","使用"].forEach((U)=>{if(q.includes(U)){let H=this.extractContext(q,U,40);if(H)X.add(H)}})}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 C2{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 C2({maxTokens:1000,maxMessages:10,timeWindow:7200000,includeTools:!1,includeWorkspace:!1}),standard:new C2({maxTokens:4000,maxMessages:30,timeWindow:43200000,includeTools:!0,includeWorkspace:!0}),comprehensive:new C2({maxTokens:8000,maxMessages:100,timeWindow:86400000,includeTools:!0,includeWorkspace:!0}),debug:new C2({maxTokens:2000,maxMessages:20,timeWindow:21600000,priority:2,includeTools:!0,includeWorkspace:!1})}}}class p9{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 g9{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 G4 from"node:fs";import{createReadStream as jK}from"node:fs";import*as n1 from"node:fs/promises";import*as m9 from"node:path";import{createInterface as vK}from"node:readline";class M0{filePath;constructor($){this.filePath=$}async append($){try{await n1.mkdir(m9.dirname(this.filePath),{recursive:!0});let Y=JSON.stringify($)+`
1187
- `;await n1.appendFile(this.filePath,Y,"utf-8")}catch(Y){throw console.error(`[JSONLStore] 追加写入失败: ${this.filePath}`,Y),Y}}async appendBatch($){try{await n1.mkdir(m9.dirname(this.filePath),{recursive:!0});let Y=$.map((Z)=>JSON.stringify(Z)).join(`
1194
+ ... (还有 ${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 r9{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 a9{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 tY=b(()=>{Z8();Q0();B1();z1();c1();sY();x2=c("Execution")});import{EventEmitter as YW}from"events";var n9;var eY=b(()=>{Q0();aY();nY();O8();p0();oY();tY();n9=class n9 extends YW{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 l9(Z,this.sessionApprovals,X);this.stages=[new c9(this.registry),Q,new p9,new i9(this.sessionApprovals,Q.getPermissionChecker()),new r9,new g9,new a9]}async execute($,Y,Z){let X=Date.now(),Q=this.generateExecutionId(),J=new H8($,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 A2.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={success:!1,llmContent:`Tool execution failed: ${X.message}`,displayContent:`错误: ${X.message}`,error:{type:"execution_error",message:X.message}},J=Date.now();return this.addToHistory({executionId:Y,toolName:$.toolName,params:$.params,result:Q,startTime:Z,endTime:J,context:$.context}),this.emit("executionFailed",{executionId:Y,toolName:$.toolName,error:X,duration:J-Z,timestamp:J}),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 ZW}from"events";var o9;var $Z=b(()=>{Q0();o9=class o9 extends ZW{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 QW($){return XW.some((Y)=>Y.test($))}function JW($){if($.supportsThinking!==void 0)return{supportsThinking:$.supportsThinking,thinkingBudget:$.thinkingBudget};return{supportsThinking:QW($.model),thinkingBudget:void 0}}function b$($){return JW($).supportsThinking}var XW;var F4=b(()=>{XW=[/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 s9{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((H)=>H.role==="system"),Q=Y.filter((H)=>H.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),U=this.estimateTokenCount(G,K,J,W);return{summary:G,keyPoints:K,recentMessages:[...X,...J],toolSummary:W,tokenCount:U}}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((U)=>{if(q.includes(U)){let H=this.extractContext(q,U,50);if(H)Y.add(H)}}),["创建","删除","修改","更新","实现","开发"].forEach((U)=>{if(q.includes(U)){let H=this.extractContext(q,U,30);if(H)Z.add(H)}}),["决定","选择","确定","采用","使用"].forEach((U)=>{if(q.includes(U)){let H=this.extractContext(q,U,40);if(H)X.add(H)}})}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 p2{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 p2({maxTokens:1000,maxMessages:10,timeWindow:7200000,includeTools:!1,includeWorkspace:!1}),standard:new p2({maxTokens:4000,maxMessages:30,timeWindow:43200000,includeTools:!0,includeWorkspace:!0}),comprehensive:new p2({maxTokens:8000,maxMessages:100,timeWindow:86400000,includeTools:!0,includeWorkspace:!0}),debug:new p2({maxTokens:2000,maxMessages:20,timeWindow:21600000,priority:2,includeTools:!0,includeWorkspace:!1})}}}class t9{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 e9{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 z4 from"node:fs";import{createReadStream as qW}from"node:fs";import*as t1 from"node:fs/promises";import*as $7 from"node:path";import{createInterface as GW}from"node:readline";class E0{filePath;constructor($){this.filePath=$}async append($){try{await t1.mkdir($7.dirname(this.filePath),{recursive:!0});let Y=JSON.stringify($)+`
1195
+ `;await t1.appendFile(this.filePath,Y,"utf-8")}catch(Y){throw console.error(`[JSONLStore] 追加写入失败: ${this.filePath}`,Y),Y}}async appendBatch($){try{await t1.mkdir($7.dirname(this.filePath),{recursive:!0});let Y=$.map((Z)=>JSON.stringify(Z)).join(`
1188
1196
  `)+`
1189
- `;await n1.appendFile(this.filePath,Y,"utf-8")}catch(Y){throw console.error(`[JSONLStore] 批量追加写入失败: ${this.filePath}`,Y),Y}}async readAll(){try{if(!G4.existsSync(this.filePath))return[];let Y=(await n1.readFile(this.filePath,"utf-8")).split(`
1190
- `).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(!G4.existsSync(this.filePath)){Y();return}let X=jK(this.filePath,"utf-8"),Q=vK({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(!G4.existsSync(this.filePath))return{exists:!1,size:0,lineCount:0};let $=await n1.stat(this.filePath),Z=(await n1.readFile(this.filePath,"utf-8")).split(`
1191
- `).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 n1.access(this.filePath),!0}catch{return!1}}async delete(){try{if(await this.exists())await n1.unlink(this.filePath)}catch($){throw console.error(`[JSONLStore] 删除文件失败: ${this.filePath}`,$),$}}getFilePath(){return this.filePath}}var dY=()=>{};import{nanoid as w$}from"nanoid";import*as $2 from"node:fs/promises";import*as uY from"node:path";class d9{projectPath;maxSessions;version;constructor($=process.cwd(),Y=100,Z="0.0.10"){this.projectPath=$,this.maxSessions=Y,this.version=Z}async initialize(){try{let $=U$(this.projectPath);await $2.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 M0(J),G={uuid:w$(),parentUuid:X,sessionId:$,timestamp:new Date().toISOString(),type:Y==="user"?"user":Y==="assistant"?"assistant":"system",cwd:this.projectPath,gitBranch:P2(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=I0(this.projectPath,$),J=new M0(Q),q={uuid:w$(),parentUuid:X,sessionId:$,timestamp:new Date().toISOString(),type:"tool_use",cwd:this.projectPath,gitBranch:P2(this.projectPath),version:this.version,message:{role:"assistant",content:""},tool:{id:w$(),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 M0(J),G={uuid:w$(),parentUuid:X,sessionId:$,timestamp:new Date().toISOString(),type:"tool_result",cwd:this.projectPath,gitBranch:P2(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=I0(this.projectPath,$),J=new M0(Q),q={uuid:w$(),parentUuid:X,sessionId:$,timestamp:new Date().toISOString(),type:"system",subtype:"compact_boundary",cwd:this.projectPath,gitBranch:P2(this.projectPath),version:this.version,message:{role:"system",content:"=== 上下文压缩边界 ==="},compactMetadata:Z};await J.append(q),console.log("[PersistentStore] 保存压缩边界标记");let G={uuid:w$(),parentUuid:q.uuid,logicalParentUuid:X??void 0,sessionId:$,timestamp:new Date().toISOString(),type:"user",isCompactSummary:!0,cwd:this.projectPath,gitBranch:P2(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=I0(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=I0(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 $=U$(this.projectPath);return(await $2.readdir($)).filter((Z)=>Z.endsWith(".jsonl")).map((Z)=>Z.replace(".jsonl","")).sort()}catch{return[]}}async getSessionSummary($){try{let Y=I0(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=I0(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=I0(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 $=U$(this.projectPath);await $2.mkdir($,{recursive:!0});let Y=uY.join($,".health-check");return await $2.writeFile(Y,"test","utf-8"),await $2.unlink(Y),{isAvailable:!0,canWrite:!0}}catch($){return{isAvailable:!1,canWrite:!1,error:$ instanceof Error?$.message:String($)}}}static async listAllProjects(){return C8()}}var cY=R(()=>{H$();dY()});import*as iY from"crypto";import{nanoid as lY}from"nanoid";class Z6{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 g9(this.options.storage.maxMemorySize),this.persistent=new d9(process.cwd(),100),this.cache=new p9(this.options.storage.cacheSize,300000),this.compressor=new x9,this.filter=new C2(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 lY()}generateMessageId(){return lY()}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 iY.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 u9=R(()=>{cY();H$()});class c9{chatService;contextManager;memoryAdapter;constructor($,Y){this.chatService=$,this.contextManager=Y||new Z6,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+`
1197
+ `;await t1.appendFile(this.filePath,Y,"utf-8")}catch(Y){throw console.error(`[JSONLStore] 批量追加写入失败: ${this.filePath}`,Y),Y}}async readAll(){try{if(!z4.existsSync(this.filePath))return[];let Y=(await t1.readFile(this.filePath,"utf-8")).split(`
1198
+ `).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(!z4.existsSync(this.filePath)){Y();return}let X=qW(this.filePath,"utf-8"),Q=GW({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(!z4.existsSync(this.filePath))return{exists:!1,size:0,lineCount:0};let $=await t1.stat(this.filePath),Z=(await t1.readFile(this.filePath,"utf-8")).split(`
1199
+ `).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 t1.access(this.filePath),!0}catch{return!1}}async delete(){try{if(await this.exists())await t1.unlink(this.filePath)}catch($){throw console.error(`[JSONLStore] 删除文件失败: ${this.filePath}`,$),$}}getFilePath(){return this.filePath}}var YZ=()=>{};import{nanoid as R$}from"nanoid";import*as Q2 from"node:fs/promises";import*as ZZ from"node:path";class Y7{projectPath;maxSessions;version;constructor($=process.cwd(),Y=100,Z="0.0.10"){this.projectPath=$,this.maxSessions=Y,this.version=Z}async initialize(){try{let $=Z6(this.projectPath);await Q2.mkdir($,{recursive:!0}),console.log(`[PersistentStore] 初始化存储目录: ${$}`)}catch($){console.warn("[PersistentStore] 无法创建持久化存储目录:",$)}}async saveMessage($,Y,Z,X=null,Q){try{let J=O0(this.projectPath,$),q=new E0(J),G={uuid:R$(),parentUuid:X,sessionId:$,timestamp:new Date().toISOString(),type:Y==="user"?"user":Y==="assistant"?"assistant":"system",cwd:this.projectPath,gitBranch:z$(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=O0(this.projectPath,$),J=new E0(Q),q={uuid:R$(),parentUuid:X,sessionId:$,timestamp:new Date().toISOString(),type:"tool_use",cwd:this.projectPath,gitBranch:z$(this.projectPath),version:this.version,message:{role:"assistant",content:""},tool:{id:R$(),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=O0(this.projectPath,$),q=new E0(J),G={uuid:R$(),parentUuid:X,sessionId:$,timestamp:new Date().toISOString(),type:"tool_result",cwd:this.projectPath,gitBranch:z$(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=O0(this.projectPath,$),J=new E0(Q),q={uuid:R$(),parentUuid:X,sessionId:$,timestamp:new Date().toISOString(),type:"system",subtype:"compact_boundary",cwd:this.projectPath,gitBranch:z$(this.projectPath),version:this.version,message:{role:"system",content:"=== 上下文压缩边界 ==="},compactMetadata:Z};await J.append(q),console.log("[PersistentStore] 保存压缩边界标记");let G={uuid:R$(),parentUuid:q.uuid,logicalParentUuid:X??void 0,sessionId:$,timestamp:new Date().toISOString(),type:"user",isCompactSummary:!0,cwd:this.projectPath,gitBranch:z$(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=O0(this.projectPath,$),X=await new E0(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=O0(this.projectPath,$),X=await new E0(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 $=Z6(this.projectPath);return(await Q2.readdir($)).filter((Z)=>Z.endsWith(".jsonl")).map((Z)=>Z.replace(".jsonl","")).sort()}catch{return[]}}async getSessionSummary($){try{let Y=O0(this.projectPath,$),Z=new E0(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=O0(this.projectPath,$);await new E0(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=O0(this.projectPath,Z),J=await new E0(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 $=Z6(this.projectPath);await Q2.mkdir($,{recursive:!0});let Y=ZZ.join($,".health-check");return await Q2.writeFile(Y,"test","utf-8"),await Q2.unlink(Y),{isAvailable:!0,canWrite:!0}}catch($){return{isAvailable:!1,canWrite:!1,error:$ instanceof Error?$.message:String($)}}}static async listAllProjects(){return k3()}}var XZ=b(()=>{X6();YZ()});import*as JZ from"crypto";import{nanoid as QZ}from"nanoid";class G6{memory;persistent;cache;compressor;filter;options;currentSessionId=null;initialized=!1;constructor($={}){let Y=$.storage?.persistentPath||f2();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 e9(this.options.storage.maxMemorySize),this.persistent=new Y7(process.cwd(),100),this.cache=new t9(this.options.storage.cacheSize,300000),this.compressor=new s9,this.filter=new p2(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 QZ()}generateMessageId(){return QZ()}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 JZ.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 Z7=b(()=>{XZ();X6()});class X7{chatService;contextManager;memoryAdapter;constructor($,Y){this.chatService=$,this.contextManager=Y||new G6,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+`
1192
1200
 
1193
1201
  `,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}
1194
1202
  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(`
1195
1203
 
1196
- `)}}var rY=R(()=>{u9()});import*as aY from"os";import*as nY from"path";class S1{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 h9,Y={...this.config.permissions,...this.runtimeOptions.permissions},Z=this.runtimeOptions.permissionMode??this.config.permissionMode??"default";return new f9($,{permissionConfig:Y,permissionMode:Z,maxHistorySize:1000})}static async create($={}){if(await I6(),l$().length===0)throw Error(`❌ 没有可用的模型配置
1204
+ `)}}var qZ=b(()=>{Z7()});import*as GZ from"os";import*as KZ from"path";class f1{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 o9,Y={...this.config.permissions,...this.runtimeOptions.permissions},Z=this.runtimeOptions.permissionMode??this.config.permissionMode??"default";return new n9($,{permissionConfig:Y,permissionMode:Z,maxHistorySize:1000})}static async create($={}){if(await P6(),a$().length===0)throw Error(`❌ 没有可用的模型配置
1197
1205
 
1198
1206
  `+`请先使用以下命令添加模型:
1199
1207
  `+` /model add
1200
1208
 
1201
1209
  `+`或运行初始化向导:
1202
- `+" /init");let Z=v1();if(!Z)throw Error("❌ 配置未初始化,请确保应用已正确启动");r1.getInstance().validateConfig(Z);let Q=new S1(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 $=e2();if(!$)throw Error("❌ 当前模型配置未找到");this.log(`\uD83D\uDE80 使用模型: ${$.name} (${$.model})`);let Y=L$($);if(Y)this.log("\uD83E\uDDE0 检测到 Thinking 模型,启用 reasoning_content 支持");this.chatService=T6({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 c9(this.chatService),this.attachmentCollector=new j8({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,U=K.metadata.planContent;E.debug(`\uD83D\uDD04 Plan 模式已批准,切换到 ${W} 模式并重新执行`),await z1().setPermissionMode(W),E.debug(`✅ 权限模式已更新: ${W}`);let H={...Y,permissionMode:W},O=X;if(U){let F=`
1210
+ `+" /init");let Z=v1();if(!Z)throw Error("❌ 配置未初始化,请确保应用已正确启动");n1.getInstance().validateConfig(Z);let Q=new f1(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 $=X$();if(!$)throw Error("❌ 当前模型配置未找到");this.log(`\uD83D\uDE80 使用模型: ${$.name} (${$.model})`);let Y=b$($);if(Y)this.log("\uD83E\uDDE0 检测到 Thinking 模型,启用 reasoning_content 支持");this.chatService=g6({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 m8({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,U=K.metadata.planContent;E.debug(`\uD83D\uDD04 Plan 模式已批准,切换到 ${W} 模式并重新执行`),await F1().setPermissionMode(W),E.debug(`✅ 权限模式已更新: ${W}`);let H={...Y,permissionMode:W},O=X;if(U){let F=`
1203
1211
 
1204
1212
  <approved-plan>
1205
1213
  ${U}
1206
1214
  </approved-plan>
1207
1215
 
1208
1216
  IMPORTANT: Execute according to the approved plan above. Follow the steps exactly as specified.`;if(typeof X==="string")O=X+F;else O=[...X,{type:"text",text:F}];E.debug(`\uD83D\uDCCB 已将 plan 内容注入到消息中 (${U.length} 字符)`)}return this.runLoop(O,H,G).then((F)=>{if(!F.success)throw Error(F.error?.message||"执行失败");return F.finalMessage||""})}return K.finalMessage||""}let Q=typeof X==="string"?X:X.filter((G)=>G.type==="text").map((G)=>G.text).join(`
1209
- `),J={id:this.generateTaskId(),type:"simple",prompt:Q};return(await this.executeTask(J)).content}async runPlanLoop($,Y,Z){E.debug("\uD83D\uDD35 Processing Plan mode message...");let{prompt:X}=await d6({projectPath:process.cwd(),mode:"plan",includeEnvironment:!0}),Q;if(typeof $==="string")Q=s$($);else{let J=$.filter((q)=>q.type==="text");if(J.length>0){let q=J[0];Q=$.map((G)=>G===q?{type:"text",text:s$(q.text)}:G)}else Q=[{type:"text",text:s$("")},...$]}return this.executeLoop(Q,Y,Z,X)}async runLoop($,Y,Z){E.debug("\uD83D\uDCAC Processing enhanced chat message...");let X=m6(),Q=this.systemPrompt?`${X}
1217
+ `),J={id:this.generateTaskId(),type:"simple",prompt:Q};return(await this.executeTask(J)).content}async runPlanLoop($,Y,Z){E.debug("\uD83D\uDD35 Processing Plan mode message...");let{prompt:X}=await n6({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){E.debug("\uD83D\uDCAC Processing enhanced chat message...");let X=a6(),Q=this.systemPrompt?`${X}
1210
1218
 
1211
1219
  ---
1212
1220
 
1213
- ${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=R8(G);let K=this.applySkillToolRestrictions(G);if(q==="plan"){let w=J.getReadOnlyTools();E.debug(`\uD83D\uDD12 Plan mode: 使用只读工具 (${w.length} 个): ${w.map((M)=>M.name).join(", ")}`)}let U=Y.messages.length===0||!Y.messages.some((w)=>w.role==="system"),H=[];if(U&&X)H.push({role:"system",content:X});H.push(...Y.messages,{role:"user",content:$});let O=null;try{let w=this.executionEngine?.getContextManager(),M=typeof $==="string"?$:$.filter((V)=>V.type==="text").map((V)=>V.text).join(`
1214
- `);if(w&&Y.sessionId&&M.trim()!=="")O=await w.saveMessage(Y.sessionId,"user",M);else if(M.trim()==="")E.debug("[Agent] 跳过保存空用户消息")}catch(w){E.warn("[Agent] 保存用户消息失败:",w)}let F=100,N=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)。如需启用,请调整配置:
1221
+ ${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=f8(G);let K=this.applySkillToolRestrictions(G);if(q==="plan"){let A=J.getReadOnlyTools();E.debug(`\uD83D\uDD12 Plan mode: 使用只读工具 (${A.length} 个): ${A.map((D)=>D.name).join(", ")}`)}let U=Y.messages.length===0||!Y.messages.some((A)=>A.role==="system"),H=[];if(U&&X)H.push({role:"system",content:X});H.push(...Y.messages,{role:"user",content:$});let O=null;try{let A=this.executionEngine?.getContextManager(),D=typeof $==="string"?$:$.filter((L)=>L.type==="text").map((L)=>L.text).join(`
1222
+ `);if(A&&Y.sessionId&&D.trim()!=="")O=await A.saveMessage(Y.sessionId,"user",D);else if(D.trim()==="")E.debug("[Agent] 跳过保存空用户消息")}catch(A){E.warn("[Agent] 保存用户消息失败:",A)}let F=100,z=Y.permissionMode==="yolo",_=this.runtimeOptions.maxTurns??Z?.maxTurns??this.config.maxTurns??-1;if(_===0)return{success:!1,error:{type:"chat_disabled",message:`对话功能已被禁用 (maxTurns=0)。如需启用,请调整配置:
1215
1223
  `+` • CLI 参数: blade --max-turns -1
1216
1224
  `+` • 配置文件: ~/.blade/config.json 中设置 "maxTurns": -1
1217
- `+" • 环境变量: export BLADE_MAX_TURNS=-1"},metadata:{turnsCount:0,toolCallsCount:0,duration:0}};let L=z===-1?F:Math.min(z,F);if(this.config.debug)E.debug(`[MaxTurns] runtimeOptions: ${this.runtimeOptions.maxTurns}, options: ${Z?.maxTurns}, config: ${this.config.maxTurns}, 最终: ${z} → ${L}, YOLO: ${N}`);let B=0,_=[],b=0,I;while(!0){if(Z?.signal?.aborted)return{success:!1,error:{type:"aborted",message:"任务已被用户中止"},metadata:{turnsCount:B,toolCallsCount:_.length,duration:Date.now()-Q}};let w=Y.messages.length;if(await this.checkAndCompactInLoop(Y,B,I,Z?.onCompacting)){E.debug(`[Agent] [轮次 ${B}] 检测到压缩发生,重建 messages 数组 (${w} → ${Y.messages.length} 条历史消息)`);let D=U&&X?1:0,y=D+w,k=H.slice(0,D),f=H.slice(y);H.length=0,H.push(...k,...Y.messages,...f),E.debug(`[Agent] [轮次 ${B}] messages 重建完成: ${k.length} system + ${Y.messages.length} 历史 + ${f.length} 新增 = ${H.length} 总计`)}if(B++,E.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}),E.debug(`
1218
- ========== 发送给 LLM ==========`),E.debug("轮次:",B+1),E.debug("消息数量:",H.length),E.debug("最后 3 条消息:"),H.slice(-3).forEach((D,y)=>{if(E.debug(` [${y}] ${D.role}:`,typeof D.content==="string"?D.content.substring(0,100)+(D.content.length>100?"...":""):JSON.stringify(D.content).substring(0,100)),D.tool_calls)E.debug(" tool_calls:",D.tool_calls.map((k)=>("function"in k)?k.function.name:k.type).join(", "))}),E.debug("可用工具数量:",K.length),E.debug(`================================
1219
- `);let V=await this.chatService.chat(H,K,Z?.signal);if(V.usage){if(V.usage.totalTokens)b+=V.usage.totalTokens;if(I=V.usage.promptTokens,E.debug(`[Agent] LLM usage: prompt=${I}, completion=${V.usage.completionTokens}, total=${V.usage.totalTokens}`),Z?.onTokenUsage)Z.onTokenUsage({inputTokens:V.usage.promptTokens??0,outputTokens:V.usage.completionTokens??0,totalTokens:b,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(E.debug(`
1220
- ========== LLM 返回 ==========`),E.debug("Content:",V.content),E.debug("Tool Calls:",JSON.stringify(V.toolCalls,null,2)),E.debug("当前权限模式:",Y.permissionMode),E.debug(`================================
1221
- `),V.reasoningContent&&Z?.onThinking&&!Z.signal?.aborted)Z.onThinking(V.reasoningContent);if(V.content&&V.content.trim()&&Z?.onContent&&!Z.signal?.aborted)Z.onContent(V.content);if(!V.toolCalls||V.toolCalls.length===0){let D=[/:\s*$/,/:\s*$/,/\.\.\.\s*$/,/让我(先|来|开始|查看|检查|修复)/,/Let me (first|start|check|look|fix)/i],y=V.content||"",k=D.some((T)=>T.test(y)),f="请执行你提到的操作,不要只是描述。",A=H.slice(-10).filter((T)=>T.role==="user"&&T.content==="请执行你提到的操作,不要只是描述。").length;if(k&&A<2){E.debug(`⚠️ 检测到意图未完成(重试 ${A+1}/2): "${y.slice(-50)}"`),H.push({role:"user",content:"请执行你提到的操作,不要只是描述。"});continue}E.debug("✅ 任务完成 - LLM 未请求工具调用");try{let T=this.executionEngine?.getContextManager();if(T&&Y.sessionId&&V.content)if(V.content.trim()!=="")O=await T.saveMessage(Y.sessionId,"assistant",V.content,O);else E.debug("[Agent] 跳过保存空响应(任务完成时)")}catch(T){E.warn("[Agent] 保存助手消息失败:",T)}return{success:!0,finalMessage:V.content,metadata:{turnsCount:B,toolCallsCount:_.length,duration:Date.now()-Q,tokensUsed:b}}}H.push({role:"assistant",content:V.content||"",reasoningContent:V.reasoningContent,tool_calls:V.toolCalls});try{let D=this.executionEngine?.getContextManager();if(D&&Y.sessionId&&V.content)if(V.content.trim()!=="")O=await D.saveMessage(Y.sessionId,"assistant",V.content,O);else E.debug("[Agent] 跳过保存空响应(工具调用时)")}catch(D){E.warn("[Agent] 保存助手工具调用消息失败:",D)}for(let D of V.toolCalls){if(D.type!=="function")continue;if(Z?.signal?.aborted)return E.info(`[Agent] Aborting before tool ${D.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 t=this.executionPipeline.getRegistry().get(D.function.name)?.kind;Z.onToolStart(D,t)}let y=JSON.parse(D.function.arguments);if(y.todos&&typeof y.todos==="string")try{y.todos=JSON.parse(y.todos),this.log("[Agent] 自动修复了字符串化的 todos 参数")}catch{this.error("[Agent] todos 参数格式异常,将由验证层处理")}let k=null;try{let r=this.executionEngine?.getContextManager();if(r&&Y.sessionId)k=await r.saveToolUse(Y.sessionId,D.function.name,y,O)}catch(r){E.warn("[Agent] 保存工具调用失败:",r)}let f=Z?.signal;if(!f)E.error("[Agent] Missing signal in tool execution, this should not happen");E.debug("[Agent] Passing confirmationHandler to ExecutionPipeline.execute:",{toolName:D.function.name,hasHandler:!!Y.confirmationHandler,hasMethod:!!Y.confirmationHandler?.requestConfirmation,methodType:typeof Y.confirmationHandler?.requestConfirmation});let A=await this.executionPipeline.execute(D.function.name,y,{sessionId:Y.sessionId,userId:Y.userId||"default",workspaceRoot:Y.workspaceRoot||process.cwd(),signal:f,confirmationHandler:Y.confirmationHandler,permissionMode:Y.permissionMode});if(_.push(A),E.debug(`
1222
- ========== 工具执行结果 ==========`),E.debug("工具名称:",D.function.name),E.debug("成功:",A.success),E.debug("LLM Content:",A.llmContent),E.debug("Display Content:",A.displayContent),A.error)E.debug("错误:",A.error);if(E.debug(`==================================
1223
- `),A.metadata?.shouldExitLoop){E.debug("\uD83D\uDEAA 检测到退出循环标记,结束 Agent 循环");let r=typeof A.llmContent==="string"?A.llmContent:"循环已退出";return{success:A.success,finalMessage:r,metadata:{turnsCount:B,toolCallsCount:_.length,duration:Date.now()-Q,shouldExitLoop:!0,targetMode:A.metadata.targetMode}}}if(Z?.onToolResult&&!Z.signal?.aborted){E.debug("[Agent] Calling onToolResult:",{toolName:D.function.name,hasCallback:!0,resultSuccess:A.success,resultKeys:Object.keys(A),hasMetadata:!!A.metadata,metadataKeys:A.metadata?Object.keys(A.metadata):[],hasSummary:!!A.metadata?.summary,summary:A.metadata?.summary});try{await Z.onToolResult(D,A),E.debug("[Agent] onToolResult callback completed successfully")}catch(r){E.error("[Agent] onToolResult callback error:",r)}}else E.debug("[Agent] No onToolResult callback provided");try{let r=this.executionEngine?.getContextManager();if(r&&Y.sessionId)O=await r.saveToolResult(Y.sessionId,D.id,A.success?A.llmContent:void 0,k,A.success?void 0:A.error?.message)}catch(r){E.warn("[Agent] 保存工具结果失败:",r)}if(D.function.name==="TodoWrite"&&A.success&&A.llmContent){let r=typeof A.llmContent==="object"?A.llmContent:{},t=Array.isArray(r)?r:r.todos||[];R0().setTodos(t)}if(D.function.name==="Skill"&&A.success&&A.metadata){let r=A.metadata;if(r.skillName)this.activeSkillContext={skillName:r.skillName,allowedTools:r.allowedTools,basePath:r.basePath||""},E.debug(`\uD83C\uDFAF Skill "${this.activeSkillContext.skillName}" activated`+(this.activeSkillContext.allowedTools?` with allowed tools: ${this.activeSkillContext.allowedTools.join(", ")}`:""))}let T=A.success?A.llmContent||A.displayContent||"":A.error?.message||"执行失败";if(typeof T==="object"&&T!==null)T=JSON.stringify(T,null,2);let Y1=typeof T==="string"?T:JSON.stringify(T);H.push({role:"tool",tool_call_id:D.id,name:D.function.name,content:Y1})}catch(y){E.error(`Tool execution failed for ${D.function.name}:`,y),H.push({role:"tool",tool_call_id:D.id,name:D.function.name,content:`Execution failed: ${y instanceof Error?y.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&&!N){if(E.info(`⚠️ 达到轮次上限 ${L} 轮,等待用户确认...`),Z?.onTurnLimitReached){let D=await Z.onTurnLimitReached({turnsCount:B});if(D?.continue){E.info("✅ 用户选择继续,压缩上下文...");try{let y=this.chatService.getConfig(),k=await X$.compact(Y.messages,{trigger:"auto",modelName:y.model,maxContextTokens:y.maxContextTokens??this.config.maxContextTokens,apiKey:y.apiKey,baseURL:y.baseUrl,actualPreTokens:I});Y.messages=k.compactedMessages;let f=H.find((T)=>T.role==="system");if(H.length=0,f)H.push(f);H.push(...Y.messages);let A={role:"user",content:`This session is being continued from a previous conversation. The conversation is summarized above.
1224
-
1225
- 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.`};H.push(A),Y.messages.push(A);try{let T=this.executionEngine?.getContextManager();if(T&&Y.sessionId)await T.saveCompaction(Y.sessionId,k.summary,{trigger:"auto",preTokens:k.preTokens,postTokens:k.postTokens,filesIncluded:k.filesIncluded},null)}catch(T){E.warn("[Agent] 保存压缩数据失败:",T)}E.info(`✅ 上下文已压缩 (${k.preTokens} → ${k.postTokens} tokens),重置轮次计数`)}catch(y){E.error("[Agent] 压缩失败,使用降级策略:",y);let k=H.find((A)=>A.role==="system"),f=H.slice(-80);if(H.length=0,k&&!f.some((A)=>A.role==="system"))H.push(k);H.push(...f),Y.messages=H.filter((A)=>A.role!=="system"),E.warn(`⚠️ 降级压缩完成,保留 ${H.length} 条消息`)}B=0;continue}return{success:!0,finalMessage:D?.reason||"已达到对话轮次上限,用户选择停止",metadata:{turnsCount:B,toolCallsCount:_.length,duration:Date.now()-Q,tokensUsed:b}}}return{success:!1,error:{type:"max_turns_exceeded",message:`已达到轮次上限 (${L} 轮)。使用 --permission-mode yolo 跳过此限制。`},metadata:{turnsCount:B,toolCallsCount:_.length,duration:Date.now()-Q,tokensUsed:b}}}}}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 E.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);E.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){E.debug(`[MainAgent] ${$}`,Y||"")}error($,Y){E.error(`[MainAgent] ${$}`,Y||"")}async initializeSystemPrompt(){try{let $=this.runtimeOptions.systemPrompt,Y=this.runtimeOptions.appendSystemPrompt,Z=await d6({projectPath:process.cwd(),replaceDefault:$,append:Y,includeEnvironment:!1});if(this.systemPrompt=Z.prompt,this.systemPrompt)this.log("系统提示已加载"),E.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 E.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(E.debug(`[Agent] [轮次 ${Y}] 压缩检查:`,{promptTokens:Z,maxContextTokens:q,maxOutputTokens:G,availableForInput:K,threshold:W,shouldCompact:Z>=W}),Z<W)return!1;let U=Y===0?"[Agent] 触发自动压缩":`[Agent] [轮次 ${Y}] 触发循环内自动压缩`;E.debug(U),X?.(!0);try{let H=await X$.compact($.messages,{trigger:"auto",modelName:J,maxContextTokens:q,apiKey:Q.apiKey,baseURL:Q.baseUrl,actualPreTokens:Z});if(H.success)$.messages=H.compactedMessages,E.debug(`[Agent] [轮次 ${Y}] 压缩完成: ${H.preTokens} → ${H.postTokens} tokens (-${((1-H.postTokens/H.preTokens)*100).toFixed(1)}%)`);else $.messages=H.compactedMessages,E.warn(`[Agent] [轮次 ${Y}] 压缩使用降级策略: ${H.preTokens} → ${H.postTokens} tokens`);try{let O=this.executionEngine?.getContextManager();if(O&&$.sessionId)await O.saveCompaction($.sessionId,H.summary,{trigger:"auto",preTokens:H.preTokens,postTokens:H.postTokens,filesIncluded:H.filesIncluded},null),E.debug(`[Agent] [轮次 ${Y}] 压缩数据已保存到 JSONL`)}catch(O){E.warn(`[Agent] [轮次 ${Y}] 保存压缩数据失败:`,O)}return X?.(!1),!0}catch(H){return X?.(!1),E.error(`[Agent] [轮次 ${Y}] 压缩失败,继续执行`,H),!1}}async registerBuiltinTools(){try{let $=await DY({sessionId:"default",configDir:nY.join(aY.homedir(),".blade")});E.debug(`\uD83D\uDCE6 Registering ${$.length} builtin tools...`),this.executionPipeline.getRegistry().registerAll($);let Y=this.executionPipeline.getRegistry().getAll().length;E.debug(`✅ Builtin tools registered: ${Y} tools`),E.debug(`[Tools] ${this.executionPipeline.getRegistry().getAll().map((Z)=>Z.name).join(", ")}`),await this.registerMcpTools()}catch($){throw E.error("Failed to register builtin tools:",$),$}}async registerMcpTools(){try{if(this.runtimeOptions.mcpConfig&&this.runtimeOptions.mcpConfig.length>0)await u5(this.runtimeOptions.mcpConfig);let $=K0();if(Object.keys($).length===0){E.debug("\uD83D\uDCE6 No MCP servers configured");return}let Y=p1.getInstance();for(let[X,Q]of Object.entries($))try{E.debug(`\uD83D\uDD0C Connecting to MCP server: ${X}`),await Y.registerServer(X,Q),E.debug(`✅ MCP server "${X}" connected`)}catch(J){E.warn(`⚠️ MCP server "${X}" connection failed:`,J)}let Z=await Y.getAvailableTools();if(Z.length>0)this.executionPipeline.getRegistry().registerAll(Z),E.debug(`✅ Registered ${Z.length} MCP tools`),E.debug(`[MCP Tools] ${Z.map((X)=>X.name).join(", ")}`)}catch($){E.warn("Failed to register MCP tools:",$)}}async loadSubagents(){if(E1.getAllNames().length>0){E.debug(`\uD83D\uDCE6 Subagents already loaded: ${E1.getAllNames().join(", ")}`);return}try{let $=E1.loadFromStandardLocations();if($>0)E.debug(`✅ Loaded ${$} subagents: ${E1.getAllNames().join(", ")}`);else E.debug("\uD83D\uDCE6 No subagents configured")}catch($){E.warn("Failed to load subagents:",$)}}async discoverSkills(){try{let $=await y2({cwd:process.cwd()});if($.skills.length>0)E.debug(`✅ Discovered ${$.skills.length} skills: ${$.skills.map((Y)=>Y.name).join(", ")}`);else E.debug("\uD83D\uDCE6 No skills configured");for(let Y of $.errors)E.warn(`⚠️ Skill loading error at ${Y.path}: ${Y.error}`)}catch($){E.warn("Failed to discover skills:",$)}}applySkillToolRestrictions($){if(!this.activeSkillContext?.allowedTools)return $;let Y=this.activeSkillContext.allowedTools;E.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 E.debug(`\uD83D\uDD12 Filtered tools: ${Z.map((X)=>X.name).join(", ")} (${Z.length}/${$.length})`),Z}clearSkillContext(){if(this.activeSkillContext)E.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(`
1225
+ `+" • 环境变量: export BLADE_MAX_TURNS=-1"},metadata:{turnsCount:0,toolCallsCount:0,duration:0}};let w=_===-1?F:Math.min(_,F);if(this.config.debug)E.debug(`[MaxTurns] runtimeOptions: ${this.runtimeOptions.maxTurns}, options: ${Z?.maxTurns}, config: ${this.config.maxTurns}, 最终: ${_} → ${w}, YOLO: ${z}`);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)){E.debug(`[Agent] [轮次 ${B}] 检测到压缩发生,重建 messages 数组 (${A} → ${Y.messages.length} 条历史消息)`);let V=U&&X?1:0,v=V+A,k=H.slice(0,V),f=H.slice(v);H.length=0,H.push(...k,...Y.messages,...f),E.debug(`[Agent] [轮次 ${B}] messages 重建完成: ${k.length} system + ${Y.messages.length} 历史 + ${f.length} 新增 = ${H.length} 总计`)}if(B++,E.debug(`\uD83D\uDD04 [轮次 ${B}/${w}] 调用 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:w}),E.debug(`
1226
+ ========== 发送给 LLM ==========`),E.debug("轮次:",B+1),E.debug("消息数量:",H.length),E.debug("最后 3 条消息:"),H.slice(-3).forEach((V,v)=>{if(E.debug(` [${v}] ${V.role}:`,typeof V.content==="string"?V.content.substring(0,100)+(V.content.length>100?"...":""):JSON.stringify(V.content).substring(0,100)),V.tool_calls)E.debug(" tool_calls:",V.tool_calls.map((k)=>("function"in k)?k.function.name:k.type).join(", "))}),E.debug("可用工具数量:",K.length),E.debug(`================================
1227
+ `);let L=await this.chatService.chat(H,K,Z?.signal);if(L.usage){if(L.usage.totalTokens)I+=L.usage.totalTokens;if(M=L.usage.promptTokens,E.debug(`[Agent] LLM usage: prompt=${M}, completion=${L.usage.completionTokens}, total=${L.usage.totalTokens}`),Z?.onTokenUsage)Z.onTokenUsage({inputTokens:L.usage.promptTokens??0,outputTokens:L.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(E.debug(`
1228
+ ========== LLM 返回 ==========`),E.debug("Content:",L.content),E.debug("Tool Calls:",JSON.stringify(L.toolCalls,null,2)),E.debug("当前权限模式:",Y.permissionMode),E.debug(`================================
1229
+ `),L.reasoningContent&&Z?.onThinking&&!Z.signal?.aborted)Z.onThinking(L.reasoningContent);if(L.content&&L.content.trim()&&Z?.onContent&&!Z.signal?.aborted)Z.onContent(L.content);if(!L.toolCalls||L.toolCalls.length===0){let V=[/:\s*$/,/:\s*$/,/\.\.\.\s*$/,/让我(先|来|开始|查看|检查|修复)/,/Let me (first|start|check|look|fix)/i],v=L.content||"",k=V.some((T)=>T.test(v)),f="请执行你提到的操作,不要只是描述。",R=H.slice(-10).filter((T)=>T.role==="user"&&T.content==="请执行你提到的操作,不要只是描述。").length;if(k&&R<2){E.debug(`⚠️ 检测到意图未完成(重试 ${R+1}/2): "${v.slice(-50)}"`),H.push({role:"user",content:"请执行你提到的操作,不要只是描述。"});continue}E.debug("✅ 任务完成 - LLM 未请求工具调用");try{let T=this.executionEngine?.getContextManager();if(T&&Y.sessionId&&L.content)if(L.content.trim()!=="")O=await T.saveMessage(Y.sessionId,"assistant",L.content,O);else E.debug("[Agent] 跳过保存空响应(任务完成时)")}catch(T){E.warn("[Agent] 保存助手消息失败:",T)}return{success:!0,finalMessage:L.content,metadata:{turnsCount:B,toolCallsCount:N.length,duration:Date.now()-Q,tokensUsed:I}}}H.push({role:"assistant",content:L.content||"",reasoningContent:L.reasoningContent,tool_calls:L.toolCalls});try{let V=this.executionEngine?.getContextManager();if(V&&Y.sessionId&&L.content)if(L.content.trim()!=="")O=await V.saveMessage(Y.sessionId,"assistant",L.content,O);else E.debug("[Agent] 跳过保存空响应(工具调用时)")}catch(V){E.warn("[Agent] 保存助手工具调用消息失败:",V)}for(let V of L.toolCalls){if(V.type!=="function")continue;if(Z?.signal?.aborted)return E.info(`[Agent] Aborting before tool ${V.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 t=this.executionPipeline.getRegistry().get(V.function.name)?.kind;Z.onToolStart(V,t)}let v=JSON.parse(V.function.arguments);if(v.todos&&typeof v.todos==="string")try{v.todos=JSON.parse(v.todos),this.log("[Agent] 自动修复了字符串化的 todos 参数")}catch{this.error("[Agent] todos 参数格式异常,将由验证层处理")}let k=null;try{let r=this.executionEngine?.getContextManager();if(r&&Y.sessionId)k=await r.saveToolUse(Y.sessionId,V.function.name,v,O)}catch(r){E.warn("[Agent] 保存工具调用失败:",r)}let f=Z?.signal;if(!f)E.error("[Agent] Missing signal in tool execution, this should not happen");E.debug("[Agent] Passing confirmationHandler to ExecutionPipeline.execute:",{toolName:V.function.name,hasHandler:!!Y.confirmationHandler,hasMethod:!!Y.confirmationHandler?.requestConfirmation,methodType:typeof Y.confirmationHandler?.requestConfirmation});let R=await this.executionPipeline.execute(V.function.name,v,{sessionId:Y.sessionId,userId:Y.userId||"default",workspaceRoot:Y.workspaceRoot||process.cwd(),signal:f,confirmationHandler:Y.confirmationHandler,permissionMode:Y.permissionMode});if(N.push(R),E.debug(`
1230
+ ========== 工具执行结果 ==========`),E.debug("工具名称:",V.function.name),E.debug("成功:",R.success),E.debug("LLM Content:",R.llmContent),E.debug("Display Content:",R.displayContent),R.error)E.debug("错误:",R.error);if(E.debug(`==================================
1231
+ `),R.metadata?.shouldExitLoop){E.debug("\uD83D\uDEAA 检测到退出循环标记,结束 Agent 循环");let r=typeof R.llmContent==="string"?R.llmContent:"循环已退出";return{success:R.success,finalMessage:r,metadata:{turnsCount:B,toolCallsCount:N.length,duration:Date.now()-Q,shouldExitLoop:!0,targetMode:R.metadata.targetMode}}}if(Z?.onToolResult&&!Z.signal?.aborted){E.debug("[Agent] Calling onToolResult:",{toolName:V.function.name,hasCallback:!0,resultSuccess:R.success,resultKeys:Object.keys(R),hasMetadata:!!R.metadata,metadataKeys:R.metadata?Object.keys(R.metadata):[],hasSummary:!!R.metadata?.summary,summary:R.metadata?.summary});try{await Z.onToolResult(V,R),E.debug("[Agent] onToolResult callback completed successfully")}catch(r){E.error("[Agent] onToolResult callback error:",r)}}else E.debug("[Agent] No onToolResult callback provided");try{let r=this.executionEngine?.getContextManager();if(r&&Y.sessionId)O=await r.saveToolResult(Y.sessionId,V.id,R.success?R.llmContent:void 0,k,R.success?void 0:R.error?.message)}catch(r){E.warn("[Agent] 保存工具结果失败:",r)}if(V.function.name==="TodoWrite"&&R.success&&R.llmContent){let r=typeof R.llmContent==="object"?R.llmContent:{},t=Array.isArray(r)?r:r.todos||[];M0().setTodos(t)}if(V.function.name==="Skill"&&R.success&&R.metadata){let r=R.metadata;if(r.skillName)this.activeSkillContext={skillName:r.skillName,allowedTools:r.allowedTools,basePath:r.basePath||""},E.debug(`\uD83C\uDFAF Skill "${this.activeSkillContext.skillName}" activated`+(this.activeSkillContext.allowedTools?` with allowed tools: ${this.activeSkillContext.allowedTools.join(", ")}`:""))}let T=R.success?R.llmContent||R.displayContent||"":R.error?.message||"执行失败";if(typeof T==="object"&&T!==null)T=JSON.stringify(T,null,2);let Y1=typeof T==="string"?T:JSON.stringify(T);H.push({role:"tool",tool_call_id:V.id,name:V.function.name,content:Y1})}catch(v){E.error(`Tool execution failed for ${V.function.name}:`,v),H.push({role:"tool",tool_call_id:V.id,name:V.function.name,content:`Execution failed: ${v instanceof Error?v.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>=w&&!z){if(E.info(`⚠️ 达到轮次上限 ${w} 轮,等待用户确认...`),Z?.onTurnLimitReached){let V=await Z.onTurnLimitReached({turnsCount:B});if(V?.continue){E.info("✅ 用户选择继续,压缩上下文...");try{let v=this.chatService.getConfig(),k=await G$.compact(Y.messages,{trigger:"auto",modelName:v.model,maxContextTokens:v.maxContextTokens??this.config.maxContextTokens,apiKey:v.apiKey,baseURL:v.baseUrl,actualPreTokens:M});Y.messages=k.compactedMessages;let f=H.find((T)=>T.role==="system");if(H.length=0,f)H.push(f);H.push(...Y.messages);let R={role:"user",content:`This session is being continued from a previous conversation. The conversation is summarized above.
1232
+
1233
+ 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.`};H.push(R),Y.messages.push(R);try{let T=this.executionEngine?.getContextManager();if(T&&Y.sessionId)await T.saveCompaction(Y.sessionId,k.summary,{trigger:"auto",preTokens:k.preTokens,postTokens:k.postTokens,filesIncluded:k.filesIncluded},null)}catch(T){E.warn("[Agent] 保存压缩数据失败:",T)}E.info(`✅ 上下文已压缩 (${k.preTokens} → ${k.postTokens} tokens),重置轮次计数`)}catch(v){E.error("[Agent] 压缩失败,使用降级策略:",v);let k=H.find((R)=>R.role==="system"),f=H.slice(-80);if(H.length=0,k&&!f.some((R)=>R.role==="system"))H.push(k);H.push(...f),Y.messages=H.filter((R)=>R.role!=="system"),E.warn(`⚠️ 降级压缩完成,保留 ${H.length} 条消息`)}B=0;continue}return{success:!0,finalMessage:V?.reason||"已达到对话轮次上限,用户选择停止",metadata:{turnsCount:B,toolCallsCount:N.length,duration:Date.now()-Q,tokensUsed:I}}}return{success:!1,error:{type:"max_turns_exceeded",message:`已达到轮次上限 (${w} 轮)。使用 --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 E.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);E.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){E.debug(`[MainAgent] ${$}`,Y||"")}error($,Y){E.error(`[MainAgent] ${$}`,Y||"")}async initializeSystemPrompt(){try{let $=this.runtimeOptions.systemPrompt,Y=this.runtimeOptions.appendSystemPrompt,Z=await n6({projectPath:process.cwd(),replaceDefault:$,append:Y,includeEnvironment:!1});if(this.systemPrompt=Z.prompt,this.systemPrompt)this.log("系统提示已加载"),E.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 E.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(E.debug(`[Agent] [轮次 ${Y}] 压缩检查:`,{promptTokens:Z,maxContextTokens:q,maxOutputTokens:G,availableForInput:K,threshold:W,shouldCompact:Z>=W}),Z<W)return!1;let U=Y===0?"[Agent] 触发自动压缩":`[Agent] [轮次 ${Y}] 触发循环内自动压缩`;E.debug(U),X?.(!0);try{let H=await G$.compact($.messages,{trigger:"auto",modelName:J,maxContextTokens:q,apiKey:Q.apiKey,baseURL:Q.baseUrl,actualPreTokens:Z});if(H.success)$.messages=H.compactedMessages,E.debug(`[Agent] [轮次 ${Y}] 压缩完成: ${H.preTokens} → ${H.postTokens} tokens (-${((1-H.postTokens/H.preTokens)*100).toFixed(1)}%)`);else $.messages=H.compactedMessages,E.warn(`[Agent] [轮次 ${Y}] 压缩使用降级策略: ${H.preTokens} → ${H.postTokens} tokens`);try{let O=this.executionEngine?.getContextManager();if(O&&$.sessionId)await O.saveCompaction($.sessionId,H.summary,{trigger:"auto",preTokens:H.preTokens,postTokens:H.postTokens,filesIncluded:H.filesIncluded},null),E.debug(`[Agent] [轮次 ${Y}] 压缩数据已保存到 JSONL`)}catch(O){E.warn(`[Agent] [轮次 ${Y}] 保存压缩数据失败:`,O)}return X?.(!1),!0}catch(H){return X?.(!1),E.error(`[Agent] [轮次 ${Y}] 压缩失败,继续执行`,H),!1}}async registerBuiltinTools(){try{let $=await hY({sessionId:"default",configDir:KZ.join(GZ.homedir(),".blade")});E.debug(`\uD83D\uDCE6 Registering ${$.length} builtin tools...`),this.executionPipeline.getRegistry().registerAll($);let Y=this.executionPipeline.getRegistry().getAll().length;E.debug(`✅ Builtin tools registered: ${Y} tools`),E.debug(`[Tools] ${this.executionPipeline.getRegistry().getAll().map((Z)=>Z.name).join(", ")}`),await this.registerMcpTools()}catch($){throw E.error("Failed to register builtin tools:",$),$}}async registerMcpTools(){try{if(this.runtimeOptions.mcpConfig&&this.runtimeOptions.mcpConfig.length>0)await Z3(this.runtimeOptions.mcpConfig);let $=U0();if(Object.keys($).length===0){E.debug("\uD83D\uDCE6 No MCP servers configured");return}let Y=g1.getInstance();for(let[X,Q]of Object.entries($))try{E.debug(`\uD83D\uDD0C Connecting to MCP server: ${X}`),await Y.registerServer(X,Q),E.debug(`✅ MCP server "${X}" connected`)}catch(J){E.warn(`⚠️ MCP server "${X}" connection failed:`,J)}let Z=await Y.getAvailableTools();if(Z.length>0)this.executionPipeline.getRegistry().registerAll(Z),E.debug(`✅ Registered ${Z.length} MCP tools`),E.debug(`[MCP Tools] ${Z.map((X)=>X.name).join(", ")}`)}catch($){E.warn("Failed to register MCP tools:",$)}}async loadSubagents(){if(k1.getAllNames().length>0){E.debug(`\uD83D\uDCE6 Subagents already loaded: ${k1.getAllNames().join(", ")}`);return}try{let $=k1.loadFromStandardLocations();if($>0)E.debug(`✅ Loaded ${$} subagents: ${k1.getAllNames().join(", ")}`);else E.debug("\uD83D\uDCE6 No subagents configured")}catch($){E.warn("Failed to load subagents:",$)}}async discoverSkills(){try{let $=await T2({cwd:process.cwd()});if($.skills.length>0)E.debug(`✅ Discovered ${$.skills.length} skills: ${$.skills.map((Y)=>Y.name).join(", ")}`);else E.debug("\uD83D\uDCE6 No skills configured");for(let Y of $.errors)E.warn(`⚠️ Skill loading error at ${Y.path}: ${Y.error}`)}catch($){E.warn("Failed to discover skills:",$)}}applySkillToolRestrictions($){if(!this.activeSkillContext?.allowedTools)return $;let Y=this.activeSkillContext.allowedTools;E.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 E.debug(`\uD83D\uDD12 Filtered tools: ${Z.map((X)=>X.name).join(", ")} (${Z.length}/${$.length})`),Z}clearSkillContext(){if(this.activeSkillContext)E.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(`
1226
1234
  `);try{let X=await this.attachmentCollector.collect(Z);if(X.length===0)return $;E.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 E.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+=`
1227
1235
 
1228
1236
  <system-reminder>
@@ -1245,16 +1253,16 @@ Please continue the conversation from where we left it off without asking the us
1245
1253
 
1246
1254
  ⚠️ Some files could not be loaded:
1247
1255
  `,Q+=X.join(`
1248
- `);return Q}}var E;var z2=R(()=>{s2();_8();A1();c5();Y$();$3();q3();z8();_1();IY();gY();mY();V8();q4();rY();z$();K2();E=i("Agent")});import{readdir as KZ,readFile as WZ}from"node:fs/promises";import*as K4 from"node:path";class g0{static async listSessions(){let $=[],Y=K4.join(O2(),"projects");try{let Z=await KZ(Y,{withFileTypes:!0});for(let X of Z){if(!X.isDirectory())continue;let Q=K4.join(Y,X.name),J=S8(X.name),G=(await KZ(Q)).filter((K)=>K.endsWith(".jsonl"));for(let K of G){let W=K4.join(Q,K),U=K.replace(".jsonl","");try{let H=await this.extractMetadata(W,U,J);$.push(H)}catch(H){x2.warn(`[SessionService] 跳过损坏的会话文件: ${W}`,H)}}}return $.sort((X,Q)=>new Date(Q.lastMessageTime).getTime()-new Date(X.lastMessageTime).getTime()),$}catch(Z){return x2.error("[SessionService] 列出会话失败:",Z),[]}}static async extractMetadata($,Y,Z){let Q=(await WZ($,"utf-8")).trim().split(`
1249
- `).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 x2.error(`[SessionService] 加载会话失败 (${$}):`,Z),Z}}static async loadSessionFromFile($){let X=(await WZ($,"utf-8")).trim().split(`
1250
- `).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,x2.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"){x2.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)x2.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)x2.debug(`[SessionService] 会话已压缩,跳过前 ${Z} 条历史,加载 ${Y.length} 条消息`);return Y}static getSessionFilePath($,Y){let{getSessionFilePath:Z}=(H$(),qJ(L3));return Z($,Y)}}var x2;var W4=R(()=>{H$();A1();x2=i("Service")});function V1($){if($.acp)return{sendMessage:(Y)=>$.acp.sendMessage(`• ${Y}
1256
+ `);return Q}}var E;var w2=b(()=>{Y$();V8();B1();X3();J$();F3();L3();R8();z1();xY();eY();$Z();h8();F4();qZ();B$();F2();E=c("Agent")});import{readdir as RZ,readFile as VZ}from"node:fs/promises";import*as _4 from"node:path";class l0{static async listSessions(){let $=[],Y=_4.join(f2(),"projects");try{let Z=await RZ(Y,{withFileTypes:!0});for(let X of Z){if(!X.isDirectory())continue;let Q=_4.join(Y,X.name),J=E3(X.name),G=(await RZ(Q)).filter((K)=>K.endsWith(".jsonl"));for(let K of G){let W=_4.join(Q,K),U=K.replace(".jsonl","");try{let H=await this.extractMetadata(W,U,J);$.push(H)}catch(H){d2.warn(`[SessionService] 跳过损坏的会话文件: ${W}`,H)}}}return $.sort((X,Q)=>new Date(Q.lastMessageTime).getTime()-new Date(X.lastMessageTime).getTime()),$}catch(Z){return d2.error("[SessionService] 列出会话失败:",Z),[]}}static async extractMetadata($,Y,Z){let Q=(await VZ($,"utf-8")).trim().split(`
1257
+ `).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 d2.error(`[SessionService] 加载会话失败 (${$}):`,Z),Z}}static async loadSessionFromFile($){let X=(await VZ($,"utf-8")).trim().split(`
1258
+ `).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,d2.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"){d2.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)d2.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)d2.debug(`[SessionService] 会话已压缩,跳过前 ${Z} 条历史,加载 ${Y.length} 条消息`);return Y}static getSessionFilePath($,Y){return O0($,Y)}}var d2;var N4=b(()=>{X6();B1();d2=c("Service")});function D1($){if($.acp)return{sendMessage:(Y)=>$.acp.sendMessage(`• ${Y}
1251
1259
 
1252
- `),sendToolStart:$.acp.sendToolStart,sendToolResult:$.acp.sendToolResult};return{sendMessage:(Y)=>v2().addAssistantMessage(Y),sendToolStart:void 0,sendToolResult:void 0}}var w2=R(()=>{_1()});import pK from"node:os";import kZ from"node:path";var PZ;var TZ=R(()=>{z$();w2();PZ={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=V1(Y);if(!Z)return{success:!0,message:"show_agents_manager",data:{action:"show_agents_manager"}};if(Z==="list"){let J=E1.getAllNames().map((H)=>E1.getSubagent(H)).filter((H)=>H!==void 0);if(J.length===0){let H=`\uD83D\uDCCB **Agents 管理**
1260
+ `),sendToolStart:$.acp.sendToolStart,sendToolResult:$.acp.sendToolResult};return{sendMessage:(Y)=>P2().addAssistantMessage(Y),sendToolStart:void 0,sendToolResult:void 0}}var V2=b(()=>{z1()});import wW from"node:os";import lZ from"node:path";var iZ;var rZ=b(()=>{B$();V2();iZ={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=D1(Y);if(!Z)return{success:!0,message:"show_agents_manager",data:{action:"show_agents_manager"}};if(Z==="list"){let J=k1.getAllNames().map((H)=>k1.getSubagent(H)).filter((H)=>H!==void 0);if(J.length===0){let H=`\uD83D\uDCCB **Agents 管理**
1253
1261
 
1254
1262
  `+`❌ 没有找到任何 agent 配置
1255
1263
 
1256
1264
  `+`**配置文件位置:**
1257
- `+"- 项目级: `.blade/agents/`\n"+"- 用户级: `~/.blade/agents/`\n\n"+"\uD83D\uDCA1 使用 `/agents` 打开管理对话框";return X.sendMessage(H),{success:!0,message:"No agents found"}}let q=kZ.join(process.cwd(),".blade","agents"),G=kZ.join(pK.homedir(),".blade","agents"),K=J.filter((H)=>H.configPath?.startsWith(q)),W=J.filter((H)=>H.configPath?.startsWith(G)),U=`\uD83D\uDCCB **Agents 管理**
1265
+ `+"- 项目级: `.blade/agents/`\n"+"- 用户级: `~/.blade/agents/`\n\n"+"\uD83D\uDCA1 使用 `/agents` 打开管理对话框";return X.sendMessage(H),{success:!0,message:"No agents found"}}let q=lZ.join(process.cwd(),".blade","agents"),G=lZ.join(wW.homedir(),".blade","agents"),K=J.filter((H)=>H.configPath?.startsWith(q)),W=J.filter((H)=>H.configPath?.startsWith(G)),U=`\uD83D\uDCCB **Agents 管理**
1258
1266
 
1259
1267
  找到 **${J.length}** 个 agent:
1260
1268
 
@@ -1294,20 +1302,20 @@ Please continue the conversation from where we left it off without asking the us
1294
1302
  `+"- 项目级 (`.blade/agents/`) - 最高优先级\n"+"- 用户级 (`~/.blade/agents/`) - 较低优先级\n\n"+`**可用工具:**
1295
1303
  `+"- `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}\`
1296
1304
 
1297
- `+"使用 `/agents help` 查看可用命令";return X.sendMessage(Q),{success:!1,error:`Unknown subcommand: ${Z}`}}}});async function gK($,Y){let Z=V1(Y);try{let X=v1(),Q=e2();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((F)=>({role:F.role,content:F.content})),W=t0.countTokens(K,Q.model),U=Q.maxContextTokens??X.maxContextTokens,H=(W/U*100).toFixed(1);if(Z.sendMessage(`\uD83D\uDCCA **当前上下文统计**
1305
+ `+"使用 `/agents help` 查看可用命令";return X.sendMessage(Q),{success:!1,error:`Unknown subcommand: ${Z}`}}}});async function LW($,Y){let Z=D1(Y);try{let X=v1(),Q=X$();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((F)=>({role:F.role,content:F.content})),W=Z2.countTokens(K,Q.model),U=Q.maxContextTokens??X.maxContextTokens,H=(W/U*100).toFixed(1);if(Z.sendMessage(`\uD83D\uDCCA **当前上下文统计**
1298
1306
  • 消息数量: ${K.length}
1299
1307
  • Token 数量: ${W.toLocaleString()}
1300
1308
  • Token 限制: ${U.toLocaleString()}
1301
1309
  • 使用率: ${H}%`),W<U*0.5)return Z.sendMessage(`\uD83D\uDCA1 提示: 当前 token 使用率较低(${H}%),可以暂时不压缩。
1302
- 系统会在达到 80% 时自动触发压缩。`),{success:!0,message:"无需压缩"};Z.sendMessage("⏳ **正在压缩上下文...**");let O=await X$.compact(K,{trigger:"manual",modelName:Q.model,maxContextTokens:U,apiKey:Q.apiKey,baseURL:Q.baseUrl});if(O.success){try{if(G)await new Z6().saveCompaction(G,O.summary,{trigger:"manual",preTokens:O.preTokens,postTokens:O.postTokens,filesIncluded:O.filesIncluded},null),console.log("[/compact] 压缩数据已保存到 JSONL")}catch(N){console.warn("[/compact] 保存压缩数据失败:",N)}let F=`✅ **压缩完成!**
1310
+ 系统会在达到 80% 时自动触发压缩。`),{success:!0,message:"无需压缩"};Z.sendMessage("⏳ **正在压缩上下文...**");let O=await G$.compact(K,{trigger:"manual",modelName:Q.model,maxContextTokens:U,apiKey:Q.apiKey,baseURL:Q.baseUrl});if(O.success){try{if(G)await new G6().saveCompaction(G,O.summary,{trigger:"manual",preTokens:O.preTokens,postTokens:O.postTokens,filesIncluded:O.filesIncluded},null),console.log("[/compact] 压缩数据已保存到 JSONL")}catch(z){console.warn("[/compact] 保存压缩数据失败:",z)}let F=`✅ **压缩完成!**
1303
1311
 
1304
1312
  \uD83D\uDCC9 **Token 变化**
1305
1313
  • 压缩前: ${O.preTokens.toLocaleString()} tokens
1306
1314
  • 压缩后: ${O.postTokens.toLocaleString()} tokens
1307
1315
  • 压缩率: ${((1-O.postTokens/O.preTokens)*100).toFixed(1)}%`;if(O.filesIncluded.length>0)F+=`
1308
1316
 
1309
- \uD83D\uDCC1 **包含文件** (${O.filesIncluded.length})`,O.filesIncluded.forEach((N,z)=>{F+=`
1310
- ${z+1}. ${N}`});return F+=`
1317
+ \uD83D\uDCC1 **包含文件** (${O.filesIncluded.length})`,O.filesIncluded.forEach((z,_)=>{F+=`
1318
+ ${_+1}. ${z}`});return F+=`
1311
1319
 
1312
1320
  \uD83D\uDCA1 对话历史已压缩,但完整记录仍保存在会话文件中。`,Z.sendMessage(F),{success:!0,message:"compact_completed",data:{compactedMessages:O.compactedMessages,boundaryMessage:O.boundaryMessage,summaryMessage:O.summaryMessage,preTokens:O.preTokens,postTokens:O.postTokens,filesIncluded:O.filesIncluded}}}else return Z.sendMessage(`⚠️ **压缩使用降级策略**
1313
1321
 
@@ -1316,32 +1324,32 @@ Please continue the conversation from where we left it off without asking the us
1316
1324
  • 压缩后: ${O.postTokens.toLocaleString()} tokens
1317
1325
 
1318
1326
  \uD83D\uDCA1 由于压缩过程出现错误,已使用简单截断策略。
1319
- 错误信息: ${O.error}`),{success:!1,message:"compact_fallback",error:O.error,data:{compactedMessages:O.compactedMessages,boundaryMessage:O.boundaryMessage,summaryMessage:O.summaryMessage,preTokens:O.preTokens,postTokens:O.postTokens}}}catch(X){let Q=X instanceof Error?X.message:String(X);return Z.sendMessage(`❌ **压缩失败**: ${Q}`),{success:!1,error:Q}}}var mK,SZ;var CZ=R(()=>{_8();u9();C6();_1();w2();mK={name:"compact",description:"手动压缩当前会话的上下文",fullDescription:"压缩当前对话历史,生成详细的技术总结,保留最近的消息。压缩后的上下文可以节省 token 使用量,同时保留关键信息。",usage:"/compact",examples:["/compact"],category:"context",handler:gK},SZ=mK});function hZ($){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 dK($){let Y=p1.getInstance(),Z=K0();if(Object.keys(Z).length===0){$.sendMessage(`\uD83D\uDD0C **MCP 服务器状态**
1327
+ 错误信息: ${O.error}`),{success:!1,message:"compact_fallback",error:O.error,data:{compactedMessages:O.compactedMessages,boundaryMessage:O.boundaryMessage,summaryMessage:O.summaryMessage,preTokens:O.preTokens,postTokens:O.postTokens}}}catch(X){let Q=X instanceof Error?X.message:String(X);return Z.sendMessage(`❌ **压缩失败**: ${Q}`),{success:!1,error:Q}}}var AW,aZ;var nZ=b(()=>{V8();Z7();d6();z1();V2();AW={name:"compact",description:"手动压缩当前会话的上下文",fullDescription:"压缩当前对话历史,生成详细的技术总结,保留最近的消息。压缩后的上下文可以节省 token 使用量,同时保留关键信息。",usage:"/compact",examples:["/compact"],category:"context",handler:LW},aZ=AW});function sZ($){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 bW($){let Y=g1.getInstance(),Z=U0();if(Object.keys(Z).length===0){$.sendMessage(`\uD83D\uDD0C **MCP 服务器状态**
1320
1328
 
1321
1329
  ⚠️ 暂无配置的 MCP 服务器
1322
1330
 
1323
- \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),uK($,Y.getAllServers())}function uK($,Y){let Z=`\uD83D\uDD0C **MCP 服务器状态**
1331
+ \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),RW($,Y.getAllServers())}function RW($,Y){let Z=`\uD83D\uDD0C **MCP 服务器状态**
1324
1332
 
1325
- `,X=0,Q=0,J=0;for(let[q,G]of Y){let{config:K,status:W,connectedAt:U,lastError:H,tools:O}=G,F=W==="connected"?"✓":"✗",N=W==="connected"?"Connected":"Disconnected";if(W==="connected")X++,J+=O.length;else Q++;if(Z+=`\uD83D\uDCE6 **${q}**
1326
- `,Z+=` 状态: ${F} ${N}
1333
+ `,X=0,Q=0,J=0;for(let[q,G]of Y){let{config:K,status:W,connectedAt:U,lastError:H,tools:O}=G,F=W==="connected"?"✓":"✗",z=W==="connected"?"Connected":"Disconnected";if(W==="connected")X++,J+=O.length;else Q++;if(Z+=`\uD83D\uDCE6 **${q}**
1334
+ `,Z+=` 状态: ${F} ${z}
1327
1335
  `,Z+=` 类型: ${K.type}
1328
1336
  `,K.type==="stdio")Z+=` 命令: ${K.command}${K.args?.length?" "+K.args.join(" "):""}
1329
1337
  `;else Z+=` URL: ${K.url}
1330
1338
  `;if(Z+=` 工具: ${O.length} 个
1331
- `,U&&W==="connected")Z+=` 连接时间: ${hZ(U)}
1339
+ `,U&&W==="connected")Z+=` 连接时间: ${sZ(U)}
1332
1340
  `;if(H&&W!=="connected")Z+=` 错误: ${H.message}
1333
1341
  `;Z+=`
1334
1342
  `}Z+=`**总计:**
1335
1343
  `,Z+=`- 服务器: ${Y.size} 个 (${X} 连接, ${Q} 断开)
1336
1344
  `,Z+=`- 可用工具: ${J} 个
1337
1345
 
1338
- `,Z+="\uD83D\uDCA1 使用 `/mcp <server-name>` 查看详细信息\n",Z+="\uD83D\uDCA1 使用 `/mcp tools` 查看所有工具",$.sendMessage(Z)}async function cK($,Y){let Z=p1.getInstance(),Q=K0()[Y];if(!Q){$.sendMessage(`❌ 服务器 "${Y}" 不存在
1346
+ `,Z+="\uD83D\uDCA1 使用 `/mcp <server-name>` 查看详细信息\n",Z+="\uD83D\uDCA1 使用 `/mcp tools` 查看所有工具",$.sendMessage(Z)}async function VW($,Y){let Z=g1.getInstance(),Q=U0()[Y];if(!Q){$.sendMessage(`❌ 服务器 "${Y}" 不存在
1339
1347
 
1340
- \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)lK($,Y,J);else fZ($,Y,Q)}catch(J){fZ($,Y,Q),$.sendMessage(`
1341
- ⚠️ 连接失败: ${J instanceof Error?J.message:"未知错误"}`)}}function lK($,Y,Z){let{config:X,status:Q,connectedAt:J,lastError:q,tools:G}=Z,K=Q==="connected"?"✓":"✗",W=Q==="connected"?"Connected":"Disconnected",U=`\uD83D\uDCE6 **${Y}**
1348
+ \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)DW($,Y,J);else oZ($,Y,Q)}catch(J){oZ($,Y,Q),$.sendMessage(`
1349
+ ⚠️ 连接失败: ${J instanceof Error?J.message:"未知错误"}`)}}function DW($,Y,Z){let{config:X,status:Q,connectedAt:J,lastError:q,tools:G}=Z,K=Q==="connected"?"✓":"✗",W=Q==="connected"?"Connected":"Disconnected",U=`\uD83D\uDCE6 **${Y}**
1342
1350
 
1343
1351
  `;if(U+=`**连接状态:**
1344
- `,U+=` ${K} ${W}`,J&&Q==="connected")U+=` (连接于 ${hZ(J)})`;if(U+=`
1352
+ `,U+=` ${K} ${W}`,J&&Q==="connected")U+=` (连接于 ${sZ(J)})`;if(U+=`
1345
1353
 
1346
1354
  `,U+=`**配置信息:**
1347
1355
  `,U+=` 类型: ${X.type}
@@ -1359,7 +1367,7 @@ Please continue the conversation from where we left it off without asking the us
1359
1367
  ⚠️ 服务器未连接,无法获取工具列表
1360
1368
  `;if(q)U+=`
1361
1369
  **错误信息:**
1362
- `,U+=` ${q.message}`;$.sendMessage(U)}function fZ($,Y,Z){let X=`\uD83D\uDCE6 **${Y}**
1370
+ `,U+=` ${q.message}`;$.sendMessage(U)}function oZ($,Y,Z){let X=`\uD83D\uDCE6 **${Y}**
1363
1371
 
1364
1372
  `;if(X+=`**连接状态:**
1365
1373
  `,X+=` ⏸️ 未启动 (等待 Agent 连接)
@@ -1373,7 +1381,7 @@ Please continue the conversation from where we left it off without asking the us
1373
1381
  `,Z.headers&&Object.keys(Z.headers).length>0)X+=` Headers: ${Object.keys(Z.headers).join(", ")}
1374
1382
  `;if(Z.timeout)X+=` 超时: ${Z.timeout}ms
1375
1383
  `;X+=`
1376
- \uD83D\uDCA1 服务器将在 Agent 启动时自动连接`,$.sendMessage(X)}async function iK($){let Y=p1.getInstance(),Z=K0();if(Object.keys(Z).length===0){$.sendMessage(`\uD83D\uDD27 **可用的 MCP 工具**
1384
+ \uD83D\uDCA1 服务器将在 Agent 启动时自动连接`,$.sendMessage(X)}async function IW($){let Y=g1.getInstance(),Z=U0();if(Object.keys(Z).length===0){$.sendMessage(`\uD83D\uDD27 **可用的 MCP 工具**
1377
1385
 
1378
1386
  ⚠️ 暂无配置的 MCP 服务器
1379
1387
 
@@ -1386,9 +1394,9 @@ Please continue the conversation from where we left it off without asking the us
1386
1394
 
1387
1395
  `;continue}q+=U.length;for(let H of U){if(J+=` • ${H.name}`,H.description){let O=H.description.length>60?H.description.substring(0,57)+"...":H.description;J+=` - ${O}`}J+=`
1388
1396
  `}J+=`
1389
- `}J+=`**总计:** ${q} 个工具可用`,$.sendMessage(J)}var rK,xZ;var pZ=R(()=>{Y$();$$();_1();w2();rK={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=V1(Y);try{if(console.log("[MCP Command] Received args:",$),$.length===0)return await dK(Z),{success:!0,message:"MCP 服务器概览已显示"};let X=$[0];if(console.log("[MCP Command] Subcommand:",X),X==="tools")return await iK(Z),{success:!0,message:"MCP 工具列表已显示"};return await cK(Z,X),{success:!0,message:`服务器 "${X}" 详情已显示`}}catch(X){return{success:!1,error:`显示 MCP 信息失败: ${X instanceof Error?X.message:"未知错误"}`}}}},xZ=rK});async function aK($,Y){return{success:!0,message:"show_permissions_editor",data:{action:"show_permissions_editor"}}}var nK,z4;var a9=R(()=>{nK={name:"permissions",description:"管理项目的本地权限规则",fullDescription:"打开权限管理器,管理 .blade/settings.local.json 中的权限规则",usage:"/permissions",aliases:["perm"],category:"ui",handler:aK},z4=nK});var oK,gZ;var mZ=R(()=>{W4();_1();w2();oK={name:"resume",description:"Resume a conversation",fullDescription:"恢复历史会话。可以指定 sessionId 直接恢复,或不带参数打开会话选择器",usage:"/resume [sessionId]",aliases:["r"],category:"Session",examples:["/resume - 打开会话选择器","/resume abc123xyz - 直接恢复指定的会话"],async handler($,Y){let Z=V1(Y),X=v2().restoreSession;if($.length>0){let Q=$[0];try{let J=await g0.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}\`
1397
+ `}J+=`**总计:** ${q} 个工具可用`,$.sendMessage(J)}var MW,tZ;var eZ=b(()=>{J$();Q$();z1();V2();MW={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=D1(Y);try{if(console.log("[MCP Command] Received args:",$),$.length===0)return await bW(Z),{success:!0,message:"MCP 服务器概览已显示"};let X=$[0];if(console.log("[MCP Command] Subcommand:",X),X==="tools")return await IW(Z),{success:!0,message:"MCP 工具列表已显示"};return await VW(Z,X),{success:!0,message:`服务器 "${X}" 详情已显示`}}catch(X){return{success:!1,error:`显示 MCP 信息失败: ${X instanceof Error?X.message:"未知错误"}`}}}},tZ=MW});async function jW($,Y){return{success:!0,message:"show_permissions_editor",data:{action:"show_permissions_editor"}}}var vW,b4;var G7=b(()=>{vW={name:"permissions",description:"管理项目的本地权限规则",fullDescription:"打开权限管理器,管理 .blade/settings.local.json 中的权限规则",usage:"/permissions",aliases:["perm"],category:"ui",handler:jW},b4=vW});var yW,$X;var YX=b(()=>{N4();z1();V2();yW={name:"resume",description:"Resume a conversation",fullDescription:"恢复历史会话。可以指定 sessionId 直接恢复,或不带参数打开会话选择器",usage:"/resume [sessionId]",aliases:["r"],category:"Session",examples:["/resume - 打开会话选择器","/resume abc123xyz - 直接恢复指定的会话"],async handler($,Y){let Z=D1(Y),X=P2().restoreSession;if($.length>0){let Q=$[0];try{let J=await l0.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}\`
1390
1398
 
1391
- 共 ${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 g0.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}`}}}},gZ=oK});var sK,tK,eK,$W,YW,ZW,dZ;var uZ=R(()=>{C6();_1();g$();TZ();CZ();pZ();a9();mZ();w2();sK={name:"help",description:"Show all available slash commands",fullDescription:"显示所有可用的 slash commands 及其使用方法",usage:"/help",aliases:["h"],async handler($,Y){let Z=V1(Y),X=`\uD83D\uDD27 **可用的 Slash Commands:**
1399
+ 共 ${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 l0.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}`}}}},$X=yW});import ZX from"node:fs/promises";import XX from"node:path";var EW,kW,PW,TW,SW,CW,QX;var JX=b(()=>{d6();z1();u$();rZ();nZ();eZ();G7();YX();V2();EW={name:"help",description:"Show all available slash commands",fullDescription:"显示所有可用的 slash commands 及其使用方法",usage:"/help",aliases:["h"],async handler($,Y){let Z=D1(Y),X=`\uD83D\uDD27 **可用的 Slash Commands:**
1392
1400
 
1393
1401
  **/init** - 分析当前项目并生成 BLADE.md 配置文件
1394
1402
  **/git** - Git 仓库查询和 AI 辅助 (status/log/diff/review/commit)
@@ -1424,7 +1432,7 @@ Please continue the conversation from where we left it off without asking the us
1424
1432
  - 在命令前加上 \`/\` 即可执行 slash command
1425
1433
  - 普通消息会发送给 AI 助手处理
1426
1434
  - 按 Ctrl+C 退出程序
1427
- - 按 Ctrl+L 快速清屏`),{success:!0,message:"帮助信息已显示"}}},tK={name:"clear",description:"Clear conversation history and free up context",fullDescription:"清除屏幕内容和对话历史",usage:"/clear",aliases:["cls"],async handler($,Y){return{success:!0,message:"clear_screen"}}},eK={name:"version",description:"Show Blade Code version information",fullDescription:"显示 Blade Code 版本信息和构建详情",usage:"/version",aliases:["v"],async handler($,Y){let Z=V1(Y),Q=`\uD83D\uDDE1️ **Blade Code v${a2()}**
1435
+ - 按 Ctrl+L 快速清屏`),{success:!0,message:"帮助信息已显示"}}},kW={name:"clear",description:"Clear conversation history and free up context",fullDescription:"清除屏幕内容和对话历史",usage:"/clear",aliases:["cls"],async handler($,Y){return{success:!0,message:"clear_screen"}}},PW={name:"version",description:"Show Blade Code version information",fullDescription:"显示 Blade Code 版本信息和构建详情",usage:"/version",aliases:["v"],async handler($,Y){let Z=D1(Y),Q=`\uD83D\uDDE1️ **Blade Code v${t2()}**
1428
1436
 
1429
1437
  **构建信息:**
1430
1438
  - Node.js: ${process.version}
@@ -1435,21 +1443,21 @@ Please continue the conversation from where we left it off without asking the us
1435
1443
  - \uD83E\uDD16 智能 AI 对话
1436
1444
  - \uD83D\uDD27 项目自动分析
1437
1445
  - \uD83D\uDCDD 自定义系统提示
1438
- - \uD83C\uDFAF 多工具集成支持`;return Z.sendMessage(Q),{success:!0,message:"版本信息已显示"}}},$W={name:"status",description:"Show current configuration status",fullDescription:"显示当前项目配置状态和环境信息",usage:"/status",async handler($,Y){let Z=V1(Y),{cwd:X}=Y,Q=x1("path"),J=x1("fs").promises;try{let q=Q.join(X,"BLADE.md"),G=await J.access(q).then(()=>!0).catch(()=>!1),K=Q.join(X,"package.json"),W="未知项目",U="未知类型";try{let O=await J.readFile(K,"utf-8"),F=JSON.parse(O);W=F.name||"未知项目";let N={...F.dependencies,...F.devDependencies};if(N.react)U="React 项目";else if(N.vue)U="Vue 项目";else if(N.next)U="Next.js 项目";else if(N.express)U="Express 项目";else U="Node.js 项目"}catch{}let H=`\uD83D\uDCCA **当前状态**
1446
+ - \uD83C\uDFAF 多工具集成支持`;return Z.sendMessage(Q),{success:!0,message:"版本信息已显示"}}},TW={name:"status",description:"Show current configuration status",fullDescription:"显示当前项目配置状态和环境信息",usage:"/status",async handler($,Y){let Z=D1(Y),{cwd:X}=Y;try{let Q=XX.join(X,"BLADE.md"),J=await ZX.access(Q).then(()=>!0).catch(()=>!1),q=XX.join(X,"package.json"),G="未知项目",K="未知类型";try{let U=await ZX.readFile(q,"utf-8"),H=JSON.parse(U);G=H.name||"未知项目";let O={...H.dependencies,...H.devDependencies};if(O.react)K="React 项目";else if(O.vue)K="Vue 项目";else if(O.next)K="Next.js 项目";else if(O.express)K="Express 项目";else K="Node.js 项目"}catch{}let W=`\uD83D\uDCCA **当前状态**
1439
1447
 
1440
1448
  **项目信息:**
1441
- - 名称: ${W}
1442
- - 类型: ${U}
1449
+ - 名称: ${G}
1450
+ - 类型: ${K}
1443
1451
  - 路径: ${X}
1444
1452
 
1445
1453
  **配置状态:**
1446
- - BLADE.md: ${G?"✅ 已配置":"❌ 未配置 (使用 /init 创建)"}
1454
+ - BLADE.md: ${J?"✅ 已配置":"❌ 未配置 (使用 /init 创建)"}
1447
1455
 
1448
1456
  **环境信息:**
1449
1457
  - 工作目录: ${process.cwd()}
1450
1458
  - Node.js: ${process.version}
1451
1459
 
1452
- ${!G?"\n\uD83D\uDCA1 **建议:** 运行 `/init` 命令来创建项目配置文件":""}`;return Z.sendMessage(H),{success:!0,message:"状态信息已显示"}}catch(q){return{success:!1,error:`获取状态信息失败: ${q instanceof Error?q.message:"未知错误"}`}}}},YW={name:"exit",description:"Exit the REPL",fullDescription:"退出 Blade Code 命令行界面",usage:"/exit",aliases:["quit","q"],async handler($,Y){return{success:!0,message:"exit_application"}}},ZW={name:"context",description:"Visualize current context usage as a colored grid",fullDescription:"可视化显示当前上下文使用情况",usage:"/context",async handler($,Y){let Z=V1(Y),X=v1(),Q=e2(),q=e().session.messages||[],G=q.map((L)=>({role:L.role,content:L.content})),K=Q?.model||"gpt-4",W=G.length>0?t0.countTokens(G,K):0,U=Q?.maxContextTokens??X?.maxContextTokens??128000,H=U>0?(W/U*100).toFixed(1):"0",O=(100-parseFloat(H)).toFixed(1),F=parseFloat(H),N;if(F<50)N="\uD83D\uDFE2 正常";else if(F<80)N="\uD83D\uDFE1 中等";else N="\uD83D\uDD34 高负载";let z=`\uD83D\uDCCA **上下文使用情况**
1460
+ ${!J?"\n\uD83D\uDCA1 **建议:** 运行 `/init` 命令来创建项目配置文件":""}`;return Z.sendMessage(W),{success:!0,message:"状态信息已显示"}}catch(Q){return{success:!1,error:`获取状态信息失败: ${Q instanceof Error?Q.message:"未知错误"}`}}}},SW={name:"exit",description:"Exit the REPL",fullDescription:"退出 Blade Code 命令行界面",usage:"/exit",aliases:["quit","q"],async handler($,Y){return{success:!0,message:"exit_application"}}},CW={name:"context",description:"Visualize current context usage as a colored grid",fullDescription:"可视化显示当前上下文使用情况",usage:"/context",async handler($,Y){let Z=D1(Y),X=v1(),Q=X$(),q=e().session.messages||[],G=q.map((w)=>({role:w.role,content:w.content})),K=Q?.model||"gpt-4",W=G.length>0?Z2.countTokens(G,K):0,U=Q?.maxContextTokens??X?.maxContextTokens??128000,H=U>0?(W/U*100).toFixed(1):"0",O=(100-parseFloat(H)).toFixed(1),F=parseFloat(H),z;if(F<50)z="\uD83D\uDFE2 正常";else if(F<80)z="\uD83D\uDFE1 中等";else z="\uD83D\uDD34 高负载";let _=`\uD83D\uDCCA **上下文使用情况**
1453
1461
 
1454
1462
  **当前会话:**
1455
1463
  - 消息数量: ${q.length}
@@ -1461,10 +1469,10 @@ ${!G?"\n\uD83D\uDCA1 **建议:** 运行 `/init` 命令来创建项目配置文
1461
1469
  - 模型: ${Q?.model||"未配置"}
1462
1470
  - 上下文窗口: ${U.toLocaleString()} tokens
1463
1471
 
1464
- **状态:** ${N}
1472
+ **状态:** ${z}
1465
1473
 
1466
- \uD83D\uDCA1 使用 \`/compact\` 可手动压缩上下文`;return Z.sendMessage(z),{success:!0,message:"上下文信息已显示"}}},dZ={help:sK,clear:tK,version:eK,status:$W,exit:YW,context:ZW,permissions:z4,resume:gZ,compact:SZ,mcp:xZ,agents:PZ}});import{execFile as cZ,spawn as XW}from"child_process";import{promisify as QW}from"util";async function X6($,Y){return new Promise((Z)=>{cZ("git",Y,{cwd:$,maxBuffer:10485760},(X,Q,J)=>{Z({code:X?X.code||1:0,stdout:Q||"",stderr:J||""})})})}async function JW($,Y){let{code:Z}=await X6($,Y);return Z===0}async function d0($,Y){let{stdout:Z}=await X6($,Y);return Z.trim()}async function Q6($){return JW($,["rev-parse","--is-inside-work-tree"])}async function _4($){return(await d0($,["status","--porcelain"])).length>0}async function lZ($){return d0($,["branch","--show-current"])}async function N4($,Y=10){return d0($,["log","-n",String(Y),"--pretty=format:%s"])}async function n9($){let{code:Y,stderr:Z}=await X6($,["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 iZ($,Y,Z=!1,X){let Q=["commit","-m",Y];if(Z)Q.push("--no-verify");if(!X){let{code:J,stderr:q}=await X6($,Q);if(J!==0)throw Error(q||"Commit failed");return}return new Promise((J,q)=>{let G=XW("git",Q,{cwd:$}),K="",W=(O,F,N)=>{let L=(N+O.toString()).split(`
1467
- `),B=L.pop()||"";for(let _ of L)if(_.trim())X(_,F);return B},U="",H="";G.stdout?.on("data",(O)=>{U=W(O,"stdout",U)}),G.stderr?.on("data",(O)=>{K+=O.toString(),H=W(O,"stderr",H)}),G.on("error",(O)=>{q(O)}),G.on("close",(O)=>{if(U.trim())X(U,"stdout");if(H.trim())X(H,"stderr");if(O===0)J();else q(Error(K||"Commit failed"))})})}async function rZ($){let{cwd:Y}=$;if(!await Q6(Y))return null;let[Z,X,Q,J,q]=await Promise.all([d0(Y,["branch","--show-current"]),d0(Y,["rev-parse","--abbrev-ref","origin/HEAD"]).then((K)=>K.replace("origin/","")).catch(()=>"main"),d0(Y,["status","--short"]),d0(Y,["log","--oneline","-n","5"]),d0(Y,["config","user.email"])]),G=q?await d0(Y,["log","--author",q,"--oneline","-n","5"]):"";return{branch:Z,mainBranch:X,status:Q,log:J,author:q,authorLog:G}}function aZ($){if(!$)return null;return`
1474
+ \uD83D\uDCA1 使用 \`/compact\` 可手动压缩上下文`;return Z.sendMessage(_),{success:!0,message:"上下文信息已显示"}}},QX={help:EW,clear:kW,version:PW,status:TW,exit:SW,context:CW,permissions:b4,resume:$X,compact:aZ,mcp:tZ,agents:iZ}});import{execFile as qX,spawn as fW}from"child_process";import{promisify as hW}from"util";async function K6($,Y){return new Promise((Z)=>{qX("git",Y,{cwd:$,maxBuffer:10485760},(X,Q,J)=>{Z({code:X?X.code||1:0,stdout:Q||"",stderr:J||""})})})}async function xW($,Y){let{code:Z}=await K6($,Y);return Z===0}async function r0($,Y){let{stdout:Z}=await K6($,Y);return Z.trim()}async function W6($){return xW($,["rev-parse","--is-inside-work-tree"])}async function R4($){return(await r0($,["status","--porcelain"])).length>0}async function GX($){return r0($,["branch","--show-current"])}async function V4($,Y=10){return r0($,["log","-n",String(Y),"--pretty=format:%s"])}async function K7($){let{code:Y,stderr:Z}=await K6($,["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 KX($,Y,Z=!1,X){let Q=["commit","-m",Y];if(Z)Q.push("--no-verify");if(!X){let{code:J,stderr:q}=await K6($,Q);if(J!==0)throw Error(q||"Commit failed");return}return new Promise((J,q)=>{let G=fW("git",Q,{cwd:$}),K="",W=(O,F,z)=>{let w=(z+O.toString()).split(`
1475
+ `),B=w.pop()||"";for(let N of w)if(N.trim())X(N,F);return B},U="",H="";G.stdout?.on("data",(O)=>{U=W(O,"stdout",U)}),G.stderr?.on("data",(O)=>{K+=O.toString(),H=W(O,"stderr",H)}),G.on("error",(O)=>{q(O)}),G.on("close",(O)=>{if(U.trim())X(U,"stdout");if(H.trim())X(H,"stderr");if(O===0)J();else q(Error(K||"Commit failed"))})})}async function WX($){let{cwd:Y}=$;if(!await W6(Y))return null;let[Z,X,Q,J,q]=await Promise.all([r0(Y,["branch","--show-current"]),r0(Y,["rev-parse","--abbrev-ref","origin/HEAD"]).then((K)=>K.replace("origin/","")).catch(()=>"main"),r0(Y,["status","--short"]),r0(Y,["log","--oneline","-n","5"]),r0(Y,["config","user.email"])]),G=q?await r0(Y,["log","--author",q,"--oneline","-n","5"]):"";return{branch:Z,mainBranch:X,status:Q,log:J,author:q,authorLog:G}}function UX($){if(!$)return null;return`
1468
1476
  Git repository status (snapshot at conversation start):
1469
1477
  Current branch: ${$.branch}
1470
1478
  Main branch (target for PRs): ${$.mainBranch}
@@ -1477,14 +1485,14 @@ ${$.log||"(no commits)"}
1477
1485
 
1478
1486
  Your recent commits:
1479
1487
  ${$.authorLog||"(no recent commits)"}
1480
- `.trim()}async function J6($){return d0($,["diff","--cached","--name-status"])}async function q6($){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 X6($,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)+`
1488
+ `.trim()}async function U6($){return r0($,["diff","--cached","--name-status"])}async function H6($){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 K6($,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)+`
1481
1489
 
1482
- [Diff truncated due to size. Total diff size: `+(Q.length/1024).toFixed(2)+"KB]";return Q}var YV;var o9=R(()=>{YV=QW(cZ)});async function nZ($){let Y=V1($),Z=await rZ({cwd:$.cwd});if(!Z)return{success:!1,error:"无法获取 Git 状态"};let X=aZ(Z);if(X)Y.sendMessage(`\`\`\`
1490
+ [Diff truncated due to size. Total diff size: `+(Q.length/1024).toFixed(2)+"KB]";return Q}var dV;var W7=b(()=>{dV=hW(qX)});async function HX($){let Y=D1($),Z=await WX({cwd:$.cwd});if(!Z)return{success:!1,error:"无法获取 Git 状态"};let X=UX(Z);if(X)Y.sendMessage(`\`\`\`
1483
1491
  ${X}
1484
- \`\`\``);else Y.sendMessage("\uD83D\uDCED 无法获取 Git 状态信息");return{success:!0}}async function GW($,Y){let Z=V1($),X=Math.min(Math.max(parseInt(Y||"5",10)||5,1),50),Q=await N4($.cwd,X);if(!Q)Z.sendMessage("\uD83D\uDCED 暂无提交记录");else Z.sendMessage(`**最近 ${X} 条提交:**
1492
+ \`\`\``);else Y.sendMessage("\uD83D\uDCED 无法获取 Git 状态信息");return{success:!0}}async function gW($,Y){let Z=D1($),X=Math.min(Math.max(parseInt(Y||"5",10)||5,1),50),Q=await V4($.cwd,X);if(!Q)Z.sendMessage("\uD83D\uDCED 暂无提交记录");else Z.sendMessage(`**最近 ${X} 条提交:**
1485
1493
  \`\`\`
1486
1494
  ${Q}
1487
- \`\`\``);return{success:!0}}async function KW($){let Y=V1($),{cwd:Z}=$,X=await J6(Z);if(!X)return Y.sendMessage("\uD83D\uDCED 暂存区为空,没有待提交的改动"),{success:!0};let Q=await q6(Z),J=`**暂存文件:**
1495
+ \`\`\``);return{success:!0}}async function mW($){let Y=D1($),{cwd:Z}=$,X=await U6(Z);if(!X)return Y.sendMessage("\uD83D\uDCED 暂存区为空,没有待提交的改动"),{success:!0};let Q=await H6(Z),J=`**暂存文件:**
1488
1496
  \`\`\`
1489
1497
  ${X}
1490
1498
  \`\`\`
@@ -1492,7 +1500,7 @@ ${X}
1492
1500
  **Diff:**
1493
1501
  \`\`\`diff
1494
1502
  ${Q||"(无差异)"}
1495
- \`\`\``;return Y.sendMessage(J),{success:!0}}async function WW($){let Y=V1($),{cwd:Z,signal:X}=$;if(!await _4(Z))return Y.sendMessage("\uD83D\uDCED 没有未提交的改动,无需 Review"),{success:!0};Y.sendMessage("\uD83D\uDD0D 正在分析代码改动...");let Q=await J6(Z),J=await q6(Z);if(!J&&!Q)return Y.sendMessage("\uD83D\uDCA1 请先使用 `git add` 暂存要 Review 的文件"),{success:!0};let q=await S1.create(),G=e().session.sessionId,K=`请对以下 Git 改动进行 Code Review。
1503
+ \`\`\``;return Y.sendMessage(J),{success:!0}}async function dW($){let Y=D1($),{cwd:Z,signal:X}=$;if(!await R4(Z))return Y.sendMessage("\uD83D\uDCED 没有未提交的改动,无需 Review"),{success:!0};Y.sendMessage("\uD83D\uDD0D 正在分析代码改动...");let Q=await U6(Z),J=await H6(Z);if(!J&&!Q)return Y.sendMessage("\uD83D\uDCA1 请先使用 `git add` 暂存要 Review 的文件"),{success:!0};let q=await f1.create(),G=e().session.sessionId,K=`请对以下 Git 改动进行 Code Review。
1496
1504
 
1497
1505
  **暂存文件:**
1498
1506
  ${Q||"(无)"}
@@ -1508,7 +1516,7 @@ ${J||"(无差异)"}
1508
1516
  3. **潜在问题**:指出可能的 bug、安全问题或性能问题
1509
1517
  4. **改进建议**:具体的代码改进建议
1510
1518
 
1511
- 如果改动很好,也请说明优点。保持简洁专业。`,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 UW($){let Y=V1($),{cwd:Z,signal:X}=$;if(!await _4(Z))return Y.sendMessage("\uD83D\uDCED 没有未提交的改动"),{success:!0};Y.sendMessage("\uD83D\uDCE6 暂存所有改动..."),await n9(Z);let Q=await J6(Z),J=await q6(Z);if(!Q)return Y.sendMessage("\uD83D\uDCED 没有需要提交的改动"),{success:!0};Y.sendMessage("\uD83E\uDD16 正在生成 commit message...");let q=await N4(Z,5),G=await S1.create(),K=e().session.sessionId,W=oZ(Q,J,q),H=(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:**
1519
+ 如果改动很好,也请说明优点。保持简洁专业。`,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 uW($){let Y=D1($),{cwd:Z,signal:X}=$;if(!await R4(Z))return Y.sendMessage("\uD83D\uDCED 没有未提交的改动"),{success:!0};Y.sendMessage("\uD83D\uDCE6 暂存所有改动..."),await K7(Z);let Q=await U6(Z),J=await H6(Z);if(!Q)return Y.sendMessage("\uD83D\uDCED 没有需要提交的改动"),{success:!0};Y.sendMessage("\uD83E\uDD16 正在生成 commit message...");let q=await V4(Z,5),G=await f1.create(),K=e().session.sessionId,W=OX(Q,J,q),H=(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:**
1512
1520
  \`\`\`
1513
1521
  ${H}
1514
1522
  \`\`\`
@@ -1517,10 +1525,10 @@ ${H}
1517
1525
  \`\`\`bash
1518
1526
  git commit -m "${H.split(`
1519
1527
  `)[0]}"
1520
- \`\`\``),{success:!0}}async function HW($){let Y=V1($),{cwd:Z,signal:X}=$;if(!await _4(Z))return Y.sendMessage("\uD83D\uDCED 没有未提交的改动"),{success:!0};Y.sendMessage("\uD83D\uDCE6 暂存所有改动..."),await n9(Z);let Q=await J6(Z),J=await q6(Z);if(!Q)return Y.sendMessage("\uD83D\uDCED 没有需要提交的改动"),{success:!0};Y.sendMessage("\uD83E\uDD16 正在生成 commit message...");let q=await N4(Z,5),G=await S1.create(),K=e().session.sessionId,W=oZ(Q,J,q),H=(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:**
1528
+ \`\`\``),{success:!0}}async function cW($){let Y=D1($),{cwd:Z,signal:X}=$;if(!await R4(Z))return Y.sendMessage("\uD83D\uDCED 没有未提交的改动"),{success:!0};Y.sendMessage("\uD83D\uDCE6 暂存所有改动..."),await K7(Z);let Q=await U6(Z),J=await H6(Z);if(!Q)return Y.sendMessage("\uD83D\uDCED 没有需要提交的改动"),{success:!0};Y.sendMessage("\uD83E\uDD16 正在生成 commit message...");let q=await V4(Z,5),G=await f1.create(),K=e().session.sessionId,W=OX(Q,J,q),H=(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:**
1521
1529
  \`\`\`
1522
1530
  ${H}
1523
- \`\`\``);try{await iZ(Z,H),Y.sendMessage("✅ 提交成功!")}catch(O){let F=O instanceof Error?O.message:"未知错误";return Y.sendMessage(`❌ 提交失败: ${F}`),{success:!1,error:F}}return{success:!0}}function oZ($,Y,Z){let X=Z&&Z.trim().length>0;return`请根据以下 Git 改动生成一条 commit message。
1531
+ \`\`\``);try{await KX(Z,H),Y.sendMessage("✅ 提交成功!")}catch(O){let F=O instanceof Error?O.message:"未知错误";return Y.sendMessage(`❌ 提交失败: ${F}`),{success:!1,error:F}}return{success:!0}}function OX($,Y,Z){let X=Z&&Z.trim().length>0;return`请根据以下 Git 改动生成一条 commit message。
1524
1532
 
1525
1533
  **暂存文件:**
1526
1534
  ${$}
@@ -1541,13 +1549,13 @@ ${Z}
1541
1549
  1. ${X?"严格模仿历史提交的语言和格式风格":"使用英文,遵循 Conventional Commits 格式(feat:, fix:, docs:, refactor:, chore: 等)"}
1542
1550
  2. 第一行简明扼要,不超过 72 字符
1543
1551
  3. 如有必要,可添加空行后的详细说明
1544
- 4. 只输出 commit message 内容,不要其他解释或代码块标记`}var qW,sZ;var tZ=R(()=>{z2();_1();o9();w2();qW={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 Q6(Z))return{success:!1,error:"❌ 当前目录不在 Git 仓库中"};try{switch(X){case"status":case"s":return nZ(Y);case"log":case"l":return GW(Y,$[1]);case"diff":case"d":return KW(Y);case"review":case"r":return WW(Y);case"commit":case"c":return HW(Y);case"pre-commit":case"pc":return UW(Y);default:return nZ(Y)}}catch(Q){return{success:!1,error:`Git 命令失败: ${Q instanceof Error?Q.message:"未知错误"}`}}}};sZ=qW});import{exec as OW}from"child_process";import{promisify as FW}from"util";class s9{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 eZ("code --version"),Z=$.trim().split(`
1545
- `)[0]||"unknown",X=[];try{let{stdout:Q}=await eZ("code --list-extensions");X=Q.trim().split(`
1546
- `).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 eZ;var $X=R(()=>{eZ=FW(OW)});import{exec as zW}from"child_process";import{promisify as _W}from"util";class G6{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 B4(Y),{success:!0,message:"扩展安装成功"}}catch(Z){return{success:!1,message:"安装失败: "+(Z instanceof Error?Z.message:"未知错误")}}}static async checkVsCode(){try{let{stdout:$}=await B4("code --version");return{id:"vscode",name:"VS Code",version:$.trim().split(`
1547
- `)[0]||"unknown"}}catch{return null}}static async checkVsCodeInsiders(){try{let{stdout:$}=await B4("code-insiders --version");return{id:"vscode-insiders",name:"VS Code Insiders",version:$.trim().split(`
1548
- `)[0]||"unknown"}}catch{return null}}static async checkCursor(){try{let{stdout:$}=await B4("cursor --version");return{id:"cursor",name:"Cursor",version:$.trim().split(`
1549
- `)[0]||"unknown"}}catch{return null}}}var B4;var YX=R(()=>{B4=_W(zW)});import{existsSync as NW,readFileSync as BW}from"fs";import{homedir as LW}from"os";import{join as wW}from"path";function AW(){switch(V$){case"connected":return{type:"info",content:`\uD83D\uDFE2 已连接到 ${t9||"IDE"} (端口: ${e9})`};case"connecting":return{type:"info",content:"\uD83D\uDFE1 正在连接..."};default:return{type:"error",content:"\uD83D\uDD34 未连接到 IDE"}}}function XX(){try{if(NW(ZX)){let $=BW(ZX,"utf-8");return JSON.parse($)}}catch{}return null}function QX(){let $=process.env.BLADE_IDE_PORT;if($)return parseInt($,10);let Y=XX();if(Y)return Y.port;return null}async function bW(){let $=[],Y=AW();$.push(Y.content),$.push(""),$.push("\uD83D\uDCE6 已安装的 IDE:");let Z=await G6.getInstalledIdes();if(Z.length===0)$.push(" (未检测到支持的 IDE)");else for(let q of Z)$.push(` • ${q.name} ${q.version}`);$.push("");let X=await s9.detectIde();if(X){if($.push(`\uD83D\uDDA5️ 当前环境: ${X.name} ${X.version}`),X.extensions.length>0)$.push(` 已安装扩展: ${X.extensions.length} 个`)}let Q=QX(),J=XX();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(`
1550
- `)}async function RW(){let $=QX();if(!$)return`❌ 未检测到 IDE 端口
1552
+ 4. 只输出 commit message 内容,不要其他解释或代码块标记`}var pW,FX;var zX=b(()=>{w2();z1();W7();V2();pW={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 W6(Z))return{success:!1,error:"❌ 当前目录不在 Git 仓库中"};try{switch(X){case"status":case"s":return HX(Y);case"log":case"l":return gW(Y,$[1]);case"diff":case"d":return mW(Y);case"review":case"r":return dW(Y);case"commit":case"c":return cW(Y);case"pre-commit":case"pc":return uW(Y);default:return HX(Y)}}catch(Q){return{success:!1,error:`Git 命令失败: ${Q instanceof Error?Q.message:"未知错误"}`}}}};FX=pW});import{exec as lW}from"child_process";import{promisify as iW}from"util";class U7{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 _X("code --version"),Z=$.trim().split(`
1553
+ `)[0]||"unknown",X=[];try{let{stdout:Q}=await _X("code --list-extensions");X=Q.trim().split(`
1554
+ `).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 _X;var NX=b(()=>{_X=iW(lW)});import{exec as rW}from"child_process";import{promisify as aW}from"util";class O6{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(`
1555
+ `)[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(`
1556
+ `)[0]||"unknown"}}catch{return null}}static async checkCursor(){try{let{stdout:$}=await D4("cursor --version");return{id:"cursor",name:"Cursor",version:$.trim().split(`
1557
+ `)[0]||"unknown"}}catch{return null}}}var D4;var BX=b(()=>{D4=aW(rW)});import{existsSync as nW,readFileSync as oW}from"fs";import{homedir as sW}from"os";import{join as tW}from"path";function eW(){switch(j$){case"connected":return{type:"info",content:`\uD83D\uDFE2 已连接到 ${H7||"IDE"} (端口: ${O7})`};case"connecting":return{type:"info",content:"\uD83D\uDFE1 正在连接..."};default:return{type:"error",content:"\uD83D\uDD34 未连接到 IDE"}}}function LX(){try{if(nW(wX)){let $=oW(wX,"utf-8");return JSON.parse($)}}catch{}return null}function AX(){let $=process.env.BLADE_IDE_PORT;if($)return parseInt($,10);let Y=LX();if(Y)return Y.port;return null}async function $U(){let $=[],Y=eW();$.push(Y.content),$.push(""),$.push("\uD83D\uDCE6 已安装的 IDE:");let Z=await O6.getInstalledIdes();if(Z.length===0)$.push(" (未检测到支持的 IDE)");else for(let q of Z)$.push(` • ${q.name} ${q.version}`);$.push("");let X=await U7.detectIde();if(X){if($.push(`\uD83D\uDDA5️ 当前环境: ${X.name} ${X.version}`),X.extensions.length>0)$.push(` 已安装扩展: ${X.extensions.length} 个`)}let Q=AX(),J=LX();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(`
1558
+ `)}async function YU(){let $=AX();if(!$)return`❌ 未检测到 IDE 端口
1551
1559
 
1552
1560
  请确保:
1553
1561
  1. 已在 VS Code 中安装 Blade Code 插件
@@ -1555,25 +1563,25 @@ ${Z}
1555
1563
  3. 在 VS Code 终端中运行 blade
1556
1564
 
1557
1565
  或手动设置端口:
1558
- export BLADE_IDE_PORT=9527`;V$="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),V$="connected",e9=$,t9="VS Code",Z.close(),X()}),Z.on("error",(q)=>{clearTimeout(J),Q(q)})}),`✅ 成功连接到 IDE (端口: ${$})
1566
+ export BLADE_IDE_PORT=9527`;j$="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),j$="connected",O7=$,H7="VS Code",Z.close(),X()}),Z.on("error",(q)=>{clearTimeout(J),Q(q)})}),`✅ 成功连接到 IDE (端口: ${$})
1559
1567
 
1560
1568
  现在可以使用以下功能:
1561
1569
  • 在 IDE 中打开文件
1562
1570
  • 获取当前选中的代码
1563
- • 查看打开的编辑器列表`}catch(Y){return V$="disconnected",`❌ 连接失败: ${Y instanceof Error?Y.message:"未知错误"}
1571
+ • 查看打开的编辑器列表`}catch(Y){return j$="disconnected",`❌ 连接失败: ${Y instanceof Error?Y.message:"未知错误"}
1564
1572
 
1565
1573
  请检查:
1566
1574
  1. VS Code 插件是否正在运行
1567
1575
  2. 端口 ${$} 是否正确
1568
- 3. 防火墙设置`}}async function VW(){let $=[];if($.push("\uD83D\uDCE6 安装 Blade Code VS Code 插件"),$.push(""),!await G6.isIdeInstalled("vscode"))return $.push("❌ 未检测到 VS Code"),$.push(""),$.push("请先安装 VS Code:"),$.push(" https://code.visualstudio.com/"),$.join(`
1576
+ 3. 防火墙设置`}}async function ZU(){let $=[];if($.push("\uD83D\uDCE6 安装 Blade Code VS Code 插件"),$.push(""),!await O6.isIdeInstalled("vscode"))return $.push("❌ 未检测到 VS Code"),$.push(""),$.push("请先安装 VS Code:"),$.push(" https://code.visualstudio.com/"),$.join(`
1569
1577
  `);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(`
1570
- `)}async function DW(){if(V$==="disconnected")return"⚠️ 当前未连接到任何 IDE";return V$="disconnected",t9=null,e9=null,"✅ 已断开与 IDE 的连接"}var ZX,V$="disconnected",t9=null,e9=null,IW,JX;var qX=R(()=>{$X();YX();ZX=wW(LW(),".blade","ide-port");IW={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 bW();break;case"connect":X=await RW();break;case"install":X=await VW();break;case"disconnect":X=await DW();break;default:X=`未知的子命令: ${Z}
1578
+ `)}async function XU(){if(j$==="disconnected")return"⚠️ 当前未连接到任何 IDE";return j$="disconnected",H7=null,O7=null,"✅ 已断开与 IDE 的连接"}var wX,j$="disconnected",H7=null,O7=null,QU,bX;var RX=b(()=>{NX();BX();wX=tW(sW(),".blade","ide-port");QU={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 $U();break;case"connect":X=await YU();break;case"install":X=await ZU();break;case"disconnect":X=await XU();break;default:X=`未知的子命令: ${Z}
1571
1579
 
1572
1580
  可用命令:
1573
1581
  /ide status - 显示连接状态
1574
1582
  /ide connect - 连接到 IDE
1575
1583
  /ide install - 安装 VS Code 插件
1576
- /ide disconnect - 断开连接`}return{success:!0,message:X}}},JX=IW});function K6($,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 GX($,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 W6}from"fs";import*as KX from"path";var D$,MW,WX;var UX=R(()=>{z2();A1();_1();w2();D$=i("Agent"),MW={name:"init",description:"分析当前项目并生成 BLADE.md 配置文件",usage:"/init",async handler($,Y){try{let{cwd:Z,signal:X}=Y,Q=V1(Y),J=(F)=>{Q.sendMessage(`${F}`)},q=e().session.sessionId,G=KX.join(Z,"BLADE.md"),K=!1,W=!1;try{if(K=(await W6.stat(G)).isFile(),K)W=(await W6.readFile(G,"utf-8")).trim().length===0}catch{K=!1}if(K&&!W){Q.sendMessage("⚠️ BLADE.md 已存在。"),Q.sendMessage("\uD83D\uDCA1 正在分析现有文件并提供改进建议...");let F=await S1.create(),N=`Please analyze the existing BLADE.md file and provide improvement suggestions.
1584
+ /ide disconnect - 断开连接`}return{success:!0,message:X}}},bX=QU});function F6($,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 VX($,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 z6}from"fs";import*as DX from"path";var v$,JU,IX;var MX=b(()=>{w2();B1();z1();V2();v$=c("Agent"),JU={name:"init",description:"分析当前项目并生成 BLADE.md 配置文件",usage:"/init",async handler($,Y){try{let{cwd:Z,signal:X}=Y,Q=D1(Y),J=(F)=>{Q.sendMessage(`${F}`)},q=e().session.sessionId,G=DX.join(Z,"BLADE.md"),K=!1,W=!1;try{if(K=(await z6.stat(G)).isFile(),K)W=(await z6.readFile(G,"utf-8")).trim().length===0}catch{K=!1}if(K&&!W){Q.sendMessage("⚠️ BLADE.md 已存在。"),Q.sendMessage("\uD83D\uDCA1 正在分析现有文件并提供改进建议...");let F=await f1.create(),z=`Please analyze the existing BLADE.md file and provide improvement suggestions.
1577
1585
 
1578
1586
  **Important**:
1579
1587
  - After each step, briefly describe what you found before proceeding
@@ -1613,7 +1621,7 @@ ${Z}
1613
1621
  - 具体的改进建议(附带示例)
1614
1622
  - 如果需要重大修改,提供完整的改进版本内容
1615
1623
 
1616
- **Final output**: Return your analysis and suggestions as plain text. Do NOT use Write tool.`;D$.info(`[/init] Starting agent.chat, signal.aborted: ${X?.aborted}`);let z=await F.chat(N,{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),_=K6(L.function.name,B);J(_)}catch{}},onToolResult:async(L,B)=>{if(L.type!=="function")return;if(B?.metadata?.summary)J(B.metadata.summary)}});if(D$.info(`[/init] agent.chat completed, signal.aborted: ${X?.aborted}`),X?.aborted)return D$.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 U=await S1.create(),H=`Please analyze this codebase and generate BLADE.md content.
1624
+ **Final output**: Return your analysis and suggestions as plain text. Do NOT use Write tool.`;v$.info(`[/init] Starting agent.chat, signal.aborted: ${X?.aborted}`);let _=await F.chat(z,{messages:[],userId:"cli-user",sessionId:q||"init-session",workspaceRoot:Z,signal:X},{onToolStart:(w)=>{if(w.type!=="function")return;try{let B=JSON.parse(w.function.arguments),N=F6(w.function.name,B);J(N)}catch{}},onToolResult:async(w,B)=>{if(w.type!=="function")return;if(B?.metadata?.summary)J(B.metadata.summary)}});if(v$.info(`[/init] agent.chat completed, signal.aborted: ${X?.aborted}`),X?.aborted)return v$.info("[/init] Returning cancelled after agent.chat"),{success:!1,message:"操作已取消"};return Q.sendMessage(_),{success:!0,message:"✅ 分析完成"}}if(W)Q.sendMessage("⚠️ 检测到空的 BLADE.md 文件,将重新生成...");Q.sendMessage("\uD83D\uDD0D 正在分析项目结构...");let U=await f1.create(),H=`Please analyze this codebase and generate BLADE.md content.
1617
1625
 
1618
1626
  **Important**: After each step, briefly describe what you found before proceeding.
1619
1627
 
@@ -1660,7 +1668,7 @@ ${Z}
1660
1668
  - Focus on non-obvious insights
1661
1669
  - Be concise but comprehensive for complex projects
1662
1670
 
1663
- **Final output**: Return ONLY the complete BLADE.md content (markdown format), ready to be written to the file.`;D$.info(`[/init] Starting agent.chat for new BLADE.md, signal.aborted: ${X?.aborted}`);let O=await U.chat(H,{messages:[],userId:"cli-user",sessionId:q||"init-session",workspaceRoot:Z,signal:X},{onToolStart:(F)=>{if(F.type!=="function")return;try{let N=JSON.parse(F.function.arguments),z=K6(F.function.name,N);J(z)}catch{}},onToolResult:async(F,N)=>{if(F.type!=="function")return;if(N?.metadata?.summary)J(N.metadata.summary)}});if(D$.info(`[/init] agent.chat completed for new BLADE.md, signal.aborted: ${X?.aborted}`),X?.aborted)return D$.info("[/init] Returning cancelled after agent.chat (new BLADE.md)"),{success:!1,message:"操作已取消"};if(!O||O.trim().length===0)throw Error("Agent 未能生成有效的 BLADE.md 内容");return Q.sendMessage("✨ 正在写入 BLADE.md..."),await W6.writeFile(G,O,"utf-8"),{success:!0,message:"✅ 已成功生成 BLADE.md 文件"}}catch(Z){return{success:!1,error:`初始化失败: ${Z instanceof Error?Z.message:"未知错误"}`}}}},WX=MW});var jW,HX;var OX=R(()=>{_1();jW={name:"model",description:"管理和切换模型配置",usage:"/model [子命令] [参数]",fullDescription:`
1671
+ **Final output**: Return ONLY the complete BLADE.md content (markdown format), ready to be written to the file.`;v$.info(`[/init] Starting agent.chat for new BLADE.md, signal.aborted: ${X?.aborted}`);let O=await U.chat(H,{messages:[],userId:"cli-user",sessionId:q||"init-session",workspaceRoot:Z,signal:X},{onToolStart:(F)=>{if(F.type!=="function")return;try{let z=JSON.parse(F.function.arguments),_=F6(F.function.name,z);J(_)}catch{}},onToolResult:async(F,z)=>{if(F.type!=="function")return;if(z?.metadata?.summary)J(z.metadata.summary)}});if(v$.info(`[/init] agent.chat completed for new BLADE.md, signal.aborted: ${X?.aborted}`),X?.aborted)return v$.info("[/init] Returning cancelled after agent.chat (new BLADE.md)"),{success:!1,message:"操作已取消"};if(!O||O.trim().length===0)throw Error("Agent 未能生成有效的 BLADE.md 内容");return Q.sendMessage("✨ 正在写入 BLADE.md..."),await z6.writeFile(G,O,"utf-8"),{success:!0,message:"✅ 已成功生成 BLADE.md 文件"}}catch(Z){return{success:!1,error:`初始化失败: ${Z instanceof Error?Z.message:"未知错误"}`}}}},IX=JU});var qU,jX;var vX=b(()=>{z1();qU={name:"model",description:"管理和切换模型配置",usage:"/model [子命令] [参数]",fullDescription:`
1664
1672
  管理和切换模型配置
1665
1673
 
1666
1674
  子命令:
@@ -1672,37 +1680,37 @@ ${Z}
1672
1680
  /model # 显示模型选择器
1673
1681
  /model add # 添加新模型
1674
1682
  /model remove 千问 # 删除名称包含"千问"的模型
1675
- `,async handler($,Y){let Z=$[0];if(!Z){if(l$().length===0)return{success:!1,message:`❌ 没有可用的模型配置
1683
+ `,async handler($,Y){let Z=$[0];if(!Z){if(a$().length===0)return{success:!1,message:`❌ 没有可用的模型配置
1676
1684
 
1677
1685
  使用 /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:`❌ 请指定要删除的模型名称
1678
- 用法: /model remove <名称>`};let J=l$().find((q)=>q.name.toLowerCase().includes(X.toLowerCase()));if(!J)return{success:!1,message:`❌ 未找到匹配的模型配置: ${X}`};try{return await z1().removeModel(J.id),{success:!0,message:`✅ 已删除模型配置: ${J.name}`}}catch(q){return{success:!1,message:`❌ ${q.message}`}}}default:return{success:!1,message:`❌ 未知的子命令: ${Z}
1679
- 使用 /model 查看可用操作`}}}},HX=jW});var vW,FX;var zX=R(()=>{K2();_1();vW={name:"skills",description:"查看所有可用的 Skills",fullDescription:"显示所有已发现的 Skills 及其详细信息,包括名称、描述、来源和允许的工具。",usage:"/skills",category:"system",examples:["/skills"],handler:async($,Y)=>{try{return await u1().refresh(),{success:!0,message:"show_skills_manager",data:{action:"show_skills_manager"}}}catch(Z){let X=`获取 Skills 失败: ${Z instanceof Error?Z.message:"未知错误"}`;return v2().addAssistantMessage(X),{success:!1,error:X}}}},FX=vW});async function yW($,Y){return{success:!0,message:"show_theme_selector",data:{action:"show_theme_selector"}}}var EW,_X;var NX=R(()=>{EW={name:"theme",description:"打开交互式主题选择器",aliases:["themes","style"],usage:"/theme",examples:["/theme"],category:"ui",handler:yW},_X=EW});import kW from"fuse.js";function L4($){return $.trim().startsWith("/")}function PW($){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 TW($){if(U6[$])return U6[$];for(let Y of Object.values(U6))if(Y.aliases?.includes($))return Y;return}function $7($){let Y=$.argumentHint?`/${$.name} ${$.argumentHint}`:`/${$.name}`;return{name:$.name,description:$.description,fullDescription:`[Skill] ${$.description}${$.whenToUse?`
1686
+ 用法: /model remove <名称>`};let J=a$().find((q)=>q.name.toLowerCase().includes(X.toLowerCase()));if(!J)return{success:!1,message:`❌ 未找到匹配的模型配置: ${X}`};try{return await F1().removeModel(J.id),{success:!0,message:`✅ 已删除模型配置: ${J.name}`}}catch(q){return{success:!1,message:`❌ ${q.message}`}}}default:return{success:!1,message:`❌ 未知的子命令: ${Z}
1687
+ 使用 /model 查看可用操作`}}}},jX=qU});var GU,yX;var EX=b(()=>{F2();z1();GU={name:"skills",description:"查看所有可用的 Skills",fullDescription:"显示所有已发现的 Skills 及其详细信息,包括名称、描述、来源和允许的工具。",usage:"/skills",category:"system",examples:["/skills"],handler:async($,Y)=>{try{return await l1().refresh(),{success:!0,message:"show_skills_manager",data:{action:"show_skills_manager"}}}catch(Z){let X=`获取 Skills 失败: ${Z instanceof Error?Z.message:"未知错误"}`;return P2().addAssistantMessage(X),{success:!1,error:X}}}},yX=GU});async function KU($,Y){return{success:!0,message:"show_theme_selector",data:{action:"show_theme_selector"}}}var WU,kX;var PX=b(()=>{WU={name:"theme",description:"打开交互式主题选择器",aliases:["themes","style"],usage:"/theme",examples:["/theme"],category:"ui",handler:KU},kX=WU});import UU from"fuse.js";function I4($){return $.trim().startsWith("/")}function HU($){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 OU($){if(_6[$])return _6[$];for(let Y of Object.values(_6))if(Y.aliases?.includes($))return Y;return}function F7($){let Y=$.argumentHint?`/${$.name} ${$.argumentHint}`:`/${$.name}`;return{name:$.name,description:$.description,fullDescription:`[Skill] ${$.description}${$.whenToUse?`
1680
1688
 
1681
- **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 SW($){return u1().getUserInvocableSkills().find((X)=>X.name===$)}async function CW(){await y2()}async function w4($,Y){try{let{command:Z,args:X}=PW($),Q=TW(Z);if(Q)return await Q.handler(X,Y);await CW();let J=SW(Z);if(J)return await $7(J).handler(X,Y);return{success:!1,error:`未知命令: /${Z}
1682
- 使用 /help 查看可用命令`}}catch(Z){return{success:!1,error:`命令执行失败: ${Z instanceof Error?Z.message:"未知错误"}`}}}function BX(){let $=Object.values(U6),Z=u1().getUserInvocableSkills().map($7);return[...$,...Z]}function LX($){let Y=($.startsWith("/")?$.slice(1):$).trim(),Z=Object.values(U6).map((W)=>({name:W.name,description:W.description,aliases:W.aliases||[],command:W,isSkill:!1})),Q=u1().getUserInvocableSkills().map((W)=>({name:W.name,description:W.description,aliases:[],command:$7(W),isSkill:!0})),J=[...Z,...Q];if(!Y)return J.map((W)=>({command:`/${W.name}`,description:W.description,matchScore:50}));return new kW(J,{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 U=W.score??1,H=Math.round((1-U)*100);return{command:`/${W.item.name}`,description:W.item.description,matchScore:H}}).filter((W)=>(W.matchScore||0)>=40)}var U6;var A4=R(()=>{K2();uZ();tZ();qX();UX();OX();a9();zX();NX();U6={...dZ,init:WX,theme:_X,permissions:z4,model:HX,git:sZ,ide:JX,skills:FX}});import{nanoid as fO}from"nanoid";class C7{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(){R1.debug(`[AcpSession ${this.id}] Initializing...`),n.initializeSession(this.connection,this.id,this.clientCapabilities,this.cwd),R1.debug(`[AcpSession ${this.id}] ACP service context initialized`),this.agent=await S1.create({}),R1.debug(`[AcpSession ${this.id}] Agent created successfully`)}sendAvailableCommandsDelayed(){R1.debug(`[AcpSession ${this.id}] Scheduling available commands update (500ms delay)`),setTimeout(()=>{this.sendAvailableCommands()},500)}async handleSlashCommand($,Y){try{R1.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 w4($,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 R1.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 $=BX(),Y=["model","permissions","theme","config","exit","ide"],X=$.filter((Q)=>!Y.includes(Q.name)).map((Q)=>({name:Q.name,description:Q.description,input:Q.aliases?.length?{hint:`Aliases: ${Q.aliases.join(", ")}`}:void 0}));R1.info(`[AcpSession ${this.id}] Sending available commands: ${JSON.stringify(X.map((Q)=>Q.name))}`),this.sendUpdate({sessionUpdate:"available_commands_update",availableCommands:X}),R1.info(`[AcpSession ${this.id}] Sent ${X.length} available commands`)}catch($){R1.error(`[AcpSession ${this.id}] Failed to send available commands:`,$)}}async prompt($){n.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(R1.debug(`[AcpSession ${this.id}] Received prompt: ${Z.slice(0,100)}...`),L4(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 O=typeof G.displayContent==="string"?G.displayContent:JSON.stringify(G.displayContent);K.push({type:"content",content:{type:"text",text:O}})}let U="function"in q?q.function.name:q.type,H=G.success?"completed":"failed";this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:q.id,status:H,content:K})}},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 R1.error(`[AcpSession ${this.id}] Prompt error:`,Z),Z}finally{if(this.pendingPrompt===Y)this.pendingPrompt=null}}cancel(){if(R1.info(`[AcpSession ${this.id}] Cancel requested`),this.pendingPrompt)this.pendingPrompt.abort(),this.pendingPrompt=null,R1.info(`[AcpSession ${this.id}] Cancelled successfully`);else R1.warn(`[AcpSession ${this.id}] No pending prompt to cancel`)}async setMode($){let Y=["default","auto-edit","yolo","plan"];this.mode=Y.includes($)?$:"default",R1.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(R1.info(`[AcpSession ${this.id}] Model set to: ${$}`),this.agent)R1.warn(`[AcpSession ${this.id}] Runtime model switching not yet implemented`)}async destroy(){if(this.cancel(),this.agent)await this.agent.destroy(),this.agent=null;n.destroySession(this.id),R1.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}">
1689
+ **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 FU($){return l1().getUserInvocableSkills().find((X)=>X.name===$)}async function zU(){await T2()}async function M4($,Y){try{let{command:Z,args:X}=HU($),Q=OU(Z);if(Q)return await Q.handler(X,Y);await zU();let J=FU(Z);if(J)return await F7(J).handler(X,Y);return{success:!1,error:`未知命令: /${Z}
1690
+ 使用 /help 查看可用命令`}}catch(Z){return{success:!1,error:`命令执行失败: ${Z instanceof Error?Z.message:"未知错误"}`}}}function TX(){let $=Object.values(_6),Z=l1().getUserInvocableSkills().map(F7);return[...$,...Z]}function SX($){let Y=($.startsWith("/")?$.slice(1):$).trim(),Z=Object.values(_6).map((W)=>({name:W.name,description:W.description,aliases:W.aliases||[],command:W,isSkill:!1})),Q=l1().getUserInvocableSkills().map((W)=>({name:W.name,description:W.description,aliases:[],command:F7(W),isSkill:!0})),J=[...Z,...Q];if(!Y)return J.map((W)=>({command:`/${W.name}`,description:W.description,matchScore:50}));return new UU(J,{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 U=W.score??1,H=Math.round((1-U)*100);return{command:`/${W.item.name}`,description:W.item.description,matchScore:H}}).filter((W)=>(W.matchScore||0)>=40)}var _6;var j4=b(()=>{F2();JX();zX();RX();MX();vX();G7();EX();PX();_6={...QX,init:IX,theme:kX,permissions:b4,model:jX,git:FX,ide:bX,skills:yX}});import{nanoid as QF}from"nanoid";class o7{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(){b1.debug(`[AcpSession ${this.id}] Initializing...`),n.initializeSession(this.connection,this.id,this.clientCapabilities,this.cwd),b1.debug(`[AcpSession ${this.id}] ACP service context initialized`),this.agent=await f1.create({}),b1.debug(`[AcpSession ${this.id}] Agent created successfully`)}sendAvailableCommandsDelayed(){b1.debug(`[AcpSession ${this.id}] Scheduling available commands update (500ms delay)`),setTimeout(()=>{this.sendAvailableCommands()},500)}async handleSlashCommand($,Y){try{b1.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 M4($,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 b1.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 $=TX(),Y=["model","permissions","theme","config","exit","ide"],X=$.filter((Q)=>!Y.includes(Q.name)).map((Q)=>({name:Q.name,description:Q.description,input:Q.aliases?.length?{hint:`Aliases: ${Q.aliases.join(", ")}`}:void 0}));b1.info(`[AcpSession ${this.id}] Sending available commands: ${JSON.stringify(X.map((Q)=>Q.name))}`),this.sendUpdate({sessionUpdate:"available_commands_update",availableCommands:X}),b1.info(`[AcpSession ${this.id}] Sent ${X.length} available commands`)}catch($){b1.error(`[AcpSession ${this.id}] Failed to send available commands:`,$)}}async prompt($){n.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(b1.debug(`[AcpSession ${this.id}] Received prompt: ${Z.slice(0,100)}...`),I4(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 O=typeof G.displayContent==="string"?G.displayContent:JSON.stringify(G.displayContent);K.push({type:"content",content:{type:"text",text:O}})}let U="function"in q?q.function.name:q.type,H=G.success?"completed":"failed";this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:q.id,status:H,content:K})}},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 b1.error(`[AcpSession ${this.id}] Prompt error:`,Z),Z}finally{if(this.pendingPrompt===Y)this.pendingPrompt=null}}cancel(){if(b1.info(`[AcpSession ${this.id}] Cancel requested`),this.pendingPrompt)this.pendingPrompt.abort(),this.pendingPrompt=null,b1.info(`[AcpSession ${this.id}] Cancelled successfully`);else b1.warn(`[AcpSession ${this.id}] No pending prompt to cancel`)}async setMode($){let Y=["default","auto-edit","yolo","plan"];this.mode=Y.includes($)?$:"default",b1.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(b1.info(`[AcpSession ${this.id}] Model set to: ${$}`),this.agent)b1.warn(`[AcpSession ${this.id}] Runtime model switching not yet implemented`)}async destroy(){if(this.cancel(),this.agent)await this.agent.destroy(),this.agent=null;n.destroySession(this.id),b1.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}">
1683
1691
  ${X.text}
1684
1692
  </file>`)}else if(Z.type==="resource_link")Y.push(`[Resource: ${Z.uri}]`);return Y.join(`
1685
- `)}sendUpdate($){let Y={sessionId:this.id,update:$};this.connection.sessionUpdate(Y).catch((Z)=>{R1.warn(`[AcpSession ${this.id}] Failed to send update:`,Z)})}async requestPermission($){let Y=$.kind?.toLowerCase()||"execute";if(this.shouldAutoApprove(Y))return R1.debug(`[AcpSession ${this.id}] Auto-approving ${Y} in mode: ${this.mode}`),{approved:!0};if(this.mode==="plan"&&(Y==="write"||Y==="execute"))return R1.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 R1.debug(`[AcpSession ${this.id}] Using cached approval for: ${Z}`),{approved:!0};try{let X=fO(),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:
1693
+ `)}sendUpdate($){let Y={sessionId:this.id,update:$};this.connection.sessionUpdate(Y).catch((Z)=>{b1.warn(`[AcpSession ${this.id}] Failed to send update:`,Z)})}async requestPermission($){let Y=$.kind?.toLowerCase()||"execute";if(this.shouldAutoApprove(Y))return b1.debug(`[AcpSession ${this.id}] Auto-approving ${Y} in mode: ${this.mode}`),{approved:!0};if(this.mode==="plan"&&(Y==="write"||Y==="execute"))return b1.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 b1.debug(`[AcpSession ${this.id}] Using cached approval for: ${Z}`),{approved:!0};try{let X=QF(),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:
1686
1694
  - ${$.risks.join(`
1687
- - `)}`}});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,U=W==="allow_once"||W==="allow_always";if(W==="allow_always")this.sessionApprovals.add(Z),R1.debug(`[AcpSession ${this.id}] Cached approval for: ${Z}`);return{approved:U,reason:U?void 0:"User denied the operation"}}catch(X){return R1.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 R1;var lQ=R(()=>{z2();Y0();A1();A4();W$();R1=i("Agent")});import{PROTOCOL_VERSION as hO}from"@agentclientprotocol/sdk";import{nanoid as xO}from"nanoid";class f7{connection;sessions=new Map;clientCapabilities;constructor($){this.connection=$}async initialize($){return r0.info("[BladeAgent] Initializing ACP connection"),r0.debug(`[BladeAgent] Client capabilities: ${JSON.stringify($.clientCapabilities)}`),this.clientCapabilities=$.clientCapabilities,{protocolVersion:hO,agentCapabilities:{loadSession:!1,promptCapabilities:{image:!0,audio:!1,embeddedContext:!0},mcpCapabilities:{http:!0,sse:!0}}}}async authenticate($){return}async newSession($){let Y=xO();r0.info(`[BladeAgent] Creating new session: ${Y}`),r0.debug(`[BladeAgent] Session cwd: ${$.cwd||process.cwd()}`);let Z=new C7(Y,$.cwd||process.cwd(),this.connection,this.clientCapabilities);await Z.initialize(),this.sessions.set(Y,Z),r0.info(`[BladeAgent] Session ${Y} created, scheduling available commands update`),Z.sendAvailableCommandsDelayed();let X=v1(),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($){r0.info(`[BladeAgent] Cancel notification received for session: ${$.sessionId}`);let Y=this.sessions.get($.sessionId);if(Y)r0.info("[BladeAgent] Found session, calling session.cancel()"),Y.cancel();else r0.warn(`[BladeAgent] Session not found for cancel: ${$.sessionId}`)}async setSessionMode($){r0.info(`[BladeAgent] Setting session mode: ${$.modeId}`);let Y=this.sessions.get($.sessionId);if(Y)await Y.setMode($.modeId);return{}}async unstable_setSessionModel($){r0.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 r0;var iQ=R(()=>{A1();_1();lQ();r0=i("Agent")});var rQ={};d7(rQ,{runAcpIntegration:()=>mO});import*as r4 from"@agentclientprotocol/sdk";import{Readable as pO,Writable as gO}from"node:stream";async function mO(){let $=gO.toWeb(process.stdout),Y=pO.toWeb(process.stdin),Z=r4.ndJsonStream($,Y);await new r4.AgentSideConnection((Q)=>new f7(Q),Z).closed}var aQ=R(()=>{iQ()});import{render as dO}from"ink";import uO from"react";import cO from"yargs";import{hideBin as oQ}from"yargs/helpers";g$();var r7={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:"}},M2={scriptName:"blade",usage:"$0 [command] [options]",description:l7(),version:a2(),locale:"en",showHelpOnFail:!0,demandCommand:!1,recommendCommands:!0,strict:!1};s2();A1();_1();var Z8=i("General"),F5=($)=>{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 r1.getInstance().initialize();if(e().config.actions.setConfig(Z),$.debug)Z8.info("[CLI] 配置已加载到 Store")}catch(Y){Z8.error("[CLI] ❌ 配置初始化失败",Y instanceof Error?Y.message:Y),console.error(`
1695
+ - `)}`}});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,U=W==="allow_once"||W==="allow_always";if(W==="allow_always")this.sessionApprovals.add(Z),b1.debug(`[AcpSession ${this.id}] Cached approval for: ${Z}`);return{approved:U,reason:U?void 0:"User denied the operation"}}catch(X){return b1.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 b1;var qJ=b(()=>{w2();Q0();B1();j4();F$();b1=c("Agent")});import{PROTOCOL_VERSION as JF}from"@agentclientprotocol/sdk";import{nanoid as qF}from"nanoid";class s7{connection;sessions=new Map;clientCapabilities;constructor($){this.connection=$}async initialize($){return s0.info("[BladeAgent] Initializing ACP connection"),s0.debug(`[BladeAgent] Client capabilities: ${JSON.stringify($.clientCapabilities)}`),this.clientCapabilities=$.clientCapabilities,{protocolVersion:JF,agentCapabilities:{loadSession:!1,promptCapabilities:{image:!0,audio:!1,embeddedContext:!0},mcpCapabilities:{http:!0,sse:!0}}}}async authenticate($){return}async newSession($){let Y=qF();s0.info(`[BladeAgent] Creating new session: ${Y}`),s0.debug(`[BladeAgent] Session cwd: ${$.cwd||process.cwd()}`);let Z=new o7(Y,$.cwd||process.cwd(),this.connection,this.clientCapabilities);await Z.initialize(),this.sessions.set(Y,Z),s0.info(`[BladeAgent] Session ${Y} created, scheduling available commands update`),Z.sendAvailableCommandsDelayed();let X=v1(),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($){s0.info(`[BladeAgent] Cancel notification received for session: ${$.sessionId}`);let Y=this.sessions.get($.sessionId);if(Y)s0.info("[BladeAgent] Found session, calling session.cancel()"),Y.cancel();else s0.warn(`[BladeAgent] Session not found for cancel: ${$.sessionId}`)}async setSessionMode($){s0.info(`[BladeAgent] Setting session mode: ${$.modeId}`);let Y=this.sessions.get($.sessionId);if(Y)await Y.setMode($.modeId);return{}}async unstable_setSessionModel($){s0.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 s0;var GJ=b(()=>{B1();z1();qJ();s0=c("Agent")});var KJ={};RJ(KJ,{runAcpIntegration:()=>WF});import*as t4 from"@agentclientprotocol/sdk";import{Readable as GF,Writable as KF}from"node:stream";async function WF(){let $=KF.toWeb(process.stdout),Y=GF.toWeb(process.stdin),Z=t4.ndJsonStream($,Y);await new t4.AgentSideConnection((Q)=>new s7(Q),Z).closed}var WJ=b(()=>{GJ()});import{render as UF}from"ink";import HF from"react";import OF from"yargs";import{hideBin as HJ}from"yargs/helpers";u$();var Q5={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:"}},E2={scriptName:"blade",usage:"$0 [command] [options]",description:Z5(),version:t2(),locale:"en",showHelpOnFail:!0,demandCommand:!1,recommendCommands:!0,strict:!1};Y$();B1();z1();var U8=c("General"),M5=($)=>{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(", ")}`)}},j5=async($)=>{try{let Z=await n1.getInstance().initialize();if(e().config.actions.setConfig(Z),$.debug)U8.info("[CLI] 配置已加载到 Store")}catch(Y){U8.error("[CLI] ❌ 配置初始化失败",Y instanceof Error?Y.message:Y),console.error(`
1688
1696
  ❌ 配置初始化失败
1689
1697
  `),console.error("原因:",Y instanceof Error?Y.message:"未知错误"),console.error(`
1690
1698
  请检查:`),console.error(" 1. 配置文件格式是否正确 (~/.blade/config.json)"),console.error(" 2. 是否需要运行 blade 进行首次配置"),console.error(` 3. 配置文件权限是否正确
1691
- `),process.exit(1)}if($.continue&&$.resume)throw Error("Cannot use both --continue and --resume flags simultaneously")},_5=($)=>{if($.outputFormat&&$.outputFormat!=="text"&&!$.print)throw Error("--output-format can only be used with --print flag");if($.inputFormat==="stream-json"&&$.print)Z8.warn("⚠️ Warning: stream-json input format may not work as expected with --print")};s2();var N5={command:"doctor",describe:"Check the health of your Blade installation",handler:async()=>{console.log(`\uD83D\uDD0D Running Blade health check...
1692
- `);let $=0;try{await r1.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(`
1693
- \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 B5={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)}}};Y$();$$();_1();import k5 from"os";import E6 from"path";function pJ(){console.log(`
1699
+ `),process.exit(1)}if($.continue&&$.resume)throw Error("Cannot use both --continue and --resume flags simultaneously")},v5=($)=>{if($.outputFormat&&$.outputFormat!=="text"&&!$.print)throw Error("--output-format can only be used with --print flag");if($.inputFormat==="stream-json"&&$.print)U8.warn("⚠️ Warning: stream-json input format may not work as expected with --print")};Y$();var y5={command:"doctor",describe:"Check the health of your Blade installation",handler:async()=>{console.log(`\uD83D\uDD0D Running Blade health check...
1700
+ `);let $=0;try{await n1.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(`
1701
+ \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 E5={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)}}};J$();Q$();z1();import c5 from"os";import h6 from"path";function zq(){console.log(`
1694
1702
  blade mcp
1695
1703
  `),console.log(`管理 MCP 服务器
1696
1704
  `),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 字符串添加服务器
1697
1705
  `),console.log("Options:"),console.log(` -h, --help 显示帮助信息 [boolean]
1698
1706
  `),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
1699
1707
  `),console.log(`使用 blade mcp <command> --help 查看各子命令的详细帮助
1700
- `)}function gJ($){return $.reduce((Y,Z)=>{let[X,...Q]=Z.split("=");return Y[X]=Q.join("="),Y},{})}function mJ($){return $.reduce((Y,Z)=>{let[X,...Q]=Z.split(":");return Y[X.trim()]=Q.join(":").trim(),Y},{})}var dJ={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(`
1708
+ `)}function _q($){return $.reduce((Y,Z)=>{let[X,...Q]=Z.split("=");return Y[X]=Q.join("="),Y},{})}function Nq($){return $.reduce((Y,Z)=>{let[X,...Q]=Z.split(":");return Y[X.trim()]=Q.join(":").trim(),Y},{})}var Bq={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(`
1701
1709
  \uD83D\uDCA1 用法:`),console.log(" blade mcp add <name> <command> [args...]"),console.log(" blade mcp add <name> -- <command> [args...]"),console.log(`
1702
- 示例:`),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=gJ(J)}else if(W.url=Z,q&&Array.isArray(q))W.headers=mJ(q);if(G)W.timeout=G;await z1().addMcpServer(Y,W,{scope:K?"global":"project"});let U=K?E6.join(k5.homedir(),".blade","config.json"):E6.join(process.cwd(),".blade","config.json");console.log(`✅ MCP 服务器 "${Y}" 已添加`),console.log(` 配置文件: ${U}`)}catch(Y){console.error(`❌ 添加失败: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}},uJ={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=K0(),Z=$.global===!0;if(!Y[$.name])console.error(`❌ 服务器 "${$.name}" 不存在`),process.exit(1);await z1().removeMcpServer($.name,{scope:Z?"global":"project"}),console.log(`✅ MCP 服务器 "${$.name}" 已删除`)}catch(Y){console.error(`❌ 删除失败: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}},cJ={command:"list",describe:"列出所有 MCP 服务器并检查健康状态",aliases:["ls"],handler:async()=>{try{let $=K0();if(console.log(""),Object.keys($).length===0){console.log("暂无配置的 MCP 服务器");return}console.log(`检查 MCP 服务器健康状态...
1703
- `);let Y=p1.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"?"✓":"✗",U=K==="connected"?"Connected":"Failed";if(console.log(`${Q}: ${J.type==="stdio"?J.command:J.url} - ${W} ${U}`),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)}}},lJ={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=K0()[$.name];if(!Z)console.error(`❌ 服务器 "${$.name}" 不存在`),process.exit(1);console.log(`
1710
+ 示例:`),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=_q(J)}else if(W.url=Z,q&&Array.isArray(q))W.headers=Nq(q);if(G)W.timeout=G;await F1().addMcpServer(Y,W,{scope:K?"global":"project"});let U=K?h6.join(c5.homedir(),".blade","config.json"):h6.join(process.cwd(),".blade","config.json");console.log(`✅ MCP 服务器 "${Y}" 已添加`),console.log(` 配置文件: ${U}`)}catch(Y){console.error(`❌ 添加失败: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}},wq={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=U0(),Z=$.global===!0;if(!Y[$.name])console.error(`❌ 服务器 "${$.name}" 不存在`),process.exit(1);await F1().removeMcpServer($.name,{scope:Z?"global":"project"}),console.log(`✅ MCP 服务器 "${$.name}" 已删除`)}catch(Y){console.error(`❌ 删除失败: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}},Lq={command:"list",describe:"列出所有 MCP 服务器并检查健康状态",aliases:["ls"],handler:async()=>{try{let $=U0();if(console.log(""),Object.keys($).length===0){console.log("暂无配置的 MCP 服务器");return}console.log(`检查 MCP 服务器健康状态...
1711
+ `);let Y=g1.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"?"✓":"✗",U=K==="connected"?"Connected":"Failed";if(console.log(`${Q}: ${J.type==="stdio"?J.command:J.url} - ${W} ${U}`),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)}}},Aq={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=U0()[$.name];if(!Z)console.error(`❌ 服务器 "${$.name}" 不存在`),process.exit(1);console.log(`
1704
1712
  服务器: ${$.name}
1705
- `),console.log(JSON.stringify(Z,null,2))}catch(Y){console.error(`❌ 获取失败: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}},iJ={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 z1().addMcpServer($.name,Y,{scope:Z?"global":"project"});let X=Z?E6.join(k5.homedir(),".blade","config.json"):E6.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)}}},P5={command:"mcp",describe:"管理 MCP 服务器",builder:($)=>{return $.command(dJ).command(uJ).command(cJ).command(lJ).command(iJ).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)pJ(),process.exit(0)}};z2();function yK($){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 S1.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 oY(){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 yK(Q),await Q.parse(),!0}catch(Z){console.error(`Print mode error: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}import{execSync as fK}from"child_process";import*as f2 from"fs/promises";import*as B2 from"path";import sY from"semver";import{fileURLToPath as EK}from"url";var l9="blade-code",kK="https://cdn.jsdelivr.net/npm/blade-code@latest/CHANGELOG.md",tY=B2.join(process.env.HOME||process.env.USERPROFILE||".",".blade"),eY=B2.join(tY,"version-cache.json"),PK=3600000,TK=`https://registry.npmjs.org/${l9}/latest`;async function SK(){try{if(process.env.BLADE_VERSION)return process.env.BLADE_VERSION;let $=EK(import.meta.url),Y=B2.dirname($),Z=[B2.join(Y,"..","..","package.json"),B2.join(Y,"..","package.json"),B2.join(process.cwd(),"package.json")];for(let X of Z)try{let Q=await f2.readFile(X,"utf-8"),J=JSON.parse(Q);if(J.name===l9&&J.version)return J.version}catch{}return"unknown"}catch{return"unknown"}}async function $Z(){try{let $=await f2.readFile(eY,"utf-8"),Y=JSON.parse($);if(Date.now()-Y.checkedAt<PK)return Y;return{...Y,checkedAt:0}}catch{return null}}async function YZ($){try{await f2.mkdir(tY,{recursive:!0}),await f2.writeFile(eY,JSON.stringify($,null,2))}catch{}}async function CK(){try{let $=new AbortController,Y=setTimeout(()=>$.abort(),5000),Z=await fetch(TK,{signal:$.signal,headers:{Accept:"application/json"}});if(clearTimeout(Y),!Z.ok)return null;return(await Z.json()).version||null}catch{return null}}async function i9($=!1){let Y=await SK(),Z=kK;if(Y==="unknown")return{currentVersion:Y,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:Z,error:"Unable to determine current version"};let X=await $Z(),Q=X?.skipUntilVersion,J=null;if(!$&&X&&X.checkedAt>0)J=X.latestVersion;else if(J=await CK(),J)await YZ({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=sY.gt(J,Y),G=q;if(q&&Q)G=sY.gt(J,Q);return{currentVersion:Y,latestVersion:J,hasUpdate:q,shouldPrompt:G,releaseNotesUrl:Z}}async function ZZ($){let Y=await $Z();await YZ({latestVersion:Y?.latestVersion||$,checkedAt:Y?.checkedAt||Date.now(),skipUntilVersion:$})}function r9(){return`npm install -g ${l9}@latest`}async function XZ(){let{spawn:$}=await import("child_process");return new Promise((Y)=>{let Z=r9(),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 QZ(){try{let $=await i9();return $.shouldPrompt?$:null}catch{return null}}var JZ={command:"update",describe:"Check for updates and install if available",handler:async()=>{console.log("\uD83D\uDD0D Checking for updates...");try{let $=await i9(!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{fK("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)}}};A1();A1();var Y2=i("Service");class A${static instance=null;cleanupHandlers=[];isShuttingDown=!1;initialized=!1;constructor(){}static getInstance(){if(!A$.instance)A$.instance=new A$;return A$.instance}initialize(){if(this.initialized){Y2.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",()=>{Y2.info("[GracefulShutdown] 收到 SIGTERM 信号"),this.shutdown("SIGTERM",0)}),process.env.BLADE_NON_INTERACTIVE==="true")process.on("SIGINT",()=>{Y2.info("[GracefulShutdown] 收到 SIGINT 信号(非交互模式)"),this.shutdown("SIGINT",0)});this.initialized=!0,Y2.debug("[GracefulShutdown] 全局错误处理器已初始化")}registerCleanup($){return this.cleanupHandlers.push($),Y2.debug(`[GracefulShutdown] 注册清理函数,当前共 ${this.cleanupHandlers.length} 个`),()=>{let Y=this.cleanupHandlers.indexOf($);if(Y!==-1)this.cleanupHandlers.splice(Y,1),Y2.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){Y2.debug("[GracefulShutdown] 已在退出过程中,跳过重复退出");return}this.isShuttingDown=!0,Y2.info(`[GracefulShutdown] 开始优雅退出 (原因: ${$})`);let Z=5000,X=new Promise((Q,J)=>{setTimeout(()=>{J(Error(`清理超时 (${Z}ms)`))},Z)});try{let Q=this.runCleanupHandlers();await Promise.race([Q,X]),Y2.info("[GracefulShutdown] 所有清理函数执行完成")}catch(Q){console.error("[GracefulShutdown] 清理过程中发生错误:",Q)}finally{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 h2=()=>{return A$.getInstance()},qZ=($)=>{return h2().registerCleanup($)},GZ=()=>{h2().initialize()};z$();s2();J4();Y$();import{useMemoizedFn as uQ}from"ahooks";import{useEffect as SO,useState as S7}from"react";K2();_1();F$();Y0();A1();W4();import{useMemoizedFn as e1}from"ahooks";import{Box as l2,useApp as EO}from"ink";import{useEffect as i2,useRef as d4}from"react";import{useShallow as _R}from"zustand/react/shallow";_1();_1();import{useStore as hK}from"zustand";function K1($){return hK(c$,$)}Y0();var xK=[],UZ=()=>K1(($)=>$.session.sessionId),U4=()=>K1(($)=>$.session.messages),HZ=()=>K1(($)=>$.session.clearCount),OZ=()=>K1(($)=>$.session.isCompacting);var b$=()=>K1(($)=>$.session.actions);var FZ=()=>K1(($)=>{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 zZ=()=>K1(($)=>$.app.initializationStatus),_Z=()=>K1(($)=>$.app.initializationError),H4=()=>K1(($)=>$.app.activeModal),NZ=()=>K1(($)=>$.app.todos),BZ=()=>K1(($)=>$.app.modelEditorTarget),LZ=()=>K1(($)=>$.app.sessionSelectorData),wZ=()=>K1(($)=>$.app.awaitingSecondCtrlC),L2=()=>K1(($)=>$.app.actions),O4=()=>K1(($)=>$.app.initializationStatus==="ready");var AZ=()=>K1(($)=>$.app.todos.length>0);var R$=()=>K1(($)=>$.config.config?.permissionMode||"default"),bZ=()=>K1(($)=>$.config.config?.models??xK),F4=()=>K1(($)=>{let Y=$.config.config;if(!Y)return;let Z=Y.currentModelId;return Y.models.find((Q)=>Q.id===Z)??Y.models[0]}),RZ=()=>K1(($)=>$.config.config?.currentModelId);var H0=()=>K1(($)=>$.focus.currentFocus);var VZ=()=>K1(($)=>$.focus.actions);var m0=()=>K1(($)=>$.command.isProcessing);var DZ=()=>K1(($)=>$.command.actions),IZ=()=>K1(($)=>$.command.pendingCommands);var MZ=()=>K1(($)=>$.app.thinkingModeEnabled),jZ=()=>K1(($)=>$.session.currentThinkingContent),vZ=()=>K1(($)=>$.session.thinkingExpanded),yZ=()=>K1(($)=>$.session.historyExpanded),EZ=()=>K1(($)=>$.session.expandedMessageCount);_1();A1();A4();import{useMemoizedFn as Y7}from"ahooks";import{useEffect as hW,useRef as xW}from"react";_1();z2();import{useMemoizedFn as wX}from"ahooks";import{useRef as fW}from"react";function AX($){let Y=fW(void 0),Z=wX(async()=>{let Q=await S1.create({systemPrompt:$.systemPrompt,appendSystemPrompt:$.appendSystemPrompt,maxTurns:$.maxTurns});return Y.current=Q,Q}),X=wX(()=>{if(Y.current)Y.current=void 0});return{agentRef:Y,createAgent:Z,cleanupAgent:X}}var pW=i("UI");function gW($,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_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 process.exit(0),!0;default:return!1}}function mW($){return typeof $==="object"&&$!==null&&$.action==="invoke_skill"&&typeof $.skillName==="string"}function dW($){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 bX=($,Y,Z,X)=>{let Q=m0(),J=U4(),q=UZ(),G=R$(),K=b$(),W=L2(),U=DZ(),H=xW(!1),{createAgent:O,cleanupAgent:F}=AX({systemPrompt:$,appendSystemPrompt:Y,maxTurns:X});hW(()=>{return()=>{F()}},[F]);let N=Y7(()=>{if(!Q)return;if(!H.current)K.addAssistantMessage("✋ 任务已停止"),H.current=!0;U.abort(),W.setTodos([])}),z=Y7(async(B)=>{let{text:_}=B,b=!1;try{if(L4(_)){await I6();let k=U.createAbortController(),f={cwd:process.cwd(),signal:k.signal},A=await w4(_,f);if(A.message){if(gW(A.message,A.data,W,K))return{success:!0}}let T=!1;if(mW(A.data)){let{skillName:Y1,skillArgs:r}=A.data,t=r?`Please use the "${Y1}" skill to help me with: ${r}`:`Please use the "${Y1}" skill.`;K.addUserMessage(t),b=!0,T=!0,B={displayText:t,text:t,images:[],parts:[{type:"text",text:t}]}}if(!T){if(!A.success&&A.error)return K.addAssistantMessage(`❌ ${A.error}`),{success:A.success,output:A.message,error:A.error,metadata:A.data};let Y1=A.message;if(A.success&&typeof Y1==="string"&&Y1.trim()!=="")K.addAssistantMessage(Y1);return{success:A.success,output:A.message,error:A.error,metadata:A.data}}}if(!b)K.addUserMessage(B.displayText);let I=dW(B),w=await O(),M=U.createAbortController(),V={messages:J.map((k)=>({role:k.role,content:k.content})),userId:"cli-user",sessionId:q,workspaceRoot:process.cwd(),signal:M.signal,confirmationHandler:Z,permissionMode:G},D={onThinking:(k)=>{K.setCurrentThinkingContent(k)},onContent:(k)=>{if(k.trim())K.addAssistantMessage(k),K.setCurrentThinkingContent(null)},onToolStart:(k)=>{if(k.type!=="function")return;if(k.function.name==="TodoWrite")return;try{let f=JSON.parse(k.function.arguments),A=K6(k.function.name,f);K.addToolMessage(A,{toolName:k.function.name,phase:"start",summary:A,params:f})}catch(f){pW.error("[useCommandHandler] onToolStart error:",f)}},onToolResult:async(k,f)=>{if(k.type!=="function")return;if(!f?.metadata?.summary)return;let A=GX(k.function.name,f)?f.displayContent:void 0;K.addToolMessage(f.metadata.summary,{toolName:k.function.name,phase:"complete",summary:f.metadata.summary,detail:A})},onTokenUsage:(k)=>{K.updateTokenUsage(k)},onCompacting:(k)=>{if(K.setCompacting(k),!k)K.resetTokenUsage()},onTurnLimitReached:Z?async(k)=>{let f=await Z.requestConfirmation({type:"maxTurnsExceeded",title:"对话轮次上限",message:`已进行 ${k.turnsCount} 轮对话。是否继续?`,risks:["继续执行可能导致更长的等待时间","可能产生更多的 API 费用"]});return{continue:f.approved,reason:f.reason}}:void 0},y=await w.chat(I,V,D);if(!y||y.trim()===""){if(!H.current)K.addAssistantMessage("⏹ 已取消");return{success:!0,output:"已取消"}}return{success:!0,output:y}}catch(I){if(H.current)return{success:!1,error:"aborted"};let w=I instanceof Error?I.message:"未知错误",M=w.includes("can only concatenate str")||w.includes("image_url")||w.includes("multimodal")||w.includes("vision")||w.includes("does not support images"),V=w;if(M)V="当前模型不支持图片理解功能。请切换到支持视觉能力的模型(如 Claude 4.5、GPT-5.2、Gemini 3 Pro、Qwen3-VL-Plus 等)后重试。";let D={success:!1,error:V};return K.addAssistantMessage(`❌ ${V}`),D}}),L=Y7(async(B)=>{if(!B.text.trim()&&B.images.length===0)return;if(Q){U.enqueueCommand({displayText:B.displayText,text:B.text,images:B.images,parts:B.parts});return}W.setTodos([]),H.current=!1,U.setProcessing(!0);try{let _=await z(B);if(!_.success&&_.error&&_.error!=="aborted")K.setError(_.error)}catch(_){if(_ instanceof Error&&(_.name==="AbortError"||_.message.includes("aborted")));else{let b=_ instanceof Error?_.message:"未知错误";K.setError(`执行失败: ${b}`)}}finally{U.setProcessing(!1),U.clearAbortController(),K.setCurrentThinkingContent(null);let _=U.dequeueCommand();if(_)setTimeout(()=>L({displayText:_.displayText,text:_.text,images:_.images,parts:_.parts}),100)}});return{executeCommand:L,handleAbort:N,isProcessing:Q}};import{useMemoizedFn as b4}from"ahooks";import{useState as RX}from"react";var VX=()=>{let[$,Y]=RX([]),[Z,X]=RX(-1),Q=b4((K,W)=>{let U={display:K,pasteMappings:W?new Map(W):new Map};Y((H)=>[...H,U]),X(-1)}),J=b4(()=>{if($.length===0)return null;let K=Z===-1?$.length-1:Math.max(0,Z-1);return X(K),$[K]||null}),q=b4(()=>{if(Z===-1)return null;let K=Z+1;if(K>=$.length)return X(-1),null;else return X(K),$[K]||null}),G=b4(()=>{X(-1)});return{commandHistory:$,historyIndex:Z,addToHistory:Q,getPreviousCommand:J,getNextCommand:q,resetHistoryIndex:G}};import{useMemoizedFn as DX}from"ahooks";import{useMemo as uW,useState as cW}from"react";var IX=()=>{let[$,Y]=cW({isVisible:!1,details:null,resolver:null}),Z=DX((J)=>{return new Promise((q)=>{Y({isVisible:!0,details:J,resolver:q})})}),X=DX((J)=>{if($.resolver)$.resolver(J);Y({isVisible:!1,details:null,resolver:null})}),Q=uW(()=>({requestConfirmation:Z}),[Z]);return{confirmationState:$,confirmationHandler:Q,handleResponse:X}};import{useMemoizedFn as p2}from"ahooks";import{useRef as MX,useState as lW}from"react";var R4="␞",V4="␟";function D4($){return`${R4}PASTE:${$}:`}function Z7(){return V4}var OD=new RegExp(`${R4}PASTE:(\\d+):[\\s\\S]*?${V4}`,"g");function iW($){return $.includes(R4)&&$.includes(V4)}function jX($="",Y=0){let[Z,X]=lW({value:$,cursorPosition:Y}),Q=MX(0),J=MX(new Map),q=p2((F)=>{X((N)=>({value:F,cursorPosition:N.cursorPosition}));for(let N of J.current.keys()){let z=D4(N);if(!F.includes(z))J.current.delete(N)}}),G=p2((F)=>{X((N)=>({...N,cursorPosition:Math.max(0,Math.min(F,N.value.length))}))}),K=p2(()=>{X({value:"",cursorPosition:0}),J.current.clear()}),W=p2((F)=>{Q.current+=1;let N=Q.current;return J.current.set(N,{type:"text",data:F}),N}),U=p2((F,N)=>{Q.current+=1;let z=Q.current;return J.current.set(z,{type:"image",data:F,mimeType:N}),z}),H=p2((F)=>{for(let[N,z]of F)if(J.current.set(N,z),N>=Q.current)Q.current=N}),O=p2((F)=>{let N=[],z=[];if(!iW(F)){let y=F.trim();if(y)z.push({type:"text",text:y});return{displayText:F,text:F,images:N,parts:z}}let L=new RegExp(`${R4}PASTE:(\\d+):[\\s\\S]*?${V4}`,"g"),B=Array.from(F.matchAll(L)),_=0,b="",I="";for(let y of B){let k=y.index,f=k+y[0].length,A=parseInt(y[1],10),T=J.current.get(A);if(k>_){let Y1=F.slice(_,k);z.push({type:"text",text:Y1}),b+=Y1,I+=Y1}if(!T)b+=y[0],I+=y[0],z.push({type:"text",text:y[0]});else if(T.type==="text")b+=T.data,I+=T.data,z.push({type:"text",text:T.data});else{let Y1={id:A,base64:T.data,mimeType:T.mimeType};N.push(Y1),z.push({type:"image",...Y1}),I+=`[Image #${A}]`}_=f}if(_<F.length){let y=F.slice(_);z.push({type:"text",text:y}),b+=y,I+=y}let w=[];for(let y of z)if(y.type==="text"&&w.length>0&&w[w.length-1].type==="text")w[w.length-1].text+=y.text;else w.push(y);let M=0,V=w.length;while(M<w.length&&w[M].type==="text"&&w[M].text.trim()==="")M++;while(V>M&&w[V-1].type==="text"&&w[V-1].text.trim()==="")V--;let D=w.slice(M,V);return{displayText:I.trim(),text:b.trim(),images:N,parts:D}});return{value:Z.value,cursorPosition:Z.cursorPosition,setValue:q,setCursorPosition:G,clear:K,pasteMap:J.current,addPasteMapping:W,addImagePasteMapping:U,restorePasteMappings:H,resolveInput:O}}A1();A4();import{useMemoizedFn as TX}from"ahooks";import{useInput as eW}from"ink";import{useEffect as SX,useRef as CX,useState as q7}from"react";q4();t6();import{useMemoizedFn as _D}from"ahooks";import rW from"fast-glob";import aW from"fuse.js";import{useEffect as vX,useMemo as X7,useState as Q7}from"react";var I$=null,nW=5000;function oW($,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 sW=[...p0.map(($)=>`${$}/**`),...p0,...l8.map(($)=>`**/${$}`)];function yX($,Y,Z={}){let{cwd:X=process.cwd(),maxSuggestions:Q=15,ignorePatterns:J=sW,debounceDelay:q=300,fuzzyMatch:G=!0}=Z,[K,W]=Q7([]),[U,H]=Q7(!1),[O,F]=Q7(0),N=X7(()=>JSON.stringify(J),[J]),z=X7(()=>{if(Y===void 0)return{hasQuery:!1,query:"",startIndex:-1,endIndex:-1,quoted:!1};return oW($,Y)},[$,Y]);vX(()=>{if(!$.includes("@")){W([]),H(!1);return}let B=Date.now();if(I$&&I$.cwd===X&&I$.ignoreKey===N&&B-I$.timestamp<nW){W(I$.files),H(!1);return}let _=!1,I=setTimeout(async()=>{H(!0);try{let M=(await rW("**/*",{cwd:X,dot:!1,followSymbolicLinks:!1,onlyFiles:!1,markDirectories:!0,unique:!0,ignore:J})).map((V)=>V.replace(/\\/g,"/"));if(!_)W(M),I$={cwd:X,ignoreKey:N,files:M,timestamp:B}}catch(w){if(console.error("Failed to load files for @ completion:",w),!_)W([])}finally{if(!_)H(!1)}},q);return()=>{_=!0,clearTimeout(I)}},[$,X,q,N]);let L=X7(()=>{if(!z.hasQuery||K.length===0)return[];let B=z.query.toLowerCase();if(B==="")return K.slice(0,Q);if(G)return new aW(K,{threshold:0.4,ignoreLocation:!0,minMatchCharLength:1}).search(B).slice(0,Q).map((I)=>I.item);return K.filter((_)=>_.toLowerCase().includes(B)).slice(0,Q)},[z,K,Q,G]);return vX(()=>{F(0)},[L]),{...z,suggestions:L,selectedIndex:O,loading:U}}function tW($,Y=!1){if($.includes(" ")||Y)return`@"${$}"`;return`@${$}`}function J7($,Y,Z){if(!Y.hasQuery)return{newInput:$,newCursorPos:$.length};let X=tW(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 EX}from"ahooks";import{useEffect as kX,useRef as PX}from"react";_1();var k1=($,Y)=>{let Z=PX(!1),X=PX(null),Q=EX(()=>{if(X.current)clearTimeout(X.current);X.current=setTimeout(()=>{R0().setAwaitingSecondCtrlC(!1),Z.current=!1,X.current=null},3000)}),J=()=>{h2().shutdown("SIGINT",0)},q=EX(()=>{if(!Z.current){if(Z.current=!0,$&&Y)Y();R0().setAwaitingSecondCtrlC(!0),Q()}else{if(X.current)clearTimeout(X.current),X.current=null;R0().setAwaitingSecondCtrlC(!1),J()}});return kX(()=>{if($){if(R0().setAwaitingSecondCtrlC(!1),Z.current=!1,X.current)clearTimeout(X.current),X.current=null}},[$]),kX(()=>{return()=>{if(X.current)clearTimeout(X.current)}},[]),q};var I4=i("UI"),fX=($,Y,Z,X,Q,J,q,G,K,W)=>{let H=H0()==="main-input",O=$.value,F=$.setValue,N=$.cursorPosition,z=b$(),L=L2(),B=F4(),_=B?L$(B):!1,[b,I]=q7(!1),[w,M]=q7([]),[V,D]=q7(0),y=yX(O,N,{cwd:process.cwd(),maxSuggestions:10}),k=k1(q||!1,J),f=CX(0),A=500,T=CX(!1);SX(()=>{if(q)T.current=!1},[q]),SX(()=>{if(y.hasQuery&&y.suggestions.length>0){let t=y.suggestions.map((p)=>({command:p,description:p.endsWith("/")?`Directory: ${p}`:`File: ${p}`,matchScore:1}));M(t),I(!0),D(0)}else if(O.startsWith("/"))if(O.includes(" "))I(!1),M([]);else{let p=LX(O);M(p),I(p.length>0),D(0)}else I(!1),M([])},[O,y.hasQuery,y.suggestions]);let Y1=TX(()=>{z.clearMessages(),z.setError(null)}),r=TX(()=>{I4.debug("[DIAG] handleSubmit called:",{input:O,showSuggestions:b});let t=O.trim();if(t){let p=$.resolveInput(t);I4.debug("[DIAG] Submitting command:",{displayText:t,textLength:p.text.length,imageCount:p.images.length}),I(!1),M([]);let P0=$.pasteMap.size>0?new Map($.pasteMap):new Map;Q(t,P0),$.clear(),Y(p),I4.debug("[DIAG] Command submitted to onSubmit callback")}else I4.debug("[DIAG] Empty command, not submitting")});return eW((t,p)=>{if(t==="?"&&!O){K?.(),setTimeout(()=>$.clear(),0);return}if(p.backspace||p.delete||p.leftArrow||p.rightArrow||p.pageUp||p.pageDown||!p.ctrl&&!p.meta&&!p.escape&&!p.tab&&!p.upArrow&&!p.downArrow&&!p.return&&!(t==="?"&&!O))return;if(p.ctrl&&t==="c"||p.meta&&t==="c"||p.ctrl&&t==="d"||p.meta&&t==="d"){k();return}if(p.ctrl&&t==="l"||p.meta&&t==="l"){Y1();return}if(p.ctrl&&t==="t"||p.meta&&t==="t"){z.toggleThinkingExpanded();return}if(p.ctrl&&t==="o"||p.meta&&t==="o"){z.toggleHistoryExpanded();return}if(p.escape){if(W)K?.();else if(q&&J){if(T.current)return;T.current=!0,J()}else if(b)I(!1),M([]);else if(O){let G1=Date.now();if(G1-f.current<500)$.clear(),f.current=0;else f.current=G1}return}if(p.tab&&p.shift){G?.();return}if(p.tab){if(b&&w.length>0){let G1=w[V].command;if(y.hasQuery&&y.suggestions.includes(G1)){let{newInput:M1,newCursorPos:a0}=J7(O,y,G1);F(M1),$.setCursorPosition(a0)}else{let M1=G1+" ";F(M1),$.setCursorPosition(M1.length)}I(!1),M([])}else if(_)L.toggleThinkingMode();return}if(p.return){if(b&&w.length>0){let G1=w[V].command;if(y.hasQuery&&y.suggestions.includes(G1)){let{newInput:M1,newCursorPos:a0}=J7(O,y,G1);F(M1),$.setCursorPosition(a0)}else{let M1=G1+" ";F(M1),$.setCursorPosition(M1.length)}I(!1),M([])}else r();return}if(p.upArrow){if(b&&w.length>0){let G1=w.length-1;D((M1)=>M1>0?M1-1:G1)}else{let G1=Z();if(G1){if(G1.pasteMappings.size>0)$.restorePasteMappings(G1.pasteMappings);F(G1.display),$.setCursorPosition(G1.display.length)}}return}if(p.downArrow){if(b&&w.length>0){let G1=w.length-1;D((M1)=>M1<G1?M1+1:0)}else{let G1=X();if(G1){if(G1.pasteMappings.size>0)$.restorePasteMappings(G1.pasteMappings);F(G1.display),$.setCursorPosition(G1.display.length)}}return}},{isActive:H}),{handleSubmit:r,showSuggestions:b,suggestions:w,selectedSuggestionIndex:V}};import QU from"ansi-escapes";import{useStdout as JU}from"ink";import{useCallback as qU,useEffect as GU,useRef as KU}from"react";import{useEffect as $U,useState as YU}from"react";import{useStdout as ZU}from"ink";import{debounce as XU}from"lodash-es";function A2($=200){let{stdout:Y}=ZU(),[Z,X]=YU(Y.columns||80);return $U(()=>{let Q=XU(()=>{X(Y.columns||80)},$);return Q(),Y.on("resize",Q),()=>{Y.off("resize",Q),Q.cancel()}},[Y,$]),Z}function hX(){let{stdout:$}=JU(),Y=A2(),Z=KU(!0),X=K1((J)=>J.session.actions.incrementClearCount),Q=qU(()=>{if($)$.write(QU.clearTerminal);X()},[$,X]);return GU(()=>{if(Z.current){Z.current=!1;return}let J=setTimeout(()=>{Q()},300);return()=>{clearTimeout(J)}},[Y,Q]),{refreshStatic:Q}}z2();import{MultiSelect as WU}from"@inkjs/ui";import{useMemoizedFn as M4}from"ahooks";import{Box as c,Text as x,useFocus as UU,useFocusManager as HU,useInput as gX}from"ink";import j4 from"ink-select-input";import OU from"ink-spinner";import H6 from"ink-text-input";import xX from"node:fs";import FU from"node:os";import G7 from"node:path";import{useEffect as pX,useState as j$}from"react";import{jsxDEV as j}from"react/jsx-dev-runtime";var zU=[{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"}],_U=[{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 NU($){if(!$||$.trim()==="")return"名称不能为空";if(!/^[a-z0-9-]+$/.test($))return"名称只能包含小写字母、数字和连字符";if($.startsWith("-")||$.endsWith("-"))return"名称不能以连字符开头或结尾";return null}function O6({onComplete:$,onCancel:Y,initialConfig:Z}){let[X,Q]=j$(Z?"name":"mode"),[J,q]=j$({name:Z?.name||"",description:Z?.description||"",tools:Z?.tools||[],color:Z?.color,location:Z?.location||"project",systemPrompt:Z?.systemPrompt||""}),[G,K]=j$(""),[W,U]=j$(!1),[H,O]=j$(""),[F,N]=j$(Z?"edit":"manual"),{focus:z}=HU(),B={manual:["mode","name","description","tools","color","location","systemPrompt","confirm"],ai:["mode","aiPrompt","aiGenerating","confirm"],edit:["name","description","tools","color","location","systemPrompt","confirm"]}[F];pX(()=>{if(X==="name"||X==="description"||X==="systemPrompt"||X==="aiPrompt")return;z(`step-${X}`)},[X,z]);let _=M4(()=>{let V=B.indexOf(X);if(V<B.length-1)Q(B[V+1])}),b=M4(()=>{if(H)O("");if(X==="confirm"&&F==="ai"){Q("aiPrompt");return}let V=B.indexOf(X);if(V>0)Q(B[V-1]);else Y()}),I=M4(async()=>{U(!0),O("");try{let V=await S1.create(),D=`你是一个 Subagent 配置生成专家。用户会描述他们想要创建的 agent,你需要根据描述生成一个完整的 agent 配置。
1713
+ `),console.log(JSON.stringify(Z,null,2))}catch(Y){console.error(`❌ 获取失败: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}},bq={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 F1().addMcpServer($.name,Y,{scope:Z?"global":"project"});let X=Z?h6.join(c5.homedir(),".blade","config.json"):h6.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)}}},l5={command:"mcp",describe:"管理 MCP 服务器",builder:($)=>{return $.command(Bq).command(wq).command(Lq).command(Aq).command(bq).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)zq(),process.exit(0)}};w2();function KW($){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 f1.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 WZ(){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 KW(Q),await Q.parse(),!0}catch(Z){console.error(`Print mode error: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}import{execSync as _W}from"child_process";import*as g2 from"fs/promises";import*as b2 from"path";import UZ from"semver";import{fileURLToPath as WW}from"url";var Q7="blade-code",UW="https://cdn.jsdelivr.net/npm/blade-code@latest/CHANGELOG.md",HZ=b2.join(process.env.HOME||process.env.USERPROFILE||".",".blade"),OZ=b2.join(HZ,"version-cache.json"),HW=3600000,OW=`https://registry.npmjs.org/${Q7}/latest`;async function FW(){try{if(process.env.BLADE_VERSION)return process.env.BLADE_VERSION;let $=WW(import.meta.url),Y=b2.dirname($),Z=[b2.join(Y,"..","..","package.json"),b2.join(Y,"..","package.json"),b2.join(process.cwd(),"package.json")];for(let X of Z)try{let Q=await g2.readFile(X,"utf-8"),J=JSON.parse(Q);if(J.name===Q7&&J.version)return J.version}catch{}return"unknown"}catch{return"unknown"}}async function FZ(){try{let $=await g2.readFile(OZ,"utf-8"),Y=JSON.parse($);if(Date.now()-Y.checkedAt<HW)return Y;return{...Y,checkedAt:0}}catch{return null}}async function zZ($){try{await g2.mkdir(HZ,{recursive:!0}),await g2.writeFile(OZ,JSON.stringify($,null,2))}catch{}}async function zW(){try{let $=new AbortController,Y=setTimeout(()=>$.abort(),5000),Z=await fetch(OW,{signal:$.signal,headers:{Accept:"application/json"}});if(clearTimeout(Y),!Z.ok)return null;return(await Z.json()).version||null}catch{return null}}async function J7($=!1){let Y=await FW(),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 FZ(),Q=X?.skipUntilVersion,J=null;if(!$&&X&&X.checkedAt>0)J=X.latestVersion;else if(J=await zW(),J)await zZ({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=UZ.gt(J,Y),G=q;if(q&&Q)G=UZ.gt(J,Q);return{currentVersion:Y,latestVersion:J,hasUpdate:q,shouldPrompt:G,releaseNotesUrl:Z}}async function _Z($){let Y=await FZ();await zZ({latestVersion:Y?.latestVersion||$,checkedAt:Y?.checkedAt||Date.now(),skipUntilVersion:$})}function q7(){return`npm install -g ${Q7}@latest`}async function NZ(){let{spawn:$}=await import("child_process");return new Promise((Y)=>{let Z=q7(),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 BZ(){try{let $=await J7();return $.shouldPrompt?$:null}catch{return null}}var wZ={command:"update",describe:"Check for updates and install if available",handler:async()=>{console.log("\uD83D\uDD0D Checking for updates...");try{let $=await J7(!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{_W("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)}}};B1();B1();function LZ(){process.stdout.write("\x1B[?25h"),process.stdout.write("\x1B[0m")}var J2=c("Service");class V${static instance=null;cleanupHandlers=[];isShuttingDown=!1;initialized=!1;constructor(){}static getInstance(){if(!V$.instance)V$.instance=new V$;return V$.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] 开始优雅退出 (原因: ${$})`);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{LZ(),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 m2=()=>{return V$.getInstance()},AZ=($)=>{return m2().registerCleanup($)},bZ=()=>{m2().initialize()};var D$=($=0)=>{LZ(),process.exit($)};B$();Y$();O4();J$();import{useMemoizedFn as QJ}from"ahooks";import{useEffect as ZF,useState as n7}from"react";F2();z1();N$();Q0();B1();import{useMemoizedFn as Y0}from"ahooks";import{Box as n2,useApp as tO}from"ink";import{useEffect as o2,useRef as r4}from"react";N4();O2();import{useShallow as eR}from"zustand/react/shallow";z1();z1();import{useStore as NW}from"zustand";function q1($){return NW(r$,$)}Q0();var BW=[],DZ=()=>q1(($)=>$.session.sessionId),B4=()=>q1(($)=>$.session.messages),IZ=()=>q1(($)=>$.session.clearCount),MZ=()=>q1(($)=>$.session.isCompacting);var I$=()=>q1(($)=>$.session.actions);var jZ=()=>q1(($)=>{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 vZ=()=>q1(($)=>$.app.initializationStatus),yZ=()=>q1(($)=>$.app.initializationError),w4=()=>q1(($)=>$.app.activeModal),EZ=()=>q1(($)=>$.app.todos),kZ=()=>q1(($)=>$.app.modelEditorTarget),PZ=()=>q1(($)=>$.app.sessionSelectorData),TZ=()=>q1(($)=>$.app.awaitingSecondCtrlC),R2=()=>q1(($)=>$.app.actions),L4=()=>q1(($)=>$.app.initializationStatus==="ready");var SZ=()=>q1(($)=>$.app.todos.length>0);var M$=()=>q1(($)=>$.config.config?.permissionMode||"default"),CZ=()=>q1(($)=>$.config.config?.models??BW),A4=()=>q1(($)=>{let Y=$.config.config;if(!Y)return;let Z=Y.currentModelId;return Y.models.find((Q)=>Q.id===Z)??Y.models[0]}),fZ=()=>q1(($)=>$.config.config?.currentModelId);var P1=()=>q1(($)=>{let Y=$.config.config?.theme??"default";if(V1.getCurrentThemeName()!==Y)try{V1.setTheme(Y)}catch{}return V1.getTheme()});var z0=()=>q1(($)=>$.focus.currentFocus);var hZ=()=>q1(($)=>$.focus.actions);var i0=()=>q1(($)=>$.command.isProcessing);var xZ=()=>q1(($)=>$.command.actions),pZ=()=>q1(($)=>$.command.pendingCommands);var gZ=()=>q1(($)=>$.app.thinkingModeEnabled),mZ=()=>q1(($)=>$.session.currentThinkingContent),dZ=()=>q1(($)=>$.session.thinkingExpanded),uZ=()=>q1(($)=>$.session.historyExpanded),cZ=()=>q1(($)=>$.session.expandedMessageCount);z1();B1();import{useMemoizedFn as z7}from"ahooks";import{useEffect as NU,useRef as BU}from"react";j4();z1();w2();import{useMemoizedFn as CX}from"ahooks";import{useRef as _U}from"react";function fX($){let Y=_U(void 0),Z=CX(async()=>{let Q=await f1.create({systemPrompt:$.systemPrompt,appendSystemPrompt:$.appendSystemPrompt,maxTurns:$.maxTurns});return Y.current=Q,Q}),X=CX(()=>{if(Y.current)Y.current=void 0});return{agentRef:Y,createAgent:Z,cleanupAgent:X}}var wU=c("UI");function LU($,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_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 D$(0),!0;default:return!1}}function AU($){return typeof $==="object"&&$!==null&&$.action==="invoke_skill"&&typeof $.skillName==="string"}function bU($){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 hX=($,Y,Z,X)=>{let Q=i0(),J=B4(),q=DZ(),G=M$(),K=I$(),W=R2(),U=xZ(),H=BU(!1),{createAgent:O,cleanupAgent:F}=fX({systemPrompt:$,appendSystemPrompt:Y,maxTurns:X});NU(()=>{return()=>{F()}},[F]);let z=z7(()=>{if(!Q)return;if(!H.current)K.addAssistantMessage("✋ 任务已停止"),H.current=!0;U.abort(),W.setTodos([])}),_=z7(async(B)=>{let{text:N}=B,I=!1;try{if(I4(N)){await P6();let k=U.createAbortController(),f={cwd:process.cwd(),signal:k.signal},R=await M4(N,f);if(R.message){if(LU(R.message,R.data,W,K))return{success:!0}}let T=!1;if(AU(R.data)){let{skillName:Y1,skillArgs:r}=R.data,t=r?`Please use the "${Y1}" skill to help me with: ${r}`:`Please use the "${Y1}" skill.`;K.addUserMessage(t),I=!0,T=!0,B={displayText:t,text:t,images:[],parts:[{type:"text",text:t}]}}if(!T){if(!R.success&&R.error)return K.addAssistantMessage(`❌ ${R.error}`),{success:R.success,output:R.message,error:R.error,metadata:R.data};let Y1=R.message;if(R.success&&typeof Y1==="string"&&Y1.trim()!=="")K.addAssistantMessage(Y1);return{success:R.success,output:R.message,error:R.error,metadata:R.data}}}if(!I)K.addUserMessage(B.displayText);let M=bU(B),A=await O(),D=U.createAbortController(),L={messages:J.map((k)=>({role:k.role,content:k.content})),userId:"cli-user",sessionId:q,workspaceRoot:process.cwd(),signal:D.signal,confirmationHandler:Z,permissionMode:G},V={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 f=JSON.parse(k.function.arguments),R=F6(k.function.name,f);K.addToolMessage(R,{toolName:k.function.name,phase:"start",summary:R,params:f})}catch(f){wU.error("[useCommandHandler] onToolStart error:",f)}},onToolResult:async(k,f)=>{if(k.type!=="function")return;if(!f?.metadata?.summary)return;let R=VX(k.function.name,f)?f.displayContent:void 0;K.addToolMessage(f.metadata.summary,{toolName:k.function.name,phase:"complete",summary:f.metadata.summary,detail:R})},onTokenUsage:(k)=>{K.updateTokenUsage(k)},onCompacting:(k)=>{if(K.setCompacting(k),!k)K.resetTokenUsage()},onTurnLimitReached:Z?async(k)=>{let f=await Z.requestConfirmation({type:"maxTurnsExceeded",title:"对话轮次上限",message:`已进行 ${k.turnsCount} 轮对话。是否继续?`,risks:["继续执行可能导致更长的等待时间","可能产生更多的 API 费用"]});return{continue:f.approved,reason:f.reason}}:void 0},v=await A.chat(M,L,V);if(!v||v.trim()===""){if(!H.current)K.addAssistantMessage("⏹ 已取消");return{success:!0,output:"已取消"}}return{success:!0,output:v}}catch(M){if(H.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"),L=A;if(D)L="当前模型不支持图片理解功能。请切换到支持视觉能力的模型(如 Claude 4.5、GPT-5.2、Gemini 3 Pro、Qwen3-VL-Plus 等)后重试。";let V={success:!1,error:L};return K.addAssistantMessage(`❌ ${L}`),V}}),w=z7(async(B)=>{if(!B.text.trim()&&B.images.length===0)return;if(Q){U.enqueueCommand({displayText:B.displayText,text:B.text,images:B.images,parts:B.parts});return}W.setTodos([]),H.current=!1,U.setProcessing(!0);try{let N=await _(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{U.setProcessing(!1),U.clearAbortController(),K.setCurrentThinkingContent(null);let N=U.dequeueCommand();if(N)setTimeout(()=>w({displayText:N.displayText,text:N.text,images:N.images,parts:N.parts}),100)}});return{executeCommand:w,handleAbort:z,isProcessing:Q}};import{useMemoizedFn as v4}from"ahooks";import{useState as xX}from"react";var pX=()=>{let[$,Y]=xX([]),[Z,X]=xX(-1),Q=v4((K,W)=>{let U={display:K,pasteMappings:W?new Map(W):new Map};Y((H)=>[...H,U]),X(-1)}),J=v4(()=>{if($.length===0)return null;let K=Z===-1?$.length-1:Math.max(0,Z-1);return X(K),$[K]||null}),q=v4(()=>{if(Z===-1)return null;let K=Z+1;if(K>=$.length)return X(-1),null;else return X(K),$[K]||null}),G=v4(()=>{X(-1)});return{commandHistory:$,historyIndex:Z,addToHistory:Q,getPreviousCommand:J,getNextCommand:q,resetHistoryIndex:G}};import{useMemoizedFn as gX}from"ahooks";import{useMemo as RU,useState as VU}from"react";var mX=()=>{let[$,Y]=VU({isVisible:!1,details:null,resolver:null}),Z=gX((J)=>{return new Promise((q)=>{Y({isVisible:!0,details:J,resolver:q})})}),X=gX((J)=>{if($.resolver)$.resolver(J);Y({isVisible:!1,details:null,resolver:null})}),Q=RU(()=>({requestConfirmation:Z}),[Z]);return{confirmationState:$,confirmationHandler:Q,handleResponse:X}};import{useMemoizedFn as u2}from"ahooks";import{useRef as dX,useState as DU}from"react";var y4="␞",E4="␟";function k4($){return`${y4}PASTE:${$}:`}function _7(){return E4}var $I=new RegExp(`${y4}PASTE:(\\d+):[\\s\\S]*?${E4}`,"g");function IU($){return $.includes(y4)&&$.includes(E4)}function uX($="",Y=0){let[Z,X]=DU({value:$,cursorPosition:Y}),Q=dX(0),J=dX(new Map),q=u2((F)=>{X((z)=>({value:F,cursorPosition:z.cursorPosition}));for(let z of J.current.keys()){let _=k4(z);if(!F.includes(_))J.current.delete(z)}}),G=u2((F)=>{X((z)=>({...z,cursorPosition:Math.max(0,Math.min(F,z.value.length))}))}),K=u2(()=>{X({value:"",cursorPosition:0}),J.current.clear()}),W=u2((F)=>{Q.current+=1;let z=Q.current;return J.current.set(z,{type:"text",data:F}),z}),U=u2((F,z)=>{Q.current+=1;let _=Q.current;return J.current.set(_,{type:"image",data:F,mimeType:z}),_}),H=u2((F)=>{for(let[z,_]of F)if(J.current.set(z,_),z>=Q.current)Q.current=z}),O=u2((F)=>{let z=[],_=[];if(!IU(F)){let v=F.trim();if(v)_.push({type:"text",text:v});return{displayText:F,text:F,images:z,parts:_}}let w=new RegExp(`${y4}PASTE:(\\d+):[\\s\\S]*?${E4}`,"g"),B=Array.from(F.matchAll(w)),N=0,I="",M="";for(let v of B){let k=v.index,f=k+v[0].length,R=parseInt(v[1],10),T=J.current.get(R);if(k>N){let Y1=F.slice(N,k);_.push({type:"text",text:Y1}),I+=Y1,M+=Y1}if(!T)I+=v[0],M+=v[0],_.push({type:"text",text:v[0]});else if(T.type==="text")I+=T.data,M+=T.data,_.push({type:"text",text:T.data});else{let Y1={id:R,base64:T.data,mimeType:T.mimeType};z.push(Y1),_.push({type:"image",...Y1}),M+=`[Image #${R}]`}N=f}if(N<F.length){let v=F.slice(N);_.push({type:"text",text:v}),I+=v,M+=v}let A=[];for(let v of _)if(v.type==="text"&&A.length>0&&A[A.length-1].type==="text")A[A.length-1].text+=v.text;else A.push(v);let D=0,L=A.length;while(D<A.length&&A[D].type==="text"&&A[D].text.trim()==="")D++;while(L>D&&A[L-1].type==="text"&&A[L-1].text.trim()==="")L--;let V=A.slice(D,L);return{displayText:M.trim(),text:I.trim(),images:z,parts:V}});return{value:Z.value,cursorPosition:Z.cursorPosition,setValue:q,setCursorPosition:G,clear:K,pasteMap:J.current,addPasteMapping:W,addImagePasteMapping:U,restorePasteMappings:H,resolveInput:O}}B1();j4();import{useMemoizedFn as nX}from"ahooks";import{useInput as PU}from"ink";import{useEffect as oX,useRef as sX,useState as L7}from"react";F4();J4();import{useMemoizedFn as XI}from"ahooks";import MU from"fast-glob";import jU from"fuse.js";import{useEffect as cX,useMemo as N7,useState as B7}from"react";var y$=null,vU=5000;function yU($,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 EU=[...c0.map(($)=>`${$}/**`),...c0,...X9.map(($)=>`**/${$}`)];function lX($,Y,Z={}){let{cwd:X=process.cwd(),maxSuggestions:Q=15,ignorePatterns:J=EU,debounceDelay:q=300,fuzzyMatch:G=!0}=Z,[K,W]=B7([]),[U,H]=B7(!1),[O,F]=B7(0),z=N7(()=>JSON.stringify(J),[J]),_=N7(()=>{if(Y===void 0)return{hasQuery:!1,query:"",startIndex:-1,endIndex:-1,quoted:!1};return yU($,Y)},[$,Y]);cX(()=>{if(!$.includes("@")){W([]),H(!1);return}let B=Date.now();if(y$&&y$.cwd===X&&y$.ignoreKey===z&&B-y$.timestamp<vU){W(y$.files),H(!1);return}let N=!1,M=setTimeout(async()=>{H(!0);try{let D=(await MU("**/*",{cwd:X,dot:!1,followSymbolicLinks:!1,onlyFiles:!1,markDirectories:!0,unique:!0,ignore:J})).map((L)=>L.replace(/\\/g,"/"));if(!N)W(D),y$={cwd:X,ignoreKey:z,files:D,timestamp:B}}catch(A){if(console.error("Failed to load files for @ completion:",A),!N)W([])}finally{if(!N)H(!1)}},q);return()=>{N=!0,clearTimeout(M)}},[$,X,q,z]);let w=N7(()=>{if(!_.hasQuery||K.length===0)return[];let B=_.query.toLowerCase();if(B==="")return K.slice(0,Q);if(G)return new jU(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)},[_,K,Q,G]);return cX(()=>{F(0)},[w]),{..._,suggestions:w,selectedIndex:O,loading:U}}function kU($,Y=!1){if($.includes(" ")||Y)return`@"${$}"`;return`@${$}`}function w7($,Y,Z){if(!Y.hasQuery)return{newInput:$,newCursorPos:$.length};let X=kU(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 iX}from"ahooks";import{useEffect as rX,useRef as aX}from"react";z1();var T1=($,Y)=>{let Z=aX(!1),X=aX(null),Q=iX(()=>{if(X.current)clearTimeout(X.current);X.current=setTimeout(()=>{M0().setAwaitingSecondCtrlC(!1),Z.current=!1,X.current=null},3000)}),J=()=>{m2().shutdown("SIGINT",0)},q=iX(()=>{if(!Z.current){if(Z.current=!0,$&&Y)Y();M0().setAwaitingSecondCtrlC(!0),Q()}else{if(X.current)clearTimeout(X.current),X.current=null;M0().setAwaitingSecondCtrlC(!1),J()}});return rX(()=>{if($){if(M0().setAwaitingSecondCtrlC(!1),Z.current=!1,X.current)clearTimeout(X.current),X.current=null}},[$]),rX(()=>{return()=>{if(X.current)clearTimeout(X.current)}},[]),q};var P4=c("UI"),tX=($,Y,Z,X,Q,J,q,G,K,W)=>{let H=z0()==="main-input",O=$.value,F=$.setValue,z=$.cursorPosition,_=I$(),w=R2(),B=A4(),N=B?b$(B):!1,[I,M]=L7(!1),[A,D]=L7([]),[L,V]=L7(0),v=lX(O,z,{cwd:process.cwd(),maxSuggestions:10}),k=T1(q||!1,J),f=sX(0),R=500,T=sX(!1);oX(()=>{if(q)T.current=!1},[q]),oX(()=>{if(v.hasQuery&&v.suggestions.length>0){let t=v.suggestions.map((p)=>({command:p,description:p.endsWith("/")?`Directory: ${p}`:`File: ${p}`,matchScore:1}));D(t),M(!0),V(0)}else if(O.startsWith("/"))if(O.includes(" "))M(!1),D([]);else{let p=SX(O);D(p),M(p.length>0),V(0)}else M(!1),D([])},[O,v.hasQuery,v.suggestions]);let Y1=nX(()=>{_.clearMessages(),_.setError(null)}),r=nX(()=>{P4.debug("[DIAG] handleSubmit called:",{input:O,showSuggestions:I});let t=O.trim();if(t){let p=$.resolveInput(t);P4.debug("[DIAG] Submitting command:",{displayText:t,textLength:p.text.length,imageCount:p.images.length}),M(!1),D([]);let C0=$.pasteMap.size>0?new Map($.pasteMap):new Map;Q(t,C0),$.clear(),Y(p),P4.debug("[DIAG] Command submitted to onSubmit callback")}else P4.debug("[DIAG] Empty command, not submitting")});return PU((t,p)=>{if(t==="?"&&!O){K?.(),setTimeout(()=>$.clear(),0);return}if(p.backspace||p.delete||p.leftArrow||p.rightArrow||p.pageUp||p.pageDown||!p.ctrl&&!p.meta&&!p.escape&&!p.tab&&!p.upArrow&&!p.downArrow&&!p.return&&!(t==="?"&&!O))return;if(p.ctrl&&t==="c"||p.meta&&t==="c"||p.ctrl&&t==="d"||p.meta&&t==="d"){k();return}if(p.ctrl&&t==="l"||p.meta&&t==="l"){Y1();return}if(p.ctrl&&t==="t"||p.meta&&t==="t"){_.toggleThinkingExpanded();return}if(p.ctrl&&t==="o"||p.meta&&t==="o"){_.toggleHistoryExpanded();return}if(p.escape){if(W)K?.();else if(q&&J){if(T.current)return;T.current=!0,J()}else if(I)M(!1),D([]);else if(O){let G1=Date.now();if(G1-f.current<500)$.clear(),f.current=0;else f.current=G1}return}if(p.tab&&p.shift){G?.();return}if(p.tab){if(I&&A.length>0){let G1=A[L].command;if(v.hasQuery&&v.suggestions.includes(G1)){let{newInput:j1,newCursorPos:t0}=w7(O,v,G1);F(j1),$.setCursorPosition(t0)}else{let j1=G1+" ";F(j1),$.setCursorPosition(j1.length)}M(!1),D([])}else if(N)w.toggleThinkingMode();return}if(p.return){if(I&&A.length>0){let G1=A[L].command;if(v.hasQuery&&v.suggestions.includes(G1)){let{newInput:j1,newCursorPos:t0}=w7(O,v,G1);F(j1),$.setCursorPosition(t0)}else{let j1=G1+" ";F(j1),$.setCursorPosition(j1.length)}M(!1),D([])}else r();return}if(p.upArrow){if(I&&A.length>0){let G1=A.length-1;V((j1)=>j1>0?j1-1:G1)}else{let G1=Z();if(G1){if(G1.pasteMappings.size>0)$.restorePasteMappings(G1.pasteMappings);F(G1.display),$.setCursorPosition(G1.display.length)}}return}if(p.downArrow){if(I&&A.length>0){let G1=A.length-1;V((j1)=>j1<G1?j1+1:0)}else{let G1=X();if(G1){if(G1.pasteMappings.size>0)$.restorePasteMappings(G1.pasteMappings);F(G1.display),$.setCursorPosition(G1.display.length)}}return}},{isActive:H}),{handleSubmit:r,showSuggestions:I,suggestions:A,selectedSuggestionIndex:L}};import hU from"ansi-escapes";import{useStdout as xU}from"ink";import{useCallback as pU,useEffect as gU,useRef as mU}from"react";import{useEffect as TU,useState as SU}from"react";import{useStdout as CU}from"ink";import{debounce as fU}from"lodash-es";function D2($=200){let{stdout:Y}=CU(),[Z,X]=SU(Y.columns||80);return TU(()=>{let Q=fU(()=>{X(Y.columns||80)},$);return Q(),Y.on("resize",Q),()=>{Y.off("resize",Q),Q.cancel()}},[Y,$]),Z}function eX(){let{stdout:$}=xU(),Y=D2(),Z=mU(!0),X=q1((J)=>J.session.actions.incrementClearCount),Q=pU(()=>{if($)$.write(hU.clearTerminal);X()},[$,X]);return gU(()=>{if(Z.current){Z.current=!1;return}let J=setTimeout(()=>{Q()},300);return()=>{clearTimeout(J)}},[Y,Q]),{refreshStatic:Q}}w2();import{MultiSelect as dU}from"@inkjs/ui";import{useMemoizedFn as T4}from"ahooks";import{Box as l,Text as x,useFocus as uU,useFocusManager as cU,useInput as ZQ}from"ink";import S4 from"ink-select-input";import lU from"ink-spinner";import N6 from"ink-text-input";import $Q from"node:fs";import iU from"node:os";import A7 from"node:path";import{useEffect as YQ,useState as k$}from"react";import{jsxDEV as j}from"react/jsx-dev-runtime";var rU=[{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"}],aU=[{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 nU($){if(!$||$.trim()==="")return"名称不能为空";if(!/^[a-z0-9-]+$/.test($))return"名称只能包含小写字母、数字和连字符";if($.startsWith("-")||$.endsWith("-"))return"名称不能以连字符开头或结尾";return null}function B6({onComplete:$,onCancel:Y,initialConfig:Z}){let[X,Q]=k$(Z?"name":"mode"),[J,q]=k$({name:Z?.name||"",description:Z?.description||"",tools:Z?.tools||[],color:Z?.color,location:Z?.location||"project",systemPrompt:Z?.systemPrompt||""}),[G,K]=k$(""),[W,U]=k$(!1),[H,O]=k$(""),[F,z]=k$(Z?"edit":"manual"),{focus:_}=cU(),B={manual:["mode","name","description","tools","color","location","systemPrompt","confirm"],ai:["mode","aiPrompt","aiGenerating","confirm"],edit:["name","description","tools","color","location","systemPrompt","confirm"]}[F];YQ(()=>{if(X==="name"||X==="description"||X==="systemPrompt"||X==="aiPrompt")return;_(`step-${X}`)},[X,_]);let N=T4(()=>{let L=B.indexOf(X);if(L<B.length-1)Q(B[L+1])}),I=T4(()=>{if(H)O("");if(X==="confirm"&&F==="ai"){Q("aiPrompt");return}let L=B.indexOf(X);if(L>0)Q(B[L-1]);else Y()}),M=T4(async()=>{U(!0),O("");try{let L=await f1.create(),V=`你是一个 Subagent 配置生成专家。用户会描述他们想要创建的 agent,你需要根据描述生成一个完整的 agent 配置。
1706
1714
 
1707
1715
  ## 可用工具列表
1708
1716
 
@@ -1739,7 +1747,7 @@ blade mcp
1739
1747
  4. **color**: 选择一个合适的颜色用于 UI 区分
1740
1748
  5. **systemPrompt**: 详细说明 agent 的职责、使用的工具、输出格式等,使用 Markdown 格式
1741
1749
 
1742
- **重要**:请直接返回 JSON,不要添加任何额外的解释或文字。`,k=(await V.chatWithSystem(`你是一个 Subagent 配置生成专家。用户会描述他们想要创建的 agent,你需要根据描述生成一个完整的 agent 配置。
1750
+ **重要**:请直接返回 JSON,不要添加任何额外的解释或文字。`,k=(await L.chatWithSystem(`你是一个 Subagent 配置生成专家。用户会描述他们想要创建的 agent,你需要根据描述生成一个完整的 agent 配置。
1743
1751
 
1744
1752
  ## 可用工具列表
1745
1753
 
@@ -1776,29 +1784,29 @@ blade mcp
1776
1784
  4. **color**: 选择一个合适的颜色用于 UI 区分
1777
1785
  5. **systemPrompt**: 详细说明 agent 的职责、使用的工具、输出格式等,使用 Markdown 格式
1778
1786
 
1779
- **重要**:请直接返回 JSON,不要添加任何额外的解释或文字。`,G)).trim(),f=k.match(/```(?:json)?\s*\n([\s\S]*?)\n```/);if(f)k=f[1];let A=JSON.parse(k);if(!A.name||!A.description||!A.systemPrompt)throw Error("Missing required fields: name, description, or systemPrompt");if(!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(A.name))throw Error("Invalid name format. Must be kebab-case (lowercase, numbers, hyphens only)");q({name:A.name,description:A.description,tools:Array.isArray(A.tools)?A.tools:[],color:A.color||"blue",location:"project",systemPrompt:A.systemPrompt}),Q("confirm")}catch(V){O(V instanceof Error?V.message:String(V))}finally{U(!1)}});pX(()=>{if(X==="aiGenerating"&&!W&&!H)I()},[X,W,H,I]);let w=M4(async()=>{try{let V=J.location==="project"?G7.join(process.cwd(),".blade","agents"):G7.join(FU.homedir(),".blade","agents");await xX.promises.mkdir(V,{recursive:!0});let D=["---",`name: ${J.name}`,`description: ${J.description}`];if(J.tools.length>0&&!J.tools.includes("all")){D.push("tools:");for(let f of J.tools)D.push(` - ${f}`)}if(J.color)D.push(`color: ${J.color}`);D.push("---");let y=[D.join(`
1787
+ **重要**:请直接返回 JSON,不要添加任何额外的解释或文字。`,G)).trim(),f=k.match(/```(?:json)?\s*\n([\s\S]*?)\n```/);if(f)k=f[1];let R=JSON.parse(k);if(!R.name||!R.description||!R.systemPrompt)throw Error("Missing required fields: name, description, or systemPrompt");if(!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(R.name))throw Error("Invalid name format. Must be kebab-case (lowercase, numbers, hyphens only)");q({name:R.name,description:R.description,tools:Array.isArray(R.tools)?R.tools:[],color:R.color||"blue",location:"project",systemPrompt:R.systemPrompt}),Q("confirm")}catch(L){O(L instanceof Error?L.message:String(L))}finally{U(!1)}});YQ(()=>{if(X==="aiGenerating"&&!W&&!H)M()},[X,W,H,M]);let A=T4(async()=>{try{let L=J.location==="project"?A7.join(process.cwd(),".blade","agents"):A7.join(iU.homedir(),".blade","agents");await $Q.promises.mkdir(L,{recursive:!0});let V=["---",`name: ${J.name}`,`description: ${J.description}`];if(J.tools.length>0&&!J.tools.includes("all")){V.push("tools:");for(let f of J.tools)V.push(` - ${f}`)}if(J.color)V.push(`color: ${J.color}`);V.push("---");let v=[V.join(`
1780
1788
  `),"",`# ${J.name} Subagent`,"",J.systemPrompt||"你是一个专门的代理,负责执行特定任务。",""].join(`
1781
- `),k=G7.join(V,`${J.name}.md`);await xX.promises.writeFile(k,y,"utf-8"),$()}catch(V){console.error("保存配置失败:",V)}}),M=k1(!1,Y);if(gX((V,D)=>{if(D.escape)b();else if(D.ctrl&&V==="c"||D.meta&&V==="c")M()},{isActive:X!=="tools"}),X==="mode")return j(c,{flexDirection:"column",paddingY:1,children:[j(c,{marginBottom:1,children:j(x,{bold:!0,color:"cyan",children:"\uD83C\uDFAF 选择创建方式"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(c,{marginBottom:1,children:j(x,{dimColor:!0,children:"你可以手动配置每个细节,或让 AI 根据你的描述自动生成配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(j4,{items:[{label:"\uD83E\uDD16 AI 智能生成 - 根据描述自动生成完整配置",value:"ai"},{label:"✍️ 手动配置 - 逐步配置每个选项",value:"manual"}],onSelect:(V)=>{if(V.value==="ai")N("ai"),Q("aiPrompt");else N("manual"),Q("name")}},void 0,!1,void 0,this),j(c,{marginTop:1,children:j(x,{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 j(c,{flexDirection:"column",paddingY:1,children:[j(c,{marginBottom:1,children:j(x,{bold:!0,color:"cyan",children:"\uD83E\uDD16 AI 智能生成"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(c,{marginBottom:1,children:j(x,{dimColor:!0,children:'描述你想要创建的 Agent(例如:"一个专门用于代码审查的 agent,能够分析代码质量和潜在bug")'},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(c,{marginBottom:1,children:[j(x,{color:"green",children:"描述: "},void 0,!1,void 0,this),j(H6,{value:G,onChange:K,onSubmit:(V)=>{if(!V.trim())return;Q("aiGenerating")}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),j(c,{children:j(x,{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(H)return j(c,{flexDirection:"column",paddingY:1,children:[j(c,{marginBottom:1,children:j(x,{bold:!0,color:"red",children:"❌ AI 生成失败"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(c,{marginBottom:1,children:j(x,{color:"red",children:H},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(c,{marginBottom:1,children:j(x,{dimColor:!0,children:"按 ESC 返回修改描述"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return j(c,{flexDirection:"column",paddingY:1,children:[j(c,{marginBottom:1,children:j(x,{bold:!0,color:"yellow",children:[j(OU,{type:"dots"},void 0,!1,void 0,this)," AI 正在生成配置..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this),j(c,{marginBottom:1,children:j(x,{dimColor:!0,children:['根据你的描述:"',G,'"']},void 0,!0,void 0,this)},void 0,!1,void 0,this),j(c,{marginBottom:1,children:j(x,{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 V=F==="edit";return j(c,{flexDirection:"column",paddingY:1,children:[j(c,{marginBottom:1,children:j(x,{bold:!0,color:"cyan",children:["\uD83D\uDCDD Step 1/7: ",V?"Agent 名称(不可修改)":"输入 Agent 名称"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),j(c,{marginBottom:1,children:j(x,{dimColor:!0,children:V?"编辑模式下名称不可修改(修改名称相当于创建新 Agent)":"名称只能包含小写字母、数字和连字符(例如:code-reviewer)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(c,{marginBottom:1,children:[j(x,{color:"green",children:"名称: "},void 0,!1,void 0,this),V?j(x,{children:J.name},void 0,!1,void 0,this):j(H6,{value:J.name,onChange:(D)=>q({...J,name:D}),onSubmit:(D)=>{if(NU(D))return;_()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),j(c,{children:j(x,{dimColor:!0,children:V?"按 Enter 继续 | ESC 返回":"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this),V&&j(H6,{value:"",onChange:()=>{},onSubmit:_,showCursor:!1},"edit-mode-dummy-input",!1,void 0,this)]},void 0,!0,void 0,this)}if(X==="description")return j(c,{flexDirection:"column",paddingY:1,children:[j(c,{marginBottom:1,children:j(x,{bold:!0,color:"cyan",children:"\uD83D\uDCDD Step 2/7: 输入描述信息"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(c,{marginBottom:1,children:j(x,{dimColor:!0,children:"简短描述这个 Agent 的用途和使用场景(这将帮助主 Agent 决定何时使用它)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(c,{marginBottom:1,children:[j(x,{color:"green",children:"描述: "},void 0,!1,void 0,this),j(H6,{value:J.description,onChange:(V)=>q({...J,description:V}),onSubmit:(V)=>{if(!V.trim())return;_()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),j(c,{children:j(x,{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 j(BU,{config:J,setConfig:q,onNext:_,onPrev:b},void 0,!1,void 0,this);if(X==="color")return j(c,{flexDirection:"column",paddingY:1,children:[j(c,{marginBottom:1,children:j(x,{bold:!0,color:"cyan",children:"\uD83C\uDFA8 Step 4/7: 选择背景颜色"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(c,{marginBottom:1,children:j(x,{dimColor:!0,children:"为 Agent 选择一个颜色标识(用于在 UI 中区分不同的 Agents)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(j4,{items:_U,onSelect:(V)=>{let D=V.value==="none"?void 0:V.value;q({...J,color:D}),_()}},void 0,!1,void 0,this),j(c,{marginTop:1,children:j(x,{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 j(c,{flexDirection:"column",paddingY:1,children:[j(c,{marginBottom:1,children:j(x,{bold:!0,color:"cyan",children:"\uD83D\uDCC2 Step 5/7: 选择保存位置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(c,{marginBottom:1,children:j(x,{dimColor:!0,children:"项目级配置仅在当前项目生效,用户级配置全局可用"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(j4,{items:[{label:"\uD83D\uDCC1 项目级 (.blade/agents/) - 仅当前项目",value:"project"},{label:"\uD83C\uDFE0 用户级 (~/.blade/agents/) - 全局可用",value:"user"}],onSelect:(V)=>{q({...J,location:V.value}),_()}},void 0,!1,void 0,this),j(c,{marginTop:1,children:j(x,{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 j(c,{flexDirection:"column",paddingY:1,children:[j(c,{marginBottom:1,children:j(x,{bold:!0,color:"cyan",children:"\uD83D\uDCAC Step 6/7: 输入系统提示词"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(c,{marginBottom:1,children:j(x,{dimColor:!0,children:"定义 Agent 的行为和职责(可选,留空将使用默认提示)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(c,{marginBottom:1,children:[j(x,{color:"green",children:"提示词: "},void 0,!1,void 0,this),j(H6,{value:J.systemPrompt,onChange:(V)=>q({...J,systemPrompt:V}),onSubmit:()=>_()},void 0,!1,void 0,this)]},void 0,!0,void 0,this),j(c,{children:j(x,{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 j(c,{flexDirection:"column",paddingY:1,children:[j(c,{marginBottom:1,children:j(x,{bold:!0,color:"cyan",children:"✅ Step 7/7: 确认配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(c,{flexDirection:"column",paddingLeft:2,marginBottom:1,children:[j(x,{children:[j(x,{bold:!0,color:"green",children:["名称:"," "]},void 0,!0,void 0,this),j(x,{children:J.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),j(x,{children:[j(x,{bold:!0,color:"green",children:["描述:"," "]},void 0,!0,void 0,this),j(x,{children:J.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),j(x,{children:[j(x,{bold:!0,color:"green",children:["工具:"," "]},void 0,!0,void 0,this),j(x,{children:J.tools.includes("all")?"所有工具":J.tools.join(", ")||"所有工具"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),j(x,{children:[j(x,{bold:!0,color:"green",children:["颜色:"," "]},void 0,!0,void 0,this),j(x,{children:J.color||"默认"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),j(x,{children:[j(x,{bold:!0,color:"green",children:["位置:"," "]},void 0,!0,void 0,this),j(x,{children:J.location==="project"?"项目级":"用户级"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),j(x,{children:[j(x,{bold:!0,color:"green",children:["提示词:"," "]},void 0,!0,void 0,this),j(x,{children:J.systemPrompt||"(使用默认)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),j(j4,{items:[{label:"✅ 确认并保存",value:"save"},{label:"⬅️ 返回上一步",value:"back"},{label:"❌ 取消",value:"cancel"}],onSelect:(V)=>{if(V.value==="save")w();else if(V.value==="back")b();else Y()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}function BU({config:$,setConfig:Y,onNext:Z,onPrev:X}){let{isFocused:Q}=UU({id:"step-tools"});gX((q,G)=>{if(G.escape)X()},{isActive:Q});let J=(q)=>{if(q.includes("all"))Y({...$,tools:["all"]});else Y({...$,tools:q});Z()};return j(c,{flexDirection:"column",paddingY:1,children:[j(c,{marginBottom:1,children:j(x,{bold:!0,color:"cyan",children:"\uD83D\uDD27 Step 3/7: 选择可用工具"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(c,{marginBottom:1,children:j(x,{dimColor:!0,children:"方向键导航,空格切换勾选,Enter 确认进入下一步 | ESC 返回上一步"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(WU,{options:zU,defaultValue:$.tools,onSubmit:J},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}z$();import{useMemoizedFn as F6}from"ahooks";import{Box as H1,Text as b1,useInput as LU}from"ink";import K7 from"ink-select-input";import wU from"node:fs";import{useMemo as AU,useState as W7}from"react";import{jsxDEV as h}from"react/jsx-dev-runtime";function mX({initialMode:$="menu",onComplete:Y,onCancel:Z}){let[X,Q]=W7($),[J,q]=W7(null),[G,K]=W7(0),W=F6(()=>{E1.clear(),E1.loadFromStandardLocations(),K((_)=>_+1)}),U=AU(()=>{return E1.getAllSubagents()},[G]),H=[{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"}],O=F6((_)=>{if(_.value==="cancel"){Z?.();return}Q(_.value)}),F=F6((_)=>{if(q(_.value),X==="edit")Q("editWizard");else if(X==="delete")Q("deleteConfirm")}),N=F6(async()=>{if(!J?.configPath)return;try{await wU.promises.unlink(J.configPath),W(),z()}catch(_){console.error("删除失败:",_)}}),z=F6(()=>{Q("menu"),q(null)}),L=k1(!1,Z);if(LU((_,b)=>{if(b.escape){if(X==="menu")Z?.();else if(X==="list"||X==="edit"||X==="delete")z();else if(X==="deleteConfirm")z()}else if(b.ctrl&&_==="c"||b.meta&&_==="c")L()},{isActive:X!=="create"&&X!=="editWizard"}),X==="menu")return h(H1,{flexDirection:"column",paddingY:1,children:[h(H1,{marginBottom:1,children:h(b1,{bold:!0,color:"cyan",children:"\uD83D\uDCCB Agents 管理"},void 0,!1,void 0,this)},void 0,!1,void 0,this),h(K7,{items:H,onSelect:O},void 0,!1,void 0,this),h(H1,{marginTop:1,children:h(b1,{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(U.length===0)return h(H1,{flexDirection:"column",paddingY:1,children:[h(H1,{marginBottom:1,children:h(b1,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this)},void 0,!1,void 0,this),h(H1,{paddingLeft:2,children:h(b1,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),h(H1,{marginTop:1,paddingLeft:2,children:h(b1,{color:"gray",children:"\uD83D\uDCA1 配置文件位置: .blade/agents/ 或 ~/.blade/agents/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),h(H1,{marginTop:1,paddingLeft:2,children:h(b1,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return h(H1,{flexDirection:"column",paddingY:1,children:[h(H1,{marginBottom:1,children:[h(b1,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this),h(b1,{color:"gray",children:[" (找到 ",U.length," 个)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),U.map((_)=>h(H1,{flexDirection:"column",paddingLeft:2,children:[h(H1,{children:h(b1,{children:[h(b1,{bold:!0,color:_.color||"white",children:["• ",_.name]},void 0,!0,void 0,this),h(b1,{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&&h(H1,{paddingLeft:2,children:h(b1,{color:"gray",children:["工具: ",_.tools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),_.configPath&&h(H1,{paddingLeft:2,children:h(b1,{color:"gray",dimColor:!0,children:_.configPath},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},_.name,!0,void 0,this)),h(H1,{marginTop:1,paddingLeft:2,children:h(b1,{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(U.length===0)return h(H1,{flexDirection:"column",paddingY:1,children:[h(H1,{marginBottom:1,children:h(b1,{bold:!0,color:"cyan",children:_},void 0,!1,void 0,this)},void 0,!1,void 0,this),h(H1,{paddingLeft:2,children:h(b1,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),h(H1,{marginTop:1,paddingLeft:2,children:h(b1,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);let b=U.map((I)=>({key:I.name,label:`${I.name} - ${I.description}`,value:I}));return h(H1,{flexDirection:"column",paddingY:1,children:[h(H1,{marginBottom:1,children:h(b1,{bold:!0,color:"cyan",children:_},void 0,!1,void 0,this)},void 0,!1,void 0,this),h(K7,{items:b,onSelect:F},void 0,!1,void 0,this),h(H1,{marginTop:1,children:h(b1,{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 h(O6,{onComplete:()=>{W(),z()},onCancel:z},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 h(O6,{initialConfig:_,onComplete:()=>{W(),z()},onCancel:z},void 0,!1,void 0,this)}if(X==="delete")return B("\uD83D\uDDD1️ 删除 Agent");if(X==="deleteConfirm"&&J)return h(H1,{flexDirection:"column",paddingY:1,children:[h(H1,{marginBottom:1,children:h(b1,{bold:!0,color:"red",children:"⚠️ 确认删除"},void 0,!1,void 0,this)},void 0,!1,void 0,this),h(H1,{marginBottom:1,paddingLeft:2,children:h(b1,{children:["你确定要删除 Agent"," ",h(b1,{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),h(H1,{marginBottom:1,paddingLeft:2,children:h(b1,{dimColor:!0,children:["文件路径: ",J.configPath]},void 0,!0,void 0,this)},void 0,!1,void 0,this),h(H1,{marginBottom:1,paddingLeft:2,children:h(b1,{color:"red",children:"此操作无法撤销!"},void 0,!1,void 0,this)},void 0,!1,void 0,this),h(K7,{items:[{label:"\uD83D\uDDD1️ 确认删除",value:"confirm"},{label:"❌ 取消",value:"cancel"}],onSelect:(_)=>{if(_.value==="confirm")N();else z()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}K2();import{Box as D1,Text as O1,useInput as bU}from"ink";import{jsxDEV as d}from"react/jsx-dev-runtime";function dX({onCancel:$}){let Z=u1().getAll(),X=Z.filter((G)=>G.source==="builtin"),Q=Z.filter((G)=>G.source==="user"),J=Z.filter((G)=>G.source==="project"),q=k1(!1,$);if(bU((G,K)=>{if(K.escape)$?.();else if(K.ctrl&&G==="c"||K.meta&&G==="c")q()}),Z.length===0)return d(D1,{flexDirection:"column",paddingY:1,children:[d(D1,{marginBottom:1,children:d(O1,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this)},void 0,!1,void 0,this),d(D1,{paddingLeft:2,children:d(O1,{color:"gray",children:"没有找到任何 Skill"},void 0,!1,void 0,this)},void 0,!1,void 0,this),d(D1,{marginTop:1,paddingLeft:2,children:d(O1,{color:"gray",children:"配置文件位置: ~/.blade/skills/ 或 .blade/skills/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),d(D1,{marginTop:1,children:d(O1,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return d(D1,{flexDirection:"column",paddingY:1,children:[d(D1,{marginBottom:1,children:[d(O1,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this),d(O1,{color:"gray",children:[" (找到 ",Z.length," 个)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),J.length>0&&d(D1,{flexDirection:"column",marginBottom:1,children:[d(D1,{paddingLeft:1,children:[d(O1,{bold:!0,color:"yellow",children:"项目级"},void 0,!1,void 0,this),d(O1,{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 d(D1,{flexDirection:"column",paddingLeft:2,children:[d(O1,{children:[d(O1,{bold:!0,color:"green",children:["• ",G.name]},void 0,!0,void 0,this),d(O1,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),G.allowedTools&&G.allowedTools.length>0&&d(D1,{paddingLeft:2,children:d(O1,{color:"gray",children:["工具: ",G.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),d(D1,{paddingLeft:2,children:d(O1,{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&&d(D1,{flexDirection:"column",marginBottom:1,children:[d(D1,{paddingLeft:1,children:[d(O1,{bold:!0,color:"yellow",children:"用户级"},void 0,!1,void 0,this),d(O1,{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 d(D1,{flexDirection:"column",paddingLeft:2,children:[d(O1,{children:[d(O1,{bold:!0,color:"green",children:["• ",G.name]},void 0,!0,void 0,this),d(O1,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),G.allowedTools&&G.allowedTools.length>0&&d(D1,{paddingLeft:2,children:d(O1,{color:"gray",children:["工具: ",G.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),d(D1,{paddingLeft:2,children:d(O1,{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&&d(D1,{flexDirection:"column",marginBottom:1,children:[d(D1,{paddingLeft:1,children:[d(O1,{bold:!0,color:"cyan",children:"内置"},void 0,!1,void 0,this),d(O1,{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 d(D1,{flexDirection:"column",paddingLeft:2,children:[d(O1,{children:[d(O1,{bold:!0,color:"green",children:["• ",G.name]},void 0,!0,void 0,this),d(O1,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),G.userInvocable&&d(D1,{paddingLeft:2,children:d(O1,{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),d(D1,{marginTop:1,children:d(O1,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}Y0();import{Box as v$,Text as B1}from"ink";import VU from"react";q4();o9();import{useEffect as RU,useState as uX}from"react";function cX($=process.cwd(),Y=5000){let[Z,X]=uX(null),[Q,J]=uX(!0);return RU(()=>{let q=!0,G=async()=>{try{let W=await Q6($);if(!q)return;if(!W){X(null),J(!1);return}let U=await lZ($);if(!q)return;X(U)}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 X1,Fragment as z6}from"react/jsx-dev-runtime";var lX=VU.memo(()=>{let $=O4(),Y=m0(),Z=R$(),Q=H4()==="shortcuts",J=wZ(),{branch:q}=cX(),G=F4(),K=FZ(),W=OZ(),U=MZ(),H=G?L$(G):!1,F=(()=>{if(Z==="default")return null;if(Z==="autoEdit")return X1(B1,{color:"magenta",children:["▶▶ auto edit on ",X1(B1,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="plan")return X1(B1,{color:"cyan",children:["‖ plan mode on ",X1(B1,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="yolo")return X1(B1,{color:"red",children:["⚡ yolo mode on ",X1(B1,{color:"gray",children:"(all tools auto-approved)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null})(),N=F!==null,z=[["Enter:发送","Shift+Enter:换行","Esc:中止"],["Shift+Tab:切换模式","↑/↓:历史","Tab:补全"],["Ctrl+A:行首","Ctrl+E:行尾","Ctrl+K:删到尾"],["Ctrl+U:删到首","Ctrl+W:删单词","Ctrl+C:退出"]];return X1(v$,{flexDirection:"row",justifyContent:"space-between",paddingX:2,paddingY:0,children:[Q?X1(v$,{flexDirection:"column",gap:0,children:z.map((L,B)=>X1(v$,{flexDirection:"row",children:[L.map((_,b)=>{let[I,w]=_.split(":");return X1(v$,{flexDirection:"row",width:20,children:[X1(B1,{color:"yellow",children:I},void 0,!1,void 0,this),X1(B1,{color:"gray",children:":"},void 0,!1,void 0,this),X1(B1,{color:"white",children:w},void 0,!1,void 0,this)]},b,!0,void 0,this)}),B===z.length-1&&X1(B1,{color:"cyan",children:" ? 关闭"},void 0,!1,void 0,this)]},B,!0,void 0,this))},void 0,!1,void 0,this):X1(v$,{flexDirection:"row",gap:1,children:[q&&X1(z6,{children:[X1(B1,{color:"gray",children:[" ",q]},void 0,!0,void 0,this),X1(B1,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),F,N&&X1(B1,{color:"gray",children:"·"},void 0,!1,void 0,this),X1(B1,{color:"gray",children:"? for shortcuts"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X1(v$,{flexDirection:"row",gap:1,children:!$?X1(B1,{color:"red",children:"⚠ API 密钥未配置"},void 0,!1,void 0,this):X1(z6,{children:[H&&X1(z6,{children:[U?X1(B1,{color:"cyan",children:"Thinking on"},void 0,!1,void 0,this):X1(B1,{color:"gray",children:"Tab:Thinking"},void 0,!1,void 0,this),X1(B1,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G&&X1(B1,{color:"gray",children:G.model},void 0,!1,void 0,this),X1(B1,{color:"gray",children:"·"},void 0,!1,void 0,this),W?X1(B1,{color:"yellow",children:"压缩中..."},void 0,!1,void 0,this):X1(B1,{color:K<20?"red":K<50?"yellow":"gray",children:[K,"%"]},void 0,!0,void 0,this),Y&&X1(z6,{children:[X1(B1,{color:"gray",children:"·"},void 0,!1,void 0,this),X1(B1,{color:"yellow",children:"Processing..."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J&&X1(z6,{children:[X1(B1,{color:"gray",children:"·"},void 0,!1,void 0,this),X1(B1,{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 U7,Text as H7}from"ink";import DU from"react";import{jsxDEV as y$}from"react/jsx-dev-runtime";var iX=DU.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 y$(U7,{flexDirection:"column",paddingX:2,paddingY:0,children:[G.map((W,U)=>{let O=Q+U===Y;return y$(U7,{justifyContent:"space-between",paddingX:1,children:[y$(H7,{color:O?"cyan":"white",bold:O,children:W.command},void 0,!1,void 0,this),y$(H7,{color:O?"cyan":"gray",dimColor:!O,children:W.description},void 0,!1,void 0,this)]},W.command,!0,void 0,this)}),K&&y$(U7,{paddingX:1,children:y$(H7,{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)});Y0();import{Box as N0,Text as y0,useInput as XH}from"ink";import QH from"ink-select-input";import{useMemo as JH}from"react";import{Box as c1,Text as t1}from"ink";import k4 from"react";var IU={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)"}},MU={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)"}},jU={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)"}},vU={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)"}},yU={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)"}},EU={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)"}},kU={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)"}},PU={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)"}},TU={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)"}},SU={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)"}},CU={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)"}},fU={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)"}},hU={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)"}},u0=[{id:"ayu-dark",label:"Ayu Dark",theme:IU,tags:["dark","popular"]},{id:"dracula",label:"Dracula",theme:MU,tags:["dark","popular"]},{id:"monokai",label:"Monokai",theme:jU,tags:["dark","classic"]},{id:"nord",label:"Nord",theme:vU,tags:["dark","minimal"]},{id:"solarized-light",label:"Solarized Light",theme:yU,tags:["light"]},{id:"solarized-dark",label:"Solarized Dark",theme:EU,tags:["dark"]},{id:"tokyo-night",label:"Tokyo Night",theme:kU,tags:["dark","popular"]},{id:"github",label:"GitHub",theme:PU,tags:["light","minimal"]},{id:"gruvbox",label:"Gruvbox",theme:TU,tags:["dark","warm"]},{id:"one-dark",label:"One Dark",theme:SU,tags:["dark","popular"]},{id:"catppuccin",label:"Catppuccin",theme:CU,tags:["dark","pastel"]},{id:"rose-pine",label:"Rose Pine",theme:fU,tags:["dark","elegant"]},{id:"kanagawa",label:"Kanagawa",theme:hU,tags:["dark","japanese"]}];function v4($){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}var rX={primary:"#0066cc",secondary:"#6c757d",accent:"#e83e8c",success:"#28a745",warning:"#ffc107",error:"#dc3545",info:"#17a2b8",light:"#f8f9fa",dark:"#343a40",muted:"#6c757d",highlight:"#fff3cd",text:{primary:"#212529",secondary:"#6c757d",muted:"#6c757d",light:"#ffffff"},background:{primary:"#ffffff",secondary:"#f8f9fa",dark:"#343a40"},border:{light:"#dee2e6",dark:"#495057"},syntax:{comment:"#6c757d",string:"#28a745",number:"#e83e8c",keyword:"#007bff",function:"#17a2b8",variable:"#495057",operator:"#ffc107",type:"#007bff",tag:"#dc3545",attr:"#ffc107",default:"#212529"}},y4={name:"default",colors:rX,spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(0, 0, 0, 0.05)",base:"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)",lg:"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"}},aX={...y4,name:"dark",colors:{...rX,text:{primary:"#ffffff",secondary:"#e2e8f0",muted:"#94a3b8",light:"#000000"},background:{primary:"#1e293b",secondary:"#334155",dark:"#0f172a"},border:{light:"#475569",dark:"#64748b"},syntax:{comment:"#94a3b8",string:"#34d399",number:"#f472b6",keyword:"#60a5fa",function:"#06b6d4",variable:"#e2e8f0",operator:"#fbbf24",type:"#60a5fa",tag:"#fb7185",attr:"#fbbf24",default:"#ffffff"}}};class O7{currentTheme=y4;themes=new Map;constructor(){this.themes.set("default",y4),this.themes.set("dark",aX);for(let $ of u0)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(!v4(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"||u0.some((Z)=>Z.id===$))throw Error(`Cannot remove built-in theme '${$}'`);this.themes.delete($)}hasTheme($){return this.themes.has($)}validateTheme($){return v4($)}}var J1=new O7;import{Box as E$,Text as c0}from"ink";import{common as xU,createLowlight as pU}from"lowlight";import gU from"react";import{jsxDEV as g1}from"react/jsx-dev-runtime";var F7=pU(xU);function E4($,Y,Z=0){if($.type==="text")return g1(c0,{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)=>E4(q,Y,G));return g1(c0,{color:Q,children:J},Z,!1,void 0,this)}if($.type==="root"&&$.children)return g1(gU.Fragment,{children:$.children.map((X,Q)=>E4(X,Y,Q))},Z,!1,void 0,this);return g1(c0,{},Z,!1,void 0,this)}function mU($,Y,Z,X){let Q=Z||J1.getTheme().colors.syntax,J=$;if(X&&$.length>X)J=$.slice(0,X-3)+"...";try{if(!Y||!F7.registered(Y)){let G=F7.highlightAuto(J);if(!G.children||G.children.length===0)return g1(c0,{color:Q.default,children:J},void 0,!1,void 0,this);return E4(G,Q)}let q=F7.highlight(Y,J);if(!q.children||q.children.length===0)return g1(c0,{color:Q.default,children:J},void 0,!1,void 0,this);return E4(q,Q)}catch(q){return g1(c0,{color:Q.default,children:J},void 0,!1,void 0,this)}}var z7=({content:$,language:Y,showLineNumbers:Z=!0,terminalWidth:X,availableHeight:Q})=>{let J=J1.getTheme(),q=$.split(`
1782
- `),G=0;if(Q&&q.length>Q){let H=Math.max(Q,5);if(q.length>H)G=q.length-H,q=q.slice(G)}let K=q.length+G,W=String(K).length+1;return g1(E$,{borderStyle:"round",borderColor:J.colors.border.light,paddingX:1,paddingY:0,marginY:1,flexDirection:"column",children:[Y&&g1(E$,{marginBottom:0,children:g1(c0,{color:J.colors.text.secondary,children:Y},void 0,!1,void 0,this)},void 0,!1,void 0,this),G>0&&g1(E$,{marginBottom:0,children:g1(c0,{color:J.colors.text.muted,dimColor:!0,children:["... ",G," lines hidden ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this),q.map((U,H)=>{let O=H+G+1;return g1(E$,{flexDirection:"row",children:[Z&&g1(E$,{width:W,children:g1(c0,{color:J.colors.text.muted,dimColor:!0,children:String(O).padStart(W-1," ")},void 0,!1,void 0,this)},void 0,!1,void 0,this),g1(E$,{flexShrink:1,children:U.trim()===""?g1(c0,{children:" "},void 0,!1,void 0,this):mU(U,Y,J.colors.syntax)},void 0,!1,void 0,this)]},H,!0,void 0,this)})]},void 0,!0,void 0,this)};import{Box as nX,Text as l0}from"ink";import{jsxDEV as O0}from"react/jsx-dev-runtime";function dU($){let Y=$.split(`
1783
- `),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 _7=({patch:$,startLine:Y,matchLine:Z,terminalWidth:X,maxLines:Q=20})=>{let J=J1.getTheme(),q=dU($),K=Math.max(...q.map((F)=>F.lineNumber||0)).toString().length+1,W=q.length,U=W>Q,H=U?q.slice(0,Q):q,O=W-Q;return O0(nX,{flexDirection:"column",marginTop:1,marginBottom:1,children:[O0(l0,{color:J.colors.muted,children:"─".repeat(Math.max(0,Math.min(60,X)))},void 0,!1,void 0,this),U&&O0(l0,{color:J.colors.info,children:["\uD83D\uDCCA 显示前 ",Q," 行,共 ",W," 行 diff"]},void 0,!0,void 0,this),U&&O0(l0,{color:J.colors.muted,children:"─".repeat(Math.max(0,Math.min(60,X)))},void 0,!1,void 0,this),H.map((F,N)=>{if(F.type==="header")return O0(l0,{color:J.colors.muted,dimColor:!0,children:F.content},N,!1,void 0,this);let z=F.lineNumber?F.lineNumber.toString().padStart(K," "):" ".repeat(K),L=" ",B,_;if(F.type==="add")L="+",_=J.colors.success,B=void 0;else if(F.type==="remove")L="-",_=J.colors.error,B=void 0;else _=J.colors.text.primary;let b=Math.max(0,X-K-2),I=F.content;if(I.length>b)I=I.substring(0,b-3)+"...";return O0(l0,{color:_,backgroundColor:B,children:[O0(l0,{dimColor:!0,children:z},void 0,!1,void 0,this),O0(l0,{children:L},void 0,!1,void 0,this),O0(l0,{children:[" ",I]},void 0,!0,void 0,this)]},N,!0,void 0,this)}),U&&O0(nX,{marginTop:1,children:O0(l0,{color:J.colors.warning,dimColor:!0,children:["⚠️ 已隐藏剩余 ",O," 行 diff(总共 ",W," 行)"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),O0(l0,{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 j0}from"ink";import cU from"react";import uU from"string-width";var g2=($)=>{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 uU(Y)},oX=($,Y,Z="...")=>{if(g2($)<=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(g2(K)<=Y-Z.length)q=K,Q=G+1;else J=G-1}return q+Z},sX=($)=>{return/[*_~`<[\]https?:]/.test($)};import{jsxDEV as F0,Fragment as iU}from"react/jsx-dev-runtime";var N7=2,B7=1,L7=2;var lU=({text:$})=>{let Y=J1.getTheme();if(!sX($))return F0(j0,{children:$},void 0,!1,void 0,this);let Z=[],X=0,Q=/(\*\*.*?\*\*|\*(?!\s).*?(?<!\s)\*|_(?!\s).*?(?<!\s)_|~~.*?~~|`+[^`]+`+|\[.*?\]\(.*?\)|https?:\/\/\S+)/g,J;while((J=Q.exec($))!==null){if(J.index>X)Z.push(F0(j0,{children:$.slice(X,J.index)},`t-${X}`,!1,void 0,this));let q=J[0],G=null,K=`m-${J.index}`;try{if(q.startsWith("**")&&q.endsWith("**")&&q.length>N7*2)G=F0(j0,{bold:!0,children:q.slice(N7,-N7)},K,!1,void 0,this);else if(q.length>B7*2&&(q.startsWith("*")&&q.endsWith("*")||q.startsWith("_")&&q.endsWith("_"))){let W=$.substring(J.index-1,J.index),U=$.substring(Q.lastIndex,Q.lastIndex+1);if(!(/\w/.test(W)||/\w/.test(U)||/[./\\]/.test(W+U)))G=F0(j0,{italic:!0,children:q.slice(B7,-B7)},K,!1,void 0,this)}else if(q.startsWith("~~")&&q.endsWith("~~")&&q.length>L7*2)G=F0(j0,{strikethrough:!0,children:q.slice(L7,-L7)},K,!1,void 0,this);else if(q.startsWith("`")&&q.endsWith("`")){let W=q.match(/^(`+)([^`]+)\1$/);if(W&&W[2])G=F0(j0,{color:Y.colors.syntax.keyword,backgroundColor:Y.colors.background.secondary,bold:!0,children:` ${W[2]} `},K,!1,void 0,this)}else if(q.startsWith("[")&&q.includes("](")&&q.endsWith(")")){let W=q.match(/\[(.*?)\]\((.*?)\)/);if(W){let U=W[1],H=W[2];G=F0(j0,{children:[U,F0(j0,{color:Y.colors.info,children:[" (",H,")"]},void 0,!0,void 0,this)]},K,!0,void 0,this)}}else if(q.match(/^https?:\/\//))G=F0(j0,{color:Y.colors.info,children:q},K,!1,void 0,this)}catch(W){console.error("InlineRenderer 解析错误:",q,W),G=null}Z.push(G??F0(j0,{children:q},K,!1,void 0,this)),X=Q.lastIndex}if(X<$.length)Z.push(F0(j0,{children:$.slice(X)},`t-${X}`,!1,void 0,this));return F0(iU,{children:Z.filter((q)=>q!==null)},void 0,!1,void 0,this)},z0=cU.memo(lU);import{Box as w7,Text as tX}from"ink";import rU from"react";import{jsxDEV as k$}from"react/jsx-dev-runtime";var aU=({itemText:$,type:Y,marker:Z,leadingWhitespace:X=""})=>{let Q=Y==="ol"?`${Z}. `:`${Z} `,J=Q.length,q=X.length;return k$(w7,{paddingLeft:q+1,flexDirection:"row",children:[k$(w7,{width:J,children:k$(tX,{children:Q},void 0,!1,void 0,this)},void 0,!1,void 0,this),k$(w7,{flexGrow:1,children:k$(tX,{wrap:"wrap",children:k$(z0,{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)},eX=rU.memo(aU);import{Box as nU,Text as m2}from"ink";import $Q from"react";import{jsxDEV as _0}from"react/jsx-dev-runtime";var YQ=({headers:$,rows:Y,terminalWidth:Z})=>{let X=J1.getTheme();if($.length===0||Y.length===0)return null;let Q=$.map((O,F)=>{let N=g2(O),z=Math.max(...Y.map((L)=>g2(L[F]||"")));return Math.max(N,z)+2}),J=$.length+1,q=Q.reduce((O,F)=>O+F,0)+J,G=q>Z?Z/q:1,K=Q.map((O)=>Math.floor(O*G)),W=(O,F,N=!1)=>{let z=Math.max(0,F-2),L=g2(O),B=O;if(L>z)B=oX(O,z);let _=g2(B),b=Math.max(0,z-_);return _0(m2,{children:[N?_0(m2,{bold:!0,color:X.colors.primary,children:_0(z0,{text:B},void 0,!1,void 0,this)},void 0,!1,void 0,this):_0(z0,{text:B},void 0,!1,void 0,this)," ".repeat(b)]},void 0,!0,void 0,this)},U=(O)=>{let N={top:{left:"┌",middle:"┬",right:"┐",horizontal:"─"},middle:{left:"├",middle:"┼",right:"┤",horizontal:"─"},bottom:{left:"└",middle:"┴",right:"┘",horizontal:"─"}}[O],z=K.map((B)=>N.horizontal.repeat(B)),L=N.left+z.join(N.middle)+N.right;return _0(m2,{color:X.colors.text.muted,dimColor:!0,children:L},void 0,!1,void 0,this)},H=(O,F=!1)=>{let N=O.map((z,L)=>{let B=K[L]||0;return W(z||"",B,F)});return _0(m2,{children:[_0(m2,{color:X.colors.text.muted,children:"│ "},void 0,!1,void 0,this),N.map((z,L)=>_0($Q.Fragment,{children:[z,L<N.length-1&&_0(m2,{color:X.colors.text.muted,children:" │ "},void 0,!1,void 0,this)]},L,!0,void 0,this)),_0(m2,{color:X.colors.text.muted,children:" │"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};return _0(nU,{flexDirection:"column",marginY:1,children:[U("top"),H($,!0),U("middle"),Y.map((O,F)=>_0($Q.Fragment,{children:H(O)},F,!1,void 0,this)),U("bottom")]},void 0,!0,void 0,this)};import{jsxDEV as u}from"react/jsx-dev-runtime";var oU=($,Y)=>{let X=J1.getTheme().colors;switch($){case"user":return{color:X.info,prefix:"> "};case"assistant":return{color:X.success,prefix:"• "};case"system":return{color:X.warning,prefix:"⚙ "};case"tool":{let Q=Y&&"phase"in Y?Y.phase:void 0;return{color:X.text.secondary,prefix:Q==="start"?"• ":Q==="complete"?" └ ":" "}}default:return{color:X.text.primary,prefix:" "}}},v0={codeBlock:/^```(\w+)?\s*$/,heading:/^ *(#{1,4}) +(.+)/,ulItem:/^([ \t]*)([-*+]) +(.+)/,olItem:/^([ \t]*)(\d+)\. +(.+)/,hr:/^ *([-*_] *){3,} *$/,table:/^\|(.+)\|$/,tableSeparator:/^\|[\s]*:?-+:?[\s]*(\|[\s]*:?-+:?[\s]*)+\|?$/,diffStart:/^<<<DIFF>>>$/,diffEnd:/^<<<\/DIFF>>>$/};function sU($){let Y=[],Z=$.split(/\r?\n/),X=!1,Q=[],J=null,q=!1,G=[],K=[],W=!1,U=[],H=!0;for(let O=0;O<Z.length;O++){let F=Z[O];if(W){if(F.match(v0.diffEnd)){try{let w=JSON.parse(U.join(`
1784
- `));Y.push({type:"diff",content:"",diffData:{patch:w.patch,startLine:w.startLine,matchLine:w.matchLine}})}catch(w){Y.push({type:"text",content:U.join(`
1785
- `)})}W=!1,U=[],H=!1;continue}U.push(F);continue}if(F.match(v0.diffStart)){W=!0,U=[],H=!1;continue}if(X){if(F.match(v0.codeBlock))Y.push({type:"code",content:Q.join(`
1786
- `),language:J||void 0}),X=!1,Q=[],J=null,H=!1;else Q.push(F);continue}let N=F.match(v0.codeBlock);if(N){X=!0,J=N[1]||null,H=!1;continue}let z=F.match(v0.table),L=F.match(v0.tableSeparator);if(z&&!q){if(O+1<Z.length){if(Z[O+1].match(v0.tableSeparator)){q=!0,G=z[1].split("|").map((M)=>M.trim()).filter((M)=>M.length>0),K=[],H=!1;continue}}}if(q&&L)continue;if(q&&z){let w=z[1].split("|").map((M)=>M.trim()).filter((M)=>M.length>0);while(w.length<G.length)w.push("");if(w.length>G.length)w.length=G.length;K.push(w);continue}if(q&&!z){if(G.length>0&&K.length>0)Y.push({type:"table",content:"",tableData:{headers:G,rows:K}});q=!1,G=[],K=[]}let B=F.match(v0.heading);if(B){Y.push({type:"heading",content:B[2],level:B[1].length}),H=!1;continue}let _=F.match(v0.ulItem);if(_){Y.push({type:"list",content:_[3],listType:"ul",marker:_[2],indentation:_[1].length}),H=!1;continue}let b=F.match(v0.olItem);if(b){Y.push({type:"list",content:b[3],listType:"ol",marker:b[2],indentation:b[1].length}),H=!1;continue}if(F.match(v0.hr)){Y.push({type:"hr",content:""}),H=!1;continue}if(F.trim().length===0){if(!H)Y.push({type:"empty",content:""}),H=!0;continue}Y.push({type:"text",content:F}),H=!1}if(X)Y.push({type:"code",content:Q.join(`
1787
- `),language:J||void 0});if(q&&G.length>0&&K.length>0)Y.push({type:"table",content:"",tableData:{headers:G,rows:K}});return Y}var tU=({content:$,language:Y,terminalWidth:Z})=>{return u(z7,{content:$,language:Y,showLineNumbers:!0,terminalWidth:Z},void 0,!1,void 0,this)},eU=({content:$,level:Y})=>{let Z=J1.getTheme();switch(Y){case 1:return u(t1,{bold:!0,color:Z.colors.primary,children:u(z0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 2:return u(t1,{bold:!0,color:Z.colors.primary,children:u(z0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 3:return u(t1,{bold:!0,color:Z.colors.text.primary,children:u(z0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 4:return u(t1,{italic:!0,color:Z.colors.text.muted,children:u(z0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);default:return u(t1,{children:u(z0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)}},$H=({terminalWidth:$})=>{let Y=J1.getTheme(),Z=Math.max(0,Math.min($-4,80));return u(t1,{dimColor:!0,color:Y.colors.text.muted,children:"─".repeat(Z)},void 0,!1,void 0,this)},YH=({content:$})=>{return u(t1,{wrap:"wrap",children:u(z0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)},ZH=k4.memo(({detail:$,terminalWidth:Y})=>{let Z=J1.getTheme(),X=50,Q=$.split(`
1789
+ `),k=A7.join(L,`${J.name}.md`);await $Q.promises.writeFile(k,v,"utf-8"),$()}catch(L){console.error("保存配置失败:",L)}}),D=T1(!1,Y);if(ZQ((L,V)=>{if(V.escape)I();else if(V.ctrl&&L==="c"||V.meta&&L==="c")D()},{isActive:X!=="tools"}),X==="mode")return j(l,{flexDirection:"column",paddingY:1,children:[j(l,{marginBottom:1,children:j(x,{bold:!0,color:"cyan",children:"\uD83C\uDFAF 选择创建方式"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(l,{marginBottom:1,children:j(x,{dimColor:!0,children:"你可以手动配置每个细节,或让 AI 根据你的描述自动生成配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(S4,{items:[{label:"\uD83E\uDD16 AI 智能生成 - 根据描述自动生成完整配置",value:"ai"},{label:"✍️ 手动配置 - 逐步配置每个选项",value:"manual"}],onSelect:(L)=>{if(L.value==="ai")z("ai"),Q("aiPrompt");else z("manual"),Q("name")}},void 0,!1,void 0,this),j(l,{marginTop:1,children:j(x,{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 j(l,{flexDirection:"column",paddingY:1,children:[j(l,{marginBottom:1,children:j(x,{bold:!0,color:"cyan",children:"\uD83E\uDD16 AI 智能生成"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(l,{marginBottom:1,children:j(x,{dimColor:!0,children:'描述你想要创建的 Agent(例如:"一个专门用于代码审查的 agent,能够分析代码质量和潜在bug")'},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(l,{marginBottom:1,children:[j(x,{color:"green",children:"描述: "},void 0,!1,void 0,this),j(N6,{value:G,onChange:K,onSubmit:(L)=>{if(!L.trim())return;Q("aiGenerating")}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),j(l,{children:j(x,{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(H)return j(l,{flexDirection:"column",paddingY:1,children:[j(l,{marginBottom:1,children:j(x,{bold:!0,color:"red",children:"❌ AI 生成失败"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(l,{marginBottom:1,children:j(x,{color:"red",children:H},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(l,{marginBottom:1,children:j(x,{dimColor:!0,children:"按 ESC 返回修改描述"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return j(l,{flexDirection:"column",paddingY:1,children:[j(l,{marginBottom:1,children:j(x,{bold:!0,color:"yellow",children:[j(lU,{type:"dots"},void 0,!1,void 0,this)," AI 正在生成配置..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this),j(l,{marginBottom:1,children:j(x,{dimColor:!0,children:['根据你的描述:"',G,'"']},void 0,!0,void 0,this)},void 0,!1,void 0,this),j(l,{marginBottom:1,children:j(x,{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 L=F==="edit";return j(l,{flexDirection:"column",paddingY:1,children:[j(l,{marginBottom:1,children:j(x,{bold:!0,color:"cyan",children:["\uD83D\uDCDD Step 1/7: ",L?"Agent 名称(不可修改)":"输入 Agent 名称"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),j(l,{marginBottom:1,children:j(x,{dimColor:!0,children:L?"编辑模式下名称不可修改(修改名称相当于创建新 Agent)":"名称只能包含小写字母、数字和连字符(例如:code-reviewer)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(l,{marginBottom:1,children:[j(x,{color:"green",children:"名称: "},void 0,!1,void 0,this),L?j(x,{children:J.name},void 0,!1,void 0,this):j(N6,{value:J.name,onChange:(V)=>q({...J,name:V}),onSubmit:(V)=>{if(nU(V))return;N()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),j(l,{children:j(x,{dimColor:!0,children:L?"按 Enter 继续 | ESC 返回":"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this),L&&j(N6,{value:"",onChange:()=>{},onSubmit:N,showCursor:!1},"edit-mode-dummy-input",!1,void 0,this)]},void 0,!0,void 0,this)}if(X==="description")return j(l,{flexDirection:"column",paddingY:1,children:[j(l,{marginBottom:1,children:j(x,{bold:!0,color:"cyan",children:"\uD83D\uDCDD Step 2/7: 输入描述信息"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(l,{marginBottom:1,children:j(x,{dimColor:!0,children:"简短描述这个 Agent 的用途和使用场景(这将帮助主 Agent 决定何时使用它)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(l,{marginBottom:1,children:[j(x,{color:"green",children:"描述: "},void 0,!1,void 0,this),j(N6,{value:J.description,onChange:(L)=>q({...J,description:L}),onSubmit:(L)=>{if(!L.trim())return;N()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),j(l,{children:j(x,{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 j(oU,{config:J,setConfig:q,onNext:N,onPrev:I},void 0,!1,void 0,this);if(X==="color")return j(l,{flexDirection:"column",paddingY:1,children:[j(l,{marginBottom:1,children:j(x,{bold:!0,color:"cyan",children:"\uD83C\uDFA8 Step 4/7: 选择背景颜色"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(l,{marginBottom:1,children:j(x,{dimColor:!0,children:"为 Agent 选择一个颜色标识(用于在 UI 中区分不同的 Agents)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(S4,{items:aU,onSelect:(L)=>{let V=L.value==="none"?void 0:L.value;q({...J,color:V}),N()}},void 0,!1,void 0,this),j(l,{marginTop:1,children:j(x,{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 j(l,{flexDirection:"column",paddingY:1,children:[j(l,{marginBottom:1,children:j(x,{bold:!0,color:"cyan",children:"\uD83D\uDCC2 Step 5/7: 选择保存位置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(l,{marginBottom:1,children:j(x,{dimColor:!0,children:"项目级配置仅在当前项目生效,用户级配置全局可用"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(S4,{items:[{label:"\uD83D\uDCC1 项目级 (.blade/agents/) - 仅当前项目",value:"project"},{label:"\uD83C\uDFE0 用户级 (~/.blade/agents/) - 全局可用",value:"user"}],onSelect:(L)=>{q({...J,location:L.value}),N()}},void 0,!1,void 0,this),j(l,{marginTop:1,children:j(x,{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 j(l,{flexDirection:"column",paddingY:1,children:[j(l,{marginBottom:1,children:j(x,{bold:!0,color:"cyan",children:"\uD83D\uDCAC Step 6/7: 输入系统提示词"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(l,{marginBottom:1,children:j(x,{dimColor:!0,children:"定义 Agent 的行为和职责(可选,留空将使用默认提示)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(l,{marginBottom:1,children:[j(x,{color:"green",children:"提示词: "},void 0,!1,void 0,this),j(N6,{value:J.systemPrompt,onChange:(L)=>q({...J,systemPrompt:L}),onSubmit:()=>N()},void 0,!1,void 0,this)]},void 0,!0,void 0,this),j(l,{children:j(x,{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 j(l,{flexDirection:"column",paddingY:1,children:[j(l,{marginBottom:1,children:j(x,{bold:!0,color:"cyan",children:"✅ Step 7/7: 确认配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(l,{flexDirection:"column",paddingLeft:2,marginBottom:1,children:[j(x,{children:[j(x,{bold:!0,color:"green",children:["名称:"," "]},void 0,!0,void 0,this),j(x,{children:J.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),j(x,{children:[j(x,{bold:!0,color:"green",children:["描述:"," "]},void 0,!0,void 0,this),j(x,{children:J.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),j(x,{children:[j(x,{bold:!0,color:"green",children:["工具:"," "]},void 0,!0,void 0,this),j(x,{children:J.tools.includes("all")?"所有工具":J.tools.join(", ")||"所有工具"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),j(x,{children:[j(x,{bold:!0,color:"green",children:["颜色:"," "]},void 0,!0,void 0,this),j(x,{children:J.color||"默认"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),j(x,{children:[j(x,{bold:!0,color:"green",children:["位置:"," "]},void 0,!0,void 0,this),j(x,{children:J.location==="project"?"项目级":"用户级"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),j(x,{children:[j(x,{bold:!0,color:"green",children:["提示词:"," "]},void 0,!0,void 0,this),j(x,{children:J.systemPrompt||"(使用默认)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),j(S4,{items:[{label:"✅ 确认并保存",value:"save"},{label:"⬅️ 返回上一步",value:"back"},{label:"❌ 取消",value:"cancel"}],onSelect:(L)=>{if(L.value==="save")A();else if(L.value==="back")I();else Y()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}function oU({config:$,setConfig:Y,onNext:Z,onPrev:X}){let{isFocused:Q}=uU({id:"step-tools"});ZQ((q,G)=>{if(G.escape)X()},{isActive:Q});let J=(q)=>{if(q.includes("all"))Y({...$,tools:["all"]});else Y({...$,tools:q});Z()};return j(l,{flexDirection:"column",paddingY:1,children:[j(l,{marginBottom:1,children:j(x,{bold:!0,color:"cyan",children:"\uD83D\uDD27 Step 3/7: 选择可用工具"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(l,{marginBottom:1,children:j(x,{dimColor:!0,children:"方向键导航,空格切换勾选,Enter 确认进入下一步 | ESC 返回上一步"},void 0,!1,void 0,this)},void 0,!1,void 0,this),j(dU,{options:rU,defaultValue:$.tools,onSubmit:J},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}B$();import{useMemoizedFn as w6}from"ahooks";import{Box as U1,Text as A1,useInput as sU}from"ink";import b7 from"ink-select-input";import tU from"node:fs";import{useMemo as eU,useState as R7}from"react";import{jsxDEV as h}from"react/jsx-dev-runtime";function XQ({initialMode:$="menu",onComplete:Y,onCancel:Z}){let[X,Q]=R7($),[J,q]=R7(null),[G,K]=R7(0),W=w6(()=>{k1.clear(),k1.loadFromStandardLocations(),K((N)=>N+1)}),U=eU(()=>{return k1.getAllSubagents()},[G]),H=[{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"}],O=w6((N)=>{if(N.value==="cancel"){Z?.();return}Q(N.value)}),F=w6((N)=>{if(q(N.value),X==="edit")Q("editWizard");else if(X==="delete")Q("deleteConfirm")}),z=w6(async()=>{if(!J?.configPath)return;try{await tU.promises.unlink(J.configPath),W(),_()}catch(N){console.error("删除失败:",N)}}),_=w6(()=>{Q("menu"),q(null)}),w=T1(!1,Z);if(sU((N,I)=>{if(I.escape){if(X==="menu")Z?.();else if(X==="list"||X==="edit"||X==="delete")_();else if(X==="deleteConfirm")_()}else if(I.ctrl&&N==="c"||I.meta&&N==="c")w()},{isActive:X!=="create"&&X!=="editWizard"}),X==="menu")return h(U1,{flexDirection:"column",paddingY:1,children:[h(U1,{marginBottom:1,children:h(A1,{bold:!0,color:"cyan",children:"\uD83D\uDCCB Agents 管理"},void 0,!1,void 0,this)},void 0,!1,void 0,this),h(b7,{items:H,onSelect:O},void 0,!1,void 0,this),h(U1,{marginTop:1,children:h(A1,{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(U.length===0)return h(U1,{flexDirection:"column",paddingY:1,children:[h(U1,{marginBottom:1,children:h(A1,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this)},void 0,!1,void 0,this),h(U1,{paddingLeft:2,children:h(A1,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),h(U1,{marginTop:1,paddingLeft:2,children:h(A1,{color:"gray",children:"\uD83D\uDCA1 配置文件位置: .blade/agents/ 或 ~/.blade/agents/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),h(U1,{marginTop:1,paddingLeft:2,children:h(A1,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return h(U1,{flexDirection:"column",paddingY:1,children:[h(U1,{marginBottom:1,children:[h(A1,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this),h(A1,{color:"gray",children:[" (找到 ",U.length," 个)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),U.map((N)=>h(U1,{flexDirection:"column",paddingLeft:2,children:[h(U1,{children:h(A1,{children:[h(A1,{bold:!0,color:N.color||"white",children:["• ",N.name]},void 0,!0,void 0,this),h(A1,{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&&h(U1,{paddingLeft:2,children:h(A1,{color:"gray",children:["工具: ",N.tools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),N.configPath&&h(U1,{paddingLeft:2,children:h(A1,{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)),h(U1,{marginTop:1,paddingLeft:2,children:h(A1,{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(U.length===0)return h(U1,{flexDirection:"column",paddingY:1,children:[h(U1,{marginBottom:1,children:h(A1,{bold:!0,color:"cyan",children:N},void 0,!1,void 0,this)},void 0,!1,void 0,this),h(U1,{paddingLeft:2,children:h(A1,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),h(U1,{marginTop:1,paddingLeft:2,children:h(A1,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);let I=U.map((M)=>({key:M.name,label:`${M.name} - ${M.description}`,value:M}));return h(U1,{flexDirection:"column",paddingY:1,children:[h(U1,{marginBottom:1,children:h(A1,{bold:!0,color:"cyan",children:N},void 0,!1,void 0,this)},void 0,!1,void 0,this),h(b7,{items:I,onSelect:F},void 0,!1,void 0,this),h(U1,{marginTop:1,children:h(A1,{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 h(B6,{onComplete:()=>{W(),_()},onCancel:_},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 h(B6,{initialConfig:N,onComplete:()=>{W(),_()},onCancel:_},void 0,!1,void 0,this)}if(X==="delete")return B("\uD83D\uDDD1️ 删除 Agent");if(X==="deleteConfirm"&&J)return h(U1,{flexDirection:"column",paddingY:1,children:[h(U1,{marginBottom:1,children:h(A1,{bold:!0,color:"red",children:"⚠️ 确认删除"},void 0,!1,void 0,this)},void 0,!1,void 0,this),h(U1,{marginBottom:1,paddingLeft:2,children:h(A1,{children:["你确定要删除 Agent"," ",h(A1,{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),h(U1,{marginBottom:1,paddingLeft:2,children:h(A1,{dimColor:!0,children:["文件路径: ",J.configPath]},void 0,!0,void 0,this)},void 0,!1,void 0,this),h(U1,{marginBottom:1,paddingLeft:2,children:h(A1,{color:"red",children:"此操作无法撤销!"},void 0,!1,void 0,this)},void 0,!1,void 0,this),h(b7,{items:[{label:"\uD83D\uDDD1️ 确认删除",value:"confirm"},{label:"❌ 取消",value:"cancel"}],onSelect:(N)=>{if(N.value==="confirm")z();else _()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}Q0();import{Box as P$,Text as N1}from"ink";import YH from"react";F4();W7();import{useEffect as $H,useState as QQ}from"react";function JQ($=process.cwd(),Y=5000){let[Z,X]=QQ(null),[Q,J]=QQ(!0);return $H(()=>{let q=!0,G=async()=>{try{let W=await W6($);if(!q)return;if(!W){X(null),J(!1);return}let U=await GX($);if(!q)return;X(U)}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 X1,Fragment as L6}from"react/jsx-dev-runtime";var qQ=YH.memo(()=>{let $=L4(),Y=i0(),Z=M$(),Q=w4()==="shortcuts",J=TZ(),{branch:q}=JQ(),G=A4(),K=jZ(),W=MZ(),U=gZ(),H=G?b$(G):!1,F=(()=>{if(Z==="default")return null;if(Z==="autoEdit")return X1(N1,{color:"magenta",children:["▶▶ auto edit on ",X1(N1,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="plan")return X1(N1,{color:"cyan",children:["‖ plan mode on ",X1(N1,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="yolo")return X1(N1,{color:"red",children:["⚡ yolo mode on ",X1(N1,{color:"gray",children:"(all tools auto-approved)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null})(),z=F!==null,_=[["Enter:发送","Shift+Enter:换行","Esc:中止"],["Shift+Tab:切换模式","↑/↓:历史","Tab:补全"],["Ctrl+A:行首","Ctrl+E:行尾","Ctrl+K:删到尾"],["Ctrl+U:删到首","Ctrl+W:删单词","Ctrl+C:退出"]];return X1(P$,{flexDirection:"row",justifyContent:"space-between",paddingX:2,paddingY:0,children:[Q?X1(P$,{flexDirection:"column",gap:0,children:_.map((w,B)=>X1(P$,{flexDirection:"row",children:[w.map((N,I)=>{let[M,A]=N.split(":");return X1(P$,{flexDirection:"row",width:20,children:[X1(N1,{color:"yellow",children:M},void 0,!1,void 0,this),X1(N1,{color:"gray",children:":"},void 0,!1,void 0,this),X1(N1,{color:"white",children:A},void 0,!1,void 0,this)]},I,!0,void 0,this)}),B===_.length-1&&X1(N1,{color:"cyan",children:" ? 关闭"},void 0,!1,void 0,this)]},B,!0,void 0,this))},void 0,!1,void 0,this):X1(P$,{flexDirection:"row",gap:1,children:[q&&X1(L6,{children:[X1(N1,{color:"gray",children:[" ",q]},void 0,!0,void 0,this),X1(N1,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),F,z&&X1(N1,{color:"gray",children:"·"},void 0,!1,void 0,this),X1(N1,{color:"gray",children:"? for shortcuts"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X1(P$,{flexDirection:"row",gap:1,children:!$?X1(N1,{color:"red",children:"⚠ API 密钥未配置"},void 0,!1,void 0,this):X1(L6,{children:[H&&X1(L6,{children:[U?X1(N1,{color:"cyan",children:"Thinking on"},void 0,!1,void 0,this):X1(N1,{color:"gray",children:"Tab:Thinking"},void 0,!1,void 0,this),X1(N1,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G&&X1(N1,{color:"gray",children:G.model},void 0,!1,void 0,this),X1(N1,{color:"gray",children:"·"},void 0,!1,void 0,this),W?X1(N1,{color:"yellow",children:"压缩中..."},void 0,!1,void 0,this):X1(N1,{color:K<20?"red":K<50?"yellow":"gray",children:[K,"%"]},void 0,!0,void 0,this),Y&&X1(L6,{children:[X1(N1,{color:"gray",children:"·"},void 0,!1,void 0,this),X1(N1,{color:"yellow",children:"Processing..."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J&&X1(L6,{children:[X1(N1,{color:"gray",children:"·"},void 0,!1,void 0,this),X1(N1,{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 V7,Text as D7}from"ink";import ZH from"react";import{jsxDEV as T$}from"react/jsx-dev-runtime";var GQ=ZH.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 T$(V7,{flexDirection:"column",paddingX:2,paddingY:0,children:[G.map((W,U)=>{let O=Q+U===Y;return T$(V7,{flexDirection:"row",paddingX:1,gap:2,children:[T$(D7,{color:O?"cyan":"white",bold:O,children:W.command},void 0,!1,void 0,this),T$(D7,{color:O?"cyan":"gray",dimColor:!O,children:["- ",W.description]},void 0,!0,void 0,this)]},W.command,!0,void 0,this)}),K&&T$(V7,{paddingX:1,children:T$(D7,{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)});Q0();import{Box as A0,Text as P0,useInput as RH}from"ink";import VH from"ink-select-input";import{useMemo as DH}from"react";import{Box as d1,Text as i1}from"ink";import f4 from"react";import{Box as S$,Text as a0}from"ink";import{common as XH,createLowlight as QH}from"lowlight";import KQ from"react";O2();import{jsxDEV as m1}from"react/jsx-dev-runtime";var I7=QH(XH);function C4($,Y,Z=0){if($.type==="text")return m1(a0,{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)=>C4(q,Y,G));return m1(a0,{color:Q,children:J},Z,!1,void 0,this)}if($.type==="root"&&$.children)return m1(KQ.Fragment,{children:$.children.map((X,Q)=>C4(X,Y,Q))},Z,!1,void 0,this);return m1(a0,{},Z,!1,void 0,this)}function JH($,Y,Z,X){let Q=Z||V1.getTheme().colors.syntax,J=$;if(X&&$.length>X)J=$.slice(0,X-3)+"...";try{if(!Y||!I7.registered(Y)){let G=I7.highlightAuto(J);if(!G.children||G.children.length===0)return m1(a0,{color:Q.default,children:J},void 0,!1,void 0,this);return C4(G,Q)}let q=I7.highlight(Y,J);if(!q.children||q.children.length===0)return m1(a0,{color:Q.default,children:J},void 0,!1,void 0,this);return C4(q,Q)}catch(q){return m1(a0,{color:Q.default,children:J},void 0,!1,void 0,this)}}var M7=KQ.memo(({content:$,language:Y,showLineNumbers:Z=!0,terminalWidth:X,availableHeight:Q})=>{let J=P1(),q=$.split(`
1790
+ `),G=0;if(Q&&q.length>Q){let H=Math.max(Q,5);if(q.length>H)G=q.length-H,q=q.slice(G)}let K=q.length+G,W=String(K).length+1;return m1(S$,{borderStyle:"round",borderColor:J.colors.border.light,paddingX:1,paddingY:0,marginY:1,flexDirection:"column",children:[Y&&m1(S$,{marginBottom:0,children:m1(a0,{color:J.colors.text.secondary,children:Y},void 0,!1,void 0,this)},void 0,!1,void 0,this),G>0&&m1(S$,{marginBottom:0,children:m1(a0,{color:J.colors.text.muted,dimColor:!0,children:["... ",G," lines hidden ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this),q.map((U,H)=>{let O=H+G+1;return m1(S$,{flexDirection:"row",children:[Z&&m1(S$,{width:W,children:m1(a0,{color:J.colors.text.muted,dimColor:!0,children:String(O).padStart(W-1," ")},void 0,!1,void 0,this)},void 0,!1,void 0,this),m1(S$,{flexShrink:1,children:U.trim()===""?m1(a0,{children:" "},void 0,!1,void 0,this):JH(U,Y,J.colors.syntax)},void 0,!1,void 0,this)]},H,!0,void 0,this)})]},void 0,!0,void 0,this)});import{Box as WQ,Text as n0}from"ink";import{jsxDEV as _0}from"react/jsx-dev-runtime";function qH($){let Y=$.split(`
1791
+ `),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 j7=({patch:$,startLine:Y,matchLine:Z,terminalWidth:X,maxLines:Q=20})=>{let J=P1(),q=qH($),K=Math.max(...q.map((F)=>F.lineNumber||0)).toString().length+1,W=q.length,U=W>Q,H=U?q.slice(0,Q):q,O=W-Q;return _0(WQ,{flexDirection:"column",marginTop:1,marginBottom:1,children:[_0(n0,{color:J.colors.muted,children:"─".repeat(Math.max(0,Math.min(60,X)))},void 0,!1,void 0,this),U&&_0(n0,{color:J.colors.info,children:["\uD83D\uDCCA 显示前 ",Q," 行,共 ",W," 行 diff"]},void 0,!0,void 0,this),U&&_0(n0,{color:J.colors.muted,children:"─".repeat(Math.max(0,Math.min(60,X)))},void 0,!1,void 0,this),H.map((F,z)=>{if(F.type==="header")return _0(n0,{color:J.colors.muted,dimColor:!0,children:F.content},z,!1,void 0,this);let _=F.lineNumber?F.lineNumber.toString().padStart(K," "):" ".repeat(K),w=" ",B,N;if(F.type==="add")w="+",N=J.colors.success,B=void 0;else if(F.type==="remove")w="-",N=J.colors.error,B=void 0;else N=J.colors.text.primary;let I=Math.max(0,X-K-2),M=F.content;if(M.length>I)M=M.substring(0,I-3)+"...";return _0(n0,{color:N,backgroundColor:B,children:[_0(n0,{dimColor:!0,children:_},void 0,!1,void 0,this),_0(n0,{children:w},void 0,!1,void 0,this),_0(n0,{children:[" ",M]},void 0,!0,void 0,this)]},z,!0,void 0,this)}),U&&_0(WQ,{marginTop:1,children:_0(n0,{color:J.colors.warning,dimColor:!0,children:["⚠️ 已隐藏剩余 ",O," 行 diff(总共 ",W," 行)"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),_0(n0,{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 k0}from"ink";import KH from"react";import GH from"string-width";var c2=($)=>{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 GH(Y)},UQ=($,Y,Z="...")=>{if(c2($)<=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(c2(K)<=Y-Z.length)q=K,Q=G+1;else J=G-1}return q+Z},HQ=($)=>{return/[*_~`<[\]https?:]/.test($)};import{jsxDEV as N0,Fragment as UH}from"react/jsx-dev-runtime";var v7=2,y7=1,E7=2;function k7($,Y){return`${$.slice(0,20).replace(/[^a-zA-Z0-9]/g,"")}-${$.length}-${Y}`}var WH=({text:$})=>{let Y=P1();if(!HQ($))return N0(k0,{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 H=$.slice(X,G.index);Z.push(N0(k0,{children:H},k7(H,Q++),!1,void 0,this))}let K=G[0],W=null,U=k7(K,J++);try{if(K.startsWith("**")&&K.endsWith("**")&&K.length>v7*2)W=N0(k0,{bold:!0,children:K.slice(v7,-v7)},U,!1,void 0,this);else if(K.length>y7*2&&(K.startsWith("*")&&K.endsWith("*")||K.startsWith("_")&&K.endsWith("_"))){let H=$.substring(G.index-1,G.index),O=$.substring(q.lastIndex,q.lastIndex+1);if(!(/\w/.test(H)||/\w/.test(O)||/[./\\]/.test(H+O)))W=N0(k0,{italic:!0,children:K.slice(y7,-y7)},U,!1,void 0,this)}else if(K.startsWith("~~")&&K.endsWith("~~")&&K.length>E7*2)W=N0(k0,{strikethrough:!0,children:K.slice(E7,-E7)},U,!1,void 0,this);else if(K.startsWith("`")&&K.endsWith("`")){let H=K.match(/^(`+)([^`]+)\1$/);if(H&&H[2])W=N0(k0,{color:Y.colors.syntax.keyword,backgroundColor:Y.colors.background.secondary,bold:!0,children:` ${H[2]} `},U,!1,void 0,this)}else if(K.startsWith("[")&&K.includes("](")&&K.endsWith(")")){let H=K.match(/\[(.*?)\]\((.*?)\)/);if(H){let O=H[1],F=H[2];W=N0(k0,{children:[O,N0(k0,{color:Y.colors.info,children:[" (",F,")"]},void 0,!0,void 0,this)]},U,!0,void 0,this)}}else if(K.match(/^https?:\/\//))W=N0(k0,{color:Y.colors.info,children:K},U,!1,void 0,this)}catch(H){console.error("InlineRenderer 解析错误:",K,H),W=null}Z.push(W??N0(k0,{children:K},U,!1,void 0,this)),X=q.lastIndex}if(X<$.length){let K=$.slice(X);Z.push(N0(k0,{children:K},k7(K,Q++),!1,void 0,this))}return N0(UH,{children:Z.filter((K)=>K!==null)},void 0,!1,void 0,this)},B0=KH.memo(WH);import{Box as P7,Text as OQ}from"ink";import HH from"react";import{jsxDEV as C$}from"react/jsx-dev-runtime";var OH=({itemText:$,type:Y,marker:Z,leadingWhitespace:X=""})=>{let Q=Y==="ol"?`${Z}. `:`${Z} `,J=Q.length,q=X.length;return C$(P7,{paddingLeft:q+1,flexDirection:"row",children:[C$(P7,{width:J,children:C$(OQ,{children:Q},void 0,!1,void 0,this)},void 0,!1,void 0,this),C$(P7,{flexGrow:1,children:C$(OQ,{wrap:"wrap",children:C$(B0,{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)},FQ=HH.memo(OH);import{Box as FH,Text as l2}from"ink";import T7 from"react";import{jsxDEV as w0}from"react/jsx-dev-runtime";var zQ=T7.memo(({headers:$,rows:Y,terminalWidth:Z})=>{let X=P1();if($.length===0||Y.length===0)return null;let Q=$.map((O,F)=>{let z=c2(O),_=Math.max(...Y.map((w)=>c2(w[F]||"")));return Math.max(z,_)+2}),J=$.length+1,q=Q.reduce((O,F)=>O+F,0)+J,G=q>Z?Z/q:1,K=Q.map((O)=>Math.floor(O*G)),W=(O,F,z=!1)=>{let _=Math.max(0,F-2),w=c2(O),B=O;if(w>_)B=UQ(O,_);let N=c2(B),I=Math.max(0,_-N);return w0(l2,{children:[z?w0(l2,{bold:!0,color:X.colors.primary,children:w0(B0,{text:B},void 0,!1,void 0,this)},void 0,!1,void 0,this):w0(B0,{text:B},void 0,!1,void 0,this)," ".repeat(I)]},void 0,!0,void 0,this)},U=(O)=>{let z={top:{left:"┌",middle:"┬",right:"┐",horizontal:"─"},middle:{left:"├",middle:"┼",right:"┤",horizontal:"─"},bottom:{left:"└",middle:"┴",right:"┘",horizontal:"─"}}[O],_=K.map((B)=>z.horizontal.repeat(B)),w=z.left+_.join(z.middle)+z.right;return w0(l2,{color:X.colors.text.muted,dimColor:!0,children:w},void 0,!1,void 0,this)},H=(O,F=!1)=>{let z=O.map((_,w)=>{let B=K[w]||0;return W(_||"",B,F)});return w0(l2,{children:[w0(l2,{color:X.colors.text.muted,children:"│ "},void 0,!1,void 0,this),z.map((_,w)=>w0(T7.Fragment,{children:[_,w<z.length-1&&w0(l2,{color:X.colors.text.muted,children:" │ "},void 0,!1,void 0,this)]},w,!0,void 0,this)),w0(l2,{color:X.colors.text.muted,children:" │"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};return w0(FH,{flexDirection:"column",marginY:1,children:[U("top"),H($,!0),U("middle"),Y.map((O,F)=>w0(T7.Fragment,{children:H(O)},F,!1,void 0,this)),U("bottom")]},void 0,!0,void 0,this)});import{jsxDEV as g}from"react/jsx-dev-runtime";var zH=($,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:" "}}},L0={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 S7($){let Y=[],Z=$.split(/\r?\n/),X=!1,Q=[],J=null,q=0,G=!1,K=[],W=[],U=!1,H=[],O=!0;for(let F=0;F<Z.length;F++){let z=Z[F];if(U){if(z.match(L0.diffEnd)){try{let L=JSON.parse(H.join(`
1792
+ `));Y.push({type:"diff",content:"",diffData:{patch:L.patch,startLine:L.startLine,matchLine:L.matchLine}})}catch(L){Y.push({type:"text",content:H.join(`
1793
+ `)})}U=!1,H=[],O=!1;continue}H.push(z);continue}if(z.match(L0.diffStart)){U=!0,H=[],O=!1;continue}if(X){let L=z.match(L0.codeBlock),V=z.trim()==="```";if(L&&L[1])q++,Q.push(z);else if(V)if(q>0)q--,Q.push(z);else{let v=Q.join(`
1794
+ `);if(J?.toLowerCase()==="markdown"||J?.toLowerCase()==="md"){let k=S7(v);Y.push(...k)}else Y.push({type:"code",content:v,language:J||void 0});X=!1,Q=[],J=null,q=0,O=!1}else Q.push(z);continue}let _=z.match(L0.codeBlock);if(_){X=!0,J=_[1]||null,q=0,O=!1;continue}let w=z.match(L0.table),B=z.match(L0.tableSeparator);if(w&&!G){if(F+1<Z.length){if(Z[F+1].match(L0.tableSeparator)){G=!0,K=w[1].split("|").map((V)=>V.trim()).filter((V)=>V.length>0),W=[],O=!1;continue}}}if(G&&B)continue;if(G&&w){let L=w[1].split("|").map((V)=>V.trim()).filter((V)=>V.length>0);while(L.length<K.length)L.push("");if(L.length>K.length)L.length=K.length;W.push(L);continue}if(G&&!w){if(K.length>0&&W.length>0)Y.push({type:"table",content:"",tableData:{headers:K,rows:W}});G=!1,K=[],W=[]}let N=z.match(L0.heading);if(N){Y.push({type:"heading",content:N[2],level:N[1].length}),O=!1;continue}let I=z.match(L0.ulItem);if(I){Y.push({type:"list",content:I[3],listType:"ul",marker:I[2],indentation:I[1].length}),O=!1;continue}let M=z.match(L0.olItem);if(M){Y.push({type:"list",content:M[3],listType:"ol",marker:M[2],indentation:M[1].length}),O=!1;continue}if(z.match(L0.hr)){Y.push({type:"hr",content:""}),O=!1;continue}if(z.trim().length===0){if(!O)Y.push({type:"empty",content:""}),O=!0;continue}let D=z.match(L0.commandMessage);if(D){Y.push({type:"command-message",content:D[1]}),O=!1;continue}Y.push({type:"text",content:z}),O=!1}if(X){let F=Q.join(`
1795
+ `);if(J?.toLowerCase()==="markdown"||J?.toLowerCase()==="md"){let z=S7(F);Y.push(...z)}else Y.push({type:"code",content:F,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 _H=({content:$,language:Y,terminalWidth:Z})=>{return g(M7,{content:$,language:Y,showLineNumbers:!0,terminalWidth:Z},void 0,!1,void 0,this)},NH=({content:$,level:Y})=>{let Z=P1();switch(Y){case 1:return g(i1,{bold:!0,color:Z.colors.primary,children:g(B0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 2:return g(i1,{bold:!0,color:Z.colors.primary,children:g(B0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 3:return g(i1,{bold:!0,color:Z.colors.text.primary,children:g(B0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 4:return g(i1,{italic:!0,color:Z.colors.text.muted,children:g(B0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);default:return g(i1,{children:g(B0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)}},BH=({terminalWidth:$})=>{let Y=P1(),Z=Math.max(0,Math.min($-4,80));return g(i1,{dimColor:!0,color:Y.colors.text.muted,children:"─".repeat(Z)},void 0,!1,void 0,this)},wH=({content:$})=>{return g(i1,{wrap:"wrap",children:g(B0,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)},LH=({content:$})=>{let Y=P1();return g(d1,{flexDirection:"row",gap:1,children:[g(i1,{color:Y.colors.info,children:"⏳"},void 0,!1,void 0,this),g(i1,{color:Y.colors.text.muted,italic:!0,children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},AH=f4.memo(({detail:$,terminalWidth:Y})=>{let Z=P1(),X=50,Q=$.split(`
1788
1796
  `),J=Q.length>50,q=J?Q.slice(0,50):Q,G=q.join(`
1789
- `),K=G.includes("<<<DIFF>>>"),W=G.includes("```");if(K){let U=G.match(/<<<DIFF>>>\s*({[\s\S]*?})\s*<<<\/DIFF>>>/);if(U)try{let H=JSON.parse(U[1]);return u(c1,{flexDirection:"column",children:[u(_7,{patch:H.patch,startLine:H.startLine,matchLine:H.matchLine,terminalWidth:Y},void 0,!1,void 0,this),J&&u(c1,{marginTop:1,children:u(t1,{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 U=G.match(/```(\w+)?\s*\n([\s\S]*?)\n```/);if(U){let H=U[1]||"text",O=U[2];return u(c1,{flexDirection:"column",children:[u(z7,{content:O,language:H,showLineNumbers:!1,terminalWidth:Y},void 0,!1,void 0,this),J&&u(c1,{marginTop:1,children:u(t1,{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 u(c1,{flexDirection:"column",children:[q.map((U,H)=>u(t1,{color:Z.colors.text.primary,children:U},H,!1,void 0,this)),J&&u(c1,{marginTop:1,children:u(t1,{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)}),_6=k4.memo(({content:$,role:Y,terminalWidth:Z,metadata:X,isPending:Q=!1})=>{let J=k4.useMemo(()=>oU(Y,X),[Y,X]),{color:q,prefix:G}=J;if(Y==="tool"&&X&&"detail"in X){let W=X;if(W.detail)return u(c1,{flexDirection:"column",marginBottom:1,children:[u(c1,{flexDirection:"row",children:[u(c1,{marginRight:1,children:u(t1,{color:q,bold:!0,children:G},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(t1,{color:q,children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),u(c1,{marginLeft:G.length+1,marginTop:1,children:u(ZH,{detail:W.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 K=k4.useMemo(()=>sU($),[$]);return u(c1,{flexDirection:"column",marginBottom:1,children:K.map((W,U)=>{if(W.type==="empty")return u(c1,{height:1},U,!1,void 0,this);return u(c1,{flexDirection:"row",children:[U===0&&u(c1,{marginRight:1,children:u(t1,{color:q,bold:!0,children:G},void 0,!1,void 0,this)},void 0,!1,void 0,this),U>0&&u(c1,{width:G.length+1},void 0,!1,void 0,this),u(c1,{flexGrow:1,children:W.type==="code"?u(tU,{content:W.content,language:W.language,terminalWidth:Z-(G.length+1)},void 0,!1,void 0,this):W.type==="table"&&W.tableData?u(YQ,{headers:W.tableData.headers,rows:W.tableData.rows,terminalWidth:Z-(G.length+1)},void 0,!1,void 0,this):W.type==="heading"?u(eU,{content:W.content,level:W.level||1},void 0,!1,void 0,this):W.type==="list"?u(eX,{type:W.listType||"ul",marker:W.marker||"-",itemText:W.content,leadingWhitespace:" ".repeat(W.indentation||0)},void 0,!1,void 0,this):W.type==="hr"?u($H,{terminalWidth:Z-(G.length+1)},void 0,!1,void 0,this):W.type==="diff"&&W.diffData?u(_7,{patch:W.diffData.patch,startLine:W.diffData.startLine,matchLine:W.diffData.matchLine,terminalWidth:Z-(G.length+1)},void 0,!1,void 0,this):u(YH,{content:W.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&&JSON.stringify($.metadata)===JSON.stringify(Y.metadata)});import{jsxDEV as L1}from"react/jsx-dev-runtime";var qH=({label:$,isSelected:Y})=>L1(y0,{color:Y?"yellow":void 0,children:$},void 0,!1,void 0,this),ZQ=({details:$,onResponse:Y})=>{let Z=A2(),Q=H0()==="confirmation-prompt",J=k1(!1),q=$.type==="exitPlanMode",G=$.type==="enterPlanMode",K=$.type==="maxTurnsExceeded";XH((O,F)=>{if(F.ctrl&&O==="c"||F.meta&&O==="c"){J();return}if(F.escape){Y({approved:!1,reason:"用户取消"});return}let N=O.toLowerCase();if(q){if(N==="y"){Y({approved:!0,targetMode:"autoEdit"});return}if(N==="s"){Y({approved:!0,targetMode:"default"});return}if(N==="n"){Y({approved:!1,reason:"方案需要改进"});return}}else if(G){if(N==="y"){Y({approved:!0});return}if(N==="n"){Y({approved:!1,reason:"用户拒绝进入 Plan 模式"});return}}else if(K){if(N==="y"){Y({approved:!0});return}if(N==="n"){Y({approved:!1,reason:"用户选择停止"});return}}else{if(N==="y"){Y({approved:!0,scope:"once"});return}if(N==="s"){Y({approved:!0,scope:"session"});return}if(N==="n"){Y({approved:!1,reason:"用户拒绝"});return}}},{isActive:Q});let W=JH(()=>{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]),H=(()=>{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 L1(N0,{flexDirection:"column",borderStyle:"round",borderColor:Q?H.color:"gray",padding:1,children:[L1(N0,{marginBottom:1,children:L1(y0,{bold:!0,color:H.color,children:H.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),$.title&&L1(N0,{marginBottom:1,children:L1(y0,{bold:!0,children:$.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),L1(N0,{marginBottom:1,children:L1(y0,{children:$.message},void 0,!1,void 0,this)},void 0,!1,void 0,this),($.planContent||$.details)&&L1(N0,{flexDirection:"column",marginBottom:1,borderStyle:"single",borderColor:H.color,padding:1,children:[L1(y0,{bold:!0,color:H.color,children:q?"\uD83D\uDCCB Implementation Plan:":G?"\uD83D\uDCDD Details:":"\uD83D\uDCC4 Operation Details:"},void 0,!1,void 0,this),L1(N0,{marginTop:1,children:L1(_6,{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&&L1(N0,{flexDirection:"column",marginBottom:1,children:[L1(y0,{color:"red",bold:!0,children:"⚠️ 风险提示:"},void 0,!1,void 0,this),$.risks.map((O,F)=>L1(N0,{marginLeft:2,children:L1(y0,{color:"red",children:["• ",O]},void 0,!0,void 0,this)},F,!1,void 0,this))]},void 0,!0,void 0,this),$.affectedFiles&&$.affectedFiles.length>0&&L1(N0,{flexDirection:"column",marginBottom:1,children:[L1(y0,{color:"yellow",children:"\uD83D\uDCC1 影响的文件:"},void 0,!1,void 0,this),$.affectedFiles.slice(0,3).map((O,F)=>L1(N0,{marginLeft:2,children:L1(y0,{children:["• ",O]},void 0,!0,void 0,this)},F,!1,void 0,this)),$.affectedFiles.length>3&&L1(N0,{marginLeft:2,children:L1(y0,{color:"gray",children:["...还有 ",$.affectedFiles.length-3," 个文件"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L1(N0,{flexDirection:"column",children:[L1(y0,{color:"gray",children:"使用 ↑ ↓ 选择,回车确认(支持 Y/S/N 快捷键,ESC 取消)"},void 0,!1,void 0,this),L1(QH,{items:W,isFocused:Q,itemComponent:qH,onSelect:(O)=>{Y(O.value)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{useMemoizedFn as OQ}from"ahooks";import{Box as LH,Text as wH}from"ink";import AH from"react";import{useMemoizedFn as OH}from"ahooks";import d2 from"chalk";import{Text as FH,useInput as zH}from"ink";import{useEffect as R7,useRef as V7}from"react";var Z2={TIMEOUT_MS:100,RAPID_INPUT_THRESHOLD_MS:150,LARGE_INPUT_THRESHOLD:300,MEDIUM_SIZE_MULTI_CHUNK_THRESHOLD:200};import{execSync as P$}from"node:child_process";import{existsSync as GH,readFileSync as A7}from"node:fs";import{basename as XQ,isAbsolute as KH}from"node:path";function WH(){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 cM=WH();function QQ($){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 JQ(){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 UH(){let{commands:$}=JQ();try{return P$($.getPath,{encoding:"utf-8"}).trim()}catch(Y){return console.error("Failed to get clipboard path:",Y),null}}function qQ($){if($.startsWith('"')&&$.endsWith('"')||$.startsWith("'")&&$.endsWith("'"))return $.slice(1,-1);return $}function GQ($){if(process.platform==="win32")return $;let Y="__DOUBLE_BACKSLASH__";return $.replace(/\\\\/g,Y).replace(/\\(.)/g,"$1").replace(new RegExp(Y,"g"),"\\")}function b7($){let Y=qQ($.trim()),Z=GQ(Y);return/\.(png|jpe?g|gif|webp)$/i.test(Z)}function HH($){let Y=qQ($.trim()),Z=GQ(Y);if(b7(Z))return Z;return null}async function KQ($){let Y=HH($);if(!Y)return null;let Z;try{if(KH(Y))Z=A7(Y);else{let q=UH();if(q&&Y===XQ(q))Z=A7(q);else return null}}catch(q){return console.error("Failed to read image file:",q),null}let X=Z.toString("base64"),Q=QQ(X),J=XQ(Y);return{path:Y,base64:X,mediaType:Q,filename:J}}async function WQ(){let $=process.platform,Y={darwin:"pbpaste",linux:"xclip -selection clipboard -o || wl-paste",win32:'powershell -Command "Get-Clipboard"'},Z=Y[$]||Y.linux;try{return P$(Z,{encoding:"utf-8"})||null}catch{return null}}async function UQ(){let{commands:$,screenshotPath:Y}=JQ();try{if(P$($.checkImage,{stdio:"ignore"}),P$($.saveImage(Y),{stdio:"ignore"}),!GH(Y))return null;let X=A7(Y).toString("base64"),Q=QQ(X);return P$($.deleteFile(Y),{stdio:"ignore"}),{base64:X,mediaType:Q}}catch(Z){try{P$($.deleteFile(Y),{stdio:"ignore"})}catch{}return null}}import{jsxDEV as BH}from"react/jsx-dev-runtime";var _H=/\r\n/g,NH=/\r/g;function u2($){if(!$.includes("\r"))return $;return $.replace(_H,`
1790
- `).replace(NH,`
1791
- `)}function c2($,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 HQ({value:$,placeholder:Y="",focus:Z=!0,onChange:X,cursorPosition:Q,onChangeCursorPosition:J,onPaste:q,onImagePaste:G,disabledKeys:K=[]}){let W=V7({chunks:[],timeoutId:null,firstInputTime:null,lastInputTime:null,totalLength:0}),U=V7($),H=V7(Q);R7(()=>{U.current=$,H.current=Q},[$,Q]),R7(()=>{return()=>{if(W.current.timeoutId)clearTimeout(W.current.timeoutId)}},[]),R7(()=>{if(Q>$.length)J($.length)},[$,Q,J]);let O=OH(()=>{let L=W.current;if(L.timeoutId)clearTimeout(L.timeoutId);let B=setTimeout(async()=>{let _=W.current.chunks,b=W.current.totalLength;if(_.length===0)return;let I=u2(_.join(""));W.current={chunks:[],timeoutId:null,firstInputTime:null,lastInputTime:null,totalLength:0};let w=U.current,M=H.current;if(G&&b7(I))try{let A=await KQ(I);if(A){let T=await G(A.base64,A.mediaType,A.filename);if(T?.prompt){let Y1=u2(T.prompt),{newValue:r,newCursorPosition:t}=c2(Y1,w,M);X(r),J(t)}return}}catch(A){console.error("Failed to process image path:",A)}let V=I.includes(`
1792
- `),D=b>Z2.MEDIUM_SIZE_MULTI_CHUNK_THRESHOLD&&_.length>3;if((b>Z2.LARGE_INPUT_THRESHOLD||V||D)&&q){let A=await q(I);if(A?.prompt){let T=u2(A.prompt),{newValue:Y1,newCursorPosition:r}=c2(T,w,M);X(Y1),J(r);return}}let{newValue:k,newCursorPosition:f}=c2(I,w,M);X(k),J(f)},Z2.TIMEOUT_MS);W.current.timeoutId=B});zH((L,B)=>{let _=u2(L);if(K.some((D)=>B[D])||B.ctrl&&L==="c"||B.shift&&B.tab||_==="?"&&$==="")return;let I=Date.now(),w=W.current,M=Q,V=$;if(B.leftArrow)M--;else if(B.rightArrow)M++;else if(B.backspace||B.delete){if(L===""){if(Q>0)V=$.slice(0,Q-1)+$.slice(Q,$.length),M--}else if(Q<$.length)V=$.slice(0,Q)+$.slice(Q+1,$.length)}else if(B.ctrl&&_==="a")M=0;else if(B.ctrl&&_==="e")M=$.length;else if(B.ctrl&&_==="k")V=$.slice(0,Q);else if(B.ctrl&&_==="u")V=$.slice(Q),M=0;else if(B.ctrl&&_==="w"){let y=$.slice(0,Q).match(/\s*\S+\s*$/);if(y){let k=y[0].length;V=$.slice(0,Q-k)+$.slice(Q),M-=k}}else if(B.ctrl&&_==="v"){let D=process.platform==="darwin";(async()=>{if(G){let k=await UQ();if(k){let f=await G(k.base64,k.mediaType,"clipboard.png");if(f?.prompt){let A=u2(f.prompt),{newValue:T,newCursorPosition:Y1}=c2(A,U.current,H.current);X(T),J(Y1)}return}}if(D)return;let y=await WQ();if(y){let k=u2(y),f=k.includes(`
1793
- `),A=k.length>Z2.LARGE_INPUT_THRESHOLD;if((f||A)&&q){let r=await q(k);if(r?.prompt){let t=u2(r.prompt),{newValue:p,newCursorPosition:P0}=c2(t,U.current,H.current);X(p),J(P0);return}}let{newValue:T,newCursorPosition:Y1}=c2(k,U.current,H.current);X(T),J(Y1)}})().catch(()=>{});return}else if(B.pageUp)M=0;else if(B.pageDown)M=$.length;else if(_===`
1794
- `&&(B.shift||B.meta)){let{newValue:D,newCursorPosition:y}=c2(_,$,Q);X(D),J(y);return}else if(!B.ctrl&&!B.meta){if(!w.firstInputTime)w.firstInputTime=I;w.lastInputTime=I;let D=I-(w.firstInputTime||I),y=_.length>Z2.LARGE_INPUT_THRESHOLD,k=_.includes(`
1795
- `)&&_.length>1,f=D<Z2.RAPID_INPUT_THRESHOLD_MS&&w.chunks.length>0,A=D<Z2.RAPID_INPUT_THRESHOLD_MS&&_.length>10,T=w.timeoutId!==null;if(q&&(y||k||f||A||T)){w.chunks.push(_),w.totalLength+=_.length,O();return}if(_.length===1&&!w.timeoutId)w.chunks=[],w.firstInputTime=null,w.lastInputTime=null,w.totalLength=0;V=$.slice(0,Q)+_+$.slice(Q,$.length),M+=_.length}if(M<0)M=0;if(M>V.length)M=V.length;if(V!==$)X(V);if(M!==Q)J(M)},{isActive:Z});let F=Z,N=$,z=Y?d2.grey(Y):void 0;if(F)if(z=Y.length>0?d2.inverse(Y[0])+d2.grey(Y.slice(1)):d2.inverse(" "),$.length===0)N=d2.inverse(" ");else{N="";for(let L=0;L<$.length;L++)if(L===Q&&Q<$.length)N+=d2.inverse($[L]);else N+=$[L];if(Q>=$.length)N+=d2.inverse(" ")}return BH(FH,{children:Y?$.length>0?N:z:N},void 0,!1,void 0,this)}import{jsxDEV as D7}from"react/jsx-dev-runtime";var FQ=AH.memo(({input:$,cursorPosition:Y,onChange:Z,onChangeCursorPosition:X,onAddPasteMapping:Q,onAddImagePasteMapping:J})=>{let G=H0()==="main-input",K=OQ((U)=>{let H=U.split(`
1796
- `).length,O=U.length,F=500,N=10;if(O>500||H>10){let z=Q(U),L=U.slice(0,30).replace(/\n/g," "),B=`${O} chars, ${H} lines: ${L}...`;return{prompt:`${D4(z)}${B}${Z7()}`}}return{}}),W=OQ(async(U,H,O)=>{try{let F=J(U,H);return{prompt:`${D4(F)}[Image #${F}]${Z7()}`}}catch(F){return console.error("[Image Paste] Failed to process image:",F),{prompt:`[Image paste failed: ${F instanceof Error?F.message:"Unknown error"}] `}}});return D7(LH,{flexDirection:"row",width:"100%",paddingX:2,paddingY:0,flexShrink:0,flexGrow:0,overflow:"hidden",borderStyle:"round",borderColor:"gray",children:[D7(wH,{color:"blue",bold:!0,children:"> "},void 0,!1,void 0,this),D7(HQ,{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 P4,Text as E0}from"ink";import IH,{useEffect as MH,useState as jH}from"react";import{useEffect as DH,useState as BQ}from"react";import{useEffect as bH,useState as RH}from"react";var VH=15000,zQ=["炼化代码灵气...","参悟 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 广纳贤才..."],_Q=["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 NQ($,Y){let[Z,X]=RH("");return bH(()=>{if(Y){X("等待用户确认...");return}if(!$){X("");return}let Q=()=>{if(Math.random()<0.16666666666666666){let K=Math.floor(Math.random()*_Q.length);return _Q[K]}let G=Math.floor(Math.random()*zQ.length);return zQ[G]};X(Q());let J=setInterval(()=>{X(Q())},VH);return()=>{clearInterval(J)}},[$,Y]),Z}function LQ($,Y=!1){let[Z,X]=BQ(0),[Q,J]=BQ(null),q=NQ($,Y);return DH(()=>{if(!$){X(0),J(null);return}if(Q===null)J(Date.now());let G=setInterval(()=>{if(Q!==null){let K=Math.floor((Date.now()-Q)/1000);X(K)}},1000);return()=>{clearInterval(G)}},[$,Q]),{currentPhrase:q,elapsedTime:Z}}import{jsxDEV as l1,Fragment as yH}from"react/jsx-dev-runtime";var I7=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"],vH=80;function wQ($){if($<60)return`${$}s`;let Y=Math.floor($/60),Z=$%60;return`${Y}m ${Z}s`}var AQ=IH.memo(({message:$})=>{let Y=m0(),Z=O4(),X=Y||!Z,[Q,J]=jH(0),q=J1.getTheme(),K=A2()>=vH,{currentPhrase:W,elapsedTime:U}=LQ(X,!1);if(MH(()=>{if(!X){J(0);return}let O=setInterval(()=>{J((F)=>(F+1)%I7.length)},80);return()=>clearInterval(O)},[X]),!X)return null;let H=W||$||"正在思考中...";if(K)return l1(P4,{paddingX:2,paddingBottom:1,flexDirection:"row",gap:1,children:[l1(E0,{color:q.colors.warning,bold:!0,children:I7[Q]},void 0,!1,void 0,this),l1(E0,{color:q.colors.text.primary,children:H},void 0,!1,void 0,this),U>0&&l1(yH,{children:[l1(E0,{color:q.colors.muted,children:"|"},void 0,!1,void 0,this),l1(E0,{color:q.colors.info,children:["已用时: ",wQ(U)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),l1(E0,{color:q.colors.muted,children:"|"},void 0,!1,void 0,this),l1(E0,{color:q.colors.secondary,children:"Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return l1(P4,{paddingX:2,paddingBottom:1,flexDirection:"column",children:[l1(P4,{flexDirection:"row",gap:1,children:[l1(E0,{color:q.colors.warning,bold:!0,children:I7[Q]},void 0,!1,void 0,this),l1(E0,{color:q.colors.text.primary,children:H},void 0,!1,void 0,this)]},void 0,!0,void 0,this),U>0&&l1(P4,{marginLeft:2,flexDirection:"row",gap:1,children:[l1(E0,{color:q.colors.info,children:["已用时: ",wQ(U)]},void 0,!0,void 0,this),l1(E0,{color:q.colors.muted,children:"|"},void 0,!1,void 0,this),l1(E0,{color:q.colors.secondary,children:"Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});import{Box as S$,Static as gH}from"ink";import jQ,{useEffect as mH,useMemo as L6}from"react";import{Box as EH,Text as bQ}from"ink";import kH from"react";import{jsxDEV as M7}from"react/jsx-dev-runtime";var j7=kH.memo(({collapsedCount:$})=>{if($<=0)return null;let Z=J1.getTheme().colors.text.muted;return M7(EH,{flexDirection:"row",marginBottom:1,children:[M7(bQ,{color:Z,children:["▶ ",$," 条历史消息"]},void 0,!0,void 0,this),M7(bQ,{color:Z,children:" [Ctrl+O 展开]"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});j7.displayName="CollapsedHistorySummary";g$();import{Box as N6,Text as B6}from"ink";import PH from"ink-big-text";import TH from"ink-gradient";import SH from"react";import{jsxDEV as B0}from"react/jsx-dev-runtime";var RQ=SH.memo(()=>{return B0(N6,{flexDirection:"column",paddingX:2,paddingTop:1,paddingBottom:1,children:[B0(N6,{flexDirection:"column",children:B0(TH,{name:"pastel",children:B0(PH,{text:"BLADE",font:"block"},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),B0(N6,{marginBottom:1,children:B0(B6,{color:"white",dimColor:!0,children:i7()},void 0,!1,void 0,this)},void 0,!1,void 0,this),B0(N6,{flexDirection:"column",marginBottom:1,children:[B0(N6,{marginBottom:1,children:B0(B6,{color:"white",bold:!0,children:"使用指南:"},void 0,!1,void 0,this)},void 0,!1,void 0,this),B0(B6,{color:"white",children:"1. 输入问题、编辑文件或运行命令"},void 0,!1,void 0,this),B0(B6,{color:"white",children:"2. 使用 /init 创建项目配置文件"},void 0,!1,void 0,this),B0(B6,{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 v7,Text as T$}from"ink";import CH,{useMemo as VQ}from"react";import{jsxDEV as X2}from"react/jsx-dev-runtime";function fH($,Y=60){if(!$)return"";let Z=$.split(`
1797
- `)[0]||"";if(Z.length<=Y)return Z;return`${Z.slice(0,Y)}...`}function hH($){if(!$)return 0;return $.split(`
1798
- `).length}var y7=CH.memo(({content:$,isStreaming:Y=!1,isExpanded:Z})=>{let X=J1.getTheme(),Q=VQ(()=>hH($),[$]),J=VQ(()=>fH($),[$]),q=X.colors.info,G=X.colors.muted;return X2(v7,{flexDirection:"column",marginBottom:1,children:[X2(v7,{flexDirection:"row",children:[X2(T$,{color:q,children:Z?"▼":"▶"},void 0,!1,void 0,this),X2(T$,{children:" "},void 0,!1,void 0,this),X2(T$,{color:G,children:["Thinking",Y?"...":` (${Q} lines)`]},void 0,!0,void 0,this),!Z&&!Y&&J&&X2(T$,{color:G,children:[" - ",J]},void 0,!0,void 0,this),X2(T$,{color:G,dimColor:!0,children:[" ","[Ctrl+T]"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Z&&$&&X2(v7,{marginLeft:2,marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,paddingY:0,children:X2(T$,{color:G,children:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});y7.displayName="ThinkingBlock";import{Box as T4,Text as E7}from"ink";import{useState as DQ}from"react";function xH(){let[$,Y]=DQ(J1.getTheme()),[Z,X]=DQ(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 IQ(){let{colors:$}=xH();return $}import{jsxDEV as b2}from"react/jsx-dev-runtime";var MQ=({todos:$,visible:Y=!0,compact:Z=!1})=>{let X=IQ();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 b2(T4,{flexDirection:"column",borderStyle:"single",borderColor:X.border.light,paddingX:1,paddingY:Z?0:1,marginBottom:1,children:[b2(T4,{marginBottom:Z?0:1,children:[b2(E7,{dimColor:!0,children:"Tasks "},void 0,!1,void 0,this),b2(E7,{color:X.text.muted,children:[Q.completed,"/",Q.total]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),b2(T4,{flexDirection:"column",children:$.map((J,q)=>b2(pH,{todo:J,compact:Z},J.id||q,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},pH=({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 b2(T4,{paddingY:Y?0:0,children:b2(E7,{dimColor:X,children:[Z," ",Q]},void 0,!0,void 0,this)},void 0,!1,void 0,this)};import{jsxDEV as J0}from"react/jsx-dev-runtime";var vQ=jQ.memo(()=>{let $=U4(),Y=m0(),Z=NZ(),X=AZ(),Q=IZ(),J=jZ(),q=vZ(),G=HZ(),K=EZ(),W=yZ(),U=A2(),H=jQ.useRef(0);mH(()=>{H.current=0},[G]);let{completedMessages:O,streamingMessage:F}=L6(()=>{let b=Math.max(H.current,Y&&$.length>0?$.length-1:$.length);H.current=b;let I=$.slice(0,b),w=b<$.length?$[b]:null;return{completedMessages:I,streamingMessage:w}},[$,Y]),N=L6(()=>{return Z.some((b)=>b.status==="pending"||b.status==="in_progress")},[Z]),z=L6(()=>{if(W)return 0;return Math.max(0,$.length-K)},[$.length,K,W]),L=(b,I=!1)=>J0(S$,{flexDirection:"column",children:J0(_6,{content:b.content,role:b.role,terminalWidth:U,metadata:b.metadata,isPending:I},void 0,!1,void 0,this)},b.id,!1,void 0,this),B=L6(()=>{return Math.min(z,O.length)},[z,O.length]),_=L6(()=>{let b=[];if(b.push(J0(RQ,{},"header",!1,void 0,this)),B>0)b.push(J0(j7,{collapsedCount:B},"collapsed-summary",!1,void 0,this));return O.forEach((I,w)=>{if(w>=z)b.push(L(I))}),b},[O,U,z,B]);return J0(S$,{flexDirection:"column",flexGrow:1,paddingX:2,children:J0(S$,{flexDirection:"column",flexGrow:1,children:[J0(gH,{items:_,children:(b)=>b},`${G}-${W}`,!1,void 0,this),J&&J0(S$,{marginBottom:1,children:J0(y7,{content:J,isStreaming:Y,isExpanded:q},void 0,!1,void 0,this)},void 0,!1,void 0,this),F&&L(F,!0),X&&N&&J0(S$,{marginTop:1,children:J0(MQ,{todos:Z,visible:!0,compact:!1},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q.map((b,I)=>J0(S$,{flexDirection:"column",children:J0(_6,{content:b.displayText,role:"user",terminalWidth:U},void 0,!1,void 0,this)},`pending-${I}`,!1,void 0,this))]},void 0,!0,void 0,this)},void 0,!1,void 0,this)});_1();import{Box as $1,Text as g,useFocus as yQ,useFocusManager as dH,useInput as f4}from"ink";import uH from"ink-select-input";import cH from"ink-text-input";import{useEffect as lH,useState as w6}from"react";import{jsxDEV as v,Fragment as C4}from"react/jsx-dev-runtime";var iH=({isSelected:$})=>v($1,{marginRight:1,children:v(g,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),rH=({isSelected:$,label:Y})=>v(g,{bold:$,color:$?"yellow":void 0,children:Y},void 0,!1,void 0,this);function aH($){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 nH=({onSelect:$,onCancel:Y,initialProvider:Z})=>{let{isFocused:X}=yQ({id:"provider-step"});f4((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 v($1,{flexDirection:"column",marginBottom:1,children:[v($1,{marginBottom:1,children:v(g,{bold:!0,color:"blue",children:"\uD83D\uDCE1 Step 2: 选择 API 提供商"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v($1,{marginBottom:1,children:v(g,{children:"根据您使用的 LLM 服务选择对应的 API 类型"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v($1,{marginBottom:1,children:v(uH,{items:Q,onSelect:(q)=>$(q.value),indicatorComponent:iH,itemComponent:rH,initialIndex:J},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},S4=({stepNumber:$,icon:Y,title:Z,description:X,hint:Q,examples:J,value:q,placeholder:G,mask:K,previousValue:W,onChange:U,onSubmit:H,onCancel:O})=>{return f4((F,N)=>{if(N.escape)O()},{isActive:!0}),v($1,{flexDirection:"column",marginBottom:1,children:[v($1,{marginBottom:1,children:v(g,{bold:!0,color:"blue",children:[Y," Step ",$,": ",Z]},void 0,!0,void 0,this)},void 0,!1,void 0,this),v($1,{marginBottom:1,children:v(g,{children:X},void 0,!1,void 0,this)},void 0,!1,void 0,this),W&&v($1,{marginBottom:1,children:v(g,{color:"green",children:["✓ ",W]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q&&v($1,{marginBottom:1,children:v(g,{dimColor:!0,children:Q},void 0,!1,void 0,this)},void 0,!1,void 0,this),J&&J.length>0&&v(C4,{children:[v($1,{marginBottom:1,children:v(g,{dimColor:!0,children:"常见示例:"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v($1,{marginBottom:1,paddingLeft:2,children:v(g,{dimColor:!0,children:J.join(`
1799
- `)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v($1,{children:[v(g,{bold:!0,color:"cyan",children:["▶"," "]},void 0,!0,void 0,this),v(cH,{value:q,onChange:U,onSubmit:H,placeholder:G,mask:K},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},oH=({mode:$,config:Y,isSaving:Z,onConfirm:X,onBack:Q,onCancel:J})=>{let{isFocused:q}=yQ({id:"confirm-step"});return f4((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}),v($1,{flexDirection:"column",marginBottom:1,children:[v($1,{marginBottom:1,children:v(g,{bold:!0,color:$==="edit"?"yellow":"blue",children:$==="edit"?"\uD83D\uDCBE 确认修改":"✅ Step 6: 确认配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v($1,{marginBottom:1,children:v(g,{children:$==="edit"?"请确认修改内容,保存后将立即生效。":"请确认以下配置信息:"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v($1,{flexDirection:"column",marginBottom:1,paddingLeft:2,children:[v($1,{marginBottom:1,children:[v(g,{dimColor:!0,children:"名称: "},void 0,!1,void 0,this),v(g,{bold:!0,color:"cyan",children:Y.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v($1,{marginBottom:1,children:[v(g,{dimColor:!0,children:"Provider: "},void 0,!1,void 0,this),v(g,{bold:!0,color:"cyan",children:aH(Y.provider)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v($1,{marginBottom:1,children:[v(g,{dimColor:!0,children:"Base URL: "},void 0,!1,void 0,this),v(g,{bold:!0,color:"blue",children:Y.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v($1,{marginBottom:1,children:[v(g,{dimColor:!0,children:"API Key: "},void 0,!1,void 0,this),v(g,{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($1,{children:[v(g,{dimColor:!0,children:"Model: "},void 0,!1,void 0,this),v(g,{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($1,{marginTop:1,children:v(g,{children:[$==="edit"?"保存修改? ":"确认保存配置? ","[",v(g,{bold:!0,color:"green",children:"Y"},void 0,!1,void 0,this),"/",v(g,{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($1,{children:v(g,{color:"yellow",children:"⏳ 正在保存配置到 ~/.blade/config.json..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},k7=({mode:$,initialConfig:Y,modelId:Z,onComplete:X,onCancel:Q})=>{let J=$==="edit",[q,G]=w6("name"),[K,W]=w6(()=>J&&Y?{...Y}:{}),[U,H]=w6(J&&Y?Y.name:""),[O,F]=w6(!1),[N,z]=w6(null),L=k1(!1);f4((A,T)=>{if(T.ctrl&&A==="c"||T.meta&&A==="c")if($==="setup")L();else Q()},{isActive:!0});let{focus:B}=dH();lH(()=>{if(q==="provider")B("provider-step");else if(q==="confirm")B("confirm-step")},[q,B]);let _=()=>{if(!U.trim()){z("配置名称不能为空");return}W({...K,name:U}),H(""),z(null),G("provider")},b=(A)=>{W({...K,provider:A});let T=J?K.baseUrl??Y?.baseUrl??"":"";H(T),G("baseUrl")},I=()=>{if(!U.trim()){z("Base URL 不能为空");return}try{new URL(U)}catch{z("请输入有效的 URL (例如: https://api.openai.com/v1)");return}W({...K,baseUrl:U});let A=J?K.apiKey??Y?.apiKey??"":"";H(A),z(null),G("apiKey")},w=()=>{if(!U.trim()){z("API Key 不能为空");return}W({...K,apiKey:U});let A=J?K.model??Y?.model??"":"";H(A),z(null),G("model")},M=()=>{if(!U.trim()){z("Model 不能为空");return}W({...K,model:U}),H(""),z(null),G("confirm")},V=async()=>{F(!0),z(null);try{let A={name:K.name,provider:K.provider,baseUrl:K.baseUrl,apiKey:K.apiKey,model:K.model};if($==="setup")X(A);else if($==="add"){let T=await z1().addModel(A);await z1().setCurrentModel(T.id),X(A)}else{if(!Z)throw Error("未提供模型 ID,无法编辑");await z1().updateModel(Z,A),X(A)}}catch(A){z(A instanceof Error?A.message:"配置失败"),F(!1)}},D=()=>{switch(z(null),H(""),q){case"provider":H(K.name||""),G("name");break;case"baseUrl":G("provider");break;case"apiKey":H(K.baseUrl||""),G("baseUrl");break;case"model":G("apiKey");break;case"confirm":H(K.model||""),G("model");break}},y=q==="name"?1:q==="provider"?2:q==="baseUrl"?3:q==="apiKey"?4:q==="model"?5:6,k=Math.floor((y-1)/5*40);return v($1,{...$==="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(C4,{children:[v($1,{marginBottom:1,children:v(g,{bold:!0,color:"blue",children:"\uD83D\uDE80 欢迎使用 Blade Code"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v($1,{marginBottom:1,children:v(g,{children:"AI 驱动的代码助手 - 让我们开始配置您的助手"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v($1,{marginBottom:1,children:[v(g,{bold:!0,color:"blue",children:"█".repeat(k)},void 0,!1,void 0,this),v(g,{dimColor:!0,children:"░".repeat(40-k)},void 0,!1,void 0,this),v(g,{children:" "},void 0,!1,void 0,this),v(g,{bold:!0,color:"cyan",children:[y,"/6"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),v($1,{marginBottom:1,children:v(g,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this):$==="add"?v(C4,{children:[v($1,{justifyContent:"center",marginBottom:1,children:v(g,{bold:!0,color:"blue",children:"添加新模型配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v($1,{marginBottom:1,children:v(g,{children:["步骤: ",y,"/6"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this):v(C4,{children:[v($1,{justifyContent:"center",marginBottom:1,children:v(g,{bold:!0,color:"yellow",children:"编辑模型配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v($1,{marginBottom:1,children:v(g,{children:["步骤: ",y,"/6"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),q==="name"&&v(S4,{stepNumber:1,icon:"\uD83D\uDCDD",title:"配置名称",description:"给这个模型配置起一个易于识别的名称",value:U,placeholder:"例如: 千问工作账号",onChange:H,onSubmit:_,onCancel:Q},void 0,!1,void 0,this),q==="provider"&&v(nH,{onSelect:b,onCancel:Q,initialProvider:K.provider},void 0,!1,void 0,this),q==="baseUrl"&&v(S4,{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:U,placeholder:"https://api.example.com/v1",onChange:H,onSubmit:I,onCancel:Q},void 0,!1,void 0,this),q==="apiKey"&&v(S4,{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:U,placeholder:"sk-...",mask:"*",onChange:H,onSubmit:w,onCancel:Q},void 0,!1,void 0,this),q==="model"&&v(S4,{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:U,placeholder:"例如: gpt-5",onChange:H,onSubmit:M,onCancel:Q},void 0,!1,void 0,this),q==="confirm"&&v(oH,{mode:$,config:K,isSaving:O,onConfirm:V,onBack:D,onCancel:Q},void 0,!1,void 0,this),N&&v($1,{marginTop:1,borderStyle:"round",borderColor:"red",paddingX:1,children:v(g,{color:"red",children:["❌ ",N]},void 0,!0,void 0,this)},void 0,!1,void 0,this),v($1,{marginTop:1,children:v(g,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this),!O&&q==="provider"&&v($1,{marginTop:1,children:v(g,{dimColor:!0,children:["\uD83D\uDCA1 使用 ",v(g,{bold:!0,children:"↑/↓"},void 0,!1,void 0,this)," 键选择,",v(g,{bold:!0,children:"Enter"},void 0,!1,void 0,this)," 确认,",v(g,{bold:!0,children:"Esc"},void 0,!1,void 0,this)," 取消"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),!O&&q!=="confirm"&&q!=="provider"&&v($1,{marginTop:1,children:v(g,{dimColor:!0,children:["\uD83D\uDCA1 输入完成后按 ",v(g,{bold:!0,children:"Enter"},void 0,!1,void 0,this),",",v(g,{bold:!0,children:"Ctrl+C"},void 0,!1,void 0,this)," 退出"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),!O&&q==="confirm"&&v($1,{marginTop:1,children:v(g,{dimColor:!0,children:["\uD83D\uDCA1 按"," ",v(g,{bold:!0,color:"green",children:"Y"},void 0,!1,void 0,this)," ","保存,",v(g,{bold:!0,color:"red",children:"N"},void 0,!1,void 0,this)," ","返回修改,",v(g,{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 h4,useMount as sH}from"ahooks";import{Box as L0,Text as U1,useFocus as tH,useFocusManager as eH,useInput as $O}from"ink";import YO from"ink-select-input";import{memo as ZO,useMemo as XO,useState as x4}from"react";_1();import{jsxDEV as o}from"react/jsx-dev-runtime";var QO=({isSelected:$})=>o(L0,{marginRight:1,children:o(U1,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),JO=({isSelected:$,label:Y})=>o(U1,{bold:$,color:$?"yellow":void 0,children:Y},void 0,!1,void 0,this),EQ=ZO(({onClose:$,onEdit:Y})=>{let Z=bZ(),X=RZ()??"",{isFocused:Q}=tH({id:"model-selector"}),J=eH(),[q,G]=x4(""),[K,W]=x4(!1),[U,H]=x4(null),O=k1(!1),[F]=x4(()=>{let M=process.stdout?.columns||80;return Math.max(20,M-8)});sH(()=>{if(J?.focus("model-selector"),Z.length>0)G(Z[0].id)}),$O((M,V)=>{if(K)return;if(V.ctrl&&M==="c"||V.meta&&M==="c"){O();return}if(V.escape){$();return}if(!Q)return;if(M==="d"||M==="D"){z();return}if((M==="e"||M==="E")&&Y)L()},{isActive:!0});let N=h4(async(M)=>{if(K)return;let V=M.value;if(V===X){$();return}W(!0),H(null);try{await z1().setCurrentModel(V),$()}catch(D){H(D.message),W(!1)}}),z=h4(async()=>{if(K||q===X)return;W(!0),H(null);try{if(await z1().removeModel(q),Z.length<=1)$()}catch(M){H(M.message)}finally{W(!1)}}),L=h4(()=>{if(K||!Y)return;let M=Z.find((V)=>V.id===q);if(!M)return;Y(M)}),B=h4((M)=>{G(M.value)}),_=XO(()=>{return Z.find((M)=>M.id===q)},[Z,q]),b=Z.map((M)=>({label:M.name+(M.id===X?" (当前)":""),value:M.id})),I=q===X;return o(L0,{flexDirection:"column",borderStyle:"round",borderColor:"gray",padding:1,width:"100%",children:[o(L0,{flexDirection:"row",justifyContent:"space-between",marginBottom:1,children:[o(U1,{bold:!0,color:"cyan",children:"模型管理"},void 0,!1,void 0,this),o(U1,{dimColor:!0,children:[K?"⏳ 处理中...":I?"Enter=关闭 • E=编辑 • Esc=取消":"Enter=切换 • D=删除 • E=编辑 • Esc=取消"," • Ctrl+C=退出"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),o(L0,{flexDirection:"row",children:[o(L0,{flexDirection:"column",flexGrow:2,marginRight:2,borderStyle:"single",borderColor:"gray",padding:1,children:[o(U1,{dimColor:!0,children:["已配置模型 (",Z.length,")"]},void 0,!0,void 0,this),o(L0,{marginTop:1,children:o(YO,{items:b,onSelect:N,onHighlight:B,indicatorComponent:QO,itemComponent:JO},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o(L0,{flexDirection:"column",flexGrow:3,borderStyle:"single",borderColor:"gray",padding:1,children:[o(U1,{dimColor:!0,children:"模型详情"},void 0,!1,void 0,this),o(L0,{marginY:1,children:o(U1,{color:I?"green":"yellow",children:I?"● 当前使用":"● 可切换"},void 0,!1,void 0,this)},void 0,!1,void 0,this),_?o(L0,{flexDirection:"column",children:[o(U1,{children:[o(U1,{dimColor:!0,children:"名称: "},void 0,!1,void 0,this),o(U1,{bold:!0,color:"cyan",children:_.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o(U1,{children:[o(U1,{dimColor:!0,children:"Provider: "},void 0,!1,void 0,this),o(U1,{bold:!0,children:_.provider},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o(U1,{children:[o(U1,{dimColor:!0,children:"Model: "},void 0,!1,void 0,this),o(U1,{bold:!0,children:_.model},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o(U1,{children:[o(U1,{dimColor:!0,children:"Base URL: "},void 0,!1,void 0,this),o(U1,{color:"blueBright",children:_.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),_.temperature!==void 0&&o(U1,{children:[o(U1,{dimColor:!0,children:"Temperature: "},void 0,!1,void 0,this),o(U1,{children:_.temperature},void 0,!1,void 0,this)]},void 0,!0,void 0,this),_.maxContextTokens!==void 0&&o(U1,{children:[o(U1,{dimColor:!0,children:"Context Window: "},void 0,!1,void 0,this),o(U1,{children:_.maxContextTokens},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this):o(U1,{dimColor:!0,children:"请选择一个模型查看详情"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),U&&o(L0,{marginTop:1,children:o(U1,{color:"red",children:["❌ ",U]},void 0,!0,void 0,this)},void 0,!1,void 0,this),o(L0,{justifyContent:"center",marginTop:1,children:o(U1,{dimColor:!0,children:"─".repeat(F)},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(L0,{justifyContent:"center",children:o(U1,{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 A6}from"ahooks";import{promises as SQ}from"fs";import{Box as q0,Text as w1,useInput as qO}from"ink";import kQ from"ink-select-input";import GO from"ink-text-input";import KO from"os";import p4 from"path";import{useEffect as WO,useMemo as g4,useRef as UO,useState as R2}from"react";_1();import{jsxDEV as s}from"react/jsx-dev-runtime";var b6=[{key:"allow",label:"Allow"},{key:"ask",label:"Ask"},{key:"deny",label:"Deny"},{key:"info",label:"Info"}],HO={allow:"Add a new rule...",ask:"Add a new rule...",deny:"Add a new rule..."},OO={allow:"Allow permission rules",ask:"Ask permission rules",deny:"Deny permission rules"},PQ={project:"[项目共享配置]",global:"[用户全局配置]",local:"[本地配置]"},FO=["project","global","local"],zO={allow:[],ask:[],deny:[]},_O={localExists:!1,projectExists:!1,globalExists:!1},TQ={allow:[],ask:[],deny:[]};function NO($){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 BO($){try{let Y=await SQ.readFile($,"utf-8"),Z=JSON.parse(Y);return{exists:!0,raw:Z,permissions:NO(Z)}}catch(Y){if(Y.code==="ENOENT")return{exists:!1,raw:{},permissions:{...TQ}};return console.warn(`[PermissionsManager] Failed to read ${$}:`,Y),{exists:!0,raw:{},permissions:{...TQ}}}}function LO($,Y){let Z=$.padEnd(32," "),X=Y==="local"?`${PQ[Y]} ← 可删除`:PQ[Y];return`${Z} ${X}`}var CQ=({onClose:$})=>{let Z=H0()==="permissions-manager",X=k1(!1),[Q,J]=R2(0),q=b6[Q].key,[G,K]=R2(zO),[W,U]=R2(_O),[H,O]=R2(!0),[F,N]=R2("list"),[z,L]=R2(""),[B,_]=R2(null),[b,I]=R2(null),w=UO(!1),M=g4(()=>p4.join(process.cwd(),".blade","settings.local.json"),[]),V=g4(()=>p4.join(process.cwd(),".blade","settings.json"),[]),D=g4(()=>p4.join(KO.homedir(),".blade","settings.json"),[]),y=A6(async()=>{O(!0);let l=[{source:"local",path:M},{source:"project",path:V},{source:"global",path:D}],W1=await Promise.all(l.map(async({source:C1,path:n0})=>{let w0=await BO(n0);return{source:C1,path:n0,...w0}})),Z1={localExists:W1.find((C1)=>C1.source==="local")?.exists??!1,projectExists:W1.find((C1)=>C1.source==="project")?.exists??!1,globalExists:W1.find((C1)=>C1.source==="global")?.exists??!1};U(Z1);let $0={allow:[],ask:[],deny:[]},D2=Object.fromEntries(W1.map((C1)=>[C1.source,C1]));["allow","ask","deny"].forEach((C1)=>{FO.forEach((n0)=>{(D2[n0]?.permissions[C1]??[]).forEach((f$,T0)=>{let I2={key:`${n0}:${T0}:${f$}`,rule:f$,source:n0};$0[C1].push(I2)})})}),K($0),O(!1)});WO(()=>{y()},[y]);let k=A6(async(l,W1)=>{try{let Z1=p4.join(process.cwd(),".blade","settings.local.json"),$0={allow:[],ask:[],deny:[]};try{let C1=await SQ.readFile(Z1,"utf-8"),w0=JSON.parse(C1).permissions||{};$0={allow:Array.isArray(w0.allow)?w0.allow:[],ask:Array.isArray(w0.ask)?w0.ask:[],deny:Array.isArray(w0.deny)?w0.deny:[]}}catch(C1){}let D2=W1($0);await z1().updateConfig({permissions:D2},{scope:"local",immediate:!0}),await y()}catch(Z1){throw console.error("[PermissionsManager] 修改权限规则失败:",Z1),Z1}});qO((l,W1)=>{if(W1.ctrl&&l==="c"||W1.meta&&l==="c"){X();return}if(F==="locked"){if(w.current){w.current=!1;return}N("list"),_(null),I(null);return}if(W1.escape){if(F==="list"||q==="info")$();else N("list"),L(""),_(null),I(null);return}if(F==="list"){if(W1.tab&&W1.shift)J((Z1)=>(Z1-1+b6.length)%b6.length);else if(W1.tab)J((Z1)=>(Z1+1)%b6.length);else if(l?.toLowerCase()==="q")$()}},{isActive:Z});let f=A6((l)=>{let W1=l.value;if(q==="info")return;if(W1.type==="add"){N("add"),L(""),I(null);return}if(W1.entry.source!=="local"){N("locked"),w.current=!0,_({tab:q,entry:W1.entry}),I({type:"error",text:W1.entry.source==="project"?"此规则定义在项目共享配置中,无法在此删除。":"此规则来自用户全局配置,无法在此删除。"});return}N("confirm-delete"),_({tab:q,entry:W1.entry}),I(null)}),A=A6(async()=>{if(q==="info")return;let l=z.trim();if(!l){I({type:"error",text:"Permission rule 不能为空"});return}if(G[q].map((Z1)=>Z1.rule).includes(l)){I({type:"error",text:"该规则已存在"});return}try{await k(q,(Z1)=>{let $0={allow:[...Z1.allow],ask:[...Z1.ask],deny:[...Z1.deny]};return $0[q]=[...new Set([...Z1[q],l])],$0}),N("list"),L(""),I({type:"success",text:"已添加本地权限规则"})}catch(Z1){I({type:"error",text:`保存失败: ${Z1 instanceof Error?Z1.message:"未知错误"}`})}}),T=A6(async()=>{if(!B)return;let{tab:l,entry:W1}=B;try{await k(l,(Z1)=>{let $0={allow:[...Z1.allow],ask:[...Z1.ask],deny:[...Z1.deny]};return $0[l]=Z1[l].filter((D2)=>D2!==W1.rule),$0}),N("list"),_(null),I({type:"success",text:"已删除本地权限规则"})}catch(Z1){I({type:"error",text:`删除失败: ${Z1 instanceof Error?Z1.message:"未知错误"}`})}}),Y1=g4(()=>{if(q==="info")return[];let l=q;return[{key:"add-new-rule",label:`› ${HO[l]}`,value:{type:"add"}},...G[l].map((Z1)=>({key:Z1.key,label:LO(Z1.rule,Z1.source),value:{type:"rule",entry:Z1}}))]},[q,G]),r=()=>s(q0,{marginBottom:1,children:b6.map((l,W1)=>s(q0,{marginRight:2,children:s(w1,{color:W1===Q?"yellow":"gray",children:["[",l.label,"]"]},void 0,!0,void 0,this)},l.key,!1,void 0,this))},void 0,!1,void 0,this),t=()=>s(q0,{flexDirection:"column",gap:1,children:[s(w1,{children:"配置文件优先级(从高到低):"},void 0,!1,void 0,this),s(q0,{flexDirection:"column",marginLeft:2,children:[s(w1,{children:["1. .blade/settings.local.json (本地配置,不提交 Git)"," ",W.localExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),s(w1,{children:["2. .blade/settings.json (项目配置,提交 Git)"," ",W.projectExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),s(w1,{children:["3. ~/.blade/settings.json (用户全局配置)"," ",W.globalExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),s(w1,{children:"说明:"},void 0,!1,void 0,this),s(q0,{flexDirection:"column",marginLeft:2,children:[s(w1,{children:"- /permissions 命令只管理本地配置 (.blade/settings.local.json)"},void 0,!1,void 0,this),s(w1,{children:"- 修改全局或项目配置请直接编辑对应文件"},void 0,!1,void 0,this),s(w1,{children:"- 本地配置不会提交到 Git"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),p=(l)=>s(q0,{flexDirection:"column",gap:1,children:[s(w1,{bold:!0,children:OO[l]},void 0,!1,void 0,this),s(w1,{children:"Permission rules are a tool name, optionally followed by a specifier in parentheses."},void 0,!1,void 0,this),s(w1,{color:"gray",children:"例如: WebFetch 或 Bash(ls:*)"},void 0,!1,void 0,this),s(q0,{marginTop:1,children:s(GO,{value:z,onChange:L,onSubmit:A},void 0,!1,void 0,this)},void 0,!1,void 0,this),s(w1,{color:"gray",children:"Enter 提交 · Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P0=(l,W1)=>s(q0,{flexDirection:"column",gap:1,children:[s(w1,{bold:!0,children:["Delete ",l," permission rule?"]},void 0,!0,void 0,this),s(w1,{children:W1.rule},void 0,!1,void 0,this),s(w1,{color:"gray",children:"From project local settings"},void 0,!1,void 0,this),s(w1,{children:"Are you sure you want to delete this permission rule?"},void 0,!1,void 0,this),s(kQ,{items:[{label:"Yes",value:"yes"},{label:"No",value:"no"}],onSelect:(Z1)=>{if(Z1.value==="yes")T();else N("list"),_(null)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G1=(l)=>s(q0,{flexDirection:"column",gap:1,children:[s(w1,{bold:!0,children:"Cannot delete this rule"},void 0,!1,void 0,this),s(w1,{children:l.rule},void 0,!1,void 0,this),s(w1,{color:"gray",children:l.source==="project"?"This rule is defined in .blade/settings.json. 请手动编辑该文件以移除规则。":"This rule is defined in ~/.blade/settings.json. 请手动编辑该文件以移除规则。"},void 0,!1,void 0,this),s(w1,{color:"gray",children:"按任意键继续"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),M1=(l)=>s(kQ,{items:Y1,isFocused:F==="list",onSelect:f},void 0,!1,void 0,this),a0=()=>{if(H)return s(w1,{children:"加载中..."},void 0,!1,void 0,this);if(q==="info")return t();if(F==="add")return p(q);if(F==="confirm-delete"&&B)return P0(B.tab,B.entry);if(F==="locked"&&B)return G1(B.entry);return M1(q)};return s(q0,{flexDirection:"column",borderStyle:"round",borderColor:Z?"cyan":"gray",padding:1,width:80,children:[s(w1,{color:"cyan",bold:!0,children:"⚙️ 权限管理器"},void 0,!1,void 0,this),r(),s(q0,{flexDirection:"column",gap:1,children:a0()},void 0,!1,void 0,this),b&&s(q0,{marginTop:1,children:s(w1,{color:b.type==="success"?"green":"red",children:b.text},void 0,!1,void 0,this)},void 0,!1,void 0,this),s(q0,{marginTop:1,children:s(w1,{color:"gray",children:"Tab 切换视图 · Esc 关闭 · Q 退出"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};W4();import{Box as C$,Text as k0,useInput as wO}from"ink";import AO from"ink-select-input";import{useEffect as fQ,useMemo as m4,useState as P7}from"react";import{jsxDEV as h1}from"react/jsx-dev-runtime";function bO($){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 RO($){let Y=$.split("/");return Y[Y.length-1]||$}var VO=({isSelected:$})=>h1(C$,{marginRight:1,children:h1(k0,{color:$?"cyan":"gray",children:$?"❯":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),DO=({isSelected:$,label:Y})=>h1(k0,{color:$?"cyan":"white",bold:$,children:Y},void 0,!1,void 0,this),R6=20,hQ=({sessions:$,onSelect:Y,onCancel:Z})=>{let[X,Q]=P7([]),[J,q]=P7(!1),[G,K]=P7(0),U=H0()==="session-selector",H=k1(!1);wO((_,b)=>{if(b.ctrl&&_==="c"||b.meta&&_==="c"){H();return}if(b.escape&&Z){Z();return}if(b.leftArrow||_==="h"||_==="H"){if(G>0)K((I)=>I-1);return}if(b.rightArrow||_==="l"||_==="L"){if(G<N-1)K((I)=>I+1);return}},{isActive:U}),fQ(()=>{if($){Q($);return}(async()=>{q(!0);try{let b=await g0.listSessions();Q(b)}catch(b){console.error("[SessionSelector] Failed to load sessions:",b),Q([])}finally{q(!1)}})()},[$]);let O=$||X,F=m4(()=>{return O.map((_)=>{let b=RO(_.projectPath),I=bO(_.lastMessageTime),w=_.gitBranch?` (${_.gitBranch})`:"",M=_.hasErrors?" ⚠️":"";return{label:`\uD83D\uDCC5 ${I} | ${b}${w} | ${_.messageCount} 条消息${M}`,value:_.sessionId}})},[O]),N=m4(()=>Math.max(1,Math.ceil(F.length/R6)),[F.length]),z=m4(()=>{let _=G*R6;return F.slice(_,_+R6)},[F,G]),L=m4(()=>({start:G*R6+1,end:Math.min((G+1)*R6,F.length)}),[G,F.length]);fQ(()=>{K(0)},[O.length]);let B=(_)=>{Y(_.value)};if(J)return h1(C$,{flexDirection:"column",paddingX:2,paddingY:1,children:h1(k0,{children:"⏳ 正在加载会话列表..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(O.length===0)return h1(C$,{flexDirection:"column",paddingX:2,paddingY:1,children:[h1(k0,{color:"yellow",children:"⚠️ 没有找到历史会话"},void 0,!1,void 0,this),h1(k0,{dimColor:!0,children:[`
1800
- `,"提示: 开始一次对话后,会话历史将保存到 ~/.blade/projects/"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this);return h1(C$,{flexDirection:"column",paddingX:2,paddingY:1,children:[h1(k0,{bold:!0,color:"cyan",children:"\uD83D\uDCC2 选择要恢复的会话:"},void 0,!1,void 0,this),h1(k0,{dimColor:!0,children:[`
1797
+ `),K=G.includes("<<<DIFF>>>"),W=G.includes("```");if(K){let U=G.match(/<<<DIFF>>>\s*({[\s\S]*?})\s*<<<\/DIFF>>>/);if(U)try{let H=JSON.parse(U[1]);return g(d1,{flexDirection:"column",children:[g(j7,{patch:H.patch,startLine:H.startLine,matchLine:H.matchLine,terminalWidth:Y},void 0,!1,void 0,this),J&&g(d1,{marginTop:1,children:g(i1,{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 U=G.match(/```(\w+)?\s*\n([\s\S]*?)\n```/);if(U){let H=U[1]||"text",O=U[2];return g(d1,{flexDirection:"column",children:[g(M7,{content:O,language:H,showLineNumbers:!1,terminalWidth:Y},void 0,!1,void 0,this),J&&g(d1,{marginTop:1,children:g(i1,{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 g(d1,{flexDirection:"column",children:[q.map((U,H)=>g(i1,{color:Z.colors.text.primary,children:U},H,!1,void 0,this)),J&&g(d1,{marginTop:1,children:g(i1,{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 bH($,Y){if($===Y)return!0;if(!$||!Y)return $===Y;return $.toolName===Y.toolName&&$.phase===Y.phase&&$.summary===Y.summary}var A6=f4.memo(({content:$,role:Y,terminalWidth:Z,metadata:X,isPending:Q=!1})=>{let J=P1(),q=f4.useMemo(()=>zH(Y,J.colors,X),[Y,J.colors,X]),{color:G,prefix:K}=q;if(Y==="tool"&&X&&"detail"in X){let U=X;if(U.detail)return g(d1,{flexDirection:"column",marginBottom:1,children:[g(d1,{flexDirection:"row",children:[g(d1,{marginRight:1,children:g(i1,{color:G,bold:!0,children:K},void 0,!1,void 0,this)},void 0,!1,void 0,this),g(i1,{color:G,children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),g(d1,{marginLeft:K.length+1,marginTop:1,children:g(AH,{detail:U.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=f4.useMemo(()=>S7($),[$]);return g(d1,{flexDirection:"column",marginBottom:1,children:W.map((U,H)=>{if(U.type==="empty")return g(d1,{height:1},H,!1,void 0,this);return g(d1,{flexDirection:"row",children:[H===0&&g(d1,{marginRight:1,children:g(i1,{color:G,bold:!0,children:K},void 0,!1,void 0,this)},void 0,!1,void 0,this),H>0&&g(d1,{width:K.length+1},void 0,!1,void 0,this),g(d1,{flexGrow:1,children:U.type==="code"?g(_H,{content:U.content,language:U.language,terminalWidth:Z-(K.length+1)},void 0,!1,void 0,this):U.type==="table"&&U.tableData?g(zQ,{headers:U.tableData.headers,rows:U.tableData.rows,terminalWidth:Z-(K.length+1)},void 0,!1,void 0,this):U.type==="heading"?g(NH,{content:U.content,level:U.level||1},void 0,!1,void 0,this):U.type==="list"?g(FQ,{type:U.listType||"ul",marker:U.marker||"-",itemText:U.content,leadingWhitespace:" ".repeat(U.indentation||0)},void 0,!1,void 0,this):U.type==="hr"?g(BH,{terminalWidth:Z-(K.length+1)},void 0,!1,void 0,this):U.type==="diff"&&U.diffData?g(j7,{patch:U.diffData.patch,startLine:U.diffData.startLine,matchLine:U.diffData.matchLine,terminalWidth:Z-(K.length+1)},void 0,!1,void 0,this):U.type==="command-message"?g(LH,{content:U.content},void 0,!1,void 0,this):g(wH,{content:U.content},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},H,!0,void 0,this)})},void 0,!1,void 0,this)},($,Y)=>{return $.content===Y.content&&$.role===Y.role&&$.terminalWidth===Y.terminalWidth&&$.isPending===Y.isPending&&bH($.metadata,Y.metadata)});import{jsxDEV as w1}from"react/jsx-dev-runtime";var IH=({label:$,isSelected:Y})=>w1(P0,{color:Y?"yellow":void 0,children:$},void 0,!1,void 0,this),_Q=({details:$,onResponse:Y})=>{let Z=D2(),Q=z0()==="confirmation-prompt",J=T1(!1),q=$.type==="exitPlanMode",G=$.type==="enterPlanMode",K=$.type==="maxTurnsExceeded";RH((O,F)=>{if(F.ctrl&&O==="c"||F.meta&&O==="c"){J();return}if(F.escape){Y({approved:!1,reason:"用户取消"});return}let z=O.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(G){if(z==="y"){Y({approved:!0});return}if(z==="n"){Y({approved:!1,reason:"用户拒绝进入 Plan 模式"});return}}else if(K){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 W=DH(()=>{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]),H=(()=>{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 w1(A0,{flexDirection:"column",borderStyle:"round",borderColor:Q?H.color:"gray",padding:1,children:[w1(A0,{marginBottom:1,children:w1(P0,{bold:!0,color:H.color,children:H.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),$.title&&w1(A0,{marginBottom:1,children:w1(P0,{bold:!0,children:$.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),w1(A0,{marginBottom:1,children:w1(P0,{children:$.message},void 0,!1,void 0,this)},void 0,!1,void 0,this),($.planContent||$.details)&&w1(A0,{flexDirection:"column",marginBottom:1,borderStyle:"single",borderColor:H.color,padding:1,children:[w1(P0,{bold:!0,color:H.color,children:q?"\uD83D\uDCCB Implementation Plan:":G?"\uD83D\uDCDD Details:":"\uD83D\uDCC4 Operation Details:"},void 0,!1,void 0,this),w1(A0,{marginTop:1,children:w1(A6,{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&&w1(A0,{flexDirection:"column",marginBottom:1,children:[w1(P0,{color:"red",bold:!0,children:"⚠️ 风险提示:"},void 0,!1,void 0,this),$.risks.map((O,F)=>w1(A0,{marginLeft:2,children:w1(P0,{color:"red",children:["• ",O]},void 0,!0,void 0,this)},F,!1,void 0,this))]},void 0,!0,void 0,this),$.affectedFiles&&$.affectedFiles.length>0&&w1(A0,{flexDirection:"column",marginBottom:1,children:[w1(P0,{color:"yellow",children:"\uD83D\uDCC1 影响的文件:"},void 0,!1,void 0,this),$.affectedFiles.slice(0,3).map((O,F)=>w1(A0,{marginLeft:2,children:w1(P0,{children:["• ",O]},void 0,!0,void 0,this)},F,!1,void 0,this)),$.affectedFiles.length>3&&w1(A0,{marginLeft:2,children:w1(P0,{color:"gray",children:["...还有 ",$.affectedFiles.length-3," 个文件"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w1(A0,{flexDirection:"column",children:[w1(P0,{color:"gray",children:"使用 ↑ ↓ 选择,回车确认(支持 Y/S/N 快捷键,ESC 取消)"},void 0,!1,void 0,this),w1(VH,{items:W,isFocused:Q,itemComponent:IH,onSelect:(O)=>{Y(O.value)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{useMemoizedFn as IQ}from"ahooks";import{Box as hH,Text as xH}from"ink";import pH from"react";import{useMemoizedFn as kH}from"ahooks";import i2 from"chalk";import{Text as PH,useInput as TH}from"ink";import{useEffect as h7,useRef as x7}from"react";var q2={TIMEOUT_MS:100,RAPID_INPUT_THRESHOLD_MS:150,LARGE_INPUT_THRESHOLD:300,MEDIUM_SIZE_MULTI_CHUNK_THRESHOLD:200};import{execSync as f$}from"node:child_process";import{existsSync as MH,readFileSync as C7}from"node:fs";import{basename as NQ,isAbsolute as jH}from"node:path";function vH(){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 Vj=vH();function BQ($){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 wQ(){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 yH(){let{commands:$}=wQ();try{return f$($.getPath,{encoding:"utf-8"}).trim()}catch(Y){return console.error("Failed to get clipboard path:",Y),null}}function LQ($){if($.startsWith('"')&&$.endsWith('"')||$.startsWith("'")&&$.endsWith("'"))return $.slice(1,-1);return $}function AQ($){if(process.platform==="win32")return $;let Y="__DOUBLE_BACKSLASH__";return $.replace(/\\\\/g,Y).replace(/\\(.)/g,"$1").replace(new RegExp(Y,"g"),"\\")}function f7($){let Y=LQ($.trim()),Z=AQ(Y);return/\.(png|jpe?g|gif|webp)$/i.test(Z)}function EH($){let Y=LQ($.trim()),Z=AQ(Y);if(f7(Z))return Z;return null}async function bQ($){let Y=EH($);if(!Y)return null;let Z;try{if(jH(Y))Z=C7(Y);else{let q=yH();if(q&&Y===NQ(q))Z=C7(q);else return null}}catch(q){return console.error("Failed to read image file:",q),null}let X=Z.toString("base64"),Q=BQ(X),J=NQ(Y);return{path:Y,base64:X,mediaType:Q,filename:J}}async function RQ(){let $=process.platform,Y={darwin:"pbpaste",linux:"xclip -selection clipboard -o || wl-paste",win32:'powershell -Command "Get-Clipboard"'},Z=Y[$]||Y.linux;try{return f$(Z,{encoding:"utf-8"})||null}catch{return null}}async function VQ(){let{commands:$,screenshotPath:Y}=wQ();try{if(f$($.checkImage,{stdio:"ignore"}),f$($.saveImage(Y),{stdio:"ignore"}),!MH(Y))return null;let X=C7(Y).toString("base64"),Q=BQ(X);return f$($.deleteFile(Y),{stdio:"ignore"}),{base64:X,mediaType:Q}}catch(Z){try{f$($.deleteFile(Y),{stdio:"ignore"})}catch{}return null}}import{jsxDEV as fH}from"react/jsx-dev-runtime";var SH=/\r\n/g,CH=/\r/g;function r2($){if(!$.includes("\r"))return $;return $.replace(SH,`
1798
+ `).replace(CH,`
1799
+ `)}function a2($,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 DQ({value:$,placeholder:Y="",focus:Z=!0,onChange:X,cursorPosition:Q,onChangeCursorPosition:J,onPaste:q,onImagePaste:G,disabledKeys:K=[]}){let W=x7({chunks:[],timeoutId:null,firstInputTime:null,lastInputTime:null,totalLength:0}),U=x7($),H=x7(Q);h7(()=>{U.current=$,H.current=Q},[$,Q]),h7(()=>{return()=>{if(W.current.timeoutId)clearTimeout(W.current.timeoutId)}},[]),h7(()=>{if(Q>$.length)J($.length)},[$,Q,J]);let O=kH(()=>{let w=W.current;if(w.timeoutId)clearTimeout(w.timeoutId);let B=setTimeout(async()=>{let N=W.current.chunks,I=W.current.totalLength;if(N.length===0)return;let M=r2(N.join(""));W.current={chunks:[],timeoutId:null,firstInputTime:null,lastInputTime:null,totalLength:0};let A=U.current,D=H.current;if(G&&f7(M))try{let R=await bQ(M);if(R){let T=await G(R.base64,R.mediaType,R.filename);if(T?.prompt){let Y1=r2(T.prompt),{newValue:r,newCursorPosition:t}=a2(Y1,A,D);X(r),J(t)}return}}catch(R){console.error("Failed to process image path:",R)}let L=M.includes(`
1800
+ `),V=I>q2.MEDIUM_SIZE_MULTI_CHUNK_THRESHOLD&&N.length>3;if((I>q2.LARGE_INPUT_THRESHOLD||L||V)&&q){let R=await q(M);if(R?.prompt){let T=r2(R.prompt),{newValue:Y1,newCursorPosition:r}=a2(T,A,D);X(Y1),J(r);return}}let{newValue:k,newCursorPosition:f}=a2(M,A,D);X(k),J(f)},q2.TIMEOUT_MS);W.current.timeoutId=B});TH((w,B)=>{let N=r2(w);if(K.some((V)=>B[V])||B.ctrl&&w==="c"||B.shift&&B.tab||N==="?"&&$==="")return;let M=Date.now(),A=W.current,D=Q,L=$;if(B.leftArrow)D--;else if(B.rightArrow)D++;else if(B.backspace||B.delete){if(w===""){if(Q>0)L=$.slice(0,Q-1)+$.slice(Q,$.length),D--}else if(Q<$.length)L=$.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")L=$.slice(0,Q);else if(B.ctrl&&N==="u")L=$.slice(Q),D=0;else if(B.ctrl&&N==="w"){let v=$.slice(0,Q).match(/\s*\S+\s*$/);if(v){let k=v[0].length;L=$.slice(0,Q-k)+$.slice(Q),D-=k}}else if(B.ctrl&&N==="v"){let V=process.platform==="darwin";(async()=>{if(G){let k=await VQ();if(k){let f=await G(k.base64,k.mediaType,"clipboard.png");if(f?.prompt){let R=r2(f.prompt),{newValue:T,newCursorPosition:Y1}=a2(R,U.current,H.current);X(T),J(Y1)}return}}if(V)return;let v=await RQ();if(v){let k=r2(v),f=k.includes(`
1801
+ `),R=k.length>q2.LARGE_INPUT_THRESHOLD;if((f||R)&&q){let r=await q(k);if(r?.prompt){let t=r2(r.prompt),{newValue:p,newCursorPosition:C0}=a2(t,U.current,H.current);X(p),J(C0);return}}let{newValue:T,newCursorPosition:Y1}=a2(k,U.current,H.current);X(T),J(Y1)}})().catch(()=>{});return}else if(B.pageUp)D=0;else if(B.pageDown)D=$.length;else if(N===`
1802
+ `&&(B.shift||B.meta)){let{newValue:V,newCursorPosition:v}=a2(N,$,Q);X(V),J(v);return}else if(!B.ctrl&&!B.meta){if(!A.firstInputTime)A.firstInputTime=M;A.lastInputTime=M;let V=M-(A.firstInputTime||M),v=N.length>q2.LARGE_INPUT_THRESHOLD,k=N.includes(`
1803
+ `)&&N.length>1,f=V<q2.RAPID_INPUT_THRESHOLD_MS&&A.chunks.length>0,R=V<q2.RAPID_INPUT_THRESHOLD_MS&&N.length>10,T=A.timeoutId!==null;if(q&&(v||k||f||R||T)){A.chunks.push(N),A.totalLength+=N.length,O();return}if(N.length===1&&!A.timeoutId)A.chunks=[],A.firstInputTime=null,A.lastInputTime=null,A.totalLength=0;L=$.slice(0,Q)+N+$.slice(Q,$.length),D+=N.length}if(D<0)D=0;if(D>L.length)D=L.length;if(L!==$)X(L);if(D!==Q)J(D)},{isActive:Z});let F=Z,z=$,_=Y?i2.grey(Y):void 0;if(F)if(_=Y.length>0?i2.inverse(Y[0])+i2.grey(Y.slice(1)):i2.inverse(" "),$.length===0)z=i2.inverse(" ");else{z="";for(let w=0;w<$.length;w++)if(w===Q&&Q<$.length)z+=i2.inverse($[w]);else z+=$[w];if(Q>=$.length)z+=i2.inverse(" ")}return fH(PH,{children:Y?$.length>0?z:_:z},void 0,!1,void 0,this)}import{jsxDEV as p7}from"react/jsx-dev-runtime";var MQ=pH.memo(({input:$,cursorPosition:Y,onChange:Z,onChangeCursorPosition:X,onAddPasteMapping:Q,onAddImagePasteMapping:J})=>{let G=z0()==="main-input",K=IQ((U)=>{let H=U.split(`
1804
+ `).length,O=U.length,F=500,z=10;if(O>500||H>10){let _=Q(U),w=U.slice(0,30).replace(/\n/g," "),B=`${O} chars, ${H} lines: ${w}...`;return{prompt:`${k4(_)}${B}${_7()}`}}return{}}),W=IQ(async(U,H,O)=>{try{let F=J(U,H);return{prompt:`${k4(F)}[Image #${F}]${_7()}`}}catch(F){return console.error("[Image Paste] Failed to process image:",F),{prompt:`[Image paste failed: ${F instanceof Error?F.message:"Unknown error"}] `}}});return p7(hH,{flexDirection:"row",width:"100%",paddingX:2,paddingY:0,flexShrink:0,flexGrow:0,overflow:"hidden",borderStyle:"round",borderColor:"gray",children:[p7(xH,{color:"blue",bold:!0,children:"> "},void 0,!1,void 0,this),p7(DQ,{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 h4,Text as T0}from"ink";import cH,{useEffect as lH,useState as iH}from"react";import{useEffect as uH,useState as EQ}from"react";import{useEffect as gH,useState as mH}from"react";var dH=15000,jQ=["炼化代码灵气...","参悟 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 广纳贤才..."],vQ=["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 yQ($,Y){let[Z,X]=mH("");return gH(()=>{if(Y){X("等待用户确认...");return}if(!$){X("");return}let Q=()=>{if(Math.random()<0.16666666666666666){let K=Math.floor(Math.random()*vQ.length);return vQ[K]}let G=Math.floor(Math.random()*jQ.length);return jQ[G]};X(Q());let J=setInterval(()=>{X(Q())},dH);return()=>{clearInterval(J)}},[$,Y]),Z}function kQ($,Y=!1){let[Z,X]=EQ(0),[Q,J]=EQ(null),q=yQ($,Y);return uH(()=>{if(!$){X(0),J(null);return}if(Q===null)J(Date.now());let G=setInterval(()=>{if(Q!==null){let K=Math.floor((Date.now()-Q)/1000);X(K)}},1000);return()=>{clearInterval(G)}},[$,Q]),{currentPhrase:q,elapsedTime:Z}}import{jsxDEV as r1,Fragment as aH}from"react/jsx-dev-runtime";var g7=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"],rH=80;function PQ($){if($<60)return`${$}s`;let Y=Math.floor($/60),Z=$%60;return`${Y}m ${Z}s`}var TQ=cH.memo(({message:$})=>{let Y=i0(),Z=L4(),X=Y||!Z,[Q,J]=iH(0),q=P1(),K=D2()>=rH,{currentPhrase:W,elapsedTime:U}=kQ(X,!1);if(lH(()=>{if(!X){J(0);return}let O=setInterval(()=>{J((F)=>(F+1)%g7.length)},80);return()=>clearInterval(O)},[X]),!X)return null;let H=W||$||"正在思考中...";if(K)return r1(h4,{paddingX:2,paddingBottom:1,flexDirection:"row",gap:1,children:[r1(T0,{color:q.colors.warning,bold:!0,children:g7[Q]},void 0,!1,void 0,this),r1(T0,{color:q.colors.text.primary,children:H},void 0,!1,void 0,this),U>0&&r1(aH,{children:[r1(T0,{color:q.colors.muted,children:"|"},void 0,!1,void 0,this),r1(T0,{color:q.colors.info,children:["已用时: ",PQ(U)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),r1(T0,{color:q.colors.muted,children:"|"},void 0,!1,void 0,this),r1(T0,{color:q.colors.secondary,children:"Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return r1(h4,{paddingX:2,paddingBottom:1,flexDirection:"column",children:[r1(h4,{flexDirection:"row",gap:1,children:[r1(T0,{color:q.colors.warning,bold:!0,children:g7[Q]},void 0,!1,void 0,this),r1(T0,{color:q.colors.text.primary,children:H},void 0,!1,void 0,this)]},void 0,!0,void 0,this),U>0&&r1(h4,{marginLeft:2,flexDirection:"row",gap:1,children:[r1(T0,{color:q.colors.info,children:["已用时: ",PQ(U)]},void 0,!0,void 0,this),r1(T0,{color:q.colors.muted,children:"|"},void 0,!1,void 0,this),r1(T0,{color:q.colors.secondary,children:"Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});import JO from"ansi-escapes";import{Box as x$,Static as qO,useStdout as GO}from"ink";import gQ,{useEffect as mQ,useMemo as V6,useRef as KO}from"react";import{Box as nH,Text as SQ}from"ink";import oH from"react";import{jsxDEV as m7}from"react/jsx-dev-runtime";var d7=oH.memo(({collapsedCount:$})=>{let Y=P1();if($<=0)return null;let Z=Y.colors.text.muted;return m7(nH,{flexDirection:"row",marginBottom:1,children:[m7(SQ,{color:Z,children:["▶ ",$," 条历史消息"]},void 0,!0,void 0,this),m7(SQ,{color:Z,children:" [Ctrl+O 展开]"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});d7.displayName="CollapsedHistorySummary";u$();import{Box as b6,Text as R6}from"ink";import sH from"ink-big-text";import tH from"ink-gradient";import eH from"react";import{jsxDEV as b0}from"react/jsx-dev-runtime";var CQ=eH.memo(()=>{return b0(b6,{flexDirection:"column",paddingX:2,paddingTop:1,paddingBottom:1,children:[b0(b6,{flexDirection:"column",children:b0(tH,{name:"pastel",children:b0(sH,{text:"BLADE",font:"block"},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),b0(b6,{marginBottom:1,children:b0(R6,{color:"white",dimColor:!0,children:X5()},void 0,!1,void 0,this)},void 0,!1,void 0,this),b0(b6,{flexDirection:"column",marginBottom:1,children:[b0(b6,{marginBottom:1,children:b0(R6,{color:"white",bold:!0,children:"使用指南:"},void 0,!1,void 0,this)},void 0,!1,void 0,this),b0(R6,{color:"white",children:"1. 输入问题、编辑文件或运行命令"},void 0,!1,void 0,this),b0(R6,{color:"white",children:"2. 使用 /init 创建项目配置文件"},void 0,!1,void 0,this),b0(R6,{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 u7,Text as h$}from"ink";import $O,{useMemo as fQ}from"react";import{jsxDEV as G2}from"react/jsx-dev-runtime";function YO($,Y=60){if(!$)return"";let Z=$.split(`
1805
+ `)[0]||"";if(Z.length<=Y)return Z;return`${Z.slice(0,Y)}...`}function ZO($){if(!$)return 0;return $.split(`
1806
+ `).length}var c7=$O.memo(({content:$,isStreaming:Y=!1,isExpanded:Z})=>{let X=P1(),Q=fQ(()=>ZO($),[$]),J=fQ(()=>YO($),[$]),q=X.colors.info,G=X.colors.muted;return G2(u7,{flexDirection:"column",marginBottom:1,children:[G2(u7,{flexDirection:"row",children:[G2(h$,{color:q,children:Z?"▼":"▶"},void 0,!1,void 0,this),G2(h$,{children:" "},void 0,!1,void 0,this),G2(h$,{color:G,children:["Thinking",Y?"...":` (${Q} lines)`]},void 0,!0,void 0,this),!Z&&!Y&&J&&G2(h$,{color:G,children:[" - ",J]},void 0,!0,void 0,this),G2(h$,{color:G,dimColor:!0,children:[" ","[Ctrl+T]"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Z&&$&&G2(u7,{marginLeft:2,marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,paddingY:0,children:G2(h$,{color:G,children:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});c7.displayName="ThinkingBlock";import{Box as x4,Text as l7}from"ink";O2();import{useState as hQ}from"react";function XO(){let[$,Y]=hQ(V1.getTheme()),[Z,X]=hQ(V1.getCurrentThemeName()),Q=(K)=>{try{V1.setTheme(K),Y(V1.getTheme()),X(K)}catch(W){console.error("Failed to change theme:",W)}},J=V1.getAvailableThemes();return{theme:$,themeName:Z,changeTheme:Q,availableThemes:J,hasTheme:(K)=>V1.hasTheme(K),getThemeByName:(K)=>V1.getThemeByName(K),colors:$.colors,spacing:$.spacing,typography:$.typography}}function xQ(){let{colors:$}=XO();return $}import{jsxDEV as I2}from"react/jsx-dev-runtime";var pQ=({todos:$,visible:Y=!0,compact:Z=!1})=>{let X=xQ();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 I2(x4,{flexDirection:"column",borderStyle:"single",borderColor:X.border.light,paddingX:1,paddingY:Z?0:1,marginBottom:1,children:[I2(x4,{marginBottom:Z?0:1,children:[I2(l7,{dimColor:!0,children:"Tasks "},void 0,!1,void 0,this),I2(l7,{color:X.text.muted,children:[Q.completed,"/",Q.total]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),I2(x4,{flexDirection:"column",children:$.map((J,q)=>I2(QO,{todo:J,compact:Z},J.id||q,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},QO=({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 I2(x4,{paddingY:Y?0:0,children:I2(l7,{dimColor:X,children:[Z," ",Q]},void 0,!0,void 0,this)},void 0,!1,void 0,this)};import{jsxDEV as G0}from"react/jsx-dev-runtime";var dQ=gQ.memo(()=>{let $=B4(),Y=i0(),Z=EZ(),X=SZ(),Q=pZ(),J=mZ(),q=dZ(),G=IZ(),K=cZ(),W=uZ(),U=D2(),{stdout:H}=GO(),O=gQ.useRef(0),F=KO(W);mQ(()=>{O.current=0},[G]),mQ(()=>{if(F.current!==W){if(H)H.write(JO.clearTerminal);O.current=0,F.current=W}},[W,H]);let{completedMessages:z,streamingMessage:_}=V6(()=>{let A=$.length>0?$[$.length-1]:null,D=Y&&A&&A.role==="assistant",L=Math.max(O.current,D?$.length-1:$.length);O.current=L;let V=$.slice(0,L),v=L<$.length?$[L]:null;return{completedMessages:V,streamingMessage:v}},[$,Y]),w=V6(()=>{return Z.some((A)=>A.status==="pending"||A.status==="in_progress")},[Z]),B=V6(()=>{if(W)return 0;return Math.max(0,$.length-K)},[$.length,K,W]),N=(A,D=!1)=>G0(x$,{flexDirection:"column",children:G0(A6,{content:A.content,role:A.role,terminalWidth:U,metadata:A.metadata,isPending:D},void 0,!1,void 0,this)},A.id,!1,void 0,this),I=V6(()=>{return Math.min(B,z.length)},[B,z.length]),M=V6(()=>{let A=[];if(A.push(G0(CQ,{},"header",!1,void 0,this)),I>0)A.push(G0(d7,{collapsedCount:I},"collapsed-summary",!1,void 0,this));return z.forEach((D,L)=>{if(L>=B)A.push(N(D))}),A},[z,U,B,I]);return G0(x$,{flexDirection:"column",flexGrow:1,paddingX:2,children:G0(x$,{flexDirection:"column",flexGrow:1,children:[G0(qO,{items:M,children:(A)=>A},`${G}-${W}`,!1,void 0,this),J&&G0(x$,{marginBottom:1,children:G0(c7,{content:J,isStreaming:Y,isExpanded:q},void 0,!1,void 0,this)},void 0,!1,void 0,this),_&&N(_,!0),X&&w&&G0(x$,{marginTop:1,children:G0(pQ,{todos:Z,visible:!0,compact:!1},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q.map((A,D)=>G0(x$,{flexDirection:"column",children:G0(A6,{content:A.displayText,role:"user",terminalWidth:U},void 0,!1,void 0,this)},`pending-${D}`,!1,void 0,this))]},void 0,!0,void 0,this)},void 0,!1,void 0,this)});z1();import{Box as $1,Text as m,useFocus as uQ,useFocusManager as WO,useInput as m4}from"ink";import UO from"ink-select-input";import HO from"ink-text-input";import{useEffect as OO,useState as D6}from"react";import{jsxDEV as y,Fragment as g4}from"react/jsx-dev-runtime";var FO=({isSelected:$})=>y($1,{marginRight:1,children:y(m,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),zO=({isSelected:$,label:Y})=>y(m,{bold:$,color:$?"yellow":void 0,children:Y},void 0,!1,void 0,this);function _O($){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 NO=({onSelect:$,onCancel:Y,initialProvider:Z})=>{let{isFocused:X}=uQ({id:"provider-step"});m4((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 y($1,{flexDirection:"column",marginBottom:1,children:[y($1,{marginBottom:1,children:y(m,{bold:!0,color:"blue",children:"\uD83D\uDCE1 Step 2: 选择 API 提供商"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y($1,{marginBottom:1,children:y(m,{children:"根据您使用的 LLM 服务选择对应的 API 类型"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y($1,{marginBottom:1,children:y(UO,{items:Q,onSelect:(q)=>$(q.value),indicatorComponent:FO,itemComponent:zO,initialIndex:J},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},p4=({stepNumber:$,icon:Y,title:Z,description:X,hint:Q,examples:J,value:q,placeholder:G,mask:K,previousValue:W,onChange:U,onSubmit:H,onCancel:O})=>{return m4((F,z)=>{if(z.escape)O()},{isActive:!0}),y($1,{flexDirection:"column",marginBottom:1,children:[y($1,{marginBottom:1,children:y(m,{bold:!0,color:"blue",children:[Y," Step ",$,": ",Z]},void 0,!0,void 0,this)},void 0,!1,void 0,this),y($1,{marginBottom:1,children:y(m,{children:X},void 0,!1,void 0,this)},void 0,!1,void 0,this),W&&y($1,{marginBottom:1,children:y(m,{color:"green",children:["✓ ",W]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q&&y($1,{marginBottom:1,children:y(m,{dimColor:!0,children:Q},void 0,!1,void 0,this)},void 0,!1,void 0,this),J&&J.length>0&&y(g4,{children:[y($1,{marginBottom:1,children:y(m,{dimColor:!0,children:"常见示例:"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y($1,{marginBottom:1,paddingLeft:2,children:y(m,{dimColor:!0,children:J.join(`
1807
+ `)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),y($1,{children:[y(m,{bold:!0,color:"cyan",children:["▶"," "]},void 0,!0,void 0,this),y(HO,{value:q,onChange:U,onSubmit:H,placeholder:G,mask:K},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},BO=({mode:$,config:Y,isSaving:Z,onConfirm:X,onBack:Q,onCancel:J})=>{let{isFocused:q}=uQ({id:"confirm-step"});return m4((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}),y($1,{flexDirection:"column",marginBottom:1,children:[y($1,{marginBottom:1,children:y(m,{bold:!0,color:$==="edit"?"yellow":"blue",children:$==="edit"?"\uD83D\uDCBE 确认修改":"✅ Step 6: 确认配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y($1,{marginBottom:1,children:y(m,{children:$==="edit"?"请确认修改内容,保存后将立即生效。":"请确认以下配置信息:"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y($1,{flexDirection:"column",marginBottom:1,paddingLeft:2,children:[y($1,{marginBottom:1,children:[y(m,{dimColor:!0,children:"名称: "},void 0,!1,void 0,this),y(m,{bold:!0,color:"cyan",children:Y.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),y($1,{marginBottom:1,children:[y(m,{dimColor:!0,children:"Provider: "},void 0,!1,void 0,this),y(m,{bold:!0,color:"cyan",children:_O(Y.provider)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),y($1,{marginBottom:1,children:[y(m,{dimColor:!0,children:"Base URL: "},void 0,!1,void 0,this),y(m,{bold:!0,color:"blue",children:Y.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),y($1,{marginBottom:1,children:[y(m,{dimColor:!0,children:"API Key: "},void 0,!1,void 0,this),y(m,{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),y($1,{children:[y(m,{dimColor:!0,children:"Model: "},void 0,!1,void 0,this),y(m,{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&&y($1,{marginTop:1,children:y(m,{children:[$==="edit"?"保存修改? ":"确认保存配置? ","[",y(m,{bold:!0,color:"green",children:"Y"},void 0,!1,void 0,this),"/",y(m,{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&&y($1,{children:y(m,{color:"yellow",children:"⏳ 正在保存配置到 ~/.blade/config.json..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},i7=({mode:$,initialConfig:Y,modelId:Z,onComplete:X,onCancel:Q})=>{let J=$==="edit",[q,G]=D6("name"),[K,W]=D6(()=>J&&Y?{...Y}:{}),[U,H]=D6(J&&Y?Y.name:""),[O,F]=D6(!1),[z,_]=D6(null),w=T1(!1);m4((R,T)=>{if(T.ctrl&&R==="c"||T.meta&&R==="c")if($==="setup")w();else Q()},{isActive:!0});let{focus:B}=WO();OO(()=>{if(q==="provider")B("provider-step");else if(q==="confirm")B("confirm-step")},[q,B]);let N=()=>{if(!U.trim()){_("配置名称不能为空");return}W({...K,name:U}),H(""),_(null),G("provider")},I=(R)=>{W({...K,provider:R});let T=J?K.baseUrl??Y?.baseUrl??"":"";H(T),G("baseUrl")},M=()=>{if(!U.trim()){_("Base URL 不能为空");return}try{new URL(U)}catch{_("请输入有效的 URL (例如: https://api.openai.com/v1)");return}W({...K,baseUrl:U});let R=J?K.apiKey??Y?.apiKey??"":"";H(R),_(null),G("apiKey")},A=()=>{if(!U.trim()){_("API Key 不能为空");return}W({...K,apiKey:U});let R=J?K.model??Y?.model??"":"";H(R),_(null),G("model")},D=()=>{if(!U.trim()){_("Model 不能为空");return}W({...K,model:U}),H(""),_(null),G("confirm")},L=async()=>{F(!0),_(null);try{let R={name:K.name,provider:K.provider,baseUrl:K.baseUrl,apiKey:K.apiKey,model:K.model};if($==="setup")X(R);else if($==="add"){let T=await F1().addModel(R);await F1().setCurrentModel(T.id),X(R)}else{if(!Z)throw Error("未提供模型 ID,无法编辑");await F1().updateModel(Z,R),X(R)}}catch(R){_(R instanceof Error?R.message:"配置失败"),F(!1)}},V=()=>{switch(_(null),H(""),q){case"provider":H(K.name||""),G("name");break;case"baseUrl":G("provider");break;case"apiKey":H(K.baseUrl||""),G("baseUrl");break;case"model":G("apiKey");break;case"confirm":H(K.model||""),G("model");break}},v=q==="name"?1:q==="provider"?2:q==="baseUrl"?3:q==="apiKey"?4:q==="model"?5:6,k=Math.floor((v-1)/5*40);return y($1,{...$==="setup"?{flexDirection:"column",padding:1}:$==="add"?{flexDirection:"column",borderStyle:"round",borderColor:"blue",padding:1}:{flexDirection:"column",borderStyle:"round",borderColor:"yellow",padding:1},children:[$==="setup"?y(g4,{children:[y($1,{marginBottom:1,children:y(m,{bold:!0,color:"blue",children:"\uD83D\uDE80 欢迎使用 Blade Code"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y($1,{marginBottom:1,children:y(m,{children:"AI 驱动的代码助手 - 让我们开始配置您的助手"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y($1,{marginBottom:1,children:[y(m,{bold:!0,color:"blue",children:"█".repeat(k)},void 0,!1,void 0,this),y(m,{dimColor:!0,children:"░".repeat(40-k)},void 0,!1,void 0,this),y(m,{children:" "},void 0,!1,void 0,this),y(m,{bold:!0,color:"cyan",children:[v,"/6"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),y($1,{marginBottom:1,children:y(m,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this):$==="add"?y(g4,{children:[y($1,{justifyContent:"center",marginBottom:1,children:y(m,{bold:!0,color:"blue",children:"添加新模型配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y($1,{marginBottom:1,children:y(m,{children:["步骤: ",v,"/6"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this):y(g4,{children:[y($1,{justifyContent:"center",marginBottom:1,children:y(m,{bold:!0,color:"yellow",children:"编辑模型配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),y($1,{marginBottom:1,children:y(m,{children:["步骤: ",v,"/6"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),q==="name"&&y(p4,{stepNumber:1,icon:"\uD83D\uDCDD",title:"配置名称",description:"给这个模型配置起一个易于识别的名称",value:U,placeholder:"例如: 千问工作账号",onChange:H,onSubmit:N,onCancel:Q},void 0,!1,void 0,this),q==="provider"&&y(NO,{onSelect:I,onCancel:Q,initialProvider:K.provider},void 0,!1,void 0,this),q==="baseUrl"&&y(p4,{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:U,placeholder:"https://api.example.com/v1",onChange:H,onSubmit:M,onCancel:Q},void 0,!1,void 0,this),q==="apiKey"&&y(p4,{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:U,placeholder:"sk-...",mask:"*",onChange:H,onSubmit:A,onCancel:Q},void 0,!1,void 0,this),q==="model"&&y(p4,{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:U,placeholder:"例如: gpt-5",onChange:H,onSubmit:D,onCancel:Q},void 0,!1,void 0,this),q==="confirm"&&y(BO,{mode:$,config:K,isSaving:O,onConfirm:L,onBack:V,onCancel:Q},void 0,!1,void 0,this),z&&y($1,{marginTop:1,borderStyle:"round",borderColor:"red",paddingX:1,children:y(m,{color:"red",children:["❌ ",z]},void 0,!0,void 0,this)},void 0,!1,void 0,this),y($1,{marginTop:1,children:y(m,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this),!O&&q==="provider"&&y($1,{marginTop:1,children:y(m,{dimColor:!0,children:["\uD83D\uDCA1 使用 ",y(m,{bold:!0,children:"↑/↓"},void 0,!1,void 0,this)," 键选择,",y(m,{bold:!0,children:"Enter"},void 0,!1,void 0,this)," 确认,",y(m,{bold:!0,children:"Esc"},void 0,!1,void 0,this)," 取消"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),!O&&q!=="confirm"&&q!=="provider"&&y($1,{marginTop:1,children:y(m,{dimColor:!0,children:["\uD83D\uDCA1 输入完成后按 ",y(m,{bold:!0,children:"Enter"},void 0,!1,void 0,this),",",y(m,{bold:!0,children:"Ctrl+C"},void 0,!1,void 0,this)," 退出"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),!O&&q==="confirm"&&y($1,{marginTop:1,children:y(m,{dimColor:!0,children:["\uD83D\uDCA1 按"," ",y(m,{bold:!0,color:"green",children:"Y"},void 0,!1,void 0,this)," ","保存,",y(m,{bold:!0,color:"red",children:"N"},void 0,!1,void 0,this)," ","返回修改,",y(m,{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 d4,useMount as wO}from"ahooks";import{Box as R0,Text as W1,useFocus as LO,useFocusManager as AO,useInput as bO}from"ink";import RO from"ink-select-input";import{memo as VO,useMemo as DO,useState as u4}from"react";z1();import{jsxDEV as o}from"react/jsx-dev-runtime";var IO=({isSelected:$})=>o(R0,{marginRight:1,children:o(W1,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),MO=({isSelected:$,label:Y})=>o(W1,{bold:$,color:$?"yellow":void 0,children:Y},void 0,!1,void 0,this),cQ=VO(({onClose:$,onEdit:Y})=>{let Z=CZ(),X=fZ()??"",{isFocused:Q}=LO({id:"model-selector"}),J=AO(),[q,G]=u4(""),[K,W]=u4(!1),[U,H]=u4(null),O=T1(!1),[F]=u4(()=>{let D=process.stdout?.columns||80;return Math.max(20,D-8)});wO(()=>{if(J?.focus("model-selector"),Z.length>0)G(Z[0].id)}),bO((D,L)=>{if(K)return;if(L.ctrl&&D==="c"||L.meta&&D==="c"){O();return}if(L.escape){$();return}if(!Q)return;if(D==="d"||D==="D"){_();return}if((D==="e"||D==="E")&&Y)w()},{isActive:!0});let z=d4(async(D)=>{if(K)return;let L=D.value;if(L===X){$();return}W(!0),H(null);try{await F1().setCurrentModel(L),$()}catch(V){H(V.message),W(!1)}}),_=d4(async()=>{if(K||q===X)return;W(!0),H(null);try{if(await F1().removeModel(q),Z.length<=1)$()}catch(D){H(D.message)}finally{W(!1)}}),w=d4(()=>{if(K||!Y)return;let D=Z.find((L)=>L.id===q);if(!D)return;Y(D)}),B=d4((D)=>{G(D.value)}),N=DO(()=>{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 o(R0,{flexDirection:"column",borderStyle:"round",borderColor:"gray",padding:1,width:"100%",children:[o(R0,{flexDirection:"row",justifyContent:"space-between",marginBottom:1,children:[o(W1,{bold:!0,color:"cyan",children:"模型管理"},void 0,!1,void 0,this),o(W1,{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),o(R0,{flexDirection:"row",children:[o(R0,{flexDirection:"column",flexGrow:2,marginRight:2,borderStyle:"single",borderColor:"gray",padding:1,children:[o(W1,{dimColor:!0,children:["已配置模型 (",Z.length,")"]},void 0,!0,void 0,this),o(R0,{marginTop:1,children:o(RO,{items:I,onSelect:z,onHighlight:B,indicatorComponent:IO,itemComponent:MO},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o(R0,{flexDirection:"column",flexGrow:3,borderStyle:"single",borderColor:"gray",padding:1,children:[o(W1,{dimColor:!0,children:"模型详情"},void 0,!1,void 0,this),o(R0,{marginY:1,children:o(W1,{color:M?"green":"yellow",children:M?"● 当前使用":"● 可切换"},void 0,!1,void 0,this)},void 0,!1,void 0,this),N?o(R0,{flexDirection:"column",children:[o(W1,{children:[o(W1,{dimColor:!0,children:"名称: "},void 0,!1,void 0,this),o(W1,{bold:!0,color:"cyan",children:N.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o(W1,{children:[o(W1,{dimColor:!0,children:"Provider: "},void 0,!1,void 0,this),o(W1,{bold:!0,children:N.provider},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o(W1,{children:[o(W1,{dimColor:!0,children:"Model: "},void 0,!1,void 0,this),o(W1,{bold:!0,children:N.model},void 0,!1,void 0,this)]},void 0,!0,void 0,this),o(W1,{children:[o(W1,{dimColor:!0,children:"Base URL: "},void 0,!1,void 0,this),o(W1,{color:"blueBright",children:N.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),N.temperature!==void 0&&o(W1,{children:[o(W1,{dimColor:!0,children:"Temperature: "},void 0,!1,void 0,this),o(W1,{children:N.temperature},void 0,!1,void 0,this)]},void 0,!0,void 0,this),N.maxContextTokens!==void 0&&o(W1,{children:[o(W1,{dimColor:!0,children:"Context Window: "},void 0,!1,void 0,this),o(W1,{children:N.maxContextTokens},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this):o(W1,{dimColor:!0,children:"请选择一个模型查看详情"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),U&&o(R0,{marginTop:1,children:o(W1,{color:"red",children:["❌ ",U]},void 0,!0,void 0,this)},void 0,!1,void 0,this),o(R0,{justifyContent:"center",marginTop:1,children:o(W1,{dimColor:!0,children:"─".repeat(F)},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(R0,{justifyContent:"center",children:o(W1,{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 I6}from"ahooks";import{promises as aQ}from"fs";import{Box as K0,Text as L1,useInput as jO}from"ink";import lQ from"ink-select-input";import vO from"ink-text-input";import yO from"os";import c4 from"path";import{useEffect as EO,useMemo as l4,useRef as kO,useState as M2}from"react";z1();import{jsxDEV as s}from"react/jsx-dev-runtime";var M6=[{key:"allow",label:"Allow"},{key:"ask",label:"Ask"},{key:"deny",label:"Deny"},{key:"info",label:"Info"}],PO={allow:"Add a new rule...",ask:"Add a new rule...",deny:"Add a new rule..."},TO={allow:"Allow permission rules",ask:"Ask permission rules",deny:"Deny permission rules"},iQ={project:"[项目共享配置]",global:"[用户全局配置]",local:"[本地配置]"},SO=["project","global","local"],CO={allow:[],ask:[],deny:[]},fO={localExists:!1,projectExists:!1,globalExists:!1},rQ={allow:[],ask:[],deny:[]};function hO($){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 xO($){try{let Y=await aQ.readFile($,"utf-8"),Z=JSON.parse(Y);return{exists:!0,raw:Z,permissions:hO(Z)}}catch(Y){if(Y.code==="ENOENT")return{exists:!1,raw:{},permissions:{...rQ}};return console.warn(`[PermissionsManager] Failed to read ${$}:`,Y),{exists:!0,raw:{},permissions:{...rQ}}}}function pO($,Y){let Z=$.padEnd(32," "),X=Y==="local"?`${iQ[Y]} ← 可删除`:iQ[Y];return`${Z} ${X}`}var nQ=({onClose:$})=>{let Z=z0()==="permissions-manager",X=T1(!1),[Q,J]=M2(0),q=M6[Q].key,[G,K]=M2(CO),[W,U]=M2(fO),[H,O]=M2(!0),[F,z]=M2("list"),[_,w]=M2(""),[B,N]=M2(null),[I,M]=M2(null),A=kO(!1),D=l4(()=>c4.join(process.cwd(),".blade","settings.local.json"),[]),L=l4(()=>c4.join(process.cwd(),".blade","settings.json"),[]),V=l4(()=>c4.join(yO.homedir(),".blade","settings.json"),[]),v=I6(async()=>{O(!0);let i=[{source:"local",path:D},{source:"project",path:L},{source:"global",path:V}],K1=await Promise.all(i.map(async({source:h1,path:e0})=>{let V0=await xO(e0);return{source:h1,path:e0,...V0}})),Z1={localExists:K1.find((h1)=>h1.source==="local")?.exists??!1,projectExists:K1.find((h1)=>h1.source==="project")?.exists??!1,globalExists:K1.find((h1)=>h1.source==="global")?.exists??!1};U(Z1);let Z0={allow:[],ask:[],deny:[]},v2=Object.fromEntries(K1.map((h1)=>[h1.source,h1]));["allow","ask","deny"].forEach((h1)=>{SO.forEach((e0)=>{(v2[e0]?.permissions[h1]??[]).forEach((g$,f0)=>{let y2={key:`${e0}:${f0}:${g$}`,rule:g$,source:e0};Z0[h1].push(y2)})})}),K(Z0),O(!1)});EO(()=>{v()},[v]);let k=I6(async(i,K1)=>{try{let Z1=c4.join(process.cwd(),".blade","settings.local.json"),Z0={allow:[],ask:[],deny:[]};try{let h1=await aQ.readFile(Z1,"utf-8"),V0=JSON.parse(h1).permissions||{};Z0={allow:Array.isArray(V0.allow)?V0.allow:[],ask:Array.isArray(V0.ask)?V0.ask:[],deny:Array.isArray(V0.deny)?V0.deny:[]}}catch(h1){}let v2=K1(Z0);await F1().updateConfig({permissions:v2},{scope:"local",immediate:!0}),await v()}catch(Z1){throw console.error("[PermissionsManager] 修改权限规则失败:",Z1),Z1}});jO((i,K1)=>{if(K1.ctrl&&i==="c"||K1.meta&&i==="c"){X();return}if(F==="locked"){if(A.current){A.current=!1;return}z("list"),N(null),M(null);return}if(K1.escape){if(F==="list"||q==="info")$();else z("list"),w(""),N(null),M(null);return}if(F==="list"){if(K1.tab&&K1.shift)J((Z1)=>(Z1-1+M6.length)%M6.length);else if(K1.tab)J((Z1)=>(Z1+1)%M6.length);else if(i?.toLowerCase()==="q")$()}},{isActive:Z});let f=I6((i)=>{let K1=i.value;if(q==="info")return;if(K1.type==="add"){z("add"),w(""),M(null);return}if(K1.entry.source!=="local"){z("locked"),A.current=!0,N({tab:q,entry:K1.entry}),M({type:"error",text:K1.entry.source==="project"?"此规则定义在项目共享配置中,无法在此删除。":"此规则来自用户全局配置,无法在此删除。"});return}z("confirm-delete"),N({tab:q,entry:K1.entry}),M(null)}),R=I6(async()=>{if(q==="info")return;let i=_.trim();if(!i){M({type:"error",text:"Permission rule 不能为空"});return}if(G[q].map((Z1)=>Z1.rule).includes(i)){M({type:"error",text:"该规则已存在"});return}try{await k(q,(Z1)=>{let Z0={allow:[...Z1.allow],ask:[...Z1.ask],deny:[...Z1.deny]};return Z0[q]=[...new Set([...Z1[q],i])],Z0}),z("list"),w(""),M({type:"success",text:"已添加本地权限规则"})}catch(Z1){M({type:"error",text:`保存失败: ${Z1 instanceof Error?Z1.message:"未知错误"}`})}}),T=I6(async()=>{if(!B)return;let{tab:i,entry:K1}=B;try{await k(i,(Z1)=>{let Z0={allow:[...Z1.allow],ask:[...Z1.ask],deny:[...Z1.deny]};return Z0[i]=Z1[i].filter((v2)=>v2!==K1.rule),Z0}),z("list"),N(null),M({type:"success",text:"已删除本地权限规则"})}catch(Z1){M({type:"error",text:`删除失败: ${Z1 instanceof Error?Z1.message:"未知错误"}`})}}),Y1=l4(()=>{if(q==="info")return[];let i=q;return[{key:"add-new-rule",label:`› ${PO[i]}`,value:{type:"add"}},...G[i].map((Z1)=>({key:Z1.key,label:pO(Z1.rule,Z1.source),value:{type:"rule",entry:Z1}}))]},[q,G]),r=()=>s(K0,{marginBottom:1,children:M6.map((i,K1)=>s(K0,{marginRight:2,children:s(L1,{color:K1===Q?"yellow":"gray",children:["[",i.label,"]"]},void 0,!0,void 0,this)},i.key,!1,void 0,this))},void 0,!1,void 0,this),t=()=>s(K0,{flexDirection:"column",gap:1,children:[s(L1,{children:"配置文件优先级(从高到低):"},void 0,!1,void 0,this),s(K0,{flexDirection:"column",marginLeft:2,children:[s(L1,{children:["1. .blade/settings.local.json (本地配置,不提交 Git)"," ",W.localExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),s(L1,{children:["2. .blade/settings.json (项目配置,提交 Git)"," ",W.projectExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),s(L1,{children:["3. ~/.blade/settings.json (用户全局配置)"," ",W.globalExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),s(L1,{children:"说明:"},void 0,!1,void 0,this),s(K0,{flexDirection:"column",marginLeft:2,children:[s(L1,{children:"- /permissions 命令只管理本地配置 (.blade/settings.local.json)"},void 0,!1,void 0,this),s(L1,{children:"- 修改全局或项目配置请直接编辑对应文件"},void 0,!1,void 0,this),s(L1,{children:"- 本地配置不会提交到 Git"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),p=(i)=>s(K0,{flexDirection:"column",gap:1,children:[s(L1,{bold:!0,children:TO[i]},void 0,!1,void 0,this),s(L1,{children:"Permission rules are a tool name, optionally followed by a specifier in parentheses."},void 0,!1,void 0,this),s(L1,{color:"gray",children:"例如: WebFetch 或 Bash(ls:*)"},void 0,!1,void 0,this),s(K0,{marginTop:1,children:s(vO,{value:_,onChange:w,onSubmit:R},void 0,!1,void 0,this)},void 0,!1,void 0,this),s(L1,{color:"gray",children:"Enter 提交 · Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C0=(i,K1)=>s(K0,{flexDirection:"column",gap:1,children:[s(L1,{bold:!0,children:["Delete ",i," permission rule?"]},void 0,!0,void 0,this),s(L1,{children:K1.rule},void 0,!1,void 0,this),s(L1,{color:"gray",children:"From project local settings"},void 0,!1,void 0,this),s(L1,{children:"Are you sure you want to delete this permission rule?"},void 0,!1,void 0,this),s(lQ,{items:[{label:"Yes",value:"yes"},{label:"No",value:"no"}],onSelect:(Z1)=>{if(Z1.value==="yes")T();else z("list"),N(null)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G1=(i)=>s(K0,{flexDirection:"column",gap:1,children:[s(L1,{bold:!0,children:"Cannot delete this rule"},void 0,!1,void 0,this),s(L1,{children:i.rule},void 0,!1,void 0,this),s(L1,{color:"gray",children:i.source==="project"?"This rule is defined in .blade/settings.json. 请手动编辑该文件以移除规则。":"This rule is defined in ~/.blade/settings.json. 请手动编辑该文件以移除规则。"},void 0,!1,void 0,this),s(L1,{color:"gray",children:"按任意键继续"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),j1=(i)=>s(lQ,{items:Y1,isFocused:F==="list",onSelect:f},void 0,!1,void 0,this),t0=()=>{if(H)return s(L1,{children:"加载中..."},void 0,!1,void 0,this);if(q==="info")return t();if(F==="add")return p(q);if(F==="confirm-delete"&&B)return C0(B.tab,B.entry);if(F==="locked"&&B)return G1(B.entry);return j1(q)};return s(K0,{flexDirection:"column",borderStyle:"round",borderColor:Z?"cyan":"gray",padding:1,width:80,children:[s(L1,{color:"cyan",bold:!0,children:"⚙️ 权限管理器"},void 0,!1,void 0,this),r(),s(K0,{flexDirection:"column",gap:1,children:t0()},void 0,!1,void 0,this),I&&s(K0,{marginTop:1,children:s(L1,{color:I.type==="success"?"green":"red",children:I.text},void 0,!1,void 0,this)},void 0,!1,void 0,this),s(K0,{marginTop:1,children:s(L1,{color:"gray",children:"Tab 切换视图 · Esc 关闭 · Q 退出"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};N4();import{Box as p$,Text as S0,useInput as gO}from"ink";import mO from"ink-select-input";import{useEffect as oQ,useMemo as i4,useState as r7}from"react";import{jsxDEV as p1}from"react/jsx-dev-runtime";function dO($){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 uO($){let Y=$.split("/");return Y[Y.length-1]||$}var cO=({isSelected:$})=>p1(p$,{marginRight:1,children:p1(S0,{color:$?"cyan":"gray",children:$?"❯":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),lO=({isSelected:$,label:Y})=>p1(S0,{color:$?"cyan":"white",bold:$,children:Y},void 0,!1,void 0,this),j6=20,sQ=({sessions:$,onSelect:Y,onCancel:Z})=>{let[X,Q]=r7([]),[J,q]=r7(!1),[G,K]=r7(0),U=z0()==="session-selector",H=T1(!1);gO((N,I)=>{if(I.ctrl&&N==="c"||I.meta&&N==="c"){H();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<z-1)K((M)=>M+1);return}},{isActive:U}),oQ(()=>{if($){Q($);return}(async()=>{q(!0);try{let I=await l0.listSessions();Q(I)}catch(I){console.error("[SessionSelector] Failed to load sessions:",I),Q([])}finally{q(!1)}})()},[$]);let O=$||X,F=i4(()=>{return O.map((N)=>{let I=uO(N.projectPath),M=dO(N.lastMessageTime),A=N.gitBranch?` (${N.gitBranch})`:"",D=N.hasErrors?" ⚠️":"";return{label:`\uD83D\uDCC5 ${M} | ${I}${A} | ${N.messageCount} 条消息${D}`,value:N.sessionId}})},[O]),z=i4(()=>Math.max(1,Math.ceil(F.length/j6)),[F.length]),_=i4(()=>{let N=G*j6;return F.slice(N,N+j6)},[F,G]),w=i4(()=>({start:G*j6+1,end:Math.min((G+1)*j6,F.length)}),[G,F.length]);oQ(()=>{K(0)},[O.length]);let B=(N)=>{Y(N.value)};if(J)return p1(p$,{flexDirection:"column",paddingX:2,paddingY:1,children:p1(S0,{children:"⏳ 正在加载会话列表..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(O.length===0)return p1(p$,{flexDirection:"column",paddingX:2,paddingY:1,children:[p1(S0,{color:"yellow",children:"⚠️ 没有找到历史会话"},void 0,!1,void 0,this),p1(S0,{dimColor:!0,children:[`
1808
+ `,"提示: 开始一次对话后,会话历史将保存到 ~/.blade/projects/"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this);return p1(p$,{flexDirection:"column",paddingX:2,paddingY:1,children:[p1(S0,{bold:!0,color:"cyan",children:"\uD83D\uDCC2 选择要恢复的会话:"},void 0,!1,void 0,this),p1(S0,{dimColor:!0,children:[`
1801
1809
  `,"(←→ 翻页 | ↑↓ 选择 | Enter 确认 | Esc 取消)",`
1802
- `]},void 0,!0,void 0,this),h1(AO,{items:z,onSelect:B,indicatorComponent:VO,itemComponent:DO},void 0,!1,void 0,this),h1(C$,{marginTop:1,flexDirection:"column",children:[h1(k0,{dimColor:!0,children:["第 ",G+1,"/",N," 页 · 共 ",O.length," 个会话 · 显示"," ",L.start,"-",L.end]},void 0,!0,void 0,this),N>1&&h1(C$,{marginTop:1,children:[h1(k0,{color:G>0?"cyan":"gray",children:G>0?"◀ ← 上一页":" "},void 0,!1,void 0,this),h1(k0,{children:" "},void 0,!1,void 0,this),h1(k0,{color:G<N-1?"cyan":"gray",children:G<N-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)};import{useMemoizedFn as IO}from"ahooks";import{Box as i0,Text as C,useInput as MO}from"ink";import jO from"ink-select-input";import{useState as xQ}from"react";_1();import{jsxDEV as P}from"react/jsx-dev-runtime";var pQ=u0.map(($)=>({label:$.label,value:$.id})),vO=({theme:$})=>{let{colors:Y}=$;return P(i0,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[P(C,{bold:!0,color:Y.text.primary,children:"代码预览"},void 0,!1,void 0,this),P(C,{children:" "},void 0,!1,void 0,this),P(C,{color:Y.syntax.comment,children:"# function"},void 0,!1,void 0,this),P(C,{children:[P(C,{color:Y.syntax.keyword,children:"def"},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.function,children:"fibonacci"},void 0,!1,void 0,this),P(C,{color:Y.text.primary,children:"("},void 0,!1,void 0,this),P(C,{color:Y.syntax.variable,children:"n"},void 0,!1,void 0,this),P(C,{color:Y.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(C,{children:[" ",P(C,{color:Y.syntax.variable,children:"a"},void 0,!1,void 0,this),P(C,{color:Y.syntax.operator,children:","},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.operator,children:"="},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.number,children:"0"},void 0,!1,void 0,this),P(C,{color:Y.syntax.operator,children:","},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.number,children:"1"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(C,{children:[" ",P(C,{color:Y.syntax.keyword,children:"for"},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.variable,children:"_"},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.keyword,children:"in"},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.function,children:"range"},void 0,!1,void 0,this),P(C,{color:Y.text.primary,children:"("},void 0,!1,void 0,this),P(C,{color:Y.syntax.variable,children:"n"},void 0,!1,void 0,this),P(C,{color:Y.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(C,{children:[" ",P(C,{color:Y.syntax.variable,children:"a"},void 0,!1,void 0,this),P(C,{color:Y.syntax.operator,children:","},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.operator,children:"="},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.variable,children:"b"},void 0,!1,void 0,this),P(C,{color:Y.syntax.operator,children:","},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.variable,children:"a"},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.operator,children:"+"},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.variable,children:"b"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(C,{children:[" ",P(C,{color:Y.syntax.keyword,children:"return"},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.variable,children:"a"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(C,{children:" "},void 0,!1,void 0,this),P(C,{color:Y.error,children:["- print(",P(C,{color:Y.syntax.string,children:'"Hello, "'},void 0,!1,void 0,this)," + name)"]},void 0,!0,void 0,this),P(C,{color:Y.success,children:["+ print(",P(C,{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)},yO=({theme:$})=>{let{colors:Y}=$;return P(i0,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[P(C,{children:" "},void 0,!1,void 0,this),P(C,{bold:!0,color:Y.text.primary,children:"颜色配置"},void 0,!1,void 0,this),P(C,{children:" "},void 0,!1,void 0,this),P(C,{children:[P(C,{color:Y.text.muted,children:"Primary: "},void 0,!1,void 0,this),P(C,{color:Y.primary,children:Y.primary},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(C,{children:[P(C,{color:Y.text.muted,children:"Success: "},void 0,!1,void 0,this),P(C,{color:Y.success,children:Y.success},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(C,{children:[P(C,{color:Y.text.muted,children:"Error: "},void 0,!1,void 0,this),P(C,{color:Y.error,children:Y.error},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(C,{children:[P(C,{color:Y.text.muted,children:"Warning: "},void 0,!1,void 0,this),P(C,{color:Y.warning,children:Y.warning},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(C,{children:[P(C,{color:Y.text.muted,children:"Info: "},void 0,!1,void 0,this),P(C,{color:Y.info,children:Y.info},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},gQ=()=>{let $=L2(),Y=J1.getCurrentThemeName(),Z=u0.findIndex((N)=>N.label===Y),X=Z>=0?u0[Z].theme:u0[0].theme,[Q,J]=xQ(X),[q,G]=xQ(!1),K=IO(async(N)=>{if(q)return;G(!0);try{J1.setTheme(N.value),await z1().setTheme(N.value),$.closeModal()}catch(z){console.error("❌ 主题切换失败:",z instanceof Error?z.message:z)}finally{G(!1)}}),W=(N)=>{let z=u0.find((L)=>L.id===N.value);if(z)J(z.theme)},H=H0()==="theme-selector",O=k1(!1);MO((N,z)=>{if(z.ctrl&&N==="c"||z.meta&&N==="c"){O();return}if(z.escape&&!q)$.closeModal()},{isActive:H});let F=(N)=>{let{isSelected:z,label:L}=N,_=L===Y?"✓":" ";return P(C,{color:z?Q.colors.primary:Q.colors.text.primary,children:[_," ",L]},void 0,!0,void 0,this)};return P(i0,{flexDirection:"column",height:"100%",children:[P(i0,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:Q.colors.border.light,children:P(C,{bold:!0,color:Q.colors.primary,children:"\uD83C\uDFA8 主题选择器"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(i0,{flexDirection:"row",flexGrow:1,children:[P(i0,{width:"40%",borderStyle:"single",borderColor:Q.colors.border.light,paddingX:1,children:P(i0,{flexDirection:"column",children:[P(i0,{paddingTop:1,paddingBottom:1,children:P(C,{bold:!0,color:Q.colors.text.primary,children:["可用主题 (",pQ.length,")"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),P(jO,{items:pQ,initialIndex:Z>=0?Z:0,onSelect:K,onHighlight:W,itemComponent:F},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),P(i0,{width:"60%",flexDirection:"column",borderStyle:"single",borderColor:Q.colors.border.light,children:[P(vO,{theme:Q},void 0,!1,void 0,this),P(yO,{theme:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),P(i0,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:Q.colors.border.light,children:P(C,{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 I1}from"react/jsx-dev-runtime";var G0=i("UI"),mQ=({debug:$,...Y})=>{if($)G0.debug("[Debug] BladeInterface props:",{permissionMode:Y.permissionMode,yolo:Y.yolo,maxTurns:Y.maxTurns});let Z=d4(!1),X=d4(!1),Q=d4(!1),J=d4(null),q=zZ(),G=_Z(),K=H4(),W=LZ(),U=BZ(),H=L2(),O=b$(),F=VZ(),N=R$(),z=m0(),{exit:L}=EO(),B=q==="ready",_=q==="needsSetup",b=q==="idle",{confirmationState:I,confirmationHandler:w,handleResponse:M}=IX(),{executeCommand:V,handleAbort:D}=bX(Y.systemPrompt,Y.appendSystemPrompt,w,Y.maxTurns),{getPreviousCommand:y,getNextCommand:k,addToHistory:f}=VX();hX();let A=jX("",0),T=e1(async()=>{let a=N,F1;if(a==="default")F1="autoEdit";else if(a==="autoEdit")F1="plan";else F1="default";try{await z1().setPermissionMode(F1)}catch(A0){G0.error("❌ 权限模式切换失败:",A0 instanceof Error?A0.message:A0)}}),Y1=e1(async(a)=>{try{await z1().addModel({name:a.name,provider:a.provider,apiKey:a.apiKey,baseUrl:a.baseUrl,model:a.model}),H.setInitializationStatus("ready")}catch(F1){G0.error("❌ 初始化配置保存失败:",F1 instanceof Error?F1.message:F1),H.setInitializationStatus("ready")}}),r=e1(()=>{if(K==="shortcuts")H.closeModal();else H.setActiveModal("shortcuts")}),{showSuggestions:t,suggestions:p,selectedSuggestionIndex:P0}=fX(A,V,y,k,f,D,z,T,r,K==="shortcuts");i2(()=>{if(A.value&&K==="shortcuts")H.closeModal()},[A.value,K,H]);let G1=e1(async()=>{try{if(typeof Y.resume==="string"&&Y.resume!=="true"){let F1=await g0.loadSession(Y.resume),A0=F1.map((o0,h$)=>({id:`restored-${Date.now()}-${h$}`,role:o0.role,content:typeof o0.content==="string"?o0.content:JSON.stringify(o0.content),timestamp:Date.now()-(F1.length-h$)*1000}));O.restoreSession(Y.resume,A0);return}let a=await g0.listSessions();if(a.length===0)G0.error("没有找到历史会话"),process.exit(1);H.showSessionSelector(a)}catch(a){G0.error("[BladeInterface] 加载会话失败:",a),process.exit(1)}});i2(()=>{if(Z.current)return;if(!Y.resume)return;Z.current=!0,G1()},[Y.resume,G1]);let M1=e1(async(a)=>{let F1=I.details?.type;if(F1==="enterPlanMode"&&a.approved)try{await z1().setPermissionMode("plan"),G0.debug("[BladeInterface] Entered Plan mode")}catch(A0){G0.error("[BladeInterface] Failed to enter Plan mode:",A0)}if(F1==="exitPlanMode"&&a.approved)G0.debug("[BladeInterface] ExitPlanMode approved, Store auto-synced");M(a)}),a0=e1(()=>{O.addAssistantMessage("❌ 设置已取消"),O.addAssistantMessage("Blade 需要 API 配置才能正常工作。"),O.addAssistantMessage("您可以稍后运行 Blade 重新进入设置向导。"),process.exit(0)}),l=e1(()=>{H.closeModal()}),W1=e1(async(a)=>{try{let F1=await g0.loadSession(a),A0=F1.map((o0,h$)=>({id:`restored-${Date.now()}-${h$}`,role:o0.role,content:typeof o0.content==="string"?o0.content:JSON.stringify(o0.content),timestamp:Date.now()-(F1.length-h$)*1000}));O.restoreSession(a,A0),H.closeModal()}catch(F1){G0.error("[BladeInterface] Failed to restore session:",F1),H.closeModal()}}),Z1=e1(()=>{if(Y.resume)L();else H.closeModal()}),$0=e1((a)=>{H.showModelEditWizard(a)}),D2=e1((a)=>{O.addAssistantMessage(`✅ 已添加模型配置: ${a.name},并已切换到该模型`),l()}),C1=e1((a)=>{O.addAssistantMessage(`✅ 已更新模型配置: ${a.name}`),l()});i2(()=>{if(_){F.setFocus("model-config-wizard");return}if(I.isVisible)F.setFocus("confirmation-prompt");else if(K==="sessionSelector")F.setFocus("session-selector");else if(K==="themeSelector")F.setFocus("theme-selector");else if(K==="modelSelector")F.setFocus("model-selector");else if(K==="modelAddWizard"||K==="modelEditWizard")F.setFocus("model-config-wizard");else if(K==="permissionsManager")F.setFocus("permissions-manager");else if(K==="agentsManager")F.setFocus("agents-manager");else if(K==="agentCreationWizard")F.setFocus("agent-creation-wizard");else if(K==="shortcuts")F.setFocus("main-input");else F.setFocus("main-input")},[_,I.isVisible,K,F.setFocus]),i2(()=>{if(!B||Q.current)return;if(O5().length>0){Q.current=!0;return}Q.current=!0,O.addAssistantMessage("请输入您的问题,我将为您提供帮助。")},[B]),i2(()=>{if(!G)return;if(J.current===G)return;if(J.current=G,q==="error")O.addAssistantMessage(`❌ 初始化失败: ${G}`);else O.addAssistantMessage(`❌ ${G}`),O.addAssistantMessage("请重新尝试设置,或检查文件权限")},[G,q,O.addAssistantMessage]);let n0=e1(async(a)=>{try{await V({displayText:a,text:a,images:[],parts:[{type:"text",text:a}]})}catch(F1){let A0=F1 instanceof Error?F1.message:"无法发送初始消息";O.addAssistantMessage(`❌ 初始消息发送失败:${A0}`)}});i2(()=>{let a=Y.initialMessage?.trim();if(!a||X.current||!B||_)return;X.current=!0,f(a),n0(a)},[Y.initialMessage,B,_,V,f]);let w0=e1(async(a)=>{try{await z1().setPermissionMode(a)}catch(F1){G0.error("❌ 权限模式初始化失败:",F1 instanceof Error?F1.message:F1)}});if(i2(()=>{let a=Y.permissionMode;if($)G0.debug("[Debug] permissionMode from CLI:",a),G0.debug("[Debug] current permissionMode:",N);if(!a||a===N)return;w0(a)},[Y.permissionMode,N]),b)return null;if(_)return I1(k7,{mode:"setup",onComplete:Y1,onCancel:a0},void 0,!1,void 0,this);if($)G0.debug("[Debug] 渲染主界面,条件检查:",{confirmationVisible:I.isVisible,activeModal:K});let f$=K==="modelSelector",T0=U,I2=K==="modelAddWizard"?"add":K==="modelEditWizard"&&T0?"edit":null,sQ=f$||Boolean(I2),tQ=K==="agentsManager",eQ=K==="agentCreationWizard",$J=K==="skillsManager",YJ=T0?{name:T0.name,provider:T0.provider,baseUrl:T0.baseUrl,apiKey:T0.apiKey,model:T0.model}:void 0,x7=I.isVisible&&I.details?I1(ZQ,{details:I.details,onResponse:M1},void 0,!1,void 0,this):K==="themeSelector"?I1(gQ,{},void 0,!1,void 0,this):K==="permissionsManager"?I1(CQ,{onClose:l},void 0,!1,void 0,this):K==="sessionSelector"?I1(hQ,{sessions:W,onSelect:W1,onCancel:Z1},void 0,!1,void 0,this):null,ZJ=Boolean(x7);return I1(l2,{flexDirection:"column",width:"100%",overflow:"hidden",children:[x7,I1(l2,{flexDirection:"column",display:ZJ?"none":"flex",children:[I1(vQ,{},void 0,!1,void 0,this),I1(AQ,{},void 0,!1,void 0,this),I1(FQ,{input:A.value,cursorPosition:A.cursorPosition,onChange:A.setValue,onChangeCursorPosition:A.setCursorPosition,onAddPasteMapping:A.addPasteMapping,onAddImagePasteMapping:A.addImagePasteMapping},void 0,!1,void 0,this),f$&&I1(l2,{marginTop:1,paddingX:2,children:I1(EQ,{onClose:l,onEdit:$0},void 0,!1,void 0,this)},void 0,!1,void 0,this),I2&&I1(l2,{marginTop:1,paddingX:2,children:I1(k7,{mode:I2,modelId:T0?.id,initialConfig:I2==="edit"?YJ:void 0,onComplete:I2==="edit"?C1:D2,onCancel:l},void 0,!1,void 0,this)},void 0,!1,void 0,this),tQ&&I1(l2,{marginTop:1,paddingX:2,children:I1(mX,{onComplete:l,onCancel:l},void 0,!1,void 0,this)},void 0,!1,void 0,this),eQ&&I1(l2,{marginTop:1,paddingX:2,children:I1(O6,{onComplete:l,onCancel:l},void 0,!1,void 0,this)},void 0,!1,void 0,this),$J&&I1(l2,{marginTop:1,paddingX:2,children:I1(dX,{onComplete:l,onCancel:l},void 0,!1,void 0,this)},void 0,!1,void 0,this),I1(iX,{suggestions:p,selectedIndex:P0,visible:t&&!sQ},void 0,!1,void 0,this),I1(lX,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{Box as kO,Text as V2}from"ink";import PO from"react";import{jsxDEV as Q2}from"react/jsx-dev-runtime";class u4 extends PO.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 Q2(kO,{flexDirection:"column",padding:1,borderStyle:"round",borderColor:"red",children:[Q2(V2,{color:"red",children:"\uD83D\uDCA5 应用发生错误"},void 0,!1,void 0,this),Q2(V2,{children:" "},void 0,!1,void 0,this),Q2(V2,{color:"red",children:this.state.error?.message},void 0,!1,void 0,this),Q2(V2,{children:" "},void 0,!1,void 0,this),Q2(V2,{color:"gray",children:"错误详情:"},void 0,!1,void 0,this),Q2(V2,{color:"gray",children:this.state.error?.stack},void 0,!1,void 0,this),Q2(V2,{children:" "},void 0,!1,void 0,this),Q2(V2,{color:"yellow",children:"请重启应用或联系开发者"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return this.props.children}}import{Box as r2,Text as J2,useInput as TO}from"ink";import{useState as T7}from"react";import{jsxDEV as i1}from"react/jsx-dev-runtime";var c4=[{key:"update",label:"Update now",description:`runs \`${r9()}\``},{key:"skip",label:"Skip",description:""},{key:"skip_until_next",label:"Skip until next version",description:""}],dQ=({versionInfo:$,onComplete:Y})=>{let[Z,X]=T7(0),[Q,J]=T7(!1),[q,G]=T7(null);TO((W,U)=>{if(U.ctrl&&W==="c"){h2().shutdown("SIGINT",0);return}if(Q||q)return;if(U.upArrow||W==="k")X((H)=>H>0?H-1:c4.length-1);else if(U.downArrow||W==="j")X((H)=>H<c4.length-1?H+1:0);else if(U.return)K(c4[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 U=await XZ();G(U.message),setTimeout(()=>{h2().shutdown("SIGINT",0)},1500);break}case"skip":Y();break;case"skip_until_next":if($.latestVersion)await ZZ($.latestVersion);Y();break}};if(q)return i1(r2,{flexDirection:"column",marginY:1,children:i1(J2,{children:q},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(Q)return i1(r2,{flexDirection:"column",marginY:1,children:i1(J2,{color:"cyan",children:"Updating..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);return i1(r2,{flexDirection:"column",marginY:1,children:[i1(J2,{color:"yellow",bold:!0,children:["✨ Update available! ",i1(J2,{color:"gray",children:[$.currentVersion," ","→"," ",$.latestVersion]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),i1(r2,{marginTop:1,children:i1(J2,{color:"gray",children:["Release notes:"," ",i1(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),i1(r2,{flexDirection:"column",marginTop:1,children:c4.map((W,U)=>{let H=U===Z,O=H?"› ":" ",F=`${U+1}. `;return i1(r2,{children:i1(J2,{color:H?"cyan":void 0,children:[O,F,W.label,W.description&&i1(J2,{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),i1(r2,{marginTop:1,children:i1(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)};function l4($){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 i4}from"react/jsx-dev-runtime";function CO($){if(e().config.actions.setConfig($),!$.models||$.models.length===0){if($.debug)console.log("[Debug] 未检测到模型配置,进入设置向导");R0().setInitializationStatus("needsSetup");return}if($.debug)console.log("[Debug] 模型配置检查通过,准备就绪");R0().setInitializationStatus("ready")}var cQ=($)=>{let[Y,Z]=S7(!1),[X,Q]=S7(null),[J,q]=S7(!1),G=uQ(async()=>{let W=e().config.config??n2,U=n4(W,$);if(CO(U),U.debug)console.error("[Debug] 运行时配置:",U);let H=U.theme;if(H&&J1.hasTheme(H)){if(J1.setTheme(H),$.debug)console.log(`✓ 已加载主题: ${H}`)}try{let O=E1.loadFromStandardLocations();if($.debug&&O>0)console.log(`✓ 已加载 ${O} 个 subagents: ${E1.getAllNames().join(", ")}`)}catch(O){if($.debug)console.warn("⚠️ Subagents 加载失败:",l4(O))}try{if(U0.getInstance().loadConfig(U.hooks||{}),$.debug&&U.hooks?.enabled)console.log("✓ Hooks 系统已启用")}catch(O){if($.debug)console.warn("⚠️ Hooks 初始化失败:",l4(O))}try{let O=await y2();if($.debug&&O.skills.length>0)console.log(`✓ 已加载 ${O.skills.length} 个 skills: ${O.skills.map((F)=>F.name).join(", ")}`);if(O.errors.length>0&&$.debug)for(let F of O.errors)console.warn(`⚠️ Skill 加载错误 (${F.path}): ${F.error}`)}catch(O){if($.debug)console.warn("⚠️ Skills 初始化失败:",l4(O))}qZ(async()=>{s1.getInstance().killAll(),await p1.getInstance().disconnectAll(),U0.getInstance().cleanup()}),Z(!0)}),K=uQ(async()=>{if($.versionCheckPromise){let W=await $.versionCheckPromise;if(W){Q(W),q(!0);return}}await G()});if(SO(()=>{K()},[]),J&&X)return i4(u4,{children:i4(dQ,{versionInfo:X,onComplete:()=>{q(!1),G()}},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(!Y)return null;return i4(u4,{children:i4(mQ,{...$},void 0,!1,void 0,this)},void 0,!1,void 0,this)};var h7=oQ(process.argv),nQ=h7.indexOf("--debug");if(nQ!==-1){let $=h7[nQ+1],Y=$&&!$.startsWith("-")?$:!0;b0.setGlobalDebug(Y)}async function lO(){GZ();let $=QZ();if(await oY())return;if(h7.includes("--acp")){let{runAcpIntegration:Z}=await Promise.resolve().then(() => (aQ(),rQ));await Z();return}let Y=cO(oQ(process.argv)).scriptName(M2.scriptName).usage(M2.usage).version(M2.version).locale(M2.locale).showHelpOnFail(M2.showHelpOnFail).demandCommand(0,"").recommendCommands().strict(M2.strict).parserConfiguration({"populate--":!0}).options(r7).middleware([F5,z5,_5]).command(P5).command(N5).command(JZ).command(B5).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(`
1810
+ `]},void 0,!0,void 0,this),p1(mO,{items:_,onSelect:B,indicatorComponent:cO,itemComponent:lO},void 0,!1,void 0,this),p1(p$,{marginTop:1,flexDirection:"column",children:[p1(S0,{dimColor:!0,children:["第 ",G+1,"/",z," 页 · 共 ",O.length," 个会话 · 显示"," ",w.start,"-",w.end]},void 0,!0,void 0,this),z>1&&p1(p$,{marginTop:1,children:[p1(S0,{color:G>0?"cyan":"gray",children:G>0?"◀ ← 上一页":" "},void 0,!1,void 0,this),p1(S0,{children:" "},void 0,!1,void 0,this),p1(S0,{color:G<z-1?"cyan":"gray",children:G<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)};F2();import{Box as I1,Text as H1,useInput as iO}from"ink";import{jsxDEV as u}from"react/jsx-dev-runtime";function tQ({onCancel:$}){let Z=l1().getAll(),X=Z.filter((G)=>G.source==="builtin"),Q=Z.filter((G)=>G.source==="user"),J=Z.filter((G)=>G.source==="project"),q=T1(!1,$);if(iO((G,K)=>{if(K.escape)$?.();else if(K.ctrl&&G==="c"||K.meta&&G==="c")q()}),Z.length===0)return u(I1,{flexDirection:"column",paddingY:1,children:[u(I1,{marginBottom:1,children:u(H1,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(I1,{paddingLeft:2,children:u(H1,{color:"gray",children:"没有找到任何 Skill"},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(I1,{marginTop:1,paddingLeft:2,children:u(H1,{color:"gray",children:"配置文件位置: ~/.blade/skills/ 或 .blade/skills/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),u(I1,{marginTop:1,children:u(H1,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return u(I1,{flexDirection:"column",paddingY:1,children:[u(I1,{marginBottom:1,children:[u(H1,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this),u(H1,{color:"gray",children:[" (找到 ",Z.length," 个)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),J.length>0&&u(I1,{flexDirection:"column",marginBottom:1,children:[u(I1,{paddingLeft:1,children:[u(H1,{bold:!0,color:"yellow",children:"项目级"},void 0,!1,void 0,this),u(H1,{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 u(I1,{flexDirection:"column",paddingLeft:2,children:[u(H1,{children:[u(H1,{bold:!0,color:"green",children:["• ",G.name]},void 0,!0,void 0,this),u(H1,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),G.allowedTools&&G.allowedTools.length>0&&u(I1,{paddingLeft:2,children:u(H1,{color:"gray",children:["工具: ",G.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),u(I1,{paddingLeft:2,children:u(H1,{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&&u(I1,{flexDirection:"column",marginBottom:1,children:[u(I1,{paddingLeft:1,children:[u(H1,{bold:!0,color:"yellow",children:"用户级"},void 0,!1,void 0,this),u(H1,{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 u(I1,{flexDirection:"column",paddingLeft:2,children:[u(H1,{children:[u(H1,{bold:!0,color:"green",children:["• ",G.name]},void 0,!0,void 0,this),u(H1,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),G.allowedTools&&G.allowedTools.length>0&&u(I1,{paddingLeft:2,children:u(H1,{color:"gray",children:["工具: ",G.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),u(I1,{paddingLeft:2,children:u(H1,{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&&u(I1,{flexDirection:"column",marginBottom:1,children:[u(I1,{paddingLeft:1,children:[u(H1,{bold:!0,color:"cyan",children:"内置"},void 0,!1,void 0,this),u(H1,{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 u(I1,{flexDirection:"column",paddingLeft:2,children:[u(H1,{children:[u(H1,{bold:!0,color:"green",children:["• ",G.name]},void 0,!0,void 0,this),u(H1,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),G.userInvocable&&u(I1,{paddingLeft:2,children:u(H1,{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),u(I1,{marginTop:1,children:u(H1,{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 rO}from"ahooks";import{Box as o0,Text as C,useInput as aO}from"ink";import nO from"ink-select-input";import{useState as eQ}from"react";z1();X8();O2();O2();import{jsxDEV as P}from"react/jsx-dev-runtime";var $J=x0.map(($)=>({label:$.label,value:$.id})),oO=({theme:$})=>{let{colors:Y}=$;return P(o0,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[P(C,{bold:!0,color:Y.text.primary,children:"代码预览"},void 0,!1,void 0,this),P(C,{children:" "},void 0,!1,void 0,this),P(C,{color:Y.syntax.comment,children:"# function"},void 0,!1,void 0,this),P(C,{children:[P(C,{color:Y.syntax.keyword,children:"def"},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.function,children:"fibonacci"},void 0,!1,void 0,this),P(C,{color:Y.text.primary,children:"("},void 0,!1,void 0,this),P(C,{color:Y.syntax.variable,children:"n"},void 0,!1,void 0,this),P(C,{color:Y.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(C,{children:[" ",P(C,{color:Y.syntax.variable,children:"a"},void 0,!1,void 0,this),P(C,{color:Y.syntax.operator,children:","},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.operator,children:"="},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.number,children:"0"},void 0,!1,void 0,this),P(C,{color:Y.syntax.operator,children:","},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.number,children:"1"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(C,{children:[" ",P(C,{color:Y.syntax.keyword,children:"for"},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.variable,children:"_"},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.keyword,children:"in"},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.function,children:"range"},void 0,!1,void 0,this),P(C,{color:Y.text.primary,children:"("},void 0,!1,void 0,this),P(C,{color:Y.syntax.variable,children:"n"},void 0,!1,void 0,this),P(C,{color:Y.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(C,{children:[" ",P(C,{color:Y.syntax.variable,children:"a"},void 0,!1,void 0,this),P(C,{color:Y.syntax.operator,children:","},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.operator,children:"="},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.variable,children:"b"},void 0,!1,void 0,this),P(C,{color:Y.syntax.operator,children:","},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.variable,children:"a"},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.operator,children:"+"},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.variable,children:"b"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(C,{children:[" ",P(C,{color:Y.syntax.keyword,children:"return"},void 0,!1,void 0,this)," ",P(C,{color:Y.syntax.variable,children:"a"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(C,{children:" "},void 0,!1,void 0,this),P(C,{color:Y.error,children:["- print(",P(C,{color:Y.syntax.string,children:'"Hello, "'},void 0,!1,void 0,this)," + name)"]},void 0,!0,void 0,this),P(C,{color:Y.success,children:["+ print(",P(C,{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)},sO=({theme:$})=>{let{colors:Y}=$;return P(o0,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[P(C,{children:" "},void 0,!1,void 0,this),P(C,{bold:!0,color:Y.text.primary,children:"颜色配置"},void 0,!1,void 0,this),P(C,{children:" "},void 0,!1,void 0,this),P(C,{children:[P(C,{color:Y.text.muted,children:"Primary: "},void 0,!1,void 0,this),P(C,{color:Y.primary,children:Y.primary},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(C,{children:[P(C,{color:Y.text.muted,children:"Success: "},void 0,!1,void 0,this),P(C,{color:Y.success,children:Y.success},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(C,{children:[P(C,{color:Y.text.muted,children:"Error: "},void 0,!1,void 0,this),P(C,{color:Y.error,children:Y.error},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(C,{children:[P(C,{color:Y.text.muted,children:"Warning: "},void 0,!1,void 0,this),P(C,{color:Y.warning,children:Y.warning},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(C,{children:[P(C,{color:Y.text.muted,children:"Info: "},void 0,!1,void 0,this),P(C,{color:Y.info,children:Y.info},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},YJ=()=>{let $=R2(),Y=V1.getCurrentThemeName(),Z=x0.findIndex((z)=>z.label===Y),X=Z>=0?x0[Z].theme:x0[0].theme,[Q,J]=eQ(X),[q,G]=eQ(!1),K=rO(async(z)=>{if(q)return;G(!0);try{await F1().setTheme(z.value),$.closeModal()}catch(_){console.error("❌ 主题切换失败:",_ instanceof Error?_.message:_)}finally{G(!1)}}),W=(z)=>{let _=x0.find((w)=>w.id===z.value);if(_)J(_.theme)},H=z0()==="theme-selector",O=T1(!1);aO((z,_)=>{if(_.ctrl&&z==="c"||_.meta&&z==="c"){O();return}if(_.escape&&!q)$.closeModal()},{isActive:H});let F=(z)=>{let{isSelected:_,label:w}=z,N=w===Y?"✓":" ";return P(C,{color:_?Q.colors.primary:Q.colors.text.primary,children:[N," ",w]},void 0,!0,void 0,this)};return P(o0,{flexDirection:"column",height:"100%",children:[P(o0,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:Q.colors.border.light,children:P(C,{bold:!0,color:Q.colors.primary,children:"\uD83C\uDFA8 主题选择器"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(o0,{flexDirection:"row",flexGrow:1,children:[P(o0,{width:"40%",borderStyle:"single",borderColor:Q.colors.border.light,paddingX:1,children:P(o0,{flexDirection:"column",children:[P(o0,{paddingTop:1,paddingBottom:1,children:P(C,{bold:!0,color:Q.colors.text.primary,children:["可用主题 (",$J.length,")"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),P(nO,{items:$J,initialIndex:Z>=0?Z:0,onSelect:K,onHighlight:W,itemComponent:F},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),P(o0,{width:"60%",flexDirection:"column",borderStyle:"single",borderColor:Q.colors.border.light,children:[P(oO,{theme:Q},void 0,!1,void 0,this),P(sO,{theme:Q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),P(o0,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:Q.colors.border.light,children:P(C,{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 M1}from"react/jsx-dev-runtime";var W0=c("UI"),ZJ=({debug:$,...Y})=>{if($)W0.debug("[Debug] BladeInterface props:",{permissionMode:Y.permissionMode,yolo:Y.yolo,maxTurns:Y.maxTurns});let Z=r4(!1),X=r4(!1),Q=r4(!1),J=r4(null),q=vZ(),G=yZ(),K=w4(),W=PZ(),U=kZ(),H=R2(),O=I$(),F=hZ(),z=M$(),_=i0(),{exit:w}=tO(),B=q==="ready",N=q==="needsSetup",I=q==="idle",{confirmationState:M,confirmationHandler:A,handleResponse:D}=mX(),{executeCommand:L,handleAbort:V}=hX(Y.systemPrompt,Y.appendSystemPrompt,A,Y.maxTurns),{getPreviousCommand:v,getNextCommand:k,addToHistory:f}=pX();eX();let R=uX("",0),T=Y0(async()=>{let a=z,O1;if(a==="default")O1="autoEdit";else if(a==="autoEdit")O1="plan";else O1="default";try{await F1().setPermissionMode(O1)}catch(D0){W0.error("❌ 权限模式切换失败:",D0 instanceof Error?D0.message:D0)}}),Y1=Y0(async(a)=>{try{await F1().addModel({name:a.name,provider:a.provider,apiKey:a.apiKey,baseUrl:a.baseUrl,model:a.model}),H.setInitializationStatus("ready")}catch(O1){W0.error("❌ 初始化配置保存失败:",O1 instanceof Error?O1.message:O1),H.setInitializationStatus("ready")}}),r=Y0(()=>{if(K==="shortcuts")H.closeModal();else H.setActiveModal("shortcuts")}),{showSuggestions:t,suggestions:p,selectedSuggestionIndex:C0}=tX(R,L,v,k,f,V,_,T,r,K==="shortcuts");o2(()=>{if(R.value&&K==="shortcuts")H.closeModal()},[R.value,K,H]);let G1=Y0(async()=>{try{if(typeof Y.resume==="string"&&Y.resume!=="true"){let O1=await l0.loadSession(Y.resume),D0=O1.map(($2,m$)=>({id:`restored-${Date.now()}-${m$}`,role:$2.role,content:typeof $2.content==="string"?$2.content:JSON.stringify($2.content),timestamp:Date.now()-(O1.length-m$)*1000}));O.restoreSession(Y.resume,D0);return}let a=await l0.listSessions();if(a.length===0)W0.error("没有找到历史会话"),D$(1);H.showSessionSelector(a)}catch(a){W0.error("[BladeInterface] 加载会话失败:",a),D$(1)}});o2(()=>{if(Z.current)return;if(!Y.resume)return;Z.current=!0,G1()},[Y.resume,G1]);let j1=Y0(async(a)=>{let O1=M.details?.type;if(O1==="enterPlanMode"&&a.approved)try{await F1().setPermissionMode("plan"),W0.debug("[BladeInterface] Entered Plan mode")}catch(D0){W0.error("[BladeInterface] Failed to enter Plan mode:",D0)}if(O1==="exitPlanMode"&&a.approved)W0.debug("[BladeInterface] ExitPlanMode approved, Store auto-synced");D(a)}),t0=Y0(()=>{O.addAssistantMessage("❌ 设置已取消"),O.addAssistantMessage("Blade 需要 API 配置才能正常工作。"),O.addAssistantMessage("您可以稍后运行 Blade 重新进入设置向导。"),D$(0)}),i=Y0(()=>{H.closeModal()}),K1=Y0(async(a)=>{try{let O1=await l0.loadSession(a),D0=O1.map(($2,m$)=>({id:`restored-${Date.now()}-${m$}`,role:$2.role,content:typeof $2.content==="string"?$2.content:JSON.stringify($2.content),timestamp:Date.now()-(O1.length-m$)*1000}));O.restoreSession(a,D0),H.closeModal()}catch(O1){W0.error("[BladeInterface] Failed to restore session:",O1),H.closeModal()}}),Z1=Y0(()=>{if(Y.resume)w();else H.closeModal()}),Z0=Y0((a)=>{H.showModelEditWizard(a)}),v2=Y0((a)=>{O.addAssistantMessage(`✅ 已添加模型配置: ${a.name},并已切换到该模型`),i()}),h1=Y0((a)=>{O.addAssistantMessage(`✅ 已更新模型配置: ${a.name}`),i()});o2(()=>{if(N){F.setFocus("model-config-wizard");return}if(M.isVisible)F.setFocus("confirmation-prompt");else if(K==="sessionSelector")F.setFocus("session-selector");else if(K==="themeSelector")F.setFocus("theme-selector");else if(K==="modelSelector")F.setFocus("model-selector");else if(K==="modelAddWizard"||K==="modelEditWizard")F.setFocus("model-config-wizard");else if(K==="permissionsManager")F.setFocus("permissions-manager");else if(K==="agentsManager")F.setFocus("agents-manager");else if(K==="agentCreationWizard")F.setFocus("agent-creation-wizard");else if(K==="shortcuts")F.setFocus("main-input");else F.setFocus("main-input")},[N,M.isVisible,K,F.setFocus]),o2(()=>{if(!B||Q.current)return;if(I5().length>0){Q.current=!0;return}Q.current=!0,O.addAssistantMessage("请输入您的问题,我将为您提供帮助。")},[B]),o2(()=>{if(!G)return;if(J.current===G)return;if(J.current=G,q==="error")O.addAssistantMessage(`❌ 初始化失败: ${G}`);else O.addAssistantMessage(`❌ ${G}`),O.addAssistantMessage("请重新尝试设置,或检查文件权限")},[G,q,O.addAssistantMessage]);let e0=Y0(async(a)=>{try{await L({displayText:a,text:a,images:[],parts:[{type:"text",text:a}]})}catch(O1){let D0=O1 instanceof Error?O1.message:"无法发送初始消息";O.addAssistantMessage(`❌ 初始消息发送失败:${D0}`)}});o2(()=>{let a=Y.initialMessage?.trim();if(!a||X.current||!B||N)return;X.current=!0,f(a),e0(a)},[Y.initialMessage,B,N,L,f]);let V0=Y0(async(a)=>{try{await F1().setPermissionMode(a)}catch(O1){W0.error("❌ 权限模式初始化失败:",O1 instanceof Error?O1.message:O1)}});if(o2(()=>{let a=Y.permissionMode;if($)W0.debug("[Debug] permissionMode from CLI:",a),W0.debug("[Debug] current permissionMode:",z);if(!a||a===z)return;V0(a)},[Y.permissionMode,z]),I)return null;if(N)return M1(i7,{mode:"setup",onComplete:Y1,onCancel:t0},void 0,!1,void 0,this);if($)W0.debug("[Debug] 渲染主界面,条件检查:",{confirmationVisible:M.isVisible,activeModal:K});let g$=K==="modelSelector",f0=U,y2=K==="modelAddWizard"?"add":K==="modelEditWizard"&&f0?"edit":null,OJ=g$||Boolean(y2),FJ=K==="agentsManager",zJ=K==="agentCreationWizard",_J=K==="skillsManager",NJ=f0?{name:f0.name,provider:f0.provider,baseUrl:f0.baseUrl,apiKey:f0.apiKey,model:f0.model}:void 0,e7=M.isVisible&&M.details?M1(_Q,{details:M.details,onResponse:j1},void 0,!1,void 0,this):K==="themeSelector"?M1(YJ,{},void 0,!1,void 0,this):K==="permissionsManager"?M1(nQ,{onClose:i},void 0,!1,void 0,this):K==="sessionSelector"?M1(sQ,{sessions:W,onSelect:K1,onCancel:Z1},void 0,!1,void 0,this):null,BJ=Boolean(e7);return M1(n2,{flexDirection:"column",width:"100%",overflow:"hidden",children:[e7,M1(n2,{flexDirection:"column",display:BJ?"none":"flex",children:[M1(dQ,{},void 0,!1,void 0,this),M1(TQ,{},void 0,!1,void 0,this),M1(MQ,{input:R.value,cursorPosition:R.cursorPosition,onChange:R.setValue,onChangeCursorPosition:R.setCursorPosition,onAddPasteMapping:R.addPasteMapping,onAddImagePasteMapping:R.addImagePasteMapping},void 0,!1,void 0,this),g$&&M1(n2,{marginTop:1,paddingX:2,children:M1(cQ,{onClose:i,onEdit:Z0},void 0,!1,void 0,this)},void 0,!1,void 0,this),y2&&M1(n2,{marginTop:1,paddingX:2,children:M1(i7,{mode:y2,modelId:f0?.id,initialConfig:y2==="edit"?NJ:void 0,onComplete:y2==="edit"?h1:v2,onCancel:i},void 0,!1,void 0,this)},void 0,!1,void 0,this),FJ&&M1(n2,{marginTop:1,paddingX:2,children:M1(XQ,{onComplete:i,onCancel:i},void 0,!1,void 0,this)},void 0,!1,void 0,this),zJ&&M1(n2,{marginTop:1,paddingX:2,children:M1(B6,{onComplete:i,onCancel:i},void 0,!1,void 0,this)},void 0,!1,void 0,this),_J&&M1(n2,{marginTop:1,paddingX:2,children:M1(tQ,{onComplete:i,onCancel:i},void 0,!1,void 0,this)},void 0,!1,void 0,this),M1(GQ,{suggestions:p,selectedIndex:C0,visible:t&&!OJ},void 0,!1,void 0,this),M1(qQ,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{Box as eO,Text as j2}from"ink";import $F from"react";import{jsxDEV as K2}from"react/jsx-dev-runtime";class a4 extends $F.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 K2(eO,{flexDirection:"column",padding:1,borderStyle:"round",borderColor:"red",children:[K2(j2,{color:"red",children:"\uD83D\uDCA5 应用发生错误"},void 0,!1,void 0,this),K2(j2,{children:" "},void 0,!1,void 0,this),K2(j2,{color:"red",children:this.state.error?.message},void 0,!1,void 0,this),K2(j2,{children:" "},void 0,!1,void 0,this),K2(j2,{color:"gray",children:"错误详情:"},void 0,!1,void 0,this),K2(j2,{color:"gray",children:this.state.error?.stack},void 0,!1,void 0,this),K2(j2,{children:" "},void 0,!1,void 0,this),K2(j2,{color:"yellow",children:"请重启应用或联系开发者"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return this.props.children}}import{Box as s2,Text as W2,useInput as YF}from"ink";import{useState as a7}from"react";import{jsxDEV as a1}from"react/jsx-dev-runtime";var n4=[{key:"update",label:"Update now",description:`runs \`${q7()}\``},{key:"skip",label:"Skip",description:""},{key:"skip_until_next",label:"Skip until next version",description:""}],XJ=({versionInfo:$,onComplete:Y})=>{let[Z,X]=a7(0),[Q,J]=a7(!1),[q,G]=a7(null);YF((W,U)=>{if(U.ctrl&&W==="c"){m2().shutdown("SIGINT",0);return}if(Q||q)return;if(U.upArrow||W==="k")X((H)=>H>0?H-1:n4.length-1);else if(U.downArrow||W==="j")X((H)=>H<n4.length-1?H+1:0);else if(U.return)K(n4[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 U=await NZ();G(U.message),setTimeout(()=>{m2().shutdown("SIGINT",0)},1500);break}case"skip":Y();break;case"skip_until_next":if($.latestVersion)await _Z($.latestVersion);Y();break}};if(q)return a1(s2,{flexDirection:"column",marginY:1,children:a1(W2,{children:q},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(Q)return a1(s2,{flexDirection:"column",marginY:1,children:a1(W2,{color:"cyan",children:"Updating..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);return a1(s2,{flexDirection:"column",marginY:1,children:[a1(W2,{color:"yellow",bold:!0,children:["✨ Update available! ",a1(W2,{color:"gray",children:[$.currentVersion," ","→"," ",$.latestVersion]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),a1(s2,{marginTop:1,children:a1(W2,{color:"gray",children:["Release notes:"," ",a1(W2,{color:"cyan",underline:!0,children:$.releaseNotesUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),a1(s2,{flexDirection:"column",marginTop:1,children:n4.map((W,U)=>{let H=U===Z,O=H?"› ":" ",F=`${U+1}. `;return a1(s2,{children:a1(W2,{color:H?"cyan":void 0,children:[O,F,W.label,W.description&&a1(W2,{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),a1(s2,{marginTop:1,children:a1(W2,{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)};O2();function o4($){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 s4}from"react/jsx-dev-runtime";function XF($){if(e().config.actions.setConfig($),!$.models||$.models.length===0){if($.debug)console.log("[Debug] 未检测到模型配置,进入设置向导");M0().setInitializationStatus("needsSetup");return}if($.debug)console.log("[Debug] 模型配置检查通过,准备就绪");M0().setInitializationStatus("ready")}var JJ=($)=>{let[Y,Z]=n7(!1),[X,Q]=n7(null),[J,q]=n7(!1),G=QJ(async()=>{let W=e().config.config??e2,U=Y8(W,$);if(XF(U),U.debug)console.error("[Debug] 运行时配置:",U);let H=U.theme;if(H&&V1.hasTheme(H)){if(V1.setTheme(H),$.debug)console.log(`✓ 已加载主题: ${H}`)}try{let O=k1.loadFromStandardLocations();if($.debug&&O>0)console.log(`✓ 已加载 ${O} 个 subagents: ${k1.getAllNames().join(", ")}`)}catch(O){if($.debug)console.warn("⚠️ Subagents 加载失败:",o4(O))}try{if(F0.getInstance().loadConfig(U.hooks||{}),$.debug&&U.hooks?.enabled)console.log("✓ Hooks 系统已启用")}catch(O){if($.debug)console.warn("⚠️ Hooks 初始化失败:",o4(O))}try{let O=await T2();if($.debug&&O.skills.length>0)console.log(`✓ 已加载 ${O.skills.length} 个 skills: ${O.skills.map((F)=>F.name).join(", ")}`);if(O.errors.length>0&&$.debug)for(let F of O.errors)console.warn(`⚠️ Skill 加载错误 (${F.path}): ${F.error}`)}catch(O){if($.debug)console.warn("⚠️ Skills 初始化失败:",o4(O))}AZ(async()=>{$0.getInstance().killAll(),await g1.getInstance().disconnectAll(),F0.getInstance().cleanup()}),Z(!0)}),K=QJ(async()=>{if($.versionCheckPromise){let W=await $.versionCheckPromise;if(W){Q(W),q(!0);return}}await G()});if(ZF(()=>{K()},[]),J&&X)return s4(a4,{children:s4(XJ,{versionInfo:X,onComplete:()=>{q(!1),G()}},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(!Y)return null;return s4(a4,{children:s4(ZJ,{...$},void 0,!1,void 0,this)},void 0,!1,void 0,this)};var t7=HJ(process.argv),UJ=t7.indexOf("--debug");if(UJ!==-1){let $=t7[UJ+1],Y=$&&!$.startsWith("-")?$:!0;I0.setGlobalDebug(Y)}async function FF(){bZ();let $=BZ();if(await WZ())return;if(t7.includes("--acp")){let{runAcpIntegration:Z}=await Promise.resolve().then(() => (WJ(),KJ));await Z();return}let Y=OF(HJ(process.argv)).scriptName(E2.scriptName).usage(E2.usage).version(E2.version).locale(E2.locale).showHelpOnFail(E2.showHelpOnFail).demandCommand(0,"").recommendCommands().strict(E2.strict).parserConfiguration({"populate--":!0}).options(Q5).middleware([M5,j5,v5]).command(l5).command(y5).command(wZ).command(E5).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(`
1803
1811
  Stack trace:`),console.error(X.stack),process.exit(1);if(Z)console.error("❌ Invalid arguments:"),console.error(Z),console.error(`
1804
- \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,dO(uO.createElement(cQ,J),{patchConsole:!0,exitOnCtrlC:!1,alternateBuffer:!1})});try{await Y.parse()}catch(Z){console.error("❌ Parse error:",Z),process.exit(1)}}if(x1.main==x1.module)lO().catch(console.error);export{lO as main};
1812
+ \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,UF(HF.createElement(JJ,J),{patchConsole:!0,exitOnCtrlC:!1,alternateBuffer:!1})});try{await Y.parse()}catch(Z){console.error("❌ Parse error:",Z),process.exit(1)}}if(X0.main==X0.module)FF().catch(console.error);export{FF as main};