blade-code 0.1.3 → 0.1.4

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 (2) hide show
  1. package/dist/blade.js +162 -162
  2. package/package.json +1 -1
package/dist/blade.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{createRequire as OH}from"node:module";var qH=Object.create;var{getPrototypeOf:WH,defineProperty:y6,getOwnPropertyNames:UH}=Object;var HH=Object.prototype.hasOwnProperty;var d0=($,Z,Y)=>{Y=$!=null?qH(WH($)):{};let Q=Z||!$||!$.__esModule?y6(Y,"default",{value:$,enumerable:!0}):Y;for(let X of UH($))if(!HH.call(Q,X))y6(Q,X,{get:()=>$[X],enumerable:!0});return Q};var FH=($,Z)=>{for(var Y in Z)y6($,Y,{get:Z[Y],enumerable:!0,configurable:!0,set:(Q)=>Z[Y]=()=>Q})};var A=($,Z)=>()=>($&&(Z=$($=0)),Z);var D0=OH(import.meta.url);var E3;var BY=A(()=>{E3={name:"blade-code",version:"0.1.3",private:!1,description:"🗡️ Blade Code - 智能代码助手命令行工具",type:"module",bin:{blade:"dist/blade.js"},files:["dist","vendor/ripgrep/**","README.md","docs/public/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:'test -n "$CI" || 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-code/issues"},engines:{node:">=20.0.0"},devDependencies:{"@biomejs/biome":"^2.2.4","@types/bun":"^1.3.4","@types/json-schema":"^7.0.15","@types/lodash-es":"^4.17.12","@types/node":"^22.15.24","@types/picomatch":"^4.0.2","@types/react":"^19.1.12","@types/react-dom":"^19.1.9","@types/semver":"^7.7.1","@types/write-file-atomic":"^4.0.3","@types/ws":"^8.5.12","@types/yargs":"^17.0.33","@vitest/coverage-v8":"^3.0.0",jsdom:"^26.0.0",knip:"^5.80.0",typescript:"^5.9.2",vitest:"^3.0.0"},optionalDependencies:{"@vscode/ripgrep":"^1.17.0"},dependencies:{"@agentclientprotocol/sdk":"^0.12.0","@anthropic-ai/sdk":"^0.71.2","@azure/identity":"^4.13.0","@google/genai":"^1.34.0","@inkjs/ui":"^2.0.0","@modelcontextprotocol/sdk":"^1.17.4",ahooks:"^3.9.5","ansi-escapes":"^7.2.0","async-mutex":"^0.5.0",axios:"^1.12.2",chalk:"^5.4.1",diff:"^8.0.2","fast-glob":"^3.3.3","fuse.js":"^7.1.0","gray-matter":"^4.0.3",ink:"npm:@jrichman/ink@6.4.6","ink-big-text":"^2.0.0","ink-gradient":"^3.0.0","ink-select-input":"^6.2.0","ink-spinner":"^5.0.0","ink-text-input":"^6.0.0","js-tiktoken":"^1.0.21","lodash-es":"^4.17.21",lowlight:"^3.3.0","lru-cache":"^11.2.4",nanoid:"^5.1.6",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 v4(){return E3.version}function LY(){return E3.name}function wY(){return E3.description}function NY(){return`v${E3.version} © 2025 Blade Code`}var P3=A(()=>{BY()});var U0=()=>{};var E4;var v6=A(()=>{U0();E4={currentModelId:"",models:[],temperature:0,maxContextTokens:128000,maxOutputTokens:32768,stream:!0,topP:0.9,topK:50,timeout:180000,theme:"GitHub",language:"zh-CN",fontSize:14,debug:!1,mcpEnabled:!1,mcpServers:{},permissions:{allow:["Bash(pwd)","Bash(which *)","Bash(whoami)","Bash(hostname)","Bash(uname *)","Bash(date)","Bash(echo *)","Bash(ls *)","Bash(tree *)","Bash(git status)","Bash(git log *)","Bash(git diff *)","Bash(git branch *)","Bash(git show *)","Bash(git remote *)","Bash(npm list *)","Bash(npm view *)","Bash(npm outdated *)","Bash(pnpm list *)","Bash(yarn list *)","Bash(pip list *)","Bash(pip show *)"],ask:["Bash(curl *)","Bash(wget *)","Bash(aria2c *)","Bash(axel *)","Bash(rm -rf *)","Bash(rm -r *)","Bash(rm --recursive *)","Bash(nc *)","Bash(netcat *)","Bash(telnet *)","Bash(ncat *)"],deny:["Read(./.env)","Read(./.env.*)","Bash(rm -rf /)","Bash(rm -rf /*)","Bash(sudo *)","Bash(chmod 777 *)","Bash(bash *)","Bash(sh *)","Bash(zsh *)","Bash(fish *)","Bash(dash *)","Bash(eval *)","Bash(source *)","Bash(mkfs *)","Bash(fdisk *)","Bash(dd *)","Bash(format *)","Bash(parted *)","Bash(open http*)","Bash(open https*)","Bash(xdg-open http*)","Bash(xdg-open https*)"]},permissionMode:"default",hooks:{enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,PreToolUse:[],PostToolUse:[],PostToolUseFailure:[],PermissionRequest:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]},env:{},disableAllHooks:!1,maxTurns:-1}});import{promises as AY}from"fs";import{merge as RY}from"lodash-es";import VY from"os";import T3 from"path";class u0{static instance=null;constructor(){}static getInstance(){if(!u0.instance)u0.instance=new u0;return u0.instance}static resetInstance(){u0.instance=null}async initialize(){try{let $=await this.loadConfigFiles(),Z=await this.loadSettingsFiles(),Y={...E4,...$,...Z};if(this.resolveEnvInterpolation(Y),Y.debug)console.log("[ConfigManager] Configuration loaded successfully");return Y}catch($){return console.error("[ConfigManager] Failed to initialize:",$),E4}}async loadConfigFiles(){let $=T3.join(VY.homedir(),".blade","config.json"),Z=T3.join(process.cwd(),".blade","config.json"),Y={},Q=await this.loadJsonFile($);if(Q)Y={...Y,...Q};let X=await this.loadJsonFile(Z);if(X){let J={...Y.mcpServers||{},...X.mcpServers||{}};if(Y={...Y,...X},Object.keys(J).length>0)Y.mcpServers=J}return Y}async loadSettingsFiles(){let $=T3.join(VY.homedir(),".blade","settings.json"),Z=T3.join(process.cwd(),".blade","settings.json"),Y=T3.join(process.cwd(),".blade","settings.local.json"),Q={},X=await this.loadJsonFile($);if(X)Q=this.mergeSettings(Q,X);let J=await this.loadJsonFile(Z);if(J)Q=this.mergeSettings(Q,J);let G=await this.loadJsonFile(Y);if(G)Q=this.mergeSettings(Q,G);return Q}mergeSettings($,Z){let Y=JSON.parse(JSON.stringify($));if(Z.permissions){if(!Y.permissions)Y.permissions={allow:[],ask:[],deny:[]};if(Z.permissions.allow){let Q=[...Y.permissions.allow||[],...Z.permissions.allow];Y.permissions.allow=Array.from(new Set(Q))}if(Z.permissions.ask){let Q=[...Y.permissions.ask||[],...Z.permissions.ask];Y.permissions.ask=Array.from(new Set(Q))}if(Z.permissions.deny){let Q=[...Y.permissions.deny||[],...Z.permissions.deny];Y.permissions.deny=Array.from(new Set(Q))}}if(Z.hooks)Y.hooks=RY({},Y.hooks,Z.hooks);if(Z.env)Y.env=RY({},Y.env,Z.env);if(Z.mcpServers)Y.mcpServers={...Y.mcpServers||{},...Z.mcpServers};if(Z.disableAllHooks!==void 0)Y.disableAllHooks=Z.disableAllHooks;if(Z.permissionMode!==void 0)Y.permissionMode=Z.permissionMode;if(Z.maxTurns!==void 0)Y.maxTurns=Z.maxTurns;return Y}resolveEnvInterpolation($){let Z=/\$\{?([A-Z_][A-Z0-9_]*)(:-([^}]+))?\}?/g,Y=(Q)=>{if(typeof Q==="string")return Q.replace(Z,(X,J,G,K)=>{return process.env[J]||K||X});return Q};for(let[Q,X]of Object.entries($))if(typeof X==="string")$[Q]=Y(X)}async loadJsonFile($){try{if(await this.fileExists($)){let Z=await AY.readFile($,"utf-8");return JSON.parse(Z)}}catch(Z){console.warn(`[ConfigManager] Failed to load ${$}:`,Z)}return null}async fileExists($){try{return await AY.access($),!0}catch{return!1}}validateConfig($){let Z=[];if(!$.models||$.models.length===0)Z.push("没有可用的模型配置");if($.models&&$.models.length>0){if(!$.currentModelId)Z.push("未设置当前模型 ID");else if(!$.models.find((Q)=>Q.id===$.currentModelId))Z.push("当前模型 ID 无效")}if(Z.length>0)throw Error(`配置验证失败:
2
+ import{createRequire as OH}from"node:module";var qH=Object.create;var{getPrototypeOf:WH,defineProperty:y6,getOwnPropertyNames:UH}=Object;var HH=Object.prototype.hasOwnProperty;var d0=($,Z,Y)=>{Y=$!=null?qH(WH($)):{};let Q=Z||!$||!$.__esModule?y6(Y,"default",{value:$,enumerable:!0}):Y;for(let X of UH($))if(!HH.call(Q,X))y6(Q,X,{get:()=>$[X],enumerable:!0});return Q};var FH=($,Z)=>{for(var Y in Z)y6($,Y,{get:Z[Y],enumerable:!0,configurable:!0,set:(Q)=>Z[Y]=()=>Q})};var A=($,Z)=>()=>($&&(Z=$($=0)),Z);var D0=OH(import.meta.url);var E8;var BY=A(()=>{E8={name:"blade-code",version:"0.1.4",private:!1,description:"🗡️ Blade Code - 智能代码助手命令行工具",type:"module",bin:{blade:"dist/blade.js"},files:["dist","vendor/ripgrep/**","README.md","docs/public/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:'test -n "$CI" || 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-code/issues"},engines:{node:">=20.0.0"},devDependencies:{"@biomejs/biome":"^2.2.4","@types/bun":"^1.3.4","@types/json-schema":"^7.0.15","@types/lodash-es":"^4.17.12","@types/node":"^22.15.24","@types/picomatch":"^4.0.2","@types/react":"^19.1.12","@types/react-dom":"^19.1.9","@types/semver":"^7.7.1","@types/write-file-atomic":"^4.0.3","@types/ws":"^8.5.12","@types/yargs":"^17.0.33","@vitest/coverage-v8":"^3.0.0",jsdom:"^26.0.0",knip:"^5.80.0",typescript:"^5.9.2",vitest:"^3.0.0"},optionalDependencies:{"@vscode/ripgrep":"^1.17.0"},dependencies:{"@agentclientprotocol/sdk":"^0.12.0","@anthropic-ai/sdk":"^0.71.2","@azure/identity":"^4.13.0","@google/genai":"^1.34.0","@inkjs/ui":"^2.0.0","@modelcontextprotocol/sdk":"^1.17.4",ahooks:"^3.9.5","ansi-escapes":"^7.2.0","async-mutex":"^0.5.0",axios:"^1.12.2",chalk:"^5.4.1",diff:"^8.0.2","fast-glob":"^3.3.3","fuse.js":"^7.1.0","gray-matter":"^4.0.3",ink:"npm:@jrichman/ink@6.4.6","ink-big-text":"^2.0.0","ink-gradient":"^3.0.0","ink-select-input":"^6.2.0","ink-spinner":"^5.0.0","ink-text-input":"^6.0.0","js-tiktoken":"^1.0.21","lodash-es":"^4.17.21",lowlight:"^3.3.0","lru-cache":"^11.2.4",nanoid:"^5.1.6",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 v2(){return E8.version}function LY(){return E8.name}function wY(){return E8.description}function NY(){return`v${E8.version} © 2025 Blade Code`}var P8=A(()=>{BY()});var U0=()=>{};var E2;var v6=A(()=>{U0();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:[],PostToolUseFailure:[],PermissionRequest:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]},env:{},disableAllHooks:!1,maxTurns:-1}});import{promises as AY}from"fs";import{merge as RY}from"lodash-es";import VY from"os";import T8 from"path";class u0{static instance=null;constructor(){}static getInstance(){if(!u0.instance)u0.instance=new u0;return u0.instance}static resetInstance(){u0.instance=null}async initialize(){try{let $=await this.loadConfigFiles(),Z=await this.loadSettingsFiles(),Y={...E2,...$,...Z};if(this.resolveEnvInterpolation(Y),Y.debug)console.log("[ConfigManager] Configuration loaded successfully");return Y}catch($){return console.error("[ConfigManager] Failed to initialize:",$),E2}}async loadConfigFiles(){let $=T8.join(VY.homedir(),".blade","config.json"),Z=T8.join(process.cwd(),".blade","config.json"),Y={},Q=await this.loadJsonFile($);if(Q)Y={...Y,...Q};let X=await this.loadJsonFile(Z);if(X){let J={...Y.mcpServers||{},...X.mcpServers||{}};if(Y={...Y,...X},Object.keys(J).length>0)Y.mcpServers=J}return Y}async loadSettingsFiles(){let $=T8.join(VY.homedir(),".blade","settings.json"),Z=T8.join(process.cwd(),".blade","settings.json"),Y=T8.join(process.cwd(),".blade","settings.local.json"),Q={},X=await this.loadJsonFile($);if(X)Q=this.mergeSettings(Q,X);let J=await this.loadJsonFile(Z);if(J)Q=this.mergeSettings(Q,J);let G=await this.loadJsonFile(Y);if(G)Q=this.mergeSettings(Q,G);return Q}mergeSettings($,Z){let Y=JSON.parse(JSON.stringify($));if(Z.permissions){if(!Y.permissions)Y.permissions={allow:[],ask:[],deny:[]};if(Z.permissions.allow){let Q=[...Y.permissions.allow||[],...Z.permissions.allow];Y.permissions.allow=Array.from(new Set(Q))}if(Z.permissions.ask){let Q=[...Y.permissions.ask||[],...Z.permissions.ask];Y.permissions.ask=Array.from(new Set(Q))}if(Z.permissions.deny){let Q=[...Y.permissions.deny||[],...Z.permissions.deny];Y.permissions.deny=Array.from(new Set(Q))}}if(Z.hooks)Y.hooks=RY({},Y.hooks,Z.hooks);if(Z.env)Y.env=RY({},Y.env,Z.env);if(Z.mcpServers)Y.mcpServers={...Y.mcpServers||{},...Z.mcpServers};if(Z.disableAllHooks!==void 0)Y.disableAllHooks=Z.disableAllHooks;if(Z.permissionMode!==void 0)Y.permissionMode=Z.permissionMode;if(Z.maxTurns!==void 0)Y.maxTurns=Z.maxTurns;return Y}resolveEnvInterpolation($){let Z=/\$\{?([A-Z_][A-Z0-9_]*)(:-([^}]+))?\}?/g,Y=(Q)=>{if(typeof Q==="string")return Q.replace(Z,(X,J,G,K)=>{return process.env[J]||K||X});return Q};for(let[Q,X]of Object.entries($))if(typeof X==="string")$[Q]=Y(X)}async loadJsonFile($){try{if(await this.fileExists($)){let Z=await AY.readFile($,"utf-8");return JSON.parse(Z)}}catch(Z){console.warn(`[ConfigManager] Failed to load ${$}:`,Z)}return null}async fileExists($){try{return await AY.access($),!0}catch{return!1}}validateConfig($){let Z=[];if(!$.models||$.models.length===0)Z.push("没有可用的模型配置");if($.models&&$.models.length>0){if(!$.currentModelId)Z.push("未设置当前模型 ID");else if(!$.models.find((Q)=>Q.id===$.currentModelId))Z.push("当前模型 ID 无效")}if(Z.length>0)throw Error(`配置验证失败:
3
3
  ${Z.map((Y)=>` - ${Y}`).join(`
4
4
  `)}
5
5
 
@@ -22,24 +22,24 @@ ${Z.map((Y)=>` - ${Y}`).join(`
22
22
  }
23
23
  ]
24
24
  }
25
- `)}}function E6($,Z={}){let Y={...$};if(Z.debug!==void 0)Y.debug=Z.debug===""?!0:Z.debug;if(Z.yolo===!0)Y.permissionMode="yolo";else if(Z.permissionMode!==void 0)Y.permissionMode=Z.permissionMode;if(Z.maxTurns!==void 0)Y.maxTurns=Z.maxTurns;return Y.systemPrompt=Z.systemPrompt,Y.appendSystemPrompt=Z.appendSystemPrompt,Y.resumeSessionId=Z.sessionId,Y.forkSession=Z.forkSession,Y.allowedTools=Z.allowedTools,Y.disallowedTools=Z.disallowedTools,Y.mcpConfigPaths=Z.mcpConfig,Y.strictMcpConfig=Z.strictMcpConfig,Y.addDirs=Z.addDir,Y.outputFormat=Z.outputFormat,Y.inputFormat=Z.inputFormat,Y.print=Z.print,Y.includePartialMessages=Z.includePartialMessages,Y.replayUserMessages=Z.replayUserMessages,Y.agentsConfig=Z.agents,Y.settingSources=Z.settingSources,Y}var DY=A(()=>{v6();U0()});import{promises as T4}from"node:fs";import _H from"node:os";import P6 from"node:path";import BH from"pino";async function jY(){if(q1)try{if(typeof q1.flush==="function")q1.flush();await new Promise(($)=>setTimeout($,100))}catch($){console.error("[Logger] 关闭日志系统时出错:",$)}q1=null,P4=null}function IY($){if(T6!==$)T6=$,C6()}async function wH(){try{let $=P6.join(_H.homedir(),".blade","logs");await T4.mkdir($,{recursive:!0,mode:493});try{if((await T4.stat($)).uid===0&&process.getuid&&process.getuid()!==0)return console.error(""),console.error("❌ 权限错误:~/.blade/logs 目录属于 root 用户"),console.error(""),console.error("这通常是因为您曾经使用 sudo 运行过 blade。"),console.error(""),console.error("解决方法:"),console.error(" sudo chown -R $USER:$USER ~/.blade/"),console.error(""),console.error("然后重新运行 blade(不要使用 sudo)"),console.error(""),null}catch(Q){}await NH($,30);let Y=`blade-${T6||"default"}.log`;return P6.join($,Y)}catch($){return console.error("[Logger] 无法创建日志目录:",$),null}}async function NH($,Z){try{let Y=await T4.readdir($),Q=Date.now(),X=Z*24*60*60*1000;for(let J of Y){if(!J.startsWith("blade-")||!J.endsWith(".log"))continue;let G=P6.join($,J);try{let K=await T4.stat(G);if(Q-K.mtimeMs>X)await T4.unlink(G),console.error(`[Logger] 已清理旧日志: ${J}`)}catch(K){}}}catch(Y){console.error("[Logger] 清理旧日志失败:",Y)}}async function bH(){if(q1)return q1;if(P4)return P4;return P4=(async()=>{try{let $=await wH();if(!$)return console.warn("[Logger] 文件日志已禁用(目录创建失败)"),null;return q1=BH({level:"debug",transport:{target:"pino/file",options:{destination:$}}}),q1}catch($){return console.error("[Logger] Pino 初始化失败:",$),null}})(),P4}function C6(){if(q1&&typeof q1.flush==="function")try{q1.flush()}catch($){}q1=null,P4=null}class V1{static globalDebugConfig=null;enabled;minLevel;category;pinoLogger=null;constructor($={}){if($.enabled!==void 0)this.enabled=$.enabled;else if(V1.globalDebugConfig!==null)this.enabled=Boolean(V1.globalDebugConfig);else this.enabled=!1;this.minLevel=$.minLevel??0,this.category=$.category??"General",this.initPino()}async initPino(){try{let $=await bH();if($)this.pinoLogger=$.child({category:this.category})}catch($){console.error("[Logger] Failed to initialize pino:",$)}}static setGlobalDebug($){V1.globalDebugConfig=$,C6()}static clearGlobalDebug(){V1.globalDebugConfig=null,C6()}setEnabled($){this.enabled=$}parseDebugFilter($){if(!$)return{enabled:!1};if($===!0||$==="true"||$==="1")return{enabled:!0};let Z=String($).trim();if(!Z)return{enabled:!0};if(Z.startsWith("!"))return{enabled:!0,filter:{mode:"exclude",categories:Z.split(",").map((X)=>X.trim().replace(/^!/,"")).filter(Boolean)}};return{enabled:!0,filter:{mode:"include",categories:Z.split(",").map((Q)=>Q.trim()).filter(Boolean)}}}shouldLogCategory($){if(!$)return!0;let Z=this.category.toLowerCase();if($.mode==="include")return $.categories.some((Y)=>Z.includes(Y.toLowerCase()));return!$.categories.some((Y)=>Z.includes(Y.toLowerCase()))}shouldLogToConsole($){if(V1.globalDebugConfig!==null){let{enabled:Z,filter:Y}=this.parseDebugFilter(V1.globalDebugConfig);if(!Z)return!1;if($<this.minLevel)return!1;return this.shouldLogCategory(Y)}return this.enabled&&$>=this.minLevel}log($,...Z){let Y=Z.map((Q)=>typeof Q==="object"?JSON.stringify(Q):String(Q)).join(" ");if(this.pinoLogger){let Q=LH[$];this.pinoLogger[Q](Y)}if(this.shouldLogToConsole($)){let Q=MY[$],X=`[${this.category}] [${Q}]`;console.error(X,...Z)}}debug(...$){this.log(0,...$)}info(...$){this.log(1,...$)}warn(...$){this.log(2,...$)}error(...$){this.log(3,...$)}}function l($,Z){return new V1({...Z,category:$})}var MY,LH,T6=null,q1=null,P4=null,u$;var O$=A(()=>{((X)=>{X[X.DEBUG=0]="DEBUG";X[X.INFO=1]="INFO";X[X.WARN=2]="WARN";X[X.ERROR=3]="ERROR"})(MY||={});LH={[0]:"debug",[1]:"info",[2]:"warn",[3]:"error"};u$=new V1({category:"General"})});import{Mutex as yY}from"async-mutex";import{merge as AH}from"lodash-es";import{promises as k8}from"node:fs";import vY from"node:os";import L2 from"node:path";import RH from"write-file-atomic";class s1{static instance=null;pendingUpdates=new Map;timers=new Map;fileLocks=new Map;lastSaveError=null;debounceDelay=300;constructor(){}static getInstance(){if(!s1.instance)s1.instance=new s1;return s1.instance}static resetInstance(){if(s1.instance)for(let $ of s1.instance.timers.values())clearTimeout($);s1.instance=null}async save($,Z={}){this.validatePersistableFields($);let Y=this.groupUpdatesByTarget($,Z.scope);if(Z.immediate)await Promise.all(Array.from(Y.entries()).map(([Q,X])=>this.flushTarget(Q,X)));else for(let[Q,X]of Y)this.scheduleSave(Q,X)}async flush(){for(let Z of this.timers.values())clearTimeout(Z);this.timers.clear();let $=Array.from(this.pendingUpdates.entries()).map(([Z,Y])=>this.flushTarget(Z,Y));this.pendingUpdates.clear(),await Promise.all($)}getLastSaveError(){return this.lastSaveError}clearLastSaveError(){this.lastSaveError=null}async appendPermissionRule($,Z={}){let Y=Z.scope??"local",Q=this.resolveFilePath("settings",Y);await this.flushTargetWithModifier(Q,(X)=>{let J=X.permissions??{allow:[],ask:[],deny:[]},G={allow:this.dedupeArray([...J.allow||[],$]),ask:J.ask||[],deny:J.deny||[]};return{...X,permissions:G}})}async appendLocalPermissionRule($,Z={}){await this.appendPermissionRule($,{...Z,scope:"local"})}validatePersistableFields($){for(let Z of Object.keys($)){let Y=C4[Z];if(!Y)throw Error(`Unknown config field: ${Z}`);if(!Y.persistable)throw Error(`Field "${Z}" is non-persistable and cannot be saved to config files. Non-persistable fields are runtime-only and only valid for the current session.`)}}groupUpdatesByTarget($,Z){let Y=new Map;for(let[Q,X]of Object.entries($)){let J=C4[Q];if(!J)continue;let G=Z??J.defaultScope,K=this.resolveFilePath(J.target,G);if(!Y.has(K))Y.set(K,{});Y.get(K)[Q]=X}return Y}resolveFilePath($,Z){if($==="config")return Z==="global"?L2.join(vY.homedir(),".blade","config.json"):L2.join(process.cwd(),".blade","config.json");switch(Z){case"local":return L2.join(process.cwd(),".blade","settings.local.json");case"project":return L2.join(process.cwd(),".blade","settings.json");case"global":return L2.join(vY.homedir(),".blade","settings.json");default:return L2.join(process.cwd(),".blade","settings.local.json")}}scheduleSave($,Z){let Y=this.pendingUpdates.get($)??{},Q=this.mergePendingUpdates(Y,Z);this.pendingUpdates.set($,Q);let X=this.timers.get($);if(X)clearTimeout(X);let J=setTimeout(async()=>{let G=this.pendingUpdates.get($);if(G){this.pendingUpdates.delete($),this.timers.delete($);try{await this.flushTarget($,G),this.lastSaveError=null}catch(K){let q=K instanceof Error?K:Error(String(K));this.lastSaveError=q,EY.error(`Failed to save config to ${$}:`,q.message),EY.error("Stack trace:",q.stack)}}},this.debounceDelay);this.timers.set($,J)}mergePendingUpdates($,Z){let Y={...$};for(let[Q,X]of Object.entries(Z)){let J=C4[Q];if(!J){Y[Q]=X;continue}switch(J.mergeStrategy){case"replace":Y[Q]=X;break;case"append-dedupe":this.applyAppendDedupe(Y,Q,X);break;case"deep-merge":this.applyDeepMerge(Y,Q,X);break}}return Y}async flushTarget($,Z){let Y=this.fileLocks.get($);if(!Y)Y=new yY,this.fileLocks.set($,Y);await Y.runExclusive(async()=>{await this.performWrite($,Z)})}async flushTargetWithModifier($,Z){let Y=this.fileLocks.get($);if(!Y)Y=new yY,this.fileLocks.set($,Y);await Y.runExclusive(async()=>{await k8.mkdir(L2.dirname($),{recursive:!0,mode:493});let Q={};try{let J=await k8.readFile($,"utf-8");Q=JSON.parse(J)}catch{Q={}}let X=Z(Q);await this.atomicWrite($,X)})}async performWrite($,Z){await k8.mkdir(L2.dirname($),{recursive:!0,mode:493});let Y={};try{let X=await k8.readFile($,"utf-8");Y=JSON.parse(X)}catch{Y={}}let Q={...Y};for(let[X,J]of Object.entries(Z)){let G=C4[X];if(!G){Q[X]=J;continue}switch(G.mergeStrategy){case"replace":Q[X]=J;break;case"append-dedupe":this.applyAppendDedupe(Q,X,J);break;case"deep-merge":this.applyDeepMerge(Q,X,J);break}}await this.atomicWrite($,Q)}applyAppendDedupe($,Z,Y){if(Z==="permissions"&&typeof Y==="object"&&Y!==null){let Q=$[Z]??{allow:[],ask:[],deny:[]},X=Y;$[Z]={allow:this.dedupeArray([...Q.allow||[],...X.allow||[]]),ask:this.dedupeArray([...Q.ask||[],...X.ask||[]]),deny:this.dedupeArray([...Q.deny||[],...X.deny||[]])}}else if(Array.isArray(Y)){let Q=Array.isArray($[Z])?$[Z]:[];$[Z]=this.dedupeArray([...Q,...Y])}else $[Z]=Y}applyDeepMerge($,Z,Y){if(typeof Y==="object"&&Y!==null&&!Array.isArray(Y)){let Q=typeof $[Z]==="object"&&$[Z]!==null?$[Z]:{};$[Z]=AH({},Q,Y)}else $[Z]=Y}dedupeArray($){return Array.from(new Set($))}async atomicWrite($,Z){await RH($,JSON.stringify(Z,null,2),{mode:384,encoding:"utf-8"})}}function C0(){return s1.getInstance()}var EY,C4,aA,rA;var PY=A(()=>{O$();EY=l("Service"),C4={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},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}},aA=new Set(Object.entries(C4).filter(([$,Z])=>Z.persistable).map(([$])=>$)),rA=new Set(Object.entries(C4).filter(([$,Z])=>!Z.persistable).map(([$])=>$))});var S4=A(()=>{DY();PY();v6();U0()});var VH,DH,MH,jH,IH,yH,vH,EH,PH,TH,CH,SH,kH,t1;var S6=A(()=>{VH={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)"}},DH={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)"}},MH={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)"}},jH={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)"}},IH={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)"}},yH={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)"}},vH={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)"}},EH={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)"}},PH={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)"}},TH={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)"}},CH={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)"}},SH={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)"}},kH={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)"}},t1=[{id:"ayu-dark",label:"Ayu Dark",theme:VH,tags:["dark","popular"]},{id:"dracula",label:"Dracula",theme:DH,tags:["dark","popular"]},{id:"monokai",label:"Monokai",theme:MH,tags:["dark","classic"]},{id:"nord",label:"Nord",theme:jH,tags:["dark","minimal"]},{id:"solarized-light",label:"Solarized Light",theme:IH,tags:["light"]},{id:"solarized-dark",label:"Solarized Dark",theme:yH,tags:["dark"]},{id:"tokyo-night",label:"Tokyo Night",theme:vH,tags:["dark","popular"]},{id:"github",label:"GitHub",theme:EH,tags:["light","minimal"]},{id:"gruvbox",label:"Gruvbox",theme:PH,tags:["dark","warm"]},{id:"one-dark",label:"One Dark",theme:TH,tags:["dark","popular"]},{id:"catppuccin",label:"Catppuccin",theme:CH,tags:["dark","pastel"]},{id:"rose-pine",label:"Rose Pine",theme:SH,tags:["dark","elegant"]},{id:"kanagawa",label:"Kanagawa",theme:kH,tags:["dark","japanese"]}]});class CY{currentTheme=k6;themes=new Map;constructor(){this.themes.set("default",k6),this.themes.set("dark",fH);for(let $ of t1)this.themes.set($.id,$.theme)}setTheme($){let Z=this.themes.get($);if(Z)this.currentTheme=Z;else throw Error(`Theme '${$}' not found`)}getTheme(){return this.currentTheme}getAvailableThemes(){return Array.from(this.themes.keys())}getCurrentThemeName(){return this.currentTheme.name}getThemeByName($){return this.themes.get($)}hasTheme($){return this.themes.has($)}}var TY,k6,fH,g0;var r2=A(()=>{S6();TY={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:TY,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)"}},fH={...k6,name:"dark",colors:{...TY,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"}}};g0=new CY});var hH,f6=($)=>({...hH,actions:{setInitializationStatus:(Z)=>{$((Y)=>({app:{...Y.app,initializationStatus:Z}}))},setInitializationError:(Z)=>{$((Y)=>({app:{...Y.app,initializationError:Z}}))},setActiveModal:(Z)=>{$((Y)=>({app:{...Y.app,activeModal:Z}}))},showSessionSelector:(Z)=>{$((Y)=>({app:{...Y.app,activeModal:"sessionSelector",sessionSelectorData:Z}}))},showModelEditWizard:(Z)=>{$((Y)=>({app:{...Y.app,activeModal:"modelEditWizard",modelEditorTarget:Z}}))},closeModal:()=>{$((Z)=>({app:{...Z.app,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null}}))},setTodos:(Z)=>{$((Y)=>({app:{...Y.app,todos:Z}}))},updateTodo:(Z)=>{$((Y)=>({app:{...Y.app,todos:Y.app.todos.map((Q)=>Q.id===Z.id?Z:Q)}}))},setAwaitingSecondCtrlC:(Z)=>{$((Y)=>({app:{...Y.app,awaitingSecondCtrlC:Z}}))},setThinkingModeEnabled:(Z)=>{$((Y)=>({app:{...Y.app,thinkingModeEnabled:Z}}))},toggleThinkingMode:()=>{$((Z)=>({app:{...Z.app,thinkingModeEnabled:!Z.app.thinkingModeEnabled}}))}}});var SY=A(()=>{hH={initializationStatus:"idle",initializationError:null,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null,todos:[],awaitingSecondCtrlC:!1,thinkingModeEnabled:!1}});var xH,h6=($,Z)=>({...xH,actions:{setProcessing:(Y)=>{$((Q)=>({command:{...Q.command,isProcessing:Y}}))},createAbortController:()=>{let Y=Z().command.abortController;if(Y&&!Y.signal.aborted)return Y;let Q=new AbortController;return $((X)=>({command:{...X.command,abortController:Q}})),Q},getAbortController:()=>{return Z().command.abortController},clearAbortController:(Y)=>{let Q=Z().command.abortController;if(Y!==void 0&&Q!==Y)return;$((X)=>({command:{...X.command,abortController:null}}))},abort:()=>{let{abortController:Y}=Z().command;if(Y&&!Y.signal.aborted)Y.abort();$((Q)=>({command:{...Q.command,isProcessing:!1,pendingCommands:[]}}))},enqueueCommand:(Y)=>{$((Q)=>({command:{...Q.command,pendingCommands:[...Q.command.pendingCommands,Y]}}))},dequeueCommand:()=>{let{pendingCommands:Y}=Z().command;if(Y.length===0)return;let[Q,...X]=Y;return $((J)=>({command:{...J.command,pendingCommands:X}})),Q},clearQueue:()=>{$((Y)=>({command:{...Y.command,pendingCommands:[]}}))}}});var kY=A(()=>{xH={isProcessing:!1,abortController:null,pendingCommands:[]}});var pH,x6=($)=>({...pH,actions:{setConfig:(Z)=>{$((Y)=>({config:{...Y.config,config:Z}}))},updateConfig:(Z)=>{$((Y)=>{if(!Y.config.config)throw Error(`[ConfigSlice] Config not initialized. Cannot update: ${JSON.stringify(Z)}`);return{config:{...Y.config,config:{...Y.config.config,...Z}}}})}}});var fY=A(()=>{pH={config:null}});var mH,p6=($)=>({...mH,actions:{setFocus:(Z)=>{$((Y)=>({focus:{...Y.focus,currentFocus:Z,previousFocus:Y.focus.currentFocus}}))},restorePreviousFocus:()=>{$((Z)=>({focus:{...Z.focus,currentFocus:Z.focus.previousFocus||"main-input",previousFocus:null}}))}}});var hY=A(()=>{mH={currentFocus:"main-input",previousFocus:null}});function n2($){let Z=[],Y=$.split(/\r?\n/),Q=!1,X=[],J=null,G=0,K=!1,q=[],W=[],U=!1,H=[],F=!0;for(let O=0;O<Y.length;O++){let z=Y[O];if(U){if(z.match(y$.diffEnd)){try{let v=JSON.parse(H.join(`
25
+ `)}}function E6($,Z={}){let Y={...$};if(Z.debug!==void 0)Y.debug=Z.debug===""?!0:Z.debug;if(Z.yolo===!0)Y.permissionMode="yolo";else if(Z.permissionMode!==void 0)Y.permissionMode=Z.permissionMode;if(Z.maxTurns!==void 0)Y.maxTurns=Z.maxTurns;return Y.systemPrompt=Z.systemPrompt,Y.appendSystemPrompt=Z.appendSystemPrompt,Y.resumeSessionId=Z.sessionId,Y.forkSession=Z.forkSession,Y.allowedTools=Z.allowedTools,Y.disallowedTools=Z.disallowedTools,Y.mcpConfigPaths=Z.mcpConfig,Y.strictMcpConfig=Z.strictMcpConfig,Y.addDirs=Z.addDir,Y.outputFormat=Z.outputFormat,Y.inputFormat=Z.inputFormat,Y.print=Z.print,Y.includePartialMessages=Z.includePartialMessages,Y.replayUserMessages=Z.replayUserMessages,Y.agentsConfig=Z.agents,Y.settingSources=Z.settingSources,Y}var DY=A(()=>{v6();U0()});import{promises as T2}from"node:fs";import _H from"node:os";import P6 from"node:path";import BH from"pino";async function jY(){if(q1)try{if(typeof q1.flush==="function")q1.flush();await new Promise(($)=>setTimeout($,100))}catch($){console.error("[Logger] 关闭日志系统时出错:",$)}q1=null,P2=null}function IY($){if(T6!==$)T6=$,C6()}async function wH(){try{let $=P6.join(_H.homedir(),".blade","logs");await T2.mkdir($,{recursive:!0,mode:493});try{if((await T2.stat($)).uid===0&&process.getuid&&process.getuid()!==0)return console.error(""),console.error("❌ 权限错误:~/.blade/logs 目录属于 root 用户"),console.error(""),console.error("这通常是因为您曾经使用 sudo 运行过 blade。"),console.error(""),console.error("解决方法:"),console.error(" sudo chown -R $USER:$USER ~/.blade/"),console.error(""),console.error("然后重新运行 blade(不要使用 sudo)"),console.error(""),null}catch(Q){}await NH($,30);let Y=`blade-${T6||"default"}.log`;return P6.join($,Y)}catch($){return console.error("[Logger] 无法创建日志目录:",$),null}}async function NH($,Z){try{let Y=await T2.readdir($),Q=Date.now(),X=Z*24*60*60*1000;for(let J of Y){if(!J.startsWith("blade-")||!J.endsWith(".log"))continue;let G=P6.join($,J);try{let K=await T2.stat(G);if(Q-K.mtimeMs>X)await T2.unlink(G),console.error(`[Logger] 已清理旧日志: ${J}`)}catch(K){}}}catch(Y){console.error("[Logger] 清理旧日志失败:",Y)}}async function bH(){if(q1)return q1;if(P2)return P2;return P2=(async()=>{try{let $=await wH();if(!$)return console.warn("[Logger] 文件日志已禁用(目录创建失败)"),null;return q1=BH({level:"debug",transport:{target:"pino/file",options:{destination:$}}}),q1}catch($){return console.error("[Logger] Pino 初始化失败:",$),null}})(),P2}function C6(){if(q1&&typeof q1.flush==="function")try{q1.flush()}catch($){}q1=null,P2=null}class V1{static globalDebugConfig=null;enabled;minLevel;category;pinoLogger=null;constructor($={}){if($.enabled!==void 0)this.enabled=$.enabled;else if(V1.globalDebugConfig!==null)this.enabled=Boolean(V1.globalDebugConfig);else this.enabled=!1;this.minLevel=$.minLevel??0,this.category=$.category??"General",this.initPino()}async initPino(){try{let $=await bH();if($)this.pinoLogger=$.child({category:this.category})}catch($){console.error("[Logger] Failed to initialize pino:",$)}}static setGlobalDebug($){V1.globalDebugConfig=$,C6()}static clearGlobalDebug(){V1.globalDebugConfig=null,C6()}setEnabled($){this.enabled=$}parseDebugFilter($){if(!$)return{enabled:!1};if($===!0||$==="true"||$==="1")return{enabled:!0};let Z=String($).trim();if(!Z)return{enabled:!0};if(Z.startsWith("!"))return{enabled:!0,filter:{mode:"exclude",categories:Z.split(",").map((X)=>X.trim().replace(/^!/,"")).filter(Boolean)}};return{enabled:!0,filter:{mode:"include",categories:Z.split(",").map((Q)=>Q.trim()).filter(Boolean)}}}shouldLogCategory($){if(!$)return!0;let Z=this.category.toLowerCase();if($.mode==="include")return $.categories.some((Y)=>Z.includes(Y.toLowerCase()));return!$.categories.some((Y)=>Z.includes(Y.toLowerCase()))}shouldLogToConsole($){if(V1.globalDebugConfig!==null){let{enabled:Z,filter:Y}=this.parseDebugFilter(V1.globalDebugConfig);if(!Z)return!1;if($<this.minLevel)return!1;return this.shouldLogCategory(Y)}return this.enabled&&$>=this.minLevel}log($,...Z){let Y=Z.map((Q)=>typeof Q==="object"?JSON.stringify(Q):String(Q)).join(" ");if(this.pinoLogger){let Q=LH[$];this.pinoLogger[Q](Y)}if(this.shouldLogToConsole($)){let Q=MY[$],X=`[${this.category}] [${Q}]`;console.error(X,...Z)}}debug(...$){this.log(0,...$)}info(...$){this.log(1,...$)}warn(...$){this.log(2,...$)}error(...$){this.log(3,...$)}}function l($,Z){return new V1({...Z,category:$})}var MY,LH,T6=null,q1=null,P2=null,u$;var O$=A(()=>{((X)=>{X[X.DEBUG=0]="DEBUG";X[X.INFO=1]="INFO";X[X.WARN=2]="WARN";X[X.ERROR=3]="ERROR"})(MY||={});LH={[0]:"debug",[1]:"info",[2]:"warn",[3]:"error"};u$=new V1({category:"General"})});import{Mutex as yY}from"async-mutex";import{merge as AH}from"lodash-es";import{promises as k3}from"node:fs";import vY from"node:os";import L4 from"node:path";import RH from"write-file-atomic";class s1{static instance=null;pendingUpdates=new Map;timers=new Map;fileLocks=new Map;lastSaveError=null;debounceDelay=300;constructor(){}static getInstance(){if(!s1.instance)s1.instance=new s1;return s1.instance}static resetInstance(){if(s1.instance)for(let $ of s1.instance.timers.values())clearTimeout($);s1.instance=null}async save($,Z={}){this.validatePersistableFields($);let Y=this.groupUpdatesByTarget($,Z.scope);if(Z.immediate)await Promise.all(Array.from(Y.entries()).map(([Q,X])=>this.flushTarget(Q,X)));else for(let[Q,X]of Y)this.scheduleSave(Q,X)}async flush(){for(let Z of this.timers.values())clearTimeout(Z);this.timers.clear();let $=Array.from(this.pendingUpdates.entries()).map(([Z,Y])=>this.flushTarget(Z,Y));this.pendingUpdates.clear(),await Promise.all($)}getLastSaveError(){return this.lastSaveError}clearLastSaveError(){this.lastSaveError=null}async appendPermissionRule($,Z={}){let Y=Z.scope??"local",Q=this.resolveFilePath("settings",Y);await this.flushTargetWithModifier(Q,(X)=>{let J=X.permissions??{allow:[],ask:[],deny:[]},G={allow:this.dedupeArray([...J.allow||[],$]),ask:J.ask||[],deny:J.deny||[]};return{...X,permissions:G}})}async appendLocalPermissionRule($,Z={}){await this.appendPermissionRule($,{...Z,scope:"local"})}validatePersistableFields($){for(let Z of Object.keys($)){let Y=C2[Z];if(!Y)throw Error(`Unknown config field: ${Z}`);if(!Y.persistable)throw Error(`Field "${Z}" is non-persistable and cannot be saved to config files. Non-persistable fields are runtime-only and only valid for the current session.`)}}groupUpdatesByTarget($,Z){let Y=new Map;for(let[Q,X]of Object.entries($)){let J=C2[Q];if(!J)continue;let G=Z??J.defaultScope,K=this.resolveFilePath(J.target,G);if(!Y.has(K))Y.set(K,{});Y.get(K)[Q]=X}return Y}resolveFilePath($,Z){if($==="config")return Z==="global"?L4.join(vY.homedir(),".blade","config.json"):L4.join(process.cwd(),".blade","config.json");switch(Z){case"local":return L4.join(process.cwd(),".blade","settings.local.json");case"project":return L4.join(process.cwd(),".blade","settings.json");case"global":return L4.join(vY.homedir(),".blade","settings.json");default:return L4.join(process.cwd(),".blade","settings.local.json")}}scheduleSave($,Z){let Y=this.pendingUpdates.get($)??{},Q=this.mergePendingUpdates(Y,Z);this.pendingUpdates.set($,Q);let X=this.timers.get($);if(X)clearTimeout(X);let J=setTimeout(async()=>{let G=this.pendingUpdates.get($);if(G){this.pendingUpdates.delete($),this.timers.delete($);try{await this.flushTarget($,G),this.lastSaveError=null}catch(K){let q=K instanceof Error?K:Error(String(K));this.lastSaveError=q,EY.error(`Failed to save config to ${$}:`,q.message),EY.error("Stack trace:",q.stack)}}},this.debounceDelay);this.timers.set($,J)}mergePendingUpdates($,Z){let Y={...$};for(let[Q,X]of Object.entries(Z)){let J=C2[Q];if(!J){Y[Q]=X;continue}switch(J.mergeStrategy){case"replace":Y[Q]=X;break;case"append-dedupe":this.applyAppendDedupe(Y,Q,X);break;case"deep-merge":this.applyDeepMerge(Y,Q,X);break}}return Y}async flushTarget($,Z){let Y=this.fileLocks.get($);if(!Y)Y=new yY,this.fileLocks.set($,Y);await Y.runExclusive(async()=>{await this.performWrite($,Z)})}async flushTargetWithModifier($,Z){let Y=this.fileLocks.get($);if(!Y)Y=new yY,this.fileLocks.set($,Y);await Y.runExclusive(async()=>{await k3.mkdir(L4.dirname($),{recursive:!0,mode:493});let Q={};try{let J=await k3.readFile($,"utf-8");Q=JSON.parse(J)}catch{Q={}}let X=Z(Q);await this.atomicWrite($,X)})}async performWrite($,Z){await k3.mkdir(L4.dirname($),{recursive:!0,mode:493});let Y={};try{let X=await k3.readFile($,"utf-8");Y=JSON.parse(X)}catch{Y={}}let Q={...Y};for(let[X,J]of Object.entries(Z)){let G=C2[X];if(!G){Q[X]=J;continue}switch(G.mergeStrategy){case"replace":Q[X]=J;break;case"append-dedupe":this.applyAppendDedupe(Q,X,J);break;case"deep-merge":this.applyDeepMerge(Q,X,J);break}}await this.atomicWrite($,Q)}applyAppendDedupe($,Z,Y){if(Z==="permissions"&&typeof Y==="object"&&Y!==null){let Q=$[Z]??{allow:[],ask:[],deny:[]},X=Y;$[Z]={allow:this.dedupeArray([...Q.allow||[],...X.allow||[]]),ask:this.dedupeArray([...Q.ask||[],...X.ask||[]]),deny:this.dedupeArray([...Q.deny||[],...X.deny||[]])}}else if(Array.isArray(Y)){let Q=Array.isArray($[Z])?$[Z]:[];$[Z]=this.dedupeArray([...Q,...Y])}else $[Z]=Y}applyDeepMerge($,Z,Y){if(typeof Y==="object"&&Y!==null&&!Array.isArray(Y)){let Q=typeof $[Z]==="object"&&$[Z]!==null?$[Z]:{};$[Z]=AH({},Q,Y)}else $[Z]=Y}dedupeArray($){return Array.from(new Set($))}async atomicWrite($,Z){await RH($,JSON.stringify(Z,null,2),{mode:384,encoding:"utf-8"})}}function C0(){return s1.getInstance()}var EY,C2,aA,rA;var PY=A(()=>{O$();EY=l("Service"),C2={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},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}},aA=new Set(Object.entries(C2).filter(([$,Z])=>Z.persistable).map(([$])=>$)),rA=new Set(Object.entries(C2).filter(([$,Z])=>!Z.persistable).map(([$])=>$))});var S2=A(()=>{DY();PY();v6();U0()});var VH,DH,MH,jH,IH,yH,vH,EH,PH,TH,CH,SH,kH,t1;var S6=A(()=>{VH={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)"}},DH={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)"}},MH={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)"}},jH={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)"}},IH={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)"}},yH={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)"}},vH={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)"}},EH={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)"}},PH={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)"}},TH={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)"}},CH={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)"}},SH={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)"}},kH={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)"}},t1=[{id:"ayu-dark",label:"Ayu Dark",theme:VH,tags:["dark","popular"]},{id:"dracula",label:"Dracula",theme:DH,tags:["dark","popular"]},{id:"monokai",label:"Monokai",theme:MH,tags:["dark","classic"]},{id:"nord",label:"Nord",theme:jH,tags:["dark","minimal"]},{id:"solarized-light",label:"Solarized Light",theme:IH,tags:["light"]},{id:"solarized-dark",label:"Solarized Dark",theme:yH,tags:["dark"]},{id:"tokyo-night",label:"Tokyo Night",theme:vH,tags:["dark","popular"]},{id:"github",label:"GitHub",theme:EH,tags:["light","minimal"]},{id:"gruvbox",label:"Gruvbox",theme:PH,tags:["dark","warm"]},{id:"one-dark",label:"One Dark",theme:TH,tags:["dark","popular"]},{id:"catppuccin",label:"Catppuccin",theme:CH,tags:["dark","pastel"]},{id:"rose-pine",label:"Rose Pine",theme:SH,tags:["dark","elegant"]},{id:"kanagawa",label:"Kanagawa",theme:kH,tags:["dark","japanese"]}]});class CY{currentTheme=k6;themes=new Map;constructor(){this.themes.set("default",k6),this.themes.set("dark",fH);for(let $ of t1)this.themes.set($.id,$.theme)}setTheme($){let Z=this.themes.get($);if(Z)this.currentTheme=Z;else throw Error(`Theme '${$}' not found`)}getTheme(){return this.currentTheme}getAvailableThemes(){return Array.from(this.themes.keys())}getCurrentThemeName(){return this.currentTheme.name}getThemeByName($){return this.themes.get($)}hasTheme($){return this.themes.has($)}}var TY,k6,fH,g0;var r4=A(()=>{S6();TY={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:TY,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)"}},fH={...k6,name:"dark",colors:{...TY,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"}}};g0=new CY});var hH,f6=($)=>({...hH,actions:{setInitializationStatus:(Z)=>{$((Y)=>({app:{...Y.app,initializationStatus:Z}}))},setInitializationError:(Z)=>{$((Y)=>({app:{...Y.app,initializationError:Z}}))},setActiveModal:(Z)=>{$((Y)=>({app:{...Y.app,activeModal:Z}}))},showSessionSelector:(Z)=>{$((Y)=>({app:{...Y.app,activeModal:"sessionSelector",sessionSelectorData:Z}}))},showModelEditWizard:(Z)=>{$((Y)=>({app:{...Y.app,activeModal:"modelEditWizard",modelEditorTarget:Z}}))},closeModal:()=>{$((Z)=>({app:{...Z.app,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null}}))},setTodos:(Z)=>{$((Y)=>({app:{...Y.app,todos:Z}}))},updateTodo:(Z)=>{$((Y)=>({app:{...Y.app,todos:Y.app.todos.map((Q)=>Q.id===Z.id?Z:Q)}}))},setAwaitingSecondCtrlC:(Z)=>{$((Y)=>({app:{...Y.app,awaitingSecondCtrlC:Z}}))},setThinkingModeEnabled:(Z)=>{$((Y)=>({app:{...Y.app,thinkingModeEnabled:Z}}))},toggleThinkingMode:()=>{$((Z)=>({app:{...Z.app,thinkingModeEnabled:!Z.app.thinkingModeEnabled}}))}}});var SY=A(()=>{hH={initializationStatus:"idle",initializationError:null,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null,todos:[],awaitingSecondCtrlC:!1,thinkingModeEnabled:!1}});var xH,h6=($,Z)=>({...xH,actions:{setProcessing:(Y)=>{$((Q)=>({command:{...Q.command,isProcessing:Y}}))},createAbortController:()=>{let Y=Z().command.abortController;if(Y&&!Y.signal.aborted)return Y;let Q=new AbortController;return $((X)=>({command:{...X.command,abortController:Q}})),Q},getAbortController:()=>{return Z().command.abortController},clearAbortController:(Y)=>{let Q=Z().command.abortController;if(Y!==void 0&&Q!==Y)return;$((X)=>({command:{...X.command,abortController:null}}))},abort:()=>{let{abortController:Y}=Z().command;if(Y&&!Y.signal.aborted)Y.abort();$((Q)=>({command:{...Q.command,isProcessing:!1,pendingCommands:[]}}))},enqueueCommand:(Y)=>{$((Q)=>({command:{...Q.command,pendingCommands:[...Q.command.pendingCommands,Y]}}))},dequeueCommand:()=>{let{pendingCommands:Y}=Z().command;if(Y.length===0)return;let[Q,...X]=Y;return $((J)=>({command:{...J.command,pendingCommands:X}})),Q},clearQueue:()=>{$((Y)=>({command:{...Y.command,pendingCommands:[]}}))}}});var kY=A(()=>{xH={isProcessing:!1,abortController:null,pendingCommands:[]}});var pH,x6=($)=>({...pH,actions:{setConfig:(Z)=>{$((Y)=>({config:{...Y.config,config:Z}}))},updateConfig:(Z)=>{$((Y)=>{if(!Y.config.config)throw Error(`[ConfigSlice] Config not initialized. Cannot update: ${JSON.stringify(Z)}`);return{config:{...Y.config,config:{...Y.config.config,...Z}}}})}}});var fY=A(()=>{pH={config:null}});var mH,p6=($)=>({...mH,actions:{setFocus:(Z)=>{$((Y)=>({focus:{...Y.focus,currentFocus:Z,previousFocus:Y.focus.currentFocus}}))},restorePreviousFocus:()=>{$((Z)=>({focus:{...Z.focus,currentFocus:Z.focus.previousFocus||"main-input",previousFocus:null}}))}}});var hY=A(()=>{mH={currentFocus:"main-input",previousFocus:null}});function n4($){let Z=[],Y=$.split(/\r?\n/),Q=!1,X=[],J=null,G=0,K=!1,q=[],W=[],U=!1,H=[],F=!0;for(let O=0;O<Y.length;O++){let z=Y[O];if(U){if(z.match(y$.diffEnd)){try{let v=JSON.parse(H.join(`
26
26
  `));Z.push({type:"diff",content:"",diffData:{patch:v.patch,startLine:v.startLine,matchLine:v.matchLine}})}catch(v){Z.push({type:"text",content:H.join(`
27
27
  `)})}U=!1,H=[],F=!1;continue}H.push(z);continue}if(z.match(y$.diffStart)){U=!0,H=[],F=!1;continue}if(Q){let v=z.match(y$.codeBlock),b=z.trim()==="```";if(v&&v[1])G++,X.push(z);else if(b)if(G>0)G--,X.push(z);else{let C=X.join(`
28
- `);if(J?.toLowerCase()==="markdown"||J?.toLowerCase()==="md"){let d=n2(C);Z.push(...d)}else Z.push({type:"code",content:C,language:J||void 0});Q=!1,X=[],J=null,G=0,F=!1}else X.push(z);continue}let _=z.match(y$.codeBlock);if(_){Q=!0,J=_[1]||null,G=0,F=!1;continue}let B=z.match(y$.table),L=z.match(y$.tableSeparator);if(B&&!K){if(O+1<Y.length){if(Y[O+1].match(y$.tableSeparator)){K=!0,q=B[1].split("|").map((b)=>b.trim()).filter((b)=>b.length>0),W=[],F=!1;continue}}}if(K&&L)continue;if(K&&B){let v=B[1].split("|").map((b)=>b.trim()).filter((b)=>b.length>0);while(v.length<q.length)v.push("");if(v.length>q.length)v.length=q.length;W.push(v);continue}if(K&&!B){if(q.length>0&&W.length>0)Z.push({type:"table",content:"",tableData:{headers:q,rows:W}});K=!1,q=[],W=[]}let w=z.match(y$.heading);if(w){Z.push({type:"heading",content:w[2],level:w[1].length}),F=!1;continue}let N=z.match(y$.ulItem);if(N){Z.push({type:"list",content:N[3],listType:"ul",marker:N[2],indentation:N[1].length}),F=!1;continue}let D=z.match(y$.olItem);if(D){Z.push({type:"list",content:D[3],listType:"ol",marker:D[2],indentation:D[1].length}),F=!1;continue}if(z.match(y$.hr)){Z.push({type:"hr",content:""}),F=!1;continue}if(z.trim().length===0){if(!F)Z.push({type:"empty",content:""}),F=!0;continue}let I=z.match(y$.commandMessage);if(I){Z.push({type:"command-message",content:I[1]}),F=!1;continue}Z.push({type:"text",content:z}),F=!1}if(Q){let O=X.join(`
29
- `);if(J?.toLowerCase()==="markdown"||J?.toLowerCase()==="md"){let z=n2(O);Z.push(...z)}else Z.push({type:"code",content:O,language:J||void 0})}if(K&&q.length>0&&W.length>0)Z.push({type:"table",content:"",tableData:{headers:q,rows:W}});while(Z.length>0&&Z[Z.length-1].type==="empty")Z.pop();return Z}var y$;var m6=A(()=>{y$={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 dH(){return{inCodeBlock:!1,codeBlockContent:[],codeBlockLang:null,codeBlockDepth:0,inTable:!1,tableHeaders:[],tableRows:[],inDiff:!1,diffContent:[],lastLineEmpty:!0,pendingTableHeader:null}}function uH($){let Z=e1.get($);if(Z)return Z;let Y={state:dH(),blocks:[],pendingLine:"",finalized:!1};return e1.set($,Y),Y}function xY($){return $.endsWith("\r")?$.slice(0,-1):$}function pY($,Z){if($.tableHeaders.length>0&&$.tableRows.length>0)Z.push({type:"table",content:"",tableData:{headers:$.tableHeaders,rows:$.tableRows}});$.inTable=!1,$.tableHeaders=[],$.tableRows=[]}function mY($,Z){let Y=$.codeBlockContent.join(`
30
- `);if($.codeBlockLang?.toLowerCase()==="markdown"||$.codeBlockLang?.toLowerCase()==="md")Z.push(...n2(Y));else Z.push({type:"code",content:Y,language:$.codeBlockLang||void 0});$.inCodeBlock=!1,$.codeBlockContent=[],$.codeBlockLang=null,$.codeBlockDepth=0,$.lastLineEmpty=!1}function d6($,Z,Y=!0){let{state:Q,blocks:X}=Z;if(Q.pendingTableHeader!==null){if($.match(y$.tableSeparator)){Q.inTable=!0,Q.tableHeaders=Q.pendingTableHeader.slice(1,-1).split("|").map((O)=>O.trim()).filter((O)=>O.length>0),Q.tableRows=[],Q.pendingTableHeader=null,Q.lastLineEmpty=!1;return}X.push({type:"text",content:Q.pendingTableHeader}),Q.pendingTableHeader=null,Q.lastLineEmpty=!1}if(Q.inDiff){if($.match(y$.diffEnd)){try{let O=JSON.parse(Q.diffContent.join(`
28
+ `);if(J?.toLowerCase()==="markdown"||J?.toLowerCase()==="md"){let d=n4(C);Z.push(...d)}else Z.push({type:"code",content:C,language:J||void 0});Q=!1,X=[],J=null,G=0,F=!1}else X.push(z);continue}let _=z.match(y$.codeBlock);if(_){Q=!0,J=_[1]||null,G=0,F=!1;continue}let B=z.match(y$.table),L=z.match(y$.tableSeparator);if(B&&!K){if(O+1<Y.length){if(Y[O+1].match(y$.tableSeparator)){K=!0,q=B[1].split("|").map((b)=>b.trim()).filter((b)=>b.length>0),W=[],F=!1;continue}}}if(K&&L)continue;if(K&&B){let v=B[1].split("|").map((b)=>b.trim()).filter((b)=>b.length>0);while(v.length<q.length)v.push("");if(v.length>q.length)v.length=q.length;W.push(v);continue}if(K&&!B){if(q.length>0&&W.length>0)Z.push({type:"table",content:"",tableData:{headers:q,rows:W}});K=!1,q=[],W=[]}let w=z.match(y$.heading);if(w){Z.push({type:"heading",content:w[2],level:w[1].length}),F=!1;continue}let N=z.match(y$.ulItem);if(N){Z.push({type:"list",content:N[3],listType:"ul",marker:N[2],indentation:N[1].length}),F=!1;continue}let D=z.match(y$.olItem);if(D){Z.push({type:"list",content:D[3],listType:"ol",marker:D[2],indentation:D[1].length}),F=!1;continue}if(z.match(y$.hr)){Z.push({type:"hr",content:""}),F=!1;continue}if(z.trim().length===0){if(!F)Z.push({type:"empty",content:""}),F=!0;continue}let I=z.match(y$.commandMessage);if(I){Z.push({type:"command-message",content:I[1]}),F=!1;continue}Z.push({type:"text",content:z}),F=!1}if(Q){let O=X.join(`
29
+ `);if(J?.toLowerCase()==="markdown"||J?.toLowerCase()==="md"){let z=n4(O);Z.push(...z)}else Z.push({type:"code",content:O,language:J||void 0})}if(K&&q.length>0&&W.length>0)Z.push({type:"table",content:"",tableData:{headers:q,rows:W}});while(Z.length>0&&Z[Z.length-1].type==="empty")Z.pop();return Z}var y$;var m6=A(()=>{y$={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 dH(){return{inCodeBlock:!1,codeBlockContent:[],codeBlockLang:null,codeBlockDepth:0,inTable:!1,tableHeaders:[],tableRows:[],inDiff:!1,diffContent:[],lastLineEmpty:!0,pendingTableHeader:null}}function uH($){let Z=e1.get($);if(Z)return Z;let Y={state:dH(),blocks:[],pendingLine:"",finalized:!1};return e1.set($,Y),Y}function xY($){return $.endsWith("\r")?$.slice(0,-1):$}function pY($,Z){if($.tableHeaders.length>0&&$.tableRows.length>0)Z.push({type:"table",content:"",tableData:{headers:$.tableHeaders,rows:$.tableRows}});$.inTable=!1,$.tableHeaders=[],$.tableRows=[]}function mY($,Z){let Y=$.codeBlockContent.join(`
30
+ `);if($.codeBlockLang?.toLowerCase()==="markdown"||$.codeBlockLang?.toLowerCase()==="md")Z.push(...n4(Y));else Z.push({type:"code",content:Y,language:$.codeBlockLang||void 0});$.inCodeBlock=!1,$.codeBlockContent=[],$.codeBlockLang=null,$.codeBlockDepth=0,$.lastLineEmpty=!1}function d6($,Z,Y=!0){let{state:Q,blocks:X}=Z;if(Q.pendingTableHeader!==null){if($.match(y$.tableSeparator)){Q.inTable=!0,Q.tableHeaders=Q.pendingTableHeader.slice(1,-1).split("|").map((O)=>O.trim()).filter((O)=>O.length>0),Q.tableRows=[],Q.pendingTableHeader=null,Q.lastLineEmpty=!1;return}X.push({type:"text",content:Q.pendingTableHeader}),Q.pendingTableHeader=null,Q.lastLineEmpty=!1}if(Q.inDiff){if($.match(y$.diffEnd)){try{let O=JSON.parse(Q.diffContent.join(`
31
31
  `));X.push({type:"diff",content:"",diffData:{patch:O.patch,startLine:O.startLine,matchLine:O.matchLine}})}catch(O){X.push({type:"text",content:Q.diffContent.join(`
32
32
  `)})}Q.inDiff=!1,Q.diffContent=[],Q.lastLineEmpty=!1;return}Q.diffContent.push($);return}if($.match(y$.diffStart)){Q.inDiff=!0,Q.diffContent=[],Q.lastLineEmpty=!1;return}if(Q.inCodeBlock){let O=$.match(y$.codeBlock),z=$.trim()==="```";if(O&&O[1])Q.codeBlockDepth++,Q.codeBlockContent.push($);else if(z)if(Q.codeBlockDepth>0)Q.codeBlockDepth--,Q.codeBlockContent.push($);else mY(Q,X);else Q.codeBlockContent.push($);return}let J=$.match(y$.codeBlock);if(J){Q.inCodeBlock=!0,Q.codeBlockLang=J[1]||null,Q.codeBlockDepth=0,Q.lastLineEmpty=!1;return}let G=$.match(y$.table),K=$.match(y$.tableSeparator);if(G&&!Q.inTable){Q.pendingTableHeader=$;return}if(Q.inTable&&K)return;if(Q.inTable&&G){let O=G[1].split("|").map((z)=>z.trim()).filter((z)=>z.length>0);while(O.length<Q.tableHeaders.length)O.push("");if(O.length>Q.tableHeaders.length)O.length=Q.tableHeaders.length;Q.tableRows.push(O);return}if(Q.inTable&&!G){if(pY(Q,X),Y){d6($,Z,!1);return}}let q=$.match(y$.heading);if(q){X.push({type:"heading",content:q[2],level:q[1].length}),Q.lastLineEmpty=!1;return}let W=$.match(y$.ulItem);if(W){X.push({type:"list",content:W[3],listType:"ul",marker:W[2],indentation:W[1].length}),Q.lastLineEmpty=!1;return}let U=$.match(y$.olItem);if(U){X.push({type:"list",content:U[3],listType:"ol",marker:U[2],indentation:U[1].length}),Q.lastLineEmpty=!1;return}if($.match(y$.hr)){X.push({type:"hr",content:""}),Q.lastLineEmpty=!1;return}if($.trim().length===0){if(!Q.lastLineEmpty)X.push({type:"empty",content:""}),Q.lastLineEmpty=!0;return}let F=$.match(y$.commandMessage);if(F){X.push({type:"command-message",content:F[1]}),Q.lastLineEmpty=!1;return}X.push({type:"text",content:$}),Q.lastLineEmpty=!1}function u6($,Z){if(!$||!Z)return;let Y=uH($);if(Y.finalized)return;let Q=Y.pendingLine+Z,X=Q.split(`
33
33
  `),J=Q.endsWith(`
34
34
  `),G=J?X:X.slice(0,-1);Y.pendingLine=J?"":X[X.length-1]??"";for(let K of G)d6(xY(K),Y)}function g6($){let Z=e1.get($);if(!Z||Z.finalized)return;if(Z.pendingLine)d6(xY(Z.pendingLine),Z),Z.pendingLine="";if(Z.state.pendingTableHeader!==null)Z.blocks.push({type:"text",content:Z.state.pendingTableHeader}),Z.state.pendingTableHeader=null;if(Z.state.inCodeBlock)mY(Z.state,Z.blocks);if(Z.state.inTable)pY(Z.state,Z.blocks);if(Z.state.inDiff)Z.blocks.push({type:"text",content:Z.state.diffContent.join(`
35
- `)}),Z.state.inDiff=!1,Z.state.diffContent=[];while(Z.blocks.length>0&&Z.blocks[Z.blocks.length-1].type==="empty")Z.blocks.pop();Z.finalized=!0}function dY($){let Z=e1.get($);if(!Z||!Z.finalized)return null;return Z.blocks}function c6($){let Z=e1.get($);if(!Z)return null;return Z.blocks}function gH($){let Z=e1.get($);if(!Z)return null;let Y=[],Q=Z.state;if(Q.inDiff)Y.push("<<<DIFF>>>"),Y.push(...Q.diffContent);else if(Q.inCodeBlock){let X=Q.codeBlockLang?`\`\`\`${Q.codeBlockLang}`:"```";Y.push(X),Y.push(...Q.codeBlockContent)}else if(Q.inTable){if(Q.tableHeaders.length>0){Y.push(`| ${Q.tableHeaders.join(" | ")} |`),Y.push(`| ${Q.tableHeaders.map(()=>"---").join(" | ")} |`);for(let X of Q.tableRows)Y.push(`| ${X.join(" | ")} |`)}}else if(Q.pendingTableHeader)Y.push(Q.pendingTableHeader);if(Z.pendingLine)Y.push(Z.pendingLine);return Y.length>0?Y:null}function uY($){let Z=e1.get($);if(!Z)return null;let Y="text";if(Z.state.inDiff)Y="diff";else if(Z.state.inCodeBlock)Y="code";else if(Z.state.inTable||Z.state.pendingTableHeader)Y="table";let Q=gH($);if(!Q||Q.length===0)return null;return{lines:Q,mode:Y}}function gY($){e1.delete($)}function f8(){e1.clear()}var e1;var C3=A(()=>{m6();e1=new Map});import{nanoid as cH}from"nanoid";var cY=2000,iY,lY,l6=($,Z)=>({...lY,actions:{addMessage:(Y)=>{$((Q)=>({session:{...Q.session,messages:[...Q.session.messages,Y],error:null}}))},addUserMessage:(Y)=>{let Q={id:`user-${Date.now()}-${Math.random()}`,role:"user",content:Y,timestamp:Date.now()};Z().session.actions.addMessage(Q)},addAssistantMessage:(Y,Q)=>{let X={id:`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:Y,timestamp:Date.now(),thinkingContent:Q};Z().session.actions.addMessage(X)},addAssistantMessageAndClearThinking:(Y)=>{let Q=Z().session.currentThinkingContent,X={id:`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:Y,timestamp:Date.now(),thinkingContent:Q||void 0};$((J)=>({session:{...J.session,messages:[...J.session.messages,X],currentThinkingContent:null,error:null}}))},addToolMessage:(Y,Q)=>{let X={id:`tool-${Date.now()}-${Math.random()}`,role:"tool",content:Y,timestamp:Date.now(),metadata:Q};Z().session.actions.addMessage(X)},setCompacting:(Y)=>{$((Q)=>({session:{...Q.session,isCompacting:Y}}))},setCommand:(Y)=>{$((Q)=>({session:{...Q.session,currentCommand:Y}}))},setError:(Y)=>{$((Q)=>({session:{...Q.session,error:Y}}))},clearMessages:()=>{f8(),$((Y)=>({session:{...Y.session,messages:[],error:null,clearCount:Y.session.clearCount+1}}))},resetSession:()=>{f8(),$((Y)=>({session:{...Y.session,...lY,sessionId:Y.session.sessionId,isActive:!0}}))},restoreSession:(Y,Q)=>{f8(),$((X)=>({session:{...X.session,sessionId:Y,messages:Q,error:null,isActive:!0}}))},updateTokenUsage:(Y)=>{$((Q)=>({session:{...Q.session,tokenUsage:{...Q.session.tokenUsage,...Y}}}))},resetTokenUsage:()=>{$((Y)=>({session:{...Y.session,tokenUsage:{...iY}}}))},setCurrentThinkingContent:(Y)=>{if(Z().session.currentThinkingContent===Y)return;$((Q)=>({session:{...Q.session,currentThinkingContent:Y}}))},appendThinkingContent:(Y)=>{$((Q)=>({session:{...Q.session,currentThinkingContent:(Q.session.currentThinkingContent||"")+Y}}))},setThinkingExpanded:(Y)=>{$((Q)=>({session:{...Q.session,thinkingExpanded:Y}}))},toggleThinkingExpanded:()=>{$((Y)=>({session:{...Y.session,thinkingExpanded:!Y.session.thinkingExpanded}}))},setHistoryExpanded:(Y)=>{$((Q)=>({session:{...Q.session,historyExpanded:Y}}))},toggleHistoryExpanded:()=>{$((Y)=>({session:{...Y.session,historyExpanded:!Y.session.historyExpanded}}))},setExpandedMessageCount:(Y)=>{$((Q)=>({session:{...Q.session,expandedMessageCount:Y}}))},incrementClearCount:()=>{$((Y)=>({session:{...Y.session,clearCount:Y.session.clearCount+1}}))},startStreamingAssistantMessage:()=>{let Y=`assistant-${Date.now()}-${Math.random()}`,Q={id:Y,role:"assistant",content:"",timestamp:Date.now()};return $((X)=>({session:{...X.session,messages:[...X.session.messages,Q],currentStreamingMessageId:Y,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,error:null}})),Y},appendAssistantContent:(Y)=>{let Q=Z().session.currentStreamingMessageId,X=Q??`assistant-${Date.now()}-${Math.random()}`;return $((J)=>{let G=(w)=>w.endsWith("\r")?w.slice(0,-1):w,K=Q?J.session.currentStreamingChunks:[],q=Q?J.session.currentStreamingLines:[],W=Q?J.session.currentStreamingTail:"",U=Q?J.session.currentStreamingLineCount:0,H=Q?J.session.currentStreamingVersion:0,O=(W+Y).split(`
36
- `),z=O.slice(0,-1).map(G),_=G(O[O.length-1]??""),B=[...K,Y],L=q;if(z.length>0){if(L=[...q,...z],L.length>cY){let w=L.length-cY;L=L.slice(w)}}return{session:{...J.session,currentStreamingMessageId:X,currentStreamingChunks:B,currentStreamingLines:L,currentStreamingTail:_,currentStreamingLineCount:U+z.length,currentStreamingVersion:H+1,error:null}}}),X},finalizeStreamingMessage:(Y,Q)=>{$((X)=>{let J=X.session.currentStreamingMessageId,K=X.session.currentStreamingChunks.join("")+(Y||""),q=(X.session.currentThinkingContent||"")+(Q||"");if(K.length>0){let W={id:J||`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:K,timestamp:Date.now(),thinkingContent:q||void 0};return{session:{...X.session,messages:[...X.session.messages,W],currentStreamingMessageId:null,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,currentThinkingContent:null,finalizingStreamingMessageId:W.id}}}return{session:{...X.session,currentStreamingMessageId:null,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,currentThinkingContent:null,finalizingStreamingMessageId:null}}})},clearFinalizingStreamingMessageId:()=>{$((Y)=>({session:{...Y.session,finalizingStreamingMessageId:null}}))}}});var aY=A(()=>{C3();iY={inputTokens:0,outputTokens:0,totalTokens:0,maxContextTokens:200000},lY={sessionId:cH(),messages:[],isCompacting:!1,currentCommand:null,error:null,isActive:!0,tokenUsage:{...iY},currentThinkingContent:null,thinkingExpanded:!1,clearCount:0,historyExpanded:!1,expandedMessageCount:100,currentStreamingMessageId:null,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,finalizingStreamingMessageId:null}});var rY,o2,s2,h1,v0,nY;var D1=A(()=>{rY={proposal:"proposal.md",spec:"spec.md",requirements:"requirements.md",design:"design.md",tasks:"tasks.md",meta:".meta.json"},o2={SPECS:"specs",CHANGES:"changes",ARCHIVE:"archive",STEERING:"steering",SPEC_DELTA:"specs"},s2={CONSTITUTION:"constitution.md",PRODUCT:"product.md",TECH:"tech.md",STRUCTURE:"structure.md"},h1={init:["requirements"],requirements:["design","tasks"],design:["tasks"],tasks:["implementation"],implementation:["done","tasks"],done:[]},v0={init:"初始化",requirements:"需求定义",design:"架构设计",tasks:"任务分解",implementation:"实现中",done:"已完成"},nY={init:"proposal",requirements:"requirements",design:"design",tasks:"tasks",implementation:"tasks",done:null}});import{promises as E0}from"node:fs";import*as h$ from"node:path";import{fileURLToPath as lH}from"node:url";import{nanoid as iH}from"nanoid";var aH,rH,oY,t2;var i6=A(()=>{D1();aH=lH(import.meta.url),rH=h$.dirname(aH),oY=h$.join(rH,"templates");t2=class t2{workspaceRoot;bladeDir;constructor($){this.workspaceRoot=$,this.bladeDir=h$.join($,".blade")}getSpecsDir(){return h$.join(this.bladeDir,o2.SPECS)}getChangesDir(){return h$.join(this.bladeDir,o2.CHANGES)}getArchiveDir(){return h$.join(this.bladeDir,o2.ARCHIVE)}getSteeringDir(){return h$.join(this.bladeDir,o2.STEERING)}getChangePath($){return h$.join(this.getChangesDir(),$)}getChangeFilePath($,Z){return h$.join(this.getChangePath($),rY[Z])}async initializeDirectories(){await E0.mkdir(this.getChangesDir(),{recursive:!0,mode:493})}async createChangeDir($){let Z=this.getChangePath($);return await E0.mkdir(Z,{recursive:!0,mode:493}),await E0.mkdir(h$.join(Z,o2.SPEC_DELTA),{recursive:!0,mode:493}),Z}async readFile($){try{return await E0.readFile($,"utf-8")}catch(Z){if(Z.code==="ENOENT")return null;throw Z}}async writeFile($,Z){let Y=h$.dirname($);await E0.mkdir(Y,{recursive:!0,mode:493}),await E0.writeFile($,Z,"utf-8")}async fileExists($){try{return await E0.access($),!0}catch{return!1}}async dirExists($){try{return(await E0.stat($)).isDirectory()}catch{return!1}}createMetadata($,Z){let Y=new Date().toISOString();return{id:iH(),name:$,description:Z,phase:"init",createdAt:Y,updatedAt:Y,tasks:[]}}async readMetadata($){let Z=this.getChangeFilePath($,"meta"),Y=await this.readFile(Z);if(!Y)return null;try{return JSON.parse(Y)}catch{return null}}async writeMetadata($,Z){let Y=this.getChangeFilePath($,"meta");Z.updatedAt=new Date().toISOString(),await this.writeFile(Y,JSON.stringify(Z,null,2))}async updatePhase($,Z){let Y=await this.readMetadata($);if(!Y)return null;return Y.phase=Z,await this.writeMetadata($,Y),Y}async readSpecFile($,Z){let Y=this.getChangeFilePath($,Z);return this.readFile(Y)}async writeSpecFile($,Z,Y){let Q=this.getChangeFilePath($,Z);await this.writeFile(Q,Y);let X=await this.readMetadata($);if(X)await this.writeMetadata($,X)}async getPhaseContent($,Z){let Y=nY[Z];if(!Y)return null;return this.readSpecFile($,Y)}async readSteeringContext(){let $=this.getSteeringDir(),[Z,Y,Q,X]=await Promise.all([this.readFile(h$.join($,s2.CONSTITUTION)),this.readFile(h$.join($,s2.PRODUCT)),this.readFile(h$.join($,s2.TECH)),this.readFile(h$.join($,s2.STRUCTURE))]);return{constitution:Z||void 0,product:Y||void 0,tech:Q||void 0,structure:X||void 0}}async writeSteeringFile($,Z){let Y=h$.join(this.getSteeringDir(),s2[$]);await this.writeFile(Y,Z)}async hasSteeringDocs(){let $=this.getSteeringDir();if(!await this.dirExists($))return!1;return(await E0.readdir($)).length>0}async listActiveChanges(){let $=this.getChangesDir();if(!await this.dirExists($))return[];return(await E0.readdir($,{withFileTypes:!0})).filter((Y)=>Y.isDirectory()).map((Y)=>Y.name)}async listArchivedChanges(){let $=this.getArchiveDir();if(!await this.dirExists($))return[];return(await E0.readdir($,{withFileTypes:!0})).filter((Y)=>Y.isDirectory()).map((Y)=>Y.name)}async changeExists($){return this.dirExists(this.getChangePath($))}async archiveChange($){let Z=this.getChangePath($),Y=h$.join(this.getArchiveDir(),$);await E0.mkdir(h$.dirname(Y),{recursive:!0,mode:493}),await E0.rename(Z,Y)}async restoreChange($){let Z=h$.join(this.getArchiveDir(),$),Y=this.getChangePath($);await E0.rename(Z,Y)}async listSpecDomains(){let $=this.getSpecsDir();if(!await this.dirExists($))return[];return(await E0.readdir($,{withFileTypes:!0})).filter((Y)=>Y.isDirectory()).map((Y)=>Y.name)}async readAuthorativeSpec($){let Z=h$.join(this.getSpecsDir(),$,"spec.md");return this.readFile(Z)}async writeAuthorativeSpec($,Z){let Y=h$.join(this.getSpecsDir(),$,"spec.md");await this.writeFile(Y,Z)}async mergeSpecDeltas($){let Z=h$.join(this.getChangePath($),o2.SPEC_DELTA);if(!await this.dirExists(Z))return[];let Y=[],Q=await E0.readdir(Z,{withFileTypes:!0});for(let X of Q){if(!X.isDirectory())continue;let J=h$.join(Z,X.name,"spec.md"),G=await this.readFile(J);if(G){let K=await this.readAuthorativeSpec(X.name),q=K?`${K}
35
+ `)}),Z.state.inDiff=!1,Z.state.diffContent=[];while(Z.blocks.length>0&&Z.blocks[Z.blocks.length-1].type==="empty")Z.blocks.pop();Z.finalized=!0}function dY($){let Z=e1.get($);if(!Z||!Z.finalized)return null;return Z.blocks}function c6($){let Z=e1.get($);if(!Z)return null;return Z.blocks}function gH($){let Z=e1.get($);if(!Z)return null;let Y=[],Q=Z.state;if(Q.inDiff)Y.push("<<<DIFF>>>"),Y.push(...Q.diffContent);else if(Q.inCodeBlock){let X=Q.codeBlockLang?`\`\`\`${Q.codeBlockLang}`:"```";Y.push(X),Y.push(...Q.codeBlockContent)}else if(Q.inTable){if(Q.tableHeaders.length>0){Y.push(`| ${Q.tableHeaders.join(" | ")} |`),Y.push(`| ${Q.tableHeaders.map(()=>"---").join(" | ")} |`);for(let X of Q.tableRows)Y.push(`| ${X.join(" | ")} |`)}}else if(Q.pendingTableHeader)Y.push(Q.pendingTableHeader);if(Z.pendingLine)Y.push(Z.pendingLine);return Y.length>0?Y:null}function uY($){let Z=e1.get($);if(!Z)return null;let Y="text";if(Z.state.inDiff)Y="diff";else if(Z.state.inCodeBlock)Y="code";else if(Z.state.inTable||Z.state.pendingTableHeader)Y="table";let Q=gH($);if(!Q||Q.length===0)return null;return{lines:Q,mode:Y}}function gY($){e1.delete($)}function f3(){e1.clear()}var e1;var C8=A(()=>{m6();e1=new Map});import{nanoid as cH}from"nanoid";var cY=2000,iY,lY,l6=($,Z)=>({...lY,actions:{addMessage:(Y)=>{$((Q)=>({session:{...Q.session,messages:[...Q.session.messages,Y],error:null}}))},addUserMessage:(Y)=>{let Q={id:`user-${Date.now()}-${Math.random()}`,role:"user",content:Y,timestamp:Date.now()};Z().session.actions.addMessage(Q)},addAssistantMessage:(Y,Q)=>{let X={id:`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:Y,timestamp:Date.now(),thinkingContent:Q};Z().session.actions.addMessage(X)},addAssistantMessageAndClearThinking:(Y)=>{let Q=Z().session.currentThinkingContent,X={id:`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:Y,timestamp:Date.now(),thinkingContent:Q||void 0};$((J)=>({session:{...J.session,messages:[...J.session.messages,X],currentThinkingContent:null,error:null}}))},addToolMessage:(Y,Q)=>{let X={id:`tool-${Date.now()}-${Math.random()}`,role:"tool",content:Y,timestamp:Date.now(),metadata:Q};Z().session.actions.addMessage(X)},setCompacting:(Y)=>{$((Q)=>({session:{...Q.session,isCompacting:Y}}))},setCommand:(Y)=>{$((Q)=>({session:{...Q.session,currentCommand:Y}}))},setError:(Y)=>{$((Q)=>({session:{...Q.session,error:Y}}))},clearMessages:()=>{f3(),$((Y)=>({session:{...Y.session,messages:[],error:null,clearCount:Y.session.clearCount+1}}))},resetSession:()=>{f3(),$((Y)=>({session:{...Y.session,...lY,sessionId:Y.session.sessionId,isActive:!0}}))},restoreSession:(Y,Q)=>{f3(),$((X)=>({session:{...X.session,sessionId:Y,messages:Q,error:null,isActive:!0}}))},updateTokenUsage:(Y)=>{$((Q)=>({session:{...Q.session,tokenUsage:{...Q.session.tokenUsage,...Y}}}))},resetTokenUsage:()=>{$((Y)=>({session:{...Y.session,tokenUsage:{...iY}}}))},setCurrentThinkingContent:(Y)=>{if(Z().session.currentThinkingContent===Y)return;$((Q)=>({session:{...Q.session,currentThinkingContent:Y}}))},appendThinkingContent:(Y)=>{$((Q)=>({session:{...Q.session,currentThinkingContent:(Q.session.currentThinkingContent||"")+Y}}))},setThinkingExpanded:(Y)=>{$((Q)=>({session:{...Q.session,thinkingExpanded:Y}}))},toggleThinkingExpanded:()=>{$((Y)=>({session:{...Y.session,thinkingExpanded:!Y.session.thinkingExpanded}}))},setHistoryExpanded:(Y)=>{$((Q)=>({session:{...Q.session,historyExpanded:Y}}))},toggleHistoryExpanded:()=>{$((Y)=>({session:{...Y.session,historyExpanded:!Y.session.historyExpanded}}))},setExpandedMessageCount:(Y)=>{$((Q)=>({session:{...Q.session,expandedMessageCount:Y}}))},incrementClearCount:()=>{$((Y)=>({session:{...Y.session,clearCount:Y.session.clearCount+1}}))},startStreamingAssistantMessage:()=>{let Y=`assistant-${Date.now()}-${Math.random()}`,Q={id:Y,role:"assistant",content:"",timestamp:Date.now()};return $((X)=>({session:{...X.session,messages:[...X.session.messages,Q],currentStreamingMessageId:Y,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,error:null}})),Y},appendAssistantContent:(Y)=>{let Q=Z().session.currentStreamingMessageId,X=Q??`assistant-${Date.now()}-${Math.random()}`;return $((J)=>{let G=(w)=>w.endsWith("\r")?w.slice(0,-1):w,K=Q?J.session.currentStreamingChunks:[],q=Q?J.session.currentStreamingLines:[],W=Q?J.session.currentStreamingTail:"",U=Q?J.session.currentStreamingLineCount:0,H=Q?J.session.currentStreamingVersion:0,O=(W+Y).split(`
36
+ `),z=O.slice(0,-1).map(G),_=G(O[O.length-1]??""),B=[...K,Y],L=q;if(z.length>0){if(L=[...q,...z],L.length>cY){let w=L.length-cY;L=L.slice(w)}}return{session:{...J.session,currentStreamingMessageId:X,currentStreamingChunks:B,currentStreamingLines:L,currentStreamingTail:_,currentStreamingLineCount:U+z.length,currentStreamingVersion:H+1,error:null}}}),X},finalizeStreamingMessage:(Y,Q)=>{$((X)=>{let J=X.session.currentStreamingMessageId,K=X.session.currentStreamingChunks.join("")+(Y||""),q=(X.session.currentThinkingContent||"")+(Q||"");if(K.length>0){let W={id:J||`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:K,timestamp:Date.now(),thinkingContent:q||void 0};return{session:{...X.session,messages:[...X.session.messages,W],currentStreamingMessageId:null,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,currentThinkingContent:null,finalizingStreamingMessageId:W.id}}}return{session:{...X.session,currentStreamingMessageId:null,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,currentThinkingContent:null,finalizingStreamingMessageId:null}}})},clearFinalizingStreamingMessageId:()=>{$((Y)=>({session:{...Y.session,finalizingStreamingMessageId:null}}))}}});var aY=A(()=>{C8();iY={inputTokens:0,outputTokens:0,totalTokens:0,maxContextTokens:200000},lY={sessionId:cH(),messages:[],isCompacting:!1,currentCommand:null,error:null,isActive:!0,tokenUsage:{...iY},currentThinkingContent:null,thinkingExpanded:!1,clearCount:0,historyExpanded:!1,expandedMessageCount:100,currentStreamingMessageId:null,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,finalizingStreamingMessageId:null}});var rY,o4,s4,h1,v0,nY;var D1=A(()=>{rY={proposal:"proposal.md",spec:"spec.md",requirements:"requirements.md",design:"design.md",tasks:"tasks.md",meta:".meta.json"},o4={SPECS:"specs",CHANGES:"changes",ARCHIVE:"archive",STEERING:"steering",SPEC_DELTA:"specs"},s4={CONSTITUTION:"constitution.md",PRODUCT:"product.md",TECH:"tech.md",STRUCTURE:"structure.md"},h1={init:["requirements"],requirements:["design","tasks"],design:["tasks"],tasks:["implementation"],implementation:["done","tasks"],done:[]},v0={init:"初始化",requirements:"需求定义",design:"架构设计",tasks:"任务分解",implementation:"实现中",done:"已完成"},nY={init:"proposal",requirements:"requirements",design:"design",tasks:"tasks",implementation:"tasks",done:null}});import{promises as E0}from"node:fs";import*as h$ from"node:path";import{fileURLToPath as lH}from"node:url";import{nanoid as iH}from"nanoid";var aH,rH,oY,t4;var i6=A(()=>{D1();aH=lH(import.meta.url),rH=h$.dirname(aH),oY=h$.join(rH,"templates");t4=class t4{workspaceRoot;bladeDir;constructor($){this.workspaceRoot=$,this.bladeDir=h$.join($,".blade")}getSpecsDir(){return h$.join(this.bladeDir,o4.SPECS)}getChangesDir(){return h$.join(this.bladeDir,o4.CHANGES)}getArchiveDir(){return h$.join(this.bladeDir,o4.ARCHIVE)}getSteeringDir(){return h$.join(this.bladeDir,o4.STEERING)}getChangePath($){return h$.join(this.getChangesDir(),$)}getChangeFilePath($,Z){return h$.join(this.getChangePath($),rY[Z])}async initializeDirectories(){await E0.mkdir(this.getChangesDir(),{recursive:!0,mode:493})}async createChangeDir($){let Z=this.getChangePath($);return await E0.mkdir(Z,{recursive:!0,mode:493}),await E0.mkdir(h$.join(Z,o4.SPEC_DELTA),{recursive:!0,mode:493}),Z}async readFile($){try{return await E0.readFile($,"utf-8")}catch(Z){if(Z.code==="ENOENT")return null;throw Z}}async writeFile($,Z){let Y=h$.dirname($);await E0.mkdir(Y,{recursive:!0,mode:493}),await E0.writeFile($,Z,"utf-8")}async fileExists($){try{return await E0.access($),!0}catch{return!1}}async dirExists($){try{return(await E0.stat($)).isDirectory()}catch{return!1}}createMetadata($,Z){let Y=new Date().toISOString();return{id:iH(),name:$,description:Z,phase:"init",createdAt:Y,updatedAt:Y,tasks:[]}}async readMetadata($){let Z=this.getChangeFilePath($,"meta"),Y=await this.readFile(Z);if(!Y)return null;try{return JSON.parse(Y)}catch{return null}}async writeMetadata($,Z){let Y=this.getChangeFilePath($,"meta");Z.updatedAt=new Date().toISOString(),await this.writeFile(Y,JSON.stringify(Z,null,2))}async updatePhase($,Z){let Y=await this.readMetadata($);if(!Y)return null;return Y.phase=Z,await this.writeMetadata($,Y),Y}async readSpecFile($,Z){let Y=this.getChangeFilePath($,Z);return this.readFile(Y)}async writeSpecFile($,Z,Y){let Q=this.getChangeFilePath($,Z);await this.writeFile(Q,Y);let X=await this.readMetadata($);if(X)await this.writeMetadata($,X)}async getPhaseContent($,Z){let Y=nY[Z];if(!Y)return null;return this.readSpecFile($,Y)}async readSteeringContext(){let $=this.getSteeringDir(),[Z,Y,Q,X]=await Promise.all([this.readFile(h$.join($,s4.CONSTITUTION)),this.readFile(h$.join($,s4.PRODUCT)),this.readFile(h$.join($,s4.TECH)),this.readFile(h$.join($,s4.STRUCTURE))]);return{constitution:Z||void 0,product:Y||void 0,tech:Q||void 0,structure:X||void 0}}async writeSteeringFile($,Z){let Y=h$.join(this.getSteeringDir(),s4[$]);await this.writeFile(Y,Z)}async hasSteeringDocs(){let $=this.getSteeringDir();if(!await this.dirExists($))return!1;return(await E0.readdir($)).length>0}async listActiveChanges(){let $=this.getChangesDir();if(!await this.dirExists($))return[];return(await E0.readdir($,{withFileTypes:!0})).filter((Y)=>Y.isDirectory()).map((Y)=>Y.name)}async listArchivedChanges(){let $=this.getArchiveDir();if(!await this.dirExists($))return[];return(await E0.readdir($,{withFileTypes:!0})).filter((Y)=>Y.isDirectory()).map((Y)=>Y.name)}async changeExists($){return this.dirExists(this.getChangePath($))}async archiveChange($){let Z=this.getChangePath($),Y=h$.join(this.getArchiveDir(),$);await E0.mkdir(h$.dirname(Y),{recursive:!0,mode:493}),await E0.rename(Z,Y)}async restoreChange($){let Z=h$.join(this.getArchiveDir(),$),Y=this.getChangePath($);await E0.rename(Z,Y)}async listSpecDomains(){let $=this.getSpecsDir();if(!await this.dirExists($))return[];return(await E0.readdir($,{withFileTypes:!0})).filter((Y)=>Y.isDirectory()).map((Y)=>Y.name)}async readAuthorativeSpec($){let Z=h$.join(this.getSpecsDir(),$,"spec.md");return this.readFile(Z)}async writeAuthorativeSpec($,Z){let Y=h$.join(this.getSpecsDir(),$,"spec.md");await this.writeFile(Y,Z)}async mergeSpecDeltas($){let Z=h$.join(this.getChangePath($),o4.SPEC_DELTA);if(!await this.dirExists(Z))return[];let Y=[],Q=await E0.readdir(Z,{withFileTypes:!0});for(let X of Q){if(!X.isDirectory())continue;let J=h$.join(Z,X.name,"spec.md"),G=await this.readFile(J);if(G){let K=await this.readAuthorativeSpec(X.name),q=K?`${K}
37
37
 
38
38
  ---
39
39
 
40
40
  <!-- Merged from ${$} -->
41
41
 
42
- ${G}`:G;await this.writeAuthorativeSpec(X.name,q),Y.push(X.name)}}return Y}static TEMPLATE_NAMES={proposal:"proposal.md.template",spec:"spec.md.template",requirements:"requirements.md.template",design:"design.md.template",tasks:"tasks.md.template",meta:""};static STEERING_TEMPLATE_NAMES={CONSTITUTION:"steering/constitution.md.template",PRODUCT:"steering/product.md.template",TECH:"steering/tech.md.template",STRUCTURE:"steering/structure.md.template"};async readTemplate($){let Z=t2.TEMPLATE_NAMES[$];if(!Z)return null;let Y=h$.join(oY,Z);return this.readFile(Y)}async readSteeringTemplate($){let Z=t2.STEERING_TEMPLATE_NAMES[$],Y=h$.join(oY,Z);return this.readFile(Y)}fillTemplate($,Z){let Y=$;for(let[Q,X]of Object.entries(Z))Y=Y.replace(new RegExp(`\\{\\{${Q}\\}\\}`,"g"),X);return Y}async createFromTemplate($,Z,Y){let Q=await this.readTemplate(Z);if(!Q)return null;let X=this.fillTemplate(Q,{name:$,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString(),...Y});return await this.writeSpecFile($,Z,X),X}async createSteeringFromTemplate($,Z={}){let Y=await this.readSteeringTemplate($);if(!Y)return null;let Q=this.fillTemplate(Y,{createdAt:new Date().toISOString(),...Z});return await this.writeSteeringFile($,Q),Q}async initializeSteeringDocs(){let $=[],Z=this.getSteeringDir();for(let[Y,Q]of Object.entries(s2)){let X=h$.join(Z,Q);if(!await this.fileExists(X))await this.createSteeringFromTemplate(Y),$.push(Q)}return $}}});import{nanoid as nH}from"nanoid";class M0{static instance=null;fileManager=null;workspaceRoot=null;constructor(){}static getInstance(){if(!M0.instance)M0.instance=new M0;return M0.instance}static resetInstance(){M0.instance=null}async initialize($){if(this.workspaceRoot===$&&this.fileManager)return;this.workspaceRoot=$,this.fileManager=new t2($),await this.fileManager.initializeDirectories()}getFileManager(){if(!this.fileManager)throw Error("SpecService not initialized. Call initialize() first.");return this.fileManager}async readSteeringContext(){return this.getFileManager().readSteeringContext()}async readSpecMetadata($){return this.getFileManager().readMetadata($)}async specExists($){return this.getFileManager().changeExists($)}getSpecPath($){return this.getFileManager().getChangePath($)}async createSpec($,Z){let Y=this.getFileManager();if(await Y.changeExists($))return{success:!1,message:`Spec "${$}" already exists`,error:"SPEC_EXISTS"};let Q=await Y.createChangeDir($),X=Y.createMetadata($,Z);await Y.writeMetadata($,X);let J=this.generateProposalTemplate($,Z);return await Y.writeSpecFile($,"proposal",J),{success:!0,message:`Spec "${$}" created successfully`,data:{spec:X,path:Q}}}async loadSpec($){let Z=this.getFileManager(),Y=await Z.readMetadata($);if(!Y)return{success:!1,message:`Spec "${$}" not found`,error:"SPEC_NOT_FOUND"};let Q=Z.getChangePath($);return{success:!0,message:`Spec "${$}" loaded successfully`,data:{spec:Y,path:Q}}}canTransitionPhase($,Z){return h1[$].includes(Z)}getAllowedTransitions($){return h1[$]}async updatePhase($,Z){return this.getFileManager().updatePhase($,Z)}createTask($,Z,Y){return{id:nH(8),title:$,description:Z,status:"pending",dependencies:Y?.dependencies||[],affectedFiles:Y?.affectedFiles||[],complexity:Y?.complexity||"medium"}}async saveMetadata($,Z){await this.getFileManager().writeMetadata($,Z)}getNextTask($){return $.find((Z)=>{if(Z.status!=="pending")return!1;return Z.dependencies.every((Y)=>{return $.find((X)=>X.id===Y)?.status==="completed"})})||null}getTaskProgress($){if($.length===0)return{total:0,completed:0,percentage:0};let Z=$.length,Y=$.filter((X)=>X.status==="completed").length,Q=Math.round(Y/Z*100);return{total:Z,completed:Y,percentage:Q}}async listActiveSpecs(){return this.getFileManager().listActiveChanges()}async listArchivedSpecs(){return this.getFileManager().listArchivedChanges()}async archiveSpec($){let Z=this.getFileManager();return await Z.mergeSpecDeltas($),await Z.updatePhase($,"done"),await Z.archiveChange($),{success:!0,message:`Spec "${$}" archived successfully`}}async validateSpec($){let Z=this.getFileManager(),Y=[],Q=[],[X,J,G,K,q]=await Promise.all([Z.readSpecFile($.name,"proposal"),Z.readSpecFile($.name,"spec"),Z.readSpecFile($.name,"requirements"),Z.readSpecFile($.name,"design"),Z.readSpecFile($.name,"tasks")]),W={proposal:!!X,spec:!!J,requirements:!!G,design:!!K,tasks:!!q};if($.phase==="requirements"&&!W.requirements)Y.push({severity:"warning",file:"requirements",message:"Requirements document is missing"}),Q.push("Generate requirements using EARS format");if($.phase==="design"&&!W.design)Y.push({severity:"warning",file:"design",message:"Design document is missing"}),Q.push("Create architecture diagrams and API contracts");if($.phase==="tasks"&&$.tasks.length===0)Y.push({severity:"warning",file:"tasks",message:"No tasks defined"}),Q.push("Break down the spec into atomic tasks");if($.phase==="implementation"){let U=this.getTaskProgress($.tasks);if(U.completed<U.total)Y.push({severity:"info",file:"tasks",message:`${U.total-U.completed} tasks remaining`})}return{valid:Y.filter((U)=>U.severity==="error").length===0,phase:$.phase,completeness:W,issues:Y,suggestions:Q}}generateProposalTemplate($,Z){return`# ${$}
42
+ ${G}`:G;await this.writeAuthorativeSpec(X.name,q),Y.push(X.name)}}return Y}static TEMPLATE_NAMES={proposal:"proposal.md.template",spec:"spec.md.template",requirements:"requirements.md.template",design:"design.md.template",tasks:"tasks.md.template",meta:""};static STEERING_TEMPLATE_NAMES={CONSTITUTION:"steering/constitution.md.template",PRODUCT:"steering/product.md.template",TECH:"steering/tech.md.template",STRUCTURE:"steering/structure.md.template"};async readTemplate($){let Z=t4.TEMPLATE_NAMES[$];if(!Z)return null;let Y=h$.join(oY,Z);return this.readFile(Y)}async readSteeringTemplate($){let Z=t4.STEERING_TEMPLATE_NAMES[$],Y=h$.join(oY,Z);return this.readFile(Y)}fillTemplate($,Z){let Y=$;for(let[Q,X]of Object.entries(Z))Y=Y.replace(new RegExp(`\\{\\{${Q}\\}\\}`,"g"),X);return Y}async createFromTemplate($,Z,Y){let Q=await this.readTemplate(Z);if(!Q)return null;let X=this.fillTemplate(Q,{name:$,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString(),...Y});return await this.writeSpecFile($,Z,X),X}async createSteeringFromTemplate($,Z={}){let Y=await this.readSteeringTemplate($);if(!Y)return null;let Q=this.fillTemplate(Y,{createdAt:new Date().toISOString(),...Z});return await this.writeSteeringFile($,Q),Q}async initializeSteeringDocs(){let $=[],Z=this.getSteeringDir();for(let[Y,Q]of Object.entries(s4)){let X=h$.join(Z,Q);if(!await this.fileExists(X))await this.createSteeringFromTemplate(Y),$.push(Q)}return $}}});import{nanoid as nH}from"nanoid";class M0{static instance=null;fileManager=null;workspaceRoot=null;constructor(){}static getInstance(){if(!M0.instance)M0.instance=new M0;return M0.instance}static resetInstance(){M0.instance=null}async initialize($){if(this.workspaceRoot===$&&this.fileManager)return;this.workspaceRoot=$,this.fileManager=new t4($),await this.fileManager.initializeDirectories()}getFileManager(){if(!this.fileManager)throw Error("SpecService not initialized. Call initialize() first.");return this.fileManager}async readSteeringContext(){return this.getFileManager().readSteeringContext()}async readSpecMetadata($){return this.getFileManager().readMetadata($)}async specExists($){return this.getFileManager().changeExists($)}getSpecPath($){return this.getFileManager().getChangePath($)}async createSpec($,Z){let Y=this.getFileManager();if(await Y.changeExists($))return{success:!1,message:`Spec "${$}" already exists`,error:"SPEC_EXISTS"};let Q=await Y.createChangeDir($),X=Y.createMetadata($,Z);await Y.writeMetadata($,X);let J=this.generateProposalTemplate($,Z);return await Y.writeSpecFile($,"proposal",J),{success:!0,message:`Spec "${$}" created successfully`,data:{spec:X,path:Q}}}async loadSpec($){let Z=this.getFileManager(),Y=await Z.readMetadata($);if(!Y)return{success:!1,message:`Spec "${$}" not found`,error:"SPEC_NOT_FOUND"};let Q=Z.getChangePath($);return{success:!0,message:`Spec "${$}" loaded successfully`,data:{spec:Y,path:Q}}}canTransitionPhase($,Z){return h1[$].includes(Z)}getAllowedTransitions($){return h1[$]}async updatePhase($,Z){return this.getFileManager().updatePhase($,Z)}createTask($,Z,Y){return{id:nH(8),title:$,description:Z,status:"pending",dependencies:Y?.dependencies||[],affectedFiles:Y?.affectedFiles||[],complexity:Y?.complexity||"medium"}}async saveMetadata($,Z){await this.getFileManager().writeMetadata($,Z)}getNextTask($){return $.find((Z)=>{if(Z.status!=="pending")return!1;return Z.dependencies.every((Y)=>{return $.find((X)=>X.id===Y)?.status==="completed"})})||null}getTaskProgress($){if($.length===0)return{total:0,completed:0,percentage:0};let Z=$.length,Y=$.filter((X)=>X.status==="completed").length,Q=Math.round(Y/Z*100);return{total:Z,completed:Y,percentage:Q}}async listActiveSpecs(){return this.getFileManager().listActiveChanges()}async listArchivedSpecs(){return this.getFileManager().listArchivedChanges()}async archiveSpec($){let Z=this.getFileManager();return await Z.mergeSpecDeltas($),await Z.updatePhase($,"done"),await Z.archiveChange($),{success:!0,message:`Spec "${$}" archived successfully`}}async validateSpec($){let Z=this.getFileManager(),Y=[],Q=[],[X,J,G,K,q]=await Promise.all([Z.readSpecFile($.name,"proposal"),Z.readSpecFile($.name,"spec"),Z.readSpecFile($.name,"requirements"),Z.readSpecFile($.name,"design"),Z.readSpecFile($.name,"tasks")]),W={proposal:!!X,spec:!!J,requirements:!!G,design:!!K,tasks:!!q};if($.phase==="requirements"&&!W.requirements)Y.push({severity:"warning",file:"requirements",message:"Requirements document is missing"}),Q.push("Generate requirements using EARS format");if($.phase==="design"&&!W.design)Y.push({severity:"warning",file:"design",message:"Design document is missing"}),Q.push("Create architecture diagrams and API contracts");if($.phase==="tasks"&&$.tasks.length===0)Y.push({severity:"warning",file:"tasks",message:"No tasks defined"}),Q.push("Break down the spec into atomic tasks");if($.phase==="implementation"){let U=this.getTaskProgress($.tasks);if(U.completed<U.total)Y.push({severity:"info",file:"tasks",message:`${U.total-U.completed} tasks remaining`})}return{valid:Y.filter((U)=>U.severity==="error").length===0,phase:$.phase,completeness:W,issues:Y,suggestions:Q}}generateProposalTemplate($,Z){return`# ${$}
43
43
 
44
44
  ## Summary
45
45
 
@@ -85,16 +85,16 @@ ${Y.structure}`);return Q.length>0?Q.join(`
85
85
 
86
86
  ---
87
87
 
88
- `):null},setError:(Y)=>{$((Q)=>({spec:{...Q.spec,error:Y}}))},setLoading:(Y)=>{$((Q)=>({spec:{...Q.spec,isLoading:Y}}))},reset:()=>{$((Y)=>({spec:{...eY,actions:Y.spec.actions}}))}}});var $Q=A(()=>{U0();O$();sY();D1();tY=l("Spec"),eY={currentSpec:null,specPath:null,isActive:!1,steeringContext:null,recentSpecs:[],isLoading:!1,error:null,workspaceRoot:null}});var ZQ=A(()=>{SY();kY();fY();hY();aY();$Q()});import{nanoid as oH}from"nanoid";import{devtools as sH,subscribeWithSelector as tH}from"zustand/middleware";import{createStore as eH}from"zustand/vanilla";async function h8(){if(H0()!==null)return;if(k4)return k4;return k4=(async()=>{try{let Y=await u0.getInstance().initialize();q$().config.actions.setConfig(Y)}catch(Z){throw k4=null,Error(`❌ Store 未初始化且无法自动初始化
88
+ `):null},setError:(Y)=>{$((Q)=>({spec:{...Q.spec,error:Y}}))},setLoading:(Y)=>{$((Q)=>({spec:{...Q.spec,isLoading:Y}}))},reset:()=>{$((Y)=>({spec:{...eY,actions:Y.spec.actions}}))}}});var $Q=A(()=>{U0();O$();sY();D1();tY=l("Spec"),eY={currentSpec:null,specPath:null,isActive:!1,steeringContext:null,recentSpecs:[],isLoading:!1,error:null,workspaceRoot:null}});var ZQ=A(()=>{SY();kY();fY();hY();aY();$Q()});import{nanoid as oH}from"nanoid";import{devtools as sH,subscribeWithSelector as tH}from"zustand/middleware";import{createStore as eH}from"zustand/vanilla";async function h3(){if(H0()!==null)return;if(k2)return k2;return k2=(async()=>{try{let Y=await u0.getInstance().initialize();q$().config.actions.setConfig(Y)}catch(Z){throw k2=null,Error(`❌ Store 未初始化且无法自动初始化
89
89
 
90
90
  `+`原因: ${Z instanceof Error?Z.message:"未知错误"}
91
91
 
92
92
  `+`请确保:
93
93
  `+`1. 配置文件格式正确 (~/.blade/config.json)
94
94
  `+`2. 运行 blade 进行首次配置
95
- `+"3. 配置文件权限正确")}finally{k4=null}})(),k4}var f4,q$=()=>f4.getState(),_$=()=>q$().session.actions,$2=()=>q$().app.actions,YQ=()=>q$().session.messages,H0=()=>q$().config.config,k4=null,S3=()=>q$().config.config?.models??[],h4=()=>{let $=H0();if(!$)return;let Z=$.currentModelId;return $.models.find((Q)=>Q.id===Z)??$.models[0]},W1=()=>q$().config.config?.mcpServers??{},QQ=()=>q$().app.thinkingModeEnabled,x$=()=>({setPermissionMode:async($)=>{q$().config.actions.updateConfig({permissionMode:$})},setTheme:async($,Z={})=>{try{g0.setTheme($)}catch{return}q$().config.actions.updateConfig({theme:$}),await C0().save({theme:$},{scope:"global",...Z})},setLanguage:async($,Z={})=>{q$().config.actions.updateConfig({language:$}),await C0().save({language:$},{scope:"global",...Z})},setDebug:async($,Z={})=>{q$().config.actions.updateConfig({debug:$}),await C0().save({debug:$},{scope:"global",...Z})},setTemperature:async($,Z={})=>{q$().config.actions.updateConfig({temperature:$}),await C0().save({temperature:$},{scope:"global",...Z})},updateConfig:async($,Z={})=>{let Y=H0();if(!Y)throw Error("Config not initialized");let Q={...Y};q$().config.actions.updateConfig($);try{await C0().save($,Z)}catch(X){throw q$().config.actions.setConfig(Q),X}},flush:async()=>{await C0().flush()},appendPermissionAllowRule:async($,Z={})=>{let Y=H0();if(!Y)throw Error("Config not initialized");let Q=Y.permissions?.allow||[];if(!Q.includes($)){let X=[...Q,$];q$().config.actions.updateConfig({permissions:{...Y.permissions,allow:X}})}await C0().appendPermissionRule($,Z)},appendLocalPermissionAllowRule:async($,Z={})=>{let Y=H0();if(!Y)throw Error("Config not initialized");let Q=Y.permissions?.allow||[];if(!Q.includes($)){let X=[...Q,$];q$().config.actions.updateConfig({permissions:{...Y.permissions,allow:X}})}await C0().appendLocalPermissionRule($,Z)},setCurrentModel:async($,Z={})=>{let Y=H0();if(!Y)throw Error("Config not initialized");if(!Y.models.find((X)=>X.id===$))throw Error(`Model not found: ${$}`);q$().config.actions.updateConfig({currentModelId:$}),await C0().save({currentModelId:$},{scope:"global",...Z})},addModel:async($,Z={})=>{let Y=H0();if(!Y)throw Error("Config not initialized");let Q="id"in $?$:{id:oH(),...$},J={models:[...Y.models,Q]};if(Y.models.length===0)J.currentModelId=Q.id;return q$().config.actions.updateConfig(J),await C0().save(J,{scope:"global",...Z}),Q},updateModel:async($,Z,Y={})=>{let Q=H0();if(!Q)throw Error("Config not initialized");let X=Q.models.findIndex((G)=>G.id===$);if(X===-1)throw Error(`Model not found: ${$}`);let J=[...Q.models];J[X]={...J[X],...Z},q$().config.actions.updateConfig({models:J}),await C0().save({models:J},{scope:"global",...Y})},removeModel:async($,Z={})=>{let Y=H0();if(!Y)throw Error("Config not initialized");if(Y.models.length===1)throw Error("Cannot remove the only model");let Q=Y.models.filter((J)=>J.id!==$),X={models:Q};if(Y.currentModelId===$)X.currentModelId=Q[0].id;q$().config.actions.updateConfig(X),await C0().save(X,{scope:"global",...Z})},addMcpServer:async($,Z,Y={})=>{let Q=H0();if(!Q)throw Error("Config not initialized");let J={...Q.mcpServers??{},[$]:Z};q$().config.actions.updateConfig({mcpServers:J}),await C0().save({mcpServers:J},{scope:"project",...Y})},removeMcpServer:async($,Z={})=>{let Y=H0();if(!Y)throw Error("Config not initialized");let X={...Y.mcpServers??{}};delete X[$],q$().config.actions.updateConfig({mcpServers:X}),await C0().save({mcpServers:X},{scope:"project",...Z})}});var k$=A(()=>{S4();r2();ZQ();f4=eH()(sH(tH((...$)=>({session:l6(...$),app:f6(...$),config:x6(...$),focus:p6(...$),command:h6(...$),spec:a6(...$)})),{name:"BladeStore",enabled:!0}))});function WQ($){return $!==void 0&&typeof $.pattern==="string"&&typeof $.search_path==="string"}function UQ($){return $!==void 0&&$.kind==="edit"&&typeof $.matches_found==="number"}function k3($){return $==="readonly"}var w0=()=>{};class n6{toolName;params;context;aborted=!1;result;_internal={};constructor($,Z,Y){this.toolName=$;this.params=Z;this.context=Y}shouldAbort(){return this.aborted||(this.context.signal?.aborted??!1)}abort($,Z){this.aborted=!0,this.result={success:!1,llmContent:`Tool execution aborted: ${$||"Unknown reason"}`,displayContent:`执行已中止: ${$||"未知原因"}`,error:{type:"execution_error",message:$||"Execution aborted"},metadata:Z?.shouldExitLoop?{shouldExitLoop:!0}:void 0}}setResult($){this.result=$}getResult(){if(!this.result)throw Error("Tool execution result not set");return this.result}}var o6=A(()=>{w0()});var j0=A(()=>{o6();w0()});import{isPlainObject as $F}from"lodash-es";function f3($){if($===void 0)return"undefined";if(typeof $==="string")return $;try{let Z=JSON.stringify($);return Z===void 0?String($):Z}catch{return String($)}}function ZF($){let{code:Z}=$,Y=$,Q=Y.received;switch(Z){case"invalid_type":{let X=Y.expected;return`类型错误:期望 ${f3(X)},实际收到 ${f3(Q)}`}case"too_small":{let{minimum:X,inclusive:J}=Y,G=typeof Y.type==="string"?Y.type:void 0;if(G==="string"&&typeof X==="number")return`长度不能少于 ${X} 个字符`;if(G==="number"&&typeof X==="number")return`不能小于${J?"等于":""} ${X}`;if(G==="array"&&typeof X==="number")return`数组长度不能少于 ${X}`;return"值太小"}case"too_big":{let{maximum:X,inclusive:J}=Y,G=typeof Y.type==="string"?Y.type:void 0;if(G==="string"&&typeof X==="number")return`长度不能超过 ${X} 个字符`;if(G==="number"&&typeof X==="number")return`不能大于${J?"等于":""} ${X}`;if(G==="array"&&typeof X==="number")return`数组长度不能超过 ${X}`;return"值太大"}case"invalid_string":{let X=Y.validation;if(X==="email")return"必须是有效的电子邮件地址";if(X==="url")return"必须是有效的 URL";if(X==="uuid")return"必须是有效的 UUID";if($F(X)){let J=X;if(typeof J.includes==="string")return`必须包含 "${J.includes}"`;if(typeof J.startsWith==="string")return`必须以 "${J.startsWith}" 开头`;if(typeof J.endsWith==="string")return`必须以 "${J.endsWith}" 结尾`}return"字符串格式不正确"}case"invalid_enum_value":{let X=Y.options;if(Array.isArray(X))return`必须是以下值之一:${X.map((J)=>f3(J)).join(", ")}`;return"必须是枚举允许的值之一"}case"invalid_literal":{let X=Y.expected;return`必须是字面量值:${f3(X)}`}case"unrecognized_keys":{let X=Y.keys;if(Array.isArray(X))return`包含未知的参数:${X.map((J)=>f3(J)).join(", ")}`;return"包含未知的参数"}case"invalid_union":return"不符合任何有效的类型定义";case"invalid_date":return"必须是有效的日期";case"custom":return $.message||"自定义验证失败";default:return $.message||"验证失败"}}function YF($){let Z=$.issues.map((Q)=>{let X=Q.path.join("."),J=ZF(Q),G=Q.received;return{field:X||"root",message:J,value:G}}),Y=Z.length===1?`参数验证失败 [${Z[0].field}]: ${Z[0].message}`:`参数验证失败 (${Z.length} 个错误):
95
+ `+"3. 配置文件权限正确")}finally{k2=null}})(),k2}var f2,q$=()=>f2.getState(),_$=()=>q$().session.actions,$4=()=>q$().app.actions,YQ=()=>q$().session.messages,H0=()=>q$().config.config,k2=null,S8=()=>q$().config.config?.models??[],h2=()=>{let $=H0();if(!$)return;let Z=$.currentModelId;return $.models.find((Q)=>Q.id===Z)??$.models[0]},W1=()=>q$().config.config?.mcpServers??{},QQ=()=>q$().app.thinkingModeEnabled,x$=()=>({setPermissionMode:async($)=>{q$().config.actions.updateConfig({permissionMode:$})},setTheme:async($,Z={})=>{try{g0.setTheme($)}catch{return}q$().config.actions.updateConfig({theme:$}),await C0().save({theme:$},{scope:"global",...Z})},setLanguage:async($,Z={})=>{q$().config.actions.updateConfig({language:$}),await C0().save({language:$},{scope:"global",...Z})},setDebug:async($,Z={})=>{q$().config.actions.updateConfig({debug:$}),await C0().save({debug:$},{scope:"global",...Z})},setTemperature:async($,Z={})=>{q$().config.actions.updateConfig({temperature:$}),await C0().save({temperature:$},{scope:"global",...Z})},updateConfig:async($,Z={})=>{let Y=H0();if(!Y)throw Error("Config not initialized");let Q={...Y};q$().config.actions.updateConfig($);try{await C0().save($,Z)}catch(X){throw q$().config.actions.setConfig(Q),X}},flush:async()=>{await C0().flush()},appendPermissionAllowRule:async($,Z={})=>{let Y=H0();if(!Y)throw Error("Config not initialized");let Q=Y.permissions?.allow||[];if(!Q.includes($)){let X=[...Q,$];q$().config.actions.updateConfig({permissions:{...Y.permissions,allow:X}})}await C0().appendPermissionRule($,Z)},appendLocalPermissionAllowRule:async($,Z={})=>{let Y=H0();if(!Y)throw Error("Config not initialized");let Q=Y.permissions?.allow||[];if(!Q.includes($)){let X=[...Q,$];q$().config.actions.updateConfig({permissions:{...Y.permissions,allow:X}})}await C0().appendLocalPermissionRule($,Z)},setCurrentModel:async($,Z={})=>{let Y=H0();if(!Y)throw Error("Config not initialized");if(!Y.models.find((X)=>X.id===$))throw Error(`Model not found: ${$}`);q$().config.actions.updateConfig({currentModelId:$}),await C0().save({currentModelId:$},{scope:"global",...Z})},addModel:async($,Z={})=>{let Y=H0();if(!Y)throw Error("Config not initialized");let Q="id"in $?$:{id:oH(),...$},J={models:[...Y.models,Q]};if(Y.models.length===0)J.currentModelId=Q.id;return q$().config.actions.updateConfig(J),await C0().save(J,{scope:"global",...Z}),Q},updateModel:async($,Z,Y={})=>{let Q=H0();if(!Q)throw Error("Config not initialized");let X=Q.models.findIndex((G)=>G.id===$);if(X===-1)throw Error(`Model not found: ${$}`);let J=[...Q.models];J[X]={...J[X],...Z},q$().config.actions.updateConfig({models:J}),await C0().save({models:J},{scope:"global",...Y})},removeModel:async($,Z={})=>{let Y=H0();if(!Y)throw Error("Config not initialized");if(Y.models.length===1)throw Error("Cannot remove the only model");let Q=Y.models.filter((J)=>J.id!==$),X={models:Q};if(Y.currentModelId===$)X.currentModelId=Q[0].id;q$().config.actions.updateConfig(X),await C0().save(X,{scope:"global",...Z})},addMcpServer:async($,Z,Y={})=>{let Q=H0();if(!Q)throw Error("Config not initialized");let J={...Q.mcpServers??{},[$]:Z};q$().config.actions.updateConfig({mcpServers:J}),await C0().save({mcpServers:J},{scope:"project",...Y})},removeMcpServer:async($,Z={})=>{let Y=H0();if(!Y)throw Error("Config not initialized");let X={...Y.mcpServers??{}};delete X[$],q$().config.actions.updateConfig({mcpServers:X}),await C0().save({mcpServers:X},{scope:"project",...Z})}});var k$=A(()=>{S2();r4();ZQ();f2=eH()(sH(tH((...$)=>({session:l6(...$),app:f6(...$),config:x6(...$),focus:p6(...$),command:h6(...$),spec:a6(...$)})),{name:"BladeStore",enabled:!0}))});function WQ($){return $!==void 0&&typeof $.pattern==="string"&&typeof $.search_path==="string"}function UQ($){return $!==void 0&&$.kind==="edit"&&typeof $.matches_found==="number"}function k8($){return $==="readonly"}var w0=()=>{};class n6{toolName;params;context;aborted=!1;result;_internal={};constructor($,Z,Y){this.toolName=$;this.params=Z;this.context=Y}shouldAbort(){return this.aborted||(this.context.signal?.aborted??!1)}abort($,Z){this.aborted=!0,this.result={success:!1,llmContent:`Tool execution aborted: ${$||"Unknown reason"}`,displayContent:`执行已中止: ${$||"未知原因"}`,error:{type:"execution_error",message:$||"Execution aborted"},metadata:Z?.shouldExitLoop?{shouldExitLoop:!0}:void 0}}setResult($){this.result=$}getResult(){if(!this.result)throw Error("Tool execution result not set");return this.result}}var o6=A(()=>{w0()});var j0=A(()=>{o6();w0()});import{isPlainObject as $F}from"lodash-es";function f8($){if($===void 0)return"undefined";if(typeof $==="string")return $;try{let Z=JSON.stringify($);return Z===void 0?String($):Z}catch{return String($)}}function ZF($){let{code:Z}=$,Y=$,Q=Y.received;switch(Z){case"invalid_type":{let X=Y.expected;return`类型错误:期望 ${f8(X)},实际收到 ${f8(Q)}`}case"too_small":{let{minimum:X,inclusive:J}=Y,G=typeof Y.type==="string"?Y.type:void 0;if(G==="string"&&typeof X==="number")return`长度不能少于 ${X} 个字符`;if(G==="number"&&typeof X==="number")return`不能小于${J?"等于":""} ${X}`;if(G==="array"&&typeof X==="number")return`数组长度不能少于 ${X}`;return"值太小"}case"too_big":{let{maximum:X,inclusive:J}=Y,G=typeof Y.type==="string"?Y.type:void 0;if(G==="string"&&typeof X==="number")return`长度不能超过 ${X} 个字符`;if(G==="number"&&typeof X==="number")return`不能大于${J?"等于":""} ${X}`;if(G==="array"&&typeof X==="number")return`数组长度不能超过 ${X}`;return"值太大"}case"invalid_string":{let X=Y.validation;if(X==="email")return"必须是有效的电子邮件地址";if(X==="url")return"必须是有效的 URL";if(X==="uuid")return"必须是有效的 UUID";if($F(X)){let J=X;if(typeof J.includes==="string")return`必须包含 "${J.includes}"`;if(typeof J.startsWith==="string")return`必须以 "${J.startsWith}" 开头`;if(typeof J.endsWith==="string")return`必须以 "${J.endsWith}" 结尾`}return"字符串格式不正确"}case"invalid_enum_value":{let X=Y.options;if(Array.isArray(X))return`必须是以下值之一:${X.map((J)=>f8(J)).join(", ")}`;return"必须是枚举允许的值之一"}case"invalid_literal":{let X=Y.expected;return`必须是字面量值:${f8(X)}`}case"unrecognized_keys":{let X=Y.keys;if(Array.isArray(X))return`包含未知的参数:${X.map((J)=>f8(J)).join(", ")}`;return"包含未知的参数"}case"invalid_union":return"不符合任何有效的类型定义";case"invalid_date":return"必须是有效的日期";case"custom":return $.message||"自定义验证失败";default:return $.message||"验证失败"}}function YF($){let Z=$.issues.map((Q)=>{let X=Q.path.join("."),J=ZF(Q),G=Q.received;return{field:X||"root",message:J,value:G}}),Y=Z.length===1?`参数验证失败 [${Z[0].field}]: ${Z[0].message}`:`参数验证失败 (${Z.length} 个错误):
96
96
  ${Z.map((Q)=>` - ${Q.field}: ${Q.message}`).join(`
97
- `)}`;return new HQ(Y,Z)}function FQ($,Z){let Y=$.safeParse(Z);if(!Y.success)throw YF(Y.error);return Y.data}var HQ;var OQ=A(()=>{j0();HQ=class HQ extends Error{issues;type;constructor($,Z,Y="validation_error"){super($);this.issues=Z;this.type=Y;this.name="ToolValidationError"}}});import{zodToJsonSchema as QF}from"zod-to-json-schema";function s6($){return QF($,{target:"jsonSchema7",$refStrategy:"none"})}var zQ=()=>{};class t6{toolName;params;executeFn;descriptionFn;affectedPathsFn;constructor($,Z,Y,Q,X){this.toolName=$;this.params=Z;this.executeFn=Y;this.descriptionFn=Q;this.affectedPathsFn=X}getDescription(){if(this.descriptionFn)return this.descriptionFn(this.params);return`执行工具: ${this.toolName}`}getAffectedPaths(){if(this.affectedPathsFn)return this.affectedPathsFn(this.params);return[]}async execute($,Z,Y){let Q={signal:$,updateOutput:Z,...Y};return this.executeFn(this.params,Q)}}function t($){return{name:$.name,displayName:$.displayName,kind:$.kind,isReadOnly:$.isReadOnly??k3($.kind),isConcurrencySafe:$.isConcurrencySafe??!0,strict:$.strict??!1,description:$.description,version:$.version||"1.0.0",category:$.category,tags:$.tags||[],getFunctionDeclaration(){let Z=s6($.schema),Y=$.description.short;if($.description.long)Y+=`
97
+ `)}`;return new HQ(Y,Z)}function FQ($,Z){let Y=$.safeParse(Z);if(!Y.success)throw YF(Y.error);return Y.data}var HQ;var OQ=A(()=>{j0();HQ=class HQ extends Error{issues;type;constructor($,Z,Y="validation_error"){super($);this.issues=Z;this.type=Y;this.name="ToolValidationError"}}});import{zodToJsonSchema as QF}from"zod-to-json-schema";function s6($){return QF($,{target:"jsonSchema7",$refStrategy:"none"})}var zQ=()=>{};class t6{toolName;params;executeFn;descriptionFn;affectedPathsFn;constructor($,Z,Y,Q,X){this.toolName=$;this.params=Z;this.executeFn=Y;this.descriptionFn=Q;this.affectedPathsFn=X}getDescription(){if(this.descriptionFn)return this.descriptionFn(this.params);return`执行工具: ${this.toolName}`}getAffectedPaths(){if(this.affectedPathsFn)return this.affectedPathsFn(this.params);return[]}async execute($,Z,Y){let Q={signal:$,updateOutput:Z,...Y};return this.executeFn(this.params,Q)}}function t($){return{name:$.name,displayName:$.displayName,kind:$.kind,isReadOnly:$.isReadOnly??k8($.kind),isConcurrencySafe:$.isConcurrencySafe??!0,strict:$.strict??!1,description:$.description,version:$.version||"1.0.0",category:$.category,tags:$.tags||[],getFunctionDeclaration(){let Z=s6($.schema),Y=$.description.short;if($.description.long)Y+=`
98
98
 
99
99
  ${$.description.long}`;if($.description.usageNotes&&$.description.usageNotes.length>0)Y+=`
100
100
 
@@ -104,12 +104,12 @@ ${$.description.usageNotes.map((Q)=>`- ${Q}`).join(`
104
104
 
105
105
  Important:
106
106
  ${$.description.important.map((Q)=>`⚠️ ${Q}`).join(`
107
- `)}`;return{name:$.name,description:Y,parameters:Z}},getMetadata(){return{name:$.name,displayName:$.displayName,kind:$.kind,version:$.version||"1.0.0",category:$.category,tags:$.tags||[],description:$.description,schema:s6($.schema)}},build(Z){let Y=FQ($.schema,Z);return new t6($.name,Y,$.execute)},async execute(Z,Y){return this.build(Z).execute(Y||new AbortController().signal)},extractSignatureContent:$.extractSignatureContent?(Z)=>$.extractSignatureContent(Z):void 0,abstractPermissionRule:$.abstractPermissionRule?(Z)=>$.abstractPermissionRule(Z):void 0}}var p$=A(()=>{w0();OQ();zQ()});import{z as U1}from"zod";function x8($,Z,Y,Q){let X;try{X=h3(Y.inputSchema)}catch(G){console.warn(`[createMcpTool] Schema 转换失败,使用降级 schema: ${Y.name}`,G),X=U1.any()}let J=Q||Y.name;return t({name:J,displayName:`${Z}: ${Y.name}`,kind:"execute",schema:X,description:{short:Y.description||`MCP Tool: ${Y.name}`,important:[`From MCP server: ${Z}`,"Executes external tools; user confirmation required"]},category:"MCP tool",tags:["mcp","external",Z],async execute(G,K){try{let q=await $.callTool(Y.name,G),W="",U="";if(q.content&&Array.isArray(q.content)){for(let H of q.content)if(H.type==="text"&&H.text)W+=H.text,U+=H.text;else if(H.type==="image")U+=`[图片: ${H.mimeType||"unknown"}]
107
+ `)}`;return{name:$.name,description:Y,parameters:Z}},getMetadata(){return{name:$.name,displayName:$.displayName,kind:$.kind,version:$.version||"1.0.0",category:$.category,tags:$.tags||[],description:$.description,schema:s6($.schema)}},build(Z){let Y=FQ($.schema,Z);return new t6($.name,Y,$.execute)},async execute(Z,Y){return this.build(Z).execute(Y||new AbortController().signal)},extractSignatureContent:$.extractSignatureContent?(Z)=>$.extractSignatureContent(Z):void 0,abstractPermissionRule:$.abstractPermissionRule?(Z)=>$.abstractPermissionRule(Z):void 0}}var p$=A(()=>{w0();OQ();zQ()});import{z as U1}from"zod";function x3($,Z,Y,Q){let X;try{X=h8(Y.inputSchema)}catch(G){console.warn(`[createMcpTool] Schema 转换失败,使用降级 schema: ${Y.name}`,G),X=U1.any()}let J=Q||Y.name;return t({name:J,displayName:`${Z}: ${Y.name}`,kind:"execute",schema:X,description:{short:Y.description||`MCP Tool: ${Y.name}`,important:[`From MCP server: ${Z}`,"Executes external tools; user confirmation required"]},category:"MCP tool",tags:["mcp","external",Z],async execute(G,K){try{let q=await $.callTool(Y.name,G),W="",U="";if(q.content&&Array.isArray(q.content)){for(let H of q.content)if(H.type==="text"&&H.text)W+=H.text,U+=H.text;else if(H.type==="image")U+=`[图片: ${H.mimeType||"unknown"}]
108
108
  `,W+=`[image: ${H.mimeType||"unknown"}]
109
109
  `;else if(H.type==="resource")U+=`[资源: ${H.mimeType||"unknown"}]
110
110
  `,W+=`[resource: ${H.mimeType||"unknown"}]
111
111
  `}if(q.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工具 ${Y.name} 执行成功
112
- ${U}`,metadata:{serverName:Z,toolName:Y.name,mcpResult:q}}}catch(q){return{success:!1,llmContent:`MCP tool execution failed: ${q.message}`,displayContent:`❌ ${q.message}`,error:{type:"execution_error",message:q.message}}}}})}function h3($){if($.type==="object"||$.properties){let Z={},Y=$.required||[];if($.properties){for(let[Q,X]of Object.entries($.properties))if(typeof X==="object"&&X!==null){let J=h3(X);if(!Y.includes(Q))J=J.optional();Z[Q]=J}}return U1.object(Z)}if($.type==="array"&&$.items){if(typeof $.items==="object"&&!Array.isArray($.items)&&$.items!==null)return U1.array(h3($.items));return U1.array(U1.any())}if($.type==="string"){let Z=U1.string();if($.minLength!==void 0)Z=Z.min($.minLength);if($.maxLength!==void 0)Z=Z.max($.maxLength);if($.pattern)Z=Z.regex(new RegExp($.pattern));if($.enum)return U1.enum($.enum);return Z}if($.type==="number"||$.type==="integer"){let Z=U1.number();if($.minimum!==void 0)Z=Z.min($.minimum);if($.maximum!==void 0)Z=Z.max($.maximum);return Z}if($.type==="boolean")return U1.boolean();if($.oneOf&&$.oneOf.length>0){let Z=$.oneOf.filter((Y)=>typeof Y==="object"&&Y!==null).map((Y)=>h3(Y));if(Z.length>=2)return U1.union(Z)}if($.anyOf&&$.anyOf.length>0){let Z=$.anyOf.filter((Y)=>typeof Y==="object"&&Y!==null).map((Y)=>h3(Y));if(Z.length>=2)return U1.union(Z)}return U1.any()}var _Q=A(()=>{p$();j0()});import{promises as e6}from"fs";import XF from"os";import $7 from"path";class Z7{tokenFilePath;constructor(){let $=XF.homedir(),Z=$7.join($,".blade");this.tokenFilePath=$7.join(Z,"mcp-oauth-tokens.json")}async ensureConfigDir(){let $=$7.dirname(this.tokenFilePath);try{await e6.mkdir($,{recursive:!0,mode:493})}catch{}}async loadAllCredentials(){let $=new Map;try{let Z=await e6.readFile(this.tokenFilePath,"utf-8"),Y=JSON.parse(Z);for(let Q of Y)$.set(Q.serverName,Q)}catch(Z){if(Z.code!=="ENOENT")console.warn("[OAuthTokenStorage] 加载令牌失败:",Z)}return $}async saveAllCredentials($){await this.ensureConfigDir();let Z=Array.from($.values());await e6.writeFile(this.tokenFilePath,JSON.stringify(Z,null,2),{mode:384})}async saveToken($,Z,Y,Q){let X=await this.loadAllCredentials(),J={serverName:$,token:Z,clientId:Y,tokenUrl:Q,updatedAt:Date.now()};X.set($,J),await this.saveAllCredentials(X)}async getCredentials($){return(await this.loadAllCredentials()).get($)||null}async deleteCredentials($){let Z=await this.loadAllCredentials();Z.delete($),await this.saveAllCredentials(Z)}async listServers(){let $=await this.loadAllCredentials();return Array.from($.keys())}isTokenExpired($){if(!$.expiresAt)return!1;let Z=300000;return Date.now()>=$.expiresAt-Z}}var BQ=()=>{};import{spawn as JF}from"child_process";import*as p3 from"crypto";import*as NQ from"http";import{URL as LQ}from"url";class p8{tokenStorage;constructor($=new Z7){this.tokenStorage=$}generatePKCEParams(){let $=p3.randomBytes(32).toString("base64url"),Z=p3.createHash("sha256").update($).digest("base64url"),Y=p3.randomBytes(16).toString("base64url");return{codeVerifier:$,codeChallenge:Z,state:Y}}buildAuthorizationUrl($,Z){let Y=$.redirectUri||`http://localhost:${x3}${Y7}`,Q=new URLSearchParams({client_id:$.clientId,response_type:"code",redirect_uri:Y,state:Z.state,code_challenge:Z.codeChallenge,code_challenge_method:"S256"});if($.scopes&&$.scopes.length>0)Q.append("scope",$.scopes.join(" "));let X=new LQ($.authorizationUrl);return Q.forEach((J,G)=>{X.searchParams.append(G,J)}),X.toString()}async startCallbackServer($){return new Promise((Z,Y)=>{let Q=NQ.createServer((X,J)=>{try{let G=new LQ(X.url,`http://localhost:${x3}`);if(G.pathname!==Y7){J.writeHead(404),J.end("Not found");return}let K=G.searchParams.get("code"),q=G.searchParams.get("state"),W=G.searchParams.get("error");if(W){J.writeHead(wQ,{"Content-Type":"text/html"}),J.end(`
112
+ ${U}`,metadata:{serverName:Z,toolName:Y.name,mcpResult:q}}}catch(q){return{success:!1,llmContent:`MCP tool execution failed: ${q.message}`,displayContent:`❌ ${q.message}`,error:{type:"execution_error",message:q.message}}}}})}function h8($){if($.type==="object"||$.properties){let Z={},Y=$.required||[];if($.properties){for(let[Q,X]of Object.entries($.properties))if(typeof X==="object"&&X!==null){let J=h8(X);if(!Y.includes(Q))J=J.optional();Z[Q]=J}}return U1.object(Z)}if($.type==="array"&&$.items){if(typeof $.items==="object"&&!Array.isArray($.items)&&$.items!==null)return U1.array(h8($.items));return U1.array(U1.any())}if($.type==="string"){let Z=U1.string();if($.minLength!==void 0)Z=Z.min($.minLength);if($.maxLength!==void 0)Z=Z.max($.maxLength);if($.pattern)Z=Z.regex(new RegExp($.pattern));if($.enum)return U1.enum($.enum);return Z}if($.type==="number"||$.type==="integer"){let Z=U1.number();if($.minimum!==void 0)Z=Z.min($.minimum);if($.maximum!==void 0)Z=Z.max($.maximum);return Z}if($.type==="boolean")return U1.boolean();if($.oneOf&&$.oneOf.length>0){let Z=$.oneOf.filter((Y)=>typeof Y==="object"&&Y!==null).map((Y)=>h8(Y));if(Z.length>=2)return U1.union(Z)}if($.anyOf&&$.anyOf.length>0){let Z=$.anyOf.filter((Y)=>typeof Y==="object"&&Y!==null).map((Y)=>h8(Y));if(Z.length>=2)return U1.union(Z)}return U1.any()}var _Q=A(()=>{p$();j0()});import{promises as e6}from"fs";import XF from"os";import $7 from"path";class Z7{tokenFilePath;constructor(){let $=XF.homedir(),Z=$7.join($,".blade");this.tokenFilePath=$7.join(Z,"mcp-oauth-tokens.json")}async ensureConfigDir(){let $=$7.dirname(this.tokenFilePath);try{await e6.mkdir($,{recursive:!0,mode:493})}catch{}}async loadAllCredentials(){let $=new Map;try{let Z=await e6.readFile(this.tokenFilePath,"utf-8"),Y=JSON.parse(Z);for(let Q of Y)$.set(Q.serverName,Q)}catch(Z){if(Z.code!=="ENOENT")console.warn("[OAuthTokenStorage] 加载令牌失败:",Z)}return $}async saveAllCredentials($){await this.ensureConfigDir();let Z=Array.from($.values());await e6.writeFile(this.tokenFilePath,JSON.stringify(Z,null,2),{mode:384})}async saveToken($,Z,Y,Q){let X=await this.loadAllCredentials(),J={serverName:$,token:Z,clientId:Y,tokenUrl:Q,updatedAt:Date.now()};X.set($,J),await this.saveAllCredentials(X)}async getCredentials($){return(await this.loadAllCredentials()).get($)||null}async deleteCredentials($){let Z=await this.loadAllCredentials();Z.delete($),await this.saveAllCredentials(Z)}async listServers(){let $=await this.loadAllCredentials();return Array.from($.keys())}isTokenExpired($){if(!$.expiresAt)return!1;let Z=300000;return Date.now()>=$.expiresAt-Z}}var BQ=()=>{};import{spawn as JF}from"child_process";import*as p8 from"crypto";import*as NQ from"http";import{URL as LQ}from"url";class p3{tokenStorage;constructor($=new Z7){this.tokenStorage=$}generatePKCEParams(){let $=p8.randomBytes(32).toString("base64url"),Z=p8.createHash("sha256").update($).digest("base64url"),Y=p8.randomBytes(16).toString("base64url");return{codeVerifier:$,codeChallenge:Z,state:Y}}buildAuthorizationUrl($,Z){let Y=$.redirectUri||`http://localhost:${x8}${Y7}`,Q=new URLSearchParams({client_id:$.clientId,response_type:"code",redirect_uri:Y,state:Z.state,code_challenge:Z.codeChallenge,code_challenge_method:"S256"});if($.scopes&&$.scopes.length>0)Q.append("scope",$.scopes.join(" "));let X=new LQ($.authorizationUrl);return Q.forEach((J,G)=>{X.searchParams.append(G,J)}),X.toString()}async startCallbackServer($){return new Promise((Z,Y)=>{let Q=NQ.createServer((X,J)=>{try{let G=new LQ(X.url,`http://localhost:${x8}`);if(G.pathname!==Y7){J.writeHead(404),J.end("Not found");return}let K=G.searchParams.get("code"),q=G.searchParams.get("state"),W=G.searchParams.get("error");if(W){J.writeHead(wQ,{"Content-Type":"text/html"}),J.end(`
113
113
  <html>
114
114
  <body>
115
115
  <h1>Authentication Failed</h1>
@@ -125,9 +125,9 @@ ${U}`,metadata:{serverName:Z,toolName:Y.name,mcpResult:q}}}catch(q){return{succe
125
125
  <script>window.close();</script>
126
126
  </body>
127
127
  </html>
128
- `),Q.close(),Z(K)}catch(G){Q.close(),Y(G)}});Q.on("error",Y),Q.listen(x3,()=>{console.log(`[OAuth] Callback server listening on port ${x3}`)}),setTimeout(()=>{Q.close(),Y(Error("OAuth callback timeout"))},300000)})}async exchangeCodeForToken($,Z,Y){let Q=$.redirectUri||`http://localhost:${x3}${Y7}`,X=new URLSearchParams({grant_type:"authorization_code",code:Z,redirect_uri:Q,code_verifier:Y,client_id:$.clientId});if($.clientSecret)X.append("client_secret",$.clientSecret);let J=await fetch($.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:X.toString()});if(!J.ok){let G=await J.text();throw Error(`Token exchange failed: ${J.status} - ${G}`)}return await J.json()}async refreshAccessToken($,Z){let Y=new URLSearchParams({grant_type:"refresh_token",refresh_token:Z,client_id:$.clientId});if($.clientSecret)Y.append("client_secret",$.clientSecret);if($.scopes&&$.scopes.length>0)Y.append("scope",$.scopes.join(" "));let Q=await fetch($.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:Y.toString()});if(!Q.ok){let X=await Q.text();throw Error(`Token refresh failed: ${Q.status} - ${X}`)}return await Q.json()}async authenticate($,Z){if(!Z.clientId||!Z.authorizationUrl||!Z.tokenUrl)throw Error("Missing required OAuth configuration");let Y=this.generatePKCEParams(),Q=this.buildAuthorizationUrl(Z,Y);console.log(`
128
+ `),Q.close(),Z(K)}catch(G){Q.close(),Y(G)}});Q.on("error",Y),Q.listen(x8,()=>{console.log(`[OAuth] Callback server listening on port ${x8}`)}),setTimeout(()=>{Q.close(),Y(Error("OAuth callback timeout"))},300000)})}async exchangeCodeForToken($,Z,Y){let Q=$.redirectUri||`http://localhost:${x8}${Y7}`,X=new URLSearchParams({grant_type:"authorization_code",code:Z,redirect_uri:Q,code_verifier:Y,client_id:$.clientId});if($.clientSecret)X.append("client_secret",$.clientSecret);let J=await fetch($.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:X.toString()});if(!J.ok){let G=await J.text();throw Error(`Token exchange failed: ${J.status} - ${G}`)}return await J.json()}async refreshAccessToken($,Z){let Y=new URLSearchParams({grant_type:"refresh_token",refresh_token:Z,client_id:$.clientId});if($.clientSecret)Y.append("client_secret",$.clientSecret);if($.scopes&&$.scopes.length>0)Y.append("scope",$.scopes.join(" "));let Q=await fetch($.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:Y.toString()});if(!Q.ok){let X=await Q.text();throw Error(`Token refresh failed: ${Q.status} - ${X}`)}return await Q.json()}async authenticate($,Z){if(!Z.clientId||!Z.authorizationUrl||!Z.tokenUrl)throw Error("Missing required OAuth configuration");let Y=this.generatePKCEParams(),Q=this.buildAuthorizationUrl(Z,Y);console.log(`
129
129
  [OAuth] Opening browser for authentication...`),console.log(`
130
- If the browser does not open automatically, copy and paste this URL:`),console.log(Q),console.log("");let X=this.startCallbackServer(Y.state);try{await this.openAuthorizationUrl(Q)}catch(q){console.warn("[OAuth] Failed to open browser automatically:",q)}let J=await X;console.log("[OAuth] Authorization code received, exchanging for tokens...");let G=await this.exchangeCodeForToken(Z,J,Y.codeVerifier),K={accessToken:G.access_token,tokenType:G.token_type||"Bearer",refreshToken:G.refresh_token,scope:G.scope};if(G.expires_in)K.expiresAt=Date.now()+G.expires_in*1000;return await this.tokenStorage.saveToken($,K,Z.clientId,Z.tokenUrl),console.log("[OAuth] Authentication successful! Token saved."),K}async openAuthorizationUrl($){let{command:Z,args:Y}=this.getBrowserCommand($);await new Promise((Q,X)=>{let J=JF(Z,Y,{stdio:"ignore"});J.once("error",X),J.once("close",(G)=>{if(G===0||G===null)Q();else X(Error(`Failed to open browser (exit code ${G})`))})})}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($,Z){let Y=await this.tokenStorage.getCredentials($);if(!Y)return null;let{token:Q}=Y;if(!this.tokenStorage.isTokenExpired(Q))return Q.accessToken;if(Q.refreshToken&&Z.clientId&&Y.tokenUrl)try{console.log(`[OAuth] Refreshing expired token for server: ${$}`);let X=await this.refreshAccessToken(Z,Q.refreshToken),J={accessToken:X.access_token,tokenType:X.token_type,refreshToken:X.refresh_token||Q.refreshToken,scope:X.scope||Q.scope};if(X.expires_in)J.expiresAt=Date.now()+X.expires_in*1000;return await this.tokenStorage.saveToken($,J,Z.clientId,Y.tokenUrl),J.accessToken}catch(X){console.error("[OAuth] Failed to refresh token:",X),await this.tokenStorage.deleteCredentials($)}return null}}var x3=7777,Y7="/oauth/callback",wQ=200;var bQ=A(()=>{BQ()});var AQ=A(()=>{bQ()});var x4=()=>{};import{EventEmitter as GF}from"events";var Q7;var RQ=A(()=>{x4();Q7=class Q7 extends GF{client;config;checkTimer=null;isChecking=!1;consecutiveFailures=0;lastCheckTime=0;currentStatus="healthy";constructor($,Z={}){super();this.client=$,this.config={interval:Z.interval??30000,timeout:Z.timeout??1e4,enabled:Z.enabled??!1,failureThreshold:Z.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 Z={status:"healthy",timestamp:Date.now(),consecutiveFailures:0};return this.emit("healthCheck",Z),Z}else throw Error(`连接状态异常: ${$}`)}catch($){this.consecutiveFailures++;let Z=$;console.warn(`[HealthMonitor] 健康检查失败(${this.consecutiveFailures}/${this.config.failureThreshold}):`,Z.message);let Y;if(this.consecutiveFailures>=this.config.failureThreshold)Y="unhealthy",this.emit("unhealthy",this.consecutiveFailures,Z),console.log("[HealthMonitor] 达到失败阈值,触发重连..."),this.triggerReconnection().catch((X)=>{console.error("[HealthMonitor] 重连失败:",X)});else Y="degraded";this.setStatus(Y);let Q={status:Y,timestamp:Date.now(),consecutiveFailures:this.consecutiveFailures,lastError:Z};return this.emit("healthCheck",Q),Q}finally{this.isChecking=!1}}async pingServer(){let $=new Promise((Y,Q)=>{setTimeout(()=>Q(Error("Health check timeout")),this.config.timeout)}),Z=(async()=>{if(this.client.availableTools.length===0){if(!this.client.server)throw Error("Server info not available")}})();await Promise.race([Z,$])}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 Z=this.currentStatus;this.currentStatus=$,this.emit("statusChanged",$,Z)}}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 KF}from"@modelcontextprotocol/sdk/client/index.js";import{SSEClientTransport as qF}from"@modelcontextprotocol/sdk/client/sse.js";import{StdioClientTransport as WF}from"@modelcontextprotocol/sdk/client/stdio.js";import{EventEmitter as UF}from"events";function VQ($){if(!($ instanceof Error))return{type:"unknown",isRetryable:!1,originalError:Error(String($))};let Z=$.message.toLowerCase();if(["command not found","no such file","permission denied","invalid configuration","malformed","syntax error"].some((X)=>Z.includes(X)))return{type:"config_error",isRetryable:!1,originalError:$};if(Z.includes("unauthorized")||Z.includes("401")||Z.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((X)=>Z.includes(X)))return{type:"network_temporary",isRetryable:!0,originalError:$};return{type:"unknown",isRetryable:!0,originalError:$}}var X7;var DQ=A(()=>{P3();AQ();RQ();x4();X7=class X7 extends UF{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($,Z,Y){super();this.config=$;if(this.serverName=Z||"default",$.oauth?.enabled)this.oauthProvider=new p8;if(Y?.enabled)this.healthMonitor=new Q7(this,Y),this.healthMonitor.on("unhealthy",(Q,X)=>{this.emit("unhealthy",Q,X)}),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,Z=1000){if(this.status!=="disconnected"&&this.status!=="error")throw Error("客户端已连接或正在连接中");if(this.status==="error"){if(this.sdkClient){try{await this.sdkClient.close()}catch{}this.sdkClient=null}this.setStatus("disconnected")}let Y=null;for(let Q=1;Q<=$;Q++)try{await this.doConnect(),this.reconnectAttempts=0;return}catch(X){Y=X;let J=VQ(X);if(!J.isRetryable)throw console.error("[McpClient] 检测到永久性错误,放弃重试:",J.type),X;if(Q<$){let G=Z*Math.pow(2,Q-1);console.warn(`[McpClient] 连接失败(${Q}/${$}),${G}ms 后重试...`),await new Promise((K)=>setTimeout(K,G))}}throw Y||Error("连接失败")}async doConnect(){try{this.setStatus("connecting"),this.sdkClient=new KF({name:LY(),version:v4()},{capabilities:{roots:{listChanged:!0},sampling:{}}}),this.sdkClient.onclose=()=>{this.handleUnexpectedClose()};let $=await this.createTransport();await this.sdkClient.connect($);let Z=this.sdkClient.getServerVersion();if(this.serverInfo={name:Z?.name||"Unknown",version:Z?.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(Z){if(console.error("[McpClient] 重连失败:",Z),VQ(Z).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($,Z={}){if(!this.sdkClient)throw Error("客户端未连接到服务器");if(!this.tools.has($))throw Error(`工具 "${$}" 不存在`);try{return await this.sdkClient.callTool({name:$,arguments:Z})}catch(Y){throw console.error(`[McpClient] 调用工具 "${$}" 失败:`,Y),Y}}async createTransport(){let{type:$,command:Z,args:Y,env:Q,url:X,headers:J,oauth:G}=this.config,K={...J};if(G?.enabled&&this.oauthProvider&&($==="sse"||$==="http"))try{let q=await this.oauthProvider.getValidToken(this.serverName,G);if(!q){console.log(`[McpClient] 服务器 "${this.serverName}" 需要 OAuth 认证`);let W=await this.oauthProvider.authenticate(this.serverName,G);K.Authorization=`Bearer ${W.accessToken}`}else K.Authorization=`Bearer ${q}`}catch(q){throw console.error("[McpClient] OAuth 认证失败:",q),Error(`OAuth 认证失败: ${q instanceof Error?q.message:String(q)}`)}if($==="stdio"){if(!Z)throw Error("stdio 传输需要 command 参数");let q={};for(let[W,U]of Object.entries(process.env))if(U!==void 0)q[W]=U;return new WF({command:Z,args:Y||[],env:{...q,...Q},stderr:"ignore"})}else if($==="sse"){if(!X)throw Error("sse 传输需要 url 参数");return new qF(new URL(X),{requestInit:{headers:K}})}else if($==="http"){if(!X)throw Error("http 传输需要 url 参数");let{StreamableHTTPClientTransport:q}=await import("@modelcontextprotocol/sdk/client/streamableHttp.js");return new q(new URL(X),{requestInit:{headers:K}})}throw Error(`不支持的传输类型: ${$}`)}async loadTools(){if(!this.sdkClient)return;try{let $=await this.sdkClient.listTools();if(this.tools.clear(),$.tools)for(let Z of $.tools)this.tools.set(Z.name,Z);this.emit("toolsUpdated",this.availableTools)}catch($){throw console.error("[McpClient] 加载工具失败:",$),$}}setStatus($){let Z=this.status;this.status=$,this.emit("statusChanged",$,Z)}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($,Z){if(!this.sdkClient)throw Error("客户端未连接");return(await this.sdkClient.readResource({uri:$})).contents?.[0]||{uri:$,text:""}}}});import{EventEmitter as HF}from"events";var b0;var e2=A(()=>{_Q();DQ();x4();b0=class b0 extends HF{static instance=null;servers=new Map;isDiscovering=!1;constructor(){super()}static getInstance(){if(!b0.instance)b0.instance=new b0;return b0.instance}async registerServer($,Z){if(this.servers.has($))throw Error(`MCP服务器 "${$}" 已经注册`);let Y=new X7(Z,$,Z.healthCheck),Q={config:Z,client:Y,status:"disconnected",tools:[]};this.setupClientEventHandlers(Y,Q,$),this.servers.set($,Q),this.emit("serverRegistered",$,Q);try{await this.connectServer($)}catch(X){console.warn(`MCP服务器 "${$}" 连接失败:`,X)}}async unregisterServer($){let Z=this.servers.get($);if(!Z)return;try{await Z.client.disconnect()}catch(Y){console.warn(`断开MCP服务器 "${$}" 时出错:`,Y)}this.servers.delete($),this.emit("serverUnregistered",$)}async connectServer($){let Z=this.servers.get($);if(!Z)throw Error(`MCP服务器 "${$}" 未注册`);if(Z.status==="connected")return;try{Z.status="connecting",await Z.client.connect(),Z.connectedAt=new Date,Z.lastError=void 0,Z.tools=Z.client.availableTools}catch(Y){throw Z.lastError=Y,Z.status="error",Y}}async disconnectServer($){let Z=this.servers.get($);if(!Z)return;await Z.client.disconnect(),Z.connectedAt=void 0}async reconnectServer($){let Z=this.servers.get($);if(!Z)throw Error(`MCP服务器 "${$}" 未注册`);if(Z.status==="connected")await Z.client.disconnect();try{Z.status="connecting",await Z.client.connect(),Z.connectedAt=new Date,Z.lastError=void 0,Z.tools=Z.client.availableTools}catch(Y){throw Z.lastError=Y,Z.status="error",Y}}async getAvailableTools(){let $=[],Z=new Map;for(let[Y,Q]of this.servers)if(Q.status==="connected")for(let X of Q.tools){let J=Z.get(X.name)||0;Z.set(X.name,J+1)}for(let[Y,Q]of this.servers)if(Q.status==="connected")for(let X of Q.tools){let G=(Z.get(X.name)||0)>1?`${Y}__${X.name}`:X.name,K=x8(Q.client,Y,X,G);$.push(K)}return $}async findTool($){for(let[Z,Y]of this.servers)if(Y.status==="connected"){let Q=Y.tools.find((X)=>X.name===$);if(Q)return x8(Y.client,Z,Q)}return null}getToolsByServer($){let Z=this.servers.get($);if(!Z||Z.status!=="connected")return[];return Z.tools.map((Y)=>x8(Z.client,$,Y))}getServerStatus($){return this.servers.get($)||null}getAllServers(){return new Map(this.servers)}async refreshAllTools(){let $=[];for(let[Z,Y]of this.servers)if(Y.status==="connected")$.push(this.refreshServerTools(Z));await Promise.allSettled($)}async refreshServerTools($){let Z=this.servers.get($);if(!Z||Z.status!=="connected")return;try{let Y=Z.client.availableTools,Q=Z.tools.length;Z.tools=Y,this.emit("toolsUpdated",$,Y,Q)}catch(Y){console.warn(`刷新服务器 "${$}" 工具列表失败:`,Y)}}setupClientEventHandlers($,Z,Y){$.on("connected",(Q)=>{Z.status="connected",Z.connectedAt=new Date,Z.tools=$.availableTools,this.emit("serverConnected",Y,Q)}),$.on("disconnected",()=>{Z.status="disconnected",Z.connectedAt=void 0,Z.tools=[],this.emit("serverDisconnected",Y)}),$.on("error",(Q)=>{Z.status="error",Z.lastError=Q,this.emit("serverError",Y,Q)}),$.on("toolsUpdated",(Q)=>{let X=Z.tools.length;Z.tools=Q,this.emit("toolsUpdated",Y,Q,X)}),$.on("statusChanged",(Q,X)=>{Z.status=Q,this.emit("serverStatusChanged",Y,Q,X)})}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 Z=Object.entries($).map(([Y,Q])=>this.registerServer(Y,Q).catch((X)=>{return console.warn(`注册MCP服务器 "${Y}" 失败:`,X),X}));await Promise.allSettled(Z)}getStatistics(){let $=0,Z=0,Y=0;for(let Q of this.servers.values())if(Q.status==="connected")$++,Z+=Q.tools.length;else if(Q.status==="error")Y++;return{totalServers:this.servers.size,connectedServers:$,errorServers:Y,totalTools:Z,isDiscovering:this.isDiscovering}}async disconnectAll(){let $=[];for(let[Z,Y]of this.servers)if(Y.status==="connected")$.push(Y.client.disconnect().catch((Q)=>{console.warn(`断开 MCP 服务器 "${Z}" 时出错:`,Q)}));await Promise.allSettled($),this.servers.clear()}}});function K7($,Z){return{...$,...Z,PreToolUse:Z.PreToolUse??$.PreToolUse,PostToolUse:Z.PostToolUse??$.PostToolUse,PostToolUseFailure:Z.PostToolUseFailure??$.PostToolUseFailure,PermissionRequest:Z.PermissionRequest??$.PermissionRequest,UserPromptSubmit:Z.UserPromptSubmit??$.UserPromptSubmit,SessionStart:Z.SessionStart??$.SessionStart,SessionEnd:Z.SessionEnd??$.SessionEnd,Stop:Z.Stop??$.Stop,SubagentStop:Z.SubagentStop??$.SubagentStop,Notification:Z.Notification??$.Notification,Compaction:Z.Compaction??$.Compaction}}function IQ(){let $={};if(process.env.BLADE_DISABLE_HOOKS==="true")$.enabled=!1;if(process.env.BLADE_HOOK_TIMEOUT){let Z=parseInt(process.env.BLADE_HOOK_TIMEOUT,10);if(!isNaN(Z)&&Z>0)$.defaultTimeout=Z}return $}var G7;var yQ=A(()=>{G7={enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,PreToolUse:[],PostToolUse:[],PostToolUseFailure:[],PermissionRequest:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]}});class q7{executedHooks=new Map;canExecute($,Z){if(!this.executedHooks.has($))this.executedHooks.set($,new Set);if(this.executedHooks.get($).has(Z))return console.warn(`[HookGuard] Hook ${Z} for tool ${$} already executed, skipping`),!1;return!0}markExecuted($,Z){let Y=this.executedHooks.get($);if(Y)Y.add(Z)}cleanup($){this.executedHooks.delete($)}cleanupAll(){this.executedHooks.clear()}}var x1,W7,U7;var m4=A(()=>{((H)=>{H.PreToolUse="PreToolUse";H.PostToolUse="PostToolUse";H.PostToolUseFailure="PostToolUseFailure";H.PermissionRequest="PermissionRequest";H.UserPromptSubmit="UserPromptSubmit";H.SessionStart="SessionStart";H.SessionEnd="SessionEnd";H.Stop="Stop";H.SubagentStop="SubagentStop";H.Notification="Notification";H.Compaction="Compaction"})(x1||={});((Q)=>{Q.Approve="approve";Q.Block="block";Q.Async="async"})(W7||={});((Q)=>{Q.Allow="allow";Q.Deny="deny";Q.Ask="ask"})(U7||={})});import{z as P}from"zod";function vQ($){let Z=mF.safeParse($);if(Z.success)return{success:!0,data:Z.data};return{success:!1,error:Z.error}}var j1,AF,RF,VF,DF,MF,jF,IF,yF,vF,EF,PF,QD,TF,CF,SF,kF,fF,hF,xF,pF,mF,dF,uF,gF,H7,cF,M1,XD;var EQ=A(()=>{m4();j1=P.object({hook_event_name:P.nativeEnum(x1),hook_execution_id:P.string(),timestamp:P.string(),project_dir:P.string(),session_id:P.string(),permission_mode:P.enum(["default","autoEdit","yolo","plan"]),_metadata:P.object({blade_version:P.string(),hook_timeout_ms:P.number()}).optional()}),AF=j1.extend({hook_event_name:P.literal("PreToolUse"),tool_name:P.string(),tool_use_id:P.string(),tool_input:P.record(P.unknown())}),RF=j1.extend({hook_event_name:P.literal("PostToolUse"),tool_name:P.string(),tool_use_id:P.string(),tool_input:P.record(P.unknown()),tool_response:P.unknown()}),VF=j1.extend({hook_event_name:P.literal("Stop"),reason:P.string().optional()}),DF=j1.extend({hook_event_name:P.literal("PostToolUseFailure"),tool_name:P.string(),tool_use_id:P.string(),tool_input:P.record(P.unknown()),error:P.string(),error_type:P.string().optional(),is_interrupt:P.boolean(),is_timeout:P.boolean()}),MF=j1.extend({hook_event_name:P.literal("PermissionRequest"),tool_name:P.string(),tool_use_id:P.string(),tool_input:P.record(P.unknown())}),jF=j1.extend({hook_event_name:P.literal("UserPromptSubmit"),user_prompt:P.string(),has_images:P.boolean(),image_count:P.number()}),IF=j1.extend({hook_event_name:P.literal("SessionStart"),is_resume:P.boolean(),resume_session_id:P.string().optional()}),yF=j1.extend({hook_event_name:P.literal("SessionEnd"),reason:P.enum(["user_exit","error","max_turns","idle_timeout","ctrl_c","clear","logout","other"])}),vF=j1.extend({hook_event_name:P.literal("SubagentStop"),agent_type:P.string(),task_description:P.string().optional(),success:P.boolean(),result_summary:P.string().optional(),error:P.string().optional()}),EF=j1.extend({hook_event_name:P.literal("Notification"),notification_type:P.enum(["permission_prompt","idle_prompt","auth_success","elicitation_dialog","info","warning","error"]),title:P.string().optional(),message:P.string()}),PF=j1.extend({hook_event_name:P.literal("Compaction"),trigger:P.enum(["manual","auto"]),messages_before:P.number(),tokens_before:P.number()}),QD=P.discriminatedUnion("hook_event_name",[AF,RF,VF,DF,MF,jF,IF,yF,vF,EF,PF]),TF=P.object({hookEventName:P.literal("PreToolUse"),permissionDecision:P.nativeEnum(U7).optional(),permissionDecisionReason:P.string().optional(),updatedInput:P.record(P.unknown()).optional()}),CF=P.object({hookEventName:P.literal("PostToolUse"),additionalContext:P.string().optional(),updatedOutput:P.unknown().optional()}),SF=P.object({hookEventName:P.literal("Stop"),continue:P.boolean().optional(),continueReason:P.string().optional()}),kF=P.object({hookEventName:P.literal("SubagentStop"),continue:P.boolean().optional(),continueReason:P.string().optional(),additionalContext:P.string().optional()}),fF=P.object({hookEventName:P.literal("PermissionRequest"),permissionDecision:P.enum(["approve","deny","ask"]).optional(),permissionDecisionReason:P.string().optional()}),hF=P.object({hookEventName:P.literal("UserPromptSubmit"),updatedPrompt:P.string().optional(),contextInjection:P.string().optional()}),xF=P.object({hookEventName:P.literal("SessionStart"),env:P.record(P.string()).optional()}),pF=P.object({hookEventName:P.literal("Compaction"),blockCompaction:P.boolean().optional(),blockReason:P.string().optional()}),mF=P.object({decision:P.object({behavior:P.nativeEnum(W7)}).optional(),systemMessage:P.string().optional(),hookSpecificOutput:P.discriminatedUnion("hookEventName",[TF,CF,SF,kF,fF,hF,xF,pF]).optional(),suppressOutput:P.boolean().optional()}),dF=P.object({type:P.literal("command"),command:P.string(),timeout:P.number().positive().optional(),statusMessage:P.string().optional()}),uF=P.object({type:P.literal("prompt"),prompt:P.string(),timeout:P.number().positive().optional()}),gF=P.discriminatedUnion("type",[dF,uF]),H7=P.union([P.string(),P.array(P.string())]),cF=P.object({tools:H7.optional(),paths:H7.optional(),commands:H7.optional()}),M1=P.object({name:P.string().optional(),matcher:cF.optional(),hooks:P.array(gF)}),XD=P.object({enabled:P.boolean().optional(),defaultTimeout:P.number().positive().optional(),timeoutBehavior:P.enum(["ignore","deny","ask"]).optional(),failureBehavior:P.enum(["ignore","deny","ask"]).optional(),maxConcurrentHooks:P.number().positive().optional(),PreToolUse:P.array(M1).optional(),PostToolUse:P.array(M1).optional(),PostToolUseFailure:P.array(M1).optional(),PermissionRequest:P.array(M1).optional(),UserPromptSubmit:P.array(M1).optional(),SessionStart:P.array(M1).optional(),SessionEnd:P.array(M1).optional(),Stop:P.array(M1).optional(),SubagentStop:P.array(M1).optional(),Notification:P.array(M1).optional(),Compaction:P.array(M1).optional()})});class F7{parse($,Z,Y){if($.timedOut){let X=Y?.timeoutBehavior||"ignore",J="Hook timeout";if(X==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z}}let Q=this.tryParseJSON($.stdout);if(Q){let X=vQ(Q);if(!X.success){let G="error"in X?X.error.message:"Unknown validation error",K=Y?.failureBehavior||"ignore",q=`Invalid hook output JSON: ${G}`;if(K==="deny")return{success:!1,blocking:!0,error:q,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else if(K==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${q}. Continue?`,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else return{success:!1,blocking:!1,warning:q,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z}}let J=X.data;if(J.decision?.behavior==="block")return{success:!1,blocking:!0,error:J.systemMessage||"Hook blocked execution",output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};if(J.decision?.behavior==="async")return{success:!0,output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};return{success:!0,output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z}}return this.parseByExitCode($,Z,Y)}parseByExitCode($,Z,Y){let Q=$.exitCode;switch(Q){case 0:return{success:!0,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};case 2:return{success:!1,blocking:!0,error:$.stderr||$.stdout||"Hook returned exit code 2",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};case 124:{let X=Y?.timeoutBehavior||"ignore",J="Hook timeout";if(X==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z}}default:{let X=Y?.failureBehavior||"ignore",J=$.stderr||$.stdout||`Hook failed with exit code ${Q}`;if(X==="deny")return{success:!1,blocking:!0,error:J,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${J}. Continue?`,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else return{success:!1,blocking:!1,warning:J,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z}}}}tryParseJSON($){try{let Z=$.trim();if(!Z)return null;let Y=Z.match(/^\s*(\{[\s\S]*\})\s*$/);if(!Y)return null;return JSON.parse(Y[1])}catch{return null}}}var PQ=A(()=>{EQ()});import{spawn as lF}from"child_process";class O7{content="";maxSize;constructor($){this.maxSize=$}append($){if(this.content.length<this.maxSize){let Z=this.maxSize-this.content.length;this.content+=$.substring(0,Z)}}getContent(){return this.content}isFull(){return this.content.length>=this.maxSize}}class z7{MAX_STDOUT_SIZE=1048576;MAX_STDERR_SIZE=1048576;MAX_INPUT_SIZE=102400;async execute($,Z,Y,Q){let X=JSON.stringify(Z);if(X.length>this.MAX_INPUT_SIZE)throw Error(`Hook input too large: ${X.length} bytes (max ${this.MAX_INPUT_SIZE})`);let J=this.createSafeEnv(Z),G=lF($,[],{shell:!0,env:J,cwd:Y.projectDir,timeout:Q}),K=new O7(this.MAX_STDOUT_SIZE),q=new O7(this.MAX_STDERR_SIZE);G.stdout.setEncoding("utf8"),G.stderr.setEncoding("utf8"),G.stdout.on("data",(W)=>{K.append(W)}),G.stderr.on("data",(W)=>{q.append(W)});try{G.stdin.write(X),G.stdin.end()}catch(W){throw G.kill("SIGTERM"),Error(`Failed to write hook input: ${W}`)}return new Promise((W,U)=>{let H=!1,F=!1,O=null,z=()=>{if(O&&Y.abortSignal)Y.abortSignal.removeEventListener("abort",O),O=null},_=setTimeout(()=>{H=!0,G.kill("SIGKILL")},Q);if(G.on("close",(B)=>{if(F)return;F=!0,clearTimeout(_),z(),W({stdout:K.getContent(),stderr:q.getContent(),exitCode:H?124:B??1,timedOut:H})}),G.on("error",(B)=>{if(F)return;F=!0,clearTimeout(_),z(),U(B)}),Y.abortSignal)O=()=>{if(F)return;F=!0,clearTimeout(_),z(),G.kill("SIGTERM"),W({stdout:K.getContent(),stderr:"Hook cancelled by abort signal",exitCode:1,timedOut:!1})},Y.abortSignal.addEventListener("abort",O)})}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 TQ=()=>{};class _7{processExecutor=new z7;outputParser=new F7;async executePreToolHooks($,Z,Y){if($.length===0)return{decision:"allow"};let Q="tool_input"in Z?Z.tool_input:{},X=[];for(let J of $)try{let G={...Z,...Q&&{tool_input:Q}},K=await this.executeHook(J,G,Y);if(!K.success){if(K.blocking)return{decision:"deny",reason:K.error};if(K.needsConfirmation)return{decision:"ask",reason:K.warning||K.error};if(K.warning)X.push(K.warning);continue}let q=K.output?.hookSpecificOutput;if(q&&"permissionDecision"in q){switch(q.permissionDecision){case"deny":return{decision:"deny",reason:q.permissionDecisionReason};case"ask":return{decision:"ask",reason:q.permissionDecisionReason};case"allow":break}if("updatedInput"in q&&q.updatedInput)Q={...Q,...q.updatedInput}}}catch(G){let K=G instanceof Error?G.message:String(G);if(X.push(`Hook failed: ${K}`),Y.config.failureBehavior==="deny")return{decision:"deny",reason:K};else if(Y.config.failureBehavior==="ask")return{decision:"ask",reason:`Hook failed: ${K}. Continue?`}}return{decision:"allow",modifiedInput:Q,warning:X.length>0?X.join(`
130
+ If the browser does not open automatically, copy and paste this URL:`),console.log(Q),console.log("");let X=this.startCallbackServer(Y.state);try{await this.openAuthorizationUrl(Q)}catch(q){console.warn("[OAuth] Failed to open browser automatically:",q)}let J=await X;console.log("[OAuth] Authorization code received, exchanging for tokens...");let G=await this.exchangeCodeForToken(Z,J,Y.codeVerifier),K={accessToken:G.access_token,tokenType:G.token_type||"Bearer",refreshToken:G.refresh_token,scope:G.scope};if(G.expires_in)K.expiresAt=Date.now()+G.expires_in*1000;return await this.tokenStorage.saveToken($,K,Z.clientId,Z.tokenUrl),console.log("[OAuth] Authentication successful! Token saved."),K}async openAuthorizationUrl($){let{command:Z,args:Y}=this.getBrowserCommand($);await new Promise((Q,X)=>{let J=JF(Z,Y,{stdio:"ignore"});J.once("error",X),J.once("close",(G)=>{if(G===0||G===null)Q();else X(Error(`Failed to open browser (exit code ${G})`))})})}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($,Z){let Y=await this.tokenStorage.getCredentials($);if(!Y)return null;let{token:Q}=Y;if(!this.tokenStorage.isTokenExpired(Q))return Q.accessToken;if(Q.refreshToken&&Z.clientId&&Y.tokenUrl)try{console.log(`[OAuth] Refreshing expired token for server: ${$}`);let X=await this.refreshAccessToken(Z,Q.refreshToken),J={accessToken:X.access_token,tokenType:X.token_type,refreshToken:X.refresh_token||Q.refreshToken,scope:X.scope||Q.scope};if(X.expires_in)J.expiresAt=Date.now()+X.expires_in*1000;return await this.tokenStorage.saveToken($,J,Z.clientId,Y.tokenUrl),J.accessToken}catch(X){console.error("[OAuth] Failed to refresh token:",X),await this.tokenStorage.deleteCredentials($)}return null}}var x8=7777,Y7="/oauth/callback",wQ=200;var bQ=A(()=>{BQ()});var AQ=A(()=>{bQ()});var x2=()=>{};import{EventEmitter as GF}from"events";var Q7;var RQ=A(()=>{x2();Q7=class Q7 extends GF{client;config;checkTimer=null;isChecking=!1;consecutiveFailures=0;lastCheckTime=0;currentStatus="healthy";constructor($,Z={}){super();this.client=$,this.config={interval:Z.interval??30000,timeout:Z.timeout??1e4,enabled:Z.enabled??!1,failureThreshold:Z.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 Z={status:"healthy",timestamp:Date.now(),consecutiveFailures:0};return this.emit("healthCheck",Z),Z}else throw Error(`连接状态异常: ${$}`)}catch($){this.consecutiveFailures++;let Z=$;console.warn(`[HealthMonitor] 健康检查失败(${this.consecutiveFailures}/${this.config.failureThreshold}):`,Z.message);let Y;if(this.consecutiveFailures>=this.config.failureThreshold)Y="unhealthy",this.emit("unhealthy",this.consecutiveFailures,Z),console.log("[HealthMonitor] 达到失败阈值,触发重连..."),this.triggerReconnection().catch((X)=>{console.error("[HealthMonitor] 重连失败:",X)});else Y="degraded";this.setStatus(Y);let Q={status:Y,timestamp:Date.now(),consecutiveFailures:this.consecutiveFailures,lastError:Z};return this.emit("healthCheck",Q),Q}finally{this.isChecking=!1}}async pingServer(){let $=new Promise((Y,Q)=>{setTimeout(()=>Q(Error("Health check timeout")),this.config.timeout)}),Z=(async()=>{if(this.client.availableTools.length===0){if(!this.client.server)throw Error("Server info not available")}})();await Promise.race([Z,$])}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 Z=this.currentStatus;this.currentStatus=$,this.emit("statusChanged",$,Z)}}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 KF}from"@modelcontextprotocol/sdk/client/index.js";import{SSEClientTransport as qF}from"@modelcontextprotocol/sdk/client/sse.js";import{StdioClientTransport as WF}from"@modelcontextprotocol/sdk/client/stdio.js";import{EventEmitter as UF}from"events";function VQ($){if(!($ instanceof Error))return{type:"unknown",isRetryable:!1,originalError:Error(String($))};let Z=$.message.toLowerCase();if(["command not found","no such file","permission denied","invalid configuration","malformed","syntax error"].some((X)=>Z.includes(X)))return{type:"config_error",isRetryable:!1,originalError:$};if(Z.includes("unauthorized")||Z.includes("401")||Z.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((X)=>Z.includes(X)))return{type:"network_temporary",isRetryable:!0,originalError:$};return{type:"unknown",isRetryable:!0,originalError:$}}var X7;var DQ=A(()=>{P8();AQ();RQ();x2();X7=class X7 extends UF{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($,Z,Y){super();this.config=$;if(this.serverName=Z||"default",$.oauth?.enabled)this.oauthProvider=new p3;if(Y?.enabled)this.healthMonitor=new Q7(this,Y),this.healthMonitor.on("unhealthy",(Q,X)=>{this.emit("unhealthy",Q,X)}),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,Z=1000){if(this.status!=="disconnected"&&this.status!=="error")throw Error("客户端已连接或正在连接中");if(this.status==="error"){if(this.sdkClient){try{await this.sdkClient.close()}catch{}this.sdkClient=null}this.setStatus("disconnected")}let Y=null;for(let Q=1;Q<=$;Q++)try{await this.doConnect(),this.reconnectAttempts=0;return}catch(X){Y=X;let J=VQ(X);if(!J.isRetryable)throw console.error("[McpClient] 检测到永久性错误,放弃重试:",J.type),X;if(Q<$){let G=Z*Math.pow(2,Q-1);console.warn(`[McpClient] 连接失败(${Q}/${$}),${G}ms 后重试...`),await new Promise((K)=>setTimeout(K,G))}}throw Y||Error("连接失败")}async doConnect(){try{this.setStatus("connecting"),this.sdkClient=new KF({name:LY(),version:v2()},{capabilities:{roots:{listChanged:!0},sampling:{}}}),this.sdkClient.onclose=()=>{this.handleUnexpectedClose()};let $=await this.createTransport();await this.sdkClient.connect($);let Z=this.sdkClient.getServerVersion();if(this.serverInfo={name:Z?.name||"Unknown",version:Z?.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(Z){if(console.error("[McpClient] 重连失败:",Z),VQ(Z).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($,Z={}){if(!this.sdkClient)throw Error("客户端未连接到服务器");if(!this.tools.has($))throw Error(`工具 "${$}" 不存在`);try{return await this.sdkClient.callTool({name:$,arguments:Z})}catch(Y){throw console.error(`[McpClient] 调用工具 "${$}" 失败:`,Y),Y}}async createTransport(){let{type:$,command:Z,args:Y,env:Q,url:X,headers:J,oauth:G}=this.config,K={...J};if(G?.enabled&&this.oauthProvider&&($==="sse"||$==="http"))try{let q=await this.oauthProvider.getValidToken(this.serverName,G);if(!q){console.log(`[McpClient] 服务器 "${this.serverName}" 需要 OAuth 认证`);let W=await this.oauthProvider.authenticate(this.serverName,G);K.Authorization=`Bearer ${W.accessToken}`}else K.Authorization=`Bearer ${q}`}catch(q){throw console.error("[McpClient] OAuth 认证失败:",q),Error(`OAuth 认证失败: ${q instanceof Error?q.message:String(q)}`)}if($==="stdio"){if(!Z)throw Error("stdio 传输需要 command 参数");let q={};for(let[W,U]of Object.entries(process.env))if(U!==void 0)q[W]=U;return new WF({command:Z,args:Y||[],env:{...q,...Q},stderr:"ignore"})}else if($==="sse"){if(!X)throw Error("sse 传输需要 url 参数");return new qF(new URL(X),{requestInit:{headers:K}})}else if($==="http"){if(!X)throw Error("http 传输需要 url 参数");let{StreamableHTTPClientTransport:q}=await import("@modelcontextprotocol/sdk/client/streamableHttp.js");return new q(new URL(X),{requestInit:{headers:K}})}throw Error(`不支持的传输类型: ${$}`)}async loadTools(){if(!this.sdkClient)return;try{let $=await this.sdkClient.listTools();if(this.tools.clear(),$.tools)for(let Z of $.tools)this.tools.set(Z.name,Z);this.emit("toolsUpdated",this.availableTools)}catch($){throw console.error("[McpClient] 加载工具失败:",$),$}}setStatus($){let Z=this.status;this.status=$,this.emit("statusChanged",$,Z)}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($,Z){if(!this.sdkClient)throw Error("客户端未连接");return(await this.sdkClient.readResource({uri:$})).contents?.[0]||{uri:$,text:""}}}});import{EventEmitter as HF}from"events";var b0;var e4=A(()=>{_Q();DQ();x2();b0=class b0 extends HF{static instance=null;servers=new Map;isDiscovering=!1;constructor(){super()}static getInstance(){if(!b0.instance)b0.instance=new b0;return b0.instance}async registerServer($,Z){if(this.servers.has($))throw Error(`MCP服务器 "${$}" 已经注册`);let Y=new X7(Z,$,Z.healthCheck),Q={config:Z,client:Y,status:"disconnected",tools:[]};this.setupClientEventHandlers(Y,Q,$),this.servers.set($,Q),this.emit("serverRegistered",$,Q);try{await this.connectServer($)}catch(X){console.warn(`MCP服务器 "${$}" 连接失败:`,X)}}async unregisterServer($){let Z=this.servers.get($);if(!Z)return;try{await Z.client.disconnect()}catch(Y){console.warn(`断开MCP服务器 "${$}" 时出错:`,Y)}this.servers.delete($),this.emit("serverUnregistered",$)}async connectServer($){let Z=this.servers.get($);if(!Z)throw Error(`MCP服务器 "${$}" 未注册`);if(Z.status==="connected")return;try{Z.status="connecting",await Z.client.connect(),Z.connectedAt=new Date,Z.lastError=void 0,Z.tools=Z.client.availableTools}catch(Y){throw Z.lastError=Y,Z.status="error",Y}}async disconnectServer($){let Z=this.servers.get($);if(!Z)return;await Z.client.disconnect(),Z.connectedAt=void 0}async reconnectServer($){let Z=this.servers.get($);if(!Z)throw Error(`MCP服务器 "${$}" 未注册`);if(Z.status==="connected")await Z.client.disconnect();try{Z.status="connecting",await Z.client.connect(),Z.connectedAt=new Date,Z.lastError=void 0,Z.tools=Z.client.availableTools}catch(Y){throw Z.lastError=Y,Z.status="error",Y}}async getAvailableTools(){let $=[],Z=new Map;for(let[Y,Q]of this.servers)if(Q.status==="connected")for(let X of Q.tools){let J=Z.get(X.name)||0;Z.set(X.name,J+1)}for(let[Y,Q]of this.servers)if(Q.status==="connected")for(let X of Q.tools){let G=(Z.get(X.name)||0)>1?`${Y}__${X.name}`:X.name,K=x3(Q.client,Y,X,G);$.push(K)}return $}async findTool($){for(let[Z,Y]of this.servers)if(Y.status==="connected"){let Q=Y.tools.find((X)=>X.name===$);if(Q)return x3(Y.client,Z,Q)}return null}getToolsByServer($){let Z=this.servers.get($);if(!Z||Z.status!=="connected")return[];return Z.tools.map((Y)=>x3(Z.client,$,Y))}getServerStatus($){return this.servers.get($)||null}getAllServers(){return new Map(this.servers)}async refreshAllTools(){let $=[];for(let[Z,Y]of this.servers)if(Y.status==="connected")$.push(this.refreshServerTools(Z));await Promise.allSettled($)}async refreshServerTools($){let Z=this.servers.get($);if(!Z||Z.status!=="connected")return;try{let Y=Z.client.availableTools,Q=Z.tools.length;Z.tools=Y,this.emit("toolsUpdated",$,Y,Q)}catch(Y){console.warn(`刷新服务器 "${$}" 工具列表失败:`,Y)}}setupClientEventHandlers($,Z,Y){$.on("connected",(Q)=>{Z.status="connected",Z.connectedAt=new Date,Z.tools=$.availableTools,this.emit("serverConnected",Y,Q)}),$.on("disconnected",()=>{Z.status="disconnected",Z.connectedAt=void 0,Z.tools=[],this.emit("serverDisconnected",Y)}),$.on("error",(Q)=>{Z.status="error",Z.lastError=Q,this.emit("serverError",Y,Q)}),$.on("toolsUpdated",(Q)=>{let X=Z.tools.length;Z.tools=Q,this.emit("toolsUpdated",Y,Q,X)}),$.on("statusChanged",(Q,X)=>{Z.status=Q,this.emit("serverStatusChanged",Y,Q,X)})}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 Z=Object.entries($).map(([Y,Q])=>this.registerServer(Y,Q).catch((X)=>{return console.warn(`注册MCP服务器 "${Y}" 失败:`,X),X}));await Promise.allSettled(Z)}getStatistics(){let $=0,Z=0,Y=0;for(let Q of this.servers.values())if(Q.status==="connected")$++,Z+=Q.tools.length;else if(Q.status==="error")Y++;return{totalServers:this.servers.size,connectedServers:$,errorServers:Y,totalTools:Z,isDiscovering:this.isDiscovering}}async disconnectAll(){let $=[];for(let[Z,Y]of this.servers)if(Y.status==="connected")$.push(Y.client.disconnect().catch((Q)=>{console.warn(`断开 MCP 服务器 "${Z}" 时出错:`,Q)}));await Promise.allSettled($),this.servers.clear()}}});function K7($,Z){return{...$,...Z,PreToolUse:Z.PreToolUse??$.PreToolUse,PostToolUse:Z.PostToolUse??$.PostToolUse,PostToolUseFailure:Z.PostToolUseFailure??$.PostToolUseFailure,PermissionRequest:Z.PermissionRequest??$.PermissionRequest,UserPromptSubmit:Z.UserPromptSubmit??$.UserPromptSubmit,SessionStart:Z.SessionStart??$.SessionStart,SessionEnd:Z.SessionEnd??$.SessionEnd,Stop:Z.Stop??$.Stop,SubagentStop:Z.SubagentStop??$.SubagentStop,Notification:Z.Notification??$.Notification,Compaction:Z.Compaction??$.Compaction}}function IQ(){let $={};if(process.env.BLADE_DISABLE_HOOKS==="true")$.enabled=!1;if(process.env.BLADE_HOOK_TIMEOUT){let Z=parseInt(process.env.BLADE_HOOK_TIMEOUT,10);if(!isNaN(Z)&&Z>0)$.defaultTimeout=Z}return $}var G7;var yQ=A(()=>{G7={enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,PreToolUse:[],PostToolUse:[],PostToolUseFailure:[],PermissionRequest:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]}});class q7{executedHooks=new Map;canExecute($,Z){if(!this.executedHooks.has($))this.executedHooks.set($,new Set);if(this.executedHooks.get($).has(Z))return console.warn(`[HookGuard] Hook ${Z} for tool ${$} already executed, skipping`),!1;return!0}markExecuted($,Z){let Y=this.executedHooks.get($);if(Y)Y.add(Z)}cleanup($){this.executedHooks.delete($)}cleanupAll(){this.executedHooks.clear()}}var x1,W7,U7;var m2=A(()=>{((H)=>{H.PreToolUse="PreToolUse";H.PostToolUse="PostToolUse";H.PostToolUseFailure="PostToolUseFailure";H.PermissionRequest="PermissionRequest";H.UserPromptSubmit="UserPromptSubmit";H.SessionStart="SessionStart";H.SessionEnd="SessionEnd";H.Stop="Stop";H.SubagentStop="SubagentStop";H.Notification="Notification";H.Compaction="Compaction"})(x1||={});((Q)=>{Q.Approve="approve";Q.Block="block";Q.Async="async"})(W7||={});((Q)=>{Q.Allow="allow";Q.Deny="deny";Q.Ask="ask"})(U7||={})});import{z as P}from"zod";function vQ($){let Z=mF.safeParse($);if(Z.success)return{success:!0,data:Z.data};return{success:!1,error:Z.error}}var j1,AF,RF,VF,DF,MF,jF,IF,yF,vF,EF,PF,QD,TF,CF,SF,kF,fF,hF,xF,pF,mF,dF,uF,gF,H7,cF,M1,XD;var EQ=A(()=>{m2();j1=P.object({hook_event_name:P.nativeEnum(x1),hook_execution_id:P.string(),timestamp:P.string(),project_dir:P.string(),session_id:P.string(),permission_mode:P.enum(["default","autoEdit","yolo","plan"]),_metadata:P.object({blade_version:P.string(),hook_timeout_ms:P.number()}).optional()}),AF=j1.extend({hook_event_name:P.literal("PreToolUse"),tool_name:P.string(),tool_use_id:P.string(),tool_input:P.record(P.unknown())}),RF=j1.extend({hook_event_name:P.literal("PostToolUse"),tool_name:P.string(),tool_use_id:P.string(),tool_input:P.record(P.unknown()),tool_response:P.unknown()}),VF=j1.extend({hook_event_name:P.literal("Stop"),reason:P.string().optional()}),DF=j1.extend({hook_event_name:P.literal("PostToolUseFailure"),tool_name:P.string(),tool_use_id:P.string(),tool_input:P.record(P.unknown()),error:P.string(),error_type:P.string().optional(),is_interrupt:P.boolean(),is_timeout:P.boolean()}),MF=j1.extend({hook_event_name:P.literal("PermissionRequest"),tool_name:P.string(),tool_use_id:P.string(),tool_input:P.record(P.unknown())}),jF=j1.extend({hook_event_name:P.literal("UserPromptSubmit"),user_prompt:P.string(),has_images:P.boolean(),image_count:P.number()}),IF=j1.extend({hook_event_name:P.literal("SessionStart"),is_resume:P.boolean(),resume_session_id:P.string().optional()}),yF=j1.extend({hook_event_name:P.literal("SessionEnd"),reason:P.enum(["user_exit","error","max_turns","idle_timeout","ctrl_c","clear","logout","other"])}),vF=j1.extend({hook_event_name:P.literal("SubagentStop"),agent_type:P.string(),task_description:P.string().optional(),success:P.boolean(),result_summary:P.string().optional(),error:P.string().optional()}),EF=j1.extend({hook_event_name:P.literal("Notification"),notification_type:P.enum(["permission_prompt","idle_prompt","auth_success","elicitation_dialog","info","warning","error"]),title:P.string().optional(),message:P.string()}),PF=j1.extend({hook_event_name:P.literal("Compaction"),trigger:P.enum(["manual","auto"]),messages_before:P.number(),tokens_before:P.number()}),QD=P.discriminatedUnion("hook_event_name",[AF,RF,VF,DF,MF,jF,IF,yF,vF,EF,PF]),TF=P.object({hookEventName:P.literal("PreToolUse"),permissionDecision:P.nativeEnum(U7).optional(),permissionDecisionReason:P.string().optional(),updatedInput:P.record(P.unknown()).optional()}),CF=P.object({hookEventName:P.literal("PostToolUse"),additionalContext:P.string().optional(),updatedOutput:P.unknown().optional()}),SF=P.object({hookEventName:P.literal("Stop"),continue:P.boolean().optional(),continueReason:P.string().optional()}),kF=P.object({hookEventName:P.literal("SubagentStop"),continue:P.boolean().optional(),continueReason:P.string().optional(),additionalContext:P.string().optional()}),fF=P.object({hookEventName:P.literal("PermissionRequest"),permissionDecision:P.enum(["approve","deny","ask"]).optional(),permissionDecisionReason:P.string().optional()}),hF=P.object({hookEventName:P.literal("UserPromptSubmit"),updatedPrompt:P.string().optional(),contextInjection:P.string().optional()}),xF=P.object({hookEventName:P.literal("SessionStart"),env:P.record(P.string()).optional()}),pF=P.object({hookEventName:P.literal("Compaction"),blockCompaction:P.boolean().optional(),blockReason:P.string().optional()}),mF=P.object({decision:P.object({behavior:P.nativeEnum(W7)}).optional(),systemMessage:P.string().optional(),hookSpecificOutput:P.discriminatedUnion("hookEventName",[TF,CF,SF,kF,fF,hF,xF,pF]).optional(),suppressOutput:P.boolean().optional()}),dF=P.object({type:P.literal("command"),command:P.string(),timeout:P.number().positive().optional(),statusMessage:P.string().optional()}),uF=P.object({type:P.literal("prompt"),prompt:P.string(),timeout:P.number().positive().optional()}),gF=P.discriminatedUnion("type",[dF,uF]),H7=P.union([P.string(),P.array(P.string())]),cF=P.object({tools:H7.optional(),paths:H7.optional(),commands:H7.optional()}),M1=P.object({name:P.string().optional(),matcher:cF.optional(),hooks:P.array(gF)}),XD=P.object({enabled:P.boolean().optional(),defaultTimeout:P.number().positive().optional(),timeoutBehavior:P.enum(["ignore","deny","ask"]).optional(),failureBehavior:P.enum(["ignore","deny","ask"]).optional(),maxConcurrentHooks:P.number().positive().optional(),PreToolUse:P.array(M1).optional(),PostToolUse:P.array(M1).optional(),PostToolUseFailure:P.array(M1).optional(),PermissionRequest:P.array(M1).optional(),UserPromptSubmit:P.array(M1).optional(),SessionStart:P.array(M1).optional(),SessionEnd:P.array(M1).optional(),Stop:P.array(M1).optional(),SubagentStop:P.array(M1).optional(),Notification:P.array(M1).optional(),Compaction:P.array(M1).optional()})});class F7{parse($,Z,Y){if($.timedOut){let X=Y?.timeoutBehavior||"ignore",J="Hook timeout";if(X==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z}}let Q=this.tryParseJSON($.stdout);if(Q){let X=vQ(Q);if(!X.success){let G="error"in X?X.error.message:"Unknown validation error",K=Y?.failureBehavior||"ignore",q=`Invalid hook output JSON: ${G}`;if(K==="deny")return{success:!1,blocking:!0,error:q,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else if(K==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${q}. Continue?`,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else return{success:!1,blocking:!1,warning:q,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z}}let J=X.data;if(J.decision?.behavior==="block")return{success:!1,blocking:!0,error:J.systemMessage||"Hook blocked execution",output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};if(J.decision?.behavior==="async")return{success:!0,output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};return{success:!0,output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z}}return this.parseByExitCode($,Z,Y)}parseByExitCode($,Z,Y){let Q=$.exitCode;switch(Q){case 0:return{success:!0,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};case 2:return{success:!1,blocking:!0,error:$.stderr||$.stdout||"Hook returned exit code 2",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};case 124:{let X=Y?.timeoutBehavior||"ignore",J="Hook timeout";if(X==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z}}default:{let X=Y?.failureBehavior||"ignore",J=$.stderr||$.stdout||`Hook failed with exit code ${Q}`;if(X==="deny")return{success:!1,blocking:!0,error:J,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${J}. Continue?`,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else return{success:!1,blocking:!1,warning:J,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z}}}}tryParseJSON($){try{let Z=$.trim();if(!Z)return null;let Y=Z.match(/^\s*(\{[\s\S]*\})\s*$/);if(!Y)return null;return JSON.parse(Y[1])}catch{return null}}}var PQ=A(()=>{EQ()});import{spawn as lF}from"child_process";class O7{content="";maxSize;constructor($){this.maxSize=$}append($){if(this.content.length<this.maxSize){let Z=this.maxSize-this.content.length;this.content+=$.substring(0,Z)}}getContent(){return this.content}isFull(){return this.content.length>=this.maxSize}}class z7{MAX_STDOUT_SIZE=1048576;MAX_STDERR_SIZE=1048576;MAX_INPUT_SIZE=102400;async execute($,Z,Y,Q){let X=JSON.stringify(Z);if(X.length>this.MAX_INPUT_SIZE)throw Error(`Hook input too large: ${X.length} bytes (max ${this.MAX_INPUT_SIZE})`);let J=this.createSafeEnv(Z),G=lF($,[],{shell:!0,env:J,cwd:Y.projectDir,timeout:Q}),K=new O7(this.MAX_STDOUT_SIZE),q=new O7(this.MAX_STDERR_SIZE);G.stdout.setEncoding("utf8"),G.stderr.setEncoding("utf8"),G.stdout.on("data",(W)=>{K.append(W)}),G.stderr.on("data",(W)=>{q.append(W)});try{G.stdin.write(X),G.stdin.end()}catch(W){throw G.kill("SIGTERM"),Error(`Failed to write hook input: ${W}`)}return new Promise((W,U)=>{let H=!1,F=!1,O=null,z=()=>{if(O&&Y.abortSignal)Y.abortSignal.removeEventListener("abort",O),O=null},_=setTimeout(()=>{H=!0,G.kill("SIGKILL")},Q);if(G.on("close",(B)=>{if(F)return;F=!0,clearTimeout(_),z(),W({stdout:K.getContent(),stderr:q.getContent(),exitCode:H?124:B??1,timedOut:H})}),G.on("error",(B)=>{if(F)return;F=!0,clearTimeout(_),z(),U(B)}),Y.abortSignal)O=()=>{if(F)return;F=!0,clearTimeout(_),z(),G.kill("SIGTERM"),W({stdout:K.getContent(),stderr:"Hook cancelled by abort signal",exitCode:1,timedOut:!1})},Y.abortSignal.addEventListener("abort",O)})}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 TQ=()=>{};class _7{processExecutor=new z7;outputParser=new F7;async executePreToolHooks($,Z,Y){if($.length===0)return{decision:"allow"};let Q="tool_input"in Z?Z.tool_input:{},X=[];for(let J of $)try{let G={...Z,...Q&&{tool_input:Q}},K=await this.executeHook(J,G,Y);if(!K.success){if(K.blocking)return{decision:"deny",reason:K.error};if(K.needsConfirmation)return{decision:"ask",reason:K.warning||K.error};if(K.warning)X.push(K.warning);continue}let q=K.output?.hookSpecificOutput;if(q&&"permissionDecision"in q){switch(q.permissionDecision){case"deny":return{decision:"deny",reason:q.permissionDecisionReason};case"ask":return{decision:"ask",reason:q.permissionDecisionReason};case"allow":break}if("updatedInput"in q&&q.updatedInput)Q={...Q,...q.updatedInput}}}catch(G){let K=G instanceof Error?G.message:String(G);if(X.push(`Hook failed: ${K}`),Y.config.failureBehavior==="deny")return{decision:"deny",reason:K};else if(Y.config.failureBehavior==="ask")return{decision:"ask",reason:`Hook failed: ${K}. Continue?`}}return{decision:"allow",modifiedInput:Q,warning:X.length>0?X.join(`
131
131
  `):void 0}}async executePostToolHooks($,Z,Y){if($.length===0)return{};let Q=Y.config.maxConcurrentHooks||5,X=await this.executeHooksConcurrently($,Z,Y,Q),J=[],G=void 0,K=[];for(let q of X){if(!q.success&&q.warning){K.push(q.warning);continue}let W=q.output?.hookSpecificOutput;if(W&&"additionalContext"in W){if(W.additionalContext)J.push(W.additionalContext);if("updatedOutput"in W&&W.updatedOutput!==void 0)G=W.updatedOutput}}return{additionalContext:J.length>0?J.join(`
132
132
 
133
133
  `):void 0,modifiedOutput:G,warning:K.length>0?K.join(`
@@ -150,12 +150,12 @@ If the browser does not open automatically, copy and paste this URL:`),console.l
150
150
  `):void 0}}async executeNotificationHooks($,Z,Y){let Q="message"in Z?Z.message:"";if($.length===0)return{suppress:!1,message:Q};let X=[],J=!1,G=Q;for(let K of $)try{let q=await this.executeHook(K,Z,Y);if(!q.success){if(q.warning)X.push(q.warning);continue}if(q.output?.suppressOutput){J=!0;break}if(q.stdout&&q.stdout.trim())G=q.stdout.trim()}catch(q){let W=q instanceof Error?q.message:String(q);X.push(`Hook failed: ${W}`)}return{suppress:J,message:G,warning:X.length>0?X.join(`
151
151
  `):void 0}}async executeCompactionHooks($,Z,Y){if($.length===0)return{blockCompaction:!1};let Q=[];for(let X of $)try{let J=await this.executeHook(X,Z,Y);if(!J.success){if(J.warning)Q.push(J.warning);continue}let G=J.output?.hookSpecificOutput;if(G&&"blockCompaction"in G&&G.blockCompaction)return{blockCompaction:!0,blockReason:G.blockReason,warning:Q.length>0?Q.join(`
152
152
  `):void 0}}catch(J){let G=J instanceof Error?J.message:String(J);Q.push(`Hook failed: ${G}`)}return{blockCompaction:!1,warning:Q.length>0?Q.join(`
153
- `):void 0}}async executeHook($,Z,Y){if($.type==="command")return this.executeCommandHook($,Z,Y);throw Error(`Hook type ${$.type} not yet implemented`)}async executeCommandHook($,Z,Y){let Q=($.timeout??Y.config.defaultTimeout??60)*1000;try{let X=await this.processExecutor.execute($.command,Z,Y,Q);return this.outputParser.parse(X,$,{timeoutBehavior:Y.config.timeoutBehavior,failureBehavior:Y.config.failureBehavior})}catch(X){return{success:!1,blocking:!1,error:X instanceof Error?X.message:String(X),hook:$}}}async executeHooksConcurrently($,Z,Y,Q){let X=[],J=new Set;for(let G of $){if(J.size>=Q)await Promise.race(J);let K=this.executeHook(G,Z,Y).catch((W)=>({success:!1,blocking:!1,error:W instanceof Error?W.message:String(W),hook:G})),q=K.then(()=>{J.delete(q)}).catch(()=>{J.delete(q)});J.add(q),X.push(K)}return Promise.all(X)}}var CQ=A(()=>{PQ();TQ();m4()});import B7 from"picomatch";class L7{matches($,Z){if(!$)return!0;if($.tools&&Z.toolName){if(!this.matchTools($.tools,Z))return!1}if($.paths&&Z.filePath){if(!this.matchPaths($.paths,Z.filePath))return!1}if($.commands&&Z.command){if(!this.matchCommands($.commands,Z.command))return!1}return!0}matchTools($,Z){if(Array.isArray($))return $.some((Y)=>this.matchToolWithParams(Y,Z));return this.matchToolWithParams($,Z)}matchPaths($,Z){if(Array.isArray($))return $.some((Q)=>{return B7(Q)(Z)});return B7($)(Z)}matchCommands($,Z){if(Array.isArray($))return $.some((Y)=>this.matchPattern(Z,Y));return this.matchPattern(Z,$)}matchToolWithParams($,Z){let{toolName:Y,command:Q,filePath:X}=Z,J=iF.exec($);if(!J)return this.matchPattern(Y,$);let[,G,K]=J;if(!this.matchPattern(Y,G))return!1;let q=this.getArgValue(Y,Q,X);if(!q)return!1;return this.matchGlobOrPattern(q,K)}getArgValue($,Z,Y){if($==="Bash"||$==="BashTool")return Z;if(["Read","Edit","Write","Glob","Grep"].includes($))return Y;return Z||Y}matchGlobOrPattern($,Z){if(/[*?[\]{}!]/.test(Z))try{return B7(Z,{bash:!0,dot:!0})($)}catch{}if(Z.endsWith("*")){let Y=Z.slice(0,-1);return $.startsWith(Y)}return $===Z}matchPattern($,Z){if(Z==="*")return!0;if(!Z.includes("|")&&!/[.*+?^${}()|[\]\\]/.test(Z))return $===Z;if(Z.includes("|"))return Z.split("|").map((Q)=>Q.trim()).includes($);try{return new RegExp(Z).test($)}catch{return $===Z}}}var iF;var SQ=A(()=>{iF=/^([A-Za-z0-9_|]+)\((.+)\)$/});import{nanoid as I1}from"nanoid";class M${static instance=null;config=G7;executor=new _7;guard=new q7;matcher=new L7;sessionDisabled=!1;constructor(){}static getInstance(){if(!M$.instance)M$.instance=new M$;return M$.instance}loadConfig($){let Z=K7(G7,$),Y=IQ();Z=K7(Z,Y),this.config=Z}isEnabled(){if(!this.config.enabled)return!1;if(this.sessionDisabled)return!1;return!0}disable(){this.sessionDisabled=!0,console.log("[HookManager] Hooks disabled for this session")}enable(){this.sessionDisabled=!1,console.log("[HookManager] Hooks enabled for this session")}getConfig(){return this.config}async reloadConfig(){let $=await import("node:fs/promises"),Z=await import("node:path");try{let Y=Z.join(process.cwd(),".blade","settings.local.json"),Q=await $.readFile(Y,"utf-8"),X=JSON.parse(Q);if(X.hooks)this.loadConfig(X.hooks)}catch{}}async executePreToolHooks($,Z,Y,Q){if(!this.isEnabled())return{decision:"allow"};if(Q.permissionMode==="plan")return{decision:"allow"};if(!this.guard.canExecute(Z,"PreToolUse"))return{decision:"allow"};let X={hook_event_name:"PreToolUse",hook_execution_id:I1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,project_dir:Q.projectDir,session_id:Q.sessionId,permission_mode:Q.permissionMode},J=this.getMatchingHooks("PreToolUse",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(J.length===0)return{decision:"allow"};let G={projectDir:Q.projectDir,sessionId:Q.sessionId,permissionMode:Q.permissionMode,config:this.config,abortSignal:Q.abortSignal};try{let K=await this.executor.executePreToolHooks(J,X,G);if(this.guard.markExecuted(Z,"PreToolUse"),Q.permissionMode==="yolo"){if(K.decision==="deny")return K;return{decision:"allow",modifiedInput:K.modifiedInput,warning:K.warning,reason:K.reason}}return K}catch(K){return console.error("[HookManager] Error executing PreToolUse hooks:",K),{decision:"allow",warning:`Hook execution failed: ${K instanceof Error?K.message:String(K)}`}}}async executePostToolHooks($,Z,Y,Q,X){if(!this.isEnabled())return{};if(X.permissionMode==="plan")return{};if(!this.guard.canExecute(Z,"PostToolUse"))return{};let J={hook_event_name:"PostToolUse",hook_execution_id:I1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,tool_response:Q,project_dir:X.projectDir,session_id:X.sessionId,permission_mode:X.permissionMode},G=this.getMatchingHooks("PostToolUse",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(G.length===0)return{};let K={projectDir:X.projectDir,sessionId:X.sessionId,permissionMode:X.permissionMode,config:this.config,abortSignal:X.abortSignal};try{let q=await this.executor.executePostToolHooks(G,J,K);return this.guard.markExecuted(Z,"PostToolUse"),q}catch(q){return console.error("[HookManager] Error executing PostToolUse hooks:",q),{warning:`Hook execution failed: ${q instanceof Error?q.message:String(q)}`}}finally{this.guard.cleanup(Z)}}async executeStopHooks($){if(!this.isEnabled())return{shouldStop:!0};let Z={hook_event_name:"Stop",hook_execution_id:I1(),timestamp:new Date().toISOString(),project_dir:$.projectDir,session_id:$.sessionId,permission_mode:$.permissionMode,reason:$.reason},Y=this.getMatchingHooks("Stop",{});if(Y.length===0)return{shouldStop:!0};let Q={projectDir:$.projectDir,sessionId:$.sessionId,permissionMode:$.permissionMode,config:this.config,abortSignal:$.abortSignal};try{return await this.executor.executeStopHooks(Y,Z,Q)}catch(X){return console.error("[HookManager] Error executing Stop hooks:",X),{shouldStop:!0,warning:`Hook execution failed: ${X instanceof Error?X.message:String(X)}`}}}async executeSubagentStopHooks($,Z){if(!this.isEnabled())return{shouldStop:!0};let Y={hook_event_name:"SubagentStop",hook_execution_id:I1(),timestamp:new Date().toISOString(),project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode,agent_type:$,task_description:Z.taskDescription,success:Z.success,result_summary:Z.resultSummary,error:Z.error},Q=this.getMatchingHooks("SubagentStop",{});if(Q.length===0)return{shouldStop:!0};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeSubagentStopHooks(Q,Y,X)}catch(J){return console.error("[HookManager] Error executing SubagentStop hooks:",J),{shouldStop:!0,warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executePermissionRequestHooks($,Z,Y,Q){if(!this.isEnabled())return{decision:"ask"};let X={hook_event_name:"PermissionRequest",hook_execution_id:I1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,project_dir:Q.projectDir,session_id:Q.sessionId,permission_mode:Q.permissionMode},J=this.getMatchingHooks("PermissionRequest",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(J.length===0)return{decision:"ask"};let G={projectDir:Q.projectDir,sessionId:Q.sessionId,permissionMode:Q.permissionMode,config:this.config,abortSignal:Q.abortSignal};try{return await this.executor.executePermissionRequestHooks(J,X,G)}catch(K){return console.error("[HookManager] Error executing PermissionRequest hooks:",K),{decision:"ask",warning:`Hook execution failed: ${K instanceof Error?K.message:String(K)}`}}}async executeUserPromptSubmitHooks($,Z){if(!this.isEnabled())return{proceed:!0};let Y={hook_event_name:"UserPromptSubmit",hook_execution_id:I1(),timestamp:new Date().toISOString(),user_prompt:$,has_images:Z.hasImages,image_count:Z.imageCount,project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode},Q=this.getMatchingHooks("UserPromptSubmit",{});if(Q.length===0)return{proceed:!0};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeUserPromptSubmitHooks(Q,Y,X)}catch(J){return console.error("[HookManager] Error executing UserPromptSubmit hooks:",J),{proceed:!0,warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executeSessionStartHooks($){if(!this.isEnabled())return{proceed:!0};let Z={hook_event_name:"SessionStart",hook_execution_id:I1(),timestamp:new Date().toISOString(),project_dir:$.projectDir,session_id:$.sessionId,permission_mode:$.permissionMode,is_resume:$.isResume,resume_session_id:$.resumeSessionId},Y=this.getMatchingHooks("SessionStart",{});if(Y.length===0)return{proceed:!0};let Q={projectDir:$.projectDir,sessionId:$.sessionId,permissionMode:$.permissionMode,config:this.config,abortSignal:$.abortSignal};try{return await this.executor.executeSessionStartHooks(Y,Z,Q)}catch(X){return console.error("[HookManager] Error executing SessionStart hooks:",X),{proceed:!0,warning:`Hook execution failed: ${X instanceof Error?X.message:String(X)}`}}}async executeSessionEndHooks($,Z){if(!this.isEnabled())return{};let Y={hook_event_name:"SessionEnd",hook_execution_id:I1(),timestamp:new Date().toISOString(),project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode,reason:$},Q=this.getMatchingHooks("SessionEnd",{});if(Q.length===0)return{};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeSessionEndHooks(Q,Y,X),{}}catch(J){return console.error("[HookManager] Error executing SessionEnd hooks:",J),{warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executePostToolUseFailureHooks($,Z,Y,Q,X){if(!this.isEnabled())return{};let J={hook_event_name:"PostToolUseFailure",hook_execution_id:I1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,error:Q,error_type:X.errorType,is_interrupt:X.isInterrupt,is_timeout:X.isTimeout,project_dir:X.projectDir,session_id:X.sessionId,permission_mode:X.permissionMode},G=this.getMatchingHooks("PostToolUseFailure",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(G.length===0)return{};let K={projectDir:X.projectDir,sessionId:X.sessionId,permissionMode:X.permissionMode,config:this.config,abortSignal:X.abortSignal};try{return await this.executor.executePostToolUseFailureHooks(G,J,K)}catch(q){return console.error("[HookManager] Error executing PostToolUseFailure hooks:",q),{warning:`Hook execution failed: ${q instanceof Error?q.message:String(q)}`}}}async executeNotificationHooks($,Z,Y){if(!this.isEnabled())return{suppress:!1,message:Z};let Q={hook_event_name:"Notification",hook_execution_id:I1(),timestamp:new Date().toISOString(),project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode,notification_type:$,title:Y.title,message:Z},X=this.getMatchingHooks("Notification",{});if(X.length===0)return{suppress:!1,message:Z};let J={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:this.config,abortSignal:Y.abortSignal};try{return await this.executor.executeNotificationHooks(X,Q,J)}catch(G){return console.error("[HookManager] Error executing Notification hooks:",G),{suppress:!1,message:Z,warning:`Hook execution failed: ${G instanceof Error?G.message:String(G)}`}}}async executeCompactionHooks($,Z){if(!this.isEnabled())return{blockCompaction:!1};let Y={hook_event_name:"Compaction",hook_execution_id:I1(),timestamp:new Date().toISOString(),project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode,trigger:$,messages_before:Z.messagesBefore,tokens_before:Z.tokensBefore},Q=this.getMatchingHooks("Compaction",{});if(Q.length===0)return{blockCompaction:!1};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeCompactionHooks(Q,Y,X)}catch(J){return console.error("[HookManager] Error executing Compaction hooks:",J),{blockCompaction:!1,warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}getMatchingHooks($,Z){let Y=this.config[$]||[],Q=[];for(let X of Y)if(this.matcher.matches(X.matcher,Z))Q.push(...X.hooks);return Q}extractFilePath($){let Z=["file_path","path","filePath","source","target"];for(let Y of Z){let Q=$[Y];if(typeof Q==="string")return Q}return}extractCommand($,Z){if($==="Bash"||$==="BashTool"){let Y=Z.command;if(typeof Y==="string")return Y}return}cleanup(){this.guard.cleanupAll()}}var t0=A(()=>{yQ();CQ();SQ();m4()});function kQ(){return"blade-builtin-glm47"}function w7($){return $==="blade-free-tier"}function N7($){return w7($.apiKey)}function rF($){return{id:"blade-builtin-glm47",name:$.name,provider:$.provider,baseUrl:$.baseUrl,model:$.model,apiKey:$.apiKey,maxContextTokens:$.maxContextTokens,maxOutputTokens:$.maxOutputTokens,supportsThinking:$.supportsThinking}}function fQ(){return rF(aF[0])}var aF;var u8=A(()=>{aF=[{name:"✨ GLM-4.7 (内置免费)",provider:"openai-compatible",baseUrl:"https://open.bigmodel.cn/api/coding/paas/v4",model:"glm-4.7",apiKey:"blade-free-tier",description:"智谱 GLM-4.7 Thinking - 由 Blade 提供免费额度",maxContextTokens:204800,maxOutputTokens:16384,supportsThinking:!0}]});import hQ from"@anthropic-ai/sdk";function nF($){if($.startsWith("data:")){let Z=$.match(/^data:([^;,]+)/);if(Z){let Y=Z[1];if(Y==="image/jpeg"||Y==="image/png"||Y==="image/gif"||Y==="image/webp")return Y}}return"image/png"}function oF($){if($.startsWith("data:")){let Z=$.indexOf(",");if(Z!==-1)return $.slice(Z+1)}return $}function xQ($){let Z=new Set;for(let Y of $)if(Y.role==="assistant"&&Y.tool_calls)for(let Q of Y.tool_calls)Z.add(Q.id);return $.filter((Y)=>{if(Y.role==="tool"){if(!Y.tool_call_id)return!1;return Z.has(Y.tool_call_id)}return!0})}function b7($){if(typeof $==="string")return $;return $.filter((Z)=>Z.type==="text").map((Z)=>Z.text).join(`
153
+ `):void 0}}async executeHook($,Z,Y){if($.type==="command")return this.executeCommandHook($,Z,Y);throw Error(`Hook type ${$.type} not yet implemented`)}async executeCommandHook($,Z,Y){let Q=($.timeout??Y.config.defaultTimeout??60)*1000;try{let X=await this.processExecutor.execute($.command,Z,Y,Q);return this.outputParser.parse(X,$,{timeoutBehavior:Y.config.timeoutBehavior,failureBehavior:Y.config.failureBehavior})}catch(X){return{success:!1,blocking:!1,error:X instanceof Error?X.message:String(X),hook:$}}}async executeHooksConcurrently($,Z,Y,Q){let X=[],J=new Set;for(let G of $){if(J.size>=Q)await Promise.race(J);let K=this.executeHook(G,Z,Y).catch((W)=>({success:!1,blocking:!1,error:W instanceof Error?W.message:String(W),hook:G})),q=K.then(()=>{J.delete(q)}).catch(()=>{J.delete(q)});J.add(q),X.push(K)}return Promise.all(X)}}var CQ=A(()=>{PQ();TQ();m2()});import B7 from"picomatch";class L7{matches($,Z){if(!$)return!0;if($.tools&&Z.toolName){if(!this.matchTools($.tools,Z))return!1}if($.paths&&Z.filePath){if(!this.matchPaths($.paths,Z.filePath))return!1}if($.commands&&Z.command){if(!this.matchCommands($.commands,Z.command))return!1}return!0}matchTools($,Z){if(Array.isArray($))return $.some((Y)=>this.matchToolWithParams(Y,Z));return this.matchToolWithParams($,Z)}matchPaths($,Z){if(Array.isArray($))return $.some((Q)=>{return B7(Q)(Z)});return B7($)(Z)}matchCommands($,Z){if(Array.isArray($))return $.some((Y)=>this.matchPattern(Z,Y));return this.matchPattern(Z,$)}matchToolWithParams($,Z){let{toolName:Y,command:Q,filePath:X}=Z,J=iF.exec($);if(!J)return this.matchPattern(Y,$);let[,G,K]=J;if(!this.matchPattern(Y,G))return!1;let q=this.getArgValue(Y,Q,X);if(!q)return!1;return this.matchGlobOrPattern(q,K)}getArgValue($,Z,Y){if($==="Bash"||$==="BashTool")return Z;if(["Read","Edit","Write","Glob","Grep"].includes($))return Y;return Z||Y}matchGlobOrPattern($,Z){if(/[*?[\]{}!]/.test(Z))try{return B7(Z,{bash:!0,dot:!0})($)}catch{}if(Z.endsWith("*")){let Y=Z.slice(0,-1);return $.startsWith(Y)}return $===Z}matchPattern($,Z){if(Z==="*")return!0;if(!Z.includes("|")&&!/[.*+?^${}()|[\]\\]/.test(Z))return $===Z;if(Z.includes("|"))return Z.split("|").map((Q)=>Q.trim()).includes($);try{return new RegExp(Z).test($)}catch{return $===Z}}}var iF;var SQ=A(()=>{iF=/^([A-Za-z0-9_|]+)\((.+)\)$/});import{nanoid as I1}from"nanoid";class M${static instance=null;config=G7;executor=new _7;guard=new q7;matcher=new L7;sessionDisabled=!1;constructor(){}static getInstance(){if(!M$.instance)M$.instance=new M$;return M$.instance}loadConfig($){let Z=K7(G7,$),Y=IQ();Z=K7(Z,Y),this.config=Z}isEnabled(){if(!this.config.enabled)return!1;if(this.sessionDisabled)return!1;return!0}disable(){this.sessionDisabled=!0,console.log("[HookManager] Hooks disabled for this session")}enable(){this.sessionDisabled=!1,console.log("[HookManager] Hooks enabled for this session")}getConfig(){return this.config}async reloadConfig(){let $=await import("node:fs/promises"),Z=await import("node:path");try{let Y=Z.join(process.cwd(),".blade","settings.local.json"),Q=await $.readFile(Y,"utf-8"),X=JSON.parse(Q);if(X.hooks)this.loadConfig(X.hooks)}catch{}}async executePreToolHooks($,Z,Y,Q){if(!this.isEnabled())return{decision:"allow"};if(Q.permissionMode==="plan")return{decision:"allow"};if(!this.guard.canExecute(Z,"PreToolUse"))return{decision:"allow"};let X={hook_event_name:"PreToolUse",hook_execution_id:I1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,project_dir:Q.projectDir,session_id:Q.sessionId,permission_mode:Q.permissionMode},J=this.getMatchingHooks("PreToolUse",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(J.length===0)return{decision:"allow"};let G={projectDir:Q.projectDir,sessionId:Q.sessionId,permissionMode:Q.permissionMode,config:this.config,abortSignal:Q.abortSignal};try{let K=await this.executor.executePreToolHooks(J,X,G);if(this.guard.markExecuted(Z,"PreToolUse"),Q.permissionMode==="yolo"){if(K.decision==="deny")return K;return{decision:"allow",modifiedInput:K.modifiedInput,warning:K.warning,reason:K.reason}}return K}catch(K){return console.error("[HookManager] Error executing PreToolUse hooks:",K),{decision:"allow",warning:`Hook execution failed: ${K instanceof Error?K.message:String(K)}`}}}async executePostToolHooks($,Z,Y,Q,X){if(!this.isEnabled())return{};if(X.permissionMode==="plan")return{};if(!this.guard.canExecute(Z,"PostToolUse"))return{};let J={hook_event_name:"PostToolUse",hook_execution_id:I1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,tool_response:Q,project_dir:X.projectDir,session_id:X.sessionId,permission_mode:X.permissionMode},G=this.getMatchingHooks("PostToolUse",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(G.length===0)return{};let K={projectDir:X.projectDir,sessionId:X.sessionId,permissionMode:X.permissionMode,config:this.config,abortSignal:X.abortSignal};try{let q=await this.executor.executePostToolHooks(G,J,K);return this.guard.markExecuted(Z,"PostToolUse"),q}catch(q){return console.error("[HookManager] Error executing PostToolUse hooks:",q),{warning:`Hook execution failed: ${q instanceof Error?q.message:String(q)}`}}finally{this.guard.cleanup(Z)}}async executeStopHooks($){if(!this.isEnabled())return{shouldStop:!0};let Z={hook_event_name:"Stop",hook_execution_id:I1(),timestamp:new Date().toISOString(),project_dir:$.projectDir,session_id:$.sessionId,permission_mode:$.permissionMode,reason:$.reason},Y=this.getMatchingHooks("Stop",{});if(Y.length===0)return{shouldStop:!0};let Q={projectDir:$.projectDir,sessionId:$.sessionId,permissionMode:$.permissionMode,config:this.config,abortSignal:$.abortSignal};try{return await this.executor.executeStopHooks(Y,Z,Q)}catch(X){return console.error("[HookManager] Error executing Stop hooks:",X),{shouldStop:!0,warning:`Hook execution failed: ${X instanceof Error?X.message:String(X)}`}}}async executeSubagentStopHooks($,Z){if(!this.isEnabled())return{shouldStop:!0};let Y={hook_event_name:"SubagentStop",hook_execution_id:I1(),timestamp:new Date().toISOString(),project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode,agent_type:$,task_description:Z.taskDescription,success:Z.success,result_summary:Z.resultSummary,error:Z.error},Q=this.getMatchingHooks("SubagentStop",{});if(Q.length===0)return{shouldStop:!0};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeSubagentStopHooks(Q,Y,X)}catch(J){return console.error("[HookManager] Error executing SubagentStop hooks:",J),{shouldStop:!0,warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executePermissionRequestHooks($,Z,Y,Q){if(!this.isEnabled())return{decision:"ask"};let X={hook_event_name:"PermissionRequest",hook_execution_id:I1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,project_dir:Q.projectDir,session_id:Q.sessionId,permission_mode:Q.permissionMode},J=this.getMatchingHooks("PermissionRequest",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(J.length===0)return{decision:"ask"};let G={projectDir:Q.projectDir,sessionId:Q.sessionId,permissionMode:Q.permissionMode,config:this.config,abortSignal:Q.abortSignal};try{return await this.executor.executePermissionRequestHooks(J,X,G)}catch(K){return console.error("[HookManager] Error executing PermissionRequest hooks:",K),{decision:"ask",warning:`Hook execution failed: ${K instanceof Error?K.message:String(K)}`}}}async executeUserPromptSubmitHooks($,Z){if(!this.isEnabled())return{proceed:!0};let Y={hook_event_name:"UserPromptSubmit",hook_execution_id:I1(),timestamp:new Date().toISOString(),user_prompt:$,has_images:Z.hasImages,image_count:Z.imageCount,project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode},Q=this.getMatchingHooks("UserPromptSubmit",{});if(Q.length===0)return{proceed:!0};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeUserPromptSubmitHooks(Q,Y,X)}catch(J){return console.error("[HookManager] Error executing UserPromptSubmit hooks:",J),{proceed:!0,warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executeSessionStartHooks($){if(!this.isEnabled())return{proceed:!0};let Z={hook_event_name:"SessionStart",hook_execution_id:I1(),timestamp:new Date().toISOString(),project_dir:$.projectDir,session_id:$.sessionId,permission_mode:$.permissionMode,is_resume:$.isResume,resume_session_id:$.resumeSessionId},Y=this.getMatchingHooks("SessionStart",{});if(Y.length===0)return{proceed:!0};let Q={projectDir:$.projectDir,sessionId:$.sessionId,permissionMode:$.permissionMode,config:this.config,abortSignal:$.abortSignal};try{return await this.executor.executeSessionStartHooks(Y,Z,Q)}catch(X){return console.error("[HookManager] Error executing SessionStart hooks:",X),{proceed:!0,warning:`Hook execution failed: ${X instanceof Error?X.message:String(X)}`}}}async executeSessionEndHooks($,Z){if(!this.isEnabled())return{};let Y={hook_event_name:"SessionEnd",hook_execution_id:I1(),timestamp:new Date().toISOString(),project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode,reason:$},Q=this.getMatchingHooks("SessionEnd",{});if(Q.length===0)return{};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeSessionEndHooks(Q,Y,X),{}}catch(J){return console.error("[HookManager] Error executing SessionEnd hooks:",J),{warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executePostToolUseFailureHooks($,Z,Y,Q,X){if(!this.isEnabled())return{};let J={hook_event_name:"PostToolUseFailure",hook_execution_id:I1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,error:Q,error_type:X.errorType,is_interrupt:X.isInterrupt,is_timeout:X.isTimeout,project_dir:X.projectDir,session_id:X.sessionId,permission_mode:X.permissionMode},G=this.getMatchingHooks("PostToolUseFailure",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(G.length===0)return{};let K={projectDir:X.projectDir,sessionId:X.sessionId,permissionMode:X.permissionMode,config:this.config,abortSignal:X.abortSignal};try{return await this.executor.executePostToolUseFailureHooks(G,J,K)}catch(q){return console.error("[HookManager] Error executing PostToolUseFailure hooks:",q),{warning:`Hook execution failed: ${q instanceof Error?q.message:String(q)}`}}}async executeNotificationHooks($,Z,Y){if(!this.isEnabled())return{suppress:!1,message:Z};let Q={hook_event_name:"Notification",hook_execution_id:I1(),timestamp:new Date().toISOString(),project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode,notification_type:$,title:Y.title,message:Z},X=this.getMatchingHooks("Notification",{});if(X.length===0)return{suppress:!1,message:Z};let J={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:this.config,abortSignal:Y.abortSignal};try{return await this.executor.executeNotificationHooks(X,Q,J)}catch(G){return console.error("[HookManager] Error executing Notification hooks:",G),{suppress:!1,message:Z,warning:`Hook execution failed: ${G instanceof Error?G.message:String(G)}`}}}async executeCompactionHooks($,Z){if(!this.isEnabled())return{blockCompaction:!1};let Y={hook_event_name:"Compaction",hook_execution_id:I1(),timestamp:new Date().toISOString(),project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode,trigger:$,messages_before:Z.messagesBefore,tokens_before:Z.tokensBefore},Q=this.getMatchingHooks("Compaction",{});if(Q.length===0)return{blockCompaction:!1};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeCompactionHooks(Q,Y,X)}catch(J){return console.error("[HookManager] Error executing Compaction hooks:",J),{blockCompaction:!1,warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}getMatchingHooks($,Z){let Y=this.config[$]||[],Q=[];for(let X of Y)if(this.matcher.matches(X.matcher,Z))Q.push(...X.hooks);return Q}extractFilePath($){let Z=["file_path","path","filePath","source","target"];for(let Y of Z){let Q=$[Y];if(typeof Q==="string")return Q}return}extractCommand($,Z){if($==="Bash"||$==="BashTool"){let Y=Z.command;if(typeof Y==="string")return Y}return}cleanup(){this.guard.cleanupAll()}}var t0=A(()=>{yQ();CQ();SQ();m2()});function kQ(){return"blade-builtin-glm47"}function w7($){return $==="blade-free-tier"}function N7($){return w7($.apiKey)}function rF($){return{id:"blade-builtin-glm47",name:$.name,provider:$.provider,baseUrl:$.baseUrl,model:$.model,apiKey:$.apiKey,maxContextTokens:$.maxContextTokens,maxOutputTokens:$.maxOutputTokens,supportsThinking:$.supportsThinking}}function fQ(){return rF(aF[0])}var aF;var u3=A(()=>{aF=[{name:"✨ GLM-4.7 (内置免费)",provider:"openai-compatible",baseUrl:"https://open.bigmodel.cn/api/coding/paas/v4",model:"glm-4.7",apiKey:"blade-free-tier",description:"智谱 GLM-4.7 Thinking - 由 Blade 提供免费额度",maxContextTokens:204800,maxOutputTokens:16384,supportsThinking:!0}]});import hQ from"@anthropic-ai/sdk";function nF($){if($.startsWith("data:")){let Z=$.match(/^data:([^;,]+)/);if(Z){let Y=Z[1];if(Y==="image/jpeg"||Y==="image/png"||Y==="image/gif"||Y==="image/webp")return Y}}return"image/png"}function oF($){if($.startsWith("data:")){let Z=$.indexOf(",");if(Z!==-1)return $.slice(Z+1)}return $}function xQ($){let Z=new Set;for(let Y of $)if(Y.role==="assistant"&&Y.tool_calls)for(let Q of Y.tool_calls)Z.add(Q.id);return $.filter((Y)=>{if(Y.role==="tool"){if(!Y.tool_call_id)return!1;return Z.has(Y.tool_call_id)}return!0})}function b7($){if(typeof $==="string")return $;return $.filter((Z)=>Z.type==="text").map((Z)=>Z.text).join(`
154
154
  `)}class A7{client;config;constructor($){if(this.config=$,P$.debug("\uD83D\uDE80 [AnthropicChatService] Initializing"),P$.debug("⚙️ [AnthropicChatService] Config:",{model:$.model,baseUrl:$.baseUrl,temperature:$.temperature,maxContextTokens:$.maxContextTokens,timeout:$.timeout,hasApiKey:!!$.apiKey}),!$.apiKey)throw P$.error("❌ [AnthropicChatService] apiKey is required"),Error("apiKey is required in ChatConfig");if(!$.model)throw P$.error("❌ [AnthropicChatService] model is required"),Error("model is required in ChatConfig");this.client=new hQ({apiKey:$.apiKey,baseURL:$.baseUrl||void 0,timeout:$.timeout??180000,maxRetries:3}),P$.debug("✅ [AnthropicChatService] Initialized successfully")}convertToAnthropicMessages($){let Z=$.find((G)=>G.role==="system"),Y=Z?b7(Z.content):void 0,Q=[],X=$.filter((G)=>G.role!=="system");for(let G=0;G<X.length;G++){let K=X[G];if(K.role==="assistant"){let q=[],W=b7(K.content);if(W)q.push({type:"text",text:W});if(K.tool_calls)for(let U of K.tool_calls){if(U.type!=="function")continue;let H={};try{H=JSON.parse(U.function.arguments||"{}")}catch{P$.warn(`⚠️ [AnthropicChatService] Failed to parse tool arguments: ${U.function.arguments}`)}q.push({type:"tool_use",id:U.id,name:U.function.name,input:H})}if(q.length>0)Q.push({role:"assistant",content:q})}else if(K.role==="tool"){let q={type:"tool_result",tool_use_id:K.tool_call_id,content:b7(K.content)},W=Q[Q.length-1];if(W?.role==="user"&&Array.isArray(W.content))W.content.push(q);else Q.push({role:"user",content:[q]})}else if(K.role==="user")if(Array.isArray(K.content)){let q=[];for(let W of K.content)if(W.type==="text")q.push({type:"text",text:W.text});else if(W.type==="image_url"){let U=W.image_url.url;q.push({type:"image",source:{type:"base64",media_type:nF(U),data:oF(U)}})}Q.push({role:"user",content:q})}else Q.push({role:"user",content:K.content})}if(Q.length>0&&Q[0].role!=="user")Q.unshift({role:"user",content:"[System initialized]"});let J=[];for(let G of Q){let K=J[J.length-1];if(K?.role===G.role){if(typeof K.content==="string"&&typeof G.content==="string")K.content=`${K.content}
155
155
 
156
- ${G.content}`;else if(Array.isArray(K.content)&&Array.isArray(G.content))K.content=[...K.content,...G.content];else if(typeof K.content==="string"&&Array.isArray(G.content))K.content=[{type:"text",text:K.content},...G.content];else if(Array.isArray(K.content)&&typeof G.content==="string")K.content.push({type:"text",text:G.content})}else J.push(G)}return{system:Y,messages:J}}convertToAnthropicTools($){if(!$||$.length===0)return;return $.map((Z)=>({name:Z.name,description:Z.description,input_schema:Z.parameters}))}parseAnthropicResponse($,Z){let Y="",Q=[];for(let X of $)if(X.type==="text")Y+=X.text;else if(X.type==="tool_use")Q.push({id:X.id,type:"function",function:{name:X.name,arguments:JSON.stringify(X.input)}});return{content:Y,toolCalls:Q.length>0?Q:void 0,usage:{promptTokens:Z.input_tokens,completionTokens:Z.output_tokens,totalTokens:Z.input_tokens+Z.output_tokens}}}async chat($,Z,Y){let Q=Date.now();P$.debug("\uD83D\uDE80 [AnthropicChatService] Starting chat request"),P$.debug("\uD83D\uDCDD [AnthropicChatService] Messages count:",$.length);let X=xQ($);if(X.length<$.length)P$.debug(`\uD83D\uDD27 [AnthropicChatService] 过滤掉 ${$.length-X.length} 条孤儿 tool 消息`);let{system:J,messages:G}=this.convertToAnthropicMessages(X),K=this.convertToAnthropicTools(Z);P$.debug("\uD83D\uDD27 [AnthropicChatService] Tools count:",K?.length||0),P$.debug("\uD83D\uDCE4 [AnthropicChatService] Request params:",{model:this.config.model,messagesCount:G.length,hasSystem:!!J,toolsCount:K?.length||0,max_tokens:this.config.maxOutputTokens??4096,temperature:this.config.temperature??0});try{let q=await this.client.messages.create({model:this.config.model,max_tokens:this.config.maxOutputTokens??4096,system:J,messages:G,tools:K,temperature:this.config.temperature??0},{signal:Y}),W=Date.now()-Q;P$.debug("\uD83D\uDCE5 [AnthropicChatService] Response received in",W,"ms"),P$.debug("\uD83D\uDCCA [AnthropicChatService] Response:",{stopReason:q.stop_reason,contentBlocksCount:q.content.length,usage:q.usage});let U=this.parseAnthropicResponse(q.content,q.usage);return P$.debug("✅ [AnthropicChatService] Chat completed successfully"),P$.debug("\uD83D\uDCCA [AnthropicChatService] Final response:",{contentLength:U.content.length,toolCallsCount:U.toolCalls?.length||0,usage:U.usage}),U}catch(q){let W=Date.now()-Q;throw P$.error("❌ [AnthropicChatService] Chat request failed after",W,"ms"),P$.error("❌ [AnthropicChatService] Error details:",q),q}}async*streamChat($,Z,Y){let Q=Date.now();P$.debug("\uD83D\uDE80 [AnthropicChatService] Starting stream request"),P$.debug("\uD83D\uDCDD [AnthropicChatService] Messages count:",$.length);let X=xQ($);if(X.length<$.length)P$.debug(`\uD83D\uDD27 [AnthropicChatService] 过滤掉 ${$.length-X.length} 条孤儿 tool 消息`);let{system:J,messages:G}=this.convertToAnthropicMessages(X),K=this.convertToAnthropicTools(Z);P$.debug("\uD83D\uDD27 [AnthropicChatService] Stream tools count:",K?.length||0),P$.debug("\uD83D\uDCE4 [AnthropicChatService] Stream request params:",{model:this.config.model,messagesCount:G.length,hasSystem:!!J,toolsCount:K?.length||0,max_tokens:this.config.maxOutputTokens??4096,temperature:this.config.temperature??0});try{let q=await this.client.messages.create({model:this.config.model,max_tokens:this.config.maxOutputTokens??4096,system:J,messages:G,tools:K,temperature:this.config.temperature??0,stream:!0},{signal:Y}),W=Date.now()-Q;P$.debug("\uD83D\uDCE5 [AnthropicChatService] Stream started in",W,"ms");let U=new Map,H=0,F="",O=!1,z=0,_=0;for await(let B of q){if(H++,B.type==="message_start"){let L=B.message?.usage;if(L)z=L.input_tokens||0,_=L.output_tokens||0}if(B.type==="content_block_start"){if(B.content_block.type==="tool_use")U.set(B.index,{id:B.content_block.id,name:B.content_block.name,arguments:""}),O=!0,P$.debug(`\uD83D\uDD27 [AnthropicChatService] Tool use started: ${B.content_block.name}`)}else if(B.type==="content_block_delta"){if(B.delta.type==="text_delta")F+=B.delta.text,yield{content:B.delta.text};else if(B.delta.type==="input_json_delta"){let L=U.get(B.index);if(L)L.arguments+=B.delta.partial_json}}else if(B.type==="content_block_stop"){let L=U.get(B.index);if(L&&L.id)P$.debug(`\uD83D\uDD27 [AnthropicChatService] Tool use completed: ${L.name}`),yield{toolCalls:[{id:L.id,type:"function",function:{name:L.name,arguments:L.arguments}}]}}else if(B.type==="message_delta"){let L=B.usage;if(L)_+=L.output_tokens||0;let w=B.delta.stop_reason;if(w){P$.debug("\uD83C\uDFC1 [AnthropicChatService] Stream finished:",w),P$.debug("\uD83D\uDCCA [AnthropicChatService] Stream summary:",{totalEvents:H,totalContentLength:F.length,hadToolCalls:O,duration:Date.now()-Q+"ms"});let N;if(w==="end_turn")N="stop";else if(w==="tool_use")N="tool_calls";else if(w==="max_tokens")N="length";else N=w;yield{finishReason:N,usage:{promptTokens:z,completionTokens:_,totalTokens:z+_}}}}}P$.debug("✅ [AnthropicChatService] Stream completed successfully")}catch(q){let W=Date.now()-Q;throw P$.error("❌ [AnthropicChatService] Stream request failed after",W,"ms"),P$.error("❌ [AnthropicChatService] Stream error details:",q),q}}getConfig(){return{...this.config}}updateConfig($){P$.debug("\uD83D\uDD04 [AnthropicChatService] Updating configuration"),this.config={...this.config,...$},this.client=new hQ({apiKey:this.config.apiKey,baseURL:this.config.baseUrl||void 0,timeout:this.config.timeout??180000,maxRetries:3}),P$.debug("✅ [AnthropicChatService] Configuration updated successfully")}}var P$;var pQ=A(()=>{O$();P$=l("Chat")});import{ProxyAgent as sF,fetch as tF}from"undici";function eF(){return process.env.HTTPS_PROXY||process.env.HTTP_PROXY||process.env.https_proxy||process.env.http_proxy}function $O(){let $=eF();if($)try{return new sF($)}catch(Z){console.warn(`[proxyFetch] Invalid proxy URL: ${$}`)}return}async function A0($,Z={}){let{timeout:Y=30000,signal:Q,...X}=Z;if(Q?.aborted)throw new DOMException("The operation was aborted.","AbortError");let J=$O(),G=new AbortController,K=!1,q=setTimeout(()=>{K=!0,G.abort()},Y),W=()=>G.abort();Q?.addEventListener("abort",W);try{let U={method:X.method,headers:X.headers,body:X.body,signal:G.signal,dispatcher:J};return await tF($.toString(),U)}catch(U){if(U instanceof Error&&U.name==="AbortError"){if(K)throw Error(`Request timeout after ${Y}ms`);throw U}throw U}finally{clearTimeout(q),Q?.removeEventListener("abort",W)}}var $4=()=>{};var mQ,dQ,m3,d3,u3,g8;var g3=A(()=>{mQ={authorizationUrl:"https://accounts.google.com/o/oauth2/v2/auth",tokenUrl:"https://oauth2.googleapis.com/token",scopes:["https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/userinfo.profile","https://www.googleapis.com/auth/cclog","https://www.googleapis.com/auth/experimentsandconfigs"],clientId:"1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com",clientSecret:"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",redirectPort:51121,redirectPath:"/oauth-callback"},dQ={authorizationUrl:"https://accounts.google.com/o/oauth2/v2/auth",tokenUrl:"https://oauth2.googleapis.com/token",scopes:["https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/userinfo.profile"],clientId:"681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com",clientSecret:"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",redirectPort:45289,redirectPath:"/"},m3={production:"https://cloudcode-pa.googleapis.com",sandbox:"https://daily-cloudcode-pa.sandbox.googleapis.com"},d3={generateContent:"/v1internal:generateContent",streamGenerateContent:"/v1internal:streamGenerateContent",loadCodeAssist:"/v1internal:loadCodeAssist",onboardUser:"/v1internal:onboardUser"},u3={"claude-sonnet-4-5":{id:"claude-sonnet-4-5",name:"Claude Sonnet 4.5",provider:"anthropic",supportsThinking:!1,description:"平衡速度与质量的 Claude 模型"},"claude-sonnet-4-5-thinking":{id:"claude-sonnet-4-5-thinking",name:"Claude Sonnet 4.5 (Thinking)",provider:"anthropic",supportsThinking:!0,description:"支持思维链的 Claude Sonnet"},"claude-opus-4-5-thinking":{id:"claude-opus-4-5-thinking",name:"Claude Opus 4.5 (Thinking)",provider:"anthropic",supportsThinking:!0,description:"最强 Claude 模型,支持思维链"},"gemini-3-pro-high":{id:"gemini-3-pro-high",name:"Gemini 3 Pro (High)",provider:"google",supportsThinking:!1,description:"高质量 Gemini 模型 (Pro)"},"gemini-3-pro-low":{id:"gemini-3-pro-low",name:"Gemini 3 Pro (Low)",provider:"google",supportsThinking:!1,description:"快速 Gemini 模型 (Pro)"},"gemini-3-flash":{id:"gemini-3-flash",name:"Gemini 3 Flash",provider:"google",supportsThinking:!1,description:"超快速 Gemini 模型 (Pro)"},"gpt-oss-120b-medium":{id:"gpt-oss-120b-medium",name:"GPT-OSS 120B Medium",provider:"openai-oss",supportsThinking:!1,description:"OpenAI 开源模型"}},g8={"gemini-2.5-pro":{id:"gemini-2.5-pro",name:"Gemini 2.5 Pro",provider:"google",supportsThinking:!1,description:"最强 Gemini 2.5 模型,1M 上下文"},"gemini-2.5-flash":{id:"gemini-2.5-flash",name:"Gemini 2.5 Flash",provider:"google",supportsThinking:!1,description:"快速 Gemini 2.5 模型"},"gemini-2.5-flash-lite":{id:"gemini-2.5-flash-lite",name:"Gemini 2.5 Flash Lite",provider:"google",supportsThinking:!1,description:"轻量级 Gemini 2.5 模型"}}});import{spawn as ZO}from"child_process";import*as l3 from"crypto";import*as N2 from"fs/promises";import*as gQ from"http";import*as c3 from"path";import{URL as YO}from"url";function uQ($){return $==="gemini-cli"?dQ:mQ}function V7(){let $=process.env.HOME||process.env.USERPROFILE||"";return c3.join($,".blade")}class I0{static instance=null;cachedToken=null;constructor(){}static getInstance(){if(!I0.instance)I0.instance=new I0;return I0.instance}async isLoggedIn(){let $=await this.loadToken();if(!$)return!1;let Z=300000;if($.expiresAt&&Date.now()>$.expiresAt-Z){if($.refreshToken)try{return await this.refreshToken(),!0}catch{return!1}return!1}return!0}async login($="antigravity"){let Z=$==="gemini-cli"?"Gemini CLI":"Antigravity";w2.info(`\uD83D\uDD10 Starting ${Z} OAuth login...`);let Y=uQ($),Q=this.generatePKCEParams(),X=this.buildAuthorizationUrl(Q,Y);console.log(`
156
+ ${G.content}`;else if(Array.isArray(K.content)&&Array.isArray(G.content))K.content=[...K.content,...G.content];else if(typeof K.content==="string"&&Array.isArray(G.content))K.content=[{type:"text",text:K.content},...G.content];else if(Array.isArray(K.content)&&typeof G.content==="string")K.content.push({type:"text",text:G.content})}else J.push(G)}return{system:Y,messages:J}}convertToAnthropicTools($){if(!$||$.length===0)return;return $.map((Z)=>({name:Z.name,description:Z.description,input_schema:Z.parameters}))}parseAnthropicResponse($,Z){let Y="",Q=[];for(let X of $)if(X.type==="text")Y+=X.text;else if(X.type==="tool_use")Q.push({id:X.id,type:"function",function:{name:X.name,arguments:JSON.stringify(X.input)}});return{content:Y,toolCalls:Q.length>0?Q:void 0,usage:{promptTokens:Z.input_tokens,completionTokens:Z.output_tokens,totalTokens:Z.input_tokens+Z.output_tokens}}}async chat($,Z,Y){let Q=Date.now();P$.debug("\uD83D\uDE80 [AnthropicChatService] Starting chat request"),P$.debug("\uD83D\uDCDD [AnthropicChatService] Messages count:",$.length);let X=xQ($);if(X.length<$.length)P$.debug(`\uD83D\uDD27 [AnthropicChatService] 过滤掉 ${$.length-X.length} 条孤儿 tool 消息`);let{system:J,messages:G}=this.convertToAnthropicMessages(X),K=this.convertToAnthropicTools(Z);P$.debug("\uD83D\uDD27 [AnthropicChatService] Tools count:",K?.length||0),P$.debug("\uD83D\uDCE4 [AnthropicChatService] Request params:",{model:this.config.model,messagesCount:G.length,hasSystem:!!J,toolsCount:K?.length||0,max_tokens:this.config.maxOutputTokens??4096,temperature:this.config.temperature??0});try{let q=await this.client.messages.create({model:this.config.model,max_tokens:this.config.maxOutputTokens??4096,system:J,messages:G,tools:K,temperature:this.config.temperature??0},{signal:Y}),W=Date.now()-Q;P$.debug("\uD83D\uDCE5 [AnthropicChatService] Response received in",W,"ms"),P$.debug("\uD83D\uDCCA [AnthropicChatService] Response:",{stopReason:q.stop_reason,contentBlocksCount:q.content.length,usage:q.usage});let U=this.parseAnthropicResponse(q.content,q.usage);return P$.debug("✅ [AnthropicChatService] Chat completed successfully"),P$.debug("\uD83D\uDCCA [AnthropicChatService] Final response:",{contentLength:U.content.length,toolCallsCount:U.toolCalls?.length||0,usage:U.usage}),U}catch(q){let W=Date.now()-Q;throw P$.error("❌ [AnthropicChatService] Chat request failed after",W,"ms"),P$.error("❌ [AnthropicChatService] Error details:",q),q}}async*streamChat($,Z,Y){let Q=Date.now();P$.debug("\uD83D\uDE80 [AnthropicChatService] Starting stream request"),P$.debug("\uD83D\uDCDD [AnthropicChatService] Messages count:",$.length);let X=xQ($);if(X.length<$.length)P$.debug(`\uD83D\uDD27 [AnthropicChatService] 过滤掉 ${$.length-X.length} 条孤儿 tool 消息`);let{system:J,messages:G}=this.convertToAnthropicMessages(X),K=this.convertToAnthropicTools(Z);P$.debug("\uD83D\uDD27 [AnthropicChatService] Stream tools count:",K?.length||0),P$.debug("\uD83D\uDCE4 [AnthropicChatService] Stream request params:",{model:this.config.model,messagesCount:G.length,hasSystem:!!J,toolsCount:K?.length||0,max_tokens:this.config.maxOutputTokens??4096,temperature:this.config.temperature??0});try{let q=await this.client.messages.create({model:this.config.model,max_tokens:this.config.maxOutputTokens??4096,system:J,messages:G,tools:K,temperature:this.config.temperature??0,stream:!0},{signal:Y}),W=Date.now()-Q;P$.debug("\uD83D\uDCE5 [AnthropicChatService] Stream started in",W,"ms");let U=new Map,H=0,F="",O=!1,z=0,_=0;for await(let B of q){if(H++,B.type==="message_start"){let L=B.message?.usage;if(L)z=L.input_tokens||0,_=L.output_tokens||0}if(B.type==="content_block_start"){if(B.content_block.type==="tool_use")U.set(B.index,{id:B.content_block.id,name:B.content_block.name,arguments:""}),O=!0,P$.debug(`\uD83D\uDD27 [AnthropicChatService] Tool use started: ${B.content_block.name}`)}else if(B.type==="content_block_delta"){if(B.delta.type==="text_delta")F+=B.delta.text,yield{content:B.delta.text};else if(B.delta.type==="input_json_delta"){let L=U.get(B.index);if(L)L.arguments+=B.delta.partial_json}}else if(B.type==="content_block_stop"){let L=U.get(B.index);if(L&&L.id)P$.debug(`\uD83D\uDD27 [AnthropicChatService] Tool use completed: ${L.name}`),yield{toolCalls:[{id:L.id,type:"function",function:{name:L.name,arguments:L.arguments}}]}}else if(B.type==="message_delta"){let L=B.usage;if(L)_+=L.output_tokens||0;let w=B.delta.stop_reason;if(w){P$.debug("\uD83C\uDFC1 [AnthropicChatService] Stream finished:",w),P$.debug("\uD83D\uDCCA [AnthropicChatService] Stream summary:",{totalEvents:H,totalContentLength:F.length,hadToolCalls:O,duration:Date.now()-Q+"ms"});let N;if(w==="end_turn")N="stop";else if(w==="tool_use")N="tool_calls";else if(w==="max_tokens")N="length";else N=w;yield{finishReason:N,usage:{promptTokens:z,completionTokens:_,totalTokens:z+_}}}}}P$.debug("✅ [AnthropicChatService] Stream completed successfully")}catch(q){let W=Date.now()-Q;throw P$.error("❌ [AnthropicChatService] Stream request failed after",W,"ms"),P$.error("❌ [AnthropicChatService] Stream error details:",q),q}}getConfig(){return{...this.config}}updateConfig($){P$.debug("\uD83D\uDD04 [AnthropicChatService] Updating configuration"),this.config={...this.config,...$},this.client=new hQ({apiKey:this.config.apiKey,baseURL:this.config.baseUrl||void 0,timeout:this.config.timeout??180000,maxRetries:3}),P$.debug("✅ [AnthropicChatService] Configuration updated successfully")}}var P$;var pQ=A(()=>{O$();P$=l("Chat")});import{ProxyAgent as sF,fetch as tF}from"undici";function eF(){return process.env.HTTPS_PROXY||process.env.HTTP_PROXY||process.env.https_proxy||process.env.http_proxy}function $O(){let $=eF();if($)try{return new sF($)}catch(Z){console.warn(`[proxyFetch] Invalid proxy URL: ${$}`)}return}async function A0($,Z={}){let{timeout:Y=30000,signal:Q,...X}=Z;if(Q?.aborted)throw new DOMException("The operation was aborted.","AbortError");let J=$O(),G=new AbortController,K=!1,q=setTimeout(()=>{K=!0,G.abort()},Y),W=()=>G.abort();Q?.addEventListener("abort",W);try{let U={method:X.method,headers:X.headers,body:X.body,signal:G.signal,dispatcher:J};return await tF($.toString(),U)}catch(U){if(U instanceof Error&&U.name==="AbortError"){if(K)throw Error(`Request timeout after ${Y}ms`);throw U}throw U}finally{clearTimeout(q),Q?.removeEventListener("abort",W)}}var $2=()=>{};var mQ,dQ,m8,d8,u8,g3;var g8=A(()=>{mQ={authorizationUrl:"https://accounts.google.com/o/oauth2/v2/auth",tokenUrl:"https://oauth2.googleapis.com/token",scopes:["https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/userinfo.profile","https://www.googleapis.com/auth/cclog","https://www.googleapis.com/auth/experimentsandconfigs"],clientId:"1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com",clientSecret:"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",redirectPort:51121,redirectPath:"/oauth-callback"},dQ={authorizationUrl:"https://accounts.google.com/o/oauth2/v2/auth",tokenUrl:"https://oauth2.googleapis.com/token",scopes:["https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/userinfo.profile"],clientId:"681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com",clientSecret:"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",redirectPort:45289,redirectPath:"/"},m8={production:"https://cloudcode-pa.googleapis.com",sandbox:"https://daily-cloudcode-pa.sandbox.googleapis.com"},d8={generateContent:"/v1internal:generateContent",streamGenerateContent:"/v1internal:streamGenerateContent",loadCodeAssist:"/v1internal:loadCodeAssist",onboardUser:"/v1internal:onboardUser"},u8={"claude-sonnet-4-5":{id:"claude-sonnet-4-5",name:"Claude Sonnet 4.5",provider:"anthropic",supportsThinking:!1,description:"平衡速度与质量的 Claude 模型"},"claude-sonnet-4-5-thinking":{id:"claude-sonnet-4-5-thinking",name:"Claude Sonnet 4.5 (Thinking)",provider:"anthropic",supportsThinking:!0,description:"支持思维链的 Claude Sonnet"},"claude-opus-4-5-thinking":{id:"claude-opus-4-5-thinking",name:"Claude Opus 4.5 (Thinking)",provider:"anthropic",supportsThinking:!0,description:"最强 Claude 模型,支持思维链"},"gemini-3-pro-high":{id:"gemini-3-pro-high",name:"Gemini 3 Pro (High)",provider:"google",supportsThinking:!1,description:"高质量 Gemini 模型 (Pro)"},"gemini-3-pro-low":{id:"gemini-3-pro-low",name:"Gemini 3 Pro (Low)",provider:"google",supportsThinking:!1,description:"快速 Gemini 模型 (Pro)"},"gemini-3-flash":{id:"gemini-3-flash",name:"Gemini 3 Flash",provider:"google",supportsThinking:!1,description:"超快速 Gemini 模型 (Pro)"},"gpt-oss-120b-medium":{id:"gpt-oss-120b-medium",name:"GPT-OSS 120B Medium",provider:"openai-oss",supportsThinking:!1,description:"OpenAI 开源模型"}},g3={"gemini-2.5-pro":{id:"gemini-2.5-pro",name:"Gemini 2.5 Pro",provider:"google",supportsThinking:!1,description:"最强 Gemini 2.5 模型,1M 上下文"},"gemini-2.5-flash":{id:"gemini-2.5-flash",name:"Gemini 2.5 Flash",provider:"google",supportsThinking:!1,description:"快速 Gemini 2.5 模型"},"gemini-2.5-flash-lite":{id:"gemini-2.5-flash-lite",name:"Gemini 2.5 Flash Lite",provider:"google",supportsThinking:!1,description:"轻量级 Gemini 2.5 模型"}}});import{spawn as ZO}from"child_process";import*as l8 from"crypto";import*as N4 from"fs/promises";import*as gQ from"http";import*as c8 from"path";import{URL as YO}from"url";function uQ($){return $==="gemini-cli"?dQ:mQ}function V7(){let $=process.env.HOME||process.env.USERPROFILE||"";return c8.join($,".blade")}class I0{static instance=null;cachedToken=null;constructor(){}static getInstance(){if(!I0.instance)I0.instance=new I0;return I0.instance}async isLoggedIn(){let $=await this.loadToken();if(!$)return!1;let Z=300000;if($.expiresAt&&Date.now()>$.expiresAt-Z){if($.refreshToken)try{return await this.refreshToken(),!0}catch{return!1}return!1}return!0}async login($="antigravity"){let Z=$==="gemini-cli"?"Gemini CLI":"Antigravity";w4.info(`\uD83D\uDD10 Starting ${Z} OAuth login...`);let Y=uQ($),Q=this.generatePKCEParams(),X=this.buildAuthorizationUrl(Q,Y);console.log(`
157
157
  \uD83C\uDF10 Opening browser for Google authentication...`),console.log(`
158
- If the browser does not open automatically, copy and paste this URL:`),console.log(X),console.log("");let J=this.startCallbackServer(Q.state,Y);try{await this.openBrowser(X)}catch(W){w2.warn("Failed to open browser automatically:",W)}let G=await J;console.log("✅ Authorization code received, exchanging for tokens...");let K=await this.exchangeCodeForToken(G,Q.codeVerifier,Y),q={accessToken:K.access_token,refreshToken:K.refresh_token||"",expiresAt:Date.now()+K.expires_in*1000,tokenType:K.token_type||"Bearer",scope:K.scope,configType:$};await this.saveToken(q),this.cachedToken=q,console.log(`✅ ${Z} login successful!`),w2.info(`${Z} OAuth login completed`)}async logout(){let $=c3.join(V7(),R7);try{await N2.unlink($),this.cachedToken=null,console.log("✅ Logged out from Antigravity"),w2.info("Antigravity logout completed")}catch(Z){if(Z.code!=="ENOENT")throw Z;this.cachedToken=null}}async getAccessToken(){if(this.cachedToken){if(this.cachedToken.expiresAt>Date.now()+300000)return this.cachedToken.accessToken}let $=await this.loadToken();if(!$)throw Error("Not logged in. Please run /login first.");let Z=300000;if($.expiresAt<=Date.now()+Z){if(!$.refreshToken)throw Error("Token expired and no refresh token available. Please run /login again.");return await this.refreshToken(),this.cachedToken.accessToken}return this.cachedToken=$,$.accessToken}async refreshToken(){let $=await this.loadToken();if(!$||!$.refreshToken)throw Error("No refresh token available");let Z=$.configType||"antigravity",Y=uQ(Z),Q=Z==="gemini-cli"?"Gemini CLI":"Antigravity";w2.info(`\uD83D\uDD04 Refreshing ${Q} access token...`);let X=new URLSearchParams({grant_type:"refresh_token",refresh_token:$.refreshToken,client_id:Y.clientId,client_secret:Y.clientSecret}),J=await A0(Y.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:X.toString()});if(!J.ok){let q=await J.text();throw w2.error("Token refresh failed:",q),Error(`Token refresh failed: ${J.status}`)}let G=await J.json(),K={accessToken:G.access_token,refreshToken:G.refresh_token||$.refreshToken,expiresAt:Date.now()+G.expires_in*1000,tokenType:G.token_type||"Bearer",scope:G.scope||$.scope,configType:Z};await this.saveToken(K),this.cachedToken=K,w2.info("✅ Token refreshed successfully")}generatePKCEParams(){let $=l3.randomBytes(32).toString("base64url"),Z=l3.createHash("sha256").update($).digest("base64url"),Y=l3.randomBytes(16).toString("base64url");return{codeVerifier:$,codeChallenge:Z,state:Y}}buildAuthorizationUrl($,Z){let Y=`http://localhost:${Z.redirectPort}${Z.redirectPath}`,Q=new URLSearchParams({client_id:Z.clientId,response_type:"code",redirect_uri:Y,state:$.state,code_challenge:$.codeChallenge,code_challenge_method:"S256",scope:Z.scopes.join(" "),access_type:"offline",prompt:"consent"});return`${Z.authorizationUrl}?${Q.toString()}`}async startCallbackServer($,Z){let{redirectPort:Y,redirectPath:Q}=Z;return new Promise((X,J)=>{let G=null,K=!1,q=()=>{if(G)clearTimeout(G),G=null},W=gQ.createServer((U,H)=>{try{let F=new YO(U.url,`http://localhost:${Y}`);if(F.pathname!==Q){H.writeHead(404),H.end("Not found");return}let O=F.searchParams.get("code"),z=F.searchParams.get("state"),_=F.searchParams.get("error");if(_){if(H.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),H.end(`
158
+ If the browser does not open automatically, copy and paste this URL:`),console.log(X),console.log("");let J=this.startCallbackServer(Q.state,Y);try{await this.openBrowser(X)}catch(W){w4.warn("Failed to open browser automatically:",W)}let G=await J;console.log("✅ Authorization code received, exchanging for tokens...");let K=await this.exchangeCodeForToken(G,Q.codeVerifier,Y),q={accessToken:K.access_token,refreshToken:K.refresh_token||"",expiresAt:Date.now()+K.expires_in*1000,tokenType:K.token_type||"Bearer",scope:K.scope,configType:$};await this.saveToken(q),this.cachedToken=q,console.log(`✅ ${Z} login successful!`),w4.info(`${Z} OAuth login completed`)}async logout(){let $=c8.join(V7(),R7);try{await N4.unlink($),this.cachedToken=null,console.log("✅ Logged out from Antigravity"),w4.info("Antigravity logout completed")}catch(Z){if(Z.code!=="ENOENT")throw Z;this.cachedToken=null}}async getAccessToken(){if(this.cachedToken){if(this.cachedToken.expiresAt>Date.now()+300000)return this.cachedToken.accessToken}let $=await this.loadToken();if(!$)throw Error("Not logged in. Please run /login first.");let Z=300000;if($.expiresAt<=Date.now()+Z){if(!$.refreshToken)throw Error("Token expired and no refresh token available. Please run /login again.");return await this.refreshToken(),this.cachedToken.accessToken}return this.cachedToken=$,$.accessToken}async refreshToken(){let $=await this.loadToken();if(!$||!$.refreshToken)throw Error("No refresh token available");let Z=$.configType||"antigravity",Y=uQ(Z),Q=Z==="gemini-cli"?"Gemini CLI":"Antigravity";w4.info(`\uD83D\uDD04 Refreshing ${Q} access token...`);let X=new URLSearchParams({grant_type:"refresh_token",refresh_token:$.refreshToken,client_id:Y.clientId,client_secret:Y.clientSecret}),J=await A0(Y.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:X.toString()});if(!J.ok){let q=await J.text();throw w4.error("Token refresh failed:",q),Error(`Token refresh failed: ${J.status}`)}let G=await J.json(),K={accessToken:G.access_token,refreshToken:G.refresh_token||$.refreshToken,expiresAt:Date.now()+G.expires_in*1000,tokenType:G.token_type||"Bearer",scope:G.scope||$.scope,configType:Z};await this.saveToken(K),this.cachedToken=K,w4.info("✅ Token refreshed successfully")}generatePKCEParams(){let $=l8.randomBytes(32).toString("base64url"),Z=l8.createHash("sha256").update($).digest("base64url"),Y=l8.randomBytes(16).toString("base64url");return{codeVerifier:$,codeChallenge:Z,state:Y}}buildAuthorizationUrl($,Z){let Y=`http://localhost:${Z.redirectPort}${Z.redirectPath}`,Q=new URLSearchParams({client_id:Z.clientId,response_type:"code",redirect_uri:Y,state:$.state,code_challenge:$.codeChallenge,code_challenge_method:"S256",scope:Z.scopes.join(" "),access_type:"offline",prompt:"consent"});return`${Z.authorizationUrl}?${Q.toString()}`}async startCallbackServer($,Z){let{redirectPort:Y,redirectPath:Q}=Z;return new Promise((X,J)=>{let G=null,K=!1,q=()=>{if(G)clearTimeout(G),G=null},W=gQ.createServer((U,H)=>{try{let F=new YO(U.url,`http://localhost:${Y}`);if(F.pathname!==Q){H.writeHead(404),H.end("Not found");return}let O=F.searchParams.get("code"),z=F.searchParams.get("state"),_=F.searchParams.get("error");if(_){if(H.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),H.end(`
159
159
  <html>
160
160
  <head><title>Authentication Failed</title></head>
161
161
  <body style="font-family: system-ui; padding: 40px; text-align: center;">
@@ -173,27 +173,27 @@ If the browser does not open automatically, copy and paste this URL:`),console.l
173
173
  <script>setTimeout(() => window.close(), 2000);</script>
174
174
  </body>
175
175
  </html>
176
- `),q(),W.close(),!K)K=!0,X(O)}catch(F){if(q(),W.close(),!K)K=!0,J(F)}});W.on("error",(U)=>{if(q(),!K)if(K=!0,U.code==="EADDRINUSE")J(Error(`Port ${Y} is already in use. Please close other applications using this port.`));else J(U)}),W.listen(Y,()=>{w2.debug(`OAuth callback server listening on port ${Y}`)}),G=setTimeout(()=>{if(W.close(),!K)K=!0,J(Error("OAuth callback timeout (5 minutes)"))},300000)})}async exchangeCodeForToken($,Z,Y){let Q=`http://localhost:${Y.redirectPort}${Y.redirectPath}`,X=new URLSearchParams({grant_type:"authorization_code",code:$,redirect_uri:Q,code_verifier:Z,client_id:Y.clientId,client_secret:Y.clientSecret}),J=await A0(Y.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:X.toString()});if(!J.ok){let G=await J.text();throw Error(`Token exchange failed: ${J.status} - ${G}`)}return await J.json()}async openBrowser($){let Z,Y;if(process.platform==="darwin")Z="open",Y=[$];else if(process.platform==="win32")Z="cmd",Y=["/c","start","",$];else Z="xdg-open",Y=[$];await new Promise((Q,X)=>{let J=ZO(Z,Y,{stdio:"ignore"});J.once("error",X),J.once("close",(G)=>{if(G===0||G===null)Q();else X(Error(`Failed to open browser (exit code ${G})`))})})}async saveToken($){let Z=V7();await N2.mkdir(Z,{recursive:!0,mode:493});let Y=c3.join(Z,R7);await N2.writeFile(Y,JSON.stringify($,null,2),{mode:384})}async loadToken(){let $=c3.join(V7(),R7);try{let Z=await N2.readFile($,"utf-8");return JSON.parse(Z)}catch(Z){if(Z.code==="ENOENT")return null;throw Z}}async getStatus(){let $=await this.loadToken();if(!$)return{loggedIn:!1};return{loggedIn:!0,expiresAt:$.expiresAt?new Date($.expiresAt):void 0,configType:$.configType||"antigravity"}}async getConfigType(){let $=await this.loadToken();if(!$)return null;return $.configType||"antigravity"}}var w2,R7="antigravity-token.json";var i3=A(()=>{O$();$4();g3();w2=l("Service")});function cQ($){if($==="antigravity")return{ideType:"ANTIGRAVITY"};return{ideType:"IDE_UNSPECIFIED",platform:"PLATFORM_UNSPECIFIED",pluginType:"GEMINI"}}function c8($){if($==="antigravity")return"antigravity/1.11.3 Darwin/arm64";return"gemini-cli/1.0.0"}function lQ($){let Z=new Set;for(let Y of $)if(Y.role==="assistant"&&Y.tool_calls)for(let Q of Y.tool_calls)Z.add(Q.id);return $.filter((Y)=>{if(Y.role==="tool"){if(!Y.tool_call_id)return!1;return Z.has(Y.tool_call_id)}return!0})}function l8($){if(typeof $==="string")return $;return $.filter((Z)=>Z.type==="text").map((Z)=>Z.text).join(`
177
- `)}function D7($){let Z=["const","$ref","$defs","$schema","$id","default","examples"],Y={};for(let[Q,X]of Object.entries($)){if(Z.includes(Q)){if(Q==="const")Y.enum=[X];continue}if(X&&typeof X==="object"&&!Array.isArray(X))Y[Q]=D7(X);else if(Array.isArray(X))Y[Q]=X.map((J)=>J&&typeof J==="object"&&!Array.isArray(J)?D7(J):J);else Y[Q]=X}return Y}class M7{config;auth;projectId;userTier;sessionId;configType="antigravity";projectIdInitialized=!1;constructor($){this.config=$,this.auth=I0.getInstance(),this.projectId=void 0,this.sessionId=`session_${Date.now()}_${Math.random().toString(36).slice(2,11)}`,T$.debug("\uD83D\uDE80 [AntigravityChatService] Initializing"),T$.debug("⚙️ [AntigravityChatService] Config:",{model:$.model,temperature:$.temperature,maxOutputTokens:$.maxOutputTokens,sessionId:this.sessionId})}async ensureProjectId(){if(this.projectIdInitialized)return;try{let $=await this.auth.getConfigType();this.configType=$||"antigravity",T$.debug(`\uD83D\uDD04 [AntigravityChatService] Using OAuth config: ${this.configType}`),T$.debug("\uD83D\uDD04 [AntigravityChatService] Setting up user via loadCodeAssist...");let Z=await this.auth.getAccessToken(),Y=await this.callLoadCodeAssist(Z);if(T$.debug("[AntigravityChatService] loadCodeAssist response:",JSON.stringify(Y)),Y.currentTier){if(this.userTier=Y.currentTier.id,Y.cloudaicompanionProject){this.projectId=Y.cloudaicompanionProject,T$.debug(`✅ [AntigravityChatService] User already setup: tier=${this.userTier}, project=${this.projectId}`),this.projectIdInitialized=!0;return}let J=process.env.GOOGLE_CLOUD_PROJECT||process.env.GOOGLE_CLOUD_PROJECT_ID;if(J){this.projectId=J,T$.debug(`✅ [AntigravityChatService] Using env project: ${this.projectId}`),this.projectIdInitialized=!0;return}T$.debug("⚠️ [AntigravityChatService] Has tier but no project, need onboarding...")}let Q=this.getDefaultTier(Y);T$.debug(`\uD83D\uDD04 [AntigravityChatService] Onboarding user with tier: ${Q.id}`);let X=await this.callOnboardUser(Z,Q.id);this.projectId=X.projectId,this.userTier=Q.id,T$.debug(`✅ [AntigravityChatService] User setup complete: tier=${this.userTier}, project=${this.projectId||"(managed)"}`)}catch($){T$.warn("Failed to setup user:",$)}this.projectIdInitialized=!0}async callLoadCodeAssist($){let Z=`${m3.production}${d3.loadCodeAssist}`,Y=cQ(this.configType),Q=c8(this.configType),X=await A0(Z,{method:"POST",headers:{Authorization:`Bearer ${$}`,"Content-Type":"application/json","User-Agent":Q},body:JSON.stringify({metadata:Y})});if(!X.ok){let J=await X.text();throw Error(`loadCodeAssist failed: ${X.status} - ${J}`)}return await X.json()}getDefaultTier($){for(let Z of $.allowedTiers||[])if(Z.isDefault)return{id:Z.id};return{id:"free-tier"}}async callOnboardUser($,Z){let Y=`${m3.production}${d3.onboardUser}`,Q=cQ(this.configType),X=c8(this.configType),J={tierId:Z,metadata:Q};if(Z!=="free-tier"){let q=process.env.GOOGLE_CLOUD_PROJECT||process.env.GOOGLE_CLOUD_PROJECT_ID;if(q)J.cloudaicompanionProject=q,J.metadata={...Q,duetProject:q}}let G=0,K=30;while(G<K){let q=await A0(Y,{method:"POST",headers:{Authorization:`Bearer ${$}`,"Content-Type":"application/json","User-Agent":X},body:JSON.stringify(J)});if(!q.ok){let U=await q.text();throw Error(`onboardUser failed: ${q.status} - ${U}`)}let W=await q.json();if(T$.debug(`[AntigravityChatService] onboardUser attempt ${G+1}:`,JSON.stringify(W)),W.error)throw Error(`onboardUser error: ${W.error.message||W.error.code}`);if(W.done)return{projectId:W.response?.cloudaicompanionProject?.id};T$.debug("[AntigravityChatService] onboardUser not done, waiting 5s..."),await new Promise((U)=>setTimeout(U,5000)),G++}throw Error("onboardUser timeout: LRO did not complete in time")}convertToAntigravityMessages($){let Z=$.find((K)=>K.role==="system"),Y=Z?{parts:[{text:l8(Z.content)}]}:void 0,Q=[],X=$.filter((K)=>K.role!=="system"),J=new Map;for(let K of X)if(K.role==="assistant"&&K.tool_calls){for(let q of K.tool_calls)if(q.type==="function")J.set(q.id,q.function.name)}for(let K of X)if(K.role==="user"){let q=[];if(Array.isArray(K.content)){for(let W of K.content)if(W.type==="text")q.push({text:W.text})}else q.push({text:K.content});Q.push({role:"user",parts:q})}else if(K.role==="assistant"){let q=[],W=l8(K.content);if(W)q.push({text:W});if(K.tool_calls)for(let U of K.tool_calls){if(U.type!=="function")continue;let H={};try{H=JSON.parse(U.function.arguments||"{}")}catch{T$.warn(`Failed to parse tool arguments: ${U.function.arguments}`)}q.push({functionCall:{name:U.function.name,args:H,id:U.id}})}if(q.length>0)Q.push({role:"model",parts:q})}else if(K.role==="tool"){let q=J.get(K.tool_call_id||"");if(q){let W;try{W=JSON.parse(l8(K.content))}catch{W={result:l8(K.content)}}Q.push({role:"user",parts:[{functionResponse:{name:q,id:K.tool_call_id,response:W}}]})}}let G=[];for(let K of Q){let q=G[G.length-1];if(q?.role===K.role)q.parts=[...q.parts,...K.parts];else G.push(K)}if(G.length>0&&G[0].role!=="user")G.unshift({role:"user",parts:[{text:"[Conversation start]"}]});return{systemInstruction:Y,contents:G}}convertToAntigravityTools($){if(!$||$.length===0)return;return[{functionDeclarations:$.map((Y)=>({name:Y.name,description:Y.description,parameters:D7(Y.parameters||{type:"object",properties:{}})}))}]}async makeRequest($,Z,Y){let Q=await this.auth.getAccessToken(),X=`${m3.production}${$}`,J=c8(this.configType),G=await A0(X,{method:"POST",headers:{Authorization:`Bearer ${Q}`,"Content-Type":"application/json","User-Agent":J},body:JSON.stringify(Z),signal:Y});if(!G.ok){let K=await G.text();if(T$.error(`Antigravity API error: ${G.status} - ${K}`),G.status===401)throw Error("Authentication expired. Please run /login again.");if(G.status===403)throw Error("Permission denied. Please check your Google account permissions.");if(G.status===429)throw Error("Rate limit exceeded. Please wait a moment and try again.");throw Error(`Antigravity API error: ${G.status} - ${K}`)}return G}async chat($,Z,Y){let Q=Date.now();T$.debug("\uD83D\uDE80 [AntigravityChatService] Starting chat request"),T$.debug("\uD83D\uDCDD [AntigravityChatService] Messages count:",$.length),await this.ensureProjectId();let X=lQ($);if(X.length<$.length)T$.debug(`Filtered ${$.length-X.length} orphan tool messages`);let{systemInstruction:J,contents:G}=this.convertToAntigravityMessages(X),K=this.convertToAntigravityTools(Z),q=`prompt_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,W={model:this.config.model,project:this.projectId,user_prompt_id:q,request:{contents:G,systemInstruction:J,generationConfig:{maxOutputTokens:this.config.maxOutputTokens??8192,temperature:this.config.temperature??0.7},tools:K,session_id:this.sessionId}};T$.debug("\uD83D\uDCE4 [AntigravityChatService] Request:",{model:this.config.model,contentsCount:G.length,hasSystemInstruction:!!J,toolsCount:K?.[0]?.functionDeclarations?.length||0});try{let H=await(await this.makeRequest(d3.generateContent,W,Y)).json(),F=Date.now()-Q;T$.debug("\uD83D\uDCE5 [AntigravityChatService] Response received in",F,"ms");let O="",z=[],B=H.response?.candidates?.[0]?.content?.parts||[];for(let N of B)if(N.text)O+=N.text;else if(N.functionCall){let D=N.functionCall;z.push({id:D.id||`call_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,type:"function",function:{name:D.name,arguments:JSON.stringify(D.args||{})}})}let L=H.response?.usageMetadata,w={content:O,toolCalls:z.length>0?z:void 0,usage:{promptTokens:L?.promptTokenCount||0,completionTokens:L?.candidatesTokenCount||0,totalTokens:L?.totalTokenCount||0}};return T$.debug("✅ [AntigravityChatService] Chat completed:",{contentLength:w.content.length,toolCallsCount:w.toolCalls?.length||0,usage:w.usage}),w}catch(U){let H=Date.now()-Q;throw T$.error("❌ [AntigravityChatService] Chat failed after",H,"ms"),T$.error("❌ [AntigravityChatService] Error:",U),U}}async*streamChat($,Z,Y){let Q=Date.now();T$.debug("\uD83D\uDE80 [AntigravityChatService] Starting stream request"),await this.ensureProjectId();let X=lQ($),{systemInstruction:J,contents:G}=this.convertToAntigravityMessages(X),K=this.convertToAntigravityTools(Z),q=`prompt_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,W={model:this.config.model,project:this.projectId,user_prompt_id:q,request:{contents:G,systemInstruction:J,generationConfig:{maxOutputTokens:this.config.maxOutputTokens??8192,temperature:this.config.temperature??0.7},tools:K,session_id:this.sessionId}};try{let U=await this.auth.getAccessToken(),H=`${m3.production}${d3.streamGenerateContent}?alt=sse`,F=c8(this.configType),O=await A0(H,{method:"POST",headers:{Authorization:`Bearer ${U}`,"Content-Type":"application/json",Accept:"text/event-stream","User-Agent":F},body:JSON.stringify(W),signal:Y});if(!O.ok){let N=await O.text();throw Error(`Antigravity API error: ${O.status} - ${N}`)}let z=O.body?.getReader();if(!z)throw Error("No response body");let _=new TextDecoder,B="",L=0,w=Date.now()-Q;T$.debug("\uD83D\uDCE5 [AntigravityChatService] Stream started in",w,"ms");while(!0){let{done:N,value:D}=await z.read();if(N)break;B+=_.decode(D,{stream:!0});let V=B.split(`
178
- `);B=V.pop()||"";for(let I of V)if(I.startsWith("data: ")){let v=I.slice(6);if(v==="[DONE]"){yield{finishReason:"stop"};continue}try{let b=JSON.parse(v);if(L++,b.usageMetadata)yield{usage:{promptTokens:b.usageMetadata.promptTokenCount||0,completionTokens:b.usageMetadata.candidatesTokenCount||0,totalTokens:b.usageMetadata.totalTokenCount||0}};let C=b.candidates?.[0],d=C?.content?.parts||[];for(let k of d)if(k.text)yield{content:k.text};else if(k.functionCall){let T=k.functionCall;yield{toolCalls:[{id:T.id||`call_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,type:"function",function:{name:T.name,arguments:JSON.stringify(T.args||{})}}]}}let e=C?.finishReason;if(e)yield{finishReason:e==="STOP"?"stop":e==="MAX_TOKENS"?"length":e.toLowerCase()}}catch(b){T$.debug("Failed to parse SSE data:",v)}}}T$.debug("✅ [AntigravityChatService] Stream completed:",{eventCount:L,duration:Date.now()-Q+"ms"})}catch(U){let H=Date.now()-Q;throw T$.error("❌ [AntigravityChatService] Stream failed after",H,"ms"),T$.error("❌ [AntigravityChatService] Error:",U),U}}getConfig(){return{...this.config}}updateConfig($){T$.debug("\uD83D\uDD04 [AntigravityChatService] Updating configuration"),this.config={...this.config,...$},T$.debug("✅ [AntigravityChatService] Configuration updated")}}var T$;var iQ=A(()=>{O$();$4();i3();g3();T$=l("Chat")});function i8($){if(!($ instanceof Error))return!1;let Z=$.message.toLowerCase();return Z.includes("stream_options")||Z.includes("include_usage")||Z.includes("unknown parameter")||Z.includes("unrecognized request argument")}import{AzureOpenAI as aQ}from"openai";function rQ($){let Z=new Set;for(let Y of $)if(Y.role==="assistant"&&Y.tool_calls)for(let Q of Y.tool_calls)Z.add(Q.id);return $.filter((Y)=>{if(Y.role==="tool"){if(!Y.tool_call_id)return!1;return Z.has(Y.tool_call_id)}return!0})}class j7{client;config;constructor($){if(this.config=$,v$.debug("\uD83D\uDE80 [AzureOpenAIChatService] Initializing"),v$.debug("⚙️ [AzureOpenAIChatService] Config:",{model:$.model,baseUrl:$.baseUrl,temperature:$.temperature,maxContextTokens:$.maxContextTokens,timeout:$.timeout,apiVersion:$.apiVersion,hasApiKey:!!$.apiKey}),!$.apiKey)throw v$.error("❌ [AzureOpenAIChatService] apiKey is required"),Error("apiKey is required in ChatConfig");if(!$.baseUrl)throw v$.error("❌ [AzureOpenAIChatService] baseUrl is required"),Error("baseUrl is required in ChatConfig");if(!$.model)throw v$.error("❌ [AzureOpenAIChatService] model (deployment) is required"),Error("model (deployment) is required in ChatConfig");this.client=new aQ({apiKey:$.apiKey,endpoint:$.baseUrl,apiVersion:$.apiVersion||"2024-08-01-preview",timeout:$.timeout??180000,maxRetries:3}),v$.debug("✅ [AzureOpenAIChatService] Initialized successfully")}convertToOpenAIMessages($){return $.map((Z)=>{if(Z.role==="tool")return{role:"tool",content:typeof Z.content==="string"?Z.content:Z.content.filter((Q)=>Q.type==="text").map((Q)=>Q.text).join(`
176
+ `),q(),W.close(),!K)K=!0,X(O)}catch(F){if(q(),W.close(),!K)K=!0,J(F)}});W.on("error",(U)=>{if(q(),!K)if(K=!0,U.code==="EADDRINUSE")J(Error(`Port ${Y} is already in use. Please close other applications using this port.`));else J(U)}),W.listen(Y,()=>{w4.debug(`OAuth callback server listening on port ${Y}`)}),G=setTimeout(()=>{if(W.close(),!K)K=!0,J(Error("OAuth callback timeout (5 minutes)"))},300000)})}async exchangeCodeForToken($,Z,Y){let Q=`http://localhost:${Y.redirectPort}${Y.redirectPath}`,X=new URLSearchParams({grant_type:"authorization_code",code:$,redirect_uri:Q,code_verifier:Z,client_id:Y.clientId,client_secret:Y.clientSecret}),J=await A0(Y.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:X.toString()});if(!J.ok){let G=await J.text();throw Error(`Token exchange failed: ${J.status} - ${G}`)}return await J.json()}async openBrowser($){let Z,Y;if(process.platform==="darwin")Z="open",Y=[$];else if(process.platform==="win32")Z="cmd",Y=["/c","start","",$];else Z="xdg-open",Y=[$];await new Promise((Q,X)=>{let J=ZO(Z,Y,{stdio:"ignore"});J.once("error",X),J.once("close",(G)=>{if(G===0||G===null)Q();else X(Error(`Failed to open browser (exit code ${G})`))})})}async saveToken($){let Z=V7();await N4.mkdir(Z,{recursive:!0,mode:493});let Y=c8.join(Z,R7);await N4.writeFile(Y,JSON.stringify($,null,2),{mode:384})}async loadToken(){let $=c8.join(V7(),R7);try{let Z=await N4.readFile($,"utf-8");return JSON.parse(Z)}catch(Z){if(Z.code==="ENOENT")return null;throw Z}}async getStatus(){let $=await this.loadToken();if(!$)return{loggedIn:!1};return{loggedIn:!0,expiresAt:$.expiresAt?new Date($.expiresAt):void 0,configType:$.configType||"antigravity"}}async getConfigType(){let $=await this.loadToken();if(!$)return null;return $.configType||"antigravity"}}var w4,R7="antigravity-token.json";var i8=A(()=>{O$();$2();g8();w4=l("Service")});function cQ($){if($==="antigravity")return{ideType:"ANTIGRAVITY"};return{ideType:"IDE_UNSPECIFIED",platform:"PLATFORM_UNSPECIFIED",pluginType:"GEMINI"}}function c3($){if($==="antigravity")return"antigravity/1.11.3 Darwin/arm64";return"gemini-cli/1.0.0"}function lQ($){let Z=new Set;for(let Y of $)if(Y.role==="assistant"&&Y.tool_calls)for(let Q of Y.tool_calls)Z.add(Q.id);return $.filter((Y)=>{if(Y.role==="tool"){if(!Y.tool_call_id)return!1;return Z.has(Y.tool_call_id)}return!0})}function l3($){if(typeof $==="string")return $;return $.filter((Z)=>Z.type==="text").map((Z)=>Z.text).join(`
177
+ `)}function D7($){let Z=["const","$ref","$defs","$schema","$id","default","examples"],Y={};for(let[Q,X]of Object.entries($)){if(Z.includes(Q)){if(Q==="const")Y.enum=[X];continue}if(X&&typeof X==="object"&&!Array.isArray(X))Y[Q]=D7(X);else if(Array.isArray(X))Y[Q]=X.map((J)=>J&&typeof J==="object"&&!Array.isArray(J)?D7(J):J);else Y[Q]=X}return Y}class M7{config;auth;projectId;userTier;sessionId;configType="antigravity";projectIdInitialized=!1;constructor($){this.config=$,this.auth=I0.getInstance(),this.projectId=void 0,this.sessionId=`session_${Date.now()}_${Math.random().toString(36).slice(2,11)}`,T$.debug("\uD83D\uDE80 [AntigravityChatService] Initializing"),T$.debug("⚙️ [AntigravityChatService] Config:",{model:$.model,temperature:$.temperature,maxOutputTokens:$.maxOutputTokens,sessionId:this.sessionId})}async ensureProjectId(){if(this.projectIdInitialized)return;try{let $=await this.auth.getConfigType();this.configType=$||"antigravity",T$.debug(`\uD83D\uDD04 [AntigravityChatService] Using OAuth config: ${this.configType}`),T$.debug("\uD83D\uDD04 [AntigravityChatService] Setting up user via loadCodeAssist...");let Z=await this.auth.getAccessToken(),Y=await this.callLoadCodeAssist(Z);if(T$.debug("[AntigravityChatService] loadCodeAssist response:",JSON.stringify(Y)),Y.currentTier){if(this.userTier=Y.currentTier.id,Y.cloudaicompanionProject){this.projectId=Y.cloudaicompanionProject,T$.debug(`✅ [AntigravityChatService] User already setup: tier=${this.userTier}, project=${this.projectId}`),this.projectIdInitialized=!0;return}let J=process.env.GOOGLE_CLOUD_PROJECT||process.env.GOOGLE_CLOUD_PROJECT_ID;if(J){this.projectId=J,T$.debug(`✅ [AntigravityChatService] Using env project: ${this.projectId}`),this.projectIdInitialized=!0;return}T$.debug("⚠️ [AntigravityChatService] Has tier but no project, need onboarding...")}let Q=this.getDefaultTier(Y);T$.debug(`\uD83D\uDD04 [AntigravityChatService] Onboarding user with tier: ${Q.id}`);let X=await this.callOnboardUser(Z,Q.id);this.projectId=X.projectId,this.userTier=Q.id,T$.debug(`✅ [AntigravityChatService] User setup complete: tier=${this.userTier}, project=${this.projectId||"(managed)"}`)}catch($){T$.warn("Failed to setup user:",$)}this.projectIdInitialized=!0}async callLoadCodeAssist($){let Z=`${m8.production}${d8.loadCodeAssist}`,Y=cQ(this.configType),Q=c3(this.configType),X=await A0(Z,{method:"POST",headers:{Authorization:`Bearer ${$}`,"Content-Type":"application/json","User-Agent":Q},body:JSON.stringify({metadata:Y})});if(!X.ok){let J=await X.text();throw Error(`loadCodeAssist failed: ${X.status} - ${J}`)}return await X.json()}getDefaultTier($){for(let Z of $.allowedTiers||[])if(Z.isDefault)return{id:Z.id};return{id:"free-tier"}}async callOnboardUser($,Z){let Y=`${m8.production}${d8.onboardUser}`,Q=cQ(this.configType),X=c3(this.configType),J={tierId:Z,metadata:Q};if(Z!=="free-tier"){let q=process.env.GOOGLE_CLOUD_PROJECT||process.env.GOOGLE_CLOUD_PROJECT_ID;if(q)J.cloudaicompanionProject=q,J.metadata={...Q,duetProject:q}}let G=0,K=30;while(G<K){let q=await A0(Y,{method:"POST",headers:{Authorization:`Bearer ${$}`,"Content-Type":"application/json","User-Agent":X},body:JSON.stringify(J)});if(!q.ok){let U=await q.text();throw Error(`onboardUser failed: ${q.status} - ${U}`)}let W=await q.json();if(T$.debug(`[AntigravityChatService] onboardUser attempt ${G+1}:`,JSON.stringify(W)),W.error)throw Error(`onboardUser error: ${W.error.message||W.error.code}`);if(W.done)return{projectId:W.response?.cloudaicompanionProject?.id};T$.debug("[AntigravityChatService] onboardUser not done, waiting 5s..."),await new Promise((U)=>setTimeout(U,5000)),G++}throw Error("onboardUser timeout: LRO did not complete in time")}convertToAntigravityMessages($){let Z=$.find((K)=>K.role==="system"),Y=Z?{parts:[{text:l3(Z.content)}]}:void 0,Q=[],X=$.filter((K)=>K.role!=="system"),J=new Map;for(let K of X)if(K.role==="assistant"&&K.tool_calls){for(let q of K.tool_calls)if(q.type==="function")J.set(q.id,q.function.name)}for(let K of X)if(K.role==="user"){let q=[];if(Array.isArray(K.content)){for(let W of K.content)if(W.type==="text")q.push({text:W.text})}else q.push({text:K.content});Q.push({role:"user",parts:q})}else if(K.role==="assistant"){let q=[],W=l3(K.content);if(W)q.push({text:W});if(K.tool_calls)for(let U of K.tool_calls){if(U.type!=="function")continue;let H={};try{H=JSON.parse(U.function.arguments||"{}")}catch{T$.warn(`Failed to parse tool arguments: ${U.function.arguments}`)}q.push({functionCall:{name:U.function.name,args:H,id:U.id}})}if(q.length>0)Q.push({role:"model",parts:q})}else if(K.role==="tool"){let q=J.get(K.tool_call_id||"");if(q){let W;try{W=JSON.parse(l3(K.content))}catch{W={result:l3(K.content)}}Q.push({role:"user",parts:[{functionResponse:{name:q,id:K.tool_call_id,response:W}}]})}}let G=[];for(let K of Q){let q=G[G.length-1];if(q?.role===K.role)q.parts=[...q.parts,...K.parts];else G.push(K)}if(G.length>0&&G[0].role!=="user")G.unshift({role:"user",parts:[{text:"[Conversation start]"}]});return{systemInstruction:Y,contents:G}}convertToAntigravityTools($){if(!$||$.length===0)return;return[{functionDeclarations:$.map((Y)=>({name:Y.name,description:Y.description,parameters:D7(Y.parameters||{type:"object",properties:{}})}))}]}async makeRequest($,Z,Y){let Q=await this.auth.getAccessToken(),X=`${m8.production}${$}`,J=c3(this.configType),G=await A0(X,{method:"POST",headers:{Authorization:`Bearer ${Q}`,"Content-Type":"application/json","User-Agent":J},body:JSON.stringify(Z),signal:Y});if(!G.ok){let K=await G.text();if(T$.error(`Antigravity API error: ${G.status} - ${K}`),G.status===401)throw Error("Authentication expired. Please run /login again.");if(G.status===403)throw Error("Permission denied. Please check your Google account permissions.");if(G.status===429)throw Error("Rate limit exceeded. Please wait a moment and try again.");throw Error(`Antigravity API error: ${G.status} - ${K}`)}return G}async chat($,Z,Y){let Q=Date.now();T$.debug("\uD83D\uDE80 [AntigravityChatService] Starting chat request"),T$.debug("\uD83D\uDCDD [AntigravityChatService] Messages count:",$.length),await this.ensureProjectId();let X=lQ($);if(X.length<$.length)T$.debug(`Filtered ${$.length-X.length} orphan tool messages`);let{systemInstruction:J,contents:G}=this.convertToAntigravityMessages(X),K=this.convertToAntigravityTools(Z),q=`prompt_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,W={model:this.config.model,project:this.projectId,user_prompt_id:q,request:{contents:G,systemInstruction:J,generationConfig:{maxOutputTokens:this.config.maxOutputTokens??8192,temperature:this.config.temperature??0.7},tools:K,session_id:this.sessionId}};T$.debug("\uD83D\uDCE4 [AntigravityChatService] Request:",{model:this.config.model,contentsCount:G.length,hasSystemInstruction:!!J,toolsCount:K?.[0]?.functionDeclarations?.length||0});try{let H=await(await this.makeRequest(d8.generateContent,W,Y)).json(),F=Date.now()-Q;T$.debug("\uD83D\uDCE5 [AntigravityChatService] Response received in",F,"ms");let O="",z=[],B=H.response?.candidates?.[0]?.content?.parts||[];for(let N of B)if(N.text)O+=N.text;else if(N.functionCall){let D=N.functionCall;z.push({id:D.id||`call_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,type:"function",function:{name:D.name,arguments:JSON.stringify(D.args||{})}})}let L=H.response?.usageMetadata,w={content:O,toolCalls:z.length>0?z:void 0,usage:{promptTokens:L?.promptTokenCount||0,completionTokens:L?.candidatesTokenCount||0,totalTokens:L?.totalTokenCount||0}};return T$.debug("✅ [AntigravityChatService] Chat completed:",{contentLength:w.content.length,toolCallsCount:w.toolCalls?.length||0,usage:w.usage}),w}catch(U){let H=Date.now()-Q;throw T$.error("❌ [AntigravityChatService] Chat failed after",H,"ms"),T$.error("❌ [AntigravityChatService] Error:",U),U}}async*streamChat($,Z,Y){let Q=Date.now();T$.debug("\uD83D\uDE80 [AntigravityChatService] Starting stream request"),await this.ensureProjectId();let X=lQ($),{systemInstruction:J,contents:G}=this.convertToAntigravityMessages(X),K=this.convertToAntigravityTools(Z),q=`prompt_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,W={model:this.config.model,project:this.projectId,user_prompt_id:q,request:{contents:G,systemInstruction:J,generationConfig:{maxOutputTokens:this.config.maxOutputTokens??8192,temperature:this.config.temperature??0.7},tools:K,session_id:this.sessionId}};try{let U=await this.auth.getAccessToken(),H=`${m8.production}${d8.streamGenerateContent}?alt=sse`,F=c3(this.configType),O=await A0(H,{method:"POST",headers:{Authorization:`Bearer ${U}`,"Content-Type":"application/json",Accept:"text/event-stream","User-Agent":F},body:JSON.stringify(W),signal:Y});if(!O.ok){let N=await O.text();throw Error(`Antigravity API error: ${O.status} - ${N}`)}let z=O.body?.getReader();if(!z)throw Error("No response body");let _=new TextDecoder,B="",L=0,w=Date.now()-Q;T$.debug("\uD83D\uDCE5 [AntigravityChatService] Stream started in",w,"ms");while(!0){let{done:N,value:D}=await z.read();if(N)break;B+=_.decode(D,{stream:!0});let V=B.split(`
178
+ `);B=V.pop()||"";for(let I of V)if(I.startsWith("data: ")){let v=I.slice(6);if(v==="[DONE]"){yield{finishReason:"stop"};continue}try{let b=JSON.parse(v);if(L++,b.usageMetadata)yield{usage:{promptTokens:b.usageMetadata.promptTokenCount||0,completionTokens:b.usageMetadata.candidatesTokenCount||0,totalTokens:b.usageMetadata.totalTokenCount||0}};let C=b.candidates?.[0],d=C?.content?.parts||[];for(let k of d)if(k.text)yield{content:k.text};else if(k.functionCall){let T=k.functionCall;yield{toolCalls:[{id:T.id||`call_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,type:"function",function:{name:T.name,arguments:JSON.stringify(T.args||{})}}]}}let e=C?.finishReason;if(e)yield{finishReason:e==="STOP"?"stop":e==="MAX_TOKENS"?"length":e.toLowerCase()}}catch(b){T$.debug("Failed to parse SSE data:",v)}}}T$.debug("✅ [AntigravityChatService] Stream completed:",{eventCount:L,duration:Date.now()-Q+"ms"})}catch(U){let H=Date.now()-Q;throw T$.error("❌ [AntigravityChatService] Stream failed after",H,"ms"),T$.error("❌ [AntigravityChatService] Error:",U),U}}getConfig(){return{...this.config}}updateConfig($){T$.debug("\uD83D\uDD04 [AntigravityChatService] Updating configuration"),this.config={...this.config,...$},T$.debug("✅ [AntigravityChatService] Configuration updated")}}var T$;var iQ=A(()=>{O$();$2();i8();g8();T$=l("Chat")});function i3($){if(!($ instanceof Error))return!1;let Z=$.message.toLowerCase();return Z.includes("stream_options")||Z.includes("include_usage")||Z.includes("unknown parameter")||Z.includes("unrecognized request argument")}import{AzureOpenAI as aQ}from"openai";function rQ($){let Z=new Set;for(let Y of $)if(Y.role==="assistant"&&Y.tool_calls)for(let Q of Y.tool_calls)Z.add(Q.id);return $.filter((Y)=>{if(Y.role==="tool"){if(!Y.tool_call_id)return!1;return Z.has(Y.tool_call_id)}return!0})}class j7{client;config;constructor($){if(this.config=$,v$.debug("\uD83D\uDE80 [AzureOpenAIChatService] Initializing"),v$.debug("⚙️ [AzureOpenAIChatService] Config:",{model:$.model,baseUrl:$.baseUrl,temperature:$.temperature,maxContextTokens:$.maxContextTokens,timeout:$.timeout,apiVersion:$.apiVersion,hasApiKey:!!$.apiKey}),!$.apiKey)throw v$.error("❌ [AzureOpenAIChatService] apiKey is required"),Error("apiKey is required in ChatConfig");if(!$.baseUrl)throw v$.error("❌ [AzureOpenAIChatService] baseUrl is required"),Error("baseUrl is required in ChatConfig");if(!$.model)throw v$.error("❌ [AzureOpenAIChatService] model (deployment) is required"),Error("model (deployment) is required in ChatConfig");this.client=new aQ({apiKey:$.apiKey,endpoint:$.baseUrl,apiVersion:$.apiVersion||"2024-08-01-preview",timeout:$.timeout??180000,maxRetries:3}),v$.debug("✅ [AzureOpenAIChatService] Initialized successfully")}convertToOpenAIMessages($){return $.map((Z)=>{if(Z.role==="tool")return{role:"tool",content:typeof Z.content==="string"?Z.content:Z.content.filter((Q)=>Q.type==="text").map((Q)=>Q.text).join(`
179
179
  `),tool_call_id:Z.tool_call_id};if(Z.role==="assistant"&&Z.tool_calls)return{role:"assistant",content:(typeof Z.content==="string"?Z.content:Z.content.filter((Q)=>Q.type==="text").map((Q)=>Q.text).join(`
180
180
  `))||null,tool_calls:Z.tool_calls};if(Z.role==="user"&&Array.isArray(Z.content))return{role:"user",content:Z.content.map((Y)=>{if(Y.type==="text")return{type:"text",text:Y.text};return{type:"image_url",image_url:{url:Y.image_url.url}}})};return{role:Z.role,content:typeof Z.content==="string"?Z.content:Z.content.filter((Y)=>Y.type==="text").map((Y)=>Y.text).join(`
181
- `)}})}convertToOpenAITools($){return $?.map((Z)=>({type:"function",function:{name:Z.name,description:Z.description,parameters:Z.parameters}}))}async chat($,Z,Y){let Q=Date.now();v$.debug("\uD83D\uDE80 [AzureOpenAIChatService] Starting chat request"),v$.debug("\uD83D\uDCDD [AzureOpenAIChatService] Messages count:",$.length);let X=rQ($);if(X.length<$.length)v$.debug(`\uD83D\uDD27 [AzureOpenAIChatService] 过滤掉 ${$.length-X.length} 条孤儿 tool 消息`);let J=this.convertToOpenAIMessages(X),G=this.convertToOpenAITools(Z);v$.debug("\uD83D\uDD27 [AzureOpenAIChatService] Tools count:",G?.length||0);let K={model:this.config.model,messages:J,tools:G,tool_choice:G&&G.length>0?"auto":void 0,max_tokens:this.config.maxOutputTokens??32768,temperature:this.config.temperature??0};v$.debug("\uD83D\uDCE4 [AzureOpenAIChatService] Request params:",{model:K.model,messagesCount:K.messages.length,toolsCount:K.tools?.length||0,max_tokens:K.max_tokens,temperature:K.temperature});try{let q=await this.client.chat.completions.create(K,{signal:Y}),W=Date.now()-Q;if(v$.debug("\uD83D\uDCE5 [AzureOpenAIChatService] Response received in",W,"ms"),!q||!q.choices||q.choices.length===0)throw Error("Invalid API response: missing choices");let U=q.choices[0];if(!U)throw Error("No completion choice returned");let H=U.message.tool_calls?.filter((O)=>O.type==="function"),F={content:U.message.content||"",toolCalls:H,usage:{promptTokens:q.usage?.prompt_tokens||0,completionTokens:q.usage?.completion_tokens||0,totalTokens:q.usage?.total_tokens||0}};return v$.debug("✅ [AzureOpenAIChatService] Chat completed successfully"),v$.debug("\uD83D\uDCCA [AzureOpenAIChatService] Final response:",{contentLength:F.content.length,toolCallsCount:F.toolCalls?.length||0,usage:F.usage}),F}catch(q){let W=Date.now()-Q;throw v$.error("❌ [AzureOpenAIChatService] Chat request failed after",W,"ms"),v$.error("❌ [AzureOpenAIChatService] Error details:",q),q}}async*streamChat($,Z,Y){let Q=Date.now();v$.debug("\uD83D\uDE80 [AzureOpenAIChatService] Starting stream request"),v$.debug("\uD83D\uDCDD [AzureOpenAIChatService] Messages count:",$.length);let X=rQ($);if(X.length<$.length)v$.debug(`\uD83D\uDD27 [AzureOpenAIChatService] 过滤掉 ${$.length-X.length} 条孤儿 tool 消息`);let J=this.convertToOpenAIMessages(X),G=this.convertToOpenAITools(Z);v$.debug("\uD83D\uDD27 [AzureOpenAIChatService] Stream tools count:",G?.length||0);let K={model:this.config.model,messages:J,tools:G,tool_choice:G&&G.length>0?"auto":void 0,max_tokens:this.config.maxOutputTokens??32768,temperature:this.config.temperature??0,stream:!0,stream_options:{include_usage:!0}};v$.debug("\uD83D\uDCE4 [AzureOpenAIChatService] Stream request params:",{model:K.model,messagesCount:K.messages.length,toolsCount:K.tools?.length||0,max_tokens:K.max_tokens,temperature:K.temperature});try{let q;try{q=await this.client.chat.completions.create(K,{signal:Y})}catch(O){if(!i8(O))throw O;v$.warn("⚠️ [AzureOpenAIChatService] stream_options 不被支持,已降级为无 usage 流式请求");let{stream_options:z,..._}=K;q=await this.client.chat.completions.create(_,{signal:Y})}let W=Date.now()-Q;v$.debug("\uD83D\uDCE5 [AzureOpenAIChatService] Stream started in",W,"ms");let U=0,H="",F=!1;for await(let O of q){U++;let z=O.usage;if(!O||!O.choices||!Array.isArray(O.choices)){if(z){yield{usage:{promptTokens:z.prompt_tokens||0,completionTokens:z.completion_tokens||0,totalTokens:z.total_tokens||0}};continue}v$.warn("⚠️ [AzureOpenAIChatService] Invalid chunk format in stream",U);continue}let _=O.choices[0]?.delta;if(!_){if(z){yield{usage:{promptTokens:z.prompt_tokens||0,completionTokens:z.completion_tokens||0,totalTokens:z.total_tokens||0}};continue}v$.warn("⚠️ [AzureOpenAIChatService] Empty delta in chunk",U);continue}if(_.content)H+=_.content;if(_.tool_calls&&!F)F=!0,v$.debug("\uD83D\uDD27 [AzureOpenAIChatService] Tool calls detected in stream");let B=O.choices[0]?.finish_reason;if(B)v$.debug("\uD83C\uDFC1 [AzureOpenAIChatService] Stream finished with reason:",B),v$.debug("\uD83D\uDCCA [AzureOpenAIChatService] Stream summary:",{totalChunks:U,totalContentLength:H.length,hadToolCalls:F,duration:Date.now()-Q+"ms"});let L={content:_.content||void 0,toolCalls:_.tool_calls,finishReason:B||void 0};if(z)L.usage={promptTokens:z.prompt_tokens||0,completionTokens:z.completion_tokens||0,totalTokens:z.total_tokens||0};yield L}v$.debug("✅ [AzureOpenAIChatService] Stream completed successfully")}catch(q){let W=Date.now()-Q;throw v$.error("❌ [AzureOpenAIChatService] Stream request failed after",W,"ms"),v$.error("❌ [AzureOpenAIChatService] Stream error details:",q),q}}getConfig(){return{...this.config}}updateConfig($){v$.debug("\uD83D\uDD04 [AzureOpenAIChatService] Updating configuration"),this.config={...this.config,...$},this.client=new aQ({apiKey:this.config.apiKey,endpoint:this.config.baseUrl,apiVersion:this.config.apiVersion||"2024-08-01-preview",timeout:this.config.timeout??180000,maxRetries:3}),v$.debug("✅ [AzureOpenAIChatService] Configuration updated successfully")}}var v$;var nQ=A(()=>{O$();v$=l("Chat")});async function sQ($){if($!==oQ)return $;if(a8)return a3.debug("使用缓存的内置 API Key"),a8;try{a3.info("\uD83D\uDD11 正在从代理服务获取内置 API Key...");let Z=await A0(QO,{method:"GET",headers:{Authorization:`Bearer ${oQ}`,"Content-Type":"application/json"},timeout:1e4});if(!Z.ok){let Q=await Z.text();throw Error(`获取 API Key 失败: ${Z.status} - ${Q}`)}let Y=await Z.json();if(!Y.apiKey)throw Error("代理服务返回的数据中没有 apiKey");if(a8=Y.apiKey,XO=Y.baseUrl,a3.info("✅ 成功获取内置 API Key"),Y.message)a3.debug(`提示: ${Y.message}`);return a8}catch(Z){throw a3.error("❌ 获取内置 API Key 失败:",Z),Error(`无法获取内置模型的 API Key: ${Z instanceof Error?Z.message:"未知错误"}
182
- `+"请检查网络连接或使用自己的 API Key (/config)")}}var a3,QO="https://blade-api-proxy.137844255.workers.dev/v1/get-zhipu-key",oQ="blade-free-tier",a8=null,XO=null;var tQ=A(()=>{O$();$4();a3=l("Service")});var Z4,r3,r8;var n3=A(()=>{Z4={deviceCodeUrl:"https://github.com/login/device/code",tokenUrl:"https://github.com/login/oauth/access_token",clientId:"01ab8ac9400c4e429b23",scope:"user:email",grantType:"urn:ietf:params:oauth:grant-type:device_code"},r3={tokenExchange:"https://api.github.com/copilot_internal/v2/token",chatCompletions:"https://api.githubcopilot.com/chat/completions",models:"https://api.githubcopilot.com/models"},r8={"gpt-5-mini":{id:"gpt-5-mini",name:"GPT-5 Mini",provider:"openai",supportsStreaming:!0,description:"快速高效,适合简单任务"},"grok-code-fast-1":{id:"grok-code-fast-1",name:"Grok Code Fast 1",provider:"xai",supportsStreaming:!0,description:"xAI 快速代码模型"},"claude-haiku-4.5":{id:"claude-haiku-4.5",name:"Claude Haiku 4.5",provider:"anthropic",supportsStreaming:!0,description:"快速智能的 Claude"},"gpt-4.1":{id:"gpt-4.1",name:"GPT-4.1",provider:"openai",supportsStreaming:!0,description:"默认模型,平衡速度与质量"},"gpt-4o":{id:"gpt-4o",name:"GPT-4o",provider:"openai",supportsStreaming:!0,description:"多模态模型,适合日常编码"},"gpt-5":{id:"gpt-5",name:"GPT-5",provider:"openai",supportsStreaming:!0,description:"最新 GPT-5 模型"},"claude-sonnet-4":{id:"claude-sonnet-4",name:"Claude Sonnet 4",provider:"anthropic",supportsStreaming:!0,description:"平衡速度与智能的 Claude"},"claude-sonnet-4.5":{id:"claude-sonnet-4.5",name:"Claude Sonnet 4.5",provider:"anthropic",supportsStreaming:!0,description:"最新 Claude Sonnet"},"claude-opus-4.1":{id:"claude-opus-4.1",name:"Claude Opus 4.1",provider:"anthropic",supportsStreaming:!0,description:"最强 Claude,适合复杂任务"},"gemini-2.5-pro":{id:"gemini-2.5-pro",name:"Gemini 2.5 Pro",provider:"google",supportsStreaming:!0,description:"高级推理和长上下文"},"gemini-3-pro":{id:"gemini-3-pro",name:"Gemini 3 Pro",provider:"google",supportsStreaming:!0,description:"数据分析和多模态"},"gemini-3-flash":{id:"gemini-3-flash",name:"Gemini 3 Flash",provider:"google",supportsStreaming:!0,description:"快速响应模型"}}});import{spawn as JO}from"child_process";import*as b2 from"fs/promises";import*as s3 from"path";function y7(){let $=process.env.HOME||process.env.USERPROFILE||"";return s3.join($,".blade")}class S0{static instance=null;cachedToken=null;constructor(){}static getInstance(){if(!S0.instance)S0.instance=new S0;return S0.instance}async isLoggedIn(){let $=await this.loadToken();if(!$)return!1;let Z=300000;if($.copilotExpiresAt&&Date.now()>$.copilotExpiresAt-Z)try{return await this.refreshCopilotToken(),!0}catch{return!1}return!0}async login(){o3.info("\uD83D\uDD10 Starting GitHub Copilot OAuth login..."),console.log(`
181
+ `)}})}convertToOpenAITools($){return $?.map((Z)=>({type:"function",function:{name:Z.name,description:Z.description,parameters:Z.parameters}}))}async chat($,Z,Y){let Q=Date.now();v$.debug("\uD83D\uDE80 [AzureOpenAIChatService] Starting chat request"),v$.debug("\uD83D\uDCDD [AzureOpenAIChatService] Messages count:",$.length);let X=rQ($);if(X.length<$.length)v$.debug(`\uD83D\uDD27 [AzureOpenAIChatService] 过滤掉 ${$.length-X.length} 条孤儿 tool 消息`);let J=this.convertToOpenAIMessages(X),G=this.convertToOpenAITools(Z);v$.debug("\uD83D\uDD27 [AzureOpenAIChatService] Tools count:",G?.length||0);let K={model:this.config.model,messages:J,tools:G,tool_choice:G&&G.length>0?"auto":void 0,max_tokens:this.config.maxOutputTokens??32768,temperature:this.config.temperature??0};v$.debug("\uD83D\uDCE4 [AzureOpenAIChatService] Request params:",{model:K.model,messagesCount:K.messages.length,toolsCount:K.tools?.length||0,max_tokens:K.max_tokens,temperature:K.temperature});try{let q=await this.client.chat.completions.create(K,{signal:Y}),W=Date.now()-Q;if(v$.debug("\uD83D\uDCE5 [AzureOpenAIChatService] Response received in",W,"ms"),!q||!q.choices||q.choices.length===0)throw Error("Invalid API response: missing choices");let U=q.choices[0];if(!U)throw Error("No completion choice returned");let H=U.message.tool_calls?.filter((O)=>O.type==="function"),F={content:U.message.content||"",toolCalls:H,usage:{promptTokens:q.usage?.prompt_tokens||0,completionTokens:q.usage?.completion_tokens||0,totalTokens:q.usage?.total_tokens||0}};return v$.debug("✅ [AzureOpenAIChatService] Chat completed successfully"),v$.debug("\uD83D\uDCCA [AzureOpenAIChatService] Final response:",{contentLength:F.content.length,toolCallsCount:F.toolCalls?.length||0,usage:F.usage}),F}catch(q){let W=Date.now()-Q;throw v$.error("❌ [AzureOpenAIChatService] Chat request failed after",W,"ms"),v$.error("❌ [AzureOpenAIChatService] Error details:",q),q}}async*streamChat($,Z,Y){let Q=Date.now();v$.debug("\uD83D\uDE80 [AzureOpenAIChatService] Starting stream request"),v$.debug("\uD83D\uDCDD [AzureOpenAIChatService] Messages count:",$.length);let X=rQ($);if(X.length<$.length)v$.debug(`\uD83D\uDD27 [AzureOpenAIChatService] 过滤掉 ${$.length-X.length} 条孤儿 tool 消息`);let J=this.convertToOpenAIMessages(X),G=this.convertToOpenAITools(Z);v$.debug("\uD83D\uDD27 [AzureOpenAIChatService] Stream tools count:",G?.length||0);let K={model:this.config.model,messages:J,tools:G,tool_choice:G&&G.length>0?"auto":void 0,max_tokens:this.config.maxOutputTokens??32768,temperature:this.config.temperature??0,stream:!0,stream_options:{include_usage:!0}};v$.debug("\uD83D\uDCE4 [AzureOpenAIChatService] Stream request params:",{model:K.model,messagesCount:K.messages.length,toolsCount:K.tools?.length||0,max_tokens:K.max_tokens,temperature:K.temperature});try{let q;try{q=await this.client.chat.completions.create(K,{signal:Y})}catch(O){if(!i3(O))throw O;v$.warn("⚠️ [AzureOpenAIChatService] stream_options 不被支持,已降级为无 usage 流式请求");let{stream_options:z,..._}=K;q=await this.client.chat.completions.create(_,{signal:Y})}let W=Date.now()-Q;v$.debug("\uD83D\uDCE5 [AzureOpenAIChatService] Stream started in",W,"ms");let U=0,H="",F=!1;for await(let O of q){U++;let z=O.usage;if(!O||!O.choices||!Array.isArray(O.choices)){if(z){yield{usage:{promptTokens:z.prompt_tokens||0,completionTokens:z.completion_tokens||0,totalTokens:z.total_tokens||0}};continue}v$.warn("⚠️ [AzureOpenAIChatService] Invalid chunk format in stream",U);continue}let _=O.choices[0]?.delta;if(!_){if(z){yield{usage:{promptTokens:z.prompt_tokens||0,completionTokens:z.completion_tokens||0,totalTokens:z.total_tokens||0}};continue}v$.warn("⚠️ [AzureOpenAIChatService] Empty delta in chunk",U);continue}if(_.content)H+=_.content;if(_.tool_calls&&!F)F=!0,v$.debug("\uD83D\uDD27 [AzureOpenAIChatService] Tool calls detected in stream");let B=O.choices[0]?.finish_reason;if(B)v$.debug("\uD83C\uDFC1 [AzureOpenAIChatService] Stream finished with reason:",B),v$.debug("\uD83D\uDCCA [AzureOpenAIChatService] Stream summary:",{totalChunks:U,totalContentLength:H.length,hadToolCalls:F,duration:Date.now()-Q+"ms"});let L={content:_.content||void 0,toolCalls:_.tool_calls,finishReason:B||void 0};if(z)L.usage={promptTokens:z.prompt_tokens||0,completionTokens:z.completion_tokens||0,totalTokens:z.total_tokens||0};yield L}v$.debug("✅ [AzureOpenAIChatService] Stream completed successfully")}catch(q){let W=Date.now()-Q;throw v$.error("❌ [AzureOpenAIChatService] Stream request failed after",W,"ms"),v$.error("❌ [AzureOpenAIChatService] Stream error details:",q),q}}getConfig(){return{...this.config}}updateConfig($){v$.debug("\uD83D\uDD04 [AzureOpenAIChatService] Updating configuration"),this.config={...this.config,...$},this.client=new aQ({apiKey:this.config.apiKey,endpoint:this.config.baseUrl,apiVersion:this.config.apiVersion||"2024-08-01-preview",timeout:this.config.timeout??180000,maxRetries:3}),v$.debug("✅ [AzureOpenAIChatService] Configuration updated successfully")}}var v$;var nQ=A(()=>{O$();v$=l("Chat")});async function sQ($){if($!==oQ)return $;if(a3)return a8.debug("使用缓存的内置 API Key"),a3;try{a8.info("\uD83D\uDD11 正在从代理服务获取内置 API Key...");let Z=await A0(QO,{method:"GET",headers:{Authorization:`Bearer ${oQ}`,"Content-Type":"application/json"},timeout:1e4});if(!Z.ok){let Q=await Z.text();throw Error(`获取 API Key 失败: ${Z.status} - ${Q}`)}let Y=await Z.json();if(!Y.apiKey)throw Error("代理服务返回的数据中没有 apiKey");if(a3=Y.apiKey,XO=Y.baseUrl,a8.info("✅ 成功获取内置 API Key"),Y.message)a8.debug(`提示: ${Y.message}`);return a3}catch(Z){throw a8.error("❌ 获取内置 API Key 失败:",Z),Error(`无法获取内置模型的 API Key: ${Z instanceof Error?Z.message:"未知错误"}
182
+ `+"请检查网络连接或使用自己的 API Key (/config)")}}var a8,QO="https://blade-api-proxy.137844255.workers.dev/v1/get-zhipu-key",oQ="blade-free-tier",a3=null,XO=null;var tQ=A(()=>{O$();$2();a8=l("Service")});var Z2,r8,r3;var n8=A(()=>{Z2={deviceCodeUrl:"https://github.com/login/device/code",tokenUrl:"https://github.com/login/oauth/access_token",clientId:"01ab8ac9400c4e429b23",scope:"user:email",grantType:"urn:ietf:params:oauth:grant-type:device_code"},r8={tokenExchange:"https://api.github.com/copilot_internal/v2/token",chatCompletions:"https://api.githubcopilot.com/chat/completions",models:"https://api.githubcopilot.com/models"},r3={"gpt-5-mini":{id:"gpt-5-mini",name:"GPT-5 Mini",provider:"openai",supportsStreaming:!0,description:"快速高效,适合简单任务"},"grok-code-fast-1":{id:"grok-code-fast-1",name:"Grok Code Fast 1",provider:"xai",supportsStreaming:!0,description:"xAI 快速代码模型"},"claude-haiku-4.5":{id:"claude-haiku-4.5",name:"Claude Haiku 4.5",provider:"anthropic",supportsStreaming:!0,description:"快速智能的 Claude"},"gpt-4.1":{id:"gpt-4.1",name:"GPT-4.1",provider:"openai",supportsStreaming:!0,description:"默认模型,平衡速度与质量"},"gpt-4o":{id:"gpt-4o",name:"GPT-4o",provider:"openai",supportsStreaming:!0,description:"多模态模型,适合日常编码"},"gpt-5":{id:"gpt-5",name:"GPT-5",provider:"openai",supportsStreaming:!0,description:"最新 GPT-5 模型"},"claude-sonnet-4":{id:"claude-sonnet-4",name:"Claude Sonnet 4",provider:"anthropic",supportsStreaming:!0,description:"平衡速度与智能的 Claude"},"claude-sonnet-4.5":{id:"claude-sonnet-4.5",name:"Claude Sonnet 4.5",provider:"anthropic",supportsStreaming:!0,description:"最新 Claude Sonnet"},"claude-opus-4.1":{id:"claude-opus-4.1",name:"Claude Opus 4.1",provider:"anthropic",supportsStreaming:!0,description:"最强 Claude,适合复杂任务"},"gemini-2.5-pro":{id:"gemini-2.5-pro",name:"Gemini 2.5 Pro",provider:"google",supportsStreaming:!0,description:"高级推理和长上下文"},"gemini-3-pro":{id:"gemini-3-pro",name:"Gemini 3 Pro",provider:"google",supportsStreaming:!0,description:"数据分析和多模态"},"gemini-3-flash":{id:"gemini-3-flash",name:"Gemini 3 Flash",provider:"google",supportsStreaming:!0,description:"快速响应模型"}}});import{spawn as JO}from"child_process";import*as b4 from"fs/promises";import*as s8 from"path";function y7(){let $=process.env.HOME||process.env.USERPROFILE||"";return s8.join($,".blade")}class S0{static instance=null;cachedToken=null;constructor(){}static getInstance(){if(!S0.instance)S0.instance=new S0;return S0.instance}async isLoggedIn(){let $=await this.loadToken();if(!$)return!1;let Z=300000;if($.copilotExpiresAt&&Date.now()>$.copilotExpiresAt-Z)try{return await this.refreshCopilotToken(),!0}catch{return!1}return!0}async login(){o8.info("\uD83D\uDD10 Starting GitHub Copilot OAuth login..."),console.log(`
183
183
  \uD83D\uDD10 开始 GitHub Copilot 认证...`);let $=await this.requestDeviceCode();console.log(`
184
184
  \uD83D\uDCCB 请在浏览器中完成授权:`),console.log(` 1. 打开 ${$.verification_uri}`),console.log(` 2. 输入代码: ${$.user_code}`),console.log("");try{await this.openBrowser($.verification_uri),console.log("\uD83C\uDF10 已自动打开浏览器,请输入上面的代码完成授权")}catch{console.log("⚠️ 无法自动打开浏览器,请手动打开上述链接")}console.log(`
185
- ⏳ 等待授权中...`);let Z=await this.pollForAccessToken($.device_code,$.interval,$.expires_in);console.log("✅ GitHub 授权成功!"),console.log("\uD83D\uDD04 正在获取 Copilot token...");let Y=await this.exchangeForCopilotToken(Z),Q={githubToken:Z,copilotToken:Y.token,copilotExpiresAt:Y.expires_at*1000};await this.saveToken(Q),this.cachedToken=Q,console.log("✅ GitHub Copilot 登录成功!"),o3.info("GitHub Copilot OAuth login completed")}async logout(){let $=s3.join(y7(),I7);try{await b2.unlink($),this.cachedToken=null,console.log("✅ 已登出 GitHub Copilot"),o3.info("GitHub Copilot logout completed")}catch(Z){if(Z.code!=="ENOENT")throw Z;this.cachedToken=null}}async getCopilotToken(){if(this.cachedToken){if(this.cachedToken.copilotExpiresAt>Date.now()+300000)return this.cachedToken.copilotToken}let $=await this.loadToken();if(!$)throw Error("Not logged in to GitHub Copilot. Please run /login copilot first.");let Z=300000;if($.copilotExpiresAt<=Date.now()+Z)return await this.refreshCopilotToken(),this.cachedToken.copilotToken;return this.cachedToken=$,$.copilotToken}async refreshCopilotToken(){let $=await this.loadToken();if(!$||!$.githubToken)throw Error("No GitHub token available");o3.info("\uD83D\uDD04 Refreshing Copilot token...");let Z=await this.exchangeForCopilotToken($.githubToken),Y={githubToken:$.githubToken,copilotToken:Z.token,copilotExpiresAt:Z.expires_at*1000};await this.saveToken(Y),this.cachedToken=Y,o3.info("✅ Copilot token refreshed successfully")}async requestDeviceCode(){let $=new URLSearchParams({client_id:Z4.clientId,scope:Z4.scope}),Z=await A0(Z4.deviceCodeUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:$.toString()});if(!Z.ok){let Y=await Z.text();throw Error(`Failed to request device code: ${Z.status} - ${Y}`)}return await Z.json()}async pollForAccessToken($,Z,Y){let Q=Date.now(),X=Y*1000;while(Date.now()-Q<X){await this.sleep(Z*1000);let J=new URLSearchParams({client_id:Z4.clientId,device_code:$,grant_type:Z4.grantType}),K=await(await A0(Z4.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:J.toString()})).json();if(K.access_token)return K.access_token;if(K.error==="authorization_pending")continue;if(K.error==="slow_down"){Z+=5;continue}if(K.error==="expired_token")throw Error("Device code expired. Please try again.");if(K.error==="access_denied")throw Error("Authorization denied by user.");if(K.error)throw Error(`OAuth error: ${K.error} - ${K.error_description||""}`)}throw Error("Device code expired. Please try again.")}async exchangeForCopilotToken($){let Z=await A0(r3.tokenExchange,{method:"GET",headers:{Authorization:`token ${$}`,Accept:"application/json","User-Agent":"GitHubCopilotChat/0.22.2024","Editor-Version":"vscode/1.95.0","Editor-Plugin-Version":"copilot-chat/0.22.2024"}});if(!Z.ok){let Y=await Z.text();if(Z.status===401)throw Error("GitHub token is invalid or expired. Please run /login copilot again.");if(Z.status===403)throw Error("No Copilot subscription found. Please ensure you have an active GitHub Copilot subscription.");throw Error(`Failed to exchange for Copilot token: ${Z.status} - ${Y}`)}return await Z.json()}async openBrowser($){let Z,Y;if(process.platform==="darwin")Z="open",Y=[$];else if(process.platform==="win32")Z="cmd",Y=["/c","start","",$];else Z="xdg-open",Y=[$];await new Promise((Q,X)=>{let J=JO(Z,Y,{stdio:"ignore"});J.once("error",X),J.once("close",(G)=>{if(G===0||G===null)Q();else X(Error(`Failed to open browser (exit code ${G})`))})})}async saveToken($){let Z=y7();await b2.mkdir(Z,{recursive:!0,mode:493});let Y=s3.join(Z,I7);await b2.writeFile(Y,JSON.stringify($,null,2),{mode:384})}async loadToken(){let $=s3.join(y7(),I7);try{let Z=await b2.readFile($,"utf-8");return JSON.parse(Z)}catch(Z){if(Z.code==="ENOENT")return null;throw Z}}async getStatus(){let $=await this.loadToken();if(!$)return{loggedIn:!1};return{loggedIn:!0,expiresAt:$.copilotExpiresAt?new Date($.copilotExpiresAt):void 0}}sleep($){return new Promise((Z)=>setTimeout(Z,$))}}var o3,I7="copilot-token.json";var t3=A(()=>{O$();$4();n3();o3=l("Service")});import{isPlainObject as n8}from"lodash-es";class v7{config;auth;constructor($){this.config=$,this.auth=S0.getInstance()}getConfig(){return this.config}updateConfig($){this.config={...this.config,...$}}async chat($,Z,Y){let Q=Date.now();H1.debug("\uD83D\uDE80 [CopilotChatService] Starting chat request"),H1.debug(`\uD83D\uDCDD [CopilotChatService] Messages count: ${$.length}`);try{let X=await this.auth.getCopilotToken(),J=this.buildRequest($,Z,!1),G=await this.makeRequest(X,J,Y),K=Date.now()-Q;return H1.debug(`✅ [CopilotChatService] Chat completed in ${K} ms`),this.parseResponse(G)}catch(X){let J=Date.now()-Q;throw H1.error(`❌ [CopilotChatService] Chat failed after ${J} ms`),H1.error(`❌ [CopilotChatService] Error: ${X}`),X}}async*streamChat($,Z,Y){let Q=Date.now();H1.debug("\uD83D\uDE80 [CopilotChatService] Starting stream chat request"),H1.debug(`\uD83D\uDCDD [CopilotChatService] Messages count: ${$.length}`);try{let X=await this.auth.getCopilotToken(),J=this.buildRequest($,Z,!0),G=await A0(r3.chatCompletions,{method:"POST",headers:{Authorization:`Bearer ${X}`,"Content-Type":"application/json",Accept:"text/event-stream","Copilot-Integration-Id":"vscode-chat","Editor-Version":"vscode/1.95.0","Editor-Plugin-Version":"copilot-chat/0.22.2024","User-Agent":"GitHubCopilotChat/0.22.2024"},body:JSON.stringify(J),signal:Y});if(!G.ok){let F=await G.text();throw Error(`Copilot API error: ${G.status} - ${F}`)}if(!G.body)throw Error("No response body");let K=G.body.getReader(),q=new TextDecoder,W="",U=new Map;while(!0){let{done:F,value:O}=await K.read();if(F)break;W+=q.decode(O,{stream:!0});let z=W.split(`
185
+ ⏳ 等待授权中...`);let Z=await this.pollForAccessToken($.device_code,$.interval,$.expires_in);console.log("✅ GitHub 授权成功!"),console.log("\uD83D\uDD04 正在获取 Copilot token...");let Y=await this.exchangeForCopilotToken(Z),Q={githubToken:Z,copilotToken:Y.token,copilotExpiresAt:Y.expires_at*1000};await this.saveToken(Q),this.cachedToken=Q,console.log("✅ GitHub Copilot 登录成功!"),o8.info("GitHub Copilot OAuth login completed")}async logout(){let $=s8.join(y7(),I7);try{await b4.unlink($),this.cachedToken=null,console.log("✅ 已登出 GitHub Copilot"),o8.info("GitHub Copilot logout completed")}catch(Z){if(Z.code!=="ENOENT")throw Z;this.cachedToken=null}}async getCopilotToken(){if(this.cachedToken){if(this.cachedToken.copilotExpiresAt>Date.now()+300000)return this.cachedToken.copilotToken}let $=await this.loadToken();if(!$)throw Error("Not logged in to GitHub Copilot. Please run /login copilot first.");let Z=300000;if($.copilotExpiresAt<=Date.now()+Z)return await this.refreshCopilotToken(),this.cachedToken.copilotToken;return this.cachedToken=$,$.copilotToken}async refreshCopilotToken(){let $=await this.loadToken();if(!$||!$.githubToken)throw Error("No GitHub token available");o8.info("\uD83D\uDD04 Refreshing Copilot token...");let Z=await this.exchangeForCopilotToken($.githubToken),Y={githubToken:$.githubToken,copilotToken:Z.token,copilotExpiresAt:Z.expires_at*1000};await this.saveToken(Y),this.cachedToken=Y,o8.info("✅ Copilot token refreshed successfully")}async requestDeviceCode(){let $=new URLSearchParams({client_id:Z2.clientId,scope:Z2.scope}),Z=await A0(Z2.deviceCodeUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:$.toString()});if(!Z.ok){let Y=await Z.text();throw Error(`Failed to request device code: ${Z.status} - ${Y}`)}return await Z.json()}async pollForAccessToken($,Z,Y){let Q=Date.now(),X=Y*1000;while(Date.now()-Q<X){await this.sleep(Z*1000);let J=new URLSearchParams({client_id:Z2.clientId,device_code:$,grant_type:Z2.grantType}),K=await(await A0(Z2.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:J.toString()})).json();if(K.access_token)return K.access_token;if(K.error==="authorization_pending")continue;if(K.error==="slow_down"){Z+=5;continue}if(K.error==="expired_token")throw Error("Device code expired. Please try again.");if(K.error==="access_denied")throw Error("Authorization denied by user.");if(K.error)throw Error(`OAuth error: ${K.error} - ${K.error_description||""}`)}throw Error("Device code expired. Please try again.")}async exchangeForCopilotToken($){let Z=await A0(r8.tokenExchange,{method:"GET",headers:{Authorization:`token ${$}`,Accept:"application/json","User-Agent":"GitHubCopilotChat/0.22.2024","Editor-Version":"vscode/1.95.0","Editor-Plugin-Version":"copilot-chat/0.22.2024"}});if(!Z.ok){let Y=await Z.text();if(Z.status===401)throw Error("GitHub token is invalid or expired. Please run /login copilot again.");if(Z.status===403)throw Error("No Copilot subscription found. Please ensure you have an active GitHub Copilot subscription.");throw Error(`Failed to exchange for Copilot token: ${Z.status} - ${Y}`)}return await Z.json()}async openBrowser($){let Z,Y;if(process.platform==="darwin")Z="open",Y=[$];else if(process.platform==="win32")Z="cmd",Y=["/c","start","",$];else Z="xdg-open",Y=[$];await new Promise((Q,X)=>{let J=JO(Z,Y,{stdio:"ignore"});J.once("error",X),J.once("close",(G)=>{if(G===0||G===null)Q();else X(Error(`Failed to open browser (exit code ${G})`))})})}async saveToken($){let Z=y7();await b4.mkdir(Z,{recursive:!0,mode:493});let Y=s8.join(Z,I7);await b4.writeFile(Y,JSON.stringify($,null,2),{mode:384})}async loadToken(){let $=s8.join(y7(),I7);try{let Z=await b4.readFile($,"utf-8");return JSON.parse(Z)}catch(Z){if(Z.code==="ENOENT")return null;throw Z}}async getStatus(){let $=await this.loadToken();if(!$)return{loggedIn:!1};return{loggedIn:!0,expiresAt:$.copilotExpiresAt?new Date($.copilotExpiresAt):void 0}}sleep($){return new Promise((Z)=>setTimeout(Z,$))}}var o8,I7="copilot-token.json";var t8=A(()=>{O$();$2();n8();o8=l("Service")});import{isPlainObject as n3}from"lodash-es";class v7{config;auth;constructor($){this.config=$,this.auth=S0.getInstance()}getConfig(){return this.config}updateConfig($){this.config={...this.config,...$}}async chat($,Z,Y){let Q=Date.now();H1.debug("\uD83D\uDE80 [CopilotChatService] Starting chat request"),H1.debug(`\uD83D\uDCDD [CopilotChatService] Messages count: ${$.length}`);try{let X=await this.auth.getCopilotToken(),J=this.buildRequest($,Z,!1),G=await this.makeRequest(X,J,Y),K=Date.now()-Q;return H1.debug(`✅ [CopilotChatService] Chat completed in ${K} ms`),this.parseResponse(G)}catch(X){let J=Date.now()-Q;throw H1.error(`❌ [CopilotChatService] Chat failed after ${J} ms`),H1.error(`❌ [CopilotChatService] Error: ${X}`),X}}async*streamChat($,Z,Y){let Q=Date.now();H1.debug("\uD83D\uDE80 [CopilotChatService] Starting stream chat request"),H1.debug(`\uD83D\uDCDD [CopilotChatService] Messages count: ${$.length}`);try{let X=await this.auth.getCopilotToken(),J=this.buildRequest($,Z,!0),G=await A0(r8.chatCompletions,{method:"POST",headers:{Authorization:`Bearer ${X}`,"Content-Type":"application/json",Accept:"text/event-stream","Copilot-Integration-Id":"vscode-chat","Editor-Version":"vscode/1.95.0","Editor-Plugin-Version":"copilot-chat/0.22.2024","User-Agent":"GitHubCopilotChat/0.22.2024"},body:JSON.stringify(J),signal:Y});if(!G.ok){let F=await G.text();throw Error(`Copilot API error: ${G.status} - ${F}`)}if(!G.body)throw Error("No response body");let K=G.body.getReader(),q=new TextDecoder,W="",U=new Map;while(!0){let{done:F,value:O}=await K.read();if(F)break;W+=q.decode(O,{stream:!0});let z=W.split(`
186
186
  `);W=z.pop()||"";for(let _ of z){if(!_.startsWith("data: "))continue;let B=_.slice(6).trim();if(B==="[DONE]"){if(U.size>0)yield{toolCalls:Array.from(U.values()),finishReason:"tool_calls"};continue}try{let w=JSON.parse(B).choices[0];if(w){let N={};if(w.delta.content)N.content=w.delta.content;if(w.delta.tool_calls)for(let D of w.delta.tool_calls){let V=U.get(D.index);if(V){if(D.function?.arguments)V.function.arguments+=D.function.arguments}else U.set(D.index,{id:D.id||"",type:"function",function:{name:D.function?.name||"",arguments:D.function?.arguments||""}})}if(w.finish_reason)N.finishReason=w.finish_reason;if(N.content||N.finishReason==="stop")yield N}}catch{}}}let H=Date.now()-Q;H1.debug(`✅ [CopilotChatService] Stream completed in ${H} ms`)}catch(X){let J=Date.now()-Q;throw H1.error(`❌ [CopilotChatService] Stream failed after ${J} ms`),H1.error(`❌ [CopilotChatService] Error: ${X}`),X}}sanitizeMessages($){let Z=[],Y=new Set;for(let Q=0;Q<$.length;Q++){let X=$[Q];if(X.role==="assistant"&&X.tool_calls&&X.tool_calls.length>0){let J=[];for(let G of X.tool_calls){let K=!1;for(let q=Q+1;q<$.length;q++){if($[q].role==="tool"&&$[q].tool_call_id===G.id){K=!0;break}if($[q].role==="assistant"||$[q].role==="user")break}if(K)J.push(G.id),Y.add(G.id)}if(J.length>0)Z.push({...X,tool_calls:X.tool_calls.filter((G)=>J.includes(G.id))});else Z.push({role:X.role,content:X.content||"",reasoningContent:X.reasoningContent})}else if(X.role==="tool"){if(X.tool_call_id&&Y.has(X.tool_call_id))Z.push(X)}else Z.push(X)}if(Z.length!==$.length)H1.debug(`[CopilotChatService] Sanitized messages: ${$.length} -> ${Z.length}`);return Z}buildRequest($,Z,Y=!1){let X=this.sanitizeMessages($).map((G)=>{let K;if(typeof G.content==="string")K=G.content;else if(Array.isArray(G.content))K=G.content.filter((W)=>W.type==="text").map((W)=>W.text).join(`
187
- `);else K=null;let q={role:G.role,content:K};if(G.tool_call_id)q.tool_call_id=G.tool_call_id;if(G.name)q.name=G.name;if(G.tool_calls&&G.tool_calls.length>0)q.tool_calls=G.tool_calls.filter((W)=>W.type==="function"&&("function"in W)).map((W)=>({id:W.id,type:"function",function:{name:W.function.name,arguments:W.function.arguments}}));return q}),J={model:this.config.model,messages:X,stream:Y};if(this.config.temperature!==void 0)J.temperature=this.config.temperature;if(this.config.maxOutputTokens)J.max_tokens=this.config.maxOutputTokens;if(Z&&Z.length>0)J.tools=Z.map((G)=>({type:"function",function:{name:G.name,description:G.description,parameters:this.cleanParameters(G.parameters)}})),J.tool_choice="auto";return J}cleanParameters($){if(!n8($))return{};let Z={};for(let[Y,Q]of Object.entries($)){if(["$ref","const","default"].includes(Y))continue;if(Y==="properties"&&n8(Q)){let X={};for(let[J,G]of Object.entries(Q))X[J]=n8(G)?this.cleanParameters(G):G;Z[Y]=X}else if(Y==="items"&&n8(Q))Z[Y]=this.cleanParameters(Q);else Z[Y]=Q}return Z}async makeRequest($,Z,Y){let Q=await A0(r3.chatCompletions,{method:"POST",headers:{Authorization:`Bearer ${$}`,"Content-Type":"application/json",Accept:"application/json","Copilot-Integration-Id":"vscode-chat","Editor-Version":"vscode/1.95.0","Editor-Plugin-Version":"copilot-chat/0.22.2024","User-Agent":"GitHubCopilotChat/0.22.2024"},body:JSON.stringify(Z),signal:Y});if(!Q.ok){let X=await Q.text();if(H1.error(`Copilot API error: ${Q.status} - ${X}`),Q.status===401)throw Error("Copilot token expired or invalid. Please run /login copilot again.");if(Q.status===403)throw Error("Permission denied. Please ensure you have an active GitHub Copilot subscription.");if(Q.status===429)throw Error("Rate limit exceeded. Please wait and try again.");throw Error(`Copilot API error: ${Q.status} - ${X}`)}return await Q.json()}parseResponse($){let Z=$.choices[0];if(!Z)throw Error("No response from Copilot API");let Y={content:Z.message.content||""};if(Z.message.tool_calls&&Z.message.tool_calls.length>0)Y.toolCalls=Z.message.tool_calls.map((Q)=>({id:Q.id,type:"function",function:{name:Q.function.name,arguments:Q.function.arguments}}));if($.usage)Y.usage={promptTokens:$.usage.prompt_tokens,completionTokens:$.usage.completion_tokens,totalTokens:$.usage.total_tokens};return Y}}var H1;var eQ=A(()=>{O$();$4();t3();n3();H1=l("Chat")});import{GoogleGenAI as $X}from"@google/genai";function ZX($){let Z=new Set;for(let Y of $)if(Y.role==="assistant"&&Y.tool_calls)for(let Q of Y.tool_calls)Z.add(Q.id);return $.filter((Y)=>{if(Y.role==="tool"){if(!Y.tool_call_id)return!1;return Z.has(Y.tool_call_id)}return!0})}function E7($){if(typeof $==="string")return $;return $.filter((Z)=>Z.type==="text").map((Z)=>Z.text).join(`
188
- `)}function P7($){let Z={};for(let[Y,Q]of Object.entries($)){if(Y==="$schema"||Y==="additionalProperties")continue;if(Q&&typeof Q==="object"&&!Array.isArray(Q))Z[Y]=P7(Q);else if(Array.isArray(Q))Z[Y]=Q.map((X)=>X&&typeof X==="object"&&!Array.isArray(X)?P7(X):X);else Z[Y]=Q}return Z}class T7{client;config;constructor($){if(this.config=$,f$.debug("\uD83D\uDE80 [GeminiChatService] Initializing"),f$.debug("⚙️ [GeminiChatService] Config:",{model:$.model,baseUrl:$.baseUrl,temperature:$.temperature,maxContextTokens:$.maxContextTokens,timeout:$.timeout,hasApiKey:!!$.apiKey}),!$.apiKey)throw f$.error("❌ [GeminiChatService] apiKey is required"),Error("apiKey is required in ChatConfig");if(!$.model)throw f$.error("❌ [GeminiChatService] model is required"),Error("model is required in ChatConfig");this.client=new $X({apiKey:$.apiKey}),f$.debug("✅ [GeminiChatService] Initialized successfully")}convertToGeminiMessages($){let Z=$.find((K)=>K.role==="system"),Y=Z?E7(Z.content):void 0,Q=[],X=$.filter((K)=>K.role!=="system"),J=new Map;for(let K of X)if(K.role==="assistant"&&K.tool_calls){for(let q of K.tool_calls)if(q.type==="function")J.set(q.id,q.function.name)}for(let K of X)if(K.role==="user"){let q=[];if(Array.isArray(K.content)){for(let W of K.content)if(W.type==="text")q.push({text:W.text});else if(W.type==="image_url"){let U=W.image_url.url;if(U.startsWith("data:")){let H=U.match(/^data:([^;,]+);base64,(.+)$/);if(H)q.push({inlineData:{mimeType:H[1],data:H[2]}})}else q.push({text:`[Image: ${U}]`})}}else q.push({text:K.content});Q.push({role:"user",parts:q})}else if(K.role==="assistant"){let q=[],W=E7(K.content);if(W)q.push({text:W});if(K.tool_calls)for(let U of K.tool_calls){if(U.type!=="function")continue;let H={};try{H=JSON.parse(U.function.arguments||"{}")}catch{f$.warn(`⚠️ [GeminiChatService] Failed to parse tool arguments: ${U.function.arguments}`)}q.push({functionCall:{name:U.function.name,args:H}})}if(q.length>0)Q.push({role:"model",parts:q})}else if(K.role==="tool"){let q=J.get(K.tool_call_id||"");if(q)Q.push({role:"user",parts:[{functionResponse:{name:q,response:{result:E7(K.content)}}}]})}let G=[];for(let K of Q){let q=G[G.length-1];if(q?.role===K.role){let W=q.parts||[],U=K.parts||[];q.parts=[...W,...U]}else G.push(K)}if(G.length>0&&G[0].role!=="user")G.unshift({role:"user",parts:[{text:"[Conversation start]"}]});return{systemInstruction:Y,contents:G}}convertToGeminiTools($){if(!$||$.length===0)return;return[{functionDeclarations:$.map((Y)=>({name:Y.name,description:Y.description,parameters:P7(Y.parameters||{type:"object",properties:{}})}))}]}async chat($,Z,Y){let Q=Date.now();f$.debug("\uD83D\uDE80 [GeminiChatService] Starting chat request"),f$.debug("\uD83D\uDCDD [GeminiChatService] Messages count:",$.length);let X=ZX($);if(X.length<$.length)f$.debug(`\uD83D\uDD27 [GeminiChatService] 过滤掉 ${$.length-X.length} 条孤儿 tool 消息`);let{systemInstruction:J,contents:G}=this.convertToGeminiMessages(X),K=this.convertToGeminiTools(Z);f$.debug("\uD83D\uDD27 [GeminiChatService] Tools count:",K?.[0]?.functionDeclarations?.length||0),f$.debug("\uD83D\uDCE4 [GeminiChatService] Request params:",{model:this.config.model,contentsCount:G.length,hasSystemInstruction:!!J,toolsCount:K?.[0]?.functionDeclarations?.length||0,maxOutputTokens:this.config.maxOutputTokens??4096,temperature:this.config.temperature??0});try{let q=await this.client.models.generateContent({model:this.config.model,contents:G,config:{systemInstruction:J||void 0,maxOutputTokens:this.config.maxOutputTokens??4096,temperature:this.config.temperature??0,tools:K}}),W=Date.now()-Q;f$.debug("\uD83D\uDCE5 [GeminiChatService] Response received in",W,"ms");let U="",H=[],O=q.candidates?.[0]?.content?.parts||[];for(let B of O)if("text"in B&&B.text)U+=B.text;else if("functionCall"in B&&B.functionCall){let L=B.functionCall;H.push({id:`call_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,type:"function",function:{name:L.name||"",arguments:JSON.stringify(L.args||{})}})}let z=q.usageMetadata,_={content:U,toolCalls:H.length>0?H:void 0,usage:{promptTokens:z?.promptTokenCount||0,completionTokens:z?.candidatesTokenCount||0,totalTokens:z?.totalTokenCount||0}};return f$.debug("✅ [GeminiChatService] Chat completed successfully"),f$.debug("\uD83D\uDCCA [GeminiChatService] Final response:",{contentLength:_.content.length,toolCallsCount:_.toolCalls?.length||0,usage:_.usage}),_}catch(q){let W=Date.now()-Q;throw f$.error("❌ [GeminiChatService] Chat request failed after",W,"ms"),f$.error("❌ [GeminiChatService] Error details:",q),q}}async*streamChat($,Z,Y){let Q=Date.now();f$.debug("\uD83D\uDE80 [GeminiChatService] Starting stream request"),f$.debug("\uD83D\uDCDD [GeminiChatService] Messages count:",$.length);let X=ZX($);if(X.length<$.length)f$.debug(`\uD83D\uDD27 [GeminiChatService] 过滤掉 ${$.length-X.length} 条孤儿 tool 消息`);let{systemInstruction:J,contents:G}=this.convertToGeminiMessages(X),K=this.convertToGeminiTools(Z);f$.debug("\uD83D\uDD27 [GeminiChatService] Stream tools count:",K?.[0]?.functionDeclarations?.length||0),f$.debug("\uD83D\uDCE4 [GeminiChatService] Stream request params:",{model:this.config.model,contentsCount:G.length,hasSystemInstruction:!!J,toolsCount:K?.[0]?.functionDeclarations?.length||0,maxOutputTokens:this.config.maxOutputTokens??4096,temperature:this.config.temperature??0});try{let q=await this.client.models.generateContentStream({model:this.config.model,contents:G,config:{systemInstruction:J||void 0,maxOutputTokens:this.config.maxOutputTokens??4096,temperature:this.config.temperature??0,tools:K}}),W=Date.now()-Q;f$.debug("\uD83D\uDCE5 [GeminiChatService] Stream started in",W,"ms");let U=0,H="",F=!1;for await(let O of q){U++;let z=O.candidates?.[0],_=z?.content?.parts||[],B=O.usageMetadata;for(let w of _)if("text"in w&&w.text)H+=w.text,yield{content:w.text};else if("functionCall"in w&&w.functionCall){F=!0;let N=w.functionCall;yield{toolCalls:[{id:`call_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,type:"function",function:{name:N.name||"",arguments:JSON.stringify(N.args||{})}}]}}let L=z?.finishReason;if(L){f$.debug("\uD83C\uDFC1 [GeminiChatService] Stream finished:",L),f$.debug("\uD83D\uDCCA [GeminiChatService] Stream summary:",{totalEvents:U,totalContentLength:H.length,hadToolCalls:F,duration:Date.now()-Q+"ms"});let w;if(L==="STOP")w="stop";else if(L==="MAX_TOKENS")w="length";else w=L.toLowerCase();let N={finishReason:w};if(B)N.usage={promptTokens:B.promptTokenCount||0,completionTokens:B.candidatesTokenCount||0,totalTokens:B.totalTokenCount||0};yield N}else if(B)yield{usage:{promptTokens:B.promptTokenCount||0,completionTokens:B.candidatesTokenCount||0,totalTokens:B.totalTokenCount||0}}}f$.debug("✅ [GeminiChatService] Stream completed successfully")}catch(q){let W=Date.now()-Q;throw f$.error("❌ [GeminiChatService] Stream request failed after",W,"ms"),f$.error("❌ [GeminiChatService] Stream error details:",q),q}}getConfig(){return{...this.config}}updateConfig($){f$.debug("\uD83D\uDD04 [GeminiChatService] Updating configuration"),this.config={...this.config,...$},this.client=new $X({apiKey:this.config.apiKey}),f$.debug("✅ [GeminiChatService] Configuration updated successfully")}}var f$;var YX=A(()=>{O$();f$=l("Chat")});import{isPlainObject as GO}from"lodash-es";import QX from"openai";function KO($){for(let Z of JX){let Y=$[Z];if(Y)return{content:Y,fieldName:Z}}return}function XX($){let Z=new Set;for(let Y of $)if(Y.role==="assistant"&&Y.tool_calls)for(let Q of Y.tool_calls)Z.add(Q.id);return $.filter((Y)=>{if(Y.role==="tool"){if(!Y.tool_call_id)return!1;return Z.has(Y.tool_call_id)}return!0})}class o8{config;client;detectedReasoningFieldName=null;convertToOpenAIMessages($){return $.map((Z)=>{if(Z.role==="tool")return{role:"tool",content:typeof Z.content==="string"?Z.content:Z.content.filter((Q)=>Q.type==="text").map((Q)=>Q.text).join(`
187
+ `);else K=null;let q={role:G.role,content:K};if(G.tool_call_id)q.tool_call_id=G.tool_call_id;if(G.name)q.name=G.name;if(G.tool_calls&&G.tool_calls.length>0)q.tool_calls=G.tool_calls.filter((W)=>W.type==="function"&&("function"in W)).map((W)=>({id:W.id,type:"function",function:{name:W.function.name,arguments:W.function.arguments}}));return q}),J={model:this.config.model,messages:X,stream:Y};if(this.config.temperature!==void 0)J.temperature=this.config.temperature;if(this.config.maxOutputTokens)J.max_tokens=this.config.maxOutputTokens;if(Z&&Z.length>0)J.tools=Z.map((G)=>({type:"function",function:{name:G.name,description:G.description,parameters:this.cleanParameters(G.parameters)}})),J.tool_choice="auto";return J}cleanParameters($){if(!n3($))return{};let Z={};for(let[Y,Q]of Object.entries($)){if(["$ref","const","default"].includes(Y))continue;if(Y==="properties"&&n3(Q)){let X={};for(let[J,G]of Object.entries(Q))X[J]=n3(G)?this.cleanParameters(G):G;Z[Y]=X}else if(Y==="items"&&n3(Q))Z[Y]=this.cleanParameters(Q);else Z[Y]=Q}return Z}async makeRequest($,Z,Y){let Q=await A0(r8.chatCompletions,{method:"POST",headers:{Authorization:`Bearer ${$}`,"Content-Type":"application/json",Accept:"application/json","Copilot-Integration-Id":"vscode-chat","Editor-Version":"vscode/1.95.0","Editor-Plugin-Version":"copilot-chat/0.22.2024","User-Agent":"GitHubCopilotChat/0.22.2024"},body:JSON.stringify(Z),signal:Y});if(!Q.ok){let X=await Q.text();if(H1.error(`Copilot API error: ${Q.status} - ${X}`),Q.status===401)throw Error("Copilot token expired or invalid. Please run /login copilot again.");if(Q.status===403)throw Error("Permission denied. Please ensure you have an active GitHub Copilot subscription.");if(Q.status===429)throw Error("Rate limit exceeded. Please wait and try again.");throw Error(`Copilot API error: ${Q.status} - ${X}`)}return await Q.json()}parseResponse($){let Z=$.choices[0];if(!Z)throw Error("No response from Copilot API");let Y={content:Z.message.content||""};if(Z.message.tool_calls&&Z.message.tool_calls.length>0)Y.toolCalls=Z.message.tool_calls.map((Q)=>({id:Q.id,type:"function",function:{name:Q.function.name,arguments:Q.function.arguments}}));if($.usage)Y.usage={promptTokens:$.usage.prompt_tokens,completionTokens:$.usage.completion_tokens,totalTokens:$.usage.total_tokens};return Y}}var H1;var eQ=A(()=>{O$();$2();t8();n8();H1=l("Chat")});import{GoogleGenAI as $X}from"@google/genai";function ZX($){let Z=new Set;for(let Y of $)if(Y.role==="assistant"&&Y.tool_calls)for(let Q of Y.tool_calls)Z.add(Q.id);return $.filter((Y)=>{if(Y.role==="tool"){if(!Y.tool_call_id)return!1;return Z.has(Y.tool_call_id)}return!0})}function E7($){if(typeof $==="string")return $;return $.filter((Z)=>Z.type==="text").map((Z)=>Z.text).join(`
188
+ `)}function P7($){let Z={};for(let[Y,Q]of Object.entries($)){if(Y==="$schema"||Y==="additionalProperties")continue;if(Q&&typeof Q==="object"&&!Array.isArray(Q))Z[Y]=P7(Q);else if(Array.isArray(Q))Z[Y]=Q.map((X)=>X&&typeof X==="object"&&!Array.isArray(X)?P7(X):X);else Z[Y]=Q}return Z}class T7{client;config;constructor($){if(this.config=$,f$.debug("\uD83D\uDE80 [GeminiChatService] Initializing"),f$.debug("⚙️ [GeminiChatService] Config:",{model:$.model,baseUrl:$.baseUrl,temperature:$.temperature,maxContextTokens:$.maxContextTokens,timeout:$.timeout,hasApiKey:!!$.apiKey}),!$.apiKey)throw f$.error("❌ [GeminiChatService] apiKey is required"),Error("apiKey is required in ChatConfig");if(!$.model)throw f$.error("❌ [GeminiChatService] model is required"),Error("model is required in ChatConfig");this.client=new $X({apiKey:$.apiKey}),f$.debug("✅ [GeminiChatService] Initialized successfully")}convertToGeminiMessages($){let Z=$.find((K)=>K.role==="system"),Y=Z?E7(Z.content):void 0,Q=[],X=$.filter((K)=>K.role!=="system"),J=new Map;for(let K of X)if(K.role==="assistant"&&K.tool_calls){for(let q of K.tool_calls)if(q.type==="function")J.set(q.id,q.function.name)}for(let K of X)if(K.role==="user"){let q=[];if(Array.isArray(K.content)){for(let W of K.content)if(W.type==="text")q.push({text:W.text});else if(W.type==="image_url"){let U=W.image_url.url;if(U.startsWith("data:")){let H=U.match(/^data:([^;,]+);base64,(.+)$/);if(H)q.push({inlineData:{mimeType:H[1],data:H[2]}})}else q.push({text:`[Image: ${U}]`})}}else q.push({text:K.content});Q.push({role:"user",parts:q})}else if(K.role==="assistant"){let q=[],W=E7(K.content);if(W)q.push({text:W});if(K.tool_calls)for(let U of K.tool_calls){if(U.type!=="function")continue;let H={};try{H=JSON.parse(U.function.arguments||"{}")}catch{f$.warn(`⚠️ [GeminiChatService] Failed to parse tool arguments: ${U.function.arguments}`)}q.push({functionCall:{name:U.function.name,args:H}})}if(q.length>0)Q.push({role:"model",parts:q})}else if(K.role==="tool"){let q=J.get(K.tool_call_id||"");if(q)Q.push({role:"user",parts:[{functionResponse:{name:q,response:{result:E7(K.content)}}}]})}let G=[];for(let K of Q){let q=G[G.length-1];if(q?.role===K.role){let W=q.parts||[],U=K.parts||[];q.parts=[...W,...U]}else G.push(K)}if(G.length>0&&G[0].role!=="user")G.unshift({role:"user",parts:[{text:"[Conversation start]"}]});return{systemInstruction:Y,contents:G}}convertToGeminiTools($){if(!$||$.length===0)return;return[{functionDeclarations:$.map((Y)=>({name:Y.name,description:Y.description,parameters:P7(Y.parameters||{type:"object",properties:{}})}))}]}async chat($,Z,Y){let Q=Date.now();f$.debug("\uD83D\uDE80 [GeminiChatService] Starting chat request"),f$.debug("\uD83D\uDCDD [GeminiChatService] Messages count:",$.length);let X=ZX($);if(X.length<$.length)f$.debug(`\uD83D\uDD27 [GeminiChatService] 过滤掉 ${$.length-X.length} 条孤儿 tool 消息`);let{systemInstruction:J,contents:G}=this.convertToGeminiMessages(X),K=this.convertToGeminiTools(Z);f$.debug("\uD83D\uDD27 [GeminiChatService] Tools count:",K?.[0]?.functionDeclarations?.length||0),f$.debug("\uD83D\uDCE4 [GeminiChatService] Request params:",{model:this.config.model,contentsCount:G.length,hasSystemInstruction:!!J,toolsCount:K?.[0]?.functionDeclarations?.length||0,maxOutputTokens:this.config.maxOutputTokens??4096,temperature:this.config.temperature??0});try{let q=await this.client.models.generateContent({model:this.config.model,contents:G,config:{systemInstruction:J||void 0,maxOutputTokens:this.config.maxOutputTokens??4096,temperature:this.config.temperature??0,tools:K}}),W=Date.now()-Q;f$.debug("\uD83D\uDCE5 [GeminiChatService] Response received in",W,"ms");let U="",H=[],O=q.candidates?.[0]?.content?.parts||[];for(let B of O)if("text"in B&&B.text)U+=B.text;else if("functionCall"in B&&B.functionCall){let L=B.functionCall;H.push({id:`call_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,type:"function",function:{name:L.name||"",arguments:JSON.stringify(L.args||{})}})}let z=q.usageMetadata,_={content:U,toolCalls:H.length>0?H:void 0,usage:{promptTokens:z?.promptTokenCount||0,completionTokens:z?.candidatesTokenCount||0,totalTokens:z?.totalTokenCount||0}};return f$.debug("✅ [GeminiChatService] Chat completed successfully"),f$.debug("\uD83D\uDCCA [GeminiChatService] Final response:",{contentLength:_.content.length,toolCallsCount:_.toolCalls?.length||0,usage:_.usage}),_}catch(q){let W=Date.now()-Q;throw f$.error("❌ [GeminiChatService] Chat request failed after",W,"ms"),f$.error("❌ [GeminiChatService] Error details:",q),q}}async*streamChat($,Z,Y){let Q=Date.now();f$.debug("\uD83D\uDE80 [GeminiChatService] Starting stream request"),f$.debug("\uD83D\uDCDD [GeminiChatService] Messages count:",$.length);let X=ZX($);if(X.length<$.length)f$.debug(`\uD83D\uDD27 [GeminiChatService] 过滤掉 ${$.length-X.length} 条孤儿 tool 消息`);let{systemInstruction:J,contents:G}=this.convertToGeminiMessages(X),K=this.convertToGeminiTools(Z);f$.debug("\uD83D\uDD27 [GeminiChatService] Stream tools count:",K?.[0]?.functionDeclarations?.length||0),f$.debug("\uD83D\uDCE4 [GeminiChatService] Stream request params:",{model:this.config.model,contentsCount:G.length,hasSystemInstruction:!!J,toolsCount:K?.[0]?.functionDeclarations?.length||0,maxOutputTokens:this.config.maxOutputTokens??4096,temperature:this.config.temperature??0});try{let q=await this.client.models.generateContentStream({model:this.config.model,contents:G,config:{systemInstruction:J||void 0,maxOutputTokens:this.config.maxOutputTokens??4096,temperature:this.config.temperature??0,tools:K}}),W=Date.now()-Q;f$.debug("\uD83D\uDCE5 [GeminiChatService] Stream started in",W,"ms");let U=0,H="",F=!1;for await(let O of q){U++;let z=O.candidates?.[0],_=z?.content?.parts||[],B=O.usageMetadata;for(let w of _)if("text"in w&&w.text)H+=w.text,yield{content:w.text};else if("functionCall"in w&&w.functionCall){F=!0;let N=w.functionCall;yield{toolCalls:[{id:`call_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,type:"function",function:{name:N.name||"",arguments:JSON.stringify(N.args||{})}}]}}let L=z?.finishReason;if(L){f$.debug("\uD83C\uDFC1 [GeminiChatService] Stream finished:",L),f$.debug("\uD83D\uDCCA [GeminiChatService] Stream summary:",{totalEvents:U,totalContentLength:H.length,hadToolCalls:F,duration:Date.now()-Q+"ms"});let w;if(L==="STOP")w="stop";else if(L==="MAX_TOKENS")w="length";else w=L.toLowerCase();let N={finishReason:w};if(B)N.usage={promptTokens:B.promptTokenCount||0,completionTokens:B.candidatesTokenCount||0,totalTokens:B.totalTokenCount||0};yield N}else if(B)yield{usage:{promptTokens:B.promptTokenCount||0,completionTokens:B.candidatesTokenCount||0,totalTokens:B.totalTokenCount||0}}}f$.debug("✅ [GeminiChatService] Stream completed successfully")}catch(q){let W=Date.now()-Q;throw f$.error("❌ [GeminiChatService] Stream request failed after",W,"ms"),f$.error("❌ [GeminiChatService] Stream error details:",q),q}}getConfig(){return{...this.config}}updateConfig($){f$.debug("\uD83D\uDD04 [GeminiChatService] Updating configuration"),this.config={...this.config,...$},this.client=new $X({apiKey:this.config.apiKey}),f$.debug("✅ [GeminiChatService] Configuration updated successfully")}}var f$;var YX=A(()=>{O$();f$=l("Chat")});import{isPlainObject as GO}from"lodash-es";import QX from"openai";function KO($){for(let Z of JX){let Y=$[Z];if(Y)return{content:Y,fieldName:Z}}return}function XX($){let Z=new Set;for(let Y of $)if(Y.role==="assistant"&&Y.tool_calls)for(let Q of Y.tool_calls)Z.add(Q.id);return $.filter((Y)=>{if(Y.role==="tool"){if(!Y.tool_call_id)return!1;return Z.has(Y.tool_call_id)}return!0})}class o3{config;client;detectedReasoningFieldName=null;convertToOpenAIMessages($){return $.map((Z)=>{if(Z.role==="tool")return{role:"tool",content:typeof Z.content==="string"?Z.content:Z.content.filter((Q)=>Q.type==="text").map((Q)=>Q.text).join(`
189
189
  `),tool_call_id:Z.tool_call_id};if(Z.role==="assistant"&&Z.tool_calls){let Q={role:"assistant",content:(typeof Z.content==="string"?Z.content:Z.content.filter((X)=>X.type==="text").map((X)=>X.text).join(`
190
190
  `))||null,tool_calls:Z.tool_calls};if(this.config.supportsThinking){let X="reasoningContent"in Z&&Z.reasoningContent?Z.reasoningContent:"";if(this.detectedReasoningFieldName)Q[this.detectedReasoningFieldName]=X;else for(let J of JX)Q[J]=X}return Q}if(Z.role==="user"&&Array.isArray(Z.content))return{role:"user",content:Z.content.map((Y)=>{if(Y.type==="text")return{type:"text",text:Y.text};return{type:"image_url",image_url:{url:Y.image_url.url}}})};return{role:Z.role,content:typeof Z.content==="string"?Z.content:Z.content.filter((Y)=>Y.type==="text").map((Y)=>Y.text).join(`
191
- `)}})}convertToOpenAITools($){return $?.map((Z)=>({type:"function",function:{name:Z.name,description:Z.description,parameters:GO(Z.parameters)?Z.parameters:{}}}))}extractAndDetectReasoning($){let Z=KO($);if(Z){if(!this.detectedReasoningFieldName)this.detectedReasoningFieldName=Z.fieldName,X$.debug(`\uD83E\uDDE0 [ChatService] Detected reasoning field: ${Z.fieldName}`);return Z.content}return}constructor($){this.config=$;if(X$.debug("\uD83D\uDE80 [ChatService] Initializing ChatService"),X$.debug("⚙️ [ChatService] Config:",{model:$.model,baseUrl:$.baseUrl,temperature:$.temperature,maxContextTokens:$.maxContextTokens,timeout:$.timeout,hasApiKey:!!$.apiKey}),!$.baseUrl)throw X$.error("❌ [ChatService] baseUrl is required in ChatConfig"),Error("baseUrl is required in ChatConfig");if(!$.apiKey)throw X$.error("❌ [ChatService] apiKey is required in ChatConfig"),Error("apiKey is required in ChatConfig");if(!$.model)throw X$.error("❌ [ChatService] model is required in ChatConfig"),Error("model is required in ChatConfig");this.client=new QX({apiKey:$.apiKey,baseURL:$.baseUrl,timeout:$.timeout??180000,maxRetries:3}),X$.debug("✅ [ChatService] ChatService initialized successfully")}async chat($,Z,Y){let Q=Date.now();X$.debug("\uD83D\uDE80 [ChatService] Starting chat request"),X$.debug("\uD83D\uDCDD [ChatService] Messages count:",$.length);let X=XX($);if(X.length<$.length)X$.debug(`\uD83D\uDD27 [ChatService] 过滤掉 ${$.length-X.length} 条孤儿 tool 消息`);X$.debug("\uD83D\uDCDD [ChatService] Messages preview:",X.map((q)=>({role:q.role,contentLength:typeof q.content==="string"?q.content.length:q.content.length,isMultimodal:Array.isArray(q.content)})));let J=this.convertToOpenAIMessages(X),G=this.convertToOpenAITools(Z);if(X$.debug("\uD83D\uDD27 [ChatService] Tools count:",G?.length||0),G&&G.length>0)X$.debug("\uD83D\uDD27 [ChatService] Available tools:",G.map((q)=>q.type==="function"?q.function.name:"unknown"));let K={model:this.config.model,messages:J,tools:G,tool_choice:G&&G.length>0?"auto":void 0,max_tokens:this.config.maxOutputTokens??32768,temperature:this.config.temperature??0};X$.debug("\uD83D\uDCE4 [ChatService] Request params:",{model:K.model,messagesCount:K.messages.length,toolsCount:K.tools?.length||0,tool_choice:K.tool_choice,max_tokens:K.max_tokens,temperature:K.temperature});try{let q=await this.client.chat.completions.create(K,{signal:Y}),W=Date.now()-Q;if(X$.debug("\uD83D\uDCE5 [ChatService] Response received in",W,"ms"),!q)throw X$.error("❌ [ChatService] API returned null/undefined response"),Error("API returned null/undefined response");if(!q.choices||!Array.isArray(q.choices))throw X$.error("❌ [ChatService] Invalid API response format - missing choices array"),X$.error("❌ [ChatService] Response object:",JSON.stringify(q,null,2)),Error(`Invalid API response: missing choices array. Response: ${JSON.stringify(q)}`);if(q.choices.length===0)throw X$.error("❌ [ChatService] API returned empty choices array"),Error("API returned empty choices array");X$.debug("\uD83D\uDCCA [ChatService] Response usage:",q.usage),X$.debug("\uD83D\uDCCA [ChatService] Response choices count:",q.choices.length);let U=q.choices[0];if(!U)throw X$.error("❌ [ChatService] No completion choice returned"),Error("No completion choice returned");if(X$.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)X$.debug("\uD83D\uDD27 [ChatService] Tool calls:",U.message.tool_calls.map((B)=>({id:B.id,type:B.type,functionName:B.type==="function"?B.function?.name:"unknown",functionArgsLength:B.type==="function"?B.function?.arguments?.length||0:0})));let H=U.message.tool_calls?.filter((B)=>B.type==="function"),F=U.message,O=this.extractAndDetectReasoning(F);if(this.config.supportsThinking)X$.debug("\uD83E\uDDE0 [ChatService] Thinking model response:",{reasoningContentLength:O?.length||0,detectedFieldName:this.detectedReasoningFieldName,messageKeys:Object.keys(U.message)});let z=q.usage,_={content:U.message.content||"",reasoningContent:O,toolCalls:H,usage:{promptTokens:q.usage?.prompt_tokens||0,completionTokens:q.usage?.completion_tokens||0,totalTokens:q.usage?.total_tokens||0,reasoningTokens:z?.reasoning_tokens}};return X$.debug("✅ [ChatService] Chat completed successfully"),X$.debug("\uD83D\uDCCA [ChatService] Final response:",{contentLength:_.content.length,toolCallsCount:_.toolCalls?.length||0,usage:_.usage}),_}catch(q){let W=Date.now()-Q;throw X$.error("❌ [ChatService] Chat request failed after",W,"ms"),X$.error("❌ [ChatService] Error details:",q),q}}async*streamChat($,Z,Y){let Q=Date.now();X$.debug("\uD83D\uDE80 [ChatService] Starting chat stream request"),X$.debug("\uD83D\uDCDD [ChatService] Messages count:",$.length);let X=XX($);if(X.length<$.length)X$.debug(`\uD83D\uDD27 [ChatService] 过滤掉 ${$.length-X.length} 条孤儿 tool 消息`);X$.debug("\uD83D\uDCDD [ChatService] Messages preview:",X.map((q)=>({role:q.role,contentLength:typeof q.content==="string"?q.content.length:q.content.length,isMultimodal:Array.isArray(q.content)})));let J=this.convertToOpenAIMessages(X),G=this.convertToOpenAITools(Z);if(X$.debug("\uD83D\uDD27 [ChatService] Stream tools count:",G?.length||0),G&&G.length>0)X$.debug("\uD83D\uDD27 [ChatService] Stream available tools:",G.map((q)=>q.type==="function"?q.function.name:"unknown"));let K={model:this.config.model,messages:J,tools:G,tool_choice:G&&G.length>0?"auto":"none",max_tokens:this.config.maxOutputTokens??32768,temperature:this.config.temperature??0,stream:!0,stream_options:{include_usage:!0}};X$.debug("\uD83D\uDCE4 [ChatService] Stream request params:",{model:K.model,messagesCount:K.messages.length,toolsCount:K.tools?.length||0,tool_choice:K.tool_choice,max_tokens:K.max_tokens,temperature:K.temperature,stream:K.stream});try{let q;try{q=await this.client.chat.completions.create(K,{signal:Y})}catch(z){if(!i8(z))throw z;X$.warn("⚠️ [ChatService] stream_options 不被支持,已降级为无 usage 流式请求");let{stream_options:_,...B}=K;q=await this.client.chat.completions.create(B,{signal:Y})}let W=Date.now()-Q;X$.debug("\uD83D\uDCE5 [ChatService] Stream started in",W,"ms");let U=0,H="",F="",O=!1;for await(let z of q){U++;let _=z.usage;if(!z||!z.choices||!Array.isArray(z.choices)){if(_){yield{usage:{promptTokens:_.prompt_tokens||0,completionTokens:_.completion_tokens||0,totalTokens:_.total_tokens||0,reasoningTokens:_.reasoning_tokens}};continue}X$.warn("⚠️ [ChatService] Invalid chunk format in stream",U);continue}let B=z.choices[0]?.delta;if(!B){if(_){yield{usage:{promptTokens:_.prompt_tokens||0,completionTokens:_.completion_tokens||0,totalTokens:_.total_tokens||0,reasoningTokens:_.reasoning_tokens}};continue}X$.warn("⚠️ [ChatService] Empty delta in chunk",U);continue}let L=B,w=this.extractAndDetectReasoning(L);if(B.content)H+=B.content;if(w)F+=w;if(B.tool_calls&&!O)O=!0,X$.debug("\uD83D\uDD27 [ChatService] Tool calls detected in stream");let N=z.choices[0]?.finish_reason;if(N)X$.debug("\uD83C\uDFC1 [ChatService] Stream finished with reason:",N),X$.debug("\uD83D\uDCCA [ChatService] Stream summary:",{totalChunks:U,totalContentLength:H.length,totalReasoningContentLength:F.length,hadToolCalls:O,duration:Date.now()-Q+"ms"});let D={content:B.content||void 0,reasoningContent:w,toolCalls:B.tool_calls,finishReason:N||void 0};if(_)D.usage={promptTokens:_.prompt_tokens||0,completionTokens:_.completion_tokens||0,totalTokens:_.total_tokens||0,reasoningTokens:_.reasoning_tokens};yield D}X$.debug("✅ [ChatService] Stream completed successfully")}catch(q){let W=Date.now()-Q;throw X$.error("❌ [ChatService] Stream request failed after",W,"ms"),X$.error("❌ [ChatService] Stream error details:",q),q}}getConfig(){return{...this.config}}updateConfig($){X$.debug("\uD83D\uDD04 [ChatService] Updating configuration"),X$.debug("\uD83D\uDD04 [ChatService] New config:",{model:$.model,baseUrl:$.baseUrl,temperature:$.temperature,maxContextTokens:$.maxContextTokens,timeout:$.timeout,hasApiKey:!!$.apiKey});let Z={...this.config};if(this.config={...this.config,...$},Z.baseUrl!==this.config.baseUrl)this.detectedReasoningFieldName=null,X$.debug("\uD83D\uDD04 [ChatService] Reset detectedReasoningFieldName due to baseUrl change");this.client=new QX({apiKey:this.config.apiKey,baseURL:this.config.baseUrl,timeout:this.config.timeout??180000,maxRetries:2}),X$.debug("✅ [ChatService] Configuration updated successfully"),X$.debug("\uD83D\uDCCA [ChatService] Config changes:",{modelChanged:Z.model!==this.config.model,baseUrlChanged:Z.baseUrl!==this.config.baseUrl,temperatureChanged:Z.temperature!==this.config.temperature,maxContextTokensChanged:Z.maxContextTokens!==this.config.maxContextTokens,timeoutChanged:Z.timeout!==this.config.timeout,apiKeyChanged:Z.apiKey!==this.config.apiKey})}}var X$,JX;var GX=A(()=>{O$();X$=l("Chat"),JX=["reasoning_content","reasoning","reasoningContent","thinking_content"]});async function s8($){let Z=$;if(w7($.apiKey)){KX.info("\uD83D\uDD11 检测到内置 API Key,正在获取...");let Y=await sQ($.apiKey);Z={...$,apiKey:Y}}return qO(Z)}function qO($){switch($.provider){case"openai-compatible":return new o8($);case"anthropic":return new A7($);case"gemini":return new T7($);case"azure-openai":return new j7($);case"antigravity":return new M7($);case"copilot":return new v7($);default:return KX.warn(`⚠️ 未知的 provider: ${$.provider}, 回退到 openai-compatible`),new o8($)}}var KX;var C7=A(()=>{u8();O$();pQ();iQ();nQ();tQ();eQ();YX();GX();KX=l("Service")});import{readFile as WO}from"node:fs/promises";import{basename as UO}from"node:path";class t8{static MAX_FILES=5;static MAX_LINES_PER_FILE=1000;static analyzeFiles($){let Z=new Map;return $.forEach((Q,X)=>{let J=typeof Q.content==="string"?Q.content:(Q.content||[]).filter((K)=>K.type==="text").map((K)=>K.text).join(`
191
+ `)}})}convertToOpenAITools($){return $?.map((Z)=>({type:"function",function:{name:Z.name,description:Z.description,parameters:GO(Z.parameters)?Z.parameters:{}}}))}extractAndDetectReasoning($){let Z=KO($);if(Z){if(!this.detectedReasoningFieldName)this.detectedReasoningFieldName=Z.fieldName,X$.debug(`\uD83E\uDDE0 [ChatService] Detected reasoning field: ${Z.fieldName}`);return Z.content}return}constructor($){this.config=$;if(X$.debug("\uD83D\uDE80 [ChatService] Initializing ChatService"),X$.debug("⚙️ [ChatService] Config:",{model:$.model,baseUrl:$.baseUrl,temperature:$.temperature,maxContextTokens:$.maxContextTokens,timeout:$.timeout,hasApiKey:!!$.apiKey}),!$.baseUrl)throw X$.error("❌ [ChatService] baseUrl is required in ChatConfig"),Error("baseUrl is required in ChatConfig");if(!$.apiKey)throw X$.error("❌ [ChatService] apiKey is required in ChatConfig"),Error("apiKey is required in ChatConfig");if(!$.model)throw X$.error("❌ [ChatService] model is required in ChatConfig"),Error("model is required in ChatConfig");this.client=new QX({apiKey:$.apiKey,baseURL:$.baseUrl,timeout:$.timeout??180000,maxRetries:3}),X$.debug("✅ [ChatService] ChatService initialized successfully")}async chat($,Z,Y){let Q=Date.now();X$.debug("\uD83D\uDE80 [ChatService] Starting chat request"),X$.debug("\uD83D\uDCDD [ChatService] Messages count:",$.length);let X=XX($);if(X.length<$.length)X$.debug(`\uD83D\uDD27 [ChatService] 过滤掉 ${$.length-X.length} 条孤儿 tool 消息`);X$.debug("\uD83D\uDCDD [ChatService] Messages preview:",X.map((q)=>({role:q.role,contentLength:typeof q.content==="string"?q.content.length:q.content.length,isMultimodal:Array.isArray(q.content)})));let J=this.convertToOpenAIMessages(X),G=this.convertToOpenAITools(Z);if(X$.debug("\uD83D\uDD27 [ChatService] Tools count:",G?.length||0),G&&G.length>0)X$.debug("\uD83D\uDD27 [ChatService] Available tools:",G.map((q)=>q.type==="function"?q.function.name:"unknown"));let K={model:this.config.model,messages:J,tools:G,tool_choice:G&&G.length>0?"auto":void 0,max_tokens:this.config.maxOutputTokens??32768,temperature:this.config.temperature??0};X$.debug("\uD83D\uDCE4 [ChatService] Request params:",{model:K.model,messagesCount:K.messages.length,toolsCount:K.tools?.length||0,tool_choice:K.tool_choice,max_tokens:K.max_tokens,temperature:K.temperature});try{let q=await this.client.chat.completions.create(K,{signal:Y}),W=Date.now()-Q;if(X$.debug("\uD83D\uDCE5 [ChatService] Response received in",W,"ms"),!q)throw X$.error("❌ [ChatService] API returned null/undefined response"),Error("API returned null/undefined response");if(!q.choices||!Array.isArray(q.choices))throw X$.error("❌ [ChatService] Invalid API response format - missing choices array"),X$.error("❌ [ChatService] Response object:",JSON.stringify(q,null,2)),Error(`Invalid API response: missing choices array. Response: ${JSON.stringify(q)}`);if(q.choices.length===0)throw X$.error("❌ [ChatService] API returned empty choices array"),Error("API returned empty choices array");X$.debug("\uD83D\uDCCA [ChatService] Response usage:",q.usage),X$.debug("\uD83D\uDCCA [ChatService] Response choices count:",q.choices.length);let U=q.choices[0];if(!U)throw X$.error("❌ [ChatService] No completion choice returned"),Error("No completion choice returned");if(X$.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)X$.debug("\uD83D\uDD27 [ChatService] Tool calls:",U.message.tool_calls.map((B)=>({id:B.id,type:B.type,functionName:B.type==="function"?B.function?.name:"unknown",functionArgsLength:B.type==="function"?B.function?.arguments?.length||0:0})));let H=U.message.tool_calls?.filter((B)=>B.type==="function"),F=U.message,O=this.extractAndDetectReasoning(F);if(this.config.supportsThinking)X$.debug("\uD83E\uDDE0 [ChatService] Thinking model response:",{reasoningContentLength:O?.length||0,detectedFieldName:this.detectedReasoningFieldName,messageKeys:Object.keys(U.message)});let z=q.usage,_={content:U.message.content||"",reasoningContent:O,toolCalls:H,usage:{promptTokens:q.usage?.prompt_tokens||0,completionTokens:q.usage?.completion_tokens||0,totalTokens:q.usage?.total_tokens||0,reasoningTokens:z?.reasoning_tokens}};return X$.debug("✅ [ChatService] Chat completed successfully"),X$.debug("\uD83D\uDCCA [ChatService] Final response:",{contentLength:_.content.length,toolCallsCount:_.toolCalls?.length||0,usage:_.usage}),_}catch(q){let W=Date.now()-Q;throw X$.error("❌ [ChatService] Chat request failed after",W,"ms"),X$.error("❌ [ChatService] Error details:",q),q}}async*streamChat($,Z,Y){let Q=Date.now();X$.debug("\uD83D\uDE80 [ChatService] Starting chat stream request"),X$.debug("\uD83D\uDCDD [ChatService] Messages count:",$.length);let X=XX($);if(X.length<$.length)X$.debug(`\uD83D\uDD27 [ChatService] 过滤掉 ${$.length-X.length} 条孤儿 tool 消息`);X$.debug("\uD83D\uDCDD [ChatService] Messages preview:",X.map((q)=>({role:q.role,contentLength:typeof q.content==="string"?q.content.length:q.content.length,isMultimodal:Array.isArray(q.content)})));let J=this.convertToOpenAIMessages(X),G=this.convertToOpenAITools(Z);if(X$.debug("\uD83D\uDD27 [ChatService] Stream tools count:",G?.length||0),G&&G.length>0)X$.debug("\uD83D\uDD27 [ChatService] Stream available tools:",G.map((q)=>q.type==="function"?q.function.name:"unknown"));let K={model:this.config.model,messages:J,tools:G,tool_choice:G&&G.length>0?"auto":"none",max_tokens:this.config.maxOutputTokens??32768,temperature:this.config.temperature??0,stream:!0,stream_options:{include_usage:!0}};X$.debug("\uD83D\uDCE4 [ChatService] Stream request params:",{model:K.model,messagesCount:K.messages.length,toolsCount:K.tools?.length||0,tool_choice:K.tool_choice,max_tokens:K.max_tokens,temperature:K.temperature,stream:K.stream});try{let q;try{q=await this.client.chat.completions.create(K,{signal:Y})}catch(z){if(!i3(z))throw z;X$.warn("⚠️ [ChatService] stream_options 不被支持,已降级为无 usage 流式请求");let{stream_options:_,...B}=K;q=await this.client.chat.completions.create(B,{signal:Y})}let W=Date.now()-Q;X$.debug("\uD83D\uDCE5 [ChatService] Stream started in",W,"ms");let U=0,H="",F="",O=!1;for await(let z of q){U++;let _=z.usage;if(!z||!z.choices||!Array.isArray(z.choices)){if(_){yield{usage:{promptTokens:_.prompt_tokens||0,completionTokens:_.completion_tokens||0,totalTokens:_.total_tokens||0,reasoningTokens:_.reasoning_tokens}};continue}X$.warn("⚠️ [ChatService] Invalid chunk format in stream",U);continue}let B=z.choices[0]?.delta;if(!B){if(_){yield{usage:{promptTokens:_.prompt_tokens||0,completionTokens:_.completion_tokens||0,totalTokens:_.total_tokens||0,reasoningTokens:_.reasoning_tokens}};continue}X$.warn("⚠️ [ChatService] Empty delta in chunk",U);continue}let L=B,w=this.extractAndDetectReasoning(L);if(B.content)H+=B.content;if(w)F+=w;if(B.tool_calls&&!O)O=!0,X$.debug("\uD83D\uDD27 [ChatService] Tool calls detected in stream");let N=z.choices[0]?.finish_reason;if(N)X$.debug("\uD83C\uDFC1 [ChatService] Stream finished with reason:",N),X$.debug("\uD83D\uDCCA [ChatService] Stream summary:",{totalChunks:U,totalContentLength:H.length,totalReasoningContentLength:F.length,hadToolCalls:O,duration:Date.now()-Q+"ms"});let D={content:B.content||void 0,reasoningContent:w,toolCalls:B.tool_calls,finishReason:N||void 0};if(_)D.usage={promptTokens:_.prompt_tokens||0,completionTokens:_.completion_tokens||0,totalTokens:_.total_tokens||0,reasoningTokens:_.reasoning_tokens};yield D}X$.debug("✅ [ChatService] Stream completed successfully")}catch(q){let W=Date.now()-Q;throw X$.error("❌ [ChatService] Stream request failed after",W,"ms"),X$.error("❌ [ChatService] Stream error details:",q),q}}getConfig(){return{...this.config}}updateConfig($){X$.debug("\uD83D\uDD04 [ChatService] Updating configuration"),X$.debug("\uD83D\uDD04 [ChatService] New config:",{model:$.model,baseUrl:$.baseUrl,temperature:$.temperature,maxContextTokens:$.maxContextTokens,timeout:$.timeout,hasApiKey:!!$.apiKey});let Z={...this.config};if(this.config={...this.config,...$},Z.baseUrl!==this.config.baseUrl)this.detectedReasoningFieldName=null,X$.debug("\uD83D\uDD04 [ChatService] Reset detectedReasoningFieldName due to baseUrl change");this.client=new QX({apiKey:this.config.apiKey,baseURL:this.config.baseUrl,timeout:this.config.timeout??180000,maxRetries:2}),X$.debug("✅ [ChatService] Configuration updated successfully"),X$.debug("\uD83D\uDCCA [ChatService] Config changes:",{modelChanged:Z.model!==this.config.model,baseUrlChanged:Z.baseUrl!==this.config.baseUrl,temperatureChanged:Z.temperature!==this.config.temperature,maxContextTokensChanged:Z.maxContextTokens!==this.config.maxContextTokens,timeoutChanged:Z.timeout!==this.config.timeout,apiKeyChanged:Z.apiKey!==this.config.apiKey})}}var X$,JX;var GX=A(()=>{O$();X$=l("Chat"),JX=["reasoning_content","reasoning","reasoningContent","thinking_content"]});async function s3($){let Z=$;if(w7($.apiKey)){KX.info("\uD83D\uDD11 检测到内置 API Key,正在获取...");let Y=await sQ($.apiKey);Z={...$,apiKey:Y}}return qO(Z)}function qO($){switch($.provider){case"openai-compatible":return new o3($);case"anthropic":return new A7($);case"gemini":return new T7($);case"azure-openai":return new j7($);case"antigravity":return new M7($);case"copilot":return new v7($);default:return KX.warn(`⚠️ 未知的 provider: ${$.provider}, 回退到 openai-compatible`),new o3($)}}var KX;var C7=A(()=>{u3();O$();pQ();iQ();nQ();tQ();eQ();YX();GX();KX=l("Service")});import{readFile as WO}from"node:fs/promises";import{basename as UO}from"node:path";class t3{static MAX_FILES=5;static MAX_LINES_PER_FILE=1000;static analyzeFiles($){let Z=new Map;return $.forEach((Q,X)=>{let J=typeof Q.content==="string"?Q.content:(Q.content||[]).filter((K)=>K.type==="text").map((K)=>K.text).join(`
192
192
  `);if(this.extractFilePathsFromContent(J).forEach((K)=>{this.updateFileReference(Z,K,X,!1)}),Q.tool_calls&&Array.isArray(Q.tool_calls))Q.tool_calls.forEach((K)=>{let q=this.extractFilePathsFromToolCall(K),W=K.type==="function"&&"function"in K?K.function?.name:"",U=["Write","Edit"].includes(W||"");q.forEach((H)=>{this.updateFileReference(Z,H,X,U)})})}),Array.from(Z.values()).sort((Q,X)=>{if(Q.wasModified!==X.wasModified)return Q.wasModified?-1:1;if(Q.mentions!==X.mentions)return X.mentions-Q.mentions;return X.lastMentioned-Q.lastMentioned}).slice(0,this.MAX_FILES)}static async readFilesContent($){let Z=[];for(let Y of $)try{let Q=await WO(Y,"utf-8"),X=Q.split(`
193
193
  `),J=X.length,G=Q,K=!1,q=J;if(J>this.MAX_LINES_PER_FILE)G=X.slice(0,this.MAX_LINES_PER_FILE).join(`
194
194
  `),G+=`
195
195
 
196
- ... (truncated ${J-this.MAX_LINES_PER_FILE} lines)`,K=!0,q=this.MAX_LINES_PER_FILE;Z.push({path:Y,content:G,truncated:K,lines:J,includedLines:q})}catch(Q){console.warn(`[FileAnalyzer] 无法读取文件: ${Y}`,Q)}return Z}static extractFilePathsFromContent($){let Z=new Set,Y=/```(?:\w+)?\s*\n?([\s\S]*?)```/g,Q=Array.from($.matchAll(Y));for(let J of Q){let G=J[1];this.extractPathsFromText(G).forEach((q)=>Z.add(q))}return this.extractPathsFromText($).forEach((J)=>Z.add(J)),Array.from(Z)}static extractPathsFromText($){let Z=[],Y=[/(?: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 Q of Y){let X=Array.from($.matchAll(Q));for(let J of X){let G=J[0];if(G=G.replace(/[,。;:!?""''()【】《》]$/g,""),G=G.replace(/[,.;:!?"'()[\]<>]$/g,""),this.isValidFilePath(G))Z.push(G)}}return Z}static extractFilePathsFromToolCall($){let Z=[];if($.type!=="function"||!$.function)return Z;try{let Y=$.function.name,Q=JSON.parse($.function.arguments||"{}");if(["Read","Write","Edit","Glob","Grep","NotebookEdit","mcp__github__get_file_contents","mcp__github__create_or_update_file"].includes(Y)){let J=["file_path","path","notebook_path","filePath"];for(let G of J)if(Q[G]&&typeof Q[G]==="string")Z.push(Q[G])}}catch{}return Z}static updateFileReference($,Z,Y,Q){let X=$.get(Z);if(X)X.mentions++,X.lastMentioned=Y,X.wasModified=X.wasModified||Q;else $.set(Z,{path:Z,mentions:1,lastMentioned:Y,wasModified:Q})}static isValidFilePath($){if(!$.includes("/"))return!1;let Z=UO($);if(!Z.includes("."))return!1;let Y=["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||!Y.includes(Q))return!1;return!0}}var qX=()=>{};import{encodingForModel as WX}from"js-tiktoken";var Z2;var e8=A(()=>{Z2=class Z2{static encodingCache=new Map;static countTokens($,Z){let Y=this.getEncoding(Z),Q=0;for(let X of $){if(Q+=4,X.role)Q+=Y.encode(X.role).length;if(X.content)if(typeof X.content==="string")Q+=Y.encode(X.content).length;else Q+=Y.encode(JSON.stringify(X.content)).length;if(X.tool_calls&&Array.isArray(X.tool_calls))Q+=this.countToolCallTokens(X.tool_calls,Y);if(X.name)Q+=Y.encode(X.name).length}return Q}static getTokenLimit($){return $}static shouldCompact($,Z,Y,Q=0.8){let X=this.countTokens($,Z),J=Math.floor(Y*Q);return X>=J}static getEncoding($){if(!this.encodingCache.has($))try{let Z=WX($);this.encodingCache.set($,Z)}catch{try{let Z=WX("gpt-4");this.encodingCache.set($,Z)}catch{console.warn(`[TokenCounter] 无法为模型 ${$} 获取 encoding,使用粗略估算`),this.encodingCache.set($,{encode:(Z)=>{return Array(Math.ceil(Z.length/4))}})}}return this.encodingCache.get($)}static countToolCallTokens($,Z){let Y=0;for(let Q of $){if(Y+=4,Q.type==="function"&&Q.function?.name)Y+=Z.encode(Q.function.name).length;if(Q.type==="function"&&Q.function?.arguments)Y+=Z.encode(Q.function.arguments).length;if(Q.id)Y+=Z.encode(Q.id).length}return Y}static clearCache(){this.encodingCache.clear()}static estimateTokens($){let Z=($.match(/[\u4e00-\u9fa5]/g)||[]).length,Y=$.length-Z;return Math.ceil(Z/1.5+Y/4)}}});import{nanoid as d4}from"nanoid";class u4{static THRESHOLD_PERCENT=0.8;static RETAIN_PERCENT=0.2;static FALLBACK_RETAIN_PERCENT=0.3;static async compact($,Z){let Y=Z.actualPreTokens??Z2.countTokens($,Z.modelName),Q=Z.actualPreTokens?"actual (from LLM usage)":"estimated";console.log(`[CompactionService] preTokens source: ${Q}`);try{let J=await M$.getInstance().executeCompactionHooks(Z.trigger,{projectDir:process.cwd(),sessionId:Z.sessionId||"unknown",permissionMode:Z.permissionMode||"default",messagesBefore:$.length,tokensBefore:Y});if(J.blockCompaction)return console.log(`[CompactionService] Compaction hook 阻止压缩: ${J.blockReason||"(无原因)"}`),{success:!1,summary:"",preTokens:Y,postTokens:Y,filesIncluded:[],compactedMessages:$,boundaryMessage:{role:"system",content:""},summaryMessage:{role:"user",content:""},error:J.blockReason||"Compaction blocked by hook"};if(J.warning)console.warn(`[CompactionService] Compaction hook warning: ${J.warning}`)}catch(X){console.warn("[CompactionService] Compaction hook execution failed:",X)}try{console.log("[CompactionService] 开始压缩,消息数:",$.length),console.log("[CompactionService] 压缩前 tokens:",Y);let J=t8.analyzeFiles($).map((w)=>w.path);console.log("[CompactionService] 提取重点文件:",J);let G=await t8.readFilesContent(J);console.log("[CompactionService] 成功读取文件:",G.length);let K=await this.generateSummary($,G,Z);console.log("[CompactionService] 生成总结,长度:",K.length);let q=Math.ceil($.length*this.RETAIN_PERCENT),W=$.slice(-q),U=new Set;for(let w of W)if(w.role==="assistant"&&w.tool_calls)for(let N of w.tool_calls)U.add(N.id);let H=W.filter((w)=>{if(w.role==="tool"&&w.tool_call_id)return U.has(w.tool_call_id);return!0});console.log("[CompactionService] 保留消息数:",q),console.log("[CompactionService] 过滤后保留消息数:",H.length);let F=d4(),O=this.createBoundaryMessage(F,Z.trigger,Y),z=d4(),_=this.createSummaryMessage(z,K),B=[_,...H],L=Z2.countTokens(B,Z.modelName);return console.log("[CompactionService] 压缩完成!"),console.log("[CompactionService] Token 变化:",Y,"→",L,`(-${((1-L/Y)*100).toFixed(1)}%)`),{success:!0,summary:K,preTokens:Y,postTokens:L,filesIncluded:J,compactedMessages:B,boundaryMessage:O,summaryMessage:_}}catch(X){return console.error("[CompactionService] 压缩失败,使用降级策略",X),this.fallbackCompact($,Z,Y,X)}}static async generateSummary($,Z,Y){let Q=this.buildCompactionPrompt($,Z);console.log("[CompactionService] 使用压缩模型:",Y.modelName);let G=(await(await s8({apiKey:Y.apiKey||process.env.BLADE_API_KEY||"",baseUrl:Y.baseURL||process.env.BLADE_BASE_URL||"https://api.openai.com/v1",model:Y.modelName,temperature:0.3,maxOutputTokens:8000,timeout:60000,provider:"openai-compatible"})).chat([{role:"user",content:Q}])).content||"",K=G.match(/<summary>([\s\S]*?)<\/summary>/);if(!K)return console.warn("[CompactionService] 总结格式不正确,使用完整响应"),G;return K[1].trim()}static buildCompactionPrompt($,Z){let Y=$.map((J,G)=>{let K=J.role||"unknown",q=typeof J.content==="string"?J.content:JSON.stringify(J.content),W=5000,U=q.length>5000?q.substring(0,5000)+"...":q;return`[${G+1}] ${K}: ${U}`}).join(`
196
+ ... (truncated ${J-this.MAX_LINES_PER_FILE} lines)`,K=!0,q=this.MAX_LINES_PER_FILE;Z.push({path:Y,content:G,truncated:K,lines:J,includedLines:q})}catch(Q){console.warn(`[FileAnalyzer] 无法读取文件: ${Y}`,Q)}return Z}static extractFilePathsFromContent($){let Z=new Set,Y=/```(?:\w+)?\s*\n?([\s\S]*?)```/g,Q=Array.from($.matchAll(Y));for(let J of Q){let G=J[1];this.extractPathsFromText(G).forEach((q)=>Z.add(q))}return this.extractPathsFromText($).forEach((J)=>Z.add(J)),Array.from(Z)}static extractPathsFromText($){let Z=[],Y=[/(?: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 Q of Y){let X=Array.from($.matchAll(Q));for(let J of X){let G=J[0];if(G=G.replace(/[,。;:!?""''()【】《》]$/g,""),G=G.replace(/[,.;:!?"'()[\]<>]$/g,""),this.isValidFilePath(G))Z.push(G)}}return Z}static extractFilePathsFromToolCall($){let Z=[];if($.type!=="function"||!$.function)return Z;try{let Y=$.function.name,Q=JSON.parse($.function.arguments||"{}");if(["Read","Write","Edit","Glob","Grep","NotebookEdit","mcp__github__get_file_contents","mcp__github__create_or_update_file"].includes(Y)){let J=["file_path","path","notebook_path","filePath"];for(let G of J)if(Q[G]&&typeof Q[G]==="string")Z.push(Q[G])}}catch{}return Z}static updateFileReference($,Z,Y,Q){let X=$.get(Z);if(X)X.mentions++,X.lastMentioned=Y,X.wasModified=X.wasModified||Q;else $.set(Z,{path:Z,mentions:1,lastMentioned:Y,wasModified:Q})}static isValidFilePath($){if(!$.includes("/"))return!1;let Z=UO($);if(!Z.includes("."))return!1;let Y=["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||!Y.includes(Q))return!1;return!0}}var qX=()=>{};import{encodingForModel as WX}from"js-tiktoken";var Z4;var e3=A(()=>{Z4=class Z4{static encodingCache=new Map;static countTokens($,Z){let Y=this.getEncoding(Z),Q=0;for(let X of $){if(Q+=4,X.role)Q+=Y.encode(X.role).length;if(X.content)if(typeof X.content==="string")Q+=Y.encode(X.content).length;else Q+=Y.encode(JSON.stringify(X.content)).length;if(X.tool_calls&&Array.isArray(X.tool_calls))Q+=this.countToolCallTokens(X.tool_calls,Y);if(X.name)Q+=Y.encode(X.name).length}return Q}static getTokenLimit($){return $}static shouldCompact($,Z,Y,Q=0.8){let X=this.countTokens($,Z),J=Math.floor(Y*Q);return X>=J}static getEncoding($){if(!this.encodingCache.has($))try{let Z=WX($);this.encodingCache.set($,Z)}catch{try{let Z=WX("gpt-4");this.encodingCache.set($,Z)}catch{console.warn(`[TokenCounter] 无法为模型 ${$} 获取 encoding,使用粗略估算`),this.encodingCache.set($,{encode:(Z)=>{return Array(Math.ceil(Z.length/4))}})}}return this.encodingCache.get($)}static countToolCallTokens($,Z){let Y=0;for(let Q of $){if(Y+=4,Q.type==="function"&&Q.function?.name)Y+=Z.encode(Q.function.name).length;if(Q.type==="function"&&Q.function?.arguments)Y+=Z.encode(Q.function.arguments).length;if(Q.id)Y+=Z.encode(Q.id).length}return Y}static clearCache(){this.encodingCache.clear()}static estimateTokens($){let Z=($.match(/[\u4e00-\u9fa5]/g)||[]).length,Y=$.length-Z;return Math.ceil(Z/1.5+Y/4)}}});import{nanoid as d2}from"nanoid";class u2{static THRESHOLD_PERCENT=0.8;static RETAIN_PERCENT=0.2;static FALLBACK_RETAIN_PERCENT=0.3;static async compact($,Z){let Y=Z.actualPreTokens??Z4.countTokens($,Z.modelName),Q=Z.actualPreTokens?"actual (from LLM usage)":"estimated";console.log(`[CompactionService] preTokens source: ${Q}`);try{let J=await M$.getInstance().executeCompactionHooks(Z.trigger,{projectDir:process.cwd(),sessionId:Z.sessionId||"unknown",permissionMode:Z.permissionMode||"default",messagesBefore:$.length,tokensBefore:Y});if(J.blockCompaction)return console.log(`[CompactionService] Compaction hook 阻止压缩: ${J.blockReason||"(无原因)"}`),{success:!1,summary:"",preTokens:Y,postTokens:Y,filesIncluded:[],compactedMessages:$,boundaryMessage:{role:"system",content:""},summaryMessage:{role:"user",content:""},error:J.blockReason||"Compaction blocked by hook"};if(J.warning)console.warn(`[CompactionService] Compaction hook warning: ${J.warning}`)}catch(X){console.warn("[CompactionService] Compaction hook execution failed:",X)}try{console.log("[CompactionService] 开始压缩,消息数:",$.length),console.log("[CompactionService] 压缩前 tokens:",Y);let J=t3.analyzeFiles($).map((w)=>w.path);console.log("[CompactionService] 提取重点文件:",J);let G=await t3.readFilesContent(J);console.log("[CompactionService] 成功读取文件:",G.length);let K=await this.generateSummary($,G,Z);console.log("[CompactionService] 生成总结,长度:",K.length);let q=Math.ceil($.length*this.RETAIN_PERCENT),W=$.slice(-q),U=new Set;for(let w of W)if(w.role==="assistant"&&w.tool_calls)for(let N of w.tool_calls)U.add(N.id);let H=W.filter((w)=>{if(w.role==="tool"&&w.tool_call_id)return U.has(w.tool_call_id);return!0});console.log("[CompactionService] 保留消息数:",q),console.log("[CompactionService] 过滤后保留消息数:",H.length);let F=d2(),O=this.createBoundaryMessage(F,Z.trigger,Y),z=d2(),_=this.createSummaryMessage(z,K),B=[_,...H],L=Z4.countTokens(B,Z.modelName);return console.log("[CompactionService] 压缩完成!"),console.log("[CompactionService] Token 变化:",Y,"→",L,`(-${((1-L/Y)*100).toFixed(1)}%)`),{success:!0,summary:K,preTokens:Y,postTokens:L,filesIncluded:J,compactedMessages:B,boundaryMessage:O,summaryMessage:_}}catch(X){return console.error("[CompactionService] 压缩失败,使用降级策略",X),this.fallbackCompact($,Z,Y,X)}}static async generateSummary($,Z,Y){let Q=this.buildCompactionPrompt($,Z);console.log("[CompactionService] 使用压缩模型:",Y.modelName);let G=(await(await s3({apiKey:Y.apiKey||process.env.BLADE_API_KEY||"",baseUrl:Y.baseURL||process.env.BLADE_BASE_URL||"https://api.openai.com/v1",model:Y.modelName,temperature:0.3,maxOutputTokens:8000,timeout:60000,provider:"openai-compatible"})).chat([{role:"user",content:Q}])).content||"",K=G.match(/<summary>([\s\S]*?)<\/summary>/);if(!K)return console.warn("[CompactionService] 总结格式不正确,使用完整响应"),G;return K[1].trim()}static buildCompactionPrompt($,Z){let Y=$.map((J,G)=>{let K=J.role||"unknown",q=typeof J.content==="string"?J.content:JSON.stringify(J.content),W=5000,U=q.length>5000?q.substring(0,5000)+"...":q;return`[${G+1}] ${K}: ${U}`}).join(`
197
197
 
198
198
  `),Q=Z.map((J)=>{return`### ${J.path}
199
199
  \`\`\`
@@ -266,14 +266,14 @@ ${Z.length>0?`## Important Files
266
266
 
267
267
  ${Q}`:""}
268
268
 
269
- Please provide your summary following the structure specified above, with both <analysis> and <summary> sections.`}static createBoundaryMessage($,Z,Y){return{id:d4(),role:"system",content:"Conversation compacted",metadata:{type:"system",subtype:"compact_boundary",parentId:$,compactMetadata:{trigger:Z,preTokens:Y}}}}static createSummaryMessage($,Z){return{id:d4(),role:"user",content:Z,metadata:{parentId:$,isCompactSummary:!0}}}static fallbackCompact($,Z,Y,Q){let X=Math.ceil($.length*this.FALLBACK_RETAIN_PERCENT),J=$.slice(-X),G=new Set;for(let _ of J)if(_.role==="assistant"&&_.tool_calls)for(let B of _.tool_calls)G.add(B.id);let K=J.filter((_)=>{if(_.role==="tool"&&_.tool_call_id)return G.has(_.tool_call_id);return!0}),q=d4(),W=this.createBoundaryMessage(q,Z.trigger,Y),U=Q instanceof Error?Q.message:String(Q),H=d4(),F=this.createSummaryMessage(H,`[Automatic compaction failed; using fallback]
269
+ Please provide your summary following the structure specified above, with both <analysis> and <summary> sections.`}static createBoundaryMessage($,Z,Y){return{id:d2(),role:"system",content:"Conversation compacted",metadata:{type:"system",subtype:"compact_boundary",parentId:$,compactMetadata:{trigger:Z,preTokens:Y}}}}static createSummaryMessage($,Z){return{id:d2(),role:"user",content:Z,metadata:{parentId:$,isCompactSummary:!0}}}static fallbackCompact($,Z,Y,Q){let X=Math.ceil($.length*this.FALLBACK_RETAIN_PERCENT),J=$.slice(-X),G=new Set;for(let _ of J)if(_.role==="assistant"&&_.tool_calls)for(let B of _.tool_calls)G.add(B.id);let K=J.filter((_)=>{if(_.role==="tool"&&_.tool_call_id)return G.has(_.tool_call_id);return!0}),q=d2(),W=this.createBoundaryMessage(q,Z.trigger,Y),U=Q instanceof Error?Q.message:String(Q),H=d2(),F=this.createSummaryMessage(H,`[Automatic compaction failed; using fallback]
270
270
 
271
271
  An error occurred during compaction. Retained the latest ${X} messages (~30%).
272
272
 
273
273
  Error: ${U}
274
274
 
275
- The conversation can continue, but consider retrying compaction later with /compact.`),O=[F,...K],z=Z2.countTokens(O,Z.modelName);return{success:!1,summary:typeof F.content==="string"?F.content:F.content.filter((_)=>_.type==="text").map((_)=>_.text).join(`
276
- `),preTokens:Y,postTokens:z,filesIncluded:[],compactedMessages:O,boundaryMessage:W,summaryMessage:F,error:U}}}var S7=A(()=>{U0();t0();C7();qX();e8()});import{appendFileSync as HO,mkdirSync as FO,writeFileSync as OO}from"node:fs";import zO from"node:os";import HX from"node:path";function _O(){if(UX)return;let $=HX.dirname(k7);FO($,{recursive:!0,mode:493}),OO(k7,`=== Stream Debug Log Started: ${new Date().toISOString()} ===
275
+ The conversation can continue, but consider retrying compaction later with /compact.`),O=[F,...K],z=Z4.countTokens(O,Z.modelName);return{success:!1,summary:typeof F.content==="string"?F.content:F.content.filter((_)=>_.type==="text").map((_)=>_.text).join(`
276
+ `),preTokens:Y,postTokens:z,filesIncluded:[],compactedMessages:O,boundaryMessage:W,summaryMessage:F,error:U}}}var S7=A(()=>{U0();t0();C7();qX();e3()});import{appendFileSync as HO,mkdirSync as FO,writeFileSync as OO}from"node:fs";import zO from"node:os";import HX from"node:path";function _O(){if(UX)return;let $=HX.dirname(k7);FO($,{recursive:!0,mode:493}),OO(k7,`=== Stream Debug Log Started: ${new Date().toISOString()} ===
277
277
  `),UX=!0}function F1($,Z,Y){_O();let Q=new Date().toISOString(),X=Y?` | ${JSON.stringify(Y)}`:"",J=`[${Q}] [${$}] ${Z}${X}
278
278
  `;HO(k7,J)}var k7,UX=!1;var f7=A(()=>{k7=HX.join(zO.homedir(),".blade","logs","stream-debug.log")});import BO from"fs/promises";import LO from"path";async function OX($){for(let Z of $)try{let Y;if(Z.trim().startsWith("{")){let J=JSON.parse(Z);if(J.name&&J.type){let{name:G,...K}=J;Y={[G]:K}}else Y=J}else{let J=LO.resolve(process.cwd(),Z),G=await BO.readFile(J,"utf-8"),K=JSON.parse(G);Y=K.mcpServers||K}let X={...W1(),...Y};q$().config.actions.updateConfig({mcpServers:X}),FX.debug(`✅ Loaded MCP config from CLI: ${Object.keys(Y).join(", ")}`)}catch(Y){FX.warn(`⚠️ Failed to load MCP config "${Z}":`,Y)}}var FX;var zX=A(()=>{O$();k$();FX=l("General")});function _X(){return{metadata:$9,instructions:`# Skill Creator
279
279
 
@@ -458,10 +458,10 @@ user-invocable: true
458
458
  <footer>
459
459
  \`\`\`
460
460
  \`\`\`
461
- `}}var $9;var BX=A(()=>{$9={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 wO}from"node:child_process";import*as F0 from"node:fs/promises";import{homedir as NO}from"node:os";import*as y1 from"node:path";import{promisify as bO}from"node:util";class LX{skillsDir;constructor($){this.skillsDir=$||y1.join(NO(),".blade","skills")}async isInstalled($){let Z=y1.join(this.skillsDir,$,"SKILL.md");try{return await F0.access(Z),!0}catch{return!1}}async isGitAvailable(){try{return await h7("git --version"),!0}catch{return!1}}async installOfficialSkill($){let{url:Z,branch:Y}=x7,Q=y1.join(this.skillsDir,$),X=y1.join(this.skillsDir,`.tmp-${$}-${Date.now()}`);try{if(!await this.isGitAvailable())return p1.warn("Git not available, skipping skill installation"),!1;p1.info(`Installing official skill: ${$}...`),await F0.mkdir(this.skillsDir,{recursive:!0,mode:493}),await h7(`git clone --depth 1 --branch ${Y} --single-branch ${Z} "${X}"`,{timeout:30000});let J=y1.join(X,"skills",$);try{await F0.access(J)}catch{return p1.warn(`Skill ${$} not found in official repository`),await F0.rm(X,{recursive:!0,force:!0}),!1}try{await F0.rm(Q,{recursive:!0,force:!0})}catch{}return await F0.cp(J,Q,{recursive:!0}),await F0.rm(X,{recursive:!0,force:!0}),p1.info(`Successfully installed: ${$}`),!0}catch(J){try{await F0.rm(X,{recursive:!0,force:!0})}catch{}return p1.warn(`Failed to install ${$}: ${J instanceof Error?J.message:"Unknown error"}`),!1}}async ensureDefaultSkillsInstalled(){await F0.mkdir(this.skillsDir,{recursive:!0,mode:493});for(let $ of x7.defaultSkills)if(!await this.isInstalled($))await this.installOfficialSkill($)}async installAllOfficialSkills(){let{url:$,branch:Z}=x7,Y=y1.join(this.skillsDir,`.tmp-all-${Date.now()}`),Q=[],X=[];try{if(!await this.isGitAvailable())return p1.warn("Git not available, skipping skill installation"),{installed:Q,failed:X};await F0.mkdir(this.skillsDir,{recursive:!0,mode:493}),p1.info("Cloning official skills repository..."),await h7(`git clone --depth 1 --branch ${Z} --single-branch ${$} "${Y}"`,{timeout:60000});let J=y1.join(Y,"skills"),G=await F0.readdir(J,{withFileTypes:!0});for(let K of G){if(!K.isDirectory())continue;let q=K.name,W=y1.join(J,q),U=y1.join(this.skillsDir,q);try{await F0.access(y1.join(W,"SKILL.md")),await F0.rm(U,{recursive:!0,force:!0}),await F0.cp(W,U,{recursive:!0}),p1.info(`Installed: ${q}`),Q.push(q)}catch(H){p1.warn(`Failed to install ${q}`),X.push(q)}}await F0.rm(Y,{recursive:!0,force:!0})}catch(J){try{await F0.rm(Y,{recursive:!0,force:!0})}catch{}p1.warn(`Failed to install skills: ${J instanceof Error?J.message:"Unknown error"}`)}return{installed:Q,failed:X}}}function wX($){if(!p7)p7=new LX($);return p7}var h7,p1,x7,p7=null;var NX=A(()=>{O$();h7=bO(wO),p1=l("General"),x7={url:"https://github.com/anthropics/skills.git",branch:"main",defaultSkills:["skill-creator"]}});import*as e3 from"node:fs/promises";import*as Z9 from"node:path";import{parse as AO}from"yaml";function DO($){if(!$)return;if(typeof $==="string")return $.split(",").map((Z)=>Z.trim()).filter(Boolean);if(Array.isArray($))return $.map((Z)=>String(Z).trim()).filter(Boolean);return}function AX($){if($===void 0)return;if(typeof $==="boolean")return $;if(typeof $==="string"){let Z=$.toLowerCase().trim();if(Z==="true"||Z==="yes"||Z==="1")return!0;if(Z==="false"||Z==="no"||Z==="0")return!1}return}function MO($,Z){if(!$.name)return{valid:!1,error:"Missing required field: name"};if(!VO.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>bX)return{valid:!1,error:`Description too long: ${$.description.length} characters (max ${bX})`};let Y;if($.model)Y=$.model==="inherit"?"inherit":$.model;return{valid:!0,metadata:{name:$.name,description:$.description.trim(),allowedTools:DO($["allowed-tools"]),version:$.version,argumentHint:$["argument-hint"]?.trim(),userInvocable:AX($["user-invocable"]),disableModelInvocation:AX($["disable-model-invocation"]),model:Y,whenToUse:$.when_to_use?.trim()}}}function RX($,Z,Y){let Q=$.match(RO);if(!Q)return{success:!1,error:"Invalid SKILL.md format: missing YAML frontmatter (must start with ---)"};let[,X,J]=Q,G;try{G=AO(X)}catch(W){return{success:!1,error:`Failed to parse YAML frontmatter: ${W instanceof Error?W.message:String(W)}`}}let K=MO(G,Z);if(!K.valid)return{success:!1,error:K.error};let q=Z9.dirname(Z);return{success:!0,content:{metadata:{...K.metadata,path:Z,basePath:q,source:Y},instructions:J.trim()}}}async function Y9($,Z){try{let Y=await e3.readFile($,"utf-8");return RX(Y,$,Z)}catch(Y){if(Y.code==="ENOENT")return{success:!1,error:`File not found: ${$}`};return{success:!1,error:`Failed to read file: ${Y instanceof Error?Y.message:String(Y)}`}}}async function VX($){try{let Z=await e3.readFile($.path,"utf-8"),Y=RX(Z,$.path,$.source);return Y.success?Y.content:null}catch{return null}}async function DX($){try{return await e3.access(Z9.join($,"SKILL.md")),!0}catch{return!1}}var RO,VO,bX=1024;var m7=A(()=>{RO=/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/,VO=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]?$/});import*as X9 from"node:fs/promises";import{homedir as MX}from"node:os";import*as m1 from"node:path";class d7{skills=new Map;pluginSkills=new Map;config;initialized=!1;constructor($){this.config={...jO,...$}}static getInstance($){if(!Q9)Q9=new d7($);return Q9}static resetInstance(){Q9=null}async initialize(){if(this.initialized)return{skills:Array.from(this.skills.values()),errors:[]};let $=[],Z=[];try{await wX(this.config.userSkillsDir).ensureDefaultSkillsInstalled()}catch(q){$.push({path:"SkillInstaller",error:`Failed to install default skills: ${q instanceof Error?q.message:"Unknown error"}`})}this.loadBuiltinSkills();let Y=await this.scanDirectory(this.config.claudeUserSkillsDir,"user");Z.push(...Y.skills),$.push(...Y.errors);let Q=await this.scanDirectory(this.config.userSkillsDir,"user");Z.push(...Q.skills),$.push(...Q.errors);let X=m1.isAbsolute(this.config.claudeProjectSkillsDir)?this.config.claudeProjectSkillsDir:m1.join(this.config.cwd,this.config.claudeProjectSkillsDir),J=await this.scanDirectory(X,"project");Z.push(...J.skills),$.push(...J.errors);let G=m1.isAbsolute(this.config.projectSkillsDir)?this.config.projectSkillsDir:m1.join(this.config.cwd,this.config.projectSkillsDir),K=await this.scanDirectory(G,"project");Z.push(...K.skills),$.push(...K.errors);for(let q of Z)this.skills.set(q.name,q);return this.initialized=!0,{skills:Array.from(this.skills.values()),errors:$}}loadBuiltinSkills(){this.skills.set($9.name,$9)}async scanDirectory($,Z){let Y=[],Q=[];try{await X9.access($)}catch{return{skills:Y,errors:Q}}try{let X=await X9.readdir($,{withFileTypes:!0});for(let J of X){if(!J.isDirectory())continue;let G=m1.join($,J.name),K=m1.join(G,"SKILL.md");if(!await DX(G))continue;let q=await Y9(K,Z);if(q.success&&q.content)Y.push(q.content.metadata);else Q.push({path:K,error:q.error||"Unknown error"})}}catch(X){Q.push({path:$,error:`Failed to scan directory: ${X instanceof Error?X.message:String(X)}`})}return{skills:Y,errors:Q}}getAll(){return Array.from(this.skills.values())}get($){return this.skills.get($)}has($){return this.skills.has($)}async loadContent($){let Z=this.skills.get($);if(!Z)return null;if(Z.source==="builtin")return this.loadBuiltinContent($);return VX(Z)}loadBuiltinContent($){switch($){case"skill-creator":return _X();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 Z=[];for(let Y of $){let Q=Y.description.length>100?`${Y.description.substring(0,97)}...`:Y.description,X=Y.argumentHint?`${Y.name} ${Y.argumentHint}`:Y.name;Z.push(`- ${X}: ${Q}`)}return Z.join(`
462
- `)}get size(){return this.skills.size}async refresh(){return this.skills.clear(),this.pluginSkills.clear(),this.initialized=!1,this.initialize()}registerPluginSkill($){this.pluginSkills.set($.namespacedName,$),this.skills.set($.namespacedName,$.metadata)}findPluginSkill($){let Z=this.pluginSkills.get($);if(Z)return Z;let Y=[];for(let Q of this.pluginSkills.values())if(Q.originalName===$)Y.push(Q);if(Y.length===1)return Y[0];return}getAllPluginSkills(){return Array.from(this.pluginSkills.values())}clearPluginSkills(){for(let $ of this.pluginSkills.values())this.skills.delete($.namespacedName);this.pluginSkills.clear()}getPluginSkillCount(){return this.pluginSkills.size}}function R0($){return d7.getInstance($)}async function Y4($){return R0($).initialize()}var jO,Q9=null;var u7=A(()=>{BX();NX();m7();jO={userSkillsDir:m1.join(MX(),".blade","skills"),projectSkillsDir:".blade/skills",claudeUserSkillsDir:m1.join(MX(),".claude","skills"),claudeProjectSkillsDir:".claude/skills",cwd:process.cwd()}});function g7($){let Y=R0().generateAvailableSkillsList();if(!Y)return $;return $.map((Q)=>{if(Q.name!==IO)return Q;let X=Q.description.replace(yO,`<available_skills>
461
+ `}}var $9;var BX=A(()=>{$9={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 wO}from"node:child_process";import*as F0 from"node:fs/promises";import{homedir as NO}from"node:os";import*as y1 from"node:path";import{promisify as bO}from"node:util";class LX{skillsDir;constructor($){this.skillsDir=$||y1.join(NO(),".blade","skills")}async isInstalled($){let Z=y1.join(this.skillsDir,$,"SKILL.md");try{return await F0.access(Z),!0}catch{return!1}}async isGitAvailable(){try{return await h7("git --version"),!0}catch{return!1}}async installOfficialSkill($){let{url:Z,branch:Y}=x7,Q=y1.join(this.skillsDir,$),X=y1.join(this.skillsDir,`.tmp-${$}-${Date.now()}`);try{if(!await this.isGitAvailable())return p1.warn("Git not available, skipping skill installation"),!1;p1.info(`Installing official skill: ${$}...`),await F0.mkdir(this.skillsDir,{recursive:!0,mode:493}),await h7(`git clone --depth 1 --branch ${Y} --single-branch ${Z} "${X}"`,{timeout:30000});let J=y1.join(X,"skills",$);try{await F0.access(J)}catch{return p1.warn(`Skill ${$} not found in official repository`),await F0.rm(X,{recursive:!0,force:!0}),!1}try{await F0.rm(Q,{recursive:!0,force:!0})}catch{}return await F0.cp(J,Q,{recursive:!0}),await F0.rm(X,{recursive:!0,force:!0}),p1.info(`Successfully installed: ${$}`),!0}catch(J){try{await F0.rm(X,{recursive:!0,force:!0})}catch{}return p1.warn(`Failed to install ${$}: ${J instanceof Error?J.message:"Unknown error"}`),!1}}async ensureDefaultSkillsInstalled(){await F0.mkdir(this.skillsDir,{recursive:!0,mode:493});for(let $ of x7.defaultSkills)if(!await this.isInstalled($))await this.installOfficialSkill($)}async installAllOfficialSkills(){let{url:$,branch:Z}=x7,Y=y1.join(this.skillsDir,`.tmp-all-${Date.now()}`),Q=[],X=[];try{if(!await this.isGitAvailable())return p1.warn("Git not available, skipping skill installation"),{installed:Q,failed:X};await F0.mkdir(this.skillsDir,{recursive:!0,mode:493}),p1.info("Cloning official skills repository..."),await h7(`git clone --depth 1 --branch ${Z} --single-branch ${$} "${Y}"`,{timeout:60000});let J=y1.join(Y,"skills"),G=await F0.readdir(J,{withFileTypes:!0});for(let K of G){if(!K.isDirectory())continue;let q=K.name,W=y1.join(J,q),U=y1.join(this.skillsDir,q);try{await F0.access(y1.join(W,"SKILL.md")),await F0.rm(U,{recursive:!0,force:!0}),await F0.cp(W,U,{recursive:!0}),p1.info(`Installed: ${q}`),Q.push(q)}catch(H){p1.warn(`Failed to install ${q}`),X.push(q)}}await F0.rm(Y,{recursive:!0,force:!0})}catch(J){try{await F0.rm(Y,{recursive:!0,force:!0})}catch{}p1.warn(`Failed to install skills: ${J instanceof Error?J.message:"Unknown error"}`)}return{installed:Q,failed:X}}}function wX($){if(!p7)p7=new LX($);return p7}var h7,p1,x7,p7=null;var NX=A(()=>{O$();h7=bO(wO),p1=l("General"),x7={url:"https://github.com/anthropics/skills.git",branch:"main",defaultSkills:["skill-creator"]}});import*as e8 from"node:fs/promises";import*as Z9 from"node:path";import{parse as AO}from"yaml";function DO($){if(!$)return;if(typeof $==="string")return $.split(",").map((Z)=>Z.trim()).filter(Boolean);if(Array.isArray($))return $.map((Z)=>String(Z).trim()).filter(Boolean);return}function AX($){if($===void 0)return;if(typeof $==="boolean")return $;if(typeof $==="string"){let Z=$.toLowerCase().trim();if(Z==="true"||Z==="yes"||Z==="1")return!0;if(Z==="false"||Z==="no"||Z==="0")return!1}return}function MO($,Z){if(!$.name)return{valid:!1,error:"Missing required field: name"};if(!VO.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>bX)return{valid:!1,error:`Description too long: ${$.description.length} characters (max ${bX})`};let Y;if($.model)Y=$.model==="inherit"?"inherit":$.model;return{valid:!0,metadata:{name:$.name,description:$.description.trim(),allowedTools:DO($["allowed-tools"]),version:$.version,argumentHint:$["argument-hint"]?.trim(),userInvocable:AX($["user-invocable"]),disableModelInvocation:AX($["disable-model-invocation"]),model:Y,whenToUse:$.when_to_use?.trim()}}}function RX($,Z,Y){let Q=$.match(RO);if(!Q)return{success:!1,error:"Invalid SKILL.md format: missing YAML frontmatter (must start with ---)"};let[,X,J]=Q,G;try{G=AO(X)}catch(W){return{success:!1,error:`Failed to parse YAML frontmatter: ${W instanceof Error?W.message:String(W)}`}}let K=MO(G,Z);if(!K.valid)return{success:!1,error:K.error};let q=Z9.dirname(Z);return{success:!0,content:{metadata:{...K.metadata,path:Z,basePath:q,source:Y},instructions:J.trim()}}}async function Y9($,Z){try{let Y=await e8.readFile($,"utf-8");return RX(Y,$,Z)}catch(Y){if(Y.code==="ENOENT")return{success:!1,error:`File not found: ${$}`};return{success:!1,error:`Failed to read file: ${Y instanceof Error?Y.message:String(Y)}`}}}async function VX($){try{let Z=await e8.readFile($.path,"utf-8"),Y=RX(Z,$.path,$.source);return Y.success?Y.content:null}catch{return null}}async function DX($){try{return await e8.access(Z9.join($,"SKILL.md")),!0}catch{return!1}}var RO,VO,bX=1024;var m7=A(()=>{RO=/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/,VO=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]?$/});import*as X9 from"node:fs/promises";import{homedir as MX}from"node:os";import*as m1 from"node:path";class d7{skills=new Map;pluginSkills=new Map;config;initialized=!1;constructor($){this.config={...jO,...$}}static getInstance($){if(!Q9)Q9=new d7($);return Q9}static resetInstance(){Q9=null}async initialize(){if(this.initialized)return{skills:Array.from(this.skills.values()),errors:[]};let $=[],Z=[];try{await wX(this.config.userSkillsDir).ensureDefaultSkillsInstalled()}catch(q){$.push({path:"SkillInstaller",error:`Failed to install default skills: ${q instanceof Error?q.message:"Unknown error"}`})}this.loadBuiltinSkills();let Y=await this.scanDirectory(this.config.claudeUserSkillsDir,"user");Z.push(...Y.skills),$.push(...Y.errors);let Q=await this.scanDirectory(this.config.userSkillsDir,"user");Z.push(...Q.skills),$.push(...Q.errors);let X=m1.isAbsolute(this.config.claudeProjectSkillsDir)?this.config.claudeProjectSkillsDir:m1.join(this.config.cwd,this.config.claudeProjectSkillsDir),J=await this.scanDirectory(X,"project");Z.push(...J.skills),$.push(...J.errors);let G=m1.isAbsolute(this.config.projectSkillsDir)?this.config.projectSkillsDir:m1.join(this.config.cwd,this.config.projectSkillsDir),K=await this.scanDirectory(G,"project");Z.push(...K.skills),$.push(...K.errors);for(let q of Z)this.skills.set(q.name,q);return this.initialized=!0,{skills:Array.from(this.skills.values()),errors:$}}loadBuiltinSkills(){this.skills.set($9.name,$9)}async scanDirectory($,Z){let Y=[],Q=[];try{await X9.access($)}catch{return{skills:Y,errors:Q}}try{let X=await X9.readdir($,{withFileTypes:!0});for(let J of X){if(!J.isDirectory())continue;let G=m1.join($,J.name),K=m1.join(G,"SKILL.md");if(!await DX(G))continue;let q=await Y9(K,Z);if(q.success&&q.content)Y.push(q.content.metadata);else Q.push({path:K,error:q.error||"Unknown error"})}}catch(X){Q.push({path:$,error:`Failed to scan directory: ${X instanceof Error?X.message:String(X)}`})}return{skills:Y,errors:Q}}getAll(){return Array.from(this.skills.values())}get($){return this.skills.get($)}has($){return this.skills.has($)}async loadContent($){let Z=this.skills.get($);if(!Z)return null;if(Z.source==="builtin")return this.loadBuiltinContent($);return VX(Z)}loadBuiltinContent($){switch($){case"skill-creator":return _X();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 Z=[];for(let Y of $){let Q=Y.description.length>100?`${Y.description.substring(0,97)}...`:Y.description,X=Y.argumentHint?`${Y.name} ${Y.argumentHint}`:Y.name;Z.push(`- ${X}: ${Q}`)}return Z.join(`
462
+ `)}get size(){return this.skills.size}async refresh(){return this.skills.clear(),this.pluginSkills.clear(),this.initialized=!1,this.initialize()}registerPluginSkill($){this.pluginSkills.set($.namespacedName,$),this.skills.set($.namespacedName,$.metadata)}findPluginSkill($){let Z=this.pluginSkills.get($);if(Z)return Z;let Y=[];for(let Q of this.pluginSkills.values())if(Q.originalName===$)Y.push(Q);if(Y.length===1)return Y[0];return}getAllPluginSkills(){return Array.from(this.pluginSkills.values())}clearPluginSkills(){for(let $ of this.pluginSkills.values())this.skills.delete($.namespacedName);this.pluginSkills.clear()}getPluginSkillCount(){return this.pluginSkills.size}}function R0($){return d7.getInstance($)}async function Y2($){return R0($).initialize()}var jO,Q9=null;var u7=A(()=>{BX();NX();m7();jO={userSkillsDir:m1.join(MX(),".blade","skills"),projectSkillsDir:".blade/skills",claudeUserSkillsDir:m1.join(MX(),".claude","skills"),claudeProjectSkillsDir:".claude/skills",cwd:process.cwd()}});function g7($){let Y=R0().generateAvailableSkillsList();if(!Y)return $;return $.map((Q)=>{if(Q.name!==IO)return Q;let X=Q.description.replace(yO,`<available_skills>
463
463
  ${Y}
464
- </available_skills>`);if(X===Q.description)return Q;return{...Q,description:X}})}var IO="Skill",yO;var jX=A(()=>{u7();yO=/<available_skills>\s*<\/available_skills>/});var Y2=A(()=>{jX();u7()});import{execSync as vO}from"child_process";import*as c4 from"os";import*as g4 from"path";function EO(){let $=process.cwd(),Z=PO($);return{workingDirectory:$,projectRoot:Z,platform:`${c4.platform()} (${c4.arch()})`,nodeVersion:process.version,currentDate:new Date().toISOString().split("T")[0],homeDirectory:c4.homedir()}}function J9(){let $=EO();return`# Environment Context
464
+ </available_skills>`);if(X===Q.description)return Q;return{...Q,description:X}})}var IO="Skill",yO;var jX=A(()=>{u7();yO=/<available_skills>\s*<\/available_skills>/});var Y4=A(()=>{jX();u7()});import{execSync as vO}from"child_process";import*as c2 from"os";import*as g2 from"path";function EO(){let $=process.cwd(),Z=PO($);return{workingDirectory:$,projectRoot:Z,platform:`${c2.platform()} (${c2.arch()})`,nodeVersion:process.version,currentDate:new Date().toISOString().split("T")[0],homeDirectory:c2.homedir()}}function J9(){let $=EO();return`# Environment Context
465
465
 
466
466
  ## Working Directory
467
467
  **Current**: \`${$.workingDirectory}\`
@@ -479,7 +479,7 @@ When using file tools (read, write, edit), provide **absolute paths**:
479
479
  - ❌ Incorrect: \`/package.json\` (root directory)
480
480
  - ❌ Incorrect: \`package.json\` (relative path without context)
481
481
 
482
- **Always use** \`${$.workingDirectory}/\` as the base for file paths.`}function PO($){let Z=$;while(Z!==g4.dirname(Z)){if(IX(g4.join(Z,".git")))return Z;if(IX(g4.join(Z,"package.json")))return Z;Z=g4.dirname(Z)}return $}function IX($){try{return vO(`test -e "${$}"`,{stdio:"ignore"}),!0}catch{return!1}}var c7=()=>{};function $8($){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>
482
+ **Always use** \`${$.workingDirectory}/\` as the base for file paths.`}function PO($){let Z=$;while(Z!==g2.dirname(Z)){if(IX(g2.join(Z,".git")))return Z;if(IX(g2.join(Z,"package.json")))return Z;Z=g2.dirname(Z)}return $}function IX($){try{return vO(`test -e "${$}"`,{stdio:"ignore"}),!0}catch{return!1}}var c7=()=>{};function $3($){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>
483
483
 
484
484
  `+$}var yX=`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.
485
485
 
@@ -866,7 +866,7 @@ Show current progress and suggest next steps based on actual project state.
866
866
 
867
867
  `);return z=fO(z),{prompt:z,sources:W}}function fO($){let Y=R0().generateAvailableSkillsList();if(!Y)return $;return $.replace(kO,`<available_skills>
868
868
  ${Y}
869
- </available_skills>`)}async function hO($){let Z=SO.join($,"BLADE.md");try{return(await EX.readFile(Z,"utf-8")).trim()||null}catch{return null}}var kO;var PX=A(()=>{U0();Y2();c7();l7();kO=/<available_skills>\s*<\/available_skills>/});var TX=A(()=>{PX()});function CX($){return $.endsWith("/")||$.endsWith("\\")}function Z8($){return $.replace(/\\/g,"/").split("/").filter(Boolean)}import*as W9 from"fs/promises";import*as c0 from"path";class U9{static normalize($,Z){let Y=c0.isAbsolute($)?$:c0.resolve(Z,$),Q=c0.normalize(Y),X=c0.normalize(Z);if(!Q.startsWith(X))throw new Q4(`Path outside workspace: ${$} (resolved to ${Q}, workspace: ${X})`,"PATH_OUTSIDE_WORKSPACE");return Q}static checkRestricted($){let Z=$.split(c0.sep);for(let Y of SX)if(Z.includes(Y))throw new Q4(`Access denied: "${Y}" is a protected directory`,"RESTRICTED_PATH")}static checkTraversal($){if($.includes(".."))throw new Q4(`Path traversal not allowed: ${$}`,"PATH_TRAVERSAL")}static async validatePath($,Z){this.checkTraversal($);let Y=this.normalize($,Z);this.checkRestricted(Y);try{await W9.access(Y)}catch(Q){throw new Q4(`Path not found: ${$}`,"PATH_NOT_FOUND")}return Y}static async resolveSymlink($,Z){try{let Y=await W9.realpath($),Q=c0.normalize(Z);if(!Y.startsWith(Q))throw new Q4(`Symlink points outside workspace: ${$} -> ${Y}`,"SYMLINK_OUTSIDE_WORKSPACE");return Y}catch(Y){if(Y instanceof Q4)throw Y;return $}}static getRelativePath($,Z){return c0.relative(Z,$)}static isWithinWorkspace($,Z){let Y=c0.normalize($),Q=c0.normalize(Z);return Y.startsWith(Q)}static isRestricted($){let Z=$.split(c0.sep);return SX.some((Y)=>Z.includes(Y))}}var SX,Q4;var kX=A(()=>{SX=[".git",".claude","node_modules",".env",".env.local",".env.production",".env.development",".env.test"];Q4=class Q4 extends Error{code;constructor($,Z){super($);this.code=Z;this.name="PathSecurityError"}}});var H9;var fX=A(()=>{H9=class H9{static PATTERN=/@"([^"]+)"|@([^\s]+)/g;static LINE_RANGE_PATTERN=/#L(\d+)(?:-(\d+))?$/;static GLOB_PATTERN=/[*?[\]]/;static extract($){let Z=[],Y;this.PATTERN.lastIndex=0;while((Y=this.PATTERN.exec($))!==null){let Q=Y[0],X=Y[1]||Y[2],J=this.parseLineRange(X);if(J)X=X.replace(this.LINE_RANGE_PATTERN,"");let G=this.GLOB_PATTERN.test(X);Z.push({raw:Q,path:X.trim(),lineRange:J,startIndex:Y.index,endIndex:Y.index+Q.length,isGlob:G})}return Z}static parseLineRange($){let Z=$.match(this.LINE_RANGE_PATTERN);if(!Z)return;let Y=parseInt(Z[1],10),Q=Z[2]?parseInt(Z[2],10):void 0;return{start:Y,end:Q}}static hasAtMentions($){return $.includes("@")}static isValidPath($){if(!$||$.trim().length===0)return!1;let Z=["<",">","|","\x00"];for(let Y of Z)if($.includes(Y))return!1;return!0}static removeAtMentions($){return this.PATTERN.lastIndex=0,$.replace(this.PATTERN,"")}}});import hX from"fast-glob";import*as l4 from"fs/promises";import*as xX from"path";function F9($){return $ instanceof Map}class i7{fileCache=new Map;options;constructor($){this.options={maxFileSize:1048576,maxLines:2000,maxTokens:32000,...$},v1.debug("AttachmentCollector initialized",{maxFileSize:this.options.maxFileSize,maxLines:this.options.maxLines})}async collect($){if(!H9.hasAtMentions($))return[];let Z=H9.extract($);if(Z.length===0)return[];v1.debug(`Found ${Z.length} @ mentions`);let Y=Z.map((X)=>this.processOne(X));return(await Promise.allSettled(Y)).map((X,J)=>{if(X.status==="fulfilled")return X.value;else{let G=Z[J],K=X.reason instanceof Error?X.reason.message:String(X.reason);return v1.warn(`Failed to process @${G.path}:`,K),{type:"error",path:G.path,content:"",error:K}}})}async processOne($){if($.isGlob)return v1.debug(`Processing glob pattern: ${$.path}`),await this.processGlob($.path);let Z=await U9.validatePath($.path,this.options.cwd),Y=await U9.resolveSymlink(Z,this.options.cwd);if((await l4.stat(Y)).isDirectory())return v1.debug(`Processing directory: ${$.path}`),await this.renderDirectoryTree(Y,$.path);return v1.debug(`Processing file: ${$.path}`,{lineRange:$.lineRange}),await this.readFile(Y,$.path,$.lineRange)}async readFile($,Z,Y){let Q=this.fileCache.get($);if(Q&&Date.now()-Q.timestamp<60000)return v1.debug(`Cache hit: ${Z}`),this.formatFileAttachment(Z,Q.content,Y);let X=await l4.stat($);if(X.size>this.options.maxFileSize)throw Error(`File too large: ${Math.round(X.size/1024/1024)}MB (max ${Math.round(this.options.maxFileSize/1024/1024)}MB)`);let J;try{J=await l4.readFile($,"utf-8")}catch(G){throw Error(`Cannot read file as text: ${Z}. It may be a binary file.`)}return this.fileCache.set($,{content:J,timestamp:Date.now()}),this.formatFileAttachment(Z,J,Y)}formatFileAttachment($,Z,Y){let Q=Z.split(`
869
+ </available_skills>`)}async function hO($){let Z=SO.join($,"BLADE.md");try{return(await EX.readFile(Z,"utf-8")).trim()||null}catch{return null}}var kO;var PX=A(()=>{U0();Y4();c7();l7();kO=/<available_skills>\s*<\/available_skills>/});var TX=A(()=>{PX()});function CX($){return $.endsWith("/")||$.endsWith("\\")}function Z3($){return $.replace(/\\/g,"/").split("/").filter(Boolean)}import*as W9 from"fs/promises";import*as c0 from"path";class U9{static normalize($,Z){let Y=c0.isAbsolute($)?$:c0.resolve(Z,$),Q=c0.normalize(Y),X=c0.normalize(Z);if(!Q.startsWith(X))throw new Q2(`Path outside workspace: ${$} (resolved to ${Q}, workspace: ${X})`,"PATH_OUTSIDE_WORKSPACE");return Q}static checkRestricted($){let Z=$.split(c0.sep);for(let Y of SX)if(Z.includes(Y))throw new Q2(`Access denied: "${Y}" is a protected directory`,"RESTRICTED_PATH")}static checkTraversal($){if($.includes(".."))throw new Q2(`Path traversal not allowed: ${$}`,"PATH_TRAVERSAL")}static async validatePath($,Z){this.checkTraversal($);let Y=this.normalize($,Z);this.checkRestricted(Y);try{await W9.access(Y)}catch(Q){throw new Q2(`Path not found: ${$}`,"PATH_NOT_FOUND")}return Y}static async resolveSymlink($,Z){try{let Y=await W9.realpath($),Q=c0.normalize(Z);if(!Y.startsWith(Q))throw new Q2(`Symlink points outside workspace: ${$} -> ${Y}`,"SYMLINK_OUTSIDE_WORKSPACE");return Y}catch(Y){if(Y instanceof Q2)throw Y;return $}}static getRelativePath($,Z){return c0.relative(Z,$)}static isWithinWorkspace($,Z){let Y=c0.normalize($),Q=c0.normalize(Z);return Y.startsWith(Q)}static isRestricted($){let Z=$.split(c0.sep);return SX.some((Y)=>Z.includes(Y))}}var SX,Q2;var kX=A(()=>{SX=[".git",".claude","node_modules",".env",".env.local",".env.production",".env.development",".env.test"];Q2=class Q2 extends Error{code;constructor($,Z){super($);this.code=Z;this.name="PathSecurityError"}}});var H9;var fX=A(()=>{H9=class H9{static PATTERN=/@"([^"]+)"|@([^\s]+)/g;static LINE_RANGE_PATTERN=/#L(\d+)(?:-(\d+))?$/;static GLOB_PATTERN=/[*?[\]]/;static extract($){let Z=[],Y;this.PATTERN.lastIndex=0;while((Y=this.PATTERN.exec($))!==null){let Q=Y[0],X=Y[1]||Y[2],J=this.parseLineRange(X);if(J)X=X.replace(this.LINE_RANGE_PATTERN,"");let G=this.GLOB_PATTERN.test(X);Z.push({raw:Q,path:X.trim(),lineRange:J,startIndex:Y.index,endIndex:Y.index+Q.length,isGlob:G})}return Z}static parseLineRange($){let Z=$.match(this.LINE_RANGE_PATTERN);if(!Z)return;let Y=parseInt(Z[1],10),Q=Z[2]?parseInt(Z[2],10):void 0;return{start:Y,end:Q}}static hasAtMentions($){return $.includes("@")}static isValidPath($){if(!$||$.trim().length===0)return!1;let Z=["<",">","|","\x00"];for(let Y of Z)if($.includes(Y))return!1;return!0}static removeAtMentions($){return this.PATTERN.lastIndex=0,$.replace(this.PATTERN,"")}}});import hX from"fast-glob";import*as l2 from"fs/promises";import*as xX from"path";function F9($){return $ instanceof Map}class i7{fileCache=new Map;options;constructor($){this.options={maxFileSize:1048576,maxLines:2000,maxTokens:32000,...$},v1.debug("AttachmentCollector initialized",{maxFileSize:this.options.maxFileSize,maxLines:this.options.maxLines})}async collect($){if(!H9.hasAtMentions($))return[];let Z=H9.extract($);if(Z.length===0)return[];v1.debug(`Found ${Z.length} @ mentions`);let Y=Z.map((X)=>this.processOne(X));return(await Promise.allSettled(Y)).map((X,J)=>{if(X.status==="fulfilled")return X.value;else{let G=Z[J],K=X.reason instanceof Error?X.reason.message:String(X.reason);return v1.warn(`Failed to process @${G.path}:`,K),{type:"error",path:G.path,content:"",error:K}}})}async processOne($){if($.isGlob)return v1.debug(`Processing glob pattern: ${$.path}`),await this.processGlob($.path);let Z=await U9.validatePath($.path,this.options.cwd),Y=await U9.resolveSymlink(Z,this.options.cwd);if((await l2.stat(Y)).isDirectory())return v1.debug(`Processing directory: ${$.path}`),await this.renderDirectoryTree(Y,$.path);return v1.debug(`Processing file: ${$.path}`,{lineRange:$.lineRange}),await this.readFile(Y,$.path,$.lineRange)}async readFile($,Z,Y){let Q=this.fileCache.get($);if(Q&&Date.now()-Q.timestamp<60000)return v1.debug(`Cache hit: ${Z}`),this.formatFileAttachment(Z,Q.content,Y);let X=await l2.stat($);if(X.size>this.options.maxFileSize)throw Error(`File too large: ${Math.round(X.size/1024/1024)}MB (max ${Math.round(this.options.maxFileSize/1024/1024)}MB)`);let J;try{J=await l2.readFile($,"utf-8")}catch(G){throw Error(`Cannot read file as text: ${Z}. It may be a binary file.`)}return this.fileCache.set($,{content:J,timestamp:Date.now()}),this.formatFileAttachment(Z,J,Y)}formatFileAttachment($,Z,Y){let Q=Z.split(`
870
870
  `),X=Z,J=!1,G=Y;if(Y){let K=Math.max(0,Y.start-1),q=Y.end?Y.end:Y.start;if(K>=Q.length)throw Error(`Line range start (${Y.start}) exceeds file length (${Q.length} lines)`);let W=Math.min(q,Q.length);X=Q.slice(K,W).join(`
871
871
  `);let U=Array.from({length:W-K},(F,O)=>K+O+1);X=X.split(`
872
872
  `).map((F,O)=>`${U[O]}: ${F}`).join(`
@@ -875,8 +875,8 @@ ${Y}
875
875
 
876
876
  [... truncated ${Q.length-this.options.maxLines} lines ...]`,J=!0;return{type:"file",path:$,content:X,metadata:{size:Z.length,lines:Q.length,truncated:J,lineRange:G}}}async renderDirectoryTree($,Z){let Y=await hX("**/*",{cwd:$,dot:!1,followSymbolicLinks:!1,onlyFiles:!0,unique:!0,ignore:["node_modules/**",".git/**","dist/**","build/**",".next/**",".cache/**","coverage/**"]});if(Y.length===0)return{type:"directory",path:Z,content:"(empty directory)"};v1.debug(`Found ${Y.length} files in directory: ${Z}`);let Q=this.buildFileTree(Y),X=this.printTree(Q,Z),J=500,G=Y.length>J?`
877
877
 
878
- [... and ${Y.length-J} more files]`:"";return{type:"directory",path:Z,content:X+G,metadata:{lines:Y.length,truncated:Y.length>J}}}buildFileTree($){let Z=new Map;for(let Y of $){let Q=Z8(Y),X=Z;for(let J=0;J<Q.length;J++){let G=Q[J],K=J===Q.length-1;if(!X.has(G))X.set(G,K?null:new Map);if(!K){let q=X.get(G);if(q&&F9(q))X=q}}}return Z}printTree($,Z,Y="",Q=!0){let X=[];if(Y==="")X.push(`${Z}/`);let J=Array.from($.entries()).sort((G,K)=>{let q=F9(G[1]),W=F9(K[1]);if(q!==W)return W?1:-1;return G[0].localeCompare(K[0])});return J.forEach(([G,K],q)=>{let W=q===J.length-1,U=W?"└── ":"├── ",H=F9(K);if(X.push(`${Y}${U}${G}${H?"/":""}`),H&&K.size>0){let F=Y+(W?" ":"│ ");X.push(this.printTree(K,"",F,W))}}),X.filter((G)=>G).join(`
879
- `)}async processGlob($){let Z=await hX($,{cwd:this.options.cwd,dot:!1,followSymbolicLinks:!1,onlyFiles:!0,unique:!0,ignore:["node_modules/**",".git/**","dist/**","build/**",".next/**",".cache/**","coverage/**"]});if(Z.length===0)return{type:"error",path:$,content:"",error:`No files matched pattern: ${$}`};v1.debug(`Glob pattern "${$}" matched ${Z.length} files`);let Y=30,Q=Z.slice(0,Y),J=(await Promise.allSettled(Q.map(async(W)=>{let U=xX.join(this.options.cwd,W);try{let H=await l4.readFile(U,"utf-8"),F=H.split(`
878
+ [... and ${Y.length-J} more files]`:"";return{type:"directory",path:Z,content:X+G,metadata:{lines:Y.length,truncated:Y.length>J}}}buildFileTree($){let Z=new Map;for(let Y of $){let Q=Z3(Y),X=Z;for(let J=0;J<Q.length;J++){let G=Q[J],K=J===Q.length-1;if(!X.has(G))X.set(G,K?null:new Map);if(!K){let q=X.get(G);if(q&&F9(q))X=q}}}return Z}printTree($,Z,Y="",Q=!0){let X=[];if(Y==="")X.push(`${Z}/`);let J=Array.from($.entries()).sort((G,K)=>{let q=F9(G[1]),W=F9(K[1]);if(q!==W)return W?1:-1;return G[0].localeCompare(K[0])});return J.forEach(([G,K],q)=>{let W=q===J.length-1,U=W?"└── ":"├── ",H=F9(K);if(X.push(`${Y}${U}${G}${H?"/":""}`),H&&K.size>0){let F=Y+(W?" ":"│ ");X.push(this.printTree(K,"",F,W))}}),X.filter((G)=>G).join(`
879
+ `)}async processGlob($){let Z=await hX($,{cwd:this.options.cwd,dot:!1,followSymbolicLinks:!1,onlyFiles:!0,unique:!0,ignore:["node_modules/**",".git/**","dist/**","build/**",".next/**",".cache/**","coverage/**"]});if(Z.length===0)return{type:"error",path:$,content:"",error:`No files matched pattern: ${$}`};v1.debug(`Glob pattern "${$}" matched ${Z.length} files`);let Y=30,Q=Z.slice(0,Y),J=(await Promise.allSettled(Q.map(async(W)=>{let U=xX.join(this.options.cwd,W);try{let H=await l2.readFile(U,"utf-8"),F=H.split(`
880
880
  `),O=200,z=H,_=!1;if(F.length>200)z=F.slice(0,200).join(`
881
881
  `),z+=`
882
882
 
@@ -885,7 +885,7 @@ ${W.content}`).join(`
885
885
 
886
886
  `),q=Z.length>Y?`
887
887
 
888
- [... and ${Z.length-Y} more files matched]`:"";return{type:"file",path:$,content:K+q,metadata:{lines:J.reduce((W,U)=>W+U.lines,0),truncated:Z.length>Y||J.some((W)=>W.truncated)}}}clearExpiredCache(){let $=Date.now(),Z=0;for(let[Y,Q]of this.fileCache.entries())if($-Q.timestamp>60000)this.fileCache.delete(Y),Z++;if(Z>0)v1.debug(`Cleared ${Z} expired cache entries`)}clearCache(){this.fileCache.clear(),v1.debug("Cleared all cache")}getCacheStats(){return{size:this.fileCache.size,keys:Array.from(this.fileCache.keys())}}}var v1;var pX=A(()=>{O$();kX();fX();v1=l("Prompts")});import{nanoid as xO}from"nanoid";class m${static instance=null;fileManager=null;constructor(){}static getInstance(){if(!m$.instance)m$.instance=new m$;return m$.instance}static resetInstance(){m$.instance=null}getStoreState(){return f4.getState().spec}updateStoreState($){f4.setState((Z)=>({spec:{...Z.spec,...$}}))}async initialize($){if(this.fileManager){O9.debug("SpecManager already initialized, skipping...");return}this.fileManager=new t2($),await this.fileManager.initializeDirectories();let Z=await this.fileManager.readSteeringContext();this.updateStoreState({steeringContext:Z}),O9.debug("SpecManager initialized successfully")}getFileManager(){if(!this.fileManager)throw Error("SpecManager not initialized. Call initialize() first.");return this.fileManager}getState(){return{...this.getStoreState()}}getCurrentSpec(){return this.getStoreState().currentSpec}isActive(){return this.getStoreState().isActive}getSteeringContext(){return this.getStoreState().steeringContext}async getSteeringContextString(){let $=this.getStoreState().steeringContext;if(!$)return null;let Z=[];if($.constitution)Z.push(`## Constitution (Project Governance)
888
+ [... and ${Z.length-Y} more files matched]`:"";return{type:"file",path:$,content:K+q,metadata:{lines:J.reduce((W,U)=>W+U.lines,0),truncated:Z.length>Y||J.some((W)=>W.truncated)}}}clearExpiredCache(){let $=Date.now(),Z=0;for(let[Y,Q]of this.fileCache.entries())if($-Q.timestamp>60000)this.fileCache.delete(Y),Z++;if(Z>0)v1.debug(`Cleared ${Z} expired cache entries`)}clearCache(){this.fileCache.clear(),v1.debug("Cleared all cache")}getCacheStats(){return{size:this.fileCache.size,keys:Array.from(this.fileCache.keys())}}}var v1;var pX=A(()=>{O$();kX();fX();v1=l("Prompts")});import{nanoid as xO}from"nanoid";class m${static instance=null;fileManager=null;constructor(){}static getInstance(){if(!m$.instance)m$.instance=new m$;return m$.instance}static resetInstance(){m$.instance=null}getStoreState(){return f2.getState().spec}updateStoreState($){f2.setState((Z)=>({spec:{...Z.spec,...$}}))}async initialize($){if(this.fileManager){O9.debug("SpecManager already initialized, skipping...");return}this.fileManager=new t4($),await this.fileManager.initializeDirectories();let Z=await this.fileManager.readSteeringContext();this.updateStoreState({steeringContext:Z}),O9.debug("SpecManager initialized successfully")}getFileManager(){if(!this.fileManager)throw Error("SpecManager not initialized. Call initialize() first.");return this.fileManager}getState(){return{...this.getStoreState()}}getCurrentSpec(){return this.getStoreState().currentSpec}isActive(){return this.getStoreState().isActive}getSteeringContext(){return this.getStoreState().steeringContext}async getSteeringContextString(){let $=this.getStoreState().steeringContext;if(!$)return null;let Z=[];if($.constitution)Z.push(`## Constitution (Project Governance)
889
889
 
890
890
  ${$.constitution}`);if($.product)Z.push(`## Product Vision
891
891
 
@@ -931,7 +931,7 @@ ${Z}
931
931
  <!-- What needs to be clarified before proceeding? -->
932
932
 
933
933
  1.
934
- `}calculateTaskProgress($){let Z=$.length,Y=$.filter((Q)=>Q.status==="completed").length;return{total:Z,completed:Y}}}var O9;var O1=A(()=>{U0();O$();k$();i6();D1();O9=l("Spec")});import*as E1 from"fs/promises";class A2{async readTextFile($){return E1.readFile($,"utf-8")}async writeTextFile($,Z){await E1.writeFile($,Z,"utf-8")}async exists($){try{return await E1.access($),!0}catch{return!1}}async readBinaryFile($){return E1.readFile($)}async stat($){try{let Z=await E1.stat($);return{size:Z.size,isDirectory:Z.isDirectory(),isFile:Z.isFile(),mtime:Z.mtime}}catch{return null}}async mkdir($,Z){await E1.mkdir($,{recursive:Z?.recursive??!1,mode:Z?.mode??493})}}function i4(){return a7}function z9($){a7=$}function mX(){a7=new A2}var a7;var a4=A(()=>{a7=new A2});class r7{connection;sessionId;capabilities;fallback;constructor($,Z,Y,Q=new A2){this.connection=$;this.sessionId=Z;this.capabilities=Y;this.fallback=Q}async readTextFile($){if(!this.capabilities.readTextFile)return Y1.debug(`[AcpFileSystem] readTextFile fallback: ${$}`),this.fallback.readTextFile($);try{return Y1.debug(`[AcpFileSystem] readTextFile via ACP: ${$}`),(await this.connection.readTextFile({path:$,sessionId:this.sessionId})).content}catch(Z){return Y1.warn(`[AcpFileSystem] readTextFile ACP failed, fallback: ${Z}`),this.fallback.readTextFile($)}}async writeTextFile($,Z){if(!this.capabilities.writeTextFile)return Y1.debug(`[AcpFileSystem] writeTextFile fallback: ${$}`),this.fallback.writeTextFile($,Z);try{Y1.debug(`[AcpFileSystem] writeTextFile via ACP: ${$}`),await this.connection.writeTextFile({path:$,content:Z,sessionId:this.sessionId})}catch(Y){return Y1.warn(`[AcpFileSystem] writeTextFile ACP failed, fallback: ${Y}`),this.fallback.writeTextFile($,Z)}}async exists($){if(!this.capabilities.readTextFile)return Y1.debug(`[AcpFileSystem] exists fallback to local: ${$}`),this.fallback.exists($);try{return await this.connection.readTextFile({path:$,sessionId:this.sessionId}),Y1.debug(`[AcpFileSystem] exists(${$}): true (ACP read success)`),!0}catch(Z){let Y=String(Z).toLowerCase();if(["not found","no such file","enoent","does not exist","file not found","path not found"].some((G)=>Y.includes(G)))return Y1.debug(`[AcpFileSystem] exists(${$}): false (ACP: not found)`),!1;let J=pO(Y);return Y1.warn(`[AcpFileSystem] exists(${$}): assuming exists due to ${J} error`,{error:String(Z),errorType:J,filePath:$}),!0}}async readBinaryFile($){return Y1.debug(`[AcpFileSystem] readBinaryFile fallback: ${$}`),this.fallback.readBinaryFile($)}async stat($){return Y1.debug(`[AcpFileSystem] stat fallback: ${$}`),this.fallback.stat($)}async mkdir($,Z){return Y1.debug(`[AcpFileSystem] mkdir fallback: ${$}`),this.fallback.mkdir($,Z)}getCapabilities(){return this.capabilities}canReadTextFile(){return this.capabilities.readTextFile??!1}canWriteTextFile(){return this.capabilities.writeTextFile??!1}}function pO($){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 Y1;var dX=A(()=>{O$();a4();Y1=l("Agent")});import{spawn as mO}from"child_process";class n7{async execute($,Z){return new Promise((Y)=>{let Q=process.platform==="win32"?"cmd.exe":"/bin/bash",X=process.platform==="win32"?["/c",$]:["-c",$],J=mO(Q,X,{cwd:Z?.cwd||process.cwd(),env:{...process.env,...Z?.env},stdio:["pipe","pipe","pipe"]}),G="",K="",q=!1,W=Z?.timeout?setTimeout(()=>{q=!0,J.kill("SIGTERM")},Z.timeout):null,U=null,H=()=>{if(W)clearTimeout(W);if(U&&Z?.signal)Z.signal.removeEventListener("abort",U),U=null};if(Z?.signal)U=()=>{q=!0,J.kill("SIGTERM")},Z.signal.addEventListener("abort",U);J.stdout.on("data",(F)=>{let O=F.toString();G+=O,Z?.onOutput?.(O)}),J.stderr.on("data",(F)=>{let O=F.toString();K+=O,Z?.onOutput?.(O)}),J.on("close",(F)=>{H(),Y({success:F===0&&!q,stdout:G,stderr:K,exitCode:F,error:q?"Command was terminated":void 0})}),J.on("error",(F)=>{H(),Y({success:!1,stdout:G,stderr:K,exitCode:null,error:F.message})})})}isAvailable(){return!0}}class uX{connection;sessionId;fallback;constructor($,Z,Y=new n7){this.connection=$;this.sessionId=Z;this.fallback=Y}async execute($,Z){try{d1.debug(`[AcpTerminal] Executing command via ACP: ${$}`);let Y=await this.connection.createTerminal({sessionId:this.sessionId,command:$,cwd:Z?.cwd,env:Z?.env?Object.entries(Z.env).map(([W,U])=>({name:W,value:U})):void 0}),Q=0,X=null;if(Z?.onOutput)X=setInterval(async()=>{try{let U=(await Y.currentOutput()).output||"";if(U.length>Q){let H=U.slice(Q);Q=U.length,Z.onOutput?.(H)}}catch{}},100);let J=(W=!1)=>{if(X)clearInterval(X),X=null;(W?Y.kill().then(()=>d1.debug("[AcpTerminal] Killed remote command")).catch(()=>{}).then(()=>Y.release()).catch(()=>{}):Y.release().catch(()=>{})).catch(()=>{})},G=[];if(G.push(Y.waitForExit().then((W)=>({type:"completed",exitCode:W.exitCode??null}))),Z?.timeout)G.push(new Promise((W)=>{setTimeout(()=>W({type:"timeout"}),Z.timeout)}));if(Z?.signal)G.push(new Promise((W)=>{if(Z.signal.aborted)W({type:"aborted"});else Z.signal.addEventListener("abort",()=>W({type:"aborted"}),{once:!0})}));let K=await Promise.race(G),q="";try{if(q=(await Y.currentOutput()).output||"",Z?.onOutput&&q.length>Q)Z.onOutput(q.slice(Q))}catch{}switch(K.type){case"completed":return J(!1),{success:K.exitCode===0,stdout:q,stderr:"",exitCode:K.exitCode};case"timeout":return d1.debug(`[AcpTerminal] Command timed out, killing: ${$}`),J(!0),{success:!1,stdout:q,stderr:"",exitCode:null,error:"Command timed out"};case"aborted":return d1.debug(`[AcpTerminal] Command aborted, killing: ${$}`),J(!0),{success:!1,stdout:q,stderr:"",exitCode:null,error:"Command was aborted"}}}catch(Y){return d1.warn("[AcpTerminal] ACP terminal failed, using fallback:",Y),this.fallback.execute($,Z)}}isAvailable(){return!0}}function gX(){return z$.getInstance().getTerminalService()}function R2(){return z$.getInstance().isAcpMode()}var d1,z$;var r4=A(()=>{O$();a4();dX();d1=l("Agent");z$=class z${static sessions=new Map;static currentSessionId=null;constructor(){}static getInstance(){return new z$}static initializeSession($,Z,Y,Q){let X=Y?.fs?new r7($,Z,Y.fs):new A2;if(Y?.fs)d1.debug(`[AcpServiceContext:${Z}] Using ACP file system service`);let J=new uX($,Z);d1.debug(`[AcpServiceContext:${Z}] Using ACP terminal service`),z$.sessions.set(Z,{fileSystemService:X,terminalService:J,connection:$,clientCapabilities:Y||null,cwd:Q}),z$.currentSessionId=Z,z9(X),d1.debug(`[AcpServiceContext:${Z}] Initialized with capabilities:`,{fs:!!Y?.fs,readTextFile:Y?.fs?.readTextFile,writeTextFile:Y?.fs?.writeTextFile,cwd:Q})}static destroySession($){if(z$.sessions.delete($),z$.currentSessionId===$){let Z=Array.from(z$.sessions.keys());if(z$.currentSessionId=Z[0]||null,!z$.currentSessionId)mX();else{let Y=z$.sessions.get(z$.currentSessionId);if(Y)z9(Y.fileSystemService)}}d1.debug(`[AcpServiceContext:${$}] Session destroyed`)}static getSessionServices($){return z$.sessions.get($)||null}static setCurrentSession($){if(z$.sessions.has($)){z$.currentSessionId=$;let Z=z$.sessions.get($);if(Z)z9(Z.fileSystemService)}}static getCurrentSessionId(){return z$.currentSessionId}initialize($,Z,Y,Q){z$.initializeSession($,Z,Y,Q||process.cwd())}reset(){if(z$.currentSessionId)z$.destroySession(z$.currentSessionId)}isAcpMode(){return z$.currentSessionId!==null}getFileSystemService(){if(z$.currentSessionId){let $=z$.sessions.get(z$.currentSessionId);if($)return $.fileSystemService}return new A2}getTerminalService(){if(z$.currentSessionId){let $=z$.sessions.get(z$.currentSessionId);if($)return $.terminalService}return new n7}getConnection(){if(z$.currentSessionId){let $=z$.sessions.get(z$.currentSessionId);if($)return $.connection}return null}getSessionId(){return z$.currentSessionId}getClientCapabilities(){if(z$.currentSessionId){let $=z$.sessions.get(z$.currentSessionId);if($)return $.clientCapabilities}return null}async sendToolUpdate($,Z,Y,Q,X){let J=z$.currentSessionId;if(!J)return;let G=z$.sessions.get(J);if(!G)return;try{await G.connection.sessionUpdate({sessionId:J,update:{sessionUpdate:"tool_call",toolCallId:$,status:Z,title:Y,content:Q||[],kind:X||"other"}})}catch(K){d1.warn("[AcpServiceContext] Failed to send tool update:",K)}}}});import{isAbsolute as cX}from"path";import{z as V0}from"zod";var r$;var V2=A(()=>{r$={filePath:($)=>V0.string().min(1,"File path is required").refine((Z)=>cX(Z),{message:"Path must be absolute"}).describe($?.description||"Absolute file path"),encoding:()=>V0.enum(["utf8","base64","binary"]).default("utf8").describe("File encoding"),timeout:($=1000,Z=300000,Y=30000)=>V0.number().int("Must be an integer").min($,`Cannot be less than ${$}ms`).max(Z,`Cannot exceed ${Z}ms`).default(Y).describe(`Timeout in milliseconds (default ${Y}ms)`),pattern:($)=>V0.string().min(1,"Pattern is required").describe($?.description||"Regex or glob pattern"),glob:($)=>V0.string().min(1,"Glob pattern is required").describe($?.description||'Glob pattern (e.g., "*.js", "**/*.ts")'),lineNumber:($)=>V0.number().int("Line number must be an integer").min($?.min??0,`Line number cannot be less than ${$?.min??0}`).describe($?.description||"Line number"),lineLimit:($)=>V0.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:()=>V0.string().min(1,"Working directory is required").refine(($)=>cX($),{message:"Path must be absolute"}).describe("Absolute working directory"),environment:()=>V0.record(V0.string(),V0.string()).describe("Environment variables (key-value)").optional(),outputMode:($,Z)=>{let Y=V0.enum($);return Z?Y.default(Z):Y},flag:($)=>V0.boolean().default($?.defaultValue??!1).describe($?.description||"Boolean flag"),url:($)=>V0.string().url("Must be a valid URL").describe($?.description||"URL"),port:()=>V0.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:($)=>V0.string().min(1,"Command is required").describe($?.description||"Command to execute"),sessionId:()=>V0.string().min(1,"Session ID is required").uuid("Must be a valid UUID").optional().describe("Session identifier (UUID)"),nonNegativeInt:($)=>V0.number().int("Must be an integer").min(0,"Cannot be negative").describe($?.description||"Non-negative integer"),positiveInt:($)=>V0.number().int("Must be an integer").min(1,"Must be greater than 0").describe($?.description||"Positive integer")}});import*as o7 from"diff";function lX($,Z,Y=4){if($===Z)return null;let Q=o7.createPatch("file",$,Z,"","",{context:Y}),X=Q.split(`
934
+ `}calculateTaskProgress($){let Z=$.length,Y=$.filter((Q)=>Q.status==="completed").length;return{total:Z,completed:Y}}}var O9;var O1=A(()=>{U0();O$();k$();i6();D1();O9=l("Spec")});import*as E1 from"fs/promises";class A4{async readTextFile($){return E1.readFile($,"utf-8")}async writeTextFile($,Z){await E1.writeFile($,Z,"utf-8")}async exists($){try{return await E1.access($),!0}catch{return!1}}async readBinaryFile($){return E1.readFile($)}async stat($){try{let Z=await E1.stat($);return{size:Z.size,isDirectory:Z.isDirectory(),isFile:Z.isFile(),mtime:Z.mtime}}catch{return null}}async mkdir($,Z){await E1.mkdir($,{recursive:Z?.recursive??!1,mode:Z?.mode??493})}}function i2(){return a7}function z9($){a7=$}function mX(){a7=new A4}var a7;var a2=A(()=>{a7=new A4});class r7{connection;sessionId;capabilities;fallback;constructor($,Z,Y,Q=new A4){this.connection=$;this.sessionId=Z;this.capabilities=Y;this.fallback=Q}async readTextFile($){if(!this.capabilities.readTextFile)return Y1.debug(`[AcpFileSystem] readTextFile fallback: ${$}`),this.fallback.readTextFile($);try{return Y1.debug(`[AcpFileSystem] readTextFile via ACP: ${$}`),(await this.connection.readTextFile({path:$,sessionId:this.sessionId})).content}catch(Z){return Y1.warn(`[AcpFileSystem] readTextFile ACP failed, fallback: ${Z}`),this.fallback.readTextFile($)}}async writeTextFile($,Z){if(!this.capabilities.writeTextFile)return Y1.debug(`[AcpFileSystem] writeTextFile fallback: ${$}`),this.fallback.writeTextFile($,Z);try{Y1.debug(`[AcpFileSystem] writeTextFile via ACP: ${$}`),await this.connection.writeTextFile({path:$,content:Z,sessionId:this.sessionId})}catch(Y){return Y1.warn(`[AcpFileSystem] writeTextFile ACP failed, fallback: ${Y}`),this.fallback.writeTextFile($,Z)}}async exists($){if(!this.capabilities.readTextFile)return Y1.debug(`[AcpFileSystem] exists fallback to local: ${$}`),this.fallback.exists($);try{return await this.connection.readTextFile({path:$,sessionId:this.sessionId}),Y1.debug(`[AcpFileSystem] exists(${$}): true (ACP read success)`),!0}catch(Z){let Y=String(Z).toLowerCase();if(["not found","no such file","enoent","does not exist","file not found","path not found"].some((G)=>Y.includes(G)))return Y1.debug(`[AcpFileSystem] exists(${$}): false (ACP: not found)`),!1;let J=pO(Y);return Y1.warn(`[AcpFileSystem] exists(${$}): assuming exists due to ${J} error`,{error:String(Z),errorType:J,filePath:$}),!0}}async readBinaryFile($){return Y1.debug(`[AcpFileSystem] readBinaryFile fallback: ${$}`),this.fallback.readBinaryFile($)}async stat($){return Y1.debug(`[AcpFileSystem] stat fallback: ${$}`),this.fallback.stat($)}async mkdir($,Z){return Y1.debug(`[AcpFileSystem] mkdir fallback: ${$}`),this.fallback.mkdir($,Z)}getCapabilities(){return this.capabilities}canReadTextFile(){return this.capabilities.readTextFile??!1}canWriteTextFile(){return this.capabilities.writeTextFile??!1}}function pO($){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 Y1;var dX=A(()=>{O$();a2();Y1=l("Agent")});import{spawn as mO}from"child_process";class n7{async execute($,Z){return new Promise((Y)=>{let Q=process.platform==="win32"?"cmd.exe":"/bin/bash",X=process.platform==="win32"?["/c",$]:["-c",$],J=mO(Q,X,{cwd:Z?.cwd||process.cwd(),env:{...process.env,...Z?.env},stdio:["pipe","pipe","pipe"]}),G="",K="",q=!1,W=Z?.timeout?setTimeout(()=>{q=!0,J.kill("SIGTERM")},Z.timeout):null,U=null,H=()=>{if(W)clearTimeout(W);if(U&&Z?.signal)Z.signal.removeEventListener("abort",U),U=null};if(Z?.signal)U=()=>{q=!0,J.kill("SIGTERM")},Z.signal.addEventListener("abort",U);J.stdout.on("data",(F)=>{let O=F.toString();G+=O,Z?.onOutput?.(O)}),J.stderr.on("data",(F)=>{let O=F.toString();K+=O,Z?.onOutput?.(O)}),J.on("close",(F)=>{H(),Y({success:F===0&&!q,stdout:G,stderr:K,exitCode:F,error:q?"Command was terminated":void 0})}),J.on("error",(F)=>{H(),Y({success:!1,stdout:G,stderr:K,exitCode:null,error:F.message})})})}isAvailable(){return!0}}class uX{connection;sessionId;fallback;constructor($,Z,Y=new n7){this.connection=$;this.sessionId=Z;this.fallback=Y}async execute($,Z){try{d1.debug(`[AcpTerminal] Executing command via ACP: ${$}`);let Y=await this.connection.createTerminal({sessionId:this.sessionId,command:$,cwd:Z?.cwd,env:Z?.env?Object.entries(Z.env).map(([W,U])=>({name:W,value:U})):void 0}),Q=0,X=null;if(Z?.onOutput)X=setInterval(async()=>{try{let U=(await Y.currentOutput()).output||"";if(U.length>Q){let H=U.slice(Q);Q=U.length,Z.onOutput?.(H)}}catch{}},100);let J=(W=!1)=>{if(X)clearInterval(X),X=null;(W?Y.kill().then(()=>d1.debug("[AcpTerminal] Killed remote command")).catch(()=>{}).then(()=>Y.release()).catch(()=>{}):Y.release().catch(()=>{})).catch(()=>{})},G=[];if(G.push(Y.waitForExit().then((W)=>({type:"completed",exitCode:W.exitCode??null}))),Z?.timeout)G.push(new Promise((W)=>{setTimeout(()=>W({type:"timeout"}),Z.timeout)}));if(Z?.signal)G.push(new Promise((W)=>{if(Z.signal.aborted)W({type:"aborted"});else Z.signal.addEventListener("abort",()=>W({type:"aborted"}),{once:!0})}));let K=await Promise.race(G),q="";try{if(q=(await Y.currentOutput()).output||"",Z?.onOutput&&q.length>Q)Z.onOutput(q.slice(Q))}catch{}switch(K.type){case"completed":return J(!1),{success:K.exitCode===0,stdout:q,stderr:"",exitCode:K.exitCode};case"timeout":return d1.debug(`[AcpTerminal] Command timed out, killing: ${$}`),J(!0),{success:!1,stdout:q,stderr:"",exitCode:null,error:"Command timed out"};case"aborted":return d1.debug(`[AcpTerminal] Command aborted, killing: ${$}`),J(!0),{success:!1,stdout:q,stderr:"",exitCode:null,error:"Command was aborted"}}}catch(Y){return d1.warn("[AcpTerminal] ACP terminal failed, using fallback:",Y),this.fallback.execute($,Z)}}isAvailable(){return!0}}function gX(){return z$.getInstance().getTerminalService()}function R4(){return z$.getInstance().isAcpMode()}var d1,z$;var r2=A(()=>{O$();a2();dX();d1=l("Agent");z$=class z${static sessions=new Map;static currentSessionId=null;constructor(){}static getInstance(){return new z$}static initializeSession($,Z,Y,Q){let X=Y?.fs?new r7($,Z,Y.fs):new A4;if(Y?.fs)d1.debug(`[AcpServiceContext:${Z}] Using ACP file system service`);let J=new uX($,Z);d1.debug(`[AcpServiceContext:${Z}] Using ACP terminal service`),z$.sessions.set(Z,{fileSystemService:X,terminalService:J,connection:$,clientCapabilities:Y||null,cwd:Q}),z$.currentSessionId=Z,z9(X),d1.debug(`[AcpServiceContext:${Z}] Initialized with capabilities:`,{fs:!!Y?.fs,readTextFile:Y?.fs?.readTextFile,writeTextFile:Y?.fs?.writeTextFile,cwd:Q})}static destroySession($){if(z$.sessions.delete($),z$.currentSessionId===$){let Z=Array.from(z$.sessions.keys());if(z$.currentSessionId=Z[0]||null,!z$.currentSessionId)mX();else{let Y=z$.sessions.get(z$.currentSessionId);if(Y)z9(Y.fileSystemService)}}d1.debug(`[AcpServiceContext:${$}] Session destroyed`)}static getSessionServices($){return z$.sessions.get($)||null}static setCurrentSession($){if(z$.sessions.has($)){z$.currentSessionId=$;let Z=z$.sessions.get($);if(Z)z9(Z.fileSystemService)}}static getCurrentSessionId(){return z$.currentSessionId}initialize($,Z,Y,Q){z$.initializeSession($,Z,Y,Q||process.cwd())}reset(){if(z$.currentSessionId)z$.destroySession(z$.currentSessionId)}isAcpMode(){return z$.currentSessionId!==null}getFileSystemService(){if(z$.currentSessionId){let $=z$.sessions.get(z$.currentSessionId);if($)return $.fileSystemService}return new A4}getTerminalService(){if(z$.currentSessionId){let $=z$.sessions.get(z$.currentSessionId);if($)return $.terminalService}return new n7}getConnection(){if(z$.currentSessionId){let $=z$.sessions.get(z$.currentSessionId);if($)return $.connection}return null}getSessionId(){return z$.currentSessionId}getClientCapabilities(){if(z$.currentSessionId){let $=z$.sessions.get(z$.currentSessionId);if($)return $.clientCapabilities}return null}async sendToolUpdate($,Z,Y,Q,X){let J=z$.currentSessionId;if(!J)return;let G=z$.sessions.get(J);if(!G)return;try{await G.connection.sessionUpdate({sessionId:J,update:{sessionUpdate:"tool_call",toolCallId:$,status:Z,title:Y,content:Q||[],kind:X||"other"}})}catch(K){d1.warn("[AcpServiceContext] Failed to send tool update:",K)}}}});import{isAbsolute as cX}from"path";import{z as V0}from"zod";var r$;var V4=A(()=>{r$={filePath:($)=>V0.string().min(1,"File path is required").refine((Z)=>cX(Z),{message:"Path must be absolute"}).describe($?.description||"Absolute file path"),encoding:()=>V0.enum(["utf8","base64","binary"]).default("utf8").describe("File encoding"),timeout:($=1000,Z=300000,Y=30000)=>V0.number().int("Must be an integer").min($,`Cannot be less than ${$}ms`).max(Z,`Cannot exceed ${Z}ms`).default(Y).describe(`Timeout in milliseconds (default ${Y}ms)`),pattern:($)=>V0.string().min(1,"Pattern is required").describe($?.description||"Regex or glob pattern"),glob:($)=>V0.string().min(1,"Glob pattern is required").describe($?.description||'Glob pattern (e.g., "*.js", "**/*.ts")'),lineNumber:($)=>V0.number().int("Line number must be an integer").min($?.min??0,`Line number cannot be less than ${$?.min??0}`).describe($?.description||"Line number"),lineLimit:($)=>V0.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:()=>V0.string().min(1,"Working directory is required").refine(($)=>cX($),{message:"Path must be absolute"}).describe("Absolute working directory"),environment:()=>V0.record(V0.string(),V0.string()).describe("Environment variables (key-value)").optional(),outputMode:($,Z)=>{let Y=V0.enum($);return Z?Y.default(Z):Y},flag:($)=>V0.boolean().default($?.defaultValue??!1).describe($?.description||"Boolean flag"),url:($)=>V0.string().url("Must be a valid URL").describe($?.description||"URL"),port:()=>V0.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:($)=>V0.string().min(1,"Command is required").describe($?.description||"Command to execute"),sessionId:()=>V0.string().min(1,"Session ID is required").uuid("Must be a valid UUID").optional().describe("Session identifier (UUID)"),nonNegativeInt:($)=>V0.number().int("Must be an integer").min(0,"Cannot be negative").describe($?.description||"Non-negative integer"),positiveInt:($)=>V0.number().int("Must be an integer").min(1,"Must be greater than 0").describe($?.description||"Positive integer")}});import*as o7 from"diff";function lX($,Z,Y=4){if($===Z)return null;let Q=o7.createPatch("file",$,Z,"","",{context:Y}),X=Q.split(`
935
935
  `),J=1;for(let G of X){let K=G.match(/@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@/);if(K){J=parseInt(K[1],10);break}}return`
936
936
  <<<DIFF>>>
937
937
  ${JSON.stringify({patch:Q,startLine:Math.max(1,J-Y),matchLine:J})}
@@ -955,7 +955,7 @@ ${JSON.stringify({patch:L,startLine:F+1,matchLine:K+1})}
955
955
  `),q=$.split(`
956
956
  `);for(let W=0;W<=q.length-Y.length;W++){let U=q[W].match(/^(\s+)/),H=U?U[1]:"",F=q.slice(W,W+Y.length);if(F.map((_)=>{if(_.startsWith(H))return _.slice(H.length);return _}).join(`
957
957
  `)===K)return F.join(`
958
- `)}return null}var nX=()=>{};import{promises as _9}from"node:fs";class e0{static instance=null;accessedFiles=new Map;constructor(){}static getInstance(){if(!e0.instance)e0.instance=new e0;return e0.instance}async recordFileRead($,Z){try{let Y=await _9.stat($),Q={filePath:$,accessTime:Date.now(),mtime:Y.mtimeMs,sessionId:Z,lastOperation:"read"};this.accessedFiles.set($,Q),Y8.debug(`记录文件读取: ${$}`)}catch(Y){Y8.warn(`记录文件读取失败: ${$}`,Y)}}async recordFileEdit($,Z,Y="edit"){try{let Q=await _9.stat($),X={filePath:$,accessTime:Date.now(),mtime:Q.mtimeMs,sessionId:Z,lastOperation:Y};this.accessedFiles.set($,X),Y8.debug(`记录文件${Y==="edit"?"编辑":"写入"}: ${$}`)}catch(Q){Y8.warn(`记录文件${Y==="edit"?"编辑":"写入"}失败: ${$}`,Q)}}hasFileBeenRead($,Z){let Y=this.accessedFiles.get($);if(!Y)return!1;if(Z&&Y.sessionId!==Z)return!1;return!0}async checkFileModification($){let Z=this.accessedFiles.get($);if(!Z)return{modified:!1,message:"文件未被跟踪"};try{let Y=await _9.stat($);if(Math.abs(Y.mtimeMs-Z.mtime)>1)return{modified:!0,message:`文件在访问后被修改(访问时间: ${new Date(Z.accessTime).toISOString()}, 当前修改时间: ${Y.mtime.toISOString()})`};return{modified:!1}}catch(Y){let Q=Y;if(Q.code==="ENOENT")return{modified:!0,message:"文件已被删除"};return{modified:!1,message:`无法检查文件状态: ${Q.message}`}}}async checkExternalModification($){let Z=this.accessedFiles.get($);if(!Z)return{isExternal:!1,message:"文件未被跟踪"};try{let Y=await _9.stat($);if(Y.mtimeMs-Z.mtime>2000)return{isExternal:!0,message:`文件在 ${new Date(Z.accessTime).toISOString()} (${Z.lastOperation}) 之后被外部程序修改(当前修改时间: ${Y.mtime.toISOString()})`};return{isExternal:!1}}catch(Y){let Q=Y;if(Q.code==="ENOENT")return{isExternal:!0,message:"文件已被删除"};return Y8.warn(`检查文件外部修改失败: ${$}`,Y),{isExternal:!1,message:`无法检查文件状态: ${Q.message}`}}}getFileRecord($){return this.accessedFiles.get($)}clearFileRecord($){this.accessedFiles.delete($)}clearAll(){this.accessedFiles.clear()}clearSession($){for(let[Z,Y]of this.accessedFiles.entries())if(Y.sessionId===$)this.accessedFiles.delete(Z)}getTrackedFiles(){return Array.from(this.accessedFiles.keys())}getTrackedFileCount(){return this.accessedFiles.size}static resetInstance(){e0.instance=null}}var Y8;var B9=A(()=>{O$();Y8=l("Tool")});import{execSync as dO}from"node:child_process";import*as t7 from"node:os";import*as X4 from"node:path";function uO($){return X4.resolve($).replace(/[/\\]/g,"-").replace(/:/g,"_")}function oX($){let Z=$.replace(/_/g,":");if(Z.startsWith("-"))Z="/"+Z.slice(1);return Z.replace(/-/g,"/")}function Q8($){let Z=t7.homedir(),Y=uO($);return X4.join(Z,".blade","projects",Y)}function z1($,Z){return X4.join(Q8($),`${Z}.jsonl`)}function n4($){try{return dO("git rev-parse --abbrev-ref HEAD",{cwd:$,encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()||void 0}catch{return}}function J4(){return X4.join(t7.homedir(),".blade")}async function sX(){let{readdir:$}=await import("node:fs/promises");try{let Z=X4.join(J4(),"projects");return(await $(Z,{withFileTypes:!0})).filter((Q)=>Q.isDirectory()).map((Q)=>Q.name)}catch{return[]}}var X8=()=>{};import*as tX from"node:crypto";import{promises as u1}from"node:fs";import*as G4 from"node:path";class J8{sessionId;enableCheckpoints;maxSnapshots;snapshotDir;trackedFileBackups=new Map;snapshots=[];constructor($){this.sessionId=$.sessionId,this.enableCheckpoints=$.enableCheckpoints??!0,this.maxSnapshots=$.maxSnapshots??10;let Z=J4();this.snapshotDir=G4.join(Z,"file-history",this.sessionId)}async initialize(){if(!this.enableCheckpoints)return;try{await u1.mkdir(this.snapshotDir,{recursive:!0,mode:493}),console.log(`[SnapshotManager] 初始化快照目录: ${this.snapshotDir}`)}catch($){throw console.warn("[SnapshotManager] 创建快照目录失败:",$),$}}async createSnapshot($,Z){if(!this.enableCheckpoints)return console.log("[SnapshotManager] 检查点已禁用,跳过快照创建"),{backupFileName:"",version:0,backupTime:new Date};try{await u1.access($)}catch{return console.warn(`[SnapshotManager] 文件不存在,跳过快照: ${$}`),{backupFileName:"",version:0,backupTime:new Date}}let Y=this.trackedFileBackups.get($),Q=Y?Y.version+1:1,X=this.generateFileHash($,Q),J=G4.join(this.snapshotDir,`${X}@v${Q}`);try{let G=await u1.readFile($,{encoding:"utf-8"});await u1.writeFile(J,G,{encoding:"utf-8"});let K={backupFileName:X,version:Q,backupTime:new Date};return this.trackedFileBackups.set($,K),this.snapshots.push({messageId:Z,backupFileName:X,timestamp:new Date,filePath:$}),console.log(`[SnapshotManager] 创建快照: ${$} -> ${X}@v${Q}`),await this.cleanupOldSnapshots($),K}catch(G){throw console.error(`[SnapshotManager] 创建快照失败: ${$}`,G),G}}async restoreSnapshot($,Z){let Y=this.snapshots.slice().reverse().find((J)=>J.messageId===Z&&J.filePath===$);if(!Y)throw Error(`未找到快照: messageId=${Z}, filePath=${$}`);let Q=this.trackedFileBackups.get($);if(!Q)throw Error(`未找到文件追踪信息: ${$}`);let X=G4.join(this.snapshotDir,`${Y.backupFileName}@v${Q.version}`);try{let J=await u1.readFile(X,{encoding:"utf-8"});await u1.writeFile($,J,{encoding:"utf-8"}),console.log(`[SnapshotManager] 恢复快照: ${$} <- ${Y.backupFileName}@v${Q.version}`)}catch(J){throw console.error(`[SnapshotManager] 恢复快照失败: ${$}`,J),J}}async listSnapshots($){return this.snapshots.filter((Z)=>Z.filePath===$)}async cleanupOldSnapshots($){let Z=this.snapshots.filter((X)=>X.filePath===$);if(Z.length<=this.maxSnapshots)return;let Q=Z.sort((X,J)=>X.timestamp.getTime()-J.timestamp.getTime()).slice(0,Z.length-this.maxSnapshots);for(let X of Q){let J=this.trackedFileBackups.get(X.filePath);if(!J)continue;let G=G4.join(this.snapshotDir,`${X.backupFileName}@v${J.version}`);try{await u1.unlink(G),console.log(`[SnapshotManager] 删除旧快照: ${G}`)}catch(q){console.warn(`[SnapshotManager] 删除快照失败: ${G}`,q)}let K=this.snapshots.indexOf(X);if(K>-1)this.snapshots.splice(K,1)}}async cleanup($=0){try{let Z=await u1.readdir(this.snapshotDir);if(Z.length<=$)return;let Y=await Promise.all(Z.map(async(X)=>{let J=G4.join(this.snapshotDir,X),G=await u1.stat(J);return{file:X,mtime:G.mtime.getTime()}}));Y.sort((X,J)=>J.mtime-X.mtime);let Q=Y.slice($);for(let{file:X}of Q){let J=G4.join(this.snapshotDir,X);await u1.unlink(J),console.log(`[SnapshotManager] 清理快照: ${J}`)}}catch(Z){console.warn("[SnapshotManager] 清理快照失败:",Z)}}generateFileHash($,Z){let Y=tX.createHash("md5");return Y.update(`${$}:${Z}`),Y.digest("hex").substring(0,16)}getSnapshotDir(){return this.snapshotDir}getSessionId(){return this.sessionId}getTrackedFileCount(){return this.trackedFileBackups.size}getSnapshotCount(){return this.snapshots.length}}var e7=A(()=>{X8()});import{basename as gO,extname as cO}from"path";import{z as L9}from"zod";function eX($){return $.replaceAll("‘","'").replaceAll("’","'").replaceAll("“",'"').replaceAll("”",'"')}function lO($,Z){if($.includes(Z))return{matched:Z,strategy:"exact"};let Y=eX(Z),X=eX($).indexOf(Y);if(X!==-1)return{matched:$.substring(X,X+Z.length),strategy:"normalize_quotes"};let J=aX(Z);if(J!==Z&&$.includes(J))return{matched:J,strategy:"unescape"};let G=rX($,Z);if(G)return{matched:G,strategy:"flexible"};return{matched:null,strategy:"failed"}}function iO($,Z){if(Z.length===0)return[];let Y=[],Q=$.indexOf(Z);while(Q!==-1)Y.push(Q),Q=$.indexOf(Z,Q+Z.length);return Y}function aO($,Z){let{file_path:Y,matches_found:Q,replacements_made:X,replace_all:J,size_diff:G}=$,K=`✅ 成功编辑文件: ${Y}`;if(K+=`
958
+ `)}return null}var nX=()=>{};import{promises as _9}from"node:fs";class e0{static instance=null;accessedFiles=new Map;constructor(){}static getInstance(){if(!e0.instance)e0.instance=new e0;return e0.instance}async recordFileRead($,Z){try{let Y=await _9.stat($),Q={filePath:$,accessTime:Date.now(),mtime:Y.mtimeMs,sessionId:Z,lastOperation:"read"};this.accessedFiles.set($,Q),Y3.debug(`记录文件读取: ${$}`)}catch(Y){Y3.warn(`记录文件读取失败: ${$}`,Y)}}async recordFileEdit($,Z,Y="edit"){try{let Q=await _9.stat($),X={filePath:$,accessTime:Date.now(),mtime:Q.mtimeMs,sessionId:Z,lastOperation:Y};this.accessedFiles.set($,X),Y3.debug(`记录文件${Y==="edit"?"编辑":"写入"}: ${$}`)}catch(Q){Y3.warn(`记录文件${Y==="edit"?"编辑":"写入"}失败: ${$}`,Q)}}hasFileBeenRead($,Z){let Y=this.accessedFiles.get($);if(!Y)return!1;if(Z&&Y.sessionId!==Z)return!1;return!0}async checkFileModification($){let Z=this.accessedFiles.get($);if(!Z)return{modified:!1,message:"文件未被跟踪"};try{let Y=await _9.stat($);if(Math.abs(Y.mtimeMs-Z.mtime)>1)return{modified:!0,message:`文件在访问后被修改(访问时间: ${new Date(Z.accessTime).toISOString()}, 当前修改时间: ${Y.mtime.toISOString()})`};return{modified:!1}}catch(Y){let Q=Y;if(Q.code==="ENOENT")return{modified:!0,message:"文件已被删除"};return{modified:!1,message:`无法检查文件状态: ${Q.message}`}}}async checkExternalModification($){let Z=this.accessedFiles.get($);if(!Z)return{isExternal:!1,message:"文件未被跟踪"};try{let Y=await _9.stat($);if(Y.mtimeMs-Z.mtime>2000)return{isExternal:!0,message:`文件在 ${new Date(Z.accessTime).toISOString()} (${Z.lastOperation}) 之后被外部程序修改(当前修改时间: ${Y.mtime.toISOString()})`};return{isExternal:!1}}catch(Y){let Q=Y;if(Q.code==="ENOENT")return{isExternal:!0,message:"文件已被删除"};return Y3.warn(`检查文件外部修改失败: ${$}`,Y),{isExternal:!1,message:`无法检查文件状态: ${Q.message}`}}}getFileRecord($){return this.accessedFiles.get($)}clearFileRecord($){this.accessedFiles.delete($)}clearAll(){this.accessedFiles.clear()}clearSession($){for(let[Z,Y]of this.accessedFiles.entries())if(Y.sessionId===$)this.accessedFiles.delete(Z)}getTrackedFiles(){return Array.from(this.accessedFiles.keys())}getTrackedFileCount(){return this.accessedFiles.size}static resetInstance(){e0.instance=null}}var Y3;var B9=A(()=>{O$();Y3=l("Tool")});import{execSync as dO}from"node:child_process";import*as t7 from"node:os";import*as X2 from"node:path";function uO($){return X2.resolve($).replace(/[/\\]/g,"-").replace(/:/g,"_")}function oX($){let Z=$.replace(/_/g,":");if(Z.startsWith("-"))Z="/"+Z.slice(1);return Z.replace(/-/g,"/")}function Q3($){let Z=t7.homedir(),Y=uO($);return X2.join(Z,".blade","projects",Y)}function z1($,Z){return X2.join(Q3($),`${Z}.jsonl`)}function n2($){try{return dO("git rev-parse --abbrev-ref HEAD",{cwd:$,encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()||void 0}catch{return}}function J2(){return X2.join(t7.homedir(),".blade")}async function sX(){let{readdir:$}=await import("node:fs/promises");try{let Z=X2.join(J2(),"projects");return(await $(Z,{withFileTypes:!0})).filter((Q)=>Q.isDirectory()).map((Q)=>Q.name)}catch{return[]}}var X3=()=>{};import*as tX from"node:crypto";import{promises as u1}from"node:fs";import*as G2 from"node:path";class J3{sessionId;enableCheckpoints;maxSnapshots;snapshotDir;trackedFileBackups=new Map;snapshots=[];constructor($){this.sessionId=$.sessionId,this.enableCheckpoints=$.enableCheckpoints??!0,this.maxSnapshots=$.maxSnapshots??10;let Z=J2();this.snapshotDir=G2.join(Z,"file-history",this.sessionId)}async initialize(){if(!this.enableCheckpoints)return;try{await u1.mkdir(this.snapshotDir,{recursive:!0,mode:493}),console.log(`[SnapshotManager] 初始化快照目录: ${this.snapshotDir}`)}catch($){throw console.warn("[SnapshotManager] 创建快照目录失败:",$),$}}async createSnapshot($,Z){if(!this.enableCheckpoints)return console.log("[SnapshotManager] 检查点已禁用,跳过快照创建"),{backupFileName:"",version:0,backupTime:new Date};try{await u1.access($)}catch{return console.warn(`[SnapshotManager] 文件不存在,跳过快照: ${$}`),{backupFileName:"",version:0,backupTime:new Date}}let Y=this.trackedFileBackups.get($),Q=Y?Y.version+1:1,X=this.generateFileHash($,Q),J=G2.join(this.snapshotDir,`${X}@v${Q}`);try{let G=await u1.readFile($,{encoding:"utf-8"});await u1.writeFile(J,G,{encoding:"utf-8"});let K={backupFileName:X,version:Q,backupTime:new Date};return this.trackedFileBackups.set($,K),this.snapshots.push({messageId:Z,backupFileName:X,timestamp:new Date,filePath:$}),console.log(`[SnapshotManager] 创建快照: ${$} -> ${X}@v${Q}`),await this.cleanupOldSnapshots($),K}catch(G){throw console.error(`[SnapshotManager] 创建快照失败: ${$}`,G),G}}async restoreSnapshot($,Z){let Y=this.snapshots.slice().reverse().find((J)=>J.messageId===Z&&J.filePath===$);if(!Y)throw Error(`未找到快照: messageId=${Z}, filePath=${$}`);let Q=this.trackedFileBackups.get($);if(!Q)throw Error(`未找到文件追踪信息: ${$}`);let X=G2.join(this.snapshotDir,`${Y.backupFileName}@v${Q.version}`);try{let J=await u1.readFile(X,{encoding:"utf-8"});await u1.writeFile($,J,{encoding:"utf-8"}),console.log(`[SnapshotManager] 恢复快照: ${$} <- ${Y.backupFileName}@v${Q.version}`)}catch(J){throw console.error(`[SnapshotManager] 恢复快照失败: ${$}`,J),J}}async listSnapshots($){return this.snapshots.filter((Z)=>Z.filePath===$)}async cleanupOldSnapshots($){let Z=this.snapshots.filter((X)=>X.filePath===$);if(Z.length<=this.maxSnapshots)return;let Q=Z.sort((X,J)=>X.timestamp.getTime()-J.timestamp.getTime()).slice(0,Z.length-this.maxSnapshots);for(let X of Q){let J=this.trackedFileBackups.get(X.filePath);if(!J)continue;let G=G2.join(this.snapshotDir,`${X.backupFileName}@v${J.version}`);try{await u1.unlink(G),console.log(`[SnapshotManager] 删除旧快照: ${G}`)}catch(q){console.warn(`[SnapshotManager] 删除快照失败: ${G}`,q)}let K=this.snapshots.indexOf(X);if(K>-1)this.snapshots.splice(K,1)}}async cleanup($=0){try{let Z=await u1.readdir(this.snapshotDir);if(Z.length<=$)return;let Y=await Promise.all(Z.map(async(X)=>{let J=G2.join(this.snapshotDir,X),G=await u1.stat(J);return{file:X,mtime:G.mtime.getTime()}}));Y.sort((X,J)=>J.mtime-X.mtime);let Q=Y.slice($);for(let{file:X}of Q){let J=G2.join(this.snapshotDir,X);await u1.unlink(J),console.log(`[SnapshotManager] 清理快照: ${J}`)}}catch(Z){console.warn("[SnapshotManager] 清理快照失败:",Z)}}generateFileHash($,Z){let Y=tX.createHash("md5");return Y.update(`${$}:${Z}`),Y.digest("hex").substring(0,16)}getSnapshotDir(){return this.snapshotDir}getSessionId(){return this.sessionId}getTrackedFileCount(){return this.trackedFileBackups.size}getSnapshotCount(){return this.snapshots.length}}var e7=A(()=>{X3()});import{basename as gO,extname as cO}from"path";import{z as L9}from"zod";function eX($){return $.replaceAll("‘","'").replaceAll("’","'").replaceAll("“",'"').replaceAll("”",'"')}function lO($,Z){if($.includes(Z))return{matched:Z,strategy:"exact"};let Y=eX(Z),X=eX($).indexOf(Y);if(X!==-1)return{matched:$.substring(X,X+Z.length),strategy:"normalize_quotes"};let J=aX(Z);if(J!==Z&&$.includes(J))return{matched:J,strategy:"unescape"};let G=rX($,Z);if(G)return{matched:G,strategy:"flexible"};return{matched:null,strategy:"failed"}}function iO($,Z){if(Z.length===0)return[];let Y=[],Q=$.indexOf(Z);while(Q!==-1)Y.push(Q),Q=$.indexOf(Z,Q+Z.length);return Y}function aO($,Z){let{file_path:Y,matches_found:Q,replacements_made:X,replace_all:J,size_diff:G}=$,K=`✅ 成功编辑文件: ${Y}`;if(K+=`
959
959
  \uD83D\uDCDD 替换了 ${X} 个匹配项`,!J&&Q>1)K+=` (共找到 ${Q} 个匹配项)`;if(G!==0){let q=G>0?`增加${G}`:`减少${Math.abs(G)}`;K+=`
960
960
  \uD83D\uDCCA 文件大小${q}个字符`}if(Z)K+=Z;return K}function rO($,Z,Y){let Q=$.split(`
961
961
  `),X=Q.length,J=nO($,Z,3),G=0,K=Math.min(20,X);if(J.length>0){let O=J[0];G=Math.max(0,O.lineNumber-10),K=Math.min(X,O.lineNumber+10)}let W=Q.slice(G,K).map((O,z)=>{return` ${(G+z+1).toString().padStart(4)}: ${O}`}).join(`
@@ -1007,7 +1007,7 @@ ${W}
1007
1007
  `,F+=" 3. 提供更多上下文代码确保唯一性",{llmContent:U,displayContent:F,metadata:{searchStringLength:Z.length,fuzzyMatches:J.map((O)=>({line:O.lineNumber,similarity:O.similarity,preview:O.text.substring(0,100)})),excerptRange:[G+1,K],totalLines:X}}}function nO($,Z,Y=3){let Q=$.split(`
1008
1008
  `),X=Z.split(`
1009
1009
  `);if(X.length===1)return Q.map((q,W)=>({text:q,lineNumber:W+1,similarity:$J(Z.trim(),q.trim())})).filter((q)=>q.similarity>0.5).sort((q,W)=>W.similarity-q.similarity).slice(0,Y);let J=X.length,G=[];for(let K=0;K<=Q.length-J;K++){let q=Q.slice(K,K+J).join(`
1010
- `),W=$J(Z,q);if(W>0.5)G.push({text:q,lineNumber:K+1,similarity:W})}return G.sort((K,q)=>q.similarity-K.similarity).slice(0,Y)}function $J($,Z){let Y=(F)=>F.trim().replace(/\s+/g," ").replace(/[\u201c\u201d"]/g,'"').replace(/[\u2018\u2019']/g,"'"),Q=Y($),X=Y(Z);if(Q===X)return 1;let J=Q.length,G=X.length;if(J===0)return G===0?1:0;if(G===0)return 0;let K=200,q=Q.substring(0,K),W=X.substring(0,K),U=oO(q,W),H=Math.max(q.length,W.length);return 1-U/H}function oO($,Z){let Y=$.length,Q=Z.length,X=Array(Y+1).fill(null).map(()=>Array(Q+1).fill(0));for(let J=0;J<=Y;J++)X[J][0]=J;for(let J=0;J<=Q;J++)X[0][J]=J;for(let J=1;J<=Y;J++)for(let G=1;G<=Q;G++){let K=$[J-1]===Z[G-1]?0:1;X[J][G]=Math.min(X[J-1][G]+1,X[J][G-1]+1,X[J-1][G-1]+K)}return X[Y][Q]}var $5;var ZJ=A(()=>{r4();a4();p$();j0();V2();s7();nX();B9();e7();$5=t({name:"Edit",displayName:"File Edit",kind:"write",strict:!0,isConcurrencySafe:!1,schema:L9.object({file_path:r$.filePath({description:"Absolute path of the file to edit"}),old_string:L9.string().min(1,"old_string cannot be empty").describe("String to replace"),new_string:L9.string().describe("Replacement string (can be empty)"),replace_all:L9.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($,Z){let{file_path:Y,old_string:Q,new_string:X,replace_all:J}=$,{updateOutput:G,sessionId:K,messageId:q}=Z,W=Z.signal??new AbortController().signal;try{G?.("Starting to read file...");let U=i4(),H=R2(),F;try{if(H)G?.("通过 IDE 读取文件...");F=await U.readTextFile(Y)}catch(b){let C=b;if(C.code==="ENOENT"||C.message?.includes("not found"))return{success:!1,llmContent:`File not found: ${Y}`,displayContent:`❌ 文件不存在: ${Y}`,error:{type:"execution_error",message:"文件不存在"}};throw b}if(W.throwIfAborted(),K){let b=e0.getInstance();if(!b.hasFileBeenRead(Y,K))return{success:!1,llmContent:"You must use your Read tool at least once in the conversation before editing. This tool will error if you attempt an edit without reading the file.",displayContent:`❌ 编辑失败:必须先使用 Read 工具读取文件
1010
+ `),W=$J(Z,q);if(W>0.5)G.push({text:q,lineNumber:K+1,similarity:W})}return G.sort((K,q)=>q.similarity-K.similarity).slice(0,Y)}function $J($,Z){let Y=(F)=>F.trim().replace(/\s+/g," ").replace(/[\u201c\u201d"]/g,'"').replace(/[\u2018\u2019']/g,"'"),Q=Y($),X=Y(Z);if(Q===X)return 1;let J=Q.length,G=X.length;if(J===0)return G===0?1:0;if(G===0)return 0;let K=200,q=Q.substring(0,K),W=X.substring(0,K),U=oO(q,W),H=Math.max(q.length,W.length);return 1-U/H}function oO($,Z){let Y=$.length,Q=Z.length,X=Array(Y+1).fill(null).map(()=>Array(Q+1).fill(0));for(let J=0;J<=Y;J++)X[J][0]=J;for(let J=0;J<=Q;J++)X[0][J]=J;for(let J=1;J<=Y;J++)for(let G=1;G<=Q;G++){let K=$[J-1]===Z[G-1]?0:1;X[J][G]=Math.min(X[J-1][G]+1,X[J][G-1]+1,X[J-1][G-1]+K)}return X[Y][Q]}var $5;var ZJ=A(()=>{r2();a2();p$();j0();V4();s7();nX();B9();e7();$5=t({name:"Edit",displayName:"File Edit",kind:"write",strict:!0,isConcurrencySafe:!1,schema:L9.object({file_path:r$.filePath({description:"Absolute path of the file to edit"}),old_string:L9.string().min(1,"old_string cannot be empty").describe("String to replace"),new_string:L9.string().describe("Replacement string (can be empty)"),replace_all:L9.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($,Z){let{file_path:Y,old_string:Q,new_string:X,replace_all:J}=$,{updateOutput:G,sessionId:K,messageId:q}=Z,W=Z.signal??new AbortController().signal;try{G?.("Starting to read file...");let U=i2(),H=R4(),F;try{if(H)G?.("通过 IDE 读取文件...");F=await U.readTextFile(Y)}catch(b){let C=b;if(C.code==="ENOENT"||C.message?.includes("not found"))return{success:!1,llmContent:`File not found: ${Y}`,displayContent:`❌ 文件不存在: ${Y}`,error:{type:"execution_error",message:"文件不存在"}};throw b}if(W.throwIfAborted(),K){let b=e0.getInstance();if(!b.hasFileBeenRead(Y,K))return{success:!1,llmContent:"You must use your Read tool at least once in the conversation before editing. This tool will error if you attempt an edit without reading the file.",displayContent:`❌ 编辑失败:必须先使用 Read 工具读取文件
1011
1011
 
1012
1012
  请先用 Read 工具查看文件内容,再进行编辑。`,error:{type:"validation_error",message:"File not read before edit"}};let C=await b.checkExternalModification(Y);if(C.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.
1013
1013
 
@@ -1015,12 +1015,12 @@ Details: ${C.message}`,displayContent:`❌ 编辑失败:文件已被外部程
1015
1015
 
1016
1016
  ${C.message}
1017
1017
 
1018
- \uD83D\uDCA1 请重新使用 Read 工具读取最新内容后再编辑`,error:{type:"validation_error",message:"File modified externally",details:{externalModification:C.message}}}}if(K&&q)try{let b=new J8({sessionId:K});await b.initialize(),await b.createSnapshot(Y,q)}catch(b){console.warn("[EditTool] 创建快照失败:",b)}if(Q===X)return{success:!1,llmContent:"New string is identical; no replacement needed",displayContent:"⚠️ 新字符串与旧字符串相同,无需进行替换",error:{type:"validation_error",message:"新旧字符串相同"}};let O=lO(F,Q);if(!O.matched){let b=rO(F,Q,Y);return{success:!1,llmContent:b.llmContent,displayContent:b.displayContent,error:{type:"execution_error",message:"未找到匹配内容",details:b.metadata}}}let z=O.matched;if(O.strategy!=="exact")console.log(`[SmartEdit] 使用策略: ${O.strategy}`);let _=iO(F,z);if(_.length>1&&!J){let b=F.split(`
1018
+ \uD83D\uDCA1 请重新使用 Read 工具读取最新内容后再编辑`,error:{type:"validation_error",message:"File modified externally",details:{externalModification:C.message}}}}if(K&&q)try{let b=new J3({sessionId:K});await b.initialize(),await b.createSnapshot(Y,q)}catch(b){console.warn("[EditTool] 创建快照失败:",b)}if(Q===X)return{success:!1,llmContent:"New string is identical; no replacement needed",displayContent:"⚠️ 新字符串与旧字符串相同,无需进行替换",error:{type:"validation_error",message:"新旧字符串相同"}};let O=lO(F,Q);if(!O.matched){let b=rO(F,Q,Y);return{success:!1,llmContent:b.llmContent,displayContent:b.displayContent,error:{type:"execution_error",message:"未找到匹配内容",details:b.metadata}}}let z=O.matched;if(O.strategy!=="exact")console.log(`[SmartEdit] 使用策略: ${O.strategy}`);let _=iO(F,z);if(_.length>1&&!J){let b=F.split(`
1019
1019
  `),C=0,d=[];for(let T=0;T<b.length;T++){let g=b[T],j=C,M=C+g.length;for(let R of _)if(R>=j&&R<M){let n=Math.max(0,T-1),y=Math.min(b.length-1,T+1),s=b.slice(n,y+1).map((i)=>i.trim()).join(" ").slice(0,80);d.push({line:T+1,column:R-j+1,context:s})}C=M+1}let e=[`⚠️ EDIT PAUSED: old_string matches ${_.length} locations (must be unique).`,"","**Matches found at:**",...d.map((T,g)=>` ${g+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(`
1020
1020
  `),k=["⚠️ 编辑暂停:需要更精确的定位","",`在文件中找到 ${_.length} 处相似代码:`,...d.map((T,g)=>` • 第 ${T.line} 行 (匹配 ${g+1}/${_.length})`),"","AI 正在自动调整,添加更多上下文以精确定位...","通常需要 1-2 次尝试即可成功","","\uD83D\uDCA1 如果多次失败,可能需要:"," • 包含函数/类名等独特标识符"," • 添加目标代码前后 3-5 行完整上下文",` • 或使用 replace_all=true 同时替换所有 ${_.length} 处匹配`].join(`
1021
1021
  `);return{success:!1,llmContent:e,displayContent:k,error:{type:"validation_error",message:"old_string is not unique",details:{matches:d.map((T)=>({line:T.line,column:T.column})),count:_.length}}}}else G?.(`找到 ${_.length} 个匹配项,开始替换...`);let B,L;if(J)B=F.split(z).join(X),L=_.length;else{let b=F.indexOf(z);B=F.substring(0,b)+X+F.substring(b+z.length),L=1}if(W.throwIfAborted(),H)G?.("通过 IDE 写入文件...");if(await U.writeTextFile(Y,B),K)await e0.getInstance().recordFileEdit(Y,K,"edit");let w=await U.stat(Y),N=iX(F,B,z,X,4),D=gO(Y),V=L===1?`替换 1 处匹配到 ${D}`:`替换 ${L} 处匹配到 ${D}`,I={file_path:Y,matches_found:_.length,replacements_made:L,replace_all:J,old_string_length:Q.length,new_string_length:X.length,original_size:F.length,new_size:B.length,size_diff:B.length-F.length,last_modified:w?.mtime instanceof Date?w.mtime.toISOString():void 0,snapshot_created:!!(K&&q),session_id:K,message_id:q,diff_snippet:N,summary:V,kind:"edit",oldContent:F,newContent:B},v=aO(I,N);return{success:!0,llmContent:{file_path:Y,replacements:L,total_matches:_.length},displayContent:v,metadata:I}}catch(U){let H=U;if(H.name==="AbortError")return{success:!1,llmContent:"File edit aborted",displayContent:"⚠️ 文件编辑被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`File edit failed: ${H.message}`,displayContent:`❌ 编辑文件失败: ${H.message}`,error:{type:"execution_error",message:H.message,details:H}}}},version:"2.0.0",category:"文件操作",tags:["file","edit","replace","modify"],extractSignatureContent:($)=>$.file_path,abstractPermissionRule:($)=>{let Z=cO($.file_path);return Z?`**/*${Z}`:"**/*"}})});import{basename as sO,extname as YJ}from"path";import{z as tO}from"zod";function eO($){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 $z($){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 Zz($,Z){let Y=`✅ 成功读取文件: ${$}`;if(Z.file_size!==void 0&&typeof Z.file_size==="number")Y+=` (${Yz(Z.file_size)})`;if(Z.lines_read!==void 0)Y+=`
1022
1022
  \uD83D\uDCC4 读取了 ${Z.lines_read} 行 (第${Z.start_line}-${Z.end_line}行,共${Z.total_lines}行)`;if(Z.is_binary)Y+=`
1023
- \uD83D\uDD10 文件以 base64 编码显示`;return Y}function Yz($){let Z=["B","KB","MB","GB"],Y=$,Q=0;while(Y>=1024&&Q<Z.length-1)Y/=1024,Q++;return`${Y.toFixed(1)}${Z[Q]}`}var Z5;var QJ=A(()=>{r4();a4();p$();j0();V2();B9();Z5=t({name:"Read",displayName:"File Read",kind:"readonly",schema:tO.object({file_path:r$.filePath({description:"File path to read (must be absolute)"}),offset:r$.lineNumber({description:"Starting line number (0-based, text files only)"}).optional(),limit:r$.lineLimit({description:"Number of lines to read (text files only)"}).optional(),encoding:r$.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($,Z){let{file_path:Y,offset:Q,limit:X,encoding:J="utf8"}=$,{updateOutput:G,sessionId:K}=Z,q=Z.signal??new AbortController().signal;try{G?.("Starting file read...");let W=i4(),U=R2();try{if(!await W.exists(Y))throw Error("File not found")}catch(V){return{success:!1,llmContent:`File not found: ${Y}`,displayContent:`❌ 文件不存在: ${Y}`,error:{type:"execution_error",message:`File not found: ${Y}`}}}if(q.throwIfAborted(),K)await e0.getInstance().recordFileRead(Y,K);let H=await W.stat(Y);if(H?.isDirectory)return{success:!1,llmContent:`Cannot read a directory: ${Y}`,displayContent:`❌ 无法读取目录: ${Y}`,error:{type:"execution_error",message:"Target is a directory, not a file"}};let F=YJ(Y).toLowerCase(),O=eO(F),z=$z(F),_,B={file_path:Y,file_size:H?.size,file_type:F,last_modified:H?.mtime instanceof Date?H.mtime.toISOString():void 0,encoding:J,acp_mode:U};if(z&&J==="utf8"){if(U)G?.("⚠️ 二进制文件通过本地读取(ACP 不支持)..."),B.acp_fallback=!0;else G?.("检测到二进制文件,使用 base64 编码...");_=(await W.readBinaryFile(Y)).toString("base64"),B.encoding="base64",B.is_binary=!0}else if(O){if(U)G?.("通过 IDE 读取文件...");_=await W.readTextFile(Y)}else{if(U)B.acp_fallback=!0;let V=await W.readBinaryFile(Y);if(J==="base64")_=V.toString("base64");else if(J==="binary")_=V.toString("binary");else _=V.toString("utf8")}if(q.throwIfAborted(),(Q!==void 0||X!==void 0)&&J==="utf8"&&O){let V=_.split(`
1023
+ \uD83D\uDD10 文件以 base64 编码显示`;return Y}function Yz($){let Z=["B","KB","MB","GB"],Y=$,Q=0;while(Y>=1024&&Q<Z.length-1)Y/=1024,Q++;return`${Y.toFixed(1)}${Z[Q]}`}var Z5;var QJ=A(()=>{r2();a2();p$();j0();V4();B9();Z5=t({name:"Read",displayName:"File Read",kind:"readonly",schema:tO.object({file_path:r$.filePath({description:"File path to read (must be absolute)"}),offset:r$.lineNumber({description:"Starting line number (0-based, text files only)"}).optional(),limit:r$.lineLimit({description:"Number of lines to read (text files only)"}).optional(),encoding:r$.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($,Z){let{file_path:Y,offset:Q,limit:X,encoding:J="utf8"}=$,{updateOutput:G,sessionId:K}=Z,q=Z.signal??new AbortController().signal;try{G?.("Starting file read...");let W=i2(),U=R4();try{if(!await W.exists(Y))throw Error("File not found")}catch(V){return{success:!1,llmContent:`File not found: ${Y}`,displayContent:`❌ 文件不存在: ${Y}`,error:{type:"execution_error",message:`File not found: ${Y}`}}}if(q.throwIfAborted(),K)await e0.getInstance().recordFileRead(Y,K);let H=await W.stat(Y);if(H?.isDirectory)return{success:!1,llmContent:`Cannot read a directory: ${Y}`,displayContent:`❌ 无法读取目录: ${Y}`,error:{type:"execution_error",message:"Target is a directory, not a file"}};let F=YJ(Y).toLowerCase(),O=eO(F),z=$z(F),_,B={file_path:Y,file_size:H?.size,file_type:F,last_modified:H?.mtime instanceof Date?H.mtime.toISOString():void 0,encoding:J,acp_mode:U};if(z&&J==="utf8"){if(U)G?.("⚠️ 二进制文件通过本地读取(ACP 不支持)..."),B.acp_fallback=!0;else G?.("检测到二进制文件,使用 base64 编码...");_=(await W.readBinaryFile(Y)).toString("base64"),B.encoding="base64",B.is_binary=!0}else if(O){if(U)G?.("通过 IDE 读取文件...");_=await W.readTextFile(Y)}else{if(U)B.acp_fallback=!0;let V=await W.readBinaryFile(Y);if(J==="base64")_=V.toString("base64");else if(J==="binary")_=V.toString("binary");else _=V.toString("utf8")}if(q.throwIfAborted(),(Q!==void 0||X!==void 0)&&J==="utf8"&&O){let V=_.split(`
1024
1024
  `),I=Q||0,v=X!==void 0?I+X:V.length,b=V.slice(I,v);_=b.map((C,d)=>{let e=I+d+1,k=C.length>2000?`${C.substring(0,2000)}...`:C;return`${e.toString().padStart(6)}→${k}`}).join(`
1025
1025
  `),B.lines_read=b.length,B.total_lines=V.length,B.start_line=I+1,B.end_line=Math.min(v,V.length)}let L=sO(Y),w=B.lines_read||B.total_lines,N=w?`读取 ${w} 行从 ${L}`:`读取 ${L}`;B.summary=N;let D=Zz(Y,B);return{success:!0,llmContent:_,displayContent:D,metadata:B}}catch(W){let U=W;if(U.name==="AbortError")return{success:!1,llmContent:"File read aborted",displayContent:"⚠️ 文件读取被用户中止",error:{type:"execution_error",message:"Operation aborted"}};return{success:!1,llmContent:`File read failed: ${U.message}`,displayContent:`❌ 读取文件失败: ${U.message}`,error:{type:"execution_error",message:U.message,details:U}}}},version:"2.0.0",category:"文件操作",tags:["file","io","read"],extractSignatureContent:($)=>$.file_path,abstractPermissionRule:($)=>{let Z=YJ($.file_path);return Z?`**/*${Z}`:"**/*"}})});import{promises as Qz}from"fs";import{basename as Xz,dirname as Jz,extname as XJ}from"path";import{z as Y5}from"zod";function Gz($,Z,Y,Q){let X=`✅ 成功写入文件: ${$}`;if(Z.file_size!==void 0)X+=` (${JJ(Z.file_size)})`;if(Z.snapshot_created)X+=`
1026
1026
  \uD83D\uDCF8 已创建快照 (可回滚)`;if(Z.encoding!=="utf8")X+=`
@@ -1035,7 +1035,7 @@ ${C.message}
1035
1035
  `))U+=`
1036
1036
  `;if(U+="```",q)U+=`
1037
1037
 
1038
- ⚠️ 内容已截断(完整文件共 ${W.length} 行,${Z.length} 字符)`;return U}function JJ($){let Z=["B","KB","MB","GB"],Y=$,Q=0;while(Y>=1024&&Q<Z.length-1)Y/=1024,Q++;return`${Y.toFixed(1)}${Z[Q]}`}var Q5;var GJ=A(()=>{r4();a4();p$();j0();V2();s7();B9();e7();Q5=t({name:"Write",displayName:"File Write",kind:"write",strict:!0,isConcurrencySafe:!1,schema:Y5.object({file_path:r$.filePath({description:"Absolute file path to write"}),content:Y5.string().describe("Content to write"),encoding:r$.encoding(),create_directories:Y5.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($,Z){let{file_path:Y,content:Q,encoding:X,create_directories:J}=$,{updateOutput:G,sessionId:K,messageId:q}=Z,W=Z.signal??new AbortController().signal;try{G?.("开始写入文件...");let U=i4(),H=R2();if(J){let V=Jz(Y);try{await U.mkdir(V,{recursive:!0,mode:493})}catch(I){if(I.code!=="EEXIST")throw I}}W.throwIfAborted();let F=!1,O=null;try{if(F=await U.exists(Y),F&&X==="utf8")try{O=await U.readTextFile(Y)}catch(V){console.warn("[WriteTool] 读取旧文件内容失败:",V)}}catch{}if(F&&K){let V=e0.getInstance();if(!V.hasFileBeenRead(Y,K))return{success:!1,llmContent:"If this is an existing file, you MUST use the Read tool first to read the file's contents. This tool will fail if you did not read the file first.",displayContent:`❌ 写入失败:必须先使用 Read 工具读取文件
1038
+ ⚠️ 内容已截断(完整文件共 ${W.length} 行,${Z.length} 字符)`;return U}function JJ($){let Z=["B","KB","MB","GB"],Y=$,Q=0;while(Y>=1024&&Q<Z.length-1)Y/=1024,Q++;return`${Y.toFixed(1)}${Z[Q]}`}var Q5;var GJ=A(()=>{r2();a2();p$();j0();V4();s7();B9();e7();Q5=t({name:"Write",displayName:"File Write",kind:"write",strict:!0,isConcurrencySafe:!1,schema:Y5.object({file_path:r$.filePath({description:"Absolute file path to write"}),content:Y5.string().describe("Content to write"),encoding:r$.encoding(),create_directories:Y5.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($,Z){let{file_path:Y,content:Q,encoding:X,create_directories:J}=$,{updateOutput:G,sessionId:K,messageId:q}=Z,W=Z.signal??new AbortController().signal;try{G?.("开始写入文件...");let U=i2(),H=R4();if(J){let V=Jz(Y);try{await U.mkdir(V,{recursive:!0,mode:493})}catch(I){if(I.code!=="EEXIST")throw I}}W.throwIfAborted();let F=!1,O=null;try{if(F=await U.exists(Y),F&&X==="utf8")try{O=await U.readTextFile(Y)}catch(V){console.warn("[WriteTool] 读取旧文件内容失败:",V)}}catch{}if(F&&K){let V=e0.getInstance();if(!V.hasFileBeenRead(Y,K))return{success:!1,llmContent:"If this is an existing file, you MUST use the Read tool first to read the file's contents. This tool will fail if you did not read the file first.",displayContent:`❌ 写入失败:必须先使用 Read 工具读取文件
1039
1039
 
1040
1040
  文件 ${Y} 已存在,请先用 Read 工具查看其内容。`,error:{type:"validation_error",message:"File not read before write"}};let I=await V.checkExternalModification(Y);if(I.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.
1041
1041
 
@@ -1043,14 +1043,14 @@ Details: ${I.message}`,displayContent:`❌ 写入失败:文件已被外部程
1043
1043
 
1044
1044
  ${I.message}
1045
1045
 
1046
- \uD83D\uDCA1 请重新使用 Read 工具读取最新内容后再写入`,error:{type:"validation_error",message:"File modified externally",details:{externalModification:I.message}}}}let z=!1;if(F&&K&&q)try{let V=new J8({sessionId:K});await V.initialize(),await V.createSnapshot(Y,q),z=!0}catch(V){console.warn("[WriteTool] 创建快照失败:",V)}if(W.throwIfAborted(),X==="utf8"){if(H)G?.("通过 IDE 写入文件...");await U.writeTextFile(Y,Q)}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 模式不支持二进制文件写入
1046
+ \uD83D\uDCA1 请重新使用 Read 工具读取最新内容后再写入`,error:{type:"validation_error",message:"File modified externally",details:{externalModification:I.message}}}}let z=!1;if(F&&K&&q)try{let V=new J3({sessionId:K});await V.initialize(),await V.createSnapshot(Y,q),z=!0}catch(V){console.warn("[WriteTool] 创建快照失败:",V)}if(W.throwIfAborted(),X==="utf8"){if(H)G?.("通过 IDE 写入文件...");await U.writeTextFile(Y,Q)}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 模式不支持二进制文件写入
1047
1047
 
1048
1048
  当前通过 IDE 执行文件操作,但 IDE 仅支持文本文件。
1049
1049
 
1050
1050
  \uD83D\uDCA1 建议:
1051
1051
  • 如果是文本文件,使用 encoding='utf8'
1052
1052
  • 如果必须写入二进制文件,请在本地终端执行`,error:{type:"validation_error",message:"Binary writes not supported in ACP mode"}};let V;if(X==="base64")V=Buffer.from(Q,"base64");else if(X==="binary")V=Buffer.from(Q,"binary");else V=Buffer.from(Q,"utf8");await Qz.writeFile(Y,V)}if(K)await e0.getInstance().recordFileEdit(Y,K,"write");W.throwIfAborted();let _=await U.stat(Y),B=X==="utf8"?Q.split(`
1053
- `).length:0,L=Xz(Y),w=null;if(O&&X==="utf8"&&O!==Q){if(O.length<1048576&&Q.length<1048576)w=lX(O,Q,4)}let N={file_path:Y,content_size:Q.length,file_size:_?.size,encoding:X,created_directories:J,snapshot_created:z,session_id:K,message_id:q,last_modified:_?.mtime instanceof Date?_.mtime.toISOString():void 0,has_diff:!!w,summary:X==="utf8"?`写入 ${B} 行到 ${L}`:`写入 ${_?.size?JJ(_.size):"unknown"} 到 ${L}`,kind:"edit",oldContent:O||"",newContent:X==="utf8"?Q:void 0},D=Gz(Y,N,Q,w);return{success:!0,llmContent:{file_path:Y,size:_?.size,modified:_?.mtime instanceof Date?_.mtime.toISOString():void 0},displayContent:D,metadata:N}}catch(U){let H=U;if(H.name==="AbortError")return{success:!1,llmContent:"File write aborted",displayContent:"⚠️ 文件写入被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`File write failed: ${H.message}`,displayContent:`❌ 写入文件失败: ${H.message}`,error:{type:"execution_error",message:H.message,details:H}}}},version:"2.0.0",category:"文件操作",tags:["file","io","write","create"],extractSignatureContent:($)=>$.file_path,abstractPermissionRule:($)=>{let Z=XJ($.file_path);return Z?`**/*${Z}`:"**/*"}})});var KJ=A(()=>{ZJ();QJ();GJ()});import*as w9 from"fs/promises";import{z as o4}from"zod";var X5;var qJ=A(()=>{p$();w0();X5=t({name:"NotebookEdit",displayName:"Notebook Edit",kind:"write",schema:o4.object({notebook_path:o4.string().describe("The absolute path to the Jupyter notebook file to edit (must be absolute, not relative)"),cell_id:o4.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:o4.string().describe("The new source for the cell"),cell_type:o4.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:o4.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($,Z){let{notebook_path:Y,cell_id:Q,new_source:X,cell_type:J,edit_mode:G="replace"}=$;try{let K=await w9.readFile(Y,"utf-8"),q=JSON.parse(K);if(!q.cells||!Array.isArray(q.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(Q){if(W=q.cells.findIndex((H)=>H.id===Q),W===-1&&G!=="insert")return{success:!1,llmContent:`Cell with ID "${Q}" not found`,displayContent:"Cell not found",error:{type:"validation_error",message:`Cell ID "${Q}" not found`}}}switch(G){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=q.cells[W];if(H.source=X.split(`
1053
+ `).length:0,L=Xz(Y),w=null;if(O&&X==="utf8"&&O!==Q){if(O.length<1048576&&Q.length<1048576)w=lX(O,Q,4)}let N={file_path:Y,content_size:Q.length,file_size:_?.size,encoding:X,created_directories:J,snapshot_created:z,session_id:K,message_id:q,last_modified:_?.mtime instanceof Date?_.mtime.toISOString():void 0,has_diff:!!w,summary:X==="utf8"?`写入 ${B} 行到 ${L}`:`写入 ${_?.size?JJ(_.size):"unknown"} 到 ${L}`,kind:"edit",oldContent:O||"",newContent:X==="utf8"?Q:void 0},D=Gz(Y,N,Q,w);return{success:!0,llmContent:{file_path:Y,size:_?.size,modified:_?.mtime instanceof Date?_.mtime.toISOString():void 0},displayContent:D,metadata:N}}catch(U){let H=U;if(H.name==="AbortError")return{success:!1,llmContent:"File write aborted",displayContent:"⚠️ 文件写入被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`File write failed: ${H.message}`,displayContent:`❌ 写入文件失败: ${H.message}`,error:{type:"execution_error",message:H.message,details:H}}}},version:"2.0.0",category:"文件操作",tags:["file","io","write","create"],extractSignatureContent:($)=>$.file_path,abstractPermissionRule:($)=>{let Z=XJ($.file_path);return Z?`**/*${Z}`:"**/*"}})});var KJ=A(()=>{ZJ();QJ();GJ()});import*as w9 from"fs/promises";import{z as o2}from"zod";var X5;var qJ=A(()=>{p$();w0();X5=t({name:"NotebookEdit",displayName:"Notebook Edit",kind:"write",schema:o2.object({notebook_path:o2.string().describe("The absolute path to the Jupyter notebook file to edit (must be absolute, not relative)"),cell_id:o2.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:o2.string().describe("The new source for the cell"),cell_type:o2.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:o2.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($,Z){let{notebook_path:Y,cell_id:Q,new_source:X,cell_type:J,edit_mode:G="replace"}=$;try{let K=await w9.readFile(Y,"utf-8"),q=JSON.parse(K);if(!q.cells||!Array.isArray(q.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(Q){if(W=q.cells.findIndex((H)=>H.id===Q),W===-1&&G!=="insert")return{success:!1,llmContent:`Cell with ID "${Q}" not found`,displayContent:"Cell not found",error:{type:"validation_error",message:`Cell ID "${Q}" not found`}}}switch(G){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=q.cells[W];if(H.source=X.split(`
1054
1054
  `).map((F,O,z)=>O<z.length-1?F+`
1055
1055
  `:F),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:X.split(`
1056
1056
  `).map((O,z,_)=>z<_.length-1?O+`
@@ -1194,22 +1194,22 @@ please reject and ask for a proper plan.`,details:"After approval, the assistant
1194
1194
  `+(Q.feedback||"No specific feedback provided.")+`
1195
1195
 
1196
1196
  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:Q.feedback,awaitingUserInput:!0}}}catch(Q){return{success:!1,llmContent:`Confirmation flow error: ${Q instanceof Error?Q.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.
1197
- `+"Proceeding with implementation.",displayContent:"Plan mode exit (non-interactive)",metadata:{approved:null}}}})});var zJ=A(()=>{UJ();OJ()});import{existsSync as Uz,readFileSync as Hz}from"node:fs";import{readFile as Fz}from"node:fs/promises";import{dirname as Oz,join as BJ}from"node:path";import zz from"fast-glob";import{LRUCache as _z}from"lru-cache";import G8 from"picomatch";function Bz($){if(!Uz($))return{patterns:[],negatePatterns:[]};try{let Z=Hz($,"utf-8"),Y=[],Q=[];for(let X of Z.split(`
1198
- `)){let J=X.trim();if(!J||J.startsWith("#"))continue;if(J.startsWith("!"))Q.push(J.slice(1));else Y.push(J)}return{patterns:Y,negatePatterns:Q}}catch(Z){return console.warn(`Failed to read .gitignore: ${Z}`),{patterns:[],negatePatterns:[]}}}async function Lz($,Z){let Y=[...g1.map((q)=>`${q}/**`),...Z?.scanIgnore??[]],Q=`${$}|${Y.join(",")}`,X=_J.get(Q);if(X)return X;let J=await zz("**/.gitignore",{cwd:$,dot:!0,onlyFiles:!0,followSymbolicLinks:!1,unique:!0,ignore:Y});J.sort((q,W)=>Z8(q).length-Z8(W).length);let G=[];for(let q of J){let W=Oz(q).replace(/\\/g,"/"),U=W==="."?"":W,F=(await Fz(BJ($,q),"utf-8")).split(`
1199
- `);for(let O of F){let z=O.trim();if(!z||z.startsWith("#"))continue;let _=z.startsWith("!"),L=(_?z.slice(1):z).trim();if(!L)continue;let w="";if(L.startsWith("/")){let N=L.slice(1).replace(/\\/g,"/");if(w=(U?U+"/":"")+N,G.push({type:_?"negate":"ignore",pattern:w}),L.endsWith("/")){let D=w+"**";G.push({type:_?"negate":"ignore",pattern:D});let V=w.replace(/\/$/,"");if(V!==w)G.push({type:_?"negate":"ignore",pattern:V})}}else{let N=L.replace(/\\/g,"/");if(N.includes("/")){if(w=(U?U+"/":"")+N,G.push({type:_?"negate":"ignore",pattern:w}),N.endsWith("/")){let D=w+"**";G.push({type:_?"negate":"ignore",pattern:D});let V=w.replace(/\/$/,"");if(V!==w)G.push({type:_?"negate":"ignore",pattern:V})}}else w=(U?U+"/**/":"**/")+N,G.push({type:_?"negate":"ignore",pattern:w})}}}let K=Z?.cacheTTL??30000;return _J.set(Q,G,{ttl:K}),G}class N9{orderedRules=[];ignorePatterns=[];negatePatterns=[];constructor($={}){this.initialize($)}static async create($={}){let Z=new N9({...$,useGitignore:!1}),{cwd:Y=process.cwd(),useGitignore:Q=!0,gitignoreScanMode:X="root",customScanIgnore:J=[],cacheTTL:G}=$;if(Q&&X==="recursive"){let K=await Lz(Y,{scanIgnore:J,cacheTTL:G});for(let q of K)if(Z.orderedRules.push({type:q.type,matcher:G8(q.pattern,{dot:!0})}),q.type==="ignore")Z.ignorePatterns.push(q.pattern);else Z.negatePatterns.push(q.pattern)}return Z}initialize($){let{cwd:Z=process.cwd(),useGitignore:Y=!0,useDefaults:Q=!0,customPatterns:X=[]}=$,J=[],G=[];if(Q){let K=[...g1.map((q)=>`${q}/**`),...g1,...q5];J.push(...K);for(let q of K)this.orderedRules.push({type:"ignore",matcher:G8(q,{dot:!0})})}if(Y){let K=BJ(Z,".gitignore"),{patterns:q,negatePatterns:W}=Bz(K);for(let U of q)this.orderedRules.push({type:"ignore",matcher:G8(U,{dot:!0})}),J.push(U);for(let U of W)this.orderedRules.push({type:"negate",matcher:G8(U,{dot:!0})}),G.push(U)}J.push(...X);for(let K of X)this.orderedRules.push({type:"ignore",matcher:G8(K,{dot:!0})});this.ignorePatterns=J,this.negatePatterns=G}shouldIgnore($){let Z=$.replace(/\\/g,"/"),Y=void 0;for(let Q of this.orderedRules)if(Q.matcher(Z))Y=Q.type==="ignore";return Y===!0}shouldIgnoreDirectory($){let Z=$.replace(/\\/g,"/");return this.shouldIgnore(Z)||this.shouldIgnore(`${Z}/`)}filter($){return $.filter((Z)=>!this.shouldIgnore(Z))}getIgnorePatterns(){return this.ignorePatterns}getNegatePatterns(){return this.negatePatterns}}var g1,q5,_J;var b9=A(()=>{g1=["node_modules",".git","dist","build","out",".next",".nuxt",".cache",".parcel-cache","coverage",".nyc_output",".idea",".vscode",".vs","bower_components","jspm_packages"],q5=["*.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"];_J=new _z({max:100,ttl:30000,updateAgeOnGet:!0})});import wz from"fast-glob";import{stat as Nz}from"node:fs/promises";import{join as bz,resolve as Az}from"path";import{z as A9}from"zod";function W5($){let Z=Error($);return Z.name="AbortError",Z}async function Rz($,Z,Y,Q){let X=Q.getIgnorePatterns(),J=[],G=!1;return await new Promise((K,q)=>{if(Y.signal.aborted){q(W5("文件搜索被用户中止"));return}let W=wz.stream(Z,{cwd:$,dot:!0,followSymbolicLinks:!1,unique:!0,caseSensitiveMatch:Y.caseSensitive,objectMode:!0,stats:!0,onlyFiles:!Y.includeDirectories,ignore:X}),U=!1,H=null,F=()=>{if(H){if(Y.signal.removeEventListener)Y.signal.removeEventListener("abort",H);else if("onabort"in Y.signal)Y.signal.onabort=null;H=null}},O=()=>{if(!U)U=!0,G=!0,W.destroy(),F(),K({matches:J,wasTruncated:G})},z=(_)=>{if(Y.signal.aborted){if(!U)U=!0,W.destroy(W5("文件搜索被用户中止"));return}if(J.length>=Y.maxResults){O();return}let B=_.path.replace(/\\/g,"/"),L=bz($,B);if(Q.shouldIgnore(B))return;let w=_.stats?_.stats.isDirectory():!1;if(w&&Q.shouldIgnoreDirectory(B))return;let N=_.stats&&_.stats.isFile()?_.stats.size:void 0,D=_.stats?_.stats.mtime.toISOString():void 0;if(J.push({path:L,relative_path:B,is_directory:w,size:N,modified:D}),J.length>=Y.maxResults)O()};if(W.on("data",z),H=()=>{if(!U)U=!0,F(),W.destroy(W5("文件搜索被用户中止"))},Y.signal.addEventListener)Y.signal.addEventListener("abort",H);else if("onabort"in Y.signal)Y.signal.onabort=H;W.once("error",(_)=>{if(!U)U=!0,F(),q(_)}),W.once("end",()=>{if(!U)U=!0,F(),K({matches:J,wasTruncated:G})})})}function Vz($){return $.sort((Z,Y)=>{if(Z.is_directory!==Y.is_directory)return Z.is_directory?1:-1;if(Z.modified&&Y.modified)return new Date(Y.modified).getTime()-new Date(Z.modified).getTime();return Z.relative_path.localeCompare(Y.relative_path)})}function Dz($){let{search_path:Z,pattern:Y,total_matches:Q,returned_matches:X,truncated:J}=$,G;if(J)G=`✅ 在 ${Z} 中找到至少 ${Q} 个匹配 "${Y}" 的文件(已截断)`,G+=`
1200
- \uD83D\uDCCB 显示前 ${X} 个结果`;else G=`✅ 在 ${Z} 中找到 ${Q} 个匹配 "${Y}" 的文件`;return G}var U5;var LJ=A(()=>{b9();p$();j0();V2();U5=t({name:"Glob",displayName:"File Pattern Match",kind:"readonly",schema:A9.object({pattern:r$.glob({description:"Glob pattern string (supports *, ?, ** wildcards)"}),path:A9.string().optional().describe("Search path (optional, defaults to cwd)"),max_results:r$.positiveInt({description:"Maximum number of results"}).max(1000,"At most 1000 results can be returned").default(100),include_directories:A9.boolean().default(!1).describe("Include directories in results"),case_sensitive:A9.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($,Z){let{pattern:Y,path:Q=process.cwd(),max_results:X,include_directories:J,case_sensitive:G}=$,{updateOutput:K}=Z,q=Z.signal??new AbortController().signal;try{K?.(`Searching in ${Q} for pattern "${Y}"...`);let W=Az(Q);try{if(!(await Nz(W)).isDirectory())return{success:!1,llmContent:`Search path must be a directory: ${W}`,displayContent:`❌ 搜索路径必须是目录: ${W}`,error:{type:"validation_error",message:"搜索路径必须是目录"}}}catch(L){if(L.code==="ENOENT")return{success:!1,llmContent:`Search path does not exist: ${W}`,displayContent:`❌ 搜索路径不存在: ${W}`,error:{type:"execution_error",message:"搜索路径不存在"}};throw L}q.throwIfAborted();let U=await N9.create({cwd:W,useGitignore:!0,useDefaults:!0,gitignoreScanMode:"recursive",customScanIgnore:[],cacheTTL:30000}),{matches:H,wasTruncated:F}=await Rz(W,Y,{maxResults:X,includeDirectories:J,caseSensitive:G,signal:q},U),O=Vz(H),z={search_path:W,pattern:Y,total_matches:H.length,returned_matches:H.length,max_results:X,include_directories:J,case_sensitive:G,truncated:F},_=Dz(z),B;if(O.length>0)B=`${F?`Found at least ${O.length} file(s) matching "${Y}" (truncated)`:`Found ${O.length} file(s) matching "${Y}"`}:
1197
+ `+"Proceeding with implementation.",displayContent:"Plan mode exit (non-interactive)",metadata:{approved:null}}}})});var zJ=A(()=>{UJ();OJ()});import{existsSync as Uz,readFileSync as Hz}from"node:fs";import{readFile as Fz}from"node:fs/promises";import{dirname as Oz,join as BJ}from"node:path";import zz from"fast-glob";import{LRUCache as _z}from"lru-cache";import G3 from"picomatch";function Bz($){if(!Uz($))return{patterns:[],negatePatterns:[]};try{let Z=Hz($,"utf-8"),Y=[],Q=[];for(let X of Z.split(`
1198
+ `)){let J=X.trim();if(!J||J.startsWith("#"))continue;if(J.startsWith("!"))Q.push(J.slice(1));else Y.push(J)}return{patterns:Y,negatePatterns:Q}}catch(Z){return console.warn(`Failed to read .gitignore: ${Z}`),{patterns:[],negatePatterns:[]}}}async function Lz($,Z){let Y=[...g1.map((q)=>`${q}/**`),...Z?.scanIgnore??[]],Q=`${$}|${Y.join(",")}`,X=_J.get(Q);if(X)return X;let J=await zz("**/.gitignore",{cwd:$,dot:!0,onlyFiles:!0,followSymbolicLinks:!1,unique:!0,ignore:Y});J.sort((q,W)=>Z3(q).length-Z3(W).length);let G=[];for(let q of J){let W=Oz(q).replace(/\\/g,"/"),U=W==="."?"":W,F=(await Fz(BJ($,q),"utf-8")).split(`
1199
+ `);for(let O of F){let z=O.trim();if(!z||z.startsWith("#"))continue;let _=z.startsWith("!"),L=(_?z.slice(1):z).trim();if(!L)continue;let w="";if(L.startsWith("/")){let N=L.slice(1).replace(/\\/g,"/");if(w=(U?U+"/":"")+N,G.push({type:_?"negate":"ignore",pattern:w}),L.endsWith("/")){let D=w+"**";G.push({type:_?"negate":"ignore",pattern:D});let V=w.replace(/\/$/,"");if(V!==w)G.push({type:_?"negate":"ignore",pattern:V})}}else{let N=L.replace(/\\/g,"/");if(N.includes("/")){if(w=(U?U+"/":"")+N,G.push({type:_?"negate":"ignore",pattern:w}),N.endsWith("/")){let D=w+"**";G.push({type:_?"negate":"ignore",pattern:D});let V=w.replace(/\/$/,"");if(V!==w)G.push({type:_?"negate":"ignore",pattern:V})}}else w=(U?U+"/**/":"**/")+N,G.push({type:_?"negate":"ignore",pattern:w})}}}let K=Z?.cacheTTL??30000;return _J.set(Q,G,{ttl:K}),G}class N9{orderedRules=[];ignorePatterns=[];negatePatterns=[];constructor($={}){this.initialize($)}static async create($={}){let Z=new N9({...$,useGitignore:!1}),{cwd:Y=process.cwd(),useGitignore:Q=!0,gitignoreScanMode:X="root",customScanIgnore:J=[],cacheTTL:G}=$;if(Q&&X==="recursive"){let K=await Lz(Y,{scanIgnore:J,cacheTTL:G});for(let q of K)if(Z.orderedRules.push({type:q.type,matcher:G3(q.pattern,{dot:!0})}),q.type==="ignore")Z.ignorePatterns.push(q.pattern);else Z.negatePatterns.push(q.pattern)}return Z}initialize($){let{cwd:Z=process.cwd(),useGitignore:Y=!0,useDefaults:Q=!0,customPatterns:X=[]}=$,J=[],G=[];if(Q){let K=[...g1.map((q)=>`${q}/**`),...g1,...q5];J.push(...K);for(let q of K)this.orderedRules.push({type:"ignore",matcher:G3(q,{dot:!0})})}if(Y){let K=BJ(Z,".gitignore"),{patterns:q,negatePatterns:W}=Bz(K);for(let U of q)this.orderedRules.push({type:"ignore",matcher:G3(U,{dot:!0})}),J.push(U);for(let U of W)this.orderedRules.push({type:"negate",matcher:G3(U,{dot:!0})}),G.push(U)}J.push(...X);for(let K of X)this.orderedRules.push({type:"ignore",matcher:G3(K,{dot:!0})});this.ignorePatterns=J,this.negatePatterns=G}shouldIgnore($){let Z=$.replace(/\\/g,"/"),Y=void 0;for(let Q of this.orderedRules)if(Q.matcher(Z))Y=Q.type==="ignore";return Y===!0}shouldIgnoreDirectory($){let Z=$.replace(/\\/g,"/");return this.shouldIgnore(Z)||this.shouldIgnore(`${Z}/`)}filter($){return $.filter((Z)=>!this.shouldIgnore(Z))}getIgnorePatterns(){return this.ignorePatterns}getNegatePatterns(){return this.negatePatterns}}var g1,q5,_J;var b9=A(()=>{g1=["node_modules",".git","dist","build","out",".next",".nuxt",".cache",".parcel-cache","coverage",".nyc_output",".idea",".vscode",".vs","bower_components","jspm_packages"],q5=["*.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"];_J=new _z({max:100,ttl:30000,updateAgeOnGet:!0})});import wz from"fast-glob";import{stat as Nz}from"node:fs/promises";import{join as bz,resolve as Az}from"path";import{z as A9}from"zod";function W5($){let Z=Error($);return Z.name="AbortError",Z}async function Rz($,Z,Y,Q){let X=Q.getIgnorePatterns(),J=[],G=!1;return await new Promise((K,q)=>{if(Y.signal.aborted){q(W5("文件搜索被用户中止"));return}let W=wz.stream(Z,{cwd:$,dot:!0,followSymbolicLinks:!1,unique:!0,caseSensitiveMatch:Y.caseSensitive,objectMode:!0,stats:!0,onlyFiles:!Y.includeDirectories,ignore:X}),U=!1,H=null,F=()=>{if(H){if(Y.signal.removeEventListener)Y.signal.removeEventListener("abort",H);else if("onabort"in Y.signal)Y.signal.onabort=null;H=null}},O=()=>{if(!U)U=!0,G=!0,W.destroy(),F(),K({matches:J,wasTruncated:G})},z=(_)=>{if(Y.signal.aborted){if(!U)U=!0,W.destroy(W5("文件搜索被用户中止"));return}if(J.length>=Y.maxResults){O();return}let B=_.path.replace(/\\/g,"/"),L=bz($,B);if(Q.shouldIgnore(B))return;let w=_.stats?_.stats.isDirectory():!1;if(w&&Q.shouldIgnoreDirectory(B))return;let N=_.stats&&_.stats.isFile()?_.stats.size:void 0,D=_.stats?_.stats.mtime.toISOString():void 0;if(J.push({path:L,relative_path:B,is_directory:w,size:N,modified:D}),J.length>=Y.maxResults)O()};if(W.on("data",z),H=()=>{if(!U)U=!0,F(),W.destroy(W5("文件搜索被用户中止"))},Y.signal.addEventListener)Y.signal.addEventListener("abort",H);else if("onabort"in Y.signal)Y.signal.onabort=H;W.once("error",(_)=>{if(!U)U=!0,F(),q(_)}),W.once("end",()=>{if(!U)U=!0,F(),K({matches:J,wasTruncated:G})})})}function Vz($){return $.sort((Z,Y)=>{if(Z.is_directory!==Y.is_directory)return Z.is_directory?1:-1;if(Z.modified&&Y.modified)return new Date(Y.modified).getTime()-new Date(Z.modified).getTime();return Z.relative_path.localeCompare(Y.relative_path)})}function Dz($){let{search_path:Z,pattern:Y,total_matches:Q,returned_matches:X,truncated:J}=$,G;if(J)G=`✅ 在 ${Z} 中找到至少 ${Q} 个匹配 "${Y}" 的文件(已截断)`,G+=`
1200
+ \uD83D\uDCCB 显示前 ${X} 个结果`;else G=`✅ 在 ${Z} 中找到 ${Q} 个匹配 "${Y}" 的文件`;return G}var U5;var LJ=A(()=>{b9();p$();j0();V4();U5=t({name:"Glob",displayName:"File Pattern Match",kind:"readonly",schema:A9.object({pattern:r$.glob({description:"Glob pattern string (supports *, ?, ** wildcards)"}),path:A9.string().optional().describe("Search path (optional, defaults to cwd)"),max_results:r$.positiveInt({description:"Maximum number of results"}).max(1000,"At most 1000 results can be returned").default(100),include_directories:A9.boolean().default(!1).describe("Include directories in results"),case_sensitive:A9.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($,Z){let{pattern:Y,path:Q=process.cwd(),max_results:X,include_directories:J,case_sensitive:G}=$,{updateOutput:K}=Z,q=Z.signal??new AbortController().signal;try{K?.(`Searching in ${Q} for pattern "${Y}"...`);let W=Az(Q);try{if(!(await Nz(W)).isDirectory())return{success:!1,llmContent:`Search path must be a directory: ${W}`,displayContent:`❌ 搜索路径必须是目录: ${W}`,error:{type:"validation_error",message:"搜索路径必须是目录"}}}catch(L){if(L.code==="ENOENT")return{success:!1,llmContent:`Search path does not exist: ${W}`,displayContent:`❌ 搜索路径不存在: ${W}`,error:{type:"execution_error",message:"搜索路径不存在"}};throw L}q.throwIfAborted();let U=await N9.create({cwd:W,useGitignore:!0,useDefaults:!0,gitignoreScanMode:"recursive",customScanIgnore:[],cacheTTL:30000}),{matches:H,wasTruncated:F}=await Rz(W,Y,{maxResults:X,includeDirectories:J,caseSensitive:G,signal:q},U),O=Vz(H),z={search_path:W,pattern:Y,total_matches:H.length,returned_matches:H.length,max_results:X,include_directories:J,case_sensitive:G,truncated:F},_=Dz(z),B;if(O.length>0)B=`${F?`Found at least ${O.length} file(s) matching "${Y}" (truncated)`:`Found ${O.length} file(s) matching "${Y}"`}:
1201
1201
 
1202
1202
  `+O.map((w)=>`- ${w.relative_path}`).join(`
1203
1203
  `)+`
1204
1204
 
1205
- Use the relative_path values above for Read/Edit operations.`;else B=`No files found matching "${Y}"`;return{success:!0,llmContent:B,displayContent:_,metadata:{...z,matches:O}}}catch(W){let U=W;if(U.name==="AbortError")return{success:!1,llmContent:"File search aborted",displayContent:"⚠️ 文件搜索被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`Search failed: ${U.message}`,displayContent:`❌ 搜索失败: ${U.message}`,error:{type:"execution_error",message:U.message,details:U}}}},version:"2.0.0",category:"搜索工具",tags:["file","search","glob","pattern","wildcard"],extractSignatureContent:($)=>$.pattern,abstractPermissionRule:()=>"*"})});import{execSync as H5,spawn as F5}from"child_process";import{existsSync as R9}from"fs";import{readdir as Mz,readFile as jz}from"fs/promises";import{join as wJ,relative as Iz}from"path";import yz from"picomatch";import{z as D2}from"zod";function vz(){let{platform:$,arch:Z}=process,Y={"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"},Q=`${$}-${Z}`,X=Y[Q];if(!X)return null;let J=wJ(process.cwd(),"vendor","ripgrep",X);if(R9(J))return J;try{let G=new URL("../../../../vendor/ripgrep/"+X,import.meta.url).pathname;if(R9(G))return G}catch{}return null}function NJ(){try{let Z=process.platform==="win32"?"where rg":"command -v rg 2>/dev/null || which rg 2>/dev/null",Y=H5(Z,{encoding:"utf8",stdio:["pipe","pipe","ignore"]}).split(/\r?\n/)[0].trim();if(Y)return Y}catch{}let $=vz();if($&&R9($))return $;try{let Z=D0("@vscode/ripgrep");if(Z?.rgPath&&R9(Z.rgPath))return Z.rgPath}catch{}return null}async function Ez($){try{return H5("git rev-parse --git-dir",{cwd:$,stdio:"ignore"}),!0}catch{return!1}}function Pz(){try{return H5("grep --version",{stdio:"ignore"}),!0}catch{return!1}}async function Tz($,Z,Y,Q){let X=NJ();if(!X)throw Error("ripgrep not available");return new Promise((J,G)=>{let K=F5(X,$,{stdio:["pipe","pipe","pipe"]}),q="",W="";K.stdout.on("data",(H)=>{q+=H.toString()}),K.stderr.on("data",(H)=>{W+=H.toString()}),K.on("close",(H)=>{J({stdout:q,stderr:W,exitCode:H||0})}),K.on("error",(H)=>{G(H)});let U=()=>{K.kill("SIGTERM"),G(Error("搜索被用户中止"))};Y.addEventListener("abort",U),K.on("close",()=>{Y.removeEventListener("abort",U)})})}async function Cz($,Z,Y,Q){let X=["grep","-n"];if(Y.caseInsensitive)X.push("-i");if(Y.contextLines!==void 0)X.push(`-C${Y.contextLines}`);if(X.push("-e",$),Y.glob)X.push("--",Y.glob);return new Promise((J,G)=>{let K=F5("git",X,{cwd:Z,stdio:["pipe","pipe","pipe"]}),q="",W="";K.stdout.on("data",(H)=>{q+=H.toString()}),K.stderr.on("data",(H)=>{W+=H.toString()}),K.on("close",(H)=>{J({stdout:q,stderr:W,exitCode:H||0})}),K.on("error",(H)=>{G(H)});let U=()=>{K.kill("SIGTERM"),G(Error("搜索被用户中止"))};Q.addEventListener("abort",U),K.on("close",()=>{Q.removeEventListener("abort",U)})})}async function Sz($,Z,Y,Q){let X=["-rn"];if(Y.caseInsensitive)X.push("-i");if(Y.contextLines!==void 0)X.push(`-C${Y.contextLines}`);for(let J of g1)X.push("--exclude-dir="+J.replace(/^\./,""));return X.push("-e",$,Z),new Promise((J,G)=>{let K=F5("grep",X,{stdio:["pipe","pipe","pipe"]}),q="",W="";K.stdout.on("data",(H)=>{q+=H.toString()}),K.stderr.on("data",(H)=>{W+=H.toString()}),K.on("close",(H)=>{J({stdout:q,stderr:W,exitCode:H||0})}),K.on("error",(H)=>{G(H)});let U=()=>{K.kill("SIGTERM"),G(Error("搜索被用户中止"))};Q.addEventListener("abort",U),K.on("close",()=>{Q.removeEventListener("abort",U)})})}async function kz($,Z,Y,Q){let X=[],J=new RegExp($,Y.caseInsensitive?"gi":"g"),G=await fz(Z,Q),K=0;for(let q of G){if(Q.throwIfAborted(),bJ(q))continue;if(Y.glob&&!hz(q,Y.glob))continue;try{(await jz(q,"utf-8")).split(`
1205
+ Use the relative_path values above for Read/Edit operations.`;else B=`No files found matching "${Y}"`;return{success:!0,llmContent:B,displayContent:_,metadata:{...z,matches:O}}}catch(W){let U=W;if(U.name==="AbortError")return{success:!1,llmContent:"File search aborted",displayContent:"⚠️ 文件搜索被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`Search failed: ${U.message}`,displayContent:`❌ 搜索失败: ${U.message}`,error:{type:"execution_error",message:U.message,details:U}}}},version:"2.0.0",category:"搜索工具",tags:["file","search","glob","pattern","wildcard"],extractSignatureContent:($)=>$.pattern,abstractPermissionRule:()=>"*"})});import{execSync as H5,spawn as F5}from"child_process";import{existsSync as R9}from"fs";import{readdir as Mz,readFile as jz}from"fs/promises";import{join as wJ,relative as Iz}from"path";import yz from"picomatch";import{z as D4}from"zod";function vz(){let{platform:$,arch:Z}=process,Y={"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"},Q=`${$}-${Z}`,X=Y[Q];if(!X)return null;let J=wJ(process.cwd(),"vendor","ripgrep",X);if(R9(J))return J;try{let G=new URL("../../../../vendor/ripgrep/"+X,import.meta.url).pathname;if(R9(G))return G}catch{}return null}function NJ(){try{let Z=process.platform==="win32"?"where rg":"command -v rg 2>/dev/null || which rg 2>/dev/null",Y=H5(Z,{encoding:"utf8",stdio:["pipe","pipe","ignore"]}).split(/\r?\n/)[0].trim();if(Y)return Y}catch{}let $=vz();if($&&R9($))return $;try{let Z=D0("@vscode/ripgrep");if(Z?.rgPath&&R9(Z.rgPath))return Z.rgPath}catch{}return null}async function Ez($){try{return H5("git rev-parse --git-dir",{cwd:$,stdio:"ignore"}),!0}catch{return!1}}function Pz(){try{return H5("grep --version",{stdio:"ignore"}),!0}catch{return!1}}async function Tz($,Z,Y,Q){let X=NJ();if(!X)throw Error("ripgrep not available");return new Promise((J,G)=>{let K=F5(X,$,{stdio:["pipe","pipe","pipe"]}),q="",W="";K.stdout.on("data",(H)=>{q+=H.toString()}),K.stderr.on("data",(H)=>{W+=H.toString()}),K.on("close",(H)=>{J({stdout:q,stderr:W,exitCode:H||0})}),K.on("error",(H)=>{G(H)});let U=()=>{K.kill("SIGTERM"),G(Error("搜索被用户中止"))};Y.addEventListener("abort",U),K.on("close",()=>{Y.removeEventListener("abort",U)})})}async function Cz($,Z,Y,Q){let X=["grep","-n"];if(Y.caseInsensitive)X.push("-i");if(Y.contextLines!==void 0)X.push(`-C${Y.contextLines}`);if(X.push("-e",$),Y.glob)X.push("--",Y.glob);return new Promise((J,G)=>{let K=F5("git",X,{cwd:Z,stdio:["pipe","pipe","pipe"]}),q="",W="";K.stdout.on("data",(H)=>{q+=H.toString()}),K.stderr.on("data",(H)=>{W+=H.toString()}),K.on("close",(H)=>{J({stdout:q,stderr:W,exitCode:H||0})}),K.on("error",(H)=>{G(H)});let U=()=>{K.kill("SIGTERM"),G(Error("搜索被用户中止"))};Q.addEventListener("abort",U),K.on("close",()=>{Q.removeEventListener("abort",U)})})}async function Sz($,Z,Y,Q){let X=["-rn"];if(Y.caseInsensitive)X.push("-i");if(Y.contextLines!==void 0)X.push(`-C${Y.contextLines}`);for(let J of g1)X.push("--exclude-dir="+J.replace(/^\./,""));return X.push("-e",$,Z),new Promise((J,G)=>{let K=F5("grep",X,{stdio:["pipe","pipe","pipe"]}),q="",W="";K.stdout.on("data",(H)=>{q+=H.toString()}),K.stderr.on("data",(H)=>{W+=H.toString()}),K.on("close",(H)=>{J({stdout:q,stderr:W,exitCode:H||0})}),K.on("error",(H)=>{G(H)});let U=()=>{K.kill("SIGTERM"),G(Error("搜索被用户中止"))};Q.addEventListener("abort",U),K.on("close",()=>{Q.removeEventListener("abort",U)})})}async function kz($,Z,Y,Q){let X=[],J=new RegExp($,Y.caseInsensitive?"gi":"g"),G=await fz(Z,Q),K=0;for(let q of G){if(Q.throwIfAborted(),bJ(q))continue;if(Y.glob&&!hz(q,Y.glob))continue;try{(await jz(q,"utf-8")).split(`
1206
1206
  `).forEach((H,F)=>{if(J.test(H))X.push({file_path:Iz(Z,q),line_number:F+1,content:H})}),K++}catch(W){continue}}return{matches:X,totalFiles:K}}async function fz($,Z){let Y=[];async function Q(X){Z.throwIfAborted();try{let J=await Mz(X,{withFileTypes:!0});for(let G of J){Z.throwIfAborted();let K=wJ(X,G.name);if(G.isDirectory()){if(!bJ(K))await Q(K)}else if(G.isFile())Y.push(K)}}catch(J){}}return await Q($),Y}function bJ($){for(let Z of g1)if($.includes(Z))return!0;return!1}function hz($,Z){return yz(Z)($)}function xz($){let Z=[];if($.case_insensitive)Z.push("-i");if($.multiline)Z.push("-U","--multiline-dotall");switch($.output_mode){case"files_with_matches":Z.push("-l");break;case"count":Z.push("-c");break;case"content":if($.line_numbers)Z.push("-n");break}if($.context!==void 0&&$.output_mode==="content")Z.push("-C",$.context.toString());else{if($.context_before!==void 0&&$.output_mode==="content")Z.push("-B",$.context_before.toString());if($.context_after!==void 0&&$.output_mode==="content")Z.push("-A",$.context_after.toString())}if($.type)Z.push("--type",$.type);for(let Y of g1)Z.push("--glob",`!${Y}/**`);if($.glob)Z.push("--glob",$.glob);if($.head_limit!==void 0){let Y=($.offset??0)+$.head_limit;Z.push("-m",Y.toString())}return Z.push($.pattern),Z.push($.path),Z}function pz($,Z){if(!$.trim())return[];let Y=$.trim().split(`
1207
1207
  `),Q=[];switch(Z){case"files_with_matches":return Y.map((X)=>({file_path:X.trim()}));case"count":return Y.map((X)=>{let[J,G]=X.split(":");return{file_path:J,count:parseInt(G,10)}});case"content":for(let X of Y){let J=mz(X);if(J)Q.push(J)}return Q;default:return[]}}function mz($){let Z=$.indexOf(":");if(Z===-1)return null;let Y=$.substring(0,Z),Q=$.substring(Z+1),X=Q.indexOf(":");if(X!==-1&&/^\d+$/.test(Q.substring(0,X))){let J=parseInt(Q.substring(0,X),10),G=Q.substring(X+1);return{file_path:Y,line_number:J,content:G}}else return{file_path:Y,content:Q}}function dz($){let{search_pattern:Z,search_path:Y,output_mode:Q,total_matches:X,strategy:J}=$,G=`✅ 在 ${Y} 中搜索 "${Z}"`;if(J)G+=`
1208
1208
  \uD83D\uDD27 使用策略: ${J}`;switch(Q){case"files_with_matches":G+=`
1209
1209
  \uD83D\uDCC1 找到 ${X} 个包含匹配内容的文件`;break;case"count":G+=`
1210
1210
  \uD83D\uDD22 统计了 ${X} 个文件的匹配数量`;break;case"content":G+=`
1211
- \uD83D\uDCDD 找到 ${X} 个匹配行`;break}return G}var O5;var AJ=A(()=>{b9();p$();j0();V2();O5=t({name:"Grep",displayName:"内容搜索",kind:"readonly",schema:D2.object({pattern:r$.pattern({description:"The regular expression pattern to search for in file contents"}),path:D2.string().optional().describe("File or directory to search in (rg PATH). Defaults to current working directory"),glob:D2.string().optional().describe('Glob pattern to filter files (e.g. "*.js", "*.{ts,tsx}") - maps to rg --glob'),type:D2.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:D2.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":D2.boolean().optional().describe("Case insensitive search (rg -i)"),"-n":D2.boolean().default(!0).describe('Show line numbers in output (rg -n). Requires output_mode: "content", ignored otherwise. Defaults to true'),"-B":r$.nonNegativeInt().optional().describe('Number of lines to show before each match (rg -B). Requires output_mode: "content", ignored otherwise'),"-A":r$.nonNegativeInt().optional().describe('Number of lines to show after each match (rg -A). Requires output_mode: "content", ignored otherwise'),"-C":r$.nonNegativeInt().optional().describe('Number of lines to show before and after each match (rg -C). Requires output_mode: "content", ignored otherwise'),head_limit:r$.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:r$.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:D2.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($,Z){let{pattern:Y,path:Q=process.cwd(),glob:X,type:J,output_mode:G,"-i":K,"-n":q=!0,"-B":W,"-A":U,"-C":H,head_limit:F,offset:O,multiline:z}=$,{updateOutput:_}=Z,B=Z.signal??new AbortController().signal;try{_?.(`使用智能搜索策略查找模式 "${Y}"...`);let L=null,w="ripgrep",N=[],D=NJ();if(D)try{_?.(`\uD83D\uDE80 使用 ripgrep (${D})`);let b=xz({pattern:Y,path:Q,glob:X,type:J,output_mode:G,case_insensitive:K??!1,line_numbers:q,context_before:W,context_after:U,context:H,head_limit:F,offset:O,multiline:z??!1});L=await Tz(b,G,B,_),w="ripgrep"}catch{_?.("⚠️ ripgrep 失败,尝试降级策略..."),L=null}if(!L&&await Ez(Q))try{_?.("\uD83D\uDCE6 使用 git grep"),L=await Cz(Y,Q,{caseInsensitive:K??!1,glob:X,contextLines:H},B),w="git-grep"}catch{_?.("⚠️ git grep 失败,继续尝试其他策略..."),L=null}if(!L&&Pz())try{_?.("\uD83D\uDD27 使用系统 grep"),L=await Sz(Y,Q,{caseInsensitive:K??!1,contextLines:H},B),w="system-grep"}catch{_?.("⚠️ 系统 grep 失败,使用纯 JavaScript 实现..."),L=null}if(!L)_?.("\uD83D\uDCA1 使用纯 JavaScript 搜索实现"),N=(await kz(Y,Q,{caseInsensitive:K??!1,glob:X,multiline:z??!1},B)).matches,w="fallback",L={stdout:"",stderr:"",exitCode:0};else N=pz(L.stdout,G);let V=N.length;if(O!==void 0&&O>0)N=N.slice(O);if(F!==void 0&&N.length>F)N=N.slice(0,F);let I={search_pattern:Y,search_path:Q,output_mode:G,case_insensitive:K??!1,total_matches:N.length,original_total:V,offset:O,head_limit:F,strategy:w,exit_code:L?.exitCode};if(L&&L.exitCode!==0&&L.stderr)return{success:!1,llmContent:`Search execution failed: ${L.stderr}`,displayContent:`❌ 搜索执行失败: ${L.stderr}`,error:{type:"execution_error",message:L.stderr}};let v=dz(I);return{success:!0,llmContent:N,displayContent:v,metadata:I}}catch(L){let w=L;if(w.name==="AbortError")return{success:!1,llmContent:"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:"3.0.0",category:"搜索工具",tags:["search","grep","ripgrep","regex","text","fallback"],extractSignatureContent:($)=>$.pattern,abstractPermissionRule:()=>"*"})});var RJ=A(()=>{LJ();AJ()});import{spawn as uz}from"child_process";import{randomUUID as gz}from"crypto";class P0{static instance=null;processes=new Map;static getInstance(){if(!P0.instance)P0.instance=new P0;return P0.instance}startBackgroundProcess($){let Z=`bash_${gz()}`,Y={};for(let[J,G]of Object.entries({...process.env,...$.env,BLADE_CLI:"1"}))if(G!==void 0)Y[J]=G;let Q=uz("bash",["-c",$.command],{cwd:$.cwd||process.cwd(),env:Y,stdio:["ignore","pipe","pipe"]}),X={id:Z,command:$.command,sessionId:$.sessionId,cwd:$.cwd,env:$.env,process:Q,pid:Q.pid,status:"running",startTime:Date.now(),pendingStdout:"",pendingStderr:""};return Q.stdout?.setEncoding("utf8"),Q.stderr?.setEncoding("utf8"),Q.stdout?.on("data",(J)=>{X.pendingStdout+=J.toString()}),Q.stderr?.on("data",(J)=>{X.pendingStderr+=J.toString()}),Q.on("close",(J,G)=>{X.status=X.status==="killed"?"killed":"exited",X.exitCode=J,X.signal=G,X.endTime=Date.now(),X.process=void 0}),Q.on("error",(J)=>{X.status="error",X.errorMessage=J.message,X.endTime=Date.now(),X.process=void 0,X.pendingStderr+=`
1212
- [error] ${J.message}`}),this.processes.set(Z,X),X}consumeOutput($){let Z=this.processes.get($);if(!Z)return;let Y={id:Z.id,command:Z.command,status:Z.status,stdout:Z.pendingStdout,stderr:Z.pendingStderr,exitCode:Z.exitCode,signal:Z.signal,pid:Z.pid,startedAt:Z.startTime,endedAt:Z.endTime,errorMessage:Z.errorMessage};return Z.pendingStdout="",Z.pendingStderr="",Y}getProcess($){return this.processes.get($)}kill($){let Z=this.processes.get($);if(!Z)return;if(Z.status!=="running"||!Z.process)return{success:!1,alreadyExited:!0,status:Z.status,pid:Z.pid,exitCode:Z.exitCode,signal:Z.signal};if(!Z.process.kill("SIGTERM"))return{success:!1,alreadyExited:!1,status:Z.status,pid:Z.pid,exitCode:Z.exitCode,signal:Z.signal};return Z.status="killed",Z.endTime=Date.now(),Z.process=void 0,{success:!0,alreadyExited:!1,status:Z.status,pid:Z.pid,exitCode:Z.exitCode,signal:Z.signal}}killAll(){for(let[$,Z]of this.processes)if(Z.status==="running"&&Z.process)try{Z.process.kill("SIGTERM"),Z.status="killed",Z.endTime=Date.now(),Z.process=void 0}catch{}this.processes.clear()}}var s4=()=>{};class K8{static getConfigForCommand($){for(let{pattern:Z,config:Y,summaryTemplate:Q}of lz)if(Z.test($))return{config:Y,summaryTemplate:Q};return{config:cz}}static truncate($,Z){let{config:Y,summaryTemplate:Q}=this.getConfigForCommand(Z);return this.truncateWithConfig($,Y,Q)}static truncateWithConfig($,Z,Y){let Q=$.length,X=$.split(`
1211
+ \uD83D\uDCDD 找到 ${X} 个匹配行`;break}return G}var O5;var AJ=A(()=>{b9();p$();j0();V4();O5=t({name:"Grep",displayName:"内容搜索",kind:"readonly",schema:D4.object({pattern:r$.pattern({description:"The regular expression pattern to search for in file contents"}),path:D4.string().optional().describe("File or directory to search in (rg PATH). Defaults to current working directory"),glob:D4.string().optional().describe('Glob pattern to filter files (e.g. "*.js", "*.{ts,tsx}") - maps to rg --glob'),type:D4.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:D4.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":D4.boolean().optional().describe("Case insensitive search (rg -i)"),"-n":D4.boolean().default(!0).describe('Show line numbers in output (rg -n). Requires output_mode: "content", ignored otherwise. Defaults to true'),"-B":r$.nonNegativeInt().optional().describe('Number of lines to show before each match (rg -B). Requires output_mode: "content", ignored otherwise'),"-A":r$.nonNegativeInt().optional().describe('Number of lines to show after each match (rg -A). Requires output_mode: "content", ignored otherwise'),"-C":r$.nonNegativeInt().optional().describe('Number of lines to show before and after each match (rg -C). Requires output_mode: "content", ignored otherwise'),head_limit:r$.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:r$.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:D4.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($,Z){let{pattern:Y,path:Q=process.cwd(),glob:X,type:J,output_mode:G,"-i":K,"-n":q=!0,"-B":W,"-A":U,"-C":H,head_limit:F,offset:O,multiline:z}=$,{updateOutput:_}=Z,B=Z.signal??new AbortController().signal;try{_?.(`使用智能搜索策略查找模式 "${Y}"...`);let L=null,w="ripgrep",N=[],D=NJ();if(D)try{_?.(`\uD83D\uDE80 使用 ripgrep (${D})`);let b=xz({pattern:Y,path:Q,glob:X,type:J,output_mode:G,case_insensitive:K??!1,line_numbers:q,context_before:W,context_after:U,context:H,head_limit:F,offset:O,multiline:z??!1});L=await Tz(b,G,B,_),w="ripgrep"}catch{_?.("⚠️ ripgrep 失败,尝试降级策略..."),L=null}if(!L&&await Ez(Q))try{_?.("\uD83D\uDCE6 使用 git grep"),L=await Cz(Y,Q,{caseInsensitive:K??!1,glob:X,contextLines:H},B),w="git-grep"}catch{_?.("⚠️ git grep 失败,继续尝试其他策略..."),L=null}if(!L&&Pz())try{_?.("\uD83D\uDD27 使用系统 grep"),L=await Sz(Y,Q,{caseInsensitive:K??!1,contextLines:H},B),w="system-grep"}catch{_?.("⚠️ 系统 grep 失败,使用纯 JavaScript 实现..."),L=null}if(!L)_?.("\uD83D\uDCA1 使用纯 JavaScript 搜索实现"),N=(await kz(Y,Q,{caseInsensitive:K??!1,glob:X,multiline:z??!1},B)).matches,w="fallback",L={stdout:"",stderr:"",exitCode:0};else N=pz(L.stdout,G);let V=N.length;if(O!==void 0&&O>0)N=N.slice(O);if(F!==void 0&&N.length>F)N=N.slice(0,F);let I={search_pattern:Y,search_path:Q,output_mode:G,case_insensitive:K??!1,total_matches:N.length,original_total:V,offset:O,head_limit:F,strategy:w,exit_code:L?.exitCode};if(L&&L.exitCode!==0&&L.stderr)return{success:!1,llmContent:`Search execution failed: ${L.stderr}`,displayContent:`❌ 搜索执行失败: ${L.stderr}`,error:{type:"execution_error",message:L.stderr}};let v=dz(I);return{success:!0,llmContent:N,displayContent:v,metadata:I}}catch(L){let w=L;if(w.name==="AbortError")return{success:!1,llmContent:"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:"3.0.0",category:"搜索工具",tags:["search","grep","ripgrep","regex","text","fallback"],extractSignatureContent:($)=>$.pattern,abstractPermissionRule:()=>"*"})});var RJ=A(()=>{LJ();AJ()});import{spawn as uz}from"child_process";import{randomUUID as gz}from"crypto";class P0{static instance=null;processes=new Map;static getInstance(){if(!P0.instance)P0.instance=new P0;return P0.instance}startBackgroundProcess($){let Z=`bash_${gz()}`,Y={};for(let[J,G]of Object.entries({...process.env,...$.env,BLADE_CLI:"1"}))if(G!==void 0)Y[J]=G;let Q=uz("bash",["-c",$.command],{cwd:$.cwd||process.cwd(),env:Y,stdio:["ignore","pipe","pipe"]}),X={id:Z,command:$.command,sessionId:$.sessionId,cwd:$.cwd,env:$.env,process:Q,pid:Q.pid,status:"running",startTime:Date.now(),pendingStdout:"",pendingStderr:""};return Q.stdout?.setEncoding("utf8"),Q.stderr?.setEncoding("utf8"),Q.stdout?.on("data",(J)=>{X.pendingStdout+=J.toString()}),Q.stderr?.on("data",(J)=>{X.pendingStderr+=J.toString()}),Q.on("close",(J,G)=>{X.status=X.status==="killed"?"killed":"exited",X.exitCode=J,X.signal=G,X.endTime=Date.now(),X.process=void 0}),Q.on("error",(J)=>{X.status="error",X.errorMessage=J.message,X.endTime=Date.now(),X.process=void 0,X.pendingStderr+=`
1212
+ [error] ${J.message}`}),this.processes.set(Z,X),X}consumeOutput($){let Z=this.processes.get($);if(!Z)return;let Y={id:Z.id,command:Z.command,status:Z.status,stdout:Z.pendingStdout,stderr:Z.pendingStderr,exitCode:Z.exitCode,signal:Z.signal,pid:Z.pid,startedAt:Z.startTime,endedAt:Z.endTime,errorMessage:Z.errorMessage};return Z.pendingStdout="",Z.pendingStderr="",Y}getProcess($){return this.processes.get($)}kill($){let Z=this.processes.get($);if(!Z)return;if(Z.status!=="running"||!Z.process)return{success:!1,alreadyExited:!0,status:Z.status,pid:Z.pid,exitCode:Z.exitCode,signal:Z.signal};if(!Z.process.kill("SIGTERM"))return{success:!1,alreadyExited:!1,status:Z.status,pid:Z.pid,exitCode:Z.exitCode,signal:Z.signal};return Z.status="killed",Z.endTime=Date.now(),Z.process=void 0,{success:!0,alreadyExited:!1,status:Z.status,pid:Z.pid,exitCode:Z.exitCode,signal:Z.signal}}killAll(){for(let[$,Z]of this.processes)if(Z.status==="running"&&Z.process)try{Z.process.kill("SIGTERM"),Z.status="killed",Z.endTime=Date.now(),Z.process=void 0}catch{}this.processes.clear()}}var s2=()=>{};class K3{static getConfigForCommand($){for(let{pattern:Z,config:Y,summaryTemplate:Q}of lz)if(Z.test($))return{config:Y,summaryTemplate:Q};return{config:cz}}static truncate($,Z){let{config:Y,summaryTemplate:Q}=this.getConfigForCommand(Z);return this.truncateWithConfig($,Y,Q)}static truncateWithConfig($,Z,Y){let Q=$.length,X=$.split(`
1213
1213
  `),J=X.length;if(J<=Z.maxLines&&Q<=Z.maxChars)return{content:$,truncated:!1,originalLines:J,originalChars:Q};let G=X.slice(0,Z.keepHead),K=X.slice(-Z.keepTail),q=J-Z.keepHead-Z.keepTail,W=G.join(`
1214
1214
  `);if(W+=`
1215
1215
 
@@ -1226,25 +1226,25 @@ ${O}`}let U=Z.summarize&&Y?Y(J,Q):void 0;if(U)W+=`
1226
1226
  `).length} lines`);if(X.truncated)G.push(`stderr: ${X.originalLines} lines → ${X.content.split(`
1227
1227
  `).length} lines`);J=`Output truncated: ${G.join(", ")}`}return{stdout:Q.content,stderr:X.content,truncationInfo:J}}static shouldTruncate($,Z){let{config:Y}=this.getConfigForCommand(Z);return $.split(`
1228
1228
  `).length>Y.maxLines||$.length>Y.maxChars}static getStats($){return{lines:$.split(`
1229
- `).length,chars:$.length,words:$.split(/\s+/).filter(Boolean).length}}}var V9,K4,VJ,cz,lz;var z5=A(()=>{V9={maxLines:30,maxChars:3000,keepHead:10,keepTail:10,summarize:!0},K4={maxLines:100,maxChars:1e4,keepHead:40,keepTail:40,summarize:!0},VJ={maxLines:200,maxChars:20000,keepHead:80,keepTail:80,summarize:!1},cz={maxLines:150,maxChars:15000,keepHead:50,keepTail:50,summarize:!0},lz=[{pattern:/^git\s+(rm|add)\s+(-r|--cached|-rf|-f)?\s*/i,config:V9,summaryTemplate:($)=>`Successfully processed ${$} files`},{pattern:/^(npm|pnpm|yarn|bun)\s+(install|i|add|remove|uninstall)/i,config:V9,summaryTemplate:($)=>`Package operation completed (${$} lines of output)`},{pattern:/^(npm|pnpm|yarn|bun)\s+(run|exec)\s+(build|compile|bundle)/i,config:K4,summaryTemplate:($)=>`Build completed (${$} lines of output)`},{pattern:/^(npm|pnpm|yarn|bun)\s+(run|exec)\s+(test|lint|check)/i,config:VJ},{pattern:/^git\s+(status|branch|remote)/i,config:K4},{pattern:/^git\s+(log|diff|show)/i,config:VJ},{pattern:/^(ls|dir|tree)\s+/i,config:K4,summaryTemplate:($)=>`Listed ${$} items`},{pattern:/^find\s+/i,config:K4,summaryTemplate:($)=>`Found ${$} matches`},{pattern:/^(grep|rg|ag)\s+/i,config:K4,summaryTemplate:($)=>`Found ${$} matching lines`},{pattern:/^(docker|podman)\s+(build|pull|push)/i,config:V9,summaryTemplate:($)=>`Docker operation completed (${$} lines)`},{pattern:/^(pip|pip3|poetry|pipenv)\s+(install|uninstall)/i,config:V9,summaryTemplate:($)=>`Python package operation completed (${$} lines)`},{pattern:/^(cargo|rustup)\s+(build|install|update)/i,config:K4,summaryTemplate:($)=>`Rust operation completed (${$} lines)`},{pattern:/^(go)\s+(build|get|mod)/i,config:K4,summaryTemplate:($)=>`Go operation completed (${$} lines)`}]});import{spawn as iz}from"child_process";import{randomUUID as az}from"crypto";import{z as _5}from"zod";function rz($,Z,Y){let X=P0.getInstance().startBackgroundProcess({command:$,sessionId:az(),cwd:Z||process.cwd(),env:Y}),G=`后台启动命令: ${$.length>30?`${$.substring(0,30)}...`:$}`,K={command:$,background:!0,pid:X.pid??0,bash_id:X.id,shell_id:X.id,message:"命令已在后台启动",summary:G},q=`✅ 命令已在后台启动
1229
+ `).length,chars:$.length,words:$.split(/\s+/).filter(Boolean).length}}}var V9,K2,VJ,cz,lz;var z5=A(()=>{V9={maxLines:30,maxChars:3000,keepHead:10,keepTail:10,summarize:!0},K2={maxLines:100,maxChars:1e4,keepHead:40,keepTail:40,summarize:!0},VJ={maxLines:200,maxChars:20000,keepHead:80,keepTail:80,summarize:!1},cz={maxLines:150,maxChars:15000,keepHead:50,keepTail:50,summarize:!0},lz=[{pattern:/^git\s+(rm|add)\s+(-r|--cached|-rf|-f)?\s*/i,config:V9,summaryTemplate:($)=>`Successfully processed ${$} files`},{pattern:/^(npm|pnpm|yarn|bun)\s+(install|i|add|remove|uninstall)/i,config:V9,summaryTemplate:($)=>`Package operation completed (${$} lines of output)`},{pattern:/^(npm|pnpm|yarn|bun)\s+(run|exec)\s+(build|compile|bundle)/i,config:K2,summaryTemplate:($)=>`Build completed (${$} lines of output)`},{pattern:/^(npm|pnpm|yarn|bun)\s+(run|exec)\s+(test|lint|check)/i,config:VJ},{pattern:/^git\s+(status|branch|remote)/i,config:K2},{pattern:/^git\s+(log|diff|show)/i,config:VJ},{pattern:/^(ls|dir|tree)\s+/i,config:K2,summaryTemplate:($)=>`Listed ${$} items`},{pattern:/^find\s+/i,config:K2,summaryTemplate:($)=>`Found ${$} matches`},{pattern:/^(grep|rg|ag)\s+/i,config:K2,summaryTemplate:($)=>`Found ${$} matching lines`},{pattern:/^(docker|podman)\s+(build|pull|push)/i,config:V9,summaryTemplate:($)=>`Docker operation completed (${$} lines)`},{pattern:/^(pip|pip3|poetry|pipenv)\s+(install|uninstall)/i,config:V9,summaryTemplate:($)=>`Python package operation completed (${$} lines)`},{pattern:/^(cargo|rustup)\s+(build|install|update)/i,config:K2,summaryTemplate:($)=>`Rust operation completed (${$} lines)`},{pattern:/^(go)\s+(build|get|mod)/i,config:K2,summaryTemplate:($)=>`Go operation completed (${$} lines)`}]});import{spawn as iz}from"child_process";import{randomUUID as az}from"crypto";import{z as _5}from"zod";function rz($,Z,Y){let X=P0.getInstance().startBackgroundProcess({command:$,sessionId:az(),cwd:Z||process.cwd(),env:Y}),G=`后台启动命令: ${$.length>30?`${$.substring(0,30)}...`:$}`,K={command:$,background:!0,pid:X.pid??0,bash_id:X.id,shell_id:X.id,message:"命令已在后台启动",summary:G},q=`✅ 命令已在后台启动
1230
1230
  `+`\uD83C\uDD94 进程 ID: ${X.pid}
1231
1231
  `+`\uD83D\uDCA1 Bash ID: ${X.id}
1232
1232
  `+"⚠️ 使用 TaskOutput/KillShell 管理后台进程";return{success:!0,llmContent:{command:$,background:!0,pid:X.pid,bash_id:X.id,shell_id:X.id},displayContent:q,metadata:K}}async function nz($,Z,Y,Q,X,J){let G=Date.now();try{let q=await gX().execute($,{cwd:Z||process.cwd(),env:Y,timeout:Q,signal:X,onOutput:(_)=>{J?.(_)}}),W=Date.now()-G;if(X.aborted||q.error==="Command was aborted"||q.error==="Command was terminated")return{success:!1,llmContent:"Command execution aborted by user",displayContent:`⚠️ 命令执行被用户中止
1233
1233
  输出: ${q.stdout}
1234
1234
  错误: ${q.stderr}`,error:{type:"execution_error",message:"操作被中止"},metadata:{command:$,aborted:!0,stdout:q.stdout,stderr:q.stderr,execution_time:W}};if(q.error==="Command timed out")return{success:!1,llmContent:`Command execution timed out (${Q}ms)`,displayContent:`⏱️ 命令执行超时 (${Q}ms)
1235
1235
  输出: ${q.stdout}
1236
- 错误: ${q.stderr}`,error:{type:"timeout_error",message:"命令执行超时"},metadata:{command:$,timeout:!0,stdout:q.stdout,stderr:q.stderr,execution_time:W}};let U=$.length>30?`${$.substring(0,30)}...`:$,H=q.exitCode===0?`执行命令成功 (${W}ms): ${U}`:`执行命令完成 (退出码 ${q.exitCode}, ${W}ms): ${U}`,F={command:$,execution_time:W,exit_code:q.exitCode,stdout_length:q.stdout.length,stderr_length:q.stderr.length,has_stderr:q.stderr.length>0,acp_mode:!0,summary:H},O=DJ({stdout:q.stdout,stderr:q.stderr,command:$,execution_time:W,exit_code:q.exitCode,signal:null}),z=K8.truncateForLLM(q.stdout.trim(),q.stderr.trim(),$);return{success:q.success,llmContent:{stdout:z.stdout,stderr:z.stderr,execution_time:W,exit_code:q.exitCode,...z.truncationInfo&&{truncation_info:z.truncationInfo}},displayContent:O,metadata:F}}catch(K){let q=K,W=Date.now()-G;return{success:!1,llmContent:`Command execution failed: ${q.message}`,displayContent:`❌ 命令执行失败: ${q.message}`,error:{type:"execution_error",message:q.message,details:q},metadata:{command:$,execution_time:W,error:q.message}}}}async function oz($,Z,Y,Q,X,J){return new Promise((G)=>{let K=Date.now(),q="",W="",U=!1,H=iz("bash",["-c",$],{cwd:Z||process.cwd(),env:{...process.env,...Y,BLADE_CLI:"1"},stdio:["pipe","pipe","pipe"]});H.stdout.on("data",(z)=>{q+=z.toString()}),H.stderr.on("data",(z)=>{W+=z.toString()});let F=setTimeout(()=>{U=!0,H.kill("SIGTERM"),setTimeout(()=>{if(!H.killed)H.kill("SIGKILL")},1000)},Q),O=()=>{H.kill("SIGTERM"),clearTimeout(F)};if(X.addEventListener)X.addEventListener("abort",O);else if("onabort"in X)X.onabort=O;H.on("close",(z,_)=>{if(clearTimeout(F),X.removeEventListener)X.removeEventListener("abort",O);else if("onabort"in X)X.onabort=null;let B=Date.now()-K;if(U){G({success:!1,llmContent:`Command execution timed out (${Q}ms)`,displayContent:`⏱️ 命令执行超时 (${Q}ms)
1236
+ 错误: ${q.stderr}`,error:{type:"timeout_error",message:"命令执行超时"},metadata:{command:$,timeout:!0,stdout:q.stdout,stderr:q.stderr,execution_time:W}};let U=$.length>30?`${$.substring(0,30)}...`:$,H=q.exitCode===0?`执行命令成功 (${W}ms): ${U}`:`执行命令完成 (退出码 ${q.exitCode}, ${W}ms): ${U}`,F={command:$,execution_time:W,exit_code:q.exitCode,stdout_length:q.stdout.length,stderr_length:q.stderr.length,has_stderr:q.stderr.length>0,acp_mode:!0,summary:H},O=DJ({stdout:q.stdout,stderr:q.stderr,command:$,execution_time:W,exit_code:q.exitCode,signal:null}),z=K3.truncateForLLM(q.stdout.trim(),q.stderr.trim(),$);return{success:q.success,llmContent:{stdout:z.stdout,stderr:z.stderr,execution_time:W,exit_code:q.exitCode,...z.truncationInfo&&{truncation_info:z.truncationInfo}},displayContent:O,metadata:F}}catch(K){let q=K,W=Date.now()-G;return{success:!1,llmContent:`Command execution failed: ${q.message}`,displayContent:`❌ 命令执行失败: ${q.message}`,error:{type:"execution_error",message:q.message,details:q},metadata:{command:$,execution_time:W,error:q.message}}}}async function oz($,Z,Y,Q,X,J){return new Promise((G)=>{let K=Date.now(),q="",W="",U=!1,H=iz("bash",["-c",$],{cwd:Z||process.cwd(),env:{...process.env,...Y,BLADE_CLI:"1"},stdio:["pipe","pipe","pipe"]});H.stdout.on("data",(z)=>{q+=z.toString()}),H.stderr.on("data",(z)=>{W+=z.toString()});let F=setTimeout(()=>{U=!0,H.kill("SIGTERM"),setTimeout(()=>{if(!H.killed)H.kill("SIGKILL")},1000)},Q),O=()=>{H.kill("SIGTERM"),clearTimeout(F)};if(X.addEventListener)X.addEventListener("abort",O);else if("onabort"in X)X.onabort=O;H.on("close",(z,_)=>{if(clearTimeout(F),X.removeEventListener)X.removeEventListener("abort",O);else if("onabort"in X)X.onabort=null;let B=Date.now()-K;if(U){G({success:!1,llmContent:`Command execution timed out (${Q}ms)`,displayContent:`⏱️ 命令执行超时 (${Q}ms)
1237
1237
  输出: ${q}
1238
1238
  错误: ${W}`,error:{type:"timeout_error",message:"命令执行超时"},metadata:{command:$,timeout:!0,stdout:q,stderr:W,execution_time:B}});return}if(X.aborted){G({success:!1,llmContent:"Command execution aborted by user",displayContent:`⚠️ 命令执行被用户中止
1239
1239
  输出: ${q}
1240
- 错误: ${W}`,error:{type:"execution_error",message:"操作被中止"},metadata:{command:$,aborted:!0,stdout:q,stderr:W,execution_time:B}});return}let L=$.length>30?`${$.substring(0,30)}...`:$,w=z===0?`执行命令成功 (${B}ms): ${L}`:`执行命令完成 (退出码 ${z}, ${B}ms): ${L}`,N={command:$,execution_time:B,exit_code:z,signal:_,stdout_length:q.length,stderr_length:W.length,has_stderr:W.length>0,summary:w},D=DJ({stdout:q,stderr:W,command:$,execution_time:B,exit_code:z,signal:_}),V=K8.truncateForLLM(q.trim(),W.trim(),$);G({success:!0,llmContent:{stdout:V.stdout,stderr:V.stderr,execution_time:B,exit_code:z,signal:_,...V.truncationInfo&&{truncation_info:V.truncationInfo}},displayContent:D,metadata:N})}),H.on("error",(z)=>{if(clearTimeout(F),X.removeEventListener)X.removeEventListener("abort",O);else if("onabort"in X)X.onabort=null;G({success:!1,llmContent:`Command execution failed: ${z.message}`,displayContent:`❌ 命令执行失败: ${z.message}`,error:{type:"execution_error",message:z.message,details:z}})})})}function DJ($){let{stdout:Z,stderr:Y,command:Q,execution_time:X,exit_code:J,signal:G}=$,K=`✅ Bash 命令执行完成: ${Q}`;if(K+=`
1240
+ 错误: ${W}`,error:{type:"execution_error",message:"操作被中止"},metadata:{command:$,aborted:!0,stdout:q,stderr:W,execution_time:B}});return}let L=$.length>30?`${$.substring(0,30)}...`:$,w=z===0?`执行命令成功 (${B}ms): ${L}`:`执行命令完成 (退出码 ${z}, ${B}ms): ${L}`,N={command:$,execution_time:B,exit_code:z,signal:_,stdout_length:q.length,stderr_length:W.length,has_stderr:W.length>0,summary:w},D=DJ({stdout:q,stderr:W,command:$,execution_time:B,exit_code:z,signal:_}),V=K3.truncateForLLM(q.trim(),W.trim(),$);G({success:!0,llmContent:{stdout:V.stdout,stderr:V.stderr,execution_time:B,exit_code:z,signal:_,...V.truncationInfo&&{truncation_info:V.truncationInfo}},displayContent:D,metadata:N})}),H.on("error",(z)=>{if(clearTimeout(F),X.removeEventListener)X.removeEventListener("abort",O);else if("onabort"in X)X.onabort=null;G({success:!1,llmContent:`Command execution failed: ${z.message}`,displayContent:`❌ 命令执行失败: ${z.message}`,error:{type:"execution_error",message:z.message,details:z}})})})}function DJ($){let{stdout:Z,stderr:Y,command:Q,execution_time:X,exit_code:J,signal:G}=$,K=`✅ Bash 命令执行完成: ${Q}`;if(K+=`
1241
1241
  ⏱️ 执行时间: ${X}ms`,K+=`
1242
1242
  \uD83D\uDCCA 退出码: ${J??"N/A"}`,G)K+=`
1243
1243
  ⚡ 信号: ${G}`;if(Z&&Z.trim())K+=`
1244
1244
  \uD83D\uDCE4 输出:
1245
1245
  ${Z.trim()}`;if(Y&&Y.trim())K+=`
1246
1246
  ⚠️ 错误输出:
1247
- ${Y.trim()}`;return K}var B5;var MJ=A(()=>{r4();p$();j0();V2();s4();z5();B5=t({name:"Bash",displayName:"Bash Command",kind:"execute",schema:_5.object({command:r$.command({description:"Bash command to execute"}),timeout:r$.timeout(1000,300000,30000),cwd:_5.string().optional().describe("Working directory (optional; applies only to this command). To persist, use cd"),env:r$.environment(),run_in_background:_5.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.
1247
+ ${Y.trim()}`;return K}var B5;var MJ=A(()=>{r2();p$();j0();V4();s2();z5();B5=t({name:"Bash",displayName:"Bash Command",kind:"execute",schema:_5.object({command:r$.command({description:"Bash command to execute"}),timeout:r$.timeout(1000,300000,30000),cwd:_5.string().optional().describe("Working directory (optional; applies only to this command). To persist, use cd"),env:r$.environment(),run_in_background:_5.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.
1248
1248
 
1249
1249
  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.
1250
1250
 
@@ -1260,13 +1260,13 @@ Before executing commands:
1260
1260
  * cd "/Users/name/My Documents" (correct)
1261
1261
  * cd /Users/name/My Documents (incorrect - will fail)
1262
1262
  * python "/path/with spaces/script.py" (correct)
1263
- * 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 TaskOutput 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($,Z){let{command:Y,timeout:Q=30000,cwd:X,env:J,run_in_background:G=!1}=$,{updateOutput:K}=Z,q=Z.signal??new AbortController().signal;try{if(K?.(`Executing Bash command: ${Y}`),G)return rz(Y,X,J);if(R2())return K?.("通过 IDE 终端执行命令..."),nz(Y,X,J,Q,q,K);else return oz(Y,X,J,Q,q,K)}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 Y=$.command.trim().split(/\s+/);if(Y.length===1)return Y[0];if(["run","exec","test","start","build","dev"].includes(Y[1])){if(Y.length===2)return`${Y[0]} ${Y[1]}`;return`${Y[0]} ${Y[1]} *`}if(Y.length===2)return`${Y[0]} ${Y[1]}`;return`${Y[0]} ${Y[1]} *`}})});import{z as jJ}from"zod";var L5;var IJ=A(()=>{p$();j0();s4();L5=t({name:"KillShell",displayName:"终止后台 Shell",kind:"execute",schema:jJ.object({shell_id:jJ.string().min(1).describe("Background Shell ID to terminate")}),description:{short:"Kills a running background bash shell by its ID",long:`
1263
+ * 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 TaskOutput 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($,Z){let{command:Y,timeout:Q=30000,cwd:X,env:J,run_in_background:G=!1}=$,{updateOutput:K}=Z,q=Z.signal??new AbortController().signal;try{if(K?.(`Executing Bash command: ${Y}`),G)return rz(Y,X,J);if(R4())return K?.("通过 IDE 终端执行命令..."),nz(Y,X,J,Q,q,K);else return oz(Y,X,J,Q,q,K)}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 Y=$.command.trim().split(/\s+/);if(Y.length===1)return Y[0];if(["run","exec","test","start","build","dev"].includes(Y[1])){if(Y.length===2)return`${Y[0]} ${Y[1]}`;return`${Y[0]} ${Y[1]} *`}if(Y.length===2)return`${Y[0]} ${Y[1]}`;return`${Y[0]} ${Y[1]} *`}})});import{z as jJ}from"zod";var L5;var IJ=A(()=>{p$();j0();s2();L5=t({name:"KillShell",displayName:"终止后台 Shell",kind:"execute",schema:jJ.object({shell_id:jJ.string().min(1).describe("Background Shell ID to terminate")}),description:{short:"Kills a running background bash shell by its ID",long:`
1264
1264
  - Kills a running background bash shell by its ID
1265
1265
  - Takes a shell_id parameter identifying the shell to kill
1266
1266
  - Returns a success or failure status
1267
1267
  - Use this tool when you need to terminate a long-running shell
1268
1268
  - Shell IDs can be found using the /tasks command
1269
- `},async execute($,Z){let Q=P0.getInstance().kill($.shell_id);if(!Q)return{success:!1,llmContent:`Shell not found: ${$.shell_id}`,displayContent:`❌ 未找到 Shell: ${$.shell_id}`,error:{type:"execution_error",message:"Shell ID 不存在或已清理"}};if(!Q.success&&!Q.alreadyExited)return{success:!1,llmContent:`Failed to terminate Shell: ${$.shell_id}`,displayContent:`❌ 无法终止 Shell (${$.shell_id})`,error:{type:"execution_error",message:"发送终止信号失败"},metadata:{...Q}};let X=Q.alreadyExited?`Shell ${$.shell_id} 已经处于 ${Q.status} 状态`:`已向 Shell ${$.shell_id} 发送终止信号`;return{success:!0,llmContent:{shell_id:$.shell_id,status:Q.status,already_exited:Q.alreadyExited,pid:Q.pid,exit_code:Q.exitCode,signal:Q.signal},displayContent:Q.alreadyExited?`ℹ️ ${X}`:`✂️ ${X}`,metadata:{...Q}}},version:"1.0.0",category:"命令工具",tags:["bash","shell","terminate"],extractSignatureContent:($)=>$.shell_id,abstractPermissionRule:()=>"*"})});var yJ=A(()=>{MJ();IJ();z5()});import{z as M2}from"zod";var vJ;var EJ=A(()=>{O1();p$();w0();vJ=t({name:"AddTask",displayName:"Add Task",kind:"write",schema:M2.object({title:M2.string().min(1).describe("Brief title of the task"),description:M2.string().min(1).describe("Detailed description of what needs to be done"),complexity:M2.enum(["low","medium","high"]).optional().default("medium").describe("Estimated complexity of the task"),affectedFiles:M2.array(M2.string()).optional().default([]).describe("List of files that will be modified by this task"),dependencies:M2.array(M2.string()).optional().default([]).describe("IDs of tasks that must be completed before this one")}),description:{short:"Add a task to the current Spec project",long:`Use this tool to add tasks to the current Spec-Driven Development project.
1269
+ `},async execute($,Z){let Q=P0.getInstance().kill($.shell_id);if(!Q)return{success:!1,llmContent:`Shell not found: ${$.shell_id}`,displayContent:`❌ 未找到 Shell: ${$.shell_id}`,error:{type:"execution_error",message:"Shell ID 不存在或已清理"}};if(!Q.success&&!Q.alreadyExited)return{success:!1,llmContent:`Failed to terminate Shell: ${$.shell_id}`,displayContent:`❌ 无法终止 Shell (${$.shell_id})`,error:{type:"execution_error",message:"发送终止信号失败"},metadata:{...Q}};let X=Q.alreadyExited?`Shell ${$.shell_id} 已经处于 ${Q.status} 状态`:`已向 Shell ${$.shell_id} 发送终止信号`;return{success:!0,llmContent:{shell_id:$.shell_id,status:Q.status,already_exited:Q.alreadyExited,pid:Q.pid,exit_code:Q.exitCode,signal:Q.signal},displayContent:Q.alreadyExited?`ℹ️ ${X}`:`✂️ ${X}`,metadata:{...Q}}},version:"1.0.0",category:"命令工具",tags:["bash","shell","terminate"],extractSignatureContent:($)=>$.shell_id,abstractPermissionRule:()=>"*"})});var yJ=A(()=>{MJ();IJ();z5()});import{z as M4}from"zod";var vJ;var EJ=A(()=>{O1();p$();w0();vJ=t({name:"AddTask",displayName:"Add Task",kind:"write",schema:M4.object({title:M4.string().min(1).describe("Brief title of the task"),description:M4.string().min(1).describe("Detailed description of what needs to be done"),complexity:M4.enum(["low","medium","high"]).optional().default("medium").describe("Estimated complexity of the task"),affectedFiles:M4.array(M4.string()).optional().default([]).describe("List of files that will be modified by this task"),dependencies:M4.array(M4.string()).optional().default([]).describe("IDs of tasks that must be completed before this one")}),description:{short:"Add a task to the current Spec project",long:`Use this tool to add tasks to the current Spec-Driven Development project.
1270
1270
 
1271
1271
  ## Task Structure
1272
1272
 
@@ -1712,7 +1712,7 @@ ${Z}
1712
1712
 
1713
1713
  ---
1714
1714
 
1715
- Remember: Follow the above instructions carefully to complete the user's request.`}var V5;var oJ=A(()=>{Y2();p$();w0();V5=t({name:"Skill",displayName:"Skill",kind:"execute",schema:R5.object({skill:R5.string().describe('The skill name. E.g., "commit-message" or "code-review"'),args:R5.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
1715
+ Remember: Follow the above instructions carefully to complete the user's request.`}var V5;var oJ=A(()=>{Y4();p$();w0();V5=t({name:"Skill",displayName:"Skill",kind:"execute",schema:R5.object({skill:R5.string().describe('The skill name. E.g., "commit-message" or "code-review"'),args:R5.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
1716
1716
 
1717
1717
  <skills_instructions>
1718
1718
  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.
@@ -1733,7 +1733,7 @@ Important:
1733
1733
  </available_skills>
1734
1734
  `},async execute($,Z){let{skill:Y}=$,Q=R0();if(!Q.has(Y))return{success:!1,llmContent:`Skill "${Y}" not found. Available skills: ${Q.getAll().map((G)=>G.name).join(", ")||"none"}`,displayContent:`❌ Skill "${Y}" not found`,error:{type:"validation_error",message:`Skill "${Y}" is not registered`}};let X=await Q.loadContent(Y);if(!X)return{success:!1,llmContent:`Failed to load skill "${Y}" content`,displayContent:`❌ Failed to load skill "${Y}"`,error:{type:"execution_error",message:`Could not read SKILL.md for "${Y}"`}};return{success:!0,llmContent:Q_(X.metadata.name,X.instructions,X.metadata.basePath),displayContent:`<command-message>The "${Y}" skill is loading</command-message>`,metadata:{skillName:Y,basePath:X.metadata.basePath,version:X.metadata.version,allowedTools:X.metadata.allowedTools}}}})});import{execSync as X_}from"node:child_process";import sJ from"node:fs";import tJ from"node:path";class D5{async execute($,Z){let Y=$.content;if(Z.signal?.aborted)throw Error("Command execution aborted");return Y=this.interpolateArgs(Y,Z.args),Y=await this.executeBashEmbeds(Y,Z),Y=await this.resolveFileReferences(Y,Z.workspaceRoot),Y}interpolateArgs($,Z){$=$.replace(/\$ARGUMENTS/g,Z.join(" "));for(let Y=9;Y>=1;Y--){let Q=`$${Y}`,X=Z[Y-1]??"";$=$.split(Q).join(X)}return $}async executeBashEmbeds($,Z){let Y=/!`([^`]+)`/g,Q=[];for(let J of $.matchAll(Y))Q.push({match:J[0],command:J[1]});let X=$;for(let{match:J,command:G}of Q){if(Z.signal?.aborted){X=X.replace(J,"[Execution aborted]");continue}try{let K=X_(G,{cwd:Z.workspaceRoot,encoding:"utf-8",timeout:30000,maxBuffer:1048576,stdio:["pipe","pipe","pipe"]}).trim();X=X.replace(J,K)}catch(K){let q=K instanceof Error?K.message:String(K);X=X.replace(J,`[Error executing '${G}': ${q}]`)}}return X}async resolveFileReferences($,Z){let Y=/@([\w./-]+(?:\/[\w./-]+|\.[\w]+))/g,Q=[];for(let J of $.matchAll(Y))Q.push({match:J[0],relativePath:J[1]});let X=$;for(let{match:J,relativePath:G}of Q){let K=tJ.resolve(Z,G);try{if(sJ.statSync(K).isFile()){let W=sJ.readFileSync(K,"utf-8"),H=`\`\`\`${tJ.extname(G).slice(1)||"text"}
1735
1735
  ${W}
1736
- \`\`\``;X=X.replace(J,H)}}catch{}}return X}hasDynamicContent($){return{hasArgs:/\$ARGUMENTS|\$\d/.test($),hasBashEmbeds:/!`[^`]+`/.test($),hasFileRefs:/@[\w./-]+(?:\/[\w./-]+|\.[\w]+)/.test($)}}}var eJ=()=>{};import J_ from"node:fs";import $G from"node:path";import G_ from"gray-matter";class M5{parse($,Z,Y,Q){try{let X=J_.readFileSync($,"utf-8"),{data:J,content:G}=G_(X),{name:K,namespace:q}=this.extractNameAndNamespace($,Z);if(!K)return null;return{name:K,namespace:q,config:this.normalizeConfig(J),content:G.trim(),path:$,source:Y,sourceDir:Q}}catch(X){return console.error(`Failed to parse command file: ${$}`,X),null}}normalizeConfig($){return{description:this.asString($.description),allowedTools:this.parseAllowedTools($["allowed-tools"]),argumentHint:this.asString($["argument-hint"]),model:this.asString($.model),disableModelInvocation:$["disable-model-invocation"]===!0}}asString($){if(typeof $==="string"&&$.trim())return $.trim();return}parseAllowedTools($){if(!$)return;if(Array.isArray($))return $.map((Z)=>String(Z).trim()).filter(Boolean);if(typeof $==="string")return $.split(",").map((Z)=>Z.trim()).filter(Boolean);return}extractNameAndNamespace($,Z){let Q=$G.relative(Z,$).split($G.sep),X=Q.pop();if(!X)return{name:""};let J=X.replace(/\.md$/i,""),G=Q.length>0?Q.join("/"):void 0;return{name:J,namespace:G}}validateConfig($){let Z=[];if($.model&&!this.isValidModelId($.model))Z.push(`Invalid model ID: ${$.model}`);return Z}isValidModelId($){return $.length>0&&$.length<200}}var ZG=()=>{};import j5 from"node:fs";import YG from"node:os";import Q2 from"node:path";class I5{parser=new M5;async discover($){let Z=[],Y=[],Q=[],X=this.getSearchDirs($);for(let J of X){if(!j5.existsSync(J.path))continue;Y.push(J.path);try{let G=await this.scanDirectory(J.path);for(let K of G)try{let q=this.parser.parse(K,J.path,J.source,J.sourceDir);if(q)Z.push(q)}catch(q){Q.push({path:K,error:q instanceof Error?q.message:String(q)})}}catch(G){Q.push({path:J.path,error:G instanceof Error?G.message:String(G)})}}return{commands:Z,scannedDirs:Y,errors:Q}}getSearchDirs($){let Z=YG.homedir();return[{path:Q2.join(Z,".blade","commands"),source:"user",sourceDir:"blade"},{path:Q2.join(Z,".claude","commands"),source:"user",sourceDir:"claude"},{path:Q2.join($,".blade","commands"),source:"project",sourceDir:"blade"},{path:Q2.join($,".claude","commands"),source:"project",sourceDir:"claude"}]}async scanDirectory($){let Z=[],Y=async(Q)=>{let X=await j5.promises.readdir(Q,{withFileTypes:!0});for(let J of X){let G=Q2.join(Q,J.name);if(J.isDirectory())await Y(G);else if(J.isFile()&&J.name.endsWith(".md"))Z.push(G)}};return await Y($),Z}async hasCommands($){let Z=this.getSearchDirs($);for(let Y of Z){if(!j5.existsSync(Y.path))continue;if((await this.scanDirectory(Y.path)).length>0)return!0}return!1}getCommandDirs($){let Z=YG.homedir();return{projectBlade:Q2.join($,".blade","commands"),projectClaude:Q2.join($,".claude","commands"),userBlade:Q2.join(Z,".blade","commands"),userClaude:Q2.join(Z,".claude","commands")}}}var QG=A(()=>{ZG()});class B0{static instance;commands=new Map;pluginCommands=new Map;loader=new I5;executor=new D5;initialized=!1;workspaceRoot="";lastDiscoveryResult=null;static getInstance(){if(!B0.instance)B0.instance=new B0;return B0.instance}static resetInstance(){B0.instance=new B0}constructor(){}async initialize($){this.workspaceRoot=$;let Z=await this.loader.discover($);this.lastDiscoveryResult=Z,this.commands.clear();for(let Y of Z.commands)this.commands.set(Y.name,Y);return this.initialized=!0,Z}async refresh(){if(!this.workspaceRoot)throw Error("Registry not initialized. Call initialize() first.");return this.initialize(this.workspaceRoot)}isInitialized(){return this.initialized}getCommand($){return this.commands.get($)}hasCommand($){return this.commands.has($)}getAllCommands(){return Array.from(this.commands.values())}getCommandCount(){return this.commands.size}getModelInvocableCommands(){return this.getAllCommands().filter(($)=>$.config.description&&!$.config.disableModelInvocation)}async executeCommand($,Z){let Y=this.getCommand($);if(!Y)return null;return this.executor.execute(Y,Z)}getCommandLabel($){let Z=$.source==="project"?"project":"user";if($.namespace)return`(${Z}:${$.namespace})`;return`(${Z})`}getCommandDisplayName($){let Z=[`/${$.name}`];if($.config.argumentHint)Z.push($.config.argumentHint);if($.config.description)Z.push("-",$.config.description);return Z.push(this.getCommandLabel($)),Z.join(" ")}getCommandsBySource(){let $=[],Z=[];for(let Y of this.commands.values())if(Y.source==="project")$.push(Y);else Z.push(Y);return{project:$,user:Z}}getLastDiscoveryResult(){return this.lastDiscoveryResult}getCommandDirs(){if(!this.workspaceRoot)return null;return this.loader.getCommandDirs(this.workspaceRoot)}generateCommandListDescription($=15000){let Z=this.getModelInvocableCommands(),Y=Z.length;if(Y===0)return{text:"No custom commands available.",includedCount:0,totalCount:0};let Q=`Available custom commands:
1736
+ \`\`\``;X=X.replace(J,H)}}catch{}}return X}hasDynamicContent($){return{hasArgs:/\$ARGUMENTS|\$\d/.test($),hasBashEmbeds:/!`[^`]+`/.test($),hasFileRefs:/@[\w./-]+(?:\/[\w./-]+|\.[\w]+)/.test($)}}}var eJ=()=>{};import J_ from"node:fs";import $G from"node:path";import G_ from"gray-matter";class M5{parse($,Z,Y,Q){try{let X=J_.readFileSync($,"utf-8"),{data:J,content:G}=G_(X),{name:K,namespace:q}=this.extractNameAndNamespace($,Z);if(!K)return null;return{name:K,namespace:q,config:this.normalizeConfig(J),content:G.trim(),path:$,source:Y,sourceDir:Q}}catch(X){return console.error(`Failed to parse command file: ${$}`,X),null}}normalizeConfig($){return{description:this.asString($.description),allowedTools:this.parseAllowedTools($["allowed-tools"]),argumentHint:this.asString($["argument-hint"]),model:this.asString($.model),disableModelInvocation:$["disable-model-invocation"]===!0}}asString($){if(typeof $==="string"&&$.trim())return $.trim();return}parseAllowedTools($){if(!$)return;if(Array.isArray($))return $.map((Z)=>String(Z).trim()).filter(Boolean);if(typeof $==="string")return $.split(",").map((Z)=>Z.trim()).filter(Boolean);return}extractNameAndNamespace($,Z){let Q=$G.relative(Z,$).split($G.sep),X=Q.pop();if(!X)return{name:""};let J=X.replace(/\.md$/i,""),G=Q.length>0?Q.join("/"):void 0;return{name:J,namespace:G}}validateConfig($){let Z=[];if($.model&&!this.isValidModelId($.model))Z.push(`Invalid model ID: ${$.model}`);return Z}isValidModelId($){return $.length>0&&$.length<200}}var ZG=()=>{};import j5 from"node:fs";import YG from"node:os";import Q4 from"node:path";class I5{parser=new M5;async discover($){let Z=[],Y=[],Q=[],X=this.getSearchDirs($);for(let J of X){if(!j5.existsSync(J.path))continue;Y.push(J.path);try{let G=await this.scanDirectory(J.path);for(let K of G)try{let q=this.parser.parse(K,J.path,J.source,J.sourceDir);if(q)Z.push(q)}catch(q){Q.push({path:K,error:q instanceof Error?q.message:String(q)})}}catch(G){Q.push({path:J.path,error:G instanceof Error?G.message:String(G)})}}return{commands:Z,scannedDirs:Y,errors:Q}}getSearchDirs($){let Z=YG.homedir();return[{path:Q4.join(Z,".blade","commands"),source:"user",sourceDir:"blade"},{path:Q4.join(Z,".claude","commands"),source:"user",sourceDir:"claude"},{path:Q4.join($,".blade","commands"),source:"project",sourceDir:"blade"},{path:Q4.join($,".claude","commands"),source:"project",sourceDir:"claude"}]}async scanDirectory($){let Z=[],Y=async(Q)=>{let X=await j5.promises.readdir(Q,{withFileTypes:!0});for(let J of X){let G=Q4.join(Q,J.name);if(J.isDirectory())await Y(G);else if(J.isFile()&&J.name.endsWith(".md"))Z.push(G)}};return await Y($),Z}async hasCommands($){let Z=this.getSearchDirs($);for(let Y of Z){if(!j5.existsSync(Y.path))continue;if((await this.scanDirectory(Y.path)).length>0)return!0}return!1}getCommandDirs($){let Z=YG.homedir();return{projectBlade:Q4.join($,".blade","commands"),projectClaude:Q4.join($,".claude","commands"),userBlade:Q4.join(Z,".blade","commands"),userClaude:Q4.join(Z,".claude","commands")}}}var QG=A(()=>{ZG()});class B0{static instance;commands=new Map;pluginCommands=new Map;loader=new I5;executor=new D5;initialized=!1;workspaceRoot="";lastDiscoveryResult=null;static getInstance(){if(!B0.instance)B0.instance=new B0;return B0.instance}static resetInstance(){B0.instance=new B0}constructor(){}async initialize($){this.workspaceRoot=$;let Z=await this.loader.discover($);this.lastDiscoveryResult=Z,this.commands.clear();for(let Y of Z.commands)this.commands.set(Y.name,Y);return this.initialized=!0,Z}async refresh(){if(!this.workspaceRoot)throw Error("Registry not initialized. Call initialize() first.");return this.initialize(this.workspaceRoot)}isInitialized(){return this.initialized}getCommand($){return this.commands.get($)}hasCommand($){return this.commands.has($)}getAllCommands(){return Array.from(this.commands.values())}getCommandCount(){return this.commands.size}getModelInvocableCommands(){return this.getAllCommands().filter(($)=>$.config.description&&!$.config.disableModelInvocation)}async executeCommand($,Z){let Y=this.getCommand($);if(!Y)return null;return this.executor.execute(Y,Z)}getCommandLabel($){let Z=$.source==="project"?"project":"user";if($.namespace)return`(${Z}:${$.namespace})`;return`(${Z})`}getCommandDisplayName($){let Z=[`/${$.name}`];if($.config.argumentHint)Z.push($.config.argumentHint);if($.config.description)Z.push("-",$.config.description);return Z.push(this.getCommandLabel($)),Z.join(" ")}getCommandsBySource(){let $=[],Z=[];for(let Y of this.commands.values())if(Y.source==="project")$.push(Y);else Z.push(Y);return{project:$,user:Z}}getLastDiscoveryResult(){return this.lastDiscoveryResult}getCommandDirs(){if(!this.workspaceRoot)return null;return this.loader.getCommandDirs(this.workspaceRoot)}generateCommandListDescription($=15000){let Z=this.getModelInvocableCommands(),Y=Z.length;if(Y===0)return{text:"No custom commands available.",includedCount:0,totalCount:0};let Q=`Available custom commands:
1737
1737
 
1738
1738
  `,X=Q.length,J=0;for(let G of Z){let K=this.getCommandLabel(G),q=G.config.argumentHint?` ${G.config.argumentHint}`:"",W=`- /${G.name}${q}: ${G.config.description} ${K}
1739
1739
  `;if(X+W.length>$)break;Q+=W,X+=W.length,J++}if(J<Y)Q+=`
@@ -1781,7 +1781,7 @@ Notes:
1781
1781
  - Only custom slash commands with descriptions are listed in Available Commands
1782
1782
  - Commands with \`disable-model-invocation: true\` cannot be invoked by this tool
1783
1783
  - If a command is not listed, ask the user to check the slash command file
1784
- ${q_()}`},async execute($,Z){let{command:Y,arguments:Q}=$,X=B0.getInstance();if(!X.isInitialized())return{success:!1,llmContent:"Custom command system not initialized. Please wait for the application to fully initialize.",displayContent:"❌ Custom command system not initialized",error:{type:"execution_error",message:"CustomCommandRegistry not initialized"}};let J=X.getCommand(Y);if(!J){let K=X.getModelInvocableCommands().map((q)=>`/${q.name}`).join(", ");return{success:!1,llmContent:`Command "/${Y}" not found. Available commands: ${K||"none"}`,displayContent:`❌ Command "/${Y}" not found`,error:{type:"validation_error",message:`Command "/${Y}" is not registered`}}}if(J.config.disableModelInvocation)return{success:!1,llmContent:`Command "/${Y}" has disabled model invocation. This command can only be executed by the user directly.`,displayContent:`❌ Command "/${Y}" disabled for AI`,error:{type:"permission_denied",message:`Command "/${Y}" has disable-model-invocation: true`}};if(!J.config.description)return{success:!1,llmContent:`Command "/${Y}" does not have a description and cannot be invoked by AI. Add a description in the command's frontmatter to enable AI invocation.`,displayContent:`❌ Command "/${Y}" has no description`,error:{type:"validation_error",message:`Command "/${Y}" missing description for AI invocation`}};let G=Q?Q.split(/\s+/).filter(Boolean):[];try{let K=await X.executeCommand(Y,{args:G,workspaceRoot:process.cwd()});if(!K)return{success:!1,llmContent:`Failed to execute command "/${Y}"`,displayContent:`❌ Failed to execute "/${Y}"`,error:{type:"execution_error",message:"Command execution returned null"}};return{success:!0,llmContent:W_(J.name,K,J.config),displayContent:`<command-message>/${Y} is running...</command-message>`,metadata:{commandName:Y,allowedTools:J.config.allowedTools,model:J.config.model,source:J.source,namespace:J.namespace}}}catch(K){let q=K instanceof Error?K.message:String(K);return{success:!1,llmContent:`Error executing command "/${Y}": ${q}`,displayContent:`❌ Error executing "/${Y}"`,error:{type:"execution_error",message:q}}}}})});var JG=A(()=>{nJ();oJ();XG()});import j2 from"node:fs";import U_ from"node:os";import GG from"node:path";class q4{static instance=null;sessionsDir;cache=new Map;constructor(){this.sessionsDir=GG.join(U_.homedir(),".blade","agents","sessions"),this.ensureDirectory()}static getInstance(){if(!q4.instance)q4.instance=new q4;return q4.instance}ensureDirectory(){if(!j2.existsSync(this.sessionsDir))j2.mkdirSync(this.sessionsDir,{recursive:!0,mode:493})}getSessionPath($){let Z=$.replace(/[^a-zA-Z0-9_-]/g,"_");return GG.join(this.sessionsDir,`${Z}.json`)}saveSession($){try{let Z=this.getSessionPath($.id),Y=JSON.stringify($,null,2);j2.writeFileSync(Z,Y,"utf-8"),this.cache.set($.id,$),t4.debug(`Session saved: ${$.id}`)}catch(Z){t4.warn(`Failed to save session ${$.id}:`,Z)}}loadSession($){if(this.cache.has($))return this.cache.get($);try{let Z=this.getSessionPath($);if(!j2.existsSync(Z))return;let Y=j2.readFileSync(Z,"utf-8"),Q=JSON.parse(Y);return this.cache.set($,Q),Q}catch(Z){t4.warn(`Failed to load session ${$}:`,Z);return}}updateSession($,Z){let Y=this.loadSession($);if(!Y)return;let Q={...Y,...Z,lastActiveAt:Date.now()};return this.saveSession(Q),Q}appendMessages($,Z){let Y=this.loadSession($);if(!Y)return;return this.updateSession($,{messages:[...Y.messages,...Z]})}markCompleted($,Z,Y){return this.updateSession($,{status:Z.success?"completed":"failed",result:Z,stats:Y,completedAt:Date.now()})}deleteSession($){try{let Z=this.getSessionPath($);if(j2.existsSync(Z))j2.unlinkSync(Z);return this.cache.delete($),!0}catch(Z){return t4.warn(`Failed to delete session ${$}:`,Z),!1}}listSessions(){try{let $=j2.readdirSync(this.sessionsDir),Z=[];for(let Y of $){if(!Y.endsWith(".json"))continue;let Q=Y.replace(".json",""),X=this.loadSession(Q);if(X)Z.push(X)}return Z.sort((Y,Q)=>Q.lastActiveAt-Y.lastActiveAt)}catch($){return t4.warn("Failed to list sessions:",$),[]}}listRunningSessions(){return this.listSessions().filter(($)=>$.status==="running")}cleanupExpiredSessions($=604800000){let Z=Date.now(),Y=this.listSessions(),Q=0;for(let X of Y){if(X.status==="running")continue;if(Z-X.lastActiveAt>$){if(this.deleteSession(X.id))Q++}}if(Q>0)t4.info(`Cleaned up ${Q} expired agent sessions`);return Q}clearCache(){this.cache.clear()}}var t4;var KG=A(()=>{O$();t4=l("Agent")});import{randomUUID as H_}from"crypto";class Q1{static instance=null;runningAgents=new Map;sessionStore=q4.getInstance();constructor(){this.cleanupOrphanedSessions()}static getInstance(){if(!Q1.instance)Q1.instance=new Q1;return Q1.instance}cleanupOrphanedSessions(){let $=this.sessionStore.listSessions(),Z=Date.now(),Y=1800000;for(let Q of $)if(Q.status==="running"){let X=this.runningAgents.has(Q.id),J=Z-Q.lastActiveAt;if(!X||J>1800000)W4.warn(`Cleaning up orphaned agent session: ${Q.id}`),this.sessionStore.updateSession(Q.id,{status:"failed",result:{success:!1,message:"",error:"Session was orphaned (process restart or timeout)"},completedAt:Z})}}startBackgroundAgent($){let{config:Z,description:Y,prompt:Q,parentSessionId:X,permissionMode:J,agentId:G,existingMessages:K}=$,q=G||`agent_${H_()}`,W=new AbortController,U={id:q,subagentType:Z.name,description:Y,prompt:Q,messages:K||[],status:"running",createdAt:Date.now(),lastActiveAt:Date.now(),parentSessionId:X};this.sessionStore.saveSession(U);let H=Date.now(),F=this.executeAgent(q,Z,Q,X,J,W.signal,K);return this.runningAgents.set(q,{id:q,promise:F,abortController:W,startTime:H}),F.finally(()=>{this.runningAgents.delete(q)}),W4.info(`Background agent started: ${q} (${Z.name})`),q}async executeAgent($,Z,Y,Q,X,J,G){let K=Date.now();try{if(J.aborted)throw Error("Agent execution was cancelled");let q=Z.systemPrompt||"",W=await O0.create({systemPrompt:q,toolWhitelist:Z.tools}),U={messages:G||[],userId:"subagent",sessionId:Q||`subagent_${$}`,workspaceRoot:process.cwd(),permissionMode:X},H=await W.runAgenticLoop(Y,U,{signal:J});this.sessionStore.updateSession($,{messages:U.messages});let F=Date.now()-K,O=H.success?{success:!0,message:H.finalMessage||"",stats:{tokens:H.metadata?.tokensUsed||0,toolCalls:H.metadata?.toolCallsCount||0,duration:F}}:{success:!1,message:"",error:H.error?.message||"Unknown error",stats:{duration:F}};return this.sessionStore.markCompleted($,{success:O.success,message:O.message,error:O.error},O.stats),W4.info(`Background agent completed: ${$} (success=${O.success})`),O}catch(q){let W=Date.now()-K,U=q instanceof Error?q.message:String(q);return this.sessionStore.markCompleted($,{success:!1,message:"",error:U},{duration:W}),W4.warn(`Background agent failed: ${$}`,q),{success:!1,message:"",error:U,stats:{duration:W}}}}getAgent($){return this.sessionStore.loadSession($)}isRunning($){return this.runningAgents.has($)}async waitForCompletion($,Z=30000){let Y=this.runningAgents.get($);if(!Y)return this.sessionStore.loadSession($);if(Z>0){let Q=new Promise((J)=>setTimeout(()=>J("timeout"),Z));if(await Promise.race([Y.promise,Q])==="timeout")return this.sessionStore.loadSession($)}else await Y.promise;return this.sessionStore.loadSession($)}resumeAgent($,Z,Y,Q,X){let J=this.sessionStore.loadSession($);if(!J){W4.warn(`Cannot resume agent ${$}: session not found`);return}if(this.isRunning($)){W4.warn(`Cannot resume agent ${$}: still running`);return}return this.startBackgroundAgent({config:Y,description:J.description,prompt:Z,parentSessionId:Q||J.parentSessionId,permissionMode:X,agentId:$,existingMessages:J.messages})}killAgent($){let Z=this.runningAgents.get($);if(!Z){let Y=this.sessionStore.loadSession($);if(Y&&Y.status==="running")this.sessionStore.updateSession($,{status:"cancelled"});return!1}return Z.abortController.abort(),this.sessionStore.updateSession($,{status:"cancelled"}),W4.info(`Background agent cancelled: ${$}`),!0}listAll(){return this.sessionStore.listSessions()}listRunning(){return this.sessionStore.listRunningSessions()}getRunningCount(){return this.runningAgents.size}killAll(){for(let[$]of this.runningAgents)this.killAgent($)}cleanupExpiredSessions($){return this.sessionStore.cleanupExpiredSessions($)}}var W4;var I9=A(()=>{O$();X2();KG();W4=l("Agent")});class P5{config;constructor($){this.config=$}async execute($){let Z=Date.now();try{let Y=this.buildSystemPrompt($),Q=await O0.create({systemPrompt:Y,toolWhitelist:this.config.tools}),X=[{role:"user",content:$.prompt}],J="",G=0,K=0,q=await Q.runAgenticLoop($.prompt,{messages:[],userId:"subagent",sessionId:$.parentSessionId||`subagent_${Date.now()}`,workspaceRoot:process.cwd(),permissionMode:$.permissionMode});if(q.success)J=q.finalMessage||"",G=q.metadata?.toolCallsCount||0,K=q.metadata?.tokensUsed||0;else throw Error(q.error?.message||"Subagent execution failed");let W=Date.now()-Z;return{success:!0,message:J,stats:{tokens:K,toolCalls:G,duration:W}}}catch(Y){let Q=Date.now()-Z;return{success:!1,message:"",error:Y instanceof Error?Y.message:String(Y),stats:{duration:Q}}}}buildSystemPrompt($){return this.config.systemPrompt||""}}var qG=A(()=>{X2()});var T5;var WG=A(()=>{T5=[{name:"general-purpose",description:"General-purpose agent for researching complex questions, searching for code, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries use this agent to perform the search for you.",tools:[]},{name:"Explore",description:'Fast agent specialized for exploring codebases. Use this when you need to quickly find files by patterns (eg. "src/components/**/*.tsx"), search code for keywords (eg. "API endpoints"), or answer questions about the codebase (eg. "how do API endpoints work?"). When calling this agent, specify the desired thoroughness level: "quick" for basic searches, "medium" for moderate exploration, or "very thorough" for comprehensive analysis across multiple locations and naming conventions.',tools:["Glob","Grep","Read","WebFetch","WebSearch"],systemPrompt:`# Explore Subagent
1784
+ ${q_()}`},async execute($,Z){let{command:Y,arguments:Q}=$,X=B0.getInstance();if(!X.isInitialized())return{success:!1,llmContent:"Custom command system not initialized. Please wait for the application to fully initialize.",displayContent:"❌ Custom command system not initialized",error:{type:"execution_error",message:"CustomCommandRegistry not initialized"}};let J=X.getCommand(Y);if(!J){let K=X.getModelInvocableCommands().map((q)=>`/${q.name}`).join(", ");return{success:!1,llmContent:`Command "/${Y}" not found. Available commands: ${K||"none"}`,displayContent:`❌ Command "/${Y}" not found`,error:{type:"validation_error",message:`Command "/${Y}" is not registered`}}}if(J.config.disableModelInvocation)return{success:!1,llmContent:`Command "/${Y}" has disabled model invocation. This command can only be executed by the user directly.`,displayContent:`❌ Command "/${Y}" disabled for AI`,error:{type:"permission_denied",message:`Command "/${Y}" has disable-model-invocation: true`}};if(!J.config.description)return{success:!1,llmContent:`Command "/${Y}" does not have a description and cannot be invoked by AI. Add a description in the command's frontmatter to enable AI invocation.`,displayContent:`❌ Command "/${Y}" has no description`,error:{type:"validation_error",message:`Command "/${Y}" missing description for AI invocation`}};let G=Q?Q.split(/\s+/).filter(Boolean):[];try{let K=await X.executeCommand(Y,{args:G,workspaceRoot:process.cwd()});if(!K)return{success:!1,llmContent:`Failed to execute command "/${Y}"`,displayContent:`❌ Failed to execute "/${Y}"`,error:{type:"execution_error",message:"Command execution returned null"}};return{success:!0,llmContent:W_(J.name,K,J.config),displayContent:`<command-message>/${Y} is running...</command-message>`,metadata:{commandName:Y,allowedTools:J.config.allowedTools,model:J.config.model,source:J.source,namespace:J.namespace}}}catch(K){let q=K instanceof Error?K.message:String(K);return{success:!1,llmContent:`Error executing command "/${Y}": ${q}`,displayContent:`❌ Error executing "/${Y}"`,error:{type:"execution_error",message:q}}}}})});var JG=A(()=>{nJ();oJ();XG()});import j4 from"node:fs";import U_ from"node:os";import GG from"node:path";class q2{static instance=null;sessionsDir;cache=new Map;constructor(){this.sessionsDir=GG.join(U_.homedir(),".blade","agents","sessions"),this.ensureDirectory()}static getInstance(){if(!q2.instance)q2.instance=new q2;return q2.instance}ensureDirectory(){if(!j4.existsSync(this.sessionsDir))j4.mkdirSync(this.sessionsDir,{recursive:!0,mode:493})}getSessionPath($){let Z=$.replace(/[^a-zA-Z0-9_-]/g,"_");return GG.join(this.sessionsDir,`${Z}.json`)}saveSession($){try{let Z=this.getSessionPath($.id),Y=JSON.stringify($,null,2);j4.writeFileSync(Z,Y,"utf-8"),this.cache.set($.id,$),t2.debug(`Session saved: ${$.id}`)}catch(Z){t2.warn(`Failed to save session ${$.id}:`,Z)}}loadSession($){if(this.cache.has($))return this.cache.get($);try{let Z=this.getSessionPath($);if(!j4.existsSync(Z))return;let Y=j4.readFileSync(Z,"utf-8"),Q=JSON.parse(Y);return this.cache.set($,Q),Q}catch(Z){t2.warn(`Failed to load session ${$}:`,Z);return}}updateSession($,Z){let Y=this.loadSession($);if(!Y)return;let Q={...Y,...Z,lastActiveAt:Date.now()};return this.saveSession(Q),Q}appendMessages($,Z){let Y=this.loadSession($);if(!Y)return;return this.updateSession($,{messages:[...Y.messages,...Z]})}markCompleted($,Z,Y){return this.updateSession($,{status:Z.success?"completed":"failed",result:Z,stats:Y,completedAt:Date.now()})}deleteSession($){try{let Z=this.getSessionPath($);if(j4.existsSync(Z))j4.unlinkSync(Z);return this.cache.delete($),!0}catch(Z){return t2.warn(`Failed to delete session ${$}:`,Z),!1}}listSessions(){try{let $=j4.readdirSync(this.sessionsDir),Z=[];for(let Y of $){if(!Y.endsWith(".json"))continue;let Q=Y.replace(".json",""),X=this.loadSession(Q);if(X)Z.push(X)}return Z.sort((Y,Q)=>Q.lastActiveAt-Y.lastActiveAt)}catch($){return t2.warn("Failed to list sessions:",$),[]}}listRunningSessions(){return this.listSessions().filter(($)=>$.status==="running")}cleanupExpiredSessions($=604800000){let Z=Date.now(),Y=this.listSessions(),Q=0;for(let X of Y){if(X.status==="running")continue;if(Z-X.lastActiveAt>$){if(this.deleteSession(X.id))Q++}}if(Q>0)t2.info(`Cleaned up ${Q} expired agent sessions`);return Q}clearCache(){this.cache.clear()}}var t2;var KG=A(()=>{O$();t2=l("Agent")});import{randomUUID as H_}from"crypto";class Q1{static instance=null;runningAgents=new Map;sessionStore=q2.getInstance();constructor(){this.cleanupOrphanedSessions()}static getInstance(){if(!Q1.instance)Q1.instance=new Q1;return Q1.instance}cleanupOrphanedSessions(){let $=this.sessionStore.listSessions(),Z=Date.now(),Y=1800000;for(let Q of $)if(Q.status==="running"){let X=this.runningAgents.has(Q.id),J=Z-Q.lastActiveAt;if(!X||J>1800000)W2.warn(`Cleaning up orphaned agent session: ${Q.id}`),this.sessionStore.updateSession(Q.id,{status:"failed",result:{success:!1,message:"",error:"Session was orphaned (process restart or timeout)"},completedAt:Z})}}startBackgroundAgent($){let{config:Z,description:Y,prompt:Q,parentSessionId:X,permissionMode:J,agentId:G,existingMessages:K}=$,q=G||`agent_${H_()}`,W=new AbortController,U={id:q,subagentType:Z.name,description:Y,prompt:Q,messages:K||[],status:"running",createdAt:Date.now(),lastActiveAt:Date.now(),parentSessionId:X};this.sessionStore.saveSession(U);let H=Date.now(),F=this.executeAgent(q,Z,Q,X,J,W.signal,K);return this.runningAgents.set(q,{id:q,promise:F,abortController:W,startTime:H}),F.finally(()=>{this.runningAgents.delete(q)}),W2.info(`Background agent started: ${q} (${Z.name})`),q}async executeAgent($,Z,Y,Q,X,J,G){let K=Date.now();try{if(J.aborted)throw Error("Agent execution was cancelled");let q=Z.systemPrompt||"",W=await O0.create({systemPrompt:q,toolWhitelist:Z.tools}),U={messages:G||[],userId:"subagent",sessionId:Q||`subagent_${$}`,workspaceRoot:process.cwd(),permissionMode:X},H=await W.runAgenticLoop(Y,U,{signal:J});this.sessionStore.updateSession($,{messages:U.messages});let F=Date.now()-K,O=H.success?{success:!0,message:H.finalMessage||"",stats:{tokens:H.metadata?.tokensUsed||0,toolCalls:H.metadata?.toolCallsCount||0,duration:F}}:{success:!1,message:"",error:H.error?.message||"Unknown error",stats:{duration:F}};return this.sessionStore.markCompleted($,{success:O.success,message:O.message,error:O.error},O.stats),W2.info(`Background agent completed: ${$} (success=${O.success})`),O}catch(q){let W=Date.now()-K,U=q instanceof Error?q.message:String(q);return this.sessionStore.markCompleted($,{success:!1,message:"",error:U},{duration:W}),W2.warn(`Background agent failed: ${$}`,q),{success:!1,message:"",error:U,stats:{duration:W}}}}getAgent($){return this.sessionStore.loadSession($)}isRunning($){return this.runningAgents.has($)}async waitForCompletion($,Z=30000){let Y=this.runningAgents.get($);if(!Y)return this.sessionStore.loadSession($);if(Z>0){let Q=new Promise((J)=>setTimeout(()=>J("timeout"),Z));if(await Promise.race([Y.promise,Q])==="timeout")return this.sessionStore.loadSession($)}else await Y.promise;return this.sessionStore.loadSession($)}resumeAgent($,Z,Y,Q,X){let J=this.sessionStore.loadSession($);if(!J){W2.warn(`Cannot resume agent ${$}: session not found`);return}if(this.isRunning($)){W2.warn(`Cannot resume agent ${$}: still running`);return}return this.startBackgroundAgent({config:Y,description:J.description,prompt:Z,parentSessionId:Q||J.parentSessionId,permissionMode:X,agentId:$,existingMessages:J.messages})}killAgent($){let Z=this.runningAgents.get($);if(!Z){let Y=this.sessionStore.loadSession($);if(Y&&Y.status==="running")this.sessionStore.updateSession($,{status:"cancelled"});return!1}return Z.abortController.abort(),this.sessionStore.updateSession($,{status:"cancelled"}),W2.info(`Background agent cancelled: ${$}`),!0}listAll(){return this.sessionStore.listSessions()}listRunning(){return this.sessionStore.listRunningSessions()}getRunningCount(){return this.runningAgents.size}killAll(){for(let[$]of this.runningAgents)this.killAgent($)}cleanupExpiredSessions($){return this.sessionStore.cleanupExpiredSessions($)}}var W2;var I9=A(()=>{O$();X4();KG();W2=l("Agent")});class P5{config;constructor($){this.config=$}async execute($){let Z=Date.now();try{let Y=this.buildSystemPrompt($),Q=await O0.create({systemPrompt:Y,toolWhitelist:this.config.tools}),X=[{role:"user",content:$.prompt}],J="",G=0,K=0,q=await Q.runAgenticLoop($.prompt,{messages:[],userId:"subagent",sessionId:$.parentSessionId||`subagent_${Date.now()}`,workspaceRoot:process.cwd(),permissionMode:$.permissionMode});if(q.success)J=q.finalMessage||"",G=q.metadata?.toolCallsCount||0,K=q.metadata?.tokensUsed||0;else throw Error(q.error?.message||"Subagent execution failed");let W=Date.now()-Z;return{success:!0,message:J,stats:{tokens:K,toolCalls:G,duration:W}}}catch(Y){let Q=Date.now()-Z;return{success:!1,message:"",error:Y instanceof Error?Y.message:String(Y),stats:{duration:Q}}}}buildSystemPrompt($){return this.config.systemPrompt||""}}var qG=A(()=>{X4()});var T5;var WG=A(()=>{T5=[{name:"general-purpose",description:"General-purpose agent for researching complex questions, searching for code, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries use this agent to perform the search for you.",tools:[]},{name:"Explore",description:'Fast agent specialized for exploring codebases. Use this when you need to quickly find files by patterns (eg. "src/components/**/*.tsx"), search code for keywords (eg. "API endpoints"), or answer questions about the codebase (eg. "how do API endpoints work?"). When calling this agent, specify the desired thoroughness level: "quick" for basic searches, "medium" for moderate exploration, or "very thorough" for comprehensive analysis across multiple locations and naming conventions.',tools:["Glob","Grep","Read","WebFetch","WebSearch"],systemPrompt:`# Explore Subagent
1785
1785
 
1786
1786
  You are a specialized code exploration agent. Your job is to **directly execute searches** using the tools available to you.
1787
1787
 
@@ -1848,9 +1848,9 @@ You are a software architect specializing in implementation planning.
1848
1848
  **Risks**:
1849
1849
  - [Potential issue and mitigation]
1850
1850
 
1851
- Be thorough but concise. Focus on actionable steps.`},{name:"statusline-setup",description:"Use this agent to configure the user's Claude Code status line setting.",tools:["Read","Edit"]}]});function UG($){switch($){case"default":case"ignore":case void 0:return"default";case"acceptEdits":return"autoEdit";case"dontAsk":case"bypassPermissions":return"yolo";case"plan":return"plan";default:return"default"}}var HG=A(()=>{U0()});import C5 from"node:fs";import y9 from"node:os";import J2 from"node:path";import F_ from"yaml";class FG{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 agent types and the tools they have access to:
1851
+ Be thorough but concise. Focus on actionable steps.`},{name:"statusline-setup",description:"Use this agent to configure the user's Claude Code status line setting.",tools:["Read","Edit"]}]});function UG($){switch($){case"default":case"ignore":case void 0:return"default";case"acceptEdits":return"autoEdit";case"dontAsk":case"bypassPermissions":return"yolo";case"plan":return"plan";default:return"default"}}var HG=A(()=>{U0()});import C5 from"node:fs";import y9 from"node:os";import J4 from"node:path";import F_ from"yaml";class FG{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 agent types and the tools they have access to:
1852
1852
  ${$.map((Y)=>{let Q=!Y.tools||Y.tools.length===0?"All tools":Y.tools.join(", ");return`- ${Y.name}: ${Y.description} (Tools: ${Q})`}).join(`
1853
- `)}`}loadFromDirectory($,Z){if(!C5.existsSync($))return;let Y=C5.readdirSync($);for(let Q of Y){if(!Q.endsWith(".md"))continue;let X=J2.join($,Q);try{let J=this.parseConfigFile(X,Z);this.subagents.set(J.name,J)}catch(J){S5.warn(`Failed to load subagent config from ${X}:`,J)}}}parseConfigFile($,Z){let Q=C5.readFileSync($,"utf-8").match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);if(!Q)throw Error(`No YAML frontmatter found in ${$}`);let[,X,J]=Q,G=F_.parse(X);if(!G.name||!G.description)throw Error(`Missing required fields (name, description) in ${$}`);let K=J.trim(),q=this.parseStringOrArray(G.tools),W=this.parseStringOrArray(G.skills),U=UG(G.permissionMode);return{name:G.name,description:G.description,systemPrompt:K,tools:q,color:G.color,configPath:$,model:G.model||"inherit",permissionMode:U,skills:W,source:Z}}parseStringOrArray($){if(!$)return;if(Array.isArray($))return $.map((Z)=>Z.trim()).filter(Boolean);return $.split(",").map((Z)=>Z.trim()).filter(Boolean)}loadFromStandardLocations(){this.loadBuiltinAgents();let $=J2.join(y9.homedir(),".claude","agents");this.loadFromDirectory($,"claude-code-user");let Z=J2.join(process.cwd(),".claude","agents");this.loadFromDirectory(Z,"claude-code-project");let Y=J2.join(y9.homedir(),".blade","agents");this.loadFromDirectory(Y,"blade-user");let Q=J2.join(process.cwd(),".blade","agents");this.loadFromDirectory(Q,"blade-project");let X=this.getAllNames().length;return S5.debug(`\uD83D\uDCE6 Loaded ${X} subagents from standard locations`),X}loadBuiltinAgents(){for(let $ of T5)this.subagents.set($.name,{...$,model:$.model||"inherit",source:"builtin"});S5.debug(`Loaded ${T5.length} builtin subagents`)}clear(){this.subagents.clear()}getSubagentsBySource(){let $={builtin:[],"claude-code-user":[],"claude-code-project":[],"blade-user":[],"blade-project":[],plugin:[]};for(let Z of this.subagents.values()){let Y=Z.source||"builtin",Q=Y.startsWith("plugin:")?"plugin":Y;$[Q].push(Z)}return $}clearPluginAgents(){let $=[];for(let[Z,Y]of this.subagents.entries())if(Y.source?.startsWith("plugin:"))$.push(Z);for(let Z of $)this.subagents.delete(Z)}static getClaudeCodeAgentsDir($){if($==="user")return J2.join(y9.homedir(),".claude","agents");return J2.join(process.cwd(),".claude","agents")}static getBladeAgentsDir($){if($==="user")return J2.join(y9.homedir(),".blade","agents");return J2.join(process.cwd(),".blade","agents")}}var S5,J0;var U4=A(()=>{O$();WG();HG();S5=l("Agent");J0=new FG});import{z as e4}from"zod";function O_(){let $=J0.getAllNames();if($.length===0)return["Explore"];return $}function z_(){return`
1853
+ `)}`}loadFromDirectory($,Z){if(!C5.existsSync($))return;let Y=C5.readdirSync($);for(let Q of Y){if(!Q.endsWith(".md"))continue;let X=J4.join($,Q);try{let J=this.parseConfigFile(X,Z);this.subagents.set(J.name,J)}catch(J){S5.warn(`Failed to load subagent config from ${X}:`,J)}}}parseConfigFile($,Z){let Q=C5.readFileSync($,"utf-8").match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);if(!Q)throw Error(`No YAML frontmatter found in ${$}`);let[,X,J]=Q,G=F_.parse(X);if(!G.name||!G.description)throw Error(`Missing required fields (name, description) in ${$}`);let K=J.trim(),q=this.parseStringOrArray(G.tools),W=this.parseStringOrArray(G.skills),U=UG(G.permissionMode);return{name:G.name,description:G.description,systemPrompt:K,tools:q,color:G.color,configPath:$,model:G.model||"inherit",permissionMode:U,skills:W,source:Z}}parseStringOrArray($){if(!$)return;if(Array.isArray($))return $.map((Z)=>Z.trim()).filter(Boolean);return $.split(",").map((Z)=>Z.trim()).filter(Boolean)}loadFromStandardLocations(){this.loadBuiltinAgents();let $=J4.join(y9.homedir(),".claude","agents");this.loadFromDirectory($,"claude-code-user");let Z=J4.join(process.cwd(),".claude","agents");this.loadFromDirectory(Z,"claude-code-project");let Y=J4.join(y9.homedir(),".blade","agents");this.loadFromDirectory(Y,"blade-user");let Q=J4.join(process.cwd(),".blade","agents");this.loadFromDirectory(Q,"blade-project");let X=this.getAllNames().length;return S5.debug(`\uD83D\uDCE6 Loaded ${X} subagents from standard locations`),X}loadBuiltinAgents(){for(let $ of T5)this.subagents.set($.name,{...$,model:$.model||"inherit",source:"builtin"});S5.debug(`Loaded ${T5.length} builtin subagents`)}clear(){this.subagents.clear()}getSubagentsBySource(){let $={builtin:[],"claude-code-user":[],"claude-code-project":[],"blade-user":[],"blade-project":[],plugin:[]};for(let Z of this.subagents.values()){let Y=Z.source||"builtin",Q=Y.startsWith("plugin:")?"plugin":Y;$[Q].push(Z)}return $}clearPluginAgents(){let $=[];for(let[Z,Y]of this.subagents.entries())if(Y.source?.startsWith("plugin:"))$.push(Z);for(let Z of $)this.subagents.delete(Z)}static getClaudeCodeAgentsDir($){if($==="user")return J4.join(y9.homedir(),".claude","agents");return J4.join(process.cwd(),".claude","agents")}static getBladeAgentsDir($){if($==="user")return J4.join(y9.homedir(),".blade","agents");return J4.join(process.cwd(),".blade","agents")}}var S5,J0;var U2=A(()=>{O$();WG();HG();S5=l("Agent");J0=new FG});import{z as e2}from"zod";function O_(){let $=J0.getAllNames();if($.length===0)return["Explore"];return $}function z_(){return`
1854
1854
  ## Task
1855
1855
 
1856
1856
  Launch a new agent to handle complex, multi-step tasks autonomously.
@@ -1898,7 +1898,7 @@ Agent 仍在运行中,请使用 TaskOutput 获取结果`,error:{type:"executio
1898
1898
  `+`类型: ${Y.name}
1899
1899
  `+`任务: ${Q}
1900
1900
 
1901
- `+"\uD83D\uDCA1 使用 TaskOutput 工具获取结果",metadata:{agent_id:K,resumed_from:$,subagent_type:Y.name,description:Q,background:!0}}}var k5;var OG=A(()=>{I9();qG();U4();U0();t0();p$();j0();k5=t({name:"Task",displayName:"Subagent Scheduler",kind:"readonly",isReadOnly:!0,schema:e4.object({subagent_type:e4.enum(O_()).describe('Subagent type to use (e.g., "Explore", "Plan")'),description:e4.string().min(3).max(100).describe("Short task description (3-5 words)"),prompt:e4.string().min(10).describe("Detailed task instructions"),run_in_background:e4.boolean().default(!1).describe("Set to true to run this agent in the background. Use TaskOutput to read the output later."),resume:e4.string().optional().describe("Optional agent ID to resume from. If provided, the agent will continue from the previous execution transcript.")}),description:{short:"Launch a new agent to handle complex, multi-step tasks autonomously",get long(){return z_()},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($,Z){let{subagent_type:Y,description:Q,prompt:X,run_in_background:J=!1,resume:G}=$,{updateOutput:K}=Z;try{let q=J0.getAllNames(),W=J0.getSubagent(Y);if(!W)return{success:!1,llmContent:`Unknown subagent type: ${Y}. Available types: ${q.join(", ")||"none"}`,displayContent:`❌ 未知的 subagent 类型: ${Y}
1901
+ `+"\uD83D\uDCA1 使用 TaskOutput 工具获取结果",metadata:{agent_id:K,resumed_from:$,subagent_type:Y.name,description:Q,background:!0}}}var k5;var OG=A(()=>{I9();qG();U2();U0();t0();p$();j0();k5=t({name:"Task",displayName:"Subagent Scheduler",kind:"readonly",isReadOnly:!0,schema:e2.object({subagent_type:e2.enum(O_()).describe('Subagent type to use (e.g., "Explore", "Plan")'),description:e2.string().min(3).max(100).describe("Short task description (3-5 words)"),prompt:e2.string().min(10).describe("Detailed task instructions"),run_in_background:e2.boolean().default(!1).describe("Set to true to run this agent in the background. Use TaskOutput to read the output later."),resume:e2.string().optional().describe("Optional agent ID to resume from. If provided, the agent will continue from the previous execution transcript.")}),description:{short:"Launch a new agent to handle complex, multi-step tasks autonomously",get long(){return z_()},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($,Z){let{subagent_type:Y,description:Q,prompt:X,run_in_background:J=!1,resume:G}=$,{updateOutput:K}=Z;try{let q=J0.getAllNames(),W=J0.getSubagent(Y);if(!W)return{success:!1,llmContent:`Unknown subagent type: ${Y}. Available types: ${q.join(", ")||"none"}`,displayContent:`❌ 未知的 subagent 类型: ${Y}
1902
1902
 
1903
1903
  可用类型: ${q.join(", ")||"无"}`,error:{type:"execution_error",message:`Unknown subagent type: ${Y}`}};if(G)return B_(G,X,W,Q,Z);if(J)return __(W,Q,X,Z);K?.(`\uD83D\uDE80 启动 ${Y} subagent: ${Q}`);let U=new P5(W),H={prompt:X,parentSessionId:Z.sessionId,permissionMode:Z.permissionMode};K?.("⚙️ 执行任务中...");let F=Date.now(),O=await U.execute(H),z=Date.now()-F;try{let B=await M$.getInstance().executeSubagentStopHooks(Y,{projectDir:process.cwd(),sessionId:Z.sessionId||"unknown",permissionMode:Z.permissionMode||"default",taskDescription:Q,success:O.success,resultSummary:O.message.slice(0,500),error:O.error});if(!B.shouldStop&&B.continueReason){console.log(`[Task] SubagentStop hook 阻止停止,继续执行: ${B.continueReason}`);let L={prompt:B.continueReason,parentSessionId:Z.sessionId,permissionMode:Z.permissionMode},w=Date.now();O=await U.execute(L),z+=Date.now()-w}if(B.warning)console.warn(`[Task] SubagentStop hook warning: ${B.warning}`)}catch(_){console.warn("[Task] SubagentStop hook execution failed:",_)}if(O.success){let _=O.message.length>1000?O.message.slice(0,1000)+`
1904
1904
  ...(截断)`:O.message;return{success:!0,llmContent:O.message,displayContent:`✅ Subagent 任务完成
@@ -1937,7 +1937,7 @@ ${J.stderr}`:"");return{success:!0,llmContent:G,displayContent:q,metadata:G}}asy
1937
1937
  `:"")+(X.result?.message?`
1938
1938
  结果:
1939
1939
  ${X.result.message}`:"")+(X.result?.error?`
1940
- 错误: ${X.result.error}`:"");return{success:!0,llmContent:J,displayContent:K,metadata:J}}async function L_($,Z){let Y=P0.getInstance(),Q=Date.now();return new Promise((X)=>{let J=setInterval(()=>{let G=Y.getProcess($);if(!G||G.status!=="running"){clearInterval(J),X();return}if(Date.now()-Q>=Z){clearInterval(J),X();return}},100)})}function BG($){switch($){case"running":return"⏳";case"completed":case"exited":return"✅";case"failed":case"error":return"❌";case"killed":case"cancelled":return"✂️";default:return"❓"}}var f5;var LG=A(()=>{I9();p$();j0();s4();f5=t({name:"TaskOutput",displayName:"Task Output",kind:"readonly",schema:v9.object({task_id:v9.string().min(1).describe("The task ID to get output from"),block:v9.boolean().default(!0).describe("Whether to wait for completion"),timeout:v9.number().min(0).max(600000).default(30000).describe("Max wait time in ms")}),description:{short:"Retrieves output from a running or completed task",long:`
1940
+ 错误: ${X.result.error}`:"");return{success:!0,llmContent:J,displayContent:K,metadata:J}}async function L_($,Z){let Y=P0.getInstance(),Q=Date.now();return new Promise((X)=>{let J=setInterval(()=>{let G=Y.getProcess($);if(!G||G.status!=="running"){clearInterval(J),X();return}if(Date.now()-Q>=Z){clearInterval(J),X();return}},100)})}function BG($){switch($){case"running":return"⏳";case"completed":case"exited":return"✅";case"failed":case"error":return"❌";case"killed":case"cancelled":return"✂️";default:return"❓"}}var f5;var LG=A(()=>{I9();p$();j0();s2();f5=t({name:"TaskOutput",displayName:"Task Output",kind:"readonly",schema:v9.object({task_id:v9.string().min(1).describe("The task ID to get output from"),block:v9.boolean().default(!0).describe("Whether to wait for completion"),timeout:v9.number().min(0).max(600000).default(30000).describe("Max wait time in ms")}),description:{short:"Retrieves output from a running or completed task",long:`
1941
1941
  - Retrieves output from a running or completed task (background shell, agent, or remote session)
1942
1942
  - Takes a task_id parameter identifying the task
1943
1943
  - Returns the task output along with status information
@@ -1949,7 +1949,7 @@ ${X.result.message}`:"")+(X.result?.error?`
1949
1949
 
1950
1950
  任务 ID 格式:
1951
1951
  - bash_xxx: 后台 shell
1952
- - agent_xxx: 后台 agent`,error:{type:"validation_error",message:`Unknown task ID: ${Y}`}}}},version:"1.0.0",category:"Task",tags:["task","output","background","shell","agent"],extractSignatureContent:($)=>$.task_id,abstractPermissionRule:()=>"*"})});var wG=A(()=>{OG();LG()});import{randomUUID as w_}from"crypto";import*as $3 from"fs/promises";import*as E9 from"path";var H4;var NG=A(()=>{H4=class H4{static instances=new Map;todos=[];filePath;loaded=!1;constructor($,Z){this.filePath=E9.join(Z,"todos",`${$}-agent-${$}.json`)}static getInstance($,Z){let Y=`${$}-${Z}`;if(!H4.instances.has(Y))H4.instances.set(Y,new H4($,Z));return H4.instances.get(Y)}validate($){if($.filter((Y)=>Y.status==="in_progress").length>1)return{valid:!1,error:"同时只能有一个任务处于 in_progress 状态"};return{valid:!0}}async updateTodos($){await this.ensureLoaded();let Z=new Date().toISOString(),Y=$.map((X)=>{let J=X,G=this.todos.find((K)=>K.id===J.id||K.content===X.content);return{...X,id:J.id||G?.id||w_(),priority:X.priority||G?.priority||"medium",createdAt:G?.createdAt||Z,startedAt:X.status==="in_progress"&&!G?.startedAt?Z:G?.startedAt,completedAt:X.status==="completed"&&!G?.completedAt?Z:G?.completedAt}}),Q=this.validate(Y);if(!Q.valid)throw Error(Q.error);this.todos=Y,await this.saveTodos()}getSortedTodos(){let $={completed:0,in_progress:1,pending:2},Z={high:0,medium:1,low:2};return[...this.todos].sort((Y,Q)=>{let X=$[Y.status]-$[Q.status];if(X!==0)return X;return Z[Y.priority]-Z[Q.priority]})}getTodos(){return this.getSortedTodos()}async ensureLoaded(){if(!this.loaded)await this.loadTodos(),this.loaded=!0}async loadTodos(){try{let $=await $3.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 $3.mkdir(E9.dirname(this.filePath),{recursive:!0,mode:493}),await $3.writeFile(this.filePath,JSON.stringify(this.todos,null,2),"utf-8")}catch($){throw console.error("保存 TODO 列表失败:",$),$}}}});import{z as Z3}from"zod";var bG;var AG=A(()=>{bG=Z3.object({id:Z3.string().optional(),content:Z3.string().min(1,"Content cannot be empty"),status:Z3.enum(["pending","in_progress","completed"]),activeForm:Z3.string().min(1,"ActiveForm cannot be empty"),priority:Z3.enum(["high","medium","low"]).default("medium")})});import{z as RG}from"zod";function h5($){let{sessionId:Z,configDir:Y}=$;return t({name:"TodoWrite",displayName:"Todo Write",kind:"readonly",schema:RG.object({todos:RG.array(bG).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.
1952
+ - agent_xxx: 后台 agent`,error:{type:"validation_error",message:`Unknown task ID: ${Y}`}}}},version:"1.0.0",category:"Task",tags:["task","output","background","shell","agent"],extractSignatureContent:($)=>$.task_id,abstractPermissionRule:()=>"*"})});var wG=A(()=>{OG();LG()});import{randomUUID as w_}from"crypto";import*as $8 from"fs/promises";import*as E9 from"path";var H2;var NG=A(()=>{H2=class H2{static instances=new Map;todos=[];filePath;loaded=!1;constructor($,Z){this.filePath=E9.join(Z,"todos",`${$}-agent-${$}.json`)}static getInstance($,Z){let Y=`${$}-${Z}`;if(!H2.instances.has(Y))H2.instances.set(Y,new H2($,Z));return H2.instances.get(Y)}validate($){if($.filter((Y)=>Y.status==="in_progress").length>1)return{valid:!1,error:"同时只能有一个任务处于 in_progress 状态"};return{valid:!0}}async updateTodos($){await this.ensureLoaded();let Z=new Date().toISOString(),Y=$.map((X)=>{let J=X,G=this.todos.find((K)=>K.id===J.id||K.content===X.content);return{...X,id:J.id||G?.id||w_(),priority:X.priority||G?.priority||"medium",createdAt:G?.createdAt||Z,startedAt:X.status==="in_progress"&&!G?.startedAt?Z:G?.startedAt,completedAt:X.status==="completed"&&!G?.completedAt?Z:G?.completedAt}}),Q=this.validate(Y);if(!Q.valid)throw Error(Q.error);this.todos=Y,await this.saveTodos()}getSortedTodos(){let $={completed:0,in_progress:1,pending:2},Z={high:0,medium:1,low:2};return[...this.todos].sort((Y,Q)=>{let X=$[Y.status]-$[Q.status];if(X!==0)return X;return Z[Y.priority]-Z[Q.priority]})}getTodos(){return this.getSortedTodos()}async ensureLoaded(){if(!this.loaded)await this.loadTodos(),this.loaded=!0}async loadTodos(){try{let $=await $8.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 $8.mkdir(E9.dirname(this.filePath),{recursive:!0,mode:493}),await $8.writeFile(this.filePath,JSON.stringify(this.todos,null,2),"utf-8")}catch($){throw console.error("保存 TODO 列表失败:",$),$}}}});import{z as Z8}from"zod";var bG;var AG=A(()=>{bG=Z8.object({id:Z8.string().optional(),content:Z8.string().min(1,"Content cannot be empty"),status:Z8.enum(["pending","in_progress","completed"]),activeForm:Z8.string().min(1,"ActiveForm cannot be empty"),priority:Z8.enum(["high","medium","low"]).default("medium")})});import{z as RG}from"zod";function h5($){let{sessionId:Z,configDir:Y}=$;return t({name:"TodoWrite",displayName:"Todo Write",kind:"readonly",schema:RG.object({todos:RG.array(bG).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.
1953
1953
  It also helps the user understand the progress of the task and overall progress of their requests.
1954
1954
 
1955
1955
  ## When to Use This Tool
@@ -2010,7 +2010,7 @@ NOTE that you should not use this tool if there is only one trivial task to do.
2010
2010
  - activeForm: "Fixing authentication bug"
2011
2011
 
2012
2012
  When in doubt, use this tool. Being proactive with task management demonstrates attentiveness and ensures you complete all requirements successfully.
2013
- `},async execute(Q,X){let{todos:J}=Q,{updateOutput:G}=X;try{let K=X.sessionId||Z,q=H4.getInstance(K,Y);G?.("Updating TODO list..."),await q.updateTodos(J);let W=q.getTodos(),U=N_(W),H=b_(W,U);return G?.(`✅ TODO list updated (${U.completed}/${U.total} completed)`),{success:!0,llmContent:{todos:W,stats:U},displayContent:H,metadata:{stats:U}}}catch(K){let q=K;return{success:!1,llmContent:`Update failed: ${q.message}`,displayContent:`❌ 更新 TODO 列表失败: ${q.message}`,error:{type:"execution_error",message:q.message,details:K}}}},version:"1.0.0",category:"TODO tools",tags:["todo","task","management","planning"],extractSignatureContent:(Q)=>`${Q.todos.length} todos`,abstractPermissionRule:()=>"*"})}function N_($){return{total:$.length,completed:$.filter((Z)=>Z.status==="completed").length,inProgress:$.filter((Z)=>Z.status==="in_progress").length,pending:$.filter((Z)=>Z.status==="pending").length}}function b_($,Z){let Y=[],Q=Z.total>0?Math.round(Z.completed/Z.total*100):0;if(Y.push(`\uD83D\uDCCB TODO 列表 (${Z.completed}/${Z.total} 完成,${Q}%)`),Y.push(""),$.length===0)return Y.push(" (暂无任务)"),Y.join(`
2013
+ `},async execute(Q,X){let{todos:J}=Q,{updateOutput:G}=X;try{let K=X.sessionId||Z,q=H2.getInstance(K,Y);G?.("Updating TODO list..."),await q.updateTodos(J);let W=q.getTodos(),U=N_(W),H=b_(W,U);return G?.(`✅ TODO list updated (${U.completed}/${U.total} completed)`),{success:!0,llmContent:{todos:W,stats:U},displayContent:H,metadata:{stats:U}}}catch(K){let q=K;return{success:!1,llmContent:`Update failed: ${q.message}`,displayContent:`❌ 更新 TODO 列表失败: ${q.message}`,error:{type:"execution_error",message:q.message,details:K}}}},version:"1.0.0",category:"TODO tools",tags:["todo","task","management","planning"],extractSignatureContent:(Q)=>`${Q.todos.length} todos`,abstractPermissionRule:()=>"*"})}function N_($){return{total:$.length,completed:$.filter((Z)=>Z.status==="completed").length,inProgress:$.filter((Z)=>Z.status==="in_progress").length,pending:$.filter((Z)=>Z.status==="pending").length}}function b_($,Z){let Y=[],Q=Z.total>0?Math.round(Z.completed/Z.total*100):0;if(Y.push(`\uD83D\uDCCB TODO 列表 (${Z.completed}/${Z.total} 完成,${Q}%)`),Y.push(""),$.length===0)return Y.push(" (暂无任务)"),Y.join(`
2014
2014
  `);for(let X of $){let J=X.status==="completed"?"☑":"☐",G=`(P${X.priority==="high"?0:X.priority==="medium"?1:2})`,K=X.status==="in_progress"?" ⚡":"",q=X.status==="completed"?"~~":"";Y.push(` ${J} ${G} ${q}${X.content}${q}${K}`)}return Y.join(`
2015
2015
  `)}var VG=A(()=>{p$();j0();NG();AG()});var DG=A(()=>{VG()});import{z as $1}from"zod";import{isPlainObject as MG}from"lodash-es";function jG($){if(!MG($))return;let Z=$;return typeof Z.name==="string"?Z.name:void 0}function A_($){if($ instanceof Error)return $.message;if(typeof $==="string")return $;if(MG($)){let Z=$;if(typeof Z.message==="string")return Z.message}return String($)}async function R_($){let{url:Z,method:Y,headers:Q,body:X,timeout:J,follow_redirects:G,max_redirects:K,signal:q}=$,W={"User-Agent":"Blade-AI/1.0",...Q},U=Z,H=Y,F=X,O=0,z=[];while(!0){let _={...W};if(F&&H!=="GET"&&H!=="HEAD"&&!j_(_,"content-type"))_["Content-Type"]="application/json";let B=await IG(U,{method:H,headers:_,body:F&&H!=="GET"&&H!=="HEAD"?F:void 0,redirect:"manual"},J,q),L=B.headers.get("location"),w=B.status>=300&&B.status<400,N=G&&w&&L&&O<K;if(w&&G&&!L)throw Error(`收到状态码 ${B.status} 但响应缺少 Location 头`);if(w&&G&&O>=K)throw Error(`超过最大重定向次数 (${K})`);if(N&&L){O++;let I=M_(L,U);if(z.push(`${B.status} → ${I}`),B.status===303||(B.status===301||B.status===302)&&H!=="GET"&&H!=="HEAD")H="GET",F=void 0;U=I;continue}let D=await B.text(),V=yG(B.headers);return{status:B.status,status_text:B.statusText,headers:V,body:D,url:B.url||U,redirected:O>0,redirect_count:O,redirect_chain:z,content_type:V["content-type"],response_time:0}}}function x5($,Z,Y){let{url:Q,method:X,status:J,response_time:G,content_length:K}=Z,q=Y?`❌ ${X} ${Q} - ${J} ${$.status_text}`:`✅ ${X} ${Q} - ${J} ${$.status_text}`;if(q+=`
2016
2016
  响应时间: ${G}ms`,q+=`
@@ -2027,7 +2027,7 @@ ${W}`;return q}function V_($,Z){if(!$)return"(空响应)";if(D_(Z,$))return"[bin
2027
2027
 
2028
2028
  `;return Z+=`---
2029
2029
 
2030
- `,Z+=$.content,Z}var p5;var vG=A(()=>{p$();j0();V2();p5=t({name:"WebFetch",displayName:"Web Fetch",kind:"readonly",schema:$1.object({url:$1.string().url().describe("URL to request"),method:$1.enum(["GET","POST","PUT","DELETE","HEAD"]).default("GET").describe("HTTP method"),extract_content:$1.boolean().default(!1).describe("Use Jina Reader to extract clean content in Markdown format. Removes HTML clutter, scripts, and styling, returning only the main content."),jina_options:$1.object({with_generated_alt:$1.boolean().default(!1).describe("Generate alt text for images"),with_links_summary:$1.boolean().default(!1).describe("Include summary of all links"),wait_for_selector:$1.string().optional().describe("Wait for specific CSS selector to load")}).optional().describe("Jina Reader advanced options (only used when extract_content is true)"),headers:$1.record($1.string()).optional().describe("Request headers (optional)"),body:$1.string().optional().describe("Request body (optional)"),timeout:r$.timeout(1000,120000,30000),follow_redirects:$1.boolean().default(!0).describe("Follow redirects"),max_redirects:$1.number().int().min(0).max(10).default(5).describe("Maximum redirect hops"),return_headers:$1.boolean().default(!1).describe("Return response headers")}),description:{short:"Fetches content from a specified URL and processes it using an AI model",long:`
2030
+ `,Z+=$.content,Z}var p5;var vG=A(()=>{p$();j0();V4();p5=t({name:"WebFetch",displayName:"Web Fetch",kind:"readonly",schema:$1.object({url:$1.string().url().describe("URL to request"),method:$1.enum(["GET","POST","PUT","DELETE","HEAD"]).default("GET").describe("HTTP method"),extract_content:$1.boolean().default(!1).describe("Use Jina Reader to extract clean content in Markdown format. Removes HTML clutter, scripts, and styling, returning only the main content."),jina_options:$1.object({with_generated_alt:$1.boolean().default(!1).describe("Generate alt text for images"),with_links_summary:$1.boolean().default(!1).describe("Include summary of all links"),wait_for_selector:$1.string().optional().describe("Wait for specific CSS selector to load")}).optional().describe("Jina Reader advanced options (only used when extract_content is true)"),headers:$1.record($1.string()).optional().describe("Request headers (optional)"),body:$1.string().optional().describe("Request body (optional)"),timeout:r$.timeout(1000,120000,30000),follow_redirects:$1.boolean().default(!0).describe("Follow redirects"),max_redirects:$1.number().int().min(0).max(10).default(5).describe("Maximum redirect hops"),return_headers:$1.boolean().default(!1).describe("Return response headers")}),description:{short:"Fetches content from a specified URL and processes it using an AI model",long:`
2031
2031
  - Fetches content from a specified URL and processes it using an AI model
2032
2032
  - Takes a URL and a prompt as input
2033
2033
  - Fetches the URL content, converts HTML to markdown
@@ -2044,14 +2044,14 @@ Usage notes:
2044
2044
  - Results may be summarized if the content is very large
2045
2045
  - Includes a self-cleaning 15-minute cache for faster responses when repeatedly accessing the same URL
2046
2046
  - 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.
2047
- `},async execute($,Z){let{url:Y,method:Q="GET",extract_content:X=!1,jina_options:J,headers:G={},body:K,timeout:q=30000,follow_redirects:W=!0,max_redirects:U=5,return_headers:H=!1}=$,{updateOutput:F}=Z,O=Z.signal??new AbortController().signal;try{if(X)try{let w=Date.now(),N=await I_({url:Y,jinaOptions:J,timeout:q,signal:O,updateOutput:F}),D=Date.now()-w;if(N.response_time=D,!H)delete N.headers;let V={url:Y,method:"GET",status:N.status,response_time:D,content_length:Buffer.byteLength(N.body||"","utf8"),redirected:N.redirected||!1,redirect_count:N.redirect_count??0,final_url:N.url,content_type:N.content_type,redirect_chain:N.redirect_chain};return{success:!0,llmContent:N,displayContent:x5(N,V,!1),metadata:V}}catch{F?.("⚠️ Jina Reader 失败,使用标准方式获取")}F?.(`发送 ${Q} 请求到: ${Y}`);let z=Date.now(),_=await R_({url:Y,method:Q,headers:G,body:K,timeout:q,follow_redirects:W,max_redirects:U,signal:O}),B=Date.now()-z;if(_.response_time=B,!H)delete _.headers;let L={url:Y,method:Q,status:_.status,response_time:B,content_length:Buffer.byteLength(_.body||"","utf8"),redirected:_.redirected||!1,redirect_count:_.redirect_count??0,final_url:_.url,content_type:_.content_type,redirect_chain:_.redirect_chain};if(_.status>=400)return{success:!1,llmContent:`HTTP error ${_.status}: ${_.status_text}`,displayContent:x5(_,L,!0),error:{type:"execution_error",message:`HTTP error ${_.status}: ${_.status_text}`,details:{...L,response_body:_.body}},metadata:L};return{success:!0,llmContent:_,displayContent:x5(_,L,!1),metadata:L}}catch(z){if(jG(z)==="AbortError")return{success:!1,llmContent:"Request aborted",displayContent:"⚠️ 请求被用户中止",error:{type:"execution_error",message:"操作被中止"}};let _=A_(z);return{success:!1,llmContent:`Network request failed: ${_}`,displayContent:`❌ 网络请求失败: ${_}`,error:{type:"execution_error",message:_,details:z}}}},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"*"}}})});import{LRUCache as EG}from"lru-cache";import E_ from"node:crypto";class PG{cache;config;hits=0;misses=0;constructor($){this.config={maxSize:$?.maxSize??100,ttl:$?.ttl??3600000,enabled:$?.enabled??!0},this.cache=new EG({max:this.config.maxSize,ttl:this.config.ttl,updateAgeOnGet:!0,updateAgeOnHas:!1})}generateKey($,Z){let Y=Z.toLowerCase().trim(),Q=E_.createHash("md5").update(Y).digest("hex").substring(0,8);return`${$}:${Q}`}get($,Z){if(!this.config.enabled)return null;let Y=this.generateKey($,Z),Q=this.cache.get(Y);if(!Q)return this.misses++,null;if(Date.now()>Q.expiresAt)return this.cache.delete(Y),this.misses++,null;return this.hits++,Q.results}set($,Z,Y){if(!this.config.enabled||Y.length===0)return;let Q=this.generateKey($,Z),X=Date.now(),J={query:Z,provider:$,results:Y,timestamp:X,expiresAt:X+this.config.ttl};this.cache.set(Q,J)}clear(){this.cache.clear(),this.hits=0,this.misses=0}getStats(){let $=this.hits+this.misses,Z=$>0?this.hits/$*100:0;return{size:this.cache.size,maxSize:this.config.maxSize,enabled:this.config.enabled,ttl:this.config.ttl,hits:this.hits,misses:this.misses,hitRate:Number.parseFloat(Z.toFixed(2))}}cleanup(){let $=Date.now(),Z=0;for(let[Y,Q]of this.cache.entries())if($>Q.expiresAt)this.cache.delete(Y),Z++;return Z}enable(){this.config.enabled=!0}disable(){this.config.enabled=!1}isEnabled(){return this.config.enabled}updateConfig($){if($.maxSize!==void 0&&$.maxSize!==this.config.maxSize){this.config.maxSize=$.maxSize;let Z=Array.from(this.cache.entries());this.cache=new EG({max:this.config.maxSize,ttl:this.config.ttl,updateAgeOnGet:!0,updateAgeOnHas:!1});for(let[Y,Q]of Z.slice(-this.config.maxSize))this.cache.set(Y,Q)}if($.ttl!==void 0)this.config.ttl=$.ttl;if($.enabled!==void 0)this.config.enabled=$.enabled}}function TG(){return P_}var P_;var CG=A(()=>{P_=new PG});function T_($){return $.replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#39;/g,"'")}function SG($){let Z=T_($).trim();if(!Z.includes(" - "))return{title:Z,snippet:Z};let[Y,...Q]=Z.split(" - "),X=Y.trim(),J=Q.join(" - ").trim()||Z;return{title:X,snippet:J}}function q8($){try{let Z=new URL($),Y=Z.pathname==="/"?"":Z.pathname;return`${Z.hostname}${Y}`}catch{return $}}function W8($){try{return new URL($).hostname.toLowerCase()}catch{return""}}function C_($){if(!$.FirstURL||!$.Text)return null;let{title:Z,snippet:Y}=SG($.Text);return{title:Z,snippet:Y,url:$.FirstURL,display_url:q8($.FirstURL),source:W8($.FirstURL)}}function kG($){let Z=[];for(let Y of $){if(Y.Topics&&Y.Topics.length>0){Z.push(...kG(Y.Topics));continue}if(Y.FirstURL&&Y.Text){let{title:Q,snippet:X}=SG(Y.Text);Z.push({title:Q,snippet:X,url:Y.FirstURL,display_url:q8(Y.FirstURL),source:W8(Y.FirstURL)})}}return Z}function S_($){let Z=$,Y=(Z.Results??[]).map((X)=>C_(X)).filter((X)=>X!==null),Q=kG(Z.RelatedTopics??[]);return[...Y,...Q]}function f_($){let Z=$,Y=[];for(let Q of Z.results??[]){if(!Q.url||!Q.title)continue;Y.push({title:Q.title,snippet:Q.content||Q.title,url:Q.url,display_url:q8(Q.url),source:W8(Q.url)})}return Y}function h_($){return{name:`SearXNG(${(()=>{try{return new URL($).hostname}catch{return $}})()})`,endpoint:$,buildUrl:(Y)=>{let Q=new URL(`${$}/search`);return Q.searchParams.set("q",Y),Q.searchParams.set("format","json"),Q.searchParams.set("categories","general"),Q.toString()},parseResponse:f_,getHeaders:()=>({Accept:"application/json","User-Agent":"Blade-AI-WebSearch/1.0"})}}function x_($){let Z=[],Y=$.split(`
2048
- `),Q={};for(let X=0;X<Y.length;X++){let J=Y[X].trim();if(J.startsWith("Title: ")){if(Q.title&&Q.url)Z.push({title:Q.title,url:Q.url,snippet:Q.snippet||Q.title,display_url:q8(Q.url),source:W8(Q.url)});Q={title:J.substring(7).trim(),snippet:""}}else if(J.startsWith("URL: "))Q.url=J.substring(5).trim();else if(J.startsWith("Text: ")){let K=J.substring(6).trim().replace(/<[^>]*>/g,"").replace(/\s+/g," ").trim();Q.snippet=K.substring(0,300)}}if(Q.title&&Q.url)Z.push({title:Q.title,url:Q.url,snippet:Q.snippet||Q.title,display_url:q8(Q.url),source:W8(Q.url)});return Z}function p_(){return{name:"Exa",endpoint:`${I2.BASE_URL}${I2.ENDPOINT}`,searchFn:async($)=>{let Z={jsonrpc:"2.0",id:1,method:"tools/call",params:{name:"web_search_exa",arguments:{query:$,type:"auto",numResults:I2.DEFAULT_NUM_RESULTS,contextMaxCharacters:1e4}}},Y=new AbortController,Q=setTimeout(()=>Y.abort(),I2.TIMEOUT);try{let X=await fetch(`${I2.BASE_URL}${I2.ENDPOINT}`,{method:"POST",headers:{accept:"application/json, text/event-stream","content-type":"application/json"},body:JSON.stringify(Z),signal:Y.signal});if(clearTimeout(Q),!X.ok)throw Error(`MCP error (${X.status})`);let G=(await X.text()).split(`
2049
- `);for(let K of G)if(K.startsWith("data: ")){let q=JSON.parse(K.substring(6));if(q.result&&q.result.content&&q.result.content.length>0)return x_(q.result.content[0].text)}throw Error("No search results found")}catch(X){if(clearTimeout(Q),X.name==="AbortError")throw Error("MCP request timed out");throw X}},buildUrl:()=>`${I2.BASE_URL}${I2.ENDPOINT}`,parseResponse:()=>[],getHeaders:()=>({})}}function hG(){let $=[];return $.push(p_()),$.push(k_),$.push(...fG.map(h_)),$}function xG(){return 2+fG.length}var k_,fG,I2;var pG=A(()=>{k_={name:"DuckDuckGo",endpoint:"https://duckduckgo.com/",buildUrl:($)=>{let Z=new URL("https://duckduckgo.com/");return Z.searchParams.set("q",$),Z.searchParams.set("format","json"),Z.searchParams.set("no_html","1"),Z.searchParams.set("skip_disambig","1"),Z.searchParams.set("t","blade-code"),Z.searchParams.set("kl","us-en"),Z.toString()},parseResponse:S_,getHeaders:()=>({Accept:"application/json, text/plain;q=0.9","User-Agent":"Blade-AI-WebSearch/1.0"})};fG=["https://searx.be","https://search.ononoki.org","https://searx.tiekoetter.com","https://searx.work"];I2={BASE_URL:"https://mcp.exa.ai",ENDPOINT:"/mcp",DEFAULT_NUM_RESULTS:10,TIMEOUT:25000}});import{ProxyAgent as m_,fetch as d_}from"undici";import{z as Y3}from"zod";function c_(){let $=process.env.HTTPS_PROXY||process.env.HTTP_PROXY||process.env.https_proxy||process.env.http_proxy;if($)try{return new m_($)}catch(Z){console.warn(`Invalid proxy URL: ${$}`)}return}async function l_($,Z,Y,Q,X){let J=new AbortController,G=setTimeout(()=>J.abort(),Y),K=()=>J.abort();Q?.addEventListener("abort",K);try{return await d_($,{...Z,signal:J.signal,dispatcher:X})}catch(q){if(q.name==="AbortError")throw Error("搜索请求超时或被中止");throw q}finally{clearTimeout(G),Q?.removeEventListener("abort",K)}}async function i_($,Z,Y,Q,X,J){let G=null;for(let K=0;K<U8.maxRetries;K++)try{return await l_($,Z,Y,Q,X)}catch(q){if(G=q,Q?.aborted)throw q;if(K<U8.maxRetries-1){let W=Math.min(U8.baseDelay*Math.pow(2,K),U8.maxDelay);J?.(`⏳ 请求失败,${W/1000}s 后重试 (${K+1}/${U8.maxRetries})...`),await new Promise((U)=>setTimeout(U,W))}}throw G}async function a_($,Z,Y,Q,X,J){let G=TG(),K=G.get($.name,Z);if(K)return J?.(`\uD83D\uDCBE 使用缓存结果 (${$.name})`),{results:K,providerName:`${$.name} (cached)`};if($.searchFn)try{J?.(`\uD83D\uDD0D 搜索中 (${$.name})...`);let B=await $.searchFn(Z);return G.set($.name,Z,B),{results:B,providerName:$.name}}catch(B){throw Error(`SDK search failed: ${B.message}`)}J?.(`\uD83D\uDD0D 搜索中 (${$.name})...`);let q=$.buildUrl(Z),W=$.method||"GET",H={headers:$.getHeaders(),method:W};if(W==="POST"&&$.buildBody)H.body=JSON.stringify($.buildBody(Z));let F=await i_(q,H,Y,Q,X,J);if(!F.ok)throw Error(`HTTP ${F.status}`);let O=await F.text(),z;try{z=JSON.parse(O)}catch{throw Error("Failed to parse search result JSON")}let _=$.parseResponse(z);return G.set($.name,Z,_),{results:_,providerName:$.name}}async function r_($,Z,Y,Q){let X=hG(),J=c_(),G=[];for(let K=0;K<X.length;K++){let q=X[K];if(Y?.aborted)throw Error("搜索被用户中止");try{return Q?.(`\uD83D\uDD0E 使用 ${q.name} 搜索...`),await a_(q,$,Z,Y,J,Q)}catch(W){let U=W,H=`${q.name}: ${U.message}`;if(G.push(H),Q?.(`⚠️ ${H}`),K===X.length-1)throw Error(`所有搜索提供商都失败了:
2047
+ `},async execute($,Z){let{url:Y,method:Q="GET",extract_content:X=!1,jina_options:J,headers:G={},body:K,timeout:q=30000,follow_redirects:W=!0,max_redirects:U=5,return_headers:H=!1}=$,{updateOutput:F}=Z,O=Z.signal??new AbortController().signal;try{if(X)try{let w=Date.now(),N=await I_({url:Y,jinaOptions:J,timeout:q,signal:O,updateOutput:F}),D=Date.now()-w;if(N.response_time=D,!H)delete N.headers;let V={url:Y,method:"GET",status:N.status,response_time:D,content_length:Buffer.byteLength(N.body||"","utf8"),redirected:N.redirected||!1,redirect_count:N.redirect_count??0,final_url:N.url,content_type:N.content_type,redirect_chain:N.redirect_chain};return{success:!0,llmContent:N,displayContent:x5(N,V,!1),metadata:V}}catch{F?.("⚠️ Jina Reader 失败,使用标准方式获取")}F?.(`发送 ${Q} 请求到: ${Y}`);let z=Date.now(),_=await R_({url:Y,method:Q,headers:G,body:K,timeout:q,follow_redirects:W,max_redirects:U,signal:O}),B=Date.now()-z;if(_.response_time=B,!H)delete _.headers;let L={url:Y,method:Q,status:_.status,response_time:B,content_length:Buffer.byteLength(_.body||"","utf8"),redirected:_.redirected||!1,redirect_count:_.redirect_count??0,final_url:_.url,content_type:_.content_type,redirect_chain:_.redirect_chain};if(_.status>=400)return{success:!1,llmContent:`HTTP error ${_.status}: ${_.status_text}`,displayContent:x5(_,L,!0),error:{type:"execution_error",message:`HTTP error ${_.status}: ${_.status_text}`,details:{...L,response_body:_.body}},metadata:L};return{success:!0,llmContent:_,displayContent:x5(_,L,!1),metadata:L}}catch(z){if(jG(z)==="AbortError")return{success:!1,llmContent:"Request aborted",displayContent:"⚠️ 请求被用户中止",error:{type:"execution_error",message:"操作被中止"}};let _=A_(z);return{success:!1,llmContent:`Network request failed: ${_}`,displayContent:`❌ 网络请求失败: ${_}`,error:{type:"execution_error",message:_,details:z}}}},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"*"}}})});import{LRUCache as EG}from"lru-cache";import E_ from"node:crypto";class PG{cache;config;hits=0;misses=0;constructor($){this.config={maxSize:$?.maxSize??100,ttl:$?.ttl??3600000,enabled:$?.enabled??!0},this.cache=new EG({max:this.config.maxSize,ttl:this.config.ttl,updateAgeOnGet:!0,updateAgeOnHas:!1})}generateKey($,Z){let Y=Z.toLowerCase().trim(),Q=E_.createHash("md5").update(Y).digest("hex").substring(0,8);return`${$}:${Q}`}get($,Z){if(!this.config.enabled)return null;let Y=this.generateKey($,Z),Q=this.cache.get(Y);if(!Q)return this.misses++,null;if(Date.now()>Q.expiresAt)return this.cache.delete(Y),this.misses++,null;return this.hits++,Q.results}set($,Z,Y){if(!this.config.enabled||Y.length===0)return;let Q=this.generateKey($,Z),X=Date.now(),J={query:Z,provider:$,results:Y,timestamp:X,expiresAt:X+this.config.ttl};this.cache.set(Q,J)}clear(){this.cache.clear(),this.hits=0,this.misses=0}getStats(){let $=this.hits+this.misses,Z=$>0?this.hits/$*100:0;return{size:this.cache.size,maxSize:this.config.maxSize,enabled:this.config.enabled,ttl:this.config.ttl,hits:this.hits,misses:this.misses,hitRate:Number.parseFloat(Z.toFixed(2))}}cleanup(){let $=Date.now(),Z=0;for(let[Y,Q]of this.cache.entries())if($>Q.expiresAt)this.cache.delete(Y),Z++;return Z}enable(){this.config.enabled=!0}disable(){this.config.enabled=!1}isEnabled(){return this.config.enabled}updateConfig($){if($.maxSize!==void 0&&$.maxSize!==this.config.maxSize){this.config.maxSize=$.maxSize;let Z=Array.from(this.cache.entries());this.cache=new EG({max:this.config.maxSize,ttl:this.config.ttl,updateAgeOnGet:!0,updateAgeOnHas:!1});for(let[Y,Q]of Z.slice(-this.config.maxSize))this.cache.set(Y,Q)}if($.ttl!==void 0)this.config.ttl=$.ttl;if($.enabled!==void 0)this.config.enabled=$.enabled}}function TG(){return P_}var P_;var CG=A(()=>{P_=new PG});function T_($){return $.replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&#39;/g,"'")}function SG($){let Z=T_($).trim();if(!Z.includes(" - "))return{title:Z,snippet:Z};let[Y,...Q]=Z.split(" - "),X=Y.trim(),J=Q.join(" - ").trim()||Z;return{title:X,snippet:J}}function q3($){try{let Z=new URL($),Y=Z.pathname==="/"?"":Z.pathname;return`${Z.hostname}${Y}`}catch{return $}}function W3($){try{return new URL($).hostname.toLowerCase()}catch{return""}}function C_($){if(!$.FirstURL||!$.Text)return null;let{title:Z,snippet:Y}=SG($.Text);return{title:Z,snippet:Y,url:$.FirstURL,display_url:q3($.FirstURL),source:W3($.FirstURL)}}function kG($){let Z=[];for(let Y of $){if(Y.Topics&&Y.Topics.length>0){Z.push(...kG(Y.Topics));continue}if(Y.FirstURL&&Y.Text){let{title:Q,snippet:X}=SG(Y.Text);Z.push({title:Q,snippet:X,url:Y.FirstURL,display_url:q3(Y.FirstURL),source:W3(Y.FirstURL)})}}return Z}function S_($){let Z=$,Y=(Z.Results??[]).map((X)=>C_(X)).filter((X)=>X!==null),Q=kG(Z.RelatedTopics??[]);return[...Y,...Q]}function f_($){let Z=$,Y=[];for(let Q of Z.results??[]){if(!Q.url||!Q.title)continue;Y.push({title:Q.title,snippet:Q.content||Q.title,url:Q.url,display_url:q3(Q.url),source:W3(Q.url)})}return Y}function h_($){return{name:`SearXNG(${(()=>{try{return new URL($).hostname}catch{return $}})()})`,endpoint:$,buildUrl:(Y)=>{let Q=new URL(`${$}/search`);return Q.searchParams.set("q",Y),Q.searchParams.set("format","json"),Q.searchParams.set("categories","general"),Q.toString()},parseResponse:f_,getHeaders:()=>({Accept:"application/json","User-Agent":"Blade-AI-WebSearch/1.0"})}}function x_($){let Z=[],Y=$.split(`
2048
+ `),Q={};for(let X=0;X<Y.length;X++){let J=Y[X].trim();if(J.startsWith("Title: ")){if(Q.title&&Q.url)Z.push({title:Q.title,url:Q.url,snippet:Q.snippet||Q.title,display_url:q3(Q.url),source:W3(Q.url)});Q={title:J.substring(7).trim(),snippet:""}}else if(J.startsWith("URL: "))Q.url=J.substring(5).trim();else if(J.startsWith("Text: ")){let K=J.substring(6).trim().replace(/<[^>]*>/g,"").replace(/\s+/g," ").trim();Q.snippet=K.substring(0,300)}}if(Q.title&&Q.url)Z.push({title:Q.title,url:Q.url,snippet:Q.snippet||Q.title,display_url:q3(Q.url),source:W3(Q.url)});return Z}function p_(){return{name:"Exa",endpoint:`${I4.BASE_URL}${I4.ENDPOINT}`,searchFn:async($)=>{let Z={jsonrpc:"2.0",id:1,method:"tools/call",params:{name:"web_search_exa",arguments:{query:$,type:"auto",numResults:I4.DEFAULT_NUM_RESULTS,contextMaxCharacters:1e4}}},Y=new AbortController,Q=setTimeout(()=>Y.abort(),I4.TIMEOUT);try{let X=await fetch(`${I4.BASE_URL}${I4.ENDPOINT}`,{method:"POST",headers:{accept:"application/json, text/event-stream","content-type":"application/json"},body:JSON.stringify(Z),signal:Y.signal});if(clearTimeout(Q),!X.ok)throw Error(`MCP error (${X.status})`);let G=(await X.text()).split(`
2049
+ `);for(let K of G)if(K.startsWith("data: ")){let q=JSON.parse(K.substring(6));if(q.result&&q.result.content&&q.result.content.length>0)return x_(q.result.content[0].text)}throw Error("No search results found")}catch(X){if(clearTimeout(Q),X.name==="AbortError")throw Error("MCP request timed out");throw X}},buildUrl:()=>`${I4.BASE_URL}${I4.ENDPOINT}`,parseResponse:()=>[],getHeaders:()=>({})}}function hG(){let $=[];return $.push(p_()),$.push(k_),$.push(...fG.map(h_)),$}function xG(){return 2+fG.length}var k_,fG,I4;var pG=A(()=>{k_={name:"DuckDuckGo",endpoint:"https://duckduckgo.com/",buildUrl:($)=>{let Z=new URL("https://duckduckgo.com/");return Z.searchParams.set("q",$),Z.searchParams.set("format","json"),Z.searchParams.set("no_html","1"),Z.searchParams.set("skip_disambig","1"),Z.searchParams.set("t","blade-code"),Z.searchParams.set("kl","us-en"),Z.toString()},parseResponse:S_,getHeaders:()=>({Accept:"application/json, text/plain;q=0.9","User-Agent":"Blade-AI-WebSearch/1.0"})};fG=["https://searx.be","https://search.ononoki.org","https://searx.tiekoetter.com","https://searx.work"];I4={BASE_URL:"https://mcp.exa.ai",ENDPOINT:"/mcp",DEFAULT_NUM_RESULTS:10,TIMEOUT:25000}});import{ProxyAgent as m_,fetch as d_}from"undici";import{z as Y8}from"zod";function c_(){let $=process.env.HTTPS_PROXY||process.env.HTTP_PROXY||process.env.https_proxy||process.env.http_proxy;if($)try{return new m_($)}catch(Z){console.warn(`Invalid proxy URL: ${$}`)}return}async function l_($,Z,Y,Q,X){let J=new AbortController,G=setTimeout(()=>J.abort(),Y),K=()=>J.abort();Q?.addEventListener("abort",K);try{return await d_($,{...Z,signal:J.signal,dispatcher:X})}catch(q){if(q.name==="AbortError")throw Error("搜索请求超时或被中止");throw q}finally{clearTimeout(G),Q?.removeEventListener("abort",K)}}async function i_($,Z,Y,Q,X,J){let G=null;for(let K=0;K<U3.maxRetries;K++)try{return await l_($,Z,Y,Q,X)}catch(q){if(G=q,Q?.aborted)throw q;if(K<U3.maxRetries-1){let W=Math.min(U3.baseDelay*Math.pow(2,K),U3.maxDelay);J?.(`⏳ 请求失败,${W/1000}s 后重试 (${K+1}/${U3.maxRetries})...`),await new Promise((U)=>setTimeout(U,W))}}throw G}async function a_($,Z,Y,Q,X,J){let G=TG(),K=G.get($.name,Z);if(K)return J?.(`\uD83D\uDCBE 使用缓存结果 (${$.name})`),{results:K,providerName:`${$.name} (cached)`};if($.searchFn)try{J?.(`\uD83D\uDD0D 搜索中 (${$.name})...`);let B=await $.searchFn(Z);return G.set($.name,Z,B),{results:B,providerName:$.name}}catch(B){throw Error(`SDK search failed: ${B.message}`)}J?.(`\uD83D\uDD0D 搜索中 (${$.name})...`);let q=$.buildUrl(Z),W=$.method||"GET",H={headers:$.getHeaders(),method:W};if(W==="POST"&&$.buildBody)H.body=JSON.stringify($.buildBody(Z));let F=await i_(q,H,Y,Q,X,J);if(!F.ok)throw Error(`HTTP ${F.status}`);let O=await F.text(),z;try{z=JSON.parse(O)}catch{throw Error("Failed to parse search result JSON")}let _=$.parseResponse(z);return G.set($.name,Z,_),{results:_,providerName:$.name}}async function r_($,Z,Y,Q){let X=hG(),J=c_(),G=[];for(let K=0;K<X.length;K++){let q=X[K];if(Y?.aborted)throw Error("搜索被用户中止");try{return Q?.(`\uD83D\uDD0E 使用 ${q.name} 搜索...`),await a_(q,$,Z,Y,J,Q)}catch(W){let U=W,H=`${q.name}: ${U.message}`;if(G.push(H),Q?.(`⚠️ ${H}`),K===X.length-1)throw Error(`所有搜索提供商都失败了:
2050
2050
  ${G.join(`
2051
2051
  `)}`)}}throw Error("No search providers available")}function n_($){try{return new URL($).hostname.toLowerCase()}catch{return null}}function o_($){return $.trim().toLowerCase()}function mG($){if(!$||$.length===0)return[];return $.map(o_).filter(Boolean)}function dG($,Z){return $===Z||$.endsWith(`.${Z}`)}function s_($,Z,Y){return $.filter((Q)=>{let X=n_(Q.url);if(!X)return!1;if(Y.length>0&&Y.some((J)=>dG(X,J)))return!1;if(Z.length>0&&!Z.some((J)=>dG(X,J)))return!1;return!0})}function t_($,Z,Y,Q){let X=`\uD83D\uDD0E WebSearch("${$}") via ${Q} - 返回 ${Z.length}/${Y} 条结果`,J=Z.map((G,K)=>`${K+1}. ${G.title}
2052
2052
  ${G.display_url}
2053
2053
  ${G.snippet}`);return[X,...J].join(`
2054
- `)}function e_($){let Z=$.trim().toLowerCase();return Z.length>80?Z.slice(0,80):Z}var u_=15000,g_=8,U8,m5;var uG=A(()=>{p$();j0();CG();pG();U8={maxRetries:3,baseDelay:1000,maxDelay:8000};m5=t({name:"WebSearch",displayName:"Web Search",kind:"readonly",schema:Y3.object({query:Y3.string().min(2,"Search query must be at least 2 characters").describe("Search query"),allowed_domains:Y3.array(Y3.string().min(1)).optional().describe("Return results only from these domains (optional)"),blocked_domains:Y3.array(Y3.string().min(1)).optional().describe("Exclude results from these domains (optional)")}),description:{short:"Search the web and use the results to inform responses",long:`
2054
+ `)}function e_($){let Z=$.trim().toLowerCase();return Z.length>80?Z.slice(0,80):Z}var u_=15000,g_=8,U3,m5;var uG=A(()=>{p$();j0();CG();pG();U3={maxRetries:3,baseDelay:1000,maxDelay:8000};m5=t({name:"WebSearch",displayName:"Web Search",kind:"readonly",schema:Y8.object({query:Y8.string().min(2,"Search query must be at least 2 characters").describe("Search query"),allowed_domains:Y8.array(Y8.string().min(1)).optional().describe("Return results only from these domains (optional)"),blocked_domains:Y8.array(Y8.string().min(1)).optional().describe("Exclude results from these domains (optional)")}),description:{short:"Search the web and use the results to inform responses",long:`
2055
2055
  - Search the web and use the results to inform responses
2056
2056
  - Provides up-to-date information for current events and recent data
2057
2057
  - Returns search result information formatted as search result blocks, including links as markdown hyperlinks
@@ -2079,11 +2079,11 @@ Usage notes:
2079
2079
  IMPORTANT - Use the correct year in search queries:
2080
2080
  - You MUST use the current year when searching for recent information, documentation, or current events.
2081
2081
  - Example: If the user asks for "latest React docs", search for "React documentation 2025", NOT "React documentation 2024"
2082
- `},async execute($,Z){let{query:Y}=$,Q=mG($.allowed_domains),X=mG($.blocked_domains),{updateOutput:J}=Z,G=Z.signal??new AbortController().signal;J?.(`\uD83D\uDD0E Searching: "${Y}" (${xG()} providers available)`);try{let{results:K,providerName:q}=await r_(Y,u_,G,J),W=s_(K,Q,X),U=W.slice(0,g_),H={query:Y,results:U,provider:q,total_results:W.length,fetched_at:new Date().toISOString()},F={query:Y,provider:q,fetched_at:H.fetched_at,total_results:W.length,returned_results:U.length,allowed_domains:Q,blocked_domains:X};if(U.length===0)return{success:!0,llmContent:H,displayContent:`\uD83D\uDD0D WebSearch("${Y}") via ${q} - 未找到匹配结果`,metadata:F};return{success:!0,llmContent:H,displayContent:t_(Y,U,W.length,q),metadata:F}}catch(K){let q=K;return{success:!1,llmContent:`WebSearch call failed: ${q.message}`,displayContent:`❌ WebSearch 调用失败: ${q.message}`,error:{type:"execution_error",message:q.message,details:{query:Y,allowedDomains:Q,blockedDomains:X}}}}},version:"2.0.0",category:"网络工具",tags:["web","search","internet","news"],extractSignatureContent:($)=>`search:${e_($.query)}`,abstractPermissionRule:()=>"search:*"})});var gG=A(()=>{vG();uG()});import*as cG from"os";import*as lG from"path";async function $B(){try{return await b0.getInstance().getAvailableTools()}catch($){return console.warn("MCP协议工具加载失败:",$),[]}}async function iG($){let Z=$?.sessionId||`session_${Date.now()}`,Y=$?.configDir||lG.join(cG.homedir(),".blade"),Q=[Z5,$5,Q5,X5,U5,O5,B5,L5,p5,m5,k5,f5,h5({sessionId:Z,configDir:Y}),J5,K5,...aJ,A5,V5,E5],X=await $B();return[...Q,...X]}var aG=A(()=>{e2();KJ();WJ();zJ();RJ();yJ();rJ();JG();wG();DG();gG()});import{nanoid as ZB}from"nanoid";class d5{name="hook";hookManager;constructor(){this.hookManager=M$.getInstance()}async process($){if(!this.hookManager.isEnabled())return;let Z=$._internal.tool;if(!Z)return;try{let Y=$.context.messageId||`tool_${ZB()}`;$._internal.hookToolUseId=Y;let Q=$.context.workspaceRoot||process.cwd(),X=await this.hookManager.executePreToolHooks(Z.name,Y,$.params,{projectDir:Q,sessionId:$.context.sessionId||"unknown",permissionMode:$.context.permissionMode??"default",abortSignal:$.context.signal});if(X.decision==="deny"){$.abort(X.reason||"Hook blocked execution");return}if(X.decision==="ask"){$._internal.needsConfirmation=!0,$._internal.confirmationReason=X.reason||"Hook requires confirmation";return}if(X.modifiedInput){let J={...$.params,...X.modifiedInput};if(Z.build)try{Z.build(J),$.params=J}catch(G){$.abort(`Hook modified parameters are invalid: ${G instanceof Error?G.message:String(G)}`);return}}if(X.warning)console.warn(`[Hook Warning] ${X.warning}`)}catch(Y){console.error("[HookStage] Error executing hooks:",Y)}}}var rG=A(()=>{U0();t0()});import{nanoid as YB}from"nanoid";function QB($){return typeof $==="object"&&$!==null&&!Array.isArray($)}class u5{name="post-hook";hookManager;constructor(){this.hookManager=M$.getInstance()}async process($){if(!this.hookManager.isEnabled())return;let Z=$._internal.tool;if(!Z)return;let Y=$.getResult();if(!Y)return;try{let Q=$._internal.hookToolUseId||$.context.messageId||`tool_${YB()}`,X=$.context.workspaceRoot||process.cwd(),J=await this.hookManager.executePostToolHooks(Z.name,Q,$.params,Y,{projectDir:X,sessionId:$.context.sessionId||"unknown",permissionMode:$.context.permissionMode??"default",abortSignal:$.context.signal});if(J.additionalContext){let G=Y.llmContent||Y.displayContent||"";Y.llmContent=`${G}
2082
+ `},async execute($,Z){let{query:Y}=$,Q=mG($.allowed_domains),X=mG($.blocked_domains),{updateOutput:J}=Z,G=Z.signal??new AbortController().signal;J?.(`\uD83D\uDD0E Searching: "${Y}" (${xG()} providers available)`);try{let{results:K,providerName:q}=await r_(Y,u_,G,J),W=s_(K,Q,X),U=W.slice(0,g_),H={query:Y,results:U,provider:q,total_results:W.length,fetched_at:new Date().toISOString()},F={query:Y,provider:q,fetched_at:H.fetched_at,total_results:W.length,returned_results:U.length,allowed_domains:Q,blocked_domains:X};if(U.length===0)return{success:!0,llmContent:H,displayContent:`\uD83D\uDD0D WebSearch("${Y}") via ${q} - 未找到匹配结果`,metadata:F};return{success:!0,llmContent:H,displayContent:t_(Y,U,W.length,q),metadata:F}}catch(K){let q=K;return{success:!1,llmContent:`WebSearch call failed: ${q.message}`,displayContent:`❌ WebSearch 调用失败: ${q.message}`,error:{type:"execution_error",message:q.message,details:{query:Y,allowedDomains:Q,blockedDomains:X}}}}},version:"2.0.0",category:"网络工具",tags:["web","search","internet","news"],extractSignatureContent:($)=>`search:${e_($.query)}`,abstractPermissionRule:()=>"search:*"})});var gG=A(()=>{vG();uG()});import*as cG from"os";import*as lG from"path";async function $B(){try{return await b0.getInstance().getAvailableTools()}catch($){return console.warn("MCP协议工具加载失败:",$),[]}}async function iG($){let Z=$?.sessionId||`session_${Date.now()}`,Y=$?.configDir||lG.join(cG.homedir(),".blade"),Q=[Z5,$5,Q5,X5,U5,O5,B5,L5,p5,m5,k5,f5,h5({sessionId:Z,configDir:Y}),J5,K5,...aJ,A5,V5,E5],X=await $B();return[...Q,...X]}var aG=A(()=>{e4();KJ();WJ();zJ();RJ();yJ();rJ();JG();wG();DG();gG()});import{nanoid as ZB}from"nanoid";class d5{name="hook";hookManager;constructor(){this.hookManager=M$.getInstance()}async process($){if(!this.hookManager.isEnabled())return;let Z=$._internal.tool;if(!Z)return;try{let Y=$.context.messageId||`tool_${ZB()}`;$._internal.hookToolUseId=Y;let Q=$.context.workspaceRoot||process.cwd(),X=await this.hookManager.executePreToolHooks(Z.name,Y,$.params,{projectDir:Q,sessionId:$.context.sessionId||"unknown",permissionMode:$.context.permissionMode??"default",abortSignal:$.context.signal});if(X.decision==="deny"){$.abort(X.reason||"Hook blocked execution");return}if(X.decision==="ask"){$._internal.needsConfirmation=!0,$._internal.confirmationReason=X.reason||"Hook requires confirmation";return}if(X.modifiedInput){let J={...$.params,...X.modifiedInput};if(Z.build)try{Z.build(J),$.params=J}catch(G){$.abort(`Hook modified parameters are invalid: ${G instanceof Error?G.message:String(G)}`);return}}if(X.warning)console.warn(`[Hook Warning] ${X.warning}`)}catch(Y){console.error("[HookStage] Error executing hooks:",Y)}}}var rG=A(()=>{U0();t0()});import{nanoid as YB}from"nanoid";function QB($){return typeof $==="object"&&$!==null&&!Array.isArray($)}class u5{name="post-hook";hookManager;constructor(){this.hookManager=M$.getInstance()}async process($){if(!this.hookManager.isEnabled())return;let Z=$._internal.tool;if(!Z)return;let Y=$.getResult();if(!Y)return;try{let Q=$._internal.hookToolUseId||$.context.messageId||`tool_${YB()}`,X=$.context.workspaceRoot||process.cwd(),J=await this.hookManager.executePostToolHooks(Z.name,Q,$.params,Y,{projectDir:X,sessionId:$.context.sessionId||"unknown",permissionMode:$.context.permissionMode??"default",abortSignal:$.context.signal});if(J.additionalContext){let G=Y.llmContent||Y.displayContent||"";Y.llmContent=`${G}
2083
2083
 
2084
2084
  ---
2085
2085
  **Hook Context:**
2086
- ${J.additionalContext}`}if(J.modifiedOutput!==void 0){let G=J.modifiedOutput;if(QB(G))Object.assign(Y,G)}if(J.warning)console.warn(`[PostToolUseHook Warning] ${J.warning}`)}catch(Q){console.error("[PostToolUseHookStage] Error executing post-tool hooks:",Q)}}}var nG=A(()=>{U0();t0()});class y2{static instance=null;locks=new Map;constructor(){}static getInstance(){if(!y2.instance)y2.instance=new y2;return y2.instance}async acquireLock($,Z){let Y=this.locks.get($);if(Y)try{await Y}catch{}let Q=this.executeWithLock($,Z);return this.locks.set($,Q.then(()=>{return})),Q}async executeWithLock($,Z){g5.debug(`获取文件锁: ${$}`);try{let Y=await Z();return g5.debug(`释放文件锁: ${$}`),Y}catch(Y){throw g5.debug(`操作失败,释放文件锁: ${$}`),Y}}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(){y2.instance=null}}var g5;var oG=A(()=>{O$();g5=l("Execution")});import H8 from"picomatch";class Q3{config;constructor($){this.config=$}check($){let Z=Q3.buildSignature($),Y=this.matchRules(Z,this.config.deny);if(Y)return{result:"deny",matchedRule:Y.rule,matchType:Y.type,reason:`工具调用被拒绝规则阻止: ${Y.rule}`};let Q=this.matchRules(Z,this.config.allow);if(Q)return{result:"allow",matchedRule:Q.rule,matchType:Q.type,reason:`工具调用符合允许规则: ${Q.rule}`};let X=this.matchRules(Z,this.config.ask);if(X)return{result:"ask",matchedRule:X.rule,matchType:X.type,reason:`工具调用需要用户确认: ${X.rule}`};return{result:"ask",reason:"工具调用未匹配任何规则,默认需要确认"}}static buildSignature($){let{toolName:Z,params:Y,tool:Q}=$;try{if(Q?.extractSignatureContent){let X=Q.extractSignatureContent(Y);return X?`${Z}(${X})`:Z}return Z}catch(X){return console.warn(`Failed to build signature for ${Z}:`,X instanceof Error?X.message:X),Z}}static abstractPattern($){let{toolName:Z,params:Y,tool:Q}=$;try{if(Q?.abstractPermissionRule){let X=Q.abstractPermissionRule(Y);if(X==="")return"";return X?`${Z}(${X})`:Z}return Z}catch(X){return console.warn(`Failed to abstract pattern for ${Z}:`,X instanceof Error?X.message:X),Z}}matchRules($,Z){for(let Y of Z){let Q=this.matchRule($,Y);if(Q)return{rule:Y,type:Q}}return null}matchRule($,Z){if($===Z)return"exact";if(Z==="*"||Z==="**")return"wildcard";let Y=this.extractToolName($),Q=this.extractToolName(Z);if(!Y||!Q)return null;if(Q.includes("*")){if(!H8.isMatch(Y,Q,{dot:!0,bash:!0}))return null}else if(Y!==Q)return null;if(Z===Q)return"prefix";if(Z.includes("*")){let X=this.extractParams($),J=this.extractParams(Z);if(J==="*"||J==="**")return"wildcard";if(this.matchParams(X,J))return J.includes("**")?"glob":"wildcard";if(H8.isMatch($,Z,{dot:!0,bash:!0}))return Z.includes("**")?"glob":"wildcard"}return null}extractParams($){let Z=$.match(/\(([\s\S]*)\)$/);return Z?Z[1]:""}matchParams($,Z){if(!$||!Z)return!1;let Y=this.parseParamPairs($),Q=this.parseParamPairs(Z),X=Object.keys(Q).length>0,J=Object.keys(Y).length>0;if(X!==J)return!1;if(!X&&!J){if(Z==="*"||Z==="**")return!0;if(Z.includes("*")||Z.includes("{")||Z.includes("?"))return H8.isMatch($,Z,{dot:!0,bash:!0});return $===Z}for(let[G,K]of Object.entries(Q)){let q=Y[G];if(q===void 0)return!1;if(K.includes("*")||K.includes("{")||K.includes("?")){if(K==="*"||K==="**")continue;if(!H8.isMatch(q,K,{dot:!0,bash:!0}))return!1}else if(q!==K)return!1}return!0}parseParamPairs($){let Z={},Y=this.smartSplit($,",");for(let Q of Y){let X=this.findTopLevelDelimiter(Q,":");if(X>0){let J=Q.slice(0,X).trim(),G=Q.slice(X+1).trim();Z[J]=G}}return Z}smartSplit($,Z){let Y=[],Q="",X=0,J=0,G=0,K=!1,q="",W=!1;for(let U=0;U<$.length;U++){let H=$[U];if(W){Q+=H,W=!1;continue}if(H==="\\"){Q+=H,W=!0;continue}if(!K&&H==="{")X++;else if(!K&&H==="}")X--;else if(!K&&H==="(")J++;else if(!K&&H===")")J--;else if(!K&&H==="[")G++;else if(!K&&H==="]")G--;if((H==='"'||H==="'")&&!K){K=!0,q=H,Q+=H;continue}else if(K&&H===q){K=!1,q="",Q+=H;continue}if(H===Z&&X===0&&J===0&&G===0&&!K)Y.push(Q.trim()),Q="";else Q+=H}if(Q)Y.push(Q.trim());return Y}findTopLevelDelimiter($,Z){let Y=0,Q=0,X=0,J=!1,G="",K=!1;for(let q=0;q<$.length;q++){let W=$[q];if(K){K=!1;continue}if(W==="\\"){K=!0;continue}if(!J&&W==="{")Y++;else if(!J&&W==="}")Y--;else if(!J&&W==="(")Q++;else if(!J&&W===")")Q--;else if(!J&&W==="[")X++;else if(!J&&W==="]")X--;if((W==='"'||W==="'")&&!J){J=!0,G=W;continue}else if(J&&W===G){J=!1,G="";continue}if(W===Z&&Y===0&&Q===0&&X===0&&!J)return q}return-1}extractToolName($){let Z=$.match(/^([A-Za-z0-9_]+)(\(|$)/);return Z?Z[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 sG=()=>{};import XB from"node:os";import c5 from"node:path";var l5;var tG=A(()=>{l5=class l5{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 Z=this.normalizePath($),Y=c5.basename(Z);for(let Q of this.SENSITIVE_PATTERNS)if(this.matchPattern(Y,Q.pattern))return{isSensitive:!0,level:Q.level,matchedPattern:Q.pattern instanceof RegExp?Q.pattern.source:Q.pattern,reason:Q.description};for(let Q of this.SENSITIVE_PATHS)if(this.matchPattern(Z,Q.path))return{isSensitive:!0,level:Q.level,matchedPattern:Q.path instanceof RegExp?Q.path.source:Q.path,reason:Q.description};return{isSensitive:!1}}static checkMultiple($){let Z=new Map;for(let Y of $)Z.set(Y,this.check(Y));return Z}static filterSensitive($,Z="low"){let Y={["high"]:3,["medium"]:2,["low"]:1},Q=Y[Z];return $.map((X)=>({path:X,result:this.check(X)})).filter(({result:X})=>X.isSensitive&&X.level&&Y[X.level]>=Q)}static normalizePath($){if($.startsWith("~/")||$==="~")return c5.join(XB.homedir(),$.slice(1));return c5.resolve($)}static matchPattern($,Z){if(Z instanceof RegExp)return Z.test($);let Y=Z.replace(/\*/g,".*");return new RegExp(`^${Y}$`,"i").test($)}static getSensitivePatterns(){return[...this.SENSITIVE_PATTERNS]}static getSensitivePaths(){return[...this.SENSITIVE_PATHS]}}});class i5{registry;name="discovery";constructor($){this.registry=$}async process($){let Z=this.registry.get($.toolName);if(!Z){$.abort(`Tool "${$.toolName}" not found`);return}$._internal.tool=Z}}class a5{name="permission";permissionChecker;sessionApprovals;defaultPermissionMode;constructor($,Z,Y){this.permissionChecker=new Q3($),this.sessionApprovals=Z,this.defaultPermissionMode=Y}getPermissionChecker(){return this.permissionChecker}async process($){let Z=$._internal.tool;if(!Z){$.abort("Discovery stage failed; cannot perform permission check");return}try{let Y=Z.build($.params),Q=Y.getAffectedPaths(),X={toolName:Z.name,params:$.params,affectedPaths:Q,tool:Z},J=Q3.buildSignature(X);$._internal.permissionSignature=J;let G=this.permissionChecker.check(X),K=$.context.permissionMode||this.defaultPermissionMode;switch(G=this.applyModeOverrides(Z.kind,G,K),G.result){case"deny":$.abort(G.reason||`Tool invocation "${Z.name}" was denied by permission rules: ${G.matchedRule}`);return;case"ask":if(this.sessionApprovals.has(J))G={result:"allow",matchedRule:"remembered:session",reason:"User already allowed this operation in this session"};else $._internal.needsConfirmation=!0,$._internal.confirmationReason=G.reason||"User confirmation required";break;case"allow":break}if(Q.length>0){let q=["/etc/","/sys/","/proc/","/dev/","/boot/","/root/","C:\\Windows\\System32","C:\\Program Files","C:\\ProgramData"],W=Q.filter((H)=>{if(H.includes(".."))return!0;return q.some((F)=>H.includes(F))});if(W.length>0){$.abort(`Access to dangerous system paths denied: ${W.join(", ")}`);return}let U=l5.filterSensitive(Q,"medium");if(U.length>0){let H=U.map(({path:O,result:z})=>`${O} (${z.level}: ${z.reason})`);if(U.filter(({result:O})=>O.level==="high").length>0&&G.result!=="allow"){$.abort(`Access to highly sensitive files denied:
2086
+ ${J.additionalContext}`}if(J.modifiedOutput!==void 0){let G=J.modifiedOutput;if(QB(G))Object.assign(Y,G)}if(J.warning)console.warn(`[PostToolUseHook Warning] ${J.warning}`)}catch(Q){console.error("[PostToolUseHookStage] Error executing post-tool hooks:",Q)}}}var nG=A(()=>{U0();t0()});class y4{static instance=null;locks=new Map;constructor(){}static getInstance(){if(!y4.instance)y4.instance=new y4;return y4.instance}async acquireLock($,Z){let Y=this.locks.get($);if(Y)try{await Y}catch{}let Q=this.executeWithLock($,Z);return this.locks.set($,Q.then(()=>{return})),Q}async executeWithLock($,Z){g5.debug(`获取文件锁: ${$}`);try{let Y=await Z();return g5.debug(`释放文件锁: ${$}`),Y}catch(Y){throw g5.debug(`操作失败,释放文件锁: ${$}`),Y}}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(){y4.instance=null}}var g5;var oG=A(()=>{O$();g5=l("Execution")});import H3 from"picomatch";class Q8{config;constructor($){this.config=$}check($){let Z=Q8.buildSignature($),Y=this.matchRules(Z,this.config.deny);if(Y)return{result:"deny",matchedRule:Y.rule,matchType:Y.type,reason:`工具调用被拒绝规则阻止: ${Y.rule}`};let Q=this.matchRules(Z,this.config.allow);if(Q)return{result:"allow",matchedRule:Q.rule,matchType:Q.type,reason:`工具调用符合允许规则: ${Q.rule}`};let X=this.matchRules(Z,this.config.ask);if(X)return{result:"ask",matchedRule:X.rule,matchType:X.type,reason:`工具调用需要用户确认: ${X.rule}`};return{result:"ask",reason:"工具调用未匹配任何规则,默认需要确认"}}static buildSignature($){let{toolName:Z,params:Y,tool:Q}=$;try{if(Q?.extractSignatureContent){let X=Q.extractSignatureContent(Y);return X?`${Z}(${X})`:Z}return Z}catch(X){return console.warn(`Failed to build signature for ${Z}:`,X instanceof Error?X.message:X),Z}}static abstractPattern($){let{toolName:Z,params:Y,tool:Q}=$;try{if(Q?.abstractPermissionRule){let X=Q.abstractPermissionRule(Y);if(X==="")return"";return X?`${Z}(${X})`:Z}return Z}catch(X){return console.warn(`Failed to abstract pattern for ${Z}:`,X instanceof Error?X.message:X),Z}}matchRules($,Z){for(let Y of Z){let Q=this.matchRule($,Y);if(Q)return{rule:Y,type:Q}}return null}matchRule($,Z){if($===Z)return"exact";if(Z==="*"||Z==="**")return"wildcard";let Y=this.extractToolName($),Q=this.extractToolName(Z);if(!Y||!Q)return null;if(Q.includes("*")){if(!H3.isMatch(Y,Q,{dot:!0,bash:!0}))return null}else if(Y!==Q)return null;if(Z===Q)return"prefix";if(Z.includes("*")){let X=this.extractParams($),J=this.extractParams(Z);if(J==="*"||J==="**")return"wildcard";if(this.matchParams(X,J))return J.includes("**")?"glob":"wildcard";if(H3.isMatch($,Z,{dot:!0,bash:!0}))return Z.includes("**")?"glob":"wildcard"}return null}extractParams($){let Z=$.match(/\(([\s\S]*)\)$/);return Z?Z[1]:""}matchParams($,Z){if(!$||!Z)return!1;let Y=this.parseParamPairs($),Q=this.parseParamPairs(Z),X=Object.keys(Q).length>0,J=Object.keys(Y).length>0;if(X!==J)return!1;if(!X&&!J){if(Z==="*"||Z==="**")return!0;if(Z.includes("*")||Z.includes("{")||Z.includes("?"))return H3.isMatch($,Z,{dot:!0,bash:!0});return $===Z}for(let[G,K]of Object.entries(Q)){let q=Y[G];if(q===void 0)return!1;if(K.includes("*")||K.includes("{")||K.includes("?")){if(K==="*"||K==="**")continue;if(!H3.isMatch(q,K,{dot:!0,bash:!0}))return!1}else if(q!==K)return!1}return!0}parseParamPairs($){let Z={},Y=this.smartSplit($,",");for(let Q of Y){let X=this.findTopLevelDelimiter(Q,":");if(X>0){let J=Q.slice(0,X).trim(),G=Q.slice(X+1).trim();Z[J]=G}}return Z}smartSplit($,Z){let Y=[],Q="",X=0,J=0,G=0,K=!1,q="",W=!1;for(let U=0;U<$.length;U++){let H=$[U];if(W){Q+=H,W=!1;continue}if(H==="\\"){Q+=H,W=!0;continue}if(!K&&H==="{")X++;else if(!K&&H==="}")X--;else if(!K&&H==="(")J++;else if(!K&&H===")")J--;else if(!K&&H==="[")G++;else if(!K&&H==="]")G--;if((H==='"'||H==="'")&&!K){K=!0,q=H,Q+=H;continue}else if(K&&H===q){K=!1,q="",Q+=H;continue}if(H===Z&&X===0&&J===0&&G===0&&!K)Y.push(Q.trim()),Q="";else Q+=H}if(Q)Y.push(Q.trim());return Y}findTopLevelDelimiter($,Z){let Y=0,Q=0,X=0,J=!1,G="",K=!1;for(let q=0;q<$.length;q++){let W=$[q];if(K){K=!1;continue}if(W==="\\"){K=!0;continue}if(!J&&W==="{")Y++;else if(!J&&W==="}")Y--;else if(!J&&W==="(")Q++;else if(!J&&W===")")Q--;else if(!J&&W==="[")X++;else if(!J&&W==="]")X--;if((W==='"'||W==="'")&&!J){J=!0,G=W;continue}else if(J&&W===G){J=!1,G="";continue}if(W===Z&&Y===0&&Q===0&&X===0&&!J)return q}return-1}extractToolName($){let Z=$.match(/^([A-Za-z0-9_]+)(\(|$)/);return Z?Z[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 sG=()=>{};import XB from"node:os";import c5 from"node:path";var l5;var tG=A(()=>{l5=class l5{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 Z=this.normalizePath($),Y=c5.basename(Z);for(let Q of this.SENSITIVE_PATTERNS)if(this.matchPattern(Y,Q.pattern))return{isSensitive:!0,level:Q.level,matchedPattern:Q.pattern instanceof RegExp?Q.pattern.source:Q.pattern,reason:Q.description};for(let Q of this.SENSITIVE_PATHS)if(this.matchPattern(Z,Q.path))return{isSensitive:!0,level:Q.level,matchedPattern:Q.path instanceof RegExp?Q.path.source:Q.path,reason:Q.description};return{isSensitive:!1}}static checkMultiple($){let Z=new Map;for(let Y of $)Z.set(Y,this.check(Y));return Z}static filterSensitive($,Z="low"){let Y={["high"]:3,["medium"]:2,["low"]:1},Q=Y[Z];return $.map((X)=>({path:X,result:this.check(X)})).filter(({result:X})=>X.isSensitive&&X.level&&Y[X.level]>=Q)}static normalizePath($){if($.startsWith("~/")||$==="~")return c5.join(XB.homedir(),$.slice(1));return c5.resolve($)}static matchPattern($,Z){if(Z instanceof RegExp)return Z.test($);let Y=Z.replace(/\*/g,".*");return new RegExp(`^${Y}$`,"i").test($)}static getSensitivePatterns(){return[...this.SENSITIVE_PATTERNS]}static getSensitivePaths(){return[...this.SENSITIVE_PATHS]}}});class i5{registry;name="discovery";constructor($){this.registry=$}async process($){let Z=this.registry.get($.toolName);if(!Z){$.abort(`Tool "${$.toolName}" not found`);return}$._internal.tool=Z}}class a5{name="permission";permissionChecker;sessionApprovals;defaultPermissionMode;constructor($,Z,Y){this.permissionChecker=new Q8($),this.sessionApprovals=Z,this.defaultPermissionMode=Y}getPermissionChecker(){return this.permissionChecker}async process($){let Z=$._internal.tool;if(!Z){$.abort("Discovery stage failed; cannot perform permission check");return}try{let Y=Z.build($.params),Q=Y.getAffectedPaths(),X={toolName:Z.name,params:$.params,affectedPaths:Q,tool:Z},J=Q8.buildSignature(X);$._internal.permissionSignature=J;let G=this.permissionChecker.check(X),K=$.context.permissionMode||this.defaultPermissionMode;switch(G=this.applyModeOverrides(Z.kind,G,K),G.result){case"deny":$.abort(G.reason||`Tool invocation "${Z.name}" was denied by permission rules: ${G.matchedRule}`);return;case"ask":if(this.sessionApprovals.has(J))G={result:"allow",matchedRule:"remembered:session",reason:"User already allowed this operation in this session"};else $._internal.needsConfirmation=!0,$._internal.confirmationReason=G.reason||"User confirmation required";break;case"allow":break}if(Q.length>0){let q=["/etc/","/sys/","/proc/","/dev/","/boot/","/root/","C:\\Windows\\System32","C:\\Program Files","C:\\ProgramData"],W=Q.filter((H)=>{if(H.includes(".."))return!0;return q.some((F)=>H.includes(F))});if(W.length>0){$.abort(`Access to dangerous system paths denied: ${W.join(", ")}`);return}let U=l5.filterSensitive(Q,"medium");if(U.length>0){let H=U.map(({path:O,result:z})=>`${O} (${z.level}: ${z.reason})`);if(U.filter(({result:O})=>O.level==="high").length>0&&G.result!=="allow"){$.abort(`Access to highly sensitive files denied:
2087
2087
  ${H.join(`
2088
2088
  `)}
2089
2089
 
@@ -2091,7 +2091,7 @@ If access is required, add an explicit allow rule in permissions.`);return}if(G.
2091
2091
  ${H.join(`
2092
2092
  `)}
2093
2093
 
2094
- Confirm to proceed?`,$._internal.needsConfirmation=!0}}$._internal.invocation=Y,$._internal.permissionCheckResult=G}catch(Y){$.abort(`Permission check failed: ${Y.message}`)}}applyModeOverrides($,Z,Y){if(Y==="yolo")return{result:"allow",matchedRule:"mode:yolo",reason:"YOLO mode: automatically approve all tool invocations"};if(Y==="plan"){if(!k3($))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(Z.result==="deny")return Z;if(Z.result==="allow")return Z;if(k3($))return{result:"allow",matchedRule:`mode:${Y}:readonly`,reason:"Read-only tools do not require confirmation"};if(Y==="autoEdit"&&$==="write")return{result:"allow",matchedRule:"mode:autoEdit:write",reason:"AUTO_EDIT mode: automatically approve write tools"};return Z}}class r5{sessionApprovals;name="confirmation";permissionChecker;constructor($,Z){this.sessionApprovals=$;this.permissionChecker=Z}async process($){let{tool:Z,invocation:Y,needsConfirmation:Q,confirmationReason:X,permissionCheckResult:J}=$._internal;if(!Z||!Y){$.abort("Pre-confirmation stage failed; cannot request user approval");return}if(!Q)return;try{let G=Z.extractSignatureContent?Z.extractSignatureContent($.params):Z.name,K=M$.getInstance();if(K.isEnabled()){let U=await K.executePermissionRequestHooks(Z.name,$.context.sessionId||"unknown",$.params,{projectDir:process.cwd(),sessionId:$.context.sessionId||"unknown",permissionMode:$.context.permissionMode||"default"});switch(U.decision){case"approve":v2.debug(`PermissionRequest hook 自动批准: ${Z.name}`);return;case"deny":$.abort(U.reason||`PermissionRequest hook denied: ${Z.name}`,{shouldExitLoop:!0});return;case"ask":default:break}}let q={title:`权限确认: ${G}`,message:X||"此操作需要用户确认",kind:Z.kind,details:this.generatePreviewForTool(Z.name,$.params),risks:this.extractRisksFromPermissionCheck(Z,$.params,J),affectedFiles:Y.getAffectedPaths()||[]};if(v2.warn(`工具 "${Z.name}" 需要用户确认: ${q.title}`),v2.warn(`详情: ${q.message}`),q.risks&&q.risks.length>0)v2.warn(`风险: ${q.risks.join(", ")}`);let W=$.context.confirmationHandler;if(W){let U=await W.requestConfirmation(q);if(!U.approved){$.abort(`User rejected execution: ${U.reason||"No reason provided"}`,{shouldExitLoop:!0});return}if((U.scope||"once")==="session"&&$._internal.permissionSignature){let F=$._internal.permissionSignature;this.sessionApprovals.add(F);let O={toolName:Z.name,params:$.params,affectedPaths:Y.getAffectedPaths()||[],tool:Z};await this.persistSessionApproval(F,O)}}else v2.warn("⚠️ No ConfirmationHandler; auto-approving tool execution (non-interactive environment only)")}catch(G){$.abort(`User confirmation failed: ${G.message}`)}}async persistSessionApproval($,Z){try{let Y=Q3.abstractPattern(Z);v2.debug(`保存权限规则: "${Y}"`),await x$().appendLocalPermissionAllowRule(Y,{immediate:!0});let Q=H0();if(Q?.permissions)v2.debug("同步权限配置到 PermissionChecker:",Q.permissions),this.permissionChecker.replaceConfig(Q.permissions)}catch(Y){v2.warn(`Failed to persist permission rule "${$}": ${Y instanceof Error?Y.message:"Unknown error"}`)}}generatePreviewForTool($,Z){switch($){case"Edit":{let{old_string:Y,new_string:Q}=Z;if(!Y&&!Q)return;let X=20,J=(G)=>{let K=G.split(`
2094
+ Confirm to proceed?`,$._internal.needsConfirmation=!0}}$._internal.invocation=Y,$._internal.permissionCheckResult=G}catch(Y){$.abort(`Permission check failed: ${Y.message}`)}}applyModeOverrides($,Z,Y){if(Y==="yolo")return{result:"allow",matchedRule:"mode:yolo",reason:"YOLO mode: automatically approve all tool invocations"};if(Y==="plan"){if(!k8($))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(Z.result==="deny")return Z;if(Z.result==="allow")return Z;if(k8($))return{result:"allow",matchedRule:`mode:${Y}:readonly`,reason:"Read-only tools do not require confirmation"};if(Y==="autoEdit"&&$==="write")return{result:"allow",matchedRule:"mode:autoEdit:write",reason:"AUTO_EDIT mode: automatically approve write tools"};return Z}}class r5{sessionApprovals;name="confirmation";permissionChecker;constructor($,Z){this.sessionApprovals=$;this.permissionChecker=Z}async process($){let{tool:Z,invocation:Y,needsConfirmation:Q,confirmationReason:X,permissionCheckResult:J}=$._internal;if(!Z||!Y){$.abort("Pre-confirmation stage failed; cannot request user approval");return}if(!Q)return;try{let G=Z.extractSignatureContent?Z.extractSignatureContent($.params):Z.name,K=M$.getInstance();if(K.isEnabled()){let U=await K.executePermissionRequestHooks(Z.name,$.context.sessionId||"unknown",$.params,{projectDir:process.cwd(),sessionId:$.context.sessionId||"unknown",permissionMode:$.context.permissionMode||"default"});switch(U.decision){case"approve":v4.debug(`PermissionRequest hook 自动批准: ${Z.name}`);return;case"deny":$.abort(U.reason||`PermissionRequest hook denied: ${Z.name}`,{shouldExitLoop:!0});return;case"ask":default:break}}let q={title:`权限确认: ${G}`,message:X||"此操作需要用户确认",kind:Z.kind,details:this.generatePreviewForTool(Z.name,$.params),risks:this.extractRisksFromPermissionCheck(Z,$.params,J),affectedFiles:Y.getAffectedPaths()||[]};if(v4.warn(`工具 "${Z.name}" 需要用户确认: ${q.title}`),v4.warn(`详情: ${q.message}`),q.risks&&q.risks.length>0)v4.warn(`风险: ${q.risks.join(", ")}`);let W=$.context.confirmationHandler;if(W){let U=await W.requestConfirmation(q);if(!U.approved){$.abort(`User rejected execution: ${U.reason||"No reason provided"}`,{shouldExitLoop:!0});return}if((U.scope||"once")==="session"&&$._internal.permissionSignature){let F=$._internal.permissionSignature;this.sessionApprovals.add(F);let O={toolName:Z.name,params:$.params,affectedPaths:Y.getAffectedPaths()||[],tool:Z};await this.persistSessionApproval(F,O)}}else v4.warn("⚠️ No ConfirmationHandler; auto-approving tool execution (non-interactive environment only)")}catch(G){$.abort(`User confirmation failed: ${G.message}`)}}async persistSessionApproval($,Z){try{let Y=Q8.abstractPattern(Z);v4.debug(`保存权限规则: "${Y}"`),await x$().appendLocalPermissionAllowRule(Y,{immediate:!0});let Q=H0();if(Q?.permissions)v4.debug("同步权限配置到 PermissionChecker:",Q.permissions),this.permissionChecker.replaceConfig(Q.permissions)}catch(Y){v4.warn(`Failed to persist permission rule "${$}": ${Y instanceof Error?Y.message:"Unknown error"}`)}}generatePreviewForTool($,Z){switch($){case"Edit":{let{old_string:Y,new_string:Q}=Z;if(!Y&&!Q)return;let X=20,J=(G)=>{let K=G.split(`
2095
2095
  `);if(K.length<=X)return G;return`${K.slice(0,X).join(`
2096
2096
  `)}
2097
2097
  ... (还有 ${K.length-X} 行)`};return`**变更前:**
@@ -2112,27 +2112,27 @@ ${Y}
2112
2112
  ${G}
2113
2113
  \`\`\`
2114
2114
 
2115
- ... (还有 ${J.length-X} 行)`}case"Bash":case"Shell":return;default:return}}extractRisksFromPermissionCheck($,Z,Y){let Q=[];if(Y?.reason)Q.push(Y.reason);if($.name==="Bash"){let X=Z.command||"",J=X.trim().split(/\s+/)[0];if(J==="cat"||J==="head"||J==="tail")Q.push(`\uD83D\uDCA1 建议使用 Read 工具代替 ${J} 命令(性能更好,支持大文件分页)`);else if(J==="grep"||J==="rg")Q.push("\uD83D\uDCA1 建议使用 Grep 工具代替 grep/rg 命令(支持更强大的过滤和上下文)");else if(J==="find")Q.push("\uD83D\uDCA1 建议使用 Glob 工具代替 find 命令(更快,支持 glob 模式)");else if(J==="sed"||J==="awk")Q.push(`\uD83D\uDCA1 建议使用 Edit 工具代替 ${J} 命令(更安全,支持预览和回滚)`);if(X.includes("rm"))Q.push("⚠️ 此命令可能删除文件");if(X.includes("sudo"))Q.push("⚠️ 此命令需要管理员权限");if(X.includes("git push"))Q.push("⚠️ 此命令将推送代码到远程仓库")}else if($.name==="Write"||$.name==="Edit")Q.push("此操作将修改文件内容");else if($.name==="Delete")Q.push("此操作将永久删除文件");return Q}}class n5{name="execution";async process($){let Z=$._internal.invocation;if(!Z){$.abort("Pre-execution stage failed; cannot run tool");return}try{let Y=await Z.execute($.context.signal??new AbortController().signal,$.context.onProgress,$.context);$.setResult(Y)}catch(Y){$.abort(`Tool execution failed: ${Y.message}`)}}}class o5{name="formatting";async process($){try{let Z=$.getResult();if(!Z.llmContent)Z.llmContent="Execution completed";if(!Z.displayContent)Z.displayContent=Z.success?"执行成功":"执行失败";if(!Z.metadata)Z.metadata={};Z.metadata.executionId=$.context.sessionId,Z.metadata.toolName=$.toolName,Z.metadata.timestamp=Date.now(),$.setResult(Z)}catch(Z){$.abort(`Result formatting failed: ${Z.message}`)}}}var v2;var eG=A(()=>{sG();U0();t0();O$();k$();j0();tG();v2=l("Execution")});import{EventEmitter as JB}from"events";var s5;var $K=A(()=>{U0();t0();rG();nG();o6();w0();oG();eG();s5=class s5 extends JB{registry;stages;executionHistory=[];maxHistorySize;sessionApprovals=new Set;constructor($,Z={}){super();this.registry=$;this.maxHistorySize=Z.maxHistorySize||1000;let Y=Z.permissionConfig||{allow:[],ask:[],deny:[]},Q=Z.permissionMode??"default",X=new a5(Y,this.sessionApprovals,Q);this.stages=[new i5(this.registry),X,new d5,new r5(this.sessionApprovals,X.getPermissionChecker()),new n5,new u5,new o5]}async execute($,Z,Y){let Q=Date.now(),X=this.generateExecutionId(),J=new n6($,Z,{...Y,sessionId:Y.sessionId||X});this.emit("executionStarted",{executionId:X,toolName:$,params:Z,context:Y,timestamp:Q});let G=this.registry.get($),K=G&&!G.isConcurrencySafe,q=K&&Z.file_path?String(Z.file_path):null;if(K&&q)return y2.getInstance().acquireLock(q,()=>this.executeWithPipeline(J,X,Q));return this.executeWithPipeline(J,X,Q)}async executeWithPipeline($,Z,Y){try{for(let J of this.stages){if($.context.signal?.aborted){$.abort("任务已被用户中止");break}if(this.emit("stageStarted",{executionId:Z,stageName:J.name,timestamp:Date.now()}),await J.process($),this.emit("stageCompleted",{executionId:Z,stageName:J.name,timestamp:Date.now()}),$.shouldAbort())break}let Q=$.getResult(),X=Date.now();return this.addToHistory({executionId:Z,toolName:$.toolName,params:$.params,result:Q,startTime:Y,endTime:X,context:$.context}),this.emit("executionCompleted",{executionId:Z,toolName:$.toolName,result:Q,duration:X-Y,timestamp:X}),Q}catch(Q){let X=Date.now(),J=Q.message?.includes("timeout")||Q.name==="TimeoutError",G={success:!1,llmContent:`Tool execution failed: ${Q.message}`,displayContent:`错误: ${Q.message}`,error:{type:"execution_error",message:Q.message}};try{let q=await M$.getInstance().executePostToolUseFailureHooks($.toolName,`tool_use_${Z}`,$.params,Q.message,{projectDir:process.cwd(),sessionId:$.context.sessionId||"unknown",permissionMode:$.context.permissionMode||"default",isInterrupt:!1,isTimeout:J,abortSignal:$.context.signal});if(q.additionalContext)G={...G,llmContent:`${G.llmContent}
2115
+ ... (还有 ${J.length-X} 行)`}case"Bash":case"Shell":return;default:return}}extractRisksFromPermissionCheck($,Z,Y){let Q=[];if(Y?.reason)Q.push(Y.reason);if($.name==="Bash"){let X=Z.command||"",J=X.trim().split(/\s+/)[0];if(J==="cat"||J==="head"||J==="tail")Q.push(`\uD83D\uDCA1 建议使用 Read 工具代替 ${J} 命令(性能更好,支持大文件分页)`);else if(J==="grep"||J==="rg")Q.push("\uD83D\uDCA1 建议使用 Grep 工具代替 grep/rg 命令(支持更强大的过滤和上下文)");else if(J==="find")Q.push("\uD83D\uDCA1 建议使用 Glob 工具代替 find 命令(更快,支持 glob 模式)");else if(J==="sed"||J==="awk")Q.push(`\uD83D\uDCA1 建议使用 Edit 工具代替 ${J} 命令(更安全,支持预览和回滚)`);if(X.includes("rm"))Q.push("⚠️ 此命令可能删除文件");if(X.includes("sudo"))Q.push("⚠️ 此命令需要管理员权限");if(X.includes("git push"))Q.push("⚠️ 此命令将推送代码到远程仓库")}else if($.name==="Write"||$.name==="Edit")Q.push("此操作将修改文件内容");else if($.name==="Delete")Q.push("此操作将永久删除文件");return Q}}class n5{name="execution";async process($){let Z=$._internal.invocation;if(!Z){$.abort("Pre-execution stage failed; cannot run tool");return}try{let Y=await Z.execute($.context.signal??new AbortController().signal,$.context.onProgress,$.context);$.setResult(Y)}catch(Y){$.abort(`Tool execution failed: ${Y.message}`)}}}class o5{name="formatting";async process($){try{let Z=$.getResult();if(!Z.llmContent)Z.llmContent="Execution completed";if(!Z.displayContent)Z.displayContent=Z.success?"执行成功":"执行失败";if(!Z.metadata)Z.metadata={};Z.metadata.executionId=$.context.sessionId,Z.metadata.toolName=$.toolName,Z.metadata.timestamp=Date.now(),$.setResult(Z)}catch(Z){$.abort(`Result formatting failed: ${Z.message}`)}}}var v4;var eG=A(()=>{sG();U0();t0();O$();k$();j0();tG();v4=l("Execution")});import{EventEmitter as JB}from"events";var s5;var $K=A(()=>{U0();t0();rG();nG();o6();w0();oG();eG();s5=class s5 extends JB{registry;stages;executionHistory=[];maxHistorySize;sessionApprovals=new Set;constructor($,Z={}){super();this.registry=$;this.maxHistorySize=Z.maxHistorySize||1000;let Y=Z.permissionConfig||{allow:[],ask:[],deny:[]},Q=Z.permissionMode??"default",X=new a5(Y,this.sessionApprovals,Q);this.stages=[new i5(this.registry),X,new d5,new r5(this.sessionApprovals,X.getPermissionChecker()),new n5,new u5,new o5]}async execute($,Z,Y){let Q=Date.now(),X=this.generateExecutionId(),J=new n6($,Z,{...Y,sessionId:Y.sessionId||X});this.emit("executionStarted",{executionId:X,toolName:$,params:Z,context:Y,timestamp:Q});let G=this.registry.get($),K=G&&!G.isConcurrencySafe,q=K&&Z.file_path?String(Z.file_path):null;if(K&&q)return y4.getInstance().acquireLock(q,()=>this.executeWithPipeline(J,X,Q));return this.executeWithPipeline(J,X,Q)}async executeWithPipeline($,Z,Y){try{for(let J of this.stages){if($.context.signal?.aborted){$.abort("任务已被用户中止");break}if(this.emit("stageStarted",{executionId:Z,stageName:J.name,timestamp:Date.now()}),await J.process($),this.emit("stageCompleted",{executionId:Z,stageName:J.name,timestamp:Date.now()}),$.shouldAbort())break}let Q=$.getResult(),X=Date.now();return this.addToHistory({executionId:Z,toolName:$.toolName,params:$.params,result:Q,startTime:Y,endTime:X,context:$.context}),this.emit("executionCompleted",{executionId:Z,toolName:$.toolName,result:Q,duration:X-Y,timestamp:X}),Q}catch(Q){let X=Date.now(),J=Q.message?.includes("timeout")||Q.name==="TimeoutError",G={success:!1,llmContent:`Tool execution failed: ${Q.message}`,displayContent:`错误: ${Q.message}`,error:{type:"execution_error",message:Q.message}};try{let q=await M$.getInstance().executePostToolUseFailureHooks($.toolName,`tool_use_${Z}`,$.params,Q.message,{projectDir:process.cwd(),sessionId:$.context.sessionId||"unknown",permissionMode:$.context.permissionMode||"default",isInterrupt:!1,isTimeout:J,abortSignal:$.context.signal});if(q.additionalContext)G={...G,llmContent:`${G.llmContent}
2116
2116
 
2117
- ${q.additionalContext}`};if(q.warning)console.warn(`[ExecutionPipeline] PostToolUseFailure hook warning: ${q.warning}`)}catch(K){console.warn("[ExecutionPipeline] PostToolUseFailure hook execution failed:",K)}return this.addToHistory({executionId:Z,toolName:$.toolName,params:$.params,result:G,startTime:Y,endTime:X,context:$.context}),this.emit("executionFailed",{executionId:Z,toolName:$.toolName,error:Q,duration:X-Y,timestamp:X}),G}}async executeAll($){let Z=$.map((Y)=>this.execute(Y.toolName,Y.params,Y.context));return Promise.all(Z)}async executeParallel($,Z=5){let Y=[],Q=[];for(let X=0;X<$.length;X++){let J=$[X],G=this.execute(J.toolName,J.params,J.context);if(Q.push(G),Q.length>=Z||X===$.length-1){let K=await Promise.all(Q);Y.push(...K),Q.length=0}}return Y}getExecutionHistory($){let Z=[...this.executionHistory];return $?Z.slice(-$):Z}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)},Z=0;for(let Y of this.executionHistory){if(Y.result.success)$.successfulExecutions++;else $.failedExecutions++;let Q=Y.endTime-Y.startTime;Z+=Q;let X=$.toolUsage.get(Y.toolName)||0;$.toolUsage.set(Y.toolName,X+1)}return $.averageDuration=$.totalExecutions>0?Z/$.totalExecutions:0,$}addStage($,Z=-1){if(Z===-1){let Y=this.stages.findIndex((Q)=>Q.name==="execution");this.stages.splice(Y,0,$)}else this.stages.splice(Z,0,$);this.emit("stageAdded",{stageName:$.name,position:Z,timestamp:Date.now()})}removeStage($){let Z=this.stages.findIndex((Y)=>Y.name===$);if(Z===-1)return!1;return this.stages.splice(Z,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 GB}from"events";var P9;var ZK=A(()=>{U0();P9=class P9 extends GB{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 Z=[];for(let Y of $)try{this.register(Y)}catch(Q){Z.push(`${Y.name}: ${Q.message}`)}if(Z.length>0)throw Error(`批量注册失败: ${Z.join(", ")}`)}unregister($){let Z=this.tools.get($);if(!Z)return!1;return this.tools.delete($),this.removeFromIndexes(Z),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 Z=this.categories.get($);if(!Z)return[];return Array.from(Z).map((Y)=>this.get(Y)).filter((Y)=>Y!==void 0)}getByTag($){let Z=this.tags.get($);if(!Z)return[];return Array.from(Z).map((Y)=>this.get(Y)).filter((Y)=>Y!==void 0)}search($){let Z=$.toLowerCase();return this.getAll().filter((Y)=>{let Q=typeof Y.description==="string"?Y.description:Y.description.short;return Y.name.toLowerCase().includes(Z)||Q.toLowerCase().includes(Z)||Y.displayName.toLowerCase().includes(Z)||Y.category&&Y.category.toLowerCase().includes(Z)||Y.tags.some((X)=>X.toLowerCase().includes(Z))})}getFunctionDeclarations(){return this.getAll().map(($)=>$.getFunctionDeclaration())}getReadOnlyFunctionDeclarations(){return this.getAll().filter(($)=>$.isReadOnly).map(($)=>$.getFunctionDeclaration())}getFunctionDeclarationsByMode($){if($==="plan")return this.getReadOnlyFunctionDeclarations();if($==="spec")return this.getSpecModeFunctionDeclarations();return this.getFunctionDeclarations()}static SPEC_TOOLS=["EnterSpecMode","UpdateSpec","GetSpecContext","TransitionSpecPhase","AddTask","UpdateTaskStatus","ValidateSpec","ExitSpecMode"];getSpecModeFunctionDeclarations(){return this.getFunctionDeclarations()}isSpecTool($){return P9.SPEC_TOOLS.includes($)}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(([$,Z])=>[$,Z.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 Z=0,Y=`mcp__${$}__`;for(let[Q,X]of this.mcpTools.entries())if(Q.startsWith(Y))this.mcpTools.delete(Q),this.removeFromIndexes(X),Z++,this.emit("toolUnregistered",{type:"mcp",toolName:Q,serverName:$,timestamp:Date.now()});return Z}updateIndexes($){if($.category){if(!this.categories.has($.category))this.categories.set($.category,new Set);this.categories.get($.category).add($.name)}for(let Z of $.tags){if(!this.tags.has(Z))this.tags.set(Z,new Set);this.tags.get(Z).add($.name)}}removeFromIndexes($){if($.category){let Z=this.categories.get($.category);if(Z){if(Z.delete($.name),Z.size===0)this.categories.delete($.category)}}for(let Z of $.tags){let Y=this.tags.get(Z);if(Y){if(Y.delete($.name),Y.size===0)this.tags.delete(Z)}}}}});function qB($){return KB.some((Z)=>Z.test($))}function WB($){if($.supportsThinking!==void 0)return{supportsThinking:$.supportsThinking,thinkingBudget:$.thinkingBudget};return{supportsThinking:qB($.model),thinkingBudget:void 0}}function X3($){return WB($).supportsThinking}var KB;var T9=A(()=>{KB=[/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,/glm-4\.7/i]});class t5{maxSummaryLength;keyPointsLimit;recentMessagesLimit;constructor($=500,Z=10,Y=20){this.maxSummaryLength=$,this.keyPointsLimit=Z,this.recentMessagesLimit=Y}async compress($){let Z=$.layers.conversation.messages,Y=$.layers.tool.recentCalls,Q=Z.filter((H)=>H.role==="system"),X=Z.filter((H)=>H.role!=="system"),J=this.getRecentMessages(X),G=X.slice(0,-this.recentMessagesLimit),K=await this.generateSummary(G),q=this.extractKeyPoints(G,Y),W=this.generateToolSummary(Y),U=this.estimateTokenCount(K,q,J,W);return{summary:K,keyPoints:q,recentMessages:[...Q,...J],toolSummary:W,tokenCount:U}}getRecentMessages($){return $.slice(-this.recentMessagesLimit)}async generateSummary($){if($.length===0)return"";let Z=new Set,Y=new Set,Q=new Set;for(let J of $){let G=J.content.toLowerCase();["关于","讨论","问题","项目","功能","需求"].forEach((U)=>{if(G.includes(U)){let H=this.extractContext(G,U,50);if(H)Z.add(H)}}),["创建","删除","修改","更新","实现","开发"].forEach((U)=>{if(G.includes(U)){let H=this.extractContext(G,U,30);if(H)Y.add(H)}}),["决定","选择","确定","采用","使用"].forEach((U)=>{if(G.includes(U)){let H=this.extractContext(G,U,40);if(H)Q.add(H)}})}let X=`对话涉及 ${$.length} 条消息。`;if(Z.size>0)X+=` 主要讨论:${Array.from(Z).slice(0,3).join("、")}。`;if(Y.size>0)X+=` 执行操作:${Array.from(Y).slice(0,3).join("、")}。`;if(Q.size>0)X+=` 关键决策:${Array.from(Q).slice(0,2).join("、")}。`;return X.length>this.maxSummaryLength?X.substring(0,this.maxSummaryLength)+"...":X}extractKeyPoints($,Z){let Y=new Set;for(let X of $)if(X.role==="user")this.extractQuestions(X.content).forEach((K)=>Y.add(`用户问题:${K}`)),this.extractRequests(X.content).forEach((K)=>Y.add(`用户请求:${K}`));else if(X.role==="assistant")this.extractSolutions(X.content).forEach((G)=>Y.add(`解决方案:${G}`));return this.summarizeToolUsage(Z).forEach((X)=>Y.add(`工具使用:${X}`)),Array.from(Y).slice(0,this.keyPointsLimit)}generateToolSummary($){if($.length===0)return"";let Z=new Map,Y=Date.now()-600000;for(let X of $){let J=Z.get(X.name)||{count:0,success:0,recent:0};if(J.count++,X.status==="success")J.success++;if(X.timestamp>Y)J.recent++;Z.set(X.name,J)}let Q=[];for(let[X,J]of Array.from(Z.entries())){let G=Math.round(J.success/J.count*100);Q.push(`${X}(${J.count}次,成功率${G}%)`)}return`工具调用:${Q.join("、")}`}estimateTokenCount($,Z,Y,Q){let X=$.length+Z.join(" ").length;if(Q)X+=Q.length;for(let J of Y)X+=J.content.length;return Math.ceil(X/4)}extractContext($,Z,Y){let Q=$.indexOf(Z);if(Q===-1)return null;let X=Math.max(0,Q-Y/2),J=Math.min($.length,Q+Y/2);return $.substring(X,J).trim()}extractQuestions($){let Z=[],Y=["?","?","如何","怎么","什么","为什么"],Q=$.split(/[。!.!]/);for(let X of Q)if(Y.some((J)=>X.includes(J))){let J=X.trim();if(J.length>5&&J.length<100)Z.push(J)}return Z.slice(0,3)}extractRequests($){let Z=[],Y=["请","帮我","需要","想要","希望","能否"],Q=$.split(/[。!.!]/);for(let X of Q)if(Y.some((J)=>X.includes(J))){let J=X.trim();if(J.length>5&&J.length<100)Z.push(J)}return Z.slice(0,3)}extractSolutions($){let Z=[],Y=["可以","建议","推荐","应该","最好","解决方案"],Q=$.split(/[。!.!]/);for(let X of Q)if(Y.some((J)=>X.includes(J))){let J=X.trim();if(J.length>10&&J.length<150)Z.push(J)}return Z.slice(0,3)}summarizeToolUsage($){let Z=[],Y=$.filter((Q)=>Date.now()-Q.timestamp<1800000);if(Y.length>0){let Q=new Map;Y.forEach((X)=>{let J=Q.get(X.name)||[];J.push(X),Q.set(X.name,J)});for(let[X,J]of Array.from(Q.entries())){let G=J.filter((K)=>K.status==="success").length;Z.push(`${X}(${J.length}次,${G}成功)`)}}return Z.slice(0,5)}shouldCompress($,Z){return this.estimateCurrentTokens($)>Z*0.8}estimateCurrentTokens($){let Y=$.layers.conversation.messages.reduce((Q,X)=>Q+X.content.length,0);return Math.ceil(Y/4)}}class F4{defaultOptions;constructor($){this.defaultOptions={maxTokens:32000,maxMessages:50,timeWindow:86400000,priority:1,includeTools:!0,includeWorkspace:!0,...$}}filter($,Z){let Y={...this.defaultOptions,...Z},Q={layers:{system:$.layers.system,session:$.layers.session,conversation:this.filterConversation($.layers.conversation,Y),tool:Y.includeTools?this.filterTools($.layers.tool,Y):{recentCalls:[],toolStates:{},dependencies:{}},workspace:Y.includeWorkspace?$.layers.workspace:{currentFiles:[],recentFiles:[],environment:{}}},metadata:{...$.metadata,lastUpdated:Date.now()}};return Q.metadata.totalTokens=this.estimateTokens(Q),Q}filterConversation($,Z){let Y=[...$.messages];if(Z.timeWindow>0){let Q=Date.now()-Z.timeWindow;Y=Y.filter((X)=>X.timestamp>=Q||X.role==="system")}if(Z.priority>1)Y=this.filterByPriority(Y,Z.priority);if(Z.maxMessages>0)Y=this.limitMessages(Y,Z.maxMessages);if(Z.maxTokens>0)Y=this.limitByTokens(Y,Z.maxTokens);return{messages:Y,summary:$.summary,topics:this.updateTopics(Y,$.topics),lastActivity:$.lastActivity}}filterTools($,Z){let Y=[...$.recentCalls];if(Z.timeWindow>0){let q=Date.now()-Z.timeWindow;Y=Y.filter((W)=>W.timestamp>=q)}let Q=Y.filter((q)=>q.status==="success"),X=Y.filter((q)=>q.status==="error"),J=Math.min(20,Q.length),G=Math.min(10,X.length);return{recentCalls:[...Q.slice(-J),...X.slice(-G)].sort((q,W)=>q.timestamp-W.timestamp),toolStates:$.toolStates,dependencies:$.dependencies}}filterByPriority($,Z){return $.filter((Y)=>{if(Y.role==="system")return!0;return this.calculateMessagePriority(Y)>=Z})}calculateMessagePriority($){let Z=1;if($.role==="system")Z+=3;else if($.role==="assistant")Z+=1;let Y=$.content.toLowerCase();if(["错误","警告","重要","关键","问题","解决"].some((J)=>Y.includes(J)))Z+=2;if(Y.includes("```")||Y.includes("function")||Y.includes("class"))Z+=1;let X=(Date.now()-$.timestamp)/3600000;if(X<1)Z+=2;else if(X<6)Z+=1;return Z}limitMessages($,Z){if($.length<=Z)return $;let Y=$.filter((G)=>G.role==="system"),Q=$.filter((G)=>G.role!=="system"),X=Z-Y.length,J=X>0?Q.slice(-X):[];return[...Y,...J].sort((G,K)=>G.timestamp-K.timestamp)}limitByTokens($,Z){if(Z<=0)return $;let Y=0,Q=[];for(let X=$.length-1;X>=0;X--){let J=$[X],G=this.estimateMessageTokens(J);if(J.role==="system")if(Y+G<=Z)Q.unshift(J),Y+=G;else{let K=this.compressMessage(J,Z-Y);Q.unshift(K),Y+=this.estimateMessageTokens(K)}else if(Y+G<=Z)Q.unshift(J),Y+=G;else break}return Q.sort((X,J)=>X.timestamp-J.timestamp)}estimateMessageTokens($){return Math.ceil($.content.length/4)}compressMessage($,Z){let Y=Z*4;if($.content.length<=Y)return $;let Q=$.content.substring(0,Y-3)+"...";return{...$,content:Q,metadata:{...$.metadata,compressed:!0,originalLength:$.content.length}}}updateTopics($,Z){let Y=new Set(Z);for(let Q of $)this.extractTopicsFromMessage(Q).forEach((J)=>Y.add(J));return Array.from(Y).slice(0,10)}extractTopicsFromMessage($){let Z=$.content.toLowerCase(),Y=[];return["项目","功能","模块","组件","服务","接口","数据库","前端","后端","算法","架构","设计"].forEach((X)=>{if(Z.includes(X))Y.push(X)}),Y}estimateTokens($){let Z=0;for(let Q of $.layers.conversation.messages)Z+=this.estimateMessageTokens(Q);let Y=JSON.stringify($.layers.system);if(Z+=Math.ceil(Y.length/4),$.layers.tool.recentCalls.length>0){let Q=JSON.stringify($.layers.tool);Z+=Math.ceil(Q.length/8)}return Z}static createPresets(){return{lightweight:new F4({maxTokens:1000,maxMessages:10,timeWindow:7200000,includeTools:!1,includeWorkspace:!1}),standard:new F4({maxTokens:4000,maxMessages:30,timeWindow:43200000,includeTools:!0,includeWorkspace:!0}),comprehensive:new F4({maxTokens:8000,maxMessages:100,timeWindow:86400000,includeTools:!0,includeWorkspace:!0}),debug:new F4({maxTokens:2000,maxMessages:20,timeWindow:21600000,priority:2,includeTools:!0,includeWorkspace:!1})}}}class e5{cache=new Map;maxSize;defaultTTL;constructor($=100,Z=300000){this.maxSize=$,this.defaultTTL=Z}set($,Z,Y){let Q=Date.now(),X={data:Z,timestamp:Q,accessCount:0,lastAccess:Q,ttl:Y||this.defaultTTL};if(this.cache.size>=this.maxSize&&!this.cache.has($))this.evictLeastUsed();this.cache.set($,X)}get($){let Z=this.cache.get($);if(!Z)return null;let Y=Date.now();if(Y-Z.timestamp>Z.ttl)return this.cache.delete($),null;return Z.accessCount++,Z.lastAccess=Y,Z.data}has($){let Z=this.cache.get($);if(!Z)return!1;if(Date.now()-Z.timestamp>Z.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($,Z,Y){let Q=`summary:${$}:${Z.length}`;this.set(Q,{summary:Y,messageCount:Z.length,lastMessage:Z[Z.length-1]?.timestamp||0},600000)}getMessageSummary($,Z){let Y=`summary:${$}:${Z}`;return this.get(Y)}cacheToolResult($,Z,Y){let Q=this.hashInput(Z),X=`tool:${$}:${Q}`;this.set(X,Y,1800000)}getToolResult($,Z){let Y=this.hashInput(Z),Q=`tool:${$}:${Y}`;return this.get(Q)}cacheCompressedContext($,Z){let Y=`compressed:${$}`;this.set(Y,Z,900000)}getCompressedContext($){let Z=`compressed:${$}`;return this.get(Z)}getStats(){this.cleanExpired();let $=0,Z=0,Y=[];for(let[Q,X]of Array.from(this.cache.entries()))$+=X.accessCount,Z+=this.estimateItemSize(X),Y.push({key:Q,accessCount:X.accessCount,lastAccess:X.lastAccess});return Y.sort((Q,X)=>X.accessCount-Q.accessCount),{size:this.cache.size,maxSize:this.maxSize,hitRate:$>0?$/($+this.cache.size):0,memoryUsage:Z,topKeys:Y.slice(0,10)}}cleanExpired(){let $=Date.now(),Z=[];for(let[Y,Q]of Array.from(this.cache.entries()))if($-Q.timestamp>Q.ttl)Z.push(Y);Z.forEach((Y)=>this.cache.delete(Y))}evictLeastUsed(){let $=null,Z=1/0,Y=Date.now();for(let[Q,X]of Array.from(this.cache.entries())){let J=1/(Y-X.lastAccess+1),G=X.accessCount,K=J*G;if(K<Z)Z=K,$=Q}if($)this.cache.delete($)}hashInput($){let Z=JSON.stringify($),Y=0;for(let Q=0;Q<Z.length;Q++){let X=Z.charCodeAt(Q);Y=(Y<<5)-Y+X,Y=Y&Y}return Math.abs(Y).toString(36)}estimateItemSize($){try{return JSON.stringify($).length*2}catch{return 1000}}setTTL($,Z){let Y=this.cache.get($);if(Y)return Y.ttl=Z,Y.timestamp=Date.now(),!0;return!1}getRemainingTTL($){let Z=this.cache.get($);if(!Z)return-1;let Y=Z.ttl-(Date.now()-Z.timestamp);return Math.max(0,Y)}warmup($){$.forEach(({key:Z,value:Y,ttl:Q})=>{this.set(Z,Y,Q)})}}class $Z{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 Z=this.contextData.layers.conversation.messages;return this.recordAccess("messages"),Z.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($,Z){if(!this.contextData)throw Error("上下文数据未初始化");this.contextData.layers.tool.toolStates[$]=Z,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 Z=Math.floor(this.maxSize*0.8);this.contextData.layers.conversation.messages=$.slice(-Z)}}getMemoryUsage(){if(!this.contextData)return 0;return JSON.stringify(this.contextData).length}}import*as C9 from"node:fs";import{createReadStream as UB}from"node:fs";import*as l0 from"node:fs/promises";import*as ZZ from"node:path";import{createInterface as HB}from"node:readline";class P1{filePath;constructor($){this.filePath=$}async append($){try{await l0.mkdir(ZZ.dirname(this.filePath),{recursive:!0,mode:493});let Z=JSON.stringify($)+`
2117
+ ${q.additionalContext}`};if(q.warning)console.warn(`[ExecutionPipeline] PostToolUseFailure hook warning: ${q.warning}`)}catch(K){console.warn("[ExecutionPipeline] PostToolUseFailure hook execution failed:",K)}return this.addToHistory({executionId:Z,toolName:$.toolName,params:$.params,result:G,startTime:Y,endTime:X,context:$.context}),this.emit("executionFailed",{executionId:Z,toolName:$.toolName,error:Q,duration:X-Y,timestamp:X}),G}}async executeAll($){let Z=$.map((Y)=>this.execute(Y.toolName,Y.params,Y.context));return Promise.all(Z)}async executeParallel($,Z=5){let Y=[],Q=[];for(let X=0;X<$.length;X++){let J=$[X],G=this.execute(J.toolName,J.params,J.context);if(Q.push(G),Q.length>=Z||X===$.length-1){let K=await Promise.all(Q);Y.push(...K),Q.length=0}}return Y}getExecutionHistory($){let Z=[...this.executionHistory];return $?Z.slice(-$):Z}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)},Z=0;for(let Y of this.executionHistory){if(Y.result.success)$.successfulExecutions++;else $.failedExecutions++;let Q=Y.endTime-Y.startTime;Z+=Q;let X=$.toolUsage.get(Y.toolName)||0;$.toolUsage.set(Y.toolName,X+1)}return $.averageDuration=$.totalExecutions>0?Z/$.totalExecutions:0,$}addStage($,Z=-1){if(Z===-1){let Y=this.stages.findIndex((Q)=>Q.name==="execution");this.stages.splice(Y,0,$)}else this.stages.splice(Z,0,$);this.emit("stageAdded",{stageName:$.name,position:Z,timestamp:Date.now()})}removeStage($){let Z=this.stages.findIndex((Y)=>Y.name===$);if(Z===-1)return!1;return this.stages.splice(Z,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 GB}from"events";var P9;var ZK=A(()=>{U0();P9=class P9 extends GB{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 Z=[];for(let Y of $)try{this.register(Y)}catch(Q){Z.push(`${Y.name}: ${Q.message}`)}if(Z.length>0)throw Error(`批量注册失败: ${Z.join(", ")}`)}unregister($){let Z=this.tools.get($);if(!Z)return!1;return this.tools.delete($),this.removeFromIndexes(Z),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 Z=this.categories.get($);if(!Z)return[];return Array.from(Z).map((Y)=>this.get(Y)).filter((Y)=>Y!==void 0)}getByTag($){let Z=this.tags.get($);if(!Z)return[];return Array.from(Z).map((Y)=>this.get(Y)).filter((Y)=>Y!==void 0)}search($){let Z=$.toLowerCase();return this.getAll().filter((Y)=>{let Q=typeof Y.description==="string"?Y.description:Y.description.short;return Y.name.toLowerCase().includes(Z)||Q.toLowerCase().includes(Z)||Y.displayName.toLowerCase().includes(Z)||Y.category&&Y.category.toLowerCase().includes(Z)||Y.tags.some((X)=>X.toLowerCase().includes(Z))})}getFunctionDeclarations(){return this.getAll().map(($)=>$.getFunctionDeclaration())}getReadOnlyFunctionDeclarations(){return this.getAll().filter(($)=>$.isReadOnly).map(($)=>$.getFunctionDeclaration())}getFunctionDeclarationsByMode($){if($==="plan")return this.getReadOnlyFunctionDeclarations();if($==="spec")return this.getSpecModeFunctionDeclarations();return this.getFunctionDeclarations()}static SPEC_TOOLS=["EnterSpecMode","UpdateSpec","GetSpecContext","TransitionSpecPhase","AddTask","UpdateTaskStatus","ValidateSpec","ExitSpecMode"];getSpecModeFunctionDeclarations(){return this.getFunctionDeclarations()}isSpecTool($){return P9.SPEC_TOOLS.includes($)}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(([$,Z])=>[$,Z.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 Z=0,Y=`mcp__${$}__`;for(let[Q,X]of this.mcpTools.entries())if(Q.startsWith(Y))this.mcpTools.delete(Q),this.removeFromIndexes(X),Z++,this.emit("toolUnregistered",{type:"mcp",toolName:Q,serverName:$,timestamp:Date.now()});return Z}updateIndexes($){if($.category){if(!this.categories.has($.category))this.categories.set($.category,new Set);this.categories.get($.category).add($.name)}for(let Z of $.tags){if(!this.tags.has(Z))this.tags.set(Z,new Set);this.tags.get(Z).add($.name)}}removeFromIndexes($){if($.category){let Z=this.categories.get($.category);if(Z){if(Z.delete($.name),Z.size===0)this.categories.delete($.category)}}for(let Z of $.tags){let Y=this.tags.get(Z);if(Y){if(Y.delete($.name),Y.size===0)this.tags.delete(Z)}}}}});function qB($){return KB.some((Z)=>Z.test($))}function WB($){if($.supportsThinking!==void 0)return{supportsThinking:$.supportsThinking,thinkingBudget:$.thinkingBudget};return{supportsThinking:qB($.model),thinkingBudget:void 0}}function X8($){return WB($).supportsThinking}var KB;var T9=A(()=>{KB=[/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,/glm-4\.7/i]});class t5{maxSummaryLength;keyPointsLimit;recentMessagesLimit;constructor($=500,Z=10,Y=20){this.maxSummaryLength=$,this.keyPointsLimit=Z,this.recentMessagesLimit=Y}async compress($){let Z=$.layers.conversation.messages,Y=$.layers.tool.recentCalls,Q=Z.filter((H)=>H.role==="system"),X=Z.filter((H)=>H.role!=="system"),J=this.getRecentMessages(X),G=X.slice(0,-this.recentMessagesLimit),K=await this.generateSummary(G),q=this.extractKeyPoints(G,Y),W=this.generateToolSummary(Y),U=this.estimateTokenCount(K,q,J,W);return{summary:K,keyPoints:q,recentMessages:[...Q,...J],toolSummary:W,tokenCount:U}}getRecentMessages($){return $.slice(-this.recentMessagesLimit)}async generateSummary($){if($.length===0)return"";let Z=new Set,Y=new Set,Q=new Set;for(let J of $){let G=J.content.toLowerCase();["关于","讨论","问题","项目","功能","需求"].forEach((U)=>{if(G.includes(U)){let H=this.extractContext(G,U,50);if(H)Z.add(H)}}),["创建","删除","修改","更新","实现","开发"].forEach((U)=>{if(G.includes(U)){let H=this.extractContext(G,U,30);if(H)Y.add(H)}}),["决定","选择","确定","采用","使用"].forEach((U)=>{if(G.includes(U)){let H=this.extractContext(G,U,40);if(H)Q.add(H)}})}let X=`对话涉及 ${$.length} 条消息。`;if(Z.size>0)X+=` 主要讨论:${Array.from(Z).slice(0,3).join("、")}。`;if(Y.size>0)X+=` 执行操作:${Array.from(Y).slice(0,3).join("、")}。`;if(Q.size>0)X+=` 关键决策:${Array.from(Q).slice(0,2).join("、")}。`;return X.length>this.maxSummaryLength?X.substring(0,this.maxSummaryLength)+"...":X}extractKeyPoints($,Z){let Y=new Set;for(let X of $)if(X.role==="user")this.extractQuestions(X.content).forEach((K)=>Y.add(`用户问题:${K}`)),this.extractRequests(X.content).forEach((K)=>Y.add(`用户请求:${K}`));else if(X.role==="assistant")this.extractSolutions(X.content).forEach((G)=>Y.add(`解决方案:${G}`));return this.summarizeToolUsage(Z).forEach((X)=>Y.add(`工具使用:${X}`)),Array.from(Y).slice(0,this.keyPointsLimit)}generateToolSummary($){if($.length===0)return"";let Z=new Map,Y=Date.now()-600000;for(let X of $){let J=Z.get(X.name)||{count:0,success:0,recent:0};if(J.count++,X.status==="success")J.success++;if(X.timestamp>Y)J.recent++;Z.set(X.name,J)}let Q=[];for(let[X,J]of Array.from(Z.entries())){let G=Math.round(J.success/J.count*100);Q.push(`${X}(${J.count}次,成功率${G}%)`)}return`工具调用:${Q.join("、")}`}estimateTokenCount($,Z,Y,Q){let X=$.length+Z.join(" ").length;if(Q)X+=Q.length;for(let J of Y)X+=J.content.length;return Math.ceil(X/4)}extractContext($,Z,Y){let Q=$.indexOf(Z);if(Q===-1)return null;let X=Math.max(0,Q-Y/2),J=Math.min($.length,Q+Y/2);return $.substring(X,J).trim()}extractQuestions($){let Z=[],Y=["?","?","如何","怎么","什么","为什么"],Q=$.split(/[。!.!]/);for(let X of Q)if(Y.some((J)=>X.includes(J))){let J=X.trim();if(J.length>5&&J.length<100)Z.push(J)}return Z.slice(0,3)}extractRequests($){let Z=[],Y=["请","帮我","需要","想要","希望","能否"],Q=$.split(/[。!.!]/);for(let X of Q)if(Y.some((J)=>X.includes(J))){let J=X.trim();if(J.length>5&&J.length<100)Z.push(J)}return Z.slice(0,3)}extractSolutions($){let Z=[],Y=["可以","建议","推荐","应该","最好","解决方案"],Q=$.split(/[。!.!]/);for(let X of Q)if(Y.some((J)=>X.includes(J))){let J=X.trim();if(J.length>10&&J.length<150)Z.push(J)}return Z.slice(0,3)}summarizeToolUsage($){let Z=[],Y=$.filter((Q)=>Date.now()-Q.timestamp<1800000);if(Y.length>0){let Q=new Map;Y.forEach((X)=>{let J=Q.get(X.name)||[];J.push(X),Q.set(X.name,J)});for(let[X,J]of Array.from(Q.entries())){let G=J.filter((K)=>K.status==="success").length;Z.push(`${X}(${J.length}次,${G}成功)`)}}return Z.slice(0,5)}shouldCompress($,Z){return this.estimateCurrentTokens($)>Z*0.8}estimateCurrentTokens($){let Y=$.layers.conversation.messages.reduce((Q,X)=>Q+X.content.length,0);return Math.ceil(Y/4)}}class F2{defaultOptions;constructor($){this.defaultOptions={maxTokens:32000,maxMessages:50,timeWindow:86400000,priority:1,includeTools:!0,includeWorkspace:!0,...$}}filter($,Z){let Y={...this.defaultOptions,...Z},Q={layers:{system:$.layers.system,session:$.layers.session,conversation:this.filterConversation($.layers.conversation,Y),tool:Y.includeTools?this.filterTools($.layers.tool,Y):{recentCalls:[],toolStates:{},dependencies:{}},workspace:Y.includeWorkspace?$.layers.workspace:{currentFiles:[],recentFiles:[],environment:{}}},metadata:{...$.metadata,lastUpdated:Date.now()}};return Q.metadata.totalTokens=this.estimateTokens(Q),Q}filterConversation($,Z){let Y=[...$.messages];if(Z.timeWindow>0){let Q=Date.now()-Z.timeWindow;Y=Y.filter((X)=>X.timestamp>=Q||X.role==="system")}if(Z.priority>1)Y=this.filterByPriority(Y,Z.priority);if(Z.maxMessages>0)Y=this.limitMessages(Y,Z.maxMessages);if(Z.maxTokens>0)Y=this.limitByTokens(Y,Z.maxTokens);return{messages:Y,summary:$.summary,topics:this.updateTopics(Y,$.topics),lastActivity:$.lastActivity}}filterTools($,Z){let Y=[...$.recentCalls];if(Z.timeWindow>0){let q=Date.now()-Z.timeWindow;Y=Y.filter((W)=>W.timestamp>=q)}let Q=Y.filter((q)=>q.status==="success"),X=Y.filter((q)=>q.status==="error"),J=Math.min(20,Q.length),G=Math.min(10,X.length);return{recentCalls:[...Q.slice(-J),...X.slice(-G)].sort((q,W)=>q.timestamp-W.timestamp),toolStates:$.toolStates,dependencies:$.dependencies}}filterByPriority($,Z){return $.filter((Y)=>{if(Y.role==="system")return!0;return this.calculateMessagePriority(Y)>=Z})}calculateMessagePriority($){let Z=1;if($.role==="system")Z+=3;else if($.role==="assistant")Z+=1;let Y=$.content.toLowerCase();if(["错误","警告","重要","关键","问题","解决"].some((J)=>Y.includes(J)))Z+=2;if(Y.includes("```")||Y.includes("function")||Y.includes("class"))Z+=1;let X=(Date.now()-$.timestamp)/3600000;if(X<1)Z+=2;else if(X<6)Z+=1;return Z}limitMessages($,Z){if($.length<=Z)return $;let Y=$.filter((G)=>G.role==="system"),Q=$.filter((G)=>G.role!=="system"),X=Z-Y.length,J=X>0?Q.slice(-X):[];return[...Y,...J].sort((G,K)=>G.timestamp-K.timestamp)}limitByTokens($,Z){if(Z<=0)return $;let Y=0,Q=[];for(let X=$.length-1;X>=0;X--){let J=$[X],G=this.estimateMessageTokens(J);if(J.role==="system")if(Y+G<=Z)Q.unshift(J),Y+=G;else{let K=this.compressMessage(J,Z-Y);Q.unshift(K),Y+=this.estimateMessageTokens(K)}else if(Y+G<=Z)Q.unshift(J),Y+=G;else break}return Q.sort((X,J)=>X.timestamp-J.timestamp)}estimateMessageTokens($){return Math.ceil($.content.length/4)}compressMessage($,Z){let Y=Z*4;if($.content.length<=Y)return $;let Q=$.content.substring(0,Y-3)+"...";return{...$,content:Q,metadata:{...$.metadata,compressed:!0,originalLength:$.content.length}}}updateTopics($,Z){let Y=new Set(Z);for(let Q of $)this.extractTopicsFromMessage(Q).forEach((J)=>Y.add(J));return Array.from(Y).slice(0,10)}extractTopicsFromMessage($){let Z=$.content.toLowerCase(),Y=[];return["项目","功能","模块","组件","服务","接口","数据库","前端","后端","算法","架构","设计"].forEach((X)=>{if(Z.includes(X))Y.push(X)}),Y}estimateTokens($){let Z=0;for(let Q of $.layers.conversation.messages)Z+=this.estimateMessageTokens(Q);let Y=JSON.stringify($.layers.system);if(Z+=Math.ceil(Y.length/4),$.layers.tool.recentCalls.length>0){let Q=JSON.stringify($.layers.tool);Z+=Math.ceil(Q.length/8)}return Z}static createPresets(){return{lightweight:new F2({maxTokens:1000,maxMessages:10,timeWindow:7200000,includeTools:!1,includeWorkspace:!1}),standard:new F2({maxTokens:4000,maxMessages:30,timeWindow:43200000,includeTools:!0,includeWorkspace:!0}),comprehensive:new F2({maxTokens:8000,maxMessages:100,timeWindow:86400000,includeTools:!0,includeWorkspace:!0}),debug:new F2({maxTokens:2000,maxMessages:20,timeWindow:21600000,priority:2,includeTools:!0,includeWorkspace:!1})}}}class e5{cache=new Map;maxSize;defaultTTL;constructor($=100,Z=300000){this.maxSize=$,this.defaultTTL=Z}set($,Z,Y){let Q=Date.now(),X={data:Z,timestamp:Q,accessCount:0,lastAccess:Q,ttl:Y||this.defaultTTL};if(this.cache.size>=this.maxSize&&!this.cache.has($))this.evictLeastUsed();this.cache.set($,X)}get($){let Z=this.cache.get($);if(!Z)return null;let Y=Date.now();if(Y-Z.timestamp>Z.ttl)return this.cache.delete($),null;return Z.accessCount++,Z.lastAccess=Y,Z.data}has($){let Z=this.cache.get($);if(!Z)return!1;if(Date.now()-Z.timestamp>Z.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($,Z,Y){let Q=`summary:${$}:${Z.length}`;this.set(Q,{summary:Y,messageCount:Z.length,lastMessage:Z[Z.length-1]?.timestamp||0},600000)}getMessageSummary($,Z){let Y=`summary:${$}:${Z}`;return this.get(Y)}cacheToolResult($,Z,Y){let Q=this.hashInput(Z),X=`tool:${$}:${Q}`;this.set(X,Y,1800000)}getToolResult($,Z){let Y=this.hashInput(Z),Q=`tool:${$}:${Y}`;return this.get(Q)}cacheCompressedContext($,Z){let Y=`compressed:${$}`;this.set(Y,Z,900000)}getCompressedContext($){let Z=`compressed:${$}`;return this.get(Z)}getStats(){this.cleanExpired();let $=0,Z=0,Y=[];for(let[Q,X]of Array.from(this.cache.entries()))$+=X.accessCount,Z+=this.estimateItemSize(X),Y.push({key:Q,accessCount:X.accessCount,lastAccess:X.lastAccess});return Y.sort((Q,X)=>X.accessCount-Q.accessCount),{size:this.cache.size,maxSize:this.maxSize,hitRate:$>0?$/($+this.cache.size):0,memoryUsage:Z,topKeys:Y.slice(0,10)}}cleanExpired(){let $=Date.now(),Z=[];for(let[Y,Q]of Array.from(this.cache.entries()))if($-Q.timestamp>Q.ttl)Z.push(Y);Z.forEach((Y)=>this.cache.delete(Y))}evictLeastUsed(){let $=null,Z=1/0,Y=Date.now();for(let[Q,X]of Array.from(this.cache.entries())){let J=1/(Y-X.lastAccess+1),G=X.accessCount,K=J*G;if(K<Z)Z=K,$=Q}if($)this.cache.delete($)}hashInput($){let Z=JSON.stringify($),Y=0;for(let Q=0;Q<Z.length;Q++){let X=Z.charCodeAt(Q);Y=(Y<<5)-Y+X,Y=Y&Y}return Math.abs(Y).toString(36)}estimateItemSize($){try{return JSON.stringify($).length*2}catch{return 1000}}setTTL($,Z){let Y=this.cache.get($);if(Y)return Y.ttl=Z,Y.timestamp=Date.now(),!0;return!1}getRemainingTTL($){let Z=this.cache.get($);if(!Z)return-1;let Y=Z.ttl-(Date.now()-Z.timestamp);return Math.max(0,Y)}warmup($){$.forEach(({key:Z,value:Y,ttl:Q})=>{this.set(Z,Y,Q)})}}class $Z{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 Z=this.contextData.layers.conversation.messages;return this.recordAccess("messages"),Z.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($,Z){if(!this.contextData)throw Error("上下文数据未初始化");this.contextData.layers.tool.toolStates[$]=Z,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 Z=Math.floor(this.maxSize*0.8);this.contextData.layers.conversation.messages=$.slice(-Z)}}getMemoryUsage(){if(!this.contextData)return 0;return JSON.stringify(this.contextData).length}}import*as C9 from"node:fs";import{createReadStream as UB}from"node:fs";import*as l0 from"node:fs/promises";import*as ZZ from"node:path";import{createInterface as HB}from"node:readline";class P1{filePath;constructor($){this.filePath=$}async append($){try{await l0.mkdir(ZZ.dirname(this.filePath),{recursive:!0,mode:493});let Z=JSON.stringify($)+`
2118
2118
  `;await l0.appendFile(this.filePath,Z,"utf-8")}catch(Z){throw console.error(`[JSONLStore] 追加写入失败: ${this.filePath}`,Z),Z}}async appendBatch($){try{await l0.mkdir(ZZ.dirname(this.filePath),{recursive:!0,mode:493});let Z=$.map((Y)=>JSON.stringify(Y)).join(`
2119
2119
  `)+`
2120
2120
  `;await l0.appendFile(this.filePath,Z,"utf-8")}catch(Z){throw console.error(`[JSONLStore] 批量追加写入失败: ${this.filePath}`,Z),Z}}async readAll(){try{if(!C9.existsSync(this.filePath))return[];let Z=(await l0.readFile(this.filePath,"utf-8")).split(`
2121
2121
  `).filter((Q)=>Q.trim().length>0),Y=[];for(let Q of Z)try{Y.push(JSON.parse(Q))}catch(X){console.warn(`[JSONLStore] 解析 JSON 行失败: ${Q}`,X)}return Y}catch($){return console.error(`[JSONLStore] 读取文件失败: ${this.filePath}`,$),[]}}async readStream($){return new Promise((Z,Y)=>{if(!C9.existsSync(this.filePath)){Z();return}let Q=UB(this.filePath,"utf-8"),X=HB({input:Q,crlfDelay:Number.POSITIVE_INFINITY});X.on("line",async(J)=>{let G=J.trim();if(G.length===0)return;try{let K=JSON.parse(G);await $(K)}catch(K){console.warn(`[JSONLStore] 解析 JSON 行失败: ${G}`,K)}}),X.on("close",()=>Z()),X.on("error",Y),Q.on("error",Y)})}async filter($){let Z=[];return await this.readStream((Y)=>{if($(Y))Z.push(Y)}),Z}async readLast($){return(await this.readAll()).slice(-$)}async getStats(){try{if(!C9.existsSync(this.filePath))return{exists:!1,size:0,lineCount:0};let $=await l0.stat(this.filePath),Y=(await l0.readFile(this.filePath,"utf-8")).split(`
2122
- `).filter((Q)=>Q.trim().length>0).length;return{exists:!0,size:$.size,lineCount:Y}}catch($){return console.error(`[JSONLStore] 获取统计信息失败: ${this.filePath}`,$),{exists:!1,size:0,lineCount:0}}}async exists(){try{return await l0.access(this.filePath),!0}catch{return!1}}async delete(){try{if(await this.exists())await l0.unlink(this.filePath)}catch($){throw console.error(`[JSONLStore] 删除文件失败: ${this.filePath}`,$),$}}getFilePath(){return this.filePath}}var YK=()=>{};import{nanoid as J3}from"nanoid";import*as G2 from"node:fs/promises";import*as QK from"node:path";class YZ{projectPath;maxSessions;version;constructor($=process.cwd(),Z=100,Y="0.0.10"){this.projectPath=$,this.maxSessions=Z,this.version=Y}async initialize(){try{let $=Q8(this.projectPath);await G2.mkdir($,{recursive:!0,mode:493}),console.log(`[PersistentStore] 初始化存储目录: ${$}`)}catch($){console.warn("[PersistentStore] 无法创建持久化存储目录:",$)}}async saveMessage($,Z,Y,Q=null,X){try{let J=z1(this.projectPath,$),G=new P1(J),K={uuid:J3(),parentUuid:Q,sessionId:$,timestamp:new Date().toISOString(),type:Z==="user"?"user":Z==="assistant"?"assistant":Z==="tool"?"tool_result":"system",cwd:this.projectPath,gitBranch:n4(this.projectPath),version:this.version,message:{role:Z,content:Y,...X||{}}};return await G.append(K),K.uuid}catch(J){throw console.error(`[PersistentStore] 保存消息失败 (session: ${$}):`,J),J}}async saveToolUse($,Z,Y,Q=null){try{let X=z1(this.projectPath,$),J=new P1(X),G={uuid:J3(),parentUuid:Q,sessionId:$,timestamp:new Date().toISOString(),type:"tool_use",cwd:this.projectPath,gitBranch:n4(this.projectPath),version:this.version,message:{role:"assistant",content:""},tool:{id:J3(),name:Z,input:Y}};return await J.append(G),G.uuid}catch(X){throw console.error(`[PersistentStore] 保存工具调用失败 (session: ${$}):`,X),X}}async saveToolResult($,Z,Y,Q=null,X){try{let J=z1(this.projectPath,$),G=new P1(J),K={uuid:J3(),parentUuid:Q,sessionId:$,timestamp:new Date().toISOString(),type:"tool_result",cwd:this.projectPath,gitBranch:n4(this.projectPath),version:this.version,message:{role:"assistant",content:""},toolResult:{id:Z,output:Y,error:X}};return await G.append(K),K.uuid}catch(J){throw console.error(`[PersistentStore] 保存工具结果失败 (session: ${$}):`,J),J}}async saveCompaction($,Z,Y,Q=null){try{let X=z1(this.projectPath,$),J=new P1(X),G={uuid:J3(),parentUuid:Q,sessionId:$,timestamp:new Date().toISOString(),type:"system",subtype:"compact_boundary",cwd:this.projectPath,gitBranch:n4(this.projectPath),version:this.version,message:{role:"system",content:"=== 上下文压缩边界 ==="},compactMetadata:Y};await J.append(G),console.log("[PersistentStore] 保存压缩边界标记");let K={uuid:J3(),parentUuid:G.uuid,logicalParentUuid:Q??void 0,sessionId:$,timestamp:new Date().toISOString(),type:"user",isCompactSummary:!0,cwd:this.projectPath,gitBranch:n4(this.projectPath),version:this.version,message:{role:"user",content:Z},compactMetadata:Y};return await J.append(K),console.log("[PersistentStore] 保存压缩总结消息"),K.uuid}catch(X){throw console.error(`[PersistentStore] 保存压缩失败 (session: ${$}):`,X),X}}async saveContext($,Z){try{let{conversation:Y}=Z.layers;for(let Q of Y.messages)await this.saveMessage($,Q.role,Q.content,null)}catch(Y){console.warn(`[PersistentStore] 保存上下文失败 (session: ${$}):`,Y)}}async saveSession($,Z){console.warn("[PersistentStore] saveSession 方法已废弃,请使用 saveMessage")}async saveConversation($,Z){console.warn("[PersistentStore] saveConversation 方法已废弃,请使用 saveMessage")}async loadSession($){try{let Z=z1(this.projectPath,$),Q=await new P1(Z).readAll();if(Q.length===0)return null;let X=Q[0];return{sessionId:$,userId:void 0,preferences:{},configuration:{},startTime:new Date(X.timestamp).getTime()}}catch{return null}}async loadConversation($){try{let Z=z1(this.projectPath,$),Q=await new P1(Z).readAll();if(Q.length===0)return null;let X=Q.filter((K)=>["user","assistant","system"].includes(K.type)).map((K)=>({id:K.uuid,role:K.message.role,content:K.message.content,timestamp:new Date(K.timestamp).getTime()})),J=Q[Q.length-1],G=new Date(J.timestamp).getTime();return{messages:X,topics:[],lastActivity:G}}catch{return null}}async listSessions(){try{let $=Q8(this.projectPath);return(await G2.readdir($)).filter((Y)=>Y.endsWith(".jsonl")).map((Y)=>Y.replace(".jsonl","")).sort()}catch{return[]}}async getSessionSummary($){try{let Z=z1(this.projectPath,$),Y=new P1(Z);if(!(await Y.getStats()).exists)return null;let X=await Y.readAll();if(X.length===0)return null;let J=X[X.length-1];return{sessionId:$,lastActivity:new Date(J.timestamp).getTime(),messageCount:X.filter((G)=>["user","assistant"].includes(G.type)).length,topics:[]}}catch{return null}}async deleteSession($){try{let Z=z1(this.projectPath,$);await new P1(Z).delete()}catch(Z){console.warn(`[PersistentStore] 删除会话失败 (session: ${$}):`,Z)}}async cleanupOldSessions(){try{let $=await this.listSessions();if($.length<=this.maxSessions)return;let Q=(await Promise.all($.map((X)=>this.getSessionSummary(X)))).filter((X)=>X!==null).sort((X,J)=>J.lastActivity-X.lastActivity).slice(this.maxSessions).map((X)=>X.sessionId);await Promise.all(Q.map((X)=>this.deleteSession(X))),console.log(`[PersistentStore] 已清理 ${Q.length} 个旧会话`)}catch($){console.error("[PersistentStore] 清理旧会话失败:",$)}}async getStorageStats(){try{let $=await this.listSessions(),Z=0;for(let Y of $){let Q=z1(this.projectPath,Y),J=await new P1(Q).getStats();Z+=J.size}return{totalSessions:$.length,totalSize:Z,projectPath:this.projectPath}}catch{return{totalSessions:0,totalSize:0,projectPath:this.projectPath}}}async checkStorageHealth(){try{let $=Q8(this.projectPath);await G2.mkdir($,{recursive:!0,mode:493});let Z=QK.join($,".health-check");return await G2.writeFile(Z,"test","utf-8"),await G2.unlink(Z),{isAvailable:!0,canWrite:!0}}catch($){return{isAvailable:!1,canWrite:!1,error:$ instanceof Error?$.message:String($)}}}static async listAllProjects(){return sX()}}var XK=A(()=>{YK();X8()});import*as GK from"crypto";import{nanoid as JK}from"nanoid";class F8{memory;persistent;cache;compressor;filter;options;currentSessionId=null;initialized=!1;constructor($={}){let Z=$.storage?.persistentPath||J4();this.options={storage:{maxMemorySize:1000,persistentPath:Z,cacheSize:100,compressionEnabled:!0,...$.storage},defaultFilter:{maxTokens:32000,maxMessages:50,timeWindow:86400000,...$.defaultFilter},compressionThreshold:$.compressionThreshold||6000,enableVectorSearch:$.enableVectorSearch||!1},this.memory=new $Z(this.options.storage.maxMemorySize),this.persistent=new YZ(process.cwd(),100),this.cache=new e5(this.options.storage.cacheSize,300000),this.compressor=new t5,this.filter=new F4(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($,Z={},Y={}){let Q=Y.sessionId||this.generateSessionId(),X=Date.now(),J={layers:{system:await this.createSystemContext(),session:{sessionId:Q,userId:$,preferences:Z,configuration:Y,startTime:X},conversation:{messages:[],topics:[],lastActivity:X},tool:{recentCalls:[],toolStates:{},dependencies:{}},workspace:await this.createWorkspaceContext()},metadata:{totalTokens:0,priority:1,lastUpdated:X}};return this.memory.setContext(J),await this.persistent.saveContext(Q,J),this.currentSessionId=Q,console.log(`新会话已创建: ${Q}`),Q}async loadSession($){try{let Z=this.memory.getContext();if(!Z||Z.layers.session.sessionId!==$){let[Y,Q]=await Promise.all([this.persistent.loadSession($),this.persistent.loadConversation($)]);if(!Y||!Q)return!1;Z={layers:{system:await this.createSystemContext(),session:Y,conversation:Q,tool:{recentCalls:[],toolStates:{},dependencies:{}},workspace:await this.createWorkspaceContext()},metadata:{totalTokens:0,priority:1,lastUpdated:Date.now()}},this.memory.setContext(Z)}return this.currentSessionId=$,console.log(`会话已加载: ${$}`),!0}catch(Z){return console.error("加载会话失败:",Z),!1}}async addMessage($,Z,Y){if(!this.currentSessionId)throw Error("没有活动会话");let Q={id:this.generateMessageId(),role:$,content:Z,timestamp:Date.now(),metadata:Y};this.memory.addMessage(Q);let X=this.memory.getContext();if(X&&this.shouldCompress(X))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($,Z,Y,Q=null,X){return this.persistent.saveMessage($,Z,Y,Q,X)}async saveToolUse($,Z,Y,Q=null){return this.persistent.saveToolUse($,Z,Y,Q)}async saveToolResult($,Z,Y,Q=null,X){return this.persistent.saveToolResult($,Z,Y,Q,X)}async saveCompaction($,Z,Y,Q=null){return this.persistent.saveCompaction($,Z,Y,Q)}updateToolState($,Z){if(!this.currentSessionId)throw Error("没有活动会话");this.memory.updateToolState($,Z)}updateWorkspace($){if(!this.currentSessionId)throw Error("没有活动会话");this.memory.updateWorkspace($)}async getFormattedContext($){let Z=this.memory.getContext();if(!Z)throw Error("没有可用的上下文数据");let Y=this.filter.filter(Z,$),Q=this.shouldCompress(Y),X;if(Q){let J=this.hashContext(Y);if(X=this.cache.getCompressedContext(J)??void 0,!X)X=await this.compressor.compress(Y),this.cache.cacheCompressedContext(J,X)}return{context:Y,compressed:X,tokenCount:X?X.tokenCount:Y.metadata.totalTokens}}async searchSessions($,Z=10){let Y=await this.persistent.listSessions(),Q=[];for(let X of Y){let J=await this.persistent.getSessionSummary(X);if(J){let G=this.calculateRelevance($,J.topics);if(G>0)Q.push({sessionId:X,summary:`${J.messageCount}条消息,主题:${J.topics.join("、")}`,lastActivity:J.lastActivity,relevanceScore:G})}}return Q.sort((X,J)=>J.relevanceScore-X.relevanceScore).slice(0,Z)}getCachedToolResult($,Z){return this.cache.getToolResult($,Z)}async getStats(){let[$,Z,Y]=await Promise.all([Promise.resolve(this.memory.getMemoryInfo()),Promise.resolve(this.cache.getStats()),this.persistent.getStorageStats()]);return{currentSession:this.currentSessionId,memory:$,cache:Z,storage:Y}}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 JK()}generateMessageId(){return JK()}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 Z=await this.compressor.compress($);$.layers.conversation.summary=Z.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 Z=JSON.stringify({messageCount:$.layers.conversation.messages.length,lastMessage:$.layers.conversation.messages[$.layers.conversation.messages.length-1]?.id,toolCallCount:$.layers.tool.recentCalls.length});return GK.createHash("md5").update(Z).digest("hex")}calculateRelevance($,Z){let Y=$.toLowerCase(),Q=0;for(let X of Z)if(Y.includes(X.toLowerCase())||X.toLowerCase().includes(Y))Q+=1;return Q}}var QZ=A(()=>{XK();X8()});class XZ{chatService;contextManager;memoryAdapter;constructor($,Z){this.chatService=$,this.contextManager=Z||new F8,this.memoryAdapter=this.createMemoryAdapter()}createMemoryAdapter(){let $=[];return{getMessages:()=>[...$],addMessage:(Z)=>{$.push(Z)},clearContext:()=>{$.length=0},getContextSize:()=>$.length}}getContextManager(){return this.contextManager}getMemoryAdapter(){return this.memoryAdapter}async executeTask($){let Z=[{role:"user",content:$.prompt}],Y=await this.chatService.chat(Z);return{taskId:$.id,content:Y.content,metadata:{taskType:$.type}}}}var KK=A(()=>{QZ()});import*as qK from"os";import*as WK from"path";function FB($){if(typeof $==="string")return $;try{return JSON.parse(JSON.stringify($))}catch{return String($)}}class O0{config;runtimeOptions;isInitialized=!1;activeTask;executionPipeline;systemPrompt;chatService;executionEngine;attachmentCollector;activeSkillContext;currentModelMaxContextTokens;constructor($,Z={},Y){this.config=$,this.runtimeOptions=Z,this.executionPipeline=Y||this.createDefaultPipeline()}createDefaultPipeline(){let $=new P9,Z={...this.config.permissions,...this.runtimeOptions.permissions},Y=this.runtimeOptions.permissionMode??this.config.permissionMode??"default";return new s5($,{permissionConfig:Z,permissionMode:Y,maxHistorySize:1000})}static async create($={}){if(await h8(),S3().length===0)throw Error(`❌ 没有可用的模型配置
2122
+ `).filter((Q)=>Q.trim().length>0).length;return{exists:!0,size:$.size,lineCount:Y}}catch($){return console.error(`[JSONLStore] 获取统计信息失败: ${this.filePath}`,$),{exists:!1,size:0,lineCount:0}}}async exists(){try{return await l0.access(this.filePath),!0}catch{return!1}}async delete(){try{if(await this.exists())await l0.unlink(this.filePath)}catch($){throw console.error(`[JSONLStore] 删除文件失败: ${this.filePath}`,$),$}}getFilePath(){return this.filePath}}var YK=()=>{};import{nanoid as J8}from"nanoid";import*as G4 from"node:fs/promises";import*as QK from"node:path";class YZ{projectPath;maxSessions;version;constructor($=process.cwd(),Z=100,Y="0.0.10"){this.projectPath=$,this.maxSessions=Z,this.version=Y}async initialize(){try{let $=Q3(this.projectPath);await G4.mkdir($,{recursive:!0,mode:493}),console.log(`[PersistentStore] 初始化存储目录: ${$}`)}catch($){console.warn("[PersistentStore] 无法创建持久化存储目录:",$)}}async saveMessage($,Z,Y,Q=null,X){try{let J=z1(this.projectPath,$),G=new P1(J),K={uuid:J8(),parentUuid:Q,sessionId:$,timestamp:new Date().toISOString(),type:Z==="user"?"user":Z==="assistant"?"assistant":Z==="tool"?"tool_result":"system",cwd:this.projectPath,gitBranch:n2(this.projectPath),version:this.version,message:{role:Z,content:Y,...X||{}}};return await G.append(K),K.uuid}catch(J){throw console.error(`[PersistentStore] 保存消息失败 (session: ${$}):`,J),J}}async saveToolUse($,Z,Y,Q=null){try{let X=z1(this.projectPath,$),J=new P1(X),G={uuid:J8(),parentUuid:Q,sessionId:$,timestamp:new Date().toISOString(),type:"tool_use",cwd:this.projectPath,gitBranch:n2(this.projectPath),version:this.version,message:{role:"assistant",content:""},tool:{id:J8(),name:Z,input:Y}};return await J.append(G),G.uuid}catch(X){throw console.error(`[PersistentStore] 保存工具调用失败 (session: ${$}):`,X),X}}async saveToolResult($,Z,Y,Q=null,X){try{let J=z1(this.projectPath,$),G=new P1(J),K={uuid:J8(),parentUuid:Q,sessionId:$,timestamp:new Date().toISOString(),type:"tool_result",cwd:this.projectPath,gitBranch:n2(this.projectPath),version:this.version,message:{role:"assistant",content:""},toolResult:{id:Z,output:Y,error:X}};return await G.append(K),K.uuid}catch(J){throw console.error(`[PersistentStore] 保存工具结果失败 (session: ${$}):`,J),J}}async saveCompaction($,Z,Y,Q=null){try{let X=z1(this.projectPath,$),J=new P1(X),G={uuid:J8(),parentUuid:Q,sessionId:$,timestamp:new Date().toISOString(),type:"system",subtype:"compact_boundary",cwd:this.projectPath,gitBranch:n2(this.projectPath),version:this.version,message:{role:"system",content:"=== 上下文压缩边界 ==="},compactMetadata:Y};await J.append(G),console.log("[PersistentStore] 保存压缩边界标记");let K={uuid:J8(),parentUuid:G.uuid,logicalParentUuid:Q??void 0,sessionId:$,timestamp:new Date().toISOString(),type:"user",isCompactSummary:!0,cwd:this.projectPath,gitBranch:n2(this.projectPath),version:this.version,message:{role:"user",content:Z},compactMetadata:Y};return await J.append(K),console.log("[PersistentStore] 保存压缩总结消息"),K.uuid}catch(X){throw console.error(`[PersistentStore] 保存压缩失败 (session: ${$}):`,X),X}}async saveContext($,Z){try{let{conversation:Y}=Z.layers;for(let Q of Y.messages)await this.saveMessage($,Q.role,Q.content,null)}catch(Y){console.warn(`[PersistentStore] 保存上下文失败 (session: ${$}):`,Y)}}async saveSession($,Z){console.warn("[PersistentStore] saveSession 方法已废弃,请使用 saveMessage")}async saveConversation($,Z){console.warn("[PersistentStore] saveConversation 方法已废弃,请使用 saveMessage")}async loadSession($){try{let Z=z1(this.projectPath,$),Q=await new P1(Z).readAll();if(Q.length===0)return null;let X=Q[0];return{sessionId:$,userId:void 0,preferences:{},configuration:{},startTime:new Date(X.timestamp).getTime()}}catch{return null}}async loadConversation($){try{let Z=z1(this.projectPath,$),Q=await new P1(Z).readAll();if(Q.length===0)return null;let X=Q.filter((K)=>["user","assistant","system"].includes(K.type)).map((K)=>({id:K.uuid,role:K.message.role,content:K.message.content,timestamp:new Date(K.timestamp).getTime()})),J=Q[Q.length-1],G=new Date(J.timestamp).getTime();return{messages:X,topics:[],lastActivity:G}}catch{return null}}async listSessions(){try{let $=Q3(this.projectPath);return(await G4.readdir($)).filter((Y)=>Y.endsWith(".jsonl")).map((Y)=>Y.replace(".jsonl","")).sort()}catch{return[]}}async getSessionSummary($){try{let Z=z1(this.projectPath,$),Y=new P1(Z);if(!(await Y.getStats()).exists)return null;let X=await Y.readAll();if(X.length===0)return null;let J=X[X.length-1];return{sessionId:$,lastActivity:new Date(J.timestamp).getTime(),messageCount:X.filter((G)=>["user","assistant"].includes(G.type)).length,topics:[]}}catch{return null}}async deleteSession($){try{let Z=z1(this.projectPath,$);await new P1(Z).delete()}catch(Z){console.warn(`[PersistentStore] 删除会话失败 (session: ${$}):`,Z)}}async cleanupOldSessions(){try{let $=await this.listSessions();if($.length<=this.maxSessions)return;let Q=(await Promise.all($.map((X)=>this.getSessionSummary(X)))).filter((X)=>X!==null).sort((X,J)=>J.lastActivity-X.lastActivity).slice(this.maxSessions).map((X)=>X.sessionId);await Promise.all(Q.map((X)=>this.deleteSession(X))),console.log(`[PersistentStore] 已清理 ${Q.length} 个旧会话`)}catch($){console.error("[PersistentStore] 清理旧会话失败:",$)}}async getStorageStats(){try{let $=await this.listSessions(),Z=0;for(let Y of $){let Q=z1(this.projectPath,Y),J=await new P1(Q).getStats();Z+=J.size}return{totalSessions:$.length,totalSize:Z,projectPath:this.projectPath}}catch{return{totalSessions:0,totalSize:0,projectPath:this.projectPath}}}async checkStorageHealth(){try{let $=Q3(this.projectPath);await G4.mkdir($,{recursive:!0,mode:493});let Z=QK.join($,".health-check");return await G4.writeFile(Z,"test","utf-8"),await G4.unlink(Z),{isAvailable:!0,canWrite:!0}}catch($){return{isAvailable:!1,canWrite:!1,error:$ instanceof Error?$.message:String($)}}}static async listAllProjects(){return sX()}}var XK=A(()=>{YK();X3()});import*as GK from"crypto";import{nanoid as JK}from"nanoid";class F3{memory;persistent;cache;compressor;filter;options;currentSessionId=null;initialized=!1;constructor($={}){let Z=$.storage?.persistentPath||J2();this.options={storage:{maxMemorySize:1000,persistentPath:Z,cacheSize:100,compressionEnabled:!0,...$.storage},defaultFilter:{maxTokens:32000,maxMessages:50,timeWindow:86400000,...$.defaultFilter},compressionThreshold:$.compressionThreshold||6000,enableVectorSearch:$.enableVectorSearch||!1},this.memory=new $Z(this.options.storage.maxMemorySize),this.persistent=new YZ(process.cwd(),100),this.cache=new e5(this.options.storage.cacheSize,300000),this.compressor=new t5,this.filter=new F2(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($,Z={},Y={}){let Q=Y.sessionId||this.generateSessionId(),X=Date.now(),J={layers:{system:await this.createSystemContext(),session:{sessionId:Q,userId:$,preferences:Z,configuration:Y,startTime:X},conversation:{messages:[],topics:[],lastActivity:X},tool:{recentCalls:[],toolStates:{},dependencies:{}},workspace:await this.createWorkspaceContext()},metadata:{totalTokens:0,priority:1,lastUpdated:X}};return this.memory.setContext(J),await this.persistent.saveContext(Q,J),this.currentSessionId=Q,console.log(`新会话已创建: ${Q}`),Q}async loadSession($){try{let Z=this.memory.getContext();if(!Z||Z.layers.session.sessionId!==$){let[Y,Q]=await Promise.all([this.persistent.loadSession($),this.persistent.loadConversation($)]);if(!Y||!Q)return!1;Z={layers:{system:await this.createSystemContext(),session:Y,conversation:Q,tool:{recentCalls:[],toolStates:{},dependencies:{}},workspace:await this.createWorkspaceContext()},metadata:{totalTokens:0,priority:1,lastUpdated:Date.now()}},this.memory.setContext(Z)}return this.currentSessionId=$,console.log(`会话已加载: ${$}`),!0}catch(Z){return console.error("加载会话失败:",Z),!1}}async addMessage($,Z,Y){if(!this.currentSessionId)throw Error("没有活动会话");let Q={id:this.generateMessageId(),role:$,content:Z,timestamp:Date.now(),metadata:Y};this.memory.addMessage(Q);let X=this.memory.getContext();if(X&&this.shouldCompress(X))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($,Z,Y,Q=null,X){return this.persistent.saveMessage($,Z,Y,Q,X)}async saveToolUse($,Z,Y,Q=null){return this.persistent.saveToolUse($,Z,Y,Q)}async saveToolResult($,Z,Y,Q=null,X){return this.persistent.saveToolResult($,Z,Y,Q,X)}async saveCompaction($,Z,Y,Q=null){return this.persistent.saveCompaction($,Z,Y,Q)}updateToolState($,Z){if(!this.currentSessionId)throw Error("没有活动会话");this.memory.updateToolState($,Z)}updateWorkspace($){if(!this.currentSessionId)throw Error("没有活动会话");this.memory.updateWorkspace($)}async getFormattedContext($){let Z=this.memory.getContext();if(!Z)throw Error("没有可用的上下文数据");let Y=this.filter.filter(Z,$),Q=this.shouldCompress(Y),X;if(Q){let J=this.hashContext(Y);if(X=this.cache.getCompressedContext(J)??void 0,!X)X=await this.compressor.compress(Y),this.cache.cacheCompressedContext(J,X)}return{context:Y,compressed:X,tokenCount:X?X.tokenCount:Y.metadata.totalTokens}}async searchSessions($,Z=10){let Y=await this.persistent.listSessions(),Q=[];for(let X of Y){let J=await this.persistent.getSessionSummary(X);if(J){let G=this.calculateRelevance($,J.topics);if(G>0)Q.push({sessionId:X,summary:`${J.messageCount}条消息,主题:${J.topics.join("、")}`,lastActivity:J.lastActivity,relevanceScore:G})}}return Q.sort((X,J)=>J.relevanceScore-X.relevanceScore).slice(0,Z)}getCachedToolResult($,Z){return this.cache.getToolResult($,Z)}async getStats(){let[$,Z,Y]=await Promise.all([Promise.resolve(this.memory.getMemoryInfo()),Promise.resolve(this.cache.getStats()),this.persistent.getStorageStats()]);return{currentSession:this.currentSessionId,memory:$,cache:Z,storage:Y}}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 JK()}generateMessageId(){return JK()}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 Z=await this.compressor.compress($);$.layers.conversation.summary=Z.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 Z=JSON.stringify({messageCount:$.layers.conversation.messages.length,lastMessage:$.layers.conversation.messages[$.layers.conversation.messages.length-1]?.id,toolCallCount:$.layers.tool.recentCalls.length});return GK.createHash("md5").update(Z).digest("hex")}calculateRelevance($,Z){let Y=$.toLowerCase(),Q=0;for(let X of Z)if(Y.includes(X.toLowerCase())||X.toLowerCase().includes(Y))Q+=1;return Q}}var QZ=A(()=>{XK();X3()});class XZ{chatService;contextManager;memoryAdapter;constructor($,Z){this.chatService=$,this.contextManager=Z||new F3,this.memoryAdapter=this.createMemoryAdapter()}createMemoryAdapter(){let $=[];return{getMessages:()=>[...$],addMessage:(Z)=>{$.push(Z)},clearContext:()=>{$.length=0},getContextSize:()=>$.length}}getContextManager(){return this.contextManager}getMemoryAdapter(){return this.memoryAdapter}async executeTask($){let Z=[{role:"user",content:$.prompt}],Y=await this.chatService.chat(Z);return{taskId:$.id,content:Y.content,metadata:{taskType:$.type}}}}var KK=A(()=>{QZ()});import*as qK from"os";import*as WK from"path";function FB($){if(typeof $==="string")return $;try{return JSON.parse(JSON.stringify($))}catch{return String($)}}class O0{config;runtimeOptions;isInitialized=!1;activeTask;executionPipeline;systemPrompt;chatService;executionEngine;attachmentCollector;activeSkillContext;currentModelMaxContextTokens;constructor($,Z={},Y){this.config=$,this.runtimeOptions=Z,this.executionPipeline=Y||this.createDefaultPipeline()}createDefaultPipeline(){let $=new P9,Z={...this.config.permissions,...this.runtimeOptions.permissions},Y=this.runtimeOptions.permissionMode??this.config.permissionMode??"default";return new s5($,{permissionConfig:Z,permissionMode:Y,maxHistorySize:1000})}static async create($={}){if(await h3(),S8().length===0)throw Error(`❌ 没有可用的模型配置
2123
2123
 
2124
2124
  `+`请先使用以下命令添加模型:
2125
2125
  `+` /model add
2126
2126
 
2127
2127
  `+`或运行初始化向导:
2128
- `+" /init");let Y=H0();if(!Y)throw Error("❌ 配置未初始化,请确保应用已正确启动");u0.getInstance().validateConfig(Y);let X=new O0(Y,$);if(await X.initialize(),$.toolWhitelist&&$.toolWhitelist.length>0)X.applyToolWhitelist($.toolWhitelist);return X}async initialize(){if(this.isInitialized)return;try{this.log("初始化Agent..."),await this.initializeSystemPrompt(),await this.registerBuiltinTools(),await this.loadSubagents(),await this.discoverSkills();let $=h4();if(!$)throw Error("❌ 当前模型配置未找到");this.log(`\uD83D\uDE80 使用模型: ${$.name} (${$.model})`);let Z=X3($),Y=QQ(),Q=Z&&Y;if(Z&&!Y)this.log("\uD83E\uDDE0 模型支持 Thinking,但用户未开启(按 Tab 开启)");else if(Q)this.log("\uD83E\uDDE0 Thinking 模式已启用,启用 reasoning_content 支持");this.currentModelMaxContextTokens=$.maxContextTokens??this.config.maxContextTokens,this.chatService=await s8({provider:$.provider,apiKey:$.apiKey,model:$.model,baseUrl:$.baseUrl,temperature:$.temperature??this.config.temperature,maxContextTokens:this.currentModelMaxContextTokens,maxOutputTokens:$.maxOutputTokens??this.config.maxOutputTokens,timeout:this.config.timeout,supportsThinking:Q}),this.executionEngine=new XZ(this.chatService),this.attachmentCollector=new i7({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 Z=await this.executionEngine.executeTask($);return this.activeTask=void 0,this.log(`任务执行完成: ${$.id}`),Z}catch(Z){throw this.activeTask=void 0,this.error(`任务执行失败: ${$.id}`,Z),Z}}async chat($,Z,Y){if(!this.isInitialized)throw Error("Agent未初始化");let Q=await this.processAtMentionsForContent($);if(Z){let K={signal:Z.signal,...Y},q;if(Z.permissionMode==="plan")q=await this.runPlanLoop(Q,Z,K);else if(Z.permissionMode==="spec")q=await this.runSpecLoop(Q,Z,K);else q=await this.runLoop(Q,Z,K);if(!q.success){if(q.error?.type==="aborted"||q.metadata?.shouldExitLoop)return"";throw Error(q.error?.message||"执行失败")}if(q.metadata?.targetMode&&Z.permissionMode==="plan"){let W=q.metadata.targetMode,U=q.metadata.planContent;h.debug(`\uD83D\uDD04 Plan 模式已批准,切换到 ${W} 模式并重新执行`),await x$().setPermissionMode(W),h.debug(`✅ 权限模式已更新: ${W}`);let H={...Z,permissionMode:W},F=Q;if(U){let O=`
2128
+ `+" /init");let Y=H0();if(!Y)throw Error("❌ 配置未初始化,请确保应用已正确启动");u0.getInstance().validateConfig(Y);let X=new O0(Y,$);if(await X.initialize(),$.toolWhitelist&&$.toolWhitelist.length>0)X.applyToolWhitelist($.toolWhitelist);return X}async initialize(){if(this.isInitialized)return;try{this.log("初始化Agent..."),await this.initializeSystemPrompt(),await this.registerBuiltinTools(),await this.loadSubagents(),await this.discoverSkills();let $=h2();if(!$)throw Error("❌ 当前模型配置未找到");this.log(`\uD83D\uDE80 使用模型: ${$.name} (${$.model})`);let Z=X8($),Y=QQ(),Q=Z&&Y;if(Z&&!Y)this.log("\uD83E\uDDE0 模型支持 Thinking,但用户未开启(按 Tab 开启)");else if(Q)this.log("\uD83E\uDDE0 Thinking 模式已启用,启用 reasoning_content 支持");this.currentModelMaxContextTokens=$.maxContextTokens??this.config.maxContextTokens,this.chatService=await s3({provider:$.provider,apiKey:$.apiKey,model:$.model,baseUrl:$.baseUrl,temperature:$.temperature??this.config.temperature,maxContextTokens:this.currentModelMaxContextTokens,maxOutputTokens:$.maxOutputTokens??this.config.maxOutputTokens,timeout:this.config.timeout,supportsThinking:Q}),this.executionEngine=new XZ(this.chatService),this.attachmentCollector=new i7({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 Z=await this.executionEngine.executeTask($);return this.activeTask=void 0,this.log(`任务执行完成: ${$.id}`),Z}catch(Z){throw this.activeTask=void 0,this.error(`任务执行失败: ${$.id}`,Z),Z}}async chat($,Z,Y){if(!this.isInitialized)throw Error("Agent未初始化");let Q=await this.processAtMentionsForContent($);if(Z){let K={signal:Z.signal,...Y},q;if(Z.permissionMode==="plan")q=await this.runPlanLoop(Q,Z,K);else if(Z.permissionMode==="spec")q=await this.runSpecLoop(Q,Z,K);else q=await this.runLoop(Q,Z,K);if(!q.success){if(q.error?.type==="aborted"||q.metadata?.shouldExitLoop)return"";throw Error(q.error?.message||"执行失败")}if(q.metadata?.targetMode&&Z.permissionMode==="plan"){let W=q.metadata.targetMode,U=q.metadata.planContent;h.debug(`\uD83D\uDD04 Plan 模式已批准,切换到 ${W} 模式并重新执行`),await x$().setPermissionMode(W),h.debug(`✅ 权限模式已更新: ${W}`);let H={...Z,permissionMode:W},F=Q;if(U){let O=`
2129
2129
 
2130
2130
  <approved-plan>
2131
2131
  ${U}
2132
2132
  </approved-plan>
2133
2133
 
2134
2134
  IMPORTANT: Execute according to the approved plan above. Follow the steps exactly as specified.`;if(typeof Q==="string")F=Q+O;else F=[...Q,{type:"text",text:O}];h.debug(`\uD83D\uDCCB 已将 plan 内容注入到消息中 (${U.length} 字符)`)}return this.runLoop(F,H,K).then((O)=>{if(!O.success)throw Error(O.error?.message||"执行失败");return O.finalMessage||""})}return q.finalMessage||""}let X=typeof Q==="string"?Q:Q.filter((K)=>K.type==="text").map((K)=>K.text).join(`
2135
- `),J={id:this.generateTaskId(),type:"simple",prompt:X};return(await this.executeTask(J)).content}async runPlanLoop($,Z,Y){h.debug("\uD83D\uDD35 Processing Plan mode message...");let{prompt:Q}=await q9({projectPath:process.cwd(),mode:"plan",includeEnvironment:!0}),X;if(typeof $==="string")X=$8($);else{let J=$.filter((G)=>G.type==="text");if(J.length>0){let G=J[0];X=$.map((K)=>K===G?{type:"text",text:$8(G.text)}:K)}else X=[{type:"text",text:$8("")},...$]}return this.executeLoop(X,Z,Y,Q)}async runSpecLoop($,Z,Y){h.debug("\uD83D\uDD37 Processing Spec mode message...");let Q=m$.getInstance(),X=Z.workspaceRoot||process.cwd();try{await Q.initialize(X)}catch(U){h.warn("SpecManager initialization warning:",U)}let J=Q.getCurrentSpec(),G=await Q.getSteeringContextString(),K=G9(J,G),q,W=J?.phase||"init";if(typeof $==="string")q=`${K9(W)}
2135
+ `),J={id:this.generateTaskId(),type:"simple",prompt:X};return(await this.executeTask(J)).content}async runPlanLoop($,Z,Y){h.debug("\uD83D\uDD35 Processing Plan mode message...");let{prompt:Q}=await q9({projectPath:process.cwd(),mode:"plan",includeEnvironment:!0}),X;if(typeof $==="string")X=$3($);else{let J=$.filter((G)=>G.type==="text");if(J.length>0){let G=J[0];X=$.map((K)=>K===G?{type:"text",text:$3(G.text)}:K)}else X=[{type:"text",text:$3("")},...$]}return this.executeLoop(X,Z,Y,Q)}async runSpecLoop($,Z,Y){h.debug("\uD83D\uDD37 Processing Spec mode message...");let Q=m$.getInstance(),X=Z.workspaceRoot||process.cwd();try{await Q.initialize(X)}catch(U){h.warn("SpecManager initialization warning:",U)}let J=Q.getCurrentSpec(),G=await Q.getSteeringContextString(),K=G9(J,G),q,W=J?.phase||"init";if(typeof $==="string")q=`${K9(W)}
2136
2136
 
2137
2137
  ${$}`;else{let U=$.filter((H)=>H.type==="text");if(U.length>0){let H=U[0];q=$.map((F)=>F===H?{type:"text",text:`${K9(W)}
2138
2138
 
@@ -2158,9 +2158,9 @@ ${n.continueReason}
2158
2158
  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.
2159
2159
  </system-reminder>`;H.push({role:"user",content:y});continue}if(n.warning)h.warn(`[Agent] Stop hook warning: ${n.warning}`)}catch(R){h.warn("[Agent] Stop hook execution failed:",R)}try{let R=this.executionEngine?.getContextManager();if(R&&Z.sessionId&&b.content)if(b.content.trim()!=="")F=await R.saveMessage(Z.sessionId,"assistant",b.content,F);else h.debug("[Agent] 跳过保存空响应(任务完成时)")}catch(R){h.warn("[Agent] 保存助手消息失败:",R)}return{success:!0,finalMessage:b.content,metadata:{turnsCount:L,toolCallsCount:w.length,duration:Date.now()-X,tokensUsed:N}}}H.push({role:"assistant",content:b.content||"",reasoningContent:b.reasoningContent,tool_calls:b.toolCalls});try{let k=this.executionEngine?.getContextManager();if(k&&Z.sessionId&&b.content)if(b.content.trim()!=="")F=await k.saveMessage(Z.sessionId,"assistant",b.content,F);else h.debug("[Agent] 跳过保存空响应(工具调用时)")}catch(k){h.warn("[Agent] 保存助手工具调用消息失败:",k)}if(Y?.signal?.aborted)return h.info("[Agent] Aborting before tool execution due to signal.aborted=true"),{success:!1,error:{type:"aborted",message:"任务已被用户中止"},metadata:{turnsCount:L,toolCallsCount:w.length,duration:Date.now()-X}};let C=b.toolCalls.filter((k)=>k.type==="function");if(Y?.onToolStart&&!Y.signal?.aborted)for(let k of C){let g=this.executionPipeline.getRegistry().get(k.function.name)?.kind;Y.onToolStart(k,g)}let d=async(k)=>{try{let T=JSON.parse(k.function.arguments);if(T.todos&&typeof T.todos==="string")try{T.todos=JSON.parse(T.todos),this.log("[Agent] 自动修复了字符串化的 todos 参数")}catch{this.error("[Agent] todos 参数格式异常,将由验证层处理")}let g=null;try{let R=this.executionEngine?.getContextManager();if(R&&Z.sessionId)g=await R.saveToolUse(Z.sessionId,k.function.name,T,F)}catch(R){h.warn("[Agent] 保存工具调用失败:",R)}let j=Y?.signal;if(!j)h.error("[Agent] Missing signal in tool execution, this should not happen");h.debug("[Agent] Passing confirmationHandler to ExecutionPipeline.execute:",{toolName:k.function.name,hasHandler:!!Z.confirmationHandler,hasMethod:!!Z.confirmationHandler?.requestConfirmation,methodType:typeof Z.confirmationHandler?.requestConfirmation});let M=await this.executionPipeline.execute(k.function.name,T,{sessionId:Z.sessionId,userId:Z.userId||"default",workspaceRoot:Z.workspaceRoot||process.cwd(),signal:j,confirmationHandler:Z.confirmationHandler,permissionMode:Z.permissionMode});if(h.debug(`
2160
2160
  ========== 工具执行结果 ==========`),h.debug("工具名称:",k.function.name),h.debug("成功:",M.success),h.debug("LLM Content:",M.llmContent),h.debug("Display Content:",M.displayContent),M.error)h.debug("错误:",M.error);return h.debug(`==================================
2161
- `),{toolCall:k,result:M,toolUseUuid:g}}catch(T){return h.error(`Tool execution failed for ${k.function.name}:`,T),{toolCall:k,result:{success:!1,llmContent:"",displayContent:"",error:{type:"execution_error",message:T instanceof Error?T.message:"Unknown error"}},toolUseUuid:null,error:T instanceof Error?T:Error("Unknown error")}}};h.info(`[Agent] Executing ${C.length} tool calls in parallel`);let e=await Promise.all(C.map(d));for(let{toolCall:k,result:T,toolUseUuid:g}of e){if(w.push(T),T.metadata?.shouldExitLoop){h.debug("\uD83D\uDEAA 检测到退出循环标记,结束 Agent 循环");let R=typeof T.llmContent==="string"?T.llmContent:"循环已退出";return{success:T.success,finalMessage:R,metadata:{turnsCount:L,toolCallsCount:w.length,duration:Date.now()-X,shouldExitLoop:!0,targetMode:T.metadata?.targetMode}}}if(Y?.onToolResult&&!Y.signal?.aborted){h.debug("[Agent] Calling onToolResult:",{toolName:k.function.name,hasCallback:!0,resultSuccess:T.success,resultKeys:Object.keys(T),hasMetadata:!!T.metadata,metadataKeys:T.metadata?Object.keys(T.metadata):[],hasSummary:!!T.metadata?.summary,summary:T.metadata?.summary});try{await Y.onToolResult(k,T),h.debug("[Agent] onToolResult callback completed successfully")}catch(R){h.error("[Agent] onToolResult callback error:",R)}}try{let R=this.executionEngine?.getContextManager();if(R&&Z.sessionId)F=await R.saveToolResult(Z.sessionId,k.id,T.success?FB(T.llmContent):null,g,T.success?void 0:T.error?.message)}catch(R){h.warn("[Agent] 保存工具结果失败:",R)}if(k.function.name==="TodoWrite"&&T.success&&T.llmContent){let R=typeof T.llmContent==="object"?T.llmContent:{},y=Array.isArray(R)?R:R.todos||[];$2().setTodos(y),Y?.onTodoUpdate?.(y)}if(k.function.name==="Skill"&&T.success&&T.metadata){let R=T.metadata;if(R.skillName)this.activeSkillContext={skillName:R.skillName,allowedTools:R.allowedTools,basePath:R.basePath||""},h.debug(`\uD83C\uDFAF Skill "${this.activeSkillContext.skillName}" activated`+(this.activeSkillContext.allowedTools?` with allowed tools: ${this.activeSkillContext.allowedTools.join(", ")}`:""))}let j=T.success?T.llmContent||T.displayContent||"":T.error?.message||"执行失败";if(typeof j==="object"&&j!==null)j=JSON.stringify(j,null,2);let M=typeof j==="string"?j:JSON.stringify(j);H.push({role:"tool",tool_call_id:k.id,name:k.function.name,content:M})}if(Y?.signal?.aborted)return{success:!1,error:{type:"aborted",message:"任务已被用户中止"},metadata:{turnsCount:L,toolCallsCount:w.length,duration:Date.now()-X}};if(L>=B&&!z){if(h.info(`⚠️ 达到轮次上限 ${B} 轮,等待用户确认...`),Y?.onTurnLimitReached){let k=await Y.onTurnLimitReached({turnsCount:L});if(k?.continue){h.info("✅ 用户选择继续,压缩上下文...");try{let T=this.chatService.getConfig(),g=await u4.compact(Z.messages,{trigger:"auto",modelName:T.model,maxContextTokens:T.maxContextTokens??this.config.maxContextTokens,apiKey:T.apiKey,baseURL:T.baseUrl,actualPreTokens:D});Z.messages=g.compactedMessages;let j=H.find((R)=>R.role==="system");if(H.length=0,j)H.push(j);H.push(...Z.messages);let M={role:"user",content:`This session is being continued from a previous conversation. The conversation is summarized above.
2161
+ `),{toolCall:k,result:M,toolUseUuid:g}}catch(T){return h.error(`Tool execution failed for ${k.function.name}:`,T),{toolCall:k,result:{success:!1,llmContent:"",displayContent:"",error:{type:"execution_error",message:T instanceof Error?T.message:"Unknown error"}},toolUseUuid:null,error:T instanceof Error?T:Error("Unknown error")}}};h.info(`[Agent] Executing ${C.length} tool calls in parallel`);let e=await Promise.all(C.map(d));for(let{toolCall:k,result:T,toolUseUuid:g}of e){if(w.push(T),T.metadata?.shouldExitLoop){h.debug("\uD83D\uDEAA 检测到退出循环标记,结束 Agent 循环");let R=typeof T.llmContent==="string"?T.llmContent:"循环已退出";return{success:T.success,finalMessage:R,metadata:{turnsCount:L,toolCallsCount:w.length,duration:Date.now()-X,shouldExitLoop:!0,targetMode:T.metadata?.targetMode}}}if(Y?.onToolResult&&!Y.signal?.aborted){h.debug("[Agent] Calling onToolResult:",{toolName:k.function.name,hasCallback:!0,resultSuccess:T.success,resultKeys:Object.keys(T),hasMetadata:!!T.metadata,metadataKeys:T.metadata?Object.keys(T.metadata):[],hasSummary:!!T.metadata?.summary,summary:T.metadata?.summary});try{await Y.onToolResult(k,T),h.debug("[Agent] onToolResult callback completed successfully")}catch(R){h.error("[Agent] onToolResult callback error:",R)}}try{let R=this.executionEngine?.getContextManager();if(R&&Z.sessionId)F=await R.saveToolResult(Z.sessionId,k.id,T.success?FB(T.llmContent):null,g,T.success?void 0:T.error?.message)}catch(R){h.warn("[Agent] 保存工具结果失败:",R)}if(k.function.name==="TodoWrite"&&T.success&&T.llmContent){let R=typeof T.llmContent==="object"?T.llmContent:{},y=Array.isArray(R)?R:R.todos||[];$4().setTodos(y),Y?.onTodoUpdate?.(y)}if(k.function.name==="Skill"&&T.success&&T.metadata){let R=T.metadata;if(R.skillName)this.activeSkillContext={skillName:R.skillName,allowedTools:R.allowedTools,basePath:R.basePath||""},h.debug(`\uD83C\uDFAF Skill "${this.activeSkillContext.skillName}" activated`+(this.activeSkillContext.allowedTools?` with allowed tools: ${this.activeSkillContext.allowedTools.join(", ")}`:""))}let j=T.success?T.llmContent||T.displayContent||"":T.error?.message||"执行失败";if(typeof j==="object"&&j!==null)j=JSON.stringify(j,null,2);let M=typeof j==="string"?j:JSON.stringify(j);H.push({role:"tool",tool_call_id:k.id,name:k.function.name,content:M})}if(Y?.signal?.aborted)return{success:!1,error:{type:"aborted",message:"任务已被用户中止"},metadata:{turnsCount:L,toolCallsCount:w.length,duration:Date.now()-X}};if(L>=B&&!z){if(h.info(`⚠️ 达到轮次上限 ${B} 轮,等待用户确认...`),Y?.onTurnLimitReached){let k=await Y.onTurnLimitReached({turnsCount:L});if(k?.continue){h.info("✅ 用户选择继续,压缩上下文...");try{let T=this.chatService.getConfig(),g=await u2.compact(Z.messages,{trigger:"auto",modelName:T.model,maxContextTokens:T.maxContextTokens??this.config.maxContextTokens,apiKey:T.apiKey,baseURL:T.baseUrl,actualPreTokens:D});Z.messages=g.compactedMessages;let j=H.find((R)=>R.role==="system");if(H.length=0,j)H.push(j);H.push(...Z.messages);let M={role:"user",content:`This session is being continued from a previous conversation. The conversation is summarized above.
2162
2162
 
2163
- 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(M),Z.messages.push(M);try{let R=this.executionEngine?.getContextManager();if(R&&Z.sessionId)await R.saveCompaction(Z.sessionId,g.summary,{trigger:"auto",preTokens:g.preTokens,postTokens:g.postTokens,filesIncluded:g.filesIncluded},null)}catch(R){h.warn("[Agent] 保存压缩数据失败:",R)}h.info(`✅ 上下文已压缩 (${g.preTokens} → ${g.postTokens} tokens),重置轮次计数`)}catch(T){h.error("[Agent] 压缩失败,使用降级策略:",T);let g=H.find((M)=>M.role==="system"),j=H.slice(-80);if(H.length=0,g&&!j.some((M)=>M.role==="system"))H.push(g);H.push(...j),Z.messages=H.filter((M)=>M.role!=="system"),h.warn(`⚠️ 降级压缩完成,保留 ${H.length} 条消息`)}L=0;continue}return{success:!0,finalMessage:k?.reason||"已达到对话轮次上限,用户选择停止",metadata:{turnsCount:L,toolCallsCount:w.length,duration:Date.now()-X,tokensUsed:N}}}return{success:!1,error:{type:"max_turns_exceeded",message:`已达到轮次上限 (${B} 轮)。使用 --permission-mode yolo 跳过此限制。`},metadata:{turnsCount:L,toolCallsCount:w.length,duration:Date.now()-X,tokensUsed:N}}}}}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()-X}};return h.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()-X}}}}async processStreamResponse($,Z,Y){let Q="",X="",J,G=new Map;try{let K=this.chatService.streamChat($,Z,Y?.signal),q=0;for await(let W of K){if(q++,Y?.signal?.aborted)break;if(W.content){let U=W.content.length;Q+=W.content,F1("processStreamResponse","onContentDelta BEFORE",{chunkLen:U,accumulatedLen:Q.length}),Y?.onContentDelta?.(W.content),F1("processStreamResponse","onContentDelta AFTER",{chunkLen:U,accumulatedLen:Q.length})}if(W.reasoningContent)X+=W.reasoningContent,Y?.onThinkingDelta?.(W.reasoningContent);if(W.usage)J=W.usage;if(W.toolCalls)for(let U of W.toolCalls)this.accumulateToolCall(G,U);if(W.finishReason){F1("processStreamResponse","finishReason received",{finishReason:W.finishReason,fullContentLen:Q.length,fullReasoningContentLen:X.length,toolCallAccumulatorSize:G.size});break}}if(F1("processStreamResponse","stream ended",{fullContentLen:Q.length,fullReasoningContentLen:X.length,toolCallAccumulatorSize:G.size}),q===0&&!Y?.signal?.aborted&&Q.length===0&&G.size===0)return h.warn("[Agent] 流式响应返回0个chunk,回退到非流式模式"),this.chatService.chat($,Z,Y?.signal);return{content:Q,reasoningContent:X||void 0,toolCalls:this.buildFinalToolCalls(G),usage:J}}catch(K){if(this.isStreamingNotSupportedError(K))return h.warn("[Agent] 流式请求失败,降级到非流式模式"),this.chatService.chat($,Z,Y?.signal);throw K}}accumulateToolCall($,Z){let Y=Z,Q=Y.index??0;if(!$.has(Q))$.set(Q,{id:Y.id||"",name:Y.function?.name||"",arguments:""});let X=$.get(Q);if(Y.id&&!X.id)X.id=Y.id;if(Y.function?.name&&!X.name)X.name=Y.function.name;if(Y.function?.arguments)X.arguments+=Y.function.arguments}buildFinalToolCalls($){if($.size===0)return;return Array.from($.values()).filter((Z)=>Z.id&&Z.name).map((Z)=>({id:Z.id,type:"function",function:{name:Z.name,arguments:Z.arguments}}))}isStreamingNotSupportedError($){if(!($ instanceof Error))return!1;return["stream not supported","streaming is not available","sse not supported","does not support streaming"].some((Y)=>$.message.toLowerCase().includes(Y.toLowerCase()))}async runAgenticLoop($,Z,Y){if(!this.isInitialized)throw Error("Agent未初始化");let Q={messages:Z.messages,userId:Z.userId||"subagent",sessionId:Z.sessionId||`subagent_${Date.now()}`,workspaceRoot:Z.workspaceRoot||process.cwd(),signal:Z.signal,confirmationHandler:Z.confirmationHandler};return await this.runLoop($,Q,Y)}async chatWithSystem($,Z){if(!this.isInitialized)throw Error("Agent未初始化");let Y=[{role:"system",content:$},{role:"user",content:Z}];return(await this.chatService.chat(Y)).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 Z=this.executionPipeline.getRegistry(),Q=Z.getAll().filter((X)=>!$.includes(X.name));for(let X of Q)Z.unregister(X.name);h.debug(`\uD83D\uDD12 Applied tool whitelist: ${$.join(", ")} (removed ${Q.length} tools)`)}getToolStats(){let $=this.getAvailableTools(),Z=new Map;return $.forEach((Y)=>{let Q=Z.get(Y.kind)||0;Z.set(Y.kind,Q+1)}),{totalTools:$.length,toolsByKind:Object.fromEntries(Z),toolNames:$.map((Y)=>Y.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($,Z){h.debug(`[MainAgent] ${$}`,Z||"")}error($,Z){h.error(`[MainAgent] ${$}`,Z||"")}async initializeSystemPrompt(){try{let $=this.runtimeOptions.systemPrompt,Z=this.runtimeOptions.appendSystemPrompt,Y=await q9({projectPath:process.cwd(),replaceDefault:$,append:Z,includeEnvironment:!1});if(this.systemPrompt=Y.prompt,this.systemPrompt)this.log("系统提示已加载"),h.debug(`[SystemPrompt] 加载来源: ${Y.sources.filter((Q)=>Q.loaded).map((Q)=>Q.name).join(", ")}`)}catch($){this.error("初始化系统提示失败",$)}}getSystemPrompt(){return this.systemPrompt}async checkAndCompactInLoop($,Z,Y,Q){if(Y===void 0)return h.debug(`[Agent] [轮次 ${Z}] 压缩检查: 跳过(无历史 usage 数据)`),!1;let X=this.chatService.getConfig(),J=X.model,G=X.maxContextTokens??this.config.maxContextTokens,K=X.maxOutputTokens??this.config.maxOutputTokens,q=G-K,W=Math.floor(q*0.8);if(h.debug(`[Agent] [轮次 ${Z}] 压缩检查:`,{promptTokens:Y,maxContextTokens:G,maxOutputTokens:K,availableForInput:q,threshold:W,shouldCompact:Y>=W}),Y<W)return!1;let U=Z===0?"[Agent] 触发自动压缩":`[Agent] [轮次 ${Z}] 触发循环内自动压缩`;h.debug(U),Q?.(!0);try{let H=await u4.compact($.messages,{trigger:"auto",modelName:J,maxContextTokens:G,apiKey:X.apiKey,baseURL:X.baseUrl,actualPreTokens:Y});if(H.success)$.messages=H.compactedMessages,h.debug(`[Agent] [轮次 ${Z}] 压缩完成: ${H.preTokens} → ${H.postTokens} tokens (-${((1-H.postTokens/H.preTokens)*100).toFixed(1)}%)`);else $.messages=H.compactedMessages,h.warn(`[Agent] [轮次 ${Z}] 压缩使用降级策略: ${H.preTokens} → ${H.postTokens} tokens`);try{let F=this.executionEngine?.getContextManager();if(F&&$.sessionId)await F.saveCompaction($.sessionId,H.summary,{trigger:"auto",preTokens:H.preTokens,postTokens:H.postTokens,filesIncluded:H.filesIncluded},null),h.debug(`[Agent] [轮次 ${Z}] 压缩数据已保存到 JSONL`)}catch(F){h.warn(`[Agent] [轮次 ${Z}] 保存压缩数据失败:`,F)}return Q?.(!1),!0}catch(H){return Q?.(!1),h.error(`[Agent] [轮次 ${Z}] 压缩失败,继续执行`,H),!1}}async registerBuiltinTools(){try{let $=await iG({sessionId:"default",configDir:WK.join(qK.homedir(),".blade")});h.debug(`\uD83D\uDCE6 Registering ${$.length} builtin tools...`),this.executionPipeline.getRegistry().registerAll($);let Z=this.executionPipeline.getRegistry().getAll().length;h.debug(`✅ Builtin tools registered: ${Z} tools`),h.debug(`[Tools] ${this.executionPipeline.getRegistry().getAll().map((Y)=>Y.name).join(", ")}`),await this.registerMcpTools()}catch($){throw h.error("Failed to register builtin tools:",$),$}}async registerMcpTools(){try{if(this.runtimeOptions.mcpConfig&&this.runtimeOptions.mcpConfig.length>0)await OX(this.runtimeOptions.mcpConfig);let $=W1();if(Object.keys($).length===0){h.debug("\uD83D\uDCE6 No MCP servers configured");return}let Z=b0.getInstance();for(let[Q,X]of Object.entries($))try{h.debug(`\uD83D\uDD0C Connecting to MCP server: ${Q}`),await Z.registerServer(Q,X),h.debug(`✅ MCP server "${Q}" connected`)}catch(J){h.warn(`⚠️ MCP server "${Q}" connection failed:`,J)}let Y=await Z.getAvailableTools();if(Y.length>0)this.executionPipeline.getRegistry().registerAll(Y),h.debug(`✅ Registered ${Y.length} MCP tools`),h.debug(`[MCP Tools] ${Y.map((Q)=>Q.name).join(", ")}`)}catch($){h.warn("Failed to register MCP tools:",$)}}async loadSubagents(){if(J0.getAllNames().length>0){h.debug(`\uD83D\uDCE6 Subagents already loaded: ${J0.getAllNames().join(", ")}`);return}try{let $=J0.loadFromStandardLocations();if($>0)h.debug(`✅ Loaded ${$} subagents: ${J0.getAllNames().join(", ")}`);else h.debug("\uD83D\uDCE6 No subagents configured")}catch($){h.warn("Failed to load subagents:",$)}}async discoverSkills(){try{let $=await Y4({cwd:process.cwd()});if($.skills.length>0)h.debug(`✅ Discovered ${$.skills.length} skills: ${$.skills.map((Z)=>Z.name).join(", ")}`);else h.debug("\uD83D\uDCE6 No skills configured");for(let Z of $.errors)h.warn(`⚠️ Skill loading error at ${Z.path}: ${Z.error}`)}catch($){h.warn("Failed to discover skills:",$)}}applySkillToolRestrictions($){if(!this.activeSkillContext?.allowedTools)return $;let Z=this.activeSkillContext.allowedTools;h.debug(`\uD83D\uDD12 Applying Skill tool restrictions: ${Z.join(", ")}`);let Y=$.filter((Q)=>{return Z.some((X)=>{if(X===Q.name)return!0;let J=X.match(/^(\w+)\(.*\)$/);if(J&&J[1]===Q.name)return!0;return!1})});return h.debug(`\uD83D\uDD12 Filtered tools: ${Y.map((Q)=>Q.name).join(", ")} (${Y.length}/${$.length})`),Y}clearSkillContext(){if(this.activeSkillContext)h.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 Z=[];for(let Q of $)if(Q.type==="text")Z.push(Q.text);if(Z.length===0)return $;let Y=Z.join(`
2163
+ 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(M),Z.messages.push(M);try{let R=this.executionEngine?.getContextManager();if(R&&Z.sessionId)await R.saveCompaction(Z.sessionId,g.summary,{trigger:"auto",preTokens:g.preTokens,postTokens:g.postTokens,filesIncluded:g.filesIncluded},null)}catch(R){h.warn("[Agent] 保存压缩数据失败:",R)}h.info(`✅ 上下文已压缩 (${g.preTokens} → ${g.postTokens} tokens),重置轮次计数`)}catch(T){h.error("[Agent] 压缩失败,使用降级策略:",T);let g=H.find((M)=>M.role==="system"),j=H.slice(-80);if(H.length=0,g&&!j.some((M)=>M.role==="system"))H.push(g);H.push(...j),Z.messages=H.filter((M)=>M.role!=="system"),h.warn(`⚠️ 降级压缩完成,保留 ${H.length} 条消息`)}L=0;continue}return{success:!0,finalMessage:k?.reason||"已达到对话轮次上限,用户选择停止",metadata:{turnsCount:L,toolCallsCount:w.length,duration:Date.now()-X,tokensUsed:N}}}return{success:!1,error:{type:"max_turns_exceeded",message:`已达到轮次上限 (${B} 轮)。使用 --permission-mode yolo 跳过此限制。`},metadata:{turnsCount:L,toolCallsCount:w.length,duration:Date.now()-X,tokensUsed:N}}}}}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()-X}};return h.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()-X}}}}async processStreamResponse($,Z,Y){let Q="",X="",J,G=new Map;try{let K=this.chatService.streamChat($,Z,Y?.signal),q=0;for await(let W of K){if(q++,Y?.signal?.aborted)break;if(W.content){let U=W.content.length;Q+=W.content,F1("processStreamResponse","onContentDelta BEFORE",{chunkLen:U,accumulatedLen:Q.length}),Y?.onContentDelta?.(W.content),F1("processStreamResponse","onContentDelta AFTER",{chunkLen:U,accumulatedLen:Q.length})}if(W.reasoningContent)X+=W.reasoningContent,Y?.onThinkingDelta?.(W.reasoningContent);if(W.usage)J=W.usage;if(W.toolCalls)for(let U of W.toolCalls)this.accumulateToolCall(G,U);if(W.finishReason){F1("processStreamResponse","finishReason received",{finishReason:W.finishReason,fullContentLen:Q.length,fullReasoningContentLen:X.length,toolCallAccumulatorSize:G.size});break}}if(F1("processStreamResponse","stream ended",{fullContentLen:Q.length,fullReasoningContentLen:X.length,toolCallAccumulatorSize:G.size}),q===0&&!Y?.signal?.aborted&&Q.length===0&&G.size===0)return h.warn("[Agent] 流式响应返回0个chunk,回退到非流式模式"),this.chatService.chat($,Z,Y?.signal);return{content:Q,reasoningContent:X||void 0,toolCalls:this.buildFinalToolCalls(G),usage:J}}catch(K){if(this.isStreamingNotSupportedError(K))return h.warn("[Agent] 流式请求失败,降级到非流式模式"),this.chatService.chat($,Z,Y?.signal);throw K}}accumulateToolCall($,Z){let Y=Z,Q=Y.index??0;if(!$.has(Q))$.set(Q,{id:Y.id||"",name:Y.function?.name||"",arguments:""});let X=$.get(Q);if(Y.id&&!X.id)X.id=Y.id;if(Y.function?.name&&!X.name)X.name=Y.function.name;if(Y.function?.arguments)X.arguments+=Y.function.arguments}buildFinalToolCalls($){if($.size===0)return;return Array.from($.values()).filter((Z)=>Z.id&&Z.name).map((Z)=>({id:Z.id,type:"function",function:{name:Z.name,arguments:Z.arguments}}))}isStreamingNotSupportedError($){if(!($ instanceof Error))return!1;return["stream not supported","streaming is not available","sse not supported","does not support streaming"].some((Y)=>$.message.toLowerCase().includes(Y.toLowerCase()))}async runAgenticLoop($,Z,Y){if(!this.isInitialized)throw Error("Agent未初始化");let Q={messages:Z.messages,userId:Z.userId||"subagent",sessionId:Z.sessionId||`subagent_${Date.now()}`,workspaceRoot:Z.workspaceRoot||process.cwd(),signal:Z.signal,confirmationHandler:Z.confirmationHandler};return await this.runLoop($,Q,Y)}async chatWithSystem($,Z){if(!this.isInitialized)throw Error("Agent未初始化");let Y=[{role:"system",content:$},{role:"user",content:Z}];return(await this.chatService.chat(Y)).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 Z=this.executionPipeline.getRegistry(),Q=Z.getAll().filter((X)=>!$.includes(X.name));for(let X of Q)Z.unregister(X.name);h.debug(`\uD83D\uDD12 Applied tool whitelist: ${$.join(", ")} (removed ${Q.length} tools)`)}getToolStats(){let $=this.getAvailableTools(),Z=new Map;return $.forEach((Y)=>{let Q=Z.get(Y.kind)||0;Z.set(Y.kind,Q+1)}),{totalTools:$.length,toolsByKind:Object.fromEntries(Z),toolNames:$.map((Y)=>Y.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($,Z){h.debug(`[MainAgent] ${$}`,Z||"")}error($,Z){h.error(`[MainAgent] ${$}`,Z||"")}async initializeSystemPrompt(){try{let $=this.runtimeOptions.systemPrompt,Z=this.runtimeOptions.appendSystemPrompt,Y=await q9({projectPath:process.cwd(),replaceDefault:$,append:Z,includeEnvironment:!1});if(this.systemPrompt=Y.prompt,this.systemPrompt)this.log("系统提示已加载"),h.debug(`[SystemPrompt] 加载来源: ${Y.sources.filter((Q)=>Q.loaded).map((Q)=>Q.name).join(", ")}`)}catch($){this.error("初始化系统提示失败",$)}}getSystemPrompt(){return this.systemPrompt}async checkAndCompactInLoop($,Z,Y,Q){if(Y===void 0)return h.debug(`[Agent] [轮次 ${Z}] 压缩检查: 跳过(无历史 usage 数据)`),!1;let X=this.chatService.getConfig(),J=X.model,G=X.maxContextTokens??this.config.maxContextTokens,K=X.maxOutputTokens??this.config.maxOutputTokens,q=G-K,W=Math.floor(q*0.8);if(h.debug(`[Agent] [轮次 ${Z}] 压缩检查:`,{promptTokens:Y,maxContextTokens:G,maxOutputTokens:K,availableForInput:q,threshold:W,shouldCompact:Y>=W}),Y<W)return!1;let U=Z===0?"[Agent] 触发自动压缩":`[Agent] [轮次 ${Z}] 触发循环内自动压缩`;h.debug(U),Q?.(!0);try{let H=await u2.compact($.messages,{trigger:"auto",modelName:J,maxContextTokens:G,apiKey:X.apiKey,baseURL:X.baseUrl,actualPreTokens:Y});if(H.success)$.messages=H.compactedMessages,h.debug(`[Agent] [轮次 ${Z}] 压缩完成: ${H.preTokens} → ${H.postTokens} tokens (-${((1-H.postTokens/H.preTokens)*100).toFixed(1)}%)`);else $.messages=H.compactedMessages,h.warn(`[Agent] [轮次 ${Z}] 压缩使用降级策略: ${H.preTokens} → ${H.postTokens} tokens`);try{let F=this.executionEngine?.getContextManager();if(F&&$.sessionId)await F.saveCompaction($.sessionId,H.summary,{trigger:"auto",preTokens:H.preTokens,postTokens:H.postTokens,filesIncluded:H.filesIncluded},null),h.debug(`[Agent] [轮次 ${Z}] 压缩数据已保存到 JSONL`)}catch(F){h.warn(`[Agent] [轮次 ${Z}] 保存压缩数据失败:`,F)}return Q?.(!1),!0}catch(H){return Q?.(!1),h.error(`[Agent] [轮次 ${Z}] 压缩失败,继续执行`,H),!1}}async registerBuiltinTools(){try{let $=await iG({sessionId:"default",configDir:WK.join(qK.homedir(),".blade")});h.debug(`\uD83D\uDCE6 Registering ${$.length} builtin tools...`),this.executionPipeline.getRegistry().registerAll($);let Z=this.executionPipeline.getRegistry().getAll().length;h.debug(`✅ Builtin tools registered: ${Z} tools`),h.debug(`[Tools] ${this.executionPipeline.getRegistry().getAll().map((Y)=>Y.name).join(", ")}`),await this.registerMcpTools()}catch($){throw h.error("Failed to register builtin tools:",$),$}}async registerMcpTools(){try{if(this.runtimeOptions.mcpConfig&&this.runtimeOptions.mcpConfig.length>0)await OX(this.runtimeOptions.mcpConfig);let $=W1();if(Object.keys($).length===0){h.debug("\uD83D\uDCE6 No MCP servers configured");return}let Z=b0.getInstance();for(let[Q,X]of Object.entries($))try{h.debug(`\uD83D\uDD0C Connecting to MCP server: ${Q}`),await Z.registerServer(Q,X),h.debug(`✅ MCP server "${Q}" connected`)}catch(J){h.warn(`⚠️ MCP server "${Q}" connection failed:`,J)}let Y=await Z.getAvailableTools();if(Y.length>0)this.executionPipeline.getRegistry().registerAll(Y),h.debug(`✅ Registered ${Y.length} MCP tools`),h.debug(`[MCP Tools] ${Y.map((Q)=>Q.name).join(", ")}`)}catch($){h.warn("Failed to register MCP tools:",$)}}async loadSubagents(){if(J0.getAllNames().length>0){h.debug(`\uD83D\uDCE6 Subagents already loaded: ${J0.getAllNames().join(", ")}`);return}try{let $=J0.loadFromStandardLocations();if($>0)h.debug(`✅ Loaded ${$} subagents: ${J0.getAllNames().join(", ")}`);else h.debug("\uD83D\uDCE6 No subagents configured")}catch($){h.warn("Failed to load subagents:",$)}}async discoverSkills(){try{let $=await Y2({cwd:process.cwd()});if($.skills.length>0)h.debug(`✅ Discovered ${$.skills.length} skills: ${$.skills.map((Z)=>Z.name).join(", ")}`);else h.debug("\uD83D\uDCE6 No skills configured");for(let Z of $.errors)h.warn(`⚠️ Skill loading error at ${Z.path}: ${Z.error}`)}catch($){h.warn("Failed to discover skills:",$)}}applySkillToolRestrictions($){if(!this.activeSkillContext?.allowedTools)return $;let Z=this.activeSkillContext.allowedTools;h.debug(`\uD83D\uDD12 Applying Skill tool restrictions: ${Z.join(", ")}`);let Y=$.filter((Q)=>{return Z.some((X)=>{if(X===Q.name)return!0;let J=X.match(/^(\w+)\(.*\)$/);if(J&&J[1]===Q.name)return!0;return!1})});return h.debug(`\uD83D\uDD12 Filtered tools: ${Y.map((Q)=>Q.name).join(", ")} (${Y.length}/${$.length})`),Y}clearSkillContext(){if(this.activeSkillContext)h.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 Z=[];for(let Q of $)if(Q.type==="text")Z.push(Q.text);if(Z.length===0)return $;let Y=Z.join(`
2164
2164
  `);try{let Q=await this.attachmentCollector.collect(Y);if(Q.length===0)return $;h.debug(`✅ Processed ${Q.length} @ file mentions in multimodal message`);let X=this.buildAttachmentText(Q);if(!X)return $;return[...$,{type:"text",text:X}]}catch(Q){return h.error("Failed to process @ mentions in multimodal message:",Q),$}}buildAttachmentText($){let Z=[],Y=[];for(let X of $)if(X.type==="file"){let J=X.metadata?.lineRange?` (lines ${X.metadata.lineRange.start}${X.metadata.lineRange.end?`-${X.metadata.lineRange.end}`:""})`:"";Z.push(`<file path="${X.path}"${J?` range="${J}"`:""}>`,X.content,"</file>")}else if(X.type==="directory")Z.push(`<directory path="${X.path}">`,X.content,"</directory>");else if(X.type==="error")Y.push(`- @${X.path}: ${X.error}`);let Q="";if(Z.length>0)Q+=`
2165
2165
 
2166
2166
  <system-reminder>
@@ -2183,10 +2183,10 @@ Please continue the conversation from where we left it off without asking the us
2183
2183
 
2184
2184
  ⚠️ Some files could not be loaded:
2185
2185
  `,X+=Q.join(`
2186
- `);return X}}var h;var X2=A(()=>{S4();S7();t0();O$();f7();zX();e2();TX();pX();l7();C7();Y2();O1();k$();aG();$K();ZK();j0();c7();T9();KK();U4();h=l("Agent")});import{z as U$}from"zod";function FK($){return BB.safeParse($)}var OB,zB,_B,HK,UK,BB;var JZ=A(()=>{OB=U$.string().min(2,"Plugin name must be at least 2 characters").max(64,"Plugin name must be at most 64 characters").regex(/^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]{1,2}$/,{message:"Plugin name must be lowercase letters, numbers, and hyphens only, starting and ending with alphanumeric"}),zB=U$.string().regex(/^\d+\.\d+\.\d+(-[\w.]+)?(\+[\w.]+)?$/,{message:"Version must be a valid semantic version (e.g., 1.0.0)"}),_B=U$.object({name:U$.string().min(1,"Author name is required"),email:U$.string().email().optional(),url:U$.string().url().optional()}),HK=U$.object({name:OB,description:U$.string().min(1,"Description is required").max(500,"Description must be at most 500 characters"),version:zB,author:_B.optional(),license:U$.string().optional(),repository:U$.string().url().optional(),homepage:U$.string().url().optional(),keywords:U$.array(U$.string()).optional(),dependencies:U$.record(U$.string()).optional(),bladeVersion:U$.string().optional()}),UK=U$.object({type:U$.enum(["stdio","sse","http"]),command:U$.string().optional(),args:U$.array(U$.string()).optional(),env:U$.record(U$.string()).optional(),url:U$.string().url().optional(),headers:U$.record(U$.string()).optional(),timeout:U$.number().positive().optional(),oauth:U$.object({enabled:U$.boolean().optional(),clientId:U$.string().optional(),clientSecret:U$.string().optional(),authorizationUrl:U$.string().url().optional(),tokenUrl:U$.string().url().optional(),scopes:U$.array(U$.string()).optional(),redirectUri:U$.string().url().optional()}).optional(),healthCheck:U$.object({enabled:U$.boolean().optional(),interval:U$.number().positive().optional(),timeout:U$.number().positive().optional(),failureThreshold:U$.number().positive().optional()}).optional()}),BB=U$.union([U$.object({mcpServers:U$.record(UK)}),U$.record(UK)])});import*as S9 from"node:fs/promises";import*as OK from"node:path";async function G3($){for(let{dir:Z,source:Y}of LB){let Q=OK.join($,Z,"plugin.json");try{await S9.access(Q)}catch{continue}try{let X=await S9.readFile(Q,"utf-8"),J=JSON.parse(X),G=HK.safeParse(J);if(!G.success){let K=G.error.issues.map((q)=>`${q.path.join(".")}: ${q.message}`).join("; ");throw Error(`Invalid plugin.json: ${K}`)}return u$.debug(`Parsed plugin manifest from ${Q}`),{manifest:G.data,source:Y,manifestPath:Q}}catch(X){if(X instanceof SyntaxError)throw Error(`Invalid JSON in ${Q}: ${X.message}`);throw X}}return null}async function zK($){try{return await G3($)!==null}catch{return!1}}var LB;var GZ=A(()=>{O$();JZ();LB=[{dir:".blade-plugin",source:"blade"},{dir:".claude-plugin",source:"claude"}]});import{execSync as _K}from"node:child_process";import*as i0 from"node:fs/promises";import{homedir as wB}from"node:os";import*as K3 from"node:path";class BK{userPluginsDir;constructor($){this.userPluginsDir=$||K3.join(wB(),".blade","plugins")}async install($){try{let Z=this.parseGitUrl($);if(!Z)return{success:!1,error:`Invalid source URL: ${$}`};let Y=this.extractPluginName(Z);if(!Y)return{success:!1,error:`Could not extract plugin name from URL: ${Z}`};await i0.mkdir(this.userPluginsDir,{recursive:!0,mode:493});let Q=K3.join(this.userPluginsDir,Y);try{return await i0.access(Q),{success:!1,pluginName:Y,pluginPath:Q,error:`Plugin "${Y}" already exists at ${Q}. Use /plugins uninstall first.`}}catch{}u$.info(`Cloning ${Z} to ${Q}...`);try{_K(`git clone --depth 1 "${Z}" "${Q}"`,{stdio:"pipe",timeout:60000})}catch(J){return{success:!1,pluginName:Y,error:`Failed to clone repository: ${J instanceof Error?J.message:String(J)}`}}if(!await zK(Q))return await i0.rm(Q,{recursive:!0,force:!0}),{success:!1,pluginName:Y,error:"Invalid plugin: No .blade-plugin/plugin.json or .claude-plugin/plugin.json found"};let X;try{X=await G3(Q)}catch(J){return await i0.rm(Q,{recursive:!0,force:!0}),{success:!1,pluginName:Y,error:`Invalid plugin manifest: ${J instanceof Error?J.message:String(J)}`}}if(!X)return await i0.rm(Q,{recursive:!0,force:!0}),{success:!1,pluginName:Y,error:"Invalid plugin manifest: No manifest found"};return u$.info(`Successfully installed plugin: ${X.manifest.name}`),{success:!0,pluginName:X.manifest.name,pluginPath:Q,manifest:X.manifest}}catch(Z){return{success:!1,error:`Installation failed: ${Z instanceof Error?Z.message:String(Z)}`}}}async uninstall($){try{let Z=K3.join(this.userPluginsDir,$);try{await i0.access(Z)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" not found at ${Z}`}}return await i0.rm(Z,{recursive:!0,force:!0}),u$.info(`Successfully uninstalled plugin: ${$}`),{success:!0,pluginName:$,pluginPath:Z}}catch(Z){return{success:!1,pluginName:$,error:`Uninstallation failed: ${Z instanceof Error?Z.message:String(Z)}`}}}async listInstalled(){try{return await i0.access(this.userPluginsDir),(await i0.readdir(this.userPluginsDir,{withFileTypes:!0})).filter((Z)=>Z.isDirectory()).map((Z)=>Z.name)}catch{return[]}}async update($){try{let Z=K3.join(this.userPluginsDir,$);try{await i0.access(Z)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" not found at ${Z}`}}let Y=K3.join(Z,".git");try{await i0.access(Y)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" is not a git repository`}}u$.info(`Updating plugin: ${$}...`);try{_K(`git -C "${Z}" pull --ff-only`,{stdio:"pipe",timeout:60000})}catch(X){return{success:!1,pluginName:$,error:`Failed to update: ${X instanceof Error?X.message:String(X)}`}}let Q;try{Q=await G3(Z)}catch(X){return{success:!1,pluginName:$,error:`Plugin manifest invalid after update: ${X instanceof Error?X.message:String(X)}`}}if(!Q)return{success:!1,pluginName:$,error:"Plugin manifest not found after update"};return u$.info(`Successfully updated plugin: ${Q.manifest.name}`),{success:!0,pluginName:Q.manifest.name,pluginPath:Z,manifest:Q.manifest}}catch(Z){return{success:!1,pluginName:$,error:`Update failed: ${Z instanceof Error?Z.message:String(Z)}`}}}parseGitUrl($){if($.startsWith("https://")||$.startsWith("git@"))return $;if(/^[a-zA-Z0-9_-]+\/[a-zA-Z0-9_.-]+$/.test($))return`https://github.com/${$}.git`;return null}extractPluginName($){let Z=$.match(/\/([a-zA-Z0-9_.-]+?)(?:\.git)?$/);if(Z)return Z[1];let Y=$.match(/:([a-zA-Z0-9_-]+\/)?([a-zA-Z0-9_.-]+?)(?:\.git)?$/);if(Y)return Y[2];return null}}function O8($){if(!KZ)KZ=new BK($);return KZ}var KZ=null;var LK=A(()=>{O$();GZ()});function k9($,Z){return`${$}:${Z}`}function wK($,Z){return`${$}__${Z}`}import*as X1 from"node:fs/promises";import{homedir as NB}from"node:os";import*as z0 from"node:path";import NK from"gray-matter";class f9{async loadPlugin($,Z,Y={}){let Q=await G3($);if(!Q)throw Error(`Not a valid plugin directory: ${$}`);let{manifest:X,source:J}=Q,G=X.name;u$.debug(`Loading plugin "${G}" from ${$}`);let K=Y.skipCommands?[]:await this.loadCommands($,G),q=Y.skipAgents?[]:await this.loadAgents($,G),W=Y.skipSkills?[]:await this.loadSkills($,G),U=Y.skipHooks?void 0:await this.loadHooks($),H=Y.skipMcp?void 0:await this.loadMcpConfig($,G);return u$.debug(`Plugin "${G}" loaded: ${K.length} commands, ${q.length} agents, ${W.length} skills`),{manifest:X,basePath:$,source:Z,manifestSource:J,commands:K,agents:q,skills:W,hooks:U,mcpServers:H,status:"active",loadedAt:new Date}}async loadCommands($,Z){let Y=z0.join($,"commands"),Q=[];if(!await this.dirExists(Y))return Q;let X=await this.scanMarkdownFiles(Y);for(let J of X)try{let G=await this.parseCommandFile(J,Y,Z);if(G)Q.push(G)}catch(G){u$.warn(`Failed to load command from ${J}: ${G instanceof Error?G.message:String(G)}`)}return Q}async parseCommandFile($,Z,Y){let Q=await X1.readFile($,"utf-8"),{data:X,content:J}=NK(Q),K=z0.relative(Z,$).split(z0.sep),q=K.pop();if(!q)return null;let W=q.replace(/\.md$/i,""),U=W;if(K.length>0)U=[...K,W].join("/");let H=k9(Y,U),F=this.normalizeCommandConfig(X);return{originalName:U,namespacedName:H,pluginName:Y,config:F,content:J.trim(),path:$}}normalizeCommandConfig($){return{description:this.asString($.description),allowedTools:this.parseStringArray($["allowed-tools"]),argumentHint:this.asString($["argument-hint"]),model:this.asString($.model),disableModelInvocation:$["disable-model-invocation"]===!0}}async loadAgents($,Z){let Y=z0.join($,"agents"),Q=[];if(!await this.dirExists(Y))return Q;let X=await this.scanMarkdownFiles(Y);for(let J of X)try{let G=await this.parseAgentFile(J,Y,Z);if(G)Q.push(G)}catch(G){u$.warn(`Failed to load agent from ${J}: ${G instanceof Error?G.message:String(G)}`)}return Q}async parseAgentFile($,Z,Y){let Q=await X1.readFile($,"utf-8"),{data:X,content:J}=NK(Q),G=z0.relative(Z,$),K=z0.basename(G,".md"),q=X.name||K,W=k9(Y,q),U={name:W,description:this.asString(X.description)||"",tools:this.parseStringArray(X.tools),color:this.asString(X.color),model:this.asString(X.model),permissionMode:this.asString(X.permissionMode),skills:this.parseStringArray(X.skills),systemPrompt:J.trim(),source:`plugin:${Y}`};return{originalName:q,namespacedName:W,pluginName:Y,config:U,path:$}}async loadSkills($,Z){let Y=z0.join($,"skills"),Q=[];if(!await this.dirExists(Y))return Q;let X=await X1.readdir(Y,{withFileTypes:!0});for(let J of X){if(!J.isDirectory())continue;let G=z0.join(Y,J.name),K=z0.join(G,"SKILL.md");try{let q=await Y9(K,"project");if(q.success&&q.content){let W=q.content.metadata.name,U=k9(Z,W);Q.push({originalName:W,namespacedName:U,pluginName:Z,metadata:{...q.content.metadata,name:U},path:G})}}catch(q){u$.warn(`Failed to load skill from ${K}: ${q instanceof Error?q.message:String(q)}`)}}return Q}async loadHooks($){let Z=z0.join($,"hooks","hooks.json");try{let Y=await X1.readFile(Z,"utf-8"),Q=JSON.parse(Y);return Q.hooks||Q}catch{return}}async loadMcpConfig($,Z){let Y=z0.join($,".mcp.json");try{let Q=await X1.readFile(Y,"utf-8"),X=JSON.parse(Q),J=FK(X);if(!J.success){u$.warn(`Invalid .mcp.json in ${$}: ${J.error}`);return}let G="mcpServers"in X?X.mcpServers:X,K={};for(let[q,W]of Object.entries(G)){let U=wK(Z,q);K[U]=W}return K}catch{return}}async scanMarkdownFiles($){let Z=[],Y=async(Q)=>{let X=await X1.readdir(Q,{withFileTypes:!0});for(let J of X){let G=z0.join(Q,J.name);if(J.isDirectory())await Y(G);else if(J.name.endsWith(".md"))Z.push(G)}};return await Y($),Z}async dirExists($){try{return(await X1.stat($)).isDirectory()}catch{return!1}}asString($){if(typeof $==="string"&&$.trim())return $.trim();return}parseStringArray($){if(!$)return;if(Array.isArray($))return $.map((Z)=>String(Z).trim()).filter(Boolean);if(typeof $==="string")return $.split(",").map((Z)=>Z.trim()).filter(Boolean);return}static getPluginDirs($){let Z=NB();return[{path:z0.join(Z,".claude","plugins"),source:"user",type:"claude"},{path:z0.join(Z,".blade","plugins"),source:"user",type:"blade"},{path:z0.join($,".claude","plugins"),source:"project",type:"claude"},{path:z0.join($,".blade","plugins"),source:"project",type:"blade"}]}async discoverPluginsInDir($,Z){let Y=[],Q=[];try{await X1.access($)}catch{return{plugins:Y,errors:Q}}let X=await X1.readdir($,{withFileTypes:!0});for(let J of X){if(!J.isDirectory())continue;let G=z0.join($,J.name);try{let K=await this.loadPlugin(G,Z);Y.push(K)}catch(K){Q.push({path:G,error:K instanceof Error?K.message:String(K)})}}return{plugins:Y,errors:Q}}}var bK=A(()=>{O$();m7();GZ();JZ()});class O4{static instance=null;plugins=new Map;loader=new f9;initialized=!1;workspaceRoot="";cliPluginDirs=[];constructor(){}static getInstance(){if(!O4.instance)O4.instance=new O4;return O4.instance}static resetInstance(){O4.instance=null}async initialize($,Z=[]){this.workspaceRoot=$,this.cliPluginDirs=Z;let Y=[],Q=[];for(let J of Z)try{let G=await this.loader.loadPlugin(J,"cli");this.plugins.set(G.manifest.name,G),Y.push(G),u$.info(`Loaded CLI plugin: ${G.manifest.name} from ${J}`)}catch(G){Q.push({path:J,error:G instanceof Error?G.message:String(G)}),u$.warn(`Failed to load CLI plugin from ${J}: ${G}`)}let X=f9.getPluginDirs($);for(let{path:J,source:G}of X){let K=await this.loader.discoverPluginsInDir(J,G);for(let q of K.plugins){let W=this.plugins.get(q.manifest.name);if(!W||W.source!=="cli")this.plugins.set(q.manifest.name,q),Y.push(q)}Q.push(...K.errors)}return this.initialized=!0,u$.info(`Plugin system initialized: ${this.plugins.size} plugins loaded`+(Q.length>0?`, ${Q.length} errors`:"")),{plugins:Array.from(this.plugins.values()),errors:Q}}isInitialized(){return this.initialized}getAll(){return Array.from(this.plugins.values())}getActive(){return Array.from(this.plugins.values()).filter(($)=>$.status==="active")}get($){return this.plugins.get($)}has($){return this.plugins.has($)}getBySource(){let $={cli:[],project:[],user:[]};for(let Z of this.plugins.values())$[Z.source].push(Z);return $}getAllCommands(){let $=[];for(let Z of this.plugins.values())if(Z.status==="active")$.push(...Z.commands);return $}getAllSkills(){let $=[];for(let Z of this.plugins.values())if(Z.status==="active")$.push(...Z.skills);return $}getAllAgents(){let $=[];for(let Z of this.plugins.values())if(Z.status==="active")$.push(...Z.agents);return $}findCommand($){for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.commands)if(Q.namespacedName===$)return Q}let Z=[];for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.commands)if(Q.originalName===$)Z.push(Q)}if(Z.length===1)return Z[0];return}findSkill($){for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.skills)if(Q.namespacedName===$)return Q}let Z=[];for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.skills)if(Q.originalName===$)Z.push(Q)}if(Z.length===1)return Z[0];return}findAgent($){for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.agents)if(Q.namespacedName===$)return Q}let Z=[];for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.agents)if(Q.originalName===$)Z.push(Q)}if(Z.length===1)return Z[0];return}hasCommandConflict($){let Z=0;for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.commands)if(Q.originalName===$){if(Z++,Z>1)return!0}}return!1}getCommandProviders($){let Z=[];for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.commands)if(Q.originalName===$){Z.push(Y.manifest.name);break}}return Z}disable($){let Z=this.plugins.get($);if(Z&&Z.status==="active")return Z.status="inactive",u$.info(`Plugin "${$}" disabled`),!0;return!1}enable($){let Z=this.plugins.get($);if(Z&&Z.status==="inactive")return Z.status="active",u$.info(`Plugin "${$}" enabled`),!0;return!1}async refresh(){return u$.info("Refreshing plugin list..."),this.plugins.clear(),this.initialized=!1,this.initialize(this.workspaceRoot,this.cliPluginDirs)}getStats(){let $=0,Z=0,Y=0,Q=0,X=0;for(let J of this.plugins.values())if(J.status==="active")$++,Y+=J.commands.length,Q+=J.skills.length,X+=J.agents.length;else Z++;return{total:this.plugins.size,active:$,inactive:Z,commands:Y,skills:Q,agents:X}}formatPluginList(){if(this.getAll().length===0)return"没有已加载的插件。";let Z=[],Y=this.getBySource();if(Y.cli.length>0){Z.push("## CLI 指定的插件");for(let Q of Y.cli){let X=Q.status==="inactive"?" (禁用)":"";Z.push(`- **${Q.manifest.name}** v${Q.manifest.version}${X}`),Z.push(` ${Q.manifest.description}`)}Z.push("")}if(Y.project.length>0){Z.push("## 项目级插件");for(let Q of Y.project){let X=Q.status==="inactive"?" (禁用)":"";Z.push(`- **${Q.manifest.name}** v${Q.manifest.version}${X}`),Z.push(` ${Q.manifest.description}`)}Z.push("")}if(Y.user.length>0){Z.push("## 用户级插件");for(let Q of Y.user){let X=Q.status==="inactive"?" (禁用)":"";Z.push(`- **${Q.manifest.name}** v${Q.manifest.version}${X}`),Z.push(` ${Q.manifest.description}`)}}return Z.join(`
2187
- `)}}function a0(){return O4.getInstance()}var qZ=A(()=>{O$();bK()});class WZ{commandRegistry;hookManager;mcpRegistry;constructor(){this.commandRegistry=B0.getInstance(),this.hookManager=M$.getInstance(),this.mcpRegistry=b0.getInstance()}clearAllPluginResources(){this.commandRegistry.clearPluginCommands(),R0().clearPluginSkills(),J0.clearPluginAgents(),u$.debug("Cleared all plugin resources from subsystems")}async integrateAll(){let Z=a0().getActive(),Y=[],Q=[],X=0,J=0,G=0,K=0;for(let q of Z){let W=await this.integratePlugin(q);Y.push(W),X+=W.commandsRegistered,J+=W.skillsRegistered,G+=W.agentsRegistered,K+=W.mcpServersRegistered,Q.push(...W.errors)}if(X+J+G>0)u$.info(`Plugin integration complete: ${X} commands, ${J} skills, ${G} agents, ${K} MCP servers`);return{plugins:Y,totalCommands:X,totalSkills:J,totalAgents:G,totalMcpServers:K,errors:Q}}async integratePlugin($){let Z={pluginName:$.manifest.name,commandsRegistered:0,skillsRegistered:0,agentsRegistered:0,hooksRegistered:!1,mcpServersRegistered:0,errors:[]};try{Z.commandsRegistered=this.integrateCommands($)}catch(Y){Z.errors.push(`Failed to integrate commands: ${Y instanceof Error?Y.message:String(Y)}`)}try{Z.skillsRegistered=this.integrateSkills($)}catch(Y){Z.errors.push(`Failed to integrate skills: ${Y instanceof Error?Y.message:String(Y)}`)}try{Z.agentsRegistered=this.integrateAgents($)}catch(Y){Z.errors.push(`Failed to integrate agents: ${Y instanceof Error?Y.message:String(Y)}`)}try{Z.hooksRegistered=this.integrateHooks($)}catch(Y){Z.errors.push(`Failed to integrate hooks: ${Y instanceof Error?Y.message:String(Y)}`)}try{Z.mcpServersRegistered=await this.integrateMcp($)}catch(Y){Z.errors.push(`Failed to integrate MCP servers: ${Y instanceof Error?Y.message:String(Y)}`)}return u$.debug(`Integrated plugin "${$.manifest.name}": ${Z.commandsRegistered} commands, ${Z.skillsRegistered} skills, ${Z.agentsRegistered} agents`),Z}integrateCommands($){let Z=0;for(let Y of $.commands)this.commandRegistry.registerPluginCommand(Y),Z++;return Z}integrateSkills($){let Z=R0(),Y=0;for(let Q of $.skills)Z.registerPluginSkill(Q),Y++;return Y}integrateAgents($){let Z=0;for(let Y of $.agents)J0.register({...Y.config,name:Y.namespacedName}),Z++;return Z}integrateHooks($){if(!$.hooks)return!1;let Z=this.hookManager.getConfig();return this.hookManager.loadConfig({...Z,...$.hooks}),!0}async integrateMcp($){if(!$.mcpServers)return 0;let Z=0;for(let[Y,Q]of Object.entries($.mcpServers))try{await this.mcpRegistry.registerServer(Y,Q),Z++}catch(X){u$.warn(`Failed to register MCP server "${Y}" from plugin "${$.manifest.name}": ${X instanceof Error?X.message:String(X)}`)}return Z}}async function E2(){return new WZ().integrateAll()}function h9(){new WZ().clearAllPluginResources()}var AK=A(()=>{U4();t0();O$();e2();Y2();y5();qZ()});var q3=A(()=>{LK();AK();qZ()});function d$($){if($.acp)return{sendMessage:(Z)=>$.acp.sendMessage(`• ${Z}
2186
+ `);return X}}var h;var X4=A(()=>{S2();S7();t0();O$();f7();zX();e4();TX();pX();l7();C7();Y4();O1();k$();aG();$K();ZK();j0();c7();T9();KK();U2();h=l("Agent")});import{z as U$}from"zod";function FK($){return BB.safeParse($)}var OB,zB,_B,HK,UK,BB;var JZ=A(()=>{OB=U$.string().min(2,"Plugin name must be at least 2 characters").max(64,"Plugin name must be at most 64 characters").regex(/^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]{1,2}$/,{message:"Plugin name must be lowercase letters, numbers, and hyphens only, starting and ending with alphanumeric"}),zB=U$.string().regex(/^\d+\.\d+\.\d+(-[\w.]+)?(\+[\w.]+)?$/,{message:"Version must be a valid semantic version (e.g., 1.0.0)"}),_B=U$.object({name:U$.string().min(1,"Author name is required"),email:U$.string().email().optional(),url:U$.string().url().optional()}),HK=U$.object({name:OB,description:U$.string().min(1,"Description is required").max(500,"Description must be at most 500 characters"),version:zB,author:_B.optional(),license:U$.string().optional(),repository:U$.string().url().optional(),homepage:U$.string().url().optional(),keywords:U$.array(U$.string()).optional(),dependencies:U$.record(U$.string()).optional(),bladeVersion:U$.string().optional()}),UK=U$.object({type:U$.enum(["stdio","sse","http"]),command:U$.string().optional(),args:U$.array(U$.string()).optional(),env:U$.record(U$.string()).optional(),url:U$.string().url().optional(),headers:U$.record(U$.string()).optional(),timeout:U$.number().positive().optional(),oauth:U$.object({enabled:U$.boolean().optional(),clientId:U$.string().optional(),clientSecret:U$.string().optional(),authorizationUrl:U$.string().url().optional(),tokenUrl:U$.string().url().optional(),scopes:U$.array(U$.string()).optional(),redirectUri:U$.string().url().optional()}).optional(),healthCheck:U$.object({enabled:U$.boolean().optional(),interval:U$.number().positive().optional(),timeout:U$.number().positive().optional(),failureThreshold:U$.number().positive().optional()}).optional()}),BB=U$.union([U$.object({mcpServers:U$.record(UK)}),U$.record(UK)])});import*as S9 from"node:fs/promises";import*as OK from"node:path";async function G8($){for(let{dir:Z,source:Y}of LB){let Q=OK.join($,Z,"plugin.json");try{await S9.access(Q)}catch{continue}try{let X=await S9.readFile(Q,"utf-8"),J=JSON.parse(X),G=HK.safeParse(J);if(!G.success){let K=G.error.issues.map((q)=>`${q.path.join(".")}: ${q.message}`).join("; ");throw Error(`Invalid plugin.json: ${K}`)}return u$.debug(`Parsed plugin manifest from ${Q}`),{manifest:G.data,source:Y,manifestPath:Q}}catch(X){if(X instanceof SyntaxError)throw Error(`Invalid JSON in ${Q}: ${X.message}`);throw X}}return null}async function zK($){try{return await G8($)!==null}catch{return!1}}var LB;var GZ=A(()=>{O$();JZ();LB=[{dir:".blade-plugin",source:"blade"},{dir:".claude-plugin",source:"claude"}]});import{execSync as _K}from"node:child_process";import*as i0 from"node:fs/promises";import{homedir as wB}from"node:os";import*as K8 from"node:path";class BK{userPluginsDir;constructor($){this.userPluginsDir=$||K8.join(wB(),".blade","plugins")}async install($){try{let Z=this.parseGitUrl($);if(!Z)return{success:!1,error:`Invalid source URL: ${$}`};let Y=this.extractPluginName(Z);if(!Y)return{success:!1,error:`Could not extract plugin name from URL: ${Z}`};await i0.mkdir(this.userPluginsDir,{recursive:!0,mode:493});let Q=K8.join(this.userPluginsDir,Y);try{return await i0.access(Q),{success:!1,pluginName:Y,pluginPath:Q,error:`Plugin "${Y}" already exists at ${Q}. Use /plugins uninstall first.`}}catch{}u$.info(`Cloning ${Z} to ${Q}...`);try{_K(`git clone --depth 1 "${Z}" "${Q}"`,{stdio:"pipe",timeout:60000})}catch(J){return{success:!1,pluginName:Y,error:`Failed to clone repository: ${J instanceof Error?J.message:String(J)}`}}if(!await zK(Q))return await i0.rm(Q,{recursive:!0,force:!0}),{success:!1,pluginName:Y,error:"Invalid plugin: No .blade-plugin/plugin.json or .claude-plugin/plugin.json found"};let X;try{X=await G8(Q)}catch(J){return await i0.rm(Q,{recursive:!0,force:!0}),{success:!1,pluginName:Y,error:`Invalid plugin manifest: ${J instanceof Error?J.message:String(J)}`}}if(!X)return await i0.rm(Q,{recursive:!0,force:!0}),{success:!1,pluginName:Y,error:"Invalid plugin manifest: No manifest found"};return u$.info(`Successfully installed plugin: ${X.manifest.name}`),{success:!0,pluginName:X.manifest.name,pluginPath:Q,manifest:X.manifest}}catch(Z){return{success:!1,error:`Installation failed: ${Z instanceof Error?Z.message:String(Z)}`}}}async uninstall($){try{let Z=K8.join(this.userPluginsDir,$);try{await i0.access(Z)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" not found at ${Z}`}}return await i0.rm(Z,{recursive:!0,force:!0}),u$.info(`Successfully uninstalled plugin: ${$}`),{success:!0,pluginName:$,pluginPath:Z}}catch(Z){return{success:!1,pluginName:$,error:`Uninstallation failed: ${Z instanceof Error?Z.message:String(Z)}`}}}async listInstalled(){try{return await i0.access(this.userPluginsDir),(await i0.readdir(this.userPluginsDir,{withFileTypes:!0})).filter((Z)=>Z.isDirectory()).map((Z)=>Z.name)}catch{return[]}}async update($){try{let Z=K8.join(this.userPluginsDir,$);try{await i0.access(Z)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" not found at ${Z}`}}let Y=K8.join(Z,".git");try{await i0.access(Y)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" is not a git repository`}}u$.info(`Updating plugin: ${$}...`);try{_K(`git -C "${Z}" pull --ff-only`,{stdio:"pipe",timeout:60000})}catch(X){return{success:!1,pluginName:$,error:`Failed to update: ${X instanceof Error?X.message:String(X)}`}}let Q;try{Q=await G8(Z)}catch(X){return{success:!1,pluginName:$,error:`Plugin manifest invalid after update: ${X instanceof Error?X.message:String(X)}`}}if(!Q)return{success:!1,pluginName:$,error:"Plugin manifest not found after update"};return u$.info(`Successfully updated plugin: ${Q.manifest.name}`),{success:!0,pluginName:Q.manifest.name,pluginPath:Z,manifest:Q.manifest}}catch(Z){return{success:!1,pluginName:$,error:`Update failed: ${Z instanceof Error?Z.message:String(Z)}`}}}parseGitUrl($){if($.startsWith("https://")||$.startsWith("git@"))return $;if(/^[a-zA-Z0-9_-]+\/[a-zA-Z0-9_.-]+$/.test($))return`https://github.com/${$}.git`;return null}extractPluginName($){let Z=$.match(/\/([a-zA-Z0-9_.-]+?)(?:\.git)?$/);if(Z)return Z[1];let Y=$.match(/:([a-zA-Z0-9_-]+\/)?([a-zA-Z0-9_.-]+?)(?:\.git)?$/);if(Y)return Y[2];return null}}function O3($){if(!KZ)KZ=new BK($);return KZ}var KZ=null;var LK=A(()=>{O$();GZ()});function k9($,Z){return`${$}:${Z}`}function wK($,Z){return`${$}__${Z}`}import*as X1 from"node:fs/promises";import{homedir as NB}from"node:os";import*as z0 from"node:path";import NK from"gray-matter";class f9{async loadPlugin($,Z,Y={}){let Q=await G8($);if(!Q)throw Error(`Not a valid plugin directory: ${$}`);let{manifest:X,source:J}=Q,G=X.name;u$.debug(`Loading plugin "${G}" from ${$}`);let K=Y.skipCommands?[]:await this.loadCommands($,G),q=Y.skipAgents?[]:await this.loadAgents($,G),W=Y.skipSkills?[]:await this.loadSkills($,G),U=Y.skipHooks?void 0:await this.loadHooks($),H=Y.skipMcp?void 0:await this.loadMcpConfig($,G);return u$.debug(`Plugin "${G}" loaded: ${K.length} commands, ${q.length} agents, ${W.length} skills`),{manifest:X,basePath:$,source:Z,manifestSource:J,commands:K,agents:q,skills:W,hooks:U,mcpServers:H,status:"active",loadedAt:new Date}}async loadCommands($,Z){let Y=z0.join($,"commands"),Q=[];if(!await this.dirExists(Y))return Q;let X=await this.scanMarkdownFiles(Y);for(let J of X)try{let G=await this.parseCommandFile(J,Y,Z);if(G)Q.push(G)}catch(G){u$.warn(`Failed to load command from ${J}: ${G instanceof Error?G.message:String(G)}`)}return Q}async parseCommandFile($,Z,Y){let Q=await X1.readFile($,"utf-8"),{data:X,content:J}=NK(Q),K=z0.relative(Z,$).split(z0.sep),q=K.pop();if(!q)return null;let W=q.replace(/\.md$/i,""),U=W;if(K.length>0)U=[...K,W].join("/");let H=k9(Y,U),F=this.normalizeCommandConfig(X);return{originalName:U,namespacedName:H,pluginName:Y,config:F,content:J.trim(),path:$}}normalizeCommandConfig($){return{description:this.asString($.description),allowedTools:this.parseStringArray($["allowed-tools"]),argumentHint:this.asString($["argument-hint"]),model:this.asString($.model),disableModelInvocation:$["disable-model-invocation"]===!0}}async loadAgents($,Z){let Y=z0.join($,"agents"),Q=[];if(!await this.dirExists(Y))return Q;let X=await this.scanMarkdownFiles(Y);for(let J of X)try{let G=await this.parseAgentFile(J,Y,Z);if(G)Q.push(G)}catch(G){u$.warn(`Failed to load agent from ${J}: ${G instanceof Error?G.message:String(G)}`)}return Q}async parseAgentFile($,Z,Y){let Q=await X1.readFile($,"utf-8"),{data:X,content:J}=NK(Q),G=z0.relative(Z,$),K=z0.basename(G,".md"),q=X.name||K,W=k9(Y,q),U={name:W,description:this.asString(X.description)||"",tools:this.parseStringArray(X.tools),color:this.asString(X.color),model:this.asString(X.model),permissionMode:this.asString(X.permissionMode),skills:this.parseStringArray(X.skills),systemPrompt:J.trim(),source:`plugin:${Y}`};return{originalName:q,namespacedName:W,pluginName:Y,config:U,path:$}}async loadSkills($,Z){let Y=z0.join($,"skills"),Q=[];if(!await this.dirExists(Y))return Q;let X=await X1.readdir(Y,{withFileTypes:!0});for(let J of X){if(!J.isDirectory())continue;let G=z0.join(Y,J.name),K=z0.join(G,"SKILL.md");try{let q=await Y9(K,"project");if(q.success&&q.content){let W=q.content.metadata.name,U=k9(Z,W);Q.push({originalName:W,namespacedName:U,pluginName:Z,metadata:{...q.content.metadata,name:U},path:G})}}catch(q){u$.warn(`Failed to load skill from ${K}: ${q instanceof Error?q.message:String(q)}`)}}return Q}async loadHooks($){let Z=z0.join($,"hooks","hooks.json");try{let Y=await X1.readFile(Z,"utf-8"),Q=JSON.parse(Y);return Q.hooks||Q}catch{return}}async loadMcpConfig($,Z){let Y=z0.join($,".mcp.json");try{let Q=await X1.readFile(Y,"utf-8"),X=JSON.parse(Q),J=FK(X);if(!J.success){u$.warn(`Invalid .mcp.json in ${$}: ${J.error}`);return}let G="mcpServers"in X?X.mcpServers:X,K={};for(let[q,W]of Object.entries(G)){let U=wK(Z,q);K[U]=W}return K}catch{return}}async scanMarkdownFiles($){let Z=[],Y=async(Q)=>{let X=await X1.readdir(Q,{withFileTypes:!0});for(let J of X){let G=z0.join(Q,J.name);if(J.isDirectory())await Y(G);else if(J.name.endsWith(".md"))Z.push(G)}};return await Y($),Z}async dirExists($){try{return(await X1.stat($)).isDirectory()}catch{return!1}}asString($){if(typeof $==="string"&&$.trim())return $.trim();return}parseStringArray($){if(!$)return;if(Array.isArray($))return $.map((Z)=>String(Z).trim()).filter(Boolean);if(typeof $==="string")return $.split(",").map((Z)=>Z.trim()).filter(Boolean);return}static getPluginDirs($){let Z=NB();return[{path:z0.join(Z,".claude","plugins"),source:"user",type:"claude"},{path:z0.join(Z,".blade","plugins"),source:"user",type:"blade"},{path:z0.join($,".claude","plugins"),source:"project",type:"claude"},{path:z0.join($,".blade","plugins"),source:"project",type:"blade"}]}async discoverPluginsInDir($,Z){let Y=[],Q=[];try{await X1.access($)}catch{return{plugins:Y,errors:Q}}let X=await X1.readdir($,{withFileTypes:!0});for(let J of X){if(!J.isDirectory())continue;let G=z0.join($,J.name);try{let K=await this.loadPlugin(G,Z);Y.push(K)}catch(K){Q.push({path:G,error:K instanceof Error?K.message:String(K)})}}return{plugins:Y,errors:Q}}}var bK=A(()=>{O$();m7();GZ();JZ()});class O2{static instance=null;plugins=new Map;loader=new f9;initialized=!1;workspaceRoot="";cliPluginDirs=[];constructor(){}static getInstance(){if(!O2.instance)O2.instance=new O2;return O2.instance}static resetInstance(){O2.instance=null}async initialize($,Z=[]){this.workspaceRoot=$,this.cliPluginDirs=Z;let Y=[],Q=[];for(let J of Z)try{let G=await this.loader.loadPlugin(J,"cli");this.plugins.set(G.manifest.name,G),Y.push(G),u$.info(`Loaded CLI plugin: ${G.manifest.name} from ${J}`)}catch(G){Q.push({path:J,error:G instanceof Error?G.message:String(G)}),u$.warn(`Failed to load CLI plugin from ${J}: ${G}`)}let X=f9.getPluginDirs($);for(let{path:J,source:G}of X){let K=await this.loader.discoverPluginsInDir(J,G);for(let q of K.plugins){let W=this.plugins.get(q.manifest.name);if(!W||W.source!=="cli")this.plugins.set(q.manifest.name,q),Y.push(q)}Q.push(...K.errors)}return this.initialized=!0,u$.info(`Plugin system initialized: ${this.plugins.size} plugins loaded`+(Q.length>0?`, ${Q.length} errors`:"")),{plugins:Array.from(this.plugins.values()),errors:Q}}isInitialized(){return this.initialized}getAll(){return Array.from(this.plugins.values())}getActive(){return Array.from(this.plugins.values()).filter(($)=>$.status==="active")}get($){return this.plugins.get($)}has($){return this.plugins.has($)}getBySource(){let $={cli:[],project:[],user:[]};for(let Z of this.plugins.values())$[Z.source].push(Z);return $}getAllCommands(){let $=[];for(let Z of this.plugins.values())if(Z.status==="active")$.push(...Z.commands);return $}getAllSkills(){let $=[];for(let Z of this.plugins.values())if(Z.status==="active")$.push(...Z.skills);return $}getAllAgents(){let $=[];for(let Z of this.plugins.values())if(Z.status==="active")$.push(...Z.agents);return $}findCommand($){for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.commands)if(Q.namespacedName===$)return Q}let Z=[];for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.commands)if(Q.originalName===$)Z.push(Q)}if(Z.length===1)return Z[0];return}findSkill($){for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.skills)if(Q.namespacedName===$)return Q}let Z=[];for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.skills)if(Q.originalName===$)Z.push(Q)}if(Z.length===1)return Z[0];return}findAgent($){for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.agents)if(Q.namespacedName===$)return Q}let Z=[];for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.agents)if(Q.originalName===$)Z.push(Q)}if(Z.length===1)return Z[0];return}hasCommandConflict($){let Z=0;for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.commands)if(Q.originalName===$){if(Z++,Z>1)return!0}}return!1}getCommandProviders($){let Z=[];for(let Y of this.plugins.values()){if(Y.status!=="active")continue;for(let Q of Y.commands)if(Q.originalName===$){Z.push(Y.manifest.name);break}}return Z}disable($){let Z=this.plugins.get($);if(Z&&Z.status==="active")return Z.status="inactive",u$.info(`Plugin "${$}" disabled`),!0;return!1}enable($){let Z=this.plugins.get($);if(Z&&Z.status==="inactive")return Z.status="active",u$.info(`Plugin "${$}" enabled`),!0;return!1}async refresh(){return u$.info("Refreshing plugin list..."),this.plugins.clear(),this.initialized=!1,this.initialize(this.workspaceRoot,this.cliPluginDirs)}getStats(){let $=0,Z=0,Y=0,Q=0,X=0;for(let J of this.plugins.values())if(J.status==="active")$++,Y+=J.commands.length,Q+=J.skills.length,X+=J.agents.length;else Z++;return{total:this.plugins.size,active:$,inactive:Z,commands:Y,skills:Q,agents:X}}formatPluginList(){if(this.getAll().length===0)return"没有已加载的插件。";let Z=[],Y=this.getBySource();if(Y.cli.length>0){Z.push("## CLI 指定的插件");for(let Q of Y.cli){let X=Q.status==="inactive"?" (禁用)":"";Z.push(`- **${Q.manifest.name}** v${Q.manifest.version}${X}`),Z.push(` ${Q.manifest.description}`)}Z.push("")}if(Y.project.length>0){Z.push("## 项目级插件");for(let Q of Y.project){let X=Q.status==="inactive"?" (禁用)":"";Z.push(`- **${Q.manifest.name}** v${Q.manifest.version}${X}`),Z.push(` ${Q.manifest.description}`)}Z.push("")}if(Y.user.length>0){Z.push("## 用户级插件");for(let Q of Y.user){let X=Q.status==="inactive"?" (禁用)":"";Z.push(`- **${Q.manifest.name}** v${Q.manifest.version}${X}`),Z.push(` ${Q.manifest.description}`)}}return Z.join(`
2187
+ `)}}function a0(){return O2.getInstance()}var qZ=A(()=>{O$();bK()});class WZ{commandRegistry;hookManager;mcpRegistry;constructor(){this.commandRegistry=B0.getInstance(),this.hookManager=M$.getInstance(),this.mcpRegistry=b0.getInstance()}clearAllPluginResources(){this.commandRegistry.clearPluginCommands(),R0().clearPluginSkills(),J0.clearPluginAgents(),u$.debug("Cleared all plugin resources from subsystems")}async integrateAll(){let Z=a0().getActive(),Y=[],Q=[],X=0,J=0,G=0,K=0;for(let q of Z){let W=await this.integratePlugin(q);Y.push(W),X+=W.commandsRegistered,J+=W.skillsRegistered,G+=W.agentsRegistered,K+=W.mcpServersRegistered,Q.push(...W.errors)}if(X+J+G>0)u$.info(`Plugin integration complete: ${X} commands, ${J} skills, ${G} agents, ${K} MCP servers`);return{plugins:Y,totalCommands:X,totalSkills:J,totalAgents:G,totalMcpServers:K,errors:Q}}async integratePlugin($){let Z={pluginName:$.manifest.name,commandsRegistered:0,skillsRegistered:0,agentsRegistered:0,hooksRegistered:!1,mcpServersRegistered:0,errors:[]};try{Z.commandsRegistered=this.integrateCommands($)}catch(Y){Z.errors.push(`Failed to integrate commands: ${Y instanceof Error?Y.message:String(Y)}`)}try{Z.skillsRegistered=this.integrateSkills($)}catch(Y){Z.errors.push(`Failed to integrate skills: ${Y instanceof Error?Y.message:String(Y)}`)}try{Z.agentsRegistered=this.integrateAgents($)}catch(Y){Z.errors.push(`Failed to integrate agents: ${Y instanceof Error?Y.message:String(Y)}`)}try{Z.hooksRegistered=this.integrateHooks($)}catch(Y){Z.errors.push(`Failed to integrate hooks: ${Y instanceof Error?Y.message:String(Y)}`)}try{Z.mcpServersRegistered=await this.integrateMcp($)}catch(Y){Z.errors.push(`Failed to integrate MCP servers: ${Y instanceof Error?Y.message:String(Y)}`)}return u$.debug(`Integrated plugin "${$.manifest.name}": ${Z.commandsRegistered} commands, ${Z.skillsRegistered} skills, ${Z.agentsRegistered} agents`),Z}integrateCommands($){let Z=0;for(let Y of $.commands)this.commandRegistry.registerPluginCommand(Y),Z++;return Z}integrateSkills($){let Z=R0(),Y=0;for(let Q of $.skills)Z.registerPluginSkill(Q),Y++;return Y}integrateAgents($){let Z=0;for(let Y of $.agents)J0.register({...Y.config,name:Y.namespacedName}),Z++;return Z}integrateHooks($){if(!$.hooks)return!1;let Z=this.hookManager.getConfig();return this.hookManager.loadConfig({...Z,...$.hooks}),!0}async integrateMcp($){if(!$.mcpServers)return 0;let Z=0;for(let[Y,Q]of Object.entries($.mcpServers))try{await this.mcpRegistry.registerServer(Y,Q),Z++}catch(X){u$.warn(`Failed to register MCP server "${Y}" from plugin "${$.manifest.name}": ${X instanceof Error?X.message:String(X)}`)}return Z}}async function E4(){return new WZ().integrateAll()}function h9(){new WZ().clearAllPluginResources()}var AK=A(()=>{U2();t0();O$();e4();Y4();y5();qZ()});var q8=A(()=>{LK();AK();qZ()});function d$($){if($.acp)return{sendMessage:(Z)=>$.acp.sendMessage(`• ${Z}
2188
2188
 
2189
- `),sendToolStart:$.acp.sendToolStart,sendToolResult:$.acp.sendToolResult};return{sendMessage:(Z)=>_$().addAssistantMessage(Z),sendToolStart:void 0,sendToolResult:void 0}}var T1=A(()=>{k$()});import bB from"node:os";import RK from"node:path";var VK;var DK=A(()=>{U4();T1();VK={name:"agents",description:"Manage agent configurations",fullDescription:"Create, edit, or delete custom subagents. Subagents are specialized agents that Claude can delegate tasks to.",usage:"/agents [list|create|help]",category:"System",examples:["/agents","/agents list","/agents help"],async handler($,Z){let Y=$[0],Q=d$(Z);if(!Y)return{success:!0,message:"show_agents_manager",data:{action:"show_agents_manager"}};if(Y==="list"){let J=J0.getAllNames().map((H)=>J0.getSubagent(H)).filter((H)=>H!==void 0);if(J.length===0){let H=`\uD83D\uDCCB **Agents 管理**
2189
+ `),sendToolStart:$.acp.sendToolStart,sendToolResult:$.acp.sendToolResult};return{sendMessage:(Z)=>_$().addAssistantMessage(Z),sendToolStart:void 0,sendToolResult:void 0}}var T1=A(()=>{k$()});import bB from"node:os";import RK from"node:path";var VK;var DK=A(()=>{U2();T1();VK={name:"agents",description:"Manage agent configurations",fullDescription:"Create, edit, or delete custom subagents. Subagents are specialized agents that Claude can delegate tasks to.",usage:"/agents [list|create|help]",category:"System",examples:["/agents","/agents list","/agents help"],async handler($,Z){let Y=$[0],Q=d$(Z);if(!Y)return{success:!0,message:"show_agents_manager",data:{action:"show_agents_manager"}};if(Y==="list"){let J=J0.getAllNames().map((H)=>J0.getSubagent(H)).filter((H)=>H!==void 0);if(J.length===0){let H=`\uD83D\uDCCB **Agents 管理**
2190
2190
 
2191
2191
  `+`❌ 没有找到任何 agent 配置
2192
2192
 
@@ -2231,12 +2231,12 @@ Please continue the conversation from where we left it off without asking the us
2231
2231
  `+"- 项目级 (`.blade/agents/`) - 最高优先级\n"+"- 用户级 (`~/.blade/agents/`) - 较低优先级\n\n"+`**可用工具:**
2232
2232
  `+"- `Glob` - 文件搜索\n"+"- `Grep` - 内容搜索\n"+"- `Read` - 读取文件\n"+"- `Write` - 写入文件\n"+"- `Edit` - 编辑文件\n"+"- `Bash` - 执行命令\n"+"- 省略 `tools` 字段 = 继承所有工具\n\n"+"\uD83D\uDCA1 **提示:** 创建文件后,重启 Blade 使配置生效";return Q.sendMessage(J),{success:!0,message:"Help displayed"}}if(Y==="create")return{success:!0,message:"show_agent_creation_wizard",data:{action:"show_agent_creation_wizard"}};let X=`❌ 未知子命令: \`${Y}\`
2233
2233
 
2234
- `+"使用 `/agents help` 查看可用命令";return Q.sendMessage(X),{success:!1,error:`Unknown subcommand: ${Y}`}}}});async function AB($,Z){let Y=d$(Z);try{let Q=H0(),X=h4();if(!Q||!X)return{success:!1,error:"配置未初始化"};let J=q$().session,G=J.messages,K=J.sessionId;if(!G||G.length===0)return Y.sendMessage("⚠️ 当前会话没有消息,无需压缩"),{success:!1,error:"没有消息需要压缩"};let q=G.map((O)=>({role:O.role,content:O.content})),W=Z2.countTokens(q,X.model),U=X.maxContextTokens??Q.maxContextTokens,H=(W/U*100).toFixed(1);if(Y.sendMessage(`\uD83D\uDCCA **当前上下文统计**
2234
+ `+"使用 `/agents help` 查看可用命令";return Q.sendMessage(X),{success:!1,error:`Unknown subcommand: ${Y}`}}}});async function AB($,Z){let Y=d$(Z);try{let Q=H0(),X=h2();if(!Q||!X)return{success:!1,error:"配置未初始化"};let J=q$().session,G=J.messages,K=J.sessionId;if(!G||G.length===0)return Y.sendMessage("⚠️ 当前会话没有消息,无需压缩"),{success:!1,error:"没有消息需要压缩"};let q=G.map((O)=>({role:O.role,content:O.content})),W=Z4.countTokens(q,X.model),U=X.maxContextTokens??Q.maxContextTokens,H=(W/U*100).toFixed(1);if(Y.sendMessage(`\uD83D\uDCCA **当前上下文统计**
2235
2235
  • 消息数量: ${q.length}
2236
2236
  • Token 数量: ${W.toLocaleString()}
2237
2237
  • Token 限制: ${U.toLocaleString()}
2238
2238
  • 使用率: ${H}%`),W<U*0.5)return Y.sendMessage(`\uD83D\uDCA1 提示: 当前 token 使用率较低(${H}%),可以暂时不压缩。
2239
- 系统会在达到 80% 时自动触发压缩。`),{success:!0,message:"无需压缩"};Y.sendMessage("⏳ **正在压缩上下文...**");let F=await u4.compact(q,{trigger:"manual",modelName:X.model,maxContextTokens:U,apiKey:X.apiKey,baseURL:X.baseUrl});if(F.success){try{if(K)await new F8().saveCompaction(K,F.summary,{trigger:"manual",preTokens:F.preTokens,postTokens:F.postTokens,filesIncluded:F.filesIncluded},null),console.log("[/compact] 压缩数据已保存到 JSONL")}catch(z){console.warn("[/compact] 保存压缩数据失败:",z)}let O=`✅ **压缩完成!**
2239
+ 系统会在达到 80% 时自动触发压缩。`),{success:!0,message:"无需压缩"};Y.sendMessage("⏳ **正在压缩上下文...**");let F=await u2.compact(q,{trigger:"manual",modelName:X.model,maxContextTokens:U,apiKey:X.apiKey,baseURL:X.baseUrl});if(F.success){try{if(K)await new F3().saveCompaction(K,F.summary,{trigger:"manual",preTokens:F.preTokens,postTokens:F.postTokens,filesIncluded:F.filesIncluded},null),console.log("[/compact] 压缩数据已保存到 JSONL")}catch(z){console.warn("[/compact] 保存压缩数据失败:",z)}let O=`✅ **压缩完成!**
2240
2240
 
2241
2241
  \uD83D\uDCC9 **Token 变化**
2242
2242
  • 压缩前: ${F.preTokens.toLocaleString()} tokens
@@ -2253,7 +2253,7 @@ Please continue the conversation from where we left it off without asking the us
2253
2253
  • 压缩后: ${F.postTokens.toLocaleString()} tokens
2254
2254
 
2255
2255
  \uD83D\uDCA1 由于压缩过程出现错误,已使用简单截断策略。
2256
- 错误信息: ${F.error}`),{success:!1,message:"compact_fallback",error:F.error,data:{compactedMessages:F.compactedMessages,boundaryMessage:F.boundaryMessage,summaryMessage:F.summaryMessage,preTokens:F.preTokens,postTokens:F.postTokens}}}catch(Q){let X=Q instanceof Error?Q.message:String(Q);return Y.sendMessage(`❌ **压缩失败**: ${X}`),{success:!1,error:X}}}var RB,MK;var jK=A(()=>{S7();QZ();e8();k$();T1();RB={name:"compact",description:"手动压缩当前会话的上下文",fullDescription:"压缩当前对话历史,生成详细的技术总结,保留最近的消息。压缩后的上下文可以节省 token 使用量,同时保留关键信息。",usage:"/compact",examples:["/compact"],category:"context",handler:AB},MK=RB});function yK($){let Z=Math.floor((Date.now()-$.getTime())/1000);if(Z<60)return`${Z}s ago`;let Y=Math.floor(Z/60);if(Y<60)return`${Y}m ago`;let Q=Math.floor(Y/60);if(Q<24)return`${Q}h ago`;return`${Math.floor(Q/24)}d ago`}async function VB($){let Z=b0.getInstance(),Y=W1();if(Object.keys(Y).length===0){$.sendMessage(`\uD83D\uDD0C **MCP 服务器状态**
2256
+ 错误信息: ${F.error}`),{success:!1,message:"compact_fallback",error:F.error,data:{compactedMessages:F.compactedMessages,boundaryMessage:F.boundaryMessage,summaryMessage:F.summaryMessage,preTokens:F.preTokens,postTokens:F.postTokens}}}catch(Q){let X=Q instanceof Error?Q.message:String(Q);return Y.sendMessage(`❌ **压缩失败**: ${X}`),{success:!1,error:X}}}var RB,MK;var jK=A(()=>{S7();QZ();e3();k$();T1();RB={name:"compact",description:"手动压缩当前会话的上下文",fullDescription:"压缩当前对话历史,生成详细的技术总结,保留最近的消息。压缩后的上下文可以节省 token 使用量,同时保留关键信息。",usage:"/compact",examples:["/compact"],category:"context",handler:AB},MK=RB});function yK($){let Z=Math.floor((Date.now()-$.getTime())/1000);if(Z<60)return`${Z}s ago`;let Y=Math.floor(Z/60);if(Y<60)return`${Y}m ago`;let Q=Math.floor(Y/60);if(Q<24)return`${Q}h ago`;return`${Math.floor(Q/24)}d ago`}async function VB($){let Z=b0.getInstance(),Y=W1();if(Object.keys(Y).length===0){$.sendMessage(`\uD83D\uDD0C **MCP 服务器状态**
2257
2257
 
2258
2258
  ⚠️ 暂无配置的 MCP 服务器
2259
2259
 
@@ -2323,11 +2323,11 @@ Please continue the conversation from where we left it off without asking the us
2323
2323
 
2324
2324
  `;continue}G+=U.length;for(let H of U){if(J+=` • ${H.name}`,H.description){let F=H.description.length>60?H.description.substring(0,57)+"...":H.description;J+=` - ${F}`}J+=`
2325
2325
  `}J+=`
2326
- `}J+=`**总计:** ${G} 个工具可用`,$.sendMessage(J)}var yB,vK;var EK=A(()=>{e2();x4();k$();T1();yB={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($,Z){let Y=d$(Z);try{if(console.log("[MCP Command] Received args:",$),$.length===0)return await VB(Y),{success:!0,message:"MCP 服务器概览已显示"};let Q=$[0];if(console.log("[MCP Command] Subcommand:",Q),Q==="tools")return await IB(Y),{success:!0,message:"MCP 工具列表已显示"};return await MB(Y,Q),{success:!0,message:`服务器 "${Q}" 详情已显示`}}catch(Q){return{success:!1,error:`显示 MCP 信息失败: ${Q instanceof Error?Q.message:"未知错误"}`}}}},vK=yB});async function vB($,Z){return{success:!0,message:"show_permissions_editor",data:{action:"show_permissions_editor"}}}var EB,x9;var UZ=A(()=>{EB={name:"permissions",description:"管理项目的本地权限规则",fullDescription:"打开权限管理器,管理 .blade/settings.local.json 中的权限规则",usage:"/permissions",aliases:["perm"],category:"ui",handler:vB},x9=EB});import{readdir as PK,readFile as TK}from"node:fs/promises";import*as p9 from"node:path";class _1{static async listSessions(){let $=[],Z=p9.join(J4(),"projects");try{let Y=await PK(Z,{withFileTypes:!0});for(let Q of Y){if(!Q.isDirectory())continue;let X=p9.join(Z,Q.name),J=oX(Q.name),K=(await PK(X)).filter((q)=>q.endsWith(".jsonl"));for(let q of K){let W=p9.join(X,q),U=q.replace(".jsonl","");try{let H=await this.extractMetadata(W,U,J);$.push(H)}catch(H){z4.warn(`[SessionService] 跳过损坏的会话文件: ${W}`,H)}}}return $.sort((Q,X)=>new Date(X.lastMessageTime).getTime()-new Date(Q.lastMessageTime).getTime()),$}catch(Y){return z4.error("[SessionService] 列出会话失败:",Y),[]}}static async extractMetadata($,Z,Y){let X=(await TK($,"utf-8")).trim().split(`
2327
- `).filter((q)=>q.trim());if(X.length===0)throw Error("空的 JSONL 文件");let J=JSON.parse(X[0]),G=JSON.parse(X[X.length-1]),K=X.some((q)=>{try{let W=JSON.parse(q);return W.type==="tool_result"&&W.toolResult?.error}catch{return!1}});return{sessionId:Z,projectPath:Y,gitBranch:J.gitBranch,messageCount:X.length,firstMessageTime:J.timestamp,lastMessageTime:G.timestamp,hasErrors:K,filePath:$}}static async loadSession($,Z){try{if(Z){let X=this.getSessionFilePath(Z,$);return await this.loadSessionFromFile(X)}let Q=(await this.listSessions()).find((X)=>X.sessionId===$);if(!Q)throw Error(`未找到会话: ${$}`);return await this.loadSessionFromFile(Q.filePath)}catch(Y){throw z4.error(`[SessionService] 加载会话失败 (${$}):`,Y),Y}}static async loadSessionFromFile($){let Q=(await TK($,"utf-8")).trim().split(`
2328
- `).filter((X)=>X.trim()).map((X)=>JSON.parse(X));return this.convertJSONLToMessages(Q)}static convertJSONLToMessages($){let Z=[],Y=-1;for(let X=$.length-1;X>=0;X--)if($[X].subtype==="compact_boundary"){Y=X,z4.debug(`[SessionService] 检测到压缩边界 at index ${X}`);break}let Q=Y>=0?Y:0;for(let X=Q;X<$.length;X++){let J=$[X];if(J.subtype==="compact_boundary"){z4.debug("[SessionService] 跳过 compact_boundary 消息");continue}switch(J.type){case"user":case"assistant":case"system":{let G={role:J.message.role,content:typeof J.message.content==="string"?J.message.content:JSON.stringify(J.message.content)};if(J.isCompactSummary)z4.debug("[SessionService] 加载压缩总结消息");Z.push(G);break}case"tool_result":if(J.toolResult){let G=J.toolResult.error?`Error: ${J.toolResult.error}`:typeof J.toolResult.output==="string"?J.toolResult.output:JSON.stringify(J.toolResult.output);Z.push({role:"tool",content:G,tool_call_id:J.toolResult.id,name:J.tool?.name})}break;case"tool_use":break;default:break}}if(Y>=0)z4.debug(`[SessionService] 会话已压缩,跳过前 ${Y} 条历史,加载 ${Z.length} 条消息`);return Z}static getSessionFilePath($,Z){return z1($,Z)}}var z4;var m9=A(()=>{X8();O$();z4=l("Service")});var PB,CK;var SK=A(()=>{m9();k$();T1();PB={name:"resume",description:"Resume a conversation",fullDescription:"恢复历史会话。可以指定 sessionId 直接恢复,或不带参数打开会话选择器",usage:"/resume [sessionId]",aliases:["r"],category:"Session",examples:["/resume - 打开会话选择器","/resume abc123xyz - 直接恢复指定的会话"],async handler($,Z){let Y=d$(Z),Q=_$().restoreSession;if($.length>0){let X=$[0];try{let J=await _1.loadSession(X);if(J.length===0)return Y.sendMessage(`❌ 会话 \`${X}\` 为空或无法加载`),{success:!1,error:"会话为空"};let G=J.filter((K)=>K.role!=="tool").map((K,q)=>({id:`restored-${Date.now()}-${q}`,role:K.role,content:typeof K.content==="string"?K.content:JSON.stringify(K.content),timestamp:Date.now()-(J.length-q)*1000}));return Q(X,G),Y.sendMessage(`✅ 已恢复会话 \`${X}\`
2326
+ `}J+=`**总计:** ${G} 个工具可用`,$.sendMessage(J)}var yB,vK;var EK=A(()=>{e4();x2();k$();T1();yB={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($,Z){let Y=d$(Z);try{if(console.log("[MCP Command] Received args:",$),$.length===0)return await VB(Y),{success:!0,message:"MCP 服务器概览已显示"};let Q=$[0];if(console.log("[MCP Command] Subcommand:",Q),Q==="tools")return await IB(Y),{success:!0,message:"MCP 工具列表已显示"};return await MB(Y,Q),{success:!0,message:`服务器 "${Q}" 详情已显示`}}catch(Q){return{success:!1,error:`显示 MCP 信息失败: ${Q instanceof Error?Q.message:"未知错误"}`}}}},vK=yB});async function vB($,Z){return{success:!0,message:"show_permissions_editor",data:{action:"show_permissions_editor"}}}var EB,x9;var UZ=A(()=>{EB={name:"permissions",description:"管理项目的本地权限规则",fullDescription:"打开权限管理器,管理 .blade/settings.local.json 中的权限规则",usage:"/permissions",aliases:["perm"],category:"ui",handler:vB},x9=EB});import{readdir as PK,readFile as TK}from"node:fs/promises";import*as p9 from"node:path";class _1{static async listSessions(){let $=[],Z=p9.join(J2(),"projects");try{let Y=await PK(Z,{withFileTypes:!0});for(let Q of Y){if(!Q.isDirectory())continue;let X=p9.join(Z,Q.name),J=oX(Q.name),K=(await PK(X)).filter((q)=>q.endsWith(".jsonl"));for(let q of K){let W=p9.join(X,q),U=q.replace(".jsonl","");try{let H=await this.extractMetadata(W,U,J);$.push(H)}catch(H){z2.warn(`[SessionService] 跳过损坏的会话文件: ${W}`,H)}}}return $.sort((Q,X)=>new Date(X.lastMessageTime).getTime()-new Date(Q.lastMessageTime).getTime()),$}catch(Y){return z2.error("[SessionService] 列出会话失败:",Y),[]}}static async extractMetadata($,Z,Y){let X=(await TK($,"utf-8")).trim().split(`
2327
+ `).filter((q)=>q.trim());if(X.length===0)throw Error("空的 JSONL 文件");let J=JSON.parse(X[0]),G=JSON.parse(X[X.length-1]),K=X.some((q)=>{try{let W=JSON.parse(q);return W.type==="tool_result"&&W.toolResult?.error}catch{return!1}});return{sessionId:Z,projectPath:Y,gitBranch:J.gitBranch,messageCount:X.length,firstMessageTime:J.timestamp,lastMessageTime:G.timestamp,hasErrors:K,filePath:$}}static async loadSession($,Z){try{if(Z){let X=this.getSessionFilePath(Z,$);return await this.loadSessionFromFile(X)}let Q=(await this.listSessions()).find((X)=>X.sessionId===$);if(!Q)throw Error(`未找到会话: ${$}`);return await this.loadSessionFromFile(Q.filePath)}catch(Y){throw z2.error(`[SessionService] 加载会话失败 (${$}):`,Y),Y}}static async loadSessionFromFile($){let Q=(await TK($,"utf-8")).trim().split(`
2328
+ `).filter((X)=>X.trim()).map((X)=>JSON.parse(X));return this.convertJSONLToMessages(Q)}static convertJSONLToMessages($){let Z=[],Y=-1;for(let X=$.length-1;X>=0;X--)if($[X].subtype==="compact_boundary"){Y=X,z2.debug(`[SessionService] 检测到压缩边界 at index ${X}`);break}let Q=Y>=0?Y:0;for(let X=Q;X<$.length;X++){let J=$[X];if(J.subtype==="compact_boundary"){z2.debug("[SessionService] 跳过 compact_boundary 消息");continue}switch(J.type){case"user":case"assistant":case"system":{let G={role:J.message.role,content:typeof J.message.content==="string"?J.message.content:JSON.stringify(J.message.content)};if(J.isCompactSummary)z2.debug("[SessionService] 加载压缩总结消息");Z.push(G);break}case"tool_result":if(J.toolResult){let G=J.toolResult.error?`Error: ${J.toolResult.error}`:typeof J.toolResult.output==="string"?J.toolResult.output:JSON.stringify(J.toolResult.output);Z.push({role:"tool",content:G,tool_call_id:J.toolResult.id,name:J.tool?.name})}break;case"tool_use":break;default:break}}if(Y>=0)z2.debug(`[SessionService] 会话已压缩,跳过前 ${Y} 条历史,加载 ${Z.length} 条消息`);return Z}static getSessionFilePath($,Z){return z1($,Z)}}var z2;var m9=A(()=>{X3();O$();z2=l("Service")});var PB,CK;var SK=A(()=>{m9();k$();T1();PB={name:"resume",description:"Resume a conversation",fullDescription:"恢复历史会话。可以指定 sessionId 直接恢复,或不带参数打开会话选择器",usage:"/resume [sessionId]",aliases:["r"],category:"Session",examples:["/resume - 打开会话选择器","/resume abc123xyz - 直接恢复指定的会话"],async handler($,Z){let Y=d$(Z),Q=_$().restoreSession;if($.length>0){let X=$[0];try{let J=await _1.loadSession(X);if(J.length===0)return Y.sendMessage(`❌ 会话 \`${X}\` 为空或无法加载`),{success:!1,error:"会话为空"};let G=J.filter((K)=>K.role!=="tool").map((K,q)=>({id:`restored-${Date.now()}-${q}`,role:K.role,content:typeof K.content==="string"?K.content:JSON.stringify(K.content),timestamp:Date.now()-(J.length-q)*1000}));return Q(X,G),Y.sendMessage(`✅ 已恢复会话 \`${X}\`
2329
2329
 
2330
- 共 ${G.length} 条消息已加载,可以继续对话`),{success:!0,message:"session_restored",data:{sessionId:X,messageCount:G.length}}}catch(J){let G=J instanceof Error?J.message:"未知错误";return Y.sendMessage(`❌ 加载会话失败: ${G}`),{success:!1,error:`加载会话失败: ${G}`}}}try{let X=await _1.listSessions();if(X.length===0)return Y.sendMessage("\uD83D\uDCED **没有找到历史会话**\n\n开始一次对话后,会话历史将自动保存到 `~/.blade/projects/`"),{success:!0,message:"没有可用会话"};return{success:!0,message:"show_session_selector",data:{sessions:X}}}catch(X){let J=X instanceof Error?X.message:"未知错误";return Y.sendMessage(`❌ 获取会话列表失败: ${J}`),{success:!1,error:`获取会话列表失败: ${J}`}}}},CK=PB});import kK from"node:fs/promises";import fK from"node:path";var TB,CB,SB,kB,fB,hB,hK;var xK=A(()=>{e8();k$();P3();DK();jK();j9();EK();UZ();SK();T1();TB={name:"help",description:"Show all available slash commands",fullDescription:"显示所有可用的 slash commands 及其使用方法",usage:"/help",aliases:["h"],async handler($,Z){let Y=d$(Z),Q=`\uD83D\uDD27 **可用的 Slash Commands:**
2330
+ 共 ${G.length} 条消息已加载,可以继续对话`),{success:!0,message:"session_restored",data:{sessionId:X,messageCount:G.length}}}catch(J){let G=J instanceof Error?J.message:"未知错误";return Y.sendMessage(`❌ 加载会话失败: ${G}`),{success:!1,error:`加载会话失败: ${G}`}}}try{let X=await _1.listSessions();if(X.length===0)return Y.sendMessage("\uD83D\uDCED **没有找到历史会话**\n\n开始一次对话后,会话历史将自动保存到 `~/.blade/projects/`"),{success:!0,message:"没有可用会话"};return{success:!0,message:"show_session_selector",data:{sessions:X}}}catch(X){let J=X instanceof Error?X.message:"未知错误";return Y.sendMessage(`❌ 获取会话列表失败: ${J}`),{success:!1,error:`获取会话列表失败: ${J}`}}}},CK=PB});import kK from"node:fs/promises";import fK from"node:path";var TB,CB,SB,kB,fB,hB,hK;var xK=A(()=>{e3();k$();P8();DK();jK();j9();EK();UZ();SK();T1();TB={name:"help",description:"Show all available slash commands",fullDescription:"显示所有可用的 slash commands 及其使用方法",usage:"/help",aliases:["h"],async handler($,Z){let Y=d$(Z),Q=`\uD83D\uDD27 **可用的 Slash Commands:**
2331
2331
 
2332
2332
  **/init** - 分析当前项目并生成 BLADE.md 配置文件
2333
2333
  **/git** - Git 仓库查询和 AI 辅助 (status/log/diff/review/commit)
@@ -2354,7 +2354,7 @@ Please continue the conversation from where we left it off without asking the us
2354
2354
  - 在命令前加上 \`/\` 即可执行 slash command
2355
2355
  - 普通消息会发送给 AI 助手处理
2356
2356
  - 按 Ctrl+C 退出程序
2357
- - 按 Ctrl+L 快速清屏`,Y.sendMessage(Q),{success:!0,message:"帮助信息已显示"}}},CB={name:"clear",description:"Clear conversation history and free up context",fullDescription:"清除屏幕内容和对话历史",usage:"/clear",aliases:["cls"],async handler($,Z){return{success:!0,message:"clear_screen"}}},SB={name:"version",description:"Show Blade Code version information",fullDescription:"显示 Blade Code 版本信息和构建详情",usage:"/version",aliases:["v"],async handler($,Z){let Y=d$(Z),X=`\uD83D\uDDE1️ **Blade Code v${v4()}**
2357
+ - 按 Ctrl+L 快速清屏`,Y.sendMessage(Q),{success:!0,message:"帮助信息已显示"}}},CB={name:"clear",description:"Clear conversation history and free up context",fullDescription:"清除屏幕内容和对话历史",usage:"/clear",aliases:["cls"],async handler($,Z){return{success:!0,message:"clear_screen"}}},SB={name:"version",description:"Show Blade Code version information",fullDescription:"显示 Blade Code 版本信息和构建详情",usage:"/version",aliases:["v"],async handler($,Z){let Y=d$(Z),X=`\uD83D\uDDE1️ **Blade Code v${v2()}**
2358
2358
 
2359
2359
  **构建信息:**
2360
2360
  - Node.js: ${process.version}
@@ -2379,7 +2379,7 @@ Please continue the conversation from where we left it off without asking the us
2379
2379
  - 工作目录: ${process.cwd()}
2380
2380
  - Node.js: ${process.version}
2381
2381
 
2382
- ${!J?"\n\uD83D\uDCA1 **建议:** 运行 `/init` 命令来创建项目配置文件":""}`;return Y.sendMessage(W),{success:!0,message:"状态信息已显示"}}catch(X){return{success:!1,error:`获取状态信息失败: ${X instanceof Error?X.message:"未知错误"}`}}}},fB={name:"exit",description:"Exit the REPL",fullDescription:"退出 Blade Code 命令行界面",usage:"/exit",aliases:["quit","q"],async handler($,Z){return{success:!0,message:"exit_application"}}},hB={name:"context",description:"Visualize current context usage as a colored grid",fullDescription:"可视化显示当前上下文使用情况",usage:"/context",async handler($,Z){let Y=d$(Z),Q=H0(),X=h4(),G=q$().session.messages||[],K=G.map((B)=>({role:B.role,content:B.content})),q=X?.model||"gpt-4",W=K.length>0?Z2.countTokens(K,q):0,U=X?.maxContextTokens??Q?.maxContextTokens??128000,H=U>0?(W/U*100).toFixed(1):"0",F=(100-parseFloat(H)).toFixed(1),O=parseFloat(H),z;if(O<50)z="\uD83D\uDFE2 正常";else if(O<80)z="\uD83D\uDFE1 中等";else z="\uD83D\uDD34 高负载";let _=`\uD83D\uDCCA **上下文使用情况**
2382
+ ${!J?"\n\uD83D\uDCA1 **建议:** 运行 `/init` 命令来创建项目配置文件":""}`;return Y.sendMessage(W),{success:!0,message:"状态信息已显示"}}catch(X){return{success:!1,error:`获取状态信息失败: ${X instanceof Error?X.message:"未知错误"}`}}}},fB={name:"exit",description:"Exit the REPL",fullDescription:"退出 Blade Code 命令行界面",usage:"/exit",aliases:["quit","q"],async handler($,Z){return{success:!0,message:"exit_application"}}},hB={name:"context",description:"Visualize current context usage as a colored grid",fullDescription:"可视化显示当前上下文使用情况",usage:"/context",async handler($,Z){let Y=d$(Z),Q=H0(),X=h2(),G=q$().session.messages||[],K=G.map((B)=>({role:B.role,content:B.content})),q=X?.model||"gpt-4",W=K.length>0?Z4.countTokens(K,q):0,U=X?.maxContextTokens??Q?.maxContextTokens??128000,H=U>0?(W/U*100).toFixed(1):"0",F=(100-parseFloat(H)).toFixed(1),O=parseFloat(H),z;if(O<50)z="\uD83D\uDFE2 正常";else if(O<80)z="\uD83D\uDFE1 中等";else z="\uD83D\uDD34 高负载";let _=`\uD83D\uDCCA **上下文使用情况**
2383
2383
 
2384
2384
  **当前会话:**
2385
2385
  - 消息数量: ${G.length}
@@ -2393,8 +2393,8 @@ ${!J?"\n\uD83D\uDCA1 **建议:** 运行 `/init` 命令来创建项目配置文
2393
2393
 
2394
2394
  **状态:** ${z}
2395
2395
 
2396
- \uD83D\uDCA1 使用 \`/compact\` 可手动压缩上下文`;return Y.sendMessage(_),{success:!0,message:"上下文信息已显示"}}},hK={help:TB,clear:CB,version:SB,status:kB,exit:fB,context:hB,permissions:x9,resume:CK,compact:MK,mcp:vK,agents:VK}});import{execFile as pK,spawn as xB}from"child_process";import{promisify as pB}from"util";async function z8($,Z){return new Promise((Y)=>{pK("git",Z,{cwd:$,maxBuffer:10485760,encoding:"utf8"},(Q,X,J)=>{let G=Q==null?0:typeof Q.code==="number"?Q.code:1;Y({code:G,stdout:X||"",stderr:J||""})})})}async function mB($,Z){let{code:Y}=await z8($,Z);return Y===0}async function l1($,Z){let{stdout:Y}=await z8($,Z);return Y.trim()}async function _8($){return mB($,["rev-parse","--is-inside-work-tree"])}async function d9($){return(await l1($,["status","--porcelain"])).length>0}async function mK($){return l1($,["branch","--show-current"])}async function u9($,Z=10){return l1($,["log","-n",String(Z),"--pretty=format:%s"])}async function HZ($){let{code:Z,stderr:Y}=await z8($,["add","."]);if(Z!==0){let Q=Y||"Unknown error";if(Q.includes("fatal: pathspec"))throw Error("Failed to stage files: Invalid file path or pattern");throw Error(`Failed to stage files: ${Q}`)}}async function dK($,Z,Y=!1,Q){let X=["commit","-m",Z];if(Y)X.push("--no-verify");if(!Q){let{code:J,stderr:G}=await z8($,X);if(J!==0)throw Error(G||"Commit failed");return}return new Promise((J,G)=>{let K=xB("git",X,{cwd:$}),q="",W=(F,O,z)=>{let B=(z+F.toString()).split(`
2397
- `),L=B.pop()||"";for(let w of B)if(w.trim())Q(w,O);return L},U="",H="";K.stdout?.on("data",(F)=>{U=W(F,"stdout",U)}),K.stderr?.on("data",(F)=>{q+=F.toString(),H=W(F,"stderr",H)}),K.on("error",(F)=>{G(F)}),K.on("close",(F)=>{if(U.trim())Q(U,"stdout");if(H.trim())Q(H,"stderr");if(F===0)J();else G(Error(q||"Commit failed"))})})}async function uK($){let{cwd:Z}=$;if(!await _8(Z))return null;let[Y,Q,X,J,G]=await Promise.all([l1(Z,["branch","--show-current"]),l1(Z,["rev-parse","--abbrev-ref","origin/HEAD"]).then((q)=>q.replace("origin/","")).catch(()=>"main"),l1(Z,["status","--short"]),l1(Z,["log","--oneline","-n","5"]),l1(Z,["config","user.email"])]),K=G?await l1(Z,["log","--author",G,"--oneline","-n","5"]):"";return{branch:Y,mainBranch:Q,status:X,log:J,author:G,authorLog:K}}function gK($){if(!$)return null;return`
2396
+ \uD83D\uDCA1 使用 \`/compact\` 可手动压缩上下文`;return Y.sendMessage(_),{success:!0,message:"上下文信息已显示"}}},hK={help:TB,clear:CB,version:SB,status:kB,exit:fB,context:hB,permissions:x9,resume:CK,compact:MK,mcp:vK,agents:VK}});import{execFile as pK,spawn as xB}from"child_process";import{promisify as pB}from"util";async function z3($,Z){return new Promise((Y)=>{pK("git",Z,{cwd:$,maxBuffer:10485760,encoding:"utf8"},(Q,X,J)=>{let G=Q==null?0:typeof Q.code==="number"?Q.code:1;Y({code:G,stdout:X||"",stderr:J||""})})})}async function mB($,Z){let{code:Y}=await z3($,Z);return Y===0}async function l1($,Z){let{stdout:Y}=await z3($,Z);return Y.trim()}async function _3($){return mB($,["rev-parse","--is-inside-work-tree"])}async function d9($){return(await l1($,["status","--porcelain"])).length>0}async function mK($){return l1($,["branch","--show-current"])}async function u9($,Z=10){return l1($,["log","-n",String(Z),"--pretty=format:%s"])}async function HZ($){let{code:Z,stderr:Y}=await z3($,["add","."]);if(Z!==0){let Q=Y||"Unknown error";if(Q.includes("fatal: pathspec"))throw Error("Failed to stage files: Invalid file path or pattern");throw Error(`Failed to stage files: ${Q}`)}}async function dK($,Z,Y=!1,Q){let X=["commit","-m",Z];if(Y)X.push("--no-verify");if(!Q){let{code:J,stderr:G}=await z3($,X);if(J!==0)throw Error(G||"Commit failed");return}return new Promise((J,G)=>{let K=xB("git",X,{cwd:$}),q="",W=(F,O,z)=>{let B=(z+F.toString()).split(`
2397
+ `),L=B.pop()||"";for(let w of B)if(w.trim())Q(w,O);return L},U="",H="";K.stdout?.on("data",(F)=>{U=W(F,"stdout",U)}),K.stderr?.on("data",(F)=>{q+=F.toString(),H=W(F,"stderr",H)}),K.on("error",(F)=>{G(F)}),K.on("close",(F)=>{if(U.trim())Q(U,"stdout");if(H.trim())Q(H,"stderr");if(F===0)J();else G(Error(q||"Commit failed"))})})}async function uK($){let{cwd:Z}=$;if(!await _3(Z))return null;let[Y,Q,X,J,G]=await Promise.all([l1(Z,["branch","--show-current"]),l1(Z,["rev-parse","--abbrev-ref","origin/HEAD"]).then((q)=>q.replace("origin/","")).catch(()=>"main"),l1(Z,["status","--short"]),l1(Z,["log","--oneline","-n","5"]),l1(Z,["config","user.email"])]),K=G?await l1(Z,["log","--author",G,"--oneline","-n","5"]):"";return{branch:Y,mainBranch:Q,status:X,log:J,author:G,authorLog:K}}function gK($){if(!$)return null;return`
2398
2398
  Git repository status (snapshot at conversation start):
2399
2399
  Current branch: ${$.branch}
2400
2400
  Main branch (target for PRs): ${$.mainBranch}
@@ -2407,14 +2407,14 @@ ${$.log||"(no commits)"}
2407
2407
 
2408
2408
  Your recent commits:
2409
2409
  ${$.authorLog||"(no recent commits)"}
2410
- `.trim()}async function B8($){return l1($,["diff","--cached","--name-status"])}async function L8($){let Y=["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:Q,stdout:X,stderr:J}=await z8($,Y);if(Q!==0){let K=J||"Unknown error";if(K.includes("bad revision"))throw Error("Failed to get staged diff: Invalid Git revision or corrupt repository");if(K.includes("fatal: not a git repository"))throw Error("Not a Git repository");throw Error(`Failed to get staged diff: ${K}`)}let G=102400;if(X.length>G)return X.substring(0,G)+`
2410
+ `.trim()}async function B3($){return l1($,["diff","--cached","--name-status"])}async function L3($){let Y=["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:Q,stdout:X,stderr:J}=await z3($,Y);if(Q!==0){let K=J||"Unknown error";if(K.includes("bad revision"))throw Error("Failed to get staged diff: Invalid Git revision or corrupt repository");if(K.includes("fatal: not a git repository"))throw Error("Not a Git repository");throw Error(`Failed to get staged diff: ${K}`)}let G=102400;if(X.length>G)return X.substring(0,G)+`
2411
2411
 
2412
2412
  [Diff truncated due to size. Total diff size: `+(X.length/1024).toFixed(2)+"KB]";return X}var Rk;var FZ=A(()=>{Rk=pB(pK)});async function cK($){let Z=d$($),Y=await uK({cwd:$.cwd});if(!Y)return{success:!1,error:"无法获取 Git 状态"};let Q=gK(Y);if(Q)Z.sendMessage(`\`\`\`
2413
2413
  ${Q}
2414
2414
  \`\`\``);else Z.sendMessage("\uD83D\uDCED 无法获取 Git 状态信息");return{success:!0}}async function uB($,Z){let Y=d$($),Q=Math.min(Math.max(parseInt(Z||"5",10)||5,1),50),X=await u9($.cwd,Q);if(!X)Y.sendMessage("\uD83D\uDCED 暂无提交记录");else Y.sendMessage(`**最近 ${Q} 条提交:**
2415
2415
  \`\`\`
2416
2416
  ${X}
2417
- \`\`\``);return{success:!0}}async function gB($){let Z=d$($),{cwd:Y}=$,Q=await B8(Y);if(!Q)return Z.sendMessage("\uD83D\uDCED 暂存区为空,没有待提交的改动"),{success:!0};let X=await L8(Y),J=`**暂存文件:**
2417
+ \`\`\``);return{success:!0}}async function gB($){let Z=d$($),{cwd:Y}=$,Q=await B3(Y);if(!Q)return Z.sendMessage("\uD83D\uDCED 暂存区为空,没有待提交的改动"),{success:!0};let X=await L3(Y),J=`**暂存文件:**
2418
2418
  \`\`\`
2419
2419
  ${Q}
2420
2420
  \`\`\`
@@ -2422,7 +2422,7 @@ ${Q}
2422
2422
  **Diff:**
2423
2423
  \`\`\`diff
2424
2424
  ${X||"(无差异)"}
2425
- \`\`\``;return Z.sendMessage(J),{success:!0}}async function cB($){let Z=d$($),{cwd:Y,signal:Q}=$;if(!await d9(Y))return Z.sendMessage("\uD83D\uDCED 没有未提交的改动,无需 Review"),{success:!0};Z.sendMessage("\uD83D\uDD0D 正在分析代码改动...");let X=await B8(Y),J=await L8(Y);if(!J&&!X)return Z.sendMessage("\uD83D\uDCA1 请先使用 `git add` 暂存要 Review 的文件"),{success:!0};let G=await O0.create();if(Q?.aborted)return{success:!1,message:"操作已取消"};let K=q$().session.sessionId,q=`请对以下 Git 改动进行 Code Review。
2425
+ \`\`\``;return Z.sendMessage(J),{success:!0}}async function cB($){let Z=d$($),{cwd:Y,signal:Q}=$;if(!await d9(Y))return Z.sendMessage("\uD83D\uDCED 没有未提交的改动,无需 Review"),{success:!0};Z.sendMessage("\uD83D\uDD0D 正在分析代码改动...");let X=await B3(Y),J=await L3(Y);if(!J&&!X)return Z.sendMessage("\uD83D\uDCA1 请先使用 `git add` 暂存要 Review 的文件"),{success:!0};let G=await O0.create();if(Q?.aborted)return{success:!1,message:"操作已取消"};let K=q$().session.sessionId,q=`请对以下 Git 改动进行 Code Review。
2426
2426
 
2427
2427
  **暂存文件:**
2428
2428
  ${X||"(无)"}
@@ -2438,7 +2438,7 @@ ${J||"(无差异)"}
2438
2438
  3. **潜在问题**:指出可能的 bug、安全问题或性能问题
2439
2439
  4. **改进建议**:具体的代码改进建议
2440
2440
 
2441
- 如果改动很好,也请说明优点。保持简洁专业。`,W=await G.chat(q,{messages:[],userId:"cli-user",sessionId:K||"git-review",workspaceRoot:Y,signal:Q});return Z.sendMessage(W),{success:!0}}async function lB($){let Z=d$($),{cwd:Y,signal:Q}=$;if(!await d9(Y))return Z.sendMessage("\uD83D\uDCED 没有未提交的改动"),{success:!0};Z.sendMessage("\uD83D\uDCE6 暂存所有改动..."),await HZ(Y);let X=await B8(Y),J=await L8(Y);if(!X)return Z.sendMessage("\uD83D\uDCED 没有需要提交的改动"),{success:!0};Z.sendMessage("\uD83E\uDD16 正在生成 commit message...");let G=await u9(Y,5),K=await O0.create();if(Q?.aborted)return{success:!1,message:"操作已取消"};let q=q$().session.sessionId,W=lK(X,J,G),H=(await K.chat(W,{messages:[],userId:"cli-user",sessionId:q||"git-pre-commit",workspaceRoot:Y,signal:Q})).replace(/^```\w*\n?/,"").replace(/\n?```$/,"").trim();return Z.sendMessage(`**生成的 Commit Message:**
2441
+ 如果改动很好,也请说明优点。保持简洁专业。`,W=await G.chat(q,{messages:[],userId:"cli-user",sessionId:K||"git-review",workspaceRoot:Y,signal:Q});return Z.sendMessage(W),{success:!0}}async function lB($){let Z=d$($),{cwd:Y,signal:Q}=$;if(!await d9(Y))return Z.sendMessage("\uD83D\uDCED 没有未提交的改动"),{success:!0};Z.sendMessage("\uD83D\uDCE6 暂存所有改动..."),await HZ(Y);let X=await B3(Y),J=await L3(Y);if(!X)return Z.sendMessage("\uD83D\uDCED 没有需要提交的改动"),{success:!0};Z.sendMessage("\uD83E\uDD16 正在生成 commit message...");let G=await u9(Y,5),K=await O0.create();if(Q?.aborted)return{success:!1,message:"操作已取消"};let q=q$().session.sessionId,W=lK(X,J,G),H=(await K.chat(W,{messages:[],userId:"cli-user",sessionId:q||"git-pre-commit",workspaceRoot:Y,signal:Q})).replace(/^```\w*\n?/,"").replace(/\n?```$/,"").trim();return Z.sendMessage(`**生成的 Commit Message:**
2442
2442
  \`\`\`
2443
2443
  ${H}
2444
2444
  \`\`\`
@@ -2447,7 +2447,7 @@ ${H}
2447
2447
  \`\`\`bash
2448
2448
  git commit -m "${H.split(`
2449
2449
  `)[0]}"
2450
- \`\`\``),{success:!0}}async function iB($){let Z=d$($),{cwd:Y,signal:Q}=$;if(!await d9(Y))return Z.sendMessage("\uD83D\uDCED 没有未提交的改动"),{success:!0};Z.sendMessage("\uD83D\uDCE6 暂存所有改动..."),await HZ(Y);let X=await B8(Y),J=await L8(Y);if(!X)return Z.sendMessage("\uD83D\uDCED 没有需要提交的改动"),{success:!0};Z.sendMessage("\uD83E\uDD16 正在生成 commit message...");let G=await u9(Y,5),K=await O0.create();if(Q?.aborted)return{success:!1,message:"操作已取消"};let q=q$().session.sessionId,W=lK(X,J,G),H=(await K.chat(W,{messages:[],userId:"cli-user",sessionId:q||"git-commit",workspaceRoot:Y,signal:Q})).replace(/^```\w*\n?/,"").replace(/\n?```$/,"").trim();Z.sendMessage(`**生成的 Commit Message:**
2450
+ \`\`\``),{success:!0}}async function iB($){let Z=d$($),{cwd:Y,signal:Q}=$;if(!await d9(Y))return Z.sendMessage("\uD83D\uDCED 没有未提交的改动"),{success:!0};Z.sendMessage("\uD83D\uDCE6 暂存所有改动..."),await HZ(Y);let X=await B3(Y),J=await L3(Y);if(!X)return Z.sendMessage("\uD83D\uDCED 没有需要提交的改动"),{success:!0};Z.sendMessage("\uD83E\uDD16 正在生成 commit message...");let G=await u9(Y,5),K=await O0.create();if(Q?.aborted)return{success:!1,message:"操作已取消"};let q=q$().session.sessionId,W=lK(X,J,G),H=(await K.chat(W,{messages:[],userId:"cli-user",sessionId:q||"git-commit",workspaceRoot:Y,signal:Q})).replace(/^```\w*\n?/,"").replace(/\n?```$/,"").trim();Z.sendMessage(`**生成的 Commit Message:**
2451
2451
  \`\`\`
2452
2452
  ${H}
2453
2453
  \`\`\``);try{await dK(Y,H),Z.sendMessage("✅ 提交成功!")}catch(F){let O=F instanceof Error?F.message:"未知错误";return Z.sendMessage(`❌ 提交失败: ${O}`),{success:!1,error:O}}return{success:!0}}function lK($,Z,Y){let Q=Y&&Y.trim().length>0;return`请根据以下 Git 改动生成一条 commit message。
@@ -2471,9 +2471,9 @@ ${Y}
2471
2471
  1. ${Q?"严格模仿历史提交的语言和格式风格":"使用英文,遵循 Conventional Commits 格式(feat:, fix:, docs:, refactor:, chore: 等)"}
2472
2472
  2. 第一行简明扼要,不超过 72 字符
2473
2473
  3. 如有必要,可添加空行后的详细说明
2474
- 4. 只输出 commit message 内容,不要其他解释或代码块标记`}var dB,iK;var aK=A(()=>{X2();k$();FZ();T1();dB={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($,Z){let{cwd:Y}=Z,Q=$[0]?.toLowerCase();if(!await _8(Y))return{success:!1,error:"❌ 当前目录不在 Git 仓库中"};try{switch(Q){case"status":case"s":return cK(Z);case"log":case"l":return uB(Z,$[1]);case"diff":case"d":return gB(Z);case"review":case"r":return cB(Z);case"commit":case"c":return iB(Z);case"pre-commit":case"pc":return lB(Z);default:return cK(Z)}}catch(X){return{success:!1,error:`Git 命令失败: ${X instanceof Error?X.message:"未知错误"}`}}}};iK=dB});function rB($){let Z=$.isEnabled(),Y=$.getConfig(),Q={};for(let J of Object.values(x1)){let G=Y[J];if(G&&Array.isArray(G)){let K=G.reduce((q,W)=>q+(W.hooks?.length||0),0);if(K>0)Q[J]=K}}let X=["## Hooks 状态","",`**状态**: ${Z?"✅ 启用":"⏸️ 禁用"}`,""];if(Object.keys(Q).length>0){X.push("**已配置的 Hooks**:"),X.push("");for(let[J,G]of Object.entries(Q))X.push(`- ${J}: ${G} 个 hook`)}else X.push("*没有配置任何 hooks*");return X.push(""),X.push("---"),X.push("使用 `/hooks list` 查看详细配置"),X.push("使用 `/hooks enable` 或 `/hooks disable` 切换状态"),_$().addAssistantMessage(X.join(`
2474
+ 4. 只输出 commit message 内容,不要其他解释或代码块标记`}var dB,iK;var aK=A(()=>{X4();k$();FZ();T1();dB={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($,Z){let{cwd:Y}=Z,Q=$[0]?.toLowerCase();if(!await _3(Y))return{success:!1,error:"❌ 当前目录不在 Git 仓库中"};try{switch(Q){case"status":case"s":return cK(Z);case"log":case"l":return uB(Z,$[1]);case"diff":case"d":return gB(Z);case"review":case"r":return cB(Z);case"commit":case"c":return iB(Z);case"pre-commit":case"pc":return lB(Z);default:return cK(Z)}}catch(X){return{success:!1,error:`Git 命令失败: ${X instanceof Error?X.message:"未知错误"}`}}}};iK=dB});function rB($){let Z=$.isEnabled(),Y=$.getConfig(),Q={};for(let J of Object.values(x1)){let G=Y[J];if(G&&Array.isArray(G)){let K=G.reduce((q,W)=>q+(W.hooks?.length||0),0);if(K>0)Q[J]=K}}let X=["## Hooks 状态","",`**状态**: ${Z?"✅ 启用":"⏸️ 禁用"}`,""];if(Object.keys(Q).length>0){X.push("**已配置的 Hooks**:"),X.push("");for(let[J,G]of Object.entries(Q))X.push(`- ${J}: ${G} 个 hook`)}else X.push("*没有配置任何 hooks*");return X.push(""),X.push("---"),X.push("使用 `/hooks list` 查看详细配置"),X.push("使用 `/hooks enable` 或 `/hooks disable` 切换状态"),_$().addAssistantMessage(X.join(`
2475
2475
  `)),{success:!0,message:"Hooks status displayed"}}function nB($){let Z=$.getConfig(),Y=["## Hooks 配置详情",""],Q=!1;for(let X of Object.values(x1)){let J=Z[X];if(!J||!Array.isArray(J)||J.length===0)continue;Q=!0,Y.push(`### ${X}`),Y.push("");for(let G=0;G<J.length;G++){let K=J[G],q=K.name||`Matcher ${G+1}`,W=K.matcher,U="所有";if(W){let H=[];if(W.tools){let F=Array.isArray(W.tools)?W.tools.join(", "):W.tools;H.push(`工具: ${F}`)}if(W.paths){let F=Array.isArray(W.paths)?W.paths.join(", "):W.paths;H.push(`路径: ${F}`)}if(W.commands){let F=Array.isArray(W.commands)?W.commands.join(", "):W.commands;H.push(`命令: ${F}`)}if(H.length>0)U=H.join("; ")}Y.push(`**${q}** (匹配: ${U})`);for(let H of K.hooks||[])if(H.type==="command")Y.push(` - \`${H.command}\``);else if(H.type==="prompt"){let F=H.prompt.slice(0,50)+(H.prompt.length>50?"...":"");Y.push(` - [prompt] ${F}`)}Y.push("")}}if(!Q)Y.push("*没有配置任何 hooks*"),Y.push(""),Y.push("在 `.blade/settings.local.json` 或 `~/.blade/settings.json` 中配置 hooks。");return _$().addAssistantMessage(Y.join(`
2476
- `)),{success:!0,message:"Hooks config listed"}}var aB,rK;var nK=A(()=>{t0();m4();k$();aB={name:"hooks",description:"Manage hook configurations for tool events",fullDescription:`管理 Hook 配置,查看当前启用的 hooks 和执行统计。
2476
+ `)),{success:!0,message:"Hooks config listed"}}var aB,rK;var nK=A(()=>{t0();m2();k$();aB={name:"hooks",description:"Manage hook configurations for tool events",fullDescription:`管理 Hook 配置,查看当前启用的 hooks 和执行统计。
2477
2477
 
2478
2478
  子命令:
2479
2479
  /hooks - 打开交互式 hooks 管理界面(添加新 hook)
@@ -2484,10 +2484,10 @@ ${Y}
2484
2484
  /hooks list - 列出所有配置的 hooks`,usage:"/hooks [add|status|enable|disable|list]",category:"system",examples:["/hooks","/hooks add","/hooks status","/hooks enable","/hooks disable","/hooks list"],handler:async($,Z)=>{let Y=$[0]?.toLowerCase()||"",Q=M$.getInstance();switch(Y){case"":case"add":return{success:!0,message:"show_hooks_manager",data:{action:"show_hooks_manager"}};case"status":return rB(Q);case"enable":return Q.enable(),_$().addAssistantMessage("✅ Hooks 已启用(当前会话)"),{success:!0,message:"Hooks enabled"};case"disable":return Q.disable(),_$().addAssistantMessage("⏸️ Hooks 已禁用(当前会话)"),{success:!0,message:"Hooks disabled"};case"list":return nB(Q);default:return _$().addAssistantMessage(`❌ 未知子命令: ${Y}
2485
2485
  使用 /hooks 查看帮助`),{success:!1,error:`Unknown subcommand: ${Y}`}}}};rK=aB});import{exec as oB}from"child_process";import{promisify as sB}from"util";class OZ{static async detectIde(){let $=process.env.TERM_PROGRAM,Z=process.env.VSCODE_INJECTION,Y=process.env.VSCODE_IPC_HOOK;if($==="vscode"||Z||Y)return await this.detectVsCode();let Q=await this.detectVsCode();if(Q)return Q;return null}static async detectVsCode(){try{let{stdout:$}=await oK("code --version"),Y=$.trim().split(`
2486
2486
  `)[0]||"unknown",Q=[];try{let{stdout:X}=await oK("code --list-extensions");Q=X.trim().split(`
2487
- `).filter(Boolean)}catch{}return{name:"VS Code",version:Y,extensions:Q}}catch{return null}}static isRunningInIdeTerminal(){let $=process.env.TERM_PROGRAM,Z=process.env.VSCODE_INJECTION,Y=process.env.VSCODE_IPC_HOOK;return $==="vscode"||!!Z||!!Y}}var oK;var sK=A(()=>{oK=sB(oB)});import{exec as tB}from"child_process";import{promisify as eB}from"util";class w8{static async getInstalledIdes(){let $=[],Z=await this.checkVsCode();if(Z)$.push(Z);let Y=await this.checkVsCodeInsiders();if(Y)$.push(Y);let Q=await this.checkCursor();if(Q)$.push(Q);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 Z;switch($){case"vscode":Z="code --install-extension blade-code.blade-code";break;case"vscode-insiders":Z="code-insiders --install-extension blade-code.blade-code";break;case"cursor":Z="cursor --install-extension blade-code.blade-code";break;default:return{success:!1,message:"不支持的 IDE: "+$}}try{return await g9(Z),{success:!0,message:"扩展安装成功"}}catch(Y){return{success:!1,message:"安装失败: "+(Y instanceof Error?Y.message:"未知错误")}}}static async checkVsCode(){try{let{stdout:$}=await g9("code --version");return{id:"vscode",name:"VS Code",version:$.trim().split(`
2487
+ `).filter(Boolean)}catch{}return{name:"VS Code",version:Y,extensions:Q}}catch{return null}}static isRunningInIdeTerminal(){let $=process.env.TERM_PROGRAM,Z=process.env.VSCODE_INJECTION,Y=process.env.VSCODE_IPC_HOOK;return $==="vscode"||!!Z||!!Y}}var oK;var sK=A(()=>{oK=sB(oB)});import{exec as tB}from"child_process";import{promisify as eB}from"util";class w3{static async getInstalledIdes(){let $=[],Z=await this.checkVsCode();if(Z)$.push(Z);let Y=await this.checkVsCodeInsiders();if(Y)$.push(Y);let Q=await this.checkCursor();if(Q)$.push(Q);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 Z;switch($){case"vscode":Z="code --install-extension blade-code.blade-code";break;case"vscode-insiders":Z="code-insiders --install-extension blade-code.blade-code";break;case"cursor":Z="cursor --install-extension blade-code.blade-code";break;default:return{success:!1,message:"不支持的 IDE: "+$}}try{return await g9(Z),{success:!0,message:"扩展安装成功"}}catch(Y){return{success:!1,message:"安装失败: "+(Y instanceof Error?Y.message:"未知错误")}}}static async checkVsCode(){try{let{stdout:$}=await g9("code --version");return{id:"vscode",name:"VS Code",version:$.trim().split(`
2488
2488
  `)[0]||"unknown"}}catch{return null}}static async checkVsCodeInsiders(){try{let{stdout:$}=await g9("code-insiders --version");return{id:"vscode-insiders",name:"VS Code Insiders",version:$.trim().split(`
2489
2489
  `)[0]||"unknown"}}catch{return null}}static async checkCursor(){try{let{stdout:$}=await g9("cursor --version");return{id:"cursor",name:"Cursor",version:$.trim().split(`
2490
- `)[0]||"unknown"}}catch{return null}}}var g9;var tK=A(()=>{g9=eB(tB)});import{existsSync as $L,readFileSync as ZL}from"fs";import{homedir as YL}from"os";import{join as QL}from"path";function XL(){switch(W3){case"connected":return{type:"info",content:`\uD83D\uDFE2 已连接到 ${zZ||"IDE"} (端口: ${_Z})`};case"connecting":return{type:"info",content:"\uD83D\uDFE1 正在连接..."};default:return{type:"error",content:"\uD83D\uDD34 未连接到 IDE"}}}function $q(){try{if($L(eK)){let $=ZL(eK,"utf-8");return JSON.parse($)}}catch{}return null}function Zq(){let $=process.env.BLADE_IDE_PORT;if($)return parseInt($,10);let Z=$q();if(Z)return Z.port;return null}async function JL(){let $=[],Z=XL();$.push(Z.content),$.push(""),$.push("\uD83D\uDCE6 已安装的 IDE:");let Y=await w8.getInstalledIdes();if(Y.length===0)$.push(" (未检测到支持的 IDE)");else for(let G of Y)$.push(` • ${G.name} ${G.version}`);$.push("");let Q=await OZ.detectIde();if(Q){if($.push(`\uD83D\uDDA5️ 当前环境: ${Q.name} ${Q.version}`),Q.extensions.length>0)$.push(` 已安装扩展: ${Q.extensions.length} 个`)}let X=Zq(),J=$q();if(X){if($.push(`\uD83D\uDD0C IDE 端口: ${X}`),J&&J.workspaceFolders.length>0)$.push(` 工作区: ${J.workspaceFolders[0]}`)}else $.push(""),$.push("\uD83D\uDCA1 提示: 在 VS Code 中安装 Blade Code 插件后,运行 /ide connect 连接");return $.join(`
2490
+ `)[0]||"unknown"}}catch{return null}}}var g9;var tK=A(()=>{g9=eB(tB)});import{existsSync as $L,readFileSync as ZL}from"fs";import{homedir as YL}from"os";import{join as QL}from"path";function XL(){switch(W8){case"connected":return{type:"info",content:`\uD83D\uDFE2 已连接到 ${zZ||"IDE"} (端口: ${_Z})`};case"connecting":return{type:"info",content:"\uD83D\uDFE1 正在连接..."};default:return{type:"error",content:"\uD83D\uDD34 未连接到 IDE"}}}function $q(){try{if($L(eK)){let $=ZL(eK,"utf-8");return JSON.parse($)}}catch{}return null}function Zq(){let $=process.env.BLADE_IDE_PORT;if($)return parseInt($,10);let Z=$q();if(Z)return Z.port;return null}async function JL(){let $=[],Z=XL();$.push(Z.content),$.push(""),$.push("\uD83D\uDCE6 已安装的 IDE:");let Y=await w3.getInstalledIdes();if(Y.length===0)$.push(" (未检测到支持的 IDE)");else for(let G of Y)$.push(` • ${G.name} ${G.version}`);$.push("");let Q=await OZ.detectIde();if(Q){if($.push(`\uD83D\uDDA5️ 当前环境: ${Q.name} ${Q.version}`),Q.extensions.length>0)$.push(` 已安装扩展: ${Q.extensions.length} 个`)}let X=Zq(),J=$q();if(X){if($.push(`\uD83D\uDD0C IDE 端口: ${X}`),J&&J.workspaceFolders.length>0)$.push(` 工作区: ${J.workspaceFolders[0]}`)}else $.push(""),$.push("\uD83D\uDCA1 提示: 在 VS Code 中安装 Blade Code 插件后,运行 /ide connect 连接");return $.join(`
2491
2491
  `)}async function GL(){let $=Zq();if(!$)return`❌ 未检测到 IDE 端口
2492
2492
 
2493
2493
  请确保:
@@ -2496,26 +2496,26 @@ ${Y}
2496
2496
  3. 在 VS Code 终端中运行 blade
2497
2497
 
2498
2498
  或手动设置端口:
2499
- export BLADE_IDE_PORT=9527`;W3="connecting";try{let Y=new(await import("ws")).default(`ws://127.0.0.1:${$}`);return await new Promise((Q,X)=>{let J=setTimeout(()=>{Y.close(),X(Error("连接超时"))},5000);Y.on("open",()=>{clearTimeout(J),W3="connected",_Z=$,zZ="VS Code",Y.close(),Q()}),Y.on("error",(G)=>{clearTimeout(J),X(G)})}),`✅ 成功连接到 IDE (端口: ${$})
2499
+ export BLADE_IDE_PORT=9527`;W8="connecting";try{let Y=new(await import("ws")).default(`ws://127.0.0.1:${$}`);return await new Promise((Q,X)=>{let J=setTimeout(()=>{Y.close(),X(Error("连接超时"))},5000);Y.on("open",()=>{clearTimeout(J),W8="connected",_Z=$,zZ="VS Code",Y.close(),Q()}),Y.on("error",(G)=>{clearTimeout(J),X(G)})}),`✅ 成功连接到 IDE (端口: ${$})
2500
2500
 
2501
2501
  现在可以使用以下功能:
2502
2502
  • 在 IDE 中打开文件
2503
2503
  • 获取当前选中的代码
2504
- • 查看打开的编辑器列表`}catch(Z){return W3="disconnected",`❌ 连接失败: ${Z instanceof Error?Z.message:"未知错误"}
2504
+ • 查看打开的编辑器列表`}catch(Z){return W8="disconnected",`❌ 连接失败: ${Z instanceof Error?Z.message:"未知错误"}
2505
2505
 
2506
2506
  请检查:
2507
2507
  1. VS Code 插件是否正在运行
2508
2508
  2. 端口 ${$} 是否正确
2509
- 3. 防火墙设置`}}async function KL(){let $=[];if($.push("\uD83D\uDCE6 安装 Blade Code VS Code 插件"),$.push(""),!await w8.isIdeInstalled("vscode"))return $.push("❌ 未检测到 VS Code"),$.push(""),$.push("请先安装 VS Code:"),$.push(" https://code.visualstudio.com/"),$.join(`
2509
+ 3. 防火墙设置`}}async function KL(){let $=[];if($.push("\uD83D\uDCE6 安装 Blade Code VS Code 插件"),$.push(""),!await w3.isIdeInstalled("vscode"))return $.push("❌ 未检测到 VS Code"),$.push(""),$.push("请先安装 VS Code:"),$.push(" https://code.visualstudio.com/"),$.join(`
2510
2510
  `);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(`
2511
- `)}async function qL(){if(W3==="disconnected")return"⚠️ 当前未连接到任何 IDE";return W3="disconnected",zZ=null,_Z=null,"✅ 已断开与 IDE 的连接"}var eK,W3="disconnected",zZ=null,_Z=null,WL,Yq;var Qq=A(()=>{sK();tK();eK=QL(YL(),".blade","ide-port");WL={name:"ide",aliases:[],description:"Manage IDE integrations and show status",usage:"/ide [status|connect|install|disconnect]",category:"system",async handler($,Z){let Y=($[0]||"").toLowerCase(),Q;switch(Y){case"":case"status":Q=await JL();break;case"connect":Q=await GL();break;case"install":Q=await KL();break;case"disconnect":Q=await qL();break;default:Q=`未知的子命令: ${Y}
2511
+ `)}async function qL(){if(W8==="disconnected")return"⚠️ 当前未连接到任何 IDE";return W8="disconnected",zZ=null,_Z=null,"✅ 已断开与 IDE 的连接"}var eK,W8="disconnected",zZ=null,_Z=null,WL,Yq;var Qq=A(()=>{sK();tK();eK=QL(YL(),".blade","ide-port");WL={name:"ide",aliases:[],description:"Manage IDE integrations and show status",usage:"/ide [status|connect|install|disconnect]",category:"system",async handler($,Z){let Y=($[0]||"").toLowerCase(),Q;switch(Y){case"":case"status":Q=await JL();break;case"connect":Q=await GL();break;case"install":Q=await KL();break;case"disconnect":Q=await qL();break;default:Q=`未知的子命令: ${Y}
2512
2512
 
2513
2513
  可用命令:
2514
2514
  /ide status - 显示连接状态
2515
2515
  /ide connect - 连接到 IDE
2516
2516
  /ide install - 安装 VS Code 插件
2517
- /ide disconnect - 断开连接`}return{success:!0,message:Q}}},Yq=WL});import{basename as P2}from"node:path";function N8($,Z){switch($){case"Write":{let Y=Z.file_path;return`\uD83D\uDCDD Writing ${Y?P2(Y):"file"}`}case"Edit":{let Y=Z.file_path;return`✏️ Editing ${Y?P2(Y):"file"}`}case"Read":{let Y=Z.file_path;return`\uD83D\uDCD6 Reading ${Y?P2(Y):"file"}`}case"Bash":{let{command:Y,description:Q}=Z;if(Q)return`⚡ ${Q}`;return`⚡ Running: ${Y?Y.substring(0,40):"command"}${Y&&Y.length>40?"...":""}`}case"Glob":return`\uD83D\uDD0D Searching files: ${Z.pattern}`;case"Grep":{let{pattern:Y,path:Q}=Z,X=Y&&Y.length>30?Y.substring(0,30)+"...":Y;if(Q){let J=P2(Q);return`\uD83D\uDD0E Searching "${X}" in ${J}`}return`\uD83D\uDD0E Searching "${X}"`}case"WebFetch":{let Y=Z.url;if(Y)try{return`\uD83C\uDF10 Fetching ${new URL(Y).hostname}`}catch{return"\uD83C\uDF10 Fetching URL"}return"\uD83C\uDF10 Fetching URL"}case"WebSearch":{let Y=Z.query;return`\uD83D\uDD0D Searching: "${Y&&Y.length>40?Y.substring(0,40)+"...":Y}"`}case"TodoWrite":return`\uD83D\uDCCB Updating tasks (${Z.todos?.length||0} items)`;case"UndoEdit":{let Y=Z.file_path;return`↩️ Undoing changes to ${Y?P2(Y):"file"}`}case"Skill":return`\uD83C\uDFAF Invoking skill: ${Z.skill}`;case"Task":{let{description:Y,subagent_type:Q}=Z;if(Y)return`\uD83E\uDD16 ${Q||"Agent"}: ${Y}`;return`\uD83E\uDD16 Running ${Q||"agent"}`}case"LSP":{let{operation:Y,filePath:Q}=Z,X=Q?P2(Q):"file";return`\uD83D\uDD17 LSP ${Y} in ${X}`}case"NotebookEdit":{let Y=Z.notebook_path;return`\uD83D\uDCD3 Editing notebook: ${Y?P2(Y):"notebook"}`}case"EnterSpecMode":return`\uD83D\uDCCB Creating spec: ${Z.name||"new spec"}`;case"UpdateSpec":return`\uD83D\uDCDD Updating ${Z.fileType}.md`;case"GetSpecContext":return"\uD83D\uDCCA Getting spec context";case"TransitionSpecPhase":return`➡️ Transitioning to: ${Z.targetPhase}`;case"AddTask":{let Y=Z.title;return`➕ Adding task: ${(Y&&Y.length>30?Y.substring(0,30)+"...":Y)||"task"}`}case"UpdateTaskStatus":{let{status:Y,taskId:Q}=Z;return`${Y==="completed"?"✅":Y==="in_progress"?"\uD83D\uDD04":"⏸️"} Task ${Q?.substring(0,8)||""}: ${Y}`}case"ValidateSpec":return"\uD83D\uDD0D Validating spec";case"ExitSpecMode":return Z.archive?"\uD83D\uDCE6 Archiving spec":"\uD83D\uDEAA Exiting spec mode";default:return`⚙️ ${$}`}}function Xq($,Z){if(!Z?.displayContent&&!Z?.success)return!1;switch($){case"Write":case"Edit":case"Read":case"Glob":case"Grep":case"Bash":return!0;case"WebFetch":case"WebSearch":return!0;case"TodoWrite":return!1;default:return!!Z.metadata?.detail}}function Jq($,Z){if(!Z?.success)return null;switch($){case"Glob":{if(!WQ(Z.metadata))return null;let{matches:Y}=Z.metadata;if(!Y?.length)return null;let Q=5,X=Y.slice(0,Q).map((J)=>J.relative_path);if(Y.length>Q)X.push(`... (+${Y.length-Q} more)`);return X.join(`
2518
- `)}case"Grep":{let Y=Z.llmContent;if(!Array.isArray(Y)||!Y.length)return null;let Q=5,X=Y.slice(0,Q).map((J)=>{let G=P2(J.file_path);if(J.line_number)return`${G}:${J.line_number}`;return G});if(Y.length>Q)X.push(`... (+${Y.length-Q} more)`);return X.join(`
2517
+ /ide disconnect - 断开连接`}return{success:!0,message:Q}}},Yq=WL});import{basename as P4}from"node:path";function N3($,Z){switch($){case"Write":{let Y=Z.file_path;return`\uD83D\uDCDD Writing ${Y?P4(Y):"file"}`}case"Edit":{let Y=Z.file_path;return`✏️ Editing ${Y?P4(Y):"file"}`}case"Read":{let Y=Z.file_path;return`\uD83D\uDCD6 Reading ${Y?P4(Y):"file"}`}case"Bash":{let{command:Y,description:Q}=Z;if(Q)return`⚡ ${Q}`;return`⚡ Running: ${Y?Y.substring(0,40):"command"}${Y&&Y.length>40?"...":""}`}case"Glob":return`\uD83D\uDD0D Searching files: ${Z.pattern}`;case"Grep":{let{pattern:Y,path:Q}=Z,X=Y&&Y.length>30?Y.substring(0,30)+"...":Y;if(Q){let J=P4(Q);return`\uD83D\uDD0E Searching "${X}" in ${J}`}return`\uD83D\uDD0E Searching "${X}"`}case"WebFetch":{let Y=Z.url;if(Y)try{return`\uD83C\uDF10 Fetching ${new URL(Y).hostname}`}catch{return"\uD83C\uDF10 Fetching URL"}return"\uD83C\uDF10 Fetching URL"}case"WebSearch":{let Y=Z.query;return`\uD83D\uDD0D Searching: "${Y&&Y.length>40?Y.substring(0,40)+"...":Y}"`}case"TodoWrite":return`\uD83D\uDCCB Updating tasks (${Z.todos?.length||0} items)`;case"UndoEdit":{let Y=Z.file_path;return`↩️ Undoing changes to ${Y?P4(Y):"file"}`}case"Skill":return`\uD83C\uDFAF Invoking skill: ${Z.skill}`;case"Task":{let{description:Y,subagent_type:Q}=Z;if(Y)return`\uD83E\uDD16 ${Q||"Agent"}: ${Y}`;return`\uD83E\uDD16 Running ${Q||"agent"}`}case"LSP":{let{operation:Y,filePath:Q}=Z,X=Q?P4(Q):"file";return`\uD83D\uDD17 LSP ${Y} in ${X}`}case"NotebookEdit":{let Y=Z.notebook_path;return`\uD83D\uDCD3 Editing notebook: ${Y?P4(Y):"notebook"}`}case"EnterSpecMode":return`\uD83D\uDCCB Creating spec: ${Z.name||"new spec"}`;case"UpdateSpec":return`\uD83D\uDCDD Updating ${Z.fileType}.md`;case"GetSpecContext":return"\uD83D\uDCCA Getting spec context";case"TransitionSpecPhase":return`➡️ Transitioning to: ${Z.targetPhase}`;case"AddTask":{let Y=Z.title;return`➕ Adding task: ${(Y&&Y.length>30?Y.substring(0,30)+"...":Y)||"task"}`}case"UpdateTaskStatus":{let{status:Y,taskId:Q}=Z;return`${Y==="completed"?"✅":Y==="in_progress"?"\uD83D\uDD04":"⏸️"} Task ${Q?.substring(0,8)||""}: ${Y}`}case"ValidateSpec":return"\uD83D\uDD0D Validating spec";case"ExitSpecMode":return Z.archive?"\uD83D\uDCE6 Archiving spec":"\uD83D\uDEAA Exiting spec mode";default:return`⚙️ ${$}`}}function Xq($,Z){if(!Z?.displayContent&&!Z?.success)return!1;switch($){case"Write":case"Edit":case"Read":case"Glob":case"Grep":case"Bash":return!0;case"WebFetch":case"WebSearch":return!0;case"TodoWrite":return!1;default:return!!Z.metadata?.detail}}function Jq($,Z){if(!Z?.success)return null;switch($){case"Glob":{if(!WQ(Z.metadata))return null;let{matches:Y}=Z.metadata;if(!Y?.length)return null;let Q=5,X=Y.slice(0,Q).map((J)=>J.relative_path);if(Y.length>Q)X.push(`... (+${Y.length-Q} more)`);return X.join(`
2518
+ `)}case"Grep":{let Y=Z.llmContent;if(!Array.isArray(Y)||!Y.length)return null;let Q=5,X=Y.slice(0,Q).map((J)=>{let G=P4(J.file_path);if(J.line_number)return`${G}:${J.line_number}`;return G});if(Y.length>Q)X.push(`... (+${Y.length-Q} more)`);return X.join(`
2519
2519
  `)}case"Read":{let Y=Z.metadata?.content_preview||Z.llmContent;if(typeof Y!=="string"||!Y)return null;let Q=Y.split(`
2520
2520
  `),X=Q.length,J=3;if(X<=J+1)return Y;return`${Q.slice(0,J).join(`
2521
2521
  `)}
@@ -2528,7 +2528,7 @@ ${Y}
2528
2528
  ... (+${Q.length-X} line(s))`}case"Edit":{if(!UQ(Z.metadata))return null;let{diff_snippet:Y}=Z.metadata;if(Y){let Q=Y.split(`
2529
2529
  `),X=6;if(Q.length>6)return Q.slice(0,6).join(`
2530
2530
  `)+`
2531
- ... (+${Q.length-6} line(s))`;return Y}return null}default:{let Y=Z.metadata?.detail;return typeof Y==="string"?Y:null}}}var BZ=A(()=>{j0()});import{promises as b8}from"fs";import*as Gq from"path";var U3,UL,Kq;var qq=A(()=>{X2();O$();k$();BZ();T1();U3=l("Agent"),UL={name:"init",description:"分析当前项目并生成 BLADE.md 配置文件",usage:"/init",async handler($,Z){try{let{cwd:Y,signal:Q}=Z,X=d$(Z),J=(O)=>{X.sendMessage(`${O}`)},G=q$().session.sessionId,K=Gq.join(Y,"BLADE.md"),q=!1,W=!1;try{if(q=(await b8.stat(K)).isFile(),q)W=(await b8.readFile(K,"utf-8")).trim().length===0}catch{q=!1}if(q&&!W){X.sendMessage("⚠️ BLADE.md 已存在。"),X.sendMessage("\uD83D\uDCA1 正在分析现有文件并提供改进建议...");let O=await O0.create();if(Q?.aborted)return{success:!1,message:"操作已取消"};let z=`Please analyze the existing BLADE.md file and provide improvement suggestions.
2531
+ ... (+${Q.length-6} line(s))`;return Y}return null}default:{let Y=Z.metadata?.detail;return typeof Y==="string"?Y:null}}}var BZ=A(()=>{j0()});import{promises as b3}from"fs";import*as Gq from"path";var U8,UL,Kq;var qq=A(()=>{X4();O$();k$();BZ();T1();U8=l("Agent"),UL={name:"init",description:"分析当前项目并生成 BLADE.md 配置文件",usage:"/init",async handler($,Z){try{let{cwd:Y,signal:Q}=Z,X=d$(Z),J=(O)=>{X.sendMessage(`${O}`)},G=q$().session.sessionId,K=Gq.join(Y,"BLADE.md"),q=!1,W=!1;try{if(q=(await b3.stat(K)).isFile(),q)W=(await b3.readFile(K,"utf-8")).trim().length===0}catch{q=!1}if(q&&!W){X.sendMessage("⚠️ BLADE.md 已存在。"),X.sendMessage("\uD83D\uDCA1 正在分析现有文件并提供改进建议...");let O=await O0.create();if(Q?.aborted)return{success:!1,message:"操作已取消"};let z=`Please analyze the existing BLADE.md file and provide improvement suggestions.
2532
2532
 
2533
2533
  **Important**:
2534
2534
  - After each step, briefly describe what you found before proceeding
@@ -2568,7 +2568,7 @@ ${Y}
2568
2568
  - 具体的改进建议(附带示例)
2569
2569
  - 如果需要重大修改,提供完整的改进版本内容
2570
2570
 
2571
- **Final output**: Return your analysis and suggestions as plain text. Do NOT use Write tool.`;U3.info(`[/init] Starting agent.chat, signal.aborted: ${Q?.aborted}`);let _=await O.chat(z,{messages:[],userId:"cli-user",sessionId:G||"init-session",workspaceRoot:Y,signal:Q},{onToolStart:(B)=>{if(B.type!=="function")return;try{let L=JSON.parse(B.function.arguments),w=N8(B.function.name,L);J(w)}catch{}},onToolResult:async(B,L)=>{if(B.type!=="function")return;let w=L.metadata?.summary;if(w)J(w)}});if(U3.info(`[/init] agent.chat completed, signal.aborted: ${Q?.aborted}`),Q?.aborted)return U3.info("[/init] Returning cancelled after agent.chat"),{success:!1,message:"操作已取消"};return X.sendMessage(_),{success:!0,message:"✅ 分析完成"}}if(W)X.sendMessage("⚠️ 检测到空的 BLADE.md 文件,将重新生成...");X.sendMessage("\uD83D\uDD0D 正在分析项目结构...");let U=await O0.create();if(Q?.aborted)return{success:!1,message:"操作已取消"};let H=`Please analyze this codebase and generate BLADE.md content.
2571
+ **Final output**: Return your analysis and suggestions as plain text. Do NOT use Write tool.`;U8.info(`[/init] Starting agent.chat, signal.aborted: ${Q?.aborted}`);let _=await O.chat(z,{messages:[],userId:"cli-user",sessionId:G||"init-session",workspaceRoot:Y,signal:Q},{onToolStart:(B)=>{if(B.type!=="function")return;try{let L=JSON.parse(B.function.arguments),w=N3(B.function.name,L);J(w)}catch{}},onToolResult:async(B,L)=>{if(B.type!=="function")return;let w=L.metadata?.summary;if(w)J(w)}});if(U8.info(`[/init] agent.chat completed, signal.aborted: ${Q?.aborted}`),Q?.aborted)return U8.info("[/init] Returning cancelled after agent.chat"),{success:!1,message:"操作已取消"};return X.sendMessage(_),{success:!0,message:"✅ 分析完成"}}if(W)X.sendMessage("⚠️ 检测到空的 BLADE.md 文件,将重新生成...");X.sendMessage("\uD83D\uDD0D 正在分析项目结构...");let U=await O0.create();if(Q?.aborted)return{success:!1,message:"操作已取消"};let H=`Please analyze this codebase and generate BLADE.md content.
2572
2572
 
2573
2573
  **Important**: After each step, briefly describe what you found before proceeding.
2574
2574
 
@@ -2615,7 +2615,7 @@ ${Y}
2615
2615
  - Focus on non-obvious insights
2616
2616
  - Be concise but comprehensive for complex projects
2617
2617
 
2618
- **Final output**: Return ONLY the complete BLADE.md content (markdown format), ready to be written to the file.`;U3.info(`[/init] Starting agent.chat for new BLADE.md, signal.aborted: ${Q?.aborted}`);let F=await U.chat(H,{messages:[],userId:"cli-user",sessionId:G||"init-session",workspaceRoot:Y,signal:Q},{onToolStart:(O)=>{if(O.type!=="function")return;try{let z=JSON.parse(O.function.arguments),_=N8(O.function.name,z);J(_)}catch{}},onToolResult:async(O,z)=>{if(O.type!=="function")return;if(z?.metadata?.summary){if(typeof z.metadata.summary==="string")J(z.metadata.summary)}}});if(U3.info(`[/init] agent.chat completed for new BLADE.md, signal.aborted: ${Q?.aborted}`),Q?.aborted)return U3.info("[/init] Returning cancelled after agent.chat (new BLADE.md)"),{success:!1,message:"操作已取消"};if(!F||F.trim().length===0)throw Error("Agent 未能生成有效的 BLADE.md 内容");return X.sendMessage("✨ 正在写入 BLADE.md..."),await b8.writeFile(K,F,"utf-8"),{success:!0,message:"✅ 已成功生成 BLADE.md 文件"}}catch(Y){return{success:!1,error:`初始化失败: ${Y instanceof Error?Y.message:"未知错误"}`}}}},Kq=UL});function HL($){if($.includes("copilot")||$.includes("github"))return"copilot";if($.includes("gemini")||$.includes("gemini-cli"))return"gemini-cli";return"antigravity"}var Wq;var Uq=A(()=>{i3();g3();t3();n3();T1();Wq={name:"login",description:"登录 OAuth 服务(Antigravity / Copilot)",fullDescription:`登录 OAuth 服务以使用 AI 模型。
2618
+ **Final output**: Return ONLY the complete BLADE.md content (markdown format), ready to be written to the file.`;U8.info(`[/init] Starting agent.chat for new BLADE.md, signal.aborted: ${Q?.aborted}`);let F=await U.chat(H,{messages:[],userId:"cli-user",sessionId:G||"init-session",workspaceRoot:Y,signal:Q},{onToolStart:(O)=>{if(O.type!=="function")return;try{let z=JSON.parse(O.function.arguments),_=N3(O.function.name,z);J(_)}catch{}},onToolResult:async(O,z)=>{if(O.type!=="function")return;if(z?.metadata?.summary){if(typeof z.metadata.summary==="string")J(z.metadata.summary)}}});if(U8.info(`[/init] agent.chat completed for new BLADE.md, signal.aborted: ${Q?.aborted}`),Q?.aborted)return U8.info("[/init] Returning cancelled after agent.chat (new BLADE.md)"),{success:!1,message:"操作已取消"};if(!F||F.trim().length===0)throw Error("Agent 未能生成有效的 BLADE.md 内容");return X.sendMessage("✨ 正在写入 BLADE.md..."),await b3.writeFile(K,F,"utf-8"),{success:!0,message:"✅ 已成功生成 BLADE.md 文件"}}catch(Y){return{success:!1,error:`初始化失败: ${Y instanceof Error?Y.message:"未知错误"}`}}}},Kq=UL});function HL($){if($.includes("copilot")||$.includes("github"))return"copilot";if($.includes("gemini")||$.includes("gemini-cli"))return"gemini-cli";return"antigravity"}var Wq;var Uq=A(()=>{i8();g8();t8();n8();T1();Wq={name:"login",description:"登录 OAuth 服务(Antigravity / Copilot)",fullDescription:`登录 OAuth 服务以使用 AI 模型。
2619
2619
 
2620
2620
  **支持的服务:**
2621
2621
 
@@ -2634,7 +2634,7 @@ ${Y}
2634
2634
  - \`/login gemini\` - 使用 Gemini CLI OAuth(Antigravity 备选)
2635
2635
  - \`/login copilot\` - 登录 GitHub Copilot
2636
2636
 
2637
- 登录后,使用 \`/model add\` 添加模型配置。`,usage:"/login [copilot|gemini]",category:"auth",examples:["/login","/login copilot","/login gemini"],async handler($,Z){let Y=d$(Z),Q=HL($);if(Q==="copilot"){let K=S0.getInstance();try{if(await K.isLoggedIn()){let W=await K.getStatus(),U=W.expiresAt?Math.round((W.expiresAt.getTime()-Date.now())/1000/60):0;return Y.sendMessage("✅ 已登录 GitHub Copilot"),Y.sendMessage(`Token 有效期还剩约 ${U} 分钟`),Y.sendMessage(""),Y.sendMessage("如需重新登录,请先执行 /logout copilot"),{success:!0,message:"已登录",content:`已登录 GitHub Copilot,Token 有效期还剩约 ${U} 分钟`}}await K.login(),Y.sendMessage(""),Y.sendMessage("**可用模型:**");for(let W of Object.values(r8))Y.sendMessage(` - ${W.id} (${W.provider})`);return Y.sendMessage(""),Y.sendMessage("**下一步:**"),Y.sendMessage("使用 `/model add` 添加 Copilot 模型配置"),Y.sendMessage("Provider 选择 `copilot`,Model 输入模型 ID(如 gpt-4o)"),{success:!0,message:"登录成功",content:"已成功登录 GitHub Copilot。使用 /model add 添加模型配置。"}}catch(q){let W=q instanceof Error?q.message:String(q);return Y.sendMessage(`❌ 登录失败: ${W}`),{success:!1,error:W}}}let X=I0.getInstance(),J=Q==="gemini-cli"?"gemini-cli":"antigravity",G=Q==="gemini-cli"?"Gemini CLI":"Antigravity";try{if(await X.isLoggedIn()){let W=await X.getStatus(),U=W.expiresAt?Math.round((W.expiresAt.getTime()-Date.now())/1000/60):0,H=W.configType==="gemini-cli"?"Gemini CLI":"Antigravity";return Y.sendMessage(`✅ 已登录(${H} OAuth)`),Y.sendMessage(`Token 有效期还剩约 ${U} 分钟`),Y.sendMessage(""),Y.sendMessage("如需重新登录或切换 OAuth 方式,请先执行 /logout"),{success:!0,message:"已登录",content:`已登录(${H} OAuth),Token 有效期还剩约 ${U} 分钟`}}Y.sendMessage(`\uD83D\uDD10 开始 ${G} OAuth 登录...`),Y.sendMessage(""),await X.login(J),Y.sendMessage(""),Y.sendMessage(`✅ ${G} 登录成功!`),Y.sendMessage(""),Y.sendMessage("**可用模型:**");let q=Q==="gemini-cli"?g8:u3;for(let W of Object.values(q)){let U=W.supportsThinking?" (Thinking)":"";Y.sendMessage(` - ${W.id}${U}`)}return Y.sendMessage(""),Y.sendMessage("**下一步:**"),Y.sendMessage(`使用 \`/model add\` 添加 ${G} 模型配置`),{success:!0,message:"登录成功",content:`已成功通过 ${G} OAuth 登录。使用 /model add 添加模型配置。`}}catch(K){let q=K instanceof Error?K.message:String(K);return Y.sendMessage(`❌ 登录失败: ${q}`),{success:!1,error:q}}}}});function FL($){if($.includes("copilot")||$.includes("github"))return"copilot";if($.includes("all"))return"all";return"antigravity"}var Hq;var Fq=A(()=>{i3();t3();T1();Hq={name:"logout",description:"登出 OAuth 服务并清除 token",fullDescription:`登出 OAuth 服务,清除本地存储的 token。
2637
+ 登录后,使用 \`/model add\` 添加模型配置。`,usage:"/login [copilot|gemini]",category:"auth",examples:["/login","/login copilot","/login gemini"],async handler($,Z){let Y=d$(Z),Q=HL($);if(Q==="copilot"){let K=S0.getInstance();try{if(await K.isLoggedIn()){let W=await K.getStatus(),U=W.expiresAt?Math.round((W.expiresAt.getTime()-Date.now())/1000/60):0;return Y.sendMessage("✅ 已登录 GitHub Copilot"),Y.sendMessage(`Token 有效期还剩约 ${U} 分钟`),Y.sendMessage(""),Y.sendMessage("如需重新登录,请先执行 /logout copilot"),{success:!0,message:"已登录",content:`已登录 GitHub Copilot,Token 有效期还剩约 ${U} 分钟`}}await K.login(),Y.sendMessage(""),Y.sendMessage("**可用模型:**");for(let W of Object.values(r3))Y.sendMessage(` - ${W.id} (${W.provider})`);return Y.sendMessage(""),Y.sendMessage("**下一步:**"),Y.sendMessage("使用 `/model add` 添加 Copilot 模型配置"),Y.sendMessage("Provider 选择 `copilot`,Model 输入模型 ID(如 gpt-4o)"),{success:!0,message:"登录成功",content:"已成功登录 GitHub Copilot。使用 /model add 添加模型配置。"}}catch(q){let W=q instanceof Error?q.message:String(q);return Y.sendMessage(`❌ 登录失败: ${W}`),{success:!1,error:W}}}let X=I0.getInstance(),J=Q==="gemini-cli"?"gemini-cli":"antigravity",G=Q==="gemini-cli"?"Gemini CLI":"Antigravity";try{if(await X.isLoggedIn()){let W=await X.getStatus(),U=W.expiresAt?Math.round((W.expiresAt.getTime()-Date.now())/1000/60):0,H=W.configType==="gemini-cli"?"Gemini CLI":"Antigravity";return Y.sendMessage(`✅ 已登录(${H} OAuth)`),Y.sendMessage(`Token 有效期还剩约 ${U} 分钟`),Y.sendMessage(""),Y.sendMessage("如需重新登录或切换 OAuth 方式,请先执行 /logout"),{success:!0,message:"已登录",content:`已登录(${H} OAuth),Token 有效期还剩约 ${U} 分钟`}}Y.sendMessage(`\uD83D\uDD10 开始 ${G} OAuth 登录...`),Y.sendMessage(""),await X.login(J),Y.sendMessage(""),Y.sendMessage(`✅ ${G} 登录成功!`),Y.sendMessage(""),Y.sendMessage("**可用模型:**");let q=Q==="gemini-cli"?g3:u8;for(let W of Object.values(q)){let U=W.supportsThinking?" (Thinking)":"";Y.sendMessage(` - ${W.id}${U}`)}return Y.sendMessage(""),Y.sendMessage("**下一步:**"),Y.sendMessage(`使用 \`/model add\` 添加 ${G} 模型配置`),{success:!0,message:"登录成功",content:`已成功通过 ${G} OAuth 登录。使用 /model add 添加模型配置。`}}catch(K){let q=K instanceof Error?K.message:String(K);return Y.sendMessage(`❌ 登录失败: ${q}`),{success:!1,error:q}}}}});function FL($){if($.includes("copilot")||$.includes("github"))return"copilot";if($.includes("all"))return"all";return"antigravity"}var Hq;var Fq=A(()=>{i8();t8();T1();Hq={name:"logout",description:"登出 OAuth 服务并清除 token",fullDescription:`登出 OAuth 服务,清除本地存储的 token。
2638
2638
 
2639
2639
  **用法:**
2640
2640
  - \`/logout\` - 登出 Antigravity(默认)
@@ -2653,22 +2653,22 @@ ${Y}
2653
2653
  /model # 显示模型选择器
2654
2654
  /model add # 添加新模型
2655
2655
  /model remove 千问 # 删除名称包含"千问"的模型
2656
- `,async handler($,Z){let Y=$[0];if(!Y){if(S3().length===0)return{success:!1,message:`❌ 没有可用的模型配置
2656
+ `,async handler($,Z){let Y=$[0];if(!Y){if(S8().length===0)return{success:!1,message:`❌ 没有可用的模型配置
2657
2657
 
2658
2658
  使用 /model add 添加模型`};return{success:!0,message:"show_model_selector",data:{action:"show_model_selector"}}}switch(Y){case"add":return{success:!0,message:"show_model_add_wizard",data:{action:"show_model_add_wizard",mode:"add"}};case"remove":{let Q=$.slice(1).join(" ");if(!Q)return{success:!1,message:`❌ 请指定要删除的模型名称
2659
- 用法: /model remove <名称>`};let J=S3().find((G)=>G.name.toLowerCase().includes(Q.toLowerCase()));if(!J)return{success:!1,message:`❌ 未找到匹配的模型配置: ${Q}`};try{return await x$().removeModel(J.id),{success:!0,message:`✅ 已删除模型配置: ${J.name}`}}catch(G){return{success:!1,message:`❌ ${G.message}`}}}default:return{success:!1,message:`❌ 未知的子命令: ${Y}
2659
+ 用法: /model remove <名称>`};let J=S8().find((G)=>G.name.toLowerCase().includes(Q.toLowerCase()));if(!J)return{success:!1,message:`❌ 未找到匹配的模型配置: ${Q}`};try{return await x$().removeModel(J.id),{success:!0,message:`✅ 已删除模型配置: ${J.name}`}}catch(G){return{success:!1,message:`❌ ${G.message}`}}}default:return{success:!1,message:`❌ 未知的子命令: ${Y}
2660
2660
  使用 /model 查看可用操作`}}}},Oq=OL});function _L($){if($.getAll().length===0)return _$().addAssistantMessage(`没有已加载的插件。
2661
2661
 
2662
2662
  `+"使用 `--plugin-dir <path>` 参数加载插件,或将插件放置在:\n"+"- `~/.blade/plugins/` - 用户级插件\n"+"- `.blade/plugins/` - 项目级插件"),{success:!0,message:"No plugins loaded"};let Y=["## 已加载的插件",""],Q=$.getBySource();if(Q.cli.length>0){Y.push("### CLI 指定");for(let X of Q.cli){let J=X.status==="inactive"?" ⏸️":" ✅";Y.push(`- **${X.manifest.name}** v${X.manifest.version}${J}`),Y.push(` ${X.manifest.description}`)}Y.push("")}if(Q.project.length>0){Y.push("### 项目级");for(let X of Q.project){let J=X.status==="inactive"?" ⏸️":" ✅";Y.push(`- **${X.manifest.name}** v${X.manifest.version}${J}`),Y.push(` ${X.manifest.description}`)}Y.push("")}if(Q.user.length>0){Y.push("### 用户级");for(let X of Q.user){let J=X.status==="inactive"?" ⏸️":" ✅";Y.push(`- **${X.manifest.name}** v${X.manifest.version}${J}`),Y.push(` ${X.manifest.description}`)}}return _$().addAssistantMessage(Y.join(`
2663
2663
  `)),{success:!0,message:"Plugins listed"}}function BL($,Z){if(!Z)return _$().addAssistantMessage("请指定插件名称: `/plugins info <name>`"),{success:!1,error:"Plugin name required"};let Y=$.get(Z);if(!Y)return _$().addAssistantMessage(`未找到插件: ${Z}`),{success:!1,error:`Plugin not found: ${Z}`};let Q=[`## ${Y.manifest.name}`,"",`**版本**: ${Y.manifest.version}`,`**描述**: ${Y.manifest.description}`,`**状态**: ${Y.status==="active"?"✅ 启用":"⏸️ 禁用"}`,`**来源**: ${RL(Y.source)}`,`**路径**: \`${Y.basePath}\``,""];if(Y.manifest.author)Q.push(`**作者**: ${Y.manifest.author.name}`);if(Y.manifest.license)Q.push(`**许可证**: ${Y.manifest.license}`);if(Y.manifest.repository)Q.push(`**仓库**: ${Y.manifest.repository}`);if(Y.commands.length>0){Q.push(""),Q.push(`### 命令 (${Y.commands.length})`);for(let X of Y.commands){let J=X.config.argumentHint?` ${X.config.argumentHint}`:"",G=X.config.description?` - ${X.config.description}`:"";Q.push(`- \`/${X.namespacedName}${J}\`${G}`)}}if(Y.skills.length>0){Q.push(""),Q.push(`### 技能 (${Y.skills.length})`);for(let X of Y.skills)Q.push(`- \`${X.namespacedName}\` - ${X.metadata.description}`)}if(Y.agents.length>0){Q.push(""),Q.push(`### 代理 (${Y.agents.length})`);for(let X of Y.agents)Q.push(`- \`${X.namespacedName}\` - ${X.config.description}`)}if(Y.mcpServers){let X=Object.keys(Y.mcpServers).length;Q.push(""),Q.push(`### MCP 服务器 (${X})`);for(let J of Object.keys(Y.mcpServers))Q.push(`- \`${J}\``)}if(Y.hooks)Q.push(""),Q.push("### Hooks"),Q.push("插件已配置 hooks");return _$().addAssistantMessage(Q.join(`
2664
- `)),{success:!0,message:"Plugin info displayed"}}function LL($,Z){if(!Z)return _$().addAssistantMessage("请指定插件名称: `/plugins enable <name>`"),{success:!1,error:"Plugin name required"};if($.enable(Z))return _$().addAssistantMessage(`✅ 已启用插件: ${Z}`),{success:!0,message:`Plugin ${Z} enabled`};if(!$.get(Z))return _$().addAssistantMessage(`未找到插件: ${Z}`),{success:!1,error:`Plugin not found: ${Z}`};return _$().addAssistantMessage(`插件 ${Z} 已经是启用状态`),{success:!0,message:`Plugin ${Z} already enabled`}}function wL($,Z){if(!Z)return _$().addAssistantMessage("请指定插件名称: `/plugins disable <name>`"),{success:!1,error:"Plugin name required"};if($.disable(Z))return _$().addAssistantMessage(`⏸️ 已禁用插件: ${Z}`),{success:!0,message:`Plugin ${Z} disabled`};if(!$.get(Z))return _$().addAssistantMessage(`未找到插件: ${Z}`),{success:!1,error:`Plugin not found: ${Z}`};return _$().addAssistantMessage(`插件 ${Z} 已经是禁用状态`),{success:!0,message:`Plugin ${Z} already disabled`}}async function NL($){h9(),await $.refresh(),await E2()}async function bL($){try{h9();let Z=await $.refresh(),Y=await E2(),Q=["✅ 已刷新插件列表","",`- 加载了 ${Z.plugins.length} 个插件`,`- 集成了 ${Y.totalCommands} 个命令, ${Y.totalSkills} 个技能, ${Y.totalAgents} 个代理`];if(Z.errors.length>0){Q.push(`- ${Z.errors.length} 个加载错误`),Q.push(""),Q.push("### 错误");for(let X of Z.errors)Q.push(`- \`${X.path}\`: ${X.error}`)}if(Y.errors.length>0){Q.push(""),Q.push("### 集成错误");for(let X of Y.errors)Q.push(`- ${X}`)}return _$().addAssistantMessage(Q.join(`
2664
+ `)),{success:!0,message:"Plugin info displayed"}}function LL($,Z){if(!Z)return _$().addAssistantMessage("请指定插件名称: `/plugins enable <name>`"),{success:!1,error:"Plugin name required"};if($.enable(Z))return _$().addAssistantMessage(`✅ 已启用插件: ${Z}`),{success:!0,message:`Plugin ${Z} enabled`};if(!$.get(Z))return _$().addAssistantMessage(`未找到插件: ${Z}`),{success:!1,error:`Plugin not found: ${Z}`};return _$().addAssistantMessage(`插件 ${Z} 已经是启用状态`),{success:!0,message:`Plugin ${Z} already enabled`}}function wL($,Z){if(!Z)return _$().addAssistantMessage("请指定插件名称: `/plugins disable <name>`"),{success:!1,error:"Plugin name required"};if($.disable(Z))return _$().addAssistantMessage(`⏸️ 已禁用插件: ${Z}`),{success:!0,message:`Plugin ${Z} disabled`};if(!$.get(Z))return _$().addAssistantMessage(`未找到插件: ${Z}`),{success:!1,error:`Plugin not found: ${Z}`};return _$().addAssistantMessage(`插件 ${Z} 已经是禁用状态`),{success:!0,message:`Plugin ${Z} already disabled`}}async function NL($){h9(),await $.refresh(),await E4()}async function bL($){try{h9();let Z=await $.refresh(),Y=await E4(),Q=["✅ 已刷新插件列表","",`- 加载了 ${Z.plugins.length} 个插件`,`- 集成了 ${Y.totalCommands} 个命令, ${Y.totalSkills} 个技能, ${Y.totalAgents} 个代理`];if(Z.errors.length>0){Q.push(`- ${Z.errors.length} 个加载错误`),Q.push(""),Q.push("### 错误");for(let X of Z.errors)Q.push(`- \`${X.path}\`: ${X.error}`)}if(Y.errors.length>0){Q.push(""),Q.push("### 集成错误");for(let X of Y.errors)Q.push(`- ${X}`)}return _$().addAssistantMessage(Q.join(`
2665
2665
  `)),{success:!0,message:"Plugins refreshed"}}catch(Z){let Y=Z instanceof Error?Z.message:String(Z);return _$().addAssistantMessage(`❌ 刷新失败: ${Y}`),{success:!1,error:Y}}}function AL($){let Z=$.getStats(),Y=["## 插件统计","","| 指标 | 数量 |","|------|------|",`| 总插件数 | ${Z.total} |`,`| 启用 | ${Z.active} |`,`| 禁用 | ${Z.inactive} |`,`| 命令 | ${Z.commands} |`,`| 技能 | ${Z.skills} |`,`| 代理 | ${Z.agents} |`];return _$().addAssistantMessage(Y.join(`
2666
2666
  `)),{success:!0,message:"Stats displayed"}}function RL($){switch($){case"cli":return"CLI 参数";case"project":return"项目级";case"user":return"用户级";default:return $}}async function VL($){if(!$)return _$().addAssistantMessage("请指定插件 URL: `/plugins install <url>`\n\n"+`支持的格式:
2667
- `+"- GitHub 简写: `user/repo`\n"+"- 完整 URL: `https://github.com/user/repo`"),{success:!1,error:"Plugin URL required"};_$().addAssistantMessage(`正在安装插件: ${$}...`);let Y=await O8().install($);if(Y.success){let Q=["✅ 插件安装成功!","",`**名称**: ${Y.pluginName}`,`**路径**: \`${Y.pluginPath}\``];if(Y.manifest)Q.push(`**版本**: ${Y.manifest.version}`),Q.push(`**描述**: ${Y.manifest.description}`);return Q.push(""),Q.push("使用 `/plugins refresh` 加载新安装的插件。"),_$().addAssistantMessage(Q.join(`
2668
- `)),{success:!0,message:`Installed ${Y.pluginName}`}}return _$().addAssistantMessage(`❌ 安装失败: ${Y.error}`),{success:!1,error:Y.error}}async function DL($){if(!$)return _$().addAssistantMessage("请指定插件名称: `/plugins uninstall <name>`"),{success:!1,error:"Plugin name required"};let Y=await O8().uninstall($);if(Y.success)return _$().addAssistantMessage(`✅ 已卸载插件: ${Y.pluginName}
2667
+ `+"- GitHub 简写: `user/repo`\n"+"- 完整 URL: `https://github.com/user/repo`"),{success:!1,error:"Plugin URL required"};_$().addAssistantMessage(`正在安装插件: ${$}...`);let Y=await O3().install($);if(Y.success){let Q=["✅ 插件安装成功!","",`**名称**: ${Y.pluginName}`,`**路径**: \`${Y.pluginPath}\``];if(Y.manifest)Q.push(`**版本**: ${Y.manifest.version}`),Q.push(`**描述**: ${Y.manifest.description}`);return Q.push(""),Q.push("使用 `/plugins refresh` 加载新安装的插件。"),_$().addAssistantMessage(Q.join(`
2668
+ `)),{success:!0,message:`Installed ${Y.pluginName}`}}return _$().addAssistantMessage(`❌ 安装失败: ${Y.error}`),{success:!1,error:Y.error}}async function DL($){if(!$)return _$().addAssistantMessage("请指定插件名称: `/plugins uninstall <name>`"),{success:!1,error:"Plugin name required"};let Y=await O3().uninstall($);if(Y.success)return _$().addAssistantMessage(`✅ 已卸载插件: ${Y.pluginName}
2669
2669
 
2670
- `+"使用 `/plugins refresh` 刷新插件列表。"),{success:!0,message:`Uninstalled ${Y.pluginName}`};return _$().addAssistantMessage(`❌ 卸载失败: ${Y.error}`),{success:!1,error:Y.error}}async function ML($){if(!$)return _$().addAssistantMessage("请指定插件名称: `/plugins update <name>`"),{success:!1,error:"Plugin name required"};_$().addAssistantMessage(`正在更新插件: ${$}...`);let Y=await O8().update($);if(Y.success){let Q=["✅ 插件更新成功!","",`**名称**: ${Y.pluginName}`];if(Y.manifest)Q.push(`**版本**: ${Y.manifest.version}`);return Q.push(""),Q.push("使用 `/plugins refresh` 重新加载插件。"),_$().addAssistantMessage(Q.join(`
2671
- `)),{success:!0,message:`Updated ${Y.pluginName}`}}return _$().addAssistantMessage(`❌ 更新失败: ${Y.error}`),{success:!1,error:Y.error}}var zL,_q;var Bq=A(()=>{q3();k$();zL={name:"plugins",description:"管理已安装的插件",fullDescription:`管理 Blade Code 插件系统。
2670
+ `+"使用 `/plugins refresh` 刷新插件列表。"),{success:!0,message:`Uninstalled ${Y.pluginName}`};return _$().addAssistantMessage(`❌ 卸载失败: ${Y.error}`),{success:!1,error:Y.error}}async function ML($){if(!$)return _$().addAssistantMessage("请指定插件名称: `/plugins update <name>`"),{success:!1,error:"Plugin name required"};_$().addAssistantMessage(`正在更新插件: ${$}...`);let Y=await O3().update($);if(Y.success){let Q=["✅ 插件更新成功!","",`**名称**: ${Y.pluginName}`];if(Y.manifest)Q.push(`**版本**: ${Y.manifest.version}`);return Q.push(""),Q.push("使用 `/plugins refresh` 重新加载插件。"),_$().addAssistantMessage(Q.join(`
2671
+ `)),{success:!0,message:`Updated ${Y.pluginName}`}}return _$().addAssistantMessage(`❌ 更新失败: ${Y.error}`),{success:!1,error:Y.error}}var zL,_q;var Bq=A(()=>{q8();k$();zL={name:"plugins",description:"管理已安装的插件",fullDescription:`管理 Blade Code 插件系统。
2672
2672
 
2673
2673
  子命令:
2674
2674
  /plugins - 打开插件管理界面
@@ -2681,13 +2681,13 @@ ${Y}
2681
2681
  /plugins disable <name> - 禁用插件
2682
2682
  /plugins refresh - 刷新插件列表
2683
2683
  /plugins stats - 显示插件统计信息`,usage:"/plugins [list|info|install|uninstall|update|enable|disable|refresh|stats] [name/url]",category:"system",examples:["/plugins","/plugins list","/plugins info my-plugin","/plugins install user/repo","/plugins install https://github.com/user/repo","/plugins uninstall my-plugin","/plugins update my-plugin","/plugins enable my-plugin","/plugins disable my-plugin","/plugins refresh","/plugins stats"],handler:async($,Z)=>{let Y=$[0]?.toLowerCase()||"",Q=a0();switch(Y){case"":return await NL(Q),{success:!0,message:"show_plugins_manager",data:{action:"show_plugins_manager"}};case"list":case"ls":return _L(Q);case"info":return BL(Q,$[1]);case"install":case"add":return VL($[1]);case"uninstall":case"remove":case"rm":return DL($[1]);case"update":case"upgrade":return ML($[1]);case"enable":return LL(Q,$[1]);case"disable":return wL(Q,$[1]);case"refresh":return bL(Q);case"stats":return AL(Q);default:return _$().addAssistantMessage(`未知子命令: ${Y}
2684
- 使用 /plugins 查看帮助`),{success:!1,error:`Unknown subcommand: ${Y}`}}}};_q=zL});var jL,Lq;var wq=A(()=>{Y2();k$();jL={name:"skills",description:"查看所有可用的 Skills",fullDescription:"显示所有已发现的 Skills 及其详细信息,包括名称、描述、来源和允许的工具。",usage:"/skills",category:"system",examples:["/skills"],handler:async($,Z)=>{try{return await R0().refresh(),{success:!0,message:"show_skills_manager",data:{action:"show_skills_manager"}}}catch(Y){let Q=`获取 Skills 失败: ${Y instanceof Error?Y.message:"未知错误"}`;return _$().addAssistantMessage(Q),{success:!1,error:Q}}}},Lq=jL});function c9($){if($<1000)return`${$}ms`;let Z=Math.floor($/1000);if(Z<60)return`${Z}s`;let Y=Math.floor(Z/60);if(Y<60)return`${Y}m ${Z%60}s`;return`${Math.floor(Y/60)}h ${Y%60}m`}function Nq($){switch($){case"running":return"⏳";case"completed":case"exited":return"✅";case"failed":case"error":return"❌";case"killed":case"cancelled":return"✂️";default:return"❓"}}function bq($,Z){if($.length<=Z)return $;return $.slice(0,Z-3)+"..."}async function IL($,Z){let Y=d$(Z),Q=$[0],X=P0.getInstance(),J=Q1.getInstance();if(Q==="clean"){let F=J.cleanupExpiredSessions(0);return Y.sendMessage(`\uD83E\uDDF9 已清理 ${F} 个已完成的 Agent 会话`),{success:!0,message:`Cleaned ${F} agent sessions`}}let G=[`\uD83D\uDCCB **后台任务列表**
2684
+ 使用 /plugins 查看帮助`),{success:!1,error:`Unknown subcommand: ${Y}`}}}};_q=zL});var jL,Lq;var wq=A(()=>{Y4();k$();jL={name:"skills",description:"查看所有可用的 Skills",fullDescription:"显示所有已发现的 Skills 及其详细信息,包括名称、描述、来源和允许的工具。",usage:"/skills",category:"system",examples:["/skills"],handler:async($,Z)=>{try{return await R0().refresh(),{success:!0,message:"show_skills_manager",data:{action:"show_skills_manager"}}}catch(Y){let Q=`获取 Skills 失败: ${Y instanceof Error?Y.message:"未知错误"}`;return _$().addAssistantMessage(Q),{success:!1,error:Q}}}},Lq=jL});function c9($){if($<1000)return`${$}ms`;let Z=Math.floor($/1000);if(Z<60)return`${Z}s`;let Y=Math.floor(Z/60);if(Y<60)return`${Y}m ${Z%60}s`;return`${Math.floor(Y/60)}h ${Y%60}m`}function Nq($){switch($){case"running":return"⏳";case"completed":case"exited":return"✅";case"failed":case"error":return"❌";case"killed":case"cancelled":return"✂️";default:return"❓"}}function bq($,Z){if($.length<=Z)return $;return $.slice(0,Z-3)+"..."}async function IL($,Z){let Y=d$(Z),Q=$[0],X=P0.getInstance(),J=Q1.getInstance();if(Q==="clean"){let F=J.cleanupExpiredSessions(0);return Y.sendMessage(`\uD83E\uDDF9 已清理 ${F} 个已完成的 Agent 会话`),{success:!0,message:`Cleaned ${F} agent sessions`}}let G=[`\uD83D\uDCCB **后台任务列表**
2685
2685
  `],K=X.processes,q=Array.from(K?.values()||[]);if(q.length>0){G.push(`### \uD83D\uDC1A Shells
2686
2686
  `),G.push("| ID | 状态 | 命令 | PID | 运行时间 |"),G.push("|:---|:-----|:-----|:----|:---------|");for(let F of q){let O=F.endTime?c9(F.endTime-F.startTime):c9(Date.now()-F.startTime),z=Nq(F.status);G.push(`| \`${F.id.slice(0,12)}...\` | ${z} ${F.status} | \`${bq(F.command,30)}\` | ${F.pid||"-"} | ${O} |`)}G.push("")}let W=J.listAll();if(W.length>0){G.push(`### \uD83E\uDD16 Agents
2687
2687
  `),G.push("| ID | 状态 | 类型 | 描述 | 运行时间 |"),G.push("|:---|:-----|:-----|:-----|:---------|");for(let F of W){let O=F.completedAt?c9(F.completedAt-F.createdAt):c9(Date.now()-F.createdAt),z=Nq(F.status);G.push(`| \`${F.id.slice(0,12)}...\` | ${z} ${F.status} | ${F.subagentType} | ${bq(F.description,25)} | ${O} |`)}G.push("")}let U=q.filter((F)=>F.status==="running").length,H=J.getRunningCount();if(q.length===0&&W.length===0)G.push(`*暂无后台任务*
2688
2688
  `);else G.push(`**统计**: ${q.length} shells (${U} 运行中), ${W.length} agents (${H} 运行中)`);return G.push(`
2689
2689
  ---`),G.push("\uD83D\uDCA1 **命令**:"),G.push("- `/tasks` - 列出所有后台任务"),G.push("- `/tasks clean` - 清理已完成的 Agent 会话"),Y.sendMessage(G.join(`
2690
- `)),{success:!0,message:`Listed ${q.length} shells and ${W.length} agents`}}var yL,Aq;var Rq=A(()=>{I9();s4();T1();yL={name:"tasks",description:"列出所有后台任务(shells 和 agents)",fullDescription:`查看和管理后台运行的任务。
2690
+ `)),{success:!0,message:`Listed ${q.length} shells and ${W.length} agents`}}var yL,Aq;var Rq=A(()=>{I9();s2();T1();yL={name:"tasks",description:"列出所有后台任务(shells 和 agents)",fullDescription:`查看和管理后台运行的任务。
2691
2691
 
2692
2692
  **功能**:
2693
2693
  - 列出所有后台 shell 进程
@@ -2696,48 +2696,48 @@ ${Y}
2696
2696
 
2697
2697
  **使用示例**:
2698
2698
  - \`/tasks\` - 显示所有后台任务
2699
- - \`/tasks clean\` - 清理已完成的 agent 会话`,usage:"/tasks [clean]",category:"system",examples:["/tasks","/tasks clean"],handler:IL},Aq=yL});async function vL($,Z){return{success:!0,message:"show_theme_selector",data:{action:"show_theme_selector"}}}var EL,Vq;var Dq=A(()=>{EL={name:"theme",description:"打开交互式主题选择器",aliases:["themes","style"],usage:"/theme",examples:["/theme"],category:"ui",handler:vL},Vq=EL});import PL from"fuse.js";function H3($){return $.trim().startsWith("/")}function TL($){let Z=$.trim();if(!Z.startsWith("/"))throw Error("不是有效的 slash command");let Y=Z.slice(1).split(/\s+/),Q=Y[0]||"",X=Y.slice(1);return{command:Q,args:X}}function CL($){if(A8[$])return A8[$];for(let Z of Object.values(A8))if(Z.aliases?.includes($))return Z;return}function Mq($){let Z=$.argumentHint?`/${$.name} ${$.argumentHint}`:`/${$.name}`;return{name:$.name,description:$.description,fullDescription:`[Skill] ${$.description}${$.whenToUse?`
2699
+ - \`/tasks clean\` - 清理已完成的 agent 会话`,usage:"/tasks [clean]",category:"system",examples:["/tasks","/tasks clean"],handler:IL},Aq=yL});async function vL($,Z){return{success:!0,message:"show_theme_selector",data:{action:"show_theme_selector"}}}var EL,Vq;var Dq=A(()=>{EL={name:"theme",description:"打开交互式主题选择器",aliases:["themes","style"],usage:"/theme",examples:["/theme"],category:"ui",handler:vL},Vq=EL});import PL from"fuse.js";function H8($){return $.trim().startsWith("/")}function TL($){let Z=$.trim();if(!Z.startsWith("/"))throw Error("不是有效的 slash command");let Y=Z.slice(1).split(/\s+/),Q=Y[0]||"",X=Y.slice(1);return{command:Q,args:X}}function CL($){if(A3[$])return A3[$];for(let Z of Object.values(A3))if(Z.aliases?.includes($))return Z;return}function Mq($){let Z=$.argumentHint?`/${$.name} ${$.argumentHint}`:`/${$.name}`;return{name:$.name,description:$.description,fullDescription:`[Skill] ${$.description}${$.whenToUse?`
2700
2700
 
2701
- **When to use:** ${$.whenToUse}`:""}`,usage:Z,category:"skill",examples:[Z],handler:async(Y,Q)=>{return{success:!0,message:`Invoking skill: ${$.name}`,data:{action:"invoke_skill",skillName:$.name,skillArgs:Y.join(" ")}}}}}function SL($){return R0().getUserInvocableSkills().find((Q)=>Q.name===$)}async function kL(){await Y4()}async function jq($){return await B0.getInstance().initialize($)}async function F3($,Z){try{let{command:Y,args:Q}=TL($),X=CL(Y);if(X)return await X.handler(Q,Z);let J=B0.getInstance();if(J.hasCommand(Y)){let W=J.getCommand(Y);if(W){let U=Z.workspaceRoot||process.cwd(),H=await J.executeCommand(Y,{args:Q,workspaceRoot:U,signal:Z.signal});if(H)return{success:!0,message:`执行自定义命令: /${Y}`,data:{action:"invoke_custom_command",commandName:Y,processedContent:H,config:W.config}}}}let K=a0().findCommand(Y);if(K){let W=Z.workspaceRoot||process.cwd(),U=await J.executePluginCommand(K.namespacedName,{args:Q,workspaceRoot:W,signal:Z.signal});if(U)return{success:!0,message:`执行插件命令: /${K.namespacedName}`,data:{action:"invoke_plugin_command",commandName:K.namespacedName,pluginName:K.pluginName,processedContent:U,config:K.config}}}await kL();let q=SL(Y);if(q)return await Mq(q).handler(Q,Z);return{success:!1,error:`未知命令: /${Y}
2702
- 使用 /help 查看可用命令`}}catch(Y){return{success:!1,error:`命令执行失败: ${Y instanceof Error?Y.message:"未知错误"}`}}}function Iq(){let $=Object.values(A8),Y=B0.getInstance().getAllCommands().map((K)=>({name:K.name,description:K.config.description||K.content.slice(0,50),usage:K.config.argumentHint?`/${K.name} ${K.config.argumentHint}`:`/${K.name}`,category:"custom",handler:async()=>({success:!0})})),X=a0().getAllCommands().map((K)=>({name:K.namespacedName,description:K.config.description||K.content.slice(0,50),usage:K.config.argumentHint?`/${K.namespacedName} ${K.config.argumentHint}`:`/${K.namespacedName}`,category:"plugin",handler:async()=>({success:!0})})),G=R0().getUserInvocableSkills().map(Mq);return[...$,...Y,...X,...G]}function yq($){let Z=($.startsWith("/")?$.slice(1):$).trim(),Y=Object.values(A8).map((O)=>({name:O.name,description:O.description,aliases:O.aliases||[],label:void 0,argumentHint:void 0,isCustom:!1,isSkill:!1,isPlugin:!1})),Q=B0.getInstance(),X=Q.getAllCommands().map((O)=>({name:O.name,description:O.config.description||O.content.slice(0,50),aliases:[],label:Q.getCommandLabel(O),argumentHint:O.config.argumentHint,isCustom:!0,isSkill:!1,isPlugin:!1})),G=a0().getAllCommands().map((O)=>({name:O.namespacedName,description:O.config.description||O.content.slice(0,50),aliases:[O.originalName],label:`(plugin: ${O.pluginName})`,argumentHint:O.config.argumentHint,isCustom:!1,isSkill:!1,isPlugin:!0})),q=R0().getUserInvocableSkills().map((O)=>({name:O.name,description:O.description,aliases:[],label:"(skill)",argumentHint:O.argumentHint,isCustom:!1,isSkill:!0,isPlugin:!1})),W=[...Y,...X,...G,...q];if(!Z)return W.map((O)=>({command:`/${O.name}`,description:O.label?`${O.description} ${O.label}`:O.description,argumentHint:O.argumentHint,matchScore:50}));return new PL(W,{keys:[{name:"name",weight:3},{name:"aliases",weight:2.5},{name:"description",weight:0.5}],threshold:0.4,includeScore:!0,ignoreLocation:!0,minMatchCharLength:1}).search(Z).map((O)=>{let z=O.score??1,_=Math.round((1-z)*100),B=O.item;return{command:`/${B.name}`,description:B.label?`${B.description} ${B.label}`:B.description,argumentHint:B.argumentHint,matchScore:_}}).filter((O)=>(O.matchScore||0)>=40)}var A8;var O3=A(()=>{q3();Y2();xK();j9();aK();nK();Qq();qq();Uq();Fq();zq();UZ();Bq();wq();Rq();Dq();A8={...hK,init:Kq,theme:Vq,permissions:x9,model:Oq,git:iK,ide:Yq,skills:Lq,hooks:rK,login:Wq,logout:Hq,tasks:Aq,plugins:_q}});import{nanoid as JA}from"nanoid";class UY{id;cwd;connection;clientCapabilities;agent=null;pendingPrompt=null;messages=[];mode="default";sessionApprovals=new Set;constructor($,Z,Y,Q){this.id=$;this.cwd=Z;this.connection=Y;this.clientCapabilities=Q}async initialize(){Y0.debug(`[AcpSession ${this.id}] Initializing...`),z$.initializeSession(this.connection,this.id,this.clientCapabilities,this.cwd),Y0.debug(`[AcpSession ${this.id}] ACP service context initialized`),this.agent=await O0.create({}),Y0.debug(`[AcpSession ${this.id}] Agent created successfully`)}sendAvailableCommandsDelayed(){Y0.debug(`[AcpSession ${this.id}] Scheduling available commands update (500ms delay)`),setTimeout(()=>{this.sendAvailableCommands()},500)}async handleSlashCommand($,Z){try{Y0.debug(`[AcpSession ${this.id}] Executing slash command: ${$}`);let Y={cwd:this.cwd,signal:Z,acp:{sendMessage:(J)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:J}})},sendToolStart:(J,G,K)=>{let q=`tool_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,W=this.mapToolKind(K);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:q,status:"in_progress",title:`${J}`,content:[{type:"content",content:{type:"text",text:JSON.stringify(G,null,2)}}],kind:W})},sendToolResult:(J,G)=>{if(G.summary)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:G.summary}})}}},Q=await F3($,Y),X=Q.content||Q.message;if(X)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:X}});if(Q.error)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`❌ ${Q.error}`}});return{stopReason:Q.success?"end_turn":"cancelled"}}catch(Y){return Y0.error(`[AcpSession ${this.id}] Slash command error:`,Y),this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`❌ 命令执行失败: ${Y instanceof Error?Y.message:"未知错误"}`}}),{stopReason:"cancelled"}}}async sendAvailableCommands(){try{let $=Iq(),Z=["model","permissions","theme","config","exit","ide"],Q=$.filter((X)=>!Z.includes(X.name)).map((X)=>{let J;if(X.usage){let G=X.usage.replace(/^\/\w+\s*/,"").trim();if(G)J=G}if(X.aliases?.length){let G=`Aliases: ${X.aliases.join(", ")}`;J=J?`${J} | ${G}`:G}return{name:X.name,description:X.description,input:J?{hint:J}:void 0}});Y0.info(`[AcpSession ${this.id}] Sending available commands: ${JSON.stringify(Q.map((X)=>X.name))}`),this.sendUpdate({sessionUpdate:"available_commands_update",availableCommands:Q}),Y0.info(`[AcpSession ${this.id}] Sent ${Q.length} available commands`)}catch($){Y0.error(`[AcpSession ${this.id}] Failed to send available commands:`,$)}}async prompt($){z$.setCurrentSession(this.id),this.pendingPrompt?.abort();let Z=new AbortController;if(this.pendingPrompt=Z,!this.agent)throw Error("Session not initialized");try{let Y=this.resolvePrompt($.prompt);if(Y0.debug(`[AcpSession ${this.id}] Received prompt: ${Y.slice(0,100)}...`),H3(Y))return await this.handleSlashCommand(Y,Z.signal);let Q={sessionId:this.id,userId:"acp-user",workspaceRoot:this.cwd,messages:[...this.messages],signal:Z.signal,permissionMode:this.mapModeToPermissionMode(),confirmationHandler:{requestConfirmation:async(G)=>{return this.requestPermission(G)}}},X={signal:Z.signal,onContent:(G)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:G}})},onThinking:(G)=>{this.sendUpdate({sessionUpdate:"agent_thought_chunk",content:{type:"text",text:G}})},onToolStart:(G,K)=>{let q="function"in G?G.function.name:G.type,W=this.mapToolKind(K);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:G.id,status:"in_progress",title:`Executing ${q}`,content:[],kind:W})},onToolResult:async(G,K)=>{let q=[],W=K.metadata;if(W?.kind==="edit"&&typeof W.file_path==="string"&&typeof W.oldContent==="string"&&(typeof W.newContent==="string"||W.newContent===void 0))q.push({type:"diff",path:W.file_path,oldText:W.oldContent,newText:W.newContent??null});else if(K.displayContent){let F=typeof K.displayContent==="string"?K.displayContent:JSON.stringify(K.displayContent);q.push({type:"content",content:{type:"text",text:F}})}let U="function"in G?G.function.name:G.type,H=K.success?"completed":"failed";this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:G.id,status:H,content:q})},onTodoUpdate:(G)=>{this.sendPlanUpdate(G)}},J=await this.agent.chat(Y,Q,X);if(J)this.messages.push({role:"user",content:Y}),this.messages.push({role:"assistant",content:J});if(Z.signal.aborted)return{stopReason:"cancelled"};return{stopReason:"end_turn"}}catch(Y){if(Z.signal.aborted||Y instanceof Error&&Y.name==="AbortError")return{stopReason:"cancelled"};throw Y0.error(`[AcpSession ${this.id}] Prompt error:`,Y),Y}finally{if(this.pendingPrompt===Z)this.pendingPrompt=null}}cancel(){if(Y0.info(`[AcpSession ${this.id}] Cancel requested`),this.pendingPrompt)this.pendingPrompt.abort(),this.pendingPrompt=null,Y0.info(`[AcpSession ${this.id}] Cancelled successfully`);else Y0.warn(`[AcpSession ${this.id}] No pending prompt to cancel`)}async setMode($){let Z=["default","auto-edit","yolo","plan"];this.mode=Z.includes($)?$:"default",Y0.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(Y0.info(`[AcpSession ${this.id}] Model set to: ${$}`),this.agent)Y0.warn(`[AcpSession ${this.id}] Runtime model switching not yet implemented`)}async destroy(){if(this.cancel(),this.agent)await this.agent.destroy(),this.agent=null;z$.destroySession(this.id),Y0.debug(`[AcpSession ${this.id}] Destroyed`)}resolvePrompt($){let Z=[];for(let Y of $)if(Y.type==="text")Z.push(Y.text);else if(Y.type==="image")Z.push(`[Image: ${Y.mimeType}]`);else if(Y.type==="resource"){let Q=Y.resource;if("text"in Q)Z.push(`<file path="${Q.uri}">
2701
+ **When to use:** ${$.whenToUse}`:""}`,usage:Z,category:"skill",examples:[Z],handler:async(Y,Q)=>{return{success:!0,message:`Invoking skill: ${$.name}`,data:{action:"invoke_skill",skillName:$.name,skillArgs:Y.join(" ")}}}}}function SL($){return R0().getUserInvocableSkills().find((Q)=>Q.name===$)}async function kL(){await Y2()}async function jq($){return await B0.getInstance().initialize($)}async function F8($,Z){try{let{command:Y,args:Q}=TL($),X=CL(Y);if(X)return await X.handler(Q,Z);let J=B0.getInstance();if(J.hasCommand(Y)){let W=J.getCommand(Y);if(W){let U=Z.workspaceRoot||process.cwd(),H=await J.executeCommand(Y,{args:Q,workspaceRoot:U,signal:Z.signal});if(H)return{success:!0,message:`执行自定义命令: /${Y}`,data:{action:"invoke_custom_command",commandName:Y,processedContent:H,config:W.config}}}}let K=a0().findCommand(Y);if(K){let W=Z.workspaceRoot||process.cwd(),U=await J.executePluginCommand(K.namespacedName,{args:Q,workspaceRoot:W,signal:Z.signal});if(U)return{success:!0,message:`执行插件命令: /${K.namespacedName}`,data:{action:"invoke_plugin_command",commandName:K.namespacedName,pluginName:K.pluginName,processedContent:U,config:K.config}}}await kL();let q=SL(Y);if(q)return await Mq(q).handler(Q,Z);return{success:!1,error:`未知命令: /${Y}
2702
+ 使用 /help 查看可用命令`}}catch(Y){return{success:!1,error:`命令执行失败: ${Y instanceof Error?Y.message:"未知错误"}`}}}function Iq(){let $=Object.values(A3),Y=B0.getInstance().getAllCommands().map((K)=>({name:K.name,description:K.config.description||K.content.slice(0,50),usage:K.config.argumentHint?`/${K.name} ${K.config.argumentHint}`:`/${K.name}`,category:"custom",handler:async()=>({success:!0})})),X=a0().getAllCommands().map((K)=>({name:K.namespacedName,description:K.config.description||K.content.slice(0,50),usage:K.config.argumentHint?`/${K.namespacedName} ${K.config.argumentHint}`:`/${K.namespacedName}`,category:"plugin",handler:async()=>({success:!0})})),G=R0().getUserInvocableSkills().map(Mq);return[...$,...Y,...X,...G]}function yq($){let Z=($.startsWith("/")?$.slice(1):$).trim(),Y=Object.values(A3).map((O)=>({name:O.name,description:O.description,aliases:O.aliases||[],label:void 0,argumentHint:void 0,isCustom:!1,isSkill:!1,isPlugin:!1})),Q=B0.getInstance(),X=Q.getAllCommands().map((O)=>({name:O.name,description:O.config.description||O.content.slice(0,50),aliases:[],label:Q.getCommandLabel(O),argumentHint:O.config.argumentHint,isCustom:!0,isSkill:!1,isPlugin:!1})),G=a0().getAllCommands().map((O)=>({name:O.namespacedName,description:O.config.description||O.content.slice(0,50),aliases:[O.originalName],label:`(plugin: ${O.pluginName})`,argumentHint:O.config.argumentHint,isCustom:!1,isSkill:!1,isPlugin:!0})),q=R0().getUserInvocableSkills().map((O)=>({name:O.name,description:O.description,aliases:[],label:"(skill)",argumentHint:O.argumentHint,isCustom:!1,isSkill:!0,isPlugin:!1})),W=[...Y,...X,...G,...q];if(!Z)return W.map((O)=>({command:`/${O.name}`,description:O.label?`${O.description} ${O.label}`:O.description,argumentHint:O.argumentHint,matchScore:50}));return new PL(W,{keys:[{name:"name",weight:3},{name:"aliases",weight:2.5},{name:"description",weight:0.5}],threshold:0.4,includeScore:!0,ignoreLocation:!0,minMatchCharLength:1}).search(Z).map((O)=>{let z=O.score??1,_=Math.round((1-z)*100),B=O.item;return{command:`/${B.name}`,description:B.label?`${B.description} ${B.label}`:B.description,argumentHint:B.argumentHint,matchScore:_}}).filter((O)=>(O.matchScore||0)>=40)}var A3;var O8=A(()=>{q8();Y4();xK();j9();aK();nK();Qq();qq();Uq();Fq();zq();UZ();Bq();wq();Rq();Dq();A3={...hK,init:Kq,theme:Vq,permissions:x9,model:Oq,git:iK,ide:Yq,skills:Lq,hooks:rK,login:Wq,logout:Hq,tasks:Aq,plugins:_q}});import{nanoid as JA}from"nanoid";class UY{id;cwd;connection;clientCapabilities;agent=null;pendingPrompt=null;messages=[];mode="default";sessionApprovals=new Set;constructor($,Z,Y,Q){this.id=$;this.cwd=Z;this.connection=Y;this.clientCapabilities=Q}async initialize(){Y0.debug(`[AcpSession ${this.id}] Initializing...`),z$.initializeSession(this.connection,this.id,this.clientCapabilities,this.cwd),Y0.debug(`[AcpSession ${this.id}] ACP service context initialized`),this.agent=await O0.create({}),Y0.debug(`[AcpSession ${this.id}] Agent created successfully`)}sendAvailableCommandsDelayed(){Y0.debug(`[AcpSession ${this.id}] Scheduling available commands update (500ms delay)`),setTimeout(()=>{this.sendAvailableCommands()},500)}async handleSlashCommand($,Z){try{Y0.debug(`[AcpSession ${this.id}] Executing slash command: ${$}`);let Y={cwd:this.cwd,signal:Z,acp:{sendMessage:(J)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:J}})},sendToolStart:(J,G,K)=>{let q=`tool_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,W=this.mapToolKind(K);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:q,status:"in_progress",title:`${J}`,content:[{type:"content",content:{type:"text",text:JSON.stringify(G,null,2)}}],kind:W})},sendToolResult:(J,G)=>{if(G.summary)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:G.summary}})}}},Q=await F8($,Y),X=Q.content||Q.message;if(X)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:X}});if(Q.error)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`❌ ${Q.error}`}});return{stopReason:Q.success?"end_turn":"cancelled"}}catch(Y){return Y0.error(`[AcpSession ${this.id}] Slash command error:`,Y),this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`❌ 命令执行失败: ${Y instanceof Error?Y.message:"未知错误"}`}}),{stopReason:"cancelled"}}}async sendAvailableCommands(){try{let $=Iq(),Z=["model","permissions","theme","config","exit","ide"],Q=$.filter((X)=>!Z.includes(X.name)).map((X)=>{let J;if(X.usage){let G=X.usage.replace(/^\/\w+\s*/,"").trim();if(G)J=G}if(X.aliases?.length){let G=`Aliases: ${X.aliases.join(", ")}`;J=J?`${J} | ${G}`:G}return{name:X.name,description:X.description,input:J?{hint:J}:void 0}});Y0.info(`[AcpSession ${this.id}] Sending available commands: ${JSON.stringify(Q.map((X)=>X.name))}`),this.sendUpdate({sessionUpdate:"available_commands_update",availableCommands:Q}),Y0.info(`[AcpSession ${this.id}] Sent ${Q.length} available commands`)}catch($){Y0.error(`[AcpSession ${this.id}] Failed to send available commands:`,$)}}async prompt($){z$.setCurrentSession(this.id),this.pendingPrompt?.abort();let Z=new AbortController;if(this.pendingPrompt=Z,!this.agent)throw Error("Session not initialized");try{let Y=this.resolvePrompt($.prompt);if(Y0.debug(`[AcpSession ${this.id}] Received prompt: ${Y.slice(0,100)}...`),H8(Y))return await this.handleSlashCommand(Y,Z.signal);let Q={sessionId:this.id,userId:"acp-user",workspaceRoot:this.cwd,messages:[...this.messages],signal:Z.signal,permissionMode:this.mapModeToPermissionMode(),confirmationHandler:{requestConfirmation:async(G)=>{return this.requestPermission(G)}}},X={signal:Z.signal,onContent:(G)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:G}})},onThinking:(G)=>{this.sendUpdate({sessionUpdate:"agent_thought_chunk",content:{type:"text",text:G}})},onToolStart:(G,K)=>{let q="function"in G?G.function.name:G.type,W=this.mapToolKind(K);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:G.id,status:"in_progress",title:`Executing ${q}`,content:[],kind:W})},onToolResult:async(G,K)=>{let q=[],W=K.metadata;if(W?.kind==="edit"&&typeof W.file_path==="string"&&typeof W.oldContent==="string"&&(typeof W.newContent==="string"||W.newContent===void 0))q.push({type:"diff",path:W.file_path,oldText:W.oldContent,newText:W.newContent??null});else if(K.displayContent){let F=typeof K.displayContent==="string"?K.displayContent:JSON.stringify(K.displayContent);q.push({type:"content",content:{type:"text",text:F}})}let U="function"in G?G.function.name:G.type,H=K.success?"completed":"failed";this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:G.id,status:H,content:q})},onTodoUpdate:(G)=>{this.sendPlanUpdate(G)}},J=await this.agent.chat(Y,Q,X);if(J)this.messages.push({role:"user",content:Y}),this.messages.push({role:"assistant",content:J});if(Z.signal.aborted)return{stopReason:"cancelled"};return{stopReason:"end_turn"}}catch(Y){if(Z.signal.aborted||Y instanceof Error&&Y.name==="AbortError")return{stopReason:"cancelled"};throw Y0.error(`[AcpSession ${this.id}] Prompt error:`,Y),Y}finally{if(this.pendingPrompt===Z)this.pendingPrompt=null}}cancel(){if(Y0.info(`[AcpSession ${this.id}] Cancel requested`),this.pendingPrompt)this.pendingPrompt.abort(),this.pendingPrompt=null,Y0.info(`[AcpSession ${this.id}] Cancelled successfully`);else Y0.warn(`[AcpSession ${this.id}] No pending prompt to cancel`)}async setMode($){let Z=["default","auto-edit","yolo","plan"];this.mode=Z.includes($)?$:"default",Y0.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(Y0.info(`[AcpSession ${this.id}] Model set to: ${$}`),this.agent)Y0.warn(`[AcpSession ${this.id}] Runtime model switching not yet implemented`)}async destroy(){if(this.cancel(),this.agent)await this.agent.destroy(),this.agent=null;z$.destroySession(this.id),Y0.debug(`[AcpSession ${this.id}] Destroyed`)}resolvePrompt($){let Z=[];for(let Y of $)if(Y.type==="text")Z.push(Y.text);else if(Y.type==="image")Z.push(`[Image: ${Y.mimeType}]`);else if(Y.type==="resource"){let Q=Y.resource;if("text"in Q)Z.push(`<file path="${Q.uri}">
2703
2703
  ${Q.text}
2704
2704
  </file>`)}else if(Y.type==="resource_link")Z.push(`[Resource: ${Y.uri}]`);return Z.join(`
2705
2705
  `)}sendUpdate($){let Z={sessionId:this.id,update:$};this.connection.sessionUpdate(Z).catch((Y)=>{Y0.warn(`[AcpSession ${this.id}] Failed to send update:`,Y)})}sendPlanUpdate($){let Z=$.map((Y)=>({content:Y.content,priority:Y.priority,status:Y.status}));Y0.debug(`[AcpSession ${this.id}] Sending plan update with ${Z.length} entries`),this.sendUpdate({sessionUpdate:"plan",entries:Z})}async requestPermission($){let Z=$.kind?.toLowerCase()||"execute";if(this.shouldAutoApprove(Z))return Y0.debug(`[AcpSession ${this.id}] Auto-approving ${Z} in mode: ${this.mode}`),{approved:!0};if(this.mode==="plan"&&(Z==="write"||Z==="execute"))return Y0.debug(`[AcpSession ${this.id}] Rejecting ${Z} in plan mode`),{approved:!1,reason:"Write and execute operations are not allowed in Plan mode"};let Y=`${Z}:${$.title||"unknown"}`;if(this.sessionApprovals.has(Y))return Y0.debug(`[AcpSession ${this.id}] Using cached approval for: ${Y}`),{approved:!0};try{let Q=JA(),X=[];if($.message)X.push({type:"content",content:{type:"text",text:$.message}});if($.risks&&$.risks.length>0)X.push({type:"content",content:{type:"text",text:`Risks:
2706
2706
  - ${$.risks.join(`
2707
- - `)}`}});let J=this.mapToolKind(Z),G={sessionId:this.id,options:[{optionId:"allow_once",name:"Allow once",kind:"allow_once"},{optionId:"allow_always",name:"Always allow",kind:"allow_always"},{optionId:"reject_once",name:"Deny once",kind:"reject_once"},{optionId:"reject_always",name:"Always deny",kind:"reject_always"}],toolCall:{toolCallId:Q,status:"pending",title:$.title||"Permission Required",content:X,kind:J}},q=(await this.connection.requestPermission(G)).outcome;if(q.outcome==="cancelled")return{approved:!1,reason:"User cancelled the permission request"};let W=q.optionId,U=W==="allow_once"||W==="allow_always";if(W==="allow_always")this.sessionApprovals.add(Y),Y0.debug(`[AcpSession ${this.id}] Cached approval for: ${Y}`);return{approved:U,reason:U?void 0:"User denied the operation"}}catch(Q){return Y0.warn(`[AcpSession ${this.id}] Permission request failed:`,Q),{approved:!1,reason:"Permission request failed"}}}mapToolKind($){return{readonly:"read",write:"edit",execute:"execute",read:"read",edit:"edit",delete:"delete",move:"move",search:"search",think:"think",fetch:"fetch"}[$||""]||"other"}}var Y0;var ZH=A(()=>{X2();U0();O$();O3();r4();Y0=l("Agent")});import{PROTOCOL_VERSION as GA}from"@agentclientprotocol/sdk";import{nanoid as KA}from"nanoid";class HY{connection;sessions=new Map;clientCapabilities;constructor($){this.connection=$}async initialize($){return n1.info("[BladeAgent] Initializing ACP connection"),n1.debug(`[BladeAgent] Client capabilities: ${JSON.stringify($.clientCapabilities)}`),this.clientCapabilities=$.clientCapabilities,{protocolVersion:GA,agentCapabilities:{loadSession:!1,promptCapabilities:{image:!0,audio:!1,embeddedContext:!0},mcpCapabilities:{http:!0,sse:!0}}}}async authenticate($){return}async newSession($){let Z=KA();n1.info(`[BladeAgent] Creating new session: ${Z}`),n1.debug(`[BladeAgent] Session cwd: ${$.cwd||process.cwd()}`);let Y=new UY(Z,$.cwd||process.cwd(),this.connection,this.clientCapabilities);await Y.initialize(),this.sessions.set(Z,Y),n1.info(`[BladeAgent] Session ${Z} created, scheduling available commands update`),Y.sendAvailableCommandsDelayed();let Q=H0(),X=Q?.models||[],J=Q?.currentModelId||X[0]?.id,G=X.map((q)=>({modelId:q.id,name:q.name||q.id,description:q.provider?`Provider: ${q.provider}`:void 0}));return{sessionId:Z,modes:{availableModes:[{id:"default",name:"Default",description:"Ask for confirmation before all file edits and commands"},{id:"auto-edit",name:"Auto Edit",description:"Auto-approve file edits, ask for shell commands"},{id:"yolo",name:"Full Auto",description:"Auto-approve everything without confirmation"},{id:"plan",name:"Plan Only",description:"Read-only mode, no file changes or commands"}],currentModeId:"default"},models:G.length>0?{availableModels:G,currentModelId:J}:void 0}}async prompt($){let Z=this.sessions.get($.sessionId);if(!Z)throw Error(`Session not found: ${$.sessionId}`);return Z.prompt($)}async cancel($){n1.info(`[BladeAgent] Cancel notification received for session: ${$.sessionId}`);let Z=this.sessions.get($.sessionId);if(Z)n1.info("[BladeAgent] Found session, calling session.cancel()"),Z.cancel();else n1.warn(`[BladeAgent] Session not found for cancel: ${$.sessionId}`)}async setSessionMode($){n1.info(`[BladeAgent] Setting session mode: ${$.modeId}`);let Z=this.sessions.get($.sessionId);if(Z)await Z.setMode($.modeId);return{}}async unstable_setSessionModel($){n1.info(`[BladeAgent] Setting session model: ${$.modelId}`);let Z=this.sessions.get($.sessionId);if(Z)await Z.setModel($.modelId);return{}}async destroy(){for(let $ of this.sessions.values())await $.destroy();this.sessions.clear()}}var n1;var YH=A(()=>{O$();k$();ZH();n1=l("Agent")});var QH={};FH(QH,{runAcpIntegration:()=>UA});import{Readable as qA,Writable as WA}from"node:stream";import*as I6 from"@agentclientprotocol/sdk";async function UA(){let $=WA.toWeb(process.stdout),Z=qA.toWeb(process.stdin),Y=I6.ndJsonStream($,Z);await new I6.AgentSideConnection((X)=>new HY(X),Y).closed}var XH=A(()=>{YH()});import{render as HA}from"ink";import FA from"react";import OA from"yargs";import{hideBin as GH}from"yargs/helpers";P3();var bY={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:"},settings:{type:"string",describe:"Path to a settings JSON file or JSON string",group:"Configuration:"},"add-dir":{alias:["addDir"],type:"array",string:!0,describe:"Additional directories to allow tool access to",group:"Security Options:"},ide:{type:"boolean",describe:"Automatically connect to IDE on startup",group:"Integration:"},acp:{type:"boolean",describe:"Run in ACP (Agent Client Protocol) mode for IDE integration",group:"Integration:"},"strict-mcp-config":{alias:["strictMcpConfig"],type:"boolean",describe:"Only use MCP servers from --mcp-config",group:"MCP Options:"},"session-id":{alias:["sessionId"],type:"string",describe:"Use a specific session ID for the conversation",group:"Session Options:"},agents:{type:"string",describe:"JSON object defining custom agents",group:"AI Options:"},"setting-sources":{alias:["settingSources"],type:"string",describe:"Comma-separated list of setting sources to load",group:"Configuration:"},"plugin-dir":{alias:["pluginDir"],type:"array",string:!0,describe:"Load plugins from specified directories",group:"Plugin Options:"}},a2={scriptName:"blade",usage:"$0 [command] [options]",description:wY(),version:v4(),locale:"en",showHelpOnFail:!0,demandCommand:!1,recommendCommands:!0,strict:!1};S4();O$();k$();var r6=l("General"),XQ=($)=>{if($.yolo){if($.permissionMode&&$.permissionMode!=="yolo")throw Error("Cannot use both --yolo and --permission-mode with different values");$.permissionMode="yolo"}if(Array.isArray($.allowedTools)&&Array.isArray($.disallowedTools)){let Z=$.allowedTools.filter((Y)=>$.disallowedTools.includes(Y));if(Z.length>0)throw Error(`Tools cannot be both allowed and disallowed: ${Z.join(", ")}`)}},JQ=async($)=>{try{let Y=await u0.getInstance().initialize();if(q$().config.actions.setConfig(Y),$.debug)r6.info("[CLI] 配置已加载到 Store")}catch(Z){r6.error("[CLI] ❌ 配置初始化失败",Z instanceof Error?Z.message:Z),console.error(`
2707
+ - `)}`}});let J=this.mapToolKind(Z),G={sessionId:this.id,options:[{optionId:"allow_once",name:"Allow once",kind:"allow_once"},{optionId:"allow_always",name:"Always allow",kind:"allow_always"},{optionId:"reject_once",name:"Deny once",kind:"reject_once"},{optionId:"reject_always",name:"Always deny",kind:"reject_always"}],toolCall:{toolCallId:Q,status:"pending",title:$.title||"Permission Required",content:X,kind:J}},q=(await this.connection.requestPermission(G)).outcome;if(q.outcome==="cancelled")return{approved:!1,reason:"User cancelled the permission request"};let W=q.optionId,U=W==="allow_once"||W==="allow_always";if(W==="allow_always")this.sessionApprovals.add(Y),Y0.debug(`[AcpSession ${this.id}] Cached approval for: ${Y}`);return{approved:U,reason:U?void 0:"User denied the operation"}}catch(Q){return Y0.warn(`[AcpSession ${this.id}] Permission request failed:`,Q),{approved:!1,reason:"Permission request failed"}}}mapToolKind($){return{readonly:"read",write:"edit",execute:"execute",read:"read",edit:"edit",delete:"delete",move:"move",search:"search",think:"think",fetch:"fetch"}[$||""]||"other"}}var Y0;var ZH=A(()=>{X4();U0();O$();O8();r2();Y0=l("Agent")});import{PROTOCOL_VERSION as GA}from"@agentclientprotocol/sdk";import{nanoid as KA}from"nanoid";class HY{connection;sessions=new Map;clientCapabilities;constructor($){this.connection=$}async initialize($){return n1.info("[BladeAgent] Initializing ACP connection"),n1.debug(`[BladeAgent] Client capabilities: ${JSON.stringify($.clientCapabilities)}`),this.clientCapabilities=$.clientCapabilities,{protocolVersion:GA,agentCapabilities:{loadSession:!1,promptCapabilities:{image:!0,audio:!1,embeddedContext:!0},mcpCapabilities:{http:!0,sse:!0}}}}async authenticate($){return}async newSession($){let Z=KA();n1.info(`[BladeAgent] Creating new session: ${Z}`),n1.debug(`[BladeAgent] Session cwd: ${$.cwd||process.cwd()}`);let Y=new UY(Z,$.cwd||process.cwd(),this.connection,this.clientCapabilities);await Y.initialize(),this.sessions.set(Z,Y),n1.info(`[BladeAgent] Session ${Z} created, scheduling available commands update`),Y.sendAvailableCommandsDelayed();let Q=H0(),X=Q?.models||[],J=Q?.currentModelId||X[0]?.id,G=X.map((q)=>({modelId:q.id,name:q.name||q.id,description:q.provider?`Provider: ${q.provider}`:void 0}));return{sessionId:Z,modes:{availableModes:[{id:"default",name:"Default",description:"Ask for confirmation before all file edits and commands"},{id:"auto-edit",name:"Auto Edit",description:"Auto-approve file edits, ask for shell commands"},{id:"yolo",name:"Full Auto",description:"Auto-approve everything without confirmation"},{id:"plan",name:"Plan Only",description:"Read-only mode, no file changes or commands"}],currentModeId:"default"},models:G.length>0?{availableModels:G,currentModelId:J}:void 0}}async prompt($){let Z=this.sessions.get($.sessionId);if(!Z)throw Error(`Session not found: ${$.sessionId}`);return Z.prompt($)}async cancel($){n1.info(`[BladeAgent] Cancel notification received for session: ${$.sessionId}`);let Z=this.sessions.get($.sessionId);if(Z)n1.info("[BladeAgent] Found session, calling session.cancel()"),Z.cancel();else n1.warn(`[BladeAgent] Session not found for cancel: ${$.sessionId}`)}async setSessionMode($){n1.info(`[BladeAgent] Setting session mode: ${$.modeId}`);let Z=this.sessions.get($.sessionId);if(Z)await Z.setMode($.modeId);return{}}async unstable_setSessionModel($){n1.info(`[BladeAgent] Setting session model: ${$.modelId}`);let Z=this.sessions.get($.sessionId);if(Z)await Z.setModel($.modelId);return{}}async destroy(){for(let $ of this.sessions.values())await $.destroy();this.sessions.clear()}}var n1;var YH=A(()=>{O$();k$();ZH();n1=l("Agent")});var QH={};FH(QH,{runAcpIntegration:()=>UA});import{Readable as qA,Writable as WA}from"node:stream";import*as I6 from"@agentclientprotocol/sdk";async function UA(){let $=WA.toWeb(process.stdout),Z=qA.toWeb(process.stdin),Y=I6.ndJsonStream($,Z);await new I6.AgentSideConnection((X)=>new HY(X),Y).closed}var XH=A(()=>{YH()});import{render as HA}from"ink";import FA from"react";import OA from"yargs";import{hideBin as GH}from"yargs/helpers";P8();var bY={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:"},settings:{type:"string",describe:"Path to a settings JSON file or JSON string",group:"Configuration:"},"add-dir":{alias:["addDir"],type:"array",string:!0,describe:"Additional directories to allow tool access to",group:"Security Options:"},ide:{type:"boolean",describe:"Automatically connect to IDE on startup",group:"Integration:"},acp:{type:"boolean",describe:"Run in ACP (Agent Client Protocol) mode for IDE integration",group:"Integration:"},"strict-mcp-config":{alias:["strictMcpConfig"],type:"boolean",describe:"Only use MCP servers from --mcp-config",group:"MCP Options:"},"session-id":{alias:["sessionId"],type:"string",describe:"Use a specific session ID for the conversation",group:"Session Options:"},agents:{type:"string",describe:"JSON object defining custom agents",group:"AI Options:"},"setting-sources":{alias:["settingSources"],type:"string",describe:"Comma-separated list of setting sources to load",group:"Configuration:"},"plugin-dir":{alias:["pluginDir"],type:"array",string:!0,describe:"Load plugins from specified directories",group:"Plugin Options:"}},a4={scriptName:"blade",usage:"$0 [command] [options]",description:wY(),version:v2(),locale:"en",showHelpOnFail:!0,demandCommand:!1,recommendCommands:!0,strict:!1};S2();O$();k$();var r6=l("General"),XQ=($)=>{if($.yolo){if($.permissionMode&&$.permissionMode!=="yolo")throw Error("Cannot use both --yolo and --permission-mode with different values");$.permissionMode="yolo"}if(Array.isArray($.allowedTools)&&Array.isArray($.disallowedTools)){let Z=$.allowedTools.filter((Y)=>$.disallowedTools.includes(Y));if(Z.length>0)throw Error(`Tools cannot be both allowed and disallowed: ${Z.join(", ")}`)}},JQ=async($)=>{try{let Y=await u0.getInstance().initialize();if(q$().config.actions.setConfig(Y),$.debug)r6.info("[CLI] 配置已加载到 Store")}catch(Z){r6.error("[CLI] ❌ 配置初始化失败",Z instanceof Error?Z.message:Z),console.error(`
2708
2708
  ❌ 配置初始化失败
2709
2709
  `),console.error("原因:",Z instanceof Error?Z.message:"未知错误"),console.error(`
2710
2710
  请检查:`),console.error(" 1. 配置文件格式是否正确 (~/.blade/config.json)"),console.error(" 2. 是否需要运行 blade 进行首次配置"),console.error(` 3. 配置文件权限是否正确
2711
- `),process.exit(1)}if($.continue&&$.resume)throw Error("Cannot use both --continue and --resume flags simultaneously")},GQ=($)=>{if($.outputFormat&&$.outputFormat!=="text"&&!$.print)throw Error("--output-format can only be used with --print flag");if($.inputFormat==="stream-json"&&$.print)r6.warn("⚠️ Warning: stream-json input format may not work as expected with --print")};S4();var KQ={command:"doctor",describe:"Check the health of your Blade installation",handler:async()=>{console.log(`\uD83D\uDD0D Running Blade health check...
2711
+ `),process.exit(1)}if($.continue&&$.resume)throw Error("Cannot use both --continue and --resume flags simultaneously")},GQ=($)=>{if($.outputFormat&&$.outputFormat!=="text"&&!$.print)throw Error("--output-format can only be used with --print flag");if($.inputFormat==="stream-json"&&$.print)r6.warn("⚠️ Warning: stream-json input format may not work as expected with --print")};S2();var KQ={command:"doctor",describe:"Check the health of your Blade installation",handler:async()=>{console.log(`\uD83D\uDD0D Running Blade health check...
2712
2712
  `);let $=0;try{await u0.getInstance().initialize(),console.log("✅ Configuration: OK")}catch(Q){console.log("❌ Configuration: FAILED"),console.log(` Error: ${Q instanceof Error?Q.message:"未知错误"}`),$++}let Z=process.version;if(parseInt(Z.slice(1).split(".")[0])>=18)console.log(`✅ Node.js version: ${Z}`);else console.log(`⚠️ Node.js version: ${Z} (recommended: v18+)`),$++;try{let Q=await import("fs/promises"),X=process.cwd();await Q.access(X,(await import("fs")).constants.R_OK|(await import("fs")).constants.W_OK),console.log("✅ File system permissions: OK")}catch(Q){console.log("❌ File system permissions: FAILED"),console.log(" Error: Cannot read/write in current directory"),$++}try{await import("ink"),console.log("✅ Dependencies: OK")}catch(Q){console.log("❌ Dependencies: FAILED"),console.log(" Error: Missing required dependencies"),$++}if(console.log(`
2713
- \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 qQ={command:"install [target]",describe:"Install Blade native build. Use [target] to specify version (stable, latest, or specific version)",builder:($)=>{return $.positional("target",{describe:"Version to install",type:"string",default:"stable",choices:["stable","latest"]}).option("force",{type:"boolean",describe:"Force reinstall",default:!1}).example([["$0 install","Install stable version"],["$0 install latest","Install latest version"],["$0 install --force","Force reinstall stable version"]])},handler:async($)=>{console.log(`\uD83D\uDCE6 Installing Blade ${$.target}...`);try{if($.force)console.log("\uD83D\uDD04 Force reinstall enabled");console.log("⬇️ Downloading..."),console.log("\uD83D\uDD27 Installing..."),console.log("✅ Installation completed successfully")}catch(Z){console.error(`❌ Installation failed: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}};e2();x4();k$();import MQ from"os";import d8 from"path";function p4($){return typeof $==="string"?$:void 0}function J7($){if(!Array.isArray($))return;let Z=[];for(let Y of $)if(typeof Y==="string")Z.push(Y);else if(Y!=null)Z.push(String(Y));return Z}function FF(){console.log(`
2713
+ \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 qQ={command:"install [target]",describe:"Install Blade native build. Use [target] to specify version (stable, latest, or specific version)",builder:($)=>{return $.positional("target",{describe:"Version to install",type:"string",default:"stable",choices:["stable","latest"]}).option("force",{type:"boolean",describe:"Force reinstall",default:!1}).example([["$0 install","Install stable version"],["$0 install latest","Install latest version"],["$0 install --force","Force reinstall stable version"]])},handler:async($)=>{console.log(`\uD83D\uDCE6 Installing Blade ${$.target}...`);try{if($.force)console.log("\uD83D\uDD04 Force reinstall enabled");console.log("⬇️ Downloading..."),console.log("\uD83D\uDD27 Installing..."),console.log("✅ Installation completed successfully")}catch(Z){console.error(`❌ Installation failed: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}};e4();x2();k$();import MQ from"os";import d3 from"path";function p2($){return typeof $==="string"?$:void 0}function J7($){if(!Array.isArray($))return;let Z=[];for(let Y of $)if(typeof Y==="string")Z.push(Y);else if(Y!=null)Z.push(String(Y));return Z}function FF(){console.log(`
2714
2714
  blade mcp
2715
2715
  `),console.log(`管理 MCP 服务器
2716
2716
  `),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 字符串添加服务器
2717
2717
  `),console.log("Options:"),console.log(` -h, --help 显示帮助信息 [boolean]
2718
2718
  `),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
2719
2719
  `),console.log(`使用 blade mcp <command> --help 查看各子命令的详细帮助
2720
- `)}function OF($){return $.reduce((Z,Y)=>{let[Q,...X]=Y.split("=");return Z[Q]=X.join("="),Z},{})}function zF($){return $.reduce((Z,Y)=>{let[Q,...X]=Y.split(":");return Z[Q.trim()]=X.join(":").trim(),Z},{})}var _F={command:"add <name> [commandOrUrl] [args...]",describe:"添加 MCP 服务器",builder:($)=>{return $.positional("name",{type:"string",describe:"服务器名称",demandOption:!0}).positional("commandOrUrl",{type:"string",describe:"stdio: 命令 | http/sse: URL"}).positional("args",{type:"string",array:!0,describe:"stdio 命令参数",default:[]}).option("transport",{alias:"t",choices:["stdio","sse","http"],default:"stdio",describe:"传输类型"}).option("env",{alias:"e",type:"array",describe:"环境变量 (KEY=value)"}).option("header",{alias:"H",type:"array",describe:"HTTP 头 (Key: Value)"}).option("timeout",{type:"number",describe:"超时时间(毫秒)"}).option("global",{alias:"g",type:"boolean",default:!1,describe:"存储到全局配置(~/.blade/config.json)"}).example([["$0 mcp add github -- npx -y @modelcontextprotocol/server-github","Add stdio server (recommended)"],["$0 mcp add github npx @modelcontextprotocol/server-github -e GITHUB_TOKEN=xxx","Add stdio server with env"],['$0 mcp add api --transport http http://localhost:3000 -H "Auth: Bearer token"',"Add HTTP server"]])},handler:async($)=>{try{let{name:Z,commandOrUrl:Y,args:Q,transport:X,env:J,header:G,timeout:K}=$,q=$.global===!0,W=p4(Z),U=p4(Y),H=J7(Q)||[],F=J7(J),O=J7(G),z=typeof K==="number"?K:void 0,_=X==="stdio"||X==="sse"||X==="http"?X:"stdio",B=$["--"];if(Array.isArray(B)&&B.length>0)U=String(B[0]),H=B.slice(1).map((N)=>String(N));if(!W||!U)console.error("❌ 缺少必需参数: name 和 commandOrUrl"),console.log(`
2720
+ `)}function OF($){return $.reduce((Z,Y)=>{let[Q,...X]=Y.split("=");return Z[Q]=X.join("="),Z},{})}function zF($){return $.reduce((Z,Y)=>{let[Q,...X]=Y.split(":");return Z[Q.trim()]=X.join(":").trim(),Z},{})}var _F={command:"add <name> [commandOrUrl] [args...]",describe:"添加 MCP 服务器",builder:($)=>{return $.positional("name",{type:"string",describe:"服务器名称",demandOption:!0}).positional("commandOrUrl",{type:"string",describe:"stdio: 命令 | http/sse: URL"}).positional("args",{type:"string",array:!0,describe:"stdio 命令参数",default:[]}).option("transport",{alias:"t",choices:["stdio","sse","http"],default:"stdio",describe:"传输类型"}).option("env",{alias:"e",type:"array",describe:"环境变量 (KEY=value)"}).option("header",{alias:"H",type:"array",describe:"HTTP 头 (Key: Value)"}).option("timeout",{type:"number",describe:"超时时间(毫秒)"}).option("global",{alias:"g",type:"boolean",default:!1,describe:"存储到全局配置(~/.blade/config.json)"}).example([["$0 mcp add github -- npx -y @modelcontextprotocol/server-github","Add stdio server (recommended)"],["$0 mcp add github npx @modelcontextprotocol/server-github -e GITHUB_TOKEN=xxx","Add stdio server with env"],['$0 mcp add api --transport http http://localhost:3000 -H "Auth: Bearer token"',"Add HTTP server"]])},handler:async($)=>{try{let{name:Z,commandOrUrl:Y,args:Q,transport:X,env:J,header:G,timeout:K}=$,q=$.global===!0,W=p2(Z),U=p2(Y),H=J7(Q)||[],F=J7(J),O=J7(G),z=typeof K==="number"?K:void 0,_=X==="stdio"||X==="sse"||X==="http"?X:"stdio",B=$["--"];if(Array.isArray(B)&&B.length>0)U=String(B[0]),H=B.slice(1).map((N)=>String(N));if(!W||!U)console.error("❌ 缺少必需参数: name 和 commandOrUrl"),console.log(`
2721
2721
  \uD83D\uDCA1 用法:`),console.log(" blade mcp add <name> <command> [args...]"),console.log(" blade mcp add <name> -- <command> [args...]"),console.log(`
2722
- 示例:`),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 L={type:_};if(_==="stdio"){if(L.command=U,L.args=H,F)L.env=OF(F)}else if(L.url=U,O)L.headers=zF(O);if(z!==void 0)L.timeout=z;await x$().addMcpServer(W,L,{scope:q?"global":"project"});let w=q?d8.join(MQ.homedir(),".blade","config.json"):d8.join(process.cwd(),".blade","config.json");console.log(`✅ MCP 服务器 "${W}" 已添加`),console.log(` 配置文件: ${w}`)}catch(Z){console.error(`❌ 添加失败: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}},BF={command:"remove <name>",describe:"删除 MCP 服务器",aliases:["rm"],builder:($)=>{return $.positional("name",{type:"string",describe:"服务器名称",demandOption:!0}).option("global",{alias:"g",type:"boolean",default:!1,describe:"从全局配置删除(~/.blade/config.json)"}).example([["$0 mcp remove github","Remove the specified MCP server"]])},handler:async($)=>{try{let Z=W1(),Y=$.global===!0,Q=p4($.name);if(!Q)console.error("❌ 缺少必需参数: name"),process.exit(1);if(!Z[Q])console.error(`❌ 服务器 "${Q}" 不存在`),process.exit(1);await x$().removeMcpServer(Q,{scope:Y?"global":"project"}),console.log(`✅ MCP 服务器 "${Q}" 已删除`)}catch(Z){console.error(`❌ 删除失败: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}},LF={command:"list",describe:"列出所有 MCP 服务器并检查健康状态",aliases:["ls"],handler:async()=>{try{let $=W1();if(console.log(""),Object.keys($).length===0){console.log("暂无配置的 MCP 服务器");return}console.log(`检查 MCP 服务器健康状态...
2723
- `);let Z=b0.getInstance(),Y=Object.entries($).map(async([X,J])=>{try{let G=Z.getServerStatus(X);if(!G)await Z.registerServer(X,J),G=Z.getServerStatus(X);else if(G.status==="disconnected")await Z.connectServer(X);return{name:X,config:J,serverInfo:G}}catch(G){return{name:X,config:J,serverInfo:null,error:G}}}),Q=await Promise.all(Y);for(let{name:X,config:J,serverInfo:G,error:K}of Q){let q=G?.status||"disconnected",W=q==="connected"?"✓":"✗",U=q==="connected"?"Connected":"Failed";if(console.log(`${X}: ${J.type==="stdio"?J.command:J.url} - ${W} ${U}`),K&&q!=="connected")console.log(` 错误: ${K instanceof Error?K.message:String(K)}`)}console.log("");for(let{name:X}of Q)try{await Z.unregisterServer(X)}catch(J){}process.exit(0)}catch($){console.error(`❌ 列表获取失败: ${$ instanceof Error?$.message:"未知错误"}`),process.exit(1)}}},wF={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=W1(),Y=p4($.name);if(!Y)console.error("❌ 缺少必需参数: name"),process.exit(1);let Q=Z[Y];if(!Q)console.error(`❌ 服务器 "${Y}" 不存在`),process.exit(1);console.log(`
2722
+ 示例:`),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 L={type:_};if(_==="stdio"){if(L.command=U,L.args=H,F)L.env=OF(F)}else if(L.url=U,O)L.headers=zF(O);if(z!==void 0)L.timeout=z;await x$().addMcpServer(W,L,{scope:q?"global":"project"});let w=q?d3.join(MQ.homedir(),".blade","config.json"):d3.join(process.cwd(),".blade","config.json");console.log(`✅ MCP 服务器 "${W}" 已添加`),console.log(` 配置文件: ${w}`)}catch(Z){console.error(`❌ 添加失败: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}},BF={command:"remove <name>",describe:"删除 MCP 服务器",aliases:["rm"],builder:($)=>{return $.positional("name",{type:"string",describe:"服务器名称",demandOption:!0}).option("global",{alias:"g",type:"boolean",default:!1,describe:"从全局配置删除(~/.blade/config.json)"}).example([["$0 mcp remove github","Remove the specified MCP server"]])},handler:async($)=>{try{let Z=W1(),Y=$.global===!0,Q=p2($.name);if(!Q)console.error("❌ 缺少必需参数: name"),process.exit(1);if(!Z[Q])console.error(`❌ 服务器 "${Q}" 不存在`),process.exit(1);await x$().removeMcpServer(Q,{scope:Y?"global":"project"}),console.log(`✅ MCP 服务器 "${Q}" 已删除`)}catch(Z){console.error(`❌ 删除失败: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}},LF={command:"list",describe:"列出所有 MCP 服务器并检查健康状态",aliases:["ls"],handler:async()=>{try{let $=W1();if(console.log(""),Object.keys($).length===0){console.log("暂无配置的 MCP 服务器");return}console.log(`检查 MCP 服务器健康状态...
2723
+ `);let Z=b0.getInstance(),Y=Object.entries($).map(async([X,J])=>{try{let G=Z.getServerStatus(X);if(!G)await Z.registerServer(X,J),G=Z.getServerStatus(X);else if(G.status==="disconnected")await Z.connectServer(X);return{name:X,config:J,serverInfo:G}}catch(G){return{name:X,config:J,serverInfo:null,error:G}}}),Q=await Promise.all(Y);for(let{name:X,config:J,serverInfo:G,error:K}of Q){let q=G?.status||"disconnected",W=q==="connected"?"✓":"✗",U=q==="connected"?"Connected":"Failed";if(console.log(`${X}: ${J.type==="stdio"?J.command:J.url} - ${W} ${U}`),K&&q!=="connected")console.log(` 错误: ${K instanceof Error?K.message:String(K)}`)}console.log("");for(let{name:X}of Q)try{await Z.unregisterServer(X)}catch(J){}process.exit(0)}catch($){console.error(`❌ 列表获取失败: ${$ instanceof Error?$.message:"未知错误"}`),process.exit(1)}}},wF={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=W1(),Y=p2($.name);if(!Y)console.error("❌ 缺少必需参数: name"),process.exit(1);let Q=Z[Y];if(!Q)console.error(`❌ 服务器 "${Y}" 不存在`),process.exit(1);console.log(`
2724
2724
  服务器: ${Y}
2725
- `),console.log(JSON.stringify(Q,null,2))}catch(Z){console.error(`❌ 获取失败: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}},NF={command:"add-json <name> <json>",describe:"从 JSON 字符串添加服务器",builder:($)=>{return $.positional("name",{type:"string",describe:"服务器名称",demandOption:!0}).positional("json",{type:"string",describe:"JSON 配置字符串",demandOption:!0}).option("global",{alias:"g",type:"boolean",default:!1,describe:"存储到全局配置(~/.blade/config.json)"}).example([[`$0 mcp add-json my-server '{"type":"stdio","command":"npx","args":["-y","@example/server"]}'`,"Add server from JSON string"]])},handler:async($)=>{try{let Z=p4($.json),Y=p4($.name);if(!Z||!Y)throw Error("缺少必需参数: name 或 json");let Q=JSON.parse(Z),X=$.global===!0;if(!Q.type)throw Error('配置必须包含 "type" 字段');await x$().addMcpServer(Y,Q,{scope:X?"global":"project"});let J=X?d8.join(MQ.homedir(),".blade","config.json"):d8.join(process.cwd(),".blade","config.json");console.log(`✅ MCP 服务器 "${Y}" 已添加`),console.log(` 配置文件: ${J}`)}catch(Z){console.error(`❌ 添加失败: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}},jQ={command:"mcp",describe:"管理 MCP 服务器",builder:($)=>{return $.command(_F).command(BF).command(LF).command(wF).command(NF).demandCommand(0).help(!1).option("help",{alias:"h",type:"boolean",describe:"显示帮助信息"})},handler:($)=>{let Z=["add","remove","list","ls","get","add-json"];if(!(Array.isArray($._)?$._:[]).some((X)=>typeof X==="string"&&Z.includes(X))||$.help)FF(),process.exit(0)}};X2();q3();O3();function fL($){return $.command("* [message]","Print response and exit (useful for pipes)",(Z)=>{return Z.positional("message",{describe:"Message to process",type:"string"}).option("p",{alias:"print",describe:"Print response and exit (useful for pipes)",type:"boolean"}).option("output-format",{describe:'Output format: "text", "json", "stream-json"',type:"string",default:"text"}).option("include-partial-messages",{describe:"Include partial message chunks as they arrive",type:"boolean"}).option("input-format",{describe:'Input format: "text", "stream-json"',type:"string",default:"text"}).option("model",{describe:"Model for the current session",type:"string"}).option("append-system-prompt",{describe:"Append a system prompt to the default system prompt",type:"string"}).option("system-prompt",{describe:"Replace the default system prompt",type:"string"}).option("max-turns",{alias:["maxTurns"],describe:"Maximum conversation turns (-1: unlimited, N>0: limit to N turns)",type:"number"})},async(Z)=>{if(!Z.print)return;try{if((await a0().initialize(process.cwd(),[])).plugins.length>0)await E2();let X="",J=Z.message||Z._?.[0];if(J&&typeof J==="string")X=J;else if(!process.stdin.isTTY){let q=[];for await(let W of process.stdin)q.push(W);X=Buffer.concat(q).toString("utf-8").trim()}else X="Hello";if(H3(X)){let q=await F3(X,{cwd:process.cwd(),workspaceRoot:process.cwd()});if(!q.success)console.error(`Error: ${q.error||"未知错误"}`),process.exit(1);let W=q.data;if(W?.action==="invoke_skill"){let{skillName:U,skillArgs:H}=W;X=H?`Please use the "${U}" skill to help me with: ${H}`:`Please use the "${U}" skill.`}else if(W?.action==="invoke_custom_command"||W?.action==="invoke_plugin_command"){let U=W.processedContent;X=`# Custom Command: /${W.commandName}
2725
+ `),console.log(JSON.stringify(Q,null,2))}catch(Z){console.error(`❌ 获取失败: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}},NF={command:"add-json <name> <json>",describe:"从 JSON 字符串添加服务器",builder:($)=>{return $.positional("name",{type:"string",describe:"服务器名称",demandOption:!0}).positional("json",{type:"string",describe:"JSON 配置字符串",demandOption:!0}).option("global",{alias:"g",type:"boolean",default:!1,describe:"存储到全局配置(~/.blade/config.json)"}).example([[`$0 mcp add-json my-server '{"type":"stdio","command":"npx","args":["-y","@example/server"]}'`,"Add server from JSON string"]])},handler:async($)=>{try{let Z=p2($.json),Y=p2($.name);if(!Z||!Y)throw Error("缺少必需参数: name 或 json");let Q=JSON.parse(Z),X=$.global===!0;if(!Q.type)throw Error('配置必须包含 "type" 字段');await x$().addMcpServer(Y,Q,{scope:X?"global":"project"});let J=X?d3.join(MQ.homedir(),".blade","config.json"):d3.join(process.cwd(),".blade","config.json");console.log(`✅ MCP 服务器 "${Y}" 已添加`),console.log(` 配置文件: ${J}`)}catch(Z){console.error(`❌ 添加失败: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}},jQ={command:"mcp",describe:"管理 MCP 服务器",builder:($)=>{return $.command(_F).command(BF).command(LF).command(wF).command(NF).demandCommand(0).help(!1).option("help",{alias:"h",type:"boolean",describe:"显示帮助信息"})},handler:($)=>{let Z=["add","remove","list","ls","get","add-json"];if(!(Array.isArray($._)?$._:[]).some((X)=>typeof X==="string"&&Z.includes(X))||$.help)FF(),process.exit(0)}};X4();q8();O8();function fL($){return $.command("* [message]","Print response and exit (useful for pipes)",(Z)=>{return Z.positional("message",{describe:"Message to process",type:"string"}).option("p",{alias:"print",describe:"Print response and exit (useful for pipes)",type:"boolean"}).option("output-format",{describe:'Output format: "text", "json", "stream-json"',type:"string",default:"text"}).option("include-partial-messages",{describe:"Include partial message chunks as they arrive",type:"boolean"}).option("input-format",{describe:'Input format: "text", "stream-json"',type:"string",default:"text"}).option("model",{describe:"Model for the current session",type:"string"}).option("append-system-prompt",{describe:"Append a system prompt to the default system prompt",type:"string"}).option("system-prompt",{describe:"Replace the default system prompt",type:"string"}).option("max-turns",{alias:["maxTurns"],describe:"Maximum conversation turns (-1: unlimited, N>0: limit to N turns)",type:"number"})},async(Z)=>{if(!Z.print)return;try{if((await a0().initialize(process.cwd(),[])).plugins.length>0)await E4();let X="",J=Z.message||Z._?.[0];if(J&&typeof J==="string")X=J;else if(!process.stdin.isTTY){let q=[];for await(let W of process.stdin)q.push(W);X=Buffer.concat(q).toString("utf-8").trim()}else X="Hello";if(H8(X)){let q=await F8(X,{cwd:process.cwd(),workspaceRoot:process.cwd()});if(!q.success)console.error(`Error: ${q.error||"未知错误"}`),process.exit(1);let W=q.data;if(W?.action==="invoke_skill"){let{skillName:U,skillArgs:H}=W;X=H?`Please use the "${U}" skill to help me with: ${H}`:`Please use the "${U}" skill.`}else if(W?.action==="invoke_custom_command"||W?.action==="invoke_plugin_command"){let U=W.processedContent;X=`# Custom Command: /${W.commandName}
2726
2726
 
2727
- ${U}`}else{if(q.message)console.log(q.message);process.exit(0)}}let G=await O0.create({systemPrompt:Z.systemPrompt,appendSystemPrompt:Z.appendSystemPrompt,maxTurns:Z.maxTurns}),K;if(Z.appendSystemPrompt)K=await G.chatWithSystem(Z.appendSystemPrompt,X);else K=await G.chat(X,{messages:[],userId:"cli-user",sessionId:`print-${Date.now()}`,workspaceRoot:process.cwd()});if(Z.outputFormat==="json")console.log(JSON.stringify({response:K,input:X,model:Z.model,timestamp:new Date().toISOString()},null,2));else if(Z.outputFormat==="stream-json")console.log(JSON.stringify({type:"response",content:K}));else console.log(K);process.exit(0)}catch(Y){console.error(`Error: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}})}async function vq(){if(process.argv.slice(2).findIndex((Y)=>Y==="--print"||Y==="-p")===-1)return!1;try{let Y=(await import("yargs")).default,{hideBin:Q}=await import("yargs/helpers"),X=Y(Q(process.argv)).scriptName("blade").strict(!1);return fL(X),await X.parse(),!0}catch(Y){console.error(`Print mode error: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}import{execSync as gL}from"child_process";$4();import*as _4 from"fs/promises";import*as T2 from"path";import Eq from"semver";import{fileURLToPath as hL}from"url";var LZ="blade-code",xL="https://cdn.jsdelivr.net/npm/blade-code@latest/CHANGELOG.md",Pq=T2.join(process.env.HOME||process.env.USERPROFILE||".",".blade"),Tq=T2.join(Pq,"version-cache.json"),pL=3600000,mL=`https://registry.npmjs.org/${LZ}/latest`;async function dL(){try{if(process.env.BLADE_VERSION)return process.env.BLADE_VERSION;let $=hL(import.meta.url),Z=T2.dirname($),Y=[T2.join(Z,"..","..","package.json"),T2.join(Z,"..","package.json"),T2.join(process.cwd(),"package.json")];for(let Q of Y)try{let X=await _4.readFile(Q,"utf-8"),J=JSON.parse(X);if(J.name===LZ&&J.version)return J.version}catch{}return"unknown"}catch{return"unknown"}}async function Cq(){try{let $=await _4.readFile(Tq,"utf-8"),Z=JSON.parse($);if(Date.now()-Z.checkedAt<pL)return Z;return{...Z,checkedAt:0}}catch{return null}}async function Sq($){try{await _4.mkdir(Pq,{recursive:!0,mode:493}),await _4.writeFile(Tq,JSON.stringify($,null,2))}catch{}}async function uL(){try{let $=await A0(mL,{timeout:5000,headers:{Accept:"application/json"}});if(!$.ok)return null;return(await $.json()).version||null}catch{return null}}async function wZ($=!1){let Z=await dL(),Y=xL;if(Z==="unknown")return{currentVersion:Z,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:Y,error:"Unable to determine current version"};let Q=await Cq(),X=Q?.skipUntilVersion,J=null;if(!$&&Q&&Q.checkedAt>0)J=Q.latestVersion;else if(J=await uL(),J)await Sq({latestVersion:J,checkedAt:Date.now(),skipUntilVersion:X});if(!J)return{currentVersion:Z,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:Y,error:"Unable to check for updates"};let G=Eq.gt(J,Z),K=G;if(G&&X)K=Eq.gt(J,X);return{currentVersion:Z,latestVersion:J,hasUpdate:G,shouldPrompt:K,releaseNotesUrl:Y}}async function kq($){let Z=await Cq();await Sq({latestVersion:Z?.latestVersion||$,checkedAt:Z?.checkedAt||Date.now(),skipUntilVersion:$})}function NZ(){return`npm install -g ${LZ}@latest --registry https://registry.npmjs.org`}async function fq(){let{spawn:$}=await import("child_process");return new Promise((Z)=>{let Y=NZ(),Q=$(Y,{stdio:"inherit",shell:!0});Q.on("close",(X)=>{if(X===0)Z({success:!0,message:"✅ 升级成功!请重新启动 blade。"});else Z({success:!1,message:`❌ 升级失败 (exit code: ${X})`})}),Q.on("error",(X)=>{Z({success:!1,message:`❌ 升级失败: ${X.message}`})})})}async function hq(){try{let $=await wZ();return $.shouldPrompt?$:null}catch{return null}}var xq={command:"update",describe:"Check for updates and install if available",handler:async()=>{console.log("\uD83D\uDD0D Checking for updates...");try{let $=await wZ(!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{gL("npm install -g blade-code@latest --registry https://registry.npmjs.org",{stdio:"inherit"}),console.log(""),console.log("✅ Update complete!")}catch(Z){console.error("❌ Update failed. Please run manually:"),console.error(" npm install -g blade-code@latest"),process.exit(1)}}else console.log("✅ You are running the latest version of Blade")}catch($){console.error(`❌ Failed to check for updates: ${$ instanceof Error?$.message:"未知错误"}`),process.exit(1)}}};O$();U0();t0();O$();k$();function pq(){process.stdout.write("\x1B[?25h"),process.stdout.write("\x1B[0m")}var C2=l("Service");function cL($){switch($){case"SIGINT":return"ctrl_c";case"esc":return"esc";case"uncaughtException":case"unhandledRejection":return"error";case"SIGTERM":case"normal":default:return"user_exit"}}class z3{static instance=null;cleanupHandlers=[];isShuttingDown=!1;initialized=!1;constructor(){}static getInstance(){if(!z3.instance)z3.instance=new z3;return z3.instance}initialize(){if(this.initialized){C2.debug("[GracefulShutdown] 已初始化,跳过重复初始化");return}if(process.on("uncaughtException",($)=>{this.handleFatalError("uncaughtException",$)}),process.on("unhandledRejection",($)=>{let Z=$ instanceof Error?$:Error(String($));this.handleFatalError("unhandledRejection",Z)}),process.on("SIGTERM",()=>{C2.info("[GracefulShutdown] 收到 SIGTERM 信号"),this.shutdown("SIGTERM",0)}),process.env.BLADE_NON_INTERACTIVE==="true")process.on("SIGINT",()=>{C2.info("[GracefulShutdown] 收到 SIGINT 信号(非交互模式)"),this.shutdown("SIGINT",0)});this.initialized=!0,C2.debug("[GracefulShutdown] 全局错误处理器已初始化")}registerCleanup($){return this.cleanupHandlers.push($),C2.debug(`[GracefulShutdown] 注册清理函数,当前共 ${this.cleanupHandlers.length} 个`),()=>{let Z=this.cleanupHandlers.indexOf($);if(Z!==-1)this.cleanupHandlers.splice(Z,1),C2.debug(`[GracefulShutdown] 取消注册清理函数,剩余 ${this.cleanupHandlers.length} 个`)}}handleFatalError($,Z){if(this.isShuttingDown){console.error(`[GracefulShutdown] 退出过程中发生额外错误 (${$}):`,Z);return}if(console.error(""),console.error("═".repeat(60)),console.error(`\uD83D\uDCA5 发生未捕获的错误 (${$})`),console.error("═".repeat(60)),console.error(""),console.error("错误信息:",Z.message),console.error(""),Z.stack)console.error("堆栈跟踪:"),console.error(Z.stack);console.error(""),console.error("═".repeat(60)),console.error(""),this.shutdown($,1)}async shutdown($,Z=0){if(this.isShuttingDown){C2.debug("[GracefulShutdown] 已在退出过程中,跳过重复退出");return}this.isShuttingDown=!0,C2.info(`[GracefulShutdown] 开始优雅退出 (原因: ${$})`);try{await jY()}catch(X){}try{let X=M$.getInstance();if(X.isEnabled()){let J=q$(),G=J.session?.sessionId||"unknown",K=J.config?.config?.permissionMode||"default";await X.executeSessionEndHooks(cL($),{projectDir:process.cwd(),sessionId:G,permissionMode:K})}}catch(X){console.error("[GracefulShutdown] SessionEnd hooks 执行失败:",X)}let Y=5000,Q=new Promise((X,J)=>{setTimeout(()=>{J(Error(`清理超时 (${Y}ms)`))},Y)});try{let X=this.runCleanupHandlers();await Promise.race([X,Q])}catch(X){console.error("[GracefulShutdown] 清理过程中发生错误:",X)}finally{pq(),setTimeout(()=>{process.exit(Z)},100)}}async runCleanupHandlers(){let $=[...this.cleanupHandlers].reverse();for(let Z of $)try{let Y=Z();if(Y instanceof Promise)await Y}catch(Y){console.error("[GracefulShutdown] 清理函数执行失败:",Y)}}isExiting(){return this.isShuttingDown}reset(){this.isShuttingDown=!1,this.cleanupHandlers=[],this.initialized=!1}}var B4=()=>{return z3.getInstance()},mq=($)=>{return B4().registerCleanup($)},dq=()=>{B4().initialize()},_3=($=0)=>{pq(),process.exit($)};U4();u8();S4();t0();O$();e2();q3();import{useMemoizedFn as eU}from"ahooks";import{useEffect as QA,useState as WY}from"react";Y2();O3();k$();s4();U0();O$();import{useMemoizedFn as r0}from"ahooks";import{Box as l2,useApp as eb}from"ink";import{useEffect as I4,useRef as V6}from"react";m9();O1();r2();import{useShallow as uq}from"zustand/react/shallow";k$();import{useStore as lL}from"zustand";function b$($){return lL(f4,$)}U0();var iL=[],gq=()=>b$(($)=>$.session.sessionId),l9=()=>b$(($)=>$.session.messages),cq=()=>b$(($)=>$.session.clearCount),lq=()=>b$(($)=>$.session.isCompacting),S2=()=>b$(($)=>$.session.actions),iq=()=>b$(($)=>{let{inputTokens:Z,maxContextTokens:Y}=$.session.tokenUsage;if(Y<=0)return 100;let Q=Math.max(0,100-Z/Y*100);return Math.round(Q)}),aq=()=>b$(($)=>$.app.initializationStatus),rq=()=>b$(($)=>$.app.initializationError),i9=()=>b$(($)=>$.app.activeModal),nq=()=>b$(($)=>$.app.todos),oq=()=>b$(($)=>$.app.modelEditorTarget),sq=()=>b$(($)=>$.app.sessionSelectorData),tq=()=>b$(($)=>$.app.awaitingSecondCtrlC),k2=()=>b$(($)=>$.app.actions),a9=()=>b$(($)=>$.app.initializationStatus==="ready"),eq=()=>b$(($)=>$.app.todos.length>0),B3=()=>b$(($)=>$.config.config?.permissionMode||"default"),$W=()=>b$(($)=>$.config.config?.models??iL),r9=()=>b$(($)=>{let Z=$.config.config;if(!Z)return;let Y=Z.currentModelId;return Z.models.find((X)=>X.id===Y)??Z.models[0]}),ZW=()=>b$(($)=>$.config.config?.currentModelId),$0=()=>b$(($)=>{let Z=$.config.config?.theme??"default";if(g0.getCurrentThemeName()!==Z)try{g0.setTheme(Z)}catch{}return g0.getTheme()}),Z1=()=>b$(($)=>$.focus.currentFocus),YW=()=>b$(($)=>$.focus.actions),f2=()=>b$(($)=>$.command.isProcessing),QW=()=>b$(($)=>$.command.actions),XW=()=>b$(($)=>$.command.pendingCommands),n9=()=>b$(($)=>$.app.thinkingModeEnabled),JW=()=>b$(($)=>$.session.currentThinkingContent),GW=()=>b$(($)=>$.session.thinkingExpanded),KW=()=>b$(($)=>$.session.currentStreamingMessageId),qW=()=>b$(uq(($)=>({lines:$.session.currentStreamingLines,tail:$.session.currentStreamingTail,lineCount:$.session.currentStreamingLineCount,version:$.session.currentStreamingVersion}))),WW=()=>b$(($)=>$.session.finalizingStreamingMessageId),UW=()=>b$(($)=>$.session.historyExpanded),HW=()=>b$(($)=>$.session.expandedMessageCount),FW=()=>b$(uq(($)=>{let Z=$.spec.currentSpec;if(!Z)return{phase:null,completed:0,total:0};let Y=Z.tasks??[],Q=Y.filter((X)=>X.status==="completed").length;return{phase:Z.phase,completed:Q,total:Y.length}}));k$();t0();O$();f7();import{useMemoizedFn as h2}from"ahooks";import{useEffect as _W,useRef as R8}from"react";O3();k$();C3();BZ();X2();import{useMemoizedFn as OW}from"ahooks";import{useRef as aL}from"react";function zW($){let Z=aL(void 0),Y=OW(async()=>{let X=await O0.create({systemPrompt:$.systemPrompt,appendSystemPrompt:$.appendSystemPrompt,maxTurns:$.maxTurns});return Z.current=X,X}),Q=OW(()=>{if(Z.current)Z.current=void 0});return{agentRef:Z,createAgent:Y,cleanupAgent:Q}}var BW=l("UI");function rL($,Z,Y,Q){switch($){case"show_theme_selector":return Y.setActiveModal("themeSelector"),!0;case"show_model_selector":return Y.setActiveModal("modelSelector"),!0;case"show_model_add_wizard":return Y.setActiveModal("modelAddWizard"),!0;case"show_permissions_manager":return Y.setActiveModal("permissionsManager"),!0;case"show_agents_manager":return Y.setActiveModal("agentsManager"),!0;case"show_skills_manager":return Y.setActiveModal("skillsManager"),!0;case"show_hooks_manager":return Y.setActiveModal("hooksManager"),!0;case"show_plugins_manager":return Y.setActiveModal("pluginsManager"),!0;case"show_agent_creation_wizard":return Y.setActiveModal("agentCreationWizard"),!0;case"show_session_selector":{let X=Z?.sessions;return Y.showSessionSelector(X),!0}case"clear_screen":return Q.clearMessages(),Q.setError(null),Q.resetTokenUsage(),Y.setTodos([]),!0;case"compact_completed":case"compact_fallback":return Q.resetTokenUsage(),!0;case"exit_application":return _3(0),!0;default:return!1}}function nL($){return typeof $==="object"&&$!==null&&$.action==="invoke_skill"&&typeof $.skillName==="string"}function oL($){return typeof $==="object"&&$!==null&&$.action==="invoke_custom_command"&&typeof $.commandName==="string"&&typeof $.processedContent==="string"}function sL($){return typeof $==="object"&&$!==null&&$.action==="invoke_plugin_command"&&typeof $.commandName==="string"&&typeof $.processedContent==="string"}function tL($){let{text:Z,images:Y,parts:Q}=$;if(Y.length===0)return Z;let X=[];for(let J of Q)if(J.type==="text")X.push({type:"text",text:J.text});else X.push({type:"image_url",image_url:{url:`data:${J.mimeType};base64,${J.base64}`}});return X}var LW=($,Z,Y,Q)=>{let X=f2(),J=l9(),G=gq(),K=B3(),q=n9(),W=S2(),U=k2(),H=QW(),F=R8(!1),{createAgent:O,cleanupAgent:z}=zW({systemPrompt:$,appendSystemPrompt:Z,maxTurns:Q}),_=300,B=5,L=400,w=R8(""),N=R8(null),D=R8(""),V=R8(null),I=h2(()=>{if(w.current){let j=w.current,M=W.appendAssistantContent(j);u6(M,j),w.current=""}if(N.current)clearTimeout(N.current),N.current=null}),v=h2(()=>{if(D.current)W.appendThinkingContent(D.current),D.current="";if(V.current)clearTimeout(V.current),V.current=null}),b=(j)=>{let M=0;for(let R of j)if(R===`
2728
- `)M++;return M},C=h2((j)=>{w.current+=j;let M=w.current;if(b(M)>=5||M.length>=400){I();return}if(!N.current)N.current=setTimeout(I,300)}),d=h2((j)=>{D.current+=j;let M=D.current;if(b(M)>=5||M.length>=400){v();return}if(!V.current)V.current=setTimeout(v,300)}),e=h2(()=>{if(w.current="",N.current)clearTimeout(N.current),N.current=null;if(D.current="",V.current)clearTimeout(V.current),V.current=null});_W(()=>{return()=>{z(),e()}},[z,e]),_W(()=>{if(!q)W.setCurrentThinkingContent(null)},[q,W]);let k=h2(()=>{if(!X)return;I(),v(),H.abort(),U.setTodos([]);let j=q$().session.currentStreamingMessageId;if(j)g6(j);if(W.finalizeStreamingMessage(),!F.current)W.addAssistantMessage("✋ 任务已停止"),F.current=!0}),T=h2(async(j)=>{let{text:M}=j,R=!1;try{if(H3(M)){await h8();let K$=H.createAbortController(),e$={cwd:process.cwd(),signal:K$.signal},L$=await F3(M,e$);if(L$.message){if(rL(L$.message,L$.data,U,W))return{success:!0}}let o1=!1;if(nL(L$.data)){let{skillName:m0,skillArgs:B2}=L$.data,R1=B2?`Please use the "${m0}" skill to help me with: ${B2}`:`Please use the "${m0}" skill.`;W.addUserMessage(R1),R=!0,o1=!0,j={displayText:R1,text:R1,images:[],parts:[{type:"text",text:R1}]}}if(oL(L$.data)){let{commandName:m0,processedContent:B2}=L$.data;W.addUserMessage(M),R=!0,o1=!0;let R1=`# Custom Command: /${m0}
2727
+ ${U}`}else{if(q.message)console.log(q.message);process.exit(0)}}let G=await O0.create({systemPrompt:Z.systemPrompt,appendSystemPrompt:Z.appendSystemPrompt,maxTurns:Z.maxTurns}),K;if(Z.appendSystemPrompt)K=await G.chatWithSystem(Z.appendSystemPrompt,X);else K=await G.chat(X,{messages:[],userId:"cli-user",sessionId:`print-${Date.now()}`,workspaceRoot:process.cwd()});if(Z.outputFormat==="json")console.log(JSON.stringify({response:K,input:X,model:Z.model,timestamp:new Date().toISOString()},null,2));else if(Z.outputFormat==="stream-json")console.log(JSON.stringify({type:"response",content:K}));else console.log(K);process.exit(0)}catch(Y){console.error(`Error: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}})}async function vq(){if(process.argv.slice(2).findIndex((Y)=>Y==="--print"||Y==="-p")===-1)return!1;try{let Y=(await import("yargs")).default,{hideBin:Q}=await import("yargs/helpers"),X=Y(Q(process.argv)).scriptName("blade").strict(!1);return fL(X),await X.parse(),!0}catch(Y){console.error(`Print mode error: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}import{execSync as gL}from"child_process";$2();import*as _2 from"fs/promises";import*as T4 from"path";import Eq from"semver";import{fileURLToPath as hL}from"url";var LZ="blade-code",xL="https://cdn.jsdelivr.net/npm/blade-code@latest/CHANGELOG.md",Pq=T4.join(process.env.HOME||process.env.USERPROFILE||".",".blade"),Tq=T4.join(Pq,"version-cache.json"),pL=3600000,mL=`https://registry.npmjs.org/${LZ}/latest`;async function dL(){try{if(process.env.BLADE_VERSION)return process.env.BLADE_VERSION;let $=hL(import.meta.url),Z=T4.dirname($),Y=[T4.join(Z,"..","..","package.json"),T4.join(Z,"..","package.json"),T4.join(process.cwd(),"package.json")];for(let Q of Y)try{let X=await _2.readFile(Q,"utf-8"),J=JSON.parse(X);if(J.name===LZ&&J.version)return J.version}catch{}return"unknown"}catch{return"unknown"}}async function Cq(){try{let $=await _2.readFile(Tq,"utf-8"),Z=JSON.parse($);if(Date.now()-Z.checkedAt<pL)return Z;return{...Z,checkedAt:0}}catch{return null}}async function Sq($){try{await _2.mkdir(Pq,{recursive:!0,mode:493}),await _2.writeFile(Tq,JSON.stringify($,null,2))}catch{}}async function uL(){try{let $=await A0(mL,{timeout:5000,headers:{Accept:"application/json"}});if(!$.ok)return null;return(await $.json()).version||null}catch{return null}}async function wZ($=!1){let Z=await dL(),Y=xL;if(Z==="unknown")return{currentVersion:Z,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:Y,error:"Unable to determine current version"};let Q=await Cq(),X=Q?.skipUntilVersion,J=null;if(!$&&Q&&Q.checkedAt>0)J=Q.latestVersion;else if(J=await uL(),J)await Sq({latestVersion:J,checkedAt:Date.now(),skipUntilVersion:X});if(!J)return{currentVersion:Z,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:Y,error:"Unable to check for updates"};let G=Eq.gt(J,Z),K=G;if(G&&X)K=Eq.gt(J,X);return{currentVersion:Z,latestVersion:J,hasUpdate:G,shouldPrompt:K,releaseNotesUrl:Y}}async function kq($){let Z=await Cq();await Sq({latestVersion:Z?.latestVersion||$,checkedAt:Z?.checkedAt||Date.now(),skipUntilVersion:$})}function NZ(){return`npm install -g ${LZ}@latest --registry https://registry.npmjs.org`}async function fq(){let{spawn:$}=await import("child_process");return new Promise((Z)=>{let Y=NZ(),Q=$(Y,{stdio:"inherit",shell:!0});Q.on("close",(X)=>{if(X===0)Z({success:!0,message:"✅ 升级成功!请重新启动 blade。"});else Z({success:!1,message:`❌ 升级失败 (exit code: ${X})`})}),Q.on("error",(X)=>{Z({success:!1,message:`❌ 升级失败: ${X.message}`})})})}async function hq(){try{let $=await wZ();return $.shouldPrompt?$:null}catch{return null}}var xq={command:"update",describe:"Check for updates and install if available",handler:async()=>{console.log("\uD83D\uDD0D Checking for updates...");try{let $=await wZ(!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{gL("npm install -g blade-code@latest --registry https://registry.npmjs.org",{stdio:"inherit"}),console.log(""),console.log("✅ Update complete!")}catch(Z){console.error("❌ Update failed. Please run manually:"),console.error(" npm install -g blade-code@latest"),process.exit(1)}}else console.log("✅ You are running the latest version of Blade")}catch($){console.error(`❌ Failed to check for updates: ${$ instanceof Error?$.message:"未知错误"}`),process.exit(1)}}};O$();U0();t0();O$();k$();function pq(){process.stdout.write("\x1B[?25h"),process.stdout.write("\x1B[0m")}var C4=l("Service");function cL($){switch($){case"SIGINT":return"ctrl_c";case"esc":return"esc";case"uncaughtException":case"unhandledRejection":return"error";case"SIGTERM":case"normal":default:return"user_exit"}}class z8{static instance=null;cleanupHandlers=[];isShuttingDown=!1;initialized=!1;constructor(){}static getInstance(){if(!z8.instance)z8.instance=new z8;return z8.instance}initialize(){if(this.initialized){C4.debug("[GracefulShutdown] 已初始化,跳过重复初始化");return}if(process.on("uncaughtException",($)=>{this.handleFatalError("uncaughtException",$)}),process.on("unhandledRejection",($)=>{let Z=$ instanceof Error?$:Error(String($));this.handleFatalError("unhandledRejection",Z)}),process.on("SIGTERM",()=>{C4.info("[GracefulShutdown] 收到 SIGTERM 信号"),this.shutdown("SIGTERM",0)}),process.env.BLADE_NON_INTERACTIVE==="true")process.on("SIGINT",()=>{C4.info("[GracefulShutdown] 收到 SIGINT 信号(非交互模式)"),this.shutdown("SIGINT",0)});this.initialized=!0,C4.debug("[GracefulShutdown] 全局错误处理器已初始化")}registerCleanup($){return this.cleanupHandlers.push($),C4.debug(`[GracefulShutdown] 注册清理函数,当前共 ${this.cleanupHandlers.length} 个`),()=>{let Z=this.cleanupHandlers.indexOf($);if(Z!==-1)this.cleanupHandlers.splice(Z,1),C4.debug(`[GracefulShutdown] 取消注册清理函数,剩余 ${this.cleanupHandlers.length} 个`)}}handleFatalError($,Z){if(this.isShuttingDown){console.error(`[GracefulShutdown] 退出过程中发生额外错误 (${$}):`,Z);return}if(console.error(""),console.error("═".repeat(60)),console.error(`\uD83D\uDCA5 发生未捕获的错误 (${$})`),console.error("═".repeat(60)),console.error(""),console.error("错误信息:",Z.message),console.error(""),Z.stack)console.error("堆栈跟踪:"),console.error(Z.stack);console.error(""),console.error("═".repeat(60)),console.error(""),this.shutdown($,1)}async shutdown($,Z=0){if(this.isShuttingDown){C4.debug("[GracefulShutdown] 已在退出过程中,跳过重复退出");return}this.isShuttingDown=!0,C4.info(`[GracefulShutdown] 开始优雅退出 (原因: ${$})`);try{await jY()}catch(X){}try{let X=M$.getInstance();if(X.isEnabled()){let J=q$(),G=J.session?.sessionId||"unknown",K=J.config?.config?.permissionMode||"default";await X.executeSessionEndHooks(cL($),{projectDir:process.cwd(),sessionId:G,permissionMode:K})}}catch(X){console.error("[GracefulShutdown] SessionEnd hooks 执行失败:",X)}let Y=5000,Q=new Promise((X,J)=>{setTimeout(()=>{J(Error(`清理超时 (${Y}ms)`))},Y)});try{let X=this.runCleanupHandlers();await Promise.race([X,Q])}catch(X){console.error("[GracefulShutdown] 清理过程中发生错误:",X)}finally{pq(),setTimeout(()=>{process.exit(Z)},100)}}async runCleanupHandlers(){let $=[...this.cleanupHandlers].reverse();for(let Z of $)try{let Y=Z();if(Y instanceof Promise)await Y}catch(Y){console.error("[GracefulShutdown] 清理函数执行失败:",Y)}}isExiting(){return this.isShuttingDown}reset(){this.isShuttingDown=!1,this.cleanupHandlers=[],this.initialized=!1}}var B2=()=>{return z8.getInstance()},mq=($)=>{return B2().registerCleanup($)},dq=()=>{B2().initialize()},_8=($=0)=>{pq(),process.exit($)};U2();u3();S2();t0();O$();e4();q8();import{useMemoizedFn as eU}from"ahooks";import{useEffect as QA,useState as WY}from"react";Y4();O8();k$();s2();U0();O$();import{useMemoizedFn as r0}from"ahooks";import{Box as l4,useApp as eb}from"ink";import{useEffect as I2,useRef as V6}from"react";m9();O1();r4();import{useShallow as uq}from"zustand/react/shallow";k$();import{useStore as lL}from"zustand";function b$($){return lL(f2,$)}U0();var iL=[],gq=()=>b$(($)=>$.session.sessionId),l9=()=>b$(($)=>$.session.messages),cq=()=>b$(($)=>$.session.clearCount),lq=()=>b$(($)=>$.session.isCompacting),S4=()=>b$(($)=>$.session.actions),iq=()=>b$(($)=>{let{inputTokens:Z,maxContextTokens:Y}=$.session.tokenUsage;if(Y<=0)return 100;let Q=Math.max(0,100-Z/Y*100);return Math.round(Q)}),aq=()=>b$(($)=>$.app.initializationStatus),rq=()=>b$(($)=>$.app.initializationError),i9=()=>b$(($)=>$.app.activeModal),nq=()=>b$(($)=>$.app.todos),oq=()=>b$(($)=>$.app.modelEditorTarget),sq=()=>b$(($)=>$.app.sessionSelectorData),tq=()=>b$(($)=>$.app.awaitingSecondCtrlC),k4=()=>b$(($)=>$.app.actions),a9=()=>b$(($)=>$.app.initializationStatus==="ready"),eq=()=>b$(($)=>$.app.todos.length>0),B8=()=>b$(($)=>$.config.config?.permissionMode||"default"),$W=()=>b$(($)=>$.config.config?.models??iL),r9=()=>b$(($)=>{let Z=$.config.config;if(!Z)return;let Y=Z.currentModelId;return Z.models.find((X)=>X.id===Y)??Z.models[0]}),ZW=()=>b$(($)=>$.config.config?.currentModelId),$0=()=>b$(($)=>{let Z=$.config.config?.theme??"default";if(g0.getCurrentThemeName()!==Z)try{g0.setTheme(Z)}catch{}return g0.getTheme()}),Z1=()=>b$(($)=>$.focus.currentFocus),YW=()=>b$(($)=>$.focus.actions),f4=()=>b$(($)=>$.command.isProcessing),QW=()=>b$(($)=>$.command.actions),XW=()=>b$(($)=>$.command.pendingCommands),n9=()=>b$(($)=>$.app.thinkingModeEnabled),JW=()=>b$(($)=>$.session.currentThinkingContent),GW=()=>b$(($)=>$.session.thinkingExpanded),KW=()=>b$(($)=>$.session.currentStreamingMessageId),qW=()=>b$(uq(($)=>({lines:$.session.currentStreamingLines,tail:$.session.currentStreamingTail,lineCount:$.session.currentStreamingLineCount,version:$.session.currentStreamingVersion}))),WW=()=>b$(($)=>$.session.finalizingStreamingMessageId),UW=()=>b$(($)=>$.session.historyExpanded),HW=()=>b$(($)=>$.session.expandedMessageCount),FW=()=>b$(uq(($)=>{let Z=$.spec.currentSpec;if(!Z)return{phase:null,completed:0,total:0};let Y=Z.tasks??[],Q=Y.filter((X)=>X.status==="completed").length;return{phase:Z.phase,completed:Q,total:Y.length}}));k$();t0();O$();f7();import{useMemoizedFn as h4}from"ahooks";import{useEffect as _W,useRef as R3}from"react";O8();k$();C8();BZ();X4();import{useMemoizedFn as OW}from"ahooks";import{useRef as aL}from"react";function zW($){let Z=aL(void 0),Y=OW(async()=>{let X=await O0.create({systemPrompt:$.systemPrompt,appendSystemPrompt:$.appendSystemPrompt,maxTurns:$.maxTurns});return Z.current=X,X}),Q=OW(()=>{if(Z.current)Z.current=void 0});return{agentRef:Z,createAgent:Y,cleanupAgent:Q}}var BW=l("UI");function rL($,Z,Y,Q){switch($){case"show_theme_selector":return Y.setActiveModal("themeSelector"),!0;case"show_model_selector":return Y.setActiveModal("modelSelector"),!0;case"show_model_add_wizard":return Y.setActiveModal("modelAddWizard"),!0;case"show_permissions_manager":return Y.setActiveModal("permissionsManager"),!0;case"show_agents_manager":return Y.setActiveModal("agentsManager"),!0;case"show_skills_manager":return Y.setActiveModal("skillsManager"),!0;case"show_hooks_manager":return Y.setActiveModal("hooksManager"),!0;case"show_plugins_manager":return Y.setActiveModal("pluginsManager"),!0;case"show_agent_creation_wizard":return Y.setActiveModal("agentCreationWizard"),!0;case"show_session_selector":{let X=Z?.sessions;return Y.showSessionSelector(X),!0}case"clear_screen":return Q.clearMessages(),Q.setError(null),Q.resetTokenUsage(),Y.setTodos([]),!0;case"compact_completed":case"compact_fallback":return Q.resetTokenUsage(),!0;case"exit_application":return _8(0),!0;default:return!1}}function nL($){return typeof $==="object"&&$!==null&&$.action==="invoke_skill"&&typeof $.skillName==="string"}function oL($){return typeof $==="object"&&$!==null&&$.action==="invoke_custom_command"&&typeof $.commandName==="string"&&typeof $.processedContent==="string"}function sL($){return typeof $==="object"&&$!==null&&$.action==="invoke_plugin_command"&&typeof $.commandName==="string"&&typeof $.processedContent==="string"}function tL($){let{text:Z,images:Y,parts:Q}=$;if(Y.length===0)return Z;let X=[];for(let J of Q)if(J.type==="text")X.push({type:"text",text:J.text});else X.push({type:"image_url",image_url:{url:`data:${J.mimeType};base64,${J.base64}`}});return X}var LW=($,Z,Y,Q)=>{let X=f4(),J=l9(),G=gq(),K=B8(),q=n9(),W=S4(),U=k4(),H=QW(),F=R3(!1),{createAgent:O,cleanupAgent:z}=zW({systemPrompt:$,appendSystemPrompt:Z,maxTurns:Q}),_=300,B=5,L=400,w=R3(""),N=R3(null),D=R3(""),V=R3(null),I=h4(()=>{if(w.current){let j=w.current,M=W.appendAssistantContent(j);u6(M,j),w.current=""}if(N.current)clearTimeout(N.current),N.current=null}),v=h4(()=>{if(D.current)W.appendThinkingContent(D.current),D.current="";if(V.current)clearTimeout(V.current),V.current=null}),b=(j)=>{let M=0;for(let R of j)if(R===`
2728
+ `)M++;return M},C=h4((j)=>{w.current+=j;let M=w.current;if(b(M)>=5||M.length>=400){I();return}if(!N.current)N.current=setTimeout(I,300)}),d=h4((j)=>{D.current+=j;let M=D.current;if(b(M)>=5||M.length>=400){v();return}if(!V.current)V.current=setTimeout(v,300)}),e=h4(()=>{if(w.current="",N.current)clearTimeout(N.current),N.current=null;if(D.current="",V.current)clearTimeout(V.current),V.current=null});_W(()=>{return()=>{z(),e()}},[z,e]),_W(()=>{if(!q)W.setCurrentThinkingContent(null)},[q,W]);let k=h4(()=>{if(!X)return;I(),v(),H.abort(),U.setTodos([]);let j=q$().session.currentStreamingMessageId;if(j)g6(j);if(W.finalizeStreamingMessage(),!F.current)W.addAssistantMessage("✋ 任务已停止"),F.current=!0}),T=h4(async(j)=>{let{text:M}=j,R=!1;try{if(H8(M)){await h3();let K$=H.createAbortController(),e$={cwd:process.cwd(),signal:K$.signal},L$=await F8(M,e$);if(L$.message){if(rL(L$.message,L$.data,U,W))return{success:!0}}let o1=!1;if(nL(L$.data)){let{skillName:m0,skillArgs:B4}=L$.data,R1=B4?`Please use the "${m0}" skill to help me with: ${B4}`:`Please use the "${m0}" skill.`;W.addUserMessage(R1),R=!0,o1=!0,j={displayText:R1,text:R1,images:[],parts:[{type:"text",text:R1}]}}if(oL(L$.data)){let{commandName:m0,processedContent:B4}=L$.data;W.addUserMessage(M),R=!0,o1=!0;let R1=`# Custom Command: /${m0}
2729
2729
 
2730
2730
  The user has invoked the custom command "/${m0}". Follow the instructions below to complete the task.
2731
2731
 
2732
2732
  ---
2733
2733
 
2734
- ${B2}
2734
+ ${B4}
2735
2735
 
2736
2736
  ---
2737
2737
 
2738
- Remember: Follow the above instructions carefully to complete the user's request.`;j={displayText:M,text:R1,images:[],parts:[{type:"text",text:R1}]}}if(sL(L$.data)){let{commandName:m0,pluginName:B2,processedContent:R1}=L$.data;W.addUserMessage(M),R=!0,o1=!0;let S8=`# Plugin Command: /${m0}
2738
+ Remember: Follow the above instructions carefully to complete the user's request.`;j={displayText:M,text:R1,images:[],parts:[{type:"text",text:R1}]}}if(sL(L$.data)){let{commandName:m0,pluginName:B4,processedContent:R1}=L$.data;W.addUserMessage(M),R=!0,o1=!0;let S3=`# Plugin Command: /${m0}
2739
2739
 
2740
- The user has invoked the plugin command "/${m0}" from plugin "${B2}". Follow the instructions below to complete the task.
2740
+ The user has invoked the plugin command "/${m0}" from plugin "${B4}". Follow the instructions below to complete the task.
2741
2741
 
2742
2742
  ---
2743
2743
 
@@ -2745,9 +2745,9 @@ ${R1}
2745
2745
 
2746
2746
  ---
2747
2747
 
2748
- Remember: Follow the above instructions carefully to complete the user's request.`;j={displayText:M,text:S8,images:[],parts:[{type:"text",text:S8}]}}if(!o1){if(!L$.success&&L$.error)return W.addAssistantMessage(`❌ ${L$.error}`),{success:L$.success,output:L$.message,error:L$.error,metadata:L$.data};let m0=L$.message;if(L$.success&&typeof m0==="string"&&m0.trim()!=="")W.addAssistantMessage(m0);return{success:L$.success,output:L$.message,error:L$.error,metadata:L$.data}}}let n=M$.getInstance(),y=j,u,s=await n.executeUserPromptSubmitHooks(j.text,{projectDir:process.cwd(),sessionId:G,permissionMode:K,hasImages:j.images.length>0,imageCount:j.images.length});if(!s.proceed){if(s.warning)W.addAssistantMessage(`⚠️ ${s.warning}`);return{success:!1,error:"blocked by hook"}}if(s.updatedPrompt)y={...j,text:s.updatedPrompt,displayText:s.updatedPrompt,parts:[{type:"text",text:s.updatedPrompt}]};if(s.contextInjection)u=s.contextInjection;if(!R)W.addUserMessage(y.displayText);let i=tL(y),Y$=H.createAbortController(),f=await O();if(Y$.signal.aborted)return BW.info("[handleCommandSubmit] Agent 创建期间已被中止"),{success:!1,error:"aborted"};let w$=J.map((K$)=>({role:K$.role,content:K$.content}));if(u)w$.push({role:"system",content:`<user-prompt-submit-hook>
2748
+ Remember: Follow the above instructions carefully to complete the user's request.`;j={displayText:M,text:S3,images:[],parts:[{type:"text",text:S3}]}}if(!o1){if(!L$.success&&L$.error)return W.addAssistantMessage(`❌ ${L$.error}`),{success:L$.success,output:L$.message,error:L$.error,metadata:L$.data};let m0=L$.message;if(L$.success&&typeof m0==="string"&&m0.trim()!=="")W.addAssistantMessage(m0);return{success:L$.success,output:L$.message,error:L$.error,metadata:L$.data}}}let n=M$.getInstance(),y=j,u,s=await n.executeUserPromptSubmitHooks(j.text,{projectDir:process.cwd(),sessionId:G,permissionMode:K,hasImages:j.images.length>0,imageCount:j.images.length});if(!s.proceed){if(s.warning)W.addAssistantMessage(`⚠️ ${s.warning}`);return{success:!1,error:"blocked by hook"}}if(s.updatedPrompt)y={...j,text:s.updatedPrompt,displayText:s.updatedPrompt,parts:[{type:"text",text:s.updatedPrompt}]};if(s.contextInjection)u=s.contextInjection;if(!R)W.addUserMessage(y.displayText);let i=tL(y),Y$=H.createAbortController(),f=await O();if(Y$.signal.aborted)return BW.info("[handleCommandSubmit] Agent 创建期间已被中止"),{success:!1,error:"aborted"};let w$=J.map((K$)=>({role:K$.role,content:K$.content}));if(u)w$.push({role:"system",content:`<user-prompt-submit-hook>
2749
2749
  ${u}
2750
- </user-prompt-submit-hook>`});let G$={messages:w$,userId:"cli-user",sessionId:G,workspaceRoot:process.cwd(),signal:Y$.signal,confirmationHandler:Y,permissionMode:K},N$=0,X0=0,G0=0,_2={stream:!0,onContentDelta:(K$)=>{N$++,X0+=K$.length,F1("useCommandHandler","onContentDelta",{callCount:N$,deltaLen:K$.length,totalLen:X0}),C(K$)},onThinkingDelta:q?(K$)=>{d(K$)}:void 0,onThinking:q?(K$)=>{W.setCurrentThinkingContent(K$)}:void 0,onStreamEnd:()=>{if(F1("useCommandHandler","onStreamEnd",{contentDeltaCallCount:N$,contentDeltaTotalLen:X0,remainingBuffer:w.current.length}),N.current)clearTimeout(N.current),N.current=null;if(V.current)clearTimeout(V.current),V.current=null;let K$=w.current,e$=D.current;w.current="",D.current="";let L$=q$().session.currentStreamingMessageId;if(L$){if(K$)u6(L$,K$);g6(L$)}W.finalizeStreamingMessage(K$,e$)},onContent:(K$)=>{if(G0++,!K$.trim())return;F1("useCommandHandler","onContent (non-stream)",{callCount:G0,contentLen:K$.length}),W.addAssistantMessageAndClearThinking(K$)},onToolStart:(K$)=>{if(K$.type!=="function")return;if(K$.function.name==="TodoWrite")return;try{let e$=JSON.parse(K$.function.arguments),L$=N8(K$.function.name,e$);W.addToolMessage(L$,{toolName:K$.function.name,phase:"start",summary:L$,params:e$})}catch(e$){BW.error("[useCommandHandler] onToolStart error:",e$)}},onToolResult:async(K$,e$)=>{if(K$.type!=="function")return;let L$=e$.metadata?.summary;if(!L$)return;let o1;if(Xq(K$.function.name,e$))o1=Jq(K$.function.name,e$)||e$.displayContent;W.addToolMessage(L$,{toolName:K$.function.name,phase:"complete",summary:L$,detail:o1})},onTokenUsage:(K$)=>{W.updateTokenUsage(K$)},onCompacting:(K$)=>{if(W.setCompacting(K$),!K$)W.resetTokenUsage()},onTurnLimitReached:Y?async(K$)=>{let e$=await Y.requestConfirmation({type:"maxTurnsExceeded",title:"对话轮次上限",message:`已进行 ${K$.turnsCount} 轮对话。是否继续?`,risks:["继续执行可能导致更长的等待时间","可能产生更多的 API 费用"]});return{continue:e$.approved,reason:e$.reason}}:void 0},T0=await f.chat(i,G$,_2);if(!T0||T0.trim()===""){if(!F.current&&N$===0)return W.addAssistantMessage("⏹ 已取消"),{success:!0,output:"已取消"};return{success:!0,output:T0??""}}return{success:!0,output:T0}}catch(n){if(F.current)return{success:!1,error:"aborted"};let y=n instanceof Error?n.message:"未知错误",u=y.includes("can only concatenate str")||y.includes("image_url")||y.includes("multimodal")||y.includes("vision")||y.includes("does not support images"),s=y;if(u)s="当前模型不支持图片理解功能。请切换到支持视觉能力的模型(如 Claude 4.5、GPT-5.2、Gemini 3 Pro、Qwen3-VL-Plus 等)后重试。";let i={success:!1,error:s};return W.addAssistantMessage(`❌ ${s}`),i}}),g=h2(async(j)=>{if(!j.text.trim()&&j.images.length===0)return;if(X){H.enqueueCommand({displayText:j.displayText,text:j.text,images:j.images,parts:j.parts});return}U.setTodos([]),F.current=!1;let M=H.createAbortController();e(),W.clearFinalizingStreamingMessageId(),H.setProcessing(!0);try{let R=await T(j);if(!R.success&&R.error&&R.error!=="aborted")W.setError(R.error)}catch(R){if(R instanceof Error&&(R.name==="AbortError"||R.message.includes("aborted")));else{let n=R instanceof Error?R.message:"未知错误";W.setError(`执行失败: ${n}`)}}finally{if(H.getAbortController()===M){H.setProcessing(!1),H.clearAbortController(M),W.setCurrentThinkingContent(null);let y=H.dequeueCommand();if(y)setTimeout(()=>g({displayText:y.displayText,text:y.text,images:y.images,parts:y.parts}),100)}}});return{executeCommand:g,handleAbort:k,isProcessing:X}};import{useMemoizedFn as o9}from"ahooks";import{useState as wW}from"react";var NW=()=>{let[$,Z]=wW([]),[Y,Q]=wW(-1),X=o9((q,W)=>{let U={display:q,pasteMappings:W?new Map(W):new Map};Z((H)=>[...H,U]),Q(-1)}),J=o9(()=>{if($.length===0)return null;let q=Y===-1?$.length-1:Math.max(0,Y-1);return Q(q),$[q]||null}),G=o9(()=>{if(Y===-1)return null;let q=Y+1;if(q>=$.length)return Q(-1),null;else return Q(q),$[q]||null}),K=o9(()=>{Q(-1)});return{commandHistory:$,historyIndex:Y,addToHistory:X,getPreviousCommand:J,getNextCommand:G,resetHistoryIndex:K}};import{useMemoizedFn as bW}from"ahooks";import{useMemo as eL,useState as $w}from"react";var AW=()=>{let[$,Z]=$w({isVisible:!1,details:null,resolver:null}),Y=bW((J)=>{return new Promise((G)=>{Z({isVisible:!0,details:J,resolver:G})})}),Q=bW((J)=>{if($.resolver)$.resolver(J);Z({isVisible:!1,details:null,resolver:null})}),X=eL(()=>({requestConfirmation:Y}),[Y]);return{confirmationState:$,confirmationHandler:X,handleResponse:Q}};import{useMemoizedFn as L4}from"ahooks";import{useRef as RW,useState as Zw}from"react";var s9="␞",t9="␟";function e9($){return`${s9}PASTE:${$}:`}function bZ(){return t9}var dh=new RegExp(`${s9}PASTE:(\\d+):[\\s\\S]*?${t9}`,"g");function Yw($){return $.includes(s9)&&$.includes(t9)}function VW($="",Z=0){let[Y,Q]=Zw({value:$,cursorPosition:Z}),X=RW(0),J=RW(new Map),G=L4((O)=>{Q((z)=>({value:O,cursorPosition:z.cursorPosition}));for(let z of J.current.keys()){let _=e9(z);if(!O.includes(_))J.current.delete(z)}}),K=L4((O)=>{Q((z)=>({...z,cursorPosition:Math.max(0,Math.min(O,z.value.length))}))}),q=L4(()=>{Q({value:"",cursorPosition:0}),J.current.clear()}),W=L4((O)=>{X.current+=1;let z=X.current;return J.current.set(z,{type:"text",data:O}),z}),U=L4((O,z)=>{X.current+=1;let _=X.current;return J.current.set(_,{type:"image",data:O,mimeType:z}),_}),H=L4((O)=>{for(let[z,_]of O)if(J.current.set(z,_),z>=X.current)X.current=z}),F=L4((O)=>{let z=[],_=[];if(!Yw(O)){let C=O.trim();if(C)_.push({type:"text",text:C});return{displayText:O,text:O,images:z,parts:_}}let B=new RegExp(`${s9}PASTE:(\\d+):[\\s\\S]*?${t9}`,"g"),L=Array.from(O.matchAll(B)),w=0,N="",D="";for(let C of L){let d=C.index,e=d+C[0].length,k=parseInt(C[1],10),T=J.current.get(k);if(d>w){let g=O.slice(w,d);_.push({type:"text",text:g}),N+=g,D+=g}if(!T)N+=C[0],D+=C[0],_.push({type:"text",text:C[0]});else if(T.type==="text")N+=T.data,D+=T.data,_.push({type:"text",text:T.data});else{let g={id:k,base64:T.data,mimeType:T.mimeType};z.push(g),_.push({type:"image",...g}),D+=`[Image #${k}]`}w=e}if(w<O.length){let C=O.slice(w);_.push({type:"text",text:C}),N+=C,D+=C}let V=[];for(let C of _)if(C.type==="text"&&V.length>0&&V[V.length-1].type==="text")V[V.length-1].text+=C.text;else V.push(C);let I=0,v=V.length;while(I<V.length&&V[I].type==="text"&&V[I].text.trim()==="")I++;while(v>I&&V[v-1].type==="text"&&V[v-1].text.trim()==="")v--;let b=V.slice(I,v);return{displayText:D.trim(),text:N.trim(),images:z,parts:b}});return{value:Y.value,cursorPosition:Y.cursorPosition,setValue:G,setCursorPosition:K,clear:q,pasteMap:J.current,addPasteMapping:W,addImagePasteMapping:U,restorePasteMappings:H,resolveInput:F}}O$();O3();import{useMemoizedFn as vW}from"ahooks";import{useInput as Ww}from"ink";import{useEffect as EW,useRef as PW,useState as DZ}from"react";T9();b9();import Qw from"fast-glob";import Xw from"fuse.js";import{useEffect as DW,useMemo as AZ,useState as RZ}from"react";var L3=null,Jw=5000;function Gw($,Z){let Y=[...$.matchAll(/(?:^|\s)(@(?:"[^"]*"|(?:[^\\ ]|\\ )*))/g)];for(let Q of Y){let X=Q[1],J=Q.index+(Q[0].length-X.length),G=J+X.length;if(Z>=J&&Z<=G){let K=X.slice(1),q=!1;if(K.startsWith('"')){if(q=!0,K=K.slice(1),K.endsWith('"'))K=K.slice(0,-1)}return{hasQuery:!0,query:K,startIndex:J,endIndex:G,quoted:q}}}return{hasQuery:!1,query:"",startIndex:-1,endIndex:-1,quoted:!1}}var Kw=[...g1.map(($)=>`${$}/**`),...g1,...q5.map(($)=>`**/${$}`)];function MW($,Z,Y={}){let{cwd:Q=process.cwd(),maxSuggestions:X=15,ignorePatterns:J=Kw,debounceDelay:G=300,fuzzyMatch:K=!0}=Y,[q,W]=RZ([]),[U,H]=RZ(!1),[F,O]=RZ(0),z=AZ(()=>JSON.stringify(J),[J]),_=AZ(()=>{if(Z===void 0)return{hasQuery:!1,query:"",startIndex:-1,endIndex:-1,quoted:!1};return Gw($,Z)},[$,Z]);DW(()=>{if(!$.includes("@")){W([]),H(!1);return}let L=Date.now();if(L3&&L3.cwd===Q&&L3.ignoreKey===z&&L-L3.timestamp<Jw){W(L3.files),H(!1);return}let w=!1,D=setTimeout(async()=>{H(!0);try{let I=(await Qw("**/*",{cwd:Q,dot:!1,followSymbolicLinks:!1,onlyFiles:!1,markDirectories:!0,unique:!0,ignore:J})).map((v)=>v.replace(/\\/g,"/"));if(!w)W(I),L3={cwd:Q,ignoreKey:z,files:I,timestamp:L}}catch(V){if(console.error("Failed to load files for @ completion:",V),!w)W([])}finally{if(!w)H(!1)}},G);return()=>{w=!0,clearTimeout(D)}},[$,Q,G,z]);let B=AZ(()=>{if(!_.hasQuery||q.length===0)return[];let L=_.query.toLowerCase();if(L==="")return q.slice(0,X);if(K)return new Xw(q,{threshold:0.4,ignoreLocation:!0,minMatchCharLength:1}).search(L).slice(0,X).map((D)=>D.item);return q.filter((w)=>w.toLowerCase().includes(L)).slice(0,X)},[_,q,X,K]);return DW(()=>{O(0)},[B]),{..._,suggestions:B,selectedIndex:F,loading:U}}function qw($,Z=!1){if($.includes(" ")||Z)return`@"${$}"`;return`@${$}`}function VZ($,Z,Y){if(!Z.hasQuery)return{newInput:$,newCursorPos:$.length};let Q=qw(Y,Z.quoted),X=$.slice(0,Z.startIndex),J=$.slice(Z.endIndex),G=X+Q+" "+J,K=Z.startIndex+Q.length+1;return{newInput:G,newCursorPos:K}}import{useMemoizedFn as jW}from"ahooks";import{useEffect as IW,useRef as yW}from"react";k$();var Q0=($,Z)=>{let Y=yW(!1),Q=yW(null),X=jW(()=>{if(Q.current)clearTimeout(Q.current);Q.current=setTimeout(()=>{$2().setAwaitingSecondCtrlC(!1),Y.current=!1,Q.current=null},3000)}),J=()=>{B4().shutdown("SIGINT",0)},G=jW(()=>{if(!Y.current){if(Y.current=!0,$&&Z)Z();$2().setAwaitingSecondCtrlC(!0),X()}else{if(Q.current)clearTimeout(Q.current),Q.current=null;$2().setAwaitingSecondCtrlC(!1),J()}});return IW(()=>{if($){if($2().setAwaitingSecondCtrlC(!1),Y.current=!1,Q.current)clearTimeout(Q.current),Q.current=null}},[$]),IW(()=>{return()=>{if(Q.current)clearTimeout(Q.current)}},[]),G};var $6=l("UI"),TW=($,Z,Y,Q,X,J,G,K,q,W)=>{let H=Z1()==="main-input",F=$.value,O=$.setValue,z=$.cursorPosition,_=S2(),B=k2(),L=r9(),w=L?X3(L):!1,[N,D]=DZ(!1),[V,I]=DZ([]),[v,b]=DZ(0),C=MW(F,z,{cwd:process.cwd(),maxSuggestions:10}),d=Q0(G||!1,J),e=PW(0),k=500,T=PW(!1);EW(()=>{if(G)T.current=!1},[G]),EW(()=>{if(C.hasQuery&&C.suggestions.length>0){let M=C.suggestions.map((R)=>({command:R,description:CX(R)?`Directory: ${R}`:`File: ${R}`,matchScore:1}));I(M),D(!0),b(0)}else if(F.startsWith("/"))if(F.includes(" "))D(!1),I([]);else{let R=yq(F);I(R),D(R.length>0),b(0)}else D(!1),I([])},[F,C.hasQuery,C.suggestions]);let g=vW(()=>{_.clearMessages(),_.setError(null)}),j=vW(()=>{$6.debug("[DIAG] handleSubmit called:",{input:F,showSuggestions:N});let M=F.trim();if(M){let R=$.resolveInput(M);$6.debug("[DIAG] Submitting command:",{displayText:M,textLength:R.text.length,imageCount:R.images.length}),D(!1),I([]);let n=$.pasteMap.size>0?new Map($.pasteMap):new Map;X(M,n),$.clear(),Z(R),$6.debug("[DIAG] Command submitted to onSubmit callback")}else $6.debug("[DIAG] Empty command, not submitting")});return Ww((M,R)=>{if(M==="?"&&!F){q?.(),setTimeout(()=>$.clear(),0);return}if(R.backspace||R.delete||R.leftArrow||R.rightArrow||R.pageUp||R.pageDown||!R.ctrl&&!R.meta&&!R.escape&&!R.tab&&!R.upArrow&&!R.downArrow&&!R.return&&!(M==="?"&&!F))return;if(R.ctrl&&M==="c"||R.meta&&M==="c"||R.ctrl&&M==="d"||R.meta&&M==="d"){d();return}if(R.ctrl&&M==="l"||R.meta&&M==="l"){g();return}if(R.ctrl&&M==="t"||R.meta&&M==="t"){_.toggleThinkingExpanded();return}if(R.ctrl&&M==="o"||R.meta&&M==="o"){_.toggleHistoryExpanded();return}if(R.escape){if(W)q?.();else if(G&&J){if(T.current)return;T.current=!0,J()}else if(N)D(!1),I([]);else if(F){let y=Date.now();if(y-e.current<500)$.clear(),e.current=0;else e.current=y}return}if(R.tab&&R.shift){K?.();return}if(R.tab){if(N&&V.length>0){let y=V[v].command;if(C.hasQuery&&C.suggestions.includes(y)){let{newInput:u,newCursorPos:s}=VZ(F,C,y);O(u),$.setCursorPosition(s)}else{let u=y+" ";O(u),$.setCursorPosition(u.length)}D(!1),I([])}else if(w)B.toggleThinkingMode();return}if(R.return){if(N&&V.length>0){let y=V[v].command;if(C.hasQuery&&C.suggestions.includes(y)){let{newInput:u,newCursorPos:s}=VZ(F,C,y);O(u),$.setCursorPosition(s)}else{let u=y+" ";O(u),$.setCursorPosition(u.length)}D(!1),I([])}else j();return}if(R.upArrow){if(N&&V.length>0){let y=V.length-1;b((u)=>u>0?u-1:y)}else{let y=Y();if(y){if(y.pasteMappings.size>0)$.restorePasteMappings(y.pasteMappings);O(y.display),$.setCursorPosition(y.display.length)}}return}if(R.downArrow){if(N&&V.length>0){let y=V.length-1;b((u)=>u<y?u+1:0)}else{let y=Q();if(y){if(y.pasteMappings.size>0)$.restorePasteMappings(y.pasteMappings);O(y.display),$.setCursorPosition(y.display.length)}}return}},{isActive:H}),{handleSubmit:j,showSuggestions:N,suggestions:V,selectedSuggestionIndex:v}};import zw from"ansi-escapes";import{useStdout as _w}from"ink";import{useCallback as Bw,useEffect as Lw,useRef as ww}from"react";import{useStdout as Uw}from"ink";import{debounce as Hw}from"lodash-es";import{useEffect as Fw,useState as Ow}from"react";function w3($=200){let{stdout:Z}=Uw(),[Y,Q]=Ow(Z.columns||80);return Fw(()=>{let X=Hw(()=>{Q(Z.columns||80)},$);return X(),Z.on("resize",X),()=>{Z.off("resize",X),X.cancel()}},[Z,$]),Y}function CW(){let{stdout:$}=_w(),Z=w3(),Y=ww(!0),Q=b$((J)=>J.session.actions.incrementClearCount),X=Bw(()=>{if($)$.write(zw.clearTerminal);Q()},[$,Q]);return Lw(()=>{if(Y.current){Y.current=!1;return}let J=setTimeout(()=>{X()},300);return()=>{clearTimeout(J)}},[Z,X]),{refreshStatic:X}}X2();import SW from"node:fs";import Nw from"node:os";import MZ from"node:path";import{MultiSelect as bw}from"@inkjs/ui";import{useMemoizedFn as Z6}from"ahooks";import{Box as W$,Text as $$,useFocus as Aw,useFocusManager as Rw,useInput as fW}from"ink";import Y6 from"ink-select-input";import Vw from"ink-spinner";import V8 from"ink-text-input";import{useEffect as kW,useState as N3}from"react";import{jsxDEV as S}from"react/jsx-dev-runtime";var Dw=[{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"}],Mw=[{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 jw($){if(!$||$.trim()==="")return"名称不能为空";if(!/^[a-z0-9-]+$/.test($))return"名称只能包含小写字母、数字和连字符";if($.startsWith("-")||$.endsWith("-"))return"名称不能以连字符开头或结尾";return null}function D8({onComplete:$,onCancel:Z,initialConfig:Y}){let[Q,X]=N3(Y?"name":"mode"),[J,G]=N3({name:Y?.name||"",description:Y?.description||"",tools:Y?.tools||[],color:Y?.color,location:Y?.location||"project",systemPrompt:Y?.systemPrompt||""}),[K,q]=N3(""),[W,U]=N3(!1),[H,F]=N3(""),[O,z]=N3(Y?"edit":"manual"),{focus:_}=Rw(),L={manual:["mode","name","description","tools","color","location","systemPrompt","confirm"],ai:["mode","aiPrompt","aiGenerating","confirm"],edit:["name","description","tools","color","location","systemPrompt","confirm"]}[O];kW(()=>{if(Q==="name"||Q==="description"||Q==="systemPrompt"||Q==="aiPrompt")return;_(`step-${Q}`)},[Q,_]);let w=Z6(()=>{let v=L.indexOf(Q);if(v<L.length-1)X(L[v+1])}),N=Z6(()=>{if(H)F("");if(Q==="confirm"&&O==="ai"){X("aiPrompt");return}let v=L.indexOf(Q);if(v>0)X(L[v-1]);else Z()}),D=Z6(async()=>{U(!0),F("");try{let v=await O0.create(),b=`你是一个 Subagent 配置生成专家。用户会描述他们想要创建的 agent,你需要根据描述生成一个完整的 agent 配置。
2750
+ </user-prompt-submit-hook>`});let G$={messages:w$,userId:"cli-user",sessionId:G,workspaceRoot:process.cwd(),signal:Y$.signal,confirmationHandler:Y,permissionMode:K},N$=0,X0=0,G0=0,_4={stream:!0,onContentDelta:(K$)=>{N$++,X0+=K$.length,F1("useCommandHandler","onContentDelta",{callCount:N$,deltaLen:K$.length,totalLen:X0}),C(K$)},onThinkingDelta:q?(K$)=>{d(K$)}:void 0,onThinking:q?(K$)=>{W.setCurrentThinkingContent(K$)}:void 0,onStreamEnd:()=>{if(F1("useCommandHandler","onStreamEnd",{contentDeltaCallCount:N$,contentDeltaTotalLen:X0,remainingBuffer:w.current.length}),N.current)clearTimeout(N.current),N.current=null;if(V.current)clearTimeout(V.current),V.current=null;let K$=w.current,e$=D.current;w.current="",D.current="";let L$=q$().session.currentStreamingMessageId;if(L$){if(K$)u6(L$,K$);g6(L$)}W.finalizeStreamingMessage(K$,e$)},onContent:(K$)=>{if(G0++,!K$.trim())return;F1("useCommandHandler","onContent (non-stream)",{callCount:G0,contentLen:K$.length}),W.addAssistantMessageAndClearThinking(K$)},onToolStart:(K$)=>{if(K$.type!=="function")return;if(K$.function.name==="TodoWrite")return;try{let e$=JSON.parse(K$.function.arguments),L$=N3(K$.function.name,e$);W.addToolMessage(L$,{toolName:K$.function.name,phase:"start",summary:L$,params:e$})}catch(e$){BW.error("[useCommandHandler] onToolStart error:",e$)}},onToolResult:async(K$,e$)=>{if(K$.type!=="function")return;let L$=e$.metadata?.summary;if(!L$)return;let o1;if(Xq(K$.function.name,e$))o1=Jq(K$.function.name,e$)||e$.displayContent;W.addToolMessage(L$,{toolName:K$.function.name,phase:"complete",summary:L$,detail:o1})},onTokenUsage:(K$)=>{W.updateTokenUsage(K$)},onCompacting:(K$)=>{if(W.setCompacting(K$),!K$)W.resetTokenUsage()},onTurnLimitReached:Y?async(K$)=>{let e$=await Y.requestConfirmation({type:"maxTurnsExceeded",title:"对话轮次上限",message:`已进行 ${K$.turnsCount} 轮对话。是否继续?`,risks:["继续执行可能导致更长的等待时间","可能产生更多的 API 费用"]});return{continue:e$.approved,reason:e$.reason}}:void 0},T0=await f.chat(i,G$,_4);if(!T0||T0.trim()===""){if(!F.current&&N$===0)return W.addAssistantMessage("⏹ 已取消"),{success:!0,output:"已取消"};return{success:!0,output:T0??""}}return{success:!0,output:T0}}catch(n){if(F.current)return{success:!1,error:"aborted"};let y=n instanceof Error?n.message:"未知错误",u=y.includes("can only concatenate str")||y.includes("image_url")||y.includes("multimodal")||y.includes("vision")||y.includes("does not support images"),s=y;if(u)s="当前模型不支持图片理解功能。请切换到支持视觉能力的模型(如 Claude 4.5、GPT-5.2、Gemini 3 Pro、Qwen3-VL-Plus 等)后重试。";let i={success:!1,error:s};return W.addAssistantMessage(`❌ ${s}`),i}}),g=h4(async(j)=>{if(!j.text.trim()&&j.images.length===0)return;if(X){H.enqueueCommand({displayText:j.displayText,text:j.text,images:j.images,parts:j.parts});return}U.setTodos([]),F.current=!1;let M=H.createAbortController();e(),W.clearFinalizingStreamingMessageId(),H.setProcessing(!0);try{let R=await T(j);if(!R.success&&R.error&&R.error!=="aborted")W.setError(R.error)}catch(R){if(R instanceof Error&&(R.name==="AbortError"||R.message.includes("aborted")));else{let n=R instanceof Error?R.message:"未知错误";W.setError(`执行失败: ${n}`)}}finally{if(H.getAbortController()===M){H.setProcessing(!1),H.clearAbortController(M),W.setCurrentThinkingContent(null);let y=H.dequeueCommand();if(y)setTimeout(()=>g({displayText:y.displayText,text:y.text,images:y.images,parts:y.parts}),100)}}});return{executeCommand:g,handleAbort:k,isProcessing:X}};import{useMemoizedFn as o9}from"ahooks";import{useState as wW}from"react";var NW=()=>{let[$,Z]=wW([]),[Y,Q]=wW(-1),X=o9((q,W)=>{let U={display:q,pasteMappings:W?new Map(W):new Map};Z((H)=>[...H,U]),Q(-1)}),J=o9(()=>{if($.length===0)return null;let q=Y===-1?$.length-1:Math.max(0,Y-1);return Q(q),$[q]||null}),G=o9(()=>{if(Y===-1)return null;let q=Y+1;if(q>=$.length)return Q(-1),null;else return Q(q),$[q]||null}),K=o9(()=>{Q(-1)});return{commandHistory:$,historyIndex:Y,addToHistory:X,getPreviousCommand:J,getNextCommand:G,resetHistoryIndex:K}};import{useMemoizedFn as bW}from"ahooks";import{useMemo as eL,useState as $w}from"react";var AW=()=>{let[$,Z]=$w({isVisible:!1,details:null,resolver:null}),Y=bW((J)=>{return new Promise((G)=>{Z({isVisible:!0,details:J,resolver:G})})}),Q=bW((J)=>{if($.resolver)$.resolver(J);Z({isVisible:!1,details:null,resolver:null})}),X=eL(()=>({requestConfirmation:Y}),[Y]);return{confirmationState:$,confirmationHandler:X,handleResponse:Q}};import{useMemoizedFn as L2}from"ahooks";import{useRef as RW,useState as Zw}from"react";var s9="␞",t9="␟";function e9($){return`${s9}PASTE:${$}:`}function bZ(){return t9}var dh=new RegExp(`${s9}PASTE:(\\d+):[\\s\\S]*?${t9}`,"g");function Yw($){return $.includes(s9)&&$.includes(t9)}function VW($="",Z=0){let[Y,Q]=Zw({value:$,cursorPosition:Z}),X=RW(0),J=RW(new Map),G=L2((O)=>{Q((z)=>({value:O,cursorPosition:z.cursorPosition}));for(let z of J.current.keys()){let _=e9(z);if(!O.includes(_))J.current.delete(z)}}),K=L2((O)=>{Q((z)=>({...z,cursorPosition:Math.max(0,Math.min(O,z.value.length))}))}),q=L2(()=>{Q({value:"",cursorPosition:0}),J.current.clear()}),W=L2((O)=>{X.current+=1;let z=X.current;return J.current.set(z,{type:"text",data:O}),z}),U=L2((O,z)=>{X.current+=1;let _=X.current;return J.current.set(_,{type:"image",data:O,mimeType:z}),_}),H=L2((O)=>{for(let[z,_]of O)if(J.current.set(z,_),z>=X.current)X.current=z}),F=L2((O)=>{let z=[],_=[];if(!Yw(O)){let C=O.trim();if(C)_.push({type:"text",text:C});return{displayText:O,text:O,images:z,parts:_}}let B=new RegExp(`${s9}PASTE:(\\d+):[\\s\\S]*?${t9}`,"g"),L=Array.from(O.matchAll(B)),w=0,N="",D="";for(let C of L){let d=C.index,e=d+C[0].length,k=parseInt(C[1],10),T=J.current.get(k);if(d>w){let g=O.slice(w,d);_.push({type:"text",text:g}),N+=g,D+=g}if(!T)N+=C[0],D+=C[0],_.push({type:"text",text:C[0]});else if(T.type==="text")N+=T.data,D+=T.data,_.push({type:"text",text:T.data});else{let g={id:k,base64:T.data,mimeType:T.mimeType};z.push(g),_.push({type:"image",...g}),D+=`[Image #${k}]`}w=e}if(w<O.length){let C=O.slice(w);_.push({type:"text",text:C}),N+=C,D+=C}let V=[];for(let C of _)if(C.type==="text"&&V.length>0&&V[V.length-1].type==="text")V[V.length-1].text+=C.text;else V.push(C);let I=0,v=V.length;while(I<V.length&&V[I].type==="text"&&V[I].text.trim()==="")I++;while(v>I&&V[v-1].type==="text"&&V[v-1].text.trim()==="")v--;let b=V.slice(I,v);return{displayText:D.trim(),text:N.trim(),images:z,parts:b}});return{value:Y.value,cursorPosition:Y.cursorPosition,setValue:G,setCursorPosition:K,clear:q,pasteMap:J.current,addPasteMapping:W,addImagePasteMapping:U,restorePasteMappings:H,resolveInput:F}}O$();O8();import{useMemoizedFn as vW}from"ahooks";import{useInput as Ww}from"ink";import{useEffect as EW,useRef as PW,useState as DZ}from"react";T9();b9();import Qw from"fast-glob";import Xw from"fuse.js";import{useEffect as DW,useMemo as AZ,useState as RZ}from"react";var L8=null,Jw=5000;function Gw($,Z){let Y=[...$.matchAll(/(?:^|\s)(@(?:"[^"]*"|(?:[^\\ ]|\\ )*))/g)];for(let Q of Y){let X=Q[1],J=Q.index+(Q[0].length-X.length),G=J+X.length;if(Z>=J&&Z<=G){let K=X.slice(1),q=!1;if(K.startsWith('"')){if(q=!0,K=K.slice(1),K.endsWith('"'))K=K.slice(0,-1)}return{hasQuery:!0,query:K,startIndex:J,endIndex:G,quoted:q}}}return{hasQuery:!1,query:"",startIndex:-1,endIndex:-1,quoted:!1}}var Kw=[...g1.map(($)=>`${$}/**`),...g1,...q5.map(($)=>`**/${$}`)];function MW($,Z,Y={}){let{cwd:Q=process.cwd(),maxSuggestions:X=15,ignorePatterns:J=Kw,debounceDelay:G=300,fuzzyMatch:K=!0}=Y,[q,W]=RZ([]),[U,H]=RZ(!1),[F,O]=RZ(0),z=AZ(()=>JSON.stringify(J),[J]),_=AZ(()=>{if(Z===void 0)return{hasQuery:!1,query:"",startIndex:-1,endIndex:-1,quoted:!1};return Gw($,Z)},[$,Z]);DW(()=>{if(!$.includes("@")){W([]),H(!1);return}let L=Date.now();if(L8&&L8.cwd===Q&&L8.ignoreKey===z&&L-L8.timestamp<Jw){W(L8.files),H(!1);return}let w=!1,D=setTimeout(async()=>{H(!0);try{let I=(await Qw("**/*",{cwd:Q,dot:!1,followSymbolicLinks:!1,onlyFiles:!1,markDirectories:!0,unique:!0,ignore:J})).map((v)=>v.replace(/\\/g,"/"));if(!w)W(I),L8={cwd:Q,ignoreKey:z,files:I,timestamp:L}}catch(V){if(console.error("Failed to load files for @ completion:",V),!w)W([])}finally{if(!w)H(!1)}},G);return()=>{w=!0,clearTimeout(D)}},[$,Q,G,z]);let B=AZ(()=>{if(!_.hasQuery||q.length===0)return[];let L=_.query.toLowerCase();if(L==="")return q.slice(0,X);if(K)return new Xw(q,{threshold:0.4,ignoreLocation:!0,minMatchCharLength:1}).search(L).slice(0,X).map((D)=>D.item);return q.filter((w)=>w.toLowerCase().includes(L)).slice(0,X)},[_,q,X,K]);return DW(()=>{O(0)},[B]),{..._,suggestions:B,selectedIndex:F,loading:U}}function qw($,Z=!1){if($.includes(" ")||Z)return`@"${$}"`;return`@${$}`}function VZ($,Z,Y){if(!Z.hasQuery)return{newInput:$,newCursorPos:$.length};let Q=qw(Y,Z.quoted),X=$.slice(0,Z.startIndex),J=$.slice(Z.endIndex),G=X+Q+" "+J,K=Z.startIndex+Q.length+1;return{newInput:G,newCursorPos:K}}import{useMemoizedFn as jW}from"ahooks";import{useEffect as IW,useRef as yW}from"react";k$();var Q0=($,Z)=>{let Y=yW(!1),Q=yW(null),X=jW(()=>{if(Q.current)clearTimeout(Q.current);Q.current=setTimeout(()=>{$4().setAwaitingSecondCtrlC(!1),Y.current=!1,Q.current=null},3000)}),J=()=>{B2().shutdown("SIGINT",0)},G=jW(()=>{if(!Y.current){if(Y.current=!0,$&&Z)Z();$4().setAwaitingSecondCtrlC(!0),X()}else{if(Q.current)clearTimeout(Q.current),Q.current=null;$4().setAwaitingSecondCtrlC(!1),J()}});return IW(()=>{if($){if($4().setAwaitingSecondCtrlC(!1),Y.current=!1,Q.current)clearTimeout(Q.current),Q.current=null}},[$]),IW(()=>{return()=>{if(Q.current)clearTimeout(Q.current)}},[]),G};var $6=l("UI"),TW=($,Z,Y,Q,X,J,G,K,q,W)=>{let H=Z1()==="main-input",F=$.value,O=$.setValue,z=$.cursorPosition,_=S4(),B=k4(),L=r9(),w=L?X8(L):!1,[N,D]=DZ(!1),[V,I]=DZ([]),[v,b]=DZ(0),C=MW(F,z,{cwd:process.cwd(),maxSuggestions:10}),d=Q0(G||!1,J),e=PW(0),k=500,T=PW(!1);EW(()=>{if(G)T.current=!1},[G]),EW(()=>{if(C.hasQuery&&C.suggestions.length>0){let M=C.suggestions.map((R)=>({command:R,description:CX(R)?`Directory: ${R}`:`File: ${R}`,matchScore:1}));I(M),D(!0),b(0)}else if(F.startsWith("/"))if(F.includes(" "))D(!1),I([]);else{let R=yq(F);I(R),D(R.length>0),b(0)}else D(!1),I([])},[F,C.hasQuery,C.suggestions]);let g=vW(()=>{_.clearMessages(),_.setError(null)}),j=vW(()=>{$6.debug("[DIAG] handleSubmit called:",{input:F,showSuggestions:N});let M=F.trim();if(M){let R=$.resolveInput(M);$6.debug("[DIAG] Submitting command:",{displayText:M,textLength:R.text.length,imageCount:R.images.length}),D(!1),I([]);let n=$.pasteMap.size>0?new Map($.pasteMap):new Map;X(M,n),$.clear(),Z(R),$6.debug("[DIAG] Command submitted to onSubmit callback")}else $6.debug("[DIAG] Empty command, not submitting")});return Ww((M,R)=>{if(M==="?"&&!F){q?.(),setTimeout(()=>$.clear(),0);return}if(R.backspace||R.delete||R.leftArrow||R.rightArrow||R.pageUp||R.pageDown||!R.ctrl&&!R.meta&&!R.escape&&!R.tab&&!R.upArrow&&!R.downArrow&&!R.return&&!(M==="?"&&!F))return;if(R.ctrl&&M==="c"||R.meta&&M==="c"||R.ctrl&&M==="d"||R.meta&&M==="d"){d();return}if(R.ctrl&&M==="l"||R.meta&&M==="l"){g();return}if(R.ctrl&&M==="t"||R.meta&&M==="t"){_.toggleThinkingExpanded();return}if(R.ctrl&&M==="o"||R.meta&&M==="o"){_.toggleHistoryExpanded();return}if(R.escape){if(W)q?.();else if(G&&J){if(T.current)return;T.current=!0,J()}else if(N)D(!1),I([]);else if(F){let y=Date.now();if(y-e.current<500)$.clear(),e.current=0;else e.current=y}return}if(R.tab&&R.shift){K?.();return}if(R.tab){if(N&&V.length>0){let y=V[v].command;if(C.hasQuery&&C.suggestions.includes(y)){let{newInput:u,newCursorPos:s}=VZ(F,C,y);O(u),$.setCursorPosition(s)}else{let u=y+" ";O(u),$.setCursorPosition(u.length)}D(!1),I([])}else if(w)B.toggleThinkingMode();return}if(R.return){if(N&&V.length>0){let y=V[v].command;if(C.hasQuery&&C.suggestions.includes(y)){let{newInput:u,newCursorPos:s}=VZ(F,C,y);O(u),$.setCursorPosition(s)}else{let u=y+" ";O(u),$.setCursorPosition(u.length)}D(!1),I([])}else j();return}if(R.upArrow){if(N&&V.length>0){let y=V.length-1;b((u)=>u>0?u-1:y)}else{let y=Y();if(y){if(y.pasteMappings.size>0)$.restorePasteMappings(y.pasteMappings);O(y.display),$.setCursorPosition(y.display.length)}}return}if(R.downArrow){if(N&&V.length>0){let y=V.length-1;b((u)=>u<y?u+1:0)}else{let y=Q();if(y){if(y.pasteMappings.size>0)$.restorePasteMappings(y.pasteMappings);O(y.display),$.setCursorPosition(y.display.length)}}return}},{isActive:H}),{handleSubmit:j,showSuggestions:N,suggestions:V,selectedSuggestionIndex:v}};import zw from"ansi-escapes";import{useStdout as _w}from"ink";import{useCallback as Bw,useEffect as Lw,useRef as ww}from"react";import{useStdout as Uw}from"ink";import{debounce as Hw}from"lodash-es";import{useEffect as Fw,useState as Ow}from"react";function w8($=200){let{stdout:Z}=Uw(),[Y,Q]=Ow(Z.columns||80);return Fw(()=>{let X=Hw(()=>{Q(Z.columns||80)},$);return X(),Z.on("resize",X),()=>{Z.off("resize",X),X.cancel()}},[Z,$]),Y}function CW(){let{stdout:$}=_w(),Z=w8(),Y=ww(!0),Q=b$((J)=>J.session.actions.incrementClearCount),X=Bw(()=>{if($)$.write(zw.clearTerminal);Q()},[$,Q]);return Lw(()=>{if(Y.current){Y.current=!1;return}let J=setTimeout(()=>{X()},300);return()=>{clearTimeout(J)}},[Z,X]),{refreshStatic:X}}X4();import SW from"node:fs";import Nw from"node:os";import MZ from"node:path";import{MultiSelect as bw}from"@inkjs/ui";import{useMemoizedFn as Z6}from"ahooks";import{Box as W$,Text as $$,useFocus as Aw,useFocusManager as Rw,useInput as fW}from"ink";import Y6 from"ink-select-input";import Vw from"ink-spinner";import V3 from"ink-text-input";import{useEffect as kW,useState as N8}from"react";import{jsxDEV as S}from"react/jsx-dev-runtime";var Dw=[{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"}],Mw=[{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 jw($){if(!$||$.trim()==="")return"名称不能为空";if(!/^[a-z0-9-]+$/.test($))return"名称只能包含小写字母、数字和连字符";if($.startsWith("-")||$.endsWith("-"))return"名称不能以连字符开头或结尾";return null}function D3({onComplete:$,onCancel:Z,initialConfig:Y}){let[Q,X]=N8(Y?"name":"mode"),[J,G]=N8({name:Y?.name||"",description:Y?.description||"",tools:Y?.tools||[],color:Y?.color,location:Y?.location||"project",systemPrompt:Y?.systemPrompt||""}),[K,q]=N8(""),[W,U]=N8(!1),[H,F]=N8(""),[O,z]=N8(Y?"edit":"manual"),{focus:_}=Rw(),L={manual:["mode","name","description","tools","color","location","systemPrompt","confirm"],ai:["mode","aiPrompt","aiGenerating","confirm"],edit:["name","description","tools","color","location","systemPrompt","confirm"]}[O];kW(()=>{if(Q==="name"||Q==="description"||Q==="systemPrompt"||Q==="aiPrompt")return;_(`step-${Q}`)},[Q,_]);let w=Z6(()=>{let v=L.indexOf(Q);if(v<L.length-1)X(L[v+1])}),N=Z6(()=>{if(H)F("");if(Q==="confirm"&&O==="ai"){X("aiPrompt");return}let v=L.indexOf(Q);if(v>0)X(L[v-1]);else Z()}),D=Z6(async()=>{U(!0),F("");try{let v=await O0.create(),b=`你是一个 Subagent 配置生成专家。用户会描述他们想要创建的 agent,你需要根据描述生成一个完整的 agent 配置。
2751
2751
 
2752
2752
  ## 可用工具列表
2753
2753
 
@@ -2823,34 +2823,34 @@ ${u}
2823
2823
 
2824
2824
  **重要**:请直接返回 JSON,不要添加任何额外的解释或文字。`,K)).trim(),e=d.match(/```(?:json)?\s*\n([\s\S]*?)\n```/);if(e)d=e[1];let k=JSON.parse(d);if(!k.name||!k.description||!k.systemPrompt)throw Error("Missing required fields: name, description, or systemPrompt");if(!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(k.name))throw Error("Invalid name format. Must be kebab-case (lowercase, numbers, hyphens only)");G({name:k.name,description:k.description,tools:Array.isArray(k.tools)?k.tools:[],color:k.color||"blue",location:"project",systemPrompt:k.systemPrompt}),X("confirm")}catch(v){F(v instanceof Error?v.message:String(v))}finally{U(!1)}});kW(()=>{if(Q==="aiGenerating"&&!W&&!H)D()},[Q,W,H,D]);let V=Z6(async()=>{try{let v=J.location==="project"?MZ.join(process.cwd(),".blade","agents"):MZ.join(Nw.homedir(),".blade","agents");await SW.promises.mkdir(v,{recursive:!0});let b=["---",`name: ${J.name}`,`description: ${J.description}`];if(J.tools.length>0&&!J.tools.includes("all")){b.push("tools:");for(let e of J.tools)b.push(` - ${e}`)}if(J.color)b.push(`color: ${J.color}`);b.push("---");let C=[b.join(`
2825
2825
  `),"",`# ${J.name} Subagent`,"",J.systemPrompt||"你是一个专门的代理,负责执行特定任务。",""].join(`
2826
- `),d=MZ.join(v,`${J.name}.md`);await SW.promises.writeFile(d,C,"utf-8"),$()}catch(v){console.error("保存配置失败:",v)}}),I=Q0(!1,Z);if(fW((v,b)=>{if(b.escape)N();else if(b.ctrl&&v==="c"||b.meta&&v==="c")I()},{isActive:Q!=="tools"}),Q==="mode")return S(W$,{flexDirection:"column",paddingY:1,children:[S(W$,{marginBottom:1,children:S($$,{bold:!0,color:"cyan",children:"\uD83C\uDFAF 选择创建方式"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:S($$,{dimColor:!0,children:"你可以手动配置每个细节,或让 AI 根据你的描述自动生成配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(Y6,{items:[{label:"\uD83E\uDD16 AI 智能生成 - 根据描述自动生成完整配置",value:"ai"},{label:"✍️ 手动配置 - 逐步配置每个选项",value:"manual"}],onSelect:(v)=>{if(v.value==="ai")z("ai"),X("aiPrompt");else z("manual"),X("name")}},void 0,!1,void 0,this),S(W$,{marginTop:1,children:S($$,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 取消"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="aiPrompt")return S(W$,{flexDirection:"column",paddingY:1,children:[S(W$,{marginBottom:1,children:S($$,{bold:!0,color:"cyan",children:"\uD83E\uDD16 AI 智能生成"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:S($$,{dimColor:!0,children:'描述你想要创建的 Agent(例如:"一个专门用于代码审查的 agent,能够分析代码质量和潜在bug")'},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:[S($$,{color:"green",children:"描述: "},void 0,!1,void 0,this),S(V8,{value:K,onChange:q,onSubmit:(v)=>{if(!v.trim())return;X("aiGenerating")}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),S(W$,{children:S($$,{dimColor:!0,children:"按 Enter 开始生成 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="aiGenerating"){if(H)return S(W$,{flexDirection:"column",paddingY:1,children:[S(W$,{marginBottom:1,children:S($$,{bold:!0,color:"red",children:"❌ AI 生成失败"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:S($$,{color:"red",children:H},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:S($$,{dimColor:!0,children:"按 ESC 返回修改描述"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return S(W$,{flexDirection:"column",paddingY:1,children:[S(W$,{marginBottom:1,children:S($$,{bold:!0,color:"yellow",children:[S(Vw,{type:"dots"},void 0,!1,void 0,this)," AI 正在生成配置..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:S($$,{dimColor:!0,children:['根据你的描述:"',K,'"']},void 0,!0,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:S($$,{color:"gray",children:"正在调用 LLM 生成 agent 配置,请稍候..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}if(Q==="name"){let v=O==="edit";return S(W$,{flexDirection:"column",paddingY:1,children:[S(W$,{marginBottom:1,children:S($$,{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),S(W$,{marginBottom:1,children:S($$,{dimColor:!0,children:v?"编辑模式下名称不可修改(修改名称相当于创建新 Agent)":"名称只能包含小写字母、数字和连字符(例如:code-reviewer)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:[S($$,{color:"green",children:"名称: "},void 0,!1,void 0,this),v?S($$,{children:J.name},void 0,!1,void 0,this):S(V8,{value:J.name,onChange:(b)=>G({...J,name:b}),onSubmit:(b)=>{if(jw(b))return;w()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),S(W$,{children:S($$,{dimColor:!0,children:v?"按 Enter 继续 | ESC 返回":"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v&&S(V8,{value:"",onChange:()=>{},onSubmit:w,showCursor:!1},"edit-mode-dummy-input",!1,void 0,this)]},void 0,!0,void 0,this)}if(Q==="description")return S(W$,{flexDirection:"column",paddingY:1,children:[S(W$,{marginBottom:1,children:S($$,{bold:!0,color:"cyan",children:"\uD83D\uDCDD Step 2/7: 输入描述信息"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:S($$,{dimColor:!0,children:"简短描述这个 Agent 的用途和使用场景(这将帮助主 Agent 决定何时使用它)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:[S($$,{color:"green",children:"描述: "},void 0,!1,void 0,this),S(V8,{value:J.description,onChange:(v)=>G({...J,description:v}),onSubmit:(v)=>{if(!v.trim())return;w()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),S(W$,{children:S($$,{dimColor:!0,children:"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="tools")return S(Iw,{config:J,setConfig:G,onNext:w,onPrev:N},void 0,!1,void 0,this);if(Q==="color")return S(W$,{flexDirection:"column",paddingY:1,children:[S(W$,{marginBottom:1,children:S($$,{bold:!0,color:"cyan",children:"\uD83C\uDFA8 Step 4/7: 选择背景颜色"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:S($$,{dimColor:!0,children:"为 Agent 选择一个颜色标识(用于在 UI 中区分不同的 Agents)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(Y6,{items:Mw,onSelect:(v)=>{let b=v.value==="none"?void 0:v.value;G({...J,color:b}),w()}},void 0,!1,void 0,this),S(W$,{marginTop:1,children:S($$,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="location")return S(W$,{flexDirection:"column",paddingY:1,children:[S(W$,{marginBottom:1,children:S($$,{bold:!0,color:"cyan",children:"\uD83D\uDCC2 Step 5/7: 选择保存位置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:S($$,{dimColor:!0,children:"项目级配置仅在当前项目生效,用户级配置全局可用"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(Y6,{items:[{label:"\uD83D\uDCC1 项目级 (.blade/agents/) - 仅当前项目",value:"project"},{label:"\uD83C\uDFE0 用户级 (~/.blade/agents/) - 全局可用",value:"user"}],onSelect:(v)=>{G({...J,location:v.value}),w()}},void 0,!1,void 0,this),S(W$,{marginTop:1,children:S($$,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="systemPrompt")return S(W$,{flexDirection:"column",paddingY:1,children:[S(W$,{marginBottom:1,children:S($$,{bold:!0,color:"cyan",children:"\uD83D\uDCAC Step 6/7: 输入系统提示词"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:S($$,{dimColor:!0,children:"定义 Agent 的行为和职责(可选,留空将使用默认提示)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:[S($$,{color:"green",children:"提示词: "},void 0,!1,void 0,this),S(V8,{value:J.systemPrompt,onChange:(v)=>G({...J,systemPrompt:v}),onSubmit:()=>w()},void 0,!1,void 0,this)]},void 0,!0,void 0,this),S(W$,{children:S($$,{dimColor:!0,children:"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="confirm")return S(W$,{flexDirection:"column",paddingY:1,children:[S(W$,{marginBottom:1,children:S($$,{bold:!0,color:"cyan",children:"✅ Step 7/7: 确认配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{flexDirection:"column",paddingLeft:2,marginBottom:1,children:[S($$,{children:[S($$,{bold:!0,color:"green",children:["名称:"," "]},void 0,!0,void 0,this),S($$,{children:J.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),S($$,{children:[S($$,{bold:!0,color:"green",children:["描述:"," "]},void 0,!0,void 0,this),S($$,{children:J.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),S($$,{children:[S($$,{bold:!0,color:"green",children:["工具:"," "]},void 0,!0,void 0,this),S($$,{children:J.tools.includes("all")?"所有工具":J.tools.join(", ")||"所有工具"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),S($$,{children:[S($$,{bold:!0,color:"green",children:["颜色:"," "]},void 0,!0,void 0,this),S($$,{children:J.color||"默认"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),S($$,{children:[S($$,{bold:!0,color:"green",children:["位置:"," "]},void 0,!0,void 0,this),S($$,{children:J.location==="project"?"项目级":"用户级"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),S($$,{children:[S($$,{bold:!0,color:"green",children:["提示词:"," "]},void 0,!0,void 0,this),S($$,{children:J.systemPrompt||"(使用默认)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),S(Y6,{items:[{label:"✅ 确认并保存",value:"save"},{label:"⬅️ 返回上一步",value:"back"},{label:"❌ 取消",value:"cancel"}],onSelect:(v)=>{if(v.value==="save")V();else if(v.value==="back")N();else Z()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}function Iw({config:$,setConfig:Z,onNext:Y,onPrev:Q}){let{isFocused:X}=Aw({id:"step-tools"});fW((G,K)=>{if(K.escape)Q()},{isActive:X});let J=(G)=>{if(G.includes("all"))Z({...$,tools:["all"]});else Z({...$,tools:G});Y()};return S(W$,{flexDirection:"column",paddingY:1,children:[S(W$,{marginBottom:1,children:S($$,{bold:!0,color:"cyan",children:"\uD83D\uDD27 Step 3/7: 选择可用工具"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:S($$,{dimColor:!0,children:"方向键导航,空格切换勾选,Enter 确认进入下一步 | ESC 返回上一步"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(bw,{options:Dw,defaultValue:$.tools,onSubmit:J},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}U4();import yw from"node:fs";import{useMemoizedFn as N4}from"ahooks";import{Box as c$,Text as n$,useInput as vw}from"ink";import jZ from"ink-select-input";import{useEffect as Ew,useMemo as hW,useState as Q6}from"react";import{jsxDEV as o}from"react/jsx-dev-runtime";var IZ=10;function xW({initialMode:$="menu",onComplete:Z,onCancel:Y}){let[Q,X]=Q6($),[J,G]=Q6(null),[K,q]=Q6(0),[W,U]=Q6(0),H=N4(()=>{J0.clear(),J0.loadFromStandardLocations(),q((b)=>b+1)}),F=hW(()=>{return J0.getAllSubagents()},[K]),O=Math.ceil(F.length/IZ)||1,z=hW(()=>{let b=W*IZ;return F.slice(b,b+IZ)},[F,W]);Ew(()=>{let b=Math.max(0,O-1);if(W>b)U(b)},[O,W]);let _=N4(()=>{if(W<O-1)U((b)=>b+1)}),B=N4(()=>{if(W>0)U((b)=>b-1)}),L=[{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"}],w=N4((b)=>{if(b.value==="cancel"){Y?.();return}X(b.value)}),N=N4((b)=>{if(G(b.value),Q==="edit")X("editWizard");else if(Q==="delete")X("deleteConfirm")}),D=N4(async()=>{if(!J?.configPath)return;try{await yw.promises.unlink(J.configPath),H(),V()}catch(b){console.error("删除失败:",b)}}),V=N4(()=>{X("menu"),G(null)}),I=Q0(!1,Y);if(vw((b,C)=>{if(C.escape){if(Q==="menu")Y?.();else if(Q==="list"||Q==="edit"||Q==="delete")U(0),V();else if(Q==="deleteConfirm")V()}else if(C.ctrl&&b==="c"||C.meta&&b==="c")I();else if(Q==="list"){if(C.leftArrow||b==="h")B();else if(C.rightArrow||b==="l")_()}},{isActive:Q!=="create"&&Q!=="editWizard"}),Q==="menu")return o(c$,{flexDirection:"column",paddingY:1,children:[o(c$,{marginBottom:1,children:o(n$,{bold:!0,color:"cyan",children:"\uD83D\uDCCB Agents 管理"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(jZ,{items:L,onSelect:w},void 0,!1,void 0,this),o(c$,{marginTop:1,children:o(n$,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 退出"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="list"){if(F.length===0)return o(c$,{flexDirection:"column",paddingY:1,children:[o(c$,{marginBottom:1,children:o(n$,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(c$,{paddingLeft:2,children:o(n$,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(c$,{marginTop:1,paddingLeft:2,children:o(n$,{color:"gray",children:"\uD83D\uDCA1 配置文件位置: .blade/agents/ 或 ~/.blade/agents/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(c$,{marginTop:1,paddingLeft:2,children:o(n$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return o(c$,{flexDirection:"column",paddingY:1,children:[o(c$,{marginBottom:1,children:[o(n$,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this),o(n$,{color:"gray",children:[" (共 ",F.length," 个)"]},void 0,!0,void 0,this),O>1&&o(n$,{color:"yellow",children:[" ","第 ",W+1,"/",O," 页"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),z.map((b)=>o(c$,{flexDirection:"column",paddingLeft:2,children:[o(c$,{children:o(n$,{children:[o(n$,{bold:!0,color:b.color||"white",children:["• ",b.name]},void 0,!0,void 0,this),o(n$,{color:"gray",children:[" - ",b.description]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),b.tools&&b.tools.length>0&&o(c$,{paddingLeft:2,children:o(n$,{color:"gray",children:["工具: ",b.tools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),b.configPath&&o(c$,{paddingLeft:2,children:o(n$,{color:"gray",dimColor:!0,children:b.configPath},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},b.name,!0,void 0,this)),o(c$,{marginTop:1,paddingLeft:2,children:O>1?o(n$,{dimColor:!0,children:"← → 翻页 | ESC 返回菜单"},void 0,!1,void 0,this):o(n$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}let v=(b)=>{if(F.length===0)return o(c$,{flexDirection:"column",paddingY:1,children:[o(c$,{marginBottom:1,children:o(n$,{bold:!0,color:"cyan",children:b},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(c$,{paddingLeft:2,children:o(n$,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(c$,{marginTop:1,paddingLeft:2,children:o(n$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);let C=F.map((d)=>({key:d.name,label:`${d.name} - ${d.description}`,value:d}));return o(c$,{flexDirection:"column",paddingY:1,children:[o(c$,{marginBottom:1,children:o(n$,{bold:!0,color:"cyan",children:b},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(jZ,{items:C,onSelect:N},void 0,!1,void 0,this),o(c$,{marginTop:1,children:o(n$,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};if(Q==="create")return o(D8,{onComplete:()=>{H(),V()},onCancel:V},void 0,!1,void 0,this);if(Q==="edit")return v("✏️ 编辑 Agent");if(Q==="editWizard"&&J){let b={name:J.name,description:J.description,tools:J.tools||[],color:J.color,location:J.configPath?.includes(".blade/agents")?"project":"user",systemPrompt:J.systemPrompt||""};return o(D8,{initialConfig:b,onComplete:()=>{H(),V()},onCancel:V},void 0,!1,void 0,this)}if(Q==="delete")return v("\uD83D\uDDD1️ 删除 Agent");if(Q==="deleteConfirm"&&J)return o(c$,{flexDirection:"column",paddingY:1,children:[o(c$,{marginBottom:1,children:o(n$,{bold:!0,color:"red",children:"⚠️ 确认删除"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(c$,{marginBottom:1,paddingLeft:2,children:o(n$,{children:["你确定要删除 Agent"," ",o(n$,{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),o(c$,{marginBottom:1,paddingLeft:2,children:o(n$,{dimColor:!0,children:["文件路径: ",J.configPath]},void 0,!0,void 0,this)},void 0,!1,void 0,this),o(c$,{marginBottom:1,paddingLeft:2,children:o(n$,{color:"red",children:"此操作无法撤销!"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(jZ,{items:[{label:"\uD83D\uDDD1️ 确认删除",value:"confirm"},{label:"❌ 取消",value:"cancel"}],onSelect:(b)=>{if(b.value==="confirm")D();else V()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}U0();import{Box as b3,Text as o$}from"ink";import Tw from"react";T9();FZ();import{useEffect as Pw,useState as pW}from"react";function mW($=process.cwd(),Z=5000){let[Y,Q]=pW(null),[X,J]=pW(!0);return Pw(()=>{let G=!0,K=async()=>{try{let W=await _8($);if(!G)return;if(!W){Q(null),J(!1);return}let U=await mK($);if(!G)return;Q(U)}catch{if(G)Q(null)}finally{if(G)J(!1)}};K();let q=null;if(Z>0)q=setInterval(K,Z);return()=>{if(G=!1,q)clearInterval(q)}},[$,Z]),{branch:Y,loading:X}}import{jsxDEV as R$,Fragment as X6}from"react/jsx-dev-runtime";var dW=Tw.memo(()=>{let $=a9(),Z=B3(),Q=i9()==="shortcuts",X=tq(),{branch:J}=mW(),G=r9(),K=iq(),q=lq(),W=n9(),U=FW(),H=G?X3(G):!1,O=(()=>{if(Z==="default")return null;if(Z==="autoEdit")return R$(o$,{color:"magenta",children:["▶▶ auto edit on ",R$(o$,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="plan")return R$(o$,{color:"cyan",children:["‖ plan mode on ",R$(o$,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="yolo")return R$(o$,{color:"red",children:["⚡ yolo mode on ",R$(o$,{color:"gray",children:"(all tools auto-approved)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="spec"){let{phase:B,completed:L,total:w}=U,N;if(!B)N="init";else if((B==="tasks"||B==="implementation")&&w>0)N=`${B} ${L}/${w}`;else N=B;return R$(o$,{color:"blue",children:["\uD83D\uDCCB spec: ",N," ",R$(o$,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}return null})(),z=O!==null,_=[["Enter:发送","Shift+Enter:换行","Esc:中止"],["Shift+Tab:切换模式","↑/↓:历史","Tab:补全"],["Ctrl+A:行首","Ctrl+E:行尾","Ctrl+K:删到尾"],["Ctrl+U:删到首","Ctrl+W:删单词","Ctrl+C:退出"]];return R$(b3,{flexDirection:"row",justifyContent:"space-between",paddingX:2,paddingY:0,children:[Q?R$(b3,{flexDirection:"column",gap:0,children:_.map((B,L)=>R$(b3,{flexDirection:"row",children:[B.map((w,N)=>{let[D,V]=w.split(":");return R$(b3,{flexDirection:"row",width:20,children:[R$(o$,{color:"yellow",children:D},void 0,!1,void 0,this),R$(o$,{color:"gray",children:":"},void 0,!1,void 0,this),R$(o$,{color:"white",children:V},void 0,!1,void 0,this)]},N,!0,void 0,this)}),L===_.length-1&&R$(o$,{color:"cyan",children:" ? 关闭"},void 0,!1,void 0,this)]},L,!0,void 0,this))},void 0,!1,void 0,this):R$(b3,{flexDirection:"row",gap:1,children:[J&&R$(X6,{children:[R$(o$,{color:"gray",children:[" ",J]},void 0,!0,void 0,this),R$(o$,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),O,z&&R$(o$,{color:"gray",children:"·"},void 0,!1,void 0,this),R$(o$,{color:"gray",children:"? for shortcuts"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),R$(b3,{flexDirection:"row",gap:1,children:!$?R$(o$,{color:"red",children:"⚠ API 密钥未配置"},void 0,!1,void 0,this):R$(X6,{children:[H&&R$(X6,{children:[W?R$(o$,{color:"cyan",children:"Thinking on"},void 0,!1,void 0,this):R$(o$,{color:"gray",children:"Tab:Thinking"},void 0,!1,void 0,this),R$(o$,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G&&R$(o$,{color:"gray",children:G.model},void 0,!1,void 0,this),R$(o$,{color:"gray",children:"·"},void 0,!1,void 0,this),q?R$(o$,{color:"yellow",children:"压缩中..."},void 0,!1,void 0,this):R$(o$,{color:K<20?"red":K<50?"yellow":"gray",children:[K,"%"]},void 0,!0,void 0,this),X&&R$(X6,{children:[R$(o$,{color:"gray",children:"·"},void 0,!1,void 0,this),R$(o$,{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 yZ,Text as vZ}from"ink";import Cw from"react";import{jsxDEV as A3}from"react/jsx-dev-runtime";var uW=Cw.memo(({suggestions:$,selectedIndex:Z,visible:Y,maxDisplay:Q=8})=>{if(!Y||$.length===0)return null;let X=0,J=Math.min(Q,$.length),G=Z>=$.length;if(Z>=Q&&!G)X=Z-Q+1,J=Z+1;let K=$.slice(X,J),q=$.length>Q;return A3(yZ,{flexDirection:"column",paddingX:2,paddingY:0,children:[K.map((W,U)=>{let F=X+U===Z;return A3(yZ,{flexDirection:"row",paddingX:1,gap:2,children:[A3(vZ,{color:F?"cyan":"white",bold:F,children:W.command},void 0,!1,void 0,this),A3(vZ,{color:F?"cyan":"gray",dimColor:!F,children:["- ",W.description]},void 0,!0,void 0,this)]},W.command,!0,void 0,this)}),q&&A3(yZ,{paddingX:1,children:A3(vZ,{color:G?"cyan":"gray",bold:G,dimColor:!G,children:["... and ",$.length-Q," more"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});U0();import{Box as b1,Text as S1,useInput as KN,useStdout as qN}from"ink";import WN from"ink-select-input";import cZ,{useMemo as $U}from"react";import{Box as V$,Text as s$}from"ink";import R4,{useEffect as gZ,useMemo as D3,useRef as eW}from"react";C3();m6();import{Box as G6,Text as i1}from"ink";import{isPlainObject as SZ}from"lodash-es";import{common as xw,createLowlight as pw}from"lowlight";import aW from"react";r2();import{Box as J6,Text as M8}from"ink";import q2,{Fragment as lW}from"react";import Sw from"string-width";var gW=new Map,cW=1000;function PZ($){let Z=!0;for(let Q=0;Q<$.length;Q++)if($.charCodeAt(Q)>127){Z=!1;break}if(Z)return $.split("");if($.length<=cW){let Q=gW.get($);if(Q)return Q}let Y=Array.from($);if($.length<=cW)gW.set($,Y);return Y}var EZ=new Map;function K2($){if(/^[\x20-\x7E]*$/.test($))return $.length;if(EZ.has($))return EZ.get($);let Z=Sw($);return EZ.set($,Z),Z}import{jsxDEV as R3}from"react/jsx-dev-runtime";var TZ=2,iW=q2.memo(({children:$,maxWidth:Z,maxHeight:Y,overflowDirection:Q="top",additionalHiddenLinesCount:X=0})=>{let J=$0(),G=[],K=Math.max(Math.round(Y??Number.MAX_SAFE_INTEGER),TZ);function q(_){if(!q2.isValidElement(_))return;if(_.type===lW){q2.Children.forEach(_.props.children,q);return}if(_.type===J6){fw(_,Z,G);return}}q2.Children.forEach($,q);let U=G.length>K||X>0?K-1:K,H=U!==void 0?Math.max(0,G.length-U):0,F=H+X,z=(H>0?Q==="top"?G.slice(H):G.slice(0,U):G).map((_,B)=>R3(J6,{children:_.length>0?_.map((L,w)=>R3(M8,{...L.props,children:L.text},w,!1,void 0,this)):R3(M8,{children:" "},void 0,!1,void 0,this)},B,!1,void 0,this));return R3(J6,{flexDirection:"column",width:Z,flexShrink:0,children:[F>0&&Q==="top"&&R3(M8,{color:J.colors.text.muted,dimColor:!0,children:["... ",F," line",F===1?"":"s"," hidden ..."]},void 0,!0,void 0,this),z,F>0&&Q==="bottom"&&R3(M8,{color:J.colors.text.muted,dimColor:!0,children:["... ",F," line",F===1?"":"s"," hidden ..."]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});function kw($){if(!q2.isValidElement($)||$.type!==J6)return{noWrapSegments:[],segments:[]};let Z={noWrapSegments:[],segments:[]},Y=!1;function Q(X,J){if(X===null||X===void 0)return;if(typeof X==="string"||typeof X==="number"){let W=String(X);if(!W)return;let U={text:W,props:J??{}};if(J===void 0||J.wrap==="wrap")Y=!0,Z.segments.push(U);else if(!Y)Z.noWrapSegments.push(U);else Z.segments.push(U);return}if(!q2.isValidElement(X))return;if(X.type===lW){q2.Children.forEach(X.props.children,(W)=>Q(W,J));return}if(X.type!==M8)return;let{children:G,...K}=X.props,q=J===void 0?K:{...J,...K};q2.Children.forEach(G,(W)=>Q(W,q))}return q2.Children.forEach($.props.children,(X)=>Q(X,void 0)),Z}function fw($,Z,Y){let Q=kw($);if(Q.segments.length===0&&Q.noWrapSegments.length===0){Y.push([]);return}let X=0;for(let H of Q.noWrapSegments)X+=K2(H.text);if(Q.segments.length===0){let H=[],F=[];for(let O of Q.noWrapSegments){let z=O.text.split(`
2826
+ `),d=MZ.join(v,`${J.name}.md`);await SW.promises.writeFile(d,C,"utf-8"),$()}catch(v){console.error("保存配置失败:",v)}}),I=Q0(!1,Z);if(fW((v,b)=>{if(b.escape)N();else if(b.ctrl&&v==="c"||b.meta&&v==="c")I()},{isActive:Q!=="tools"}),Q==="mode")return S(W$,{flexDirection:"column",paddingY:1,children:[S(W$,{marginBottom:1,children:S($$,{bold:!0,color:"cyan",children:"\uD83C\uDFAF 选择创建方式"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:S($$,{dimColor:!0,children:"你可以手动配置每个细节,或让 AI 根据你的描述自动生成配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(Y6,{items:[{label:"\uD83E\uDD16 AI 智能生成 - 根据描述自动生成完整配置",value:"ai"},{label:"✍️ 手动配置 - 逐步配置每个选项",value:"manual"}],onSelect:(v)=>{if(v.value==="ai")z("ai"),X("aiPrompt");else z("manual"),X("name")}},void 0,!1,void 0,this),S(W$,{marginTop:1,children:S($$,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 取消"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="aiPrompt")return S(W$,{flexDirection:"column",paddingY:1,children:[S(W$,{marginBottom:1,children:S($$,{bold:!0,color:"cyan",children:"\uD83E\uDD16 AI 智能生成"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:S($$,{dimColor:!0,children:'描述你想要创建的 Agent(例如:"一个专门用于代码审查的 agent,能够分析代码质量和潜在bug")'},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:[S($$,{color:"green",children:"描述: "},void 0,!1,void 0,this),S(V3,{value:K,onChange:q,onSubmit:(v)=>{if(!v.trim())return;X("aiGenerating")}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),S(W$,{children:S($$,{dimColor:!0,children:"按 Enter 开始生成 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="aiGenerating"){if(H)return S(W$,{flexDirection:"column",paddingY:1,children:[S(W$,{marginBottom:1,children:S($$,{bold:!0,color:"red",children:"❌ AI 生成失败"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:S($$,{color:"red",children:H},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:S($$,{dimColor:!0,children:"按 ESC 返回修改描述"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return S(W$,{flexDirection:"column",paddingY:1,children:[S(W$,{marginBottom:1,children:S($$,{bold:!0,color:"yellow",children:[S(Vw,{type:"dots"},void 0,!1,void 0,this)," AI 正在生成配置..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:S($$,{dimColor:!0,children:['根据你的描述:"',K,'"']},void 0,!0,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:S($$,{color:"gray",children:"正在调用 LLM 生成 agent 配置,请稍候..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}if(Q==="name"){let v=O==="edit";return S(W$,{flexDirection:"column",paddingY:1,children:[S(W$,{marginBottom:1,children:S($$,{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),S(W$,{marginBottom:1,children:S($$,{dimColor:!0,children:v?"编辑模式下名称不可修改(修改名称相当于创建新 Agent)":"名称只能包含小写字母、数字和连字符(例如:code-reviewer)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:[S($$,{color:"green",children:"名称: "},void 0,!1,void 0,this),v?S($$,{children:J.name},void 0,!1,void 0,this):S(V3,{value:J.name,onChange:(b)=>G({...J,name:b}),onSubmit:(b)=>{if(jw(b))return;w()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),S(W$,{children:S($$,{dimColor:!0,children:v?"按 Enter 继续 | ESC 返回":"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v&&S(V3,{value:"",onChange:()=>{},onSubmit:w,showCursor:!1},"edit-mode-dummy-input",!1,void 0,this)]},void 0,!0,void 0,this)}if(Q==="description")return S(W$,{flexDirection:"column",paddingY:1,children:[S(W$,{marginBottom:1,children:S($$,{bold:!0,color:"cyan",children:"\uD83D\uDCDD Step 2/7: 输入描述信息"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:S($$,{dimColor:!0,children:"简短描述这个 Agent 的用途和使用场景(这将帮助主 Agent 决定何时使用它)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:[S($$,{color:"green",children:"描述: "},void 0,!1,void 0,this),S(V3,{value:J.description,onChange:(v)=>G({...J,description:v}),onSubmit:(v)=>{if(!v.trim())return;w()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),S(W$,{children:S($$,{dimColor:!0,children:"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="tools")return S(Iw,{config:J,setConfig:G,onNext:w,onPrev:N},void 0,!1,void 0,this);if(Q==="color")return S(W$,{flexDirection:"column",paddingY:1,children:[S(W$,{marginBottom:1,children:S($$,{bold:!0,color:"cyan",children:"\uD83C\uDFA8 Step 4/7: 选择背景颜色"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:S($$,{dimColor:!0,children:"为 Agent 选择一个颜色标识(用于在 UI 中区分不同的 Agents)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(Y6,{items:Mw,onSelect:(v)=>{let b=v.value==="none"?void 0:v.value;G({...J,color:b}),w()}},void 0,!1,void 0,this),S(W$,{marginTop:1,children:S($$,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="location")return S(W$,{flexDirection:"column",paddingY:1,children:[S(W$,{marginBottom:1,children:S($$,{bold:!0,color:"cyan",children:"\uD83D\uDCC2 Step 5/7: 选择保存位置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:S($$,{dimColor:!0,children:"项目级配置仅在当前项目生效,用户级配置全局可用"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(Y6,{items:[{label:"\uD83D\uDCC1 项目级 (.blade/agents/) - 仅当前项目",value:"project"},{label:"\uD83C\uDFE0 用户级 (~/.blade/agents/) - 全局可用",value:"user"}],onSelect:(v)=>{G({...J,location:v.value}),w()}},void 0,!1,void 0,this),S(W$,{marginTop:1,children:S($$,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="systemPrompt")return S(W$,{flexDirection:"column",paddingY:1,children:[S(W$,{marginBottom:1,children:S($$,{bold:!0,color:"cyan",children:"\uD83D\uDCAC Step 6/7: 输入系统提示词"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:S($$,{dimColor:!0,children:"定义 Agent 的行为和职责(可选,留空将使用默认提示)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:[S($$,{color:"green",children:"提示词: "},void 0,!1,void 0,this),S(V3,{value:J.systemPrompt,onChange:(v)=>G({...J,systemPrompt:v}),onSubmit:()=>w()},void 0,!1,void 0,this)]},void 0,!0,void 0,this),S(W$,{children:S($$,{dimColor:!0,children:"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="confirm")return S(W$,{flexDirection:"column",paddingY:1,children:[S(W$,{marginBottom:1,children:S($$,{bold:!0,color:"cyan",children:"✅ Step 7/7: 确认配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{flexDirection:"column",paddingLeft:2,marginBottom:1,children:[S($$,{children:[S($$,{bold:!0,color:"green",children:["名称:"," "]},void 0,!0,void 0,this),S($$,{children:J.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),S($$,{children:[S($$,{bold:!0,color:"green",children:["描述:"," "]},void 0,!0,void 0,this),S($$,{children:J.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),S($$,{children:[S($$,{bold:!0,color:"green",children:["工具:"," "]},void 0,!0,void 0,this),S($$,{children:J.tools.includes("all")?"所有工具":J.tools.join(", ")||"所有工具"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),S($$,{children:[S($$,{bold:!0,color:"green",children:["颜色:"," "]},void 0,!0,void 0,this),S($$,{children:J.color||"默认"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),S($$,{children:[S($$,{bold:!0,color:"green",children:["位置:"," "]},void 0,!0,void 0,this),S($$,{children:J.location==="project"?"项目级":"用户级"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),S($$,{children:[S($$,{bold:!0,color:"green",children:["提示词:"," "]},void 0,!0,void 0,this),S($$,{children:J.systemPrompt||"(使用默认)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),S(Y6,{items:[{label:"✅ 确认并保存",value:"save"},{label:"⬅️ 返回上一步",value:"back"},{label:"❌ 取消",value:"cancel"}],onSelect:(v)=>{if(v.value==="save")V();else if(v.value==="back")N();else Z()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}function Iw({config:$,setConfig:Z,onNext:Y,onPrev:Q}){let{isFocused:X}=Aw({id:"step-tools"});fW((G,K)=>{if(K.escape)Q()},{isActive:X});let J=(G)=>{if(G.includes("all"))Z({...$,tools:["all"]});else Z({...$,tools:G});Y()};return S(W$,{flexDirection:"column",paddingY:1,children:[S(W$,{marginBottom:1,children:S($$,{bold:!0,color:"cyan",children:"\uD83D\uDD27 Step 3/7: 选择可用工具"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(W$,{marginBottom:1,children:S($$,{dimColor:!0,children:"方向键导航,空格切换勾选,Enter 确认进入下一步 | ESC 返回上一步"},void 0,!1,void 0,this)},void 0,!1,void 0,this),S(bw,{options:Dw,defaultValue:$.tools,onSubmit:J},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}U2();import yw from"node:fs";import{useMemoizedFn as N2}from"ahooks";import{Box as c$,Text as n$,useInput as vw}from"ink";import jZ from"ink-select-input";import{useEffect as Ew,useMemo as hW,useState as Q6}from"react";import{jsxDEV as o}from"react/jsx-dev-runtime";var IZ=10;function xW({initialMode:$="menu",onComplete:Z,onCancel:Y}){let[Q,X]=Q6($),[J,G]=Q6(null),[K,q]=Q6(0),[W,U]=Q6(0),H=N2(()=>{J0.clear(),J0.loadFromStandardLocations(),q((b)=>b+1)}),F=hW(()=>{return J0.getAllSubagents()},[K]),O=Math.ceil(F.length/IZ)||1,z=hW(()=>{let b=W*IZ;return F.slice(b,b+IZ)},[F,W]);Ew(()=>{let b=Math.max(0,O-1);if(W>b)U(b)},[O,W]);let _=N2(()=>{if(W<O-1)U((b)=>b+1)}),B=N2(()=>{if(W>0)U((b)=>b-1)}),L=[{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"}],w=N2((b)=>{if(b.value==="cancel"){Y?.();return}X(b.value)}),N=N2((b)=>{if(G(b.value),Q==="edit")X("editWizard");else if(Q==="delete")X("deleteConfirm")}),D=N2(async()=>{if(!J?.configPath)return;try{await yw.promises.unlink(J.configPath),H(),V()}catch(b){console.error("删除失败:",b)}}),V=N2(()=>{X("menu"),G(null)}),I=Q0(!1,Y);if(vw((b,C)=>{if(C.escape){if(Q==="menu")Y?.();else if(Q==="list"||Q==="edit"||Q==="delete")U(0),V();else if(Q==="deleteConfirm")V()}else if(C.ctrl&&b==="c"||C.meta&&b==="c")I();else if(Q==="list"){if(C.leftArrow||b==="h")B();else if(C.rightArrow||b==="l")_()}},{isActive:Q!=="create"&&Q!=="editWizard"}),Q==="menu")return o(c$,{flexDirection:"column",paddingY:1,children:[o(c$,{marginBottom:1,children:o(n$,{bold:!0,color:"cyan",children:"\uD83D\uDCCB Agents 管理"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(jZ,{items:L,onSelect:w},void 0,!1,void 0,this),o(c$,{marginTop:1,children:o(n$,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 退出"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="list"){if(F.length===0)return o(c$,{flexDirection:"column",paddingY:1,children:[o(c$,{marginBottom:1,children:o(n$,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(c$,{paddingLeft:2,children:o(n$,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(c$,{marginTop:1,paddingLeft:2,children:o(n$,{color:"gray",children:"\uD83D\uDCA1 配置文件位置: .blade/agents/ 或 ~/.blade/agents/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(c$,{marginTop:1,paddingLeft:2,children:o(n$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return o(c$,{flexDirection:"column",paddingY:1,children:[o(c$,{marginBottom:1,children:[o(n$,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this),o(n$,{color:"gray",children:[" (共 ",F.length," 个)"]},void 0,!0,void 0,this),O>1&&o(n$,{color:"yellow",children:[" ","第 ",W+1,"/",O," 页"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),z.map((b)=>o(c$,{flexDirection:"column",paddingLeft:2,children:[o(c$,{children:o(n$,{children:[o(n$,{bold:!0,color:b.color||"white",children:["• ",b.name]},void 0,!0,void 0,this),o(n$,{color:"gray",children:[" - ",b.description]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),b.tools&&b.tools.length>0&&o(c$,{paddingLeft:2,children:o(n$,{color:"gray",children:["工具: ",b.tools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),b.configPath&&o(c$,{paddingLeft:2,children:o(n$,{color:"gray",dimColor:!0,children:b.configPath},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},b.name,!0,void 0,this)),o(c$,{marginTop:1,paddingLeft:2,children:O>1?o(n$,{dimColor:!0,children:"← → 翻页 | ESC 返回菜单"},void 0,!1,void 0,this):o(n$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}let v=(b)=>{if(F.length===0)return o(c$,{flexDirection:"column",paddingY:1,children:[o(c$,{marginBottom:1,children:o(n$,{bold:!0,color:"cyan",children:b},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(c$,{paddingLeft:2,children:o(n$,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(c$,{marginTop:1,paddingLeft:2,children:o(n$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);let C=F.map((d)=>({key:d.name,label:`${d.name} - ${d.description}`,value:d}));return o(c$,{flexDirection:"column",paddingY:1,children:[o(c$,{marginBottom:1,children:o(n$,{bold:!0,color:"cyan",children:b},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(jZ,{items:C,onSelect:N},void 0,!1,void 0,this),o(c$,{marginTop:1,children:o(n$,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};if(Q==="create")return o(D3,{onComplete:()=>{H(),V()},onCancel:V},void 0,!1,void 0,this);if(Q==="edit")return v("✏️ 编辑 Agent");if(Q==="editWizard"&&J){let b={name:J.name,description:J.description,tools:J.tools||[],color:J.color,location:J.configPath?.includes(".blade/agents")?"project":"user",systemPrompt:J.systemPrompt||""};return o(D3,{initialConfig:b,onComplete:()=>{H(),V()},onCancel:V},void 0,!1,void 0,this)}if(Q==="delete")return v("\uD83D\uDDD1️ 删除 Agent");if(Q==="deleteConfirm"&&J)return o(c$,{flexDirection:"column",paddingY:1,children:[o(c$,{marginBottom:1,children:o(n$,{bold:!0,color:"red",children:"⚠️ 确认删除"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(c$,{marginBottom:1,paddingLeft:2,children:o(n$,{children:["你确定要删除 Agent"," ",o(n$,{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),o(c$,{marginBottom:1,paddingLeft:2,children:o(n$,{dimColor:!0,children:["文件路径: ",J.configPath]},void 0,!0,void 0,this)},void 0,!1,void 0,this),o(c$,{marginBottom:1,paddingLeft:2,children:o(n$,{color:"red",children:"此操作无法撤销!"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(jZ,{items:[{label:"\uD83D\uDDD1️ 确认删除",value:"confirm"},{label:"❌ 取消",value:"cancel"}],onSelect:(b)=>{if(b.value==="confirm")D();else V()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}U0();import{Box as b8,Text as o$}from"ink";import Tw from"react";T9();FZ();import{useEffect as Pw,useState as pW}from"react";function mW($=process.cwd(),Z=5000){let[Y,Q]=pW(null),[X,J]=pW(!0);return Pw(()=>{let G=!0,K=async()=>{try{let W=await _3($);if(!G)return;if(!W){Q(null),J(!1);return}let U=await mK($);if(!G)return;Q(U)}catch{if(G)Q(null)}finally{if(G)J(!1)}};K();let q=null;if(Z>0)q=setInterval(K,Z);return()=>{if(G=!1,q)clearInterval(q)}},[$,Z]),{branch:Y,loading:X}}import{jsxDEV as R$,Fragment as X6}from"react/jsx-dev-runtime";var dW=Tw.memo(()=>{let $=a9(),Z=B8(),Q=i9()==="shortcuts",X=tq(),{branch:J}=mW(),G=r9(),K=iq(),q=lq(),W=n9(),U=FW(),H=G?X8(G):!1,O=(()=>{if(Z==="default")return null;if(Z==="autoEdit")return R$(o$,{color:"magenta",children:["▶▶ auto edit on ",R$(o$,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="plan")return R$(o$,{color:"cyan",children:["‖ plan mode on ",R$(o$,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="yolo")return R$(o$,{color:"red",children:["⚡ yolo mode on ",R$(o$,{color:"gray",children:"(all tools auto-approved)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="spec"){let{phase:B,completed:L,total:w}=U,N;if(!B)N="init";else if((B==="tasks"||B==="implementation")&&w>0)N=`${B} ${L}/${w}`;else N=B;return R$(o$,{color:"blue",children:["\uD83D\uDCCB spec: ",N," ",R$(o$,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}return null})(),z=O!==null,_=[["Enter:发送","Shift+Enter:换行","Esc:中止"],["Shift+Tab:切换模式","↑/↓:历史","Tab:补全"],["Ctrl+A:行首","Ctrl+E:行尾","Ctrl+K:删到尾"],["Ctrl+U:删到首","Ctrl+W:删单词","Ctrl+C:退出"]];return R$(b8,{flexDirection:"row",justifyContent:"space-between",paddingX:2,paddingY:0,children:[Q?R$(b8,{flexDirection:"column",gap:0,children:_.map((B,L)=>R$(b8,{flexDirection:"row",children:[B.map((w,N)=>{let[D,V]=w.split(":");return R$(b8,{flexDirection:"row",width:20,children:[R$(o$,{color:"yellow",children:D},void 0,!1,void 0,this),R$(o$,{color:"gray",children:":"},void 0,!1,void 0,this),R$(o$,{color:"white",children:V},void 0,!1,void 0,this)]},N,!0,void 0,this)}),L===_.length-1&&R$(o$,{color:"cyan",children:" ? 关闭"},void 0,!1,void 0,this)]},L,!0,void 0,this))},void 0,!1,void 0,this):R$(b8,{flexDirection:"row",gap:1,children:[J&&R$(X6,{children:[R$(o$,{color:"gray",children:[" ",J]},void 0,!0,void 0,this),R$(o$,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),O,z&&R$(o$,{color:"gray",children:"·"},void 0,!1,void 0,this),R$(o$,{color:"gray",children:"? for shortcuts"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),R$(b8,{flexDirection:"row",gap:1,children:!$?R$(o$,{color:"red",children:"⚠ API 密钥未配置"},void 0,!1,void 0,this):R$(X6,{children:[H&&R$(X6,{children:[W?R$(o$,{color:"cyan",children:"Thinking on"},void 0,!1,void 0,this):R$(o$,{color:"gray",children:"Tab:Thinking"},void 0,!1,void 0,this),R$(o$,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G&&R$(o$,{color:"gray",children:G.model},void 0,!1,void 0,this),R$(o$,{color:"gray",children:"·"},void 0,!1,void 0,this),q?R$(o$,{color:"yellow",children:"压缩中..."},void 0,!1,void 0,this):R$(o$,{color:K<20?"red":K<50?"yellow":"gray",children:[K,"%"]},void 0,!0,void 0,this),X&&R$(X6,{children:[R$(o$,{color:"gray",children:"·"},void 0,!1,void 0,this),R$(o$,{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 yZ,Text as vZ}from"ink";import Cw from"react";import{jsxDEV as A8}from"react/jsx-dev-runtime";var uW=Cw.memo(({suggestions:$,selectedIndex:Z,visible:Y,maxDisplay:Q=8})=>{if(!Y||$.length===0)return null;let X=0,J=Math.min(Q,$.length),G=Z>=$.length;if(Z>=Q&&!G)X=Z-Q+1,J=Z+1;let K=$.slice(X,J),q=$.length>Q;return A8(yZ,{flexDirection:"column",paddingX:2,paddingY:0,children:[K.map((W,U)=>{let F=X+U===Z;return A8(yZ,{flexDirection:"row",paddingX:1,gap:2,children:[A8(vZ,{color:F?"cyan":"white",bold:F,children:W.command},void 0,!1,void 0,this),A8(vZ,{color:F?"cyan":"gray",dimColor:!F,children:["- ",W.description]},void 0,!0,void 0,this)]},W.command,!0,void 0,this)}),q&&A8(yZ,{paddingX:1,children:A8(vZ,{color:G?"cyan":"gray",bold:G,dimColor:!G,children:["... and ",$.length-Q," more"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});U0();import{Box as b1,Text as S1,useInput as KN,useStdout as qN}from"ink";import WN from"ink-select-input";import cZ,{useMemo as $U}from"react";import{Box as V$,Text as s$}from"ink";import R2,{useEffect as gZ,useMemo as D8,useRef as eW}from"react";C8();m6();import{Box as G6,Text as i1}from"ink";import{isPlainObject as SZ}from"lodash-es";import{common as xw,createLowlight as pw}from"lowlight";import aW from"react";r4();import{Box as J6,Text as M3}from"ink";import q4,{Fragment as lW}from"react";import Sw from"string-width";var gW=new Map,cW=1000;function PZ($){let Z=!0;for(let Q=0;Q<$.length;Q++)if($.charCodeAt(Q)>127){Z=!1;break}if(Z)return $.split("");if($.length<=cW){let Q=gW.get($);if(Q)return Q}let Y=Array.from($);if($.length<=cW)gW.set($,Y);return Y}var EZ=new Map;function K4($){if(/^[\x20-\x7E]*$/.test($))return $.length;if(EZ.has($))return EZ.get($);let Z=Sw($);return EZ.set($,Z),Z}import{jsxDEV as R8}from"react/jsx-dev-runtime";var TZ=2,iW=q4.memo(({children:$,maxWidth:Z,maxHeight:Y,overflowDirection:Q="top",additionalHiddenLinesCount:X=0})=>{let J=$0(),G=[],K=Math.max(Math.round(Y??Number.MAX_SAFE_INTEGER),TZ);function q(_){if(!q4.isValidElement(_))return;if(_.type===lW){q4.Children.forEach(_.props.children,q);return}if(_.type===J6){fw(_,Z,G);return}}q4.Children.forEach($,q);let U=G.length>K||X>0?K-1:K,H=U!==void 0?Math.max(0,G.length-U):0,F=H+X,z=(H>0?Q==="top"?G.slice(H):G.slice(0,U):G).map((_,B)=>R8(J6,{children:_.length>0?_.map((L,w)=>R8(M3,{...L.props,children:L.text},w,!1,void 0,this)):R8(M3,{children:" "},void 0,!1,void 0,this)},B,!1,void 0,this));return R8(J6,{flexDirection:"column",width:Z,flexShrink:0,children:[F>0&&Q==="top"&&R8(M3,{color:J.colors.text.muted,dimColor:!0,children:["... ",F," line",F===1?"":"s"," hidden ..."]},void 0,!0,void 0,this),z,F>0&&Q==="bottom"&&R8(M3,{color:J.colors.text.muted,dimColor:!0,children:["... ",F," line",F===1?"":"s"," hidden ..."]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});function kw($){if(!q4.isValidElement($)||$.type!==J6)return{noWrapSegments:[],segments:[]};let Z={noWrapSegments:[],segments:[]},Y=!1;function Q(X,J){if(X===null||X===void 0)return;if(typeof X==="string"||typeof X==="number"){let W=String(X);if(!W)return;let U={text:W,props:J??{}};if(J===void 0||J.wrap==="wrap")Y=!0,Z.segments.push(U);else if(!Y)Z.noWrapSegments.push(U);else Z.segments.push(U);return}if(!q4.isValidElement(X))return;if(X.type===lW){q4.Children.forEach(X.props.children,(W)=>Q(W,J));return}if(X.type!==M3)return;let{children:G,...K}=X.props,q=J===void 0?K:{...J,...K};q4.Children.forEach(G,(W)=>Q(W,q))}return q4.Children.forEach($.props.children,(X)=>Q(X,void 0)),Z}function fw($,Z,Y){let Q=kw($);if(Q.segments.length===0&&Q.noWrapSegments.length===0){Y.push([]);return}let X=0;for(let H of Q.noWrapSegments)X+=K4(H.text);if(Q.segments.length===0){let H=[],F=[];for(let O of Q.noWrapSegments){let z=O.text.split(`
2827
2827
  `);for(let _=0;_<z.length;_++){if(_>0)H.push(F),F=[];if(z[_])F.push({text:z[_],props:O.props})}}if(F.length>0)H.push(F);for(let O of H)Y.push(O);return}let J=Z-X;if(J<1){hw(Q.noWrapSegments,Z,Y);return}let G=[],K=[],q=0;function W(){if(G.length===0)G.push([...Q.noWrapSegments,...K]);else if(X>0)G.push([{text:" ".repeat(X),props:{}},...K]);else G.push(K);K=[],q=0}function U(H,F){if(K.length>0&&K[K.length-1].props===F)K[K.length-1].text+=H;else K.push({text:H,props:F})}for(let H of Q.segments){let F=H.text.split(`
2828
- `);for(let O=0;O<F.length;O++){if(O>0)W();let _=F[O].split(/(\s+)/);for(let B of _){if(!B)continue;let L=K2(B);if(q+L>J&&q>0){if(W(),/^\s+$/.test(B))continue}if(L>J){let N=PZ(B);while(N.length>0){let D=0,V=0;for(let I of N){let v=K2(I);if(q+V+v>J)break;V+=v,D++}if(D>0){let I=N.slice(0,D).join("");U(I,H.props),q+=K2(I),N=N.slice(D)}if(N.length>0)W()}}else U(B,H.props),q+=L}}if(H.text.endsWith(`
2828
+ `);for(let O=0;O<F.length;O++){if(O>0)W();let _=F[O].split(/(\s+)/);for(let B of _){if(!B)continue;let L=K4(B);if(q+L>J&&q>0){if(W(),/^\s+$/.test(B))continue}if(L>J){let N=PZ(B);while(N.length>0){let D=0,V=0;for(let I of N){let v=K4(I);if(q+V+v>J)break;V+=v,D++}if(D>0){let I=N.slice(0,D).join("");U(I,H.props),q+=K4(I),N=N.slice(D)}if(N.length>0)W()}}else U(B,H.props),q+=L}}if(H.text.endsWith(`
2829
2829
  `))W()}if(K.length>0)W();for(let H of G)Y.push(H)}function hw($,Z,Y){let Q=[],X=[],J=0;for(let G of $){let K=G.text.split(`
2830
- `);for(let q=0;q<K.length;q++){if(q>0)Q.push(X),X=[],J=0;let W=K[q];if(!W)continue;let U=K2(W),H=Math.max(0,Z-K2("…"));if(U<=H&&J===0)X.push({text:W,props:G.props}),J+=U;else{let F=PZ(W),O=J,z=0;for(let B of F){let L=K2(B);if(O+L>H)break;O+=L,z++}let _=F.slice(0,z).join("");if(_)X.push({text:_,props:G.props});X.push({text:"…",props:{}}),J=O+K2("…")}}}if(X.length>0)Q.push(X);if(Q.length===0)Q.push([{text:"…",props:{}}]);for(let G of Q)Y.push(G)}import{jsxDEV as k0}from"react/jsx-dev-runtime";var CZ=pw(xw);function mw($){return SZ($)&&$.type==="text"&&typeof $.value==="string"}function dw($){return SZ($)&&$.type==="element"}function uw($){return SZ($)&&$.type==="root"&&Array.isArray($.children)}function K6($,Z,Y=0){if(mw($))return k0(i1,{wrap:"wrap",children:$.value},Y,!1,void 0,this);if(dw($)){let Q=$.properties?.className?.[0]||"",X=Z.default;if(Q.includes("comment"))X=Z.comment;else if(Q.includes("string"))X=Z.string;else if(Q.includes("number"))X=Z.number;else if(Q.includes("keyword"))X=Z.keyword;else if(Q.includes("function"))X=Z.function;else if(Q.includes("variable"))X=Z.variable;else if(Q.includes("operator"))X=Z.operator;else if(Q.includes("type"))X=Z.type;else if(Q.includes("tag"))X=Z.tag;else if(Q.includes("attr"))X=Z.attr;let J=$.children?.map((G,K)=>K6(G,Z,K));return k0(i1,{color:X,wrap:"wrap",children:J},Y,!1,void 0,this)}if(uw($))return k0(aW.Fragment,{children:$.children.map((Q,X)=>K6(Q,Z,X))},Y,!1,void 0,this);return k0(i1,{},Y,!1,void 0,this)}function gw($,Z,Y){let Q=Y||g0.getTheme().colors.syntax;try{if(!Z||!CZ.registered(Z)){let J=CZ.highlightAuto($);if(!J.children||J.children.length===0)return k0(i1,{color:Q.default,wrap:"wrap",children:$},void 0,!1,void 0,this);return K6(J,Q)}let X=CZ.highlight(Z,$);if(!X.children||X.children.length===0)return k0(i1,{color:Q.default,wrap:"wrap",children:$},void 0,!1,void 0,this);return K6(X,Q)}catch(X){return k0(i1,{color:Q.default,wrap:"wrap",children:$},void 0,!1,void 0,this)}}var q6=aW.memo(({content:$,language:Z,showLineNumbers:Y=!0,terminalWidth:Q,availableHeight:X})=>{let J=$0(),G=$.split(`
2830
+ `);for(let q=0;q<K.length;q++){if(q>0)Q.push(X),X=[],J=0;let W=K[q];if(!W)continue;let U=K4(W),H=Math.max(0,Z-K4("…"));if(U<=H&&J===0)X.push({text:W,props:G.props}),J+=U;else{let F=PZ(W),O=J,z=0;for(let B of F){let L=K4(B);if(O+L>H)break;O+=L,z++}let _=F.slice(0,z).join("");if(_)X.push({text:_,props:G.props});X.push({text:"…",props:{}}),J=O+K4("…")}}}if(X.length>0)Q.push(X);if(Q.length===0)Q.push([{text:"…",props:{}}]);for(let G of Q)Y.push(G)}import{jsxDEV as k0}from"react/jsx-dev-runtime";var CZ=pw(xw);function mw($){return SZ($)&&$.type==="text"&&typeof $.value==="string"}function dw($){return SZ($)&&$.type==="element"}function uw($){return SZ($)&&$.type==="root"&&Array.isArray($.children)}function K6($,Z,Y=0){if(mw($))return k0(i1,{wrap:"wrap",children:$.value},Y,!1,void 0,this);if(dw($)){let Q=$.properties?.className?.[0]||"",X=Z.default;if(Q.includes("comment"))X=Z.comment;else if(Q.includes("string"))X=Z.string;else if(Q.includes("number"))X=Z.number;else if(Q.includes("keyword"))X=Z.keyword;else if(Q.includes("function"))X=Z.function;else if(Q.includes("variable"))X=Z.variable;else if(Q.includes("operator"))X=Z.operator;else if(Q.includes("type"))X=Z.type;else if(Q.includes("tag"))X=Z.tag;else if(Q.includes("attr"))X=Z.attr;let J=$.children?.map((G,K)=>K6(G,Z,K));return k0(i1,{color:X,wrap:"wrap",children:J},Y,!1,void 0,this)}if(uw($))return k0(aW.Fragment,{children:$.children.map((Q,X)=>K6(Q,Z,X))},Y,!1,void 0,this);return k0(i1,{},Y,!1,void 0,this)}function gw($,Z,Y){let Q=Y||g0.getTheme().colors.syntax;try{if(!Z||!CZ.registered(Z)){let J=CZ.highlightAuto($);if(!J.children||J.children.length===0)return k0(i1,{color:Q.default,wrap:"wrap",children:$},void 0,!1,void 0,this);return K6(J,Q)}let X=CZ.highlight(Z,$);if(!X.children||X.children.length===0)return k0(i1,{color:Q.default,wrap:"wrap",children:$},void 0,!1,void 0,this);return K6(X,Q)}catch(X){return k0(i1,{color:Q.default,wrap:"wrap",children:$},void 0,!1,void 0,this)}}var q6=aW.memo(({content:$,language:Z,showLineNumbers:Y=!0,terminalWidth:Q,availableHeight:X})=>{let J=$0(),G=$.split(`
2831
2831
  `),K=0;if(X&&G.length>X){let H=Math.max(X,TZ);if(G.length>H)K=G.length-H,G=G.slice(K)}let q=G.length+K,W=String(q).length+1,U=Math.max(20,Q-4);return k0(G6,{borderStyle:"round",borderColor:J.colors.border.light,paddingX:1,paddingY:0,marginY:1,flexDirection:"column",children:[Z&&k0(G6,{marginBottom:0,children:k0(i1,{color:J.colors.text.secondary,children:Z},void 0,!1,void 0,this)},void 0,!1,void 0,this),K>0&&k0(G6,{marginBottom:0,children:k0(i1,{color:J.colors.text.muted,dimColor:!0,children:["... ",K," lines hidden ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this),k0(iW,{maxWidth:U,maxHeight:X,children:G.map((H,F)=>{let O=F+K+1;return k0(G6,{flexDirection:"row",children:[Y&&k0(i1,{color:J.colors.text.muted,dimColor:!0,wrap:"truncate",children:[String(O).padStart(W-1," ")," "]},void 0,!0,void 0,this),H.trim()===""?k0(i1,{wrap:"wrap",children:" "},void 0,!1,void 0,this):gw(H,Z,J.colors.syntax)]},F,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});import{Box as rW,Text as a1}from"ink";import cw from"react";import{jsxDEV as B1}from"react/jsx-dev-runtime";function lw($){let Z=$.split(`
2832
- `),Y=[],Q=0,X=0;for(let J of Z){if(J.startsWith("---")||J.startsWith("+++"))continue;if(J.startsWith("@@")){let G=J.match(/@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@/);if(G)Q=parseInt(G[1],10),X=parseInt(G[3],10);Y.push({type:"header",content:J});continue}if(J.startsWith("-")){Y.push({type:"remove",content:J.substring(1),lineNumber:Q}),Q++;continue}if(J.startsWith("+")){Y.push({type:"add",content:J.substring(1),lineNumber:X}),X++;continue}if(J.startsWith(" ")||J===""){Y.push({type:"context",content:J.substring(1),lineNumber:X}),Q++,X++;continue}}return Y}var kZ=cw.memo(({patch:$,startLine:Z,matchLine:Y,terminalWidth:Q,maxLines:X=20})=>{let J=$0(),G=lw($),q=Math.max(...G.map((O)=>O.lineNumber||0)).toString().length+1,W=G.length,U=W>X,H=U?G.slice(0,X):G,F=W-X;return B1(rW,{flexDirection:"column",marginTop:1,marginBottom:1,children:[B1(a1,{color:J.colors.muted,children:"─".repeat(Math.max(0,Math.min(60,Q)))},void 0,!1,void 0,this),U&&B1(a1,{color:J.colors.info,children:["\uD83D\uDCCA 显示前 ",X," 行,共 ",W," 行 diff"]},void 0,!0,void 0,this),U&&B1(a1,{color:J.colors.muted,children:"─".repeat(Math.max(0,Math.min(60,Q)))},void 0,!1,void 0,this),H.map((O,z)=>{if(O.type==="header")return B1(a1,{color:J.colors.muted,dimColor:!0,children:O.content},z,!1,void 0,this);let _=O.lineNumber?O.lineNumber.toString().padStart(q," "):" ".repeat(q),B=" ",L,w;if(O.type==="add")B="+",w=J.colors.success,L=void 0;else if(O.type==="remove")B="-",w=J.colors.error,L=void 0;else w=J.colors.text.primary;let N=Math.max(0,Q-q-2),D=O.content;if(D.length>N)D=D.substring(0,N-3)+"...";return B1(a1,{color:w,backgroundColor:L,children:[B1(a1,{dimColor:!0,children:_},void 0,!1,void 0,this),B1(a1,{children:B},void 0,!1,void 0,this),B1(a1,{children:[" ",D]},void 0,!0,void 0,this)]},z,!0,void 0,this)}),U&&B1(rW,{marginTop:1,children:B1(a1,{color:J.colors.warning,dimColor:!0,children:["⚠️ 已隐藏剩余 ",F," 行 diff(总共 ",W," 行)"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),B1(a1,{color:J.colors.muted,children:"─".repeat(Math.max(0,Math.min(60,Q)))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});import{Text as C1}from"ink";import aw from"react";import iw from"string-width";var b4=($)=>{let Z=$.replace(/\*\*(.*?)\*\*/g,"$1").replace(/\*(.*?)\*/g,"$1").replace(/_(.*?)_/g,"$1").replace(/~~(.*?)~~/g,"$1").replace(/`(.*?)`/g,"$1").replace(/<u>(.*?)<\/u>/g,"$1").replace(/\[(.*?)\]\(.*?\)/g,"$1");return iw(Z)},nW=($,Z,Y="...")=>{if(b4($)<=Z)return $;if(Z<=Y.length)return Y.substring(0,Z);let X=0,J=$.length,G="";while(X<=J){let K=Math.floor((X+J)/2),q=$.substring(0,K);if(b4(q)<=Z-Y.length)G=q,X=K+1;else J=K-1}return G+Y},oW=($)=>{return/[*_~`<[\]https?:]/.test($)};import{jsxDEV as L1,Fragment as nw}from"react/jsx-dev-runtime";var fZ=2,hZ=1,xZ=2;function pZ($,Z){return`inline-${$}-${Z}`}var rw=({text:$})=>{let Z=$0();if(!oW($))return L1(C1,{children:$},void 0,!1,void 0,this);let Y=[],Q=0,X=0,J=0,G=/(\*\*.*?\*\*|\*(?!\s).*?(?<!\s)\*|_(?!\s).*?(?<!\s)_|~~.*?~~|`+[^`]+`+|\[.*?\]\(.*?\)|https?:\/\/\S+)/g,K;while((K=G.exec($))!==null){if(K.index>Q){let H=$.slice(Q,K.index);Y.push(L1(C1,{children:H},pZ("text",X++),!1,void 0,this))}let q=K[0],W=null,U=pZ("match",J++);try{if(q.startsWith("**")&&q.endsWith("**")&&q.length>fZ*2)W=L1(C1,{bold:!0,children:q.slice(fZ,-fZ)},U,!1,void 0,this);else if(q.length>hZ*2&&(q.startsWith("*")&&q.endsWith("*")||q.startsWith("_")&&q.endsWith("_"))){let H=$.substring(K.index-1,K.index),F=$.substring(G.lastIndex,G.lastIndex+1);if(!(/\w/.test(H)||/\w/.test(F)||/[./\\]/.test(H+F)))W=L1(C1,{italic:!0,children:q.slice(hZ,-hZ)},U,!1,void 0,this)}else if(q.startsWith("~~")&&q.endsWith("~~")&&q.length>xZ*2)W=L1(C1,{strikethrough:!0,children:q.slice(xZ,-xZ)},U,!1,void 0,this);else if(q.startsWith("`")&&q.endsWith("`")){let H=q.match(/^(`+)([^`]+)\1$/);if(H&&H[2])W=L1(C1,{color:Z.colors.syntax.keyword,backgroundColor:Z.colors.background.secondary,bold:!0,children:` ${H[2]} `},U,!1,void 0,this)}else if(q.startsWith("[")&&q.includes("](")&&q.endsWith(")")){let H=q.match(/\[(.*?)\]\((.*?)\)/);if(H){let F=H[1],O=H[2];W=L1(C1,{children:[F,L1(C1,{color:Z.colors.info,children:[" (",O,")"]},void 0,!0,void 0,this)]},U,!0,void 0,this)}}else if(q.match(/^https?:\/\//))W=L1(C1,{color:Z.colors.info,children:q},U,!1,void 0,this)}catch(H){console.error("InlineRenderer 解析错误:",q,H),W=null}Y.push(W??L1(C1,{children:q},U,!1,void 0,this)),Q=G.lastIndex}if(Q<$.length){let q=$.slice(Q);Y.push(L1(C1,{children:q},pZ("text",X++),!1,void 0,this))}return L1(nw,{children:Y.filter((q)=>q!==null)},void 0,!1,void 0,this)},w1=aw.memo(rw);import{Box as mZ,Text as sW}from"ink";import ow from"react";import{jsxDEV as V3}from"react/jsx-dev-runtime";var sw=({itemText:$,type:Z,marker:Y,leadingWhitespace:Q=""})=>{let X=Z==="ol"?`${Y}. `:`${Y} `,J=X.length,G=Q.length;return V3(mZ,{paddingLeft:G+1,flexDirection:"row",children:[V3(mZ,{width:J,children:V3(sW,{children:X},void 0,!1,void 0,this)},void 0,!1,void 0,this),V3(mZ,{flexGrow:1,children:V3(sW,{wrap:"wrap",children:V3(w1,{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)},dZ=ow.memo(sw);import{Box as tw,Text as A4}from"ink";import uZ from"react";import{jsxDEV as N1}from"react/jsx-dev-runtime";var tW=uZ.memo(({headers:$,rows:Z,terminalWidth:Y})=>{let Q=$0();if($.length===0||Z.length===0)return null;let X=$.map((F,O)=>{let z=b4(F),_=Math.max(...Z.map((B)=>b4(B[O]||"")));return Math.max(z,_)+2}),J=$.length+1,G=X.reduce((F,O)=>F+O,0)+J,K=G>Y?Y/G:1,q=X.map((F)=>Math.floor(F*K)),W=(F,O,z=!1)=>{let _=Math.max(0,O-2),B=b4(F),L=F;if(B>_)L=nW(F,_);let w=b4(L),N=Math.max(0,_-w);return N1(A4,{children:[z?N1(A4,{bold:!0,color:Q.colors.primary,children:N1(w1,{text:L},void 0,!1,void 0,this)},void 0,!1,void 0,this):N1(w1,{text:L},void 0,!1,void 0,this)," ".repeat(N)]},void 0,!0,void 0,this)},U=(F)=>{let z={top:{left:"┌",middle:"┬",right:"┐",horizontal:"─"},middle:{left:"├",middle:"┼",right:"┤",horizontal:"─"},bottom:{left:"└",middle:"┴",right:"┘",horizontal:"─"}}[F],_=q.map((L)=>z.horizontal.repeat(L)),B=z.left+_.join(z.middle)+z.right;return N1(A4,{color:Q.colors.text.muted,dimColor:!0,children:B},void 0,!1,void 0,this)},H=(F,O=!1)=>{let z=F.map((_,B)=>{let L=q[B]||0;return W(_||"",L,O)});return N1(A4,{children:[N1(A4,{color:Q.colors.text.muted,children:"│ "},void 0,!1,void 0,this),z.map((_,B)=>N1(uZ.Fragment,{children:[_,B<z.length-1&&N1(A4,{color:Q.colors.text.muted,children:" │ "},void 0,!1,void 0,this)]},B,!0,void 0,this)),N1(A4,{color:Q.colors.text.muted,children:" │"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};return N1(tw,{flexDirection:"column",marginY:1,children:[U("top"),H($,!0),U("middle"),Z.map((F,O)=>N1(uZ.Fragment,{children:H(F)},O,!1,void 0,this)),U("bottom")]},void 0,!0,void 0,this)});import{jsxDEV as x}from"react/jsx-dev-runtime";var ew=($,Z,Y)=>{switch($){case"user":return{color:Z.info,prefix:"> "};case"assistant":return{color:Z.success,prefix:"• "};case"system":return{color:Z.warning,prefix:"⚙ "};case"tool":{let Q=Y&&"phase"in Y?Y.phase:void 0;return{color:Z.text.secondary,prefix:Q==="start"?"• ":Q==="complete"?" └ ":" "}}default:return{color:Z.text.primary,prefix:" "}}},$N=R4.memo(({content:$,language:Z,terminalWidth:Y,isPending:Q=!1,availableHeight:X})=>{let J=$0();if(Q&&X!==void 0){let G=$.split(`
2832
+ `),Y=[],Q=0,X=0;for(let J of Z){if(J.startsWith("---")||J.startsWith("+++"))continue;if(J.startsWith("@@")){let G=J.match(/@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@/);if(G)Q=parseInt(G[1],10),X=parseInt(G[3],10);Y.push({type:"header",content:J});continue}if(J.startsWith("-")){Y.push({type:"remove",content:J.substring(1),lineNumber:Q}),Q++;continue}if(J.startsWith("+")){Y.push({type:"add",content:J.substring(1),lineNumber:X}),X++;continue}if(J.startsWith(" ")||J===""){Y.push({type:"context",content:J.substring(1),lineNumber:X}),Q++,X++;continue}}return Y}var kZ=cw.memo(({patch:$,startLine:Z,matchLine:Y,terminalWidth:Q,maxLines:X=20})=>{let J=$0(),G=lw($),q=Math.max(...G.map((O)=>O.lineNumber||0)).toString().length+1,W=G.length,U=W>X,H=U?G.slice(0,X):G,F=W-X;return B1(rW,{flexDirection:"column",marginTop:1,marginBottom:1,children:[B1(a1,{color:J.colors.muted,children:"─".repeat(Math.max(0,Math.min(60,Q)))},void 0,!1,void 0,this),U&&B1(a1,{color:J.colors.info,children:["\uD83D\uDCCA 显示前 ",X," 行,共 ",W," 行 diff"]},void 0,!0,void 0,this),U&&B1(a1,{color:J.colors.muted,children:"─".repeat(Math.max(0,Math.min(60,Q)))},void 0,!1,void 0,this),H.map((O,z)=>{if(O.type==="header")return B1(a1,{color:J.colors.muted,dimColor:!0,children:O.content},z,!1,void 0,this);let _=O.lineNumber?O.lineNumber.toString().padStart(q," "):" ".repeat(q),B=" ",L,w;if(O.type==="add")B="+",w=J.colors.success,L=void 0;else if(O.type==="remove")B="-",w=J.colors.error,L=void 0;else w=J.colors.text.primary;let N=Math.max(0,Q-q-2),D=O.content;if(D.length>N)D=D.substring(0,N-3)+"...";return B1(a1,{color:w,backgroundColor:L,children:[B1(a1,{dimColor:!0,children:_},void 0,!1,void 0,this),B1(a1,{children:B},void 0,!1,void 0,this),B1(a1,{children:[" ",D]},void 0,!0,void 0,this)]},z,!0,void 0,this)}),U&&B1(rW,{marginTop:1,children:B1(a1,{color:J.colors.warning,dimColor:!0,children:["⚠️ 已隐藏剩余 ",F," 行 diff(总共 ",W," 行)"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),B1(a1,{color:J.colors.muted,children:"─".repeat(Math.max(0,Math.min(60,Q)))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});import{Text as C1}from"ink";import aw from"react";import iw from"string-width";var b2=($)=>{let Z=$.replace(/\*\*(.*?)\*\*/g,"$1").replace(/\*(.*?)\*/g,"$1").replace(/_(.*?)_/g,"$1").replace(/~~(.*?)~~/g,"$1").replace(/`(.*?)`/g,"$1").replace(/<u>(.*?)<\/u>/g,"$1").replace(/\[(.*?)\]\(.*?\)/g,"$1");return iw(Z)},nW=($,Z,Y="...")=>{if(b2($)<=Z)return $;if(Z<=Y.length)return Y.substring(0,Z);let X=0,J=$.length,G="";while(X<=J){let K=Math.floor((X+J)/2),q=$.substring(0,K);if(b2(q)<=Z-Y.length)G=q,X=K+1;else J=K-1}return G+Y},oW=($)=>{return/[*_~`<[\]https?:]/.test($)};import{jsxDEV as L1,Fragment as nw}from"react/jsx-dev-runtime";var fZ=2,hZ=1,xZ=2;function pZ($,Z){return`inline-${$}-${Z}`}var rw=({text:$})=>{let Z=$0();if(!oW($))return L1(C1,{children:$},void 0,!1,void 0,this);let Y=[],Q=0,X=0,J=0,G=/(\*\*.*?\*\*|\*(?!\s).*?(?<!\s)\*|_(?!\s).*?(?<!\s)_|~~.*?~~|`+[^`]+`+|\[.*?\]\(.*?\)|https?:\/\/\S+)/g,K;while((K=G.exec($))!==null){if(K.index>Q){let H=$.slice(Q,K.index);Y.push(L1(C1,{children:H},pZ("text",X++),!1,void 0,this))}let q=K[0],W=null,U=pZ("match",J++);try{if(q.startsWith("**")&&q.endsWith("**")&&q.length>fZ*2)W=L1(C1,{bold:!0,children:q.slice(fZ,-fZ)},U,!1,void 0,this);else if(q.length>hZ*2&&(q.startsWith("*")&&q.endsWith("*")||q.startsWith("_")&&q.endsWith("_"))){let H=$.substring(K.index-1,K.index),F=$.substring(G.lastIndex,G.lastIndex+1);if(!(/\w/.test(H)||/\w/.test(F)||/[./\\]/.test(H+F)))W=L1(C1,{italic:!0,children:q.slice(hZ,-hZ)},U,!1,void 0,this)}else if(q.startsWith("~~")&&q.endsWith("~~")&&q.length>xZ*2)W=L1(C1,{strikethrough:!0,children:q.slice(xZ,-xZ)},U,!1,void 0,this);else if(q.startsWith("`")&&q.endsWith("`")){let H=q.match(/^(`+)([^`]+)\1$/);if(H&&H[2])W=L1(C1,{color:Z.colors.syntax.keyword,backgroundColor:Z.colors.background.secondary,bold:!0,children:` ${H[2]} `},U,!1,void 0,this)}else if(q.startsWith("[")&&q.includes("](")&&q.endsWith(")")){let H=q.match(/\[(.*?)\]\((.*?)\)/);if(H){let F=H[1],O=H[2];W=L1(C1,{children:[F,L1(C1,{color:Z.colors.info,children:[" (",O,")"]},void 0,!0,void 0,this)]},U,!0,void 0,this)}}else if(q.match(/^https?:\/\//))W=L1(C1,{color:Z.colors.info,children:q},U,!1,void 0,this)}catch(H){console.error("InlineRenderer 解析错误:",q,H),W=null}Y.push(W??L1(C1,{children:q},U,!1,void 0,this)),Q=G.lastIndex}if(Q<$.length){let q=$.slice(Q);Y.push(L1(C1,{children:q},pZ("text",X++),!1,void 0,this))}return L1(nw,{children:Y.filter((q)=>q!==null)},void 0,!1,void 0,this)},w1=aw.memo(rw);import{Box as mZ,Text as sW}from"ink";import ow from"react";import{jsxDEV as V8}from"react/jsx-dev-runtime";var sw=({itemText:$,type:Z,marker:Y,leadingWhitespace:Q=""})=>{let X=Z==="ol"?`${Y}. `:`${Y} `,J=X.length,G=Q.length;return V8(mZ,{paddingLeft:G+1,flexDirection:"row",children:[V8(mZ,{width:J,children:V8(sW,{children:X},void 0,!1,void 0,this)},void 0,!1,void 0,this),V8(mZ,{flexGrow:1,children:V8(sW,{wrap:"wrap",children:V8(w1,{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)},dZ=ow.memo(sw);import{Box as tw,Text as A2}from"ink";import uZ from"react";import{jsxDEV as N1}from"react/jsx-dev-runtime";var tW=uZ.memo(({headers:$,rows:Z,terminalWidth:Y})=>{let Q=$0();if($.length===0||Z.length===0)return null;let X=$.map((F,O)=>{let z=b2(F),_=Math.max(...Z.map((B)=>b2(B[O]||"")));return Math.max(z,_)+2}),J=$.length+1,G=X.reduce((F,O)=>F+O,0)+J,K=G>Y?Y/G:1,q=X.map((F)=>Math.floor(F*K)),W=(F,O,z=!1)=>{let _=Math.max(0,O-2),B=b2(F),L=F;if(B>_)L=nW(F,_);let w=b2(L),N=Math.max(0,_-w);return N1(A2,{children:[z?N1(A2,{bold:!0,color:Q.colors.primary,children:N1(w1,{text:L},void 0,!1,void 0,this)},void 0,!1,void 0,this):N1(w1,{text:L},void 0,!1,void 0,this)," ".repeat(N)]},void 0,!0,void 0,this)},U=(F)=>{let z={top:{left:"┌",middle:"┬",right:"┐",horizontal:"─"},middle:{left:"├",middle:"┼",right:"┤",horizontal:"─"},bottom:{left:"└",middle:"┴",right:"┘",horizontal:"─"}}[F],_=q.map((L)=>z.horizontal.repeat(L)),B=z.left+_.join(z.middle)+z.right;return N1(A2,{color:Q.colors.text.muted,dimColor:!0,children:B},void 0,!1,void 0,this)},H=(F,O=!1)=>{let z=F.map((_,B)=>{let L=q[B]||0;return W(_||"",L,O)});return N1(A2,{children:[N1(A2,{color:Q.colors.text.muted,children:"│ "},void 0,!1,void 0,this),z.map((_,B)=>N1(uZ.Fragment,{children:[_,B<z.length-1&&N1(A2,{color:Q.colors.text.muted,children:" │ "},void 0,!1,void 0,this)]},B,!0,void 0,this)),N1(A2,{color:Q.colors.text.muted,children:" │"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};return N1(tw,{flexDirection:"column",marginY:1,children:[U("top"),H($,!0),U("middle"),Z.map((F,O)=>N1(uZ.Fragment,{children:H(F)},O,!1,void 0,this)),U("bottom")]},void 0,!0,void 0,this)});import{jsxDEV as x}from"react/jsx-dev-runtime";var ew=($,Z,Y)=>{switch($){case"user":return{color:Z.info,prefix:"> "};case"assistant":return{color:Z.success,prefix:"• "};case"system":return{color:Z.warning,prefix:"⚙ "};case"tool":{let Q=Y&&"phase"in Y?Y.phase:void 0;return{color:Z.text.secondary,prefix:Q==="start"?"• ":Q==="complete"?" └ ":" "}}default:return{color:Z.text.primary,prefix:" "}}},$N=R2.memo(({content:$,language:Z,terminalWidth:Y,isPending:Q=!1,availableHeight:X})=>{let J=$0();if(Q&&X!==void 0){let G=$.split(`
2833
2833
  `),K=4,q=Math.max(1,X-4);if(G.length>q){let W=G.slice(0,q).join(`
2834
- `);return x(V$,{flexDirection:"column",flexShrink:0,children:[x(q6,{content:W,language:Z,showLineNumbers:!0,terminalWidth:Y},void 0,!1,void 0,this),x(s$,{color:J.colors.text.muted,dimColor:!0,children:"... generating more code ..."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}}return x(q6,{content:$,language:Z,showLineNumbers:!0,terminalWidth:Y},void 0,!1,void 0,this)}),ZN=R4.memo(({content:$,level:Z})=>{let Y=$0();switch(Z){case 1:return x(s$,{bold:!0,color:Y.colors.primary,children:x(w1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 2:return x(s$,{bold:!0,color:Y.colors.primary,children:x(w1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 3:return x(s$,{bold:!0,color:Y.colors.text.primary,children:x(w1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 4:return x(s$,{italic:!0,color:Y.colors.text.muted,children:x(w1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);default:return x(s$,{children:x(w1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)}}),YN=R4.memo(({terminalWidth:$})=>{let Z=$0(),Y=Math.max(0,Math.min($-4,80));return x(s$,{dimColor:!0,color:Z.colors.text.muted,children:"─".repeat(Y)},void 0,!1,void 0,this)}),QN=R4.memo(({content:$})=>{return x(s$,{wrap:"wrap",children:x(w1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)}),XN=R4.memo(({content:$})=>{let Z=$0();return x(V$,{flexDirection:"row",gap:1,children:[x(s$,{color:Z.colors.info,children:"⏳"},void 0,!1,void 0,this),x(s$,{color:Z.colors.text.muted,italic:!0,children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}),JN=R4.memo(({detail:$,terminalWidth:Z})=>{let Y=$0(),Q=50,X=$.split(`
2834
+ `);return x(V$,{flexDirection:"column",flexShrink:0,children:[x(q6,{content:W,language:Z,showLineNumbers:!0,terminalWidth:Y},void 0,!1,void 0,this),x(s$,{color:J.colors.text.muted,dimColor:!0,children:"... generating more code ..."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}}return x(q6,{content:$,language:Z,showLineNumbers:!0,terminalWidth:Y},void 0,!1,void 0,this)}),ZN=R2.memo(({content:$,level:Z})=>{let Y=$0();switch(Z){case 1:return x(s$,{bold:!0,color:Y.colors.primary,children:x(w1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 2:return x(s$,{bold:!0,color:Y.colors.primary,children:x(w1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 3:return x(s$,{bold:!0,color:Y.colors.text.primary,children:x(w1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 4:return x(s$,{italic:!0,color:Y.colors.text.muted,children:x(w1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);default:return x(s$,{children:x(w1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)}}),YN=R2.memo(({terminalWidth:$})=>{let Z=$0(),Y=Math.max(0,Math.min($-4,80));return x(s$,{dimColor:!0,color:Z.colors.text.muted,children:"─".repeat(Y)},void 0,!1,void 0,this)}),QN=R2.memo(({content:$})=>{return x(s$,{wrap:"wrap",children:x(w1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)}),XN=R2.memo(({content:$})=>{let Z=$0();return x(V$,{flexDirection:"row",gap:1,children:[x(s$,{color:Z.colors.info,children:"⏳"},void 0,!1,void 0,this),x(s$,{color:Z.colors.text.muted,italic:!0,children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}),JN=R2.memo(({detail:$,terminalWidth:Z})=>{let Y=$0(),Q=50,X=$.split(`
2835
2835
  `);while(X.length>0&&X[0].trim()==="")X.shift();while(X.length>0&&X[X.length-1].trim()==="")X.pop();let J=X.length>50,G=J?X.slice(0,50):X,K=G.join(`
2836
2836
  `),q=K.includes("<<<DIFF>>>"),W=K.includes("```");if(q){let U=K.match(/<<<DIFF>>>\s*({[\s\S]*?})\s*<<<\/DIFF>>>/);if(U)try{let H=JSON.parse(U[1]);return x(V$,{flexDirection:"column",children:[x(kZ,{patch:H.patch,startLine:H.startLine,matchLine:H.matchLine,terminalWidth:Z},void 0,!1,void 0,this),J&&x(V$,{marginTop:1,children:x(s$,{dimColor:!0,color:Y.colors.text.muted,children:["... 省略 ",X.length-50," 行 ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}catch{}}if(W){let U=K.match(/```(\w+)?\s*\n([\s\S]*?)\n```/);if(U){let H=U[1]||"text",F=U[2];return x(V$,{flexDirection:"column",children:[x(q6,{content:F,language:H,showLineNumbers:!1,terminalWidth:Z},void 0,!1,void 0,this),J&&x(V$,{marginTop:1,children:x(s$,{dimColor:!0,color:Y.colors.text.muted,children:["... 省略 ",X.length-50," 行 ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}}return x(V$,{flexDirection:"column",children:[G.map((U,H)=>x(s$,{color:Y.colors.text.primary,children:U},H,!1,void 0,this)),J&&x(V$,{marginTop:1,children:x(s$,{dimColor:!0,color:Y.colors.text.muted,children:["... 省略 ",X.length-50," 行 ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});function GN($,Z,Y,Q=80){if(!Y||Z===void 0||Z<=0)return{content:$,isTruncated:!1,hiddenLines:0};let J=Math.max(1,Z-8),G=Math.max(40,Q*0.8),K=J*G;if($.length<=K)return{content:$,isTruncated:!1,hiddenLines:0};let q=Math.floor(K*0.9),W=$.length-q,U=W,H=$.indexOf(`
2837
- `,W);if(H!==-1&&H-W<G)U=H+1;let F=$.slice(U),z=($.slice(0,U).match(/\n/g)||[]).length+1;return{content:F,isTruncated:!0,hiddenLines:z}}var x2=R4.memo(({content:$,role:Z,terminalWidth:Y,metadata:Q,isPending:X=!1,availableTerminalHeight:J,hidePrefix:G=!1,noMargin:K=!1,renderPlainTextOnly:q=!1,streamingLines:W,streamingHiddenLines:U,messageId:H,blocksOverride:F,currentLineOverride:O,streamingMode:z="text",renderCodeBlocksAsPlainText:_=!1})=>{let B=$0(),L=F!==void 0,w=D3(()=>ew(Z,B.colors,Q),[Z,B.colors,Q]),{color:N,prefix:D}=w,V=D.length+1,I=Z==="tool"&&Q?.phase==="start",v=!K&&!I,b=D3(()=>{if(!q)return[];return $.split(/\r?\n/)},[$,q]);if(!L&&X){let y=W??$.split(/\r?\n/),u=U??0,s=!1,i=!1,Y$=!1;if(z!=="text")s=z==="code",i=z==="diff",Y$=z==="table";return x(V$,{flexDirection:"column",marginBottom:v?1:0,flexShrink:0,children:[u>0&&x(V$,{flexDirection:"row",flexShrink:0,children:[x(V$,{width:V,flexShrink:0},void 0,!1,void 0,this),x(s$,{color:B.colors.text.muted,dimColor:!0,children:["↑ ",u," lines above (streaming...)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),y.map((f,w$)=>{if(z==="text"){if(f.match(y$.codeBlock))s=!s;else if(f.match(y$.diffStart))i=!0;else if(f.match(y$.diffEnd))i=!1;else if(f.match(y$.table))Y$=!0;else if(Y$&&!f.match(y$.table))Y$=!1}let G$=z==="text"&&!s&&!i&&!Y$,N$=G$?f.match(y$.ulItem):null,X0=G$?f.match(y$.olItem):null,G0=N$??X0;return x(V$,{flexDirection:"row",flexShrink:0,children:[w$===0&&!G?x(V$,{marginRight:1,flexShrink:0,children:x(s$,{color:N,bold:!0,children:D},void 0,!1,void 0,this)},void 0,!1,void 0,this):x(V$,{width:V,flexShrink:0},void 0,!1,void 0,this),x(V$,{flexGrow:1,flexShrink:0,children:G0?x(dZ,{type:N$?"ul":"ol",marker:G0[2],itemText:G0[3],leadingWhitespace:G0[1]},void 0,!1,void 0,this):x(s$,{wrap:"wrap",children:f===""?" ":f},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},w$,!0,void 0,this)})]},void 0,!0,void 0,this)}if(!L&&q)return x(V$,{flexDirection:"column",marginBottom:v?1:0,flexShrink:0,children:b.map((y,u)=>x(V$,{flexDirection:"row",flexShrink:0,children:[u===0&&!G?x(V$,{marginRight:1,flexShrink:0,children:x(s$,{color:N,bold:!0,children:D},void 0,!1,void 0,this)},void 0,!1,void 0,this):x(V$,{width:V,flexShrink:0},void 0,!1,void 0,this),x(V$,{flexGrow:1,flexShrink:0,children:x(s$,{wrap:"wrap",children:y===""?" ":y},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},u,!0,void 0,this))},void 0,!1,void 0,this);let C=eW(null);gZ(()=>{C.current=null},[H]);let d=D3(()=>{if(L)return null;if(!H)return null;return dY(H)},[H,L]);gZ(()=>{if(L)return;if(!d||!H)return;C.current={messageId:H,blocks:d}},[d,H,L]),gZ(()=>{if(L)return;if(!d||!H)return;gY(H)},[d,H,L]);let e=D3(()=>L?{content:$,isTruncated:!1,hiddenLines:0}:GN($,J,X,Y),[$,J,X,Y,L]),{content:k,isTruncated:T,hiddenLines:g}=e;if(!L&&Z==="tool"&&Q&&"detail"in Q){let y=Q;if(y.detail)return x(V$,{flexDirection:"column",marginBottom:K?0:1,children:[x(V$,{flexDirection:"row",children:[x(V$,{marginRight:1,children:x(s$,{color:N,bold:!0,children:D},void 0,!1,void 0,this)},void 0,!1,void 0,this),x(s$,{color:N,children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),x(V$,{marginLeft:D.length+1,children:x(JN,{detail:y.detail,terminalWidth:Y-(D.length+1)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}let{completedContent:j,currentLine:M}=D3(()=>{if(L)return{completedContent:"",currentLine:O??""};if(!X)return{completedContent:k,currentLine:""};let y=k.lastIndexOf(`
2838
- `);if(y===-1)return{completedContent:"",currentLine:k};return{completedContent:k.slice(0,y+1),currentLine:k.slice(y+1)}},[k,X,L,O]),R=eW({content:"",blocks:[]}),n=D3(()=>{if(L)return F??[];if(d)return d;if(C.current&&C.current.messageId===H)return C.current.blocks;let y=R.current;if(!X||!j.startsWith(y.content)){let Y$=n2(j);return R.current={content:j,blocks:Y$},Y$}if(j===y.content)return y.blocks;let u=j.slice(y.content.length),s=n2(u),i=[...y.blocks,...s];return R.current={content:j,blocks:i},i},[j,X,L,F]);return x(V$,{flexDirection:"column",marginBottom:v?1:0,flexShrink:0,children:[T&&x(V$,{flexDirection:"row",flexShrink:0,children:[x(V$,{width:V,flexShrink:0},void 0,!1,void 0,this),x(s$,{color:B.colors.text.muted,dimColor:!0,children:["↑ ",g," lines above (streaming...)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),n.map((y,u)=>{if(y.type==="empty")return x(V$,{height:1,flexShrink:0},u,!1,void 0,this);return x(V$,{flexDirection:"row",flexShrink:0,children:[u===0&&!G&&x(V$,{marginRight:1,flexShrink:0,children:x(s$,{color:N,bold:!0,children:D},void 0,!1,void 0,this)},void 0,!1,void 0,this),(u>0||G)&&x(V$,{width:V,flexShrink:0},void 0,!1,void 0,this),x(V$,{flexGrow:1,flexShrink:0,children:y.type==="code"?_?x(s$,{wrap:"wrap",children:y.content},void 0,!1,void 0,this):x($N,{content:y.content,language:y.language,terminalWidth:Y-V,isPending:X,availableHeight:J},void 0,!1,void 0,this):y.type==="table"&&y.tableData?x(tW,{headers:y.tableData.headers,rows:y.tableData.rows,terminalWidth:Y-V},void 0,!1,void 0,this):y.type==="heading"?x(ZN,{content:y.content,level:y.level||1},void 0,!1,void 0,this):y.type==="list"?x(dZ,{type:y.listType||"ul",marker:y.marker||"-",itemText:y.content,leadingWhitespace:" ".repeat(y.indentation||0)},void 0,!1,void 0,this):y.type==="hr"?x(YN,{terminalWidth:Y-V},void 0,!1,void 0,this):y.type==="diff"&&y.diffData?x(kZ,{patch:y.diffData.patch,startLine:y.diffData.startLine,matchLine:y.diffData.matchLine,terminalWidth:Y-V},void 0,!1,void 0,this):y.type==="command-message"?x(XN,{content:y.content},void 0,!1,void 0,this):x(QN,{content:y.content},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},u,!0,void 0,this)}),M&&x(V$,{flexDirection:"row",flexShrink:0,children:[n.length===0&&!G?x(V$,{marginRight:1,flexShrink:0,children:x(s$,{color:N,bold:!0,children:D},void 0,!1,void 0,this)},void 0,!1,void 0,this):x(V$,{width:V,flexShrink:0},void 0,!1,void 0,this),x(V$,{flexGrow:1,flexShrink:0,children:x(s$,{wrap:"wrap",children:M},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},($,Z)=>{return $.content===Z.content&&$.role===Z.role&&$.terminalWidth===Z.terminalWidth&&$.isPending===Z.isPending&&$.availableTerminalHeight===Z.availableTerminalHeight&&$.hidePrefix===Z.hidePrefix&&$.noMargin===Z.noMargin&&$.renderPlainTextOnly===Z.renderPlainTextOnly&&$.streamingHiddenLines===Z.streamingHiddenLines&&$.streamingLines===Z.streamingLines&&$.messageId===Z.messageId&&$.metadata===Z.metadata&&$.blocksOverride===Z.blocksOverride&&$.currentLineOverride===Z.currentLineOverride&&$.streamingMode===Z.streamingMode&&$.renderCodeBlocksAsPlainText===Z.renderCodeBlocksAsPlainText});import{jsxDEV as l$,Fragment as FN}from"react/jsx-dev-runtime";var UN=cZ.memo(({label:$,isSelected:Z})=>l$(S1,{color:Z?"yellow":void 0,children:$},void 0,!1,void 0,this)),HN=cZ.memo(({details:$,headerColor:Z,isPlanModeExit:Y,isPlanModeEnter:Q,terminalWidth:X})=>l$(FN,{children:[$.title&&l$(b1,{marginBottom:1,children:l$(S1,{bold:!0,children:$.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),l$(b1,{marginBottom:1,children:l$(S1,{children:$.message},void 0,!1,void 0,this)},void 0,!1,void 0,this),($.planContent||$.details)&&l$(b1,{flexDirection:"column",marginBottom:1,borderStyle:"single",borderColor:Z,padding:1,children:[l$(S1,{bold:!0,color:Z,children:Y?"\uD83D\uDCCB Implementation Plan:":Q?"\uD83D\uDCDD Details:":"\uD83D\uDCC4 Operation Details:"},void 0,!1,void 0,this),l$(b1,{marginTop:1,children:l$(x2,{content:$.planContent||$.details||"",role:"assistant",terminalWidth:X-4},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$.risks&&$.risks.length>0&&l$(b1,{flexDirection:"column",marginBottom:1,children:[l$(S1,{color:"red",bold:!0,children:"⚠️ 风险提示:"},void 0,!1,void 0,this),$.risks.map((J,G)=>l$(b1,{marginLeft:2,children:l$(S1,{color:"red",children:["• ",J]},void 0,!0,void 0,this)},G,!1,void 0,this))]},void 0,!0,void 0,this),$.affectedFiles&&$.affectedFiles.length>0&&l$(b1,{flexDirection:"column",marginBottom:1,children:[l$(S1,{color:"yellow",children:"\uD83D\uDCC1 影响的文件:"},void 0,!1,void 0,this),$.affectedFiles.slice(0,3).map((J,G)=>l$(b1,{marginLeft:2,children:l$(S1,{children:["• ",J]},void 0,!0,void 0,this)},G,!1,void 0,this)),$.affectedFiles.length>3&&l$(b1,{marginLeft:2,children:l$(S1,{color:"gray",children:["...还有 ",$.affectedFiles.length-3," 个文件"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)),ZU=cZ.memo(({details:$,onResponse:Z})=>{let{stdout:Y}=qN(),Q=Y.columns||80,J=Z1()==="confirmation-prompt",G=Q0(!1),K=$.type==="exitPlanMode",q=$.type==="enterPlanMode",W=$.type==="maxTurnsExceeded";KN((F,O)=>{if(O.ctrl&&F==="c"||O.meta&&F==="c"){G();return}if(O.escape){Z({approved:!1,reason:"用户取消"});return}let z=F.toLowerCase();if(K){if(z==="y"){Z({approved:!0,targetMode:"autoEdit"});return}if(z==="s"){Z({approved:!0,targetMode:"default"});return}if(z==="n"){Z({approved:!1,reason:"方案需要改进"});return}}else if(q){if(z==="y"){Z({approved:!0});return}if(z==="n"){Z({approved:!1,reason:"用户拒绝进入 Plan 模式"});return}}else if(W){if(z==="y"){Z({approved:!0});return}if(z==="n"){Z({approved:!1,reason:"用户选择停止"});return}}else{if(z==="y"){Z({approved:!0,scope:"once"});return}if(z==="s"){Z({approved:!0,scope:"session"});return}if(z==="n"){Z({approved:!1,reason:"用户拒绝"});return}}},{isActive:J});let U=$U(()=>{if(K)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(q)return[{key:"approve",label:"[Y] Yes, enter Plan mode",value:{approved:!0}},{key:"reject",label:"[N] No, proceed directly",value:{approved:!1,reason:"用户拒绝进入 Plan 模式"}}];if(W)return[{key:"continue",label:"[Y] Yes, continue",value:{approved:!0}},{key:"stop",label:"[N] No, stop here",value:{approved:!1,reason:"用户选择停止"}}];return[{key:"approve-once",label:"[Y] Yes (once only)",value:{approved:!0,scope:"once"}},{key:"approve-session",label:"[S] Yes, remember for this project (Shift+Tab)",value:{approved:!0,scope:"session"}},{key:"reject",label:"[N] No",value:{approved:!1,reason:"用户拒绝"}}]},[K,q,W]),H=$U(()=>{if(K)return{color:"cyan",title:"\uD83D\uDD35 Plan Mode - Review Implementation Plan"};if(q)return{color:"magenta",title:"\uD83D\uDFE3 Enter Plan Mode?"};if(W)return{color:"yellow",title:"⚡ Max Turns Exceeded"};return{color:"yellow",title:"\uD83D\uDD14 Confirmation Required"}},[K,q,W]);return l$(b1,{flexDirection:"column",borderStyle:"round",borderColor:J?H.color:"gray",padding:1,children:[l$(b1,{marginBottom:1,children:l$(S1,{bold:!0,color:H.color,children:H.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),l$(HN,{details:$,headerColor:H.color,isPlanModeExit:K,isPlanModeEnter:q,terminalWidth:Q},void 0,!1,void 0,this),l$(b1,{flexDirection:"column",children:[l$(S1,{color:"gray",children:"使用 ↑ ↓ 选择,回车确认(支持 Y/S/N 快捷键,ESC 取消)"},void 0,!1,void 0,this),l$(WN,{items:U,isFocused:J,itemComponent:UN,onSelect:(F)=>{Z(F.value)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});t0();m4();r2();import{Box as j$,Text as F$,useInput as ON}from"ink";import YU from"ink-text-input";import{useState as W2}from"react";import{jsxDEV as p}from"react/jsx-dev-runtime";var j8=[{action:"add",description:"Add a new hook"},{action:"status",description:"Show hooks status"},{action:"list",description:"List all configured hooks"}],W6=[{location:"local",name:"Project settings (local)",description:"Saved in .blade/settings.local.json"},{location:"project",name:"Project settings",description:"Checked in at .blade/settings.json"},{location:"user",name:"User settings",description:"Saved in at ~/.blade/settings.json"}],U6=[{event:"PreToolUse",description:"Before tool execution"},{event:"PostToolUse",description:"After tool execution"},{event:"PostToolUseFailure",description:"After tool execution fails"},{event:"PermissionRequest",description:"When permission is requested"},{event:"UserPromptSubmit",description:"Before processing user prompt"},{event:"Stop",description:"When Claude stops responding"},{event:"SubagentStop",description:"When subagent stops"},{event:"SessionStart",description:"When session starts"},{event:"SessionEnd",description:"When session ends"},{event:"Notification",description:"When notification is sent"},{event:"Compaction",description:"Before context compaction"}],zN=[`jq -r '.tool_input.file_path | select(endswith(".go"))' | xargs -r gofmt -w`,`jq -r '"\\(.tool_input.command) - \\(.tool_input.description // "No description")"' >> ~/.blade/bash-command-log.txt`,"/usr/local/bin/security_check.sh","python3 ~/hooks/validate_changes.py"],QU=({onClose:$,onSave:Z})=>{let Y=g0.getTheme(),[Q,X]=W2("action"),[J,G]=W2(0),[K,q]=W2(0),[W,U]=W2(0),[H,F]=W2(""),[O,z]=W2(""),[_,B]=W2(null),[L,w]=W2(!1),[N,D]=W2(null),V=j8[J],I=U6[K],v=W6[W],b=()=>{if(N){D(null);return}switch(Q){case"action":$();break;case"event":X("action");break;case"matcher":X("event");break;case"command":X("matcher");break;case"location":X("command");break;case"confirm":X("location");break}};ON((j,M)=>{if(M.escape){b();return}if(Q==="action"){if(M.upArrow)G((R)=>R>0?R-1:j8.length-1);else if(M.downArrow)G((R)=>R<j8.length-1?R+1:0);else if(M.return)C()}else if(Q==="event"){if(M.upArrow)q((R)=>R>0?R-1:U6.length-1);else if(M.downArrow)q((R)=>R<U6.length-1?R+1:0);else if(M.return)X("matcher")}else if(Q==="location"){if(M.upArrow)U((R)=>R>0?R-1:W6.length-1);else if(M.downArrow)U((R)=>R<W6.length-1?R+1:0);else if(M.return)X("confirm")}else if(Q==="confirm"){if(M.return)g()}});let C=()=>{let j=j8[J].action;if(j==="add")X("event");else if(j==="status")d();else if(j==="list")e()},d=()=>{let j=M$.getInstance(),M=j.isEnabled(),R=j.getConfig(),n={};for(let u of Object.values(x1)){let s=R[u];if(s&&Array.isArray(s)){let i=s.reduce((Y$,f)=>Y$+(f.hooks?.length||0),0);if(i>0)n[u]=i}}let y=[`Status: ${M?"✅ Enabled":"⏸️ Disabled"}`,""];if(Object.keys(n).length>0){y.push("Configured hooks:");for(let[u,s]of Object.entries(n))y.push(` ${u}: ${s} hook(s)`)}else y.push("No hooks configured");D(y.join(`
2837
+ `,W);if(H!==-1&&H-W<G)U=H+1;let F=$.slice(U),z=($.slice(0,U).match(/\n/g)||[]).length+1;return{content:F,isTruncated:!0,hiddenLines:z}}var x4=R2.memo(({content:$,role:Z,terminalWidth:Y,metadata:Q,isPending:X=!1,availableTerminalHeight:J,hidePrefix:G=!1,noMargin:K=!1,renderPlainTextOnly:q=!1,streamingLines:W,streamingHiddenLines:U,messageId:H,blocksOverride:F,currentLineOverride:O,streamingMode:z="text",renderCodeBlocksAsPlainText:_=!1})=>{let B=$0(),L=F!==void 0,w=D8(()=>ew(Z,B.colors,Q),[Z,B.colors,Q]),{color:N,prefix:D}=w,V=D.length+1,I=Z==="tool"&&Q?.phase==="start",v=!K&&!I,b=D8(()=>{if(!q)return[];return $.split(/\r?\n/)},[$,q]);if(!L&&X){let y=W??$.split(/\r?\n/),u=U??0,s=!1,i=!1,Y$=!1;if(z!=="text")s=z==="code",i=z==="diff",Y$=z==="table";return x(V$,{flexDirection:"column",marginBottom:v?1:0,flexShrink:0,children:[u>0&&x(V$,{flexDirection:"row",flexShrink:0,children:[x(V$,{width:V,flexShrink:0},void 0,!1,void 0,this),x(s$,{color:B.colors.text.muted,dimColor:!0,children:["↑ ",u," lines above (streaming...)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),y.map((f,w$)=>{if(z==="text"){if(f.match(y$.codeBlock))s=!s;else if(f.match(y$.diffStart))i=!0;else if(f.match(y$.diffEnd))i=!1;else if(f.match(y$.table))Y$=!0;else if(Y$&&!f.match(y$.table))Y$=!1}let G$=z==="text"&&!s&&!i&&!Y$,N$=G$?f.match(y$.ulItem):null,X0=G$?f.match(y$.olItem):null,G0=N$??X0;return x(V$,{flexDirection:"row",flexShrink:0,children:[w$===0&&!G?x(V$,{marginRight:1,flexShrink:0,children:x(s$,{color:N,bold:!0,children:D},void 0,!1,void 0,this)},void 0,!1,void 0,this):x(V$,{width:V,flexShrink:0},void 0,!1,void 0,this),x(V$,{flexGrow:1,flexShrink:0,children:G0?x(dZ,{type:N$?"ul":"ol",marker:G0[2],itemText:G0[3],leadingWhitespace:G0[1]},void 0,!1,void 0,this):x(s$,{wrap:"wrap",children:f===""?" ":f},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},w$,!0,void 0,this)})]},void 0,!0,void 0,this)}if(!L&&q)return x(V$,{flexDirection:"column",marginBottom:v?1:0,flexShrink:0,children:b.map((y,u)=>x(V$,{flexDirection:"row",flexShrink:0,children:[u===0&&!G?x(V$,{marginRight:1,flexShrink:0,children:x(s$,{color:N,bold:!0,children:D},void 0,!1,void 0,this)},void 0,!1,void 0,this):x(V$,{width:V,flexShrink:0},void 0,!1,void 0,this),x(V$,{flexGrow:1,flexShrink:0,children:x(s$,{wrap:"wrap",children:y===""?" ":y},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},u,!0,void 0,this))},void 0,!1,void 0,this);let C=eW(null);gZ(()=>{C.current=null},[H]);let d=D8(()=>{if(L)return null;if(!H)return null;return dY(H)},[H,L]);gZ(()=>{if(L)return;if(!d||!H)return;C.current={messageId:H,blocks:d}},[d,H,L]),gZ(()=>{if(L)return;if(!d||!H)return;gY(H)},[d,H,L]);let e=D8(()=>L?{content:$,isTruncated:!1,hiddenLines:0}:GN($,J,X,Y),[$,J,X,Y,L]),{content:k,isTruncated:T,hiddenLines:g}=e;if(!L&&Z==="tool"&&Q&&"detail"in Q){let y=Q;if(y.detail)return x(V$,{flexDirection:"column",marginBottom:K?0:1,children:[x(V$,{flexDirection:"row",children:[x(V$,{marginRight:1,children:x(s$,{color:N,bold:!0,children:D},void 0,!1,void 0,this)},void 0,!1,void 0,this),x(s$,{color:N,children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),x(V$,{marginLeft:D.length+1,children:x(JN,{detail:y.detail,terminalWidth:Y-(D.length+1)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}let{completedContent:j,currentLine:M}=D8(()=>{if(L)return{completedContent:"",currentLine:O??""};if(!X)return{completedContent:k,currentLine:""};let y=k.lastIndexOf(`
2838
+ `);if(y===-1)return{completedContent:"",currentLine:k};return{completedContent:k.slice(0,y+1),currentLine:k.slice(y+1)}},[k,X,L,O]),R=eW({content:"",blocks:[]}),n=D8(()=>{if(L)return F??[];if(d)return d;if(C.current&&C.current.messageId===H)return C.current.blocks;let y=R.current;if(!X||!j.startsWith(y.content)){let Y$=n4(j);return R.current={content:j,blocks:Y$},Y$}if(j===y.content)return y.blocks;let u=j.slice(y.content.length),s=n4(u),i=[...y.blocks,...s];return R.current={content:j,blocks:i},i},[j,X,L,F]);return x(V$,{flexDirection:"column",marginBottom:v?1:0,flexShrink:0,children:[T&&x(V$,{flexDirection:"row",flexShrink:0,children:[x(V$,{width:V,flexShrink:0},void 0,!1,void 0,this),x(s$,{color:B.colors.text.muted,dimColor:!0,children:["↑ ",g," lines above (streaming...)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),n.map((y,u)=>{if(y.type==="empty")return x(V$,{height:1,flexShrink:0},u,!1,void 0,this);return x(V$,{flexDirection:"row",flexShrink:0,children:[u===0&&!G&&x(V$,{marginRight:1,flexShrink:0,children:x(s$,{color:N,bold:!0,children:D},void 0,!1,void 0,this)},void 0,!1,void 0,this),(u>0||G)&&x(V$,{width:V,flexShrink:0},void 0,!1,void 0,this),x(V$,{flexGrow:1,flexShrink:0,children:y.type==="code"?_?x(s$,{wrap:"wrap",children:y.content},void 0,!1,void 0,this):x($N,{content:y.content,language:y.language,terminalWidth:Y-V,isPending:X,availableHeight:J},void 0,!1,void 0,this):y.type==="table"&&y.tableData?x(tW,{headers:y.tableData.headers,rows:y.tableData.rows,terminalWidth:Y-V},void 0,!1,void 0,this):y.type==="heading"?x(ZN,{content:y.content,level:y.level||1},void 0,!1,void 0,this):y.type==="list"?x(dZ,{type:y.listType||"ul",marker:y.marker||"-",itemText:y.content,leadingWhitespace:" ".repeat(y.indentation||0)},void 0,!1,void 0,this):y.type==="hr"?x(YN,{terminalWidth:Y-V},void 0,!1,void 0,this):y.type==="diff"&&y.diffData?x(kZ,{patch:y.diffData.patch,startLine:y.diffData.startLine,matchLine:y.diffData.matchLine,terminalWidth:Y-V},void 0,!1,void 0,this):y.type==="command-message"?x(XN,{content:y.content},void 0,!1,void 0,this):x(QN,{content:y.content},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},u,!0,void 0,this)}),M&&x(V$,{flexDirection:"row",flexShrink:0,children:[n.length===0&&!G?x(V$,{marginRight:1,flexShrink:0,children:x(s$,{color:N,bold:!0,children:D},void 0,!1,void 0,this)},void 0,!1,void 0,this):x(V$,{width:V,flexShrink:0},void 0,!1,void 0,this),x(V$,{flexGrow:1,flexShrink:0,children:x(s$,{wrap:"wrap",children:M},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},($,Z)=>{return $.content===Z.content&&$.role===Z.role&&$.terminalWidth===Z.terminalWidth&&$.isPending===Z.isPending&&$.availableTerminalHeight===Z.availableTerminalHeight&&$.hidePrefix===Z.hidePrefix&&$.noMargin===Z.noMargin&&$.renderPlainTextOnly===Z.renderPlainTextOnly&&$.streamingHiddenLines===Z.streamingHiddenLines&&$.streamingLines===Z.streamingLines&&$.messageId===Z.messageId&&$.metadata===Z.metadata&&$.blocksOverride===Z.blocksOverride&&$.currentLineOverride===Z.currentLineOverride&&$.streamingMode===Z.streamingMode&&$.renderCodeBlocksAsPlainText===Z.renderCodeBlocksAsPlainText});import{jsxDEV as l$,Fragment as FN}from"react/jsx-dev-runtime";var UN=cZ.memo(({label:$,isSelected:Z})=>l$(S1,{color:Z?"yellow":void 0,children:$},void 0,!1,void 0,this)),HN=cZ.memo(({details:$,headerColor:Z,isPlanModeExit:Y,isPlanModeEnter:Q,terminalWidth:X})=>l$(FN,{children:[$.title&&l$(b1,{marginBottom:1,children:l$(S1,{bold:!0,children:$.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),l$(b1,{marginBottom:1,children:l$(S1,{children:$.message},void 0,!1,void 0,this)},void 0,!1,void 0,this),($.planContent||$.details)&&l$(b1,{flexDirection:"column",marginBottom:1,borderStyle:"single",borderColor:Z,padding:1,children:[l$(S1,{bold:!0,color:Z,children:Y?"\uD83D\uDCCB Implementation Plan:":Q?"\uD83D\uDCDD Details:":"\uD83D\uDCC4 Operation Details:"},void 0,!1,void 0,this),l$(b1,{marginTop:1,children:l$(x4,{content:$.planContent||$.details||"",role:"assistant",terminalWidth:X-4},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$.risks&&$.risks.length>0&&l$(b1,{flexDirection:"column",marginBottom:1,children:[l$(S1,{color:"red",bold:!0,children:"⚠️ 风险提示:"},void 0,!1,void 0,this),$.risks.map((J,G)=>l$(b1,{marginLeft:2,children:l$(S1,{color:"red",children:["• ",J]},void 0,!0,void 0,this)},G,!1,void 0,this))]},void 0,!0,void 0,this),$.affectedFiles&&$.affectedFiles.length>0&&l$(b1,{flexDirection:"column",marginBottom:1,children:[l$(S1,{color:"yellow",children:"\uD83D\uDCC1 影响的文件:"},void 0,!1,void 0,this),$.affectedFiles.slice(0,3).map((J,G)=>l$(b1,{marginLeft:2,children:l$(S1,{children:["• ",J]},void 0,!0,void 0,this)},G,!1,void 0,this)),$.affectedFiles.length>3&&l$(b1,{marginLeft:2,children:l$(S1,{color:"gray",children:["...还有 ",$.affectedFiles.length-3," 个文件"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)),ZU=cZ.memo(({details:$,onResponse:Z})=>{let{stdout:Y}=qN(),Q=Y.columns||80,J=Z1()==="confirmation-prompt",G=Q0(!1),K=$.type==="exitPlanMode",q=$.type==="enterPlanMode",W=$.type==="maxTurnsExceeded";KN((F,O)=>{if(O.ctrl&&F==="c"||O.meta&&F==="c"){G();return}if(O.escape){Z({approved:!1,reason:"用户取消"});return}let z=F.toLowerCase();if(K){if(z==="y"){Z({approved:!0,targetMode:"autoEdit"});return}if(z==="s"){Z({approved:!0,targetMode:"default"});return}if(z==="n"){Z({approved:!1,reason:"方案需要改进"});return}}else if(q){if(z==="y"){Z({approved:!0});return}if(z==="n"){Z({approved:!1,reason:"用户拒绝进入 Plan 模式"});return}}else if(W){if(z==="y"){Z({approved:!0});return}if(z==="n"){Z({approved:!1,reason:"用户选择停止"});return}}else{if(z==="y"){Z({approved:!0,scope:"once"});return}if(z==="s"){Z({approved:!0,scope:"session"});return}if(z==="n"){Z({approved:!1,reason:"用户拒绝"});return}}},{isActive:J});let U=$U(()=>{if(K)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(q)return[{key:"approve",label:"[Y] Yes, enter Plan mode",value:{approved:!0}},{key:"reject",label:"[N] No, proceed directly",value:{approved:!1,reason:"用户拒绝进入 Plan 模式"}}];if(W)return[{key:"continue",label:"[Y] Yes, continue",value:{approved:!0}},{key:"stop",label:"[N] No, stop here",value:{approved:!1,reason:"用户选择停止"}}];return[{key:"approve-once",label:"[Y] Yes (once only)",value:{approved:!0,scope:"once"}},{key:"approve-session",label:"[S] Yes, remember for this project (Shift+Tab)",value:{approved:!0,scope:"session"}},{key:"reject",label:"[N] No",value:{approved:!1,reason:"用户拒绝"}}]},[K,q,W]),H=$U(()=>{if(K)return{color:"cyan",title:"\uD83D\uDD35 Plan Mode - Review Implementation Plan"};if(q)return{color:"magenta",title:"\uD83D\uDFE3 Enter Plan Mode?"};if(W)return{color:"yellow",title:"⚡ Max Turns Exceeded"};return{color:"yellow",title:"\uD83D\uDD14 Confirmation Required"}},[K,q,W]);return l$(b1,{flexDirection:"column",borderStyle:"round",borderColor:J?H.color:"gray",padding:1,children:[l$(b1,{marginBottom:1,children:l$(S1,{bold:!0,color:H.color,children:H.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),l$(HN,{details:$,headerColor:H.color,isPlanModeExit:K,isPlanModeEnter:q,terminalWidth:Q},void 0,!1,void 0,this),l$(b1,{flexDirection:"column",children:[l$(S1,{color:"gray",children:"使用 ↑ ↓ 选择,回车确认(支持 Y/S/N 快捷键,ESC 取消)"},void 0,!1,void 0,this),l$(WN,{items:U,isFocused:J,itemComponent:UN,onSelect:(F)=>{Z(F.value)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});t0();m2();r4();import{Box as j$,Text as F$,useInput as ON}from"ink";import YU from"ink-text-input";import{useState as W4}from"react";import{jsxDEV as p}from"react/jsx-dev-runtime";var j3=[{action:"add",description:"Add a new hook"},{action:"status",description:"Show hooks status"},{action:"list",description:"List all configured hooks"}],W6=[{location:"local",name:"Project settings (local)",description:"Saved in .blade/settings.local.json"},{location:"project",name:"Project settings",description:"Checked in at .blade/settings.json"},{location:"user",name:"User settings",description:"Saved in at ~/.blade/settings.json"}],U6=[{event:"PreToolUse",description:"Before tool execution"},{event:"PostToolUse",description:"After tool execution"},{event:"PostToolUseFailure",description:"After tool execution fails"},{event:"PermissionRequest",description:"When permission is requested"},{event:"UserPromptSubmit",description:"Before processing user prompt"},{event:"Stop",description:"When Claude stops responding"},{event:"SubagentStop",description:"When subagent stops"},{event:"SessionStart",description:"When session starts"},{event:"SessionEnd",description:"When session ends"},{event:"Notification",description:"When notification is sent"},{event:"Compaction",description:"Before context compaction"}],zN=[`jq -r '.tool_input.file_path | select(endswith(".go"))' | xargs -r gofmt -w`,`jq -r '"\\(.tool_input.command) - \\(.tool_input.description // "No description")"' >> ~/.blade/bash-command-log.txt`,"/usr/local/bin/security_check.sh","python3 ~/hooks/validate_changes.py"],QU=({onClose:$,onSave:Z})=>{let Y=g0.getTheme(),[Q,X]=W4("action"),[J,G]=W4(0),[K,q]=W4(0),[W,U]=W4(0),[H,F]=W4(""),[O,z]=W4(""),[_,B]=W4(null),[L,w]=W4(!1),[N,D]=W4(null),V=j3[J],I=U6[K],v=W6[W],b=()=>{if(N){D(null);return}switch(Q){case"action":$();break;case"event":X("action");break;case"matcher":X("event");break;case"command":X("matcher");break;case"location":X("command");break;case"confirm":X("location");break}};ON((j,M)=>{if(M.escape){b();return}if(Q==="action"){if(M.upArrow)G((R)=>R>0?R-1:j3.length-1);else if(M.downArrow)G((R)=>R<j3.length-1?R+1:0);else if(M.return)C()}else if(Q==="event"){if(M.upArrow)q((R)=>R>0?R-1:U6.length-1);else if(M.downArrow)q((R)=>R<U6.length-1?R+1:0);else if(M.return)X("matcher")}else if(Q==="location"){if(M.upArrow)U((R)=>R>0?R-1:W6.length-1);else if(M.downArrow)U((R)=>R<W6.length-1?R+1:0);else if(M.return)X("confirm")}else if(Q==="confirm"){if(M.return)g()}});let C=()=>{let j=j3[J].action;if(j==="add")X("event");else if(j==="status")d();else if(j==="list")e()},d=()=>{let j=M$.getInstance(),M=j.isEnabled(),R=j.getConfig(),n={};for(let u of Object.values(x1)){let s=R[u];if(s&&Array.isArray(s)){let i=s.reduce((Y$,f)=>Y$+(f.hooks?.length||0),0);if(i>0)n[u]=i}}let y=[`Status: ${M?"✅ Enabled":"⏸️ Disabled"}`,""];if(Object.keys(n).length>0){y.push("Configured hooks:");for(let[u,s]of Object.entries(n))y.push(` ${u}: ${s} hook(s)`)}else y.push("No hooks configured");D(y.join(`
2839
2839
  `))},e=()=>{let M=M$.getInstance().getConfig(),R=[],n=!1;for(let y of Object.values(x1)){let u=M[y];if(!u||!Array.isArray(u)||u.length===0)continue;n=!0,R.push(`${y}:`);for(let s of u){let i=s.matcher,Y$="all";if(i?.tools)Y$=`tools: ${Array.isArray(i.tools)?i.tools.join(", "):i.tools}`;R.push(` [${Y$}]`);for(let f of s.hooks||[])if(f.type==="command")R.push(` → ${f.command}`)}R.push("")}if(!n)R.push("No hooks configured"),R.push(""),R.push("Configure hooks in .blade/settings.local.json");D(R.join(`
2840
- `))},k=()=>{X("command")},T=()=>{if(!O.trim()){B("Command cannot be empty");return}B(null),X("location")},g=async()=>{w(!0),B(null);try{let j=M$.getInstance(),M=await import("node:fs/promises"),R=await import("node:path"),n=await import("node:os"),y={matcher:H.trim()?{tools:H.trim()}:{},hooks:[{type:"command",command:O.trim()}]},u;switch(v.location){case"local":u=R.join(process.cwd(),".blade","settings.local.json");break;case"project":u=R.join(process.cwd(),".blade","settings.json");break;case"user":u=R.join(n.homedir(),".blade","settings.json");break}await M.mkdir(R.dirname(u),{recursive:!0});let s={};try{let w$=await M.readFile(u,"utf-8");s=JSON.parse(w$)}catch{}let i=s.hooks||{},Y$=i[I.event]||[],f={...i,enabled:!0,[I.event]:[...Y$,y]};if(s.hooks=f,await M.writeFile(u,JSON.stringify(s,null,2),"utf-8"),await j.reloadConfig(),Z)Z({event:I.event,matcher:H.trim(),command:O.trim()});$()}catch(j){B(`Failed to save hook: ${j instanceof Error?j.message:"Unknown error"}`),w(!1)}};return p(j$,{flexDirection:"column",padding:1,children:[p(j$,{marginBottom:1,children:p(F$,{bold:!0,color:Y.colors.success,children:"Hooks Manager"},void 0,!1,void 0,this)},void 0,!1,void 0,this),p(j$,{marginBottom:1,children:p(F$,{color:Y.colors.warning,children:"⚠ Hooks execute shell commands with your full user permissions. Only use hooks from trusted sources."},void 0,!1,void 0,this)},void 0,!1,void 0,this),N&&p(j$,{flexDirection:"column",marginBottom:1,children:[p(F$,{children:N},void 0,!1,void 0,this),p(j$,{marginTop:1,children:p(F$,{color:Y.colors.muted,children:"Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="action"&&!N&&p(j$,{flexDirection:"column",children:[p(j$,{flexDirection:"column",marginTop:1,children:j8.map((j,M)=>p(j$,{children:[p(F$,{color:M===J?Y.colors.primary:void 0,bold:M===J,children:[M===J?"❯ ":" ",j.action]},void 0,!0,void 0,this),p(F$,{color:Y.colors.muted,children:[" - ",j.description]},void 0,!0,void 0,this)]},j.action,!0,void 0,this))},void 0,!1,void 0,this),p(j$,{marginTop:1,children:p(F$,{color:Y.colors.muted,children:"↑/↓ to select · Enter to continue · Esc to close"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="event"&&p(j$,{flexDirection:"column",children:[p(F$,{bold:!0,children:"Select Event:"},void 0,!1,void 0,this),p(j$,{flexDirection:"column",marginTop:1,children:U6.map((j,M)=>p(j$,{children:[p(F$,{color:M===K?Y.colors.primary:void 0,bold:M===K,children:[M===K?"❯ ":" ",j.event]},void 0,!0,void 0,this),p(F$,{color:Y.colors.muted,children:[" - ",j.description]},void 0,!0,void 0,this)]},j.event,!0,void 0,this))},void 0,!1,void 0,this),p(j$,{marginTop:1,children:p(F$,{color:Y.colors.muted,children:"↑/↓ to select · Enter to continue · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q!=="event"&&p(j$,{marginBottom:1,children:p(F$,{children:["Event:"," ",p(F$,{bold:!0,color:Y.colors.primary,children:I.event},void 0,!1,void 0,this),p(F$,{color:Y.colors.muted,children:[" - ",I.description]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),(Q==="matcher"||Q==="command"||Q==="confirm")&&p(j$,{flexDirection:"column",marginBottom:1,children:[p(F$,{color:Y.colors.muted,children:"Input to command is JSON of tool call arguments."},void 0,!1,void 0,this),p(F$,{color:Y.colors.muted,children:"Exit code 0 - stdout/stderr not shown"},void 0,!1,void 0,this),p(F$,{color:Y.colors.muted,children:"Exit code 2 - show stderr to model and block tool call"},void 0,!1,void 0,this),p(F$,{color:Y.colors.muted,children:"Other exit codes - show stderr to user only but continue with tool call"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="matcher"&&p(j$,{flexDirection:"column",children:[p(j$,{children:[p(F$,{bold:!0,children:"Matcher: "},void 0,!1,void 0,this),p(YU,{value:H,onChange:F,onSubmit:k,placeholder:"e.g., Read, Bash, Edit|Write (empty = all tools)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p(j$,{marginTop:1,children:p(F$,{color:Y.colors.muted,children:"Tool name pattern (supports | for multiple). Leave empty to match all."},void 0,!1,void 0,this)},void 0,!1,void 0,this),p(j$,{marginTop:1,children:p(F$,{color:Y.colors.muted,children:"Enter to continue · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),(Q==="command"||Q==="confirm")&&p(j$,{marginBottom:1,children:p(F$,{children:["Matcher: ",p(F$,{bold:!0,children:H||"(all tools)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q==="command"&&p(j$,{flexDirection:"column",children:[p(j$,{children:p(F$,{bold:!0,children:"Command: "},void 0,!1,void 0,this)},void 0,!1,void 0,this),p(j$,{borderStyle:"single",borderColor:Y.colors.border.light,paddingX:1,marginTop:1,children:p(YU,{value:O,onChange:z,onSubmit:T,placeholder:"Enter shell command..."},void 0,!1,void 0,this)},void 0,!1,void 0,this),p(j$,{flexDirection:"column",marginTop:1,children:[p(F$,{bold:!0,children:"Examples:"},void 0,!1,void 0,this),zN.map((j,M)=>p(F$,{color:Y.colors.muted,children:["• ",j]},M,!0,void 0,this))]},void 0,!0,void 0,this),p(j$,{marginTop:1,children:p(F$,{color:Y.colors.muted,children:"Enter to continue · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="location"&&p(j$,{flexDirection:"column",children:[p(j$,{flexDirection:"column",borderStyle:"round",borderColor:Y.colors.border.light,paddingX:2,paddingY:1,marginBottom:1,children:[p(F$,{bold:!0,color:Y.colors.primary,children:"Save hook configuration"},void 0,!1,void 0,this),p(F$,{children:" "},void 0,!1,void 0,this),p(F$,{children:[" ","Event: ",I.event," - ",I.description]},void 0,!0,void 0,this),p(F$,{children:[" Matcher: ",H||"(all)"]},void 0,!0,void 0,this),p(F$,{children:[" Command: ",O]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),p(F$,{bold:!0,children:"Where should this hook be saved?"},void 0,!1,void 0,this),p(j$,{flexDirection:"column",marginTop:1,children:W6.map((j,M)=>p(j$,{children:[p(F$,{color:M===W?Y.colors.primary:void 0,bold:M===W,children:[M===W?"❯ ":" ",M+1,". ",j.name]},void 0,!0,void 0,this),p(F$,{color:Y.colors.muted,children:[" ",j.description]},void 0,!0,void 0,this)]},j.location,!0,void 0,this))},void 0,!1,void 0,this),p(j$,{marginTop:1,children:p(F$,{color:Y.colors.muted,children:"Enter to confirm · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="confirm"&&p(j$,{flexDirection:"column",children:[p(j$,{flexDirection:"column",borderStyle:"round",borderColor:Y.colors.success,paddingX:2,paddingY:1,children:[p(F$,{bold:!0,children:["Saving hook to ",v.description,"..."]},void 0,!0,void 0,this),p(F$,{children:" "},void 0,!1,void 0,this),p(F$,{children:["Event: ",I.event]},void 0,!0,void 0,this),p(F$,{children:["Matcher: ",H||"(all tools)"]},void 0,!0,void 0,this),p(F$,{children:["Command: ",O]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),p(j$,{marginTop:1,children:p(F$,{color:Y.colors.muted,children:L?"Saving...":"Enter to confirm · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),_&&p(j$,{marginTop:1,children:p(F$,{color:Y.colors.error,children:["❌ ",_]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{useMemoizedFn as OU}from"ahooks";import{Box as MN,Text as jN}from"ink";import IN from"react";import{useMemoizedFn as NN}from"ahooks";import V4 from"chalk";import{Text as bN,useInput as AN}from"ink";import{useEffect as aZ,useRef as rZ}from"react";var U2={TIMEOUT_MS:100,RAPID_INPUT_THRESHOLD_MS:150,LARGE_INPUT_THRESHOLD:300,MEDIUM_SIZE_MULTI_CHUNK_THRESHOLD:200};import{execSync as M3}from"node:child_process";import{existsSync as _N,readFileSync as lZ}from"node:fs";import{basename as XU,isAbsolute as BN}from"node:path";function JU($){try{let Z=Buffer.from($,"base64");if(Z.length<4)return"image/png";if(Z[0]===137&&Z[1]===80&&Z[2]===78&&Z[3]===71)return"image/png";if(Z[0]===255&&Z[1]===216&&Z[2]===255)return"image/jpeg";if(Z[0]===71&&Z[1]===73&&Z[2]===70)return"image/gif";if(Z[0]===82&&Z[1]===73&&Z[2]===70&&Z[3]===70){if(Z.length>=12&&Z[8]===87&&Z[9]===69&&Z[10]===66&&Z[11]===80)return"image/webp"}return"image/png"}catch{return"image/png"}}function GU(){let $=process.platform,Z={darwin:"/tmp/blade_cli_latest_screenshot.png",linux:"/tmp/blade_cli_latest_screenshot.png",win32:process.env.TEMP?`${process.env.TEMP}\\blade_cli_latest_screenshot.png`:"C:\\Temp\\blade_cli_latest_screenshot.png"},Y={darwin:{checkImage:"osascript -e 'the clipboard as «class PNGf»'",saveImage:(Q)=>`osascript -e 'set png_data to (the clipboard as «class PNGf»)' -e 'set fp to open for access POSIX file "${Q}" with write permission' -e 'write png_data to fp' -e 'close access fp'`,getPath:"osascript -e 'get POSIX path of (the clipboard as «class furl»)'",deleteFile:(Q)=>`rm -f "${Q}"`},linux:{checkImage:'xclip -selection clipboard -t TARGETS -o | grep -E "image/(png|jpeg|jpg|gif|webp)"',saveImage:(Q)=>`xclip -selection clipboard -t image/png -o > "${Q}" || wl-paste --type image/png > "${Q}"`,getPath:"xclip -selection clipboard -t text/plain -o",deleteFile:(Q)=>`rm -f "${Q}"`},win32:{checkImage:'powershell -Command "(Get-Clipboard -Format Image) -ne $null"',saveImage:(Q)=>`powershell -Command "$img = Get-Clipboard -Format Image; if ($img) { $img.Save('${Q.replace(/\\/g,"\\\\")}', [System.Drawing.Imaging.ImageFormat]::Png) }"`,getPath:'powershell -Command "Get-Clipboard"',deleteFile:(Q)=>`del /f "${Q}"`}};return{commands:Y[$]||Y.linux,screenshotPath:Z[$]||Z.linux}}function LN(){let{commands:$}=GU();try{return M3($.getPath,{encoding:"utf-8"}).trim()}catch(Z){return console.error("Failed to get clipboard path:",Z),null}}function KU($){if($.startsWith('"')&&$.endsWith('"')||$.startsWith("'")&&$.endsWith("'"))return $.slice(1,-1);return $}function qU($){if(process.platform==="win32")return $;let Z="__DOUBLE_BACKSLASH__";return $.replace(/\\\\/g,Z).replace(/\\(.)/g,"$1").replace(new RegExp(Z,"g"),"\\")}function iZ($){let Z=KU($.trim()),Y=qU(Z);return/\.(png|jpe?g|gif|webp)$/i.test(Y)}function wN($){let Z=KU($.trim()),Y=qU(Z);if(iZ(Y))return Y;return null}async function WU($){let Z=wN($);if(!Z)return null;let Y;try{if(BN(Z))Y=lZ(Z);else{let G=LN();if(G&&Z===XU(G))Y=lZ(G);else return null}}catch(G){return console.error("Failed to read image file:",G),null}let Q=Y.toString("base64"),X=JU(Q),J=XU(Z);return{path:Z,base64:Q,mediaType:X,filename:J}}async function UU(){let $=process.platform,Z={darwin:"pbpaste",linux:"xclip -selection clipboard -o || wl-paste",win32:'powershell -Command "Get-Clipboard"'},Y=Z[$]||Z.linux;try{return M3(Y,{encoding:"utf-8"})||null}catch{return null}}async function HU(){let{commands:$,screenshotPath:Z}=GU();try{if(M3($.checkImage,{stdio:"ignore"}),M3($.saveImage(Z),{stdio:"ignore"}),!_N(Z))return null;let Q=lZ(Z).toString("base64"),X=JU(Q);return M3($.deleteFile(Z),{stdio:"ignore"}),{base64:Q,mediaType:X}}catch(Y){try{M3($.deleteFile(Z),{stdio:"ignore"})}catch{}return null}}import{jsxDEV as DN}from"react/jsx-dev-runtime";var RN=/\r\n/g,VN=/\r/g;function D4($){if(!$.includes("\r"))return $;return $.replace(RN,`
2840
+ `))},k=()=>{X("command")},T=()=>{if(!O.trim()){B("Command cannot be empty");return}B(null),X("location")},g=async()=>{w(!0),B(null);try{let j=M$.getInstance(),M=await import("node:fs/promises"),R=await import("node:path"),n=await import("node:os"),y={matcher:H.trim()?{tools:H.trim()}:{},hooks:[{type:"command",command:O.trim()}]},u;switch(v.location){case"local":u=R.join(process.cwd(),".blade","settings.local.json");break;case"project":u=R.join(process.cwd(),".blade","settings.json");break;case"user":u=R.join(n.homedir(),".blade","settings.json");break}await M.mkdir(R.dirname(u),{recursive:!0});let s={};try{let w$=await M.readFile(u,"utf-8");s=JSON.parse(w$)}catch{}let i=s.hooks||{},Y$=i[I.event]||[],f={...i,enabled:!0,[I.event]:[...Y$,y]};if(s.hooks=f,await M.writeFile(u,JSON.stringify(s,null,2),"utf-8"),await j.reloadConfig(),Z)Z({event:I.event,matcher:H.trim(),command:O.trim()});$()}catch(j){B(`Failed to save hook: ${j instanceof Error?j.message:"Unknown error"}`),w(!1)}};return p(j$,{flexDirection:"column",padding:1,children:[p(j$,{marginBottom:1,children:p(F$,{bold:!0,color:Y.colors.success,children:"Hooks Manager"},void 0,!1,void 0,this)},void 0,!1,void 0,this),p(j$,{marginBottom:1,children:p(F$,{color:Y.colors.warning,children:"⚠ Hooks execute shell commands with your full user permissions. Only use hooks from trusted sources."},void 0,!1,void 0,this)},void 0,!1,void 0,this),N&&p(j$,{flexDirection:"column",marginBottom:1,children:[p(F$,{children:N},void 0,!1,void 0,this),p(j$,{marginTop:1,children:p(F$,{color:Y.colors.muted,children:"Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="action"&&!N&&p(j$,{flexDirection:"column",children:[p(j$,{flexDirection:"column",marginTop:1,children:j3.map((j,M)=>p(j$,{children:[p(F$,{color:M===J?Y.colors.primary:void 0,bold:M===J,children:[M===J?"❯ ":" ",j.action]},void 0,!0,void 0,this),p(F$,{color:Y.colors.muted,children:[" - ",j.description]},void 0,!0,void 0,this)]},j.action,!0,void 0,this))},void 0,!1,void 0,this),p(j$,{marginTop:1,children:p(F$,{color:Y.colors.muted,children:"↑/↓ to select · Enter to continue · Esc to close"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="event"&&p(j$,{flexDirection:"column",children:[p(F$,{bold:!0,children:"Select Event:"},void 0,!1,void 0,this),p(j$,{flexDirection:"column",marginTop:1,children:U6.map((j,M)=>p(j$,{children:[p(F$,{color:M===K?Y.colors.primary:void 0,bold:M===K,children:[M===K?"❯ ":" ",j.event]},void 0,!0,void 0,this),p(F$,{color:Y.colors.muted,children:[" - ",j.description]},void 0,!0,void 0,this)]},j.event,!0,void 0,this))},void 0,!1,void 0,this),p(j$,{marginTop:1,children:p(F$,{color:Y.colors.muted,children:"↑/↓ to select · Enter to continue · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q!=="event"&&p(j$,{marginBottom:1,children:p(F$,{children:["Event:"," ",p(F$,{bold:!0,color:Y.colors.primary,children:I.event},void 0,!1,void 0,this),p(F$,{color:Y.colors.muted,children:[" - ",I.description]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),(Q==="matcher"||Q==="command"||Q==="confirm")&&p(j$,{flexDirection:"column",marginBottom:1,children:[p(F$,{color:Y.colors.muted,children:"Input to command is JSON of tool call arguments."},void 0,!1,void 0,this),p(F$,{color:Y.colors.muted,children:"Exit code 0 - stdout/stderr not shown"},void 0,!1,void 0,this),p(F$,{color:Y.colors.muted,children:"Exit code 2 - show stderr to model and block tool call"},void 0,!1,void 0,this),p(F$,{color:Y.colors.muted,children:"Other exit codes - show stderr to user only but continue with tool call"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="matcher"&&p(j$,{flexDirection:"column",children:[p(j$,{children:[p(F$,{bold:!0,children:"Matcher: "},void 0,!1,void 0,this),p(YU,{value:H,onChange:F,onSubmit:k,placeholder:"e.g., Read, Bash, Edit|Write (empty = all tools)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p(j$,{marginTop:1,children:p(F$,{color:Y.colors.muted,children:"Tool name pattern (supports | for multiple). Leave empty to match all."},void 0,!1,void 0,this)},void 0,!1,void 0,this),p(j$,{marginTop:1,children:p(F$,{color:Y.colors.muted,children:"Enter to continue · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),(Q==="command"||Q==="confirm")&&p(j$,{marginBottom:1,children:p(F$,{children:["Matcher: ",p(F$,{bold:!0,children:H||"(all tools)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q==="command"&&p(j$,{flexDirection:"column",children:[p(j$,{children:p(F$,{bold:!0,children:"Command: "},void 0,!1,void 0,this)},void 0,!1,void 0,this),p(j$,{borderStyle:"single",borderColor:Y.colors.border.light,paddingX:1,marginTop:1,children:p(YU,{value:O,onChange:z,onSubmit:T,placeholder:"Enter shell command..."},void 0,!1,void 0,this)},void 0,!1,void 0,this),p(j$,{flexDirection:"column",marginTop:1,children:[p(F$,{bold:!0,children:"Examples:"},void 0,!1,void 0,this),zN.map((j,M)=>p(F$,{color:Y.colors.muted,children:["• ",j]},M,!0,void 0,this))]},void 0,!0,void 0,this),p(j$,{marginTop:1,children:p(F$,{color:Y.colors.muted,children:"Enter to continue · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="location"&&p(j$,{flexDirection:"column",children:[p(j$,{flexDirection:"column",borderStyle:"round",borderColor:Y.colors.border.light,paddingX:2,paddingY:1,marginBottom:1,children:[p(F$,{bold:!0,color:Y.colors.primary,children:"Save hook configuration"},void 0,!1,void 0,this),p(F$,{children:" "},void 0,!1,void 0,this),p(F$,{children:[" ","Event: ",I.event," - ",I.description]},void 0,!0,void 0,this),p(F$,{children:[" Matcher: ",H||"(all)"]},void 0,!0,void 0,this),p(F$,{children:[" Command: ",O]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),p(F$,{bold:!0,children:"Where should this hook be saved?"},void 0,!1,void 0,this),p(j$,{flexDirection:"column",marginTop:1,children:W6.map((j,M)=>p(j$,{children:[p(F$,{color:M===W?Y.colors.primary:void 0,bold:M===W,children:[M===W?"❯ ":" ",M+1,". ",j.name]},void 0,!0,void 0,this),p(F$,{color:Y.colors.muted,children:[" ",j.description]},void 0,!0,void 0,this)]},j.location,!0,void 0,this))},void 0,!1,void 0,this),p(j$,{marginTop:1,children:p(F$,{color:Y.colors.muted,children:"Enter to confirm · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="confirm"&&p(j$,{flexDirection:"column",children:[p(j$,{flexDirection:"column",borderStyle:"round",borderColor:Y.colors.success,paddingX:2,paddingY:1,children:[p(F$,{bold:!0,children:["Saving hook to ",v.description,"..."]},void 0,!0,void 0,this),p(F$,{children:" "},void 0,!1,void 0,this),p(F$,{children:["Event: ",I.event]},void 0,!0,void 0,this),p(F$,{children:["Matcher: ",H||"(all tools)"]},void 0,!0,void 0,this),p(F$,{children:["Command: ",O]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),p(j$,{marginTop:1,children:p(F$,{color:Y.colors.muted,children:L?"Saving...":"Enter to confirm · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),_&&p(j$,{marginTop:1,children:p(F$,{color:Y.colors.error,children:["❌ ",_]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{useMemoizedFn as OU}from"ahooks";import{Box as MN,Text as jN}from"ink";import IN from"react";import{useMemoizedFn as NN}from"ahooks";import V2 from"chalk";import{Text as bN,useInput as AN}from"ink";import{useEffect as aZ,useRef as rZ}from"react";var U4={TIMEOUT_MS:100,RAPID_INPUT_THRESHOLD_MS:150,LARGE_INPUT_THRESHOLD:300,MEDIUM_SIZE_MULTI_CHUNK_THRESHOLD:200};import{execSync as M8}from"node:child_process";import{existsSync as _N,readFileSync as lZ}from"node:fs";import{basename as XU,isAbsolute as BN}from"node:path";function JU($){try{let Z=Buffer.from($,"base64");if(Z.length<4)return"image/png";if(Z[0]===137&&Z[1]===80&&Z[2]===78&&Z[3]===71)return"image/png";if(Z[0]===255&&Z[1]===216&&Z[2]===255)return"image/jpeg";if(Z[0]===71&&Z[1]===73&&Z[2]===70)return"image/gif";if(Z[0]===82&&Z[1]===73&&Z[2]===70&&Z[3]===70){if(Z.length>=12&&Z[8]===87&&Z[9]===69&&Z[10]===66&&Z[11]===80)return"image/webp"}return"image/png"}catch{return"image/png"}}function GU(){let $=process.platform,Z={darwin:"/tmp/blade_cli_latest_screenshot.png",linux:"/tmp/blade_cli_latest_screenshot.png",win32:process.env.TEMP?`${process.env.TEMP}\\blade_cli_latest_screenshot.png`:"C:\\Temp\\blade_cli_latest_screenshot.png"},Y={darwin:{checkImage:"osascript -e 'the clipboard as «class PNGf»'",saveImage:(Q)=>`osascript -e 'set png_data to (the clipboard as «class PNGf»)' -e 'set fp to open for access POSIX file "${Q}" with write permission' -e 'write png_data to fp' -e 'close access fp'`,getPath:"osascript -e 'get POSIX path of (the clipboard as «class furl»)'",deleteFile:(Q)=>`rm -f "${Q}"`},linux:{checkImage:'xclip -selection clipboard -t TARGETS -o | grep -E "image/(png|jpeg|jpg|gif|webp)"',saveImage:(Q)=>`xclip -selection clipboard -t image/png -o > "${Q}" || wl-paste --type image/png > "${Q}"`,getPath:"xclip -selection clipboard -t text/plain -o",deleteFile:(Q)=>`rm -f "${Q}"`},win32:{checkImage:'powershell -Command "(Get-Clipboard -Format Image) -ne $null"',saveImage:(Q)=>`powershell -Command "$img = Get-Clipboard -Format Image; if ($img) { $img.Save('${Q.replace(/\\/g,"\\\\")}', [System.Drawing.Imaging.ImageFormat]::Png) }"`,getPath:'powershell -Command "Get-Clipboard"',deleteFile:(Q)=>`del /f "${Q}"`}};return{commands:Y[$]||Y.linux,screenshotPath:Z[$]||Z.linux}}function LN(){let{commands:$}=GU();try{return M8($.getPath,{encoding:"utf-8"}).trim()}catch(Z){return console.error("Failed to get clipboard path:",Z),null}}function KU($){if($.startsWith('"')&&$.endsWith('"')||$.startsWith("'")&&$.endsWith("'"))return $.slice(1,-1);return $}function qU($){if(process.platform==="win32")return $;let Z="__DOUBLE_BACKSLASH__";return $.replace(/\\\\/g,Z).replace(/\\(.)/g,"$1").replace(new RegExp(Z,"g"),"\\")}function iZ($){let Z=KU($.trim()),Y=qU(Z);return/\.(png|jpe?g|gif|webp)$/i.test(Y)}function wN($){let Z=KU($.trim()),Y=qU(Z);if(iZ(Y))return Y;return null}async function WU($){let Z=wN($);if(!Z)return null;let Y;try{if(BN(Z))Y=lZ(Z);else{let G=LN();if(G&&Z===XU(G))Y=lZ(G);else return null}}catch(G){return console.error("Failed to read image file:",G),null}let Q=Y.toString("base64"),X=JU(Q),J=XU(Z);return{path:Z,base64:Q,mediaType:X,filename:J}}async function UU(){let $=process.platform,Z={darwin:"pbpaste",linux:"xclip -selection clipboard -o || wl-paste",win32:'powershell -Command "Get-Clipboard"'},Y=Z[$]||Z.linux;try{return M8(Y,{encoding:"utf-8"})||null}catch{return null}}async function HU(){let{commands:$,screenshotPath:Z}=GU();try{if(M8($.checkImage,{stdio:"ignore"}),M8($.saveImage(Z),{stdio:"ignore"}),!_N(Z))return null;let Q=lZ(Z).toString("base64"),X=JU(Q);return M8($.deleteFile(Z),{stdio:"ignore"}),{base64:Q,mediaType:X}}catch(Y){try{M8($.deleteFile(Z),{stdio:"ignore"})}catch{}return null}}import{jsxDEV as DN}from"react/jsx-dev-runtime";var RN=/\r\n/g,VN=/\r/g;function D2($){if(!$.includes("\r"))return $;return $.replace(RN,`
2841
2841
  `).replace(VN,`
2842
- `)}function M4($,Z,Y){let Q=Math.max(0,Math.min(Y,Z.length)),X=Z.slice(0,Q),J=Z.slice(Q);return{newValue:X+$+J,newCursorPosition:Q+$.length}}function FU({value:$,placeholder:Z="",focus:Y=!0,onChange:Q,cursorPosition:X,onChangeCursorPosition:J,onPaste:G,onImagePaste:K,disabledKeys:q=[]}){let W=rZ({chunks:[],timeoutId:null,firstInputTime:null,lastInputTime:null,totalLength:0}),U=rZ($),H=rZ(X);aZ(()=>{U.current=$,H.current=X},[$,X]),aZ(()=>{return()=>{if(W.current.timeoutId)clearTimeout(W.current.timeoutId)}},[]),aZ(()=>{if(X>$.length)J($.length)},[$,X,J]);let F=NN(()=>{let B=W.current;if(B.timeoutId)clearTimeout(B.timeoutId);let L=setTimeout(async()=>{let w=W.current.chunks,N=W.current.totalLength;if(w.length===0)return;let D=D4(w.join(""));W.current={chunks:[],timeoutId:null,firstInputTime:null,lastInputTime:null,totalLength:0};let V=U.current,I=H.current;if(K&&iZ(D))try{let k=await WU(D);if(k){let T=await K(k.base64,k.mediaType,k.filename);if(T?.prompt){let g=D4(T.prompt),{newValue:j,newCursorPosition:M}=M4(g,V,I);Q(j),J(M)}return}}catch(k){console.error("Failed to process image path:",k)}let v=D.includes(`
2843
- `),b=N>U2.MEDIUM_SIZE_MULTI_CHUNK_THRESHOLD&&w.length>3;if((N>U2.LARGE_INPUT_THRESHOLD||v||b)&&G){let k=await G(D);if(k?.prompt){let T=D4(k.prompt),{newValue:g,newCursorPosition:j}=M4(T,V,I);Q(g),J(j);return}}let{newValue:d,newCursorPosition:e}=M4(D,V,I);Q(d),J(e)},U2.TIMEOUT_MS);W.current.timeoutId=L});AN((B,L)=>{let w=D4(B);if(q.some((b)=>L[b])||L.ctrl&&B==="c"||L.ctrl&&B==="l"||L.ctrl&&B==="t"||L.ctrl&&B==="o"||L.meta&&B==="l"||L.meta&&B==="t"||L.meta&&B==="o"||L.shift&&L.tab||w==="?"&&$==="")return;let D=Date.now(),V=W.current,I=X,v=$;if(L.leftArrow)I--;else if(L.rightArrow)I++;else if(L.backspace||L.delete){if(B===""){if(X>0)v=$.slice(0,X-1)+$.slice(X,$.length),I--}else if(X<$.length)v=$.slice(0,X)+$.slice(X+1,$.length)}else if(L.ctrl&&w==="a")I=0;else if(L.ctrl&&w==="e")I=$.length;else if(L.ctrl&&w==="k")v=$.slice(0,X);else if(L.ctrl&&w==="u")v=$.slice(X),I=0;else if(L.ctrl&&w==="w"){let C=$.slice(0,X).match(/\s*\S+\s*$/);if(C){let d=C[0].length;v=$.slice(0,X-d)+$.slice(X),I-=d}}else if(L.ctrl&&w==="v"){let b=process.platform==="darwin";(async()=>{if(K){let d=await HU();if(d){let e=await K(d.base64,d.mediaType,"clipboard.png");if(e?.prompt){let k=D4(e.prompt),{newValue:T,newCursorPosition:g}=M4(k,U.current,H.current);Q(T),J(g)}return}}if(b)return;let C=await UU();if(C){let d=D4(C),e=d.includes(`
2844
- `),k=d.length>U2.LARGE_INPUT_THRESHOLD;if((e||k)&&G){let j=await G(d);if(j?.prompt){let M=D4(j.prompt),{newValue:R,newCursorPosition:n}=M4(M,U.current,H.current);Q(R),J(n);return}}let{newValue:T,newCursorPosition:g}=M4(d,U.current,H.current);Q(T),J(g)}})().catch(()=>{});return}else if(L.pageUp)I=0;else if(L.pageDown)I=$.length;else if(w===`
2845
- `&&(L.shift||L.meta)){let{newValue:b,newCursorPosition:C}=M4(w,$,X);Q(b),J(C);return}else if(!L.ctrl&&!L.meta){if(!V.firstInputTime)V.firstInputTime=D;V.lastInputTime=D;let b=D-(V.firstInputTime||D),C=w.length>U2.LARGE_INPUT_THRESHOLD,d=w.includes(`
2846
- `)&&w.length>1,e=b<U2.RAPID_INPUT_THRESHOLD_MS&&V.chunks.length>0,k=b<U2.RAPID_INPUT_THRESHOLD_MS&&w.length>10,T=V.timeoutId!==null;if(G&&(C||d||e||k||T)){V.chunks.push(w),V.totalLength+=w.length,F();return}if(w.length===1&&!V.timeoutId)V.chunks=[],V.firstInputTime=null,V.lastInputTime=null,V.totalLength=0;v=$.slice(0,X)+w+$.slice(X,$.length),I+=w.length}if(I<0)I=0;if(I>v.length)I=v.length;if(v!==$)Q(v);if(I!==X)J(I)},{isActive:Y});let O=Y,z=$,_=Z?V4.grey(Z):void 0;if(O)if(_=Z.length>0?V4.inverse(Z[0])+V4.grey(Z.slice(1)):V4.inverse(" "),$.length===0)z=V4.inverse(" ");else{z="";for(let B=0;B<$.length;B++)if(B===X&&X<$.length)z+=V4.inverse($[B]);else z+=$[B];if(X>=$.length)z+=V4.inverse(" ")}return DN(bN,{children:Z?$.length>0?z:_:z},void 0,!1,void 0,this)}import{jsxDEV as nZ}from"react/jsx-dev-runtime";var zU=IN.memo(({input:$,cursorPosition:Z,onChange:Y,onChangeCursorPosition:Q,onAddPasteMapping:X,onAddImagePasteMapping:J})=>{let K=Z1()==="main-input",q=OU((U)=>{let H=U.split(`
2847
- `).length,F=U.length,O=500,z=10;if(F>500||H>10){let _=X(U),B=U.slice(0,30).replace(/\n/g," "),L=`${F} chars, ${H} lines: ${B}...`;return{prompt:`${e9(_)}${L}${bZ()}`}}return{}}),W=OU(async(U,H,F)=>{try{let O=J(U,H);return{prompt:`${e9(O)}[Image #${O}]${bZ()}`}}catch(O){return console.error("[Image Paste] Failed to process image:",O),{prompt:`[Image paste failed: ${O instanceof Error?O.message:"Unknown error"}] `}}});return nZ(MN,{flexDirection:"row",width:"100%",paddingX:2,paddingY:0,flexShrink:0,flexGrow:0,overflow:"hidden",borderStyle:"round",borderColor:"gray",children:[nZ(jN,{color:"blue",bold:!0,children:"> "},void 0,!1,void 0,this),nZ(FU,{value:$,cursorPosition:Z,onChange:Y,onChangeCursorPosition:Q,onPaste:q,onImagePaste:W,placeholder:" 输入命令...",focus:K,disabledKeys:["upArrow","downArrow","tab","return","escape"]},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});import{Box as H6,Text as k1}from"ink";import TN,{useEffect as CN,useState as SN}from"react";import{useEffect as PN,useState as wU}from"react";import{useEffect as yN,useState as vN}from"react";var EN=15000,_U=["炼化代码灵气...","参悟 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 广纳贤才..."],BU=["Esc - 停止任务 / 隐藏建议 / 双击清空输入","Shift+Tab - 切换模式 (DEFAULT → AUTO_EDIT → PLAN → SPEC)","Tab - 选中建议 / 切换 thinking 模式","↑↓ - 浏览建议或输入历史记录","? - 显示快捷键帮助面板(输入框为空时)","Ctrl+C - 停止任务(双击退出应用)","Ctrl+L - 清屏(清除所有消息)","Ctrl+T - 切换 thinking 内容展开/折叠","Ctrl+O - 切换历史消息展开/折叠","Ctrl+U - 删除从行首到光标的内容","Ctrl+K - 删除从光标到行尾的内容","Shift+Enter - 插入换行(多行输入)","/help - 显示所有可用的 slash commands","/init - 分析项目并生成 BLADE.md 配置","/resume - 恢复历史会话","/compact - 手动压缩当前会话上下文","/theme - 打开交互式主题选择器","/model - 管理和切换模型配置","/model add - 添加新模型配置","/permissions - 管理项目的本地权限规则","/mcp - 显示 MCP 服务器状态和可用工具","/agents - 管理 subagent 配置","/version - 显示版本信息和构建详情","/clear - 清除屏幕内容和对话历史","/status - 显示当前项目配置状态","/context - 可视化当前上下文 Token 使用情况","/git - Git 仓库查询和 AI 辅助","/git review - AI Code Review","/hooks - 管理 Hook 配置","/tasks - 列出所有后台任务","@ 文件路径 - 附加文件到上下文","@dir/ - 附加整个目录","@file.ts:10-20 - 附加指定行范围","Plan 模式 - 先规划后编码(Shift+Tab 切换)","Auto Edit 模式 - 自动批准工具调用","MCP 协议 - 扩展外部工具集成","Subagents - 并行执行子任务","Hooks 系统 - 自定义工具执行流程","Context 压缩 - 自动总结历史对话","Loop 检测 - 防止无限循环","提示:使用 /init 让 AI 理解你的项目结构","提示:Plan 模式适合复杂多步骤任务","提示:Auto Edit 可加速重复性操作","提示:@ 引用可提供更精准的上下文","提示:定期 /compact 节省 token 成本","提示:使用 /permissions 控制工具权限","提示:Shift+Tab 快速切换模式","提示:Esc 可随时中断长时间任务","提示:/resume 继续未完成的对话","提示:/git commit 让 AI 生成 commit message"];function LU($,Z,Y=!1){let[Q,X]=vN("");return yN(()=>{if(Z){X("等待用户确认...");return}if(!$){X("");return}if(Y)return;let J=()=>{if(Math.random()<0.16666666666666666){let W=Math.floor(Math.random()*BU.length);return BU[W]}let q=Math.floor(Math.random()*_U.length);return _U[q]};X(J());let G=setInterval(()=>{X(J())},EN);return()=>{clearInterval(G)}},[$,Z,Y]),Q}function NU($,Z=!1,Y=!1){let[Q,X]=wU(0),[J,G]=wU(null),K=LU($,Z,Y);return PN(()=>{if(!$){X(0),G(null);return}if(Y)return;if(J===null)G(Date.now());let q=setInterval(()=>{if(J!==null){let W=Math.floor((Date.now()-J)/1000);X(W)}},1000);return()=>{clearInterval(q)}},[$,J,Y]),{currentPhrase:K,elapsedTime:Q}}import{jsxDEV as f0,Fragment as fN}from"react/jsx-dev-runtime";var oZ=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"],kN=80;function bU($){if($<60)return`${$}s`;let Z=Math.floor($/60),Y=$%60;return`${Z}m ${Y}s`}var AU=TN.memo(({message:$,paused:Z=!1})=>{let Y=f2(),Q=a9(),X=Y||!Q,[J,G]=SN(0),K=$0(),W=w3()>=kN,{currentPhrase:U,elapsedTime:H}=NU(X,!1,Z);if(CN(()=>{if(!X||Z){G(0);return}let O=setInterval(()=>{G((z)=>(z+1)%oZ.length)},80);return()=>clearInterval(O)},[X,Z]),!X)return null;let F=U||$||"正在思考中...";if(W)return f0(H6,{paddingX:2,paddingBottom:1,flexDirection:"row",gap:1,children:[f0(k1,{color:K.colors.warning,bold:!0,children:oZ[J]},void 0,!1,void 0,this),f0(k1,{color:K.colors.text.primary,children:F},void 0,!1,void 0,this),H>0&&f0(fN,{children:[f0(k1,{color:K.colors.muted,children:"|"},void 0,!1,void 0,this),f0(k1,{color:K.colors.info,children:["已用时: ",bU(H)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),f0(k1,{color:K.colors.muted,children:"|"},void 0,!1,void 0,this),f0(k1,{color:K.colors.secondary,children:"Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return f0(H6,{paddingX:2,paddingBottom:1,flexDirection:"column",children:[f0(H6,{flexDirection:"row",gap:1,children:[f0(k1,{color:K.colors.warning,bold:!0,children:oZ[J]},void 0,!1,void 0,this),f0(k1,{color:K.colors.text.primary,children:F},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H>0&&f0(H6,{marginLeft:2,flexDirection:"row",gap:1,children:[f0(k1,{color:K.colors.info,children:["已用时: ",bU(H)]},void 0,!0,void 0,this),f0(k1,{color:K.colors.muted,children:"|"},void 0,!1,void 0,this),f0(k1,{color:K.colors.secondary,children:"Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});import YY from"ansi-escapes";import{Box as F2,Static as yU,useStdout as oN}from"ink";import sN,{useEffect as j4,useMemo as O6,useRef as m2,useState as QY}from"react";import{useStdout as hN}from"ink";import{debounce as xN}from"lodash-es";import{useEffect as pN,useState as mN}from"react";function RU($=200){let{stdout:Z}=hN(),[Y,Q]=mN(Z.rows||24);return pN(()=>{let X=xN(()=>{Q(Z.rows||24)},$);return X(),Z.on("resize",X),()=>{Z.off("resize",X),X.cancel()}},[Z,$]),Y}C3();import{Box as dN,Text as VU}from"ink";import uN from"react";import{jsxDEV as sZ}from"react/jsx-dev-runtime";var tZ=uN.memo(({collapsedCount:$})=>{let Z=$0();if($<=0)return null;let Y=Z.colors.text.muted;return sZ(dN,{flexDirection:"row",marginBottom:1,children:[sZ(VU,{color:Y,children:["▶ ",$," 条历史消息"]},void 0,!0,void 0,this),sZ(VU,{color:Y,children:" [Ctrl+O 展开]"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});tZ.displayName="CollapsedHistorySummary";P3();import{Box as I8,Text as y8}from"ink";import gN from"ink-big-text";import cN from"ink-gradient";import lN from"react";import{jsxDEV as A1}from"react/jsx-dev-runtime";var DU=lN.memo(()=>{return A1(I8,{flexDirection:"column",paddingX:2,paddingTop:1,paddingBottom:1,children:[A1(I8,{flexDirection:"column",children:A1(cN,{name:"pastel",children:A1(gN,{text:"BLADE",font:"block"},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),A1(I8,{marginBottom:1,children:A1(y8,{color:"white",dimColor:!0,children:NY()},void 0,!1,void 0,this)},void 0,!1,void 0,this),A1(I8,{flexDirection:"column",marginBottom:1,children:[A1(I8,{marginBottom:1,children:A1(y8,{color:"white",bold:!0,children:"使用指南:"},void 0,!1,void 0,this)},void 0,!1,void 0,this),A1(y8,{color:"white",children:"1. 输入问题、编辑文件或运行命令"},void 0,!1,void 0,this),A1(y8,{color:"white",children:"2. 使用 /init 创建项目配置文件"},void 0,!1,void 0,this),A1(y8,{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 eZ,Text as j3}from"ink";import iN,{useMemo as MU}from"react";import{jsxDEV as H2}from"react/jsx-dev-runtime";function aN($,Z=60){if(!$)return"";let Y=$.split(`
2842
+ `)}function M2($,Z,Y){let Q=Math.max(0,Math.min(Y,Z.length)),X=Z.slice(0,Q),J=Z.slice(Q);return{newValue:X+$+J,newCursorPosition:Q+$.length}}function FU({value:$,placeholder:Z="",focus:Y=!0,onChange:Q,cursorPosition:X,onChangeCursorPosition:J,onPaste:G,onImagePaste:K,disabledKeys:q=[]}){let W=rZ({chunks:[],timeoutId:null,firstInputTime:null,lastInputTime:null,totalLength:0}),U=rZ($),H=rZ(X);aZ(()=>{U.current=$,H.current=X},[$,X]),aZ(()=>{return()=>{if(W.current.timeoutId)clearTimeout(W.current.timeoutId)}},[]),aZ(()=>{if(X>$.length)J($.length)},[$,X,J]);let F=NN(()=>{let B=W.current;if(B.timeoutId)clearTimeout(B.timeoutId);let L=setTimeout(async()=>{let w=W.current.chunks,N=W.current.totalLength;if(w.length===0)return;let D=D2(w.join(""));W.current={chunks:[],timeoutId:null,firstInputTime:null,lastInputTime:null,totalLength:0};let V=U.current,I=H.current;if(K&&iZ(D))try{let k=await WU(D);if(k){let T=await K(k.base64,k.mediaType,k.filename);if(T?.prompt){let g=D2(T.prompt),{newValue:j,newCursorPosition:M}=M2(g,V,I);Q(j),J(M)}return}}catch(k){console.error("Failed to process image path:",k)}let v=D.includes(`
2843
+ `),b=N>U4.MEDIUM_SIZE_MULTI_CHUNK_THRESHOLD&&w.length>3;if((N>U4.LARGE_INPUT_THRESHOLD||v||b)&&G){let k=await G(D);if(k?.prompt){let T=D2(k.prompt),{newValue:g,newCursorPosition:j}=M2(T,V,I);Q(g),J(j);return}}let{newValue:d,newCursorPosition:e}=M2(D,V,I);Q(d),J(e)},U4.TIMEOUT_MS);W.current.timeoutId=L});AN((B,L)=>{let w=D2(B);if(q.some((b)=>L[b])||L.ctrl&&B==="c"||L.ctrl&&B==="l"||L.ctrl&&B==="t"||L.ctrl&&B==="o"||L.meta&&B==="l"||L.meta&&B==="t"||L.meta&&B==="o"||L.shift&&L.tab||w==="?"&&$==="")return;let D=Date.now(),V=W.current,I=X,v=$;if(L.leftArrow)I--;else if(L.rightArrow)I++;else if(L.backspace||L.delete){if(B===""){if(X>0)v=$.slice(0,X-1)+$.slice(X,$.length),I--}else if(X<$.length)v=$.slice(0,X)+$.slice(X+1,$.length)}else if(L.ctrl&&w==="a")I=0;else if(L.ctrl&&w==="e")I=$.length;else if(L.ctrl&&w==="k")v=$.slice(0,X);else if(L.ctrl&&w==="u")v=$.slice(X),I=0;else if(L.ctrl&&w==="w"){let C=$.slice(0,X).match(/\s*\S+\s*$/);if(C){let d=C[0].length;v=$.slice(0,X-d)+$.slice(X),I-=d}}else if(L.ctrl&&w==="v"){let b=process.platform==="darwin";(async()=>{if(K){let d=await HU();if(d){let e=await K(d.base64,d.mediaType,"clipboard.png");if(e?.prompt){let k=D2(e.prompt),{newValue:T,newCursorPosition:g}=M2(k,U.current,H.current);Q(T),J(g)}return}}if(b)return;let C=await UU();if(C){let d=D2(C),e=d.includes(`
2844
+ `),k=d.length>U4.LARGE_INPUT_THRESHOLD;if((e||k)&&G){let j=await G(d);if(j?.prompt){let M=D2(j.prompt),{newValue:R,newCursorPosition:n}=M2(M,U.current,H.current);Q(R),J(n);return}}let{newValue:T,newCursorPosition:g}=M2(d,U.current,H.current);Q(T),J(g)}})().catch(()=>{});return}else if(L.pageUp)I=0;else if(L.pageDown)I=$.length;else if(w===`
2845
+ `&&(L.shift||L.meta)){let{newValue:b,newCursorPosition:C}=M2(w,$,X);Q(b),J(C);return}else if(!L.ctrl&&!L.meta){if(!V.firstInputTime)V.firstInputTime=D;V.lastInputTime=D;let b=D-(V.firstInputTime||D),C=w.length>U4.LARGE_INPUT_THRESHOLD,d=w.includes(`
2846
+ `)&&w.length>1,e=b<U4.RAPID_INPUT_THRESHOLD_MS&&V.chunks.length>0,k=b<U4.RAPID_INPUT_THRESHOLD_MS&&w.length>10,T=V.timeoutId!==null;if(G&&(C||d||e||k||T)){V.chunks.push(w),V.totalLength+=w.length,F();return}if(w.length===1&&!V.timeoutId)V.chunks=[],V.firstInputTime=null,V.lastInputTime=null,V.totalLength=0;v=$.slice(0,X)+w+$.slice(X,$.length),I+=w.length}if(I<0)I=0;if(I>v.length)I=v.length;if(v!==$)Q(v);if(I!==X)J(I)},{isActive:Y});let O=Y,z=$,_=Z?V2.grey(Z):void 0;if(O)if(_=Z.length>0?V2.inverse(Z[0])+V2.grey(Z.slice(1)):V2.inverse(" "),$.length===0)z=V2.inverse(" ");else{z="";for(let B=0;B<$.length;B++)if(B===X&&X<$.length)z+=V2.inverse($[B]);else z+=$[B];if(X>=$.length)z+=V2.inverse(" ")}return DN(bN,{children:Z?$.length>0?z:_:z},void 0,!1,void 0,this)}import{jsxDEV as nZ}from"react/jsx-dev-runtime";var zU=IN.memo(({input:$,cursorPosition:Z,onChange:Y,onChangeCursorPosition:Q,onAddPasteMapping:X,onAddImagePasteMapping:J})=>{let K=Z1()==="main-input",q=OU((U)=>{let H=U.split(`
2847
+ `).length,F=U.length,O=500,z=10;if(F>500||H>10){let _=X(U),B=U.slice(0,30).replace(/\n/g," "),L=`${F} chars, ${H} lines: ${B}...`;return{prompt:`${e9(_)}${L}${bZ()}`}}return{}}),W=OU(async(U,H,F)=>{try{let O=J(U,H);return{prompt:`${e9(O)}[Image #${O}]${bZ()}`}}catch(O){return console.error("[Image Paste] Failed to process image:",O),{prompt:`[Image paste failed: ${O instanceof Error?O.message:"Unknown error"}] `}}});return nZ(MN,{flexDirection:"row",width:"100%",paddingX:2,paddingY:0,flexShrink:0,flexGrow:0,overflow:"hidden",borderStyle:"round",borderColor:"gray",children:[nZ(jN,{color:"blue",bold:!0,children:"> "},void 0,!1,void 0,this),nZ(FU,{value:$,cursorPosition:Z,onChange:Y,onChangeCursorPosition:Q,onPaste:q,onImagePaste:W,placeholder:" 输入命令...",focus:K,disabledKeys:["upArrow","downArrow","tab","return","escape"]},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});import{Box as H6,Text as k1}from"ink";import TN,{useEffect as CN,useState as SN}from"react";import{useEffect as PN,useState as wU}from"react";import{useEffect as yN,useState as vN}from"react";var EN=15000,_U=["炼化代码灵气...","参悟 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 广纳贤才..."],BU=["Esc - 停止任务 / 隐藏建议 / 双击清空输入","Shift+Tab - 切换模式 (DEFAULT → AUTO_EDIT → PLAN → SPEC)","Tab - 选中建议 / 切换 thinking 模式","↑↓ - 浏览建议或输入历史记录","? - 显示快捷键帮助面板(输入框为空时)","Ctrl+C - 停止任务(双击退出应用)","Ctrl+L - 清屏(清除所有消息)","Ctrl+T - 切换 thinking 内容展开/折叠","Ctrl+O - 切换历史消息展开/折叠","Ctrl+U - 删除从行首到光标的内容","Ctrl+K - 删除从光标到行尾的内容","Shift+Enter - 插入换行(多行输入)","/help - 显示所有可用的 slash commands","/init - 分析项目并生成 BLADE.md 配置","/resume - 恢复历史会话","/compact - 手动压缩当前会话上下文","/theme - 打开交互式主题选择器","/model - 管理和切换模型配置","/model add - 添加新模型配置","/permissions - 管理项目的本地权限规则","/mcp - 显示 MCP 服务器状态和可用工具","/agents - 管理 subagent 配置","/version - 显示版本信息和构建详情","/clear - 清除屏幕内容和对话历史","/status - 显示当前项目配置状态","/context - 可视化当前上下文 Token 使用情况","/git - Git 仓库查询和 AI 辅助","/git review - AI Code Review","/hooks - 管理 Hook 配置","/tasks - 列出所有后台任务","@ 文件路径 - 附加文件到上下文","@dir/ - 附加整个目录","@file.ts:10-20 - 附加指定行范围","Plan 模式 - 先规划后编码(Shift+Tab 切换)","Auto Edit 模式 - 自动批准工具调用","MCP 协议 - 扩展外部工具集成","Subagents - 并行执行子任务","Hooks 系统 - 自定义工具执行流程","Context 压缩 - 自动总结历史对话","Loop 检测 - 防止无限循环","提示:使用 /init 让 AI 理解你的项目结构","提示:Plan 模式适合复杂多步骤任务","提示:Auto Edit 可加速重复性操作","提示:@ 引用可提供更精准的上下文","提示:定期 /compact 节省 token 成本","提示:使用 /permissions 控制工具权限","提示:Shift+Tab 快速切换模式","提示:Esc 可随时中断长时间任务","提示:/resume 继续未完成的对话","提示:/git commit 让 AI 生成 commit message"];function LU($,Z,Y=!1){let[Q,X]=vN("");return yN(()=>{if(Z){X("等待用户确认...");return}if(!$){X("");return}if(Y)return;let J=()=>{if(Math.random()<0.16666666666666666){let W=Math.floor(Math.random()*BU.length);return BU[W]}let q=Math.floor(Math.random()*_U.length);return _U[q]};X(J());let G=setInterval(()=>{X(J())},EN);return()=>{clearInterval(G)}},[$,Z,Y]),Q}function NU($,Z=!1,Y=!1){let[Q,X]=wU(0),[J,G]=wU(null),K=LU($,Z,Y);return PN(()=>{if(!$){X(0),G(null);return}if(Y)return;if(J===null)G(Date.now());let q=setInterval(()=>{if(J!==null){let W=Math.floor((Date.now()-J)/1000);X(W)}},1000);return()=>{clearInterval(q)}},[$,J,Y]),{currentPhrase:K,elapsedTime:Q}}import{jsxDEV as f0,Fragment as fN}from"react/jsx-dev-runtime";var oZ=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"],kN=80;function bU($){if($<60)return`${$}s`;let Z=Math.floor($/60),Y=$%60;return`${Z}m ${Y}s`}var AU=TN.memo(({message:$,paused:Z=!1})=>{let Y=f4(),Q=a9(),X=Y||!Q,[J,G]=SN(0),K=$0(),W=w8()>=kN,{currentPhrase:U,elapsedTime:H}=NU(X,!1,Z);if(CN(()=>{if(!X||Z){G(0);return}let O=setInterval(()=>{G((z)=>(z+1)%oZ.length)},80);return()=>clearInterval(O)},[X,Z]),!X)return null;let F=U||$||"正在思考中...";if(W)return f0(H6,{paddingX:2,paddingBottom:1,flexDirection:"row",gap:1,children:[f0(k1,{color:K.colors.warning,bold:!0,children:oZ[J]},void 0,!1,void 0,this),f0(k1,{color:K.colors.text.primary,children:F},void 0,!1,void 0,this),H>0&&f0(fN,{children:[f0(k1,{color:K.colors.muted,children:"|"},void 0,!1,void 0,this),f0(k1,{color:K.colors.info,children:["已用时: ",bU(H)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),f0(k1,{color:K.colors.muted,children:"|"},void 0,!1,void 0,this),f0(k1,{color:K.colors.secondary,children:"Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return f0(H6,{paddingX:2,paddingBottom:1,flexDirection:"column",children:[f0(H6,{flexDirection:"row",gap:1,children:[f0(k1,{color:K.colors.warning,bold:!0,children:oZ[J]},void 0,!1,void 0,this),f0(k1,{color:K.colors.text.primary,children:F},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H>0&&f0(H6,{marginLeft:2,flexDirection:"row",gap:1,children:[f0(k1,{color:K.colors.info,children:["已用时: ",bU(H)]},void 0,!0,void 0,this),f0(k1,{color:K.colors.muted,children:"|"},void 0,!1,void 0,this),f0(k1,{color:K.colors.secondary,children:"Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});import YY from"ansi-escapes";import{Box as F4,Static as yU,useStdout as oN}from"ink";import sN,{useEffect as j2,useMemo as O6,useRef as m4,useState as QY}from"react";import{useStdout as hN}from"ink";import{debounce as xN}from"lodash-es";import{useEffect as pN,useState as mN}from"react";function RU($=200){let{stdout:Z}=hN(),[Y,Q]=mN(Z.rows||24);return pN(()=>{let X=xN(()=>{Q(Z.rows||24)},$);return X(),Z.on("resize",X),()=>{Z.off("resize",X),X.cancel()}},[Z,$]),Y}C8();import{Box as dN,Text as VU}from"ink";import uN from"react";import{jsxDEV as sZ}from"react/jsx-dev-runtime";var tZ=uN.memo(({collapsedCount:$})=>{let Z=$0();if($<=0)return null;let Y=Z.colors.text.muted;return sZ(dN,{flexDirection:"row",marginBottom:1,children:[sZ(VU,{color:Y,children:["▶ ",$," 条历史消息"]},void 0,!0,void 0,this),sZ(VU,{color:Y,children:" [Ctrl+O 展开]"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});tZ.displayName="CollapsedHistorySummary";P8();import{Box as I3,Text as y3}from"ink";import gN from"ink-big-text";import cN from"ink-gradient";import lN from"react";import{jsxDEV as A1}from"react/jsx-dev-runtime";var DU=lN.memo(()=>{return A1(I3,{flexDirection:"column",paddingX:2,paddingTop:1,paddingBottom:1,children:[A1(I3,{flexDirection:"column",children:A1(cN,{name:"pastel",children:A1(gN,{text:"BLADE",font:"block"},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),A1(I3,{marginBottom:1,children:A1(y3,{color:"white",dimColor:!0,children:NY()},void 0,!1,void 0,this)},void 0,!1,void 0,this),A1(I3,{flexDirection:"column",marginBottom:1,children:[A1(I3,{marginBottom:1,children:A1(y3,{color:"white",bold:!0,children:"使用指南:"},void 0,!1,void 0,this)},void 0,!1,void 0,this),A1(y3,{color:"white",children:"1. 输入问题、编辑文件或运行命令"},void 0,!1,void 0,this),A1(y3,{color:"white",children:"2. 使用 /init 创建项目配置文件"},void 0,!1,void 0,this),A1(y3,{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 eZ,Text as j8}from"ink";import iN,{useMemo as MU}from"react";import{jsxDEV as H4}from"react/jsx-dev-runtime";function aN($,Z=60){if(!$)return"";let Y=$.split(`
2848
2848
  `)[0]||"";if(Y.length<=Z)return Y;return`${Y.slice(0,Z)}...`}function rN($){if(!$)return 0;return $.split(`
2849
- `).length}var $Y=iN.memo(({content:$,isStreaming:Z=!1,isExpanded:Y})=>{let Q=$0(),X=MU(()=>rN($),[$]),J=MU(()=>aN($),[$]),G=Q.colors.info,K=Q.colors.muted;return H2(eZ,{flexDirection:"column",marginBottom:1,children:[H2(eZ,{flexDirection:"row",children:[H2(j3,{color:G,children:Y?"▼":"▶"},void 0,!1,void 0,this),H2(j3,{children:" "},void 0,!1,void 0,this),H2(j3,{color:K,children:["Thinking",Z?"...":` (${X} lines)`]},void 0,!0,void 0,this),!Y&&!Z&&J&&H2(j3,{color:K,children:[" - ",J]},void 0,!0,void 0,this),H2(j3,{color:K,dimColor:!0,children:[" ","[Ctrl+T]"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Y&&$&&H2(eZ,{marginLeft:2,marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,paddingY:0,children:H2(j3,{color:K,children:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});$Y.displayName="ThinkingBlock";import{Box as F6,Text as ZY}from"ink";import jU from"react";import{jsxDEV as p2}from"react/jsx-dev-runtime";var IU=jU.memo(({todos:$,visible:Z=!0,compact:Y=!1})=>{let{colors:Q}=$0();if(!Z||$.length===0)return null;let X={total:$.length,completed:$.filter((J)=>J.status==="completed").length,inProgress:$.filter((J)=>J.status==="in_progress").length};return p2(F6,{flexDirection:"column",borderStyle:"single",borderColor:Q.border.light,paddingX:1,paddingY:Y?0:1,marginBottom:1,children:[p2(F6,{marginBottom:Y?0:1,children:[p2(ZY,{dimColor:!0,children:"Tasks "},void 0,!1,void 0,this),p2(ZY,{color:Q.text.muted,children:[X.completed,"/",X.total]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),p2(F6,{flexDirection:"column",children:$.map((J,G)=>p2(nN,{todo:J,compact:Y},J.id||G,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}),nN=jU.memo(({todo:$,compact:Z})=>{let Y,Q=!1,X;switch($.status){case"completed":Y="✓",Q=!0,X=$.content;break;case"in_progress":Y="▶",Q=!1,X=$.activeForm;break;case"pending":default:Y="○",Q=!0,X=$.content;break}return p2(F6,{paddingY:Z?0:0,children:p2(ZY,{dimColor:Q,children:[Y," ",X]},void 0,!0,void 0,this)},void 0,!1,void 0,this)});import{jsxDEV as L0}from"react/jsx-dev-runtime";var vU=sN.memo(()=>{let $=l9(),Z=KW(),Y=qW(),Q=WW(),X=f2(),J=nq(),G=eq(),K=XW(),q=JW(),W=GW(),U=cq(),H=HW(),F=UW(),O=w3(),z=RU(),{stdout:_}=oN(),B=S2(),[L,w]=QY(null),[N,D]=QY([]),[V,I]=QY(new Set),v=m2(F),b=m2(null),C=m2(0),d=m2(0),e=m2(new Set),k=m2(new Set),T=m2([]),g=m2(null);j4(()=>{if(v.current!==F){if(_)_.write(YY.clearTerminal);B.incrementClearCount(),v.current=F}},[F,_,B]);let j=$,M=Q;j4(()=>{if(!Q||X){g.current=null;return}if(g.current===Q)return;g.current=Q;let f=setTimeout(()=>{if(_)_.write(YY.clearTerminal);e.current=new Set,k.current=new Set(j.filter((w$)=>w$.role==="tool").map((w$)=>w$.id)),b.current=null,C.current=0,d.current=0,T.current=[],D([]),I(new Set),B.incrementClearCount(),B.clearFinalizingStreamingMessageId()},50);return()=>clearTimeout(f)},[Q,X,_,B,j]);let R=Z??Q;j4(()=>{b.current=null,C.current=0,d.current=0,e.current=new Set,k.current=new Set(j.filter((f)=>f.role==="tool").map((f)=>f.id)),T.current=[],D([]),I(new Set)},[U]),j4(()=>{if(!R)return;if(b.current===R)return;b.current=R,C.current=0,d.current=0,k.current=new Set(j.filter((f)=>f.role==="tool").map((f)=>f.id)),T.current=[],D([])},[R,j]),j4(()=>{if(!R)return;let f=c6(R);if(!f||f.length<=C.current)return;let w$=f.slice(C.current);C.current=f.length;let G$=w$,N$=T.current;if(N$.length>0)if(G$.some((T0)=>T0.type!=="empty"))G$=[...N$,...G$],T.current=[];else{T.current=[...N$,...G$];return}let X0=G$.length;while(X0>0&&G$[X0-1].type==="empty")X0-=1;if(X0!==G$.length)T.current=G$.slice(X0),G$=G$.slice(0,X0);if(G$.length===0)return;let G0=d.current;d.current+=1;let _2=G0>0;I((T0)=>{if(!R||T0.has(R))return T0;let K$=new Set(T0);return K$.add(R),K$}),D((T0)=>[...T0,L0(F2,{flexDirection:"column",children:L0(x2,{content:"",role:"assistant",terminalWidth:O,isPending:!1,hidePrefix:_2,noMargin:!0,blocksOverride:G$,renderCodeBlocksAsPlainText:!0},void 0,!1,void 0,this)},`streaming-${R}-${G0}`,!1,void 0,this)])},[R,Y.version,O,U]),j4(()=>{if(!R)return;let f=k.current,w$=j.filter((G$)=>G$.role==="tool"&&!f.has(G$.id)&&!e.current.has(G$.id));if(w$.length===0)return;for(let G$ of w$)e.current.add(G$.id);D((G$)=>[...G$,...w$.map((N$)=>L0(F2,{flexDirection:"column",children:L0(x2,{content:N$.content,role:N$.role,terminalWidth:O,metadata:N$.metadata,isPending:!1,messageId:N$.id},void 0,!1,void 0,this)},`streaming-tool-${N$.id}`,!1,void 0,this))])},[R,j,O]);let n=O6(()=>{if(!R)return null;let f=uY(R);if(!f||f.lines.length===0)return null;let G$=Math.max(1,z-8),N$=Math.max(0,f.lines.length-G$);return{visibleLines:f.lines.slice(-G$),hiddenLines:N$,mode:f.mode}},[R,Y.version,z]),y=O6(()=>{if(!R)return!1;return(c6(R)?.length??0)>0},[R,Y.version]);j4(()=>{if(L===null&&j.length>H){if(w(j.length),_)_.write(YY.clearTerminal);B.incrementClearCount()}},[j.length,H,L,_,B]);let u=O6(()=>{return J.some((f)=>f.status==="pending"||f.status==="in_progress")},[J]),s=F?0:L??0,i=s,Y$=O6(()=>{let f=[];if(f.push(L0(DU,{},"header",!1,void 0,this)),i>0)f.push(L0(tZ,{collapsedCount:i},"collapsed-summary",!1,void 0,this));for(let w$=s;w$<j.length;w$++){let G$=j[w$];if(M&&G$.id===M)continue;if(G$.role==="tool"&&e.current.has(G$.id))continue;if(G$.role==="assistant"&&V.has(G$.id))continue;f.push(L0(F2,{flexDirection:"column",children:L0(x2,{content:G$.content,role:G$.role,terminalWidth:O,metadata:G$.metadata,isPending:!1,messageId:G$.id},void 0,!1,void 0,this)},G$.id,!1,void 0,this))}return f},[j,s,i,O,M,V]);return L0(F2,{flexDirection:"column",flexGrow:1,paddingX:2,children:L0(F2,{flexDirection:"column",flexGrow:1,children:[L0(yU,{items:Y$,children:(f)=>f},U,!1,void 0,this),q&&L0(F2,{marginBottom:1,children:L0($Y,{content:q,isStreaming:X,isExpanded:W},void 0,!1,void 0,this)},void 0,!1,void 0,this),N.length>0&&L0(yU,{items:N,children:(f)=>f},`streaming-${U}`,!1,void 0,this),n&&L0(F2,{flexDirection:"column",children:L0(x2,{content:"",role:"assistant",terminalWidth:O,isPending:!0,hidePrefix:y,streamingLines:n.visibleLines,streamingHiddenLines:n.hiddenLines,streamingMode:n.mode},void 0,!1,void 0,this)},void 0,!1,void 0,this),G&&u&&L0(F2,{marginTop:1,children:L0(IU,{todos:J,visible:!0,compact:!1},void 0,!1,void 0,this)},void 0,!1,void 0,this),K.map((f,w$)=>L0(F2,{flexDirection:"column",children:L0(x2,{content:f.displayText,role:"user",terminalWidth:O},void 0,!1,void 0,this)},`pending-${w$}`,!1,void 0,this))]},void 0,!0,void 0,this)},void 0,!1,void 0,this)});i3();g3();t3();n3();k$();import{Box as Z$,Text as c,useFocus as B6,useFocusManager as tN,useInput as I3}from"ink";import EU from"ink-select-input";import eN from"ink-text-input";import{useEffect as PU,useState as d2}from"react";import{jsxDEV as E,Fragment as v8}from"react/jsx-dev-runtime";var TU=({isSelected:$})=>E(Z$,{marginRight:1,children:E(c,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),CU=({isSelected:$,label:Z})=>E(c,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),_6={"openai-compatible":{icon:"⚡",name:"OpenAI Compatible",description:"兼容 OpenAI API 的服务 (千问/豆包/DeepSeek/Ollama等)",isOAuth:!1},anthropic:{icon:"\uD83E\uDD16",name:"Anthropic Claude",description:"Claude 官方 API",isOAuth:!1},gemini:{icon:"✨",name:"Google Gemini",description:"Gemini 官方 API",isOAuth:!1},antigravity:{icon:"\uD83D\uDE80",name:"Google Antigravity",description:"OAuth 登录使用 Claude/Gemini (需 Code Assist 订阅)",isOAuth:!0},copilot:{icon:"\uD83D\uDC19",name:"GitHub Copilot",description:"OAuth 登录使用 GPT/Claude/Gemini (需 Copilot 订阅)",isOAuth:!0},"azure-openai":{icon:"☁️",name:"Azure OpenAI",description:"微软 Azure OpenAI 服务",isOAuth:!1}};function $b($){let Z=_6[$];return`${Z.icon} ${Z.name}`}function XY($){switch($){case"anthropic":return"https://api.anthropic.com";case"gemini":return"https://generativelanguage.googleapis.com/v1beta";case"antigravity":return"https://cloudcode-pa.googleapis.com";case"copilot":return"https://api.githubcopilot.com";default:return null}}var Zb=({onSelect:$,onCancel:Z,initialProvider:Y})=>{let{isFocused:Q}=B6({id:"provider-step"});I3((G,K)=>{if(K.escape)Z()},{isActive:Q});let X=Object.keys(_6).map((G)=>{let K=_6[G];return{label:`${K.icon} ${K.name} - ${K.description}`,value:G}}),J=Y?Math.max(0,X.findIndex((G)=>G.value===Y)):0;return E(Z$,{flexDirection:"column",marginBottom:1,children:[E(Z$,{marginBottom:1,children:E(c,{bold:!0,color:"blue",children:"\uD83D\uDCE1 Step 1: 选择 API 提供商"},void 0,!1,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,children:E(c,{children:"根据您使用的 LLM 服务选择对应的 API 类型"},void 0,!1,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,children:E(EU,{items:X,onSelect:(G)=>$(G.value),indicatorComponent:TU,itemComponent:CU,initialIndex:J},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},z6=({stepNumber:$,icon:Z,title:Y,description:Q,hint:X,examples:J,value:G,placeholder:K,mask:q,previousValue:W,onChange:U,onSubmit:H,onCancel:F})=>{return I3((O,z)=>{if(z.escape)F()},{isActive:!0}),E(Z$,{flexDirection:"column",marginBottom:1,children:[E(Z$,{marginBottom:1,children:E(c,{bold:!0,color:"blue",children:[Z," Step ",$,": ",Y]},void 0,!0,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,children:E(c,{children:Q},void 0,!1,void 0,this)},void 0,!1,void 0,this),W&&E(Z$,{marginBottom:1,children:E(c,{color:"green",children:["✓ ",W]},void 0,!0,void 0,this)},void 0,!1,void 0,this),X&&E(Z$,{marginBottom:1,children:E(c,{dimColor:!0,children:X},void 0,!1,void 0,this)},void 0,!1,void 0,this),J&&J.length>0&&E(v8,{children:[E(Z$,{marginBottom:1,children:E(c,{dimColor:!0,children:"常见示例:"},void 0,!1,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,paddingLeft:2,children:E(c,{dimColor:!0,children:J.join(`
2850
- `)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),E(Z$,{children:[E(c,{bold:!0,color:"cyan",children:["▶"," "]},void 0,!0,void 0,this),E(eN,{value:G,onChange:U,onSubmit:H,placeholder:K,mask:q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},Yb=({provider:$,onLogin:Z,onCancel:Y,isLoggingIn:Q})=>{let{isFocused:X}=B6({id:"oauth-login-step"});I3((G,K)=>{if(Q)return;if(G==="y"||G==="Y")Z();else if(G==="n"||G==="N"||K.escape)Y()},{isActive:X&&!Q});let J=$==="antigravity"?{name:"Google Antigravity",icon:"\uD83D\uDE80",loginCommand:"/login",description:"通过 Google OAuth 登录,使用 Claude/Gemini 模型"}:{name:"GitHub Copilot",icon:"\uD83D\uDC19",loginCommand:"/login copilot",description:"通过 GitHub Device Flow 登录,使用 GPT/Claude/Gemini 模型"};return E(Z$,{flexDirection:"column",marginBottom:1,children:[E(Z$,{marginBottom:1,children:E(c,{bold:!0,color:"yellow",children:[J.icon," 需要登录 ",J.name]},void 0,!0,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,children:E(c,{children:J.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,paddingLeft:2,children:E(c,{dimColor:!0,children:["您也可以稍后手动执行 ",E(c,{bold:!0,children:J.loginCommand},void 0,!1,void 0,this)," 命令登录"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),!Q&&E(Z$,{marginTop:1,children:E(c,{children:["现在登录? [",E(c,{bold:!0,color:"green",children:"Y"},void 0,!1,void 0,this),"/",E(c,{bold:!0,color:"red",children:"n"},void 0,!1,void 0,this),"]"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q&&E(Z$,{marginTop:1,children:E(c,{color:"yellow",children:"⏳ 正在启动登录流程..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},Qb=({provider:$,onSelect:Z,onCancel:Y})=>{let{isFocused:Q}=B6({id:"oauth-model-step"}),[X,J]=d2([]),[G,K]=d2(!0);PU(()=>{(async()=>{K(!0);try{if($==="copilot")J(Object.values(r8));else if(await I0.getInstance().getConfigType()==="gemini-cli")J(Object.values(g8));else J(Object.values(u3))}catch{J(Object.values(u3))}finally{K(!1)}})()},[$]),I3((U,H)=>{if(H.escape)Y()},{isActive:Q});let q=X.map((U)=>({label:`${U.name} - ${U.description}`,value:U.id})),W=$==="antigravity"?"Antigravity":"Copilot";if(G)return E(Z$,{flexDirection:"column",marginBottom:1,children:E(Z$,{marginBottom:1,children:E(c,{bold:!0,color:"blue",children:["\uD83E\uDD16 加载 ",W," 模型列表..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this);return E(Z$,{flexDirection:"column",marginBottom:1,children:[E(Z$,{marginBottom:1,children:E(c,{bold:!0,color:"blue",children:["\uD83E\uDD16 选择 ",W," 模型"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,children:E(c,{children:"从可用模型列表中选择一个"},void 0,!1,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,children:E(EU,{items:q,onSelect:(U)=>Z(U.value),indicatorComponent:TU,itemComponent:CU},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},Xb=({mode:$,config:Z,isSaving:Y,stepNumber:Q,onConfirm:X,onBack:J,onCancel:G})=>{let{isFocused:K}=B6({id:"confirm-step"});return I3((q,W)=>{if(Y)return;if(q==="y"||q==="Y")X();else if(q==="n"||q==="N")J();else if(W.escape)G()},{isActive:K&&!Y}),E(Z$,{flexDirection:"column",marginBottom:1,children:[E(Z$,{marginBottom:1,children:E(c,{bold:!0,color:$==="edit"?"yellow":"blue",children:$==="edit"?"\uD83D\uDCBE 确认修改":`✅ Step ${Q}: 确认配置`},void 0,!1,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,children:E(c,{children:$==="edit"?"请确认修改内容,保存后将立即生效。":"请确认以下配置信息:"},void 0,!1,void 0,this)},void 0,!1,void 0,this),E(Z$,{flexDirection:"column",marginBottom:1,paddingLeft:2,children:[E(Z$,{marginBottom:1,children:[E(c,{dimColor:!0,children:"名称: "},void 0,!1,void 0,this),E(c,{bold:!0,color:"cyan",children:Z.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),E(Z$,{marginBottom:1,children:[E(c,{dimColor:!0,children:"Provider: "},void 0,!1,void 0,this),E(c,{bold:!0,color:"cyan",children:$b(Z.provider)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),E(Z$,{marginBottom:1,children:[E(c,{dimColor:!0,children:"Base URL: "},void 0,!1,void 0,this),E(c,{bold:!0,color:"blue",children:Z.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),E(Z$,{marginBottom:1,children:[E(c,{dimColor:!0,children:"API Key: "},void 0,!1,void 0,this),E(c,{bold:!0,color:"yellow",children:Z.apiKey==="oauth"?"\uD83D\uDD10 OAuth 认证(使用 /login 登录)":E(v8,{children:[Z.apiKey?.slice(0,8),"*".repeat(Math.min(32,(Z.apiKey?.length||0)-8))]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),E(Z$,{children:[E(c,{dimColor:!0,children:"Model: "},void 0,!1,void 0,this),E(c,{bold:!0,color:"cyan",children:Z.model},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),!Y&&E(Z$,{marginTop:1,children:E(c,{children:[$==="edit"?"保存修改? ":"确认保存配置? ","[",E(c,{bold:!0,color:"green",children:"Y"},void 0,!1,void 0,this),"/",E(c,{bold:!0,color:"red",children:"n"},void 0,!1,void 0,this),"]"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Y&&E(Z$,{children:E(c,{color:"yellow",children:"⏳ 正在保存配置到 ~/.blade/config.json..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},JY=({mode:$,initialConfig:Z,modelId:Y,onComplete:Q,onCancel:X})=>{let J=$==="edit",[G,K]=d2("provider"),[q,W]=d2(()=>J&&Z?{...Z}:{}),[U,H]=d2(""),[F,O]=d2(!1),[z,_]=d2(!1),[B,L]=d2(null),w=Q0(!1);I3((y,u)=>{if(u.ctrl&&y==="c"||u.meta&&y==="c")if($==="setup")w();else X()},{isActive:!0});let{focus:N}=tN();PU(()=>{if(G==="provider")N("provider-step");else if(G==="confirm")N("confirm-step");else if(G==="oauthLogin")N("oauth-login-step");else if(G==="oauthModelSelect")N("oauth-model-step")},[G,N]);let D=()=>{if(!U.trim()){L("配置名称不能为空");return}W({...q,name:U}),H(""),L(null),K("confirm")},V=async(y)=>{if(W({...q,provider:y}),I(y)){let i=y==="antigravity"?I0.getInstance():S0.getInstance();try{if(await i.isLoggedIn())K("oauthModelSelect");else K("oauthLogin")}catch{K("oauthLogin")}return}let u=XY(y),s=J?q.baseUrl??Z?.baseUrl??"":u??"";H(s),K("baseUrl")},I=(y)=>{return _6[y].isOAuth},v=()=>{if(!U.trim()){L("Base URL 不能为空");return}try{new URL(U)}catch{L("请输入有效的 URL (例如: https://api.openai.com/v1)");return}if(W({...q,baseUrl:U}),L(null),I(q.provider)){W((u)=>({...u,baseUrl:U,apiKey:"oauth"}));let y=J?q.model??Z?.model??"":"";H(y),K("model")}else{let y=J?q.apiKey??Z?.apiKey??"":"";H(y),K("apiKey")}},b=()=>{if(!U.trim()){L("API Key 不能为空");return}W({...q,apiKey:U});let y=J?q.model??Z?.model??"":"";H(y),L(null),K("model")},C=()=>{if(!U.trim()){L("Model 不能为空");return}W({...q,model:U});let y=J?q.name??Z?.name??"":"";H(y),L(null),K("name")},d=async()=>{let u=q.provider==="antigravity"?I0.getInstance():S0.getInstance();_(!0),L(null);try{await u.login(),K("oauthModelSelect")}catch(s){L(s instanceof Error?s.message:"登录失败")}finally{_(!1)}},e=(y)=>{let u=q.provider,s=XY(u)||"";W({...q,baseUrl:s,apiKey:"oauth",model:y}),H(""),K("name")},k=async()=>{O(!0),L(null);try{let y={name:q.name,provider:q.provider,baseUrl:q.baseUrl,apiKey:q.apiKey,model:q.model};if($==="setup")Q(y);else if($==="add"){let u=await x$().addModel(y);await x$().setCurrentModel(u.id),Q(y)}else{if(!Y)throw Error("未提供模型 ID,无法编辑");await x$().updateModel(Y,y),Q(y)}}catch(y){L(y instanceof Error?y.message:"配置失败"),O(!1)}},T=()=>{switch(L(null),H(""),G){case"provider":X();break;case"baseUrl":K("provider");break;case"apiKey":H(q.baseUrl||""),K("baseUrl");break;case"model":K("apiKey");break;case"oauthLogin":K("provider");break;case"oauthModelSelect":K("provider");break;case"name":if(I(q.provider))K("oauthModelSelect");else H(q.model||""),K("model");break;case"confirm":H(q.name||""),K("name");break}},g=q.provider&&I(q.provider),j=g?4:6,M=(()=>{if(G==="provider")return 1;if(g){if(G==="oauthLogin"||G==="oauthModelSelect")return 2;if(G==="name")return 3;return 4}if(G==="baseUrl")return 2;if(G==="apiKey")return 3;if(G==="model")return 4;if(G==="name")return 5;return 6})(),R=Math.floor((M-1)/(j-1)*40);return E(Z$,{...$==="setup"?{flexDirection:"column",padding:1}:$==="add"?{flexDirection:"column",borderStyle:"round",borderColor:"blue",padding:1}:{flexDirection:"column",borderStyle:"round",borderColor:"yellow",padding:1},children:[$==="setup"?E(v8,{children:[E(Z$,{marginBottom:1,children:E(c,{bold:!0,color:"blue",children:"\uD83D\uDE80 欢迎使用 Blade Code"},void 0,!1,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,children:E(c,{children:"AI 驱动的代码助手 - 让我们开始配置您的助手"},void 0,!1,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,children:[E(c,{bold:!0,color:"blue",children:"█".repeat(R)},void 0,!1,void 0,this),E(c,{dimColor:!0,children:"░".repeat(40-R)},void 0,!1,void 0,this),E(c,{children:" "},void 0,!1,void 0,this),E(c,{bold:!0,color:"cyan",children:[M,"/",j]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),E(Z$,{marginBottom:1,children:E(c,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this):$==="add"?E(v8,{children:[E(Z$,{justifyContent:"center",marginBottom:1,children:E(c,{bold:!0,color:"blue",children:"添加新模型配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,children:E(c,{children:["步骤: ",M,"/",j]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this):E(v8,{children:[E(Z$,{justifyContent:"center",marginBottom:1,children:E(c,{bold:!0,color:"yellow",children:"编辑模型配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,children:E(c,{children:["步骤: ",M,"/",j]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G==="name"&&E(z6,{stepNumber:5,icon:"\uD83D\uDCDD",title:"配置名称",description:"给这个模型配置起一个易于识别的名称(可选,用于区分多个配置)",value:U,placeholder:"例如: 千问工作账号",onChange:H,onSubmit:D,onCancel:X},void 0,!1,void 0,this),G==="provider"&&E(Zb,{onSelect:V,onCancel:X,initialProvider:q.provider},void 0,!1,void 0,this),G==="oauthLogin"&&q.provider&&I(q.provider)&&E(Yb,{provider:q.provider,onLogin:d,onCancel:X,isLoggingIn:z},void 0,!1,void 0,this),G==="oauthModelSelect"&&q.provider&&I(q.provider)&&E(Qb,{provider:q.provider,onSelect:e,onCancel:X},void 0,!1,void 0,this),G==="baseUrl"&&E(z6,{stepNumber:2,icon:"\uD83C\uDF10",title:"配置 Base URL",description:"输入您的 API 端点地址(完整的 URL 包含协议)",hint:q.provider&&XY(q.provider)?"\uD83D\uDCA1 已预填充官方 URL,直接回车使用。如需代理服务(如 OpenRouter),请修改。":void 0,examples:["• OpenAI: https://api.openai.com/v1","• Anthropic: https://api.anthropic.com","• Gemini: https://generativelanguage.googleapis.com/v1beta","• Azure: https://{resource}.openai.azure.com","• 代理: https://openrouter.ai/api/v1"],value:U,placeholder:"https://api.example.com/v1",onChange:H,onSubmit:v,onCancel:X},void 0,!1,void 0,this),G==="apiKey"&&E(z6,{stepNumber:3,icon:"\uD83D\uDD11",title:"输入 API Key",description:"您的 API 密钥将被安全存储在 ~/.blade/config.json (权限 600)",hint:"\uD83D\uDCA1 提示: 输入时字符会被隐藏,支持粘贴 (Ctrl+V / Cmd+V)",previousValue:q.baseUrl?`✓ Base URL: ${q.baseUrl}`:void 0,value:U,placeholder:"sk-...",mask:"*",onChange:H,onSubmit:b,onCancel:X},void 0,!1,void 0,this),G==="model"&&E(z6,{stepNumber:4,icon:"\uD83E\uDD16",title:"选择模型",description:"输入您想使用的模型名称(请参考您的 API 提供商文档)",examples:q.provider==="antigravity"?["• Claude: claude-sonnet-4-5, claude-opus-4-5-thinking","• Gemini: gemini-3-pro-high, gemini-3-pro-low","• GPT-OSS: gpt-oss-120b-medium"]:["• OpenAI: gpt-4o, gpt-4o-mini, o1-preview","• Claude: claude-sonnet-4-20250514, claude-opus-4-20250514","• Gemini: gemini-2.5-pro, gemini-2.5-flash","• Azure: {deployment-name}","• 千问: qwen3-max, qwen3-235b, qwen3-32b","• DeepSeek: deepseek-v3.1, deepseek-r1-0528"],value:U,placeholder:"例如: gpt-5",onChange:H,onSubmit:C,onCancel:X},void 0,!1,void 0,this),G==="confirm"&&E(Xb,{mode:$,config:q,isSaving:F,stepNumber:j,onConfirm:k,onBack:T,onCancel:X},void 0,!1,void 0,this),B&&E(Z$,{marginTop:1,borderStyle:"round",borderColor:"red",paddingX:1,children:E(c,{color:"red",children:["❌ ",B]},void 0,!0,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginTop:1,children:E(c,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this),!F&&!z&&G==="provider"&&E(Z$,{marginTop:1,children:E(c,{dimColor:!0,children:["\uD83D\uDCA1 使用 ",E(c,{bold:!0,children:"↑/↓"},void 0,!1,void 0,this)," 键选择,",E(c,{bold:!0,children:"Enter"},void 0,!1,void 0,this)," 确认,",E(c,{bold:!0,children:"Esc"},void 0,!1,void 0,this)," 取消"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),!F&&!z&&G==="oauthModelSelect"&&E(Z$,{marginTop:1,children:E(c,{dimColor:!0,children:["\uD83D\uDCA1 使用 ",E(c,{bold:!0,children:"↑/↓"},void 0,!1,void 0,this)," 键选择模型,",E(c,{bold:!0,children:"Enter"},void 0,!1,void 0,this)," 确认,",E(c,{bold:!0,children:"Esc"},void 0,!1,void 0,this)," 返回"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),!F&&!z&&G==="oauthLogin"&&E(Z$,{marginTop:1,children:E(c,{dimColor:!0,children:["\uD83D\uDCA1 按"," ",E(c,{bold:!0,color:"green",children:"Y"},void 0,!1,void 0,this)," ","登录,",E(c,{bold:!0,color:"red",children:"N"},void 0,!1,void 0,this)," ","返回,",E(c,{bold:!0,children:"Esc"},void 0,!1,void 0,this)," 取消"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),!F&&!z&&G!=="confirm"&&G!=="provider"&&G!=="oauthLogin"&&G!=="oauthModelSelect"&&E(Z$,{marginTop:1,children:E(c,{dimColor:!0,children:["\uD83D\uDCA1 输入完成后按 ",E(c,{bold:!0,children:"Enter"},void 0,!1,void 0,this),",",E(c,{bold:!0,children:"Ctrl+C"},void 0,!1,void 0,this)," 退出"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),!F&&!z&&G==="confirm"&&E(Z$,{marginTop:1,children:E(c,{dimColor:!0,children:["\uD83D\uDCA1 按"," ",E(c,{bold:!0,color:"green",children:"Y"},void 0,!1,void 0,this)," ","保存,",E(c,{bold:!0,color:"red",children:"N"},void 0,!1,void 0,this)," ","返回修改,",E(c,{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)};u8();import{useMemoizedFn as L6,useMount as Jb}from"ahooks";import{Box as J1,Text as C$,useFocus as Gb,useFocusManager as Kb,useInput as qb}from"ink";import Wb from"ink-select-input";import{memo as Ub,useMemo as Hb,useState as w6}from"react";k$();import{jsxDEV as H$}from"react/jsx-dev-runtime";function Fb($){switch($){case"openai-compatible":return"⚡ OpenAI Compatible";case"anthropic":return"\uD83E\uDD16 Anthropic Claude";case"gemini":return"✨ Google Gemini";case"azure-openai":return"☁️ Azure OpenAI";default:return $}}var Ob=({isSelected:$})=>H$(J1,{marginRight:1,children:H$(C$,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),zb=({isSelected:$,label:Z})=>H$(C$,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),SU=Ub(({onClose:$,onEdit:Z})=>{let Y=$W(),Q=ZW()??"",{isFocused:X}=Gb({id:"model-selector"}),J=Kb(),[G,K]=w6(""),[q,W]=w6(!1),[U,H]=w6(null),F=Q0(!1),[O]=w6(()=>{let I=process.stdout?.columns||80;return Math.max(20,I-8)});Jb(()=>{if(J?.focus("model-selector"),Y.length>0)K(Y[0].id)}),qb((I,v)=>{if(q)return;if(v.ctrl&&I==="c"||v.meta&&I==="c"){F();return}if(v.escape){$();return}if(!X)return;if(I==="d"||I==="D"){_();return}if((I==="e"||I==="E")&&Z)B()},{isActive:!0});let z=L6(async(I)=>{if(q)return;let v=I.value;if(v===Q){$();return}W(!0),H(null);try{await x$().setCurrentModel(v),$()}catch(b){H(b.message),W(!1)}}),_=L6(async()=>{if(q||G===Q)return;W(!0),H(null);try{if(await x$().removeModel(G),Y.length<=1)$()}catch(I){H(I.message)}finally{W(!1)}}),B=L6(()=>{if(q||!Z)return;let I=Y.find((v)=>v.id===G);if(!I)return;Z(I)}),L=L6((I)=>{K(I.value)}),w=Hb(()=>{return Y.find((I)=>I.id===G)},[Y,G]),N=Y.map((I)=>{let v=I.id===Q?" (当前)":"";return{label:I.name+v,value:I.id}}),D=G===Q;return H$(J1,{flexDirection:"column",borderStyle:"round",borderColor:"gray",padding:1,width:"100%",children:[H$(J1,{flexDirection:"row",justifyContent:"space-between",marginBottom:1,children:[H$(C$,{bold:!0,color:"cyan",children:"模型管理"},void 0,!1,void 0,this),H$(C$,{dimColor:!0,children:[q?"⏳ 处理中...":D?"Enter=关闭 • E=编辑 • Esc=取消":"Enter=切换 • D=删除 • E=编辑 • Esc=取消"," • Ctrl+C=退出"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),H$(J1,{flexDirection:"row",children:[H$(J1,{flexDirection:"column",flexGrow:2,marginRight:2,borderStyle:"single",borderColor:"gray",padding:1,children:[H$(C$,{dimColor:!0,children:["已配置模型 (",Y.length,")"]},void 0,!0,void 0,this),H$(J1,{marginTop:1,children:H$(Wb,{items:N,onSelect:z,onHighlight:L,indicatorComponent:Ob,itemComponent:zb},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H$(J1,{flexDirection:"column",flexGrow:3,borderStyle:"single",borderColor:"gray",padding:1,children:[H$(C$,{dimColor:!0,children:"模型详情"},void 0,!1,void 0,this),H$(J1,{marginY:1,children:H$(C$,{color:D?"green":"yellow",children:D?"● 当前使用":"● 可切换"},void 0,!1,void 0,this)},void 0,!1,void 0,this),w?H$(J1,{flexDirection:"column",children:[H$(C$,{children:[H$(C$,{dimColor:!0,children:"名称: "},void 0,!1,void 0,this),H$(C$,{bold:!0,color:"cyan",children:w.name},void 0,!1,void 0,this),N7(w)&&H$(C$,{color:"green",children:" (内置免费)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H$(C$,{children:[H$(C$,{dimColor:!0,children:"Provider: "},void 0,!1,void 0,this),H$(C$,{bold:!0,children:Fb(w.provider)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H$(C$,{children:[H$(C$,{dimColor:!0,children:"Model: "},void 0,!1,void 0,this),H$(C$,{bold:!0,children:w.model},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H$(C$,{children:[H$(C$,{dimColor:!0,children:"Base URL: "},void 0,!1,void 0,this),H$(C$,{color:"blueBright",children:w.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w.temperature!==void 0&&H$(C$,{children:[H$(C$,{dimColor:!0,children:"Temperature: "},void 0,!1,void 0,this),H$(C$,{children:w.temperature},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w.maxContextTokens!==void 0&&H$(C$,{children:[H$(C$,{dimColor:!0,children:"Context Window: "},void 0,!1,void 0,this),H$(C$,{children:w.maxContextTokens},void 0,!1,void 0,this)]},void 0,!0,void 0,this),N7(w)&&H$(J1,{marginTop:1,children:H$(C$,{color:"green",dimColor:!0,children:"\uD83D\uDCA1 此模型由 Blade 提供免费额度"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this):H$(C$,{dimColor:!0,children:"请选择一个模型查看详情"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),U&&H$(J1,{marginTop:1,children:H$(C$,{color:"red",children:["❌ ",U]},void 0,!0,void 0,this)},void 0,!1,void 0,this),H$(J1,{justifyContent:"center",marginTop:1,children:H$(C$,{dimColor:!0,children:"─".repeat(O)},void 0,!1,void 0,this)},void 0,!1,void 0,this),H$(J1,{justifyContent:"center",children:H$(C$,{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 E8}from"ahooks";import{promises as xU}from"fs";import{Box as G1,Text as Z0,useInput as _b}from"ink";import kU from"ink-select-input";import Bb from"ink-text-input";import Lb from"os";import N6 from"path";import{useEffect as wb,useMemo as b6,useRef as Nb,useState as u2}from"react";k$();import{jsxDEV as B$}from"react/jsx-dev-runtime";var P8=[{key:"allow",label:"Allow"},{key:"ask",label:"Ask"},{key:"deny",label:"Deny"},{key:"info",label:"Info"}],bb={allow:"Add a new rule...",ask:"Add a new rule...",deny:"Add a new rule..."},Ab={allow:"Allow permission rules",ask:"Ask permission rules",deny:"Deny permission rules"},fU={project:"[项目共享配置]",global:"[用户全局配置]",local:"[本地配置]"},Rb=["project","global","local"],Vb={allow:[],ask:[],deny:[]},Db={localExists:!1,projectExists:!1,globalExists:!1},hU={allow:[],ask:[],deny:[]};function Mb($){let Z=(Q)=>Array.isArray(Q)?Q.filter((X)=>typeof X==="string"):[],Y=$?.permissions??{};return{allow:Z(Y?.allow),ask:Z(Y?.ask),deny:Z(Y?.deny)}}async function jb($){try{let Z=await xU.readFile($,"utf-8"),Y=JSON.parse(Z);return{exists:!0,raw:Y,permissions:Mb(Y)}}catch(Z){if(Z.code==="ENOENT")return{exists:!1,raw:{},permissions:{...hU}};return console.warn(`[PermissionsManager] Failed to read ${$}:`,Z),{exists:!0,raw:{},permissions:{...hU}}}}function Ib($,Z){let Y=$.padEnd(32," "),Q=Z==="local"?`${fU[Z]} ← 可删除`:fU[Z];return`${Y} ${Q}`}var pU=({onClose:$})=>{let Y=Z1()==="permissions-manager",Q=Q0(!1),[X,J]=u2(0),G=P8[X].key,[K,q]=u2(Vb),[W,U]=u2(Db),[H,F]=u2(!0),[O,z]=u2("list"),[_,B]=u2(""),[L,w]=u2(null),[N,D]=u2(null),V=Nb(!1),I=b6(()=>N6.join(process.cwd(),".blade","settings.local.json"),[]),v=b6(()=>N6.join(process.cwd(),".blade","settings.json"),[]),b=b6(()=>N6.join(Lb.homedir(),".blade","settings.json"),[]),C=E8(async()=>{F(!0);let i=[{source:"local",path:I},{source:"project",path:v},{source:"global",path:b}],Y$=await Promise.all(i.map(async({source:N$,path:X0})=>{let G0=await jb(X0);return{source:N$,path:X0,...G0}})),f={localExists:Y$.find((N$)=>N$.source==="local")?.exists??!1,projectExists:Y$.find((N$)=>N$.source==="project")?.exists??!1,globalExists:Y$.find((N$)=>N$.source==="global")?.exists??!1};U(f);let w$={allow:[],ask:[],deny:[]},G$=Object.fromEntries(Y$.map((N$)=>[N$.source,N$]));["allow","ask","deny"].forEach((N$)=>{Rb.forEach((X0)=>{(G$[X0]?.permissions[N$]??[]).forEach((_2,T0)=>{let K$={key:`${X0}:${T0}:${_2}`,rule:_2,source:X0};w$[N$].push(K$)})})}),q(w$),F(!1)});wb(()=>{C()},[C]);let d=E8(async(i,Y$)=>{try{let f=N6.join(process.cwd(),".blade","settings.local.json"),w$={allow:[],ask:[],deny:[]};try{let N$=await xU.readFile(f,"utf-8"),G0=JSON.parse(N$).permissions||{};w$={allow:Array.isArray(G0.allow)?G0.allow:[],ask:Array.isArray(G0.ask)?G0.ask:[],deny:Array.isArray(G0.deny)?G0.deny:[]}}catch(N$){}let G$=Y$(w$);await x$().updateConfig({permissions:G$},{scope:"local",immediate:!0}),await C()}catch(f){throw console.error("[PermissionsManager] 修改权限规则失败:",f),f}});_b((i,Y$)=>{if(Y$.ctrl&&i==="c"||Y$.meta&&i==="c"){Q();return}if(O==="locked"){if(V.current){V.current=!1;return}z("list"),w(null),D(null);return}if(Y$.escape){if(O==="list"||G==="info")$();else z("list"),B(""),w(null),D(null);return}if(O==="list"){if(Y$.tab&&Y$.shift)J((f)=>(f-1+P8.length)%P8.length);else if(Y$.tab)J((f)=>(f+1)%P8.length);else if(i?.toLowerCase()==="q")$()}},{isActive:Y});let e=E8((i)=>{let Y$=i.value;if(G==="info")return;if(Y$.type==="add"){z("add"),B(""),D(null);return}if(Y$.entry.source!=="local"){z("locked"),V.current=!0,w({tab:G,entry:Y$.entry}),D({type:"error",text:Y$.entry.source==="project"?"此规则定义在项目共享配置中,无法在此删除。":"此规则来自用户全局配置,无法在此删除。"});return}z("confirm-delete"),w({tab:G,entry:Y$.entry}),D(null)}),k=E8(async()=>{if(G==="info")return;let i=_.trim();if(!i){D({type:"error",text:"Permission rule 不能为空"});return}if(K[G].map((f)=>f.rule).includes(i)){D({type:"error",text:"该规则已存在"});return}try{await d(G,(f)=>{let w$={allow:[...f.allow],ask:[...f.ask],deny:[...f.deny]};return w$[G]=[...new Set([...f[G],i])],w$}),z("list"),B(""),D({type:"success",text:"已添加本地权限规则"})}catch(f){D({type:"error",text:`保存失败: ${f instanceof Error?f.message:"未知错误"}`})}}),T=E8(async()=>{if(!L)return;let{tab:i,entry:Y$}=L;try{await d(i,(f)=>{let w$={allow:[...f.allow],ask:[...f.ask],deny:[...f.deny]};return w$[i]=f[i].filter((G$)=>G$!==Y$.rule),w$}),z("list"),w(null),D({type:"success",text:"已删除本地权限规则"})}catch(f){D({type:"error",text:`删除失败: ${f instanceof Error?f.message:"未知错误"}`})}}),g=b6(()=>{if(G==="info")return[];let i=G;return[{key:"add-new-rule",label:`› ${bb[i]}`,value:{type:"add"}},...K[i].map((f)=>({key:f.key,label:Ib(f.rule,f.source),value:{type:"rule",entry:f}}))]},[G,K]),j=()=>B$(G1,{marginBottom:1,children:P8.map((i,Y$)=>B$(G1,{marginRight:2,children:B$(Z0,{color:Y$===X?"yellow":"gray",children:["[",i.label,"]"]},void 0,!0,void 0,this)},i.key,!1,void 0,this))},void 0,!1,void 0,this),M=()=>B$(G1,{flexDirection:"column",gap:1,children:[B$(Z0,{children:"配置文件优先级(从高到低):"},void 0,!1,void 0,this),B$(G1,{flexDirection:"column",marginLeft:2,children:[B$(Z0,{children:["1. .blade/settings.local.json (本地配置,不提交 Git)"," ",W.localExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),B$(Z0,{children:["2. .blade/settings.json (项目配置,提交 Git)"," ",W.projectExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),B$(Z0,{children:["3. ~/.blade/settings.json (用户全局配置)"," ",W.globalExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),B$(Z0,{children:"说明:"},void 0,!1,void 0,this),B$(G1,{flexDirection:"column",marginLeft:2,children:[B$(Z0,{children:"- /permissions 命令只管理本地配置 (.blade/settings.local.json)"},void 0,!1,void 0,this),B$(Z0,{children:"- 修改全局或项目配置请直接编辑对应文件"},void 0,!1,void 0,this),B$(Z0,{children:"- 本地配置不会提交到 Git"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),R=(i)=>B$(G1,{flexDirection:"column",gap:1,children:[B$(Z0,{bold:!0,children:Ab[i]},void 0,!1,void 0,this),B$(Z0,{children:"Permission rules are a tool name, optionally followed by a specifier in parentheses."},void 0,!1,void 0,this),B$(Z0,{color:"gray",children:"例如: WebFetch 或 Bash(ls:*)"},void 0,!1,void 0,this),B$(G1,{marginTop:1,children:B$(Bb,{value:_,onChange:B,onSubmit:k},void 0,!1,void 0,this)},void 0,!1,void 0,this),B$(Z0,{color:"gray",children:"Enter 提交 · Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),n=(i,Y$)=>B$(G1,{flexDirection:"column",gap:1,children:[B$(Z0,{bold:!0,children:["Delete ",i," permission rule?"]},void 0,!0,void 0,this),B$(Z0,{children:Y$.rule},void 0,!1,void 0,this),B$(Z0,{color:"gray",children:"From project local settings"},void 0,!1,void 0,this),B$(Z0,{children:"Are you sure you want to delete this permission rule?"},void 0,!1,void 0,this),B$(kU,{items:[{label:"Yes",value:"yes"},{label:"No",value:"no"}],onSelect:(f)=>{if(f.value==="yes")T();else z("list"),w(null)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),y=(i)=>B$(G1,{flexDirection:"column",gap:1,children:[B$(Z0,{bold:!0,children:"Cannot delete this rule"},void 0,!1,void 0,this),B$(Z0,{children:i.rule},void 0,!1,void 0,this),B$(Z0,{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),B$(Z0,{color:"gray",children:"按任意键继续"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),u=(i)=>B$(kU,{items:g,isFocused:O==="list",onSelect:e},void 0,!1,void 0,this),s=()=>{if(H)return B$(Z0,{children:"加载中..."},void 0,!1,void 0,this);if(G==="info")return M();if(O==="add")return R(G);if(O==="confirm-delete"&&L)return n(L.tab,L.entry);if(O==="locked"&&L)return y(L.entry);return u(G)};return B$(G1,{flexDirection:"column",borderStyle:"round",borderColor:Y?"cyan":"gray",padding:1,width:80,children:[B$(Z0,{color:"cyan",bold:!0,children:"⚙️ 权限管理器"},void 0,!1,void 0,this),j(),B$(G1,{flexDirection:"column",gap:1,children:s()},void 0,!1,void 0,this),N&&B$(G1,{marginTop:1,children:B$(Z0,{color:N.type==="success"?"green":"red",children:N.text},void 0,!1,void 0,this)},void 0,!1,void 0,this),B$(G1,{marginTop:1,children:B$(Z0,{color:"gray",children:"Tab 切换视图 · Esc 关闭 · Q 退出"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};q3();import{Box as t$,Text as A$,useInput as yb}from"ink";import{jsxDEV as r}from"react/jsx-dev-runtime";function mU({onCancel:$}){let Z=a0(),Y=Z.getAll(),Q=Z.getBySource(),X=Z.getStats(),J=Q0(!1,$);if(yb((G,K)=>{if(K.escape)$?.();else if(K.ctrl&&G==="c"||K.meta&&G==="c")J()}),Y.length===0)return r(t$,{flexDirection:"column",paddingY:1,children:[r(t$,{marginBottom:1,children:r(A$,{bold:!0,color:"cyan",children:"\uD83D\uDD0C 插件管理器"},void 0,!1,void 0,this)},void 0,!1,void 0,this),r(t$,{paddingLeft:2,children:r(A$,{color:"gray",children:"没有已加载的插件"},void 0,!1,void 0,this)},void 0,!1,void 0,this),r(t$,{marginTop:1,paddingLeft:2,flexDirection:"column",children:[r(A$,{color:"gray",children:"插件目录位置:"},void 0,!1,void 0,this),r(A$,{color:"gray",dimColor:!0,children:[" ","• ~/.blade/plugins/ - 用户级插件"]},void 0,!0,void 0,this),r(A$,{color:"gray",dimColor:!0,children:[" ","• .blade/plugins/ - 项目级插件"]},void 0,!0,void 0,this),r(A$,{color:"gray",dimColor:!0,children:[" ","• --plugin-dir - CLI 指定的插件"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),r(t$,{marginTop:1,paddingLeft:2,children:r(A$,{color:"gray",children:"使用 /plugins install <url> 安装新插件"},void 0,!1,void 0,this)},void 0,!1,void 0,this),r(t$,{marginTop:1,children:r(A$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return r(t$,{flexDirection:"column",paddingY:1,children:[r(t$,{marginBottom:1,children:[r(A$,{bold:!0,color:"cyan",children:"\uD83D\uDD0C 插件管理器"},void 0,!1,void 0,this),r(A$,{color:"gray",children:[" (共 ",X.total," 个插件)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),r(t$,{paddingLeft:2,marginBottom:1,children:r(A$,{color:"gray",children:["启用: ",X.active," | 禁用: ",X.inactive," | 命令: ",X.commands," | 技能:"," ",X.skills," | 代理: ",X.agents]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q.cli.length>0&&r(t$,{flexDirection:"column",marginBottom:1,children:[r(t$,{paddingLeft:1,children:[r(A$,{bold:!0,color:"magenta",children:"CLI 指定"},void 0,!1,void 0,this),r(A$,{color:"gray",children:" (--plugin-dir)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.cli.map((G)=>{let K=G.status==="active"?"✅":"⏸️";return r(t$,{flexDirection:"column",paddingLeft:2,children:[r(A$,{children:[r(A$,{bold:!0,color:"green",children:[K," ",G.manifest.name]},void 0,!0,void 0,this),r(A$,{color:"gray",children:[" v",G.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),r(t$,{paddingLeft:2,children:r(A$,{color:"gray",children:G.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),G.commands.length>0&&r(t$,{paddingLeft:2,children:r(A$,{color:"blue",children:["命令:"," ",G.commands.map((q)=>`/${q.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},G.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.project.length>0&&r(t$,{flexDirection:"column",marginBottom:1,children:[r(t$,{paddingLeft:1,children:[r(A$,{bold:!0,color:"yellow",children:"项目级"},void 0,!1,void 0,this),r(A$,{color:"gray",children:" (.blade/plugins/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.project.map((G)=>{let K=G.status==="active"?"✅":"⏸️";return r(t$,{flexDirection:"column",paddingLeft:2,children:[r(A$,{children:[r(A$,{bold:!0,color:"green",children:[K," ",G.manifest.name]},void 0,!0,void 0,this),r(A$,{color:"gray",children:[" v",G.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),r(t$,{paddingLeft:2,children:r(A$,{color:"gray",children:G.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),G.commands.length>0&&r(t$,{paddingLeft:2,children:r(A$,{color:"blue",children:["命令:"," ",G.commands.map((q)=>`/${q.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},G.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.user.length>0&&r(t$,{flexDirection:"column",marginBottom:1,children:[r(t$,{paddingLeft:1,children:[r(A$,{bold:!0,color:"cyan",children:"用户级"},void 0,!1,void 0,this),r(A$,{color:"gray",children:" (~/.blade/plugins/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.user.map((G)=>{let K=G.status==="active"?"✅":"⏸️";return r(t$,{flexDirection:"column",paddingLeft:2,children:[r(A$,{children:[r(A$,{bold:!0,color:"green",children:[K," ",G.manifest.name]},void 0,!0,void 0,this),r(A$,{color:"gray",children:[" v",G.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),r(t$,{paddingLeft:2,children:r(A$,{color:"gray",children:G.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),G.commands.length>0&&r(t$,{paddingLeft:2,children:r(A$,{color:"blue",children:["命令:"," ",G.commands.map((q)=>`/${q.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},G.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),r(t$,{marginTop:1,paddingLeft:2,flexDirection:"column",children:[r(A$,{color:"gray",children:"可用命令:"},void 0,!1,void 0,this),r(A$,{color:"gray",dimColor:!0,children:[" ","• /plugins list - 列出所有插件"]},void 0,!0,void 0,this),r(A$,{color:"gray",dimColor:!0,children:[" ","• /plugins info <name> - 显示插件详情"]},void 0,!0,void 0,this),r(A$,{color:"gray",dimColor:!0,children:[" ","• /plugins install <url> - 安装插件"]},void 0,!0,void 0,this),r(A$,{color:"gray",dimColor:!0,children:[" ","• /plugins enable/disable <name> - 启用/禁用插件"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),r(t$,{marginTop:1,children:r(A$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}import{Box as h0,Text as x0,useInput as dU,useStdout as vb}from"ink";import Eb from"ink-text-input";import GY,{useCallback as T8,useMemo as Pb,useState as g2}from"react";import{jsxDEV as D$}from"react/jsx-dev-runtime";var Tb=GY.memo(({option:$,index:Z,isSelected:Y,isMultiSelect:Q,isHighlighted:X})=>D$(h0,{flexDirection:"column",marginBottom:1,children:[D$(x0,{color:X?"yellow":Y?"green":void 0,bold:X,children:[Q?Y?"● ":"○ ":X?"❯ ":" ",Z+1,". ",$.label]},void 0,!0,void 0,this),D$(h0,{marginLeft:4,children:D$(x0,{color:"gray",children:$.description},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)),Cb=GY.memo(({questions:$,answers:Z})=>D$(h0,{flexDirection:"column",marginBottom:1,children:$.map((Y)=>{let Q=Z[Y.header],X=Array.isArray(Q)?Q.join(", "):Q||"(no answer)";return D$(h0,{marginBottom:1,children:[D$(x0,{backgroundColor:"blue",color:"white",children:[" ",Y.header," "]},void 0,!0,void 0,this),D$(x0,{color:"green",children:[" ",X]},void 0,!0,void 0,this)]},Y.header,!0,void 0,this)})},void 0,!1,void 0,this)),uU=GY.memo(({questions:$,onComplete:Z,onCancel:Y})=>{let{stdout:Q}=vb(),X=Q.columns||80,G=Z1()==="confirmation-prompt",K=Q0(!1),[q,W]=g2("answering"),[U,H]=g2(0),[F,O]=g2({}),[z,_]=g2(0),[B,L]=g2([]),[w,N]=g2(!1),[D,V]=g2(""),[I,v]=g2(0),b=$[U],C=Pb(()=>{if(!b)return[];return[...b.options.map((j)=>({label:j.label,value:j.label,description:j.description})),{label:"Type something...",value:"__other__",description:"Enter custom response"}]},[b]),d=T8((j)=>{let M={...F,[b.header]:j};if(O(M),U<$.length-1)H(U+1),_(0),L([]),N(!1),V("");else W("submit"),v(0)},[F,b?.header,U,$.length]),e=T8((j)=>{let M=C[j];if(!M)return;if(M.value==="__other__"){N(!0);return}if(b.multiSelect)L((R)=>R.includes(M.value)?R.filter((n)=>n!==M.value):[...R,M.value]);else d(M.value)},[C,b?.multiSelect,d]),k=T8((j)=>{if(j.trim())d(j.trim())},[d]),T=T8(()=>{W("answering"),H(0),_(0),L([]),N(!1)},[]),g=T8(()=>{Z(F)},[F,Z]);if(dU((j,M)=>{if(M.ctrl&&j==="c"||M.meta&&j==="c"){K();return}if(w){if(M.escape)N(!1),V("");return}if(M.escape){Y();return}let R=parseInt(j);if(R>=1&&R<=C.length){e(R-1);return}if(M.upArrow){_((n)=>n>0?n-1:C.length-1);return}if(M.downArrow||M.tab){_((n)=>n<C.length-1?n+1:0);return}if(M.return){if(b.multiSelect&&B.length>0)d(B);else e(z);return}if(j===" "&&b.multiSelect){let n=C[z];if(n&&n.value!=="__other__")L((y)=>y.includes(n.value)?y.filter((u)=>u!==n.value):[...y,n.value]);return}},{isActive:G&&q==="answering"&&!w}),dU((j,M)=>{if(M.ctrl&&j==="c"||M.meta&&j==="c"){K();return}if(M.escape){Y();return}if(M.upArrow||M.downArrow||M.tab){v((R)=>R===0?1:0);return}if(M.return){if(I===0)g();else T();return}if(j.toLowerCase()==="y"){g();return}if(j.toLowerCase()==="e"){T();return}},{isActive:G&&q==="submit"}),q==="submit")return D$(h0,{flexDirection:"column",borderStyle:"round",borderColor:G?"green":"gray",padding:1,width:Math.min(X-4,80),children:[D$(h0,{marginBottom:1,children:D$(x0,{bold:!0,color:"green",children:"✓ Review Your Answers"},void 0,!1,void 0,this)},void 0,!1,void 0,this),D$(Cb,{questions:$,answers:F},void 0,!1,void 0,this),D$(h0,{flexDirection:"column",marginTop:1,children:[D$(x0,{color:I===0?"yellow":void 0,bold:I===0,children:[I===0?"❯ ":" ","[Y] Submit answers"]},void 0,!0,void 0,this),D$(x0,{color:I===1?"yellow":void 0,bold:I===1,children:[I===1?"❯ ":" ","[E] Edit answers"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),D$(h0,{marginTop:1,children:D$(x0,{color:"gray",children:"Enter to confirm · ↑↓ to navigate · Y/E for quick select"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(!b)return null;return D$(h0,{flexDirection:"column",borderStyle:"round",borderColor:G?"cyan":"gray",padding:1,width:Math.min(X-4,80),children:[D$(h0,{marginBottom:1,children:[D$(x0,{backgroundColor:"blue",color:"white",children:[" ",b.header," "]},void 0,!0,void 0,this),D$(x0,{children:[" ",b.question]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),w?D$(h0,{flexDirection:"column",marginTop:1,children:[D$(x0,{color:"yellow",children:"Enter your response:"},void 0,!1,void 0,this),D$(h0,{marginTop:1,children:[D$(x0,{color:"cyan",children:"❯ "},void 0,!1,void 0,this),D$(Eb,{value:D,onChange:V,onSubmit:k,focus:G},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D$(h0,{marginTop:1,children:D$(x0,{color:"gray",children:"(Press Enter to submit, ESC to go back)"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this):D$(h0,{flexDirection:"column",children:C.map((j,M)=>D$(Tb,{option:j,index:M,isSelected:B.includes(j.value),isMultiSelect:b.multiSelect,isHighlighted:z===M},j.value,!1,void 0,this))},void 0,!1,void 0,this),!w&&D$(h0,{marginTop:1,flexDirection:"column",children:[D$(x0,{color:"gray",children:b.multiSelect?"Space to toggle · Enter to confirm · 1-9 for quick select":"Enter to select · ↑↓ or Tab to navigate · 1-9 for quick select"},void 0,!1,void 0,this),b.multiSelect&&B.length>0&&D$(x0,{color:"green",children:["Selected: ",B.join(", ")]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$.length>1&&D$(h0,{marginTop:1,children:D$(x0,{color:"gray",children:["Question ",U+1," of ",$.length]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});m9();import{Box as y3,Text as f1,useInput as Sb}from"ink";import kb from"ink-select-input";import{basename as fb}from"node:path";import{useEffect as gU,useMemo as A6,useState as KY}from"react";import{jsxDEV as y0}from"react/jsx-dev-runtime";function hb($){let Z=new Date($),Q=new Date().getTime()-Z.getTime(),X=Math.floor(Q/86400000);if(X===0)return`今天 ${Z.getHours().toString().padStart(2,"0")}:${Z.getMinutes().toString().padStart(2,"0")}`;if(X===1)return"昨天";if(X<7)return`${X}天前`;return`${Z.getMonth()+1}/${Z.getDate()}`}function xb($){return fb($)}var pb=({isSelected:$})=>y0(y3,{marginRight:1,children:y0(f1,{color:$?"cyan":"gray",children:$?"❯":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),mb=({isSelected:$,label:Z})=>y0(f1,{color:$?"cyan":"white",bold:$,children:Z},void 0,!1,void 0,this),C8=20,cU=({sessions:$,onSelect:Z,onCancel:Y})=>{let[Q,X]=KY([]),[J,G]=KY(!1),[K,q]=KY(0),U=Z1()==="session-selector",H=Q0(!1);Sb((w,N)=>{if(N.ctrl&&w==="c"||N.meta&&w==="c"){H();return}if(N.escape&&Y){Y();return}if(N.leftArrow||w==="h"||w==="H"){if(K>0)q((D)=>D-1);return}if(N.rightArrow||w==="l"||w==="L"){if(K<z-1)q((D)=>D+1);return}},{isActive:U}),gU(()=>{if($){X($);return}(async()=>{G(!0);try{let N=await _1.listSessions();X(N)}catch(N){console.error("[SessionSelector] Failed to load sessions:",N),X([])}finally{G(!1)}})()},[$]);let F=$||Q,O=A6(()=>{return F.map((w)=>{let N=xb(w.projectPath),D=hb(w.lastMessageTime),V=w.gitBranch?` (${w.gitBranch})`:"",I=w.hasErrors?" ⚠️":"";return{label:`\uD83D\uDCC5 ${D} | ${N}${V} | ${w.messageCount} 条消息${I}`,value:w.sessionId}})},[F]),z=A6(()=>Math.max(1,Math.ceil(O.length/C8)),[O.length]),_=A6(()=>{let w=K*C8;return O.slice(w,w+C8)},[O,K]),B=A6(()=>({start:K*C8+1,end:Math.min((K+1)*C8,O.length)}),[K,O.length]);gU(()=>{q(0)},[F.length]);let L=(w)=>{Z(w.value)};if(J)return y0(y3,{flexDirection:"column",paddingX:2,paddingY:1,children:y0(f1,{children:"⏳ 正在加载会话列表..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(F.length===0)return y0(y3,{flexDirection:"column",paddingX:2,paddingY:1,children:[y0(f1,{color:"yellow",children:"⚠️ 没有找到历史会话"},void 0,!1,void 0,this),y0(f1,{dimColor:!0,children:[`
2851
- `,"提示: 开始一次对话后,会话历史将保存到 ~/.blade/projects/"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this);return y0(y3,{flexDirection:"column",paddingX:2,paddingY:1,children:[y0(f1,{bold:!0,color:"cyan",children:"\uD83D\uDCC2 选择要恢复的会话:"},void 0,!1,void 0,this),y0(f1,{dimColor:!0,children:[`
2849
+ `).length}var $Y=iN.memo(({content:$,isStreaming:Z=!1,isExpanded:Y})=>{let Q=$0(),X=MU(()=>rN($),[$]),J=MU(()=>aN($),[$]),G=Q.colors.info,K=Q.colors.muted;return H4(eZ,{flexDirection:"column",marginBottom:1,children:[H4(eZ,{flexDirection:"row",children:[H4(j8,{color:G,children:Y?"▼":"▶"},void 0,!1,void 0,this),H4(j8,{children:" "},void 0,!1,void 0,this),H4(j8,{color:K,children:["Thinking",Z?"...":` (${X} lines)`]},void 0,!0,void 0,this),!Y&&!Z&&J&&H4(j8,{color:K,children:[" - ",J]},void 0,!0,void 0,this),H4(j8,{color:K,dimColor:!0,children:[" ","[Ctrl+T]"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Y&&$&&H4(eZ,{marginLeft:2,marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,paddingY:0,children:H4(j8,{color:K,children:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});$Y.displayName="ThinkingBlock";import{Box as F6,Text as ZY}from"ink";import jU from"react";import{jsxDEV as p4}from"react/jsx-dev-runtime";var IU=jU.memo(({todos:$,visible:Z=!0,compact:Y=!1})=>{let{colors:Q}=$0();if(!Z||$.length===0)return null;let X={total:$.length,completed:$.filter((J)=>J.status==="completed").length,inProgress:$.filter((J)=>J.status==="in_progress").length};return p4(F6,{flexDirection:"column",borderStyle:"single",borderColor:Q.border.light,paddingX:1,paddingY:Y?0:1,marginBottom:1,children:[p4(F6,{marginBottom:Y?0:1,children:[p4(ZY,{dimColor:!0,children:"Tasks "},void 0,!1,void 0,this),p4(ZY,{color:Q.text.muted,children:[X.completed,"/",X.total]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),p4(F6,{flexDirection:"column",children:$.map((J,G)=>p4(nN,{todo:J,compact:Y},J.id||G,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}),nN=jU.memo(({todo:$,compact:Z})=>{let Y,Q=!1,X;switch($.status){case"completed":Y="✓",Q=!0,X=$.content;break;case"in_progress":Y="▶",Q=!1,X=$.activeForm;break;case"pending":default:Y="○",Q=!0,X=$.content;break}return p4(F6,{paddingY:Z?0:0,children:p4(ZY,{dimColor:Q,children:[Y," ",X]},void 0,!0,void 0,this)},void 0,!1,void 0,this)});import{jsxDEV as L0}from"react/jsx-dev-runtime";var vU=sN.memo(()=>{let $=l9(),Z=KW(),Y=qW(),Q=WW(),X=f4(),J=nq(),G=eq(),K=XW(),q=JW(),W=GW(),U=cq(),H=HW(),F=UW(),O=w8(),z=RU(),{stdout:_}=oN(),B=S4(),[L,w]=QY(null),[N,D]=QY([]),[V,I]=QY(new Set),v=m4(F),b=m4(null),C=m4(0),d=m4(0),e=m4(new Set),k=m4(new Set),T=m4([]),g=m4(null);j2(()=>{if(v.current!==F){if(_)_.write(YY.clearTerminal);B.incrementClearCount(),v.current=F}},[F,_,B]);let j=$,M=Q;j2(()=>{if(!Q||X){g.current=null;return}if(g.current===Q)return;g.current=Q;let f=setTimeout(()=>{if(_)_.write(YY.clearTerminal);e.current=new Set,k.current=new Set(j.filter((w$)=>w$.role==="tool").map((w$)=>w$.id)),b.current=null,C.current=0,d.current=0,T.current=[],D([]),I(new Set),B.incrementClearCount(),B.clearFinalizingStreamingMessageId()},50);return()=>clearTimeout(f)},[Q,X,_,B,j]);let R=Z??Q;j2(()=>{b.current=null,C.current=0,d.current=0,e.current=new Set,k.current=new Set(j.filter((f)=>f.role==="tool").map((f)=>f.id)),T.current=[],D([]),I(new Set)},[U]),j2(()=>{if(!R)return;if(b.current===R)return;b.current=R,C.current=0,d.current=0,k.current=new Set(j.filter((f)=>f.role==="tool").map((f)=>f.id)),T.current=[],D([])},[R,j]),j2(()=>{if(!R)return;let f=c6(R);if(!f||f.length<=C.current)return;let w$=f.slice(C.current);C.current=f.length;let G$=w$,N$=T.current;if(N$.length>0)if(G$.some((T0)=>T0.type!=="empty"))G$=[...N$,...G$],T.current=[];else{T.current=[...N$,...G$];return}let X0=G$.length;while(X0>0&&G$[X0-1].type==="empty")X0-=1;if(X0!==G$.length)T.current=G$.slice(X0),G$=G$.slice(0,X0);if(G$.length===0)return;let G0=d.current;d.current+=1;let _4=G0>0;I((T0)=>{if(!R||T0.has(R))return T0;let K$=new Set(T0);return K$.add(R),K$}),D((T0)=>[...T0,L0(F4,{flexDirection:"column",children:L0(x4,{content:"",role:"assistant",terminalWidth:O,isPending:!1,hidePrefix:_4,noMargin:!0,blocksOverride:G$,renderCodeBlocksAsPlainText:!0},void 0,!1,void 0,this)},`streaming-${R}-${G0}`,!1,void 0,this)])},[R,Y.version,O,U]),j2(()=>{if(!R)return;let f=k.current,w$=j.filter((G$)=>G$.role==="tool"&&!f.has(G$.id)&&!e.current.has(G$.id));if(w$.length===0)return;for(let G$ of w$)e.current.add(G$.id);D((G$)=>[...G$,...w$.map((N$)=>L0(F4,{flexDirection:"column",children:L0(x4,{content:N$.content,role:N$.role,terminalWidth:O,metadata:N$.metadata,isPending:!1,messageId:N$.id},void 0,!1,void 0,this)},`streaming-tool-${N$.id}`,!1,void 0,this))])},[R,j,O]);let n=O6(()=>{if(!R)return null;let f=uY(R);if(!f||f.lines.length===0)return null;let G$=Math.max(1,z-8),N$=Math.max(0,f.lines.length-G$);return{visibleLines:f.lines.slice(-G$),hiddenLines:N$,mode:f.mode}},[R,Y.version,z]),y=O6(()=>{if(!R)return!1;return(c6(R)?.length??0)>0},[R,Y.version]);j2(()=>{if(L===null&&j.length>H){if(w(j.length),_)_.write(YY.clearTerminal);B.incrementClearCount()}},[j.length,H,L,_,B]);let u=O6(()=>{return J.some((f)=>f.status==="pending"||f.status==="in_progress")},[J]),s=F?0:L??0,i=s,Y$=O6(()=>{let f=[];if(f.push(L0(DU,{},"header",!1,void 0,this)),i>0)f.push(L0(tZ,{collapsedCount:i},"collapsed-summary",!1,void 0,this));for(let w$=s;w$<j.length;w$++){let G$=j[w$];if(M&&G$.id===M)continue;if(G$.role==="tool"&&e.current.has(G$.id))continue;if(G$.role==="assistant"&&V.has(G$.id))continue;f.push(L0(F4,{flexDirection:"column",children:L0(x4,{content:G$.content,role:G$.role,terminalWidth:O,metadata:G$.metadata,isPending:!1,messageId:G$.id},void 0,!1,void 0,this)},G$.id,!1,void 0,this))}return f},[j,s,i,O,M,V]);return L0(F4,{flexDirection:"column",flexGrow:1,paddingX:2,children:L0(F4,{flexDirection:"column",flexGrow:1,children:[L0(yU,{items:Y$,children:(f)=>f},U,!1,void 0,this),q&&L0(F4,{marginBottom:1,children:L0($Y,{content:q,isStreaming:X,isExpanded:W},void 0,!1,void 0,this)},void 0,!1,void 0,this),N.length>0&&L0(yU,{items:N,children:(f)=>f},`streaming-${U}`,!1,void 0,this),n&&L0(F4,{flexDirection:"column",children:L0(x4,{content:"",role:"assistant",terminalWidth:O,isPending:!0,hidePrefix:y,streamingLines:n.visibleLines,streamingHiddenLines:n.hiddenLines,streamingMode:n.mode},void 0,!1,void 0,this)},void 0,!1,void 0,this),G&&u&&L0(F4,{marginTop:1,children:L0(IU,{todos:J,visible:!0,compact:!1},void 0,!1,void 0,this)},void 0,!1,void 0,this),K.map((f,w$)=>L0(F4,{flexDirection:"column",children:L0(x4,{content:f.displayText,role:"user",terminalWidth:O},void 0,!1,void 0,this)},`pending-${w$}`,!1,void 0,this))]},void 0,!0,void 0,this)},void 0,!1,void 0,this)});i8();g8();t8();n8();k$();import{Box as Z$,Text as c,useFocus as B6,useFocusManager as tN,useInput as I8}from"ink";import EU from"ink-select-input";import eN from"ink-text-input";import{useEffect as PU,useState as d4}from"react";import{jsxDEV as E,Fragment as v3}from"react/jsx-dev-runtime";var TU=({isSelected:$})=>E(Z$,{marginRight:1,children:E(c,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),CU=({isSelected:$,label:Z})=>E(c,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),_6={"openai-compatible":{icon:"⚡",name:"OpenAI Compatible",description:"兼容 OpenAI API 的服务 (千问/豆包/DeepSeek/Ollama等)",isOAuth:!1},anthropic:{icon:"\uD83E\uDD16",name:"Anthropic Claude",description:"Claude 官方 API",isOAuth:!1},gemini:{icon:"✨",name:"Google Gemini",description:"Gemini 官方 API",isOAuth:!1},antigravity:{icon:"\uD83D\uDE80",name:"Google Antigravity",description:"OAuth 登录使用 Claude/Gemini (需 Code Assist 订阅)",isOAuth:!0},copilot:{icon:"\uD83D\uDC19",name:"GitHub Copilot",description:"OAuth 登录使用 GPT/Claude/Gemini (需 Copilot 订阅)",isOAuth:!0},"azure-openai":{icon:"☁️",name:"Azure OpenAI",description:"微软 Azure OpenAI 服务",isOAuth:!1}};function $b($){let Z=_6[$];return`${Z.icon} ${Z.name}`}function XY($){switch($){case"anthropic":return"https://api.anthropic.com";case"gemini":return"https://generativelanguage.googleapis.com/v1beta";case"antigravity":return"https://cloudcode-pa.googleapis.com";case"copilot":return"https://api.githubcopilot.com";default:return null}}var Zb=({onSelect:$,onCancel:Z,initialProvider:Y})=>{let{isFocused:Q}=B6({id:"provider-step"});I8((G,K)=>{if(K.escape)Z()},{isActive:Q});let X=Object.keys(_6).map((G)=>{let K=_6[G];return{label:`${K.icon} ${K.name} - ${K.description}`,value:G}}),J=Y?Math.max(0,X.findIndex((G)=>G.value===Y)):0;return E(Z$,{flexDirection:"column",marginBottom:1,children:[E(Z$,{marginBottom:1,children:E(c,{bold:!0,color:"blue",children:"\uD83D\uDCE1 Step 1: 选择 API 提供商"},void 0,!1,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,children:E(c,{children:"根据您使用的 LLM 服务选择对应的 API 类型"},void 0,!1,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,children:E(EU,{items:X,onSelect:(G)=>$(G.value),indicatorComponent:TU,itemComponent:CU,initialIndex:J},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},z6=({stepNumber:$,icon:Z,title:Y,description:Q,hint:X,examples:J,value:G,placeholder:K,mask:q,previousValue:W,onChange:U,onSubmit:H,onCancel:F})=>{return I8((O,z)=>{if(z.escape)F()},{isActive:!0}),E(Z$,{flexDirection:"column",marginBottom:1,children:[E(Z$,{marginBottom:1,children:E(c,{bold:!0,color:"blue",children:[Z," Step ",$,": ",Y]},void 0,!0,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,children:E(c,{children:Q},void 0,!1,void 0,this)},void 0,!1,void 0,this),W&&E(Z$,{marginBottom:1,children:E(c,{color:"green",children:["✓ ",W]},void 0,!0,void 0,this)},void 0,!1,void 0,this),X&&E(Z$,{marginBottom:1,children:E(c,{dimColor:!0,children:X},void 0,!1,void 0,this)},void 0,!1,void 0,this),J&&J.length>0&&E(v3,{children:[E(Z$,{marginBottom:1,children:E(c,{dimColor:!0,children:"常见示例:"},void 0,!1,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,paddingLeft:2,children:E(c,{dimColor:!0,children:J.join(`
2850
+ `)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),E(Z$,{children:[E(c,{bold:!0,color:"cyan",children:["▶"," "]},void 0,!0,void 0,this),E(eN,{value:G,onChange:U,onSubmit:H,placeholder:K,mask:q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},Yb=({provider:$,onLogin:Z,onCancel:Y,isLoggingIn:Q})=>{let{isFocused:X}=B6({id:"oauth-login-step"});I8((G,K)=>{if(Q)return;if(G==="y"||G==="Y")Z();else if(G==="n"||G==="N"||K.escape)Y()},{isActive:X&&!Q});let J=$==="antigravity"?{name:"Google Antigravity",icon:"\uD83D\uDE80",loginCommand:"/login",description:"通过 Google OAuth 登录,使用 Claude/Gemini 模型"}:{name:"GitHub Copilot",icon:"\uD83D\uDC19",loginCommand:"/login copilot",description:"通过 GitHub Device Flow 登录,使用 GPT/Claude/Gemini 模型"};return E(Z$,{flexDirection:"column",marginBottom:1,children:[E(Z$,{marginBottom:1,children:E(c,{bold:!0,color:"yellow",children:[J.icon," 需要登录 ",J.name]},void 0,!0,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,children:E(c,{children:J.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,paddingLeft:2,children:E(c,{dimColor:!0,children:["您也可以稍后手动执行 ",E(c,{bold:!0,children:J.loginCommand},void 0,!1,void 0,this)," 命令登录"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),!Q&&E(Z$,{marginTop:1,children:E(c,{children:["现在登录? [",E(c,{bold:!0,color:"green",children:"Y"},void 0,!1,void 0,this),"/",E(c,{bold:!0,color:"red",children:"n"},void 0,!1,void 0,this),"]"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q&&E(Z$,{marginTop:1,children:E(c,{color:"yellow",children:"⏳ 正在启动登录流程..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},Qb=({provider:$,onSelect:Z,onCancel:Y})=>{let{isFocused:Q}=B6({id:"oauth-model-step"}),[X,J]=d4([]),[G,K]=d4(!0);PU(()=>{(async()=>{K(!0);try{if($==="copilot")J(Object.values(r3));else if(await I0.getInstance().getConfigType()==="gemini-cli")J(Object.values(g3));else J(Object.values(u8))}catch{J(Object.values(u8))}finally{K(!1)}})()},[$]),I8((U,H)=>{if(H.escape)Y()},{isActive:Q});let q=X.map((U)=>({label:`${U.name} - ${U.description}`,value:U.id})),W=$==="antigravity"?"Antigravity":"Copilot";if(G)return E(Z$,{flexDirection:"column",marginBottom:1,children:E(Z$,{marginBottom:1,children:E(c,{bold:!0,color:"blue",children:["\uD83E\uDD16 加载 ",W," 模型列表..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this);return E(Z$,{flexDirection:"column",marginBottom:1,children:[E(Z$,{marginBottom:1,children:E(c,{bold:!0,color:"blue",children:["\uD83E\uDD16 选择 ",W," 模型"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,children:E(c,{children:"从可用模型列表中选择一个"},void 0,!1,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,children:E(EU,{items:q,onSelect:(U)=>Z(U.value),indicatorComponent:TU,itemComponent:CU},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},Xb=({mode:$,config:Z,isSaving:Y,stepNumber:Q,onConfirm:X,onBack:J,onCancel:G})=>{let{isFocused:K}=B6({id:"confirm-step"});return I8((q,W)=>{if(Y)return;if(q==="y"||q==="Y")X();else if(q==="n"||q==="N")J();else if(W.escape)G()},{isActive:K&&!Y}),E(Z$,{flexDirection:"column",marginBottom:1,children:[E(Z$,{marginBottom:1,children:E(c,{bold:!0,color:$==="edit"?"yellow":"blue",children:$==="edit"?"\uD83D\uDCBE 确认修改":`✅ Step ${Q}: 确认配置`},void 0,!1,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,children:E(c,{children:$==="edit"?"请确认修改内容,保存后将立即生效。":"请确认以下配置信息:"},void 0,!1,void 0,this)},void 0,!1,void 0,this),E(Z$,{flexDirection:"column",marginBottom:1,paddingLeft:2,children:[E(Z$,{marginBottom:1,children:[E(c,{dimColor:!0,children:"名称: "},void 0,!1,void 0,this),E(c,{bold:!0,color:"cyan",children:Z.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),E(Z$,{marginBottom:1,children:[E(c,{dimColor:!0,children:"Provider: "},void 0,!1,void 0,this),E(c,{bold:!0,color:"cyan",children:$b(Z.provider)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),E(Z$,{marginBottom:1,children:[E(c,{dimColor:!0,children:"Base URL: "},void 0,!1,void 0,this),E(c,{bold:!0,color:"blue",children:Z.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),E(Z$,{marginBottom:1,children:[E(c,{dimColor:!0,children:"API Key: "},void 0,!1,void 0,this),E(c,{bold:!0,color:"yellow",children:Z.apiKey==="oauth"?"\uD83D\uDD10 OAuth 认证(使用 /login 登录)":E(v3,{children:[Z.apiKey?.slice(0,8),"*".repeat(Math.min(32,(Z.apiKey?.length||0)-8))]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),E(Z$,{children:[E(c,{dimColor:!0,children:"Model: "},void 0,!1,void 0,this),E(c,{bold:!0,color:"cyan",children:Z.model},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),!Y&&E(Z$,{marginTop:1,children:E(c,{children:[$==="edit"?"保存修改? ":"确认保存配置? ","[",E(c,{bold:!0,color:"green",children:"Y"},void 0,!1,void 0,this),"/",E(c,{bold:!0,color:"red",children:"n"},void 0,!1,void 0,this),"]"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Y&&E(Z$,{children:E(c,{color:"yellow",children:"⏳ 正在保存配置到 ~/.blade/config.json..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},JY=({mode:$,initialConfig:Z,modelId:Y,onComplete:Q,onCancel:X})=>{let J=$==="edit",[G,K]=d4("provider"),[q,W]=d4(()=>J&&Z?{...Z}:{}),[U,H]=d4(""),[F,O]=d4(!1),[z,_]=d4(!1),[B,L]=d4(null),w=Q0(!1);I8((y,u)=>{if(u.ctrl&&y==="c"||u.meta&&y==="c")if($==="setup")w();else X()},{isActive:!0});let{focus:N}=tN();PU(()=>{if(G==="provider")N("provider-step");else if(G==="confirm")N("confirm-step");else if(G==="oauthLogin")N("oauth-login-step");else if(G==="oauthModelSelect")N("oauth-model-step")},[G,N]);let D=()=>{if(!U.trim()){L("配置名称不能为空");return}W({...q,name:U}),H(""),L(null),K("confirm")},V=async(y)=>{if(W({...q,provider:y}),I(y)){let i=y==="antigravity"?I0.getInstance():S0.getInstance();try{if(await i.isLoggedIn())K("oauthModelSelect");else K("oauthLogin")}catch{K("oauthLogin")}return}let u=XY(y),s=J?q.baseUrl??Z?.baseUrl??"":u??"";H(s),K("baseUrl")},I=(y)=>{return _6[y].isOAuth},v=()=>{if(!U.trim()){L("Base URL 不能为空");return}try{new URL(U)}catch{L("请输入有效的 URL (例如: https://api.openai.com/v1)");return}if(W({...q,baseUrl:U}),L(null),I(q.provider)){W((u)=>({...u,baseUrl:U,apiKey:"oauth"}));let y=J?q.model??Z?.model??"":"";H(y),K("model")}else{let y=J?q.apiKey??Z?.apiKey??"":"";H(y),K("apiKey")}},b=()=>{if(!U.trim()){L("API Key 不能为空");return}W({...q,apiKey:U});let y=J?q.model??Z?.model??"":"";H(y),L(null),K("model")},C=()=>{if(!U.trim()){L("Model 不能为空");return}W({...q,model:U});let y=J?q.name??Z?.name??"":"";H(y),L(null),K("name")},d=async()=>{let u=q.provider==="antigravity"?I0.getInstance():S0.getInstance();_(!0),L(null);try{await u.login(),K("oauthModelSelect")}catch(s){L(s instanceof Error?s.message:"登录失败")}finally{_(!1)}},e=(y)=>{let u=q.provider,s=XY(u)||"";W({...q,baseUrl:s,apiKey:"oauth",model:y}),H(""),K("name")},k=async()=>{O(!0),L(null);try{let y={name:q.name,provider:q.provider,baseUrl:q.baseUrl,apiKey:q.apiKey,model:q.model};if($==="setup")Q(y);else if($==="add"){let u=await x$().addModel(y);await x$().setCurrentModel(u.id),Q(y)}else{if(!Y)throw Error("未提供模型 ID,无法编辑");await x$().updateModel(Y,y),Q(y)}}catch(y){L(y instanceof Error?y.message:"配置失败"),O(!1)}},T=()=>{switch(L(null),H(""),G){case"provider":X();break;case"baseUrl":K("provider");break;case"apiKey":H(q.baseUrl||""),K("baseUrl");break;case"model":K("apiKey");break;case"oauthLogin":K("provider");break;case"oauthModelSelect":K("provider");break;case"name":if(I(q.provider))K("oauthModelSelect");else H(q.model||""),K("model");break;case"confirm":H(q.name||""),K("name");break}},g=q.provider&&I(q.provider),j=g?4:6,M=(()=>{if(G==="provider")return 1;if(g){if(G==="oauthLogin"||G==="oauthModelSelect")return 2;if(G==="name")return 3;return 4}if(G==="baseUrl")return 2;if(G==="apiKey")return 3;if(G==="model")return 4;if(G==="name")return 5;return 6})(),R=Math.floor((M-1)/(j-1)*40);return E(Z$,{...$==="setup"?{flexDirection:"column",padding:1}:$==="add"?{flexDirection:"column",borderStyle:"round",borderColor:"blue",padding:1}:{flexDirection:"column",borderStyle:"round",borderColor:"yellow",padding:1},children:[$==="setup"?E(v3,{children:[E(Z$,{marginBottom:1,children:E(c,{bold:!0,color:"blue",children:"\uD83D\uDE80 欢迎使用 Blade Code"},void 0,!1,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,children:E(c,{children:"AI 驱动的代码助手 - 让我们开始配置您的助手"},void 0,!1,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,children:[E(c,{bold:!0,color:"blue",children:"█".repeat(R)},void 0,!1,void 0,this),E(c,{dimColor:!0,children:"░".repeat(40-R)},void 0,!1,void 0,this),E(c,{children:" "},void 0,!1,void 0,this),E(c,{bold:!0,color:"cyan",children:[M,"/",j]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),E(Z$,{marginBottom:1,children:E(c,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this):$==="add"?E(v3,{children:[E(Z$,{justifyContent:"center",marginBottom:1,children:E(c,{bold:!0,color:"blue",children:"添加新模型配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,children:E(c,{children:["步骤: ",M,"/",j]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this):E(v3,{children:[E(Z$,{justifyContent:"center",marginBottom:1,children:E(c,{bold:!0,color:"yellow",children:"编辑模型配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginBottom:1,children:E(c,{children:["步骤: ",M,"/",j]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G==="name"&&E(z6,{stepNumber:5,icon:"\uD83D\uDCDD",title:"配置名称",description:"给这个模型配置起一个易于识别的名称(可选,用于区分多个配置)",value:U,placeholder:"例如: 千问工作账号",onChange:H,onSubmit:D,onCancel:X},void 0,!1,void 0,this),G==="provider"&&E(Zb,{onSelect:V,onCancel:X,initialProvider:q.provider},void 0,!1,void 0,this),G==="oauthLogin"&&q.provider&&I(q.provider)&&E(Yb,{provider:q.provider,onLogin:d,onCancel:X,isLoggingIn:z},void 0,!1,void 0,this),G==="oauthModelSelect"&&q.provider&&I(q.provider)&&E(Qb,{provider:q.provider,onSelect:e,onCancel:X},void 0,!1,void 0,this),G==="baseUrl"&&E(z6,{stepNumber:2,icon:"\uD83C\uDF10",title:"配置 Base URL",description:"输入您的 API 端点地址(完整的 URL 包含协议)",hint:q.provider&&XY(q.provider)?"\uD83D\uDCA1 已预填充官方 URL,直接回车使用。如需代理服务(如 OpenRouter),请修改。":void 0,examples:["• OpenAI: https://api.openai.com/v1","• Anthropic: https://api.anthropic.com","• Gemini: https://generativelanguage.googleapis.com/v1beta","• Azure: https://{resource}.openai.azure.com","• 代理: https://openrouter.ai/api/v1"],value:U,placeholder:"https://api.example.com/v1",onChange:H,onSubmit:v,onCancel:X},void 0,!1,void 0,this),G==="apiKey"&&E(z6,{stepNumber:3,icon:"\uD83D\uDD11",title:"输入 API Key",description:"您的 API 密钥将被安全存储在 ~/.blade/config.json (权限 600)",hint:"\uD83D\uDCA1 提示: 输入时字符会被隐藏,支持粘贴 (Ctrl+V / Cmd+V)",previousValue:q.baseUrl?`✓ Base URL: ${q.baseUrl}`:void 0,value:U,placeholder:"sk-...",mask:"*",onChange:H,onSubmit:b,onCancel:X},void 0,!1,void 0,this),G==="model"&&E(z6,{stepNumber:4,icon:"\uD83E\uDD16",title:"选择模型",description:"输入您想使用的模型名称(请参考您的 API 提供商文档)",examples:q.provider==="antigravity"?["• Claude: claude-sonnet-4-5, claude-opus-4-5-thinking","• Gemini: gemini-3-pro-high, gemini-3-pro-low","• GPT-OSS: gpt-oss-120b-medium"]:["• OpenAI: gpt-4o, gpt-4o-mini, o1-preview","• Claude: claude-sonnet-4-20250514, claude-opus-4-20250514","• Gemini: gemini-2.5-pro, gemini-2.5-flash","• Azure: {deployment-name}","• 千问: qwen3-max, qwen3-235b, qwen3-32b","• DeepSeek: deepseek-v3.1, deepseek-r1-0528"],value:U,placeholder:"例如: gpt-5",onChange:H,onSubmit:C,onCancel:X},void 0,!1,void 0,this),G==="confirm"&&E(Xb,{mode:$,config:q,isSaving:F,stepNumber:j,onConfirm:k,onBack:T,onCancel:X},void 0,!1,void 0,this),B&&E(Z$,{marginTop:1,borderStyle:"round",borderColor:"red",paddingX:1,children:E(c,{color:"red",children:["❌ ",B]},void 0,!0,void 0,this)},void 0,!1,void 0,this),E(Z$,{marginTop:1,children:E(c,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this),!F&&!z&&G==="provider"&&E(Z$,{marginTop:1,children:E(c,{dimColor:!0,children:["\uD83D\uDCA1 使用 ",E(c,{bold:!0,children:"↑/↓"},void 0,!1,void 0,this)," 键选择,",E(c,{bold:!0,children:"Enter"},void 0,!1,void 0,this)," 确认,",E(c,{bold:!0,children:"Esc"},void 0,!1,void 0,this)," 取消"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),!F&&!z&&G==="oauthModelSelect"&&E(Z$,{marginTop:1,children:E(c,{dimColor:!0,children:["\uD83D\uDCA1 使用 ",E(c,{bold:!0,children:"↑/↓"},void 0,!1,void 0,this)," 键选择模型,",E(c,{bold:!0,children:"Enter"},void 0,!1,void 0,this)," 确认,",E(c,{bold:!0,children:"Esc"},void 0,!1,void 0,this)," 返回"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),!F&&!z&&G==="oauthLogin"&&E(Z$,{marginTop:1,children:E(c,{dimColor:!0,children:["\uD83D\uDCA1 按"," ",E(c,{bold:!0,color:"green",children:"Y"},void 0,!1,void 0,this)," ","登录,",E(c,{bold:!0,color:"red",children:"N"},void 0,!1,void 0,this)," ","返回,",E(c,{bold:!0,children:"Esc"},void 0,!1,void 0,this)," 取消"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),!F&&!z&&G!=="confirm"&&G!=="provider"&&G!=="oauthLogin"&&G!=="oauthModelSelect"&&E(Z$,{marginTop:1,children:E(c,{dimColor:!0,children:["\uD83D\uDCA1 输入完成后按 ",E(c,{bold:!0,children:"Enter"},void 0,!1,void 0,this),",",E(c,{bold:!0,children:"Ctrl+C"},void 0,!1,void 0,this)," 退出"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),!F&&!z&&G==="confirm"&&E(Z$,{marginTop:1,children:E(c,{dimColor:!0,children:["\uD83D\uDCA1 按"," ",E(c,{bold:!0,color:"green",children:"Y"},void 0,!1,void 0,this)," ","保存,",E(c,{bold:!0,color:"red",children:"N"},void 0,!1,void 0,this)," ","返回修改,",E(c,{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)};u3();import{useMemoizedFn as L6,useMount as Jb}from"ahooks";import{Box as J1,Text as C$,useFocus as Gb,useFocusManager as Kb,useInput as qb}from"ink";import Wb from"ink-select-input";import{memo as Ub,useMemo as Hb,useState as w6}from"react";k$();import{jsxDEV as H$}from"react/jsx-dev-runtime";function Fb($){switch($){case"openai-compatible":return"⚡ OpenAI Compatible";case"anthropic":return"\uD83E\uDD16 Anthropic Claude";case"gemini":return"✨ Google Gemini";case"azure-openai":return"☁️ Azure OpenAI";default:return $}}var Ob=({isSelected:$})=>H$(J1,{marginRight:1,children:H$(C$,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),zb=({isSelected:$,label:Z})=>H$(C$,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),SU=Ub(({onClose:$,onEdit:Z})=>{let Y=$W(),Q=ZW()??"",{isFocused:X}=Gb({id:"model-selector"}),J=Kb(),[G,K]=w6(""),[q,W]=w6(!1),[U,H]=w6(null),F=Q0(!1),[O]=w6(()=>{let I=process.stdout?.columns||80;return Math.max(20,I-8)});Jb(()=>{if(J?.focus("model-selector"),Y.length>0)K(Y[0].id)}),qb((I,v)=>{if(q)return;if(v.ctrl&&I==="c"||v.meta&&I==="c"){F();return}if(v.escape){$();return}if(!X)return;if(I==="d"||I==="D"){_();return}if((I==="e"||I==="E")&&Z)B()},{isActive:!0});let z=L6(async(I)=>{if(q)return;let v=I.value;if(v===Q){$();return}W(!0),H(null);try{await x$().setCurrentModel(v),$()}catch(b){H(b.message),W(!1)}}),_=L6(async()=>{if(q||G===Q)return;W(!0),H(null);try{if(await x$().removeModel(G),Y.length<=1)$()}catch(I){H(I.message)}finally{W(!1)}}),B=L6(()=>{if(q||!Z)return;let I=Y.find((v)=>v.id===G);if(!I)return;Z(I)}),L=L6((I)=>{K(I.value)}),w=Hb(()=>{return Y.find((I)=>I.id===G)},[Y,G]),N=Y.map((I)=>{let v=I.id===Q?" (当前)":"";return{label:I.name+v,value:I.id}}),D=G===Q;return H$(J1,{flexDirection:"column",borderStyle:"round",borderColor:"gray",padding:1,width:"100%",children:[H$(J1,{flexDirection:"row",justifyContent:"space-between",marginBottom:1,children:[H$(C$,{bold:!0,color:"cyan",children:"模型管理"},void 0,!1,void 0,this),H$(C$,{dimColor:!0,children:[q?"⏳ 处理中...":D?"Enter=关闭 • E=编辑 • Esc=取消":"Enter=切换 • D=删除 • E=编辑 • Esc=取消"," • Ctrl+C=退出"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),H$(J1,{flexDirection:"row",children:[H$(J1,{flexDirection:"column",flexGrow:2,marginRight:2,borderStyle:"single",borderColor:"gray",padding:1,children:[H$(C$,{dimColor:!0,children:["已配置模型 (",Y.length,")"]},void 0,!0,void 0,this),H$(J1,{marginTop:1,children:H$(Wb,{items:N,onSelect:z,onHighlight:L,indicatorComponent:Ob,itemComponent:zb},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H$(J1,{flexDirection:"column",flexGrow:3,borderStyle:"single",borderColor:"gray",padding:1,children:[H$(C$,{dimColor:!0,children:"模型详情"},void 0,!1,void 0,this),H$(J1,{marginY:1,children:H$(C$,{color:D?"green":"yellow",children:D?"● 当前使用":"● 可切换"},void 0,!1,void 0,this)},void 0,!1,void 0,this),w?H$(J1,{flexDirection:"column",children:[H$(C$,{children:[H$(C$,{dimColor:!0,children:"名称: "},void 0,!1,void 0,this),H$(C$,{bold:!0,color:"cyan",children:w.name},void 0,!1,void 0,this),N7(w)&&H$(C$,{color:"green",children:" (内置免费)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H$(C$,{children:[H$(C$,{dimColor:!0,children:"Provider: "},void 0,!1,void 0,this),H$(C$,{bold:!0,children:Fb(w.provider)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H$(C$,{children:[H$(C$,{dimColor:!0,children:"Model: "},void 0,!1,void 0,this),H$(C$,{bold:!0,children:w.model},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H$(C$,{children:[H$(C$,{dimColor:!0,children:"Base URL: "},void 0,!1,void 0,this),H$(C$,{color:"blueBright",children:w.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w.temperature!==void 0&&H$(C$,{children:[H$(C$,{dimColor:!0,children:"Temperature: "},void 0,!1,void 0,this),H$(C$,{children:w.temperature},void 0,!1,void 0,this)]},void 0,!0,void 0,this),w.maxContextTokens!==void 0&&H$(C$,{children:[H$(C$,{dimColor:!0,children:"Context Window: "},void 0,!1,void 0,this),H$(C$,{children:w.maxContextTokens},void 0,!1,void 0,this)]},void 0,!0,void 0,this),N7(w)&&H$(J1,{marginTop:1,children:H$(C$,{color:"green",dimColor:!0,children:"\uD83D\uDCA1 此模型由 Blade 提供免费额度"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this):H$(C$,{dimColor:!0,children:"请选择一个模型查看详情"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),U&&H$(J1,{marginTop:1,children:H$(C$,{color:"red",children:["❌ ",U]},void 0,!0,void 0,this)},void 0,!1,void 0,this),H$(J1,{justifyContent:"center",marginTop:1,children:H$(C$,{dimColor:!0,children:"─".repeat(O)},void 0,!1,void 0,this)},void 0,!1,void 0,this),H$(J1,{justifyContent:"center",children:H$(C$,{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 E3}from"ahooks";import{promises as xU}from"fs";import{Box as G1,Text as Z0,useInput as _b}from"ink";import kU from"ink-select-input";import Bb from"ink-text-input";import Lb from"os";import N6 from"path";import{useEffect as wb,useMemo as b6,useRef as Nb,useState as u4}from"react";k$();import{jsxDEV as B$}from"react/jsx-dev-runtime";var P3=[{key:"allow",label:"Allow"},{key:"ask",label:"Ask"},{key:"deny",label:"Deny"},{key:"info",label:"Info"}],bb={allow:"Add a new rule...",ask:"Add a new rule...",deny:"Add a new rule..."},Ab={allow:"Allow permission rules",ask:"Ask permission rules",deny:"Deny permission rules"},fU={project:"[项目共享配置]",global:"[用户全局配置]",local:"[本地配置]"},Rb=["project","global","local"],Vb={allow:[],ask:[],deny:[]},Db={localExists:!1,projectExists:!1,globalExists:!1},hU={allow:[],ask:[],deny:[]};function Mb($){let Z=(Q)=>Array.isArray(Q)?Q.filter((X)=>typeof X==="string"):[],Y=$?.permissions??{};return{allow:Z(Y?.allow),ask:Z(Y?.ask),deny:Z(Y?.deny)}}async function jb($){try{let Z=await xU.readFile($,"utf-8"),Y=JSON.parse(Z);return{exists:!0,raw:Y,permissions:Mb(Y)}}catch(Z){if(Z.code==="ENOENT")return{exists:!1,raw:{},permissions:{...hU}};return console.warn(`[PermissionsManager] Failed to read ${$}:`,Z),{exists:!0,raw:{},permissions:{...hU}}}}function Ib($,Z){let Y=$.padEnd(32," "),Q=Z==="local"?`${fU[Z]} ← 可删除`:fU[Z];return`${Y} ${Q}`}var pU=({onClose:$})=>{let Y=Z1()==="permissions-manager",Q=Q0(!1),[X,J]=u4(0),G=P3[X].key,[K,q]=u4(Vb),[W,U]=u4(Db),[H,F]=u4(!0),[O,z]=u4("list"),[_,B]=u4(""),[L,w]=u4(null),[N,D]=u4(null),V=Nb(!1),I=b6(()=>N6.join(process.cwd(),".blade","settings.local.json"),[]),v=b6(()=>N6.join(process.cwd(),".blade","settings.json"),[]),b=b6(()=>N6.join(Lb.homedir(),".blade","settings.json"),[]),C=E3(async()=>{F(!0);let i=[{source:"local",path:I},{source:"project",path:v},{source:"global",path:b}],Y$=await Promise.all(i.map(async({source:N$,path:X0})=>{let G0=await jb(X0);return{source:N$,path:X0,...G0}})),f={localExists:Y$.find((N$)=>N$.source==="local")?.exists??!1,projectExists:Y$.find((N$)=>N$.source==="project")?.exists??!1,globalExists:Y$.find((N$)=>N$.source==="global")?.exists??!1};U(f);let w$={allow:[],ask:[],deny:[]},G$=Object.fromEntries(Y$.map((N$)=>[N$.source,N$]));["allow","ask","deny"].forEach((N$)=>{Rb.forEach((X0)=>{(G$[X0]?.permissions[N$]??[]).forEach((_4,T0)=>{let K$={key:`${X0}:${T0}:${_4}`,rule:_4,source:X0};w$[N$].push(K$)})})}),q(w$),F(!1)});wb(()=>{C()},[C]);let d=E3(async(i,Y$)=>{try{let f=N6.join(process.cwd(),".blade","settings.local.json"),w$={allow:[],ask:[],deny:[]};try{let N$=await xU.readFile(f,"utf-8"),G0=JSON.parse(N$).permissions||{};w$={allow:Array.isArray(G0.allow)?G0.allow:[],ask:Array.isArray(G0.ask)?G0.ask:[],deny:Array.isArray(G0.deny)?G0.deny:[]}}catch(N$){}let G$=Y$(w$);await x$().updateConfig({permissions:G$},{scope:"local",immediate:!0}),await C()}catch(f){throw console.error("[PermissionsManager] 修改权限规则失败:",f),f}});_b((i,Y$)=>{if(Y$.ctrl&&i==="c"||Y$.meta&&i==="c"){Q();return}if(O==="locked"){if(V.current){V.current=!1;return}z("list"),w(null),D(null);return}if(Y$.escape){if(O==="list"||G==="info")$();else z("list"),B(""),w(null),D(null);return}if(O==="list"){if(Y$.tab&&Y$.shift)J((f)=>(f-1+P3.length)%P3.length);else if(Y$.tab)J((f)=>(f+1)%P3.length);else if(i?.toLowerCase()==="q")$()}},{isActive:Y});let e=E3((i)=>{let Y$=i.value;if(G==="info")return;if(Y$.type==="add"){z("add"),B(""),D(null);return}if(Y$.entry.source!=="local"){z("locked"),V.current=!0,w({tab:G,entry:Y$.entry}),D({type:"error",text:Y$.entry.source==="project"?"此规则定义在项目共享配置中,无法在此删除。":"此规则来自用户全局配置,无法在此删除。"});return}z("confirm-delete"),w({tab:G,entry:Y$.entry}),D(null)}),k=E3(async()=>{if(G==="info")return;let i=_.trim();if(!i){D({type:"error",text:"Permission rule 不能为空"});return}if(K[G].map((f)=>f.rule).includes(i)){D({type:"error",text:"该规则已存在"});return}try{await d(G,(f)=>{let w$={allow:[...f.allow],ask:[...f.ask],deny:[...f.deny]};return w$[G]=[...new Set([...f[G],i])],w$}),z("list"),B(""),D({type:"success",text:"已添加本地权限规则"})}catch(f){D({type:"error",text:`保存失败: ${f instanceof Error?f.message:"未知错误"}`})}}),T=E3(async()=>{if(!L)return;let{tab:i,entry:Y$}=L;try{await d(i,(f)=>{let w$={allow:[...f.allow],ask:[...f.ask],deny:[...f.deny]};return w$[i]=f[i].filter((G$)=>G$!==Y$.rule),w$}),z("list"),w(null),D({type:"success",text:"已删除本地权限规则"})}catch(f){D({type:"error",text:`删除失败: ${f instanceof Error?f.message:"未知错误"}`})}}),g=b6(()=>{if(G==="info")return[];let i=G;return[{key:"add-new-rule",label:`› ${bb[i]}`,value:{type:"add"}},...K[i].map((f)=>({key:f.key,label:Ib(f.rule,f.source),value:{type:"rule",entry:f}}))]},[G,K]),j=()=>B$(G1,{marginBottom:1,children:P3.map((i,Y$)=>B$(G1,{marginRight:2,children:B$(Z0,{color:Y$===X?"yellow":"gray",children:["[",i.label,"]"]},void 0,!0,void 0,this)},i.key,!1,void 0,this))},void 0,!1,void 0,this),M=()=>B$(G1,{flexDirection:"column",gap:1,children:[B$(Z0,{children:"配置文件优先级(从高到低):"},void 0,!1,void 0,this),B$(G1,{flexDirection:"column",marginLeft:2,children:[B$(Z0,{children:["1. .blade/settings.local.json (本地配置,不提交 Git)"," ",W.localExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),B$(Z0,{children:["2. .blade/settings.json (项目配置,提交 Git)"," ",W.projectExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),B$(Z0,{children:["3. ~/.blade/settings.json (用户全局配置)"," ",W.globalExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),B$(Z0,{children:"说明:"},void 0,!1,void 0,this),B$(G1,{flexDirection:"column",marginLeft:2,children:[B$(Z0,{children:"- /permissions 命令只管理本地配置 (.blade/settings.local.json)"},void 0,!1,void 0,this),B$(Z0,{children:"- 修改全局或项目配置请直接编辑对应文件"},void 0,!1,void 0,this),B$(Z0,{children:"- 本地配置不会提交到 Git"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),R=(i)=>B$(G1,{flexDirection:"column",gap:1,children:[B$(Z0,{bold:!0,children:Ab[i]},void 0,!1,void 0,this),B$(Z0,{children:"Permission rules are a tool name, optionally followed by a specifier in parentheses."},void 0,!1,void 0,this),B$(Z0,{color:"gray",children:"例如: WebFetch 或 Bash(ls:*)"},void 0,!1,void 0,this),B$(G1,{marginTop:1,children:B$(Bb,{value:_,onChange:B,onSubmit:k},void 0,!1,void 0,this)},void 0,!1,void 0,this),B$(Z0,{color:"gray",children:"Enter 提交 · Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),n=(i,Y$)=>B$(G1,{flexDirection:"column",gap:1,children:[B$(Z0,{bold:!0,children:["Delete ",i," permission rule?"]},void 0,!0,void 0,this),B$(Z0,{children:Y$.rule},void 0,!1,void 0,this),B$(Z0,{color:"gray",children:"From project local settings"},void 0,!1,void 0,this),B$(Z0,{children:"Are you sure you want to delete this permission rule?"},void 0,!1,void 0,this),B$(kU,{items:[{label:"Yes",value:"yes"},{label:"No",value:"no"}],onSelect:(f)=>{if(f.value==="yes")T();else z("list"),w(null)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),y=(i)=>B$(G1,{flexDirection:"column",gap:1,children:[B$(Z0,{bold:!0,children:"Cannot delete this rule"},void 0,!1,void 0,this),B$(Z0,{children:i.rule},void 0,!1,void 0,this),B$(Z0,{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),B$(Z0,{color:"gray",children:"按任意键继续"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),u=(i)=>B$(kU,{items:g,isFocused:O==="list",onSelect:e},void 0,!1,void 0,this),s=()=>{if(H)return B$(Z0,{children:"加载中..."},void 0,!1,void 0,this);if(G==="info")return M();if(O==="add")return R(G);if(O==="confirm-delete"&&L)return n(L.tab,L.entry);if(O==="locked"&&L)return y(L.entry);return u(G)};return B$(G1,{flexDirection:"column",borderStyle:"round",borderColor:Y?"cyan":"gray",padding:1,width:80,children:[B$(Z0,{color:"cyan",bold:!0,children:"⚙️ 权限管理器"},void 0,!1,void 0,this),j(),B$(G1,{flexDirection:"column",gap:1,children:s()},void 0,!1,void 0,this),N&&B$(G1,{marginTop:1,children:B$(Z0,{color:N.type==="success"?"green":"red",children:N.text},void 0,!1,void 0,this)},void 0,!1,void 0,this),B$(G1,{marginTop:1,children:B$(Z0,{color:"gray",children:"Tab 切换视图 · Esc 关闭 · Q 退出"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};q8();import{Box as t$,Text as A$,useInput as yb}from"ink";import{jsxDEV as r}from"react/jsx-dev-runtime";function mU({onCancel:$}){let Z=a0(),Y=Z.getAll(),Q=Z.getBySource(),X=Z.getStats(),J=Q0(!1,$);if(yb((G,K)=>{if(K.escape)$?.();else if(K.ctrl&&G==="c"||K.meta&&G==="c")J()}),Y.length===0)return r(t$,{flexDirection:"column",paddingY:1,children:[r(t$,{marginBottom:1,children:r(A$,{bold:!0,color:"cyan",children:"\uD83D\uDD0C 插件管理器"},void 0,!1,void 0,this)},void 0,!1,void 0,this),r(t$,{paddingLeft:2,children:r(A$,{color:"gray",children:"没有已加载的插件"},void 0,!1,void 0,this)},void 0,!1,void 0,this),r(t$,{marginTop:1,paddingLeft:2,flexDirection:"column",children:[r(A$,{color:"gray",children:"插件目录位置:"},void 0,!1,void 0,this),r(A$,{color:"gray",dimColor:!0,children:[" ","• ~/.blade/plugins/ - 用户级插件"]},void 0,!0,void 0,this),r(A$,{color:"gray",dimColor:!0,children:[" ","• .blade/plugins/ - 项目级插件"]},void 0,!0,void 0,this),r(A$,{color:"gray",dimColor:!0,children:[" ","• --plugin-dir - CLI 指定的插件"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),r(t$,{marginTop:1,paddingLeft:2,children:r(A$,{color:"gray",children:"使用 /plugins install <url> 安装新插件"},void 0,!1,void 0,this)},void 0,!1,void 0,this),r(t$,{marginTop:1,children:r(A$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return r(t$,{flexDirection:"column",paddingY:1,children:[r(t$,{marginBottom:1,children:[r(A$,{bold:!0,color:"cyan",children:"\uD83D\uDD0C 插件管理器"},void 0,!1,void 0,this),r(A$,{color:"gray",children:[" (共 ",X.total," 个插件)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),r(t$,{paddingLeft:2,marginBottom:1,children:r(A$,{color:"gray",children:["启用: ",X.active," | 禁用: ",X.inactive," | 命令: ",X.commands," | 技能:"," ",X.skills," | 代理: ",X.agents]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q.cli.length>0&&r(t$,{flexDirection:"column",marginBottom:1,children:[r(t$,{paddingLeft:1,children:[r(A$,{bold:!0,color:"magenta",children:"CLI 指定"},void 0,!1,void 0,this),r(A$,{color:"gray",children:" (--plugin-dir)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.cli.map((G)=>{let K=G.status==="active"?"✅":"⏸️";return r(t$,{flexDirection:"column",paddingLeft:2,children:[r(A$,{children:[r(A$,{bold:!0,color:"green",children:[K," ",G.manifest.name]},void 0,!0,void 0,this),r(A$,{color:"gray",children:[" v",G.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),r(t$,{paddingLeft:2,children:r(A$,{color:"gray",children:G.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),G.commands.length>0&&r(t$,{paddingLeft:2,children:r(A$,{color:"blue",children:["命令:"," ",G.commands.map((q)=>`/${q.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},G.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.project.length>0&&r(t$,{flexDirection:"column",marginBottom:1,children:[r(t$,{paddingLeft:1,children:[r(A$,{bold:!0,color:"yellow",children:"项目级"},void 0,!1,void 0,this),r(A$,{color:"gray",children:" (.blade/plugins/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.project.map((G)=>{let K=G.status==="active"?"✅":"⏸️";return r(t$,{flexDirection:"column",paddingLeft:2,children:[r(A$,{children:[r(A$,{bold:!0,color:"green",children:[K," ",G.manifest.name]},void 0,!0,void 0,this),r(A$,{color:"gray",children:[" v",G.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),r(t$,{paddingLeft:2,children:r(A$,{color:"gray",children:G.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),G.commands.length>0&&r(t$,{paddingLeft:2,children:r(A$,{color:"blue",children:["命令:"," ",G.commands.map((q)=>`/${q.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},G.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.user.length>0&&r(t$,{flexDirection:"column",marginBottom:1,children:[r(t$,{paddingLeft:1,children:[r(A$,{bold:!0,color:"cyan",children:"用户级"},void 0,!1,void 0,this),r(A$,{color:"gray",children:" (~/.blade/plugins/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.user.map((G)=>{let K=G.status==="active"?"✅":"⏸️";return r(t$,{flexDirection:"column",paddingLeft:2,children:[r(A$,{children:[r(A$,{bold:!0,color:"green",children:[K," ",G.manifest.name]},void 0,!0,void 0,this),r(A$,{color:"gray",children:[" v",G.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),r(t$,{paddingLeft:2,children:r(A$,{color:"gray",children:G.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),G.commands.length>0&&r(t$,{paddingLeft:2,children:r(A$,{color:"blue",children:["命令:"," ",G.commands.map((q)=>`/${q.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},G.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),r(t$,{marginTop:1,paddingLeft:2,flexDirection:"column",children:[r(A$,{color:"gray",children:"可用命令:"},void 0,!1,void 0,this),r(A$,{color:"gray",dimColor:!0,children:[" ","• /plugins list - 列出所有插件"]},void 0,!0,void 0,this),r(A$,{color:"gray",dimColor:!0,children:[" ","• /plugins info <name> - 显示插件详情"]},void 0,!0,void 0,this),r(A$,{color:"gray",dimColor:!0,children:[" ","• /plugins install <url> - 安装插件"]},void 0,!0,void 0,this),r(A$,{color:"gray",dimColor:!0,children:[" ","• /plugins enable/disable <name> - 启用/禁用插件"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),r(t$,{marginTop:1,children:r(A$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}import{Box as h0,Text as x0,useInput as dU,useStdout as vb}from"ink";import Eb from"ink-text-input";import GY,{useCallback as T3,useMemo as Pb,useState as g4}from"react";import{jsxDEV as D$}from"react/jsx-dev-runtime";var Tb=GY.memo(({option:$,index:Z,isSelected:Y,isMultiSelect:Q,isHighlighted:X})=>D$(h0,{flexDirection:"column",marginBottom:1,children:[D$(x0,{color:X?"yellow":Y?"green":void 0,bold:X,children:[Q?Y?"● ":"○ ":X?"❯ ":" ",Z+1,". ",$.label]},void 0,!0,void 0,this),D$(h0,{marginLeft:4,children:D$(x0,{color:"gray",children:$.description},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)),Cb=GY.memo(({questions:$,answers:Z})=>D$(h0,{flexDirection:"column",marginBottom:1,children:$.map((Y)=>{let Q=Z[Y.header],X=Array.isArray(Q)?Q.join(", "):Q||"(no answer)";return D$(h0,{marginBottom:1,children:[D$(x0,{backgroundColor:"blue",color:"white",children:[" ",Y.header," "]},void 0,!0,void 0,this),D$(x0,{color:"green",children:[" ",X]},void 0,!0,void 0,this)]},Y.header,!0,void 0,this)})},void 0,!1,void 0,this)),uU=GY.memo(({questions:$,onComplete:Z,onCancel:Y})=>{let{stdout:Q}=vb(),X=Q.columns||80,G=Z1()==="confirmation-prompt",K=Q0(!1),[q,W]=g4("answering"),[U,H]=g4(0),[F,O]=g4({}),[z,_]=g4(0),[B,L]=g4([]),[w,N]=g4(!1),[D,V]=g4(""),[I,v]=g4(0),b=$[U],C=Pb(()=>{if(!b)return[];return[...b.options.map((j)=>({label:j.label,value:j.label,description:j.description})),{label:"Type something...",value:"__other__",description:"Enter custom response"}]},[b]),d=T3((j)=>{let M={...F,[b.header]:j};if(O(M),U<$.length-1)H(U+1),_(0),L([]),N(!1),V("");else W("submit"),v(0)},[F,b?.header,U,$.length]),e=T3((j)=>{let M=C[j];if(!M)return;if(M.value==="__other__"){N(!0);return}if(b.multiSelect)L((R)=>R.includes(M.value)?R.filter((n)=>n!==M.value):[...R,M.value]);else d(M.value)},[C,b?.multiSelect,d]),k=T3((j)=>{if(j.trim())d(j.trim())},[d]),T=T3(()=>{W("answering"),H(0),_(0),L([]),N(!1)},[]),g=T3(()=>{Z(F)},[F,Z]);if(dU((j,M)=>{if(M.ctrl&&j==="c"||M.meta&&j==="c"){K();return}if(w){if(M.escape)N(!1),V("");return}if(M.escape){Y();return}let R=parseInt(j);if(R>=1&&R<=C.length){e(R-1);return}if(M.upArrow){_((n)=>n>0?n-1:C.length-1);return}if(M.downArrow||M.tab){_((n)=>n<C.length-1?n+1:0);return}if(M.return){if(b.multiSelect&&B.length>0)d(B);else e(z);return}if(j===" "&&b.multiSelect){let n=C[z];if(n&&n.value!=="__other__")L((y)=>y.includes(n.value)?y.filter((u)=>u!==n.value):[...y,n.value]);return}},{isActive:G&&q==="answering"&&!w}),dU((j,M)=>{if(M.ctrl&&j==="c"||M.meta&&j==="c"){K();return}if(M.escape){Y();return}if(M.upArrow||M.downArrow||M.tab){v((R)=>R===0?1:0);return}if(M.return){if(I===0)g();else T();return}if(j.toLowerCase()==="y"){g();return}if(j.toLowerCase()==="e"){T();return}},{isActive:G&&q==="submit"}),q==="submit")return D$(h0,{flexDirection:"column",borderStyle:"round",borderColor:G?"green":"gray",padding:1,width:Math.min(X-4,80),children:[D$(h0,{marginBottom:1,children:D$(x0,{bold:!0,color:"green",children:"✓ Review Your Answers"},void 0,!1,void 0,this)},void 0,!1,void 0,this),D$(Cb,{questions:$,answers:F},void 0,!1,void 0,this),D$(h0,{flexDirection:"column",marginTop:1,children:[D$(x0,{color:I===0?"yellow":void 0,bold:I===0,children:[I===0?"❯ ":" ","[Y] Submit answers"]},void 0,!0,void 0,this),D$(x0,{color:I===1?"yellow":void 0,bold:I===1,children:[I===1?"❯ ":" ","[E] Edit answers"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),D$(h0,{marginTop:1,children:D$(x0,{color:"gray",children:"Enter to confirm · ↑↓ to navigate · Y/E for quick select"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(!b)return null;return D$(h0,{flexDirection:"column",borderStyle:"round",borderColor:G?"cyan":"gray",padding:1,width:Math.min(X-4,80),children:[D$(h0,{marginBottom:1,children:[D$(x0,{backgroundColor:"blue",color:"white",children:[" ",b.header," "]},void 0,!0,void 0,this),D$(x0,{children:[" ",b.question]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),w?D$(h0,{flexDirection:"column",marginTop:1,children:[D$(x0,{color:"yellow",children:"Enter your response:"},void 0,!1,void 0,this),D$(h0,{marginTop:1,children:[D$(x0,{color:"cyan",children:"❯ "},void 0,!1,void 0,this),D$(Eb,{value:D,onChange:V,onSubmit:k,focus:G},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D$(h0,{marginTop:1,children:D$(x0,{color:"gray",children:"(Press Enter to submit, ESC to go back)"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this):D$(h0,{flexDirection:"column",children:C.map((j,M)=>D$(Tb,{option:j,index:M,isSelected:B.includes(j.value),isMultiSelect:b.multiSelect,isHighlighted:z===M},j.value,!1,void 0,this))},void 0,!1,void 0,this),!w&&D$(h0,{marginTop:1,flexDirection:"column",children:[D$(x0,{color:"gray",children:b.multiSelect?"Space to toggle · Enter to confirm · 1-9 for quick select":"Enter to select · ↑↓ or Tab to navigate · 1-9 for quick select"},void 0,!1,void 0,this),b.multiSelect&&B.length>0&&D$(x0,{color:"green",children:["Selected: ",B.join(", ")]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$.length>1&&D$(h0,{marginTop:1,children:D$(x0,{color:"gray",children:["Question ",U+1," of ",$.length]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});m9();import{Box as y8,Text as f1,useInput as Sb}from"ink";import kb from"ink-select-input";import{basename as fb}from"node:path";import{useEffect as gU,useMemo as A6,useState as KY}from"react";import{jsxDEV as y0}from"react/jsx-dev-runtime";function hb($){let Z=new Date($),Q=new Date().getTime()-Z.getTime(),X=Math.floor(Q/86400000);if(X===0)return`今天 ${Z.getHours().toString().padStart(2,"0")}:${Z.getMinutes().toString().padStart(2,"0")}`;if(X===1)return"昨天";if(X<7)return`${X}天前`;return`${Z.getMonth()+1}/${Z.getDate()}`}function xb($){return fb($)}var pb=({isSelected:$})=>y0(y8,{marginRight:1,children:y0(f1,{color:$?"cyan":"gray",children:$?"❯":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),mb=({isSelected:$,label:Z})=>y0(f1,{color:$?"cyan":"white",bold:$,children:Z},void 0,!1,void 0,this),C3=20,cU=({sessions:$,onSelect:Z,onCancel:Y})=>{let[Q,X]=KY([]),[J,G]=KY(!1),[K,q]=KY(0),U=Z1()==="session-selector",H=Q0(!1);Sb((w,N)=>{if(N.ctrl&&w==="c"||N.meta&&w==="c"){H();return}if(N.escape&&Y){Y();return}if(N.leftArrow||w==="h"||w==="H"){if(K>0)q((D)=>D-1);return}if(N.rightArrow||w==="l"||w==="L"){if(K<z-1)q((D)=>D+1);return}},{isActive:U}),gU(()=>{if($){X($);return}(async()=>{G(!0);try{let N=await _1.listSessions();X(N)}catch(N){console.error("[SessionSelector] Failed to load sessions:",N),X([])}finally{G(!1)}})()},[$]);let F=$||Q,O=A6(()=>{return F.map((w)=>{let N=xb(w.projectPath),D=hb(w.lastMessageTime),V=w.gitBranch?` (${w.gitBranch})`:"",I=w.hasErrors?" ⚠️":"";return{label:`\uD83D\uDCC5 ${D} | ${N}${V} | ${w.messageCount} 条消息${I}`,value:w.sessionId}})},[F]),z=A6(()=>Math.max(1,Math.ceil(O.length/C3)),[O.length]),_=A6(()=>{let w=K*C3;return O.slice(w,w+C3)},[O,K]),B=A6(()=>({start:K*C3+1,end:Math.min((K+1)*C3,O.length)}),[K,O.length]);gU(()=>{q(0)},[F.length]);let L=(w)=>{Z(w.value)};if(J)return y0(y8,{flexDirection:"column",paddingX:2,paddingY:1,children:y0(f1,{children:"⏳ 正在加载会话列表..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(F.length===0)return y0(y8,{flexDirection:"column",paddingX:2,paddingY:1,children:[y0(f1,{color:"yellow",children:"⚠️ 没有找到历史会话"},void 0,!1,void 0,this),y0(f1,{dimColor:!0,children:[`
2851
+ `,"提示: 开始一次对话后,会话历史将保存到 ~/.blade/projects/"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this);return y0(y8,{flexDirection:"column",paddingX:2,paddingY:1,children:[y0(f1,{bold:!0,color:"cyan",children:"\uD83D\uDCC2 选择要恢复的会话:"},void 0,!1,void 0,this),y0(f1,{dimColor:!0,children:[`
2852
2852
  `,"(←→ 翻页 | ↑↓ 选择 | Enter 确认 | Esc 取消)",`
2853
- `]},void 0,!0,void 0,this),y0(kb,{items:_,onSelect:L,indicatorComponent:pb,itemComponent:mb},void 0,!1,void 0,this),y0(y3,{marginTop:1,flexDirection:"column",children:[y0(f1,{dimColor:!0,children:["第 ",K+1,"/",z," 页 · 共 ",F.length," 个会话 · 显示"," ",B.start,"-",B.end]},void 0,!0,void 0,this),z>1&&y0(y3,{marginTop:1,children:[y0(f1,{color:K>0?"cyan":"gray",children:K>0?"◀ ← 上一页":" "},void 0,!1,void 0,this),y0(f1,{children:" "},void 0,!1,void 0,this),y0(f1,{color:K<z-1?"cyan":"gray",children:K<z-1?"下一页 → ▶":""},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};Y2();import{Box as q0,Text as i$,useInput as db}from"ink";import{jsxDEV as J$}from"react/jsx-dev-runtime";function lU({onCancel:$}){let Y=R0().getAll(),Q=Y.filter((K)=>K.source==="builtin"),X=Y.filter((K)=>K.source==="user"),J=Y.filter((K)=>K.source==="project"),G=Q0(!1,$);if(db((K,q)=>{if(q.escape)$?.();else if(q.ctrl&&K==="c"||q.meta&&K==="c")G()}),Y.length===0)return J$(q0,{flexDirection:"column",paddingY:1,children:[J$(q0,{marginBottom:1,children:J$(i$,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this)},void 0,!1,void 0,this),J$(q0,{paddingLeft:2,children:J$(i$,{color:"gray",children:"没有找到任何 Skill"},void 0,!1,void 0,this)},void 0,!1,void 0,this),J$(q0,{marginTop:1,paddingLeft:2,children:J$(i$,{color:"gray",children:"配置文件位置: ~/.blade/skills/ 或 .blade/skills/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),J$(q0,{marginTop:1,children:J$(i$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return J$(q0,{flexDirection:"column",paddingY:1,children:[J$(q0,{marginBottom:1,children:[J$(i$,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this),J$(i$,{color:"gray",children:[" (找到 ",Y.length," 个)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),J.length>0&&J$(q0,{flexDirection:"column",marginBottom:1,children:[J$(q0,{paddingLeft:1,children:[J$(i$,{bold:!0,color:"yellow",children:"项目级"},void 0,!1,void 0,this),J$(i$,{color:"gray",children:" (.blade/skills/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J.map((K)=>{let W=K.description.length>80?`${K.description.substring(0,80)}...`:K.description;return J$(q0,{flexDirection:"column",paddingLeft:2,children:[J$(i$,{children:[J$(i$,{bold:!0,color:"green",children:["• ",K.name]},void 0,!0,void 0,this),J$(i$,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),K.allowedTools&&K.allowedTools.length>0&&J$(q0,{paddingLeft:2,children:J$(i$,{color:"gray",children:["工具: ",K.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),J$(q0,{paddingLeft:2,children:J$(i$,{color:"gray",dimColor:!0,children:K.path},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},K.name,!0,void 0,this)})]},void 0,!0,void 0,this),X.length>0&&J$(q0,{flexDirection:"column",marginBottom:1,children:[J$(q0,{paddingLeft:1,children:[J$(i$,{bold:!0,color:"yellow",children:"用户级"},void 0,!1,void 0,this),J$(i$,{color:"gray",children:" (~/.blade/skills/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X.map((K)=>{let W=K.description.length>80?`${K.description.substring(0,80)}...`:K.description;return J$(q0,{flexDirection:"column",paddingLeft:2,children:[J$(i$,{children:[J$(i$,{bold:!0,color:"green",children:["• ",K.name]},void 0,!0,void 0,this),J$(i$,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),K.allowedTools&&K.allowedTools.length>0&&J$(q0,{paddingLeft:2,children:J$(i$,{color:"gray",children:["工具: ",K.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),J$(q0,{paddingLeft:2,children:J$(i$,{color:"gray",dimColor:!0,children:K.path},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},K.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.length>0&&J$(q0,{flexDirection:"column",marginBottom:1,children:[J$(q0,{paddingLeft:1,children:[J$(i$,{bold:!0,color:"cyan",children:"内置"},void 0,!1,void 0,this),J$(i$,{color:"gray",children:" (builtin)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.map((K)=>{let W=K.description.length>80?`${K.description.substring(0,80)}...`:K.description;return J$(q0,{flexDirection:"column",paddingLeft:2,children:[J$(i$,{children:[J$(i$,{bold:!0,color:"green",children:["• ",K.name]},void 0,!0,void 0,this),J$(i$,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),K.userInvocable&&J$(q0,{paddingLeft:2,children:J$(i$,{color:"blue",children:["命令: /",K.name]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},K.name,!0,void 0,this)})]},void 0,!0,void 0,this),J$(q0,{marginTop:1,children:J$(i$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}O1();D1();import{Box as c2,Text as K1}from"ink";import iU,{useEffect as ub,useState as gb}from"react";import{jsxDEV as W0}from"react/jsx-dev-runtime";var cb={init:"\uD83D\uDCDD",requirements:"\uD83D\uDCCB",design:"\uD83C\uDFA8",tasks:"\uD83D\uDCCC",implementation:"\uD83D\uDD27",done:"✅"},R6=["init","requirements","design","tasks","implementation","done"],lb={pending:"○",in_progress:"◐",completed:"●",blocked:"✕"},ib={pending:"gray",in_progress:"yellow",completed:"green",blocked:"red"},aU=iU.memo(({expanded:$=!1,maxTasks:Z=5})=>{let[Y,Q]=gb(null);if(ub(()=>{let G=m$.getInstance();Q(G.getCurrentSpec());let K=setInterval(()=>{Q(G.getCurrentSpec())},1000);return()=>clearInterval(K)},[]),!Y)return null;let X=R6.indexOf(Y.phase),J=Y.tasks.length>0?Math.round(Y.tasks.filter((G)=>G.status==="completed").length/Y.tasks.length*100):0;return W0(c2,{flexDirection:"column",borderStyle:"round",borderColor:"blue",paddingX:1,marginBottom:1,children:[W0(c2,{flexDirection:"row",justifyContent:"space-between",children:[W0(K1,{color:"blue",bold:!0,children:["\uD83D\uDCCB Spec: ",Y.name]},void 0,!0,void 0,this),W0(K1,{color:"gray",children:[cb[Y.phase]," ",v0[Y.phase]]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),W0(c2,{flexDirection:"row",marginTop:1,children:[R6.map((G,K)=>{let q=K<X,W=K===X;return W0(c2,{flexDirection:"row",children:[W0(K1,{color:q?"green":W?"blue":"gray",children:q?"●":W?"◉":"○"},void 0,!1,void 0,this),K<R6.length-1&&W0(K1,{color:q?"green":"gray",children:"──"},void 0,!1,void 0,this)]},G,!0,void 0,this)}),W0(K1,{color:"gray",children:[" (",J,"%)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),W0(c2,{flexDirection:"row",marginTop:0,children:W0(K1,{color:"gray",dimColor:!0,children:R6.map((G,K)=>{let q=G.slice(0,3).toUpperCase();return K===X?`[${q}]`:` ${q} `}).join("")},void 0,!1,void 0,this)},void 0,!1,void 0,this),$&&Y.tasks.length>0&&W0(c2,{flexDirection:"column",marginTop:1,children:[W0(K1,{color:"gray",dimColor:!0,children:["─── Tasks (",Y.tasks.filter((G)=>G.status==="completed").length,"/",Y.tasks.length,") ───"]},void 0,!0,void 0,this),Y.tasks.slice(0,Z).map((G)=>W0(ab,{task:G,isCurrent:G.id===Y.currentTaskId},G.id,!1,void 0,this)),Y.tasks.length>Z&&W0(K1,{color:"gray",dimColor:!0,children:["... and ",Y.tasks.length-Z," more tasks"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),!$&&Y.currentTaskId&&W0(c2,{flexDirection:"row",marginTop:1,children:[W0(K1,{color:"gray",children:"Current: "},void 0,!1,void 0,this),W0(K1,{color:"yellow",children:Y.tasks.find((G)=>G.id===Y.currentTaskId)?.title||"Unknown"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}),ab=iU.memo(({task:$,isCurrent:Z})=>{let Y=lb[$.status]||"?",Q=ib[$.status]||"gray";return W0(c2,{flexDirection:"row",children:[W0(K1,{color:Q,children:[Y," "]},void 0,!0,void 0,this),W0(K1,{color:Z?"yellow":"white",bold:Z,children:$.title},void 0,!1,void 0,this),$.complexity&&W0(K1,{color:"gray",dimColor:!0,children:[" ","[",$.complexity,"]"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});import{useMemoizedFn as rb}from"ahooks";import{Box as r1,Text as a,useInput as nb}from"ink";import ob from"ink-select-input";import{useState as rU}from"react";k$();S6();r2();import{jsxDEV as m}from"react/jsx-dev-runtime";var nU=t1.map(($)=>({label:$.label,value:$.id})),sb=({theme:$})=>{let{colors:Z}=$;return m(r1,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[m(a,{bold:!0,color:Z.text.primary,children:"代码预览"},void 0,!1,void 0,this),m(a,{children:" "},void 0,!1,void 0,this),m(a,{color:Z.syntax.comment,children:"# function"},void 0,!1,void 0,this),m(a,{children:[m(a,{color:Z.syntax.keyword,children:"def"},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.function,children:"fibonacci"},void 0,!1,void 0,this),m(a,{color:Z.text.primary,children:"("},void 0,!1,void 0,this),m(a,{color:Z.syntax.variable,children:"n"},void 0,!1,void 0,this),m(a,{color:Z.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(a,{children:[" ",m(a,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this),m(a,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.operator,children:"="},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.number,children:"0"},void 0,!1,void 0,this),m(a,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.number,children:"1"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(a,{children:[" ",m(a,{color:Z.syntax.keyword,children:"for"},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.variable,children:"_"},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.keyword,children:"in"},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.function,children:"range"},void 0,!1,void 0,this),m(a,{color:Z.text.primary,children:"("},void 0,!1,void 0,this),m(a,{color:Z.syntax.variable,children:"n"},void 0,!1,void 0,this),m(a,{color:Z.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(a,{children:[" ",m(a,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this),m(a,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.operator,children:"="},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this),m(a,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.operator,children:"+"},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(a,{children:[" ",m(a,{color:Z.syntax.keyword,children:"return"},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(a,{children:" "},void 0,!1,void 0,this),m(a,{color:Z.error,children:["- print(",m(a,{color:Z.syntax.string,children:'"Hello, "'},void 0,!1,void 0,this)," + name)"]},void 0,!0,void 0,this),m(a,{color:Z.success,children:["+ print(",m(a,{color:Z.syntax.string,children:['f"Hello, ',"{","name","}",'"']},void 0,!0,void 0,this),")"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},tb=({theme:$})=>{let{colors:Z}=$;return m(r1,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[m(a,{children:" "},void 0,!1,void 0,this),m(a,{bold:!0,color:Z.text.primary,children:"颜色配置"},void 0,!1,void 0,this),m(a,{children:" "},void 0,!1,void 0,this),m(a,{children:[m(a,{color:Z.text.muted,children:"Primary: "},void 0,!1,void 0,this),m(a,{color:Z.primary,children:Z.primary},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(a,{children:[m(a,{color:Z.text.muted,children:"Success: "},void 0,!1,void 0,this),m(a,{color:Z.success,children:Z.success},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(a,{children:[m(a,{color:Z.text.muted,children:"Error: "},void 0,!1,void 0,this),m(a,{color:Z.error,children:Z.error},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(a,{children:[m(a,{color:Z.text.muted,children:"Warning: "},void 0,!1,void 0,this),m(a,{color:Z.warning,children:Z.warning},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(a,{children:[m(a,{color:Z.text.muted,children:"Info: "},void 0,!1,void 0,this),m(a,{color:Z.info,children:Z.info},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},oU=()=>{let $=k2(),Z=g0.getCurrentThemeName(),Y=t1.findIndex((z)=>z.label===Z),Q=Y>=0?t1[Y].theme:t1[0].theme,[X,J]=rU(Q),[G,K]=rU(!1),q=rb(async(z)=>{if(G)return;K(!0);try{await x$().setTheme(z.value),$.closeModal()}catch(_){console.error("❌ 主题切换失败:",_ instanceof Error?_.message:_)}finally{K(!1)}}),W=(z)=>{let _=t1.find((B)=>B.id===z.value);if(_)J(_.theme)},H=Z1()==="theme-selector",F=Q0(!1);nb((z,_)=>{if(_.ctrl&&z==="c"||_.meta&&z==="c"){F();return}if(_.escape&&!G)$.closeModal()},{isActive:H});let O=(z)=>{let{isSelected:_,label:B}=z,w=B===Z?"✓":" ";return m(a,{color:_?X.colors.primary:X.colors.text.primary,children:[w," ",B]},void 0,!0,void 0,this)};return m(r1,{flexDirection:"column",height:"100%",children:[m(r1,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:X.colors.border.light,children:m(a,{bold:!0,color:X.colors.primary,children:"\uD83C\uDFA8 主题选择器"},void 0,!1,void 0,this)},void 0,!1,void 0,this),m(r1,{flexDirection:"row",flexGrow:1,children:[m(r1,{width:"40%",borderStyle:"single",borderColor:X.colors.border.light,paddingX:1,children:m(r1,{flexDirection:"column",children:[m(r1,{paddingTop:1,paddingBottom:1,children:m(a,{bold:!0,color:X.colors.text.primary,children:["可用主题 (",nU.length,")"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),m(ob,{items:nU,initialIndex:Y>=0?Y:0,onSelect:q,onHighlight:W,itemComponent:O},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),m(r1,{width:"60%",flexDirection:"column",borderStyle:"single",borderColor:X.colors.border.light,children:[m(sb,{theme:X},void 0,!1,void 0,this),m(tb,{theme:X},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),m(r1,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:X.colors.border.light,children:m(a,{color:X.colors.text.muted,children:G?"正在保存...":"Enter: 选择主题 | Esc: 取消"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as a$}from"react/jsx-dev-runtime";var n0=l("UI"),sU=({debug:$,continue:Z,...Y})=>{if($)n0.debug("[Debug] BladeInterface props:",{permissionMode:Y.permissionMode,yolo:Y.yolo,maxTurns:Y.maxTurns,continue:Z});let Q=V6(!1),X=V6(!1),J=V6(!1),G=V6(null),K=aq(),q=rq(),W=i9(),U=sq(),H=oq(),F=k2(),O=S2(),z=YW(),_=B3(),B=f2(),{exit:L}=eb(),w=K==="ready",N=K==="needsSetup",D=K==="idle",{confirmationState:V,confirmationHandler:I,handleResponse:v}=AW(),{executeCommand:b,handleAbort:C}=LW(Y.systemPrompt,Y.appendSystemPrompt,I,Y.maxTurns),{getPreviousCommand:d,getNextCommand:e,addToHistory:k}=NW();CW();let T=VW("",0),g=r0(async()=>{let Q$=_,E$;if(Q$==="default")E$="autoEdit";else if(Q$==="autoEdit")E$="plan";else if(Q$==="plan")E$="spec";else if(Q$==="spec")E$="default";else E$="default";try{if(await x$().setPermissionMode(E$),E$==="spec")try{let _0=m$.getInstance();await _0.initialize(process.cwd());let o0=await _0.listSpecs();if(o0.length>0){let s0=o0[0];await _0.loadSpec(s0.name),O.addAssistantMessage(`\uD83D\uDCCB **已进入 Spec 模式**
2853
+ `]},void 0,!0,void 0,this),y0(kb,{items:_,onSelect:L,indicatorComponent:pb,itemComponent:mb},void 0,!1,void 0,this),y0(y8,{marginTop:1,flexDirection:"column",children:[y0(f1,{dimColor:!0,children:["第 ",K+1,"/",z," 页 · 共 ",F.length," 个会话 · 显示"," ",B.start,"-",B.end]},void 0,!0,void 0,this),z>1&&y0(y8,{marginTop:1,children:[y0(f1,{color:K>0?"cyan":"gray",children:K>0?"◀ ← 上一页":" "},void 0,!1,void 0,this),y0(f1,{children:" "},void 0,!1,void 0,this),y0(f1,{color:K<z-1?"cyan":"gray",children:K<z-1?"下一页 → ▶":""},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};Y4();import{Box as q0,Text as i$,useInput as db}from"ink";import{jsxDEV as J$}from"react/jsx-dev-runtime";function lU({onCancel:$}){let Y=R0().getAll(),Q=Y.filter((K)=>K.source==="builtin"),X=Y.filter((K)=>K.source==="user"),J=Y.filter((K)=>K.source==="project"),G=Q0(!1,$);if(db((K,q)=>{if(q.escape)$?.();else if(q.ctrl&&K==="c"||q.meta&&K==="c")G()}),Y.length===0)return J$(q0,{flexDirection:"column",paddingY:1,children:[J$(q0,{marginBottom:1,children:J$(i$,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this)},void 0,!1,void 0,this),J$(q0,{paddingLeft:2,children:J$(i$,{color:"gray",children:"没有找到任何 Skill"},void 0,!1,void 0,this)},void 0,!1,void 0,this),J$(q0,{marginTop:1,paddingLeft:2,children:J$(i$,{color:"gray",children:"配置文件位置: ~/.blade/skills/ 或 .blade/skills/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),J$(q0,{marginTop:1,children:J$(i$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return J$(q0,{flexDirection:"column",paddingY:1,children:[J$(q0,{marginBottom:1,children:[J$(i$,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this),J$(i$,{color:"gray",children:[" (找到 ",Y.length," 个)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),J.length>0&&J$(q0,{flexDirection:"column",marginBottom:1,children:[J$(q0,{paddingLeft:1,children:[J$(i$,{bold:!0,color:"yellow",children:"项目级"},void 0,!1,void 0,this),J$(i$,{color:"gray",children:" (.blade/skills/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J.map((K)=>{let W=K.description.length>80?`${K.description.substring(0,80)}...`:K.description;return J$(q0,{flexDirection:"column",paddingLeft:2,children:[J$(i$,{children:[J$(i$,{bold:!0,color:"green",children:["• ",K.name]},void 0,!0,void 0,this),J$(i$,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),K.allowedTools&&K.allowedTools.length>0&&J$(q0,{paddingLeft:2,children:J$(i$,{color:"gray",children:["工具: ",K.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),J$(q0,{paddingLeft:2,children:J$(i$,{color:"gray",dimColor:!0,children:K.path},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},K.name,!0,void 0,this)})]},void 0,!0,void 0,this),X.length>0&&J$(q0,{flexDirection:"column",marginBottom:1,children:[J$(q0,{paddingLeft:1,children:[J$(i$,{bold:!0,color:"yellow",children:"用户级"},void 0,!1,void 0,this),J$(i$,{color:"gray",children:" (~/.blade/skills/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X.map((K)=>{let W=K.description.length>80?`${K.description.substring(0,80)}...`:K.description;return J$(q0,{flexDirection:"column",paddingLeft:2,children:[J$(i$,{children:[J$(i$,{bold:!0,color:"green",children:["• ",K.name]},void 0,!0,void 0,this),J$(i$,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),K.allowedTools&&K.allowedTools.length>0&&J$(q0,{paddingLeft:2,children:J$(i$,{color:"gray",children:["工具: ",K.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),J$(q0,{paddingLeft:2,children:J$(i$,{color:"gray",dimColor:!0,children:K.path},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},K.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.length>0&&J$(q0,{flexDirection:"column",marginBottom:1,children:[J$(q0,{paddingLeft:1,children:[J$(i$,{bold:!0,color:"cyan",children:"内置"},void 0,!1,void 0,this),J$(i$,{color:"gray",children:" (builtin)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.map((K)=>{let W=K.description.length>80?`${K.description.substring(0,80)}...`:K.description;return J$(q0,{flexDirection:"column",paddingLeft:2,children:[J$(i$,{children:[J$(i$,{bold:!0,color:"green",children:["• ",K.name]},void 0,!0,void 0,this),J$(i$,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),K.userInvocable&&J$(q0,{paddingLeft:2,children:J$(i$,{color:"blue",children:["命令: /",K.name]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},K.name,!0,void 0,this)})]},void 0,!0,void 0,this),J$(q0,{marginTop:1,children:J$(i$,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}O1();D1();import{Box as c4,Text as K1}from"ink";import iU,{useEffect as ub,useState as gb}from"react";import{jsxDEV as W0}from"react/jsx-dev-runtime";var cb={init:"\uD83D\uDCDD",requirements:"\uD83D\uDCCB",design:"\uD83C\uDFA8",tasks:"\uD83D\uDCCC",implementation:"\uD83D\uDD27",done:"✅"},R6=["init","requirements","design","tasks","implementation","done"],lb={pending:"○",in_progress:"◐",completed:"●",blocked:"✕"},ib={pending:"gray",in_progress:"yellow",completed:"green",blocked:"red"},aU=iU.memo(({expanded:$=!1,maxTasks:Z=5})=>{let[Y,Q]=gb(null);if(ub(()=>{let G=m$.getInstance();Q(G.getCurrentSpec());let K=setInterval(()=>{Q(G.getCurrentSpec())},1000);return()=>clearInterval(K)},[]),!Y)return null;let X=R6.indexOf(Y.phase),J=Y.tasks.length>0?Math.round(Y.tasks.filter((G)=>G.status==="completed").length/Y.tasks.length*100):0;return W0(c4,{flexDirection:"column",borderStyle:"round",borderColor:"blue",paddingX:1,marginBottom:1,children:[W0(c4,{flexDirection:"row",justifyContent:"space-between",children:[W0(K1,{color:"blue",bold:!0,children:["\uD83D\uDCCB Spec: ",Y.name]},void 0,!0,void 0,this),W0(K1,{color:"gray",children:[cb[Y.phase]," ",v0[Y.phase]]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),W0(c4,{flexDirection:"row",marginTop:1,children:[R6.map((G,K)=>{let q=K<X,W=K===X;return W0(c4,{flexDirection:"row",children:[W0(K1,{color:q?"green":W?"blue":"gray",children:q?"●":W?"◉":"○"},void 0,!1,void 0,this),K<R6.length-1&&W0(K1,{color:q?"green":"gray",children:"──"},void 0,!1,void 0,this)]},G,!0,void 0,this)}),W0(K1,{color:"gray",children:[" (",J,"%)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),W0(c4,{flexDirection:"row",marginTop:0,children:W0(K1,{color:"gray",dimColor:!0,children:R6.map((G,K)=>{let q=G.slice(0,3).toUpperCase();return K===X?`[${q}]`:` ${q} `}).join("")},void 0,!1,void 0,this)},void 0,!1,void 0,this),$&&Y.tasks.length>0&&W0(c4,{flexDirection:"column",marginTop:1,children:[W0(K1,{color:"gray",dimColor:!0,children:["─── Tasks (",Y.tasks.filter((G)=>G.status==="completed").length,"/",Y.tasks.length,") ───"]},void 0,!0,void 0,this),Y.tasks.slice(0,Z).map((G)=>W0(ab,{task:G,isCurrent:G.id===Y.currentTaskId},G.id,!1,void 0,this)),Y.tasks.length>Z&&W0(K1,{color:"gray",dimColor:!0,children:["... and ",Y.tasks.length-Z," more tasks"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),!$&&Y.currentTaskId&&W0(c4,{flexDirection:"row",marginTop:1,children:[W0(K1,{color:"gray",children:"Current: "},void 0,!1,void 0,this),W0(K1,{color:"yellow",children:Y.tasks.find((G)=>G.id===Y.currentTaskId)?.title||"Unknown"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}),ab=iU.memo(({task:$,isCurrent:Z})=>{let Y=lb[$.status]||"?",Q=ib[$.status]||"gray";return W0(c4,{flexDirection:"row",children:[W0(K1,{color:Q,children:[Y," "]},void 0,!0,void 0,this),W0(K1,{color:Z?"yellow":"white",bold:Z,children:$.title},void 0,!1,void 0,this),$.complexity&&W0(K1,{color:"gray",dimColor:!0,children:[" ","[",$.complexity,"]"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});import{useMemoizedFn as rb}from"ahooks";import{Box as r1,Text as a,useInput as nb}from"ink";import ob from"ink-select-input";import{useState as rU}from"react";k$();S6();r4();import{jsxDEV as m}from"react/jsx-dev-runtime";var nU=t1.map(($)=>({label:$.label,value:$.id})),sb=({theme:$})=>{let{colors:Z}=$;return m(r1,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[m(a,{bold:!0,color:Z.text.primary,children:"代码预览"},void 0,!1,void 0,this),m(a,{children:" "},void 0,!1,void 0,this),m(a,{color:Z.syntax.comment,children:"# function"},void 0,!1,void 0,this),m(a,{children:[m(a,{color:Z.syntax.keyword,children:"def"},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.function,children:"fibonacci"},void 0,!1,void 0,this),m(a,{color:Z.text.primary,children:"("},void 0,!1,void 0,this),m(a,{color:Z.syntax.variable,children:"n"},void 0,!1,void 0,this),m(a,{color:Z.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(a,{children:[" ",m(a,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this),m(a,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.operator,children:"="},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.number,children:"0"},void 0,!1,void 0,this),m(a,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.number,children:"1"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(a,{children:[" ",m(a,{color:Z.syntax.keyword,children:"for"},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.variable,children:"_"},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.keyword,children:"in"},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.function,children:"range"},void 0,!1,void 0,this),m(a,{color:Z.text.primary,children:"("},void 0,!1,void 0,this),m(a,{color:Z.syntax.variable,children:"n"},void 0,!1,void 0,this),m(a,{color:Z.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(a,{children:[" ",m(a,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this),m(a,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.operator,children:"="},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this),m(a,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.operator,children:"+"},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(a,{children:[" ",m(a,{color:Z.syntax.keyword,children:"return"},void 0,!1,void 0,this)," ",m(a,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(a,{children:" "},void 0,!1,void 0,this),m(a,{color:Z.error,children:["- print(",m(a,{color:Z.syntax.string,children:'"Hello, "'},void 0,!1,void 0,this)," + name)"]},void 0,!0,void 0,this),m(a,{color:Z.success,children:["+ print(",m(a,{color:Z.syntax.string,children:['f"Hello, ',"{","name","}",'"']},void 0,!0,void 0,this),")"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},tb=({theme:$})=>{let{colors:Z}=$;return m(r1,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[m(a,{children:" "},void 0,!1,void 0,this),m(a,{bold:!0,color:Z.text.primary,children:"颜色配置"},void 0,!1,void 0,this),m(a,{children:" "},void 0,!1,void 0,this),m(a,{children:[m(a,{color:Z.text.muted,children:"Primary: "},void 0,!1,void 0,this),m(a,{color:Z.primary,children:Z.primary},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(a,{children:[m(a,{color:Z.text.muted,children:"Success: "},void 0,!1,void 0,this),m(a,{color:Z.success,children:Z.success},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(a,{children:[m(a,{color:Z.text.muted,children:"Error: "},void 0,!1,void 0,this),m(a,{color:Z.error,children:Z.error},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(a,{children:[m(a,{color:Z.text.muted,children:"Warning: "},void 0,!1,void 0,this),m(a,{color:Z.warning,children:Z.warning},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(a,{children:[m(a,{color:Z.text.muted,children:"Info: "},void 0,!1,void 0,this),m(a,{color:Z.info,children:Z.info},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},oU=()=>{let $=k4(),Z=g0.getCurrentThemeName(),Y=t1.findIndex((z)=>z.label===Z),Q=Y>=0?t1[Y].theme:t1[0].theme,[X,J]=rU(Q),[G,K]=rU(!1),q=rb(async(z)=>{if(G)return;K(!0);try{await x$().setTheme(z.value),$.closeModal()}catch(_){console.error("❌ 主题切换失败:",_ instanceof Error?_.message:_)}finally{K(!1)}}),W=(z)=>{let _=t1.find((B)=>B.id===z.value);if(_)J(_.theme)},H=Z1()==="theme-selector",F=Q0(!1);nb((z,_)=>{if(_.ctrl&&z==="c"||_.meta&&z==="c"){F();return}if(_.escape&&!G)$.closeModal()},{isActive:H});let O=(z)=>{let{isSelected:_,label:B}=z,w=B===Z?"✓":" ";return m(a,{color:_?X.colors.primary:X.colors.text.primary,children:[w," ",B]},void 0,!0,void 0,this)};return m(r1,{flexDirection:"column",height:"100%",children:[m(r1,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:X.colors.border.light,children:m(a,{bold:!0,color:X.colors.primary,children:"\uD83C\uDFA8 主题选择器"},void 0,!1,void 0,this)},void 0,!1,void 0,this),m(r1,{flexDirection:"row",flexGrow:1,children:[m(r1,{width:"40%",borderStyle:"single",borderColor:X.colors.border.light,paddingX:1,children:m(r1,{flexDirection:"column",children:[m(r1,{paddingTop:1,paddingBottom:1,children:m(a,{bold:!0,color:X.colors.text.primary,children:["可用主题 (",nU.length,")"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),m(ob,{items:nU,initialIndex:Y>=0?Y:0,onSelect:q,onHighlight:W,itemComponent:O},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),m(r1,{width:"60%",flexDirection:"column",borderStyle:"single",borderColor:X.colors.border.light,children:[m(sb,{theme:X},void 0,!1,void 0,this),m(tb,{theme:X},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),m(r1,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:X.colors.border.light,children:m(a,{color:X.colors.text.muted,children:G?"正在保存...":"Enter: 选择主题 | Esc: 取消"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as a$}from"react/jsx-dev-runtime";var n0=l("UI"),sU=({debug:$,continue:Z,...Y})=>{if($)n0.debug("[Debug] BladeInterface props:",{permissionMode:Y.permissionMode,yolo:Y.yolo,maxTurns:Y.maxTurns,continue:Z});let Q=V6(!1),X=V6(!1),J=V6(!1),G=V6(null),K=aq(),q=rq(),W=i9(),U=sq(),H=oq(),F=k4(),O=S4(),z=YW(),_=B8(),B=f4(),{exit:L}=eb(),w=K==="ready",N=K==="needsSetup",D=K==="idle",{confirmationState:V,confirmationHandler:I,handleResponse:v}=AW(),{executeCommand:b,handleAbort:C}=LW(Y.systemPrompt,Y.appendSystemPrompt,I,Y.maxTurns),{getPreviousCommand:d,getNextCommand:e,addToHistory:k}=NW();CW();let T=VW("",0),g=r0(async()=>{let Q$=_,E$;if(Q$==="default")E$="autoEdit";else if(Q$==="autoEdit")E$="plan";else if(Q$==="plan")E$="spec";else if(Q$==="spec")E$="default";else E$="default";try{if(await x$().setPermissionMode(E$),E$==="spec")try{let _0=m$.getInstance();await _0.initialize(process.cwd());let o0=await _0.listSpecs();if(o0.length>0){let s0=o0[0];await _0.loadSpec(s0.name),O.addAssistantMessage(`\uD83D\uDCCB **已进入 Spec 模式**
2854
2854
 
2855
2855
  `+`检测到已存在的 Spec: **${s0.name}**
2856
2856
  `+`当前阶段: ${s0.phase}
@@ -2861,6 +2861,6 @@ ${u}
2861
2861
  `+"`提案 → 需求 → 设计 → 任务 → 实现`\n\n"+'例如:"实现用户认证功能" 或 "添加暗黑模式支持"')}catch(_0){n0.warn("Failed to initialize SpecManager:",_0),O.addAssistantMessage(`\uD83D\uDCCB **已进入 Spec 模式**
2862
2862
 
2863
2863
  `+`请告诉我你想实现什么功能,我会引导你完成整个工作流:
2864
- `+"`提案 → 需求 → 设计 → 任务 → 实现`\n\n"+'例如:"实现用户认证功能" 或 "添加暗黑模式支持"')}}catch(_0){n0.error("❌ 权限模式切换失败:",_0 instanceof Error?_0.message:_0)}}),j=r0(async(Q$)=>{try{await x$().addModel({name:Q$.name,provider:Q$.provider,apiKey:Q$.apiKey,baseUrl:Q$.baseUrl,model:Q$.model}),F.setInitializationStatus("ready")}catch(E$){n0.error("❌ 初始化配置保存失败:",E$ instanceof Error?E$.message:E$),F.setInitializationStatus("ready")}}),M=r0(()=>{if(W==="shortcuts")F.closeModal();else F.setActiveModal("shortcuts")}),{showSuggestions:R,suggestions:n,selectedSuggestionIndex:y}=TW(T,b,d,e,k,C,B,g,M,W==="shortcuts");I4(()=>{if(T.value&&W==="shortcuts")F.closeModal()},[T.value,W,F]);let u=r0(async()=>{J.current=!0;try{let Q$=await _1.listSessions();if(Q$.length===0){O.addAssistantMessage("没有找到历史会话,开始新对话。");return}let E$=Q$[0],_0=await _1.loadSession(E$.sessionId),o0=_0.map((s0,_Y)=>({id:`restored-${Date.now()}-${_Y}`,role:s0.role,content:typeof s0.content==="string"?s0.content:JSON.stringify(s0.content),timestamp:Date.now()-(_0.length-_Y)*1000}));O.restoreSession(E$.sessionId,o0)}catch(Q$){n0.error("[BladeInterface] 继续会话失败:",Q$),O.addAssistantMessage("继续会话失败,开始新对话。")}}),s=r0(async()=>{J.current=!0;try{if(typeof Y.resume==="string"&&Y.resume!=="true"){let E$=await _1.loadSession(Y.resume),_0=E$.map((o0,s0)=>({id:`restored-${Date.now()}-${s0}`,role:o0.role,content:typeof o0.content==="string"?o0.content:JSON.stringify(o0.content),timestamp:Date.now()-(E$.length-s0)*1000}));O.restoreSession(Y.resume,_0);return}let Q$=await _1.listSessions();if(Q$.length===0)n0.error("没有找到历史会话"),_3(1);F.showSessionSelector(Q$)}catch(Q$){n0.error("[BladeInterface] 加载会话失败:",Q$),_3(1)}});I4(()=>{if(Q.current)return;if(Z){Q.current=!0,u();return}if(Y.resume)Q.current=!0,s()},[Z,Y.resume,u,s]);let i=r0(async(Q$)=>{let E$=V.details?.type;if(E$==="enterPlanMode"&&Q$.approved)try{await x$().setPermissionMode("plan"),n0.debug("[BladeInterface] Entered Plan mode")}catch(_0){n0.error("[BladeInterface] Failed to enter Plan mode:",_0)}if(E$==="exitPlanMode"&&Q$.approved)n0.debug("[BladeInterface] ExitPlanMode approved, Store auto-synced");v(Q$)}),Y$=r0(()=>{O.addAssistantMessage("❌ 设置已取消"),O.addAssistantMessage("Blade 需要 API 配置才能正常工作。"),O.addAssistantMessage("您可以稍后运行 Blade 重新进入设置向导。"),_3(0)}),f=r0(()=>{F.closeModal()}),w$=r0(async(Q$)=>{try{let E$=await _1.loadSession(Q$),_0=E$.map((o0,s0)=>({id:`restored-${Date.now()}-${s0}`,role:o0.role,content:typeof o0.content==="string"?o0.content:JSON.stringify(o0.content),timestamp:Date.now()-(E$.length-s0)*1000}));O.restoreSession(Q$,_0),F.closeModal()}catch(E$){n0.error("[BladeInterface] Failed to restore session:",E$),F.closeModal()}}),G$=r0(()=>{if(Y.resume)L();else F.closeModal()}),N$=r0((Q$)=>{F.showModelEditWizard(Q$)}),X0=r0((Q$)=>{O.addAssistantMessage(`✅ 已添加模型配置: ${Q$.name},并已切换到该模型`),f()}),G0=r0((Q$)=>{O.addAssistantMessage(`✅ 已更新模型配置: ${Q$.name}`),f()});I4(()=>{if(N){z.setFocus("model-config-wizard");return}if(V.isVisible)z.setFocus("confirmation-prompt");else if(W==="sessionSelector")z.setFocus("session-selector");else if(W==="themeSelector")z.setFocus("theme-selector");else if(W==="modelSelector")z.setFocus("model-selector");else if(W==="modelAddWizard"||W==="modelEditWizard")z.setFocus("model-config-wizard");else if(W==="permissionsManager")z.setFocus("permissions-manager");else if(W==="agentsManager")z.setFocus("agents-manager");else if(W==="agentCreationWizard")z.setFocus("agent-creation-wizard");else if(W==="hooksManager")z.setFocus("hooks-manager");else if(W==="shortcuts")z.setFocus("main-input");else z.setFocus("main-input")},[N,V.isVisible,W,z.setFocus]),I4(()=>{if(!w||J.current)return;if(YQ().length>0){J.current=!0;return}J.current=!0,O.addAssistantMessage("请输入您的问题,我将为您提供帮助。")},[w]),I4(()=>{if(!q)return;if(G.current===q)return;if(G.current=q,K==="error")O.addAssistantMessage(`❌ 初始化失败: ${q}`);else O.addAssistantMessage(`❌ ${q}`),O.addAssistantMessage("请重新尝试设置,或检查文件权限")},[q,K,O.addAssistantMessage]);let _2=r0(async(Q$)=>{try{await b({displayText:Q$,text:Q$,images:[],parts:[{type:"text",text:Q$}]})}catch(E$){let _0=E$ instanceof Error?E$.message:"无法发送初始消息";O.addAssistantMessage(`❌ 初始消息发送失败:${_0}`)}});I4(()=>{let Q$=Y.initialMessage?.trim();if(!Q$||X.current||!w||N)return;X.current=!0,k(Q$),_2(Q$)},[Y.initialMessage,w,N,b,k]);let T0=r0(async(Q$)=>{try{await x$().setPermissionMode(Q$)}catch(E$){n0.error("❌ 权限模式初始化失败:",E$ instanceof Error?E$.message:E$)}});if(I4(()=>{let Q$=Y.permissionMode;if($)n0.debug("[Debug] permissionMode from CLI:",Q$),n0.debug("[Debug] current permissionMode:",_);if(!Q$||Q$===_)return;T0(Q$)},[Y.permissionMode,_]),D)return null;if(N)return a$(JY,{mode:"setup",onComplete:j,onCancel:Y$},void 0,!1,void 0,this);if($)n0.debug("[Debug] 渲染主界面,条件检查:",{confirmationVisible:V.isVisible,activeModal:W});let K$=W==="modelSelector",e$=H,L$=W==="modelAddWizard"?"add":W==="modelEditWizard"&&e$?"edit":null,o1=K$||Boolean(L$),m0=W==="agentsManager",B2=W==="agentCreationWizard",R1=W==="skillsManager",S8=W==="pluginsManager",KH=e$?{name:e$.name,provider:e$.provider,baseUrl:e$.baseUrl,apiKey:e$.apiKey,model:e$.model}:void 0,OY=V.isVisible&&V.details?V.details.type==="askUserQuestion"&&V.details.questions?a$(uU,{questions:V.details.questions,onComplete:(Q$)=>i({approved:!0,answers:Q$}),onCancel:()=>i({approved:!1})},void 0,!1,void 0,this):a$(ZU,{details:V.details,onResponse:i},void 0,!1,void 0,this):W==="themeSelector"?a$(oU,{},void 0,!1,void 0,this):W==="permissionsManager"?a$(pU,{onClose:f},void 0,!1,void 0,this):W==="sessionSelector"?a$(cU,{sessions:U,onSelect:w$,onCancel:G$},void 0,!1,void 0,this):W==="hooksManager"?a$(QU,{onClose:f},void 0,!1,void 0,this):null,zY=Boolean(OY);return a$(l2,{flexDirection:"column",width:"100%",overflow:"hidden",children:[OY,a$(l2,{flexDirection:"column",display:zY?"none":"flex",children:[_==="spec"&&a$(aU,{},void 0,!1,void 0,this),a$(vU,{},void 0,!1,void 0,this),a$(AU,{paused:zY},void 0,!1,void 0,this),a$(zU,{input:T.value,cursorPosition:T.cursorPosition,onChange:T.setValue,onChangeCursorPosition:T.setCursorPosition,onAddPasteMapping:T.addPasteMapping,onAddImagePasteMapping:T.addImagePasteMapping},void 0,!1,void 0,this),K$&&a$(l2,{marginTop:1,paddingX:2,children:a$(SU,{onClose:f,onEdit:N$},void 0,!1,void 0,this)},void 0,!1,void 0,this),L$&&a$(l2,{marginTop:1,paddingX:2,children:a$(JY,{mode:L$,modelId:e$?.id,initialConfig:L$==="edit"?KH:void 0,onComplete:L$==="edit"?G0:X0,onCancel:f},void 0,!1,void 0,this)},void 0,!1,void 0,this),m0&&a$(l2,{marginTop:1,paddingX:2,children:a$(xW,{onComplete:f,onCancel:f},void 0,!1,void 0,this)},void 0,!1,void 0,this),B2&&a$(l2,{marginTop:1,paddingX:2,children:a$(D8,{onComplete:f,onCancel:f},void 0,!1,void 0,this)},void 0,!1,void 0,this),R1&&a$(l2,{marginTop:1,paddingX:2,children:a$(lU,{onComplete:f,onCancel:f},void 0,!1,void 0,this)},void 0,!1,void 0,this),S8&&a$(l2,{marginTop:1,paddingX:2,children:a$(mU,{onComplete:f,onCancel:f},void 0,!1,void 0,this)},void 0,!1,void 0,this),a$(uW,{suggestions:n,selectedIndex:y,visible:R&&!o1},void 0,!1,void 0,this),a$(dW,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{Box as $A,Text as i2}from"ink";import ZA from"react";import{jsxDEV as O2}from"react/jsx-dev-runtime";class D6 extends ZA.Component{constructor($){super($);this.state={hasError:!1,error:null,errorInfo:null}}static getDerivedStateFromError($){return{hasError:!0,error:$,errorInfo:null}}componentDidCatch($,Z){this.setState({error:$,errorInfo:Z}),console.error("未捕获的错误:",$,Z)}render(){if(this.state.hasError)return O2($A,{flexDirection:"column",padding:1,borderStyle:"round",borderColor:"red",children:[O2(i2,{color:"red",children:"\uD83D\uDCA5 应用发生错误"},void 0,!1,void 0,this),O2(i2,{children:" "},void 0,!1,void 0,this),O2(i2,{color:"red",children:this.state.error?.message},void 0,!1,void 0,this),O2(i2,{children:" "},void 0,!1,void 0,this),O2(i2,{color:"gray",children:"错误详情:"},void 0,!1,void 0,this),O2(i2,{color:"gray",children:this.state.error?.stack},void 0,!1,void 0,this),O2(i2,{children:" "},void 0,!1,void 0,this),O2(i2,{color:"yellow",children:"请重启应用或联系开发者"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return this.props.children}}import{Box as y4,Text as z2,useInput as YA}from"ink";import{useState as qY}from"react";import{jsxDEV as p0}from"react/jsx-dev-runtime";var M6=[{key:"update",label:"Update now",description:`runs \`${NZ()}\``},{key:"skip",label:"Skip",description:""},{key:"skip_until_next",label:"Skip until next version",description:""}],tU=({versionInfo:$,onComplete:Z})=>{let[Y,Q]=qY(0),[X,J]=qY(!1),[G,K]=qY(null);YA((W,U)=>{if(U.ctrl&&W==="c"){B4().shutdown("SIGINT",0);return}if(X||G)return;if(U.upArrow||W==="k")Q((H)=>H>0?H-1:M6.length-1);else if(U.downArrow||W==="j")Q((H)=>H<M6.length-1?H+1:0);else if(U.return)q(M6[Y].key);else if(W==="1")q("update");else if(W==="2")q("skip");else if(W==="3")q("skip_until_next")});let q=async(W)=>{switch(W){case"update":{J(!0);let U=await fq();K(U.message),setTimeout(()=>{B4().shutdown("SIGINT",0)},1500);break}case"skip":Z();break;case"skip_until_next":if($.latestVersion)await kq($.latestVersion);Z();break}};if(G)return p0(y4,{flexDirection:"column",marginY:1,children:p0(z2,{children:G},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(X)return p0(y4,{flexDirection:"column",marginY:1,children:p0(z2,{color:"cyan",children:"Updating..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);return p0(y4,{flexDirection:"column",marginY:1,children:[p0(z2,{color:"yellow",bold:!0,children:["✨ Update available! ",p0(z2,{color:"gray",children:[$.currentVersion," ","→"," ",$.latestVersion]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),p0(y4,{marginTop:1,children:p0(z2,{color:"gray",children:["Release notes:"," ",p0(z2,{color:"cyan",underline:!0,children:$.releaseNotesUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),p0(y4,{flexDirection:"column",marginTop:1,children:M6.map((W,U)=>{let H=U===Y,F=H?"› ":" ",O=`${U+1}. `;return p0(y4,{children:p0(z2,{color:H?"cyan":void 0,children:[F,O,W.label,W.description&&p0(z2,{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),p0(y4,{marginTop:1,children:p0(z2,{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)};r2();function v3($){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 j6}from"react/jsx-dev-runtime";function XA($){let Z=fQ();if(!$.models)$.models=[];let Y=kQ();if(!$.models.some((X)=>X.id===Y)){if($.models.unshift(Z),$.debug)console.log("[Debug] 已添加内置免费模型到模型列表")}if(!$.currentModelId)$.currentModelId=Z.id,console.log("✨ 已自动配置内置免费模型: GLM-4.7");if(q$().config.actions.setConfig($),$.debug)console.log("[Debug] 模型配置检查通过,准备就绪");$2().setInitializationStatus("ready")}var $H=($)=>{let[Z,Y]=WY(!1),[Q,X]=WY(null),[J,G]=WY(!1),K=eU(async()=>{let W=q$().config.config??E4,U=E6(W,$);if(XA(U),U.debug)console.error("[Debug] 运行时配置:",U);let H=U.theme;if(H&&g0.hasTheme(H)){if(g0.setTheme(H),$.debug)console.log(`✓ 已加载主题: ${H}`)}try{let F=J0.loadFromStandardLocations();if($.debug&&F>0)console.log(`✓ 已加载 ${F} 个 subagents: ${J0.getAllNames().join(", ")}`)}catch(F){if($.debug)console.warn("⚠️ Subagents 加载失败:",v3(F))}try{let F=M$.getInstance();if(F.loadConfig(U.hooks||{}),$.debug&&U.hooks?.enabled)console.log("✓ Hooks 系统已启用");let O=q$(),z=O.session.sessionId;if(IY(z),F.isEnabled()){let _=O.config.config?.permissionMode||"default",B=!!$.resume,L=await F.executeSessionStartHooks({projectDir:process.cwd(),sessionId:z,permissionMode:_,isResume:B,resumeSessionId:typeof $.resume==="string"?$.resume:void 0});if(L.env){for(let[w,N]of Object.entries(L.env))process.env[w]=N;if($.debug)console.log("✓ SessionStart hooks 注入环境变量:",Object.keys(L.env).join(", "))}if(L.warning&&$.debug)console.warn("⚠️ SessionStart hooks 警告:",L.warning)}}catch(F){if($.debug)console.warn("⚠️ Hooks 初始化失败:",v3(F))}try{let F=await Y4();if($.debug&&F.skills.length>0)console.log(`✓ 已加载 ${F.skills.length} 个 skills: ${F.skills.map((O)=>O.name).join(", ")}`);if(F.errors.length>0&&$.debug)for(let O of F.errors)console.warn(`⚠️ Skill 加载错误 (${O.path}): ${O.error}`)}catch(F){if($.debug)console.warn("⚠️ Skills 初始化失败:",v3(F))}try{let F=await jq(process.cwd());if($.debug&&F.commands.length>0)console.log(`✓ 已加载 ${F.commands.length} 个自定义命令: ${F.commands.map((O)=>O.name).join(", ")}`);if(F.errors.length>0&&$.debug)for(let O of F.errors)console.warn(`⚠️ 自定义命令加载错误 (${O.path}): ${O.error}`)}catch(F){if($.debug)console.warn("⚠️ 自定义命令初始化失败:",v3(F))}try{let O=await a0().initialize(process.cwd(),$.pluginDir||[]);if($.debug&&O.plugins.length>0)console.log(`✓ 已加载 ${O.plugins.length} 个插件: ${O.plugins.map((z)=>z.manifest.name).join(", ")}`);if(O.plugins.length>0){let z=await E2();if($.debug){let{totalCommands:_,totalSkills:B,totalAgents:L,totalMcpServers:w}=z;console.log(` ✓ 已集成: ${_} 命令, ${B} 技能, ${L} 代理, ${w} MCP 服务器`)}}if(O.errors.length>0&&$.debug)for(let z of O.errors)console.warn(`⚠️ 插件加载错误 (${z.path}): ${z.error}`)}catch(F){if($.debug)console.warn("⚠️ 插件系统初始化失败:",v3(F))}mq(async()=>{P0.getInstance().killAll(),await b0.getInstance().disconnectAll(),M$.getInstance().cleanup()}),Y(!0)}),q=eU(async()=>{if($.versionCheckPromise){let W=await $.versionCheckPromise;if(W){X(W),G(!0);return}}await K()});if(QA(()=>{q()},[]),J&&Q)return j6(D6,{children:j6(tU,{versionInfo:Q,onComplete:()=>{G(!1),K()}},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(!Z)return null;return j6(D6,{children:j6(sU,{...$},void 0,!1,void 0,this)},void 0,!1,void 0,this)};var FY=GH(process.argv),JH=FY.indexOf("--debug");if(JH!==-1){let $=FY[JH+1],Z=$&&!$.startsWith("-")?$:!0;V1.setGlobalDebug(Z)}async function zA(){if(process.getuid&&process.getuid()===0)console.error(""),console.error("❌ 请不要使用 sudo 运行 blade"),console.error(""),console.error("原因:"),console.error(" 使用 sudo 会创建属于 root 的配置文件,"),console.error(" 导致普通用户无法访问。"),console.error(""),console.error("正确用法:"),console.error(" blade # 直接运行,不要加 sudo"),console.error(""),console.error("如果遇到权限错误,请运行:"),console.error(" sudo chown -R $USER:$USER ~/.blade/"),console.error(""),process.exit(1);dq();let $=hq();if(await vq())return;if(FY.includes("--acp")){let{runAcpIntegration:Y}=await Promise.resolve().then(() => (XH(),QH));await Y();return}let Z=OA(GH(process.argv)).scriptName(a2.scriptName).usage(a2.usage).version(a2.version).locale(a2.locale).showHelpOnFail(a2.showHelpOnFail).demandCommand(0,"").recommendCommands().strict(a2.strict).parserConfiguration({"populate--":!0}).options(bY).middleware([XQ,JQ,GQ]).command(jQ).command(KQ).command(xq).command(qQ).completion("completion",!1).help("help","Show help").alias("help","h").alias("version","V").fail((Y,Q,X)=>{if(Q)console.error("\uD83D\uDCA5 An error occurred:"),console.error(Q.message),console.error(`
2864
+ `+"`提案 → 需求 → 设计 → 任务 → 实现`\n\n"+'例如:"实现用户认证功能" 或 "添加暗黑模式支持"')}}catch(_0){n0.error("❌ 权限模式切换失败:",_0 instanceof Error?_0.message:_0)}}),j=r0(async(Q$)=>{try{await x$().addModel({name:Q$.name,provider:Q$.provider,apiKey:Q$.apiKey,baseUrl:Q$.baseUrl,model:Q$.model}),F.setInitializationStatus("ready")}catch(E$){n0.error("❌ 初始化配置保存失败:",E$ instanceof Error?E$.message:E$),F.setInitializationStatus("ready")}}),M=r0(()=>{if(W==="shortcuts")F.closeModal();else F.setActiveModal("shortcuts")}),{showSuggestions:R,suggestions:n,selectedSuggestionIndex:y}=TW(T,b,d,e,k,C,B,g,M,W==="shortcuts");I2(()=>{if(T.value&&W==="shortcuts")F.closeModal()},[T.value,W,F]);let u=r0(async()=>{J.current=!0;try{let Q$=await _1.listSessions();if(Q$.length===0){O.addAssistantMessage("没有找到历史会话,开始新对话。");return}let E$=Q$[0],_0=await _1.loadSession(E$.sessionId),o0=_0.map((s0,_Y)=>({id:`restored-${Date.now()}-${_Y}`,role:s0.role,content:typeof s0.content==="string"?s0.content:JSON.stringify(s0.content),timestamp:Date.now()-(_0.length-_Y)*1000}));O.restoreSession(E$.sessionId,o0)}catch(Q$){n0.error("[BladeInterface] 继续会话失败:",Q$),O.addAssistantMessage("继续会话失败,开始新对话。")}}),s=r0(async()=>{J.current=!0;try{if(typeof Y.resume==="string"&&Y.resume!=="true"){let E$=await _1.loadSession(Y.resume),_0=E$.map((o0,s0)=>({id:`restored-${Date.now()}-${s0}`,role:o0.role,content:typeof o0.content==="string"?o0.content:JSON.stringify(o0.content),timestamp:Date.now()-(E$.length-s0)*1000}));O.restoreSession(Y.resume,_0);return}let Q$=await _1.listSessions();if(Q$.length===0)n0.error("没有找到历史会话"),_8(1);F.showSessionSelector(Q$)}catch(Q$){n0.error("[BladeInterface] 加载会话失败:",Q$),_8(1)}});I2(()=>{if(Q.current)return;if(Z){Q.current=!0,u();return}if(Y.resume)Q.current=!0,s()},[Z,Y.resume,u,s]);let i=r0(async(Q$)=>{let E$=V.details?.type;if(E$==="enterPlanMode"&&Q$.approved)try{await x$().setPermissionMode("plan"),n0.debug("[BladeInterface] Entered Plan mode")}catch(_0){n0.error("[BladeInterface] Failed to enter Plan mode:",_0)}if(E$==="exitPlanMode"&&Q$.approved)n0.debug("[BladeInterface] ExitPlanMode approved, Store auto-synced");v(Q$)}),Y$=r0(()=>{O.addAssistantMessage("❌ 设置已取消"),O.addAssistantMessage("Blade 需要 API 配置才能正常工作。"),O.addAssistantMessage("您可以稍后运行 Blade 重新进入设置向导。"),_8(0)}),f=r0(()=>{F.closeModal()}),w$=r0(async(Q$)=>{try{let E$=await _1.loadSession(Q$),_0=E$.map((o0,s0)=>({id:`restored-${Date.now()}-${s0}`,role:o0.role,content:typeof o0.content==="string"?o0.content:JSON.stringify(o0.content),timestamp:Date.now()-(E$.length-s0)*1000}));O.restoreSession(Q$,_0),F.closeModal()}catch(E$){n0.error("[BladeInterface] Failed to restore session:",E$),F.closeModal()}}),G$=r0(()=>{if(Y.resume)L();else F.closeModal()}),N$=r0((Q$)=>{F.showModelEditWizard(Q$)}),X0=r0((Q$)=>{O.addAssistantMessage(`✅ 已添加模型配置: ${Q$.name},并已切换到该模型`),f()}),G0=r0((Q$)=>{O.addAssistantMessage(`✅ 已更新模型配置: ${Q$.name}`),f()});I2(()=>{if(N){z.setFocus("model-config-wizard");return}if(V.isVisible)z.setFocus("confirmation-prompt");else if(W==="sessionSelector")z.setFocus("session-selector");else if(W==="themeSelector")z.setFocus("theme-selector");else if(W==="modelSelector")z.setFocus("model-selector");else if(W==="modelAddWizard"||W==="modelEditWizard")z.setFocus("model-config-wizard");else if(W==="permissionsManager")z.setFocus("permissions-manager");else if(W==="agentsManager")z.setFocus("agents-manager");else if(W==="agentCreationWizard")z.setFocus("agent-creation-wizard");else if(W==="hooksManager")z.setFocus("hooks-manager");else if(W==="shortcuts")z.setFocus("main-input");else z.setFocus("main-input")},[N,V.isVisible,W,z.setFocus]),I2(()=>{if(!w||J.current)return;if(YQ().length>0){J.current=!0;return}J.current=!0,O.addAssistantMessage("请输入您的问题,我将为您提供帮助。")},[w]),I2(()=>{if(!q)return;if(G.current===q)return;if(G.current=q,K==="error")O.addAssistantMessage(`❌ 初始化失败: ${q}`);else O.addAssistantMessage(`❌ ${q}`),O.addAssistantMessage("请重新尝试设置,或检查文件权限")},[q,K,O.addAssistantMessage]);let _4=r0(async(Q$)=>{try{await b({displayText:Q$,text:Q$,images:[],parts:[{type:"text",text:Q$}]})}catch(E$){let _0=E$ instanceof Error?E$.message:"无法发送初始消息";O.addAssistantMessage(`❌ 初始消息发送失败:${_0}`)}});I2(()=>{let Q$=Y.initialMessage?.trim();if(!Q$||X.current||!w||N)return;X.current=!0,k(Q$),_4(Q$)},[Y.initialMessage,w,N,b,k]);let T0=r0(async(Q$)=>{try{await x$().setPermissionMode(Q$)}catch(E$){n0.error("❌ 权限模式初始化失败:",E$ instanceof Error?E$.message:E$)}});if(I2(()=>{let Q$=Y.permissionMode;if($)n0.debug("[Debug] permissionMode from CLI:",Q$),n0.debug("[Debug] current permissionMode:",_);if(!Q$||Q$===_)return;T0(Q$)},[Y.permissionMode,_]),D)return null;if(N)return a$(JY,{mode:"setup",onComplete:j,onCancel:Y$},void 0,!1,void 0,this);if($)n0.debug("[Debug] 渲染主界面,条件检查:",{confirmationVisible:V.isVisible,activeModal:W});let K$=W==="modelSelector",e$=H,L$=W==="modelAddWizard"?"add":W==="modelEditWizard"&&e$?"edit":null,o1=K$||Boolean(L$),m0=W==="agentsManager",B4=W==="agentCreationWizard",R1=W==="skillsManager",S3=W==="pluginsManager",KH=e$?{name:e$.name,provider:e$.provider,baseUrl:e$.baseUrl,apiKey:e$.apiKey,model:e$.model}:void 0,OY=V.isVisible&&V.details?V.details.type==="askUserQuestion"&&V.details.questions?a$(uU,{questions:V.details.questions,onComplete:(Q$)=>i({approved:!0,answers:Q$}),onCancel:()=>i({approved:!1})},void 0,!1,void 0,this):a$(ZU,{details:V.details,onResponse:i},void 0,!1,void 0,this):W==="themeSelector"?a$(oU,{},void 0,!1,void 0,this):W==="permissionsManager"?a$(pU,{onClose:f},void 0,!1,void 0,this):W==="sessionSelector"?a$(cU,{sessions:U,onSelect:w$,onCancel:G$},void 0,!1,void 0,this):W==="hooksManager"?a$(QU,{onClose:f},void 0,!1,void 0,this):null,zY=Boolean(OY);return a$(l4,{flexDirection:"column",width:"100%",overflow:"hidden",children:[OY,a$(l4,{flexDirection:"column",display:zY?"none":"flex",children:[_==="spec"&&a$(aU,{},void 0,!1,void 0,this),a$(vU,{},void 0,!1,void 0,this),a$(AU,{paused:zY},void 0,!1,void 0,this),a$(zU,{input:T.value,cursorPosition:T.cursorPosition,onChange:T.setValue,onChangeCursorPosition:T.setCursorPosition,onAddPasteMapping:T.addPasteMapping,onAddImagePasteMapping:T.addImagePasteMapping},void 0,!1,void 0,this),K$&&a$(l4,{marginTop:1,paddingX:2,children:a$(SU,{onClose:f,onEdit:N$},void 0,!1,void 0,this)},void 0,!1,void 0,this),L$&&a$(l4,{marginTop:1,paddingX:2,children:a$(JY,{mode:L$,modelId:e$?.id,initialConfig:L$==="edit"?KH:void 0,onComplete:L$==="edit"?G0:X0,onCancel:f},void 0,!1,void 0,this)},void 0,!1,void 0,this),m0&&a$(l4,{marginTop:1,paddingX:2,children:a$(xW,{onComplete:f,onCancel:f},void 0,!1,void 0,this)},void 0,!1,void 0,this),B4&&a$(l4,{marginTop:1,paddingX:2,children:a$(D3,{onComplete:f,onCancel:f},void 0,!1,void 0,this)},void 0,!1,void 0,this),R1&&a$(l4,{marginTop:1,paddingX:2,children:a$(lU,{onComplete:f,onCancel:f},void 0,!1,void 0,this)},void 0,!1,void 0,this),S3&&a$(l4,{marginTop:1,paddingX:2,children:a$(mU,{onComplete:f,onCancel:f},void 0,!1,void 0,this)},void 0,!1,void 0,this),a$(uW,{suggestions:n,selectedIndex:y,visible:R&&!o1},void 0,!1,void 0,this),a$(dW,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{Box as $A,Text as i4}from"ink";import ZA from"react";import{jsxDEV as O4}from"react/jsx-dev-runtime";class D6 extends ZA.Component{constructor($){super($);this.state={hasError:!1,error:null,errorInfo:null}}static getDerivedStateFromError($){return{hasError:!0,error:$,errorInfo:null}}componentDidCatch($,Z){this.setState({error:$,errorInfo:Z}),console.error("未捕获的错误:",$,Z)}render(){if(this.state.hasError)return O4($A,{flexDirection:"column",padding:1,borderStyle:"round",borderColor:"red",children:[O4(i4,{color:"red",children:"\uD83D\uDCA5 应用发生错误"},void 0,!1,void 0,this),O4(i4,{children:" "},void 0,!1,void 0,this),O4(i4,{color:"red",children:this.state.error?.message},void 0,!1,void 0,this),O4(i4,{children:" "},void 0,!1,void 0,this),O4(i4,{color:"gray",children:"错误详情:"},void 0,!1,void 0,this),O4(i4,{color:"gray",children:this.state.error?.stack},void 0,!1,void 0,this),O4(i4,{children:" "},void 0,!1,void 0,this),O4(i4,{color:"yellow",children:"请重启应用或联系开发者"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return this.props.children}}import{Box as y2,Text as z4,useInput as YA}from"ink";import{useState as qY}from"react";import{jsxDEV as p0}from"react/jsx-dev-runtime";var M6=[{key:"update",label:"Update now",description:`runs \`${NZ()}\``},{key:"skip",label:"Skip",description:""},{key:"skip_until_next",label:"Skip until next version",description:""}],tU=({versionInfo:$,onComplete:Z})=>{let[Y,Q]=qY(0),[X,J]=qY(!1),[G,K]=qY(null);YA((W,U)=>{if(U.ctrl&&W==="c"){B2().shutdown("SIGINT",0);return}if(X||G)return;if(U.upArrow||W==="k")Q((H)=>H>0?H-1:M6.length-1);else if(U.downArrow||W==="j")Q((H)=>H<M6.length-1?H+1:0);else if(U.return)q(M6[Y].key);else if(W==="1")q("update");else if(W==="2")q("skip");else if(W==="3")q("skip_until_next")});let q=async(W)=>{switch(W){case"update":{J(!0);let U=await fq();K(U.message),setTimeout(()=>{B2().shutdown("SIGINT",0)},1500);break}case"skip":Z();break;case"skip_until_next":if($.latestVersion)await kq($.latestVersion);Z();break}};if(G)return p0(y2,{flexDirection:"column",marginY:1,children:p0(z4,{children:G},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(X)return p0(y2,{flexDirection:"column",marginY:1,children:p0(z4,{color:"cyan",children:"Updating..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);return p0(y2,{flexDirection:"column",marginY:1,children:[p0(z4,{color:"yellow",bold:!0,children:["✨ Update available! ",p0(z4,{color:"gray",children:[$.currentVersion," ","→"," ",$.latestVersion]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),p0(y2,{marginTop:1,children:p0(z4,{color:"gray",children:["Release notes:"," ",p0(z4,{color:"cyan",underline:!0,children:$.releaseNotesUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),p0(y2,{flexDirection:"column",marginTop:1,children:M6.map((W,U)=>{let H=U===Y,F=H?"› ":" ",O=`${U+1}. `;return p0(y2,{children:p0(z4,{color:H?"cyan":void 0,children:[F,O,W.label,W.description&&p0(z4,{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),p0(y2,{marginTop:1,children:p0(z4,{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)};r4();function v8($){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 j6}from"react/jsx-dev-runtime";function XA($){let Z=fQ();if(!$.models)$.models=[];let Y=kQ(),Q=$.models.findIndex((X)=>X.id===Y);if(Q>=0){if($.models[Q]=Z,$.debug)console.log("[Debug] 已更新内置免费模型配置")}else if($.models.unshift(Z),$.debug)console.log("[Debug] 已添加内置免费模型到模型列表");if(!$.currentModelId)$.currentModelId=Z.id,console.log("✨ 已自动配置内置免费模型: GLM-4.7");if(q$().config.actions.setConfig($),$.debug)console.log("[Debug] 模型配置检查通过,准备就绪");$4().setInitializationStatus("ready")}var $H=($)=>{let[Z,Y]=WY(!1),[Q,X]=WY(null),[J,G]=WY(!1),K=eU(async()=>{let W=q$().config.config??E2,U=E6(W,$);if(XA(U),U.debug)console.error("[Debug] 运行时配置:",U);let H=U.theme;if(H&&g0.hasTheme(H)){if(g0.setTheme(H),$.debug)console.log(`✓ 已加载主题: ${H}`)}try{let F=J0.loadFromStandardLocations();if($.debug&&F>0)console.log(`✓ 已加载 ${F} 个 subagents: ${J0.getAllNames().join(", ")}`)}catch(F){if($.debug)console.warn("⚠️ Subagents 加载失败:",v8(F))}try{let F=M$.getInstance();if(F.loadConfig(U.hooks||{}),$.debug&&U.hooks?.enabled)console.log("✓ Hooks 系统已启用");let O=q$(),z=O.session.sessionId;if(IY(z),F.isEnabled()){let _=O.config.config?.permissionMode||"default",B=!!$.resume,L=await F.executeSessionStartHooks({projectDir:process.cwd(),sessionId:z,permissionMode:_,isResume:B,resumeSessionId:typeof $.resume==="string"?$.resume:void 0});if(L.env){for(let[w,N]of Object.entries(L.env))process.env[w]=N;if($.debug)console.log("✓ SessionStart hooks 注入环境变量:",Object.keys(L.env).join(", "))}if(L.warning&&$.debug)console.warn("⚠️ SessionStart hooks 警告:",L.warning)}}catch(F){if($.debug)console.warn("⚠️ Hooks 初始化失败:",v8(F))}try{let F=await Y2();if($.debug&&F.skills.length>0)console.log(`✓ 已加载 ${F.skills.length} 个 skills: ${F.skills.map((O)=>O.name).join(", ")}`);if(F.errors.length>0&&$.debug)for(let O of F.errors)console.warn(`⚠️ Skill 加载错误 (${O.path}): ${O.error}`)}catch(F){if($.debug)console.warn("⚠️ Skills 初始化失败:",v8(F))}try{let F=await jq(process.cwd());if($.debug&&F.commands.length>0)console.log(`✓ 已加载 ${F.commands.length} 个自定义命令: ${F.commands.map((O)=>O.name).join(", ")}`);if(F.errors.length>0&&$.debug)for(let O of F.errors)console.warn(`⚠️ 自定义命令加载错误 (${O.path}): ${O.error}`)}catch(F){if($.debug)console.warn("⚠️ 自定义命令初始化失败:",v8(F))}try{let O=await a0().initialize(process.cwd(),$.pluginDir||[]);if($.debug&&O.plugins.length>0)console.log(`✓ 已加载 ${O.plugins.length} 个插件: ${O.plugins.map((z)=>z.manifest.name).join(", ")}`);if(O.plugins.length>0){let z=await E4();if($.debug){let{totalCommands:_,totalSkills:B,totalAgents:L,totalMcpServers:w}=z;console.log(` ✓ 已集成: ${_} 命令, ${B} 技能, ${L} 代理, ${w} MCP 服务器`)}}if(O.errors.length>0&&$.debug)for(let z of O.errors)console.warn(`⚠️ 插件加载错误 (${z.path}): ${z.error}`)}catch(F){if($.debug)console.warn("⚠️ 插件系统初始化失败:",v8(F))}mq(async()=>{P0.getInstance().killAll(),await b0.getInstance().disconnectAll(),M$.getInstance().cleanup()}),Y(!0)}),q=eU(async()=>{if($.versionCheckPromise){let W=await $.versionCheckPromise;if(W){X(W),G(!0);return}}await K()});if(QA(()=>{q()},[]),J&&Q)return j6(D6,{children:j6(tU,{versionInfo:Q,onComplete:()=>{G(!1),K()}},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(!Z)return null;return j6(D6,{children:j6(sU,{...$},void 0,!1,void 0,this)},void 0,!1,void 0,this)};var FY=GH(process.argv),JH=FY.indexOf("--debug");if(JH!==-1){let $=FY[JH+1],Z=$&&!$.startsWith("-")?$:!0;V1.setGlobalDebug(Z)}async function zA(){if(process.getuid&&process.getuid()===0)console.error(""),console.error("❌ 请不要使用 sudo 运行 blade"),console.error(""),console.error("原因:"),console.error(" 使用 sudo 会创建属于 root 的配置文件,"),console.error(" 导致普通用户无法访问。"),console.error(""),console.error("正确用法:"),console.error(" blade # 直接运行,不要加 sudo"),console.error(""),console.error("如果遇到权限错误,请运行:"),console.error(" sudo chown -R $USER:$USER ~/.blade/"),console.error(""),process.exit(1);dq();let $=hq();if(await vq())return;if(FY.includes("--acp")){let{runAcpIntegration:Y}=await Promise.resolve().then(() => (XH(),QH));await Y();return}let Z=OA(GH(process.argv)).scriptName(a4.scriptName).usage(a4.usage).version(a4.version).locale(a4.locale).showHelpOnFail(a4.showHelpOnFail).demandCommand(0,"").recommendCommands().strict(a4.strict).parserConfiguration({"populate--":!0}).options(bY).middleware([XQ,JQ,GQ]).command(jQ).command(KQ).command(xq).command(qQ).completion("completion",!1).help("help","Show help").alias("help","h").alias("version","V").fail((Y,Q,X)=>{if(Q)console.error("\uD83D\uDCA5 An error occurred:"),console.error(Q.message),console.error(`
2865
2865
  Stack trace:`),console.error(Q.stack),process.exit(1);if(Y)console.error("❌ Invalid arguments:"),console.error(Y),console.error(`
2866
2866
  \uD83D\uDCA1 Did you mean:`),X.showHelp(),process.exit(1)}).command("$0",!1,()=>{},async(Y)=>{let Q=Y._.slice(1),X=Q.length>0?Q.join(" "):void 0,J={...Y,initialMessage:X,debug:Y.debug,print:Boolean(Y.print),versionCheckPromise:$};delete J._,delete J.$0,delete J.message,HA(FA.createElement($H,J),{patchConsole:!0,exitOnCtrlC:!1,alternateBuffer:!1})});try{await Z.parse()}catch(Y){console.error("❌ Parse error:",Y),process.exit(1)}}if(D0.main==D0.module)zA().catch(console.error);export{zA as main};