blade-code 0.1.9 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blade.js +114 -114
- package/package.json +1 -1
package/dist/blade.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{createRequire as kF}from"node:module";var TF=Object.create;var{getPrototypeOf:EF,defineProperty:p7,getOwnPropertyNames:PF}=Object;var CF=Object.prototype.hasOwnProperty;var m$=($,Z,Y)=>{Y=$!=null?TF(EF($)):{};let Q=Z||!$||!$.__esModule?p7(Y,"default",{value:$,enumerable:!0}):Y;for(let X of PF($))if(!CF.call(Q,X))p7(Q,X,{get:()=>$[X],enumerable:!0});return Q};var SF=($,Z)=>{for(var Y in Z)p7($,Y,{get:Z[Y],enumerable:!0,configurable:!0,set:(Q)=>Z[Y]=()=>Q})};var b=($,Z)=>()=>($&&(Z=$($=0)),Z);var A$=kF(import.meta.url);var u3;var jY=b(()=>{u3={name:"blade-code",version:"0.1.
|
|
2
|
+
import{createRequire as kF}from"node:module";var TF=Object.create;var{getPrototypeOf:EF,defineProperty:p7,getOwnPropertyNames:PF}=Object;var CF=Object.prototype.hasOwnProperty;var m$=($,Z,Y)=>{Y=$!=null?TF(EF($)):{};let Q=Z||!$||!$.__esModule?p7(Y,"default",{value:$,enumerable:!0}):Y;for(let X of PF($))if(!CF.call(Q,X))p7(Q,X,{get:()=>$[X],enumerable:!0});return Q};var SF=($,Z)=>{for(var Y in Z)p7($,Y,{get:Z[Y],enumerable:!0,configurable:!0,set:(Q)=>Z[Y]=()=>Q})};var b=($,Z)=>()=>($&&(Z=$($=0)),Z);var A$=kF(import.meta.url);var u3;var jY=b(()=>{u3={name:"blade-code",version:"0.1.10",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","@ai-sdk/anthropic":"^3.0.7","@ai-sdk/azure":"^3.0.5","@ai-sdk/deepseek":"^2.0.4","@ai-sdk/google":"^3.0.4","@ai-sdk/openai":"^3.0.5","@ai-sdk/openai-compatible":"^2.0.4","@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",ai:"^6.0.39","ansi-escapes":"^7.2.0","async-mutex":"^0.5.0",axios:"^1.12.2",chalk:"^5.4.1",diff:"^8.0.2","fast-glob":"^3.3.3","fuse.js":"^7.1.0","gray-matter":"^4.0.3",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 u4(){return u3.version}function IY(){return u3.name}function yY(){return u3.description}function vY(){return`v${u3.version} © 2025 Blade Code`}var d3=b(()=>{jY()});var G$=()=>{};var d4;var m7=b(()=>{G$();d4={currentModelId:"",models:[],temperature:0,maxContextTokens:128000,maxOutputTokens:void 0,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 EY}from"fs";import{merge as PY}from"lodash-es";import CY from"os";import c3 from"path";class g${static instance=null;constructor(){}static getInstance(){if(!g$.instance)g$.instance=new g$;return g$.instance}static resetInstance(){g$.instance=null}async initialize(){try{let $=await this.loadConfigFiles(),Z=await this.loadSettingsFiles(),Y={...d4,...$,...Z};if(this.resolveEnvInterpolation(Y),Y.debug)console.log("[ConfigManager] Configuration loaded successfully");return Y}catch($){return console.error("[ConfigManager] Failed to initialize:",$),d4}}async loadConfigFiles(){let $=c3.join(CY.homedir(),".blade","config.json"),Z=c3.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 $=c3.join(CY.homedir(),".blade","settings.json"),Z=c3.join(process.cwd(),".blade","settings.json"),Y=c3.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 q=await this.loadJsonFile(Y);if(q)Q=this.mergeSettings(Q,q);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=PY({},Y.hooks,Z.hooks);if(Z.env)Y.env=PY({},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,q,G)=>{return process.env[J]||G||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 EY.readFile($,"utf-8");return JSON.parse(Z)}}catch(Z){console.warn(`[ConfigManager] Failed to load ${$}:`,Z)}return null}async fileExists($){try{return await EY.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,7 +22,7 @@ ${Z.map((Y)=>` - ${Y}`).join(`
|
|
|
22
22
|
}
|
|
23
23
|
]
|
|
24
24
|
}
|
|
25
|
-
`)}}function g7($,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 SY=b(()=>{m7();G$()});import{promises as l4}from"node:fs";import hF from"node:os";import u7 from"node:path";import xF from"pino";async function fY(){if(U1)try{if(typeof U1.flush==="function")U1.flush();await new Promise(($)=>setTimeout($,100))}catch($){console.error("[Logger] 关闭日志系统时出错:",$)}U1=null,c4=null}function hY($){if(d7!==$)d7=$,c7()}async function mF(){try{let $=u7.join(hF.homedir(),".blade","logs");await l4.mkdir($,{recursive:!0,mode:493});try{if((await l4.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 gF($,30);let Y=`blade-${d7||"default"}.log`;return u7.join($,Y)}catch($){return console.error("[Logger] 无法创建日志目录:",$),null}}async function gF($,Z){try{let Y=await l4.readdir($),Q=Date.now(),X=Z*24*60*60*1000;for(let J of Y){if(!J.startsWith("blade-")||!J.endsWith(".log"))continue;let q=u7.join($,J);try{let G=await l4.stat(q);if(Q-G.mtimeMs>X)await l4.unlink(q),console.error(`[Logger] 已清理旧日志: ${J}`)}catch(G){}}}catch(Y){console.error("[Logger] 清理旧日志失败:",Y)}}async function uF(){if(U1)return U1;if(c4)return c4;return c4=(async()=>{try{let $=await mF();if(!$)return console.warn("[Logger] 文件日志已禁用(目录创建失败)"),null;return U1=xF({level:"debug",transport:{target:"pino/file",options:{destination:$}}}),U1}catch($){return console.error("[Logger] Pino 初始化失败:",$),null}})(),c4}function c7(){if(U1&&typeof U1.flush==="function")try{U1.flush()}catch($){}U1=null,c4=null}class y1{static globalDebugConfig=null;enabled;minLevel;category;pinoLogger=null;constructor($={}){if($.enabled!==void 0)this.enabled=$.enabled;else if(y1.globalDebugConfig!==null)this.enabled=Boolean(y1.globalDebugConfig);else this.enabled=!1;this.minLevel=$.minLevel??0,this.category=$.category??"General",this.initPino()}async initPino(){try{let $=await uF();if($)this.pinoLogger=$.child({category:this.category})}catch($){console.error("[Logger] Failed to initialize pino:",$)}}static setGlobalDebug($){y1.globalDebugConfig=$,c7()}static clearGlobalDebug(){y1.globalDebugConfig=null,c7()}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(y1.globalDebugConfig!==null){let{enabled:Z,filter:Y}=this.parseDebugFilter(y1.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=pF[$];this.pinoLogger[Q](Y)}if(this.shouldLogToConsole($)){let Q=kY[$],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 y1({...Z,category:$})}var kY,pF,d7=null,U1=null,c4=null,x0;var z0=b(()=>{((X)=>{X[X.DEBUG=0]="DEBUG";X[X.INFO=1]="INFO";X[X.WARN=2]="WARN";X[X.ERROR=3]="ERROR"})(kY||={});pF={[0]:"debug",[1]:"info",[2]:"warn",[3]:"error"};x0=new y1({category:"General"})});import{Mutex as xY}from"async-mutex";import{merge as dF}from"lodash-es";import{promises as r8}from"node:fs";import pY from"node:os";import y2 from"node:path";import cF from"write-file-atomic";class J2{static instance=null;pendingUpdates=new Map;timers=new Map;fileLocks=new Map;lastSaveError=null;debounceDelay=300;constructor(){}static getInstance(){if(!J2.instance)J2.instance=new J2;return J2.instance}static resetInstance(){if(J2.instance)for(let $ of J2.instance.timers.values())clearTimeout($);J2.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:[]},q={allow:this.dedupeArray([...J.allow||[],$]),ask:J.ask||[],deny:J.deny||[]};return{...X,permissions:q}})}async appendLocalPermissionRule($,Z={}){await this.appendPermissionRule($,{...Z,scope:"local"})}validatePersistableFields($){for(let Z of Object.keys($)){let Y=i4[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=i4[Q];if(!J)continue;let q=Z??J.defaultScope,G=this.resolveFilePath(J.target,q);if(!Y.has(G))Y.set(G,{});Y.get(G)[Q]=X}return Y}resolveFilePath($,Z){if($==="config")return Z==="global"?y2.join(pY.homedir(),".blade","config.json"):y2.join(process.cwd(),".blade","config.json");switch(Z){case"local":return y2.join(process.cwd(),".blade","settings.local.json");case"project":return y2.join(process.cwd(),".blade","settings.json");case"global":return y2.join(pY.homedir(),".blade","settings.json");default:return y2.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 q=this.pendingUpdates.get($);if(q){this.pendingUpdates.delete($),this.timers.delete($);try{await this.flushTarget($,q),this.lastSaveError=null}catch(G){let K=G instanceof Error?G:Error(String(G));this.lastSaveError=K,mY.error(`Failed to save config to ${$}:`,K.message),mY.error("Stack trace:",K.stack)}}},this.debounceDelay);this.timers.set($,J)}mergePendingUpdates($,Z){let Y={...$};for(let[Q,X]of Object.entries(Z)){let J=i4[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 xY,this.fileLocks.set($,Y);await Y.runExclusive(async()=>{await this.performWrite($,Z)})}async flushTargetWithModifier($,Z){let Y=this.fileLocks.get($);if(!Y)Y=new xY,this.fileLocks.set($,Y);await Y.runExclusive(async()=>{await r8.mkdir(y2.dirname($),{recursive:!0,mode:493});let Q={};try{let J=await r8.readFile($,"utf-8");Q=JSON.parse(J)}catch{Q={}}let X=Z(Q);await this.atomicWrite($,X)})}async performWrite($,Z){await r8.mkdir(y2.dirname($),{recursive:!0,mode:493});let Y={};try{let X=await r8.readFile($,"utf-8");Y=JSON.parse(X)}catch{Y={}}let Q={...Y};for(let[X,J]of Object.entries(Z)){let q=i4[X];if(!q){Q[X]=J;continue}switch(q.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]=dF({},Q,Y)}else $[Z]=Y}dedupeArray($){return Array.from(new Set($))}async atomicWrite($,Z){await cF($,JSON.stringify(Z,null,2),{mode:384,encoding:"utf-8"})}}function P$(){return J2.getInstance()}var mY,i4,lR,iR;var gY=b(()=>{z0();mY=l("Service"),i4={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}},lR=new Set(Object.entries(i4).filter(([$,Z])=>Z.persistable).map(([$])=>$)),iR=new Set(Object.entries(i4).filter(([$,Z])=>!Z.persistable).map(([$])=>$))});var a4=b(()=>{SY();gY();m7();G$()});var lF,iF,aF,rF,nF,oF,sF,tF,eF,$O,ZO,YO,QO,q2;var l7=b(()=>{lF={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)"}},iF={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)"}},aF={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)"}},rF={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)"}},nF={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)"}},oF={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)"}},sF={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)"}},tF={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)"}},eF={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)"}},$O={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)"}},ZO={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)"}},YO={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)"}},QO={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)"}},q2=[{id:"ayu-dark",label:"Ayu Dark",theme:lF,tags:["dark","popular"]},{id:"dracula",label:"Dracula",theme:iF,tags:["dark","popular"]},{id:"monokai",label:"Monokai",theme:aF,tags:["dark","classic"]},{id:"nord",label:"Nord",theme:rF,tags:["dark","minimal"]},{id:"solarized-light",label:"Solarized Light",theme:nF,tags:["light"]},{id:"solarized-dark",label:"Solarized Dark",theme:oF,tags:["dark"]},{id:"tokyo-night",label:"Tokyo Night",theme:sF,tags:["dark","popular"]},{id:"github",label:"GitHub",theme:tF,tags:["light","minimal"]},{id:"gruvbox",label:"Gruvbox",theme:eF,tags:["dark","warm"]},{id:"one-dark",label:"One Dark",theme:$O,tags:["dark","popular"]},{id:"catppuccin",label:"Catppuccin",theme:ZO,tags:["dark","pastel"]},{id:"rose-pine",label:"Rose Pine",theme:YO,tags:["dark","elegant"]},{id:"kanagawa",label:"Kanagawa",theme:QO,tags:["dark","japanese"]}]});class dY{currentTheme=i7;themes=new Map;constructor(){this.themes.set("default",i7),this.themes.set("dark",XO);for(let $ of q2)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 uY,i7,XO,u$;var q4=b(()=>{l7();uY={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"}},i7={name:"default",colors:uY,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)"}},XO={...i7,name:"dark",colors:{...uY,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"}}};u$=new dY});var JO,a7=($)=>({...JO,actions:{setInitializationStatus:(Z)=>{$((Y)=>({app:{...Y.app,initializationStatus:Z}}))},setInitializationError:(Z)=>{$((Y)=>({app:{...Y.app,initializationError:Z}}))},setActiveModal:(Z)=>{$((Y)=>({app:{...Y.app,activeModal:Z}}))},showSessionSelector:(Z)=>{$((Y)=>({app:{...Y.app,activeModal:"sessionSelector",sessionSelectorData:Z}}))},showModelEditWizard:(Z)=>{$((Y)=>({app:{...Y.app,activeModal:"modelEditWizard",modelEditorTarget:Z}}))},closeModal:()=>{$((Z)=>({app:{...Z.app,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null}}))},setTodos:(Z)=>{$((Y)=>({app:{...Y.app,todos:Z}}))},updateTodo:(Z)=>{$((Y)=>({app:{...Y.app,todos:Y.app.todos.map((Q)=>Q.id===Z.id?Z:Q)}}))},setAwaitingSecondCtrlC:(Z)=>{$((Y)=>({app:{...Y.app,awaitingSecondCtrlC:Z}}))},setThinkingModeEnabled:(Z)=>{$((Y)=>({app:{...Y.app,thinkingModeEnabled:Z}}))},toggleThinkingMode:()=>{$((Z)=>({app:{...Z.app,thinkingModeEnabled:!Z.app.thinkingModeEnabled}}))},startSubagentProgress:(Z,Y,Q)=>{$((X)=>({app:{...X.app,subagentProgress:{id:Z,type:Y,description:Q,status:"running",startTime:Date.now()}}}))},updateSubagentTool:(Z)=>{$((Y)=>{if(!Y.app.subagentProgress)return Y;return{app:{...Y.app,subagentProgress:{...Y.app.subagentProgress,currentTool:Z}}}})},completeSubagentProgress:(Z)=>{$((Y)=>{if(!Y.app.subagentProgress)return Y;return{app:{...Y.app,subagentProgress:{...Y.app.subagentProgress,status:Z?"completed":"failed",currentTool:void 0}}}}),setTimeout(()=>{$((Y)=>({app:{...Y.app,subagentProgress:null}}))},1500)}}});var cY=b(()=>{JO={initializationStatus:"idle",initializationError:null,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null,todos:[],awaitingSecondCtrlC:!1,thinkingModeEnabled:!1,subagentProgress:null}});var qO,r7=($,Z)=>({...qO,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 lY=b(()=>{qO={isProcessing:!1,abortController:null,pendingCommands:[]}});var GO,n7=($)=>({...GO,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 iY=b(()=>{GO={config:null}});var KO,o7=($)=>({...KO,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 aY=b(()=>{KO={currentFocus:"main-input",previousFocus:null}});function G4($){let Z=[],Y=$.split(/\r?\n/),Q=!1,X=[],J=null,q=0,G=!1,K=[],W=[],U=!1,F=[],O=!0;for(let H=0;H<Y.length;H++){let _=Y[H];if(U){if(_.match(D0.diffEnd)){try{let I=JSON.parse(F.join(`
|
|
25
|
+
`)}}function g7($,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 SY=b(()=>{m7();G$()});import{promises as l4}from"node:fs";import hF from"node:os";import u7 from"node:path";import xF from"pino";async function fY(){if(U1)try{if(typeof U1.flush==="function")U1.flush();await new Promise(($)=>setTimeout($,100))}catch($){console.error("[Logger] 关闭日志系统时出错:",$)}U1=null,c4=null}function hY($){if(d7!==$)d7=$,c7()}async function mF(){try{let $=u7.join(hF.homedir(),".blade","logs");await l4.mkdir($,{recursive:!0,mode:493});try{if((await l4.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 gF($,30);let Y=`blade-${d7||"default"}.log`;return u7.join($,Y)}catch($){return console.error("[Logger] 无法创建日志目录:",$),null}}async function gF($,Z){try{let Y=await l4.readdir($),Q=Date.now(),X=Z*24*60*60*1000;for(let J of Y){if(!J.startsWith("blade-")||!J.endsWith(".log"))continue;let q=u7.join($,J);try{let G=await l4.stat(q);if(Q-G.mtimeMs>X)await l4.unlink(q),console.error(`[Logger] 已清理旧日志: ${J}`)}catch(G){}}}catch(Y){console.error("[Logger] 清理旧日志失败:",Y)}}async function uF(){if(U1)return U1;if(c4)return c4;return c4=(async()=>{try{let $=await mF();if(!$)return console.warn("[Logger] 文件日志已禁用(目录创建失败)"),null;return U1=xF({level:"debug",transport:{target:"pino/file",options:{destination:$}}}),U1}catch($){return console.error("[Logger] Pino 初始化失败:",$),null}})(),c4}function c7(){if(U1&&typeof U1.flush==="function")try{U1.flush()}catch($){}U1=null,c4=null}class y1{static globalDebugConfig=null;enabled;minLevel;category;pinoLogger=null;constructor($={}){if($.enabled!==void 0)this.enabled=$.enabled;else if(y1.globalDebugConfig!==null)this.enabled=Boolean(y1.globalDebugConfig);else this.enabled=!1;this.minLevel=$.minLevel??0,this.category=$.category??"General",this.initPino()}async initPino(){try{let $=await uF();if($)this.pinoLogger=$.child({category:this.category})}catch($){console.error("[Logger] Failed to initialize pino:",$)}}static setGlobalDebug($){y1.globalDebugConfig=$,c7()}static clearGlobalDebug(){y1.globalDebugConfig=null,c7()}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(y1.globalDebugConfig!==null){let{enabled:Z,filter:Y}=this.parseDebugFilter(y1.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=pF[$];this.pinoLogger[Q](Y)}if(this.shouldLogToConsole($)){let Q=kY[$],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 y1({...Z,category:$})}var kY,pF,d7=null,U1=null,c4=null,x0;var z0=b(()=>{((X)=>{X[X.DEBUG=0]="DEBUG";X[X.INFO=1]="INFO";X[X.WARN=2]="WARN";X[X.ERROR=3]="ERROR"})(kY||={});pF={[0]:"debug",[1]:"info",[2]:"warn",[3]:"error"};x0=new y1({category:"General"})});import{Mutex as xY}from"async-mutex";import{merge as dF}from"lodash-es";import{promises as r8}from"node:fs";import pY from"node:os";import y2 from"node:path";import cF from"write-file-atomic";class J2{static instance=null;pendingUpdates=new Map;timers=new Map;fileLocks=new Map;lastSaveError=null;debounceDelay=300;constructor(){}static getInstance(){if(!J2.instance)J2.instance=new J2;return J2.instance}static resetInstance(){if(J2.instance)for(let $ of J2.instance.timers.values())clearTimeout($);J2.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:[]},q={allow:this.dedupeArray([...J.allow||[],$]),ask:J.ask||[],deny:J.deny||[]};return{...X,permissions:q}})}async appendLocalPermissionRule($,Z={}){await this.appendPermissionRule($,{...Z,scope:"local"})}validatePersistableFields($){for(let Z of Object.keys($)){let Y=i4[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=i4[Q];if(!J)continue;let q=Z??J.defaultScope,G=this.resolveFilePath(J.target,q);if(!Y.has(G))Y.set(G,{});Y.get(G)[Q]=X}return Y}resolveFilePath($,Z){if($==="config")return Z==="global"?y2.join(pY.homedir(),".blade","config.json"):y2.join(process.cwd(),".blade","config.json");switch(Z){case"local":return y2.join(process.cwd(),".blade","settings.local.json");case"project":return y2.join(process.cwd(),".blade","settings.json");case"global":return y2.join(pY.homedir(),".blade","settings.json");default:return y2.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 q=this.pendingUpdates.get($);if(q){this.pendingUpdates.delete($),this.timers.delete($);try{await this.flushTarget($,q),this.lastSaveError=null}catch(G){let K=G instanceof Error?G:Error(String(G));this.lastSaveError=K,mY.error(`Failed to save config to ${$}:`,K.message),mY.error("Stack trace:",K.stack)}}},this.debounceDelay);this.timers.set($,J)}mergePendingUpdates($,Z){let Y={...$};for(let[Q,X]of Object.entries(Z)){let J=i4[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 xY,this.fileLocks.set($,Y);await Y.runExclusive(async()=>{await this.performWrite($,Z)})}async flushTargetWithModifier($,Z){let Y=this.fileLocks.get($);if(!Y)Y=new xY,this.fileLocks.set($,Y);await Y.runExclusive(async()=>{await r8.mkdir(y2.dirname($),{recursive:!0,mode:493});let Q={};try{let J=await r8.readFile($,"utf-8");Q=JSON.parse(J)}catch{Q={}}let X=Z(Q);await this.atomicWrite($,X)})}async performWrite($,Z){await r8.mkdir(y2.dirname($),{recursive:!0,mode:493});let Y={};try{let X=await r8.readFile($,"utf-8");Y=JSON.parse(X)}catch{Y={}}let Q={...Y};for(let[X,J]of Object.entries(Z)){let q=i4[X];if(!q){Q[X]=J;continue}switch(q.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]=dF({},Q,Y)}else $[Z]=Y}dedupeArray($){return Array.from(new Set($))}async atomicWrite($,Z){await cF($,JSON.stringify(Z,null,2),{mode:384,encoding:"utf-8"})}}function P$(){return J2.getInstance()}var mY,i4,iR,aR;var gY=b(()=>{z0();mY=l("Service"),i4={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}},iR=new Set(Object.entries(i4).filter(([$,Z])=>Z.persistable).map(([$])=>$)),aR=new Set(Object.entries(i4).filter(([$,Z])=>!Z.persistable).map(([$])=>$))});var a4=b(()=>{SY();gY();m7();G$()});var lF,iF,aF,rF,nF,oF,sF,tF,eF,$O,ZO,YO,QO,q2;var l7=b(()=>{lF={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)"}},iF={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)"}},aF={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)"}},rF={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)"}},nF={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)"}},oF={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)"}},sF={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)"}},tF={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)"}},eF={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)"}},$O={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)"}},ZO={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)"}},YO={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)"}},QO={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)"}},q2=[{id:"ayu-dark",label:"Ayu Dark",theme:lF,tags:["dark","popular"]},{id:"dracula",label:"Dracula",theme:iF,tags:["dark","popular"]},{id:"monokai",label:"Monokai",theme:aF,tags:["dark","classic"]},{id:"nord",label:"Nord",theme:rF,tags:["dark","minimal"]},{id:"solarized-light",label:"Solarized Light",theme:nF,tags:["light"]},{id:"solarized-dark",label:"Solarized Dark",theme:oF,tags:["dark"]},{id:"tokyo-night",label:"Tokyo Night",theme:sF,tags:["dark","popular"]},{id:"github",label:"GitHub",theme:tF,tags:["light","minimal"]},{id:"gruvbox",label:"Gruvbox",theme:eF,tags:["dark","warm"]},{id:"one-dark",label:"One Dark",theme:$O,tags:["dark","popular"]},{id:"catppuccin",label:"Catppuccin",theme:ZO,tags:["dark","pastel"]},{id:"rose-pine",label:"Rose Pine",theme:YO,tags:["dark","elegant"]},{id:"kanagawa",label:"Kanagawa",theme:QO,tags:["dark","japanese"]}]});class dY{currentTheme=i7;themes=new Map;constructor(){this.themes.set("default",i7),this.themes.set("dark",XO);for(let $ of q2)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 uY,i7,XO,u$;var q4=b(()=>{l7();uY={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"}},i7={name:"default",colors:uY,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)"}},XO={...i7,name:"dark",colors:{...uY,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"}}};u$=new dY});var JO,a7=($)=>({...JO,actions:{setInitializationStatus:(Z)=>{$((Y)=>({app:{...Y.app,initializationStatus:Z}}))},setInitializationError:(Z)=>{$((Y)=>({app:{...Y.app,initializationError:Z}}))},setActiveModal:(Z)=>{$((Y)=>({app:{...Y.app,activeModal:Z}}))},showSessionSelector:(Z)=>{$((Y)=>({app:{...Y.app,activeModal:"sessionSelector",sessionSelectorData:Z}}))},showModelEditWizard:(Z)=>{$((Y)=>({app:{...Y.app,activeModal:"modelEditWizard",modelEditorTarget:Z}}))},closeModal:()=>{$((Z)=>({app:{...Z.app,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null}}))},setTodos:(Z)=>{$((Y)=>({app:{...Y.app,todos:Z}}))},updateTodo:(Z)=>{$((Y)=>({app:{...Y.app,todos:Y.app.todos.map((Q)=>Q.id===Z.id?Z:Q)}}))},setAwaitingSecondCtrlC:(Z)=>{$((Y)=>({app:{...Y.app,awaitingSecondCtrlC:Z}}))},setThinkingModeEnabled:(Z)=>{$((Y)=>({app:{...Y.app,thinkingModeEnabled:Z}}))},toggleThinkingMode:()=>{$((Z)=>({app:{...Z.app,thinkingModeEnabled:!Z.app.thinkingModeEnabled}}))},startSubagentProgress:(Z,Y,Q)=>{$((X)=>({app:{...X.app,subagentProgress:{id:Z,type:Y,description:Q,status:"running",startTime:Date.now()}}}))},updateSubagentTool:(Z)=>{$((Y)=>{if(!Y.app.subagentProgress)return Y;return{app:{...Y.app,subagentProgress:{...Y.app.subagentProgress,currentTool:Z}}}})},completeSubagentProgress:(Z)=>{$((Y)=>{if(!Y.app.subagentProgress)return Y;return{app:{...Y.app,subagentProgress:{...Y.app.subagentProgress,status:Z?"completed":"failed",currentTool:void 0}}}}),setTimeout(()=>{$((Y)=>({app:{...Y.app,subagentProgress:null}}))},1500)}}});var cY=b(()=>{JO={initializationStatus:"idle",initializationError:null,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null,todos:[],awaitingSecondCtrlC:!1,thinkingModeEnabled:!1,subagentProgress:null}});var qO,r7=($,Z)=>({...qO,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 lY=b(()=>{qO={isProcessing:!1,abortController:null,pendingCommands:[]}});var GO,n7=($)=>({...GO,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 iY=b(()=>{GO={config:null}});var KO,o7=($)=>({...KO,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 aY=b(()=>{KO={currentFocus:"main-input",previousFocus:null}});function G4($){let Z=[],Y=$.split(/\r?\n/),Q=!1,X=[],J=null,q=0,G=!1,K=[],W=[],U=!1,F=[],O=!0;for(let H=0;H<Y.length;H++){let _=Y[H];if(U){if(_.match(D0.diffEnd)){try{let I=JSON.parse(F.join(`
|
|
26
26
|
`));Z.push({type:"diff",content:"",diffData:{patch:I.patch,startLine:I.startLine,matchLine:I.matchLine}})}catch(I){Z.push({type:"text",content:F.join(`
|
|
27
27
|
`)})}U=!1,F=[],O=!1;continue}F.push(_);continue}if(_.match(D0.diffStart)){U=!0,F=[],O=!1;continue}if(Q){let I=_.match(D0.codeBlock),N=_.trim()==="```";if(I&&I[1])q++,X.push(_);else if(N)if(q>0)q--,X.push(_);else{let P=X.join(`
|
|
28
28
|
`);if(J?.toLowerCase()==="markdown"||J?.toLowerCase()==="md"){let m=G4(P);Z.push(...m)}else Z.push({type:"code",content:P,language:J||void 0});Q=!1,X=[],J=null,q=0,O=!1}else X.push(_);continue}let z=_.match(D0.codeBlock);if(z){Q=!0,J=z[1]||null,q=0,O=!1;continue}let w=_.match(D0.table),B=_.match(D0.tableSeparator);if(w&&!G){if(H+1<Y.length){if(Y[H+1].match(D0.tableSeparator)){G=!0,K=w[1].split("|").map((N)=>N.trim()).filter((N)=>N.length>0),W=[],O=!1;continue}}}if(G&&B)continue;if(G&&w){let I=w[1].split("|").map((N)=>N.trim()).filter((N)=>N.length>0);while(I.length<K.length)I.push("");if(I.length>K.length)I.length=K.length;W.push(I);continue}if(G&&!w){if(K.length>0&&W.length>0)Z.push({type:"table",content:"",tableData:{headers:K,rows:W}});G=!1,K=[],W=[]}let L=_.match(D0.heading);if(L){Z.push({type:"heading",content:L[2],level:L[1].length}),O=!1;continue}let V=_.match(D0.ulItem);if(V){Z.push({type:"list",content:V[3],listType:"ul",marker:V[2],indentation:V[1].length}),O=!1;continue}let D=_.match(D0.olItem);if(D){Z.push({type:"list",content:D[3],listType:"ol",marker:D[2],indentation:D[1].length}),O=!1;continue}if(_.match(D0.hr)){Z.push({type:"hr",content:""}),O=!1;continue}if(_.trim().length===0){if(!O)Z.push({type:"empty",content:""}),O=!0;continue}let y=_.match(D0.commandMessage);if(y){Z.push({type:"command-message",content:y[1]}),O=!1;continue}Z.push({type:"text",content:_}),O=!1}if(Q){let H=X.join(`
|
|
@@ -127,7 +127,7 @@ ${U}`,metadata:{serverName:Z,toolName:Y.name,mcpResult:K}}}catch(K){return{succe
|
|
|
127
127
|
</html>
|
|
128
128
|
`),Q.close(),Z(G)}catch(q){Q.close(),Y(q)}});Q.on("error",Y),Q.listen(o3,()=>{console.log(`[OAuth] Callback server listening on port ${o3}`)}),setTimeout(()=>{Q.close(),Y(Error("OAuth callback timeout"))},300000)})}async exchangeCodeForToken($,Z,Y){let Q=$.redirectUri||`http://localhost:${o3}${H9}`,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 q=await J.text();throw Error(`Token exchange failed: ${J.status} - ${q}`)}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(K){console.warn("[OAuth] Failed to open browser automatically:",K)}let J=await X;console.log("[OAuth] Authorization code received, exchanging for tokens...");let q=await this.exchangeCodeForToken(Z,J,Y.codeVerifier),G={accessToken:q.access_token,tokenType:q.token_type||"Bearer",refreshToken:q.refresh_token,scope:q.scope};if(q.expires_in)G.expiresAt=Date.now()+q.expires_in*1000;return await this.tokenStorage.saveToken($,G,Z.clientId,Z.tokenUrl),console.log("[OAuth] Authentication successful! Token saved."),G}async openAuthorizationUrl($){let{command:Z,args:Y}=this.getBrowserCommand($);await new Promise((Q,X)=>{let J=IO(Z,Y,{stdio:"ignore"});J.once("error",X),J.once("close",(q)=>{if(q===0||q===null)Q();else X(Error(`Failed to open browser (exit code ${q})`))})})}getBrowserCommand($){if(process.platform==="darwin")return{command:"open",args:[$]};if(process.platform==="win32")return{command:"cmd",args:["/c","start","",$]};return{command:"xdg-open",args:[$]}}async getValidToken($,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 o3=7777,H9="/oauth/callback",yQ=200;var TQ=b(()=>{jQ()});var EQ=b(()=>{TQ()});var o4=()=>{};import{EventEmitter as yO}from"events";var _9;var PQ=b(()=>{o4();_9=class _9 extends yO{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 vO}from"@modelcontextprotocol/sdk/client/index.js";import{SSEClientTransport as TO}from"@modelcontextprotocol/sdk/client/sse.js";import{StdioClientTransport as EO}from"@modelcontextprotocol/sdk/client/stdio.js";import{EventEmitter as PO}from"events";function CQ($){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 z9;var SQ=b(()=>{d3();EQ();PQ();o4();z9=class z9 extends PO{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 t8;if(Y?.enabled)this.healthMonitor=new _9(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=CQ(X);if(!J.isRetryable)throw console.error("[McpClient] 检测到永久性错误,放弃重试:",J.type),X;if(Q<$){let q=Z*Math.pow(2,Q-1);console.warn(`[McpClient] 连接失败(${Q}/${$}),${q}ms 后重试...`),await new Promise((G)=>setTimeout(G,q))}}throw Y||Error("连接失败")}async doConnect(){try{this.setStatus("connecting"),this.sdkClient=new vO({name:IY(),version:u4()},{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),CQ(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:q}=this.config,G={...J};if(q?.enabled&&this.oauthProvider&&($==="sse"||$==="http"))try{let K=await this.oauthProvider.getValidToken(this.serverName,q);if(!K){console.log(`[McpClient] 服务器 "${this.serverName}" 需要 OAuth 认证`);let W=await this.oauthProvider.authenticate(this.serverName,q);G.Authorization=`Bearer ${W.accessToken}`}else G.Authorization=`Bearer ${K}`}catch(K){throw console.error("[McpClient] OAuth 认证失败:",K),Error(`OAuth 认证失败: ${K instanceof Error?K.message:String(K)}`)}if($==="stdio"){if(!Z)throw Error("stdio 传输需要 command 参数");let K={};for(let[W,U]of Object.entries(process.env))if(U!==void 0)K[W]=U;return new EO({command:Z,args:Y||[],env:{...K,...Q},stderr:"ignore"})}else if($==="sse"){if(!X)throw Error("sse 传输需要 url 参数");return new TO(new URL(X),{requestInit:{headers:G}})}else if($==="http"){if(!X)throw Error("http 传输需要 url 参数");let{StreamableHTTPClientTransport:K}=await import("@modelcontextprotocol/sdk/client/streamableHttp.js");return new K(new URL(X),{requestInit:{headers:G}})}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 CO}from"events";var w$;var F4=b(()=>{MQ();SQ();o4();w$=class w$ extends CO{static instance=null;servers=new Map;isDiscovering=!1;constructor(){super()}static getInstance(){if(!w$.instance)w$.instance=new w$;return w$.instance}async registerServer($,Z){if(this.servers.has($))throw Error(`MCP服务器 "${$}" 已经注册`);let Y=new z9(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 q=(Z.get(X.name)||0)>1?`${Y}__${X.name}`:X.name,G=s8(Q.client,Y,X,q);$.push(G)}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 s8(Y.client,Z,Q)}return null}getToolsByServer($){let Z=this.servers.get($);if(!Z||Z.status!=="connected")return[];return Z.tools.map((Y)=>s8(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 L9($,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 hQ(){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 w9;var xQ=b(()=>{w9={enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,PreToolUse:[],PostToolUse:[],PostToolUseFailure:[],PermissionRequest:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]}});class N9{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 i1,b9,A9;var t4=b(()=>{((F)=>{F.PreToolUse="PreToolUse";F.PostToolUse="PostToolUse";F.PostToolUseFailure="PostToolUseFailure";F.PermissionRequest="PermissionRequest";F.UserPromptSubmit="UserPromptSubmit";F.SessionStart="SessionStart";F.SessionEnd="SessionEnd";F.Stop="Stop";F.SubagentStop="SubagentStop";F.Notification="Notification";F.Compaction="Compaction"})(i1||={});((Q)=>{Q.Approve="approve";Q.Block="block";Q.Async="async"})(b9||={});((Q)=>{Q.Allow="allow";Q.Deny="deny";Q.Ask="ask"})(A9||={})});import{z as v}from"zod";function pQ($){let Z=KH.safeParse($);if(Z.success)return{success:!0,data:Z.data};return{success:!1,error:Z.error}}var P1,dO,cO,lO,iO,aO,rO,nO,oO,sO,tO,eO,ZM,$H,ZH,YH,QH,XH,JH,qH,GH,KH,WH,UH,FH,R9,OH,E1,YM;var mQ=b(()=>{t4();P1=v.object({hook_event_name:v.nativeEnum(i1),hook_execution_id:v.string(),timestamp:v.string(),project_dir:v.string(),session_id:v.string(),permission_mode:v.enum(["default","autoEdit","yolo","plan"]),_metadata:v.object({blade_version:v.string(),hook_timeout_ms:v.number()}).optional()}),dO=P1.extend({hook_event_name:v.literal("PreToolUse"),tool_name:v.string(),tool_use_id:v.string(),tool_input:v.record(v.unknown())}),cO=P1.extend({hook_event_name:v.literal("PostToolUse"),tool_name:v.string(),tool_use_id:v.string(),tool_input:v.record(v.unknown()),tool_response:v.unknown()}),lO=P1.extend({hook_event_name:v.literal("Stop"),reason:v.string().optional()}),iO=P1.extend({hook_event_name:v.literal("PostToolUseFailure"),tool_name:v.string(),tool_use_id:v.string(),tool_input:v.record(v.unknown()),error:v.string(),error_type:v.string().optional(),is_interrupt:v.boolean(),is_timeout:v.boolean()}),aO=P1.extend({hook_event_name:v.literal("PermissionRequest"),tool_name:v.string(),tool_use_id:v.string(),tool_input:v.record(v.unknown())}),rO=P1.extend({hook_event_name:v.literal("UserPromptSubmit"),user_prompt:v.string(),has_images:v.boolean(),image_count:v.number()}),nO=P1.extend({hook_event_name:v.literal("SessionStart"),is_resume:v.boolean(),resume_session_id:v.string().optional()}),oO=P1.extend({hook_event_name:v.literal("SessionEnd"),reason:v.enum(["user_exit","error","max_turns","idle_timeout","ctrl_c","clear","logout","other"])}),sO=P1.extend({hook_event_name:v.literal("SubagentStop"),agent_type:v.string(),task_description:v.string().optional(),success:v.boolean(),result_summary:v.string().optional(),error:v.string().optional()}),tO=P1.extend({hook_event_name:v.literal("Notification"),notification_type:v.enum(["permission_prompt","idle_prompt","auth_success","elicitation_dialog","info","warning","error"]),title:v.string().optional(),message:v.string()}),eO=P1.extend({hook_event_name:v.literal("Compaction"),trigger:v.enum(["manual","auto"]),messages_before:v.number(),tokens_before:v.number()}),ZM=v.discriminatedUnion("hook_event_name",[dO,cO,lO,iO,aO,rO,nO,oO,sO,tO,eO]),$H=v.object({hookEventName:v.literal("PreToolUse"),permissionDecision:v.nativeEnum(A9).optional(),permissionDecisionReason:v.string().optional(),updatedInput:v.record(v.unknown()).optional()}),ZH=v.object({hookEventName:v.literal("PostToolUse"),additionalContext:v.string().optional(),updatedOutput:v.unknown().optional()}),YH=v.object({hookEventName:v.literal("Stop"),continue:v.boolean().optional(),continueReason:v.string().optional()}),QH=v.object({hookEventName:v.literal("SubagentStop"),continue:v.boolean().optional(),continueReason:v.string().optional(),additionalContext:v.string().optional()}),XH=v.object({hookEventName:v.literal("PermissionRequest"),permissionDecision:v.enum(["approve","deny","ask"]).optional(),permissionDecisionReason:v.string().optional()}),JH=v.object({hookEventName:v.literal("UserPromptSubmit"),updatedPrompt:v.string().optional(),contextInjection:v.string().optional()}),qH=v.object({hookEventName:v.literal("SessionStart"),env:v.record(v.string()).optional()}),GH=v.object({hookEventName:v.literal("Compaction"),blockCompaction:v.boolean().optional(),blockReason:v.string().optional()}),KH=v.object({decision:v.object({behavior:v.nativeEnum(b9)}).optional(),systemMessage:v.string().optional(),hookSpecificOutput:v.discriminatedUnion("hookEventName",[$H,ZH,YH,QH,XH,JH,qH,GH]).optional(),suppressOutput:v.boolean().optional()}),WH=v.object({type:v.literal("command"),command:v.string(),timeout:v.number().positive().optional(),statusMessage:v.string().optional()}),UH=v.object({type:v.literal("prompt"),prompt:v.string(),timeout:v.number().positive().optional()}),FH=v.discriminatedUnion("type",[WH,UH]),R9=v.union([v.string(),v.array(v.string())]),OH=v.object({tools:R9.optional(),paths:R9.optional(),commands:R9.optional()}),E1=v.object({name:v.string().optional(),matcher:OH.optional(),hooks:v.array(FH)}),YM=v.object({enabled:v.boolean().optional(),defaultTimeout:v.number().positive().optional(),timeoutBehavior:v.enum(["ignore","deny","ask"]).optional(),failureBehavior:v.enum(["ignore","deny","ask"]).optional(),maxConcurrentHooks:v.number().positive().optional(),PreToolUse:v.array(E1).optional(),PostToolUse:v.array(E1).optional(),PostToolUseFailure:v.array(E1).optional(),PermissionRequest:v.array(E1).optional(),UserPromptSubmit:v.array(E1).optional(),SessionStart:v.array(E1).optional(),SessionEnd:v.array(E1).optional(),Stop:v.array(E1).optional(),SubagentStop:v.array(E1).optional(),Notification:v.array(E1).optional(),Compaction:v.array(E1).optional()})});class V9{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=pQ(Q);if(!X.success){let q="error"in X?X.error.message:"Unknown validation error",G=Y?.failureBehavior||"ignore",K=`Invalid hook output JSON: ${q}`;if(G==="deny")return{success:!1,blocking:!0,error:K,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else if(G==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${K}. Continue?`,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else return{success:!1,blocking:!1,warning:K,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z}}let J=X.data;if(J.decision?.behavior==="block")return{success:!1,blocking:!0,error:J.systemMessage||"Hook blocked execution",output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};if(J.decision?.behavior==="async")return{success:!0,output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};return{success:!0,output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z}}return this.parseByExitCode($,Z,Y)}parseByExitCode($,Z,Y){let Q=$.exitCode;switch(Q){case 0:return{success:!0,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};case 2:return{success:!1,blocking:!0,error:$.stderr||$.stdout||"Hook returned exit code 2",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};case 124:{let X=Y?.timeoutBehavior||"ignore",J="Hook timeout";if(X==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z}}default:{let X=Y?.failureBehavior||"ignore",J=$.stderr||$.stdout||`Hook failed with exit code ${Q}`;if(X==="deny")return{success:!1,blocking:!0,error:J,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${J}. Continue?`,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else return{success:!1,blocking:!1,warning:J,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z}}}}tryParseJSON($){try{let Z=$.trim();if(!Z)return null;let Y=Z.match(/^\s*(\{[\s\S]*\})\s*$/);if(!Y)return null;return JSON.parse(Y[1])}catch{return null}}}var gQ=b(()=>{mQ()});import{spawn as HH}from"child_process";class D9{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 M9{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),q=HH($,[],{shell:!0,env:J,cwd:Y.projectDir,timeout:Q}),G=new D9(this.MAX_STDOUT_SIZE),K=new D9(this.MAX_STDERR_SIZE);q.stdout.setEncoding("utf8"),q.stderr.setEncoding("utf8"),q.stdout.on("data",(W)=>{G.append(W)}),q.stderr.on("data",(W)=>{K.append(W)});try{q.stdin.write(X),q.stdin.end()}catch(W){throw q.kill("SIGTERM"),Error(`Failed to write hook input: ${W}`)}return new Promise((W,U)=>{let F=!1,O=!1,H=null,_=()=>{if(H&&Y.abortSignal)Y.abortSignal.removeEventListener("abort",H),H=null},z=setTimeout(()=>{F=!0,q.kill("SIGKILL")},Q);if(q.on("close",(w)=>{if(O)return;O=!0,clearTimeout(z),_(),W({stdout:G.getContent(),stderr:K.getContent(),exitCode:F?124:w??1,timedOut:F})}),q.on("error",(w)=>{if(O)return;O=!0,clearTimeout(z),_(),U(w)}),Y.abortSignal)H=()=>{if(O)return;O=!0,clearTimeout(z),_(),q.kill("SIGTERM"),W({stdout:G.getContent(),stderr:"Hook cancelled by abort signal",exitCode:1,timedOut:!1})},Y.abortSignal.addEventListener("abort",H)})}createSafeEnv($){return{BLADE_PROJECT_DIR:$.project_dir,BLADE_SESSION_ID:$.session_id,BLADE_HOOK_EVENT:$.hook_event_name,BLADE_TOOL_NAME:"tool_name"in $?$.tool_name:"",BLADE_TOOL_USE_ID:"tool_use_id"in $?$.tool_use_id:"",PATH:process.env.PATH||"",HOME:process.env.HOME||"",USER:process.env.USER||"",SHELL:process.env.SHELL||"/bin/sh"}}}var uQ=()=>{};class j9{processExecutor=new M9;outputParser=new V9;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 q={...Z,...Q&&{tool_input:Q}},G=await this.executeHook(J,q,Y);if(!G.success){if(G.blocking)return{decision:"deny",reason:G.error};if(G.needsConfirmation)return{decision:"ask",reason:G.warning||G.error};if(G.warning)X.push(G.warning);continue}let K=G.output?.hookSpecificOutput;if(K&&"permissionDecision"in K){switch(K.permissionDecision){case"deny":return{decision:"deny",reason:K.permissionDecisionReason};case"ask":return{decision:"ask",reason:K.permissionDecisionReason};case"allow":break}if("updatedInput"in K&&K.updatedInput)Q={...Q,...K.updatedInput}}}catch(q){let G=q instanceof Error?q.message:String(q);if(X.push(`Hook failed: ${G}`),Y.config.failureBehavior==="deny")return{decision:"deny",reason:G};else if(Y.config.failureBehavior==="ask")return{decision:"ask",reason:`Hook failed: ${G}. 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(K){console.warn("[OAuth] Failed to open browser automatically:",K)}let J=await X;console.log("[OAuth] Authorization code received, exchanging for tokens...");let q=await this.exchangeCodeForToken(Z,J,Y.codeVerifier),G={accessToken:q.access_token,tokenType:q.token_type||"Bearer",refreshToken:q.refresh_token,scope:q.scope};if(q.expires_in)G.expiresAt=Date.now()+q.expires_in*1000;return await this.tokenStorage.saveToken($,G,Z.clientId,Z.tokenUrl),console.log("[OAuth] Authentication successful! Token saved."),G}async openAuthorizationUrl($){let{command:Z,args:Y}=this.getBrowserCommand($);await new Promise((Q,X)=>{let J=IO(Z,Y,{stdio:"ignore"});J.once("error",X),J.once("close",(q)=>{if(q===0||q===null)Q();else X(Error(`Failed to open browser (exit code ${q})`))})})}getBrowserCommand($){if(process.platform==="darwin")return{command:"open",args:[$]};if(process.platform==="win32")return{command:"cmd",args:["/c","start","",$]};return{command:"xdg-open",args:[$]}}async getValidToken($,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 o3=7777,H9="/oauth/callback",yQ=200;var TQ=b(()=>{jQ()});var EQ=b(()=>{TQ()});var o4=()=>{};import{EventEmitter as yO}from"events";var _9;var PQ=b(()=>{o4();_9=class _9 extends yO{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 vO}from"@modelcontextprotocol/sdk/client/index.js";import{SSEClientTransport as TO}from"@modelcontextprotocol/sdk/client/sse.js";import{StdioClientTransport as EO}from"@modelcontextprotocol/sdk/client/stdio.js";import{EventEmitter as PO}from"events";function CQ($){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 z9;var SQ=b(()=>{d3();EQ();PQ();o4();z9=class z9 extends PO{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 t8;if(Y?.enabled)this.healthMonitor=new _9(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=CQ(X);if(!J.isRetryable)throw console.error("[McpClient] 检测到永久性错误,放弃重试:",J.type),X;if(Q<$){let q=Z*Math.pow(2,Q-1);console.warn(`[McpClient] 连接失败(${Q}/${$}),${q}ms 后重试...`),await new Promise((G)=>setTimeout(G,q))}}throw Y||Error("连接失败")}async doConnect(){try{this.setStatus("connecting"),this.sdkClient=new vO({name:IY(),version:u4()},{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),CQ(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:q}=this.config,G={...J};if(q?.enabled&&this.oauthProvider&&($==="sse"||$==="http"))try{let K=await this.oauthProvider.getValidToken(this.serverName,q);if(!K){console.log(`[McpClient] 服务器 "${this.serverName}" 需要 OAuth 认证`);let W=await this.oauthProvider.authenticate(this.serverName,q);G.Authorization=`Bearer ${W.accessToken}`}else G.Authorization=`Bearer ${K}`}catch(K){throw console.error("[McpClient] OAuth 认证失败:",K),Error(`OAuth 认证失败: ${K instanceof Error?K.message:String(K)}`)}if($==="stdio"){if(!Z)throw Error("stdio 传输需要 command 参数");let K={};for(let[W,U]of Object.entries(process.env))if(U!==void 0)K[W]=U;return new EO({command:Z,args:Y||[],env:{...K,...Q},stderr:"ignore"})}else if($==="sse"){if(!X)throw Error("sse 传输需要 url 参数");return new TO(new URL(X),{requestInit:{headers:G}})}else if($==="http"){if(!X)throw Error("http 传输需要 url 参数");let{StreamableHTTPClientTransport:K}=await import("@modelcontextprotocol/sdk/client/streamableHttp.js");return new K(new URL(X),{requestInit:{headers:G}})}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 CO}from"events";var w$;var F4=b(()=>{MQ();SQ();o4();w$=class w$ extends CO{static instance=null;servers=new Map;isDiscovering=!1;constructor(){super()}static getInstance(){if(!w$.instance)w$.instance=new w$;return w$.instance}async registerServer($,Z){if(this.servers.has($))throw Error(`MCP服务器 "${$}" 已经注册`);let Y=new z9(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 q=(Z.get(X.name)||0)>1?`${Y}__${X.name}`:X.name,G=s8(Q.client,Y,X,q);$.push(G)}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 s8(Y.client,Z,Q)}return null}getToolsByServer($){let Z=this.servers.get($);if(!Z||Z.status!=="connected")return[];return Z.tools.map((Y)=>s8(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 L9($,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 hQ(){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 w9;var xQ=b(()=>{w9={enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,PreToolUse:[],PostToolUse:[],PostToolUseFailure:[],PermissionRequest:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]}});class N9{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 i1,b9,A9;var t4=b(()=>{((F)=>{F.PreToolUse="PreToolUse";F.PostToolUse="PostToolUse";F.PostToolUseFailure="PostToolUseFailure";F.PermissionRequest="PermissionRequest";F.UserPromptSubmit="UserPromptSubmit";F.SessionStart="SessionStart";F.SessionEnd="SessionEnd";F.Stop="Stop";F.SubagentStop="SubagentStop";F.Notification="Notification";F.Compaction="Compaction"})(i1||={});((Q)=>{Q.Approve="approve";Q.Block="block";Q.Async="async"})(b9||={});((Q)=>{Q.Allow="allow";Q.Deny="deny";Q.Ask="ask"})(A9||={})});import{z as v}from"zod";function pQ($){let Z=KH.safeParse($);if(Z.success)return{success:!0,data:Z.data};return{success:!1,error:Z.error}}var P1,dO,cO,lO,iO,aO,rO,nO,oO,sO,tO,eO,YM,$H,ZH,YH,QH,XH,JH,qH,GH,KH,WH,UH,FH,R9,OH,E1,QM;var mQ=b(()=>{t4();P1=v.object({hook_event_name:v.nativeEnum(i1),hook_execution_id:v.string(),timestamp:v.string(),project_dir:v.string(),session_id:v.string(),permission_mode:v.enum(["default","autoEdit","yolo","plan"]),_metadata:v.object({blade_version:v.string(),hook_timeout_ms:v.number()}).optional()}),dO=P1.extend({hook_event_name:v.literal("PreToolUse"),tool_name:v.string(),tool_use_id:v.string(),tool_input:v.record(v.unknown())}),cO=P1.extend({hook_event_name:v.literal("PostToolUse"),tool_name:v.string(),tool_use_id:v.string(),tool_input:v.record(v.unknown()),tool_response:v.unknown()}),lO=P1.extend({hook_event_name:v.literal("Stop"),reason:v.string().optional()}),iO=P1.extend({hook_event_name:v.literal("PostToolUseFailure"),tool_name:v.string(),tool_use_id:v.string(),tool_input:v.record(v.unknown()),error:v.string(),error_type:v.string().optional(),is_interrupt:v.boolean(),is_timeout:v.boolean()}),aO=P1.extend({hook_event_name:v.literal("PermissionRequest"),tool_name:v.string(),tool_use_id:v.string(),tool_input:v.record(v.unknown())}),rO=P1.extend({hook_event_name:v.literal("UserPromptSubmit"),user_prompt:v.string(),has_images:v.boolean(),image_count:v.number()}),nO=P1.extend({hook_event_name:v.literal("SessionStart"),is_resume:v.boolean(),resume_session_id:v.string().optional()}),oO=P1.extend({hook_event_name:v.literal("SessionEnd"),reason:v.enum(["user_exit","error","max_turns","idle_timeout","ctrl_c","clear","logout","other"])}),sO=P1.extend({hook_event_name:v.literal("SubagentStop"),agent_type:v.string(),task_description:v.string().optional(),success:v.boolean(),result_summary:v.string().optional(),error:v.string().optional()}),tO=P1.extend({hook_event_name:v.literal("Notification"),notification_type:v.enum(["permission_prompt","idle_prompt","auth_success","elicitation_dialog","info","warning","error"]),title:v.string().optional(),message:v.string()}),eO=P1.extend({hook_event_name:v.literal("Compaction"),trigger:v.enum(["manual","auto"]),messages_before:v.number(),tokens_before:v.number()}),YM=v.discriminatedUnion("hook_event_name",[dO,cO,lO,iO,aO,rO,nO,oO,sO,tO,eO]),$H=v.object({hookEventName:v.literal("PreToolUse"),permissionDecision:v.nativeEnum(A9).optional(),permissionDecisionReason:v.string().optional(),updatedInput:v.record(v.unknown()).optional()}),ZH=v.object({hookEventName:v.literal("PostToolUse"),additionalContext:v.string().optional(),updatedOutput:v.unknown().optional()}),YH=v.object({hookEventName:v.literal("Stop"),continue:v.boolean().optional(),continueReason:v.string().optional()}),QH=v.object({hookEventName:v.literal("SubagentStop"),continue:v.boolean().optional(),continueReason:v.string().optional(),additionalContext:v.string().optional()}),XH=v.object({hookEventName:v.literal("PermissionRequest"),permissionDecision:v.enum(["approve","deny","ask"]).optional(),permissionDecisionReason:v.string().optional()}),JH=v.object({hookEventName:v.literal("UserPromptSubmit"),updatedPrompt:v.string().optional(),contextInjection:v.string().optional()}),qH=v.object({hookEventName:v.literal("SessionStart"),env:v.record(v.string()).optional()}),GH=v.object({hookEventName:v.literal("Compaction"),blockCompaction:v.boolean().optional(),blockReason:v.string().optional()}),KH=v.object({decision:v.object({behavior:v.nativeEnum(b9)}).optional(),systemMessage:v.string().optional(),hookSpecificOutput:v.discriminatedUnion("hookEventName",[$H,ZH,YH,QH,XH,JH,qH,GH]).optional(),suppressOutput:v.boolean().optional()}),WH=v.object({type:v.literal("command"),command:v.string(),timeout:v.number().positive().optional(),statusMessage:v.string().optional()}),UH=v.object({type:v.literal("prompt"),prompt:v.string(),timeout:v.number().positive().optional()}),FH=v.discriminatedUnion("type",[WH,UH]),R9=v.union([v.string(),v.array(v.string())]),OH=v.object({tools:R9.optional(),paths:R9.optional(),commands:R9.optional()}),E1=v.object({name:v.string().optional(),matcher:OH.optional(),hooks:v.array(FH)}),QM=v.object({enabled:v.boolean().optional(),defaultTimeout:v.number().positive().optional(),timeoutBehavior:v.enum(["ignore","deny","ask"]).optional(),failureBehavior:v.enum(["ignore","deny","ask"]).optional(),maxConcurrentHooks:v.number().positive().optional(),PreToolUse:v.array(E1).optional(),PostToolUse:v.array(E1).optional(),PostToolUseFailure:v.array(E1).optional(),PermissionRequest:v.array(E1).optional(),UserPromptSubmit:v.array(E1).optional(),SessionStart:v.array(E1).optional(),SessionEnd:v.array(E1).optional(),Stop:v.array(E1).optional(),SubagentStop:v.array(E1).optional(),Notification:v.array(E1).optional(),Compaction:v.array(E1).optional()})});class V9{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=pQ(Q);if(!X.success){let q="error"in X?X.error.message:"Unknown validation error",G=Y?.failureBehavior||"ignore",K=`Invalid hook output JSON: ${q}`;if(G==="deny")return{success:!1,blocking:!0,error:K,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else if(G==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${K}. Continue?`,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else return{success:!1,blocking:!1,warning:K,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z}}let J=X.data;if(J.decision?.behavior==="block")return{success:!1,blocking:!0,error:J.systemMessage||"Hook blocked execution",output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};if(J.decision?.behavior==="async")return{success:!0,output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};return{success:!0,output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z}}return this.parseByExitCode($,Z,Y)}parseByExitCode($,Z,Y){let Q=$.exitCode;switch(Q){case 0:return{success:!0,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};case 2:return{success:!1,blocking:!0,error:$.stderr||$.stdout||"Hook returned exit code 2",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};case 124:{let X=Y?.timeoutBehavior||"ignore",J="Hook timeout";if(X==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z}}default:{let X=Y?.failureBehavior||"ignore",J=$.stderr||$.stdout||`Hook failed with exit code ${Q}`;if(X==="deny")return{success:!1,blocking:!0,error:J,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${J}. Continue?`,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else return{success:!1,blocking:!1,warning:J,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z}}}}tryParseJSON($){try{let Z=$.trim();if(!Z)return null;let Y=Z.match(/^\s*(\{[\s\S]*\})\s*$/);if(!Y)return null;return JSON.parse(Y[1])}catch{return null}}}var gQ=b(()=>{mQ()});import{spawn as HH}from"child_process";class D9{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 M9{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),q=HH($,[],{shell:!0,env:J,cwd:Y.projectDir,timeout:Q}),G=new D9(this.MAX_STDOUT_SIZE),K=new D9(this.MAX_STDERR_SIZE);q.stdout.setEncoding("utf8"),q.stderr.setEncoding("utf8"),q.stdout.on("data",(W)=>{G.append(W)}),q.stderr.on("data",(W)=>{K.append(W)});try{q.stdin.write(X),q.stdin.end()}catch(W){throw q.kill("SIGTERM"),Error(`Failed to write hook input: ${W}`)}return new Promise((W,U)=>{let F=!1,O=!1,H=null,_=()=>{if(H&&Y.abortSignal)Y.abortSignal.removeEventListener("abort",H),H=null},z=setTimeout(()=>{F=!0,q.kill("SIGKILL")},Q);if(q.on("close",(w)=>{if(O)return;O=!0,clearTimeout(z),_(),W({stdout:G.getContent(),stderr:K.getContent(),exitCode:F?124:w??1,timedOut:F})}),q.on("error",(w)=>{if(O)return;O=!0,clearTimeout(z),_(),U(w)}),Y.abortSignal)H=()=>{if(O)return;O=!0,clearTimeout(z),_(),q.kill("SIGTERM"),W({stdout:G.getContent(),stderr:"Hook cancelled by abort signal",exitCode:1,timedOut:!1})},Y.abortSignal.addEventListener("abort",H)})}createSafeEnv($){return{BLADE_PROJECT_DIR:$.project_dir,BLADE_SESSION_ID:$.session_id,BLADE_HOOK_EVENT:$.hook_event_name,BLADE_TOOL_NAME:"tool_name"in $?$.tool_name:"",BLADE_TOOL_USE_ID:"tool_use_id"in $?$.tool_use_id:"",PATH:process.env.PATH||"",HOME:process.env.HOME||"",USER:process.env.USER||"",SHELL:process.env.SHELL||"/bin/sh"}}}var uQ=()=>{};class j9{processExecutor=new M9;outputParser=new V9;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 q={...Z,...Q&&{tool_input:Q}},G=await this.executeHook(J,q,Y);if(!G.success){if(G.blocking)return{decision:"deny",reason:G.error};if(G.needsConfirmation)return{decision:"ask",reason:G.warning||G.error};if(G.warning)X.push(G.warning);continue}let K=G.output?.hookSpecificOutput;if(K&&"permissionDecision"in K){switch(K.permissionDecision){case"deny":return{decision:"deny",reason:K.permissionDecisionReason};case"ask":return{decision:"ask",reason:K.permissionDecisionReason};case"allow":break}if("updatedInput"in K&&K.updatedInput)Q={...Q,...K.updatedInput}}}catch(q){let G=q instanceof Error?q.message:String(q);if(X.push(`Hook failed: ${G}`),Y.config.failureBehavior==="deny")return{decision:"deny",reason:G};else if(Y.config.failureBehavior==="ask")return{decision:"ask",reason:`Hook failed: ${G}. 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=[],q=void 0,G=[];for(let K of X){if(!K.success&&K.warning){G.push(K.warning);continue}let W=K.output?.hookSpecificOutput;if(W&&"additionalContext"in W){if(W.additionalContext)J.push(W.additionalContext);if("updatedOutput"in W&&W.updatedOutput!==void 0)q=W.updatedOutput}}return{additionalContext:J.length>0?J.join(`
|
|
132
132
|
|
|
133
133
|
`):void 0,modifiedOutput:q,warning:G.length>0?G.join(`
|
|
@@ -1841,15 +1841,15 @@ You are a software architect specializing in implementation planning.
|
|
|
1841
1841
|
|
|
1842
1842
|
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 Oq($){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 Hq=b(()=>{G$()});import u5 from"node:fs";import m6 from"node:os";import H2 from"node:path";import mz from"yaml";class _q{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:
|
|
1843
1843
|
${$.map((Y)=>{let Q=!Y.tools||Y.tools.length===0?"All tools":Y.tools.join(", ");return`- ${Y.name}: ${Y.description} (Tools: ${Q})`}).join(`
|
|
1844
|
-
`)}`}loadFromDirectory($,Z){if(!u5.existsSync($))return;let Y=u5.readdirSync($);for(let Q of Y){if(!Q.endsWith(".md"))continue;let X=H2.join($,Q);try{let J=this.parseConfigFile(X,Z);this.subagents.set(J.name,J)}catch(J){d5.warn(`Failed to load subagent config from ${X}:`,J)}}}parseConfigFile($,Z){let Q=u5.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,q=mz.parse(X);if(!q.name||!q.description)throw Error(`Missing required fields (name, description) in ${$}`);let G=J.trim(),K=this.parseStringOrArray(q.tools),W=this.parseStringOrArray(q.skills),U=Oq(q.permissionMode);return{name:q.name,description:q.description,systemPrompt:G,tools:K,color:q.color,configPath:$,model:q.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 $=H2.join(m6.homedir(),".claude","agents");this.loadFromDirectory($,"claude-code-user");let Z=H2.join(process.cwd(),".claude","agents");this.loadFromDirectory(Z,"claude-code-project");let Y=H2.join(m6.homedir(),".blade","agents");this.loadFromDirectory(Y,"blade-user");let Q=H2.join(process.cwd(),".blade","agents");this.loadFromDirectory(Q,"blade-project");let X=this.getAllNames().length;return d5.debug(`\uD83D\uDCE6 Loaded ${X} subagents from standard locations`),X}loadBuiltinAgents(){for(let $ of g5)this.subagents.set($.name,{...$,model:$.model||"inherit",source:"builtin"});d5.debug(`Loaded ${g5.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 H2.join(m6.homedir(),".claude","agents");return H2.join(process.cwd(),".claude","agents")}static getBladeAgentsDir($){if($==="user")return H2.join(m6.homedir(),".blade","agents");return H2.join(process.cwd(),".blade","agents")}}var d5,
|
|
1845
|
-
`)[0]}function dz(){let $=
|
|
1844
|
+
`)}`}loadFromDirectory($,Z){if(!u5.existsSync($))return;let Y=u5.readdirSync($);for(let Q of Y){if(!Q.endsWith(".md"))continue;let X=H2.join($,Q);try{let J=this.parseConfigFile(X,Z);this.subagents.set(J.name,J)}catch(J){d5.warn(`Failed to load subagent config from ${X}:`,J)}}}parseConfigFile($,Z){let Q=u5.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,q=mz.parse(X);if(!q.name||!q.description)throw Error(`Missing required fields (name, description) in ${$}`);let G=J.trim(),K=this.parseStringOrArray(q.tools),W=this.parseStringOrArray(q.skills),U=Oq(q.permissionMode);return{name:q.name,description:q.description,systemPrompt:G,tools:K,color:q.color,configPath:$,model:q.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 $=H2.join(m6.homedir(),".claude","agents");this.loadFromDirectory($,"claude-code-user");let Z=H2.join(process.cwd(),".claude","agents");this.loadFromDirectory(Z,"claude-code-project");let Y=H2.join(m6.homedir(),".blade","agents");this.loadFromDirectory(Y,"blade-user");let Q=H2.join(process.cwd(),".blade","agents");this.loadFromDirectory(Q,"blade-project");let X=this.getAllNames().length;return d5.debug(`\uD83D\uDCE6 Loaded ${X} subagents from standard locations`),X}loadBuiltinAgents(){for(let $ of g5)this.subagents.set($.name,{...$,model:$.model||"inherit",source:"builtin"});d5.debug(`Loaded ${g5.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 H2.join(m6.homedir(),".claude","agents");return H2.join(process.cwd(),".claude","agents")}static getBladeAgentsDir($){if($==="user")return H2.join(m6.homedir(),".blade","agents");return H2.join(process.cwd(),".blade","agents")}}var d5,Z$;var R4=b(()=>{z0();Fq();Hq();d5=l("Agent");Z$=new _q});import{nanoid as gz}from"nanoid";import{z as F3}from"zod";function uz($){let Z=$.message||"Unknown error";if(Z.includes("Too Many Requests")||Z.includes("429")){let Y=$.cause;if(Y?.responseBody)try{let Q=JSON.parse(Y.responseBody);if(Q.message)return Q.message}catch{}return"API 请求过于频繁,请稍后重试"}if(Z.includes("ECONNREFUSED")||Z.includes("ETIMEDOUT"))return"网络连接失败,请检查网络设置";if(Z.includes("401")||Z.includes("Unauthorized"))return"API 认证失败,请检查 API Key 配置";return Z.split(`
|
|
1845
|
+
`)[0]}function dz($){return Z$.getAllNames().includes($)}function cz(){let $=Z$.getAllNames();return $.length>0?$.join(", "):"none (registry not initialized)"}function lz(){return`
|
|
1846
1846
|
## Task
|
|
1847
1847
|
|
|
1848
1848
|
Launch a new agent to handle complex, multi-step tasks autonomously.
|
|
1849
1849
|
|
|
1850
1850
|
The Task tool launches specialized agents (subprocesses) that autonomously handle complex tasks. Each agent type has specific capabilities and tools available to it.
|
|
1851
1851
|
|
|
1852
|
-
${
|
|
1852
|
+
${Z$.getDescriptionsForPrompt()}
|
|
1853
1853
|
|
|
1854
1854
|
When using the Task tool, you must specify a subagent_type parameter to select which agent type to use.
|
|
1855
1855
|
|
|
@@ -1873,13 +1873,13 @@ Usage notes:
|
|
|
1873
1873
|
- Clearly tell the agent whether you expect it to write code or just to do research (search, file reads, web fetches, etc.), since it is not aware of the user's intent
|
|
1874
1874
|
- If the agent description mentions that it should be used proactively, then you should try your best to use it without the user having to ask for it first. Use your judgement.
|
|
1875
1875
|
- If the user specifies that they want you to run agents "in parallel", you MUST send a single message with multiple Task tool use content blocks. For example, if you need to launch both a code-reviewer agent and a test-runner agent in parallel, send a single message with both tool calls.
|
|
1876
|
-
`.trim()}function
|
|
1876
|
+
`.trim()}function iz($,Z,Y,Q){let J=Q1.getInstance().startBackgroundAgent({config:$,description:Z,prompt:Y,parentSessionId:Q.sessionId,permissionMode:Q.permissionMode});return{success:!0,llmContent:{agent_id:J,status:"running",message:`Agent started in background. Use TaskOutput(task_id: "${J}") to retrieve results.`},displayContent:`\uD83D\uDE80 后台 Agent 已启动
|
|
1877
1877
|
|
|
1878
1878
|
`+`Agent ID: ${J}
|
|
1879
1879
|
`+`类型: ${$.name}
|
|
1880
1880
|
`+`任务: ${Z}
|
|
1881
1881
|
|
|
1882
|
-
`+"\uD83D\uDCA1 使用 TaskOutput 工具获取结果",metadata:{agent_id:J,subagent_type:$.name,description:Z,background:!0}}}function
|
|
1882
|
+
`+"\uD83D\uDCA1 使用 TaskOutput 工具获取结果",metadata:{agent_id:J,subagent_type:$.name,description:Z,background:!0}}}function az($,Z,Y,Q,X){let J=Q1.getInstance();if(!J.getAgent($))return{success:!1,llmContent:`Cannot resume agent ${$}: session not found`,displayContent:`❌ 无法恢复 Agent: ${$}
|
|
1883
1883
|
|
|
1884
1884
|
会话不存在或已过期`,error:{type:"execution_error",message:`Agent session not found: ${$}`}};if(J.isRunning($))return{success:!1,llmContent:`Cannot resume agent ${$}: still running`,displayContent:`❌ 无法恢复 Agent: ${$}
|
|
1885
1885
|
|
|
@@ -1890,9 +1890,9 @@ Agent 仍在运行中,请使用 TaskOutput 获取结果`,error:{type:"executio
|
|
|
1890
1890
|
`+`类型: ${Y.name}
|
|
1891
1891
|
`+`任务: ${Q}
|
|
1892
1892
|
|
|
1893
|
-
`+"\uD83D\uDCA1 使用 TaskOutput 工具获取结果",metadata:{agent_id:G,resumed_from:$,subagent_type:Y.name,description:Q,background:!0}}}var c5;var zq=b(()=>{p6();Uq();R4();G$();t$();T0();S0();V$();c5=t({name:"Task",displayName:"Subagent Scheduler",kind:"readonly",isReadOnly:!0,schema:F3.object({subagent_type:F3.
|
|
1893
|
+
`+"\uD83D\uDCA1 使用 TaskOutput 工具获取结果",metadata:{agent_id:G,resumed_from:$,subagent_type:Y.name,description:Q,background:!0}}}var c5;var zq=b(()=>{p6();Uq();R4();G$();t$();T0();S0();V$();c5=t({name:"Task",displayName:"Subagent Scheduler",kind:"readonly",isReadOnly:!0,schema:F3.object({subagent_type:F3.string().refine(dz,($)=>({message:`Invalid subagent type: "${$}". Available: ${cz()}`})).describe('Subagent type to use (e.g., "Explore", "Plan")'),description:F3.string().min(3).max(100).describe("Short task description (3-5 words)"),prompt:F3.string().min(10).describe("Detailed task instructions"),run_in_background:F3.boolean().default(!1).describe("Set to true to run this agent in the background. Use TaskOutput to read the output later."),resume:F3.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 lz()},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:q}=$,{updateOutput:G}=Z;try{let K=Z$.getAllNames(),W=Z$.getSubagent(Y);if(!W)return{success:!1,llmContent:`Unknown subagent type: ${Y}. Available types: ${K.join(", ")||"none"}`,displayContent:`❌ 未知的 subagent 类型: ${Y}
|
|
1894
1894
|
|
|
1895
|
-
可用类型: ${K.join(", ")||"无"}`,error:{type:"execution_error",message:`Unknown subagent type: ${Y}`}};if(q)return
|
|
1895
|
+
可用类型: ${K.join(", ")||"无"}`,error:{type:"execution_error",message:`Unknown subagent type: ${Y}`}};if(q)return az(q,X,W,Q,Z);if(J)return iz(W,Q,X,Z);G?.(`\uD83D\uDE80 启动 ${Y} subagent: ${Q}`);let U=new m5(W),F=gz(8);T1.getState().app.actions.startSubagentProgress(F,Y,Q);let O={prompt:X,parentSessionId:Z.sessionId,permissionMode:Z.permissionMode,onToolStart:(w)=>{T1.getState().app.actions.updateSubagentTool(w)}};G?.("⚙️ 执行任务中...");let H=Date.now(),_=await U.execute(O),z=Date.now()-H;try{let B=await R0.getInstance().executeSubagentStopHooks(Y,{projectDir:process.cwd(),sessionId:Z.sessionId||"unknown",permissionMode:Z.permissionMode||"default",taskDescription:Q,success:_.success,resultSummary:_.message.slice(0,500),error:_.error});if(!B.shouldStop&&B.continueReason){console.log(`[Task] SubagentStop hook 阻止停止,继续执行: ${B.continueReason}`);let L={prompt:B.continueReason,parentSessionId:Z.sessionId,permissionMode:Z.permissionMode},V=Date.now();_=await U.execute(L),z+=Date.now()-V}if(B.warning)console.warn(`[Task] SubagentStop hook warning: ${B.warning}`)}catch(w){console.warn("[Task] SubagentStop hook execution failed:",w)}if(T1.getState().app.actions.completeSubagentProgress(_.success),_.success){let w=_.message.length>1000?_.message.slice(0,1000)+`
|
|
1896
1896
|
...(截断)`:_.message;return{success:!0,llmContent:_.message,displayContent:`✅ Subagent 任务完成
|
|
1897
1897
|
|
|
1898
1898
|
`+`类型: ${Y}
|
|
@@ -1909,7 +1909,7 @@ ${w}`,metadata:{subagent_type:Y,description:Q,duration:z,stats:_.stats}}}else re
|
|
|
1909
1909
|
`+`耗时: ${z}ms
|
|
1910
1910
|
`+`错误: ${_.error}`,error:{type:"execution_error",message:_.error||"Unknown error"}}}catch(K){T1.getState().app.actions.completeSubagentProgress(!1);let W=K,U=uz(W);return{success:!1,llmContent:`Subagent execution error: ${W.message}`,displayContent:`❌ Subagent 执行异常
|
|
1911
1911
|
|
|
1912
|
-
${U}`,error:{type:"execution_error",message:W.message,details:K}}}},version:"4.0.0",category:"Subagent",tags:["task","subagent","delegation","explore","plan"],extractSignatureContent:($)=>`${$.subagent_type}:${$.description}`,abstractPermissionRule:()=>""})});import{z as g6}from"zod";async function Bq($,Z,Y){let Q=y$.getInstance(),X=Q.getProcess($);if(!X)return{success:!1,llmContent:`Shell not found: ${$}`,displayContent:`❌ 未找到 Shell: ${$}`,error:{type:"execution_error",message:"Shell 会话不存在或已清理"}};if(Z&&X.status==="running")await
|
|
1912
|
+
${U}`,error:{type:"execution_error",message:W.message,details:K}}}},version:"4.0.0",category:"Subagent",tags:["task","subagent","delegation","explore","plan"],extractSignatureContent:($)=>`${$.subagent_type}:${$.description}`,abstractPermissionRule:()=>""})});import{z as g6}from"zod";async function Bq($,Z,Y){let Q=y$.getInstance(),X=Q.getProcess($);if(!X)return{success:!1,llmContent:`Shell not found: ${$}`,displayContent:`❌ 未找到 Shell: ${$}`,error:{type:"execution_error",message:"Shell 会话不存在或已清理"}};if(Z&&X.status==="running")await rz($,Y);let J=Q.consumeOutput($);if(!J)return{success:!1,llmContent:`Failed to get output for shell: ${$}`,displayContent:`❌ 获取 Shell 输出失败: ${$}`,error:{type:"execution_error",message:"Failed to consume output"}};let q={task_id:J.id,type:"shell",status:J.status,command:J.command,pid:J.pid,exit_code:J.exitCode,signal:J.signal,started_at:new Date(J.startedAt).toISOString(),finished_at:J.endedAt?new Date(J.endedAt).toISOString():void 0,stdout:J.stdout,stderr:J.stderr},K=`${Lq(J.status)} TaskOutput(${$}) - Shell
|
|
1913
1913
|
`+`状态: ${J.status}
|
|
1914
1914
|
`+`命令: ${J.command}
|
|
1915
1915
|
`+(J.pid?`PID: ${J.pid}
|
|
@@ -1927,7 +1927,7 @@ ${J.stderr}`:"");return{success:!0,llmContent:q,displayContent:K,metadata:q}}asy
|
|
|
1927
1927
|
`:"")+(X.result?.message?`
|
|
1928
1928
|
结果:
|
|
1929
1929
|
${X.result.message}`:"")+(X.result?.error?`
|
|
1930
|
-
错误: ${X.result.error}`:"");return{success:!0,llmContent:J,displayContent:G,metadata:J}}async function
|
|
1930
|
+
错误: ${X.result.error}`:"");return{success:!0,llmContent:J,displayContent:G,metadata:J}}async function rz($,Z){let Y=y$.getInstance(),Q=Date.now();return new Promise((X)=>{let J=setInterval(()=>{let q=Y.getProcess($);if(!q||q.status!=="running"){clearInterval(J),X();return}if(Date.now()-Q>=Z){clearInterval(J),X();return}},100)})}function Lq($){switch($){case"running":return"⏳";case"completed":case"exited":return"✅";case"failed":case"error":return"❌";case"killed":case"cancelled":return"✂️";default:return"❓"}}var l5;var Nq=b(()=>{p6();S0();V$();W3();l5=t({name:"TaskOutput",displayName:"Task Output",kind:"readonly",schema:g6.object({task_id:g6.string().min(1).describe("The task ID to get output from"),block:g6.boolean().default(!0).describe("Whether to wait for completion"),timeout:g6.number().min(0).max(600000).default(30000).describe("Max wait time in ms")}),description:{short:"Retrieves output from a running or completed task",long:`
|
|
1931
1931
|
- Retrieves output from a running or completed task (background shell, agent, or remote session)
|
|
1932
1932
|
- Takes a task_id parameter identifying the task
|
|
1933
1933
|
- Returns the task output along with status information
|
|
@@ -1939,7 +1939,7 @@ ${X.result.message}`:"")+(X.result?.error?`
|
|
|
1939
1939
|
|
|
1940
1940
|
任务 ID 格式:
|
|
1941
1941
|
- bash_xxx: 后台 shell
|
|
1942
|
-
- 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 bq=b(()=>{zq();Nq()});import{randomUUID as
|
|
1942
|
+
- 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 bq=b(()=>{zq();Nq()});import{randomUUID as nz}from"crypto";import*as O3 from"fs/promises";import*as u6 from"path";var V4;var Aq=b(()=>{V4=class V4{static instances=new Map;todos=[];filePath;loaded=!1;constructor($,Z){this.filePath=u6.join(Z,"todos",`${$}-agent-${$}.json`)}static getInstance($,Z){let Y=`${$}-${Z}`;if(!V4.instances.has(Y))V4.instances.set(Y,new V4($,Z));return V4.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,q=this.todos.find((G)=>G.id===J.id||G.content===X.content);return{...X,id:J.id||q?.id||nz(),priority:X.priority||q?.priority||"medium",createdAt:q?.createdAt||Z,startedAt:X.status==="in_progress"&&!q?.startedAt?Z:q?.startedAt,completedAt:X.status==="completed"&&!q?.completedAt?Z:q?.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 O3.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 O3.mkdir(u6.dirname(this.filePath),{recursive:!0,mode:493}),await O3.writeFile(this.filePath,JSON.stringify(this.todos,null,2),"utf-8")}catch($){throw console.error("保存 TODO 列表失败:",$),$}}}});import{z as H3}from"zod";var Rq;var Vq=b(()=>{Rq=H3.object({id:H3.string().optional(),content:H3.string().min(1,"Content cannot be empty"),status:H3.enum(["pending","in_progress","completed"]),activeForm:H3.string().min(1,"ActiveForm cannot be empty"),priority:H3.enum(["high","medium","low"]).default("medium")})});import{z as Dq}from"zod";function i5($){let{sessionId:Z,configDir:Y}=$;return t({name:"TodoWrite",displayName:"Todo Write",kind:"readonly",schema:Dq.object({todos:Dq.array(Rq).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.
|
|
1943
1943
|
It also helps the user understand the progress of the task and overall progress of their requests.
|
|
1944
1944
|
|
|
1945
1945
|
## When to Use This Tool
|
|
@@ -2000,18 +2000,18 @@ NOTE that you should not use this tool if there is only one trivial task to do.
|
|
|
2000
2000
|
- activeForm: "Fixing authentication bug"
|
|
2001
2001
|
|
|
2002
2002
|
When in doubt, use this tool. Being proactive with task management demonstrates attentiveness and ensures you complete all requirements successfully.
|
|
2003
|
-
`},async execute(Q,X){let{todos:J}=Q,{updateOutput:q}=X;try{let G=X.sessionId||Z,K=V4.getInstance(G,Y);q?.("Updating TODO list..."),await K.updateTodos(J);let W=K.getTodos(),U=
|
|
2003
|
+
`},async execute(Q,X){let{todos:J}=Q,{updateOutput:q}=X;try{let G=X.sessionId||Z,K=V4.getInstance(G,Y);q?.("Updating TODO list..."),await K.updateTodos(J);let W=K.getTodos(),U=oz(W),F=sz(W,U);return q?.(`✅ TODO list updated (${U.completed}/${U.total} completed)`),{success:!0,llmContent:{todos:W,stats:U},displayContent:F,metadata:{stats:U}}}catch(G){let K=G;return{success:!1,llmContent:`Update failed: ${K.message}`,displayContent:`❌ 更新 TODO 列表失败: ${K.message}`,error:{type:"execution_error",message:K.message,details:G}}}},version:"1.0.0",category:"TODO tools",tags:["todo","task","management","planning"],extractSignatureContent:(Q)=>`${Q.todos.length} todos`,abstractPermissionRule:()=>"*"})}function oz($){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 sz($,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(`
|
|
2004
2004
|
`);for(let X of $){let J=X.status==="completed"?"☑":"☐",q=`(P${X.priority==="high"?0:X.priority==="medium"?1:2})`,G=X.status==="in_progress"?" ⚡":"",K=X.status==="completed"?"~~":"";Y.push(` ${J} ${q} ${K}${X.content}${K}${G}`)}return Y.join(`
|
|
2005
|
-
`)}var Mq=b(()=>{S0();V$();Aq();Vq()});var jq=b(()=>{Mq()});import{z as $1}from"zod";import{isPlainObject as Iq}from"lodash-es";function yq($){if(!Iq($))return;let Z=$;return typeof Z.name==="string"?Z.name:void 0}function
|
|
2005
|
+
`)}var Mq=b(()=>{S0();V$();Aq();Vq()});var jq=b(()=>{Mq()});import{z as $1}from"zod";import{isPlainObject as Iq}from"lodash-es";function yq($){if(!Iq($))return;let Z=$;return typeof Z.name==="string"?Z.name:void 0}function tz($){if($ instanceof Error)return $.message;if(typeof $==="string")return $;if(Iq($)){let Z=$;if(typeof Z.message==="string")return Z.message}return String($)}async function ez($){let{url:Z,method:Y,headers:Q,body:X,timeout:J,follow_redirects:q,max_redirects:G,signal:K}=$,W={"User-Agent":"Blade-AI/1.0",...Q},U=Z,F=Y,O=X,H=0,_=[];while(!0){let z={...W};if(O&&F!=="GET"&&F!=="HEAD"&&!QB(z,"content-type"))z["Content-Type"]="application/json";let w=await vq(U,{method:F,headers:z,body:O&&F!=="GET"&&F!=="HEAD"?O:void 0,redirect:"manual"},J,K),B=w.headers.get("location"),L=w.status>=300&&w.status<400,V=q&&L&&B&&H<G;if(L&&q&&!B)throw Error(`收到状态码 ${w.status} 但响应缺少 Location 头`);if(L&&q&&H>=G)throw Error(`超过最大重定向次数 (${G})`);if(V&&B){H++;let y=YB(B,U);if(_.push(`${w.status} → ${y}`),w.status===303||(w.status===301||w.status===302)&&F!=="GET"&&F!=="HEAD")F="GET",O=void 0;U=y;continue}let D=await w.text(),R=Tq(w.headers);return{status:w.status,status_text:w.statusText,headers:R,body:D,url:w.url||U,redirected:H>0,redirect_count:H,redirect_chain:_,content_type:R["content-type"],response_time:0}}}function a5($,Z,Y){let{url:Q,method:X,status:J,response_time:q,content_length:G}=Z,K=Y?`❌ ${X} ${Q} - ${J} ${$.status_text}`:`✅ ${X} ${Q} - ${J} ${$.status_text}`;if(K+=`
|
|
2006
2006
|
响应时间: ${q}ms`,K+=`
|
|
2007
2007
|
内容长度: ${G} 字节`,Z.content_type)K+=`
|
|
2008
2008
|
Content-Type: ${Z.content_type}`;if($.redirected&&Z.final_url&&Z.final_url!==Q){if(K+=`
|
|
2009
2009
|
最终URL: ${Z.final_url}`,Z.redirect_count)K+=`
|
|
2010
|
-
重定向次数: ${Z.redirect_count}`}let W
|
|
2010
|
+
重定向次数: ${Z.redirect_count}`}let W=$B($.body,$.content_type);if(W)K+=`
|
|
2011
2011
|
响应内容:
|
|
2012
|
-
${W}`;return K}function
|
|
2012
|
+
${W}`;return K}function $B($,Z){if(!$)return"(空响应)";if(ZB(Z,$))return"[binary content omitted]";let Y=$.trim();if(!Y)return"(仅包含空白字符)";return Y.length>800?`${Y.slice(0,800)}...`:Y}function ZB($,Z){if($){let X=$.toLowerCase();if(["image/","audio/","video/","application/pdf","application/zip","application/octet-stream"].some((q)=>X.startsWith(q)))return!0}if(!Z)return!1;let Y=0,Q=Math.min(Z.length,200);for(let X=0;X<Q;X++){let J=Z.charCodeAt(X);if(J===9||J===10||J===13)continue;if(J<32||J>126)Y++}return Y/(Q||1)>0.3}async function vq($,Z,Y,Q){let X=new AbortController,J=setTimeout(()=>X.abort(),Y),q=()=>X.abort();Q?.addEventListener("abort",q);try{return await fetch($,{...Z,signal:X.signal})}catch(G){if(yq(G)==="AbortError"){if(G instanceof Error)throw G.message="请求被中止或超时",G;let K=Error("请求被中止或超时");throw K.name="AbortError",K}throw G}finally{clearTimeout(J),Q?.removeEventListener("abort",q)}}function YB($,Z){try{return new URL($,Z).toString()}catch{return $}}function Tq($){let Z={};return $.forEach((Y,Q)=>{Z[Q.toLowerCase()]=Y}),Z}function QB($,Z){let Y=Z.toLowerCase();return Object.keys($).some((Q)=>Q.toLowerCase()===Y)}async function XB($){let{url:Z,jinaOptions:Y,timeout:Q,signal:X,updateOutput:J}=$,q=`https://r.jina.ai/${encodeURIComponent(Z)}`;J?.(`\uD83D\uDD0D 使用 Jina Reader 提取内容: ${Z}`);let G={"User-Agent":"Blade-AI/1.0",Accept:"text/markdown"};if(Y?.with_generated_alt)G["X-With-Generated-Alt"]="true";if(Y?.with_links_summary)G["X-With-Links-Summary"]="true";if(Y?.wait_for_selector)G["X-Wait-For-Selector"]=Y.wait_for_selector;try{let K=await vq(q,{method:"GET",headers:G},Q,X);if(!K.ok)throw Error(`Jina Reader error: ${K.status} ${K.statusText}`);let W=await K.text(),U=JB(W);return J?.(`✅ Jina Reader 成功提取内容 (${U.content.length} 字符)`),{status:K.status,status_text:K.statusText,headers:Tq(K.headers),body:qB(U),url:U.sourceUrl||Z,redirected:!1,redirect_count:0,content_type:"text/markdown",response_time:0}}catch(K){throw J?.("⚠️ Jina Reader 失败,回退到直接获取"),K}}function JB($){let Z=$.split(`
|
|
2013
2013
|
`),Y="",Q="",X=0;for(let q=0;q<Z.length;q++){let G=Z[q];if(G.startsWith("Title: "))Y=G.substring(7).trim();else if(G.startsWith("URL Source: "))Q=G.substring(12).trim();else if(G.startsWith("Markdown Content:")){X=q+1;break}}let J=Z.slice(X).join(`
|
|
2014
|
-
`).trim();return{title:Y||"Untitled",sourceUrl:Q||"",content:J||$}}function
|
|
2014
|
+
`).trim();return{title:Y||"Untitled",sourceUrl:Q||"",content:J||$}}function qB($){let Z="";if($.title)Z+=`# ${$.title}
|
|
2015
2015
|
|
|
2016
2016
|
`;if($.sourceUrl)Z+=`**Source**: ${$.sourceUrl}
|
|
2017
2017
|
|
|
@@ -2034,14 +2034,14 @@ Usage notes:
|
|
|
2034
2034
|
- Results may be summarized if the content is very large
|
|
2035
2035
|
- Includes a self-cleaning 15-minute cache for faster responses when repeatedly accessing the same URL
|
|
2036
2036
|
- 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.
|
|
2037
|
-
`},async execute($,Z){let{url:Y,method:Q="GET",extract_content:X=!1,jina_options:J,headers:q={},body:G,timeout:K=30000,follow_redirects:W=!0,max_redirects:U=5,return_headers:F=!1}=$,{updateOutput:O}=Z,H=Z.signal??new AbortController().signal;try{if(X)try{let L=Date.now(),V=await
|
|
2038
|
-
`),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:R8(Q.url),source:V8(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 G=J.substring(6).trim().replace(/<[^>]*>/g,"").replace(/\s+/g," ").trim();Q.snippet=G.substring(0,300)}}if(Q.title&&Q.url)Z.push({title:Q.title,url:Q.url,snippet:Q.snippet||Q.title,display_url:R8(Q.url),source:V8(Q.url)});return Z}function
|
|
2039
|
-
`);for(let G of q)if(G.startsWith("data: ")){let K=JSON.parse(G.substring(6));if(K.result&&K.result.content&&K.result.content.length>0)return
|
|
2037
|
+
`},async execute($,Z){let{url:Y,method:Q="GET",extract_content:X=!1,jina_options:J,headers:q={},body:G,timeout:K=30000,follow_redirects:W=!0,max_redirects:U=5,return_headers:F=!1}=$,{updateOutput:O}=Z,H=Z.signal??new AbortController().signal;try{if(X)try{let L=Date.now(),V=await XB({url:Y,jinaOptions:J,timeout:K,signal:H,updateOutput:O}),D=Date.now()-L;if(V.response_time=D,!F)delete V.headers;let R={url:Y,method:"GET",status:V.status,response_time:D,content_length:Buffer.byteLength(V.body||"","utf8"),redirected:V.redirected||!1,redirect_count:V.redirect_count??0,final_url:V.url,content_type:V.content_type,redirect_chain:V.redirect_chain};return{success:!0,llmContent:V,displayContent:a5(V,R,!1),metadata:R}}catch{O?.("⚠️ Jina Reader 失败,使用标准方式获取")}O?.(`发送 ${Q} 请求到: ${Y}`);let _=Date.now(),z=await ez({url:Y,method:Q,headers:q,body:G,timeout:K,follow_redirects:W,max_redirects:U,signal:H}),w=Date.now()-_;if(z.response_time=w,!F)delete z.headers;let B={url:Y,method:Q,status:z.status,response_time:w,content_length:Buffer.byteLength(z.body||"","utf8"),redirected:z.redirected||!1,redirect_count:z.redirect_count??0,final_url:z.url,content_type:z.content_type,redirect_chain:z.redirect_chain};if(z.status>=400)return{success:!1,llmContent:`HTTP error ${z.status}: ${z.status_text}`,displayContent:a5(z,B,!0),error:{type:"execution_error",message:`HTTP error ${z.status}: ${z.status_text}`,details:{...B,response_body:z.body}},metadata:B};return{success:!0,llmContent:z,displayContent:a5(z,B,!1),metadata:B}}catch(_){if(yq(_)==="AbortError")return{success:!1,llmContent:"Request aborted",displayContent:"⚠️ 请求被用户中止",error:{type:"execution_error",message:"操作被中止"}};let z=tz(_);return{success:!1,llmContent:`Network request failed: ${z}`,displayContent:`❌ 网络请求失败: ${z}`,error:{type:"execution_error",message:z,details:_}}}},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 Pq}from"lru-cache";import GB from"node:crypto";class Cq{cache;config;hits=0;misses=0;constructor($){this.config={maxSize:$?.maxSize??100,ttl:$?.ttl??3600000,enabled:$?.enabled??!0},this.cache=new Pq({max:this.config.maxSize,ttl:this.config.ttl,updateAgeOnGet:!0,updateAgeOnHas:!1})}generateKey($,Z){let Y=Z.toLowerCase().trim(),Q=GB.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 Pq({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 Sq(){return KB}var KB;var kq=b(()=>{KB=new Cq});function WB($){return $.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').replace(/'/g,"'")}function fq($){let Z=WB($).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 R8($){try{let Z=new URL($),Y=Z.pathname==="/"?"":Z.pathname;return`${Z.hostname}${Y}`}catch{return $}}function V8($){try{return new URL($).hostname.toLowerCase()}catch{return""}}function UB($){if(!$.FirstURL||!$.Text)return null;let{title:Z,snippet:Y}=fq($.Text);return{title:Z,snippet:Y,url:$.FirstURL,display_url:R8($.FirstURL),source:V8($.FirstURL)}}function hq($){let Z=[];for(let Y of $){if(Y.Topics&&Y.Topics.length>0){Z.push(...hq(Y.Topics));continue}if(Y.FirstURL&&Y.Text){let{title:Q,snippet:X}=fq(Y.Text);Z.push({title:Q,snippet:X,url:Y.FirstURL,display_url:R8(Y.FirstURL),source:V8(Y.FirstURL)})}}return Z}function FB($){let Z=$,Y=(Z.Results??[]).map((X)=>UB(X)).filter((X)=>X!==null),Q=hq(Z.RelatedTopics??[]);return[...Y,...Q]}function HB($){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:R8(Q.url),source:V8(Q.url)})}return Y}function _B($){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:HB,getHeaders:()=>({Accept:"application/json","User-Agent":"Blade-AI-WebSearch/1.0"})}}function zB($){let Z=[],Y=$.split(`
|
|
2038
|
+
`),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:R8(Q.url),source:V8(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 G=J.substring(6).trim().replace(/<[^>]*>/g,"").replace(/\s+/g," ").trim();Q.snippet=G.substring(0,300)}}if(Q.title&&Q.url)Z.push({title:Q.title,url:Q.url,snippet:Q.snippet||Q.title,display_url:R8(Q.url),source:V8(Q.url)});return Z}function BB(){return{name:"Exa",endpoint:`${x2.BASE_URL}${x2.ENDPOINT}`,searchFn:async($)=>{let Z={jsonrpc:"2.0",id:1,method:"tools/call",params:{name:"web_search_exa",arguments:{query:$,type:"auto",numResults:x2.DEFAULT_NUM_RESULTS,contextMaxCharacters:1e4}}},Y=new AbortController,Q=setTimeout(()=>Y.abort(),x2.TIMEOUT);try{let X=await fetch(`${x2.BASE_URL}${x2.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 q=(await X.text()).split(`
|
|
2039
|
+
`);for(let G of q)if(G.startsWith("data: ")){let K=JSON.parse(G.substring(6));if(K.result&&K.result.content&&K.result.content.length>0)return zB(K.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:()=>`${x2.BASE_URL}${x2.ENDPOINT}`,parseResponse:()=>[],getHeaders:()=>({})}}function pq(){let $=[];return $.push(BB()),$.push(OB),$.push(...xq.map(_B)),$}function mq(){return 2+xq.length}var OB,xq,x2;var gq=b(()=>{OB={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:FB,getHeaders:()=>({Accept:"application/json, text/plain;q=0.9","User-Agent":"Blade-AI-WebSearch/1.0"})};xq=["https://searx.be","https://search.ononoki.org","https://searx.tiekoetter.com","https://searx.work"];x2={BASE_URL:"https://mcp.exa.ai",ENDPOINT:"/mcp",DEFAULT_NUM_RESULTS:10,TIMEOUT:25000}});import{ProxyAgent as wB,fetch as LB}from"undici";import{z as _3}from"zod";function AB(){let $=process.env.HTTPS_PROXY||process.env.HTTP_PROXY||process.env.https_proxy||process.env.http_proxy;if($)try{return new wB($)}catch(Z){console.warn(`Invalid proxy URL: ${$}`)}return}async function RB($,Z,Y,Q,X){let J=new AbortController,q=setTimeout(()=>J.abort(),Y),G=()=>J.abort();Q?.addEventListener("abort",G);try{return await LB($,{...Z,signal:J.signal,dispatcher:X})}catch(K){if(K.name==="AbortError")throw Error("搜索请求超时或被中止");throw K}finally{clearTimeout(q),Q?.removeEventListener("abort",G)}}async function VB($,Z,Y,Q,X,J){let q=null;for(let G=0;G<D8.maxRetries;G++)try{return await RB($,Z,Y,Q,X)}catch(K){if(q=K,Q?.aborted)throw K;if(G<D8.maxRetries-1){let W=Math.min(D8.baseDelay*Math.pow(2,G),D8.maxDelay);J?.(`⏳ 请求失败,${W/1000}s 后重试 (${G+1}/${D8.maxRetries})...`),await new Promise((U)=>setTimeout(U,W))}}throw q}async function DB($,Z,Y,Q,X,J){let q=Sq(),G=q.get($.name,Z);if(G)return J?.(`\uD83D\uDCBE 使用缓存结果 (${$.name})`),{results:G,providerName:`${$.name} (cached)`};if($.searchFn)try{J?.(`\uD83D\uDD0D 搜索中 (${$.name})...`);let w=await $.searchFn(Z);return q.set($.name,Z,w),{results:w,providerName:$.name}}catch(w){throw Error(`SDK search failed: ${w.message}`)}J?.(`\uD83D\uDD0D 搜索中 (${$.name})...`);let K=$.buildUrl(Z),W=$.method||"GET",F={headers:$.getHeaders(),method:W};if(W==="POST"&&$.buildBody)F.body=JSON.stringify($.buildBody(Z));let O=await VB(K,F,Y,Q,X,J);if(!O.ok)throw Error(`HTTP ${O.status}`);let H=await O.text(),_;try{_=JSON.parse(H)}catch{throw Error("Failed to parse search result JSON")}let z=$.parseResponse(_);return q.set($.name,Z,z),{results:z,providerName:$.name}}async function MB($,Z,Y,Q){let X=pq(),J=AB(),q=[];for(let G=0;G<X.length;G++){let K=X[G];if(Y?.aborted)throw Error("搜索被用户中止");try{return Q?.(`\uD83D\uDD0E 使用 ${K.name} 搜索...`),await DB(K,$,Z,Y,J,Q)}catch(W){let U=W,F=`${K.name}: ${U.message}`;if(q.push(F),Q?.(`⚠️ ${F}`),G===X.length-1)throw Error(`所有搜索提供商都失败了:
|
|
2040
2040
|
${q.join(`
|
|
2041
|
-
`)}`)}}throw Error("No search providers available")}function
|
|
2041
|
+
`)}`)}}throw Error("No search providers available")}function jB($){try{return new URL($).hostname.toLowerCase()}catch{return null}}function IB($){return $.trim().toLowerCase()}function uq($){if(!$||$.length===0)return[];return $.map(IB).filter(Boolean)}function dq($,Z){return $===Z||$.endsWith(`.${Z}`)}function yB($,Z,Y){return $.filter((Q)=>{let X=jB(Q.url);if(!X)return!1;if(Y.length>0&&Y.some((J)=>dq(X,J)))return!1;if(Z.length>0&&!Z.some((J)=>dq(X,J)))return!1;return!0})}function vB($,Z,Y,Q){let X=`\uD83D\uDD0E WebSearch("${$}") via ${Q} - 返回 ${Z.length}/${Y} 条结果`,J=Z.map((q,G)=>`${G+1}. ${q.title}
|
|
2042
2042
|
${q.display_url}
|
|
2043
2043
|
${q.snippet}`);return[X,...J].join(`
|
|
2044
|
-
`)}function
|
|
2044
|
+
`)}function TB($){let Z=$.trim().toLowerCase();return Z.length>80?Z.slice(0,80):Z}var NB=15000,bB=8,D8,n5;var cq=b(()=>{S0();V$();kq();gq();D8={maxRetries:3,baseDelay:1000,maxDelay:8000};n5=t({name:"WebSearch",displayName:"Web Search",kind:"readonly",schema:_3.object({query:_3.string().min(2,"Search query must be at least 2 characters").describe("Search query"),allowed_domains:_3.array(_3.string().min(1)).optional().describe("Return results only from these domains (optional)"),blocked_domains:_3.array(_3.string().min(1)).optional().describe("Exclude results from these domains (optional)")}),description:{short:"Search the web and use the results to inform responses",long:`
|
|
2045
2045
|
- Search the web and use the results to inform responses
|
|
2046
2046
|
- Provides up-to-date information for current events and recent data
|
|
2047
2047
|
- Returns search result information formatted as search result blocks, including links as markdown hyperlinks
|
|
@@ -2069,11 +2069,11 @@ Usage notes:
|
|
|
2069
2069
|
IMPORTANT - Use the correct year in search queries:
|
|
2070
2070
|
- You MUST use the current year when searching for recent information, documentation, or current events.
|
|
2071
2071
|
- Example: If the user asks for "latest React docs", search for "React documentation 2025", NOT "React documentation 2024"
|
|
2072
|
-
`},async execute($,Z){let{query:Y}=$,Q=uq($.allowed_domains),X=uq($.blocked_domains),{updateOutput:J}=Z,q=Z.signal??new AbortController().signal;J?.(`\uD83D\uDD0E Searching: "${Y}" (${mq()} providers available)`);try{let{results:G,providerName:K}=await
|
|
2072
|
+
`},async execute($,Z){let{query:Y}=$,Q=uq($.allowed_domains),X=uq($.blocked_domains),{updateOutput:J}=Z,q=Z.signal??new AbortController().signal;J?.(`\uD83D\uDD0E Searching: "${Y}" (${mq()} providers available)`);try{let{results:G,providerName:K}=await MB(Y,NB,q,J),W=yB(G,Q,X),U=W.slice(0,bB),F={query:Y,results:U,provider:K,total_results:W.length,fetched_at:new Date().toISOString()},O={query:Y,provider:K,fetched_at:F.fetched_at,total_results:W.length,returned_results:U.length,allowed_domains:Q,blocked_domains:X};if(U.length===0)return{success:!0,llmContent:F,displayContent:`\uD83D\uDD0D WebSearch("${Y}") via ${K} - 未找到匹配结果`,metadata:O};return{success:!0,llmContent:F,displayContent:vB(Y,U,W.length,K),metadata:O}}catch(G){let K=G;return{success:!1,llmContent:`WebSearch call failed: ${K.message}`,displayContent:`❌ WebSearch 调用失败: ${K.message}`,error:{type:"execution_error",message:K.message,details:{query:Y,allowedDomains:Q,blockedDomains:X}}}}},version:"2.0.0",category:"网络工具",tags:["web","search","internet","news"],extractSignatureContent:($)=>`search:${TB($.query)}`,abstractPermissionRule:()=>"search:*"})});var lq=b(()=>{Eq();cq()});import*as iq from"os";import*as aq from"path";async function EB(){try{return await w$.getInstance().getAvailableTools()}catch($){return console.warn("MCP协议工具加载失败:",$),[]}}async function rq($){let Z=$?.sessionId||`session_${Date.now()}`,Y=$?.configDir||aq.join(iq.homedir(),".blade"),Q=[U5,W5,O5,H5,N5,R5,M5,j5,r5,n5,c5,l5,i5({sessionId:Z,configDir:Y}),_5,B5,...nJ,T5,P5,p5],X=await EB();return[...Q,...X]}var nq=b(()=>{F4();WJ();FJ();BJ();DJ();TJ();oJ();Gq();bq();jq();lq()});import{nanoid as PB}from"nanoid";class o5{name="hook";hookManager;constructor(){this.hookManager=R0.getInstance()}async process($){if(!this.hookManager.isEnabled())return;let Z=$._internal.tool;if(!Z)return;try{let Y=$.context.messageId||`tool_${PB()}`;$._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(q){$.abort(`Hook modified parameters are invalid: ${q instanceof Error?q.message:String(q)}`);return}}if(X.warning)console.warn(`[Hook Warning] ${X.warning}`)}catch(Y){console.error("[HookStage] Error executing hooks:",Y)}}}var oq=b(()=>{G$();t$()});import{nanoid as CB}from"nanoid";function SB($){return typeof $==="object"&&$!==null&&!Array.isArray($)}class s5{name="post-hook";hookManager;constructor(){this.hookManager=R0.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_${CB()}`,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 q=Y.llmContent||Y.displayContent||"";Y.llmContent=`${q}
|
|
2073
2073
|
|
|
2074
2074
|
---
|
|
2075
2075
|
**Hook Context:**
|
|
2076
|
-
${J.additionalContext}`}if(J.modifiedOutput!==void 0){let q=J.modifiedOutput;if(CB(q))Object.assign(Y,q)}if(J.warning)console.warn(`[PostToolUseHook Warning] ${J.warning}`)}catch(Q){console.error("[PostToolUseHookStage] Error executing post-tool hooks:",Q)}}}var sq=b(()=>{G$();t$()});class p2{static instance=null;locks=new Map;constructor(){}static getInstance(){if(!p2.instance)p2.instance=new p2;return p2.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){t5.debug(`获取文件锁: ${$}`);try{let Y=await Z();return t5.debug(`释放文件锁: ${$}`),Y}catch(Y){throw t5.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(){p2.instance=null}}var t5;var tq=b(()=>{z0();t5=l("Execution")});import M8 from"picomatch";class z3{config;constructor($){this.config=$}check($){let Z=z3.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(!M8.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(M8.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 M8.isMatch($,Z,{dot:!0,bash:!0});return $===Z}for(let[q,G]of Object.entries(Q)){let K=Y[q];if(K===void 0)return!1;if(G.includes("*")||G.includes("{")||G.includes("?")){if(G==="*"||G==="**")continue;if(!M8.isMatch(K,G,{dot:!0,bash:!0}))return!1}else if(K!==G)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(),q=Q.slice(X+1).trim();Z[J]=q}}return Z}smartSplit($,Z){let Y=[],Q="",X=0,J=0,q=0,G=!1,K="",W=!1;for(let U=0;U<$.length;U++){let F=$[U];if(W){Q+=F,W=!1;continue}if(F==="\\"){Q+=F,W=!0;continue}if(!G&&F==="{")X++;else if(!G&&F==="}")X--;else if(!G&&F==="(")J++;else if(!G&&F===")")J--;else if(!G&&F==="[")q++;else if(!G&&F==="]")q--;if((F==='"'||F==="'")&&!G){G=!0,K=F,Q+=F;continue}else if(G&&F===K){G=!1,K="",Q+=F;continue}if(F===Z&&X===0&&J===0&&q===0&&!G)Y.push(Q.trim()),Q="";else Q+=F}if(Q)Y.push(Q.trim());return Y}findTopLevelDelimiter($,Z){let Y=0,Q=0,X=0,J=!1,q="",G=!1;for(let K=0;K<$.length;K++){let W=$[K];if(G){G=!1;continue}if(W==="\\"){G=!0;continue}if(!J&&W==="{")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,q=W;continue}else if(J&&W===q){J=!1,q="";continue}if(W===Z&&Y===0&&Q===0&&X===0&&!J)return K}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 eq=()=>{};import SB from"node:os";import e5 from"node:path";var $Z;var $G=b(()=>{$Z=class $Z{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=e5.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 e5.join(SB.homedir(),$.slice(1));return e5.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 ZZ{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 YZ{name="permission";permissionChecker;sessionApprovals;defaultPermissionMode;constructor($,Z,Y){this.permissionChecker=new z3($),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=z3.buildSignature(X);$._internal.permissionSignature=J;let q=this.permissionChecker.check(X),G=$.context.permissionMode||this.defaultPermissionMode;switch(q=this.applyModeOverrides(Z.kind,q,G),q.result){case"deny":$.abort(q.reason||`Tool invocation "${Z.name}" was denied by permission rules: ${q.matchedRule}`);return;case"ask":if(this.sessionApprovals.has(J))q={result:"allow",matchedRule:"remembered:session",reason:"User already allowed this operation in this session"};else $._internal.needsConfirmation=!0,$._internal.confirmationReason=q.reason||"User confirmation required";break;case"allow":break}if(Q.length>0){let K=["/etc/","/sys/","/proc/","/dev/","/boot/","/root/","C:\\Windows\\System32","C:\\Program Files","C:\\ProgramData"],W=Q.filter((F)=>{if(F.includes(".."))return!0;return K.some((O)=>F.includes(O))});if(W.length>0){$.abort(`Access to dangerous system paths denied: ${W.join(", ")}`);return}let U=$Z.filterSensitive(Q,"medium");if(U.length>0){let F=U.map(({path:H,result:_})=>`${H} (${_.level}: ${_.reason})`);if(U.filter(({result:H})=>H.level==="high").length>0&&q.result!=="allow"){$.abort(`Access to highly sensitive files denied:
|
|
2076
|
+
${J.additionalContext}`}if(J.modifiedOutput!==void 0){let q=J.modifiedOutput;if(SB(q))Object.assign(Y,q)}if(J.warning)console.warn(`[PostToolUseHook Warning] ${J.warning}`)}catch(Q){console.error("[PostToolUseHookStage] Error executing post-tool hooks:",Q)}}}var sq=b(()=>{G$();t$()});class p2{static instance=null;locks=new Map;constructor(){}static getInstance(){if(!p2.instance)p2.instance=new p2;return p2.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){t5.debug(`获取文件锁: ${$}`);try{let Y=await Z();return t5.debug(`释放文件锁: ${$}`),Y}catch(Y){throw t5.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(){p2.instance=null}}var t5;var tq=b(()=>{z0();t5=l("Execution")});import M8 from"picomatch";class z3{config;constructor($){this.config=$}check($){let Z=z3.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(!M8.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(M8.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 M8.isMatch($,Z,{dot:!0,bash:!0});return $===Z}for(let[q,G]of Object.entries(Q)){let K=Y[q];if(K===void 0)return!1;if(G.includes("*")||G.includes("{")||G.includes("?")){if(G==="*"||G==="**")continue;if(!M8.isMatch(K,G,{dot:!0,bash:!0}))return!1}else if(K!==G)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(),q=Q.slice(X+1).trim();Z[J]=q}}return Z}smartSplit($,Z){let Y=[],Q="",X=0,J=0,q=0,G=!1,K="",W=!1;for(let U=0;U<$.length;U++){let F=$[U];if(W){Q+=F,W=!1;continue}if(F==="\\"){Q+=F,W=!0;continue}if(!G&&F==="{")X++;else if(!G&&F==="}")X--;else if(!G&&F==="(")J++;else if(!G&&F===")")J--;else if(!G&&F==="[")q++;else if(!G&&F==="]")q--;if((F==='"'||F==="'")&&!G){G=!0,K=F,Q+=F;continue}else if(G&&F===K){G=!1,K="",Q+=F;continue}if(F===Z&&X===0&&J===0&&q===0&&!G)Y.push(Q.trim()),Q="";else Q+=F}if(Q)Y.push(Q.trim());return Y}findTopLevelDelimiter($,Z){let Y=0,Q=0,X=0,J=!1,q="",G=!1;for(let K=0;K<$.length;K++){let W=$[K];if(G){G=!1;continue}if(W==="\\"){G=!0;continue}if(!J&&W==="{")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,q=W;continue}else if(J&&W===q){J=!1,q="";continue}if(W===Z&&Y===0&&Q===0&&X===0&&!J)return K}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 eq=()=>{};import kB from"node:os";import e5 from"node:path";var $Z;var $G=b(()=>{$Z=class $Z{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=e5.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 e5.join(kB.homedir(),$.slice(1));return e5.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 ZZ{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 YZ{name="permission";permissionChecker;sessionApprovals;defaultPermissionMode;constructor($,Z,Y){this.permissionChecker=new z3($),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=z3.buildSignature(X);$._internal.permissionSignature=J;let q=this.permissionChecker.check(X),G=$.context.permissionMode||this.defaultPermissionMode;switch(q=this.applyModeOverrides(Z.kind,q,G),q.result){case"deny":$.abort(q.reason||`Tool invocation "${Z.name}" was denied by permission rules: ${q.matchedRule}`);return;case"ask":if(this.sessionApprovals.has(J))q={result:"allow",matchedRule:"remembered:session",reason:"User already allowed this operation in this session"};else $._internal.needsConfirmation=!0,$._internal.confirmationReason=q.reason||"User confirmation required";break;case"allow":break}if(Q.length>0){let K=["/etc/","/sys/","/proc/","/dev/","/boot/","/root/","C:\\Windows\\System32","C:\\Program Files","C:\\ProgramData"],W=Q.filter((F)=>{if(F.includes(".."))return!0;return K.some((O)=>F.includes(O))});if(W.length>0){$.abort(`Access to dangerous system paths denied: ${W.join(", ")}`);return}let U=$Z.filterSensitive(Q,"medium");if(U.length>0){let F=U.map(({path:H,result:_})=>`${H} (${_.level}: ${_.reason})`);if(U.filter(({result:H})=>H.level==="high").length>0&&q.result!=="allow"){$.abort(`Access to highly sensitive files denied:
|
|
2077
2077
|
${F.join(`
|
|
2078
2078
|
`)}
|
|
2079
2079
|
|
|
@@ -2102,14 +2102,14 @@ ${Y}
|
|
|
2102
2102
|
${q}
|
|
2103
2103
|
\`\`\`
|
|
2104
2104
|
|
|
2105
|
-
... (还有 ${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 XZ{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 JZ{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 m2;var ZG=b(()=>{eq();G$();t$();z0();T0();V$();$G();m2=l("Execution")});import{EventEmitter as
|
|
2105
|
+
... (还有 ${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 XZ{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 JZ{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 m2;var ZG=b(()=>{eq();G$();t$();z0();T0();V$();$G();m2=l("Execution")});import{EventEmitter as fB}from"events";var qZ;var YG=b(()=>{G$();t$();oq();sq();G9();B$();tq();ZG();qZ=class qZ extends fB{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 YZ(Y,this.sessionApprovals,Q);this.stages=[new ZZ(this.registry),X,new o5,new QZ(this.sessionApprovals,X.getPermissionChecker()),new XZ,new s5,new JZ]}async execute($,Z,Y){let Q=Date.now(),X=this.generateExecutionId(),J=new q9($,Z,{...Y,sessionId:Y.sessionId||X});this.emit("executionStarted",{executionId:X,toolName:$,params:Z,context:Y,timestamp:Q});let q=this.registry.get($),G=q&&!q.isConcurrencySafe,K=G&&Z.file_path?String(Z.file_path):null;if(G&&K)return p2.getInstance().acquireLock(K,()=>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",q={success:!1,llmContent:`Tool execution failed: ${Q.message}`,displayContent:`错误: ${Q.message}`,error:{type:"execution_error",message:Q.message}};try{let K=await R0.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(K.additionalContext)q={...q,llmContent:`${q.llmContent}
|
|
2106
2106
|
|
|
2107
|
-
${K.additionalContext}`};if(K.warning)console.warn(`[ExecutionPipeline] PostToolUseFailure hook warning: ${K.warning}`)}catch(G){console.warn("[ExecutionPipeline] PostToolUseFailure hook execution failed:",G)}return this.addToHistory({executionId:Z,toolName:$.toolName,params:$.params,result:q,startTime:Y,endTime:X,context:$.context}),this.emit("executionFailed",{executionId:Z,toolName:$.toolName,error:Q,duration:X-Y,timestamp:X}),q}}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],q=this.execute(J.toolName,J.params,J.context);if(Q.push(q),Q.length>=Z||X===$.length-1){let G=await Promise.all(Q);Y.push(...G),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 fB}from"events";var d6;var QG=b(()=>{G$();d6=class d6 extends fB{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 d6.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 xB($){return hB.some((Z)=>Z.test($))}function pB($){if($.supportsThinking!==void 0)return{supportsThinking:$.supportsThinking,thinkingBudget:$.thinkingBudget};return{supportsThinking:xB($.model),thinkingBudget:void 0}}function B3($){return pB($).supportsThinking}var hB;var c6=b(()=>{hB=[/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 GZ{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((F)=>F.role==="system"),X=Z.filter((F)=>F.role!=="system"),J=this.getRecentMessages(X),q=X.slice(0,-this.recentMessagesLimit),G=await this.generateSummary(q),K=this.extractKeyPoints(q,Y),W=this.generateToolSummary(Y),U=this.estimateTokenCount(G,K,J,W);return{summary:G,keyPoints:K,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 q=J.content.toLowerCase();["关于","讨论","问题","项目","功能","需求"].forEach((U)=>{if(q.includes(U)){let F=this.extractContext(q,U,50);if(F)Z.add(F)}}),["创建","删除","修改","更新","实现","开发"].forEach((U)=>{if(q.includes(U)){let F=this.extractContext(q,U,30);if(F)Y.add(F)}}),["决定","选择","确定","采用","使用"].forEach((U)=>{if(q.includes(U)){let F=this.extractContext(q,U,40);if(F)Q.add(F)}})}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((G)=>Y.add(`用户问题:${G}`)),this.extractRequests(X.content).forEach((G)=>Y.add(`用户请求:${G}`));else if(X.role==="assistant")this.extractSolutions(X.content).forEach((q)=>Y.add(`解决方案:${q}`));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 q=Math.round(J.success/J.count*100);Q.push(`${X}(${J.count}次,成功率${q}%)`)}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 q=J.filter((G)=>G.status==="success").length;Z.push(`${X}(${J.length}次,${q}成功)`)}}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 D4{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 K=Date.now()-Z.timeWindow;Y=Y.filter((W)=>W.timestamp>=K)}let Q=Y.filter((K)=>K.status==="success"),X=Y.filter((K)=>K.status==="error"),J=Math.min(20,Q.length),q=Math.min(10,X.length);return{recentCalls:[...Q.slice(-J),...X.slice(-q)].sort((K,W)=>K.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((q)=>q.role==="system"),Q=$.filter((q)=>q.role!=="system"),X=Z-Y.length,J=X>0?Q.slice(-X):[];return[...Y,...J].sort((q,G)=>q.timestamp-G.timestamp)}limitByTokens($,Z){if(Z<=0)return $;let Y=0,Q=[];for(let X=$.length-1;X>=0;X--){let J=$[X],q=this.estimateMessageTokens(J);if(J.role==="system")if(Y+q<=Z)Q.unshift(J),Y+=q;else{let G=this.compressMessage(J,Z-Y);Q.unshift(G),Y+=this.estimateMessageTokens(G)}else if(Y+q<=Z)Q.unshift(J),Y+=q;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 D4({maxTokens:1000,maxMessages:10,timeWindow:7200000,includeTools:!1,includeWorkspace:!1}),standard:new D4({maxTokens:4000,maxMessages:30,timeWindow:43200000,includeTools:!0,includeWorkspace:!0}),comprehensive:new D4({maxTokens:8000,maxMessages:100,timeWindow:86400000,includeTools:!0,includeWorkspace:!0}),debug:new D4({maxTokens:2000,maxMessages:20,timeWindow:21600000,priority:2,includeTools:!0,includeWorkspace:!1})}}}class KZ{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),q=X.accessCount,G=J*q;if(G<Z)Z=G,$=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 WZ{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 l6 from"node:fs";import{createReadStream as mB}from"node:fs";import*as l$ from"node:fs/promises";import*as UZ from"node:path";import{createInterface as gB}from"node:readline";class x1{filePath;constructor($){this.filePath=$}async append($){try{await l$.mkdir(UZ.dirname(this.filePath),{recursive:!0,mode:493});let Z=JSON.stringify($)+`
|
|
2107
|
+
${K.additionalContext}`};if(K.warning)console.warn(`[ExecutionPipeline] PostToolUseFailure hook warning: ${K.warning}`)}catch(G){console.warn("[ExecutionPipeline] PostToolUseFailure hook execution failed:",G)}return this.addToHistory({executionId:Z,toolName:$.toolName,params:$.params,result:q,startTime:Y,endTime:X,context:$.context}),this.emit("executionFailed",{executionId:Z,toolName:$.toolName,error:Q,duration:X-Y,timestamp:X}),q}}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],q=this.execute(J.toolName,J.params,J.context);if(Q.push(q),Q.length>=Z||X===$.length-1){let G=await Promise.all(Q);Y.push(...G),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 hB}from"events";var d6;var QG=b(()=>{G$();d6=class d6 extends hB{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 d6.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 pB($){return xB.some((Z)=>Z.test($))}function mB($){if($.supportsThinking!==void 0)return{supportsThinking:$.supportsThinking,thinkingBudget:$.thinkingBudget};return{supportsThinking:pB($.model),thinkingBudget:void 0}}function B3($){return mB($).supportsThinking}var xB;var c6=b(()=>{xB=[/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 GZ{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((F)=>F.role==="system"),X=Z.filter((F)=>F.role!=="system"),J=this.getRecentMessages(X),q=X.slice(0,-this.recentMessagesLimit),G=await this.generateSummary(q),K=this.extractKeyPoints(q,Y),W=this.generateToolSummary(Y),U=this.estimateTokenCount(G,K,J,W);return{summary:G,keyPoints:K,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 q=J.content.toLowerCase();["关于","讨论","问题","项目","功能","需求"].forEach((U)=>{if(q.includes(U)){let F=this.extractContext(q,U,50);if(F)Z.add(F)}}),["创建","删除","修改","更新","实现","开发"].forEach((U)=>{if(q.includes(U)){let F=this.extractContext(q,U,30);if(F)Y.add(F)}}),["决定","选择","确定","采用","使用"].forEach((U)=>{if(q.includes(U)){let F=this.extractContext(q,U,40);if(F)Q.add(F)}})}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((G)=>Y.add(`用户问题:${G}`)),this.extractRequests(X.content).forEach((G)=>Y.add(`用户请求:${G}`));else if(X.role==="assistant")this.extractSolutions(X.content).forEach((q)=>Y.add(`解决方案:${q}`));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 q=Math.round(J.success/J.count*100);Q.push(`${X}(${J.count}次,成功率${q}%)`)}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 q=J.filter((G)=>G.status==="success").length;Z.push(`${X}(${J.length}次,${q}成功)`)}}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 D4{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 K=Date.now()-Z.timeWindow;Y=Y.filter((W)=>W.timestamp>=K)}let Q=Y.filter((K)=>K.status==="success"),X=Y.filter((K)=>K.status==="error"),J=Math.min(20,Q.length),q=Math.min(10,X.length);return{recentCalls:[...Q.slice(-J),...X.slice(-q)].sort((K,W)=>K.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((q)=>q.role==="system"),Q=$.filter((q)=>q.role!=="system"),X=Z-Y.length,J=X>0?Q.slice(-X):[];return[...Y,...J].sort((q,G)=>q.timestamp-G.timestamp)}limitByTokens($,Z){if(Z<=0)return $;let Y=0,Q=[];for(let X=$.length-1;X>=0;X--){let J=$[X],q=this.estimateMessageTokens(J);if(J.role==="system")if(Y+q<=Z)Q.unshift(J),Y+=q;else{let G=this.compressMessage(J,Z-Y);Q.unshift(G),Y+=this.estimateMessageTokens(G)}else if(Y+q<=Z)Q.unshift(J),Y+=q;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 D4({maxTokens:1000,maxMessages:10,timeWindow:7200000,includeTools:!1,includeWorkspace:!1}),standard:new D4({maxTokens:4000,maxMessages:30,timeWindow:43200000,includeTools:!0,includeWorkspace:!0}),comprehensive:new D4({maxTokens:8000,maxMessages:100,timeWindow:86400000,includeTools:!0,includeWorkspace:!0}),debug:new D4({maxTokens:2000,maxMessages:20,timeWindow:21600000,priority:2,includeTools:!0,includeWorkspace:!1})}}}class KZ{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),q=X.accessCount,G=J*q;if(G<Z)Z=G,$=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 WZ{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 l6 from"node:fs";import{createReadStream as gB}from"node:fs";import*as l$ from"node:fs/promises";import*as UZ from"node:path";import{createInterface as uB}from"node:readline";class x1{filePath;constructor($){this.filePath=$}async append($){try{await l$.mkdir(UZ.dirname(this.filePath),{recursive:!0,mode:493});let Z=JSON.stringify($)+`
|
|
2108
2108
|
`;await l$.appendFile(this.filePath,Z,"utf-8")}catch(Z){throw console.error(`[JSONLStore] 追加写入失败: ${this.filePath}`,Z),Z}}async appendBatch($){try{await l$.mkdir(UZ.dirname(this.filePath),{recursive:!0,mode:493});let Z=$.map((Y)=>JSON.stringify(Y)).join(`
|
|
2109
2109
|
`)+`
|
|
2110
2110
|
`;await l$.appendFile(this.filePath,Z,"utf-8")}catch(Z){throw console.error(`[JSONLStore] 批量追加写入失败: ${this.filePath}`,Z),Z}}async readAll(){try{if(!l6.existsSync(this.filePath))return[];let Z=(await l$.readFile(this.filePath,"utf-8")).split(`
|
|
2111
|
-
`).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(!l6.existsSync(this.filePath)){Z();return}let Q=
|
|
2112
|
-
`).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 l$.access(this.filePath),!0}catch{return!1}}async delete(){try{if(await this.exists())await l$.unlink(this.filePath)}catch($){throw console.error(`[JSONLStore] 删除文件失败: ${this.filePath}`,$),$}}getFilePath(){return this.filePath}}var XG=()=>{};import{nanoid as w3}from"nanoid";import*as _2 from"node:fs/promises";import*as JG from"node:path";class FZ{projectPath;maxSessions;version;constructor($=process.cwd(),Z=100,Y="0.0.10"){this.projectPath=$,this.maxSessions=Z,this.version=Y}async initialize(){try{let $=w8(this.projectPath);await _2.mkdir($,{recursive:!0,mode:493}),console.log(`[PersistentStore] 初始化存储目录: ${$}`)}catch($){console.warn("[PersistentStore] 无法创建持久化存储目录:",$)}}async saveMessage($,Z,Y,Q=null,X){try{let J=B1(this.projectPath,$),q=new x1(J),G={uuid:w3(),parentUuid:Q,sessionId:$,timestamp:new Date().toISOString(),type:Z==="user"?"user":Z==="assistant"?"assistant":Z==="tool"?"tool_result":"system",cwd:this.projectPath,gitBranch:G3(this.projectPath),version:this.version,message:{role:Z,content:Y,...X||{}}};return await q.append(G),G.uuid}catch(J){throw console.error(`[PersistentStore] 保存消息失败 (session: ${$}):`,J),J}}async saveToolUse($,Z,Y,Q=null){try{let X=B1(this.projectPath,$),J=new x1(X),q={uuid:w3(),parentUuid:Q,sessionId:$,timestamp:new Date().toISOString(),type:"tool_use",cwd:this.projectPath,gitBranch:G3(this.projectPath),version:this.version,message:{role:"assistant",content:""},tool:{id:w3(),name:Z,input:Y}};return await J.append(q),q.uuid}catch(X){throw console.error(`[PersistentStore] 保存工具调用失败 (session: ${$}):`,X),X}}async saveToolResult($,Z,Y,Q=null,X){try{let J=B1(this.projectPath,$),q=new x1(J),G={uuid:w3(),parentUuid:Q,sessionId:$,timestamp:new Date().toISOString(),type:"tool_result",cwd:this.projectPath,gitBranch:G3(this.projectPath),version:this.version,message:{role:"assistant",content:""},toolResult:{id:Z,output:Y,error:X}};return await q.append(G),G.uuid}catch(J){throw console.error(`[PersistentStore] 保存工具结果失败 (session: ${$}):`,J),J}}async saveCompaction($,Z,Y,Q=null){try{let X=B1(this.projectPath,$),J=new x1(X),q={uuid:w3(),parentUuid:Q,sessionId:$,timestamp:new Date().toISOString(),type:"system",subtype:"compact_boundary",cwd:this.projectPath,gitBranch:G3(this.projectPath),version:this.version,message:{role:"system",content:"=== 上下文压缩边界 ==="},compactMetadata:Y};await J.append(q),console.log("[PersistentStore] 保存压缩边界标记");let G={uuid:w3(),parentUuid:q.uuid,logicalParentUuid:Q??void 0,sessionId:$,timestamp:new Date().toISOString(),type:"user",isCompactSummary:!0,cwd:this.projectPath,gitBranch:G3(this.projectPath),version:this.version,message:{role:"user",content:Z},compactMetadata:Y};return await J.append(G),console.log("[PersistentStore] 保存压缩总结消息"),G.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=B1(this.projectPath,$),Q=await new x1(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=B1(this.projectPath,$),Q=await new x1(Z).readAll();if(Q.length===0)return null;let X=Q.filter((G)=>["user","assistant","system"].includes(G.type)).map((G)=>({id:G.uuid,role:G.message.role,content:G.message.content,timestamp:new Date(G.timestamp).getTime()})),J=Q[Q.length-1],q=new Date(J.timestamp).getTime();return{messages:X,topics:[],lastActivity:q}}catch{return null}}async listSessions(){try{let $=w8(this.projectPath);return(await _2.readdir($)).filter((Y)=>Y.endsWith(".jsonl")).map((Y)=>Y.replace(".jsonl","")).sort()}catch{return[]}}async getSessionSummary($){try{let Z=B1(this.projectPath,$),Y=new x1(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((q)=>["user","assistant"].includes(q.type)).length,topics:[]}}catch{return null}}async deleteSession($){try{let Z=B1(this.projectPath,$);await new x1(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=B1(this.projectPath,Y),J=await new x1(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 $=w8(this.projectPath);await _2.mkdir($,{recursive:!0,mode:493});let Z=JG.join($,".health-check");return await _2.writeFile(Z,"test","utf-8"),await _2.unlink(Z),{isAvailable:!0,canWrite:!0}}catch($){return{isAvailable:!1,canWrite:!1,error:$ instanceof Error?$.message:String($)}}}static async listAllProjects(){return eX()}}var qG=b(()=>{XG();L8()});import*as KG from"crypto";import{nanoid as GG}from"nanoid";class j8{memory;persistent;cache;compressor;filter;options;currentSessionId=null;initialized=!1;constructor($={}){let Z=$.storage?.persistentPath||w4();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 WZ(this.options.storage.maxMemorySize),this.persistent=new FZ(process.cwd(),100),this.cache=new KZ(this.options.storage.cacheSize,300000),this.compressor=new GZ,this.filter=new D4(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 q=this.calculateRelevance($,J.topics);if(q>0)Q.push({sessionId:X,summary:`${J.messageCount}条消息,主题:${J.topics.join("、")}`,lastActivity:J.lastActivity,relevanceScore:q})}}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 GG()}generateMessageId(){return GG()}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 KG.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 OZ=b(()=>{qG();L8()});class HZ{chatService;contextManager;memoryAdapter;constructor($,Z){this.chatService=$,this.contextManager=Z||new j8,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 WG=b(()=>{OZ()});import*as UG from"os";import*as FG from"path";function uB($){if(typeof $==="string")return $;try{return JSON.parse(JSON.stringify($))}catch{return String($)}}class U${config;runtimeOptions;isInitialized=!1;activeTask;executionPipeline;chatService;executionEngine;attachmentCollector;activeSkillContext;currentModelMaxContextTokens;constructor($,Z={},Y){this.config=$,this.runtimeOptions=Z,this.executionPipeline=Y||this.createDefaultPipeline()}createDefaultPipeline(){let $=new d6,Z={...this.config.permissions,...this.runtimeOptions.permissions},Y=this.runtimeOptions.permissionMode??this.config.permissionMode??"default";return new qZ($,{permissionConfig:Z,permissionMode:Y,maxHistorySize:1000})}static async create($={}){if(await o8(),i3().length===0)throw Error(`❌ 没有可用的模型配置
|
|
2111
|
+
`).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(!l6.existsSync(this.filePath)){Z();return}let Q=gB(this.filePath,"utf-8"),X=uB({input:Q,crlfDelay:Number.POSITIVE_INFINITY});X.on("line",async(J)=>{let q=J.trim();if(q.length===0)return;try{let G=JSON.parse(q);await $(G)}catch(G){console.warn(`[JSONLStore] 解析 JSON 行失败: ${q}`,G)}}),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(!l6.existsSync(this.filePath))return{exists:!1,size:0,lineCount:0};let $=await l$.stat(this.filePath),Y=(await l$.readFile(this.filePath,"utf-8")).split(`
|
|
2112
|
+
`).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 l$.access(this.filePath),!0}catch{return!1}}async delete(){try{if(await this.exists())await l$.unlink(this.filePath)}catch($){throw console.error(`[JSONLStore] 删除文件失败: ${this.filePath}`,$),$}}getFilePath(){return this.filePath}}var XG=()=>{};import{nanoid as w3}from"nanoid";import*as _2 from"node:fs/promises";import*as JG from"node:path";class FZ{projectPath;maxSessions;version;constructor($=process.cwd(),Z=100,Y="0.0.10"){this.projectPath=$,this.maxSessions=Z,this.version=Y}async initialize(){try{let $=w8(this.projectPath);await _2.mkdir($,{recursive:!0,mode:493}),console.log(`[PersistentStore] 初始化存储目录: ${$}`)}catch($){console.warn("[PersistentStore] 无法创建持久化存储目录:",$)}}async saveMessage($,Z,Y,Q=null,X){try{let J=B1(this.projectPath,$),q=new x1(J),G={uuid:w3(),parentUuid:Q,sessionId:$,timestamp:new Date().toISOString(),type:Z==="user"?"user":Z==="assistant"?"assistant":Z==="tool"?"tool_result":"system",cwd:this.projectPath,gitBranch:G3(this.projectPath),version:this.version,message:{role:Z,content:Y,...X||{}}};return await q.append(G),G.uuid}catch(J){throw console.error(`[PersistentStore] 保存消息失败 (session: ${$}):`,J),J}}async saveToolUse($,Z,Y,Q=null){try{let X=B1(this.projectPath,$),J=new x1(X),q={uuid:w3(),parentUuid:Q,sessionId:$,timestamp:new Date().toISOString(),type:"tool_use",cwd:this.projectPath,gitBranch:G3(this.projectPath),version:this.version,message:{role:"assistant",content:""},tool:{id:w3(),name:Z,input:Y}};return await J.append(q),q.uuid}catch(X){throw console.error(`[PersistentStore] 保存工具调用失败 (session: ${$}):`,X),X}}async saveToolResult($,Z,Y,Q=null,X){try{let J=B1(this.projectPath,$),q=new x1(J),G={uuid:w3(),parentUuid:Q,sessionId:$,timestamp:new Date().toISOString(),type:"tool_result",cwd:this.projectPath,gitBranch:G3(this.projectPath),version:this.version,message:{role:"assistant",content:""},toolResult:{id:Z,output:Y,error:X}};return await q.append(G),G.uuid}catch(J){throw console.error(`[PersistentStore] 保存工具结果失败 (session: ${$}):`,J),J}}async saveCompaction($,Z,Y,Q=null){try{let X=B1(this.projectPath,$),J=new x1(X),q={uuid:w3(),parentUuid:Q,sessionId:$,timestamp:new Date().toISOString(),type:"system",subtype:"compact_boundary",cwd:this.projectPath,gitBranch:G3(this.projectPath),version:this.version,message:{role:"system",content:"=== 上下文压缩边界 ==="},compactMetadata:Y};await J.append(q),console.log("[PersistentStore] 保存压缩边界标记");let G={uuid:w3(),parentUuid:q.uuid,logicalParentUuid:Q??void 0,sessionId:$,timestamp:new Date().toISOString(),type:"user",isCompactSummary:!0,cwd:this.projectPath,gitBranch:G3(this.projectPath),version:this.version,message:{role:"user",content:Z},compactMetadata:Y};return await J.append(G),console.log("[PersistentStore] 保存压缩总结消息"),G.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=B1(this.projectPath,$),Q=await new x1(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=B1(this.projectPath,$),Q=await new x1(Z).readAll();if(Q.length===0)return null;let X=Q.filter((G)=>["user","assistant","system"].includes(G.type)).map((G)=>({id:G.uuid,role:G.message.role,content:G.message.content,timestamp:new Date(G.timestamp).getTime()})),J=Q[Q.length-1],q=new Date(J.timestamp).getTime();return{messages:X,topics:[],lastActivity:q}}catch{return null}}async listSessions(){try{let $=w8(this.projectPath);return(await _2.readdir($)).filter((Y)=>Y.endsWith(".jsonl")).map((Y)=>Y.replace(".jsonl","")).sort()}catch{return[]}}async getSessionSummary($){try{let Z=B1(this.projectPath,$),Y=new x1(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((q)=>["user","assistant"].includes(q.type)).length,topics:[]}}catch{return null}}async deleteSession($){try{let Z=B1(this.projectPath,$);await new x1(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=B1(this.projectPath,Y),J=await new x1(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 $=w8(this.projectPath);await _2.mkdir($,{recursive:!0,mode:493});let Z=JG.join($,".health-check");return await _2.writeFile(Z,"test","utf-8"),await _2.unlink(Z),{isAvailable:!0,canWrite:!0}}catch($){return{isAvailable:!1,canWrite:!1,error:$ instanceof Error?$.message:String($)}}}static async listAllProjects(){return eX()}}var qG=b(()=>{XG();L8()});import*as KG from"crypto";import{nanoid as GG}from"nanoid";class j8{memory;persistent;cache;compressor;filter;options;currentSessionId=null;initialized=!1;constructor($={}){let Z=$.storage?.persistentPath||w4();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 WZ(this.options.storage.maxMemorySize),this.persistent=new FZ(process.cwd(),100),this.cache=new KZ(this.options.storage.cacheSize,300000),this.compressor=new GZ,this.filter=new D4(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 q=this.calculateRelevance($,J.topics);if(q>0)Q.push({sessionId:X,summary:`${J.messageCount}条消息,主题:${J.topics.join("、")}`,lastActivity:J.lastActivity,relevanceScore:q})}}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 GG()}generateMessageId(){return GG()}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 KG.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 OZ=b(()=>{qG();L8()});class HZ{chatService;contextManager;memoryAdapter;constructor($,Z){this.chatService=$,this.contextManager=Z||new j8,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 WG=b(()=>{OZ()});import*as UG from"os";import*as FG from"path";function dB($){if(typeof $==="string")return $;try{return JSON.parse(JSON.stringify($))}catch{return String($)}}class U${config;runtimeOptions;isInitialized=!1;activeTask;executionPipeline;chatService;executionEngine;attachmentCollector;activeSkillContext;currentModelMaxContextTokens;constructor($,Z={},Y){this.config=$,this.runtimeOptions=Z,this.executionPipeline=Y||this.createDefaultPipeline()}createDefaultPipeline(){let $=new d6,Z={...this.config.permissions,...this.runtimeOptions.permissions},Y=this.runtimeOptions.permissionMode??this.config.permissionMode??"default";return new qZ($,{permissionConfig:Z,permissionMode:Y,maxHistorySize:1000})}static async create($={}){if(await o8(),i3().length===0)throw Error(`❌ 没有可用的模型配置
|
|
2113
2113
|
|
|
2114
2114
|
`+`请先使用以下命令添加模型:
|
|
2115
2115
|
`+` /model add
|
|
@@ -2148,9 +2148,9 @@ ${r.continueReason}
|
|
|
2148
2148
|
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.
|
|
2149
2149
|
</system-reminder>`;F.push({role:"user",content:E});continue}if(r.warning)f.warn(`[Agent] Stop hook warning: ${r.warning}`)}catch(A){f.warn("[Agent] Stop hook execution failed:",A)}try{let A=this.executionEngine?.getContextManager();if(A&&Z.sessionId&&N.content)if(N.content.trim()!=="")O=await A.saveMessage(Z.sessionId,"assistant",N.content,O);else f.debug("[Agent] 跳过保存空响应(任务完成时)")}catch(A){f.warn("[Agent] 保存助手消息失败:",A)}return{success:!0,finalMessage:N.content,metadata:{turnsCount:B,toolCallsCount:L.length,duration:Date.now()-X,tokensUsed:V}}}F.push({role:"assistant",content:N.content||"",reasoningContent:N.reasoningContent,tool_calls:N.toolCalls});try{let S=this.executionEngine?.getContextManager();if(S&&Z.sessionId&&N.content)if(N.content.trim()!=="")O=await S.saveMessage(Z.sessionId,"assistant",N.content,O);else f.debug("[Agent] 跳过保存空响应(工具调用时)")}catch(S){f.warn("[Agent] 保存助手工具调用消息失败:",S)}if(Y?.signal?.aborted)return f.info("[Agent] Aborting before tool execution due to signal.aborted=true"),{success:!1,error:{type:"aborted",message:"任务已被用户中止"},metadata:{turnsCount:B,toolCallsCount:L.length,duration:Date.now()-X}};let P=N.toolCalls.filter((S)=>S.type==="function");if(Y?.onToolStart&&!Y.signal?.aborted)for(let S of P){let g=this.executionPipeline.getRegistry().get(S.function.name)?.kind;Y.onToolStart(S,g)}let m=async(S)=>{try{let T=JSON.parse(S.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 A=this.executionEngine?.getContextManager();if(A&&Z.sessionId)g=await A.saveToolUse(Z.sessionId,S.function.name,T,O)}catch(A){f.warn("[Agent] 保存工具调用失败:",A)}let j=Y?.signal;if(!j)f.error("[Agent] Missing signal in tool execution, this should not happen");f.debug("[Agent] Passing confirmationHandler to ExecutionPipeline.execute:",{toolName:S.function.name,hasHandler:!!Z.confirmationHandler,hasMethod:!!Z.confirmationHandler?.requestConfirmation,methodType:typeof Z.confirmationHandler?.requestConfirmation});let M=await this.executionPipeline.execute(S.function.name,T,{sessionId:Z.sessionId,userId:Z.userId||"default",workspaceRoot:Z.workspaceRoot||process.cwd(),signal:j,confirmationHandler:Z.confirmationHandler,permissionMode:Z.permissionMode});if(f.debug(`
|
|
2150
2150
|
========== 工具执行结果 ==========`),f.debug("工具名称:",S.function.name),f.debug("成功:",M.success),f.debug("LLM Content:",M.llmContent),f.debug("Display Content:",M.displayContent),M.error)f.debug("错误:",M.error);return f.debug(`==================================
|
|
2151
|
-
`),{toolCall:S,result:M,toolUseUuid:g}}catch(T){return f.error(`Tool execution failed for ${S.function.name}:`,T),{toolCall:S,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")}}};f.info(`[Agent] Executing ${P.length} tool calls in parallel`);let e=await Promise.all(P.map(m));for(let{toolCall:S,result:T,toolUseUuid:g}of e){if(L.push(T),T.metadata?.shouldExitLoop){f.debug("\uD83D\uDEAA 检测到退出循环标记,结束 Agent 循环");let A=typeof T.llmContent==="string"?T.llmContent:"循环已退出";return{success:T.success,finalMessage:A,metadata:{turnsCount:B,toolCallsCount:L.length,duration:Date.now()-X,shouldExitLoop:!0,targetMode:T.metadata?.targetMode}}}if(Y?.onToolResult&&!Y.signal?.aborted){f.debug("[Agent] Calling onToolResult:",{toolName:S.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(S,T),f.debug("[Agent] onToolResult callback completed successfully")}catch(A){f.error("[Agent] onToolResult callback error:",A)}}try{let A=this.executionEngine?.getContextManager();if(A&&Z.sessionId)O=await A.saveToolResult(Z.sessionId,S.id,T.success?
|
|
2151
|
+
`),{toolCall:S,result:M,toolUseUuid:g}}catch(T){return f.error(`Tool execution failed for ${S.function.name}:`,T),{toolCall:S,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")}}};f.info(`[Agent] Executing ${P.length} tool calls in parallel`);let e=await Promise.all(P.map(m));for(let{toolCall:S,result:T,toolUseUuid:g}of e){if(L.push(T),T.metadata?.shouldExitLoop){f.debug("\uD83D\uDEAA 检测到退出循环标记,结束 Agent 循环");let A=typeof T.llmContent==="string"?T.llmContent:"循环已退出";return{success:T.success,finalMessage:A,metadata:{turnsCount:B,toolCallsCount:L.length,duration:Date.now()-X,shouldExitLoop:!0,targetMode:T.metadata?.targetMode}}}if(Y?.onToolResult&&!Y.signal?.aborted){f.debug("[Agent] Calling onToolResult:",{toolName:S.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(S,T),f.debug("[Agent] onToolResult callback completed successfully")}catch(A){f.error("[Agent] onToolResult callback error:",A)}}try{let A=this.executionEngine?.getContextManager();if(A&&Z.sessionId)O=await A.saveToolResult(Z.sessionId,S.id,T.success?dB(T.llmContent):null,g,T.success?void 0:T.error?.message)}catch(A){f.warn("[Agent] 保存工具结果失败:",A)}if(S.function.name==="TodoWrite"&&T.success&&T.llmContent){let A=typeof T.llmContent==="object"?T.llmContent:{},E=Array.isArray(A)?A:A.todos||[];K2().setTodos(E),Y?.onTodoUpdate?.(E)}if(S.function.name==="Skill"&&T.success&&T.metadata){let A=T.metadata;if(A.skillName)this.activeSkillContext={skillName:A.skillName,allowedTools:A.allowedTools,basePath:A.basePath||""},f.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);F.push({role:"tool",tool_call_id:S.id,name:S.function.name,content:M})}if(Y?.signal?.aborted)return{success:!1,error:{type:"aborted",message:"任务已被用户中止"},metadata:{turnsCount:B,toolCallsCount:L.length,duration:Date.now()-X}};if(B>=w&&!_){if(f.info(`⚠️ 达到轮次上限 ${w} 轮,等待用户确认...`),Y?.onTurnLimitReached){let S=await Y.onTurnLimitReached({turnsCount:B});if(S?.continue){f.info("✅ 用户选择继续,压缩上下文...");try{let T=this.chatService.getConfig(),g=await $3.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=F.find((A)=>A.role==="system");if(F.length=0,j)F.push(j);F.push(...Z.messages);let M={role:"user",content:`This session is being continued from a previous conversation. The conversation is summarized above.
|
|
2152
2152
|
|
|
2153
|
-
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.`};F.push(M),Z.messages.push(M);try{let A=this.executionEngine?.getContextManager();if(A&&Z.sessionId)await A.saveCompaction(Z.sessionId,g.summary,{trigger:"auto",preTokens:g.preTokens,postTokens:g.postTokens,filesIncluded:g.filesIncluded},null)}catch(A){f.warn("[Agent] 保存压缩数据失败:",A)}f.info(`✅ 上下文已压缩 (${g.preTokens} → ${g.postTokens} tokens),重置轮次计数`)}catch(T){f.error("[Agent] 压缩失败,使用降级策略:",T);let g=F.find((M)=>M.role==="system"),j=F.slice(-80);if(F.length=0,g&&!j.some((M)=>M.role==="system"))F.push(g);F.push(...j),Z.messages=F.filter((M)=>M.role!=="system"),f.warn(`⚠️ 降级压缩完成,保留 ${F.length} 条消息`)}B=0;continue}return{success:!0,finalMessage:S?.reason||"已达到对话轮次上限,用户选择停止",metadata:{turnsCount:B,toolCallsCount:L.length,duration:Date.now()-X,tokensUsed:V}}}return{success:!1,error:{type:"max_turns_exceeded",message:`已达到轮次上限 (${w} 轮)。使用 --permission-mode yolo 跳过此限制。`},metadata:{turnsCount:B,toolCallsCount:L.length,duration:Date.now()-X,tokensUsed:V}}}}}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 f.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,q=new Map;try{let G=this.chatService.streamChat($,Z,Y?.signal),K=0;for await(let W of G){if(K++,Y?.signal?.aborted)break;if(W.content){let U=W.content.length;Q+=W.content,_1("processStreamResponse","onContentDelta BEFORE",{chunkLen:U,accumulatedLen:Q.length}),Y?.onContentDelta?.(W.content),_1("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(q,U);if(W.finishReason){_1("processStreamResponse","finishReason received",{finishReason:W.finishReason,fullContentLen:Q.length,fullReasoningContentLen:X.length,toolCallAccumulatorSize:q.size});break}}if(_1("processStreamResponse","stream ended",{fullContentLen:Q.length,fullReasoningContentLen:X.length,toolCallAccumulatorSize:q.size}),K===0&&!Y?.signal?.aborted&&Q.length===0&&q.size===0)return f.warn("[Agent] 流式响应返回0个chunk,回退到非流式模式"),this.chatService.chat($,Z,Y?.signal);return{content:Q,reasoningContent:X||void 0,toolCalls:this.buildFinalToolCalls(q),usage:J}}catch(G){if(this.isStreamingNotSupportedError(G))return f.warn("[Agent] 流式请求失败,降级到非流式模式"),this.chatService.chat($,Z,Y?.signal);throw G}}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,permissionMode:Z.permissionMode,systemPrompt:Z.systemPrompt};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);f.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){f.debug(`[MainAgent] ${$}`,Z||"")}error($,Z){f.error(`[MainAgent] ${$}`,Z||"")}async initializeSystemPrompt(){try{let $=this.runtimeOptions.systemPrompt,Z=this.runtimeOptions.appendSystemPrompt,Y=await _8({projectPath:process.cwd(),replaceDefault:$,append:Z,includeEnvironment:!1});if(Y.prompt)this.log("系统提示配置验证成功"),f.debug(`[SystemPrompt] 可用来源: ${Y.sources.filter((Q)=>Q.loaded).map((Q)=>Q.name).join(", ")}`)}catch($){this.error("系统提示配置验证失败",$)}}async getSystemPrompt(){return this.buildSystemPromptOnDemand()}async checkAndCompactInLoop($,Z,Y,Q){if(Y===void 0)return f.debug(`[Agent] [轮次 ${Z}] 压缩检查: 跳过(无历史 usage 数据)`),!1;let X=this.chatService.getConfig(),J=X.model,q=X.maxContextTokens??this.config.maxContextTokens,G=X.maxOutputTokens??this.config.maxOutputTokens??8192,K=q-G,W=Math.floor(K*0.8);if(f.debug(`[Agent] [轮次 ${Z}] 压缩检查:`,{promptTokens:Y,maxContextTokens:q,maxOutputTokens:G,availableForInput:K,threshold:W,shouldCompact:Y>=W}),Y<W)return!1;let U=Z===0?"[Agent] 触发自动压缩":`[Agent] [轮次 ${Z}] 触发循环内自动压缩`;f.debug(U),Q?.(!0);try{let F=await $3.compact($.messages,{trigger:"auto",modelName:J,maxContextTokens:q,apiKey:X.apiKey,baseURL:X.baseUrl,actualPreTokens:Y});if(F.success)$.messages=F.compactedMessages,f.debug(`[Agent] [轮次 ${Z}] 压缩完成: ${F.preTokens} → ${F.postTokens} tokens (-${((1-F.postTokens/F.preTokens)*100).toFixed(1)}%)`);else $.messages=F.compactedMessages,f.warn(`[Agent] [轮次 ${Z}] 压缩使用降级策略: ${F.preTokens} → ${F.postTokens} tokens`);try{let O=this.executionEngine?.getContextManager();if(O&&$.sessionId)await O.saveCompaction($.sessionId,F.summary,{trigger:"auto",preTokens:F.preTokens,postTokens:F.postTokens,filesIncluded:F.filesIncluded},null),f.debug(`[Agent] [轮次 ${Z}] 压缩数据已保存到 JSONL`)}catch(O){f.warn(`[Agent] [轮次 ${Z}] 保存压缩数据失败:`,O)}return Q?.(!1),!0}catch(F){return Q?.(!1),f.error(`[Agent] [轮次 ${Z}] 压缩失败,继续执行`,F),!1}}async registerBuiltinTools(){try{let $=await rq({sessionId:"default",configDir:FG.join(UG.homedir(),".blade")});f.debug(`\uD83D\uDCE6 Registering ${$.length} builtin tools...`),this.executionPipeline.getRegistry().registerAll($);let Z=this.executionPipeline.getRegistry().getAll().length;f.debug(`✅ Builtin tools registered: ${Z} tools`),f.debug(`[Tools] ${this.executionPipeline.getRegistry().getAll().map((Y)=>Y.name).join(", ")}`),await this.registerMcpTools()}catch($){throw f.error("Failed to register builtin tools:",$),$}}async registerMcpTools(){try{if(this.runtimeOptions.mcpConfig&&this.runtimeOptions.mcpConfig.length>0)await zX(this.runtimeOptions.mcpConfig);let $=F1();if(Object.keys($).length===0){f.debug("\uD83D\uDCE6 No MCP servers configured");return}let Z=w$.getInstance();for(let[Q,X]of Object.entries($))try{f.debug(`\uD83D\uDD0C Connecting to MCP server: ${Q}`),await Z.registerServer(Q,X),f.debug(`✅ MCP server "${Q}" connected`)}catch(J){f.warn(`⚠️ MCP server "${Q}" connection failed:`,J)}let Y=await Z.getAvailableTools();if(Y.length>0)this.executionPipeline.getRegistry().registerAll(Y),f.debug(`✅ Registered ${Y.length} MCP tools`),f.debug(`[MCP Tools] ${Y.map((Q)=>Q.name).join(", ")}`)}catch($){f.warn("Failed to register MCP tools:",$)}}async loadSubagents(){if(
|
|
2153
|
+
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.`};F.push(M),Z.messages.push(M);try{let A=this.executionEngine?.getContextManager();if(A&&Z.sessionId)await A.saveCompaction(Z.sessionId,g.summary,{trigger:"auto",preTokens:g.preTokens,postTokens:g.postTokens,filesIncluded:g.filesIncluded},null)}catch(A){f.warn("[Agent] 保存压缩数据失败:",A)}f.info(`✅ 上下文已压缩 (${g.preTokens} → ${g.postTokens} tokens),重置轮次计数`)}catch(T){f.error("[Agent] 压缩失败,使用降级策略:",T);let g=F.find((M)=>M.role==="system"),j=F.slice(-80);if(F.length=0,g&&!j.some((M)=>M.role==="system"))F.push(g);F.push(...j),Z.messages=F.filter((M)=>M.role!=="system"),f.warn(`⚠️ 降级压缩完成,保留 ${F.length} 条消息`)}B=0;continue}return{success:!0,finalMessage:S?.reason||"已达到对话轮次上限,用户选择停止",metadata:{turnsCount:B,toolCallsCount:L.length,duration:Date.now()-X,tokensUsed:V}}}return{success:!1,error:{type:"max_turns_exceeded",message:`已达到轮次上限 (${w} 轮)。使用 --permission-mode yolo 跳过此限制。`},metadata:{turnsCount:B,toolCallsCount:L.length,duration:Date.now()-X,tokensUsed:V}}}}}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 f.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,q=new Map;try{let G=this.chatService.streamChat($,Z,Y?.signal),K=0;for await(let W of G){if(K++,Y?.signal?.aborted)break;if(W.content){let U=W.content.length;Q+=W.content,_1("processStreamResponse","onContentDelta BEFORE",{chunkLen:U,accumulatedLen:Q.length}),Y?.onContentDelta?.(W.content),_1("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(q,U);if(W.finishReason){_1("processStreamResponse","finishReason received",{finishReason:W.finishReason,fullContentLen:Q.length,fullReasoningContentLen:X.length,toolCallAccumulatorSize:q.size});break}}if(_1("processStreamResponse","stream ended",{fullContentLen:Q.length,fullReasoningContentLen:X.length,toolCallAccumulatorSize:q.size}),K===0&&!Y?.signal?.aborted&&Q.length===0&&q.size===0)return f.warn("[Agent] 流式响应返回0个chunk,回退到非流式模式"),this.chatService.chat($,Z,Y?.signal);return{content:Q,reasoningContent:X||void 0,toolCalls:this.buildFinalToolCalls(q),usage:J}}catch(G){if(this.isStreamingNotSupportedError(G))return f.warn("[Agent] 流式请求失败,降级到非流式模式"),this.chatService.chat($,Z,Y?.signal);throw G}}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,permissionMode:Z.permissionMode,systemPrompt:Z.systemPrompt};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);f.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){f.debug(`[MainAgent] ${$}`,Z||"")}error($,Z){f.error(`[MainAgent] ${$}`,Z||"")}async initializeSystemPrompt(){try{let $=this.runtimeOptions.systemPrompt,Z=this.runtimeOptions.appendSystemPrompt,Y=await _8({projectPath:process.cwd(),replaceDefault:$,append:Z,includeEnvironment:!1});if(Y.prompt)this.log("系统提示配置验证成功"),f.debug(`[SystemPrompt] 可用来源: ${Y.sources.filter((Q)=>Q.loaded).map((Q)=>Q.name).join(", ")}`)}catch($){this.error("系统提示配置验证失败",$)}}async getSystemPrompt(){return this.buildSystemPromptOnDemand()}async checkAndCompactInLoop($,Z,Y,Q){if(Y===void 0)return f.debug(`[Agent] [轮次 ${Z}] 压缩检查: 跳过(无历史 usage 数据)`),!1;let X=this.chatService.getConfig(),J=X.model,q=X.maxContextTokens??this.config.maxContextTokens,G=X.maxOutputTokens??this.config.maxOutputTokens??8192,K=q-G,W=Math.floor(K*0.8);if(f.debug(`[Agent] [轮次 ${Z}] 压缩检查:`,{promptTokens:Y,maxContextTokens:q,maxOutputTokens:G,availableForInput:K,threshold:W,shouldCompact:Y>=W}),Y<W)return!1;let U=Z===0?"[Agent] 触发自动压缩":`[Agent] [轮次 ${Z}] 触发循环内自动压缩`;f.debug(U),Q?.(!0);try{let F=await $3.compact($.messages,{trigger:"auto",modelName:J,maxContextTokens:q,apiKey:X.apiKey,baseURL:X.baseUrl,actualPreTokens:Y});if(F.success)$.messages=F.compactedMessages,f.debug(`[Agent] [轮次 ${Z}] 压缩完成: ${F.preTokens} → ${F.postTokens} tokens (-${((1-F.postTokens/F.preTokens)*100).toFixed(1)}%)`);else $.messages=F.compactedMessages,f.warn(`[Agent] [轮次 ${Z}] 压缩使用降级策略: ${F.preTokens} → ${F.postTokens} tokens`);try{let O=this.executionEngine?.getContextManager();if(O&&$.sessionId)await O.saveCompaction($.sessionId,F.summary,{trigger:"auto",preTokens:F.preTokens,postTokens:F.postTokens,filesIncluded:F.filesIncluded},null),f.debug(`[Agent] [轮次 ${Z}] 压缩数据已保存到 JSONL`)}catch(O){f.warn(`[Agent] [轮次 ${Z}] 保存压缩数据失败:`,O)}return Q?.(!1),!0}catch(F){return Q?.(!1),f.error(`[Agent] [轮次 ${Z}] 压缩失败,继续执行`,F),!1}}async registerBuiltinTools(){try{let $=await rq({sessionId:"default",configDir:FG.join(UG.homedir(),".blade")});f.debug(`\uD83D\uDCE6 Registering ${$.length} builtin tools...`),this.executionPipeline.getRegistry().registerAll($);let Z=this.executionPipeline.getRegistry().getAll().length;f.debug(`✅ Builtin tools registered: ${Z} tools`),f.debug(`[Tools] ${this.executionPipeline.getRegistry().getAll().map((Y)=>Y.name).join(", ")}`),await this.registerMcpTools()}catch($){throw f.error("Failed to register builtin tools:",$),$}}async registerMcpTools(){try{if(this.runtimeOptions.mcpConfig&&this.runtimeOptions.mcpConfig.length>0)await zX(this.runtimeOptions.mcpConfig);let $=F1();if(Object.keys($).length===0){f.debug("\uD83D\uDCE6 No MCP servers configured");return}let Z=w$.getInstance();for(let[Q,X]of Object.entries($))try{f.debug(`\uD83D\uDD0C Connecting to MCP server: ${Q}`),await Z.registerServer(Q,X),f.debug(`✅ MCP server "${Q}" connected`)}catch(J){f.warn(`⚠️ MCP server "${Q}" connection failed:`,J)}let Y=await Z.getAvailableTools();if(Y.length>0)this.executionPipeline.getRegistry().registerAll(Y),f.debug(`✅ Registered ${Y.length} MCP tools`),f.debug(`[MCP Tools] ${Y.map((Q)=>Q.name).join(", ")}`)}catch($){f.warn("Failed to register MCP tools:",$)}}async loadSubagents(){if(Z$.getAllNames().length>0){f.debug(`\uD83D\uDCE6 Subagents already loaded: ${Z$.getAllNames().join(", ")}`);return}try{let $=Z$.loadFromStandardLocations();if($>0)f.debug(`✅ Loaded ${$} subagents: ${Z$.getAllNames().join(", ")}`);else f.debug("\uD83D\uDCE6 No subagents configured")}catch($){f.warn("Failed to load subagents:",$)}}async discoverSkills(){try{let $=await _4({cwd:process.cwd()});if($.skills.length>0)f.debug(`✅ Discovered ${$.skills.length} skills: ${$.skills.map((Z)=>Z.name).join(", ")}`);else f.debug("\uD83D\uDCE6 No skills configured");for(let Z of $.errors)f.warn(`⚠️ Skill loading error at ${Z.path}: ${Z.error}`)}catch($){f.warn("Failed to discover skills:",$)}}applySkillToolRestrictions($){if(!this.activeSkillContext?.allowedTools)return $;let Z=this.activeSkillContext.allowedTools;f.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 f.debug(`\uD83D\uDD12 Filtered tools: ${Y.map((Q)=>Q.name).join(", ")} (${Y.length}/${$.length})`),Y}clearSkillContext(){if(this.activeSkillContext)f.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(`
|
|
2154
2154
|
`);try{let Q=await this.attachmentCollector.collect(Y);if(Q.length===0)return $;f.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 f.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+=`
|
|
2155
2155
|
|
|
2156
2156
|
<system-reminder>
|
|
@@ -2173,15 +2173,15 @@ Please continue the conversation from where we left it off without asking the us
|
|
|
2173
2173
|
|
|
2174
2174
|
⚠️ Some files could not be loaded:
|
|
2175
2175
|
`,X+=Q.join(`
|
|
2176
|
-
`);return X}}var f;var O2=b(()=>{a4();d9();t$();z0();l9();BX();F4();SX();gX();$5();u9();U2();z1();T0();nq();YG();QG();V$();e9();c6();WG();R4();f=l("Agent")});import{z as K0}from"zod";function _G($){return iB.safeParse($)}var dB,cB,lB,HG,OG,iB;var _Z=b(()=>{dB=K0.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"}),cB=K0.string().regex(/^\d+\.\d+\.\d+(-[\w.]+)?(\+[\w.]+)?$/,{message:"Version must be a valid semantic version (e.g., 1.0.0)"}),lB=K0.object({name:K0.string().min(1,"Author name is required"),email:K0.string().email().optional(),url:K0.string().url().optional()}),HG=K0.object({name:dB,description:K0.string().min(1,"Description is required").max(500,"Description must be at most 500 characters"),version:cB,author:lB.optional(),license:K0.string().optional(),repository:K0.string().url().optional(),homepage:K0.string().url().optional(),keywords:K0.array(K0.string()).optional(),dependencies:K0.record(K0.string()).optional(),bladeVersion:K0.string().optional()}),OG=K0.object({type:K0.enum(["stdio","sse","http"]),command:K0.string().optional(),args:K0.array(K0.string()).optional(),env:K0.record(K0.string()).optional(),url:K0.string().url().optional(),headers:K0.record(K0.string()).optional(),timeout:K0.number().positive().optional(),oauth:K0.object({enabled:K0.boolean().optional(),clientId:K0.string().optional(),clientSecret:K0.string().optional(),authorizationUrl:K0.string().url().optional(),tokenUrl:K0.string().url().optional(),scopes:K0.array(K0.string()).optional(),redirectUri:K0.string().url().optional()}).optional(),healthCheck:K0.object({enabled:K0.boolean().optional(),interval:K0.number().positive().optional(),timeout:K0.number().positive().optional(),failureThreshold:K0.number().positive().optional()}).optional()}),iB=K0.union([K0.object({mcpServers:K0.record(OG)}),K0.record(OG)])});import*as i6 from"node:fs/promises";import*as zG from"node:path";async function L3($){for(let{dir:Z,source:Y}of aB){let Q=zG.join($,Z,"plugin.json");try{await i6.access(Q)}catch{continue}try{let X=await i6.readFile(Q,"utf-8"),J=JSON.parse(X),q=HG.safeParse(J);if(!q.success){let G=q.error.issues.map((K)=>`${K.path.join(".")}: ${K.message}`).join("; ");throw Error(`Invalid plugin.json: ${G}`)}return x0.debug(`Parsed plugin manifest from ${Q}`),{manifest:q.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 BG($){try{return await L3($)!==null}catch{return!1}}var aB;var zZ=b(()=>{z0();_Z();aB=[{dir:".blade-plugin",source:"blade"},{dir:".claude-plugin",source:"claude"}]});import{execSync as wG}from"node:child_process";import*as i$ from"node:fs/promises";import{homedir as rB}from"node:os";import*as N3 from"node:path";class LG{userPluginsDir;constructor($){this.userPluginsDir=$||N3.join(rB(),".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 i$.mkdir(this.userPluginsDir,{recursive:!0,mode:493});let Q=N3.join(this.userPluginsDir,Y);try{return await i$.access(Q),{success:!1,pluginName:Y,pluginPath:Q,error:`Plugin "${Y}" already exists at ${Q}. Use /plugins uninstall first.`}}catch{}x0.info(`Cloning ${Z} to ${Q}...`);try{wG(`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 BG(Q))return await i$.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 L3(Q)}catch(J){return await i$.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 i$.rm(Q,{recursive:!0,force:!0}),{success:!1,pluginName:Y,error:"Invalid plugin manifest: No manifest found"};return x0.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=N3.join(this.userPluginsDir,$);try{await i$.access(Z)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" not found at ${Z}`}}return await i$.rm(Z,{recursive:!0,force:!0}),x0.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 i$.access(this.userPluginsDir),(await i$.readdir(this.userPluginsDir,{withFileTypes:!0})).filter((Z)=>Z.isDirectory()).map((Z)=>Z.name)}catch{return[]}}async update($){try{let Z=N3.join(this.userPluginsDir,$);try{await i$.access(Z)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" not found at ${Z}`}}let Y=N3.join(Z,".git");try{await i$.access(Y)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" is not a git repository`}}x0.info(`Updating plugin: ${$}...`);try{wG(`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 L3(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 x0.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 I8($){if(!BZ)BZ=new LG($);return BZ}var BZ=null;var NG=b(()=>{z0();zZ()});function a6($,Z){return`${$}:${Z}`}function bG($,Z){return`${$}__${Z}`}import*as X1 from"node:fs/promises";import{homedir as nB}from"node:os";import*as F$ from"node:path";import AG from"gray-matter";class r6{async loadPlugin($,Z,Y={}){let Q=await L3($);if(!Q)throw Error(`Not a valid plugin directory: ${$}`);let{manifest:X,source:J}=Q,q=X.name;x0.debug(`Loading plugin "${q}" from ${$}`);let G=Y.skipCommands?[]:await this.loadCommands($,q),K=Y.skipAgents?[]:await this.loadAgents($,q),W=Y.skipSkills?[]:await this.loadSkills($,q),U=Y.skipHooks?void 0:await this.loadHooks($),F=Y.skipMcp?void 0:await this.loadMcpConfig($,q);return x0.debug(`Plugin "${q}" loaded: ${G.length} commands, ${K.length} agents, ${W.length} skills`),{manifest:X,basePath:$,source:Z,manifestSource:J,commands:G,agents:K,skills:W,hooks:U,mcpServers:F,status:"active",loadedAt:new Date}}async loadCommands($,Z){let Y=F$.join($,"commands"),Q=[];if(!await this.dirExists(Y))return Q;let X=await this.scanMarkdownFiles(Y);for(let J of X)try{let q=await this.parseCommandFile(J,Y,Z);if(q)Q.push(q)}catch(q){x0.warn(`Failed to load command from ${J}: ${q instanceof Error?q.message:String(q)}`)}return Q}async parseCommandFile($,Z,Y){let Q=await X1.readFile($,"utf-8"),{data:X,content:J}=AG(Q),G=F$.relative(Z,$).split(F$.sep),K=G.pop();if(!K)return null;let W=K.replace(/\.md$/i,""),U=W;if(G.length>0)U=[...G,W].join("/");let F=a6(Y,U),O=this.normalizeCommandConfig(X);return{originalName:U,namespacedName:F,pluginName:Y,config:O,content:J.trim(),path:$}}normalizeCommandConfig($){return{description:this.asString($.description),allowedTools:this.parseStringArray($["allowed-tools"]),argumentHint:this.asString($["argument-hint"]),model:this.asString($.model),disableModelInvocation:$["disable-model-invocation"]===!0}}async loadAgents($,Z){let Y=F$.join($,"agents"),Q=[];if(!await this.dirExists(Y))return Q;let X=await this.scanMarkdownFiles(Y);for(let J of X)try{let q=await this.parseAgentFile(J,Y,Z);if(q)Q.push(q)}catch(q){x0.warn(`Failed to load agent from ${J}: ${q instanceof Error?q.message:String(q)}`)}return Q}async parseAgentFile($,Z,Y){let Q=await X1.readFile($,"utf-8"),{data:X,content:J}=AG(Q),q=F$.relative(Z,$),G=F$.basename(q,".md"),K=X.name||G,W=a6(Y,K),U={name:W,description:this.asString(X.description)||"",tools:this.parseStringArray(X.tools),color:this.asString(X.color),model:this.asString(X.model),permissionMode:this.asString(X.permissionMode),skills:this.parseStringArray(X.skills),systemPrompt:J.trim(),source:`plugin:${Y}`};return{originalName:K,namespacedName:W,pluginName:Y,config:U,path:$}}async loadSkills($,Z){let Y=F$.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 q=F$.join(Y,J.name),G=F$.join(q,"SKILL.md");try{let K=await z6(G,"project");if(K.success&&K.content){let W=K.content.metadata.name,U=a6(Z,W);Q.push({originalName:W,namespacedName:U,pluginName:Z,metadata:{...K.content.metadata,name:U},path:q})}}catch(K){x0.warn(`Failed to load skill from ${G}: ${K instanceof Error?K.message:String(K)}`)}}return Q}async loadHooks($){let Z=F$.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=F$.join($,".mcp.json");try{let Q=await X1.readFile(Y,"utf-8"),X=JSON.parse(Q),J=_G(X);if(!J.success){x0.warn(`Invalid .mcp.json in ${$}: ${J.error}`);return}let q="mcpServers"in X?X.mcpServers:X,G={};for(let[K,W]of Object.entries(q)){let U=bG(Z,K);G[U]=W}return G}catch{return}}async scanMarkdownFiles($){let Z=[],Y=async(Q)=>{let X=await X1.readdir(Q,{withFileTypes:!0});for(let J of X){let q=F$.join(Q,J.name);if(J.isDirectory())await Y(q);else if(J.name.endsWith(".md"))Z.push(q)}};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:F$.join(Z,".claude","plugins"),source:"user",type:"claude"},{path:F$.join(Z,".blade","plugins"),source:"user",type:"blade"},{path:F$.join($,".claude","plugins"),source:"project",type:"claude"},{path:F$.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 q=F$.join($,J.name);try{let G=await this.loadPlugin(q,Z);Y.push(G)}catch(G){Q.push({path:q,error:G instanceof Error?G.message:String(G)})}}return{plugins:Y,errors:Q}}}var RG=b(()=>{z0();n9();zZ();_Z()});class M4{static instance=null;plugins=new Map;loader=new r6;initialized=!1;workspaceRoot="";cliPluginDirs=[];constructor(){}static getInstance(){if(!M4.instance)M4.instance=new M4;return M4.instance}static resetInstance(){M4.instance=null}async initialize($,Z=[]){this.workspaceRoot=$,this.cliPluginDirs=Z;let Y=[],Q=[];for(let J of Z)try{let q=await this.loader.loadPlugin(J,"cli");this.plugins.set(q.manifest.name,q),Y.push(q),x0.info(`Loaded CLI plugin: ${q.manifest.name} from ${J}`)}catch(q){Q.push({path:J,error:q instanceof Error?q.message:String(q)}),x0.warn(`Failed to load CLI plugin from ${J}: ${q}`)}let X=r6.getPluginDirs($);for(let{path:J,source:q}of X){let G=await this.loader.discoverPluginsInDir(J,q);for(let K of G.plugins){let W=this.plugins.get(K.manifest.name);if(!W||W.source!=="cli")this.plugins.set(K.manifest.name,K),Y.push(K)}Q.push(...G.errors)}return this.initialized=!0,x0.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",x0.info(`Plugin "${$}" disabled`),!0;return!1}enable($){let Z=this.plugins.get($);if(Z&&Z.status==="inactive")return Z.status="active",x0.info(`Plugin "${$}" enabled`),!0;return!1}async refresh(){return x0.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(`
|
|
2177
|
-
`)}}function a$(){return M4.getInstance()}var wZ=b(()=>{z0();RG()});class LZ{commandRegistry;hookManager;mcpRegistry;constructor(){this.commandRegistry=_$.getInstance(),this.hookManager=R0.getInstance(),this.mcpRegistry=w$.getInstance()}clearAllPluginResources(){this.commandRegistry.clearPluginCommands(),N$().clearPluginSkills(),
|
|
2176
|
+
`);return X}}var f;var O2=b(()=>{a4();d9();t$();z0();l9();BX();F4();SX();gX();$5();u9();U2();z1();T0();nq();YG();QG();V$();e9();c6();WG();R4();f=l("Agent")});import{z as K0}from"zod";function _G($){return aB.safeParse($)}var cB,lB,iB,HG,OG,aB;var _Z=b(()=>{cB=K0.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"}),lB=K0.string().regex(/^\d+\.\d+\.\d+(-[\w.]+)?(\+[\w.]+)?$/,{message:"Version must be a valid semantic version (e.g., 1.0.0)"}),iB=K0.object({name:K0.string().min(1,"Author name is required"),email:K0.string().email().optional(),url:K0.string().url().optional()}),HG=K0.object({name:cB,description:K0.string().min(1,"Description is required").max(500,"Description must be at most 500 characters"),version:lB,author:iB.optional(),license:K0.string().optional(),repository:K0.string().url().optional(),homepage:K0.string().url().optional(),keywords:K0.array(K0.string()).optional(),dependencies:K0.record(K0.string()).optional(),bladeVersion:K0.string().optional()}),OG=K0.object({type:K0.enum(["stdio","sse","http"]),command:K0.string().optional(),args:K0.array(K0.string()).optional(),env:K0.record(K0.string()).optional(),url:K0.string().url().optional(),headers:K0.record(K0.string()).optional(),timeout:K0.number().positive().optional(),oauth:K0.object({enabled:K0.boolean().optional(),clientId:K0.string().optional(),clientSecret:K0.string().optional(),authorizationUrl:K0.string().url().optional(),tokenUrl:K0.string().url().optional(),scopes:K0.array(K0.string()).optional(),redirectUri:K0.string().url().optional()}).optional(),healthCheck:K0.object({enabled:K0.boolean().optional(),interval:K0.number().positive().optional(),timeout:K0.number().positive().optional(),failureThreshold:K0.number().positive().optional()}).optional()}),aB=K0.union([K0.object({mcpServers:K0.record(OG)}),K0.record(OG)])});import*as i6 from"node:fs/promises";import*as zG from"node:path";async function L3($){for(let{dir:Z,source:Y}of rB){let Q=zG.join($,Z,"plugin.json");try{await i6.access(Q)}catch{continue}try{let X=await i6.readFile(Q,"utf-8"),J=JSON.parse(X),q=HG.safeParse(J);if(!q.success){let G=q.error.issues.map((K)=>`${K.path.join(".")}: ${K.message}`).join("; ");throw Error(`Invalid plugin.json: ${G}`)}return x0.debug(`Parsed plugin manifest from ${Q}`),{manifest:q.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 BG($){try{return await L3($)!==null}catch{return!1}}var rB;var zZ=b(()=>{z0();_Z();rB=[{dir:".blade-plugin",source:"blade"},{dir:".claude-plugin",source:"claude"}]});import{execSync as wG}from"node:child_process";import*as i$ from"node:fs/promises";import{homedir as nB}from"node:os";import*as N3 from"node:path";class LG{userPluginsDir;constructor($){this.userPluginsDir=$||N3.join(nB(),".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 i$.mkdir(this.userPluginsDir,{recursive:!0,mode:493});let Q=N3.join(this.userPluginsDir,Y);try{return await i$.access(Q),{success:!1,pluginName:Y,pluginPath:Q,error:`Plugin "${Y}" already exists at ${Q}. Use /plugins uninstall first.`}}catch{}x0.info(`Cloning ${Z} to ${Q}...`);try{wG(`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 BG(Q))return await i$.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 L3(Q)}catch(J){return await i$.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 i$.rm(Q,{recursive:!0,force:!0}),{success:!1,pluginName:Y,error:"Invalid plugin manifest: No manifest found"};return x0.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=N3.join(this.userPluginsDir,$);try{await i$.access(Z)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" not found at ${Z}`}}return await i$.rm(Z,{recursive:!0,force:!0}),x0.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 i$.access(this.userPluginsDir),(await i$.readdir(this.userPluginsDir,{withFileTypes:!0})).filter((Z)=>Z.isDirectory()).map((Z)=>Z.name)}catch{return[]}}async update($){try{let Z=N3.join(this.userPluginsDir,$);try{await i$.access(Z)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" not found at ${Z}`}}let Y=N3.join(Z,".git");try{await i$.access(Y)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" is not a git repository`}}x0.info(`Updating plugin: ${$}...`);try{wG(`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 L3(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 x0.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 I8($){if(!BZ)BZ=new LG($);return BZ}var BZ=null;var NG=b(()=>{z0();zZ()});function a6($,Z){return`${$}:${Z}`}function bG($,Z){return`${$}__${Z}`}import*as X1 from"node:fs/promises";import{homedir as oB}from"node:os";import*as F$ from"node:path";import AG from"gray-matter";class r6{async loadPlugin($,Z,Y={}){let Q=await L3($);if(!Q)throw Error(`Not a valid plugin directory: ${$}`);let{manifest:X,source:J}=Q,q=X.name;x0.debug(`Loading plugin "${q}" from ${$}`);let G=Y.skipCommands?[]:await this.loadCommands($,q),K=Y.skipAgents?[]:await this.loadAgents($,q),W=Y.skipSkills?[]:await this.loadSkills($,q),U=Y.skipHooks?void 0:await this.loadHooks($),F=Y.skipMcp?void 0:await this.loadMcpConfig($,q);return x0.debug(`Plugin "${q}" loaded: ${G.length} commands, ${K.length} agents, ${W.length} skills`),{manifest:X,basePath:$,source:Z,manifestSource:J,commands:G,agents:K,skills:W,hooks:U,mcpServers:F,status:"active",loadedAt:new Date}}async loadCommands($,Z){let Y=F$.join($,"commands"),Q=[];if(!await this.dirExists(Y))return Q;let X=await this.scanMarkdownFiles(Y);for(let J of X)try{let q=await this.parseCommandFile(J,Y,Z);if(q)Q.push(q)}catch(q){x0.warn(`Failed to load command from ${J}: ${q instanceof Error?q.message:String(q)}`)}return Q}async parseCommandFile($,Z,Y){let Q=await X1.readFile($,"utf-8"),{data:X,content:J}=AG(Q),G=F$.relative(Z,$).split(F$.sep),K=G.pop();if(!K)return null;let W=K.replace(/\.md$/i,""),U=W;if(G.length>0)U=[...G,W].join("/");let F=a6(Y,U),O=this.normalizeCommandConfig(X);return{originalName:U,namespacedName:F,pluginName:Y,config:O,content:J.trim(),path:$}}normalizeCommandConfig($){return{description:this.asString($.description),allowedTools:this.parseStringArray($["allowed-tools"]),argumentHint:this.asString($["argument-hint"]),model:this.asString($.model),disableModelInvocation:$["disable-model-invocation"]===!0}}async loadAgents($,Z){let Y=F$.join($,"agents"),Q=[];if(!await this.dirExists(Y))return Q;let X=await this.scanMarkdownFiles(Y);for(let J of X)try{let q=await this.parseAgentFile(J,Y,Z);if(q)Q.push(q)}catch(q){x0.warn(`Failed to load agent from ${J}: ${q instanceof Error?q.message:String(q)}`)}return Q}async parseAgentFile($,Z,Y){let Q=await X1.readFile($,"utf-8"),{data:X,content:J}=AG(Q),q=F$.relative(Z,$),G=F$.basename(q,".md"),K=X.name||G,W=a6(Y,K),U={name:W,description:this.asString(X.description)||"",tools:this.parseStringArray(X.tools),color:this.asString(X.color),model:this.asString(X.model),permissionMode:this.asString(X.permissionMode),skills:this.parseStringArray(X.skills),systemPrompt:J.trim(),source:`plugin:${Y}`};return{originalName:K,namespacedName:W,pluginName:Y,config:U,path:$}}async loadSkills($,Z){let Y=F$.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 q=F$.join(Y,J.name),G=F$.join(q,"SKILL.md");try{let K=await z6(G,"project");if(K.success&&K.content){let W=K.content.metadata.name,U=a6(Z,W);Q.push({originalName:W,namespacedName:U,pluginName:Z,metadata:{...K.content.metadata,name:U},path:q})}}catch(K){x0.warn(`Failed to load skill from ${G}: ${K instanceof Error?K.message:String(K)}`)}}return Q}async loadHooks($){let Z=F$.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=F$.join($,".mcp.json");try{let Q=await X1.readFile(Y,"utf-8"),X=JSON.parse(Q),J=_G(X);if(!J.success){x0.warn(`Invalid .mcp.json in ${$}: ${J.error}`);return}let q="mcpServers"in X?X.mcpServers:X,G={};for(let[K,W]of Object.entries(q)){let U=bG(Z,K);G[U]=W}return G}catch{return}}async scanMarkdownFiles($){let Z=[],Y=async(Q)=>{let X=await X1.readdir(Q,{withFileTypes:!0});for(let J of X){let q=F$.join(Q,J.name);if(J.isDirectory())await Y(q);else if(J.name.endsWith(".md"))Z.push(q)}};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=oB();return[{path:F$.join(Z,".claude","plugins"),source:"user",type:"claude"},{path:F$.join(Z,".blade","plugins"),source:"user",type:"blade"},{path:F$.join($,".claude","plugins"),source:"project",type:"claude"},{path:F$.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 q=F$.join($,J.name);try{let G=await this.loadPlugin(q,Z);Y.push(G)}catch(G){Q.push({path:q,error:G instanceof Error?G.message:String(G)})}}return{plugins:Y,errors:Q}}}var RG=b(()=>{z0();n9();zZ();_Z()});class M4{static instance=null;plugins=new Map;loader=new r6;initialized=!1;workspaceRoot="";cliPluginDirs=[];constructor(){}static getInstance(){if(!M4.instance)M4.instance=new M4;return M4.instance}static resetInstance(){M4.instance=null}async initialize($,Z=[]){this.workspaceRoot=$,this.cliPluginDirs=Z;let Y=[],Q=[];for(let J of Z)try{let q=await this.loader.loadPlugin(J,"cli");this.plugins.set(q.manifest.name,q),Y.push(q),x0.info(`Loaded CLI plugin: ${q.manifest.name} from ${J}`)}catch(q){Q.push({path:J,error:q instanceof Error?q.message:String(q)}),x0.warn(`Failed to load CLI plugin from ${J}: ${q}`)}let X=r6.getPluginDirs($);for(let{path:J,source:q}of X){let G=await this.loader.discoverPluginsInDir(J,q);for(let K of G.plugins){let W=this.plugins.get(K.manifest.name);if(!W||W.source!=="cli")this.plugins.set(K.manifest.name,K),Y.push(K)}Q.push(...G.errors)}return this.initialized=!0,x0.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",x0.info(`Plugin "${$}" disabled`),!0;return!1}enable($){let Z=this.plugins.get($);if(Z&&Z.status==="inactive")return Z.status="active",x0.info(`Plugin "${$}" enabled`),!0;return!1}async refresh(){return x0.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(`
|
|
2177
|
+
`)}}function a$(){return M4.getInstance()}var wZ=b(()=>{z0();RG()});class LZ{commandRegistry;hookManager;mcpRegistry;constructor(){this.commandRegistry=_$.getInstance(),this.hookManager=R0.getInstance(),this.mcpRegistry=w$.getInstance()}clearAllPluginResources(){this.commandRegistry.clearPluginCommands(),N$().clearPluginSkills(),Z$.clearPluginAgents(),x0.debug("Cleared all plugin resources from subsystems")}async integrateAll(){let Z=a$().getActive(),Y=[],Q=[],X=0,J=0,q=0,G=0;for(let K of Z){let W=await this.integratePlugin(K);Y.push(W),X+=W.commandsRegistered,J+=W.skillsRegistered,q+=W.agentsRegistered,G+=W.mcpServersRegistered,Q.push(...W.errors)}if(X+J+q>0)x0.info(`Plugin integration complete: ${X} commands, ${J} skills, ${q} agents, ${G} MCP servers`);return{plugins:Y,totalCommands:X,totalSkills:J,totalAgents:q,totalMcpServers:G,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 x0.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=N$(),Y=0;for(let Q of $.skills)Z.registerPluginSkill(Q),Y++;return Y}integrateAgents($){let Z=0;for(let Y of $.agents)Z$.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){x0.warn(`Failed to register MCP server "${Y}" from plugin "${$.manifest.name}": ${X instanceof Error?X.message:String(X)}`)}return Z}}async function g2(){return new LZ().integrateAll()}function n6(){new LZ().clearAllPluginResources()}var VG=b(()=>{R4();t$();z0();F4();U2();h5();wZ()});var b3=b(()=>{NG();VG();wZ()});function f0($){if($.acp)return{sendMessage:(Z)=>$.acp.sendMessage(`• ${Z}
|
|
2178
2178
|
|
|
2179
|
-
`),sendToolStart:$.acp.sendToolStart,sendToolResult:$.acp.sendToolResult};return{sendMessage:(Z)=>H0().addAssistantMessage(Z),sendToolStart:void 0,sendToolResult:void 0}}var p1=b(()=>{T0()});import
|
|
2179
|
+
`),sendToolStart:$.acp.sendToolStart,sendToolResult:$.acp.sendToolResult};return{sendMessage:(Z)=>H0().addAssistantMessage(Z),sendToolStart:void 0,sendToolResult:void 0}}var p1=b(()=>{T0()});import sB from"node:os";import DG from"node:path";var MG;var jG=b(()=>{R4();p1();MG={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=f0(Z);if(!Y)return{success:!0,message:"show_agents_manager",data:{action:"show_agents_manager"}};if(Y==="list"){let J=Z$.getAllNames().map((F)=>Z$.getSubagent(F)).filter((F)=>F!==void 0);if(J.length===0){let F=`\uD83D\uDCCB **Agents 管理**
|
|
2180
2180
|
|
|
2181
2181
|
`+`❌ 没有找到任何 agent 配置
|
|
2182
2182
|
|
|
2183
2183
|
`+`**配置文件位置:**
|
|
2184
|
-
`+"- 项目级: `.blade/agents/`\n"+"- 用户级: `~/.blade/agents/`\n\n"+"\uD83D\uDCA1 使用 `/agents` 打开管理对话框";return Q.sendMessage(F),{success:!0,message:"No agents found"}}let q=DG.join(process.cwd(),".blade","agents"),G=DG.join(
|
|
2184
|
+
`+"- 项目级: `.blade/agents/`\n"+"- 用户级: `~/.blade/agents/`\n\n"+"\uD83D\uDCA1 使用 `/agents` 打开管理对话框";return Q.sendMessage(F),{success:!0,message:"No agents found"}}let q=DG.join(process.cwd(),".blade","agents"),G=DG.join(sB.homedir(),".blade","agents"),K=J.filter((F)=>F.configPath?.startsWith(q)),W=J.filter((F)=>F.configPath?.startsWith(G)),U=`\uD83D\uDCCB **Agents 管理**
|
|
2185
2185
|
|
|
2186
2186
|
找到 **${J.length}** 个 agent:
|
|
2187
2187
|
|
|
@@ -2221,7 +2221,7 @@ Please continue the conversation from where we left it off without asking the us
|
|
|
2221
2221
|
`+"- 项目级 (`.blade/agents/`) - 最高优先级\n"+"- 用户级 (`~/.blade/agents/`) - 较低优先级\n\n"+`**可用工具:**
|
|
2222
2222
|
`+"- `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}\`
|
|
2223
2223
|
|
|
2224
|
-
`+"使用 `/agents help` 查看可用命令";return Q.sendMessage(X),{success:!1,error:`Unknown subcommand: ${Y}`}}}});async function
|
|
2224
|
+
`+"使用 `/agents help` 查看可用命令";return Q.sendMessage(X),{success:!1,error:`Unknown subcommand: ${Y}`}}}});async function tB($,Z){let Y=f0(Z);try{let Q=K$(),X=n4();if(!Q||!X)return{success:!1,error:"配置未初始化"};let J=J0().session,q=J.messages,G=J.sessionId;if(!q||q.length===0)return Y.sendMessage("⚠️ 当前会话没有消息,无需压缩"),{success:!1,error:"没有消息需要压缩"};let K=q.map((H)=>({role:H.role,content:H.content})),W=W2.countTokens(K,X.model),U=X.maxContextTokens??Q.maxContextTokens,F=(W/U*100).toFixed(1);if(Y.sendMessage(`\uD83D\uDCCA **当前上下文统计**
|
|
2225
2225
|
• 消息数量: ${K.length}
|
|
2226
2226
|
• Token 数量: ${W.toLocaleString()}
|
|
2227
2227
|
• Token 限制: ${U.toLocaleString()}
|
|
@@ -2243,11 +2243,11 @@ Please continue the conversation from where we left it off without asking the us
|
|
|
2243
2243
|
• 压缩后: ${O.postTokens.toLocaleString()} tokens
|
|
2244
2244
|
|
|
2245
2245
|
\uD83D\uDCA1 由于压缩过程出现错误,已使用简单截断策略。
|
|
2246
|
-
错误信息: ${O.error}`),{success:!1,message:"compact_fallback",error:O.error,data:{compactedMessages:O.compactedMessages,boundaryMessage:O.boundaryMessage,summaryMessage:O.summaryMessage,preTokens:O.preTokens,postTokens:O.postTokens}}}catch(Q){let X=Q instanceof Error?Q.message:String(Q);return Y.sendMessage(`❌ **压缩失败**: ${X}`),{success:!1,error:X}}}var
|
|
2246
|
+
错误信息: ${O.error}`),{success:!1,message:"compact_fallback",error:O.error,data:{compactedMessages:O.compactedMessages,boundaryMessage:O.boundaryMessage,summaryMessage:O.summaryMessage,preTokens:O.preTokens,postTokens:O.postTokens}}}catch(Q){let X=Q instanceof Error?Q.message:String(Q);return Y.sendMessage(`❌ **压缩失败**: ${X}`),{success:!1,error:X}}}var eB,IG;var yG=b(()=>{d9();OZ();O6();T0();p1();eB={name:"compact",description:"手动压缩当前会话的上下文",fullDescription:"压缩当前对话历史,生成详细的技术总结,保留最近的消息。压缩后的上下文可以节省 token 使用量,同时保留关键信息。",usage:"/compact",examples:["/compact"],category:"context",handler:tB},IG=eB});function TG($){let Z=Math.floor((Date.now()-$.getTime())/1000);if(Z<60)return`${Z}s ago`;let Y=Math.floor(Z/60);if(Y<60)return`${Y}m ago`;let Q=Math.floor(Y/60);if(Q<24)return`${Q}h ago`;return`${Math.floor(Q/24)}d ago`}async function $w($){let Z=w$.getInstance(),Y=F1();if(Object.keys(Y).length===0){$.sendMessage(`\uD83D\uDD0C **MCP 服务器状态**
|
|
2247
2247
|
|
|
2248
2248
|
⚠️ 暂无配置的 MCP 服务器
|
|
2249
2249
|
|
|
2250
|
-
\uD83D\uDCA1 使用 \`blade mcp add\` 命令添加 MCP 服务器`);return}$.sendMessage("\uD83D\uDD0D 正在检查 MCP 服务器状态...");let Q=Object.entries(Y).map(async([X,J])=>{try{let q=Z.getServerStatus(X);if(!q)await Z.registerServer(X,J),q=Z.getServerStatus(X);else if(q.status==="disconnected")await Z.connectServer(X);return{name:X,config:J,serverInfo:Z.getServerStatus(X)}}catch(q){return{name:X,config:J,serverInfo:null,error:q}}});await Promise.all(Q)
|
|
2250
|
+
\uD83D\uDCA1 使用 \`blade mcp add\` 命令添加 MCP 服务器`);return}$.sendMessage("\uD83D\uDD0D 正在检查 MCP 服务器状态...");let Q=Object.entries(Y).map(async([X,J])=>{try{let q=Z.getServerStatus(X);if(!q)await Z.registerServer(X,J),q=Z.getServerStatus(X);else if(q.status==="disconnected")await Z.connectServer(X);return{name:X,config:J,serverInfo:Z.getServerStatus(X)}}catch(q){return{name:X,config:J,serverInfo:null,error:q}}});await Promise.all(Q),Zw($,Z.getAllServers())}function Zw($,Z){let Y=`\uD83D\uDD0C **MCP 服务器状态**
|
|
2251
2251
|
|
|
2252
2252
|
`,Q=0,X=0,J=0;for(let[q,G]of Z){let{config:K,status:W,connectedAt:U,lastError:F,tools:O}=G,H=W==="connected"?"✓":"✗",_=W==="connected"?"Connected":"Disconnected";if(W==="connected")Q++,J+=O.length;else X++;if(Y+=`\uD83D\uDCE6 **${q}**
|
|
2253
2253
|
`,Y+=` 状态: ${H} ${_}
|
|
@@ -2262,10 +2262,10 @@ Please continue the conversation from where we left it off without asking the us
|
|
|
2262
2262
|
`,Y+=`- 服务器: ${Z.size} 个 (${Q} 连接, ${X} 断开)
|
|
2263
2263
|
`,Y+=`- 可用工具: ${J} 个
|
|
2264
2264
|
|
|
2265
|
-
`,Y+="\uD83D\uDCA1 使用 `/mcp <server-name>` 查看详细信息\n",Y+="\uD83D\uDCA1 使用 `/mcp tools` 查看所有工具",$.sendMessage(Y)}async function
|
|
2265
|
+
`,Y+="\uD83D\uDCA1 使用 `/mcp <server-name>` 查看详细信息\n",Y+="\uD83D\uDCA1 使用 `/mcp tools` 查看所有工具",$.sendMessage(Y)}async function Yw($,Z){let Y=w$.getInstance(),X=F1()[Z];if(!X){$.sendMessage(`❌ 服务器 "${Z}" 不存在
|
|
2266
2266
|
|
|
2267
|
-
\uD83D\uDCA1 使用 \`/mcp\` 查看所有可用服务器`);return}try{let J=Y.getServerStatus(Z);if(!J)$.sendMessage(`\uD83D\uDD0D 正在连接 ${Z}...`),await Y.registerServer(Z,X),J=Y.getServerStatus(Z);else if(J.status==="disconnected")$.sendMessage(`\uD83D\uDD0D 正在重新连接 ${Z}...`),await Y.connectServer(Z),J=Y.getServerStatus(Z);if(J)
|
|
2268
|
-
⚠️ 连接失败: ${J instanceof Error?J.message:"未知错误"}`)}}function
|
|
2267
|
+
\uD83D\uDCA1 使用 \`/mcp\` 查看所有可用服务器`);return}try{let J=Y.getServerStatus(Z);if(!J)$.sendMessage(`\uD83D\uDD0D 正在连接 ${Z}...`),await Y.registerServer(Z,X),J=Y.getServerStatus(Z);else if(J.status==="disconnected")$.sendMessage(`\uD83D\uDD0D 正在重新连接 ${Z}...`),await Y.connectServer(Z),J=Y.getServerStatus(Z);if(J)Qw($,Z,J);else vG($,Z,X)}catch(J){vG($,Z,X),$.sendMessage(`
|
|
2268
|
+
⚠️ 连接失败: ${J instanceof Error?J.message:"未知错误"}`)}}function Qw($,Z,Y){let{config:Q,status:X,connectedAt:J,lastError:q,tools:G}=Y,K=X==="connected"?"✓":"✗",W=X==="connected"?"Connected":"Disconnected",U=`\uD83D\uDCE6 **${Z}**
|
|
2269
2269
|
|
|
2270
2270
|
`;if(U+=`**连接状态:**
|
|
2271
2271
|
`,U+=` ${K} ${W}`,J&&X==="connected")U+=` (连接于 ${TG(J)})`;if(U+=`
|
|
@@ -2300,7 +2300,7 @@ Please continue the conversation from where we left it off without asking the us
|
|
|
2300
2300
|
`,Y.headers&&Object.keys(Y.headers).length>0)Q+=` Headers: ${Object.keys(Y.headers).join(", ")}
|
|
2301
2301
|
`;if(Y.timeout)Q+=` 超时: ${Y.timeout}ms
|
|
2302
2302
|
`;Q+=`
|
|
2303
|
-
\uD83D\uDCA1 服务器将在 Agent 启动时自动连接`,$.sendMessage(Q)}async function
|
|
2303
|
+
\uD83D\uDCA1 服务器将在 Agent 启动时自动连接`,$.sendMessage(Q)}async function Xw($){let Z=w$.getInstance(),Y=F1();if(Object.keys(Y).length===0){$.sendMessage(`\uD83D\uDD27 **可用的 MCP 工具**
|
|
2304
2304
|
|
|
2305
2305
|
⚠️ 暂无配置的 MCP 服务器
|
|
2306
2306
|
|
|
@@ -2313,11 +2313,11 @@ Please continue the conversation from where we left it off without asking the us
|
|
|
2313
2313
|
|
|
2314
2314
|
`;continue}q+=U.length;for(let F of U){if(J+=` • ${F.name}`,F.description){let O=F.description.length>60?F.description.substring(0,57)+"...":F.description;J+=` - ${O}`}J+=`
|
|
2315
2315
|
`}J+=`
|
|
2316
|
-
`}J+=`**总计:** ${q} 个工具可用`,$.sendMessage(J)}var
|
|
2316
|
+
`}J+=`**总计:** ${q} 个工具可用`,$.sendMessage(J)}var Jw,EG;var PG=b(()=>{F4();o4();T0();p1();Jw={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=f0(Z);try{if(console.log("[MCP Command] Received args:",$),$.length===0)return await $w(Y),{success:!0,message:"MCP 服务器概览已显示"};let Q=$[0];if(console.log("[MCP Command] Subcommand:",Q),Q==="tools")return await Xw(Y),{success:!0,message:"MCP 工具列表已显示"};return await Yw(Y,Q),{success:!0,message:`服务器 "${Q}" 详情已显示`}}catch(Q){return{success:!1,error:`显示 MCP 信息失败: ${Q instanceof Error?Q.message:"未知错误"}`}}}},EG=Jw});async function qw($,Z){return{success:!0,message:"show_permissions_editor",data:{action:"show_permissions_editor"}}}var Gw,o6;var NZ=b(()=>{Gw={name:"permissions",description:"管理项目的本地权限规则",fullDescription:"打开权限管理器,管理 .blade/settings.local.json 中的权限规则",usage:"/permissions",aliases:["perm"],category:"ui",handler:qw},o6=Gw});import{readdir as CG,readFile as SG}from"node:fs/promises";import*as s6 from"node:path";class w1{static async listSessions(){let $=[],Z=s6.join(w4(),"projects");try{let Y=await CG(Z,{withFileTypes:!0});for(let Q of Y){if(!Q.isDirectory())continue;let X=s6.join(Z,Q.name),J=tX(Q.name),G=(await CG(X)).filter((K)=>K.endsWith(".jsonl"));for(let K of G){let W=s6.join(X,K),U=K.replace(".jsonl","");try{let F=await this.extractMetadata(W,U,J);$.push(F)}catch(F){j4.warn(`[SessionService] 跳过损坏的会话文件: ${W}`,F)}}}return $.sort((Q,X)=>new Date(X.lastMessageTime).getTime()-new Date(Q.lastMessageTime).getTime()),$}catch(Y){return j4.error("[SessionService] 列出会话失败:",Y),[]}}static async extractMetadata($,Z,Y){let X=(await SG($,"utf-8")).trim().split(`
|
|
2317
2317
|
`).filter((K)=>K.trim());if(X.length===0)throw Error("空的 JSONL 文件");let J=JSON.parse(X[0]),q=JSON.parse(X[X.length-1]),G=X.some((K)=>{try{let W=JSON.parse(K);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:q.timestamp,hasErrors:G,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 j4.error(`[SessionService] 加载会话失败 (${$}):`,Y),Y}}static async loadSessionFromFile($){let Q=(await SG($,"utf-8")).trim().split(`
|
|
2318
|
-
`).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,j4.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"){j4.debug("[SessionService] 跳过 compact_boundary 消息");continue}switch(J.type){case"user":case"assistant":case"system":{let q={role:J.message.role,content:typeof J.message.content==="string"?J.message.content:JSON.stringify(J.message.content)};if(J.isCompactSummary)j4.debug("[SessionService] 加载压缩总结消息");Z.push(q);break}case"tool_result":if(J.toolResult){let q=J.toolResult.error?`Error: ${J.toolResult.error}`:typeof J.toolResult.output==="string"?J.toolResult.output:JSON.stringify(J.toolResult.output);Z.push({role:"tool",content:q,tool_call_id:J.toolResult.id,name:J.tool?.name})}break;case"tool_use":break;default:break}}if(Y>=0)j4.debug(`[SessionService] 会话已压缩,跳过前 ${Y} 条历史,加载 ${Z.length} 条消息`);return Z}static getSessionFilePath($,Z){return B1($,Z)}}var j4;var t6=b(()=>{L8();z0();j4=l("Service")});var
|
|
2318
|
+
`).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,j4.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"){j4.debug("[SessionService] 跳过 compact_boundary 消息");continue}switch(J.type){case"user":case"assistant":case"system":{let q={role:J.message.role,content:typeof J.message.content==="string"?J.message.content:JSON.stringify(J.message.content)};if(J.isCompactSummary)j4.debug("[SessionService] 加载压缩总结消息");Z.push(q);break}case"tool_result":if(J.toolResult){let q=J.toolResult.error?`Error: ${J.toolResult.error}`:typeof J.toolResult.output==="string"?J.toolResult.output:JSON.stringify(J.toolResult.output);Z.push({role:"tool",content:q,tool_call_id:J.toolResult.id,name:J.tool?.name})}break;case"tool_use":break;default:break}}if(Y>=0)j4.debug(`[SessionService] 会话已压缩,跳过前 ${Y} 条历史,加载 ${Z.length} 条消息`);return Z}static getSessionFilePath($,Z){return B1($,Z)}}var j4;var t6=b(()=>{L8();z0();j4=l("Service")});var Kw,kG;var fG=b(()=>{t6();T0();p1();Kw={name:"resume",description:"Resume a conversation",fullDescription:"恢复历史会话。可以指定 sessionId 直接恢复,或不带参数打开会话选择器",usage:"/resume [sessionId]",aliases:["r"],category:"Session",examples:["/resume - 打开会话选择器","/resume abc123xyz - 直接恢复指定的会话"],async handler($,Z){let Y=f0(Z),Q=H0().restoreSession;if($.length>0){let X=$[0];try{let J=await w1.loadSession(X);if(J.length===0)return Y.sendMessage(`❌ 会话 \`${X}\` 为空或无法加载`),{success:!1,error:"会话为空"};let q=J.filter((G)=>G.role!=="tool").map((G,K)=>({id:`restored-${Date.now()}-${K}`,role:G.role,content:typeof G.content==="string"?G.content:JSON.stringify(G.content),timestamp:Date.now()-(J.length-K)*1000}));return Q(X,q),Y.sendMessage(`✅ 已恢复会话 \`${X}\`
|
|
2319
2319
|
|
|
2320
|
-
共 ${q.length} 条消息已加载,可以继续对话`),{success:!0,message:"session_restored",data:{sessionId:X,messageCount:q.length}}}catch(J){let q=J instanceof Error?J.message:"未知错误";return Y.sendMessage(`❌ 加载会话失败: ${q}`),{success:!1,error:`加载会话失败: ${q}`}}}try{let X=await w1.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}`}}}},kG=
|
|
2320
|
+
共 ${q.length} 条消息已加载,可以继续对话`),{success:!0,message:"session_restored",data:{sessionId:X,messageCount:q.length}}}catch(J){let q=J instanceof Error?J.message:"未知错误";return Y.sendMessage(`❌ 加载会话失败: ${q}`),{success:!1,error:`加载会话失败: ${q}`}}}try{let X=await w1.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}`}}}},kG=Kw});import hG from"node:fs/promises";import xG from"node:path";var Ww,Uw,Fw,Ow,Hw,_w,pG;var mG=b(()=>{O6();T0();d3();jG();yG();x6();PG();NZ();fG();p1();Ww={name:"help",description:"Show all available slash commands",fullDescription:"显示所有可用的 slash commands 及其使用方法",usage:"/help",aliases:["h"],async handler($,Z){let Y=f0(Z),Q=`\uD83D\uDD27 **可用的 Slash Commands:**
|
|
2321
2321
|
|
|
2322
2322
|
**/init** - 分析当前项目并生成 BLADE.md 配置文件
|
|
2323
2323
|
**/git** - Git 仓库查询和 AI 辅助 (status/log/diff/review/commit)
|
|
@@ -2344,7 +2344,7 @@ Please continue the conversation from where we left it off without asking the us
|
|
|
2344
2344
|
- 在命令前加上 \`/\` 即可执行 slash command
|
|
2345
2345
|
- 普通消息会发送给 AI 助手处理
|
|
2346
2346
|
- 按 Ctrl+C 退出程序
|
|
2347
|
-
- 按 Ctrl+L 快速清屏`,Y.sendMessage(Q),{success:!0,message:"帮助信息已显示"}}},
|
|
2347
|
+
- 按 Ctrl+L 快速清屏`,Y.sendMessage(Q),{success:!0,message:"帮助信息已显示"}}},Uw={name:"clear",description:"Clear conversation history and free up context",fullDescription:"清除屏幕内容和对话历史",usage:"/clear",aliases:["cls"],async handler($,Z){return{success:!0,message:"clear_screen"}}},Fw={name:"version",description:"Show Blade Code version information",fullDescription:"显示 Blade Code 版本信息和构建详情",usage:"/version",aliases:["v"],async handler($,Z){let Y=f0(Z),X=`\uD83D\uDDE1️ **Blade Code v${u4()}**
|
|
2348
2348
|
|
|
2349
2349
|
**构建信息:**
|
|
2350
2350
|
- Node.js: ${process.version}
|
|
@@ -2355,7 +2355,7 @@ Please continue the conversation from where we left it off without asking the us
|
|
|
2355
2355
|
- \uD83E\uDD16 智能 AI 对话
|
|
2356
2356
|
- \uD83D\uDD27 项目自动分析
|
|
2357
2357
|
- \uD83D\uDCDD 自定义系统提示
|
|
2358
|
-
- \uD83C\uDFAF 多工具集成支持`;return Y.sendMessage(X),{success:!0,message:"版本信息已显示"}}},
|
|
2358
|
+
- \uD83C\uDFAF 多工具集成支持`;return Y.sendMessage(X),{success:!0,message:"版本信息已显示"}}},Ow={name:"status",description:"Show current configuration status",fullDescription:"显示当前项目配置状态和环境信息",usage:"/status",async handler($,Z){let Y=f0(Z),{cwd:Q}=Z;try{let X=xG.join(Q,"BLADE.md"),J=await hG.access(X).then(()=>!0).catch(()=>!1),q=xG.join(Q,"package.json"),G="未知项目",K="未知类型";try{let U=await hG.readFile(q,"utf-8"),F=JSON.parse(U);G=F.name||"未知项目";let O={...F.dependencies,...F.devDependencies};if(O.react)K="React 项目";else if(O.vue)K="Vue 项目";else if(O.next)K="Next.js 项目";else if(O.express)K="Express 项目";else K="Node.js 项目"}catch{}let W=`\uD83D\uDCCA **当前状态**
|
|
2359
2359
|
|
|
2360
2360
|
**项目信息:**
|
|
2361
2361
|
- 名称: ${G}
|
|
@@ -2369,7 +2369,7 @@ Please continue the conversation from where we left it off without asking the us
|
|
|
2369
2369
|
- 工作目录: ${process.cwd()}
|
|
2370
2370
|
- Node.js: ${process.version}
|
|
2371
2371
|
|
|
2372
|
-
${!J?"\n\uD83D\uDCA1 **建议:** 运行 `/init` 命令来创建项目配置文件":""}`;return Y.sendMessage(W),{success:!0,message:"状态信息已显示"}}catch(X){return{success:!1,error:`获取状态信息失败: ${X instanceof Error?X.message:"未知错误"}`}}}},
|
|
2372
|
+
${!J?"\n\uD83D\uDCA1 **建议:** 运行 `/init` 命令来创建项目配置文件":""}`;return Y.sendMessage(W),{success:!0,message:"状态信息已显示"}}catch(X){return{success:!1,error:`获取状态信息失败: ${X instanceof Error?X.message:"未知错误"}`}}}},Hw={name:"exit",description:"Exit the REPL",fullDescription:"退出 Blade Code 命令行界面",usage:"/exit",aliases:["quit","q"],async handler($,Z){return{success:!0,message:"exit_application"}}},_w={name:"context",description:"Visualize current context usage as a colored grid",fullDescription:"可视化显示当前上下文使用情况",usage:"/context",async handler($,Z){let Y=f0(Z),Q=K$(),X=n4(),q=J0().session.messages||[],G=q.map((w)=>({role:w.role,content:w.content})),K=X?.model||"gpt-4",W=G.length>0?W2.countTokens(G,K):0,U=X?.maxContextTokens??Q?.maxContextTokens??128000,F=U>0?(W/U*100).toFixed(1):"0",O=(100-parseFloat(F)).toFixed(1),H=parseFloat(F),_;if(H<50)_="\uD83D\uDFE2 正常";else if(H<80)_="\uD83D\uDFE1 中等";else _="\uD83D\uDD34 高负载";let z=`\uD83D\uDCCA **上下文使用情况**
|
|
2373
2373
|
|
|
2374
2374
|
**当前会话:**
|
|
2375
2375
|
- 消息数量: ${q.length}
|
|
@@ -2383,7 +2383,7 @@ ${!J?"\n\uD83D\uDCA1 **建议:** 运行 `/init` 命令来创建项目配置文
|
|
|
2383
2383
|
|
|
2384
2384
|
**状态:** ${_}
|
|
2385
2385
|
|
|
2386
|
-
\uD83D\uDCA1 使用 \`/compact\` 可手动压缩上下文`;return Y.sendMessage(z),{success:!0,message:"上下文信息已显示"}}},pG={help:
|
|
2386
|
+
\uD83D\uDCA1 使用 \`/compact\` 可手动压缩上下文`;return Y.sendMessage(z),{success:!0,message:"上下文信息已显示"}}},pG={help:Ww,clear:Uw,version:Fw,status:Ow,exit:Hw,context:_w,permissions:o6,resume:kG,compact:IG,mcp:EG,agents:MG}});import{execFile as gG,spawn as zw}from"child_process";import{promisify as Bw}from"util";async function y8($,Z){return new Promise((Y)=>{gG("git",Z,{cwd:$,maxBuffer:10485760,encoding:"utf8"},(Q,X,J)=>{let q=Q==null?0:typeof Q.code==="number"?Q.code:1;Y({code:q,stdout:X||"",stderr:J||""})})})}async function ww($,Z){let{code:Y}=await y8($,Z);return Y===0}async function e1($,Z){let{stdout:Y}=await y8($,Z);return Y.trim()}async function v8($){return ww($,["rev-parse","--is-inside-work-tree"])}async function e6($){return(await e1($,["status","--porcelain"])).length>0}async function uG($){return e1($,["branch","--show-current"])}async function $7($,Z=10){return e1($,["log","-n",String(Z),"--pretty=format:%s"])}async function bZ($){let{code:Z,stderr:Y}=await y8($,["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 dG($,Z,Y=!1,Q){let X=["commit","-m",Z];if(Y)X.push("--no-verify");if(!Q){let{code:J,stderr:q}=await y8($,X);if(J!==0)throw Error(q||"Commit failed");return}return new Promise((J,q)=>{let G=zw("git",X,{cwd:$}),K="",W=(O,H,_)=>{let w=(_+O.toString()).split(`
|
|
2387
2387
|
`),B=w.pop()||"";for(let L of w)if(L.trim())Q(L,H);return B},U="",F="";G.stdout?.on("data",(O)=>{U=W(O,"stdout",U)}),G.stderr?.on("data",(O)=>{K+=O.toString(),F=W(O,"stderr",F)}),G.on("error",(O)=>{q(O)}),G.on("close",(O)=>{if(U.trim())Q(U,"stdout");if(F.trim())Q(F,"stderr");if(O===0)J();else q(Error(K||"Commit failed"))})})}async function cG($){let{cwd:Z}=$;if(!await v8(Z))return null;let[Y,Q,X,J,q]=await Promise.all([e1(Z,["branch","--show-current"]),e1(Z,["rev-parse","--abbrev-ref","origin/HEAD"]).then((K)=>K.replace("origin/","")).catch(()=>"main"),e1(Z,["status","--short"]),e1(Z,["log","--oneline","-n","5"]),e1(Z,["config","user.email"])]),G=q?await e1(Z,["log","--author",q,"--oneline","-n","5"]):"";return{branch:Y,mainBranch:Q,status:X,log:J,author:q,authorLog:G}}function lG($){if(!$)return null;return`
|
|
2388
2388
|
Git repository status (snapshot at conversation start):
|
|
2389
2389
|
Current branch: ${$.branch}
|
|
@@ -2399,12 +2399,12 @@ Your recent commits:
|
|
|
2399
2399
|
${$.authorLog||"(no recent commits)"}
|
|
2400
2400
|
`.trim()}async function T8($){return e1($,["diff","--cached","--name-status"])}async function E8($){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 y8($,Y);if(Q!==0){let G=J||"Unknown error";if(G.includes("bad revision"))throw Error("Failed to get staged diff: Invalid Git revision or corrupt repository");if(G.includes("fatal: not a git repository"))throw Error("Not a Git repository");throw Error(`Failed to get staged diff: ${G}`)}let q=102400;if(X.length>q)return X.substring(0,q)+`
|
|
2401
2401
|
|
|
2402
|
-
[Diff truncated due to size. Total diff size: `+(X.length/1024).toFixed(2)+"KB]";return X}var
|
|
2402
|
+
[Diff truncated due to size. Total diff size: `+(X.length/1024).toFixed(2)+"KB]";return X}var _f;var AZ=b(()=>{_f=Bw(gG)});async function iG($){let Z=f0($),Y=await cG({cwd:$.cwd});if(!Y)return{success:!1,error:"无法获取 Git 状态"};let Q=lG(Y);if(Q)Z.sendMessage(`\`\`\`
|
|
2403
2403
|
${Q}
|
|
2404
|
-
\`\`\``);else Z.sendMessage("\uD83D\uDCED 无法获取 Git 状态信息");return{success:!0}}async function
|
|
2404
|
+
\`\`\``);else Z.sendMessage("\uD83D\uDCED 无法获取 Git 状态信息");return{success:!0}}async function Nw($,Z){let Y=f0($),Q=Math.min(Math.max(parseInt(Z||"5",10)||5,1),50),X=await $7($.cwd,Q);if(!X)Y.sendMessage("\uD83D\uDCED 暂无提交记录");else Y.sendMessage(`**最近 ${Q} 条提交:**
|
|
2405
2405
|
\`\`\`
|
|
2406
2406
|
${X}
|
|
2407
|
-
\`\`\``);return{success:!0}}async function
|
|
2407
|
+
\`\`\``);return{success:!0}}async function bw($){let Z=f0($),{cwd:Y}=$,Q=await T8(Y);if(!Q)return Z.sendMessage("\uD83D\uDCED 暂存区为空,没有待提交的改动"),{success:!0};let X=await E8(Y),J=`**暂存文件:**
|
|
2408
2408
|
\`\`\`
|
|
2409
2409
|
${Q}
|
|
2410
2410
|
\`\`\`
|
|
@@ -2412,7 +2412,7 @@ ${Q}
|
|
|
2412
2412
|
**Diff:**
|
|
2413
2413
|
\`\`\`diff
|
|
2414
2414
|
${X||"(无差异)"}
|
|
2415
|
-
\`\`\``;return Z.sendMessage(J),{success:!0}}async function
|
|
2415
|
+
\`\`\``;return Z.sendMessage(J),{success:!0}}async function Aw($){let Z=f0($),{cwd:Y,signal:Q}=$;if(!await e6(Y))return Z.sendMessage("\uD83D\uDCED 没有未提交的改动,无需 Review"),{success:!0};Z.sendMessage("\uD83D\uDD0D 正在分析代码改动...");let X=await T8(Y),J=await E8(Y);if(!J&&!X)return Z.sendMessage("\uD83D\uDCA1 请先使用 `git add` 暂存要 Review 的文件"),{success:!0};let q=await U$.create();if(Q?.aborted)return{success:!1,message:"操作已取消"};let G=J0().session.sessionId,K=`请对以下 Git 改动进行 Code Review。
|
|
2416
2416
|
|
|
2417
2417
|
**暂存文件:**
|
|
2418
2418
|
${X||"(无)"}
|
|
@@ -2428,7 +2428,7 @@ ${J||"(无差异)"}
|
|
|
2428
2428
|
3. **潜在问题**:指出可能的 bug、安全问题或性能问题
|
|
2429
2429
|
4. **改进建议**:具体的代码改进建议
|
|
2430
2430
|
|
|
2431
|
-
如果改动很好,也请说明优点。保持简洁专业。`,W=await q.chat(K,{messages:[],userId:"cli-user",sessionId:G||"git-review",workspaceRoot:Y,signal:Q});return Z.sendMessage(W),{success:!0}}async function
|
|
2431
|
+
如果改动很好,也请说明优点。保持简洁专业。`,W=await q.chat(K,{messages:[],userId:"cli-user",sessionId:G||"git-review",workspaceRoot:Y,signal:Q});return Z.sendMessage(W),{success:!0}}async function Rw($){let Z=f0($),{cwd:Y,signal:Q}=$;if(!await e6(Y))return Z.sendMessage("\uD83D\uDCED 没有未提交的改动"),{success:!0};Z.sendMessage("\uD83D\uDCE6 暂存所有改动..."),await bZ(Y);let X=await T8(Y),J=await E8(Y);if(!X)return Z.sendMessage("\uD83D\uDCED 没有需要提交的改动"),{success:!0};Z.sendMessage("\uD83E\uDD16 正在生成 commit message...");let q=await $7(Y,5),G=await U$.create();if(Q?.aborted)return{success:!1,message:"操作已取消"};let K=J0().session.sessionId,W=aG(X,J,q),F=(await G.chat(W,{messages:[],userId:"cli-user",sessionId:K||"git-pre-commit",workspaceRoot:Y,signal:Q})).replace(/^```\w*\n?/,"").replace(/\n?```$/,"").trim();return Z.sendMessage(`**生成的 Commit Message:**
|
|
2432
2432
|
\`\`\`
|
|
2433
2433
|
${F}
|
|
2434
2434
|
\`\`\`
|
|
@@ -2437,7 +2437,7 @@ ${F}
|
|
|
2437
2437
|
\`\`\`bash
|
|
2438
2438
|
git commit -m "${F.split(`
|
|
2439
2439
|
`)[0]}"
|
|
2440
|
-
\`\`\``),{success:!0}}async function
|
|
2440
|
+
\`\`\``),{success:!0}}async function Vw($){let Z=f0($),{cwd:Y,signal:Q}=$;if(!await e6(Y))return Z.sendMessage("\uD83D\uDCED 没有未提交的改动"),{success:!0};Z.sendMessage("\uD83D\uDCE6 暂存所有改动..."),await bZ(Y);let X=await T8(Y),J=await E8(Y);if(!X)return Z.sendMessage("\uD83D\uDCED 没有需要提交的改动"),{success:!0};Z.sendMessage("\uD83E\uDD16 正在生成 commit message...");let q=await $7(Y,5),G=await U$.create();if(Q?.aborted)return{success:!1,message:"操作已取消"};let K=J0().session.sessionId,W=aG(X,J,q),F=(await G.chat(W,{messages:[],userId:"cli-user",sessionId:K||"git-commit",workspaceRoot:Y,signal:Q})).replace(/^```\w*\n?/,"").replace(/\n?```$/,"").trim();Z.sendMessage(`**生成的 Commit Message:**
|
|
2441
2441
|
\`\`\`
|
|
2442
2442
|
${F}
|
|
2443
2443
|
\`\`\``);try{await dG(Y,F),Z.sendMessage("✅ 提交成功!")}catch(O){let H=O instanceof Error?O.message:"未知错误";return Z.sendMessage(`❌ 提交失败: ${H}`),{success:!1,error:H}}return{success:!0}}function aG($,Z,Y){let Q=Y&&Y.trim().length>0;return`请根据以下 Git 改动生成一条 commit message。
|
|
@@ -2461,9 +2461,9 @@ ${Y}
|
|
|
2461
2461
|
1. ${Q?"严格模仿历史提交的语言和格式风格":"使用英文,遵循 Conventional Commits 格式(feat:, fix:, docs:, refactor:, chore: 等)"}
|
|
2462
2462
|
2. 第一行简明扼要,不超过 72 字符
|
|
2463
2463
|
3. 如有必要,可添加空行后的详细说明
|
|
2464
|
-
4. 只输出 commit message 内容,不要其他解释或代码块标记`}var
|
|
2465
|
-
`)),{success:!0,message:"Hooks status displayed"}}function
|
|
2466
|
-
`)),{success:!0,message:"Hooks config listed"}}var
|
|
2464
|
+
4. 只输出 commit message 内容,不要其他解释或代码块标记`}var Lw,rG;var nG=b(()=>{O2();T0();AZ();p1();Lw={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 v8(Y))return{success:!1,error:"❌ 当前目录不在 Git 仓库中"};try{switch(Q){case"status":case"s":return iG(Z);case"log":case"l":return Nw(Z,$[1]);case"diff":case"d":return bw(Z);case"review":case"r":return Aw(Z);case"commit":case"c":return Vw(Z);case"pre-commit":case"pc":return Rw(Z);default:return iG(Z)}}catch(X){return{success:!1,error:`Git 命令失败: ${X instanceof Error?X.message:"未知错误"}`}}}};rG=Lw});function Mw($){let Z=$.isEnabled(),Y=$.getConfig(),Q={};for(let J of Object.values(i1)){let q=Y[J];if(q&&Array.isArray(q)){let G=q.reduce((K,W)=>K+(W.hooks?.length||0),0);if(G>0)Q[J]=G}}let X=["## Hooks 状态","",`**状态**: ${Z?"✅ 启用":"⏸️ 禁用"}`,""];if(Object.keys(Q).length>0){X.push("**已配置的 Hooks**:"),X.push("");for(let[J,q]of Object.entries(Q))X.push(`- ${J}: ${q} 个 hook`)}else X.push("*没有配置任何 hooks*");return X.push(""),X.push("---"),X.push("使用 `/hooks list` 查看详细配置"),X.push("使用 `/hooks enable` 或 `/hooks disable` 切换状态"),H0().addAssistantMessage(X.join(`
|
|
2465
|
+
`)),{success:!0,message:"Hooks status displayed"}}function jw($){let Z=$.getConfig(),Y=["## Hooks 配置详情",""],Q=!1;for(let X of Object.values(i1)){let J=Z[X];if(!J||!Array.isArray(J)||J.length===0)continue;Q=!0,Y.push(`### ${X}`),Y.push("");for(let q=0;q<J.length;q++){let G=J[q],K=G.name||`Matcher ${q+1}`,W=G.matcher,U="所有";if(W){let F=[];if(W.tools){let O=Array.isArray(W.tools)?W.tools.join(", "):W.tools;F.push(`工具: ${O}`)}if(W.paths){let O=Array.isArray(W.paths)?W.paths.join(", "):W.paths;F.push(`路径: ${O}`)}if(W.commands){let O=Array.isArray(W.commands)?W.commands.join(", "):W.commands;F.push(`命令: ${O}`)}if(F.length>0)U=F.join("; ")}Y.push(`**${K}** (匹配: ${U})`);for(let F of G.hooks||[])if(F.type==="command")Y.push(` - \`${F.command}\``);else if(F.type==="prompt"){let O=F.prompt.slice(0,50)+(F.prompt.length>50?"...":"");Y.push(` - [prompt] ${O}`)}Y.push("")}}if(!Q)Y.push("*没有配置任何 hooks*"),Y.push(""),Y.push("在 `.blade/settings.local.json` 或 `~/.blade/settings.json` 中配置 hooks。");return H0().addAssistantMessage(Y.join(`
|
|
2466
|
+
`)),{success:!0,message:"Hooks config listed"}}var Dw,oG;var sG=b(()=>{t$();t4();T0();Dw={name:"hooks",description:"Manage hook configurations for tool events",fullDescription:`管理 Hook 配置,查看当前启用的 hooks 和执行统计。
|
|
2467
2467
|
|
|
2468
2468
|
子命令:
|
|
2469
2469
|
/hooks - 打开交互式 hooks 管理界面(添加新 hook)
|
|
@@ -2471,14 +2471,14 @@ ${Y}
|
|
|
2471
2471
|
/hooks status - 显示 hooks 启用状态和统计
|
|
2472
2472
|
/hooks enable - 启用当前会话的 hooks
|
|
2473
2473
|
/hooks disable - 禁用当前会话的 hooks
|
|
2474
|
-
/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=R0.getInstance();switch(Y){case"":case"add":return{success:!0,message:"show_hooks_manager",data:{action:"show_hooks_manager"}};case"status":return
|
|
2475
|
-
使用 /hooks 查看帮助`),{success:!1,error:`Unknown subcommand: ${Y}`}}}};oG=
|
|
2474
|
+
/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=R0.getInstance();switch(Y){case"":case"add":return{success:!0,message:"show_hooks_manager",data:{action:"show_hooks_manager"}};case"status":return Mw(Q);case"enable":return Q.enable(),H0().addAssistantMessage("✅ Hooks 已启用(当前会话)"),{success:!0,message:"Hooks enabled"};case"disable":return Q.disable(),H0().addAssistantMessage("⏸️ Hooks 已禁用(当前会话)"),{success:!0,message:"Hooks disabled"};case"list":return jw(Q);default:return H0().addAssistantMessage(`❌ 未知子命令: ${Y}
|
|
2475
|
+
使用 /hooks 查看帮助`),{success:!1,error:`Unknown subcommand: ${Y}`}}}};oG=Dw});import{exec as Iw}from"child_process";import{promisify as yw}from"util";class RZ{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 tG("code --version"),Y=$.trim().split(`
|
|
2476
2476
|
`)[0]||"unknown",Q=[];try{let{stdout:X}=await tG("code --list-extensions");Q=X.trim().split(`
|
|
2477
|
-
`).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 tG;var eG=b(()=>{tG=Iw
|
|
2477
|
+
`).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 tG;var eG=b(()=>{tG=yw(Iw)});import{exec as vw}from"child_process";import{promisify as Tw}from"util";class P8{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 Z7(Z),{success:!0,message:"扩展安装成功"}}catch(Y){return{success:!1,message:"安装失败: "+(Y instanceof Error?Y.message:"未知错误")}}}static async checkVsCode(){try{let{stdout:$}=await Z7("code --version");return{id:"vscode",name:"VS Code",version:$.trim().split(`
|
|
2478
2478
|
`)[0]||"unknown"}}catch{return null}}static async checkVsCodeInsiders(){try{let{stdout:$}=await Z7("code-insiders --version");return{id:"vscode-insiders",name:"VS Code Insiders",version:$.trim().split(`
|
|
2479
2479
|
`)[0]||"unknown"}}catch{return null}}static async checkCursor(){try{let{stdout:$}=await Z7("cursor --version");return{id:"cursor",name:"Cursor",version:$.trim().split(`
|
|
2480
|
-
`)[0]||"unknown"}}catch{return null}}}var Z7;var $K=b(()=>{Z7=vw
|
|
2481
|
-
`)}async function
|
|
2480
|
+
`)[0]||"unknown"}}catch{return null}}}var Z7;var $K=b(()=>{Z7=Tw(vw)});import{existsSync as Ew,readFileSync as Pw}from"fs";import{homedir as Cw}from"os";import{join as Sw}from"path";function kw(){switch(A3){case"connected":return{type:"info",content:`\uD83D\uDFE2 已连接到 ${VZ||"IDE"} (端口: ${DZ})`};case"connecting":return{type:"info",content:"\uD83D\uDFE1 正在连接..."};default:return{type:"error",content:"\uD83D\uDD34 未连接到 IDE"}}}function YK(){try{if(Ew(ZK)){let $=Pw(ZK,"utf-8");return JSON.parse($)}}catch{}return null}function QK(){let $=process.env.BLADE_IDE_PORT;if($)return parseInt($,10);let Z=YK();if(Z)return Z.port;return null}async function fw(){let $=[],Z=kw();$.push(Z.content),$.push(""),$.push("\uD83D\uDCE6 已安装的 IDE:");let Y=await P8.getInstalledIdes();if(Y.length===0)$.push(" (未检测到支持的 IDE)");else for(let q of Y)$.push(` • ${q.name} ${q.version}`);$.push("");let Q=await RZ.detectIde();if(Q){if($.push(`\uD83D\uDDA5️ 当前环境: ${Q.name} ${Q.version}`),Q.extensions.length>0)$.push(` 已安装扩展: ${Q.extensions.length} 个`)}let X=QK(),J=YK();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(`
|
|
2481
|
+
`)}async function hw(){let $=QK();if(!$)return`❌ 未检测到 IDE 端口
|
|
2482
2482
|
|
|
2483
2483
|
请确保:
|
|
2484
2484
|
1. 已在 VS Code 中安装 Blade Code 插件
|
|
@@ -2496,15 +2496,15 @@ ${Y}
|
|
|
2496
2496
|
请检查:
|
|
2497
2497
|
1. VS Code 插件是否正在运行
|
|
2498
2498
|
2. 端口 ${$} 是否正确
|
|
2499
|
-
3. 防火墙设置`}}async function
|
|
2499
|
+
3. 防火墙设置`}}async function xw(){let $=[];if($.push("\uD83D\uDCE6 安装 Blade Code VS Code 插件"),$.push(""),!await P8.isIdeInstalled("vscode"))return $.push("❌ 未检测到 VS Code"),$.push(""),$.push("请先安装 VS Code:"),$.push(" https://code.visualstudio.com/"),$.join(`
|
|
2500
2500
|
`);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(`
|
|
2501
|
-
`)}async function
|
|
2501
|
+
`)}async function pw(){if(A3==="disconnected")return"⚠️ 当前未连接到任何 IDE";return A3="disconnected",VZ=null,DZ=null,"✅ 已断开与 IDE 的连接"}var ZK,A3="disconnected",VZ=null,DZ=null,mw,XK;var JK=b(()=>{eG();$K();ZK=Sw(Cw(),".blade","ide-port");mw={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 fw();break;case"connect":Q=await hw();break;case"install":Q=await xw();break;case"disconnect":Q=await pw();break;default:Q=`未知的子命令: ${Y}
|
|
2502
2502
|
|
|
2503
2503
|
可用命令:
|
|
2504
2504
|
/ide status - 显示连接状态
|
|
2505
2505
|
/ide connect - 连接到 IDE
|
|
2506
2506
|
/ide install - 安装 VS Code 插件
|
|
2507
|
-
/ide disconnect - 断开连接`}return{success:!0,message:Q}}},XK=
|
|
2507
|
+
/ide disconnect - 断开连接`}return{success:!0,message:Q}}},XK=mw});import{basename as u2}from"node:path";function C8($,Z){switch($){case"Write":{let Y=Z.file_path;return`\uD83D\uDCDD Writing ${Y?u2(Y):"file"}`}case"Edit":{let Y=Z.file_path;return`✏️ Editing ${Y?u2(Y):"file"}`}case"Read":{let Y=Z.file_path;return`\uD83D\uDCD6 Reading ${Y?u2(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=u2(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?u2(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?u2(Q):"file";return`\uD83D\uDD17 LSP ${Y} in ${X}`}case"NotebookEdit":{let Y=Z.notebook_path;return`\uD83D\uDCD3 Editing notebook: ${Y?u2(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 qK($,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 GK($,Z){if(!Z?.success)return null;switch($){case"Glob":{if(!NQ(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(`
|
|
2508
2508
|
`)}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 q=u2(J.file_path);if(J.line_number)return`${q}:${J.line_number}`;return q});if(Y.length>Q)X.push(`... (+${Y.length-Q} more)`);return X.join(`
|
|
2509
2509
|
`)}case"Read":{let Y=Z.metadata?.content_preview||Z.llmContent;if(typeof Y!=="string"||!Y)return null;let Q=Y.split(`
|
|
2510
2510
|
`),X=Q.length,J=3;if(X<=J+1)return Y;return`${Q.slice(0,J).join(`
|
|
@@ -2518,7 +2518,7 @@ ${Y}
|
|
|
2518
2518
|
... (+${Q.length-X} line(s))`}case"Edit":{if(!bQ(Z.metadata))return null;let{diff_snippet:Y}=Z.metadata;if(Y){let Q=Y.split(`
|
|
2519
2519
|
`),X=6;if(Q.length>6)return Q.slice(0,6).join(`
|
|
2520
2520
|
`)+`
|
|
2521
|
-
... (+${Q.length-6} line(s))`;return Y}return null}default:{let Y=Z.metadata?.detail;return typeof Y==="string"?Y:null}}}var MZ=b(()=>{V$()});import{promises as S8}from"fs";import*as KK from"path";var R3,
|
|
2521
|
+
... (+${Q.length-6} line(s))`;return Y}return null}default:{let Y=Z.metadata?.detail;return typeof Y==="string"?Y:null}}}var MZ=b(()=>{V$()});import{promises as S8}from"fs";import*as KK from"path";var R3,gw,WK;var UK=b(()=>{O2();z0();T0();MZ();p1();R3=l("Agent"),gw={name:"init",description:"分析当前项目并生成 BLADE.md 配置文件",usage:"/init",async handler($,Z){try{let{cwd:Y,signal:Q}=Z,X=f0(Z),J=(H)=>{X.sendMessage(`${H}`)},q=J0().session.sessionId,G=KK.join(Y,"BLADE.md"),K=!1,W=!1;try{if(K=(await S8.stat(G)).isFile(),K)W=(await S8.readFile(G,"utf-8")).trim().length===0}catch{K=!1}if(K&&!W){X.sendMessage("⚠️ BLADE.md 已存在。"),X.sendMessage("\uD83D\uDCA1 正在分析现有文件并提供改进建议...");let H=await U$.create();if(Q?.aborted)return{success:!1,message:"操作已取消"};let _=`Please analyze the existing BLADE.md file and provide improvement suggestions.
|
|
2522
2522
|
|
|
2523
2523
|
**Important**:
|
|
2524
2524
|
- After each step, briefly describe what you found before proceeding
|
|
@@ -2605,7 +2605,7 @@ ${Y}
|
|
|
2605
2605
|
- Focus on non-obvious insights
|
|
2606
2606
|
- Be concise but comprehensive for complex projects
|
|
2607
2607
|
|
|
2608
|
-
**Final output**: Return ONLY the complete BLADE.md content (markdown format), ready to be written to the file.`;R3.info(`[/init] Starting agent.chat for new BLADE.md, signal.aborted: ${Q?.aborted}`);let O=await U.chat(F,{messages:[],userId:"cli-user",sessionId:q||"init-session",workspaceRoot:Y,signal:Q},{onToolStart:(H)=>{if(H.type!=="function")return;try{let _=JSON.parse(H.function.arguments),z=C8(H.function.name,_);J(z)}catch{}},onToolResult:async(H,_)=>{if(H.type!=="function")return;if(_?.metadata?.summary){if(typeof _.metadata.summary==="string")J(_.metadata.summary)}}});if(R3.info(`[/init] agent.chat completed for new BLADE.md, signal.aborted: ${Q?.aborted}`),Q?.aborted)return R3.info("[/init] Returning cancelled after agent.chat (new BLADE.md)"),{success:!1,message:"操作已取消"};if(!O||O.trim().length===0)throw Error("Agent 未能生成有效的 BLADE.md 内容");return X.sendMessage("✨ 正在写入 BLADE.md..."),await S8.writeFile(G,O,"utf-8"),{success:!0,message:"✅ 已成功生成 BLADE.md 文件"}}catch(Y){return{success:!1,error:`初始化失败: ${Y instanceof Error?Y.message:"未知错误"}`}}}},WK=
|
|
2608
|
+
**Final output**: Return ONLY the complete BLADE.md content (markdown format), ready to be written to the file.`;R3.info(`[/init] Starting agent.chat for new BLADE.md, signal.aborted: ${Q?.aborted}`);let O=await U.chat(F,{messages:[],userId:"cli-user",sessionId:q||"init-session",workspaceRoot:Y,signal:Q},{onToolStart:(H)=>{if(H.type!=="function")return;try{let _=JSON.parse(H.function.arguments),z=C8(H.function.name,_);J(z)}catch{}},onToolResult:async(H,_)=>{if(H.type!=="function")return;if(_?.metadata?.summary){if(typeof _.metadata.summary==="string")J(_.metadata.summary)}}});if(R3.info(`[/init] agent.chat completed for new BLADE.md, signal.aborted: ${Q?.aborted}`),Q?.aborted)return R3.info("[/init] Returning cancelled after agent.chat (new BLADE.md)"),{success:!1,message:"操作已取消"};if(!O||O.trim().length===0)throw Error("Agent 未能生成有效的 BLADE.md 内容");return X.sendMessage("✨ 正在写入 BLADE.md..."),await S8.writeFile(G,O,"utf-8"),{success:!0,message:"✅ 已成功生成 BLADE.md 文件"}}catch(Y){return{success:!1,error:`初始化失败: ${Y instanceof Error?Y.message:"未知错误"}`}}}},WK=gw});function uw($){if($.includes("copilot")||$.includes("github"))return"copilot";if($.includes("gemini")||$.includes("gemini-cli"))return"gemini-cli";return"antigravity"}var FK;var OK=b(()=>{J8();Y8();F8();K8();p1();FK={name:"login",description:"登录 OAuth 服务(Antigravity / Copilot)",fullDescription:`登录 OAuth 服务以使用 AI 模型。
|
|
2609
2609
|
|
|
2610
2610
|
**支持的服务:**
|
|
2611
2611
|
|
|
@@ -2624,14 +2624,14 @@ ${Y}
|
|
|
2624
2624
|
- \`/login gemini\` - 使用 Gemini CLI OAuth(Antigravity 备选)
|
|
2625
2625
|
- \`/login copilot\` - 登录 GitHub Copilot
|
|
2626
2626
|
|
|
2627
|
-
登录后,使用 \`/model add\` 添加模型配置。`,usage:"/login [copilot|gemini]",category:"auth",examples:["/login","/login copilot","/login gemini"],async handler($,Z){let Y=f0(Z),Q=
|
|
2627
|
+
登录后,使用 \`/model add\` 添加模型配置。`,usage:"/login [copilot|gemini]",category:"auth",examples:["/login","/login copilot","/login gemini"],async handler($,Z){let Y=f0(Z),Q=uw($);if(Q==="copilot"){let G=d$.getInstance();try{if(await G.isLoggedIn()){let W=await G.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 G.login(),Y.sendMessage(""),Y.sendMessage("**可用模型:**");for(let W of Object.values(G6))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(K){let W=K instanceof Error?K.message:String(K);return Y.sendMessage(`❌ 登录失败: ${W}`),{success:!1,error:W}}}let X=C$.getInstance(),J=Q==="gemini-cli"?"gemini-cli":"antigravity",q=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,F=W.configType==="gemini-cli"?"Gemini CLI":"Antigravity";return Y.sendMessage(`✅ 已登录(${F} OAuth)`),Y.sendMessage(`Token 有效期还剩约 ${U} 分钟`),Y.sendMessage(""),Y.sendMessage("如需重新登录或切换 OAuth 方式,请先执行 /logout"),{success:!0,message:"已登录",content:`已登录(${F} OAuth),Token 有效期还剩约 ${U} 分钟`}}Y.sendMessage(`\uD83D\uDD10 开始 ${q} OAuth 登录...`),Y.sendMessage(""),await X.login(J),Y.sendMessage(""),Y.sendMessage(`✅ ${q} 登录成功!`),Y.sendMessage(""),Y.sendMessage("**可用模型:**");let K=Q==="gemini-cli"?Q6:Z8;for(let W of Object.values(K)){let U=W.supportsThinking?" (Thinking)":"";Y.sendMessage(` - ${W.id}${U}`)}return Y.sendMessage(""),Y.sendMessage("**下一步:**"),Y.sendMessage(`使用 \`/model add\` 添加 ${q} 模型配置`),{success:!0,message:"登录成功",content:`已成功通过 ${q} OAuth 登录。使用 /model add 添加模型配置。`}}catch(G){let K=G instanceof Error?G.message:String(G);return Y.sendMessage(`❌ 登录失败: ${K}`),{success:!1,error:K}}}}});function dw($){if($.includes("copilot")||$.includes("github"))return"copilot";if($.includes("all"))return"all";return"antigravity"}var HK;var _K=b(()=>{J8();F8();p1();HK={name:"logout",description:"登出 OAuth 服务并清除 token",fullDescription:`登出 OAuth 服务,清除本地存储的 token。
|
|
2628
2628
|
|
|
2629
2629
|
**用法:**
|
|
2630
2630
|
- \`/logout\` - 登出 Antigravity(默认)
|
|
2631
2631
|
- \`/logout copilot\` - 登出 GitHub Copilot
|
|
2632
2632
|
- \`/logout all\` - 登出所有服务
|
|
2633
2633
|
|
|
2634
|
-
登出后,使用对应服务的模型将需要重新登录。`,usage:"/logout [copilot|all]",category:"auth",examples:["/logout","/logout copilot","/logout all"],async handler($,Z){let Y=f0(Z),Q=
|
|
2634
|
+
登出后,使用对应服务的模型将需要重新登录。`,usage:"/logout [copilot|all]",category:"auth",examples:["/logout","/logout copilot","/logout all"],async handler($,Z){let Y=f0(Z),Q=dw($);if(Q==="all"){let J=[];try{let q=C$.getInstance();if(await q.isLoggedIn())await q.logout(),J.push("Antigravity")}catch{}try{let q=d$.getInstance();if(await q.isLoggedIn())await q.logout(),J.push("GitHub Copilot")}catch{}if(J.length>0)Y.sendMessage(`✅ 已登出: ${J.join(", ")}`);else Y.sendMessage("ℹ️ 当前未登录任何服务");return{success:!0,message:"登出完成",content:J.length>0?`已登出: ${J.join(", ")}`:"当前未登录任何服务"}}if(Q==="copilot"){let J=d$.getInstance();try{if(!await J.isLoggedIn())return Y.sendMessage("ℹ️ 当前未登录 GitHub Copilot"),{success:!0,message:"未登录",content:"当前未登录 GitHub Copilot"};return await J.logout(),Y.sendMessage("✅ 已登出 GitHub Copilot"),Y.sendMessage(""),Y.sendMessage("Token 已清除。如需重新使用,请执行 /login copilot"),{success:!0,message:"登出成功",content:"已登出 GitHub Copilot,Token 已清除。"}}catch(q){let G=q instanceof Error?q.message:String(q);return Y.sendMessage(`❌ 登出失败: ${G}`),{success:!1,error:G}}}let X=C$.getInstance();try{if(!await X.isLoggedIn())return Y.sendMessage("ℹ️ 当前未登录 Antigravity"),{success:!0,message:"未登录",content:"当前未登录 Antigravity"};return await X.logout(),Y.sendMessage("✅ 已登出 Antigravity"),Y.sendMessage(""),Y.sendMessage("Token 已清除。如需重新使用 Antigravity,请执行 /login"),{success:!0,message:"登出成功",content:"已登出 Antigravity,Token 已清除。"}}catch(J){let q=J instanceof Error?J.message:String(J);return Y.sendMessage(`❌ 登出失败: ${q}`),{success:!1,error:q}}}}});var cw,zK;var BK=b(()=>{T0();cw={name:"model",description:"管理和切换模型配置",usage:"/model [子命令] [参数]",fullDescription:`
|
|
2635
2635
|
管理和切换模型配置
|
|
2636
2636
|
|
|
2637
2637
|
子命令:
|
|
@@ -2647,18 +2647,18 @@ ${Y}
|
|
|
2647
2647
|
|
|
2648
2648
|
使用 /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:`❌ 请指定要删除的模型名称
|
|
2649
2649
|
用法: /model remove <名称>`};let J=i3().find((q)=>q.name.toLowerCase().includes(Q.toLowerCase()));if(!J)return{success:!1,message:`❌ 未找到匹配的模型配置: ${Q}`};try{return await C0().removeModel(J.id),{success:!0,message:`✅ 已删除模型配置: ${J.name}`}}catch(q){return{success:!1,message:`❌ ${q.message}`}}}default:return{success:!1,message:`❌ 未知的子命令: ${Y}
|
|
2650
|
-
使用 /model 查看可用操作`}}}},zK=
|
|
2650
|
+
使用 /model 查看可用操作`}}}},zK=cw});function iw($){if($.getAll().length===0)return H0().addAssistantMessage(`没有已加载的插件。
|
|
2651
2651
|
|
|
2652
2652
|
`+"使用 `--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 H0().addAssistantMessage(Y.join(`
|
|
2653
|
-
`)),{success:!0,message:"Plugins listed"}}function
|
|
2654
|
-
`)),{success:!0,message:"Plugin info displayed"}}function
|
|
2655
|
-
`)),{success:!0,message:"Plugins refreshed"}}catch(Z){let Y=Z instanceof Error?Z.message:String(Z);return H0().addAssistantMessage(`❌ 刷新失败: ${Y}`),{success:!1,error:Y}}}function
|
|
2656
|
-
`)),{success:!0,message:"Stats displayed"}}function
|
|
2653
|
+
`)),{success:!0,message:"Plugins listed"}}function aw($,Z){if(!Z)return H0().addAssistantMessage("请指定插件名称: `/plugins info <name>`"),{success:!1,error:"Plugin name required"};let Y=$.get(Z);if(!Y)return H0().addAssistantMessage(`未找到插件: ${Z}`),{success:!1,error:`Plugin not found: ${Z}`};let Q=[`## ${Y.manifest.name}`,"",`**版本**: ${Y.manifest.version}`,`**描述**: ${Y.manifest.description}`,`**状态**: ${Y.status==="active"?"✅ 启用":"⏸️ 禁用"}`,`**来源**: ${ew(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}`:"",q=X.config.description?` - ${X.config.description}`:"";Q.push(`- \`/${X.namespacedName}${J}\`${q}`)}}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 H0().addAssistantMessage(Q.join(`
|
|
2654
|
+
`)),{success:!0,message:"Plugin info displayed"}}function rw($,Z){if(!Z)return H0().addAssistantMessage("请指定插件名称: `/plugins enable <name>`"),{success:!1,error:"Plugin name required"};if($.enable(Z))return H0().addAssistantMessage(`✅ 已启用插件: ${Z}`),{success:!0,message:`Plugin ${Z} enabled`};if(!$.get(Z))return H0().addAssistantMessage(`未找到插件: ${Z}`),{success:!1,error:`Plugin not found: ${Z}`};return H0().addAssistantMessage(`插件 ${Z} 已经是启用状态`),{success:!0,message:`Plugin ${Z} already enabled`}}function nw($,Z){if(!Z)return H0().addAssistantMessage("请指定插件名称: `/plugins disable <name>`"),{success:!1,error:"Plugin name required"};if($.disable(Z))return H0().addAssistantMessage(`⏸️ 已禁用插件: ${Z}`),{success:!0,message:`Plugin ${Z} disabled`};if(!$.get(Z))return H0().addAssistantMessage(`未找到插件: ${Z}`),{success:!1,error:`Plugin not found: ${Z}`};return H0().addAssistantMessage(`插件 ${Z} 已经是禁用状态`),{success:!0,message:`Plugin ${Z} already disabled`}}async function ow($){n6(),await $.refresh(),await g2()}async function sw($){try{n6();let Z=await $.refresh(),Y=await g2(),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 H0().addAssistantMessage(Q.join(`
|
|
2655
|
+
`)),{success:!0,message:"Plugins refreshed"}}catch(Z){let Y=Z instanceof Error?Z.message:String(Z);return H0().addAssistantMessage(`❌ 刷新失败: ${Y}`),{success:!1,error:Y}}}function tw($){let Z=$.getStats(),Y=["## 插件统计","","| 指标 | 数量 |","|------|------|",`| 总插件数 | ${Z.total} |`,`| 启用 | ${Z.active} |`,`| 禁用 | ${Z.inactive} |`,`| 命令 | ${Z.commands} |`,`| 技能 | ${Z.skills} |`,`| 代理 | ${Z.agents} |`];return H0().addAssistantMessage(Y.join(`
|
|
2656
|
+
`)),{success:!0,message:"Stats displayed"}}function ew($){switch($){case"cli":return"CLI 参数";case"project":return"项目级";case"user":return"用户级";default:return $}}async function $L($){if(!$)return H0().addAssistantMessage("请指定插件 URL: `/plugins install <url>`\n\n"+`支持的格式:
|
|
2657
2657
|
`+"- GitHub 简写: `user/repo`\n"+"- 完整 URL: `https://github.com/user/repo`"),{success:!1,error:"Plugin URL required"};H0().addAssistantMessage(`正在安装插件: ${$}...`);let Y=await I8().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` 加载新安装的插件。"),H0().addAssistantMessage(Q.join(`
|
|
2658
|
-
`)),{success:!0,message:`Installed ${Y.pluginName}`}}return H0().addAssistantMessage(`❌ 安装失败: ${Y.error}`),{success:!1,error:Y.error}}async function
|
|
2658
|
+
`)),{success:!0,message:`Installed ${Y.pluginName}`}}return H0().addAssistantMessage(`❌ 安装失败: ${Y.error}`),{success:!1,error:Y.error}}async function ZL($){if(!$)return H0().addAssistantMessage("请指定插件名称: `/plugins uninstall <name>`"),{success:!1,error:"Plugin name required"};let Y=await I8().uninstall($);if(Y.success)return H0().addAssistantMessage(`✅ 已卸载插件: ${Y.pluginName}
|
|
2659
2659
|
|
|
2660
|
-
`+"使用 `/plugins refresh` 刷新插件列表。"),{success:!0,message:`Uninstalled ${Y.pluginName}`};return H0().addAssistantMessage(`❌ 卸载失败: ${Y.error}`),{success:!1,error:Y.error}}async function
|
|
2661
|
-
`)),{success:!0,message:`Updated ${Y.pluginName}`}}return H0().addAssistantMessage(`❌ 更新失败: ${Y.error}`),{success:!1,error:Y.error}}var
|
|
2660
|
+
`+"使用 `/plugins refresh` 刷新插件列表。"),{success:!0,message:`Uninstalled ${Y.pluginName}`};return H0().addAssistantMessage(`❌ 卸载失败: ${Y.error}`),{success:!1,error:Y.error}}async function YL($){if(!$)return H0().addAssistantMessage("请指定插件名称: `/plugins update <name>`"),{success:!1,error:"Plugin name required"};H0().addAssistantMessage(`正在更新插件: ${$}...`);let Y=await I8().update($);if(Y.success){let Q=["✅ 插件更新成功!","",`**名称**: ${Y.pluginName}`];if(Y.manifest)Q.push(`**版本**: ${Y.manifest.version}`);return Q.push(""),Q.push("使用 `/plugins refresh` 重新加载插件。"),H0().addAssistantMessage(Q.join(`
|
|
2661
|
+
`)),{success:!0,message:`Updated ${Y.pluginName}`}}return H0().addAssistantMessage(`❌ 更新失败: ${Y.error}`),{success:!1,error:Y.error}}var lw,wK;var LK=b(()=>{b3();T0();lw={name:"plugins",description:"管理已安装的插件",fullDescription:`管理 Blade Code 插件系统。
|
|
2662
2662
|
|
|
2663
2663
|
子命令:
|
|
2664
2664
|
/plugins - 打开插件管理界面
|
|
@@ -2670,14 +2670,14 @@ ${Y}
|
|
|
2670
2670
|
/plugins enable <name> - 启用插件
|
|
2671
2671
|
/plugins disable <name> - 禁用插件
|
|
2672
2672
|
/plugins refresh - 刷新插件列表
|
|
2673
|
-
/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=a$();switch(Y){case"":return await
|
|
2674
|
-
使用 /plugins 查看帮助`),{success:!1,error:`Unknown subcommand: ${Y}`}}}};wK=
|
|
2673
|
+
/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=a$();switch(Y){case"":return await ow(Q),{success:!0,message:"show_plugins_manager",data:{action:"show_plugins_manager"}};case"list":case"ls":return iw(Q);case"info":return aw(Q,$[1]);case"install":case"add":return $L($[1]);case"uninstall":case"remove":case"rm":return ZL($[1]);case"update":case"upgrade":return YL($[1]);case"enable":return rw(Q,$[1]);case"disable":return nw(Q,$[1]);case"refresh":return sw(Q);case"stats":return tw(Q);default:return H0().addAssistantMessage(`未知子命令: ${Y}
|
|
2674
|
+
使用 /plugins 查看帮助`),{success:!1,error:`Unknown subcommand: ${Y}`}}}};wK=lw});var QL,NK;var bK=b(()=>{U2();T0();QL={name:"skills",description:"查看所有可用的 Skills",fullDescription:"显示所有已发现的 Skills 及其详细信息,包括名称、描述、来源和允许的工具。",usage:"/skills",category:"system",examples:["/skills"],handler:async($,Z)=>{try{return await N$().refresh(),{success:!0,message:"show_skills_manager",data:{action:"show_skills_manager"}}}catch(Y){let Q=`获取 Skills 失败: ${Y instanceof Error?Y.message:"未知错误"}`;return H0().addAssistantMessage(Q),{success:!1,error:Q}}}},NK=QL});function Y7($){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 AK($){switch($){case"running":return"⏳";case"completed":case"exited":return"✅";case"failed":case"error":return"❌";case"killed":case"cancelled":return"✂️";default:return"❓"}}function RK($,Z){if($.length<=Z)return $;return $.slice(0,Z-3)+"..."}async function XL($,Z){let Y=f0(Z),Q=$[0],X=y$.getInstance(),J=Q1.getInstance();if(Q==="clean"){let O=J.cleanupExpiredSessions(0);return Y.sendMessage(`\uD83E\uDDF9 已清理 ${O} 个已完成的 Agent 会话`),{success:!0,message:`Cleaned ${O} agent sessions`}}let q=[`\uD83D\uDCCB **后台任务列表**
|
|
2675
2675
|
`],G=X.processes,K=Array.from(G?.values()||[]);if(K.length>0){q.push(`### \uD83D\uDC1A Shells
|
|
2676
2676
|
`),q.push("| ID | 状态 | 命令 | PID | 运行时间 |"),q.push("|:---|:-----|:-----|:----|:---------|");for(let O of K){let H=O.endTime?Y7(O.endTime-O.startTime):Y7(Date.now()-O.startTime),_=AK(O.status);q.push(`| \`${O.id.slice(0,12)}...\` | ${_} ${O.status} | \`${RK(O.command,30)}\` | ${O.pid||"-"} | ${H} |`)}q.push("")}let W=J.listAll();if(W.length>0){q.push(`### \uD83E\uDD16 Agents
|
|
2677
2677
|
`),q.push("| ID | 状态 | 类型 | 描述 | 运行时间 |"),q.push("|:---|:-----|:-----|:-----|:---------|");for(let O of W){let H=O.completedAt?Y7(O.completedAt-O.createdAt):Y7(Date.now()-O.createdAt),_=AK(O.status);q.push(`| \`${O.id.slice(0,12)}...\` | ${_} ${O.status} | ${O.subagentType} | ${RK(O.description,25)} | ${H} |`)}q.push("")}let U=K.filter((O)=>O.status==="running").length,F=J.getRunningCount();if(K.length===0&&W.length===0)q.push(`*暂无后台任务*
|
|
2678
2678
|
`);else q.push(`**统计**: ${K.length} shells (${U} 运行中), ${W.length} agents (${F} 运行中)`);return q.push(`
|
|
2679
2679
|
---`),q.push("\uD83D\uDCA1 **命令**:"),q.push("- `/tasks` - 列出所有后台任务"),q.push("- `/tasks clean` - 清理已完成的 Agent 会话"),Y.sendMessage(q.join(`
|
|
2680
|
-
`)),{success:!0,message:`Listed ${K.length} shells and ${W.length} agents`}}var
|
|
2680
|
+
`)),{success:!0,message:`Listed ${K.length} shells and ${W.length} agents`}}var JL,VK;var DK=b(()=>{p6();W3();p1();JL={name:"tasks",description:"列出所有后台任务(shells 和 agents)",fullDescription:`查看和管理后台运行的任务。
|
|
2681
2681
|
|
|
2682
2682
|
**功能**:
|
|
2683
2683
|
- 列出所有后台 shell 进程
|
|
@@ -2686,15 +2686,15 @@ ${Y}
|
|
|
2686
2686
|
|
|
2687
2687
|
**使用示例**:
|
|
2688
2688
|
- \`/tasks\` - 显示所有后台任务
|
|
2689
|
-
- \`/tasks clean\` - 清理已完成的 agent 会话`,usage:"/tasks [clean]",category:"system",examples:["/tasks","/tasks clean"],handler:
|
|
2689
|
+
- \`/tasks clean\` - 清理已完成的 agent 会话`,usage:"/tasks [clean]",category:"system",examples:["/tasks","/tasks clean"],handler:XL},VK=JL});async function qL($,Z){return{success:!0,message:"show_theme_selector",data:{action:"show_theme_selector"}}}var GL,MK;var jK=b(()=>{GL={name:"theme",description:"打开交互式主题选择器",aliases:["themes","style"],usage:"/theme",examples:["/theme"],category:"ui",handler:qL},MK=GL});import KL from"fuse.js";function V3($){return $.trim().startsWith("/")}function WL($){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 UL($){if(k8[$])return k8[$];for(let Z of Object.values(k8))if(Z.aliases?.includes($))return Z;return}function IK($){let Z=$.argumentHint?`/${$.name} ${$.argumentHint}`:`/${$.name}`;return{name:$.name,description:$.description,fullDescription:`[Skill] ${$.description}${$.whenToUse?`
|
|
2690
2690
|
|
|
2691
|
-
**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
|
|
2692
|
-
使用 /help 查看可用命令`}}catch(Y){return{success:!1,error:`命令执行失败: ${Y instanceof Error?Y.message:"未知错误"}`}}}function vK(){let $=Object.values(k8),Y=_$.getInstance().getAllCommands().map((G)=>({name:G.name,description:G.config.description||G.content.slice(0,50),usage:G.config.argumentHint?`/${G.name} ${G.config.argumentHint}`:`/${G.name}`,category:"custom",handler:async()=>({success:!0})})),X=a$().getAllCommands().map((G)=>({name:G.namespacedName,description:G.config.description||G.content.slice(0,50),usage:G.config.argumentHint?`/${G.namespacedName} ${G.config.argumentHint}`:`/${G.namespacedName}`,category:"plugin",handler:async()=>({success:!0})})),q=N$().getUserInvocableSkills().map(IK);return[...$,...Y,...X,...q]}function TK($){let Z=($.startsWith("/")?$.slice(1):$).trim(),Y=Object.values(k8).map((H)=>({name:H.name,description:H.description,aliases:H.aliases||[],label:void 0,argumentHint:void 0,isCustom:!1,isSkill:!1,isPlugin:!1})),Q=_$.getInstance(),X=Q.getAllCommands().map((H)=>({name:H.name,description:H.config.description||H.content.slice(0,50),aliases:[],label:Q.getCommandLabel(H),argumentHint:H.config.argumentHint,isCustom:!0,isSkill:!1,isPlugin:!1})),q=a$().getAllCommands().map((H)=>({name:H.namespacedName,description:H.config.description||H.content.slice(0,50),aliases:[H.originalName],label:`(plugin: ${H.pluginName})`,argumentHint:H.config.argumentHint,isCustom:!1,isSkill:!1,isPlugin:!0})),K=N$().getUserInvocableSkills().map((H)=>({name:H.name,description:H.description,aliases:[],label:"(skill)",argumentHint:H.argumentHint,isCustom:!1,isSkill:!0,isPlugin:!1})),W=[...Y,...X,...q,...K];if(!Z)return W.map((H)=>({command:`/${H.name}`,description:H.label?`${H.description} ${H.label}`:H.description,argumentHint:H.argumentHint,matchScore:50}));return new
|
|
2691
|
+
**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 FL($){return N$().getUserInvocableSkills().find((Q)=>Q.name===$)}async function OL(){await _4()}async function yK($){return await _$.getInstance().initialize($)}async function D3($,Z){try{let{command:Y,args:Q}=WL($),X=UL(Y);if(X)return await X.handler(Q,Z);let J=_$.getInstance();if(J.hasCommand(Y)){let W=J.getCommand(Y);if(W){let U=Z.workspaceRoot||process.cwd(),F=await J.executeCommand(Y,{args:Q,workspaceRoot:U,signal:Z.signal});if(F)return{success:!0,message:`执行自定义命令: /${Y}`,data:{action:"invoke_custom_command",commandName:Y,processedContent:F,config:W.config}}}}let G=a$().findCommand(Y);if(G){let W=Z.workspaceRoot||process.cwd(),U=await J.executePluginCommand(G.namespacedName,{args:Q,workspaceRoot:W,signal:Z.signal});if(U)return{success:!0,message:`执行插件命令: /${G.namespacedName}`,data:{action:"invoke_plugin_command",commandName:G.namespacedName,pluginName:G.pluginName,processedContent:U,config:G.config}}}await OL();let K=FL(Y);if(K)return await IK(K).handler(Q,Z);return{success:!1,error:`未知命令: /${Y}
|
|
2692
|
+
使用 /help 查看可用命令`}}catch(Y){return{success:!1,error:`命令执行失败: ${Y instanceof Error?Y.message:"未知错误"}`}}}function vK(){let $=Object.values(k8),Y=_$.getInstance().getAllCommands().map((G)=>({name:G.name,description:G.config.description||G.content.slice(0,50),usage:G.config.argumentHint?`/${G.name} ${G.config.argumentHint}`:`/${G.name}`,category:"custom",handler:async()=>({success:!0})})),X=a$().getAllCommands().map((G)=>({name:G.namespacedName,description:G.config.description||G.content.slice(0,50),usage:G.config.argumentHint?`/${G.namespacedName} ${G.config.argumentHint}`:`/${G.namespacedName}`,category:"plugin",handler:async()=>({success:!0})})),q=N$().getUserInvocableSkills().map(IK);return[...$,...Y,...X,...q]}function TK($){let Z=($.startsWith("/")?$.slice(1):$).trim(),Y=Object.values(k8).map((H)=>({name:H.name,description:H.description,aliases:H.aliases||[],label:void 0,argumentHint:void 0,isCustom:!1,isSkill:!1,isPlugin:!1})),Q=_$.getInstance(),X=Q.getAllCommands().map((H)=>({name:H.name,description:H.config.description||H.content.slice(0,50),aliases:[],label:Q.getCommandLabel(H),argumentHint:H.config.argumentHint,isCustom:!0,isSkill:!1,isPlugin:!1})),q=a$().getAllCommands().map((H)=>({name:H.namespacedName,description:H.config.description||H.content.slice(0,50),aliases:[H.originalName],label:`(plugin: ${H.pluginName})`,argumentHint:H.config.argumentHint,isCustom:!1,isSkill:!1,isPlugin:!0})),K=N$().getUserInvocableSkills().map((H)=>({name:H.name,description:H.description,aliases:[],label:"(skill)",argumentHint:H.argumentHint,isCustom:!1,isSkill:!0,isPlugin:!1})),W=[...Y,...X,...q,...K];if(!Z)return W.map((H)=>({command:`/${H.name}`,description:H.label?`${H.description} ${H.label}`:H.description,argumentHint:H.argumentHint,matchScore:50}));return new KL(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((H)=>{let _=H.score??1,z=Math.round((1-_)*100),w=H.item;return{command:`/${w.name}`,description:w.label?`${w.description} ${w.label}`:w.description,argumentHint:w.argumentHint,matchScore:z}}).filter((H)=>(H.matchScore||0)>=40)}var k8;var M3=b(()=>{b3();U2();mG();x6();nG();sG();JK();UK();OK();_K();BK();NZ();LK();bK();DK();jK();k8={...pG,init:WK,theme:MK,permissions:o6,model:zK,git:rG,ide:XK,skills:NK,hooks:oG,login:FK,logout:HK,tasks:VK,plugins:wK}});import{nanoid as XR}from"nanoid";class bY{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(){e0.debug(`[AcpSession ${this.id}] Initializing...`),O0.initializeSession(this.connection,this.id,this.clientCapabilities,this.cwd),e0.debug(`[AcpSession ${this.id}] ACP service context initialized`),this.agent=await U$.create({}),e0.debug(`[AcpSession ${this.id}] Agent created successfully`)}sendAvailableCommandsDelayed(){e0.debug(`[AcpSession ${this.id}] Scheduling available commands update (500ms delay)`),setTimeout(()=>{this.sendAvailableCommands()},500)}async handleSlashCommand($,Z){try{e0.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,q,G)=>{let K=`tool_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,W=this.mapToolKind(G);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:K,status:"in_progress",title:`${J}`,content:[{type:"content",content:{type:"text",text:JSON.stringify(q,null,2)}}],kind:W})},sendToolResult:(J,q)=>{if(q.summary)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:q.summary}})}}},Q=await D3($,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 e0.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 $=vK(),Z=["model","permissions","theme","config","exit","ide"],Q=$.filter((X)=>!Z.includes(X.name)).map((X)=>{let J;if(X.usage){let q=X.usage.replace(/^\/\w+\s*/,"").trim();if(q)J=q}if(X.aliases?.length){let q=`Aliases: ${X.aliases.join(", ")}`;J=J?`${J} | ${q}`:q}return{name:X.name,description:X.description,input:J?{hint:J}:void 0}});e0.info(`[AcpSession ${this.id}] Sending available commands: ${JSON.stringify(Q.map((X)=>X.name))}`),this.sendUpdate({sessionUpdate:"available_commands_update",availableCommands:Q}),e0.info(`[AcpSession ${this.id}] Sent ${Q.length} available commands`)}catch($){e0.error(`[AcpSession ${this.id}] Failed to send available commands:`,$)}}async prompt($){O0.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(e0.debug(`[AcpSession ${this.id}] Received prompt: ${Y.slice(0,100)}...`),V3(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(q)=>{return this.requestPermission(q)}}},X={signal:Z.signal,onContent:(q)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:q}})},onThinking:(q)=>{this.sendUpdate({sessionUpdate:"agent_thought_chunk",content:{type:"text",text:q}})},onToolStart:(q,G)=>{let K="function"in q?q.function.name:q.type,W=this.mapToolKind(G);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:q.id,status:"in_progress",title:`Executing ${K}`,content:[],kind:W})},onToolResult:async(q,G)=>{let K=[],W=G.metadata;if(W?.kind==="edit"&&typeof W.file_path==="string"&&typeof W.oldContent==="string"&&(typeof W.newContent==="string"||W.newContent===void 0))K.push({type:"diff",path:W.file_path,oldText:W.oldContent,newText:W.newContent??null});else if(G.displayContent){let O=typeof G.displayContent==="string"?G.displayContent:JSON.stringify(G.displayContent);K.push({type:"content",content:{type:"text",text:O}})}let U="function"in q?q.function.name:q.type,F=G.success?"completed":"failed";this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:q.id,status:F,content:K})},onTodoUpdate:(q)=>{this.sendPlanUpdate(q)}},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 e0.error(`[AcpSession ${this.id}] Prompt error:`,Y),Y}finally{if(this.pendingPrompt===Z)this.pendingPrompt=null}}cancel(){if(e0.info(`[AcpSession ${this.id}] Cancel requested`),this.pendingPrompt)this.pendingPrompt.abort(),this.pendingPrompt=null,e0.info(`[AcpSession ${this.id}] Cancelled successfully`);else e0.warn(`[AcpSession ${this.id}] No pending prompt to cancel`)}async setMode($){let Z=["default","auto-edit","yolo","plan"];this.mode=Z.includes($)?$:"default",e0.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(e0.info(`[AcpSession ${this.id}] Model set to: ${$}`),this.agent)e0.warn(`[AcpSession ${this.id}] Runtime model switching not yet implemented`)}async destroy(){if(this.cancel(),this.agent)await this.agent.destroy(),this.agent=null;O0.destroySession(this.id),e0.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}">
|
|
2693
2693
|
${Q.text}
|
|
2694
2694
|
</file>`)}else if(Y.type==="resource_link")Z.push(`[Resource: ${Y.uri}]`);return Z.join(`
|
|
2695
|
-
`)}sendUpdate($){let Z={sessionId:this.id,update:$};this.connection.sessionUpdate(Z).catch((Y)=>{e0.warn(`[AcpSession ${this.id}] Failed to send update:`,Y)})}sendPlanUpdate($){let Z=$.map((Y)=>({content:Y.content,priority:Y.priority,status:Y.status}));e0.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 e0.debug(`[AcpSession ${this.id}] Auto-approving ${Z} in mode: ${this.mode}`),{approved:!0};if(this.mode==="plan"&&(Z==="write"||Z==="execute"))return e0.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 e0.debug(`[AcpSession ${this.id}] Using cached approval for: ${Y}`),{approved:!0};try{let Q=
|
|
2695
|
+
`)}sendUpdate($){let Z={sessionId:this.id,update:$};this.connection.sessionUpdate(Z).catch((Y)=>{e0.warn(`[AcpSession ${this.id}] Failed to send update:`,Y)})}sendPlanUpdate($){let Z=$.map((Y)=>({content:Y.content,priority:Y.priority,status:Y.status}));e0.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 e0.debug(`[AcpSession ${this.id}] Auto-approving ${Z} in mode: ${this.mode}`),{approved:!0};if(this.mode==="plan"&&(Z==="write"||Z==="execute"))return e0.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 e0.debug(`[AcpSession ${this.id}] Using cached approval for: ${Y}`),{approved:!0};try{let Q=XR(),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:
|
|
2696
2696
|
- ${$.risks.join(`
|
|
2697
|
-
- `)}`}});let J=this.mapToolKind(Z),q={sessionId:this.id,options:[{optionId:"allow_once",name:"Allow once",kind:"allow_once"},{optionId:"allow_always",name:"Always allow",kind:"allow_always"},{optionId:"reject_once",name:"Deny once",kind:"reject_once"},{optionId:"reject_always",name:"Always deny",kind:"reject_always"}],toolCall:{toolCallId:Q,status:"pending",title:$.title||"Permission Required",content:X,kind:J}},K=(await this.connection.requestPermission(q)).outcome;if(K.outcome==="cancelled")return{approved:!1,reason:"User cancelled the permission request"};let W=K.optionId,U=W==="allow_once"||W==="allow_always";if(W==="allow_always")this.sessionApprovals.add(Y),e0.debug(`[AcpSession ${this.id}] Cached approval for: ${Y}`);return{approved:U,reason:U?void 0:"User denied the operation"}}catch(Q){return e0.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 e0;var VF=b(()=>{O2();G$();z0();M3();q3();e0=l("Agent")});import{PROTOCOL_VERSION as
|
|
2697
|
+
- `)}`}});let J=this.mapToolKind(Z),q={sessionId:this.id,options:[{optionId:"allow_once",name:"Allow once",kind:"allow_once"},{optionId:"allow_always",name:"Always allow",kind:"allow_always"},{optionId:"reject_once",name:"Deny once",kind:"reject_once"},{optionId:"reject_always",name:"Always deny",kind:"reject_always"}],toolCall:{toolCallId:Q,status:"pending",title:$.title||"Permission Required",content:X,kind:J}},K=(await this.connection.requestPermission(q)).outcome;if(K.outcome==="cancelled")return{approved:!1,reason:"User cancelled the permission request"};let W=K.optionId,U=W==="allow_once"||W==="allow_always";if(W==="allow_always")this.sessionApprovals.add(Y),e0.debug(`[AcpSession ${this.id}] Cached approval for: ${Y}`);return{approved:U,reason:U?void 0:"User denied the operation"}}catch(Q){return e0.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 e0;var VF=b(()=>{O2();G$();z0();M3();q3();e0=l("Agent")});import{PROTOCOL_VERSION as JR}from"@agentclientprotocol/sdk";import{nanoid as qR}from"nanoid";class AY{connection;sessions=new Map;clientCapabilities;constructor($){this.connection=$}async initialize($){return Q2.info("[BladeAgent] Initializing ACP connection"),Q2.debug(`[BladeAgent] Client capabilities: ${JSON.stringify($.clientCapabilities)}`),this.clientCapabilities=$.clientCapabilities,{protocolVersion:JR,agentCapabilities:{loadSession:!1,promptCapabilities:{image:!0,audio:!1,embeddedContext:!0},mcpCapabilities:{http:!0,sse:!0}}}}async authenticate($){return}async newSession($){let Z=qR();Q2.info(`[BladeAgent] Creating new session: ${Z}`),Q2.debug(`[BladeAgent] Session cwd: ${$.cwd||process.cwd()}`);let Y=new bY(Z,$.cwd||process.cwd(),this.connection,this.clientCapabilities);await Y.initialize(),this.sessions.set(Z,Y),Q2.info(`[BladeAgent] Session ${Z} created, scheduling available commands update`),Y.sendAvailableCommandsDelayed();let Q=K$(),X=Q?.models||[],J=Q?.currentModelId||X[0]?.id,q=X.map((K)=>({modelId:K.id,name:K.name||K.id,description:K.provider?`Provider: ${K.provider}`:void 0}));return{sessionId:Z,modes:{availableModes:[{id:"default",name:"Default",description:"Ask for confirmation before all file edits and commands"},{id:"auto-edit",name:"Auto Edit",description:"Auto-approve file edits, ask for shell commands"},{id:"yolo",name:"Full Auto",description:"Auto-approve everything without confirmation"},{id:"plan",name:"Plan Only",description:"Read-only mode, no file changes or commands"}],currentModeId:"default"},models:q.length>0?{availableModels:q,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($){Q2.info(`[BladeAgent] Cancel notification received for session: ${$.sessionId}`);let Z=this.sessions.get($.sessionId);if(Z)Q2.info("[BladeAgent] Found session, calling session.cancel()"),Z.cancel();else Q2.warn(`[BladeAgent] Session not found for cancel: ${$.sessionId}`)}async setSessionMode($){Q2.info(`[BladeAgent] Setting session mode: ${$.modeId}`);let Z=this.sessions.get($.sessionId);if(Z)await Z.setMode($.modeId);return{}}async unstable_setSessionModel($){Q2.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 Q2;var DF=b(()=>{z0();T0();VF();Q2=l("Agent")});var MF={};SF(MF,{runAcpIntegration:()=>WR});import{Readable as GR,Writable as KR}from"node:stream";import*as x7 from"@agentclientprotocol/sdk";async function WR(){let $=KR.toWeb(process.stdout),Z=GR.toWeb(process.stdin),Y=x7.ndJsonStream($,Z);await new x7.AgentSideConnection((X)=>new AY(X),Y).closed}var jF=b(()=>{DF()});import{render as UR}from"ink";import FR from"react";import OR from"yargs";import{hideBin as yF}from"yargs/helpers";d3();var TY={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:"}},J4={scriptName:"blade",usage:"$0 [command] [options]",description:yY(),version:u4(),locale:"en",showHelpOnFail:!0,demandCommand:!1,recommendCommands:!0,strict:!1};a4();z0();T0();var J9=l("General"),_Q=($)=>{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(", ")}`)}},zQ=async($)=>{try{let Y=await g$.getInstance().initialize();if(J0().config.actions.setConfig(Y),$.debug)J9.info("[CLI] 配置已加载到 Store")}catch(Z){J9.error("[CLI] ❌ 配置初始化失败",Z instanceof Error?Z.message:Z),console.error(`
|
|
2698
2698
|
❌ 配置初始化失败
|
|
2699
2699
|
`),console.error("原因:",Z instanceof Error?Z.message:"未知错误"),console.error(`
|
|
2700
2700
|
请检查:`),console.error(" 1. 配置文件格式是否正确 (~/.blade/config.json)"),console.error(" 2. 是否需要运行 blade 进行首次配置"),console.error(` 3. 配置文件权限是否正确
|
|
@@ -2712,10 +2712,10 @@ blade mcp
|
|
|
2712
2712
|
示例:`),console.log(" blade mcp add github npx -y @modelcontextprotocol/server-github"),console.log(" blade mcp add github -- npx -y @modelcontextprotocol/server-github"),process.exit(1);let B={type:z};if(z==="stdio"){if(B.command=U,B.args=F,O)B.env=kO(O)}else if(B.url=U,H)B.headers=fO(H);if(_!==void 0)B.timeout=_;await C0().addMcpServer(W,B,{scope:K?"global":"project"});let L=K?$6.join(kQ.homedir(),".blade","config.json"):$6.join(process.cwd(),".blade","config.json");console.log(`✅ MCP 服务器 "${W}" 已添加`),console.log(` 配置文件: ${L}`)}catch(Z){console.error(`❌ 添加失败: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}},xO={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=F1(),Y=$.global===!0,Q=s4($.name);if(!Q)console.error("❌ 缺少必需参数: name"),process.exit(1);if(!Z[Q])console.error(`❌ 服务器 "${Q}" 不存在`),process.exit(1);await C0().removeMcpServer(Q,{scope:Y?"global":"project"}),console.log(`✅ MCP 服务器 "${Q}" 已删除`)}catch(Z){console.error(`❌ 删除失败: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}},pO={command:"list",describe:"列出所有 MCP 服务器并检查健康状态",aliases:["ls"],handler:async()=>{try{let $=F1();if(console.log(""),Object.keys($).length===0){console.log("暂无配置的 MCP 服务器");return}console.log(`检查 MCP 服务器健康状态...
|
|
2713
2713
|
`);let Z=w$.getInstance(),Y=Object.entries($).map(async([X,J])=>{try{let q=Z.getServerStatus(X);if(!q)await Z.registerServer(X,J),q=Z.getServerStatus(X);else if(q.status==="disconnected")await Z.connectServer(X);return{name:X,config:J,serverInfo:q}}catch(q){return{name:X,config:J,serverInfo:null,error:q}}}),Q=await Promise.all(Y);for(let{name:X,config:J,serverInfo:q,error:G}of Q){let K=q?.status||"disconnected",W=K==="connected"?"✓":"✗",U=K==="connected"?"Connected":"Failed";if(console.log(`${X}: ${J.type==="stdio"?J.command:J.url} - ${W} ${U}`),G&&K!=="connected")console.log(` 错误: ${G instanceof Error?G.message:String(G)}`)}console.log("");for(let{name:X}of Q)try{await Z.unregisterServer(X)}catch(J){}process.exit(0)}catch($){console.error(`❌ 列表获取失败: ${$ instanceof Error?$.message:"未知错误"}`),process.exit(1)}}},mO={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=F1(),Y=s4($.name);if(!Y)console.error("❌ 缺少必需参数: name"),process.exit(1);let Q=Z[Y];if(!Q)console.error(`❌ 服务器 "${Y}" 不存在`),process.exit(1);console.log(`
|
|
2714
2714
|
服务器: ${Y}
|
|
2715
|
-
`),console.log(JSON.stringify(Q,null,2))}catch(Z){console.error(`❌ 获取失败: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}},gO={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=s4($.json),Y=s4($.name);if(!Z||!Y)throw Error("缺少必需参数: name 或 json");let Q=JSON.parse(Z),X=$.global===!0;if(!Q.type)throw Error('配置必须包含 "type" 字段');await C0().addMcpServer(Y,Q,{scope:X?"global":"project"});let J=X?$6.join(kQ.homedir(),".blade","config.json"):$6.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)}}},fQ={command:"mcp",describe:"管理 MCP 服务器",builder:($)=>{return $.command(hO).command(xO).command(pO).command(mO).command(gO).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)SO(),process.exit(0)}};O2();b3();M3();function
|
|
2715
|
+
`),console.log(JSON.stringify(Q,null,2))}catch(Z){console.error(`❌ 获取失败: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}},gO={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=s4($.json),Y=s4($.name);if(!Z||!Y)throw Error("缺少必需参数: name 或 json");let Q=JSON.parse(Z),X=$.global===!0;if(!Q.type)throw Error('配置必须包含 "type" 字段');await C0().addMcpServer(Y,Q,{scope:X?"global":"project"});let J=X?$6.join(kQ.homedir(),".blade","config.json"):$6.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)}}},fQ={command:"mcp",describe:"管理 MCP 服务器",builder:($)=>{return $.command(hO).command(xO).command(pO).command(mO).command(gO).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)SO(),process.exit(0)}};O2();b3();M3();function HL($){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 a$().initialize(process.cwd(),[])).plugins.length>0)await g2();let X="",J=Z.message||Z._?.[0];if(J&&typeof J==="string")X=J;else if(!process.stdin.isTTY){let K=[];for await(let W of process.stdin)K.push(W);X=Buffer.concat(K).toString("utf-8").trim()}else X="Hello";if(V3(X)){let K=await D3(X,{cwd:process.cwd(),workspaceRoot:process.cwd()});if(!K.success)console.error(`Error: ${K.error||"未知错误"}`),process.exit(1);let W=K.data;if(W?.action==="invoke_skill"){let{skillName:U,skillArgs:F}=W;X=F?`Please use the "${U}" skill to help me with: ${F}`:`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}
|
|
2716
2716
|
|
|
2717
|
-
${U}`}else{if(K.message)console.log(K.message);process.exit(0)}}let q=await U$.create({systemPrompt:Z.systemPrompt,appendSystemPrompt:Z.appendSystemPrompt,maxTurns:Z.maxTurns}),G;if(Z.appendSystemPrompt)G=await q.chatWithSystem(Z.appendSystemPrompt,X);else G=await q.chat(X,{messages:[],userId:"cli-user",sessionId:`print-${Date.now()}`,workspaceRoot:process.cwd()});if(Z.outputFormat==="json")console.log(JSON.stringify({response:G,input:X,model:Z.model,timestamp:new Date().toISOString()},null,2));else if(Z.outputFormat==="stream-json")console.log(JSON.stringify({type:"response",content:G}));else console.log(G);process.exit(0)}catch(Y){console.error(`Error: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}})}async function EK(){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 OL(X),await X.parse(),!0}catch(Y){console.error(`Print mode error: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}import{execSync as NL}from"child_process";O4();import*as I4 from"fs/promises";import*as d2 from"path";import PK from"semver";import{fileURLToPath as HL}from"url";var jZ="blade-code",_L="https://cdn.jsdelivr.net/npm/blade-code@latest/CHANGELOG.md",CK=d2.join(process.env.HOME||process.env.USERPROFILE||".",".blade"),SK=d2.join(CK,"version-cache.json"),zL=3600000,BL=`https://registry.npmjs.org/${jZ}/latest`;async function wL(){try{if(process.env.BLADE_VERSION)return process.env.BLADE_VERSION;let $=HL(import.meta.url),Z=d2.dirname($),Y=[d2.join(Z,"..","..","package.json"),d2.join(Z,"..","package.json"),d2.join(process.cwd(),"package.json")];for(let Q of Y)try{let X=await I4.readFile(Q,"utf-8"),J=JSON.parse(X);if(J.name===jZ&&J.version)return J.version}catch{}return"unknown"}catch{return"unknown"}}async function kK(){try{let $=await I4.readFile(SK,"utf-8"),Z=JSON.parse($);if(Date.now()-Z.checkedAt<zL)return Z;return{...Z,checkedAt:0}}catch{return null}}async function fK($){try{await I4.mkdir(CK,{recursive:!0,mode:493}),await I4.writeFile(SK,JSON.stringify($,null,2))}catch{}}async function LL(){try{let $=await L$(BL,{timeout:5000,headers:{Accept:"application/json"}});if(!$.ok)return null;return(await $.json()).version||null}catch{return null}}async function IZ($=!1){let Z=await wL(),Y=_L;if(Z==="unknown")return{currentVersion:Z,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:Y,error:"Unable to determine current version"};let Q=await kK(),X=Q?.skipUntilVersion,J=null;if(!$&&Q&&Q.checkedAt>0)J=Q.latestVersion;else if(J=await LL(),J)await fK({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 q=PK.gt(J,Z),G=q;if(q&&X)G=PK.gt(J,X);return{currentVersion:Z,latestVersion:J,hasUpdate:q,shouldPrompt:G,releaseNotesUrl:Y}}async function hK($){let Z=await kK();await fK({latestVersion:Z?.latestVersion||$,checkedAt:Z?.checkedAt||Date.now(),skipUntilVersion:$})}function yZ(){return`npm install -g ${jZ}@latest --registry https://registry.npmjs.org`}async function xK(){let{spawn:$}=await import("child_process");return new Promise((Z)=>{let Y=yZ(),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 pK(){try{let $=await IZ();return $.shouldPrompt?$:null}catch{return null}}var mK={command:"update",describe:"Check for updates and install if available",handler:async()=>{console.log("\uD83D\uDD0D Checking for updates...");try{let $=await IZ(!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{NL("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)}}};z0();G$();t$();z0();T0();function gK(){process.stdout.write("\x1B[?25h"),process.stdout.write("\x1B[0m")}var c2=l("Service");function bL($){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 j3{static instance=null;cleanupHandlers=[];isShuttingDown=!1;initialized=!1;constructor(){}static getInstance(){if(!j3.instance)j3.instance=new j3;return j3.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 fY()}catch(X){}try{let X=R0.getInstance();if(X.isEnabled()){let J=J0(),q=J.session?.sessionId||"unknown",G=J.config?.config?.permissionMode||"default";await X.executeSessionEndHooks(bL($),{projectDir:process.cwd(),sessionId:q,permissionMode:G})}}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{gK(),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 y4=()=>{return j3.getInstance()},uK=($)=>{return y4().registerCleanup($)},dK=()=>{y4().initialize()},I3=($=0)=>{gK(),process.exit($)};R4();Z6();a4();t$();z0();F4();b3();import{useMemoizedFn as AF}from"ahooks";import{useEffect as ZR,useState as NY}from"react";U2();M3();T0();W3();G$();z0();import{useMemoizedFn as r$}from"ahooks";import{Box as Q4,useApp as sA}from"ink";import{useEffect as m4,useRef as S7}from"react";t6();z1();q4();import{useShallow as cK}from"zustand/react/shallow";T0();import{useStore as AL}from"zustand";function B0($){return AL(T1,$)}G$();var RL=[],lK=()=>B0(($)=>$.session.sessionId),Q7=()=>B0(($)=>$.session.messages),iK=()=>B0(($)=>$.session.clearCount),aK=()=>B0(($)=>$.session.isCompacting),l2=()=>B0(($)=>$.session.actions),rK=()=>B0(($)=>{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)}),nK=()=>B0(($)=>$.app.initializationStatus),oK=()=>B0(($)=>$.app.initializationError),X7=()=>B0(($)=>$.app.activeModal),sK=()=>B0(($)=>$.app.todos),tK=()=>B0(($)=>$.app.modelEditorTarget),eK=()=>B0(($)=>$.app.sessionSelectorData),$W=()=>B0(($)=>$.app.awaitingSecondCtrlC),i2=()=>B0(($)=>$.app.actions),J7=()=>B0(($)=>$.app.initializationStatus==="ready"),ZW=()=>B0(($)=>$.app.todos.length>0),y3=()=>B0(($)=>$.config.config?.permissionMode||"default"),YW=()=>B0(($)=>$.config.config?.models??RL),q7=()=>B0(($)=>{let Z=$.config.config;if(!Z)return;let Y=Z.currentModelId;return Z.models.find((X)=>X.id===Y)??Z.models[0]}),QW=()=>B0(($)=>$.config.config?.currentModelId),m0=()=>B0(($)=>{let Z=$.config.config?.theme??"default";if(u$.getCurrentThemeName()!==Z)try{u$.setTheme(Z)}catch{}return u$.getTheme()}),Z1=()=>B0(($)=>$.focus.currentFocus),XW=()=>B0(($)=>$.focus.actions),a2=()=>B0(($)=>$.command.isProcessing),JW=()=>B0(($)=>$.command.actions),qW=()=>B0(($)=>$.command.pendingCommands),G7=()=>B0(($)=>$.app.thinkingModeEnabled),GW=()=>B0(($)=>$.session.currentThinkingContent),KW=()=>B0(($)=>$.session.thinkingExpanded),WW=()=>B0(($)=>$.session.currentStreamingMessageId),UW=()=>B0(cK(($)=>({lines:$.session.currentStreamingLines,tail:$.session.currentStreamingTail,lineCount:$.session.currentStreamingLineCount,version:$.session.currentStreamingVersion}))),FW=()=>B0(($)=>$.session.finalizingStreamingMessageId),OW=()=>B0(($)=>$.session.historyExpanded),HW=()=>B0(($)=>$.session.expandedMessageCount),_W=()=>B0(cK(($)=>{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}}));T0();t$();z0();l9();import{useMemoizedFn as r2}from"ahooks";import{useEffect as wW,useRef as f8}from"react";M3();T0();l3();MZ();O2();import{useMemoizedFn as zW}from"ahooks";import{useRef as VL}from"react";function BW($){let Z=VL(void 0),Y=zW(async()=>{let X=await U$.create({systemPrompt:$.systemPrompt,appendSystemPrompt:$.appendSystemPrompt,maxTurns:$.maxTurns});return Z.current=X,X}),Q=zW(()=>{if(Z.current)Z.current=void 0});return{agentRef:Z,createAgent:Y,cleanupAgent:Q}}var LW=l("UI");function DL($,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 I3(0),!0;default:return!1}}function ML($){return typeof $==="object"&&$!==null&&$.action==="invoke_skill"&&typeof $.skillName==="string"}function jL($){return typeof $==="object"&&$!==null&&$.action==="invoke_custom_command"&&typeof $.commandName==="string"&&typeof $.processedContent==="string"}function IL($){return typeof $==="object"&&$!==null&&$.action==="invoke_plugin_command"&&typeof $.commandName==="string"&&typeof $.processedContent==="string"}function yL($){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 NW=($,Z,Y,Q)=>{let X=a2(),J=Q7(),q=lK(),G=y3(),K=G7(),W=l2(),U=i2(),F=JW(),O=f8(!1),{createAgent:H,cleanupAgent:_}=BW({systemPrompt:$,appendSystemPrompt:Z,maxTurns:Q}),z=300,w=5,B=400,L=f8(""),V=f8(null),D=f8(""),R=f8(null),y=r2(()=>{if(L.current){let j=L.current,M=W.appendAssistantContent(j);e7(M,j),L.current=""}if(V.current)clearTimeout(V.current),V.current=null}),I=r2(()=>{if(D.current)W.appendThinkingContent(D.current),D.current="";if(R.current)clearTimeout(R.current),R.current=null}),N=(j)=>{let M=0;for(let A of j)if(A===`
|
|
2718
|
-
`)M++;return M},P=r2((j)=>{L.current+=j;let M=L.current;if(N(M)>=5||M.length>=400){y();return}if(!V.current)V.current=setTimeout(y,300)}),m=r2((j)=>{D.current+=j;let M=D.current;if(N(M)>=5||M.length>=400){I();return}if(!R.current)R.current=setTimeout(I,300)}),e=r2(()=>{if(L.current="",V.current)clearTimeout(V.current),V.current=null;if(D.current="",R.current)clearTimeout(R.current),R.current=null});wW(()=>{return()=>{_(),e()}},[_,e]),wW(()=>{if(!K)W.setCurrentThinkingContent(null)},[K,W]);let S=r2(()=>{if(!X)return;y(),I(),F.abort(),U.setTodos([]);let j=J0().session.currentStreamingMessageId;if(j)$9(j);if(W.finalizeStreamingMessage(),!O.current)W.addAssistantMessage("✋ 任务已停止"),O.current=!0}),T=r2(async(j)=>{let{text:M}=j,A=!1;try{if(V3(M)){await o8();let X0=F.createAbortController(),s0={cwd:process.cwd(),signal:X0.signal},w0=await D3(M,s0);if(w0.message){if(
|
|
2717
|
+
${U}`}else{if(K.message)console.log(K.message);process.exit(0)}}let q=await U$.create({systemPrompt:Z.systemPrompt,appendSystemPrompt:Z.appendSystemPrompt,maxTurns:Z.maxTurns}),G;if(Z.appendSystemPrompt)G=await q.chatWithSystem(Z.appendSystemPrompt,X);else G=await q.chat(X,{messages:[],userId:"cli-user",sessionId:`print-${Date.now()}`,workspaceRoot:process.cwd()});if(Z.outputFormat==="json")console.log(JSON.stringify({response:G,input:X,model:Z.model,timestamp:new Date().toISOString()},null,2));else if(Z.outputFormat==="stream-json")console.log(JSON.stringify({type:"response",content:G}));else console.log(G);process.exit(0)}catch(Y){console.error(`Error: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}})}async function EK(){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 HL(X),await X.parse(),!0}catch(Y){console.error(`Print mode error: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}import{execSync as bL}from"child_process";O4();import*as I4 from"fs/promises";import*as d2 from"path";import PK from"semver";import{fileURLToPath as _L}from"url";var jZ="blade-code",zL="https://cdn.jsdelivr.net/npm/blade-code@latest/CHANGELOG.md",CK=d2.join(process.env.HOME||process.env.USERPROFILE||".",".blade"),SK=d2.join(CK,"version-cache.json"),BL=3600000,wL=`https://registry.npmjs.org/${jZ}/latest`;async function LL(){try{if(process.env.BLADE_VERSION)return process.env.BLADE_VERSION;let $=_L(import.meta.url),Z=d2.dirname($),Y=[d2.join(Z,"..","..","package.json"),d2.join(Z,"..","package.json"),d2.join(process.cwd(),"package.json")];for(let Q of Y)try{let X=await I4.readFile(Q,"utf-8"),J=JSON.parse(X);if(J.name===jZ&&J.version)return J.version}catch{}return"unknown"}catch{return"unknown"}}async function kK(){try{let $=await I4.readFile(SK,"utf-8"),Z=JSON.parse($);if(Date.now()-Z.checkedAt<BL)return Z;return{...Z,checkedAt:0}}catch{return null}}async function fK($){try{await I4.mkdir(CK,{recursive:!0,mode:493}),await I4.writeFile(SK,JSON.stringify($,null,2))}catch{}}async function NL(){try{let $=await L$(wL,{timeout:5000,headers:{Accept:"application/json"}});if(!$.ok)return null;return(await $.json()).version||null}catch{return null}}async function IZ($=!1){let Z=await LL(),Y=zL;if(Z==="unknown")return{currentVersion:Z,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:Y,error:"Unable to determine current version"};let Q=await kK(),X=Q?.skipUntilVersion,J=null;if(!$&&Q&&Q.checkedAt>0)J=Q.latestVersion;else if(J=await NL(),J)await fK({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 q=PK.gt(J,Z),G=q;if(q&&X)G=PK.gt(J,X);return{currentVersion:Z,latestVersion:J,hasUpdate:q,shouldPrompt:G,releaseNotesUrl:Y}}async function hK($){let Z=await kK();await fK({latestVersion:Z?.latestVersion||$,checkedAt:Z?.checkedAt||Date.now(),skipUntilVersion:$})}function yZ(){return`npm install -g ${jZ}@latest --registry https://registry.npmjs.org`}async function xK(){let{spawn:$}=await import("child_process");return new Promise((Z)=>{let Y=yZ(),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 pK(){try{let $=await IZ();return $.shouldPrompt?$:null}catch{return null}}var mK={command:"update",describe:"Check for updates and install if available",handler:async()=>{console.log("\uD83D\uDD0D Checking for updates...");try{let $=await IZ(!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{bL("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)}}};z0();G$();t$();z0();T0();function gK(){process.stdout.write("\x1B[?25h"),process.stdout.write("\x1B[0m")}var c2=l("Service");function AL($){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 j3{static instance=null;cleanupHandlers=[];isShuttingDown=!1;initialized=!1;constructor(){}static getInstance(){if(!j3.instance)j3.instance=new j3;return j3.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 fY()}catch(X){}try{let X=R0.getInstance();if(X.isEnabled()){let J=J0(),q=J.session?.sessionId||"unknown",G=J.config?.config?.permissionMode||"default";await X.executeSessionEndHooks(AL($),{projectDir:process.cwd(),sessionId:q,permissionMode:G})}}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{gK(),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 y4=()=>{return j3.getInstance()},uK=($)=>{return y4().registerCleanup($)},dK=()=>{y4().initialize()},I3=($=0)=>{gK(),process.exit($)};R4();Z6();a4();t$();z0();F4();b3();import{useMemoizedFn as AF}from"ahooks";import{useEffect as YR,useState as NY}from"react";U2();M3();T0();W3();G$();z0();import{useMemoizedFn as r$}from"ahooks";import{Box as Q4,useApp as tA}from"ink";import{useEffect as m4,useRef as S7}from"react";t6();z1();q4();import{useShallow as cK}from"zustand/react/shallow";T0();import{useStore as RL}from"zustand";function B0($){return RL(T1,$)}G$();var VL=[],lK=()=>B0(($)=>$.session.sessionId),Q7=()=>B0(($)=>$.session.messages),iK=()=>B0(($)=>$.session.clearCount),aK=()=>B0(($)=>$.session.isCompacting),l2=()=>B0(($)=>$.session.actions),rK=()=>B0(($)=>{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)}),nK=()=>B0(($)=>$.app.initializationStatus),oK=()=>B0(($)=>$.app.initializationError),X7=()=>B0(($)=>$.app.activeModal),sK=()=>B0(($)=>$.app.todos),tK=()=>B0(($)=>$.app.modelEditorTarget),eK=()=>B0(($)=>$.app.sessionSelectorData),$W=()=>B0(($)=>$.app.awaitingSecondCtrlC),i2=()=>B0(($)=>$.app.actions),J7=()=>B0(($)=>$.app.initializationStatus==="ready"),ZW=()=>B0(($)=>$.app.todos.length>0),y3=()=>B0(($)=>$.config.config?.permissionMode||"default"),YW=()=>B0(($)=>$.config.config?.models??VL),q7=()=>B0(($)=>{let Z=$.config.config;if(!Z)return;let Y=Z.currentModelId;return Z.models.find((X)=>X.id===Y)??Z.models[0]}),QW=()=>B0(($)=>$.config.config?.currentModelId),m0=()=>B0(($)=>{let Z=$.config.config?.theme??"default";if(u$.getCurrentThemeName()!==Z)try{u$.setTheme(Z)}catch{}return u$.getTheme()}),Z1=()=>B0(($)=>$.focus.currentFocus),XW=()=>B0(($)=>$.focus.actions),a2=()=>B0(($)=>$.command.isProcessing),JW=()=>B0(($)=>$.command.actions),qW=()=>B0(($)=>$.command.pendingCommands),G7=()=>B0(($)=>$.app.thinkingModeEnabled),GW=()=>B0(($)=>$.session.currentThinkingContent),KW=()=>B0(($)=>$.session.thinkingExpanded),WW=()=>B0(($)=>$.session.currentStreamingMessageId),UW=()=>B0(cK(($)=>({lines:$.session.currentStreamingLines,tail:$.session.currentStreamingTail,lineCount:$.session.currentStreamingLineCount,version:$.session.currentStreamingVersion}))),FW=()=>B0(($)=>$.session.finalizingStreamingMessageId),OW=()=>B0(($)=>$.session.historyExpanded),HW=()=>B0(($)=>$.session.expandedMessageCount),_W=()=>B0(cK(($)=>{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}}));T0();t$();z0();l9();import{useMemoizedFn as r2}from"ahooks";import{useEffect as wW,useRef as f8}from"react";M3();T0();l3();MZ();O2();import{useMemoizedFn as zW}from"ahooks";import{useRef as DL}from"react";function BW($){let Z=DL(void 0),Y=zW(async()=>{let X=await U$.create({systemPrompt:$.systemPrompt,appendSystemPrompt:$.appendSystemPrompt,maxTurns:$.maxTurns});return Z.current=X,X}),Q=zW(()=>{if(Z.current)Z.current=void 0});return{agentRef:Z,createAgent:Y,cleanupAgent:Q}}var LW=l("UI");function ML($,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 I3(0),!0;default:return!1}}function jL($){return typeof $==="object"&&$!==null&&$.action==="invoke_skill"&&typeof $.skillName==="string"}function IL($){return typeof $==="object"&&$!==null&&$.action==="invoke_custom_command"&&typeof $.commandName==="string"&&typeof $.processedContent==="string"}function yL($){return typeof $==="object"&&$!==null&&$.action==="invoke_plugin_command"&&typeof $.commandName==="string"&&typeof $.processedContent==="string"}function vL($){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 NW=($,Z,Y,Q)=>{let X=a2(),J=Q7(),q=lK(),G=y3(),K=G7(),W=l2(),U=i2(),F=JW(),O=f8(!1),{createAgent:H,cleanupAgent:_}=BW({systemPrompt:$,appendSystemPrompt:Z,maxTurns:Q}),z=300,w=5,B=400,L=f8(""),V=f8(null),D=f8(""),R=f8(null),y=r2(()=>{if(L.current){let j=L.current,M=W.appendAssistantContent(j);e7(M,j),L.current=""}if(V.current)clearTimeout(V.current),V.current=null}),I=r2(()=>{if(D.current)W.appendThinkingContent(D.current),D.current="";if(R.current)clearTimeout(R.current),R.current=null}),N=(j)=>{let M=0;for(let A of j)if(A===`
|
|
2718
|
+
`)M++;return M},P=r2((j)=>{L.current+=j;let M=L.current;if(N(M)>=5||M.length>=400){y();return}if(!V.current)V.current=setTimeout(y,300)}),m=r2((j)=>{D.current+=j;let M=D.current;if(N(M)>=5||M.length>=400){I();return}if(!R.current)R.current=setTimeout(I,300)}),e=r2(()=>{if(L.current="",V.current)clearTimeout(V.current),V.current=null;if(D.current="",R.current)clearTimeout(R.current),R.current=null});wW(()=>{return()=>{_(),e()}},[_,e]),wW(()=>{if(!K)W.setCurrentThinkingContent(null)},[K,W]);let S=r2(()=>{if(!X)return;y(),I(),F.abort(),U.setTodos([]);let j=J0().session.currentStreamingMessageId;if(j)$9(j);if(W.finalizeStreamingMessage(),!O.current)W.addAssistantMessage("✋ 任务已停止"),O.current=!0}),T=r2(async(j)=>{let{text:M}=j,A=!1;try{if(V3(M)){await o8();let X0=F.createAbortController(),s0={cwd:process.cwd(),signal:X0.signal},w0=await D3(M,s0);if(w0.message){if(ML(w0.message,w0.data,U,W))return{success:!0}}let X2=!1;if(jL(w0.data)){let{skillName:p$,skillArgs:I2}=w0.data,I1=I2?`Please use the "${p$}" skill to help me with: ${I2}`:`Please use the "${p$}" skill.`;W.addUserMessage(I1),A=!0,X2=!0,j={displayText:I1,text:I1,images:[],parts:[{type:"text",text:I1}]}}if(IL(w0.data)){let{commandName:p$,processedContent:I2}=w0.data;W.addUserMessage(M),A=!0,X2=!0;let I1=`# Custom Command: /${p$}
|
|
2719
2719
|
|
|
2720
2720
|
The user has invoked the custom command "/${p$}". Follow the instructions below to complete the task.
|
|
2721
2721
|
|
|
@@ -2725,7 +2725,7 @@ ${I2}
|
|
|
2725
2725
|
|
|
2726
2726
|
---
|
|
2727
2727
|
|
|
2728
|
-
Remember: Follow the above instructions carefully to complete the user's request.`;j={displayText:M,text:I1,images:[],parts:[{type:"text",text:I1}]}}if(
|
|
2728
|
+
Remember: Follow the above instructions carefully to complete the user's request.`;j={displayText:M,text:I1,images:[],parts:[{type:"text",text:I1}]}}if(yL(w0.data)){let{commandName:p$,pluginName:I2,processedContent:I1}=w0.data;W.addUserMessage(M),A=!0,X2=!0;let a8=`# Plugin Command: /${p$}
|
|
2729
2729
|
|
|
2730
2730
|
The user has invoked the plugin command "/${p$}" from plugin "${I2}". Follow the instructions below to complete the task.
|
|
2731
2731
|
|
|
@@ -2735,9 +2735,9 @@ ${I1}
|
|
|
2735
2735
|
|
|
2736
2736
|
---
|
|
2737
2737
|
|
|
2738
|
-
Remember: Follow the above instructions carefully to complete the user's request.`;j={displayText:M,text:a8,images:[],parts:[{type:"text",text:a8}]}}if(!X2){if(!w0.success&&w0.error)return W.addAssistantMessage(`❌ ${w0.error}`),{success:w0.success,output:w0.message,error:w0.error,metadata:w0.data};let p$=w0.message;if(w0.success&&typeof p$==="string"&&p$.trim()!=="")W.addAssistantMessage(p$);return{success:w0.success,output:w0.message,error:w0.error,metadata:w0.data}}}let r=R0.getInstance(),E=j,u,Z0=await r.executeUserPromptSubmitHooks(j.text,{projectDir:process.cwd(),sessionId:q,permissionMode:G,hasImages:j.images.length>0,imageCount:j.images.length});if(!Z0.proceed){if(Z0.warning)W.addAssistantMessage(`⚠️ ${Z0.warning}`);return{success:!1,error:"blocked by hook"}}if(Z0.updatedPrompt)E={...j,text:Z0.updatedPrompt,displayText:Z0.updatedPrompt,parts:[{type:"text",text:Z0.updatedPrompt}]};if(Z0.contextInjection)u=Z0.contextInjection;if(!A)W.addUserMessage(E.displayText);let d=
|
|
2738
|
+
Remember: Follow the above instructions carefully to complete the user's request.`;j={displayText:M,text:a8,images:[],parts:[{type:"text",text:a8}]}}if(!X2){if(!w0.success&&w0.error)return W.addAssistantMessage(`❌ ${w0.error}`),{success:w0.success,output:w0.message,error:w0.error,metadata:w0.data};let p$=w0.message;if(w0.success&&typeof p$==="string"&&p$.trim()!=="")W.addAssistantMessage(p$);return{success:w0.success,output:w0.message,error:w0.error,metadata:w0.data}}}let r=R0.getInstance(),E=j,u,Z0=await r.executeUserPromptSubmitHooks(j.text,{projectDir:process.cwd(),sessionId:q,permissionMode:G,hasImages:j.images.length>0,imageCount:j.images.length});if(!Z0.proceed){if(Z0.warning)W.addAssistantMessage(`⚠️ ${Z0.warning}`);return{success:!1,error:"blocked by hook"}}if(Z0.updatedPrompt)E={...j,text:Z0.updatedPrompt,displayText:Z0.updatedPrompt,parts:[{type:"text",text:Z0.updatedPrompt}]};if(Z0.contextInjection)u=Z0.contextInjection;if(!A)W.addUserMessage(E.displayText);let d=vL(E),s=F.createAbortController(),k=await H();if(s.signal.aborted)return LW.info("[handleCommandSubmit] Agent 创建期间已被中止"),{success:!1,error:"aborted"};let a=J.map((X0)=>({role:X0.role,content:X0.content}));if(u)a.push({role:"system",content:`<user-prompt-submit-hook>
|
|
2739
2739
|
${u}
|
|
2740
|
-
</user-prompt-submit-hook>`});let n={messages:a,userId:"cli-user",sessionId:q,workspaceRoot:process.cwd(),signal:s.signal,confirmationHandler:Y,permissionMode:G},U0=0,M0=0,$$=0,j2={stream:!0,onContentDelta:(X0)=>{U0++,M0+=X0.length,_1("useCommandHandler","onContentDelta",{callCount:U0,deltaLen:X0.length,totalLen:M0}),P(X0)},onThinkingDelta:K?(X0)=>{m(X0)}:void 0,onThinking:K?(X0)=>{W.setCurrentThinkingContent(X0)}:void 0,onStreamEnd:()=>{if(_1("useCommandHandler","onStreamEnd",{contentDeltaCallCount:U0,contentDeltaTotalLen:M0,remainingBuffer:L.current.length}),V.current)clearTimeout(V.current),V.current=null;if(R.current)clearTimeout(R.current),R.current=null;let X0=L.current,s0=D.current;L.current="",D.current="";let w0=J0().session.currentStreamingMessageId;if(w0){if(X0)e7(w0,X0);$9(w0)}W.finalizeStreamingMessage(X0,s0)},onContent:(X0)=>{if($$++,!X0.trim())return;_1("useCommandHandler","onContent (non-stream)",{callCount:$$,contentLen:X0.length}),W.addAssistantMessageAndClearThinking(X0)},onToolStart:(X0)=>{if(X0.type!=="function")return;if(X0.function.name==="TodoWrite")return;try{let s0=JSON.parse(X0.function.arguments),w0=C8(X0.function.name,s0);W.addToolMessage(w0,{toolName:X0.function.name,phase:"start",summary:w0,params:s0})}catch(s0){LW.error("[useCommandHandler] onToolStart error:",s0)}},onToolResult:async(X0,s0)=>{if(X0.type!=="function")return;let w0=s0.metadata?.summary;if(!w0)return;let X2;if(qK(X0.function.name,s0))X2=GK(X0.function.name,s0)||s0.displayContent;W.addToolMessage(w0,{toolName:X0.function.name,phase:"complete",summary:w0,detail:X2})},onTokenUsage:(X0)=>{W.updateTokenUsage(X0)},onCompacting:(X0)=>{if(W.setCompacting(X0),!X0)W.resetTokenUsage()},onTurnLimitReached:Y?async(X0)=>{let s0=await Y.requestConfirmation({type:"maxTurnsExceeded",title:"对话轮次上限",message:`已进行 ${X0.turnsCount} 轮对话。是否继续?`,risks:["继续执行可能导致更长的等待时间","可能产生更多的 API 费用"]});return{continue:s0.approved,reason:s0.reason}}:void 0},E$=await k.chat(d,n,j2);if(!E$||E$.trim()===""){if(!O.current&&U0===0)return W.addAssistantMessage("⏹ 已取消"),{success:!0,output:"已取消"};return{success:!0,output:E$??""}}return{success:!0,output:E$}}catch(r){if(O.current)return{success:!1,error:"aborted"};let E=r instanceof Error?r.message:"未知错误",u=E.includes("can only concatenate str")||E.includes("image_url")||E.includes("multimodal")||E.includes("vision")||E.includes("does not support images"),Z0=E;if(u)Z0="当前模型不支持图片理解功能。请切换到支持视觉能力的模型(如 Claude 4.5、GPT-5.2、Gemini 3 Pro、Qwen3-VL-Plus 等)后重试。";let d={success:!1,error:Z0};return W.addAssistantMessage(`❌ ${Z0}`),d}}),g=r2(async(j)=>{if(!j.text.trim()&&j.images.length===0)return;if(X){F.enqueueCommand({displayText:j.displayText,text:j.text,images:j.images,parts:j.parts});return}U.setTodos([]),O.current=!1;let M=F.createAbortController();e(),W.clearFinalizingStreamingMessageId(),F.setProcessing(!0);try{let A=await T(j);if(!A.success&&A.error&&A.error!=="aborted")W.setError(A.error)}catch(A){if(A instanceof Error&&(A.name==="AbortError"||A.message.includes("aborted")));else{let r=A instanceof Error?A.message:"未知错误";W.setError(`执行失败: ${r}`)}}finally{if(F.getAbortController()===M){F.setProcessing(!1),F.clearAbortController(M),W.setCurrentThinkingContent(null);let E=F.dequeueCommand();if(E)setTimeout(()=>g({displayText:E.displayText,text:E.text,images:E.images,parts:E.parts}),100)}}});return{executeCommand:g,handleAbort:S,isProcessing:X}};import{useMemoizedFn as K7}from"ahooks";import{useState as bW}from"react";var AW=()=>{let[$,Z]=bW([]),[Y,Q]=bW(-1),X=K7((K,W)=>{let U={display:K,pasteMappings:W?new Map(W):new Map};Z((F)=>[...F,U]),Q(-1)}),J=K7(()=>{if($.length===0)return null;let K=Y===-1?$.length-1:Math.max(0,Y-1);return Q(K),$[K]||null}),q=K7(()=>{if(Y===-1)return null;let K=Y+1;if(K>=$.length)return Q(-1),null;else return Q(K),$[K]||null}),G=K7(()=>{Q(-1)});return{commandHistory:$,historyIndex:Y,addToHistory:X,getPreviousCommand:J,getNextCommand:q,resetHistoryIndex:G}};import{useMemoizedFn as vZ}from"ahooks";import{useMemo as vL,useRef as RW,useState as TL}from"react";var VW=()=>{let[$,Z]=TL({isVisible:!1,details:null,resolver:null}),Y=RW(null),Q=RW([]),X=vZ((K)=>{Y.current=K,Z({isVisible:Boolean(K),details:K?.details??null,resolver:K?.resolve??null})}),J=vZ((K)=>{return new Promise((W)=>{let U={details:K,resolve:W};if(!Y.current){X(U);return}Q.current.push(U)})}),q=vZ((K)=>{if(Y.current)Y.current.resolve(K);let W=Q.current.shift()??null;X(W)}),G=vL(()=>({requestConfirmation:J}),[J]);return{confirmationState:$,confirmationHandler:G,handleResponse:q}};import{useMemoizedFn as v4}from"ahooks";import{useRef as DW,useState as EL}from"react";var W7="␞",U7="␟";function F7($){return`${W7}PASTE:${$}:`}function TZ(){return U7}var Px=new RegExp(`${W7}PASTE:(\\d+):[\\s\\S]*?${U7}`,"g");function PL($){return $.includes(W7)&&$.includes(U7)}function MW($="",Z=0){let[Y,Q]=EL({value:$,cursorPosition:Z}),X=DW(0),J=DW(new Map),q=v4((H)=>{Q((_)=>({value:H,cursorPosition:_.cursorPosition}));for(let _ of J.current.keys()){let z=F7(_);if(!H.includes(z))J.current.delete(_)}}),G=v4((H)=>{Q((_)=>({..._,cursorPosition:Math.max(0,Math.min(H,_.value.length))}))}),K=v4(()=>{Q({value:"",cursorPosition:0}),J.current.clear()}),W=v4((H)=>{X.current+=1;let _=X.current;return J.current.set(_,{type:"text",data:H}),_}),U=v4((H,_)=>{X.current+=1;let z=X.current;return J.current.set(z,{type:"image",data:H,mimeType:_}),z}),F=v4((H)=>{for(let[_,z]of H)if(J.current.set(_,z),_>=X.current)X.current=_}),O=v4((H)=>{let _=[],z=[];if(!PL(H)){let P=H.trim();if(P)z.push({type:"text",text:P});return{displayText:H,text:H,images:_,parts:z}}let w=new RegExp(`${W7}PASTE:(\\d+):[\\s\\S]*?${U7}`,"g"),B=Array.from(H.matchAll(w)),L=0,V="",D="";for(let P of B){let m=P.index,e=m+P[0].length,S=parseInt(P[1],10),T=J.current.get(S);if(m>L){let g=H.slice(L,m);z.push({type:"text",text:g}),V+=g,D+=g}if(!T)V+=P[0],D+=P[0],z.push({type:"text",text:P[0]});else if(T.type==="text")V+=T.data,D+=T.data,z.push({type:"text",text:T.data});else{let g={id:S,base64:T.data,mimeType:T.mimeType};_.push(g),z.push({type:"image",...g}),D+=`[Image #${S}]`}L=e}if(L<H.length){let P=H.slice(L);z.push({type:"text",text:P}),V+=P,D+=P}let R=[];for(let P of z)if(P.type==="text"&&R.length>0&&R[R.length-1].type==="text")R[R.length-1].text+=P.text;else R.push(P);let y=0,I=R.length;while(y<R.length&&R[y].type==="text"&&R[y].text.trim()==="")y++;while(I>y&&R[I-1].type==="text"&&R[I-1].text.trim()==="")I--;let N=R.slice(y,I);return{displayText:D.trim(),text:V.trim(),images:_,parts:N}});return{value:Y.value,cursorPosition:Y.cursorPosition,setValue:q,setCursorPosition:G,clear:K,pasteMap:J.current,addPasteMapping:W,addImagePasteMapping:U,restorePasteMappings:F,resolveInput:O}}z0();M3();import{useMemoizedFn as EW}from"ahooks";import{useInput as pL}from"ink";import{useEffect as PW,useRef as CW,useState as SZ}from"react";c6();P6();import CL from"fast-glob";import SL from"fuse.js";import{useEffect as jW,useMemo as EZ,useState as PZ}from"react";var v3=null,kL=5000;function fL($,Z){let Y=[...$.matchAll(/(?:^|\s)(@(?:"[^"]*"|(?:[^\\ ]|\\ )*))/g)];for(let Q of Y){let X=Q[1],J=Q.index+(Q[0].length-X.length),q=J+X.length;if(Z>=J&&Z<=q){let G=X.slice(1),K=!1;if(G.startsWith('"')){if(K=!0,G=G.slice(1),G.endsWith('"'))G=G.slice(0,-1)}return{hasQuery:!0,query:G,startIndex:J,endIndex:q,quoted:K}}}return{hasQuery:!1,query:"",startIndex:-1,endIndex:-1,quoted:!1}}var hL=[...s1.map(($)=>`${$}/**`),...s1,...w5.map(($)=>`**/${$}`)];function IW($,Z,Y={}){let{cwd:Q=process.cwd(),maxSuggestions:X=15,ignorePatterns:J=hL,debounceDelay:q=300,fuzzyMatch:G=!0}=Y,[K,W]=PZ([]),[U,F]=PZ(!1),[O,H]=PZ(0),_=EZ(()=>JSON.stringify(J),[J]),z=EZ(()=>{if(Z===void 0)return{hasQuery:!1,query:"",startIndex:-1,endIndex:-1,quoted:!1};return fL($,Z)},[$,Z]);jW(()=>{if(!$.includes("@")){W([]),F(!1);return}let B=Date.now();if(v3&&v3.cwd===Q&&v3.ignoreKey===_&&B-v3.timestamp<kL){W(v3.files),F(!1);return}let L=!1,D=setTimeout(async()=>{F(!0);try{let y=(await CL("**/*",{cwd:Q,dot:!1,followSymbolicLinks:!1,onlyFiles:!1,markDirectories:!0,unique:!0,ignore:J})).map((I)=>I.replace(/\\/g,"/"));if(!L)W(y),v3={cwd:Q,ignoreKey:_,files:y,timestamp:B}}catch(R){if(console.error("Failed to load files for @ completion:",R),!L)W([])}finally{if(!L)F(!1)}},q);return()=>{L=!0,clearTimeout(D)}},[$,Q,q,_]);let w=EZ(()=>{if(!z.hasQuery||K.length===0)return[];let B=z.query.toLowerCase();if(B==="")return K.slice(0,X);if(G)return new SL(K,{threshold:0.4,ignoreLocation:!0,minMatchCharLength:1}).search(B).slice(0,X).map((D)=>D.item);return K.filter((L)=>L.toLowerCase().includes(B)).slice(0,X)},[z,K,X,G]);return jW(()=>{H(0)},[w]),{...z,suggestions:w,selectedIndex:O,loading:U}}function xL($,Z=!1){if($.includes(" ")||Z)return`@"${$}"`;return`@${$}`}function CZ($,Z,Y){if(!Z.hasQuery)return{newInput:$,newCursorPos:$.length};let Q=xL(Y,Z.quoted),X=$.slice(0,Z.startIndex),J=$.slice(Z.endIndex),q=X+Q+" "+J,G=Z.startIndex+Q.length+1;return{newInput:q,newCursorPos:G}}import{useMemoizedFn as yW}from"ahooks";import{useEffect as vW,useRef as TW}from"react";T0();var Z$=($,Z)=>{let Y=TW(!1),Q=TW(null),X=yW(()=>{if(Q.current)clearTimeout(Q.current);Q.current=setTimeout(()=>{K2().setAwaitingSecondCtrlC(!1),Y.current=!1,Q.current=null},3000)}),J=()=>{y4().shutdown("SIGINT",0)},q=yW(()=>{if(!Y.current){if(Y.current=!0,$&&Z)Z();K2().setAwaitingSecondCtrlC(!0),X()}else{if(Q.current)clearTimeout(Q.current),Q.current=null;K2().setAwaitingSecondCtrlC(!1),J()}});return vW(()=>{if($){if(K2().setAwaitingSecondCtrlC(!1),Y.current=!1,Q.current)clearTimeout(Q.current),Q.current=null}},[$]),vW(()=>{return()=>{if(Q.current)clearTimeout(Q.current)}},[]),q};var O7=l("UI"),SW=($,Z,Y,Q,X,J,q,G,K,W)=>{let F=Z1()==="main-input",O=$.value,H=$.setValue,_=$.cursorPosition,z=l2(),w=i2(),B=q7(),L=B?B3(B):!1,[V,D]=SZ(!1),[R,y]=SZ([]),[I,N]=SZ(0),P=IW(O,_,{cwd:process.cwd(),maxSuggestions:10}),m=Z$(q||!1,J),e=CW(0),S=500,T=CW(!1);PW(()=>{if(q)T.current=!1},[q]),PW(()=>{if(P.hasQuery&&P.suggestions.length>0){let M=P.suggestions.map((A)=>({command:A,description:kX(A)?`Directory: ${A}`:`File: ${A}`,matchScore:1}));y(M),D(!0),N(0)}else if(O.startsWith("/"))if(O.includes(" "))D(!1),y([]);else{let A=TK(O);y(A),D(A.length>0),N(0)}else D(!1),y([])},[O,P.hasQuery,P.suggestions]);let g=EW(()=>{z.clearMessages(),z.setError(null)}),j=EW(()=>{O7.debug("[DIAG] handleSubmit called:",{input:O,showSuggestions:V});let M=O.trim();if(M){let A=$.resolveInput(M);O7.debug("[DIAG] Submitting command:",{displayText:M,textLength:A.text.length,imageCount:A.images.length}),D(!1),y([]);let r=$.pasteMap.size>0?new Map($.pasteMap):new Map;X(M,r),$.clear(),Z(A),O7.debug("[DIAG] Command submitted to onSubmit callback")}else O7.debug("[DIAG] Empty command, not submitting")});return pL((M,A)=>{if(M==="?"&&!O){K?.(),setTimeout(()=>$.clear(),0);return}if(A.backspace||A.delete||A.leftArrow||A.rightArrow||A.pageUp||A.pageDown||!A.ctrl&&!A.meta&&!A.escape&&!A.tab&&!A.upArrow&&!A.downArrow&&!A.return&&!(M==="?"&&!O))return;if(A.ctrl&&M==="c"||A.meta&&M==="c"||A.ctrl&&M==="d"||A.meta&&M==="d"){m();return}if(A.ctrl&&M==="l"||A.meta&&M==="l"){g();return}if(A.ctrl&&M==="t"||A.meta&&M==="t"){z.toggleThinkingExpanded();return}if(A.ctrl&&M==="o"||A.meta&&M==="o"){z.toggleHistoryExpanded();return}if(A.escape){if(W)K?.();else if(q&&J){if(T.current)return;T.current=!0,J()}else if(V)D(!1),y([]);else if(O){let E=Date.now();if(E-e.current<500)$.clear(),e.current=0;else e.current=E}return}if(A.tab&&A.shift){G?.();return}if(A.tab){if(V&&R.length>0){let E=R[I].command;if(P.hasQuery&&P.suggestions.includes(E)){let{newInput:u,newCursorPos:Z0}=CZ(O,P,E);H(u),$.setCursorPosition(Z0)}else{let u=E+" ";H(u),$.setCursorPosition(u.length)}D(!1),y([])}else if(L)w.toggleThinkingMode();return}if(A.return){if(V&&R.length>0){let E=R[I].command;if(P.hasQuery&&P.suggestions.includes(E)){let{newInput:u,newCursorPos:Z0}=CZ(O,P,E);H(u),$.setCursorPosition(Z0)}else{let u=E+" ";H(u),$.setCursorPosition(u.length)}D(!1),y([])}else j();return}if(A.upArrow){if(V&&R.length>0){let E=R.length-1;N((u)=>u>0?u-1:E)}else{let E=Y();if(E){if(E.pasteMappings.size>0)$.restorePasteMappings(E.pasteMappings);H(E.display),$.setCursorPosition(E.display.length)}}return}if(A.downArrow){if(V&&R.length>0){let E=R.length-1;N((u)=>u<E?u+1:0)}else{let E=Q();if(E){if(E.pasteMappings.size>0)$.restorePasteMappings(E.pasteMappings);H(E.display),$.setCursorPosition(E.display.length)}}return}},{isActive:F}),{handleSubmit:j,showSuggestions:V,suggestions:R,selectedSuggestionIndex:I}};import cL from"ansi-escapes";import{useStdout as lL}from"ink";import{useCallback as iL,useEffect as aL,useRef as rL}from"react";import{useStdout as mL}from"ink";import{debounce as gL}from"lodash-es";import{useEffect as uL,useState as dL}from"react";function T3($=200){let{stdout:Z}=mL(),[Y,Q]=dL(Z.columns||80);return uL(()=>{let X=gL(()=>{Q(Z.columns||80)},$);return X(),Z.on("resize",X),()=>{Z.off("resize",X),X.cancel()}},[Z,$]),Y}function kW(){let{stdout:$}=lL(),Z=T3(),Y=rL(!0),Q=B0((J)=>J.session.actions.incrementClearCount),X=iL(()=>{if($)$.write(cL.clearTerminal);Q()},[$,Q]);return aL(()=>{if(Y.current){Y.current=!1;return}let J=setTimeout(()=>{X()},300);return()=>{clearTimeout(J)}},[Z,X]),{refreshStatic:X}}O2();import fW from"node:fs";import nL from"node:os";import kZ from"node:path";import{MultiSelect as oL}from"@inkjs/ui";import{useMemoizedFn as H7}from"ahooks";import{Box as q0,Text as $0,useFocus as sL,useFocusManager as tL,useInput as xW}from"ink";import _7 from"ink-select-input";import eL from"ink-spinner";import h8 from"ink-text-input";import{useEffect as hW,useState as E3}from"react";import{jsxDEV as C}from"react/jsx-dev-runtime";var $N=[{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"}],ZN=[{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 YN($){if(!$||$.trim()==="")return"名称不能为空";if(!/^[a-z0-9-]+$/.test($))return"名称只能包含小写字母、数字和连字符";if($.startsWith("-")||$.endsWith("-"))return"名称不能以连字符开头或结尾";return null}function x8({onComplete:$,onCancel:Z,initialConfig:Y}){let[Q,X]=E3(Y?"name":"mode"),[J,q]=E3({name:Y?.name||"",description:Y?.description||"",tools:Y?.tools||[],color:Y?.color,location:Y?.location||"project",systemPrompt:Y?.systemPrompt||""}),[G,K]=E3(""),[W,U]=E3(!1),[F,O]=E3(""),[H,_]=E3(Y?"edit":"manual"),{focus:z}=tL(),B={manual:["mode","name","description","tools","color","location","systemPrompt","confirm"],ai:["mode","aiPrompt","aiGenerating","confirm"],edit:["name","description","tools","color","location","systemPrompt","confirm"]}[H];hW(()=>{if(Q==="name"||Q==="description"||Q==="systemPrompt"||Q==="aiPrompt")return;z(`step-${Q}`)},[Q,z]);let L=H7(()=>{let I=B.indexOf(Q);if(I<B.length-1)X(B[I+1])}),V=H7(()=>{if(F)O("");if(Q==="confirm"&&H==="ai"){X("aiPrompt");return}let I=B.indexOf(Q);if(I>0)X(B[I-1]);else Z()}),D=H7(async()=>{U(!0),O("");try{let I=await U$.create(),N=`你是一个 Subagent 配置生成专家。用户会描述他们想要创建的 agent,你需要根据描述生成一个完整的 agent 配置。
|
|
2740
|
+
</user-prompt-submit-hook>`});let n={messages:a,userId:"cli-user",sessionId:q,workspaceRoot:process.cwd(),signal:s.signal,confirmationHandler:Y,permissionMode:G},U0=0,M0=0,$$=0,j2={stream:!0,onContentDelta:(X0)=>{U0++,M0+=X0.length,_1("useCommandHandler","onContentDelta",{callCount:U0,deltaLen:X0.length,totalLen:M0}),P(X0)},onThinkingDelta:K?(X0)=>{m(X0)}:void 0,onThinking:K?(X0)=>{W.setCurrentThinkingContent(X0)}:void 0,onStreamEnd:()=>{if(_1("useCommandHandler","onStreamEnd",{contentDeltaCallCount:U0,contentDeltaTotalLen:M0,remainingBuffer:L.current.length}),V.current)clearTimeout(V.current),V.current=null;if(R.current)clearTimeout(R.current),R.current=null;let X0=L.current,s0=D.current;L.current="",D.current="";let w0=J0().session.currentStreamingMessageId;if(w0){if(X0)e7(w0,X0);$9(w0)}W.finalizeStreamingMessage(X0,s0)},onContent:(X0)=>{if($$++,!X0.trim())return;_1("useCommandHandler","onContent (non-stream)",{callCount:$$,contentLen:X0.length}),W.addAssistantMessageAndClearThinking(X0)},onToolStart:(X0)=>{if(X0.type!=="function")return;if(X0.function.name==="TodoWrite")return;try{let s0=JSON.parse(X0.function.arguments),w0=C8(X0.function.name,s0);W.addToolMessage(w0,{toolName:X0.function.name,phase:"start",summary:w0,params:s0})}catch(s0){LW.error("[useCommandHandler] onToolStart error:",s0)}},onToolResult:async(X0,s0)=>{if(X0.type!=="function")return;let w0=s0.metadata?.summary;if(!w0)return;let X2;if(qK(X0.function.name,s0))X2=GK(X0.function.name,s0)||s0.displayContent;W.addToolMessage(w0,{toolName:X0.function.name,phase:"complete",summary:w0,detail:X2})},onTokenUsage:(X0)=>{W.updateTokenUsage(X0)},onCompacting:(X0)=>{if(W.setCompacting(X0),!X0)W.resetTokenUsage()},onTurnLimitReached:Y?async(X0)=>{let s0=await Y.requestConfirmation({type:"maxTurnsExceeded",title:"对话轮次上限",message:`已进行 ${X0.turnsCount} 轮对话。是否继续?`,risks:["继续执行可能导致更长的等待时间","可能产生更多的 API 费用"]});return{continue:s0.approved,reason:s0.reason}}:void 0},E$=await k.chat(d,n,j2);if(!E$||E$.trim()===""){if(!O.current&&U0===0)return W.addAssistantMessage("⏹ 已取消"),{success:!0,output:"已取消"};return{success:!0,output:E$??""}}return{success:!0,output:E$}}catch(r){if(O.current)return{success:!1,error:"aborted"};let E=r instanceof Error?r.message:"未知错误",u=E.includes("can only concatenate str")||E.includes("image_url")||E.includes("multimodal")||E.includes("vision")||E.includes("does not support images"),Z0=E;if(u)Z0="当前模型不支持图片理解功能。请切换到支持视觉能力的模型(如 Claude 4.5、GPT-5.2、Gemini 3 Pro、Qwen3-VL-Plus 等)后重试。";let d={success:!1,error:Z0};return W.addAssistantMessage(`❌ ${Z0}`),d}}),g=r2(async(j)=>{if(!j.text.trim()&&j.images.length===0)return;if(X){F.enqueueCommand({displayText:j.displayText,text:j.text,images:j.images,parts:j.parts});return}U.setTodos([]),O.current=!1;let M=F.createAbortController();e(),W.clearFinalizingStreamingMessageId(),F.setProcessing(!0);try{let A=await T(j);if(!A.success&&A.error&&A.error!=="aborted")W.setError(A.error)}catch(A){if(A instanceof Error&&(A.name==="AbortError"||A.message.includes("aborted")));else{let r=A instanceof Error?A.message:"未知错误";W.setError(`执行失败: ${r}`)}}finally{if(F.getAbortController()===M){F.setProcessing(!1),F.clearAbortController(M),W.setCurrentThinkingContent(null);let E=F.dequeueCommand();if(E)setTimeout(()=>g({displayText:E.displayText,text:E.text,images:E.images,parts:E.parts}),100)}}});return{executeCommand:g,handleAbort:S,isProcessing:X}};import{useMemoizedFn as K7}from"ahooks";import{useState as bW}from"react";var AW=()=>{let[$,Z]=bW([]),[Y,Q]=bW(-1),X=K7((K,W)=>{let U={display:K,pasteMappings:W?new Map(W):new Map};Z((F)=>[...F,U]),Q(-1)}),J=K7(()=>{if($.length===0)return null;let K=Y===-1?$.length-1:Math.max(0,Y-1);return Q(K),$[K]||null}),q=K7(()=>{if(Y===-1)return null;let K=Y+1;if(K>=$.length)return Q(-1),null;else return Q(K),$[K]||null}),G=K7(()=>{Q(-1)});return{commandHistory:$,historyIndex:Y,addToHistory:X,getPreviousCommand:J,getNextCommand:q,resetHistoryIndex:G}};import{useMemoizedFn as vZ}from"ahooks";import{useMemo as TL,useRef as RW,useState as EL}from"react";var VW=()=>{let[$,Z]=EL({isVisible:!1,details:null,resolver:null}),Y=RW(null),Q=RW([]),X=vZ((K)=>{Y.current=K,Z({isVisible:Boolean(K),details:K?.details??null,resolver:K?.resolve??null})}),J=vZ((K)=>{return new Promise((W)=>{let U={details:K,resolve:W};if(!Y.current){X(U);return}Q.current.push(U)})}),q=vZ((K)=>{if(Y.current)Y.current.resolve(K);let W=Q.current.shift()??null;X(W)}),G=TL(()=>({requestConfirmation:J}),[J]);return{confirmationState:$,confirmationHandler:G,handleResponse:q}};import{useMemoizedFn as v4}from"ahooks";import{useRef as DW,useState as PL}from"react";var W7="␞",U7="␟";function F7($){return`${W7}PASTE:${$}:`}function TZ(){return U7}var Cx=new RegExp(`${W7}PASTE:(\\d+):[\\s\\S]*?${U7}`,"g");function CL($){return $.includes(W7)&&$.includes(U7)}function MW($="",Z=0){let[Y,Q]=PL({value:$,cursorPosition:Z}),X=DW(0),J=DW(new Map),q=v4((H)=>{Q((_)=>({value:H,cursorPosition:_.cursorPosition}));for(let _ of J.current.keys()){let z=F7(_);if(!H.includes(z))J.current.delete(_)}}),G=v4((H)=>{Q((_)=>({..._,cursorPosition:Math.max(0,Math.min(H,_.value.length))}))}),K=v4(()=>{Q({value:"",cursorPosition:0}),J.current.clear()}),W=v4((H)=>{X.current+=1;let _=X.current;return J.current.set(_,{type:"text",data:H}),_}),U=v4((H,_)=>{X.current+=1;let z=X.current;return J.current.set(z,{type:"image",data:H,mimeType:_}),z}),F=v4((H)=>{for(let[_,z]of H)if(J.current.set(_,z),_>=X.current)X.current=_}),O=v4((H)=>{let _=[],z=[];if(!CL(H)){let P=H.trim();if(P)z.push({type:"text",text:P});return{displayText:H,text:H,images:_,parts:z}}let w=new RegExp(`${W7}PASTE:(\\d+):[\\s\\S]*?${U7}`,"g"),B=Array.from(H.matchAll(w)),L=0,V="",D="";for(let P of B){let m=P.index,e=m+P[0].length,S=parseInt(P[1],10),T=J.current.get(S);if(m>L){let g=H.slice(L,m);z.push({type:"text",text:g}),V+=g,D+=g}if(!T)V+=P[0],D+=P[0],z.push({type:"text",text:P[0]});else if(T.type==="text")V+=T.data,D+=T.data,z.push({type:"text",text:T.data});else{let g={id:S,base64:T.data,mimeType:T.mimeType};_.push(g),z.push({type:"image",...g}),D+=`[Image #${S}]`}L=e}if(L<H.length){let P=H.slice(L);z.push({type:"text",text:P}),V+=P,D+=P}let R=[];for(let P of z)if(P.type==="text"&&R.length>0&&R[R.length-1].type==="text")R[R.length-1].text+=P.text;else R.push(P);let y=0,I=R.length;while(y<R.length&&R[y].type==="text"&&R[y].text.trim()==="")y++;while(I>y&&R[I-1].type==="text"&&R[I-1].text.trim()==="")I--;let N=R.slice(y,I);return{displayText:D.trim(),text:V.trim(),images:_,parts:N}});return{value:Y.value,cursorPosition:Y.cursorPosition,setValue:q,setCursorPosition:G,clear:K,pasteMap:J.current,addPasteMapping:W,addImagePasteMapping:U,restorePasteMappings:F,resolveInput:O}}z0();M3();import{useMemoizedFn as EW}from"ahooks";import{useInput as mL}from"ink";import{useEffect as PW,useRef as CW,useState as SZ}from"react";c6();P6();import SL from"fast-glob";import kL from"fuse.js";import{useEffect as jW,useMemo as EZ,useState as PZ}from"react";var v3=null,fL=5000;function hL($,Z){let Y=[...$.matchAll(/(?:^|\s)(@(?:"[^"]*"|(?:[^\\ ]|\\ )*))/g)];for(let Q of Y){let X=Q[1],J=Q.index+(Q[0].length-X.length),q=J+X.length;if(Z>=J&&Z<=q){let G=X.slice(1),K=!1;if(G.startsWith('"')){if(K=!0,G=G.slice(1),G.endsWith('"'))G=G.slice(0,-1)}return{hasQuery:!0,query:G,startIndex:J,endIndex:q,quoted:K}}}return{hasQuery:!1,query:"",startIndex:-1,endIndex:-1,quoted:!1}}var xL=[...s1.map(($)=>`${$}/**`),...s1,...w5.map(($)=>`**/${$}`)];function IW($,Z,Y={}){let{cwd:Q=process.cwd(),maxSuggestions:X=15,ignorePatterns:J=xL,debounceDelay:q=300,fuzzyMatch:G=!0}=Y,[K,W]=PZ([]),[U,F]=PZ(!1),[O,H]=PZ(0),_=EZ(()=>JSON.stringify(J),[J]),z=EZ(()=>{if(Z===void 0)return{hasQuery:!1,query:"",startIndex:-1,endIndex:-1,quoted:!1};return hL($,Z)},[$,Z]);jW(()=>{if(!$.includes("@")){W([]),F(!1);return}let B=Date.now();if(v3&&v3.cwd===Q&&v3.ignoreKey===_&&B-v3.timestamp<fL){W(v3.files),F(!1);return}let L=!1,D=setTimeout(async()=>{F(!0);try{let y=(await SL("**/*",{cwd:Q,dot:!1,followSymbolicLinks:!1,onlyFiles:!1,markDirectories:!0,unique:!0,ignore:J})).map((I)=>I.replace(/\\/g,"/"));if(!L)W(y),v3={cwd:Q,ignoreKey:_,files:y,timestamp:B}}catch(R){if(console.error("Failed to load files for @ completion:",R),!L)W([])}finally{if(!L)F(!1)}},q);return()=>{L=!0,clearTimeout(D)}},[$,Q,q,_]);let w=EZ(()=>{if(!z.hasQuery||K.length===0)return[];let B=z.query.toLowerCase();if(B==="")return K.slice(0,X);if(G)return new kL(K,{threshold:0.4,ignoreLocation:!0,minMatchCharLength:1}).search(B).slice(0,X).map((D)=>D.item);return K.filter((L)=>L.toLowerCase().includes(B)).slice(0,X)},[z,K,X,G]);return jW(()=>{H(0)},[w]),{...z,suggestions:w,selectedIndex:O,loading:U}}function pL($,Z=!1){if($.includes(" ")||Z)return`@"${$}"`;return`@${$}`}function CZ($,Z,Y){if(!Z.hasQuery)return{newInput:$,newCursorPos:$.length};let Q=pL(Y,Z.quoted),X=$.slice(0,Z.startIndex),J=$.slice(Z.endIndex),q=X+Q+" "+J,G=Z.startIndex+Q.length+1;return{newInput:q,newCursorPos:G}}import{useMemoizedFn as yW}from"ahooks";import{useEffect as vW,useRef as TW}from"react";T0();var Y$=($,Z)=>{let Y=TW(!1),Q=TW(null),X=yW(()=>{if(Q.current)clearTimeout(Q.current);Q.current=setTimeout(()=>{K2().setAwaitingSecondCtrlC(!1),Y.current=!1,Q.current=null},3000)}),J=()=>{y4().shutdown("SIGINT",0)},q=yW(()=>{if(!Y.current){if(Y.current=!0,$&&Z)Z();K2().setAwaitingSecondCtrlC(!0),X()}else{if(Q.current)clearTimeout(Q.current),Q.current=null;K2().setAwaitingSecondCtrlC(!1),J()}});return vW(()=>{if($){if(K2().setAwaitingSecondCtrlC(!1),Y.current=!1,Q.current)clearTimeout(Q.current),Q.current=null}},[$]),vW(()=>{return()=>{if(Q.current)clearTimeout(Q.current)}},[]),q};var O7=l("UI"),SW=($,Z,Y,Q,X,J,q,G,K,W)=>{let F=Z1()==="main-input",O=$.value,H=$.setValue,_=$.cursorPosition,z=l2(),w=i2(),B=q7(),L=B?B3(B):!1,[V,D]=SZ(!1),[R,y]=SZ([]),[I,N]=SZ(0),P=IW(O,_,{cwd:process.cwd(),maxSuggestions:10}),m=Y$(q||!1,J),e=CW(0),S=500,T=CW(!1);PW(()=>{if(q)T.current=!1},[q]),PW(()=>{if(P.hasQuery&&P.suggestions.length>0){let M=P.suggestions.map((A)=>({command:A,description:kX(A)?`Directory: ${A}`:`File: ${A}`,matchScore:1}));y(M),D(!0),N(0)}else if(O.startsWith("/"))if(O.includes(" "))D(!1),y([]);else{let A=TK(O);y(A),D(A.length>0),N(0)}else D(!1),y([])},[O,P.hasQuery,P.suggestions]);let g=EW(()=>{z.clearMessages(),z.setError(null)}),j=EW(()=>{O7.debug("[DIAG] handleSubmit called:",{input:O,showSuggestions:V});let M=O.trim();if(M){let A=$.resolveInput(M);O7.debug("[DIAG] Submitting command:",{displayText:M,textLength:A.text.length,imageCount:A.images.length}),D(!1),y([]);let r=$.pasteMap.size>0?new Map($.pasteMap):new Map;X(M,r),$.clear(),Z(A),O7.debug("[DIAG] Command submitted to onSubmit callback")}else O7.debug("[DIAG] Empty command, not submitting")});return mL((M,A)=>{if(M==="?"&&!O){K?.(),setTimeout(()=>$.clear(),0);return}if(A.backspace||A.delete||A.leftArrow||A.rightArrow||A.pageUp||A.pageDown||!A.ctrl&&!A.meta&&!A.escape&&!A.tab&&!A.upArrow&&!A.downArrow&&!A.return&&!(M==="?"&&!O))return;if(A.ctrl&&M==="c"||A.meta&&M==="c"||A.ctrl&&M==="d"||A.meta&&M==="d"){m();return}if(A.ctrl&&M==="l"||A.meta&&M==="l"){g();return}if(A.ctrl&&M==="t"||A.meta&&M==="t"){z.toggleThinkingExpanded();return}if(A.ctrl&&M==="o"||A.meta&&M==="o"){z.toggleHistoryExpanded();return}if(A.escape){if(W)K?.();else if(q&&J){if(T.current)return;T.current=!0,J()}else if(V)D(!1),y([]);else if(O){let E=Date.now();if(E-e.current<500)$.clear(),e.current=0;else e.current=E}return}if(A.tab&&A.shift){G?.();return}if(A.tab){if(V&&R.length>0){let E=R[I].command;if(P.hasQuery&&P.suggestions.includes(E)){let{newInput:u,newCursorPos:Z0}=CZ(O,P,E);H(u),$.setCursorPosition(Z0)}else{let u=E+" ";H(u),$.setCursorPosition(u.length)}D(!1),y([])}else if(L)w.toggleThinkingMode();return}if(A.return){if(V&&R.length>0){let E=R[I].command;if(P.hasQuery&&P.suggestions.includes(E)){let{newInput:u,newCursorPos:Z0}=CZ(O,P,E);H(u),$.setCursorPosition(Z0)}else{let u=E+" ";H(u),$.setCursorPosition(u.length)}D(!1),y([])}else j();return}if(A.upArrow){if(V&&R.length>0){let E=R.length-1;N((u)=>u>0?u-1:E)}else{let E=Y();if(E){if(E.pasteMappings.size>0)$.restorePasteMappings(E.pasteMappings);H(E.display),$.setCursorPosition(E.display.length)}}return}if(A.downArrow){if(V&&R.length>0){let E=R.length-1;N((u)=>u<E?u+1:0)}else{let E=Q();if(E){if(E.pasteMappings.size>0)$.restorePasteMappings(E.pasteMappings);H(E.display),$.setCursorPosition(E.display.length)}}return}},{isActive:F}),{handleSubmit:j,showSuggestions:V,suggestions:R,selectedSuggestionIndex:I}};import lL from"ansi-escapes";import{useStdout as iL}from"ink";import{useCallback as aL,useEffect as rL,useRef as nL}from"react";import{useStdout as gL}from"ink";import{debounce as uL}from"lodash-es";import{useEffect as dL,useState as cL}from"react";function T3($=200){let{stdout:Z}=gL(),[Y,Q]=cL(Z.columns||80);return dL(()=>{let X=uL(()=>{Q(Z.columns||80)},$);return X(),Z.on("resize",X),()=>{Z.off("resize",X),X.cancel()}},[Z,$]),Y}function kW(){let{stdout:$}=iL(),Z=T3(),Y=nL(!0),Q=B0((J)=>J.session.actions.incrementClearCount),X=aL(()=>{if($)$.write(lL.clearTerminal);Q()},[$,Q]);return rL(()=>{if(Y.current){Y.current=!1;return}let J=setTimeout(()=>{X()},300);return()=>{clearTimeout(J)}},[Z,X]),{refreshStatic:X}}O2();import fW from"node:fs";import oL from"node:os";import kZ from"node:path";import{MultiSelect as sL}from"@inkjs/ui";import{useMemoizedFn as H7}from"ahooks";import{Box as q0,Text as $0,useFocus as tL,useFocusManager as eL,useInput as xW}from"ink";import _7 from"ink-select-input";import $N from"ink-spinner";import h8 from"ink-text-input";import{useEffect as hW,useState as E3}from"react";import{jsxDEV as C}from"react/jsx-dev-runtime";var ZN=[{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"}],YN=[{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 QN($){if(!$||$.trim()==="")return"名称不能为空";if(!/^[a-z0-9-]+$/.test($))return"名称只能包含小写字母、数字和连字符";if($.startsWith("-")||$.endsWith("-"))return"名称不能以连字符开头或结尾";return null}function x8({onComplete:$,onCancel:Z,initialConfig:Y}){let[Q,X]=E3(Y?"name":"mode"),[J,q]=E3({name:Y?.name||"",description:Y?.description||"",tools:Y?.tools||[],color:Y?.color,location:Y?.location||"project",systemPrompt:Y?.systemPrompt||""}),[G,K]=E3(""),[W,U]=E3(!1),[F,O]=E3(""),[H,_]=E3(Y?"edit":"manual"),{focus:z}=eL(),B={manual:["mode","name","description","tools","color","location","systemPrompt","confirm"],ai:["mode","aiPrompt","aiGenerating","confirm"],edit:["name","description","tools","color","location","systemPrompt","confirm"]}[H];hW(()=>{if(Q==="name"||Q==="description"||Q==="systemPrompt"||Q==="aiPrompt")return;z(`step-${Q}`)},[Q,z]);let L=H7(()=>{let I=B.indexOf(Q);if(I<B.length-1)X(B[I+1])}),V=H7(()=>{if(F)O("");if(Q==="confirm"&&H==="ai"){X("aiPrompt");return}let I=B.indexOf(Q);if(I>0)X(B[I-1]);else Z()}),D=H7(async()=>{U(!0),O("");try{let I=await U$.create(),N=`你是一个 Subagent 配置生成专家。用户会描述他们想要创建的 agent,你需要根据描述生成一个完整的 agent 配置。
|
|
2741
2741
|
|
|
2742
2742
|
## 可用工具列表
|
|
2743
2743
|
|
|
@@ -2811,35 +2811,35 @@ ${u}
|
|
|
2811
2811
|
4. **color**: 选择一个合适的颜色用于 UI 区分
|
|
2812
2812
|
5. **systemPrompt**: 详细说明 agent 的职责、使用的工具、输出格式等,使用 Markdown 格式
|
|
2813
2813
|
|
|
2814
|
-
**重要**:请直接返回 JSON,不要添加任何额外的解释或文字。`,G)).trim(),e=m.match(/```(?:json)?\s*\n([\s\S]*?)\n```/);if(e)m=e[1];let S=JSON.parse(m);if(!S.name||!S.description||!S.systemPrompt)throw Error("Missing required fields: name, description, or systemPrompt");if(!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(S.name))throw Error("Invalid name format. Must be kebab-case (lowercase, numbers, hyphens only)");q({name:S.name,description:S.description,tools:Array.isArray(S.tools)?S.tools:[],color:S.color||"blue",location:"project",systemPrompt:S.systemPrompt}),X("confirm")}catch(I){O(I instanceof Error?I.message:String(I))}finally{U(!1)}});hW(()=>{if(Q==="aiGenerating"&&!W&&!F)D()},[Q,W,F,D]);let R=H7(async()=>{try{let I=J.location==="project"?kZ.join(process.cwd(),".blade","agents"):kZ.join(
|
|
2814
|
+
**重要**:请直接返回 JSON,不要添加任何额外的解释或文字。`,G)).trim(),e=m.match(/```(?:json)?\s*\n([\s\S]*?)\n```/);if(e)m=e[1];let S=JSON.parse(m);if(!S.name||!S.description||!S.systemPrompt)throw Error("Missing required fields: name, description, or systemPrompt");if(!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(S.name))throw Error("Invalid name format. Must be kebab-case (lowercase, numbers, hyphens only)");q({name:S.name,description:S.description,tools:Array.isArray(S.tools)?S.tools:[],color:S.color||"blue",location:"project",systemPrompt:S.systemPrompt}),X("confirm")}catch(I){O(I instanceof Error?I.message:String(I))}finally{U(!1)}});hW(()=>{if(Q==="aiGenerating"&&!W&&!F)D()},[Q,W,F,D]);let R=H7(async()=>{try{let I=J.location==="project"?kZ.join(process.cwd(),".blade","agents"):kZ.join(oL.homedir(),".blade","agents");await fW.promises.mkdir(I,{recursive:!0});let N=["---",`name: ${J.name}`,`description: ${J.description}`];if(J.tools.length>0&&!J.tools.includes("all")){N.push("tools:");for(let e of J.tools)N.push(` - ${e}`)}if(J.color)N.push(`color: ${J.color}`);N.push("---");let P=[N.join(`
|
|
2815
2815
|
`),"",`# ${J.name} Subagent`,"",J.systemPrompt||"你是一个专门的代理,负责执行特定任务。",""].join(`
|
|
2816
|
-
`),m=kZ.join(I,`${J.name}.md`);await fW.promises.writeFile(m,P,"utf-8"),$()}catch(I){console.error("保存配置失败:",I)}}),y=Z$(!1,Z);if(xW((I,N)=>{if(N.escape)V();else if(N.ctrl&&I==="c"||N.meta&&I==="c")y()},{isActive:Q!=="tools"}),Q==="mode")return C(q0,{flexDirection:"column",paddingY:1,children:[C(q0,{marginBottom:1,children:C($0,{bold:!0,color:"cyan",children:"\uD83C\uDFAF 选择创建方式"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{dimColor:!0,children:"你可以手动配置每个细节,或让 AI 根据你的描述自动生成配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(_7,{items:[{label:"\uD83E\uDD16 AI 智能生成 - 根据描述自动生成完整配置",value:"ai"},{label:"✍️ 手动配置 - 逐步配置每个选项",value:"manual"}],onSelect:(I)=>{if(I.value==="ai")_("ai"),X("aiPrompt");else _("manual"),X("name")}},void 0,!1,void 0,this),C(q0,{marginTop:1,children:C($0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 取消"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="aiPrompt")return C(q0,{flexDirection:"column",paddingY:1,children:[C(q0,{marginBottom:1,children:C($0,{bold:!0,color:"cyan",children:"\uD83E\uDD16 AI 智能生成"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{dimColor:!0,children:'描述你想要创建的 Agent(例如:"一个专门用于代码审查的 agent,能够分析代码质量和潜在bug")'},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:[C($0,{color:"green",children:"描述: "},void 0,!1,void 0,this),C(h8,{value:G,onChange:K,onSubmit:(I)=>{if(!I.trim())return;X("aiGenerating")}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C(q0,{children:C($0,{dimColor:!0,children:"按 Enter 开始生成 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="aiGenerating"){if(F)return C(q0,{flexDirection:"column",paddingY:1,children:[C(q0,{marginBottom:1,children:C($0,{bold:!0,color:"red",children:"❌ AI 生成失败"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{color:"red",children:F},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{dimColor:!0,children:"按 ESC 返回修改描述"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return C(q0,{flexDirection:"column",paddingY:1,children:[C(q0,{marginBottom:1,children:C($0,{bold:!0,color:"yellow",children:[C(eL,{type:"dots"},void 0,!1,void 0,this)," AI 正在生成配置..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{dimColor:!0,children:['根据你的描述:"',G,'"']},void 0,!0,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{color:"gray",children:"正在调用 LLM 生成 agent 配置,请稍候..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}if(Q==="name"){let I=H==="edit";return C(q0,{flexDirection:"column",paddingY:1,children:[C(q0,{marginBottom:1,children:C($0,{bold:!0,color:"cyan",children:["\uD83D\uDCDD Step 1/7: ",I?"Agent 名称(不可修改)":"输入 Agent 名称"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{dimColor:!0,children:I?"编辑模式下名称不可修改(修改名称相当于创建新 Agent)":"名称只能包含小写字母、数字和连字符(例如:code-reviewer)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:[C($0,{color:"green",children:"名称: "},void 0,!1,void 0,this),I?C($0,{children:J.name},void 0,!1,void 0,this):C(h8,{value:J.name,onChange:(N)=>q({...J,name:N}),onSubmit:(N)=>{if(YN(N))return;L()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C(q0,{children:C($0,{dimColor:!0,children:I?"按 Enter 继续 | ESC 返回":"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this),I&&C(h8,{value:"",onChange:()=>{},onSubmit:L,showCursor:!1},"edit-mode-dummy-input",!1,void 0,this)]},void 0,!0,void 0,this)}if(Q==="description")return C(q0,{flexDirection:"column",paddingY:1,children:[C(q0,{marginBottom:1,children:C($0,{bold:!0,color:"cyan",children:"\uD83D\uDCDD Step 2/7: 输入描述信息"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{dimColor:!0,children:"简短描述这个 Agent 的用途和使用场景(这将帮助主 Agent 决定何时使用它)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:[C($0,{color:"green",children:"描述: "},void 0,!1,void 0,this),C(h8,{value:J.description,onChange:(I)=>q({...J,description:I}),onSubmit:(I)=>{if(!I.trim())return;L()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C(q0,{children:C($0,{dimColor:!0,children:"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="tools")return C(QN,{config:J,setConfig:q,onNext:L,onPrev:V},void 0,!1,void 0,this);if(Q==="color")return C(q0,{flexDirection:"column",paddingY:1,children:[C(q0,{marginBottom:1,children:C($0,{bold:!0,color:"cyan",children:"\uD83C\uDFA8 Step 4/7: 选择背景颜色"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{dimColor:!0,children:"为 Agent 选择一个颜色标识(用于在 UI 中区分不同的 Agents)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(_7,{items:ZN,onSelect:(I)=>{let N=I.value==="none"?void 0:I.value;q({...J,color:N}),L()}},void 0,!1,void 0,this),C(q0,{marginTop:1,children:C($0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="location")return C(q0,{flexDirection:"column",paddingY:1,children:[C(q0,{marginBottom:1,children:C($0,{bold:!0,color:"cyan",children:"\uD83D\uDCC2 Step 5/7: 选择保存位置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{dimColor:!0,children:"项目级配置仅在当前项目生效,用户级配置全局可用"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(_7,{items:[{label:"\uD83D\uDCC1 项目级 (.blade/agents/) - 仅当前项目",value:"project"},{label:"\uD83C\uDFE0 用户级 (~/.blade/agents/) - 全局可用",value:"user"}],onSelect:(I)=>{q({...J,location:I.value}),L()}},void 0,!1,void 0,this),C(q0,{marginTop:1,children:C($0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="systemPrompt")return C(q0,{flexDirection:"column",paddingY:1,children:[C(q0,{marginBottom:1,children:C($0,{bold:!0,color:"cyan",children:"\uD83D\uDCAC Step 6/7: 输入系统提示词"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{dimColor:!0,children:"定义 Agent 的行为和职责(可选,留空将使用默认提示)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:[C($0,{color:"green",children:"提示词: "},void 0,!1,void 0,this),C(h8,{value:J.systemPrompt,onChange:(I)=>q({...J,systemPrompt:I}),onSubmit:()=>L()},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C(q0,{children:C($0,{dimColor:!0,children:"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="confirm")return C(q0,{flexDirection:"column",paddingY:1,children:[C(q0,{marginBottom:1,children:C($0,{bold:!0,color:"cyan",children:"✅ Step 7/7: 确认配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{flexDirection:"column",paddingLeft:2,marginBottom:1,children:[C($0,{children:[C($0,{bold:!0,color:"green",children:["名称:"," "]},void 0,!0,void 0,this),C($0,{children:J.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C($0,{children:[C($0,{bold:!0,color:"green",children:["描述:"," "]},void 0,!0,void 0,this),C($0,{children:J.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C($0,{children:[C($0,{bold:!0,color:"green",children:["工具:"," "]},void 0,!0,void 0,this),C($0,{children:J.tools.includes("all")?"所有工具":J.tools.join(", ")||"所有工具"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C($0,{children:[C($0,{bold:!0,color:"green",children:["颜色:"," "]},void 0,!0,void 0,this),C($0,{children:J.color||"默认"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C($0,{children:[C($0,{bold:!0,color:"green",children:["位置:"," "]},void 0,!0,void 0,this),C($0,{children:J.location==="project"?"项目级":"用户级"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C($0,{children:[C($0,{bold:!0,color:"green",children:["提示词:"," "]},void 0,!0,void 0,this),C($0,{children:J.systemPrompt||"(使用默认)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),C(_7,{items:[{label:"✅ 确认并保存",value:"save"},{label:"⬅️ 返回上一步",value:"back"},{label:"❌ 取消",value:"cancel"}],onSelect:(I)=>{if(I.value==="save")R();else if(I.value==="back")V();else Z()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}function QN({config:$,setConfig:Z,onNext:Y,onPrev:Q}){let{isFocused:X}=sL({id:"step-tools"});xW((q,G)=>{if(G.escape)Q()},{isActive:X});let J=(q)=>{if(q.includes("all"))Z({...$,tools:["all"]});else Z({...$,tools:q});Y()};return C(q0,{flexDirection:"column",paddingY:1,children:[C(q0,{marginBottom:1,children:C($0,{bold:!0,color:"cyan",children:"\uD83D\uDD27 Step 3/7: 选择可用工具"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{dimColor:!0,children:"方向键导航,空格切换勾选,Enter 确认进入下一步 | ESC 返回上一步"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(oL,{options:$N,defaultValue:$.tools,onSubmit:J},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}R4();import XN from"node:fs";import{useMemoizedFn as E4}from"ahooks";import{Box as g0,Text as i0,useInput as JN}from"ink";import fZ from"ink-select-input";import{useEffect as qN,useMemo as pW,useState as z7}from"react";import{jsxDEV as o}from"react/jsx-dev-runtime";var hZ=10;function mW({initialMode:$="menu",onComplete:Z,onCancel:Y}){let[Q,X]=z7($),[J,q]=z7(null),[G,K]=z7(0),[W,U]=z7(0),F=E4(()=>{Y$.clear(),Y$.loadFromStandardLocations(),K((N)=>N+1)}),O=pW(()=>{return Y$.getAllSubagents()},[G]),H=Math.ceil(O.length/hZ)||1,_=pW(()=>{let N=W*hZ;return O.slice(N,N+hZ)},[O,W]);qN(()=>{let N=Math.max(0,H-1);if(W>N)U(N)},[H,W]);let z=E4(()=>{if(W<H-1)U((N)=>N+1)}),w=E4(()=>{if(W>0)U((N)=>N-1)}),B=[{key:"list",label:"\uD83D\uDCCB 查看所有 Agents",value:"list"},{key:"create",label:"➕ 创建新 Agent",value:"create"},{key:"edit",label:"✏️ 编辑 Agent",value:"edit"},{key:"delete",label:"\uD83D\uDDD1️ 删除 Agent",value:"delete"},{key:"cancel",label:"❌ 取消",value:"cancel"}],L=E4((N)=>{if(N.value==="cancel"){Y?.();return}X(N.value)}),V=E4((N)=>{if(q(N.value),Q==="edit")X("editWizard");else if(Q==="delete")X("deleteConfirm")}),D=E4(async()=>{if(!J?.configPath)return;try{await XN.promises.unlink(J.configPath),F(),R()}catch(N){console.error("删除失败:",N)}}),R=E4(()=>{X("menu"),q(null)}),y=Z$(!1,Y);if(JN((N,P)=>{if(P.escape){if(Q==="menu")Y?.();else if(Q==="list"||Q==="edit"||Q==="delete")U(0),R();else if(Q==="deleteConfirm")R()}else if(P.ctrl&&N==="c"||P.meta&&N==="c")y();else if(Q==="list"){if(P.leftArrow||N==="h")w();else if(P.rightArrow||N==="l")z()}},{isActive:Q!=="create"&&Q!=="editWizard"}),Q==="menu")return o(g0,{flexDirection:"column",paddingY:1,children:[o(g0,{marginBottom:1,children:o(i0,{bold:!0,color:"cyan",children:"\uD83D\uDCCB Agents 管理"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(fZ,{items:B,onSelect:L},void 0,!1,void 0,this),o(g0,{marginTop:1,children:o(i0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 退出"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="list"){if(O.length===0)return o(g0,{flexDirection:"column",paddingY:1,children:[o(g0,{marginBottom:1,children:o(i0,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(g0,{paddingLeft:2,children:o(i0,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(g0,{marginTop:1,paddingLeft:2,children:o(i0,{color:"gray",children:"\uD83D\uDCA1 配置文件位置: .blade/agents/ 或 ~/.blade/agents/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(g0,{marginTop:1,paddingLeft:2,children:o(i0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return o(g0,{flexDirection:"column",paddingY:1,children:[o(g0,{marginBottom:1,children:[o(i0,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this),o(i0,{color:"gray",children:[" (共 ",O.length," 个)"]},void 0,!0,void 0,this),H>1&&o(i0,{color:"yellow",children:[" ","第 ",W+1,"/",H," 页"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),_.map((N)=>o(g0,{flexDirection:"column",paddingLeft:2,children:[o(g0,{children:o(i0,{children:[o(i0,{bold:!0,color:N.color||"white",children:["• ",N.name]},void 0,!0,void 0,this),o(i0,{color:"gray",children:[" - ",N.description]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),N.tools&&N.tools.length>0&&o(g0,{paddingLeft:2,children:o(i0,{color:"gray",children:["工具: ",N.tools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),N.configPath&&o(g0,{paddingLeft:2,children:o(i0,{color:"gray",dimColor:!0,children:N.configPath},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},N.name,!0,void 0,this)),o(g0,{marginTop:1,paddingLeft:2,children:H>1?o(i0,{dimColor:!0,children:"← → 翻页 | ESC 返回菜单"},void 0,!1,void 0,this):o(i0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}let I=(N)=>{if(O.length===0)return o(g0,{flexDirection:"column",paddingY:1,children:[o(g0,{marginBottom:1,children:o(i0,{bold:!0,color:"cyan",children:N},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(g0,{paddingLeft:2,children:o(i0,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(g0,{marginTop:1,paddingLeft:2,children:o(i0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);let P=O.map((m)=>({key:m.name,label:`${m.name} - ${m.description}`,value:m}));return o(g0,{flexDirection:"column",paddingY:1,children:[o(g0,{marginBottom:1,children:o(i0,{bold:!0,color:"cyan",children:N},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(fZ,{items:P,onSelect:V},void 0,!1,void 0,this),o(g0,{marginTop:1,children:o(i0,{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(x8,{onComplete:()=>{F(),R()},onCancel:R},void 0,!1,void 0,this);if(Q==="edit")return I("✏️ 编辑 Agent");if(Q==="editWizard"&&J){let N={name:J.name,description:J.description,tools:J.tools||[],color:J.color,location:J.configPath?.includes(".blade/agents")?"project":"user",systemPrompt:J.systemPrompt||""};return o(x8,{initialConfig:N,onComplete:()=>{F(),R()},onCancel:R},void 0,!1,void 0,this)}if(Q==="delete")return I("\uD83D\uDDD1️ 删除 Agent");if(Q==="deleteConfirm"&&J)return o(g0,{flexDirection:"column",paddingY:1,children:[o(g0,{marginBottom:1,children:o(i0,{bold:!0,color:"red",children:"⚠️ 确认删除"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(g0,{marginBottom:1,paddingLeft:2,children:o(i0,{children:["你确定要删除 Agent"," ",o(i0,{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(g0,{marginBottom:1,paddingLeft:2,children:o(i0,{dimColor:!0,children:["文件路径: ",J.configPath]},void 0,!0,void 0,this)},void 0,!1,void 0,this),o(g0,{marginBottom:1,paddingLeft:2,children:o(i0,{color:"red",children:"此操作无法撤销!"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(fZ,{items:[{label:"\uD83D\uDDD1️ 确认删除",value:"confirm"},{label:"❌ 取消",value:"cancel"}],onSelect:(N)=>{if(N.value==="confirm")D();else R()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}G$();import{Box as P3,Text as a0}from"ink";import KN from"react";c6();AZ();import{useEffect as GN,useState as gW}from"react";function uW($=process.cwd(),Z=5000){let[Y,Q]=gW(null),[X,J]=gW(!0);return GN(()=>{let q=!0,G=async()=>{try{let W=await v8($);if(!q)return;if(!W){Q(null),J(!1);return}let U=await uG($);if(!q)return;Q(U)}catch{if(q)Q(null)}finally{if(q)J(!1)}};G();let K=null;if(Z>0)K=setInterval(G,Z);return()=>{if(q=!1,K)clearInterval(K)}},[$,Z]),{branch:Y,loading:X}}import{jsxDEV as N0,Fragment as B7}from"react/jsx-dev-runtime";var dW=KN.memo(()=>{let $=J7(),Z=y3(),Q=X7()==="shortcuts",X=$W(),{branch:J}=uW(),q=q7(),G=rK(),K=aK(),W=G7(),U=_W(),F=q?B3(q):!1,H=(()=>{if(Z==="default")return null;if(Z==="autoEdit")return N0(a0,{color:"magenta",children:["▶▶ auto edit on ",N0(a0,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="plan")return N0(a0,{color:"cyan",children:["‖ plan mode on ",N0(a0,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="yolo")return N0(a0,{color:"red",children:["⚡ yolo mode on ",N0(a0,{color:"gray",children:"(all tools auto-approved)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="spec"){let{phase:w,completed:B,total:L}=U,V;if(!w)V="init";else if((w==="tasks"||w==="implementation")&&L>0)V=`${w} ${B}/${L}`;else V=w;return N0(a0,{color:"blue",children:["\uD83D\uDCCB spec: ",V," ",N0(a0,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}return null})(),_=H!==null,z=[["Enter:发送","Shift+Enter:换行","Esc:中止"],["Shift+Tab:切换模式","↑/↓:历史","Tab:补全"],["Ctrl+A:行首","Ctrl+E:行尾","Ctrl+K:删到尾"],["Ctrl+U:删到首","Ctrl+W:删单词","Ctrl+C:退出"]];return N0(P3,{flexDirection:"row",justifyContent:"space-between",paddingX:2,paddingY:0,children:[Q?N0(P3,{flexDirection:"column",gap:0,children:z.map((w,B)=>N0(P3,{flexDirection:"row",children:[w.map((L,V)=>{let[D,R]=L.split(":");return N0(P3,{flexDirection:"row",width:20,children:[N0(a0,{color:"yellow",children:D},void 0,!1,void 0,this),N0(a0,{color:"gray",children:":"},void 0,!1,void 0,this),N0(a0,{color:"white",children:R},void 0,!1,void 0,this)]},V,!0,void 0,this)}),B===z.length-1&&N0(a0,{color:"cyan",children:" ? 关闭"},void 0,!1,void 0,this)]},B,!0,void 0,this))},void 0,!1,void 0,this):N0(P3,{flexDirection:"row",gap:1,children:[J&&N0(B7,{children:[N0(a0,{color:"gray",children:[" ",J]},void 0,!0,void 0,this),N0(a0,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H,_&&N0(a0,{color:"gray",children:"·"},void 0,!1,void 0,this),N0(a0,{color:"gray",children:"? for shortcuts"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),N0(P3,{flexDirection:"row",gap:1,children:!$?N0(a0,{color:"red",children:"⚠ API 密钥未配置"},void 0,!1,void 0,this):N0(B7,{children:[F&&N0(B7,{children:[W?N0(a0,{color:"cyan",children:"Thinking on"},void 0,!1,void 0,this):N0(a0,{color:"gray",children:"Tab:Thinking"},void 0,!1,void 0,this),N0(a0,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),q&&N0(a0,{color:"gray",children:q.model},void 0,!1,void 0,this),N0(a0,{color:"gray",children:"·"},void 0,!1,void 0,this),K?N0(a0,{color:"yellow",children:"压缩中..."},void 0,!1,void 0,this):N0(a0,{color:G<20?"red":G<50?"yellow":"gray",children:[G,"%"]},void 0,!0,void 0,this),X&&N0(B7,{children:[N0(a0,{color:"gray",children:"·"},void 0,!1,void 0,this),N0(a0,{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 xZ,Text as pZ}from"ink";import WN from"react";import{jsxDEV as C3}from"react/jsx-dev-runtime";var cW=WN.memo(({suggestions:$,selectedIndex:Z,visible:Y,maxDisplay:Q=8})=>{if(!Y||$.length===0)return null;let X=0,J=Math.min(Q,$.length),q=Z>=$.length;if(Z>=Q&&!q)X=Z-Q+1,J=Z+1;let G=$.slice(X,J),K=$.length>Q;return C3(xZ,{flexDirection:"column",paddingX:2,paddingY:0,children:[G.map((W,U)=>{let O=X+U===Z;return C3(xZ,{flexDirection:"row",paddingX:1,gap:2,children:[C3(pZ,{color:O?"cyan":"white",bold:O,children:W.command},void 0,!1,void 0,this),C3(pZ,{color:O?"cyan":"gray",dimColor:!O,children:["- ",W.description]},void 0,!0,void 0,this)]},W.command,!0,void 0,this)}),K&&C3(xZ,{paddingX:1,children:C3(pZ,{color:q?"cyan":"gray",bold:q,dimColor:!q,children:["... and ",$.length-Q," more"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});G$();import{Box as R1,Text as g1,useInput as hN,useStdout as xN}from"ink";import pN from"ink-select-input";import $Y,{useMemo as YU}from"react";import{Box as b0,Text as r0}from"ink";import S4,{useEffect as eZ,useMemo as f3,useRef as ZU}from"react";l3();s7();import{Box as L7,Text as $2}from"ink";import{isPlainObject as cZ}from"lodash-es";import{common as _N,createLowlight as zN}from"lowlight";import nW from"react";q4();import{Box as w7,Text as p8}from"ink";import B2,{Fragment as aW}from"react";import UN from"string-width";var lW=new Map,iW=1000;function gZ($){let Z=!0;for(let Q=0;Q<$.length;Q++)if($.charCodeAt(Q)>127){Z=!1;break}if(Z)return $.split("");if($.length<=iW){let Q=lW.get($);if(Q)return Q}let Y=Array.from($);if($.length<=iW)lW.set($,Y);return Y}var mZ=new Map;function z2($){if(/^[\x20-\x7E]*$/.test($))return $.length;if(mZ.has($))return mZ.get($);let Z=UN($);return mZ.set($,Z),Z}import{jsxDEV as S3}from"react/jsx-dev-runtime";var uZ=2,rW=B2.memo(({children:$,maxWidth:Z,maxHeight:Y,overflowDirection:Q="top",additionalHiddenLinesCount:X=0})=>{let J=m0(),q=[],G=Math.max(Math.round(Y??Number.MAX_SAFE_INTEGER),uZ);function K(z){if(!B2.isValidElement(z))return;if(z.type===aW){B2.Children.forEach(z.props.children,K);return}if(z.type===w7){ON(z,Z,q);return}}B2.Children.forEach($,K);let U=q.length>G||X>0?G-1:G,F=U!==void 0?Math.max(0,q.length-U):0,O=F+X,_=(F>0?Q==="top"?q.slice(F):q.slice(0,U):q).map((z,w)=>S3(w7,{children:z.length>0?z.map((B,L)=>S3(p8,{...B.props,children:B.text},L,!1,void 0,this)):S3(p8,{children:" "},void 0,!1,void 0,this)},w,!1,void 0,this));return S3(w7,{flexDirection:"column",width:Z,flexShrink:0,children:[O>0&&Q==="top"&&S3(p8,{color:J.colors.text.muted,dimColor:!0,children:["... ",O," line",O===1?"":"s"," hidden ..."]},void 0,!0,void 0,this),_,O>0&&Q==="bottom"&&S3(p8,{color:J.colors.text.muted,dimColor:!0,children:["... ",O," line",O===1?"":"s"," hidden ..."]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});function FN($){if(!B2.isValidElement($)||$.type!==w7)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(!B2.isValidElement(X))return;if(X.type===aW){B2.Children.forEach(X.props.children,(W)=>Q(W,J));return}if(X.type!==p8)return;let{children:q,...G}=X.props,K=J===void 0?G:{...J,...G};B2.Children.forEach(q,(W)=>Q(W,K))}return B2.Children.forEach($.props.children,(X)=>Q(X,void 0)),Z}function ON($,Z,Y){let Q=FN($);if(Q.segments.length===0&&Q.noWrapSegments.length===0){Y.push([]);return}let X=0;for(let F of Q.noWrapSegments)X+=z2(F.text);if(Q.segments.length===0){let F=[],O=[];for(let H of Q.noWrapSegments){let _=H.text.split(`
|
|
2817
|
-
`);for(let z=0;z<_.length;z++){if(z>0)F.push(O),O=[];if(_[z])O.push({text:_[z],props:H.props})}}if(O.length>0)F.push(O);for(let H of F)Y.push(H);return}let J=Z-X;if(J<1){
|
|
2816
|
+
`),m=kZ.join(I,`${J.name}.md`);await fW.promises.writeFile(m,P,"utf-8"),$()}catch(I){console.error("保存配置失败:",I)}}),y=Y$(!1,Z);if(xW((I,N)=>{if(N.escape)V();else if(N.ctrl&&I==="c"||N.meta&&I==="c")y()},{isActive:Q!=="tools"}),Q==="mode")return C(q0,{flexDirection:"column",paddingY:1,children:[C(q0,{marginBottom:1,children:C($0,{bold:!0,color:"cyan",children:"\uD83C\uDFAF 选择创建方式"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{dimColor:!0,children:"你可以手动配置每个细节,或让 AI 根据你的描述自动生成配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(_7,{items:[{label:"\uD83E\uDD16 AI 智能生成 - 根据描述自动生成完整配置",value:"ai"},{label:"✍️ 手动配置 - 逐步配置每个选项",value:"manual"}],onSelect:(I)=>{if(I.value==="ai")_("ai"),X("aiPrompt");else _("manual"),X("name")}},void 0,!1,void 0,this),C(q0,{marginTop:1,children:C($0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 取消"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="aiPrompt")return C(q0,{flexDirection:"column",paddingY:1,children:[C(q0,{marginBottom:1,children:C($0,{bold:!0,color:"cyan",children:"\uD83E\uDD16 AI 智能生成"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{dimColor:!0,children:'描述你想要创建的 Agent(例如:"一个专门用于代码审查的 agent,能够分析代码质量和潜在bug")'},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:[C($0,{color:"green",children:"描述: "},void 0,!1,void 0,this),C(h8,{value:G,onChange:K,onSubmit:(I)=>{if(!I.trim())return;X("aiGenerating")}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C(q0,{children:C($0,{dimColor:!0,children:"按 Enter 开始生成 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="aiGenerating"){if(F)return C(q0,{flexDirection:"column",paddingY:1,children:[C(q0,{marginBottom:1,children:C($0,{bold:!0,color:"red",children:"❌ AI 生成失败"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{color:"red",children:F},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{dimColor:!0,children:"按 ESC 返回修改描述"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return C(q0,{flexDirection:"column",paddingY:1,children:[C(q0,{marginBottom:1,children:C($0,{bold:!0,color:"yellow",children:[C($N,{type:"dots"},void 0,!1,void 0,this)," AI 正在生成配置..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{dimColor:!0,children:['根据你的描述:"',G,'"']},void 0,!0,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{color:"gray",children:"正在调用 LLM 生成 agent 配置,请稍候..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}if(Q==="name"){let I=H==="edit";return C(q0,{flexDirection:"column",paddingY:1,children:[C(q0,{marginBottom:1,children:C($0,{bold:!0,color:"cyan",children:["\uD83D\uDCDD Step 1/7: ",I?"Agent 名称(不可修改)":"输入 Agent 名称"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{dimColor:!0,children:I?"编辑模式下名称不可修改(修改名称相当于创建新 Agent)":"名称只能包含小写字母、数字和连字符(例如:code-reviewer)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:[C($0,{color:"green",children:"名称: "},void 0,!1,void 0,this),I?C($0,{children:J.name},void 0,!1,void 0,this):C(h8,{value:J.name,onChange:(N)=>q({...J,name:N}),onSubmit:(N)=>{if(QN(N))return;L()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C(q0,{children:C($0,{dimColor:!0,children:I?"按 Enter 继续 | ESC 返回":"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this),I&&C(h8,{value:"",onChange:()=>{},onSubmit:L,showCursor:!1},"edit-mode-dummy-input",!1,void 0,this)]},void 0,!0,void 0,this)}if(Q==="description")return C(q0,{flexDirection:"column",paddingY:1,children:[C(q0,{marginBottom:1,children:C($0,{bold:!0,color:"cyan",children:"\uD83D\uDCDD Step 2/7: 输入描述信息"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{dimColor:!0,children:"简短描述这个 Agent 的用途和使用场景(这将帮助主 Agent 决定何时使用它)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:[C($0,{color:"green",children:"描述: "},void 0,!1,void 0,this),C(h8,{value:J.description,onChange:(I)=>q({...J,description:I}),onSubmit:(I)=>{if(!I.trim())return;L()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C(q0,{children:C($0,{dimColor:!0,children:"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="tools")return C(XN,{config:J,setConfig:q,onNext:L,onPrev:V},void 0,!1,void 0,this);if(Q==="color")return C(q0,{flexDirection:"column",paddingY:1,children:[C(q0,{marginBottom:1,children:C($0,{bold:!0,color:"cyan",children:"\uD83C\uDFA8 Step 4/7: 选择背景颜色"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{dimColor:!0,children:"为 Agent 选择一个颜色标识(用于在 UI 中区分不同的 Agents)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(_7,{items:YN,onSelect:(I)=>{let N=I.value==="none"?void 0:I.value;q({...J,color:N}),L()}},void 0,!1,void 0,this),C(q0,{marginTop:1,children:C($0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="location")return C(q0,{flexDirection:"column",paddingY:1,children:[C(q0,{marginBottom:1,children:C($0,{bold:!0,color:"cyan",children:"\uD83D\uDCC2 Step 5/7: 选择保存位置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{dimColor:!0,children:"项目级配置仅在当前项目生效,用户级配置全局可用"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(_7,{items:[{label:"\uD83D\uDCC1 项目级 (.blade/agents/) - 仅当前项目",value:"project"},{label:"\uD83C\uDFE0 用户级 (~/.blade/agents/) - 全局可用",value:"user"}],onSelect:(I)=>{q({...J,location:I.value}),L()}},void 0,!1,void 0,this),C(q0,{marginTop:1,children:C($0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="systemPrompt")return C(q0,{flexDirection:"column",paddingY:1,children:[C(q0,{marginBottom:1,children:C($0,{bold:!0,color:"cyan",children:"\uD83D\uDCAC Step 6/7: 输入系统提示词"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{dimColor:!0,children:"定义 Agent 的行为和职责(可选,留空将使用默认提示)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:[C($0,{color:"green",children:"提示词: "},void 0,!1,void 0,this),C(h8,{value:J.systemPrompt,onChange:(I)=>q({...J,systemPrompt:I}),onSubmit:()=>L()},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C(q0,{children:C($0,{dimColor:!0,children:"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="confirm")return C(q0,{flexDirection:"column",paddingY:1,children:[C(q0,{marginBottom:1,children:C($0,{bold:!0,color:"cyan",children:"✅ Step 7/7: 确认配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{flexDirection:"column",paddingLeft:2,marginBottom:1,children:[C($0,{children:[C($0,{bold:!0,color:"green",children:["名称:"," "]},void 0,!0,void 0,this),C($0,{children:J.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C($0,{children:[C($0,{bold:!0,color:"green",children:["描述:"," "]},void 0,!0,void 0,this),C($0,{children:J.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C($0,{children:[C($0,{bold:!0,color:"green",children:["工具:"," "]},void 0,!0,void 0,this),C($0,{children:J.tools.includes("all")?"所有工具":J.tools.join(", ")||"所有工具"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C($0,{children:[C($0,{bold:!0,color:"green",children:["颜色:"," "]},void 0,!0,void 0,this),C($0,{children:J.color||"默认"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C($0,{children:[C($0,{bold:!0,color:"green",children:["位置:"," "]},void 0,!0,void 0,this),C($0,{children:J.location==="project"?"项目级":"用户级"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C($0,{children:[C($0,{bold:!0,color:"green",children:["提示词:"," "]},void 0,!0,void 0,this),C($0,{children:J.systemPrompt||"(使用默认)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),C(_7,{items:[{label:"✅ 确认并保存",value:"save"},{label:"⬅️ 返回上一步",value:"back"},{label:"❌ 取消",value:"cancel"}],onSelect:(I)=>{if(I.value==="save")R();else if(I.value==="back")V();else Z()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}function XN({config:$,setConfig:Z,onNext:Y,onPrev:Q}){let{isFocused:X}=tL({id:"step-tools"});xW((q,G)=>{if(G.escape)Q()},{isActive:X});let J=(q)=>{if(q.includes("all"))Z({...$,tools:["all"]});else Z({...$,tools:q});Y()};return C(q0,{flexDirection:"column",paddingY:1,children:[C(q0,{marginBottom:1,children:C($0,{bold:!0,color:"cyan",children:"\uD83D\uDD27 Step 3/7: 选择可用工具"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(q0,{marginBottom:1,children:C($0,{dimColor:!0,children:"方向键导航,空格切换勾选,Enter 确认进入下一步 | ESC 返回上一步"},void 0,!1,void 0,this)},void 0,!1,void 0,this),C(sL,{options:ZN,defaultValue:$.tools,onSubmit:J},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}R4();import JN from"node:fs";import{useMemoizedFn as E4}from"ahooks";import{Box as g0,Text as i0,useInput as qN}from"ink";import fZ from"ink-select-input";import{useEffect as GN,useMemo as pW,useState as z7}from"react";import{jsxDEV as o}from"react/jsx-dev-runtime";var hZ=10;function mW({initialMode:$="menu",onComplete:Z,onCancel:Y}){let[Q,X]=z7($),[J,q]=z7(null),[G,K]=z7(0),[W,U]=z7(0),F=E4(()=>{Z$.clear(),Z$.loadFromStandardLocations(),K((N)=>N+1)}),O=pW(()=>{return Z$.getAllSubagents()},[G]),H=Math.ceil(O.length/hZ)||1,_=pW(()=>{let N=W*hZ;return O.slice(N,N+hZ)},[O,W]);GN(()=>{let N=Math.max(0,H-1);if(W>N)U(N)},[H,W]);let z=E4(()=>{if(W<H-1)U((N)=>N+1)}),w=E4(()=>{if(W>0)U((N)=>N-1)}),B=[{key:"list",label:"\uD83D\uDCCB 查看所有 Agents",value:"list"},{key:"create",label:"➕ 创建新 Agent",value:"create"},{key:"edit",label:"✏️ 编辑 Agent",value:"edit"},{key:"delete",label:"\uD83D\uDDD1️ 删除 Agent",value:"delete"},{key:"cancel",label:"❌ 取消",value:"cancel"}],L=E4((N)=>{if(N.value==="cancel"){Y?.();return}X(N.value)}),V=E4((N)=>{if(q(N.value),Q==="edit")X("editWizard");else if(Q==="delete")X("deleteConfirm")}),D=E4(async()=>{if(!J?.configPath)return;try{await JN.promises.unlink(J.configPath),F(),R()}catch(N){console.error("删除失败:",N)}}),R=E4(()=>{X("menu"),q(null)}),y=Y$(!1,Y);if(qN((N,P)=>{if(P.escape){if(Q==="menu")Y?.();else if(Q==="list"||Q==="edit"||Q==="delete")U(0),R();else if(Q==="deleteConfirm")R()}else if(P.ctrl&&N==="c"||P.meta&&N==="c")y();else if(Q==="list"){if(P.leftArrow||N==="h")w();else if(P.rightArrow||N==="l")z()}},{isActive:Q!=="create"&&Q!=="editWizard"}),Q==="menu")return o(g0,{flexDirection:"column",paddingY:1,children:[o(g0,{marginBottom:1,children:o(i0,{bold:!0,color:"cyan",children:"\uD83D\uDCCB Agents 管理"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(fZ,{items:B,onSelect:L},void 0,!1,void 0,this),o(g0,{marginTop:1,children:o(i0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 退出"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="list"){if(O.length===0)return o(g0,{flexDirection:"column",paddingY:1,children:[o(g0,{marginBottom:1,children:o(i0,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(g0,{paddingLeft:2,children:o(i0,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(g0,{marginTop:1,paddingLeft:2,children:o(i0,{color:"gray",children:"\uD83D\uDCA1 配置文件位置: .blade/agents/ 或 ~/.blade/agents/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(g0,{marginTop:1,paddingLeft:2,children:o(i0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return o(g0,{flexDirection:"column",paddingY:1,children:[o(g0,{marginBottom:1,children:[o(i0,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this),o(i0,{color:"gray",children:[" (共 ",O.length," 个)"]},void 0,!0,void 0,this),H>1&&o(i0,{color:"yellow",children:[" ","第 ",W+1,"/",H," 页"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),_.map((N)=>o(g0,{flexDirection:"column",paddingLeft:2,children:[o(g0,{children:o(i0,{children:[o(i0,{bold:!0,color:N.color||"white",children:["• ",N.name]},void 0,!0,void 0,this),o(i0,{color:"gray",children:[" - ",N.description]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),N.tools&&N.tools.length>0&&o(g0,{paddingLeft:2,children:o(i0,{color:"gray",children:["工具: ",N.tools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),N.configPath&&o(g0,{paddingLeft:2,children:o(i0,{color:"gray",dimColor:!0,children:N.configPath},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},N.name,!0,void 0,this)),o(g0,{marginTop:1,paddingLeft:2,children:H>1?o(i0,{dimColor:!0,children:"← → 翻页 | ESC 返回菜单"},void 0,!1,void 0,this):o(i0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}let I=(N)=>{if(O.length===0)return o(g0,{flexDirection:"column",paddingY:1,children:[o(g0,{marginBottom:1,children:o(i0,{bold:!0,color:"cyan",children:N},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(g0,{paddingLeft:2,children:o(i0,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(g0,{marginTop:1,paddingLeft:2,children:o(i0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);let P=O.map((m)=>({key:m.name,label:`${m.name} - ${m.description}`,value:m}));return o(g0,{flexDirection:"column",paddingY:1,children:[o(g0,{marginBottom:1,children:o(i0,{bold:!0,color:"cyan",children:N},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(fZ,{items:P,onSelect:V},void 0,!1,void 0,this),o(g0,{marginTop:1,children:o(i0,{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(x8,{onComplete:()=>{F(),R()},onCancel:R},void 0,!1,void 0,this);if(Q==="edit")return I("✏️ 编辑 Agent");if(Q==="editWizard"&&J){let N={name:J.name,description:J.description,tools:J.tools||[],color:J.color,location:J.configPath?.includes(".blade/agents")?"project":"user",systemPrompt:J.systemPrompt||""};return o(x8,{initialConfig:N,onComplete:()=>{F(),R()},onCancel:R},void 0,!1,void 0,this)}if(Q==="delete")return I("\uD83D\uDDD1️ 删除 Agent");if(Q==="deleteConfirm"&&J)return o(g0,{flexDirection:"column",paddingY:1,children:[o(g0,{marginBottom:1,children:o(i0,{bold:!0,color:"red",children:"⚠️ 确认删除"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(g0,{marginBottom:1,paddingLeft:2,children:o(i0,{children:["你确定要删除 Agent"," ",o(i0,{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(g0,{marginBottom:1,paddingLeft:2,children:o(i0,{dimColor:!0,children:["文件路径: ",J.configPath]},void 0,!0,void 0,this)},void 0,!1,void 0,this),o(g0,{marginBottom:1,paddingLeft:2,children:o(i0,{color:"red",children:"此操作无法撤销!"},void 0,!1,void 0,this)},void 0,!1,void 0,this),o(fZ,{items:[{label:"\uD83D\uDDD1️ 确认删除",value:"confirm"},{label:"❌ 取消",value:"cancel"}],onSelect:(N)=>{if(N.value==="confirm")D();else R()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}G$();import{Box as P3,Text as a0}from"ink";import WN from"react";c6();AZ();import{useEffect as KN,useState as gW}from"react";function uW($=process.cwd(),Z=5000){let[Y,Q]=gW(null),[X,J]=gW(!0);return KN(()=>{let q=!0,G=async()=>{try{let W=await v8($);if(!q)return;if(!W){Q(null),J(!1);return}let U=await uG($);if(!q)return;Q(U)}catch{if(q)Q(null)}finally{if(q)J(!1)}};G();let K=null;if(Z>0)K=setInterval(G,Z);return()=>{if(q=!1,K)clearInterval(K)}},[$,Z]),{branch:Y,loading:X}}import{jsxDEV as N0,Fragment as B7}from"react/jsx-dev-runtime";var dW=WN.memo(()=>{let $=J7(),Z=y3(),Q=X7()==="shortcuts",X=$W(),{branch:J}=uW(),q=q7(),G=rK(),K=aK(),W=G7(),U=_W(),F=q?B3(q):!1,H=(()=>{if(Z==="default")return null;if(Z==="autoEdit")return N0(a0,{color:"magenta",children:["▶▶ auto edit on ",N0(a0,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="plan")return N0(a0,{color:"cyan",children:["‖ plan mode on ",N0(a0,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="yolo")return N0(a0,{color:"red",children:["⚡ yolo mode on ",N0(a0,{color:"gray",children:"(all tools auto-approved)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="spec"){let{phase:w,completed:B,total:L}=U,V;if(!w)V="init";else if((w==="tasks"||w==="implementation")&&L>0)V=`${w} ${B}/${L}`;else V=w;return N0(a0,{color:"blue",children:["\uD83D\uDCCB spec: ",V," ",N0(a0,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}return null})(),_=H!==null,z=[["Enter:发送","Shift+Enter:换行","Esc:中止"],["Shift+Tab:切换模式","↑/↓:历史","Tab:补全"],["Ctrl+A:行首","Ctrl+E:行尾","Ctrl+K:删到尾"],["Ctrl+U:删到首","Ctrl+W:删单词","Ctrl+C:退出"]];return N0(P3,{flexDirection:"row",justifyContent:"space-between",paddingX:2,paddingY:0,children:[Q?N0(P3,{flexDirection:"column",gap:0,children:z.map((w,B)=>N0(P3,{flexDirection:"row",children:[w.map((L,V)=>{let[D,R]=L.split(":");return N0(P3,{flexDirection:"row",width:20,children:[N0(a0,{color:"yellow",children:D},void 0,!1,void 0,this),N0(a0,{color:"gray",children:":"},void 0,!1,void 0,this),N0(a0,{color:"white",children:R},void 0,!1,void 0,this)]},V,!0,void 0,this)}),B===z.length-1&&N0(a0,{color:"cyan",children:" ? 关闭"},void 0,!1,void 0,this)]},B,!0,void 0,this))},void 0,!1,void 0,this):N0(P3,{flexDirection:"row",gap:1,children:[J&&N0(B7,{children:[N0(a0,{color:"gray",children:[" ",J]},void 0,!0,void 0,this),N0(a0,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H,_&&N0(a0,{color:"gray",children:"·"},void 0,!1,void 0,this),N0(a0,{color:"gray",children:"? for shortcuts"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),N0(P3,{flexDirection:"row",gap:1,children:!$?N0(a0,{color:"red",children:"⚠ API 密钥未配置"},void 0,!1,void 0,this):N0(B7,{children:[F&&N0(B7,{children:[W?N0(a0,{color:"cyan",children:"Thinking on"},void 0,!1,void 0,this):N0(a0,{color:"gray",children:"Tab:Thinking"},void 0,!1,void 0,this),N0(a0,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),q&&N0(a0,{color:"gray",children:q.model},void 0,!1,void 0,this),N0(a0,{color:"gray",children:"·"},void 0,!1,void 0,this),K?N0(a0,{color:"yellow",children:"压缩中..."},void 0,!1,void 0,this):N0(a0,{color:G<20?"red":G<50?"yellow":"gray",children:[G,"%"]},void 0,!0,void 0,this),X&&N0(B7,{children:[N0(a0,{color:"gray",children:"·"},void 0,!1,void 0,this),N0(a0,{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 xZ,Text as pZ}from"ink";import UN from"react";import{jsxDEV as C3}from"react/jsx-dev-runtime";var cW=UN.memo(({suggestions:$,selectedIndex:Z,visible:Y,maxDisplay:Q=8})=>{if(!Y||$.length===0)return null;let X=0,J=Math.min(Q,$.length),q=Z>=$.length;if(Z>=Q&&!q)X=Z-Q+1,J=Z+1;let G=$.slice(X,J),K=$.length>Q;return C3(xZ,{flexDirection:"column",paddingX:2,paddingY:0,children:[G.map((W,U)=>{let O=X+U===Z;return C3(xZ,{flexDirection:"row",paddingX:1,gap:2,children:[C3(pZ,{color:O?"cyan":"white",bold:O,children:W.command},void 0,!1,void 0,this),C3(pZ,{color:O?"cyan":"gray",dimColor:!O,children:["- ",W.description]},void 0,!0,void 0,this)]},W.command,!0,void 0,this)}),K&&C3(xZ,{paddingX:1,children:C3(pZ,{color:q?"cyan":"gray",bold:q,dimColor:!q,children:["... and ",$.length-Q," more"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});G$();import{Box as R1,Text as g1,useInput as xN,useStdout as pN}from"ink";import mN from"ink-select-input";import $Y,{useMemo as YU}from"react";import{Box as b0,Text as r0}from"ink";import S4,{useEffect as eZ,useMemo as f3,useRef as ZU}from"react";l3();s7();import{Box as L7,Text as $2}from"ink";import{isPlainObject as cZ}from"lodash-es";import{common as zN,createLowlight as BN}from"lowlight";import nW from"react";q4();import{Box as w7,Text as p8}from"ink";import B2,{Fragment as aW}from"react";import FN from"string-width";var lW=new Map,iW=1000;function gZ($){let Z=!0;for(let Q=0;Q<$.length;Q++)if($.charCodeAt(Q)>127){Z=!1;break}if(Z)return $.split("");if($.length<=iW){let Q=lW.get($);if(Q)return Q}let Y=Array.from($);if($.length<=iW)lW.set($,Y);return Y}var mZ=new Map;function z2($){if(/^[\x20-\x7E]*$/.test($))return $.length;if(mZ.has($))return mZ.get($);let Z=FN($);return mZ.set($,Z),Z}import{jsxDEV as S3}from"react/jsx-dev-runtime";var uZ=2,rW=B2.memo(({children:$,maxWidth:Z,maxHeight:Y,overflowDirection:Q="top",additionalHiddenLinesCount:X=0})=>{let J=m0(),q=[],G=Math.max(Math.round(Y??Number.MAX_SAFE_INTEGER),uZ);function K(z){if(!B2.isValidElement(z))return;if(z.type===aW){B2.Children.forEach(z.props.children,K);return}if(z.type===w7){HN(z,Z,q);return}}B2.Children.forEach($,K);let U=q.length>G||X>0?G-1:G,F=U!==void 0?Math.max(0,q.length-U):0,O=F+X,_=(F>0?Q==="top"?q.slice(F):q.slice(0,U):q).map((z,w)=>S3(w7,{children:z.length>0?z.map((B,L)=>S3(p8,{...B.props,children:B.text},L,!1,void 0,this)):S3(p8,{children:" "},void 0,!1,void 0,this)},w,!1,void 0,this));return S3(w7,{flexDirection:"column",width:Z,flexShrink:0,children:[O>0&&Q==="top"&&S3(p8,{color:J.colors.text.muted,dimColor:!0,children:["... ",O," line",O===1?"":"s"," hidden ..."]},void 0,!0,void 0,this),_,O>0&&Q==="bottom"&&S3(p8,{color:J.colors.text.muted,dimColor:!0,children:["... ",O," line",O===1?"":"s"," hidden ..."]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});function ON($){if(!B2.isValidElement($)||$.type!==w7)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(!B2.isValidElement(X))return;if(X.type===aW){B2.Children.forEach(X.props.children,(W)=>Q(W,J));return}if(X.type!==p8)return;let{children:q,...G}=X.props,K=J===void 0?G:{...J,...G};B2.Children.forEach(q,(W)=>Q(W,K))}return B2.Children.forEach($.props.children,(X)=>Q(X,void 0)),Z}function HN($,Z,Y){let Q=ON($);if(Q.segments.length===0&&Q.noWrapSegments.length===0){Y.push([]);return}let X=0;for(let F of Q.noWrapSegments)X+=z2(F.text);if(Q.segments.length===0){let F=[],O=[];for(let H of Q.noWrapSegments){let _=H.text.split(`
|
|
2817
|
+
`);for(let z=0;z<_.length;z++){if(z>0)F.push(O),O=[];if(_[z])O.push({text:_[z],props:H.props})}}if(O.length>0)F.push(O);for(let H of F)Y.push(H);return}let J=Z-X;if(J<1){_N(Q.noWrapSegments,Z,Y);return}let q=[],G=[],K=0;function W(){if(q.length===0)q.push([...Q.noWrapSegments,...G]);else if(X>0)q.push([{text:" ".repeat(X),props:{}},...G]);else q.push(G);G=[],K=0}function U(F,O){if(G.length>0&&G[G.length-1].props===O)G[G.length-1].text+=F;else G.push({text:F,props:O})}for(let F of Q.segments){let O=F.text.split(`
|
|
2818
2818
|
`);for(let H=0;H<O.length;H++){if(H>0)W();let z=O[H].split(/(\s+)/);for(let w of z){if(!w)continue;let B=z2(w);if(K+B>J&&K>0){if(W(),/^\s+$/.test(w))continue}if(B>J){let V=gZ(w);while(V.length>0){let D=0,R=0;for(let y of V){let I=z2(y);if(K+R+I>J)break;R+=I,D++}if(D>0){let y=V.slice(0,D).join("");U(y,F.props),K+=z2(y),V=V.slice(D)}if(V.length>0)W()}}else U(w,F.props),K+=B}}if(F.text.endsWith(`
|
|
2819
|
-
`))W()}if(G.length>0)W();for(let F of q)Y.push(F)}function
|
|
2820
|
-
`);for(let K=0;K<G.length;K++){if(K>0)Q.push(X),X=[],J=0;let W=G[K];if(!W)continue;let U=z2(W),F=Math.max(0,Z-z2("…"));if(U<=F&&J===0)X.push({text:W,props:q.props}),J+=U;else{let O=gZ(W),H=J,_=0;for(let w of O){let B=z2(w);if(H+B>F)break;H+=B,_++}let z=O.slice(0,_).join("");if(z)X.push({text:z,props:q.props});X.push({text:"…",props:{}}),J=H+z2("…")}}}if(X.length>0)Q.push(X);if(Q.length===0)Q.push([{text:"…",props:{}}]);for(let q of Q)Y.push(q)}import{jsxDEV as S$}from"react/jsx-dev-runtime";var dZ=zN
|
|
2821
|
-
`),G=0;if(X&&q.length>X){let F=Math.max(X,uZ);if(q.length>F)G=q.length-F,q=q.slice(G)}let K=q.length+G,W=String(K).length+1,U=Math.max(20,Q-4);return S$(L7,{borderStyle:"round",borderColor:J.colors.border.light,paddingX:1,paddingY:0,marginY:1,flexDirection:"column",children:[Z&&S$(L7,{marginBottom:0,children:S$($2,{color:J.colors.text.secondary,children:Z},void 0,!1,void 0,this)},void 0,!1,void 0,this),G>0&&S$(L7,{marginBottom:0,children:S$($2,{color:J.colors.text.muted,dimColor:!0,children:["... ",G," lines hidden ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this),S$(rW,{maxWidth:U,maxHeight:X,children:q.map((F,O)=>{let H=O+G+1;return S$(L7,{flexDirection:"row",children:[Y&&S$($2,{color:J.colors.text.muted,dimColor:!0,wrap:"truncate",children:[String(H).padStart(W-1," ")," "]},void 0,!0,void 0,this),F.trim()===""?S$($2,{wrap:"wrap",children:" "},void 0,!1,void 0,this):
|
|
2822
|
-
`),Y=[],Q=0,X=0;for(let J of Z){if(J.startsWith("---")||J.startsWith("+++"))continue;if(J.startsWith("@@")){let q=J.match(/@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@/);if(q)Q=parseInt(q[1],10),X=parseInt(q[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 lZ=
|
|
2819
|
+
`))W()}if(G.length>0)W();for(let F of q)Y.push(F)}function _N($,Z,Y){let Q=[],X=[],J=0;for(let q of $){let G=q.text.split(`
|
|
2820
|
+
`);for(let K=0;K<G.length;K++){if(K>0)Q.push(X),X=[],J=0;let W=G[K];if(!W)continue;let U=z2(W),F=Math.max(0,Z-z2("…"));if(U<=F&&J===0)X.push({text:W,props:q.props}),J+=U;else{let O=gZ(W),H=J,_=0;for(let w of O){let B=z2(w);if(H+B>F)break;H+=B,_++}let z=O.slice(0,_).join("");if(z)X.push({text:z,props:q.props});X.push({text:"…",props:{}}),J=H+z2("…")}}}if(X.length>0)Q.push(X);if(Q.length===0)Q.push([{text:"…",props:{}}]);for(let q of Q)Y.push(q)}import{jsxDEV as S$}from"react/jsx-dev-runtime";var dZ=BN(zN);function wN($){return cZ($)&&$.type==="text"&&typeof $.value==="string"}function LN($){return cZ($)&&$.type==="element"}function NN($){return cZ($)&&$.type==="root"&&Array.isArray($.children)}function N7($,Z,Y=0){if(wN($))return S$($2,{wrap:"wrap",children:$.value},Y,!1,void 0,this);if(LN($)){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((q,G)=>N7(q,Z,G));return S$($2,{color:X,wrap:"wrap",children:J},Y,!1,void 0,this)}if(NN($))return S$(nW.Fragment,{children:$.children.map((Q,X)=>N7(Q,Z,X))},Y,!1,void 0,this);return S$($2,{},Y,!1,void 0,this)}function bN($,Z,Y){let Q=Y||u$.getTheme().colors.syntax;try{if(!Z||!dZ.registered(Z)){let J=dZ.highlightAuto($);if(!J.children||J.children.length===0)return S$($2,{color:Q.default,wrap:"wrap",children:$},void 0,!1,void 0,this);return N7(J,Q)}let X=dZ.highlight(Z,$);if(!X.children||X.children.length===0)return S$($2,{color:Q.default,wrap:"wrap",children:$},void 0,!1,void 0,this);return N7(X,Q)}catch(X){return S$($2,{color:Q.default,wrap:"wrap",children:$},void 0,!1,void 0,this)}}var b7=nW.memo(({content:$,language:Z,showLineNumbers:Y=!0,terminalWidth:Q,availableHeight:X})=>{let J=m0(),q=$.split(`
|
|
2821
|
+
`),G=0;if(X&&q.length>X){let F=Math.max(X,uZ);if(q.length>F)G=q.length-F,q=q.slice(G)}let K=q.length+G,W=String(K).length+1,U=Math.max(20,Q-4);return S$(L7,{borderStyle:"round",borderColor:J.colors.border.light,paddingX:1,paddingY:0,marginY:1,flexDirection:"column",children:[Z&&S$(L7,{marginBottom:0,children:S$($2,{color:J.colors.text.secondary,children:Z},void 0,!1,void 0,this)},void 0,!1,void 0,this),G>0&&S$(L7,{marginBottom:0,children:S$($2,{color:J.colors.text.muted,dimColor:!0,children:["... ",G," lines hidden ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this),S$(rW,{maxWidth:U,maxHeight:X,children:q.map((F,O)=>{let H=O+G+1;return S$(L7,{flexDirection:"row",children:[Y&&S$($2,{color:J.colors.text.muted,dimColor:!0,wrap:"truncate",children:[String(H).padStart(W-1," ")," "]},void 0,!0,void 0,this),F.trim()===""?S$($2,{wrap:"wrap",children:" "},void 0,!1,void 0,this):bN(F,Z,J.colors.syntax)]},O,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});import{Box as oW,Text as Z2}from"ink";import AN from"react";import{jsxDEV as L1}from"react/jsx-dev-runtime";function RN($){let Z=$.split(`
|
|
2822
|
+
`),Y=[],Q=0,X=0;for(let J of Z){if(J.startsWith("---")||J.startsWith("+++"))continue;if(J.startsWith("@@")){let q=J.match(/@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@/);if(q)Q=parseInt(q[1],10),X=parseInt(q[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 lZ=AN.memo(({patch:$,startLine:Z,matchLine:Y,terminalWidth:Q,maxLines:X=20})=>{let J=m0(),q=RN($),K=Math.max(...q.map((H)=>H.lineNumber||0)).toString().length+1,W=q.length,U=W>X,F=U?q.slice(0,X):q,O=W-X;return L1(oW,{flexDirection:"column",marginTop:1,marginBottom:1,children:[L1(Z2,{color:J.colors.muted,children:"─".repeat(Math.max(0,Math.min(60,Q)))},void 0,!1,void 0,this),U&&L1(Z2,{color:J.colors.info,children:["\uD83D\uDCCA 显示前 ",X," 行,共 ",W," 行 diff"]},void 0,!0,void 0,this),U&&L1(Z2,{color:J.colors.muted,children:"─".repeat(Math.max(0,Math.min(60,Q)))},void 0,!1,void 0,this),F.map((H,_)=>{if(H.type==="header")return L1(Z2,{color:J.colors.muted,dimColor:!0,children:H.content},_,!1,void 0,this);let z=H.lineNumber?H.lineNumber.toString().padStart(K," "):" ".repeat(K),w=" ",B,L;if(H.type==="add")w="+",L=J.colors.success,B=void 0;else if(H.type==="remove")w="-",L=J.colors.error,B=void 0;else L=J.colors.text.primary;let V=Math.max(0,Q-K-2),D=H.content;if(D.length>V)D=D.substring(0,V-3)+"...";return L1(Z2,{color:L,backgroundColor:B,children:[L1(Z2,{dimColor:!0,children:z},void 0,!1,void 0,this),L1(Z2,{children:w},void 0,!1,void 0,this),L1(Z2,{children:[" ",D]},void 0,!0,void 0,this)]},_,!0,void 0,this)}),U&&L1(oW,{marginTop:1,children:L1(Z2,{color:J.colors.warning,dimColor:!0,children:["⚠️ 已隐藏剩余 ",O," 行 diff(总共 ",W," 行)"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),L1(Z2,{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 m1}from"ink";import DN from"react";import VN from"string-width";var P4=($)=>{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 VN(Z)},sW=($,Z,Y="...")=>{if(P4($)<=Z)return $;if(Z<=Y.length)return Y.substring(0,Z);let X=0,J=$.length,q="";while(X<=J){let G=Math.floor((X+J)/2),K=$.substring(0,G);if(P4(K)<=Z-Y.length)q=K,X=G+1;else J=G-1}return q+Y},tW=($)=>{return/[*_~`<[\]https?:]/.test($)};import{jsxDEV as N1,Fragment as jN}from"react/jsx-dev-runtime";var iZ=2,aZ=1,rZ=2;function nZ($,Z){return`inline-${$}-${Z}`}var MN=({text:$})=>{let Z=m0();if(!tW($))return N1(m1,{children:$},void 0,!1,void 0,this);let Y=[],Q=0,X=0,J=0,q=/(\*\*.*?\*\*|\*(?!\s).*?(?<!\s)\*|_(?!\s).*?(?<!\s)_|~~.*?~~|`+[^`]+`+|\[.*?\]\(.*?\)|https?:\/\/\S+)/g,G;while((G=q.exec($))!==null){if(G.index>Q){let F=$.slice(Q,G.index);Y.push(N1(m1,{children:F},nZ("text",X++),!1,void 0,this))}let K=G[0],W=null,U=nZ("match",J++);try{if(K.startsWith("**")&&K.endsWith("**")&&K.length>iZ*2)W=N1(m1,{bold:!0,children:K.slice(iZ,-iZ)},U,!1,void 0,this);else if(K.length>aZ*2&&(K.startsWith("*")&&K.endsWith("*")||K.startsWith("_")&&K.endsWith("_"))){let F=$.substring(G.index-1,G.index),O=$.substring(q.lastIndex,q.lastIndex+1);if(!(/\w/.test(F)||/\w/.test(O)||/[./\\]/.test(F+O)))W=N1(m1,{italic:!0,children:K.slice(aZ,-aZ)},U,!1,void 0,this)}else if(K.startsWith("~~")&&K.endsWith("~~")&&K.length>rZ*2)W=N1(m1,{strikethrough:!0,children:K.slice(rZ,-rZ)},U,!1,void 0,this);else if(K.startsWith("`")&&K.endsWith("`")){let F=K.match(/^(`+)([^`]+)\1$/);if(F&&F[2])W=N1(m1,{color:Z.colors.syntax.keyword,backgroundColor:Z.colors.background.secondary,bold:!0,children:` ${F[2]} `},U,!1,void 0,this)}else if(K.startsWith("[")&&K.includes("](")&&K.endsWith(")")){let F=K.match(/\[(.*?)\]\((.*?)\)/);if(F){let O=F[1],H=F[2];W=N1(m1,{children:[O,N1(m1,{color:Z.colors.info,children:[" (",H,")"]},void 0,!0,void 0,this)]},U,!0,void 0,this)}}else if(K.match(/^https?:\/\//))W=N1(m1,{color:Z.colors.info,children:K},U,!1,void 0,this)}catch(F){console.error("InlineRenderer 解析错误:",K,F),W=null}Y.push(W??N1(m1,{children:K},U,!1,void 0,this)),Q=q.lastIndex}if(Q<$.length){let K=$.slice(Q);Y.push(N1(m1,{children:K},nZ("text",X++),!1,void 0,this))}return N1(jN,{children:Y.filter((K)=>K!==null)},void 0,!1,void 0,this)},b1=DN.memo(MN);import{Box as oZ,Text as eW}from"ink";import IN from"react";import{jsxDEV as k3}from"react/jsx-dev-runtime";var yN=({itemText:$,type:Z,marker:Y,leadingWhitespace:Q=""})=>{let X=Z==="ol"?`${Y}. `:`${Y} `,J=X.length,q=Q.length;return k3(oZ,{paddingLeft:q+1,flexDirection:"row",children:[k3(oZ,{width:J,children:k3(eW,{children:X},void 0,!1,void 0,this)},void 0,!1,void 0,this),k3(oZ,{flexGrow:1,children:k3(eW,{wrap:"wrap",children:k3(b1,{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)},sZ=IN.memo(yN);import{Box as vN,Text as C4}from"ink";import tZ from"react";import{jsxDEV as A1}from"react/jsx-dev-runtime";var $U=tZ.memo(({headers:$,rows:Z,terminalWidth:Y})=>{let Q=m0();if($.length===0||Z.length===0)return null;let X=$.map((O,H)=>{let _=P4(O),z=Math.max(...Z.map((w)=>P4(w[H]||"")));return Math.max(_,z)+2}),J=$.length+1,q=X.reduce((O,H)=>O+H,0)+J,G=q>Y?Y/q:1,K=X.map((O)=>Math.floor(O*G)),W=(O,H,_=!1)=>{let z=Math.max(0,H-2),w=P4(O),B=O;if(w>z)B=sW(O,z);let L=P4(B),V=Math.max(0,z-L);return A1(C4,{children:[_?A1(C4,{bold:!0,color:Q.colors.primary,children:A1(b1,{text:B},void 0,!1,void 0,this)},void 0,!1,void 0,this):A1(b1,{text:B},void 0,!1,void 0,this)," ".repeat(V)]},void 0,!0,void 0,this)},U=(O)=>{let _={top:{left:"┌",middle:"┬",right:"┐",horizontal:"─"},middle:{left:"├",middle:"┼",right:"┤",horizontal:"─"},bottom:{left:"└",middle:"┴",right:"┘",horizontal:"─"}}[O],z=K.map((B)=>_.horizontal.repeat(B)),w=_.left+z.join(_.middle)+_.right;return A1(C4,{color:Q.colors.text.muted,dimColor:!0,children:w},void 0,!1,void 0,this)},F=(O,H=!1)=>{let _=O.map((z,w)=>{let B=K[w]||0;return W(z||"",B,H)});return A1(C4,{children:[A1(C4,{color:Q.colors.text.muted,children:"│ "},void 0,!1,void 0,this),_.map((z,w)=>A1(tZ.Fragment,{children:[z,w<_.length-1&&A1(C4,{color:Q.colors.text.muted,children:" │ "},void 0,!1,void 0,this)]},w,!0,void 0,this)),A1(C4,{color:Q.colors.text.muted,children:" │"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};return A1(vN,{flexDirection:"column",marginY:1,children:[U("top"),F($,!0),U("middle"),Z.map((O,H)=>A1(tZ.Fragment,{children:F(O)},H,!1,void 0,this)),U("bottom")]},void 0,!0,void 0,this)});import{jsxDEV as h}from"react/jsx-dev-runtime";var TN=($,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:" "}}},EN=S4.memo(({content:$,language:Z,terminalWidth:Y,isPending:Q=!1,availableHeight:X})=>{let J=m0();if(Q&&X!==void 0){let q=$.split(`
|
|
2823
2823
|
`),G=4,K=Math.max(1,X-4);if(q.length>K){let W=q.slice(0,K).join(`
|
|
2824
|
-
`);return h(b0,{flexDirection:"column",flexShrink:0,children:[h(b7,{content:W,language:Z,showLineNumbers:!0,terminalWidth:Y},void 0,!1,void 0,this),h(r0,{color:J.colors.text.muted,dimColor:!0,children:"... generating more code ..."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}}return h(b7,{content:$,language:Z,showLineNumbers:!0,terminalWidth:Y},void 0,!1,void 0,this)}),
|
|
2824
|
+
`);return h(b0,{flexDirection:"column",flexShrink:0,children:[h(b7,{content:W,language:Z,showLineNumbers:!0,terminalWidth:Y},void 0,!1,void 0,this),h(r0,{color:J.colors.text.muted,dimColor:!0,children:"... generating more code ..."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}}return h(b7,{content:$,language:Z,showLineNumbers:!0,terminalWidth:Y},void 0,!1,void 0,this)}),PN=S4.memo(({content:$,level:Z})=>{let Y=m0();switch(Z){case 1:return h(r0,{bold:!0,color:Y.colors.primary,children:h(b1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 2:return h(r0,{bold:!0,color:Y.colors.primary,children:h(b1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 3:return h(r0,{bold:!0,color:Y.colors.text.primary,children:h(b1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 4:return h(r0,{italic:!0,color:Y.colors.text.muted,children:h(b1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);default:return h(r0,{children:h(b1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)}}),CN=S4.memo(({terminalWidth:$})=>{let Z=m0(),Y=Math.max(0,Math.min($-4,80));return h(r0,{dimColor:!0,color:Z.colors.text.muted,children:"─".repeat(Y)},void 0,!1,void 0,this)}),SN=S4.memo(({content:$})=>{return h(r0,{wrap:"wrap",children:h(b1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)}),kN=S4.memo(({content:$})=>{let Z=m0();return h(b0,{flexDirection:"row",gap:1,children:[h(r0,{color:Z.colors.info,children:"⏳"},void 0,!1,void 0,this),h(r0,{color:Z.colors.text.muted,italic:!0,children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}),fN=S4.memo(({detail:$,terminalWidth:Z})=>{let Y=m0(),Q=50,X=$.split(`
|
|
2825
2825
|
`);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,q=J?X.slice(0,50):X,G=q.join(`
|
|
2826
|
-
`),K=G.includes("<<<DIFF>>>"),W=G.includes("```");if(K){let U=G.match(/<<<DIFF>>>\s*({[\s\S]*?})\s*<<<\/DIFF>>>/);if(U)try{let F=JSON.parse(U[1]);return h(b0,{flexDirection:"column",children:[h(lZ,{patch:F.patch,startLine:F.startLine,matchLine:F.matchLine,terminalWidth:Z},void 0,!1,void 0,this),J&&h(b0,{marginTop:1,children:h(r0,{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=G.match(/```(\w+)?\s*\n([\s\S]*?)\n```/);if(U){let F=U[1]||"text",O=U[2];return h(b0,{flexDirection:"column",children:[h(b7,{content:O,language:F,showLineNumbers:!1,terminalWidth:Z},void 0,!1,void 0,this),J&&h(b0,{marginTop:1,children:h(r0,{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 h(b0,{flexDirection:"column",children:[q.map((U,F)=>h(r0,{color:Y.colors.text.primary,children:U},F,!1,void 0,this)),J&&h(b0,{marginTop:1,children:h(r0,{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
|
|
2827
|
-
`,W);if(F!==-1&&F-W<q)U=F+1;let O=$.slice(U),_=($.slice(0,U).match(/\n/g)||[]).length+1;return{content:O,isTruncated:!0,hiddenLines:_}}var n2=S4.memo(({content:$,role:Z,terminalWidth:Y,metadata:Q,isPending:X=!1,availableTerminalHeight:J,hidePrefix:q=!1,noMargin:G=!1,renderPlainTextOnly:K=!1,streamingLines:W,streamingHiddenLines:U,messageId:F,blocksOverride:O,currentLineOverride:H,streamingMode:_="text",renderCodeBlocksAsPlainText:z=!1})=>{let w=m0(),B=O!==void 0,L=f3(()=>
|
|
2828
|
-
`);if(E===-1)return{completedContent:"",currentLine:S};return{completedContent:S.slice(0,E+1),currentLine:S.slice(E+1)}},[S,X,B,H]),A=ZU({content:"",blocks:[]}),r=f3(()=>{if(B)return O??[];if(m)return m;if(P.current&&P.current.messageId===F)return P.current.blocks;let E=A.current;if(!X||!j.startsWith(E.content)){let s=G4(j);return A.current={content:j,blocks:s},s}if(j===E.content)return E.blocks;let u=j.slice(E.content.length),Z0=G4(u),d=[...E.blocks,...Z0];return A.current={content:j,blocks:d},d},[j,X,B,O]);return h(b0,{flexDirection:"column",marginBottom:I?1:0,flexShrink:0,children:[T&&h(b0,{flexDirection:"row",flexShrink:0,children:[h(b0,{width:R,flexShrink:0},void 0,!1,void 0,this),h(r0,{color:w.colors.text.muted,dimColor:!0,children:["↑ ",g," lines above (streaming...)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),r.map((E,u)=>{if(E.type==="empty")return h(b0,{height:1,flexShrink:0},u,!1,void 0,this);return h(b0,{flexDirection:"row",flexShrink:0,children:[u===0&&!q&&h(b0,{marginRight:1,flexShrink:0,children:h(r0,{color:V,bold:!0,children:D},void 0,!1,void 0,this)},void 0,!1,void 0,this),(u>0||q)&&h(b0,{width:R,flexShrink:0},void 0,!1,void 0,this),h(b0,{flexGrow:1,flexShrink:0,children:E.type==="code"?z?h(r0,{wrap:"wrap",children:E.content},void 0,!1,void 0,this):h(TN,{content:E.content,language:E.language,terminalWidth:Y-R,isPending:X,availableHeight:J},void 0,!1,void 0,this):E.type==="table"&&E.tableData?h($U,{headers:E.tableData.headers,rows:E.tableData.rows,terminalWidth:Y-R},void 0,!1,void 0,this):E.type==="heading"?h(EN,{content:E.content,level:E.level||1},void 0,!1,void 0,this):E.type==="list"?h(sZ,{type:E.listType||"ul",marker:E.marker||"-",itemText:E.content,leadingWhitespace:" ".repeat(E.indentation||0)},void 0,!1,void 0,this):E.type==="hr"?h(PN,{terminalWidth:Y-R},void 0,!1,void 0,this):E.type==="diff"&&E.diffData?h(lZ,{patch:E.diffData.patch,startLine:E.diffData.startLine,matchLine:E.diffData.matchLine,terminalWidth:Y-R},void 0,!1,void 0,this):E.type==="command-message"?h(SN,{content:E.content},void 0,!1,void 0,this):h(CN,{content:E.content},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},u,!0,void 0,this)}),M&&h(b0,{flexDirection:"row",flexShrink:0,children:[r.length===0&&!q?h(b0,{marginRight:1,flexShrink:0,children:h(r0,{color:V,bold:!0,children:D},void 0,!1,void 0,this)},void 0,!1,void 0,this):h(b0,{width:R,flexShrink:0},void 0,!1,void 0,this),h(b0,{flexGrow:1,flexShrink:0,children:h(r0,{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 u0,Fragment as uN}from"react/jsx-dev-runtime";var mN=$Y.memo(({label:$,isSelected:Z})=>u0(g1,{color:Z?"yellow":void 0,children:$},void 0,!1,void 0,this)),gN=$Y.memo(({details:$,headerColor:Z,isPlanModeExit:Y,isPlanModeEnter:Q,terminalWidth:X})=>u0(uN,{children:[$.title&&u0(R1,{marginBottom:1,children:u0(g1,{bold:!0,children:$.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),u0(R1,{marginBottom:1,children:u0(g1,{children:$.message},void 0,!1,void 0,this)},void 0,!1,void 0,this),($.planContent||$.details)&&u0(R1,{flexDirection:"column",marginBottom:1,borderStyle:"single",borderColor:Z,padding:1,children:[u0(g1,{bold:!0,color:Z,children:Y?"\uD83D\uDCCB Implementation Plan:":Q?"\uD83D\uDCDD Details:":"\uD83D\uDCC4 Operation Details:"},void 0,!1,void 0,this),u0(R1,{marginTop:1,children:u0(n2,{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&&u0(R1,{flexDirection:"column",marginBottom:1,children:[u0(g1,{color:"red",bold:!0,children:"⚠️ 风险提示:"},void 0,!1,void 0,this),$.risks.map((J,q)=>u0(R1,{marginLeft:2,children:u0(g1,{color:"red",children:["• ",J]},void 0,!0,void 0,this)},q,!1,void 0,this))]},void 0,!0,void 0,this),$.affectedFiles&&$.affectedFiles.length>0&&u0(R1,{flexDirection:"column",marginBottom:1,children:[u0(g1,{color:"yellow",children:"\uD83D\uDCC1 影响的文件:"},void 0,!1,void 0,this),$.affectedFiles.slice(0,3).map((J,q)=>u0(R1,{marginLeft:2,children:u0(g1,{children:["• ",J]},void 0,!0,void 0,this)},q,!1,void 0,this)),$.affectedFiles.length>3&&u0(R1,{marginLeft:2,children:u0(g1,{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)),QU=$Y.memo(({details:$,onResponse:Z})=>{let{stdout:Y}=xN(),Q=Y.columns||80,J=Z1()==="confirmation-prompt",q=Z$(!1),G=$.type==="exitPlanMode",K=$.type==="enterPlanMode",W=$.type==="maxTurnsExceeded";hN((O,H)=>{if(H.ctrl&&O==="c"||H.meta&&O==="c"){q();return}if(H.escape){Z({approved:!1,reason:"用户取消"});return}let _=O.toLowerCase();if(G){if(_==="y"){Z({approved:!0,targetMode:"autoEdit"});return}if(_==="s"){Z({approved:!0,targetMode:"default"});return}if(_==="n"){Z({approved:!1,reason:"方案需要改进"});return}}else if(K){if(_==="y"){Z({approved:!0});return}if(_==="n"){Z({approved:!1,reason:"用户拒绝进入 Plan 模式"});return}}else if(W){if(_==="y"){Z({approved:!0});return}if(_==="n"){Z({approved:!1,reason:"用户选择停止"});return}}else{if(_==="y"){Z({approved:!0,scope:"once"});return}if(_==="s"){Z({approved:!0,scope:"session"});return}if(_==="n"){Z({approved:!1,reason:"用户拒绝"});return}}},{isActive:J});let U=YU(()=>{if(G)return[{key:"approve-auto",label:"[Y] Yes, execute with auto-edit mode",value:{approved:!0,targetMode:"autoEdit"}},{key:"approve-default",label:"[S] Yes, execute with default mode (ask for each operation)",value:{approved:!0,targetMode:"default"}},{key:"reject",label:"[N] No, keep planning",value:{approved:!1,reason:"方案需要改进"}}];if(K)return[{key:"approve",label:"[Y] Yes, enter Plan mode",value:{approved:!0}},{key:"reject",label:"[N] No, proceed directly",value:{approved:!1,reason:"用户拒绝进入 Plan 模式"}}];if(W)return[{key:"continue",label:"[Y] Yes, continue",value:{approved:!0}},{key:"stop",label:"[N] No, stop here",value:{approved:!1,reason:"用户选择停止"}}];return[{key:"approve-once",label:"[Y] Yes (once only)",value:{approved:!0,scope:"once"}},{key:"approve-session",label:"[S] Yes, remember for this project (Shift+Tab)",value:{approved:!0,scope:"session"}},{key:"reject",label:"[N] No",value:{approved:!1,reason:"用户拒绝"}}]},[G,K,W]),F=YU(()=>{if(G)return{color:"cyan",title:"\uD83D\uDD35 Plan Mode - Review Implementation Plan"};if(K)return{color:"magenta",title:"\uD83D\uDFE3 Enter Plan Mode?"};if(W)return{color:"yellow",title:"⚡ Max Turns Exceeded"};return{color:"yellow",title:"\uD83D\uDD14 Confirmation Required"}},[G,K,W]);return u0(R1,{flexDirection:"column",borderStyle:"round",borderColor:J?F.color:"gray",padding:1,children:[u0(R1,{marginBottom:1,children:u0(g1,{bold:!0,color:F.color,children:F.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),u0(gN,{details:$,headerColor:F.color,isPlanModeExit:G,isPlanModeEnter:K,terminalWidth:Q},void 0,!1,void 0,this),u0(R1,{flexDirection:"column",children:[u0(g1,{color:"gray",children:"使用 ↑ ↓ 选择,回车确认(支持 Y/S/N 快捷键,ESC 取消)"},void 0,!1,void 0,this),u0(pN,{items:U,isFocused:J,itemComponent:mN,onSelect:(O)=>{Z(O.value)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});t$();t4();q4();import{Box as V0,Text as F0,useInput as dN}from"ink";import XU from"ink-text-input";import{useState as w2}from"react";import{jsxDEV as x}from"react/jsx-dev-runtime";var m8=[{action:"add",description:"Add a new hook"},{action:"status",description:"Show hooks status"},{action:"list",description:"List all configured hooks"}],A7=[{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"}],R7=[{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"}],cN=[`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"],JU=({onClose:$,onSave:Z})=>{let Y=u$.getTheme(),[Q,X]=w2("action"),[J,q]=w2(0),[G,K]=w2(0),[W,U]=w2(0),[F,O]=w2(""),[H,_]=w2(""),[z,w]=w2(null),[B,L]=w2(!1),[V,D]=w2(null),R=m8[J],y=R7[G],I=A7[W],N=()=>{if(V){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}};dN((j,M)=>{if(M.escape){N();return}if(Q==="action"){if(M.upArrow)q((A)=>A>0?A-1:m8.length-1);else if(M.downArrow)q((A)=>A<m8.length-1?A+1:0);else if(M.return)P()}else if(Q==="event"){if(M.upArrow)K((A)=>A>0?A-1:R7.length-1);else if(M.downArrow)K((A)=>A<R7.length-1?A+1:0);else if(M.return)X("matcher")}else if(Q==="location"){if(M.upArrow)U((A)=>A>0?A-1:A7.length-1);else if(M.downArrow)U((A)=>A<A7.length-1?A+1:0);else if(M.return)X("confirm")}else if(Q==="confirm"){if(M.return)g()}});let P=()=>{let j=m8[J].action;if(j==="add")X("event");else if(j==="status")m();else if(j==="list")e()},m=()=>{let j=R0.getInstance(),M=j.isEnabled(),A=j.getConfig(),r={};for(let u of Object.values(i1)){let Z0=A[u];if(Z0&&Array.isArray(Z0)){let d=Z0.reduce((s,k)=>s+(k.hooks?.length||0),0);if(d>0)r[u]=d}}let E=[`Status: ${M?"✅ Enabled":"⏸️ Disabled"}`,""];if(Object.keys(r).length>0){E.push("Configured hooks:");for(let[u,Z0]of Object.entries(r))E.push(` ${u}: ${Z0} hook(s)`)}else E.push("No hooks configured");D(E.join(`
|
|
2826
|
+
`),K=G.includes("<<<DIFF>>>"),W=G.includes("```");if(K){let U=G.match(/<<<DIFF>>>\s*({[\s\S]*?})\s*<<<\/DIFF>>>/);if(U)try{let F=JSON.parse(U[1]);return h(b0,{flexDirection:"column",children:[h(lZ,{patch:F.patch,startLine:F.startLine,matchLine:F.matchLine,terminalWidth:Z},void 0,!1,void 0,this),J&&h(b0,{marginTop:1,children:h(r0,{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=G.match(/```(\w+)?\s*\n([\s\S]*?)\n```/);if(U){let F=U[1]||"text",O=U[2];return h(b0,{flexDirection:"column",children:[h(b7,{content:O,language:F,showLineNumbers:!1,terminalWidth:Z},void 0,!1,void 0,this),J&&h(b0,{marginTop:1,children:h(r0,{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 h(b0,{flexDirection:"column",children:[q.map((U,F)=>h(r0,{color:Y.colors.text.primary,children:U},F,!1,void 0,this)),J&&h(b0,{marginTop:1,children:h(r0,{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 hN($,Z,Y,Q=80){if(!Y||Z===void 0||Z<=0)return{content:$,isTruncated:!1,hiddenLines:0};let J=Math.max(1,Z-8),q=Math.max(40,Q*0.8),G=J*q;if($.length<=G)return{content:$,isTruncated:!1,hiddenLines:0};let K=Math.floor(G*0.9),W=$.length-K,U=W,F=$.indexOf(`
|
|
2827
|
+
`,W);if(F!==-1&&F-W<q)U=F+1;let O=$.slice(U),_=($.slice(0,U).match(/\n/g)||[]).length+1;return{content:O,isTruncated:!0,hiddenLines:_}}var n2=S4.memo(({content:$,role:Z,terminalWidth:Y,metadata:Q,isPending:X=!1,availableTerminalHeight:J,hidePrefix:q=!1,noMargin:G=!1,renderPlainTextOnly:K=!1,streamingLines:W,streamingHiddenLines:U,messageId:F,blocksOverride:O,currentLineOverride:H,streamingMode:_="text",renderCodeBlocksAsPlainText:z=!1})=>{let w=m0(),B=O!==void 0,L=f3(()=>TN(Z,w.colors,Q),[Z,w.colors,Q]),{color:V,prefix:D}=L,R=D.length+1,y=Z==="tool"&&Q?.phase==="start",I=!G&&!y,N=f3(()=>{if(!K)return[];return $.split(/\r?\n/)},[$,K]);if(!B&&X){let E=W??$.split(/\r?\n/),u=U??0,Z0=!1,d=!1,s=!1;if(_!=="text")Z0=_==="code",d=_==="diff",s=_==="table";return h(b0,{flexDirection:"column",marginBottom:I?1:0,flexShrink:0,children:[u>0&&h(b0,{flexDirection:"row",flexShrink:0,children:[h(b0,{width:R,flexShrink:0},void 0,!1,void 0,this),h(r0,{color:w.colors.text.muted,dimColor:!0,children:["↑ ",u," lines above (streaming...)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),E.map((k,a)=>{if(_==="text"){if(k.match(D0.codeBlock))Z0=!Z0;else if(k.match(D0.diffStart))d=!0;else if(k.match(D0.diffEnd))d=!1;else if(k.match(D0.table))s=!0;else if(s&&!k.match(D0.table))s=!1}let n=_==="text"&&!Z0&&!d&&!s,U0=n?k.match(D0.ulItem):null,M0=n?k.match(D0.olItem):null,$$=U0??M0;return h(b0,{flexDirection:"row",flexShrink:0,children:[a===0&&!q?h(b0,{marginRight:1,flexShrink:0,children:h(r0,{color:V,bold:!0,children:D},void 0,!1,void 0,this)},void 0,!1,void 0,this):h(b0,{width:R,flexShrink:0},void 0,!1,void 0,this),h(b0,{flexGrow:1,flexShrink:0,children:$$?h(sZ,{type:U0?"ul":"ol",marker:$$[2],itemText:$$[3],leadingWhitespace:$$[1]},void 0,!1,void 0,this):h(r0,{wrap:"wrap",children:k===""?" ":k},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},a,!0,void 0,this)})]},void 0,!0,void 0,this)}if(!B&&K)return h(b0,{flexDirection:"column",marginBottom:I?1:0,flexShrink:0,children:N.map((E,u)=>h(b0,{flexDirection:"row",flexShrink:0,children:[u===0&&!q?h(b0,{marginRight:1,flexShrink:0,children:h(r0,{color:V,bold:!0,children:D},void 0,!1,void 0,this)},void 0,!1,void 0,this):h(b0,{width:R,flexShrink:0},void 0,!1,void 0,this),h(b0,{flexGrow:1,flexShrink:0,children:h(r0,{wrap:"wrap",children:E===""?" ":E},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},u,!0,void 0,this))},void 0,!1,void 0,this);let P=ZU(null);eZ(()=>{P.current=null},[F]);let m=f3(()=>{if(B)return null;if(!F)return null;return sY(F)},[F,B]);eZ(()=>{if(B)return;if(!m||!F)return;P.current={messageId:F,blocks:m}},[m,F,B]),eZ(()=>{if(B)return;if(!m||!F)return;eY(F)},[m,F,B]);let e=f3(()=>B?{content:$,isTruncated:!1,hiddenLines:0}:hN($,J,X,Y),[$,J,X,Y,B]),{content:S,isTruncated:T,hiddenLines:g}=e;if(!B&&Z==="tool"&&Q&&"detail"in Q){let E=Q;if(E.detail)return h(b0,{flexDirection:"column",marginBottom:G?0:1,children:[h(b0,{flexDirection:"row",children:[h(b0,{marginRight:1,children:h(r0,{color:V,bold:!0,children:D},void 0,!1,void 0,this)},void 0,!1,void 0,this),h(r0,{color:V,children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h(b0,{marginLeft:D.length+1,children:h(fN,{detail:E.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}=f3(()=>{if(B)return{completedContent:"",currentLine:H??""};if(!X)return{completedContent:S,currentLine:""};let E=S.lastIndexOf(`
|
|
2828
|
+
`);if(E===-1)return{completedContent:"",currentLine:S};return{completedContent:S.slice(0,E+1),currentLine:S.slice(E+1)}},[S,X,B,H]),A=ZU({content:"",blocks:[]}),r=f3(()=>{if(B)return O??[];if(m)return m;if(P.current&&P.current.messageId===F)return P.current.blocks;let E=A.current;if(!X||!j.startsWith(E.content)){let s=G4(j);return A.current={content:j,blocks:s},s}if(j===E.content)return E.blocks;let u=j.slice(E.content.length),Z0=G4(u),d=[...E.blocks,...Z0];return A.current={content:j,blocks:d},d},[j,X,B,O]);return h(b0,{flexDirection:"column",marginBottom:I?1:0,flexShrink:0,children:[T&&h(b0,{flexDirection:"row",flexShrink:0,children:[h(b0,{width:R,flexShrink:0},void 0,!1,void 0,this),h(r0,{color:w.colors.text.muted,dimColor:!0,children:["↑ ",g," lines above (streaming...)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),r.map((E,u)=>{if(E.type==="empty")return h(b0,{height:1,flexShrink:0},u,!1,void 0,this);return h(b0,{flexDirection:"row",flexShrink:0,children:[u===0&&!q&&h(b0,{marginRight:1,flexShrink:0,children:h(r0,{color:V,bold:!0,children:D},void 0,!1,void 0,this)},void 0,!1,void 0,this),(u>0||q)&&h(b0,{width:R,flexShrink:0},void 0,!1,void 0,this),h(b0,{flexGrow:1,flexShrink:0,children:E.type==="code"?z?h(r0,{wrap:"wrap",children:E.content},void 0,!1,void 0,this):h(EN,{content:E.content,language:E.language,terminalWidth:Y-R,isPending:X,availableHeight:J},void 0,!1,void 0,this):E.type==="table"&&E.tableData?h($U,{headers:E.tableData.headers,rows:E.tableData.rows,terminalWidth:Y-R},void 0,!1,void 0,this):E.type==="heading"?h(PN,{content:E.content,level:E.level||1},void 0,!1,void 0,this):E.type==="list"?h(sZ,{type:E.listType||"ul",marker:E.marker||"-",itemText:E.content,leadingWhitespace:" ".repeat(E.indentation||0)},void 0,!1,void 0,this):E.type==="hr"?h(CN,{terminalWidth:Y-R},void 0,!1,void 0,this):E.type==="diff"&&E.diffData?h(lZ,{patch:E.diffData.patch,startLine:E.diffData.startLine,matchLine:E.diffData.matchLine,terminalWidth:Y-R},void 0,!1,void 0,this):E.type==="command-message"?h(kN,{content:E.content},void 0,!1,void 0,this):h(SN,{content:E.content},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},u,!0,void 0,this)}),M&&h(b0,{flexDirection:"row",flexShrink:0,children:[r.length===0&&!q?h(b0,{marginRight:1,flexShrink:0,children:h(r0,{color:V,bold:!0,children:D},void 0,!1,void 0,this)},void 0,!1,void 0,this):h(b0,{width:R,flexShrink:0},void 0,!1,void 0,this),h(b0,{flexGrow:1,flexShrink:0,children:h(r0,{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 u0,Fragment as dN}from"react/jsx-dev-runtime";var gN=$Y.memo(({label:$,isSelected:Z})=>u0(g1,{color:Z?"yellow":void 0,children:$},void 0,!1,void 0,this)),uN=$Y.memo(({details:$,headerColor:Z,isPlanModeExit:Y,isPlanModeEnter:Q,terminalWidth:X})=>u0(dN,{children:[$.title&&u0(R1,{marginBottom:1,children:u0(g1,{bold:!0,children:$.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),u0(R1,{marginBottom:1,children:u0(g1,{children:$.message},void 0,!1,void 0,this)},void 0,!1,void 0,this),($.planContent||$.details)&&u0(R1,{flexDirection:"column",marginBottom:1,borderStyle:"single",borderColor:Z,padding:1,children:[u0(g1,{bold:!0,color:Z,children:Y?"\uD83D\uDCCB Implementation Plan:":Q?"\uD83D\uDCDD Details:":"\uD83D\uDCC4 Operation Details:"},void 0,!1,void 0,this),u0(R1,{marginTop:1,children:u0(n2,{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&&u0(R1,{flexDirection:"column",marginBottom:1,children:[u0(g1,{color:"red",bold:!0,children:"⚠️ 风险提示:"},void 0,!1,void 0,this),$.risks.map((J,q)=>u0(R1,{marginLeft:2,children:u0(g1,{color:"red",children:["• ",J]},void 0,!0,void 0,this)},q,!1,void 0,this))]},void 0,!0,void 0,this),$.affectedFiles&&$.affectedFiles.length>0&&u0(R1,{flexDirection:"column",marginBottom:1,children:[u0(g1,{color:"yellow",children:"\uD83D\uDCC1 影响的文件:"},void 0,!1,void 0,this),$.affectedFiles.slice(0,3).map((J,q)=>u0(R1,{marginLeft:2,children:u0(g1,{children:["• ",J]},void 0,!0,void 0,this)},q,!1,void 0,this)),$.affectedFiles.length>3&&u0(R1,{marginLeft:2,children:u0(g1,{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)),QU=$Y.memo(({details:$,onResponse:Z})=>{let{stdout:Y}=pN(),Q=Y.columns||80,J=Z1()==="confirmation-prompt",q=Y$(!1),G=$.type==="exitPlanMode",K=$.type==="enterPlanMode",W=$.type==="maxTurnsExceeded";xN((O,H)=>{if(H.ctrl&&O==="c"||H.meta&&O==="c"){q();return}if(H.escape){Z({approved:!1,reason:"用户取消"});return}let _=O.toLowerCase();if(G){if(_==="y"){Z({approved:!0,targetMode:"autoEdit"});return}if(_==="s"){Z({approved:!0,targetMode:"default"});return}if(_==="n"){Z({approved:!1,reason:"方案需要改进"});return}}else if(K){if(_==="y"){Z({approved:!0});return}if(_==="n"){Z({approved:!1,reason:"用户拒绝进入 Plan 模式"});return}}else if(W){if(_==="y"){Z({approved:!0});return}if(_==="n"){Z({approved:!1,reason:"用户选择停止"});return}}else{if(_==="y"){Z({approved:!0,scope:"once"});return}if(_==="s"){Z({approved:!0,scope:"session"});return}if(_==="n"){Z({approved:!1,reason:"用户拒绝"});return}}},{isActive:J});let U=YU(()=>{if(G)return[{key:"approve-auto",label:"[Y] Yes, execute with auto-edit mode",value:{approved:!0,targetMode:"autoEdit"}},{key:"approve-default",label:"[S] Yes, execute with default mode (ask for each operation)",value:{approved:!0,targetMode:"default"}},{key:"reject",label:"[N] No, keep planning",value:{approved:!1,reason:"方案需要改进"}}];if(K)return[{key:"approve",label:"[Y] Yes, enter Plan mode",value:{approved:!0}},{key:"reject",label:"[N] No, proceed directly",value:{approved:!1,reason:"用户拒绝进入 Plan 模式"}}];if(W)return[{key:"continue",label:"[Y] Yes, continue",value:{approved:!0}},{key:"stop",label:"[N] No, stop here",value:{approved:!1,reason:"用户选择停止"}}];return[{key:"approve-once",label:"[Y] Yes (once only)",value:{approved:!0,scope:"once"}},{key:"approve-session",label:"[S] Yes, remember for this project (Shift+Tab)",value:{approved:!0,scope:"session"}},{key:"reject",label:"[N] No",value:{approved:!1,reason:"用户拒绝"}}]},[G,K,W]),F=YU(()=>{if(G)return{color:"cyan",title:"\uD83D\uDD35 Plan Mode - Review Implementation Plan"};if(K)return{color:"magenta",title:"\uD83D\uDFE3 Enter Plan Mode?"};if(W)return{color:"yellow",title:"⚡ Max Turns Exceeded"};return{color:"yellow",title:"\uD83D\uDD14 Confirmation Required"}},[G,K,W]);return u0(R1,{flexDirection:"column",borderStyle:"round",borderColor:J?F.color:"gray",padding:1,children:[u0(R1,{marginBottom:1,children:u0(g1,{bold:!0,color:F.color,children:F.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),u0(uN,{details:$,headerColor:F.color,isPlanModeExit:G,isPlanModeEnter:K,terminalWidth:Q},void 0,!1,void 0,this),u0(R1,{flexDirection:"column",children:[u0(g1,{color:"gray",children:"使用 ↑ ↓ 选择,回车确认(支持 Y/S/N 快捷键,ESC 取消)"},void 0,!1,void 0,this),u0(mN,{items:U,isFocused:J,itemComponent:gN,onSelect:(O)=>{Z(O.value)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});t$();t4();q4();import{Box as V0,Text as F0,useInput as cN}from"ink";import XU from"ink-text-input";import{useState as w2}from"react";import{jsxDEV as x}from"react/jsx-dev-runtime";var m8=[{action:"add",description:"Add a new hook"},{action:"status",description:"Show hooks status"},{action:"list",description:"List all configured hooks"}],A7=[{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"}],R7=[{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"}],lN=[`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"],JU=({onClose:$,onSave:Z})=>{let Y=u$.getTheme(),[Q,X]=w2("action"),[J,q]=w2(0),[G,K]=w2(0),[W,U]=w2(0),[F,O]=w2(""),[H,_]=w2(""),[z,w]=w2(null),[B,L]=w2(!1),[V,D]=w2(null),R=m8[J],y=R7[G],I=A7[W],N=()=>{if(V){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}};cN((j,M)=>{if(M.escape){N();return}if(Q==="action"){if(M.upArrow)q((A)=>A>0?A-1:m8.length-1);else if(M.downArrow)q((A)=>A<m8.length-1?A+1:0);else if(M.return)P()}else if(Q==="event"){if(M.upArrow)K((A)=>A>0?A-1:R7.length-1);else if(M.downArrow)K((A)=>A<R7.length-1?A+1:0);else if(M.return)X("matcher")}else if(Q==="location"){if(M.upArrow)U((A)=>A>0?A-1:A7.length-1);else if(M.downArrow)U((A)=>A<A7.length-1?A+1:0);else if(M.return)X("confirm")}else if(Q==="confirm"){if(M.return)g()}});let P=()=>{let j=m8[J].action;if(j==="add")X("event");else if(j==="status")m();else if(j==="list")e()},m=()=>{let j=R0.getInstance(),M=j.isEnabled(),A=j.getConfig(),r={};for(let u of Object.values(i1)){let Z0=A[u];if(Z0&&Array.isArray(Z0)){let d=Z0.reduce((s,k)=>s+(k.hooks?.length||0),0);if(d>0)r[u]=d}}let E=[`Status: ${M?"✅ Enabled":"⏸️ Disabled"}`,""];if(Object.keys(r).length>0){E.push("Configured hooks:");for(let[u,Z0]of Object.entries(r))E.push(` ${u}: ${Z0} hook(s)`)}else E.push("No hooks configured");D(E.join(`
|
|
2829
2829
|
`))},e=()=>{let M=R0.getInstance().getConfig(),A=[],r=!1;for(let E of Object.values(i1)){let u=M[E];if(!u||!Array.isArray(u)||u.length===0)continue;r=!0,A.push(`${E}:`);for(let Z0 of u){let d=Z0.matcher,s="all";if(d?.tools)s=`tools: ${Array.isArray(d.tools)?d.tools.join(", "):d.tools}`;A.push(` [${s}]`);for(let k of Z0.hooks||[])if(k.type==="command")A.push(` → ${k.command}`)}A.push("")}if(!r)A.push("No hooks configured"),A.push(""),A.push("Configure hooks in .blade/settings.local.json");D(A.join(`
|
|
2830
|
-
`))},S=()=>{X("command")},T=()=>{if(!H.trim()){w("Command cannot be empty");return}w(null),X("location")},g=async()=>{L(!0),w(null);try{let j=R0.getInstance(),M=await import("node:fs/promises"),A=await import("node:path"),r=await import("node:os"),E={matcher:F.trim()?{tools:F.trim()}:{},hooks:[{type:"command",command:H.trim()}]},u;switch(I.location){case"local":u=A.join(process.cwd(),".blade","settings.local.json");break;case"project":u=A.join(process.cwd(),".blade","settings.json");break;case"user":u=A.join(r.homedir(),".blade","settings.json");break}await M.mkdir(A.dirname(u),{recursive:!0});let Z0={};try{let a=await M.readFile(u,"utf-8");Z0=JSON.parse(a)}catch{}let d=Z0.hooks||{},s=d[y.event]||[],k={...d,enabled:!0,[y.event]:[...s,E]};if(Z0.hooks=k,await M.writeFile(u,JSON.stringify(Z0,null,2),"utf-8"),await j.reloadConfig(),Z)Z({event:y.event,matcher:F.trim(),command:H.trim()});$()}catch(j){w(`Failed to save hook: ${j instanceof Error?j.message:"Unknown error"}`),L(!1)}};return x(V0,{flexDirection:"column",padding:1,children:[x(V0,{marginBottom:1,children:x(F0,{bold:!0,color:Y.colors.success,children:"Hooks Manager"},void 0,!1,void 0,this)},void 0,!1,void 0,this),x(V0,{marginBottom:1,children:x(F0,{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),V&&x(V0,{flexDirection:"column",marginBottom:1,children:[x(F0,{children:V},void 0,!1,void 0,this),x(V0,{marginTop:1,children:x(F0,{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"&&!V&&x(V0,{flexDirection:"column",children:[x(V0,{flexDirection:"column",marginTop:1,children:m8.map((j,M)=>x(V0,{children:[x(F0,{color:M===J?Y.colors.primary:void 0,bold:M===J,children:[M===J?"❯ ":" ",j.action]},void 0,!0,void 0,this),x(F0,{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),x(V0,{marginTop:1,children:x(F0,{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"&&x(V0,{flexDirection:"column",children:[x(F0,{bold:!0,children:"Select Event:"},void 0,!1,void 0,this),x(V0,{flexDirection:"column",marginTop:1,children:R7.map((j,M)=>x(V0,{children:[x(F0,{color:M===G?Y.colors.primary:void 0,bold:M===G,children:[M===G?"❯ ":" ",j.event]},void 0,!0,void 0,this),x(F0,{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),x(V0,{marginTop:1,children:x(F0,{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"&&x(V0,{marginBottom:1,children:x(F0,{children:["Event:"," ",x(F0,{bold:!0,color:Y.colors.primary,children:y.event},void 0,!1,void 0,this),x(F0,{color:Y.colors.muted,children:[" - ",y.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")&&x(V0,{flexDirection:"column",marginBottom:1,children:[x(F0,{color:Y.colors.muted,children:"Input to command is JSON of tool call arguments."},void 0,!1,void 0,this),x(F0,{color:Y.colors.muted,children:"Exit code 0 - stdout/stderr not shown"},void 0,!1,void 0,this),x(F0,{color:Y.colors.muted,children:"Exit code 2 - show stderr to model and block tool call"},void 0,!1,void 0,this),x(F0,{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"&&x(V0,{flexDirection:"column",children:[x(V0,{children:[x(F0,{bold:!0,children:"Matcher: "},void 0,!1,void 0,this),x(XU,{value:F,onChange:O,onSubmit:S,placeholder:"e.g., Read, Bash, Edit|Write (empty = all tools)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),x(V0,{marginTop:1,children:x(F0,{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),x(V0,{marginTop:1,children:x(F0,{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")&&x(V0,{marginBottom:1,children:x(F0,{children:["Matcher: ",x(F0,{bold:!0,children:F||"(all tools)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q==="command"&&x(V0,{flexDirection:"column",children:[x(V0,{children:x(F0,{bold:!0,children:"Command: "},void 0,!1,void 0,this)},void 0,!1,void 0,this),x(V0,{borderStyle:"single",borderColor:Y.colors.border.light,paddingX:1,marginTop:1,children:x(XU,{value:H,onChange:_,onSubmit:T,placeholder:"Enter shell command..."},void 0,!1,void 0,this)},void 0,!1,void 0,this),x(V0,{flexDirection:"column",marginTop:1,children:[x(F0,{bold:!0,children:"Examples:"},void 0,!1,void 0,this),cN.map((j,M)=>x(F0,{color:Y.colors.muted,children:["• ",j]},M,!0,void 0,this))]},void 0,!0,void 0,this),x(V0,{marginTop:1,children:x(F0,{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"&&x(V0,{flexDirection:"column",children:[x(V0,{flexDirection:"column",borderStyle:"round",borderColor:Y.colors.border.light,paddingX:2,paddingY:1,marginBottom:1,children:[x(F0,{bold:!0,color:Y.colors.primary,children:"Save hook configuration"},void 0,!1,void 0,this),x(F0,{children:" "},void 0,!1,void 0,this),x(F0,{children:[" ","Event: ",y.event," - ",y.description]},void 0,!0,void 0,this),x(F0,{children:[" Matcher: ",F||"(all)"]},void 0,!0,void 0,this),x(F0,{children:[" Command: ",H]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),x(F0,{bold:!0,children:"Where should this hook be saved?"},void 0,!1,void 0,this),x(V0,{flexDirection:"column",marginTop:1,children:A7.map((j,M)=>x(V0,{children:[x(F0,{color:M===W?Y.colors.primary:void 0,bold:M===W,children:[M===W?"❯ ":" ",M+1,". ",j.name]},void 0,!0,void 0,this),x(F0,{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),x(V0,{marginTop:1,children:x(F0,{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"&&x(V0,{flexDirection:"column",children:[x(V0,{flexDirection:"column",borderStyle:"round",borderColor:Y.colors.success,paddingX:2,paddingY:1,children:[x(F0,{bold:!0,children:["Saving hook to ",I.description,"..."]},void 0,!0,void 0,this),x(F0,{children:" "},void 0,!1,void 0,this),x(F0,{children:["Event: ",y.event]},void 0,!0,void 0,this),x(F0,{children:["Matcher: ",F||"(all tools)"]},void 0,!0,void 0,this),x(F0,{children:["Command: ",H]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),x(V0,{marginTop:1,children:x(F0,{color:Y.colors.muted,children:B?"Saving...":"Enter to confirm · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),z&&x(V0,{marginTop:1,children:x(F0,{color:Y.colors.error,children:["❌ ",z]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{useMemoizedFn as zU}from"ahooks";import{Box as Zb,Text as Yb}from"ink";import Qb from"react";import{useMemoizedFn as nN}from"ahooks";import k4 from"chalk";import{Text as oN,useInput as sN}from"ink";import{useEffect as QY,useRef as XY}from"react";var L2={TIMEOUT_MS:100,RAPID_INPUT_THRESHOLD_MS:150,LARGE_INPUT_THRESHOLD:300,MEDIUM_SIZE_MULTI_CHUNK_THRESHOLD:200};import{execSync as h3}from"node:child_process";import{existsSync as lN,readFileSync as ZY}from"node:fs";import{basename as qU,isAbsolute as iN}from"node:path";function GU($){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 KU(){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 aN(){let{commands:$}=KU();try{return h3($.getPath,{encoding:"utf-8"}).trim()}catch(Z){return console.error("Failed to get clipboard path:",Z),null}}function WU($){if($.startsWith('"')&&$.endsWith('"')||$.startsWith("'")&&$.endsWith("'"))return $.slice(1,-1);return $}function UU($){if(process.platform==="win32")return $;let Z="__DOUBLE_BACKSLASH__";return $.replace(/\\\\/g,Z).replace(/\\(.)/g,"$1").replace(new RegExp(Z,"g"),"\\")}function YY($){let Z=WU($.trim()),Y=UU(Z);return/\.(png|jpe?g|gif|webp)$/i.test(Y)}function rN($){let Z=WU($.trim()),Y=UU(Z);if(YY(Y))return Y;return null}async function FU($){let Z=rN($);if(!Z)return null;let Y;try{if(iN(Z))Y=ZY(Z);else{let q=aN();if(q&&Z===qU(q))Y=ZY(q);else return null}}catch(q){return console.error("Failed to read image file:",q),null}let Q=Y.toString("base64"),X=GU(Q),J=qU(Z);return{path:Z,base64:Q,mediaType:X,filename:J}}async function OU(){let $=process.platform,Z={darwin:"pbpaste",linux:"xclip -selection clipboard -o || wl-paste",win32:'powershell -Command "Get-Clipboard"'},Y=Z[$]||Z.linux;try{return h3(Y,{encoding:"utf-8"})||null}catch{return null}}async function HU(){let{commands:$,screenshotPath:Z}=KU();try{if(h3($.checkImage,{stdio:"ignore"}),h3($.saveImage(Z),{stdio:"ignore"}),!lN(Z))return null;let Q=ZY(Z).toString("base64"),X=GU(Q);return h3($.deleteFile(Z),{stdio:"ignore"}),{base64:Q,mediaType:X}}catch(Y){try{h3($.deleteFile(Z),{stdio:"ignore"})}catch{}return null}}import{jsxDEV as $b}from"react/jsx-dev-runtime";var tN=/\r\n/g,eN=/\r/g;function f4($){if(!$.includes("\r"))return $;return $.replace(tN,`
|
|
2831
|
-
`).replace(
|
|
2832
|
-
`)}function h4($,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 _U({value:$,placeholder:Z="",focus:Y=!0,onChange:Q,cursorPosition:X,onChangeCursorPosition:J,onPaste:q,onImagePaste:G,disabledKeys:K=[]}){let W=XY({chunks:[],timeoutId:null,firstInputTime:null,lastInputTime:null,totalLength:0}),U=XY($),F=XY(X);QY(()=>{U.current=$,F.current=X},[$,X]),QY(()=>{return()=>{if(W.current.timeoutId)clearTimeout(W.current.timeoutId)}},[]),QY(()=>{if(X>$.length)J($.length)},[$,X,J]);let O=
|
|
2833
|
-
`),N=V>L2.MEDIUM_SIZE_MULTI_CHUNK_THRESHOLD&&L.length>3;if((V>L2.LARGE_INPUT_THRESHOLD||I||N)&&q){let S=await q(D);if(S?.prompt){let T=f4(S.prompt),{newValue:g,newCursorPosition:j}=h4(T,R,y);Q(g),J(j);return}}let{newValue:m,newCursorPosition:e}=h4(D,R,y);Q(m),J(e)},L2.TIMEOUT_MS);W.current.timeoutId=B});
|
|
2830
|
+
`))},S=()=>{X("command")},T=()=>{if(!H.trim()){w("Command cannot be empty");return}w(null),X("location")},g=async()=>{L(!0),w(null);try{let j=R0.getInstance(),M=await import("node:fs/promises"),A=await import("node:path"),r=await import("node:os"),E={matcher:F.trim()?{tools:F.trim()}:{},hooks:[{type:"command",command:H.trim()}]},u;switch(I.location){case"local":u=A.join(process.cwd(),".blade","settings.local.json");break;case"project":u=A.join(process.cwd(),".blade","settings.json");break;case"user":u=A.join(r.homedir(),".blade","settings.json");break}await M.mkdir(A.dirname(u),{recursive:!0});let Z0={};try{let a=await M.readFile(u,"utf-8");Z0=JSON.parse(a)}catch{}let d=Z0.hooks||{},s=d[y.event]||[],k={...d,enabled:!0,[y.event]:[...s,E]};if(Z0.hooks=k,await M.writeFile(u,JSON.stringify(Z0,null,2),"utf-8"),await j.reloadConfig(),Z)Z({event:y.event,matcher:F.trim(),command:H.trim()});$()}catch(j){w(`Failed to save hook: ${j instanceof Error?j.message:"Unknown error"}`),L(!1)}};return x(V0,{flexDirection:"column",padding:1,children:[x(V0,{marginBottom:1,children:x(F0,{bold:!0,color:Y.colors.success,children:"Hooks Manager"},void 0,!1,void 0,this)},void 0,!1,void 0,this),x(V0,{marginBottom:1,children:x(F0,{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),V&&x(V0,{flexDirection:"column",marginBottom:1,children:[x(F0,{children:V},void 0,!1,void 0,this),x(V0,{marginTop:1,children:x(F0,{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"&&!V&&x(V0,{flexDirection:"column",children:[x(V0,{flexDirection:"column",marginTop:1,children:m8.map((j,M)=>x(V0,{children:[x(F0,{color:M===J?Y.colors.primary:void 0,bold:M===J,children:[M===J?"❯ ":" ",j.action]},void 0,!0,void 0,this),x(F0,{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),x(V0,{marginTop:1,children:x(F0,{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"&&x(V0,{flexDirection:"column",children:[x(F0,{bold:!0,children:"Select Event:"},void 0,!1,void 0,this),x(V0,{flexDirection:"column",marginTop:1,children:R7.map((j,M)=>x(V0,{children:[x(F0,{color:M===G?Y.colors.primary:void 0,bold:M===G,children:[M===G?"❯ ":" ",j.event]},void 0,!0,void 0,this),x(F0,{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),x(V0,{marginTop:1,children:x(F0,{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"&&x(V0,{marginBottom:1,children:x(F0,{children:["Event:"," ",x(F0,{bold:!0,color:Y.colors.primary,children:y.event},void 0,!1,void 0,this),x(F0,{color:Y.colors.muted,children:[" - ",y.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")&&x(V0,{flexDirection:"column",marginBottom:1,children:[x(F0,{color:Y.colors.muted,children:"Input to command is JSON of tool call arguments."},void 0,!1,void 0,this),x(F0,{color:Y.colors.muted,children:"Exit code 0 - stdout/stderr not shown"},void 0,!1,void 0,this),x(F0,{color:Y.colors.muted,children:"Exit code 2 - show stderr to model and block tool call"},void 0,!1,void 0,this),x(F0,{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"&&x(V0,{flexDirection:"column",children:[x(V0,{children:[x(F0,{bold:!0,children:"Matcher: "},void 0,!1,void 0,this),x(XU,{value:F,onChange:O,onSubmit:S,placeholder:"e.g., Read, Bash, Edit|Write (empty = all tools)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),x(V0,{marginTop:1,children:x(F0,{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),x(V0,{marginTop:1,children:x(F0,{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")&&x(V0,{marginBottom:1,children:x(F0,{children:["Matcher: ",x(F0,{bold:!0,children:F||"(all tools)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q==="command"&&x(V0,{flexDirection:"column",children:[x(V0,{children:x(F0,{bold:!0,children:"Command: "},void 0,!1,void 0,this)},void 0,!1,void 0,this),x(V0,{borderStyle:"single",borderColor:Y.colors.border.light,paddingX:1,marginTop:1,children:x(XU,{value:H,onChange:_,onSubmit:T,placeholder:"Enter shell command..."},void 0,!1,void 0,this)},void 0,!1,void 0,this),x(V0,{flexDirection:"column",marginTop:1,children:[x(F0,{bold:!0,children:"Examples:"},void 0,!1,void 0,this),lN.map((j,M)=>x(F0,{color:Y.colors.muted,children:["• ",j]},M,!0,void 0,this))]},void 0,!0,void 0,this),x(V0,{marginTop:1,children:x(F0,{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"&&x(V0,{flexDirection:"column",children:[x(V0,{flexDirection:"column",borderStyle:"round",borderColor:Y.colors.border.light,paddingX:2,paddingY:1,marginBottom:1,children:[x(F0,{bold:!0,color:Y.colors.primary,children:"Save hook configuration"},void 0,!1,void 0,this),x(F0,{children:" "},void 0,!1,void 0,this),x(F0,{children:[" ","Event: ",y.event," - ",y.description]},void 0,!0,void 0,this),x(F0,{children:[" Matcher: ",F||"(all)"]},void 0,!0,void 0,this),x(F0,{children:[" Command: ",H]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),x(F0,{bold:!0,children:"Where should this hook be saved?"},void 0,!1,void 0,this),x(V0,{flexDirection:"column",marginTop:1,children:A7.map((j,M)=>x(V0,{children:[x(F0,{color:M===W?Y.colors.primary:void 0,bold:M===W,children:[M===W?"❯ ":" ",M+1,". ",j.name]},void 0,!0,void 0,this),x(F0,{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),x(V0,{marginTop:1,children:x(F0,{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"&&x(V0,{flexDirection:"column",children:[x(V0,{flexDirection:"column",borderStyle:"round",borderColor:Y.colors.success,paddingX:2,paddingY:1,children:[x(F0,{bold:!0,children:["Saving hook to ",I.description,"..."]},void 0,!0,void 0,this),x(F0,{children:" "},void 0,!1,void 0,this),x(F0,{children:["Event: ",y.event]},void 0,!0,void 0,this),x(F0,{children:["Matcher: ",F||"(all tools)"]},void 0,!0,void 0,this),x(F0,{children:["Command: ",H]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),x(V0,{marginTop:1,children:x(F0,{color:Y.colors.muted,children:B?"Saving...":"Enter to confirm · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),z&&x(V0,{marginTop:1,children:x(F0,{color:Y.colors.error,children:["❌ ",z]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{useMemoizedFn as zU}from"ahooks";import{Box as Yb,Text as Qb}from"ink";import Xb from"react";import{useMemoizedFn as oN}from"ahooks";import k4 from"chalk";import{Text as sN,useInput as tN}from"ink";import{useEffect as QY,useRef as XY}from"react";var L2={TIMEOUT_MS:100,RAPID_INPUT_THRESHOLD_MS:150,LARGE_INPUT_THRESHOLD:300,MEDIUM_SIZE_MULTI_CHUNK_THRESHOLD:200};import{execSync as h3}from"node:child_process";import{existsSync as iN,readFileSync as ZY}from"node:fs";import{basename as qU,isAbsolute as aN}from"node:path";function GU($){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 KU(){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 rN(){let{commands:$}=KU();try{return h3($.getPath,{encoding:"utf-8"}).trim()}catch(Z){return console.error("Failed to get clipboard path:",Z),null}}function WU($){if($.startsWith('"')&&$.endsWith('"')||$.startsWith("'")&&$.endsWith("'"))return $.slice(1,-1);return $}function UU($){if(process.platform==="win32")return $;let Z="__DOUBLE_BACKSLASH__";return $.replace(/\\\\/g,Z).replace(/\\(.)/g,"$1").replace(new RegExp(Z,"g"),"\\")}function YY($){let Z=WU($.trim()),Y=UU(Z);return/\.(png|jpe?g|gif|webp)$/i.test(Y)}function nN($){let Z=WU($.trim()),Y=UU(Z);if(YY(Y))return Y;return null}async function FU($){let Z=nN($);if(!Z)return null;let Y;try{if(aN(Z))Y=ZY(Z);else{let q=rN();if(q&&Z===qU(q))Y=ZY(q);else return null}}catch(q){return console.error("Failed to read image file:",q),null}let Q=Y.toString("base64"),X=GU(Q),J=qU(Z);return{path:Z,base64:Q,mediaType:X,filename:J}}async function OU(){let $=process.platform,Z={darwin:"pbpaste",linux:"xclip -selection clipboard -o || wl-paste",win32:'powershell -Command "Get-Clipboard"'},Y=Z[$]||Z.linux;try{return h3(Y,{encoding:"utf-8"})||null}catch{return null}}async function HU(){let{commands:$,screenshotPath:Z}=KU();try{if(h3($.checkImage,{stdio:"ignore"}),h3($.saveImage(Z),{stdio:"ignore"}),!iN(Z))return null;let Q=ZY(Z).toString("base64"),X=GU(Q);return h3($.deleteFile(Z),{stdio:"ignore"}),{base64:Q,mediaType:X}}catch(Y){try{h3($.deleteFile(Z),{stdio:"ignore"})}catch{}return null}}import{jsxDEV as Zb}from"react/jsx-dev-runtime";var eN=/\r\n/g,$b=/\r/g;function f4($){if(!$.includes("\r"))return $;return $.replace(eN,`
|
|
2831
|
+
`).replace($b,`
|
|
2832
|
+
`)}function h4($,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 _U({value:$,placeholder:Z="",focus:Y=!0,onChange:Q,cursorPosition:X,onChangeCursorPosition:J,onPaste:q,onImagePaste:G,disabledKeys:K=[]}){let W=XY({chunks:[],timeoutId:null,firstInputTime:null,lastInputTime:null,totalLength:0}),U=XY($),F=XY(X);QY(()=>{U.current=$,F.current=X},[$,X]),QY(()=>{return()=>{if(W.current.timeoutId)clearTimeout(W.current.timeoutId)}},[]),QY(()=>{if(X>$.length)J($.length)},[$,X,J]);let O=oN(()=>{let w=W.current;if(w.timeoutId)clearTimeout(w.timeoutId);let B=setTimeout(async()=>{let L=W.current.chunks,V=W.current.totalLength;if(L.length===0)return;let D=f4(L.join(""));W.current={chunks:[],timeoutId:null,firstInputTime:null,lastInputTime:null,totalLength:0};let R=U.current,y=F.current;if(G&&YY(D))try{let S=await FU(D);if(S){let T=await G(S.base64,S.mediaType,S.filename);if(T?.prompt){let g=f4(T.prompt),{newValue:j,newCursorPosition:M}=h4(g,R,y);Q(j),J(M)}return}}catch(S){console.error("Failed to process image path:",S)}let I=D.includes(`
|
|
2833
|
+
`),N=V>L2.MEDIUM_SIZE_MULTI_CHUNK_THRESHOLD&&L.length>3;if((V>L2.LARGE_INPUT_THRESHOLD||I||N)&&q){let S=await q(D);if(S?.prompt){let T=f4(S.prompt),{newValue:g,newCursorPosition:j}=h4(T,R,y);Q(g),J(j);return}}let{newValue:m,newCursorPosition:e}=h4(D,R,y);Q(m),J(e)},L2.TIMEOUT_MS);W.current.timeoutId=B});tN((w,B)=>{let L=f4(w);if(K.some((N)=>B[N])||B.ctrl&&w==="c"||B.ctrl&&w==="l"||B.ctrl&&w==="t"||B.ctrl&&w==="o"||B.meta&&w==="l"||B.meta&&w==="t"||B.meta&&w==="o"||B.shift&&B.tab||L==="?"&&$==="")return;let D=Date.now(),R=W.current,y=X,I=$;if(B.leftArrow)y--;else if(B.rightArrow)y++;else if(B.backspace||B.delete){if(w===""){if(X>0)I=$.slice(0,X-1)+$.slice(X,$.length),y--}else if(X<$.length)I=$.slice(0,X)+$.slice(X+1,$.length)}else if(B.ctrl&&L==="a")y=0;else if(B.ctrl&&L==="e")y=$.length;else if(B.ctrl&&L==="k")I=$.slice(0,X);else if(B.ctrl&&L==="u")I=$.slice(X),y=0;else if(B.ctrl&&L==="w"){let P=$.slice(0,X).match(/\s*\S+\s*$/);if(P){let m=P[0].length;I=$.slice(0,X-m)+$.slice(X),y-=m}}else if(B.ctrl&&L==="v"){let N=process.platform==="darwin";(async()=>{if(G){let m=await HU();if(m){let e=await G(m.base64,m.mediaType,"clipboard.png");if(e?.prompt){let S=f4(e.prompt),{newValue:T,newCursorPosition:g}=h4(S,U.current,F.current);Q(T),J(g)}return}}if(N)return;let P=await OU();if(P){let m=f4(P),e=m.includes(`
|
|
2834
2834
|
`),S=m.length>L2.LARGE_INPUT_THRESHOLD;if((e||S)&&q){let j=await q(m);if(j?.prompt){let M=f4(j.prompt),{newValue:A,newCursorPosition:r}=h4(M,U.current,F.current);Q(A),J(r);return}}let{newValue:T,newCursorPosition:g}=h4(m,U.current,F.current);Q(T),J(g)}})().catch(()=>{});return}else if(B.pageUp)y=0;else if(B.pageDown)y=$.length;else if(L===`
|
|
2835
2835
|
`&&(B.shift||B.meta)){let{newValue:N,newCursorPosition:P}=h4(L,$,X);Q(N),J(P);return}else if(!B.ctrl&&!B.meta){if(!R.firstInputTime)R.firstInputTime=D;R.lastInputTime=D;let N=D-(R.firstInputTime||D),P=L.length>L2.LARGE_INPUT_THRESHOLD,m=L.includes(`
|
|
2836
|
-
`)&&L.length>1,e=N<L2.RAPID_INPUT_THRESHOLD_MS&&R.chunks.length>0,S=N<L2.RAPID_INPUT_THRESHOLD_MS&&L.length>10,T=R.timeoutId!==null;if(q&&(P||m||e||S||T)){R.chunks.push(L),R.totalLength+=L.length,O();return}if(L.length===1&&!R.timeoutId)R.chunks=[],R.firstInputTime=null,R.lastInputTime=null,R.totalLength=0;I=$.slice(0,X)+L+$.slice(X,$.length),y+=L.length}if(y<0)y=0;if(y>I.length)y=I.length;if(I!==$)Q(I);if(y!==X)J(y)},{isActive:Y});let H=Y,_=$,z=Z?k4.grey(Z):void 0;if(H)if(z=Z.length>0?k4.inverse(Z[0])+k4.grey(Z.slice(1)):k4.inverse(" "),$.length===0)_=k4.inverse(" ");else{_="";for(let w=0;w<$.length;w++)if(w===X&&X<$.length)_+=k4.inverse($[w]);else _+=$[w];if(X>=$.length)_+=k4.inverse(" ")}return
|
|
2837
|
-
`).length,O=U.length,H=500,_=10;if(O>500||F>10){let z=X(U),w=U.slice(0,30).replace(/\n/g," "),B=`${O} chars, ${F} lines: ${w}...`;return{prompt:`${F7(z)}${B}${TZ()}`}}return{}}),W=zU(async(U,F,O)=>{try{let H=J(U,F);return{prompt:`${F7(H)}[Image #${H}]${TZ()}`}}catch(H){return console.error("[Image Paste] Failed to process image:",H),{prompt:`[Image paste failed: ${H instanceof Error?H.message:"Unknown error"}] `}}});return JY(
|
|
2838
|
-
`)[0]||"";if(Y.length<=Z)return Y;return`${Y.slice(0,Z)}...`}function
|
|
2839
|
-
`).length}var UY=Rb.memo(({content:$,isStreaming:Z=!1,isExpanded:Y})=>{let Q=m0(),X=IU(()=>Db($),[$]),J=IU(()=>Vb($),[$]),q=Q.colors.info,G=Q.colors.muted;return N2(WY,{flexDirection:"column",marginBottom:1,children:[N2(WY,{flexDirection:"row",children:[N2(x3,{color:q,children:Y?"▼":"▶"},void 0,!1,void 0,this),N2(x3,{children:" "},void 0,!1,void 0,this),N2(x3,{color:G,children:["Thinking",Z?"...":` (${X} lines)`]},void 0,!0,void 0,this),!Y&&!Z&&J&&N2(x3,{color:G,children:[" - ",J]},void 0,!0,void 0,this),N2(x3,{color:G,dimColor:!0,children:[" ","[Ctrl+T]"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Y&&$&&N2(WY,{marginLeft:2,marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,paddingY:0,children:N2(x3,{color:G,children:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});UY.displayName="ThinkingBlock";import{Box as D7,Text as FY}from"ink";import yU from"react";import{jsxDEV as o2}from"react/jsx-dev-runtime";var vU=yU.memo(({todos:$,visible:Z=!0,compact:Y=!1})=>{let{colors:Q}=m0();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 o2(D7,{flexDirection:"column",borderStyle:"single",borderColor:Q.border.light,paddingX:1,paddingY:Y?0:1,marginBottom:1,children:[o2(D7,{marginBottom:Y?0:1,children:[o2(FY,{dimColor:!0,children:"Tasks "},void 0,!1,void 0,this),o2(FY,{color:Q.text.muted,children:[X.completed,"/",X.total]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),o2(D7,{flexDirection:"column",children:$.map((J,q)=>o2(Mb,{todo:J,compact:Y},J.id||q,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}),Mb=yU.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 o2(D7,{paddingY:Z?0:0,children:o2(FY,{dimColor:Q,children:[Y," ",X]},void 0,!0,void 0,this)},void 0,!1,void 0,this)});import{jsxDEV as z$}from"react/jsx-dev-runtime";var EU=Ib.memo(()=>{let $=Q7(),Z=WW(),Y=UW(),Q=FW(),X=a2(),J=sK(),q=ZW(),G=qW(),K=GW(),W=KW(),U=iK(),F=HW(),O=OW(),H=T3(),_=DU(),{stdout:z}=jb(),w=l2(),[B,L]=HY(null),[V,D]=HY([]),[R,y]=HY(new Set),I=s2(O),N=s2(null),P=s2(0),m=s2(0),e=s2(new Set),S=s2(new Set),T=s2([]),g=s2(null);x4(()=>{if(I.current!==O){if(z)z.write(OY.clearTerminal);w.incrementClearCount(),I.current=O}},[O,z,w]);let j=$,M=Q;x4(()=>{if(!Q||X){g.current=null;return}if(g.current===Q)return;g.current=Q;let k=setTimeout(()=>{if(z)z.write(OY.clearTerminal);e.current=new Set,S.current=new Set(j.filter((a)=>a.role==="tool").map((a)=>a.id)),N.current=null,P.current=0,m.current=0,T.current=[],D([]),y(new Set),w.incrementClearCount(),w.clearFinalizingStreamingMessageId()},50);return()=>clearTimeout(k)},[Q,X,z,w,j]);let A=Z??Q;x4(()=>{N.current=null,P.current=0,m.current=0,e.current=new Set,S.current=new Set(j.filter((k)=>k.role==="tool").map((k)=>k.id)),T.current=[],D([]),y(new Set)},[U]),x4(()=>{if(!A)return;if(N.current===A)return;N.current=A,P.current=0,m.current=0,S.current=new Set(j.filter((k)=>k.role==="tool").map((k)=>k.id)),T.current=[],D([])},[A,j]),x4(()=>{if(!A)return;let k=Z9(A);if(!k||k.length<=P.current)return;let a=k.slice(P.current);P.current=k.length;let n=a,U0=T.current;if(U0.length>0)if(n.some((E$)=>E$.type!=="empty"))n=[...U0,...n],T.current=[];else{T.current=[...U0,...n];return}let M0=n.length;while(M0>0&&n[M0-1].type==="empty")M0-=1;if(M0!==n.length)T.current=n.slice(M0),n=n.slice(0,M0);if(n.length===0)return;let $$=m.current;m.current+=1;let j2=$$>0;y((E$)=>{if(!A||E$.has(A))return E$;let X0=new Set(E$);return X0.add(A),X0}),D((E$)=>[...E$,z$(b2,{flexDirection:"column",children:z$(n2,{content:"",role:"assistant",terminalWidth:H,isPending:!1,hidePrefix:j2,noMargin:!0,blocksOverride:n,renderCodeBlocksAsPlainText:!0},void 0,!1,void 0,this)},`streaming-${A}-${$$}`,!1,void 0,this)])},[A,Y.version,H,U]),x4(()=>{if(!A)return;let k=S.current,a=j.filter((n)=>n.role==="tool"&&!k.has(n.id)&&!e.current.has(n.id));if(a.length===0)return;for(let n of a)e.current.add(n.id);D((n)=>[...n,...a.map((U0)=>z$(b2,{flexDirection:"column",children:z$(n2,{content:U0.content,role:U0.role,terminalWidth:H,metadata:U0.metadata,isPending:!1,messageId:U0.id},void 0,!1,void 0,this)},`streaming-tool-${U0.id}`,!1,void 0,this))])},[A,j,H]);let r=M7(()=>{if(!A)return null;let k=tY(A);if(!k||k.lines.length===0)return null;let n=Math.max(1,_-8),U0=Math.max(0,k.lines.length-n);return{visibleLines:k.lines.slice(-n),hiddenLines:U0,mode:k.mode}},[A,Y.version,_]),E=M7(()=>{if(!A)return!1;return(Z9(A)?.length??0)>0},[A,Y.version]);x4(()=>{if(B===null&&j.length>F){if(L(j.length),z)z.write(OY.clearTerminal);w.incrementClearCount()}},[j.length,F,B,z,w]);let u=M7(()=>{return J.some((k)=>k.status==="pending"||k.status==="in_progress")},[J]),Z0=O?0:B??0,d=Z0,s=M7(()=>{let k=[];if(k.push(z$(jU,{},"header",!1,void 0,this)),d>0)k.push(z$(KY,{collapsedCount:d},"collapsed-summary",!1,void 0,this));for(let a=Z0;a<j.length;a++){let n=j[a];if(M&&n.id===M)continue;if(n.role==="tool"&&e.current.has(n.id))continue;if(n.role==="assistant"&&R.has(n.id))continue;k.push(z$(b2,{flexDirection:"column",children:z$(n2,{content:n.content,role:n.role,terminalWidth:H,metadata:n.metadata,isPending:!1,messageId:n.id},void 0,!1,void 0,this)},n.id,!1,void 0,this))}return k},[j,Z0,d,H,M,R]);return z$(b2,{flexDirection:"column",paddingX:2,children:z$(b2,{flexDirection:"column",children:[z$(TU,{items:s,children:(k)=>k},U,!1,void 0,this),K&&z$(b2,{marginBottom:1,children:z$(UY,{content:K,isStreaming:X,isExpanded:W},void 0,!1,void 0,this)},void 0,!1,void 0,this),V.length>0&&z$(TU,{items:V,children:(k)=>k},`streaming-${U}`,!1,void 0,this),r&&z$(b2,{flexDirection:"column",children:z$(n2,{content:"",role:"assistant",terminalWidth:H,isPending:!0,hidePrefix:E,streamingLines:r.visibleLines,streamingHiddenLines:r.hiddenLines,streamingMode:r.mode},void 0,!1,void 0,this)},void 0,!1,void 0,this),q&&u&&z$(b2,{marginTop:1,children:z$(vU,{todos:J,visible:!0,compact:!1},void 0,!1,void 0,this)},void 0,!1,void 0,this),G.map((k,a)=>z$(b2,{flexDirection:"column",children:z$(n2,{content:k.displayText,role:"user",terminalWidth:H},void 0,!1,void 0,this)},`pending-${a}`,!1,void 0,this))]},void 0,!0,void 0,this)},void 0,!1,void 0,this)});T0();import{useMemoizedFn as R2}from"ahooks";import{Box as T$,Text as O$,useFocusManager as nb,useInput as sU}from"ink";import ob from"ink-text-input";import{useState as e2}from"react";import{Box as A2,Text as J1,useInput as yb}from"ink";import vb from"ink-text-input";import{jsxDEV as Q$}from"react/jsx-dev-runtime";var PU=({provider:$,value:Z,onChange:Y,onSubmit:Q,onCancel:X,error:J})=>{yb((G,K)=>{if(K.escape)X()});let q=$.envVars.length>0?$.envVars[0]:null;return Q$(A2,{flexDirection:"column",children:[Q$(A2,{marginBottom:1,children:Q$(J1,{bold:!0,color:"blue",children:"\uD83D\uDD11 Step 2: 输入 API Key"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q$(A2,{marginBottom:1,children:Q$(J1,{children:["Provider: ",$.icon," ",Q$(J1,{bold:!0,children:$.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),q&&Q$(A2,{marginBottom:1,children:Q$(J1,{dimColor:!0,children:["\uD83D\uDCA1 环境变量: ",Q$(J1,{color:"cyan",children:q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),$.docUrl&&Q$(A2,{marginBottom:1,children:Q$(J1,{dimColor:!0,children:["\uD83D\uDCD6 文档: ",Q$(J1,{color:"blue",children:$.docUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q$(A2,{marginBottom:1,children:Q$(J1,{dimColor:!0,children:"您的 API 密钥将被安全存储在 ~/.blade/config.json (权限 600)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q$(A2,{children:[Q$(J1,{bold:!0,color:"cyan",children:["▶"," "]},void 0,!0,void 0,this),Q$(vb,{value:Z,onChange:Y,onSubmit:Q,placeholder:"sk-...",mask:"*"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J&&Q$(A2,{marginTop:1,children:Q$(J1,{color:"red",children:["❌ ",J]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q$(A2,{marginTop:1,children:Q$(J1,{dimColor:!0,children:["\uD83D\uDCA1 输入完成后按 ",Q$(J1,{bold:!0,children:"Enter"},void 0,!1,void 0,this),",",Q$(J1,{bold:!0,children:"Esc"},void 0,!1,void 0,this)," 返回"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{useEffect as fU,useState as p3}from"react";z0();t3();var I7=l("Service"),Tb="https://models.dev/api.json",Eb=3600000,j7=null,CU=async()=>{if(j7&&Date.now()-j7.timestamp<Eb)return j7.data;try{I7.info("\uD83D\uDCE1 Fetching models.dev data...");let $=await fetch(Tb,{headers:{"User-Agent":"Blade-CLI/1.0"}});if(!$.ok)throw Error(`HTTP ${$.status}: ${$.statusText}`);let Z=await $.json();return j7={data:Z,timestamp:Date.now()},I7.info(`✅ Loaded ${Object.keys(Z).length} providers from models.dev`),Z}catch($){throw I7.error("❌ Failed to fetch models.dev data:",$),$}},SU=async()=>{let $=await CU(),Z=[];for(let[Y,Q]of Object.entries($)){let X=Object.keys(Q.models||{}).length;if(X===0)continue;Z.push({id:Y,name:Q.name||Y,icon:P9[Y]||P9.default,description:`${X} 个模型`,isOAuth:!1,envVars:Q.env||[],docUrl:Q.doc,defaultBaseUrl:Y6[Y],bladeProvider:rQ(Y)})}return Z.sort((Y,Q)=>{let X=E9.indexOf(Y.id),J=E9.indexOf(Q.id);if(X!==-1&&J!==-1)return X-J;if(X!==-1)return-1;if(J!==-1)return 1;return Y.name.localeCompare(Q.name)})},kU=async($)=>{let Y=(await CU())[$];if(!Y?.models)return I7.warn(`⚠️ No models found for provider: ${$}`),[];return Object.values(Y.models).map((Q)=>({id:Q.id,name:Q.name||Q.id,contextWindow:Q.limit?.context,maxOutput:Q.limit?.output,inputCost:Q.cost?.input,outputCost:Q.cost?.output}))};t3();var Pb={id:"custom-openai-compatible",name:"自定义 OpenAI Compatible",icon:"\uD83D\uDD27",description:"使用自定义 Base URL 和 API Key",isOAuth:!1,envVars:[],bladeProvider:"openai-compatible",isCustom:!0},hU=()=>{let[$,Z]=p3([]),[Y,Q]=p3(!0),[X,J]=p3(null);return fU(()=>{(async()=>{try{let G=await SU(),K=Object.entries(aQ).map(([W,U])=>({id:W,name:W==="antigravity"?"Google Antigravity":"GitHub Copilot",icon:U.icon,description:U.description,isOAuth:!0,envVars:[],bladeProvider:U.bladeProvider}));Z([...K,Pb,...G])}catch(G){J(G instanceof Error?G.message:"加载 Provider 列表失败")}finally{Q(!1)}})()},[]),{providers:$,isLoading:Y,error:X}},xU=($)=>{let[Z,Y]=p3([]),[Q,X]=p3(!1),[J,q]=p3(null);return fU(()=>{if(!$){Y([]);return}(async()=>{X(!0),q(null);try{let K=await kU($);Y(K)}catch(K){q(K instanceof Error?K.message:"加载模型列表失败")}finally{X(!1)}})()},[$]),{models:Z,isLoading:Q,error:J}};import{Box as d1,Text as D1,useInput as Cb}from"ink";import Sb from"ink-select-input";import pU from"ink-text-input";import{useMemo as mU,useState as _Y}from"react";import{jsxDEV as d0,Fragment as xb}from"react/jsx-dev-runtime";var kb=({isSelected:$})=>d0(d1,{marginRight:1,children:d0(D1,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),fb=($)=>{let Z=[$.name];if($.contextWindow){let Y=$.contextWindow>=1e6?`${($.contextWindow/1e6).toFixed(1)}M`:$.contextWindow>=1000?`${Math.round($.contextWindow/1000)}K`:`${$.contextWindow}`;Z.push(`[${Y} ctx]`)}if($.inputCost!==void 0&&$.outputCost!==void 0)Z.push(`[$${$.inputCost}/$${$.outputCost}]`);return Z.join(" ")},hb=({isSelected:$,label:Z})=>d0(D1,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),gU=({provider:$,models:Z,isLoading:Y,error:Q,onSelect:X,onCancel:J,initialModel:q})=>{let[G,K]=_Y(""),W=$.isCustom||Z.length===0,[U,F]=_Y(W),[O,H]=_Y(q||"");Cb((B,L)=>{if(L.escape){if(U&&!W)F(!1),H(q||"");else if(G)K("");else J();return}if(B==="+"&&!U)F(!0)});let _=mU(()=>{if(!G)return Z;let B=G.toLowerCase();return Z.filter((L)=>L.name.toLowerCase().includes(B)||L.id.toLowerCase().includes(B))},[Z,G]),z=mU(()=>_.map((B)=>({key:B.id,label:fb(B),value:B})),[_]),w=()=>{if(O.trim())X({id:O.trim(),name:O.trim()})};if(Y)return d0(d1,{flexDirection:"column",children:d0(D1,{color:"yellow",children:["⏳ 正在加载 ",$.name," 模型列表..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this);if(Q)return d0(d1,{flexDirection:"column",children:[d0(D1,{color:"red",children:["❌ ",Q]},void 0,!0,void 0,this),d0(D1,{dimColor:!0,children:"按 Esc 返回"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return d0(d1,{flexDirection:"column",children:[d0(d1,{marginBottom:1,children:d0(D1,{bold:!0,color:"blue",children:"\uD83E\uDD16 Step 3: 选择模型"},void 0,!1,void 0,this)},void 0,!1,void 0,this),d0(d1,{marginBottom:1,children:d0(D1,{children:["Provider: ",$.icon," ",d0(D1,{bold:!0,children:$.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),U?d0(d1,{flexDirection:"column",children:[d0(d1,{marginBottom:1,children:d0(D1,{dimColor:!0,children:W?"输入模型名称:":"输入自定义模型名称(按 Esc 返回列表):"},void 0,!1,void 0,this)},void 0,!1,void 0,this),d0(d1,{children:[d0(D1,{bold:!0,color:"cyan",children:"▶ "},void 0,!1,void 0,this),d0(pU,{value:O,onChange:H,onSubmit:w,placeholder:"例如: gpt-4o-mini"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this):d0(xb,{children:[d0(d1,{marginBottom:1,children:[d0(D1,{color:"cyan",children:"\uD83D\uDD0D "},void 0,!1,void 0,this),d0(pU,{value:G,onChange:K,placeholder:`搜索 ${Z.length} 个模型,按 + 自定义...`},void 0,!1,void 0,this)]},void 0,!0,void 0,this),d0(d1,{flexDirection:"column",height:12,children:d0(Sb,{items:z,onSelect:(B)=>X(B.value),indicatorComponent:kb,itemComponent:hb,limit:10},void 0,!1,void 0,this)},void 0,!1,void 0,this),_.length===0&&d0(D1,{color:"yellow",children:"未找到匹配的模型,按 + 输入自定义模型名称"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};J8();Y8();F8();K8();import{Box as M1,Text as q1,useFocus as dU,useInput as cU}from"ink";import pb from"ink-select-input";import{useEffect as mb,useState as uU}from"react";import{jsxDEV as n0}from"react/jsx-dev-runtime";var lU=({provider:$,onLogin:Z,onCancel:Y,isLoggingIn:Q})=>{let{isFocused:X}=dU({id:"oauth-login"});return cU((J,q)=>{if(Q)return;if(J==="y"||J==="Y")Z();else if(J==="n"||J==="N"||q.escape)Y()},{isActive:X&&!Q}),n0(M1,{flexDirection:"column",children:[n0(M1,{marginBottom:1,children:n0(q1,{bold:!0,color:"yellow",children:[$.icon," 需要登录 ",$.name]},void 0,!0,void 0,this)},void 0,!1,void 0,this),n0(M1,{marginBottom:1,children:n0(q1,{children:$.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),n0(M1,{marginBottom:1,paddingLeft:2,children:n0(q1,{dimColor:!0,children:["您也可以稍后手动执行"," ",n0(q1,{bold:!0,children:$.id==="antigravity"?"/login":"/login copilot"},void 0,!1,void 0,this)," ","命令登录"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),!Q&&n0(M1,{marginTop:1,children:n0(q1,{children:["现在登录? [",n0(q1,{bold:!0,color:"green",children:"Y"},void 0,!1,void 0,this),"/",n0(q1,{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&&n0(M1,{marginTop:1,children:n0(q1,{color:"yellow",children:"⏳ 正在启动登录流程..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},gb=({isSelected:$})=>n0(M1,{marginRight:1,children:n0(q1,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),ub=({isSelected:$,label:Z})=>n0(q1,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),iU=({provider:$,onSelect:Z,onCancel:Y})=>{let{isFocused:Q}=dU({id:"oauth-model-select"}),[X,J]=uU([]),[q,G]=uU(!0);mb(()=>{(async()=>{G(!0);try{if($.id==="copilot")J(Object.values(G6));else{let F=await C$.getInstance().getConfigType();J(F==="gemini-cli"?Object.values(Q6):Object.values(Z8))}}catch{J(Object.values(Z8))}finally{G(!1)}})()},[$.id]),cU((W,U)=>{if(U.escape)Y()},{isActive:Q});let K=X.map((W)=>({key:W.id,label:`${W.name} - ${W.description}`,value:{id:W.id,name:W.name}}));if(q)return n0(M1,{flexDirection:"column",children:n0(q1,{color:"yellow",children:["⏳ 加载 ",$.name," 模型列表..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this);return n0(M1,{flexDirection:"column",children:[n0(M1,{marginBottom:1,children:n0(q1,{bold:!0,color:"blue",children:["\uD83E\uDD16 选择 ",$.name," 模型"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),n0(M1,{marginBottom:1,children:n0(q1,{dimColor:!0,children:"从可用模型列表中选择一个"},void 0,!1,void 0,this)},void 0,!1,void 0,this),n0(M1,{flexDirection:"column",height:12,children:n0(pb,{items:K,onSelect:(W)=>Z(W.value),indicatorComponent:gb,itemComponent:ub,limit:10},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},aU=async($)=>{let Z=$==="antigravity"?C$.getInstance():d$.getInstance();try{return await Z.login(),!0}catch{return!1}},rU=async($)=>{let Z=$==="antigravity"?C$.getInstance():d$.getInstance();try{return await Z.isLoggedIn()}catch{return!1}};import{Box as p4,Text as t2,useInput as db}from"ink";import cb from"ink-select-input";import lb from"ink-text-input";import{useMemo as nU,useState as ib}from"react";import{jsxDEV as v$}from"react/jsx-dev-runtime";var ab=({isSelected:$})=>v$(p4,{marginRight:1,children:v$(t2,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),rb=({isSelected:$,label:Z})=>v$(t2,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),oU=({providers:$,isLoading:Z,error:Y,onSelect:Q,onCancel:X})=>{let[J,q]=ib("");db((W,U)=>{if(U.escape)if(J)q("");else X()});let G=nU(()=>{if(!J)return $;let W=J.toLowerCase();return $.filter((U)=>U.name.toLowerCase().includes(W)||U.id.toLowerCase().includes(W))},[$,J]),K=nU(()=>G.map((W)=>({key:W.id,label:`${W.icon} ${W.name} - ${W.description}`,value:W})),[G]);if(Z)return v$(p4,{flexDirection:"column",children:v$(t2,{color:"yellow",children:"⏳ 正在加载 Provider 列表..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(Y)return v$(p4,{flexDirection:"column",children:[v$(t2,{color:"red",children:["❌ ",Y]},void 0,!0,void 0,this),v$(t2,{dimColor:!0,children:"按 Esc 返回"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return v$(p4,{flexDirection:"column",children:[v$(p4,{marginBottom:1,children:v$(t2,{bold:!0,color:"blue",children:"\uD83D\uDCE1 Step 1: 选择 API 提供商"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v$(p4,{marginBottom:1,children:[v$(t2,{color:"cyan",children:"\uD83D\uDD0D "},void 0,!1,void 0,this),v$(lb,{value:J,onChange:q,placeholder:`搜索 ${$.length} 个 Provider...`},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v$(p4,{flexDirection:"column",height:12,children:v$(cb,{items:K,onSelect:(W)=>Q(W.value),indicatorComponent:ab,itemComponent:rb,limit:10},void 0,!1,void 0,this)},void 0,!1,void 0,this),G.length===0&&v$(t2,{color:"yellow",children:"未找到匹配的 Provider,按 Esc 清除搜索"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};t3();import{jsxDEV as G0,Fragment as tb}from"react/jsx-dev-runtime";var zY=({mode:$,initialConfig:Z,modelId:Y,onComplete:Q,onCancel:X})=>{let J=$==="edit",[q,G]=e2("provider"),[K,W]=e2(),[U,F]=e2(J?Z?.apiKey||"":""),[O,H]=e2(J?Z?.baseUrl||"":""),[_]=e2(J?Z?.model||"":""),[z,w]=e2(),[B,L]=e2(!1),[V,D]=e2(!1),{providers:R,isLoading:y,error:I}=hU(),{models:N,isLoading:P,error:m}=xU(K?.isOAuth?void 0:K?.id),e=Z$(!1),{focus:S}=nb();sU((a,n)=>{if(n.ctrl&&a==="c"||n.meta&&a==="c")$==="setup"?e():X()});let T=R2((a)=>{let U0={provider:"",apiKey:"",baseUrl:"",model:"",oauthLogin:"oauth-login",oauthModelSelect:"oauth-model-select",confirm:""}[a];if(U0)S(U0)}),g=R2((a)=>{return a.defaultBaseUrl||Y6[a.id]||""}),j=R2(async(a)=>{W(a),w(void 0);let n=g(a);if(!J)H(n);if(a.isOAuth){let M0=await rU(a.id)?"oauthModelSelect":"oauthLogin";G(M0),T(M0)}else G("apiKey")}),M=R2(()=>{if(!U.trim()){w("API Key 不能为空");return}w(void 0);let a=K?g(K):"";if(K?.isCustom||!a&&!O)G("baseUrl");else G("model")}),A=R2(()=>{if(!O.trim()){w("Base URL 不能为空");return}try{new URL(O)}catch{w("请输入有效的 URL (例如: https://api.example.com/v1)");return}w(void 0),G("model")}),r=R2(async(a)=>{w(void 0),L(!0);try{let n=O||(K?g(K):""),M0={name:J&&Z?.name?Z.name:`${K?.name||"Model"} - ${a.name}`,provider:K?.bladeProvider||Z?.provider||"openai-compatible",baseUrl:n,apiKey:K?.isOAuth?"oauth":U,model:a.id,...a.contextWindow&&{maxContextTokens:a.contextWindow},...a.maxOutput&&{maxOutputTokens:a.maxOutput},...K?.id&&{providerId:K.id}};if($==="setup")Q(M0);else if($==="add"){let $$=await C0().addModel(M0);await C0().setCurrentModel($$.id),Q(M0)}else if($==="edit"&&Y)await C0().updateModel(Y,M0),Q(M0)}catch(n){w(n instanceof Error?n.message:"保存配置失败"),L(!1)}}),E=R2(async()=>{if(!K)return;D(!0),w(void 0);let a=await aU(K.id);if(D(!1),a)G("oauthModelSelect"),T("oauthModelSelect");else w("登录失败,请重试")}),u=R2(()=>{switch(w(void 0),q){case"apiKey":G("provider");break;case"baseUrl":G("apiKey");break;case"model":{if(!(K?g(K):""))G("baseUrl");else G("apiKey");break}case"oauthLogin":case"oauthModelSelect":G("provider");break}}),Z0=R2(()=>{G("apiKey")}),d=q==="provider"?1:q==="apiKey"||q==="oauthLogin"?2:q==="baseUrl"?2.5:3,s=3;return G0(T$,{...$==="setup"?{flexDirection:"column",padding:1}:{flexDirection:"column",borderStyle:"round",borderColor:$==="edit"?"yellow":"blue",padding:1},children:[$==="setup"&&G0(tb,{children:[G0(T$,{marginBottom:1,children:G0(O$,{bold:!0,color:"blue",children:"\uD83D\uDE80 欢迎使用 Blade Code"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(T$,{marginBottom:1,children:G0(O$,{children:"AI 驱动的代码助手 - 让我们开始配置您的助手"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(T$,{marginBottom:1,children:[G0(O$,{bold:!0,color:"blue",children:"█".repeat(Math.floor((d-1)/(s-1)*40))},void 0,!1,void 0,this),G0(O$,{dimColor:!0,children:"░".repeat(40-Math.floor((d-1)/(s-1)*40))},void 0,!1,void 0,this),G0(O$,{children:" "},void 0,!1,void 0,this),G0(O$,{bold:!0,color:"cyan",children:[Math.ceil(d),"/",s]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),G0(T$,{marginBottom:1,children:G0(O$,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$!=="setup"&&G0(T$,{justifyContent:"center",marginBottom:1,children:G0(O$,{bold:!0,color:$==="edit"?"yellow":"blue",children:$==="edit"?"编辑模型配置":"添加新模型配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),q==="provider"&&G0(oU,{providers:R,isLoading:y,error:I,onSelect:j,onCancel:$==="setup"?()=>{}:X},void 0,!1,void 0,this),q==="apiKey"&&K&&G0(PU,{provider:K,value:U,onChange:F,onSubmit:M,onCancel:u,error:z},void 0,!1,void 0,this),q==="baseUrl"&&K&&G0(sb,{provider:K,value:O,onChange:H,onSubmit:A,onCancel:Z0,error:z},void 0,!1,void 0,this),q==="model"&&K&&G0(gU,{provider:K,models:N,isLoading:P,error:m,onSelect:r,onCancel:u,initialModel:J?_:void 0},void 0,!1,void 0,this),q==="oauthLogin"&&K&&G0(lU,{provider:K,onLogin:E,onCancel:u,isLoggingIn:V},void 0,!1,void 0,this),q==="oauthModelSelect"&&K&&G0(iU,{provider:K,onSelect:r,onCancel:u},void 0,!1,void 0,this),z&&q!=="apiKey"&&q!=="baseUrl"&&G0(T$,{marginTop:1,borderStyle:"round",borderColor:"red",paddingX:1,children:G0(O$,{color:"red",children:["❌ ",z]},void 0,!0,void 0,this)},void 0,!1,void 0,this),B&&G0(T$,{marginTop:1,children:G0(O$,{color:"yellow",children:"⏳ 正在保存配置..."},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(T$,{marginTop:1,children:G0(O$,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},sb=({provider:$,value:Z,onChange:Y,onSubmit:Q,onCancel:X,error:J})=>{return sU((q,G)=>{if(G.escape)X()}),G0(T$,{flexDirection:"column",children:[G0(T$,{marginBottom:1,children:G0(O$,{bold:!0,color:"blue",children:"\uD83C\uDF10 输入 Base URL"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(T$,{marginBottom:1,children:G0(O$,{children:["Provider: ",$.icon," ",G0(O$,{bold:!0,children:$.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),G0(T$,{marginBottom:1,children:G0(O$,{dimColor:!0,children:"此 Provider 没有默认的 API 端点,请输入完整的 Base URL"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(T$,{marginBottom:1,children:G0(O$,{dimColor:!0,children:"示例: https://api.example.com/v1"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(T$,{children:[G0(O$,{bold:!0,color:"cyan",children:"▶ "},void 0,!1,void 0,this),G0(ob,{value:Z,onChange:Y,onSubmit:Q,placeholder:"https://api.example.com/v1"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J&&G0(T$,{marginTop:1,children:G0(O$,{color:"red",children:["❌ ",J]},void 0,!0,void 0,this)},void 0,!1,void 0,this),G0(T$,{marginTop:1,children:G0(O$,{dimColor:!0,children:["\uD83D\uDCA1 输入完成后按 ",G0(O$,{bold:!0,children:"Enter"},void 0,!1,void 0,this),",",G0(O$,{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)};Z6();import{useMemoizedFn as y7,useMount as eb}from"ahooks";import{Box as G1,Text as v0,useFocus as $A,useFocusManager as ZA,useInput as YA}from"ink";import QA from"ink-select-input";import{memo as XA,useMemo as JA,useState as v7}from"react";T0();import{jsxDEV as W0}from"react/jsx-dev-runtime";function qA($){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 GA=({isSelected:$})=>W0(G1,{marginRight:1,children:W0(v0,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),KA=({isSelected:$,label:Z})=>W0(v0,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),tU=XA(({onClose:$,onEdit:Z})=>{let Y=YW(),Q=QW()??"",{isFocused:X}=$A({id:"model-selector"}),J=ZA(),[q,G]=v7(""),[K,W]=v7(!1),[U,F]=v7(null),O=Z$(!1),[H]=v7(()=>{let y=process.stdout?.columns||80;return Math.max(20,y-8)});eb(()=>{if(J?.focus("model-selector"),Y.length>0)G(Y[0].id)}),YA((y,I)=>{if(K)return;if(I.ctrl&&y==="c"||I.meta&&y==="c"){O();return}if(I.escape){$();return}if(!X)return;if(y==="d"||y==="D"){z();return}if((y==="e"||y==="E")&&Z)w()},{isActive:!0});let _=y7(async(y)=>{if(K)return;let I=y.value;if(I===Q){$();return}W(!0),F(null);try{await C0().setCurrentModel(I),$()}catch(N){F(N.message),W(!1)}}),z=y7(async()=>{if(K||q===Q)return;W(!0),F(null);try{if(await C0().removeModel(q),Y.length<=1)$()}catch(y){F(y.message)}finally{W(!1)}}),w=y7(()=>{if(K||!Z)return;let y=Y.find((I)=>I.id===q);if(!y)return;Z(y)}),B=y7((y)=>{G(y.value)}),L=JA(()=>{return Y.find((y)=>y.id===q)},[Y,q]),V=Y.map((y)=>{let I=y.id===Q?" (当前)":"";return{label:y.name+I,value:y.id}}),D=q===Q;return W0(G1,{flexDirection:"column",borderStyle:"round",borderColor:"gray",padding:1,width:"100%",children:[W0(G1,{flexDirection:"row",justifyContent:"space-between",marginBottom:1,children:[W0(v0,{bold:!0,color:"cyan",children:"模型管理"},void 0,!1,void 0,this),W0(v0,{dimColor:!0,children:[K?"⏳ 处理中...":D?"Enter=关闭 • E=编辑 • Esc=取消":"Enter=切换 • D=删除 • E=编辑 • Esc=取消"," • Ctrl+C=退出"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),W0(G1,{flexDirection:"row",children:[W0(G1,{flexDirection:"column",flexGrow:2,marginRight:2,borderStyle:"single",borderColor:"gray",padding:1,children:[W0(v0,{dimColor:!0,children:["已配置模型 (",Y.length,")"]},void 0,!0,void 0,this),W0(G1,{marginTop:1,children:W0(QA,{items:V,onSelect:_,onHighlight:B,indicatorComponent:GA,itemComponent:KA},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),W0(G1,{flexDirection:"column",flexGrow:3,borderStyle:"single",borderColor:"gray",padding:1,children:[W0(v0,{dimColor:!0,children:"模型详情"},void 0,!1,void 0,this),W0(G1,{marginY:1,children:W0(v0,{color:D?"green":"yellow",children:D?"● 当前使用":"● 可切换"},void 0,!1,void 0,this)},void 0,!1,void 0,this),L?W0(G1,{flexDirection:"column",children:[W0(v0,{children:[W0(v0,{dimColor:!0,children:"名称: "},void 0,!1,void 0,this),W0(v0,{bold:!0,color:"cyan",children:L.name},void 0,!1,void 0,this),T9(L)&&W0(v0,{color:"green",children:" (内置免费)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),W0(v0,{children:[W0(v0,{dimColor:!0,children:"Provider: "},void 0,!1,void 0,this),W0(v0,{bold:!0,children:qA(L.provider)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),W0(v0,{children:[W0(v0,{dimColor:!0,children:"Model: "},void 0,!1,void 0,this),W0(v0,{bold:!0,children:L.model},void 0,!1,void 0,this)]},void 0,!0,void 0,this),W0(v0,{children:[W0(v0,{dimColor:!0,children:"Base URL: "},void 0,!1,void 0,this),W0(v0,{color:"blueBright",children:L.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L.temperature!==void 0&&W0(v0,{children:[W0(v0,{dimColor:!0,children:"Temperature: "},void 0,!1,void 0,this),W0(v0,{children:L.temperature},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L.maxContextTokens!==void 0&&W0(v0,{children:[W0(v0,{dimColor:!0,children:"Context Window: "},void 0,!1,void 0,this),W0(v0,{children:L.maxContextTokens},void 0,!1,void 0,this)]},void 0,!0,void 0,this),T9(L)&&W0(G1,{marginTop:1,children:W0(v0,{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):W0(v0,{dimColor:!0,children:"请选择一个模型查看详情"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),U&&W0(G1,{marginTop:1,children:W0(v0,{color:"red",children:["❌ ",U]},void 0,!0,void 0,this)},void 0,!1,void 0,this),W0(G1,{justifyContent:"center",marginTop:1,children:W0(v0,{dimColor:!0,children:"─".repeat(H)},void 0,!1,void 0,this)},void 0,!1,void 0,this),W0(G1,{justifyContent:"center",children:W0(v0,{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 d8}from"ahooks";import{promises as YF}from"fs";import{Box as K1,Text as t0,useInput as WA}from"ink";import eU from"ink-select-input";import UA from"ink-text-input";import FA from"os";import T7 from"path";import{useEffect as OA,useMemo as E7,useRef as HA,useState as $4}from"react";T0();import{jsxDEV as _0}from"react/jsx-dev-runtime";var c8=[{key:"allow",label:"Allow"},{key:"ask",label:"Ask"},{key:"deny",label:"Deny"},{key:"info",label:"Info"}],_A={allow:"Add a new rule...",ask:"Add a new rule...",deny:"Add a new rule..."},zA={allow:"Allow permission rules",ask:"Ask permission rules",deny:"Deny permission rules"},$F={project:"[项目共享配置]",global:"[用户全局配置]",local:"[本地配置]"},BA=["project","global","local"],wA={allow:[],ask:[],deny:[]},LA={localExists:!1,projectExists:!1,globalExists:!1},ZF={allow:[],ask:[],deny:[]};function NA($){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 bA($){try{let Z=await YF.readFile($,"utf-8"),Y=JSON.parse(Z);return{exists:!0,raw:Y,permissions:NA(Y)}}catch(Z){if(Z.code==="ENOENT")return{exists:!1,raw:{},permissions:{...ZF}};return console.warn(`[PermissionsManager] Failed to read ${$}:`,Z),{exists:!0,raw:{},permissions:{...ZF}}}}function AA($,Z){let Y=$.padEnd(32," "),Q=Z==="local"?`${$F[Z]} ← 可删除`:$F[Z];return`${Y} ${Q}`}var QF=({onClose:$})=>{let Y=Z1()==="permissions-manager",Q=Z$(!1),[X,J]=$4(0),q=c8[X].key,[G,K]=$4(wA),[W,U]=$4(LA),[F,O]=$4(!0),[H,_]=$4("list"),[z,w]=$4(""),[B,L]=$4(null),[V,D]=$4(null),R=HA(!1),y=E7(()=>T7.join(process.cwd(),".blade","settings.local.json"),[]),I=E7(()=>T7.join(process.cwd(),".blade","settings.json"),[]),N=E7(()=>T7.join(FA.homedir(),".blade","settings.json"),[]),P=d8(async()=>{O(!0);let d=[{source:"local",path:y},{source:"project",path:I},{source:"global",path:N}],s=await Promise.all(d.map(async({source:U0,path:M0})=>{let $$=await bA(M0);return{source:U0,path:M0,...$$}})),k={localExists:s.find((U0)=>U0.source==="local")?.exists??!1,projectExists:s.find((U0)=>U0.source==="project")?.exists??!1,globalExists:s.find((U0)=>U0.source==="global")?.exists??!1};U(k);let a={allow:[],ask:[],deny:[]},n=Object.fromEntries(s.map((U0)=>[U0.source,U0]));["allow","ask","deny"].forEach((U0)=>{BA.forEach((M0)=>{(n[M0]?.permissions[U0]??[]).forEach((j2,E$)=>{let X0={key:`${M0}:${E$}:${j2}`,rule:j2,source:M0};a[U0].push(X0)})})}),K(a),O(!1)});OA(()=>{P()},[P]);let m=d8(async(d,s)=>{try{let k=T7.join(process.cwd(),".blade","settings.local.json"),a={allow:[],ask:[],deny:[]};try{let U0=await YF.readFile(k,"utf-8"),$$=JSON.parse(U0).permissions||{};a={allow:Array.isArray($$.allow)?$$.allow:[],ask:Array.isArray($$.ask)?$$.ask:[],deny:Array.isArray($$.deny)?$$.deny:[]}}catch(U0){}let n=s(a);await C0().updateConfig({permissions:n},{scope:"local",immediate:!0}),await P()}catch(k){throw console.error("[PermissionsManager] 修改权限规则失败:",k),k}});WA((d,s)=>{if(s.ctrl&&d==="c"||s.meta&&d==="c"){Q();return}if(H==="locked"){if(R.current){R.current=!1;return}_("list"),L(null),D(null);return}if(s.escape){if(H==="list"||q==="info")$();else _("list"),w(""),L(null),D(null);return}if(H==="list"){if(s.tab&&s.shift)J((k)=>(k-1+c8.length)%c8.length);else if(s.tab)J((k)=>(k+1)%c8.length);else if(d?.toLowerCase()==="q")$()}},{isActive:Y});let e=d8((d)=>{let s=d.value;if(q==="info")return;if(s.type==="add"){_("add"),w(""),D(null);return}if(s.entry.source!=="local"){_("locked"),R.current=!0,L({tab:q,entry:s.entry}),D({type:"error",text:s.entry.source==="project"?"此规则定义在项目共享配置中,无法在此删除。":"此规则来自用户全局配置,无法在此删除。"});return}_("confirm-delete"),L({tab:q,entry:s.entry}),D(null)}),S=d8(async()=>{if(q==="info")return;let d=z.trim();if(!d){D({type:"error",text:"Permission rule 不能为空"});return}if(G[q].map((k)=>k.rule).includes(d)){D({type:"error",text:"该规则已存在"});return}try{await m(q,(k)=>{let a={allow:[...k.allow],ask:[...k.ask],deny:[...k.deny]};return a[q]=[...new Set([...k[q],d])],a}),_("list"),w(""),D({type:"success",text:"已添加本地权限规则"})}catch(k){D({type:"error",text:`保存失败: ${k instanceof Error?k.message:"未知错误"}`})}}),T=d8(async()=>{if(!B)return;let{tab:d,entry:s}=B;try{await m(d,(k)=>{let a={allow:[...k.allow],ask:[...k.ask],deny:[...k.deny]};return a[d]=k[d].filter((n)=>n!==s.rule),a}),_("list"),L(null),D({type:"success",text:"已删除本地权限规则"})}catch(k){D({type:"error",text:`删除失败: ${k instanceof Error?k.message:"未知错误"}`})}}),g=E7(()=>{if(q==="info")return[];let d=q;return[{key:"add-new-rule",label:`› ${_A[d]}`,value:{type:"add"}},...G[d].map((k)=>({key:k.key,label:AA(k.rule,k.source),value:{type:"rule",entry:k}}))]},[q,G]),j=()=>_0(K1,{marginBottom:1,children:c8.map((d,s)=>_0(K1,{marginRight:2,children:_0(t0,{color:s===X?"yellow":"gray",children:["[",d.label,"]"]},void 0,!0,void 0,this)},d.key,!1,void 0,this))},void 0,!1,void 0,this),M=()=>_0(K1,{flexDirection:"column",gap:1,children:[_0(t0,{children:"配置文件优先级(从高到低):"},void 0,!1,void 0,this),_0(K1,{flexDirection:"column",marginLeft:2,children:[_0(t0,{children:["1. .blade/settings.local.json (本地配置,不提交 Git)"," ",W.localExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),_0(t0,{children:["2. .blade/settings.json (项目配置,提交 Git)"," ",W.projectExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),_0(t0,{children:["3. ~/.blade/settings.json (用户全局配置)"," ",W.globalExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),_0(t0,{children:"说明:"},void 0,!1,void 0,this),_0(K1,{flexDirection:"column",marginLeft:2,children:[_0(t0,{children:"- /permissions 命令只管理本地配置 (.blade/settings.local.json)"},void 0,!1,void 0,this),_0(t0,{children:"- 修改全局或项目配置请直接编辑对应文件"},void 0,!1,void 0,this),_0(t0,{children:"- 本地配置不会提交到 Git"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),A=(d)=>_0(K1,{flexDirection:"column",gap:1,children:[_0(t0,{bold:!0,children:zA[d]},void 0,!1,void 0,this),_0(t0,{children:"Permission rules are a tool name, optionally followed by a specifier in parentheses."},void 0,!1,void 0,this),_0(t0,{color:"gray",children:"例如: WebFetch 或 Bash(ls:*)"},void 0,!1,void 0,this),_0(K1,{marginTop:1,children:_0(UA,{value:z,onChange:w,onSubmit:S},void 0,!1,void 0,this)},void 0,!1,void 0,this),_0(t0,{color:"gray",children:"Enter 提交 · Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),r=(d,s)=>_0(K1,{flexDirection:"column",gap:1,children:[_0(t0,{bold:!0,children:["Delete ",d," permission rule?"]},void 0,!0,void 0,this),_0(t0,{children:s.rule},void 0,!1,void 0,this),_0(t0,{color:"gray",children:"From project local settings"},void 0,!1,void 0,this),_0(t0,{children:"Are you sure you want to delete this permission rule?"},void 0,!1,void 0,this),_0(eU,{items:[{label:"Yes",value:"yes"},{label:"No",value:"no"}],onSelect:(k)=>{if(k.value==="yes")T();else _("list"),L(null)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),E=(d)=>_0(K1,{flexDirection:"column",gap:1,children:[_0(t0,{bold:!0,children:"Cannot delete this rule"},void 0,!1,void 0,this),_0(t0,{children:d.rule},void 0,!1,void 0,this),_0(t0,{color:"gray",children:d.source==="project"?"This rule is defined in .blade/settings.json. 请手动编辑该文件以移除规则。":"This rule is defined in ~/.blade/settings.json. 请手动编辑该文件以移除规则。"},void 0,!1,void 0,this),_0(t0,{color:"gray",children:"按任意键继续"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),u=(d)=>_0(eU,{items:g,isFocused:H==="list",onSelect:e},void 0,!1,void 0,this),Z0=()=>{if(F)return _0(t0,{children:"加载中..."},void 0,!1,void 0,this);if(q==="info")return M();if(H==="add")return A(q);if(H==="confirm-delete"&&B)return r(B.tab,B.entry);if(H==="locked"&&B)return E(B.entry);return u(q)};return _0(K1,{flexDirection:"column",borderStyle:"round",borderColor:Y?"cyan":"gray",padding:1,width:80,children:[_0(t0,{color:"cyan",bold:!0,children:"⚙️ 权限管理器"},void 0,!1,void 0,this),j(),_0(K1,{flexDirection:"column",gap:1,children:Z0()},void 0,!1,void 0,this),V&&_0(K1,{marginTop:1,children:_0(t0,{color:V.type==="success"?"green":"red",children:V.text},void 0,!1,void 0,this)},void 0,!1,void 0,this),_0(K1,{marginTop:1,children:_0(t0,{color:"gray",children:"Tab 切换视图 · Esc 关闭 · Q 退出"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};b3();import{Box as o0,Text as L0,useInput as RA}from"ink";import{jsxDEV as i}from"react/jsx-dev-runtime";function XF({onCancel:$}){let Z=a$(),Y=Z.getAll(),Q=Z.getBySource(),X=Z.getStats(),J=Z$(!1,$);if(RA((q,G)=>{if(G.escape)$?.();else if(G.ctrl&&q==="c"||G.meta&&q==="c")J()}),Y.length===0)return i(o0,{flexDirection:"column",paddingY:1,children:[i(o0,{marginBottom:1,children:i(L0,{bold:!0,color:"cyan",children:"\uD83D\uDD0C 插件管理器"},void 0,!1,void 0,this)},void 0,!1,void 0,this),i(o0,{paddingLeft:2,children:i(L0,{color:"gray",children:"没有已加载的插件"},void 0,!1,void 0,this)},void 0,!1,void 0,this),i(o0,{marginTop:1,paddingLeft:2,flexDirection:"column",children:[i(L0,{color:"gray",children:"插件目录位置:"},void 0,!1,void 0,this),i(L0,{color:"gray",dimColor:!0,children:[" ","• ~/.blade/plugins/ - 用户级插件"]},void 0,!0,void 0,this),i(L0,{color:"gray",dimColor:!0,children:[" ","• .blade/plugins/ - 项目级插件"]},void 0,!0,void 0,this),i(L0,{color:"gray",dimColor:!0,children:[" ","• --plugin-dir - CLI 指定的插件"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),i(o0,{marginTop:1,paddingLeft:2,children:i(L0,{color:"gray",children:"使用 /plugins install <url> 安装新插件"},void 0,!1,void 0,this)},void 0,!1,void 0,this),i(o0,{marginTop:1,children:i(L0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return i(o0,{flexDirection:"column",paddingY:1,children:[i(o0,{marginBottom:1,children:[i(L0,{bold:!0,color:"cyan",children:"\uD83D\uDD0C 插件管理器"},void 0,!1,void 0,this),i(L0,{color:"gray",children:[" (共 ",X.total," 个插件)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),i(o0,{paddingLeft:2,marginBottom:1,children:i(L0,{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&&i(o0,{flexDirection:"column",marginBottom:1,children:[i(o0,{paddingLeft:1,children:[i(L0,{bold:!0,color:"magenta",children:"CLI 指定"},void 0,!1,void 0,this),i(L0,{color:"gray",children:" (--plugin-dir)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.cli.map((q)=>{let G=q.status==="active"?"✅":"⏸️";return i(o0,{flexDirection:"column",paddingLeft:2,children:[i(L0,{children:[i(L0,{bold:!0,color:"green",children:[G," ",q.manifest.name]},void 0,!0,void 0,this),i(L0,{color:"gray",children:[" v",q.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),i(o0,{paddingLeft:2,children:i(L0,{color:"gray",children:q.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),q.commands.length>0&&i(o0,{paddingLeft:2,children:i(L0,{color:"blue",children:["命令:"," ",q.commands.map((K)=>`/${K.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},q.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.project.length>0&&i(o0,{flexDirection:"column",marginBottom:1,children:[i(o0,{paddingLeft:1,children:[i(L0,{bold:!0,color:"yellow",children:"项目级"},void 0,!1,void 0,this),i(L0,{color:"gray",children:" (.blade/plugins/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.project.map((q)=>{let G=q.status==="active"?"✅":"⏸️";return i(o0,{flexDirection:"column",paddingLeft:2,children:[i(L0,{children:[i(L0,{bold:!0,color:"green",children:[G," ",q.manifest.name]},void 0,!0,void 0,this),i(L0,{color:"gray",children:[" v",q.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),i(o0,{paddingLeft:2,children:i(L0,{color:"gray",children:q.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),q.commands.length>0&&i(o0,{paddingLeft:2,children:i(L0,{color:"blue",children:["命令:"," ",q.commands.map((K)=>`/${K.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},q.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.user.length>0&&i(o0,{flexDirection:"column",marginBottom:1,children:[i(o0,{paddingLeft:1,children:[i(L0,{bold:!0,color:"cyan",children:"用户级"},void 0,!1,void 0,this),i(L0,{color:"gray",children:" (~/.blade/plugins/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.user.map((q)=>{let G=q.status==="active"?"✅":"⏸️";return i(o0,{flexDirection:"column",paddingLeft:2,children:[i(L0,{children:[i(L0,{bold:!0,color:"green",children:[G," ",q.manifest.name]},void 0,!0,void 0,this),i(L0,{color:"gray",children:[" v",q.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),i(o0,{paddingLeft:2,children:i(L0,{color:"gray",children:q.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),q.commands.length>0&&i(o0,{paddingLeft:2,children:i(L0,{color:"blue",children:["命令:"," ",q.commands.map((K)=>`/${K.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},q.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),i(o0,{marginTop:1,paddingLeft:2,flexDirection:"column",children:[i(L0,{color:"gray",children:"可用命令:"},void 0,!1,void 0,this),i(L0,{color:"gray",dimColor:!0,children:[" ","• /plugins list - 列出所有插件"]},void 0,!0,void 0,this),i(L0,{color:"gray",dimColor:!0,children:[" ","• /plugins info <name> - 显示插件详情"]},void 0,!0,void 0,this),i(L0,{color:"gray",dimColor:!0,children:[" ","• /plugins install <url> - 安装插件"]},void 0,!0,void 0,this),i(L0,{color:"gray",dimColor:!0,children:[" ","• /plugins enable/disable <name> - 启用/禁用插件"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),i(o0,{marginTop:1,children:i(L0,{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 f$,Text as h$,useInput as JF,useStdout as VA}from"ink";import DA from"ink-text-input";import BY,{useCallback as l8,useMemo as MA,useState as Z4}from"react";import{jsxDEV as A0}from"react/jsx-dev-runtime";var jA=BY.memo(({option:$,index:Z,isSelected:Y,isMultiSelect:Q,isHighlighted:X})=>A0(f$,{flexDirection:"column",marginBottom:1,children:[A0(h$,{color:X?"yellow":Y?"green":void 0,bold:X,children:[Q?Y?"● ":"○ ":X?"❯ ":" ",Z+1,". ",$.label]},void 0,!0,void 0,this),A0(f$,{marginLeft:4,children:A0(h$,{color:"gray",children:$.description},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)),IA=BY.memo(({questions:$,answers:Z})=>A0(f$,{flexDirection:"column",marginBottom:1,children:$.map((Y)=>{let Q=Z[Y.header],X=Array.isArray(Q)?Q.join(", "):Q||"(no answer)";return A0(f$,{marginBottom:1,children:[A0(h$,{backgroundColor:"blue",color:"white",children:[" ",Y.header," "]},void 0,!0,void 0,this),A0(h$,{color:"green",children:[" ",X]},void 0,!0,void 0,this)]},Y.header,!0,void 0,this)})},void 0,!1,void 0,this)),qF=BY.memo(({questions:$,onComplete:Z,onCancel:Y})=>{let{stdout:Q}=VA(),X=Q.columns||80,q=Z1()==="confirmation-prompt",G=Z$(!1),[K,W]=Z4("answering"),[U,F]=Z4(0),[O,H]=Z4({}),[_,z]=Z4(0),[w,B]=Z4([]),[L,V]=Z4(!1),[D,R]=Z4(""),[y,I]=Z4(0),N=$[U],P=MA(()=>{if(!N)return[];return[...N.options.map((j)=>({label:j.label,value:j.label,description:j.description})),{label:"Type something...",value:"__other__",description:"Enter custom response"}]},[N]),m=l8((j)=>{let M={...O,[N.header]:j};if(H(M),U<$.length-1)F(U+1),z(0),B([]),V(!1),R("");else W("submit"),I(0)},[O,N?.header,U,$.length]),e=l8((j)=>{let M=P[j];if(!M)return;if(M.value==="__other__"){V(!0);return}if(N.multiSelect)B((A)=>A.includes(M.value)?A.filter((r)=>r!==M.value):[...A,M.value]);else m(M.value)},[P,N?.multiSelect,m]),S=l8((j)=>{if(j.trim())m(j.trim())},[m]),T=l8(()=>{W("answering"),F(0),z(0),B([]),V(!1)},[]),g=l8(()=>{Z(O)},[O,Z]);if(JF((j,M)=>{if(M.ctrl&&j==="c"||M.meta&&j==="c"){G();return}if(L){if(M.escape)V(!1),R("");return}if(M.escape){Y();return}let A=parseInt(j);if(A>=1&&A<=P.length){e(A-1);return}if(M.upArrow){z((r)=>r>0?r-1:P.length-1);return}if(M.downArrow||M.tab){z((r)=>r<P.length-1?r+1:0);return}if(M.return){if(N.multiSelect&&w.length>0)m(w);else e(_);return}if(j===" "&&N.multiSelect){let r=P[_];if(r&&r.value!=="__other__")B((E)=>E.includes(r.value)?E.filter((u)=>u!==r.value):[...E,r.value]);return}},{isActive:q&&K==="answering"&&!L}),JF((j,M)=>{if(M.ctrl&&j==="c"||M.meta&&j==="c"){G();return}if(M.escape){Y();return}if(M.upArrow||M.downArrow||M.tab){I((A)=>A===0?1:0);return}if(M.return){if(y===0)g();else T();return}if(j.toLowerCase()==="y"){g();return}if(j.toLowerCase()==="e"){T();return}},{isActive:q&&K==="submit"}),K==="submit")return A0(f$,{flexDirection:"column",borderStyle:"round",borderColor:q?"green":"gray",padding:1,width:Math.min(X-4,80),children:[A0(f$,{marginBottom:1,children:A0(h$,{bold:!0,color:"green",children:"✓ Review Your Answers"},void 0,!1,void 0,this)},void 0,!1,void 0,this),A0(IA,{questions:$,answers:O},void 0,!1,void 0,this),A0(f$,{flexDirection:"column",marginTop:1,children:[A0(h$,{color:y===0?"yellow":void 0,bold:y===0,children:[y===0?"❯ ":" ","[Y] Submit answers"]},void 0,!0,void 0,this),A0(h$,{color:y===1?"yellow":void 0,bold:y===1,children:[y===1?"❯ ":" ","[E] Edit answers"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),A0(f$,{marginTop:1,children:A0(h$,{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(!N)return null;return A0(f$,{flexDirection:"column",borderStyle:"round",borderColor:q?"cyan":"gray",padding:1,width:Math.min(X-4,80),children:[A0(f$,{marginBottom:1,children:[A0(h$,{backgroundColor:"blue",color:"white",children:[" ",N.header," "]},void 0,!0,void 0,this),A0(h$,{children:[" ",N.question]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),L?A0(f$,{flexDirection:"column",marginTop:1,children:[A0(h$,{color:"yellow",children:"Enter your response:"},void 0,!1,void 0,this),A0(f$,{marginTop:1,children:[A0(h$,{color:"cyan",children:"❯ "},void 0,!1,void 0,this),A0(DA,{value:D,onChange:R,onSubmit:S,focus:q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A0(f$,{marginTop:1,children:A0(h$,{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):A0(f$,{flexDirection:"column",children:P.map((j,M)=>A0(jA,{option:j,index:M,isSelected:w.includes(j.value),isMultiSelect:N.multiSelect,isHighlighted:_===M},j.value,!1,void 0,this))},void 0,!1,void 0,this),!L&&A0(f$,{marginTop:1,flexDirection:"column",children:[A0(h$,{color:"gray",children:N.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),N.multiSelect&&w.length>0&&A0(h$,{color:"green",children:["Selected: ",w.join(", ")]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$.length>1&&A0(f$,{marginTop:1,children:A0(h$,{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)});t6();import{Box as m3,Text as c1,useInput as yA}from"ink";import vA from"ink-select-input";import{basename as TA}from"node:path";import{useEffect as GF,useMemo as P7,useState as wY}from"react";import{jsxDEV as D$}from"react/jsx-dev-runtime";function EA($){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 PA($){return TA($)}var CA=({isSelected:$})=>D$(m3,{marginRight:1,children:D$(c1,{color:$?"cyan":"gray",children:$?"❯":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),SA=({isSelected:$,label:Z})=>D$(c1,{color:$?"cyan":"white",bold:$,children:Z},void 0,!1,void 0,this),i8=20,KF=({sessions:$,onSelect:Z,onCancel:Y})=>{let[Q,X]=wY([]),[J,q]=wY(!1),[G,K]=wY(0),U=Z1()==="session-selector",F=Z$(!1);yA((L,V)=>{if(V.ctrl&&L==="c"||V.meta&&L==="c"){F();return}if(V.escape&&Y){Y();return}if(V.leftArrow||L==="h"||L==="H"){if(G>0)K((D)=>D-1);return}if(V.rightArrow||L==="l"||L==="L"){if(G<_-1)K((D)=>D+1);return}},{isActive:U}),GF(()=>{if($){X($);return}(async()=>{q(!0);try{let V=await w1.listSessions();X(V)}catch(V){console.error("[SessionSelector] Failed to load sessions:",V),X([])}finally{q(!1)}})()},[$]);let O=$||Q,H=P7(()=>{return O.map((L)=>{let V=PA(L.projectPath),D=EA(L.lastMessageTime),R=L.gitBranch?` (${L.gitBranch})`:"",y=L.hasErrors?" ⚠️":"";return{label:`\uD83D\uDCC5 ${D} | ${V}${R} | ${L.messageCount} 条消息${y}`,value:L.sessionId}})},[O]),_=P7(()=>Math.max(1,Math.ceil(H.length/i8)),[H.length]),z=P7(()=>{let L=G*i8;return H.slice(L,L+i8)},[H,G]),w=P7(()=>({start:G*i8+1,end:Math.min((G+1)*i8,H.length)}),[G,H.length]);GF(()=>{K(0)},[O.length]);let B=(L)=>{Z(L.value)};if(J)return D$(m3,{flexDirection:"column",paddingX:2,paddingY:1,children:D$(c1,{children:"⏳ 正在加载会话列表..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(O.length===0)return D$(m3,{flexDirection:"column",paddingX:2,paddingY:1,children:[D$(c1,{color:"yellow",children:"⚠️ 没有找到历史会话"},void 0,!1,void 0,this),D$(c1,{dimColor:!0,children:[`
|
|
2836
|
+
`)&&L.length>1,e=N<L2.RAPID_INPUT_THRESHOLD_MS&&R.chunks.length>0,S=N<L2.RAPID_INPUT_THRESHOLD_MS&&L.length>10,T=R.timeoutId!==null;if(q&&(P||m||e||S||T)){R.chunks.push(L),R.totalLength+=L.length,O();return}if(L.length===1&&!R.timeoutId)R.chunks=[],R.firstInputTime=null,R.lastInputTime=null,R.totalLength=0;I=$.slice(0,X)+L+$.slice(X,$.length),y+=L.length}if(y<0)y=0;if(y>I.length)y=I.length;if(I!==$)Q(I);if(y!==X)J(y)},{isActive:Y});let H=Y,_=$,z=Z?k4.grey(Z):void 0;if(H)if(z=Z.length>0?k4.inverse(Z[0])+k4.grey(Z.slice(1)):k4.inverse(" "),$.length===0)_=k4.inverse(" ");else{_="";for(let w=0;w<$.length;w++)if(w===X&&X<$.length)_+=k4.inverse($[w]);else _+=$[w];if(X>=$.length)_+=k4.inverse(" ")}return Zb(sN,{children:Z?$.length>0?_:z:_},void 0,!1,void 0,this)}import{jsxDEV as JY}from"react/jsx-dev-runtime";var BU=Xb.memo(({input:$,cursorPosition:Z,onChange:Y,onChangeCursorPosition:Q,onAddPasteMapping:X,onAddImagePasteMapping:J})=>{let G=Z1()==="main-input",K=zU((U)=>{let F=U.split(`
|
|
2837
|
+
`).length,O=U.length,H=500,_=10;if(O>500||F>10){let z=X(U),w=U.slice(0,30).replace(/\n/g," "),B=`${O} chars, ${F} lines: ${w}...`;return{prompt:`${F7(z)}${B}${TZ()}`}}return{}}),W=zU(async(U,F,O)=>{try{let H=J(U,F);return{prompt:`${F7(H)}[Image #${H}]${TZ()}`}}catch(H){return console.error("[Image Paste] Failed to process image:",H),{prompt:`[Image paste failed: ${H instanceof Error?H.message:"Unknown error"}] `}}});return JY(Yb,{flexDirection:"row",width:"100%",paddingX:2,paddingY:0,flexShrink:0,flexGrow:0,overflow:"hidden",borderStyle:"round",borderColor:"gray",children:[JY(Qb,{color:"blue",bold:!0,children:"> "},void 0,!1,void 0,this),JY(_U,{value:$,cursorPosition:Z,onChange:Y,onChangeCursorPosition:Q,onPaste:K,onImagePaste:W,placeholder:" 输入命令...",focus:G,disabledKeys:["upArrow","downArrow","tab","return","escape"]},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});import{Box as V7,Text as u1}from"ink";import Wb,{useEffect as Ub,useState as Fb}from"react";import{useEffect as Kb,useState as bU}from"react";import{useEffect as Jb,useState as qb}from"react";var Gb=15000,wU=["炼化代码灵气...","参悟 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 广纳贤才..."],LU=["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 NU($,Z,Y=!1){let[Q,X]=qb("");return Jb(()=>{if(Z){X("等待用户确认...");return}if(!$){X("");return}if(Y)return;let J=()=>{if(Math.random()<0.16666666666666666){let W=Math.floor(Math.random()*LU.length);return LU[W]}let K=Math.floor(Math.random()*wU.length);return wU[K]};X(J());let q=setInterval(()=>{X(J())},Gb);return()=>{clearInterval(q)}},[$,Z,Y]),Q}function AU($,Z=!1,Y=!1){let[Q,X]=bU(0),[J,q]=bU(null),G=NU($,Z,Y);return Kb(()=>{if(!$){X(0),q(null);return}if(Y)return;if(J===null)q(Date.now());let K=setInterval(()=>{if(J!==null){let W=Math.floor((Date.now()-J)/1000);X(W)}},1000);return()=>{clearInterval(K)}},[$,J,Y]),{currentPhrase:G,elapsedTime:Q}}import{jsxDEV as k$,Fragment as Hb}from"react/jsx-dev-runtime";var qY=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"],Ob=80;function RU($){if($<60)return`${$}s`;let Z=Math.floor($/60),Y=$%60;return`${Z}m ${Y}s`}var VU=Wb.memo(({message:$,paused:Z=!1})=>{let Y=a2(),Q=J7(),X=Y||!Q,[J,q]=Fb(0),G=m0(),W=T3()>=Ob,{currentPhrase:U,elapsedTime:F}=AU(X,!1,Z);if(Ub(()=>{if(!X||Z){q(0);return}let H=setInterval(()=>{q((_)=>(_+1)%qY.length)},80);return()=>clearInterval(H)},[X,Z]),!X)return null;let O=U||$||"正在思考中...";if(W)return k$(V7,{paddingX:2,paddingBottom:1,flexDirection:"row",gap:1,children:[k$(u1,{color:G.colors.warning,bold:!0,children:qY[J]},void 0,!1,void 0,this),k$(u1,{color:G.colors.text.primary,children:O},void 0,!1,void 0,this),F>0&&k$(Hb,{children:[k$(u1,{color:G.colors.muted,children:"|"},void 0,!1,void 0,this),k$(u1,{color:G.colors.info,children:["已用时: ",RU(F)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),k$(u1,{color:G.colors.muted,children:"|"},void 0,!1,void 0,this),k$(u1,{color:G.colors.secondary,children:"Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return k$(V7,{paddingX:2,paddingBottom:1,flexDirection:"column",children:[k$(V7,{flexDirection:"row",gap:1,children:[k$(u1,{color:G.colors.warning,bold:!0,children:qY[J]},void 0,!1,void 0,this),k$(u1,{color:G.colors.text.primary,children:O},void 0,!1,void 0,this)]},void 0,!0,void 0,this),F>0&&k$(V7,{marginLeft:2,flexDirection:"row",gap:1,children:[k$(u1,{color:G.colors.info,children:["已用时: ",RU(F)]},void 0,!0,void 0,this),k$(u1,{color:G.colors.muted,children:"|"},void 0,!1,void 0,this),k$(u1,{color:G.colors.secondary,children:"Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});import OY from"ansi-escapes";import{Box as b2,Static as TU,useStdout as Ib}from"ink";import yb,{useEffect as x4,useMemo as M7,useRef as s2,useState as HY}from"react";import{useStdout as _b}from"ink";import{debounce as zb}from"lodash-es";import{useEffect as Bb,useState as wb}from"react";function DU($=200){let{stdout:Z}=_b(),[Y,Q]=wb(Z.rows||24);return Bb(()=>{let X=zb(()=>{Q(Z.rows||24)},$);return X(),Z.on("resize",X),()=>{Z.off("resize",X),X.cancel()}},[Z,$]),Y}l3();import{Box as Lb,Text as MU}from"ink";import Nb from"react";import{jsxDEV as GY}from"react/jsx-dev-runtime";var KY=Nb.memo(({collapsedCount:$})=>{let Z=m0();if($<=0)return null;let Y=Z.colors.text.muted;return GY(Lb,{flexDirection:"row",marginBottom:1,children:[GY(MU,{color:Y,children:["▶ ",$," 条历史消息"]},void 0,!0,void 0,this),GY(MU,{color:Y,children:" [Ctrl+O 展开]"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});KY.displayName="CollapsedHistorySummary";d3();import{Box as g8,Text as u8}from"ink";import bb from"ink-big-text";import Ab from"ink-gradient";import Rb from"react";import{jsxDEV as V1}from"react/jsx-dev-runtime";var jU=Rb.memo(()=>{return V1(g8,{flexDirection:"column",paddingX:2,paddingTop:1,paddingBottom:1,children:[V1(g8,{flexDirection:"column",children:V1(Ab,{name:"pastel",children:V1(bb,{text:"BLADE",font:"block"},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),V1(g8,{marginBottom:1,children:V1(u8,{color:"white",dimColor:!0,children:vY()},void 0,!1,void 0,this)},void 0,!1,void 0,this),V1(g8,{flexDirection:"column",marginBottom:1,children:[V1(g8,{marginBottom:1,children:V1(u8,{color:"white",bold:!0,children:"使用指南:"},void 0,!1,void 0,this)},void 0,!1,void 0,this),V1(u8,{color:"white",children:"1. 输入问题、编辑文件或运行命令"},void 0,!1,void 0,this),V1(u8,{color:"white",children:"2. 使用 /init 创建项目配置文件"},void 0,!1,void 0,this),V1(u8,{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 WY,Text as x3}from"ink";import Vb,{useMemo as IU}from"react";import{jsxDEV as N2}from"react/jsx-dev-runtime";function Db($,Z=60){if(!$)return"";let Y=$.split(`
|
|
2838
|
+
`)[0]||"";if(Y.length<=Z)return Y;return`${Y.slice(0,Z)}...`}function Mb($){if(!$)return 0;return $.split(`
|
|
2839
|
+
`).length}var UY=Vb.memo(({content:$,isStreaming:Z=!1,isExpanded:Y})=>{let Q=m0(),X=IU(()=>Mb($),[$]),J=IU(()=>Db($),[$]),q=Q.colors.info,G=Q.colors.muted;return N2(WY,{flexDirection:"column",marginBottom:1,children:[N2(WY,{flexDirection:"row",children:[N2(x3,{color:q,children:Y?"▼":"▶"},void 0,!1,void 0,this),N2(x3,{children:" "},void 0,!1,void 0,this),N2(x3,{color:G,children:["Thinking",Z?"...":` (${X} lines)`]},void 0,!0,void 0,this),!Y&&!Z&&J&&N2(x3,{color:G,children:[" - ",J]},void 0,!0,void 0,this),N2(x3,{color:G,dimColor:!0,children:[" ","[Ctrl+T]"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Y&&$&&N2(WY,{marginLeft:2,marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,paddingY:0,children:N2(x3,{color:G,children:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});UY.displayName="ThinkingBlock";import{Box as D7,Text as FY}from"ink";import yU from"react";import{jsxDEV as o2}from"react/jsx-dev-runtime";var vU=yU.memo(({todos:$,visible:Z=!0,compact:Y=!1})=>{let{colors:Q}=m0();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 o2(D7,{flexDirection:"column",borderStyle:"single",borderColor:Q.border.light,paddingX:1,paddingY:Y?0:1,marginBottom:1,children:[o2(D7,{marginBottom:Y?0:1,children:[o2(FY,{dimColor:!0,children:"Tasks "},void 0,!1,void 0,this),o2(FY,{color:Q.text.muted,children:[X.completed,"/",X.total]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),o2(D7,{flexDirection:"column",children:$.map((J,q)=>o2(jb,{todo:J,compact:Y},J.id||q,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}),jb=yU.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 o2(D7,{paddingY:Z?0:0,children:o2(FY,{dimColor:Q,children:[Y," ",X]},void 0,!0,void 0,this)},void 0,!1,void 0,this)});import{jsxDEV as z$}from"react/jsx-dev-runtime";var EU=yb.memo(()=>{let $=Q7(),Z=WW(),Y=UW(),Q=FW(),X=a2(),J=sK(),q=ZW(),G=qW(),K=GW(),W=KW(),U=iK(),F=HW(),O=OW(),H=T3(),_=DU(),{stdout:z}=Ib(),w=l2(),[B,L]=HY(null),[V,D]=HY([]),[R,y]=HY(new Set),I=s2(O),N=s2(null),P=s2(0),m=s2(0),e=s2(new Set),S=s2(new Set),T=s2([]),g=s2(null);x4(()=>{if(I.current!==O){if(z)z.write(OY.clearTerminal);w.incrementClearCount(),I.current=O}},[O,z,w]);let j=$,M=Q;x4(()=>{if(!Q||X){g.current=null;return}if(g.current===Q)return;g.current=Q;let k=setTimeout(()=>{if(z)z.write(OY.clearTerminal);e.current=new Set,S.current=new Set(j.filter((a)=>a.role==="tool").map((a)=>a.id)),N.current=null,P.current=0,m.current=0,T.current=[],D([]),y(new Set),w.incrementClearCount(),w.clearFinalizingStreamingMessageId()},50);return()=>clearTimeout(k)},[Q,X,z,w,j]);let A=Z??Q;x4(()=>{N.current=null,P.current=0,m.current=0,e.current=new Set,S.current=new Set(j.filter((k)=>k.role==="tool").map((k)=>k.id)),T.current=[],D([]),y(new Set)},[U]),x4(()=>{if(!A)return;if(N.current===A)return;N.current=A,P.current=0,m.current=0,S.current=new Set(j.filter((k)=>k.role==="tool").map((k)=>k.id)),T.current=[],D([])},[A,j]),x4(()=>{if(!A)return;let k=Z9(A);if(!k||k.length<=P.current)return;let a=k.slice(P.current);P.current=k.length;let n=a,U0=T.current;if(U0.length>0)if(n.some((E$)=>E$.type!=="empty"))n=[...U0,...n],T.current=[];else{T.current=[...U0,...n];return}let M0=n.length;while(M0>0&&n[M0-1].type==="empty")M0-=1;if(M0!==n.length)T.current=n.slice(M0),n=n.slice(0,M0);if(n.length===0)return;let $$=m.current;m.current+=1;let j2=$$>0;y((E$)=>{if(!A||E$.has(A))return E$;let X0=new Set(E$);return X0.add(A),X0}),D((E$)=>[...E$,z$(b2,{flexDirection:"column",children:z$(n2,{content:"",role:"assistant",terminalWidth:H,isPending:!1,hidePrefix:j2,noMargin:!0,blocksOverride:n,renderCodeBlocksAsPlainText:!0},void 0,!1,void 0,this)},`streaming-${A}-${$$}`,!1,void 0,this)])},[A,Y.version,H,U]),x4(()=>{if(!A)return;let k=S.current,a=j.filter((n)=>n.role==="tool"&&!k.has(n.id)&&!e.current.has(n.id));if(a.length===0)return;for(let n of a)e.current.add(n.id);D((n)=>[...n,...a.map((U0)=>z$(b2,{flexDirection:"column",children:z$(n2,{content:U0.content,role:U0.role,terminalWidth:H,metadata:U0.metadata,isPending:!1,messageId:U0.id},void 0,!1,void 0,this)},`streaming-tool-${U0.id}`,!1,void 0,this))])},[A,j,H]);let r=M7(()=>{if(!A)return null;let k=tY(A);if(!k||k.lines.length===0)return null;let n=Math.max(1,_-8),U0=Math.max(0,k.lines.length-n);return{visibleLines:k.lines.slice(-n),hiddenLines:U0,mode:k.mode}},[A,Y.version,_]),E=M7(()=>{if(!A)return!1;return(Z9(A)?.length??0)>0},[A,Y.version]);x4(()=>{if(B===null&&j.length>F){if(L(j.length),z)z.write(OY.clearTerminal);w.incrementClearCount()}},[j.length,F,B,z,w]);let u=M7(()=>{return J.some((k)=>k.status==="pending"||k.status==="in_progress")},[J]),Z0=O?0:B??0,d=Z0,s=M7(()=>{let k=[];if(k.push(z$(jU,{},"header",!1,void 0,this)),d>0)k.push(z$(KY,{collapsedCount:d},"collapsed-summary",!1,void 0,this));for(let a=Z0;a<j.length;a++){let n=j[a];if(M&&n.id===M)continue;if(n.role==="tool"&&e.current.has(n.id))continue;if(n.role==="assistant"&&R.has(n.id))continue;k.push(z$(b2,{flexDirection:"column",children:z$(n2,{content:n.content,role:n.role,terminalWidth:H,metadata:n.metadata,isPending:!1,messageId:n.id},void 0,!1,void 0,this)},n.id,!1,void 0,this))}return k},[j,Z0,d,H,M,R]);return z$(b2,{flexDirection:"column",paddingX:2,children:z$(b2,{flexDirection:"column",children:[z$(TU,{items:s,children:(k)=>k},U,!1,void 0,this),K&&z$(b2,{marginBottom:1,children:z$(UY,{content:K,isStreaming:X,isExpanded:W},void 0,!1,void 0,this)},void 0,!1,void 0,this),V.length>0&&z$(TU,{items:V,children:(k)=>k},`streaming-${U}`,!1,void 0,this),r&&z$(b2,{flexDirection:"column",children:z$(n2,{content:"",role:"assistant",terminalWidth:H,isPending:!0,hidePrefix:E,streamingLines:r.visibleLines,streamingHiddenLines:r.hiddenLines,streamingMode:r.mode},void 0,!1,void 0,this)},void 0,!1,void 0,this),q&&u&&z$(b2,{marginTop:1,children:z$(vU,{todos:J,visible:!0,compact:!1},void 0,!1,void 0,this)},void 0,!1,void 0,this),G.map((k,a)=>z$(b2,{flexDirection:"column",children:z$(n2,{content:k.displayText,role:"user",terminalWidth:H},void 0,!1,void 0,this)},`pending-${a}`,!1,void 0,this))]},void 0,!0,void 0,this)},void 0,!1,void 0,this)});T0();import{useMemoizedFn as R2}from"ahooks";import{Box as T$,Text as O$,useFocusManager as ob,useInput as sU}from"ink";import sb from"ink-text-input";import{useState as e2}from"react";import{Box as A2,Text as J1,useInput as vb}from"ink";import Tb from"ink-text-input";import{jsxDEV as Q$}from"react/jsx-dev-runtime";var PU=({provider:$,value:Z,onChange:Y,onSubmit:Q,onCancel:X,error:J})=>{vb((G,K)=>{if(K.escape)X()});let q=$.envVars.length>0?$.envVars[0]:null;return Q$(A2,{flexDirection:"column",children:[Q$(A2,{marginBottom:1,children:Q$(J1,{bold:!0,color:"blue",children:"\uD83D\uDD11 Step 2: 输入 API Key"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q$(A2,{marginBottom:1,children:Q$(J1,{children:["Provider: ",$.icon," ",Q$(J1,{bold:!0,children:$.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),q&&Q$(A2,{marginBottom:1,children:Q$(J1,{dimColor:!0,children:["\uD83D\uDCA1 环境变量: ",Q$(J1,{color:"cyan",children:q},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),$.docUrl&&Q$(A2,{marginBottom:1,children:Q$(J1,{dimColor:!0,children:["\uD83D\uDCD6 文档: ",Q$(J1,{color:"blue",children:$.docUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q$(A2,{marginBottom:1,children:Q$(J1,{dimColor:!0,children:"您的 API 密钥将被安全存储在 ~/.blade/config.json (权限 600)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q$(A2,{children:[Q$(J1,{bold:!0,color:"cyan",children:["▶"," "]},void 0,!0,void 0,this),Q$(Tb,{value:Z,onChange:Y,onSubmit:Q,placeholder:"sk-...",mask:"*"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J&&Q$(A2,{marginTop:1,children:Q$(J1,{color:"red",children:["❌ ",J]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q$(A2,{marginTop:1,children:Q$(J1,{dimColor:!0,children:["\uD83D\uDCA1 输入完成后按 ",Q$(J1,{bold:!0,children:"Enter"},void 0,!1,void 0,this),",",Q$(J1,{bold:!0,children:"Esc"},void 0,!1,void 0,this)," 返回"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{useEffect as fU,useState as p3}from"react";z0();t3();var I7=l("Service"),Eb="https://models.dev/api.json",Pb=3600000,j7=null,CU=async()=>{if(j7&&Date.now()-j7.timestamp<Pb)return j7.data;try{I7.info("\uD83D\uDCE1 Fetching models.dev data...");let $=await fetch(Eb,{headers:{"User-Agent":"Blade-CLI/1.0"}});if(!$.ok)throw Error(`HTTP ${$.status}: ${$.statusText}`);let Z=await $.json();return j7={data:Z,timestamp:Date.now()},I7.info(`✅ Loaded ${Object.keys(Z).length} providers from models.dev`),Z}catch($){throw I7.error("❌ Failed to fetch models.dev data:",$),$}},SU=async()=>{let $=await CU(),Z=[];for(let[Y,Q]of Object.entries($)){let X=Object.keys(Q.models||{}).length;if(X===0)continue;Z.push({id:Y,name:Q.name||Y,icon:P9[Y]||P9.default,description:`${X} 个模型`,isOAuth:!1,envVars:Q.env||[],docUrl:Q.doc,defaultBaseUrl:Y6[Y],bladeProvider:rQ(Y)})}return Z.sort((Y,Q)=>{let X=E9.indexOf(Y.id),J=E9.indexOf(Q.id);if(X!==-1&&J!==-1)return X-J;if(X!==-1)return-1;if(J!==-1)return 1;return Y.name.localeCompare(Q.name)})},kU=async($)=>{let Y=(await CU())[$];if(!Y?.models)return I7.warn(`⚠️ No models found for provider: ${$}`),[];return Object.values(Y.models).map((Q)=>({id:Q.id,name:Q.name||Q.id,contextWindow:Q.limit?.context,maxOutput:Q.limit?.output,inputCost:Q.cost?.input,outputCost:Q.cost?.output}))};t3();var Cb={id:"custom-openai-compatible",name:"自定义 OpenAI Compatible",icon:"\uD83D\uDD27",description:"使用自定义 Base URL 和 API Key",isOAuth:!1,envVars:[],bladeProvider:"openai-compatible",isCustom:!0},hU=()=>{let[$,Z]=p3([]),[Y,Q]=p3(!0),[X,J]=p3(null);return fU(()=>{(async()=>{try{let G=await SU(),K=Object.entries(aQ).map(([W,U])=>({id:W,name:W==="antigravity"?"Google Antigravity":"GitHub Copilot",icon:U.icon,description:U.description,isOAuth:!0,envVars:[],bladeProvider:U.bladeProvider}));Z([...K,Cb,...G])}catch(G){J(G instanceof Error?G.message:"加载 Provider 列表失败")}finally{Q(!1)}})()},[]),{providers:$,isLoading:Y,error:X}},xU=($)=>{let[Z,Y]=p3([]),[Q,X]=p3(!1),[J,q]=p3(null);return fU(()=>{if(!$){Y([]);return}(async()=>{X(!0),q(null);try{let K=await kU($);Y(K)}catch(K){q(K instanceof Error?K.message:"加载模型列表失败")}finally{X(!1)}})()},[$]),{models:Z,isLoading:Q,error:J}};import{Box as d1,Text as D1,useInput as Sb}from"ink";import kb from"ink-select-input";import pU from"ink-text-input";import{useMemo as mU,useState as _Y}from"react";import{jsxDEV as d0,Fragment as pb}from"react/jsx-dev-runtime";var fb=({isSelected:$})=>d0(d1,{marginRight:1,children:d0(D1,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),hb=($)=>{let Z=[$.name];if($.contextWindow){let Y=$.contextWindow>=1e6?`${($.contextWindow/1e6).toFixed(1)}M`:$.contextWindow>=1000?`${Math.round($.contextWindow/1000)}K`:`${$.contextWindow}`;Z.push(`[${Y} ctx]`)}if($.inputCost!==void 0&&$.outputCost!==void 0)Z.push(`[$${$.inputCost}/$${$.outputCost}]`);return Z.join(" ")},xb=({isSelected:$,label:Z})=>d0(D1,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),gU=({provider:$,models:Z,isLoading:Y,error:Q,onSelect:X,onCancel:J,initialModel:q})=>{let[G,K]=_Y(""),W=$.isCustom||Z.length===0,[U,F]=_Y(W),[O,H]=_Y(q||"");Sb((B,L)=>{if(L.escape){if(U&&!W)F(!1),H(q||"");else if(G)K("");else J();return}if(B==="+"&&!U)F(!0)});let _=mU(()=>{if(!G)return Z;let B=G.toLowerCase();return Z.filter((L)=>L.name.toLowerCase().includes(B)||L.id.toLowerCase().includes(B))},[Z,G]),z=mU(()=>_.map((B)=>({key:B.id,label:hb(B),value:B})),[_]),w=()=>{if(O.trim())X({id:O.trim(),name:O.trim()})};if(Y)return d0(d1,{flexDirection:"column",children:d0(D1,{color:"yellow",children:["⏳ 正在加载 ",$.name," 模型列表..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this);if(Q)return d0(d1,{flexDirection:"column",children:[d0(D1,{color:"red",children:["❌ ",Q]},void 0,!0,void 0,this),d0(D1,{dimColor:!0,children:"按 Esc 返回"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return d0(d1,{flexDirection:"column",children:[d0(d1,{marginBottom:1,children:d0(D1,{bold:!0,color:"blue",children:"\uD83E\uDD16 Step 3: 选择模型"},void 0,!1,void 0,this)},void 0,!1,void 0,this),d0(d1,{marginBottom:1,children:d0(D1,{children:["Provider: ",$.icon," ",d0(D1,{bold:!0,children:$.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),U?d0(d1,{flexDirection:"column",children:[d0(d1,{marginBottom:1,children:d0(D1,{dimColor:!0,children:W?"输入模型名称:":"输入自定义模型名称(按 Esc 返回列表):"},void 0,!1,void 0,this)},void 0,!1,void 0,this),d0(d1,{children:[d0(D1,{bold:!0,color:"cyan",children:"▶ "},void 0,!1,void 0,this),d0(pU,{value:O,onChange:H,onSubmit:w,placeholder:"例如: gpt-4o-mini"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this):d0(pb,{children:[d0(d1,{marginBottom:1,children:[d0(D1,{color:"cyan",children:"\uD83D\uDD0D "},void 0,!1,void 0,this),d0(pU,{value:G,onChange:K,placeholder:`搜索 ${Z.length} 个模型,按 + 自定义...`},void 0,!1,void 0,this)]},void 0,!0,void 0,this),d0(d1,{flexDirection:"column",height:12,children:d0(kb,{items:z,onSelect:(B)=>X(B.value),indicatorComponent:fb,itemComponent:xb,limit:10},void 0,!1,void 0,this)},void 0,!1,void 0,this),_.length===0&&d0(D1,{color:"yellow",children:"未找到匹配的模型,按 + 输入自定义模型名称"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};J8();Y8();F8();K8();import{Box as M1,Text as q1,useFocus as dU,useInput as cU}from"ink";import mb from"ink-select-input";import{useEffect as gb,useState as uU}from"react";import{jsxDEV as n0}from"react/jsx-dev-runtime";var lU=({provider:$,onLogin:Z,onCancel:Y,isLoggingIn:Q})=>{let{isFocused:X}=dU({id:"oauth-login"});return cU((J,q)=>{if(Q)return;if(J==="y"||J==="Y")Z();else if(J==="n"||J==="N"||q.escape)Y()},{isActive:X&&!Q}),n0(M1,{flexDirection:"column",children:[n0(M1,{marginBottom:1,children:n0(q1,{bold:!0,color:"yellow",children:[$.icon," 需要登录 ",$.name]},void 0,!0,void 0,this)},void 0,!1,void 0,this),n0(M1,{marginBottom:1,children:n0(q1,{children:$.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),n0(M1,{marginBottom:1,paddingLeft:2,children:n0(q1,{dimColor:!0,children:["您也可以稍后手动执行"," ",n0(q1,{bold:!0,children:$.id==="antigravity"?"/login":"/login copilot"},void 0,!1,void 0,this)," ","命令登录"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),!Q&&n0(M1,{marginTop:1,children:n0(q1,{children:["现在登录? [",n0(q1,{bold:!0,color:"green",children:"Y"},void 0,!1,void 0,this),"/",n0(q1,{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&&n0(M1,{marginTop:1,children:n0(q1,{color:"yellow",children:"⏳ 正在启动登录流程..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},ub=({isSelected:$})=>n0(M1,{marginRight:1,children:n0(q1,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),db=({isSelected:$,label:Z})=>n0(q1,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),iU=({provider:$,onSelect:Z,onCancel:Y})=>{let{isFocused:Q}=dU({id:"oauth-model-select"}),[X,J]=uU([]),[q,G]=uU(!0);gb(()=>{(async()=>{G(!0);try{if($.id==="copilot")J(Object.values(G6));else{let F=await C$.getInstance().getConfigType();J(F==="gemini-cli"?Object.values(Q6):Object.values(Z8))}}catch{J(Object.values(Z8))}finally{G(!1)}})()},[$.id]),cU((W,U)=>{if(U.escape)Y()},{isActive:Q});let K=X.map((W)=>({key:W.id,label:`${W.name} - ${W.description}`,value:{id:W.id,name:W.name}}));if(q)return n0(M1,{flexDirection:"column",children:n0(q1,{color:"yellow",children:["⏳ 加载 ",$.name," 模型列表..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this);return n0(M1,{flexDirection:"column",children:[n0(M1,{marginBottom:1,children:n0(q1,{bold:!0,color:"blue",children:["\uD83E\uDD16 选择 ",$.name," 模型"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),n0(M1,{marginBottom:1,children:n0(q1,{dimColor:!0,children:"从可用模型列表中选择一个"},void 0,!1,void 0,this)},void 0,!1,void 0,this),n0(M1,{flexDirection:"column",height:12,children:n0(mb,{items:K,onSelect:(W)=>Z(W.value),indicatorComponent:ub,itemComponent:db,limit:10},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},aU=async($)=>{let Z=$==="antigravity"?C$.getInstance():d$.getInstance();try{return await Z.login(),!0}catch{return!1}},rU=async($)=>{let Z=$==="antigravity"?C$.getInstance():d$.getInstance();try{return await Z.isLoggedIn()}catch{return!1}};import{Box as p4,Text as t2,useInput as cb}from"ink";import lb from"ink-select-input";import ib from"ink-text-input";import{useMemo as nU,useState as ab}from"react";import{jsxDEV as v$}from"react/jsx-dev-runtime";var rb=({isSelected:$})=>v$(p4,{marginRight:1,children:v$(t2,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),nb=({isSelected:$,label:Z})=>v$(t2,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),oU=({providers:$,isLoading:Z,error:Y,onSelect:Q,onCancel:X})=>{let[J,q]=ab("");cb((W,U)=>{if(U.escape)if(J)q("");else X()});let G=nU(()=>{if(!J)return $;let W=J.toLowerCase();return $.filter((U)=>U.name.toLowerCase().includes(W)||U.id.toLowerCase().includes(W))},[$,J]),K=nU(()=>G.map((W)=>({key:W.id,label:`${W.icon} ${W.name} - ${W.description}`,value:W})),[G]);if(Z)return v$(p4,{flexDirection:"column",children:v$(t2,{color:"yellow",children:"⏳ 正在加载 Provider 列表..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(Y)return v$(p4,{flexDirection:"column",children:[v$(t2,{color:"red",children:["❌ ",Y]},void 0,!0,void 0,this),v$(t2,{dimColor:!0,children:"按 Esc 返回"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return v$(p4,{flexDirection:"column",children:[v$(p4,{marginBottom:1,children:v$(t2,{bold:!0,color:"blue",children:"\uD83D\uDCE1 Step 1: 选择 API 提供商"},void 0,!1,void 0,this)},void 0,!1,void 0,this),v$(p4,{marginBottom:1,children:[v$(t2,{color:"cyan",children:"\uD83D\uDD0D "},void 0,!1,void 0,this),v$(ib,{value:J,onChange:q,placeholder:`搜索 ${$.length} 个 Provider...`},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v$(p4,{flexDirection:"column",height:12,children:v$(lb,{items:K,onSelect:(W)=>Q(W.value),indicatorComponent:rb,itemComponent:nb,limit:10},void 0,!1,void 0,this)},void 0,!1,void 0,this),G.length===0&&v$(t2,{color:"yellow",children:"未找到匹配的 Provider,按 Esc 清除搜索"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};t3();import{jsxDEV as G0,Fragment as eb}from"react/jsx-dev-runtime";var zY=({mode:$,initialConfig:Z,modelId:Y,onComplete:Q,onCancel:X})=>{let J=$==="edit",[q,G]=e2("provider"),[K,W]=e2(),[U,F]=e2(J?Z?.apiKey||"":""),[O,H]=e2(J?Z?.baseUrl||"":""),[_]=e2(J?Z?.model||"":""),[z,w]=e2(),[B,L]=e2(!1),[V,D]=e2(!1),{providers:R,isLoading:y,error:I}=hU(),{models:N,isLoading:P,error:m}=xU(K?.isOAuth?void 0:K?.id),e=Y$(!1),{focus:S}=ob();sU((a,n)=>{if(n.ctrl&&a==="c"||n.meta&&a==="c")$==="setup"?e():X()});let T=R2((a)=>{let U0={provider:"",apiKey:"",baseUrl:"",model:"",oauthLogin:"oauth-login",oauthModelSelect:"oauth-model-select",confirm:""}[a];if(U0)S(U0)}),g=R2((a)=>{return a.defaultBaseUrl||Y6[a.id]||""}),j=R2(async(a)=>{W(a),w(void 0);let n=g(a);if(!J)H(n);if(a.isOAuth){let M0=await rU(a.id)?"oauthModelSelect":"oauthLogin";G(M0),T(M0)}else G("apiKey")}),M=R2(()=>{if(!U.trim()){w("API Key 不能为空");return}w(void 0);let a=K?g(K):"";if(K?.isCustom||!a&&!O)G("baseUrl");else G("model")}),A=R2(()=>{if(!O.trim()){w("Base URL 不能为空");return}try{new URL(O)}catch{w("请输入有效的 URL (例如: https://api.example.com/v1)");return}w(void 0),G("model")}),r=R2(async(a)=>{w(void 0),L(!0);try{let n=O||(K?g(K):""),M0={name:J&&Z?.name?Z.name:`${K?.name||"Model"} - ${a.name}`,provider:K?.bladeProvider||Z?.provider||"openai-compatible",baseUrl:n,apiKey:K?.isOAuth?"oauth":U,model:a.id,...a.contextWindow&&{maxContextTokens:a.contextWindow},...a.maxOutput&&{maxOutputTokens:a.maxOutput},...K?.id&&{providerId:K.id}};if($==="setup")Q(M0);else if($==="add"){let $$=await C0().addModel(M0);await C0().setCurrentModel($$.id),Q(M0)}else if($==="edit"&&Y)await C0().updateModel(Y,M0),Q(M0)}catch(n){w(n instanceof Error?n.message:"保存配置失败"),L(!1)}}),E=R2(async()=>{if(!K)return;D(!0),w(void 0);let a=await aU(K.id);if(D(!1),a)G("oauthModelSelect"),T("oauthModelSelect");else w("登录失败,请重试")}),u=R2(()=>{switch(w(void 0),q){case"apiKey":G("provider");break;case"baseUrl":G("apiKey");break;case"model":{if(!(K?g(K):""))G("baseUrl");else G("apiKey");break}case"oauthLogin":case"oauthModelSelect":G("provider");break}}),Z0=R2(()=>{G("apiKey")}),d=q==="provider"?1:q==="apiKey"||q==="oauthLogin"?2:q==="baseUrl"?2.5:3,s=3;return G0(T$,{...$==="setup"?{flexDirection:"column",padding:1}:{flexDirection:"column",borderStyle:"round",borderColor:$==="edit"?"yellow":"blue",padding:1},children:[$==="setup"&&G0(eb,{children:[G0(T$,{marginBottom:1,children:G0(O$,{bold:!0,color:"blue",children:"\uD83D\uDE80 欢迎使用 Blade Code"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(T$,{marginBottom:1,children:G0(O$,{children:"AI 驱动的代码助手 - 让我们开始配置您的助手"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(T$,{marginBottom:1,children:[G0(O$,{bold:!0,color:"blue",children:"█".repeat(Math.floor((d-1)/(s-1)*40))},void 0,!1,void 0,this),G0(O$,{dimColor:!0,children:"░".repeat(40-Math.floor((d-1)/(s-1)*40))},void 0,!1,void 0,this),G0(O$,{children:" "},void 0,!1,void 0,this),G0(O$,{bold:!0,color:"cyan",children:[Math.ceil(d),"/",s]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),G0(T$,{marginBottom:1,children:G0(O$,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$!=="setup"&&G0(T$,{justifyContent:"center",marginBottom:1,children:G0(O$,{bold:!0,color:$==="edit"?"yellow":"blue",children:$==="edit"?"编辑模型配置":"添加新模型配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),q==="provider"&&G0(oU,{providers:R,isLoading:y,error:I,onSelect:j,onCancel:$==="setup"?()=>{}:X},void 0,!1,void 0,this),q==="apiKey"&&K&&G0(PU,{provider:K,value:U,onChange:F,onSubmit:M,onCancel:u,error:z},void 0,!1,void 0,this),q==="baseUrl"&&K&&G0(tb,{provider:K,value:O,onChange:H,onSubmit:A,onCancel:Z0,error:z},void 0,!1,void 0,this),q==="model"&&K&&G0(gU,{provider:K,models:N,isLoading:P,error:m,onSelect:r,onCancel:u,initialModel:J?_:void 0},void 0,!1,void 0,this),q==="oauthLogin"&&K&&G0(lU,{provider:K,onLogin:E,onCancel:u,isLoggingIn:V},void 0,!1,void 0,this),q==="oauthModelSelect"&&K&&G0(iU,{provider:K,onSelect:r,onCancel:u},void 0,!1,void 0,this),z&&q!=="apiKey"&&q!=="baseUrl"&&G0(T$,{marginTop:1,borderStyle:"round",borderColor:"red",paddingX:1,children:G0(O$,{color:"red",children:["❌ ",z]},void 0,!0,void 0,this)},void 0,!1,void 0,this),B&&G0(T$,{marginTop:1,children:G0(O$,{color:"yellow",children:"⏳ 正在保存配置..."},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(T$,{marginTop:1,children:G0(O$,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},tb=({provider:$,value:Z,onChange:Y,onSubmit:Q,onCancel:X,error:J})=>{return sU((q,G)=>{if(G.escape)X()}),G0(T$,{flexDirection:"column",children:[G0(T$,{marginBottom:1,children:G0(O$,{bold:!0,color:"blue",children:"\uD83C\uDF10 输入 Base URL"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(T$,{marginBottom:1,children:G0(O$,{children:["Provider: ",$.icon," ",G0(O$,{bold:!0,children:$.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),G0(T$,{marginBottom:1,children:G0(O$,{dimColor:!0,children:"此 Provider 没有默认的 API 端点,请输入完整的 Base URL"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(T$,{marginBottom:1,children:G0(O$,{dimColor:!0,children:"示例: https://api.example.com/v1"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G0(T$,{children:[G0(O$,{bold:!0,color:"cyan",children:"▶ "},void 0,!1,void 0,this),G0(sb,{value:Z,onChange:Y,onSubmit:Q,placeholder:"https://api.example.com/v1"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J&&G0(T$,{marginTop:1,children:G0(O$,{color:"red",children:["❌ ",J]},void 0,!0,void 0,this)},void 0,!1,void 0,this),G0(T$,{marginTop:1,children:G0(O$,{dimColor:!0,children:["\uD83D\uDCA1 输入完成后按 ",G0(O$,{bold:!0,children:"Enter"},void 0,!1,void 0,this),",",G0(O$,{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)};Z6();import{useMemoizedFn as y7,useMount as $A}from"ahooks";import{Box as G1,Text as v0,useFocus as ZA,useFocusManager as YA,useInput as QA}from"ink";import XA from"ink-select-input";import{memo as JA,useMemo as qA,useState as v7}from"react";T0();import{jsxDEV as W0}from"react/jsx-dev-runtime";function GA($){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 KA=({isSelected:$})=>W0(G1,{marginRight:1,children:W0(v0,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),WA=({isSelected:$,label:Z})=>W0(v0,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),tU=JA(({onClose:$,onEdit:Z})=>{let Y=YW(),Q=QW()??"",{isFocused:X}=ZA({id:"model-selector"}),J=YA(),[q,G]=v7(""),[K,W]=v7(!1),[U,F]=v7(null),O=Y$(!1),[H]=v7(()=>{let y=process.stdout?.columns||80;return Math.max(20,y-8)});$A(()=>{if(J?.focus("model-selector"),Y.length>0)G(Y[0].id)}),QA((y,I)=>{if(K)return;if(I.ctrl&&y==="c"||I.meta&&y==="c"){O();return}if(I.escape){$();return}if(!X)return;if(y==="d"||y==="D"){z();return}if((y==="e"||y==="E")&&Z)w()},{isActive:!0});let _=y7(async(y)=>{if(K)return;let I=y.value;if(I===Q){$();return}W(!0),F(null);try{await C0().setCurrentModel(I),$()}catch(N){F(N.message),W(!1)}}),z=y7(async()=>{if(K||q===Q)return;W(!0),F(null);try{if(await C0().removeModel(q),Y.length<=1)$()}catch(y){F(y.message)}finally{W(!1)}}),w=y7(()=>{if(K||!Z)return;let y=Y.find((I)=>I.id===q);if(!y)return;Z(y)}),B=y7((y)=>{G(y.value)}),L=qA(()=>{return Y.find((y)=>y.id===q)},[Y,q]),V=Y.map((y)=>{let I=y.id===Q?" (当前)":"";return{label:y.name+I,value:y.id}}),D=q===Q;return W0(G1,{flexDirection:"column",borderStyle:"round",borderColor:"gray",padding:1,width:"100%",children:[W0(G1,{flexDirection:"row",justifyContent:"space-between",marginBottom:1,children:[W0(v0,{bold:!0,color:"cyan",children:"模型管理"},void 0,!1,void 0,this),W0(v0,{dimColor:!0,children:[K?"⏳ 处理中...":D?"Enter=关闭 • E=编辑 • Esc=取消":"Enter=切换 • D=删除 • E=编辑 • Esc=取消"," • Ctrl+C=退出"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),W0(G1,{flexDirection:"row",children:[W0(G1,{flexDirection:"column",flexGrow:2,marginRight:2,borderStyle:"single",borderColor:"gray",padding:1,children:[W0(v0,{dimColor:!0,children:["已配置模型 (",Y.length,")"]},void 0,!0,void 0,this),W0(G1,{marginTop:1,children:W0(XA,{items:V,onSelect:_,onHighlight:B,indicatorComponent:KA,itemComponent:WA},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),W0(G1,{flexDirection:"column",flexGrow:3,borderStyle:"single",borderColor:"gray",padding:1,children:[W0(v0,{dimColor:!0,children:"模型详情"},void 0,!1,void 0,this),W0(G1,{marginY:1,children:W0(v0,{color:D?"green":"yellow",children:D?"● 当前使用":"● 可切换"},void 0,!1,void 0,this)},void 0,!1,void 0,this),L?W0(G1,{flexDirection:"column",children:[W0(v0,{children:[W0(v0,{dimColor:!0,children:"名称: "},void 0,!1,void 0,this),W0(v0,{bold:!0,color:"cyan",children:L.name},void 0,!1,void 0,this),T9(L)&&W0(v0,{color:"green",children:" (内置免费)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),W0(v0,{children:[W0(v0,{dimColor:!0,children:"Provider: "},void 0,!1,void 0,this),W0(v0,{bold:!0,children:GA(L.provider)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),W0(v0,{children:[W0(v0,{dimColor:!0,children:"Model: "},void 0,!1,void 0,this),W0(v0,{bold:!0,children:L.model},void 0,!1,void 0,this)]},void 0,!0,void 0,this),W0(v0,{children:[W0(v0,{dimColor:!0,children:"Base URL: "},void 0,!1,void 0,this),W0(v0,{color:"blueBright",children:L.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L.temperature!==void 0&&W0(v0,{children:[W0(v0,{dimColor:!0,children:"Temperature: "},void 0,!1,void 0,this),W0(v0,{children:L.temperature},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L.maxContextTokens!==void 0&&W0(v0,{children:[W0(v0,{dimColor:!0,children:"Context Window: "},void 0,!1,void 0,this),W0(v0,{children:L.maxContextTokens},void 0,!1,void 0,this)]},void 0,!0,void 0,this),T9(L)&&W0(G1,{marginTop:1,children:W0(v0,{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):W0(v0,{dimColor:!0,children:"请选择一个模型查看详情"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),U&&W0(G1,{marginTop:1,children:W0(v0,{color:"red",children:["❌ ",U]},void 0,!0,void 0,this)},void 0,!1,void 0,this),W0(G1,{justifyContent:"center",marginTop:1,children:W0(v0,{dimColor:!0,children:"─".repeat(H)},void 0,!1,void 0,this)},void 0,!1,void 0,this),W0(G1,{justifyContent:"center",children:W0(v0,{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 d8}from"ahooks";import{promises as YF}from"fs";import{Box as K1,Text as t0,useInput as UA}from"ink";import eU from"ink-select-input";import FA from"ink-text-input";import OA from"os";import T7 from"path";import{useEffect as HA,useMemo as E7,useRef as _A,useState as $4}from"react";T0();import{jsxDEV as _0}from"react/jsx-dev-runtime";var c8=[{key:"allow",label:"Allow"},{key:"ask",label:"Ask"},{key:"deny",label:"Deny"},{key:"info",label:"Info"}],zA={allow:"Add a new rule...",ask:"Add a new rule...",deny:"Add a new rule..."},BA={allow:"Allow permission rules",ask:"Ask permission rules",deny:"Deny permission rules"},$F={project:"[项目共享配置]",global:"[用户全局配置]",local:"[本地配置]"},wA=["project","global","local"],LA={allow:[],ask:[],deny:[]},NA={localExists:!1,projectExists:!1,globalExists:!1},ZF={allow:[],ask:[],deny:[]};function bA($){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 AA($){try{let Z=await YF.readFile($,"utf-8"),Y=JSON.parse(Z);return{exists:!0,raw:Y,permissions:bA(Y)}}catch(Z){if(Z.code==="ENOENT")return{exists:!1,raw:{},permissions:{...ZF}};return console.warn(`[PermissionsManager] Failed to read ${$}:`,Z),{exists:!0,raw:{},permissions:{...ZF}}}}function RA($,Z){let Y=$.padEnd(32," "),Q=Z==="local"?`${$F[Z]} ← 可删除`:$F[Z];return`${Y} ${Q}`}var QF=({onClose:$})=>{let Y=Z1()==="permissions-manager",Q=Y$(!1),[X,J]=$4(0),q=c8[X].key,[G,K]=$4(LA),[W,U]=$4(NA),[F,O]=$4(!0),[H,_]=$4("list"),[z,w]=$4(""),[B,L]=$4(null),[V,D]=$4(null),R=_A(!1),y=E7(()=>T7.join(process.cwd(),".blade","settings.local.json"),[]),I=E7(()=>T7.join(process.cwd(),".blade","settings.json"),[]),N=E7(()=>T7.join(OA.homedir(),".blade","settings.json"),[]),P=d8(async()=>{O(!0);let d=[{source:"local",path:y},{source:"project",path:I},{source:"global",path:N}],s=await Promise.all(d.map(async({source:U0,path:M0})=>{let $$=await AA(M0);return{source:U0,path:M0,...$$}})),k={localExists:s.find((U0)=>U0.source==="local")?.exists??!1,projectExists:s.find((U0)=>U0.source==="project")?.exists??!1,globalExists:s.find((U0)=>U0.source==="global")?.exists??!1};U(k);let a={allow:[],ask:[],deny:[]},n=Object.fromEntries(s.map((U0)=>[U0.source,U0]));["allow","ask","deny"].forEach((U0)=>{wA.forEach((M0)=>{(n[M0]?.permissions[U0]??[]).forEach((j2,E$)=>{let X0={key:`${M0}:${E$}:${j2}`,rule:j2,source:M0};a[U0].push(X0)})})}),K(a),O(!1)});HA(()=>{P()},[P]);let m=d8(async(d,s)=>{try{let k=T7.join(process.cwd(),".blade","settings.local.json"),a={allow:[],ask:[],deny:[]};try{let U0=await YF.readFile(k,"utf-8"),$$=JSON.parse(U0).permissions||{};a={allow:Array.isArray($$.allow)?$$.allow:[],ask:Array.isArray($$.ask)?$$.ask:[],deny:Array.isArray($$.deny)?$$.deny:[]}}catch(U0){}let n=s(a);await C0().updateConfig({permissions:n},{scope:"local",immediate:!0}),await P()}catch(k){throw console.error("[PermissionsManager] 修改权限规则失败:",k),k}});UA((d,s)=>{if(s.ctrl&&d==="c"||s.meta&&d==="c"){Q();return}if(H==="locked"){if(R.current){R.current=!1;return}_("list"),L(null),D(null);return}if(s.escape){if(H==="list"||q==="info")$();else _("list"),w(""),L(null),D(null);return}if(H==="list"){if(s.tab&&s.shift)J((k)=>(k-1+c8.length)%c8.length);else if(s.tab)J((k)=>(k+1)%c8.length);else if(d?.toLowerCase()==="q")$()}},{isActive:Y});let e=d8((d)=>{let s=d.value;if(q==="info")return;if(s.type==="add"){_("add"),w(""),D(null);return}if(s.entry.source!=="local"){_("locked"),R.current=!0,L({tab:q,entry:s.entry}),D({type:"error",text:s.entry.source==="project"?"此规则定义在项目共享配置中,无法在此删除。":"此规则来自用户全局配置,无法在此删除。"});return}_("confirm-delete"),L({tab:q,entry:s.entry}),D(null)}),S=d8(async()=>{if(q==="info")return;let d=z.trim();if(!d){D({type:"error",text:"Permission rule 不能为空"});return}if(G[q].map((k)=>k.rule).includes(d)){D({type:"error",text:"该规则已存在"});return}try{await m(q,(k)=>{let a={allow:[...k.allow],ask:[...k.ask],deny:[...k.deny]};return a[q]=[...new Set([...k[q],d])],a}),_("list"),w(""),D({type:"success",text:"已添加本地权限规则"})}catch(k){D({type:"error",text:`保存失败: ${k instanceof Error?k.message:"未知错误"}`})}}),T=d8(async()=>{if(!B)return;let{tab:d,entry:s}=B;try{await m(d,(k)=>{let a={allow:[...k.allow],ask:[...k.ask],deny:[...k.deny]};return a[d]=k[d].filter((n)=>n!==s.rule),a}),_("list"),L(null),D({type:"success",text:"已删除本地权限规则"})}catch(k){D({type:"error",text:`删除失败: ${k instanceof Error?k.message:"未知错误"}`})}}),g=E7(()=>{if(q==="info")return[];let d=q;return[{key:"add-new-rule",label:`› ${zA[d]}`,value:{type:"add"}},...G[d].map((k)=>({key:k.key,label:RA(k.rule,k.source),value:{type:"rule",entry:k}}))]},[q,G]),j=()=>_0(K1,{marginBottom:1,children:c8.map((d,s)=>_0(K1,{marginRight:2,children:_0(t0,{color:s===X?"yellow":"gray",children:["[",d.label,"]"]},void 0,!0,void 0,this)},d.key,!1,void 0,this))},void 0,!1,void 0,this),M=()=>_0(K1,{flexDirection:"column",gap:1,children:[_0(t0,{children:"配置文件优先级(从高到低):"},void 0,!1,void 0,this),_0(K1,{flexDirection:"column",marginLeft:2,children:[_0(t0,{children:["1. .blade/settings.local.json (本地配置,不提交 Git)"," ",W.localExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),_0(t0,{children:["2. .blade/settings.json (项目配置,提交 Git)"," ",W.projectExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),_0(t0,{children:["3. ~/.blade/settings.json (用户全局配置)"," ",W.globalExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),_0(t0,{children:"说明:"},void 0,!1,void 0,this),_0(K1,{flexDirection:"column",marginLeft:2,children:[_0(t0,{children:"- /permissions 命令只管理本地配置 (.blade/settings.local.json)"},void 0,!1,void 0,this),_0(t0,{children:"- 修改全局或项目配置请直接编辑对应文件"},void 0,!1,void 0,this),_0(t0,{children:"- 本地配置不会提交到 Git"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),A=(d)=>_0(K1,{flexDirection:"column",gap:1,children:[_0(t0,{bold:!0,children:BA[d]},void 0,!1,void 0,this),_0(t0,{children:"Permission rules are a tool name, optionally followed by a specifier in parentheses."},void 0,!1,void 0,this),_0(t0,{color:"gray",children:"例如: WebFetch 或 Bash(ls:*)"},void 0,!1,void 0,this),_0(K1,{marginTop:1,children:_0(FA,{value:z,onChange:w,onSubmit:S},void 0,!1,void 0,this)},void 0,!1,void 0,this),_0(t0,{color:"gray",children:"Enter 提交 · Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),r=(d,s)=>_0(K1,{flexDirection:"column",gap:1,children:[_0(t0,{bold:!0,children:["Delete ",d," permission rule?"]},void 0,!0,void 0,this),_0(t0,{children:s.rule},void 0,!1,void 0,this),_0(t0,{color:"gray",children:"From project local settings"},void 0,!1,void 0,this),_0(t0,{children:"Are you sure you want to delete this permission rule?"},void 0,!1,void 0,this),_0(eU,{items:[{label:"Yes",value:"yes"},{label:"No",value:"no"}],onSelect:(k)=>{if(k.value==="yes")T();else _("list"),L(null)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),E=(d)=>_0(K1,{flexDirection:"column",gap:1,children:[_0(t0,{bold:!0,children:"Cannot delete this rule"},void 0,!1,void 0,this),_0(t0,{children:d.rule},void 0,!1,void 0,this),_0(t0,{color:"gray",children:d.source==="project"?"This rule is defined in .blade/settings.json. 请手动编辑该文件以移除规则。":"This rule is defined in ~/.blade/settings.json. 请手动编辑该文件以移除规则。"},void 0,!1,void 0,this),_0(t0,{color:"gray",children:"按任意键继续"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),u=(d)=>_0(eU,{items:g,isFocused:H==="list",onSelect:e},void 0,!1,void 0,this),Z0=()=>{if(F)return _0(t0,{children:"加载中..."},void 0,!1,void 0,this);if(q==="info")return M();if(H==="add")return A(q);if(H==="confirm-delete"&&B)return r(B.tab,B.entry);if(H==="locked"&&B)return E(B.entry);return u(q)};return _0(K1,{flexDirection:"column",borderStyle:"round",borderColor:Y?"cyan":"gray",padding:1,width:80,children:[_0(t0,{color:"cyan",bold:!0,children:"⚙️ 权限管理器"},void 0,!1,void 0,this),j(),_0(K1,{flexDirection:"column",gap:1,children:Z0()},void 0,!1,void 0,this),V&&_0(K1,{marginTop:1,children:_0(t0,{color:V.type==="success"?"green":"red",children:V.text},void 0,!1,void 0,this)},void 0,!1,void 0,this),_0(K1,{marginTop:1,children:_0(t0,{color:"gray",children:"Tab 切换视图 · Esc 关闭 · Q 退出"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};b3();import{Box as o0,Text as L0,useInput as VA}from"ink";import{jsxDEV as i}from"react/jsx-dev-runtime";function XF({onCancel:$}){let Z=a$(),Y=Z.getAll(),Q=Z.getBySource(),X=Z.getStats(),J=Y$(!1,$);if(VA((q,G)=>{if(G.escape)$?.();else if(G.ctrl&&q==="c"||G.meta&&q==="c")J()}),Y.length===0)return i(o0,{flexDirection:"column",paddingY:1,children:[i(o0,{marginBottom:1,children:i(L0,{bold:!0,color:"cyan",children:"\uD83D\uDD0C 插件管理器"},void 0,!1,void 0,this)},void 0,!1,void 0,this),i(o0,{paddingLeft:2,children:i(L0,{color:"gray",children:"没有已加载的插件"},void 0,!1,void 0,this)},void 0,!1,void 0,this),i(o0,{marginTop:1,paddingLeft:2,flexDirection:"column",children:[i(L0,{color:"gray",children:"插件目录位置:"},void 0,!1,void 0,this),i(L0,{color:"gray",dimColor:!0,children:[" ","• ~/.blade/plugins/ - 用户级插件"]},void 0,!0,void 0,this),i(L0,{color:"gray",dimColor:!0,children:[" ","• .blade/plugins/ - 项目级插件"]},void 0,!0,void 0,this),i(L0,{color:"gray",dimColor:!0,children:[" ","• --plugin-dir - CLI 指定的插件"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),i(o0,{marginTop:1,paddingLeft:2,children:i(L0,{color:"gray",children:"使用 /plugins install <url> 安装新插件"},void 0,!1,void 0,this)},void 0,!1,void 0,this),i(o0,{marginTop:1,children:i(L0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return i(o0,{flexDirection:"column",paddingY:1,children:[i(o0,{marginBottom:1,children:[i(L0,{bold:!0,color:"cyan",children:"\uD83D\uDD0C 插件管理器"},void 0,!1,void 0,this),i(L0,{color:"gray",children:[" (共 ",X.total," 个插件)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),i(o0,{paddingLeft:2,marginBottom:1,children:i(L0,{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&&i(o0,{flexDirection:"column",marginBottom:1,children:[i(o0,{paddingLeft:1,children:[i(L0,{bold:!0,color:"magenta",children:"CLI 指定"},void 0,!1,void 0,this),i(L0,{color:"gray",children:" (--plugin-dir)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.cli.map((q)=>{let G=q.status==="active"?"✅":"⏸️";return i(o0,{flexDirection:"column",paddingLeft:2,children:[i(L0,{children:[i(L0,{bold:!0,color:"green",children:[G," ",q.manifest.name]},void 0,!0,void 0,this),i(L0,{color:"gray",children:[" v",q.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),i(o0,{paddingLeft:2,children:i(L0,{color:"gray",children:q.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),q.commands.length>0&&i(o0,{paddingLeft:2,children:i(L0,{color:"blue",children:["命令:"," ",q.commands.map((K)=>`/${K.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},q.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.project.length>0&&i(o0,{flexDirection:"column",marginBottom:1,children:[i(o0,{paddingLeft:1,children:[i(L0,{bold:!0,color:"yellow",children:"项目级"},void 0,!1,void 0,this),i(L0,{color:"gray",children:" (.blade/plugins/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.project.map((q)=>{let G=q.status==="active"?"✅":"⏸️";return i(o0,{flexDirection:"column",paddingLeft:2,children:[i(L0,{children:[i(L0,{bold:!0,color:"green",children:[G," ",q.manifest.name]},void 0,!0,void 0,this),i(L0,{color:"gray",children:[" v",q.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),i(o0,{paddingLeft:2,children:i(L0,{color:"gray",children:q.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),q.commands.length>0&&i(o0,{paddingLeft:2,children:i(L0,{color:"blue",children:["命令:"," ",q.commands.map((K)=>`/${K.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},q.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.user.length>0&&i(o0,{flexDirection:"column",marginBottom:1,children:[i(o0,{paddingLeft:1,children:[i(L0,{bold:!0,color:"cyan",children:"用户级"},void 0,!1,void 0,this),i(L0,{color:"gray",children:" (~/.blade/plugins/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.user.map((q)=>{let G=q.status==="active"?"✅":"⏸️";return i(o0,{flexDirection:"column",paddingLeft:2,children:[i(L0,{children:[i(L0,{bold:!0,color:"green",children:[G," ",q.manifest.name]},void 0,!0,void 0,this),i(L0,{color:"gray",children:[" v",q.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),i(o0,{paddingLeft:2,children:i(L0,{color:"gray",children:q.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),q.commands.length>0&&i(o0,{paddingLeft:2,children:i(L0,{color:"blue",children:["命令:"," ",q.commands.map((K)=>`/${K.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},q.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),i(o0,{marginTop:1,paddingLeft:2,flexDirection:"column",children:[i(L0,{color:"gray",children:"可用命令:"},void 0,!1,void 0,this),i(L0,{color:"gray",dimColor:!0,children:[" ","• /plugins list - 列出所有插件"]},void 0,!0,void 0,this),i(L0,{color:"gray",dimColor:!0,children:[" ","• /plugins info <name> - 显示插件详情"]},void 0,!0,void 0,this),i(L0,{color:"gray",dimColor:!0,children:[" ","• /plugins install <url> - 安装插件"]},void 0,!0,void 0,this),i(L0,{color:"gray",dimColor:!0,children:[" ","• /plugins enable/disable <name> - 启用/禁用插件"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),i(o0,{marginTop:1,children:i(L0,{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 f$,Text as h$,useInput as JF,useStdout as DA}from"ink";import MA from"ink-text-input";import BY,{useCallback as l8,useMemo as jA,useState as Z4}from"react";import{jsxDEV as A0}from"react/jsx-dev-runtime";var IA=BY.memo(({option:$,index:Z,isSelected:Y,isMultiSelect:Q,isHighlighted:X})=>A0(f$,{flexDirection:"column",marginBottom:1,children:[A0(h$,{color:X?"yellow":Y?"green":void 0,bold:X,children:[Q?Y?"● ":"○ ":X?"❯ ":" ",Z+1,". ",$.label]},void 0,!0,void 0,this),A0(f$,{marginLeft:4,children:A0(h$,{color:"gray",children:$.description},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)),yA=BY.memo(({questions:$,answers:Z})=>A0(f$,{flexDirection:"column",marginBottom:1,children:$.map((Y)=>{let Q=Z[Y.header],X=Array.isArray(Q)?Q.join(", "):Q||"(no answer)";return A0(f$,{marginBottom:1,children:[A0(h$,{backgroundColor:"blue",color:"white",children:[" ",Y.header," "]},void 0,!0,void 0,this),A0(h$,{color:"green",children:[" ",X]},void 0,!0,void 0,this)]},Y.header,!0,void 0,this)})},void 0,!1,void 0,this)),qF=BY.memo(({questions:$,onComplete:Z,onCancel:Y})=>{let{stdout:Q}=DA(),X=Q.columns||80,q=Z1()==="confirmation-prompt",G=Y$(!1),[K,W]=Z4("answering"),[U,F]=Z4(0),[O,H]=Z4({}),[_,z]=Z4(0),[w,B]=Z4([]),[L,V]=Z4(!1),[D,R]=Z4(""),[y,I]=Z4(0),N=$[U],P=jA(()=>{if(!N)return[];return[...N.options.map((j)=>({label:j.label,value:j.label,description:j.description})),{label:"Type something...",value:"__other__",description:"Enter custom response"}]},[N]),m=l8((j)=>{let M={...O,[N.header]:j};if(H(M),U<$.length-1)F(U+1),z(0),B([]),V(!1),R("");else W("submit"),I(0)},[O,N?.header,U,$.length]),e=l8((j)=>{let M=P[j];if(!M)return;if(M.value==="__other__"){V(!0);return}if(N.multiSelect)B((A)=>A.includes(M.value)?A.filter((r)=>r!==M.value):[...A,M.value]);else m(M.value)},[P,N?.multiSelect,m]),S=l8((j)=>{if(j.trim())m(j.trim())},[m]),T=l8(()=>{W("answering"),F(0),z(0),B([]),V(!1)},[]),g=l8(()=>{Z(O)},[O,Z]);if(JF((j,M)=>{if(M.ctrl&&j==="c"||M.meta&&j==="c"){G();return}if(L){if(M.escape)V(!1),R("");return}if(M.escape){Y();return}let A=parseInt(j);if(A>=1&&A<=P.length){e(A-1);return}if(M.upArrow){z((r)=>r>0?r-1:P.length-1);return}if(M.downArrow||M.tab){z((r)=>r<P.length-1?r+1:0);return}if(M.return){if(N.multiSelect&&w.length>0)m(w);else e(_);return}if(j===" "&&N.multiSelect){let r=P[_];if(r&&r.value!=="__other__")B((E)=>E.includes(r.value)?E.filter((u)=>u!==r.value):[...E,r.value]);return}},{isActive:q&&K==="answering"&&!L}),JF((j,M)=>{if(M.ctrl&&j==="c"||M.meta&&j==="c"){G();return}if(M.escape){Y();return}if(M.upArrow||M.downArrow||M.tab){I((A)=>A===0?1:0);return}if(M.return){if(y===0)g();else T();return}if(j.toLowerCase()==="y"){g();return}if(j.toLowerCase()==="e"){T();return}},{isActive:q&&K==="submit"}),K==="submit")return A0(f$,{flexDirection:"column",borderStyle:"round",borderColor:q?"green":"gray",padding:1,width:Math.min(X-4,80),children:[A0(f$,{marginBottom:1,children:A0(h$,{bold:!0,color:"green",children:"✓ Review Your Answers"},void 0,!1,void 0,this)},void 0,!1,void 0,this),A0(yA,{questions:$,answers:O},void 0,!1,void 0,this),A0(f$,{flexDirection:"column",marginTop:1,children:[A0(h$,{color:y===0?"yellow":void 0,bold:y===0,children:[y===0?"❯ ":" ","[Y] Submit answers"]},void 0,!0,void 0,this),A0(h$,{color:y===1?"yellow":void 0,bold:y===1,children:[y===1?"❯ ":" ","[E] Edit answers"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),A0(f$,{marginTop:1,children:A0(h$,{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(!N)return null;return A0(f$,{flexDirection:"column",borderStyle:"round",borderColor:q?"cyan":"gray",padding:1,width:Math.min(X-4,80),children:[A0(f$,{marginBottom:1,children:[A0(h$,{backgroundColor:"blue",color:"white",children:[" ",N.header," "]},void 0,!0,void 0,this),A0(h$,{children:[" ",N.question]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),L?A0(f$,{flexDirection:"column",marginTop:1,children:[A0(h$,{color:"yellow",children:"Enter your response:"},void 0,!1,void 0,this),A0(f$,{marginTop:1,children:[A0(h$,{color:"cyan",children:"❯ "},void 0,!1,void 0,this),A0(MA,{value:D,onChange:R,onSubmit:S,focus:q},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A0(f$,{marginTop:1,children:A0(h$,{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):A0(f$,{flexDirection:"column",children:P.map((j,M)=>A0(IA,{option:j,index:M,isSelected:w.includes(j.value),isMultiSelect:N.multiSelect,isHighlighted:_===M},j.value,!1,void 0,this))},void 0,!1,void 0,this),!L&&A0(f$,{marginTop:1,flexDirection:"column",children:[A0(h$,{color:"gray",children:N.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),N.multiSelect&&w.length>0&&A0(h$,{color:"green",children:["Selected: ",w.join(", ")]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$.length>1&&A0(f$,{marginTop:1,children:A0(h$,{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)});t6();import{Box as m3,Text as c1,useInput as vA}from"ink";import TA from"ink-select-input";import{basename as EA}from"node:path";import{useEffect as GF,useMemo as P7,useState as wY}from"react";import{jsxDEV as D$}from"react/jsx-dev-runtime";function PA($){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 CA($){return EA($)}var SA=({isSelected:$})=>D$(m3,{marginRight:1,children:D$(c1,{color:$?"cyan":"gray",children:$?"❯":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),kA=({isSelected:$,label:Z})=>D$(c1,{color:$?"cyan":"white",bold:$,children:Z},void 0,!1,void 0,this),i8=20,KF=({sessions:$,onSelect:Z,onCancel:Y})=>{let[Q,X]=wY([]),[J,q]=wY(!1),[G,K]=wY(0),U=Z1()==="session-selector",F=Y$(!1);vA((L,V)=>{if(V.ctrl&&L==="c"||V.meta&&L==="c"){F();return}if(V.escape&&Y){Y();return}if(V.leftArrow||L==="h"||L==="H"){if(G>0)K((D)=>D-1);return}if(V.rightArrow||L==="l"||L==="L"){if(G<_-1)K((D)=>D+1);return}},{isActive:U}),GF(()=>{if($){X($);return}(async()=>{q(!0);try{let V=await w1.listSessions();X(V)}catch(V){console.error("[SessionSelector] Failed to load sessions:",V),X([])}finally{q(!1)}})()},[$]);let O=$||Q,H=P7(()=>{return O.map((L)=>{let V=CA(L.projectPath),D=PA(L.lastMessageTime),R=L.gitBranch?` (${L.gitBranch})`:"",y=L.hasErrors?" ⚠️":"";return{label:`\uD83D\uDCC5 ${D} | ${V}${R} | ${L.messageCount} 条消息${y}`,value:L.sessionId}})},[O]),_=P7(()=>Math.max(1,Math.ceil(H.length/i8)),[H.length]),z=P7(()=>{let L=G*i8;return H.slice(L,L+i8)},[H,G]),w=P7(()=>({start:G*i8+1,end:Math.min((G+1)*i8,H.length)}),[G,H.length]);GF(()=>{K(0)},[O.length]);let B=(L)=>{Z(L.value)};if(J)return D$(m3,{flexDirection:"column",paddingX:2,paddingY:1,children:D$(c1,{children:"⏳ 正在加载会话列表..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(O.length===0)return D$(m3,{flexDirection:"column",paddingX:2,paddingY:1,children:[D$(c1,{color:"yellow",children:"⚠️ 没有找到历史会话"},void 0,!1,void 0,this),D$(c1,{dimColor:!0,children:[`
|
|
2840
2840
|
`,"提示: 开始一次对话后,会话历史将保存到 ~/.blade/projects/"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this);return D$(m3,{flexDirection:"column",paddingX:2,paddingY:1,children:[D$(c1,{bold:!0,color:"cyan",children:"\uD83D\uDCC2 选择要恢复的会话:"},void 0,!1,void 0,this),D$(c1,{dimColor:!0,children:[`
|
|
2841
2841
|
`,"(←→ 翻页 | ↑↓ 选择 | Enter 确认 | Esc 取消)",`
|
|
2842
|
-
`]},void 0,!0,void 0,this),D$(vA,{items:z,onSelect:B,indicatorComponent:CA,itemComponent:SA},void 0,!1,void 0,this),D$(m3,{marginTop:1,flexDirection:"column",children:[D$(c1,{dimColor:!0,children:["第 ",G+1,"/",_," 页 · 共 ",O.length," 个会话 · 显示"," ",w.start,"-",w.end]},void 0,!0,void 0,this),_>1&&D$(m3,{marginTop:1,children:[D$(c1,{color:G>0?"cyan":"gray",children:G>0?"◀ ← 上一页":" "},void 0,!1,void 0,this),D$(c1,{children:" "},void 0,!1,void 0,this),D$(c1,{color:G<_-1?"cyan":"gray",children:G<_-1?"下一页 → ▶":""},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};U2();import{Box as J$,Text as c0,useInput as kA}from"ink";import{jsxDEV as Q0}from"react/jsx-dev-runtime";function WF({onCancel:$}){let Y=N$().getAll(),Q=Y.filter((G)=>G.source==="builtin"),X=Y.filter((G)=>G.source==="user"),J=Y.filter((G)=>G.source==="project"),q=Z$(!1,$);if(kA((G,K)=>{if(K.escape)$?.();else if(K.ctrl&&G==="c"||K.meta&&G==="c")q()}),Y.length===0)return Q0(J$,{flexDirection:"column",paddingY:1,children:[Q0(J$,{marginBottom:1,children:Q0(c0,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q0(J$,{paddingLeft:2,children:Q0(c0,{color:"gray",children:"没有找到任何 Skill"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q0(J$,{marginTop:1,paddingLeft:2,children:Q0(c0,{color:"gray",children:"配置文件位置: ~/.blade/skills/ 或 .blade/skills/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q0(J$,{marginTop:1,children:Q0(c0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return Q0(J$,{flexDirection:"column",paddingY:1,children:[Q0(J$,{marginBottom:1,children:[Q0(c0,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this),Q0(c0,{color:"gray",children:[" (找到 ",Y.length," 个)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),J.length>0&&Q0(J$,{flexDirection:"column",marginBottom:1,children:[Q0(J$,{paddingLeft:1,children:[Q0(c0,{bold:!0,color:"yellow",children:"项目级"},void 0,!1,void 0,this),Q0(c0,{color:"gray",children:" (.blade/skills/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J.map((G)=>{let W=G.description.length>80?`${G.description.substring(0,80)}...`:G.description;return Q0(J$,{flexDirection:"column",paddingLeft:2,children:[Q0(c0,{children:[Q0(c0,{bold:!0,color:"green",children:["• ",G.name]},void 0,!0,void 0,this),Q0(c0,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),G.allowedTools&&G.allowedTools.length>0&&Q0(J$,{paddingLeft:2,children:Q0(c0,{color:"gray",children:["工具: ",G.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q0(J$,{paddingLeft:2,children:Q0(c0,{color:"gray",dimColor:!0,children:G.path},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},G.name,!0,void 0,this)})]},void 0,!0,void 0,this),X.length>0&&Q0(J$,{flexDirection:"column",marginBottom:1,children:[Q0(J$,{paddingLeft:1,children:[Q0(c0,{bold:!0,color:"yellow",children:"用户级"},void 0,!1,void 0,this),Q0(c0,{color:"gray",children:" (~/.blade/skills/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X.map((G)=>{let W=G.description.length>80?`${G.description.substring(0,80)}...`:G.description;return Q0(J$,{flexDirection:"column",paddingLeft:2,children:[Q0(c0,{children:[Q0(c0,{bold:!0,color:"green",children:["• ",G.name]},void 0,!0,void 0,this),Q0(c0,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),G.allowedTools&&G.allowedTools.length>0&&Q0(J$,{paddingLeft:2,children:Q0(c0,{color:"gray",children:["工具: ",G.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q0(J$,{paddingLeft:2,children:Q0(c0,{color:"gray",dimColor:!0,children:G.path},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},G.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.length>0&&Q0(J$,{flexDirection:"column",marginBottom:1,children:[Q0(J$,{paddingLeft:1,children:[Q0(c0,{bold:!0,color:"cyan",children:"内置"},void 0,!1,void 0,this),Q0(c0,{color:"gray",children:" (builtin)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.map((G)=>{let W=G.description.length>80?`${G.description.substring(0,80)}...`:G.description;return Q0(J$,{flexDirection:"column",paddingLeft:2,children:[Q0(c0,{children:[Q0(c0,{bold:!0,color:"green",children:["• ",G.name]},void 0,!0,void 0,this),Q0(c0,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),G.userInvocable&&Q0(J$,{paddingLeft:2,children:Q0(c0,{color:"blue",children:["命令: /",G.name]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},G.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q0(J$,{marginTop:1,children:Q0(c0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}z1();v1();import{Box as Y4,Text as W1}from"ink";import UF,{useEffect as fA,useState as hA}from"react";import{jsxDEV as q$}from"react/jsx-dev-runtime";var xA={init:"\uD83D\uDCDD",requirements:"\uD83D\uDCCB",design:"\uD83C\uDFA8",tasks:"\uD83D\uDCCC",implementation:"\uD83D\uDD27",done:"✅"},C7=["init","requirements","design","tasks","implementation","done"],pA={pending:"○",in_progress:"◐",completed:"●",blocked:"✕"},mA={pending:"gray",in_progress:"yellow",completed:"green",blocked:"red"},FF=UF.memo(({expanded:$=!1,maxTasks:Z=5})=>{let[Y,Q]=hA(null);if(fA(()=>{let q=k0.getInstance();Q(q.getCurrentSpec());let G=setInterval(()=>{Q(q.getCurrentSpec())},1000);return()=>clearInterval(G)},[]),!Y)return null;let X=C7.indexOf(Y.phase),J=Y.tasks.length>0?Math.round(Y.tasks.filter((q)=>q.status==="completed").length/Y.tasks.length*100):0;return q$(Y4,{flexDirection:"column",borderStyle:"round",borderColor:"blue",paddingX:1,marginBottom:1,children:[q$(Y4,{flexDirection:"row",justifyContent:"space-between",children:[q$(W1,{color:"blue",bold:!0,children:["\uD83D\uDCCB Spec: ",Y.name]},void 0,!0,void 0,this),q$(W1,{color:"gray",children:[xA[Y.phase]," ",M$[Y.phase]]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q$(Y4,{flexDirection:"row",marginTop:1,children:[C7.map((q,G)=>{let K=G<X,W=G===X;return q$(Y4,{flexDirection:"row",children:[q$(W1,{color:K?"green":W?"blue":"gray",children:K?"●":W?"◉":"○"},void 0,!1,void 0,this),G<C7.length-1&&q$(W1,{color:K?"green":"gray",children:"──"},void 0,!1,void 0,this)]},q,!0,void 0,this)}),q$(W1,{color:"gray",children:[" (",J,"%)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q$(Y4,{flexDirection:"row",marginTop:0,children:q$(W1,{color:"gray",dimColor:!0,children:C7.map((q,G)=>{let K=q.slice(0,3).toUpperCase();return G===X?`[${K}]`:` ${K} `}).join("")},void 0,!1,void 0,this)},void 0,!1,void 0,this),$&&Y.tasks.length>0&&q$(Y4,{flexDirection:"column",marginTop:1,children:[q$(W1,{color:"gray",dimColor:!0,children:["─── Tasks (",Y.tasks.filter((q)=>q.status==="completed").length,"/",Y.tasks.length,") ───"]},void 0,!0,void 0,this),Y.tasks.slice(0,Z).map((q)=>q$(gA,{task:q,isCurrent:q.id===Y.currentTaskId},q.id,!1,void 0,this)),Y.tasks.length>Z&&q$(W1,{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&&q$(Y4,{flexDirection:"row",marginTop:1,children:[q$(W1,{color:"gray",children:"Current: "},void 0,!1,void 0,this),q$(W1,{color:"yellow",children:Y.tasks.find((q)=>q.id===Y.currentTaskId)?.title||"Unknown"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}),gA=UF.memo(({task:$,isCurrent:Z})=>{let Y=pA[$.status]||"?",Q=mA[$.status]||"gray";return q$(Y4,{flexDirection:"row",children:[q$(W1,{color:Q,children:[Y," "]},void 0,!0,void 0,this),q$(W1,{color:Z?"yellow":"white",bold:Z,children:$.title},void 0,!1,void 0,this),$.complexity&&q$(W1,{color:"gray",dimColor:!0,children:[" ","[",$.complexity,"]"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});import{Box as uA,Text as V2}from"ink";import dA,{useEffect as cA,useState as OF}from"react";import{jsxDEV as j1,Fragment as _F}from"react/jsx-dev-runtime";var HF=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];function lA($){let Z=Math.floor($/1000);if(Z<60)return`${Z}s`;let Y=Math.floor(Z/60),Q=Z%60;return`${Y}m ${Q}s`}var zF=dA.memo(()=>{let $=B0((K)=>K.app.subagentProgress),Z=m0(),[Y,Q]=OF(0),[X,J]=OF(0);if(cA(()=>{if(!$||$.status!=="running"){Q(0),J(0);return}let K=setInterval(()=>{Q((U)=>(U+1)%HF.length)},80),W=setInterval(()=>{J(Date.now()-$.startTime)},1000);return()=>{clearInterval(K),clearInterval(W)}},[$]),!$)return null;let q=$.status==="running"?HF[Y]:$.status==="completed"?"✓":"✗",G=$.status==="running"?Z.colors.info:$.status==="completed"?Z.colors.success:Z.colors.error;return j1(uA,{paddingX:2,paddingY:0,flexDirection:"row",gap:1,children:[j1(V2,{color:G,bold:!0,children:q},void 0,!1,void 0,this),j1(V2,{color:Z.colors.muted,children:"Subagent"},void 0,!1,void 0,this),j1(V2,{color:Z.colors.text.primary,bold:!0,children:$.type},void 0,!1,void 0,this),j1(V2,{color:Z.colors.muted,children:"|"},void 0,!1,void 0,this),j1(V2,{color:Z.colors.text.secondary,children:$.description},void 0,!1,void 0,this),$.currentTool&&j1(_F,{children:[j1(V2,{color:Z.colors.muted,children:"|"},void 0,!1,void 0,this),j1(V2,{color:Z.colors.warning,children:$.currentTool},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$.status==="running"&&X>0&&j1(_F,{children:[j1(V2,{color:Z.colors.muted,children:"|"},void 0,!1,void 0,this),j1(V2,{color:Z.colors.info,children:lA(X)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});import{useMemoizedFn as iA}from"ahooks";import{Box as Y2,Text as c,useInput as aA}from"ink";import rA from"ink-select-input";import{useState as BF}from"react";T0();l7();q4();import{jsxDEV as p}from"react/jsx-dev-runtime";var wF=q2.map(($)=>({label:$.label,value:$.id})),nA=({theme:$})=>{let{colors:Z}=$;return p(Y2,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[p(c,{bold:!0,color:Z.text.primary,children:"代码预览"},void 0,!1,void 0,this),p(c,{children:" "},void 0,!1,void 0,this),p(c,{color:Z.syntax.comment,children:"# function"},void 0,!1,void 0,this),p(c,{children:[p(c,{color:Z.syntax.keyword,children:"def"},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.function,children:"fibonacci"},void 0,!1,void 0,this),p(c,{color:Z.text.primary,children:"("},void 0,!1,void 0,this),p(c,{color:Z.syntax.variable,children:"n"},void 0,!1,void 0,this),p(c,{color:Z.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p(c,{children:[" ",p(c,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this),p(c,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.operator,children:"="},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.number,children:"0"},void 0,!1,void 0,this),p(c,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.number,children:"1"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p(c,{children:[" ",p(c,{color:Z.syntax.keyword,children:"for"},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.variable,children:"_"},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.keyword,children:"in"},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.function,children:"range"},void 0,!1,void 0,this),p(c,{color:Z.text.primary,children:"("},void 0,!1,void 0,this),p(c,{color:Z.syntax.variable,children:"n"},void 0,!1,void 0,this),p(c,{color:Z.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p(c,{children:[" ",p(c,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this),p(c,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.operator,children:"="},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this),p(c,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.operator,children:"+"},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p(c,{children:[" ",p(c,{color:Z.syntax.keyword,children:"return"},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p(c,{children:" "},void 0,!1,void 0,this),p(c,{color:Z.error,children:["- print(",p(c,{color:Z.syntax.string,children:'"Hello, "'},void 0,!1,void 0,this)," + name)"]},void 0,!0,void 0,this),p(c,{color:Z.success,children:["+ print(",p(c,{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)},oA=({theme:$})=>{let{colors:Z}=$;return p(Y2,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[p(c,{children:" "},void 0,!1,void 0,this),p(c,{bold:!0,color:Z.text.primary,children:"颜色配置"},void 0,!1,void 0,this),p(c,{children:" "},void 0,!1,void 0,this),p(c,{children:[p(c,{color:Z.text.muted,children:"Primary: "},void 0,!1,void 0,this),p(c,{color:Z.primary,children:Z.primary},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p(c,{children:[p(c,{color:Z.text.muted,children:"Success: "},void 0,!1,void 0,this),p(c,{color:Z.success,children:Z.success},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p(c,{children:[p(c,{color:Z.text.muted,children:"Error: "},void 0,!1,void 0,this),p(c,{color:Z.error,children:Z.error},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p(c,{children:[p(c,{color:Z.text.muted,children:"Warning: "},void 0,!1,void 0,this),p(c,{color:Z.warning,children:Z.warning},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p(c,{children:[p(c,{color:Z.text.muted,children:"Info: "},void 0,!1,void 0,this),p(c,{color:Z.info,children:Z.info},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},LF=()=>{let $=i2(),Z=u$.getCurrentThemeName(),Y=q2.findIndex((_)=>_.label===Z),Q=Y>=0?q2[Y].theme:q2[0].theme,[X,J]=BF(Q),[q,G]=BF(!1),K=iA(async(_)=>{if(q)return;G(!0);try{await C0().setTheme(_.value),$.closeModal()}catch(z){console.error("❌ 主题切换失败:",z instanceof Error?z.message:z)}finally{G(!1)}}),W=(_)=>{let z=q2.find((w)=>w.id===_.value);if(z)J(z.theme)},F=Z1()==="theme-selector",O=Z$(!1);aA((_,z)=>{if(z.ctrl&&_==="c"||z.meta&&_==="c"){O();return}if(z.escape&&!q)$.closeModal()},{isActive:F});let H=(_)=>{let{isSelected:z,label:w}=_,L=w===Z?"✓":" ";return p(c,{color:z?X.colors.primary:X.colors.text.primary,children:[L," ",w]},void 0,!0,void 0,this)};return p(Y2,{flexDirection:"column",height:"100%",children:[p(Y2,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:X.colors.border.light,children:p(c,{bold:!0,color:X.colors.primary,children:"\uD83C\uDFA8 主题选择器"},void 0,!1,void 0,this)},void 0,!1,void 0,this),p(Y2,{flexDirection:"row",flexGrow:1,children:[p(Y2,{width:"40%",borderStyle:"single",borderColor:X.colors.border.light,paddingX:1,children:p(Y2,{flexDirection:"column",children:[p(Y2,{paddingTop:1,paddingBottom:1,children:p(c,{bold:!0,color:X.colors.text.primary,children:["可用主题 (",wF.length,")"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),p(rA,{items:wF,initialIndex:Y>=0?Y:0,onSelect:K,onHighlight:W,itemComponent:H},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),p(Y2,{width:"60%",flexDirection:"column",borderStyle:"single",borderColor:X.colors.border.light,children:[p(nA,{theme:X},void 0,!1,void 0,this),p(oA,{theme:X},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),p(Y2,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:X.colors.border.light,children:p(c,{color:X.colors.text.muted,children:q?"正在保存...":"Enter: 选择主题 | Esc: 取消"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as h0}from"react/jsx-dev-runtime";var n$=l("UI"),NF=({debug:$,continue:Z,...Y})=>{if($)n$.debug("[Debug] BladeInterface props:",{permissionMode:Y.permissionMode,yolo:Y.yolo,maxTurns:Y.maxTurns,continue:Z});let Q=S7(!1),X=S7(!1),J=S7(!1),q=S7(null),G=nK(),K=oK(),W=X7(),U=eK(),F=tK(),O=i2(),H=l2(),_=XW(),z=y3(),w=a2(),{exit:B}=sA(),L=G==="ready",V=G==="needsSetup",D=G==="idle",{confirmationState:R,confirmationHandler:y,handleResponse:I}=VW(),{executeCommand:N,handleAbort:P}=NW(Y.systemPrompt,Y.appendSystemPrompt,y,Y.maxTurns),{getPreviousCommand:m,getNextCommand:e,addToHistory:S}=AW();kW();let T=MW("",0),g=r$(async()=>{let Y0=z,j0;if(Y0==="default")j0="autoEdit";else if(Y0==="autoEdit")j0="plan";else if(Y0==="plan")j0="spec";else if(Y0==="spec")j0="default";else j0="default";try{if(await C0().setPermissionMode(j0),j0==="spec")try{let H$=k0.getInstance();await H$.initialize(process.cwd());let o$=await H$.listSpecs();if(o$.length>0){let s$=o$[0];await H$.loadSpec(s$.name),H.addAssistantMessage(`\uD83D\uDCCB **已进入 Spec 模式**
|
|
2842
|
+
`]},void 0,!0,void 0,this),D$(TA,{items:z,onSelect:B,indicatorComponent:SA,itemComponent:kA},void 0,!1,void 0,this),D$(m3,{marginTop:1,flexDirection:"column",children:[D$(c1,{dimColor:!0,children:["第 ",G+1,"/",_," 页 · 共 ",O.length," 个会话 · 显示"," ",w.start,"-",w.end]},void 0,!0,void 0,this),_>1&&D$(m3,{marginTop:1,children:[D$(c1,{color:G>0?"cyan":"gray",children:G>0?"◀ ← 上一页":" "},void 0,!1,void 0,this),D$(c1,{children:" "},void 0,!1,void 0,this),D$(c1,{color:G<_-1?"cyan":"gray",children:G<_-1?"下一页 → ▶":""},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};U2();import{Box as J$,Text as c0,useInput as fA}from"ink";import{jsxDEV as Q0}from"react/jsx-dev-runtime";function WF({onCancel:$}){let Y=N$().getAll(),Q=Y.filter((G)=>G.source==="builtin"),X=Y.filter((G)=>G.source==="user"),J=Y.filter((G)=>G.source==="project"),q=Y$(!1,$);if(fA((G,K)=>{if(K.escape)$?.();else if(K.ctrl&&G==="c"||K.meta&&G==="c")q()}),Y.length===0)return Q0(J$,{flexDirection:"column",paddingY:1,children:[Q0(J$,{marginBottom:1,children:Q0(c0,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q0(J$,{paddingLeft:2,children:Q0(c0,{color:"gray",children:"没有找到任何 Skill"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q0(J$,{marginTop:1,paddingLeft:2,children:Q0(c0,{color:"gray",children:"配置文件位置: ~/.blade/skills/ 或 .blade/skills/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),Q0(J$,{marginTop:1,children:Q0(c0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return Q0(J$,{flexDirection:"column",paddingY:1,children:[Q0(J$,{marginBottom:1,children:[Q0(c0,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this),Q0(c0,{color:"gray",children:[" (找到 ",Y.length," 个)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),J.length>0&&Q0(J$,{flexDirection:"column",marginBottom:1,children:[Q0(J$,{paddingLeft:1,children:[Q0(c0,{bold:!0,color:"yellow",children:"项目级"},void 0,!1,void 0,this),Q0(c0,{color:"gray",children:" (.blade/skills/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J.map((G)=>{let W=G.description.length>80?`${G.description.substring(0,80)}...`:G.description;return Q0(J$,{flexDirection:"column",paddingLeft:2,children:[Q0(c0,{children:[Q0(c0,{bold:!0,color:"green",children:["• ",G.name]},void 0,!0,void 0,this),Q0(c0,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),G.allowedTools&&G.allowedTools.length>0&&Q0(J$,{paddingLeft:2,children:Q0(c0,{color:"gray",children:["工具: ",G.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q0(J$,{paddingLeft:2,children:Q0(c0,{color:"gray",dimColor:!0,children:G.path},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},G.name,!0,void 0,this)})]},void 0,!0,void 0,this),X.length>0&&Q0(J$,{flexDirection:"column",marginBottom:1,children:[Q0(J$,{paddingLeft:1,children:[Q0(c0,{bold:!0,color:"yellow",children:"用户级"},void 0,!1,void 0,this),Q0(c0,{color:"gray",children:" (~/.blade/skills/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X.map((G)=>{let W=G.description.length>80?`${G.description.substring(0,80)}...`:G.description;return Q0(J$,{flexDirection:"column",paddingLeft:2,children:[Q0(c0,{children:[Q0(c0,{bold:!0,color:"green",children:["• ",G.name]},void 0,!0,void 0,this),Q0(c0,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),G.allowedTools&&G.allowedTools.length>0&&Q0(J$,{paddingLeft:2,children:Q0(c0,{color:"gray",children:["工具: ",G.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q0(J$,{paddingLeft:2,children:Q0(c0,{color:"gray",dimColor:!0,children:G.path},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},G.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.length>0&&Q0(J$,{flexDirection:"column",marginBottom:1,children:[Q0(J$,{paddingLeft:1,children:[Q0(c0,{bold:!0,color:"cyan",children:"内置"},void 0,!1,void 0,this),Q0(c0,{color:"gray",children:" (builtin)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.map((G)=>{let W=G.description.length>80?`${G.description.substring(0,80)}...`:G.description;return Q0(J$,{flexDirection:"column",paddingLeft:2,children:[Q0(c0,{children:[Q0(c0,{bold:!0,color:"green",children:["• ",G.name]},void 0,!0,void 0,this),Q0(c0,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),G.userInvocable&&Q0(J$,{paddingLeft:2,children:Q0(c0,{color:"blue",children:["命令: /",G.name]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},G.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q0(J$,{marginTop:1,children:Q0(c0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}z1();v1();import{Box as Y4,Text as W1}from"ink";import UF,{useEffect as hA,useState as xA}from"react";import{jsxDEV as q$}from"react/jsx-dev-runtime";var pA={init:"\uD83D\uDCDD",requirements:"\uD83D\uDCCB",design:"\uD83C\uDFA8",tasks:"\uD83D\uDCCC",implementation:"\uD83D\uDD27",done:"✅"},C7=["init","requirements","design","tasks","implementation","done"],mA={pending:"○",in_progress:"◐",completed:"●",blocked:"✕"},gA={pending:"gray",in_progress:"yellow",completed:"green",blocked:"red"},FF=UF.memo(({expanded:$=!1,maxTasks:Z=5})=>{let[Y,Q]=xA(null);if(hA(()=>{let q=k0.getInstance();Q(q.getCurrentSpec());let G=setInterval(()=>{Q(q.getCurrentSpec())},1000);return()=>clearInterval(G)},[]),!Y)return null;let X=C7.indexOf(Y.phase),J=Y.tasks.length>0?Math.round(Y.tasks.filter((q)=>q.status==="completed").length/Y.tasks.length*100):0;return q$(Y4,{flexDirection:"column",borderStyle:"round",borderColor:"blue",paddingX:1,marginBottom:1,children:[q$(Y4,{flexDirection:"row",justifyContent:"space-between",children:[q$(W1,{color:"blue",bold:!0,children:["\uD83D\uDCCB Spec: ",Y.name]},void 0,!0,void 0,this),q$(W1,{color:"gray",children:[pA[Y.phase]," ",M$[Y.phase]]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q$(Y4,{flexDirection:"row",marginTop:1,children:[C7.map((q,G)=>{let K=G<X,W=G===X;return q$(Y4,{flexDirection:"row",children:[q$(W1,{color:K?"green":W?"blue":"gray",children:K?"●":W?"◉":"○"},void 0,!1,void 0,this),G<C7.length-1&&q$(W1,{color:K?"green":"gray",children:"──"},void 0,!1,void 0,this)]},q,!0,void 0,this)}),q$(W1,{color:"gray",children:[" (",J,"%)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q$(Y4,{flexDirection:"row",marginTop:0,children:q$(W1,{color:"gray",dimColor:!0,children:C7.map((q,G)=>{let K=q.slice(0,3).toUpperCase();return G===X?`[${K}]`:` ${K} `}).join("")},void 0,!1,void 0,this)},void 0,!1,void 0,this),$&&Y.tasks.length>0&&q$(Y4,{flexDirection:"column",marginTop:1,children:[q$(W1,{color:"gray",dimColor:!0,children:["─── Tasks (",Y.tasks.filter((q)=>q.status==="completed").length,"/",Y.tasks.length,") ───"]},void 0,!0,void 0,this),Y.tasks.slice(0,Z).map((q)=>q$(uA,{task:q,isCurrent:q.id===Y.currentTaskId},q.id,!1,void 0,this)),Y.tasks.length>Z&&q$(W1,{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&&q$(Y4,{flexDirection:"row",marginTop:1,children:[q$(W1,{color:"gray",children:"Current: "},void 0,!1,void 0,this),q$(W1,{color:"yellow",children:Y.tasks.find((q)=>q.id===Y.currentTaskId)?.title||"Unknown"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}),uA=UF.memo(({task:$,isCurrent:Z})=>{let Y=mA[$.status]||"?",Q=gA[$.status]||"gray";return q$(Y4,{flexDirection:"row",children:[q$(W1,{color:Q,children:[Y," "]},void 0,!0,void 0,this),q$(W1,{color:Z?"yellow":"white",bold:Z,children:$.title},void 0,!1,void 0,this),$.complexity&&q$(W1,{color:"gray",dimColor:!0,children:[" ","[",$.complexity,"]"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});import{Box as dA,Text as V2}from"ink";import cA,{useEffect as lA,useState as OF}from"react";import{jsxDEV as j1,Fragment as _F}from"react/jsx-dev-runtime";var HF=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];function iA($){let Z=Math.floor($/1000);if(Z<60)return`${Z}s`;let Y=Math.floor(Z/60),Q=Z%60;return`${Y}m ${Q}s`}var zF=cA.memo(()=>{let $=B0((K)=>K.app.subagentProgress),Z=m0(),[Y,Q]=OF(0),[X,J]=OF(0);if(lA(()=>{if(!$||$.status!=="running"){Q(0),J(0);return}let K=setInterval(()=>{Q((U)=>(U+1)%HF.length)},80),W=setInterval(()=>{J(Date.now()-$.startTime)},1000);return()=>{clearInterval(K),clearInterval(W)}},[$]),!$)return null;let q=$.status==="running"?HF[Y]:$.status==="completed"?"✓":"✗",G=$.status==="running"?Z.colors.info:$.status==="completed"?Z.colors.success:Z.colors.error;return j1(dA,{paddingX:2,paddingY:0,flexDirection:"row",gap:1,children:[j1(V2,{color:G,bold:!0,children:q},void 0,!1,void 0,this),j1(V2,{color:Z.colors.muted,children:"Subagent"},void 0,!1,void 0,this),j1(V2,{color:Z.colors.text.primary,bold:!0,children:$.type},void 0,!1,void 0,this),j1(V2,{color:Z.colors.muted,children:"|"},void 0,!1,void 0,this),j1(V2,{color:Z.colors.text.secondary,children:$.description},void 0,!1,void 0,this),$.currentTool&&j1(_F,{children:[j1(V2,{color:Z.colors.muted,children:"|"},void 0,!1,void 0,this),j1(V2,{color:Z.colors.warning,children:$.currentTool},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$.status==="running"&&X>0&&j1(_F,{children:[j1(V2,{color:Z.colors.muted,children:"|"},void 0,!1,void 0,this),j1(V2,{color:Z.colors.info,children:iA(X)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});import{useMemoizedFn as aA}from"ahooks";import{Box as Y2,Text as c,useInput as rA}from"ink";import nA from"ink-select-input";import{useState as BF}from"react";T0();l7();q4();import{jsxDEV as p}from"react/jsx-dev-runtime";var wF=q2.map(($)=>({label:$.label,value:$.id})),oA=({theme:$})=>{let{colors:Z}=$;return p(Y2,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[p(c,{bold:!0,color:Z.text.primary,children:"代码预览"},void 0,!1,void 0,this),p(c,{children:" "},void 0,!1,void 0,this),p(c,{color:Z.syntax.comment,children:"# function"},void 0,!1,void 0,this),p(c,{children:[p(c,{color:Z.syntax.keyword,children:"def"},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.function,children:"fibonacci"},void 0,!1,void 0,this),p(c,{color:Z.text.primary,children:"("},void 0,!1,void 0,this),p(c,{color:Z.syntax.variable,children:"n"},void 0,!1,void 0,this),p(c,{color:Z.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p(c,{children:[" ",p(c,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this),p(c,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.operator,children:"="},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.number,children:"0"},void 0,!1,void 0,this),p(c,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.number,children:"1"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p(c,{children:[" ",p(c,{color:Z.syntax.keyword,children:"for"},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.variable,children:"_"},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.keyword,children:"in"},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.function,children:"range"},void 0,!1,void 0,this),p(c,{color:Z.text.primary,children:"("},void 0,!1,void 0,this),p(c,{color:Z.syntax.variable,children:"n"},void 0,!1,void 0,this),p(c,{color:Z.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p(c,{children:[" ",p(c,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this),p(c,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.operator,children:"="},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this),p(c,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.operator,children:"+"},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p(c,{children:[" ",p(c,{color:Z.syntax.keyword,children:"return"},void 0,!1,void 0,this)," ",p(c,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p(c,{children:" "},void 0,!1,void 0,this),p(c,{color:Z.error,children:["- print(",p(c,{color:Z.syntax.string,children:'"Hello, "'},void 0,!1,void 0,this)," + name)"]},void 0,!0,void 0,this),p(c,{color:Z.success,children:["+ print(",p(c,{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)},sA=({theme:$})=>{let{colors:Z}=$;return p(Y2,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[p(c,{children:" "},void 0,!1,void 0,this),p(c,{bold:!0,color:Z.text.primary,children:"颜色配置"},void 0,!1,void 0,this),p(c,{children:" "},void 0,!1,void 0,this),p(c,{children:[p(c,{color:Z.text.muted,children:"Primary: "},void 0,!1,void 0,this),p(c,{color:Z.primary,children:Z.primary},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p(c,{children:[p(c,{color:Z.text.muted,children:"Success: "},void 0,!1,void 0,this),p(c,{color:Z.success,children:Z.success},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p(c,{children:[p(c,{color:Z.text.muted,children:"Error: "},void 0,!1,void 0,this),p(c,{color:Z.error,children:Z.error},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p(c,{children:[p(c,{color:Z.text.muted,children:"Warning: "},void 0,!1,void 0,this),p(c,{color:Z.warning,children:Z.warning},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p(c,{children:[p(c,{color:Z.text.muted,children:"Info: "},void 0,!1,void 0,this),p(c,{color:Z.info,children:Z.info},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},LF=()=>{let $=i2(),Z=u$.getCurrentThemeName(),Y=q2.findIndex((_)=>_.label===Z),Q=Y>=0?q2[Y].theme:q2[0].theme,[X,J]=BF(Q),[q,G]=BF(!1),K=aA(async(_)=>{if(q)return;G(!0);try{await C0().setTheme(_.value),$.closeModal()}catch(z){console.error("❌ 主题切换失败:",z instanceof Error?z.message:z)}finally{G(!1)}}),W=(_)=>{let z=q2.find((w)=>w.id===_.value);if(z)J(z.theme)},F=Z1()==="theme-selector",O=Y$(!1);rA((_,z)=>{if(z.ctrl&&_==="c"||z.meta&&_==="c"){O();return}if(z.escape&&!q)$.closeModal()},{isActive:F});let H=(_)=>{let{isSelected:z,label:w}=_,L=w===Z?"✓":" ";return p(c,{color:z?X.colors.primary:X.colors.text.primary,children:[L," ",w]},void 0,!0,void 0,this)};return p(Y2,{flexDirection:"column",height:"100%",children:[p(Y2,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:X.colors.border.light,children:p(c,{bold:!0,color:X.colors.primary,children:"\uD83C\uDFA8 主题选择器"},void 0,!1,void 0,this)},void 0,!1,void 0,this),p(Y2,{flexDirection:"row",flexGrow:1,children:[p(Y2,{width:"40%",borderStyle:"single",borderColor:X.colors.border.light,paddingX:1,children:p(Y2,{flexDirection:"column",children:[p(Y2,{paddingTop:1,paddingBottom:1,children:p(c,{bold:!0,color:X.colors.text.primary,children:["可用主题 (",wF.length,")"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),p(nA,{items:wF,initialIndex:Y>=0?Y:0,onSelect:K,onHighlight:W,itemComponent:H},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),p(Y2,{width:"60%",flexDirection:"column",borderStyle:"single",borderColor:X.colors.border.light,children:[p(oA,{theme:X},void 0,!1,void 0,this),p(sA,{theme:X},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),p(Y2,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:X.colors.border.light,children:p(c,{color:X.colors.text.muted,children:q?"正在保存...":"Enter: 选择主题 | Esc: 取消"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as h0}from"react/jsx-dev-runtime";var n$=l("UI"),NF=({debug:$,continue:Z,...Y})=>{if($)n$.debug("[Debug] BladeInterface props:",{permissionMode:Y.permissionMode,yolo:Y.yolo,maxTurns:Y.maxTurns,continue:Z});let Q=S7(!1),X=S7(!1),J=S7(!1),q=S7(null),G=nK(),K=oK(),W=X7(),U=eK(),F=tK(),O=i2(),H=l2(),_=XW(),z=y3(),w=a2(),{exit:B}=tA(),L=G==="ready",V=G==="needsSetup",D=G==="idle",{confirmationState:R,confirmationHandler:y,handleResponse:I}=VW(),{executeCommand:N,handleAbort:P}=NW(Y.systemPrompt,Y.appendSystemPrompt,y,Y.maxTurns),{getPreviousCommand:m,getNextCommand:e,addToHistory:S}=AW();kW();let T=MW("",0),g=r$(async()=>{let Y0=z,j0;if(Y0==="default")j0="autoEdit";else if(Y0==="autoEdit")j0="plan";else if(Y0==="plan")j0="spec";else if(Y0==="spec")j0="default";else j0="default";try{if(await C0().setPermissionMode(j0),j0==="spec")try{let H$=k0.getInstance();await H$.initialize(process.cwd());let o$=await H$.listSpecs();if(o$.length>0){let s$=o$[0];await H$.loadSpec(s$.name),H.addAssistantMessage(`\uD83D\uDCCB **已进入 Spec 模式**
|
|
2843
2843
|
|
|
2844
2844
|
`+`检测到已存在的 Spec: **${s$.name}**
|
|
2845
2845
|
`+`当前阶段: ${s$.phase}
|
|
@@ -2850,6 +2850,6 @@ ${u}
|
|
|
2850
2850
|
`+"`提案 → 需求 → 设计 → 任务 → 实现`\n\n"+'例如:"实现用户认证功能" 或 "添加暗黑模式支持"')}catch(H$){n$.warn("Failed to initialize SpecManager:",H$),H.addAssistantMessage(`\uD83D\uDCCB **已进入 Spec 模式**
|
|
2851
2851
|
|
|
2852
2852
|
`+`请告诉我你想实现什么功能,我会引导你完成整个工作流:
|
|
2853
|
-
`+"`提案 → 需求 → 设计 → 任务 → 实现`\n\n"+'例如:"实现用户认证功能" 或 "添加暗黑模式支持"')}}catch(H$){n$.error("❌ 权限模式切换失败:",H$ instanceof Error?H$.message:H$)}}),j=r$(async(Y0)=>{try{await C0().addModel({name:Y0.name,provider:Y0.provider,apiKey:Y0.apiKey,baseUrl:Y0.baseUrl,model:Y0.model}),O.setInitializationStatus("ready")}catch(j0){n$.error("❌ 初始化配置保存失败:",j0 instanceof Error?j0.message:j0),O.setInitializationStatus("ready")}}),M=r$(()=>{if(W==="shortcuts")O.closeModal();else O.setActiveModal("shortcuts")}),{showSuggestions:A,suggestions:r,selectedSuggestionIndex:E}=SW(T,N,m,e,S,P,w,g,M,W==="shortcuts");m4(()=>{if(T.value&&W==="shortcuts")O.closeModal()},[T.value,W,O]);let u=r$(async()=>{J.current=!0;try{let Y0=await w1.listSessions();if(Y0.length===0){H.addAssistantMessage("没有找到历史会话,开始新对话。");return}let j0=Y0[0],H$=await w1.loadSession(j0.sessionId),o$=H$.map((s$,MY)=>({id:`restored-${Date.now()}-${MY}`,role:s$.role,content:typeof s$.content==="string"?s$.content:JSON.stringify(s$.content),timestamp:Date.now()-(H$.length-MY)*1000}));H.restoreSession(j0.sessionId,o$)}catch(Y0){n$.error("[BladeInterface] 继续会话失败:",Y0),H.addAssistantMessage("继续会话失败,开始新对话。")}}),Z0=r$(async()=>{J.current=!0;try{if(typeof Y.resume==="string"&&Y.resume!=="true"){let j0=await w1.loadSession(Y.resume),H$=j0.map((o$,s$)=>({id:`restored-${Date.now()}-${s$}`,role:o$.role,content:typeof o$.content==="string"?o$.content:JSON.stringify(o$.content),timestamp:Date.now()-(j0.length-s$)*1000}));H.restoreSession(Y.resume,H$);return}let Y0=await w1.listSessions();if(Y0.length===0)n$.error("没有找到历史会话"),I3(1);O.showSessionSelector(Y0)}catch(Y0){n$.error("[BladeInterface] 加载会话失败:",Y0),I3(1)}});m4(()=>{if(Q.current)return;if(Z){Q.current=!0,u();return}if(Y.resume)Q.current=!0,Z0()},[Z,Y.resume,u,Z0]);let d=r$(async(Y0)=>{let j0=R.details?.type;if(j0==="enterPlanMode"&&Y0.approved)try{await C0().setPermissionMode("plan"),n$.debug("[BladeInterface] Entered Plan mode")}catch(H$){n$.error("[BladeInterface] Failed to enter Plan mode:",H$)}if(j0==="exitPlanMode"&&Y0.approved)n$.debug("[BladeInterface] ExitPlanMode approved, Store auto-synced");I(Y0)}),s=r$(()=>{H.addAssistantMessage("❌ 设置已取消"),H.addAssistantMessage("Blade 需要 API 配置才能正常工作。"),H.addAssistantMessage("您可以稍后运行 Blade 重新进入设置向导。"),I3(0)}),k=r$(()=>{O.closeModal()}),a=r$(async(Y0)=>{try{let j0=await w1.loadSession(Y0),H$=j0.map((o$,s$)=>({id:`restored-${Date.now()}-${s$}`,role:o$.role,content:typeof o$.content==="string"?o$.content:JSON.stringify(o$.content),timestamp:Date.now()-(j0.length-s$)*1000}));H.restoreSession(Y0,H$),O.closeModal()}catch(j0){n$.error("[BladeInterface] Failed to restore session:",j0),O.closeModal()}}),n=r$(()=>{if(Y.resume)B();else O.closeModal()}),U0=r$((Y0)=>{O.showModelEditWizard(Y0)}),M0=r$((Y0)=>{H.addAssistantMessage(`✅ 已添加模型配置: ${Y0.name},并已切换到该模型`),k()}),$$=r$((Y0)=>{H.addAssistantMessage(`✅ 已更新模型配置: ${Y0.name}`),k()});m4(()=>{if(V){_.setFocus("model-config-wizard");return}if(R.isVisible)_.setFocus("confirmation-prompt");else if(W==="sessionSelector")_.setFocus("session-selector");else if(W==="themeSelector")_.setFocus("theme-selector");else if(W==="modelSelector")_.setFocus("model-selector");else if(W==="modelAddWizard"||W==="modelEditWizard")_.setFocus("model-config-wizard");else if(W==="permissionsManager")_.setFocus("permissions-manager");else if(W==="agentsManager")_.setFocus("agents-manager");else if(W==="agentCreationWizard")_.setFocus("agent-creation-wizard");else if(W==="hooksManager")_.setFocus("hooks-manager");else if(W==="shortcuts")_.setFocus("main-input");else _.setFocus("main-input")},[V,R.isVisible,W,_.setFocus]),m4(()=>{if(!L||J.current)return;if(OQ().length>0){J.current=!0;return}J.current=!0,H.addAssistantMessage("请输入您的问题,我将为您提供帮助。")},[L]),m4(()=>{if(!K)return;if(q.current===K)return;if(q.current=K,G==="error")H.addAssistantMessage(`❌ 初始化失败: ${K}`);else H.addAssistantMessage(`❌ ${K}`),H.addAssistantMessage("请重新尝试设置,或检查文件权限")},[K,G,H.addAssistantMessage]);let j2=r$(async(Y0)=>{try{await N({displayText:Y0,text:Y0,images:[],parts:[{type:"text",text:Y0}]})}catch(j0){let H$=j0 instanceof Error?j0.message:"无法发送初始消息";H.addAssistantMessage(`❌ 初始消息发送失败:${H$}`)}});m4(()=>{let Y0=Y.initialMessage?.trim();if(!Y0||X.current||!L||V)return;X.current=!0,S(Y0),j2(Y0)},[Y.initialMessage,L,V,N,S]);let E$=r$(async(Y0)=>{try{await C0().setPermissionMode(Y0)}catch(j0){n$.error("❌ 权限模式初始化失败:",j0 instanceof Error?j0.message:j0)}});if(m4(()=>{let Y0=Y.permissionMode;if($)n$.debug("[Debug] permissionMode from CLI:",Y0),n$.debug("[Debug] current permissionMode:",z);if(!Y0||Y0===z)return;E$(Y0)},[Y.permissionMode,z]),D)return null;if(V)return h0(zY,{mode:"setup",onComplete:j,onCancel:s},void 0,!1,void 0,this);if($)n$.debug("[Debug] 渲染主界面,条件检查:",{confirmationVisible:R.isVisible,activeModal:W});let X0=W==="modelSelector",s0=F,w0=W==="modelAddWizard"?"add":W==="modelEditWizard"&&s0?"edit":null,X2=X0||Boolean(w0),p$=W==="agentsManager",I2=W==="agentCreationWizard",I1=W==="skillsManager",a8=W==="pluginsManager",vF=s0?{name:s0.name,provider:s0.provider,baseUrl:s0.baseUrl,apiKey:s0.apiKey,model:s0.model}:void 0,VY=R.isVisible&&R.details?R.details.type==="askUserQuestion"&&R.details.questions?h0(qF,{questions:R.details.questions,onComplete:(Y0)=>d({approved:!0,answers:Y0}),onCancel:()=>d({approved:!1})},void 0,!1,void 0,this):h0(QU,{details:R.details,onResponse:d},void 0,!1,void 0,this):W==="themeSelector"?h0(LF,{},void 0,!1,void 0,this):W==="permissionsManager"?h0(QF,{onClose:k},void 0,!1,void 0,this):W==="sessionSelector"?h0(KF,{sessions:U,onSelect:a,onCancel:n},void 0,!1,void 0,this):W==="hooksManager"?h0(JU,{onClose:k},void 0,!1,void 0,this):null,DY=Boolean(VY);return h0(Q4,{flexDirection:"column",width:"100%",overflow:"hidden",children:[VY,h0(Q4,{flexDirection:"column",display:DY?"none":"flex",children:[z==="spec"&&h0(FF,{},void 0,!1,void 0,this),h0(EU,{},void 0,!1,void 0,this),h0(zF,{},void 0,!1,void 0,this),h0(VU,{paused:DY},void 0,!1,void 0,this),h0(BU,{input:T.value,cursorPosition:T.cursorPosition,onChange:T.setValue,onChangeCursorPosition:T.setCursorPosition,onAddPasteMapping:T.addPasteMapping,onAddImagePasteMapping:T.addImagePasteMapping},void 0,!1,void 0,this),X0&&h0(Q4,{marginTop:1,paddingX:2,children:h0(tU,{onClose:k,onEdit:U0},void 0,!1,void 0,this)},void 0,!1,void 0,this),w0&&h0(Q4,{marginTop:1,paddingX:2,children:h0(zY,{mode:w0,modelId:s0?.id,initialConfig:w0==="edit"?vF:void 0,onComplete:w0==="edit"?$$:M0,onCancel:k},void 0,!1,void 0,this)},void 0,!1,void 0,this),p$&&h0(Q4,{marginTop:1,paddingX:2,children:h0(mW,{onComplete:k,onCancel:k},void 0,!1,void 0,this)},void 0,!1,void 0,this),I2&&h0(Q4,{marginTop:1,paddingX:2,children:h0(x8,{onComplete:k,onCancel:k},void 0,!1,void 0,this)},void 0,!1,void 0,this),I1&&h0(Q4,{marginTop:1,paddingX:2,children:h0(WF,{onComplete:k,onCancel:k},void 0,!1,void 0,this)},void 0,!1,void 0,this),a8&&h0(Q4,{marginTop:1,paddingX:2,children:h0(XF,{onComplete:k,onCancel:k},void 0,!1,void 0,this)},void 0,!1,void 0,this),h0(cW,{suggestions:r,selectedIndex:E,visible:A&&!X2},void 0,!1,void 0,this),h0(dW,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{Box as tA,Text as X4}from"ink";import eA from"react";import{jsxDEV as D2}from"react/jsx-dev-runtime";class k7 extends eA.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 D2(tA,{flexDirection:"column",padding:1,borderStyle:"round",borderColor:"red",children:[D2(X4,{color:"red",children:"\uD83D\uDCA5 应用发生错误"},void 0,!1,void 0,this),D2(X4,{children:" "},void 0,!1,void 0,this),D2(X4,{color:"red",children:this.state.error?.message},void 0,!1,void 0,this),D2(X4,{children:" "},void 0,!1,void 0,this),D2(X4,{color:"gray",children:"错误详情:"},void 0,!1,void 0,this),D2(X4,{color:"gray",children:this.state.error?.stack},void 0,!1,void 0,this),D2(X4,{children:" "},void 0,!1,void 0,this),D2(X4,{color:"yellow",children:"请重启应用或联系开发者"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return this.props.children}}import{Box as g4,Text as M2,useInput as $R}from"ink";import{useState as LY}from"react";import{jsxDEV as x$}from"react/jsx-dev-runtime";var f7=[{key:"update",label:"Update now",description:`runs \`${yZ()}\``},{key:"skip",label:"Skip",description:""},{key:"skip_until_next",label:"Skip until next version",description:""}],bF=({versionInfo:$,onComplete:Z})=>{let[Y,Q]=LY(0),[X,J]=LY(!1),[q,G]=LY(null);$R((W,U)=>{if(U.ctrl&&W==="c"){y4().shutdown("SIGINT",0);return}if(X||q)return;if(U.upArrow||W==="k")Q((F)=>F>0?F-1:f7.length-1);else if(U.downArrow||W==="j")Q((F)=>F<f7.length-1?F+1:0);else if(U.return)K(f7[Y].key);else if(W==="1")K("update");else if(W==="2")K("skip");else if(W==="3")K("skip_until_next")});let K=async(W)=>{switch(W){case"update":{J(!0);let U=await xK();G(U.message),setTimeout(()=>{y4().shutdown("SIGINT",0)},1500);break}case"skip":Z();break;case"skip_until_next":if($.latestVersion)await hK($.latestVersion);Z();break}};if(q)return x$(g4,{flexDirection:"column",marginY:1,children:x$(M2,{children:q},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(X)return x$(g4,{flexDirection:"column",marginY:1,children:x$(M2,{color:"cyan",children:"Updating..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);return x$(g4,{flexDirection:"column",marginY:1,children:[x$(M2,{color:"yellow",bold:!0,children:["✨ Update available! ",x$(M2,{color:"gray",children:[$.currentVersion," ","→"," ",$.latestVersion]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),x$(g4,{marginTop:1,children:x$(M2,{color:"gray",children:["Release notes:"," ",x$(M2,{color:"cyan",underline:!0,children:$.releaseNotesUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),x$(g4,{flexDirection:"column",marginTop:1,children:f7.map((W,U)=>{let F=U===Y,O=F?"› ":" ",H=`${U+1}. `;return x$(g4,{children:x$(M2,{color:F?"cyan":void 0,children:[O,H,W.label,W.description&&x$(M2,{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),x$(g4,{marginTop:1,children:x$(M2,{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)};q4();function g3($){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 h7}from"react/jsx-dev-runtime";function YR($){let Z=iQ();if(!$.models)$.models=[];for(let Y of Z){let Q=$.models.findIndex((X)=>X.id===Y.id);if(Q>=0){if($.models[Q]=Y,$.debug)console.log(`[Debug] 已更新内置模型: ${Y.name}`)}else if($.models.unshift(Y),$.debug)console.log(`[Debug] 已添加内置模型: ${Y.name}`)}if(!$.currentModelId)$.currentModelId=lQ();if(J0().config.actions.setConfig($),$.debug)console.log("[Debug] 模型配置检查通过,准备就绪");K2().setInitializationStatus("ready")}var RF=($)=>{let[Z,Y]=NY(!1),[Q,X]=NY(null),[J,q]=NY(!1),G=AF(async()=>{let W=J0().config.config??d4,U=g7(W,$);if(YR(U),U.debug)console.error("[Debug] 运行时配置:",U);let F=U.theme;if(F&&u$.hasTheme(F)){if(u$.setTheme(F),$.debug)console.log(`✓ 已加载主题: ${F}`)}try{let O=Y$.loadFromStandardLocations();if($.debug&&O>0)console.log(`✓ 已加载 ${O} 个 subagents: ${Y$.getAllNames().join(", ")}`)}catch(O){if($.debug)console.warn("⚠️ Subagents 加载失败:",g3(O))}try{let O=R0.getInstance();if(O.loadConfig(U.hooks||{}),$.debug&&U.hooks?.enabled)console.log("✓ Hooks 系统已启用");let H=J0(),_=H.session.sessionId;if(hY(_),O.isEnabled()){let z=H.config.config?.permissionMode||"default",w=!!$.resume,B=await O.executeSessionStartHooks({projectDir:process.cwd(),sessionId:_,permissionMode:z,isResume:w,resumeSessionId:typeof $.resume==="string"?$.resume:void 0});if(B.env){for(let[L,V]of Object.entries(B.env))process.env[L]=V;if($.debug)console.log("✓ SessionStart hooks 注入环境变量:",Object.keys(B.env).join(", "))}if(B.warning&&$.debug)console.warn("⚠️ SessionStart hooks 警告:",B.warning)}}catch(O){if($.debug)console.warn("⚠️ Hooks 初始化失败:",g3(O))}try{let O=await _4();if($.debug&&O.skills.length>0)console.log(`✓ 已加载 ${O.skills.length} 个 skills: ${O.skills.map((H)=>H.name).join(", ")}`);if(O.errors.length>0&&$.debug)for(let H of O.errors)console.warn(`⚠️ Skill 加载错误 (${H.path}): ${H.error}`)}catch(O){if($.debug)console.warn("⚠️ Skills 初始化失败:",g3(O))}try{let O=await yK(process.cwd());if($.debug&&O.commands.length>0)console.log(`✓ 已加载 ${O.commands.length} 个自定义命令: ${O.commands.map((H)=>H.name).join(", ")}`);if(O.errors.length>0&&$.debug)for(let H of O.errors)console.warn(`⚠️ 自定义命令加载错误 (${H.path}): ${H.error}`)}catch(O){if($.debug)console.warn("⚠️ 自定义命令初始化失败:",g3(O))}try{let H=await a$().initialize(process.cwd(),$.pluginDir||[]);if($.debug&&H.plugins.length>0)console.log(`✓ 已加载 ${H.plugins.length} 个插件: ${H.plugins.map((_)=>_.manifest.name).join(", ")}`);if(H.plugins.length>0){let _=await g2();if($.debug){let{totalCommands:z,totalSkills:w,totalAgents:B,totalMcpServers:L}=_;console.log(` ✓ 已集成: ${z} 命令, ${w} 技能, ${B} 代理, ${L} MCP 服务器`)}}if(H.errors.length>0&&$.debug)for(let _ of H.errors)console.warn(`⚠️ 插件加载错误 (${_.path}): ${_.error}`)}catch(O){if($.debug)console.warn("⚠️ 插件系统初始化失败:",g3(O))}uK(async()=>{y$.getInstance().killAll(),await w$.getInstance().disconnectAll(),R0.getInstance().cleanup()}),Y(!0)}),K=AF(async()=>{if($.versionCheckPromise){let W=await $.versionCheckPromise;if(W){X(W),q(!0);return}}await G()});if(ZR(()=>{K()},[]),J&&Q)return h7(k7,{children:h7(bF,{versionInfo:Q,onComplete:()=>{q(!1),G()}},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(!Z)return null;return h7(k7,{children:h7(NF,{...$},void 0,!1,void 0,this)},void 0,!1,void 0,this)};var RY=yF(process.argv),IF=RY.indexOf("--debug");if(IF!==-1){let $=RY[IF+1],Z=$&&!$.startsWith("-")?$:!0;y1.setGlobalDebug(Z)}async function OR(){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);dK();let $=pK();if(await EK())return;if(RY.includes("--acp")){let{runAcpIntegration:Y}=await Promise.resolve().then(() => (jF(),MF));await Y();return}let Z=FR(yF(process.argv)).scriptName(J4.scriptName).usage(J4.usage).version(J4.version).locale(J4.locale).showHelpOnFail(J4.showHelpOnFail).demandCommand(0,"").recommendCommands().strict(J4.strict).parserConfiguration({"populate--":!0}).options(TY).middleware([_Q,zQ,BQ]).command(fQ).command(wQ).command(mK).command(LQ).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(`
|
|
2853
|
+
`+"`提案 → 需求 → 设计 → 任务 → 实现`\n\n"+'例如:"实现用户认证功能" 或 "添加暗黑模式支持"')}}catch(H$){n$.error("❌ 权限模式切换失败:",H$ instanceof Error?H$.message:H$)}}),j=r$(async(Y0)=>{try{await C0().addModel({name:Y0.name,provider:Y0.provider,apiKey:Y0.apiKey,baseUrl:Y0.baseUrl,model:Y0.model}),O.setInitializationStatus("ready")}catch(j0){n$.error("❌ 初始化配置保存失败:",j0 instanceof Error?j0.message:j0),O.setInitializationStatus("ready")}}),M=r$(()=>{if(W==="shortcuts")O.closeModal();else O.setActiveModal("shortcuts")}),{showSuggestions:A,suggestions:r,selectedSuggestionIndex:E}=SW(T,N,m,e,S,P,w,g,M,W==="shortcuts");m4(()=>{if(T.value&&W==="shortcuts")O.closeModal()},[T.value,W,O]);let u=r$(async()=>{J.current=!0;try{let Y0=await w1.listSessions();if(Y0.length===0){H.addAssistantMessage("没有找到历史会话,开始新对话。");return}let j0=Y0[0],H$=await w1.loadSession(j0.sessionId),o$=H$.map((s$,MY)=>({id:`restored-${Date.now()}-${MY}`,role:s$.role,content:typeof s$.content==="string"?s$.content:JSON.stringify(s$.content),timestamp:Date.now()-(H$.length-MY)*1000}));H.restoreSession(j0.sessionId,o$)}catch(Y0){n$.error("[BladeInterface] 继续会话失败:",Y0),H.addAssistantMessage("继续会话失败,开始新对话。")}}),Z0=r$(async()=>{J.current=!0;try{if(typeof Y.resume==="string"&&Y.resume!=="true"){let j0=await w1.loadSession(Y.resume),H$=j0.map((o$,s$)=>({id:`restored-${Date.now()}-${s$}`,role:o$.role,content:typeof o$.content==="string"?o$.content:JSON.stringify(o$.content),timestamp:Date.now()-(j0.length-s$)*1000}));H.restoreSession(Y.resume,H$);return}let Y0=await w1.listSessions();if(Y0.length===0)n$.error("没有找到历史会话"),I3(1);O.showSessionSelector(Y0)}catch(Y0){n$.error("[BladeInterface] 加载会话失败:",Y0),I3(1)}});m4(()=>{if(Q.current)return;if(Z){Q.current=!0,u();return}if(Y.resume)Q.current=!0,Z0()},[Z,Y.resume,u,Z0]);let d=r$(async(Y0)=>{let j0=R.details?.type;if(j0==="enterPlanMode"&&Y0.approved)try{await C0().setPermissionMode("plan"),n$.debug("[BladeInterface] Entered Plan mode")}catch(H$){n$.error("[BladeInterface] Failed to enter Plan mode:",H$)}if(j0==="exitPlanMode"&&Y0.approved)n$.debug("[BladeInterface] ExitPlanMode approved, Store auto-synced");I(Y0)}),s=r$(()=>{H.addAssistantMessage("❌ 设置已取消"),H.addAssistantMessage("Blade 需要 API 配置才能正常工作。"),H.addAssistantMessage("您可以稍后运行 Blade 重新进入设置向导。"),I3(0)}),k=r$(()=>{O.closeModal()}),a=r$(async(Y0)=>{try{let j0=await w1.loadSession(Y0),H$=j0.map((o$,s$)=>({id:`restored-${Date.now()}-${s$}`,role:o$.role,content:typeof o$.content==="string"?o$.content:JSON.stringify(o$.content),timestamp:Date.now()-(j0.length-s$)*1000}));H.restoreSession(Y0,H$),O.closeModal()}catch(j0){n$.error("[BladeInterface] Failed to restore session:",j0),O.closeModal()}}),n=r$(()=>{if(Y.resume)B();else O.closeModal()}),U0=r$((Y0)=>{O.showModelEditWizard(Y0)}),M0=r$((Y0)=>{H.addAssistantMessage(`✅ 已添加模型配置: ${Y0.name},并已切换到该模型`),k()}),$$=r$((Y0)=>{H.addAssistantMessage(`✅ 已更新模型配置: ${Y0.name}`),k()});m4(()=>{if(V){_.setFocus("model-config-wizard");return}if(R.isVisible)_.setFocus("confirmation-prompt");else if(W==="sessionSelector")_.setFocus("session-selector");else if(W==="themeSelector")_.setFocus("theme-selector");else if(W==="modelSelector")_.setFocus("model-selector");else if(W==="modelAddWizard"||W==="modelEditWizard")_.setFocus("model-config-wizard");else if(W==="permissionsManager")_.setFocus("permissions-manager");else if(W==="agentsManager")_.setFocus("agents-manager");else if(W==="agentCreationWizard")_.setFocus("agent-creation-wizard");else if(W==="hooksManager")_.setFocus("hooks-manager");else if(W==="shortcuts")_.setFocus("main-input");else _.setFocus("main-input")},[V,R.isVisible,W,_.setFocus]),m4(()=>{if(!L||J.current)return;if(OQ().length>0){J.current=!0;return}J.current=!0,H.addAssistantMessage("请输入您的问题,我将为您提供帮助。")},[L]),m4(()=>{if(!K)return;if(q.current===K)return;if(q.current=K,G==="error")H.addAssistantMessage(`❌ 初始化失败: ${K}`);else H.addAssistantMessage(`❌ ${K}`),H.addAssistantMessage("请重新尝试设置,或检查文件权限")},[K,G,H.addAssistantMessage]);let j2=r$(async(Y0)=>{try{await N({displayText:Y0,text:Y0,images:[],parts:[{type:"text",text:Y0}]})}catch(j0){let H$=j0 instanceof Error?j0.message:"无法发送初始消息";H.addAssistantMessage(`❌ 初始消息发送失败:${H$}`)}});m4(()=>{let Y0=Y.initialMessage?.trim();if(!Y0||X.current||!L||V)return;X.current=!0,S(Y0),j2(Y0)},[Y.initialMessage,L,V,N,S]);let E$=r$(async(Y0)=>{try{await C0().setPermissionMode(Y0)}catch(j0){n$.error("❌ 权限模式初始化失败:",j0 instanceof Error?j0.message:j0)}});if(m4(()=>{let Y0=Y.permissionMode;if($)n$.debug("[Debug] permissionMode from CLI:",Y0),n$.debug("[Debug] current permissionMode:",z);if(!Y0||Y0===z)return;E$(Y0)},[Y.permissionMode,z]),D)return null;if(V)return h0(zY,{mode:"setup",onComplete:j,onCancel:s},void 0,!1,void 0,this);if($)n$.debug("[Debug] 渲染主界面,条件检查:",{confirmationVisible:R.isVisible,activeModal:W});let X0=W==="modelSelector",s0=F,w0=W==="modelAddWizard"?"add":W==="modelEditWizard"&&s0?"edit":null,X2=X0||Boolean(w0),p$=W==="agentsManager",I2=W==="agentCreationWizard",I1=W==="skillsManager",a8=W==="pluginsManager",vF=s0?{name:s0.name,provider:s0.provider,baseUrl:s0.baseUrl,apiKey:s0.apiKey,model:s0.model}:void 0,VY=R.isVisible&&R.details?R.details.type==="askUserQuestion"&&R.details.questions?h0(qF,{questions:R.details.questions,onComplete:(Y0)=>d({approved:!0,answers:Y0}),onCancel:()=>d({approved:!1})},void 0,!1,void 0,this):h0(QU,{details:R.details,onResponse:d},void 0,!1,void 0,this):W==="themeSelector"?h0(LF,{},void 0,!1,void 0,this):W==="permissionsManager"?h0(QF,{onClose:k},void 0,!1,void 0,this):W==="sessionSelector"?h0(KF,{sessions:U,onSelect:a,onCancel:n},void 0,!1,void 0,this):W==="hooksManager"?h0(JU,{onClose:k},void 0,!1,void 0,this):null,DY=Boolean(VY);return h0(Q4,{flexDirection:"column",width:"100%",overflow:"hidden",children:[VY,h0(Q4,{flexDirection:"column",display:DY?"none":"flex",children:[z==="spec"&&h0(FF,{},void 0,!1,void 0,this),h0(EU,{},void 0,!1,void 0,this),h0(zF,{},void 0,!1,void 0,this),h0(VU,{paused:DY},void 0,!1,void 0,this),h0(BU,{input:T.value,cursorPosition:T.cursorPosition,onChange:T.setValue,onChangeCursorPosition:T.setCursorPosition,onAddPasteMapping:T.addPasteMapping,onAddImagePasteMapping:T.addImagePasteMapping},void 0,!1,void 0,this),X0&&h0(Q4,{marginTop:1,paddingX:2,children:h0(tU,{onClose:k,onEdit:U0},void 0,!1,void 0,this)},void 0,!1,void 0,this),w0&&h0(Q4,{marginTop:1,paddingX:2,children:h0(zY,{mode:w0,modelId:s0?.id,initialConfig:w0==="edit"?vF:void 0,onComplete:w0==="edit"?$$:M0,onCancel:k},void 0,!1,void 0,this)},void 0,!1,void 0,this),p$&&h0(Q4,{marginTop:1,paddingX:2,children:h0(mW,{onComplete:k,onCancel:k},void 0,!1,void 0,this)},void 0,!1,void 0,this),I2&&h0(Q4,{marginTop:1,paddingX:2,children:h0(x8,{onComplete:k,onCancel:k},void 0,!1,void 0,this)},void 0,!1,void 0,this),I1&&h0(Q4,{marginTop:1,paddingX:2,children:h0(WF,{onComplete:k,onCancel:k},void 0,!1,void 0,this)},void 0,!1,void 0,this),a8&&h0(Q4,{marginTop:1,paddingX:2,children:h0(XF,{onComplete:k,onCancel:k},void 0,!1,void 0,this)},void 0,!1,void 0,this),h0(cW,{suggestions:r,selectedIndex:E,visible:A&&!X2},void 0,!1,void 0,this),h0(dW,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{Box as eA,Text as X4}from"ink";import $R from"react";import{jsxDEV as D2}from"react/jsx-dev-runtime";class k7 extends $R.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 D2(eA,{flexDirection:"column",padding:1,borderStyle:"round",borderColor:"red",children:[D2(X4,{color:"red",children:"\uD83D\uDCA5 应用发生错误"},void 0,!1,void 0,this),D2(X4,{children:" "},void 0,!1,void 0,this),D2(X4,{color:"red",children:this.state.error?.message},void 0,!1,void 0,this),D2(X4,{children:" "},void 0,!1,void 0,this),D2(X4,{color:"gray",children:"错误详情:"},void 0,!1,void 0,this),D2(X4,{color:"gray",children:this.state.error?.stack},void 0,!1,void 0,this),D2(X4,{children:" "},void 0,!1,void 0,this),D2(X4,{color:"yellow",children:"请重启应用或联系开发者"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return this.props.children}}import{Box as g4,Text as M2,useInput as ZR}from"ink";import{useState as LY}from"react";import{jsxDEV as x$}from"react/jsx-dev-runtime";var f7=[{key:"update",label:"Update now",description:`runs \`${yZ()}\``},{key:"skip",label:"Skip",description:""},{key:"skip_until_next",label:"Skip until next version",description:""}],bF=({versionInfo:$,onComplete:Z})=>{let[Y,Q]=LY(0),[X,J]=LY(!1),[q,G]=LY(null);ZR((W,U)=>{if(U.ctrl&&W==="c"){y4().shutdown("SIGINT",0);return}if(X||q)return;if(U.upArrow||W==="k")Q((F)=>F>0?F-1:f7.length-1);else if(U.downArrow||W==="j")Q((F)=>F<f7.length-1?F+1:0);else if(U.return)K(f7[Y].key);else if(W==="1")K("update");else if(W==="2")K("skip");else if(W==="3")K("skip_until_next")});let K=async(W)=>{switch(W){case"update":{J(!0);let U=await xK();G(U.message),setTimeout(()=>{y4().shutdown("SIGINT",0)},1500);break}case"skip":Z();break;case"skip_until_next":if($.latestVersion)await hK($.latestVersion);Z();break}};if(q)return x$(g4,{flexDirection:"column",marginY:1,children:x$(M2,{children:q},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(X)return x$(g4,{flexDirection:"column",marginY:1,children:x$(M2,{color:"cyan",children:"Updating..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);return x$(g4,{flexDirection:"column",marginY:1,children:[x$(M2,{color:"yellow",bold:!0,children:["✨ Update available! ",x$(M2,{color:"gray",children:[$.currentVersion," ","→"," ",$.latestVersion]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),x$(g4,{marginTop:1,children:x$(M2,{color:"gray",children:["Release notes:"," ",x$(M2,{color:"cyan",underline:!0,children:$.releaseNotesUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),x$(g4,{flexDirection:"column",marginTop:1,children:f7.map((W,U)=>{let F=U===Y,O=F?"› ":" ",H=`${U+1}. `;return x$(g4,{children:x$(M2,{color:F?"cyan":void 0,children:[O,H,W.label,W.description&&x$(M2,{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),x$(g4,{marginTop:1,children:x$(M2,{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)};q4();function g3($){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 h7}from"react/jsx-dev-runtime";function QR($){let Z=iQ();if(!$.models)$.models=[];for(let Y of Z){let Q=$.models.findIndex((X)=>X.id===Y.id);if(Q>=0){if($.models[Q]=Y,$.debug)console.log(`[Debug] 已更新内置模型: ${Y.name}`)}else if($.models.unshift(Y),$.debug)console.log(`[Debug] 已添加内置模型: ${Y.name}`)}if(!$.currentModelId)$.currentModelId=lQ();if(J0().config.actions.setConfig($),$.debug)console.log("[Debug] 模型配置检查通过,准备就绪");K2().setInitializationStatus("ready")}var RF=($)=>{let[Z,Y]=NY(!1),[Q,X]=NY(null),[J,q]=NY(!1),G=AF(async()=>{let W=J0().config.config??d4,U=g7(W,$);if(QR(U),U.debug)console.error("[Debug] 运行时配置:",U);let F=U.theme;if(F&&u$.hasTheme(F)){if(u$.setTheme(F),$.debug)console.log(`✓ 已加载主题: ${F}`)}try{let O=Z$.loadFromStandardLocations();if($.debug&&O>0)console.log(`✓ 已加载 ${O} 个 subagents: ${Z$.getAllNames().join(", ")}`)}catch(O){if($.debug)console.warn("⚠️ Subagents 加载失败:",g3(O))}try{let O=R0.getInstance();if(O.loadConfig(U.hooks||{}),$.debug&&U.hooks?.enabled)console.log("✓ Hooks 系统已启用");let H=J0(),_=H.session.sessionId;if(hY(_),O.isEnabled()){let z=H.config.config?.permissionMode||"default",w=!!$.resume,B=await O.executeSessionStartHooks({projectDir:process.cwd(),sessionId:_,permissionMode:z,isResume:w,resumeSessionId:typeof $.resume==="string"?$.resume:void 0});if(B.env){for(let[L,V]of Object.entries(B.env))process.env[L]=V;if($.debug)console.log("✓ SessionStart hooks 注入环境变量:",Object.keys(B.env).join(", "))}if(B.warning&&$.debug)console.warn("⚠️ SessionStart hooks 警告:",B.warning)}}catch(O){if($.debug)console.warn("⚠️ Hooks 初始化失败:",g3(O))}try{let O=await _4();if($.debug&&O.skills.length>0)console.log(`✓ 已加载 ${O.skills.length} 个 skills: ${O.skills.map((H)=>H.name).join(", ")}`);if(O.errors.length>0&&$.debug)for(let H of O.errors)console.warn(`⚠️ Skill 加载错误 (${H.path}): ${H.error}`)}catch(O){if($.debug)console.warn("⚠️ Skills 初始化失败:",g3(O))}try{let O=await yK(process.cwd());if($.debug&&O.commands.length>0)console.log(`✓ 已加载 ${O.commands.length} 个自定义命令: ${O.commands.map((H)=>H.name).join(", ")}`);if(O.errors.length>0&&$.debug)for(let H of O.errors)console.warn(`⚠️ 自定义命令加载错误 (${H.path}): ${H.error}`)}catch(O){if($.debug)console.warn("⚠️ 自定义命令初始化失败:",g3(O))}try{let H=await a$().initialize(process.cwd(),$.pluginDir||[]);if($.debug&&H.plugins.length>0)console.log(`✓ 已加载 ${H.plugins.length} 个插件: ${H.plugins.map((_)=>_.manifest.name).join(", ")}`);if(H.plugins.length>0){let _=await g2();if($.debug){let{totalCommands:z,totalSkills:w,totalAgents:B,totalMcpServers:L}=_;console.log(` ✓ 已集成: ${z} 命令, ${w} 技能, ${B} 代理, ${L} MCP 服务器`)}}if(H.errors.length>0&&$.debug)for(let _ of H.errors)console.warn(`⚠️ 插件加载错误 (${_.path}): ${_.error}`)}catch(O){if($.debug)console.warn("⚠️ 插件系统初始化失败:",g3(O))}uK(async()=>{y$.getInstance().killAll(),await w$.getInstance().disconnectAll(),R0.getInstance().cleanup()}),Y(!0)}),K=AF(async()=>{if($.versionCheckPromise){let W=await $.versionCheckPromise;if(W){X(W),q(!0);return}}await G()});if(YR(()=>{K()},[]),J&&Q)return h7(k7,{children:h7(bF,{versionInfo:Q,onComplete:()=>{q(!1),G()}},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(!Z)return null;return h7(k7,{children:h7(NF,{...$},void 0,!1,void 0,this)},void 0,!1,void 0,this)};var RY=yF(process.argv),IF=RY.indexOf("--debug");if(IF!==-1){let $=RY[IF+1],Z=$&&!$.startsWith("-")?$:!0;y1.setGlobalDebug(Z)}async function HR(){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);dK();let $=pK();if(await EK())return;if(RY.includes("--acp")){let{runAcpIntegration:Y}=await Promise.resolve().then(() => (jF(),MF));await Y();return}let Z=OR(yF(process.argv)).scriptName(J4.scriptName).usage(J4.usage).version(J4.version).locale(J4.locale).showHelpOnFail(J4.showHelpOnFail).demandCommand(0,"").recommendCommands().strict(J4.strict).parserConfiguration({"populate--":!0}).options(TY).middleware([_Q,zQ,BQ]).command(fQ).command(wQ).command(mK).command(LQ).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(`
|
|
2854
2854
|
Stack trace:`),console.error(Q.stack),process.exit(1);if(Y)console.error("❌ Invalid arguments:"),console.error(Y),console.error(`
|
|
2855
|
-
\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,
|
|
2855
|
+
\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,UR(FR.createElement(RF,J),{patchConsole:!0,exitOnCtrlC:!1,alternateBuffer:!1})});try{await Z.parse()}catch(Y){console.error("❌ Parse error:",Y),process.exit(1)}}if(A$.main==A$.module)HR().catch(console.error);export{HR as main};
|