blade-code 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/blade.js +99 -99
  2. package/package.json +2 -2
package/dist/blade.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{createRequire as fF}from"node:module";var SF=Object.defineProperty;var kF=($,Z)=>{for(var Y in Z)SF($,Y,{get:Z[Y],enumerable:!0,configurable:!0,set:(Q)=>Z[Y]=()=>Q})};var R=($,Z)=>()=>($&&(Z=$($=0)),Z);var H$=fF(import.meta.url);var q3;var FQ=R(()=>{q3={name:"blade-code",version:"0.2.4",private:!1,description:"🗡️ Blade Code - 智能代码助手命令行工具",type:"module",bin:{blade:"dist/blade.js"},files:["dist","vendor/ripgrep/**","README.md"],scripts:{dev:"bun --watch src/blade.tsx","dev:serve":"bun --watch src/blade.tsx serve --port 4097",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:e2e":"node scripts/test.js e2e","test:performance":"node scripts/test.js performance","test:snapshot":"node scripts/test.js snapshot","test:security":"node scripts/test.js security","test:coverage":"node scripts/test.js all --coverage","test:watch":"vitest --watch --config vitest.config.ts","test:update-snapshots":"node scripts/test.js snapshot --update",lint:"biome lint src tests","lint:fix":"biome lint --write src tests","type-check":"tsc --noEmit",release:"node scripts/release.js","release:dry":"node scripts/release.js --dry-run","release:major":"node scripts/release.js --major","release:minor":"node scripts/release.js --minor","release:patch":"node scripts/release.js --patch"},keywords:["cli","blade","ai","assistant","agent","llm"],author:"echoVic",license:"MIT",engines:{node:">=20.0.0"},optionalDependencies:{"@vscode/ripgrep":"^1.17.0","bun-pty":"^0.4.8","node-pty":"1.0.0"},dependencies:{"@agentclientprotocol/sdk":"^0.12.0","@ai-sdk/anthropic":"^3.0.7","@ai-sdk/azure":"^3.0.5","@ai-sdk/deepseek":"^2.0.4","@ai-sdk/google":"^3.0.4","@ai-sdk/openai-compatible":"^2.0.4","@inkjs/ui":"^2.0.0","@modelcontextprotocol/sdk":"^1.17.4",ahooks:"^3.9.6",ai:"^6.0.39","ansi-escapes":"^7.2.0","async-mutex":"^0.5.0",axios:"^1.12.2",chalk:"^5.4.1",diff:"^8.0.2","fast-glob":"^3.3.3","fuse.js":"^7.1.0","gray-matter":"^4.0.3",hono:"^4.7.10",ink:"npm:@jrichman/ink@6.4.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",open:"^10.1.2",openai:"^6.2.0",picomatch:"^4.0.3",react:"^19.1.1","react-dom":"^19.1.1",semver:"^7.7.3","string-width":"^8.1.0",undici:"^7.16.0","write-file-atomic":"^7.0.0",ws:"^8.18.0",yaml:"^2.8.1",yargs:"^18.0.0",zod:"^3.24.2","zod-to-json-schema":"^3.24.6",zustand:"^5.0.9"},devDependencies:{"@biomejs/biome":"^2.2.4","@types/bun":"^1.3.4","@types/json-schema":"^7.0.15","@types/lodash-es":"^4.17.12","@types/node":"^22.15.24","@types/picomatch":"^4.0.2","@types/react":"^19.1.1","@types/react-dom":"^19.1.1","@types/semver":"^7.7.1","@types/write-file-atomic":"^4.0.3","@types/ws":"^8.5.12","@types/yargs":"^17.0.33","@vitest/coverage-v8":"^3.0.0",jsdom:"^26.0.0",typescript:"^5.9.2",vitest:"^3.0.0"}}});function Z1(){return q3.version}function HQ(){return q3.name}function _Q(){return q3.description}function zQ(){return`v${q3.version} © 2025 Blade Code`}var x2=R(()=>{FQ()});var U$=()=>{};var O8;var w5=R(()=>{U$();O8={currentModelId:"",models:[],temperature:0,maxContextTokens:128000,maxOutputTokens:void 0,stream:!0,topP:0.9,topK:50,timeout:180000,theme:"dracula",uiTheme:"system",language:"zh-CN",fontSize:14,autoSaveSessions:!0,notifyBuild:!0,notifyErrors:!1,notifySounds:!1,privacyTelemetry:!1,privacyCrash:!0,debug:!1,mcpEnabled:!1,mcpServers:{},permissions:{allow:["Bash(pwd)","Bash(which *)","Bash(whoami)","Bash(hostname)","Bash(uname *)","Bash(date)","Bash(echo *)","Bash(ls *)","Bash(tree *)","Bash(git status)","Bash(git log *)","Bash(git diff *)","Bash(git branch *)","Bash(git show *)","Bash(git remote *)","Bash(npm list *)","Bash(npm view *)","Bash(npm outdated *)","Bash(pnpm list *)","Bash(yarn list *)","Bash(pip list *)","Bash(pip show *)"],ask:["Bash(curl *)","Bash(wget *)","Bash(aria2c *)","Bash(axel *)","Bash(rm -rf *)","Bash(rm -r *)","Bash(rm --recursive *)","Bash(nc *)","Bash(netcat *)","Bash(telnet *)","Bash(ncat *)"],deny:["Read(./.env)","Read(./.env.*)","Bash(rm -rf /)","Bash(rm -rf /*)","Bash(sudo *)","Bash(chmod 777 *)","Bash(bash *)","Bash(sh *)","Bash(zsh *)","Bash(fish *)","Bash(dash *)","Bash(eval *)","Bash(source *)","Bash(mkfs *)","Bash(fdisk *)","Bash(dd *)","Bash(format *)","Bash(parted *)","Bash(open http*)","Bash(open https*)","Bash(xdg-open http*)","Bash(xdg-open https*)"]},permissionMode:"default",hooks:{enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,PreToolUse:[],PostToolUse:[],PostToolUseFailure:[],PermissionRequest:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]},env:{},disableAllHooks:!1,maxTurns:-1}});import{promises as wQ}from"fs";import{merge as LQ}from"lodash-es";import NQ from"os";import K3 from"path";class l${static instance=null;constructor(){}static getInstance(){if(!l$.instance)l$.instance=new l$;return l$.instance}static resetInstance(){l$.instance=null}async initialize(){try{let $=await this.loadConfigFiles(),Z=await this.loadSettingsFiles(),Y={...O8,...$,...Z};if(this.resolveEnvInterpolation(Y),Y.debug)console.log("[ConfigManager] Configuration loaded successfully");return Y}catch($){return console.error("[ConfigManager] Failed to initialize:",$),O8}}async loadConfigFiles(){let $=K3.join(NQ.homedir(),".blade","config.json"),Z=K3.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 $=K3.join(NQ.homedir(),".blade","settings.json"),Z=K3.join(process.cwd(),".blade","settings.json"),Y=K3.join(process.cwd(),".blade","settings.local.json"),Q={},X=await this.loadJsonFile($);if(X)Q=this.mergeSettings(Q,X);let J=await this.loadJsonFile(Z);if(J)Q=this.mergeSettings(Q,J);let G=await this.loadJsonFile(Y);if(G)Q=this.mergeSettings(Q,G);return Q}mergeSettings($,Z){let Y=JSON.parse(JSON.stringify($));if(Z.permissions){if(!Y.permissions)Y.permissions={allow:[],ask:[],deny:[]};if(Z.permissions.allow){let Q=[...Y.permissions.allow||[],...Z.permissions.allow];Y.permissions.allow=Array.from(new Set(Q))}if(Z.permissions.ask){let Q=[...Y.permissions.ask||[],...Z.permissions.ask];Y.permissions.ask=Array.from(new Set(Q))}if(Z.permissions.deny){let Q=[...Y.permissions.deny||[],...Z.permissions.deny];Y.permissions.deny=Array.from(new Set(Q))}}if(Z.hooks)Y.hooks=LQ({},Y.hooks,Z.hooks);if(Z.env)Y.env=LQ({},Y.env,Z.env);if(Z.mcpServers)Y.mcpServers={...Y.mcpServers||{},...Z.mcpServers};if(Z.disableAllHooks!==void 0)Y.disableAllHooks=Z.disableAllHooks;if(Z.permissionMode!==void 0)Y.permissionMode=Z.permissionMode;if(Z.maxTurns!==void 0)Y.maxTurns=Z.maxTurns;return Y}resolveEnvInterpolation($){let Z=/\$\{?([A-Z_][A-Z0-9_]*)(:-([^}]+))?\}?/g,Y=(Q)=>{if(typeof Q==="string")return Q.replace(Z,(X,J,G,q)=>{return process.env[J]||q||X});return Q};for(let[Q,X]of Object.entries($))if(typeof X==="string")$[Q]=Y(X)}async loadJsonFile($){try{if(await this.fileExists($)){let Z=await wQ.readFile($,"utf-8");return JSON.parse(Z)}}catch(Z){console.warn(`[ConfigManager] Failed to load ${$}:`,Z)}return null}async fileExists($){try{return await wQ.access($),!0}catch{return!1}}validateConfig($){let Z=[];if(!$.models||$.models.length===0)Z.push("没有可用的模型配置");if($.models&&$.models.length>0){if(!$.currentModelId)Z.push("未设置当前模型 ID");else if(!$.models.find((Q)=>Q.id===$.currentModelId))Z.push("当前模型 ID 无效")}if(Z.length>0)throw Error(`配置验证失败:
2
+ import{createRequire as fF}from"node:module";var SF=Object.defineProperty;var kF=($,Z)=>{for(var Y in Z)SF($,Y,{get:Z[Y],enumerable:!0,configurable:!0,set:(Q)=>Z[Y]=()=>Q})};var R=($,Z)=>()=>($&&(Z=$($=0)),Z);var H$=fF(import.meta.url);var q3;var FQ=R(()=>{q3={name:"blade-code",version:"0.2.5",private:!1,description:"🗡️ Blade Code - 智能代码助手命令行工具",type:"module",bin:{blade:"dist/blade.js"},files:["dist","vendor/ripgrep/**","README.md"],scripts:{dev:"bun --watch src/blade.tsx","dev:serve":"bun --watch src/blade.tsx serve --port 4097",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:e2e":"node scripts/test.js e2e","test:performance":"node scripts/test.js performance","test:snapshot":"node scripts/test.js snapshot","test:security":"node scripts/test.js security","test:coverage":"node scripts/test.js all --coverage","test:watch":"vitest --watch --config vitest.config.ts","test:update-snapshots":"node scripts/test.js snapshot --update",lint:"biome lint src tests","lint:fix":"biome lint --write src tests","type-check":"tsc --noEmit",release:"node scripts/release.js","release:dry":"node scripts/release.js --dry-run","release:major":"node scripts/release.js --major","release:minor":"node scripts/release.js --minor","release:patch":"node scripts/release.js --patch"},keywords:["cli","blade","ai","assistant","agent","llm"],author:"echoVic",license:"MIT",engines:{node:">=20.0.0"},optionalDependencies:{"@vscode/ripgrep":"^1.17.0","bun-pty":"^0.4.8","node-pty":"1.0.0"},dependencies:{"@agentclientprotocol/sdk":"^0.12.0","@ai-sdk/anthropic":"^3.0.7","@ai-sdk/azure":"^3.0.5","@ai-sdk/deepseek":"^2.0.4","@ai-sdk/google":"^3.0.4","@ai-sdk/openai-compatible":"^2.0.4","@inkjs/ui":"^2.0.0","@modelcontextprotocol/sdk":"^1.17.4",ahooks:"^3.9.6",ai:"^6.0.39","ansi-escapes":"^7.2.0","async-mutex":"^0.5.0",axios:"^1.12.2",chalk:"^5.4.1",diff:"^8.0.2","fast-glob":"^3.3.3","fuse.js":"^7.1.0","gray-matter":"^4.0.3",hono:"^4.7.10",ink:"npm:@jrichman/ink@6.4.10","ink-big-text":"^2.0.0","ink-gradient":"^3.0.0","ink-select-input":"^6.2.0","ink-spinner":"^5.0.0","ink-text-input":"^6.0.0","js-tiktoken":"^1.0.21","lodash-es":"^4.17.21",lowlight:"^3.3.0","lru-cache":"^11.2.4",nanoid:"^5.1.6",open:"^10.1.2",openai:"^6.2.0",picomatch:"^4.0.3",react:"^19.1.1","react-dom":"^19.1.1",semver:"^7.7.3","string-width":"^8.1.0",undici:"^7.16.0","write-file-atomic":"^7.0.0",ws:"^8.18.0",yaml:"^2.8.1",yargs:"^18.0.0",zod:"^3.24.2","zod-to-json-schema":"^3.24.6",zustand:"^5.0.9"},devDependencies:{"@biomejs/biome":"^2.2.4","@types/bun":"^1.3.4","@types/json-schema":"^7.0.15","@types/lodash-es":"^4.17.12","@types/node":"^22.15.24","@types/picomatch":"^4.0.2","@types/react":"^19.1.1","@types/react-dom":"^19.1.1","@types/semver":"^7.7.1","@types/write-file-atomic":"^4.0.3","@types/ws":"^8.5.12","@types/yargs":"^17.0.33","@vitest/coverage-v8":"^3.0.0",jsdom:"^26.0.0",typescript:"^5.9.2",vitest:"^3.0.0"}}});function Z1(){return q3.version}function HQ(){return q3.name}function _Q(){return q3.description}function zQ(){return`v${q3.version} © 2025 Blade Code`}var x2=R(()=>{FQ()});var U$=()=>{};var O8;var w5=R(()=>{U$();O8={currentModelId:"",models:[],temperature:0,maxContextTokens:128000,maxOutputTokens:void 0,stream:!0,topP:0.9,topK:50,timeout:180000,theme:"dracula",uiTheme:"system",language:"zh-CN",fontSize:14,autoSaveSessions:!0,notifyBuild:!0,notifyErrors:!1,notifySounds:!1,privacyTelemetry:!1,privacyCrash:!0,debug:!1,mcpEnabled:!1,mcpServers:{},permissions:{allow:["Bash(pwd)","Bash(which *)","Bash(whoami)","Bash(hostname)","Bash(uname *)","Bash(date)","Bash(echo *)","Bash(ls *)","Bash(tree *)","Bash(git status)","Bash(git log *)","Bash(git diff *)","Bash(git branch *)","Bash(git show *)","Bash(git remote *)","Bash(npm list *)","Bash(npm view *)","Bash(npm outdated *)","Bash(pnpm list *)","Bash(yarn list *)","Bash(pip list *)","Bash(pip show *)"],ask:["Bash(curl *)","Bash(wget *)","Bash(aria2c *)","Bash(axel *)","Bash(rm -rf *)","Bash(rm -r *)","Bash(rm --recursive *)","Bash(nc *)","Bash(netcat *)","Bash(telnet *)","Bash(ncat *)"],deny:["Read(./.env)","Read(./.env.*)","Bash(rm -rf /)","Bash(rm -rf /*)","Bash(sudo *)","Bash(chmod 777 *)","Bash(bash *)","Bash(sh *)","Bash(zsh *)","Bash(fish *)","Bash(dash *)","Bash(eval *)","Bash(source *)","Bash(mkfs *)","Bash(fdisk *)","Bash(dd *)","Bash(format *)","Bash(parted *)","Bash(open http*)","Bash(open https*)","Bash(xdg-open http*)","Bash(xdg-open https*)"]},permissionMode:"default",hooks:{enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,PreToolUse:[],PostToolUse:[],PostToolUseFailure:[],PermissionRequest:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]},env:{},disableAllHooks:!1,maxTurns:-1}});import{promises as wQ}from"fs";import{merge as LQ}from"lodash-es";import NQ from"os";import K3 from"path";class l${static instance=null;constructor(){}static getInstance(){if(!l$.instance)l$.instance=new l$;return l$.instance}static resetInstance(){l$.instance=null}async initialize(){try{let $=await this.loadConfigFiles(),Z=await this.loadSettingsFiles(),Y={...O8,...$,...Z};if(this.resolveEnvInterpolation(Y),Y.debug)console.log("[ConfigManager] Configuration loaded successfully");return Y}catch($){return console.error("[ConfigManager] Failed to initialize:",$),O8}}async loadConfigFiles(){let $=K3.join(NQ.homedir(),".blade","config.json"),Z=K3.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 $=K3.join(NQ.homedir(),".blade","settings.json"),Z=K3.join(process.cwd(),".blade","settings.json"),Y=K3.join(process.cwd(),".blade","settings.local.json"),Q={},X=await this.loadJsonFile($);if(X)Q=this.mergeSettings(Q,X);let J=await this.loadJsonFile(Z);if(J)Q=this.mergeSettings(Q,J);let G=await this.loadJsonFile(Y);if(G)Q=this.mergeSettings(Q,G);return Q}mergeSettings($,Z){let Y=JSON.parse(JSON.stringify($));if(Z.permissions){if(!Y.permissions)Y.permissions={allow:[],ask:[],deny:[]};if(Z.permissions.allow){let Q=[...Y.permissions.allow||[],...Z.permissions.allow];Y.permissions.allow=Array.from(new Set(Q))}if(Z.permissions.ask){let Q=[...Y.permissions.ask||[],...Z.permissions.ask];Y.permissions.ask=Array.from(new Set(Q))}if(Z.permissions.deny){let Q=[...Y.permissions.deny||[],...Z.permissions.deny];Y.permissions.deny=Array.from(new Set(Q))}}if(Z.hooks)Y.hooks=LQ({},Y.hooks,Z.hooks);if(Z.env)Y.env=LQ({},Y.env,Z.env);if(Z.mcpServers)Y.mcpServers={...Y.mcpServers||{},...Z.mcpServers};if(Z.disableAllHooks!==void 0)Y.disableAllHooks=Z.disableAllHooks;if(Z.permissionMode!==void 0)Y.permissionMode=Z.permissionMode;if(Z.maxTurns!==void 0)Y.maxTurns=Z.maxTurns;return Y}resolveEnvInterpolation($){let Z=/\$\{?([A-Z_][A-Z0-9_]*)(:-([^}]+))?\}?/g,Y=(Q)=>{if(typeof Q==="string")return Q.replace(Z,(X,J,G,q)=>{return process.env[J]||q||X});return Q};for(let[Q,X]of Object.entries($))if(typeof X==="string")$[Q]=Y(X)}async loadJsonFile($){try{if(await this.fileExists($)){let Z=await wQ.readFile($,"utf-8");return JSON.parse(Z)}}catch(Z){console.warn(`[ConfigManager] Failed to load ${$}:`,Z)}return null}async fileExists($){try{return await wQ.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
 
@@ -23,7 +23,7 @@ ${Z.map((Y)=>` - ${Y}`).join(`
23
23
  ]
24
24
  }
25
25
  `)}}function L5($,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 AQ=R(()=>{w5();U$()});import{appendFileSync as xF,existsSync as pF,mkdirSync as mF,readdirSync as gF,statSync as VQ,unlinkSync as uF}from"node:fs";import dF from"node:os";import A5 from"node:path";function MQ($){if(N5!==$)N5=$}async function DQ(){}function cF(){if(RQ)return bQ;RQ=!0;try{let $=A5.join(dF.homedir(),".blade","logs");if(!pF($))mF($,{recursive:!0,mode:493});if(VQ($).uid===0&&process.getuid&&process.getuid()!==0)return console.error(""),console.error("❌ 权限错误:~/.blade/logs 目录属于 root 用户"),console.error(""),console.error("这通常是因为您曾经使用 sudo 运行过 blade。"),console.error(""),console.error("解决方法:"),console.error(" sudo chown -R $USER:$USER ~/.blade/"),console.error(""),console.error("然后重新运行 blade(不要使用 sudo)"),console.error(""),null;return lF($,30),bQ=$,$}catch($){return console.error("[Logger] 无法创建日志目录:",$),null}}function lF($,Z){try{let Y=gF($),Q=Date.now(),X=Z*24*60*60*1000;for(let J of Y){if(!J.startsWith("blade-")||!J.endsWith(".log")&&!J.endsWith(".jsonl"))continue;let G=A5.join($,J);try{let q=VQ(G);if(Q-q.mtimeMs>X)uF(G)}catch(q){}}}catch(Y){}}function iF(){let $=cF();if(!$)return null;let Z=N5||"default";return A5.join($,`blade-${Z}.jsonl`)}function rF($,Z,Y){let Q=iF();if(!Q)return;try{let X={timestamp:new Date().toISOString(),level:b5[Z],category:$,message:Y};xF(Q,JSON.stringify(X)+`
26
- `)}catch(X){}}class m1{static globalDebugConfig=null;enabled;minLevel;category;constructor($={}){if($.enabled!==void 0)this.enabled=$.enabled;else if(m1.globalDebugConfig!==null)this.enabled=Boolean(m1.globalDebugConfig);else this.enabled=!1;this.minLevel=$.minLevel??0,this.category=$.category??"General"}static setGlobalDebug($){m1.globalDebugConfig=$}static clearGlobalDebug(){m1.globalDebugConfig=null}setEnabled($){this.enabled=$}parseDebugFilter($){if(!$)return{enabled:!1};if($===!0||$==="true"||$==="1")return{enabled:!0};let Z=String($).trim();if(!Z)return{enabled:!0};if(Z.startsWith("!"))return{enabled:!0,filter:{mode:"exclude",categories:Z.split(",").map((X)=>X.trim().replace(/^!/,"")).filter(Boolean)}};return{enabled:!0,filter:{mode:"include",categories:Z.split(",").map((Q)=>Q.trim()).filter(Boolean)}}}shouldLogCategory($){if(!$)return!0;let Z=this.category.toLowerCase();if($.mode==="include")return $.categories.some((Y)=>Z.includes(Y.toLowerCase()));return!$.categories.some((Y)=>Z.includes(Y.toLowerCase()))}shouldLogToConsole($){if(m1.globalDebugConfig!==null){let{enabled:Z,filter:Y}=this.parseDebugFilter(m1.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(rF(this.category,$,Y),this.shouldLogToConsole($)){let Q=b5[$],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 x($,Z){return new m1({...Z,category:$})}var b5,N5=null,bQ=null,RQ=!1,g0;var Q0=R(()=>{((X)=>{X[X.DEBUG=0]="DEBUG";X[X.INFO=1]="INFO";X[X.WARN=2]="WARN";X[X.ERROR=3]="ERROR"})(b5||={});g0=new m1({category:"General"})});import{Mutex as jQ}from"async-mutex";import{merge as aF}from"lodash-es";import{promises as L6}from"node:fs";import yQ from"node:os";import p2 from"node:path";import nF from"write-file-atomic";class N2{static instance=null;pendingUpdates=new Map;timers=new Map;fileLocks=new Map;lastSaveError=null;debounceDelay=300;constructor(){}static getInstance(){if(!N2.instance)N2.instance=new N2;return N2.instance}static resetInstance(){if(N2.instance)for(let $ of N2.instance.timers.values())clearTimeout($);N2.instance=null}async save($,Z={}){this.validatePersistableFields($);let Y=this.groupUpdatesByTarget($,Z.scope);if(Z.immediate)await Promise.all(Array.from(Y.entries()).map(([Q,X])=>this.flushTarget(Q,X)));else for(let[Q,X]of Y)this.scheduleSave(Q,X)}async flush(){for(let Z of this.timers.values())clearTimeout(Z);this.timers.clear();let $=Array.from(this.pendingUpdates.entries()).map(([Z,Y])=>this.flushTarget(Z,Y));this.pendingUpdates.clear(),await Promise.all($)}getLastSaveError(){return this.lastSaveError}clearLastSaveError(){this.lastSaveError=null}async appendPermissionRule($,Z={}){let Y=Z.scope??"local",Q=this.resolveFilePath("settings",Y);await this.flushTargetWithModifier(Q,(X)=>{let J=X.permissions??{allow:[],ask:[],deny:[]},G={allow:this.dedupeArray([...J.allow||[],$]),ask:J.ask||[],deny:J.deny||[]};return{...X,permissions:G}})}async appendLocalPermissionRule($,Z={}){await this.appendPermissionRule($,{...Z,scope:"local"})}validatePersistableFields($){for(let Z of Object.keys($)){let Y=F8[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=F8[Q];if(!J)continue;let G=Z??J.defaultScope,q=this.resolveFilePath(J.target,G);if(!Y.has(q))Y.set(q,{});Y.get(q)[Q]=X}return Y}resolveFilePath($,Z){if($==="config")return Z==="global"?p2.join(yQ.homedir(),".blade","config.json"):p2.join(process.cwd(),".blade","config.json");switch(Z){case"local":return p2.join(process.cwd(),".blade","settings.local.json");case"project":return p2.join(process.cwd(),".blade","settings.json");case"global":return p2.join(yQ.homedir(),".blade","settings.json");default:return p2.join(process.cwd(),".blade","settings.local.json")}}scheduleSave($,Z){let Y=this.pendingUpdates.get($)??{},Q=this.mergePendingUpdates(Y,Z);this.pendingUpdates.set($,Q);let X=this.timers.get($);if(X)clearTimeout(X);let J=setTimeout(async()=>{let G=this.pendingUpdates.get($);if(G){this.pendingUpdates.delete($),this.timers.delete($);try{await this.flushTarget($,G),this.lastSaveError=null}catch(q){let K=q instanceof Error?q:Error(String(q));this.lastSaveError=K,TQ.error(`Failed to save config to ${$}:`,K.message),TQ.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=F8[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 jQ,this.fileLocks.set($,Y);await Y.runExclusive(async()=>{await this.performWrite($,Z)})}async flushTargetWithModifier($,Z){let Y=this.fileLocks.get($);if(!Y)Y=new jQ,this.fileLocks.set($,Y);await Y.runExclusive(async()=>{await L6.mkdir(p2.dirname($),{recursive:!0,mode:493});let Q={};try{let J=await L6.readFile($,"utf-8");Q=JSON.parse(J)}catch{Q={}}let X=Z(Q);await this.atomicWrite($,X)})}async performWrite($,Z){await L6.mkdir(p2.dirname($),{recursive:!0,mode:493});let Y={};try{let X=await L6.readFile($,"utf-8");Y=JSON.parse(X)}catch{Y={}}let Q={...Y};for(let[X,J]of Object.entries(Z)){let G=F8[X];if(!G){Q[X]=J;continue}switch(G.mergeStrategy){case"replace":Q[X]=J;break;case"append-dedupe":this.applyAppendDedupe(Q,X,J);break;case"deep-merge":this.applyDeepMerge(Q,X,J);break}}await this.atomicWrite($,Q)}applyAppendDedupe($,Z,Y){if(Z==="permissions"&&typeof Y==="object"&&Y!==null){let Q=$[Z]??{allow:[],ask:[],deny:[]},X=Y;$[Z]={allow:this.dedupeArray([...Q.allow||[],...X.allow||[]]),ask:this.dedupeArray([...Q.ask||[],...X.ask||[]]),deny:this.dedupeArray([...Q.deny||[],...X.deny||[]])}}else if(Array.isArray(Y)){let Q=Array.isArray($[Z])?$[Z]:[];$[Z]=this.dedupeArray([...Q,...Y])}else $[Z]=Y}applyDeepMerge($,Z,Y){if(typeof Y==="object"&&Y!==null&&!Array.isArray(Y)){let Q=typeof $[Z]==="object"&&$[Z]!==null?$[Z]:{};$[Z]=aF({},Q,Y)}else $[Z]=Y}dedupeArray($){return Array.from(new Set($))}async atomicWrite($,Z){await nF($,JSON.stringify(Z,null,2),{mode:384,encoding:"utf-8"})}}function x$(){return N2.getInstance()}var TQ,F8,cM,lM;var EQ=R(()=>{Q0();TQ=x("Service"),F8={models:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},currentModelId:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},temperature:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},maxContextTokens:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},maxOutputTokens:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},timeout:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},theme:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},uiTheme:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},language:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},debug:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},fontSize:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},autoSaveSessions:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},notifyBuild:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},notifyErrors:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},notifySounds:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},privacyTelemetry:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},privacyCrash:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},permissionMode:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},permissions:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!0},hooks:{target:"settings",defaultScope:"local",mergeStrategy:"deep-merge",persistable:!0},env:{target:"settings",defaultScope:"local",mergeStrategy:"deep-merge",persistable:!0},disableAllHooks:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!0},maxTurns:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!0},mcpServers:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},stream:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},topP:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},topK:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},mcpEnabled:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},systemPrompt:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},appendSystemPrompt:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},initialMessage:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},resumeSessionId:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},forkSession:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},allowedTools:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},disallowedTools:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},mcpConfigPaths:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},strictMcpConfig:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},addDirs:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},outputFormat:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},inputFormat:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},print:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},includePartialMessages:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},replayUserMessages:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},agentsConfig:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},settingSources:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1}},cM=new Set(Object.entries(F8).filter(([$,Z])=>Z.persistable).map(([$])=>$)),lM=new Set(Object.entries(F8).filter(([$,Z])=>!Z.persistable).map(([$])=>$))});var H8=R(()=>{AQ();EQ();w5();U$()});var oF,sF,tF,eF,$H,ZH,YH,QH,XH,JH,GH,qH,KH,A2;var R5=R(()=>{oF={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)"}},sF={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)"}},tF={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)"}},eF={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)"}},$H={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)"}},ZH={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)"}},YH={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)"}},QH={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)"}},XH={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)"}},JH={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)"}},GH={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)"}},qH={name:"rose-pine",colors:{primary:"#9ccfd8",secondary:"#c4a7e7",accent:"#f6c177",success:"#31748f",warning:"#f6c177",error:"#eb6f92",info:"#9ccfd8",light:"#e0def4",dark:"#191724",muted:"#6e6a86",highlight:"#1f1d2e",text:{primary:"#e0def4",secondary:"#cecacd",muted:"#6e6a86",light:"#ffffff"},background:{primary:"#191724",secondary:"#1f1d2e",dark:"#12101a"},border:{light:"#1f1d2e",dark:"#000000"},syntax:{comment:"#6e6a86",string:"#9ccfd8",number:"#ea9a97",keyword:"#c4a7e7",function:"#31748f",variable:"#e0def4",operator:"#f6c177",type:"#9ccfd8",tag:"#eb6f92",attr:"#f6c177",default:"#e0def4"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(25, 23, 36, 0.2)",base:"0 1px 3px 0 rgba(25, 23, 36, 0.3), 0 1px 2px 0 rgba(25, 23, 36, 0.2)",lg:"0 10px 15px -3px rgba(25, 23, 36, 0.3), 0 4px 6px -2px rgba(25, 23, 36, 0.2)"}},KH={name:"kanagawa",colors:{primary:"#8ba4b0",secondary:"#a292a3",accent:"#c47fd5",success:"#76946a",warning:"#c0a36e",error:"#c34043",info:"#7e9cd8",light:"#dcd7ba",dark:"#1f1f28",muted:"#727169",highlight:"#2a2a37",text:{primary:"#dcd7ba",secondary:"#c8c093",muted:"#727169",light:"#ffffff"},background:{primary:"#1f1f28",secondary:"#2a2a37",dark:"#16161d"},border:{light:"#2a2a37",dark:"#000000"},syntax:{comment:"#727169",string:"#98bb6c",number:"#d27e99",keyword:"#957fb8",function:"#7e9cd8",variable:"#dcd7ba",operator:"#c0a36e",type:"#7aa89f",tag:"#c34043",attr:"#7fb4ca",default:"#dcd7ba"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(31, 31, 40, 0.2)",base:"0 1px 3px 0 rgba(31, 31, 40, 0.3), 0 1px 2px 0 rgba(31, 31, 40, 0.2)",lg:"0 10px 15px -3px rgba(31, 31, 40, 0.3), 0 4px 6px -2px rgba(31, 31, 40, 0.2)"}},A2=[{id:"ayu-dark",label:"Ayu Dark",theme:oF,tags:["dark","popular"]},{id:"dracula",label:"Dracula",theme:sF,tags:["dark","popular"]},{id:"monokai",label:"Monokai",theme:tF,tags:["dark","classic"]},{id:"nord",label:"Nord",theme:eF,tags:["dark","minimal"]},{id:"solarized-light",label:"Solarized Light",theme:$H,tags:["light"]},{id:"solarized-dark",label:"Solarized Dark",theme:ZH,tags:["dark"]},{id:"tokyo-night",label:"Tokyo Night",theme:YH,tags:["dark","popular"]},{id:"github",label:"GitHub",theme:QH,tags:["light","minimal"]},{id:"gruvbox",label:"Gruvbox",theme:XH,tags:["dark","warm"]},{id:"one-dark",label:"One Dark",theme:JH,tags:["dark","popular"]},{id:"catppuccin",label:"Catppuccin",theme:GH,tags:["dark","pastel"]},{id:"rose-pine",label:"Rose Pine",theme:qH,tags:["dark","elegant"]},{id:"kanagawa",label:"Kanagawa",theme:KH,tags:["dark","japanese"]}]});class vQ{currentTheme=V5;themes=new Map;constructor(){this.themes.set("default",V5),this.themes.set("dark",WH);for(let $ of A2)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 IQ,V5,WH,i$;var V4=R(()=>{R5();IQ={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"}},V5={name:"default",colors:IQ,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)"}},WH={...V5,name:"dark",colors:{...IQ,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"}}};i$=new vQ});var UH,M5=($)=>({...UH,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 PQ=R(()=>{UH={initializationStatus:"idle",initializationError:null,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null,todos:[],awaitingSecondCtrlC:!1,thinkingModeEnabled:!1,subagentProgress:null}});var OH,D5=($,Z)=>({...OH,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 CQ=R(()=>{OH={isProcessing:!1,abortController:null,pendingCommands:[]}});var FH,j5=($)=>({...FH,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 SQ=R(()=>{FH={config:null}});var HH,y5=($)=>({...HH,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 kQ=R(()=>{HH={currentFocus:"main-input",previousFocus:null}});function M4($){let Z=[],Y=$.split(/\r?\n/),Q=!1,X=[],J=null,G=0,q=!1,K=[],W=[],U=!1,O=[],F=!0;for(let H=0;H<Y.length;H++){let _=Y[H];if(U){if(_.match(E0.diffEnd)){try{let T=JSON.parse(O.join(`
26
+ `)}catch(X){}}class m1{static globalDebugConfig=null;enabled;minLevel;category;constructor($={}){if($.enabled!==void 0)this.enabled=$.enabled;else if(m1.globalDebugConfig!==null)this.enabled=Boolean(m1.globalDebugConfig);else this.enabled=!1;this.minLevel=$.minLevel??0,this.category=$.category??"General"}static setGlobalDebug($){m1.globalDebugConfig=$}static clearGlobalDebug(){m1.globalDebugConfig=null}setEnabled($){this.enabled=$}parseDebugFilter($){if(!$)return{enabled:!1};if($===!0||$==="true"||$==="1")return{enabled:!0};let Z=String($).trim();if(!Z)return{enabled:!0};if(Z.startsWith("!"))return{enabled:!0,filter:{mode:"exclude",categories:Z.split(",").map((X)=>X.trim().replace(/^!/,"")).filter(Boolean)}};return{enabled:!0,filter:{mode:"include",categories:Z.split(",").map((Q)=>Q.trim()).filter(Boolean)}}}shouldLogCategory($){if(!$)return!0;let Z=this.category.toLowerCase();if($.mode==="include")return $.categories.some((Y)=>Z.includes(Y.toLowerCase()));return!$.categories.some((Y)=>Z.includes(Y.toLowerCase()))}shouldLogToConsole($){if(m1.globalDebugConfig!==null){let{enabled:Z,filter:Y}=this.parseDebugFilter(m1.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(rF(this.category,$,Y),this.shouldLogToConsole($)){let Q=b5[$],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 x($,Z){return new m1({...Z,category:$})}var b5,N5=null,bQ=null,RQ=!1,g0;var Q0=R(()=>{((X)=>{X[X.DEBUG=0]="DEBUG";X[X.INFO=1]="INFO";X[X.WARN=2]="WARN";X[X.ERROR=3]="ERROR"})(b5||={});g0=new m1({category:"General"})});import{Mutex as jQ}from"async-mutex";import{merge as aF}from"lodash-es";import{promises as L7}from"node:fs";import yQ from"node:os";import p2 from"node:path";import nF from"write-file-atomic";class N2{static instance=null;pendingUpdates=new Map;timers=new Map;fileLocks=new Map;lastSaveError=null;debounceDelay=300;constructor(){}static getInstance(){if(!N2.instance)N2.instance=new N2;return N2.instance}static resetInstance(){if(N2.instance)for(let $ of N2.instance.timers.values())clearTimeout($);N2.instance=null}async save($,Z={}){this.validatePersistableFields($);let Y=this.groupUpdatesByTarget($,Z.scope);if(Z.immediate)await Promise.all(Array.from(Y.entries()).map(([Q,X])=>this.flushTarget(Q,X)));else for(let[Q,X]of Y)this.scheduleSave(Q,X)}async flush(){for(let Z of this.timers.values())clearTimeout(Z);this.timers.clear();let $=Array.from(this.pendingUpdates.entries()).map(([Z,Y])=>this.flushTarget(Z,Y));this.pendingUpdates.clear(),await Promise.all($)}getLastSaveError(){return this.lastSaveError}clearLastSaveError(){this.lastSaveError=null}async appendPermissionRule($,Z={}){let Y=Z.scope??"local",Q=this.resolveFilePath("settings",Y);await this.flushTargetWithModifier(Q,(X)=>{let J=X.permissions??{allow:[],ask:[],deny:[]},G={allow:this.dedupeArray([...J.allow||[],$]),ask:J.ask||[],deny:J.deny||[]};return{...X,permissions:G}})}async appendLocalPermissionRule($,Z={}){await this.appendPermissionRule($,{...Z,scope:"local"})}validatePersistableFields($){for(let Z of Object.keys($)){let Y=F8[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=F8[Q];if(!J)continue;let G=Z??J.defaultScope,q=this.resolveFilePath(J.target,G);if(!Y.has(q))Y.set(q,{});Y.get(q)[Q]=X}return Y}resolveFilePath($,Z){if($==="config")return Z==="global"?p2.join(yQ.homedir(),".blade","config.json"):p2.join(process.cwd(),".blade","config.json");switch(Z){case"local":return p2.join(process.cwd(),".blade","settings.local.json");case"project":return p2.join(process.cwd(),".blade","settings.json");case"global":return p2.join(yQ.homedir(),".blade","settings.json");default:return p2.join(process.cwd(),".blade","settings.local.json")}}scheduleSave($,Z){let Y=this.pendingUpdates.get($)??{},Q=this.mergePendingUpdates(Y,Z);this.pendingUpdates.set($,Q);let X=this.timers.get($);if(X)clearTimeout(X);let J=setTimeout(async()=>{let G=this.pendingUpdates.get($);if(G){this.pendingUpdates.delete($),this.timers.delete($);try{await this.flushTarget($,G),this.lastSaveError=null}catch(q){let K=q instanceof Error?q:Error(String(q));this.lastSaveError=K,TQ.error(`Failed to save config to ${$}:`,K.message),TQ.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=F8[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 jQ,this.fileLocks.set($,Y);await Y.runExclusive(async()=>{await this.performWrite($,Z)})}async flushTargetWithModifier($,Z){let Y=this.fileLocks.get($);if(!Y)Y=new jQ,this.fileLocks.set($,Y);await Y.runExclusive(async()=>{await L7.mkdir(p2.dirname($),{recursive:!0,mode:493});let Q={};try{let J=await L7.readFile($,"utf-8");Q=JSON.parse(J)}catch{Q={}}let X=Z(Q);await this.atomicWrite($,X)})}async performWrite($,Z){await L7.mkdir(p2.dirname($),{recursive:!0,mode:493});let Y={};try{let X=await L7.readFile($,"utf-8");Y=JSON.parse(X)}catch{Y={}}let Q={...Y};for(let[X,J]of Object.entries(Z)){let G=F8[X];if(!G){Q[X]=J;continue}switch(G.mergeStrategy){case"replace":Q[X]=J;break;case"append-dedupe":this.applyAppendDedupe(Q,X,J);break;case"deep-merge":this.applyDeepMerge(Q,X,J);break}}await this.atomicWrite($,Q)}applyAppendDedupe($,Z,Y){if(Z==="permissions"&&typeof Y==="object"&&Y!==null){let Q=$[Z]??{allow:[],ask:[],deny:[]},X=Y;$[Z]={allow:this.dedupeArray([...Q.allow||[],...X.allow||[]]),ask:this.dedupeArray([...Q.ask||[],...X.ask||[]]),deny:this.dedupeArray([...Q.deny||[],...X.deny||[]])}}else if(Array.isArray(Y)){let Q=Array.isArray($[Z])?$[Z]:[];$[Z]=this.dedupeArray([...Q,...Y])}else $[Z]=Y}applyDeepMerge($,Z,Y){if(typeof Y==="object"&&Y!==null&&!Array.isArray(Y)){let Q=typeof $[Z]==="object"&&$[Z]!==null?$[Z]:{};$[Z]=aF({},Q,Y)}else $[Z]=Y}dedupeArray($){return Array.from(new Set($))}async atomicWrite($,Z){await nF($,JSON.stringify(Z,null,2),{mode:384,encoding:"utf-8"})}}function x$(){return N2.getInstance()}var TQ,F8,cM,lM;var EQ=R(()=>{Q0();TQ=x("Service"),F8={models:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},currentModelId:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},temperature:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},maxContextTokens:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},maxOutputTokens:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},timeout:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},theme:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},uiTheme:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},language:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},debug:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},fontSize:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},autoSaveSessions:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},notifyBuild:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},notifyErrors:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},notifySounds:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},privacyTelemetry:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},privacyCrash:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},permissionMode:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},permissions:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!0},hooks:{target:"settings",defaultScope:"local",mergeStrategy:"deep-merge",persistable:!0},env:{target:"settings",defaultScope:"local",mergeStrategy:"deep-merge",persistable:!0},disableAllHooks:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!0},maxTurns:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!0},mcpServers:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},stream:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},topP:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},topK:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},mcpEnabled:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},systemPrompt:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},appendSystemPrompt:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},initialMessage:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},resumeSessionId:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},forkSession:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},allowedTools:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},disallowedTools:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},mcpConfigPaths:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},strictMcpConfig:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},addDirs:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},outputFormat:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},inputFormat:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},print:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},includePartialMessages:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},replayUserMessages:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},agentsConfig:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},settingSources:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1}},cM=new Set(Object.entries(F8).filter(([$,Z])=>Z.persistable).map(([$])=>$)),lM=new Set(Object.entries(F8).filter(([$,Z])=>!Z.persistable).map(([$])=>$))});var H8=R(()=>{AQ();EQ();w5();U$()});var oF,sF,tF,eF,$H,ZH,YH,QH,XH,JH,GH,qH,KH,A2;var R5=R(()=>{oF={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)"}},sF={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)"}},tF={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)"}},eF={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)"}},$H={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)"}},ZH={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)"}},YH={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)"}},QH={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)"}},XH={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)"}},JH={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)"}},GH={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)"}},qH={name:"rose-pine",colors:{primary:"#9ccfd8",secondary:"#c4a7e7",accent:"#f6c177",success:"#31748f",warning:"#f6c177",error:"#eb6f92",info:"#9ccfd8",light:"#e0def4",dark:"#191724",muted:"#6e6a86",highlight:"#1f1d2e",text:{primary:"#e0def4",secondary:"#cecacd",muted:"#6e6a86",light:"#ffffff"},background:{primary:"#191724",secondary:"#1f1d2e",dark:"#12101a"},border:{light:"#1f1d2e",dark:"#000000"},syntax:{comment:"#6e6a86",string:"#9ccfd8",number:"#ea9a97",keyword:"#c4a7e7",function:"#31748f",variable:"#e0def4",operator:"#f6c177",type:"#9ccfd8",tag:"#eb6f92",attr:"#f6c177",default:"#e0def4"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(25, 23, 36, 0.2)",base:"0 1px 3px 0 rgba(25, 23, 36, 0.3), 0 1px 2px 0 rgba(25, 23, 36, 0.2)",lg:"0 10px 15px -3px rgba(25, 23, 36, 0.3), 0 4px 6px -2px rgba(25, 23, 36, 0.2)"}},KH={name:"kanagawa",colors:{primary:"#8ba4b0",secondary:"#a292a3",accent:"#c47fd5",success:"#76946a",warning:"#c0a36e",error:"#c34043",info:"#7e9cd8",light:"#dcd7ba",dark:"#1f1f28",muted:"#727169",highlight:"#2a2a37",text:{primary:"#dcd7ba",secondary:"#c8c093",muted:"#727169",light:"#ffffff"},background:{primary:"#1f1f28",secondary:"#2a2a37",dark:"#16161d"},border:{light:"#2a2a37",dark:"#000000"},syntax:{comment:"#727169",string:"#98bb6c",number:"#d27e99",keyword:"#957fb8",function:"#7e9cd8",variable:"#dcd7ba",operator:"#c0a36e",type:"#7aa89f",tag:"#c34043",attr:"#7fb4ca",default:"#dcd7ba"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(31, 31, 40, 0.2)",base:"0 1px 3px 0 rgba(31, 31, 40, 0.3), 0 1px 2px 0 rgba(31, 31, 40, 0.2)",lg:"0 10px 15px -3px rgba(31, 31, 40, 0.3), 0 4px 6px -2px rgba(31, 31, 40, 0.2)"}},A2=[{id:"ayu-dark",label:"Ayu Dark",theme:oF,tags:["dark","popular"]},{id:"dracula",label:"Dracula",theme:sF,tags:["dark","popular"]},{id:"monokai",label:"Monokai",theme:tF,tags:["dark","classic"]},{id:"nord",label:"Nord",theme:eF,tags:["dark","minimal"]},{id:"solarized-light",label:"Solarized Light",theme:$H,tags:["light"]},{id:"solarized-dark",label:"Solarized Dark",theme:ZH,tags:["dark"]},{id:"tokyo-night",label:"Tokyo Night",theme:YH,tags:["dark","popular"]},{id:"github",label:"GitHub",theme:QH,tags:["light","minimal"]},{id:"gruvbox",label:"Gruvbox",theme:XH,tags:["dark","warm"]},{id:"one-dark",label:"One Dark",theme:JH,tags:["dark","popular"]},{id:"catppuccin",label:"Catppuccin",theme:GH,tags:["dark","pastel"]},{id:"rose-pine",label:"Rose Pine",theme:qH,tags:["dark","elegant"]},{id:"kanagawa",label:"Kanagawa",theme:KH,tags:["dark","japanese"]}]});class vQ{currentTheme=V5;themes=new Map;constructor(){this.themes.set("default",V5),this.themes.set("dark",WH);for(let $ of A2)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 IQ,V5,WH,i$;var V4=R(()=>{R5();IQ={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"}},V5={name:"default",colors:IQ,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)"}},WH={...V5,name:"dark",colors:{...IQ,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"}}};i$=new vQ});var UH,M5=($)=>({...UH,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 PQ=R(()=>{UH={initializationStatus:"idle",initializationError:null,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null,todos:[],awaitingSecondCtrlC:!1,thinkingModeEnabled:!1,subagentProgress:null}});var OH,D5=($,Z)=>({...OH,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 CQ=R(()=>{OH={isProcessing:!1,abortController:null,pendingCommands:[]}});var FH,j5=($)=>({...FH,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 SQ=R(()=>{FH={config:null}});var HH,y5=($)=>({...HH,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 kQ=R(()=>{HH={currentFocus:"main-input",previousFocus:null}});function M4($){let Z=[],Y=$.split(/\r?\n/),Q=!1,X=[],J=null,G=0,q=!1,K=[],W=[],U=!1,O=[],F=!0;for(let H=0;H<Y.length;H++){let _=Y[H];if(U){if(_.match(E0.diffEnd)){try{let T=JSON.parse(O.join(`
27
27
  `));Z.push({type:"diff",content:"",diffData:{patch:T.patch,startLine:T.startLine,matchLine:T.matchLine}})}catch(T){Z.push({type:"text",content:O.join(`
28
28
  `)})}U=!1,O=[],F=!1;continue}O.push(_);continue}if(_.match(E0.diffStart)){U=!0,O=[],F=!1;continue}if(Q){let T=_.match(E0.codeBlock),A=_.trim()==="```";if(T&&T[1])G++,X.push(_);else if(A)if(G>0)G--,X.push(_);else{let k=X.join(`
29
29
  `);if(J?.toLowerCase()==="markdown"||J?.toLowerCase()==="md"){let c=M4(k);Z.push(...c)}else Z.push({type:"code",content:k,language:J||void 0});Q=!1,X=[],J=null,G=0,F=!1}else X.push(_);continue}let z=_.match(E0.codeBlock);if(z){Q=!0,J=z[1]||null,G=0,F=!1;continue}let w=_.match(E0.table),B=_.match(E0.tableSeparator);if(w&&!q){if(H+1<Y.length){if(Y[H+1].match(E0.tableSeparator)){q=!0,K=w[1].split("|").map((A)=>A.trim()).filter((A)=>A.length>0),W=[],F=!1;continue}}}if(q&&B)continue;if(q&&w){let T=w[1].split("|").map((A)=>A.trim()).filter((A)=>A.length>0);while(T.length<K.length)T.push("");if(T.length>K.length)T.length=K.length;W.push(T);continue}if(q&&!w){if(K.length>0&&W.length>0)Z.push({type:"table",content:"",tableData:{headers:K,rows:W}});q=!1,K=[],W=[]}let L=_.match(E0.heading);if(L){Z.push({type:"heading",content:L[2],level:L[1].length}),F=!1;continue}let N=_.match(E0.ulItem);if(N){Z.push({type:"list",content:N[3],listType:"ul",marker:N[2],indentation:N[1].length}),F=!1;continue}let M=_.match(E0.olItem);if(M){Z.push({type:"list",content:M[3],listType:"ol",marker:M[2],indentation:M[1].length}),F=!1;continue}if(_.match(E0.hr)){Z.push({type:"hr",content:""}),F=!1;continue}if(_.trim().length===0){if(!F)Z.push({type:"empty",content:""}),F=!0;continue}let j=_.match(E0.commandMessage);if(j){Z.push({type:"command-message",content:j[1]}),F=!1;continue}Z.push({type:"text",content:_}),F=!1}if(Q){let H=X.join(`
@@ -33,7 +33,7 @@ ${Z.map((Y)=>` - ${Y}`).join(`
33
33
  `)})}Q.inDiff=!1,Q.diffContent=[],Q.lastLineEmpty=!1;return}Q.diffContent.push($);return}if($.match(E0.diffStart)){Q.inDiff=!0,Q.diffContent=[],Q.lastLineEmpty=!1;return}if(Q.inCodeBlock){let H=$.match(E0.codeBlock),_=$.trim()==="```";if(H&&H[1])Q.codeBlockDepth++,Q.codeBlockContent.push($);else if(_)if(Q.codeBlockDepth>0)Q.codeBlockDepth--,Q.codeBlockContent.push($);else xQ(Q,X);else Q.codeBlockContent.push($);return}let J=$.match(E0.codeBlock);if(J){Q.inCodeBlock=!0,Q.codeBlockLang=J[1]||null,Q.codeBlockDepth=0,Q.lastLineEmpty=!1;return}let G=$.match(E0.table),q=$.match(E0.tableSeparator);if(G&&!Q.inTable){Q.pendingTableHeader=$;return}if(Q.inTable&&q)return;if(Q.inTable&&G){let H=G[1].split("|").map((_)=>_.trim()).filter((_)=>_.length>0);while(H.length<Q.tableHeaders.length)H.push("");if(H.length>Q.tableHeaders.length)H.length=Q.tableHeaders.length;Q.tableRows.push(H);return}if(Q.inTable&&!G){if(hQ(Q,X),Y){E5($,Z,!1);return}}let K=$.match(E0.heading);if(K){X.push({type:"heading",content:K[2],level:K[1].length}),Q.lastLineEmpty=!1;return}let W=$.match(E0.ulItem);if(W){X.push({type:"list",content:W[3],listType:"ul",marker:W[2],indentation:W[1].length}),Q.lastLineEmpty=!1;return}let U=$.match(E0.olItem);if(U){X.push({type:"list",content:U[3],listType:"ol",marker:U[2],indentation:U[1].length}),Q.lastLineEmpty=!1;return}if($.match(E0.hr)){X.push({type:"hr",content:""}),Q.lastLineEmpty=!1;return}if($.trim().length===0){if(!Q.lastLineEmpty)X.push({type:"empty",content:""}),Q.lastLineEmpty=!0;return}let F=$.match(E0.commandMessage);if(F){X.push({type:"command-message",content:F[1]}),Q.lastLineEmpty=!1;return}X.push({type:"text",content:$}),Q.lastLineEmpty=!1}function I5($,Z){if(!$||!Z)return;let Y=zH($);if(Y.finalized)return;let Q=Y.pendingLine+Z,X=Q.split(`
34
34
  `),J=Q.endsWith(`
35
35
  `),G=J?X:X.slice(0,-1);Y.pendingLine=J?"":X[X.length-1]??"";for(let q of G)E5(fQ(q),Y)}function v5($){let Z=b2.get($);if(!Z||Z.finalized)return;if(Z.pendingLine)E5(fQ(Z.pendingLine),Z),Z.pendingLine="";if(Z.state.pendingTableHeader!==null)Z.blocks.push({type:"text",content:Z.state.pendingTableHeader}),Z.state.pendingTableHeader=null;if(Z.state.inCodeBlock)xQ(Z.state,Z.blocks);if(Z.state.inTable)hQ(Z.state,Z.blocks);if(Z.state.inDiff)Z.blocks.push({type:"text",content:Z.state.diffContent.join(`
36
- `)}),Z.state.inDiff=!1,Z.state.diffContent=[];while(Z.blocks.length>0&&Z.blocks[Z.blocks.length-1].type==="empty")Z.blocks.pop();Z.finalized=!0}function pQ($){let Z=b2.get($);if(!Z||!Z.finalized)return null;return Z.blocks}function P5($){let Z=b2.get($);if(!Z)return null;return Z.blocks}function BH($){let Z=b2.get($);if(!Z)return null;let Y=[],Q=Z.state;if(Q.inDiff)Y.push("<<<DIFF>>>"),Y.push(...Q.diffContent);else if(Q.inCodeBlock){let X=Q.codeBlockLang?`\`\`\`${Q.codeBlockLang}`:"```";Y.push(X),Y.push(...Q.codeBlockContent)}else if(Q.inTable){if(Q.tableHeaders.length>0){Y.push(`| ${Q.tableHeaders.join(" | ")} |`),Y.push(`| ${Q.tableHeaders.map(()=>"---").join(" | ")} |`);for(let X of Q.tableRows)Y.push(`| ${X.join(" | ")} |`)}}else if(Q.pendingTableHeader)Y.push(Q.pendingTableHeader);if(Z.pendingLine)Y.push(Z.pendingLine);return Y.length>0?Y:null}function mQ($){let Z=b2.get($);if(!Z)return null;let Y="text";if(Z.state.inDiff)Y="diff";else if(Z.state.inCodeBlock)Y="code";else if(Z.state.inTable||Z.state.pendingTableHeader)Y="table";let Q=BH($);if(!Q||Q.length===0)return null;return{lines:Q,mode:Y}}function gQ($){b2.delete($)}function N6(){b2.clear()}var b2;var W3=R(()=>{T5();b2=new Map});import{nanoid as wH}from"nanoid";var uQ=2000,cQ,dQ,C5=($,Z)=>({...dQ,actions:{addMessage:(Y)=>{$((Q)=>({session:{...Q.session,messages:[...Q.session.messages,Y],error:null}}))},addUserMessage:(Y)=>{let Q={id:`user-${Date.now()}-${Math.random()}`,role:"user",content:Y,timestamp:Date.now()};Z().session.actions.addMessage(Q)},addAssistantMessage:(Y,Q)=>{let X={id:`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:Y,timestamp:Date.now(),thinkingContent:Q};Z().session.actions.addMessage(X)},addAssistantMessageAndClearThinking:(Y)=>{let Q=Z().session.currentThinkingContent,X={id:`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:Y,timestamp:Date.now(),thinkingContent:Q||void 0};$((J)=>({session:{...J.session,messages:[...J.session.messages,X],currentThinkingContent:null,error:null}}))},addToolMessage:(Y,Q)=>{let X={id:`tool-${Date.now()}-${Math.random()}`,role:"tool",content:Y,timestamp:Date.now(),metadata:Q};Z().session.actions.addMessage(X)},setCompacting:(Y)=>{$((Q)=>({session:{...Q.session,isCompacting:Y}}))},setCommand:(Y)=>{$((Q)=>({session:{...Q.session,currentCommand:Y}}))},setError:(Y)=>{$((Q)=>({session:{...Q.session,error:Y}}))},clearMessages:()=>{N6(),$((Y)=>({session:{...Y.session,messages:[],error:null,clearCount:Y.session.clearCount+1}}))},resetSession:()=>{N6(),$((Y)=>({session:{...Y.session,...dQ,sessionId:Y.session.sessionId,isActive:!0}}))},restoreSession:(Y,Q)=>{N6(),$((X)=>({session:{...X.session,sessionId:Y,messages:Q,error:null,isActive:!0}}))},updateTokenUsage:(Y)=>{$((Q)=>({session:{...Q.session,tokenUsage:{...Q.session.tokenUsage,...Y}}}))},resetTokenUsage:()=>{$((Y)=>({session:{...Y.session,tokenUsage:{...cQ}}}))},setCurrentThinkingContent:(Y)=>{if(Z().session.currentThinkingContent===Y)return;$((Q)=>({session:{...Q.session,currentThinkingContent:Y}}))},appendThinkingContent:(Y)=>{$((Q)=>({session:{...Q.session,currentThinkingContent:(Q.session.currentThinkingContent||"")+Y}}))},setThinkingExpanded:(Y)=>{$((Q)=>({session:{...Q.session,thinkingExpanded:Y}}))},toggleThinkingExpanded:()=>{$((Y)=>({session:{...Y.session,thinkingExpanded:!Y.session.thinkingExpanded}}))},setHistoryExpanded:(Y)=>{$((Q)=>({session:{...Q.session,historyExpanded:Y}}))},toggleHistoryExpanded:()=>{$((Y)=>({session:{...Y.session,historyExpanded:!Y.session.historyExpanded}}))},setExpandedMessageCount:(Y)=>{$((Q)=>({session:{...Q.session,expandedMessageCount:Y}}))},incrementClearCount:()=>{$((Y)=>({session:{...Y.session,clearCount:Y.session.clearCount+1}}))},startStreamingAssistantMessage:()=>{let Y=`assistant-${Date.now()}-${Math.random()}`,Q={id:Y,role:"assistant",content:"",timestamp:Date.now()};return $((X)=>({session:{...X.session,messages:[...X.session.messages,Q],currentStreamingMessageId:Y,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,error:null}})),Y},appendAssistantContent:(Y)=>{let Q=Z().session.currentStreamingMessageId,X=Q??`assistant-${Date.now()}-${Math.random()}`;return $((J)=>{let G=(L)=>L.endsWith("\r")?L.slice(0,-1):L,q=Q?J.session.currentStreamingChunks:[],K=Q?J.session.currentStreamingLines:[],W=Q?J.session.currentStreamingTail:"",U=Q?J.session.currentStreamingLineCount:0,O=Q?J.session.currentStreamingVersion:0,H=(W+Y).split(`
36
+ `)}),Z.state.inDiff=!1,Z.state.diffContent=[];while(Z.blocks.length>0&&Z.blocks[Z.blocks.length-1].type==="empty")Z.blocks.pop();Z.finalized=!0}function pQ($){let Z=b2.get($);if(!Z||!Z.finalized)return null;return Z.blocks}function P5($){let Z=b2.get($);if(!Z)return null;return Z.blocks}function BH($){let Z=b2.get($);if(!Z)return null;let Y=[],Q=Z.state;if(Q.inDiff)Y.push("<<<DIFF>>>"),Y.push(...Q.diffContent);else if(Q.inCodeBlock){let X=Q.codeBlockLang?`\`\`\`${Q.codeBlockLang}`:"```";Y.push(X),Y.push(...Q.codeBlockContent)}else if(Q.inTable){if(Q.tableHeaders.length>0){Y.push(`| ${Q.tableHeaders.join(" | ")} |`),Y.push(`| ${Q.tableHeaders.map(()=>"---").join(" | ")} |`);for(let X of Q.tableRows)Y.push(`| ${X.join(" | ")} |`)}}else if(Q.pendingTableHeader)Y.push(Q.pendingTableHeader);if(Z.pendingLine)Y.push(Z.pendingLine);return Y.length>0?Y:null}function mQ($){let Z=b2.get($);if(!Z)return null;let Y="text";if(Z.state.inDiff)Y="diff";else if(Z.state.inCodeBlock)Y="code";else if(Z.state.inTable||Z.state.pendingTableHeader)Y="table";let Q=BH($);if(!Q||Q.length===0)return null;return{lines:Q,mode:Y}}function gQ($){b2.delete($)}function N7(){b2.clear()}var b2;var W3=R(()=>{T5();b2=new Map});import{nanoid as wH}from"nanoid";var uQ=2000,cQ,dQ,C5=($,Z)=>({...dQ,actions:{addMessage:(Y)=>{$((Q)=>({session:{...Q.session,messages:[...Q.session.messages,Y],error:null}}))},addUserMessage:(Y)=>{let Q={id:`user-${Date.now()}-${Math.random()}`,role:"user",content:Y,timestamp:Date.now()};Z().session.actions.addMessage(Q)},addAssistantMessage:(Y,Q)=>{let X={id:`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:Y,timestamp:Date.now(),thinkingContent:Q};Z().session.actions.addMessage(X)},addAssistantMessageAndClearThinking:(Y)=>{let Q=Z().session.currentThinkingContent,X={id:`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:Y,timestamp:Date.now(),thinkingContent:Q||void 0};$((J)=>({session:{...J.session,messages:[...J.session.messages,X],currentThinkingContent:null,error:null}}))},addToolMessage:(Y,Q)=>{let X={id:`tool-${Date.now()}-${Math.random()}`,role:"tool",content:Y,timestamp:Date.now(),metadata:Q};Z().session.actions.addMessage(X)},setCompacting:(Y)=>{$((Q)=>({session:{...Q.session,isCompacting:Y}}))},setCommand:(Y)=>{$((Q)=>({session:{...Q.session,currentCommand:Y}}))},setError:(Y)=>{$((Q)=>({session:{...Q.session,error:Y}}))},clearMessages:()=>{N7(),$((Y)=>({session:{...Y.session,messages:[],error:null,clearCount:Y.session.clearCount+1}}))},resetSession:()=>{N7(),$((Y)=>({session:{...Y.session,...dQ,sessionId:Y.session.sessionId,isActive:!0}}))},restoreSession:(Y,Q)=>{N7(),$((X)=>({session:{...X.session,sessionId:Y,messages:Q,error:null,isActive:!0}}))},updateTokenUsage:(Y)=>{$((Q)=>({session:{...Q.session,tokenUsage:{...Q.session.tokenUsage,...Y}}}))},resetTokenUsage:()=>{$((Y)=>({session:{...Y.session,tokenUsage:{...cQ}}}))},setCurrentThinkingContent:(Y)=>{if(Z().session.currentThinkingContent===Y)return;$((Q)=>({session:{...Q.session,currentThinkingContent:Y}}))},appendThinkingContent:(Y)=>{$((Q)=>({session:{...Q.session,currentThinkingContent:(Q.session.currentThinkingContent||"")+Y}}))},setThinkingExpanded:(Y)=>{$((Q)=>({session:{...Q.session,thinkingExpanded:Y}}))},toggleThinkingExpanded:()=>{$((Y)=>({session:{...Y.session,thinkingExpanded:!Y.session.thinkingExpanded}}))},setHistoryExpanded:(Y)=>{$((Q)=>({session:{...Q.session,historyExpanded:Y}}))},toggleHistoryExpanded:()=>{$((Y)=>({session:{...Y.session,historyExpanded:!Y.session.historyExpanded}}))},setExpandedMessageCount:(Y)=>{$((Q)=>({session:{...Q.session,expandedMessageCount:Y}}))},incrementClearCount:()=>{$((Y)=>({session:{...Y.session,clearCount:Y.session.clearCount+1}}))},startStreamingAssistantMessage:()=>{let Y=`assistant-${Date.now()}-${Math.random()}`,Q={id:Y,role:"assistant",content:"",timestamp:Date.now()};return $((X)=>({session:{...X.session,messages:[...X.session.messages,Q],currentStreamingMessageId:Y,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,error:null}})),Y},appendAssistantContent:(Y)=>{let Q=Z().session.currentStreamingMessageId,X=Q??`assistant-${Date.now()}-${Math.random()}`;return $((J)=>{let G=(L)=>L.endsWith("\r")?L.slice(0,-1):L,q=Q?J.session.currentStreamingChunks:[],K=Q?J.session.currentStreamingLines:[],W=Q?J.session.currentStreamingTail:"",U=Q?J.session.currentStreamingLineCount:0,O=Q?J.session.currentStreamingVersion:0,H=(W+Y).split(`
37
37
  `),_=H.slice(0,-1).map(G),z=G(H[H.length-1]??""),w=[...q,Y],B=K;if(_.length>0){if(B=[...K,..._],B.length>uQ){let L=B.length-uQ;B=B.slice(L)}}return{session:{...J.session,currentStreamingMessageId:X,currentStreamingChunks:w,currentStreamingLines:B,currentStreamingTail:z,currentStreamingLineCount:U+_.length,currentStreamingVersion:O+1,error:null}}}),X},finalizeStreamingMessage:(Y,Q)=>{$((X)=>{let J=X.session.currentStreamingMessageId,q=X.session.currentStreamingChunks.join("")+(Y||""),K=(X.session.currentThinkingContent||"")+(Q||"");if(q.length>0){let W={id:J||`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:q,timestamp:Date.now(),thinkingContent:K||void 0};return{session:{...X.session,messages:[...X.session.messages,W],currentStreamingMessageId:null,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,currentThinkingContent:null,finalizingStreamingMessageId:W.id}}}return{session:{...X.session,currentStreamingMessageId:null,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,currentThinkingContent:null,finalizingStreamingMessageId:null}}})},clearFinalizingStreamingMessageId:()=>{$((Y)=>({session:{...Y.session,finalizingStreamingMessageId:null}}))}}});var lQ=R(()=>{W3();cQ={inputTokens:0,outputTokens:0,totalTokens:0,maxContextTokens:200000},dQ={sessionId:wH(),messages:[],isCompacting:!1,currentCommand:null,error:null,isActive:!0,tokenUsage:{...cQ},currentThinkingContent:null,thinkingExpanded:!1,clearCount:0,historyExpanded:!1,expandedMessageCount:100,currentStreamingMessageId:null,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,finalizingStreamingMessageId:null}});var iQ,D4,j4,J2,I$,rQ;var g1=R(()=>{iQ={proposal:"proposal.md",spec:"spec.md",requirements:"requirements.md",design:"design.md",tasks:"tasks.md",meta:".meta.json"},D4={SPECS:"specs",CHANGES:"changes",ARCHIVE:"archive",STEERING:"steering",SPEC_DELTA:"specs"},j4={CONSTITUTION:"constitution.md",PRODUCT:"product.md",TECH:"tech.md",STRUCTURE:"structure.md"},J2={init:["requirements"],requirements:["design","tasks"],design:["tasks"],tasks:["implementation"],implementation:["done","tasks"],done:[]},I$={init:"初始化",requirements:"需求定义",design:"架构设计",tasks:"任务分解",implementation:"实现中",done:"已完成"},rQ={init:"proposal",requirements:"requirements",design:"design",tasks:"tasks",implementation:"tasks",done:null}});import{promises as v$}from"node:fs";import*as k0 from"node:path";import{fileURLToPath as LH}from"node:url";import{nanoid as NH}from"nanoid";var AH,bH,aQ,y4;var S5=R(()=>{g1();AH=LH(import.meta.url),bH=k0.dirname(AH),aQ=k0.join(bH,"templates");y4=class y4{workspaceRoot;bladeDir;constructor($){this.workspaceRoot=$,this.bladeDir=k0.join($,".blade")}getSpecsDir(){return k0.join(this.bladeDir,D4.SPECS)}getChangesDir(){return k0.join(this.bladeDir,D4.CHANGES)}getArchiveDir(){return k0.join(this.bladeDir,D4.ARCHIVE)}getSteeringDir(){return k0.join(this.bladeDir,D4.STEERING)}getChangePath($){return k0.join(this.getChangesDir(),$)}getChangeFilePath($,Z){return k0.join(this.getChangePath($),iQ[Z])}async initializeDirectories(){await v$.mkdir(this.getChangesDir(),{recursive:!0,mode:493})}async createChangeDir($){let Z=this.getChangePath($);return await v$.mkdir(Z,{recursive:!0,mode:493}),await v$.mkdir(k0.join(Z,D4.SPEC_DELTA),{recursive:!0,mode:493}),Z}async readFile($){try{return await v$.readFile($,"utf-8")}catch(Z){if(Z.code==="ENOENT")return null;throw Z}}async writeFile($,Z){let Y=k0.dirname($);await v$.mkdir(Y,{recursive:!0,mode:493}),await v$.writeFile($,Z,"utf-8")}async fileExists($){try{return await v$.access($),!0}catch{return!1}}async dirExists($){try{return(await v$.stat($)).isDirectory()}catch{return!1}}createMetadata($,Z){let Y=new Date().toISOString();return{id:NH(),name:$,description:Z,phase:"init",createdAt:Y,updatedAt:Y,tasks:[]}}async readMetadata($){let Z=this.getChangeFilePath($,"meta"),Y=await this.readFile(Z);if(!Y)return null;try{return JSON.parse(Y)}catch{return null}}async writeMetadata($,Z){let Y=this.getChangeFilePath($,"meta");Z.updatedAt=new Date().toISOString(),await this.writeFile(Y,JSON.stringify(Z,null,2))}async updatePhase($,Z){let Y=await this.readMetadata($);if(!Y)return null;return Y.phase=Z,await this.writeMetadata($,Y),Y}async readSpecFile($,Z){let Y=this.getChangeFilePath($,Z);return this.readFile(Y)}async writeSpecFile($,Z,Y){let Q=this.getChangeFilePath($,Z);await this.writeFile(Q,Y);let X=await this.readMetadata($);if(X)await this.writeMetadata($,X)}async getPhaseContent($,Z){let Y=rQ[Z];if(!Y)return null;return this.readSpecFile($,Y)}async readSteeringContext(){let $=this.getSteeringDir(),[Z,Y,Q,X]=await Promise.all([this.readFile(k0.join($,j4.CONSTITUTION)),this.readFile(k0.join($,j4.PRODUCT)),this.readFile(k0.join($,j4.TECH)),this.readFile(k0.join($,j4.STRUCTURE))]);return{constitution:Z||void 0,product:Y||void 0,tech:Q||void 0,structure:X||void 0}}async writeSteeringFile($,Z){let Y=k0.join(this.getSteeringDir(),j4[$]);await this.writeFile(Y,Z)}async hasSteeringDocs(){let $=this.getSteeringDir();if(!await this.dirExists($))return!1;return(await v$.readdir($)).length>0}async listActiveChanges(){let $=this.getChangesDir();if(!await this.dirExists($))return[];return(await v$.readdir($,{withFileTypes:!0})).filter((Y)=>Y.isDirectory()).map((Y)=>Y.name)}async listArchivedChanges(){let $=this.getArchiveDir();if(!await this.dirExists($))return[];return(await v$.readdir($,{withFileTypes:!0})).filter((Y)=>Y.isDirectory()).map((Y)=>Y.name)}async changeExists($){return this.dirExists(this.getChangePath($))}async archiveChange($){let Z=this.getChangePath($),Y=k0.join(this.getArchiveDir(),$);await v$.mkdir(k0.dirname(Y),{recursive:!0,mode:493}),await v$.rename(Z,Y)}async restoreChange($){let Z=k0.join(this.getArchiveDir(),$),Y=this.getChangePath($);await v$.rename(Z,Y)}async listSpecDomains(){let $=this.getSpecsDir();if(!await this.dirExists($))return[];return(await v$.readdir($,{withFileTypes:!0})).filter((Y)=>Y.isDirectory()).map((Y)=>Y.name)}async readAuthorativeSpec($){let Z=k0.join(this.getSpecsDir(),$,"spec.md");return this.readFile(Z)}async writeAuthorativeSpec($,Z){let Y=k0.join(this.getSpecsDir(),$,"spec.md");await this.writeFile(Y,Z)}async mergeSpecDeltas($){let Z=k0.join(this.getChangePath($),D4.SPEC_DELTA);if(!await this.dirExists(Z))return[];let Y=[],Q=await v$.readdir(Z,{withFileTypes:!0});for(let X of Q){if(!X.isDirectory())continue;let J=k0.join(Z,X.name,"spec.md"),G=await this.readFile(J);if(G){let q=await this.readAuthorativeSpec(X.name),K=q?`${q}
38
38
 
39
39
  ---
@@ -105,12 +105,12 @@ ${$.description.usageNotes.map((Q)=>`- ${Q}`).join(`
105
105
 
106
106
  Important:
107
107
  ${$.description.important.map((Q)=>`⚠️ ${Q}`).join(`
108
- `)}`;return{name:$.name,description:Y,parameters:Z}},getMetadata(){return{name:$.name,displayName:$.displayName,kind:$.kind,version:$.version||"1.0.0",category:$.category,tags:$.tags||[],description:$.description,schema:m5($.schema)}},build(Z){let Y=UX($.schema,Z);return new g5($.name,Y,$.execute)},async execute(Z,Y){return this.build(Z).execute(Y||new AbortController().signal)},extractSignatureContent:$.extractSignatureContent?(Z)=>$.extractSignatureContent(Z):void 0,abstractPermissionRule:$.abstractPermissionRule?(Z)=>$.abstractPermissionRule(Z):void 0}}var h0=R(()=>{R$();OX();FX()});import{z as V1}from"zod";function A6($,Z,Y,Q){let X;try{X=F3(Y.inputSchema)}catch(G){console.warn(`[createMcpTool] Schema 转换失败,使用降级 schema: ${Y.name}`,G),X=V1.any()}let J=Q||Y.name;return e({name:J,displayName:`${Z}: ${Y.name}`,kind:"execute",schema:X,description:{short:Y.description||`MCP Tool: ${Y.name}`,important:[`From MCP server: ${Z}`,"Executes external tools; user confirmation required"]},category:"MCP tool",tags:["mcp","external",Z],async execute(G,q){try{let K=await $.callTool(Y.name,G),W="",U="";if(K.content&&Array.isArray(K.content)){for(let O of K.content)if(O.type==="text"&&O.text)W+=O.text,U+=O.text;else if(O.type==="image")U+=`[图片: ${O.mimeType||"unknown"}]
108
+ `)}`;return{name:$.name,description:Y,parameters:Z}},getMetadata(){return{name:$.name,displayName:$.displayName,kind:$.kind,version:$.version||"1.0.0",category:$.category,tags:$.tags||[],description:$.description,schema:m5($.schema)}},build(Z){let Y=UX($.schema,Z);return new g5($.name,Y,$.execute)},async execute(Z,Y){return this.build(Z).execute(Y||new AbortController().signal)},extractSignatureContent:$.extractSignatureContent?(Z)=>$.extractSignatureContent(Z):void 0,abstractPermissionRule:$.abstractPermissionRule?(Z)=>$.abstractPermissionRule(Z):void 0}}var h0=R(()=>{R$();OX();FX()});import{z as V1}from"zod";function A7($,Z,Y,Q){let X;try{X=F3(Y.inputSchema)}catch(G){console.warn(`[createMcpTool] Schema 转换失败,使用降级 schema: ${Y.name}`,G),X=V1.any()}let J=Q||Y.name;return e({name:J,displayName:`${Z}: ${Y.name}`,kind:"execute",schema:X,description:{short:Y.description||`MCP Tool: ${Y.name}`,important:[`From MCP server: ${Z}`,"Executes external tools; user confirmation required"]},category:"MCP tool",tags:["mcp","external",Z],async execute(G,q){try{let K=await $.callTool(Y.name,G),W="",U="";if(K.content&&Array.isArray(K.content)){for(let O of K.content)if(O.type==="text"&&O.text)W+=O.text,U+=O.text;else if(O.type==="image")U+=`[图片: ${O.mimeType||"unknown"}]
109
109
  `,W+=`[image: ${O.mimeType||"unknown"}]
110
110
  `;else if(O.type==="resource")U+=`[资源: ${O.mimeType||"unknown"}]
111
111
  `,W+=`[resource: ${O.mimeType||"unknown"}]
112
112
  `}if(K.isError)return{success:!1,llmContent:W||"MCP tool execution failed",displayContent:`❌ ${U||"MCP工具执行失败"}`,error:{type:"execution_error",message:W||"MCP tool execution failed"}};return{success:!0,llmContent:W||"Execution succeeded",displayContent:`✅ MCP工具 ${Y.name} 执行成功
113
- ${U}`,metadata:{serverName:Z,toolName:Y.name,mcpResult:K}}}catch(K){return{success:!1,llmContent:`MCP tool execution failed: ${K.message}`,displayContent:`❌ ${K.message}`,error:{type:"execution_error",message:K.message}}}}})}function F3($){if($.type==="object"||$.properties){let Z={},Y=$.required||[];if($.properties){for(let[Q,X]of Object.entries($.properties))if(typeof X==="object"&&X!==null){let J=F3(X);if(!Y.includes(Q))J=J.optional();Z[Q]=J}}return V1.object(Z)}if($.type==="array"&&$.items){if(typeof $.items==="object"&&!Array.isArray($.items)&&$.items!==null)return V1.array(F3($.items));return V1.array(V1.any())}if($.type==="string"){let Z=V1.string();if($.minLength!==void 0)Z=Z.min($.minLength);if($.maxLength!==void 0)Z=Z.max($.maxLength);if($.pattern)Z=Z.regex(new RegExp($.pattern));if($.enum)return V1.enum($.enum);return Z}if($.type==="number"||$.type==="integer"){let Z=V1.number();if($.minimum!==void 0)Z=Z.min($.minimum);if($.maximum!==void 0)Z=Z.max($.maximum);return Z}if($.type==="boolean")return V1.boolean();if($.oneOf&&$.oneOf.length>0){let Z=$.oneOf.filter((Y)=>typeof Y==="object"&&Y!==null).map((Y)=>F3(Y));if(Z.length>=2)return V1.union(Z)}if($.anyOf&&$.anyOf.length>0){let Z=$.anyOf.filter((Y)=>typeof Y==="object"&&Y!==null).map((Y)=>F3(Y));if(Z.length>=2)return V1.union(Z)}return V1.any()}var HX=R(()=>{h0();j$()});import{promises as u5}from"fs";import vH from"os";import d5 from"path";class c5{tokenFilePath;constructor(){let $=vH.homedir(),Z=d5.join($,".blade");this.tokenFilePath=d5.join(Z,"mcp-oauth-tokens.json")}async ensureConfigDir(){let $=d5.dirname(this.tokenFilePath);try{await u5.mkdir($,{recursive:!0,mode:493})}catch{}}async loadAllCredentials(){let $=new Map;try{let Z=await u5.readFile(this.tokenFilePath,"utf-8"),Y=JSON.parse(Z);for(let Q of Y)$.set(Q.serverName,Q)}catch(Z){if(Z.code!=="ENOENT")console.warn("[OAuthTokenStorage] 加载令牌失败:",Z)}return $}async saveAllCredentials($){await this.ensureConfigDir();let Z=Array.from($.values());await u5.writeFile(this.tokenFilePath,JSON.stringify(Z,null,2),{mode:384})}async saveToken($,Z,Y,Q){let X=await this.loadAllCredentials(),J={serverName:$,token:Z,clientId:Y,tokenUrl:Q,updatedAt:Date.now()};X.set($,J),await this.saveAllCredentials(X)}async getCredentials($){return(await this.loadAllCredentials()).get($)||null}async deleteCredentials($){let Z=await this.loadAllCredentials();Z.delete($),await this.saveAllCredentials(Z)}async listServers(){let $=await this.loadAllCredentials();return Array.from($.keys())}isTokenExpired($){if(!$.expiresAt)return!1;let Z=300000;return Date.now()>=$.expiresAt-Z}}var _X=()=>{};import{spawn as PH}from"child_process";import*as _3 from"crypto";import*as wX from"http";import{URL as zX}from"url";class b6{tokenStorage;constructor($=new c5){this.tokenStorage=$}generatePKCEParams(){let $=_3.randomBytes(32).toString("base64url"),Z=_3.createHash("sha256").update($).digest("base64url"),Y=_3.randomBytes(16).toString("base64url");return{codeVerifier:$,codeChallenge:Z,state:Y}}buildAuthorizationUrl($,Z){let Y=$.redirectUri||`http://localhost:${H3}${l5}`,Q=new URLSearchParams({client_id:$.clientId,response_type:"code",redirect_uri:Y,state:Z.state,code_challenge:Z.codeChallenge,code_challenge_method:"S256"});if($.scopes&&$.scopes.length>0)Q.append("scope",$.scopes.join(" "));let X=new zX($.authorizationUrl);return Q.forEach((J,G)=>{X.searchParams.append(G,J)}),X.toString()}async startCallbackServer($){return new Promise((Z,Y)=>{let Q=wX.createServer((X,J)=>{try{let G=new zX(X.url,`http://localhost:${H3}`);if(G.pathname!==l5){J.writeHead(404),J.end("Not found");return}let q=G.searchParams.get("code"),K=G.searchParams.get("state"),W=G.searchParams.get("error");if(W){J.writeHead(BX,{"Content-Type":"text/html"}),J.end(`
113
+ ${U}`,metadata:{serverName:Z,toolName:Y.name,mcpResult:K}}}catch(K){return{success:!1,llmContent:`MCP tool execution failed: ${K.message}`,displayContent:`❌ ${K.message}`,error:{type:"execution_error",message:K.message}}}}})}function F3($){if($.type==="object"||$.properties){let Z={},Y=$.required||[];if($.properties){for(let[Q,X]of Object.entries($.properties))if(typeof X==="object"&&X!==null){let J=F3(X);if(!Y.includes(Q))J=J.optional();Z[Q]=J}}return V1.object(Z)}if($.type==="array"&&$.items){if(typeof $.items==="object"&&!Array.isArray($.items)&&$.items!==null)return V1.array(F3($.items));return V1.array(V1.any())}if($.type==="string"){let Z=V1.string();if($.minLength!==void 0)Z=Z.min($.minLength);if($.maxLength!==void 0)Z=Z.max($.maxLength);if($.pattern)Z=Z.regex(new RegExp($.pattern));if($.enum)return V1.enum($.enum);return Z}if($.type==="number"||$.type==="integer"){let Z=V1.number();if($.minimum!==void 0)Z=Z.min($.minimum);if($.maximum!==void 0)Z=Z.max($.maximum);return Z}if($.type==="boolean")return V1.boolean();if($.oneOf&&$.oneOf.length>0){let Z=$.oneOf.filter((Y)=>typeof Y==="object"&&Y!==null).map((Y)=>F3(Y));if(Z.length>=2)return V1.union(Z)}if($.anyOf&&$.anyOf.length>0){let Z=$.anyOf.filter((Y)=>typeof Y==="object"&&Y!==null).map((Y)=>F3(Y));if(Z.length>=2)return V1.union(Z)}return V1.any()}var HX=R(()=>{h0();j$()});import{promises as u5}from"fs";import vH from"os";import d5 from"path";class c5{tokenFilePath;constructor(){let $=vH.homedir(),Z=d5.join($,".blade");this.tokenFilePath=d5.join(Z,"mcp-oauth-tokens.json")}async ensureConfigDir(){let $=d5.dirname(this.tokenFilePath);try{await u5.mkdir($,{recursive:!0,mode:493})}catch{}}async loadAllCredentials(){let $=new Map;try{let Z=await u5.readFile(this.tokenFilePath,"utf-8"),Y=JSON.parse(Z);for(let Q of Y)$.set(Q.serverName,Q)}catch(Z){if(Z.code!=="ENOENT")console.warn("[OAuthTokenStorage] 加载令牌失败:",Z)}return $}async saveAllCredentials($){await this.ensureConfigDir();let Z=Array.from($.values());await u5.writeFile(this.tokenFilePath,JSON.stringify(Z,null,2),{mode:384})}async saveToken($,Z,Y,Q){let X=await this.loadAllCredentials(),J={serverName:$,token:Z,clientId:Y,tokenUrl:Q,updatedAt:Date.now()};X.set($,J),await this.saveAllCredentials(X)}async getCredentials($){return(await this.loadAllCredentials()).get($)||null}async deleteCredentials($){let Z=await this.loadAllCredentials();Z.delete($),await this.saveAllCredentials(Z)}async listServers(){let $=await this.loadAllCredentials();return Array.from($.keys())}isTokenExpired($){if(!$.expiresAt)return!1;let Z=300000;return Date.now()>=$.expiresAt-Z}}var _X=()=>{};import{spawn as PH}from"child_process";import*as _3 from"crypto";import*as wX from"http";import{URL as zX}from"url";class b7{tokenStorage;constructor($=new c5){this.tokenStorage=$}generatePKCEParams(){let $=_3.randomBytes(32).toString("base64url"),Z=_3.createHash("sha256").update($).digest("base64url"),Y=_3.randomBytes(16).toString("base64url");return{codeVerifier:$,codeChallenge:Z,state:Y}}buildAuthorizationUrl($,Z){let Y=$.redirectUri||`http://localhost:${H3}${l5}`,Q=new URLSearchParams({client_id:$.clientId,response_type:"code",redirect_uri:Y,state:Z.state,code_challenge:Z.codeChallenge,code_challenge_method:"S256"});if($.scopes&&$.scopes.length>0)Q.append("scope",$.scopes.join(" "));let X=new zX($.authorizationUrl);return Q.forEach((J,G)=>{X.searchParams.append(G,J)}),X.toString()}async startCallbackServer($){return new Promise((Z,Y)=>{let Q=wX.createServer((X,J)=>{try{let G=new zX(X.url,`http://localhost:${H3}`);if(G.pathname!==l5){J.writeHead(404),J.end("Not found");return}let q=G.searchParams.get("code"),K=G.searchParams.get("state"),W=G.searchParams.get("error");if(W){J.writeHead(BX,{"Content-Type":"text/html"}),J.end(`
114
114
  <html>
115
115
  <body>
116
116
  <h1>Authentication Failed</h1>
@@ -128,7 +128,7 @@ ${U}`,metadata:{serverName:Z,toolName:Y.name,mcpResult:K}}}catch(K){return{succe
128
128
  </html>
129
129
  `),Q.close(),Z(q)}catch(G){Q.close(),Y(G)}});Q.on("error",Y),Q.listen(H3,()=>{console.log(`[OAuth] Callback server listening on port ${H3}`)}),setTimeout(()=>{Q.close(),Y(Error("OAuth callback timeout"))},300000)})}async exchangeCodeForToken($,Z,Y){let Q=$.redirectUri||`http://localhost:${H3}${l5}`,X=new URLSearchParams({grant_type:"authorization_code",code:Z,redirect_uri:Q,code_verifier:Y,client_id:$.clientId});if($.clientSecret)X.append("client_secret",$.clientSecret);let J=await fetch($.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:X.toString()});if(!J.ok){let G=await J.text();throw Error(`Token exchange failed: ${J.status} - ${G}`)}return await J.json()}async refreshAccessToken($,Z){let Y=new URLSearchParams({grant_type:"refresh_token",refresh_token:Z,client_id:$.clientId});if($.clientSecret)Y.append("client_secret",$.clientSecret);if($.scopes&&$.scopes.length>0)Y.append("scope",$.scopes.join(" "));let Q=await fetch($.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:Y.toString()});if(!Q.ok){let X=await Q.text();throw Error(`Token refresh failed: ${Q.status} - ${X}`)}return await Q.json()}async authenticate($,Z){if(!Z.clientId||!Z.authorizationUrl||!Z.tokenUrl)throw Error("Missing required OAuth configuration");let Y=this.generatePKCEParams(),Q=this.buildAuthorizationUrl(Z,Y);console.log(`
130
130
  [OAuth] Opening browser for authentication...`),console.log(`
131
- 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 G=await this.exchangeCodeForToken(Z,J,Y.codeVerifier),q={accessToken:G.access_token,tokenType:G.token_type||"Bearer",refreshToken:G.refresh_token,scope:G.scope};if(G.expires_in)q.expiresAt=Date.now()+G.expires_in*1000;return await this.tokenStorage.saveToken($,q,Z.clientId,Z.tokenUrl),console.log("[OAuth] Authentication successful! Token saved."),q}async openAuthorizationUrl($){let{command:Z,args:Y}=this.getBrowserCommand($);await new Promise((Q,X)=>{let J=PH(Z,Y,{stdio:"ignore"});J.once("error",X),J.once("close",(G)=>{if(G===0||G===null)Q();else X(Error(`Failed to open browser (exit code ${G})`))})})}getBrowserCommand($){if(process.platform==="darwin")return{command:"open",args:[$]};if(process.platform==="win32")return{command:"cmd",args:["/c","start","",$]};return{command:"xdg-open",args:[$]}}async getValidToken($,Z){let Y=await this.tokenStorage.getCredentials($);if(!Y)return null;let{token:Q}=Y;if(!this.tokenStorage.isTokenExpired(Q))return Q.accessToken;if(Q.refreshToken&&Z.clientId&&Y.tokenUrl)try{console.log(`[OAuth] Refreshing expired token for server: ${$}`);let X=await this.refreshAccessToken(Z,Q.refreshToken),J={accessToken:X.access_token,tokenType:X.token_type,refreshToken:X.refresh_token||Q.refreshToken,scope:X.scope||Q.scope};if(X.expires_in)J.expiresAt=Date.now()+X.expires_in*1000;return await this.tokenStorage.saveToken($,J,Z.clientId,Y.tokenUrl),J.accessToken}catch(X){console.error("[OAuth] Failed to refresh token:",X),await this.tokenStorage.deleteCredentials($)}return null}}var H3=7777,l5="/oauth/callback",BX=200;var LX=R(()=>{_X()});var NX=R(()=>{LX()});var T4=()=>{};import{EventEmitter as CH}from"events";var i5;var AX=R(()=>{T4();i5=class i5 extends CH{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 SH}from"@modelcontextprotocol/sdk/client/index.js";import{SSEClientTransport as kH}from"@modelcontextprotocol/sdk/client/sse.js";import{StdioClientTransport as fH}from"@modelcontextprotocol/sdk/client/stdio.js";import{EventEmitter as hH}from"events";function bX($){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 r5;var RX=R(()=>{x2();NX();AX();T4();r5=class r5 extends hH{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 b6;if(Y?.enabled)this.healthMonitor=new i5(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=bX(X);if(!J.isRetryable)throw console.error("[McpClient] 检测到永久性错误,放弃重试:",J.type),X;if(Q<$){let G=Z*Math.pow(2,Q-1);console.warn(`[McpClient] 连接失败(${Q}/${$}),${G}ms 后重试...`),await new Promise((q)=>setTimeout(q,G))}}throw Y||Error("连接失败")}async doConnect(){try{this.setStatus("connecting"),this.sdkClient=new SH({name:HQ(),version:Z1()},{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),bX(Z).isRetryable)this.scheduleReconnect();else console.error("[McpClient] 检测到永久性错误,停止重连"),this.emit("reconnectFailed")}},$)}async disconnect(){if(this.isManualDisconnect=!0,this.healthMonitor)this.healthMonitor.stop();if(this.reconnectTimer)clearTimeout(this.reconnectTimer),this.reconnectTimer=null;if(this.sdkClient){try{await this.sdkClient.close()}catch($){console.warn("[McpClient] 断开连接时出错:",$)}this.sdkClient=null}this.tools.clear(),this.serverInfo=null,this.reconnectAttempts=0,this.setStatus("disconnected"),this.emit("disconnected"),this.isManualDisconnect=!1}async callTool($,Z={}){if(!this.sdkClient)throw Error("客户端未连接到服务器");if(!this.tools.has($))throw Error(`工具 "${$}" 不存在`);try{return await this.sdkClient.callTool({name:$,arguments:Z})}catch(Y){throw console.error(`[McpClient] 调用工具 "${$}" 失败:`,Y),Y}}async createTransport(){let{type:$,command:Z,args:Y,env:Q,url:X,headers:J,oauth:G}=this.config,q={...J};if(G?.enabled&&this.oauthProvider&&($==="sse"||$==="http"))try{let K=await this.oauthProvider.getValidToken(this.serverName,G);if(!K){console.log(`[McpClient] 服务器 "${this.serverName}" 需要 OAuth 认证`);let W=await this.oauthProvider.authenticate(this.serverName,G);q.Authorization=`Bearer ${W.accessToken}`}else q.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 fH({command:Z,args:Y||[],env:{...K,...Q},stderr:"ignore"})}else if($==="sse"){if(!X)throw Error("sse 传输需要 url 参数");return new kH(new URL(X),{requestInit:{headers:q}})}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:q}})}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 xH}from"events";var e0;var d2=R(()=>{HX();RX();T4();e0=class e0 extends xH{static instance=null;servers=new Map;isDiscovering=!1;constructor(){super()}static getInstance(){if(!e0.instance)e0.instance=new e0;return e0.instance}async registerServer($,Z){if(this.servers.has($))throw Error(`MCP服务器 "${$}" 已经注册`);let Y=new r5(Z,$,Z.healthCheck),Q={config:Z,client:Y,status:"disconnected",tools:[]};this.setupClientEventHandlers(Y,Q,$),this.servers.set($,Q),this.emit("serverRegistered",$,Q);try{await this.connectServer($)}catch(X){console.warn(`MCP服务器 "${$}" 连接失败:`,X)}}async unregisterServer($){let Z=this.servers.get($);if(!Z)return;try{await Z.client.disconnect()}catch(Y){console.warn(`断开MCP服务器 "${$}" 时出错:`,Y)}this.servers.delete($),this.emit("serverUnregistered",$)}async connectServer($){let Z=this.servers.get($);if(!Z)throw Error(`MCP服务器 "${$}" 未注册`);if(Z.status==="connected")return;try{Z.status="connecting",await Z.client.connect(),Z.connectedAt=new Date,Z.lastError=void 0,Z.tools=Z.client.availableTools}catch(Y){throw Z.lastError=Y,Z.status="error",Y}}async disconnectServer($){let Z=this.servers.get($);if(!Z)return;await Z.client.disconnect(),Z.connectedAt=void 0}async reconnectServer($){let Z=this.servers.get($);if(!Z)throw Error(`MCP服务器 "${$}" 未注册`);if(Z.status==="connected")await Z.client.disconnect();try{Z.status="connecting",await Z.client.connect(),Z.connectedAt=new Date,Z.lastError=void 0,Z.tools=Z.client.availableTools}catch(Y){throw Z.lastError=Y,Z.status="error",Y}}async getAvailableTools(){let $=[],Z=new Map;for(let[Y,Q]of this.servers)if(Q.status==="connected")for(let X of Q.tools){let J=Z.get(X.name)||0;Z.set(X.name,J+1)}for(let[Y,Q]of this.servers)if(Q.status==="connected")for(let X of Q.tools){let G=(Z.get(X.name)||0)>1?`${Y}__${X.name}`:X.name,q=A6(Q.client,Y,X,G);$.push(q)}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 A6(Y.client,Z,Q)}return null}getToolsByServer($){let Z=this.servers.get($);if(!Z||Z.status!=="connected")return[];return Z.tools.map((Y)=>A6(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 o5($,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 DX(){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 n5;var jX=R(()=>{n5={enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,PreToolUse:[],PostToolUse:[],PostToolUseFailure:[],PermissionRequest:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]}});class s5{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 G2,t5,e5;var B8=R(()=>{((O)=>{O.PreToolUse="PreToolUse";O.PostToolUse="PostToolUse";O.PostToolUseFailure="PostToolUseFailure";O.PermissionRequest="PermissionRequest";O.UserPromptSubmit="UserPromptSubmit";O.SessionStart="SessionStart";O.SessionEnd="SessionEnd";O.Stop="Stop";O.SubagentStop="SubagentStop";O.Notification="Notification";O.Compaction="Compaction"})(G2||={});((Q)=>{Q.Approve="approve";Q.Block="block";Q.Async="async"})(t5||={});((Q)=>{Q.Allow="allow";Q.Deny="deny";Q.Ask="ask"})(e5||={})});import{z as E}from"zod";function yX($){let Z=H_.safeParse($);if(Z.success)return{success:!0,data:Z.data};return{success:!1,error:Z.error}}var c1,aH,nH,oH,sH,tH,eH,$_,Z_,Y_,Q_,X_,$y,J_,G_,q_,K_,W_,U_,O_,F_,H_,__,z_,B_,$9,w_,d1,Zy;var TX=R(()=>{B8();c1=E.object({hook_event_name:E.nativeEnum(G2),hook_execution_id:E.string(),timestamp:E.string(),project_dir:E.string(),session_id:E.string(),permission_mode:E.enum(["default","autoEdit","yolo","plan"]),_metadata:E.object({blade_version:E.string(),hook_timeout_ms:E.number()}).optional()}),aH=c1.extend({hook_event_name:E.literal("PreToolUse"),tool_name:E.string(),tool_use_id:E.string(),tool_input:E.record(E.unknown())}),nH=c1.extend({hook_event_name:E.literal("PostToolUse"),tool_name:E.string(),tool_use_id:E.string(),tool_input:E.record(E.unknown()),tool_response:E.unknown()}),oH=c1.extend({hook_event_name:E.literal("Stop"),reason:E.string().optional()}),sH=c1.extend({hook_event_name:E.literal("PostToolUseFailure"),tool_name:E.string(),tool_use_id:E.string(),tool_input:E.record(E.unknown()),error:E.string(),error_type:E.string().optional(),is_interrupt:E.boolean(),is_timeout:E.boolean()}),tH=c1.extend({hook_event_name:E.literal("PermissionRequest"),tool_name:E.string(),tool_use_id:E.string(),tool_input:E.record(E.unknown())}),eH=c1.extend({hook_event_name:E.literal("UserPromptSubmit"),user_prompt:E.string(),has_images:E.boolean(),image_count:E.number()}),$_=c1.extend({hook_event_name:E.literal("SessionStart"),is_resume:E.boolean(),resume_session_id:E.string().optional()}),Z_=c1.extend({hook_event_name:E.literal("SessionEnd"),reason:E.enum(["user_exit","error","max_turns","idle_timeout","ctrl_c","clear","logout","other"])}),Y_=c1.extend({hook_event_name:E.literal("SubagentStop"),agent_type:E.string(),task_description:E.string().optional(),success:E.boolean(),result_summary:E.string().optional(),error:E.string().optional()}),Q_=c1.extend({hook_event_name:E.literal("Notification"),notification_type:E.enum(["permission_prompt","idle_prompt","auth_success","elicitation_dialog","info","warning","error"]),title:E.string().optional(),message:E.string()}),X_=c1.extend({hook_event_name:E.literal("Compaction"),trigger:E.enum(["manual","auto"]),messages_before:E.number(),tokens_before:E.number()}),$y=E.discriminatedUnion("hook_event_name",[aH,nH,oH,sH,tH,eH,$_,Z_,Y_,Q_,X_]),J_=E.object({hookEventName:E.literal("PreToolUse"),permissionDecision:E.nativeEnum(e5).optional(),permissionDecisionReason:E.string().optional(),updatedInput:E.record(E.unknown()).optional()}),G_=E.object({hookEventName:E.literal("PostToolUse"),additionalContext:E.string().optional(),updatedOutput:E.unknown().optional()}),q_=E.object({hookEventName:E.literal("Stop"),continue:E.boolean().optional(),continueReason:E.string().optional()}),K_=E.object({hookEventName:E.literal("SubagentStop"),continue:E.boolean().optional(),continueReason:E.string().optional(),additionalContext:E.string().optional()}),W_=E.object({hookEventName:E.literal("PermissionRequest"),permissionDecision:E.enum(["approve","deny","ask"]).optional(),permissionDecisionReason:E.string().optional()}),U_=E.object({hookEventName:E.literal("UserPromptSubmit"),updatedPrompt:E.string().optional(),contextInjection:E.string().optional()}),O_=E.object({hookEventName:E.literal("SessionStart"),env:E.record(E.string()).optional()}),F_=E.object({hookEventName:E.literal("Compaction"),blockCompaction:E.boolean().optional(),blockReason:E.string().optional()}),H_=E.object({decision:E.object({behavior:E.nativeEnum(t5)}).optional(),systemMessage:E.string().optional(),hookSpecificOutput:E.discriminatedUnion("hookEventName",[J_,G_,q_,K_,W_,U_,O_,F_]).optional(),suppressOutput:E.boolean().optional()}),__=E.object({type:E.literal("command"),command:E.string(),timeout:E.number().positive().optional(),statusMessage:E.string().optional()}),z_=E.object({type:E.literal("prompt"),prompt:E.string(),timeout:E.number().positive().optional()}),B_=E.discriminatedUnion("type",[__,z_]),$9=E.union([E.string(),E.array(E.string())]),w_=E.object({tools:$9.optional(),paths:$9.optional(),commands:$9.optional()}),d1=E.object({name:E.string().optional(),matcher:w_.optional(),hooks:E.array(B_)}),Zy=E.object({enabled:E.boolean().optional(),defaultTimeout:E.number().positive().optional(),timeoutBehavior:E.enum(["ignore","deny","ask"]).optional(),failureBehavior:E.enum(["ignore","deny","ask"]).optional(),maxConcurrentHooks:E.number().positive().optional(),PreToolUse:E.array(d1).optional(),PostToolUse:E.array(d1).optional(),PostToolUseFailure:E.array(d1).optional(),PermissionRequest:E.array(d1).optional(),UserPromptSubmit:E.array(d1).optional(),SessionStart:E.array(d1).optional(),SessionEnd:E.array(d1).optional(),Stop:E.array(d1).optional(),SubagentStop:E.array(d1).optional(),Notification:E.array(d1).optional(),Compaction:E.array(d1).optional()})});class Z9{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=yX(Q);if(!X.success){let G="error"in X?X.error.message:"Unknown validation error",q=Y?.failureBehavior||"ignore",K=`Invalid hook output JSON: ${G}`;if(q==="deny")return{success:!1,blocking:!0,error:K,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else if(q==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${K}. Continue?`,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else return{success:!1,blocking:!1,warning:K,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z}}let J=X.data;if(J.decision?.behavior==="block")return{success:!1,blocking:!0,error:J.systemMessage||"Hook blocked execution",output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};if(J.decision?.behavior==="async")return{success:!0,output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};return{success:!0,output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z}}return this.parseByExitCode($,Z,Y)}parseByExitCode($,Z,Y){let Q=$.exitCode;switch(Q){case 0:return{success:!0,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};case 2:return{success:!1,blocking:!0,error:$.stderr||$.stdout||"Hook returned exit code 2",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};case 124:{let X=Y?.timeoutBehavior||"ignore",J="Hook timeout";if(X==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z}}default:{let X=Y?.failureBehavior||"ignore",J=$.stderr||$.stdout||`Hook failed with exit code ${Q}`;if(X==="deny")return{success:!1,blocking:!0,error:J,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${J}. Continue?`,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else return{success:!1,blocking:!1,warning:J,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z}}}}tryParseJSON($){try{let Z=$.trim();if(!Z)return null;let Y=Z.match(/^\s*(\{[\s\S]*\})\s*$/);if(!Y)return null;return JSON.parse(Y[1])}catch{return null}}}var EX=R(()=>{TX()});import{spawn as L_}from"child_process";class Y9{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 Q9{MAX_STDOUT_SIZE=1048576;MAX_STDERR_SIZE=1048576;MAX_INPUT_SIZE=102400;async execute($,Z,Y,Q){let X=JSON.stringify(Z);if(X.length>this.MAX_INPUT_SIZE)throw Error(`Hook input too large: ${X.length} bytes (max ${this.MAX_INPUT_SIZE})`);let J=this.createSafeEnv(Z),G=L_($,[],{shell:!0,env:J,cwd:Y.projectDir,timeout:Q}),q=new Y9(this.MAX_STDOUT_SIZE),K=new Y9(this.MAX_STDERR_SIZE);G.stdout.setEncoding("utf8"),G.stderr.setEncoding("utf8"),G.stdout.on("data",(W)=>{q.append(W)}),G.stderr.on("data",(W)=>{K.append(W)});try{G.stdin.write(X),G.stdin.end()}catch(W){throw G.kill("SIGTERM"),Error(`Failed to write hook input: ${W}`)}return new Promise((W,U)=>{let O=!1,F=!1,H=null,_=()=>{if(H&&Y.abortSignal)Y.abortSignal.removeEventListener("abort",H),H=null},z=setTimeout(()=>{O=!0,G.kill("SIGKILL")},Q);if(G.on("close",(w)=>{if(F)return;F=!0,clearTimeout(z),_(),W({stdout:q.getContent(),stderr:K.getContent(),exitCode:O?124:w??1,timedOut:O})}),G.on("error",(w)=>{if(F)return;F=!0,clearTimeout(z),_(),U(w)}),Y.abortSignal)H=()=>{if(F)return;F=!0,clearTimeout(z),_(),G.kill("SIGTERM"),W({stdout:q.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 IX=()=>{};class X9{processExecutor=new Q9;outputParser=new Z9;async executePreToolHooks($,Z,Y){if($.length===0)return{decision:"allow"};let Q="tool_input"in Z?Z.tool_input:{},X=[];for(let J of $)try{let G={...Z,...Q&&{tool_input:Q}},q=await this.executeHook(J,G,Y);if(!q.success){if(q.blocking)return{decision:"deny",reason:q.error};if(q.needsConfirmation)return{decision:"ask",reason:q.warning||q.error};if(q.warning)X.push(q.warning);continue}let K=q.output?.hookSpecificOutput;if(K&&"permissionDecision"in K){switch(K.permissionDecision){case"deny":return{decision:"deny",reason:K.permissionDecisionReason};case"ask":return{decision:"ask",reason:K.permissionDecisionReason};case"allow":break}if("updatedInput"in K&&K.updatedInput)Q={...Q,...K.updatedInput}}}catch(G){let q=G instanceof Error?G.message:String(G);if(X.push(`Hook failed: ${q}`),Y.config.failureBehavior==="deny")return{decision:"deny",reason:q};else if(Y.config.failureBehavior==="ask")return{decision:"ask",reason:`Hook failed: ${q}. Continue?`}}return{decision:"allow",modifiedInput:Q,warning:X.length>0?X.join(`
131
+ 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 G=await this.exchangeCodeForToken(Z,J,Y.codeVerifier),q={accessToken:G.access_token,tokenType:G.token_type||"Bearer",refreshToken:G.refresh_token,scope:G.scope};if(G.expires_in)q.expiresAt=Date.now()+G.expires_in*1000;return await this.tokenStorage.saveToken($,q,Z.clientId,Z.tokenUrl),console.log("[OAuth] Authentication successful! Token saved."),q}async openAuthorizationUrl($){let{command:Z,args:Y}=this.getBrowserCommand($);await new Promise((Q,X)=>{let J=PH(Z,Y,{stdio:"ignore"});J.once("error",X),J.once("close",(G)=>{if(G===0||G===null)Q();else X(Error(`Failed to open browser (exit code ${G})`))})})}getBrowserCommand($){if(process.platform==="darwin")return{command:"open",args:[$]};if(process.platform==="win32")return{command:"cmd",args:["/c","start","",$]};return{command:"xdg-open",args:[$]}}async getValidToken($,Z){let Y=await this.tokenStorage.getCredentials($);if(!Y)return null;let{token:Q}=Y;if(!this.tokenStorage.isTokenExpired(Q))return Q.accessToken;if(Q.refreshToken&&Z.clientId&&Y.tokenUrl)try{console.log(`[OAuth] Refreshing expired token for server: ${$}`);let X=await this.refreshAccessToken(Z,Q.refreshToken),J={accessToken:X.access_token,tokenType:X.token_type,refreshToken:X.refresh_token||Q.refreshToken,scope:X.scope||Q.scope};if(X.expires_in)J.expiresAt=Date.now()+X.expires_in*1000;return await this.tokenStorage.saveToken($,J,Z.clientId,Y.tokenUrl),J.accessToken}catch(X){console.error("[OAuth] Failed to refresh token:",X),await this.tokenStorage.deleteCredentials($)}return null}}var H3=7777,l5="/oauth/callback",BX=200;var LX=R(()=>{_X()});var NX=R(()=>{LX()});var T4=()=>{};import{EventEmitter as CH}from"events";var i5;var AX=R(()=>{T4();i5=class i5 extends CH{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 SH}from"@modelcontextprotocol/sdk/client/index.js";import{SSEClientTransport as kH}from"@modelcontextprotocol/sdk/client/sse.js";import{StdioClientTransport as fH}from"@modelcontextprotocol/sdk/client/stdio.js";import{EventEmitter as hH}from"events";function bX($){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 r5;var RX=R(()=>{x2();NX();AX();T4();r5=class r5 extends hH{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 b7;if(Y?.enabled)this.healthMonitor=new i5(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=bX(X);if(!J.isRetryable)throw console.error("[McpClient] 检测到永久性错误,放弃重试:",J.type),X;if(Q<$){let G=Z*Math.pow(2,Q-1);console.warn(`[McpClient] 连接失败(${Q}/${$}),${G}ms 后重试...`),await new Promise((q)=>setTimeout(q,G))}}throw Y||Error("连接失败")}async doConnect(){try{this.setStatus("connecting"),this.sdkClient=new SH({name:HQ(),version:Z1()},{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),bX(Z).isRetryable)this.scheduleReconnect();else console.error("[McpClient] 检测到永久性错误,停止重连"),this.emit("reconnectFailed")}},$)}async disconnect(){if(this.isManualDisconnect=!0,this.healthMonitor)this.healthMonitor.stop();if(this.reconnectTimer)clearTimeout(this.reconnectTimer),this.reconnectTimer=null;if(this.sdkClient){try{await this.sdkClient.close()}catch($){console.warn("[McpClient] 断开连接时出错:",$)}this.sdkClient=null}this.tools.clear(),this.serverInfo=null,this.reconnectAttempts=0,this.setStatus("disconnected"),this.emit("disconnected"),this.isManualDisconnect=!1}async callTool($,Z={}){if(!this.sdkClient)throw Error("客户端未连接到服务器");if(!this.tools.has($))throw Error(`工具 "${$}" 不存在`);try{return await this.sdkClient.callTool({name:$,arguments:Z})}catch(Y){throw console.error(`[McpClient] 调用工具 "${$}" 失败:`,Y),Y}}async createTransport(){let{type:$,command:Z,args:Y,env:Q,url:X,headers:J,oauth:G}=this.config,q={...J};if(G?.enabled&&this.oauthProvider&&($==="sse"||$==="http"))try{let K=await this.oauthProvider.getValidToken(this.serverName,G);if(!K){console.log(`[McpClient] 服务器 "${this.serverName}" 需要 OAuth 认证`);let W=await this.oauthProvider.authenticate(this.serverName,G);q.Authorization=`Bearer ${W.accessToken}`}else q.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 fH({command:Z,args:Y||[],env:{...K,...Q},stderr:"ignore"})}else if($==="sse"){if(!X)throw Error("sse 传输需要 url 参数");return new kH(new URL(X),{requestInit:{headers:q}})}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:q}})}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 xH}from"events";var e0;var d2=R(()=>{HX();RX();T4();e0=class e0 extends xH{static instance=null;servers=new Map;isDiscovering=!1;constructor(){super()}static getInstance(){if(!e0.instance)e0.instance=new e0;return e0.instance}async registerServer($,Z){if(this.servers.has($))throw Error(`MCP服务器 "${$}" 已经注册`);let Y=new r5(Z,$,Z.healthCheck),Q={config:Z,client:Y,status:"disconnected",tools:[]};this.setupClientEventHandlers(Y,Q,$),this.servers.set($,Q),this.emit("serverRegistered",$,Q);try{await this.connectServer($)}catch(X){console.warn(`MCP服务器 "${$}" 连接失败:`,X)}}async unregisterServer($){let Z=this.servers.get($);if(!Z)return;try{await Z.client.disconnect()}catch(Y){console.warn(`断开MCP服务器 "${$}" 时出错:`,Y)}this.servers.delete($),this.emit("serverUnregistered",$)}async connectServer($){let Z=this.servers.get($);if(!Z)throw Error(`MCP服务器 "${$}" 未注册`);if(Z.status==="connected")return;try{Z.status="connecting",await Z.client.connect(),Z.connectedAt=new Date,Z.lastError=void 0,Z.tools=Z.client.availableTools}catch(Y){throw Z.lastError=Y,Z.status="error",Y}}async disconnectServer($){let Z=this.servers.get($);if(!Z)return;await Z.client.disconnect(),Z.connectedAt=void 0}async reconnectServer($){let Z=this.servers.get($);if(!Z)throw Error(`MCP服务器 "${$}" 未注册`);if(Z.status==="connected")await Z.client.disconnect();try{Z.status="connecting",await Z.client.connect(),Z.connectedAt=new Date,Z.lastError=void 0,Z.tools=Z.client.availableTools}catch(Y){throw Z.lastError=Y,Z.status="error",Y}}async getAvailableTools(){let $=[],Z=new Map;for(let[Y,Q]of this.servers)if(Q.status==="connected")for(let X of Q.tools){let J=Z.get(X.name)||0;Z.set(X.name,J+1)}for(let[Y,Q]of this.servers)if(Q.status==="connected")for(let X of Q.tools){let G=(Z.get(X.name)||0)>1?`${Y}__${X.name}`:X.name,q=A7(Q.client,Y,X,G);$.push(q)}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 A7(Y.client,Z,Q)}return null}getToolsByServer($){let Z=this.servers.get($);if(!Z||Z.status!=="connected")return[];return Z.tools.map((Y)=>A7(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 o5($,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 DX(){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 n5;var jX=R(()=>{n5={enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,PreToolUse:[],PostToolUse:[],PostToolUseFailure:[],PermissionRequest:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]}});class s5{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 G2,t5,e5;var B8=R(()=>{((O)=>{O.PreToolUse="PreToolUse";O.PostToolUse="PostToolUse";O.PostToolUseFailure="PostToolUseFailure";O.PermissionRequest="PermissionRequest";O.UserPromptSubmit="UserPromptSubmit";O.SessionStart="SessionStart";O.SessionEnd="SessionEnd";O.Stop="Stop";O.SubagentStop="SubagentStop";O.Notification="Notification";O.Compaction="Compaction"})(G2||={});((Q)=>{Q.Approve="approve";Q.Block="block";Q.Async="async"})(t5||={});((Q)=>{Q.Allow="allow";Q.Deny="deny";Q.Ask="ask"})(e5||={})});import{z as E}from"zod";function yX($){let Z=H_.safeParse($);if(Z.success)return{success:!0,data:Z.data};return{success:!1,error:Z.error}}var c1,aH,nH,oH,sH,tH,eH,$_,Z_,Y_,Q_,X_,$y,J_,G_,q_,K_,W_,U_,O_,F_,H_,__,z_,B_,$9,w_,d1,Zy;var TX=R(()=>{B8();c1=E.object({hook_event_name:E.nativeEnum(G2),hook_execution_id:E.string(),timestamp:E.string(),project_dir:E.string(),session_id:E.string(),permission_mode:E.enum(["default","autoEdit","yolo","plan"]),_metadata:E.object({blade_version:E.string(),hook_timeout_ms:E.number()}).optional()}),aH=c1.extend({hook_event_name:E.literal("PreToolUse"),tool_name:E.string(),tool_use_id:E.string(),tool_input:E.record(E.unknown())}),nH=c1.extend({hook_event_name:E.literal("PostToolUse"),tool_name:E.string(),tool_use_id:E.string(),tool_input:E.record(E.unknown()),tool_response:E.unknown()}),oH=c1.extend({hook_event_name:E.literal("Stop"),reason:E.string().optional()}),sH=c1.extend({hook_event_name:E.literal("PostToolUseFailure"),tool_name:E.string(),tool_use_id:E.string(),tool_input:E.record(E.unknown()),error:E.string(),error_type:E.string().optional(),is_interrupt:E.boolean(),is_timeout:E.boolean()}),tH=c1.extend({hook_event_name:E.literal("PermissionRequest"),tool_name:E.string(),tool_use_id:E.string(),tool_input:E.record(E.unknown())}),eH=c1.extend({hook_event_name:E.literal("UserPromptSubmit"),user_prompt:E.string(),has_images:E.boolean(),image_count:E.number()}),$_=c1.extend({hook_event_name:E.literal("SessionStart"),is_resume:E.boolean(),resume_session_id:E.string().optional()}),Z_=c1.extend({hook_event_name:E.literal("SessionEnd"),reason:E.enum(["user_exit","error","max_turns","idle_timeout","ctrl_c","clear","logout","other"])}),Y_=c1.extend({hook_event_name:E.literal("SubagentStop"),agent_type:E.string(),task_description:E.string().optional(),success:E.boolean(),result_summary:E.string().optional(),error:E.string().optional()}),Q_=c1.extend({hook_event_name:E.literal("Notification"),notification_type:E.enum(["permission_prompt","idle_prompt","auth_success","elicitation_dialog","info","warning","error"]),title:E.string().optional(),message:E.string()}),X_=c1.extend({hook_event_name:E.literal("Compaction"),trigger:E.enum(["manual","auto"]),messages_before:E.number(),tokens_before:E.number()}),$y=E.discriminatedUnion("hook_event_name",[aH,nH,oH,sH,tH,eH,$_,Z_,Y_,Q_,X_]),J_=E.object({hookEventName:E.literal("PreToolUse"),permissionDecision:E.nativeEnum(e5).optional(),permissionDecisionReason:E.string().optional(),updatedInput:E.record(E.unknown()).optional()}),G_=E.object({hookEventName:E.literal("PostToolUse"),additionalContext:E.string().optional(),updatedOutput:E.unknown().optional()}),q_=E.object({hookEventName:E.literal("Stop"),continue:E.boolean().optional(),continueReason:E.string().optional()}),K_=E.object({hookEventName:E.literal("SubagentStop"),continue:E.boolean().optional(),continueReason:E.string().optional(),additionalContext:E.string().optional()}),W_=E.object({hookEventName:E.literal("PermissionRequest"),permissionDecision:E.enum(["approve","deny","ask"]).optional(),permissionDecisionReason:E.string().optional()}),U_=E.object({hookEventName:E.literal("UserPromptSubmit"),updatedPrompt:E.string().optional(),contextInjection:E.string().optional()}),O_=E.object({hookEventName:E.literal("SessionStart"),env:E.record(E.string()).optional()}),F_=E.object({hookEventName:E.literal("Compaction"),blockCompaction:E.boolean().optional(),blockReason:E.string().optional()}),H_=E.object({decision:E.object({behavior:E.nativeEnum(t5)}).optional(),systemMessage:E.string().optional(),hookSpecificOutput:E.discriminatedUnion("hookEventName",[J_,G_,q_,K_,W_,U_,O_,F_]).optional(),suppressOutput:E.boolean().optional()}),__=E.object({type:E.literal("command"),command:E.string(),timeout:E.number().positive().optional(),statusMessage:E.string().optional()}),z_=E.object({type:E.literal("prompt"),prompt:E.string(),timeout:E.number().positive().optional()}),B_=E.discriminatedUnion("type",[__,z_]),$9=E.union([E.string(),E.array(E.string())]),w_=E.object({tools:$9.optional(),paths:$9.optional(),commands:$9.optional()}),d1=E.object({name:E.string().optional(),matcher:w_.optional(),hooks:E.array(B_)}),Zy=E.object({enabled:E.boolean().optional(),defaultTimeout:E.number().positive().optional(),timeoutBehavior:E.enum(["ignore","deny","ask"]).optional(),failureBehavior:E.enum(["ignore","deny","ask"]).optional(),maxConcurrentHooks:E.number().positive().optional(),PreToolUse:E.array(d1).optional(),PostToolUse:E.array(d1).optional(),PostToolUseFailure:E.array(d1).optional(),PermissionRequest:E.array(d1).optional(),UserPromptSubmit:E.array(d1).optional(),SessionStart:E.array(d1).optional(),SessionEnd:E.array(d1).optional(),Stop:E.array(d1).optional(),SubagentStop:E.array(d1).optional(),Notification:E.array(d1).optional(),Compaction:E.array(d1).optional()})});class Z9{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=yX(Q);if(!X.success){let G="error"in X?X.error.message:"Unknown validation error",q=Y?.failureBehavior||"ignore",K=`Invalid hook output JSON: ${G}`;if(q==="deny")return{success:!1,blocking:!0,error:K,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else if(q==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${K}. Continue?`,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};else return{success:!1,blocking:!1,warning:K,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z}}let J=X.data;if(J.decision?.behavior==="block")return{success:!1,blocking:!0,error:J.systemMessage||"Hook blocked execution",output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};if(J.decision?.behavior==="async")return{success:!0,output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z};return{success:!0,output:J,stdout:$.stdout,stderr:$.stderr,exitCode:$.exitCode,hook:Z}}return this.parseByExitCode($,Z,Y)}parseByExitCode($,Z,Y){let Q=$.exitCode;switch(Q){case 0:return{success:!0,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};case 2:return{success:!1,blocking:!0,error:$.stderr||$.stdout||"Hook returned exit code 2",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};case 124:{let X=Y?.timeoutBehavior||"ignore",J="Hook timeout";if(X==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z}}default:{let X=Y?.failureBehavior||"ignore",J=$.stderr||$.stdout||`Hook failed with exit code ${Q}`;if(X==="deny")return{success:!1,blocking:!0,error:J,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${J}. Continue?`,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z};else return{success:!1,blocking:!1,warning:J,stdout:$.stdout,stderr:$.stderr,exitCode:Q,hook:Z}}}}tryParseJSON($){try{let Z=$.trim();if(!Z)return null;let Y=Z.match(/^\s*(\{[\s\S]*\})\s*$/);if(!Y)return null;return JSON.parse(Y[1])}catch{return null}}}var EX=R(()=>{TX()});import{spawn as L_}from"child_process";class Y9{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 Q9{MAX_STDOUT_SIZE=1048576;MAX_STDERR_SIZE=1048576;MAX_INPUT_SIZE=102400;async execute($,Z,Y,Q){let X=JSON.stringify(Z);if(X.length>this.MAX_INPUT_SIZE)throw Error(`Hook input too large: ${X.length} bytes (max ${this.MAX_INPUT_SIZE})`);let J=this.createSafeEnv(Z),G=L_($,[],{shell:!0,env:J,cwd:Y.projectDir,timeout:Q}),q=new Y9(this.MAX_STDOUT_SIZE),K=new Y9(this.MAX_STDERR_SIZE);G.stdout.setEncoding("utf8"),G.stderr.setEncoding("utf8"),G.stdout.on("data",(W)=>{q.append(W)}),G.stderr.on("data",(W)=>{K.append(W)});try{G.stdin.write(X),G.stdin.end()}catch(W){throw G.kill("SIGTERM"),Error(`Failed to write hook input: ${W}`)}return new Promise((W,U)=>{let O=!1,F=!1,H=null,_=()=>{if(H&&Y.abortSignal)Y.abortSignal.removeEventListener("abort",H),H=null},z=setTimeout(()=>{O=!0,G.kill("SIGKILL")},Q);if(G.on("close",(w)=>{if(F)return;F=!0,clearTimeout(z),_(),W({stdout:q.getContent(),stderr:K.getContent(),exitCode:O?124:w??1,timedOut:O})}),G.on("error",(w)=>{if(F)return;F=!0,clearTimeout(z),_(),U(w)}),Y.abortSignal)H=()=>{if(F)return;F=!0,clearTimeout(z),_(),G.kill("SIGTERM"),W({stdout:q.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 IX=()=>{};class X9{processExecutor=new Q9;outputParser=new Z9;async executePreToolHooks($,Z,Y){if($.length===0)return{decision:"allow"};let Q="tool_input"in Z?Z.tool_input:{},X=[];for(let J of $)try{let G={...Z,...Q&&{tool_input:Q}},q=await this.executeHook(J,G,Y);if(!q.success){if(q.blocking)return{decision:"deny",reason:q.error};if(q.needsConfirmation)return{decision:"ask",reason:q.warning||q.error};if(q.warning)X.push(q.warning);continue}let K=q.output?.hookSpecificOutput;if(K&&"permissionDecision"in K){switch(K.permissionDecision){case"deny":return{decision:"deny",reason:K.permissionDecisionReason};case"ask":return{decision:"ask",reason:K.permissionDecisionReason};case"allow":break}if("updatedInput"in K&&K.updatedInput)Q={...Q,...K.updatedInput}}}catch(G){let q=G instanceof Error?G.message:String(G);if(X.push(`Hook failed: ${q}`),Y.config.failureBehavior==="deny")return{decision:"deny",reason:q};else if(Y.config.failureBehavior==="ask")return{decision:"ask",reason:`Hook failed: ${q}. Continue?`}}return{decision:"allow",modifiedInput:Q,warning:X.length>0?X.join(`
132
132
  `):void 0}}async executePostToolHooks($,Z,Y){if($.length===0)return{};let Q=Y.config.maxConcurrentHooks||5,X=await this.executeHooksConcurrently($,Z,Y,Q),J=[],G=void 0,q=[];for(let K of X){if(!K.success&&K.warning){q.push(K.warning);continue}let W=K.output?.hookSpecificOutput;if(W&&"additionalContext"in W){if(W.additionalContext)J.push(W.additionalContext);if("updatedOutput"in W&&W.updatedOutput!==void 0)G=W.updatedOutput}}return{additionalContext:J.length>0?J.join(`
133
133
 
134
134
  `):void 0,modifiedOutput:G,warning:q.length>0?q.join(`
@@ -151,7 +151,7 @@ If the browser does not open automatically, copy and paste this URL:`),console.l
151
151
  `):void 0}}async executeNotificationHooks($,Z,Y){let Q="message"in Z?Z.message:"";if($.length===0)return{suppress:!1,message:Q};let X=[],J=!1,G=Q;for(let q of $)try{let K=await this.executeHook(q,Z,Y);if(!K.success){if(K.warning)X.push(K.warning);continue}if(K.output?.suppressOutput){J=!0;break}if(K.stdout&&K.stdout.trim())G=K.stdout.trim()}catch(K){let W=K instanceof Error?K.message:String(K);X.push(`Hook failed: ${W}`)}return{suppress:J,message:G,warning:X.length>0?X.join(`
152
152
  `):void 0}}async executeCompactionHooks($,Z,Y){if($.length===0)return{blockCompaction:!1};let Q=[];for(let X of $)try{let J=await this.executeHook(X,Z,Y);if(!J.success){if(J.warning)Q.push(J.warning);continue}let G=J.output?.hookSpecificOutput;if(G&&"blockCompaction"in G&&G.blockCompaction)return{blockCompaction:!0,blockReason:G.blockReason,warning:Q.length>0?Q.join(`
153
153
  `):void 0}}catch(J){let G=J instanceof Error?J.message:String(J);Q.push(`Hook failed: ${G}`)}return{blockCompaction:!1,warning:Q.length>0?Q.join(`
154
- `):void 0}}async executeHook($,Z,Y){if($.type==="command")return this.executeCommandHook($,Z,Y);throw Error(`Hook type ${$.type} not yet implemented`)}async executeCommandHook($,Z,Y){let Q=($.timeout??Y.config.defaultTimeout??60)*1000;try{let X=await this.processExecutor.execute($.command,Z,Y,Q);return this.outputParser.parse(X,$,{timeoutBehavior:Y.config.timeoutBehavior,failureBehavior:Y.config.failureBehavior})}catch(X){return{success:!1,blocking:!1,error:X instanceof Error?X.message:String(X),hook:$}}}async executeHooksConcurrently($,Z,Y,Q){let X=[],J=new Set;for(let G of $){if(J.size>=Q)await Promise.race(J);let q=this.executeHook(G,Z,Y).catch((W)=>({success:!1,blocking:!1,error:W instanceof Error?W.message:String(W),hook:G})),K=q.then(()=>{J.delete(K)}).catch(()=>{J.delete(K)});J.add(K),X.push(q)}return Promise.all(X)}}var vX=R(()=>{EX();IX();B8()});import J9 from"picomatch";class G9{matches($,Z){if(!$)return!0;if($.tools&&Z.toolName){if(!this.matchTools($.tools,Z))return!1}if($.paths&&Z.filePath){if(!this.matchPaths($.paths,Z.filePath))return!1}if($.commands&&Z.command){if(!this.matchCommands($.commands,Z.command))return!1}return!0}matchTools($,Z){if(Array.isArray($))return $.some((Y)=>this.matchToolWithParams(Y,Z));return this.matchToolWithParams($,Z)}matchPaths($,Z){if(Array.isArray($))return $.some((Q)=>{return J9(Q)(Z)});return J9($)(Z)}matchCommands($,Z){if(Array.isArray($))return $.some((Y)=>this.matchPattern(Z,Y));return this.matchPattern(Z,$)}matchToolWithParams($,Z){let{toolName:Y,command:Q,filePath:X}=Z,J=N_.exec($);if(!J)return this.matchPattern(Y,$);let[,G,q]=J;if(!this.matchPattern(Y,G))return!1;let K=this.getArgValue(Y,Q,X);if(!K)return!1;return this.matchGlobOrPattern(K,q)}getArgValue($,Z,Y){if($==="Bash"||$==="BashTool")return Z;if(["Read","Edit","Write","Glob","Grep"].includes($))return Y;return Z||Y}matchGlobOrPattern($,Z){if(/[*?[\]{}!]/.test(Z))try{return J9(Z,{bash:!0,dot:!0})($)}catch{}if(Z.endsWith("*")){let Y=Z.slice(0,-1);return $.startsWith(Y)}return $===Z}matchPattern($,Z){if(Z==="*")return!0;if(!Z.includes("|")&&!/[.*+?^${}()|[\]\\]/.test(Z))return $===Z;if(Z.includes("|"))return Z.split("|").map((Q)=>Q.trim()).includes($);try{return new RegExp(Z).test($)}catch{return $===Z}}}var N_;var PX=R(()=>{N_=/^([A-Za-z0-9_|]+)\((.+)\)$/});import{nanoid as l1}from"nanoid";class y0{static instance=null;config=n5;executor=new X9;guard=new s5;matcher=new G9;sessionDisabled=!1;constructor(){}static getInstance(){if(!y0.instance)y0.instance=new y0;return y0.instance}loadConfig($){let Z=o5(n5,$),Y=DX();Z=o5(Z,Y),this.config=Z}isEnabled(){if(!this.config.enabled)return!1;if(this.sessionDisabled)return!1;return!0}disable(){this.sessionDisabled=!0,console.log("[HookManager] Hooks disabled for this session")}enable(){this.sessionDisabled=!1,console.log("[HookManager] Hooks enabled for this session")}getConfig(){return this.config}async reloadConfig(){let $=await import("node:fs/promises"),Z=await import("node:path");try{let Y=Z.join(process.cwd(),".blade","settings.local.json"),Q=await $.readFile(Y,"utf-8"),X=JSON.parse(Q);if(X.hooks)this.loadConfig(X.hooks)}catch{}}async executePreToolHooks($,Z,Y,Q){if(!this.isEnabled())return{decision:"allow"};if(Q.permissionMode==="plan")return{decision:"allow"};if(!this.guard.canExecute(Z,"PreToolUse"))return{decision:"allow"};let X={hook_event_name:"PreToolUse",hook_execution_id:l1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,project_dir:Q.projectDir,session_id:Q.sessionId,permission_mode:Q.permissionMode},J=this.getMatchingHooks("PreToolUse",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(J.length===0)return{decision:"allow"};let G={projectDir:Q.projectDir,sessionId:Q.sessionId,permissionMode:Q.permissionMode,config:this.config,abortSignal:Q.abortSignal};try{let q=await this.executor.executePreToolHooks(J,X,G);if(this.guard.markExecuted(Z,"PreToolUse"),Q.permissionMode==="yolo"){if(q.decision==="deny")return q;return{decision:"allow",modifiedInput:q.modifiedInput,warning:q.warning,reason:q.reason}}return q}catch(q){return console.error("[HookManager] Error executing PreToolUse hooks:",q),{decision:"allow",warning:`Hook execution failed: ${q instanceof Error?q.message:String(q)}`}}}async executePostToolHooks($,Z,Y,Q,X){if(!this.isEnabled())return{};if(X.permissionMode==="plan")return{};if(!this.guard.canExecute(Z,"PostToolUse"))return{};let J={hook_event_name:"PostToolUse",hook_execution_id:l1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,tool_response:Q,project_dir:X.projectDir,session_id:X.sessionId,permission_mode:X.permissionMode},G=this.getMatchingHooks("PostToolUse",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(G.length===0)return{};let q={projectDir:X.projectDir,sessionId:X.sessionId,permissionMode:X.permissionMode,config:this.config,abortSignal:X.abortSignal};try{let K=await this.executor.executePostToolHooks(G,J,q);return this.guard.markExecuted(Z,"PostToolUse"),K}catch(K){return console.error("[HookManager] Error executing PostToolUse hooks:",K),{warning:`Hook execution failed: ${K instanceof Error?K.message:String(K)}`}}finally{this.guard.cleanup(Z)}}async executeStopHooks($){if(!this.isEnabled())return{shouldStop:!0};let Z={hook_event_name:"Stop",hook_execution_id:l1(),timestamp:new Date().toISOString(),project_dir:$.projectDir,session_id:$.sessionId,permission_mode:$.permissionMode,reason:$.reason},Y=this.getMatchingHooks("Stop",{});if(Y.length===0)return{shouldStop:!0};let Q={projectDir:$.projectDir,sessionId:$.sessionId,permissionMode:$.permissionMode,config:this.config,abortSignal:$.abortSignal};try{return await this.executor.executeStopHooks(Y,Z,Q)}catch(X){return console.error("[HookManager] Error executing Stop hooks:",X),{shouldStop:!0,warning:`Hook execution failed: ${X instanceof Error?X.message:String(X)}`}}}async executeSubagentStopHooks($,Z){if(!this.isEnabled())return{shouldStop:!0};let Y={hook_event_name:"SubagentStop",hook_execution_id:l1(),timestamp:new Date().toISOString(),project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode,agent_type:$,task_description:Z.taskDescription,success:Z.success,result_summary:Z.resultSummary,error:Z.error},Q=this.getMatchingHooks("SubagentStop",{});if(Q.length===0)return{shouldStop:!0};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeSubagentStopHooks(Q,Y,X)}catch(J){return console.error("[HookManager] Error executing SubagentStop hooks:",J),{shouldStop:!0,warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executePermissionRequestHooks($,Z,Y,Q){if(!this.isEnabled())return{decision:"ask"};let X={hook_event_name:"PermissionRequest",hook_execution_id:l1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,project_dir:Q.projectDir,session_id:Q.sessionId,permission_mode:Q.permissionMode},J=this.getMatchingHooks("PermissionRequest",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(J.length===0)return{decision:"ask"};let G={projectDir:Q.projectDir,sessionId:Q.sessionId,permissionMode:Q.permissionMode,config:this.config,abortSignal:Q.abortSignal};try{return await this.executor.executePermissionRequestHooks(J,X,G)}catch(q){return console.error("[HookManager] Error executing PermissionRequest hooks:",q),{decision:"ask",warning:`Hook execution failed: ${q instanceof Error?q.message:String(q)}`}}}async executeUserPromptSubmitHooks($,Z){if(!this.isEnabled())return{proceed:!0};let Y={hook_event_name:"UserPromptSubmit",hook_execution_id:l1(),timestamp:new Date().toISOString(),user_prompt:$,has_images:Z.hasImages,image_count:Z.imageCount,project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode},Q=this.getMatchingHooks("UserPromptSubmit",{});if(Q.length===0)return{proceed:!0};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeUserPromptSubmitHooks(Q,Y,X)}catch(J){return console.error("[HookManager] Error executing UserPromptSubmit hooks:",J),{proceed:!0,warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executeSessionStartHooks($){if(!this.isEnabled())return{proceed:!0};let Z={hook_event_name:"SessionStart",hook_execution_id:l1(),timestamp:new Date().toISOString(),project_dir:$.projectDir,session_id:$.sessionId,permission_mode:$.permissionMode,is_resume:$.isResume,resume_session_id:$.resumeSessionId},Y=this.getMatchingHooks("SessionStart",{});if(Y.length===0)return{proceed:!0};let Q={projectDir:$.projectDir,sessionId:$.sessionId,permissionMode:$.permissionMode,config:this.config,abortSignal:$.abortSignal};try{return await this.executor.executeSessionStartHooks(Y,Z,Q)}catch(X){return console.error("[HookManager] Error executing SessionStart hooks:",X),{proceed:!0,warning:`Hook execution failed: ${X instanceof Error?X.message:String(X)}`}}}async executeSessionEndHooks($,Z){if(!this.isEnabled())return{};let Y={hook_event_name:"SessionEnd",hook_execution_id:l1(),timestamp:new Date().toISOString(),project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode,reason:$},Q=this.getMatchingHooks("SessionEnd",{});if(Q.length===0)return{};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeSessionEndHooks(Q,Y,X),{}}catch(J){return console.error("[HookManager] Error executing SessionEnd hooks:",J),{warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executePostToolUseFailureHooks($,Z,Y,Q,X){if(!this.isEnabled())return{};let J={hook_event_name:"PostToolUseFailure",hook_execution_id:l1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,error:Q,error_type:X.errorType,is_interrupt:X.isInterrupt,is_timeout:X.isTimeout,project_dir:X.projectDir,session_id:X.sessionId,permission_mode:X.permissionMode},G=this.getMatchingHooks("PostToolUseFailure",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(G.length===0)return{};let q={projectDir:X.projectDir,sessionId:X.sessionId,permissionMode:X.permissionMode,config:this.config,abortSignal:X.abortSignal};try{return await this.executor.executePostToolUseFailureHooks(G,J,q)}catch(K){return console.error("[HookManager] Error executing PostToolUseFailure hooks:",K),{warning:`Hook execution failed: ${K instanceof Error?K.message:String(K)}`}}}async executeNotificationHooks($,Z,Y){if(!this.isEnabled())return{suppress:!1,message:Z};let Q={hook_event_name:"Notification",hook_execution_id:l1(),timestamp:new Date().toISOString(),project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode,notification_type:$,title:Y.title,message:Z},X=this.getMatchingHooks("Notification",{});if(X.length===0)return{suppress:!1,message:Z};let J={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:this.config,abortSignal:Y.abortSignal};try{return await this.executor.executeNotificationHooks(X,Q,J)}catch(G){return console.error("[HookManager] Error executing Notification hooks:",G),{suppress:!1,message:Z,warning:`Hook execution failed: ${G instanceof Error?G.message:String(G)}`}}}async executeCompactionHooks($,Z){if(!this.isEnabled())return{blockCompaction:!1};let Y={hook_event_name:"Compaction",hook_execution_id:l1(),timestamp:new Date().toISOString(),project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode,trigger:$,messages_before:Z.messagesBefore,tokens_before:Z.tokensBefore},Q=this.getMatchingHooks("Compaction",{});if(Q.length===0)return{blockCompaction:!1};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeCompactionHooks(Q,Y,X)}catch(J){return console.error("[HookManager] Error executing Compaction hooks:",J),{blockCompaction:!1,warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}getMatchingHooks($,Z){let Y=this.config[$]||[],Q=[];for(let X of Y)if(this.matcher.matches(X.matcher,Z))Q.push(...X.hooks);return Q}extractFilePath($){let Z=["file_path","path","filePath","source","target"];for(let Y of Z){let Q=$[Y];if(typeof Q==="string")return Q}return}extractCommand($,Z){if($==="Bash"||$==="BashTool"){let Y=Z.command;if(typeof Y==="string")return Y}return}cleanup(){this.guard.cleanupAll()}}var Y1=R(()=>{jX();vX();PX();B8()});function q9($){return $==="blade-free-tier"}function K9($){return q9($.apiKey)}var W9=()=>{};var U9,V6,O9,M6,A_,CX=($)=>{return A_[$]||"openai-compatible"},b_,SX=($)=>{return b_[$]||{}};var w8=R(()=>{U9=["anthropic","openai","deepseek","google-generative-ai","groq","openrouter"],V6={antigravity:{bladeProvider:"antigravity",icon:"\uD83D\uDE80",description:"OAuth 登录使用 Claude/Gemini (需 Code Assist 订阅)"},copilot:{bladeProvider:"copilot",icon:"\uD83D\uDC19",description:"OAuth 登录使用 GPT/Claude/Gemini (需 Copilot 订阅)"}},O9={anthropic:"\uD83E\uDD16",openai:"⚡","google-generative-ai":"✨",deepseek:"\uD83C\uDF0A",groq:"\uD83D\uDE80",openrouter:"\uD83D\uDD00",azure:"☁️",ollama:"\uD83E\uDD99",together:"\uD83E\uDD1D",fireworks:"\uD83C\uDF86",mistral:"\uD83C\uDF00",cohere:"\uD83D\uDD2E",perplexity:"\uD83D\uDD0D",xai:"\uD83C\uDD67",default:"\uD83D\uDD0C"},M6={anthropic:"https://api.anthropic.com",openai:"https://api.openai.com/v1",google:"https://generativelanguage.googleapis.com/v1beta",deepseek:"https://api.deepseek.com/v1",groq:"https://api.groq.com/openai/v1",openrouter:"https://openrouter.ai/api/v1",togetherai:"https://api.together.xyz/v1","fireworks-ai":"https://api.fireworks.ai/inference/v1",mistral:"https://api.mistral.ai/v1",cohere:"https://api.cohere.ai/v1",perplexity:"https://api.perplexity.ai",xai:"https://api.x.ai/v1",cerebras:"https://api.cerebras.ai/v1","novita-ai":"https://api.novita.ai/v3/openai",nvidia:"https://integrate.api.nvidia.com/v1"},A_={anthropic:"anthropic",google:"gemini","google-vertex":"gemini","google-vertex-anthropic":"anthropic",azure:"azure-openai"},b_={anthropic:{"anthropic-beta":"claude-code-20250219,interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14"},openrouter:{"HTTP-Referer":"https://github.com/anthropics/blade","X-Title":"Blade"},cerebras:{"X-Cerebras-3rd-Party-Integration":"blade"},vercel:{"http-referer":"https://github.com/anthropics/blade","x-title":"blade"},zenmux:{"HTTP-Referer":"https://github.com/anthropics/blade","X-Title":"blade"}}});import{ProxyAgent as R_,fetch as V_}from"undici";function M_(){return process.env.HTTPS_PROXY||process.env.HTTP_PROXY||process.env.https_proxy||process.env.http_proxy}function D_(){let $=M_();if($)try{return new R_($)}catch(Z){console.warn(`[proxyFetch] Invalid proxy URL: ${$}`)}return}async function V$($,Z={}){let{timeout:Y=30000,signal:Q,...X}=Z;if(Q?.aborted)throw new DOMException("The operation was aborted.","AbortError");let J=D_(),G=new AbortController,q=!1,K=setTimeout(()=>{q=!0,G.abort()},Y),W=()=>G.abort();Q?.addEventListener("abort",W);try{let U={method:X.method,headers:X.headers,body:X.body,signal:G.signal,dispatcher:J};return await V_($.toString(),U)}catch(U){if(U instanceof Error&&U.name==="AbortError"){if(q)throw Error(`Request timeout after ${Y}ms`);throw U}throw U}finally{clearTimeout(K),Q?.removeEventListener("abort",W)}}var E4=()=>{};var kX,fX,B3,w3,L3,D6;var N3=R(()=>{kX={authorizationUrl:"https://accounts.google.com/o/oauth2/v2/auth",tokenUrl:"https://oauth2.googleapis.com/token",scopes:["https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/userinfo.profile","https://www.googleapis.com/auth/cclog","https://www.googleapis.com/auth/experimentsandconfigs"],clientId:"1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com",clientSecret:"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",redirectPort:51121,redirectPath:"/oauth-callback"},fX={authorizationUrl:"https://accounts.google.com/o/oauth2/v2/auth",tokenUrl:"https://oauth2.googleapis.com/token",scopes:["https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/userinfo.profile"],clientId:"681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com",clientSecret:"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",redirectPort:45289,redirectPath:"/"},B3={production:"https://cloudcode-pa.googleapis.com",sandbox:"https://daily-cloudcode-pa.sandbox.googleapis.com"},w3={generateContent:"/v1internal:generateContent",streamGenerateContent:"/v1internal:streamGenerateContent",loadCodeAssist:"/v1internal:loadCodeAssist",onboardUser:"/v1internal:onboardUser"},L3={"claude-sonnet-4-5":{id:"claude-sonnet-4-5",name:"Claude Sonnet 4.5",provider:"anthropic",supportsThinking:!1,description:"平衡速度与质量的 Claude 模型"},"claude-sonnet-4-5-thinking":{id:"claude-sonnet-4-5-thinking",name:"Claude Sonnet 4.5 (Thinking)",provider:"anthropic",supportsThinking:!0,description:"支持思维链的 Claude Sonnet"},"claude-opus-4-5-thinking":{id:"claude-opus-4-5-thinking",name:"Claude Opus 4.5 (Thinking)",provider:"anthropic",supportsThinking:!0,description:"最强 Claude 模型,支持思维链"},"gemini-3-pro-high":{id:"gemini-3-pro-high",name:"Gemini 3 Pro (High)",provider:"google",supportsThinking:!1,description:"高质量 Gemini 模型 (Pro)"},"gemini-3-pro-low":{id:"gemini-3-pro-low",name:"Gemini 3 Pro (Low)",provider:"google",supportsThinking:!1,description:"快速 Gemini 模型 (Pro)"},"gemini-3-flash":{id:"gemini-3-flash",name:"Gemini 3 Flash",provider:"google",supportsThinking:!1,description:"超快速 Gemini 模型 (Pro)"},"gpt-oss-120b-medium":{id:"gpt-oss-120b-medium",name:"GPT-OSS 120B Medium",provider:"openai-oss",supportsThinking:!1,description:"OpenAI 开源模型"}},D6={"gemini-2.5-pro":{id:"gemini-2.5-pro",name:"Gemini 2.5 Pro",provider:"google",supportsThinking:!1,description:"最强 Gemini 2.5 模型,1M 上下文"},"gemini-2.5-flash":{id:"gemini-2.5-flash",name:"Gemini 2.5 Flash",provider:"google",supportsThinking:!1,description:"快速 Gemini 2.5 模型"},"gemini-2.5-flash-lite":{id:"gemini-2.5-flash-lite",name:"Gemini 2.5 Flash Lite",provider:"google",supportsThinking:!1,description:"轻量级 Gemini 2.5 模型"}}});import{spawn as j_}from"child_process";import*as b3 from"crypto";import*as l2 from"fs/promises";import*as xX from"http";import*as A3 from"path";import{URL as y_}from"url";function hX($){return $==="gemini-cli"?fX:kX}function H9(){let $=process.env.HOME||process.env.USERPROFILE||"";return A3.join($,".blade")}class p${static instance=null;cachedToken=null;constructor(){}static getInstance(){if(!p$.instance)p$.instance=new p$;return p$.instance}async isLoggedIn(){let $=await this.loadToken();if(!$)return!1;let Z=300000;if($.expiresAt&&Date.now()>$.expiresAt-Z){if($.refreshToken)try{return await this.refreshToken(),!0}catch{return!1}return!1}return!0}async login($="antigravity"){let Z=$==="gemini-cli"?"Gemini CLI":"Antigravity";c2.info(`\uD83D\uDD10 Starting ${Z} OAuth login...`);let Y=hX($),Q=this.generatePKCEParams(),X=this.buildAuthorizationUrl(Q,Y);console.log(`
154
+ `):void 0}}async executeHook($,Z,Y){if($.type==="command")return this.executeCommandHook($,Z,Y);throw Error(`Hook type ${$.type} not yet implemented`)}async executeCommandHook($,Z,Y){let Q=($.timeout??Y.config.defaultTimeout??60)*1000;try{let X=await this.processExecutor.execute($.command,Z,Y,Q);return this.outputParser.parse(X,$,{timeoutBehavior:Y.config.timeoutBehavior,failureBehavior:Y.config.failureBehavior})}catch(X){return{success:!1,blocking:!1,error:X instanceof Error?X.message:String(X),hook:$}}}async executeHooksConcurrently($,Z,Y,Q){let X=[],J=new Set;for(let G of $){if(J.size>=Q)await Promise.race(J);let q=this.executeHook(G,Z,Y).catch((W)=>({success:!1,blocking:!1,error:W instanceof Error?W.message:String(W),hook:G})),K=q.then(()=>{J.delete(K)}).catch(()=>{J.delete(K)});J.add(K),X.push(q)}return Promise.all(X)}}var vX=R(()=>{EX();IX();B8()});import J9 from"picomatch";class G9{matches($,Z){if(!$)return!0;if($.tools&&Z.toolName){if(!this.matchTools($.tools,Z))return!1}if($.paths&&Z.filePath){if(!this.matchPaths($.paths,Z.filePath))return!1}if($.commands&&Z.command){if(!this.matchCommands($.commands,Z.command))return!1}return!0}matchTools($,Z){if(Array.isArray($))return $.some((Y)=>this.matchToolWithParams(Y,Z));return this.matchToolWithParams($,Z)}matchPaths($,Z){if(Array.isArray($))return $.some((Q)=>{return J9(Q)(Z)});return J9($)(Z)}matchCommands($,Z){if(Array.isArray($))return $.some((Y)=>this.matchPattern(Z,Y));return this.matchPattern(Z,$)}matchToolWithParams($,Z){let{toolName:Y,command:Q,filePath:X}=Z,J=N_.exec($);if(!J)return this.matchPattern(Y,$);let[,G,q]=J;if(!this.matchPattern(Y,G))return!1;let K=this.getArgValue(Y,Q,X);if(!K)return!1;return this.matchGlobOrPattern(K,q)}getArgValue($,Z,Y){if($==="Bash"||$==="BashTool")return Z;if(["Read","Edit","Write","Glob","Grep"].includes($))return Y;return Z||Y}matchGlobOrPattern($,Z){if(/[*?[\]{}!]/.test(Z))try{return J9(Z,{bash:!0,dot:!0})($)}catch{}if(Z.endsWith("*")){let Y=Z.slice(0,-1);return $.startsWith(Y)}return $===Z}matchPattern($,Z){if(Z==="*")return!0;if(!Z.includes("|")&&!/[.*+?^${}()|[\]\\]/.test(Z))return $===Z;if(Z.includes("|"))return Z.split("|").map((Q)=>Q.trim()).includes($);try{return new RegExp(Z).test($)}catch{return $===Z}}}var N_;var PX=R(()=>{N_=/^([A-Za-z0-9_|]+)\((.+)\)$/});import{nanoid as l1}from"nanoid";class y0{static instance=null;config=n5;executor=new X9;guard=new s5;matcher=new G9;sessionDisabled=!1;constructor(){}static getInstance(){if(!y0.instance)y0.instance=new y0;return y0.instance}loadConfig($){let Z=o5(n5,$),Y=DX();Z=o5(Z,Y),this.config=Z}isEnabled(){if(!this.config.enabled)return!1;if(this.sessionDisabled)return!1;return!0}disable(){this.sessionDisabled=!0,console.log("[HookManager] Hooks disabled for this session")}enable(){this.sessionDisabled=!1,console.log("[HookManager] Hooks enabled for this session")}getConfig(){return this.config}async reloadConfig(){let $=await import("node:fs/promises"),Z=await import("node:path");try{let Y=Z.join(process.cwd(),".blade","settings.local.json"),Q=await $.readFile(Y,"utf-8"),X=JSON.parse(Q);if(X.hooks)this.loadConfig(X.hooks)}catch{}}async executePreToolHooks($,Z,Y,Q){if(!this.isEnabled())return{decision:"allow"};if(Q.permissionMode==="plan")return{decision:"allow"};if(!this.guard.canExecute(Z,"PreToolUse"))return{decision:"allow"};let X={hook_event_name:"PreToolUse",hook_execution_id:l1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,project_dir:Q.projectDir,session_id:Q.sessionId,permission_mode:Q.permissionMode},J=this.getMatchingHooks("PreToolUse",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(J.length===0)return{decision:"allow"};let G={projectDir:Q.projectDir,sessionId:Q.sessionId,permissionMode:Q.permissionMode,config:this.config,abortSignal:Q.abortSignal};try{let q=await this.executor.executePreToolHooks(J,X,G);if(this.guard.markExecuted(Z,"PreToolUse"),Q.permissionMode==="yolo"){if(q.decision==="deny")return q;return{decision:"allow",modifiedInput:q.modifiedInput,warning:q.warning,reason:q.reason}}return q}catch(q){return console.error("[HookManager] Error executing PreToolUse hooks:",q),{decision:"allow",warning:`Hook execution failed: ${q instanceof Error?q.message:String(q)}`}}}async executePostToolHooks($,Z,Y,Q,X){if(!this.isEnabled())return{};if(X.permissionMode==="plan")return{};if(!this.guard.canExecute(Z,"PostToolUse"))return{};let J={hook_event_name:"PostToolUse",hook_execution_id:l1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,tool_response:Q,project_dir:X.projectDir,session_id:X.sessionId,permission_mode:X.permissionMode},G=this.getMatchingHooks("PostToolUse",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(G.length===0)return{};let q={projectDir:X.projectDir,sessionId:X.sessionId,permissionMode:X.permissionMode,config:this.config,abortSignal:X.abortSignal};try{let K=await this.executor.executePostToolHooks(G,J,q);return this.guard.markExecuted(Z,"PostToolUse"),K}catch(K){return console.error("[HookManager] Error executing PostToolUse hooks:",K),{warning:`Hook execution failed: ${K instanceof Error?K.message:String(K)}`}}finally{this.guard.cleanup(Z)}}async executeStopHooks($){if(!this.isEnabled())return{shouldStop:!0};let Z={hook_event_name:"Stop",hook_execution_id:l1(),timestamp:new Date().toISOString(),project_dir:$.projectDir,session_id:$.sessionId,permission_mode:$.permissionMode,reason:$.reason},Y=this.getMatchingHooks("Stop",{});if(Y.length===0)return{shouldStop:!0};let Q={projectDir:$.projectDir,sessionId:$.sessionId,permissionMode:$.permissionMode,config:this.config,abortSignal:$.abortSignal};try{return await this.executor.executeStopHooks(Y,Z,Q)}catch(X){return console.error("[HookManager] Error executing Stop hooks:",X),{shouldStop:!0,warning:`Hook execution failed: ${X instanceof Error?X.message:String(X)}`}}}async executeSubagentStopHooks($,Z){if(!this.isEnabled())return{shouldStop:!0};let Y={hook_event_name:"SubagentStop",hook_execution_id:l1(),timestamp:new Date().toISOString(),project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode,agent_type:$,task_description:Z.taskDescription,success:Z.success,result_summary:Z.resultSummary,error:Z.error},Q=this.getMatchingHooks("SubagentStop",{});if(Q.length===0)return{shouldStop:!0};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeSubagentStopHooks(Q,Y,X)}catch(J){return console.error("[HookManager] Error executing SubagentStop hooks:",J),{shouldStop:!0,warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executePermissionRequestHooks($,Z,Y,Q){if(!this.isEnabled())return{decision:"ask"};let X={hook_event_name:"PermissionRequest",hook_execution_id:l1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,project_dir:Q.projectDir,session_id:Q.sessionId,permission_mode:Q.permissionMode},J=this.getMatchingHooks("PermissionRequest",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(J.length===0)return{decision:"ask"};let G={projectDir:Q.projectDir,sessionId:Q.sessionId,permissionMode:Q.permissionMode,config:this.config,abortSignal:Q.abortSignal};try{return await this.executor.executePermissionRequestHooks(J,X,G)}catch(q){return console.error("[HookManager] Error executing PermissionRequest hooks:",q),{decision:"ask",warning:`Hook execution failed: ${q instanceof Error?q.message:String(q)}`}}}async executeUserPromptSubmitHooks($,Z){if(!this.isEnabled())return{proceed:!0};let Y={hook_event_name:"UserPromptSubmit",hook_execution_id:l1(),timestamp:new Date().toISOString(),user_prompt:$,has_images:Z.hasImages,image_count:Z.imageCount,project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode},Q=this.getMatchingHooks("UserPromptSubmit",{});if(Q.length===0)return{proceed:!0};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeUserPromptSubmitHooks(Q,Y,X)}catch(J){return console.error("[HookManager] Error executing UserPromptSubmit hooks:",J),{proceed:!0,warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executeSessionStartHooks($){if(!this.isEnabled())return{proceed:!0};let Z={hook_event_name:"SessionStart",hook_execution_id:l1(),timestamp:new Date().toISOString(),project_dir:$.projectDir,session_id:$.sessionId,permission_mode:$.permissionMode,is_resume:$.isResume,resume_session_id:$.resumeSessionId},Y=this.getMatchingHooks("SessionStart",{});if(Y.length===0)return{proceed:!0};let Q={projectDir:$.projectDir,sessionId:$.sessionId,permissionMode:$.permissionMode,config:this.config,abortSignal:$.abortSignal};try{return await this.executor.executeSessionStartHooks(Y,Z,Q)}catch(X){return console.error("[HookManager] Error executing SessionStart hooks:",X),{proceed:!0,warning:`Hook execution failed: ${X instanceof Error?X.message:String(X)}`}}}async executeSessionEndHooks($,Z){if(!this.isEnabled())return{};let Y={hook_event_name:"SessionEnd",hook_execution_id:l1(),timestamp:new Date().toISOString(),project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode,reason:$},Q=this.getMatchingHooks("SessionEnd",{});if(Q.length===0)return{};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeSessionEndHooks(Q,Y,X),{}}catch(J){return console.error("[HookManager] Error executing SessionEnd hooks:",J),{warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executePostToolUseFailureHooks($,Z,Y,Q,X){if(!this.isEnabled())return{};let J={hook_event_name:"PostToolUseFailure",hook_execution_id:l1(),timestamp:new Date().toISOString(),tool_name:$,tool_use_id:Z,tool_input:Y,error:Q,error_type:X.errorType,is_interrupt:X.isInterrupt,is_timeout:X.isTimeout,project_dir:X.projectDir,session_id:X.sessionId,permission_mode:X.permissionMode},G=this.getMatchingHooks("PostToolUseFailure",{toolName:$,filePath:this.extractFilePath(Y),command:this.extractCommand($,Y)});if(G.length===0)return{};let q={projectDir:X.projectDir,sessionId:X.sessionId,permissionMode:X.permissionMode,config:this.config,abortSignal:X.abortSignal};try{return await this.executor.executePostToolUseFailureHooks(G,J,q)}catch(K){return console.error("[HookManager] Error executing PostToolUseFailure hooks:",K),{warning:`Hook execution failed: ${K instanceof Error?K.message:String(K)}`}}}async executeNotificationHooks($,Z,Y){if(!this.isEnabled())return{suppress:!1,message:Z};let Q={hook_event_name:"Notification",hook_execution_id:l1(),timestamp:new Date().toISOString(),project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode,notification_type:$,title:Y.title,message:Z},X=this.getMatchingHooks("Notification",{});if(X.length===0)return{suppress:!1,message:Z};let J={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:this.config,abortSignal:Y.abortSignal};try{return await this.executor.executeNotificationHooks(X,Q,J)}catch(G){return console.error("[HookManager] Error executing Notification hooks:",G),{suppress:!1,message:Z,warning:`Hook execution failed: ${G instanceof Error?G.message:String(G)}`}}}async executeCompactionHooks($,Z){if(!this.isEnabled())return{blockCompaction:!1};let Y={hook_event_name:"Compaction",hook_execution_id:l1(),timestamp:new Date().toISOString(),project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode,trigger:$,messages_before:Z.messagesBefore,tokens_before:Z.tokensBefore},Q=this.getMatchingHooks("Compaction",{});if(Q.length===0)return{blockCompaction:!1};let X={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeCompactionHooks(Q,Y,X)}catch(J){return console.error("[HookManager] Error executing Compaction hooks:",J),{blockCompaction:!1,warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}getMatchingHooks($,Z){let Y=this.config[$]||[],Q=[];for(let X of Y)if(this.matcher.matches(X.matcher,Z))Q.push(...X.hooks);return Q}extractFilePath($){let Z=["file_path","path","filePath","source","target"];for(let Y of Z){let Q=$[Y];if(typeof Q==="string")return Q}return}extractCommand($,Z){if($==="Bash"||$==="BashTool"){let Y=Z.command;if(typeof Y==="string")return Y}return}cleanup(){this.guard.cleanupAll()}}var Y1=R(()=>{jX();vX();PX();B8()});function q9($){return $==="blade-free-tier"}function K9($){return q9($.apiKey)}var W9=()=>{};var U9,V7,O9,M7,A_,CX=($)=>{return A_[$]||"openai-compatible"},b_,SX=($)=>{return b_[$]||{}};var w8=R(()=>{U9=["anthropic","openai","deepseek","google-generative-ai","groq","openrouter"],V7={antigravity:{bladeProvider:"antigravity",icon:"\uD83D\uDE80",description:"OAuth 登录使用 Claude/Gemini (需 Code Assist 订阅)"},copilot:{bladeProvider:"copilot",icon:"\uD83D\uDC19",description:"OAuth 登录使用 GPT/Claude/Gemini (需 Copilot 订阅)"}},O9={anthropic:"\uD83E\uDD16",openai:"⚡","google-generative-ai":"✨",deepseek:"\uD83C\uDF0A",groq:"\uD83D\uDE80",openrouter:"\uD83D\uDD00",azure:"☁️",ollama:"\uD83E\uDD99",together:"\uD83E\uDD1D",fireworks:"\uD83C\uDF86",mistral:"\uD83C\uDF00",cohere:"\uD83D\uDD2E",perplexity:"\uD83D\uDD0D",xai:"\uD83C\uDD67",default:"\uD83D\uDD0C"},M7={anthropic:"https://api.anthropic.com",openai:"https://api.openai.com/v1",google:"https://generativelanguage.googleapis.com/v1beta",deepseek:"https://api.deepseek.com/v1",groq:"https://api.groq.com/openai/v1",openrouter:"https://openrouter.ai/api/v1",togetherai:"https://api.together.xyz/v1","fireworks-ai":"https://api.fireworks.ai/inference/v1",mistral:"https://api.mistral.ai/v1",cohere:"https://api.cohere.ai/v1",perplexity:"https://api.perplexity.ai",xai:"https://api.x.ai/v1",cerebras:"https://api.cerebras.ai/v1","novita-ai":"https://api.novita.ai/v3/openai",nvidia:"https://integrate.api.nvidia.com/v1"},A_={anthropic:"anthropic",google:"gemini","google-vertex":"gemini","google-vertex-anthropic":"anthropic",azure:"azure-openai"},b_={anthropic:{"anthropic-beta":"claude-code-20250219,interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14"},openrouter:{"HTTP-Referer":"https://github.com/anthropics/blade","X-Title":"Blade"},cerebras:{"X-Cerebras-3rd-Party-Integration":"blade"},vercel:{"http-referer":"https://github.com/anthropics/blade","x-title":"blade"},zenmux:{"HTTP-Referer":"https://github.com/anthropics/blade","X-Title":"blade"}}});import{ProxyAgent as R_,fetch as V_}from"undici";function M_(){return process.env.HTTPS_PROXY||process.env.HTTP_PROXY||process.env.https_proxy||process.env.http_proxy}function D_(){let $=M_();if($)try{return new R_($)}catch(Z){console.warn(`[proxyFetch] Invalid proxy URL: ${$}`)}return}async function V$($,Z={}){let{timeout:Y=30000,signal:Q,...X}=Z;if(Q?.aborted)throw new DOMException("The operation was aborted.","AbortError");let J=D_(),G=new AbortController,q=!1,K=setTimeout(()=>{q=!0,G.abort()},Y),W=()=>G.abort();Q?.addEventListener("abort",W);try{let U={method:X.method,headers:X.headers,body:X.body,signal:G.signal,dispatcher:J};return await V_($.toString(),U)}catch(U){if(U instanceof Error&&U.name==="AbortError"){if(q)throw Error(`Request timeout after ${Y}ms`);throw U}throw U}finally{clearTimeout(K),Q?.removeEventListener("abort",W)}}var E4=()=>{};var kX,fX,B3,w3,L3,D7;var N3=R(()=>{kX={authorizationUrl:"https://accounts.google.com/o/oauth2/v2/auth",tokenUrl:"https://oauth2.googleapis.com/token",scopes:["https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/userinfo.profile","https://www.googleapis.com/auth/cclog","https://www.googleapis.com/auth/experimentsandconfigs"],clientId:"1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com",clientSecret:"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",redirectPort:51121,redirectPath:"/oauth-callback"},fX={authorizationUrl:"https://accounts.google.com/o/oauth2/v2/auth",tokenUrl:"https://oauth2.googleapis.com/token",scopes:["https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/userinfo.profile"],clientId:"681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com",clientSecret:"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",redirectPort:45289,redirectPath:"/"},B3={production:"https://cloudcode-pa.googleapis.com",sandbox:"https://daily-cloudcode-pa.sandbox.googleapis.com"},w3={generateContent:"/v1internal:generateContent",streamGenerateContent:"/v1internal:streamGenerateContent",loadCodeAssist:"/v1internal:loadCodeAssist",onboardUser:"/v1internal:onboardUser"},L3={"claude-sonnet-4-5":{id:"claude-sonnet-4-5",name:"Claude Sonnet 4.5",provider:"anthropic",supportsThinking:!1,description:"平衡速度与质量的 Claude 模型"},"claude-sonnet-4-5-thinking":{id:"claude-sonnet-4-5-thinking",name:"Claude Sonnet 4.5 (Thinking)",provider:"anthropic",supportsThinking:!0,description:"支持思维链的 Claude Sonnet"},"claude-opus-4-5-thinking":{id:"claude-opus-4-5-thinking",name:"Claude Opus 4.5 (Thinking)",provider:"anthropic",supportsThinking:!0,description:"最强 Claude 模型,支持思维链"},"gemini-3-pro-high":{id:"gemini-3-pro-high",name:"Gemini 3 Pro (High)",provider:"google",supportsThinking:!1,description:"高质量 Gemini 模型 (Pro)"},"gemini-3-pro-low":{id:"gemini-3-pro-low",name:"Gemini 3 Pro (Low)",provider:"google",supportsThinking:!1,description:"快速 Gemini 模型 (Pro)"},"gemini-3-flash":{id:"gemini-3-flash",name:"Gemini 3 Flash",provider:"google",supportsThinking:!1,description:"超快速 Gemini 模型 (Pro)"},"gpt-oss-120b-medium":{id:"gpt-oss-120b-medium",name:"GPT-OSS 120B Medium",provider:"openai-oss",supportsThinking:!1,description:"OpenAI 开源模型"}},D7={"gemini-2.5-pro":{id:"gemini-2.5-pro",name:"Gemini 2.5 Pro",provider:"google",supportsThinking:!1,description:"最强 Gemini 2.5 模型,1M 上下文"},"gemini-2.5-flash":{id:"gemini-2.5-flash",name:"Gemini 2.5 Flash",provider:"google",supportsThinking:!1,description:"快速 Gemini 2.5 模型"},"gemini-2.5-flash-lite":{id:"gemini-2.5-flash-lite",name:"Gemini 2.5 Flash Lite",provider:"google",supportsThinking:!1,description:"轻量级 Gemini 2.5 模型"}}});import{spawn as j_}from"child_process";import*as b3 from"crypto";import*as l2 from"fs/promises";import*as xX from"http";import*as A3 from"path";import{URL as y_}from"url";function hX($){return $==="gemini-cli"?fX:kX}function H9(){let $=process.env.HOME||process.env.USERPROFILE||"";return A3.join($,".blade")}class p${static instance=null;cachedToken=null;constructor(){}static getInstance(){if(!p$.instance)p$.instance=new p$;return p$.instance}async isLoggedIn(){let $=await this.loadToken();if(!$)return!1;let Z=300000;if($.expiresAt&&Date.now()>$.expiresAt-Z){if($.refreshToken)try{return await this.refreshToken(),!0}catch{return!1}return!1}return!0}async login($="antigravity"){let Z=$==="gemini-cli"?"Gemini CLI":"Antigravity";c2.info(`\uD83D\uDD10 Starting ${Z} OAuth login...`);let Y=hX($),Q=this.generatePKCEParams(),X=this.buildAuthorizationUrl(Q,Y);console.log(`
155
155
  \uD83C\uDF10 Opening browser for Google authentication...`),console.log(`
156
156
  If the browser does not open automatically, copy and paste this URL:`),console.log(X),console.log("");let J=this.startCallbackServer(Q.state,Y);try{await this.openBrowser(X)}catch(W){c2.warn("Failed to open browser automatically:",W)}let G=await J;console.log("✅ Authorization code received, exchanging for tokens...");let q=await this.exchangeCodeForToken(G,Q.codeVerifier,Y),K={accessToken:q.access_token,refreshToken:q.refresh_token||"",expiresAt:Date.now()+q.expires_in*1000,tokenType:q.token_type||"Bearer",scope:q.scope,configType:$};await this.saveToken(K),this.cachedToken=K,console.log(`✅ ${Z} login successful!`),c2.info(`${Z} OAuth login completed`)}async logout(){let $=A3.join(H9(),F9);try{await l2.unlink($),this.cachedToken=null,console.log("✅ Logged out from Antigravity"),c2.info("Antigravity logout completed")}catch(Z){if(Z.code!=="ENOENT")throw Z;this.cachedToken=null}}async getAccessToken(){if(this.cachedToken){if(this.cachedToken.expiresAt>Date.now()+300000)return this.cachedToken.accessToken}let $=await this.loadToken();if(!$)throw Error("Not logged in. Please run /login first.");let Z=300000;if($.expiresAt<=Date.now()+Z){if(!$.refreshToken)throw Error("Token expired and no refresh token available. Please run /login again.");return await this.refreshToken(),this.cachedToken.accessToken}return this.cachedToken=$,$.accessToken}async refreshToken(){let $=await this.loadToken();if(!$||!$.refreshToken)throw Error("No refresh token available");let Z=$.configType||"antigravity",Y=hX(Z),Q=Z==="gemini-cli"?"Gemini CLI":"Antigravity";c2.info(`\uD83D\uDD04 Refreshing ${Q} access token...`);let X=new URLSearchParams({grant_type:"refresh_token",refresh_token:$.refreshToken,client_id:Y.clientId,client_secret:Y.clientSecret}),J=await V$(Y.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:X.toString()});if(!J.ok){let K=await J.text();throw c2.error("Token refresh failed:",K),Error(`Token refresh failed: ${J.status}`)}let G=await J.json(),q={accessToken:G.access_token,refreshToken:G.refresh_token||$.refreshToken,expiresAt:Date.now()+G.expires_in*1000,tokenType:G.token_type||"Bearer",scope:G.scope||$.scope,configType:Z};await this.saveToken(q),this.cachedToken=q,c2.info("✅ Token refreshed successfully")}generatePKCEParams(){let $=b3.randomBytes(32).toString("base64url"),Z=b3.createHash("sha256").update($).digest("base64url"),Y=b3.randomBytes(16).toString("base64url");return{codeVerifier:$,codeChallenge:Z,state:Y}}buildAuthorizationUrl($,Z){let Y=`http://localhost:${Z.redirectPort}${Z.redirectPath}`,Q=new URLSearchParams({client_id:Z.clientId,response_type:"code",redirect_uri:Y,state:$.state,code_challenge:$.codeChallenge,code_challenge_method:"S256",scope:Z.scopes.join(" "),access_type:"offline",prompt:"consent"});return`${Z.authorizationUrl}?${Q.toString()}`}async startCallbackServer($,Z){let{redirectPort:Y,redirectPath:Q}=Z;return new Promise((X,J)=>{let G=null,q=!1,K=()=>{if(G)clearTimeout(G),G=null},W=xX.createServer((U,O)=>{try{let F=new y_(U.url,`http://localhost:${Y}`);if(F.pathname!==Q){O.writeHead(404),O.end("Not found");return}let H=F.searchParams.get("code"),_=F.searchParams.get("state"),z=F.searchParams.get("error");if(z){if(O.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),O.end(`
157
157
  <html>
@@ -171,21 +171,21 @@ If the browser does not open automatically, copy and paste this URL:`),console.l
171
171
  <script>setTimeout(() => window.close(), 2000);</script>
172
172
  </body>
173
173
  </html>
174
- `),K(),W.close(),!q)q=!0,X(H)}catch(F){if(K(),W.close(),!q)q=!0,J(F)}});W.on("error",(U)=>{if(K(),!q)if(q=!0,U.code==="EADDRINUSE")J(Error(`Port ${Y} is already in use. Please close other applications using this port.`));else J(U)}),W.listen(Y,()=>{c2.debug(`OAuth callback server listening on port ${Y}`)}),G=setTimeout(()=>{if(W.close(),!q)q=!0,J(Error("OAuth callback timeout (5 minutes)"))},300000)})}async exchangeCodeForToken($,Z,Y){let Q=`http://localhost:${Y.redirectPort}${Y.redirectPath}`,X=new URLSearchParams({grant_type:"authorization_code",code:$,redirect_uri:Q,code_verifier:Z,client_id:Y.clientId,client_secret:Y.clientSecret}),J=await V$(Y.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:X.toString()});if(!J.ok){let G=await J.text();throw Error(`Token exchange failed: ${J.status} - ${G}`)}return await J.json()}async openBrowser($){let Z,Y;if(process.platform==="darwin")Z="open",Y=[$];else if(process.platform==="win32")Z="cmd",Y=["/c","start","",$];else Z="xdg-open",Y=[$];await new Promise((Q,X)=>{let J=j_(Z,Y,{stdio:"ignore"});J.once("error",X),J.once("close",(G)=>{if(G===0||G===null)Q();else X(Error(`Failed to open browser (exit code ${G})`))})})}async saveToken($){let Z=H9();await l2.mkdir(Z,{recursive:!0,mode:493});let Y=A3.join(Z,F9);await l2.writeFile(Y,JSON.stringify($,null,2),{mode:384})}async loadToken(){let $=A3.join(H9(),F9);try{let Z=await l2.readFile($,"utf-8");return JSON.parse(Z)}catch(Z){if(Z.code==="ENOENT")return null;throw Z}}async getStatus(){let $=await this.loadToken();if(!$)return{loggedIn:!1};return{loggedIn:!0,expiresAt:$.expiresAt?new Date($.expiresAt):void 0,configType:$.configType||"antigravity"}}async getConfigType(){let $=await this.loadToken();if(!$)return null;return $.configType||"antigravity"}}var c2,F9="antigravity-token.json";var R3=R(()=>{Q0();E4();N3();c2=x("Service")});function pX($){if($==="antigravity")return{ideType:"ANTIGRAVITY"};return{ideType:"IDE_UNSPECIFIED",platform:"PLATFORM_UNSPECIFIED",pluginType:"GEMINI"}}function j6($){if($==="antigravity")return"antigravity/1.11.3 Darwin/arm64";return"gemini-cli/1.0.0"}function mX($){let Z=new Set;for(let Y of $)if(Y.role==="assistant"&&Y.tool_calls)for(let Q of Y.tool_calls)Z.add(Q.id);return $.filter((Y)=>{if(Y.role==="tool"){if(!Y.tool_call_id)return!1;return Z.has(Y.tool_call_id)}return!0})}function y6($){if(typeof $==="string")return $;return $.filter((Z)=>Z.type==="text").map((Z)=>Z.text).join(`
175
- `)}function _9($){let Z=["const","$ref","$defs","$schema","$id","default","examples"],Y={};for(let[Q,X]of Object.entries($)){if(Z.includes(Q)){if(Q==="const")Y.enum=[X];continue}if(X&&typeof X==="object"&&!Array.isArray(X))Y[Q]=_9(X);else if(Array.isArray(X))Y[Q]=X.map((J)=>J&&typeof J==="object"&&!Array.isArray(J)?_9(J):J);else Y[Q]=X}return Y}class z9{config;auth;projectId;userTier;sessionId;configType="antigravity";projectIdInitialized=!1;constructor($){this.config=$,this.auth=p$.getInstance(),this.projectId=void 0,this.sessionId=`session_${Date.now()}_${Math.random().toString(36).slice(2,11)}`,v0.debug("\uD83D\uDE80 [AntigravityChatService] Initializing"),v0.debug("⚙️ [AntigravityChatService] Config:",{model:$.model,temperature:$.temperature,maxOutputTokens:$.maxOutputTokens,sessionId:this.sessionId})}async ensureProjectId(){if(this.projectIdInitialized)return;try{let $=await this.auth.getConfigType();this.configType=$||"antigravity",v0.debug(`\uD83D\uDD04 [AntigravityChatService] Using OAuth config: ${this.configType}`),v0.debug("\uD83D\uDD04 [AntigravityChatService] Setting up user via loadCodeAssist...");let Z=await this.auth.getAccessToken(),Y=await this.callLoadCodeAssist(Z);if(v0.debug("[AntigravityChatService] loadCodeAssist response:",JSON.stringify(Y)),Y.currentTier){if(this.userTier=Y.currentTier.id,Y.cloudaicompanionProject){this.projectId=Y.cloudaicompanionProject,v0.debug(`✅ [AntigravityChatService] User already setup: tier=${this.userTier}, project=${this.projectId}`),this.projectIdInitialized=!0;return}let J=process.env.GOOGLE_CLOUD_PROJECT||process.env.GOOGLE_CLOUD_PROJECT_ID;if(J){this.projectId=J,v0.debug(`✅ [AntigravityChatService] Using env project: ${this.projectId}`),this.projectIdInitialized=!0;return}v0.debug("⚠️ [AntigravityChatService] Has tier but no project, need onboarding...")}let Q=this.getDefaultTier(Y);v0.debug(`\uD83D\uDD04 [AntigravityChatService] Onboarding user with tier: ${Q.id}`);let X=await this.callOnboardUser(Z,Q.id);this.projectId=X.projectId,this.userTier=Q.id,v0.debug(`✅ [AntigravityChatService] User setup complete: tier=${this.userTier}, project=${this.projectId||"(managed)"}`)}catch($){v0.warn("Failed to setup user:",$)}this.projectIdInitialized=!0}async callLoadCodeAssist($){let Z=`${B3.production}${w3.loadCodeAssist}`,Y=pX(this.configType),Q=j6(this.configType),X=await V$(Z,{method:"POST",headers:{Authorization:`Bearer ${$}`,"Content-Type":"application/json","User-Agent":Q},body:JSON.stringify({metadata:Y})});if(!X.ok){let J=await X.text();throw Error(`loadCodeAssist failed: ${X.status} - ${J}`)}return await X.json()}getDefaultTier($){for(let Z of $.allowedTiers||[])if(Z.isDefault)return{id:Z.id};return{id:"free-tier"}}async callOnboardUser($,Z){let Y=`${B3.production}${w3.onboardUser}`,Q=pX(this.configType),X=j6(this.configType),J={tierId:Z,metadata:Q};if(Z!=="free-tier"){let K=process.env.GOOGLE_CLOUD_PROJECT||process.env.GOOGLE_CLOUD_PROJECT_ID;if(K)J.cloudaicompanionProject=K,J.metadata={...Q,duetProject:K}}let G=0,q=30;while(G<q){let K=await V$(Y,{method:"POST",headers:{Authorization:`Bearer ${$}`,"Content-Type":"application/json","User-Agent":X},body:JSON.stringify(J)});if(!K.ok){let U=await K.text();throw Error(`onboardUser failed: ${K.status} - ${U}`)}let W=await K.json();if(v0.debug(`[AntigravityChatService] onboardUser attempt ${G+1}:`,JSON.stringify(W)),W.error)throw Error(`onboardUser error: ${W.error.message||W.error.code}`);if(W.done)return{projectId:W.response?.cloudaicompanionProject?.id};v0.debug("[AntigravityChatService] onboardUser not done, waiting 5s..."),await new Promise((U)=>setTimeout(U,5000)),G++}throw Error("onboardUser timeout: LRO did not complete in time")}convertToAntigravityMessages($){let Z=$.find((q)=>q.role==="system"),Y=Z?{parts:[{text:y6(Z.content)}]}:void 0,Q=[],X=$.filter((q)=>q.role!=="system"),J=new Map;for(let q of X)if(q.role==="assistant"&&q.tool_calls){for(let K of q.tool_calls)if(K.type==="function")J.set(K.id,K.function.name)}for(let q of X)if(q.role==="user"){let K=[];if(Array.isArray(q.content)){for(let W of q.content)if(W.type==="text")K.push({text:W.text})}else K.push({text:q.content});Q.push({role:"user",parts:K})}else if(q.role==="assistant"){let K=[],W=y6(q.content);if(W)K.push({text:W});if(q.tool_calls)for(let U of q.tool_calls){if(U.type!=="function")continue;let O={};try{O=JSON.parse(U.function.arguments||"{}")}catch{v0.warn(`Failed to parse tool arguments: ${U.function.arguments}`)}K.push({functionCall:{name:U.function.name,args:O,id:U.id}})}if(K.length>0)Q.push({role:"model",parts:K})}else if(q.role==="tool"){let K=J.get(q.tool_call_id||"");if(K){let W;try{W=JSON.parse(y6(q.content))}catch{W={result:y6(q.content)}}Q.push({role:"user",parts:[{functionResponse:{name:K,id:q.tool_call_id,response:W}}]})}}let G=[];for(let q of Q){let K=G[G.length-1];if(K?.role===q.role)K.parts=[...K.parts,...q.parts];else G.push(q)}if(G.length>0&&G[0].role!=="user")G.unshift({role:"user",parts:[{text:"[Conversation start]"}]});return{systemInstruction:Y,contents:G}}convertToAntigravityTools($){if(!$||$.length===0)return;return[{functionDeclarations:$.map((Y)=>({name:Y.name,description:Y.description,parameters:_9(Y.parameters||{type:"object",properties:{}})}))}]}async makeRequest($,Z,Y){let Q=await this.auth.getAccessToken(),X=`${B3.production}${$}`,J=j6(this.configType),G=await V$(X,{method:"POST",headers:{Authorization:`Bearer ${Q}`,"Content-Type":"application/json","User-Agent":J},body:JSON.stringify(Z),signal:Y});if(!G.ok){let q=await G.text();if(v0.error(`Antigravity API error: ${G.status} - ${q}`),G.status===401)throw Error("Authentication expired. Please run /login again.");if(G.status===403)throw Error("Permission denied. Please check your Google account permissions.");if(G.status===429)throw Error("Rate limit exceeded. Please wait a moment and try again.");throw Error(`Antigravity API error: ${G.status} - ${q}`)}return G}async chat($,Z,Y){let Q=Date.now();v0.debug("\uD83D\uDE80 [AntigravityChatService] Starting chat request"),v0.debug("\uD83D\uDCDD [AntigravityChatService] Messages count:",$.length),await this.ensureProjectId();let X=mX($);if(X.length<$.length)v0.debug(`Filtered ${$.length-X.length} orphan tool messages`);let{systemInstruction:J,contents:G}=this.convertToAntigravityMessages(X),q=this.convertToAntigravityTools(Z),K=`prompt_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,W={model:this.config.model,project:this.projectId,user_prompt_id:K,request:{contents:G,systemInstruction:J,generationConfig:{...this.config.maxOutputTokens&&{maxOutputTokens:this.config.maxOutputTokens},temperature:this.config.temperature??0.7},tools:q,session_id:this.sessionId}};v0.debug("\uD83D\uDCE4 [AntigravityChatService] Request:",{model:this.config.model,contentsCount:G.length,hasSystemInstruction:!!J,toolsCount:q?.[0]?.functionDeclarations?.length||0});try{let O=await(await this.makeRequest(w3.generateContent,W,Y)).json(),F=Date.now()-Q;v0.debug("\uD83D\uDCE5 [AntigravityChatService] Response received in",F,"ms");let H="",_=[],w=O.response?.candidates?.[0]?.content?.parts||[];for(let N of w)if(N.text)H+=N.text;else if(N.functionCall){let M=N.functionCall;_.push({id:M.id||`call_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,type:"function",function:{name:M.name,arguments:JSON.stringify(M.args||{})}})}let B=O.response?.usageMetadata,L={content:H,toolCalls:_.length>0?_:void 0,usage:{promptTokens:B?.promptTokenCount||0,completionTokens:B?.candidatesTokenCount||0,totalTokens:B?.totalTokenCount||0}};return v0.debug("✅ [AntigravityChatService] Chat completed:",{contentLength:L.content.length,toolCallsCount:L.toolCalls?.length||0,usage:L.usage}),L}catch(U){let O=Date.now()-Q;throw v0.error("❌ [AntigravityChatService] Chat failed after",O,"ms"),v0.error("❌ [AntigravityChatService] Error:",U),U}}async*streamChat($,Z,Y){let Q=Date.now();v0.debug("\uD83D\uDE80 [AntigravityChatService] Starting stream request"),await this.ensureProjectId();let X=mX($),{systemInstruction:J,contents:G}=this.convertToAntigravityMessages(X),q=this.convertToAntigravityTools(Z),K=`prompt_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,W={model:this.config.model,project:this.projectId,user_prompt_id:K,request:{contents:G,systemInstruction:J,generationConfig:{...this.config.maxOutputTokens&&{maxOutputTokens:this.config.maxOutputTokens},temperature:this.config.temperature??0.7},tools:q,session_id:this.sessionId}};try{let U=await this.auth.getAccessToken(),O=`${B3.production}${w3.streamGenerateContent}?alt=sse`,F=j6(this.configType),H=await V$(O,{method:"POST",headers:{Authorization:`Bearer ${U}`,"Content-Type":"application/json",Accept:"text/event-stream","User-Agent":F},body:JSON.stringify(W),signal:Y});if(!H.ok){let N=await H.text();throw Error(`Antigravity API error: ${H.status} - ${N}`)}let _=H.body?.getReader();if(!_)throw Error("No response body");let z=new TextDecoder,w="",B=0,L=Date.now()-Q;v0.debug("\uD83D\uDCE5 [AntigravityChatService] Stream started in",L,"ms");while(!0){let{done:N,value:M}=await _.read();if(N)break;w+=z.decode(M,{stream:!0});let b=w.split(`
176
- `);w=b.pop()||"";for(let j of b)if(j.startsWith("data: ")){let T=j.slice(6);if(T==="[DONE]"){yield{finishReason:"stop"};continue}try{let A=JSON.parse(T);if(B++,A.usageMetadata)yield{usage:{promptTokens:A.usageMetadata.promptTokenCount||0,completionTokens:A.usageMetadata.candidatesTokenCount||0,totalTokens:A.usageMetadata.totalTokenCount||0}};let k=A.candidates?.[0],c=k?.content?.parts||[];for(let S of c)if(S.text)yield{content:S.text};else if(S.functionCall){let y=S.functionCall;yield{toolCalls:[{id:y.id||`call_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,type:"function",function:{name:y.name,arguments:JSON.stringify(y.args||{})}}]}}let o=k?.finishReason;if(o)yield{finishReason:o==="STOP"?"stop":o==="MAX_TOKENS"?"length":o.toLowerCase()}}catch(A){v0.debug("Failed to parse SSE data:",T)}}}v0.debug("✅ [AntigravityChatService] Stream completed:",{eventCount:B,duration:Date.now()-Q+"ms"})}catch(U){let O=Date.now()-Q;throw v0.error("❌ [AntigravityChatService] Stream failed after",O,"ms"),v0.error("❌ [AntigravityChatService] Error:",U),U}}getConfig(){return{...this.config}}updateConfig($){v0.debug("\uD83D\uDD04 [AntigravityChatService] Updating configuration"),this.config={...this.config,...$},v0.debug("✅ [AntigravityChatService] Configuration updated")}}var v0;var gX=R(()=>{Q0();E4();R3();N3();v0=x("Chat")});async function dX($){if($!==uX)return $;if(T6)return V3.debug("使用缓存的内置 API Key"),T6;try{V3.info("\uD83D\uDD11 正在从代理服务获取内置 API Key...");let Z=await V$(T_,{method:"GET",headers:{Authorization:`Bearer ${uX}`,"Content-Type":"application/json"},timeout:1e4});if(!Z.ok){let Q=await Z.text();throw Error(`获取 API Key 失败: ${Z.status} - ${Q}`)}let Y=await Z.json();if(!Y.apiKey)throw Error("代理服务返回的数据中没有 apiKey");if(T6=Y.apiKey,V3.info("✅ 成功获取内置 API Key"),Y.message)V3.debug(`提示: ${Y.message}`);return T6}catch(Z){throw V3.error("❌ 获取内置 API Key 失败:",Z),Error(`无法获取内置模型的 API Key: ${Z instanceof Error?Z.message:"未知错误"}
177
- `+"请检查网络连接或使用自己的 API Key (/config)")}}var V3,T_="https://blade-api-proxy.137844255.workers.dev/v1/get-zhipu-key",uX="blade-free-tier",T6=null;var cX=R(()=>{Q0();E4();V3=x("Service")});var I4,M3,E6;var D3=R(()=>{I4={deviceCodeUrl:"https://github.com/login/device/code",tokenUrl:"https://github.com/login/oauth/access_token",clientId:"01ab8ac9400c4e429b23",scope:"user:email",grantType:"urn:ietf:params:oauth:grant-type:device_code"},M3={tokenExchange:"https://api.github.com/copilot_internal/v2/token",chatCompletions:"https://api.githubcopilot.com/chat/completions",models:"https://api.githubcopilot.com/models"},E6={"gpt-5-mini":{id:"gpt-5-mini",name:"GPT-5 Mini",provider:"openai",supportsStreaming:!0,description:"快速高效,适合简单任务"},"grok-code-fast-1":{id:"grok-code-fast-1",name:"Grok Code Fast 1",provider:"xai",supportsStreaming:!0,description:"xAI 快速代码模型"},"claude-haiku-4.5":{id:"claude-haiku-4.5",name:"Claude Haiku 4.5",provider:"anthropic",supportsStreaming:!0,description:"快速智能的 Claude"},"gpt-4.1":{id:"gpt-4.1",name:"GPT-4.1",provider:"openai",supportsStreaming:!0,description:"默认模型,平衡速度与质量"},"gpt-4o":{id:"gpt-4o",name:"GPT-4o",provider:"openai",supportsStreaming:!0,description:"多模态模型,适合日常编码"},"gpt-5":{id:"gpt-5",name:"GPT-5",provider:"openai",supportsStreaming:!0,description:"最新 GPT-5 模型"},"claude-sonnet-4":{id:"claude-sonnet-4",name:"Claude Sonnet 4",provider:"anthropic",supportsStreaming:!0,description:"平衡速度与智能的 Claude"},"claude-sonnet-4.5":{id:"claude-sonnet-4.5",name:"Claude Sonnet 4.5",provider:"anthropic",supportsStreaming:!0,description:"最新 Claude Sonnet"},"claude-opus-4.1":{id:"claude-opus-4.1",name:"Claude Opus 4.1",provider:"anthropic",supportsStreaming:!0,description:"最强 Claude,适合复杂任务"},"gemini-2.5-pro":{id:"gemini-2.5-pro",name:"Gemini 2.5 Pro",provider:"google",supportsStreaming:!0,description:"高级推理和长上下文"},"gemini-3-pro":{id:"gemini-3-pro",name:"Gemini 3 Pro",provider:"google",supportsStreaming:!0,description:"数据分析和多模态"},"gemini-3-flash":{id:"gemini-3-flash",name:"Gemini 3 Flash",provider:"google",supportsStreaming:!0,description:"快速响应模型"}}});import{spawn as E_}from"child_process";import*as i2 from"fs/promises";import*as y3 from"path";function w9(){let $=process.env.HOME||process.env.USERPROFILE||"";return y3.join($,".blade")}class r${static instance=null;cachedToken=null;constructor(){}static getInstance(){if(!r$.instance)r$.instance=new r$;return r$.instance}async isLoggedIn(){let $=await this.loadToken();if(!$)return!1;let Z=300000;if($.copilotExpiresAt&&Date.now()>$.copilotExpiresAt-Z)try{return await this.refreshCopilotToken(),!0}catch{return!1}return!0}async login(){j3.info("\uD83D\uDD10 Starting GitHub Copilot OAuth login..."),console.log(`
174
+ `),K(),W.close(),!q)q=!0,X(H)}catch(F){if(K(),W.close(),!q)q=!0,J(F)}});W.on("error",(U)=>{if(K(),!q)if(q=!0,U.code==="EADDRINUSE")J(Error(`Port ${Y} is already in use. Please close other applications using this port.`));else J(U)}),W.listen(Y,()=>{c2.debug(`OAuth callback server listening on port ${Y}`)}),G=setTimeout(()=>{if(W.close(),!q)q=!0,J(Error("OAuth callback timeout (5 minutes)"))},300000)})}async exchangeCodeForToken($,Z,Y){let Q=`http://localhost:${Y.redirectPort}${Y.redirectPath}`,X=new URLSearchParams({grant_type:"authorization_code",code:$,redirect_uri:Q,code_verifier:Z,client_id:Y.clientId,client_secret:Y.clientSecret}),J=await V$(Y.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:X.toString()});if(!J.ok){let G=await J.text();throw Error(`Token exchange failed: ${J.status} - ${G}`)}return await J.json()}async openBrowser($){let Z,Y;if(process.platform==="darwin")Z="open",Y=[$];else if(process.platform==="win32")Z="cmd",Y=["/c","start","",$];else Z="xdg-open",Y=[$];await new Promise((Q,X)=>{let J=j_(Z,Y,{stdio:"ignore"});J.once("error",X),J.once("close",(G)=>{if(G===0||G===null)Q();else X(Error(`Failed to open browser (exit code ${G})`))})})}async saveToken($){let Z=H9();await l2.mkdir(Z,{recursive:!0,mode:493});let Y=A3.join(Z,F9);await l2.writeFile(Y,JSON.stringify($,null,2),{mode:384})}async loadToken(){let $=A3.join(H9(),F9);try{let Z=await l2.readFile($,"utf-8");return JSON.parse(Z)}catch(Z){if(Z.code==="ENOENT")return null;throw Z}}async getStatus(){let $=await this.loadToken();if(!$)return{loggedIn:!1};return{loggedIn:!0,expiresAt:$.expiresAt?new Date($.expiresAt):void 0,configType:$.configType||"antigravity"}}async getConfigType(){let $=await this.loadToken();if(!$)return null;return $.configType||"antigravity"}}var c2,F9="antigravity-token.json";var R3=R(()=>{Q0();E4();N3();c2=x("Service")});function pX($){if($==="antigravity")return{ideType:"ANTIGRAVITY"};return{ideType:"IDE_UNSPECIFIED",platform:"PLATFORM_UNSPECIFIED",pluginType:"GEMINI"}}function j7($){if($==="antigravity")return"antigravity/1.11.3 Darwin/arm64";return"gemini-cli/1.0.0"}function mX($){let Z=new Set;for(let Y of $)if(Y.role==="assistant"&&Y.tool_calls)for(let Q of Y.tool_calls)Z.add(Q.id);return $.filter((Y)=>{if(Y.role==="tool"){if(!Y.tool_call_id)return!1;return Z.has(Y.tool_call_id)}return!0})}function y7($){if(typeof $==="string")return $;return $.filter((Z)=>Z.type==="text").map((Z)=>Z.text).join(`
175
+ `)}function _9($){let Z=["const","$ref","$defs","$schema","$id","default","examples"],Y={};for(let[Q,X]of Object.entries($)){if(Z.includes(Q)){if(Q==="const")Y.enum=[X];continue}if(X&&typeof X==="object"&&!Array.isArray(X))Y[Q]=_9(X);else if(Array.isArray(X))Y[Q]=X.map((J)=>J&&typeof J==="object"&&!Array.isArray(J)?_9(J):J);else Y[Q]=X}return Y}class z9{config;auth;projectId;userTier;sessionId;configType="antigravity";projectIdInitialized=!1;constructor($){this.config=$,this.auth=p$.getInstance(),this.projectId=void 0,this.sessionId=`session_${Date.now()}_${Math.random().toString(36).slice(2,11)}`,v0.debug("\uD83D\uDE80 [AntigravityChatService] Initializing"),v0.debug("⚙️ [AntigravityChatService] Config:",{model:$.model,temperature:$.temperature,maxOutputTokens:$.maxOutputTokens,sessionId:this.sessionId})}async ensureProjectId(){if(this.projectIdInitialized)return;try{let $=await this.auth.getConfigType();this.configType=$||"antigravity",v0.debug(`\uD83D\uDD04 [AntigravityChatService] Using OAuth config: ${this.configType}`),v0.debug("\uD83D\uDD04 [AntigravityChatService] Setting up user via loadCodeAssist...");let Z=await this.auth.getAccessToken(),Y=await this.callLoadCodeAssist(Z);if(v0.debug("[AntigravityChatService] loadCodeAssist response:",JSON.stringify(Y)),Y.currentTier){if(this.userTier=Y.currentTier.id,Y.cloudaicompanionProject){this.projectId=Y.cloudaicompanionProject,v0.debug(`✅ [AntigravityChatService] User already setup: tier=${this.userTier}, project=${this.projectId}`),this.projectIdInitialized=!0;return}let J=process.env.GOOGLE_CLOUD_PROJECT||process.env.GOOGLE_CLOUD_PROJECT_ID;if(J){this.projectId=J,v0.debug(`✅ [AntigravityChatService] Using env project: ${this.projectId}`),this.projectIdInitialized=!0;return}v0.debug("⚠️ [AntigravityChatService] Has tier but no project, need onboarding...")}let Q=this.getDefaultTier(Y);v0.debug(`\uD83D\uDD04 [AntigravityChatService] Onboarding user with tier: ${Q.id}`);let X=await this.callOnboardUser(Z,Q.id);this.projectId=X.projectId,this.userTier=Q.id,v0.debug(`✅ [AntigravityChatService] User setup complete: tier=${this.userTier}, project=${this.projectId||"(managed)"}`)}catch($){v0.warn("Failed to setup user:",$)}this.projectIdInitialized=!0}async callLoadCodeAssist($){let Z=`${B3.production}${w3.loadCodeAssist}`,Y=pX(this.configType),Q=j7(this.configType),X=await V$(Z,{method:"POST",headers:{Authorization:`Bearer ${$}`,"Content-Type":"application/json","User-Agent":Q},body:JSON.stringify({metadata:Y})});if(!X.ok){let J=await X.text();throw Error(`loadCodeAssist failed: ${X.status} - ${J}`)}return await X.json()}getDefaultTier($){for(let Z of $.allowedTiers||[])if(Z.isDefault)return{id:Z.id};return{id:"free-tier"}}async callOnboardUser($,Z){let Y=`${B3.production}${w3.onboardUser}`,Q=pX(this.configType),X=j7(this.configType),J={tierId:Z,metadata:Q};if(Z!=="free-tier"){let K=process.env.GOOGLE_CLOUD_PROJECT||process.env.GOOGLE_CLOUD_PROJECT_ID;if(K)J.cloudaicompanionProject=K,J.metadata={...Q,duetProject:K}}let G=0,q=30;while(G<q){let K=await V$(Y,{method:"POST",headers:{Authorization:`Bearer ${$}`,"Content-Type":"application/json","User-Agent":X},body:JSON.stringify(J)});if(!K.ok){let U=await K.text();throw Error(`onboardUser failed: ${K.status} - ${U}`)}let W=await K.json();if(v0.debug(`[AntigravityChatService] onboardUser attempt ${G+1}:`,JSON.stringify(W)),W.error)throw Error(`onboardUser error: ${W.error.message||W.error.code}`);if(W.done)return{projectId:W.response?.cloudaicompanionProject?.id};v0.debug("[AntigravityChatService] onboardUser not done, waiting 5s..."),await new Promise((U)=>setTimeout(U,5000)),G++}throw Error("onboardUser timeout: LRO did not complete in time")}convertToAntigravityMessages($){let Z=$.find((q)=>q.role==="system"),Y=Z?{parts:[{text:y7(Z.content)}]}:void 0,Q=[],X=$.filter((q)=>q.role!=="system"),J=new Map;for(let q of X)if(q.role==="assistant"&&q.tool_calls){for(let K of q.tool_calls)if(K.type==="function")J.set(K.id,K.function.name)}for(let q of X)if(q.role==="user"){let K=[];if(Array.isArray(q.content)){for(let W of q.content)if(W.type==="text")K.push({text:W.text})}else K.push({text:q.content});Q.push({role:"user",parts:K})}else if(q.role==="assistant"){let K=[],W=y7(q.content);if(W)K.push({text:W});if(q.tool_calls)for(let U of q.tool_calls){if(U.type!=="function")continue;let O={};try{O=JSON.parse(U.function.arguments||"{}")}catch{v0.warn(`Failed to parse tool arguments: ${U.function.arguments}`)}K.push({functionCall:{name:U.function.name,args:O,id:U.id}})}if(K.length>0)Q.push({role:"model",parts:K})}else if(q.role==="tool"){let K=J.get(q.tool_call_id||"");if(K){let W;try{W=JSON.parse(y7(q.content))}catch{W={result:y7(q.content)}}Q.push({role:"user",parts:[{functionResponse:{name:K,id:q.tool_call_id,response:W}}]})}}let G=[];for(let q of Q){let K=G[G.length-1];if(K?.role===q.role)K.parts=[...K.parts,...q.parts];else G.push(q)}if(G.length>0&&G[0].role!=="user")G.unshift({role:"user",parts:[{text:"[Conversation start]"}]});return{systemInstruction:Y,contents:G}}convertToAntigravityTools($){if(!$||$.length===0)return;return[{functionDeclarations:$.map((Y)=>({name:Y.name,description:Y.description,parameters:_9(Y.parameters||{type:"object",properties:{}})}))}]}async makeRequest($,Z,Y){let Q=await this.auth.getAccessToken(),X=`${B3.production}${$}`,J=j7(this.configType),G=await V$(X,{method:"POST",headers:{Authorization:`Bearer ${Q}`,"Content-Type":"application/json","User-Agent":J},body:JSON.stringify(Z),signal:Y});if(!G.ok){let q=await G.text();if(v0.error(`Antigravity API error: ${G.status} - ${q}`),G.status===401)throw Error("Authentication expired. Please run /login again.");if(G.status===403)throw Error("Permission denied. Please check your Google account permissions.");if(G.status===429)throw Error("Rate limit exceeded. Please wait a moment and try again.");throw Error(`Antigravity API error: ${G.status} - ${q}`)}return G}async chat($,Z,Y){let Q=Date.now();v0.debug("\uD83D\uDE80 [AntigravityChatService] Starting chat request"),v0.debug("\uD83D\uDCDD [AntigravityChatService] Messages count:",$.length),await this.ensureProjectId();let X=mX($);if(X.length<$.length)v0.debug(`Filtered ${$.length-X.length} orphan tool messages`);let{systemInstruction:J,contents:G}=this.convertToAntigravityMessages(X),q=this.convertToAntigravityTools(Z),K=`prompt_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,W={model:this.config.model,project:this.projectId,user_prompt_id:K,request:{contents:G,systemInstruction:J,generationConfig:{...this.config.maxOutputTokens&&{maxOutputTokens:this.config.maxOutputTokens},temperature:this.config.temperature??0.7},tools:q,session_id:this.sessionId}};v0.debug("\uD83D\uDCE4 [AntigravityChatService] Request:",{model:this.config.model,contentsCount:G.length,hasSystemInstruction:!!J,toolsCount:q?.[0]?.functionDeclarations?.length||0});try{let O=await(await this.makeRequest(w3.generateContent,W,Y)).json(),F=Date.now()-Q;v0.debug("\uD83D\uDCE5 [AntigravityChatService] Response received in",F,"ms");let H="",_=[],w=O.response?.candidates?.[0]?.content?.parts||[];for(let N of w)if(N.text)H+=N.text;else if(N.functionCall){let M=N.functionCall;_.push({id:M.id||`call_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,type:"function",function:{name:M.name,arguments:JSON.stringify(M.args||{})}})}let B=O.response?.usageMetadata,L={content:H,toolCalls:_.length>0?_:void 0,usage:{promptTokens:B?.promptTokenCount||0,completionTokens:B?.candidatesTokenCount||0,totalTokens:B?.totalTokenCount||0}};return v0.debug("✅ [AntigravityChatService] Chat completed:",{contentLength:L.content.length,toolCallsCount:L.toolCalls?.length||0,usage:L.usage}),L}catch(U){let O=Date.now()-Q;throw v0.error("❌ [AntigravityChatService] Chat failed after",O,"ms"),v0.error("❌ [AntigravityChatService] Error:",U),U}}async*streamChat($,Z,Y){let Q=Date.now();v0.debug("\uD83D\uDE80 [AntigravityChatService] Starting stream request"),await this.ensureProjectId();let X=mX($),{systemInstruction:J,contents:G}=this.convertToAntigravityMessages(X),q=this.convertToAntigravityTools(Z),K=`prompt_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,W={model:this.config.model,project:this.projectId,user_prompt_id:K,request:{contents:G,systemInstruction:J,generationConfig:{...this.config.maxOutputTokens&&{maxOutputTokens:this.config.maxOutputTokens},temperature:this.config.temperature??0.7},tools:q,session_id:this.sessionId}};try{let U=await this.auth.getAccessToken(),O=`${B3.production}${w3.streamGenerateContent}?alt=sse`,F=j7(this.configType),H=await V$(O,{method:"POST",headers:{Authorization:`Bearer ${U}`,"Content-Type":"application/json",Accept:"text/event-stream","User-Agent":F},body:JSON.stringify(W),signal:Y});if(!H.ok){let N=await H.text();throw Error(`Antigravity API error: ${H.status} - ${N}`)}let _=H.body?.getReader();if(!_)throw Error("No response body");let z=new TextDecoder,w="",B=0,L=Date.now()-Q;v0.debug("\uD83D\uDCE5 [AntigravityChatService] Stream started in",L,"ms");while(!0){let{done:N,value:M}=await _.read();if(N)break;w+=z.decode(M,{stream:!0});let b=w.split(`
176
+ `);w=b.pop()||"";for(let j of b)if(j.startsWith("data: ")){let T=j.slice(6);if(T==="[DONE]"){yield{finishReason:"stop"};continue}try{let A=JSON.parse(T);if(B++,A.usageMetadata)yield{usage:{promptTokens:A.usageMetadata.promptTokenCount||0,completionTokens:A.usageMetadata.candidatesTokenCount||0,totalTokens:A.usageMetadata.totalTokenCount||0}};let k=A.candidates?.[0],c=k?.content?.parts||[];for(let S of c)if(S.text)yield{content:S.text};else if(S.functionCall){let y=S.functionCall;yield{toolCalls:[{id:y.id||`call_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,type:"function",function:{name:y.name,arguments:JSON.stringify(y.args||{})}}]}}let o=k?.finishReason;if(o)yield{finishReason:o==="STOP"?"stop":o==="MAX_TOKENS"?"length":o.toLowerCase()}}catch(A){v0.debug("Failed to parse SSE data:",T)}}}v0.debug("✅ [AntigravityChatService] Stream completed:",{eventCount:B,duration:Date.now()-Q+"ms"})}catch(U){let O=Date.now()-Q;throw v0.error("❌ [AntigravityChatService] Stream failed after",O,"ms"),v0.error("❌ [AntigravityChatService] Error:",U),U}}getConfig(){return{...this.config}}updateConfig($){v0.debug("\uD83D\uDD04 [AntigravityChatService] Updating configuration"),this.config={...this.config,...$},v0.debug("✅ [AntigravityChatService] Configuration updated")}}var v0;var gX=R(()=>{Q0();E4();R3();N3();v0=x("Chat")});async function dX($){if($!==uX)return $;if(T7)return V3.debug("使用缓存的内置 API Key"),T7;try{V3.info("\uD83D\uDD11 正在从代理服务获取内置 API Key...");let Z=await V$(T_,{method:"GET",headers:{Authorization:`Bearer ${uX}`,"Content-Type":"application/json"},timeout:1e4});if(!Z.ok){let Q=await Z.text();throw Error(`获取 API Key 失败: ${Z.status} - ${Q}`)}let Y=await Z.json();if(!Y.apiKey)throw Error("代理服务返回的数据中没有 apiKey");if(T7=Y.apiKey,V3.info("✅ 成功获取内置 API Key"),Y.message)V3.debug(`提示: ${Y.message}`);return T7}catch(Z){throw V3.error("❌ 获取内置 API Key 失败:",Z),Error(`无法获取内置模型的 API Key: ${Z instanceof Error?Z.message:"未知错误"}
177
+ `+"请检查网络连接或使用自己的 API Key (/config)")}}var V3,T_="https://blade-api-proxy.137844255.workers.dev/v1/get-zhipu-key",uX="blade-free-tier",T7=null;var cX=R(()=>{Q0();E4();V3=x("Service")});var I4,M3,E7;var D3=R(()=>{I4={deviceCodeUrl:"https://github.com/login/device/code",tokenUrl:"https://github.com/login/oauth/access_token",clientId:"01ab8ac9400c4e429b23",scope:"user:email",grantType:"urn:ietf:params:oauth:grant-type:device_code"},M3={tokenExchange:"https://api.github.com/copilot_internal/v2/token",chatCompletions:"https://api.githubcopilot.com/chat/completions",models:"https://api.githubcopilot.com/models"},E7={"gpt-5-mini":{id:"gpt-5-mini",name:"GPT-5 Mini",provider:"openai",supportsStreaming:!0,description:"快速高效,适合简单任务"},"grok-code-fast-1":{id:"grok-code-fast-1",name:"Grok Code Fast 1",provider:"xai",supportsStreaming:!0,description:"xAI 快速代码模型"},"claude-haiku-4.5":{id:"claude-haiku-4.5",name:"Claude Haiku 4.5",provider:"anthropic",supportsStreaming:!0,description:"快速智能的 Claude"},"gpt-4.1":{id:"gpt-4.1",name:"GPT-4.1",provider:"openai",supportsStreaming:!0,description:"默认模型,平衡速度与质量"},"gpt-4o":{id:"gpt-4o",name:"GPT-4o",provider:"openai",supportsStreaming:!0,description:"多模态模型,适合日常编码"},"gpt-5":{id:"gpt-5",name:"GPT-5",provider:"openai",supportsStreaming:!0,description:"最新 GPT-5 模型"},"claude-sonnet-4":{id:"claude-sonnet-4",name:"Claude Sonnet 4",provider:"anthropic",supportsStreaming:!0,description:"平衡速度与智能的 Claude"},"claude-sonnet-4.5":{id:"claude-sonnet-4.5",name:"Claude Sonnet 4.5",provider:"anthropic",supportsStreaming:!0,description:"最新 Claude Sonnet"},"claude-opus-4.1":{id:"claude-opus-4.1",name:"Claude Opus 4.1",provider:"anthropic",supportsStreaming:!0,description:"最强 Claude,适合复杂任务"},"gemini-2.5-pro":{id:"gemini-2.5-pro",name:"Gemini 2.5 Pro",provider:"google",supportsStreaming:!0,description:"高级推理和长上下文"},"gemini-3-pro":{id:"gemini-3-pro",name:"Gemini 3 Pro",provider:"google",supportsStreaming:!0,description:"数据分析和多模态"},"gemini-3-flash":{id:"gemini-3-flash",name:"Gemini 3 Flash",provider:"google",supportsStreaming:!0,description:"快速响应模型"}}});import{spawn as E_}from"child_process";import*as i2 from"fs/promises";import*as y3 from"path";function w9(){let $=process.env.HOME||process.env.USERPROFILE||"";return y3.join($,".blade")}class r${static instance=null;cachedToken=null;constructor(){}static getInstance(){if(!r$.instance)r$.instance=new r$;return r$.instance}async isLoggedIn(){let $=await this.loadToken();if(!$)return!1;let Z=300000;if($.copilotExpiresAt&&Date.now()>$.copilotExpiresAt-Z)try{return await this.refreshCopilotToken(),!0}catch{return!1}return!0}async login(){j3.info("\uD83D\uDD10 Starting GitHub Copilot OAuth login..."),console.log(`
178
178
  \uD83D\uDD10 开始 GitHub Copilot 认证...`);let $=await this.requestDeviceCode();console.log(`
179
179
  \uD83D\uDCCB 请在浏览器中完成授权:`),console.log(` 1. 打开 ${$.verification_uri}`),console.log(` 2. 输入代码: ${$.user_code}`),console.log("");try{await this.openBrowser($.verification_uri),console.log("\uD83C\uDF10 已自动打开浏览器,请输入上面的代码完成授权")}catch{console.log("⚠️ 无法自动打开浏览器,请手动打开上述链接")}console.log(`
180
- ⏳ 等待授权中...`);let Z=await this.pollForAccessToken($.device_code,$.interval,$.expires_in);console.log("✅ GitHub 授权成功!"),console.log("\uD83D\uDD04 正在获取 Copilot token...");let Y=await this.exchangeForCopilotToken(Z),Q={githubToken:Z,copilotToken:Y.token,copilotExpiresAt:Y.expires_at*1000};await this.saveToken(Q),this.cachedToken=Q,console.log("✅ GitHub Copilot 登录成功!"),j3.info("GitHub Copilot OAuth login completed")}async logout(){let $=y3.join(w9(),B9);try{await i2.unlink($),this.cachedToken=null,console.log("✅ 已登出 GitHub Copilot"),j3.info("GitHub Copilot logout completed")}catch(Z){if(Z.code!=="ENOENT")throw Z;this.cachedToken=null}}async getCopilotToken(){if(this.cachedToken){if(this.cachedToken.copilotExpiresAt>Date.now()+300000)return this.cachedToken.copilotToken}let $=await this.loadToken();if(!$)throw Error("Not logged in to GitHub Copilot. Please run /login copilot first.");let Z=300000;if($.copilotExpiresAt<=Date.now()+Z)return await this.refreshCopilotToken(),this.cachedToken.copilotToken;return this.cachedToken=$,$.copilotToken}async refreshCopilotToken(){let $=await this.loadToken();if(!$||!$.githubToken)throw Error("No GitHub token available");j3.info("\uD83D\uDD04 Refreshing Copilot token...");let Z=await this.exchangeForCopilotToken($.githubToken),Y={githubToken:$.githubToken,copilotToken:Z.token,copilotExpiresAt:Z.expires_at*1000};await this.saveToken(Y),this.cachedToken=Y,j3.info("✅ Copilot token refreshed successfully")}async requestDeviceCode(){let $=new URLSearchParams({client_id:I4.clientId,scope:I4.scope}),Z=await V$(I4.deviceCodeUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:$.toString()});if(!Z.ok){let Y=await Z.text();throw Error(`Failed to request device code: ${Z.status} - ${Y}`)}return await Z.json()}async pollForAccessToken($,Z,Y){let Q=Date.now(),X=Y*1000;while(Date.now()-Q<X){await this.sleep(Z*1000);let J=new URLSearchParams({client_id:I4.clientId,device_code:$,grant_type:I4.grantType}),q=await(await V$(I4.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:J.toString()})).json();if(q.access_token)return q.access_token;if(q.error==="authorization_pending")continue;if(q.error==="slow_down"){Z+=5;continue}if(q.error==="expired_token")throw Error("Device code expired. Please try again.");if(q.error==="access_denied")throw Error("Authorization denied by user.");if(q.error)throw Error(`OAuth error: ${q.error} - ${q.error_description||""}`)}throw Error("Device code expired. Please try again.")}async exchangeForCopilotToken($){let Z=await V$(M3.tokenExchange,{method:"GET",headers:{Authorization:`token ${$}`,Accept:"application/json","User-Agent":"GitHubCopilotChat/0.22.2024","Editor-Version":"vscode/1.95.0","Editor-Plugin-Version":"copilot-chat/0.22.2024"}});if(!Z.ok){let Y=await Z.text();if(Z.status===401)throw Error("GitHub token is invalid or expired. Please run /login copilot again.");if(Z.status===403)throw Error("No Copilot subscription found. Please ensure you have an active GitHub Copilot subscription.");throw Error(`Failed to exchange for Copilot token: ${Z.status} - ${Y}`)}return await Z.json()}async openBrowser($){let Z,Y;if(process.platform==="darwin")Z="open",Y=[$];else if(process.platform==="win32")Z="cmd",Y=["/c","start","",$];else Z="xdg-open",Y=[$];await new Promise((Q,X)=>{let J=E_(Z,Y,{stdio:"ignore"});J.once("error",X),J.once("close",(G)=>{if(G===0||G===null)Q();else X(Error(`Failed to open browser (exit code ${G})`))})})}async saveToken($){let Z=w9();await i2.mkdir(Z,{recursive:!0,mode:493});let Y=y3.join(Z,B9);await i2.writeFile(Y,JSON.stringify($,null,2),{mode:384})}async loadToken(){let $=y3.join(w9(),B9);try{let Z=await i2.readFile($,"utf-8");return JSON.parse(Z)}catch(Z){if(Z.code==="ENOENT")return null;throw Z}}async getStatus(){let $=await this.loadToken();if(!$)return{loggedIn:!1};return{loggedIn:!0,expiresAt:$.copilotExpiresAt?new Date($.copilotExpiresAt):void 0}}sleep($){return new Promise((Z)=>setTimeout(Z,$))}}var j3,B9="copilot-token.json";var T3=R(()=>{Q0();E4();D3();j3=x("Service")});import{isPlainObject as I6}from"lodash-es";class L9{config;auth;constructor($){this.config=$,this.auth=r$.getInstance()}getConfig(){return this.config}updateConfig($){this.config={...this.config,...$}}async chat($,Z,Y){let Q=Date.now();M1.debug("\uD83D\uDE80 [CopilotChatService] Starting chat request"),M1.debug(`\uD83D\uDCDD [CopilotChatService] Messages count: ${$.length}`);try{let X=await this.auth.getCopilotToken(),J=this.buildRequest($,Z,!1),G=await this.makeRequest(X,J,Y),q=Date.now()-Q;return M1.debug(`✅ [CopilotChatService] Chat completed in ${q} ms`),this.parseResponse(G)}catch(X){let J=Date.now()-Q;throw M1.error(`❌ [CopilotChatService] Chat failed after ${J} ms`),M1.error(`❌ [CopilotChatService] Error: ${X}`),X}}async*streamChat($,Z,Y){let Q=Date.now();M1.debug("\uD83D\uDE80 [CopilotChatService] Starting stream chat request"),M1.debug(`\uD83D\uDCDD [CopilotChatService] Messages count: ${$.length}`);try{let X=await this.auth.getCopilotToken(),J=this.buildRequest($,Z,!0),G=await V$(M3.chatCompletions,{method:"POST",headers:{Authorization:`Bearer ${X}`,"Content-Type":"application/json",Accept:"text/event-stream","Copilot-Integration-Id":"vscode-chat","Editor-Version":"vscode/1.95.0","Editor-Plugin-Version":"copilot-chat/0.22.2024","User-Agent":"GitHubCopilotChat/0.22.2024"},body:JSON.stringify(J),signal:Y});if(!G.ok){let F=await G.text();throw Error(`Copilot API error: ${G.status} - ${F}`)}if(!G.body)throw Error("No response body");let q=G.body.getReader(),K=new TextDecoder,W="",U=new Map;while(!0){let{done:F,value:H}=await q.read();if(F)break;W+=K.decode(H,{stream:!0});let _=W.split(`
180
+ ⏳ 等待授权中...`);let Z=await this.pollForAccessToken($.device_code,$.interval,$.expires_in);console.log("✅ GitHub 授权成功!"),console.log("\uD83D\uDD04 正在获取 Copilot token...");let Y=await this.exchangeForCopilotToken(Z),Q={githubToken:Z,copilotToken:Y.token,copilotExpiresAt:Y.expires_at*1000};await this.saveToken(Q),this.cachedToken=Q,console.log("✅ GitHub Copilot 登录成功!"),j3.info("GitHub Copilot OAuth login completed")}async logout(){let $=y3.join(w9(),B9);try{await i2.unlink($),this.cachedToken=null,console.log("✅ 已登出 GitHub Copilot"),j3.info("GitHub Copilot logout completed")}catch(Z){if(Z.code!=="ENOENT")throw Z;this.cachedToken=null}}async getCopilotToken(){if(this.cachedToken){if(this.cachedToken.copilotExpiresAt>Date.now()+300000)return this.cachedToken.copilotToken}let $=await this.loadToken();if(!$)throw Error("Not logged in to GitHub Copilot. Please run /login copilot first.");let Z=300000;if($.copilotExpiresAt<=Date.now()+Z)return await this.refreshCopilotToken(),this.cachedToken.copilotToken;return this.cachedToken=$,$.copilotToken}async refreshCopilotToken(){let $=await this.loadToken();if(!$||!$.githubToken)throw Error("No GitHub token available");j3.info("\uD83D\uDD04 Refreshing Copilot token...");let Z=await this.exchangeForCopilotToken($.githubToken),Y={githubToken:$.githubToken,copilotToken:Z.token,copilotExpiresAt:Z.expires_at*1000};await this.saveToken(Y),this.cachedToken=Y,j3.info("✅ Copilot token refreshed successfully")}async requestDeviceCode(){let $=new URLSearchParams({client_id:I4.clientId,scope:I4.scope}),Z=await V$(I4.deviceCodeUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:$.toString()});if(!Z.ok){let Y=await Z.text();throw Error(`Failed to request device code: ${Z.status} - ${Y}`)}return await Z.json()}async pollForAccessToken($,Z,Y){let Q=Date.now(),X=Y*1000;while(Date.now()-Q<X){await this.sleep(Z*1000);let J=new URLSearchParams({client_id:I4.clientId,device_code:$,grant_type:I4.grantType}),q=await(await V$(I4.tokenUrl,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"},body:J.toString()})).json();if(q.access_token)return q.access_token;if(q.error==="authorization_pending")continue;if(q.error==="slow_down"){Z+=5;continue}if(q.error==="expired_token")throw Error("Device code expired. Please try again.");if(q.error==="access_denied")throw Error("Authorization denied by user.");if(q.error)throw Error(`OAuth error: ${q.error} - ${q.error_description||""}`)}throw Error("Device code expired. Please try again.")}async exchangeForCopilotToken($){let Z=await V$(M3.tokenExchange,{method:"GET",headers:{Authorization:`token ${$}`,Accept:"application/json","User-Agent":"GitHubCopilotChat/0.22.2024","Editor-Version":"vscode/1.95.0","Editor-Plugin-Version":"copilot-chat/0.22.2024"}});if(!Z.ok){let Y=await Z.text();if(Z.status===401)throw Error("GitHub token is invalid or expired. Please run /login copilot again.");if(Z.status===403)throw Error("No Copilot subscription found. Please ensure you have an active GitHub Copilot subscription.");throw Error(`Failed to exchange for Copilot token: ${Z.status} - ${Y}`)}return await Z.json()}async openBrowser($){let Z,Y;if(process.platform==="darwin")Z="open",Y=[$];else if(process.platform==="win32")Z="cmd",Y=["/c","start","",$];else Z="xdg-open",Y=[$];await new Promise((Q,X)=>{let J=E_(Z,Y,{stdio:"ignore"});J.once("error",X),J.once("close",(G)=>{if(G===0||G===null)Q();else X(Error(`Failed to open browser (exit code ${G})`))})})}async saveToken($){let Z=w9();await i2.mkdir(Z,{recursive:!0,mode:493});let Y=y3.join(Z,B9);await i2.writeFile(Y,JSON.stringify($,null,2),{mode:384})}async loadToken(){let $=y3.join(w9(),B9);try{let Z=await i2.readFile($,"utf-8");return JSON.parse(Z)}catch(Z){if(Z.code==="ENOENT")return null;throw Z}}async getStatus(){let $=await this.loadToken();if(!$)return{loggedIn:!1};return{loggedIn:!0,expiresAt:$.copilotExpiresAt?new Date($.copilotExpiresAt):void 0}}sleep($){return new Promise((Z)=>setTimeout(Z,$))}}var j3,B9="copilot-token.json";var T3=R(()=>{Q0();E4();D3();j3=x("Service")});import{isPlainObject as I7}from"lodash-es";class L9{config;auth;constructor($){this.config=$,this.auth=r$.getInstance()}getConfig(){return this.config}updateConfig($){this.config={...this.config,...$}}async chat($,Z,Y){let Q=Date.now();M1.debug("\uD83D\uDE80 [CopilotChatService] Starting chat request"),M1.debug(`\uD83D\uDCDD [CopilotChatService] Messages count: ${$.length}`);try{let X=await this.auth.getCopilotToken(),J=this.buildRequest($,Z,!1),G=await this.makeRequest(X,J,Y),q=Date.now()-Q;return M1.debug(`✅ [CopilotChatService] Chat completed in ${q} ms`),this.parseResponse(G)}catch(X){let J=Date.now()-Q;throw M1.error(`❌ [CopilotChatService] Chat failed after ${J} ms`),M1.error(`❌ [CopilotChatService] Error: ${X}`),X}}async*streamChat($,Z,Y){let Q=Date.now();M1.debug("\uD83D\uDE80 [CopilotChatService] Starting stream chat request"),M1.debug(`\uD83D\uDCDD [CopilotChatService] Messages count: ${$.length}`);try{let X=await this.auth.getCopilotToken(),J=this.buildRequest($,Z,!0),G=await V$(M3.chatCompletions,{method:"POST",headers:{Authorization:`Bearer ${X}`,"Content-Type":"application/json",Accept:"text/event-stream","Copilot-Integration-Id":"vscode-chat","Editor-Version":"vscode/1.95.0","Editor-Plugin-Version":"copilot-chat/0.22.2024","User-Agent":"GitHubCopilotChat/0.22.2024"},body:JSON.stringify(J),signal:Y});if(!G.ok){let F=await G.text();throw Error(`Copilot API error: ${G.status} - ${F}`)}if(!G.body)throw Error("No response body");let q=G.body.getReader(),K=new TextDecoder,W="",U=new Map;while(!0){let{done:F,value:H}=await q.read();if(F)break;W+=K.decode(H,{stream:!0});let _=W.split(`
181
181
  `);W=_.pop()||"";for(let z of _){if(!z.startsWith("data: "))continue;let w=z.slice(6).trim();if(w==="[DONE]"){if(U.size>0)yield{toolCalls:Array.from(U.values()),finishReason:"tool_calls"};continue}try{let L=JSON.parse(w).choices[0];if(L){let N={};if(L.delta.content)N.content=L.delta.content;if(L.delta.tool_calls)for(let M of L.delta.tool_calls){let b=U.get(M.index);if(b){if(M.function?.arguments)b.function.arguments+=M.function.arguments}else U.set(M.index,{id:M.id||"",type:"function",function:{name:M.function?.name||"",arguments:M.function?.arguments||""}})}if(L.finish_reason)N.finishReason=L.finish_reason;if(N.content||N.finishReason==="stop")yield N}}catch{}}}let O=Date.now()-Q;M1.debug(`✅ [CopilotChatService] Stream completed in ${O} ms`)}catch(X){let J=Date.now()-Q;throw M1.error(`❌ [CopilotChatService] Stream failed after ${J} ms`),M1.error(`❌ [CopilotChatService] Error: ${X}`),X}}sanitizeMessages($){let Z=[],Y=new Set;for(let Q=0;Q<$.length;Q++){let X=$[Q];if(X.role==="assistant"&&X.tool_calls&&X.tool_calls.length>0){let J=[];for(let G of X.tool_calls){let q=!1;for(let K=Q+1;K<$.length;K++){if($[K].role==="tool"&&$[K].tool_call_id===G.id){q=!0;break}if($[K].role==="assistant"||$[K].role==="user")break}if(q)J.push(G.id),Y.add(G.id)}if(J.length>0)Z.push({...X,tool_calls:X.tool_calls.filter((G)=>J.includes(G.id))});else Z.push({role:X.role,content:X.content||"",reasoningContent:X.reasoningContent})}else if(X.role==="tool"){if(X.tool_call_id&&Y.has(X.tool_call_id))Z.push(X)}else Z.push(X)}if(Z.length!==$.length)M1.debug(`[CopilotChatService] Sanitized messages: ${$.length} -> ${Z.length}`);return Z}buildRequest($,Z,Y=!1){let X=this.sanitizeMessages($).map((G)=>{let q;if(typeof G.content==="string")q=G.content;else if(Array.isArray(G.content))q=G.content.filter((W)=>W.type==="text").map((W)=>W.text).join(`
182
- `);else q=null;let K={role:G.role,content:q};if(G.tool_call_id)K.tool_call_id=G.tool_call_id;if(G.name)K.name=G.name;if(G.tool_calls&&G.tool_calls.length>0)K.tool_calls=G.tool_calls.filter((W)=>W.type==="function"&&("function"in W)).map((W)=>({id:W.id,type:"function",function:{name:W.function.name,arguments:W.function.arguments}}));return K}),J={model:this.config.model,messages:X,stream:Y};if(this.config.temperature!==void 0)J.temperature=this.config.temperature;if(this.config.maxOutputTokens)J.max_tokens=this.config.maxOutputTokens;if(Z&&Z.length>0)J.tools=Z.map((G)=>({type:"function",function:{name:G.name,description:G.description,parameters:this.cleanParameters(G.parameters)}})),J.tool_choice="auto";return J}cleanParameters($){if(!I6($))return{};let Z={};for(let[Y,Q]of Object.entries($)){if(["$ref","const","default"].includes(Y))continue;if(Y==="properties"&&I6(Q)){let X={};for(let[J,G]of Object.entries(Q))X[J]=I6(G)?this.cleanParameters(G):G;Z[Y]=X}else if(Y==="items"&&I6(Q))Z[Y]=this.cleanParameters(Q);else Z[Y]=Q}return Z}async makeRequest($,Z,Y){let Q=await V$(M3.chatCompletions,{method:"POST",headers:{Authorization:`Bearer ${$}`,"Content-Type":"application/json",Accept:"application/json","Copilot-Integration-Id":"vscode-chat","Editor-Version":"vscode/1.95.0","Editor-Plugin-Version":"copilot-chat/0.22.2024","User-Agent":"GitHubCopilotChat/0.22.2024"},body:JSON.stringify(Z),signal:Y});if(!Q.ok){let X=await Q.text();if(M1.error(`Copilot API error: ${Q.status} - ${X}`),Q.status===401)throw Error("Copilot token expired or invalid. Please run /login copilot again.");if(Q.status===403)throw Error("Permission denied. Please ensure you have an active GitHub Copilot subscription.");if(Q.status===429)throw Error("Rate limit exceeded. Please wait and try again.");throw Error(`Copilot API error: ${Q.status} - ${X}`)}return await Q.json()}parseResponse($){let Z=$.choices[0];if(!Z)throw Error("No response from Copilot API");let Y={content:Z.message.content||""};if(Z.message.tool_calls&&Z.message.tool_calls.length>0)Y.toolCalls=Z.message.tool_calls.map((Q)=>({id:Q.id,type:"function",function:{name:Q.function.name,arguments:Q.function.arguments}}));if($.usage)Y.usage={promptTokens:$.usage.prompt_tokens,completionTokens:$.usage.completion_tokens,totalTokens:$.usage.total_tokens};return Y}}var M1;var lX=R(()=>{Q0();E4();T3();D3();M1=x("Chat")});import{createAnthropic as I_}from"@ai-sdk/anthropic";import{createAzure as v_}from"@ai-sdk/azure";import{createDeepSeek as P_}from"@ai-sdk/deepseek";import{createGoogleGenerativeAI as C_}from"@ai-sdk/google";import{createOpenAICompatible as N9}from"@ai-sdk/openai-compatible";import{generateText as S_,jsonSchema as k_,streamText as f_}from"ai";function iX($){let Z=new Set;for(let Y of $)if(Y.role==="assistant"&&Y.tool_calls)for(let Q of Y.tool_calls)Z.add(Q.id);return $.filter((Y)=>{if(Y.role==="tool"){if(!Y.tool_call_id)return!1;return Z.has(Y.tool_call_id)}return!0})}function v6($){if(typeof $==="string")return $;return $.filter((Z)=>Z.type==="text").map((Z)=>Z.text).join(`
183
- `)}function h_($,Z={}){try{return JSON.parse($)}catch{return i1.warn("⚠️ [VercelAIChatService] Failed to parse JSON, using fallback",{str:$}),Z}}class A9{model;config;constructor($){this.config=$,this.model=this.createModel($),i1.debug("\uD83D\uDE80 [VercelAIChatService] Initialized",{provider:$.provider,model:$.model,providerId:$.providerId})}createModel($){let{provider:Z,apiKey:Y,baseUrl:Q,model:X,customHeaders:J,providerId:G,apiVersion:q}=$;switch(Z){case"anthropic":return I_({apiKey:Y,baseURL:Q||void 0,headers:J})(X);case"gemini":{if(Q&&!this.isGeminiOfficialUrl(Q))return N9({name:"gemini",apiKey:Y,baseURL:Q,headers:J})(X);return C_({apiKey:Y,baseURL:Q||void 0})(X)}case"azure-openai":{let K=this.extractAzureResourceName(Q);if(K)return v_({apiKey:Y,resourceName:K,apiVersion:q||"2024-08-01-preview"})(X);let W=this.buildAzureBaseUrl(Q,X);return N9({name:"azure-openai",apiKey:Y,baseURL:W,headers:{...J,"api-key":Y},queryParams:{"api-version":q||"2024-08-01-preview"}})(X)}default:{if(G==="deepseek")return P_({apiKey:Y,baseURL:Q||void 0,headers:J})(X);return N9({name:G||"custom",apiKey:Y,baseURL:Q,headers:J})(X)}}}extractAzureResourceName($){if(!$)return;let Z=$.match(/https:\/\/([^.]+)\.openai\.azure(?:\.com|\.us|\.cn|\.de)/);return Z?Z[1]:void 0}buildAzureBaseUrl($,Z){if(!$)return"";let Y=$.replace(/\/$/,"").replace(/\?.*$/,"");if(Y.includes("/openai/deployments/"))return Y;return`${Y}/openai/deployments/${Z}`}isGeminiOfficialUrl($){return $.includes("generativelanguage.googleapis.com")||$.includes("aiplatform.googleapis.com")}convertMessages($){let Z=[];for(let Y of $)if(Y.role==="system")if(Array.isArray(Y.content)){let Q=Y.content.find((J)=>J.type==="text"),X={role:"system",content:v6(Y.content)};if(Q?.providerOptions)X.providerOptions=Q.providerOptions;Z.push(X)}else Z.push({role:"system",content:Y.content});else if(Y.role==="user")if(Array.isArray(Y.content)){let Q=Y.content.map((X)=>{if(X.type==="text"){let J={type:"text",text:X.text};if(X.providerOptions)J.providerOptions=X.providerOptions;return J}return{type:"image",image:X.image_url.url}});Z.push({role:"user",content:Q})}else Z.push({role:"user",content:Y.content});else if(Y.role==="assistant")if(Y.tool_calls&&Y.tool_calls.length>0){let Q=Y.tool_calls.map((J)=>{let G=J.function;return{type:"tool-call",toolCallId:J.id,toolName:G?.name||"",input:h_(G?.arguments||"{}",{})}}),X=v6(Y.content);if(X)Z.push({role:"assistant",content:[{type:"text",text:X},...Q]});else Z.push({role:"assistant",content:Q})}else Z.push({role:"assistant",content:v6(Y.content)});else if(Y.role==="tool")Z.push({role:"tool",content:[{type:"tool-result",toolCallId:Y.tool_call_id,toolName:Y.name||"unknown",output:{type:"text",value:v6(Y.content)}}]});return Z}convertTools($){if(!$||$.length===0)return;let Z={};for(let Y of $)Z[Y.name]={description:Y.description,inputSchema:k_(Y.parameters)};return Z}convertToolCalls($){return $.map((Z)=>({id:Z.toolCallId,type:"function",function:{name:Z.toolName,arguments:JSON.stringify(Z.args??Z.input??{})}}))}convertUsage($,Z){if(!$)return;let Y=$.promptTokens??0,Q=$.completionTokens??0,X={promptTokens:Y,completionTokens:Q,totalTokens:$.totalTokens??Y+Q};if(Z?.anthropic){if(Z.anthropic.cacheCreationInputTokens!==void 0)X.cacheCreationInputTokens=Z.anthropic.cacheCreationInputTokens;if(Z.anthropic.cacheReadInputTokens!==void 0)X.cacheReadInputTokens=Z.anthropic.cacheReadInputTokens}return X}async chat($,Z,Y){let Q=Date.now();i1.debug("\uD83D\uDE80 [VercelAIChatService] Starting chat request");let X=iX($),J=this.convertMessages(X),G=this.convertTools(Z);try{let q=await S_({model:this.model,messages:J,tools:G,maxOutputTokens:this.config.maxOutputTokens,temperature:this.config.temperature??0,abortSignal:Y}),K=Date.now()-Q;i1.debug("\uD83D\uDCE5 [VercelAIChatService] Response received in",K,"ms");let W=q.toolCalls&&q.toolCalls.length>0?this.convertToolCalls(q.toolCalls):void 0,U=Array.isArray(q.reasoning)?q.reasoning.map((O)=>O.text).join(""):void 0;return{content:q.text,reasoningContent:U,toolCalls:W,usage:this.convertUsage(q.usage,q.providerMetadata)}}catch(q){let K=Date.now()-Q;throw i1.error("❌ [VercelAIChatService] Chat failed after",K,"ms"),q}}async*streamChat($,Z,Y){let Q=Date.now();i1.debug("\uD83D\uDE80 [VercelAIChatService] Starting stream request");let X=iX($),J=this.convertMessages(X),G=this.convertTools(Z);try{let q=f_({model:this.model,messages:J,tools:G,maxOutputTokens:this.config.maxOutputTokens,temperature:this.config.temperature??0,abortSignal:Y});i1.debug("\uD83D\uDCE5 [VercelAIChatService] Stream started");let K=0;for await(let U of q.fullStream)switch(U.type){case"text-delta":yield{content:U.text??U.textDelta};break;case"reasoning-delta":yield{reasoningContent:U.textDelta};break;case"tool-call":yield{toolCalls:[{index:K++,id:U.toolCallId,type:"function",function:{name:U.toolName,arguments:JSON.stringify(U.args??U.input??{})}}]};break;case"finish":yield{finishReason:U.finishReason,usage:this.convertUsage(U.totalUsage,U.providerMetadata)};break}let W=Date.now()-Q;i1.debug("✅ [VercelAIChatService] Stream completed in",W,"ms")}catch(q){let K=Date.now()-Q;throw i1.error("❌ [VercelAIChatService] Stream failed after",K,"ms"),q}}getConfig(){return{...this.config}}updateConfig($){i1.debug("\uD83D\uDD04 [VercelAIChatService] Updating configuration"),this.config={...this.config,...$},this.model=this.createModel(this.config),i1.debug("✅ [VercelAIChatService] Configuration updated")}}var i1;var rX=R(()=>{Q0();i1=x("Chat")});async function P6($){let Z=$;if(q9($.apiKey)){aX.info("\uD83D\uDD11 检测到内置 API Key,正在获取...");let Y=await dX($.apiKey);Z={...$,apiKey:Y}}if(Z.providerId){let Y=SX(Z.providerId);if(Object.keys(Y).length>0)Z={...Z,customHeaders:{...Y,...Z.customHeaders}},aX.debug(`\uD83D\uDD27 注入 ${Z.providerId} 特定 headers:`,Object.keys(Y))}return x_(Z)}function x_($){switch($.provider){case"antigravity":return new z9($);case"copilot":return new L9($);default:return new A9($)}}var aX;var b9=R(()=>{W9();Q0();w8();gX();cX();lX();rX();aX=x("Service")});import{readFile as p_}from"node:fs/promises";import{basename as m_}from"node:path";class C6{static MAX_FILES=5;static MAX_LINES_PER_FILE=1000;static analyzeFiles($){let Z=new Map;return $.forEach((Q,X)=>{let J=typeof Q.content==="string"?Q.content:(Q.content||[]).filter((q)=>q.type==="text").map((q)=>q.text).join(`
182
+ `);else q=null;let K={role:G.role,content:q};if(G.tool_call_id)K.tool_call_id=G.tool_call_id;if(G.name)K.name=G.name;if(G.tool_calls&&G.tool_calls.length>0)K.tool_calls=G.tool_calls.filter((W)=>W.type==="function"&&("function"in W)).map((W)=>({id:W.id,type:"function",function:{name:W.function.name,arguments:W.function.arguments}}));return K}),J={model:this.config.model,messages:X,stream:Y};if(this.config.temperature!==void 0)J.temperature=this.config.temperature;if(this.config.maxOutputTokens)J.max_tokens=this.config.maxOutputTokens;if(Z&&Z.length>0)J.tools=Z.map((G)=>({type:"function",function:{name:G.name,description:G.description,parameters:this.cleanParameters(G.parameters)}})),J.tool_choice="auto";return J}cleanParameters($){if(!I7($))return{};let Z={};for(let[Y,Q]of Object.entries($)){if(["$ref","const","default"].includes(Y))continue;if(Y==="properties"&&I7(Q)){let X={};for(let[J,G]of Object.entries(Q))X[J]=I7(G)?this.cleanParameters(G):G;Z[Y]=X}else if(Y==="items"&&I7(Q))Z[Y]=this.cleanParameters(Q);else Z[Y]=Q}return Z}async makeRequest($,Z,Y){let Q=await V$(M3.chatCompletions,{method:"POST",headers:{Authorization:`Bearer ${$}`,"Content-Type":"application/json",Accept:"application/json","Copilot-Integration-Id":"vscode-chat","Editor-Version":"vscode/1.95.0","Editor-Plugin-Version":"copilot-chat/0.22.2024","User-Agent":"GitHubCopilotChat/0.22.2024"},body:JSON.stringify(Z),signal:Y});if(!Q.ok){let X=await Q.text();if(M1.error(`Copilot API error: ${Q.status} - ${X}`),Q.status===401)throw Error("Copilot token expired or invalid. Please run /login copilot again.");if(Q.status===403)throw Error("Permission denied. Please ensure you have an active GitHub Copilot subscription.");if(Q.status===429)throw Error("Rate limit exceeded. Please wait and try again.");throw Error(`Copilot API error: ${Q.status} - ${X}`)}return await Q.json()}parseResponse($){let Z=$.choices[0];if(!Z)throw Error("No response from Copilot API");let Y={content:Z.message.content||""};if(Z.message.tool_calls&&Z.message.tool_calls.length>0)Y.toolCalls=Z.message.tool_calls.map((Q)=>({id:Q.id,type:"function",function:{name:Q.function.name,arguments:Q.function.arguments}}));if($.usage)Y.usage={promptTokens:$.usage.prompt_tokens,completionTokens:$.usage.completion_tokens,totalTokens:$.usage.total_tokens};return Y}}var M1;var lX=R(()=>{Q0();E4();T3();D3();M1=x("Chat")});import{createAnthropic as I_}from"@ai-sdk/anthropic";import{createAzure as v_}from"@ai-sdk/azure";import{createDeepSeek as P_}from"@ai-sdk/deepseek";import{createGoogleGenerativeAI as C_}from"@ai-sdk/google";import{createOpenAICompatible as N9}from"@ai-sdk/openai-compatible";import{generateText as S_,jsonSchema as k_,streamText as f_}from"ai";function iX($){let Z=new Set;for(let Y of $)if(Y.role==="assistant"&&Y.tool_calls)for(let Q of Y.tool_calls)Z.add(Q.id);return $.filter((Y)=>{if(Y.role==="tool"){if(!Y.tool_call_id)return!1;return Z.has(Y.tool_call_id)}return!0})}function v7($){if(typeof $==="string")return $;return $.filter((Z)=>Z.type==="text").map((Z)=>Z.text).join(`
183
+ `)}function h_($,Z={}){try{return JSON.parse($)}catch{return i1.warn("⚠️ [VercelAIChatService] Failed to parse JSON, using fallback",{str:$}),Z}}class A9{model;config;constructor($){this.config=$,this.model=this.createModel($),i1.debug("\uD83D\uDE80 [VercelAIChatService] Initialized",{provider:$.provider,model:$.model,providerId:$.providerId})}createModel($){let{provider:Z,apiKey:Y,baseUrl:Q,model:X,customHeaders:J,providerId:G,apiVersion:q}=$;switch(Z){case"anthropic":return I_({apiKey:Y,baseURL:Q||void 0,headers:J})(X);case"gemini":{if(Q&&!this.isGeminiOfficialUrl(Q))return N9({name:"gemini",apiKey:Y,baseURL:Q,headers:J})(X);return C_({apiKey:Y,baseURL:Q||void 0})(X)}case"azure-openai":{let K=this.extractAzureResourceName(Q);if(K)return v_({apiKey:Y,resourceName:K,apiVersion:q||"2024-08-01-preview"})(X);let W=this.buildAzureBaseUrl(Q,X);return N9({name:"azure-openai",apiKey:Y,baseURL:W,headers:{...J,"api-key":Y},queryParams:{"api-version":q||"2024-08-01-preview"}})(X)}default:{if(G==="deepseek")return P_({apiKey:Y,baseURL:Q||void 0,headers:J})(X);return N9({name:G||"custom",apiKey:Y,baseURL:Q,headers:J})(X)}}}extractAzureResourceName($){if(!$)return;let Z=$.match(/https:\/\/([^.]+)\.openai\.azure(?:\.com|\.us|\.cn|\.de)/);return Z?Z[1]:void 0}buildAzureBaseUrl($,Z){if(!$)return"";let Y=$.replace(/\/$/,"").replace(/\?.*$/,"");if(Y.includes("/openai/deployments/"))return Y;return`${Y}/openai/deployments/${Z}`}isGeminiOfficialUrl($){return $.includes("generativelanguage.googleapis.com")||$.includes("aiplatform.googleapis.com")}convertMessages($){let Z=[];for(let Y of $)if(Y.role==="system")if(Array.isArray(Y.content)){let Q=Y.content.find((J)=>J.type==="text"),X={role:"system",content:v7(Y.content)};if(Q?.providerOptions)X.providerOptions=Q.providerOptions;Z.push(X)}else Z.push({role:"system",content:Y.content});else if(Y.role==="user")if(Array.isArray(Y.content)){let Q=Y.content.map((X)=>{if(X.type==="text"){let J={type:"text",text:X.text};if(X.providerOptions)J.providerOptions=X.providerOptions;return J}return{type:"image",image:X.image_url.url}});Z.push({role:"user",content:Q})}else Z.push({role:"user",content:Y.content});else if(Y.role==="assistant")if(Y.tool_calls&&Y.tool_calls.length>0){let Q=Y.tool_calls.map((J)=>{let G=J.function;return{type:"tool-call",toolCallId:J.id,toolName:G?.name||"",input:h_(G?.arguments||"{}",{})}}),X=v7(Y.content);if(X)Z.push({role:"assistant",content:[{type:"text",text:X},...Q]});else Z.push({role:"assistant",content:Q})}else Z.push({role:"assistant",content:v7(Y.content)});else if(Y.role==="tool")Z.push({role:"tool",content:[{type:"tool-result",toolCallId:Y.tool_call_id,toolName:Y.name||"unknown",output:{type:"text",value:v7(Y.content)}}]});return Z}convertTools($){if(!$||$.length===0)return;let Z={};for(let Y of $)Z[Y.name]={description:Y.description,inputSchema:k_(Y.parameters)};return Z}convertToolCalls($){return $.map((Z)=>({id:Z.toolCallId,type:"function",function:{name:Z.toolName,arguments:JSON.stringify(Z.args??Z.input??{})}}))}convertUsage($,Z){if(!$)return;let Y=$.promptTokens??0,Q=$.completionTokens??0,X={promptTokens:Y,completionTokens:Q,totalTokens:$.totalTokens??Y+Q};if(Z?.anthropic){if(Z.anthropic.cacheCreationInputTokens!==void 0)X.cacheCreationInputTokens=Z.anthropic.cacheCreationInputTokens;if(Z.anthropic.cacheReadInputTokens!==void 0)X.cacheReadInputTokens=Z.anthropic.cacheReadInputTokens}return X}async chat($,Z,Y){let Q=Date.now();i1.debug("\uD83D\uDE80 [VercelAIChatService] Starting chat request");let X=iX($),J=this.convertMessages(X),G=this.convertTools(Z);try{let q=await S_({model:this.model,messages:J,tools:G,maxOutputTokens:this.config.maxOutputTokens,temperature:this.config.temperature??0,abortSignal:Y}),K=Date.now()-Q;i1.debug("\uD83D\uDCE5 [VercelAIChatService] Response received in",K,"ms");let W=q.toolCalls&&q.toolCalls.length>0?this.convertToolCalls(q.toolCalls):void 0,U=Array.isArray(q.reasoning)?q.reasoning.map((O)=>O.text).join(""):void 0;return{content:q.text,reasoningContent:U,toolCalls:W,usage:this.convertUsage(q.usage,q.providerMetadata)}}catch(q){let K=Date.now()-Q;throw i1.error("❌ [VercelAIChatService] Chat failed after",K,"ms"),q}}async*streamChat($,Z,Y){let Q=Date.now();i1.debug("\uD83D\uDE80 [VercelAIChatService] Starting stream request");let X=iX($),J=this.convertMessages(X),G=this.convertTools(Z);try{let q=f_({model:this.model,messages:J,tools:G,maxOutputTokens:this.config.maxOutputTokens,temperature:this.config.temperature??0,abortSignal:Y});i1.debug("\uD83D\uDCE5 [VercelAIChatService] Stream started");let K=0;for await(let U of q.fullStream)switch(U.type){case"text-delta":yield{content:U.text??U.textDelta};break;case"reasoning-delta":yield{reasoningContent:U.textDelta};break;case"tool-call":yield{toolCalls:[{index:K++,id:U.toolCallId,type:"function",function:{name:U.toolName,arguments:JSON.stringify(U.args??U.input??{})}}]};break;case"finish":yield{finishReason:U.finishReason,usage:this.convertUsage(U.totalUsage,U.providerMetadata)};break}let W=Date.now()-Q;i1.debug("✅ [VercelAIChatService] Stream completed in",W,"ms")}catch(q){let K=Date.now()-Q;throw i1.error("❌ [VercelAIChatService] Stream failed after",K,"ms"),q}}getConfig(){return{...this.config}}updateConfig($){i1.debug("\uD83D\uDD04 [VercelAIChatService] Updating configuration"),this.config={...this.config,...$},this.model=this.createModel(this.config),i1.debug("✅ [VercelAIChatService] Configuration updated")}}var i1;var rX=R(()=>{Q0();i1=x("Chat")});async function P7($){let Z=$;if(q9($.apiKey)){aX.info("\uD83D\uDD11 检测到内置 API Key,正在获取...");let Y=await dX($.apiKey);Z={...$,apiKey:Y}}if(Z.providerId){let Y=SX(Z.providerId);if(Object.keys(Y).length>0)Z={...Z,customHeaders:{...Y,...Z.customHeaders}},aX.debug(`\uD83D\uDD27 注入 ${Z.providerId} 特定 headers:`,Object.keys(Y))}return x_(Z)}function x_($){switch($.provider){case"antigravity":return new z9($);case"copilot":return new L9($);default:return new A9($)}}var aX;var b9=R(()=>{W9();Q0();w8();gX();cX();lX();rX();aX=x("Service")});import{readFile as p_}from"node:fs/promises";import{basename as m_}from"node:path";class C7{static MAX_FILES=5;static MAX_LINES_PER_FILE=1000;static analyzeFiles($){let Z=new Map;return $.forEach((Q,X)=>{let J=typeof Q.content==="string"?Q.content:(Q.content||[]).filter((q)=>q.type==="text").map((q)=>q.text).join(`
184
184
  `);if(this.extractFilePathsFromContent(J).forEach((q)=>{this.updateFileReference(Z,q,X,!1)}),Q.tool_calls&&Array.isArray(Q.tool_calls))Q.tool_calls.forEach((q)=>{let K=this.extractFilePathsFromToolCall(q),W=q.type==="function"&&"function"in q?q.function?.name:"",U=["Write","Edit"].includes(W||"");K.forEach((O)=>{this.updateFileReference(Z,O,X,U)})})}),Array.from(Z.values()).sort((Q,X)=>{if(Q.wasModified!==X.wasModified)return Q.wasModified?-1:1;if(Q.mentions!==X.mentions)return X.mentions-Q.mentions;return X.lastMentioned-Q.lastMentioned}).slice(0,this.MAX_FILES)}static async readFilesContent($){let Z=[];for(let Y of $)try{let Q=await p_(Y,"utf-8"),X=Q.split(`
185
185
  `),J=X.length,G=Q,q=!1,K=J;if(J>this.MAX_LINES_PER_FILE)G=X.slice(0,this.MAX_LINES_PER_FILE).join(`
186
186
  `),G+=`
187
187
 
188
- ... (truncated ${J-this.MAX_LINES_PER_FILE} lines)`,q=!0,K=this.MAX_LINES_PER_FILE;Z.push({path:Y,content:G,truncated:q,lines:J,includedLines:K})}catch(Q){console.warn(`[FileAnalyzer] 无法读取文件: ${Y}`,Q)}return Z}static extractFilePathsFromContent($){let Z=new Set,Y=/```(?:\w+)?\s*\n?([\s\S]*?)```/g,Q=Array.from($.matchAll(Y));for(let J of Q){let G=J[1];this.extractPathsFromText(G).forEach((K)=>Z.add(K))}return this.extractPathsFromText($).forEach((J)=>Z.add(J)),Array.from(Z)}static extractPathsFromText($){let Z=[],Y=[/(?:src|tests?|docs?|lib|config|scripts?|bin|utils?|components?|services?|hooks?)\/[\w\-/.]+\.[\w]+/g,/(?:package|tsconfig|vite\.config|webpack\.config|next\.config|babel\.config)\.[\w]+/g,/(?:\.\.?\/|\/)[a-zA-Z0-9\-_/.]+\.[\w]+/g];for(let Q of Y){let X=Array.from($.matchAll(Q));for(let J of X){let G=J[0];if(G=G.replace(/[,。;:!?""''()【】《》]$/g,""),G=G.replace(/[,.;:!?"'()[\]<>]$/g,""),this.isValidFilePath(G))Z.push(G)}}return Z}static extractFilePathsFromToolCall($){let Z=[];if($.type!=="function"||!$.function)return Z;try{let Y=$.function.name,Q=JSON.parse($.function.arguments||"{}");if(["Read","Write","Edit","Glob","Grep","NotebookEdit","mcp__github__get_file_contents","mcp__github__create_or_update_file"].includes(Y)){let J=["file_path","path","notebook_path","filePath"];for(let G of J)if(Q[G]&&typeof Q[G]==="string")Z.push(Q[G])}}catch{}return Z}static updateFileReference($,Z,Y,Q){let X=$.get(Z);if(X)X.mentions++,X.lastMentioned=Y,X.wasModified=X.wasModified||Q;else $.set(Z,{path:Z,mentions:1,lastMentioned:Y,wasModified:Q})}static isValidFilePath($){if(!$.includes("/"))return!1;let Z=m_($);if(!Z.includes("."))return!1;let Y=["ts","tsx","js","jsx","json","md","py","java","go","rs","c","cpp","h","css","scss","html","xml","yaml","yml","toml","sh","bash","sql","graphql","vue","svelte"],Q=Z.split(".").pop()?.toLowerCase();if(!Q||!Y.includes(Q))return!1;return!0}}var nX=()=>{};import{encodingForModel as oX}from"js-tiktoken";var V2;var S6=R(()=>{V2=class V2{static encodingCache=new Map;static countTokens($,Z){let Y=this.getEncoding(Z),Q=0;for(let X of $){if(Q+=4,X.role)Q+=Y.encode(X.role).length;if(X.content)if(typeof X.content==="string")Q+=Y.encode(X.content).length;else Q+=Y.encode(JSON.stringify(X.content)).length;if(X.tool_calls&&Array.isArray(X.tool_calls))Q+=this.countToolCallTokens(X.tool_calls,Y);if(X.name)Q+=Y.encode(X.name).length}return Q}static getTokenLimit($){return $}static shouldCompact($,Z,Y,Q=0.8){let X=this.countTokens($,Z),J=Math.floor(Y*Q);return X>=J}static getEncoding($){if(!this.encodingCache.has($))try{let Z=oX($);this.encodingCache.set($,Z)}catch{try{let Z=oX("gpt-4");this.encodingCache.set($,Z)}catch{console.warn(`[TokenCounter] 无法为模型 ${$} 获取 encoding,使用粗略估算`),this.encodingCache.set($,{encode:(Z)=>{return Array(Math.ceil(Z.length/4))}})}}return this.encodingCache.get($)}static countToolCallTokens($,Z){let Y=0;for(let Q of $){if(Y+=4,Q.type==="function"&&Q.function?.name)Y+=Z.encode(Q.function.name).length;if(Q.type==="function"&&Q.function?.arguments)Y+=Z.encode(Q.function.arguments).length;if(Q.id)Y+=Z.encode(Q.id).length}return Y}static clearCache(){this.encodingCache.clear()}static estimateTokens($){let Z=($.match(/[\u4e00-\u9fa5]/g)||[]).length,Y=$.length-Z;return Math.ceil(Z/1.5+Y/4)}}});import{nanoid as L8}from"nanoid";class N8{static THRESHOLD_PERCENT=0.8;static RETAIN_PERCENT=0.2;static FALLBACK_RETAIN_PERCENT=0.3;static async compact($,Z){let Y=Z.actualPreTokens??V2.countTokens($,Z.modelName),Q=Z.actualPreTokens?"actual (from LLM usage)":"estimated";console.log(`[CompactionService] preTokens source: ${Q}`);try{let J=await y0.getInstance().executeCompactionHooks(Z.trigger,{projectDir:process.cwd(),sessionId:Z.sessionId||"unknown",permissionMode:Z.permissionMode||"default",messagesBefore:$.length,tokensBefore:Y});if(J.blockCompaction)return console.log(`[CompactionService] Compaction hook 阻止压缩: ${J.blockReason||"(无原因)"}`),{success:!1,summary:"",preTokens:Y,postTokens:Y,filesIncluded:[],compactedMessages:$,boundaryMessage:{role:"system",content:""},summaryMessage:{role:"user",content:""},error:J.blockReason||"Compaction blocked by hook"};if(J.warning)console.warn(`[CompactionService] Compaction hook warning: ${J.warning}`)}catch(X){console.warn("[CompactionService] Compaction hook execution failed:",X)}try{console.log("[CompactionService] 开始压缩,消息数:",$.length),console.log("[CompactionService] 压缩前 tokens:",Y);let J=C6.analyzeFiles($).map((L)=>L.path);console.log("[CompactionService] 提取重点文件:",J);let G=await C6.readFilesContent(J);console.log("[CompactionService] 成功读取文件:",G.length);let q=await this.generateSummary($,G,Z);console.log("[CompactionService] 生成总结,长度:",q.length);let K=Math.ceil($.length*this.RETAIN_PERCENT),W=$.slice(-K),U=new Set;for(let L of W)if(L.role==="assistant"&&L.tool_calls)for(let N of L.tool_calls)U.add(N.id);let O=W.filter((L)=>{if(L.role==="tool"&&L.tool_call_id)return U.has(L.tool_call_id);return!0});console.log("[CompactionService] 保留消息数:",K),console.log("[CompactionService] 过滤后保留消息数:",O.length);let F=L8(),H=this.createBoundaryMessage(F,Z.trigger,Y),_=L8(),z=this.createSummaryMessage(_,q),w=[z,...O],B=V2.countTokens(w,Z.modelName);return console.log("[CompactionService] 压缩完成!"),console.log("[CompactionService] Token 变化:",Y,"→",B,`(-${((1-B/Y)*100).toFixed(1)}%)`),{success:!0,summary:q,preTokens:Y,postTokens:B,filesIncluded:J,compactedMessages:w,boundaryMessage:H,summaryMessage:z}}catch(X){return console.error("[CompactionService] 压缩失败,使用降级策略",X),this.fallbackCompact($,Z,Y,X)}}static async generateSummary($,Z,Y){let Q=this.buildCompactionPrompt($,Z);console.log("[CompactionService] 使用压缩模型:",Y.modelName);let G=(await(await P6({apiKey:Y.apiKey||process.env.BLADE_API_KEY||"",baseUrl:Y.baseURL||process.env.BLADE_BASE_URL||"https://api.openai.com/v1",model:Y.modelName,temperature:0.3,maxOutputTokens:8000,timeout:60000,provider:"openai-compatible"})).chat([{role:"user",content:Q}])).content||"",q=G.match(/<summary>([\s\S]*?)<\/summary>/);if(!q)return console.warn("[CompactionService] 总结格式不正确,使用完整响应"),G;return q[1].trim()}static buildCompactionPrompt($,Z){let Y=$.map((J,G)=>{let q=J.role||"unknown",K=typeof J.content==="string"?J.content:JSON.stringify(J.content),W=5000,U=K.length>5000?K.substring(0,5000)+"...":K;return`[${G+1}] ${q}: ${U}`}).join(`
188
+ ... (truncated ${J-this.MAX_LINES_PER_FILE} lines)`,q=!0,K=this.MAX_LINES_PER_FILE;Z.push({path:Y,content:G,truncated:q,lines:J,includedLines:K})}catch(Q){console.warn(`[FileAnalyzer] 无法读取文件: ${Y}`,Q)}return Z}static extractFilePathsFromContent($){let Z=new Set,Y=/```(?:\w+)?\s*\n?([\s\S]*?)```/g,Q=Array.from($.matchAll(Y));for(let J of Q){let G=J[1];this.extractPathsFromText(G).forEach((K)=>Z.add(K))}return this.extractPathsFromText($).forEach((J)=>Z.add(J)),Array.from(Z)}static extractPathsFromText($){let Z=[],Y=[/(?:src|tests?|docs?|lib|config|scripts?|bin|utils?|components?|services?|hooks?)\/[\w\-/.]+\.[\w]+/g,/(?:package|tsconfig|vite\.config|webpack\.config|next\.config|babel\.config)\.[\w]+/g,/(?:\.\.?\/|\/)[a-zA-Z0-9\-_/.]+\.[\w]+/g];for(let Q of Y){let X=Array.from($.matchAll(Q));for(let J of X){let G=J[0];if(G=G.replace(/[,。;:!?""''()【】《》]$/g,""),G=G.replace(/[,.;:!?"'()[\]<>]$/g,""),this.isValidFilePath(G))Z.push(G)}}return Z}static extractFilePathsFromToolCall($){let Z=[];if($.type!=="function"||!$.function)return Z;try{let Y=$.function.name,Q=JSON.parse($.function.arguments||"{}");if(["Read","Write","Edit","Glob","Grep","NotebookEdit","mcp__github__get_file_contents","mcp__github__create_or_update_file"].includes(Y)){let J=["file_path","path","notebook_path","filePath"];for(let G of J)if(Q[G]&&typeof Q[G]==="string")Z.push(Q[G])}}catch{}return Z}static updateFileReference($,Z,Y,Q){let X=$.get(Z);if(X)X.mentions++,X.lastMentioned=Y,X.wasModified=X.wasModified||Q;else $.set(Z,{path:Z,mentions:1,lastMentioned:Y,wasModified:Q})}static isValidFilePath($){if(!$.includes("/"))return!1;let Z=m_($);if(!Z.includes("."))return!1;let Y=["ts","tsx","js","jsx","json","md","py","java","go","rs","c","cpp","h","css","scss","html","xml","yaml","yml","toml","sh","bash","sql","graphql","vue","svelte"],Q=Z.split(".").pop()?.toLowerCase();if(!Q||!Y.includes(Q))return!1;return!0}}var nX=()=>{};import{encodingForModel as oX}from"js-tiktoken";var V2;var S7=R(()=>{V2=class V2{static encodingCache=new Map;static countTokens($,Z){let Y=this.getEncoding(Z),Q=0;for(let X of $){if(Q+=4,X.role)Q+=Y.encode(X.role).length;if(X.content)if(typeof X.content==="string")Q+=Y.encode(X.content).length;else Q+=Y.encode(JSON.stringify(X.content)).length;if(X.tool_calls&&Array.isArray(X.tool_calls))Q+=this.countToolCallTokens(X.tool_calls,Y);if(X.name)Q+=Y.encode(X.name).length}return Q}static getTokenLimit($){return $}static shouldCompact($,Z,Y,Q=0.8){let X=this.countTokens($,Z),J=Math.floor(Y*Q);return X>=J}static getEncoding($){if(!this.encodingCache.has($))try{let Z=oX($);this.encodingCache.set($,Z)}catch{try{let Z=oX("gpt-4");this.encodingCache.set($,Z)}catch{console.warn(`[TokenCounter] 无法为模型 ${$} 获取 encoding,使用粗略估算`),this.encodingCache.set($,{encode:(Z)=>{return Array(Math.ceil(Z.length/4))}})}}return this.encodingCache.get($)}static countToolCallTokens($,Z){let Y=0;for(let Q of $){if(Y+=4,Q.type==="function"&&Q.function?.name)Y+=Z.encode(Q.function.name).length;if(Q.type==="function"&&Q.function?.arguments)Y+=Z.encode(Q.function.arguments).length;if(Q.id)Y+=Z.encode(Q.id).length}return Y}static clearCache(){this.encodingCache.clear()}static estimateTokens($){let Z=($.match(/[\u4e00-\u9fa5]/g)||[]).length,Y=$.length-Z;return Math.ceil(Z/1.5+Y/4)}}});import{nanoid as L8}from"nanoid";class N8{static THRESHOLD_PERCENT=0.8;static RETAIN_PERCENT=0.2;static FALLBACK_RETAIN_PERCENT=0.3;static async compact($,Z){let Y=Z.actualPreTokens??V2.countTokens($,Z.modelName),Q=Z.actualPreTokens?"actual (from LLM usage)":"estimated";console.log(`[CompactionService] preTokens source: ${Q}`);try{let J=await y0.getInstance().executeCompactionHooks(Z.trigger,{projectDir:process.cwd(),sessionId:Z.sessionId||"unknown",permissionMode:Z.permissionMode||"default",messagesBefore:$.length,tokensBefore:Y});if(J.blockCompaction)return console.log(`[CompactionService] Compaction hook 阻止压缩: ${J.blockReason||"(无原因)"}`),{success:!1,summary:"",preTokens:Y,postTokens:Y,filesIncluded:[],compactedMessages:$,boundaryMessage:{role:"system",content:""},summaryMessage:{role:"user",content:""},error:J.blockReason||"Compaction blocked by hook"};if(J.warning)console.warn(`[CompactionService] Compaction hook warning: ${J.warning}`)}catch(X){console.warn("[CompactionService] Compaction hook execution failed:",X)}try{console.log("[CompactionService] 开始压缩,消息数:",$.length),console.log("[CompactionService] 压缩前 tokens:",Y);let J=C7.analyzeFiles($).map((L)=>L.path);console.log("[CompactionService] 提取重点文件:",J);let G=await C7.readFilesContent(J);console.log("[CompactionService] 成功读取文件:",G.length);let q=await this.generateSummary($,G,Z);console.log("[CompactionService] 生成总结,长度:",q.length);let K=Math.ceil($.length*this.RETAIN_PERCENT),W=$.slice(-K),U=new Set;for(let L of W)if(L.role==="assistant"&&L.tool_calls)for(let N of L.tool_calls)U.add(N.id);let O=W.filter((L)=>{if(L.role==="tool"&&L.tool_call_id)return U.has(L.tool_call_id);return!0});console.log("[CompactionService] 保留消息数:",K),console.log("[CompactionService] 过滤后保留消息数:",O.length);let F=L8(),H=this.createBoundaryMessage(F,Z.trigger,Y),_=L8(),z=this.createSummaryMessage(_,q),w=[z,...O],B=V2.countTokens(w,Z.modelName);return console.log("[CompactionService] 压缩完成!"),console.log("[CompactionService] Token 变化:",Y,"→",B,`(-${((1-B/Y)*100).toFixed(1)}%)`),{success:!0,summary:q,preTokens:Y,postTokens:B,filesIncluded:J,compactedMessages:w,boundaryMessage:H,summaryMessage:z}}catch(X){return console.error("[CompactionService] 压缩失败,使用降级策略",X),this.fallbackCompact($,Z,Y,X)}}static async generateSummary($,Z,Y){let Q=this.buildCompactionPrompt($,Z);console.log("[CompactionService] 使用压缩模型:",Y.modelName);let G=(await(await P7({apiKey:Y.apiKey||process.env.BLADE_API_KEY||"",baseUrl:Y.baseURL||process.env.BLADE_BASE_URL||"https://api.openai.com/v1",model:Y.modelName,temperature:0.3,maxOutputTokens:8000,timeout:60000,provider:"openai-compatible"})).chat([{role:"user",content:Q}])).content||"",q=G.match(/<summary>([\s\S]*?)<\/summary>/);if(!q)return console.warn("[CompactionService] 总结格式不正确,使用完整响应"),G;return q[1].trim()}static buildCompactionPrompt($,Z){let Y=$.map((J,G)=>{let q=J.role||"unknown",K=typeof J.content==="string"?J.content:JSON.stringify(J.content),W=5000,U=K.length>5000?K.substring(0,5000)+"...":K;return`[${G+1}] ${q}: ${U}`}).join(`
189
189
 
190
190
  `),Q=Z.map((J)=>{return`### ${J.path}
191
191
  \`\`\`
@@ -265,9 +265,9 @@ An error occurred during compaction. Retained the latest ${X} messages (~30%).
265
265
  Error: ${U}
266
266
 
267
267
  The conversation can continue, but consider retrying compaction later with /compact.`),H=[F,...q],_=V2.countTokens(H,Z.modelName);return{success:!1,summary:typeof F.content==="string"?F.content:F.content.filter((z)=>z.type==="text").map((z)=>z.text).join(`
268
- `),preTokens:Y,postTokens:_,filesIncluded:[],compactedMessages:H,boundaryMessage:W,summaryMessage:F,error:U}}}var R9=R(()=>{U$();Y1();b9();nX();S6()});import{appendFileSync as g_,mkdirSync as u_,writeFileSync as d_}from"node:fs";import c_ from"node:os";import tX from"node:path";function l_(){if(sX)return;let $=tX.dirname(V9);u_($,{recursive:!0,mode:493}),d_(V9,`=== Stream Debug Log Started: ${new Date().toISOString()} ===
268
+ `),preTokens:Y,postTokens:_,filesIncluded:[],compactedMessages:H,boundaryMessage:W,summaryMessage:F,error:U}}}var R9=R(()=>{U$();Y1();b9();nX();S7()});import{appendFileSync as g_,mkdirSync as u_,writeFileSync as d_}from"node:fs";import c_ from"node:os";import tX from"node:path";function l_(){if(sX)return;let $=tX.dirname(V9);u_($,{recursive:!0,mode:493}),d_(V9,`=== Stream Debug Log Started: ${new Date().toISOString()} ===
269
269
  `),sX=!0}function D1($,Z,Y){l_();let Q=new Date().toISOString(),X=Y?` | ${JSON.stringify(Y)}`:"",J=`[${Q}] [${$}] ${Z}${X}
270
- `;g_(V9,J)}var V9,sX=!1;var M9=R(()=>{V9=tX.join(c_.homedir(),".blade","logs","stream-debug.log")});import i_ from"fs/promises";import r_ from"path";async function $J($){for(let Z of $)try{let Y;if(Z.trim().startsWith("{")){let J=JSON.parse(Z);if(J.name&&J.type){let{name:G,...q}=J;Y={[G]:q}}else Y=J}else{let J=r_.resolve(process.cwd(),Z),G=await i_.readFile(J,"utf-8"),q=JSON.parse(G);Y=q.mcpServers||q}let X={...R1(),...Y};G0().config.actions.updateConfig({mcpServers:X}),eX.debug(`✅ Loaded MCP config from CLI: ${Object.keys(Y).join(", ")}`)}catch(Y){eX.warn(`⚠️ Failed to load MCP config "${Z}":`,Y)}}var eX;var ZJ=R(()=>{Q0();M0();eX=x("General")});function YJ(){return{metadata:k6,instructions:`# Skill Creator
270
+ `;g_(V9,J)}var V9,sX=!1;var M9=R(()=>{V9=tX.join(c_.homedir(),".blade","logs","stream-debug.log")});import i_ from"fs/promises";import r_ from"path";async function $J($){for(let Z of $)try{let Y;if(Z.trim().startsWith("{")){let J=JSON.parse(Z);if(J.name&&J.type){let{name:G,...q}=J;Y={[G]:q}}else Y=J}else{let J=r_.resolve(process.cwd(),Z),G=await i_.readFile(J,"utf-8"),q=JSON.parse(G);Y=q.mcpServers||q}let X={...R1(),...Y};G0().config.actions.updateConfig({mcpServers:X}),eX.debug(`✅ Loaded MCP config from CLI: ${Object.keys(Y).join(", ")}`)}catch(Y){eX.warn(`⚠️ Failed to load MCP config "${Z}":`,Y)}}var eX;var ZJ=R(()=>{Q0();M0();eX=x("General")});function YJ(){return{metadata:k7,instructions:`# Skill Creator
271
271
 
272
272
  帮助用户创建新的 Blade Skills。
273
273
 
@@ -450,10 +450,10 @@ user-invocable: true
450
450
  <footer>
451
451
  \`\`\`
452
452
  \`\`\`
453
- `}}var k6;var QJ=R(()=>{k6={name:"skill-creator",description:"Create new Skills interactively. Use when the user wants to create a new Skill, define a custom workflow, or add a specialized capability to Blade.",allowedTools:["Read","Write","Glob","Bash","AskUserQuestion"],version:"1.0.0",argumentHint:void 0,userInvocable:!0,disableModelInvocation:!1,model:void 0,whenToUse:"User wants to create a new skill, define a custom workflow, or add a specialized capability.",path:"builtin://skill-creator",basePath:"",source:"builtin"}});import{exec as a_}from"node:child_process";import*as R0 from"node:fs/promises";import{homedir as n_}from"node:os";import*as z$ from"node:path";import{promisify as o_}from"node:util";class XJ{skillsDir;constructor($){this.skillsDir=$||z$.join(n_(),".blade","skills")}async isInstalled($){let Z=z$.join(this.skillsDir,$,"SKILL.md");try{return await R0.access(Z),!0}catch{return!1}}async isGitAvailable(){try{return await f6("git --version"),!0}catch{return!1}}async installOfficialSkill($){let{url:Z,branch:Y}=D9,Q=z$.join(this.skillsDir,$),X=z$.join(this.skillsDir,`.tmp-${$}-${Date.now()}`);try{if(!await this.isGitAvailable())return _$.warn("Git not available, skipping skill installation"),!1;_$.info(`Installing official skill: ${$}...`),await R0.mkdir(this.skillsDir,{recursive:!0,mode:493}),await f6(`git clone --depth 1 --branch ${Y} --single-branch ${Z} "${X}"`,{timeout:30000});let J=z$.join(X,"skills",$);try{await R0.access(J)}catch{return _$.warn(`Skill ${$} not found in official repository`),await R0.rm(X,{recursive:!0,force:!0}),!1}try{await R0.rm(Q,{recursive:!0,force:!0})}catch{}return await R0.cp(J,Q,{recursive:!0}),await R0.rm(X,{recursive:!0,force:!0}),_$.info(`Successfully installed: ${$}`),!0}catch(J){try{await R0.rm(X,{recursive:!0,force:!0})}catch{}return _$.warn(`Failed to install ${$}: ${J instanceof Error?J.message:"Unknown error"}`),!1}}async ensureDefaultSkillsInstalled(){await R0.mkdir(this.skillsDir,{recursive:!0,mode:493});for(let $ of D9.defaultSkills)if(!await this.isInstalled($))await this.installOfficialSkill($)}async installFromRepo($,Z){let Y=Z||this.extractRepoName($),Q=z$.join(this.skillsDir,Y),X=z$.join(this.skillsDir,`.tmp-repo-${Y}-${Date.now()}`);try{if(!await this.isGitAvailable())return _$.warn("Git not available, cannot install from repo"),!1;_$.info(`Installing skill from repo: ${$}...`),await R0.mkdir(this.skillsDir,{recursive:!0,mode:493}),await f6(`git clone --depth 1 "${$}" "${X}"`,{timeout:60000});let J=z$.join(X,"SKILL.md");try{await R0.access(J)}catch{return _$.warn(`No SKILL.md found in repository ${$}`),await R0.rm(X,{recursive:!0,force:!0}),!1}await R0.rm(Q,{recursive:!0,force:!0}),await R0.rename(X,Q);try{await R0.rm(z$.join(Q,".git"),{recursive:!0,force:!0})}catch{}return _$.info(`Successfully installed skill from repo: ${Y}`),!0}catch(J){try{await R0.rm(X,{recursive:!0,force:!0})}catch{}return _$.warn(`Failed to install from repo ${$}: ${J instanceof Error?J.message:"Unknown error"}`),!1}}async installFromLocal($,Z,Y=!0){let Q=Z||z$.basename($),X=z$.join(this.skillsDir,Q);try{let J=z$.resolve($);try{await R0.access(J)}catch{return _$.warn(`Local path does not exist: ${J}`),!1}let G=z$.join(J,"SKILL.md");try{await R0.access(G)}catch{return _$.warn(`No SKILL.md found in local path: ${J}`),!1}if(_$.info(`Installing skill from local path: ${J}...`),await R0.mkdir(this.skillsDir,{recursive:!0,mode:493}),await R0.rm(X,{recursive:!0,force:!0}),Y)await R0.symlink(J,X,"dir"),_$.info(`Created symlink for skill: ${Q}`);else await R0.cp(J,X,{recursive:!0}),_$.info(`Copied skill to: ${Q}`);return!0}catch(J){return _$.warn(`Failed to install from local path ${$}: ${J instanceof Error?J.message:"Unknown error"}`),!1}}extractRepoName($){return $.match(/\/([^/]+?)(\.git)?$/)?.[1]||"unknown-skill"}async installAllOfficialSkills(){let{url:$,branch:Z}=D9,Y=z$.join(this.skillsDir,`.tmp-all-${Date.now()}`),Q=[],X=[];try{if(!await this.isGitAvailable())return _$.warn("Git not available, skipping skill installation"),{installed:Q,failed:X};await R0.mkdir(this.skillsDir,{recursive:!0,mode:493}),_$.info("Cloning official skills repository..."),await f6(`git clone --depth 1 --branch ${Z} --single-branch ${$} "${Y}"`,{timeout:60000});let J=z$.join(Y,"skills"),G=await R0.readdir(J,{withFileTypes:!0});for(let q of G){if(!q.isDirectory())continue;let K=q.name,W=z$.join(J,K),U=z$.join(this.skillsDir,K);try{await R0.access(z$.join(W,"SKILL.md")),await R0.rm(U,{recursive:!0,force:!0}),await R0.cp(W,U,{recursive:!0}),_$.info(`Installed: ${K}`),Q.push(K)}catch(O){_$.warn(`Failed to install ${K}`),X.push(K)}}await R0.rm(Y,{recursive:!0,force:!0})}catch(J){try{await R0.rm(Y,{recursive:!0,force:!0})}catch{}_$.warn(`Failed to install skills: ${J instanceof Error?J.message:"Unknown error"}`)}return{installed:Q,failed:X}}}function h6($){if(!j9)j9=new XJ($);return j9}var f6,_$,D9,j9=null;var y9=R(()=>{Q0();f6=o_(a_),_$=x("General"),D9={url:"https://github.com/anthropics/skills.git",branch:"main",defaultSkills:["skill-creator"]}});import*as E3 from"node:fs/promises";import*as x6 from"node:path";import{parse as s_}from"yaml";function $z($){if(!$)return;if(typeof $==="string")return $.split(",").map((Z)=>Z.trim()).filter(Boolean);if(Array.isArray($))return $.map((Z)=>String(Z).trim()).filter(Boolean);return}function GJ($){if($===void 0)return;if(typeof $==="boolean")return $;if(typeof $==="string"){let Z=$.toLowerCase().trim();if(Z==="true"||Z==="yes"||Z==="1")return!0;if(Z==="false"||Z==="no"||Z==="0")return!1}return}function Zz($,Z){if(!$.name)return{valid:!1,error:"Missing required field: name"};if(!e_.test($.name))return{valid:!1,error:`Invalid name "${$.name}": must be lowercase letters, numbers, and hyphens only, 1-64 characters`};if(!$.description)return{valid:!1,error:"Missing required field: description"};if($.description.length>JJ)return{valid:!1,error:`Description too long: ${$.description.length} characters (max ${JJ})`};let Y;if($.model)Y=$.model==="inherit"?"inherit":$.model;return{valid:!0,metadata:{name:$.name,description:$.description.trim(),allowedTools:$z($["allowed-tools"]),version:$.version,argumentHint:$["argument-hint"]?.trim(),userInvocable:GJ($["user-invocable"]),disableModelInvocation:GJ($["disable-model-invocation"]),model:Y,whenToUse:$.when_to_use?.trim()}}}function qJ($,Z,Y){let Q=$.match(t_);if(!Q)return{success:!1,error:"Invalid SKILL.md format: missing YAML frontmatter (must start with ---)"};let[,X,J]=Q,G;try{G=s_(X)}catch(W){return{success:!1,error:`Failed to parse YAML frontmatter: ${W instanceof Error?W.message:String(W)}`}}let q=Zz(G,Z);if(!q.valid)return{success:!1,error:q.error};let K=x6.dirname(Z);return{success:!0,content:{metadata:{...q.metadata,path:Z,basePath:K,source:Y},instructions:J.trim()}}}async function p6($,Z){try{let Y=await E3.readFile($,"utf-8");return qJ(Y,$,Z)}catch(Y){if(Y.code==="ENOENT")return{success:!1,error:`File not found: ${$}`};return{success:!1,error:`Failed to read file: ${Y instanceof Error?Y.message:String(Y)}`}}}async function KJ($){try{let Z=await E3.readFile($.path,"utf-8"),Y=qJ(Z,$.path,$.source);return Y.success?Y.content:null}catch{return null}}async function WJ($){try{return await E3.access(x6.join($,"SKILL.md")),!0}catch{return!1}}var t_,e_,JJ=1024;var T9=R(()=>{t_=/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/,e_=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]?$/});import*as g6 from"node:fs/promises";import{homedir as UJ}from"node:os";import*as q2 from"node:path";class E9{skills=new Map;pluginSkills=new Map;config;initialized=!1;constructor($){this.config={...Yz,...$}}static getInstance($){if(!m6)m6=new E9($);return m6}static resetInstance(){m6=null}async initialize(){if(this.initialized)return{skills:Array.from(this.skills.values()),errors:[]};let $=[],Z=[];try{await h6(this.config.userSkillsDir).ensureDefaultSkillsInstalled()}catch(K){$.push({path:"SkillInstaller",error:`Failed to install default skills: ${K instanceof Error?K.message:"Unknown error"}`})}this.loadBuiltinSkills();let Y=await this.scanDirectory(this.config.claudeUserSkillsDir,"user");Z.push(...Y.skills),$.push(...Y.errors);let Q=await this.scanDirectory(this.config.userSkillsDir,"user");Z.push(...Q.skills),$.push(...Q.errors);let X=q2.isAbsolute(this.config.claudeProjectSkillsDir)?this.config.claudeProjectSkillsDir:q2.join(this.config.cwd,this.config.claudeProjectSkillsDir),J=await this.scanDirectory(X,"project");Z.push(...J.skills),$.push(...J.errors);let G=q2.isAbsolute(this.config.projectSkillsDir)?this.config.projectSkillsDir:q2.join(this.config.cwd,this.config.projectSkillsDir),q=await this.scanDirectory(G,"project");Z.push(...q.skills),$.push(...q.errors);for(let K of Z)this.skills.set(K.name,K);return this.initialized=!0,{skills:Array.from(this.skills.values()),errors:$}}loadBuiltinSkills(){this.skills.set(k6.name,k6)}async scanDirectory($,Z){let Y=[],Q=[];try{await g6.access($)}catch{return{skills:Y,errors:Q}}try{let X=await g6.readdir($,{withFileTypes:!0});for(let J of X){if(!J.isDirectory())continue;let G=q2.join($,J.name),q=q2.join(G,"SKILL.md");if(!await WJ(G))continue;let K=await p6(q,Z);if(K.success&&K.content)Y.push(K.content.metadata);else Q.push({path:q,error:K.error||"Unknown error"})}}catch(X){Q.push({path:$,error:`Failed to scan directory: ${X instanceof Error?X.message:String(X)}`})}return{skills:Y,errors:Q}}getAll(){return Array.from(this.skills.values())}get($){return this.skills.get($)}has($){return this.skills.has($)}async loadContent($){let Z=this.skills.get($);if(!Z)return null;if(Z.source==="builtin")return this.loadBuiltinContent($);return KJ(Z)}loadBuiltinContent($){switch($){case"skill-creator":return YJ();default:return null}}getModelInvocableSkills(){return Array.from(this.skills.values()).filter(($)=>!$.disableModelInvocation)}getUserInvocableSkills(){return Array.from(this.skills.values()).filter(($)=>$.userInvocable===!0)}generateAvailableSkillsList(){let $=this.getModelInvocableSkills();if($.length===0)return"";let Z=[];for(let Y of $){let Q=Y.description.length>100?`${Y.description.substring(0,97)}...`:Y.description,X=Y.argumentHint?`${Y.name} ${Y.argumentHint}`:Y.name;Z.push(`- ${X}: ${Q}`)}return Z.join(`
454
- `)}get size(){return this.skills.size}async refresh(){return this.skills.clear(),this.pluginSkills.clear(),this.initialized=!1,this.initialize()}registerPluginSkill($){this.pluginSkills.set($.namespacedName,$),this.skills.set($.namespacedName,$.metadata)}findPluginSkill($){let Z=this.pluginSkills.get($);if(Z)return Z;let Y=[];for(let Q of this.pluginSkills.values())if(Q.originalName===$)Y.push(Q);if(Y.length===1)return Y[0];return}getAllPluginSkills(){return Array.from(this.pluginSkills.values())}clearPluginSkills(){for(let $ of this.pluginSkills.values())this.skills.delete($.namespacedName);this.pluginSkills.clear()}getPluginSkillCount(){return this.pluginSkills.size}}function J$($){return E9.getInstance($)}async function v4($){return J$($).initialize()}var Yz,m6=null;var I9=R(()=>{QJ();y9();T9();Yz={userSkillsDir:q2.join(UJ(),".blade","skills"),projectSkillsDir:".blade/skills",claudeUserSkillsDir:q2.join(UJ(),".claude","skills"),claudeProjectSkillsDir:".claude/skills",cwd:process.cwd()}});function v9($){let Y=J$().generateAvailableSkillsList();if(!Y)return $;return $.map((Q)=>{if(Q.name!==Qz)return Q;let X=Q.description.replace(Xz,`<available_skills>
453
+ `}}var k7;var QJ=R(()=>{k7={name:"skill-creator",description:"Create new Skills interactively. Use when the user wants to create a new Skill, define a custom workflow, or add a specialized capability to Blade.",allowedTools:["Read","Write","Glob","Bash","AskUserQuestion"],version:"1.0.0",argumentHint:void 0,userInvocable:!0,disableModelInvocation:!1,model:void 0,whenToUse:"User wants to create a new skill, define a custom workflow, or add a specialized capability.",path:"builtin://skill-creator",basePath:"",source:"builtin"}});import{exec as a_}from"node:child_process";import*as R0 from"node:fs/promises";import{homedir as n_}from"node:os";import*as z$ from"node:path";import{promisify as o_}from"node:util";class XJ{skillsDir;constructor($){this.skillsDir=$||z$.join(n_(),".blade","skills")}async isInstalled($){let Z=z$.join(this.skillsDir,$,"SKILL.md");try{return await R0.access(Z),!0}catch{return!1}}async isGitAvailable(){try{return await f7("git --version"),!0}catch{return!1}}async installOfficialSkill($){let{url:Z,branch:Y}=D9,Q=z$.join(this.skillsDir,$),X=z$.join(this.skillsDir,`.tmp-${$}-${Date.now()}`);try{if(!await this.isGitAvailable())return _$.warn("Git not available, skipping skill installation"),!1;_$.info(`Installing official skill: ${$}...`),await R0.mkdir(this.skillsDir,{recursive:!0,mode:493}),await f7(`git clone --depth 1 --branch ${Y} --single-branch ${Z} "${X}"`,{timeout:30000});let J=z$.join(X,"skills",$);try{await R0.access(J)}catch{return _$.warn(`Skill ${$} not found in official repository`),await R0.rm(X,{recursive:!0,force:!0}),!1}try{await R0.rm(Q,{recursive:!0,force:!0})}catch{}return await R0.cp(J,Q,{recursive:!0}),await R0.rm(X,{recursive:!0,force:!0}),_$.info(`Successfully installed: ${$}`),!0}catch(J){try{await R0.rm(X,{recursive:!0,force:!0})}catch{}return _$.warn(`Failed to install ${$}: ${J instanceof Error?J.message:"Unknown error"}`),!1}}async ensureDefaultSkillsInstalled(){await R0.mkdir(this.skillsDir,{recursive:!0,mode:493});for(let $ of D9.defaultSkills)if(!await this.isInstalled($))await this.installOfficialSkill($)}async installFromRepo($,Z){let Y=Z||this.extractRepoName($),Q=z$.join(this.skillsDir,Y),X=z$.join(this.skillsDir,`.tmp-repo-${Y}-${Date.now()}`);try{if(!await this.isGitAvailable())return _$.warn("Git not available, cannot install from repo"),!1;_$.info(`Installing skill from repo: ${$}...`),await R0.mkdir(this.skillsDir,{recursive:!0,mode:493}),await f7(`git clone --depth 1 "${$}" "${X}"`,{timeout:60000});let J=z$.join(X,"SKILL.md");try{await R0.access(J)}catch{return _$.warn(`No SKILL.md found in repository ${$}`),await R0.rm(X,{recursive:!0,force:!0}),!1}await R0.rm(Q,{recursive:!0,force:!0}),await R0.rename(X,Q);try{await R0.rm(z$.join(Q,".git"),{recursive:!0,force:!0})}catch{}return _$.info(`Successfully installed skill from repo: ${Y}`),!0}catch(J){try{await R0.rm(X,{recursive:!0,force:!0})}catch{}return _$.warn(`Failed to install from repo ${$}: ${J instanceof Error?J.message:"Unknown error"}`),!1}}async installFromLocal($,Z,Y=!0){let Q=Z||z$.basename($),X=z$.join(this.skillsDir,Q);try{let J=z$.resolve($);try{await R0.access(J)}catch{return _$.warn(`Local path does not exist: ${J}`),!1}let G=z$.join(J,"SKILL.md");try{await R0.access(G)}catch{return _$.warn(`No SKILL.md found in local path: ${J}`),!1}if(_$.info(`Installing skill from local path: ${J}...`),await R0.mkdir(this.skillsDir,{recursive:!0,mode:493}),await R0.rm(X,{recursive:!0,force:!0}),Y)await R0.symlink(J,X,"dir"),_$.info(`Created symlink for skill: ${Q}`);else await R0.cp(J,X,{recursive:!0}),_$.info(`Copied skill to: ${Q}`);return!0}catch(J){return _$.warn(`Failed to install from local path ${$}: ${J instanceof Error?J.message:"Unknown error"}`),!1}}extractRepoName($){return $.match(/\/([^/]+?)(\.git)?$/)?.[1]||"unknown-skill"}async installAllOfficialSkills(){let{url:$,branch:Z}=D9,Y=z$.join(this.skillsDir,`.tmp-all-${Date.now()}`),Q=[],X=[];try{if(!await this.isGitAvailable())return _$.warn("Git not available, skipping skill installation"),{installed:Q,failed:X};await R0.mkdir(this.skillsDir,{recursive:!0,mode:493}),_$.info("Cloning official skills repository..."),await f7(`git clone --depth 1 --branch ${Z} --single-branch ${$} "${Y}"`,{timeout:60000});let J=z$.join(Y,"skills"),G=await R0.readdir(J,{withFileTypes:!0});for(let q of G){if(!q.isDirectory())continue;let K=q.name,W=z$.join(J,K),U=z$.join(this.skillsDir,K);try{await R0.access(z$.join(W,"SKILL.md")),await R0.rm(U,{recursive:!0,force:!0}),await R0.cp(W,U,{recursive:!0}),_$.info(`Installed: ${K}`),Q.push(K)}catch(O){_$.warn(`Failed to install ${K}`),X.push(K)}}await R0.rm(Y,{recursive:!0,force:!0})}catch(J){try{await R0.rm(Y,{recursive:!0,force:!0})}catch{}_$.warn(`Failed to install skills: ${J instanceof Error?J.message:"Unknown error"}`)}return{installed:Q,failed:X}}}function h7($){if(!j9)j9=new XJ($);return j9}var f7,_$,D9,j9=null;var y9=R(()=>{Q0();f7=o_(a_),_$=x("General"),D9={url:"https://github.com/anthropics/skills.git",branch:"main",defaultSkills:["skill-creator"]}});import*as E3 from"node:fs/promises";import*as x7 from"node:path";import{parse as s_}from"yaml";function $z($){if(!$)return;if(typeof $==="string")return $.split(",").map((Z)=>Z.trim()).filter(Boolean);if(Array.isArray($))return $.map((Z)=>String(Z).trim()).filter(Boolean);return}function GJ($){if($===void 0)return;if(typeof $==="boolean")return $;if(typeof $==="string"){let Z=$.toLowerCase().trim();if(Z==="true"||Z==="yes"||Z==="1")return!0;if(Z==="false"||Z==="no"||Z==="0")return!1}return}function Zz($,Z){if(!$.name)return{valid:!1,error:"Missing required field: name"};if(!e_.test($.name))return{valid:!1,error:`Invalid name "${$.name}": must be lowercase letters, numbers, and hyphens only, 1-64 characters`};if(!$.description)return{valid:!1,error:"Missing required field: description"};if($.description.length>JJ)return{valid:!1,error:`Description too long: ${$.description.length} characters (max ${JJ})`};let Y;if($.model)Y=$.model==="inherit"?"inherit":$.model;return{valid:!0,metadata:{name:$.name,description:$.description.trim(),allowedTools:$z($["allowed-tools"]),version:$.version,argumentHint:$["argument-hint"]?.trim(),userInvocable:GJ($["user-invocable"]),disableModelInvocation:GJ($["disable-model-invocation"]),model:Y,whenToUse:$.when_to_use?.trim()}}}function qJ($,Z,Y){let Q=$.match(t_);if(!Q)return{success:!1,error:"Invalid SKILL.md format: missing YAML frontmatter (must start with ---)"};let[,X,J]=Q,G;try{G=s_(X)}catch(W){return{success:!1,error:`Failed to parse YAML frontmatter: ${W instanceof Error?W.message:String(W)}`}}let q=Zz(G,Z);if(!q.valid)return{success:!1,error:q.error};let K=x7.dirname(Z);return{success:!0,content:{metadata:{...q.metadata,path:Z,basePath:K,source:Y},instructions:J.trim()}}}async function p7($,Z){try{let Y=await E3.readFile($,"utf-8");return qJ(Y,$,Z)}catch(Y){if(Y.code==="ENOENT")return{success:!1,error:`File not found: ${$}`};return{success:!1,error:`Failed to read file: ${Y instanceof Error?Y.message:String(Y)}`}}}async function KJ($){try{let Z=await E3.readFile($.path,"utf-8"),Y=qJ(Z,$.path,$.source);return Y.success?Y.content:null}catch{return null}}async function WJ($){try{return await E3.access(x7.join($,"SKILL.md")),!0}catch{return!1}}var t_,e_,JJ=1024;var T9=R(()=>{t_=/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/,e_=/^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]?$/});import*as g7 from"node:fs/promises";import{homedir as UJ}from"node:os";import*as q2 from"node:path";class E9{skills=new Map;pluginSkills=new Map;config;initialized=!1;constructor($){this.config={...Yz,...$}}static getInstance($){if(!m7)m7=new E9($);return m7}static resetInstance(){m7=null}async initialize(){if(this.initialized)return{skills:Array.from(this.skills.values()),errors:[]};let $=[],Z=[];try{await h7(this.config.userSkillsDir).ensureDefaultSkillsInstalled()}catch(K){$.push({path:"SkillInstaller",error:`Failed to install default skills: ${K instanceof Error?K.message:"Unknown error"}`})}this.loadBuiltinSkills();let Y=await this.scanDirectory(this.config.claudeUserSkillsDir,"user");Z.push(...Y.skills),$.push(...Y.errors);let Q=await this.scanDirectory(this.config.userSkillsDir,"user");Z.push(...Q.skills),$.push(...Q.errors);let X=q2.isAbsolute(this.config.claudeProjectSkillsDir)?this.config.claudeProjectSkillsDir:q2.join(this.config.cwd,this.config.claudeProjectSkillsDir),J=await this.scanDirectory(X,"project");Z.push(...J.skills),$.push(...J.errors);let G=q2.isAbsolute(this.config.projectSkillsDir)?this.config.projectSkillsDir:q2.join(this.config.cwd,this.config.projectSkillsDir),q=await this.scanDirectory(G,"project");Z.push(...q.skills),$.push(...q.errors);for(let K of Z)this.skills.set(K.name,K);return this.initialized=!0,{skills:Array.from(this.skills.values()),errors:$}}loadBuiltinSkills(){this.skills.set(k7.name,k7)}async scanDirectory($,Z){let Y=[],Q=[];try{await g7.access($)}catch{return{skills:Y,errors:Q}}try{let X=await g7.readdir($,{withFileTypes:!0});for(let J of X){if(!J.isDirectory())continue;let G=q2.join($,J.name),q=q2.join(G,"SKILL.md");if(!await WJ(G))continue;let K=await p7(q,Z);if(K.success&&K.content)Y.push(K.content.metadata);else Q.push({path:q,error:K.error||"Unknown error"})}}catch(X){Q.push({path:$,error:`Failed to scan directory: ${X instanceof Error?X.message:String(X)}`})}return{skills:Y,errors:Q}}getAll(){return Array.from(this.skills.values())}get($){return this.skills.get($)}has($){return this.skills.has($)}async loadContent($){let Z=this.skills.get($);if(!Z)return null;if(Z.source==="builtin")return this.loadBuiltinContent($);return KJ(Z)}loadBuiltinContent($){switch($){case"skill-creator":return YJ();default:return null}}getModelInvocableSkills(){return Array.from(this.skills.values()).filter(($)=>!$.disableModelInvocation)}getUserInvocableSkills(){return Array.from(this.skills.values()).filter(($)=>$.userInvocable===!0)}generateAvailableSkillsList(){let $=this.getModelInvocableSkills();if($.length===0)return"";let Z=[];for(let Y of $){let Q=Y.description.length>100?`${Y.description.substring(0,97)}...`:Y.description,X=Y.argumentHint?`${Y.name} ${Y.argumentHint}`:Y.name;Z.push(`- ${X}: ${Q}`)}return Z.join(`
454
+ `)}get size(){return this.skills.size}async refresh(){return this.skills.clear(),this.pluginSkills.clear(),this.initialized=!1,this.initialize()}registerPluginSkill($){this.pluginSkills.set($.namespacedName,$),this.skills.set($.namespacedName,$.metadata)}findPluginSkill($){let Z=this.pluginSkills.get($);if(Z)return Z;let Y=[];for(let Q of this.pluginSkills.values())if(Q.originalName===$)Y.push(Q);if(Y.length===1)return Y[0];return}getAllPluginSkills(){return Array.from(this.pluginSkills.values())}clearPluginSkills(){for(let $ of this.pluginSkills.values())this.skills.delete($.namespacedName);this.pluginSkills.clear()}getPluginSkillCount(){return this.pluginSkills.size}}function J$($){return E9.getInstance($)}async function v4($){return J$($).initialize()}var Yz,m7=null;var I9=R(()=>{QJ();y9();T9();Yz={userSkillsDir:q2.join(UJ(),".blade","skills"),projectSkillsDir:".blade/skills",claudeUserSkillsDir:q2.join(UJ(),".claude","skills"),claudeProjectSkillsDir:".claude/skills",cwd:process.cwd()}});function v9($){let Y=J$().generateAvailableSkillsList();if(!Y)return $;return $.map((Q)=>{if(Q.name!==Qz)return Q;let X=Q.description.replace(Xz,`<available_skills>
455
455
  ${Y}
456
- </available_skills>`);if(X===Q.description)return Q;return{...Q,description:X}})}var Qz="Skill",Xz;var OJ=R(()=>{I9();Xz=/<available_skills>\s*<\/available_skills>/});var K2=R(()=>{OJ();I9()});import{execSync as Jz}from"child_process";import*as b8 from"os";import*as A8 from"path";function Gz(){let $=process.cwd(),Z=qz($);return{workingDirectory:$,projectRoot:Z,platform:`${b8.platform()} (${b8.arch()})`,nodeVersion:process.version,currentDate:new Date().toISOString().split("T")[0],homeDirectory:b8.homedir()}}function u6(){let $=Gz();return`# Environment Context
456
+ </available_skills>`);if(X===Q.description)return Q;return{...Q,description:X}})}var Qz="Skill",Xz;var OJ=R(()=>{I9();Xz=/<available_skills>\s*<\/available_skills>/});var K2=R(()=>{OJ();I9()});import{execSync as Jz}from"child_process";import*as b8 from"os";import*as A8 from"path";function Gz(){let $=process.cwd(),Z=qz($);return{workingDirectory:$,projectRoot:Z,platform:`${b8.platform()} (${b8.arch()})`,nodeVersion:process.version,currentDate:new Date().toISOString().split("T")[0],homeDirectory:b8.homedir()}}function u7(){let $=Gz();return`# Environment Context
457
457
 
458
458
  ## Working Directory
459
459
  **Current**: \`${$.workingDirectory}\`
@@ -776,7 +776,7 @@ When all tasks are complete, use ExitSpecMode with archive: true to finish.
776
776
  ## Phase: Done
777
777
 
778
778
  The spec is complete. Use ExitSpecMode if you haven't already.
779
- `;default:return""}}function d6($,Z){let Y=[Kz];if($){if(Y.push(`
779
+ `;default:return""}}function d7($,Z){let Y=[Kz];if($){if(Y.push(`
780
780
  ---
781
781
 
782
782
  ## Current Spec: ${$.name}
@@ -794,7 +794,7 @@ The following project governance documents are available:
794
794
 
795
795
  ${Z}
796
796
  `);return Y.join(`
797
- `)}function c6($){return`<spec-mode-reminder>
797
+ `)}function c7($){return`<spec-mode-reminder>
798
798
  You are in Spec Mode (${I$[$]} phase).
799
799
  - Use Spec tools: UpdateSpec, GetSpecContext, TransitionSpecPhase, ValidateSpec
800
800
  - Follow the workflow: Requirements → Design → Tasks → Implementation
@@ -852,13 +852,13 @@ Show current progress and suggest next steps based on actual project state.
852
852
  3. **User confirmation** - Wait for user approval before implementation
853
853
  4. **Proactive guidance** - Guide users through the workflow
854
854
  5. **State transparency** - Always show current phase and progress
855
- `;var C9=R(()=>{g1()});import{promises as zJ}from"fs";import Uz from"path";async function v3($={}){let{projectPath:Z,replaceDefault:Y,append:Q,mode:X,includeEnvironment:J=!0,currentSpec:G,steeringContext:q,language:K}=$,W=[],U=[];if(J){let w=u6();if(w)W.push(w),U.push({name:"environment",loaded:!0,length:w.length})}let O=X==="plan",F=X==="spec",H,_;if(F)H=d6(G??null,q??null),_="spec_mode_prompt";else if(O)H=_J,_="plan_mode_prompt";else H=Y??HJ,_=Y?"replace_default":"default";if(W.push(H),U.push({name:_,loaded:!0,length:H.length}),Z){let w=await zz(Z);if(w)W.push(w),U.push({name:"blade_md",loaded:!0,length:w.length});else U.push({name:"blade_md",loaded:!1})}if(Q?.trim())W.push(Q.trim()),U.push({name:"append",loaded:!0,length:Q.trim().length});let z=W.join(`
855
+ `;var C9=R(()=>{g1()});import{promises as zJ}from"fs";import Uz from"path";async function v3($={}){let{projectPath:Z,replaceDefault:Y,append:Q,mode:X,includeEnvironment:J=!0,currentSpec:G,steeringContext:q,language:K}=$,W=[],U=[];if(J){let w=u7();if(w)W.push(w),U.push({name:"environment",loaded:!0,length:w.length})}let O=X==="plan",F=X==="spec",H,_;if(F)H=d7(G??null,q??null),_="spec_mode_prompt";else if(O)H=_J,_="plan_mode_prompt";else H=Y??HJ,_=Y?"replace_default":"default";if(W.push(H),U.push({name:_,loaded:!0,length:H.length}),Z){let w=await zz(Z);if(w)W.push(w),U.push({name:"blade_md",loaded:!0,length:w.length});else U.push({name:"blade_md",loaded:!1})}if(Q?.trim())W.push(Q.trim()),U.push({name:"append",loaded:!0,length:Q.trim().length});let z=W.join(`
856
856
 
857
857
  ---
858
858
 
859
859
  `);return z=Fz(z),z=_z(z,K),{prompt:z,sources:U}}function Fz($){let Y=J$().generateAvailableSkillsList();if(!Y)return $;return $.replace(Oz,`<available_skills>
860
860
  ${Y}
861
- </available_skills>`)}function _z($,Z){let Y=Z||"zh-CN",Q=Hz[Y]||Y,X=`IMPORTANT: Always respond in ${Q}. All your responses must be in ${Q}.`;return $.replace("{{LANGUAGE_INSTRUCTION}}",X)}async function zz($){let Z=Uz.join($,"BLADE.md");try{return(await zJ.readFile(Z,"utf-8")).trim()||null}catch{return null}}var Oz,Hz;var BJ=R(()=>{U$();K2();P9();C9();Oz=/<available_skills>\s*<\/available_skills>/;Hz={"zh-CN":"Chinese (Simplified Chinese)","zh-TW":"Chinese (Traditional Chinese)","en-US":"English","en-GB":"English (British)","ja-JP":"Japanese","ko-KR":"Korean","es-ES":"Spanish","fr-FR":"French","de-DE":"German","pt-BR":"Portuguese (Brazilian)","ru-RU":"Russian"}});var wJ=R(()=>{BJ()});function LJ($){return $.endsWith("/")||$.endsWith("\\")}function P3($){return $.replace(/\\/g,"/").split("/").filter(Boolean)}import*as l6 from"fs/promises";import*as a$ from"path";class i6{static normalize($,Z){let Y=a$.isAbsolute($)?$:a$.resolve(Z,$),Q=a$.normalize(Y),X=a$.normalize(Z);if(!Q.startsWith(X))throw new P4(`Path outside workspace: ${$} (resolved to ${Q}, workspace: ${X})`,"PATH_OUTSIDE_WORKSPACE");return Q}static checkRestricted($){let Z=$.split(a$.sep);for(let Y of NJ)if(Z.includes(Y))throw new P4(`Access denied: "${Y}" is a protected directory`,"RESTRICTED_PATH")}static checkTraversal($){if($.includes(".."))throw new P4(`Path traversal not allowed: ${$}`,"PATH_TRAVERSAL")}static async validatePath($,Z){this.checkTraversal($);let Y=this.normalize($,Z);this.checkRestricted(Y);try{await l6.access(Y)}catch(Q){throw new P4(`Path not found: ${$}`,"PATH_NOT_FOUND")}return Y}static async resolveSymlink($,Z){try{let Y=await l6.realpath($),Q=a$.normalize(Z);if(!Y.startsWith(Q))throw new P4(`Symlink points outside workspace: ${$} -> ${Y}`,"SYMLINK_OUTSIDE_WORKSPACE");return Y}catch(Y){if(Y instanceof P4)throw Y;return $}}static getRelativePath($,Z){return a$.relative(Z,$)}static isWithinWorkspace($,Z){let Y=a$.normalize($),Q=a$.normalize(Z);return Y.startsWith(Q)}static isRestricted($){let Z=$.split(a$.sep);return NJ.some((Y)=>Z.includes(Y))}}var NJ,P4;var AJ=R(()=>{NJ=[".git",".claude","node_modules",".env",".env.local",".env.production",".env.development",".env.test"];P4=class P4 extends Error{code;constructor($,Z){super($);this.code=Z;this.name="PathSecurityError"}}});var r6;var bJ=R(()=>{r6=class r6{static PATTERN=/@"([^"]+)"|@([^\s]+)/g;static LINE_RANGE_PATTERN=/#L(\d+)(?:-(\d+))?$/;static GLOB_PATTERN=/[*?[\]]/;static extract($){let Z=[],Y;this.PATTERN.lastIndex=0;while((Y=this.PATTERN.exec($))!==null){let Q=Y[0],X=Y[1]||Y[2],J=this.parseLineRange(X);if(J)X=X.replace(this.LINE_RANGE_PATTERN,"");let G=this.GLOB_PATTERN.test(X);Z.push({raw:Q,path:X.trim(),lineRange:J,startIndex:Y.index,endIndex:Y.index+Q.length,isGlob:G})}return Z}static parseLineRange($){let Z=$.match(this.LINE_RANGE_PATTERN);if(!Z)return;let Y=parseInt(Z[1],10),Q=Z[2]?parseInt(Z[2],10):void 0;return{start:Y,end:Q}}static hasAtMentions($){return $.includes("@")}static isValidPath($){if(!$||$.trim().length===0)return!1;let Z=["<",">","|","\x00"];for(let Y of Z)if($.includes(Y))return!1;return!0}static removeAtMentions($){return this.PATTERN.lastIndex=0,$.replace(this.PATTERN,"")}}});import RJ from"fast-glob";import*as R8 from"fs/promises";import*as VJ from"path";function a6($){return $ instanceof Map}class S9{fileCache=new Map;options;constructor($){this.options={maxFileSize:1048576,maxLines:2000,maxTokens:32000,...$},r1.debug("AttachmentCollector initialized",{maxFileSize:this.options.maxFileSize,maxLines:this.options.maxLines})}async collect($){if(!r6.hasAtMentions($))return[];let Z=r6.extract($);if(Z.length===0)return[];r1.debug(`Found ${Z.length} @ mentions`);let Y=Z.map((X)=>this.processOne(X));return(await Promise.allSettled(Y)).map((X,J)=>{if(X.status==="fulfilled")return X.value;else{let G=Z[J],q=X.reason instanceof Error?X.reason.message:String(X.reason);return r1.warn(`Failed to process @${G.path}:`,q),{type:"error",path:G.path,content:"",error:q}}})}async processOne($){if($.isGlob)return r1.debug(`Processing glob pattern: ${$.path}`),await this.processGlob($.path);let Z=await i6.validatePath($.path,this.options.cwd),Y=await i6.resolveSymlink(Z,this.options.cwd);if((await R8.stat(Y)).isDirectory())return r1.debug(`Processing directory: ${$.path}`),await this.renderDirectoryTree(Y,$.path);return r1.debug(`Processing file: ${$.path}`,{lineRange:$.lineRange}),await this.readFile(Y,$.path,$.lineRange)}async readFile($,Z,Y){let Q=this.fileCache.get($);if(Q&&Date.now()-Q.timestamp<60000)return r1.debug(`Cache hit: ${Z}`),this.formatFileAttachment(Z,Q.content,Y);let X=await R8.stat($);if(X.size>this.options.maxFileSize)throw Error(`File too large: ${Math.round(X.size/1024/1024)}MB (max ${Math.round(this.options.maxFileSize/1024/1024)}MB)`);let J;try{J=await R8.readFile($,"utf-8")}catch(G){throw Error(`Cannot read file as text: ${Z}. It may be a binary file.`)}return this.fileCache.set($,{content:J,timestamp:Date.now()}),this.formatFileAttachment(Z,J,Y)}formatFileAttachment($,Z,Y){let Q=Z.split(`
861
+ </available_skills>`)}function _z($,Z){let Y=Z||"zh-CN",Q=Hz[Y]||Y,X=`IMPORTANT: Always respond in ${Q}. All your responses must be in ${Q}.`;return $.replace("{{LANGUAGE_INSTRUCTION}}",X)}async function zz($){let Z=Uz.join($,"BLADE.md");try{return(await zJ.readFile(Z,"utf-8")).trim()||null}catch{return null}}var Oz,Hz;var BJ=R(()=>{U$();K2();P9();C9();Oz=/<available_skills>\s*<\/available_skills>/;Hz={"zh-CN":"Chinese (Simplified Chinese)","zh-TW":"Chinese (Traditional Chinese)","en-US":"English","en-GB":"English (British)","ja-JP":"Japanese","ko-KR":"Korean","es-ES":"Spanish","fr-FR":"French","de-DE":"German","pt-BR":"Portuguese (Brazilian)","ru-RU":"Russian"}});var wJ=R(()=>{BJ()});function LJ($){return $.endsWith("/")||$.endsWith("\\")}function P3($){return $.replace(/\\/g,"/").split("/").filter(Boolean)}import*as l7 from"fs/promises";import*as a$ from"path";class i7{static normalize($,Z){let Y=a$.isAbsolute($)?$:a$.resolve(Z,$),Q=a$.normalize(Y),X=a$.normalize(Z);if(!Q.startsWith(X))throw new P4(`Path outside workspace: ${$} (resolved to ${Q}, workspace: ${X})`,"PATH_OUTSIDE_WORKSPACE");return Q}static checkRestricted($){let Z=$.split(a$.sep);for(let Y of NJ)if(Z.includes(Y))throw new P4(`Access denied: "${Y}" is a protected directory`,"RESTRICTED_PATH")}static checkTraversal($){if($.includes(".."))throw new P4(`Path traversal not allowed: ${$}`,"PATH_TRAVERSAL")}static async validatePath($,Z){this.checkTraversal($);let Y=this.normalize($,Z);this.checkRestricted(Y);try{await l7.access(Y)}catch(Q){throw new P4(`Path not found: ${$}`,"PATH_NOT_FOUND")}return Y}static async resolveSymlink($,Z){try{let Y=await l7.realpath($),Q=a$.normalize(Z);if(!Y.startsWith(Q))throw new P4(`Symlink points outside workspace: ${$} -> ${Y}`,"SYMLINK_OUTSIDE_WORKSPACE");return Y}catch(Y){if(Y instanceof P4)throw Y;return $}}static getRelativePath($,Z){return a$.relative(Z,$)}static isWithinWorkspace($,Z){let Y=a$.normalize($),Q=a$.normalize(Z);return Y.startsWith(Q)}static isRestricted($){let Z=$.split(a$.sep);return NJ.some((Y)=>Z.includes(Y))}}var NJ,P4;var AJ=R(()=>{NJ=[".git",".claude","node_modules",".env",".env.local",".env.production",".env.development",".env.test"];P4=class P4 extends Error{code;constructor($,Z){super($);this.code=Z;this.name="PathSecurityError"}}});var r7;var bJ=R(()=>{r7=class r7{static PATTERN=/@"([^"]+)"|@([^\s]+)/g;static LINE_RANGE_PATTERN=/#L(\d+)(?:-(\d+))?$/;static GLOB_PATTERN=/[*?[\]]/;static extract($){let Z=[],Y;this.PATTERN.lastIndex=0;while((Y=this.PATTERN.exec($))!==null){let Q=Y[0],X=Y[1]||Y[2],J=this.parseLineRange(X);if(J)X=X.replace(this.LINE_RANGE_PATTERN,"");let G=this.GLOB_PATTERN.test(X);Z.push({raw:Q,path:X.trim(),lineRange:J,startIndex:Y.index,endIndex:Y.index+Q.length,isGlob:G})}return Z}static parseLineRange($){let Z=$.match(this.LINE_RANGE_PATTERN);if(!Z)return;let Y=parseInt(Z[1],10),Q=Z[2]?parseInt(Z[2],10):void 0;return{start:Y,end:Q}}static hasAtMentions($){return $.includes("@")}static isValidPath($){if(!$||$.trim().length===0)return!1;let Z=["<",">","|","\x00"];for(let Y of Z)if($.includes(Y))return!1;return!0}static removeAtMentions($){return this.PATTERN.lastIndex=0,$.replace(this.PATTERN,"")}}});import RJ from"fast-glob";import*as R8 from"fs/promises";import*as VJ from"path";function a7($){return $ instanceof Map}class S9{fileCache=new Map;options;constructor($){this.options={maxFileSize:1048576,maxLines:2000,maxTokens:32000,...$},r1.debug("AttachmentCollector initialized",{maxFileSize:this.options.maxFileSize,maxLines:this.options.maxLines})}async collect($){if(!r7.hasAtMentions($))return[];let Z=r7.extract($);if(Z.length===0)return[];r1.debug(`Found ${Z.length} @ mentions`);let Y=Z.map((X)=>this.processOne(X));return(await Promise.allSettled(Y)).map((X,J)=>{if(X.status==="fulfilled")return X.value;else{let G=Z[J],q=X.reason instanceof Error?X.reason.message:String(X.reason);return r1.warn(`Failed to process @${G.path}:`,q),{type:"error",path:G.path,content:"",error:q}}})}async processOne($){if($.isGlob)return r1.debug(`Processing glob pattern: ${$.path}`),await this.processGlob($.path);let Z=await i7.validatePath($.path,this.options.cwd),Y=await i7.resolveSymlink(Z,this.options.cwd);if((await R8.stat(Y)).isDirectory())return r1.debug(`Processing directory: ${$.path}`),await this.renderDirectoryTree(Y,$.path);return r1.debug(`Processing file: ${$.path}`,{lineRange:$.lineRange}),await this.readFile(Y,$.path,$.lineRange)}async readFile($,Z,Y){let Q=this.fileCache.get($);if(Q&&Date.now()-Q.timestamp<60000)return r1.debug(`Cache hit: ${Z}`),this.formatFileAttachment(Z,Q.content,Y);let X=await R8.stat($);if(X.size>this.options.maxFileSize)throw Error(`File too large: ${Math.round(X.size/1024/1024)}MB (max ${Math.round(this.options.maxFileSize/1024/1024)}MB)`);let J;try{J=await R8.readFile($,"utf-8")}catch(G){throw Error(`Cannot read file as text: ${Z}. It may be a binary file.`)}return this.fileCache.set($,{content:J,timestamp:Date.now()}),this.formatFileAttachment(Z,J,Y)}formatFileAttachment($,Z,Y){let Q=Z.split(`
862
862
  `),X=Z,J=!1,G=Y;if(Y){let q=Math.max(0,Y.start-1),K=Y.end?Y.end:Y.start;if(q>=Q.length)throw Error(`Line range start (${Y.start}) exceeds file length (${Q.length} lines)`);let W=Math.min(K,Q.length);X=Q.slice(q,W).join(`
863
863
  `);let U=Array.from({length:W-q},(F,H)=>q+H+1);X=X.split(`
864
864
  `).map((F,H)=>`${U[H]}: ${F}`).join(`
@@ -867,7 +867,7 @@ ${Y}
867
867
 
868
868
  [... truncated ${Q.length-this.options.maxLines} lines ...]`,J=!0;return{type:"file",path:$,content:X,metadata:{size:Z.length,lines:Q.length,truncated:J,lineRange:G}}}async renderDirectoryTree($,Z){let Y=await RJ("**/*",{cwd:$,dot:!1,followSymbolicLinks:!1,onlyFiles:!0,unique:!0,ignore:["node_modules/**",".git/**","dist/**","build/**",".next/**",".cache/**","coverage/**"]});if(Y.length===0)return{type:"directory",path:Z,content:"(empty directory)"};r1.debug(`Found ${Y.length} files in directory: ${Z}`);let Q=this.buildFileTree(Y),X=this.printTree(Q,Z),J=500,G=Y.length>J?`
869
869
 
870
- [... and ${Y.length-J} more files]`:"";return{type:"directory",path:Z,content:X+G,metadata:{lines:Y.length,truncated:Y.length>J}}}buildFileTree($){let Z=new Map;for(let Y of $){let Q=P3(Y),X=Z;for(let J=0;J<Q.length;J++){let G=Q[J],q=J===Q.length-1;if(!X.has(G))X.set(G,q?null:new Map);if(!q){let K=X.get(G);if(K&&a6(K))X=K}}}return Z}printTree($,Z,Y="",Q=!0){let X=[];if(Y==="")X.push(`${Z}/`);let J=Array.from($.entries()).sort((G,q)=>{let K=a6(G[1]),W=a6(q[1]);if(K!==W)return W?1:-1;return G[0].localeCompare(q[0])});return J.forEach(([G,q],K)=>{let W=K===J.length-1,U=W?"└── ":"├── ",O=a6(q);if(X.push(`${Y}${U}${G}${O?"/":""}`),O&&q.size>0){let F=Y+(W?" ":"│ ");X.push(this.printTree(q,"",F,W))}}),X.filter((G)=>G).join(`
870
+ [... and ${Y.length-J} more files]`:"";return{type:"directory",path:Z,content:X+G,metadata:{lines:Y.length,truncated:Y.length>J}}}buildFileTree($){let Z=new Map;for(let Y of $){let Q=P3(Y),X=Z;for(let J=0;J<Q.length;J++){let G=Q[J],q=J===Q.length-1;if(!X.has(G))X.set(G,q?null:new Map);if(!q){let K=X.get(G);if(K&&a7(K))X=K}}}return Z}printTree($,Z,Y="",Q=!0){let X=[];if(Y==="")X.push(`${Z}/`);let J=Array.from($.entries()).sort((G,q)=>{let K=a7(G[1]),W=a7(q[1]);if(K!==W)return W?1:-1;return G[0].localeCompare(q[0])});return J.forEach(([G,q],K)=>{let W=K===J.length-1,U=W?"└── ":"├── ",O=a7(q);if(X.push(`${Y}${U}${G}${O?"/":""}`),O&&q.size>0){let F=Y+(W?" ":"│ ");X.push(this.printTree(q,"",F,W))}}),X.filter((G)=>G).join(`
871
871
  `)}async processGlob($){let Z=await RJ($,{cwd:this.options.cwd,dot:!1,followSymbolicLinks:!1,onlyFiles:!0,unique:!0,ignore:["node_modules/**",".git/**","dist/**","build/**",".next/**",".cache/**","coverage/**"]});if(Z.length===0)return{type:"error",path:$,content:"",error:`No files matched pattern: ${$}`};r1.debug(`Glob pattern "${$}" matched ${Z.length} files`);let Y=30,Q=Z.slice(0,Y),J=(await Promise.allSettled(Q.map(async(W)=>{let U=VJ.join(this.options.cwd,W);try{let O=await R8.readFile(U,"utf-8"),F=O.split(`
872
872
  `),H=200,_=O,z=!1;if(F.length>200)_=F.slice(0,200).join(`
873
873
  `),_+=`
@@ -877,7 +877,7 @@ ${W.content}`).join(`
877
877
 
878
878
  `),K=Z.length>Y?`
879
879
 
880
- [... and ${Z.length-Y} more files matched]`:"";return{type:"file",path:$,content:q+K,metadata:{lines:J.reduce((W,U)=>W+U.lines,0),truncated:Z.length>Y||J.some((W)=>W.truncated)}}}clearExpiredCache(){let $=Date.now(),Z=0;for(let[Y,Q]of this.fileCache.entries())if($-Q.timestamp>60000)this.fileCache.delete(Y),Z++;if(Z>0)r1.debug(`Cleared ${Z} expired cache entries`)}clearCache(){this.fileCache.clear(),r1.debug("Cleared all cache")}getCacheStats(){return{size:this.fileCache.size,keys:Array.from(this.fileCache.keys())}}}var r1;var MJ=R(()=>{Q0();AJ();bJ();r1=x("Prompts")});import{nanoid as Bz}from"nanoid";class x0{static instance=null;fileManager=null;constructor(){}static getInstance(){if(!x0.instance)x0.instance=new x0;return x0.instance}static resetInstance(){x0.instance=null}getStoreState(){return u1.getState().spec}updateStoreState($){u1.setState((Z)=>({spec:{...Z.spec,...$}}))}async initialize($){if(this.fileManager){n6.debug("SpecManager already initialized, skipping...");return}this.fileManager=new y4($),await this.fileManager.initializeDirectories();let Z=await this.fileManager.readSteeringContext();this.updateStoreState({steeringContext:Z}),n6.debug("SpecManager initialized successfully")}getFileManager(){if(!this.fileManager)throw Error("SpecManager not initialized. Call initialize() first.");return this.fileManager}getState(){return{...this.getStoreState()}}getCurrentSpec(){return this.getStoreState().currentSpec}isActive(){return this.getStoreState().isActive}getSteeringContext(){return this.getStoreState().steeringContext}async getSteeringContextString(){let $=this.getStoreState().steeringContext;if(!$)return null;let Z=[];if($.constitution)Z.push(`## Constitution (Project Governance)
880
+ [... and ${Z.length-Y} more files matched]`:"";return{type:"file",path:$,content:q+K,metadata:{lines:J.reduce((W,U)=>W+U.lines,0),truncated:Z.length>Y||J.some((W)=>W.truncated)}}}clearExpiredCache(){let $=Date.now(),Z=0;for(let[Y,Q]of this.fileCache.entries())if($-Q.timestamp>60000)this.fileCache.delete(Y),Z++;if(Z>0)r1.debug(`Cleared ${Z} expired cache entries`)}clearCache(){this.fileCache.clear(),r1.debug("Cleared all cache")}getCacheStats(){return{size:this.fileCache.size,keys:Array.from(this.fileCache.keys())}}}var r1;var MJ=R(()=>{Q0();AJ();bJ();r1=x("Prompts")});import{nanoid as Bz}from"nanoid";class x0{static instance=null;fileManager=null;constructor(){}static getInstance(){if(!x0.instance)x0.instance=new x0;return x0.instance}static resetInstance(){x0.instance=null}getStoreState(){return u1.getState().spec}updateStoreState($){u1.setState((Z)=>({spec:{...Z.spec,...$}}))}async initialize($){if(this.fileManager){n7.debug("SpecManager already initialized, skipping...");return}this.fileManager=new y4($),await this.fileManager.initializeDirectories();let Z=await this.fileManager.readSteeringContext();this.updateStoreState({steeringContext:Z}),n7.debug("SpecManager initialized successfully")}getFileManager(){if(!this.fileManager)throw Error("SpecManager not initialized. Call initialize() first.");return this.fileManager}getState(){return{...this.getStoreState()}}getCurrentSpec(){return this.getStoreState().currentSpec}isActive(){return this.getStoreState().isActive}getSteeringContext(){return this.getStoreState().steeringContext}async getSteeringContextString(){let $=this.getStoreState().steeringContext;if(!$)return null;let Z=[];if($.constitution)Z.push(`## Constitution (Project Governance)
881
881
 
882
882
  ${$.constitution}`);if($.product)Z.push(`## Product Vision
883
883
 
@@ -889,7 +889,7 @@ ${$.structure}`);return Z.length>0?Z.join(`
889
889
 
890
890
  ---
891
891
 
892
- `):null}async createSpec($,Z){let Y=this.getFileManager();if(await Y.changeExists($))return{success:!1,message:`Spec "${$}" already exists`,error:"SPEC_EXISTS"};let Q=await Y.createChangeDir($),X=Y.createMetadata($,Z);await Y.writeMetadata($,X);let J=this.generateProposalTemplate($,Z);await Y.writeSpecFile($,"proposal",J);let G=this.getStoreState().recentSpecs.filter((q)=>q!==$);return G.unshift($),this.updateStoreState({currentSpec:X,specPath:Q,isActive:!0,recentSpecs:G.slice(0,10)}),{success:!0,message:`Spec "${$}" created successfully`,data:{spec:X,path:Q}}}async loadSpec($){let Z=this.getFileManager(),Y=await Z.readMetadata($);if(!Y)return{success:!1,message:`Spec "${$}" not found`,error:"SPEC_NOT_FOUND"};let Q=Z.getChangePath($),X=this.getStoreState().recentSpecs.filter((J)=>J!==$);return X.unshift($),this.updateStoreState({currentSpec:Y,specPath:Q,isActive:!0,recentSpecs:X.slice(0,10)}),{success:!0,message:`Spec "${$}" loaded successfully`,data:{spec:Y,path:Q}}}closeSpec(){this.updateStoreState({currentSpec:null,specPath:null,isActive:!1})}exitSpecMode(){this.closeSpec()}async transitionPhase($){let Z=this.getCurrentSpec();if(!Z)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};if(!J2[Z.phase].includes($))return{success:!1,message:`Cannot transition from "${Z.phase}" to "${$}"`,error:"INVALID_TRANSITION"};let X=await this.getFileManager().updatePhase(Z.name,$);if(!X)return{success:!1,message:"Failed to update phase",error:"UPDATE_FAILED"};if(this.updateStoreState({currentSpec:X}),$==="done")try{await b0().setPermissionMode("default"),n6.info("Spec 已完成,已自动退出 Spec 模式")}catch(J){n6.error("自动退出 Spec 模式失败:",J)}return{success:!0,message:`Transitioned to "${$}" phase`,data:{spec:X,phase:$}}}getAllowedTransitions(){let $=this.getCurrentSpec();if(!$)return[];return J2[$.phase]}async addTask($,Z,Y){let Q=this.getCurrentSpec();if(!Q)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let X={id:Bz(8),title:$,description:Z,status:"pending",dependencies:Y?.dependencies||[],affectedFiles:Y?.affectedFiles||[],complexity:Y?.complexity||"medium"},J={...Q,tasks:[...Q.tasks,X],updatedAt:new Date().toISOString()};return await this.getFileManager().writeMetadata(Q.name,J),this.updateStoreState({currentSpec:J}),{success:!0,message:`Task "${$}" added`,data:{task:X}}}async updateTaskStatus($,Z){let Y=this.getCurrentSpec();if(!Y)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let Q=Y.tasks.find((q)=>q.id===$);if(!Q)return{success:!1,message:`Task "${$}" not found`,error:"TASK_NOT_FOUND"};let X={...Q,status:Z,completedAt:Z==="completed"?new Date().toISOString():Q.completedAt},J=Y.tasks.map((q)=>q.id===$?X:q),G={...Y,tasks:J,currentTaskId:Z==="in_progress"?$:Y.currentTaskId===$?void 0:Y.currentTaskId,updatedAt:new Date().toISOString()};return await this.getFileManager().writeMetadata(Y.name,G),this.updateStoreState({currentSpec:G}),{success:!0,message:`Task status updated to "${Z}"`,data:{task:X}}}getNextTask(){let $=this.getCurrentSpec();if(!$)return null;return $.tasks.find((Z)=>{if(Z.status!=="pending")return!1;return Z.dependencies.every((Y)=>{return $.tasks.find((X)=>X.id===Y)?.status==="completed"})})||null}getTaskProgress(){let $=this.getCurrentSpec();if(!$||$.tasks.length===0)return{total:0,completed:0,percentage:0};let Z=$.tasks.length,Y=$.tasks.filter((X)=>X.status==="completed").length,Q=Math.round(Y/Z*100);return{total:Z,completed:Y,percentage:Q}}async listSpecs($){let Z=this.getFileManager(),Y=[],Q=await Z.listActiveChanges();for(let X of Q){let J=await Z.readMetadata(X);if(!J)continue;if($?.phase&&J.phase!==$.phase)continue;if($?.tags&&!$.tags.some((q)=>J.tags?.includes(q)))continue;if($?.query&&!J.name.toLowerCase().includes($.query.toLowerCase())&&!J.description.toLowerCase().includes($.query.toLowerCase()))continue;let G=this.calculateTaskProgress(J.tasks);Y.push({name:J.name,description:J.description,phase:J.phase,updatedAt:J.updatedAt,path:Z.getChangePath(X),isArchived:!1,taskProgress:G})}if($?.includeArchived){let X=await Z.listArchivedChanges();for(let J of X)Y.push({name:J,description:"(archived)",phase:"done",updatedAt:"",path:`${Z.getArchiveDir()}/${J}`,isArchived:!0,taskProgress:{total:0,completed:0}})}return Y.sort((X,J)=>{if(X.isArchived!==J.isArchived)return X.isArchived?1:-1;return new Date(J.updatedAt).getTime()-new Date(X.updatedAt).getTime()}),Y}async archiveCurrentSpec(){let $=this.getCurrentSpec();if(!$)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let Z=this.getFileManager(),Y=await Z.mergeSpecDeltas($.name);return await Z.updatePhase($.name,"done"),await Z.archiveChange($.name),this.closeSpec(),{success:!0,message:`Spec "${$.name}" archived successfully`,data:{spec:{...$,phase:"done"}}}}async validateCurrentSpec(){let $=this.getCurrentSpec();if(!$)return{valid:!1,phase:"init",completeness:{proposal:!1,spec:!1,requirements:!1,design:!1,tasks:!1},issues:[{severity:"error",file:"meta",message:"No active spec"}],suggestions:["Create a new spec with /spec proposal <name>"]};let Z=this.getFileManager(),Y=[],Q=[],[X,J,G,q,K]=await Promise.all([Z.readSpecFile($.name,"proposal"),Z.readSpecFile($.name,"spec"),Z.readSpecFile($.name,"requirements"),Z.readSpecFile($.name,"design"),Z.readSpecFile($.name,"tasks")]),W={proposal:!!X,spec:!!J,requirements:!!G,design:!!q,tasks:!!K};if($.phase==="requirements"&&!W.requirements)Y.push({severity:"warning",file:"requirements",message:"Requirements document is missing"}),Q.push("Generate requirements using EARS format");if($.phase==="design"&&!W.design)Y.push({severity:"warning",file:"design",message:"Design document is missing"}),Q.push("Create architecture diagrams and API contracts");if($.phase==="tasks"&&$.tasks.length===0)Y.push({severity:"warning",file:"tasks",message:"No tasks defined"}),Q.push("Break down the spec into atomic tasks");if($.phase==="implementation"){let U=this.getTaskProgress();if(U.completed<U.total)Y.push({severity:"info",file:"tasks",message:`${U.total-U.completed} tasks remaining`})}return{valid:Y.filter((U)=>U.severity==="error").length===0,phase:$.phase,completeness:W,issues:Y,suggestions:Q}}generateProposalTemplate($,Z){return`# ${$}
892
+ `):null}async createSpec($,Z){let Y=this.getFileManager();if(await Y.changeExists($))return{success:!1,message:`Spec "${$}" already exists`,error:"SPEC_EXISTS"};let Q=await Y.createChangeDir($),X=Y.createMetadata($,Z);await Y.writeMetadata($,X);let J=this.generateProposalTemplate($,Z);await Y.writeSpecFile($,"proposal",J);let G=this.getStoreState().recentSpecs.filter((q)=>q!==$);return G.unshift($),this.updateStoreState({currentSpec:X,specPath:Q,isActive:!0,recentSpecs:G.slice(0,10)}),{success:!0,message:`Spec "${$}" created successfully`,data:{spec:X,path:Q}}}async loadSpec($){let Z=this.getFileManager(),Y=await Z.readMetadata($);if(!Y)return{success:!1,message:`Spec "${$}" not found`,error:"SPEC_NOT_FOUND"};let Q=Z.getChangePath($),X=this.getStoreState().recentSpecs.filter((J)=>J!==$);return X.unshift($),this.updateStoreState({currentSpec:Y,specPath:Q,isActive:!0,recentSpecs:X.slice(0,10)}),{success:!0,message:`Spec "${$}" loaded successfully`,data:{spec:Y,path:Q}}}closeSpec(){this.updateStoreState({currentSpec:null,specPath:null,isActive:!1})}exitSpecMode(){this.closeSpec()}async transitionPhase($){let Z=this.getCurrentSpec();if(!Z)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};if(!J2[Z.phase].includes($))return{success:!1,message:`Cannot transition from "${Z.phase}" to "${$}"`,error:"INVALID_TRANSITION"};let X=await this.getFileManager().updatePhase(Z.name,$);if(!X)return{success:!1,message:"Failed to update phase",error:"UPDATE_FAILED"};if(this.updateStoreState({currentSpec:X}),$==="done")try{await b0().setPermissionMode("default"),n7.info("Spec 已完成,已自动退出 Spec 模式")}catch(J){n7.error("自动退出 Spec 模式失败:",J)}return{success:!0,message:`Transitioned to "${$}" phase`,data:{spec:X,phase:$}}}getAllowedTransitions(){let $=this.getCurrentSpec();if(!$)return[];return J2[$.phase]}async addTask($,Z,Y){let Q=this.getCurrentSpec();if(!Q)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let X={id:Bz(8),title:$,description:Z,status:"pending",dependencies:Y?.dependencies||[],affectedFiles:Y?.affectedFiles||[],complexity:Y?.complexity||"medium"},J={...Q,tasks:[...Q.tasks,X],updatedAt:new Date().toISOString()};return await this.getFileManager().writeMetadata(Q.name,J),this.updateStoreState({currentSpec:J}),{success:!0,message:`Task "${$}" added`,data:{task:X}}}async updateTaskStatus($,Z){let Y=this.getCurrentSpec();if(!Y)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let Q=Y.tasks.find((q)=>q.id===$);if(!Q)return{success:!1,message:`Task "${$}" not found`,error:"TASK_NOT_FOUND"};let X={...Q,status:Z,completedAt:Z==="completed"?new Date().toISOString():Q.completedAt},J=Y.tasks.map((q)=>q.id===$?X:q),G={...Y,tasks:J,currentTaskId:Z==="in_progress"?$:Y.currentTaskId===$?void 0:Y.currentTaskId,updatedAt:new Date().toISOString()};return await this.getFileManager().writeMetadata(Y.name,G),this.updateStoreState({currentSpec:G}),{success:!0,message:`Task status updated to "${Z}"`,data:{task:X}}}getNextTask(){let $=this.getCurrentSpec();if(!$)return null;return $.tasks.find((Z)=>{if(Z.status!=="pending")return!1;return Z.dependencies.every((Y)=>{return $.tasks.find((X)=>X.id===Y)?.status==="completed"})})||null}getTaskProgress(){let $=this.getCurrentSpec();if(!$||$.tasks.length===0)return{total:0,completed:0,percentage:0};let Z=$.tasks.length,Y=$.tasks.filter((X)=>X.status==="completed").length,Q=Math.round(Y/Z*100);return{total:Z,completed:Y,percentage:Q}}async listSpecs($){let Z=this.getFileManager(),Y=[],Q=await Z.listActiveChanges();for(let X of Q){let J=await Z.readMetadata(X);if(!J)continue;if($?.phase&&J.phase!==$.phase)continue;if($?.tags&&!$.tags.some((q)=>J.tags?.includes(q)))continue;if($?.query&&!J.name.toLowerCase().includes($.query.toLowerCase())&&!J.description.toLowerCase().includes($.query.toLowerCase()))continue;let G=this.calculateTaskProgress(J.tasks);Y.push({name:J.name,description:J.description,phase:J.phase,updatedAt:J.updatedAt,path:Z.getChangePath(X),isArchived:!1,taskProgress:G})}if($?.includeArchived){let X=await Z.listArchivedChanges();for(let J of X)Y.push({name:J,description:"(archived)",phase:"done",updatedAt:"",path:`${Z.getArchiveDir()}/${J}`,isArchived:!0,taskProgress:{total:0,completed:0}})}return Y.sort((X,J)=>{if(X.isArchived!==J.isArchived)return X.isArchived?1:-1;return new Date(J.updatedAt).getTime()-new Date(X.updatedAt).getTime()}),Y}async archiveCurrentSpec(){let $=this.getCurrentSpec();if(!$)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let Z=this.getFileManager(),Y=await Z.mergeSpecDeltas($.name);return await Z.updatePhase($.name,"done"),await Z.archiveChange($.name),this.closeSpec(),{success:!0,message:`Spec "${$.name}" archived successfully`,data:{spec:{...$,phase:"done"}}}}async validateCurrentSpec(){let $=this.getCurrentSpec();if(!$)return{valid:!1,phase:"init",completeness:{proposal:!1,spec:!1,requirements:!1,design:!1,tasks:!1},issues:[{severity:"error",file:"meta",message:"No active spec"}],suggestions:["Create a new spec with /spec proposal <name>"]};let Z=this.getFileManager(),Y=[],Q=[],[X,J,G,q,K]=await Promise.all([Z.readSpecFile($.name,"proposal"),Z.readSpecFile($.name,"spec"),Z.readSpecFile($.name,"requirements"),Z.readSpecFile($.name,"design"),Z.readSpecFile($.name,"tasks")]),W={proposal:!!X,spec:!!J,requirements:!!G,design:!!q,tasks:!!K};if($.phase==="requirements"&&!W.requirements)Y.push({severity:"warning",file:"requirements",message:"Requirements document is missing"}),Q.push("Generate requirements using EARS format");if($.phase==="design"&&!W.design)Y.push({severity:"warning",file:"design",message:"Design document is missing"}),Q.push("Create architecture diagrams and API contracts");if($.phase==="tasks"&&$.tasks.length===0)Y.push({severity:"warning",file:"tasks",message:"No tasks defined"}),Q.push("Break down the spec into atomic tasks");if($.phase==="implementation"){let U=this.getTaskProgress();if(U.completed<U.total)Y.push({severity:"info",file:"tasks",message:`${U.total-U.completed} tasks remaining`})}return{valid:Y.filter((U)=>U.severity==="error").length===0,phase:$.phase,completeness:W,issues:Y,suggestions:Q}}generateProposalTemplate($,Z){return`# ${$}
893
893
 
894
894
  ## Summary
895
895
 
@@ -923,7 +923,7 @@ ${Z}
923
923
  <!-- What needs to be clarified before proceeding? -->
924
924
 
925
925
  1.
926
- `}calculateTaskProgress($){let Z=$.length,Y=$.filter((Q)=>Q.status==="completed").length;return{total:Z,completed:Y}}}var n6;var j1=R(()=>{U$();Q0();M0();S5();g1();n6=x("Spec")});import*as a1 from"fs/promises";class r2{async readTextFile($){return a1.readFile($,"utf-8")}async writeTextFile($,Z){await a1.writeFile($,Z,"utf-8")}async exists($){try{return await a1.access($),!0}catch{return!1}}async readBinaryFile($){return a1.readFile($)}async stat($){try{let Z=await a1.stat($);return{size:Z.size,isDirectory:Z.isDirectory(),isFile:Z.isFile(),mtime:Z.mtime}}catch{return null}}async mkdir($,Z){await a1.mkdir($,{recursive:Z?.recursive??!1,mode:Z?.mode??493})}}function a2(){return k9}function o6($){k9=$}function DJ(){k9=new r2}var k9;var C4=R(()=>{k9=new r2});class f9{connection;sessionId;capabilities;fallback;constructor($,Z,Y,Q=new r2){this.connection=$;this.sessionId=Z;this.capabilities=Y;this.fallback=Q}async readTextFile($){if(!this.capabilities.readTextFile)return U1.debug(`[AcpFileSystem] readTextFile fallback: ${$}`),this.fallback.readTextFile($);try{return U1.debug(`[AcpFileSystem] readTextFile via ACP: ${$}`),(await this.connection.readTextFile({path:$,sessionId:this.sessionId})).content}catch(Z){return U1.warn(`[AcpFileSystem] readTextFile ACP failed, fallback: ${Z}`),this.fallback.readTextFile($)}}async writeTextFile($,Z){if(!this.capabilities.writeTextFile)return U1.debug(`[AcpFileSystem] writeTextFile fallback: ${$}`),this.fallback.writeTextFile($,Z);try{U1.debug(`[AcpFileSystem] writeTextFile via ACP: ${$}`),await this.connection.writeTextFile({path:$,content:Z,sessionId:this.sessionId})}catch(Y){return U1.warn(`[AcpFileSystem] writeTextFile ACP failed, fallback: ${Y}`),this.fallback.writeTextFile($,Z)}}async exists($){if(!this.capabilities.readTextFile)return U1.debug(`[AcpFileSystem] exists fallback to local: ${$}`),this.fallback.exists($);try{return await this.connection.readTextFile({path:$,sessionId:this.sessionId}),U1.debug(`[AcpFileSystem] exists(${$}): true (ACP read success)`),!0}catch(Z){let Y=String(Z).toLowerCase();if(["not found","no such file","enoent","does not exist","file not found","path not found"].some((G)=>Y.includes(G)))return U1.debug(`[AcpFileSystem] exists(${$}): false (ACP: not found)`),!1;let J=wz(Y);return U1.warn(`[AcpFileSystem] exists(${$}): assuming exists due to ${J} error`,{error:String(Z),errorType:J,filePath:$}),!0}}async readBinaryFile($){return U1.debug(`[AcpFileSystem] readBinaryFile fallback: ${$}`),this.fallback.readBinaryFile($)}async stat($){return U1.debug(`[AcpFileSystem] stat fallback: ${$}`),this.fallback.stat($)}async mkdir($,Z){return U1.debug(`[AcpFileSystem] mkdir fallback: ${$}`),this.fallback.mkdir($,Z)}getCapabilities(){return this.capabilities}canReadTextFile(){return this.capabilities.readTextFile??!1}canWriteTextFile(){return this.capabilities.writeTextFile??!1}}function wz($){if($.includes("permission")||$.includes("access denied"))return"permission";if($.includes("timeout")||$.includes("timed out"))return"timeout";if($.includes("binary")||$.includes("encoding"))return"binary";if($.includes("too large")||$.includes("size"))return"size";if($.includes("connection")||$.includes("network"))return"network";return"unknown"}var U1;var jJ=R(()=>{Q0();C4();U1=x("Agent")});import{spawn as Lz}from"child_process";class h9{async execute($,Z){return new Promise((Y)=>{let Q=process.platform==="win32"?"cmd.exe":"/bin/bash",X=process.platform==="win32"?["/c",$]:["-c",$],J=Lz(Q,X,{cwd:Z?.cwd||process.cwd(),env:{...process.env,...Z?.env},stdio:["pipe","pipe","pipe"]}),G="",q="",K=!1,W=Z?.timeout?setTimeout(()=>{K=!0,J.kill("SIGTERM")},Z.timeout):null,U=null,O=()=>{if(W)clearTimeout(W);if(U&&Z?.signal)Z.signal.removeEventListener("abort",U),U=null};if(Z?.signal)U=()=>{K=!0,J.kill("SIGTERM")},Z.signal.addEventListener("abort",U);J.stdout.on("data",(F)=>{let H=F.toString();G+=H,Z?.onOutput?.(H)}),J.stderr.on("data",(F)=>{let H=F.toString();q+=H,Z?.onOutput?.(H)}),J.on("close",(F)=>{O(),Y({success:F===0&&!K,stdout:G,stderr:q,exitCode:F,error:K?"Command was terminated":void 0})}),J.on("error",(F)=>{O(),Y({success:!1,stdout:G,stderr:q,exitCode:null,error:F.message})})})}isAvailable(){return!0}}class yJ{connection;sessionId;fallback;constructor($,Z,Y=new h9){this.connection=$;this.sessionId=Z;this.fallback=Y}async execute($,Z){try{W2.debug(`[AcpTerminal] Executing command via ACP: ${$}`);let Y=await this.connection.createTerminal({sessionId:this.sessionId,command:$,cwd:Z?.cwd,env:Z?.env?Object.entries(Z.env).map(([W,U])=>({name:W,value:U})):void 0}),Q=0,X=null;if(Z?.onOutput)X=setInterval(async()=>{try{let U=(await Y.currentOutput()).output||"";if(U.length>Q){let O=U.slice(Q);Q=U.length,Z.onOutput?.(O)}}catch{}},100);let J=(W=!1)=>{if(X)clearInterval(X),X=null;(W?Y.kill().then(()=>W2.debug("[AcpTerminal] Killed remote command")).catch(()=>{}).then(()=>Y.release()).catch(()=>{}):Y.release().catch(()=>{})).catch(()=>{})},G=[];if(G.push(Y.waitForExit().then((W)=>({type:"completed",exitCode:W.exitCode??null}))),Z?.timeout)G.push(new Promise((W)=>{setTimeout(()=>W({type:"timeout"}),Z.timeout)}));if(Z?.signal)G.push(new Promise((W)=>{if(Z.signal.aborted)W({type:"aborted"});else Z.signal.addEventListener("abort",()=>W({type:"aborted"}),{once:!0})}));let q=await Promise.race(G),K="";try{if(K=(await Y.currentOutput()).output||"",Z?.onOutput&&K.length>Q)Z.onOutput(K.slice(Q))}catch{}switch(q.type){case"completed":return J(!1),{success:q.exitCode===0,stdout:K,stderr:"",exitCode:q.exitCode};case"timeout":return W2.debug(`[AcpTerminal] Command timed out, killing: ${$}`),J(!0),{success:!1,stdout:K,stderr:"",exitCode:null,error:"Command timed out"};case"aborted":return W2.debug(`[AcpTerminal] Command aborted, killing: ${$}`),J(!0),{success:!1,stdout:K,stderr:"",exitCode:null,error:"Command was aborted"}}}catch(Y){return W2.warn("[AcpTerminal] ACP terminal failed, using fallback:",Y),this.fallback.execute($,Z)}}isAvailable(){return!0}}function TJ(){return F0.getInstance().getTerminalService()}function n2(){return F0.getInstance().isAcpMode()}var W2,F0;var V8=R(()=>{Q0();C4();jJ();W2=x("Agent");F0=class F0{static sessions=new Map;static currentSessionId=null;constructor(){}static getInstance(){return new F0}static initializeSession($,Z,Y,Q){let X=Y?.fs?new f9($,Z,Y.fs):new r2;if(Y?.fs)W2.debug(`[AcpServiceContext:${Z}] Using ACP file system service`);let J=new yJ($,Z);W2.debug(`[AcpServiceContext:${Z}] Using ACP terminal service`),F0.sessions.set(Z,{fileSystemService:X,terminalService:J,connection:$,clientCapabilities:Y||null,cwd:Q}),F0.currentSessionId=Z,o6(X),W2.debug(`[AcpServiceContext:${Z}] Initialized with capabilities:`,{fs:!!Y?.fs,readTextFile:Y?.fs?.readTextFile,writeTextFile:Y?.fs?.writeTextFile,cwd:Q})}static destroySession($){if(F0.sessions.delete($),F0.currentSessionId===$){let Z=Array.from(F0.sessions.keys());if(F0.currentSessionId=Z[0]||null,!F0.currentSessionId)DJ();else{let Y=F0.sessions.get(F0.currentSessionId);if(Y)o6(Y.fileSystemService)}}W2.debug(`[AcpServiceContext:${$}] Session destroyed`)}static getSessionServices($){return F0.sessions.get($)||null}static setCurrentSession($){if(F0.sessions.has($)){F0.currentSessionId=$;let Z=F0.sessions.get($);if(Z)o6(Z.fileSystemService)}}static getCurrentSessionId(){return F0.currentSessionId}initialize($,Z,Y,Q){F0.initializeSession($,Z,Y,Q||process.cwd())}reset(){if(F0.currentSessionId)F0.destroySession(F0.currentSessionId)}isAcpMode(){return F0.currentSessionId!==null}getFileSystemService(){if(F0.currentSessionId){let $=F0.sessions.get(F0.currentSessionId);if($)return $.fileSystemService}return new r2}getTerminalService(){if(F0.currentSessionId){let $=F0.sessions.get(F0.currentSessionId);if($)return $.terminalService}return new h9}getConnection(){if(F0.currentSessionId){let $=F0.sessions.get(F0.currentSessionId);if($)return $.connection}return null}getSessionId(){return F0.currentSessionId}getClientCapabilities(){if(F0.currentSessionId){let $=F0.sessions.get(F0.currentSessionId);if($)return $.clientCapabilities}return null}async sendToolUpdate($,Z,Y,Q,X){let J=F0.currentSessionId;if(!J)return;let G=F0.sessions.get(J);if(!G)return;try{await G.connection.sessionUpdate({sessionId:J,update:{sessionUpdate:"tool_call",toolCallId:$,status:Z,title:Y,content:Q||[],kind:X||"other"}})}catch(q){W2.warn("[AcpServiceContext] Failed to send tool update:",q)}}}});import{isAbsolute as EJ}from"path";import{z as M$}from"zod";var a0;var o2=R(()=>{a0={filePath:($)=>M$.string().min(1,"File path is required").refine((Z)=>EJ(Z),{message:"Path must be absolute"}).describe($?.description||"Absolute file path"),encoding:()=>M$.enum(["utf8","base64","binary"]).default("utf8").describe("File encoding"),timeout:($=1000,Z=300000,Y=30000)=>M$.number().int("Must be an integer").min($,`Cannot be less than ${$}ms`).max(Z,`Cannot exceed ${Z}ms`).default(Y).describe(`Timeout in milliseconds (default ${Y}ms)`),pattern:($)=>M$.string().min(1,"Pattern is required").describe($?.description||"Regex or glob pattern"),glob:($)=>M$.string().min(1,"Glob pattern is required").describe($?.description||'Glob pattern (e.g., "*.js", "**/*.ts")'),lineNumber:($)=>M$.number().int("Line number must be an integer").min($?.min??0,`Line number cannot be less than ${$?.min??0}`).describe($?.description||"Line number"),lineLimit:($)=>M$.number().int("Line count must be an integer").min($?.min??1,`Line count cannot be less than ${$?.min??1}`).max($?.max??1e4,`Line count cannot exceed ${$?.max??1e4}`).describe($?.description||"Limit on lines to read"),workingDirectory:()=>M$.string().min(1,"Working directory is required").refine(($)=>EJ($),{message:"Path must be absolute"}).describe("Absolute working directory"),environment:()=>M$.record(M$.string(),M$.string()).describe("Environment variables (key-value)").optional(),outputMode:($,Z)=>{let Y=M$.enum($);return Z?Y.default(Z):Y},flag:($)=>M$.boolean().default($?.defaultValue??!1).describe($?.description||"Boolean flag"),url:($)=>M$.string().url("Must be a valid URL").describe($?.description||"URL"),port:()=>M$.number().int("Port must be an integer").min(1,"Port cannot be less than 1").max(65535,"Port cannot exceed 65535").describe("Port number"),command:($)=>M$.string().min(1,"Command is required").describe($?.description||"Command to execute"),sessionId:()=>M$.string().min(1,"Session ID is required").uuid("Must be a valid UUID").optional().describe("Session identifier (UUID)"),nonNegativeInt:($)=>M$.number().int("Must be an integer").min(0,"Cannot be negative").describe($?.description||"Non-negative integer"),positiveInt:($)=>M$.number().int("Must be an integer").min(1,"Must be greater than 0").describe($?.description||"Positive integer")}});import*as x9 from"diff";function IJ($,Z,Y=4){if($===Z)return null;let Q=x9.createPatch("file",$,Z,"","",{context:Y}),X=Q.split(`
926
+ `}calculateTaskProgress($){let Z=$.length,Y=$.filter((Q)=>Q.status==="completed").length;return{total:Z,completed:Y}}}var n7;var j1=R(()=>{U$();Q0();M0();S5();g1();n7=x("Spec")});import*as a1 from"fs/promises";class r2{async readTextFile($){return a1.readFile($,"utf-8")}async writeTextFile($,Z){await a1.writeFile($,Z,"utf-8")}async exists($){try{return await a1.access($),!0}catch{return!1}}async readBinaryFile($){return a1.readFile($)}async stat($){try{let Z=await a1.stat($);return{size:Z.size,isDirectory:Z.isDirectory(),isFile:Z.isFile(),mtime:Z.mtime}}catch{return null}}async mkdir($,Z){await a1.mkdir($,{recursive:Z?.recursive??!1,mode:Z?.mode??493})}}function a2(){return k9}function o7($){k9=$}function DJ(){k9=new r2}var k9;var C4=R(()=>{k9=new r2});class f9{connection;sessionId;capabilities;fallback;constructor($,Z,Y,Q=new r2){this.connection=$;this.sessionId=Z;this.capabilities=Y;this.fallback=Q}async readTextFile($){if(!this.capabilities.readTextFile)return U1.debug(`[AcpFileSystem] readTextFile fallback: ${$}`),this.fallback.readTextFile($);try{return U1.debug(`[AcpFileSystem] readTextFile via ACP: ${$}`),(await this.connection.readTextFile({path:$,sessionId:this.sessionId})).content}catch(Z){return U1.warn(`[AcpFileSystem] readTextFile ACP failed, fallback: ${Z}`),this.fallback.readTextFile($)}}async writeTextFile($,Z){if(!this.capabilities.writeTextFile)return U1.debug(`[AcpFileSystem] writeTextFile fallback: ${$}`),this.fallback.writeTextFile($,Z);try{U1.debug(`[AcpFileSystem] writeTextFile via ACP: ${$}`),await this.connection.writeTextFile({path:$,content:Z,sessionId:this.sessionId})}catch(Y){return U1.warn(`[AcpFileSystem] writeTextFile ACP failed, fallback: ${Y}`),this.fallback.writeTextFile($,Z)}}async exists($){if(!this.capabilities.readTextFile)return U1.debug(`[AcpFileSystem] exists fallback to local: ${$}`),this.fallback.exists($);try{return await this.connection.readTextFile({path:$,sessionId:this.sessionId}),U1.debug(`[AcpFileSystem] exists(${$}): true (ACP read success)`),!0}catch(Z){let Y=String(Z).toLowerCase();if(["not found","no such file","enoent","does not exist","file not found","path not found"].some((G)=>Y.includes(G)))return U1.debug(`[AcpFileSystem] exists(${$}): false (ACP: not found)`),!1;let J=wz(Y);return U1.warn(`[AcpFileSystem] exists(${$}): assuming exists due to ${J} error`,{error:String(Z),errorType:J,filePath:$}),!0}}async readBinaryFile($){return U1.debug(`[AcpFileSystem] readBinaryFile fallback: ${$}`),this.fallback.readBinaryFile($)}async stat($){return U1.debug(`[AcpFileSystem] stat fallback: ${$}`),this.fallback.stat($)}async mkdir($,Z){return U1.debug(`[AcpFileSystem] mkdir fallback: ${$}`),this.fallback.mkdir($,Z)}getCapabilities(){return this.capabilities}canReadTextFile(){return this.capabilities.readTextFile??!1}canWriteTextFile(){return this.capabilities.writeTextFile??!1}}function wz($){if($.includes("permission")||$.includes("access denied"))return"permission";if($.includes("timeout")||$.includes("timed out"))return"timeout";if($.includes("binary")||$.includes("encoding"))return"binary";if($.includes("too large")||$.includes("size"))return"size";if($.includes("connection")||$.includes("network"))return"network";return"unknown"}var U1;var jJ=R(()=>{Q0();C4();U1=x("Agent")});import{spawn as Lz}from"child_process";class h9{async execute($,Z){return new Promise((Y)=>{let Q=process.platform==="win32"?"cmd.exe":"/bin/bash",X=process.platform==="win32"?["/c",$]:["-c",$],J=Lz(Q,X,{cwd:Z?.cwd||process.cwd(),env:{...process.env,...Z?.env},stdio:["pipe","pipe","pipe"]}),G="",q="",K=!1,W=Z?.timeout?setTimeout(()=>{K=!0,J.kill("SIGTERM")},Z.timeout):null,U=null,O=()=>{if(W)clearTimeout(W);if(U&&Z?.signal)Z.signal.removeEventListener("abort",U),U=null};if(Z?.signal)U=()=>{K=!0,J.kill("SIGTERM")},Z.signal.addEventListener("abort",U);J.stdout.on("data",(F)=>{let H=F.toString();G+=H,Z?.onOutput?.(H)}),J.stderr.on("data",(F)=>{let H=F.toString();q+=H,Z?.onOutput?.(H)}),J.on("close",(F)=>{O(),Y({success:F===0&&!K,stdout:G,stderr:q,exitCode:F,error:K?"Command was terminated":void 0})}),J.on("error",(F)=>{O(),Y({success:!1,stdout:G,stderr:q,exitCode:null,error:F.message})})})}isAvailable(){return!0}}class yJ{connection;sessionId;fallback;constructor($,Z,Y=new h9){this.connection=$;this.sessionId=Z;this.fallback=Y}async execute($,Z){try{W2.debug(`[AcpTerminal] Executing command via ACP: ${$}`);let Y=await this.connection.createTerminal({sessionId:this.sessionId,command:$,cwd:Z?.cwd,env:Z?.env?Object.entries(Z.env).map(([W,U])=>({name:W,value:U})):void 0}),Q=0,X=null;if(Z?.onOutput)X=setInterval(async()=>{try{let U=(await Y.currentOutput()).output||"";if(U.length>Q){let O=U.slice(Q);Q=U.length,Z.onOutput?.(O)}}catch{}},100);let J=(W=!1)=>{if(X)clearInterval(X),X=null;(W?Y.kill().then(()=>W2.debug("[AcpTerminal] Killed remote command")).catch(()=>{}).then(()=>Y.release()).catch(()=>{}):Y.release().catch(()=>{})).catch(()=>{})},G=[];if(G.push(Y.waitForExit().then((W)=>({type:"completed",exitCode:W.exitCode??null}))),Z?.timeout)G.push(new Promise((W)=>{setTimeout(()=>W({type:"timeout"}),Z.timeout)}));if(Z?.signal)G.push(new Promise((W)=>{if(Z.signal.aborted)W({type:"aborted"});else Z.signal.addEventListener("abort",()=>W({type:"aborted"}),{once:!0})}));let q=await Promise.race(G),K="";try{if(K=(await Y.currentOutput()).output||"",Z?.onOutput&&K.length>Q)Z.onOutput(K.slice(Q))}catch{}switch(q.type){case"completed":return J(!1),{success:q.exitCode===0,stdout:K,stderr:"",exitCode:q.exitCode};case"timeout":return W2.debug(`[AcpTerminal] Command timed out, killing: ${$}`),J(!0),{success:!1,stdout:K,stderr:"",exitCode:null,error:"Command timed out"};case"aborted":return W2.debug(`[AcpTerminal] Command aborted, killing: ${$}`),J(!0),{success:!1,stdout:K,stderr:"",exitCode:null,error:"Command was aborted"}}}catch(Y){return W2.warn("[AcpTerminal] ACP terminal failed, using fallback:",Y),this.fallback.execute($,Z)}}isAvailable(){return!0}}function TJ(){return F0.getInstance().getTerminalService()}function n2(){return F0.getInstance().isAcpMode()}var W2,F0;var V8=R(()=>{Q0();C4();jJ();W2=x("Agent");F0=class F0{static sessions=new Map;static currentSessionId=null;constructor(){}static getInstance(){return new F0}static initializeSession($,Z,Y,Q){let X=Y?.fs?new f9($,Z,Y.fs):new r2;if(Y?.fs)W2.debug(`[AcpServiceContext:${Z}] Using ACP file system service`);let J=new yJ($,Z);W2.debug(`[AcpServiceContext:${Z}] Using ACP terminal service`),F0.sessions.set(Z,{fileSystemService:X,terminalService:J,connection:$,clientCapabilities:Y||null,cwd:Q}),F0.currentSessionId=Z,o7(X),W2.debug(`[AcpServiceContext:${Z}] Initialized with capabilities:`,{fs:!!Y?.fs,readTextFile:Y?.fs?.readTextFile,writeTextFile:Y?.fs?.writeTextFile,cwd:Q})}static destroySession($){if(F0.sessions.delete($),F0.currentSessionId===$){let Z=Array.from(F0.sessions.keys());if(F0.currentSessionId=Z[0]||null,!F0.currentSessionId)DJ();else{let Y=F0.sessions.get(F0.currentSessionId);if(Y)o7(Y.fileSystemService)}}W2.debug(`[AcpServiceContext:${$}] Session destroyed`)}static getSessionServices($){return F0.sessions.get($)||null}static setCurrentSession($){if(F0.sessions.has($)){F0.currentSessionId=$;let Z=F0.sessions.get($);if(Z)o7(Z.fileSystemService)}}static getCurrentSessionId(){return F0.currentSessionId}initialize($,Z,Y,Q){F0.initializeSession($,Z,Y,Q||process.cwd())}reset(){if(F0.currentSessionId)F0.destroySession(F0.currentSessionId)}isAcpMode(){return F0.currentSessionId!==null}getFileSystemService(){if(F0.currentSessionId){let $=F0.sessions.get(F0.currentSessionId);if($)return $.fileSystemService}return new r2}getTerminalService(){if(F0.currentSessionId){let $=F0.sessions.get(F0.currentSessionId);if($)return $.terminalService}return new h9}getConnection(){if(F0.currentSessionId){let $=F0.sessions.get(F0.currentSessionId);if($)return $.connection}return null}getSessionId(){return F0.currentSessionId}getClientCapabilities(){if(F0.currentSessionId){let $=F0.sessions.get(F0.currentSessionId);if($)return $.clientCapabilities}return null}async sendToolUpdate($,Z,Y,Q,X){let J=F0.currentSessionId;if(!J)return;let G=F0.sessions.get(J);if(!G)return;try{await G.connection.sessionUpdate({sessionId:J,update:{sessionUpdate:"tool_call",toolCallId:$,status:Z,title:Y,content:Q||[],kind:X||"other"}})}catch(q){W2.warn("[AcpServiceContext] Failed to send tool update:",q)}}}});import{isAbsolute as EJ}from"path";import{z as M$}from"zod";var a0;var o2=R(()=>{a0={filePath:($)=>M$.string().min(1,"File path is required").refine((Z)=>EJ(Z),{message:"Path must be absolute"}).describe($?.description||"Absolute file path"),encoding:()=>M$.enum(["utf8","base64","binary"]).default("utf8").describe("File encoding"),timeout:($=1000,Z=300000,Y=30000)=>M$.number().int("Must be an integer").min($,`Cannot be less than ${$}ms`).max(Z,`Cannot exceed ${Z}ms`).default(Y).describe(`Timeout in milliseconds (default ${Y}ms)`),pattern:($)=>M$.string().min(1,"Pattern is required").describe($?.description||"Regex or glob pattern"),glob:($)=>M$.string().min(1,"Glob pattern is required").describe($?.description||'Glob pattern (e.g., "*.js", "**/*.ts")'),lineNumber:($)=>M$.number().int("Line number must be an integer").min($?.min??0,`Line number cannot be less than ${$?.min??0}`).describe($?.description||"Line number"),lineLimit:($)=>M$.number().int("Line count must be an integer").min($?.min??1,`Line count cannot be less than ${$?.min??1}`).max($?.max??1e4,`Line count cannot exceed ${$?.max??1e4}`).describe($?.description||"Limit on lines to read"),workingDirectory:()=>M$.string().min(1,"Working directory is required").refine(($)=>EJ($),{message:"Path must be absolute"}).describe("Absolute working directory"),environment:()=>M$.record(M$.string(),M$.string()).describe("Environment variables (key-value)").optional(),outputMode:($,Z)=>{let Y=M$.enum($);return Z?Y.default(Z):Y},flag:($)=>M$.boolean().default($?.defaultValue??!1).describe($?.description||"Boolean flag"),url:($)=>M$.string().url("Must be a valid URL").describe($?.description||"URL"),port:()=>M$.number().int("Port must be an integer").min(1,"Port cannot be less than 1").max(65535,"Port cannot exceed 65535").describe("Port number"),command:($)=>M$.string().min(1,"Command is required").describe($?.description||"Command to execute"),sessionId:()=>M$.string().min(1,"Session ID is required").uuid("Must be a valid UUID").optional().describe("Session identifier (UUID)"),nonNegativeInt:($)=>M$.number().int("Must be an integer").min(0,"Cannot be negative").describe($?.description||"Non-negative integer"),positiveInt:($)=>M$.number().int("Must be an integer").min(1,"Must be greater than 0").describe($?.description||"Positive integer")}});import*as x9 from"diff";function IJ($,Z,Y=4){if($===Z)return null;let Q=x9.createPatch("file",$,Z,"","",{context:Y}),X=Q.split(`
927
927
  `),J=1;for(let G of X){let q=G.match(/@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@/);if(q){J=parseInt(q[1],10);break}}return`
928
928
  <<<DIFF>>>
929
929
  ${JSON.stringify({patch:Q,startLine:Math.max(1,J-Y),matchLine:J})}
@@ -947,7 +947,7 @@ ${JSON.stringify({patch:B,startLine:F+1,matchLine:q+1})}
947
947
  `),K=$.split(`
948
948
  `);for(let W=0;W<=K.length-Y.length;W++){let U=K[W].match(/^(\s+)/),O=U?U[1]:"",F=K.slice(W,W+Y.length);if(F.map((z)=>{if(z.startsWith(O))return z.slice(O.length);return z}).join(`
949
949
  `)===q)return F.join(`
950
- `)}return null}var SJ=()=>{};import{promises as s6}from"node:fs";class Q1{static instance=null;accessedFiles=new Map;constructor(){}static getInstance(){if(!Q1.instance)Q1.instance=new Q1;return Q1.instance}async recordFileRead($,Z){try{let Y=await s6.stat($),Q={filePath:$,accessTime:Date.now(),mtime:Y.mtimeMs,sessionId:Z,lastOperation:"read"};this.accessedFiles.set($,Q),C3.debug(`记录文件读取: ${$}`)}catch(Y){C3.warn(`记录文件读取失败: ${$}`,Y)}}async recordFileEdit($,Z,Y="edit"){try{let Q=await s6.stat($),X={filePath:$,accessTime:Date.now(),mtime:Q.mtimeMs,sessionId:Z,lastOperation:Y};this.accessedFiles.set($,X),C3.debug(`记录文件${Y==="edit"?"编辑":"写入"}: ${$}`)}catch(Q){C3.warn(`记录文件${Y==="edit"?"编辑":"写入"}失败: ${$}`,Q)}}hasFileBeenRead($,Z){let Y=this.accessedFiles.get($);if(!Y)return!1;if(Z&&Y.sessionId!==Z)return!1;return!0}async checkFileModification($){let Z=this.accessedFiles.get($);if(!Z)return{modified:!1,message:"文件未被跟踪"};try{let Y=await s6.stat($);if(Math.abs(Y.mtimeMs-Z.mtime)>1)return{modified:!0,message:`文件在访问后被修改(访问时间: ${new Date(Z.accessTime).toISOString()}, 当前修改时间: ${Y.mtime.toISOString()})`};return{modified:!1}}catch(Y){let Q=Y;if(Q.code==="ENOENT")return{modified:!0,message:"文件已被删除"};return{modified:!1,message:`无法检查文件状态: ${Q.message}`}}}async checkExternalModification($){let Z=this.accessedFiles.get($);if(!Z)return{isExternal:!1,message:"文件未被跟踪"};try{let Y=await s6.stat($);if(Y.mtimeMs-Z.mtime>2000)return{isExternal:!0,message:`文件在 ${new Date(Z.accessTime).toISOString()} (${Z.lastOperation}) 之后被外部程序修改(当前修改时间: ${Y.mtime.toISOString()})`};return{isExternal:!1}}catch(Y){let Q=Y;if(Q.code==="ENOENT")return{isExternal:!0,message:"文件已被删除"};return C3.warn(`检查文件外部修改失败: ${$}`,Y),{isExternal:!1,message:`无法检查文件状态: ${Q.message}`}}}getFileRecord($){return this.accessedFiles.get($)}clearFileRecord($){this.accessedFiles.delete($)}clearAll(){this.accessedFiles.clear()}clearSession($){for(let[Z,Y]of this.accessedFiles.entries())if(Y.sessionId===$)this.accessedFiles.delete(Z)}getTrackedFiles(){return Array.from(this.accessedFiles.keys())}getTrackedFileCount(){return this.accessedFiles.size}static resetInstance(){Q1.instance=null}}var C3;var t6=R(()=>{Q0();C3=x("Tool")});import{execSync as Nz}from"node:child_process";import*as m9 from"node:os";import*as S4 from"node:path";function Az($){return S4.resolve($).replace(/[/\\]/g,"-").replace(/:/g,"_")}function kJ($){let Z=$.replace(/_/g,":");if(Z.startsWith("-"))Z="/"+Z.slice(1);return Z.replace(/-/g,"/")}function S3($){let Z=m9.homedir(),Y=Az($);return S4.join(Z,".blade","projects",Y)}function O1($,Z){return S4.join(S3($),`${Z}.jsonl`)}function fJ($){try{return Nz("git rev-parse --abbrev-ref HEAD",{cwd:$,encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()||void 0}catch{return}}function k4(){return S4.join(m9.homedir(),".blade")}async function hJ(){let{readdir:$}=await import("node:fs/promises");try{let Z=S4.join(k4(),"projects");return(await $(Z,{withFileTypes:!0})).filter((Q)=>Q.isDirectory()).map((Q)=>Q.name)}catch{return[]}}var k3=()=>{};import*as xJ from"node:crypto";import{promises as U2}from"node:fs";import*as f4 from"node:path";class f3{sessionId;enableCheckpoints;maxSnapshots;snapshotDir;trackedFileBackups=new Map;snapshots=[];constructor($){this.sessionId=$.sessionId,this.enableCheckpoints=$.enableCheckpoints??!0,this.maxSnapshots=$.maxSnapshots??10;let Z=k4();this.snapshotDir=f4.join(Z,"file-history",this.sessionId)}async initialize(){if(!this.enableCheckpoints)return;try{await U2.mkdir(this.snapshotDir,{recursive:!0,mode:493}),console.log(`[SnapshotManager] 初始化快照目录: ${this.snapshotDir}`)}catch($){throw console.warn("[SnapshotManager] 创建快照目录失败:",$),$}}async createSnapshot($,Z){if(!this.enableCheckpoints)return console.log("[SnapshotManager] 检查点已禁用,跳过快照创建"),{backupFileName:"",version:0,backupTime:new Date};try{await U2.access($)}catch{return console.warn(`[SnapshotManager] 文件不存在,跳过快照: ${$}`),{backupFileName:"",version:0,backupTime:new Date}}let Y=this.trackedFileBackups.get($),Q=Y?Y.version+1:1,X=this.generateFileHash($,Q),J=f4.join(this.snapshotDir,`${X}@v${Q}`);try{let G=await U2.readFile($,{encoding:"utf-8"});await U2.writeFile(J,G,{encoding:"utf-8"});let q={backupFileName:X,version:Q,backupTime:new Date};return this.trackedFileBackups.set($,q),this.snapshots.push({messageId:Z,backupFileName:X,timestamp:new Date,filePath:$}),console.log(`[SnapshotManager] 创建快照: ${$} -> ${X}@v${Q}`),await this.cleanupOldSnapshots($),q}catch(G){throw console.error(`[SnapshotManager] 创建快照失败: ${$}`,G),G}}async restoreSnapshot($,Z){let Y=this.snapshots.slice().reverse().find((J)=>J.messageId===Z&&J.filePath===$);if(!Y)throw Error(`未找到快照: messageId=${Z}, filePath=${$}`);let Q=this.trackedFileBackups.get($);if(!Q)throw Error(`未找到文件追踪信息: ${$}`);let X=f4.join(this.snapshotDir,`${Y.backupFileName}@v${Q.version}`);try{let J=await U2.readFile(X,{encoding:"utf-8"});await U2.writeFile($,J,{encoding:"utf-8"}),console.log(`[SnapshotManager] 恢复快照: ${$} <- ${Y.backupFileName}@v${Q.version}`)}catch(J){throw console.error(`[SnapshotManager] 恢复快照失败: ${$}`,J),J}}async listSnapshots($){return this.snapshots.filter((Z)=>Z.filePath===$)}async cleanupOldSnapshots($){let Z=this.snapshots.filter((X)=>X.filePath===$);if(Z.length<=this.maxSnapshots)return;let Q=Z.sort((X,J)=>X.timestamp.getTime()-J.timestamp.getTime()).slice(0,Z.length-this.maxSnapshots);for(let X of Q){let J=this.trackedFileBackups.get(X.filePath);if(!J)continue;let G=f4.join(this.snapshotDir,`${X.backupFileName}@v${J.version}`);try{await U2.unlink(G),console.log(`[SnapshotManager] 删除旧快照: ${G}`)}catch(K){console.warn(`[SnapshotManager] 删除快照失败: ${G}`,K)}let q=this.snapshots.indexOf(X);if(q>-1)this.snapshots.splice(q,1)}}async cleanup($=0){try{let Z=await U2.readdir(this.snapshotDir);if(Z.length<=$)return;let Y=await Promise.all(Z.map(async(X)=>{let J=f4.join(this.snapshotDir,X),G=await U2.stat(J);return{file:X,mtime:G.mtime.getTime()}}));Y.sort((X,J)=>J.mtime-X.mtime);let Q=Y.slice($);for(let{file:X}of Q){let J=f4.join(this.snapshotDir,X);await U2.unlink(J),console.log(`[SnapshotManager] 清理快照: ${J}`)}}catch(Z){console.warn("[SnapshotManager] 清理快照失败:",Z)}}generateFileHash($,Z){let Y=xJ.createHash("md5");return Y.update(`${$}:${Z}`),Y.digest("hex").substring(0,16)}getSnapshotDir(){return this.snapshotDir}getSessionId(){return this.sessionId}getTrackedFileCount(){return this.trackedFileBackups.size}getSnapshotCount(){return this.snapshots.length}}var g9=R(()=>{k3()});import{basename as bz,extname as Rz}from"path";import{z as e6}from"zod";function pJ($){return $.replaceAll("‘","'").replaceAll("’","'").replaceAll("“",'"').replaceAll("”",'"')}function Vz($,Z){if($.includes(Z))return{matched:Z,strategy:"exact"};let Y=pJ(Z),X=pJ($).indexOf(Y);if(X!==-1)return{matched:$.substring(X,X+Z.length),strategy:"normalize_quotes"};let J=PJ(Z);if(J!==Z&&$.includes(J))return{matched:J,strategy:"unescape"};let G=CJ($,Z);if(G)return{matched:G,strategy:"flexible"};return{matched:null,strategy:"failed"}}function Mz($,Z){if(Z.length===0)return[];let Y=[],Q=$.indexOf(Z);while(Q!==-1)Y.push(Q),Q=$.indexOf(Z,Q+Z.length);return Y}function Dz($,Z){let{file_path:Y,matches_found:Q,replacements_made:X,replace_all:J,size_diff:G}=$,q=`✅ 成功编辑文件: ${Y}`;if(q+=`
950
+ `)}return null}var SJ=()=>{};import{promises as s7}from"node:fs";class Q1{static instance=null;accessedFiles=new Map;constructor(){}static getInstance(){if(!Q1.instance)Q1.instance=new Q1;return Q1.instance}async recordFileRead($,Z){try{let Y=await s7.stat($),Q={filePath:$,accessTime:Date.now(),mtime:Y.mtimeMs,sessionId:Z,lastOperation:"read"};this.accessedFiles.set($,Q),C3.debug(`记录文件读取: ${$}`)}catch(Y){C3.warn(`记录文件读取失败: ${$}`,Y)}}async recordFileEdit($,Z,Y="edit"){try{let Q=await s7.stat($),X={filePath:$,accessTime:Date.now(),mtime:Q.mtimeMs,sessionId:Z,lastOperation:Y};this.accessedFiles.set($,X),C3.debug(`记录文件${Y==="edit"?"编辑":"写入"}: ${$}`)}catch(Q){C3.warn(`记录文件${Y==="edit"?"编辑":"写入"}失败: ${$}`,Q)}}hasFileBeenRead($,Z){let Y=this.accessedFiles.get($);if(!Y)return!1;if(Z&&Y.sessionId!==Z)return!1;return!0}async checkFileModification($){let Z=this.accessedFiles.get($);if(!Z)return{modified:!1,message:"文件未被跟踪"};try{let Y=await s7.stat($);if(Math.abs(Y.mtimeMs-Z.mtime)>1)return{modified:!0,message:`文件在访问后被修改(访问时间: ${new Date(Z.accessTime).toISOString()}, 当前修改时间: ${Y.mtime.toISOString()})`};return{modified:!1}}catch(Y){let Q=Y;if(Q.code==="ENOENT")return{modified:!0,message:"文件已被删除"};return{modified:!1,message:`无法检查文件状态: ${Q.message}`}}}async checkExternalModification($){let Z=this.accessedFiles.get($);if(!Z)return{isExternal:!1,message:"文件未被跟踪"};try{let Y=await s7.stat($);if(Y.mtimeMs-Z.mtime>2000)return{isExternal:!0,message:`文件在 ${new Date(Z.accessTime).toISOString()} (${Z.lastOperation}) 之后被外部程序修改(当前修改时间: ${Y.mtime.toISOString()})`};return{isExternal:!1}}catch(Y){let Q=Y;if(Q.code==="ENOENT")return{isExternal:!0,message:"文件已被删除"};return C3.warn(`检查文件外部修改失败: ${$}`,Y),{isExternal:!1,message:`无法检查文件状态: ${Q.message}`}}}getFileRecord($){return this.accessedFiles.get($)}clearFileRecord($){this.accessedFiles.delete($)}clearAll(){this.accessedFiles.clear()}clearSession($){for(let[Z,Y]of this.accessedFiles.entries())if(Y.sessionId===$)this.accessedFiles.delete(Z)}getTrackedFiles(){return Array.from(this.accessedFiles.keys())}getTrackedFileCount(){return this.accessedFiles.size}static resetInstance(){Q1.instance=null}}var C3;var t7=R(()=>{Q0();C3=x("Tool")});import{execSync as Nz}from"node:child_process";import*as m9 from"node:os";import*as S4 from"node:path";function Az($){return S4.resolve($).replace(/[/\\]/g,"-").replace(/:/g,"_")}function kJ($){let Z=$.replace(/_/g,":");if(Z.startsWith("-"))Z="/"+Z.slice(1);return Z.replace(/-/g,"/")}function S3($){let Z=m9.homedir(),Y=Az($);return S4.join(Z,".blade","projects",Y)}function O1($,Z){return S4.join(S3($),`${Z}.jsonl`)}function fJ($){try{return Nz("git rev-parse --abbrev-ref HEAD",{cwd:$,encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()||void 0}catch{return}}function k4(){return S4.join(m9.homedir(),".blade")}async function hJ(){let{readdir:$}=await import("node:fs/promises");try{let Z=S4.join(k4(),"projects");return(await $(Z,{withFileTypes:!0})).filter((Q)=>Q.isDirectory()).map((Q)=>Q.name)}catch{return[]}}var k3=()=>{};import*as xJ from"node:crypto";import{promises as U2}from"node:fs";import*as f4 from"node:path";class f3{sessionId;enableCheckpoints;maxSnapshots;snapshotDir;trackedFileBackups=new Map;snapshots=[];constructor($){this.sessionId=$.sessionId,this.enableCheckpoints=$.enableCheckpoints??!0,this.maxSnapshots=$.maxSnapshots??10;let Z=k4();this.snapshotDir=f4.join(Z,"file-history",this.sessionId)}async initialize(){if(!this.enableCheckpoints)return;try{await U2.mkdir(this.snapshotDir,{recursive:!0,mode:493}),console.log(`[SnapshotManager] 初始化快照目录: ${this.snapshotDir}`)}catch($){throw console.warn("[SnapshotManager] 创建快照目录失败:",$),$}}async createSnapshot($,Z){if(!this.enableCheckpoints)return console.log("[SnapshotManager] 检查点已禁用,跳过快照创建"),{backupFileName:"",version:0,backupTime:new Date};try{await U2.access($)}catch{return console.warn(`[SnapshotManager] 文件不存在,跳过快照: ${$}`),{backupFileName:"",version:0,backupTime:new Date}}let Y=this.trackedFileBackups.get($),Q=Y?Y.version+1:1,X=this.generateFileHash($,Q),J=f4.join(this.snapshotDir,`${X}@v${Q}`);try{let G=await U2.readFile($,{encoding:"utf-8"});await U2.writeFile(J,G,{encoding:"utf-8"});let q={backupFileName:X,version:Q,backupTime:new Date};return this.trackedFileBackups.set($,q),this.snapshots.push({messageId:Z,backupFileName:X,timestamp:new Date,filePath:$}),console.log(`[SnapshotManager] 创建快照: ${$} -> ${X}@v${Q}`),await this.cleanupOldSnapshots($),q}catch(G){throw console.error(`[SnapshotManager] 创建快照失败: ${$}`,G),G}}async restoreSnapshot($,Z){let Y=this.snapshots.slice().reverse().find((J)=>J.messageId===Z&&J.filePath===$);if(!Y)throw Error(`未找到快照: messageId=${Z}, filePath=${$}`);let Q=this.trackedFileBackups.get($);if(!Q)throw Error(`未找到文件追踪信息: ${$}`);let X=f4.join(this.snapshotDir,`${Y.backupFileName}@v${Q.version}`);try{let J=await U2.readFile(X,{encoding:"utf-8"});await U2.writeFile($,J,{encoding:"utf-8"}),console.log(`[SnapshotManager] 恢复快照: ${$} <- ${Y.backupFileName}@v${Q.version}`)}catch(J){throw console.error(`[SnapshotManager] 恢复快照失败: ${$}`,J),J}}async listSnapshots($){return this.snapshots.filter((Z)=>Z.filePath===$)}async cleanupOldSnapshots($){let Z=this.snapshots.filter((X)=>X.filePath===$);if(Z.length<=this.maxSnapshots)return;let Q=Z.sort((X,J)=>X.timestamp.getTime()-J.timestamp.getTime()).slice(0,Z.length-this.maxSnapshots);for(let X of Q){let J=this.trackedFileBackups.get(X.filePath);if(!J)continue;let G=f4.join(this.snapshotDir,`${X.backupFileName}@v${J.version}`);try{await U2.unlink(G),console.log(`[SnapshotManager] 删除旧快照: ${G}`)}catch(K){console.warn(`[SnapshotManager] 删除快照失败: ${G}`,K)}let q=this.snapshots.indexOf(X);if(q>-1)this.snapshots.splice(q,1)}}async cleanup($=0){try{let Z=await U2.readdir(this.snapshotDir);if(Z.length<=$)return;let Y=await Promise.all(Z.map(async(X)=>{let J=f4.join(this.snapshotDir,X),G=await U2.stat(J);return{file:X,mtime:G.mtime.getTime()}}));Y.sort((X,J)=>J.mtime-X.mtime);let Q=Y.slice($);for(let{file:X}of Q){let J=f4.join(this.snapshotDir,X);await U2.unlink(J),console.log(`[SnapshotManager] 清理快照: ${J}`)}}catch(Z){console.warn("[SnapshotManager] 清理快照失败:",Z)}}generateFileHash($,Z){let Y=xJ.createHash("md5");return Y.update(`${$}:${Z}`),Y.digest("hex").substring(0,16)}getSnapshotDir(){return this.snapshotDir}getSessionId(){return this.sessionId}getTrackedFileCount(){return this.trackedFileBackups.size}getSnapshotCount(){return this.snapshots.length}}var g9=R(()=>{k3()});import{basename as bz,extname as Rz}from"path";import{z as e7}from"zod";function pJ($){return $.replaceAll("‘","'").replaceAll("’","'").replaceAll("“",'"').replaceAll("”",'"')}function Vz($,Z){if($.includes(Z))return{matched:Z,strategy:"exact"};let Y=pJ(Z),X=pJ($).indexOf(Y);if(X!==-1)return{matched:$.substring(X,X+Z.length),strategy:"normalize_quotes"};let J=PJ(Z);if(J!==Z&&$.includes(J))return{matched:J,strategy:"unescape"};let G=CJ($,Z);if(G)return{matched:G,strategy:"flexible"};return{matched:null,strategy:"failed"}}function Mz($,Z){if(Z.length===0)return[];let Y=[],Q=$.indexOf(Z);while(Q!==-1)Y.push(Q),Q=$.indexOf(Z,Q+Z.length);return Y}function Dz($,Z){let{file_path:Y,matches_found:Q,replacements_made:X,replace_all:J,size_diff:G}=$,q=`✅ 成功编辑文件: ${Y}`;if(q+=`
951
951
  \uD83D\uDCDD 替换了 ${X} 个匹配项`,!J&&Q>1)q+=` (共找到 ${Q} 个匹配项)`;if(G!==0){let K=G>0?`增加${G}`:`减少${Math.abs(G)}`;q+=`
952
952
  \uD83D\uDCCA 文件大小${K}个字符`}if(Z)q+=Z;return q}function jz($,Z,Y){let Q=$.split(`
953
953
  `),X=Q.length,J=yz($,Z,3),G=0,q=Math.min(20,X);if(J.length>0){let H=J[0];G=Math.max(0,H.lineNumber-10),q=Math.min(X,H.lineNumber+10)}let W=Q.slice(G,q).map((H,_)=>{return` ${(G+_+1).toString().padStart(4)}: ${H}`}).join(`
@@ -999,7 +999,7 @@ ${W}
999
999
  `,F+=" 3. 使用更多上下文代码确保唯一性",{llmContent:U,displayContent:F,metadata:{searchStringLength:Z.length,fuzzyMatches:J.map((H)=>({line:H.lineNumber,similarity:H.similarity,preview:H.text.substring(0,100)})),excerptRange:[G+1,q],totalLines:X}}}function yz($,Z,Y=3){let Q=$.split(`
1000
1000
  `),X=Z.split(`
1001
1001
  `);if(X.length===1)return Q.map((K,W)=>({text:K,lineNumber:W+1,similarity:mJ(Z.trim(),K.trim())})).filter((K)=>K.similarity>0.5).sort((K,W)=>W.similarity-K.similarity).slice(0,Y);let J=X.length,G=[];for(let q=0;q<=Q.length-J;q++){let K=Q.slice(q,q+J).join(`
1002
- `),W=mJ(Z,K);if(W>0.5)G.push({text:K,lineNumber:q+1,similarity:W})}return G.sort((q,K)=>K.similarity-q.similarity).slice(0,Y)}function mJ($,Z){let Y=(F)=>F.trim().replace(/\s+/g," ").replace(/[\u201c\u201d"]/g,'"').replace(/[\u2018\u2019']/g,"'"),Q=Y($),X=Y(Z);if(Q===X)return 1;let J=Q.length,G=X.length;if(J===0)return G===0?1:0;if(G===0)return 0;let q=200,K=Q.substring(0,q),W=X.substring(0,q),U=Tz(K,W),O=Math.max(K.length,W.length);return 1-U/O}function Tz($,Z){let Y=$.length,Q=Z.length,X=Array(Y+1).fill(null).map(()=>Array(Q+1).fill(0));for(let J=0;J<=Y;J++)X[J][0]=J;for(let J=0;J<=Q;J++)X[0][J]=J;for(let J=1;J<=Y;J++)for(let G=1;G<=Q;G++){let q=$[J-1]===Z[G-1]?0:1;X[J][G]=Math.min(X[J-1][G]+1,X[J][G-1]+1,X[J-1][G-1]+q)}return X[Y][Q]}var u9;var gJ=R(()=>{V8();C4();h0();j$();o2();p9();SJ();t6();g9();u9=e({name:"Edit",displayName:"File Edit",kind:"write",strict:!0,isConcurrencySafe:!1,schema:e6.object({file_path:a0.filePath({description:"Absolute path of the file to edit"}),old_string:e6.string().min(1,"old_string cannot be empty").describe("String to replace"),new_string:e6.string().describe("Replacement string (can be empty)"),replace_all:e6.boolean().default(!1).describe("Replace all matches (default: first only)")}),description:{short:"Performs exact string replacements in files",long:"Performs exact string replacements in files.",usageNotes:["You must use your Read tool at least once in the conversation before editing. This tool will error if you attempt an edit without reading the file.","When editing text from Read tool output, ensure you preserve the exact indentation (tabs/spaces) as it appears AFTER the line number prefix. The line number prefix format is: spaces + line number + tab. Everything after that tab is the actual file content to match. Never include any part of the line number prefix in the old_string or new_string.","ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.","Only use emojis if the user explicitly requests it. Avoid adding emojis to files unless asked.","The edit will FAIL if old_string is not unique in the file. Either provide a larger string with more surrounding context to make it unique or use replace_all to change every instance of old_string.","Use replace_all for replacing and renaming strings across the file. This parameter is useful if you want to rename a variable for instance."]},async execute($,Z){let{file_path:Y,old_string:Q,new_string:X,replace_all:J}=$,{updateOutput:G,sessionId:q,messageId:K}=Z,W=Z.signal??new AbortController().signal;try{G?.("Starting to read file...");let U=a2(),O=n2(),F;try{if(O)G?.("通过 IDE 读取文件...");F=await U.readTextFile(Y)}catch(A){let k=A;if(k.code==="ENOENT"||k.message?.includes("not found"))return{success:!1,llmContent:`File not found: ${Y}`,displayContent:`❌ 文件不存在: ${Y}`,error:{type:"execution_error",message:"文件不存在"}};throw A}if(typeof W.throwIfAborted==="function")W.throwIfAborted();if(q){let A=Q1.getInstance();if(!A.hasFileBeenRead(Y,q))return{success:!1,llmContent:"You must use your Read tool at least once in the conversation before editing. This tool will error if you attempt an edit without reading the file.",displayContent:"\uD83D\uDCD6 我需要先读取文件内容,然后再进行编辑。",error:{type:"validation_error",message:"File not read before edit"},metadata:{requiresRead:!0}};let k=await A.checkExternalModification(Y);if(k.isExternal)return{success:!1,llmContent:`The file has been modified by an external program since you last read it. You must use the Read tool again to see the current content before editing.
1002
+ `),W=mJ(Z,K);if(W>0.5)G.push({text:K,lineNumber:q+1,similarity:W})}return G.sort((q,K)=>K.similarity-q.similarity).slice(0,Y)}function mJ($,Z){let Y=(F)=>F.trim().replace(/\s+/g," ").replace(/[\u201c\u201d"]/g,'"').replace(/[\u2018\u2019']/g,"'"),Q=Y($),X=Y(Z);if(Q===X)return 1;let J=Q.length,G=X.length;if(J===0)return G===0?1:0;if(G===0)return 0;let q=200,K=Q.substring(0,q),W=X.substring(0,q),U=Tz(K,W),O=Math.max(K.length,W.length);return 1-U/O}function Tz($,Z){let Y=$.length,Q=Z.length,X=Array(Y+1).fill(null).map(()=>Array(Q+1).fill(0));for(let J=0;J<=Y;J++)X[J][0]=J;for(let J=0;J<=Q;J++)X[0][J]=J;for(let J=1;J<=Y;J++)for(let G=1;G<=Q;G++){let q=$[J-1]===Z[G-1]?0:1;X[J][G]=Math.min(X[J-1][G]+1,X[J][G-1]+1,X[J-1][G-1]+q)}return X[Y][Q]}var u9;var gJ=R(()=>{V8();C4();h0();j$();o2();p9();SJ();t7();g9();u9=e({name:"Edit",displayName:"File Edit",kind:"write",strict:!0,isConcurrencySafe:!1,schema:e7.object({file_path:a0.filePath({description:"Absolute path of the file to edit"}),old_string:e7.string().min(1,"old_string cannot be empty").describe("String to replace"),new_string:e7.string().describe("Replacement string (can be empty)"),replace_all:e7.boolean().default(!1).describe("Replace all matches (default: first only)")}),description:{short:"Performs exact string replacements in files",long:"Performs exact string replacements in files.",usageNotes:["You must use your Read tool at least once in the conversation before editing. This tool will error if you attempt an edit without reading the file.","When editing text from Read tool output, ensure you preserve the exact indentation (tabs/spaces) as it appears AFTER the line number prefix. The line number prefix format is: spaces + line number + tab. Everything after that tab is the actual file content to match. Never include any part of the line number prefix in the old_string or new_string.","ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.","Only use emojis if the user explicitly requests it. Avoid adding emojis to files unless asked.","The edit will FAIL if old_string is not unique in the file. Either provide a larger string with more surrounding context to make it unique or use replace_all to change every instance of old_string.","Use replace_all for replacing and renaming strings across the file. This parameter is useful if you want to rename a variable for instance."]},async execute($,Z){let{file_path:Y,old_string:Q,new_string:X,replace_all:J}=$,{updateOutput:G,sessionId:q,messageId:K}=Z,W=Z.signal??new AbortController().signal;try{G?.("Starting to read file...");let U=a2(),O=n2(),F;try{if(O)G?.("通过 IDE 读取文件...");F=await U.readTextFile(Y)}catch(A){let k=A;if(k.code==="ENOENT"||k.message?.includes("not found"))return{success:!1,llmContent:`File not found: ${Y}`,displayContent:`❌ 文件不存在: ${Y}`,error:{type:"execution_error",message:"文件不存在"}};throw A}if(typeof W.throwIfAborted==="function")W.throwIfAborted();if(q){let A=Q1.getInstance();if(!A.hasFileBeenRead(Y,q))return{success:!1,llmContent:"You must use your Read tool at least once in the conversation before editing. This tool will error if you attempt an edit without reading the file.",displayContent:"\uD83D\uDCD6 我需要先读取文件内容,然后再进行编辑。",error:{type:"validation_error",message:"File not read before edit"},metadata:{requiresRead:!0}};let k=await A.checkExternalModification(Y);if(k.isExternal)return{success:!1,llmContent:`The file has been modified by an external program since you last read it. You must use the Read tool again to see the current content before editing.
1003
1003
 
1004
1004
  Details: ${k.message}`,displayContent:`❌ 编辑失败:文件已被外部程序修改
1005
1005
 
@@ -1010,7 +1010,7 @@ ${k.message}
1010
1010
  `),S=["⚠️ 编辑暂停:需要更精确的定位","",`在文件中找到 ${z.length} 处相似代码:`,...c.map((y,l)=>` • 第 ${y.line} 行 (匹配 ${l+1}/${z.length})`),"","AI 正在自动调整,添加更多上下文以精确定位...","通常需要 1-2 次尝试即可成功","","\uD83D\uDCA1 如果多次失败,可能需要:"," • 包含函数/类名等独特标识符"," • 添加目标代码前后 3-5 行完整上下文",` • 或使用 replace_all=true 同时替换所有 ${z.length} 处匹配`].join(`
1011
1011
  `);return{success:!1,llmContent:o,displayContent:S,error:{type:"validation_error",message:"old_string is not unique",details:{matches:c.map((y)=>({line:y.line,column:y.column})),count:z.length}}}}else G?.(`找到 ${z.length} 个匹配项,开始替换...`);let w,B;if(J)w=F.split(_).join(X),B=z.length;else{let A=F.indexOf(_);w=F.substring(0,A)+X+F.substring(A+_.length),B=1}if(typeof W.throwIfAborted==="function")W.throwIfAborted();if(O)G?.("通过 IDE 写入文件...");if(await U.writeTextFile(Y,w),q)await Q1.getInstance().recordFileEdit(Y,q,"edit");let L=await U.stat(Y),N=vJ(F,w,_,X,4),M=bz(Y),b=B===1?`替换 1 处匹配到 ${M}`:`替换 ${B} 处匹配到 ${M}`,j={file_path:Y,matches_found:z.length,replacements_made:B,replace_all:J,old_string_length:Q.length,new_string_length:X.length,original_size:F.length,new_size:w.length,size_diff:w.length-F.length,last_modified:L?.mtime instanceof Date?L.mtime.toISOString():void 0,snapshot_created:!!(q&&K),session_id:q,message_id:K,diff_snippet:N,summary:b,kind:"edit",oldContent:F,newContent:w},T=Dz(j,N);return{success:!0,llmContent:{file_path:Y,replacements:B,total_matches:z.length},displayContent:T,metadata:j}}catch(U){let O=U;if(O.name==="AbortError")return{success:!1,llmContent:"File edit aborted",displayContent:"⚠️ 文件编辑被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`File edit failed: ${O.message}`,displayContent:`❌ 编辑文件失败: ${O.message}`,error:{type:"execution_error",message:O.message,details:O}}}},version:"2.0.0",category:"文件操作",tags:["file","edit","replace","modify"],extractSignatureContent:($)=>$.file_path,abstractPermissionRule:($)=>{let Z=Rz($.file_path);return Z?`**/*${Z}`:"**/*"}})});import{basename as Ez,extname as uJ}from"path";import{z as Iz}from"zod";function vz($){return[".txt",".md",".js",".ts",".jsx",".tsx",".json",".xml",".html",".htm",".css",".scss",".sass",".less",".yml",".yaml",".toml",".ini",".cfg",".py",".rb",".php",".java",".cpp",".c",".h",".hpp",".rs",".go",".sh",".bash",".zsh",".fish",".ps1",".bat",".cmd",".sql",".graphql",".vue",".svelte",".astro",".dockerfile",".gitignore",".env"].includes($)||$===""}function Pz($){return[".jpg",".jpeg",".png",".gif",".bmp",".svg",".ico",".webp",".mp3",".wav",".mp4",".avi",".mov",".wmv",".flv",".webm",".pdf",".doc",".docx",".xls",".xlsx",".ppt",".pptx",".zip",".tar",".gz",".rar",".7z",".exe",".dll",".so",".ttf",".otf",".woff",".woff2",".eot"].includes($)}function Cz($,Z){let Y=`✅ 成功读取文件: ${$}`;if(Z.file_size!==void 0&&typeof Z.file_size==="number")Y+=` (${Sz(Z.file_size)})`;if(Z.lines_read!==void 0)Y+=`
1012
1012
  \uD83D\uDCC4 读取了 ${Z.lines_read} 行 (第${Z.start_line}-${Z.end_line}行,共${Z.total_lines}行)`;if(Z.is_binary)Y+=`
1013
- \uD83D\uDD10 文件以 base64 编码显示`;return Y}function Sz($){let Z=["B","KB","MB","GB"],Y=$,Q=0;while(Y>=1024&&Q<Z.length-1)Y/=1024,Q++;return`${Y.toFixed(1)}${Z[Q]}`}var d9;var dJ=R(()=>{V8();C4();h0();j$();o2();t6();d9=e({name:"Read",displayName:"File Read",kind:"readonly",schema:Iz.object({file_path:a0.filePath({description:"File path to read (must be absolute)"}),offset:a0.lineNumber({description:"Starting line number (0-based, text files only)"}).optional(),limit:a0.lineLimit({description:"Number of lines to read (text files only)"}).optional(),encoding:a0.encoding()}),description:{short:"Read files from the local filesystem",long:"Reads a file from the local filesystem. You can access any file directly by using this tool. Assume this tool is able to read all files on the machine. If the User provides a path to a file assume that path is valid. It is okay to read a file that does not exist; an error will be returned.",usageNotes:["The file_path parameter must be an absolute path, not a relative path","By default, it reads up to 2000 lines starting from the beginning of the file","You can optionally specify a line offset and limit (especially handy for long files), but it's recommended to read the whole file by not providing these parameters","Any lines longer than 2000 characters will be truncated","Results are returned using cat -n format, with line numbers starting at 1","This tool allows reading images (eg PNG, JPG, etc). When reading an image file the contents are presented visually as this is a multimodal LLM.","This tool can read PDF files (.pdf). PDFs are processed page by page, extracting both text and visual content for analysis.","This tool can read Jupyter notebooks (.ipynb files) and returns all cells with their outputs, combining code, text, and visualizations.","This tool can only read files, not directories. To read a directory, use an ls command via the Bash tool.","You can call multiple tools in a single response. It is always better to speculatively read multiple potentially useful files in parallel.","You will regularly be asked to read screenshots. If the user provides a path to a screenshot, ALWAYS use this tool to view the file at the path. This tool will work with all temporary file paths.","If you read a file that exists but has empty contents you will receive a system reminder warning in place of file contents."],examples:[{description:"Read the entire file (recommended)",params:{file_path:"/path/to/file.ts"}},{description:"Read the first 100 lines",params:{file_path:"/path/to/file.txt",limit:100}},{description:"Read 100 lines starting at line 50 (large file)",params:{file_path:"/path/to/large-file.log",offset:50,limit:100}}],important:["file_path must be absolute","Prefer reading the entire file (omit offset and limit)","Use offset/limit only for very large files","Line numbers start at 1 (cat -n format)"]},async execute($,Z){let{file_path:Y,offset:Q,limit:X,encoding:J="utf8"}=$,{updateOutput:G,sessionId:q}=Z,K=Z.signal??new AbortController().signal;try{G?.("Starting file read...");let W=a2(),U=n2();try{if(!await W.exists(Y))throw Error("File not found")}catch(b){return{success:!1,llmContent:`File not found: ${Y}`,displayContent:`❌ 文件不存在: ${Y}`,error:{type:"execution_error",message:`File not found: ${Y}`}}}if(typeof K.throwIfAborted==="function")K.throwIfAborted();if(q)await Q1.getInstance().recordFileRead(Y,q);let O=await W.stat(Y);if(O?.isDirectory)return{success:!1,llmContent:`Cannot read a directory: ${Y}`,displayContent:`❌ 无法读取目录: ${Y}`,error:{type:"execution_error",message:"Target is a directory, not a file"}};let F=uJ(Y).toLowerCase(),H=vz(F),_=Pz(F),z,w={file_path:Y,file_size:O?.size,file_type:F,last_modified:O?.mtime instanceof Date?O.mtime.toISOString():void 0,encoding:J,acp_mode:U};if(_&&J==="utf8"){if(U)G?.("⚠️ 二进制文件通过本地读取(ACP 不支持)..."),w.acp_fallback=!0;else G?.("检测到二进制文件,使用 base64 编码...");z=(await W.readBinaryFile(Y)).toString("base64"),w.encoding="base64",w.is_binary=!0}else if(H){if(U)G?.("通过 IDE 读取文件...");z=await W.readTextFile(Y)}else{if(U)w.acp_fallback=!0;let b=await W.readBinaryFile(Y);if(J==="base64")z=b.toString("base64");else if(J==="binary")z=b.toString("binary");else z=b.toString("utf8")}if(typeof K.throwIfAborted==="function")K.throwIfAborted();if((Q!==void 0||X!==void 0)&&J==="utf8"&&H){let b=z.split(`
1013
+ \uD83D\uDD10 文件以 base64 编码显示`;return Y}function Sz($){let Z=["B","KB","MB","GB"],Y=$,Q=0;while(Y>=1024&&Q<Z.length-1)Y/=1024,Q++;return`${Y.toFixed(1)}${Z[Q]}`}var d9;var dJ=R(()=>{V8();C4();h0();j$();o2();t7();d9=e({name:"Read",displayName:"File Read",kind:"readonly",schema:Iz.object({file_path:a0.filePath({description:"File path to read (must be absolute)"}),offset:a0.lineNumber({description:"Starting line number (0-based, text files only)"}).optional(),limit:a0.lineLimit({description:"Number of lines to read (text files only)"}).optional(),encoding:a0.encoding()}),description:{short:"Read files from the local filesystem",long:"Reads a file from the local filesystem. You can access any file directly by using this tool. Assume this tool is able to read all files on the machine. If the User provides a path to a file assume that path is valid. It is okay to read a file that does not exist; an error will be returned.",usageNotes:["The file_path parameter must be an absolute path, not a relative path","By default, it reads up to 2000 lines starting from the beginning of the file","You can optionally specify a line offset and limit (especially handy for long files), but it's recommended to read the whole file by not providing these parameters","Any lines longer than 2000 characters will be truncated","Results are returned using cat -n format, with line numbers starting at 1","This tool allows reading images (eg PNG, JPG, etc). When reading an image file the contents are presented visually as this is a multimodal LLM.","This tool can read PDF files (.pdf). PDFs are processed page by page, extracting both text and visual content for analysis.","This tool can read Jupyter notebooks (.ipynb files) and returns all cells with their outputs, combining code, text, and visualizations.","This tool can only read files, not directories. To read a directory, use an ls command via the Bash tool.","You can call multiple tools in a single response. It is always better to speculatively read multiple potentially useful files in parallel.","You will regularly be asked to read screenshots. If the user provides a path to a screenshot, ALWAYS use this tool to view the file at the path. This tool will work with all temporary file paths.","If you read a file that exists but has empty contents you will receive a system reminder warning in place of file contents."],examples:[{description:"Read the entire file (recommended)",params:{file_path:"/path/to/file.ts"}},{description:"Read the first 100 lines",params:{file_path:"/path/to/file.txt",limit:100}},{description:"Read 100 lines starting at line 50 (large file)",params:{file_path:"/path/to/large-file.log",offset:50,limit:100}}],important:["file_path must be absolute","Prefer reading the entire file (omit offset and limit)","Use offset/limit only for very large files","Line numbers start at 1 (cat -n format)"]},async execute($,Z){let{file_path:Y,offset:Q,limit:X,encoding:J="utf8"}=$,{updateOutput:G,sessionId:q}=Z,K=Z.signal??new AbortController().signal;try{G?.("Starting file read...");let W=a2(),U=n2();try{if(!await W.exists(Y))throw Error("File not found")}catch(b){return{success:!1,llmContent:`File not found: ${Y}`,displayContent:`❌ 文件不存在: ${Y}`,error:{type:"execution_error",message:`File not found: ${Y}`}}}if(typeof K.throwIfAborted==="function")K.throwIfAborted();if(q)await Q1.getInstance().recordFileRead(Y,q);let O=await W.stat(Y);if(O?.isDirectory)return{success:!1,llmContent:`Cannot read a directory: ${Y}`,displayContent:`❌ 无法读取目录: ${Y}`,error:{type:"execution_error",message:"Target is a directory, not a file"}};let F=uJ(Y).toLowerCase(),H=vz(F),_=Pz(F),z,w={file_path:Y,file_size:O?.size,file_type:F,last_modified:O?.mtime instanceof Date?O.mtime.toISOString():void 0,encoding:J,acp_mode:U};if(_&&J==="utf8"){if(U)G?.("⚠️ 二进制文件通过本地读取(ACP 不支持)..."),w.acp_fallback=!0;else G?.("检测到二进制文件,使用 base64 编码...");z=(await W.readBinaryFile(Y)).toString("base64"),w.encoding="base64",w.is_binary=!0}else if(H){if(U)G?.("通过 IDE 读取文件...");z=await W.readTextFile(Y)}else{if(U)w.acp_fallback=!0;let b=await W.readBinaryFile(Y);if(J==="base64")z=b.toString("base64");else if(J==="binary")z=b.toString("binary");else z=b.toString("utf8")}if(typeof K.throwIfAborted==="function")K.throwIfAborted();if((Q!==void 0||X!==void 0)&&J==="utf8"&&H){let b=z.split(`
1014
1014
  `),j=Q||0,T=X!==void 0?j+X:b.length,A=b.slice(j,T);z=A.map((k,c)=>{let o=j+c+1,S=k.length>2000?`${k.substring(0,2000)}...`:k;return`${o.toString().padStart(6)}→${S}`}).join(`
1015
1015
  `),w.lines_read=A.length,w.total_lines=b.length,w.start_line=j+1,w.end_line=Math.min(T,b.length)}let B=Ez(Y),L=w.lines_read||w.total_lines,N=L?`读取 ${L} 行从 ${B}`:`读取 ${B}`;w.summary=N;let M=Cz(Y,w);return{success:!0,llmContent:z,displayContent:M,metadata:w}}catch(W){let U=W;if(U.name==="AbortError")return{success:!1,llmContent:"File read aborted",displayContent:"⚠️ 文件读取被用户中止",error:{type:"execution_error",message:"Operation aborted"}};return{success:!1,llmContent:`File read failed: ${U.message}`,displayContent:`❌ 读取文件失败: ${U.message}`,error:{type:"execution_error",message:U.message,details:U}}}},version:"2.0.0",category:"文件操作",tags:["file","io","read"],extractSignatureContent:($)=>$.file_path,abstractPermissionRule:($)=>{let Z=uJ($.file_path);return Z?`**/*${Z}`:"**/*"}})});import{promises as kz}from"fs";import{basename as fz,dirname as hz,extname as cJ}from"path";import{z as c9}from"zod";function xz($,Z,Y,Q){let X=`✅ 成功写入文件: ${$}`;if(Z.file_size!==void 0)X+=` (${lJ(Z.file_size)})`;if(Z.snapshot_created)X+=`
1016
1016
  \uD83D\uDCF8 已创建快照 (可回滚)`;if(Z.encoding!=="utf8")X+=`
@@ -1025,7 +1025,7 @@ ${k.message}
1025
1025
  `))U+=`
1026
1026
  `;if(U+="```",K)U+=`
1027
1027
 
1028
- ⚠️ 内容已截断(完整文件共 ${W.length} 行,${Z.length} 字符)`;return U}function lJ($){let Z=["B","KB","MB","GB"],Y=$,Q=0;while(Y>=1024&&Q<Z.length-1)Y/=1024,Q++;return`${Y.toFixed(1)}${Z[Q]}`}var l9;var iJ=R(()=>{V8();C4();h0();j$();o2();p9();t6();g9();l9=e({name:"Write",displayName:"File Write",kind:"write",strict:!0,isConcurrencySafe:!1,schema:c9.object({file_path:a0.filePath({description:"Absolute file path to write"}),content:c9.string().describe("Content to write"),encoding:a0.encoding(),create_directories:c9.boolean().default(!0).describe("Automatically create missing parent directories")}),description:{short:"Writes a file to the local filesystem",long:"Writes a file to the local filesystem.",usageNotes:["This tool will overwrite the existing file if there is one at the provided path.","If this is an existing file, you MUST use the Read tool first to read the file's contents. This tool will fail if you did not read the file first.","ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.","NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User.","Only use emojis if the user explicitly requests it. Avoid writing emojis to files unless asked."]},async execute($,Z){let{file_path:Y,content:Q,encoding:X,create_directories:J}=$,{updateOutput:G,sessionId:q,messageId:K}=Z,W=Z.signal??new AbortController().signal;try{G?.("开始写入文件...");let U=a2(),O=n2();if(J){let b=hz(Y);try{await U.mkdir(b,{recursive:!0,mode:493})}catch(j){if(j.code!=="EEXIST")throw j}}if(typeof W.throwIfAborted==="function")W.throwIfAborted();let F=!1,H=null;try{if(F=await U.exists(Y),F&&X==="utf8")try{H=await U.readTextFile(Y)}catch(b){console.warn("[WriteTool] 读取旧文件内容失败:",b)}}catch{}if(F&&q){let b=Q1.getInstance();if(!b.hasFileBeenRead(Y,q))return{success:!1,llmContent:"If this is an existing file, you MUST use the Read tool first to read the file's contents. This tool will fail if you did not read the file first.",displayContent:"\uD83D\uDCD6 我需要先读取文件内容,然后再进行写入。",error:{type:"validation_error",message:"File not read before write"},metadata:{requiresRead:!0}};let j=await b.checkExternalModification(Y);if(j.isExternal)return{success:!1,llmContent:`The file has been modified by an external program since you last read it. You must use the Read tool again to see the current content before writing.
1028
+ ⚠️ 内容已截断(完整文件共 ${W.length} 行,${Z.length} 字符)`;return U}function lJ($){let Z=["B","KB","MB","GB"],Y=$,Q=0;while(Y>=1024&&Q<Z.length-1)Y/=1024,Q++;return`${Y.toFixed(1)}${Z[Q]}`}var l9;var iJ=R(()=>{V8();C4();h0();j$();o2();p9();t7();g9();l9=e({name:"Write",displayName:"File Write",kind:"write",strict:!0,isConcurrencySafe:!1,schema:c9.object({file_path:a0.filePath({description:"Absolute file path to write"}),content:c9.string().describe("Content to write"),encoding:a0.encoding(),create_directories:c9.boolean().default(!0).describe("Automatically create missing parent directories")}),description:{short:"Writes a file to the local filesystem",long:"Writes a file to the local filesystem.",usageNotes:["This tool will overwrite the existing file if there is one at the provided path.","If this is an existing file, you MUST use the Read tool first to read the file's contents. This tool will fail if you did not read the file first.","ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.","NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User.","Only use emojis if the user explicitly requests it. Avoid writing emojis to files unless asked."]},async execute($,Z){let{file_path:Y,content:Q,encoding:X,create_directories:J}=$,{updateOutput:G,sessionId:q,messageId:K}=Z,W=Z.signal??new AbortController().signal;try{G?.("开始写入文件...");let U=a2(),O=n2();if(J){let b=hz(Y);try{await U.mkdir(b,{recursive:!0,mode:493})}catch(j){if(j.code!=="EEXIST")throw j}}if(typeof W.throwIfAborted==="function")W.throwIfAborted();let F=!1,H=null;try{if(F=await U.exists(Y),F&&X==="utf8")try{H=await U.readTextFile(Y)}catch(b){console.warn("[WriteTool] 读取旧文件内容失败:",b)}}catch{}if(F&&q){let b=Q1.getInstance();if(!b.hasFileBeenRead(Y,q))return{success:!1,llmContent:"If this is an existing file, you MUST use the Read tool first to read the file's contents. This tool will fail if you did not read the file first.",displayContent:"\uD83D\uDCD6 我需要先读取文件内容,然后再进行写入。",error:{type:"validation_error",message:"File not read before write"},metadata:{requiresRead:!0}};let j=await b.checkExternalModification(Y);if(j.isExternal)return{success:!1,llmContent:`The file has been modified by an external program since you last read it. You must use the Read tool again to see the current content before writing.
1029
1029
 
1030
1030
  Details: ${j.message}`,displayContent:`❌ 写入失败:文件已被外部程序修改
1031
1031
 
@@ -1036,11 +1036,11 @@ ${j.message}
1036
1036
  当前通过 IDE 执行文件操作,但 IDE 仅支持文本文件。
1037
1037
 
1038
1038
  \uD83D\uDCA1 如果是文本文件,我会使用 encoding='utf8' 重试;如果必须写入二进制文件,需要在本地终端执行`,error:{type:"validation_error",message:"Binary writes not supported in ACP mode"}};let b;if(X==="base64")b=Buffer.from(Q,"base64");else if(X==="binary")b=Buffer.from(Q,"binary");else b=Buffer.from(Q,"utf8");await kz.writeFile(Y,b)}if(q)await Q1.getInstance().recordFileEdit(Y,q,"write");if(typeof W.throwIfAborted==="function")W.throwIfAborted();let z=await U.stat(Y),w=X==="utf8"?Q.split(`
1039
- `).length:0,B=fz(Y),L=null;if(H&&X==="utf8"&&H!==Q){if(H.length<1048576&&Q.length<1048576)L=IJ(H,Q,4)}let N={file_path:Y,content_size:Q.length,file_size:z?.size,encoding:X,created_directories:J,snapshot_created:_,session_id:q,message_id:K,last_modified:z?.mtime instanceof Date?z.mtime.toISOString():void 0,has_diff:!!L,summary:X==="utf8"?`写入 ${w} 行到 ${B}`:`写入 ${z?.size?lJ(z.size):"unknown"} 到 ${B}`,kind:"edit",oldContent:H||"",newContent:X==="utf8"?Q:void 0},M=xz(Y,N,Q,L);return{success:!0,llmContent:{file_path:Y,size:z?.size,modified:z?.mtime instanceof Date?z.mtime.toISOString():void 0},displayContent:M,metadata:N}}catch(U){let O=U;if(O.name==="AbortError")return{success:!1,llmContent:"File write aborted",displayContent:"⚠️ 文件写入被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`File write failed: ${O.message}`,displayContent:`❌ 写入文件失败: ${O.message}`,error:{type:"execution_error",message:O.message,details:O}}}},version:"2.0.0",category:"文件操作",tags:["file","io","write","create"],extractSignatureContent:($)=>$.file_path,abstractPermissionRule:($)=>{let Z=cJ($.file_path);return Z?`**/*${Z}`:"**/*"}})});var rJ=R(()=>{gJ();dJ();iJ()});import*as $7 from"fs/promises";import{z as M8}from"zod";var i9;var aJ=R(()=>{h0();R$();i9=e({name:"NotebookEdit",displayName:"Notebook Edit",kind:"write",schema:M8.object({notebook_path:M8.string().describe("The absolute path to the Jupyter notebook file to edit (must be absolute, not relative)"),cell_id:M8.string().optional().describe("The ID of the cell to edit. When inserting a new cell, the new cell will be inserted after the cell with this ID, or at the beginning if not specified."),new_source:M8.string().describe("The new source for the cell"),cell_type:M8.enum(["code","markdown"]).optional().describe("The type of the cell (code or markdown). If not specified, it defaults to the current cell type. If using edit_mode=insert, this is required."),edit_mode:M8.enum(["replace","insert","delete"]).optional().default("replace").describe("The type of edit to make (replace, insert, delete). Defaults to replace.")}),description:{short:"Completely replaces the contents of a specific cell in a Jupyter notebook",long:"Completely replaces the contents of a specific cell in a Jupyter notebook (.ipynb file) with new source. Jupyter notebooks are interactive documents that combine code, text, and visualizations, commonly used for data analysis and scientific computing. The notebook_path parameter must be an absolute path, not a relative path. The cell_number is 0-indexed. Use edit_mode=insert to add a new cell at the index specified by cell_number. Use edit_mode=delete to delete the cell at the index specified by cell_number."},async execute($,Z){let{notebook_path:Y,cell_id:Q,new_source:X,cell_type:J,edit_mode:G="replace"}=$;try{let q=await $7.readFile(Y,"utf-8"),K=JSON.parse(q);if(!K.cells||!Array.isArray(K.cells))return{success:!1,llmContent:"Invalid notebook format: no cells array found",displayContent:"Invalid notebook format",error:{type:"validation_error",message:"Invalid notebook format"}};let W=-1;if(Q){if(W=K.cells.findIndex((O)=>O.id===Q),W===-1&&G!=="insert")return{success:!1,llmContent:`Cell with ID "${Q}" not found`,displayContent:"Cell not found",error:{type:"validation_error",message:`Cell ID "${Q}" not found`}}}switch(G){case"replace":{if(W===-1)return{success:!1,llmContent:"Cell ID required for replace operation",displayContent:"Cell ID required",error:{type:"validation_error",message:"Cell ID required for replace"}};let O=K.cells[W];if(O.source=X.split(`
1039
+ `).length:0,B=fz(Y),L=null;if(H&&X==="utf8"&&H!==Q){if(H.length<1048576&&Q.length<1048576)L=IJ(H,Q,4)}let N={file_path:Y,content_size:Q.length,file_size:z?.size,encoding:X,created_directories:J,snapshot_created:_,session_id:q,message_id:K,last_modified:z?.mtime instanceof Date?z.mtime.toISOString():void 0,has_diff:!!L,summary:X==="utf8"?`写入 ${w} 行到 ${B}`:`写入 ${z?.size?lJ(z.size):"unknown"} 到 ${B}`,kind:"edit",oldContent:H||"",newContent:X==="utf8"?Q:void 0},M=xz(Y,N,Q,L);return{success:!0,llmContent:{file_path:Y,size:z?.size,modified:z?.mtime instanceof Date?z.mtime.toISOString():void 0},displayContent:M,metadata:N}}catch(U){let O=U;if(O.name==="AbortError")return{success:!1,llmContent:"File write aborted",displayContent:"⚠️ 文件写入被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`File write failed: ${O.message}`,displayContent:`❌ 写入文件失败: ${O.message}`,error:{type:"execution_error",message:O.message,details:O}}}},version:"2.0.0",category:"文件操作",tags:["file","io","write","create"],extractSignatureContent:($)=>$.file_path,abstractPermissionRule:($)=>{let Z=cJ($.file_path);return Z?`**/*${Z}`:"**/*"}})});var rJ=R(()=>{gJ();dJ();iJ()});import*as $6 from"fs/promises";import{z as M8}from"zod";var i9;var aJ=R(()=>{h0();R$();i9=e({name:"NotebookEdit",displayName:"Notebook Edit",kind:"write",schema:M8.object({notebook_path:M8.string().describe("The absolute path to the Jupyter notebook file to edit (must be absolute, not relative)"),cell_id:M8.string().optional().describe("The ID of the cell to edit. When inserting a new cell, the new cell will be inserted after the cell with this ID, or at the beginning if not specified."),new_source:M8.string().describe("The new source for the cell"),cell_type:M8.enum(["code","markdown"]).optional().describe("The type of the cell (code or markdown). If not specified, it defaults to the current cell type. If using edit_mode=insert, this is required."),edit_mode:M8.enum(["replace","insert","delete"]).optional().default("replace").describe("The type of edit to make (replace, insert, delete). Defaults to replace.")}),description:{short:"Completely replaces the contents of a specific cell in a Jupyter notebook",long:"Completely replaces the contents of a specific cell in a Jupyter notebook (.ipynb file) with new source. Jupyter notebooks are interactive documents that combine code, text, and visualizations, commonly used for data analysis and scientific computing. The notebook_path parameter must be an absolute path, not a relative path. The cell_number is 0-indexed. Use edit_mode=insert to add a new cell at the index specified by cell_number. Use edit_mode=delete to delete the cell at the index specified by cell_number."},async execute($,Z){let{notebook_path:Y,cell_id:Q,new_source:X,cell_type:J,edit_mode:G="replace"}=$;try{let q=await $6.readFile(Y,"utf-8"),K=JSON.parse(q);if(!K.cells||!Array.isArray(K.cells))return{success:!1,llmContent:"Invalid notebook format: no cells array found",displayContent:"Invalid notebook format",error:{type:"validation_error",message:"Invalid notebook format"}};let W=-1;if(Q){if(W=K.cells.findIndex((O)=>O.id===Q),W===-1&&G!=="insert")return{success:!1,llmContent:`Cell with ID "${Q}" not found`,displayContent:"Cell not found",error:{type:"validation_error",message:`Cell ID "${Q}" not found`}}}switch(G){case"replace":{if(W===-1)return{success:!1,llmContent:"Cell ID required for replace operation",displayContent:"Cell ID required",error:{type:"validation_error",message:"Cell ID required for replace"}};let O=K.cells[W];if(O.source=X.split(`
1040
1040
  `).map((F,H,_)=>H<_.length-1?F+`
1041
1041
  `:F),J)O.cell_type=J;break}case"insert":{if(!J)return{success:!1,llmContent:"cell_type is required for insert operation",displayContent:"cell_type required",error:{type:"validation_error",message:"cell_type required for insert"}};let O={cell_type:J,source:X.split(`
1042
1042
  `).map((H,_,z)=>_<z.length-1?H+`
1043
- `:H),metadata:{},...J==="code"?{execution_count:null,outputs:[]}:{}},F=W===-1?0:W+1;K.cells.splice(F,0,O);break}case"delete":{if(W===-1)return{success:!1,llmContent:"Cell ID required for delete operation",displayContent:"Cell ID required",error:{type:"validation_error",message:"Cell ID required for delete"}};K.cells.splice(W,1);break}}await $7.writeFile(Y,JSON.stringify(K,null,2));let U=G==="replace"?"replaced":G==="insert"?"inserted":"deleted";return{success:!0,llmContent:`Successfully ${U} cell in ${Y}`,displayContent:`Cell ${U} in notebook`,metadata:{notebook_path:Y,edit_mode:G,cell_id:Q}}}catch(q){let K=q instanceof Error?q.message:"Unknown error";return{success:!1,llmContent:`Failed to edit notebook: ${K}`,displayContent:"Notebook edit failed",error:{type:"execution_error",message:K}}}}})});var nJ=R(()=>{aJ()});import{z as mz}from"zod";var r9;var oJ=R(()=>{h0();R$();r9=e({name:"EnterPlanMode",displayName:"Enter Plan Mode",kind:"readonly",schema:mz.object({}),description:{short:"Use this tool to enter plan mode for complex tasks requiring careful planning",long:`Use this tool when you encounter a complex task that requires careful planning and exploration before implementation. This tool transitions you into plan mode where you can thoroughly explore the codebase and design an implementation approach.
1043
+ `:H),metadata:{},...J==="code"?{execution_count:null,outputs:[]}:{}},F=W===-1?0:W+1;K.cells.splice(F,0,O);break}case"delete":{if(W===-1)return{success:!1,llmContent:"Cell ID required for delete operation",displayContent:"Cell ID required",error:{type:"validation_error",message:"Cell ID required for delete"}};K.cells.splice(W,1);break}}await $6.writeFile(Y,JSON.stringify(K,null,2));let U=G==="replace"?"replaced":G==="insert"?"inserted":"deleted";return{success:!0,llmContent:`Successfully ${U} cell in ${Y}`,displayContent:`Cell ${U} in notebook`,metadata:{notebook_path:Y,edit_mode:G,cell_id:Q}}}catch(q){let K=q instanceof Error?q.message:"Unknown error";return{success:!1,llmContent:`Failed to edit notebook: ${K}`,displayContent:"Notebook edit failed",error:{type:"execution_error",message:K}}}}})});var nJ=R(()=>{aJ()});import{z as mz}from"zod";var r9;var oJ=R(()=>{h0();R$();r9=e({name:"EnterPlanMode",displayName:"Enter Plan Mode",kind:"readonly",schema:mz.object({}),description:{short:"Use this tool to enter plan mode for complex tasks requiring careful planning",long:`Use this tool when you encounter a complex task that requires careful planning and exploration before implementation. This tool transitions you into plan mode where you can thoroughly explore the codebase and design an implementation approach.
1044
1044
 
1045
1045
  ## When to Use This Tool
1046
1046
 
@@ -1182,13 +1182,13 @@ please reject and ask for a proper plan.`,details:"After approval, the assistant
1182
1182
  The agent has stopped and control is returned to the user. The user can now provide additional information or clarification.`,displayContent:"⚠️ 方案被拒绝,等待用户补充信息",metadata:{approved:!1,shouldExitLoop:!0,feedback:Q.feedback,awaitingUserInput:!0}}}catch(Q){return{success:!1,llmContent:`Confirmation flow error: ${Q instanceof Error?Q.message:"Unknown error"}`,displayContent:"❌ Confirmation failed",error:{type:"execution_error",message:"Confirmation flow error"}}}return{success:!0,llmContent:`✅ Plan mode exit requested. No interactive confirmation available.
1183
1183
  `+"Proceeding with implementation.",displayContent:"Plan mode exit (non-interactive)",metadata:{approved:null}}}})});var $G=R(()=>{oJ();eJ()});import{existsSync as uz,readFileSync as dz}from"node:fs";import{readFile as cz}from"node:fs/promises";import{dirname as lz,join as YG}from"node:path";import iz from"fast-glob";import{LRUCache as rz}from"lru-cache";import h3 from"picomatch";function az($){if(!uz($))return{patterns:[],negatePatterns:[]};try{let Z=dz($,"utf-8"),Y=[],Q=[];for(let X of Z.split(`
1184
1184
  `)){let J=X.trim();if(!J||J.startsWith("#"))continue;if(J.startsWith("!"))Q.push(J.slice(1));else Y.push(J)}return{patterns:Y,negatePatterns:Q}}catch(Z){return console.warn(`Failed to read .gitignore: ${Z}`),{patterns:[],negatePatterns:[]}}}async function nz($,Z){let Y=[...X1.map((K)=>`${K}/**`),...Z?.scanIgnore??[]],Q=`${$}|${Y.join(",")}`,X=ZG.get(Q);if(X)return X;let J=await iz("**/.gitignore",{cwd:$,dot:!0,onlyFiles:!0,followSymbolicLinks:!1,unique:!0,ignore:Y});J.sort((K,W)=>P3(K).length-P3(W).length);let G=[];for(let K of J){let W=lz(K).replace(/\\/g,"/"),U=W==="."?"":W,F=(await cz(YG($,K),"utf-8")).split(`
1185
- `);for(let H of F){let _=H.trim();if(!_||_.startsWith("#"))continue;let z=_.startsWith("!"),B=(z?_.slice(1):_).trim();if(!B)continue;let L="";if(B.startsWith("/")){let N=B.slice(1).replace(/\\/g,"/");if(L=(U?U+"/":"")+N,G.push({type:z?"negate":"ignore",pattern:L}),B.endsWith("/")){let M=L+"**";G.push({type:z?"negate":"ignore",pattern:M});let b=L.replace(/\/$/,"");if(b!==L)G.push({type:z?"negate":"ignore",pattern:b})}}else{let N=B.replace(/\\/g,"/");if(N.includes("/")){if(L=(U?U+"/":"")+N,G.push({type:z?"negate":"ignore",pattern:L}),N.endsWith("/")){let M=L+"**";G.push({type:z?"negate":"ignore",pattern:M});let b=L.replace(/\/$/,"");if(b!==L)G.push({type:z?"negate":"ignore",pattern:b})}}else L=(U?U+"/**/":"**/")+N,G.push({type:z?"negate":"ignore",pattern:L})}}}let q=Z?.cacheTTL??30000;return ZG.set(Q,G,{ttl:q}),G}class Z7{orderedRules=[];ignorePatterns=[];negatePatterns=[];constructor($={}){this.initialize($)}static async create($={}){let Z=new Z7({...$,useGitignore:!1}),{cwd:Y=process.cwd(),useGitignore:Q=!0,gitignoreScanMode:X="root",customScanIgnore:J=[],cacheTTL:G}=$;if(Q&&X==="recursive"){let q=await nz(Y,{scanIgnore:J,cacheTTL:G});for(let K of q)if(Z.orderedRules.push({type:K.type,matcher:h3(K.pattern,{dot:!0})}),K.type==="ignore")Z.ignorePatterns.push(K.pattern);else Z.negatePatterns.push(K.pattern)}return Z}initialize($){let{cwd:Z=process.cwd(),useGitignore:Y=!0,useDefaults:Q=!0,customPatterns:X=[]}=$,J=[],G=[];if(Q){let q=[...X1.map((K)=>`${K}/**`),...X1,...D8];J.push(...q);for(let K of q)this.orderedRules.push({type:"ignore",matcher:h3(K,{dot:!0})})}if(Y){let q=YG(Z,".gitignore"),{patterns:K,negatePatterns:W}=az(q);for(let U of K)this.orderedRules.push({type:"ignore",matcher:h3(U,{dot:!0})}),J.push(U);for(let U of W)this.orderedRules.push({type:"negate",matcher:h3(U,{dot:!0})}),G.push(U)}J.push(...X);for(let q of X)this.orderedRules.push({type:"ignore",matcher:h3(q,{dot:!0})});this.ignorePatterns=J,this.negatePatterns=G}shouldIgnore($){let Z=$.replace(/\\/g,"/"),Y=void 0;for(let Q of this.orderedRules)if(Q.matcher(Z))Y=Q.type==="ignore";return Y===!0}shouldIgnoreDirectory($){let Z=$.replace(/\\/g,"/");return this.shouldIgnore(Z)||this.shouldIgnore(`${Z}/`)}filter($){return $.filter((Z)=>!this.shouldIgnore(Z))}getIgnorePatterns(){return this.ignorePatterns}getNegatePatterns(){return this.negatePatterns}}var X1,D8,ZG;var x3=R(()=>{X1=["node_modules",".git","dist","build","out",".next",".nuxt",".cache",".parcel-cache","coverage",".nyc_output",".idea",".vscode",".vs","bower_components","jspm_packages"],D8=["*.log","npm-debug.log*","yarn-debug.log*","pnpm-debug.log*","*.lock","package-lock.json","yarn.lock","pnpm-lock.yaml","*.tmp","*.temp","*.swp","*.bak","*~",".DS_Store","Thumbs.db","*.pid","*.seed"];ZG=new rz({max:100,ttl:30000,updateAgeOnGet:!0})});import oz from"fast-glob";import{stat as sz}from"node:fs/promises";import{join as tz,resolve as ez}from"path";import{z as Y7}from"zod";function o9($){let Z=Error($);return Z.name="AbortError",Z}async function $B($,Z,Y,Q){let X=Q.getIgnorePatterns(),J=[],G=!1;return await new Promise((q,K)=>{if(Y.signal.aborted){K(o9("文件搜索被用户中止"));return}let W=oz.stream(Z,{cwd:$,dot:!0,followSymbolicLinks:!1,unique:!0,caseSensitiveMatch:Y.caseSensitive,objectMode:!0,stats:!0,onlyFiles:!Y.includeDirectories,ignore:X}),U=!1,O=null,F=()=>{if(O){if(Y.signal.removeEventListener)Y.signal.removeEventListener("abort",O);else if("onabort"in Y.signal)Y.signal.onabort=null;O=null}},H=()=>{if(!U)U=!0,G=!0,W.destroy(),F(),q({matches:J,wasTruncated:G})},_=(z)=>{if(Y.signal.aborted){if(!U)U=!0,W.destroy(o9("文件搜索被用户中止"));return}if(J.length>=Y.maxResults){H();return}let w=z.path.replace(/\\/g,"/"),B=tz($,w);if(Q.shouldIgnore(w))return;let L=z.stats?z.stats.isDirectory():!1;if(L&&Q.shouldIgnoreDirectory(w))return;let N=z.stats&&z.stats.isFile()?z.stats.size:void 0,M=z.stats?z.stats.mtime.toISOString():void 0;if(J.push({path:B,relative_path:w,is_directory:L,size:N,modified:M}),J.length>=Y.maxResults)H()};if(W.on("data",_),O=()=>{if(!U)U=!0,F(),W.destroy(o9("文件搜索被用户中止"))},Y.signal.addEventListener)Y.signal.addEventListener("abort",O);else if("onabort"in Y.signal)Y.signal.onabort=O;W.once("error",(z)=>{if(!U)U=!0,F(),K(z)}),W.once("end",()=>{if(!U)U=!0,F(),q({matches:J,wasTruncated:G})})})}function ZB($){return $.sort((Z,Y)=>{if(Z.is_directory!==Y.is_directory)return Z.is_directory?1:-1;if(Z.modified&&Y.modified)return new Date(Y.modified).getTime()-new Date(Z.modified).getTime();return Z.relative_path.localeCompare(Y.relative_path)})}function YB($){let{search_path:Z,pattern:Y,total_matches:Q,returned_matches:X,truncated:J}=$,G;if(J)G=`✅ 在 ${Z} 中找到至少 ${Q} 个匹配 "${Y}" 的文件(已截断)`,G+=`
1186
- \uD83D\uDCCB 显示前 ${X} 个结果`;else G=`✅ 在 ${Z} 中找到 ${Q} 个匹配 "${Y}" 的文件`;return G}var s9;var QG=R(()=>{x3();h0();j$();o2();s9=e({name:"Glob",displayName:"File Pattern Match",kind:"readonly",schema:Y7.object({pattern:a0.glob({description:"Glob pattern string (supports *, ?, ** wildcards)"}),path:Y7.string().optional().describe("Search path (optional, defaults to cwd)"),max_results:a0.positiveInt({description:"Maximum number of results"}).max(1000,"At most 1000 results can be returned").default(100),include_directories:Y7.boolean().default(!1).describe("Include directories in results"),case_sensitive:Y7.boolean().default(!1).describe("Case sensitive matching")}),description:{short:"Fast file pattern matching tool that works with any codebase size",long:'Fast file pattern matching tool that works with any codebase size. Supports glob patterns like "**/*.js" or "src/**/*.ts". Returns matching file paths sorted by modification time.',usageNotes:["Use this tool when you need to find files by name patterns","When you are doing an open ended search that may require multiple rounds of globbing and grepping, use the Agent tool instead","You can call multiple tools in a single response. It is always better to speculatively perform multiple searches in parallel if they are potentially useful."]},async execute($,Z){let{pattern:Y,path:Q=process.cwd(),max_results:X,include_directories:J,case_sensitive:G}=$,{updateOutput:q}=Z,K=Z.signal??new AbortController().signal;try{q?.(`Searching in ${Q} for pattern "${Y}"...`);let W=ez(Q);try{if(!(await sz(W)).isDirectory())return{success:!1,llmContent:`Search path must be a directory: ${W}`,displayContent:`❌ 搜索路径必须是目录: ${W}`,error:{type:"validation_error",message:"搜索路径必须是目录"}}}catch(B){if(B.code==="ENOENT")return{success:!1,llmContent:`Search path does not exist: ${W}`,displayContent:`❌ 搜索路径不存在: ${W}`,error:{type:"execution_error",message:"搜索路径不存在"}};throw B}K.throwIfAborted();let U=await Z7.create({cwd:W,useGitignore:!0,useDefaults:!0,gitignoreScanMode:"recursive",customScanIgnore:[],cacheTTL:30000}),{matches:O,wasTruncated:F}=await $B(W,Y,{maxResults:X,includeDirectories:J,caseSensitive:G,signal:K},U),H=ZB(O),_={search_path:W,pattern:Y,total_matches:O.length,returned_matches:O.length,max_results:X,include_directories:J,case_sensitive:G,truncated:F},z=YB(_),w;if(H.length>0)w=`${F?`Found at least ${H.length} file(s) matching "${Y}" (truncated)`:`Found ${H.length} file(s) matching "${Y}"`}:
1185
+ `);for(let H of F){let _=H.trim();if(!_||_.startsWith("#"))continue;let z=_.startsWith("!"),B=(z?_.slice(1):_).trim();if(!B)continue;let L="";if(B.startsWith("/")){let N=B.slice(1).replace(/\\/g,"/");if(L=(U?U+"/":"")+N,G.push({type:z?"negate":"ignore",pattern:L}),B.endsWith("/")){let M=L+"**";G.push({type:z?"negate":"ignore",pattern:M});let b=L.replace(/\/$/,"");if(b!==L)G.push({type:z?"negate":"ignore",pattern:b})}}else{let N=B.replace(/\\/g,"/");if(N.includes("/")){if(L=(U?U+"/":"")+N,G.push({type:z?"negate":"ignore",pattern:L}),N.endsWith("/")){let M=L+"**";G.push({type:z?"negate":"ignore",pattern:M});let b=L.replace(/\/$/,"");if(b!==L)G.push({type:z?"negate":"ignore",pattern:b})}}else L=(U?U+"/**/":"**/")+N,G.push({type:z?"negate":"ignore",pattern:L})}}}let q=Z?.cacheTTL??30000;return ZG.set(Q,G,{ttl:q}),G}class Z6{orderedRules=[];ignorePatterns=[];negatePatterns=[];constructor($={}){this.initialize($)}static async create($={}){let Z=new Z6({...$,useGitignore:!1}),{cwd:Y=process.cwd(),useGitignore:Q=!0,gitignoreScanMode:X="root",customScanIgnore:J=[],cacheTTL:G}=$;if(Q&&X==="recursive"){let q=await nz(Y,{scanIgnore:J,cacheTTL:G});for(let K of q)if(Z.orderedRules.push({type:K.type,matcher:h3(K.pattern,{dot:!0})}),K.type==="ignore")Z.ignorePatterns.push(K.pattern);else Z.negatePatterns.push(K.pattern)}return Z}initialize($){let{cwd:Z=process.cwd(),useGitignore:Y=!0,useDefaults:Q=!0,customPatterns:X=[]}=$,J=[],G=[];if(Q){let q=[...X1.map((K)=>`${K}/**`),...X1,...D8];J.push(...q);for(let K of q)this.orderedRules.push({type:"ignore",matcher:h3(K,{dot:!0})})}if(Y){let q=YG(Z,".gitignore"),{patterns:K,negatePatterns:W}=az(q);for(let U of K)this.orderedRules.push({type:"ignore",matcher:h3(U,{dot:!0})}),J.push(U);for(let U of W)this.orderedRules.push({type:"negate",matcher:h3(U,{dot:!0})}),G.push(U)}J.push(...X);for(let q of X)this.orderedRules.push({type:"ignore",matcher:h3(q,{dot:!0})});this.ignorePatterns=J,this.negatePatterns=G}shouldIgnore($){let Z=$.replace(/\\/g,"/"),Y=void 0;for(let Q of this.orderedRules)if(Q.matcher(Z))Y=Q.type==="ignore";return Y===!0}shouldIgnoreDirectory($){let Z=$.replace(/\\/g,"/");return this.shouldIgnore(Z)||this.shouldIgnore(`${Z}/`)}filter($){return $.filter((Z)=>!this.shouldIgnore(Z))}getIgnorePatterns(){return this.ignorePatterns}getNegatePatterns(){return this.negatePatterns}}var X1,D8,ZG;var x3=R(()=>{X1=["node_modules",".git","dist","build","out",".next",".nuxt",".cache",".parcel-cache","coverage",".nyc_output",".idea",".vscode",".vs","bower_components","jspm_packages"],D8=["*.log","npm-debug.log*","yarn-debug.log*","pnpm-debug.log*","*.lock","package-lock.json","yarn.lock","pnpm-lock.yaml","*.tmp","*.temp","*.swp","*.bak","*~",".DS_Store","Thumbs.db","*.pid","*.seed"];ZG=new rz({max:100,ttl:30000,updateAgeOnGet:!0})});import oz from"fast-glob";import{stat as sz}from"node:fs/promises";import{join as tz,resolve as ez}from"path";import{z as Y6}from"zod";function o9($){let Z=Error($);return Z.name="AbortError",Z}async function $B($,Z,Y,Q){let X=Q.getIgnorePatterns(),J=[],G=!1;return await new Promise((q,K)=>{if(Y.signal.aborted){K(o9("文件搜索被用户中止"));return}let W=oz.stream(Z,{cwd:$,dot:!0,followSymbolicLinks:!1,unique:!0,caseSensitiveMatch:Y.caseSensitive,objectMode:!0,stats:!0,onlyFiles:!Y.includeDirectories,ignore:X}),U=!1,O=null,F=()=>{if(O){if(Y.signal.removeEventListener)Y.signal.removeEventListener("abort",O);else if("onabort"in Y.signal)Y.signal.onabort=null;O=null}},H=()=>{if(!U)U=!0,G=!0,W.destroy(),F(),q({matches:J,wasTruncated:G})},_=(z)=>{if(Y.signal.aborted){if(!U)U=!0,W.destroy(o9("文件搜索被用户中止"));return}if(J.length>=Y.maxResults){H();return}let w=z.path.replace(/\\/g,"/"),B=tz($,w);if(Q.shouldIgnore(w))return;let L=z.stats?z.stats.isDirectory():!1;if(L&&Q.shouldIgnoreDirectory(w))return;let N=z.stats&&z.stats.isFile()?z.stats.size:void 0,M=z.stats?z.stats.mtime.toISOString():void 0;if(J.push({path:B,relative_path:w,is_directory:L,size:N,modified:M}),J.length>=Y.maxResults)H()};if(W.on("data",_),O=()=>{if(!U)U=!0,F(),W.destroy(o9("文件搜索被用户中止"))},Y.signal.addEventListener)Y.signal.addEventListener("abort",O);else if("onabort"in Y.signal)Y.signal.onabort=O;W.once("error",(z)=>{if(!U)U=!0,F(),K(z)}),W.once("end",()=>{if(!U)U=!0,F(),q({matches:J,wasTruncated:G})})})}function ZB($){return $.sort((Z,Y)=>{if(Z.is_directory!==Y.is_directory)return Z.is_directory?1:-1;if(Z.modified&&Y.modified)return new Date(Y.modified).getTime()-new Date(Z.modified).getTime();return Z.relative_path.localeCompare(Y.relative_path)})}function YB($){let{search_path:Z,pattern:Y,total_matches:Q,returned_matches:X,truncated:J}=$,G;if(J)G=`✅ 在 ${Z} 中找到至少 ${Q} 个匹配 "${Y}" 的文件(已截断)`,G+=`
1186
+ \uD83D\uDCCB 显示前 ${X} 个结果`;else G=`✅ 在 ${Z} 中找到 ${Q} 个匹配 "${Y}" 的文件`;return G}var s9;var QG=R(()=>{x3();h0();j$();o2();s9=e({name:"Glob",displayName:"File Pattern Match",kind:"readonly",schema:Y6.object({pattern:a0.glob({description:"Glob pattern string (supports *, ?, ** wildcards)"}),path:Y6.string().optional().describe("Search path (optional, defaults to cwd)"),max_results:a0.positiveInt({description:"Maximum number of results"}).max(1000,"At most 1000 results can be returned").default(100),include_directories:Y6.boolean().default(!1).describe("Include directories in results"),case_sensitive:Y6.boolean().default(!1).describe("Case sensitive matching")}),description:{short:"Fast file pattern matching tool that works with any codebase size",long:'Fast file pattern matching tool that works with any codebase size. Supports glob patterns like "**/*.js" or "src/**/*.ts". Returns matching file paths sorted by modification time.',usageNotes:["Use this tool when you need to find files by name patterns","When you are doing an open ended search that may require multiple rounds of globbing and grepping, use the Agent tool instead","You can call multiple tools in a single response. It is always better to speculatively perform multiple searches in parallel if they are potentially useful."]},async execute($,Z){let{pattern:Y,path:Q=process.cwd(),max_results:X,include_directories:J,case_sensitive:G}=$,{updateOutput:q}=Z,K=Z.signal??new AbortController().signal;try{q?.(`Searching in ${Q} for pattern "${Y}"...`);let W=ez(Q);try{if(!(await sz(W)).isDirectory())return{success:!1,llmContent:`Search path must be a directory: ${W}`,displayContent:`❌ 搜索路径必须是目录: ${W}`,error:{type:"validation_error",message:"搜索路径必须是目录"}}}catch(B){if(B.code==="ENOENT")return{success:!1,llmContent:`Search path does not exist: ${W}`,displayContent:`❌ 搜索路径不存在: ${W}`,error:{type:"execution_error",message:"搜索路径不存在"}};throw B}K.throwIfAborted();let U=await Z6.create({cwd:W,useGitignore:!0,useDefaults:!0,gitignoreScanMode:"recursive",customScanIgnore:[],cacheTTL:30000}),{matches:O,wasTruncated:F}=await $B(W,Y,{maxResults:X,includeDirectories:J,caseSensitive:G,signal:K},U),H=ZB(O),_={search_path:W,pattern:Y,total_matches:O.length,returned_matches:O.length,max_results:X,include_directories:J,case_sensitive:G,truncated:F},z=YB(_),w;if(H.length>0)w=`${F?`Found at least ${H.length} file(s) matching "${Y}" (truncated)`:`Found ${H.length} file(s) matching "${Y}"`}:
1187
1187
 
1188
1188
  `+H.map((L)=>`- ${L.relative_path}`).join(`
1189
1189
  `)+`
1190
1190
 
1191
- Use the relative_path values above for Read/Edit operations.`;else w=`No files found matching "${Y}"`;return{success:!0,llmContent:w,displayContent:z,metadata:{..._,matches:H}}}catch(W){let U=W;if(U.name==="AbortError")return{success:!1,llmContent:"File search aborted",displayContent:"⚠️ 文件搜索被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`Search failed: ${U.message}`,displayContent:`❌ 搜索失败: ${U.message}`,error:{type:"execution_error",message:U.message,details:U}}}},version:"2.0.0",category:"搜索工具",tags:["file","search","glob","pattern","wildcard"],extractSignatureContent:($)=>$.pattern,abstractPermissionRule:()=>"*"})});import{execSync as t9,spawn as e9}from"child_process";import{existsSync as Q7}from"fs";import{readdir as QB,readFile as XB}from"fs/promises";import{join as XG,relative as JB}from"path";import GB from"picomatch";import{z as s2}from"zod";function qB(){let{platform:$,arch:Z}=process,Y={"darwin-arm64":"darwin-arm64/rg","darwin-x64":"darwin-x64/rg","linux-arm64":"linux-arm64/rg","linux-x64":"linux-x64/rg","win32-x64":"win32-x64/rg.exe"},Q=`${$}-${Z}`,X=Y[Q];if(!X)return null;let J=XG(process.cwd(),"vendor","ripgrep",X);if(Q7(J))return J;try{let G=new URL("../../../../vendor/ripgrep/"+X,import.meta.url).pathname;if(Q7(G))return G}catch{}return null}function JG(){try{let Z=process.platform==="win32"?"where rg":"command -v rg 2>/dev/null || which rg 2>/dev/null",Y=t9(Z,{encoding:"utf8",stdio:["pipe","pipe","ignore"]}).split(/\r?\n/)[0].trim();if(Y)return Y}catch{}let $=qB();if($&&Q7($))return $;try{let Z=H$("@vscode/ripgrep");if(Z?.rgPath&&Q7(Z.rgPath))return Z.rgPath}catch{}return null}async function KB($){try{return t9("git rev-parse --git-dir",{cwd:$,stdio:"ignore"}),!0}catch{return!1}}function WB(){try{return t9("grep --version",{stdio:"ignore"}),!0}catch{return!1}}async function UB($,Z,Y,Q){let X=JG();if(!X)throw Error("ripgrep not available");return new Promise((J,G)=>{let q=e9(X,$,{stdio:["pipe","pipe","pipe"]}),K="",W="";q.stdout.on("data",(O)=>{K+=O.toString()}),q.stderr.on("data",(O)=>{W+=O.toString()}),q.on("close",(O)=>{J({stdout:K,stderr:W,exitCode:O||0})}),q.on("error",(O)=>{G(O)});let U=()=>{q.kill("SIGTERM"),G(Error("搜索被用户中止"))};Y.addEventListener("abort",U),q.on("close",()=>{Y.removeEventListener("abort",U)})})}async function OB($,Z,Y,Q){let X=["grep","-n"];if(Y.caseInsensitive)X.push("-i");if(Y.contextLines!==void 0)X.push(`-C${Y.contextLines}`);if(X.push("-e",$),Y.glob)X.push("--",Y.glob);return new Promise((J,G)=>{let q=e9("git",X,{cwd:Z,stdio:["pipe","pipe","pipe"]}),K="",W="";q.stdout.on("data",(O)=>{K+=O.toString()}),q.stderr.on("data",(O)=>{W+=O.toString()}),q.on("close",(O)=>{J({stdout:K,stderr:W,exitCode:O||0})}),q.on("error",(O)=>{G(O)});let U=()=>{q.kill("SIGTERM"),G(Error("搜索被用户中止"))};Q.addEventListener("abort",U),q.on("close",()=>{Q.removeEventListener("abort",U)})})}async function FB($,Z,Y,Q){let X=["-rn"];if(Y.caseInsensitive)X.push("-i");if(Y.contextLines!==void 0)X.push(`-C${Y.contextLines}`);for(let J of X1)X.push("--exclude-dir="+J.replace(/^\./,""));return X.push("-e",$,Z),new Promise((J,G)=>{let q=e9("grep",X,{stdio:["pipe","pipe","pipe"]}),K="",W="";q.stdout.on("data",(O)=>{K+=O.toString()}),q.stderr.on("data",(O)=>{W+=O.toString()}),q.on("close",(O)=>{J({stdout:K,stderr:W,exitCode:O||0})}),q.on("error",(O)=>{G(O)});let U=()=>{q.kill("SIGTERM"),G(Error("搜索被用户中止"))};Q.addEventListener("abort",U),q.on("close",()=>{Q.removeEventListener("abort",U)})})}async function HB($,Z,Y,Q){let X=[],J=new RegExp($,Y.caseInsensitive?"gi":"g"),G=await _B(Z,Q),q=0;for(let K of G){if(Q.throwIfAborted(),GG(K))continue;if(Y.glob&&!zB(K,Y.glob))continue;try{(await XB(K,"utf-8")).split(`
1191
+ Use the relative_path values above for Read/Edit operations.`;else w=`No files found matching "${Y}"`;return{success:!0,llmContent:w,displayContent:z,metadata:{..._,matches:H}}}catch(W){let U=W;if(U.name==="AbortError")return{success:!1,llmContent:"File search aborted",displayContent:"⚠️ 文件搜索被用户中止",error:{type:"execution_error",message:"操作被中止"}};return{success:!1,llmContent:`Search failed: ${U.message}`,displayContent:`❌ 搜索失败: ${U.message}`,error:{type:"execution_error",message:U.message,details:U}}}},version:"2.0.0",category:"搜索工具",tags:["file","search","glob","pattern","wildcard"],extractSignatureContent:($)=>$.pattern,abstractPermissionRule:()=>"*"})});import{execSync as t9,spawn as e9}from"child_process";import{existsSync as Q6}from"fs";import{readdir as QB,readFile as XB}from"fs/promises";import{join as XG,relative as JB}from"path";import GB from"picomatch";import{z as s2}from"zod";function qB(){let{platform:$,arch:Z}=process,Y={"darwin-arm64":"darwin-arm64/rg","darwin-x64":"darwin-x64/rg","linux-arm64":"linux-arm64/rg","linux-x64":"linux-x64/rg","win32-x64":"win32-x64/rg.exe"},Q=`${$}-${Z}`,X=Y[Q];if(!X)return null;let J=XG(process.cwd(),"vendor","ripgrep",X);if(Q6(J))return J;try{let G=new URL("../../../../vendor/ripgrep/"+X,import.meta.url).pathname;if(Q6(G))return G}catch{}return null}function JG(){try{let Z=process.platform==="win32"?"where rg":"command -v rg 2>/dev/null || which rg 2>/dev/null",Y=t9(Z,{encoding:"utf8",stdio:["pipe","pipe","ignore"]}).split(/\r?\n/)[0].trim();if(Y)return Y}catch{}let $=qB();if($&&Q6($))return $;try{let Z=H$("@vscode/ripgrep");if(Z?.rgPath&&Q6(Z.rgPath))return Z.rgPath}catch{}return null}async function KB($){try{return t9("git rev-parse --git-dir",{cwd:$,stdio:"ignore"}),!0}catch{return!1}}function WB(){try{return t9("grep --version",{stdio:"ignore"}),!0}catch{return!1}}async function UB($,Z,Y,Q){let X=JG();if(!X)throw Error("ripgrep not available");return new Promise((J,G)=>{let q=e9(X,$,{stdio:["pipe","pipe","pipe"]}),K="",W="";q.stdout.on("data",(O)=>{K+=O.toString()}),q.stderr.on("data",(O)=>{W+=O.toString()}),q.on("close",(O)=>{J({stdout:K,stderr:W,exitCode:O||0})}),q.on("error",(O)=>{G(O)});let U=()=>{q.kill("SIGTERM"),G(Error("搜索被用户中止"))};Y.addEventListener("abort",U),q.on("close",()=>{Y.removeEventListener("abort",U)})})}async function OB($,Z,Y,Q){let X=["grep","-n"];if(Y.caseInsensitive)X.push("-i");if(Y.contextLines!==void 0)X.push(`-C${Y.contextLines}`);if(X.push("-e",$),Y.glob)X.push("--",Y.glob);return new Promise((J,G)=>{let q=e9("git",X,{cwd:Z,stdio:["pipe","pipe","pipe"]}),K="",W="";q.stdout.on("data",(O)=>{K+=O.toString()}),q.stderr.on("data",(O)=>{W+=O.toString()}),q.on("close",(O)=>{J({stdout:K,stderr:W,exitCode:O||0})}),q.on("error",(O)=>{G(O)});let U=()=>{q.kill("SIGTERM"),G(Error("搜索被用户中止"))};Q.addEventListener("abort",U),q.on("close",()=>{Q.removeEventListener("abort",U)})})}async function FB($,Z,Y,Q){let X=["-rn"];if(Y.caseInsensitive)X.push("-i");if(Y.contextLines!==void 0)X.push(`-C${Y.contextLines}`);for(let J of X1)X.push("--exclude-dir="+J.replace(/^\./,""));return X.push("-e",$,Z),new Promise((J,G)=>{let q=e9("grep",X,{stdio:["pipe","pipe","pipe"]}),K="",W="";q.stdout.on("data",(O)=>{K+=O.toString()}),q.stderr.on("data",(O)=>{W+=O.toString()}),q.on("close",(O)=>{J({stdout:K,stderr:W,exitCode:O||0})}),q.on("error",(O)=>{G(O)});let U=()=>{q.kill("SIGTERM"),G(Error("搜索被用户中止"))};Q.addEventListener("abort",U),q.on("close",()=>{Q.removeEventListener("abort",U)})})}async function HB($,Z,Y,Q){let X=[],J=new RegExp($,Y.caseInsensitive?"gi":"g"),G=await _B(Z,Q),q=0;for(let K of G){if(Q.throwIfAborted(),GG(K))continue;if(Y.glob&&!zB(K,Y.glob))continue;try{(await XB(K,"utf-8")).split(`
1192
1192
  `).forEach((O,F)=>{if(J.test(O))X.push({file_path:JB(Z,K),line_number:F+1,content:O})}),q++}catch(W){continue}}return{matches:X,totalFiles:q}}async function _B($,Z){let Y=[];async function Q(X){Z.throwIfAborted();try{let J=await QB(X,{withFileTypes:!0});for(let G of J){Z.throwIfAborted();let q=XG(X,G.name);if(G.isDirectory()){if(!GG(q))await Q(q)}else if(G.isFile())Y.push(q)}}catch(J){}}return await Q($),Y}function GG($){for(let Z of X1)if($.includes(Z))return!0;return!1}function zB($,Z){return GB(Z)($)}function BB($){let Z=[];if($.case_insensitive)Z.push("-i");if($.multiline)Z.push("-U","--multiline-dotall");switch($.output_mode){case"files_with_matches":Z.push("-l");break;case"count":Z.push("-c");break;case"content":if($.line_numbers)Z.push("-n");break}if($.context!==void 0&&$.output_mode==="content")Z.push("-C",$.context.toString());else{if($.context_before!==void 0&&$.output_mode==="content")Z.push("-B",$.context_before.toString());if($.context_after!==void 0&&$.output_mode==="content")Z.push("-A",$.context_after.toString())}if($.type)Z.push("--type",$.type);for(let Y of X1)Z.push("--glob",`!${Y}/**`);if($.glob)Z.push("--glob",$.glob);if($.head_limit!==void 0){let Y=($.offset??0)+$.head_limit;Z.push("-m",Y.toString())}return Z.push($.pattern),Z.push($.path),Z}function wB($,Z){if(!$.trim())return[];let Y=$.trim().split(`
1193
1193
  `),Q=[];switch(Z){case"files_with_matches":return Y.map((X)=>({file_path:X.trim()}));case"count":return Y.map((X)=>{let[J,G]=X.split(":");return{file_path:J,count:parseInt(G,10)}});case"content":for(let X of Y){let J=LB(X);if(J)Q.push(J)}return Q;default:return[]}}function LB($){let Z=$.indexOf(":");if(Z===-1)return null;let Y=$.substring(0,Z),Q=$.substring(Z+1),X=Q.indexOf(":");if(X!==-1&&/^\d+$/.test(Q.substring(0,X))){let J=parseInt(Q.substring(0,X),10),G=Q.substring(X+1);return{file_path:Y,line_number:J,content:G}}else return{file_path:Y,content:Q}}function NB($){let{search_pattern:Z,search_path:Y,output_mode:Q,total_matches:X,strategy:J}=$,G=`✅ 在 ${Y} 中搜索 "${Z}"`;if(J)G+=`
1194
1194
  \uD83D\uDD27 使用策略: ${J}`;switch(Q){case"files_with_matches":G+=`
@@ -1212,7 +1212,7 @@ ${H}`}let U=Z.summarize&&Y?Y(J,Q):void 0;if(U)W+=`
1212
1212
  `).length} lines`);if(X.truncated)G.push(`stderr: ${X.originalLines} lines → ${X.content.split(`
1213
1213
  `).length} lines`);J=`Output truncated: ${G.join(", ")}`}return{stdout:Q.content,stderr:X.content,truncationInfo:J}}static shouldTruncate($,Z){let{config:Y}=this.getConfigForCommand(Z);return $.split(`
1214
1214
  `).length>Y.maxLines||$.length>Y.maxChars}static getStats($){return{lines:$.split(`
1215
- `).length,chars:$.length,words:$.split(/\s+/).filter(Boolean).length}}}var X7,h4,WG,RB,VB;var ZZ=R(()=>{X7={maxLines:30,maxChars:3000,keepHead:10,keepTail:10,summarize:!0},h4={maxLines:100,maxChars:1e4,keepHead:40,keepTail:40,summarize:!0},WG={maxLines:200,maxChars:20000,keepHead:80,keepTail:80,summarize:!1},RB={maxLines:150,maxChars:15000,keepHead:50,keepTail:50,summarize:!0},VB=[{pattern:/^git\s+(rm|add)\s+(-r|--cached|-rf|-f)?\s*/i,config:X7,summaryTemplate:($)=>`Successfully processed ${$} files`},{pattern:/^(npm|pnpm|yarn|bun)\s+(install|i|add|remove|uninstall)/i,config:X7,summaryTemplate:($)=>`Package operation completed (${$} lines of output)`},{pattern:/^(npm|pnpm|yarn|bun)\s+(run|exec)\s+(build|compile|bundle)/i,config:h4,summaryTemplate:($)=>`Build completed (${$} lines of output)`},{pattern:/^(npm|pnpm|yarn|bun)\s+(run|exec)\s+(test|lint|check)/i,config:WG},{pattern:/^git\s+(status|branch|remote)/i,config:h4},{pattern:/^git\s+(log|diff|show)/i,config:WG},{pattern:/^(ls|dir|tree)\s+/i,config:h4,summaryTemplate:($)=>`Listed ${$} items`},{pattern:/^find\s+/i,config:h4,summaryTemplate:($)=>`Found ${$} matches`},{pattern:/^(grep|rg|ag)\s+/i,config:h4,summaryTemplate:($)=>`Found ${$} matching lines`},{pattern:/^(docker|podman)\s+(build|pull|push)/i,config:X7,summaryTemplate:($)=>`Docker operation completed (${$} lines)`},{pattern:/^(pip|pip3|poetry|pipenv)\s+(install|uninstall)/i,config:X7,summaryTemplate:($)=>`Python package operation completed (${$} lines)`},{pattern:/^(cargo|rustup)\s+(build|install|update)/i,config:h4,summaryTemplate:($)=>`Rust operation completed (${$} lines)`},{pattern:/^(go)\s+(build|get|mod)/i,config:h4,summaryTemplate:($)=>`Go operation completed (${$} lines)`}]});import{spawn as MB}from"child_process";import{randomUUID as DB}from"crypto";import{z as YZ}from"zod";function jB($,Z,Y){let X=C$.getInstance().startBackgroundProcess({command:$,sessionId:DB(),cwd:Z||process.cwd(),env:Y}),G=`后台启动命令: ${$.length>30?`${$.substring(0,30)}...`:$}`,q={command:$,background:!0,pid:X.pid??0,bash_id:X.id,shell_id:X.id,message:"命令已在后台启动",summary:G},K=`✅ 命令已在后台启动
1215
+ `).length,chars:$.length,words:$.split(/\s+/).filter(Boolean).length}}}var X6,h4,WG,RB,VB;var ZZ=R(()=>{X6={maxLines:30,maxChars:3000,keepHead:10,keepTail:10,summarize:!0},h4={maxLines:100,maxChars:1e4,keepHead:40,keepTail:40,summarize:!0},WG={maxLines:200,maxChars:20000,keepHead:80,keepTail:80,summarize:!1},RB={maxLines:150,maxChars:15000,keepHead:50,keepTail:50,summarize:!0},VB=[{pattern:/^git\s+(rm|add)\s+(-r|--cached|-rf|-f)?\s*/i,config:X6,summaryTemplate:($)=>`Successfully processed ${$} files`},{pattern:/^(npm|pnpm|yarn|bun)\s+(install|i|add|remove|uninstall)/i,config:X6,summaryTemplate:($)=>`Package operation completed (${$} lines of output)`},{pattern:/^(npm|pnpm|yarn|bun)\s+(run|exec)\s+(build|compile|bundle)/i,config:h4,summaryTemplate:($)=>`Build completed (${$} lines of output)`},{pattern:/^(npm|pnpm|yarn|bun)\s+(run|exec)\s+(test|lint|check)/i,config:WG},{pattern:/^git\s+(status|branch|remote)/i,config:h4},{pattern:/^git\s+(log|diff|show)/i,config:WG},{pattern:/^(ls|dir|tree)\s+/i,config:h4,summaryTemplate:($)=>`Listed ${$} items`},{pattern:/^find\s+/i,config:h4,summaryTemplate:($)=>`Found ${$} matches`},{pattern:/^(grep|rg|ag)\s+/i,config:h4,summaryTemplate:($)=>`Found ${$} matching lines`},{pattern:/^(docker|podman)\s+(build|pull|push)/i,config:X6,summaryTemplate:($)=>`Docker operation completed (${$} lines)`},{pattern:/^(pip|pip3|poetry|pipenv)\s+(install|uninstall)/i,config:X6,summaryTemplate:($)=>`Python package operation completed (${$} lines)`},{pattern:/^(cargo|rustup)\s+(build|install|update)/i,config:h4,summaryTemplate:($)=>`Rust operation completed (${$} lines)`},{pattern:/^(go)\s+(build|get|mod)/i,config:h4,summaryTemplate:($)=>`Go operation completed (${$} lines)`}]});import{spawn as MB}from"child_process";import{randomUUID as DB}from"crypto";import{z as YZ}from"zod";function jB($,Z,Y){let X=C$.getInstance().startBackgroundProcess({command:$,sessionId:DB(),cwd:Z||process.cwd(),env:Y}),G=`后台启动命令: ${$.length>30?`${$.substring(0,30)}...`:$}`,q={command:$,background:!0,pid:X.pid??0,bash_id:X.id,shell_id:X.id,message:"命令已在后台启动",summary:G},K=`✅ 命令已在后台启动
1216
1216
  `+`\uD83C\uDD94 进程 ID: ${X.pid}
1217
1217
  `+`\uD83D\uDCA1 Bash ID: ${X.id}
1218
1218
  `+"⚠️ 使用 TaskOutput/KillShell 管理后台进程";return{success:!0,llmContent:{command:$,background:!0,pid:X.pid,bash_id:X.id,shell_id:X.id},displayContent:K,metadata:q}}async function yB($,Z,Y,Q,X,J){let G=Date.now();try{let K=await TJ().execute($,{cwd:Z||process.cwd(),env:Y,timeout:Q,signal:X,onOutput:(z)=>{J?.(z)}}),W=Date.now()-G;if(X.aborted||K.error==="Command was aborted"||K.error==="Command was terminated")return{success:!1,llmContent:"Command execution aborted by user",displayContent:`⚠️ 命令执行被用户中止
@@ -1562,12 +1562,12 @@ After adding tasks, try transitioning again.`,displayContent:"❌ No tasks defin
1562
1562
 
1563
1563
  Are you sure you want to mark this spec as done?`,details:`Completed: ${G.completed}/${G.total}`})).approved)return{success:!1,llmContent:"User cancelled transition to done phase.",displayContent:"⚠️ Transition cancelled",error:{type:"validation_error",message:"User cancelled"}}}}}try{let G=await Q.transitionPhase(Y);if(!G.success)return{success:!1,llmContent:G.message,displayContent:`❌ ${G.message}`,error:{type:"execution_error",message:G.error||"Transition failed"}};let q=I$[X.phase],K=I$[Y];return{success:!0,llmContent:`✅ Transitioned from "${q}" to "${K}"
1564
1564
 
1565
- `+EB(Y),displayContent:`✅ Phase: ${q} → ${K}`,metadata:{fromPhase:X.phase,toPhase:Y,featureName:X.name}}}catch(G){return{success:!1,llmContent:`Transition failed: ${G instanceof Error?G.message:"Unknown error"}`,displayContent:"❌ Transition failed",error:{type:"execution_error",message:G instanceof Error?G.message:"Transition error"}}}}})});import{z as J7}from"zod";function IB($,Z){let Y=["init","requirements","design","tasks","implementation"],X={proposal:"init",requirements:"requirements",design:"design",tasks:"tasks"}[$];if(!X)return"";let J=Y.indexOf(Z);if(Y.indexOf(X)>J)return`
1565
+ `+EB(Y),displayContent:`✅ Phase: ${q} → ${K}`,metadata:{fromPhase:X.phase,toPhase:Y,featureName:X.name}}}catch(G){return{success:!1,llmContent:`Transition failed: ${G instanceof Error?G.message:"Unknown error"}`,displayContent:"❌ Transition failed",error:{type:"execution_error",message:G instanceof Error?G.message:"Transition error"}}}}})});import{z as J6}from"zod";function IB($,Z){let Y=["init","requirements","design","tasks","implementation"],X={proposal:"init",requirements:"requirements",design:"design",tasks:"tasks"}[$];if(!X)return"";let J=Y.indexOf(Z);if(Y.indexOf(X)>J)return`
1566
1566
  \uD83D\uDCA1 Consider transitioning to "${X}" phase using TransitionSpecPhase tool.`;switch($){case"proposal":return`
1567
1567
  \uD83D\uDCDD Next: Define requirements in requirements.md using EARS format.`;case"requirements":return`
1568
1568
  \uD83D\uDCDD Next: Create technical design in design.md (diagrams, API contracts).`;case"design":return`
1569
1569
  \uD83D\uDCDD Next: Break down into tasks in tasks.md (atomic, with dependencies).`;case"tasks":return`
1570
- \uD83D\uDCDD Next: Start implementation. Update task status as you progress.`;default:return""}}var jG;var yG=R(()=>{j1();h0();R$();jG=e({name:"UpdateSpec",displayName:"Update Spec",kind:"write",schema:J7.object({fileType:J7.enum(["proposal","spec","requirements","design","tasks"]).describe("The type of spec file to update"),content:J7.string().min(1).describe("The content to write to the file"),append:J7.boolean().optional().default(!1).describe("If true, append to existing content instead of replacing")}),description:{short:"Update a spec file in the current Spec project",long:`Use this tool to update spec files in the current Spec-Driven Development project.
1570
+ \uD83D\uDCDD Next: Start implementation. Update task status as you progress.`;default:return""}}var jG;var yG=R(()=>{j1();h0();R$();jG=e({name:"UpdateSpec",displayName:"Update Spec",kind:"write",schema:J6.object({fileType:J6.enum(["proposal","spec","requirements","design","tasks"]).describe("The type of spec file to update"),content:J6.string().min(1).describe("The content to write to the file"),append:J6.boolean().optional().default(!1).describe("If true, append to existing content instead of replacing")}),description:{short:"Update a spec file in the current Spec project",long:`Use this tool to update spec files in the current Spec-Driven Development project.
1571
1571
 
1572
1572
  ## Available File Types
1573
1573
 
@@ -1607,7 +1607,7 @@ ${Q}`:Q}await q.writeSpecFile(G.name,Y,K);let W=K.split(`
1607
1607
 
1608
1608
  `+`\uD83D\uDCCA Stats: ${W} lines, ${U} characters
1609
1609
 
1610
- `+IB(Y,G.phase),displayContent:`✅ Updated ${Y}.md (${W} lines)`,metadata:{featureName:G.name,fileType:Y,lines:W,chars:U,append:X}}}catch(q){return{success:!1,llmContent:`Failed to update ${Y}.md: ${q instanceof Error?q.message:"Unknown error"}`,displayContent:`❌ Failed to update ${Y}.md`,error:{type:"execution_error",message:q instanceof Error?q.message:"Write error"}}}}})});import{z as G7}from"zod";var TG,EG;var IG=R(()=>{j1();h0();R$();TG={pending:"⏳ 待处理",in_progress:"\uD83D\uDD04 进行中",completed:"✅ 已完成",blocked:"\uD83D\uDEAB 已阻塞",skipped:"⏭️ 已跳过"},EG=e({name:"UpdateTaskStatus",displayName:"Update Task Status",kind:"write",schema:G7.object({taskId:G7.string().min(1).describe("The ID of the task to update"),status:G7.enum(["pending","in_progress","completed","blocked","skipped"]).describe("The new status for the task"),notes:G7.string().optional().describe("Optional notes about the status change (e.g., why blocked)")}),description:{short:"Update the status of a task in the current Spec",long:`Use this tool to update the status of tasks in the current Spec project.
1610
+ `+IB(Y,G.phase),displayContent:`✅ Updated ${Y}.md (${W} lines)`,metadata:{featureName:G.name,fileType:Y,lines:W,chars:U,append:X}}}catch(q){return{success:!1,llmContent:`Failed to update ${Y}.md: ${q instanceof Error?q.message:"Unknown error"}`,displayContent:`❌ Failed to update ${Y}.md`,error:{type:"execution_error",message:q instanceof Error?q.message:"Write error"}}}}})});import{z as G6}from"zod";var TG,EG;var IG=R(()=>{j1();h0();R$();TG={pending:"⏳ 待处理",in_progress:"\uD83D\uDD04 进行中",completed:"✅ 已完成",blocked:"\uD83D\uDEAB 已阻塞",skipped:"⏭️ 已跳过"},EG=e({name:"UpdateTaskStatus",displayName:"Update Task Status",kind:"write",schema:G6.object({taskId:G6.string().min(1).describe("The ID of the task to update"),status:G6.enum(["pending","in_progress","completed","blocked","skipped"]).describe("The new status for the task"),notes:G6.string().optional().describe("Optional notes about the status change (e.g., why blocked)")}),description:{short:"Update the status of a task in the current Spec",long:`Use this tool to update the status of tasks in the current Spec project.
1611
1611
 
1612
1612
  ## Task Statuses
1613
1613
 
@@ -1723,7 +1723,7 @@ ${W}
1723
1723
 
1724
1724
  `,X=Q.length,J=0;for(let G of Z){let q=this.getCommandLabel(G),K=G.config.argumentHint?` ${G.config.argumentHint}`:"",W=`- /${G.name}${K}: ${G.config.description} ${q}
1725
1725
  `;if(X+W.length>$)break;Q+=W,X+=W.length,J++}if(J<Y)Q+=`
1726
- (${J} of ${Y} commands shown due to character budget)`;return{text:Q,includedCount:J,totalCount:Y}}registerPluginCommand($){this.pluginCommands.set($.namespacedName,$)}findPluginCommand($){let Z=this.pluginCommands.get($);if(Z)return Z;let Y=[];for(let Q of this.pluginCommands.values())if(Q.originalName===$)Y.push(Q);if(Y.length===1)return Y[0];return}hasPluginCommand($){return this.findPluginCommand($)!==void 0}getAllPluginCommands(){return Array.from(this.pluginCommands.values())}async executePluginCommand($,Z){let Y=this.findPluginCommand($);if(!Y)return null;let Q={name:Y.namespacedName,config:Y.config,content:Y.content,path:Y.path,source:"project",sourceDir:"blade"};return this.executor.execute(Q,Z)}clearPluginCommands(){this.pluginCommands.clear()}getPluginCommandCount(){return this.pluginCommands.size}hasPluginCommandConflict($){let Z=0;for(let Y of this.pluginCommands.values())if(Y.originalName===$){if(Z++,Z>1)return!0}return!1}getPluginCommandProviders($){let Z=[];for(let Y of this.pluginCommands.values())if(Y.originalName===$)Z.push(Y.pluginName);return Z}}var zZ=R(()=>{pG();dG()});var q7=R(()=>{zZ()});import{z as BZ}from"zod";function mB(){let $=A$.getInstance();if(!$.isInitialized())return`
1726
+ (${J} of ${Y} commands shown due to character budget)`;return{text:Q,includedCount:J,totalCount:Y}}registerPluginCommand($){this.pluginCommands.set($.namespacedName,$)}findPluginCommand($){let Z=this.pluginCommands.get($);if(Z)return Z;let Y=[];for(let Q of this.pluginCommands.values())if(Q.originalName===$)Y.push(Q);if(Y.length===1)return Y[0];return}hasPluginCommand($){return this.findPluginCommand($)!==void 0}getAllPluginCommands(){return Array.from(this.pluginCommands.values())}async executePluginCommand($,Z){let Y=this.findPluginCommand($);if(!Y)return null;let Q={name:Y.namespacedName,config:Y.config,content:Y.content,path:Y.path,source:"project",sourceDir:"blade"};return this.executor.execute(Q,Z)}clearPluginCommands(){this.pluginCommands.clear()}getPluginCommandCount(){return this.pluginCommands.size}hasPluginCommandConflict($){let Z=0;for(let Y of this.pluginCommands.values())if(Y.originalName===$){if(Z++,Z>1)return!0}return!1}getPluginCommandProviders($){let Z=[];for(let Y of this.pluginCommands.values())if(Y.originalName===$)Z.push(Y.pluginName);return Z}}var zZ=R(()=>{pG();dG()});var q6=R(()=>{zZ()});import{z as BZ}from"zod";function mB(){let $=A$.getInstance();if(!$.isInitialized())return`
1727
1727
  (Custom commands not yet initialized)`;let{text:Z,totalCount:Y}=$.generateCommandListDescription(pB);if(Y===0)return`
1728
1728
  (No custom commands available)`;return`
1729
1729
 
@@ -1744,7 +1744,7 @@ ${Z}
1744
1744
 
1745
1745
  ---
1746
1746
 
1747
- Remember: Follow the above instructions carefully to complete the user's request.`,Q}var pB,wZ;var cG=R(()=>{q7();h0();R$();pB=Number.parseInt(process.env.SLASH_COMMAND_TOOL_CHAR_BUDGET||"15000",10);wZ=e({name:"SlashCommand",displayName:"Slash Command",kind:"execute",schema:BZ.object({command:BZ.string().describe('The command name without the leading slash, e.g., "review-pr" or "commit"'),arguments:BZ.string().optional().describe('Arguments to pass to the command, e.g., "123" or "fix bug"')}),description:{short:"Execute a custom slash command within the main conversation",long:`Execute a custom slash command within the main conversation
1747
+ Remember: Follow the above instructions carefully to complete the user's request.`,Q}var pB,wZ;var cG=R(()=>{q6();h0();R$();pB=Number.parseInt(process.env.SLASH_COMMAND_TOOL_CHAR_BUDGET||"15000",10);wZ=e({name:"SlashCommand",displayName:"Slash Command",kind:"execute",schema:BZ.object({command:BZ.string().describe('The command name without the leading slash, e.g., "review-pr" or "commit"'),arguments:BZ.string().optional().describe('Arguments to pass to the command, e.g., "123" or "fix bug"')}),description:{short:"Execute a custom slash command within the main conversation",long:`Execute a custom slash command within the main conversation
1748
1748
 
1749
1749
  How slash commands work:
1750
1750
  When you use this tool, the command's content (from .blade/commands/ or .claude/commands/) will be processed and returned. The content may include:
@@ -1767,7 +1767,7 @@ Notes:
1767
1767
  - Only custom slash commands with descriptions are listed in Available Commands
1768
1768
  - Commands with \`disable-model-invocation: true\` cannot be invoked by this tool
1769
1769
  - If a command is not listed, ask the user to check the slash command file
1770
- ${mB()}`},async execute($,Z){let{command:Y,arguments:Q}=$,X=A$.getInstance();if(!X.isInitialized())return{success:!1,llmContent:"Custom command system not initialized. Please wait for the application to fully initialize.",displayContent:"❌ Custom command system not initialized",error:{type:"execution_error",message:"CustomCommandRegistry not initialized"}};let J=X.getCommand(Y);if(!J){let q=X.getModelInvocableCommands().map((K)=>`/${K.name}`).join(", ");return{success:!1,llmContent:`Command "/${Y}" not found. Available commands: ${q||"none"}`,displayContent:`❌ Command "/${Y}" not found`,error:{type:"validation_error",message:`Command "/${Y}" is not registered`}}}if(J.config.disableModelInvocation)return{success:!1,llmContent:`Command "/${Y}" has disabled model invocation. This command can only be executed by the user directly.`,displayContent:`❌ Command "/${Y}" disabled for AI`,error:{type:"permission_denied",message:`Command "/${Y}" has disable-model-invocation: true`}};if(!J.config.description)return{success:!1,llmContent:`Command "/${Y}" does not have a description and cannot be invoked by AI. Add a description in the command's frontmatter to enable AI invocation.`,displayContent:`❌ Command "/${Y}" has no description`,error:{type:"validation_error",message:`Command "/${Y}" missing description for AI invocation`}};let G=Q?Q.split(/\s+/).filter(Boolean):[];try{let q=await X.executeCommand(Y,{args:G,workspaceRoot:process.cwd()});if(!q)return{success:!1,llmContent:`Failed to execute command "/${Y}"`,displayContent:`❌ Failed to execute "/${Y}"`,error:{type:"execution_error",message:"Command execution returned null"}};return{success:!0,llmContent:gB(J.name,q,J.config),displayContent:`<command-message>/${Y} is running...</command-message>`,metadata:{commandName:Y,allowedTools:J.config.allowedTools,model:J.config.model,source:J.source,namespace:J.namespace}}}catch(q){let K=q instanceof Error?q.message:String(q);return{success:!1,llmContent:`Error executing command "/${Y}": ${K}`,displayContent:`❌ Error executing "/${Y}"`,error:{type:"execution_error",message:K}}}}})});var lG=R(()=>{kG();fG();cG()});import e2 from"node:fs";import uB from"node:os";import iG from"node:path";class x4{static instance=null;sessionsDir;cache=new Map;constructor(){this.sessionsDir=iG.join(uB.homedir(),".blade","agents","sessions"),this.ensureDirectory()}static getInstance(){if(!x4.instance)x4.instance=new x4;return x4.instance}ensureDirectory(){if(!e2.existsSync(this.sessionsDir))e2.mkdirSync(this.sessionsDir,{recursive:!0,mode:493})}getSessionPath($){let Z=$.replace(/[^a-zA-Z0-9_-]/g,"_");return iG.join(this.sessionsDir,`${Z}.json`)}saveSession($){try{let Z=this.getSessionPath($.id),Y=JSON.stringify($,null,2);e2.writeFileSync(Z,Y,"utf-8"),this.cache.set($.id,$),y8.debug(`Session saved: ${$.id}`)}catch(Z){y8.warn(`Failed to save session ${$.id}:`,Z)}}loadSession($){if(this.cache.has($))return this.cache.get($);try{let Z=this.getSessionPath($);if(!e2.existsSync(Z))return;let Y=e2.readFileSync(Z,"utf-8"),Q=JSON.parse(Y);return this.cache.set($,Q),Q}catch(Z){y8.warn(`Failed to load session ${$}:`,Z);return}}updateSession($,Z){let Y=this.loadSession($);if(!Y)return;let Q={...Y,...Z,lastActiveAt:Date.now()};return this.saveSession(Q),Q}appendMessages($,Z){let Y=this.loadSession($);if(!Y)return;return this.updateSession($,{messages:[...Y.messages,...Z]})}markCompleted($,Z,Y){return this.updateSession($,{status:Z.success?"completed":"failed",result:Z,stats:Y,completedAt:Date.now()})}deleteSession($){try{let Z=this.getSessionPath($);if(e2.existsSync(Z))e2.unlinkSync(Z);return this.cache.delete($),!0}catch(Z){return y8.warn(`Failed to delete session ${$}:`,Z),!1}}listSessions(){try{let $=e2.readdirSync(this.sessionsDir),Z=[];for(let Y of $){if(!Y.endsWith(".json"))continue;let Q=Y.replace(".json",""),X=this.loadSession(Q);if(X)Z.push(X)}return Z.sort((Y,Q)=>Q.lastActiveAt-Y.lastActiveAt)}catch($){return y8.warn("Failed to list sessions:",$),[]}}listRunningSessions(){return this.listSessions().filter(($)=>$.status==="running")}cleanupExpiredSessions($=604800000){let Z=Date.now(),Y=this.listSessions(),Q=0;for(let X of Y){if(X.status==="running")continue;if(Z-X.lastActiveAt>$){if(this.deleteSession(X.id))Q++}}if(Q>0)y8.info(`Cleaned up ${Q} expired agent sessions`);return Q}clearCache(){this.cache.clear()}}var y8;var rG=R(()=>{Q0();y8=x("Agent")});import{nanoid as dB}from"nanoid";class F1{static instance=null;runningAgents=new Map;sessionStore=x4.getInstance();constructor(){this.cleanupOrphanedSessions()}static getInstance(){if(!F1.instance)F1.instance=new F1;return F1.instance}cleanupOrphanedSessions(){let $=this.sessionStore.listSessions(),Z=Date.now(),Y=1800000;for(let Q of $)if(Q.status==="running"){let X=this.runningAgents.has(Q.id),J=Z-Q.lastActiveAt;if(!X||J>1800000)p4.warn(`Cleaning up orphaned agent session: ${Q.id}`),this.sessionStore.updateSession(Q.id,{status:"failed",result:{success:!1,message:"",error:"Session was orphaned (process restart or timeout)"},completedAt:Z})}}startBackgroundAgent($){let{config:Z,description:Y,prompt:Q,parentSessionId:X,permissionMode:J,agentId:G,existingMessages:q}=$,K=G||dB(),W=new AbortController,U={id:K,subagentType:Z.name,description:Y,prompt:Q,messages:q||[],status:"running",createdAt:Date.now(),lastActiveAt:Date.now(),parentSessionId:X};this.sessionStore.saveSession(U);let O=Date.now(),F=this.executeAgent(K,Z,Q,X,J,W.signal,q);return this.runningAgents.set(K,{id:K,promise:F,abortController:W,startTime:O}),F.finally(()=>{this.runningAgents.delete(K)}),p4.info(`Background agent started: ${K} (${Z.name})`),K}async executeAgent($,Z,Y,Q,X,J,G){let q=Date.now();try{if(J.aborted)throw Error("Agent execution was cancelled");let K=Z.systemPrompt||"",W=Z.model&&Z.model!=="inherit"?Z.model:void 0,U=await G$.create({systemPrompt:K,toolWhitelist:Z.tools,modelId:W}),O={messages:G||[],userId:"subagent",sessionId:$,workspaceRoot:process.cwd(),permissionMode:X,subagentInfo:{parentSessionId:Q||"",subagentType:Z.name,isSidechain:!1}},F=await U.runAgenticLoop(Y,O,{signal:J});this.sessionStore.updateSession($,{messages:O.messages});let H=Date.now()-q,_=F.success?{success:!0,message:F.finalMessage||"",agentId:$,stats:{tokens:F.metadata?.tokensUsed||0,toolCalls:F.metadata?.toolCallsCount||0,duration:H}}:{success:!1,message:"",agentId:$,error:F.error?.message||"Unknown error",stats:{duration:H}};return this.sessionStore.markCompleted($,{success:_.success,message:_.message,error:_.error},_.stats),p4.info(`Background agent completed: ${$} (success=${_.success})`),_}catch(K){let W=Date.now()-q,U=K instanceof Error?K.message:String(K);return this.sessionStore.markCompleted($,{success:!1,message:"",error:U},{duration:W}),p4.warn(`Background agent failed: ${$}`,K),{success:!1,message:"",agentId:$,error:U,stats:{duration:W}}}}getAgent($){return this.sessionStore.loadSession($)}isRunning($){return this.runningAgents.has($)}async waitForCompletion($,Z=30000){let Y=this.runningAgents.get($);if(!Y)return this.sessionStore.loadSession($);if(Z>0){let Q=new Promise((J)=>setTimeout(()=>J("timeout"),Z));if(await Promise.race([Y.promise,Q])==="timeout")return this.sessionStore.loadSession($)}else await Y.promise;return this.sessionStore.loadSession($)}resumeAgent($,Z,Y,Q,X){let J=this.sessionStore.loadSession($);if(!J){p4.warn(`Cannot resume agent ${$}: session not found`);return}if(this.isRunning($)){p4.warn(`Cannot resume agent ${$}: still running`);return}return this.startBackgroundAgent({config:Y,description:J.description,prompt:Z,parentSessionId:Q||J.parentSessionId,permissionMode:X,agentId:$,existingMessages:J.messages})}killAgent($){let Z=this.runningAgents.get($);if(!Z){let Y=this.sessionStore.loadSession($);if(Y&&Y.status==="running")this.sessionStore.updateSession($,{status:"cancelled"});return!1}return Z.abortController.abort(),this.sessionStore.updateSession($,{status:"cancelled"}),p4.info(`Background agent cancelled: ${$}`),!0}listAll(){return this.sessionStore.listSessions()}listRunning(){return this.sessionStore.listRunningSessions()}getRunningCount(){return this.runningAgents.size}killAll(){for(let[$]of this.runningAgents)this.killAgent($)}cleanupExpiredSessions($){return this.sessionStore.cleanupExpiredSessions($)}}var p4;var K7=R(()=>{Q0();F2();rG();p4=x("Agent")});import{nanoid as cB}from"nanoid";class LZ{config;constructor($){this.config=$}async execute($){let Z=Date.now(),Y=$.subagentSessionId??cB();try{let Q=this.buildSystemPrompt($),X=this.config.model&&this.config.model!=="inherit"?this.config.model:void 0,J=await G$.create({toolWhitelist:this.config.tools,modelId:X}),G="",q=0,K=0,W={parentSessionId:$.parentSessionId||"",subagentType:this.config.name,isSidechain:!1},U=await J.runAgenticLoop($.prompt,{messages:[],userId:"subagent",sessionId:Y,workspaceRoot:process.cwd(),permissionMode:$.permissionMode,systemPrompt:Q,subagentInfo:W},{onToolStart:$.onToolStart,onToolResult:$.onToolResult?async(F,H)=>{$.onToolResult?.(F,H)}:void 0,onContentDelta:$.onContentDelta,onThinkingDelta:$.onThinkingDelta,onStreamEnd:$.onStreamEnd});if(U.success)G=U.finalMessage||"",q=U.metadata?.toolCallsCount||0,K=U.metadata?.tokensUsed||0;else throw Error(U.error?.message||"Subagent execution failed");let O=Date.now()-Z;return{success:!0,message:G,agentId:Y,stats:{tokens:K,toolCalls:q,duration:O}}}catch(Q){let X=Date.now()-Z;return{success:!1,message:"",agentId:Y,error:Q instanceof Error?Q.message:String(Q),stats:{duration:X}}}}buildSystemPrompt($){return this.config.systemPrompt||""}}var aG=R(()=>{F2()});var NZ;var nG=R(()=>{NZ=[{name:"general-purpose",description:"General-purpose agent for researching complex questions, searching for code, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries use this agent to perform the search for you.",tools:[]},{name:"Explore",description:'Fast agent specialized for exploring codebases. Use this when you need to quickly find files by patterns (eg. "src/components/**/*.tsx"), search code for keywords (eg. "API endpoints"), or answer questions about the codebase (eg. "how do API endpoints work?"). When calling this agent, specify the desired thoroughness level: "quick" for basic searches, "medium" for moderate exploration, or "very thorough" for comprehensive analysis across multiple locations and naming conventions.',tools:["Glob","Grep","Read","WebFetch","WebSearch"],systemPrompt:`# Explore Subagent
1770
+ ${mB()}`},async execute($,Z){let{command:Y,arguments:Q}=$,X=A$.getInstance();if(!X.isInitialized())return{success:!1,llmContent:"Custom command system not initialized. Please wait for the application to fully initialize.",displayContent:"❌ Custom command system not initialized",error:{type:"execution_error",message:"CustomCommandRegistry not initialized"}};let J=X.getCommand(Y);if(!J){let q=X.getModelInvocableCommands().map((K)=>`/${K.name}`).join(", ");return{success:!1,llmContent:`Command "/${Y}" not found. Available commands: ${q||"none"}`,displayContent:`❌ Command "/${Y}" not found`,error:{type:"validation_error",message:`Command "/${Y}" is not registered`}}}if(J.config.disableModelInvocation)return{success:!1,llmContent:`Command "/${Y}" has disabled model invocation. This command can only be executed by the user directly.`,displayContent:`❌ Command "/${Y}" disabled for AI`,error:{type:"permission_denied",message:`Command "/${Y}" has disable-model-invocation: true`}};if(!J.config.description)return{success:!1,llmContent:`Command "/${Y}" does not have a description and cannot be invoked by AI. Add a description in the command's frontmatter to enable AI invocation.`,displayContent:`❌ Command "/${Y}" has no description`,error:{type:"validation_error",message:`Command "/${Y}" missing description for AI invocation`}};let G=Q?Q.split(/\s+/).filter(Boolean):[];try{let q=await X.executeCommand(Y,{args:G,workspaceRoot:process.cwd()});if(!q)return{success:!1,llmContent:`Failed to execute command "/${Y}"`,displayContent:`❌ Failed to execute "/${Y}"`,error:{type:"execution_error",message:"Command execution returned null"}};return{success:!0,llmContent:gB(J.name,q,J.config),displayContent:`<command-message>/${Y} is running...</command-message>`,metadata:{commandName:Y,allowedTools:J.config.allowedTools,model:J.config.model,source:J.source,namespace:J.namespace}}}catch(q){let K=q instanceof Error?q.message:String(q);return{success:!1,llmContent:`Error executing command "/${Y}": ${K}`,displayContent:`❌ Error executing "/${Y}"`,error:{type:"execution_error",message:K}}}}})});var lG=R(()=>{kG();fG();cG()});import e2 from"node:fs";import uB from"node:os";import iG from"node:path";class x4{static instance=null;sessionsDir;cache=new Map;constructor(){this.sessionsDir=iG.join(uB.homedir(),".blade","agents","sessions"),this.ensureDirectory()}static getInstance(){if(!x4.instance)x4.instance=new x4;return x4.instance}ensureDirectory(){if(!e2.existsSync(this.sessionsDir))e2.mkdirSync(this.sessionsDir,{recursive:!0,mode:493})}getSessionPath($){let Z=$.replace(/[^a-zA-Z0-9_-]/g,"_");return iG.join(this.sessionsDir,`${Z}.json`)}saveSession($){try{let Z=this.getSessionPath($.id),Y=JSON.stringify($,null,2);e2.writeFileSync(Z,Y,"utf-8"),this.cache.set($.id,$),y8.debug(`Session saved: ${$.id}`)}catch(Z){y8.warn(`Failed to save session ${$.id}:`,Z)}}loadSession($){if(this.cache.has($))return this.cache.get($);try{let Z=this.getSessionPath($);if(!e2.existsSync(Z))return;let Y=e2.readFileSync(Z,"utf-8"),Q=JSON.parse(Y);return this.cache.set($,Q),Q}catch(Z){y8.warn(`Failed to load session ${$}:`,Z);return}}updateSession($,Z){let Y=this.loadSession($);if(!Y)return;let Q={...Y,...Z,lastActiveAt:Date.now()};return this.saveSession(Q),Q}appendMessages($,Z){let Y=this.loadSession($);if(!Y)return;return this.updateSession($,{messages:[...Y.messages,...Z]})}markCompleted($,Z,Y){return this.updateSession($,{status:Z.success?"completed":"failed",result:Z,stats:Y,completedAt:Date.now()})}deleteSession($){try{let Z=this.getSessionPath($);if(e2.existsSync(Z))e2.unlinkSync(Z);return this.cache.delete($),!0}catch(Z){return y8.warn(`Failed to delete session ${$}:`,Z),!1}}listSessions(){try{let $=e2.readdirSync(this.sessionsDir),Z=[];for(let Y of $){if(!Y.endsWith(".json"))continue;let Q=Y.replace(".json",""),X=this.loadSession(Q);if(X)Z.push(X)}return Z.sort((Y,Q)=>Q.lastActiveAt-Y.lastActiveAt)}catch($){return y8.warn("Failed to list sessions:",$),[]}}listRunningSessions(){return this.listSessions().filter(($)=>$.status==="running")}cleanupExpiredSessions($=604800000){let Z=Date.now(),Y=this.listSessions(),Q=0;for(let X of Y){if(X.status==="running")continue;if(Z-X.lastActiveAt>$){if(this.deleteSession(X.id))Q++}}if(Q>0)y8.info(`Cleaned up ${Q} expired agent sessions`);return Q}clearCache(){this.cache.clear()}}var y8;var rG=R(()=>{Q0();y8=x("Agent")});import{nanoid as dB}from"nanoid";class F1{static instance=null;runningAgents=new Map;sessionStore=x4.getInstance();constructor(){this.cleanupOrphanedSessions()}static getInstance(){if(!F1.instance)F1.instance=new F1;return F1.instance}cleanupOrphanedSessions(){let $=this.sessionStore.listSessions(),Z=Date.now(),Y=1800000;for(let Q of $)if(Q.status==="running"){let X=this.runningAgents.has(Q.id),J=Z-Q.lastActiveAt;if(!X||J>1800000)p4.warn(`Cleaning up orphaned agent session: ${Q.id}`),this.sessionStore.updateSession(Q.id,{status:"failed",result:{success:!1,message:"",error:"Session was orphaned (process restart or timeout)"},completedAt:Z})}}startBackgroundAgent($){let{config:Z,description:Y,prompt:Q,parentSessionId:X,permissionMode:J,agentId:G,existingMessages:q}=$,K=G||dB(),W=new AbortController,U={id:K,subagentType:Z.name,description:Y,prompt:Q,messages:q||[],status:"running",createdAt:Date.now(),lastActiveAt:Date.now(),parentSessionId:X};this.sessionStore.saveSession(U);let O=Date.now(),F=this.executeAgent(K,Z,Q,X,J,W.signal,q);return this.runningAgents.set(K,{id:K,promise:F,abortController:W,startTime:O}),F.finally(()=>{this.runningAgents.delete(K)}),p4.info(`Background agent started: ${K} (${Z.name})`),K}async executeAgent($,Z,Y,Q,X,J,G){let q=Date.now();try{if(J.aborted)throw Error("Agent execution was cancelled");let K=Z.systemPrompt||"",W=Z.model&&Z.model!=="inherit"?Z.model:void 0,U=await G$.create({systemPrompt:K,toolWhitelist:Z.tools,modelId:W}),O={messages:G||[],userId:"subagent",sessionId:$,workspaceRoot:process.cwd(),permissionMode:X,subagentInfo:{parentSessionId:Q||"",subagentType:Z.name,isSidechain:!1}},F=await U.runAgenticLoop(Y,O,{signal:J});this.sessionStore.updateSession($,{messages:O.messages});let H=Date.now()-q,_=F.success?{success:!0,message:F.finalMessage||"",agentId:$,stats:{tokens:F.metadata?.tokensUsed||0,toolCalls:F.metadata?.toolCallsCount||0,duration:H}}:{success:!1,message:"",agentId:$,error:F.error?.message||"Unknown error",stats:{duration:H}};return this.sessionStore.markCompleted($,{success:_.success,message:_.message,error:_.error},_.stats),p4.info(`Background agent completed: ${$} (success=${_.success})`),_}catch(K){let W=Date.now()-q,U=K instanceof Error?K.message:String(K);return this.sessionStore.markCompleted($,{success:!1,message:"",error:U},{duration:W}),p4.warn(`Background agent failed: ${$}`,K),{success:!1,message:"",agentId:$,error:U,stats:{duration:W}}}}getAgent($){return this.sessionStore.loadSession($)}isRunning($){return this.runningAgents.has($)}async waitForCompletion($,Z=30000){let Y=this.runningAgents.get($);if(!Y)return this.sessionStore.loadSession($);if(Z>0){let Q=new Promise((J)=>setTimeout(()=>J("timeout"),Z));if(await Promise.race([Y.promise,Q])==="timeout")return this.sessionStore.loadSession($)}else await Y.promise;return this.sessionStore.loadSession($)}resumeAgent($,Z,Y,Q,X){let J=this.sessionStore.loadSession($);if(!J){p4.warn(`Cannot resume agent ${$}: session not found`);return}if(this.isRunning($)){p4.warn(`Cannot resume agent ${$}: still running`);return}return this.startBackgroundAgent({config:Y,description:J.description,prompt:Z,parentSessionId:Q||J.parentSessionId,permissionMode:X,agentId:$,existingMessages:J.messages})}killAgent($){let Z=this.runningAgents.get($);if(!Z){let Y=this.sessionStore.loadSession($);if(Y&&Y.status==="running")this.sessionStore.updateSession($,{status:"cancelled"});return!1}return Z.abortController.abort(),this.sessionStore.updateSession($,{status:"cancelled"}),p4.info(`Background agent cancelled: ${$}`),!0}listAll(){return this.sessionStore.listSessions()}listRunning(){return this.sessionStore.listRunningSessions()}getRunningCount(){return this.runningAgents.size}killAll(){for(let[$]of this.runningAgents)this.killAgent($)}cleanupExpiredSessions($){return this.sessionStore.cleanupExpiredSessions($)}}var p4;var K6=R(()=>{Q0();F2();rG();p4=x("Agent")});import{nanoid as cB}from"nanoid";class LZ{config;constructor($){this.config=$}async execute($){let Z=Date.now(),Y=$.subagentSessionId??cB();try{let Q=this.buildSystemPrompt($),X=this.config.model&&this.config.model!=="inherit"?this.config.model:void 0,J=await G$.create({toolWhitelist:this.config.tools,modelId:X}),G="",q=0,K=0,W={parentSessionId:$.parentSessionId||"",subagentType:this.config.name,isSidechain:!1},U=await J.runAgenticLoop($.prompt,{messages:[],userId:"subagent",sessionId:Y,workspaceRoot:process.cwd(),permissionMode:$.permissionMode,systemPrompt:Q,subagentInfo:W},{onToolStart:$.onToolStart,onToolResult:$.onToolResult?async(F,H)=>{$.onToolResult?.(F,H)}:void 0,onContentDelta:$.onContentDelta,onThinkingDelta:$.onThinkingDelta,onStreamEnd:$.onStreamEnd});if(U.success)G=U.finalMessage||"",q=U.metadata?.toolCallsCount||0,K=U.metadata?.tokensUsed||0;else throw Error(U.error?.message||"Subagent execution failed");let O=Date.now()-Z;return{success:!0,message:G,agentId:Y,stats:{tokens:K,toolCalls:q,duration:O}}}catch(Q){let X=Date.now()-Z;return{success:!1,message:"",agentId:Y,error:Q instanceof Error?Q.message:String(Q),stats:{duration:X}}}}buildSystemPrompt($){return this.config.systemPrompt||""}}var aG=R(()=>{F2()});var NZ;var nG=R(()=>{NZ=[{name:"general-purpose",description:"General-purpose agent for researching complex questions, searching for code, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries use this agent to perform the search for you.",tools:[]},{name:"Explore",description:'Fast agent specialized for exploring codebases. Use this when you need to quickly find files by patterns (eg. "src/components/**/*.tsx"), search code for keywords (eg. "API endpoints"), or answer questions about the codebase (eg. "how do API endpoints work?"). When calling this agent, specify the desired thoroughness level: "quick" for basic searches, "medium" for moderate exploration, or "very thorough" for comprehensive analysis across multiple locations and naming conventions.',tools:["Glob","Grep","Read","WebFetch","WebSearch"],systemPrompt:`# Explore Subagent
1771
1771
 
1772
1772
  You are a specialized code exploration agent. Your job is to **directly execute searches** using the tools available to you.
1773
1773
 
@@ -1834,9 +1834,9 @@ You are a software architect specializing in implementation planning.
1834
1834
  **Risks**:
1835
1835
  - [Potential issue and mitigation]
1836
1836
 
1837
- 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 oG($){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 sG=R(()=>{U$()});import AZ from"node:fs";import W7 from"node:os";import D2 from"node:path";import lB from"yaml";class tG{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:
1837
+ 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 oG($){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 sG=R(()=>{U$()});import AZ from"node:fs";import W6 from"node:os";import D2 from"node:path";import lB from"yaml";class tG{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:
1838
1838
  ${$.map((Y)=>{let Q=!Y.tools||Y.tools.length===0?"All tools":Y.tools.join(", ");return`- ${Y.name}: ${Y.description} (Tools: ${Q})`}).join(`
1839
- `)}`}loadFromDirectory($,Z){if(!AZ.existsSync($))return;let Y=AZ.readdirSync($);for(let Q of Y){if(!Q.endsWith(".md"))continue;let X=D2.join($,Q);try{let J=this.parseConfigFile(X,Z);this.subagents.set(J.name,J)}catch(J){bZ.warn(`Failed to load subagent config from ${X}:`,J)}}}parseConfigFile($,Z){let Q=AZ.readFileSync($,"utf-8").match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);if(!Q)throw Error(`No YAML frontmatter found in ${$}`);let[,X,J]=Q,G=lB.parse(X);if(!G.name||!G.description)throw Error(`Missing required fields (name, description) in ${$}`);let q=J.trim(),K=this.parseStringOrArray(G.tools),W=this.parseStringOrArray(G.skills),U=oG(G.permissionMode);return{name:G.name,description:G.description,systemPrompt:q,tools:K,color:G.color,configPath:$,model:G.model||"inherit",permissionMode:U,skills:W,source:Z}}parseStringOrArray($){if(!$)return;if(Array.isArray($))return $.map((Z)=>Z.trim()).filter(Boolean);return $.split(",").map((Z)=>Z.trim()).filter(Boolean)}loadFromStandardLocations(){this.loadBuiltinAgents();let $=D2.join(W7.homedir(),".claude","agents");this.loadFromDirectory($,"claude-code-user");let Z=D2.join(process.cwd(),".claude","agents");this.loadFromDirectory(Z,"claude-code-project");let Y=D2.join(W7.homedir(),".blade","agents");this.loadFromDirectory(Y,"blade-user");let Q=D2.join(process.cwd(),".blade","agents");this.loadFromDirectory(Q,"blade-project");let X=this.getAllNames().length;return bZ.debug(`\uD83D\uDCE6 Loaded ${X} subagents from standard locations`),X}loadBuiltinAgents(){for(let $ of NZ)this.subagents.set($.name,{...$,model:$.model||"inherit",source:"builtin"});bZ.debug(`Loaded ${NZ.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 D2.join(W7.homedir(),".claude","agents");return D2.join(process.cwd(),".claude","agents")}static getBladeAgentsDir($){if($==="user")return D2.join(W7.homedir(),".blade","agents");return D2.join(process.cwd(),".blade","agents")}}var bZ,Y$;var m4=R(()=>{Q0();nG();sG();bZ=x("Agent");Y$=new tG});import{EventEmitter as iB}from"events";var T8,y1;var RZ=R(()=>{T8=class T8 extends iB{static instance;constructor(){super();this.setMaxListeners(100)}static getInstance(){if(!T8.instance)T8.instance=new T8;return T8.instance}publish($,Z,Y){this.emit("event",{sessionId:$,type:Z,properties:Y})}subscribe($){return this.on("event",$),()=>this.off("event",$)}};y1=T8.getInstance()});import{nanoid as eG}from"nanoid";import{z as g4}from"zod";function rB($){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(`
1839
+ `)}`}loadFromDirectory($,Z){if(!AZ.existsSync($))return;let Y=AZ.readdirSync($);for(let Q of Y){if(!Q.endsWith(".md"))continue;let X=D2.join($,Q);try{let J=this.parseConfigFile(X,Z);this.subagents.set(J.name,J)}catch(J){bZ.warn(`Failed to load subagent config from ${X}:`,J)}}}parseConfigFile($,Z){let Q=AZ.readFileSync($,"utf-8").match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);if(!Q)throw Error(`No YAML frontmatter found in ${$}`);let[,X,J]=Q,G=lB.parse(X);if(!G.name||!G.description)throw Error(`Missing required fields (name, description) in ${$}`);let q=J.trim(),K=this.parseStringOrArray(G.tools),W=this.parseStringOrArray(G.skills),U=oG(G.permissionMode);return{name:G.name,description:G.description,systemPrompt:q,tools:K,color:G.color,configPath:$,model:G.model||"inherit",permissionMode:U,skills:W,source:Z}}parseStringOrArray($){if(!$)return;if(Array.isArray($))return $.map((Z)=>Z.trim()).filter(Boolean);return $.split(",").map((Z)=>Z.trim()).filter(Boolean)}loadFromStandardLocations(){this.loadBuiltinAgents();let $=D2.join(W6.homedir(),".claude","agents");this.loadFromDirectory($,"claude-code-user");let Z=D2.join(process.cwd(),".claude","agents");this.loadFromDirectory(Z,"claude-code-project");let Y=D2.join(W6.homedir(),".blade","agents");this.loadFromDirectory(Y,"blade-user");let Q=D2.join(process.cwd(),".blade","agents");this.loadFromDirectory(Q,"blade-project");let X=this.getAllNames().length;return bZ.debug(`\uD83D\uDCE6 Loaded ${X} subagents from standard locations`),X}loadBuiltinAgents(){for(let $ of NZ)this.subagents.set($.name,{...$,model:$.model||"inherit",source:"builtin"});bZ.debug(`Loaded ${NZ.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 D2.join(W6.homedir(),".claude","agents");return D2.join(process.cwd(),".claude","agents")}static getBladeAgentsDir($){if($==="user")return D2.join(W6.homedir(),".blade","agents");return D2.join(process.cwd(),".blade","agents")}}var bZ,Y$;var m4=R(()=>{Q0();nG();sG();bZ=x("Agent");Y$=new tG});import{EventEmitter as iB}from"events";var T8,y1;var RZ=R(()=>{T8=class T8 extends iB{static instance;constructor(){super();this.setMaxListeners(100)}static getInstance(){if(!T8.instance)T8.instance=new T8;return T8.instance}publish($,Z,Y){this.emit("event",{sessionId:$,type:Z,properties:Y})}subscribe($){return this.on("event",$),()=>this.off("event",$)}};y1=T8.getInstance()});import{nanoid as eG}from"nanoid";import{z as g4}from"zod";function rB($){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(`
1840
1840
  `)[0]}function aB($){return Y$.getAllNames().includes($)}function nB(){let $=Y$.getAllNames();return $.length>0?$.join(", "):"none (registry not initialized)"}function oB(){return`
1841
1841
  ## Task
1842
1842
 
@@ -1885,7 +1885,7 @@ Agent 仍在运行中,我会使用 TaskOutput 获取结果`,error:{type:"execu
1885
1885
  `+`类型: ${Y.name}
1886
1886
  `+`任务: ${Q}
1887
1887
 
1888
- `+"\uD83D\uDCA1 使用 TaskOutput 工具获取结果",metadata:{agent_id:q,resumed_from:$,subagent_type:Y.name,description:Q,background:!0,subagentSessionId:q,subagentType:Y.name,subagentStatus:"running"}}}var VZ;var $q=R(()=>{K7();aG();m4();U$();Y1();RZ();M0();h0();j$();VZ=e({name:"Task",displayName:"Subagent Scheduler",kind:"readonly",isReadOnly:!0,schema:g4.object({subagent_type:g4.string().refine(aB,($)=>({message:`Invalid subagent type: "${$}". Available: ${nB()}`})).describe('Subagent type to use (e.g., "Explore", "Plan")'),description:g4.string().min(3).max(100).describe("Short task description (3-5 words)"),prompt:g4.string().min(10).describe("Detailed task instructions"),run_in_background:g4.boolean().default(!1).describe("Set to true to run this agent in the background. Use TaskOutput to read the output later."),resume:g4.string().optional().describe("Optional agent ID to resume from. If provided, the agent will continue from the previous execution transcript."),subagent_session_id:g4.string().optional().describe("Internal subagent session id for tracking")}),description:{short:"Launch a new agent to handle complex, multi-step tasks autonomously",get long(){return oB()},usageNotes:["subagent_type is required - choose from available agent types",'description should be 3-5 words (e.g., "Explore error handling")',"prompt should contain a highly detailed task description and specify exactly what information to return","Launch multiple agents concurrently when possible for better performance"],examples:[{description:"Explore codebase for API endpoints",params:{subagent_type:"Explore",description:"Find API endpoints",prompt:"Search the codebase for all API endpoint definitions. Look for route handlers, REST endpoints, and GraphQL resolvers. Return a structured list with file paths, endpoint URLs, HTTP methods, and descriptions."}},{description:"Plan authentication feature",params:{subagent_type:"Plan",description:"Plan user auth",prompt:"Create a detailed implementation plan for adding user authentication to this project. Analyze the existing architecture, then provide step-by-step instructions including: 1) Database schema changes 2) API routes to create 3) Frontend components needed 4) Security considerations 5) Testing strategy. Be specific about file names and code locations."}}]},async execute($,Z){let{subagent_type:Y,description:Q,prompt:X,run_in_background:J=!1,resume:G,subagent_session_id:q}=$,{updateOutput:K}=Z,W=Z.sessionId,U=typeof q==="string"&&q.length>0?q:typeof G==="string"&&G.length>0?G:eG();try{let O=Y$.getAllNames(),F=Y$.getSubagent(Y);if(!F)return{success:!1,llmContent:`Unknown subagent type: ${Y}. Available types: ${O.join(", ")||"none"}`,displayContent:`❌ 未知的 subagent 类型: ${Y}
1888
+ `+"\uD83D\uDCA1 使用 TaskOutput 工具获取结果",metadata:{agent_id:q,resumed_from:$,subagent_type:Y.name,description:Q,background:!0,subagentSessionId:q,subagentType:Y.name,subagentStatus:"running"}}}var VZ;var $q=R(()=>{K6();aG();m4();U$();Y1();RZ();M0();h0();j$();VZ=e({name:"Task",displayName:"Subagent Scheduler",kind:"readonly",isReadOnly:!0,schema:g4.object({subagent_type:g4.string().refine(aB,($)=>({message:`Invalid subagent type: "${$}". Available: ${nB()}`})).describe('Subagent type to use (e.g., "Explore", "Plan")'),description:g4.string().min(3).max(100).describe("Short task description (3-5 words)"),prompt:g4.string().min(10).describe("Detailed task instructions"),run_in_background:g4.boolean().default(!1).describe("Set to true to run this agent in the background. Use TaskOutput to read the output later."),resume:g4.string().optional().describe("Optional agent ID to resume from. If provided, the agent will continue from the previous execution transcript."),subagent_session_id:g4.string().optional().describe("Internal subagent session id for tracking")}),description:{short:"Launch a new agent to handle complex, multi-step tasks autonomously",get long(){return oB()},usageNotes:["subagent_type is required - choose from available agent types",'description should be 3-5 words (e.g., "Explore error handling")',"prompt should contain a highly detailed task description and specify exactly what information to return","Launch multiple agents concurrently when possible for better performance"],examples:[{description:"Explore codebase for API endpoints",params:{subagent_type:"Explore",description:"Find API endpoints",prompt:"Search the codebase for all API endpoint definitions. Look for route handlers, REST endpoints, and GraphQL resolvers. Return a structured list with file paths, endpoint URLs, HTTP methods, and descriptions."}},{description:"Plan authentication feature",params:{subagent_type:"Plan",description:"Plan user auth",prompt:"Create a detailed implementation plan for adding user authentication to this project. Analyze the existing architecture, then provide step-by-step instructions including: 1) Database schema changes 2) API routes to create 3) Frontend components needed 4) Security considerations 5) Testing strategy. Be specific about file names and code locations."}}]},async execute($,Z){let{subagent_type:Y,description:Q,prompt:X,run_in_background:J=!1,resume:G,subagent_session_id:q}=$,{updateOutput:K}=Z,W=Z.sessionId,U=typeof q==="string"&&q.length>0?q:typeof G==="string"&&G.length>0?G:eG();try{let O=Y$.getAllNames(),F=Y$.getSubagent(Y);if(!F)return{success:!1,llmContent:`Unknown subagent type: ${Y}. Available types: ${O.join(", ")||"none"}`,displayContent:`❌ 未知的 subagent 类型: ${Y}
1889
1889
 
1890
1890
  可用类型: ${O.join(", ")||"无"}`,error:{type:"execution_error",message:`Unknown subagent type: ${Y}`}};if(G)return tB(G,X,F,Q,Z);if(J)return sB(F,Q,X,Z,U);K?.(`\uD83D\uDE80 启动 ${Y} subagent: ${Q}`);let H=new LZ(F),_=eG(8);u1.getState().app.actions.startSubagentProgress(_,Y,Q);let z={prompt:X,parentSessionId:Z.sessionId,permissionMode:Z.permissionMode,subagentSessionId:U,onToolStart:(N,M)=>{let b=N.type==="function"?N.function.name:"Unknown";if(u1.getState().app.actions.updateSubagentTool(b),W){if(y1.publish(W,"subagent.update",{subagentSessionId:U,toolName:b}),N.type==="function")y1.publish(W,"subagent.tool.start",{subagentSessionId:U,toolCallId:N.id,toolName:b,arguments:N.function.arguments,toolKind:M})}},onToolResult:(N,M)=>{if(!W)return;if(N.type!=="function")return;y1.publish(W,"subagent.tool.result",{subagentSessionId:U,toolCallId:N.id,toolName:N.function.name,success:!M.error,summary:M.metadata?.summary,output:M.displayContent,metadata:M.metadata})},onContentDelta:(N)=>{if(W)y1.publish(W,"subagent.delta",{subagentSessionId:U,delta:N})},onThinkingDelta:(N)=>{if(W)y1.publish(W,"subagent.thinking.delta",{subagentSessionId:U,delta:N})},onStreamEnd:()=>{if(W)y1.publish(W,"subagent.stream.end",{subagentSessionId:U})}};K?.("⚙️ 执行任务中...");let w=Date.now(),B=await H.execute(z),L=Date.now()-w;try{let M=await y0.getInstance().executeSubagentStopHooks(Y,{projectDir:process.cwd(),sessionId:Z.sessionId||"unknown",permissionMode:Z.permissionMode||"default",taskDescription:Q,success:B.success,resultSummary:B.message.slice(0,500),error:B.error});if(!M.shouldStop&&M.continueReason){console.log(`[Task] SubagentStop hook 阻止停止,继续执行: ${M.continueReason}`);let b={prompt:M.continueReason,parentSessionId:Z.sessionId,permissionMode:Z.permissionMode},j=Date.now();B=await H.execute(b),L+=Date.now()-j}if(M.warning)console.warn(`[Task] SubagentStop hook warning: ${M.warning}`)}catch(N){console.warn("[Task] SubagentStop hook execution failed:",N)}if(u1.getState().app.actions.completeSubagentProgress(B.success),B.success){let N=B.message.length>1000?B.message.slice(0,1000)+`
1891
1891
  ...(截断)`:B.message;return{success:!0,llmContent:B.message,displayContent:`✅ Subagent 任务完成
@@ -1906,7 +1906,7 @@ Agent ID: ${B.agentId||"N/A"}
1906
1906
  `+`耗时: ${L}ms
1907
1907
  `+`错误: ${B.error}`,error:{type:"execution_error",message:B.error||"Unknown error"},metadata:{subagentSessionId:U,subagentType:Y,subagentStatus:"failed"}}}catch(O){u1.getState().app.actions.completeSubagentProgress(!1);let F=O,H=rB(F);return{success:!1,llmContent:`Subagent execution error: ${F.message}`,displayContent:`❌ Subagent 执行异常
1908
1908
 
1909
- ${H}`,error:{type:"execution_error",message:F.message,details:O}}}},version:"4.0.0",category:"Subagent",tags:["task","subagent","delegation","explore","plan"],extractSignatureContent:($)=>`${$.subagent_type}:${$.description}`,abstractPermissionRule:()=>""})});import{z as U7}from"zod";async function Zq($,Z,Y){let Q=C$.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 $w($,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 G={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=`${Yq(J.status)} TaskOutput(${$}) - Shell
1909
+ ${H}`,error:{type:"execution_error",message:F.message,details:O}}}},version:"4.0.0",category:"Subagent",tags:["task","subagent","delegation","explore","plan"],extractSignatureContent:($)=>`${$.subagent_type}:${$.description}`,abstractPermissionRule:()=>""})});import{z as U6}from"zod";async function Zq($,Z,Y){let Q=C$.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 $w($,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 G={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=`${Yq(J.status)} TaskOutput(${$}) - Shell
1910
1910
  `+`状态: ${J.status}
1911
1911
  `+`命令: ${J.command}
1912
1912
  `+(J.pid?`PID: ${J.pid}
@@ -1924,7 +1924,7 @@ ${J.stderr}`:"");return{success:!0,llmContent:G,displayContent:K,metadata:G}}asy
1924
1924
  `:"")+(X.result?.message?`
1925
1925
  结果:
1926
1926
  ${X.result.message}`:"")+(X.result?.error?`
1927
- 错误: ${X.result.error}`:"");return{success:!0,llmContent:J,displayContent:K,metadata:{...J,subagentSessionId:X.id,subagentType:X.subagentType,subagentStatus:G,subagentSummary:typeof X.result?.message==="string"?X.result.message.slice(0,500):void 0}}}async function $w($,Z){let Y=C$.getInstance(),Q=Date.now();return new Promise((X)=>{let J=setInterval(()=>{let G=Y.getProcess($);if(!G||G.status!=="running"){clearInterval(J),X();return}if(Date.now()-Q>=Z){clearInterval(J),X();return}},100)})}function Yq($){switch($){case"running":return"⏳";case"completed":case"exited":return"✅";case"failed":case"error":return"❌";case"killed":case"cancelled":return"✂️";default:return"❓"}}var MZ;var Qq=R(()=>{K7();h0();j$();j8();MZ=e({name:"TaskOutput",displayName:"Task Output",kind:"readonly",schema:U7.object({task_id:U7.string().min(1).describe("The task ID to get output from"),block:U7.boolean().default(!0).describe("Whether to wait for completion"),timeout:U7.number().min(0).max(600000).default(30000).describe("Max wait time in ms")}),description:{short:"Retrieves output from a running or completed task",long:`
1927
+ 错误: ${X.result.error}`:"");return{success:!0,llmContent:J,displayContent:K,metadata:{...J,subagentSessionId:X.id,subagentType:X.subagentType,subagentStatus:G,subagentSummary:typeof X.result?.message==="string"?X.result.message.slice(0,500):void 0}}}async function $w($,Z){let Y=C$.getInstance(),Q=Date.now();return new Promise((X)=>{let J=setInterval(()=>{let G=Y.getProcess($);if(!G||G.status!=="running"){clearInterval(J),X();return}if(Date.now()-Q>=Z){clearInterval(J),X();return}},100)})}function Yq($){switch($){case"running":return"⏳";case"completed":case"exited":return"✅";case"failed":case"error":return"❌";case"killed":case"cancelled":return"✂️";default:return"❓"}}var MZ;var Qq=R(()=>{K6();h0();j$();j8();MZ=e({name:"TaskOutput",displayName:"Task Output",kind:"readonly",schema:U6.object({task_id:U6.string().min(1).describe("The task ID to get output from"),block:U6.boolean().default(!0).describe("Whether to wait for completion"),timeout:U6.number().min(0).max(600000).default(30000).describe("Max wait time in ms")}),description:{short:"Retrieves output from a running or completed task",long:`
1928
1928
  - Retrieves output from a running or completed task (background shell, agent, or remote session)
1929
1929
  - Takes a task_id parameter identifying the task
1930
1930
  - Returns the task output along with status information
@@ -1936,7 +1936,7 @@ ${X.result.message}`:"")+(X.result?.error?`
1936
1936
 
1937
1937
  任务 ID 格式:
1938
1938
  - bash_xxx: 后台 shell
1939
- - agent: 后台 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 Xq=R(()=>{$q();Qq()});import{randomUUID as Zw}from"crypto";import*as E8 from"fs/promises";import*as O7 from"path";var u4;var Jq=R(()=>{u4=class u4{static instances=new Map;todos=[];filePath;loaded=!1;constructor($,Z){this.filePath=O7.join(Z,"todos",`${$}-agent-${$}.json`)}static getInstance($,Z){let Y=`${$}-${Z}`;if(!u4.instances.has(Y))u4.instances.set(Y,new u4($,Z));return u4.instances.get(Y)}validate($){if($.filter((Y)=>Y.status==="in_progress").length>1)return{valid:!1,error:"同时只能有一个任务处于 in_progress 状态"};return{valid:!0}}async updateTodos($){await this.ensureLoaded();let Z=new Date().toISOString(),Y=$.map((X)=>{let J=X,G=this.todos.find((q)=>q.id===J.id||q.content===X.content);return{...X,id:J.id||G?.id||Zw(),priority:X.priority||G?.priority||"medium",createdAt:G?.createdAt||Z,startedAt:X.status==="in_progress"&&!G?.startedAt?Z:G?.startedAt,completedAt:X.status==="completed"&&!G?.completedAt?Z:G?.completedAt}}),Q=this.validate(Y);if(!Q.valid)throw Error(Q.error);this.todos=Y,await this.saveTodos()}getSortedTodos(){let $={completed:0,in_progress:1,pending:2},Z={high:0,medium:1,low:2};return[...this.todos].sort((Y,Q)=>{let X=$[Y.status]-$[Q.status];if(X!==0)return X;return Z[Y.priority]-Z[Q.priority]})}getTodos(){return this.getSortedTodos()}async ensureLoaded(){if(!this.loaded)await this.loadTodos(),this.loaded=!0}async loadTodos(){try{let $=await E8.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 E8.mkdir(O7.dirname(this.filePath),{recursive:!0,mode:493}),await E8.writeFile(this.filePath,JSON.stringify(this.todos,null,2),"utf-8")}catch($){throw console.error("保存 TODO 列表失败:",$),$}}}});import{z as I8}from"zod";var Gq;var qq=R(()=>{Gq=I8.object({id:I8.string().optional(),content:I8.string().min(1,"Content cannot be empty"),status:I8.enum(["pending","in_progress","completed"]),activeForm:I8.string().min(1,"ActiveForm cannot be empty"),priority:I8.enum(["high","medium","low"]).default("medium")})});import{z as Kq}from"zod";function DZ($){let{sessionId:Z,configDir:Y}=$;return e({name:"TodoWrite",displayName:"Todo Write",kind:"readonly",schema:Kq.object({todos:Kq.array(Gq).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.
1939
+ - agent: 后台 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 Xq=R(()=>{$q();Qq()});import{randomUUID as Zw}from"crypto";import*as E8 from"fs/promises";import*as O6 from"path";var u4;var Jq=R(()=>{u4=class u4{static instances=new Map;todos=[];filePath;loaded=!1;constructor($,Z){this.filePath=O6.join(Z,"todos",`${$}-agent-${$}.json`)}static getInstance($,Z){let Y=`${$}-${Z}`;if(!u4.instances.has(Y))u4.instances.set(Y,new u4($,Z));return u4.instances.get(Y)}validate($){if($.filter((Y)=>Y.status==="in_progress").length>1)return{valid:!1,error:"同时只能有一个任务处于 in_progress 状态"};return{valid:!0}}async updateTodos($){await this.ensureLoaded();let Z=new Date().toISOString(),Y=$.map((X)=>{let J=X,G=this.todos.find((q)=>q.id===J.id||q.content===X.content);return{...X,id:J.id||G?.id||Zw(),priority:X.priority||G?.priority||"medium",createdAt:G?.createdAt||Z,startedAt:X.status==="in_progress"&&!G?.startedAt?Z:G?.startedAt,completedAt:X.status==="completed"&&!G?.completedAt?Z:G?.completedAt}}),Q=this.validate(Y);if(!Q.valid)throw Error(Q.error);this.todos=Y,await this.saveTodos()}getSortedTodos(){let $={completed:0,in_progress:1,pending:2},Z={high:0,medium:1,low:2};return[...this.todos].sort((Y,Q)=>{let X=$[Y.status]-$[Q.status];if(X!==0)return X;return Z[Y.priority]-Z[Q.priority]})}getTodos(){return this.getSortedTodos()}async ensureLoaded(){if(!this.loaded)await this.loadTodos(),this.loaded=!0}async loadTodos(){try{let $=await E8.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 E8.mkdir(O6.dirname(this.filePath),{recursive:!0,mode:493}),await E8.writeFile(this.filePath,JSON.stringify(this.todos,null,2),"utf-8")}catch($){throw console.error("保存 TODO 列表失败:",$),$}}}});import{z as I8}from"zod";var Gq;var qq=R(()=>{Gq=I8.object({id:I8.string().optional(),content:I8.string().min(1,"Content cannot be empty"),status:I8.enum(["pending","in_progress","completed"]),activeForm:I8.string().min(1,"ActiveForm cannot be empty"),priority:I8.enum(["high","medium","low"]).default("medium")})});import{z as Kq}from"zod";function DZ($){let{sessionId:Z,configDir:Y}=$;return e({name:"TodoWrite",displayName:"Todo Write",kind:"readonly",schema:Kq.object({todos:Kq.array(Gq).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.
1940
1940
  It also helps the user understand the progress of the task and overall progress of their requests.
1941
1941
 
1942
1942
  ## When to Use This Tool
@@ -2101,12 +2101,12 @@ ${G}
2101
2101
 
2102
2102
  ... (还有 ${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 hZ{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 xZ{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 n1;var pq=R(()=>{hq();U$();Y1();Q0();M0();j$();xq();n1=x("Execution")});import{EventEmitter as uw}from"events";var pZ;var mq=R(()=>{U$();Y1();Sq();kq();p5();R$();fq();pq();pZ=class pZ extends uw{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 kZ(Y,this.sessionApprovals,Q);this.stages=[new SZ(this.registry),X,new EZ,new fZ(this.sessionApprovals,X.getPermissionChecker()),new hZ,new IZ,new xZ]}async execute($,Z,Y){let Q=Date.now(),X=this.generateExecutionId(),J=new x5($,Z,{...Y,sessionId:Y.sessionId||X});this.emit("executionStarted",{executionId:X,toolName:$,params:Z,context:Y,timestamp:Q});let G=this.registry.get($),q=G&&!G.isConcurrencySafe,K=q&&Z.file_path?String(Z.file_path):null;if(q&&K)return Z4.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",G={success:!1,llmContent:`Tool execution failed: ${Q.message}`,displayContent:`错误: ${Q.message}`,error:{type:"execution_error",message:Q.message}};try{let K=await y0.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)G={...G,llmContent:`${G.llmContent}
2103
2103
 
2104
- ${K.additionalContext}`};if(K.warning)console.warn(`[ExecutionPipeline] PostToolUseFailure hook warning: ${K.warning}`)}catch(q){console.warn("[ExecutionPipeline] PostToolUseFailure hook execution failed:",q)}return this.addToHistory({executionId:Z,toolName:$.toolName,params:$.params,result:G,startTime:Y,endTime:X,context:$.context}),this.emit("executionFailed",{executionId:Z,toolName:$.toolName,error:Q,duration:X-Y,timestamp:X}),G}}async executeAll($){let Z=$.map((Y)=>this.execute(Y.toolName,Y.params,Y.context));return Promise.all(Z)}async executeParallel($,Z=5){let Y=[],Q=[];for(let X=0;X<$.length;X++){let J=$[X],G=this.execute(J.toolName,J.params,J.context);if(Q.push(G),Q.length>=Z||X===$.length-1){let q=await Promise.all(Q);Y.push(...q),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 dw}from"events";var F7;var gq=R(()=>{U$();F7=class F7 extends dw{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 F7.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 lw($){return cw.some((Z)=>Z.test($))}function iw($){if($.supportsThinking!==void 0)return{supportsThinking:$.supportsThinking,thinkingBudget:$.thinkingBudget};return{supportsThinking:lw($.model),thinkingBudget:void 0}}function C8($){return iw($).supportsThinking}var cw;var H7=R(()=>{cw=[/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 mZ{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((O)=>O.role==="system"),X=Z.filter((O)=>O.role!=="system"),J=this.getRecentMessages(X),G=X.slice(0,-this.recentMessagesLimit),q=await this.generateSummary(G),K=this.extractKeyPoints(G,Y),W=this.generateToolSummary(Y),U=this.estimateTokenCount(q,K,J,W);return{summary:q,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 G=J.content.toLowerCase();["关于","讨论","问题","项目","功能","需求"].forEach((U)=>{if(G.includes(U)){let O=this.extractContext(G,U,50);if(O)Z.add(O)}}),["创建","删除","修改","更新","实现","开发"].forEach((U)=>{if(G.includes(U)){let O=this.extractContext(G,U,30);if(O)Y.add(O)}}),["决定","选择","确定","采用","使用"].forEach((U)=>{if(G.includes(U)){let O=this.extractContext(G,U,40);if(O)Q.add(O)}})}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((q)=>Y.add(`用户问题:${q}`)),this.extractRequests(X.content).forEach((q)=>Y.add(`用户请求:${q}`));else if(X.role==="assistant")this.extractSolutions(X.content).forEach((G)=>Y.add(`解决方案:${G}`));return this.summarizeToolUsage(Z).forEach((X)=>Y.add(`工具使用:${X}`)),Array.from(Y).slice(0,this.keyPointsLimit)}generateToolSummary($){if($.length===0)return"";let Z=new Map,Y=Date.now()-600000;for(let X of $){let J=Z.get(X.name)||{count:0,success:0,recent:0};if(J.count++,X.status==="success")J.success++;if(X.timestamp>Y)J.recent++;Z.set(X.name,J)}let Q=[];for(let[X,J]of Array.from(Z.entries())){let G=Math.round(J.success/J.count*100);Q.push(`${X}(${J.count}次,成功率${G}%)`)}return`工具调用:${Q.join("、")}`}estimateTokenCount($,Z,Y,Q){let X=$.length+Z.join(" ").length;if(Q)X+=Q.length;for(let J of Y)X+=J.content.length;return Math.ceil(X/4)}extractContext($,Z,Y){let Q=$.indexOf(Z);if(Q===-1)return null;let X=Math.max(0,Q-Y/2),J=Math.min($.length,Q+Y/2);return $.substring(X,J).trim()}extractQuestions($){let Z=[],Y=["?","?","如何","怎么","什么","为什么"],Q=$.split(/[。!.!]/);for(let X of Q)if(Y.some((J)=>X.includes(J))){let J=X.trim();if(J.length>5&&J.length<100)Z.push(J)}return Z.slice(0,3)}extractRequests($){let Z=[],Y=["请","帮我","需要","想要","希望","能否"],Q=$.split(/[。!.!]/);for(let X of Q)if(Y.some((J)=>X.includes(J))){let J=X.trim();if(J.length>5&&J.length<100)Z.push(J)}return Z.slice(0,3)}extractSolutions($){let Z=[],Y=["可以","建议","推荐","应该","最好","解决方案"],Q=$.split(/[。!.!]/);for(let X of Q)if(Y.some((J)=>X.includes(J))){let J=X.trim();if(J.length>10&&J.length<150)Z.push(J)}return Z.slice(0,3)}summarizeToolUsage($){let Z=[],Y=$.filter((Q)=>Date.now()-Q.timestamp<1800000);if(Y.length>0){let Q=new Map;Y.forEach((X)=>{let J=Q.get(X.name)||[];J.push(X),Q.set(X.name,J)});for(let[X,J]of Array.from(Q.entries())){let G=J.filter((q)=>q.status==="success").length;Z.push(`${X}(${J.length}次,${G}成功)`)}}return Z.slice(0,5)}shouldCompress($,Z){return this.estimateCurrentTokens($)>Z*0.8}estimateCurrentTokens($){let Y=$.layers.conversation.messages.reduce((Q,X)=>Q+X.content.length,0);return Math.ceil(Y/4)}}class 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),G=Math.min(10,X.length);return{recentCalls:[...Q.slice(-J),...X.slice(-G)].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((G)=>G.role==="system"),Q=$.filter((G)=>G.role!=="system"),X=Z-Y.length,J=X>0?Q.slice(-X):[];return[...Y,...J].sort((G,q)=>G.timestamp-q.timestamp)}limitByTokens($,Z){if(Z<=0)return $;let Y=0,Q=[];for(let X=$.length-1;X>=0;X--){let J=$[X],G=this.estimateMessageTokens(J);if(J.role==="system")if(Y+G<=Z)Q.unshift(J),Y+=G;else{let q=this.compressMessage(J,Z-Y);Q.unshift(q),Y+=this.estimateMessageTokens(q)}else if(Y+G<=Z)Q.unshift(J),Y+=G;else break}return Q.sort((X,J)=>X.timestamp-J.timestamp)}estimateMessageTokens($){return Math.ceil($.content.length/4)}compressMessage($,Z){let Y=Z*4;if($.content.length<=Y)return $;let Q=$.content.substring(0,Y-3)+"...";return{...$,content:Q,metadata:{...$.metadata,compressed:!0,originalLength:$.content.length}}}updateTopics($,Z){let Y=new Set(Z);for(let Q of $)this.extractTopicsFromMessage(Q).forEach((J)=>Y.add(J));return Array.from(Y).slice(0,10)}extractTopicsFromMessage($){let Z=$.content.toLowerCase(),Y=[];return["项目","功能","模块","组件","服务","接口","数据库","前端","后端","算法","架构","设计"].forEach((X)=>{if(Z.includes(X))Y.push(X)}),Y}estimateTokens($){let Z=0;for(let Q of $.layers.conversation.messages)Z+=this.estimateMessageTokens(Q);let Y=JSON.stringify($.layers.system);if(Z+=Math.ceil(Y.length/4),$.layers.tool.recentCalls.length>0){let Q=JSON.stringify($.layers.tool);Z+=Math.ceil(Q.length/8)}return Z}static createPresets(){return{lightweight:new 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 gZ{cache=new Map;maxSize;defaultTTL;constructor($=100,Z=300000){this.maxSize=$,this.defaultTTL=Z}set($,Z,Y){let Q=Date.now(),X={data:Z,timestamp:Q,accessCount:0,lastAccess:Q,ttl:Y||this.defaultTTL};if(this.cache.size>=this.maxSize&&!this.cache.has($))this.evictLeastUsed();this.cache.set($,X)}get($){let Z=this.cache.get($);if(!Z)return null;let Y=Date.now();if(Y-Z.timestamp>Z.ttl)return this.cache.delete($),null;return Z.accessCount++,Z.lastAccess=Y,Z.data}has($){let Z=this.cache.get($);if(!Z)return!1;if(Date.now()-Z.timestamp>Z.ttl)return this.cache.delete($),!1;return!0}delete($){return this.cache.delete($)}clear(){this.cache.clear()}size(){return this.cleanExpired(),this.cache.size}cacheMessageSummary($,Z,Y){let Q=`summary:${$}:${Z.length}`;this.set(Q,{summary:Y,messageCount:Z.length,lastMessage:Z[Z.length-1]?.timestamp||0},600000)}getMessageSummary($,Z){let Y=`summary:${$}:${Z}`;return this.get(Y)}cacheToolResult($,Z,Y){let Q=this.hashInput(Z),X=`tool:${$}:${Q}`;this.set(X,Y,1800000)}getToolResult($,Z){let Y=this.hashInput(Z),Q=`tool:${$}:${Y}`;return this.get(Q)}cacheCompressedContext($,Z){let Y=`compressed:${$}`;this.set(Y,Z,900000)}getCompressedContext($){let Z=`compressed:${$}`;return this.get(Z)}getStats(){this.cleanExpired();let $=0,Z=0,Y=[];for(let[Q,X]of Array.from(this.cache.entries()))$+=X.accessCount,Z+=this.estimateItemSize(X),Y.push({key:Q,accessCount:X.accessCount,lastAccess:X.lastAccess});return Y.sort((Q,X)=>X.accessCount-Q.accessCount),{size:this.cache.size,maxSize:this.maxSize,hitRate:$>0?$/($+this.cache.size):0,memoryUsage:Z,topKeys:Y.slice(0,10)}}cleanExpired(){let $=Date.now(),Z=[];for(let[Y,Q]of Array.from(this.cache.entries()))if($-Q.timestamp>Q.ttl)Z.push(Y);Z.forEach((Y)=>this.cache.delete(Y))}evictLeastUsed(){let $=null,Z=1/0,Y=Date.now();for(let[Q,X]of Array.from(this.cache.entries())){let J=1/(Y-X.lastAccess+1),G=X.accessCount,q=J*G;if(q<Z)Z=q,$=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 uZ{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 _7 from"node:fs";import{createReadStream as rw}from"node:fs";import*as n$ from"node:fs/promises";import*as dZ from"node:path";import{createInterface as aw}from"node:readline";class T1{filePath;constructor($){this.filePath=$}async append($){try{await n$.mkdir(dZ.dirname(this.filePath),{recursive:!0,mode:493});let Z=JSON.stringify($)+`
2104
+ ${K.additionalContext}`};if(K.warning)console.warn(`[ExecutionPipeline] PostToolUseFailure hook warning: ${K.warning}`)}catch(q){console.warn("[ExecutionPipeline] PostToolUseFailure hook execution failed:",q)}return this.addToHistory({executionId:Z,toolName:$.toolName,params:$.params,result:G,startTime:Y,endTime:X,context:$.context}),this.emit("executionFailed",{executionId:Z,toolName:$.toolName,error:Q,duration:X-Y,timestamp:X}),G}}async executeAll($){let Z=$.map((Y)=>this.execute(Y.toolName,Y.params,Y.context));return Promise.all(Z)}async executeParallel($,Z=5){let Y=[],Q=[];for(let X=0;X<$.length;X++){let J=$[X],G=this.execute(J.toolName,J.params,J.context);if(Q.push(G),Q.length>=Z||X===$.length-1){let q=await Promise.all(Q);Y.push(...q),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 dw}from"events";var F6;var gq=R(()=>{U$();F6=class F6 extends dw{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 F6.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 lw($){return cw.some((Z)=>Z.test($))}function iw($){if($.supportsThinking!==void 0)return{supportsThinking:$.supportsThinking,thinkingBudget:$.thinkingBudget};return{supportsThinking:lw($.model),thinkingBudget:void 0}}function C8($){return iw($).supportsThinking}var cw;var H6=R(()=>{cw=[/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 mZ{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((O)=>O.role==="system"),X=Z.filter((O)=>O.role!=="system"),J=this.getRecentMessages(X),G=X.slice(0,-this.recentMessagesLimit),q=await this.generateSummary(G),K=this.extractKeyPoints(G,Y),W=this.generateToolSummary(Y),U=this.estimateTokenCount(q,K,J,W);return{summary:q,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 G=J.content.toLowerCase();["关于","讨论","问题","项目","功能","需求"].forEach((U)=>{if(G.includes(U)){let O=this.extractContext(G,U,50);if(O)Z.add(O)}}),["创建","删除","修改","更新","实现","开发"].forEach((U)=>{if(G.includes(U)){let O=this.extractContext(G,U,30);if(O)Y.add(O)}}),["决定","选择","确定","采用","使用"].forEach((U)=>{if(G.includes(U)){let O=this.extractContext(G,U,40);if(O)Q.add(O)}})}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((q)=>Y.add(`用户问题:${q}`)),this.extractRequests(X.content).forEach((q)=>Y.add(`用户请求:${q}`));else if(X.role==="assistant")this.extractSolutions(X.content).forEach((G)=>Y.add(`解决方案:${G}`));return this.summarizeToolUsage(Z).forEach((X)=>Y.add(`工具使用:${X}`)),Array.from(Y).slice(0,this.keyPointsLimit)}generateToolSummary($){if($.length===0)return"";let Z=new Map,Y=Date.now()-600000;for(let X of $){let J=Z.get(X.name)||{count:0,success:0,recent:0};if(J.count++,X.status==="success")J.success++;if(X.timestamp>Y)J.recent++;Z.set(X.name,J)}let Q=[];for(let[X,J]of Array.from(Z.entries())){let G=Math.round(J.success/J.count*100);Q.push(`${X}(${J.count}次,成功率${G}%)`)}return`工具调用:${Q.join("、")}`}estimateTokenCount($,Z,Y,Q){let X=$.length+Z.join(" ").length;if(Q)X+=Q.length;for(let J of Y)X+=J.content.length;return Math.ceil(X/4)}extractContext($,Z,Y){let Q=$.indexOf(Z);if(Q===-1)return null;let X=Math.max(0,Q-Y/2),J=Math.min($.length,Q+Y/2);return $.substring(X,J).trim()}extractQuestions($){let Z=[],Y=["?","?","如何","怎么","什么","为什么"],Q=$.split(/[。!.!]/);for(let X of Q)if(Y.some((J)=>X.includes(J))){let J=X.trim();if(J.length>5&&J.length<100)Z.push(J)}return Z.slice(0,3)}extractRequests($){let Z=[],Y=["请","帮我","需要","想要","希望","能否"],Q=$.split(/[。!.!]/);for(let X of Q)if(Y.some((J)=>X.includes(J))){let J=X.trim();if(J.length>5&&J.length<100)Z.push(J)}return Z.slice(0,3)}extractSolutions($){let Z=[],Y=["可以","建议","推荐","应该","最好","解决方案"],Q=$.split(/[。!.!]/);for(let X of Q)if(Y.some((J)=>X.includes(J))){let J=X.trim();if(J.length>10&&J.length<150)Z.push(J)}return Z.slice(0,3)}summarizeToolUsage($){let Z=[],Y=$.filter((Q)=>Date.now()-Q.timestamp<1800000);if(Y.length>0){let Q=new Map;Y.forEach((X)=>{let J=Q.get(X.name)||[];J.push(X),Q.set(X.name,J)});for(let[X,J]of Array.from(Q.entries())){let G=J.filter((q)=>q.status==="success").length;Z.push(`${X}(${J.length}次,${G}成功)`)}}return Z.slice(0,5)}shouldCompress($,Z){return this.estimateCurrentTokens($)>Z*0.8}estimateCurrentTokens($){let Y=$.layers.conversation.messages.reduce((Q,X)=>Q+X.content.length,0);return Math.ceil(Y/4)}}class 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),G=Math.min(10,X.length);return{recentCalls:[...Q.slice(-J),...X.slice(-G)].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((G)=>G.role==="system"),Q=$.filter((G)=>G.role!=="system"),X=Z-Y.length,J=X>0?Q.slice(-X):[];return[...Y,...J].sort((G,q)=>G.timestamp-q.timestamp)}limitByTokens($,Z){if(Z<=0)return $;let Y=0,Q=[];for(let X=$.length-1;X>=0;X--){let J=$[X],G=this.estimateMessageTokens(J);if(J.role==="system")if(Y+G<=Z)Q.unshift(J),Y+=G;else{let q=this.compressMessage(J,Z-Y);Q.unshift(q),Y+=this.estimateMessageTokens(q)}else if(Y+G<=Z)Q.unshift(J),Y+=G;else break}return Q.sort((X,J)=>X.timestamp-J.timestamp)}estimateMessageTokens($){return Math.ceil($.content.length/4)}compressMessage($,Z){let Y=Z*4;if($.content.length<=Y)return $;let Q=$.content.substring(0,Y-3)+"...";return{...$,content:Q,metadata:{...$.metadata,compressed:!0,originalLength:$.content.length}}}updateTopics($,Z){let Y=new Set(Z);for(let Q of $)this.extractTopicsFromMessage(Q).forEach((J)=>Y.add(J));return Array.from(Y).slice(0,10)}extractTopicsFromMessage($){let Z=$.content.toLowerCase(),Y=[];return["项目","功能","模块","组件","服务","接口","数据库","前端","后端","算法","架构","设计"].forEach((X)=>{if(Z.includes(X))Y.push(X)}),Y}estimateTokens($){let Z=0;for(let Q of $.layers.conversation.messages)Z+=this.estimateMessageTokens(Q);let Y=JSON.stringify($.layers.system);if(Z+=Math.ceil(Y.length/4),$.layers.tool.recentCalls.length>0){let Q=JSON.stringify($.layers.tool);Z+=Math.ceil(Q.length/8)}return Z}static createPresets(){return{lightweight:new 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 gZ{cache=new Map;maxSize;defaultTTL;constructor($=100,Z=300000){this.maxSize=$,this.defaultTTL=Z}set($,Z,Y){let Q=Date.now(),X={data:Z,timestamp:Q,accessCount:0,lastAccess:Q,ttl:Y||this.defaultTTL};if(this.cache.size>=this.maxSize&&!this.cache.has($))this.evictLeastUsed();this.cache.set($,X)}get($){let Z=this.cache.get($);if(!Z)return null;let Y=Date.now();if(Y-Z.timestamp>Z.ttl)return this.cache.delete($),null;return Z.accessCount++,Z.lastAccess=Y,Z.data}has($){let Z=this.cache.get($);if(!Z)return!1;if(Date.now()-Z.timestamp>Z.ttl)return this.cache.delete($),!1;return!0}delete($){return this.cache.delete($)}clear(){this.cache.clear()}size(){return this.cleanExpired(),this.cache.size}cacheMessageSummary($,Z,Y){let Q=`summary:${$}:${Z.length}`;this.set(Q,{summary:Y,messageCount:Z.length,lastMessage:Z[Z.length-1]?.timestamp||0},600000)}getMessageSummary($,Z){let Y=`summary:${$}:${Z}`;return this.get(Y)}cacheToolResult($,Z,Y){let Q=this.hashInput(Z),X=`tool:${$}:${Q}`;this.set(X,Y,1800000)}getToolResult($,Z){let Y=this.hashInput(Z),Q=`tool:${$}:${Y}`;return this.get(Q)}cacheCompressedContext($,Z){let Y=`compressed:${$}`;this.set(Y,Z,900000)}getCompressedContext($){let Z=`compressed:${$}`;return this.get(Z)}getStats(){this.cleanExpired();let $=0,Z=0,Y=[];for(let[Q,X]of Array.from(this.cache.entries()))$+=X.accessCount,Z+=this.estimateItemSize(X),Y.push({key:Q,accessCount:X.accessCount,lastAccess:X.lastAccess});return Y.sort((Q,X)=>X.accessCount-Q.accessCount),{size:this.cache.size,maxSize:this.maxSize,hitRate:$>0?$/($+this.cache.size):0,memoryUsage:Z,topKeys:Y.slice(0,10)}}cleanExpired(){let $=Date.now(),Z=[];for(let[Y,Q]of Array.from(this.cache.entries()))if($-Q.timestamp>Q.ttl)Z.push(Y);Z.forEach((Y)=>this.cache.delete(Y))}evictLeastUsed(){let $=null,Z=1/0,Y=Date.now();for(let[Q,X]of Array.from(this.cache.entries())){let J=1/(Y-X.lastAccess+1),G=X.accessCount,q=J*G;if(q<Z)Z=q,$=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 uZ{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 _6 from"node:fs";import{createReadStream as rw}from"node:fs";import*as n$ from"node:fs/promises";import*as dZ from"node:path";import{createInterface as aw}from"node:readline";class T1{filePath;constructor($){this.filePath=$}async append($){try{await n$.mkdir(dZ.dirname(this.filePath),{recursive:!0,mode:493});let Z=JSON.stringify($)+`
2105
2105
  `;await n$.appendFile(this.filePath,Z,"utf-8")}catch(Z){throw console.error(`[JSONLStore] 追加写入失败: ${this.filePath}`,Z),Z}}async appendBatch($){try{await n$.mkdir(dZ.dirname(this.filePath),{recursive:!0,mode:493});let Z=$.map((Y)=>JSON.stringify(Y)).join(`
2106
2106
  `)+`
2107
- `;await n$.appendFile(this.filePath,Z,"utf-8")}catch(Z){throw console.error(`[JSONLStore] 批量追加写入失败: ${this.filePath}`,Z),Z}}async readAll(){try{if(!_7.existsSync(this.filePath))return[];let Z=(await n$.readFile(this.filePath,"utf-8")).split(`
2108
- `).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(!_7.existsSync(this.filePath)){Z();return}let Q=rw(this.filePath,"utf-8"),X=aw({input:Q,crlfDelay:Number.POSITIVE_INFINITY});X.on("line",async(J)=>{let G=J.trim();if(G.length===0)return;try{let q=JSON.parse(G);await $(q)}catch(q){console.warn(`[JSONLStore] 解析 JSON 行失败: ${G}`,q)}}),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(!_7.existsSync(this.filePath))return{exists:!1,size:0,lineCount:0};let $=await n$.stat(this.filePath),Y=(await n$.readFile(this.filePath,"utf-8")).split(`
2109
- `).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 n$.access(this.filePath),!0}catch{return!1}}async delete(){try{if(await this.exists())await n$.unlink(this.filePath)}catch($){throw console.error(`[JSONLStore] 删除文件失败: ${this.filePath}`,$),$}}getFilePath(){return this.filePath}}var uq=()=>{};import{nanoid as H2}from"nanoid";import*as j2 from"node:fs/promises";import*as dq from"node:path";class cZ{projectPath;maxSessions;version;constructor($=process.cwd(),Z=100,Y="0.0.10"){this.projectPath=$,this.maxSessions=Z,this.version=Y}createEvent($,Z,Y){return{id:H2(),sessionId:Z,timestamp:new Date().toISOString(),type:$,cwd:this.projectPath,gitBranch:fJ(this.projectPath),version:this.version,data:Y}}async ensureSessionCreated($,Z){let Y=O1(this.projectPath,$),Q=new T1(Y);if((await Q.getStats()).lineCount>0)return;let J=new Date().toISOString(),G={sessionId:$,rootId:Z?.parentSessionId??$,parentId:Z?.parentSessionId,relationType:Z?"subagent":void 0,title:void 0,status:"running",agentType:Z?.subagentType,model:void 0,permission:void 0,createdAt:J,updatedAt:J},q=this.createEvent("session_created",$,G);await Q.append(q)}buildCompactionMetadata($){let Z={trigger:$.trigger,preTokens:$.preTokens};if($.postTokens!==void 0)Z.postTokens=$.postTokens;if($.filesIncluded)Z.filesIncluded=$.filesIncluded;return Z}async initialize(){try{let $=S3(this.projectPath);await j2.mkdir($,{recursive:!0,mode:493}),console.log(`[PersistentStore] 初始化存储目录: ${$}`)}catch($){console.warn("[PersistentStore] 无法创建持久化存储目录:",$)}}async saveMessage($,Z,Y,Q=null,X,J){try{let G=O1(this.projectPath,$),q=new T1(G);await this.ensureSessionCreated($,J);let K=new Date().toISOString(),W=H2(),U={messageId:W,role:Z,parentMessageId:Q??void 0,createdAt:K,model:X?.model,usage:X?.usage},O=this.createEvent("message_created",$,U),F={partId:H2(),messageId:W,partType:"text",payload:{text:Y},createdAt:K},H=this.createEvent("part_created",$,F);return await q.appendBatch([O,H]),W}catch(G){throw console.error(`[PersistentStore] 保存消息失败 (session: ${$}):`,G),G}}async saveToolUse($,Z,Y,Q=null,X){try{let J=O1(this.projectPath,$),G=new T1(J);await this.ensureSessionCreated($,X);let q=new Date().toISOString(),K=Q??H2(),W=[];if(!Q){let F={messageId:K,role:"assistant",parentMessageId:void 0,createdAt:q};W.push(this.createEvent("message_created",$,F))}let U=H2(),O={partId:U,messageId:K,partType:"tool_call",payload:{toolCallId:U,toolName:Z,input:Y},createdAt:q};if(W.push(this.createEvent("part_created",$,O)),Z==="Task"&&Y&&typeof Y==="object"){let F=Y,H=typeof F.subagent_session_id==="string"?F.subagent_session_id:void 0,_=typeof F.subagent_type==="string"?F.subagent_type:void 0;if(H&&_){let z={partId:H2(),messageId:K,partType:"subtask_ref",payload:{childSessionId:H,agentType:_,status:"running",summary:typeof F.description==="string"?F.description:"",startedAt:q},createdAt:q};W.push(this.createEvent("part_created",$,z))}}return await G.appendBatch(W),U}catch(J){throw console.error(`[PersistentStore] 保存工具调用失败 (session: ${$}):`,J),J}}async saveToolResult($,Z,Y,Q,X=null,J,G,q){try{let K=O1(this.projectPath,$),W=new T1(K);await this.ensureSessionCreated($,G);let U=new Date().toISOString(),O=X??H2(),F=[];if(!X){let _={messageId:O,role:"assistant",parentMessageId:void 0,createdAt:U};F.push(this.createEvent("message_created",$,_))}let H={partId:Z,messageId:O,partType:"tool_result",payload:{toolCallId:Z,toolName:Y,output:Q,error:J??null},createdAt:U};if(F.push(this.createEvent("part_created",$,H)),q){let _=q.subagentStatus==="running"?null:U,z={partId:H2(),messageId:O,partType:"subtask_ref",payload:{childSessionId:q.subagentSessionId,agentType:q.subagentType,status:q.subagentStatus,summary:q.subagentSummary??"",startedAt:U,finishedAt:_},createdAt:U};F.push(this.createEvent("part_created",$,z))}return await W.appendBatch(F),Z}catch(K){throw console.error(`[PersistentStore] 保存工具结果失败 (session: ${$}):`,K),K}}async saveCompaction($,Z,Y,Q=null){try{let X=O1(this.projectPath,$),J=new T1(X);await this.ensureSessionCreated($);let G=new Date().toISOString(),q=H2(),K={messageId:q,role:"system",parentMessageId:Q??void 0,createdAt:G},W=this.buildCompactionMetadata(Y),U={partId:H2(),messageId:q,partType:"summary",payload:{text:Z,metadata:W},createdAt:G},O=[this.createEvent("message_created",$,K),this.createEvent("part_created",$,U)];return await J.appendBatch(O),q}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=O1(this.projectPath,$),Q=await new T1(Z).readAll();if(Q.length===0)return null;let X=Q.find((J)=>J.type==="session_created");return{sessionId:$,userId:void 0,preferences:{},configuration:{},startTime:new Date(X?.timestamp??Q[0].timestamp).getTime()}}catch{return null}}async loadConversation($){try{let Z=O1(this.projectPath,$),Q=await new T1(Z).readAll();if(Q.length===0)return null;let X=new Map;for(let K of Q){if(K.type==="message_created")X.set(K.data.messageId,{id:K.data.messageId,role:K.data.role,content:"",timestamp:new Date(K.timestamp).getTime()});if(K.type==="part_created"&&K.data.partType==="text"){let W=X.get(K.data.messageId);if(W){let U=K.data.payload;W.content=U.text??""}}}let J=Array.from(X.values()),G=Q[Q.length-1],q=new Date(G.timestamp).getTime();return{messages:J,topics:[],lastActivity:q}}catch{return null}}async listSessions(){try{let $=S3(this.projectPath);return(await j2.readdir($)).filter((Y)=>Y.endsWith(".jsonl")).map((Y)=>Y.replace(".jsonl","")).sort()}catch{return[]}}async getSessionSummary($){try{let Z=O1(this.projectPath,$),Y=new T1(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],G=X.filter((q)=>q.type==="message_created"&&["user","assistant"].includes(q.data.role)).length;return{sessionId:$,lastActivity:new Date(J.timestamp).getTime(),messageCount:G,topics:[]}}catch{return null}}async deleteSession($){try{let Z=O1(this.projectPath,$);await new T1(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=O1(this.projectPath,Y),J=await new T1(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 $=S3(this.projectPath);await j2.mkdir($,{recursive:!0,mode:493});let Z=dq.join($,".health-check");return await j2.writeFile(Z,"test","utf-8"),await j2.unlink(Z),{isAvailable:!0,canWrite:!0}}catch($){return{isAvailable:!1,canWrite:!1,error:$ instanceof Error?$.message:String($)}}}static async listAllProjects(){return hJ()}}var cq=R(()=>{uq();k3()});import*as iq from"crypto";import{nanoid as lq}from"nanoid";class c3{memory;persistent;cache;compressor;filter;options;currentSessionId=null;initialized=!1;constructor($={}){let Z=$.storage?.persistentPath||k4();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 uZ(this.options.storage.maxMemorySize),this.persistent=new cZ(process.cwd(),100),this.cache=new gZ(this.options.storage.cacheSize,300000),this.compressor=new mZ,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,J){return this.persistent.saveMessage($,Z,Y,Q,X,J)}async saveToolUse($,Z,Y,Q=null,X){return this.persistent.saveToolUse($,Z,Y,Q,X)}async saveToolResult($,Z,Y,Q,X=null,J,G,q){return this.persistent.saveToolResult($,Z,Y,Q,X,J,G,q)}async saveCompaction($,Z,Y,Q=null){return this.persistent.saveCompaction($,Z,Y,Q)}updateToolState($,Z){if(!this.currentSessionId)throw Error("没有活动会话");this.memory.updateToolState($,Z)}updateWorkspace($){if(!this.currentSessionId)throw Error("没有活动会话");this.memory.updateWorkspace($)}async getFormattedContext($){let Z=this.memory.getContext();if(!Z)throw Error("没有可用的上下文数据");let Y=this.filter.filter(Z,$),Q=this.shouldCompress(Y),X;if(Q){let J=this.hashContext(Y);if(X=this.cache.getCompressedContext(J)??void 0,!X)X=await this.compressor.compress(Y),this.cache.cacheCompressedContext(J,X)}return{context:Y,compressed:X,tokenCount:X?X.tokenCount:Y.metadata.totalTokens}}async searchSessions($,Z=10){let Y=await this.persistent.listSessions(),Q=[];for(let X of Y){let J=await this.persistent.getSessionSummary(X);if(J){let G=this.calculateRelevance($,J.topics);if(G>0)Q.push({sessionId:X,summary:`${J.messageCount}条消息,主题:${J.topics.join("、")}`,lastActivity:J.lastActivity,relevanceScore:G})}}return Q.sort((X,J)=>J.relevanceScore-X.relevanceScore).slice(0,Z)}getCachedToolResult($,Z){return this.cache.getToolResult($,Z)}async getStats(){let[$,Z,Y]=await Promise.all([Promise.resolve(this.memory.getMemoryInfo()),Promise.resolve(this.cache.getStats()),this.persistent.getStorageStats()]);return{currentSession:this.currentSessionId,memory:$,cache:Z,storage:Y}}async cleanup(){if(this.currentSessionId)await this.saveCurrentSession();this.memory.clear(),this.cache.clear(),await this.persistent.cleanupOldSessions(),this.currentSessionId=null,console.log("上下文管理器资源清理完成")}generateSessionId(){return lq()}generateMessageId(){return lq()}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 iq.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 lZ=R(()=>{cq();k3()});class iZ{chatService;contextManager;memoryAdapter;constructor($,Z){this.chatService=$,this.contextManager=Z||new c3,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 rq=R(()=>{lZ()});import{nanoid as nw}from"nanoid";import*as aq from"os";import*as nq from"path";function ow($){if(typeof $==="string")return $;try{return JSON.parse(JSON.stringify($))}catch{return String($)}}class G${config;runtimeOptions;isInitialized=!1;activeTask;executionPipeline;chatService;executionEngine;attachmentCollector;activeSkillContext;currentModelMaxContextTokens;currentModelId;constructor($,Z={},Y){this.config=$,this.runtimeOptions=Z,this.executionPipeline=Y||this.createDefaultPipeline()}createDefaultPipeline(){let $=new F7,Z={...this.config.permissions,...this.runtimeOptions.permissions},Y=this.runtimeOptions.permissionMode??this.config.permissionMode??"default";return new pZ($,{permissionConfig:Z,permissionMode:Y,maxHistorySize:1000})}resolveModelConfig($){let Z=$&&$!=="inherit"?$:void 0,Y=Z?f5(Z):u2();if(!Y)throw Error(`❌ 模型配置未找到: ${Z??"current"}`);return Y}async applyModelConfig($,Z){this.log(`${Z} ${$.name} (${$.model})`);let Y=C8($),Q=ZX(),X=Y&&Q;if(Y&&!Q)this.log("\uD83E\uDDE0 模型支持 Thinking,但用户未开启(按 Tab 开启)");else if(X)this.log("\uD83E\uDDE0 Thinking 模式已启用,启用 reasoning_content 支持");this.currentModelMaxContextTokens=$.maxContextTokens??this.config.maxContextTokens,this.chatService=await P6({provider:$.provider,apiKey:$.apiKey,model:$.model,baseUrl:$.baseUrl,temperature:$.temperature??this.config.temperature,maxContextTokens:this.currentModelMaxContextTokens,maxOutputTokens:$.maxOutputTokens??this.config.maxOutputTokens,timeout:this.config.timeout,supportsThinking:X});let J=this.executionEngine?.getContextManager();this.executionEngine=new iZ(this.chatService,J),this.currentModelId=$.id}async switchModelIfNeeded($){if(!$||$===this.currentModelId)return;let Z=f5($);if(!Z){this.log(`⚠️ 模型配置未找到: ${$}`);return}await this.applyModelConfig(Z,"\uD83D\uDD01 切换模型")}static async create($={}){if(await m2(),g2().length===0)throw Error(`❌ 没有可用的模型配置
2107
+ `;await n$.appendFile(this.filePath,Z,"utf-8")}catch(Z){throw console.error(`[JSONLStore] 批量追加写入失败: ${this.filePath}`,Z),Z}}async readAll(){try{if(!_6.existsSync(this.filePath))return[];let Z=(await n$.readFile(this.filePath,"utf-8")).split(`
2108
+ `).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(!_6.existsSync(this.filePath)){Z();return}let Q=rw(this.filePath,"utf-8"),X=aw({input:Q,crlfDelay:Number.POSITIVE_INFINITY});X.on("line",async(J)=>{let G=J.trim();if(G.length===0)return;try{let q=JSON.parse(G);await $(q)}catch(q){console.warn(`[JSONLStore] 解析 JSON 行失败: ${G}`,q)}}),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(!_6.existsSync(this.filePath))return{exists:!1,size:0,lineCount:0};let $=await n$.stat(this.filePath),Y=(await n$.readFile(this.filePath,"utf-8")).split(`
2109
+ `).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 n$.access(this.filePath),!0}catch{return!1}}async delete(){try{if(await this.exists())await n$.unlink(this.filePath)}catch($){throw console.error(`[JSONLStore] 删除文件失败: ${this.filePath}`,$),$}}getFilePath(){return this.filePath}}var uq=()=>{};import{nanoid as H2}from"nanoid";import*as j2 from"node:fs/promises";import*as dq from"node:path";class cZ{projectPath;maxSessions;version;constructor($=process.cwd(),Z=100,Y="0.0.10"){this.projectPath=$,this.maxSessions=Z,this.version=Y}createEvent($,Z,Y){return{id:H2(),sessionId:Z,timestamp:new Date().toISOString(),type:$,cwd:this.projectPath,gitBranch:fJ(this.projectPath),version:this.version,data:Y}}async ensureSessionCreated($,Z){let Y=O1(this.projectPath,$),Q=new T1(Y);if((await Q.getStats()).lineCount>0)return;let J=new Date().toISOString(),G={sessionId:$,rootId:Z?.parentSessionId??$,parentId:Z?.parentSessionId,relationType:Z?"subagent":void 0,title:void 0,status:"running",agentType:Z?.subagentType,model:void 0,permission:void 0,createdAt:J,updatedAt:J},q=this.createEvent("session_created",$,G);await Q.append(q)}buildCompactionMetadata($){let Z={trigger:$.trigger,preTokens:$.preTokens};if($.postTokens!==void 0)Z.postTokens=$.postTokens;if($.filesIncluded)Z.filesIncluded=$.filesIncluded;return Z}async initialize(){try{let $=S3(this.projectPath);await j2.mkdir($,{recursive:!0,mode:493}),console.log(`[PersistentStore] 初始化存储目录: ${$}`)}catch($){console.warn("[PersistentStore] 无法创建持久化存储目录:",$)}}async saveMessage($,Z,Y,Q=null,X,J){try{let G=O1(this.projectPath,$),q=new T1(G);await this.ensureSessionCreated($,J);let K=new Date().toISOString(),W=H2(),U={messageId:W,role:Z,parentMessageId:Q??void 0,createdAt:K,model:X?.model,usage:X?.usage},O=this.createEvent("message_created",$,U),F={partId:H2(),messageId:W,partType:"text",payload:{text:Y},createdAt:K},H=this.createEvent("part_created",$,F);return await q.appendBatch([O,H]),W}catch(G){throw console.error(`[PersistentStore] 保存消息失败 (session: ${$}):`,G),G}}async saveToolUse($,Z,Y,Q=null,X){try{let J=O1(this.projectPath,$),G=new T1(J);await this.ensureSessionCreated($,X);let q=new Date().toISOString(),K=Q??H2(),W=[];if(!Q){let F={messageId:K,role:"assistant",parentMessageId:void 0,createdAt:q};W.push(this.createEvent("message_created",$,F))}let U=H2(),O={partId:U,messageId:K,partType:"tool_call",payload:{toolCallId:U,toolName:Z,input:Y},createdAt:q};if(W.push(this.createEvent("part_created",$,O)),Z==="Task"&&Y&&typeof Y==="object"){let F=Y,H=typeof F.subagent_session_id==="string"?F.subagent_session_id:void 0,_=typeof F.subagent_type==="string"?F.subagent_type:void 0;if(H&&_){let z={partId:H2(),messageId:K,partType:"subtask_ref",payload:{childSessionId:H,agentType:_,status:"running",summary:typeof F.description==="string"?F.description:"",startedAt:q},createdAt:q};W.push(this.createEvent("part_created",$,z))}}return await G.appendBatch(W),U}catch(J){throw console.error(`[PersistentStore] 保存工具调用失败 (session: ${$}):`,J),J}}async saveToolResult($,Z,Y,Q,X=null,J,G,q){try{let K=O1(this.projectPath,$),W=new T1(K);await this.ensureSessionCreated($,G);let U=new Date().toISOString(),O=X??H2(),F=[];if(!X){let _={messageId:O,role:"assistant",parentMessageId:void 0,createdAt:U};F.push(this.createEvent("message_created",$,_))}let H={partId:Z,messageId:O,partType:"tool_result",payload:{toolCallId:Z,toolName:Y,output:Q,error:J??null},createdAt:U};if(F.push(this.createEvent("part_created",$,H)),q){let _=q.subagentStatus==="running"?null:U,z={partId:H2(),messageId:O,partType:"subtask_ref",payload:{childSessionId:q.subagentSessionId,agentType:q.subagentType,status:q.subagentStatus,summary:q.subagentSummary??"",startedAt:U,finishedAt:_},createdAt:U};F.push(this.createEvent("part_created",$,z))}return await W.appendBatch(F),Z}catch(K){throw console.error(`[PersistentStore] 保存工具结果失败 (session: ${$}):`,K),K}}async saveCompaction($,Z,Y,Q=null){try{let X=O1(this.projectPath,$),J=new T1(X);await this.ensureSessionCreated($);let G=new Date().toISOString(),q=H2(),K={messageId:q,role:"system",parentMessageId:Q??void 0,createdAt:G},W=this.buildCompactionMetadata(Y),U={partId:H2(),messageId:q,partType:"summary",payload:{text:Z,metadata:W},createdAt:G},O=[this.createEvent("message_created",$,K),this.createEvent("part_created",$,U)];return await J.appendBatch(O),q}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=O1(this.projectPath,$),Q=await new T1(Z).readAll();if(Q.length===0)return null;let X=Q.find((J)=>J.type==="session_created");return{sessionId:$,userId:void 0,preferences:{},configuration:{},startTime:new Date(X?.timestamp??Q[0].timestamp).getTime()}}catch{return null}}async loadConversation($){try{let Z=O1(this.projectPath,$),Q=await new T1(Z).readAll();if(Q.length===0)return null;let X=new Map;for(let K of Q){if(K.type==="message_created")X.set(K.data.messageId,{id:K.data.messageId,role:K.data.role,content:"",timestamp:new Date(K.timestamp).getTime()});if(K.type==="part_created"&&K.data.partType==="text"){let W=X.get(K.data.messageId);if(W){let U=K.data.payload;W.content=U.text??""}}}let J=Array.from(X.values()),G=Q[Q.length-1],q=new Date(G.timestamp).getTime();return{messages:J,topics:[],lastActivity:q}}catch{return null}}async listSessions(){try{let $=S3(this.projectPath);return(await j2.readdir($)).filter((Y)=>Y.endsWith(".jsonl")).map((Y)=>Y.replace(".jsonl","")).sort()}catch{return[]}}async getSessionSummary($){try{let Z=O1(this.projectPath,$),Y=new T1(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],G=X.filter((q)=>q.type==="message_created"&&["user","assistant"].includes(q.data.role)).length;return{sessionId:$,lastActivity:new Date(J.timestamp).getTime(),messageCount:G,topics:[]}}catch{return null}}async deleteSession($){try{let Z=O1(this.projectPath,$);await new T1(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=O1(this.projectPath,Y),J=await new T1(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 $=S3(this.projectPath);await j2.mkdir($,{recursive:!0,mode:493});let Z=dq.join($,".health-check");return await j2.writeFile(Z,"test","utf-8"),await j2.unlink(Z),{isAvailable:!0,canWrite:!0}}catch($){return{isAvailable:!1,canWrite:!1,error:$ instanceof Error?$.message:String($)}}}static async listAllProjects(){return hJ()}}var cq=R(()=>{uq();k3()});import*as iq from"crypto";import{nanoid as lq}from"nanoid";class c3{memory;persistent;cache;compressor;filter;options;currentSessionId=null;initialized=!1;constructor($={}){let Z=$.storage?.persistentPath||k4();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 uZ(this.options.storage.maxMemorySize),this.persistent=new cZ(process.cwd(),100),this.cache=new gZ(this.options.storage.cacheSize,300000),this.compressor=new mZ,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,J){return this.persistent.saveMessage($,Z,Y,Q,X,J)}async saveToolUse($,Z,Y,Q=null,X){return this.persistent.saveToolUse($,Z,Y,Q,X)}async saveToolResult($,Z,Y,Q,X=null,J,G,q){return this.persistent.saveToolResult($,Z,Y,Q,X,J,G,q)}async saveCompaction($,Z,Y,Q=null){return this.persistent.saveCompaction($,Z,Y,Q)}updateToolState($,Z){if(!this.currentSessionId)throw Error("没有活动会话");this.memory.updateToolState($,Z)}updateWorkspace($){if(!this.currentSessionId)throw Error("没有活动会话");this.memory.updateWorkspace($)}async getFormattedContext($){let Z=this.memory.getContext();if(!Z)throw Error("没有可用的上下文数据");let Y=this.filter.filter(Z,$),Q=this.shouldCompress(Y),X;if(Q){let J=this.hashContext(Y);if(X=this.cache.getCompressedContext(J)??void 0,!X)X=await this.compressor.compress(Y),this.cache.cacheCompressedContext(J,X)}return{context:Y,compressed:X,tokenCount:X?X.tokenCount:Y.metadata.totalTokens}}async searchSessions($,Z=10){let Y=await this.persistent.listSessions(),Q=[];for(let X of Y){let J=await this.persistent.getSessionSummary(X);if(J){let G=this.calculateRelevance($,J.topics);if(G>0)Q.push({sessionId:X,summary:`${J.messageCount}条消息,主题:${J.topics.join("、")}`,lastActivity:J.lastActivity,relevanceScore:G})}}return Q.sort((X,J)=>J.relevanceScore-X.relevanceScore).slice(0,Z)}getCachedToolResult($,Z){return this.cache.getToolResult($,Z)}async getStats(){let[$,Z,Y]=await Promise.all([Promise.resolve(this.memory.getMemoryInfo()),Promise.resolve(this.cache.getStats()),this.persistent.getStorageStats()]);return{currentSession:this.currentSessionId,memory:$,cache:Z,storage:Y}}async cleanup(){if(this.currentSessionId)await this.saveCurrentSession();this.memory.clear(),this.cache.clear(),await this.persistent.cleanupOldSessions(),this.currentSessionId=null,console.log("上下文管理器资源清理完成")}generateSessionId(){return lq()}generateMessageId(){return lq()}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 iq.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 lZ=R(()=>{cq();k3()});class iZ{chatService;contextManager;memoryAdapter;constructor($,Z){this.chatService=$,this.contextManager=Z||new c3,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 rq=R(()=>{lZ()});import{nanoid as nw}from"nanoid";import*as aq from"os";import*as nq from"path";function ow($){if(typeof $==="string")return $;try{return JSON.parse(JSON.stringify($))}catch{return String($)}}class G${config;runtimeOptions;isInitialized=!1;activeTask;executionPipeline;chatService;executionEngine;attachmentCollector;activeSkillContext;currentModelMaxContextTokens;currentModelId;constructor($,Z={},Y){this.config=$,this.runtimeOptions=Z,this.executionPipeline=Y||this.createDefaultPipeline()}createDefaultPipeline(){let $=new F6,Z={...this.config.permissions,...this.runtimeOptions.permissions},Y=this.runtimeOptions.permissionMode??this.config.permissionMode??"default";return new pZ($,{permissionConfig:Z,permissionMode:Y,maxHistorySize:1000})}resolveModelConfig($){let Z=$&&$!=="inherit"?$:void 0,Y=Z?f5(Z):u2();if(!Y)throw Error(`❌ 模型配置未找到: ${Z??"current"}`);return Y}async applyModelConfig($,Z){this.log(`${Z} ${$.name} (${$.model})`);let Y=C8($),Q=ZX(),X=Y&&Q;if(Y&&!Q)this.log("\uD83E\uDDE0 模型支持 Thinking,但用户未开启(按 Tab 开启)");else if(X)this.log("\uD83E\uDDE0 Thinking 模式已启用,启用 reasoning_content 支持");this.currentModelMaxContextTokens=$.maxContextTokens??this.config.maxContextTokens,this.chatService=await P7({provider:$.provider,apiKey:$.apiKey,model:$.model,baseUrl:$.baseUrl,temperature:$.temperature??this.config.temperature,maxContextTokens:this.currentModelMaxContextTokens,maxOutputTokens:$.maxOutputTokens??this.config.maxOutputTokens,timeout:this.config.timeout,supportsThinking:X});let J=this.executionEngine?.getContextManager();this.executionEngine=new iZ(this.chatService,J),this.currentModelId=$.id}async switchModelIfNeeded($){if(!$||$===this.currentModelId)return;let Z=f5($);if(!Z){this.log(`⚠️ 模型配置未找到: ${$}`);return}await this.applyModelConfig(Z,"\uD83D\uDD01 切换模型")}static async create($={}){if(await m2(),g2().length===0)throw Error(`❌ 没有可用的模型配置
2110
2110
 
2111
2111
  `+`请先使用以下命令添加模型:
2112
2112
  `+` /model add
@@ -2119,11 +2119,11 @@ ${U}
2119
2119
  </approved-plan>
2120
2120
 
2121
2121
  IMPORTANT: Execute according to the approved plan above. Follow the steps exactly as specified.`;if(typeof Q==="string")F=Q+H;else F=[...Q,{type:"text",text:H}];f.debug(`\uD83D\uDCCB 已将 plan 内容注入到消息中 (${U.length} 字符)`)}return this.runLoop(F,O,q).then((H)=>{if(!H.success)throw Error(H.error?.message||"执行失败");return H.finalMessage||""})}return K.finalMessage||""}let X=typeof Q==="string"?Q:Q.filter((q)=>q.type==="text").map((q)=>q.text).join(`
2122
- `),J={id:this.generateTaskId(),type:"simple",prompt:X};return(await this.executeTask(J)).content}async runPlanLoop($,Z,Y){f.debug("\uD83D\uDD35 Processing Plan mode message...");let{prompt:Q}=await v3({projectPath:process.cwd(),mode:"plan",includeEnvironment:!0,language:this.config.language}),X;if(typeof $==="string")X=I3($);else{let J=$.filter((G)=>G.type==="text");if(J.length>0){let G=J[0];X=$.map((q)=>q===G?{type:"text",text:I3(G.text)}:q)}else X=[{type:"text",text:I3("")},...$]}return this.executeLoop(X,Z,Y,Q)}async runSpecLoop($,Z,Y){f.debug("\uD83D\uDD37 Processing Spec mode message...");let Q=x0.getInstance(),X=Z.workspaceRoot||process.cwd();try{await Q.initialize(X)}catch(U){f.warn("SpecManager initialization warning:",U)}let J=Q.getCurrentSpec(),G=await Q.getSteeringContextString(),q=d6(J,G),K,W=J?.phase||"init";if(typeof $==="string")K=`${c6(W)}
2122
+ `),J={id:this.generateTaskId(),type:"simple",prompt:X};return(await this.executeTask(J)).content}async runPlanLoop($,Z,Y){f.debug("\uD83D\uDD35 Processing Plan mode message...");let{prompt:Q}=await v3({projectPath:process.cwd(),mode:"plan",includeEnvironment:!0,language:this.config.language}),X;if(typeof $==="string")X=I3($);else{let J=$.filter((G)=>G.type==="text");if(J.length>0){let G=J[0];X=$.map((q)=>q===G?{type:"text",text:I3(G.text)}:q)}else X=[{type:"text",text:I3("")},...$]}return this.executeLoop(X,Z,Y,Q)}async runSpecLoop($,Z,Y){f.debug("\uD83D\uDD37 Processing Spec mode message...");let Q=x0.getInstance(),X=Z.workspaceRoot||process.cwd();try{await Q.initialize(X)}catch(U){f.warn("SpecManager initialization warning:",U)}let J=Q.getCurrentSpec(),G=await Q.getSteeringContextString(),q=d7(J,G),K,W=J?.phase||"init";if(typeof $==="string")K=`${c7(W)}
2123
2123
 
2124
- ${$}`;else{let U=$.filter((O)=>O.type==="text");if(U.length>0){let O=U[0];K=$.map((F)=>F===O?{type:"text",text:`${c6(W)}
2124
+ ${$}`;else{let U=$.filter((O)=>O.type==="text");if(U.length>0){let O=U[0];K=$.map((F)=>F===O?{type:"text",text:`${c7(W)}
2125
2125
 
2126
- ${O.text}`}:F)}else K=[{type:"text",text:c6(W)},...$]}return this.executeLoop(K,Z,Y,q)}async runLoop($,Z,Y){f.debug("\uD83D\uDCAC Processing enhanced chat message...");let Q=Z.systemPrompt??await this.buildSystemPromptOnDemand(),X=u6(),J=Q?`${X}
2126
+ ${O.text}`}:F)}else K=[{type:"text",text:c7(W)},...$]}return this.executeLoop(K,Z,Y,q)}async runLoop($,Z,Y){f.debug("\uD83D\uDCAC Processing enhanced chat message...");let Q=Z.systemPrompt??await this.buildSystemPromptOnDemand(),X=u7(),J=Q?`${X}
2127
2127
 
2128
2128
  ---
2129
2129
 
@@ -2170,8 +2170,8 @@ Please continue the conversation from where we left it off without asking the us
2170
2170
 
2171
2171
  ⚠️ Some files could not be loaded:
2172
2172
  `,X+=Q.join(`
2173
- `);return X}}var f;var F2=R(()=>{H8();R9();Y1();Q0();M9();ZJ();d2();wJ();MJ();C9();b9();K2();j1();M0();Cq();mq();gq();j$();P9();H7();rq();m4();f=x("Agent")});import{z as W0}from"zod";function tq($){return $L.safeParse($)}var sw,tw,ew,sq,oq,$L;var rZ=R(()=>{sw=W0.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"}),tw=W0.string().regex(/^\d+\.\d+\.\d+(-[\w.]+)?(\+[\w.]+)?$/,{message:"Version must be a valid semantic version (e.g., 1.0.0)"}),ew=W0.object({name:W0.string().min(1,"Author name is required"),email:W0.string().email().optional(),url:W0.string().url().optional()}),sq=W0.object({name:sw,description:W0.string().min(1,"Description is required").max(500,"Description must be at most 500 characters"),version:tw,author:ew.optional(),license:W0.string().optional(),repository:W0.string().url().optional(),homepage:W0.string().url().optional(),keywords:W0.array(W0.string()).optional(),dependencies:W0.record(W0.string()).optional(),bladeVersion:W0.string().optional()}),oq=W0.object({type:W0.enum(["stdio","sse","http"]),command:W0.string().optional(),args:W0.array(W0.string()).optional(),env:W0.record(W0.string()).optional(),url:W0.string().url().optional(),headers:W0.record(W0.string()).optional(),timeout:W0.number().positive().optional(),oauth:W0.object({enabled:W0.boolean().optional(),clientId:W0.string().optional(),clientSecret:W0.string().optional(),authorizationUrl:W0.string().url().optional(),tokenUrl:W0.string().url().optional(),scopes:W0.array(W0.string()).optional(),redirectUri:W0.string().url().optional()}).optional(),healthCheck:W0.object({enabled:W0.boolean().optional(),interval:W0.number().positive().optional(),timeout:W0.number().positive().optional(),failureThreshold:W0.number().positive().optional()}).optional()}),$L=W0.union([W0.object({mcpServers:W0.record(oq)}),W0.record(oq)])});import*as z7 from"node:fs/promises";import*as eq from"node:path";async function S8($){for(let{dir:Z,source:Y}of ZL){let Q=eq.join($,Z,"plugin.json");try{await z7.access(Q)}catch{continue}try{let X=await z7.readFile(Q,"utf-8"),J=JSON.parse(X),G=sq.safeParse(J);if(!G.success){let q=G.error.issues.map((K)=>`${K.path.join(".")}: ${K.message}`).join("; ");throw Error(`Invalid plugin.json: ${q}`)}return g0.debug(`Parsed plugin manifest from ${Q}`),{manifest:G.data,source:Y,manifestPath:Q}}catch(X){if(X instanceof SyntaxError)throw Error(`Invalid JSON in ${Q}: ${X.message}`);throw X}}return null}async function $K($){try{return await S8($)!==null}catch{return!1}}var ZL;var aZ=R(()=>{Q0();rZ();ZL=[{dir:".blade-plugin",source:"blade"},{dir:".claude-plugin",source:"claude"}]});import{execSync as ZK}from"node:child_process";import*as o$ from"node:fs/promises";import{homedir as YL}from"node:os";import*as k8 from"node:path";class YK{userPluginsDir;constructor($){this.userPluginsDir=$||k8.join(YL(),".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 o$.mkdir(this.userPluginsDir,{recursive:!0,mode:493});let Q=k8.join(this.userPluginsDir,Y);try{return await o$.access(Q),{success:!1,pluginName:Y,pluginPath:Q,error:`Plugin "${Y}" already exists at ${Q}. Use /plugins uninstall first.`}}catch{}g0.info(`Cloning ${Z} to ${Q}...`);try{ZK(`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 $K(Q))return await o$.rm(Q,{recursive:!0,force:!0}),{success:!1,pluginName:Y,error:"Invalid plugin: No .blade-plugin/plugin.json or .claude-plugin/plugin.json found"};let X;try{X=await S8(Q)}catch(J){return await o$.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 o$.rm(Q,{recursive:!0,force:!0}),{success:!1,pluginName:Y,error:"Invalid plugin manifest: No manifest found"};return g0.info(`Successfully installed plugin: ${X.manifest.name}`),{success:!0,pluginName:X.manifest.name,pluginPath:Q,manifest:X.manifest}}catch(Z){return{success:!1,error:`Installation failed: ${Z instanceof Error?Z.message:String(Z)}`}}}async uninstall($){try{let Z=k8.join(this.userPluginsDir,$);try{await o$.access(Z)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" not found at ${Z}`}}return await o$.rm(Z,{recursive:!0,force:!0}),g0.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 o$.access(this.userPluginsDir),(await o$.readdir(this.userPluginsDir,{withFileTypes:!0})).filter((Z)=>Z.isDirectory()).map((Z)=>Z.name)}catch{return[]}}async update($){try{let Z=k8.join(this.userPluginsDir,$);try{await o$.access(Z)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" not found at ${Z}`}}let Y=k8.join(Z,".git");try{await o$.access(Y)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" is not a git repository`}}g0.info(`Updating plugin: ${$}...`);try{ZK(`git -C "${Z}" pull --ff-only`,{stdio:"pipe",timeout:60000})}catch(X){return{success:!1,pluginName:$,error:`Failed to update: ${X instanceof Error?X.message:String(X)}`}}let Q;try{Q=await S8(Z)}catch(X){return{success:!1,pluginName:$,error:`Plugin manifest invalid after update: ${X instanceof Error?X.message:String(X)}`}}if(!Q)return{success:!1,pluginName:$,error:"Plugin manifest not found after update"};return g0.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 l3($){if(!nZ)nZ=new YK($);return nZ}var nZ=null;var QK=R(()=>{Q0();aZ()});function B7($,Z){return`${$}:${Z}`}function XK($,Z){return`${$}__${Z}`}import*as H1 from"node:fs/promises";import{homedir as QL}from"node:os";import*as B$ from"node:path";import JK from"gray-matter";class w7{async loadPlugin($,Z,Y={}){let Q=await S8($);if(!Q)throw Error(`Not a valid plugin directory: ${$}`);let{manifest:X,source:J}=Q,G=X.name;g0.debug(`Loading plugin "${G}" from ${$}`);let q=Y.skipCommands?[]:await this.loadCommands($,G),K=Y.skipAgents?[]:await this.loadAgents($,G),W=Y.skipSkills?[]:await this.loadSkills($,G),U=Y.skipHooks?void 0:await this.loadHooks($),O=Y.skipMcp?void 0:await this.loadMcpConfig($,G);return g0.debug(`Plugin "${G}" loaded: ${q.length} commands, ${K.length} agents, ${W.length} skills`),{manifest:X,basePath:$,source:Z,manifestSource:J,commands:q,agents:K,skills:W,hooks:U,mcpServers:O,status:"active",loadedAt:new Date}}async loadCommands($,Z){let Y=B$.join($,"commands"),Q=[];if(!await this.dirExists(Y))return Q;let X=await this.scanMarkdownFiles(Y);for(let J of X)try{let G=await this.parseCommandFile(J,Y,Z);if(G)Q.push(G)}catch(G){g0.warn(`Failed to load command from ${J}: ${G instanceof Error?G.message:String(G)}`)}return Q}async parseCommandFile($,Z,Y){let Q=await H1.readFile($,"utf-8"),{data:X,content:J}=JK(Q),q=B$.relative(Z,$).split(B$.sep),K=q.pop();if(!K)return null;let W=K.replace(/\.md$/i,""),U=W;if(q.length>0)U=[...q,W].join("/");let O=B7(Y,U),F=this.normalizeCommandConfig(X);return{originalName:U,namespacedName:O,pluginName:Y,config:F,content:J.trim(),path:$}}normalizeCommandConfig($){return{description:this.asString($.description),allowedTools:this.parseStringArray($["allowed-tools"]),argumentHint:this.asString($["argument-hint"]),model:this.asString($.model),disableModelInvocation:$["disable-model-invocation"]===!0}}async loadAgents($,Z){let Y=B$.join($,"agents"),Q=[];if(!await this.dirExists(Y))return Q;let X=await this.scanMarkdownFiles(Y);for(let J of X)try{let G=await this.parseAgentFile(J,Y,Z);if(G)Q.push(G)}catch(G){g0.warn(`Failed to load agent from ${J}: ${G instanceof Error?G.message:String(G)}`)}return Q}async parseAgentFile($,Z,Y){let Q=await H1.readFile($,"utf-8"),{data:X,content:J}=JK(Q),G=B$.relative(Z,$),q=B$.basename(G,".md"),K=X.name||q,W=B7(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=B$.join($,"skills"),Q=[];if(!await this.dirExists(Y))return Q;let X=await H1.readdir(Y,{withFileTypes:!0});for(let J of X){if(!J.isDirectory())continue;let G=B$.join(Y,J.name),q=B$.join(G,"SKILL.md");try{let K=await p6(q,"project");if(K.success&&K.content){let W=K.content.metadata.name,U=B7(Z,W);Q.push({originalName:W,namespacedName:U,pluginName:Z,metadata:{...K.content.metadata,name:U},path:G})}}catch(K){g0.warn(`Failed to load skill from ${q}: ${K instanceof Error?K.message:String(K)}`)}}return Q}async loadHooks($){let Z=B$.join($,"hooks","hooks.json");try{let Y=await H1.readFile(Z,"utf-8"),Q=JSON.parse(Y);return Q.hooks||Q}catch{return}}async loadMcpConfig($,Z){let Y=B$.join($,".mcp.json");try{let Q=await H1.readFile(Y,"utf-8"),X=JSON.parse(Q),J=tq(X);if(!J.success){g0.warn(`Invalid .mcp.json in ${$}: ${J.error}`);return}let G="mcpServers"in X?X.mcpServers:X,q={};for(let[K,W]of Object.entries(G)){let U=XK(Z,K);q[U]=W}return q}catch{return}}async scanMarkdownFiles($){let Z=[],Y=async(Q)=>{let X=await H1.readdir(Q,{withFileTypes:!0});for(let J of X){let G=B$.join(Q,J.name);if(J.isDirectory())await Y(G);else if(J.name.endsWith(".md"))Z.push(G)}};return await Y($),Z}async dirExists($){try{return(await H1.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=QL();return[{path:B$.join(Z,".claude","plugins"),source:"user",type:"claude"},{path:B$.join(Z,".blade","plugins"),source:"user",type:"blade"},{path:B$.join($,".claude","plugins"),source:"project",type:"claude"},{path:B$.join($,".blade","plugins"),source:"project",type:"blade"}]}async discoverPluginsInDir($,Z){let Y=[],Q=[];try{await H1.access($)}catch{return{plugins:Y,errors:Q}}let X=await H1.readdir($,{withFileTypes:!0});for(let J of X){if(!J.isDirectory())continue;let G=B$.join($,J.name);try{let q=await this.loadPlugin(G,Z);Y.push(q)}catch(q){Q.push({path:G,error:q instanceof Error?q.message:String(q)})}}return{plugins:Y,errors:Q}}}var GK=R(()=>{Q0();T9();aZ();rZ()});class c4{static instance=null;plugins=new Map;loader=new w7;initialized=!1;workspaceRoot="";cliPluginDirs=[];constructor(){}static getInstance(){if(!c4.instance)c4.instance=new c4;return c4.instance}static resetInstance(){c4.instance=null}async initialize($,Z=[]){this.workspaceRoot=$,this.cliPluginDirs=Z;let Y=[],Q=[];for(let J of Z)try{let G=await this.loader.loadPlugin(J,"cli");this.plugins.set(G.manifest.name,G),Y.push(G),g0.info(`Loaded CLI plugin: ${G.manifest.name} from ${J}`)}catch(G){Q.push({path:J,error:G instanceof Error?G.message:String(G)}),g0.warn(`Failed to load CLI plugin from ${J}: ${G}`)}let X=w7.getPluginDirs($);for(let{path:J,source:G}of X){let q=await this.loader.discoverPluginsInDir(J,G);for(let K of q.plugins){let W=this.plugins.get(K.manifest.name);if(!W||W.source!=="cli")this.plugins.set(K.manifest.name,K),Y.push(K)}Q.push(...q.errors)}return this.initialized=!0,g0.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",g0.info(`Plugin "${$}" disabled`),!0;return!1}enable($){let Z=this.plugins.get($);if(Z&&Z.status==="inactive")return Z.status="active",g0.info(`Plugin "${$}" enabled`),!0;return!1}async refresh(){return g0.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(`
2174
- `)}}function s$(){return c4.getInstance()}var oZ=R(()=>{Q0();GK()});class sZ{commandRegistry;hookManager;mcpRegistry;constructor(){this.commandRegistry=A$.getInstance(),this.hookManager=y0.getInstance(),this.mcpRegistry=e0.getInstance()}clearAllPluginResources(){this.commandRegistry.clearPluginCommands(),J$().clearPluginSkills(),Y$.clearPluginAgents(),g0.debug("Cleared all plugin resources from subsystems")}async integrateAll(){let Z=s$().getActive(),Y=[],Q=[],X=0,J=0,G=0,q=0;for(let K of Z){let W=await this.integratePlugin(K);Y.push(W),X+=W.commandsRegistered,J+=W.skillsRegistered,G+=W.agentsRegistered,q+=W.mcpServersRegistered,Q.push(...W.errors)}if(X+J+G>0)g0.info(`Plugin integration complete: ${X} commands, ${J} skills, ${G} agents, ${q} MCP servers`);return{plugins:Y,totalCommands:X,totalSkills:J,totalAgents:G,totalMcpServers:q,errors:Q}}async integratePlugin($){let Z={pluginName:$.manifest.name,commandsRegistered:0,skillsRegistered:0,agentsRegistered:0,hooksRegistered:!1,mcpServersRegistered:0,errors:[]};try{Z.commandsRegistered=this.integrateCommands($)}catch(Y){Z.errors.push(`Failed to integrate commands: ${Y instanceof Error?Y.message:String(Y)}`)}try{Z.skillsRegistered=this.integrateSkills($)}catch(Y){Z.errors.push(`Failed to integrate skills: ${Y instanceof Error?Y.message:String(Y)}`)}try{Z.agentsRegistered=this.integrateAgents($)}catch(Y){Z.errors.push(`Failed to integrate agents: ${Y instanceof Error?Y.message:String(Y)}`)}try{Z.hooksRegistered=this.integrateHooks($)}catch(Y){Z.errors.push(`Failed to integrate hooks: ${Y instanceof Error?Y.message:String(Y)}`)}try{Z.mcpServersRegistered=await this.integrateMcp($)}catch(Y){Z.errors.push(`Failed to integrate MCP servers: ${Y instanceof Error?Y.message:String(Y)}`)}return g0.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=J$(),Y=0;for(let Q of $.skills)Z.registerPluginSkill(Q),Y++;return Y}integrateAgents($){let Z=0;for(let Y of $.agents)Y$.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){g0.warn(`Failed to register MCP server "${Y}" from plugin "${$.manifest.name}": ${X instanceof Error?X.message:String(X)}`)}return Z}}async function Y4(){return new sZ().integrateAll()}function L7(){new sZ().clearAllPluginResources()}var qK=R(()=>{m4();Y1();Q0();d2();K2();zZ();oZ()});var f8=R(()=>{QK();qK();oZ()});function p0($){if($.acp)return{sendMessage:(Z)=>$.acp.sendMessage(`• ${Z}
2173
+ `);return X}}var f;var F2=R(()=>{H8();R9();Y1();Q0();M9();ZJ();d2();wJ();MJ();C9();b9();K2();j1();M0();Cq();mq();gq();j$();P9();H6();rq();m4();f=x("Agent")});import{z as W0}from"zod";function tq($){return $L.safeParse($)}var sw,tw,ew,sq,oq,$L;var rZ=R(()=>{sw=W0.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"}),tw=W0.string().regex(/^\d+\.\d+\.\d+(-[\w.]+)?(\+[\w.]+)?$/,{message:"Version must be a valid semantic version (e.g., 1.0.0)"}),ew=W0.object({name:W0.string().min(1,"Author name is required"),email:W0.string().email().optional(),url:W0.string().url().optional()}),sq=W0.object({name:sw,description:W0.string().min(1,"Description is required").max(500,"Description must be at most 500 characters"),version:tw,author:ew.optional(),license:W0.string().optional(),repository:W0.string().url().optional(),homepage:W0.string().url().optional(),keywords:W0.array(W0.string()).optional(),dependencies:W0.record(W0.string()).optional(),bladeVersion:W0.string().optional()}),oq=W0.object({type:W0.enum(["stdio","sse","http"]),command:W0.string().optional(),args:W0.array(W0.string()).optional(),env:W0.record(W0.string()).optional(),url:W0.string().url().optional(),headers:W0.record(W0.string()).optional(),timeout:W0.number().positive().optional(),oauth:W0.object({enabled:W0.boolean().optional(),clientId:W0.string().optional(),clientSecret:W0.string().optional(),authorizationUrl:W0.string().url().optional(),tokenUrl:W0.string().url().optional(),scopes:W0.array(W0.string()).optional(),redirectUri:W0.string().url().optional()}).optional(),healthCheck:W0.object({enabled:W0.boolean().optional(),interval:W0.number().positive().optional(),timeout:W0.number().positive().optional(),failureThreshold:W0.number().positive().optional()}).optional()}),$L=W0.union([W0.object({mcpServers:W0.record(oq)}),W0.record(oq)])});import*as z6 from"node:fs/promises";import*as eq from"node:path";async function S8($){for(let{dir:Z,source:Y}of ZL){let Q=eq.join($,Z,"plugin.json");try{await z6.access(Q)}catch{continue}try{let X=await z6.readFile(Q,"utf-8"),J=JSON.parse(X),G=sq.safeParse(J);if(!G.success){let q=G.error.issues.map((K)=>`${K.path.join(".")}: ${K.message}`).join("; ");throw Error(`Invalid plugin.json: ${q}`)}return g0.debug(`Parsed plugin manifest from ${Q}`),{manifest:G.data,source:Y,manifestPath:Q}}catch(X){if(X instanceof SyntaxError)throw Error(`Invalid JSON in ${Q}: ${X.message}`);throw X}}return null}async function $K($){try{return await S8($)!==null}catch{return!1}}var ZL;var aZ=R(()=>{Q0();rZ();ZL=[{dir:".blade-plugin",source:"blade"},{dir:".claude-plugin",source:"claude"}]});import{execSync as ZK}from"node:child_process";import*as o$ from"node:fs/promises";import{homedir as YL}from"node:os";import*as k8 from"node:path";class YK{userPluginsDir;constructor($){this.userPluginsDir=$||k8.join(YL(),".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 o$.mkdir(this.userPluginsDir,{recursive:!0,mode:493});let Q=k8.join(this.userPluginsDir,Y);try{return await o$.access(Q),{success:!1,pluginName:Y,pluginPath:Q,error:`Plugin "${Y}" already exists at ${Q}. Use /plugins uninstall first.`}}catch{}g0.info(`Cloning ${Z} to ${Q}...`);try{ZK(`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 $K(Q))return await o$.rm(Q,{recursive:!0,force:!0}),{success:!1,pluginName:Y,error:"Invalid plugin: No .blade-plugin/plugin.json or .claude-plugin/plugin.json found"};let X;try{X=await S8(Q)}catch(J){return await o$.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 o$.rm(Q,{recursive:!0,force:!0}),{success:!1,pluginName:Y,error:"Invalid plugin manifest: No manifest found"};return g0.info(`Successfully installed plugin: ${X.manifest.name}`),{success:!0,pluginName:X.manifest.name,pluginPath:Q,manifest:X.manifest}}catch(Z){return{success:!1,error:`Installation failed: ${Z instanceof Error?Z.message:String(Z)}`}}}async uninstall($){try{let Z=k8.join(this.userPluginsDir,$);try{await o$.access(Z)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" not found at ${Z}`}}return await o$.rm(Z,{recursive:!0,force:!0}),g0.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 o$.access(this.userPluginsDir),(await o$.readdir(this.userPluginsDir,{withFileTypes:!0})).filter((Z)=>Z.isDirectory()).map((Z)=>Z.name)}catch{return[]}}async update($){try{let Z=k8.join(this.userPluginsDir,$);try{await o$.access(Z)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" not found at ${Z}`}}let Y=k8.join(Z,".git");try{await o$.access(Y)}catch{return{success:!1,pluginName:$,error:`Plugin "${$}" is not a git repository`}}g0.info(`Updating plugin: ${$}...`);try{ZK(`git -C "${Z}" pull --ff-only`,{stdio:"pipe",timeout:60000})}catch(X){return{success:!1,pluginName:$,error:`Failed to update: ${X instanceof Error?X.message:String(X)}`}}let Q;try{Q=await S8(Z)}catch(X){return{success:!1,pluginName:$,error:`Plugin manifest invalid after update: ${X instanceof Error?X.message:String(X)}`}}if(!Q)return{success:!1,pluginName:$,error:"Plugin manifest not found after update"};return g0.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 l3($){if(!nZ)nZ=new YK($);return nZ}var nZ=null;var QK=R(()=>{Q0();aZ()});function B6($,Z){return`${$}:${Z}`}function XK($,Z){return`${$}__${Z}`}import*as H1 from"node:fs/promises";import{homedir as QL}from"node:os";import*as B$ from"node:path";import JK from"gray-matter";class w6{async loadPlugin($,Z,Y={}){let Q=await S8($);if(!Q)throw Error(`Not a valid plugin directory: ${$}`);let{manifest:X,source:J}=Q,G=X.name;g0.debug(`Loading plugin "${G}" from ${$}`);let q=Y.skipCommands?[]:await this.loadCommands($,G),K=Y.skipAgents?[]:await this.loadAgents($,G),W=Y.skipSkills?[]:await this.loadSkills($,G),U=Y.skipHooks?void 0:await this.loadHooks($),O=Y.skipMcp?void 0:await this.loadMcpConfig($,G);return g0.debug(`Plugin "${G}" loaded: ${q.length} commands, ${K.length} agents, ${W.length} skills`),{manifest:X,basePath:$,source:Z,manifestSource:J,commands:q,agents:K,skills:W,hooks:U,mcpServers:O,status:"active",loadedAt:new Date}}async loadCommands($,Z){let Y=B$.join($,"commands"),Q=[];if(!await this.dirExists(Y))return Q;let X=await this.scanMarkdownFiles(Y);for(let J of X)try{let G=await this.parseCommandFile(J,Y,Z);if(G)Q.push(G)}catch(G){g0.warn(`Failed to load command from ${J}: ${G instanceof Error?G.message:String(G)}`)}return Q}async parseCommandFile($,Z,Y){let Q=await H1.readFile($,"utf-8"),{data:X,content:J}=JK(Q),q=B$.relative(Z,$).split(B$.sep),K=q.pop();if(!K)return null;let W=K.replace(/\.md$/i,""),U=W;if(q.length>0)U=[...q,W].join("/");let O=B6(Y,U),F=this.normalizeCommandConfig(X);return{originalName:U,namespacedName:O,pluginName:Y,config:F,content:J.trim(),path:$}}normalizeCommandConfig($){return{description:this.asString($.description),allowedTools:this.parseStringArray($["allowed-tools"]),argumentHint:this.asString($["argument-hint"]),model:this.asString($.model),disableModelInvocation:$["disable-model-invocation"]===!0}}async loadAgents($,Z){let Y=B$.join($,"agents"),Q=[];if(!await this.dirExists(Y))return Q;let X=await this.scanMarkdownFiles(Y);for(let J of X)try{let G=await this.parseAgentFile(J,Y,Z);if(G)Q.push(G)}catch(G){g0.warn(`Failed to load agent from ${J}: ${G instanceof Error?G.message:String(G)}`)}return Q}async parseAgentFile($,Z,Y){let Q=await H1.readFile($,"utf-8"),{data:X,content:J}=JK(Q),G=B$.relative(Z,$),q=B$.basename(G,".md"),K=X.name||q,W=B6(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=B$.join($,"skills"),Q=[];if(!await this.dirExists(Y))return Q;let X=await H1.readdir(Y,{withFileTypes:!0});for(let J of X){if(!J.isDirectory())continue;let G=B$.join(Y,J.name),q=B$.join(G,"SKILL.md");try{let K=await p7(q,"project");if(K.success&&K.content){let W=K.content.metadata.name,U=B6(Z,W);Q.push({originalName:W,namespacedName:U,pluginName:Z,metadata:{...K.content.metadata,name:U},path:G})}}catch(K){g0.warn(`Failed to load skill from ${q}: ${K instanceof Error?K.message:String(K)}`)}}return Q}async loadHooks($){let Z=B$.join($,"hooks","hooks.json");try{let Y=await H1.readFile(Z,"utf-8"),Q=JSON.parse(Y);return Q.hooks||Q}catch{return}}async loadMcpConfig($,Z){let Y=B$.join($,".mcp.json");try{let Q=await H1.readFile(Y,"utf-8"),X=JSON.parse(Q),J=tq(X);if(!J.success){g0.warn(`Invalid .mcp.json in ${$}: ${J.error}`);return}let G="mcpServers"in X?X.mcpServers:X,q={};for(let[K,W]of Object.entries(G)){let U=XK(Z,K);q[U]=W}return q}catch{return}}async scanMarkdownFiles($){let Z=[],Y=async(Q)=>{let X=await H1.readdir(Q,{withFileTypes:!0});for(let J of X){let G=B$.join(Q,J.name);if(J.isDirectory())await Y(G);else if(J.name.endsWith(".md"))Z.push(G)}};return await Y($),Z}async dirExists($){try{return(await H1.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=QL();return[{path:B$.join(Z,".claude","plugins"),source:"user",type:"claude"},{path:B$.join(Z,".blade","plugins"),source:"user",type:"blade"},{path:B$.join($,".claude","plugins"),source:"project",type:"claude"},{path:B$.join($,".blade","plugins"),source:"project",type:"blade"}]}async discoverPluginsInDir($,Z){let Y=[],Q=[];try{await H1.access($)}catch{return{plugins:Y,errors:Q}}let X=await H1.readdir($,{withFileTypes:!0});for(let J of X){if(!J.isDirectory())continue;let G=B$.join($,J.name);try{let q=await this.loadPlugin(G,Z);Y.push(q)}catch(q){Q.push({path:G,error:q instanceof Error?q.message:String(q)})}}return{plugins:Y,errors:Q}}}var GK=R(()=>{Q0();T9();aZ();rZ()});class c4{static instance=null;plugins=new Map;loader=new w6;initialized=!1;workspaceRoot="";cliPluginDirs=[];constructor(){}static getInstance(){if(!c4.instance)c4.instance=new c4;return c4.instance}static resetInstance(){c4.instance=null}async initialize($,Z=[]){this.workspaceRoot=$,this.cliPluginDirs=Z;let Y=[],Q=[];for(let J of Z)try{let G=await this.loader.loadPlugin(J,"cli");this.plugins.set(G.manifest.name,G),Y.push(G),g0.info(`Loaded CLI plugin: ${G.manifest.name} from ${J}`)}catch(G){Q.push({path:J,error:G instanceof Error?G.message:String(G)}),g0.warn(`Failed to load CLI plugin from ${J}: ${G}`)}let X=w6.getPluginDirs($);for(let{path:J,source:G}of X){let q=await this.loader.discoverPluginsInDir(J,G);for(let K of q.plugins){let W=this.plugins.get(K.manifest.name);if(!W||W.source!=="cli")this.plugins.set(K.manifest.name,K),Y.push(K)}Q.push(...q.errors)}return this.initialized=!0,g0.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",g0.info(`Plugin "${$}" disabled`),!0;return!1}enable($){let Z=this.plugins.get($);if(Z&&Z.status==="inactive")return Z.status="active",g0.info(`Plugin "${$}" enabled`),!0;return!1}async refresh(){return g0.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(`
2174
+ `)}}function s$(){return c4.getInstance()}var oZ=R(()=>{Q0();GK()});class sZ{commandRegistry;hookManager;mcpRegistry;constructor(){this.commandRegistry=A$.getInstance(),this.hookManager=y0.getInstance(),this.mcpRegistry=e0.getInstance()}clearAllPluginResources(){this.commandRegistry.clearPluginCommands(),J$().clearPluginSkills(),Y$.clearPluginAgents(),g0.debug("Cleared all plugin resources from subsystems")}async integrateAll(){let Z=s$().getActive(),Y=[],Q=[],X=0,J=0,G=0,q=0;for(let K of Z){let W=await this.integratePlugin(K);Y.push(W),X+=W.commandsRegistered,J+=W.skillsRegistered,G+=W.agentsRegistered,q+=W.mcpServersRegistered,Q.push(...W.errors)}if(X+J+G>0)g0.info(`Plugin integration complete: ${X} commands, ${J} skills, ${G} agents, ${q} MCP servers`);return{plugins:Y,totalCommands:X,totalSkills:J,totalAgents:G,totalMcpServers:q,errors:Q}}async integratePlugin($){let Z={pluginName:$.manifest.name,commandsRegistered:0,skillsRegistered:0,agentsRegistered:0,hooksRegistered:!1,mcpServersRegistered:0,errors:[]};try{Z.commandsRegistered=this.integrateCommands($)}catch(Y){Z.errors.push(`Failed to integrate commands: ${Y instanceof Error?Y.message:String(Y)}`)}try{Z.skillsRegistered=this.integrateSkills($)}catch(Y){Z.errors.push(`Failed to integrate skills: ${Y instanceof Error?Y.message:String(Y)}`)}try{Z.agentsRegistered=this.integrateAgents($)}catch(Y){Z.errors.push(`Failed to integrate agents: ${Y instanceof Error?Y.message:String(Y)}`)}try{Z.hooksRegistered=this.integrateHooks($)}catch(Y){Z.errors.push(`Failed to integrate hooks: ${Y instanceof Error?Y.message:String(Y)}`)}try{Z.mcpServersRegistered=await this.integrateMcp($)}catch(Y){Z.errors.push(`Failed to integrate MCP servers: ${Y instanceof Error?Y.message:String(Y)}`)}return g0.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=J$(),Y=0;for(let Q of $.skills)Z.registerPluginSkill(Q),Y++;return Y}integrateAgents($){let Z=0;for(let Y of $.agents)Y$.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){g0.warn(`Failed to register MCP server "${Y}" from plugin "${$.manifest.name}": ${X instanceof Error?X.message:String(X)}`)}return Z}}async function Y4(){return new sZ().integrateAll()}function L6(){new sZ().clearAllPluginResources()}var qK=R(()=>{m4();Y1();Q0();d2();K2();zZ();oZ()});var f8=R(()=>{QK();qK();oZ()});function p0($){if($.acp)return{sendMessage:(Z)=>$.acp.sendMessage(`• ${Z}
2175
2175
 
2176
2176
  `),sendToolStart:$.acp.sendToolStart,sendToolResult:$.acp.sendToolResult};return{sendMessage:(Z)=>_0().addAssistantMessage(Z),sendToolStart:void 0,sendToolResult:void 0}}var o1=R(()=>{M0()});import XL from"node:os";import KK from"node:path";var WK;var UK=R(()=>{m4();o1();WK={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=p0(Z);if(!Y)return{success:!0,message:"show_agents_manager",data:{action:"show_agents_manager"}};if(Y==="list"){let J=Y$.getAllNames().map((O)=>Y$.getSubagent(O)).filter((O)=>O!==void 0);if(J.length===0){let O=`\uD83D\uDCCB **Agents 管理**
2177
2177
 
@@ -2240,7 +2240,7 @@ Please continue the conversation from where we left it off without asking the us
2240
2240
  • 压缩后: ${F.postTokens.toLocaleString()} tokens
2241
2241
 
2242
2242
  \uD83D\uDCA1 由于压缩过程出现错误,已使用简单截断策略。
2243
- 错误信息: ${F.error}`),{success:!1,message:"compact_fallback",error:F.error,data:{compactedMessages:F.compactedMessages,boundaryMessage:F.boundaryMessage,summaryMessage:F.summaryMessage,preTokens:F.preTokens,postTokens:F.postTokens}}}catch(Q){let X=Q instanceof Error?Q.message:String(Q);return Y.sendMessage(`❌ **压缩失败**: ${X}`),{success:!1,error:X}}}var GL,OK;var FK=R(()=>{R9();lZ();S6();M0();o1();GL={name:"compact",description:"手动压缩当前会话的上下文",fullDescription:"压缩当前对话历史,生成详细的技术总结,保留最近的消息。压缩后的上下文可以节省 token 使用量,同时保留关键信息。",usage:"/compact",examples:["/compact"],category:"context",handler:JL},OK=GL});function _K($){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 qL($){let Z=e0.getInstance(),Y=R1();if(Object.keys(Y).length===0){$.sendMessage(`\uD83D\uDD0C **MCP 服务器状态**
2243
+ 错误信息: ${F.error}`),{success:!1,message:"compact_fallback",error:F.error,data:{compactedMessages:F.compactedMessages,boundaryMessage:F.boundaryMessage,summaryMessage:F.summaryMessage,preTokens:F.preTokens,postTokens:F.postTokens}}}catch(Q){let X=Q instanceof Error?Q.message:String(Q);return Y.sendMessage(`❌ **压缩失败**: ${X}`),{success:!1,error:X}}}var GL,OK;var FK=R(()=>{R9();lZ();S7();M0();o1();GL={name:"compact",description:"手动压缩当前会话的上下文",fullDescription:"压缩当前对话历史,生成详细的技术总结,保留最近的消息。压缩后的上下文可以节省 token 使用量,同时保留关键信息。",usage:"/compact",examples:["/compact"],category:"context",handler:JL},OK=GL});function _K($){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 qL($){let Z=e0.getInstance(),Y=R1();if(Object.keys(Y).length===0){$.sendMessage(`\uD83D\uDD0C **MCP 服务器状态**
2244
2244
 
2245
2245
  ⚠️ 暂无配置的 MCP 服务器
2246
2246
 
@@ -2310,11 +2310,11 @@ Please continue the conversation from where we left it off without asking the us
2310
2310
 
2311
2311
  `;continue}G+=U.length;for(let O of U){if(J+=` • ${O.name}`,O.description){let F=O.description.length>60?O.description.substring(0,57)+"...":O.description;J+=` - ${F}`}J+=`
2312
2312
  `}J+=`
2313
- `}J+=`**总计:** ${G} 个工具可用`,$.sendMessage(J)}var FL,zK;var BK=R(()=>{d2();T4();M0();o1();FL={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=p0(Z);try{if(console.log("[MCP Command] Received args:",$),$.length===0)return await qL(Y),{success:!0,message:"MCP 服务器概览已显示"};let Q=$[0];if(console.log("[MCP Command] Subcommand:",Q),Q==="tools")return await OL(Y),{success:!0,message:"MCP 工具列表已显示"};return await WL(Y,Q),{success:!0,message:`服务器 "${Q}" 详情已显示`}}catch(Q){return{success:!1,error:`显示 MCP 信息失败: ${Q instanceof Error?Q.message:"未知错误"}`}}}},zK=FL});async function HL($,Z){return{success:!0,message:"show_permissions_editor",data:{action:"show_permissions_editor"}}}var _L,N7;var tZ=R(()=>{_L={name:"permissions",description:"管理项目的本地权限规则",fullDescription:"打开权限管理器,管理 .blade/settings.local.json 中的权限规则",usage:"/permissions",aliases:["perm"],category:"ui",handler:HL},N7=_L});import{readdir as wK,readFile as LK,rm as zL}from"node:fs/promises";import*as A7 from"node:path";class S${static async listSessions(){let $=[],Z=A7.join(k4(),"projects");try{let Y=await wK(Z,{withFileTypes:!0});for(let Q of Y){if(!Q.isDirectory())continue;let X=A7.join(Z,Q.name),J=kJ(Q.name),q=(await wK(X)).filter((K)=>K.endsWith(".jsonl"));for(let K of q){let W=A7.join(X,K),U=K.replace(".jsonl","");try{let O=await this.extractMetadata(W,U,J);$.push(O)}catch(O){eZ.warn(`[SessionService] 跳过损坏的会话文件: ${W}`,O)}}}return $.sort((Q,X)=>new Date(X.lastMessageTime).getTime()-new Date(Q.lastMessageTime).getTime()),$}catch(Y){return eZ.error("[SessionService] 列出会话失败:",Y),[]}}static async extractMetadata($,Z,Y){let X=(await LK($,"utf-8")).trim().split(`
2313
+ `}J+=`**总计:** ${G} 个工具可用`,$.sendMessage(J)}var FL,zK;var BK=R(()=>{d2();T4();M0();o1();FL={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=p0(Z);try{if(console.log("[MCP Command] Received args:",$),$.length===0)return await qL(Y),{success:!0,message:"MCP 服务器概览已显示"};let Q=$[0];if(console.log("[MCP Command] Subcommand:",Q),Q==="tools")return await OL(Y),{success:!0,message:"MCP 工具列表已显示"};return await WL(Y,Q),{success:!0,message:`服务器 "${Q}" 详情已显示`}}catch(Q){return{success:!1,error:`显示 MCP 信息失败: ${Q instanceof Error?Q.message:"未知错误"}`}}}},zK=FL});async function HL($,Z){return{success:!0,message:"show_permissions_editor",data:{action:"show_permissions_editor"}}}var _L,N6;var tZ=R(()=>{_L={name:"permissions",description:"管理项目的本地权限规则",fullDescription:"打开权限管理器,管理 .blade/settings.local.json 中的权限规则",usage:"/permissions",aliases:["perm"],category:"ui",handler:HL},N6=_L});import{readdir as wK,readFile as LK,rm as zL}from"node:fs/promises";import*as A6 from"node:path";class S${static async listSessions(){let $=[],Z=A6.join(k4(),"projects");try{let Y=await wK(Z,{withFileTypes:!0});for(let Q of Y){if(!Q.isDirectory())continue;let X=A6.join(Z,Q.name),J=kJ(Q.name),q=(await wK(X)).filter((K)=>K.endsWith(".jsonl"));for(let K of q){let W=A6.join(X,K),U=K.replace(".jsonl","");try{let O=await this.extractMetadata(W,U,J);$.push(O)}catch(O){eZ.warn(`[SessionService] 跳过损坏的会话文件: ${W}`,O)}}}return $.sort((Q,X)=>new Date(X.lastMessageTime).getTime()-new Date(Q.lastMessageTime).getTime()),$}catch(Y){return eZ.error("[SessionService] 列出会话失败:",Y),[]}}static async extractMetadata($,Z,Y){let X=(await LK($,"utf-8")).trim().split(`
2314
2314
  `).filter((O)=>O.trim());if(X.length===0)throw Error("空的 JSONL 文件");let J=X.map((O)=>JSON.parse(O)),G=J[0],q=J[J.length-1],K=J.find((O)=>O.type==="session_created"),W=J.filter((O)=>O.type==="message_created"&&["user","assistant"].includes(O.data.role)).length,U=J.some((O)=>O.type==="part_created"&&O.data.partType==="tool_result"&&typeof O.data.payload.error==="string");return{sessionId:Z,projectPath:Y,gitBranch:K?.gitBranch??G.gitBranch,parentId:K?.data.parentId,relationType:K?.data.relationType,status:K?.data.status,agentType:K?.data.agentType,model:K?.data.model,messageCount:W,firstMessageTime:G.timestamp,lastMessageTime:q.timestamp,hasErrors:U,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 eZ.error(`[SessionService] 加载会话失败 (${$}):`,Y),Y}}static async deleteSession($){let Y=(await this.listSessions()).filter((Q)=>Q.sessionId===$);if(Y.length===0)return 0;return await Promise.all(Y.map((Q)=>zL(Q.filePath,{force:!0}))),Y.length}static async loadSessionFromFile($){let Q=(await LK($,"utf-8")).trim().split(`
2315
2315
  `).filter((X)=>X.trim()).map((X)=>JSON.parse(X));return this.convertJSONLToMessages(Q)}static convertJSONLToMessages($){let Z=[],Y=new Map;for(let Q of $){if(Q.type==="message_created"){let X={role:Q.data.role,content:""};Y.set(Q.data.messageId,X),Z.push(X)}if(Q.type==="part_created"){if(Q.data.partType==="text"){let X=Y.get(Q.data.messageId);if(X){let J=Q.data.payload;X.content=J.text??""}}if(Q.data.partType==="tool_result"){let X=Q.data.payload,J=typeof X.error==="string"?`Error: ${X.error}`:typeof X.output==="string"?X.output:JSON.stringify(X.output??""),G=X;Z.push({role:"tool",content:J,tool_call_id:X.toolCallId,name:X.toolName,metadata:G})}if(Q.data.partType==="summary"){let X=Q.data.payload,J=Q.data.payload;Z.push({role:"system",content:X.text??"",metadata:J})}if(Q.data.partType==="subtask_ref"){let X=Y.get(Q.data.messageId);if(X){let J=Q.data.payload,G=X.metadata??{};X.metadata={...G,subtaskRef:J}}}}}return Z}static getSessionFilePath($,Z){return O1($,Z)}}var eZ;var i3=R(()=>{k3();Q0();eZ=x("Service")});var BL,NK;var AK=R(()=>{i3();M0();o1();BL={name:"resume",description:"Resume a conversation",fullDescription:"恢复历史会话。可以指定 sessionId 直接恢复,或不带参数打开会话选择器",usage:"/resume [sessionId]",aliases:["r"],category:"Session",examples:["/resume - 打开会话选择器","/resume abc123xyz - 直接恢复指定的会话"],async handler($,Z){let Y=p0(Z),Q=_0().restoreSession;if($.length>0){let X=$[0];try{let J=await S$.loadSession(X);if(J.length===0)return Y.sendMessage(`❌ 会话 \`${X}\` 为空或无法加载`),{success:!1,error:"会话为空"};let G=J.filter((q)=>q.role!=="tool").map((q,K)=>({id:`restored-${Date.now()}-${K}`,role:q.role,content:typeof q.content==="string"?q.content:JSON.stringify(q.content),timestamp:Date.now()-(J.length-K)*1000}));return Q(X,G),Y.sendMessage(`✅ 已恢复会话 \`${X}\`
2316
2316
 
2317
- 共 ${G.length} 条消息已加载,可以继续对话`),{success:!0,message:"session_restored",data:{sessionId:X,messageCount:G.length}}}catch(J){let G=J instanceof Error?J.message:"未知错误";return Y.sendMessage(`❌ 加载会话失败: ${G}`),{success:!1,error:`加载会话失败: ${G}`}}}try{let X=await S$.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}`}}}},NK=BL});import bK from"node:fs/promises";import RK from"node:path";var wL,LL,NL,AL,bL,RL,VK;var MK=R(()=>{S6();M0();x2();UK();FK();q7();BK();tZ();AK();o1();wL={name:"help",description:"Show all available slash commands",fullDescription:"显示所有可用的 slash commands 及其使用方法",usage:"/help",aliases:["h"],async handler($,Z){let Y=p0(Z),Q=`\uD83D\uDD27 **可用的 Slash Commands:**
2317
+ 共 ${G.length} 条消息已加载,可以继续对话`),{success:!0,message:"session_restored",data:{sessionId:X,messageCount:G.length}}}catch(J){let G=J instanceof Error?J.message:"未知错误";return Y.sendMessage(`❌ 加载会话失败: ${G}`),{success:!1,error:`加载会话失败: ${G}`}}}try{let X=await S$.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}`}}}},NK=BL});import bK from"node:fs/promises";import RK from"node:path";var wL,LL,NL,AL,bL,RL,VK;var MK=R(()=>{S7();M0();x2();UK();FK();q6();BK();tZ();AK();o1();wL={name:"help",description:"Show all available slash commands",fullDescription:"显示所有可用的 slash commands 及其使用方法",usage:"/help",aliases:["h"],async handler($,Z){let Y=p0(Z),Q=`\uD83D\uDD27 **可用的 Slash Commands:**
2318
2318
 
2319
2319
  **/init** - 分析当前项目并生成 BLADE.md 配置文件
2320
2320
  **/git** - Git 仓库查询和 AI 辅助 (status/log/diff/review/commit)
@@ -2380,7 +2380,7 @@ ${!J?"\n\uD83D\uDCA1 **建议:** 运行 `/init` 命令来创建项目配置文
2380
2380
 
2381
2381
  **状态:** ${_}
2382
2382
 
2383
- \uD83D\uDCA1 使用 \`/compact\` 可手动压缩上下文`;return Y.sendMessage(z),{success:!0,message:"上下文信息已显示"}}},VK={help:wL,clear:LL,version:NL,status:AL,exit:bL,context:RL,permissions:N7,resume:NK,compact:OK,mcp:zK,agents:WK}});import{execFile as DK,spawn as VL}from"child_process";import{promisify as ML}from"util";async function r3($,Z){return new Promise((Y)=>{DK("git",Z,{cwd:$,maxBuffer:10485760,encoding:"utf8"},(Q,X,J)=>{let G=Q==null?0:typeof Q.code==="number"?Q.code:1;Y({code:G,stdout:X||"",stderr:J||""})})})}async function DL($,Z){let{code:Y}=await r3($,Z);return Y===0}async function _2($,Z){let{stdout:Y}=await r3($,Z);return Y.trim()}async function a3($){return DL($,["rev-parse","--is-inside-work-tree"])}async function b7($){return(await _2($,["status","--porcelain"])).length>0}async function jK($){return _2($,["branch","--show-current"])}async function R7($,Z=10){return _2($,["log","-n",String(Z),"--pretty=format:%s"])}async function $Y($){let{code:Z,stderr:Y}=await r3($,["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 yK($,Z,Y=!1,Q){let X=["commit","-m",Z];if(Y)X.push("--no-verify");if(!Q){let{code:J,stderr:G}=await r3($,X);if(J!==0)throw Error(G||"Commit failed");return}return new Promise((J,G)=>{let q=VL("git",X,{cwd:$}),K="",W=(F,H,_)=>{let w=(_+F.toString()).split(`
2383
+ \uD83D\uDCA1 使用 \`/compact\` 可手动压缩上下文`;return Y.sendMessage(z),{success:!0,message:"上下文信息已显示"}}},VK={help:wL,clear:LL,version:NL,status:AL,exit:bL,context:RL,permissions:N6,resume:NK,compact:OK,mcp:zK,agents:WK}});import{execFile as DK,spawn as VL}from"child_process";import{promisify as ML}from"util";async function r3($,Z){return new Promise((Y)=>{DK("git",Z,{cwd:$,maxBuffer:10485760,encoding:"utf8"},(Q,X,J)=>{let G=Q==null?0:typeof Q.code==="number"?Q.code:1;Y({code:G,stdout:X||"",stderr:J||""})})})}async function DL($,Z){let{code:Y}=await r3($,Z);return Y===0}async function _2($,Z){let{stdout:Y}=await r3($,Z);return Y.trim()}async function a3($){return DL($,["rev-parse","--is-inside-work-tree"])}async function b6($){return(await _2($,["status","--porcelain"])).length>0}async function jK($){return _2($,["branch","--show-current"])}async function R6($,Z=10){return _2($,["log","-n",String(Z),"--pretty=format:%s"])}async function $Y($){let{code:Z,stderr:Y}=await r3($,["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 yK($,Z,Y=!1,Q){let X=["commit","-m",Z];if(Y)X.push("--no-verify");if(!Q){let{code:J,stderr:G}=await r3($,X);if(J!==0)throw Error(G||"Commit failed");return}return new Promise((J,G)=>{let q=VL("git",X,{cwd:$}),K="",W=(F,H,_)=>{let w=(_+F.toString()).split(`
2384
2384
  `),B=w.pop()||"";for(let L of w)if(L.trim())Q(L,H);return B},U="",O="";q.stdout?.on("data",(F)=>{U=W(F,"stdout",U)}),q.stderr?.on("data",(F)=>{K+=F.toString(),O=W(F,"stderr",O)}),q.on("error",(F)=>{G(F)}),q.on("close",(F)=>{if(U.trim())Q(U,"stdout");if(O.trim())Q(O,"stderr");if(F===0)J();else G(Error(K||"Commit failed"))})})}async function TK($){let{cwd:Z}=$;if(!await a3(Z))return null;let[Y,Q,X,J,G]=await Promise.all([_2(Z,["branch","--show-current"]),_2(Z,["rev-parse","--abbrev-ref","origin/HEAD"]).then((K)=>K.replace("origin/","")).catch(()=>"main"),_2(Z,["status","--short"]),_2(Z,["log","--oneline","-n","5"]),_2(Z,["config","user.email"])]),q=G?await _2(Z,["log","--author",G,"--oneline","-n","5"]):"";return{branch:Y,mainBranch:Q,status:X,log:J,author:G,authorLog:q}}function EK($){if(!$)return null;return`
2385
2385
  Git repository status (snapshot at conversation start):
2386
2386
  Current branch: ${$.branch}
@@ -2398,7 +2398,7 @@ ${$.authorLog||"(no recent commits)"}
2398
2398
 
2399
2399
  [Diff truncated due to size. Total diff size: `+(X.length/1024).toFixed(2)+"KB]";return X}var Lx;var ZY=R(()=>{Lx=ML(DK)});async function IK($){let Z=p0($),Y=await TK({cwd:$.cwd});if(!Y)return{success:!1,error:"无法获取 Git 状态"};let Q=EK(Y);if(Q)Z.sendMessage(`\`\`\`
2400
2400
  ${Q}
2401
- \`\`\``);else Z.sendMessage("\uD83D\uDCED 无法获取 Git 状态信息");return{success:!0}}async function yL($,Z){let Y=p0($),Q=Math.min(Math.max(parseInt(Z||"5",10)||5,1),50),X=await R7($.cwd,Q);if(!X)Y.sendMessage("\uD83D\uDCED 暂无提交记录");else Y.sendMessage(`**最近 ${Q} 条提交:**
2401
+ \`\`\``);else Z.sendMessage("\uD83D\uDCED 无法获取 Git 状态信息");return{success:!0}}async function yL($,Z){let Y=p0($),Q=Math.min(Math.max(parseInt(Z||"5",10)||5,1),50),X=await R6($.cwd,Q);if(!X)Y.sendMessage("\uD83D\uDCED 暂无提交记录");else Y.sendMessage(`**最近 ${Q} 条提交:**
2402
2402
  \`\`\`
2403
2403
  ${X}
2404
2404
  \`\`\``);return{success:!0}}async function TL($){let Z=p0($),{cwd:Y}=$,Q=await n3(Y);if(!Q)return Z.sendMessage("\uD83D\uDCED 暂存区为空,没有待提交的改动"),{success:!0};let X=await o3(Y),J=`**暂存文件:**
@@ -2409,7 +2409,7 @@ ${Q}
2409
2409
  **Diff:**
2410
2410
  \`\`\`diff
2411
2411
  ${X||"(无差异)"}
2412
- \`\`\``;return Z.sendMessage(J),{success:!0}}async function EL($){let Z=p0($),{cwd:Y,signal:Q}=$;if(!await b7(Y))return Z.sendMessage("\uD83D\uDCED 没有未提交的改动,无需 Review"),{success:!0};Z.sendMessage("\uD83D\uDD0D 正在分析代码改动...");let X=await n3(Y),J=await o3(Y);if(!J&&!X)return Z.sendMessage("\uD83D\uDCA1 请先使用 `git add` 暂存要 Review 的文件"),{success:!0};let G=await G$.create();if(Q?.aborted)return{success:!1,message:"操作已取消"};let q=G0().session.sessionId,K=`请对以下 Git 改动进行 Code Review。
2412
+ \`\`\``;return Z.sendMessage(J),{success:!0}}async function EL($){let Z=p0($),{cwd:Y,signal:Q}=$;if(!await b6(Y))return Z.sendMessage("\uD83D\uDCED 没有未提交的改动,无需 Review"),{success:!0};Z.sendMessage("\uD83D\uDD0D 正在分析代码改动...");let X=await n3(Y),J=await o3(Y);if(!J&&!X)return Z.sendMessage("\uD83D\uDCA1 请先使用 `git add` 暂存要 Review 的文件"),{success:!0};let G=await G$.create();if(Q?.aborted)return{success:!1,message:"操作已取消"};let q=G0().session.sessionId,K=`请对以下 Git 改动进行 Code Review。
2413
2413
 
2414
2414
  **暂存文件:**
2415
2415
  ${X||"(无)"}
@@ -2425,7 +2425,7 @@ ${J||"(无差异)"}
2425
2425
  3. **潜在问题**:指出可能的 bug、安全问题或性能问题
2426
2426
  4. **改进建议**:具体的代码改进建议
2427
2427
 
2428
- 如果改动很好,也请说明优点。保持简洁专业。`,W=await G.chat(K,{messages:[],userId:"cli-user",sessionId:q||"git-review",workspaceRoot:Y,signal:Q});return Z.sendMessage(W),{success:!0}}async function IL($){let Z=p0($),{cwd:Y,signal:Q}=$;if(!await b7(Y))return Z.sendMessage("\uD83D\uDCED 没有未提交的改动"),{success:!0};Z.sendMessage("\uD83D\uDCE6 暂存所有改动..."),await $Y(Y);let X=await n3(Y),J=await o3(Y);if(!X)return Z.sendMessage("\uD83D\uDCED 没有需要提交的改动"),{success:!0};Z.sendMessage("\uD83E\uDD16 正在生成 commit message...");let G=await R7(Y,5),q=await G$.create();if(Q?.aborted)return{success:!1,message:"操作已取消"};let K=G0().session.sessionId,W=vK(X,J,G),O=(await q.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:**
2428
+ 如果改动很好,也请说明优点。保持简洁专业。`,W=await G.chat(K,{messages:[],userId:"cli-user",sessionId:q||"git-review",workspaceRoot:Y,signal:Q});return Z.sendMessage(W),{success:!0}}async function IL($){let Z=p0($),{cwd:Y,signal:Q}=$;if(!await b6(Y))return Z.sendMessage("\uD83D\uDCED 没有未提交的改动"),{success:!0};Z.sendMessage("\uD83D\uDCE6 暂存所有改动..."),await $Y(Y);let X=await n3(Y),J=await o3(Y);if(!X)return Z.sendMessage("\uD83D\uDCED 没有需要提交的改动"),{success:!0};Z.sendMessage("\uD83E\uDD16 正在生成 commit message...");let G=await R6(Y,5),q=await G$.create();if(Q?.aborted)return{success:!1,message:"操作已取消"};let K=G0().session.sessionId,W=vK(X,J,G),O=(await q.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:**
2429
2429
  \`\`\`
2430
2430
  ${O}
2431
2431
  \`\`\`
@@ -2434,7 +2434,7 @@ ${O}
2434
2434
  \`\`\`bash
2435
2435
  git commit -m "${O.split(`
2436
2436
  `)[0]}"
2437
- \`\`\``),{success:!0}}async function vL($){let Z=p0($),{cwd:Y,signal:Q}=$;if(!await b7(Y))return Z.sendMessage("\uD83D\uDCED 没有未提交的改动"),{success:!0};Z.sendMessage("\uD83D\uDCE6 暂存所有改动..."),await $Y(Y);let X=await n3(Y),J=await o3(Y);if(!X)return Z.sendMessage("\uD83D\uDCED 没有需要提交的改动"),{success:!0};Z.sendMessage("\uD83E\uDD16 正在生成 commit message...");let G=await R7(Y,5),q=await G$.create();if(Q?.aborted)return{success:!1,message:"操作已取消"};let K=G0().session.sessionId,W=vK(X,J,G),O=(await q.chat(W,{messages:[],userId:"cli-user",sessionId:K||"git-commit",workspaceRoot:Y,signal:Q})).replace(/^```\w*\n?/,"").replace(/\n?```$/,"").trim();Z.sendMessage(`**生成的 Commit Message:**
2437
+ \`\`\``),{success:!0}}async function vL($){let Z=p0($),{cwd:Y,signal:Q}=$;if(!await b6(Y))return Z.sendMessage("\uD83D\uDCED 没有未提交的改动"),{success:!0};Z.sendMessage("\uD83D\uDCE6 暂存所有改动..."),await $Y(Y);let X=await n3(Y),J=await o3(Y);if(!X)return Z.sendMessage("\uD83D\uDCED 没有需要提交的改动"),{success:!0};Z.sendMessage("\uD83E\uDD16 正在生成 commit message...");let G=await R6(Y,5),q=await G$.create();if(Q?.aborted)return{success:!1,message:"操作已取消"};let K=G0().session.sessionId,W=vK(X,J,G),O=(await q.chat(W,{messages:[],userId:"cli-user",sessionId:K||"git-commit",workspaceRoot:Y,signal:Q})).replace(/^```\w*\n?/,"").replace(/\n?```$/,"").trim();Z.sendMessage(`**生成的 Commit Message:**
2438
2438
  \`\`\`
2439
2439
  ${O}
2440
2440
  \`\`\``);try{await yK(Y,O),Z.sendMessage("✅ 提交成功!")}catch(F){let H=F instanceof Error?F.message:"未知错误";return Z.sendMessage(`❌ 提交失败: ${H}`),{success:!1,error:H}}return{success:!0}}function vK($,Z,Y){let Q=Y&&Y.trim().length>0;return`请根据以下 Git 改动生成一条 commit message。
@@ -2471,10 +2471,10 @@ ${Y}
2471
2471
  /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=y0.getInstance();switch(Y){case"":case"add":return{success:!0,message:"show_hooks_manager",data:{action:"show_hooks_manager"}};case"status":return CL(Q);case"enable":return Q.enable(),_0().addAssistantMessage("✅ Hooks 已启用(当前会话)"),{success:!0,message:"Hooks enabled"};case"disable":return Q.disable(),_0().addAssistantMessage("⏸️ Hooks 已禁用(当前会话)"),{success:!0,message:"Hooks disabled"};case"list":return SL(Q);default:return _0().addAssistantMessage(`❌ 未知子命令: ${Y}
2472
2472
  使用 /hooks 查看帮助`),{success:!1,error:`Unknown subcommand: ${Y}`}}}};SK=PL});import{exec as kL}from"child_process";import{promisify as fL}from"util";class YY{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 fK("code --version"),Y=$.trim().split(`
2473
2473
  `)[0]||"unknown",Q=[];try{let{stdout:X}=await fK("code --list-extensions");Q=X.trim().split(`
2474
- `).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 fK;var hK=R(()=>{fK=fL(kL)});import{exec as hL}from"child_process";import{promisify as xL}from"util";class s3{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 V7(Z),{success:!0,message:"扩展安装成功"}}catch(Y){return{success:!1,message:"安装失败: "+(Y instanceof Error?Y.message:"未知错误")}}}static async checkVsCode(){try{let{stdout:$}=await V7("code --version");return{id:"vscode",name:"VS Code",version:$.trim().split(`
2475
- `)[0]||"unknown"}}catch{return null}}static async checkVsCodeInsiders(){try{let{stdout:$}=await V7("code-insiders --version");return{id:"vscode-insiders",name:"VS Code Insiders",version:$.trim().split(`
2476
- `)[0]||"unknown"}}catch{return null}}static async checkCursor(){try{let{stdout:$}=await V7("cursor --version");return{id:"cursor",name:"Cursor",version:$.trim().split(`
2477
- `)[0]||"unknown"}}catch{return null}}}var V7;var xK=R(()=>{V7=xL(hL)});import{existsSync as pL,readFileSync as mL}from"fs";import{homedir as gL}from"os";import{join as uL}from"path";function dL(){switch(h8){case"connected":return{type:"info",content:`\uD83D\uDFE2 已连接到 ${QY||"IDE"} (端口: ${XY})`};case"connecting":return{type:"info",content:"\uD83D\uDFE1 正在连接..."};default:return{type:"error",content:"\uD83D\uDD34 未连接到 IDE"}}}function mK(){try{if(pL(pK)){let $=mL(pK,"utf-8");return JSON.parse($)}}catch{}return null}function gK(){let $=process.env.BLADE_IDE_PORT;if($)return parseInt($,10);let Z=mK();if(Z)return Z.port;return null}async function cL(){let $=[],Z=dL();$.push(Z.content),$.push(""),$.push("\uD83D\uDCE6 已安装的 IDE:");let Y=await s3.getInstalledIdes();if(Y.length===0)$.push(" (未检测到支持的 IDE)");else for(let G of Y)$.push(` • ${G.name} ${G.version}`);$.push("");let Q=await YY.detectIde();if(Q){if($.push(`\uD83D\uDDA5️ 当前环境: ${Q.name} ${Q.version}`),Q.extensions.length>0)$.push(` 已安装扩展: ${Q.extensions.length} 个`)}let X=gK(),J=mK();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(`
2474
+ `).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 fK;var hK=R(()=>{fK=fL(kL)});import{exec as hL}from"child_process";import{promisify as xL}from"util";class s3{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 V6(Z),{success:!0,message:"扩展安装成功"}}catch(Y){return{success:!1,message:"安装失败: "+(Y instanceof Error?Y.message:"未知错误")}}}static async checkVsCode(){try{let{stdout:$}=await V6("code --version");return{id:"vscode",name:"VS Code",version:$.trim().split(`
2475
+ `)[0]||"unknown"}}catch{return null}}static async checkVsCodeInsiders(){try{let{stdout:$}=await V6("code-insiders --version");return{id:"vscode-insiders",name:"VS Code Insiders",version:$.trim().split(`
2476
+ `)[0]||"unknown"}}catch{return null}}static async checkCursor(){try{let{stdout:$}=await V6("cursor --version");return{id:"cursor",name:"Cursor",version:$.trim().split(`
2477
+ `)[0]||"unknown"}}catch{return null}}}var V6;var xK=R(()=>{V6=xL(hL)});import{existsSync as pL,readFileSync as mL}from"fs";import{homedir as gL}from"os";import{join as uL}from"path";function dL(){switch(h8){case"connected":return{type:"info",content:`\uD83D\uDFE2 已连接到 ${QY||"IDE"} (端口: ${XY})`};case"connecting":return{type:"info",content:"\uD83D\uDFE1 正在连接..."};default:return{type:"error",content:"\uD83D\uDD34 未连接到 IDE"}}}function mK(){try{if(pL(pK)){let $=mL(pK,"utf-8");return JSON.parse($)}}catch{}return null}function gK(){let $=process.env.BLADE_IDE_PORT;if($)return parseInt($,10);let Z=mK();if(Z)return Z.port;return null}async function cL(){let $=[],Z=dL();$.push(Z.content),$.push(""),$.push("\uD83D\uDCE6 已安装的 IDE:");let Y=await s3.getInstalledIdes();if(Y.length===0)$.push(" (未检测到支持的 IDE)");else for(let G of Y)$.push(` • ${G.name} ${G.version}`);$.push("");let Q=await YY.detectIde();if(Q){if($.push(`\uD83D\uDDA5️ 当前环境: ${Q.name} ${Q.version}`),Q.extensions.length>0)$.push(` 已安装扩展: ${Q.extensions.length} 个`)}let X=gK(),J=mK();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(`
2478
2478
  `)}async function lL(){let $=gK();if(!$)return`❌ 未检测到 IDE 端口
2479
2479
 
2480
2480
  请确保:
@@ -2621,7 +2621,7 @@ ${Y}
2621
2621
  - \`/login gemini\` - 使用 Gemini CLI OAuth(Antigravity 备选)
2622
2622
  - \`/login copilot\` - 登录 GitHub Copilot
2623
2623
 
2624
- 登录后,使用 \`/model add\` 添加模型配置。`,usage:"/login [copilot|gemini]",category:"auth",examples:["/login","/login copilot","/login gemini"],async handler($,Z){let Y=p0(Z),Q=oL($);if(Q==="copilot"){let q=r$.getInstance();try{if(await q.isLoggedIn()){let W=await q.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 q.login(),Y.sendMessage(""),Y.sendMessage("**可用模型:**");for(let W of Object.values(E6))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=p$.getInstance(),J=Q==="gemini-cli"?"gemini-cli":"antigravity",G=Q==="gemini-cli"?"Gemini CLI":"Antigravity";try{if(await X.isLoggedIn()){let W=await X.getStatus(),U=W.expiresAt?Math.round((W.expiresAt.getTime()-Date.now())/1000/60):0,O=W.configType==="gemini-cli"?"Gemini CLI":"Antigravity";return Y.sendMessage(`✅ 已登录(${O} OAuth)`),Y.sendMessage(`Token 有效期还剩约 ${U} 分钟`),Y.sendMessage(""),Y.sendMessage("如需重新登录或切换 OAuth 方式,请先执行 /logout"),{success:!0,message:"已登录",content:`已登录(${O} OAuth),Token 有效期还剩约 ${U} 分钟`}}Y.sendMessage(`\uD83D\uDD10 开始 ${G} OAuth 登录...`),Y.sendMessage(""),await X.login(J),Y.sendMessage(""),Y.sendMessage(`✅ ${G} 登录成功!`),Y.sendMessage(""),Y.sendMessage("**可用模型:**");let K=Q==="gemini-cli"?D6:L3;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\` 添加 ${G} 模型配置`),{success:!0,message:"登录成功",content:`已成功通过 ${G} OAuth 登录。使用 /model add 添加模型配置。`}}catch(q){let K=q instanceof Error?q.message:String(q);return Y.sendMessage(`❌ 登录失败: ${K}`),{success:!1,error:K}}}}});function sL($){if($.includes("copilot")||$.includes("github"))return"copilot";if($.includes("all"))return"all";return"antigravity"}var sK;var tK=R(()=>{R3();T3();o1();sK={name:"logout",description:"登出 OAuth 服务并清除 token",fullDescription:`登出 OAuth 服务,清除本地存储的 token。
2624
+ 登录后,使用 \`/model add\` 添加模型配置。`,usage:"/login [copilot|gemini]",category:"auth",examples:["/login","/login copilot","/login gemini"],async handler($,Z){let Y=p0(Z),Q=oL($);if(Q==="copilot"){let q=r$.getInstance();try{if(await q.isLoggedIn()){let W=await q.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 q.login(),Y.sendMessage(""),Y.sendMessage("**可用模型:**");for(let W of Object.values(E7))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=p$.getInstance(),J=Q==="gemini-cli"?"gemini-cli":"antigravity",G=Q==="gemini-cli"?"Gemini CLI":"Antigravity";try{if(await X.isLoggedIn()){let W=await X.getStatus(),U=W.expiresAt?Math.round((W.expiresAt.getTime()-Date.now())/1000/60):0,O=W.configType==="gemini-cli"?"Gemini CLI":"Antigravity";return Y.sendMessage(`✅ 已登录(${O} OAuth)`),Y.sendMessage(`Token 有效期还剩约 ${U} 分钟`),Y.sendMessage(""),Y.sendMessage("如需重新登录或切换 OAuth 方式,请先执行 /logout"),{success:!0,message:"已登录",content:`已登录(${O} OAuth),Token 有效期还剩约 ${U} 分钟`}}Y.sendMessage(`\uD83D\uDD10 开始 ${G} OAuth 登录...`),Y.sendMessage(""),await X.login(J),Y.sendMessage(""),Y.sendMessage(`✅ ${G} 登录成功!`),Y.sendMessage(""),Y.sendMessage("**可用模型:**");let K=Q==="gemini-cli"?D7:L3;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\` 添加 ${G} 模型配置`),{success:!0,message:"登录成功",content:`已成功通过 ${G} OAuth 登录。使用 /model add 添加模型配置。`}}catch(q){let K=q instanceof Error?q.message:String(q);return Y.sendMessage(`❌ 登录失败: ${K}`),{success:!1,error:K}}}}});function sL($){if($.includes("copilot")||$.includes("github"))return"copilot";if($.includes("all"))return"all";return"antigravity"}var sK;var tK=R(()=>{R3();T3();o1();sK={name:"logout",description:"登出 OAuth 服务并清除 token",fullDescription:`登出 OAuth 服务,清除本地存储的 token。
2625
2625
 
2626
2626
  **用法:**
2627
2627
  - \`/logout\` - 登出 Antigravity(默认)
@@ -2650,7 +2650,7 @@ ${Y}
2650
2650
 
2651
2651
  `+"使用 `--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 _0().addAssistantMessage(Y.join(`
2652
2652
  `)),{success:!0,message:"Plugins listed"}}function ZN($,Z){if(!Z)return _0().addAssistantMessage("请指定插件名称: `/plugins info <name>`"),{success:!1,error:"Plugin name required"};let Y=$.get(Z);if(!Y)return _0().addAssistantMessage(`未找到插件: ${Z}`),{success:!1,error:`Plugin not found: ${Z}`};let Q=[`## ${Y.manifest.name}`,"",`**版本**: ${Y.manifest.version}`,`**描述**: ${Y.manifest.description}`,`**状态**: ${Y.status==="active"?"✅ 启用":"⏸️ 禁用"}`,`**来源**: ${qN(Y.source)}`,`**路径**: \`${Y.basePath}\``,""];if(Y.manifest.author)Q.push(`**作者**: ${Y.manifest.author.name}`);if(Y.manifest.license)Q.push(`**许可证**: ${Y.manifest.license}`);if(Y.manifest.repository)Q.push(`**仓库**: ${Y.manifest.repository}`);if(Y.commands.length>0){Q.push(""),Q.push(`### 命令 (${Y.commands.length})`);for(let X of Y.commands){let J=X.config.argumentHint?` ${X.config.argumentHint}`:"",G=X.config.description?` - ${X.config.description}`:"";Q.push(`- \`/${X.namespacedName}${J}\`${G}`)}}if(Y.skills.length>0){Q.push(""),Q.push(`### 技能 (${Y.skills.length})`);for(let X of Y.skills)Q.push(`- \`${X.namespacedName}\` - ${X.metadata.description}`)}if(Y.agents.length>0){Q.push(""),Q.push(`### 代理 (${Y.agents.length})`);for(let X of Y.agents)Q.push(`- \`${X.namespacedName}\` - ${X.config.description}`)}if(Y.mcpServers){let X=Object.keys(Y.mcpServers).length;Q.push(""),Q.push(`### MCP 服务器 (${X})`);for(let J of Object.keys(Y.mcpServers))Q.push(`- \`${J}\``)}if(Y.hooks)Q.push(""),Q.push("### Hooks"),Q.push("插件已配置 hooks");return _0().addAssistantMessage(Q.join(`
2653
- `)),{success:!0,message:"Plugin info displayed"}}function YN($,Z){if(!Z)return _0().addAssistantMessage("请指定插件名称: `/plugins enable <name>`"),{success:!1,error:"Plugin name required"};if($.enable(Z))return _0().addAssistantMessage(`✅ 已启用插件: ${Z}`),{success:!0,message:`Plugin ${Z} enabled`};if(!$.get(Z))return _0().addAssistantMessage(`未找到插件: ${Z}`),{success:!1,error:`Plugin not found: ${Z}`};return _0().addAssistantMessage(`插件 ${Z} 已经是启用状态`),{success:!0,message:`Plugin ${Z} already enabled`}}function QN($,Z){if(!Z)return _0().addAssistantMessage("请指定插件名称: `/plugins disable <name>`"),{success:!1,error:"Plugin name required"};if($.disable(Z))return _0().addAssistantMessage(`⏸️ 已禁用插件: ${Z}`),{success:!0,message:`Plugin ${Z} disabled`};if(!$.get(Z))return _0().addAssistantMessage(`未找到插件: ${Z}`),{success:!1,error:`Plugin not found: ${Z}`};return _0().addAssistantMessage(`插件 ${Z} 已经是禁用状态`),{success:!0,message:`Plugin ${Z} already disabled`}}async function XN($){L7(),await $.refresh(),await Y4()}async function JN($){try{L7();let Z=await $.refresh(),Y=await Y4(),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 _0().addAssistantMessage(Q.join(`
2653
+ `)),{success:!0,message:"Plugin info displayed"}}function YN($,Z){if(!Z)return _0().addAssistantMessage("请指定插件名称: `/plugins enable <name>`"),{success:!1,error:"Plugin name required"};if($.enable(Z))return _0().addAssistantMessage(`✅ 已启用插件: ${Z}`),{success:!0,message:`Plugin ${Z} enabled`};if(!$.get(Z))return _0().addAssistantMessage(`未找到插件: ${Z}`),{success:!1,error:`Plugin not found: ${Z}`};return _0().addAssistantMessage(`插件 ${Z} 已经是启用状态`),{success:!0,message:`Plugin ${Z} already enabled`}}function QN($,Z){if(!Z)return _0().addAssistantMessage("请指定插件名称: `/plugins disable <name>`"),{success:!1,error:"Plugin name required"};if($.disable(Z))return _0().addAssistantMessage(`⏸️ 已禁用插件: ${Z}`),{success:!0,message:`Plugin ${Z} disabled`};if(!$.get(Z))return _0().addAssistantMessage(`未找到插件: ${Z}`),{success:!1,error:`Plugin not found: ${Z}`};return _0().addAssistantMessage(`插件 ${Z} 已经是禁用状态`),{success:!0,message:`Plugin ${Z} already disabled`}}async function XN($){L6(),await $.refresh(),await Y4()}async function JN($){try{L6();let Z=await $.refresh(),Y=await Y4(),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 _0().addAssistantMessage(Q.join(`
2654
2654
  `)),{success:!0,message:"Plugins refreshed"}}catch(Z){let Y=Z instanceof Error?Z.message:String(Z);return _0().addAssistantMessage(`❌ 刷新失败: ${Y}`),{success:!1,error:Y}}}function GN($){let Z=$.getStats(),Y=["## 插件统计","","| 指标 | 数量 |","|------|------|",`| 总插件数 | ${Z.total} |`,`| 启用 | ${Z.active} |`,`| 禁用 | ${Z.inactive} |`,`| 命令 | ${Z.commands} |`,`| 技能 | ${Z.skills} |`,`| 代理 | ${Z.agents} |`];return _0().addAssistantMessage(Y.join(`
2655
2655
  `)),{success:!0,message:"Stats displayed"}}function qN($){switch($){case"cli":return"CLI 参数";case"project":return"项目级";case"user":return"用户级";default:return $}}async function KN($){if(!$)return _0().addAssistantMessage("请指定插件 URL: `/plugins install <url>`\n\n"+`支持的格式:
2656
2656
  `+"- GitHub 简写: `user/repo`\n"+"- 完整 URL: `https://github.com/user/repo`"),{success:!1,error:"Plugin URL required"};_0().addAssistantMessage(`正在安装插件: ${$}...`);let Y=await l3().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` 加载新安装的插件。"),_0().addAssistantMessage(Q.join(`
@@ -2670,13 +2670,13 @@ ${Y}
2670
2670
  /plugins disable <name> - 禁用插件
2671
2671
  /plugins refresh - 刷新插件列表
2672
2672
  /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=s$();switch(Y){case"":return await XN(Q),{success:!0,message:"show_plugins_manager",data:{action:"show_plugins_manager"}};case"list":case"ls":return $N(Q);case"info":return ZN(Q,$[1]);case"install":case"add":return KN($[1]);case"uninstall":case"remove":case"rm":return WN($[1]);case"update":case"upgrade":return UN($[1]);case"enable":return YN(Q,$[1]);case"disable":return QN(Q,$[1]);case"refresh":return JN(Q);case"stats":return GN(Q);default:return _0().addAssistantMessage(`未知子命令: ${Y}
2673
- 使用 /plugins 查看帮助`),{success:!1,error:`Unknown subcommand: ${Y}`}}}};ZW=eL});var ON,QW;var XW=R(()=>{K2();M0();ON={name:"skills",description:"查看所有可用的 Skills",fullDescription:"显示所有已发现的 Skills 及其详细信息,包括名称、描述、来源和允许的工具。",usage:"/skills",category:"system",examples:["/skills"],handler:async($,Z)=>{try{return await J$().refresh(),{success:!0,message:"show_skills_manager",data:{action:"show_skills_manager"}}}catch(Y){let Q=`获取 Skills 失败: ${Y instanceof Error?Y.message:"未知错误"}`;return _0().addAssistantMessage(Q),{success:!1,error:Q}}}},QW=ON});function M7($){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 JW($){switch($){case"running":return"⏳";case"completed":case"exited":return"✅";case"failed":case"error":return"❌";case"killed":case"cancelled":return"✂️";default:return"❓"}}function GW($,Z){if($.length<=Z)return $;return $.slice(0,Z-3)+"..."}async function FN($,Z){let Y=p0(Z),Q=$[0],X=C$.getInstance(),J=F1.getInstance();if(Q==="clean"){let F=J.cleanupExpiredSessions(0);return Y.sendMessage(`\uD83E\uDDF9 已清理 ${F} 个已完成的 Agent 会话`),{success:!0,message:`Cleaned ${F} agent sessions`}}let G=[`\uD83D\uDCCB **后台任务列表**
2673
+ 使用 /plugins 查看帮助`),{success:!1,error:`Unknown subcommand: ${Y}`}}}};ZW=eL});var ON,QW;var XW=R(()=>{K2();M0();ON={name:"skills",description:"查看所有可用的 Skills",fullDescription:"显示所有已发现的 Skills 及其详细信息,包括名称、描述、来源和允许的工具。",usage:"/skills",category:"system",examples:["/skills"],handler:async($,Z)=>{try{return await J$().refresh(),{success:!0,message:"show_skills_manager",data:{action:"show_skills_manager"}}}catch(Y){let Q=`获取 Skills 失败: ${Y instanceof Error?Y.message:"未知错误"}`;return _0().addAssistantMessage(Q),{success:!1,error:Q}}}},QW=ON});function M6($){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 JW($){switch($){case"running":return"⏳";case"completed":case"exited":return"✅";case"failed":case"error":return"❌";case"killed":case"cancelled":return"✂️";default:return"❓"}}function GW($,Z){if($.length<=Z)return $;return $.slice(0,Z-3)+"..."}async function FN($,Z){let Y=p0(Z),Q=$[0],X=C$.getInstance(),J=F1.getInstance();if(Q==="clean"){let F=J.cleanupExpiredSessions(0);return Y.sendMessage(`\uD83E\uDDF9 已清理 ${F} 个已完成的 Agent 会话`),{success:!0,message:`Cleaned ${F} agent sessions`}}let G=[`\uD83D\uDCCB **后台任务列表**
2674
2674
  `],q=X.processes,K=Array.from(q?.values()||[]);if(K.length>0){G.push(`### \uD83D\uDC1A Shells
2675
- `),G.push("| ID | 状态 | 命令 | PID | 运行时间 |"),G.push("|:---|:-----|:-----|:----|:---------|");for(let F of K){let H=F.endTime?M7(F.endTime-F.startTime):M7(Date.now()-F.startTime),_=JW(F.status);G.push(`| \`${F.id.slice(0,12)}...\` | ${_} ${F.status} | \`${GW(F.command,30)}\` | ${F.pid||"-"} | ${H} |`)}G.push("")}let W=J.listAll();if(W.length>0){G.push(`### \uD83E\uDD16 Agents
2676
- `),G.push("| ID | 状态 | 类型 | 描述 | 运行时间 |"),G.push("|:---|:-----|:-----|:-----|:---------|");for(let F of W){let H=F.completedAt?M7(F.completedAt-F.createdAt):M7(Date.now()-F.createdAt),_=JW(F.status);G.push(`| \`${F.id.slice(0,12)}...\` | ${_} ${F.status} | ${F.subagentType} | ${GW(F.description,25)} | ${H} |`)}G.push("")}let U=K.filter((F)=>F.status==="running").length,O=J.getRunningCount();if(K.length===0&&W.length===0)G.push(`*暂无后台任务*
2675
+ `),G.push("| ID | 状态 | 命令 | PID | 运行时间 |"),G.push("|:---|:-----|:-----|:----|:---------|");for(let F of K){let H=F.endTime?M6(F.endTime-F.startTime):M6(Date.now()-F.startTime),_=JW(F.status);G.push(`| \`${F.id.slice(0,12)}...\` | ${_} ${F.status} | \`${GW(F.command,30)}\` | ${F.pid||"-"} | ${H} |`)}G.push("")}let W=J.listAll();if(W.length>0){G.push(`### \uD83E\uDD16 Agents
2676
+ `),G.push("| ID | 状态 | 类型 | 描述 | 运行时间 |"),G.push("|:---|:-----|:-----|:-----|:---------|");for(let F of W){let H=F.completedAt?M6(F.completedAt-F.createdAt):M6(Date.now()-F.createdAt),_=JW(F.status);G.push(`| \`${F.id.slice(0,12)}...\` | ${_} ${F.status} | ${F.subagentType} | ${GW(F.description,25)} | ${H} |`)}G.push("")}let U=K.filter((F)=>F.status==="running").length,O=J.getRunningCount();if(K.length===0&&W.length===0)G.push(`*暂无后台任务*
2677
2677
  `);else G.push(`**统计**: ${K.length} shells (${U} 运行中), ${W.length} agents (${O} 运行中)`);return G.push(`
2678
2678
  ---`),G.push("\uD83D\uDCA1 **命令**:"),G.push("- `/tasks` - 列出所有后台任务"),G.push("- `/tasks clean` - 清理已完成的 Agent 会话"),Y.sendMessage(G.join(`
2679
- `)),{success:!0,message:`Listed ${K.length} shells and ${W.length} agents`}}var HN,qW;var KW=R(()=>{K7();j8();o1();HN={name:"tasks",description:"列出所有后台任务(shells 和 agents)",fullDescription:`查看和管理后台运行的任务。
2679
+ `)),{success:!0,message:`Listed ${K.length} shells and ${W.length} agents`}}var HN,qW;var KW=R(()=>{K6();j8();o1();HN={name:"tasks",description:"列出所有后台任务(shells 和 agents)",fullDescription:`查看和管理后台运行的任务。
2680
2680
 
2681
2681
  **功能**:
2682
2682
  - 列出所有后台 shell 进程
@@ -2685,10 +2685,10 @@ ${Y}
2685
2685
 
2686
2686
  **使用示例**:
2687
2687
  - \`/tasks\` - 显示所有后台任务
2688
- - \`/tasks clean\` - 清理已完成的 agent 会话`,usage:"/tasks [clean]",category:"system",examples:["/tasks","/tasks clean"],handler:FN},qW=HN});async function _N($,Z){return{success:!0,message:"show_theme_selector",data:{action:"show_theme_selector"}}}var zN,WW;var UW=R(()=>{zN={name:"theme",description:"打开交互式主题选择器",aliases:["themes","style"],usage:"/theme",examples:["/theme"],category:"ui",handler:_N},WW=zN});import BN from"fuse.js";function p8($){return $.trim().startsWith("/")}function wN($){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 LN($){if($6[$])return $6[$];for(let Z of Object.values($6))if(Z.aliases?.includes($))return Z;return}function OW($){let Z=$.argumentHint?`/${$.name} ${$.argumentHint}`:`/${$.name}`;return{name:$.name,description:$.description,fullDescription:`[Skill] ${$.description}${$.whenToUse?`
2688
+ - \`/tasks clean\` - 清理已完成的 agent 会话`,usage:"/tasks [clean]",category:"system",examples:["/tasks","/tasks clean"],handler:FN},qW=HN});async function _N($,Z){return{success:!0,message:"show_theme_selector",data:{action:"show_theme_selector"}}}var zN,WW;var UW=R(()=>{zN={name:"theme",description:"打开交互式主题选择器",aliases:["themes","style"],usage:"/theme",examples:["/theme"],category:"ui",handler:_N},WW=zN});import BN from"fuse.js";function p8($){return $.trim().startsWith("/")}function wN($){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 LN($){if($7[$])return $7[$];for(let Z of Object.values($7))if(Z.aliases?.includes($))return Z;return}function OW($){let Z=$.argumentHint?`/${$.name} ${$.argumentHint}`:`/${$.name}`;return{name:$.name,description:$.description,fullDescription:`[Skill] ${$.description}${$.whenToUse?`
2689
2689
 
2690
2690
  **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 NN($){return J$().getUserInvocableSkills().find((Q)=>Q.name===$)}async function AN(){await v4()}async function FW($){return await A$.getInstance().initialize($)}async function m8($,Z){try{let{command:Y,args:Q}=wN($),X=LN(Y);if(X)return await X.handler(Q,Z);let J=A$.getInstance();if(J.hasCommand(Y)){let W=J.getCommand(Y);if(W){let U=Z.workspaceRoot||process.cwd(),O=await J.executeCommand(Y,{args:Q,workspaceRoot:U,signal:Z.signal});if(O)return{success:!0,message:`执行自定义命令: /${Y}`,data:{action:"invoke_custom_command",commandName:Y,processedContent:O,config:W.config}}}}let q=s$().findCommand(Y);if(q){let W=Z.workspaceRoot||process.cwd(),U=await J.executePluginCommand(q.namespacedName,{args:Q,workspaceRoot:W,signal:Z.signal});if(U)return{success:!0,message:`执行插件命令: /${q.namespacedName}`,data:{action:"invoke_plugin_command",commandName:q.namespacedName,pluginName:q.pluginName,processedContent:U,config:q.config}}}await AN();let K=NN(Y);if(K)return await OW(K).handler(Q,Z);return{success:!1,error:`未知命令: /${Y}
2691
- 使用 /help 查看可用命令`}}catch(Y){return{success:!1,error:`命令执行失败: ${Y instanceof Error?Y.message:"未知错误"}`}}}function HW(){let $=Object.values($6),Y=A$.getInstance().getAllCommands().map((q)=>({name:q.name,description:q.config.description||q.content.slice(0,50),usage:q.config.argumentHint?`/${q.name} ${q.config.argumentHint}`:`/${q.name}`,category:"custom",handler:async()=>({success:!0})})),X=s$().getAllCommands().map((q)=>({name:q.namespacedName,description:q.config.description||q.content.slice(0,50),usage:q.config.argumentHint?`/${q.namespacedName} ${q.config.argumentHint}`:`/${q.namespacedName}`,category:"plugin",handler:async()=>({success:!0})})),G=J$().getUserInvocableSkills().map(OW);return[...$,...Y,...X,...G]}function D7($){let Z=($.startsWith("/")?$.slice(1):$).trim(),Y=Object.values($6).map((H)=>({name:H.name,description:H.description,aliases:H.aliases||[],label:void 0,argumentHint:void 0,isCustom:!1,isSkill:!1,isPlugin:!1})),Q=A$.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})),G=s$().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=J$().getUserInvocableSkills().map((H)=>({name:H.name,description:H.description,aliases:[],label:"(skill)",argumentHint:H.argumentHint,isCustom:!1,isSkill:!0,isPlugin:!1})),W=[...Y,...X,...G,...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 BN(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 $6;var l4=R(()=>{f8();K2();MK();q7();CK();kK();dK();aK();oK();tK();$W();tZ();YW();XW();KW();UW();$6={...VK,init:rK,theme:WW,permissions:N7,model:eK,git:PK,ide:uK,skills:QW,hooks:SK,login:nK,logout:sK,tasks:qW,plugins:ZW}});import{nanoid as QM}from"nanoid";class GQ{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(){Z$.debug(`[AcpSession ${this.id}] Initializing...`),F0.initializeSession(this.connection,this.id,this.clientCapabilities,this.cwd),Z$.debug(`[AcpSession ${this.id}] ACP service context initialized`),this.agent=await G$.create({}),Z$.debug(`[AcpSession ${this.id}] Agent created successfully`)}sendAvailableCommandsDelayed(){Z$.debug(`[AcpSession ${this.id}] Scheduling available commands update (500ms delay)`),setTimeout(()=>{this.sendAvailableCommands()},500)}async handleSlashCommand($,Z){try{Z$.debug(`[AcpSession ${this.id}] Executing slash command: ${$}`);let Y={cwd:this.cwd,signal:Z,acp:{sendMessage:(J)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:J}})},sendToolStart:(J,G,q)=>{let K=`tool_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,W=this.mapToolKind(q);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:K,status:"in_progress",title:`${J}`,content:[{type:"content",content:{type:"text",text:JSON.stringify(G,null,2)}}],kind:W})},sendToolResult:(J,G)=>{if(G.summary)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:G.summary}})}}},Q=await m8($,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 Z$.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 $=HW(),Z=["model","permissions","theme","config","exit","ide"],Q=$.filter((X)=>!Z.includes(X.name)).map((X)=>{let J;if(X.usage){let G=X.usage.replace(/^\/\w+\s*/,"").trim();if(G)J=G}if(X.aliases?.length){let G=`Aliases: ${X.aliases.join(", ")}`;J=J?`${J} | ${G}`:G}return{name:X.name,description:X.description,input:J?{hint:J}:void 0}});Z$.info(`[AcpSession ${this.id}] Sending available commands: ${JSON.stringify(Q.map((X)=>X.name))}`),this.sendUpdate({sessionUpdate:"available_commands_update",availableCommands:Q}),Z$.info(`[AcpSession ${this.id}] Sent ${Q.length} available commands`)}catch($){Z$.error(`[AcpSession ${this.id}] Failed to send available commands:`,$)}}async prompt($){F0.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(Z$.debug(`[AcpSession ${this.id}] Received prompt: ${Y.slice(0,100)}...`),p8(Y))return await this.handleSlashCommand(Y,Z.signal);let Q={sessionId:this.id,userId:"acp-user",workspaceRoot:this.cwd,messages:[...this.messages],signal:Z.signal,permissionMode:this.mapModeToPermissionMode(),confirmationHandler:{requestConfirmation:async(G)=>{return this.requestPermission(G)}}},X={signal:Z.signal,onContent:(G)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:G}})},onThinking:(G)=>{this.sendUpdate({sessionUpdate:"agent_thought_chunk",content:{type:"text",text:G}})},onToolStart:(G,q)=>{let K="function"in G?G.function.name:G.type,W=this.mapToolKind(q);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:G.id,status:"in_progress",title:`Executing ${K}`,content:[],kind:W})},onToolResult:async(G,q)=>{let K=[],W=q.metadata;if(W?.kind==="edit"&&typeof W.file_path==="string"&&typeof W.oldContent==="string"&&(typeof W.newContent==="string"||W.newContent===void 0))K.push({type:"diff",path:W.file_path,oldText:W.oldContent,newText:W.newContent??null});else if(q.displayContent){let F=typeof q.displayContent==="string"?q.displayContent:JSON.stringify(q.displayContent);K.push({type:"content",content:{type:"text",text:F}})}let U="function"in G?G.function.name:G.type,O=q.success?"completed":"failed";this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:G.id,status:O,content:K})},onTodoUpdate:(G)=>{this.sendPlanUpdate(G)}},J=await this.agent.chat(Y,Q,X);if(J)this.messages.push({role:"user",content:Y}),this.messages.push({role:"assistant",content:J});if(Z.signal.aborted)return{stopReason:"cancelled"};return{stopReason:"end_turn"}}catch(Y){if(Z.signal.aborted||Y instanceof Error&&Y.name==="AbortError")return{stopReason:"cancelled"};throw Z$.error(`[AcpSession ${this.id}] Prompt error:`,Y),Y}finally{if(this.pendingPrompt===Z)this.pendingPrompt=null}}cancel(){if(Z$.info(`[AcpSession ${this.id}] Cancel requested`),this.pendingPrompt)this.pendingPrompt.abort(),this.pendingPrompt=null,Z$.info(`[AcpSession ${this.id}] Cancelled successfully`);else Z$.warn(`[AcpSession ${this.id}] No pending prompt to cancel`)}async setMode($){let Z=["default","auto-edit","yolo","plan"];this.mode=Z.includes($)?$:"default",Z$.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(Z$.info(`[AcpSession ${this.id}] Model set to: ${$}`),this.agent)Z$.warn(`[AcpSession ${this.id}] Runtime model switching not yet implemented`)}async destroy(){if(this.cancel(),this.agent)await this.agent.destroy(),this.agent=null;F0.destroySession(this.id),Z$.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}">
2691
+ 使用 /help 查看可用命令`}}catch(Y){return{success:!1,error:`命令执行失败: ${Y instanceof Error?Y.message:"未知错误"}`}}}function HW(){let $=Object.values($7),Y=A$.getInstance().getAllCommands().map((q)=>({name:q.name,description:q.config.description||q.content.slice(0,50),usage:q.config.argumentHint?`/${q.name} ${q.config.argumentHint}`:`/${q.name}`,category:"custom",handler:async()=>({success:!0})})),X=s$().getAllCommands().map((q)=>({name:q.namespacedName,description:q.config.description||q.content.slice(0,50),usage:q.config.argumentHint?`/${q.namespacedName} ${q.config.argumentHint}`:`/${q.namespacedName}`,category:"plugin",handler:async()=>({success:!0})})),G=J$().getUserInvocableSkills().map(OW);return[...$,...Y,...X,...G]}function D6($){let Z=($.startsWith("/")?$.slice(1):$).trim(),Y=Object.values($7).map((H)=>({name:H.name,description:H.description,aliases:H.aliases||[],label:void 0,argumentHint:void 0,isCustom:!1,isSkill:!1,isPlugin:!1})),Q=A$.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})),G=s$().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=J$().getUserInvocableSkills().map((H)=>({name:H.name,description:H.description,aliases:[],label:"(skill)",argumentHint:H.argumentHint,isCustom:!1,isSkill:!0,isPlugin:!1})),W=[...Y,...X,...G,...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 BN(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 $7;var l4=R(()=>{f8();K2();MK();q6();CK();kK();dK();aK();oK();tK();$W();tZ();YW();XW();KW();UW();$7={...VK,init:rK,theme:WW,permissions:N6,model:eK,git:PK,ide:uK,skills:QW,hooks:SK,login:nK,logout:sK,tasks:qW,plugins:ZW}});import{nanoid as QM}from"nanoid";class GQ{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(){Z$.debug(`[AcpSession ${this.id}] Initializing...`),F0.initializeSession(this.connection,this.id,this.clientCapabilities,this.cwd),Z$.debug(`[AcpSession ${this.id}] ACP service context initialized`),this.agent=await G$.create({}),Z$.debug(`[AcpSession ${this.id}] Agent created successfully`)}sendAvailableCommandsDelayed(){Z$.debug(`[AcpSession ${this.id}] Scheduling available commands update (500ms delay)`),setTimeout(()=>{this.sendAvailableCommands()},500)}async handleSlashCommand($,Z){try{Z$.debug(`[AcpSession ${this.id}] Executing slash command: ${$}`);let Y={cwd:this.cwd,signal:Z,acp:{sendMessage:(J)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:J}})},sendToolStart:(J,G,q)=>{let K=`tool_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,W=this.mapToolKind(q);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:K,status:"in_progress",title:`${J}`,content:[{type:"content",content:{type:"text",text:JSON.stringify(G,null,2)}}],kind:W})},sendToolResult:(J,G)=>{if(G.summary)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:G.summary}})}}},Q=await m8($,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 Z$.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 $=HW(),Z=["model","permissions","theme","config","exit","ide"],Q=$.filter((X)=>!Z.includes(X.name)).map((X)=>{let J;if(X.usage){let G=X.usage.replace(/^\/\w+\s*/,"").trim();if(G)J=G}if(X.aliases?.length){let G=`Aliases: ${X.aliases.join(", ")}`;J=J?`${J} | ${G}`:G}return{name:X.name,description:X.description,input:J?{hint:J}:void 0}});Z$.info(`[AcpSession ${this.id}] Sending available commands: ${JSON.stringify(Q.map((X)=>X.name))}`),this.sendUpdate({sessionUpdate:"available_commands_update",availableCommands:Q}),Z$.info(`[AcpSession ${this.id}] Sent ${Q.length} available commands`)}catch($){Z$.error(`[AcpSession ${this.id}] Failed to send available commands:`,$)}}async prompt($){F0.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(Z$.debug(`[AcpSession ${this.id}] Received prompt: ${Y.slice(0,100)}...`),p8(Y))return await this.handleSlashCommand(Y,Z.signal);let Q={sessionId:this.id,userId:"acp-user",workspaceRoot:this.cwd,messages:[...this.messages],signal:Z.signal,permissionMode:this.mapModeToPermissionMode(),confirmationHandler:{requestConfirmation:async(G)=>{return this.requestPermission(G)}}},X={signal:Z.signal,onContent:(G)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:G}})},onThinking:(G)=>{this.sendUpdate({sessionUpdate:"agent_thought_chunk",content:{type:"text",text:G}})},onToolStart:(G,q)=>{let K="function"in G?G.function.name:G.type,W=this.mapToolKind(q);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:G.id,status:"in_progress",title:`Executing ${K}`,content:[],kind:W})},onToolResult:async(G,q)=>{let K=[],W=q.metadata;if(W?.kind==="edit"&&typeof W.file_path==="string"&&typeof W.oldContent==="string"&&(typeof W.newContent==="string"||W.newContent===void 0))K.push({type:"diff",path:W.file_path,oldText:W.oldContent,newText:W.newContent??null});else if(q.displayContent){let F=typeof q.displayContent==="string"?q.displayContent:JSON.stringify(q.displayContent);K.push({type:"content",content:{type:"text",text:F}})}let U="function"in G?G.function.name:G.type,O=q.success?"completed":"failed";this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:G.id,status:O,content:K})},onTodoUpdate:(G)=>{this.sendPlanUpdate(G)}},J=await this.agent.chat(Y,Q,X);if(J)this.messages.push({role:"user",content:Y}),this.messages.push({role:"assistant",content:J});if(Z.signal.aborted)return{stopReason:"cancelled"};return{stopReason:"end_turn"}}catch(Y){if(Z.signal.aborted||Y instanceof Error&&Y.name==="AbortError")return{stopReason:"cancelled"};throw Z$.error(`[AcpSession ${this.id}] Prompt error:`,Y),Y}finally{if(this.pendingPrompt===Z)this.pendingPrompt=null}}cancel(){if(Z$.info(`[AcpSession ${this.id}] Cancel requested`),this.pendingPrompt)this.pendingPrompt.abort(),this.pendingPrompt=null,Z$.info(`[AcpSession ${this.id}] Cancelled successfully`);else Z$.warn(`[AcpSession ${this.id}] No pending prompt to cancel`)}async setMode($){let Z=["default","auto-edit","yolo","plan"];this.mode=Z.includes($)?$:"default",Z$.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(Z$.info(`[AcpSession ${this.id}] Model set to: ${$}`),this.agent)Z$.warn(`[AcpSession ${this.id}] Runtime model switching not yet implemented`)}async destroy(){if(this.cancel(),this.agent)await this.agent.destroy(),this.agent=null;F0.destroySession(this.id),Z$.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}">
2692
2692
  ${Q.text}
2693
2693
  </file>`)}else if(Y.type==="resource_link")Z.push(`[Resource: ${Y.uri}]`);return Z.join(`
2694
2694
  `)}sendUpdate($){let Z={sessionId:this.id,update:$};this.connection.sessionUpdate(Z).catch((Y)=>{Z$.warn(`[AcpSession ${this.id}] Failed to send update:`,Y)})}sendPlanUpdate($){let Z=$.map((Y)=>({content:Y.content,priority:Y.priority,status:Y.status}));Z$.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 Z$.debug(`[AcpSession ${this.id}] Auto-approving ${Z} in mode: ${this.mode}`),{approved:!0};if(this.mode==="plan"&&(Z==="write"||Z==="execute"))return Z$.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 Z$.debug(`[AcpSession ${this.id}] Using cached approval for: ${Y}`),{approved:!0};try{let Q=QM(),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:
@@ -2699,7 +2699,7 @@ ${Q.text}
2699
2699
  请检查:`),console.error(" 1. 配置文件格式是否正确 (~/.blade/config.json)"),console.error(" 2. 是否需要运行 blade 进行首次配置"),console.error(` 3. 配置文件权限是否正确
2700
2700
  `),process.exit(1)}if($.continue&&$.resume)throw Error("Cannot use both --continue and --resume flags simultaneously")},XX=($)=>{if($.outputFormat&&$.outputFormat!=="text"&&!$.print)throw Error("--output-format can only be used with --print flag");if($.inputFormat==="stream-json"&&$.print)h5.warn("⚠️ Warning: stream-json input format may not work as expected with --print")};H8();var JX={command:"doctor",describe:"Check the health of your Blade installation",handler:async()=>{console.log(`\uD83D\uDD0D Running Blade health check...
2701
2701
  `);let $=0;try{await l$.getInstance().initialize(),console.log("✅ Configuration: OK")}catch(Q){console.log("❌ Configuration: FAILED"),console.log(` Error: ${Q instanceof Error?Q.message:"未知错误"}`),$++}let Z=process.version;if(parseInt(Z.slice(1).split(".")[0])>=18)console.log(`✅ Node.js version: ${Z}`);else console.log(`⚠️ Node.js version: ${Z} (recommended: v18+)`),$++;try{let Q=await import("fs/promises"),X=process.cwd();await Q.access(X,(await import("fs")).constants.R_OK|(await import("fs")).constants.W_OK),console.log("✅ File system permissions: OK")}catch(Q){console.log("❌ File system permissions: FAILED"),console.log(" Error: Cannot read/write in current directory"),$++}try{await import("ink"),console.log("✅ Dependencies: OK")}catch(Q){console.log("❌ Dependencies: FAILED"),console.log(" Error: Missing required dependencies"),$++}if(console.log(`
2702
- \uD83D\uDCCA Health Check Summary:`),$===0)console.log("\uD83C\uDF89 All checks passed! Blade is ready to use.");else console.log(`⚠️ Found ${$} issue(s). Please resolve them for optimal performance.`),process.exit(1)}};var GX={command:"install [target]",describe:"Install Blade native build. Use [target] to specify version (stable, latest, or specific version)",builder:($)=>{return $.positional("target",{describe:"Version to install",type:"string",default:"stable",choices:["stable","latest"]}).option("force",{type:"boolean",describe:"Force reinstall",default:!1}).example([["$0 install","Install stable version"],["$0 install latest","Install latest version"],["$0 install --force","Force reinstall stable version"]])},handler:async($)=>{console.log(`\uD83D\uDCE6 Installing Blade ${$.target}...`);try{if($.force)console.log("\uD83D\uDD04 Force reinstall enabled");console.log("⬇️ Downloading..."),console.log("\uD83D\uDD27 Installing..."),console.log("✅ Installation completed successfully")}catch(Z){console.error(`❌ Installation failed: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}};d2();T4();M0();import VX from"os";import R6 from"path";function z8($){return typeof $==="string"?$:void 0}function a5($){if(!Array.isArray($))return;let Z=[];for(let Y of $)if(typeof Y==="string")Z.push(Y);else if(Y!=null)Z.push(String(Y));return Z}function pH(){console.log(`
2702
+ \uD83D\uDCCA Health Check Summary:`),$===0)console.log("\uD83C\uDF89 All checks passed! Blade is ready to use.");else console.log(`⚠️ Found ${$} issue(s). Please resolve them for optimal performance.`),process.exit(1)}};var GX={command:"install [target]",describe:"Install Blade native build. Use [target] to specify version (stable, latest, or specific version)",builder:($)=>{return $.positional("target",{describe:"Version to install",type:"string",default:"stable",choices:["stable","latest"]}).option("force",{type:"boolean",describe:"Force reinstall",default:!1}).example([["$0 install","Install stable version"],["$0 install latest","Install latest version"],["$0 install --force","Force reinstall stable version"]])},handler:async($)=>{console.log(`\uD83D\uDCE6 Installing Blade ${$.target}...`);try{if($.force)console.log("\uD83D\uDD04 Force reinstall enabled");console.log("⬇️ Downloading..."),console.log("\uD83D\uDD27 Installing..."),console.log("✅ Installation completed successfully")}catch(Z){console.error(`❌ Installation failed: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}};d2();T4();M0();import VX from"os";import R7 from"path";function z8($){return typeof $==="string"?$:void 0}function a5($){if(!Array.isArray($))return;let Z=[];for(let Y of $)if(typeof Y==="string")Z.push(Y);else if(Y!=null)Z.push(String(Y));return Z}function pH(){console.log(`
2703
2703
  blade mcp
2704
2704
  `),console.log(`管理 MCP 服务器
2705
2705
  `),console.log("Commands:"),console.log(" blade mcp add <name> <commandOrUrl> [args...] 添加 MCP 服务器"),console.log(" blade mcp remove <name> 删除 MCP 服务器 [aliases: rm]"),console.log(" blade mcp list 列出所有 MCP 服务器并检查健康状态 [aliases: ls]"),console.log(" blade mcp get <name> 获取服务器详情"),console.log(` blade mcp add-json <name> <json> 从 JSON 字符串添加服务器
@@ -2708,21 +2708,21 @@ blade mcp
2708
2708
  `),console.log(`使用 blade mcp <command> --help 查看各子命令的详细帮助
2709
2709
  `)}function mH($){return $.reduce((Z,Y)=>{let[Q,...X]=Y.split("=");return Z[Q]=X.join("="),Z},{})}function gH($){return $.reduce((Z,Y)=>{let[Q,...X]=Y.split(":");return Z[Q.trim()]=X.join(":").trim(),Z},{})}var uH={command:"add <name> [commandOrUrl] [args...]",describe:"添加 MCP 服务器",builder:($)=>{return $.positional("name",{type:"string",describe:"服务器名称",demandOption:!0}).positional("commandOrUrl",{type:"string",describe:"stdio: 命令 | http/sse: URL"}).positional("args",{type:"string",array:!0,describe:"stdio 命令参数",default:[]}).option("transport",{alias:"t",choices:["stdio","sse","http"],default:"stdio",describe:"传输类型"}).option("env",{alias:"e",type:"array",describe:"环境变量 (KEY=value)"}).option("header",{alias:"H",type:"array",describe:"HTTP 头 (Key: Value)"}).option("timeout",{type:"number",describe:"超时时间(毫秒)"}).option("global",{alias:"g",type:"boolean",default:!1,describe:"存储到全局配置(~/.blade/config.json)"}).example([["$0 mcp add github -- npx -y @modelcontextprotocol/server-github","Add stdio server (recommended)"],["$0 mcp add github npx @modelcontextprotocol/server-github -e GITHUB_TOKEN=xxx","Add stdio server with env"],['$0 mcp add api --transport http http://localhost:3000 -H "Auth: Bearer token"',"Add HTTP server"]])},handler:async($)=>{try{let{name:Z,commandOrUrl:Y,args:Q,transport:X,env:J,header:G,timeout:q}=$,K=$.global===!0,W=z8(Z),U=z8(Y),O=a5(Q)||[],F=a5(J),H=a5(G),_=typeof q==="number"?q:void 0,z=X==="stdio"||X==="sse"||X==="http"?X:"stdio",w=$["--"];if(Array.isArray(w)&&w.length>0)U=String(w[0]),O=w.slice(1).map((N)=>String(N));if(!W||!U)console.error("❌ 缺少必需参数: name 和 commandOrUrl"),console.log(`
2710
2710
  \uD83D\uDCA1 用法:`),console.log(" blade mcp add <name> <command> [args...]"),console.log(" blade mcp add <name> -- <command> [args...]"),console.log(`
2711
- 示例:`),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=O,F)B.env=mH(F)}else if(B.url=U,H)B.headers=gH(H);if(_!==void 0)B.timeout=_;await b0().addMcpServer(W,B,{scope:K?"global":"project"});let L=K?R6.join(VX.homedir(),".blade","config.json"):R6.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)}}},dH={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=R1(),Y=$.global===!0,Q=z8($.name);if(!Q)console.error("❌ 缺少必需参数: name"),process.exit(1);if(!Z[Q])console.error(`❌ 服务器 "${Q}" 不存在`),process.exit(1);await b0().removeMcpServer(Q,{scope:Y?"global":"project"}),console.log(`✅ MCP 服务器 "${Q}" 已删除`)}catch(Z){console.error(`❌ 删除失败: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}},cH={command:"list",describe:"列出所有 MCP 服务器并检查健康状态",aliases:["ls"],handler:async()=>{try{let $=R1();if(console.log(""),Object.keys($).length===0){console.log("暂无配置的 MCP 服务器");return}console.log(`检查 MCP 服务器健康状态...
2711
+ 示例:`),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=O,F)B.env=mH(F)}else if(B.url=U,H)B.headers=gH(H);if(_!==void 0)B.timeout=_;await b0().addMcpServer(W,B,{scope:K?"global":"project"});let L=K?R7.join(VX.homedir(),".blade","config.json"):R7.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)}}},dH={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=R1(),Y=$.global===!0,Q=z8($.name);if(!Q)console.error("❌ 缺少必需参数: name"),process.exit(1);if(!Z[Q])console.error(`❌ 服务器 "${Q}" 不存在`),process.exit(1);await b0().removeMcpServer(Q,{scope:Y?"global":"project"}),console.log(`✅ MCP 服务器 "${Q}" 已删除`)}catch(Z){console.error(`❌ 删除失败: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}},cH={command:"list",describe:"列出所有 MCP 服务器并检查健康状态",aliases:["ls"],handler:async()=>{try{let $=R1();if(console.log(""),Object.keys($).length===0){console.log("暂无配置的 MCP 服务器");return}console.log(`检查 MCP 服务器健康状态...
2712
2712
  `);let Z=e0.getInstance(),Y=Object.entries($).map(async([X,J])=>{try{let G=Z.getServerStatus(X);if(!G)await Z.registerServer(X,J),G=Z.getServerStatus(X);else if(G.status==="disconnected")await Z.connectServer(X);return{name:X,config:J,serverInfo:G}}catch(G){return{name:X,config:J,serverInfo:null,error:G}}}),Q=await Promise.all(Y);for(let{name:X,config:J,serverInfo:G,error:q}of Q){let K=G?.status||"disconnected",W=K==="connected"?"✓":"✗",U=K==="connected"?"Connected":"Failed";if(console.log(`${X}: ${J.type==="stdio"?J.command:J.url} - ${W} ${U}`),q&&K!=="connected")console.log(` 错误: ${q instanceof Error?q.message:String(q)}`)}console.log("");for(let{name:X}of Q)try{await Z.unregisterServer(X)}catch(J){}process.exit(0)}catch($){console.error(`❌ 列表获取失败: ${$ instanceof Error?$.message:"未知错误"}`),process.exit(1)}}},lH={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=R1(),Y=z8($.name);if(!Y)console.error("❌ 缺少必需参数: name"),process.exit(1);let Q=Z[Y];if(!Q)console.error(`❌ 服务器 "${Y}" 不存在`),process.exit(1);console.log(`
2713
2713
  服务器: ${Y}
2714
- `),console.log(JSON.stringify(Q,null,2))}catch(Z){console.error(`❌ 获取失败: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}},iH={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=z8($.json),Y=z8($.name);if(!Z||!Y)throw Error("缺少必需参数: name 或 json");let Q=JSON.parse(Z),X=$.global===!0;if(!Q.type)throw Error('配置必须包含 "type" 字段');await b0().addMcpServer(Y,Q,{scope:X?"global":"project"});let J=X?R6.join(VX.homedir(),".blade","config.json"):R6.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)}}},MX={command:"mcp",describe:"管理 MCP 服务器",builder:($)=>{return $.command(uH).command(dH).command(cH).command(lH).command(iH).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)pH(),process.exit(0)}};F2();f8();l4();function bN($){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 s$().initialize(process.cwd(),[])).plugins.length>0)await Y4();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(p8(X)){let K=await m8(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:O}=W;X=O?`Please use the "${U}" skill to help me with: ${O}`:`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}
2714
+ `),console.log(JSON.stringify(Q,null,2))}catch(Z){console.error(`❌ 获取失败: ${Z instanceof Error?Z.message:"未知错误"}`),process.exit(1)}}},iH={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=z8($.json),Y=z8($.name);if(!Z||!Y)throw Error("缺少必需参数: name 或 json");let Q=JSON.parse(Z),X=$.global===!0;if(!Q.type)throw Error('配置必须包含 "type" 字段');await b0().addMcpServer(Y,Q,{scope:X?"global":"project"});let J=X?R7.join(VX.homedir(),".blade","config.json"):R7.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)}}},MX={command:"mcp",describe:"管理 MCP 服务器",builder:($)=>{return $.command(uH).command(dH).command(cH).command(lH).command(iH).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)pH(),process.exit(0)}};F2();f8();l4();function bN($){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 s$().initialize(process.cwd(),[])).plugins.length>0)await Y4();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(p8(X)){let K=await m8(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:O}=W;X=O?`Please use the "${U}" skill to help me with: ${O}`:`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}
2715
2715
 
2716
- ${U}`}else{if(K.message)console.log(K.message);process.exit(0)}}let G=await G$.create({systemPrompt:Z.systemPrompt,appendSystemPrompt:Z.appendSystemPrompt,maxTurns:Z.maxTurns}),q;if(Z.appendSystemPrompt)q=await G.chatWithSystem(Z.appendSystemPrompt,X);else q=await G.chat(X,{messages:[],userId:"cli-user",sessionId:`print-${Date.now()}`,workspaceRoot:process.cwd()});if(Z.outputFormat==="json")console.log(JSON.stringify({response:q,input:X,model:Z.model,timestamp:new Date().toISOString()},null,2));else if(Z.outputFormat==="stream-json")console.log(JSON.stringify({type:"response",content:q}));else console.log(q);process.exit(0)}catch(Y){console.error(`Error: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}})}async function _W(){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 bN(X),await X.parse(),!0}catch(Y){console.error(`Print mode error: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}import FA from"chalk";var j7={port:{type:"number",describe:"Port to listen on (0 for auto)",default:0},hostname:{type:"string",describe:"Hostname to listen on",default:"127.0.0.1"},cors:{type:"array",describe:"Additional domains to allow for CORS",default:[]}};function y7($){return{port:$.port??0,hostname:$.hostname??"127.0.0.1",cors:$.cors??[]}}import{z as T7}from"zod";class Z6 extends Error{code;statusCode;constructor($,Z,Y=500){super(Z);this.code=$;this.statusCode=Y;this.name="BladeServerError"}toObject(){return{error:{code:this.code,message:this.message}}}}class g8 extends Z6{constructor($,Z){super("NOT_FOUND",Z?`${$} not found: ${Z}`:`${$} not found`,404)}}class E1 extends Z6{constructor($){super("BAD_REQUEST",$,400)}}var cp=T7.object({error:T7.object({code:T7.string(),message:T7.string()})});Q0();x2();import{Hono as ZA}from"hono";import{cors as YA}from"hono/cors";import{existsSync as fW,readFileSync as f7}from"node:fs";import{createServer as QA}from"node:http";import{networkInterfaces as XA}from"node:os";import{dirname as JA,extname as GA,join as a4}from"node:path";import{fileURLToPath as qA}from"node:url";import{WebSocketServer as KA}from"ws";Q0();import{Hono as RN}from"hono";import{z as u8}from"zod";M0();var GY=x("Service"),VN=u8.object({updates:u8.record(u8.any()),options:u8.object({scope:u8.enum(["local","project","global"]).optional(),immediate:u8.boolean().optional()}).optional()}),zW=()=>{let $=new RN;return $.get("/",async(Z)=>{try{let Y=f0();return Z.json(Y||{})}catch(Y){return GY.error("[ConfigRoutes] Failed to get config:",Y),Z.json({})}}),$.put("/",async(Z)=>{try{let Y=await Z.req.json(),Q=VN.safeParse(Y);if(!Q.success)throw new E1("Invalid config update format");let{updates:X,options:J}=Q.data;return await b0().updateConfig(X,J),Z.json({success:!0,updates:X})}catch(Y){throw GY.error("[ConfigRoutes] Failed to update config:",Y),Y}}),$.get("/permissions",async(Z)=>{try{let Y=f0();return Z.json(Y?.permissions||{})}catch(Y){return GY.error("[ConfigRoutes] Failed to get permissions:",Y),Z.json({})}}),$};x2();import{Hono as MN}from"hono";var BW=()=>{let $=new MN;return $.get("/health",(Z)=>{return Z.json({healthy:!0,version:Z1()})}),$.get("/info",(Z)=>{return Z.json({version:Z1(),platform:process.platform,arch:process.arch,nodeVersion:process.version,cwd:process.cwd()})}),$};Q0();d2();T4();M0();import{Hono as DN}from"hono";var Y6=x("Service"),wW=()=>{let $=new DN;return $.get("/",async(Z)=>{try{let Q=e0.getInstance().getAllServers(),X=Array.from(Q.entries()).map(([J,G])=>({id:J,name:J,status:G.status==="connected"?"connected":G.status==="connecting"?"connecting":G.lastError?"error":"offline",endpoint:G.config.command?`${G.config.command} ${(G.config.args||[]).join(" ")}`.trim():G.config.url||"Unknown",description:`MCP server: ${J}`,tools:G.tools.map((q)=>q.name),connectedAt:G.connectedAt?.toISOString(),error:G.lastError?.message}));return Z.json(X)}catch(Y){return Y6.error("[McpRoutes] Failed to get MCP servers:",Y),Z.json([])}}),$.post("/:name/connect",async(Z)=>{try{let Y=Z.req.param("name");return await e0.getInstance().connectServer(Y),Z.json({success:!0})}catch(Y){return Y6.error("[McpRoutes] Failed to connect MCP server:",Y),Z.json({success:!1,error:Y.message},500)}}),$.post("/:name/disconnect",async(Z)=>{try{let Y=Z.req.param("name");return await e0.getInstance().disconnectServer(Y),Z.json({success:!0})}catch(Y){return Y6.error("[McpRoutes] Failed to disconnect MCP server:",Y),Z.json({success:!1,error:Y.message},500)}}),$.delete("/:name",async(Z)=>{try{let Y=Z.req.param("name");await e0.getInstance().unregisterServer(Y);let X=f0();if(X?.mcpServers){let{[Y]:J,...G}=X.mcpServers;await b0().updateConfig({mcpServers:G})}return Z.json({success:!0})}catch(Y){return Y6.error("[McpRoutes] Failed to delete MCP server:",Y),Z.json({success:!1,error:Y.message},500)}}),$.post("/",async(Z)=>{try{let Y=await Z.req.json(),{name:Q,config:X}=Y;if(!Q||!X)return Z.json({success:!1,error:"Missing name or config"},400);await e0.getInstance().registerServer(Q,X);let G=f0();return await b0().updateConfig({mcpServers:{...G?.mcpServers,[Q]:X}}),Z.json({success:!0})}catch(Y){return Y6.error("[McpRoutes] Failed to add MCP server:",Y),Z.json({success:!1,error:Y.message},500)}}),$};Q0();M0();import{Hono as jN}from"hono";var E7=x("Service"),LW=()=>{let $=new jN;return $.get("/",async(Z)=>{try{let Y=g2(),Q=u2();return Z.json({configured:Y,current:Q})}catch(Y){return E7.error("[ModelsRoutes] Failed to get models:",Y),Z.json({configured:[],current:null})}}),$.post("/",async(Z)=>{try{let Y=await Z.req.json(),{provider:Q,name:X,model:J,baseUrl:G,apiKey:q}=Y;if(!J)throw new E1("model is required");let K=await b0().addModel({provider:Q||"openai-compatible",name:X||J,model:J,baseUrl:G||void 0,apiKey:q||void 0});return Z.json({success:!0,model:K})}catch(Y){throw E7.error("[ModelsRoutes] Failed to add model:",Y),Y}}),$.put("/:modelId",async(Z)=>{try{let Y=Z.req.param("modelId"),Q=await Z.req.json(),{baseUrl:X,apiKey:J,model:G}=Q;return await b0().updateModel(Y,{baseUrl:X||void 0,apiKey:J||void 0,model:G||void 0}),Z.json({success:!0})}catch(Y){throw E7.error("[ModelsRoutes] Failed to update model:",Y),Y}}),$.delete("/:modelId",async(Z)=>{try{let Y=Z.req.param("modelId");return await b0().removeModel(Y),Z.json({success:!0})}catch(Y){throw E7.error("[ModelsRoutes] Failed to delete model:",Y),Y}}),$};Q0();import{Hono as kN}from"hono";import{z as s1}from"zod";F2();U$();Q0();i3();RZ();import{Hono as yN}from"hono";import{streamSSE as TN}from"hono/streaming";import{LRUCache as EN}from"lru-cache";import{nanoid as Q6}from"nanoid";import{z as G1}from"zod";var k$=x("Service"),IN=G1.object({title:G1.string().optional(),projectPath:G1.string().optional()}),vN=G1.object({content:G1.string(),attachments:G1.array(G1.object({type:G1.enum(["file","image","url"]),path:G1.string().optional(),url:G1.string().optional(),content:G1.string().optional()})).optional(),permissionMode:G1.enum(["default","autoEdit","plan","spec","yolo"]).optional()}),PN=G1.object({title:G1.string().optional()}),_1=new Map,i4=new EN({max:100,ttl:1800000,dispose:($,Z)=>{if($.status==="running"||$.status==="waiting_permission")$.abortController.abort(),k$.debug(`[SessionRoutes] Run ${Z} disposed due to cache eviction`)}}),CN=($)=>{if(!$||typeof $!=="object")return $;let Z={...$},Y=200000;if(typeof Z.oldContent==="string"&&Z.oldContent.length>Y)delete Z.oldContent;if(typeof Z.newContent==="string"&&Z.newContent.length>Y)delete Z.newContent;return Z},NW=()=>{let $=new yN;return $.get("/",async(Z)=>{try{let Y=await S$.listSessions(),Q=new Set(Y.filter((U)=>U.relationType==="subagent").map((U)=>U.sessionId)),X=Array.from(_1.values()).filter((U)=>!Q.has(U.id)&&U.relationType!=="subagent").map((U)=>({sessionId:U.id,projectPath:U.projectPath,title:U.title,parentId:void 0,relationType:void 0,status:void 0,agentType:void 0,model:void 0,messageCount:U.messages.length,firstMessageTime:U.createdAt.toISOString(),lastMessageTime:new Date().toISOString(),hasErrors:!1,isActive:!0})),J=new Set(X.map((U)=>U.sessionId)),G=Y.filter((U)=>!_1.has(U.sessionId)&&!J.has(U.sessionId)&&U.relationType!=="subagent"),q=new Set(J),K=G.filter((U)=>{if(q.has(U.sessionId))return!1;return q.add(U.sessionId),!0}),W=[...X,...K];return Z.json(W)}catch(Y){return k$.error("[SessionRoutes] Failed to list sessions:",Y),Z.json([])}}),$.post("/",async(Z)=>{try{let Y=await Z.req.json(),Q=IN.safeParse(Y);if(!Q.success)throw new E1("Invalid request body");let{title:X,projectPath:J}=Q.data,G=Q6(12),q=J||Z.get("directory")||process.cwd(),K={id:G,projectPath:q,title:X||`Session ${G.slice(0,6)}`,createdAt:new Date,messages:[]};return _1.set(G,K),Z.json({sessionId:G,projectPath:q,title:K.title,parentId:void 0,relationType:void 0,status:void 0,agentType:void 0,model:void 0,messageCount:0,firstMessageTime:K.createdAt.toISOString(),lastMessageTime:K.createdAt.toISOString(),hasErrors:!1})}catch(Y){throw k$.error("[SessionRoutes] Failed to create session:",Y),Y}}),$.get("/:sessionId",async(Z)=>{let Y=Z.req.param("sessionId"),Q=_1.get(Y);if(Q)return Z.json({sessionId:Q.id,projectPath:Q.projectPath,title:Q.title,messageCount:Q.messages.length,firstMessageTime:Q.createdAt.toISOString(),lastMessageTime:new Date().toISOString(),hasErrors:!1,isActive:!0});try{let J=(await S$.listSessions()).find((G)=>G.sessionId===Y);if(!J)throw new g8("Session",Y);return Z.json(J)}catch(X){if(X instanceof g8)throw X;throw k$.error("[SessionRoutes] Failed to get session:",X),X}}),$.patch("/:sessionId",async(Z)=>{let Y=Z.req.param("sessionId");try{let Q=await Z.req.json(),X=PN.safeParse(Q);if(!X.success)throw new E1("Invalid request body");let{title:J}=X.data,G=_1.get(Y);if(G&&J)G.title=J;return Z.json({success:!0,title:J})}catch(Q){throw k$.error("[SessionRoutes] Failed to update session:",Q),Q}}),$.delete("/:sessionId",async(Z)=>{let Y=Z.req.param("sessionId"),Q=_1.get(Y);if(Q?.currentRunId){let X=i4.get(Q.currentRunId);if(X)X.abortController.abort(),y1.publish(Y,"run.cancelled",{runId:X.id}),i4.delete(Q.currentRunId)}try{await S$.deleteSession(Y)}catch(X){k$.warn("[SessionRoutes] Failed to delete session file:",X)}return _1.delete(Y),Z.json({success:!0})}),$.get("/:sessionId/message",async(Z)=>{let Y=Z.req.param("sessionId");try{let Q=await S$.loadSession(Y);return Z.json(Q)}catch(Q){return k$.error("[SessionRoutes] Failed to get messages:",Q),Z.json([])}}),$.get("/:sessionId/events",async(Z)=>{let Y=Z.req.param("sessionId"),Q=_1.get(Y);if(!Q){let X=Z.get("directory")||process.cwd();Q={id:Y,projectPath:X,title:`Session ${Y.slice(0,6)}`,createdAt:new Date,messages:[]},_1.set(Y,Q)}return TN(Z,async(X)=>{await X.writeSSE({data:JSON.stringify({type:"connected",properties:{sessionId:Y,timestamp:Date.now()}})});let G=y1.subscribe((K)=>{if(K.sessionId!==Y)return;X.writeSSE({data:JSON.stringify({type:K.type,properties:{sessionId:K.sessionId,...K.properties}})}).catch(()=>{})}),q=setInterval(()=>{if(!X.aborted)X.writeSSE({data:JSON.stringify({type:"heartbeat",properties:{timestamp:Date.now()}})}).catch(()=>{})},15000);X.onAbort(()=>{clearInterval(q),G()});while(!0)if(await new Promise((K)=>setTimeout(K,1000)),X.aborted)break})}),$.post("/:sessionId/message",async(Z)=>{let Y=Z.req.param("sessionId"),Q=await Z.req.json(),X=vN.safeParse(Q);if(!X.success)throw new E1("Invalid message format");let{content:J,permissionMode:G}=X.data,q=G||"default",K=Z.get("directory")||process.cwd(),W=_1.get(Y);if(!W)W={id:Y,projectPath:K,title:`Session ${Y.slice(0,6)}`,createdAt:new Date,messages:[]},_1.set(Y,W);let U=Q6(12),O=new AbortController,F={id:U,sessionId:Y,status:"running",abortController:O,createdAt:new Date};return i4.set(U,F),W.currentRunId=U,SN(F,W,J,q).catch((H)=>{k$.error(`[SessionRoutes] Run ${U} failed:`,H)}),Z.json({runId:U,status:"running"},202)}),$.post("/:sessionId/abort",async(Z)=>{let Y=Z.req.param("sessionId"),Q=_1.get(Y);if(Q?.currentRunId){let X=i4.get(Q.currentRunId);if(X)X.abortController.abort(),X.status="cancelled",y1.publish(Y,"run.cancelled",{runId:X.id})}return Z.json({success:!0})}),$.get("/:sessionId/status",async(Z)=>{let Y=Z.req.param("sessionId"),Q=_1.get(Y);if(!Q?.currentRunId)return Z.json({sessionId:Y,status:"idle"});let X=i4.get(Q.currentRunId);return Z.json({sessionId:Y,runId:Q.currentRunId,status:X?.status||"idle"})}),$};async function SN($,Z,Y,Q){let{abortController:X,sessionId:J,id:G}=$,q=Q6(12),K=Q6(12),W=(U,O)=>{y1.publish(J,U,O)};try{W("message.created",{messageId:q,role:"user",content:Y}),W("session.status",{status:"running"}),W("message.created",{messageId:K,role:"assistant",content:""});let U=await G$.create({}),O=async(z)=>{let w=Q6(12),B=300000;$.status="waiting_permission";let L=new Promise((M)=>{let b=setTimeout(()=>{k$.warn(`[SessionRoutes] Permission ${w} timed out after 300000ms`),W("permission.timeout",{requestId:w}),M({approved:!1,reason:"timeout"})},300000);$.pendingPermission={permissionId:w,resolve:(j)=>{clearTimeout(b),M(j)},details:z}});W("permission.asked",{requestId:w,toolName:z.toolName,description:z.message,args:z.args,details:z}),k$.info(`[SessionRoutes] Permission request created: ${w}, runId: ${G}`);let N=await L;return k$.info(`[SessionRoutes] Permission response received: ${w}, approved: ${N.approved}`),$.status="running",$.pendingPermission=void 0,N},F={messages:Z.messages,userId:"web-user",sessionId:J,workspaceRoot:Z.projectPath,signal:X.signal,permissionMode:Q,confirmationHandler:{requestConfirmation:O}},H={stream:!0,onContentDelta:async(z)=>{W("message.delta",{messageId:K,delta:z})},onThinkingDelta:async(z)=>{W("thinking.delta",{delta:z})},onStreamEnd:async()=>{W("message.complete",{messageId:K}),W("thinking.completed",{})},onToolStart:async(z,w)=>{if(z.type!=="function")return;W("tool.start",{messageId:K,toolName:z.function.name,toolCallId:z.id,arguments:z.function.arguments,toolKind:w})},onToolResult:async(z,w)=>{if(z.type!=="function")return;W("tool.result",{messageId:K,toolName:z.function.name,toolCallId:z.id,success:!w.error,summary:w.metadata?.summary,output:w.displayContent,metadata:CN(w.metadata)})},onTokenUsage:async(z)=>{W("token.usage",z)},onTodoUpdate:async(z)=>{W("todo.updated",{todos:z})}},_=await U.chat(Y,F,H);Z.messages.push({role:"user",content:Y},{role:"assistant",content:_}),$.status="completed",W("session.completed",{runId:G}),W("session.status",{status:"idle"})}catch(U){k$.error("[SessionRoutes] Agent execution error:",U),$.status="failed",W("session.error",{error:U instanceof Error?U.message:"Unknown error"}),W("session.status",{status:"error"})}}function AW($,Z,Y){k$.info(`[SessionRoutes] Looking for permission ${Z} in session ${$}`),k$.info(`[SessionRoutes] Active runs: ${i4.size}`);for(let[Q,X]of i4.entries())if(k$.info(`[SessionRoutes] Checking run ${Q}: sessionId=${X.sessionId}, pendingPermission=${X.pendingPermission?.permissionId}`),X.sessionId===$&&X.pendingPermission?.permissionId===Z)return X.pendingPermission.resolve(Y),k$.info(`[SessionRoutes] Permission ${Z} responded, runId: ${X.id}`),!0;return k$.error(`[SessionRoutes] Permission not found: ${Z}`),!1}var qY=x("Service"),fN=s1.object({approved:s1.boolean(),remember:s1.boolean().optional(),scope:s1.enum(["once","session"]).optional(),targetMode:s1.enum(["default","autoEdit","plan","spec","yolo"]).optional(),feedback:s1.string().optional(),answers:s1.record(s1.union([s1.string(),s1.array(s1.string())])).optional()}),bW=()=>{let $=new kN;return $.post("/:permissionId",async(Z)=>{let Y=Z.req.param("permissionId"),Q=Z.req.query("sessionId");qY.info(`[PermissionRoutes] Received permission response: permissionId=${Y}, sessionId=${Q}`);try{let X=await Z.req.json(),J=fN.safeParse(X);if(!J.success)throw new E1("Invalid permission response format");let{approved:G,remember:q,scope:K,targetMode:W,feedback:U,answers:O}=J.data;if(!Q)throw new E1("sessionId query parameter is required");if(!AW(Q,Y,{approved:G,reason:U,scope:K,targetMode:W,feedback:U,answers:O}))throw new g8("Permission request",Y);return qY.info(`[PermissionRoutes] Permission ${Y} ${G?"approved":"denied"}`),Z.json({success:!0,approved:G,remember:q})}catch(X){throw qY.error("[PermissionRoutes] Failed to respond to permission:",X),X}}),$};Q0();import{Hono as pN}from"hono";Q0();w8();var v7=x("Service"),hN="https://models.dev/api.json",xN=3600000,I7=null,RW=async()=>{if(I7&&Date.now()-I7.timestamp<xN)return I7.data;try{v7.info("\uD83D\uDCE1 Fetching models.dev data...");let $=await fetch(hN,{headers:{"User-Agent":"Blade-CLI/1.0"}});if(!$.ok)throw Error(`HTTP ${$.status}: ${$.statusText}`);let Z=await $.json();return I7={data:Z,timestamp:Date.now()},v7.info(`✅ Loaded ${Object.keys(Z).length} providers from models.dev`),Z}catch($){throw v7.error("❌ Failed to fetch models.dev data:",$),$}},P7=async()=>{let $=await RW(),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:O9[Y]||O9.default,description:`${X} 个模型`,isOAuth:!1,envVars:Q.env||[],docUrl:Q.doc,defaultBaseUrl:M6[Y],bladeProvider:CX(Y)})}return Z.sort((Y,Q)=>{let X=U9.indexOf(Y.id),J=U9.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)})},C7=async($)=>{let Y=(await RW())[$];if(!Y?.models)return v7.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}))};w8();var VW=x("Service"),MW=()=>{let $=new pN;return $.get("/",async(Z)=>{try{let Y=await P7(),Q=Object.entries(V6).map(([X,J])=>({id:X,name:X.charAt(0).toUpperCase()+X.slice(1),icon:J.icon,description:J.description,isOAuth:!0,envVars:[],bladeProvider:J.bladeProvider}));return Z.json([...Y,...Q])}catch(Y){return VW.error("[ProviderRoutes] Failed to list providers:",Y),Z.json([])}}),$.get("/:providerId/models",async(Z)=>{let Y=Z.req.param("providerId");try{let Q=await C7(Y);return Z.json(Q)}catch(Q){return VW.error("[ProviderRoutes] Failed to list models:",Q),Z.json([])}}),$};Q0();K2();y9();import{Hono as mN}from"hono";import*as X4 from"node:fs/promises";import{homedir as gN}from"node:os";import*as S7 from"node:path";var r4=x("Service"),KY=S7.join(gN(),".blade","skills-config.json");async function DW(){try{let $=await X4.readFile(KY,"utf-8");return JSON.parse($)}catch{return{disabled:[]}}}async function uN($){await X4.mkdir(S7.dirname(KY),{recursive:!0}),await X4.writeFile(KY,JSON.stringify($,null,2))}async function dN($,Z){let Y=await DW();if(Z)Y.disabled=Y.disabled.filter((Q)=>Q!==$);else if(!Y.disabled.includes($))Y.disabled.push($);await uN(Y)}var d8=null,cN=300000;async function lN(){if(d8&&Date.now()-d8.timestamp<cN)return d8.data;try{let $=await fetch("https://api.github.com/repos/anthropics/skills/contents/skills",{headers:{Accept:"application/vnd.github.v3+json","User-Agent":"Blade-Skills-Catalog"}});if(!$.ok)return r4.warn(`GitHub API returned ${$.status}`),d8?.data||[];let Z=await $.json(),Y=[];for(let Q of Z){if(Q.type!=="dir")continue;let X=`Official ${Q.name} skill`;try{let J=await fetch(`https://raw.githubusercontent.com/anthropics/skills/main/skills/${Q.name}/SKILL.md`,{headers:{"User-Agent":"Blade-Skills-Catalog"}});if(J.ok){let q=(await J.text()).match(/^#[^\n]*\n+([^\n#]+)/);if(q)X=q[1].trim().slice(0,100)}}catch{}Y.push({name:Q.name,description:X,tag:"Official",author:"Anthropic"})}return d8={data:Y,timestamp:Date.now()},Y}catch($){return r4.warn("Failed to fetch skills catalog from GitHub:",$),d8?.data||[]}}var jW=()=>{let $=new mN;return $.get("/",async(Z)=>{try{let Y=J$();await Y.initialize();let Q=Y.getAll(),X=await DW(),J=Q.map((G)=>({id:G.name,name:G.name,enabled:!X.disabled.includes(G.name),description:G.description||"",version:G.version||"1.0.0",provider:"Local",location:G.source==="builtin"?"Built-in":G.basePath,capabilities:["prompts"],allowedTools:G.allowedTools||[]}));return Z.json(J)}catch(Y){return r4.error("[SkillsRoutes] Failed to get skills:",Y),Z.json([])}}),$.post("/:name/toggle",async(Z)=>{try{let Y=Z.req.param("name"),Q=await Z.req.json();return await dN(Y,Q.enabled),Z.json({success:!0,enabled:Q.enabled})}catch(Y){return r4.error("[SkillsRoutes] Failed to toggle skill:",Y),Z.json({success:!1,error:Y.message},500)}}),$.delete("/:name",async(Z)=>{try{let Y=Z.req.param("name"),Q=`${process.env.HOME}/.blade/skills/${Y}`;return await X4.rm(Q,{recursive:!0,force:!0}),await J$().refresh(),Z.json({success:!0})}catch(Y){return r4.error("[SkillsRoutes] Failed to uninstall skill:",Y),Z.json({success:!1,error:Y.message},500)}}),$.post("/install",async(Z)=>{try{let Y=await Z.req.json(),Q=h6(),X=J$(),J=!1;if(Y.source==="catalog"&&Y.name){if(J=await Q.installOfficialSkill(Y.name),!J)return Z.json({success:!1,error:"Failed to install skill from catalog"},500)}else if(Y.source==="repo"&&Y.url){if(J=await Q.installFromRepo(Y.url,Y.name),!J)return Z.json({success:!1,error:"Failed to install skill from repository. Make sure the repo contains a SKILL.md file."},500)}else if(Y.source==="local"&&Y.path){if(J=await Q.installFromLocal(Y.path,Y.name),!J)return Z.json({success:!1,error:"Failed to install skill from local path. Make sure the path exists and contains a SKILL.md file."},500)}else return Z.json({success:!1,error:"Invalid install parameters. Required: source with corresponding url/path/name"},400);return await X.refresh(),Z.json({success:!0})}catch(Y){return r4.error("[SkillsRoutes] Failed to install skill:",Y),Z.json({success:!1,error:Y.message},500)}}),$.get("/catalog",async(Z)=>{try{let Y=await lN();return Z.json(Y)}catch(Y){return r4.error("[SkillsRoutes] Failed to get catalog:",Y),Z.json([])}}),$};Q0();C4();l4();x3();import iN from"fast-glob";import{Hono as rN}from"hono";import{execSync as aN}from"node:child_process";import{readdir as nN}from"node:fs/promises";import k7 from"node:path";var X6=x("Service"),oN=($)=>{try{return aN("git rev-parse --abbrev-ref HEAD",{cwd:$,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||null}catch{return null}},sN=[...X1.map(($)=>`${$}/**`),...X1,...D8.map(($)=>`**/${$}`)],tN=new Set(["/theme","/model","/permissions","/mcp","/skills","/exit","/resume","/ide","/login","/logout"]),yW=()=>{let $=new rN;return $.get("/commands",async(Z)=>{try{let Y=Z.req.query("q")||"",Q=D7(Y).filter((X)=>!tN.has(X.command));return Z.json(Q)}catch(Y){return X6.error("[SuggestionsRoutes] Failed to get command suggestions:",Y),Z.json([])}}),$.get("/files",async(Z)=>{try{let Y=Z.req.query("q")||"",Q=Z.get("directory")||process.cwd(),X=Math.min(Number(Z.req.query("limit"))||100,1000),G=(await iN("**/*",{cwd:Q,dot:!1,followSymbolicLinks:!1,onlyFiles:!1,markDirectories:!0,unique:!0,ignore:sN})).map((W)=>W.replace(/\\/g,"/"));if(!Y)return Z.json(G.slice(0,X));let q=Y.toLowerCase(),K=G.filter((W)=>W.toLowerCase().includes(q)).slice(0,X);return Z.json(K)}catch(Y){return X6.error("[SuggestionsRoutes] Failed to get file suggestions:",Y),Z.json([])}}),$.get("/files/tree",async(Z)=>{try{let Y=Z.get("directory")||process.cwd(),Q=Z.req.query("path")||"",X=Q?k7.join(Y,Q):Y,G=(await nN(X,{withFileTypes:!0})).map((W)=>({name:W.name,path:Q?`${Q}/${W.name}`:W.name,type:W.isDirectory()?"dir":"file"}));G.sort((W,U)=>{if(W.type!==U.type)return W.type==="dir"?-1:1;return W.name.localeCompare(U.name)});let q=new Set(X1),K=G.filter((W)=>{let U=W.name;if(U.startsWith("."))return!1;if(q.has(U))return!1;for(let O of D8)if(U.match(new RegExp(O.replace("*",".*"))))return!1;return!0});return Z.json(K)}catch(Y){return X6.error("[SuggestionsRoutes] Failed to get file tree:",Y),Z.json([])}}),$.get("/files/content",async(Z)=>{try{let Y=Z.req.query("path");if(!Y)return Z.json({error:"Missing file path"},400);let Q=Z.get("directory")||process.cwd(),X=k7.resolve(Q,Y),J=k7.relative(Q,X);if(J.startsWith("..")||k7.isAbsolute(J))return Z.json({error:"Invalid file path"},400);let G=a2(),q=await G.stat(X);if(!q?.isFile)return Z.json({error:"File not found"},404);let K=200000,W=await G.readTextFile(X),U=W.length>K;return Z.json({path:Y,content:U?W.slice(0,K):W,truncated:U,size:q.size})}catch(Y){return X6.error("[SuggestionsRoutes] Failed to get file content:",Y),Z.json({error:"Failed to read file"},500)}}),$.get("/git-info",async(Z)=>{try{let Y=Z.get("directory")||process.cwd(),Q=oN(Y);return Z.json({branch:Q})}catch(Y){return X6.error("[SuggestionsRoutes] Failed to get git info:",Y),Z.json({branch:null})}}),$};Q0();import{Hono as eN}from"hono";var J4=x("Service"),c8=new Map,TW=2097152,EW=65536;function IW(){return typeof globalThis.Bun<"u"}async function $A($,Z,Y){if(IW()){let{spawn:J}=await import("bun-pty"),G=J($,Z,{name:"xterm-256color",cwd:Y.cwd,env:Y.env});return{pid:G.pid,write:(q)=>G.write(q),resize:(q,K)=>G.resize(q,K),kill:()=>G.kill(),onData:(q)=>G.onData(q),onExit:(q)=>G.onExit(q)}}let X=(await import("node-pty")).spawn($,Z,{name:"xterm-256color",cwd:Y.cwd,env:Y.env,cols:80,rows:24});return{pid:X.pid,write:(J)=>X.write(J),resize:(J,G)=>X.resize(J,G),kill:()=>X.kill(),onData:(J)=>{X.onData(J)},onExit:(J)=>{X.onExit(J)}}}var UY=void 0,WY;if(IW())try{let{createBunWebSocket:$}=await import("hono/bun"),Z=$();WY=Z.upgradeWebSocket,UY=Z.websocket}catch($){J4.warn("[Terminal] Failed to initialize Bun WebSocket support:",$)}async function vW($,Z){let Y=`term-${Date.now()}`;J4.info(`[Terminal] New connection: ${Y}, cwd: ${$}`);let Q=process.platform==="win32"?"powershell.exe":process.env.SHELL||"/bin/zsh",X=Q.endsWith("sh")?["-l"]:[],J=await $A(Q,X,{cwd:$,env:{...process.env,TERM:"xterm-256color",COLORTERM:"truecolor"}}),G={id:Y,process:J,cwd:$,buffer:"",subscribers:new Set};if(c8.set(Y,G),G.subscribers.add(Z),J.onData((q)=>{let K=!1;for(let W of G.subscribers)try{W.send(q),K=!0}catch{G.subscribers.delete(W)}if(K)return;if(G.buffer+=q,G.buffer.length>TW)G.buffer=G.buffer.slice(-TW)}),J.onExit(({exitCode:q})=>{J4.info(`[Terminal] Process exited: ${Y}, code: ${q}`);for(let K of G.subscribers)try{K.close()}catch{}c8.delete(Y)}),G.buffer){let q=G.buffer;G.buffer="";for(let K=0;K<q.length;K+=EW)Z.send(q.slice(K,K+EW))}return{session:G,cleanup:()=>{if(J4.info(`[Terminal] Connection closed: ${Y}`),G.subscribers.delete(Z),G.subscribers.size===0){try{G.process.kill()}catch{}c8.delete(Y)}}}}function PW($,Z){$.on("connection",async(Y,Q)=>{let X=new URL(Q.url||"/",`http://${Q.headers.host}`);if(!X.pathname.endsWith("/terminal/ws")){Y.close();return}let J=X.searchParams.get("cwd")||Z()||process.cwd();try{let{session:G,cleanup:q}=await vW(J,{send:(K)=>Y.send(K),close:()=>Y.close()});Y.on("message",(K)=>{try{G.process.write(String(K))}catch(W){J4.error("[Terminal] Failed to write to PTY:",W)}}),Y.on("close",q),Y.on("error",q)}catch(G){J4.error("[Terminal] Failed to spawn PTY:",G),Y.close()}})}var CW=()=>{let $=new eN;if($.get("/status",(Z)=>{let Y=Array.from(c8.values()).map((Q)=>({id:Q.id,cwd:Q.cwd}));return Z.json({active:Y.length,terminals:Y})}),$.post("/kill/:terminalId",(Z)=>{let Y=Z.req.param("terminalId"),Q=c8.get(Y);if(Q){try{Q.process.kill()}catch{}for(let X of Q.subscribers)X.close();return c8.delete(Y),Z.json({success:!0})}return Z.json({success:!1,error:"Terminal not found"},404)}),WY)$.get("/ws",WY((Z)=>{let Y=Z.req.query("cwd")||Z.get("directory")||process.cwd(),Q;return{async onOpen(X,J){try{Q=await vW(Y,{send:(G)=>J.send(G),close:()=>J.close()})}catch(G){J4.error("[Terminal] Failed to spawn PTY:",G),J.close()}},onMessage(X){if(!Q)return;try{Q.session.process.write(String(X.data))}catch(J){J4.error("[Terminal] Failed to write to PTY:",J)}},onClose(){Q?.cleanup()}}}));else $.get("/ws",(Z)=>{return Z.json({message:"WebSocket endpoint - connect via ws:// protocol",hint:"Use WebSocket client to connect to this endpoint"})});return $};var z1=x("Service"),OY=[];function WA(){let $=JA(qA(import.meta.url)),Z=[a4($,"web"),a4(process.cwd(),"dist/web"),a4(process.cwd(),"packages/cli/dist/web")];for(let Y of Z){let Q=a4(Y,"index.html");if(fW(Q)){if(f7(Q,"utf-8").includes("/assets/"))return z1.debug(`[Server] Found web dist at: ${Y}`),Y}}return null}function UA(){let $=new ZA;$.onError((Y,Q)=>{if(z1.error("[Server] Request error:",Y),Y instanceof Z6)return Q.json(Y.toObject(),Y.statusCode);let X=Y instanceof Error?Y.message:String(Y);return Q.json({error:{code:"INTERNAL_ERROR",message:X}},500)}),$.use(async(Y,Q)=>{let X=process.env.BLADE_SERVER_PASSWORD;if(!X)return Q();let J=Y.req.path;if(J==="/"||J.startsWith("/assets/")||J.endsWith(".html")||J.endsWith(".js")||J.endsWith(".css"))return Q();let G=Y.req.header("Authorization");if(!G?.startsWith("Basic "))return Y.header("WWW-Authenticate",'Basic realm="Blade Server"'),Y.json({error:{code:"UNAUTHORIZED",message:"Authentication required"}},401);let q=Buffer.from(G.slice(6),"base64").toString(),[K,W]=q.split(":"),U=process.env.BLADE_SERVER_USERNAME??"blade";if(K!==U||W!==X)return Y.json({error:{code:"UNAUTHORIZED",message:"Invalid credentials"}},401);return Q()}),$.use(async(Y,Q)=>{let X=Y.req.path==="/health"||Y.req.path==="/global/health"||Y.req.path.startsWith("/assets/");if(!X)z1.debug(`[Server] ${Y.req.method} ${Y.req.path}`);let J=Date.now();if(await Q(),!X){let G=Date.now()-J;z1.debug(`[Server] ${Y.req.method} ${Y.req.path} - ${Y.res.status} (${G}ms)`)}}),$.use(YA({origin(Y){if(!Y)return;if(Y.startsWith("http://localhost:"))return Y;if(Y.startsWith("http://127.0.0.1:"))return Y;if(Y==="tauri://localhost"||Y==="http://tauri.localhost")return Y;if(OY.includes(Y))return Y;return}})),$.use(async(Y,Q)=>{let X=Y.req.query("directory")||Y.req.header("x-blade-directory")||process.cwd();try{X=decodeURIComponent(X)}catch{}return Y.set("directory",X),Q()}),$.route("/global",BW()),$.route("/sessions",NW()),$.route("/configs",zW()),$.route("/permissions",bW()),$.route("/providers",MW()),$.route("/models",LW()),$.route("/suggestions",yW()),$.route("/terminal",CW()),$.route("/mcp",wW()),$.route("/skills",jW()),$.get("/health",(Y)=>{return Y.json({healthy:!0,version:Z1()})});let Z=WA();if(Z)z1.info(`[Server] Serving static files from ${Z}`),$.get("/assets/*",(Y)=>{let Q=a4(Z,Y.req.path);if(!fW(Q))return Y.json({error:{code:"NOT_FOUND",message:`File not found: ${Y.req.path}`}},404);let X=f7(Q),J=GA(Q).toLowerCase(),q={".js":"application/javascript",".css":"text/css",".html":"text/html",".json":"application/json",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".ico":"image/x-icon",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".eot":"application/vnd.ms-fontobject"}[J]||"application/octet-stream";return new Response(X,{headers:{"Content-Type":q,"Cache-Control":"public, max-age=31536000, immutable"}})}),$.get("/",(Y)=>{let Q=a4(Z,"index.html"),X=f7(Q,"utf-8");return Y.html(X)}),$.get("*",(Y)=>{let Q=Y.req.path;if(Q.includes("."))return Y.json({error:{code:"NOT_FOUND",message:`File not found: ${Q}`}},404);let X=a4(Z,"index.html"),J=f7(X,"utf-8");return Y.html(J)});else z1.warn('[Server] Web UI not found. Run "cd web && pnpm build" to enable web interface.'),$.get("/",(Y)=>{return Y.json({message:"Blade API Server",version:Z1(),webUI:!1,hint:'Web UI not built. Run "cd web && pnpm build" to enable.',endpoints:{health:"/health",sessions:"/sessions",configs:"/configs",permissions:"/permissions",providers:"/providers"}})}),$.all("*",(Y)=>{return Y.json({error:{code:"NOT_FOUND",message:`Route not found: ${Y.req.path}`}},404)});return $}function J6(){let $=XA(),Z=[];for(let Y of Object.keys($)){let Q=$[Y];if(!Q)continue;for(let X of Q){if(X.internal||X.family!=="IPv4")continue;if(X.address.startsWith("172."))continue;Z.push(X.address)}}return Z}function SW(){return typeof globalThis.Bun<"u"}function kW($,Z){let Y=globalThis.Bun,Q=(J)=>{try{return Y.serve({hostname:Z.hostname,port:J,fetch:$.fetch,idleTimeout:0,websocket:UY})}catch(G){z1.error("Failed to start Bun server:",G);return}},X=Z.port===0?Q(4096)??Q(0):Q(Z.port);if(!X)throw Error(`Failed to start Bun server on port ${Z.port}`);return{url:X.url,port:X.port,hostname:X.hostname,stop:async()=>{X.stop(!0)}}}function OA($,Z){return new Promise((Y,Q)=>{let X=QA(async(W,U)=>{let O=new URL(W.url||"/",`http://${W.headers.host}`),F=new Headers;for(let[z,w]of Object.entries(W.headers))if(w)if(Array.isArray(w))for(let B of w)F.append(z,B);else F.set(z,w);let H;if(W.method!=="GET"&&W.method!=="HEAD")H=(await new Promise((w)=>{let B=[];W.on("data",(L)=>B.push(L)),W.on("end",()=>w(Buffer.concat(B)))})).toString();let _=new Request(O.toString(),{method:W.method,headers:F,body:H});try{let z=await $.fetch(_);if(U.statusCode=z.status,z.headers.forEach((w,B)=>{U.setHeader(B,w)}),z.body){let w=z.body.getReader(),B=async()=>{let{done:L,value:N}=await w.read();if(L){U.end();return}return U.write(N),B()};await B()}else{let w=await z.text();U.end(w)}}catch(z){z1.error("[Server] Node request error:",z),U.statusCode=500,U.end(JSON.stringify({error:{code:"INTERNAL_ERROR",message:"Internal server error"}}))}}),J=new KA({noServer:!0}),G=process.cwd();PW(J,()=>G),X.on("upgrade",(W,U,O)=>{if(new URL(W.url||"/",`http://${W.headers.host}`).pathname==="/terminal/ws")J.handleUpgrade(W,U,O,(H)=>{J.emit("connection",H,W)});else U.destroy()});let q=(W)=>{return new Promise((U,O)=>{X.once("error",(F)=>{if(F.code==="EADDRINUSE")O(F);else O(F)}),X.listen(W,Z.hostname,()=>{let F=X.address();if(F&&typeof F==="object")U(F.port);else U(W)})})};(async()=>{let W;if(Z.port===0)try{W=await q(4096)}catch{W=await q(0)}else W=await q(Z.port);let U=new URL(`http://${Z.hostname==="0.0.0.0"?"localhost":Z.hostname}:${W}`);Y({url:U,port:W,hostname:Z.hostname,stop:async()=>{return new Promise((O)=>{J.close(()=>{X.close(()=>O())})})}})})().catch(Q)})}var l8;((Mg)=>{let $,Z;function Y(){if(!Z)Z=UA();return Z}Mg.getApp=Y;function Q(G){OY=G.cors??[];let q=Y();if(SW())$=kW(q,G),z1.info(`[Server] Blade server listening on ${$.url} (Bun runtime)`);else throw Error("Blade web server requires Bun runtime. Please run with Bun: `bun run blade web` or install Bun from https://bun.sh");let K=$;return{url:K.url,port:K.port,hostname:K.hostname,stop:async()=>{if($)await $.stop(),$=void 0,Z=void 0,z1.info("[Server] Blade server stopped")}}}Mg.listen=Q;async function X(G){OY=G.cors??[];let q=Y();if(SW())$=kW(q,G),z1.info(`[Server] Blade server listening on ${$.url} (Bun runtime)`);else $=await OA(q,G),z1.info(`[Server] Blade server listening on ${$.url} (Node.js runtime)`);let K=$;return{url:K.url,port:K.port,hostname:K.hostname,stop:async()=>{if($)await $.stop(),$=void 0,Z=void 0,z1.info("[Server] Blade server stopped")}}}Mg.listenAsync=X;function J(){return $!==void 0}Mg.isRunning=J})(l8||={});M0();var hW={command:"serve",describe:"Start a headless Blade server (no browser)",builder:j7,handler:async($)=>{let Z=y7($);if(await m2(),!process.env.BLADE_SERVER_PASSWORD)console.log(FA.yellow("Warning: BLADE_SERVER_PASSWORD is not set; server is unsecured."));let Y=await l8.listenAsync(Z);if(console.log(`Blade server listening on http://${Y.hostname}:${Y.port}`),Z.hostname==="0.0.0.0"){let Q=J6();for(let X of Q)console.log(` Network: http://${X}:${Y.port}`)}await new Promise(()=>{}),await Y.stop()}};import{execSync as NA}from"child_process";E4();import*as n4 from"fs/promises";import*as G4 from"path";import xW from"semver";import{fileURLToPath as HA}from"url";var FY="blade-code",_A="https://cdn.jsdelivr.net/npm/blade-code@latest/CHANGELOG.md",pW=G4.join(process.env.HOME||process.env.USERPROFILE||".",".blade"),mW=G4.join(pW,"version-cache.json"),zA=3600000,BA=`https://registry.npmjs.org/${FY}/latest`;async function wA(){try{if(process.env.BLADE_VERSION)return process.env.BLADE_VERSION;let $=HA(import.meta.url),Z=G4.dirname($),Y=[G4.join(Z,"..","..","package.json"),G4.join(Z,"..","package.json"),G4.join(process.cwd(),"package.json")];for(let Q of Y)try{let X=await n4.readFile(Q,"utf-8"),J=JSON.parse(X);if(J.name===FY&&J.version)return J.version}catch{}return"unknown"}catch{return"unknown"}}async function gW(){try{let $=await n4.readFile(mW,"utf-8"),Z=JSON.parse($);if(Date.now()-Z.checkedAt<zA)return Z;return{...Z,checkedAt:0}}catch{return null}}async function uW($){try{await n4.mkdir(pW,{recursive:!0,mode:493}),await n4.writeFile(mW,JSON.stringify($,null,2))}catch{}}async function LA(){try{let $=await V$(BA,{timeout:5000,headers:{Accept:"application/json"}});if(!$.ok)return null;return(await $.json()).version||null}catch{return null}}async function HY($=!1){let Z=await wA(),Y=_A;if(Z==="unknown")return{currentVersion:Z,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:Y,error:"Unable to determine current version"};let Q=await gW(),X=Q?.skipUntilVersion,J=null;if(!$&&Q&&Q.checkedAt>0)J=Q.latestVersion;else if(J=await LA(),J)await uW({latestVersion:J,checkedAt:Date.now(),skipUntilVersion:X});if(!J)return{currentVersion:Z,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:Y,error:"Unable to check for updates"};let G=xW.gt(J,Z),q=G;if(G&&X)q=xW.gt(J,X);return{currentVersion:Z,latestVersion:J,hasUpdate:G,shouldPrompt:q,releaseNotesUrl:Y}}async function dW($){let Z=await gW();await uW({latestVersion:Z?.latestVersion||$,checkedAt:Z?.checkedAt||Date.now(),skipUntilVersion:$})}function _Y(){return`npm install -g ${FY}@latest --registry https://registry.npmjs.org`}async function cW(){let{spawn:$}=await import("child_process");return new Promise((Z)=>{let Y=_Y(),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 lW(){try{let $=await HY();return $.shouldPrompt?$:null}catch{return null}}var iW={command:"update",describe:"Check for updates and install if available",handler:async()=>{console.log("\uD83D\uDD0D Checking for updates...");try{let $=await HY(!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{NA("npm install -g blade-code@latest --registry https://registry.npmjs.org",{stdio:"inherit"}),console.log(""),console.log("✅ Update complete!")}catch(Z){console.error("❌ Update failed. Please run manually:"),console.error(" npm install -g blade-code@latest"),process.exit(1)}}else console.log("✅ You are running the latest version of Blade")}catch($){console.error(`❌ Failed to check for updates: ${$ instanceof Error?$.message:"未知错误"}`),process.exit(1)}}};import t1 from"chalk";import rW from"open";M0();x2();var AA=`
2716
+ ${U}`}else{if(K.message)console.log(K.message);process.exit(0)}}let G=await G$.create({systemPrompt:Z.systemPrompt,appendSystemPrompt:Z.appendSystemPrompt,maxTurns:Z.maxTurns}),q;if(Z.appendSystemPrompt)q=await G.chatWithSystem(Z.appendSystemPrompt,X);else q=await G.chat(X,{messages:[],userId:"cli-user",sessionId:`print-${Date.now()}`,workspaceRoot:process.cwd()});if(Z.outputFormat==="json")console.log(JSON.stringify({response:q,input:X,model:Z.model,timestamp:new Date().toISOString()},null,2));else if(Z.outputFormat==="stream-json")console.log(JSON.stringify({type:"response",content:q}));else console.log(q);process.exit(0)}catch(Y){console.error(`Error: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}})}async function _W(){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 bN(X),await X.parse(),!0}catch(Y){console.error(`Print mode error: ${Y instanceof Error?Y.message:"未知错误"}`),process.exit(1)}}import FA from"chalk";var j6={port:{type:"number",describe:"Port to listen on (0 for auto)",default:0},hostname:{type:"string",describe:"Hostname to listen on",default:"127.0.0.1"},cors:{type:"array",describe:"Additional domains to allow for CORS",default:[]}};function y6($){return{port:$.port??0,hostname:$.hostname??"127.0.0.1",cors:$.cors??[]}}import{z as T6}from"zod";class Z7 extends Error{code;statusCode;constructor($,Z,Y=500){super(Z);this.code=$;this.statusCode=Y;this.name="BladeServerError"}toObject(){return{error:{code:this.code,message:this.message}}}}class g8 extends Z7{constructor($,Z){super("NOT_FOUND",Z?`${$} not found: ${Z}`:`${$} not found`,404)}}class E1 extends Z7{constructor($){super("BAD_REQUEST",$,400)}}var cp=T6.object({error:T6.object({code:T6.string(),message:T6.string()})});Q0();x2();import{Hono as ZA}from"hono";import{cors as YA}from"hono/cors";import{existsSync as fW,readFileSync as f6}from"node:fs";import{createServer as QA}from"node:http";import{networkInterfaces as XA}from"node:os";import{dirname as JA,extname as GA,join as a4}from"node:path";import{fileURLToPath as qA}from"node:url";import{WebSocketServer as KA}from"ws";Q0();import{Hono as RN}from"hono";import{z as u8}from"zod";M0();var GY=x("Service"),VN=u8.object({updates:u8.record(u8.any()),options:u8.object({scope:u8.enum(["local","project","global"]).optional(),immediate:u8.boolean().optional()}).optional()}),zW=()=>{let $=new RN;return $.get("/",async(Z)=>{try{let Y=f0();return Z.json(Y||{})}catch(Y){return GY.error("[ConfigRoutes] Failed to get config:",Y),Z.json({})}}),$.put("/",async(Z)=>{try{let Y=await Z.req.json(),Q=VN.safeParse(Y);if(!Q.success)throw new E1("Invalid config update format");let{updates:X,options:J}=Q.data;return await b0().updateConfig(X,J),Z.json({success:!0,updates:X})}catch(Y){throw GY.error("[ConfigRoutes] Failed to update config:",Y),Y}}),$.get("/permissions",async(Z)=>{try{let Y=f0();return Z.json(Y?.permissions||{})}catch(Y){return GY.error("[ConfigRoutes] Failed to get permissions:",Y),Z.json({})}}),$};x2();import{Hono as MN}from"hono";var BW=()=>{let $=new MN;return $.get("/health",(Z)=>{return Z.json({healthy:!0,version:Z1()})}),$.get("/info",(Z)=>{return Z.json({version:Z1(),platform:process.platform,arch:process.arch,nodeVersion:process.version,cwd:process.cwd()})}),$};Q0();d2();T4();M0();import{Hono as DN}from"hono";var Y7=x("Service"),wW=()=>{let $=new DN;return $.get("/",async(Z)=>{try{let Q=e0.getInstance().getAllServers(),X=Array.from(Q.entries()).map(([J,G])=>({id:J,name:J,status:G.status==="connected"?"connected":G.status==="connecting"?"connecting":G.lastError?"error":"offline",endpoint:G.config.command?`${G.config.command} ${(G.config.args||[]).join(" ")}`.trim():G.config.url||"Unknown",description:`MCP server: ${J}`,tools:G.tools.map((q)=>q.name),connectedAt:G.connectedAt?.toISOString(),error:G.lastError?.message}));return Z.json(X)}catch(Y){return Y7.error("[McpRoutes] Failed to get MCP servers:",Y),Z.json([])}}),$.post("/:name/connect",async(Z)=>{try{let Y=Z.req.param("name");return await e0.getInstance().connectServer(Y),Z.json({success:!0})}catch(Y){return Y7.error("[McpRoutes] Failed to connect MCP server:",Y),Z.json({success:!1,error:Y.message},500)}}),$.post("/:name/disconnect",async(Z)=>{try{let Y=Z.req.param("name");return await e0.getInstance().disconnectServer(Y),Z.json({success:!0})}catch(Y){return Y7.error("[McpRoutes] Failed to disconnect MCP server:",Y),Z.json({success:!1,error:Y.message},500)}}),$.delete("/:name",async(Z)=>{try{let Y=Z.req.param("name");await e0.getInstance().unregisterServer(Y);let X=f0();if(X?.mcpServers){let{[Y]:J,...G}=X.mcpServers;await b0().updateConfig({mcpServers:G})}return Z.json({success:!0})}catch(Y){return Y7.error("[McpRoutes] Failed to delete MCP server:",Y),Z.json({success:!1,error:Y.message},500)}}),$.post("/",async(Z)=>{try{let Y=await Z.req.json(),{name:Q,config:X}=Y;if(!Q||!X)return Z.json({success:!1,error:"Missing name or config"},400);await e0.getInstance().registerServer(Q,X);let G=f0();return await b0().updateConfig({mcpServers:{...G?.mcpServers,[Q]:X}}),Z.json({success:!0})}catch(Y){return Y7.error("[McpRoutes] Failed to add MCP server:",Y),Z.json({success:!1,error:Y.message},500)}}),$};Q0();M0();import{Hono as jN}from"hono";var E6=x("Service"),LW=()=>{let $=new jN;return $.get("/",async(Z)=>{try{let Y=g2(),Q=u2();return Z.json({configured:Y,current:Q})}catch(Y){return E6.error("[ModelsRoutes] Failed to get models:",Y),Z.json({configured:[],current:null})}}),$.post("/",async(Z)=>{try{let Y=await Z.req.json(),{provider:Q,name:X,model:J,baseUrl:G,apiKey:q}=Y;if(!J)throw new E1("model is required");let K=await b0().addModel({provider:Q||"openai-compatible",name:X||J,model:J,baseUrl:G||void 0,apiKey:q||void 0});return Z.json({success:!0,model:K})}catch(Y){throw E6.error("[ModelsRoutes] Failed to add model:",Y),Y}}),$.put("/:modelId",async(Z)=>{try{let Y=Z.req.param("modelId"),Q=await Z.req.json(),{baseUrl:X,apiKey:J,model:G}=Q;return await b0().updateModel(Y,{baseUrl:X||void 0,apiKey:J||void 0,model:G||void 0}),Z.json({success:!0})}catch(Y){throw E6.error("[ModelsRoutes] Failed to update model:",Y),Y}}),$.delete("/:modelId",async(Z)=>{try{let Y=Z.req.param("modelId");return await b0().removeModel(Y),Z.json({success:!0})}catch(Y){throw E6.error("[ModelsRoutes] Failed to delete model:",Y),Y}}),$};Q0();import{Hono as kN}from"hono";import{z as s1}from"zod";F2();U$();Q0();i3();RZ();import{Hono as yN}from"hono";import{streamSSE as TN}from"hono/streaming";import{LRUCache as EN}from"lru-cache";import{nanoid as Q7}from"nanoid";import{z as G1}from"zod";var k$=x("Service"),IN=G1.object({title:G1.string().optional(),projectPath:G1.string().optional()}),vN=G1.object({content:G1.string(),attachments:G1.array(G1.object({type:G1.enum(["file","image","url"]),path:G1.string().optional(),url:G1.string().optional(),content:G1.string().optional()})).optional(),permissionMode:G1.enum(["default","autoEdit","plan","spec","yolo"]).optional()}),PN=G1.object({title:G1.string().optional()}),_1=new Map,i4=new EN({max:100,ttl:1800000,dispose:($,Z)=>{if($.status==="running"||$.status==="waiting_permission")$.abortController.abort(),k$.debug(`[SessionRoutes] Run ${Z} disposed due to cache eviction`)}}),CN=($)=>{if(!$||typeof $!=="object")return $;let Z={...$},Y=200000;if(typeof Z.oldContent==="string"&&Z.oldContent.length>Y)delete Z.oldContent;if(typeof Z.newContent==="string"&&Z.newContent.length>Y)delete Z.newContent;return Z},NW=()=>{let $=new yN;return $.get("/",async(Z)=>{try{let Y=await S$.listSessions(),Q=new Set(Y.filter((U)=>U.relationType==="subagent").map((U)=>U.sessionId)),X=Array.from(_1.values()).filter((U)=>!Q.has(U.id)&&U.relationType!=="subagent").map((U)=>({sessionId:U.id,projectPath:U.projectPath,title:U.title,parentId:void 0,relationType:void 0,status:void 0,agentType:void 0,model:void 0,messageCount:U.messages.length,firstMessageTime:U.createdAt.toISOString(),lastMessageTime:new Date().toISOString(),hasErrors:!1,isActive:!0})),J=new Set(X.map((U)=>U.sessionId)),G=Y.filter((U)=>!_1.has(U.sessionId)&&!J.has(U.sessionId)&&U.relationType!=="subagent"),q=new Set(J),K=G.filter((U)=>{if(q.has(U.sessionId))return!1;return q.add(U.sessionId),!0}),W=[...X,...K];return Z.json(W)}catch(Y){return k$.error("[SessionRoutes] Failed to list sessions:",Y),Z.json([])}}),$.post("/",async(Z)=>{try{let Y=await Z.req.json(),Q=IN.safeParse(Y);if(!Q.success)throw new E1("Invalid request body");let{title:X,projectPath:J}=Q.data,G=Q7(12),q=J||Z.get("directory")||process.cwd(),K={id:G,projectPath:q,title:X||`Session ${G.slice(0,6)}`,createdAt:new Date,messages:[]};return _1.set(G,K),Z.json({sessionId:G,projectPath:q,title:K.title,parentId:void 0,relationType:void 0,status:void 0,agentType:void 0,model:void 0,messageCount:0,firstMessageTime:K.createdAt.toISOString(),lastMessageTime:K.createdAt.toISOString(),hasErrors:!1})}catch(Y){throw k$.error("[SessionRoutes] Failed to create session:",Y),Y}}),$.get("/:sessionId",async(Z)=>{let Y=Z.req.param("sessionId"),Q=_1.get(Y);if(Q)return Z.json({sessionId:Q.id,projectPath:Q.projectPath,title:Q.title,messageCount:Q.messages.length,firstMessageTime:Q.createdAt.toISOString(),lastMessageTime:new Date().toISOString(),hasErrors:!1,isActive:!0});try{let J=(await S$.listSessions()).find((G)=>G.sessionId===Y);if(!J)throw new g8("Session",Y);return Z.json(J)}catch(X){if(X instanceof g8)throw X;throw k$.error("[SessionRoutes] Failed to get session:",X),X}}),$.patch("/:sessionId",async(Z)=>{let Y=Z.req.param("sessionId");try{let Q=await Z.req.json(),X=PN.safeParse(Q);if(!X.success)throw new E1("Invalid request body");let{title:J}=X.data,G=_1.get(Y);if(G&&J)G.title=J;return Z.json({success:!0,title:J})}catch(Q){throw k$.error("[SessionRoutes] Failed to update session:",Q),Q}}),$.delete("/:sessionId",async(Z)=>{let Y=Z.req.param("sessionId"),Q=_1.get(Y);if(Q?.currentRunId){let X=i4.get(Q.currentRunId);if(X)X.abortController.abort(),y1.publish(Y,"run.cancelled",{runId:X.id}),i4.delete(Q.currentRunId)}try{await S$.deleteSession(Y)}catch(X){k$.warn("[SessionRoutes] Failed to delete session file:",X)}return _1.delete(Y),Z.json({success:!0})}),$.get("/:sessionId/message",async(Z)=>{let Y=Z.req.param("sessionId");try{let Q=await S$.loadSession(Y);return Z.json(Q)}catch(Q){return k$.error("[SessionRoutes] Failed to get messages:",Q),Z.json([])}}),$.get("/:sessionId/events",async(Z)=>{let Y=Z.req.param("sessionId"),Q=_1.get(Y);if(!Q){let X=Z.get("directory")||process.cwd();Q={id:Y,projectPath:X,title:`Session ${Y.slice(0,6)}`,createdAt:new Date,messages:[]},_1.set(Y,Q)}return TN(Z,async(X)=>{await X.writeSSE({data:JSON.stringify({type:"connected",properties:{sessionId:Y,timestamp:Date.now()}})});let G=y1.subscribe((K)=>{if(K.sessionId!==Y)return;X.writeSSE({data:JSON.stringify({type:K.type,properties:{sessionId:K.sessionId,...K.properties}})}).catch(()=>{})}),q=setInterval(()=>{if(!X.aborted)X.writeSSE({data:JSON.stringify({type:"heartbeat",properties:{timestamp:Date.now()}})}).catch(()=>{})},15000);X.onAbort(()=>{clearInterval(q),G()});while(!0)if(await new Promise((K)=>setTimeout(K,1000)),X.aborted)break})}),$.post("/:sessionId/message",async(Z)=>{let Y=Z.req.param("sessionId"),Q=await Z.req.json(),X=vN.safeParse(Q);if(!X.success)throw new E1("Invalid message format");let{content:J,permissionMode:G}=X.data,q=G||"default",K=Z.get("directory")||process.cwd(),W=_1.get(Y);if(!W)W={id:Y,projectPath:K,title:`Session ${Y.slice(0,6)}`,createdAt:new Date,messages:[]},_1.set(Y,W);let U=Q7(12),O=new AbortController,F={id:U,sessionId:Y,status:"running",abortController:O,createdAt:new Date};return i4.set(U,F),W.currentRunId=U,SN(F,W,J,q).catch((H)=>{k$.error(`[SessionRoutes] Run ${U} failed:`,H)}),Z.json({runId:U,status:"running"},202)}),$.post("/:sessionId/abort",async(Z)=>{let Y=Z.req.param("sessionId"),Q=_1.get(Y);if(Q?.currentRunId){let X=i4.get(Q.currentRunId);if(X)X.abortController.abort(),X.status="cancelled",y1.publish(Y,"run.cancelled",{runId:X.id})}return Z.json({success:!0})}),$.get("/:sessionId/status",async(Z)=>{let Y=Z.req.param("sessionId"),Q=_1.get(Y);if(!Q?.currentRunId)return Z.json({sessionId:Y,status:"idle"});let X=i4.get(Q.currentRunId);return Z.json({sessionId:Y,runId:Q.currentRunId,status:X?.status||"idle"})}),$};async function SN($,Z,Y,Q){let{abortController:X,sessionId:J,id:G}=$,q=Q7(12),K=Q7(12),W=(U,O)=>{y1.publish(J,U,O)};try{W("message.created",{messageId:q,role:"user",content:Y}),W("session.status",{status:"running"}),W("message.created",{messageId:K,role:"assistant",content:""});let U=await G$.create({}),O=async(z)=>{let w=Q7(12),B=300000;$.status="waiting_permission";let L=new Promise((M)=>{let b=setTimeout(()=>{k$.warn(`[SessionRoutes] Permission ${w} timed out after 300000ms`),W("permission.timeout",{requestId:w}),M({approved:!1,reason:"timeout"})},300000);$.pendingPermission={permissionId:w,resolve:(j)=>{clearTimeout(b),M(j)},details:z}});W("permission.asked",{requestId:w,toolName:z.toolName,description:z.message,args:z.args,details:z}),k$.info(`[SessionRoutes] Permission request created: ${w}, runId: ${G}`);let N=await L;return k$.info(`[SessionRoutes] Permission response received: ${w}, approved: ${N.approved}`),$.status="running",$.pendingPermission=void 0,N},F={messages:Z.messages,userId:"web-user",sessionId:J,workspaceRoot:Z.projectPath,signal:X.signal,permissionMode:Q,confirmationHandler:{requestConfirmation:O}},H={stream:!0,onContentDelta:async(z)=>{W("message.delta",{messageId:K,delta:z})},onThinkingDelta:async(z)=>{W("thinking.delta",{delta:z})},onStreamEnd:async()=>{W("message.complete",{messageId:K}),W("thinking.completed",{})},onToolStart:async(z,w)=>{if(z.type!=="function")return;W("tool.start",{messageId:K,toolName:z.function.name,toolCallId:z.id,arguments:z.function.arguments,toolKind:w})},onToolResult:async(z,w)=>{if(z.type!=="function")return;W("tool.result",{messageId:K,toolName:z.function.name,toolCallId:z.id,success:!w.error,summary:w.metadata?.summary,output:w.displayContent,metadata:CN(w.metadata)})},onTokenUsage:async(z)=>{W("token.usage",z)},onTodoUpdate:async(z)=>{W("todo.updated",{todos:z})}},_=await U.chat(Y,F,H);Z.messages.push({role:"user",content:Y},{role:"assistant",content:_}),$.status="completed",W("session.completed",{runId:G}),W("session.status",{status:"idle"})}catch(U){k$.error("[SessionRoutes] Agent execution error:",U),$.status="failed",W("session.error",{error:U instanceof Error?U.message:"Unknown error"}),W("session.status",{status:"error"})}}function AW($,Z,Y){k$.info(`[SessionRoutes] Looking for permission ${Z} in session ${$}`),k$.info(`[SessionRoutes] Active runs: ${i4.size}`);for(let[Q,X]of i4.entries())if(k$.info(`[SessionRoutes] Checking run ${Q}: sessionId=${X.sessionId}, pendingPermission=${X.pendingPermission?.permissionId}`),X.sessionId===$&&X.pendingPermission?.permissionId===Z)return X.pendingPermission.resolve(Y),k$.info(`[SessionRoutes] Permission ${Z} responded, runId: ${X.id}`),!0;return k$.error(`[SessionRoutes] Permission not found: ${Z}`),!1}var qY=x("Service"),fN=s1.object({approved:s1.boolean(),remember:s1.boolean().optional(),scope:s1.enum(["once","session"]).optional(),targetMode:s1.enum(["default","autoEdit","plan","spec","yolo"]).optional(),feedback:s1.string().optional(),answers:s1.record(s1.union([s1.string(),s1.array(s1.string())])).optional()}),bW=()=>{let $=new kN;return $.post("/:permissionId",async(Z)=>{let Y=Z.req.param("permissionId"),Q=Z.req.query("sessionId");qY.info(`[PermissionRoutes] Received permission response: permissionId=${Y}, sessionId=${Q}`);try{let X=await Z.req.json(),J=fN.safeParse(X);if(!J.success)throw new E1("Invalid permission response format");let{approved:G,remember:q,scope:K,targetMode:W,feedback:U,answers:O}=J.data;if(!Q)throw new E1("sessionId query parameter is required");if(!AW(Q,Y,{approved:G,reason:U,scope:K,targetMode:W,feedback:U,answers:O}))throw new g8("Permission request",Y);return qY.info(`[PermissionRoutes] Permission ${Y} ${G?"approved":"denied"}`),Z.json({success:!0,approved:G,remember:q})}catch(X){throw qY.error("[PermissionRoutes] Failed to respond to permission:",X),X}}),$};Q0();import{Hono as pN}from"hono";Q0();w8();var v6=x("Service"),hN="https://models.dev/api.json",xN=3600000,I6=null,RW=async()=>{if(I6&&Date.now()-I6.timestamp<xN)return I6.data;try{v6.info("\uD83D\uDCE1 Fetching models.dev data...");let $=await fetch(hN,{headers:{"User-Agent":"Blade-CLI/1.0"}});if(!$.ok)throw Error(`HTTP ${$.status}: ${$.statusText}`);let Z=await $.json();return I6={data:Z,timestamp:Date.now()},v6.info(`✅ Loaded ${Object.keys(Z).length} providers from models.dev`),Z}catch($){throw v6.error("❌ Failed to fetch models.dev data:",$),$}},P6=async()=>{let $=await RW(),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:O9[Y]||O9.default,description:`${X} 个模型`,isOAuth:!1,envVars:Q.env||[],docUrl:Q.doc,defaultBaseUrl:M7[Y],bladeProvider:CX(Y)})}return Z.sort((Y,Q)=>{let X=U9.indexOf(Y.id),J=U9.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)})},C6=async($)=>{let Y=(await RW())[$];if(!Y?.models)return v6.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}))};w8();var VW=x("Service"),MW=()=>{let $=new pN;return $.get("/",async(Z)=>{try{let Y=await P6(),Q=Object.entries(V7).map(([X,J])=>({id:X,name:X.charAt(0).toUpperCase()+X.slice(1),icon:J.icon,description:J.description,isOAuth:!0,envVars:[],bladeProvider:J.bladeProvider}));return Z.json([...Y,...Q])}catch(Y){return VW.error("[ProviderRoutes] Failed to list providers:",Y),Z.json([])}}),$.get("/:providerId/models",async(Z)=>{let Y=Z.req.param("providerId");try{let Q=await C6(Y);return Z.json(Q)}catch(Q){return VW.error("[ProviderRoutes] Failed to list models:",Q),Z.json([])}}),$};Q0();K2();y9();import{Hono as mN}from"hono";import*as X4 from"node:fs/promises";import{homedir as gN}from"node:os";import*as S6 from"node:path";var r4=x("Service"),KY=S6.join(gN(),".blade","skills-config.json");async function DW(){try{let $=await X4.readFile(KY,"utf-8");return JSON.parse($)}catch{return{disabled:[]}}}async function uN($){await X4.mkdir(S6.dirname(KY),{recursive:!0}),await X4.writeFile(KY,JSON.stringify($,null,2))}async function dN($,Z){let Y=await DW();if(Z)Y.disabled=Y.disabled.filter((Q)=>Q!==$);else if(!Y.disabled.includes($))Y.disabled.push($);await uN(Y)}var d8=null,cN=300000;async function lN(){if(d8&&Date.now()-d8.timestamp<cN)return d8.data;try{let $=await fetch("https://api.github.com/repos/anthropics/skills/contents/skills",{headers:{Accept:"application/vnd.github.v3+json","User-Agent":"Blade-Skills-Catalog"}});if(!$.ok)return r4.warn(`GitHub API returned ${$.status}`),d8?.data||[];let Z=await $.json(),Y=[];for(let Q of Z){if(Q.type!=="dir")continue;let X=`Official ${Q.name} skill`;try{let J=await fetch(`https://raw.githubusercontent.com/anthropics/skills/main/skills/${Q.name}/SKILL.md`,{headers:{"User-Agent":"Blade-Skills-Catalog"}});if(J.ok){let q=(await J.text()).match(/^#[^\n]*\n+([^\n#]+)/);if(q)X=q[1].trim().slice(0,100)}}catch{}Y.push({name:Q.name,description:X,tag:"Official",author:"Anthropic"})}return d8={data:Y,timestamp:Date.now()},Y}catch($){return r4.warn("Failed to fetch skills catalog from GitHub:",$),d8?.data||[]}}var jW=()=>{let $=new mN;return $.get("/",async(Z)=>{try{let Y=J$();await Y.initialize();let Q=Y.getAll(),X=await DW(),J=Q.map((G)=>({id:G.name,name:G.name,enabled:!X.disabled.includes(G.name),description:G.description||"",version:G.version||"1.0.0",provider:"Local",location:G.source==="builtin"?"Built-in":G.basePath,capabilities:["prompts"],allowedTools:G.allowedTools||[]}));return Z.json(J)}catch(Y){return r4.error("[SkillsRoutes] Failed to get skills:",Y),Z.json([])}}),$.post("/:name/toggle",async(Z)=>{try{let Y=Z.req.param("name"),Q=await Z.req.json();return await dN(Y,Q.enabled),Z.json({success:!0,enabled:Q.enabled})}catch(Y){return r4.error("[SkillsRoutes] Failed to toggle skill:",Y),Z.json({success:!1,error:Y.message},500)}}),$.delete("/:name",async(Z)=>{try{let Y=Z.req.param("name"),Q=`${process.env.HOME}/.blade/skills/${Y}`;return await X4.rm(Q,{recursive:!0,force:!0}),await J$().refresh(),Z.json({success:!0})}catch(Y){return r4.error("[SkillsRoutes] Failed to uninstall skill:",Y),Z.json({success:!1,error:Y.message},500)}}),$.post("/install",async(Z)=>{try{let Y=await Z.req.json(),Q=h7(),X=J$(),J=!1;if(Y.source==="catalog"&&Y.name){if(J=await Q.installOfficialSkill(Y.name),!J)return Z.json({success:!1,error:"Failed to install skill from catalog"},500)}else if(Y.source==="repo"&&Y.url){if(J=await Q.installFromRepo(Y.url,Y.name),!J)return Z.json({success:!1,error:"Failed to install skill from repository. Make sure the repo contains a SKILL.md file."},500)}else if(Y.source==="local"&&Y.path){if(J=await Q.installFromLocal(Y.path,Y.name),!J)return Z.json({success:!1,error:"Failed to install skill from local path. Make sure the path exists and contains a SKILL.md file."},500)}else return Z.json({success:!1,error:"Invalid install parameters. Required: source with corresponding url/path/name"},400);return await X.refresh(),Z.json({success:!0})}catch(Y){return r4.error("[SkillsRoutes] Failed to install skill:",Y),Z.json({success:!1,error:Y.message},500)}}),$.get("/catalog",async(Z)=>{try{let Y=await lN();return Z.json(Y)}catch(Y){return r4.error("[SkillsRoutes] Failed to get catalog:",Y),Z.json([])}}),$};Q0();C4();l4();x3();import iN from"fast-glob";import{Hono as rN}from"hono";import{execSync as aN}from"node:child_process";import{readdir as nN}from"node:fs/promises";import k6 from"node:path";var X7=x("Service"),oN=($)=>{try{return aN("git rev-parse --abbrev-ref HEAD",{cwd:$,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||null}catch{return null}},sN=[...X1.map(($)=>`${$}/**`),...X1,...D8.map(($)=>`**/${$}`)],tN=new Set(["/theme","/model","/permissions","/mcp","/skills","/exit","/resume","/ide","/login","/logout"]),yW=()=>{let $=new rN;return $.get("/commands",async(Z)=>{try{let Y=Z.req.query("q")||"",Q=D6(Y).filter((X)=>!tN.has(X.command));return Z.json(Q)}catch(Y){return X7.error("[SuggestionsRoutes] Failed to get command suggestions:",Y),Z.json([])}}),$.get("/files",async(Z)=>{try{let Y=Z.req.query("q")||"",Q=Z.get("directory")||process.cwd(),X=Math.min(Number(Z.req.query("limit"))||100,1000),G=(await iN("**/*",{cwd:Q,dot:!1,followSymbolicLinks:!1,onlyFiles:!1,markDirectories:!0,unique:!0,ignore:sN})).map((W)=>W.replace(/\\/g,"/"));if(!Y)return Z.json(G.slice(0,X));let q=Y.toLowerCase(),K=G.filter((W)=>W.toLowerCase().includes(q)).slice(0,X);return Z.json(K)}catch(Y){return X7.error("[SuggestionsRoutes] Failed to get file suggestions:",Y),Z.json([])}}),$.get("/files/tree",async(Z)=>{try{let Y=Z.get("directory")||process.cwd(),Q=Z.req.query("path")||"",X=Q?k6.join(Y,Q):Y,G=(await nN(X,{withFileTypes:!0})).map((W)=>({name:W.name,path:Q?`${Q}/${W.name}`:W.name,type:W.isDirectory()?"dir":"file"}));G.sort((W,U)=>{if(W.type!==U.type)return W.type==="dir"?-1:1;return W.name.localeCompare(U.name)});let q=new Set(X1),K=G.filter((W)=>{let U=W.name;if(U.startsWith("."))return!1;if(q.has(U))return!1;for(let O of D8)if(U.match(new RegExp(O.replace("*",".*"))))return!1;return!0});return Z.json(K)}catch(Y){return X7.error("[SuggestionsRoutes] Failed to get file tree:",Y),Z.json([])}}),$.get("/files/content",async(Z)=>{try{let Y=Z.req.query("path");if(!Y)return Z.json({error:"Missing file path"},400);let Q=Z.get("directory")||process.cwd(),X=k6.resolve(Q,Y),J=k6.relative(Q,X);if(J.startsWith("..")||k6.isAbsolute(J))return Z.json({error:"Invalid file path"},400);let G=a2(),q=await G.stat(X);if(!q?.isFile)return Z.json({error:"File not found"},404);let K=200000,W=await G.readTextFile(X),U=W.length>K;return Z.json({path:Y,content:U?W.slice(0,K):W,truncated:U,size:q.size})}catch(Y){return X7.error("[SuggestionsRoutes] Failed to get file content:",Y),Z.json({error:"Failed to read file"},500)}}),$.get("/git-info",async(Z)=>{try{let Y=Z.get("directory")||process.cwd(),Q=oN(Y);return Z.json({branch:Q})}catch(Y){return X7.error("[SuggestionsRoutes] Failed to get git info:",Y),Z.json({branch:null})}}),$};Q0();import{Hono as eN}from"hono";var J4=x("Service"),c8=new Map,TW=2097152,EW=65536;function IW(){return typeof globalThis.Bun<"u"}async function $A($,Z,Y){if(IW()){let{spawn:J}=await import("bun-pty"),G=J($,Z,{name:"xterm-256color",cwd:Y.cwd,env:Y.env});return{pid:G.pid,write:(q)=>G.write(q),resize:(q,K)=>G.resize(q,K),kill:()=>G.kill(),onData:(q)=>G.onData(q),onExit:(q)=>G.onExit(q)}}let X=(await import("node-pty")).spawn($,Z,{name:"xterm-256color",cwd:Y.cwd,env:Y.env,cols:80,rows:24});return{pid:X.pid,write:(J)=>X.write(J),resize:(J,G)=>X.resize(J,G),kill:()=>X.kill(),onData:(J)=>{X.onData(J)},onExit:(J)=>{X.onExit(J)}}}var UY=void 0,WY;if(IW())try{let{createBunWebSocket:$}=await import("hono/bun"),Z=$();WY=Z.upgradeWebSocket,UY=Z.websocket}catch($){J4.warn("[Terminal] Failed to initialize Bun WebSocket support:",$)}async function vW($,Z){let Y=`term-${Date.now()}`;J4.info(`[Terminal] New connection: ${Y}, cwd: ${$}`);let Q=process.platform==="win32"?"powershell.exe":process.env.SHELL||"/bin/zsh",X=Q.endsWith("sh")?["-l"]:[],J=await $A(Q,X,{cwd:$,env:{...process.env,TERM:"xterm-256color",COLORTERM:"truecolor"}}),G={id:Y,process:J,cwd:$,buffer:"",subscribers:new Set};if(c8.set(Y,G),G.subscribers.add(Z),J.onData((q)=>{let K=!1;for(let W of G.subscribers)try{W.send(q),K=!0}catch{G.subscribers.delete(W)}if(K)return;if(G.buffer+=q,G.buffer.length>TW)G.buffer=G.buffer.slice(-TW)}),J.onExit(({exitCode:q})=>{J4.info(`[Terminal] Process exited: ${Y}, code: ${q}`);for(let K of G.subscribers)try{K.close()}catch{}c8.delete(Y)}),G.buffer){let q=G.buffer;G.buffer="";for(let K=0;K<q.length;K+=EW)Z.send(q.slice(K,K+EW))}return{session:G,cleanup:()=>{if(J4.info(`[Terminal] Connection closed: ${Y}`),G.subscribers.delete(Z),G.subscribers.size===0){try{G.process.kill()}catch{}c8.delete(Y)}}}}function PW($,Z){$.on("connection",async(Y,Q)=>{let X=new URL(Q.url||"/",`http://${Q.headers.host}`);if(!X.pathname.endsWith("/terminal/ws")){Y.close();return}let J=X.searchParams.get("cwd")||Z()||process.cwd();try{let{session:G,cleanup:q}=await vW(J,{send:(K)=>Y.send(K),close:()=>Y.close()});Y.on("message",(K)=>{try{G.process.write(String(K))}catch(W){J4.error("[Terminal] Failed to write to PTY:",W)}}),Y.on("close",q),Y.on("error",q)}catch(G){J4.error("[Terminal] Failed to spawn PTY:",G),Y.close()}})}var CW=()=>{let $=new eN;if($.get("/status",(Z)=>{let Y=Array.from(c8.values()).map((Q)=>({id:Q.id,cwd:Q.cwd}));return Z.json({active:Y.length,terminals:Y})}),$.post("/kill/:terminalId",(Z)=>{let Y=Z.req.param("terminalId"),Q=c8.get(Y);if(Q){try{Q.process.kill()}catch{}for(let X of Q.subscribers)X.close();return c8.delete(Y),Z.json({success:!0})}return Z.json({success:!1,error:"Terminal not found"},404)}),WY)$.get("/ws",WY((Z)=>{let Y=Z.req.query("cwd")||Z.get("directory")||process.cwd(),Q;return{async onOpen(X,J){try{Q=await vW(Y,{send:(G)=>J.send(G),close:()=>J.close()})}catch(G){J4.error("[Terminal] Failed to spawn PTY:",G),J.close()}},onMessage(X){if(!Q)return;try{Q.session.process.write(String(X.data))}catch(J){J4.error("[Terminal] Failed to write to PTY:",J)}},onClose(){Q?.cleanup()}}}));else $.get("/ws",(Z)=>{return Z.json({message:"WebSocket endpoint - connect via ws:// protocol",hint:"Use WebSocket client to connect to this endpoint"})});return $};var z1=x("Service"),OY=[];function WA(){let $=JA(qA(import.meta.url)),Z=[a4($,"web"),a4(process.cwd(),"dist/web"),a4(process.cwd(),"packages/cli/dist/web")];for(let Y of Z){let Q=a4(Y,"index.html");if(fW(Q)){if(f6(Q,"utf-8").includes("/assets/"))return z1.debug(`[Server] Found web dist at: ${Y}`),Y}}return null}function UA(){let $=new ZA;$.onError((Y,Q)=>{if(z1.error("[Server] Request error:",Y),Y instanceof Z7)return Q.json(Y.toObject(),Y.statusCode);let X=Y instanceof Error?Y.message:String(Y);return Q.json({error:{code:"INTERNAL_ERROR",message:X}},500)}),$.use(async(Y,Q)=>{let X=process.env.BLADE_SERVER_PASSWORD;if(!X)return Q();let J=Y.req.path;if(J==="/"||J.startsWith("/assets/")||J.endsWith(".html")||J.endsWith(".js")||J.endsWith(".css"))return Q();let G=Y.req.header("Authorization");if(!G?.startsWith("Basic "))return Y.header("WWW-Authenticate",'Basic realm="Blade Server"'),Y.json({error:{code:"UNAUTHORIZED",message:"Authentication required"}},401);let q=Buffer.from(G.slice(6),"base64").toString(),[K,W]=q.split(":"),U=process.env.BLADE_SERVER_USERNAME??"blade";if(K!==U||W!==X)return Y.json({error:{code:"UNAUTHORIZED",message:"Invalid credentials"}},401);return Q()}),$.use(async(Y,Q)=>{let X=Y.req.path==="/health"||Y.req.path==="/global/health"||Y.req.path.startsWith("/assets/");if(!X)z1.debug(`[Server] ${Y.req.method} ${Y.req.path}`);let J=Date.now();if(await Q(),!X){let G=Date.now()-J;z1.debug(`[Server] ${Y.req.method} ${Y.req.path} - ${Y.res.status} (${G}ms)`)}}),$.use(YA({origin(Y){if(!Y)return;if(Y.startsWith("http://localhost:"))return Y;if(Y.startsWith("http://127.0.0.1:"))return Y;if(Y==="tauri://localhost"||Y==="http://tauri.localhost")return Y;if(OY.includes(Y))return Y;return}})),$.use(async(Y,Q)=>{let X=Y.req.query("directory")||Y.req.header("x-blade-directory")||process.cwd();try{X=decodeURIComponent(X)}catch{}return Y.set("directory",X),Q()}),$.route("/global",BW()),$.route("/sessions",NW()),$.route("/configs",zW()),$.route("/permissions",bW()),$.route("/providers",MW()),$.route("/models",LW()),$.route("/suggestions",yW()),$.route("/terminal",CW()),$.route("/mcp",wW()),$.route("/skills",jW()),$.get("/health",(Y)=>{return Y.json({healthy:!0,version:Z1()})});let Z=WA();if(Z)z1.info(`[Server] Serving static files from ${Z}`),$.get("/assets/*",(Y)=>{let Q=a4(Z,Y.req.path);if(!fW(Q))return Y.json({error:{code:"NOT_FOUND",message:`File not found: ${Y.req.path}`}},404);let X=f6(Q),J=GA(Q).toLowerCase(),q={".js":"application/javascript",".css":"text/css",".html":"text/html",".json":"application/json",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".ico":"image/x-icon",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".eot":"application/vnd.ms-fontobject"}[J]||"application/octet-stream";return new Response(X,{headers:{"Content-Type":q,"Cache-Control":"public, max-age=31536000, immutable"}})}),$.get("/",(Y)=>{let Q=a4(Z,"index.html"),X=f6(Q,"utf-8");return Y.html(X)}),$.get("*",(Y)=>{let Q=Y.req.path;if(Q.includes("."))return Y.json({error:{code:"NOT_FOUND",message:`File not found: ${Q}`}},404);let X=a4(Z,"index.html"),J=f6(X,"utf-8");return Y.html(J)});else z1.warn('[Server] Web UI not found. Run "cd web && pnpm build" to enable web interface.'),$.get("/",(Y)=>{return Y.json({message:"Blade API Server",version:Z1(),webUI:!1,hint:'Web UI not built. Run "cd web && pnpm build" to enable.',endpoints:{health:"/health",sessions:"/sessions",configs:"/configs",permissions:"/permissions",providers:"/providers"}})}),$.all("*",(Y)=>{return Y.json({error:{code:"NOT_FOUND",message:`Route not found: ${Y.req.path}`}},404)});return $}function J7(){let $=XA(),Z=[];for(let Y of Object.keys($)){let Q=$[Y];if(!Q)continue;for(let X of Q){if(X.internal||X.family!=="IPv4")continue;if(X.address.startsWith("172."))continue;Z.push(X.address)}}return Z}function SW(){return typeof globalThis.Bun<"u"}function kW($,Z){let Y=globalThis.Bun,Q=(J)=>{try{return Y.serve({hostname:Z.hostname,port:J,fetch:$.fetch,idleTimeout:0,websocket:UY})}catch(G){z1.error("Failed to start Bun server:",G);return}},X=Z.port===0?Q(4096)??Q(0):Q(Z.port);if(!X)throw Error(`Failed to start Bun server on port ${Z.port}`);return{url:X.url,port:X.port,hostname:X.hostname,stop:async()=>{X.stop(!0)}}}function OA($,Z){return new Promise((Y,Q)=>{let X=QA(async(W,U)=>{let O=new URL(W.url||"/",`http://${W.headers.host}`),F=new Headers;for(let[z,w]of Object.entries(W.headers))if(w)if(Array.isArray(w))for(let B of w)F.append(z,B);else F.set(z,w);let H;if(W.method!=="GET"&&W.method!=="HEAD")H=(await new Promise((w)=>{let B=[];W.on("data",(L)=>B.push(L)),W.on("end",()=>w(Buffer.concat(B)))})).toString();let _=new Request(O.toString(),{method:W.method,headers:F,body:H});try{let z=await $.fetch(_);if(U.statusCode=z.status,z.headers.forEach((w,B)=>{U.setHeader(B,w)}),z.body){let w=z.body.getReader(),B=async()=>{let{done:L,value:N}=await w.read();if(L){U.end();return}return U.write(N),B()};await B()}else{let w=await z.text();U.end(w)}}catch(z){z1.error("[Server] Node request error:",z),U.statusCode=500,U.end(JSON.stringify({error:{code:"INTERNAL_ERROR",message:"Internal server error"}}))}}),J=new KA({noServer:!0}),G=process.cwd();PW(J,()=>G),X.on("upgrade",(W,U,O)=>{if(new URL(W.url||"/",`http://${W.headers.host}`).pathname==="/terminal/ws")J.handleUpgrade(W,U,O,(H)=>{J.emit("connection",H,W)});else U.destroy()});let q=(W)=>{return new Promise((U,O)=>{X.once("error",(F)=>{if(F.code==="EADDRINUSE")O(F);else O(F)}),X.listen(W,Z.hostname,()=>{let F=X.address();if(F&&typeof F==="object")U(F.port);else U(W)})})};(async()=>{let W;if(Z.port===0)try{W=await q(4096)}catch{W=await q(0)}else W=await q(Z.port);let U=new URL(`http://${Z.hostname==="0.0.0.0"?"localhost":Z.hostname}:${W}`);Y({url:U,port:W,hostname:Z.hostname,stop:async()=>{return new Promise((O)=>{J.close(()=>{X.close(()=>O())})})}})})().catch(Q)})}var l8;((Mg)=>{let $,Z;function Y(){if(!Z)Z=UA();return Z}Mg.getApp=Y;function Q(G){OY=G.cors??[];let q=Y();if(SW())$=kW(q,G),z1.info(`[Server] Blade server listening on ${$.url} (Bun runtime)`);else throw Error("Blade web server requires Bun runtime. Please run with Bun: `bun run blade web` or install Bun from https://bun.sh");let K=$;return{url:K.url,port:K.port,hostname:K.hostname,stop:async()=>{if($)await $.stop(),$=void 0,Z=void 0,z1.info("[Server] Blade server stopped")}}}Mg.listen=Q;async function X(G){OY=G.cors??[];let q=Y();if(SW())$=kW(q,G),z1.info(`[Server] Blade server listening on ${$.url} (Bun runtime)`);else $=await OA(q,G),z1.info(`[Server] Blade server listening on ${$.url} (Node.js runtime)`);let K=$;return{url:K.url,port:K.port,hostname:K.hostname,stop:async()=>{if($)await $.stop(),$=void 0,Z=void 0,z1.info("[Server] Blade server stopped")}}}Mg.listenAsync=X;function J(){return $!==void 0}Mg.isRunning=J})(l8||={});M0();var hW={command:"serve",describe:"Start a headless Blade server (no browser)",builder:j6,handler:async($)=>{let Z=y6($);if(await m2(),!process.env.BLADE_SERVER_PASSWORD)console.log(FA.yellow("Warning: BLADE_SERVER_PASSWORD is not set; server is unsecured."));let Y=await l8.listenAsync(Z);if(console.log(`Blade server listening on http://${Y.hostname}:${Y.port}`),Z.hostname==="0.0.0.0"){let Q=J7();for(let X of Q)console.log(` Network: http://${X}:${Y.port}`)}await new Promise(()=>{}),await Y.stop()}};import{execSync as NA}from"child_process";E4();import*as n4 from"fs/promises";import*as G4 from"path";import xW from"semver";import{fileURLToPath as HA}from"url";var FY="blade-code",_A="https://cdn.jsdelivr.net/npm/blade-code@latest/CHANGELOG.md",pW=G4.join(process.env.HOME||process.env.USERPROFILE||".",".blade"),mW=G4.join(pW,"version-cache.json"),zA=3600000,BA=`https://registry.npmjs.org/${FY}/latest`;async function wA(){try{if(process.env.BLADE_VERSION)return process.env.BLADE_VERSION;let $=HA(import.meta.url),Z=G4.dirname($),Y=[G4.join(Z,"..","..","package.json"),G4.join(Z,"..","package.json"),G4.join(process.cwd(),"package.json")];for(let Q of Y)try{let X=await n4.readFile(Q,"utf-8"),J=JSON.parse(X);if(J.name===FY&&J.version)return J.version}catch{}return"unknown"}catch{return"unknown"}}async function gW(){try{let $=await n4.readFile(mW,"utf-8"),Z=JSON.parse($);if(Date.now()-Z.checkedAt<zA)return Z;return{...Z,checkedAt:0}}catch{return null}}async function uW($){try{await n4.mkdir(pW,{recursive:!0,mode:493}),await n4.writeFile(mW,JSON.stringify($,null,2))}catch{}}async function LA(){try{let $=await V$(BA,{timeout:5000,headers:{Accept:"application/json"}});if(!$.ok)return null;return(await $.json()).version||null}catch{return null}}async function HY($=!1){let Z=await wA(),Y=_A;if(Z==="unknown")return{currentVersion:Z,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:Y,error:"Unable to determine current version"};let Q=await gW(),X=Q?.skipUntilVersion,J=null;if(!$&&Q&&Q.checkedAt>0)J=Q.latestVersion;else if(J=await LA(),J)await uW({latestVersion:J,checkedAt:Date.now(),skipUntilVersion:X});if(!J)return{currentVersion:Z,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:Y,error:"Unable to check for updates"};let G=xW.gt(J,Z),q=G;if(G&&X)q=xW.gt(J,X);return{currentVersion:Z,latestVersion:J,hasUpdate:G,shouldPrompt:q,releaseNotesUrl:Y}}async function dW($){let Z=await gW();await uW({latestVersion:Z?.latestVersion||$,checkedAt:Z?.checkedAt||Date.now(),skipUntilVersion:$})}function _Y(){return`npm install -g ${FY}@latest --registry https://registry.npmjs.org`}async function cW(){let{spawn:$}=await import("child_process");return new Promise((Z)=>{let Y=_Y(),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 lW(){try{let $=await HY();return $.shouldPrompt?$:null}catch{return null}}var iW={command:"update",describe:"Check for updates and install if available",handler:async()=>{console.log("\uD83D\uDD0D Checking for updates...");try{let $=await HY(!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{NA("npm install -g blade-code@latest --registry https://registry.npmjs.org",{stdio:"inherit"}),console.log(""),console.log("✅ Update complete!")}catch(Z){console.error("❌ Update failed. Please run manually:"),console.error(" npm install -g blade-code@latest"),process.exit(1)}}else console.log("✅ You are running the latest version of Blade")}catch($){console.error(`❌ Failed to check for updates: ${$ instanceof Error?$.message:"未知错误"}`),process.exit(1)}}};import t1 from"chalk";import rW from"open";M0();x2();var AA=`
2717
2717
  ____ _ _
2718
2718
  | __ )| | __ _ __| | ___
2719
2719
  | _ \\| |/ _\` |/ _\` |/ _ \\
2720
2720
  | |_) | | (_| | (_| | __/
2721
2721
  |____/|_|\\__,_|\\__,_|\\___|
2722
- `,aW={command:"web",describe:"Start Blade server and open web interface",builder:j7,handler:async($)=>{let Z=y7($);if(await m2(),!process.env.BLADE_SERVER_PASSWORD)console.log(t1.yellow("⚠️ BLADE_SERVER_PASSWORD is not set; server is unsecured.")),console.log(t1.gray(` Set this environment variable to enable Basic Auth.
2722
+ `,aW={command:"web",describe:"Start Blade server and open web interface",builder:j6,handler:async($)=>{let Z=y6($);if(await m2(),!process.env.BLADE_SERVER_PASSWORD)console.log(t1.yellow("⚠️ BLADE_SERVER_PASSWORD is not set; server is unsecured.")),console.log(t1.gray(` Set this environment variable to enable Basic Auth.
2723
2723
  `));let Y=await l8.listenAsync(Z);if(console.log(t1.cyan(AA)),console.log(t1.gray(` v${Z1()}
2724
- `)),Z.hostname==="0.0.0.0"){let Q=`http://localhost:${Y.port}`;console.log(t1.blue.bold(" Local access: "),t1.white(Q));let X=J6();for(let J of X)console.log(t1.blue.bold(" Network access: "),t1.white(`http://${J}:${Y.port}`));rW(Q).catch(()=>{})}else{let Q=Y.url.toString();console.log(t1.blue.bold(" Web interface: "),t1.white(Q)),rW(Q).catch(()=>{})}console.log(""),console.log(t1.gray(` Press Ctrl+C to stop the server.
2725
- `)),await new Promise(()=>{}),await Y.stop()}};Q0();U$();Y1();Q0();M0();function nW(){process.stdout.write("\x1B[?25h"),process.stdout.write("\x1B[0m")}var q4=x("Service");function bA($){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 i8{static instance=null;cleanupHandlers=[];isShuttingDown=!1;initialized=!1;constructor(){}static getInstance(){if(!i8.instance)i8.instance=new i8;return i8.instance}initialize(){if(this.initialized){q4.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",()=>{q4.info("[GracefulShutdown] 收到 SIGTERM 信号"),this.shutdown("SIGTERM",0)}),process.env.BLADE_NON_INTERACTIVE==="true")process.on("SIGINT",()=>{q4.info("[GracefulShutdown] 收到 SIGINT 信号(非交互模式)"),this.shutdown("SIGINT",0)});this.initialized=!0,q4.debug("[GracefulShutdown] 全局错误处理器已初始化")}registerCleanup($){return this.cleanupHandlers.push($),q4.debug(`[GracefulShutdown] 注册清理函数,当前共 ${this.cleanupHandlers.length} 个`),()=>{let Z=this.cleanupHandlers.indexOf($);if(Z!==-1)this.cleanupHandlers.splice(Z,1),q4.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){q4.debug("[GracefulShutdown] 已在退出过程中,跳过重复退出");return}this.isShuttingDown=!0,q4.info(`[GracefulShutdown] 开始优雅退出 (原因: ${$})`);try{await DQ()}catch(X){}try{let X=y0.getInstance();if(X.isEnabled()){let J=G0(),G=J.session?.sessionId||"unknown",q=J.config?.config?.permissionMode||"default";await X.executeSessionEndHooks(bA($),{projectDir:process.cwd(),sessionId:G,permissionMode:q})}}catch(X){console.error("[GracefulShutdown] SessionEnd hooks 执行失败:",X)}let Y=5000,Q=new Promise((X,J)=>{setTimeout(()=>{J(Error(`清理超时 (${Y}ms)`))},Y)});try{let X=this.runCleanupHandlers();await Promise.race([X,Q])}catch(X){console.error("[GracefulShutdown] 清理过程中发生错误:",X)}finally{nW(),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 o4=()=>{return i8.getInstance()},oW=($)=>{return o4().registerCleanup($)},sW=()=>{o4().initialize()},r8=($=0)=>{nW(),process.exit($)};m4();H8();Y1();Q0();d2();f8();import{useMemoizedFn as jF}from"ahooks";import{useEffect as ZM,useState as JQ}from"react";K2();l4();M0();j8();U$();Q0();import{useMemoizedFn as t$}from"ahooks";import{Box as A4,useApp as sV}from"ink";import{useEffect as W8,useRef as F5}from"react";i3();j1();V4();import{useShallow as tW}from"zustand/react/shallow";M0();import{useStore as RA}from"zustand";function w0($){return RA(u1,$)}U$();var VA=[],eW=()=>w0(($)=>$.session.sessionId),h7=()=>w0(($)=>$.session.messages),$U=()=>w0(($)=>$.session.clearCount),ZU=()=>w0(($)=>$.session.isCompacting),K4=()=>w0(($)=>$.session.actions),YU=()=>w0(($)=>{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)}),QU=()=>w0(($)=>$.app.initializationStatus),XU=()=>w0(($)=>$.app.initializationError),x7=()=>w0(($)=>$.app.activeModal),JU=()=>w0(($)=>$.app.todos),GU=()=>w0(($)=>$.app.modelEditorTarget),qU=()=>w0(($)=>$.app.sessionSelectorData),KU=()=>w0(($)=>$.app.awaitingSecondCtrlC),W4=()=>w0(($)=>$.app.actions),p7=()=>w0(($)=>$.app.initializationStatus==="ready"),WU=()=>w0(($)=>$.app.todos.length>0),a8=()=>w0(($)=>$.config.config?.permissionMode||"default"),UU=()=>w0(($)=>$.config.config?.models??VA),m7=()=>w0(($)=>{let Z=$.config.config;if(!Z)return;let Y=Z.currentModelId;return Z.models.find((X)=>X.id===Y)??Z.models[0]}),OU=()=>w0(($)=>$.config.config?.currentModelId),d0=()=>w0(($)=>{let Z=$.config.config?.theme??"default";if(i$.getCurrentThemeName()!==Z)try{i$.setTheme(Z)}catch{}return i$.getTheme()}),q1=()=>w0(($)=>$.focus.currentFocus),FU=()=>w0(($)=>$.focus.actions),U4=()=>w0(($)=>$.command.isProcessing),HU=()=>w0(($)=>$.command.actions),_U=()=>w0(($)=>$.command.pendingCommands),g7=()=>w0(($)=>$.app.thinkingModeEnabled),zU=()=>w0(($)=>$.session.currentThinkingContent),BU=()=>w0(($)=>$.session.thinkingExpanded),wU=()=>w0(($)=>$.session.currentStreamingMessageId),LU=()=>w0(tW(($)=>({lines:$.session.currentStreamingLines,tail:$.session.currentStreamingTail,lineCount:$.session.currentStreamingLineCount,version:$.session.currentStreamingVersion}))),NU=()=>w0(($)=>$.session.finalizingStreamingMessageId),AU=()=>w0(($)=>$.session.historyExpanded),bU=()=>w0(($)=>$.session.expandedMessageCount),RU=()=>w0(tW(($)=>{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}}));M0();Y1();Q0();M9();import{useMemoizedFn as O4}from"ahooks";import{useEffect as DU,useRef as G6}from"react";l4();M0();W3();JY();F2();import{useMemoizedFn as VU}from"ahooks";import{useRef as MA}from"react";function MU($){let Z=MA(void 0),Y=VU(async(X)=>{let J=await G$.create({systemPrompt:X?.systemPrompt??$.systemPrompt,appendSystemPrompt:X?.appendSystemPrompt??$.appendSystemPrompt,maxTurns:X?.maxTurns??$.maxTurns,modelId:X?.modelId??$.modelId});return Z.current=J,J}),Q=VU(()=>{if(Z.current)Z.current=void 0});return{agentRef:Z,createAgent:Y,cleanupAgent:Q}}var jU=x("UI");function DA($,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 r8(0),!0;default:return!1}}function jA($){return typeof $==="object"&&$!==null&&$.action==="invoke_once_model"&&typeof $.modelId==="string"&&typeof $.prompt==="string"}function yA($){return typeof $==="object"&&$!==null&&$.action==="invoke_skill"&&typeof $.skillName==="string"}function TA($){return typeof $==="object"&&$!==null&&$.action==="invoke_custom_command"&&typeof $.commandName==="string"&&typeof $.processedContent==="string"}function EA($){return typeof $==="object"&&$!==null&&$.action==="invoke_plugin_command"&&typeof $.commandName==="string"&&typeof $.processedContent==="string"}function IA($){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 yU=($,Z,Y,Q)=>{let X=U4(),J=h7(),G=eW(),q=a8(),K=g7(),W=K4(),U=W4(),O=HU(),F=G6(!1),{createAgent:H,cleanupAgent:_}=MU({systemPrompt:$,appendSystemPrompt:Z,maxTurns:Q}),z=300,w=5,B=400,L=G6(""),N=G6(null),M=G6(""),b=G6(null),j=O4(()=>{if(L.current){let I=L.current,D=W.appendAssistantContent(I);I5(D,I),L.current=""}if(N.current)clearTimeout(N.current),N.current=null}),T=O4(()=>{if(M.current)W.appendThinkingContent(M.current),M.current="";if(b.current)clearTimeout(b.current),b.current=null}),A=(I)=>{let D=0;for(let V of I)if(V===`
2724
+ `)),Z.hostname==="0.0.0.0"){let Q=`http://localhost:${Y.port}`;console.log(t1.blue.bold(" Local access: "),t1.white(Q));let X=J7();for(let J of X)console.log(t1.blue.bold(" Network access: "),t1.white(`http://${J}:${Y.port}`));rW(Q).catch(()=>{})}else{let Q=Y.url.toString();console.log(t1.blue.bold(" Web interface: "),t1.white(Q)),rW(Q).catch(()=>{})}console.log(""),console.log(t1.gray(` Press Ctrl+C to stop the server.
2725
+ `)),await new Promise(()=>{}),await Y.stop()}};Q0();U$();Y1();Q0();M0();function nW(){process.stdout.write("\x1B[?25h"),process.stdout.write("\x1B[0m")}var q4=x("Service");function bA($){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 i8{static instance=null;cleanupHandlers=[];isShuttingDown=!1;initialized=!1;constructor(){}static getInstance(){if(!i8.instance)i8.instance=new i8;return i8.instance}initialize(){if(this.initialized){q4.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",()=>{q4.info("[GracefulShutdown] 收到 SIGTERM 信号"),this.shutdown("SIGTERM",0)}),process.env.BLADE_NON_INTERACTIVE==="true")process.on("SIGINT",()=>{q4.info("[GracefulShutdown] 收到 SIGINT 信号(非交互模式)"),this.shutdown("SIGINT",0)});this.initialized=!0,q4.debug("[GracefulShutdown] 全局错误处理器已初始化")}registerCleanup($){return this.cleanupHandlers.push($),q4.debug(`[GracefulShutdown] 注册清理函数,当前共 ${this.cleanupHandlers.length} 个`),()=>{let Z=this.cleanupHandlers.indexOf($);if(Z!==-1)this.cleanupHandlers.splice(Z,1),q4.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){q4.debug("[GracefulShutdown] 已在退出过程中,跳过重复退出");return}this.isShuttingDown=!0,q4.info(`[GracefulShutdown] 开始优雅退出 (原因: ${$})`);try{await DQ()}catch(X){}try{let X=y0.getInstance();if(X.isEnabled()){let J=G0(),G=J.session?.sessionId||"unknown",q=J.config?.config?.permissionMode||"default";await X.executeSessionEndHooks(bA($),{projectDir:process.cwd(),sessionId:G,permissionMode:q})}}catch(X){console.error("[GracefulShutdown] SessionEnd hooks 执行失败:",X)}let Y=5000,Q=new Promise((X,J)=>{setTimeout(()=>{J(Error(`清理超时 (${Y}ms)`))},Y)});try{let X=this.runCleanupHandlers();await Promise.race([X,Q])}catch(X){console.error("[GracefulShutdown] 清理过程中发生错误:",X)}finally{nW(),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 o4=()=>{return i8.getInstance()},oW=($)=>{return o4().registerCleanup($)},sW=()=>{o4().initialize()},r8=($=0)=>{nW(),process.exit($)};m4();H8();Y1();Q0();d2();f8();import{useMemoizedFn as jF}from"ahooks";import{useEffect as ZM,useState as JQ}from"react";K2();l4();M0();j8();U$();Q0();import{useMemoizedFn as t$}from"ahooks";import{Box as A4,useApp as sV}from"ink";import{useEffect as W8,useRef as F5}from"react";i3();j1();V4();import{useShallow as tW}from"zustand/react/shallow";M0();import{useStore as RA}from"zustand";function w0($){return RA(u1,$)}U$();var VA=[],eW=()=>w0(($)=>$.session.sessionId),h6=()=>w0(($)=>$.session.messages),$U=()=>w0(($)=>$.session.clearCount),ZU=()=>w0(($)=>$.session.isCompacting),K4=()=>w0(($)=>$.session.actions),YU=()=>w0(($)=>{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)}),QU=()=>w0(($)=>$.app.initializationStatus),XU=()=>w0(($)=>$.app.initializationError),x6=()=>w0(($)=>$.app.activeModal),JU=()=>w0(($)=>$.app.todos),GU=()=>w0(($)=>$.app.modelEditorTarget),qU=()=>w0(($)=>$.app.sessionSelectorData),KU=()=>w0(($)=>$.app.awaitingSecondCtrlC),W4=()=>w0(($)=>$.app.actions),p6=()=>w0(($)=>$.app.initializationStatus==="ready"),WU=()=>w0(($)=>$.app.todos.length>0),a8=()=>w0(($)=>$.config.config?.permissionMode||"default"),UU=()=>w0(($)=>$.config.config?.models??VA),m6=()=>w0(($)=>{let Z=$.config.config;if(!Z)return;let Y=Z.currentModelId;return Z.models.find((X)=>X.id===Y)??Z.models[0]}),OU=()=>w0(($)=>$.config.config?.currentModelId),d0=()=>w0(($)=>{let Z=$.config.config?.theme??"default";if(i$.getCurrentThemeName()!==Z)try{i$.setTheme(Z)}catch{}return i$.getTheme()}),q1=()=>w0(($)=>$.focus.currentFocus),FU=()=>w0(($)=>$.focus.actions),U4=()=>w0(($)=>$.command.isProcessing),HU=()=>w0(($)=>$.command.actions),_U=()=>w0(($)=>$.command.pendingCommands),g6=()=>w0(($)=>$.app.thinkingModeEnabled),zU=()=>w0(($)=>$.session.currentThinkingContent),BU=()=>w0(($)=>$.session.thinkingExpanded),wU=()=>w0(($)=>$.session.currentStreamingMessageId),LU=()=>w0(tW(($)=>({lines:$.session.currentStreamingLines,tail:$.session.currentStreamingTail,lineCount:$.session.currentStreamingLineCount,version:$.session.currentStreamingVersion}))),NU=()=>w0(($)=>$.session.finalizingStreamingMessageId),AU=()=>w0(($)=>$.session.historyExpanded),bU=()=>w0(($)=>$.session.expandedMessageCount),RU=()=>w0(tW(($)=>{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}}));M0();Y1();Q0();M9();import{useMemoizedFn as O4}from"ahooks";import{useEffect as DU,useRef as G7}from"react";l4();M0();W3();JY();F2();import{useMemoizedFn as VU}from"ahooks";import{useRef as MA}from"react";function MU($){let Z=MA(void 0),Y=VU(async(X)=>{let J=await G$.create({systemPrompt:X?.systemPrompt??$.systemPrompt,appendSystemPrompt:X?.appendSystemPrompt??$.appendSystemPrompt,maxTurns:X?.maxTurns??$.maxTurns,modelId:X?.modelId??$.modelId});return Z.current=J,J}),Q=VU(()=>{if(Z.current)Z.current=void 0});return{agentRef:Z,createAgent:Y,cleanupAgent:Q}}var jU=x("UI");function DA($,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 r8(0),!0;default:return!1}}function jA($){return typeof $==="object"&&$!==null&&$.action==="invoke_once_model"&&typeof $.modelId==="string"&&typeof $.prompt==="string"}function yA($){return typeof $==="object"&&$!==null&&$.action==="invoke_skill"&&typeof $.skillName==="string"}function TA($){return typeof $==="object"&&$!==null&&$.action==="invoke_custom_command"&&typeof $.commandName==="string"&&typeof $.processedContent==="string"}function EA($){return typeof $==="object"&&$!==null&&$.action==="invoke_plugin_command"&&typeof $.commandName==="string"&&typeof $.processedContent==="string"}function IA($){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 yU=($,Z,Y,Q)=>{let X=U4(),J=h6(),G=eW(),q=a8(),K=g6(),W=K4(),U=W4(),O=HU(),F=G7(!1),{createAgent:H,cleanupAgent:_}=MU({systemPrompt:$,appendSystemPrompt:Z,maxTurns:Q}),z=300,w=5,B=400,L=G7(""),N=G7(null),M=G7(""),b=G7(null),j=O4(()=>{if(L.current){let I=L.current,D=W.appendAssistantContent(I);I5(D,I),L.current=""}if(N.current)clearTimeout(N.current),N.current=null}),T=O4(()=>{if(M.current)W.appendThinkingContent(M.current),M.current="";if(b.current)clearTimeout(b.current),b.current=null}),A=(I)=>{let D=0;for(let V of I)if(V===`
2726
2726
  `)D++;return D},k=O4((I)=>{L.current+=I;let D=L.current;if(A(D)>=5||D.length>=400){j();return}if(!N.current)N.current=setTimeout(j,300)}),c=O4((I)=>{M.current+=I;let D=M.current;if(A(D)>=5||D.length>=400){T();return}if(!b.current)b.current=setTimeout(T,300)}),o=O4(()=>{if(L.current="",N.current)clearTimeout(N.current),N.current=null;if(M.current="",b.current)clearTimeout(b.current),b.current=null});DU(()=>{return()=>{_(),o()}},[_,o]),DU(()=>{if(!K)W.setCurrentThinkingContent(null)},[K,W]);let S=O4(()=>{if(!X)return;j(),T(),O.abort(),U.setTodos([]);let I=G0().session.currentStreamingMessageId;if(I)v5(I);if(W.finalizeStreamingMessage(),!F.current)W.addAssistantMessage("✋ 任务已停止"),F.current=!0}),y=O4(async(I)=>{let{text:D}=I,V=!1,g;try{if(p8(D)){await m2();let J0=O.createAbortController(),W$={cwd:process.cwd(),signal:J0.signal},A0=await m8(D,W$);if(A0.message){if(DA(A0.message,A0.data,U,W))return{success:!0}}let X2=!1;if(yA(A0.data)){let{skillName:T$,skillArgs:W1}=A0.data,p1=W1?`Please use the "${T$}" skill to help me with: ${W1}`:`Please use the "${T$}" skill.`;W.addUserMessage(p1),V=!0,X2=!0,I={displayText:p1,text:p1,images:[],parts:[{type:"text",text:p1}]}}if(TA(A0.data)){let{commandName:T$,processedContent:W1}=A0.data;W.addUserMessage(D),V=!0,X2=!0;let p1=`# Custom Command: /${T$}
2727
2727
 
2728
2728
  The user has invoked the custom command "/${T$}". Follow the instructions below to complete the task.
@@ -2733,7 +2733,7 @@ ${W1}
2733
2733
 
2734
2734
  ---
2735
2735
 
2736
- Remember: Follow the above instructions carefully to complete the user's request.`;I={displayText:D,text:p1,images:[],parts:[{type:"text",text:p1}]}}if(EA(A0.data)){let{commandName:T$,pluginName:W1,processedContent:p1}=A0.data;W.addUserMessage(D),V=!0,X2=!0;let w6=`# Plugin Command: /${T$}
2736
+ Remember: Follow the above instructions carefully to complete the user's request.`;I={displayText:D,text:p1,images:[],parts:[{type:"text",text:p1}]}}if(EA(A0.data)){let{commandName:T$,pluginName:W1,processedContent:p1}=A0.data;W.addUserMessage(D),V=!0,X2=!0;let w7=`# Plugin Command: /${T$}
2737
2737
 
2738
2738
  The user has invoked the plugin command "/${T$}" from plugin "${W1}". Follow the instructions below to complete the task.
2739
2739
 
@@ -2743,9 +2743,9 @@ ${p1}
2743
2743
 
2744
2744
  ---
2745
2745
 
2746
- Remember: Follow the above instructions carefully to complete the user's request.`;I={displayText:D,text:w6,images:[],parts:[{type:"text",text:w6}]}}if(jA(A0.data)){let{modelId:T$,prompt:W1}=A0.data;W.addUserMessage(W1),V=!0,X2=!0,g=T$,I={displayText:W1,text:W1,images:[],parts:[{type:"text",text:W1}]}}if(!X2){if(!A0.success&&A0.error)return W.addAssistantMessage(`❌ ${A0.error}`),{success:A0.success,output:A0.message,error:A0.error,metadata:A0.data};let T$=A0.message;if(A0.success&&typeof T$==="string"&&T$.trim()!=="")W.addAssistantMessage(T$);return{success:A0.success,output:A0.message,error:A0.error,metadata:A0.data}}}let u=y0.getInstance(),v=I,Z0,d=await u.executeUserPromptSubmitHooks(I.text,{projectDir:process.cwd(),sessionId:G,permissionMode:q,hasImages:I.images.length>0,imageCount:I.images.length});if(!d.proceed){if(d.warning)W.addAssistantMessage(`⚠️ ${d.warning}`);return{success:!1,error:"blocked by hook"}}if(d.updatedPrompt)v={...I,text:d.updatedPrompt,displayText:d.updatedPrompt,parts:[{type:"text",text:d.updatedPrompt}]};if(d.contextInjection)Z0=d.contextInjection;if(!V)W.addUserMessage(v.displayText);let s=IA(v),C=O.createAbortController(),i=await H(g?{modelId:g}:void 0);if(C.signal.aborted)return jU.info("[handleCommandSubmit] Agent 创建期间已被中止"),{success:!1,error:"aborted"};let n=J.map((J0)=>({role:J0.role,content:J0.content}));if(Z0)n.push({role:"system",content:`<user-prompt-submit-hook>
2746
+ Remember: Follow the above instructions carefully to complete the user's request.`;I={displayText:D,text:w7,images:[],parts:[{type:"text",text:w7}]}}if(jA(A0.data)){let{modelId:T$,prompt:W1}=A0.data;W.addUserMessage(W1),V=!0,X2=!0,g=T$,I={displayText:W1,text:W1,images:[],parts:[{type:"text",text:W1}]}}if(!X2){if(!A0.success&&A0.error)return W.addAssistantMessage(`❌ ${A0.error}`),{success:A0.success,output:A0.message,error:A0.error,metadata:A0.data};let T$=A0.message;if(A0.success&&typeof T$==="string"&&T$.trim()!=="")W.addAssistantMessage(T$);return{success:A0.success,output:A0.message,error:A0.error,metadata:A0.data}}}let u=y0.getInstance(),v=I,Z0,d=await u.executeUserPromptSubmitHooks(I.text,{projectDir:process.cwd(),sessionId:G,permissionMode:q,hasImages:I.images.length>0,imageCount:I.images.length});if(!d.proceed){if(d.warning)W.addAssistantMessage(`⚠️ ${d.warning}`);return{success:!1,error:"blocked by hook"}}if(d.updatedPrompt)v={...I,text:d.updatedPrompt,displayText:d.updatedPrompt,parts:[{type:"text",text:d.updatedPrompt}]};if(d.contextInjection)Z0=d.contextInjection;if(!V)W.addUserMessage(v.displayText);let s=IA(v),C=O.createAbortController(),i=await H(g?{modelId:g}:void 0);if(C.signal.aborted)return jU.info("[handleCommandSubmit] Agent 创建期间已被中止"),{success:!1,error:"aborted"};let n=J.map((J0)=>({role:J0.role,content:J0.content}));if(Z0)n.push({role:"system",content:`<user-prompt-submit-hook>
2747
2747
  ${Z0}
2748
- </user-prompt-submit-hook>`});let B0={messages:n,userId:"cli-user",sessionId:G,workspaceRoot:process.cwd(),signal:C.signal,confirmationHandler:Y,permissionMode:q},j0=0,K$=0,$1=0,K1={stream:!0,onContentDelta:(J0)=>{j0++,K$+=J0.length,D1("useCommandHandler","onContentDelta",{callCount:j0,deltaLen:J0.length,totalLen:K$}),k(J0)},onThinkingDelta:K?(J0)=>{c(J0)}:void 0,onThinking:K?(J0)=>{W.setCurrentThinkingContent(J0)}:void 0,onStreamEnd:()=>{if(D1("useCommandHandler","onStreamEnd",{contentDeltaCallCount:j0,contentDeltaTotalLen:K$,remainingBuffer:L.current.length}),N.current)clearTimeout(N.current),N.current=null;if(b.current)clearTimeout(b.current),b.current=null;let J0=L.current,W$=M.current;L.current="",M.current="";let A0=G0().session.currentStreamingMessageId;if(A0){if(J0)I5(A0,J0);v5(A0)}W.finalizeStreamingMessage(J0,W$)},onContent:(J0)=>{if($1++,!J0.trim())return;D1("useCommandHandler","onContent (non-stream)",{callCount:$1,contentLen:J0.length}),W.addAssistantMessageAndClearThinking(J0)},onToolStart:(J0)=>{if(J0.type!=="function")return;if(J0.function.name==="TodoWrite")return;try{let W$=JSON.parse(J0.function.arguments),A0=t3(J0.function.name,W$);W.addToolMessage(A0,{toolName:J0.function.name,phase:"start",summary:A0,params:W$})}catch(W$){jU.error("[useCommandHandler] onToolStart error:",W$)}},onToolResult:async(J0,W$)=>{if(J0.type!=="function")return;let A0=W$.metadata?.summary;if(!A0)return;let X2;if(cK(J0.function.name,W$))X2=lK(J0.function.name,W$)||W$.displayContent;W.addToolMessage(A0,{toolName:J0.function.name,phase:"complete",summary:A0,detail:X2})},onTokenUsage:(J0)=>{W.updateTokenUsage(J0)},onCompacting:(J0)=>{if(W.setCompacting(J0),!J0)W.resetTokenUsage()},onTurnLimitReached:Y?async(J0)=>{let W$=await Y.requestConfirmation({type:"maxTurnsExceeded",title:"对话轮次上限",message:`已进行 ${J0.turnsCount} 轮对话。是否继续?`,risks:["继续执行可能导致更长的等待时间","可能产生更多的 API 费用"]});return{continue:W$.approved,reason:W$.reason}}:void 0},b1=await i.chat(s,B0,K1);if(!b1||b1.trim()===""){if(!F.current&&j0===0)return W.addAssistantMessage("⏹ 已取消"),{success:!0,output:"已取消"};return{success:!0,output:b1??""}}return{success:!0,output:b1}}catch(u){if(F.current)return{success:!1,error:"aborted"};let v=u instanceof Error?u.message:"未知错误",Z0=v.includes("can only concatenate str")||v.includes("image_url")||v.includes("multimodal")||v.includes("vision")||v.includes("does not support images"),d=v;if(Z0)d="当前模型不支持图片理解功能。请切换到支持视觉能力的模型(如 Claude 4.5、GPT-5.2、Gemini 3 Pro、Qwen3-VL-Plus 等)后重试。";let s={success:!1,error:d};return W.addAssistantMessage(`❌ ${d}`),s}}),l=O4(async(I)=>{if(!I.text.trim()&&I.images.length===0)return;if(X){O.enqueueCommand({displayText:I.displayText,text:I.text,images:I.images,parts:I.parts});return}U.setTodos([]),F.current=!1;let D=O.createAbortController();o(),W.clearFinalizingStreamingMessageId(),O.setProcessing(!0);try{let V=await y(I);if(!V.success&&V.error&&V.error!=="aborted")W.setError(V.error)}catch(V){if(V instanceof Error&&(V.name==="AbortError"||V.message.includes("aborted")));else{let g=V instanceof Error?V.message:"未知错误";W.setError(`执行失败: ${g}`)}}finally{if(O.getAbortController()===D){O.setProcessing(!1),O.clearAbortController(D),W.setCurrentThinkingContent(null);let u=O.dequeueCommand();if(u)setTimeout(()=>l({displayText:u.displayText,text:u.text,images:u.images,parts:u.parts}),100)}}});return{executeCommand:l,handleAbort:S,isProcessing:X}};import{useMemoizedFn as u7}from"ahooks";import{useState as TU}from"react";var EU=()=>{let[$,Z]=TU([]),[Y,Q]=TU(-1),X=u7((K,W)=>{let U={display:K,pasteMappings:W?new Map(W):new Map};Z((O)=>[...O,U]),Q(-1)}),J=u7(()=>{if($.length===0)return null;let K=Y===-1?$.length-1:Math.max(0,Y-1);return Q(K),$[K]||null}),G=u7(()=>{if(Y===-1)return null;let K=Y+1;if(K>=$.length)return Q(-1),null;else return Q(K),$[K]||null}),q=u7(()=>{Q(-1)});return{commandHistory:$,historyIndex:Y,addToHistory:X,getPreviousCommand:J,getNextCommand:G,resetHistoryIndex:q}};import{useMemoizedFn as zY}from"ahooks";import{useMemo as vA,useRef as IU,useState as PA}from"react";var vU=()=>{let[$,Z]=PA({isVisible:!1,details:null,resolver:null}),Y=IU(null),Q=IU([]),X=zY((K)=>{Y.current=K,Z({isVisible:Boolean(K),details:K?.details??null,resolver:K?.resolve??null})}),J=zY((K)=>{return new Promise((W)=>{let U={details:K,resolve:W};if(!Y.current){X(U);return}Q.current.push(U)})}),G=zY((K)=>{if(Y.current)Y.current.resolve(K);let W=Q.current.shift()??null;X(W)}),q=vA(()=>({requestConfirmation:J}),[J]);return{confirmationState:$,confirmationHandler:q,handleResponse:G}};import{useMemoizedFn as s4}from"ahooks";import{useRef as PU,useState as CA}from"react";var d7="␞",c7="␟";function l7($){return`${d7}PASTE:${$}:`}function BY(){return c7}var ku=new RegExp(`${d7}PASTE:(\\d+):[\\s\\S]*?${c7}`,"g");function SA($){return $.includes(d7)&&$.includes(c7)}function CU($="",Z=0){let[Y,Q]=CA({value:$,cursorPosition:Z}),X=PU(0),J=PU(new Map),G=s4((H)=>{Q((_)=>({value:H,cursorPosition:_.cursorPosition}));for(let _ of J.current.keys()){let z=l7(_);if(!H.includes(z))J.current.delete(_)}}),q=s4((H)=>{Q((_)=>({..._,cursorPosition:Math.max(0,Math.min(H,_.value.length))}))}),K=s4(()=>{Q({value:"",cursorPosition:0}),J.current.clear()}),W=s4((H)=>{X.current+=1;let _=X.current;return J.current.set(_,{type:"text",data:H}),_}),U=s4((H,_)=>{X.current+=1;let z=X.current;return J.current.set(z,{type:"image",data:H,mimeType:_}),z}),O=s4((H)=>{for(let[_,z]of H)if(J.current.set(_,z),_>=X.current)X.current=_}),F=s4((H)=>{let _=[],z=[];if(!SA(H)){let k=H.trim();if(k)z.push({type:"text",text:k});return{displayText:H,text:H,images:_,parts:z}}let w=new RegExp(`${d7}PASTE:(\\d+):[\\s\\S]*?${c7}`,"g"),B=Array.from(H.matchAll(w)),L=0,N="",M="";for(let k of B){let c=k.index,o=c+k[0].length,S=parseInt(k[1],10),y=J.current.get(S);if(c>L){let l=H.slice(L,c);z.push({type:"text",text:l}),N+=l,M+=l}if(!y)N+=k[0],M+=k[0],z.push({type:"text",text:k[0]});else if(y.type==="text")N+=y.data,M+=y.data,z.push({type:"text",text:y.data});else{let l={id:S,base64:y.data,mimeType:y.mimeType};_.push(l),z.push({type:"image",...l}),M+=`[Image #${S}]`}L=o}if(L<H.length){let k=H.slice(L);z.push({type:"text",text:k}),N+=k,M+=k}let b=[];for(let k of z)if(k.type==="text"&&b.length>0&&b[b.length-1].type==="text")b[b.length-1].text+=k.text;else b.push(k);let j=0,T=b.length;while(j<b.length&&b[j].type==="text"&&b[j].text.trim()==="")j++;while(T>j&&b[T-1].type==="text"&&b[T-1].text.trim()==="")T--;let A=b.slice(j,T);return{displayText:M.trim(),text:N.trim(),images:_,parts:A}});return{value:Y.value,cursorPosition:Y.cursorPosition,setValue:G,setCursorPosition:q,clear:K,pasteMap:J.current,addPasteMapping:W,addImagePasteMapping:U,restorePasteMappings:O,resolveInput:F}}Q0();l4();import{useMemoizedFn as pU}from"ahooks";import{useInput as gA}from"ink";import{useEffect as mU,useRef as gU,useState as AY}from"react";H7();x3();import kA from"fast-glob";import fA from"fuse.js";import{useEffect as SU,useMemo as wY,useState as LY}from"react";var n8=null,hA=5000;function xA($,Z){let Y=[...$.matchAll(/(?:^|\s)(@(?:"[^"]*"|(?:[^\\ ]|\\ )*))/g)];for(let Q of Y){let X=Q[1],J=Q.index+(Q[0].length-X.length),G=J+X.length;if(Z>=J&&Z<=G){let q=X.slice(1),K=!1;if(q.startsWith('"')){if(K=!0,q=q.slice(1),q.endsWith('"'))q=q.slice(0,-1)}return{hasQuery:!0,query:q,startIndex:J,endIndex:G,quoted:K}}}return{hasQuery:!1,query:"",startIndex:-1,endIndex:-1,quoted:!1}}var pA=[...X1.map(($)=>`${$}/**`),...X1,...D8.map(($)=>`**/${$}`)];function kU($,Z,Y={}){let{cwd:Q=process.cwd(),maxSuggestions:X=15,ignorePatterns:J=pA,debounceDelay:G=300,fuzzyMatch:q=!0}=Y,[K,W]=LY([]),[U,O]=LY(!1),[F,H]=LY(0),_=wY(()=>JSON.stringify(J),[J]),z=wY(()=>{if(Z===void 0)return{hasQuery:!1,query:"",startIndex:-1,endIndex:-1,quoted:!1};return xA($,Z)},[$,Z]);SU(()=>{if(!$.includes("@")){W([]),O(!1);return}let B=Date.now();if(n8&&n8.cwd===Q&&n8.ignoreKey===_&&B-n8.timestamp<hA){W(n8.files),O(!1);return}let L=!1,M=setTimeout(async()=>{O(!0);try{let j=(await kA("**/*",{cwd:Q,dot:!1,followSymbolicLinks:!1,onlyFiles:!1,markDirectories:!0,unique:!0,ignore:J})).map((T)=>T.replace(/\\/g,"/"));if(!L)W(j),n8={cwd:Q,ignoreKey:_,files:j,timestamp:B}}catch(b){if(console.error("Failed to load files for @ completion:",b),!L)W([])}finally{if(!L)O(!1)}},G);return()=>{L=!0,clearTimeout(M)}},[$,Q,G,_]);let w=wY(()=>{if(!z.hasQuery||K.length===0)return[];let B=z.query.toLowerCase();if(B==="")return K.slice(0,X);if(q)return new fA(K,{threshold:0.4,ignoreLocation:!0,minMatchCharLength:1}).search(B).slice(0,X).map((M)=>M.item);return K.filter((L)=>L.toLowerCase().includes(B)).slice(0,X)},[z,K,X,q]);return SU(()=>{H(0)},[w]),{...z,suggestions:w,selectedIndex:F,loading:U}}function mA($,Z=!1){if($.includes(" ")||Z)return`@"${$}"`;return`@${$}`}function NY($,Z,Y){if(!Z.hasQuery)return{newInput:$,newCursorPos:$.length};let Q=mA(Y,Z.quoted),X=$.slice(0,Z.startIndex),J=$.slice(Z.endIndex),G=X+Q+" "+J,q=Z.startIndex+Q.length+1;return{newInput:G,newCursorPos:q}}import{useMemoizedFn as fU}from"ahooks";import{useEffect as hU,useRef as xU}from"react";M0();var Q$=($,Z)=>{let Y=xU(!1),Q=xU(null),X=fU(()=>{if(Q.current)clearTimeout(Q.current);Q.current=setTimeout(()=>{R2().setAwaitingSecondCtrlC(!1),Y.current=!1,Q.current=null},3000)}),J=()=>{o4().shutdown("SIGINT",0)},G=fU(()=>{if(!Y.current){if(Y.current=!0,$&&Z)Z();R2().setAwaitingSecondCtrlC(!0),X()}else{if(Q.current)clearTimeout(Q.current),Q.current=null;R2().setAwaitingSecondCtrlC(!1),J()}});return hU(()=>{if($){if(R2().setAwaitingSecondCtrlC(!1),Y.current=!1,Q.current)clearTimeout(Q.current),Q.current=null}},[$]),hU(()=>{return()=>{if(Q.current)clearTimeout(Q.current)}},[]),G};var i7=x("UI"),uU=($,Z,Y,Q,X,J,G,q,K,W)=>{let O=q1()==="main-input",F=$.value,H=$.setValue,_=$.cursorPosition,z=K4(),w=W4(),B=m7(),L=B?C8(B):!1,[N,M]=AY(!1),[b,j]=AY([]),[T,A]=AY(0),k=kU(F,_,{cwd:process.cwd(),maxSuggestions:10}),c=Q$(G||!1,J),o=gU(0),S=500,y=gU(!1);mU(()=>{if(G)y.current=!1},[G]),mU(()=>{if(k.hasQuery&&k.suggestions.length>0){let D=k.suggestions.map((V)=>({command:V,description:LJ(V)?`Directory: ${V}`:`File: ${V}`,matchScore:1}));j(D),M(!0),A(0)}else if(F.startsWith("/"))if(F.includes(" "))M(!1),j([]);else{let V=D7(F);j(V),M(V.length>0),A(0)}else M(!1),j([])},[F,k.hasQuery,k.suggestions]);let l=pU(()=>{z.clearMessages(),z.setError(null)}),I=pU(()=>{i7.debug("[DIAG] handleSubmit called:",{input:F,showSuggestions:N});let D=F.trim();if(D){let V=$.resolveInput(D);i7.debug("[DIAG] Submitting command:",{displayText:D,textLength:V.text.length,imageCount:V.images.length}),M(!1),j([]);let g=$.pasteMap.size>0?new Map($.pasteMap):new Map;X(D,g),$.clear(),Z(V),i7.debug("[DIAG] Command submitted to onSubmit callback")}else i7.debug("[DIAG] Empty command, not submitting")});return gA((D,V)=>{if(D==="?"&&!F){K?.(),setTimeout(()=>$.clear(),0);return}if(V.backspace||V.delete||V.leftArrow||V.rightArrow||V.pageUp||V.pageDown||!V.ctrl&&!V.meta&&!V.escape&&!V.tab&&!V.upArrow&&!V.downArrow&&!V.return&&!(D==="?"&&!F))return;if(V.ctrl&&D==="c"||V.meta&&D==="c"||V.ctrl&&D==="d"||V.meta&&D==="d"){c();return}if(V.ctrl&&D==="l"||V.meta&&D==="l"){l();return}if(V.ctrl&&D==="t"||V.meta&&D==="t"){z.toggleThinkingExpanded();return}if(V.ctrl&&D==="o"||V.meta&&D==="o"){z.toggleHistoryExpanded();return}if(V.escape){if(W)K?.();else if(G&&J){if(y.current)return;y.current=!0,J()}else if(N)M(!1),j([]);else if(F){let u=Date.now();if(u-o.current<500)$.clear(),o.current=0;else o.current=u}return}if(V.tab&&V.shift){q?.();return}if(V.tab){if(N&&b.length>0){let u=b[T].command;if(k.hasQuery&&k.suggestions.includes(u)){let{newInput:v,newCursorPos:Z0}=NY(F,k,u);H(v),$.setCursorPosition(Z0)}else{let v=u+" ";H(v),$.setCursorPosition(v.length)}M(!1),j([])}else if(L)w.toggleThinkingMode();return}if(V.return){if(N&&b.length>0){let u=b[T].command;if(k.hasQuery&&k.suggestions.includes(u)){let{newInput:v,newCursorPos:Z0}=NY(F,k,u);H(v),$.setCursorPosition(Z0)}else{let v=u+" ";H(v),$.setCursorPosition(v.length)}M(!1),j([])}else I();return}if(V.upArrow){if(N&&b.length>0){let u=b.length-1;A((v)=>v>0?v-1:u)}else{let u=Y();if(u){if(u.pasteMappings.size>0)$.restorePasteMappings(u.pasteMappings);H(u.display),$.setCursorPosition(u.display.length)}}return}if(V.downArrow){if(N&&b.length>0){let u=b.length-1;A((v)=>v<u?v+1:0)}else{let u=Q();if(u){if(u.pasteMappings.size>0)$.restorePasteMappings(u.pasteMappings);H(u.display),$.setCursorPosition(u.display.length)}}return}},{isActive:O}),{handleSubmit:I,showSuggestions:N,suggestions:b,selectedSuggestionIndex:T}};import iA from"ansi-escapes";import{useStdout as rA}from"ink";import{useCallback as aA,useEffect as nA,useRef as oA}from"react";import{useStdout as uA}from"ink";import{debounce as dA}from"lodash-es";import{useEffect as cA,useState as lA}from"react";function o8($=200){let{stdout:Z}=uA(),[Y,Q]=lA(Z.columns||80);return cA(()=>{let X=dA(()=>{Q(Z.columns||80)},$);return X(),Z.on("resize",X),()=>{Z.off("resize",X),X.cancel()}},[Z,$]),Y}function dU(){let{stdout:$}=rA(),Z=o8(),Y=oA(!0),Q=w0((J)=>J.session.actions.incrementClearCount),X=aA(()=>{if($)$.write(iA.clearTerminal);Q()},[$,Q]);return nA(()=>{if(Y.current){Y.current=!1;return}let J=setTimeout(()=>{X()},300);return()=>{clearTimeout(J)}},[Z,X]),{refreshStatic:X}}F2();import cU from"node:fs";import sA from"node:os";import bY from"node:path";import{MultiSelect as tA}from"@inkjs/ui";import{useMemoizedFn as r7}from"ahooks";import{Box as q0,Text as $0,useFocus as eA,useFocusManager as $b,useInput as iU}from"ink";import a7 from"ink-select-input";import Zb from"ink-spinner";import q6 from"ink-text-input";import{useEffect as lU,useState as s8}from"react";import{jsxDEV as P}from"react/jsx-dev-runtime";var Yb=[{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"}],Qb=[{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 Xb($){if(!$||$.trim()==="")return"名称不能为空";if(!/^[a-z0-9-]+$/.test($))return"名称只能包含小写字母、数字和连字符";if($.startsWith("-")||$.endsWith("-"))return"名称不能以连字符开头或结尾";return null}function K6({onComplete:$,onCancel:Z,initialConfig:Y}){let[Q,X]=s8(Y?"name":"mode"),[J,G]=s8({name:Y?.name||"",description:Y?.description||"",tools:Y?.tools||[],color:Y?.color,location:Y?.location||"project",systemPrompt:Y?.systemPrompt||""}),[q,K]=s8(""),[W,U]=s8(!1),[O,F]=s8(""),[H,_]=s8(Y?"edit":"manual"),{focus:z}=$b(),B={manual:["mode","name","description","tools","color","location","systemPrompt","confirm"],ai:["mode","aiPrompt","aiGenerating","confirm"],edit:["name","description","tools","color","location","systemPrompt","confirm"]}[H];lU(()=>{if(Q==="name"||Q==="description"||Q==="systemPrompt"||Q==="aiPrompt")return;z(`step-${Q}`)},[Q,z]);let L=r7(()=>{let T=B.indexOf(Q);if(T<B.length-1)X(B[T+1])}),N=r7(()=>{if(O)F("");if(Q==="confirm"&&H==="ai"){X("aiPrompt");return}let T=B.indexOf(Q);if(T>0)X(B[T-1]);else Z()}),M=r7(async()=>{U(!0),F("");try{let T=await G$.create(),A=`你是一个 Subagent 配置生成专家。用户会描述他们想要创建的 agent,你需要根据描述生成一个完整的 agent 配置。
2748
+ </user-prompt-submit-hook>`});let B0={messages:n,userId:"cli-user",sessionId:G,workspaceRoot:process.cwd(),signal:C.signal,confirmationHandler:Y,permissionMode:q},j0=0,K$=0,$1=0,K1={stream:!0,onContentDelta:(J0)=>{j0++,K$+=J0.length,D1("useCommandHandler","onContentDelta",{callCount:j0,deltaLen:J0.length,totalLen:K$}),k(J0)},onThinkingDelta:K?(J0)=>{c(J0)}:void 0,onThinking:K?(J0)=>{W.setCurrentThinkingContent(J0)}:void 0,onStreamEnd:()=>{if(D1("useCommandHandler","onStreamEnd",{contentDeltaCallCount:j0,contentDeltaTotalLen:K$,remainingBuffer:L.current.length}),N.current)clearTimeout(N.current),N.current=null;if(b.current)clearTimeout(b.current),b.current=null;let J0=L.current,W$=M.current;L.current="",M.current="";let A0=G0().session.currentStreamingMessageId;if(A0){if(J0)I5(A0,J0);v5(A0)}W.finalizeStreamingMessage(J0,W$)},onContent:(J0)=>{if($1++,!J0.trim())return;D1("useCommandHandler","onContent (non-stream)",{callCount:$1,contentLen:J0.length}),W.addAssistantMessageAndClearThinking(J0)},onToolStart:(J0)=>{if(J0.type!=="function")return;if(J0.function.name==="TodoWrite")return;try{let W$=JSON.parse(J0.function.arguments),A0=t3(J0.function.name,W$);W.addToolMessage(A0,{toolName:J0.function.name,phase:"start",summary:A0,params:W$})}catch(W$){jU.error("[useCommandHandler] onToolStart error:",W$)}},onToolResult:async(J0,W$)=>{if(J0.type!=="function")return;let A0=W$.metadata?.summary;if(!A0)return;let X2;if(cK(J0.function.name,W$))X2=lK(J0.function.name,W$)||W$.displayContent;W.addToolMessage(A0,{toolName:J0.function.name,phase:"complete",summary:A0,detail:X2})},onTokenUsage:(J0)=>{W.updateTokenUsage(J0)},onCompacting:(J0)=>{if(W.setCompacting(J0),!J0)W.resetTokenUsage()},onTurnLimitReached:Y?async(J0)=>{let W$=await Y.requestConfirmation({type:"maxTurnsExceeded",title:"对话轮次上限",message:`已进行 ${J0.turnsCount} 轮对话。是否继续?`,risks:["继续执行可能导致更长的等待时间","可能产生更多的 API 费用"]});return{continue:W$.approved,reason:W$.reason}}:void 0},b1=await i.chat(s,B0,K1);if(!b1||b1.trim()===""){if(!F.current&&j0===0)return W.addAssistantMessage("⏹ 已取消"),{success:!0,output:"已取消"};return{success:!0,output:b1??""}}return{success:!0,output:b1}}catch(u){if(F.current)return{success:!1,error:"aborted"};let v=u instanceof Error?u.message:"未知错误",Z0=v.includes("can only concatenate str")||v.includes("image_url")||v.includes("multimodal")||v.includes("vision")||v.includes("does not support images"),d=v;if(Z0)d="当前模型不支持图片理解功能。请切换到支持视觉能力的模型(如 Claude 4.5、GPT-5.2、Gemini 3 Pro、Qwen3-VL-Plus 等)后重试。";let s={success:!1,error:d};return W.addAssistantMessage(`❌ ${d}`),s}}),l=O4(async(I)=>{if(!I.text.trim()&&I.images.length===0)return;if(X){O.enqueueCommand({displayText:I.displayText,text:I.text,images:I.images,parts:I.parts});return}U.setTodos([]),F.current=!1;let D=O.createAbortController();o(),W.clearFinalizingStreamingMessageId(),O.setProcessing(!0);try{let V=await y(I);if(!V.success&&V.error&&V.error!=="aborted")W.setError(V.error)}catch(V){if(V instanceof Error&&(V.name==="AbortError"||V.message.includes("aborted")));else{let g=V instanceof Error?V.message:"未知错误";W.setError(`执行失败: ${g}`)}}finally{if(O.getAbortController()===D){O.setProcessing(!1),O.clearAbortController(D),W.setCurrentThinkingContent(null);let u=O.dequeueCommand();if(u)setTimeout(()=>l({displayText:u.displayText,text:u.text,images:u.images,parts:u.parts}),100)}}});return{executeCommand:l,handleAbort:S,isProcessing:X}};import{useMemoizedFn as u6}from"ahooks";import{useState as TU}from"react";var EU=()=>{let[$,Z]=TU([]),[Y,Q]=TU(-1),X=u6((K,W)=>{let U={display:K,pasteMappings:W?new Map(W):new Map};Z((O)=>[...O,U]),Q(-1)}),J=u6(()=>{if($.length===0)return null;let K=Y===-1?$.length-1:Math.max(0,Y-1);return Q(K),$[K]||null}),G=u6(()=>{if(Y===-1)return null;let K=Y+1;if(K>=$.length)return Q(-1),null;else return Q(K),$[K]||null}),q=u6(()=>{Q(-1)});return{commandHistory:$,historyIndex:Y,addToHistory:X,getPreviousCommand:J,getNextCommand:G,resetHistoryIndex:q}};import{useMemoizedFn as zY}from"ahooks";import{useMemo as vA,useRef as IU,useState as PA}from"react";var vU=()=>{let[$,Z]=PA({isVisible:!1,details:null,resolver:null}),Y=IU(null),Q=IU([]),X=zY((K)=>{Y.current=K,Z({isVisible:Boolean(K),details:K?.details??null,resolver:K?.resolve??null})}),J=zY((K)=>{return new Promise((W)=>{let U={details:K,resolve:W};if(!Y.current){X(U);return}Q.current.push(U)})}),G=zY((K)=>{if(Y.current)Y.current.resolve(K);let W=Q.current.shift()??null;X(W)}),q=vA(()=>({requestConfirmation:J}),[J]);return{confirmationState:$,confirmationHandler:q,handleResponse:G}};import{useMemoizedFn as s4}from"ahooks";import{useRef as PU,useState as CA}from"react";var d6="␞",c6="␟";function l6($){return`${d6}PASTE:${$}:`}function BY(){return c6}var ku=new RegExp(`${d6}PASTE:(\\d+):[\\s\\S]*?${c6}`,"g");function SA($){return $.includes(d6)&&$.includes(c6)}function CU($="",Z=0){let[Y,Q]=CA({value:$,cursorPosition:Z}),X=PU(0),J=PU(new Map),G=s4((H)=>{Q((_)=>({value:H,cursorPosition:_.cursorPosition}));for(let _ of J.current.keys()){let z=l6(_);if(!H.includes(z))J.current.delete(_)}}),q=s4((H)=>{Q((_)=>({..._,cursorPosition:Math.max(0,Math.min(H,_.value.length))}))}),K=s4(()=>{Q({value:"",cursorPosition:0}),J.current.clear()}),W=s4((H)=>{X.current+=1;let _=X.current;return J.current.set(_,{type:"text",data:H}),_}),U=s4((H,_)=>{X.current+=1;let z=X.current;return J.current.set(z,{type:"image",data:H,mimeType:_}),z}),O=s4((H)=>{for(let[_,z]of H)if(J.current.set(_,z),_>=X.current)X.current=_}),F=s4((H)=>{let _=[],z=[];if(!SA(H)){let k=H.trim();if(k)z.push({type:"text",text:k});return{displayText:H,text:H,images:_,parts:z}}let w=new RegExp(`${d6}PASTE:(\\d+):[\\s\\S]*?${c6}`,"g"),B=Array.from(H.matchAll(w)),L=0,N="",M="";for(let k of B){let c=k.index,o=c+k[0].length,S=parseInt(k[1],10),y=J.current.get(S);if(c>L){let l=H.slice(L,c);z.push({type:"text",text:l}),N+=l,M+=l}if(!y)N+=k[0],M+=k[0],z.push({type:"text",text:k[0]});else if(y.type==="text")N+=y.data,M+=y.data,z.push({type:"text",text:y.data});else{let l={id:S,base64:y.data,mimeType:y.mimeType};_.push(l),z.push({type:"image",...l}),M+=`[Image #${S}]`}L=o}if(L<H.length){let k=H.slice(L);z.push({type:"text",text:k}),N+=k,M+=k}let b=[];for(let k of z)if(k.type==="text"&&b.length>0&&b[b.length-1].type==="text")b[b.length-1].text+=k.text;else b.push(k);let j=0,T=b.length;while(j<b.length&&b[j].type==="text"&&b[j].text.trim()==="")j++;while(T>j&&b[T-1].type==="text"&&b[T-1].text.trim()==="")T--;let A=b.slice(j,T);return{displayText:M.trim(),text:N.trim(),images:_,parts:A}});return{value:Y.value,cursorPosition:Y.cursorPosition,setValue:G,setCursorPosition:q,clear:K,pasteMap:J.current,addPasteMapping:W,addImagePasteMapping:U,restorePasteMappings:O,resolveInput:F}}Q0();l4();import{useMemoizedFn as pU}from"ahooks";import{useInput as gA}from"ink";import{useEffect as mU,useRef as gU,useState as AY}from"react";H6();x3();import kA from"fast-glob";import fA from"fuse.js";import{useEffect as SU,useMemo as wY,useState as LY}from"react";var n8=null,hA=5000;function xA($,Z){let Y=[...$.matchAll(/(?:^|\s)(@(?:"[^"]*"|(?:[^\\ ]|\\ )*))/g)];for(let Q of Y){let X=Q[1],J=Q.index+(Q[0].length-X.length),G=J+X.length;if(Z>=J&&Z<=G){let q=X.slice(1),K=!1;if(q.startsWith('"')){if(K=!0,q=q.slice(1),q.endsWith('"'))q=q.slice(0,-1)}return{hasQuery:!0,query:q,startIndex:J,endIndex:G,quoted:K}}}return{hasQuery:!1,query:"",startIndex:-1,endIndex:-1,quoted:!1}}var pA=[...X1.map(($)=>`${$}/**`),...X1,...D8.map(($)=>`**/${$}`)];function kU($,Z,Y={}){let{cwd:Q=process.cwd(),maxSuggestions:X=15,ignorePatterns:J=pA,debounceDelay:G=300,fuzzyMatch:q=!0}=Y,[K,W]=LY([]),[U,O]=LY(!1),[F,H]=LY(0),_=wY(()=>JSON.stringify(J),[J]),z=wY(()=>{if(Z===void 0)return{hasQuery:!1,query:"",startIndex:-1,endIndex:-1,quoted:!1};return xA($,Z)},[$,Z]);SU(()=>{if(!$.includes("@")){W([]),O(!1);return}let B=Date.now();if(n8&&n8.cwd===Q&&n8.ignoreKey===_&&B-n8.timestamp<hA){W(n8.files),O(!1);return}let L=!1,M=setTimeout(async()=>{O(!0);try{let j=(await kA("**/*",{cwd:Q,dot:!1,followSymbolicLinks:!1,onlyFiles:!1,markDirectories:!0,unique:!0,ignore:J})).map((T)=>T.replace(/\\/g,"/"));if(!L)W(j),n8={cwd:Q,ignoreKey:_,files:j,timestamp:B}}catch(b){if(console.error("Failed to load files for @ completion:",b),!L)W([])}finally{if(!L)O(!1)}},G);return()=>{L=!0,clearTimeout(M)}},[$,Q,G,_]);let w=wY(()=>{if(!z.hasQuery||K.length===0)return[];let B=z.query.toLowerCase();if(B==="")return K.slice(0,X);if(q)return new fA(K,{threshold:0.4,ignoreLocation:!0,minMatchCharLength:1}).search(B).slice(0,X).map((M)=>M.item);return K.filter((L)=>L.toLowerCase().includes(B)).slice(0,X)},[z,K,X,q]);return SU(()=>{H(0)},[w]),{...z,suggestions:w,selectedIndex:F,loading:U}}function mA($,Z=!1){if($.includes(" ")||Z)return`@"${$}"`;return`@${$}`}function NY($,Z,Y){if(!Z.hasQuery)return{newInput:$,newCursorPos:$.length};let Q=mA(Y,Z.quoted),X=$.slice(0,Z.startIndex),J=$.slice(Z.endIndex),G=X+Q+" "+J,q=Z.startIndex+Q.length+1;return{newInput:G,newCursorPos:q}}import{useMemoizedFn as fU}from"ahooks";import{useEffect as hU,useRef as xU}from"react";M0();var Q$=($,Z)=>{let Y=xU(!1),Q=xU(null),X=fU(()=>{if(Q.current)clearTimeout(Q.current);Q.current=setTimeout(()=>{R2().setAwaitingSecondCtrlC(!1),Y.current=!1,Q.current=null},3000)}),J=()=>{o4().shutdown("SIGINT",0)},G=fU(()=>{if(!Y.current){if(Y.current=!0,$&&Z)Z();R2().setAwaitingSecondCtrlC(!0),X()}else{if(Q.current)clearTimeout(Q.current),Q.current=null;R2().setAwaitingSecondCtrlC(!1),J()}});return hU(()=>{if($){if(R2().setAwaitingSecondCtrlC(!1),Y.current=!1,Q.current)clearTimeout(Q.current),Q.current=null}},[$]),hU(()=>{return()=>{if(Q.current)clearTimeout(Q.current)}},[]),G};var i6=x("UI"),uU=($,Z,Y,Q,X,J,G,q,K,W)=>{let O=q1()==="main-input",F=$.value,H=$.setValue,_=$.cursorPosition,z=K4(),w=W4(),B=m6(),L=B?C8(B):!1,[N,M]=AY(!1),[b,j]=AY([]),[T,A]=AY(0),k=kU(F,_,{cwd:process.cwd(),maxSuggestions:10}),c=Q$(G||!1,J),o=gU(0),S=500,y=gU(!1);mU(()=>{if(G)y.current=!1},[G]),mU(()=>{if(k.hasQuery&&k.suggestions.length>0){let D=k.suggestions.map((V)=>({command:V,description:LJ(V)?`Directory: ${V}`:`File: ${V}`,matchScore:1}));j(D),M(!0),A(0)}else if(F.startsWith("/"))if(F.includes(" "))M(!1),j([]);else{let V=D6(F);j(V),M(V.length>0),A(0)}else M(!1),j([])},[F,k.hasQuery,k.suggestions]);let l=pU(()=>{z.clearMessages(),z.setError(null)}),I=pU(()=>{i6.debug("[DIAG] handleSubmit called:",{input:F,showSuggestions:N});let D=F.trim();if(D){let V=$.resolveInput(D);i6.debug("[DIAG] Submitting command:",{displayText:D,textLength:V.text.length,imageCount:V.images.length}),M(!1),j([]);let g=$.pasteMap.size>0?new Map($.pasteMap):new Map;X(D,g),$.clear(),Z(V),i6.debug("[DIAG] Command submitted to onSubmit callback")}else i6.debug("[DIAG] Empty command, not submitting")});return gA((D,V)=>{if(D==="?"&&!F){K?.(),setTimeout(()=>$.clear(),0);return}if(V.backspace||V.delete||V.leftArrow||V.rightArrow||V.pageUp||V.pageDown||!V.ctrl&&!V.meta&&!V.escape&&!V.tab&&!V.upArrow&&!V.downArrow&&!V.return&&!(D==="?"&&!F))return;if(V.ctrl&&D==="c"||V.meta&&D==="c"||V.ctrl&&D==="d"||V.meta&&D==="d"){c();return}if(V.ctrl&&D==="l"||V.meta&&D==="l"){l();return}if(V.ctrl&&D==="t"||V.meta&&D==="t"){z.toggleThinkingExpanded();return}if(V.ctrl&&D==="o"||V.meta&&D==="o"){z.toggleHistoryExpanded();return}if(V.escape){if(W)K?.();else if(G&&J){if(y.current)return;y.current=!0,J()}else if(N)M(!1),j([]);else if(F){let u=Date.now();if(u-o.current<500)$.clear(),o.current=0;else o.current=u}return}if(V.tab&&V.shift){q?.();return}if(V.tab){if(N&&b.length>0){let u=b[T].command;if(k.hasQuery&&k.suggestions.includes(u)){let{newInput:v,newCursorPos:Z0}=NY(F,k,u);H(v),$.setCursorPosition(Z0)}else{let v=u+" ";H(v),$.setCursorPosition(v.length)}M(!1),j([])}else if(L)w.toggleThinkingMode();return}if(V.return){if(N&&b.length>0){let u=b[T].command;if(k.hasQuery&&k.suggestions.includes(u)){let{newInput:v,newCursorPos:Z0}=NY(F,k,u);H(v),$.setCursorPosition(Z0)}else{let v=u+" ";H(v),$.setCursorPosition(v.length)}M(!1),j([])}else I();return}if(V.upArrow){if(N&&b.length>0){let u=b.length-1;A((v)=>v>0?v-1:u)}else{let u=Y();if(u){if(u.pasteMappings.size>0)$.restorePasteMappings(u.pasteMappings);H(u.display),$.setCursorPosition(u.display.length)}}return}if(V.downArrow){if(N&&b.length>0){let u=b.length-1;A((v)=>v<u?v+1:0)}else{let u=Q();if(u){if(u.pasteMappings.size>0)$.restorePasteMappings(u.pasteMappings);H(u.display),$.setCursorPosition(u.display.length)}}return}},{isActive:O}),{handleSubmit:I,showSuggestions:N,suggestions:b,selectedSuggestionIndex:T}};import iA from"ansi-escapes";import{useStdout as rA}from"ink";import{useCallback as aA,useEffect as nA,useRef as oA}from"react";import{useStdout as uA}from"ink";import{debounce as dA}from"lodash-es";import{useEffect as cA,useState as lA}from"react";function o8($=200){let{stdout:Z}=uA(),[Y,Q]=lA(Z.columns||80);return cA(()=>{let X=dA(()=>{Q(Z.columns||80)},$);return X(),Z.on("resize",X),()=>{Z.off("resize",X),X.cancel()}},[Z,$]),Y}function dU(){let{stdout:$}=rA(),Z=o8(),Y=oA(!0),Q=w0((J)=>J.session.actions.incrementClearCount),X=aA(()=>{if($)$.write(iA.clearTerminal);Q()},[$,Q]);return nA(()=>{if(Y.current){Y.current=!1;return}let J=setTimeout(()=>{X()},300);return()=>{clearTimeout(J)}},[Z,X]),{refreshStatic:X}}F2();import cU from"node:fs";import sA from"node:os";import bY from"node:path";import{MultiSelect as tA}from"@inkjs/ui";import{useMemoizedFn as r6}from"ahooks";import{Box as q0,Text as $0,useFocus as eA,useFocusManager as $b,useInput as iU}from"ink";import a6 from"ink-select-input";import Zb from"ink-spinner";import q7 from"ink-text-input";import{useEffect as lU,useState as s8}from"react";import{jsxDEV as P}from"react/jsx-dev-runtime";var Yb=[{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"}],Qb=[{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 Xb($){if(!$||$.trim()==="")return"名称不能为空";if(!/^[a-z0-9-]+$/.test($))return"名称只能包含小写字母、数字和连字符";if($.startsWith("-")||$.endsWith("-"))return"名称不能以连字符开头或结尾";return null}function K7({onComplete:$,onCancel:Z,initialConfig:Y}){let[Q,X]=s8(Y?"name":"mode"),[J,G]=s8({name:Y?.name||"",description:Y?.description||"",tools:Y?.tools||[],color:Y?.color,location:Y?.location||"project",systemPrompt:Y?.systemPrompt||""}),[q,K]=s8(""),[W,U]=s8(!1),[O,F]=s8(""),[H,_]=s8(Y?"edit":"manual"),{focus:z}=$b(),B={manual:["mode","name","description","tools","color","location","systemPrompt","confirm"],ai:["mode","aiPrompt","aiGenerating","confirm"],edit:["name","description","tools","color","location","systemPrompt","confirm"]}[H];lU(()=>{if(Q==="name"||Q==="description"||Q==="systemPrompt"||Q==="aiPrompt")return;z(`step-${Q}`)},[Q,z]);let L=r6(()=>{let T=B.indexOf(Q);if(T<B.length-1)X(B[T+1])}),N=r6(()=>{if(O)F("");if(Q==="confirm"&&H==="ai"){X("aiPrompt");return}let T=B.indexOf(Q);if(T>0)X(B[T-1]);else Z()}),M=r6(async()=>{U(!0),F("");try{let T=await G$.create(),A=`你是一个 Subagent 配置生成专家。用户会描述他们想要创建的 agent,你需要根据描述生成一个完整的 agent 配置。
2749
2749
 
2750
2750
  ## 可用工具列表
2751
2751
 
@@ -2819,35 +2819,35 @@ ${Z0}
2819
2819
  4. **color**: 选择一个合适的颜色用于 UI 区分
2820
2820
  5. **systemPrompt**: 详细说明 agent 的职责、使用的工具、输出格式等,使用 Markdown 格式
2821
2821
 
2822
- **重要**:请直接返回 JSON,不要添加任何额外的解释或文字。`,q)).trim(),o=c.match(/```(?:json)?\s*\n([\s\S]*?)\n```/);if(o)c=o[1];let S=JSON.parse(c);if(!S.name||!S.description||!S.systemPrompt)throw Error("Missing required fields: name, description, or systemPrompt");if(!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(S.name))throw Error("Invalid name format. Must be kebab-case (lowercase, numbers, hyphens only)");G({name:S.name,description:S.description,tools:Array.isArray(S.tools)?S.tools:[],color:S.color||"blue",location:"project",systemPrompt:S.systemPrompt}),X("confirm")}catch(T){F(T instanceof Error?T.message:String(T))}finally{U(!1)}});lU(()=>{if(Q==="aiGenerating"&&!W&&!O)M()},[Q,W,O,M]);let b=r7(async()=>{try{let T=J.location==="project"?bY.join(process.cwd(),".blade","agents"):bY.join(sA.homedir(),".blade","agents");await cU.promises.mkdir(T,{recursive:!0});let A=["---",`name: ${J.name}`,`description: ${J.description}`];if(J.tools.length>0&&!J.tools.includes("all")){A.push("tools:");for(let o of J.tools)A.push(` - ${o}`)}if(J.color)A.push(`color: ${J.color}`);A.push("---");let k=[A.join(`
2822
+ **重要**:请直接返回 JSON,不要添加任何额外的解释或文字。`,q)).trim(),o=c.match(/```(?:json)?\s*\n([\s\S]*?)\n```/);if(o)c=o[1];let S=JSON.parse(c);if(!S.name||!S.description||!S.systemPrompt)throw Error("Missing required fields: name, description, or systemPrompt");if(!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(S.name))throw Error("Invalid name format. Must be kebab-case (lowercase, numbers, hyphens only)");G({name:S.name,description:S.description,tools:Array.isArray(S.tools)?S.tools:[],color:S.color||"blue",location:"project",systemPrompt:S.systemPrompt}),X("confirm")}catch(T){F(T instanceof Error?T.message:String(T))}finally{U(!1)}});lU(()=>{if(Q==="aiGenerating"&&!W&&!O)M()},[Q,W,O,M]);let b=r6(async()=>{try{let T=J.location==="project"?bY.join(process.cwd(),".blade","agents"):bY.join(sA.homedir(),".blade","agents");await cU.promises.mkdir(T,{recursive:!0});let A=["---",`name: ${J.name}`,`description: ${J.description}`];if(J.tools.length>0&&!J.tools.includes("all")){A.push("tools:");for(let o of J.tools)A.push(` - ${o}`)}if(J.color)A.push(`color: ${J.color}`);A.push("---");let k=[A.join(`
2823
2823
  `),"",`# ${J.name} Subagent`,"",J.systemPrompt||"你是一个专门的代理,负责执行特定任务。",""].join(`
2824
- `),c=bY.join(T,`${J.name}.md`);await cU.promises.writeFile(c,k,"utf-8"),$()}catch(T){console.error("保存配置失败:",T)}}),j=Q$(!1,Z);if(iU((T,A)=>{if(A.escape)N();else if(A.ctrl&&T==="c"||A.meta&&T==="c")j()},{isActive:Q!=="tools"}),Q==="mode")return P(q0,{flexDirection:"column",paddingY:1,children:[P(q0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83C\uDFAF 选择创建方式"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{dimColor:!0,children:"你可以手动配置每个细节,或让 AI 根据你的描述自动生成配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(a7,{items:[{label:"\uD83E\uDD16 AI 智能生成 - 根据描述自动生成完整配置",value:"ai"},{label:"✍️ 手动配置 - 逐步配置每个选项",value:"manual"}],onSelect:(T)=>{if(T.value==="ai")_("ai"),X("aiPrompt");else _("manual"),X("name")}},void 0,!1,void 0,this),P(q0,{marginTop:1,children:P($0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 取消"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="aiPrompt")return P(q0,{flexDirection:"column",paddingY:1,children:[P(q0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83E\uDD16 AI 智能生成"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{dimColor:!0,children:'描述你想要创建的 Agent(例如:"一个专门用于代码审查的 agent,能够分析代码质量和潜在bug")'},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:[P($0,{color:"green",children:"描述: "},void 0,!1,void 0,this),P(q6,{value:q,onChange:K,onSubmit:(T)=>{if(!T.trim())return;X("aiGenerating")}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(q0,{children:P($0,{dimColor:!0,children:"按 Enter 开始生成 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="aiGenerating"){if(O)return P(q0,{flexDirection:"column",paddingY:1,children:[P(q0,{marginBottom:1,children:P($0,{bold:!0,color:"red",children:"❌ AI 生成失败"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{color:"red",children:O},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{dimColor:!0,children:"按 ESC 返回修改描述"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return P(q0,{flexDirection:"column",paddingY:1,children:[P(q0,{marginBottom:1,children:P($0,{bold:!0,color:"yellow",children:[P(Zb,{type:"dots"},void 0,!1,void 0,this)," AI 正在生成配置..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{dimColor:!0,children:['根据你的描述:"',q,'"']},void 0,!0,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{color:"gray",children:"正在调用 LLM 生成 agent 配置,请稍候..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}if(Q==="name"){let T=H==="edit";return P(q0,{flexDirection:"column",paddingY:1,children:[P(q0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:["\uD83D\uDCDD Step 1/7: ",T?"Agent 名称(不可修改)":"输入 Agent 名称"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{dimColor:!0,children:T?"编辑模式下名称不可修改(修改名称相当于创建新 Agent)":"名称只能包含小写字母、数字和连字符(例如:code-reviewer)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:[P($0,{color:"green",children:"名称: "},void 0,!1,void 0,this),T?P($0,{children:J.name},void 0,!1,void 0,this):P(q6,{value:J.name,onChange:(A)=>G({...J,name:A}),onSubmit:(A)=>{if(Xb(A))return;L()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(q0,{children:P($0,{dimColor:!0,children:T?"按 Enter 继续 | ESC 返回":"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this),T&&P(q6,{value:"",onChange:()=>{},onSubmit:L,showCursor:!1},"edit-mode-dummy-input",!1,void 0,this)]},void 0,!0,void 0,this)}if(Q==="description")return P(q0,{flexDirection:"column",paddingY:1,children:[P(q0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83D\uDCDD Step 2/7: 输入描述信息"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{dimColor:!0,children:"简短描述这个 Agent 的用途和使用场景(这将帮助主 Agent 决定何时使用它)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:[P($0,{color:"green",children:"描述: "},void 0,!1,void 0,this),P(q6,{value:J.description,onChange:(T)=>G({...J,description:T}),onSubmit:(T)=>{if(!T.trim())return;L()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(q0,{children:P($0,{dimColor:!0,children:"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="tools")return P(Jb,{config:J,setConfig:G,onNext:L,onPrev:N},void 0,!1,void 0,this);if(Q==="color")return P(q0,{flexDirection:"column",paddingY:1,children:[P(q0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83C\uDFA8 Step 4/7: 选择背景颜色"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{dimColor:!0,children:"为 Agent 选择一个颜色标识(用于在 UI 中区分不同的 Agents)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(a7,{items:Qb,onSelect:(T)=>{let A=T.value==="none"?void 0:T.value;G({...J,color:A}),L()}},void 0,!1,void 0,this),P(q0,{marginTop:1,children:P($0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="location")return P(q0,{flexDirection:"column",paddingY:1,children:[P(q0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83D\uDCC2 Step 5/7: 选择保存位置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{dimColor:!0,children:"项目级配置仅在当前项目生效,用户级配置全局可用"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(a7,{items:[{label:"\uD83D\uDCC1 项目级 (.blade/agents/) - 仅当前项目",value:"project"},{label:"\uD83C\uDFE0 用户级 (~/.blade/agents/) - 全局可用",value:"user"}],onSelect:(T)=>{G({...J,location:T.value}),L()}},void 0,!1,void 0,this),P(q0,{marginTop:1,children:P($0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="systemPrompt")return P(q0,{flexDirection:"column",paddingY:1,children:[P(q0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83D\uDCAC Step 6/7: 输入系统提示词"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{dimColor:!0,children:"定义 Agent 的行为和职责(可选,留空将使用默认提示)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:[P($0,{color:"green",children:"提示词: "},void 0,!1,void 0,this),P(q6,{value:J.systemPrompt,onChange:(T)=>G({...J,systemPrompt:T}),onSubmit:()=>L()},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(q0,{children:P($0,{dimColor:!0,children:"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="confirm")return P(q0,{flexDirection:"column",paddingY:1,children:[P(q0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"✅ Step 7/7: 确认配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{flexDirection:"column",paddingLeft:2,marginBottom:1,children:[P($0,{children:[P($0,{bold:!0,color:"green",children:["名称:"," "]},void 0,!0,void 0,this),P($0,{children:J.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P($0,{children:[P($0,{bold:!0,color:"green",children:["描述:"," "]},void 0,!0,void 0,this),P($0,{children:J.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P($0,{children:[P($0,{bold:!0,color:"green",children:["工具:"," "]},void 0,!0,void 0,this),P($0,{children:J.tools.includes("all")?"所有工具":J.tools.join(", ")||"所有工具"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P($0,{children:[P($0,{bold:!0,color:"green",children:["颜色:"," "]},void 0,!0,void 0,this),P($0,{children:J.color||"默认"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P($0,{children:[P($0,{bold:!0,color:"green",children:["位置:"," "]},void 0,!0,void 0,this),P($0,{children:J.location==="project"?"项目级":"用户级"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P($0,{children:[P($0,{bold:!0,color:"green",children:["提示词:"," "]},void 0,!0,void 0,this),P($0,{children:J.systemPrompt||"(使用默认)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),P(a7,{items:[{label:"✅ 确认并保存",value:"save"},{label:"⬅️ 返回上一步",value:"back"},{label:"❌ 取消",value:"cancel"}],onSelect:(T)=>{if(T.value==="save")b();else if(T.value==="back")N();else Z()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}function Jb({config:$,setConfig:Z,onNext:Y,onPrev:Q}){let{isFocused:X}=eA({id:"step-tools"});iU((G,q)=>{if(q.escape)Q()},{isActive:X});let J=(G)=>{if(G.includes("all"))Z({...$,tools:["all"]});else Z({...$,tools:G});Y()};return P(q0,{flexDirection:"column",paddingY:1,children:[P(q0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83D\uDD27 Step 3/7: 选择可用工具"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{dimColor:!0,children:"方向键导航,空格切换勾选,Enter 确认进入下一步 | ESC 返回上一步"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(tA,{options:Yb,defaultValue:$.tools,onSubmit:J},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}m4();import Gb from"node:fs";import{useMemoizedFn as e4}from"ahooks";import{Box as c0,Text as n0,useInput as qb}from"ink";import RY from"ink-select-input";import{useEffect as Kb,useMemo as rU,useState as n7}from"react";import{jsxDEV as t}from"react/jsx-dev-runtime";var VY=10;function aU({initialMode:$="menu",onComplete:Z,onCancel:Y}){let[Q,X]=n7($),[J,G]=n7(null),[q,K]=n7(0),[W,U]=n7(0),O=e4(()=>{Y$.clear(),Y$.loadFromStandardLocations(),K((A)=>A+1)}),F=rU(()=>{return Y$.getAllSubagents()},[q]),H=Math.ceil(F.length/VY)||1,_=rU(()=>{let A=W*VY;return F.slice(A,A+VY)},[F,W]);Kb(()=>{let A=Math.max(0,H-1);if(W>A)U(A)},[H,W]);let z=e4(()=>{if(W<H-1)U((A)=>A+1)}),w=e4(()=>{if(W>0)U((A)=>A-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((A)=>{if(A.value==="cancel"){Y?.();return}X(A.value)}),N=e4((A)=>{if(G(A.value),Q==="edit")X("editWizard");else if(Q==="delete")X("deleteConfirm")}),M=e4(async()=>{if(!J?.configPath)return;try{await Gb.promises.unlink(J.configPath),O(),b()}catch(A){console.error("删除失败:",A)}}),b=e4(()=>{X("menu"),G(null)}),j=Q$(!1,Y);if(qb((A,k)=>{if(k.escape){if(Q==="menu")Y?.();else if(Q==="list"||Q==="edit"||Q==="delete")U(0),b();else if(Q==="deleteConfirm")b()}else if(k.ctrl&&A==="c"||k.meta&&A==="c")j();else if(Q==="list"){if(k.leftArrow||A==="h")w();else if(k.rightArrow||A==="l")z()}},{isActive:Q!=="create"&&Q!=="editWizard"}),Q==="menu")return t(c0,{flexDirection:"column",paddingY:1,children:[t(c0,{marginBottom:1,children:t(n0,{bold:!0,color:"cyan",children:"\uD83D\uDCCB Agents 管理"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(RY,{items:B,onSelect:L},void 0,!1,void 0,this),t(c0,{marginTop:1,children:t(n0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 退出"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="list"){if(F.length===0)return t(c0,{flexDirection:"column",paddingY:1,children:[t(c0,{marginBottom:1,children:t(n0,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(c0,{paddingLeft:2,children:t(n0,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(c0,{marginTop:1,paddingLeft:2,children:t(n0,{color:"gray",children:"\uD83D\uDCA1 配置文件位置: .blade/agents/ 或 ~/.blade/agents/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(c0,{marginTop:1,paddingLeft:2,children:t(n0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return t(c0,{flexDirection:"column",paddingY:1,children:[t(c0,{marginBottom:1,children:[t(n0,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this),t(n0,{color:"gray",children:[" (共 ",F.length," 个)"]},void 0,!0,void 0,this),H>1&&t(n0,{color:"yellow",children:[" ","第 ",W+1,"/",H," 页"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),_.map((A)=>t(c0,{flexDirection:"column",paddingLeft:2,children:[t(c0,{children:t(n0,{children:[t(n0,{bold:!0,color:A.color||"white",children:["• ",A.name]},void 0,!0,void 0,this),t(n0,{color:"gray",children:[" - ",A.description]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),A.tools&&A.tools.length>0&&t(c0,{paddingLeft:2,children:t(n0,{color:"gray",children:["工具: ",A.tools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),A.configPath&&t(c0,{paddingLeft:2,children:t(n0,{color:"gray",dimColor:!0,children:A.configPath},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},A.name,!0,void 0,this)),t(c0,{marginTop:1,paddingLeft:2,children:H>1?t(n0,{dimColor:!0,children:"← → 翻页 | ESC 返回菜单"},void 0,!1,void 0,this):t(n0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}let T=(A)=>{if(F.length===0)return t(c0,{flexDirection:"column",paddingY:1,children:[t(c0,{marginBottom:1,children:t(n0,{bold:!0,color:"cyan",children:A},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(c0,{paddingLeft:2,children:t(n0,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(c0,{marginTop:1,paddingLeft:2,children:t(n0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);let k=F.map((c)=>({key:c.name,label:`${c.name} - ${c.description}`,value:c}));return t(c0,{flexDirection:"column",paddingY:1,children:[t(c0,{marginBottom:1,children:t(n0,{bold:!0,color:"cyan",children:A},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(RY,{items:k,onSelect:N},void 0,!1,void 0,this),t(c0,{marginTop:1,children:t(n0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};if(Q==="create")return t(K6,{onComplete:()=>{O(),b()},onCancel:b},void 0,!1,void 0,this);if(Q==="edit")return T("✏️ 编辑 Agent");if(Q==="editWizard"&&J){let A={name:J.name,description:J.description,tools:J.tools||[],color:J.color,location:J.configPath?.includes(".blade/agents")?"project":"user",systemPrompt:J.systemPrompt||""};return t(K6,{initialConfig:A,onComplete:()=>{O(),b()},onCancel:b},void 0,!1,void 0,this)}if(Q==="delete")return T("\uD83D\uDDD1️ 删除 Agent");if(Q==="deleteConfirm"&&J)return t(c0,{flexDirection:"column",paddingY:1,children:[t(c0,{marginBottom:1,children:t(n0,{bold:!0,color:"red",children:"⚠️ 确认删除"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(c0,{marginBottom:1,paddingLeft:2,children:t(n0,{children:["你确定要删除 Agent"," ",t(n0,{bold:!0,color:"yellow",children:J.name},void 0,!1,void 0,this)," ","吗?"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),t(c0,{marginBottom:1,paddingLeft:2,children:t(n0,{dimColor:!0,children:["文件路径: ",J.configPath]},void 0,!0,void 0,this)},void 0,!1,void 0,this),t(c0,{marginBottom:1,paddingLeft:2,children:t(n0,{color:"red",children:"此操作无法撤销!"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(RY,{items:[{label:"\uD83D\uDDD1️ 确认删除",value:"confirm"},{label:"❌ 取消",value:"cancel"}],onSelect:(A)=>{if(A.value==="confirm")M();else b()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}U$();import{Box as t8,Text as o0}from"ink";import Ub from"react";H7();ZY();import{useEffect as Wb,useState as nU}from"react";function oU($=process.cwd(),Z=5000){let[Y,Q]=nU(null),[X,J]=nU(!0);return Wb(()=>{let G=!0,q=async()=>{try{let W=await a3($);if(!G)return;if(!W){Q(null),J(!1);return}let U=await jK($);if(!G)return;Q(U)}catch{if(G)Q(null)}finally{if(G)J(!1)}};q();let K=null;if(Z>0)K=setInterval(q,Z);return()=>{if(G=!1,K)clearInterval(K)}},[$,Z]),{branch:Y,loading:X}}import{jsxDEV as V0,Fragment as o7}from"react/jsx-dev-runtime";var sU=Ub.memo(()=>{let $=p7(),Z=a8(),Q=x7()==="shortcuts",X=KU(),{branch:J}=oU(),G=m7(),q=YU(),K=ZU(),W=g7(),U=RU(),O=G?C8(G):!1,H=(()=>{if(Z==="default")return null;if(Z==="autoEdit")return V0(o0,{color:"magenta",children:["▶▶ auto edit on ",V0(o0,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="plan")return V0(o0,{color:"cyan",children:["‖ plan mode on ",V0(o0,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="yolo")return V0(o0,{color:"red",children:["⚡ yolo mode on ",V0(o0,{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,N;if(!w)N="init";else if((w==="tasks"||w==="implementation")&&L>0)N=`${w} ${B}/${L}`;else N=w;return V0(o0,{color:"blue",children:["\uD83D\uDCCB spec: ",N," ",V0(o0,{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 V0(t8,{flexDirection:"row",justifyContent:"space-between",paddingX:2,paddingY:0,children:[Q?V0(t8,{flexDirection:"column",gap:0,children:z.map((w,B)=>V0(t8,{flexDirection:"row",children:[w.map((L,N)=>{let[M,b]=L.split(":");return V0(t8,{flexDirection:"row",width:20,children:[V0(o0,{color:"yellow",children:M},void 0,!1,void 0,this),V0(o0,{color:"gray",children:":"},void 0,!1,void 0,this),V0(o0,{color:"white",children:b},void 0,!1,void 0,this)]},N,!0,void 0,this)}),B===z.length-1&&V0(o0,{color:"cyan",children:" ? 关闭"},void 0,!1,void 0,this)]},B,!0,void 0,this))},void 0,!1,void 0,this):V0(t8,{flexDirection:"row",gap:1,children:[J&&V0(o7,{children:[V0(o0,{color:"gray",children:[" ",J]},void 0,!0,void 0,this),V0(o0,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H,_&&V0(o0,{color:"gray",children:"·"},void 0,!1,void 0,this),V0(o0,{color:"gray",children:"? for shortcuts"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),V0(t8,{flexDirection:"row",gap:1,children:!$?V0(o0,{color:"red",children:"⚠ API 密钥未配置"},void 0,!1,void 0,this):V0(o7,{children:[O&&V0(o7,{children:[W?V0(o0,{color:"cyan",children:"Thinking on"},void 0,!1,void 0,this):V0(o0,{color:"gray",children:"Tab:Thinking"},void 0,!1,void 0,this),V0(o0,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G&&V0(o0,{color:"gray",children:G.model},void 0,!1,void 0,this),V0(o0,{color:"gray",children:"·"},void 0,!1,void 0,this),K?V0(o0,{color:"yellow",children:"压缩中..."},void 0,!1,void 0,this):V0(o0,{color:q<20?"red":q<50?"yellow":"gray",children:[q,"%"]},void 0,!0,void 0,this),X&&V0(o7,{children:[V0(o0,{color:"gray",children:"·"},void 0,!1,void 0,this),V0(o0,{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 MY,Text as DY}from"ink";import Ob from"react";import{jsxDEV as e8}from"react/jsx-dev-runtime";var tU=Ob.memo(({suggestions:$,selectedIndex:Z,visible:Y,maxDisplay:Q=8})=>{if(!Y||$.length===0)return null;let X=0,J=Math.min(Q,$.length),G=Z>=$.length;if(Z>=Q&&!G)X=Z-Q+1,J=Z+1;let q=$.slice(X,J),K=$.length>Q;return e8(MY,{flexDirection:"column",paddingX:2,paddingY:0,children:[q.map((W,U)=>{let F=X+U===Z;return e8(MY,{flexDirection:"row",paddingX:1,gap:2,children:[e8(DY,{color:F?"cyan":"white",bold:F,children:W.command},void 0,!1,void 0,this),e8(DY,{color:F?"cyan":"gray",dimColor:!F,children:["- ",W.description]},void 0,!0,void 0,this)]},W.command,!0,void 0,this)}),K&&e8(MY,{paddingX:1,children:e8(DY,{color:G?"cyan":"gray",bold:G,dimColor:!G,children:["... and ",$.length-Q," more"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});U$();import{Box as S1,Text as $2,useInput as pb,useStdout as mb}from"ink";import gb from"ink-select-input";import mY,{useMemo as UO}from"react";import{Box as L0,Text as S0}from"ink";import Q8,{useEffect as pY,useMemo as Y8,useRef as WO}from"react";W3();T5();import{Box as t7,Text as z2}from"ink";import{isPlainObject as IY}from"lodash-es";import{common as Bb,createLowlight as wb}from"lowlight";import QO from"react";V4();import{Box as s7,Text as W6}from"ink";import T2,{Fragment as ZO}from"react";import Fb from"string-width";var eU=new Map,$O=1000;function yY($){let Z=!0;for(let Q=0;Q<$.length;Q++)if($.charCodeAt(Q)>127){Z=!1;break}if(Z)return $.split("");if($.length<=$O){let Q=eU.get($);if(Q)return Q}let Y=Array.from($);if($.length<=$O)eU.set($,Y);return Y}var jY=new Map;function y2($){if(/^[\x20-\x7E]*$/.test($))return $.length;if(jY.has($))return jY.get($);let Z=Fb($);return jY.set($,Z),Z}import{jsxDEV as $3}from"react/jsx-dev-runtime";var TY=2,YO=T2.memo(({children:$,maxWidth:Z,maxHeight:Y,overflowDirection:Q="top",additionalHiddenLinesCount:X=0})=>{let J=d0(),G=[],q=Math.max(Math.round(Y??Number.MAX_SAFE_INTEGER),TY);function K(z){if(!T2.isValidElement(z))return;if(z.type===ZO){T2.Children.forEach(z.props.children,K);return}if(z.type===s7){_b(z,Z,G);return}}T2.Children.forEach($,K);let U=G.length>q||X>0?q-1:q,O=U!==void 0?Math.max(0,G.length-U):0,F=O+X,_=(O>0?Q==="top"?G.slice(O):G.slice(0,U):G).map((z,w)=>$3(s7,{children:z.length>0?z.map((B,L)=>$3(W6,{...B.props,children:B.text},L,!1,void 0,this)):$3(W6,{children:" "},void 0,!1,void 0,this)},w,!1,void 0,this));return $3(s7,{flexDirection:"column",width:Z,flexShrink:0,children:[F>0&&Q==="top"&&$3(W6,{color:J.colors.text.muted,dimColor:!0,children:["... ",F," line",F===1?"":"s"," hidden ..."]},void 0,!0,void 0,this),_,F>0&&Q==="bottom"&&$3(W6,{color:J.colors.text.muted,dimColor:!0,children:["... ",F," line",F===1?"":"s"," hidden ..."]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});function Hb($){if(!T2.isValidElement($)||$.type!==s7)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(!T2.isValidElement(X))return;if(X.type===ZO){T2.Children.forEach(X.props.children,(W)=>Q(W,J));return}if(X.type!==W6)return;let{children:G,...q}=X.props,K=J===void 0?q:{...J,...q};T2.Children.forEach(G,(W)=>Q(W,K))}return T2.Children.forEach($.props.children,(X)=>Q(X,void 0)),Z}function _b($,Z,Y){let Q=Hb($);if(Q.segments.length===0&&Q.noWrapSegments.length===0){Y.push([]);return}let X=0;for(let O of Q.noWrapSegments)X+=y2(O.text);if(Q.segments.length===0){let O=[],F=[];for(let H of Q.noWrapSegments){let _=H.text.split(`
2824
+ `),c=bY.join(T,`${J.name}.md`);await cU.promises.writeFile(c,k,"utf-8"),$()}catch(T){console.error("保存配置失败:",T)}}),j=Q$(!1,Z);if(iU((T,A)=>{if(A.escape)N();else if(A.ctrl&&T==="c"||A.meta&&T==="c")j()},{isActive:Q!=="tools"}),Q==="mode")return P(q0,{flexDirection:"column",paddingY:1,children:[P(q0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83C\uDFAF 选择创建方式"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{dimColor:!0,children:"你可以手动配置每个细节,或让 AI 根据你的描述自动生成配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(a6,{items:[{label:"\uD83E\uDD16 AI 智能生成 - 根据描述自动生成完整配置",value:"ai"},{label:"✍️ 手动配置 - 逐步配置每个选项",value:"manual"}],onSelect:(T)=>{if(T.value==="ai")_("ai"),X("aiPrompt");else _("manual"),X("name")}},void 0,!1,void 0,this),P(q0,{marginTop:1,children:P($0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 取消"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="aiPrompt")return P(q0,{flexDirection:"column",paddingY:1,children:[P(q0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83E\uDD16 AI 智能生成"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{dimColor:!0,children:'描述你想要创建的 Agent(例如:"一个专门用于代码审查的 agent,能够分析代码质量和潜在bug")'},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:[P($0,{color:"green",children:"描述: "},void 0,!1,void 0,this),P(q7,{value:q,onChange:K,onSubmit:(T)=>{if(!T.trim())return;X("aiGenerating")}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(q0,{children:P($0,{dimColor:!0,children:"按 Enter 开始生成 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="aiGenerating"){if(O)return P(q0,{flexDirection:"column",paddingY:1,children:[P(q0,{marginBottom:1,children:P($0,{bold:!0,color:"red",children:"❌ AI 生成失败"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{color:"red",children:O},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{dimColor:!0,children:"按 ESC 返回修改描述"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return P(q0,{flexDirection:"column",paddingY:1,children:[P(q0,{marginBottom:1,children:P($0,{bold:!0,color:"yellow",children:[P(Zb,{type:"dots"},void 0,!1,void 0,this)," AI 正在生成配置..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{dimColor:!0,children:['根据你的描述:"',q,'"']},void 0,!0,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{color:"gray",children:"正在调用 LLM 生成 agent 配置,请稍候..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}if(Q==="name"){let T=H==="edit";return P(q0,{flexDirection:"column",paddingY:1,children:[P(q0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:["\uD83D\uDCDD Step 1/7: ",T?"Agent 名称(不可修改)":"输入 Agent 名称"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{dimColor:!0,children:T?"编辑模式下名称不可修改(修改名称相当于创建新 Agent)":"名称只能包含小写字母、数字和连字符(例如:code-reviewer)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:[P($0,{color:"green",children:"名称: "},void 0,!1,void 0,this),T?P($0,{children:J.name},void 0,!1,void 0,this):P(q7,{value:J.name,onChange:(A)=>G({...J,name:A}),onSubmit:(A)=>{if(Xb(A))return;L()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(q0,{children:P($0,{dimColor:!0,children:T?"按 Enter 继续 | ESC 返回":"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this),T&&P(q7,{value:"",onChange:()=>{},onSubmit:L,showCursor:!1},"edit-mode-dummy-input",!1,void 0,this)]},void 0,!0,void 0,this)}if(Q==="description")return P(q0,{flexDirection:"column",paddingY:1,children:[P(q0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83D\uDCDD Step 2/7: 输入描述信息"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{dimColor:!0,children:"简短描述这个 Agent 的用途和使用场景(这将帮助主 Agent 决定何时使用它)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:[P($0,{color:"green",children:"描述: "},void 0,!1,void 0,this),P(q7,{value:J.description,onChange:(T)=>G({...J,description:T}),onSubmit:(T)=>{if(!T.trim())return;L()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(q0,{children:P($0,{dimColor:!0,children:"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="tools")return P(Jb,{config:J,setConfig:G,onNext:L,onPrev:N},void 0,!1,void 0,this);if(Q==="color")return P(q0,{flexDirection:"column",paddingY:1,children:[P(q0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83C\uDFA8 Step 4/7: 选择背景颜色"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{dimColor:!0,children:"为 Agent 选择一个颜色标识(用于在 UI 中区分不同的 Agents)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(a6,{items:Qb,onSelect:(T)=>{let A=T.value==="none"?void 0:T.value;G({...J,color:A}),L()}},void 0,!1,void 0,this),P(q0,{marginTop:1,children:P($0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="location")return P(q0,{flexDirection:"column",paddingY:1,children:[P(q0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83D\uDCC2 Step 5/7: 选择保存位置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{dimColor:!0,children:"项目级配置仅在当前项目生效,用户级配置全局可用"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(a6,{items:[{label:"\uD83D\uDCC1 项目级 (.blade/agents/) - 仅当前项目",value:"project"},{label:"\uD83C\uDFE0 用户级 (~/.blade/agents/) - 全局可用",value:"user"}],onSelect:(T)=>{G({...J,location:T.value}),L()}},void 0,!1,void 0,this),P(q0,{marginTop:1,children:P($0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="systemPrompt")return P(q0,{flexDirection:"column",paddingY:1,children:[P(q0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83D\uDCAC Step 6/7: 输入系统提示词"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{dimColor:!0,children:"定义 Agent 的行为和职责(可选,留空将使用默认提示)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:[P($0,{color:"green",children:"提示词: "},void 0,!1,void 0,this),P(q7,{value:J.systemPrompt,onChange:(T)=>G({...J,systemPrompt:T}),onSubmit:()=>L()},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P(q0,{children:P($0,{dimColor:!0,children:"按 Enter 继续 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="confirm")return P(q0,{flexDirection:"column",paddingY:1,children:[P(q0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"✅ Step 7/7: 确认配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{flexDirection:"column",paddingLeft:2,marginBottom:1,children:[P($0,{children:[P($0,{bold:!0,color:"green",children:["名称:"," "]},void 0,!0,void 0,this),P($0,{children:J.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P($0,{children:[P($0,{bold:!0,color:"green",children:["描述:"," "]},void 0,!0,void 0,this),P($0,{children:J.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P($0,{children:[P($0,{bold:!0,color:"green",children:["工具:"," "]},void 0,!0,void 0,this),P($0,{children:J.tools.includes("all")?"所有工具":J.tools.join(", ")||"所有工具"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P($0,{children:[P($0,{bold:!0,color:"green",children:["颜色:"," "]},void 0,!0,void 0,this),P($0,{children:J.color||"默认"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P($0,{children:[P($0,{bold:!0,color:"green",children:["位置:"," "]},void 0,!0,void 0,this),P($0,{children:J.location==="project"?"项目级":"用户级"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),P($0,{children:[P($0,{bold:!0,color:"green",children:["提示词:"," "]},void 0,!0,void 0,this),P($0,{children:J.systemPrompt||"(使用默认)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),P(a6,{items:[{label:"✅ 确认并保存",value:"save"},{label:"⬅️ 返回上一步",value:"back"},{label:"❌ 取消",value:"cancel"}],onSelect:(T)=>{if(T.value==="save")b();else if(T.value==="back")N();else Z()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}function Jb({config:$,setConfig:Z,onNext:Y,onPrev:Q}){let{isFocused:X}=eA({id:"step-tools"});iU((G,q)=>{if(q.escape)Q()},{isActive:X});let J=(G)=>{if(G.includes("all"))Z({...$,tools:["all"]});else Z({...$,tools:G});Y()};return P(q0,{flexDirection:"column",paddingY:1,children:[P(q0,{marginBottom:1,children:P($0,{bold:!0,color:"cyan",children:"\uD83D\uDD27 Step 3/7: 选择可用工具"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(q0,{marginBottom:1,children:P($0,{dimColor:!0,children:"方向键导航,空格切换勾选,Enter 确认进入下一步 | ESC 返回上一步"},void 0,!1,void 0,this)},void 0,!1,void 0,this),P(tA,{options:Yb,defaultValue:$.tools,onSubmit:J},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}m4();import Gb from"node:fs";import{useMemoizedFn as e4}from"ahooks";import{Box as c0,Text as n0,useInput as qb}from"ink";import RY from"ink-select-input";import{useEffect as Kb,useMemo as rU,useState as n6}from"react";import{jsxDEV as t}from"react/jsx-dev-runtime";var VY=10;function aU({initialMode:$="menu",onComplete:Z,onCancel:Y}){let[Q,X]=n6($),[J,G]=n6(null),[q,K]=n6(0),[W,U]=n6(0),O=e4(()=>{Y$.clear(),Y$.loadFromStandardLocations(),K((A)=>A+1)}),F=rU(()=>{return Y$.getAllSubagents()},[q]),H=Math.ceil(F.length/VY)||1,_=rU(()=>{let A=W*VY;return F.slice(A,A+VY)},[F,W]);Kb(()=>{let A=Math.max(0,H-1);if(W>A)U(A)},[H,W]);let z=e4(()=>{if(W<H-1)U((A)=>A+1)}),w=e4(()=>{if(W>0)U((A)=>A-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((A)=>{if(A.value==="cancel"){Y?.();return}X(A.value)}),N=e4((A)=>{if(G(A.value),Q==="edit")X("editWizard");else if(Q==="delete")X("deleteConfirm")}),M=e4(async()=>{if(!J?.configPath)return;try{await Gb.promises.unlink(J.configPath),O(),b()}catch(A){console.error("删除失败:",A)}}),b=e4(()=>{X("menu"),G(null)}),j=Q$(!1,Y);if(qb((A,k)=>{if(k.escape){if(Q==="menu")Y?.();else if(Q==="list"||Q==="edit"||Q==="delete")U(0),b();else if(Q==="deleteConfirm")b()}else if(k.ctrl&&A==="c"||k.meta&&A==="c")j();else if(Q==="list"){if(k.leftArrow||A==="h")w();else if(k.rightArrow||A==="l")z()}},{isActive:Q!=="create"&&Q!=="editWizard"}),Q==="menu")return t(c0,{flexDirection:"column",paddingY:1,children:[t(c0,{marginBottom:1,children:t(n0,{bold:!0,color:"cyan",children:"\uD83D\uDCCB Agents 管理"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(RY,{items:B,onSelect:L},void 0,!1,void 0,this),t(c0,{marginTop:1,children:t(n0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 退出"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Q==="list"){if(F.length===0)return t(c0,{flexDirection:"column",paddingY:1,children:[t(c0,{marginBottom:1,children:t(n0,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(c0,{paddingLeft:2,children:t(n0,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(c0,{marginTop:1,paddingLeft:2,children:t(n0,{color:"gray",children:"\uD83D\uDCA1 配置文件位置: .blade/agents/ 或 ~/.blade/agents/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(c0,{marginTop:1,paddingLeft:2,children:t(n0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return t(c0,{flexDirection:"column",paddingY:1,children:[t(c0,{marginBottom:1,children:[t(n0,{bold:!0,color:"cyan",children:"\uD83D\uDCCB 所有 Agents"},void 0,!1,void 0,this),t(n0,{color:"gray",children:[" (共 ",F.length," 个)"]},void 0,!0,void 0,this),H>1&&t(n0,{color:"yellow",children:[" ","第 ",W+1,"/",H," 页"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),_.map((A)=>t(c0,{flexDirection:"column",paddingLeft:2,children:[t(c0,{children:t(n0,{children:[t(n0,{bold:!0,color:A.color||"white",children:["• ",A.name]},void 0,!0,void 0,this),t(n0,{color:"gray",children:[" - ",A.description]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),A.tools&&A.tools.length>0&&t(c0,{paddingLeft:2,children:t(n0,{color:"gray",children:["工具: ",A.tools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),A.configPath&&t(c0,{paddingLeft:2,children:t(n0,{color:"gray",dimColor:!0,children:A.configPath},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},A.name,!0,void 0,this)),t(c0,{marginTop:1,paddingLeft:2,children:H>1?t(n0,{dimColor:!0,children:"← → 翻页 | ESC 返回菜单"},void 0,!1,void 0,this):t(n0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}let T=(A)=>{if(F.length===0)return t(c0,{flexDirection:"column",paddingY:1,children:[t(c0,{marginBottom:1,children:t(n0,{bold:!0,color:"cyan",children:A},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(c0,{paddingLeft:2,children:t(n0,{color:"gray",children:"❌ 没有找到任何 agent 配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(c0,{marginTop:1,paddingLeft:2,children:t(n0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);let k=F.map((c)=>({key:c.name,label:`${c.name} - ${c.description}`,value:c}));return t(c0,{flexDirection:"column",paddingY:1,children:[t(c0,{marginBottom:1,children:t(n0,{bold:!0,color:"cyan",children:A},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(RY,{items:k,onSelect:N},void 0,!1,void 0,this),t(c0,{marginTop:1,children:t(n0,{dimColor:!0,children:"使用方向键选择 | Enter 确认 | ESC 返回"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};if(Q==="create")return t(K7,{onComplete:()=>{O(),b()},onCancel:b},void 0,!1,void 0,this);if(Q==="edit")return T("✏️ 编辑 Agent");if(Q==="editWizard"&&J){let A={name:J.name,description:J.description,tools:J.tools||[],color:J.color,location:J.configPath?.includes(".blade/agents")?"project":"user",systemPrompt:J.systemPrompt||""};return t(K7,{initialConfig:A,onComplete:()=>{O(),b()},onCancel:b},void 0,!1,void 0,this)}if(Q==="delete")return T("\uD83D\uDDD1️ 删除 Agent");if(Q==="deleteConfirm"&&J)return t(c0,{flexDirection:"column",paddingY:1,children:[t(c0,{marginBottom:1,children:t(n0,{bold:!0,color:"red",children:"⚠️ 确认删除"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(c0,{marginBottom:1,paddingLeft:2,children:t(n0,{children:["你确定要删除 Agent"," ",t(n0,{bold:!0,color:"yellow",children:J.name},void 0,!1,void 0,this)," ","吗?"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),t(c0,{marginBottom:1,paddingLeft:2,children:t(n0,{dimColor:!0,children:["文件路径: ",J.configPath]},void 0,!0,void 0,this)},void 0,!1,void 0,this),t(c0,{marginBottom:1,paddingLeft:2,children:t(n0,{color:"red",children:"此操作无法撤销!"},void 0,!1,void 0,this)},void 0,!1,void 0,this),t(RY,{items:[{label:"\uD83D\uDDD1️ 确认删除",value:"confirm"},{label:"❌ 取消",value:"cancel"}],onSelect:(A)=>{if(A.value==="confirm")M();else b()}},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return null}U$();import{Box as t8,Text as o0}from"ink";import Ub from"react";H6();ZY();import{useEffect as Wb,useState as nU}from"react";function oU($=process.cwd(),Z=5000){let[Y,Q]=nU(null),[X,J]=nU(!0);return Wb(()=>{let G=!0,q=async()=>{try{let W=await a3($);if(!G)return;if(!W){Q(null),J(!1);return}let U=await jK($);if(!G)return;Q(U)}catch{if(G)Q(null)}finally{if(G)J(!1)}};q();let K=null;if(Z>0)K=setInterval(q,Z);return()=>{if(G=!1,K)clearInterval(K)}},[$,Z]),{branch:Y,loading:X}}import{jsxDEV as V0,Fragment as o6}from"react/jsx-dev-runtime";var sU=Ub.memo(()=>{let $=p6(),Z=a8(),Q=x6()==="shortcuts",X=KU(),{branch:J}=oU(),G=m6(),q=YU(),K=ZU(),W=g6(),U=RU(),O=G?C8(G):!1,H=(()=>{if(Z==="default")return null;if(Z==="autoEdit")return V0(o0,{color:"magenta",children:["▶▶ auto edit on ",V0(o0,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="plan")return V0(o0,{color:"cyan",children:["‖ plan mode on ",V0(o0,{color:"gray",children:"(shift+tab to cycle)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(Z==="yolo")return V0(o0,{color:"red",children:["⚡ yolo mode on ",V0(o0,{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,N;if(!w)N="init";else if((w==="tasks"||w==="implementation")&&L>0)N=`${w} ${B}/${L}`;else N=w;return V0(o0,{color:"blue",children:["\uD83D\uDCCB spec: ",N," ",V0(o0,{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 V0(t8,{flexDirection:"row",justifyContent:"space-between",paddingX:2,paddingY:0,children:[Q?V0(t8,{flexDirection:"column",gap:0,children:z.map((w,B)=>V0(t8,{flexDirection:"row",children:[w.map((L,N)=>{let[M,b]=L.split(":");return V0(t8,{flexDirection:"row",width:20,children:[V0(o0,{color:"yellow",children:M},void 0,!1,void 0,this),V0(o0,{color:"gray",children:":"},void 0,!1,void 0,this),V0(o0,{color:"white",children:b},void 0,!1,void 0,this)]},N,!0,void 0,this)}),B===z.length-1&&V0(o0,{color:"cyan",children:" ? 关闭"},void 0,!1,void 0,this)]},B,!0,void 0,this))},void 0,!1,void 0,this):V0(t8,{flexDirection:"row",gap:1,children:[J&&V0(o6,{children:[V0(o0,{color:"gray",children:[" ",J]},void 0,!0,void 0,this),V0(o0,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),H,_&&V0(o0,{color:"gray",children:"·"},void 0,!1,void 0,this),V0(o0,{color:"gray",children:"? for shortcuts"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),V0(t8,{flexDirection:"row",gap:1,children:!$?V0(o0,{color:"red",children:"⚠ API 密钥未配置"},void 0,!1,void 0,this):V0(o6,{children:[O&&V0(o6,{children:[W?V0(o0,{color:"cyan",children:"Thinking on"},void 0,!1,void 0,this):V0(o0,{color:"gray",children:"Tab:Thinking"},void 0,!1,void 0,this),V0(o0,{color:"gray",children:"·"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),G&&V0(o0,{color:"gray",children:G.model},void 0,!1,void 0,this),V0(o0,{color:"gray",children:"·"},void 0,!1,void 0,this),K?V0(o0,{color:"yellow",children:"压缩中..."},void 0,!1,void 0,this):V0(o0,{color:q<20?"red":q<50?"yellow":"gray",children:[q,"%"]},void 0,!0,void 0,this),X&&V0(o6,{children:[V0(o0,{color:"gray",children:"·"},void 0,!1,void 0,this),V0(o0,{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 MY,Text as DY}from"ink";import Ob from"react";import{jsxDEV as e8}from"react/jsx-dev-runtime";var tU=Ob.memo(({suggestions:$,selectedIndex:Z,visible:Y,maxDisplay:Q=8})=>{if(!Y||$.length===0)return null;let X=0,J=Math.min(Q,$.length),G=Z>=$.length;if(Z>=Q&&!G)X=Z-Q+1,J=Z+1;let q=$.slice(X,J),K=$.length>Q;return e8(MY,{flexDirection:"column",paddingX:2,paddingY:0,children:[q.map((W,U)=>{let F=X+U===Z;return e8(MY,{flexDirection:"row",paddingX:1,gap:2,children:[e8(DY,{color:F?"cyan":"white",bold:F,children:W.command},void 0,!1,void 0,this),e8(DY,{color:F?"cyan":"gray",dimColor:!F,children:["- ",W.description]},void 0,!0,void 0,this)]},W.command,!0,void 0,this)}),K&&e8(MY,{paddingX:1,children:e8(DY,{color:G?"cyan":"gray",bold:G,dimColor:!G,children:["... and ",$.length-Q," more"]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});U$();import{Box as S1,Text as $2,useInput as pb,useStdout as mb}from"ink";import gb from"ink-select-input";import mY,{useMemo as UO}from"react";import{Box as L0,Text as S0}from"ink";import Q8,{useEffect as pY,useMemo as Y8,useRef as WO}from"react";W3();T5();import{Box as t6,Text as z2}from"ink";import{isPlainObject as IY}from"lodash-es";import{common as Bb,createLowlight as wb}from"lowlight";import QO from"react";V4();import{Box as s6,Text as W7}from"ink";import T2,{Fragment as ZO}from"react";import Fb from"string-width";var eU=new Map,$O=1000;function yY($){let Z=!0;for(let Q=0;Q<$.length;Q++)if($.charCodeAt(Q)>127){Z=!1;break}if(Z)return $.split("");if($.length<=$O){let Q=eU.get($);if(Q)return Q}let Y=Array.from($);if($.length<=$O)eU.set($,Y);return Y}var jY=new Map;function y2($){if(/^[\x20-\x7E]*$/.test($))return $.length;if(jY.has($))return jY.get($);let Z=Fb($);return jY.set($,Z),Z}import{jsxDEV as $3}from"react/jsx-dev-runtime";var TY=2,YO=T2.memo(({children:$,maxWidth:Z,maxHeight:Y,overflowDirection:Q="top",additionalHiddenLinesCount:X=0})=>{let J=d0(),G=[],q=Math.max(Math.round(Y??Number.MAX_SAFE_INTEGER),TY);function K(z){if(!T2.isValidElement(z))return;if(z.type===ZO){T2.Children.forEach(z.props.children,K);return}if(z.type===s6){_b(z,Z,G);return}}T2.Children.forEach($,K);let U=G.length>q||X>0?q-1:q,O=U!==void 0?Math.max(0,G.length-U):0,F=O+X,_=(O>0?Q==="top"?G.slice(O):G.slice(0,U):G).map((z,w)=>$3(s6,{children:z.length>0?z.map((B,L)=>$3(W7,{...B.props,children:B.text},L,!1,void 0,this)):$3(W7,{children:" "},void 0,!1,void 0,this)},w,!1,void 0,this));return $3(s6,{flexDirection:"column",width:Z,flexShrink:0,children:[F>0&&Q==="top"&&$3(W7,{color:J.colors.text.muted,dimColor:!0,children:["... ",F," line",F===1?"":"s"," hidden ..."]},void 0,!0,void 0,this),_,F>0&&Q==="bottom"&&$3(W7,{color:J.colors.text.muted,dimColor:!0,children:["... ",F," line",F===1?"":"s"," hidden ..."]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});function Hb($){if(!T2.isValidElement($)||$.type!==s6)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(!T2.isValidElement(X))return;if(X.type===ZO){T2.Children.forEach(X.props.children,(W)=>Q(W,J));return}if(X.type!==W7)return;let{children:G,...q}=X.props,K=J===void 0?q:{...J,...q};T2.Children.forEach(G,(W)=>Q(W,K))}return T2.Children.forEach($.props.children,(X)=>Q(X,void 0)),Z}function _b($,Z,Y){let Q=Hb($);if(Q.segments.length===0&&Q.noWrapSegments.length===0){Y.push([]);return}let X=0;for(let O of Q.noWrapSegments)X+=y2(O.text);if(Q.segments.length===0){let O=[],F=[];for(let H of Q.noWrapSegments){let _=H.text.split(`
2825
2825
  `);for(let z=0;z<_.length;z++){if(z>0)O.push(F),F=[];if(_[z])F.push({text:_[z],props:H.props})}}if(F.length>0)O.push(F);for(let H of O)Y.push(H);return}let J=Z-X;if(J<1){zb(Q.noWrapSegments,Z,Y);return}let G=[],q=[],K=0;function W(){if(G.length===0)G.push([...Q.noWrapSegments,...q]);else if(X>0)G.push([{text:" ".repeat(X),props:{}},...q]);else G.push(q);q=[],K=0}function U(O,F){if(q.length>0&&q[q.length-1].props===F)q[q.length-1].text+=O;else q.push({text:O,props:F})}for(let O of Q.segments){let F=O.text.split(`
2826
2826
  `);for(let H=0;H<F.length;H++){if(H>0)W();let z=F[H].split(/(\s+)/);for(let w of z){if(!w)continue;let B=y2(w);if(K+B>J&&K>0){if(W(),/^\s+$/.test(w))continue}if(B>J){let N=yY(w);while(N.length>0){let M=0,b=0;for(let j of N){let T=y2(j);if(K+b+T>J)break;b+=T,M++}if(M>0){let j=N.slice(0,M).join("");U(j,O.props),K+=y2(j),N=N.slice(M)}if(N.length>0)W()}}else U(w,O.props),K+=B}}if(O.text.endsWith(`
2827
2827
  `))W()}if(q.length>0)W();for(let O of G)Y.push(O)}function zb($,Z,Y){let Q=[],X=[],J=0;for(let G of $){let q=G.text.split(`
2828
- `);for(let K=0;K<q.length;K++){if(K>0)Q.push(X),X=[],J=0;let W=q[K];if(!W)continue;let U=y2(W),O=Math.max(0,Z-y2("…"));if(U<=O&&J===0)X.push({text:W,props:G.props}),J+=U;else{let F=yY(W),H=J,_=0;for(let w of F){let B=y2(w);if(H+B>O)break;H+=B,_++}let z=F.slice(0,_).join("");if(z)X.push({text:z,props:G.props});X.push({text:"…",props:{}}),J=H+y2("…")}}}if(X.length>0)Q.push(X);if(Q.length===0)Q.push([{text:"…",props:{}}]);for(let G of Q)Y.push(G)}import{jsxDEV as m$}from"react/jsx-dev-runtime";var EY=wb(Bb);function Lb($){return IY($)&&$.type==="text"&&typeof $.value==="string"}function Nb($){return IY($)&&$.type==="element"}function Ab($){return IY($)&&$.type==="root"&&Array.isArray($.children)}function e7($,Z,Y=0){if(Lb($))return m$(z2,{wrap:"wrap",children:$.value},Y,!1,void 0,this);if(Nb($)){let Q=$.properties?.className?.[0]||"",X=Z.default;if(Q.includes("comment"))X=Z.comment;else if(Q.includes("string"))X=Z.string;else if(Q.includes("number"))X=Z.number;else if(Q.includes("keyword"))X=Z.keyword;else if(Q.includes("function"))X=Z.function;else if(Q.includes("variable"))X=Z.variable;else if(Q.includes("operator"))X=Z.operator;else if(Q.includes("type"))X=Z.type;else if(Q.includes("tag"))X=Z.tag;else if(Q.includes("attr"))X=Z.attr;let J=$.children?.map((G,q)=>e7(G,Z,q));return m$(z2,{color:X,wrap:"wrap",children:J},Y,!1,void 0,this)}if(Ab($))return m$(QO.Fragment,{children:$.children.map((Q,X)=>e7(Q,Z,X))},Y,!1,void 0,this);return m$(z2,{},Y,!1,void 0,this)}function bb($,Z,Y){let Q=Y||i$.getTheme().colors.syntax;try{if(!Z||!EY.registered(Z)){let J=EY.highlightAuto($);if(!J.children||J.children.length===0)return m$(z2,{color:Q.default,wrap:"wrap",children:$},void 0,!1,void 0,this);return e7(J,Q)}let X=EY.highlight(Z,$);if(!X.children||X.children.length===0)return m$(z2,{color:Q.default,wrap:"wrap",children:$},void 0,!1,void 0,this);return e7(X,Q)}catch(X){return m$(z2,{color:Q.default,wrap:"wrap",children:$},void 0,!1,void 0,this)}}var $5=QO.memo(({content:$,language:Z,showLineNumbers:Y=!0,terminalWidth:Q,availableHeight:X})=>{let J=d0(),G=$.split(`
2829
- `),q=0;if(X&&G.length>X){let O=Math.max(X,TY);if(G.length>O)q=G.length-O,G=G.slice(q)}let K=G.length+q,W=String(K).length+1,U=Math.max(20,Q-4);return m$(t7,{borderStyle:"round",borderColor:J.colors.border.light,paddingX:1,paddingY:0,marginY:1,flexDirection:"column",children:[Z&&m$(t7,{marginBottom:0,children:m$(z2,{color:J.colors.text.secondary,children:Z},void 0,!1,void 0,this)},void 0,!1,void 0,this),q>0&&m$(t7,{marginBottom:0,children:m$(z2,{color:J.colors.text.muted,dimColor:!0,children:["... ",q," lines hidden ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this),m$(YO,{maxWidth:U,maxHeight:X,children:G.map((O,F)=>{let H=F+q+1;return m$(t7,{flexDirection:"row",children:[Y&&m$(z2,{color:J.colors.text.muted,dimColor:!0,wrap:"truncate",children:[String(H).padStart(W-1," ")," "]},void 0,!0,void 0,this),O.trim()===""?m$(z2,{wrap:"wrap",children:" "},void 0,!1,void 0,this):bb(O,Z,J.colors.syntax)]},F,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});import{Box as XO,Text as B2}from"ink";import Rb from"react";import{jsxDEV as I1}from"react/jsx-dev-runtime";function Vb($){let Z=$.split(`
2828
+ `);for(let K=0;K<q.length;K++){if(K>0)Q.push(X),X=[],J=0;let W=q[K];if(!W)continue;let U=y2(W),O=Math.max(0,Z-y2("…"));if(U<=O&&J===0)X.push({text:W,props:G.props}),J+=U;else{let F=yY(W),H=J,_=0;for(let w of F){let B=y2(w);if(H+B>O)break;H+=B,_++}let z=F.slice(0,_).join("");if(z)X.push({text:z,props:G.props});X.push({text:"…",props:{}}),J=H+y2("…")}}}if(X.length>0)Q.push(X);if(Q.length===0)Q.push([{text:"…",props:{}}]);for(let G of Q)Y.push(G)}import{jsxDEV as m$}from"react/jsx-dev-runtime";var EY=wb(Bb);function Lb($){return IY($)&&$.type==="text"&&typeof $.value==="string"}function Nb($){return IY($)&&$.type==="element"}function Ab($){return IY($)&&$.type==="root"&&Array.isArray($.children)}function e6($,Z,Y=0){if(Lb($))return m$(z2,{wrap:"wrap",children:$.value},Y,!1,void 0,this);if(Nb($)){let Q=$.properties?.className?.[0]||"",X=Z.default;if(Q.includes("comment"))X=Z.comment;else if(Q.includes("string"))X=Z.string;else if(Q.includes("number"))X=Z.number;else if(Q.includes("keyword"))X=Z.keyword;else if(Q.includes("function"))X=Z.function;else if(Q.includes("variable"))X=Z.variable;else if(Q.includes("operator"))X=Z.operator;else if(Q.includes("type"))X=Z.type;else if(Q.includes("tag"))X=Z.tag;else if(Q.includes("attr"))X=Z.attr;let J=$.children?.map((G,q)=>e6(G,Z,q));return m$(z2,{color:X,wrap:"wrap",children:J},Y,!1,void 0,this)}if(Ab($))return m$(QO.Fragment,{children:$.children.map((Q,X)=>e6(Q,Z,X))},Y,!1,void 0,this);return m$(z2,{},Y,!1,void 0,this)}function bb($,Z,Y){let Q=Y||i$.getTheme().colors.syntax;try{if(!Z||!EY.registered(Z)){let J=EY.highlightAuto($);if(!J.children||J.children.length===0)return m$(z2,{color:Q.default,wrap:"wrap",children:$},void 0,!1,void 0,this);return e6(J,Q)}let X=EY.highlight(Z,$);if(!X.children||X.children.length===0)return m$(z2,{color:Q.default,wrap:"wrap",children:$},void 0,!1,void 0,this);return e6(X,Q)}catch(X){return m$(z2,{color:Q.default,wrap:"wrap",children:$},void 0,!1,void 0,this)}}var $5=QO.memo(({content:$,language:Z,showLineNumbers:Y=!0,terminalWidth:Q,availableHeight:X})=>{let J=d0(),G=$.split(`
2829
+ `),q=0;if(X&&G.length>X){let O=Math.max(X,TY);if(G.length>O)q=G.length-O,G=G.slice(q)}let K=G.length+q,W=String(K).length+1,U=Math.max(20,Q-4);return m$(t6,{borderStyle:"round",borderColor:J.colors.border.light,paddingX:1,paddingY:0,marginY:1,flexDirection:"column",children:[Z&&m$(t6,{marginBottom:0,children:m$(z2,{color:J.colors.text.secondary,children:Z},void 0,!1,void 0,this)},void 0,!1,void 0,this),q>0&&m$(t6,{marginBottom:0,children:m$(z2,{color:J.colors.text.muted,dimColor:!0,children:["... ",q," lines hidden ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this),m$(YO,{maxWidth:U,maxHeight:X,children:G.map((O,F)=>{let H=F+q+1;return m$(t6,{flexDirection:"row",children:[Y&&m$(z2,{color:J.colors.text.muted,dimColor:!0,wrap:"truncate",children:[String(H).padStart(W-1," ")," "]},void 0,!0,void 0,this),O.trim()===""?m$(z2,{wrap:"wrap",children:" "},void 0,!1,void 0,this):bb(O,Z,J.colors.syntax)]},F,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});import{Box as XO,Text as B2}from"ink";import Rb from"react";import{jsxDEV as I1}from"react/jsx-dev-runtime";function Vb($){let Z=$.split(`
2830
2830
  `),Y=[],Q=0,X=0;for(let J of Z){if(J.startsWith("---")||J.startsWith("+++"))continue;if(J.startsWith("@@")){let G=J.match(/@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@/);if(G)Q=parseInt(G[1],10),X=parseInt(G[3],10);Y.push({type:"header",content:J});continue}if(J.startsWith("-")){Y.push({type:"remove",content:J.substring(1),lineNumber:Q}),Q++;continue}if(J.startsWith("+")){Y.push({type:"add",content:J.substring(1),lineNumber:X}),X++;continue}if(J.startsWith(" ")||J===""){Y.push({type:"context",content:J.substring(1),lineNumber:X}),Q++,X++;continue}}return Y}var vY=Rb.memo(({patch:$,startLine:Z,matchLine:Y,terminalWidth:Q,maxLines:X=20})=>{let J=d0(),G=Vb($),K=Math.max(...G.map((H)=>H.lineNumber||0)).toString().length+1,W=G.length,U=W>X,O=U?G.slice(0,X):G,F=W-X;return I1(XO,{flexDirection:"column",marginTop:1,marginBottom:1,children:[I1(B2,{color:J.colors.muted,children:"─".repeat(Math.max(0,Math.min(60,Q)))},void 0,!1,void 0,this),U&&I1(B2,{color:J.colors.info,children:["\uD83D\uDCCA 显示前 ",X," 行,共 ",W," 行 diff"]},void 0,!0,void 0,this),U&&I1(B2,{color:J.colors.muted,children:"─".repeat(Math.max(0,Math.min(60,Q)))},void 0,!1,void 0,this),O.map((H,_)=>{if(H.type==="header")return I1(B2,{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 N=Math.max(0,Q-K-2),M=H.content;if(M.length>N)M=M.substring(0,N-3)+"...";return I1(B2,{color:L,backgroundColor:B,children:[I1(B2,{dimColor:!0,children:z},void 0,!1,void 0,this),I1(B2,{children:w},void 0,!1,void 0,this),I1(B2,{children:[" ",M]},void 0,!0,void 0,this)]},_,!0,void 0,this)}),U&&I1(XO,{marginTop:1,children:I1(B2,{color:J.colors.warning,dimColor:!0,children:["⚠️ 已隐藏剩余 ",F," 行 diff(总共 ",W," 行)"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),I1(B2,{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 e1}from"ink";import Db from"react";import Mb from"string-width";var $8=($)=>{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 Mb(Z)},JO=($,Z,Y="...")=>{if($8($)<=Z)return $;if(Z<=Y.length)return Y.substring(0,Z);let X=0,J=$.length,G="";while(X<=J){let q=Math.floor((X+J)/2),K=$.substring(0,q);if($8(K)<=Z-Y.length)G=K,X=q+1;else J=q-1}return G+Y},GO=($)=>{return/[*_~`<[\]https?:]/.test($)};import{jsxDEV as v1,Fragment as yb}from"react/jsx-dev-runtime";var PY=2,CY=1,SY=2;function kY($,Z){return`inline-${$}-${Z}`}var jb=({text:$})=>{let Z=d0();if(!GO($))return v1(e1,{children:$},void 0,!1,void 0,this);let Y=[],Q=0,X=0,J=0,G=/(\*\*.*?\*\*|\*(?!\s).*?(?<!\s)\*|_(?!\s).*?(?<!\s)_|~~.*?~~|`+[^`]+`+|\[.*?\]\(.*?\)|https?:\/\/\S+)/g,q;while((q=G.exec($))!==null){if(q.index>Q){let O=$.slice(Q,q.index);Y.push(v1(e1,{children:O},kY("text",X++),!1,void 0,this))}let K=q[0],W=null,U=kY("match",J++);try{if(K.startsWith("**")&&K.endsWith("**")&&K.length>PY*2)W=v1(e1,{bold:!0,children:K.slice(PY,-PY)},U,!1,void 0,this);else if(K.length>CY*2&&(K.startsWith("*")&&K.endsWith("*")||K.startsWith("_")&&K.endsWith("_"))){let O=$.substring(q.index-1,q.index),F=$.substring(G.lastIndex,G.lastIndex+1);if(!(/\w/.test(O)||/\w/.test(F)||/[./\\]/.test(O+F)))W=v1(e1,{italic:!0,children:K.slice(CY,-CY)},U,!1,void 0,this)}else if(K.startsWith("~~")&&K.endsWith("~~")&&K.length>SY*2)W=v1(e1,{strikethrough:!0,children:K.slice(SY,-SY)},U,!1,void 0,this);else if(K.startsWith("`")&&K.endsWith("`")){let O=K.match(/^(`+)([^`]+)\1$/);if(O&&O[2])W=v1(e1,{color:Z.colors.syntax.keyword,backgroundColor:Z.colors.background.secondary,bold:!0,children:` ${O[2]} `},U,!1,void 0,this)}else if(K.startsWith("[")&&K.includes("](")&&K.endsWith(")")){let O=K.match(/\[(.*?)\]\((.*?)\)/);if(O){let F=O[1],H=O[2];W=v1(e1,{children:[F,v1(e1,{color:Z.colors.info,children:[" (",H,")"]},void 0,!0,void 0,this)]},U,!0,void 0,this)}}else if(K.match(/^https?:\/\//))W=v1(e1,{color:Z.colors.info,children:K},U,!1,void 0,this)}catch(O){console.error("InlineRenderer 解析错误:",K,O),W=null}Y.push(W??v1(e1,{children:K},U,!1,void 0,this)),Q=G.lastIndex}if(Q<$.length){let K=$.slice(Q);Y.push(v1(e1,{children:K},kY("text",X++),!1,void 0,this))}return v1(yb,{children:Y.filter((K)=>K!==null)},void 0,!1,void 0,this)},P1=Db.memo(jb);import{Box as fY,Text as qO}from"ink";import Tb from"react";import{jsxDEV as Z3}from"react/jsx-dev-runtime";var Eb=({itemText:$,type:Z,marker:Y,leadingWhitespace:Q=""})=>{let X=Z==="ol"?`${Y}. `:`${Y} `,J=X.length,G=Q.length;return Z3(fY,{paddingLeft:G+1,flexDirection:"row",children:[Z3(fY,{width:J,children:Z3(qO,{children:X},void 0,!1,void 0,this)},void 0,!1,void 0,this),Z3(fY,{flexGrow:1,children:Z3(qO,{wrap:"wrap",children:Z3(P1,{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)},hY=Tb.memo(Eb);import{Box as Ib,Text as Z8}from"ink";import xY from"react";import{jsxDEV as C1}from"react/jsx-dev-runtime";var KO=xY.memo(({headers:$,rows:Z,terminalWidth:Y})=>{let Q=d0();if($.length===0||Z.length===0)return null;let X=$.map((F,H)=>{let _=$8(F),z=Math.max(...Z.map((w)=>$8(w[H]||"")));return Math.max(_,z)+2}),J=$.length+1,G=X.reduce((F,H)=>F+H,0)+J,q=G>Y?Y/G:1,K=X.map((F)=>Math.floor(F*q)),W=(F,H,_=!1)=>{let z=Math.max(0,H-2),w=$8(F),B=F;if(w>z)B=JO(F,z);let L=$8(B),N=Math.max(0,z-L);return C1(Z8,{children:[_?C1(Z8,{bold:!0,color:Q.colors.primary,children:C1(P1,{text:B},void 0,!1,void 0,this)},void 0,!1,void 0,this):C1(P1,{text:B},void 0,!1,void 0,this)," ".repeat(N)]},void 0,!0,void 0,this)},U=(F)=>{let _={top:{left:"┌",middle:"┬",right:"┐",horizontal:"─"},middle:{left:"├",middle:"┼",right:"┤",horizontal:"─"},bottom:{left:"└",middle:"┴",right:"┘",horizontal:"─"}}[F],z=K.map((B)=>_.horizontal.repeat(B)),w=_.left+z.join(_.middle)+_.right;return C1(Z8,{color:Q.colors.text.muted,dimColor:!0,children:w},void 0,!1,void 0,this)},O=(F,H=!1)=>{let _=F.map((z,w)=>{let B=K[w]||0;return W(z||"",B,H)});return C1(Z8,{children:[C1(Z8,{color:Q.colors.text.muted,children:"│ "},void 0,!1,void 0,this),_.map((z,w)=>C1(xY.Fragment,{children:[z,w<_.length-1&&C1(Z8,{color:Q.colors.text.muted,children:" │ "},void 0,!1,void 0,this)]},w,!0,void 0,this)),C1(Z8,{color:Q.colors.text.muted,children:" │"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};return C1(Ib,{flexDirection:"column",marginY:1,children:[U("top"),O($,!0),U("middle"),Z.map((F,H)=>C1(xY.Fragment,{children:O(F)},H,!1,void 0,this)),U("bottom")]},void 0,!0,void 0,this)});import{jsxDEV as h}from"react/jsx-dev-runtime";var vb=($,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:" "}}},Pb=Q8.memo(({content:$,language:Z,terminalWidth:Y,isPending:Q=!1,availableHeight:X})=>{let J=d0();if(Q&&X!==void 0){let G=$.split(`
2831
2831
  `),q=4,K=Math.max(1,X-4);if(G.length>K){let W=G.slice(0,K).join(`
2832
2832
  `);return h(L0,{flexDirection:"column",flexShrink:0,children:[h($5,{content:W,language:Z,showLineNumbers:!0,terminalWidth:Y},void 0,!1,void 0,this),h(S0,{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($5,{content:$,language:Z,showLineNumbers:!0,terminalWidth:Y},void 0,!1,void 0,this)}),Cb=Q8.memo(({content:$,level:Z})=>{let Y=d0();switch(Z){case 1:return h(S0,{bold:!0,color:Y.colors.primary,children:h(P1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 2:return h(S0,{bold:!0,color:Y.colors.primary,children:h(P1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 3:return h(S0,{bold:!0,color:Y.colors.text.primary,children:h(P1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);case 4:return h(S0,{italic:!0,color:Y.colors.text.muted,children:h(P1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this);default:return h(S0,{children:h(P1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)}}),Sb=Q8.memo(({terminalWidth:$})=>{let Z=d0(),Y=Math.max(0,Math.min($-4,80));return h(S0,{dimColor:!0,color:Z.colors.text.muted,children:"─".repeat(Y)},void 0,!1,void 0,this)}),kb=Q8.memo(({content:$})=>{return h(S0,{wrap:"wrap",children:h(P1,{text:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)}),fb=Q8.memo(({content:$})=>{let Z=d0();return h(L0,{flexDirection:"row",gap:1,children:[h(S0,{color:Z.colors.info,children:"⏳"},void 0,!1,void 0,this),h(S0,{color:Z.colors.text.muted,italic:!0,children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}),hb=Q8.memo(({detail:$,terminalWidth:Z})=>{let Y=d0(),Q=50,X=$.split(`
2833
2833
  `);while(X.length>0&&X[0].trim()==="")X.shift();while(X.length>0&&X[X.length-1].trim()==="")X.pop();let J=X.length>50,G=J?X.slice(0,50):X,q=G.join(`
2834
2834
  `),K=q.includes("<<<DIFF>>>"),W=q.includes("```");if(K){let U=q.match(/<<<DIFF>>>\s*({[\s\S]*?})\s*<<<\/DIFF>>>/);if(U)try{let O=JSON.parse(U[1]);return h(L0,{flexDirection:"column",children:[h(vY,{patch:O.patch,startLine:O.startLine,matchLine:O.matchLine,terminalWidth:Z},void 0,!1,void 0,this),J&&h(L0,{marginTop:1,children:h(S0,{dimColor:!0,color:Y.colors.text.muted,children:["... 省略 ",X.length-50," 行 ..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}catch{}}if(W){let U=q.match(/```(\w+)?\s*\n([\s\S]*?)\n```/);if(U){let O=U[1]||"text",F=U[2];return h(L0,{flexDirection:"column",children:[h($5,{content:F,language:O,showLineNumbers:!1,terminalWidth:Z},void 0,!1,void 0,this),J&&h(L0,{marginTop:1,children:h(S0,{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(L0,{flexDirection:"column",children:[G.map((U,O)=>h(S0,{color:Y.colors.text.primary,children:U},O,!1,void 0,this)),J&&h(L0,{marginTop:1,children:h(S0,{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 xb($,Z,Y,Q=80){if(!Y||Z===void 0||Z<=0)return{content:$,isTruncated:!1,hiddenLines:0};let J=Math.max(1,Z-8),G=Math.max(40,Q*0.8),q=J*G;if($.length<=q)return{content:$,isTruncated:!1,hiddenLines:0};let K=Math.floor(q*0.9),W=$.length-K,U=W,O=$.indexOf(`
2835
2835
  `,W);if(O!==-1&&O-W<G)U=O+1;let F=$.slice(U),_=($.slice(0,U).match(/\n/g)||[]).length+1;return{content:F,isTruncated:!0,hiddenLines:_}}var F4=Q8.memo(({content:$,role:Z,terminalWidth:Y,metadata:Q,isPending:X=!1,availableTerminalHeight:J,hidePrefix:G=!1,noMargin:q=!1,renderPlainTextOnly:K=!1,streamingLines:W,streamingHiddenLines:U,messageId:O,blocksOverride:F,currentLineOverride:H,streamingMode:_="text",renderCodeBlocksAsPlainText:z=!1})=>{let w=d0(),B=F!==void 0,L=Y8(()=>vb(Z,w.colors,Q),[Z,w.colors,Q]),{color:N,prefix:M}=L,b=M.length+1,j=Y8(()=>{if(!Q||typeof Q!=="object")return null;if(!("subtaskRef"in Q))return null;let v=Q.subtaskRef;if(!v||typeof v!=="object")return null;return v},[Q]),T=Z==="tool"&&Q?.phase==="start",A=!q&&!T,k=Y8(()=>{if(!K)return[];return $.split(/\r?\n/)},[$,K]);if(!B&&X){let v=W??$.split(/\r?\n/),Z0=U??0,d=!1,s=!1,C=!1;if(_!=="text")d=_==="code",s=_==="diff",C=_==="table";return h(L0,{flexDirection:"column",marginBottom:A?1:0,flexShrink:0,children:[Z0>0&&h(L0,{flexDirection:"row",flexShrink:0,children:[h(L0,{width:b,flexShrink:0},void 0,!1,void 0,this),h(S0,{color:w.colors.text.muted,dimColor:!0,children:["↑ ",Z0," lines above (streaming...)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),v.map((i,n)=>{if(_==="text"){if(i.match(E0.codeBlock))d=!d;else if(i.match(E0.diffStart))s=!0;else if(i.match(E0.diffEnd))s=!1;else if(i.match(E0.table))C=!0;else if(C&&!i.match(E0.table))C=!1}let B0=_==="text"&&!d&&!s&&!C,j0=B0?i.match(E0.ulItem):null,K$=B0?i.match(E0.olItem):null,$1=j0??K$;return h(L0,{flexDirection:"row",flexShrink:0,children:[n===0&&!G?h(L0,{marginRight:1,flexShrink:0,children:h(S0,{color:N,bold:!0,children:M},void 0,!1,void 0,this)},void 0,!1,void 0,this):h(L0,{width:b,flexShrink:0},void 0,!1,void 0,this),h(L0,{flexGrow:1,flexShrink:0,children:$1?h(hY,{type:j0?"ul":"ol",marker:$1[2],itemText:$1[3],leadingWhitespace:$1[1]},void 0,!1,void 0,this):h(S0,{wrap:"wrap",children:i===""?" ":i},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},n,!0,void 0,this)})]},void 0,!0,void 0,this)}if(!B&&K)return h(L0,{flexDirection:"column",marginBottom:A?1:0,flexShrink:0,children:k.map((v,Z0)=>h(L0,{flexDirection:"row",flexShrink:0,children:[Z0===0&&!G?h(L0,{marginRight:1,flexShrink:0,children:h(S0,{color:N,bold:!0,children:M},void 0,!1,void 0,this)},void 0,!1,void 0,this):h(L0,{width:b,flexShrink:0},void 0,!1,void 0,this),h(L0,{flexGrow:1,flexShrink:0,children:h(S0,{wrap:"wrap",children:v===""?" ":v},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},Z0,!0,void 0,this))},void 0,!1,void 0,this);let c=WO(null);pY(()=>{c.current=null},[O]);let o=Y8(()=>{if(B)return null;if(!O)return null;return pQ(O)},[O,B]);pY(()=>{if(B)return;if(!o||!O)return;c.current={messageId:O,blocks:o}},[o,O,B]),pY(()=>{if(B)return;if(!o||!O)return;gQ(O)},[o,O,B]);let S=Y8(()=>B?{content:$,isTruncated:!1,hiddenLines:0}:xb($,J,X,Y),[$,J,X,Y,B]),{content:y,isTruncated:l,hiddenLines:I}=S;if(!B&&Z==="tool"&&Q&&"detail"in Q){let v=Q;if(v.detail)return h(L0,{flexDirection:"column",marginBottom:q?0:1,children:[h(L0,{flexDirection:"row",children:[h(L0,{marginRight:1,children:h(S0,{color:N,bold:!0,children:M},void 0,!1,void 0,this)},void 0,!1,void 0,this),h(S0,{color:N,children:$},void 0,!1,void 0,this)]},void 0,!0,void 0,this),h(L0,{marginLeft:M.length+1,children:h(hb,{detail:v.detail,terminalWidth:Y-(M.length+1)},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}let{completedContent:D,currentLine:V}=Y8(()=>{if(B)return{completedContent:"",currentLine:H??""};if(!X)return{completedContent:y,currentLine:""};let v=y.lastIndexOf(`
2836
- `);if(v===-1)return{completedContent:"",currentLine:y};return{completedContent:y.slice(0,v+1),currentLine:y.slice(v+1)}},[y,X,B,H]),g=WO({content:"",blocks:[]}),u=Y8(()=>{if(B)return F??[];if(o)return o;if(c.current&&c.current.messageId===O)return c.current.blocks;let v=g.current;if(!X||!D.startsWith(v.content)){let C=M4(D);return g.current={content:D,blocks:C},C}if(D===v.content)return v.blocks;let Z0=D.slice(v.content.length),d=M4(Z0),s=[...v.blocks,...d];return g.current={content:D,blocks:s},s},[D,X,B,F]);return h(L0,{flexDirection:"column",marginBottom:A?1:0,flexShrink:0,children:[l&&h(L0,{flexDirection:"row",flexShrink:0,children:[h(L0,{width:b,flexShrink:0},void 0,!1,void 0,this),h(S0,{color:w.colors.text.muted,dimColor:!0,children:["↑ ",I," lines above (streaming...)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),u.map((v,Z0)=>{if(v.type==="empty")return h(L0,{height:1,flexShrink:0},Z0,!1,void 0,this);return h(L0,{flexDirection:"row",flexShrink:0,children:[Z0===0&&!G&&h(L0,{marginRight:1,flexShrink:0,children:h(S0,{color:N,bold:!0,children:M},void 0,!1,void 0,this)},void 0,!1,void 0,this),(Z0>0||G)&&h(L0,{width:b,flexShrink:0},void 0,!1,void 0,this),h(L0,{flexGrow:1,flexShrink:0,children:v.type==="code"?z?h(S0,{wrap:"wrap",children:v.content},void 0,!1,void 0,this):h(Pb,{content:v.content,language:v.language,terminalWidth:Y-b,isPending:X,availableHeight:J},void 0,!1,void 0,this):v.type==="table"&&v.tableData?h(KO,{headers:v.tableData.headers,rows:v.tableData.rows,terminalWidth:Y-b},void 0,!1,void 0,this):v.type==="heading"?h(Cb,{content:v.content,level:v.level||1},void 0,!1,void 0,this):v.type==="list"?h(hY,{type:v.listType||"ul",marker:v.marker||"-",itemText:v.content,leadingWhitespace:" ".repeat(v.indentation||0)},void 0,!1,void 0,this):v.type==="hr"?h(Sb,{terminalWidth:Y-b},void 0,!1,void 0,this):v.type==="diff"&&v.diffData?h(vY,{patch:v.diffData.patch,startLine:v.diffData.startLine,matchLine:v.diffData.matchLine,terminalWidth:Y-b},void 0,!1,void 0,this):v.type==="command-message"?h(fb,{content:v.content},void 0,!1,void 0,this):h(kb,{content:v.content},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},Z0,!0,void 0,this)}),V&&h(L0,{flexDirection:"row",flexShrink:0,children:[u.length===0&&!G?h(L0,{marginRight:1,flexShrink:0,children:h(S0,{color:N,bold:!0,children:M},void 0,!1,void 0,this)},void 0,!1,void 0,this):h(L0,{width:b,flexShrink:0},void 0,!1,void 0,this),h(L0,{flexGrow:1,flexShrink:0,children:h(S0,{wrap:"wrap",children:V},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),j&&h(L0,{flexDirection:"row",flexShrink:0,children:[h(L0,{width:b,flexShrink:0},void 0,!1,void 0,this),h(L0,{flexDirection:"column",flexGrow:1,flexShrink:0,children:[h(S0,{color:w.colors.text.muted,children:["Subtask ",typeof j.agentType==="string"?`@${j.agentType}`:"",typeof j.status==="string"?` · ${j.status}`:""]},void 0,!0,void 0,this),typeof j.summary==="string"&&j.summary.trim()!==""&&h(S0,{wrap:"wrap",children:j.summary},void 0,!1,void 0,this),typeof j.childSessionId==="string"&&h(S0,{color:w.colors.text.muted,children:["Session ",j.childSessionId]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},($,Z)=>{return $.content===Z.content&&$.role===Z.role&&$.terminalWidth===Z.terminalWidth&&$.isPending===Z.isPending&&$.availableTerminalHeight===Z.availableTerminalHeight&&$.hidePrefix===Z.hidePrefix&&$.noMargin===Z.noMargin&&$.renderPlainTextOnly===Z.renderPlainTextOnly&&$.streamingHiddenLines===Z.streamingHiddenLines&&$.streamingLines===Z.streamingLines&&$.messageId===Z.messageId&&$.metadata===Z.metadata&&$.blocksOverride===Z.blocksOverride&&$.currentLineOverride===Z.currentLineOverride&&$.streamingMode===Z.streamingMode&&$.renderCodeBlocksAsPlainText===Z.renderCodeBlocksAsPlainText});import{jsxDEV as l0,Fragment as cb}from"react/jsx-dev-runtime";var ub=mY.memo(({label:$,isSelected:Z})=>l0($2,{color:Z?"yellow":void 0,children:$},void 0,!1,void 0,this)),db=mY.memo(({details:$,headerColor:Z,isPlanModeExit:Y,isPlanModeEnter:Q,terminalWidth:X})=>l0(cb,{children:[$.title&&l0(S1,{marginBottom:1,children:l0($2,{bold:!0,children:$.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),l0(S1,{marginBottom:1,children:l0($2,{children:$.message},void 0,!1,void 0,this)},void 0,!1,void 0,this),($.planContent||$.details)&&l0(S1,{flexDirection:"column",marginBottom:1,borderStyle:"single",borderColor:Z,padding:1,children:[l0($2,{bold:!0,color:Z,children:Y?"\uD83D\uDCCB Implementation Plan:":Q?"\uD83D\uDCDD Details:":"\uD83D\uDCC4 Operation Details:"},void 0,!1,void 0,this),l0(S1,{marginTop:1,children:l0(F4,{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&&l0(S1,{flexDirection:"column",marginBottom:1,children:[l0($2,{color:"red",bold:!0,children:"⚠️ 风险提示:"},void 0,!1,void 0,this),$.risks.map((J,G)=>l0(S1,{marginLeft:2,children:l0($2,{color:"red",children:["• ",J]},void 0,!0,void 0,this)},G,!1,void 0,this))]},void 0,!0,void 0,this),$.affectedFiles&&$.affectedFiles.length>0&&l0(S1,{flexDirection:"column",marginBottom:1,children:[l0($2,{color:"yellow",children:"\uD83D\uDCC1 影响的文件:"},void 0,!1,void 0,this),$.affectedFiles.slice(0,3).map((J,G)=>l0(S1,{marginLeft:2,children:l0($2,{children:["• ",J]},void 0,!0,void 0,this)},G,!1,void 0,this)),$.affectedFiles.length>3&&l0(S1,{marginLeft:2,children:l0($2,{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)),OO=mY.memo(({details:$,onResponse:Z})=>{let{stdout:Y}=mb(),Q=Y.columns||80,J=q1()==="confirmation-prompt",G=Q$(!1),q=$.type==="exitPlanMode",K=$.type==="enterPlanMode",W=$.type==="maxTurnsExceeded";pb((F,H)=>{if(H.ctrl&&F==="c"||H.meta&&F==="c"){G();return}if(H.escape){Z({approved:!1,reason:"用户取消"});return}let _=F.toLowerCase();if(q){if(_==="y"){Z({approved:!0,targetMode:"autoEdit"});return}if(_==="s"){Z({approved:!0,targetMode:"default"});return}if(_==="n"){Z({approved:!1,reason:"方案需要改进"});return}}else if(K){if(_==="y"){Z({approved:!0});return}if(_==="n"){Z({approved:!1,reason:"用户拒绝进入 Plan 模式"});return}}else if(W){if(_==="y"){Z({approved:!0});return}if(_==="n"){Z({approved:!1,reason:"用户选择停止"});return}}else{if(_==="y"){Z({approved:!0,scope:"once"});return}if(_==="s"){Z({approved:!0,scope:"session"});return}if(_==="n"){Z({approved:!1,reason:"用户拒绝"});return}}},{isActive:J});let U=UO(()=>{if(q)return[{key:"approve-auto",label:"[Y] Yes, execute with auto-edit mode",value:{approved:!0,targetMode:"autoEdit"}},{key:"approve-default",label:"[S] Yes, execute with default mode (ask for each operation)",value:{approved:!0,targetMode:"default"}},{key:"reject",label:"[N] No, keep planning",value:{approved:!1,reason:"方案需要改进"}}];if(K)return[{key:"approve",label:"[Y] Yes, enter Plan mode",value:{approved:!0}},{key:"reject",label:"[N] No, proceed directly",value:{approved:!1,reason:"用户拒绝进入 Plan 模式"}}];if(W)return[{key:"continue",label:"[Y] Yes, continue",value:{approved:!0}},{key:"stop",label:"[N] No, stop here",value:{approved:!1,reason:"用户选择停止"}}];return[{key:"approve-once",label:"[Y] Yes (once only)",value:{approved:!0,scope:"once"}},{key:"approve-session",label:"[S] Yes, remember for this project (Shift+Tab)",value:{approved:!0,scope:"session"}},{key:"reject",label:"[N] No",value:{approved:!1,reason:"用户拒绝"}}]},[q,K,W]),O=UO(()=>{if(q)return{color:"cyan",title:"\uD83D\uDD35 Plan Mode - Review Implementation Plan"};if(K)return{color:"magenta",title:"\uD83D\uDFE3 Enter Plan Mode?"};if(W)return{color:"yellow",title:"⚡ Max Turns Exceeded"};return{color:"yellow",title:"\uD83D\uDD14 Confirmation Required"}},[q,K,W]);return l0(S1,{flexDirection:"column",borderStyle:"round",borderColor:J?O.color:"gray",padding:1,children:[l0(S1,{marginBottom:1,children:l0($2,{bold:!0,color:O.color,children:O.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),l0(db,{details:$,headerColor:O.color,isPlanModeExit:q,isPlanModeEnter:K,terminalWidth:Q},void 0,!1,void 0,this),l0(S1,{flexDirection:"column",children:[l0($2,{color:"gray",children:"使用 ↑ ↓ 选择,回车确认(支持 Y/S/N 快捷键,ESC 取消)"},void 0,!1,void 0,this),l0(gb,{items:U,isFocused:J,itemComponent:ub,onSelect:(F)=>{Z(F.value)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});Y1();B8();V4();import{Box as T0,Text as O0,useInput as lb}from"ink";import FO from"ink-text-input";import{useState as E2}from"react";import{jsxDEV as p}from"react/jsx-dev-runtime";var U6=[{action:"add",description:"Add a new hook"},{action:"status",description:"Show hooks status"},{action:"list",description:"List all configured hooks"}],Z5=[{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"}],Y5=[{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"}],ib=[`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"],HO=({onClose:$,onSave:Z})=>{let Y=i$.getTheme(),[Q,X]=E2("action"),[J,G]=E2(0),[q,K]=E2(0),[W,U]=E2(0),[O,F]=E2(""),[H,_]=E2(""),[z,w]=E2(null),[B,L]=E2(!1),[N,M]=E2(null),b=U6[J],j=Y5[q],T=Z5[W],A=()=>{if(N){M(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}};lb((I,D)=>{if(D.escape){A();return}if(Q==="action"){if(D.upArrow)G((V)=>V>0?V-1:U6.length-1);else if(D.downArrow)G((V)=>V<U6.length-1?V+1:0);else if(D.return)k()}else if(Q==="event"){if(D.upArrow)K((V)=>V>0?V-1:Y5.length-1);else if(D.downArrow)K((V)=>V<Y5.length-1?V+1:0);else if(D.return)X("matcher")}else if(Q==="location"){if(D.upArrow)U((V)=>V>0?V-1:Z5.length-1);else if(D.downArrow)U((V)=>V<Z5.length-1?V+1:0);else if(D.return)X("confirm")}else if(Q==="confirm"){if(D.return)l()}});let k=()=>{let I=U6[J].action;if(I==="add")X("event");else if(I==="status")c();else if(I==="list")o()},c=()=>{let I=y0.getInstance(),D=I.isEnabled(),V=I.getConfig(),g={};for(let v of Object.values(G2)){let Z0=V[v];if(Z0&&Array.isArray(Z0)){let d=Z0.reduce((s,C)=>s+(C.hooks?.length||0),0);if(d>0)g[v]=d}}let u=[`Status: ${D?"✅ Enabled":"⏸️ Disabled"}`,""];if(Object.keys(g).length>0){u.push("Configured hooks:");for(let[v,Z0]of Object.entries(g))u.push(` ${v}: ${Z0} hook(s)`)}else u.push("No hooks configured");M(u.join(`
2836
+ `);if(v===-1)return{completedContent:"",currentLine:y};return{completedContent:y.slice(0,v+1),currentLine:y.slice(v+1)}},[y,X,B,H]),g=WO({content:"",blocks:[]}),u=Y8(()=>{if(B)return F??[];if(o)return o;if(c.current&&c.current.messageId===O)return c.current.blocks;let v=g.current;if(!X||!D.startsWith(v.content)){let C=M4(D);return g.current={content:D,blocks:C},C}if(D===v.content)return v.blocks;let Z0=D.slice(v.content.length),d=M4(Z0),s=[...v.blocks,...d];return g.current={content:D,blocks:s},s},[D,X,B,F]);return h(L0,{flexDirection:"column",marginBottom:A?1:0,flexShrink:0,children:[l&&h(L0,{flexDirection:"row",flexShrink:0,children:[h(L0,{width:b,flexShrink:0},void 0,!1,void 0,this),h(S0,{color:w.colors.text.muted,dimColor:!0,children:["↑ ",I," lines above (streaming...)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),u.map((v,Z0)=>{if(v.type==="empty")return h(L0,{height:1,flexShrink:0},Z0,!1,void 0,this);return h(L0,{flexDirection:"row",flexShrink:0,children:[Z0===0&&!G&&h(L0,{marginRight:1,flexShrink:0,children:h(S0,{color:N,bold:!0,children:M},void 0,!1,void 0,this)},void 0,!1,void 0,this),(Z0>0||G)&&h(L0,{width:b,flexShrink:0},void 0,!1,void 0,this),h(L0,{flexGrow:1,flexShrink:0,children:v.type==="code"?z?h(S0,{wrap:"wrap",children:v.content},void 0,!1,void 0,this):h(Pb,{content:v.content,language:v.language,terminalWidth:Y-b,isPending:X,availableHeight:J},void 0,!1,void 0,this):v.type==="table"&&v.tableData?h(KO,{headers:v.tableData.headers,rows:v.tableData.rows,terminalWidth:Y-b},void 0,!1,void 0,this):v.type==="heading"?h(Cb,{content:v.content,level:v.level||1},void 0,!1,void 0,this):v.type==="list"?h(hY,{type:v.listType||"ul",marker:v.marker||"-",itemText:v.content,leadingWhitespace:" ".repeat(v.indentation||0)},void 0,!1,void 0,this):v.type==="hr"?h(Sb,{terminalWidth:Y-b},void 0,!1,void 0,this):v.type==="diff"&&v.diffData?h(vY,{patch:v.diffData.patch,startLine:v.diffData.startLine,matchLine:v.diffData.matchLine,terminalWidth:Y-b},void 0,!1,void 0,this):v.type==="command-message"?h(fb,{content:v.content},void 0,!1,void 0,this):h(kb,{content:v.content},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},Z0,!0,void 0,this)}),V&&h(L0,{flexDirection:"row",flexShrink:0,children:[u.length===0&&!G?h(L0,{marginRight:1,flexShrink:0,children:h(S0,{color:N,bold:!0,children:M},void 0,!1,void 0,this)},void 0,!1,void 0,this):h(L0,{width:b,flexShrink:0},void 0,!1,void 0,this),h(L0,{flexGrow:1,flexShrink:0,children:h(S0,{wrap:"wrap",children:V},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),j&&h(L0,{flexDirection:"row",flexShrink:0,children:[h(L0,{width:b,flexShrink:0},void 0,!1,void 0,this),h(L0,{flexDirection:"column",flexGrow:1,flexShrink:0,children:[h(S0,{color:w.colors.text.muted,children:["Subtask ",typeof j.agentType==="string"?`@${j.agentType}`:"",typeof j.status==="string"?` · ${j.status}`:""]},void 0,!0,void 0,this),typeof j.summary==="string"&&j.summary.trim()!==""&&h(S0,{wrap:"wrap",children:j.summary},void 0,!1,void 0,this),typeof j.childSessionId==="string"&&h(S0,{color:w.colors.text.muted,children:["Session ",j.childSessionId]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},($,Z)=>{return $.content===Z.content&&$.role===Z.role&&$.terminalWidth===Z.terminalWidth&&$.isPending===Z.isPending&&$.availableTerminalHeight===Z.availableTerminalHeight&&$.hidePrefix===Z.hidePrefix&&$.noMargin===Z.noMargin&&$.renderPlainTextOnly===Z.renderPlainTextOnly&&$.streamingHiddenLines===Z.streamingHiddenLines&&$.streamingLines===Z.streamingLines&&$.messageId===Z.messageId&&$.metadata===Z.metadata&&$.blocksOverride===Z.blocksOverride&&$.currentLineOverride===Z.currentLineOverride&&$.streamingMode===Z.streamingMode&&$.renderCodeBlocksAsPlainText===Z.renderCodeBlocksAsPlainText});import{jsxDEV as l0,Fragment as cb}from"react/jsx-dev-runtime";var ub=mY.memo(({label:$,isSelected:Z})=>l0($2,{color:Z?"yellow":void 0,children:$},void 0,!1,void 0,this)),db=mY.memo(({details:$,headerColor:Z,isPlanModeExit:Y,isPlanModeEnter:Q,terminalWidth:X})=>l0(cb,{children:[$.title&&l0(S1,{marginBottom:1,children:l0($2,{bold:!0,children:$.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),l0(S1,{marginBottom:1,children:l0($2,{children:$.message},void 0,!1,void 0,this)},void 0,!1,void 0,this),($.planContent||$.details)&&l0(S1,{flexDirection:"column",marginBottom:1,borderStyle:"single",borderColor:Z,padding:1,children:[l0($2,{bold:!0,color:Z,children:Y?"\uD83D\uDCCB Implementation Plan:":Q?"\uD83D\uDCDD Details:":"\uD83D\uDCC4 Operation Details:"},void 0,!1,void 0,this),l0(S1,{marginTop:1,children:l0(F4,{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&&l0(S1,{flexDirection:"column",marginBottom:1,children:[l0($2,{color:"red",bold:!0,children:"⚠️ 风险提示:"},void 0,!1,void 0,this),$.risks.map((J,G)=>l0(S1,{marginLeft:2,children:l0($2,{color:"red",children:["• ",J]},void 0,!0,void 0,this)},G,!1,void 0,this))]},void 0,!0,void 0,this),$.affectedFiles&&$.affectedFiles.length>0&&l0(S1,{flexDirection:"column",marginBottom:1,children:[l0($2,{color:"yellow",children:"\uD83D\uDCC1 影响的文件:"},void 0,!1,void 0,this),$.affectedFiles.slice(0,3).map((J,G)=>l0(S1,{marginLeft:2,children:l0($2,{children:["• ",J]},void 0,!0,void 0,this)},G,!1,void 0,this)),$.affectedFiles.length>3&&l0(S1,{marginLeft:2,children:l0($2,{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)),OO=mY.memo(({details:$,onResponse:Z})=>{let{stdout:Y}=mb(),Q=Y.columns||80,J=q1()==="confirmation-prompt",G=Q$(!1),q=$.type==="exitPlanMode",K=$.type==="enterPlanMode",W=$.type==="maxTurnsExceeded";pb((F,H)=>{if(H.ctrl&&F==="c"||H.meta&&F==="c"){G();return}if(H.escape){Z({approved:!1,reason:"用户取消"});return}let _=F.toLowerCase();if(q){if(_==="y"){Z({approved:!0,targetMode:"autoEdit"});return}if(_==="s"){Z({approved:!0,targetMode:"default"});return}if(_==="n"){Z({approved:!1,reason:"方案需要改进"});return}}else if(K){if(_==="y"){Z({approved:!0});return}if(_==="n"){Z({approved:!1,reason:"用户拒绝进入 Plan 模式"});return}}else if(W){if(_==="y"){Z({approved:!0});return}if(_==="n"){Z({approved:!1,reason:"用户选择停止"});return}}else{if(_==="y"){Z({approved:!0,scope:"once"});return}if(_==="s"){Z({approved:!0,scope:"session"});return}if(_==="n"){Z({approved:!1,reason:"用户拒绝"});return}}},{isActive:J});let U=UO(()=>{if(q)return[{key:"approve-auto",label:"[Y] Yes, execute with auto-edit mode",value:{approved:!0,targetMode:"autoEdit"}},{key:"approve-default",label:"[S] Yes, execute with default mode (ask for each operation)",value:{approved:!0,targetMode:"default"}},{key:"reject",label:"[N] No, keep planning",value:{approved:!1,reason:"方案需要改进"}}];if(K)return[{key:"approve",label:"[Y] Yes, enter Plan mode",value:{approved:!0}},{key:"reject",label:"[N] No, proceed directly",value:{approved:!1,reason:"用户拒绝进入 Plan 模式"}}];if(W)return[{key:"continue",label:"[Y] Yes, continue",value:{approved:!0}},{key:"stop",label:"[N] No, stop here",value:{approved:!1,reason:"用户选择停止"}}];return[{key:"approve-once",label:"[Y] Yes (once only)",value:{approved:!0,scope:"once"}},{key:"approve-session",label:"[S] Yes, remember for this project (Shift+Tab)",value:{approved:!0,scope:"session"}},{key:"reject",label:"[N] No",value:{approved:!1,reason:"用户拒绝"}}]},[q,K,W]),O=UO(()=>{if(q)return{color:"cyan",title:"\uD83D\uDD35 Plan Mode - Review Implementation Plan"};if(K)return{color:"magenta",title:"\uD83D\uDFE3 Enter Plan Mode?"};if(W)return{color:"yellow",title:"⚡ Max Turns Exceeded"};return{color:"yellow",title:"\uD83D\uDD14 Confirmation Required"}},[q,K,W]);return l0(S1,{flexDirection:"column",borderStyle:"round",borderColor:J?O.color:"gray",padding:1,children:[l0(S1,{marginBottom:1,children:l0($2,{bold:!0,color:O.color,children:O.title},void 0,!1,void 0,this)},void 0,!1,void 0,this),l0(db,{details:$,headerColor:O.color,isPlanModeExit:q,isPlanModeEnter:K,terminalWidth:Q},void 0,!1,void 0,this),l0(S1,{flexDirection:"column",children:[l0($2,{color:"gray",children:"使用 ↑ ↓ 选择,回车确认(支持 Y/S/N 快捷键,ESC 取消)"},void 0,!1,void 0,this),l0(gb,{items:U,isFocused:J,itemComponent:ub,onSelect:(F)=>{Z(F.value)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});Y1();B8();V4();import{Box as T0,Text as O0,useInput as lb}from"ink";import FO from"ink-text-input";import{useState as E2}from"react";import{jsxDEV as p}from"react/jsx-dev-runtime";var U7=[{action:"add",description:"Add a new hook"},{action:"status",description:"Show hooks status"},{action:"list",description:"List all configured hooks"}],Z5=[{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"}],Y5=[{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"}],ib=[`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"],HO=({onClose:$,onSave:Z})=>{let Y=i$.getTheme(),[Q,X]=E2("action"),[J,G]=E2(0),[q,K]=E2(0),[W,U]=E2(0),[O,F]=E2(""),[H,_]=E2(""),[z,w]=E2(null),[B,L]=E2(!1),[N,M]=E2(null),b=U7[J],j=Y5[q],T=Z5[W],A=()=>{if(N){M(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}};lb((I,D)=>{if(D.escape){A();return}if(Q==="action"){if(D.upArrow)G((V)=>V>0?V-1:U7.length-1);else if(D.downArrow)G((V)=>V<U7.length-1?V+1:0);else if(D.return)k()}else if(Q==="event"){if(D.upArrow)K((V)=>V>0?V-1:Y5.length-1);else if(D.downArrow)K((V)=>V<Y5.length-1?V+1:0);else if(D.return)X("matcher")}else if(Q==="location"){if(D.upArrow)U((V)=>V>0?V-1:Z5.length-1);else if(D.downArrow)U((V)=>V<Z5.length-1?V+1:0);else if(D.return)X("confirm")}else if(Q==="confirm"){if(D.return)l()}});let k=()=>{let I=U7[J].action;if(I==="add")X("event");else if(I==="status")c();else if(I==="list")o()},c=()=>{let I=y0.getInstance(),D=I.isEnabled(),V=I.getConfig(),g={};for(let v of Object.values(G2)){let Z0=V[v];if(Z0&&Array.isArray(Z0)){let d=Z0.reduce((s,C)=>s+(C.hooks?.length||0),0);if(d>0)g[v]=d}}let u=[`Status: ${D?"✅ Enabled":"⏸️ Disabled"}`,""];if(Object.keys(g).length>0){u.push("Configured hooks:");for(let[v,Z0]of Object.entries(g))u.push(` ${v}: ${Z0} hook(s)`)}else u.push("No hooks configured");M(u.join(`
2837
2837
  `))},o=()=>{let D=y0.getInstance().getConfig(),V=[],g=!1;for(let u of Object.values(G2)){let v=D[u];if(!v||!Array.isArray(v)||v.length===0)continue;g=!0,V.push(`${u}:`);for(let Z0 of v){let d=Z0.matcher,s="all";if(d?.tools)s=`tools: ${Array.isArray(d.tools)?d.tools.join(", "):d.tools}`;V.push(` [${s}]`);for(let C of Z0.hooks||[])if(C.type==="command")V.push(` → ${C.command}`)}V.push("")}if(!g)V.push("No hooks configured"),V.push(""),V.push("Configure hooks in .blade/settings.local.json");M(V.join(`
2838
- `))},S=()=>{X("command")},y=()=>{if(!H.trim()){w("Command cannot be empty");return}w(null),X("location")},l=async()=>{L(!0),w(null);try{let I=y0.getInstance(),D=await import("node:fs/promises"),V=await import("node:path"),g=await import("node:os"),u={matcher:O.trim()?{tools:O.trim()}:{},hooks:[{type:"command",command:H.trim()}]},v;switch(T.location){case"local":v=V.join(process.cwd(),".blade","settings.local.json");break;case"project":v=V.join(process.cwd(),".blade","settings.json");break;case"user":v=V.join(g.homedir(),".blade","settings.json");break}await D.mkdir(V.dirname(v),{recursive:!0});let Z0={};try{let i=await D.readFile(v,"utf-8");Z0=JSON.parse(i)}catch{}let d=Z0.hooks||{},s=d[j.event]||[],C={...d,enabled:!0,[j.event]:[...s,u]};if(Z0.hooks=C,await D.writeFile(v,JSON.stringify(Z0,null,2),"utf-8"),await I.reloadConfig(),Z)Z({event:j.event,matcher:O.trim(),command:H.trim()});$()}catch(I){w(`Failed to save hook: ${I instanceof Error?I.message:"Unknown error"}`),L(!1)}};return p(T0,{flexDirection:"column",padding:1,children:[p(T0,{marginBottom:1,children:p(O0,{bold:!0,color:Y.colors.success,children:"Hooks Manager"},void 0,!1,void 0,this)},void 0,!1,void 0,this),p(T0,{marginBottom:1,children:p(O0,{color:Y.colors.warning,children:"⚠ Hooks execute shell commands with your full user permissions. Only use hooks from trusted sources."},void 0,!1,void 0,this)},void 0,!1,void 0,this),N&&p(T0,{flexDirection:"column",marginBottom:1,children:[p(O0,{children:N},void 0,!1,void 0,this),p(T0,{marginTop:1,children:p(O0,{color:Y.colors.muted,children:"Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="action"&&!N&&p(T0,{flexDirection:"column",children:[p(T0,{flexDirection:"column",marginTop:1,children:U6.map((I,D)=>p(T0,{children:[p(O0,{color:D===J?Y.colors.primary:void 0,bold:D===J,children:[D===J?"❯ ":" ",I.action]},void 0,!0,void 0,this),p(O0,{color:Y.colors.muted,children:[" - ",I.description]},void 0,!0,void 0,this)]},I.action,!0,void 0,this))},void 0,!1,void 0,this),p(T0,{marginTop:1,children:p(O0,{color:Y.colors.muted,children:"↑/↓ to select · Enter to continue · Esc to close"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="event"&&p(T0,{flexDirection:"column",children:[p(O0,{bold:!0,children:"Select Event:"},void 0,!1,void 0,this),p(T0,{flexDirection:"column",marginTop:1,children:Y5.map((I,D)=>p(T0,{children:[p(O0,{color:D===q?Y.colors.primary:void 0,bold:D===q,children:[D===q?"❯ ":" ",I.event]},void 0,!0,void 0,this),p(O0,{color:Y.colors.muted,children:[" - ",I.description]},void 0,!0,void 0,this)]},I.event,!0,void 0,this))},void 0,!1,void 0,this),p(T0,{marginTop:1,children:p(O0,{color:Y.colors.muted,children:"↑/↓ to select · Enter to continue · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q!=="event"&&p(T0,{marginBottom:1,children:p(O0,{children:["Event:"," ",p(O0,{bold:!0,color:Y.colors.primary,children:j.event},void 0,!1,void 0,this),p(O0,{color:Y.colors.muted,children:[" - ",j.description]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),(Q==="matcher"||Q==="command"||Q==="confirm")&&p(T0,{flexDirection:"column",marginBottom:1,children:[p(O0,{color:Y.colors.muted,children:"Input to command is JSON of tool call arguments."},void 0,!1,void 0,this),p(O0,{color:Y.colors.muted,children:"Exit code 0 - stdout/stderr not shown"},void 0,!1,void 0,this),p(O0,{color:Y.colors.muted,children:"Exit code 2 - show stderr to model and block tool call"},void 0,!1,void 0,this),p(O0,{color:Y.colors.muted,children:"Other exit codes - show stderr to user only but continue with tool call"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="matcher"&&p(T0,{flexDirection:"column",children:[p(T0,{children:[p(O0,{bold:!0,children:"Matcher: "},void 0,!1,void 0,this),p(FO,{value:O,onChange:F,onSubmit:S,placeholder:"e.g., Read, Bash, Edit|Write (empty = all tools)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p(T0,{marginTop:1,children:p(O0,{color:Y.colors.muted,children:"Tool name pattern (supports | for multiple). Leave empty to match all."},void 0,!1,void 0,this)},void 0,!1,void 0,this),p(T0,{marginTop:1,children:p(O0,{color:Y.colors.muted,children:"Enter to continue · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),(Q==="command"||Q==="confirm")&&p(T0,{marginBottom:1,children:p(O0,{children:["Matcher: ",p(O0,{bold:!0,children:O||"(all tools)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q==="command"&&p(T0,{flexDirection:"column",children:[p(T0,{children:p(O0,{bold:!0,children:"Command: "},void 0,!1,void 0,this)},void 0,!1,void 0,this),p(T0,{borderStyle:"single",borderColor:Y.colors.border.light,paddingX:1,marginTop:1,children:p(FO,{value:H,onChange:_,onSubmit:y,placeholder:"Enter shell command..."},void 0,!1,void 0,this)},void 0,!1,void 0,this),p(T0,{flexDirection:"column",marginTop:1,children:[p(O0,{bold:!0,children:"Examples:"},void 0,!1,void 0,this),ib.map((I,D)=>p(O0,{color:Y.colors.muted,children:["• ",I]},D,!0,void 0,this))]},void 0,!0,void 0,this),p(T0,{marginTop:1,children:p(O0,{color:Y.colors.muted,children:"Enter to continue · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="location"&&p(T0,{flexDirection:"column",children:[p(T0,{flexDirection:"column",borderStyle:"round",borderColor:Y.colors.border.light,paddingX:2,paddingY:1,marginBottom:1,children:[p(O0,{bold:!0,color:Y.colors.primary,children:"Save hook configuration"},void 0,!1,void 0,this),p(O0,{children:" "},void 0,!1,void 0,this),p(O0,{children:[" ","Event: ",j.event," - ",j.description]},void 0,!0,void 0,this),p(O0,{children:[" Matcher: ",O||"(all)"]},void 0,!0,void 0,this),p(O0,{children:[" Command: ",H]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),p(O0,{bold:!0,children:"Where should this hook be saved?"},void 0,!1,void 0,this),p(T0,{flexDirection:"column",marginTop:1,children:Z5.map((I,D)=>p(T0,{children:[p(O0,{color:D===W?Y.colors.primary:void 0,bold:D===W,children:[D===W?"❯ ":" ",D+1,". ",I.name]},void 0,!0,void 0,this),p(O0,{color:Y.colors.muted,children:[" ",I.description]},void 0,!0,void 0,this)]},I.location,!0,void 0,this))},void 0,!1,void 0,this),p(T0,{marginTop:1,children:p(O0,{color:Y.colors.muted,children:"Enter to confirm · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="confirm"&&p(T0,{flexDirection:"column",children:[p(T0,{flexDirection:"column",borderStyle:"round",borderColor:Y.colors.success,paddingX:2,paddingY:1,children:[p(O0,{bold:!0,children:["Saving hook to ",T.description,"..."]},void 0,!0,void 0,this),p(O0,{children:" "},void 0,!1,void 0,this),p(O0,{children:["Event: ",j.event]},void 0,!0,void 0,this),p(O0,{children:["Matcher: ",O||"(all tools)"]},void 0,!0,void 0,this),p(O0,{children:["Command: ",H]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),p(T0,{marginTop:1,children:p(O0,{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&&p(T0,{marginTop:1,children:p(O0,{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 VO}from"ahooks";import{Box as QR,Text as XR}from"ink";import JR from"react";import{useMemoizedFn as sb}from"ahooks";import X8 from"chalk";import{Text as tb,useInput as eb}from"ink";import{useEffect as dY,useRef as cY}from"react";var I2={TIMEOUT_MS:100,RAPID_INPUT_THRESHOLD_MS:150,LARGE_INPUT_THRESHOLD:300,MEDIUM_SIZE_MULTI_CHUNK_THRESHOLD:200};import{execSync as Y3}from"node:child_process";import{existsSync as rb,readFileSync as gY}from"node:fs";import{basename as _O,isAbsolute as ab}from"node:path";function zO($){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 BO(){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 nb(){let{commands:$}=BO();try{return Y3($.getPath,{encoding:"utf-8"}).trim()}catch(Z){return console.error("Failed to get clipboard path:",Z),null}}function wO($){if($.startsWith('"')&&$.endsWith('"')||$.startsWith("'")&&$.endsWith("'"))return $.slice(1,-1);return $}function LO($){if(process.platform==="win32")return $;let Z="__DOUBLE_BACKSLASH__";return $.replace(/\\\\/g,Z).replace(/\\(.)/g,"$1").replace(new RegExp(Z,"g"),"\\")}function uY($){let Z=wO($.trim()),Y=LO(Z);return/\.(png|jpe?g|gif|webp)$/i.test(Y)}function ob($){let Z=wO($.trim()),Y=LO(Z);if(uY(Y))return Y;return null}async function NO($){let Z=ob($);if(!Z)return null;let Y;try{if(ab(Z))Y=gY(Z);else{let G=nb();if(G&&Z===_O(G))Y=gY(G);else return null}}catch(G){return console.error("Failed to read image file:",G),null}let Q=Y.toString("base64"),X=zO(Q),J=_O(Z);return{path:Z,base64:Q,mediaType:X,filename:J}}async function AO(){let $=process.platform,Z={darwin:"pbpaste",linux:"xclip -selection clipboard -o || wl-paste",win32:'powershell -Command "Get-Clipboard"'},Y=Z[$]||Z.linux;try{return Y3(Y,{encoding:"utf-8"})||null}catch{return null}}async function bO(){let{commands:$,screenshotPath:Z}=BO();try{if(Y3($.checkImage,{stdio:"ignore"}),Y3($.saveImage(Z),{stdio:"ignore"}),!rb(Z))return null;let Q=gY(Z).toString("base64"),X=zO(Q);return Y3($.deleteFile(Z),{stdio:"ignore"}),{base64:Q,mediaType:X}}catch(Y){try{Y3($.deleteFile(Z),{stdio:"ignore"})}catch{}return null}}import{jsxDEV as YR}from"react/jsx-dev-runtime";var $R=/\r\n/g,ZR=/\r/g;function J8($){if(!$.includes("\r"))return $;return $.replace($R,`
2838
+ `))},S=()=>{X("command")},y=()=>{if(!H.trim()){w("Command cannot be empty");return}w(null),X("location")},l=async()=>{L(!0),w(null);try{let I=y0.getInstance(),D=await import("node:fs/promises"),V=await import("node:path"),g=await import("node:os"),u={matcher:O.trim()?{tools:O.trim()}:{},hooks:[{type:"command",command:H.trim()}]},v;switch(T.location){case"local":v=V.join(process.cwd(),".blade","settings.local.json");break;case"project":v=V.join(process.cwd(),".blade","settings.json");break;case"user":v=V.join(g.homedir(),".blade","settings.json");break}await D.mkdir(V.dirname(v),{recursive:!0});let Z0={};try{let i=await D.readFile(v,"utf-8");Z0=JSON.parse(i)}catch{}let d=Z0.hooks||{},s=d[j.event]||[],C={...d,enabled:!0,[j.event]:[...s,u]};if(Z0.hooks=C,await D.writeFile(v,JSON.stringify(Z0,null,2),"utf-8"),await I.reloadConfig(),Z)Z({event:j.event,matcher:O.trim(),command:H.trim()});$()}catch(I){w(`Failed to save hook: ${I instanceof Error?I.message:"Unknown error"}`),L(!1)}};return p(T0,{flexDirection:"column",padding:1,children:[p(T0,{marginBottom:1,children:p(O0,{bold:!0,color:Y.colors.success,children:"Hooks Manager"},void 0,!1,void 0,this)},void 0,!1,void 0,this),p(T0,{marginBottom:1,children:p(O0,{color:Y.colors.warning,children:"⚠ Hooks execute shell commands with your full user permissions. Only use hooks from trusted sources."},void 0,!1,void 0,this)},void 0,!1,void 0,this),N&&p(T0,{flexDirection:"column",marginBottom:1,children:[p(O0,{children:N},void 0,!1,void 0,this),p(T0,{marginTop:1,children:p(O0,{color:Y.colors.muted,children:"Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="action"&&!N&&p(T0,{flexDirection:"column",children:[p(T0,{flexDirection:"column",marginTop:1,children:U7.map((I,D)=>p(T0,{children:[p(O0,{color:D===J?Y.colors.primary:void 0,bold:D===J,children:[D===J?"❯ ":" ",I.action]},void 0,!0,void 0,this),p(O0,{color:Y.colors.muted,children:[" - ",I.description]},void 0,!0,void 0,this)]},I.action,!0,void 0,this))},void 0,!1,void 0,this),p(T0,{marginTop:1,children:p(O0,{color:Y.colors.muted,children:"↑/↓ to select · Enter to continue · Esc to close"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="event"&&p(T0,{flexDirection:"column",children:[p(O0,{bold:!0,children:"Select Event:"},void 0,!1,void 0,this),p(T0,{flexDirection:"column",marginTop:1,children:Y5.map((I,D)=>p(T0,{children:[p(O0,{color:D===q?Y.colors.primary:void 0,bold:D===q,children:[D===q?"❯ ":" ",I.event]},void 0,!0,void 0,this),p(O0,{color:Y.colors.muted,children:[" - ",I.description]},void 0,!0,void 0,this)]},I.event,!0,void 0,this))},void 0,!1,void 0,this),p(T0,{marginTop:1,children:p(O0,{color:Y.colors.muted,children:"↑/↓ to select · Enter to continue · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q!=="event"&&p(T0,{marginBottom:1,children:p(O0,{children:["Event:"," ",p(O0,{bold:!0,color:Y.colors.primary,children:j.event},void 0,!1,void 0,this),p(O0,{color:Y.colors.muted,children:[" - ",j.description]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),(Q==="matcher"||Q==="command"||Q==="confirm")&&p(T0,{flexDirection:"column",marginBottom:1,children:[p(O0,{color:Y.colors.muted,children:"Input to command is JSON of tool call arguments."},void 0,!1,void 0,this),p(O0,{color:Y.colors.muted,children:"Exit code 0 - stdout/stderr not shown"},void 0,!1,void 0,this),p(O0,{color:Y.colors.muted,children:"Exit code 2 - show stderr to model and block tool call"},void 0,!1,void 0,this),p(O0,{color:Y.colors.muted,children:"Other exit codes - show stderr to user only but continue with tool call"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="matcher"&&p(T0,{flexDirection:"column",children:[p(T0,{children:[p(O0,{bold:!0,children:"Matcher: "},void 0,!1,void 0,this),p(FO,{value:O,onChange:F,onSubmit:S,placeholder:"e.g., Read, Bash, Edit|Write (empty = all tools)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),p(T0,{marginTop:1,children:p(O0,{color:Y.colors.muted,children:"Tool name pattern (supports | for multiple). Leave empty to match all."},void 0,!1,void 0,this)},void 0,!1,void 0,this),p(T0,{marginTop:1,children:p(O0,{color:Y.colors.muted,children:"Enter to continue · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),(Q==="command"||Q==="confirm")&&p(T0,{marginBottom:1,children:p(O0,{children:["Matcher: ",p(O0,{bold:!0,children:O||"(all tools)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Q==="command"&&p(T0,{flexDirection:"column",children:[p(T0,{children:p(O0,{bold:!0,children:"Command: "},void 0,!1,void 0,this)},void 0,!1,void 0,this),p(T0,{borderStyle:"single",borderColor:Y.colors.border.light,paddingX:1,marginTop:1,children:p(FO,{value:H,onChange:_,onSubmit:y,placeholder:"Enter shell command..."},void 0,!1,void 0,this)},void 0,!1,void 0,this),p(T0,{flexDirection:"column",marginTop:1,children:[p(O0,{bold:!0,children:"Examples:"},void 0,!1,void 0,this),ib.map((I,D)=>p(O0,{color:Y.colors.muted,children:["• ",I]},D,!0,void 0,this))]},void 0,!0,void 0,this),p(T0,{marginTop:1,children:p(O0,{color:Y.colors.muted,children:"Enter to continue · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="location"&&p(T0,{flexDirection:"column",children:[p(T0,{flexDirection:"column",borderStyle:"round",borderColor:Y.colors.border.light,paddingX:2,paddingY:1,marginBottom:1,children:[p(O0,{bold:!0,color:Y.colors.primary,children:"Save hook configuration"},void 0,!1,void 0,this),p(O0,{children:" "},void 0,!1,void 0,this),p(O0,{children:[" ","Event: ",j.event," - ",j.description]},void 0,!0,void 0,this),p(O0,{children:[" Matcher: ",O||"(all)"]},void 0,!0,void 0,this),p(O0,{children:[" Command: ",H]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),p(O0,{bold:!0,children:"Where should this hook be saved?"},void 0,!1,void 0,this),p(T0,{flexDirection:"column",marginTop:1,children:Z5.map((I,D)=>p(T0,{children:[p(O0,{color:D===W?Y.colors.primary:void 0,bold:D===W,children:[D===W?"❯ ":" ",D+1,". ",I.name]},void 0,!0,void 0,this),p(O0,{color:Y.colors.muted,children:[" ",I.description]},void 0,!0,void 0,this)]},I.location,!0,void 0,this))},void 0,!1,void 0,this),p(T0,{marginTop:1,children:p(O0,{color:Y.colors.muted,children:"Enter to confirm · Esc to go back"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q==="confirm"&&p(T0,{flexDirection:"column",children:[p(T0,{flexDirection:"column",borderStyle:"round",borderColor:Y.colors.success,paddingX:2,paddingY:1,children:[p(O0,{bold:!0,children:["Saving hook to ",T.description,"..."]},void 0,!0,void 0,this),p(O0,{children:" "},void 0,!1,void 0,this),p(O0,{children:["Event: ",j.event]},void 0,!0,void 0,this),p(O0,{children:["Matcher: ",O||"(all tools)"]},void 0,!0,void 0,this),p(O0,{children:["Command: ",H]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),p(T0,{marginTop:1,children:p(O0,{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&&p(T0,{marginTop:1,children:p(O0,{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 VO}from"ahooks";import{Box as QR,Text as XR}from"ink";import JR from"react";import{useMemoizedFn as sb}from"ahooks";import X8 from"chalk";import{Text as tb,useInput as eb}from"ink";import{useEffect as dY,useRef as cY}from"react";var I2={TIMEOUT_MS:100,RAPID_INPUT_THRESHOLD_MS:150,LARGE_INPUT_THRESHOLD:300,MEDIUM_SIZE_MULTI_CHUNK_THRESHOLD:200};import{execSync as Y3}from"node:child_process";import{existsSync as rb,readFileSync as gY}from"node:fs";import{basename as _O,isAbsolute as ab}from"node:path";function zO($){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 BO(){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 nb(){let{commands:$}=BO();try{return Y3($.getPath,{encoding:"utf-8"}).trim()}catch(Z){return console.error("Failed to get clipboard path:",Z),null}}function wO($){if($.startsWith('"')&&$.endsWith('"')||$.startsWith("'")&&$.endsWith("'"))return $.slice(1,-1);return $}function LO($){if(process.platform==="win32")return $;let Z="__DOUBLE_BACKSLASH__";return $.replace(/\\\\/g,Z).replace(/\\(.)/g,"$1").replace(new RegExp(Z,"g"),"\\")}function uY($){let Z=wO($.trim()),Y=LO(Z);return/\.(png|jpe?g|gif|webp)$/i.test(Y)}function ob($){let Z=wO($.trim()),Y=LO(Z);if(uY(Y))return Y;return null}async function NO($){let Z=ob($);if(!Z)return null;let Y;try{if(ab(Z))Y=gY(Z);else{let G=nb();if(G&&Z===_O(G))Y=gY(G);else return null}}catch(G){return console.error("Failed to read image file:",G),null}let Q=Y.toString("base64"),X=zO(Q),J=_O(Z);return{path:Z,base64:Q,mediaType:X,filename:J}}async function AO(){let $=process.platform,Z={darwin:"pbpaste",linux:"xclip -selection clipboard -o || wl-paste",win32:'powershell -Command "Get-Clipboard"'},Y=Z[$]||Z.linux;try{return Y3(Y,{encoding:"utf-8"})||null}catch{return null}}async function bO(){let{commands:$,screenshotPath:Z}=BO();try{if(Y3($.checkImage,{stdio:"ignore"}),Y3($.saveImage(Z),{stdio:"ignore"}),!rb(Z))return null;let Q=gY(Z).toString("base64"),X=zO(Q);return Y3($.deleteFile(Z),{stdio:"ignore"}),{base64:Q,mediaType:X}}catch(Y){try{Y3($.deleteFile(Z),{stdio:"ignore"})}catch{}return null}}import{jsxDEV as YR}from"react/jsx-dev-runtime";var $R=/\r\n/g,ZR=/\r/g;function J8($){if(!$.includes("\r"))return $;return $.replace($R,`
2839
2839
  `).replace(ZR,`
2840
2840
  `)}function G8($,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 RO({value:$,placeholder:Z="",focus:Y=!0,onChange:Q,cursorPosition:X,onChangeCursorPosition:J,onPaste:G,onImagePaste:q,disabledKeys:K=[]}){let W=cY({chunks:[],timeoutId:null,firstInputTime:null,lastInputTime:null,totalLength:0}),U=cY($),O=cY(X);dY(()=>{U.current=$,O.current=X},[$,X]),dY(()=>{return()=>{if(W.current.timeoutId)clearTimeout(W.current.timeoutId)}},[]),dY(()=>{if(X>$.length)J($.length)},[$,X,J]);let F=sb(()=>{let w=W.current;if(w.timeoutId)clearTimeout(w.timeoutId);let B=setTimeout(async()=>{let L=W.current.chunks,N=W.current.totalLength;if(L.length===0)return;let M=J8(L.join(""));W.current={chunks:[],timeoutId:null,firstInputTime:null,lastInputTime:null,totalLength:0};let b=U.current,j=O.current;if(q&&uY(M))try{let S=await NO(M);if(S){let y=await q(S.base64,S.mediaType,S.filename);if(y?.prompt){let l=J8(y.prompt),{newValue:I,newCursorPosition:D}=G8(l,b,j);Q(I),J(D)}return}}catch(S){console.error("Failed to process image path:",S)}let T=M.includes(`
2841
2841
  `),A=N>I2.MEDIUM_SIZE_MULTI_CHUNK_THRESHOLD&&L.length>3;if((N>I2.LARGE_INPUT_THRESHOLD||T||A)&&G){let S=await G(M);if(S?.prompt){let y=J8(S.prompt),{newValue:l,newCursorPosition:I}=G8(y,b,j);Q(l),J(I);return}}let{newValue:c,newCursorPosition:o}=G8(M,b,j);Q(c),J(o)},I2.TIMEOUT_MS);W.current.timeoutId=B});eb((w,B)=>{let L=J8(w);if(K.some((A)=>B[A])||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 M=Date.now(),b=W.current,j=X,T=$;if(B.leftArrow)j--;else if(B.rightArrow)j++;else if(B.backspace||B.delete){if(w===""){if(X>0)T=$.slice(0,X-1)+$.slice(X,$.length),j--}else if(X<$.length)T=$.slice(0,X)+$.slice(X+1,$.length)}else if(B.ctrl&&L==="a")j=0;else if(B.ctrl&&L==="e")j=$.length;else if(B.ctrl&&L==="k")T=$.slice(0,X);else if(B.ctrl&&L==="u")T=$.slice(X),j=0;else if(B.ctrl&&L==="w"){let k=$.slice(0,X).match(/\s*\S+\s*$/);if(k){let c=k[0].length;T=$.slice(0,X-c)+$.slice(X),j-=c}}else if(B.ctrl&&L==="v"){let A=process.platform==="darwin";(async()=>{if(q){let c=await bO();if(c){let o=await q(c.base64,c.mediaType,"clipboard.png");if(o?.prompt){let S=J8(o.prompt),{newValue:y,newCursorPosition:l}=G8(S,U.current,O.current);Q(y),J(l)}return}}if(A)return;let k=await AO();if(k){let c=J8(k),o=c.includes(`
2842
2842
  `),S=c.length>I2.LARGE_INPUT_THRESHOLD;if((o||S)&&G){let I=await G(c);if(I?.prompt){let D=J8(I.prompt),{newValue:V,newCursorPosition:g}=G8(D,U.current,O.current);Q(V),J(g);return}}let{newValue:y,newCursorPosition:l}=G8(c,U.current,O.current);Q(y),J(l)}})().catch(()=>{});return}else if(B.pageUp)j=0;else if(B.pageDown)j=$.length;else if(L===`
2843
2843
  `&&(B.shift||B.meta)){let{newValue:A,newCursorPosition:k}=G8(L,$,X);Q(A),J(k);return}else if(!B.ctrl&&!B.meta){if(!b.firstInputTime)b.firstInputTime=M;b.lastInputTime=M;let A=M-(b.firstInputTime||M),k=L.length>I2.LARGE_INPUT_THRESHOLD,c=L.includes(`
2844
2844
  `)&&L.length>1,o=A<I2.RAPID_INPUT_THRESHOLD_MS&&b.chunks.length>0,S=A<I2.RAPID_INPUT_THRESHOLD_MS&&L.length>10,y=b.timeoutId!==null;if(G&&(k||c||o||S||y)){b.chunks.push(L),b.totalLength+=L.length,F();return}if(L.length===1&&!b.timeoutId)b.chunks=[],b.firstInputTime=null,b.lastInputTime=null,b.totalLength=0;T=$.slice(0,X)+L+$.slice(X,$.length),j+=L.length}if(j<0)j=0;if(j>T.length)j=T.length;if(T!==$)Q(T);if(j!==X)J(j)},{isActive:Y});let H=Y,_=$,z=Z?X8.grey(Z):void 0;if(H)if(z=Z.length>0?X8.inverse(Z[0])+X8.grey(Z.slice(1)):X8.inverse(" "),$.length===0)_=X8.inverse(" ");else{_="";for(let w=0;w<$.length;w++)if(w===X&&X<$.length)_+=X8.inverse($[w]);else _+=$[w];if(X>=$.length)_+=X8.inverse(" ")}return YR(tb,{children:Z?$.length>0?_:z:_},void 0,!1,void 0,this)}import{jsxDEV as lY}from"react/jsx-dev-runtime";var MO=JR.memo(({input:$,cursorPosition:Z,onChange:Y,onChangeCursorPosition:Q,onAddPasteMapping:X,onAddImagePasteMapping:J})=>{let q=q1()==="main-input",K=VO((U)=>{let O=U.split(`
2845
- `).length,F=U.length,H=500,_=10;if(F>500||O>10){let z=X(U),w=U.slice(0,30).replace(/\n/g," "),B=`${F} chars, ${O} lines: ${w}...`;return{prompt:`${l7(z)}${B}${BY()}`}}return{}}),W=VO(async(U,O,F)=>{try{let H=J(U,O);return{prompt:`${l7(H)}[Image #${H}]${BY()}`}}catch(H){return console.error("[Image Paste] Failed to process image:",H),{prompt:`[Image paste failed: ${H instanceof Error?H.message:"Unknown error"}] `}}});return lY(QR,{flexDirection:"row",width:"100%",paddingX:2,paddingY:0,flexShrink:0,flexGrow:0,overflow:"hidden",borderStyle:"round",borderColor:"gray",children:[lY(XR,{color:"blue",bold:!0,children:"> "},void 0,!1,void 0,this),lY(RO,{value:$,cursorPosition:Z,onChange:Y,onChangeCursorPosition:Q,onPaste:K,onImagePaste:W,placeholder:" 输入命令...",focus:q,disabledKeys:["upArrow","downArrow","tab","return","escape"]},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});import{Box as Q5,Text as Z2}from"ink";import UR,{useEffect as OR,useState as FR}from"react";import{useEffect as WR,useState as TO}from"react";import{useEffect as GR,useState as qR}from"react";var KR=15000,DO=["炼化代码灵气...","参悟 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 广纳贤才..."],jO=["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 yO($,Z,Y=!1){let[Q,X]=qR("");return GR(()=>{if(Z){X("等待用户确认...");return}if(!$){X("");return}if(Y)return;let J=()=>{if(Math.random()<0.16666666666666666){let W=Math.floor(Math.random()*jO.length);return jO[W]}let K=Math.floor(Math.random()*DO.length);return DO[K]};X(J());let G=setInterval(()=>{X(J())},KR);return()=>{clearInterval(G)}},[$,Z,Y]),Q}function EO($,Z=!1,Y=!1){let[Q,X]=TO(0),[J,G]=TO(null),q=yO($,Z,Y);return WR(()=>{if(!$){X(0),G(null);return}if(Y)return;if(J===null)G(Date.now());let K=setInterval(()=>{if(J!==null){let W=Math.floor((Date.now()-J)/1000);X(W)}},1000);return()=>{clearInterval(K)}},[$,J,Y]),{currentPhrase:q,elapsedTime:Q}}import{jsxDEV as g$,Fragment as _R}from"react/jsx-dev-runtime";var iY=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"],HR=80;function IO($){if($<60)return`${$}s`;let Z=Math.floor($/60),Y=$%60;return`${Z}m ${Y}s`}var vO=UR.memo(({message:$,paused:Z=!1})=>{let Y=U4(),Q=p7(),X=Y||!Q,[J,G]=FR(0),q=d0(),W=o8()>=HR,{currentPhrase:U,elapsedTime:O}=EO(X,!1,Z);if(OR(()=>{if(!X||Z){G(0);return}let H=setInterval(()=>{G((_)=>(_+1)%iY.length)},80);return()=>clearInterval(H)},[X,Z]),!X)return null;let F=U||$||"正在思考中...";if(W)return g$(Q5,{paddingX:2,paddingBottom:1,flexDirection:"row",gap:1,children:[g$(Z2,{color:q.colors.warning,bold:!0,children:iY[J]},void 0,!1,void 0,this),g$(Z2,{color:q.colors.text.primary,children:F},void 0,!1,void 0,this),O>0&&g$(_R,{children:[g$(Z2,{color:q.colors.muted,children:"|"},void 0,!1,void 0,this),g$(Z2,{color:q.colors.info,children:["已用时: ",IO(O)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),g$(Z2,{color:q.colors.muted,children:"|"},void 0,!1,void 0,this),g$(Z2,{color:q.colors.secondary,children:"Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return g$(Q5,{paddingX:2,paddingBottom:1,flexDirection:"column",children:[g$(Q5,{flexDirection:"row",gap:1,children:[g$(Z2,{color:q.colors.warning,bold:!0,children:iY[J]},void 0,!1,void 0,this),g$(Z2,{color:q.colors.text.primary,children:F},void 0,!1,void 0,this)]},void 0,!0,void 0,this),O>0&&g$(Q5,{marginLeft:2,flexDirection:"row",gap:1,children:[g$(Z2,{color:q.colors.info,children:["已用时: ",IO(O)]},void 0,!0,void 0,this),g$(Z2,{color:q.colors.muted,children:"|"},void 0,!1,void 0,this),g$(Z2,{color:q.colors.secondary,children:"Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});import tY from"ansi-escapes";import{Box as P2,Static as xO,useStdout as TR}from"ink";import ER,{useEffect as q8,useMemo as J5,useRef as _4,useState as eY}from"react";import{useStdout as zR}from"ink";import{debounce as BR}from"lodash-es";import{useEffect as wR,useState as LR}from"react";function PO($=200){let{stdout:Z}=zR(),[Y,Q]=LR(Z.rows||24);return wR(()=>{let X=BR(()=>{Q(Z.rows||24)},$);return X(),Z.on("resize",X),()=>{Z.off("resize",X),X.cancel()}},[Z,$]),Y}W3();import{Box as NR,Text as CO}from"ink";import AR from"react";import{jsxDEV as rY}from"react/jsx-dev-runtime";var aY=AR.memo(({collapsedCount:$})=>{let Z=d0();if($<=0)return null;let Y=Z.colors.text.muted;return rY(NR,{flexDirection:"row",marginBottom:1,children:[rY(CO,{color:Y,children:["▶ ",$," 条历史消息"]},void 0,!0,void 0,this),rY(CO,{color:Y,children:" [Ctrl+O 展开]"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});aY.displayName="CollapsedHistorySummary";x2();import{Box as O6,Text as F6}from"ink";import bR from"ink-big-text";import RR from"ink-gradient";import VR from"react";import{jsxDEV as k1}from"react/jsx-dev-runtime";var SO=VR.memo(()=>{return k1(O6,{flexDirection:"column",paddingX:2,paddingTop:1,paddingBottom:1,children:[k1(O6,{flexDirection:"column",children:k1(RR,{name:"pastel",children:k1(bR,{text:"BLADE",font:"block"},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),k1(O6,{marginBottom:1,children:k1(F6,{color:"white",dimColor:!0,children:zQ()},void 0,!1,void 0,this)},void 0,!1,void 0,this),k1(O6,{flexDirection:"column",marginBottom:1,children:[k1(O6,{marginBottom:1,children:k1(F6,{color:"white",bold:!0,children:"使用指南:"},void 0,!1,void 0,this)},void 0,!1,void 0,this),k1(F6,{color:"white",children:"1. 输入问题、编辑文件或运行命令"},void 0,!1,void 0,this),k1(F6,{color:"white",children:"2. 使用 /init 创建项目配置文件"},void 0,!1,void 0,this),k1(F6,{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 nY,Text as Q3}from"ink";import MR,{useMemo as kO}from"react";import{jsxDEV as v2}from"react/jsx-dev-runtime";function DR($,Z=60){if(!$)return"";let Y=$.split(`
2845
+ `).length,F=U.length,H=500,_=10;if(F>500||O>10){let z=X(U),w=U.slice(0,30).replace(/\n/g," "),B=`${F} chars, ${O} lines: ${w}...`;return{prompt:`${l6(z)}${B}${BY()}`}}return{}}),W=VO(async(U,O,F)=>{try{let H=J(U,O);return{prompt:`${l6(H)}[Image #${H}]${BY()}`}}catch(H){return console.error("[Image Paste] Failed to process image:",H),{prompt:`[Image paste failed: ${H instanceof Error?H.message:"Unknown error"}] `}}});return lY(QR,{flexDirection:"row",width:"100%",paddingX:2,paddingY:0,flexShrink:0,flexGrow:0,overflow:"hidden",borderStyle:"round",borderColor:"gray",children:[lY(XR,{color:"blue",bold:!0,children:"> "},void 0,!1,void 0,this),lY(RO,{value:$,cursorPosition:Z,onChange:Y,onChangeCursorPosition:Q,onPaste:K,onImagePaste:W,placeholder:" 输入命令...",focus:q,disabledKeys:["upArrow","downArrow","tab","return","escape"]},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});import{Box as Q5,Text as Z2}from"ink";import UR,{useEffect as OR,useState as FR}from"react";import{useEffect as WR,useState as TO}from"react";import{useEffect as GR,useState as qR}from"react";var KR=15000,DO=["炼化代码灵气...","参悟 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 广纳贤才..."],jO=["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 yO($,Z,Y=!1){let[Q,X]=qR("");return GR(()=>{if(Z){X("等待用户确认...");return}if(!$){X("");return}if(Y)return;let J=()=>{if(Math.random()<0.16666666666666666){let W=Math.floor(Math.random()*jO.length);return jO[W]}let K=Math.floor(Math.random()*DO.length);return DO[K]};X(J());let G=setInterval(()=>{X(J())},KR);return()=>{clearInterval(G)}},[$,Z,Y]),Q}function EO($,Z=!1,Y=!1){let[Q,X]=TO(0),[J,G]=TO(null),q=yO($,Z,Y);return WR(()=>{if(!$){X(0),G(null);return}if(Y)return;if(J===null)G(Date.now());let K=setInterval(()=>{if(J!==null){let W=Math.floor((Date.now()-J)/1000);X(W)}},1000);return()=>{clearInterval(K)}},[$,J,Y]),{currentPhrase:q,elapsedTime:Q}}import{jsxDEV as g$,Fragment as _R}from"react/jsx-dev-runtime";var iY=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"],HR=80;function IO($){if($<60)return`${$}s`;let Z=Math.floor($/60),Y=$%60;return`${Z}m ${Y}s`}var vO=UR.memo(({message:$,paused:Z=!1})=>{let Y=U4(),Q=p6(),X=Y||!Q,[J,G]=FR(0),q=d0(),W=o8()>=HR,{currentPhrase:U,elapsedTime:O}=EO(X,!1,Z);if(OR(()=>{if(!X||Z){G(0);return}let H=setInterval(()=>{G((_)=>(_+1)%iY.length)},80);return()=>clearInterval(H)},[X,Z]),!X)return null;let F=U||$||"正在思考中...";if(W)return g$(Q5,{paddingX:2,paddingBottom:1,flexDirection:"row",gap:1,children:[g$(Z2,{color:q.colors.warning,bold:!0,children:iY[J]},void 0,!1,void 0,this),g$(Z2,{color:q.colors.text.primary,children:F},void 0,!1,void 0,this),O>0&&g$(_R,{children:[g$(Z2,{color:q.colors.muted,children:"|"},void 0,!1,void 0,this),g$(Z2,{color:q.colors.info,children:["已用时: ",IO(O)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),g$(Z2,{color:q.colors.muted,children:"|"},void 0,!1,void 0,this),g$(Z2,{color:q.colors.secondary,children:"Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return g$(Q5,{paddingX:2,paddingBottom:1,flexDirection:"column",children:[g$(Q5,{flexDirection:"row",gap:1,children:[g$(Z2,{color:q.colors.warning,bold:!0,children:iY[J]},void 0,!1,void 0,this),g$(Z2,{color:q.colors.text.primary,children:F},void 0,!1,void 0,this)]},void 0,!0,void 0,this),O>0&&g$(Q5,{marginLeft:2,flexDirection:"row",gap:1,children:[g$(Z2,{color:q.colors.info,children:["已用时: ",IO(O)]},void 0,!0,void 0,this),g$(Z2,{color:q.colors.muted,children:"|"},void 0,!1,void 0,this),g$(Z2,{color:q.colors.secondary,children:"Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});import tY from"ansi-escapes";import{Box as P2,Static as xO,useStdout as TR}from"ink";import ER,{useEffect as q8,useMemo as J5,useRef as _4,useState as eY}from"react";import{useStdout as zR}from"ink";import{debounce as BR}from"lodash-es";import{useEffect as wR,useState as LR}from"react";function PO($=200){let{stdout:Z}=zR(),[Y,Q]=LR(Z.rows||24);return wR(()=>{let X=BR(()=>{Q(Z.rows||24)},$);return X(),Z.on("resize",X),()=>{Z.off("resize",X),X.cancel()}},[Z,$]),Y}W3();import{Box as NR,Text as CO}from"ink";import AR from"react";import{jsxDEV as rY}from"react/jsx-dev-runtime";var aY=AR.memo(({collapsedCount:$})=>{let Z=d0();if($<=0)return null;let Y=Z.colors.text.muted;return rY(NR,{flexDirection:"row",marginBottom:1,children:[rY(CO,{color:Y,children:["▶ ",$," 条历史消息"]},void 0,!0,void 0,this),rY(CO,{color:Y,children:" [Ctrl+O 展开]"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});aY.displayName="CollapsedHistorySummary";x2();import{Box as O7,Text as F7}from"ink";import bR from"ink-big-text";import RR from"ink-gradient";import VR from"react";import{jsxDEV as k1}from"react/jsx-dev-runtime";var SO=VR.memo(()=>{return k1(O7,{flexDirection:"column",paddingX:2,paddingTop:1,paddingBottom:1,children:[k1(O7,{flexDirection:"column",children:k1(RR,{name:"pastel",children:k1(bR,{text:"BLADE",font:"block"},void 0,!1,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),k1(O7,{marginBottom:1,children:k1(F7,{color:"white",dimColor:!0,children:zQ()},void 0,!1,void 0,this)},void 0,!1,void 0,this),k1(O7,{flexDirection:"column",marginBottom:1,children:[k1(O7,{marginBottom:1,children:k1(F7,{color:"white",bold:!0,children:"使用指南:"},void 0,!1,void 0,this)},void 0,!1,void 0,this),k1(F7,{color:"white",children:"1. 输入问题、编辑文件或运行命令"},void 0,!1,void 0,this),k1(F7,{color:"white",children:"2. 使用 /init 创建项目配置文件"},void 0,!1,void 0,this),k1(F7,{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 nY,Text as Q3}from"ink";import MR,{useMemo as kO}from"react";import{jsxDEV as v2}from"react/jsx-dev-runtime";function DR($,Z=60){if(!$)return"";let Y=$.split(`
2846
2846
  `)[0]||"";if(Y.length<=Z)return Y;return`${Y.slice(0,Z)}...`}function jR($){if(!$)return 0;return $.split(`
2847
- `).length}var oY=MR.memo(({content:$,isStreaming:Z=!1,isExpanded:Y})=>{let Q=d0(),X=kO(()=>jR($),[$]),J=kO(()=>DR($),[$]),G=Q.colors.info,q=Q.colors.muted;return v2(nY,{flexDirection:"column",marginBottom:1,children:[v2(nY,{flexDirection:"row",children:[v2(Q3,{color:G,children:Y?"▼":"▶"},void 0,!1,void 0,this),v2(Q3,{children:" "},void 0,!1,void 0,this),v2(Q3,{color:q,children:["Thinking",Z?"...":` (${X} lines)`]},void 0,!0,void 0,this),!Y&&!Z&&J&&v2(Q3,{color:q,children:[" - ",J]},void 0,!0,void 0,this),v2(Q3,{color:q,dimColor:!0,children:[" ","[Ctrl+T]"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Y&&$&&v2(nY,{marginLeft:2,marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,paddingY:0,children:v2(Q3,{color:q,children:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});oY.displayName="ThinkingBlock";import{Box as X5,Text as sY}from"ink";import fO from"react";import{jsxDEV as H4}from"react/jsx-dev-runtime";var hO=fO.memo(({todos:$,visible:Z=!0,compact:Y=!1})=>{let{colors:Q}=d0();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 H4(X5,{flexDirection:"column",borderStyle:"single",borderColor:Q.border.light,paddingX:1,paddingY:Y?0:1,marginBottom:1,children:[H4(X5,{marginBottom:Y?0:1,children:[H4(sY,{dimColor:!0,children:"Tasks "},void 0,!1,void 0,this),H4(sY,{color:Q.text.muted,children:[X.completed,"/",X.total]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),H4(X5,{flexDirection:"column",children:$.map((J,G)=>H4(yR,{todo:J,compact:Y},J.id||G,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}),yR=fO.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 H4(X5,{paddingY:Z?0:0,children:H4(sY,{dimColor:Q,children:[Y," ",X]},void 0,!0,void 0,this)},void 0,!1,void 0,this)});import{jsxDEV as b$}from"react/jsx-dev-runtime";var pO=ER.memo(()=>{let $=h7(),Z=wU(),Y=LU(),Q=NU(),X=U4(),J=JU(),G=WU(),q=_U(),K=zU(),W=BU(),U=$U(),O=bU(),F=AU(),H=o8(),_=PO(),{stdout:z}=TR(),w=K4(),[B,L]=eY(null),[N,M]=eY([]),[b,j]=eY(new Set),T=_4(F),A=_4(null),k=_4(0),c=_4(0),o=_4(new Set),S=_4(new Set),y=_4([]),l=_4(null);q8(()=>{if(T.current!==F){if(z)z.write(tY.clearTerminal);w.incrementClearCount(),T.current=F}},[F,z,w]);let I=$,D=Q;q8(()=>{if(!Q||X){l.current=null;return}if(l.current===Q)return;l.current=Q;let C=setTimeout(()=>{if(z)z.write(tY.clearTerminal);o.current=new Set,S.current=new Set(I.filter((i)=>i.role==="tool").map((i)=>i.id)),A.current=null,k.current=0,c.current=0,y.current=[],M([]),j(new Set),w.incrementClearCount(),w.clearFinalizingStreamingMessageId()},50);return()=>clearTimeout(C)},[Q,X,z,w,I]);let V=Z??Q;q8(()=>{A.current=null,k.current=0,c.current=0,o.current=new Set,S.current=new Set(I.filter((C)=>C.role==="tool").map((C)=>C.id)),y.current=[],M([]),j(new Set)},[U]),q8(()=>{if(!V)return;if(A.current===V)return;A.current=V,k.current=0,c.current=0,S.current=new Set(I.filter((C)=>C.role==="tool").map((C)=>C.id)),y.current=[],M([])},[V,I]),q8(()=>{if(!V)return;let C=P5(V);if(!C||C.length<=k.current)return;let i=C.slice(k.current);k.current=C.length;let n=i,B0=y.current;if(B0.length>0)if(n.some((K1)=>K1.type!=="empty"))n=[...B0,...n],y.current=[];else{y.current=[...B0,...n];return}let j0=n.length;while(j0>0&&n[j0-1].type==="empty")j0-=1;if(j0!==n.length)y.current=n.slice(j0),n=n.slice(0,j0);if(n.length===0)return;let K$=c.current;c.current+=1;let $1=K$>0;j((K1)=>{if(!V||K1.has(V))return K1;let b1=new Set(K1);return b1.add(V),b1}),M((K1)=>[...K1,b$(P2,{flexDirection:"column",children:b$(F4,{content:"",role:"assistant",terminalWidth:H,isPending:!1,hidePrefix:$1,noMargin:!0,blocksOverride:n,renderCodeBlocksAsPlainText:!0},void 0,!1,void 0,this)},`streaming-${V}-${K$}`,!1,void 0,this)])},[V,Y.version,H,U]),q8(()=>{if(!V)return;let C=S.current,i=I.filter((n)=>n.role==="tool"&&!C.has(n.id)&&!o.current.has(n.id));if(i.length===0)return;for(let n of i)o.current.add(n.id);M((n)=>[...n,...i.map((B0)=>b$(P2,{flexDirection:"column",children:b$(F4,{content:B0.content,role:B0.role,terminalWidth:H,metadata:B0.metadata,isPending:!1,messageId:B0.id},void 0,!1,void 0,this)},`streaming-tool-${B0.id}`,!1,void 0,this))])},[V,I,H]);let g=J5(()=>{if(!V)return null;let C=mQ(V);if(!C||C.lines.length===0)return null;let n=Math.max(1,_-8),B0=Math.max(0,C.lines.length-n);return{visibleLines:C.lines.slice(-n),hiddenLines:B0,mode:C.mode}},[V,Y.version,_]),u=J5(()=>{if(!V)return!1;return(P5(V)?.length??0)>0},[V,Y.version]);q8(()=>{if(B===null&&I.length>O){if(L(I.length),z)z.write(tY.clearTerminal);w.incrementClearCount()}},[I.length,O,B,z,w]);let v=J5(()=>{return J.some((C)=>C.status==="pending"||C.status==="in_progress")},[J]),Z0=F?0:B??0,d=Z0,s=J5(()=>{let C=[];if(C.push(b$(SO,{},"header",!1,void 0,this)),d>0)C.push(b$(aY,{collapsedCount:d},"collapsed-summary",!1,void 0,this));for(let i=Z0;i<I.length;i++){let n=I[i];if(D&&n.id===D)continue;if(n.role==="tool"&&o.current.has(n.id))continue;if(n.role==="assistant"&&b.has(n.id))continue;C.push(b$(P2,{flexDirection:"column",children:b$(F4,{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 C},[I,Z0,d,H,D,b]);return b$(P2,{flexDirection:"column",paddingX:2,children:b$(P2,{flexDirection:"column",children:[b$(xO,{items:s,children:(C)=>C},U,!1,void 0,this),K&&b$(P2,{marginBottom:1,children:b$(oY,{content:K,isStreaming:X,isExpanded:W},void 0,!1,void 0,this)},void 0,!1,void 0,this),N.length>0&&b$(xO,{items:N,children:(C)=>C},`streaming-${U}`,!1,void 0,this),g&&b$(P2,{flexDirection:"column",children:b$(F4,{content:"",role:"assistant",terminalWidth:H,isPending:!0,hidePrefix:u,streamingLines:g.visibleLines,streamingHiddenLines:g.hiddenLines,streamingMode:g.mode},void 0,!1,void 0,this)},void 0,!1,void 0,this),G&&v&&b$(P2,{marginTop:1,children:b$(hO,{todos:J,visible:!0,compact:!1},void 0,!1,void 0,this)},void 0,!1,void 0,this),q.map((C,i)=>b$(P2,{flexDirection:"column",children:b$(F4,{content:C.displayText,role:"user",terminalWidth:H},void 0,!1,void 0,this)},`pending-${i}`,!1,void 0,this))]},void 0,!0,void 0,this)},void 0,!1,void 0,this)});M0();import{useMemoizedFn as S2}from"ahooks";import{Box as h$,Text as w$,useFocusManager as nR,useInput as YF}from"ink";import oR from"ink-text-input";import{useState as B4}from"react";import{Box as C2,Text as B1,useInput as IR}from"ink";import vR from"ink-text-input";import{jsxDEV as q$}from"react/jsx-dev-runtime";var mO=({provider:$,value:Z,onChange:Y,onSubmit:Q,onCancel:X,error:J})=>{IR((q,K)=>{if(K.escape)X()});let G=$.envVars.length>0?$.envVars[0]:null;return q$(C2,{flexDirection:"column",children:[q$(C2,{marginBottom:1,children:q$(B1,{bold:!0,color:"blue",children:"\uD83D\uDD11 Step 2: 输入 API Key"},void 0,!1,void 0,this)},void 0,!1,void 0,this),q$(C2,{marginBottom:1,children:q$(B1,{children:["Provider: ",$.icon," ",q$(B1,{bold:!0,children:$.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),G&&q$(C2,{marginBottom:1,children:q$(B1,{dimColor:!0,children:["\uD83D\uDCA1 环境变量: ",q$(B1,{color:"cyan",children:G},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),$.docUrl&&q$(C2,{marginBottom:1,children:q$(B1,{dimColor:!0,children:["\uD83D\uDCD6 文档: ",q$(B1,{color:"blue",children:$.docUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),q$(C2,{marginBottom:1,children:q$(B1,{dimColor:!0,children:"您的 API 密钥将被安全存储在 ~/.blade/config.json (权限 600)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),q$(C2,{children:[q$(B1,{bold:!0,color:"cyan",children:["▶"," "]},void 0,!0,void 0,this),q$(vR,{value:Z,onChange:Y,onSubmit:Q,placeholder:"sk-...",mask:"*"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J&&q$(C2,{marginTop:1,children:q$(B1,{color:"red",children:["❌ ",J]},void 0,!0,void 0,this)},void 0,!1,void 0,this),q$(C2,{marginTop:1,children:q$(B1,{dimColor:!0,children:["\uD83D\uDCA1 输入完成后按 ",q$(B1,{bold:!0,children:"Enter"},void 0,!1,void 0,this),",",q$(B1,{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 gO,useState as X3}from"react";w8();var PR={id:"custom-openai-compatible",name:"自定义 OpenAI Compatible",icon:"\uD83D\uDD27",description:"使用自定义 Base URL 和 API Key",isOAuth:!1,envVars:[],bladeProvider:"openai-compatible",isCustom:!0},uO=()=>{let[$,Z]=X3([]),[Y,Q]=X3(!0),[X,J]=X3(null);return gO(()=>{(async()=>{try{let q=await P7(),K=Object.entries(V6).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,PR,...q])}catch(q){J(q instanceof Error?q.message:"加载 Provider 列表失败")}finally{Q(!1)}})()},[]),{providers:$,isLoading:Y,error:X}},dO=($)=>{let[Z,Y]=X3([]),[Q,X]=X3(!1),[J,G]=X3(null);return gO(()=>{if(!$){Y([]);return}(async()=>{X(!0),G(null);try{let K=await C7($);Y(K)}catch(K){G(K instanceof Error?K.message:"加载模型列表失败")}finally{X(!1)}})()},[$]),{models:Z,isLoading:Q,error:J}};import{Box as Y2,Text as f1,useInput as CR}from"ink";import SR from"ink-select-input";import cO from"ink-text-input";import{useMemo as lO,useState as $Q}from"react";import{jsxDEV as i0,Fragment as xR}from"react/jsx-dev-runtime";var kR=({isSelected:$})=>i0(Y2,{marginRight:1,children:i0(f1,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),fR=($)=>{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(" ")},hR=({isSelected:$,label:Z})=>i0(f1,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),iO=({provider:$,models:Z,isLoading:Y,error:Q,onSelect:X,onCancel:J,initialModel:G})=>{let[q,K]=$Q(""),W=$.isCustom||Z.length===0,[U,O]=$Q(W),[F,H]=$Q(G||"");CR((B,L)=>{if(L.escape){if(U&&!W)O(!1),H(G||"");else if(q)K("");else J();return}if(B==="+"&&!U)O(!0)});let _=lO(()=>{if(!q)return Z;let B=q.toLowerCase();return Z.filter((L)=>L.name.toLowerCase().includes(B)||L.id.toLowerCase().includes(B))},[Z,q]),z=lO(()=>_.map((B)=>({key:B.id,label:fR(B),value:B})),[_]),w=()=>{if(F.trim())X({id:F.trim(),name:F.trim()})};if(Y)return i0(Y2,{flexDirection:"column",children:i0(f1,{color:"yellow",children:["⏳ 正在加载 ",$.name," 模型列表..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this);if(Q)return i0(Y2,{flexDirection:"column",children:[i0(f1,{color:"red",children:["❌ ",Q]},void 0,!0,void 0,this),i0(f1,{dimColor:!0,children:"按 Esc 返回"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return i0(Y2,{flexDirection:"column",children:[i0(Y2,{marginBottom:1,children:i0(f1,{bold:!0,color:"blue",children:"\uD83E\uDD16 Step 3: 选择模型"},void 0,!1,void 0,this)},void 0,!1,void 0,this),i0(Y2,{marginBottom:1,children:i0(f1,{children:["Provider: ",$.icon," ",i0(f1,{bold:!0,children:$.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),U?i0(Y2,{flexDirection:"column",children:[i0(Y2,{marginBottom:1,children:i0(f1,{dimColor:!0,children:W?"输入模型名称:":"输入自定义模型名称(按 Esc 返回列表):"},void 0,!1,void 0,this)},void 0,!1,void 0,this),i0(Y2,{children:[i0(f1,{bold:!0,color:"cyan",children:"▶ "},void 0,!1,void 0,this),i0(cO,{value:F,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):i0(xR,{children:[i0(Y2,{marginBottom:1,children:[i0(f1,{color:"cyan",children:"\uD83D\uDD0D "},void 0,!1,void 0,this),i0(cO,{value:q,onChange:K,placeholder:`搜索 ${Z.length} 个模型,按 + 自定义...`},void 0,!1,void 0,this)]},void 0,!0,void 0,this),i0(Y2,{flexDirection:"column",height:12,children:i0(SR,{items:z,onSelect:(B)=>X(B.value),indicatorComponent:kR,itemComponent:hR,limit:10},void 0,!1,void 0,this)},void 0,!1,void 0,this),_.length===0&&i0(f1,{color:"yellow",children:"未找到匹配的模型,按 + 输入自定义模型名称"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};R3();N3();T3();D3();import{Box as h1,Text as w1,useFocus as aO,useInput as nO}from"ink";import pR from"ink-select-input";import{useEffect as mR,useState as rO}from"react";import{jsxDEV as s0}from"react/jsx-dev-runtime";var oO=({provider:$,onLogin:Z,onCancel:Y,isLoggingIn:Q})=>{let{isFocused:X}=aO({id:"oauth-login"});return nO((J,G)=>{if(Q)return;if(J==="y"||J==="Y")Z();else if(J==="n"||J==="N"||G.escape)Y()},{isActive:X&&!Q}),s0(h1,{flexDirection:"column",children:[s0(h1,{marginBottom:1,children:s0(w1,{bold:!0,color:"yellow",children:[$.icon," 需要登录 ",$.name]},void 0,!0,void 0,this)},void 0,!1,void 0,this),s0(h1,{marginBottom:1,children:s0(w1,{children:$.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),s0(h1,{marginBottom:1,paddingLeft:2,children:s0(w1,{dimColor:!0,children:["您也可以稍后手动执行"," ",s0(w1,{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&&s0(h1,{marginTop:1,children:s0(w1,{children:["现在登录? [",s0(w1,{bold:!0,color:"green",children:"Y"},void 0,!1,void 0,this),"/",s0(w1,{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&&s0(h1,{marginTop:1,children:s0(w1,{color:"yellow",children:"⏳ 正在启动登录流程..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},gR=({isSelected:$})=>s0(h1,{marginRight:1,children:s0(w1,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),uR=({isSelected:$,label:Z})=>s0(w1,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),sO=({provider:$,onSelect:Z,onCancel:Y})=>{let{isFocused:Q}=aO({id:"oauth-model-select"}),[X,J]=rO([]),[G,q]=rO(!0);mR(()=>{(async()=>{q(!0);try{if($.id==="copilot")J(Object.values(E6));else{let O=await p$.getInstance().getConfigType();J(O==="gemini-cli"?Object.values(D6):Object.values(L3))}}catch{J(Object.values(L3))}finally{q(!1)}})()},[$.id]),nO((W,U)=>{if(U.escape)Y()},{isActive:Q});let K=X.map((W)=>({key:W.id,label:`${W.name} - ${W.description}`,value:{id:W.id,name:W.name}}));if(G)return s0(h1,{flexDirection:"column",children:s0(w1,{color:"yellow",children:["⏳ 加载 ",$.name," 模型列表..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this);return s0(h1,{flexDirection:"column",children:[s0(h1,{marginBottom:1,children:s0(w1,{bold:!0,color:"blue",children:["\uD83E\uDD16 选择 ",$.name," 模型"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),s0(h1,{marginBottom:1,children:s0(w1,{dimColor:!0,children:"从可用模型列表中选择一个"},void 0,!1,void 0,this)},void 0,!1,void 0,this),s0(h1,{flexDirection:"column",height:12,children:s0(pR,{items:K,onSelect:(W)=>Z(W.value),indicatorComponent:gR,itemComponent:uR,limit:10},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},tO=async($)=>{let Z=$==="antigravity"?p$.getInstance():r$.getInstance();try{return await Z.login(),!0}catch{return!1}},eO=async($)=>{let Z=$==="antigravity"?p$.getInstance():r$.getInstance();try{return await Z.isLoggedIn()}catch{return!1}};import{Box as K8,Text as z4,useInput as dR}from"ink";import cR from"ink-select-input";import lR from"ink-text-input";import{useMemo as $F,useState as iR}from"react";import{jsxDEV as f$}from"react/jsx-dev-runtime";var rR=({isSelected:$})=>f$(K8,{marginRight:1,children:f$(z4,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),aR=({isSelected:$,label:Z})=>f$(z4,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),ZF=({providers:$,isLoading:Z,error:Y,onSelect:Q,onCancel:X})=>{let[J,G]=iR("");dR((W,U)=>{if(U.escape)if(J)G("");else X()});let q=$F(()=>{if(!J)return $;let W=J.toLowerCase();return $.filter((U)=>U.name.toLowerCase().includes(W)||U.id.toLowerCase().includes(W))},[$,J]),K=$F(()=>q.map((W)=>({key:W.id,label:`${W.icon} ${W.name} - ${W.description}`,value:W})),[q]);if(Z)return f$(K8,{flexDirection:"column",children:f$(z4,{color:"yellow",children:"⏳ 正在加载 Provider 列表..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(Y)return f$(K8,{flexDirection:"column",children:[f$(z4,{color:"red",children:["❌ ",Y]},void 0,!0,void 0,this),f$(z4,{dimColor:!0,children:"按 Esc 返回"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return f$(K8,{flexDirection:"column",children:[f$(K8,{marginBottom:1,children:f$(z4,{bold:!0,color:"blue",children:"\uD83D\uDCE1 Step 1: 选择 API 提供商"},void 0,!1,void 0,this)},void 0,!1,void 0,this),f$(K8,{marginBottom:1,children:[f$(z4,{color:"cyan",children:"\uD83D\uDD0D "},void 0,!1,void 0,this),f$(lR,{value:J,onChange:G,placeholder:`搜索 ${$.length} 个 Provider...`},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f$(K8,{flexDirection:"column",height:12,children:f$(cR,{items:K,onSelect:(W)=>Q(W.value),indicatorComponent:rR,itemComponent:aR,limit:10},void 0,!1,void 0,this)},void 0,!1,void 0,this),q.length===0&&f$(z4,{color:"yellow",children:"未找到匹配的 Provider,按 Esc 清除搜索"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};w8();import{jsxDEV as K0,Fragment as tR}from"react/jsx-dev-runtime";var ZQ=({mode:$,initialConfig:Z,modelId:Y,onComplete:Q,onCancel:X})=>{let J=$==="edit",[G,q]=B4("provider"),[K,W]=B4(),[U,O]=B4(J?Z?.apiKey||"":""),[F,H]=B4(J?Z?.baseUrl||"":""),[_]=B4(J?Z?.model||"":""),[z,w]=B4(),[B,L]=B4(!1),[N,M]=B4(!1),{providers:b,isLoading:j,error:T}=uO(),{models:A,isLoading:k,error:c}=dO(K?.isOAuth?void 0:K?.id),o=Q$(!1),{focus:S}=nR();YF((i,n)=>{if(n.ctrl&&i==="c"||n.meta&&i==="c")$==="setup"?o():X()});let y=S2((i)=>{let B0={provider:"",apiKey:"",baseUrl:"",model:"",oauthLogin:"oauth-login",oauthModelSelect:"oauth-model-select",confirm:""}[i];if(B0)S(B0)}),l=S2((i)=>{return i.defaultBaseUrl||M6[i.id]||""}),I=S2(async(i)=>{W(i),w(void 0);let n=l(i);if(!J)H(n);if(i.isOAuth){let j0=await eO(i.id)?"oauthModelSelect":"oauthLogin";q(j0),y(j0)}else q("apiKey")}),D=S2(()=>{if(!U.trim()){w("API Key 不能为空");return}w(void 0);let i=K?l(K):"";if(K?.isCustom||!i&&!F)q("baseUrl");else q("model")}),V=S2(()=>{if(!F.trim()){w("Base URL 不能为空");return}try{new URL(F)}catch{w("请输入有效的 URL (例如: https://api.example.com/v1)");return}w(void 0),q("model")}),g=S2(async(i)=>{w(void 0),L(!0);try{let n=F||(K?l(K):""),j0={name:J&&Z?.name?Z.name:`${K?.name||"Model"} - ${i.name}`,provider:K?.bladeProvider||Z?.provider||"openai-compatible",baseUrl:n,apiKey:K?.isOAuth?"oauth":U,model:i.id,...i.contextWindow&&{maxContextTokens:i.contextWindow},...i.maxOutput&&{maxOutputTokens:i.maxOutput},...K?.id&&{providerId:K.id}};if($==="setup")Q(j0);else if($==="add"){let K$=await b0().addModel(j0);await b0().setCurrentModel(K$.id),Q(j0)}else if($==="edit"&&Y)await b0().updateModel(Y,j0),Q(j0)}catch(n){w(n instanceof Error?n.message:"保存配置失败"),L(!1)}}),u=S2(async()=>{if(!K)return;M(!0),w(void 0);let i=await tO(K.id);if(M(!1),i)q("oauthModelSelect"),y("oauthModelSelect");else w("登录失败,请重试")}),v=S2(()=>{switch(w(void 0),G){case"apiKey":q("provider");break;case"baseUrl":q("apiKey");break;case"model":{if(!(K?l(K):""))q("baseUrl");else q("apiKey");break}case"oauthLogin":case"oauthModelSelect":q("provider");break}}),Z0=S2(()=>{q("apiKey")}),d=G==="provider"?1:G==="apiKey"||G==="oauthLogin"?2:G==="baseUrl"?2.5:3,s=3;return K0(h$,{...$==="setup"?{flexDirection:"column",padding:1}:{flexDirection:"column",borderStyle:"round",borderColor:$==="edit"?"yellow":"blue",padding:1},children:[$==="setup"&&K0(tR,{children:[K0(h$,{marginBottom:1,children:K0(w$,{bold:!0,color:"blue",children:"\uD83D\uDE80 欢迎使用 Blade Code"},void 0,!1,void 0,this)},void 0,!1,void 0,this),K0(h$,{marginBottom:1,children:K0(w$,{children:"AI 驱动的代码助手 - 让我们开始配置您的助手"},void 0,!1,void 0,this)},void 0,!1,void 0,this),K0(h$,{marginBottom:1,children:[K0(w$,{bold:!0,color:"blue",children:"█".repeat(Math.floor((d-1)/(s-1)*40))},void 0,!1,void 0,this),K0(w$,{dimColor:!0,children:"░".repeat(40-Math.floor((d-1)/(s-1)*40))},void 0,!1,void 0,this),K0(w$,{children:" "},void 0,!1,void 0,this),K0(w$,{bold:!0,color:"cyan",children:[Math.ceil(d),"/",s]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),K0(h$,{marginBottom:1,children:K0(w$,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$!=="setup"&&K0(h$,{justifyContent:"center",marginBottom:1,children:K0(w$,{bold:!0,color:$==="edit"?"yellow":"blue",children:$==="edit"?"编辑模型配置":"添加新模型配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G==="provider"&&K0(ZF,{providers:b,isLoading:j,error:T,onSelect:I,onCancel:$==="setup"?()=>{}:X},void 0,!1,void 0,this),G==="apiKey"&&K&&K0(mO,{provider:K,value:U,onChange:O,onSubmit:D,onCancel:v,error:z},void 0,!1,void 0,this),G==="baseUrl"&&K&&K0(sR,{provider:K,value:F,onChange:H,onSubmit:V,onCancel:Z0,error:z},void 0,!1,void 0,this),G==="model"&&K&&K0(iO,{provider:K,models:A,isLoading:k,error:c,onSelect:g,onCancel:v,initialModel:J?_:void 0},void 0,!1,void 0,this),G==="oauthLogin"&&K&&K0(oO,{provider:K,onLogin:u,onCancel:v,isLoggingIn:N},void 0,!1,void 0,this),G==="oauthModelSelect"&&K&&K0(sO,{provider:K,onSelect:g,onCancel:v},void 0,!1,void 0,this),z&&G!=="apiKey"&&G!=="baseUrl"&&K0(h$,{marginTop:1,borderStyle:"round",borderColor:"red",paddingX:1,children:K0(w$,{color:"red",children:["❌ ",z]},void 0,!0,void 0,this)},void 0,!1,void 0,this),B&&K0(h$,{marginTop:1,children:K0(w$,{color:"yellow",children:"⏳ 正在保存配置..."},void 0,!1,void 0,this)},void 0,!1,void 0,this),K0(h$,{marginTop:1,children:K0(w$,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},sR=({provider:$,value:Z,onChange:Y,onSubmit:Q,onCancel:X,error:J})=>{return YF((G,q)=>{if(q.escape)X()}),K0(h$,{flexDirection:"column",children:[K0(h$,{marginBottom:1,children:K0(w$,{bold:!0,color:"blue",children:"\uD83C\uDF10 输入 Base URL"},void 0,!1,void 0,this)},void 0,!1,void 0,this),K0(h$,{marginBottom:1,children:K0(w$,{children:["Provider: ",$.icon," ",K0(w$,{bold:!0,children:$.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),K0(h$,{marginBottom:1,children:K0(w$,{dimColor:!0,children:"此 Provider 没有默认的 API 端点,请输入完整的 Base URL"},void 0,!1,void 0,this)},void 0,!1,void 0,this),K0(h$,{marginBottom:1,children:K0(w$,{dimColor:!0,children:"示例: https://api.example.com/v1"},void 0,!1,void 0,this)},void 0,!1,void 0,this),K0(h$,{children:[K0(w$,{bold:!0,color:"cyan",children:"▶ "},void 0,!1,void 0,this),K0(oR,{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&&K0(h$,{marginTop:1,children:K0(w$,{color:"red",children:["❌ ",J]},void 0,!0,void 0,this)},void 0,!1,void 0,this),K0(h$,{marginTop:1,children:K0(w$,{dimColor:!0,children:["\uD83D\uDCA1 输入完成后按 ",K0(w$,{bold:!0,children:"Enter"},void 0,!1,void 0,this),",",K0(w$,{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)};W9();import{useMemoizedFn as G5,useMount as eR}from"ahooks";import{Box as L1,Text as P0,useFocus as $V,useFocusManager as ZV,useInput as YV}from"ink";import QV from"ink-select-input";import{memo as XV,useMemo as JV,useState as q5}from"react";M0();import{jsxDEV as U0}from"react/jsx-dev-runtime";function GV($){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 qV=({isSelected:$})=>U0(L1,{marginRight:1,children:U0(P0,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),KV=({isSelected:$,label:Z})=>U0(P0,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),QF=XV(({onClose:$,onEdit:Z})=>{let Y=UU(),Q=OU()??"",{isFocused:X}=$V({id:"model-selector"}),J=ZV(),[G,q]=q5(""),[K,W]=q5(!1),[U,O]=q5(null),F=Q$(!1),[H]=q5(()=>{let j=process.stdout?.columns||80;return Math.max(20,j-8)});eR(()=>{if(J?.focus("model-selector"),Y.length>0)q(Y[0].id)}),YV((j,T)=>{if(K)return;if(T.ctrl&&j==="c"||T.meta&&j==="c"){F();return}if(T.escape){$();return}if(!X)return;if(j==="d"||j==="D"){z();return}if((j==="e"||j==="E")&&Z)w()},{isActive:!0});let _=G5(async(j)=>{if(K)return;let T=j.value;if(T===Q){$();return}W(!0),O(null);try{await b0().setCurrentModel(T),$()}catch(A){O(A.message),W(!1)}}),z=G5(async()=>{if(K||G===Q)return;W(!0),O(null);try{if(await b0().removeModel(G),Y.length<=1)$()}catch(j){O(j.message)}finally{W(!1)}}),w=G5(()=>{if(K||!Z)return;let j=Y.find((T)=>T.id===G);if(!j)return;Z(j)}),B=G5((j)=>{q(j.value)}),L=JV(()=>{return Y.find((j)=>j.id===G)},[Y,G]),N=Y.map((j)=>{let T=j.id===Q?" (当前)":"";return{label:j.name+T,value:j.id}}),M=G===Q;return U0(L1,{flexDirection:"column",borderStyle:"round",borderColor:"gray",padding:1,width:"100%",children:[U0(L1,{flexDirection:"row",justifyContent:"space-between",marginBottom:1,children:[U0(P0,{bold:!0,color:"cyan",children:"模型管理"},void 0,!1,void 0,this),U0(P0,{dimColor:!0,children:[K?"⏳ 处理中...":M?"Enter=关闭 • E=编辑 • Esc=取消":"Enter=切换 • D=删除 • E=编辑 • Esc=取消"," • Ctrl+C=退出"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),U0(L1,{flexDirection:"row",children:[U0(L1,{flexDirection:"column",flexGrow:2,marginRight:2,borderStyle:"single",borderColor:"gray",padding:1,children:[U0(P0,{dimColor:!0,children:["已配置模型 (",Y.length,")"]},void 0,!0,void 0,this),U0(L1,{marginTop:1,children:U0(QV,{items:N,onSelect:_,onHighlight:B,indicatorComponent:qV,itemComponent:KV},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),U0(L1,{flexDirection:"column",flexGrow:3,borderStyle:"single",borderColor:"gray",padding:1,children:[U0(P0,{dimColor:!0,children:"模型详情"},void 0,!1,void 0,this),U0(L1,{marginY:1,children:U0(P0,{color:M?"green":"yellow",children:M?"● 当前使用":"● 可切换"},void 0,!1,void 0,this)},void 0,!1,void 0,this),L?U0(L1,{flexDirection:"column",children:[U0(P0,{children:[U0(P0,{dimColor:!0,children:"名称: "},void 0,!1,void 0,this),U0(P0,{bold:!0,color:"cyan",children:L.name},void 0,!1,void 0,this),K9(L)&&U0(P0,{color:"green",children:" (内置免费)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),U0(P0,{children:[U0(P0,{dimColor:!0,children:"Provider: "},void 0,!1,void 0,this),U0(P0,{bold:!0,children:GV(L.provider)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),U0(P0,{children:[U0(P0,{dimColor:!0,children:"Model: "},void 0,!1,void 0,this),U0(P0,{bold:!0,children:L.model},void 0,!1,void 0,this)]},void 0,!0,void 0,this),U0(P0,{children:[U0(P0,{dimColor:!0,children:"Base URL: "},void 0,!1,void 0,this),U0(P0,{color:"blueBright",children:L.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L.temperature!==void 0&&U0(P0,{children:[U0(P0,{dimColor:!0,children:"Temperature: "},void 0,!1,void 0,this),U0(P0,{children:L.temperature},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L.maxContextTokens!==void 0&&U0(P0,{children:[U0(P0,{dimColor:!0,children:"Context Window: "},void 0,!1,void 0,this),U0(P0,{children:L.maxContextTokens},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K9(L)&&U0(L1,{marginTop:1,children:U0(P0,{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):U0(P0,{dimColor:!0,children:"请选择一个模型查看详情"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),U&&U0(L1,{marginTop:1,children:U0(P0,{color:"red",children:["❌ ",U]},void 0,!0,void 0,this)},void 0,!1,void 0,this),U0(L1,{justifyContent:"center",marginTop:1,children:U0(P0,{dimColor:!0,children:"─".repeat(H)},void 0,!1,void 0,this)},void 0,!1,void 0,this),U0(L1,{justifyContent:"center",children:U0(P0,{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 H6}from"ahooks";import{promises as qF}from"fs";import{Box as N1,Text as $$,useInput as WV}from"ink";import XF from"ink-select-input";import UV from"ink-text-input";import OV from"os";import K5 from"path";import{useEffect as FV,useMemo as W5,useRef as HV,useState as w4}from"react";M0();import{jsxDEV as z0}from"react/jsx-dev-runtime";var _6=[{key:"allow",label:"Allow"},{key:"ask",label:"Ask"},{key:"deny",label:"Deny"},{key:"info",label:"Info"}],_V={allow:"Add a new rule...",ask:"Add a new rule...",deny:"Add a new rule..."},zV={allow:"Allow permission rules",ask:"Ask permission rules",deny:"Deny permission rules"},JF={project:"[项目共享配置]",global:"[用户全局配置]",local:"[本地配置]"},BV=["project","global","local"],wV={allow:[],ask:[],deny:[]},LV={localExists:!1,projectExists:!1,globalExists:!1},GF={allow:[],ask:[],deny:[]};function NV($){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 AV($){try{let Z=await qF.readFile($,"utf-8"),Y=JSON.parse(Z);return{exists:!0,raw:Y,permissions:NV(Y)}}catch(Z){if(Z.code==="ENOENT")return{exists:!1,raw:{},permissions:{...GF}};return console.warn(`[PermissionsManager] Failed to read ${$}:`,Z),{exists:!0,raw:{},permissions:{...GF}}}}function bV($,Z){let Y=$.padEnd(32," "),Q=Z==="local"?`${JF[Z]} ← 可删除`:JF[Z];return`${Y} ${Q}`}var KF=({onClose:$})=>{let Y=q1()==="permissions-manager",Q=Q$(!1),[X,J]=w4(0),G=_6[X].key,[q,K]=w4(wV),[W,U]=w4(LV),[O,F]=w4(!0),[H,_]=w4("list"),[z,w]=w4(""),[B,L]=w4(null),[N,M]=w4(null),b=HV(!1),j=W5(()=>K5.join(process.cwd(),".blade","settings.local.json"),[]),T=W5(()=>K5.join(process.cwd(),".blade","settings.json"),[]),A=W5(()=>K5.join(OV.homedir(),".blade","settings.json"),[]),k=H6(async()=>{F(!0);let s=await Promise.all([{source:"local",path:j},{source:"project",path:T},{source:"global",path:A}].map(async({source:B0,path:j0})=>{let K$=await AV(j0);return{source:B0,path:j0,...K$}})),C={localExists:s.find((B0)=>B0.source==="local")?.exists??!1,projectExists:s.find((B0)=>B0.source==="project")?.exists??!1,globalExists:s.find((B0)=>B0.source==="global")?.exists??!1};U(C);let i={allow:[],ask:[],deny:[]},n=Object.fromEntries(s.map((B0)=>[B0.source,B0]));["allow","ask","deny"].forEach((B0)=>{BV.forEach((j0)=>{(n[j0]?.permissions[B0]??[]).forEach(($1,K1)=>{let b1={key:`${j0}:${K1}:${$1}`,rule:$1,source:j0};i[B0].push(b1)})})}),K(i),F(!1)});FV(()=>{k()},[k]);let c=H6(async(d,s)=>{try{let C=K5.join(process.cwd(),".blade","settings.local.json"),i={allow:[],ask:[],deny:[]};try{let B0=await qF.readFile(C,"utf-8"),K$=JSON.parse(B0).permissions||{};i={allow:Array.isArray(K$.allow)?K$.allow:[],ask:Array.isArray(K$.ask)?K$.ask:[],deny:Array.isArray(K$.deny)?K$.deny:[]}}catch(B0){}let n=s(i);await b0().updateConfig({permissions:n},{scope:"local",immediate:!0}),await k()}catch(C){throw console.error("[PermissionsManager] 修改权限规则失败:",C),C}});WV((d,s)=>{if(s.ctrl&&d==="c"||s.meta&&d==="c"){Q();return}if(H==="locked"){if(b.current){b.current=!1;return}_("list"),L(null),M(null);return}if(s.escape){if(H==="list"||G==="info")$();else _("list"),w(""),L(null),M(null);return}if(H==="list"){if(s.tab&&s.shift)J((C)=>(C-1+_6.length)%_6.length);else if(s.tab)J((C)=>(C+1)%_6.length);else if(d?.toLowerCase()==="q")$()}},{isActive:Y});let o=H6((d)=>{let s=d.value;if(G==="info")return;if(s.type==="add"){_("add"),w(""),M(null);return}if(s.entry.source!=="local"){_("locked"),b.current=!0,L({tab:G,entry:s.entry}),M({type:"error",text:s.entry.source==="project"?"此规则定义在项目共享配置中,无法在此删除。":"此规则来自用户全局配置,无法在此删除。"});return}_("confirm-delete"),L({tab:G,entry:s.entry}),M(null)}),S=H6(async()=>{if(G==="info")return;let d=z.trim();if(!d){M({type:"error",text:"Permission rule 不能为空"});return}if(q[G].map((C)=>C.rule).includes(d)){M({type:"error",text:"该规则已存在"});return}try{await c(G,(C)=>{let i={allow:[...C.allow],ask:[...C.ask],deny:[...C.deny]};return i[G]=[...new Set([...C[G],d])],i}),_("list"),w(""),M({type:"success",text:"已添加本地权限规则"})}catch(C){M({type:"error",text:`保存失败: ${C instanceof Error?C.message:"未知错误"}`})}}),y=H6(async()=>{if(!B)return;let{tab:d,entry:s}=B;try{await c(d,(C)=>{let i={allow:[...C.allow],ask:[...C.ask],deny:[...C.deny]};return i[d]=C[d].filter((n)=>n!==s.rule),i}),_("list"),L(null),M({type:"success",text:"已删除本地权限规则"})}catch(C){M({type:"error",text:`删除失败: ${C instanceof Error?C.message:"未知错误"}`})}}),l=W5(()=>{if(G==="info")return[];let d=G;return[{key:"add-new-rule",label:`› ${_V[d]}`,value:{type:"add"}},...q[d].map((C)=>({key:C.key,label:bV(C.rule,C.source),value:{type:"rule",entry:C}}))]},[G,q]),I=()=>z0(N1,{marginBottom:1,children:_6.map((d,s)=>z0(N1,{marginRight:2,children:z0($$,{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),D=()=>z0(N1,{flexDirection:"column",gap:1,children:[z0($$,{children:"配置文件优先级(从高到低):"},void 0,!1,void 0,this),z0(N1,{flexDirection:"column",marginLeft:2,children:[z0($$,{children:["1. .blade/settings.local.json (本地配置,不提交 Git)"," ",W.localExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),z0($$,{children:["2. .blade/settings.json (项目配置,提交 Git)"," ",W.projectExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),z0($$,{children:["3. ~/.blade/settings.json (用户全局配置)"," ",W.globalExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),z0($$,{children:"说明:"},void 0,!1,void 0,this),z0(N1,{flexDirection:"column",marginLeft:2,children:[z0($$,{children:"- /permissions 命令只管理本地配置 (.blade/settings.local.json)"},void 0,!1,void 0,this),z0($$,{children:"- 修改全局或项目配置请直接编辑对应文件"},void 0,!1,void 0,this),z0($$,{children:"- 本地配置不会提交到 Git"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),V=(d)=>z0(N1,{flexDirection:"column",gap:1,children:[z0($$,{bold:!0,children:zV[d]},void 0,!1,void 0,this),z0($$,{children:"Permission rules are a tool name, optionally followed by a specifier in parentheses."},void 0,!1,void 0,this),z0($$,{color:"gray",children:"例如: WebFetch 或 Bash(ls:*)"},void 0,!1,void 0,this),z0(N1,{marginTop:1,children:z0(UV,{value:z,onChange:w,onSubmit:S},void 0,!1,void 0,this)},void 0,!1,void 0,this),z0($$,{color:"gray",children:"Enter 提交 · Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),g=(d,s)=>z0(N1,{flexDirection:"column",gap:1,children:[z0($$,{bold:!0,children:["Delete ",d," permission rule?"]},void 0,!0,void 0,this),z0($$,{children:s.rule},void 0,!1,void 0,this),z0($$,{color:"gray",children:"From project local settings"},void 0,!1,void 0,this),z0($$,{children:"Are you sure you want to delete this permission rule?"},void 0,!1,void 0,this),z0(XF,{items:[{label:"Yes",value:"yes"},{label:"No",value:"no"}],onSelect:(C)=>{if(C.value==="yes")y();else _("list"),L(null)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),u=(d)=>z0(N1,{flexDirection:"column",gap:1,children:[z0($$,{bold:!0,children:"Cannot delete this rule"},void 0,!1,void 0,this),z0($$,{children:d.rule},void 0,!1,void 0,this),z0($$,{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),z0($$,{color:"gray",children:"按任意键继续"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v=(d)=>z0(XF,{items:l,isFocused:H==="list",onSelect:o},void 0,!1,void 0,this),Z0=()=>{if(O)return z0($$,{children:"加载中..."},void 0,!1,void 0,this);if(G==="info")return D();if(H==="add")return V(G);if(H==="confirm-delete"&&B)return g(B.tab,B.entry);if(H==="locked"&&B)return u(B.entry);return v(G)};return z0(N1,{flexDirection:"column",borderStyle:"round",borderColor:Y?"cyan":"gray",padding:1,width:80,children:[z0($$,{color:"cyan",bold:!0,children:"⚙️ 权限管理器"},void 0,!1,void 0,this),I(),z0(N1,{flexDirection:"column",gap:1,children:Z0()},void 0,!1,void 0,this),N&&z0(N1,{marginTop:1,children:z0($$,{color:N.type==="success"?"green":"red",children:N.text},void 0,!1,void 0,this)},void 0,!1,void 0,this),z0(N1,{marginTop:1,children:z0($$,{color:"gray",children:"Tab 切换视图 · Esc 关闭 · Q 退出"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};f8();import{Box as t0,Text as N0,useInput as RV}from"ink";import{jsxDEV as a}from"react/jsx-dev-runtime";function WF({onCancel:$}){let Z=s$(),Y=Z.getAll(),Q=Z.getBySource(),X=Z.getStats(),J=Q$(!1,$);if(RV((G,q)=>{if(q.escape)$?.();else if(q.ctrl&&G==="c"||q.meta&&G==="c")J()}),Y.length===0)return a(t0,{flexDirection:"column",paddingY:1,children:[a(t0,{marginBottom:1,children:a(N0,{bold:!0,color:"cyan",children:"\uD83D\uDD0C 插件管理器"},void 0,!1,void 0,this)},void 0,!1,void 0,this),a(t0,{paddingLeft:2,children:a(N0,{color:"gray",children:"没有已加载的插件"},void 0,!1,void 0,this)},void 0,!1,void 0,this),a(t0,{marginTop:1,paddingLeft:2,flexDirection:"column",children:[a(N0,{color:"gray",children:"插件目录位置:"},void 0,!1,void 0,this),a(N0,{color:"gray",dimColor:!0,children:[" ","• ~/.blade/plugins/ - 用户级插件"]},void 0,!0,void 0,this),a(N0,{color:"gray",dimColor:!0,children:[" ","• .blade/plugins/ - 项目级插件"]},void 0,!0,void 0,this),a(N0,{color:"gray",dimColor:!0,children:[" ","• --plugin-dir - CLI 指定的插件"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),a(t0,{marginTop:1,paddingLeft:2,children:a(N0,{color:"gray",children:"使用 /plugins install <url> 安装新插件"},void 0,!1,void 0,this)},void 0,!1,void 0,this),a(t0,{marginTop:1,children:a(N0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return a(t0,{flexDirection:"column",paddingY:1,children:[a(t0,{marginBottom:1,children:[a(N0,{bold:!0,color:"cyan",children:"\uD83D\uDD0C 插件管理器"},void 0,!1,void 0,this),a(N0,{color:"gray",children:[" (共 ",X.total," 个插件)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),a(t0,{paddingLeft:2,marginBottom:1,children:a(N0,{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&&a(t0,{flexDirection:"column",marginBottom:1,children:[a(t0,{paddingLeft:1,children:[a(N0,{bold:!0,color:"magenta",children:"CLI 指定"},void 0,!1,void 0,this),a(N0,{color:"gray",children:" (--plugin-dir)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.cli.map((G)=>{let q=G.status==="active"?"✅":"⏸️";return a(t0,{flexDirection:"column",paddingLeft:2,children:[a(N0,{children:[a(N0,{bold:!0,color:"green",children:[q," ",G.manifest.name]},void 0,!0,void 0,this),a(N0,{color:"gray",children:[" v",G.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),a(t0,{paddingLeft:2,children:a(N0,{color:"gray",children:G.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),G.commands.length>0&&a(t0,{paddingLeft:2,children:a(N0,{color:"blue",children:["命令:"," ",G.commands.map((K)=>`/${K.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},G.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.project.length>0&&a(t0,{flexDirection:"column",marginBottom:1,children:[a(t0,{paddingLeft:1,children:[a(N0,{bold:!0,color:"yellow",children:"项目级"},void 0,!1,void 0,this),a(N0,{color:"gray",children:" (.blade/plugins/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.project.map((G)=>{let q=G.status==="active"?"✅":"⏸️";return a(t0,{flexDirection:"column",paddingLeft:2,children:[a(N0,{children:[a(N0,{bold:!0,color:"green",children:[q," ",G.manifest.name]},void 0,!0,void 0,this),a(N0,{color:"gray",children:[" v",G.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),a(t0,{paddingLeft:2,children:a(N0,{color:"gray",children:G.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),G.commands.length>0&&a(t0,{paddingLeft:2,children:a(N0,{color:"blue",children:["命令:"," ",G.commands.map((K)=>`/${K.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},G.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.user.length>0&&a(t0,{flexDirection:"column",marginBottom:1,children:[a(t0,{paddingLeft:1,children:[a(N0,{bold:!0,color:"cyan",children:"用户级"},void 0,!1,void 0,this),a(N0,{color:"gray",children:" (~/.blade/plugins/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.user.map((G)=>{let q=G.status==="active"?"✅":"⏸️";return a(t0,{flexDirection:"column",paddingLeft:2,children:[a(N0,{children:[a(N0,{bold:!0,color:"green",children:[q," ",G.manifest.name]},void 0,!0,void 0,this),a(N0,{color:"gray",children:[" v",G.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),a(t0,{paddingLeft:2,children:a(N0,{color:"gray",children:G.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),G.commands.length>0&&a(t0,{paddingLeft:2,children:a(N0,{color:"blue",children:["命令:"," ",G.commands.map((K)=>`/${K.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},G.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),a(t0,{marginTop:1,paddingLeft:2,flexDirection:"column",children:[a(N0,{color:"gray",children:"可用命令:"},void 0,!1,void 0,this),a(N0,{color:"gray",dimColor:!0,children:[" ","• /plugins list - 列出所有插件"]},void 0,!0,void 0,this),a(N0,{color:"gray",dimColor:!0,children:[" ","• /plugins info <name> - 显示插件详情"]},void 0,!0,void 0,this),a(N0,{color:"gray",dimColor:!0,children:[" ","• /plugins install <url> - 安装插件"]},void 0,!0,void 0,this),a(N0,{color:"gray",dimColor:!0,children:[" ","• /plugins enable/disable <name> - 启用/禁用插件"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),a(t0,{marginTop:1,children:a(N0,{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 u$,Text as d$,useInput as UF,useStdout as VV}from"ink";import MV from"ink-text-input";import YQ,{useCallback as z6,useMemo as DV,useState as L4}from"react";import{jsxDEV as D0}from"react/jsx-dev-runtime";var jV=YQ.memo(({option:$,index:Z,isSelected:Y,isMultiSelect:Q,isHighlighted:X})=>D0(u$,{flexDirection:"column",marginBottom:1,children:[D0(d$,{color:X?"yellow":Y?"green":void 0,bold:X,children:[Q?Y?"● ":"○ ":X?"❯ ":" ",Z+1,". ",$.label]},void 0,!0,void 0,this),D0(u$,{marginLeft:4,children:D0(d$,{color:"gray",children:$.description},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)),yV=YQ.memo(({questions:$,answers:Z})=>D0(u$,{flexDirection:"column",marginBottom:1,children:$.map((Y)=>{let Q=Z[Y.header],X=Array.isArray(Q)?Q.join(", "):Q||"(no answer)";return D0(u$,{marginBottom:1,children:[D0(d$,{backgroundColor:"blue",color:"white",children:[" ",Y.header," "]},void 0,!0,void 0,this),D0(d$,{color:"green",children:[" ",X]},void 0,!0,void 0,this)]},Y.header,!0,void 0,this)})},void 0,!1,void 0,this)),OF=YQ.memo(({questions:$,onComplete:Z,onCancel:Y})=>{let{stdout:Q}=VV(),X=Q.columns||80,G=q1()==="confirmation-prompt",q=Q$(!1),[K,W]=L4("answering"),[U,O]=L4(0),[F,H]=L4({}),[_,z]=L4(0),[w,B]=L4([]),[L,N]=L4(!1),[M,b]=L4(""),[j,T]=L4(0),A=$[U],k=DV(()=>{if(!A)return[];return[...A.options.map((I)=>({label:I.label,value:I.label,description:I.description})),{label:"Type something...",value:"__other__",description:"Enter custom response"}]},[A]),c=z6((I)=>{let D={...F,[A.header]:I};if(H(D),U<$.length-1)O(U+1),z(0),B([]),N(!1),b("");else W("submit"),T(0)},[F,A?.header,U,$.length]),o=z6((I)=>{let D=k[I];if(!D)return;if(D.value==="__other__"){N(!0);return}if(A.multiSelect)B((V)=>V.includes(D.value)?V.filter((g)=>g!==D.value):[...V,D.value]);else c(D.value)},[k,A?.multiSelect,c]),S=z6((I)=>{if(I.trim())c(I.trim())},[c]),y=z6(()=>{W("answering"),O(0),z(0),B([]),N(!1)},[]),l=z6(()=>{Z(F)},[F,Z]);if(UF((I,D)=>{if(D.ctrl&&I==="c"||D.meta&&I==="c"){q();return}if(L){if(D.escape)N(!1),b("");return}if(D.escape){Y();return}let V=parseInt(I);if(V>=1&&V<=k.length){o(V-1);return}if(D.upArrow){z((g)=>g>0?g-1:k.length-1);return}if(D.downArrow||D.tab){z((g)=>g<k.length-1?g+1:0);return}if(D.return){if(A.multiSelect&&w.length>0)c(w);else o(_);return}if(I===" "&&A.multiSelect){let g=k[_];if(g&&g.value!=="__other__")B((u)=>u.includes(g.value)?u.filter((v)=>v!==g.value):[...u,g.value]);return}},{isActive:G&&K==="answering"&&!L}),UF((I,D)=>{if(D.ctrl&&I==="c"||D.meta&&I==="c"){q();return}if(D.escape){Y();return}if(D.upArrow||D.downArrow||D.tab){T((V)=>V===0?1:0);return}if(D.return){if(j===0)l();else y();return}if(I.toLowerCase()==="y"){l();return}if(I.toLowerCase()==="e"){y();return}},{isActive:G&&K==="submit"}),K==="submit")return D0(u$,{flexDirection:"column",borderStyle:"round",borderColor:G?"green":"gray",padding:1,width:Math.min(X-4,80),children:[D0(u$,{marginBottom:1,children:D0(d$,{bold:!0,color:"green",children:"✓ Review Your Answers"},void 0,!1,void 0,this)},void 0,!1,void 0,this),D0(yV,{questions:$,answers:F},void 0,!1,void 0,this),D0(u$,{flexDirection:"column",marginTop:1,children:[D0(d$,{color:j===0?"yellow":void 0,bold:j===0,children:[j===0?"❯ ":" ","[Y] Submit answers"]},void 0,!0,void 0,this),D0(d$,{color:j===1?"yellow":void 0,bold:j===1,children:[j===1?"❯ ":" ","[E] Edit answers"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),D0(u$,{marginTop:1,children:D0(d$,{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(!A)return null;return D0(u$,{flexDirection:"column",borderStyle:"round",borderColor:G?"cyan":"gray",padding:1,width:Math.min(X-4,80),children:[D0(u$,{marginBottom:1,children:[D0(d$,{backgroundColor:"blue",color:"white",children:[" ",A.header," "]},void 0,!0,void 0,this),D0(d$,{children:[" ",A.question]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),L?D0(u$,{flexDirection:"column",marginTop:1,children:[D0(d$,{color:"yellow",children:"Enter your response:"},void 0,!1,void 0,this),D0(u$,{marginTop:1,children:[D0(d$,{color:"cyan",children:"❯ "},void 0,!1,void 0,this),D0(MV,{value:M,onChange:b,onSubmit:S,focus:G},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D0(u$,{marginTop:1,children:D0(d$,{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):D0(u$,{flexDirection:"column",children:k.map((I,D)=>D0(jV,{option:I,index:D,isSelected:w.includes(I.value),isMultiSelect:A.multiSelect,isHighlighted:_===D},I.value,!1,void 0,this))},void 0,!1,void 0,this),!L&&D0(u$,{marginTop:1,flexDirection:"column",children:[D0(d$,{color:"gray",children:A.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),A.multiSelect&&w.length>0&&D0(d$,{color:"green",children:["Selected: ",w.join(", ")]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$.length>1&&D0(u$,{marginTop:1,children:D0(d$,{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)});i3();import{Box as J3,Text as Q2,useInput as TV}from"ink";import EV from"ink-select-input";import{basename as IV}from"node:path";import{useEffect as FF,useMemo as U5,useState as QQ}from"react";import{jsxDEV as y$}from"react/jsx-dev-runtime";function vV($){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 PV($){return IV($)}var CV=({isSelected:$})=>y$(J3,{marginRight:1,children:y$(Q2,{color:$?"cyan":"gray",children:$?"❯":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),SV=({isSelected:$,label:Z})=>y$(Q2,{color:$?"cyan":"white",bold:$,children:Z},void 0,!1,void 0,this),B6=20,HF=({sessions:$,onSelect:Z,onCancel:Y})=>{let[Q,X]=QQ([]),[J,G]=QQ(!1),[q,K]=QQ(0),U=q1()==="session-selector",O=Q$(!1);TV((L,N)=>{if(N.ctrl&&L==="c"||N.meta&&L==="c"){O();return}if(N.escape&&Y){Y();return}if(N.leftArrow||L==="h"||L==="H"){if(q>0)K((M)=>M-1);return}if(N.rightArrow||L==="l"||L==="L"){if(q<_-1)K((M)=>M+1);return}},{isActive:U}),FF(()=>{if($){X($);return}(async()=>{G(!0);try{let N=await S$.listSessions();X(N)}catch(N){console.error("[SessionSelector] Failed to load sessions:",N),X([])}finally{G(!1)}})()},[$]);let F=$||Q,H=U5(()=>{return F.map((L)=>{let N=PV(L.projectPath),M=vV(L.lastMessageTime),b=L.gitBranch?` (${L.gitBranch})`:"",j=L.hasErrors?" ⚠️":"",T=L.relationType==="subagent"?" ↳ subagent":"";return{label:`\uD83D\uDCC5 ${M} | ${N}${b} | ${L.messageCount} 条消息${j}${T}`,value:L.sessionId}})},[F]),_=U5(()=>Math.max(1,Math.ceil(H.length/B6)),[H.length]),z=U5(()=>{let L=q*B6;return H.slice(L,L+B6)},[H,q]),w=U5(()=>({start:q*B6+1,end:Math.min((q+1)*B6,H.length)}),[q,H.length]);FF(()=>{K(0)},[F.length]);let B=(L)=>{Z(L.value)};if(J)return y$(J3,{flexDirection:"column",paddingX:2,paddingY:1,children:y$(Q2,{children:"⏳ 正在加载会话列表..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(F.length===0)return y$(J3,{flexDirection:"column",paddingX:2,paddingY:1,children:[y$(Q2,{color:"yellow",children:"⚠️ 没有找到历史会话"},void 0,!1,void 0,this),y$(Q2,{dimColor:!0,children:[`
2847
+ `).length}var oY=MR.memo(({content:$,isStreaming:Z=!1,isExpanded:Y})=>{let Q=d0(),X=kO(()=>jR($),[$]),J=kO(()=>DR($),[$]),G=Q.colors.info,q=Q.colors.muted;return v2(nY,{flexDirection:"column",marginBottom:1,children:[v2(nY,{flexDirection:"row",children:[v2(Q3,{color:G,children:Y?"▼":"▶"},void 0,!1,void 0,this),v2(Q3,{children:" "},void 0,!1,void 0,this),v2(Q3,{color:q,children:["Thinking",Z?"...":` (${X} lines)`]},void 0,!0,void 0,this),!Y&&!Z&&J&&v2(Q3,{color:q,children:[" - ",J]},void 0,!0,void 0,this),v2(Q3,{color:q,dimColor:!0,children:[" ","[Ctrl+T]"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),Y&&$&&v2(nY,{marginLeft:2,marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,paddingY:0,children:v2(Q3,{color:q,children:$},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)});oY.displayName="ThinkingBlock";import{Box as X5,Text as sY}from"ink";import fO from"react";import{jsxDEV as H4}from"react/jsx-dev-runtime";var hO=fO.memo(({todos:$,visible:Z=!0,compact:Y=!1})=>{let{colors:Q}=d0();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 H4(X5,{flexDirection:"column",borderStyle:"single",borderColor:Q.border.light,paddingX:1,paddingY:Y?0:1,marginBottom:1,children:[H4(X5,{marginBottom:Y?0:1,children:[H4(sY,{dimColor:!0,children:"Tasks "},void 0,!1,void 0,this),H4(sY,{color:Q.text.muted,children:[X.completed,"/",X.total]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),H4(X5,{flexDirection:"column",children:$.map((J,G)=>H4(yR,{todo:J,compact:Y},J.id||G,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}),yR=fO.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 H4(X5,{paddingY:Z?0:0,children:H4(sY,{dimColor:Q,children:[Y," ",X]},void 0,!0,void 0,this)},void 0,!1,void 0,this)});import{jsxDEV as b$}from"react/jsx-dev-runtime";var pO=ER.memo(()=>{let $=h6(),Z=wU(),Y=LU(),Q=NU(),X=U4(),J=JU(),G=WU(),q=_U(),K=zU(),W=BU(),U=$U(),O=bU(),F=AU(),H=o8(),_=PO(),{stdout:z}=TR(),w=K4(),[B,L]=eY(null),[N,M]=eY([]),[b,j]=eY(new Set),T=_4(F),A=_4(null),k=_4(0),c=_4(0),o=_4(new Set),S=_4(new Set),y=_4([]),l=_4(null);q8(()=>{if(T.current!==F){if(z)z.write(tY.clearTerminal);w.incrementClearCount(),T.current=F}},[F,z,w]);let I=$,D=Q;q8(()=>{if(!Q||X){l.current=null;return}if(l.current===Q)return;l.current=Q;let C=setTimeout(()=>{if(z)z.write(tY.clearTerminal);o.current=new Set,S.current=new Set(I.filter((i)=>i.role==="tool").map((i)=>i.id)),A.current=null,k.current=0,c.current=0,y.current=[],M([]),j(new Set),w.incrementClearCount(),w.clearFinalizingStreamingMessageId()},50);return()=>clearTimeout(C)},[Q,X,z,w,I]);let V=Z??Q;q8(()=>{A.current=null,k.current=0,c.current=0,o.current=new Set,S.current=new Set(I.filter((C)=>C.role==="tool").map((C)=>C.id)),y.current=[],M([]),j(new Set)},[U]),q8(()=>{if(!V)return;if(A.current===V)return;A.current=V,k.current=0,c.current=0,S.current=new Set(I.filter((C)=>C.role==="tool").map((C)=>C.id)),y.current=[],M([])},[V,I]),q8(()=>{if(!V)return;let C=P5(V);if(!C||C.length<=k.current)return;let i=C.slice(k.current);k.current=C.length;let n=i,B0=y.current;if(B0.length>0)if(n.some((K1)=>K1.type!=="empty"))n=[...B0,...n],y.current=[];else{y.current=[...B0,...n];return}let j0=n.length;while(j0>0&&n[j0-1].type==="empty")j0-=1;if(j0!==n.length)y.current=n.slice(j0),n=n.slice(0,j0);if(n.length===0)return;let K$=c.current;c.current+=1;let $1=K$>0;j((K1)=>{if(!V||K1.has(V))return K1;let b1=new Set(K1);return b1.add(V),b1}),M((K1)=>[...K1,b$(P2,{flexDirection:"column",children:b$(F4,{content:"",role:"assistant",terminalWidth:H,isPending:!1,hidePrefix:$1,noMargin:!0,blocksOverride:n,renderCodeBlocksAsPlainText:!0},void 0,!1,void 0,this)},`streaming-${V}-${K$}`,!1,void 0,this)])},[V,Y.version,H,U]),q8(()=>{if(!V)return;let C=S.current,i=I.filter((n)=>n.role==="tool"&&!C.has(n.id)&&!o.current.has(n.id));if(i.length===0)return;for(let n of i)o.current.add(n.id);M((n)=>[...n,...i.map((B0)=>b$(P2,{flexDirection:"column",children:b$(F4,{content:B0.content,role:B0.role,terminalWidth:H,metadata:B0.metadata,isPending:!1,messageId:B0.id},void 0,!1,void 0,this)},`streaming-tool-${B0.id}`,!1,void 0,this))])},[V,I,H]);let g=J5(()=>{if(!V)return null;let C=mQ(V);if(!C||C.lines.length===0)return null;let n=Math.max(1,_-8),B0=Math.max(0,C.lines.length-n);return{visibleLines:C.lines.slice(-n),hiddenLines:B0,mode:C.mode}},[V,Y.version,_]),u=J5(()=>{if(!V)return!1;return(P5(V)?.length??0)>0},[V,Y.version]);q8(()=>{if(B===null&&I.length>O){if(L(I.length),z)z.write(tY.clearTerminal);w.incrementClearCount()}},[I.length,O,B,z,w]);let v=J5(()=>{return J.some((C)=>C.status==="pending"||C.status==="in_progress")},[J]),Z0=F?0:B??0,d=Z0,s=J5(()=>{let C=[];if(C.push(b$(SO,{},"header",!1,void 0,this)),d>0)C.push(b$(aY,{collapsedCount:d},"collapsed-summary",!1,void 0,this));for(let i=Z0;i<I.length;i++){let n=I[i];if(D&&n.id===D)continue;if(n.role==="tool"&&o.current.has(n.id))continue;if(n.role==="assistant"&&b.has(n.id))continue;C.push(b$(P2,{flexDirection:"column",children:b$(F4,{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 C},[I,Z0,d,H,D,b]);return b$(P2,{flexDirection:"column",paddingX:2,children:b$(P2,{flexDirection:"column",children:[b$(xO,{items:s,children:(C)=>C},U,!1,void 0,this),K&&b$(P2,{marginBottom:1,children:b$(oY,{content:K,isStreaming:X,isExpanded:W},void 0,!1,void 0,this)},void 0,!1,void 0,this),N.length>0&&b$(xO,{items:N,children:(C)=>C},`streaming-${U}`,!1,void 0,this),g&&b$(P2,{flexDirection:"column",children:b$(F4,{content:"",role:"assistant",terminalWidth:H,isPending:!0,hidePrefix:u,streamingLines:g.visibleLines,streamingHiddenLines:g.hiddenLines,streamingMode:g.mode},void 0,!1,void 0,this)},void 0,!1,void 0,this),G&&v&&b$(P2,{marginTop:1,children:b$(hO,{todos:J,visible:!0,compact:!1},void 0,!1,void 0,this)},void 0,!1,void 0,this),q.map((C,i)=>b$(P2,{flexDirection:"column",children:b$(F4,{content:C.displayText,role:"user",terminalWidth:H},void 0,!1,void 0,this)},`pending-${i}`,!1,void 0,this))]},void 0,!0,void 0,this)},void 0,!1,void 0,this)});M0();import{useMemoizedFn as S2}from"ahooks";import{Box as h$,Text as w$,useFocusManager as nR,useInput as YF}from"ink";import oR from"ink-text-input";import{useState as B4}from"react";import{Box as C2,Text as B1,useInput as IR}from"ink";import vR from"ink-text-input";import{jsxDEV as q$}from"react/jsx-dev-runtime";var mO=({provider:$,value:Z,onChange:Y,onSubmit:Q,onCancel:X,error:J})=>{IR((q,K)=>{if(K.escape)X()});let G=$.envVars.length>0?$.envVars[0]:null;return q$(C2,{flexDirection:"column",children:[q$(C2,{marginBottom:1,children:q$(B1,{bold:!0,color:"blue",children:"\uD83D\uDD11 Step 2: 输入 API Key"},void 0,!1,void 0,this)},void 0,!1,void 0,this),q$(C2,{marginBottom:1,children:q$(B1,{children:["Provider: ",$.icon," ",q$(B1,{bold:!0,children:$.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),G&&q$(C2,{marginBottom:1,children:q$(B1,{dimColor:!0,children:["\uD83D\uDCA1 环境变量: ",q$(B1,{color:"cyan",children:G},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),$.docUrl&&q$(C2,{marginBottom:1,children:q$(B1,{dimColor:!0,children:["\uD83D\uDCD6 文档: ",q$(B1,{color:"blue",children:$.docUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),q$(C2,{marginBottom:1,children:q$(B1,{dimColor:!0,children:"您的 API 密钥将被安全存储在 ~/.blade/config.json (权限 600)"},void 0,!1,void 0,this)},void 0,!1,void 0,this),q$(C2,{children:[q$(B1,{bold:!0,color:"cyan",children:["▶"," "]},void 0,!0,void 0,this),q$(vR,{value:Z,onChange:Y,onSubmit:Q,placeholder:"sk-...",mask:"*"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J&&q$(C2,{marginTop:1,children:q$(B1,{color:"red",children:["❌ ",J]},void 0,!0,void 0,this)},void 0,!1,void 0,this),q$(C2,{marginTop:1,children:q$(B1,{dimColor:!0,children:["\uD83D\uDCA1 输入完成后按 ",q$(B1,{bold:!0,children:"Enter"},void 0,!1,void 0,this),",",q$(B1,{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 gO,useState as X3}from"react";w8();var PR={id:"custom-openai-compatible",name:"自定义 OpenAI Compatible",icon:"\uD83D\uDD27",description:"使用自定义 Base URL 和 API Key",isOAuth:!1,envVars:[],bladeProvider:"openai-compatible",isCustom:!0},uO=()=>{let[$,Z]=X3([]),[Y,Q]=X3(!0),[X,J]=X3(null);return gO(()=>{(async()=>{try{let q=await P6(),K=Object.entries(V7).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,PR,...q])}catch(q){J(q instanceof Error?q.message:"加载 Provider 列表失败")}finally{Q(!1)}})()},[]),{providers:$,isLoading:Y,error:X}},dO=($)=>{let[Z,Y]=X3([]),[Q,X]=X3(!1),[J,G]=X3(null);return gO(()=>{if(!$){Y([]);return}(async()=>{X(!0),G(null);try{let K=await C6($);Y(K)}catch(K){G(K instanceof Error?K.message:"加载模型列表失败")}finally{X(!1)}})()},[$]),{models:Z,isLoading:Q,error:J}};import{Box as Y2,Text as f1,useInput as CR}from"ink";import SR from"ink-select-input";import cO from"ink-text-input";import{useMemo as lO,useState as $Q}from"react";import{jsxDEV as i0,Fragment as xR}from"react/jsx-dev-runtime";var kR=({isSelected:$})=>i0(Y2,{marginRight:1,children:i0(f1,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),fR=($)=>{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(" ")},hR=({isSelected:$,label:Z})=>i0(f1,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),iO=({provider:$,models:Z,isLoading:Y,error:Q,onSelect:X,onCancel:J,initialModel:G})=>{let[q,K]=$Q(""),W=$.isCustom||Z.length===0,[U,O]=$Q(W),[F,H]=$Q(G||"");CR((B,L)=>{if(L.escape){if(U&&!W)O(!1),H(G||"");else if(q)K("");else J();return}if(B==="+"&&!U)O(!0)});let _=lO(()=>{if(!q)return Z;let B=q.toLowerCase();return Z.filter((L)=>L.name.toLowerCase().includes(B)||L.id.toLowerCase().includes(B))},[Z,q]),z=lO(()=>_.map((B)=>({key:B.id,label:fR(B),value:B})),[_]),w=()=>{if(F.trim())X({id:F.trim(),name:F.trim()})};if(Y)return i0(Y2,{flexDirection:"column",children:i0(f1,{color:"yellow",children:["⏳ 正在加载 ",$.name," 模型列表..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this);if(Q)return i0(Y2,{flexDirection:"column",children:[i0(f1,{color:"red",children:["❌ ",Q]},void 0,!0,void 0,this),i0(f1,{dimColor:!0,children:"按 Esc 返回"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return i0(Y2,{flexDirection:"column",children:[i0(Y2,{marginBottom:1,children:i0(f1,{bold:!0,color:"blue",children:"\uD83E\uDD16 Step 3: 选择模型"},void 0,!1,void 0,this)},void 0,!1,void 0,this),i0(Y2,{marginBottom:1,children:i0(f1,{children:["Provider: ",$.icon," ",i0(f1,{bold:!0,children:$.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),U?i0(Y2,{flexDirection:"column",children:[i0(Y2,{marginBottom:1,children:i0(f1,{dimColor:!0,children:W?"输入模型名称:":"输入自定义模型名称(按 Esc 返回列表):"},void 0,!1,void 0,this)},void 0,!1,void 0,this),i0(Y2,{children:[i0(f1,{bold:!0,color:"cyan",children:"▶ "},void 0,!1,void 0,this),i0(cO,{value:F,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):i0(xR,{children:[i0(Y2,{marginBottom:1,children:[i0(f1,{color:"cyan",children:"\uD83D\uDD0D "},void 0,!1,void 0,this),i0(cO,{value:q,onChange:K,placeholder:`搜索 ${Z.length} 个模型,按 + 自定义...`},void 0,!1,void 0,this)]},void 0,!0,void 0,this),i0(Y2,{flexDirection:"column",height:12,children:i0(SR,{items:z,onSelect:(B)=>X(B.value),indicatorComponent:kR,itemComponent:hR,limit:10},void 0,!1,void 0,this)},void 0,!1,void 0,this),_.length===0&&i0(f1,{color:"yellow",children:"未找到匹配的模型,按 + 输入自定义模型名称"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};R3();N3();T3();D3();import{Box as h1,Text as w1,useFocus as aO,useInput as nO}from"ink";import pR from"ink-select-input";import{useEffect as mR,useState as rO}from"react";import{jsxDEV as s0}from"react/jsx-dev-runtime";var oO=({provider:$,onLogin:Z,onCancel:Y,isLoggingIn:Q})=>{let{isFocused:X}=aO({id:"oauth-login"});return nO((J,G)=>{if(Q)return;if(J==="y"||J==="Y")Z();else if(J==="n"||J==="N"||G.escape)Y()},{isActive:X&&!Q}),s0(h1,{flexDirection:"column",children:[s0(h1,{marginBottom:1,children:s0(w1,{bold:!0,color:"yellow",children:[$.icon," 需要登录 ",$.name]},void 0,!0,void 0,this)},void 0,!1,void 0,this),s0(h1,{marginBottom:1,children:s0(w1,{children:$.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),s0(h1,{marginBottom:1,paddingLeft:2,children:s0(w1,{dimColor:!0,children:["您也可以稍后手动执行"," ",s0(w1,{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&&s0(h1,{marginTop:1,children:s0(w1,{children:["现在登录? [",s0(w1,{bold:!0,color:"green",children:"Y"},void 0,!1,void 0,this),"/",s0(w1,{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&&s0(h1,{marginTop:1,children:s0(w1,{color:"yellow",children:"⏳ 正在启动登录流程..."},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},gR=({isSelected:$})=>s0(h1,{marginRight:1,children:s0(w1,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),uR=({isSelected:$,label:Z})=>s0(w1,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),sO=({provider:$,onSelect:Z,onCancel:Y})=>{let{isFocused:Q}=aO({id:"oauth-model-select"}),[X,J]=rO([]),[G,q]=rO(!0);mR(()=>{(async()=>{q(!0);try{if($.id==="copilot")J(Object.values(E7));else{let O=await p$.getInstance().getConfigType();J(O==="gemini-cli"?Object.values(D7):Object.values(L3))}}catch{J(Object.values(L3))}finally{q(!1)}})()},[$.id]),nO((W,U)=>{if(U.escape)Y()},{isActive:Q});let K=X.map((W)=>({key:W.id,label:`${W.name} - ${W.description}`,value:{id:W.id,name:W.name}}));if(G)return s0(h1,{flexDirection:"column",children:s0(w1,{color:"yellow",children:["⏳ 加载 ",$.name," 模型列表..."]},void 0,!0,void 0,this)},void 0,!1,void 0,this);return s0(h1,{flexDirection:"column",children:[s0(h1,{marginBottom:1,children:s0(w1,{bold:!0,color:"blue",children:["\uD83E\uDD16 选择 ",$.name," 模型"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),s0(h1,{marginBottom:1,children:s0(w1,{dimColor:!0,children:"从可用模型列表中选择一个"},void 0,!1,void 0,this)},void 0,!1,void 0,this),s0(h1,{flexDirection:"column",height:12,children:s0(pR,{items:K,onSelect:(W)=>Z(W.value),indicatorComponent:gR,itemComponent:uR,limit:10},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},tO=async($)=>{let Z=$==="antigravity"?p$.getInstance():r$.getInstance();try{return await Z.login(),!0}catch{return!1}},eO=async($)=>{let Z=$==="antigravity"?p$.getInstance():r$.getInstance();try{return await Z.isLoggedIn()}catch{return!1}};import{Box as K8,Text as z4,useInput as dR}from"ink";import cR from"ink-select-input";import lR from"ink-text-input";import{useMemo as $F,useState as iR}from"react";import{jsxDEV as f$}from"react/jsx-dev-runtime";var rR=({isSelected:$})=>f$(K8,{marginRight:1,children:f$(z4,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),aR=({isSelected:$,label:Z})=>f$(z4,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),ZF=({providers:$,isLoading:Z,error:Y,onSelect:Q,onCancel:X})=>{let[J,G]=iR("");dR((W,U)=>{if(U.escape)if(J)G("");else X()});let q=$F(()=>{if(!J)return $;let W=J.toLowerCase();return $.filter((U)=>U.name.toLowerCase().includes(W)||U.id.toLowerCase().includes(W))},[$,J]),K=$F(()=>q.map((W)=>({key:W.id,label:`${W.icon} ${W.name} - ${W.description}`,value:W})),[q]);if(Z)return f$(K8,{flexDirection:"column",children:f$(z4,{color:"yellow",children:"⏳ 正在加载 Provider 列表..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(Y)return f$(K8,{flexDirection:"column",children:[f$(z4,{color:"red",children:["❌ ",Y]},void 0,!0,void 0,this),f$(z4,{dimColor:!0,children:"按 Esc 返回"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return f$(K8,{flexDirection:"column",children:[f$(K8,{marginBottom:1,children:f$(z4,{bold:!0,color:"blue",children:"\uD83D\uDCE1 Step 1: 选择 API 提供商"},void 0,!1,void 0,this)},void 0,!1,void 0,this),f$(K8,{marginBottom:1,children:[f$(z4,{color:"cyan",children:"\uD83D\uDD0D "},void 0,!1,void 0,this),f$(lR,{value:J,onChange:G,placeholder:`搜索 ${$.length} 个 Provider...`},void 0,!1,void 0,this)]},void 0,!0,void 0,this),f$(K8,{flexDirection:"column",height:12,children:f$(cR,{items:K,onSelect:(W)=>Q(W.value),indicatorComponent:rR,itemComponent:aR,limit:10},void 0,!1,void 0,this)},void 0,!1,void 0,this),q.length===0&&f$(z4,{color:"yellow",children:"未找到匹配的 Provider,按 Esc 清除搜索"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};w8();import{jsxDEV as K0,Fragment as tR}from"react/jsx-dev-runtime";var ZQ=({mode:$,initialConfig:Z,modelId:Y,onComplete:Q,onCancel:X})=>{let J=$==="edit",[G,q]=B4("provider"),[K,W]=B4(),[U,O]=B4(J?Z?.apiKey||"":""),[F,H]=B4(J?Z?.baseUrl||"":""),[_]=B4(J?Z?.model||"":""),[z,w]=B4(),[B,L]=B4(!1),[N,M]=B4(!1),{providers:b,isLoading:j,error:T}=uO(),{models:A,isLoading:k,error:c}=dO(K?.isOAuth?void 0:K?.id),o=Q$(!1),{focus:S}=nR();YF((i,n)=>{if(n.ctrl&&i==="c"||n.meta&&i==="c")$==="setup"?o():X()});let y=S2((i)=>{let B0={provider:"",apiKey:"",baseUrl:"",model:"",oauthLogin:"oauth-login",oauthModelSelect:"oauth-model-select",confirm:""}[i];if(B0)S(B0)}),l=S2((i)=>{return i.defaultBaseUrl||M7[i.id]||""}),I=S2(async(i)=>{W(i),w(void 0);let n=l(i);if(!J)H(n);if(i.isOAuth){let j0=await eO(i.id)?"oauthModelSelect":"oauthLogin";q(j0),y(j0)}else q("apiKey")}),D=S2(()=>{if(!U.trim()){w("API Key 不能为空");return}w(void 0);let i=K?l(K):"";if(K?.isCustom||!i&&!F)q("baseUrl");else q("model")}),V=S2(()=>{if(!F.trim()){w("Base URL 不能为空");return}try{new URL(F)}catch{w("请输入有效的 URL (例如: https://api.example.com/v1)");return}w(void 0),q("model")}),g=S2(async(i)=>{w(void 0),L(!0);try{let n=F||(K?l(K):""),j0={name:J&&Z?.name?Z.name:`${K?.name||"Model"} - ${i.name}`,provider:K?.bladeProvider||Z?.provider||"openai-compatible",baseUrl:n,apiKey:K?.isOAuth?"oauth":U,model:i.id,...i.contextWindow&&{maxContextTokens:i.contextWindow},...i.maxOutput&&{maxOutputTokens:i.maxOutput},...K?.id&&{providerId:K.id}};if($==="setup")Q(j0);else if($==="add"){let K$=await b0().addModel(j0);await b0().setCurrentModel(K$.id),Q(j0)}else if($==="edit"&&Y)await b0().updateModel(Y,j0),Q(j0)}catch(n){w(n instanceof Error?n.message:"保存配置失败"),L(!1)}}),u=S2(async()=>{if(!K)return;M(!0),w(void 0);let i=await tO(K.id);if(M(!1),i)q("oauthModelSelect"),y("oauthModelSelect");else w("登录失败,请重试")}),v=S2(()=>{switch(w(void 0),G){case"apiKey":q("provider");break;case"baseUrl":q("apiKey");break;case"model":{if(!(K?l(K):""))q("baseUrl");else q("apiKey");break}case"oauthLogin":case"oauthModelSelect":q("provider");break}}),Z0=S2(()=>{q("apiKey")}),d=G==="provider"?1:G==="apiKey"||G==="oauthLogin"?2:G==="baseUrl"?2.5:3,s=3;return K0(h$,{...$==="setup"?{flexDirection:"column",padding:1}:{flexDirection:"column",borderStyle:"round",borderColor:$==="edit"?"yellow":"blue",padding:1},children:[$==="setup"&&K0(tR,{children:[K0(h$,{marginBottom:1,children:K0(w$,{bold:!0,color:"blue",children:"\uD83D\uDE80 欢迎使用 Blade Code"},void 0,!1,void 0,this)},void 0,!1,void 0,this),K0(h$,{marginBottom:1,children:K0(w$,{children:"AI 驱动的代码助手 - 让我们开始配置您的助手"},void 0,!1,void 0,this)},void 0,!1,void 0,this),K0(h$,{marginBottom:1,children:[K0(w$,{bold:!0,color:"blue",children:"█".repeat(Math.floor((d-1)/(s-1)*40))},void 0,!1,void 0,this),K0(w$,{dimColor:!0,children:"░".repeat(40-Math.floor((d-1)/(s-1)*40))},void 0,!1,void 0,this),K0(w$,{children:" "},void 0,!1,void 0,this),K0(w$,{bold:!0,color:"cyan",children:[Math.ceil(d),"/",s]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),K0(h$,{marginBottom:1,children:K0(w$,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$!=="setup"&&K0(h$,{justifyContent:"center",marginBottom:1,children:K0(w$,{bold:!0,color:$==="edit"?"yellow":"blue",children:$==="edit"?"编辑模型配置":"添加新模型配置"},void 0,!1,void 0,this)},void 0,!1,void 0,this),G==="provider"&&K0(ZF,{providers:b,isLoading:j,error:T,onSelect:I,onCancel:$==="setup"?()=>{}:X},void 0,!1,void 0,this),G==="apiKey"&&K&&K0(mO,{provider:K,value:U,onChange:O,onSubmit:D,onCancel:v,error:z},void 0,!1,void 0,this),G==="baseUrl"&&K&&K0(sR,{provider:K,value:F,onChange:H,onSubmit:V,onCancel:Z0,error:z},void 0,!1,void 0,this),G==="model"&&K&&K0(iO,{provider:K,models:A,isLoading:k,error:c,onSelect:g,onCancel:v,initialModel:J?_:void 0},void 0,!1,void 0,this),G==="oauthLogin"&&K&&K0(oO,{provider:K,onLogin:u,onCancel:v,isLoggingIn:N},void 0,!1,void 0,this),G==="oauthModelSelect"&&K&&K0(sO,{provider:K,onSelect:g,onCancel:v},void 0,!1,void 0,this),z&&G!=="apiKey"&&G!=="baseUrl"&&K0(h$,{marginTop:1,borderStyle:"round",borderColor:"red",paddingX:1,children:K0(w$,{color:"red",children:["❌ ",z]},void 0,!0,void 0,this)},void 0,!1,void 0,this),B&&K0(h$,{marginTop:1,children:K0(w$,{color:"yellow",children:"⏳ 正在保存配置..."},void 0,!1,void 0,this)},void 0,!1,void 0,this),K0(h$,{marginTop:1,children:K0(w$,{dimColor:!0,children:"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},sR=({provider:$,value:Z,onChange:Y,onSubmit:Q,onCancel:X,error:J})=>{return YF((G,q)=>{if(q.escape)X()}),K0(h$,{flexDirection:"column",children:[K0(h$,{marginBottom:1,children:K0(w$,{bold:!0,color:"blue",children:"\uD83C\uDF10 输入 Base URL"},void 0,!1,void 0,this)},void 0,!1,void 0,this),K0(h$,{marginBottom:1,children:K0(w$,{children:["Provider: ",$.icon," ",K0(w$,{bold:!0,children:$.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),K0(h$,{marginBottom:1,children:K0(w$,{dimColor:!0,children:"此 Provider 没有默认的 API 端点,请输入完整的 Base URL"},void 0,!1,void 0,this)},void 0,!1,void 0,this),K0(h$,{marginBottom:1,children:K0(w$,{dimColor:!0,children:"示例: https://api.example.com/v1"},void 0,!1,void 0,this)},void 0,!1,void 0,this),K0(h$,{children:[K0(w$,{bold:!0,color:"cyan",children:"▶ "},void 0,!1,void 0,this),K0(oR,{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&&K0(h$,{marginTop:1,children:K0(w$,{color:"red",children:["❌ ",J]},void 0,!0,void 0,this)},void 0,!1,void 0,this),K0(h$,{marginTop:1,children:K0(w$,{dimColor:!0,children:["\uD83D\uDCA1 输入完成后按 ",K0(w$,{bold:!0,children:"Enter"},void 0,!1,void 0,this),",",K0(w$,{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)};W9();import{useMemoizedFn as G5,useMount as eR}from"ahooks";import{Box as L1,Text as P0,useFocus as $V,useFocusManager as ZV,useInput as YV}from"ink";import QV from"ink-select-input";import{memo as XV,useMemo as JV,useState as q5}from"react";M0();import{jsxDEV as U0}from"react/jsx-dev-runtime";function GV($){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 qV=({isSelected:$})=>U0(L1,{marginRight:1,children:U0(P0,{color:$?"yellow":"gray",children:$?"▶":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),KV=({isSelected:$,label:Z})=>U0(P0,{bold:$,color:$?"yellow":void 0,children:Z},void 0,!1,void 0,this),QF=XV(({onClose:$,onEdit:Z})=>{let Y=UU(),Q=OU()??"",{isFocused:X}=$V({id:"model-selector"}),J=ZV(),[G,q]=q5(""),[K,W]=q5(!1),[U,O]=q5(null),F=Q$(!1),[H]=q5(()=>{let j=process.stdout?.columns||80;return Math.max(20,j-8)});eR(()=>{if(J?.focus("model-selector"),Y.length>0)q(Y[0].id)}),YV((j,T)=>{if(K)return;if(T.ctrl&&j==="c"||T.meta&&j==="c"){F();return}if(T.escape){$();return}if(!X)return;if(j==="d"||j==="D"){z();return}if((j==="e"||j==="E")&&Z)w()},{isActive:!0});let _=G5(async(j)=>{if(K)return;let T=j.value;if(T===Q){$();return}W(!0),O(null);try{await b0().setCurrentModel(T),$()}catch(A){O(A.message),W(!1)}}),z=G5(async()=>{if(K||G===Q)return;W(!0),O(null);try{if(await b0().removeModel(G),Y.length<=1)$()}catch(j){O(j.message)}finally{W(!1)}}),w=G5(()=>{if(K||!Z)return;let j=Y.find((T)=>T.id===G);if(!j)return;Z(j)}),B=G5((j)=>{q(j.value)}),L=JV(()=>{return Y.find((j)=>j.id===G)},[Y,G]),N=Y.map((j)=>{let T=j.id===Q?" (当前)":"";return{label:j.name+T,value:j.id}}),M=G===Q;return U0(L1,{flexDirection:"column",borderStyle:"round",borderColor:"gray",padding:1,width:"100%",children:[U0(L1,{flexDirection:"row",justifyContent:"space-between",marginBottom:1,children:[U0(P0,{bold:!0,color:"cyan",children:"模型管理"},void 0,!1,void 0,this),U0(P0,{dimColor:!0,children:[K?"⏳ 处理中...":M?"Enter=关闭 • E=编辑 • Esc=取消":"Enter=切换 • D=删除 • E=编辑 • Esc=取消"," • Ctrl+C=退出"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),U0(L1,{flexDirection:"row",children:[U0(L1,{flexDirection:"column",flexGrow:2,marginRight:2,borderStyle:"single",borderColor:"gray",padding:1,children:[U0(P0,{dimColor:!0,children:["已配置模型 (",Y.length,")"]},void 0,!0,void 0,this),U0(L1,{marginTop:1,children:U0(QV,{items:N,onSelect:_,onHighlight:B,indicatorComponent:qV,itemComponent:KV},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),U0(L1,{flexDirection:"column",flexGrow:3,borderStyle:"single",borderColor:"gray",padding:1,children:[U0(P0,{dimColor:!0,children:"模型详情"},void 0,!1,void 0,this),U0(L1,{marginY:1,children:U0(P0,{color:M?"green":"yellow",children:M?"● 当前使用":"● 可切换"},void 0,!1,void 0,this)},void 0,!1,void 0,this),L?U0(L1,{flexDirection:"column",children:[U0(P0,{children:[U0(P0,{dimColor:!0,children:"名称: "},void 0,!1,void 0,this),U0(P0,{bold:!0,color:"cyan",children:L.name},void 0,!1,void 0,this),K9(L)&&U0(P0,{color:"green",children:" (内置免费)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),U0(P0,{children:[U0(P0,{dimColor:!0,children:"Provider: "},void 0,!1,void 0,this),U0(P0,{bold:!0,children:GV(L.provider)},void 0,!1,void 0,this)]},void 0,!0,void 0,this),U0(P0,{children:[U0(P0,{dimColor:!0,children:"Model: "},void 0,!1,void 0,this),U0(P0,{bold:!0,children:L.model},void 0,!1,void 0,this)]},void 0,!0,void 0,this),U0(P0,{children:[U0(P0,{dimColor:!0,children:"Base URL: "},void 0,!1,void 0,this),U0(P0,{color:"blueBright",children:L.baseUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L.temperature!==void 0&&U0(P0,{children:[U0(P0,{dimColor:!0,children:"Temperature: "},void 0,!1,void 0,this),U0(P0,{children:L.temperature},void 0,!1,void 0,this)]},void 0,!0,void 0,this),L.maxContextTokens!==void 0&&U0(P0,{children:[U0(P0,{dimColor:!0,children:"Context Window: "},void 0,!1,void 0,this),U0(P0,{children:L.maxContextTokens},void 0,!1,void 0,this)]},void 0,!0,void 0,this),K9(L)&&U0(L1,{marginTop:1,children:U0(P0,{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):U0(P0,{dimColor:!0,children:"请选择一个模型查看详情"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),U&&U0(L1,{marginTop:1,children:U0(P0,{color:"red",children:["❌ ",U]},void 0,!0,void 0,this)},void 0,!1,void 0,this),U0(L1,{justifyContent:"center",marginTop:1,children:U0(P0,{dimColor:!0,children:"─".repeat(H)},void 0,!1,void 0,this)},void 0,!1,void 0,this),U0(L1,{justifyContent:"center",children:U0(P0,{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 H7}from"ahooks";import{promises as qF}from"fs";import{Box as N1,Text as $$,useInput as WV}from"ink";import XF from"ink-select-input";import UV from"ink-text-input";import OV from"os";import K5 from"path";import{useEffect as FV,useMemo as W5,useRef as HV,useState as w4}from"react";M0();import{jsxDEV as z0}from"react/jsx-dev-runtime";var _7=[{key:"allow",label:"Allow"},{key:"ask",label:"Ask"},{key:"deny",label:"Deny"},{key:"info",label:"Info"}],_V={allow:"Add a new rule...",ask:"Add a new rule...",deny:"Add a new rule..."},zV={allow:"Allow permission rules",ask:"Ask permission rules",deny:"Deny permission rules"},JF={project:"[项目共享配置]",global:"[用户全局配置]",local:"[本地配置]"},BV=["project","global","local"],wV={allow:[],ask:[],deny:[]},LV={localExists:!1,projectExists:!1,globalExists:!1},GF={allow:[],ask:[],deny:[]};function NV($){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 AV($){try{let Z=await qF.readFile($,"utf-8"),Y=JSON.parse(Z);return{exists:!0,raw:Y,permissions:NV(Y)}}catch(Z){if(Z.code==="ENOENT")return{exists:!1,raw:{},permissions:{...GF}};return console.warn(`[PermissionsManager] Failed to read ${$}:`,Z),{exists:!0,raw:{},permissions:{...GF}}}}function bV($,Z){let Y=$.padEnd(32," "),Q=Z==="local"?`${JF[Z]} ← 可删除`:JF[Z];return`${Y} ${Q}`}var KF=({onClose:$})=>{let Y=q1()==="permissions-manager",Q=Q$(!1),[X,J]=w4(0),G=_7[X].key,[q,K]=w4(wV),[W,U]=w4(LV),[O,F]=w4(!0),[H,_]=w4("list"),[z,w]=w4(""),[B,L]=w4(null),[N,M]=w4(null),b=HV(!1),j=W5(()=>K5.join(process.cwd(),".blade","settings.local.json"),[]),T=W5(()=>K5.join(process.cwd(),".blade","settings.json"),[]),A=W5(()=>K5.join(OV.homedir(),".blade","settings.json"),[]),k=H7(async()=>{F(!0);let s=await Promise.all([{source:"local",path:j},{source:"project",path:T},{source:"global",path:A}].map(async({source:B0,path:j0})=>{let K$=await AV(j0);return{source:B0,path:j0,...K$}})),C={localExists:s.find((B0)=>B0.source==="local")?.exists??!1,projectExists:s.find((B0)=>B0.source==="project")?.exists??!1,globalExists:s.find((B0)=>B0.source==="global")?.exists??!1};U(C);let i={allow:[],ask:[],deny:[]},n=Object.fromEntries(s.map((B0)=>[B0.source,B0]));["allow","ask","deny"].forEach((B0)=>{BV.forEach((j0)=>{(n[j0]?.permissions[B0]??[]).forEach(($1,K1)=>{let b1={key:`${j0}:${K1}:${$1}`,rule:$1,source:j0};i[B0].push(b1)})})}),K(i),F(!1)});FV(()=>{k()},[k]);let c=H7(async(d,s)=>{try{let C=K5.join(process.cwd(),".blade","settings.local.json"),i={allow:[],ask:[],deny:[]};try{let B0=await qF.readFile(C,"utf-8"),K$=JSON.parse(B0).permissions||{};i={allow:Array.isArray(K$.allow)?K$.allow:[],ask:Array.isArray(K$.ask)?K$.ask:[],deny:Array.isArray(K$.deny)?K$.deny:[]}}catch(B0){}let n=s(i);await b0().updateConfig({permissions:n},{scope:"local",immediate:!0}),await k()}catch(C){throw console.error("[PermissionsManager] 修改权限规则失败:",C),C}});WV((d,s)=>{if(s.ctrl&&d==="c"||s.meta&&d==="c"){Q();return}if(H==="locked"){if(b.current){b.current=!1;return}_("list"),L(null),M(null);return}if(s.escape){if(H==="list"||G==="info")$();else _("list"),w(""),L(null),M(null);return}if(H==="list"){if(s.tab&&s.shift)J((C)=>(C-1+_7.length)%_7.length);else if(s.tab)J((C)=>(C+1)%_7.length);else if(d?.toLowerCase()==="q")$()}},{isActive:Y});let o=H7((d)=>{let s=d.value;if(G==="info")return;if(s.type==="add"){_("add"),w(""),M(null);return}if(s.entry.source!=="local"){_("locked"),b.current=!0,L({tab:G,entry:s.entry}),M({type:"error",text:s.entry.source==="project"?"此规则定义在项目共享配置中,无法在此删除。":"此规则来自用户全局配置,无法在此删除。"});return}_("confirm-delete"),L({tab:G,entry:s.entry}),M(null)}),S=H7(async()=>{if(G==="info")return;let d=z.trim();if(!d){M({type:"error",text:"Permission rule 不能为空"});return}if(q[G].map((C)=>C.rule).includes(d)){M({type:"error",text:"该规则已存在"});return}try{await c(G,(C)=>{let i={allow:[...C.allow],ask:[...C.ask],deny:[...C.deny]};return i[G]=[...new Set([...C[G],d])],i}),_("list"),w(""),M({type:"success",text:"已添加本地权限规则"})}catch(C){M({type:"error",text:`保存失败: ${C instanceof Error?C.message:"未知错误"}`})}}),y=H7(async()=>{if(!B)return;let{tab:d,entry:s}=B;try{await c(d,(C)=>{let i={allow:[...C.allow],ask:[...C.ask],deny:[...C.deny]};return i[d]=C[d].filter((n)=>n!==s.rule),i}),_("list"),L(null),M({type:"success",text:"已删除本地权限规则"})}catch(C){M({type:"error",text:`删除失败: ${C instanceof Error?C.message:"未知错误"}`})}}),l=W5(()=>{if(G==="info")return[];let d=G;return[{key:"add-new-rule",label:`› ${_V[d]}`,value:{type:"add"}},...q[d].map((C)=>({key:C.key,label:bV(C.rule,C.source),value:{type:"rule",entry:C}}))]},[G,q]),I=()=>z0(N1,{marginBottom:1,children:_7.map((d,s)=>z0(N1,{marginRight:2,children:z0($$,{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),D=()=>z0(N1,{flexDirection:"column",gap:1,children:[z0($$,{children:"配置文件优先级(从高到低):"},void 0,!1,void 0,this),z0(N1,{flexDirection:"column",marginLeft:2,children:[z0($$,{children:["1. .blade/settings.local.json (本地配置,不提交 Git)"," ",W.localExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),z0($$,{children:["2. .blade/settings.json (项目配置,提交 Git)"," ",W.projectExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this),z0($$,{children:["3. ~/.blade/settings.json (用户全局配置)"," ",W.globalExists?"✓ 存在":"✗ 不存在"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),z0($$,{children:"说明:"},void 0,!1,void 0,this),z0(N1,{flexDirection:"column",marginLeft:2,children:[z0($$,{children:"- /permissions 命令只管理本地配置 (.blade/settings.local.json)"},void 0,!1,void 0,this),z0($$,{children:"- 修改全局或项目配置请直接编辑对应文件"},void 0,!1,void 0,this),z0($$,{children:"- 本地配置不会提交到 Git"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),V=(d)=>z0(N1,{flexDirection:"column",gap:1,children:[z0($$,{bold:!0,children:zV[d]},void 0,!1,void 0,this),z0($$,{children:"Permission rules are a tool name, optionally followed by a specifier in parentheses."},void 0,!1,void 0,this),z0($$,{color:"gray",children:"例如: WebFetch 或 Bash(ls:*)"},void 0,!1,void 0,this),z0(N1,{marginTop:1,children:z0(UV,{value:z,onChange:w,onSubmit:S},void 0,!1,void 0,this)},void 0,!1,void 0,this),z0($$,{color:"gray",children:"Enter 提交 · Esc 取消"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),g=(d,s)=>z0(N1,{flexDirection:"column",gap:1,children:[z0($$,{bold:!0,children:["Delete ",d," permission rule?"]},void 0,!0,void 0,this),z0($$,{children:s.rule},void 0,!1,void 0,this),z0($$,{color:"gray",children:"From project local settings"},void 0,!1,void 0,this),z0($$,{children:"Are you sure you want to delete this permission rule?"},void 0,!1,void 0,this),z0(XF,{items:[{label:"Yes",value:"yes"},{label:"No",value:"no"}],onSelect:(C)=>{if(C.value==="yes")y();else _("list"),L(null)}},void 0,!1,void 0,this)]},void 0,!0,void 0,this),u=(d)=>z0(N1,{flexDirection:"column",gap:1,children:[z0($$,{bold:!0,children:"Cannot delete this rule"},void 0,!1,void 0,this),z0($$,{children:d.rule},void 0,!1,void 0,this),z0($$,{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),z0($$,{color:"gray",children:"按任意键继续"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),v=(d)=>z0(XF,{items:l,isFocused:H==="list",onSelect:o},void 0,!1,void 0,this),Z0=()=>{if(O)return z0($$,{children:"加载中..."},void 0,!1,void 0,this);if(G==="info")return D();if(H==="add")return V(G);if(H==="confirm-delete"&&B)return g(B.tab,B.entry);if(H==="locked"&&B)return u(B.entry);return v(G)};return z0(N1,{flexDirection:"column",borderStyle:"round",borderColor:Y?"cyan":"gray",padding:1,width:80,children:[z0($$,{color:"cyan",bold:!0,children:"⚙️ 权限管理器"},void 0,!1,void 0,this),I(),z0(N1,{flexDirection:"column",gap:1,children:Z0()},void 0,!1,void 0,this),N&&z0(N1,{marginTop:1,children:z0($$,{color:N.type==="success"?"green":"red",children:N.text},void 0,!1,void 0,this)},void 0,!1,void 0,this),z0(N1,{marginTop:1,children:z0($$,{color:"gray",children:"Tab 切换视图 · Esc 关闭 · Q 退出"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};f8();import{Box as t0,Text as N0,useInput as RV}from"ink";import{jsxDEV as a}from"react/jsx-dev-runtime";function WF({onCancel:$}){let Z=s$(),Y=Z.getAll(),Q=Z.getBySource(),X=Z.getStats(),J=Q$(!1,$);if(RV((G,q)=>{if(q.escape)$?.();else if(q.ctrl&&G==="c"||q.meta&&G==="c")J()}),Y.length===0)return a(t0,{flexDirection:"column",paddingY:1,children:[a(t0,{marginBottom:1,children:a(N0,{bold:!0,color:"cyan",children:"\uD83D\uDD0C 插件管理器"},void 0,!1,void 0,this)},void 0,!1,void 0,this),a(t0,{paddingLeft:2,children:a(N0,{color:"gray",children:"没有已加载的插件"},void 0,!1,void 0,this)},void 0,!1,void 0,this),a(t0,{marginTop:1,paddingLeft:2,flexDirection:"column",children:[a(N0,{color:"gray",children:"插件目录位置:"},void 0,!1,void 0,this),a(N0,{color:"gray",dimColor:!0,children:[" ","• ~/.blade/plugins/ - 用户级插件"]},void 0,!0,void 0,this),a(N0,{color:"gray",dimColor:!0,children:[" ","• .blade/plugins/ - 项目级插件"]},void 0,!0,void 0,this),a(N0,{color:"gray",dimColor:!0,children:[" ","• --plugin-dir - CLI 指定的插件"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),a(t0,{marginTop:1,paddingLeft:2,children:a(N0,{color:"gray",children:"使用 /plugins install <url> 安装新插件"},void 0,!1,void 0,this)},void 0,!1,void 0,this),a(t0,{marginTop:1,children:a(N0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return a(t0,{flexDirection:"column",paddingY:1,children:[a(t0,{marginBottom:1,children:[a(N0,{bold:!0,color:"cyan",children:"\uD83D\uDD0C 插件管理器"},void 0,!1,void 0,this),a(N0,{color:"gray",children:[" (共 ",X.total," 个插件)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),a(t0,{paddingLeft:2,marginBottom:1,children:a(N0,{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&&a(t0,{flexDirection:"column",marginBottom:1,children:[a(t0,{paddingLeft:1,children:[a(N0,{bold:!0,color:"magenta",children:"CLI 指定"},void 0,!1,void 0,this),a(N0,{color:"gray",children:" (--plugin-dir)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.cli.map((G)=>{let q=G.status==="active"?"✅":"⏸️";return a(t0,{flexDirection:"column",paddingLeft:2,children:[a(N0,{children:[a(N0,{bold:!0,color:"green",children:[q," ",G.manifest.name]},void 0,!0,void 0,this),a(N0,{color:"gray",children:[" v",G.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),a(t0,{paddingLeft:2,children:a(N0,{color:"gray",children:G.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),G.commands.length>0&&a(t0,{paddingLeft:2,children:a(N0,{color:"blue",children:["命令:"," ",G.commands.map((K)=>`/${K.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},G.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.project.length>0&&a(t0,{flexDirection:"column",marginBottom:1,children:[a(t0,{paddingLeft:1,children:[a(N0,{bold:!0,color:"yellow",children:"项目级"},void 0,!1,void 0,this),a(N0,{color:"gray",children:" (.blade/plugins/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.project.map((G)=>{let q=G.status==="active"?"✅":"⏸️";return a(t0,{flexDirection:"column",paddingLeft:2,children:[a(N0,{children:[a(N0,{bold:!0,color:"green",children:[q," ",G.manifest.name]},void 0,!0,void 0,this),a(N0,{color:"gray",children:[" v",G.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),a(t0,{paddingLeft:2,children:a(N0,{color:"gray",children:G.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),G.commands.length>0&&a(t0,{paddingLeft:2,children:a(N0,{color:"blue",children:["命令:"," ",G.commands.map((K)=>`/${K.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},G.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.user.length>0&&a(t0,{flexDirection:"column",marginBottom:1,children:[a(t0,{paddingLeft:1,children:[a(N0,{bold:!0,color:"cyan",children:"用户级"},void 0,!1,void 0,this),a(N0,{color:"gray",children:" (~/.blade/plugins/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.user.map((G)=>{let q=G.status==="active"?"✅":"⏸️";return a(t0,{flexDirection:"column",paddingLeft:2,children:[a(N0,{children:[a(N0,{bold:!0,color:"green",children:[q," ",G.manifest.name]},void 0,!0,void 0,this),a(N0,{color:"gray",children:[" v",G.manifest.version]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),a(t0,{paddingLeft:2,children:a(N0,{color:"gray",children:G.manifest.description},void 0,!1,void 0,this)},void 0,!1,void 0,this),G.commands.length>0&&a(t0,{paddingLeft:2,children:a(N0,{color:"blue",children:["命令:"," ",G.commands.map((K)=>`/${K.namespacedName}`).join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},G.manifest.name,!0,void 0,this)})]},void 0,!0,void 0,this),a(t0,{marginTop:1,paddingLeft:2,flexDirection:"column",children:[a(N0,{color:"gray",children:"可用命令:"},void 0,!1,void 0,this),a(N0,{color:"gray",dimColor:!0,children:[" ","• /plugins list - 列出所有插件"]},void 0,!0,void 0,this),a(N0,{color:"gray",dimColor:!0,children:[" ","• /plugins info <name> - 显示插件详情"]},void 0,!0,void 0,this),a(N0,{color:"gray",dimColor:!0,children:[" ","• /plugins install <url> - 安装插件"]},void 0,!0,void 0,this),a(N0,{color:"gray",dimColor:!0,children:[" ","• /plugins enable/disable <name> - 启用/禁用插件"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),a(t0,{marginTop:1,children:a(N0,{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 u$,Text as d$,useInput as UF,useStdout as VV}from"ink";import MV from"ink-text-input";import YQ,{useCallback as z7,useMemo as DV,useState as L4}from"react";import{jsxDEV as D0}from"react/jsx-dev-runtime";var jV=YQ.memo(({option:$,index:Z,isSelected:Y,isMultiSelect:Q,isHighlighted:X})=>D0(u$,{flexDirection:"column",marginBottom:1,children:[D0(d$,{color:X?"yellow":Y?"green":void 0,bold:X,children:[Q?Y?"● ":"○ ":X?"❯ ":" ",Z+1,". ",$.label]},void 0,!0,void 0,this),D0(u$,{marginLeft:4,children:D0(d$,{color:"gray",children:$.description},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)),yV=YQ.memo(({questions:$,answers:Z})=>D0(u$,{flexDirection:"column",marginBottom:1,children:$.map((Y)=>{let Q=Z[Y.header],X=Array.isArray(Q)?Q.join(", "):Q||"(no answer)";return D0(u$,{marginBottom:1,children:[D0(d$,{backgroundColor:"blue",color:"white",children:[" ",Y.header," "]},void 0,!0,void 0,this),D0(d$,{color:"green",children:[" ",X]},void 0,!0,void 0,this)]},Y.header,!0,void 0,this)})},void 0,!1,void 0,this)),OF=YQ.memo(({questions:$,onComplete:Z,onCancel:Y})=>{let{stdout:Q}=VV(),X=Q.columns||80,G=q1()==="confirmation-prompt",q=Q$(!1),[K,W]=L4("answering"),[U,O]=L4(0),[F,H]=L4({}),[_,z]=L4(0),[w,B]=L4([]),[L,N]=L4(!1),[M,b]=L4(""),[j,T]=L4(0),A=$[U],k=DV(()=>{if(!A)return[];return[...A.options.map((I)=>({label:I.label,value:I.label,description:I.description})),{label:"Type something...",value:"__other__",description:"Enter custom response"}]},[A]),c=z7((I)=>{let D={...F,[A.header]:I};if(H(D),U<$.length-1)O(U+1),z(0),B([]),N(!1),b("");else W("submit"),T(0)},[F,A?.header,U,$.length]),o=z7((I)=>{let D=k[I];if(!D)return;if(D.value==="__other__"){N(!0);return}if(A.multiSelect)B((V)=>V.includes(D.value)?V.filter((g)=>g!==D.value):[...V,D.value]);else c(D.value)},[k,A?.multiSelect,c]),S=z7((I)=>{if(I.trim())c(I.trim())},[c]),y=z7(()=>{W("answering"),O(0),z(0),B([]),N(!1)},[]),l=z7(()=>{Z(F)},[F,Z]);if(UF((I,D)=>{if(D.ctrl&&I==="c"||D.meta&&I==="c"){q();return}if(L){if(D.escape)N(!1),b("");return}if(D.escape){Y();return}let V=parseInt(I);if(V>=1&&V<=k.length){o(V-1);return}if(D.upArrow){z((g)=>g>0?g-1:k.length-1);return}if(D.downArrow||D.tab){z((g)=>g<k.length-1?g+1:0);return}if(D.return){if(A.multiSelect&&w.length>0)c(w);else o(_);return}if(I===" "&&A.multiSelect){let g=k[_];if(g&&g.value!=="__other__")B((u)=>u.includes(g.value)?u.filter((v)=>v!==g.value):[...u,g.value]);return}},{isActive:G&&K==="answering"&&!L}),UF((I,D)=>{if(D.ctrl&&I==="c"||D.meta&&I==="c"){q();return}if(D.escape){Y();return}if(D.upArrow||D.downArrow||D.tab){T((V)=>V===0?1:0);return}if(D.return){if(j===0)l();else y();return}if(I.toLowerCase()==="y"){l();return}if(I.toLowerCase()==="e"){y();return}},{isActive:G&&K==="submit"}),K==="submit")return D0(u$,{flexDirection:"column",borderStyle:"round",borderColor:G?"green":"gray",padding:1,width:Math.min(X-4,80),children:[D0(u$,{marginBottom:1,children:D0(d$,{bold:!0,color:"green",children:"✓ Review Your Answers"},void 0,!1,void 0,this)},void 0,!1,void 0,this),D0(yV,{questions:$,answers:F},void 0,!1,void 0,this),D0(u$,{flexDirection:"column",marginTop:1,children:[D0(d$,{color:j===0?"yellow":void 0,bold:j===0,children:[j===0?"❯ ":" ","[Y] Submit answers"]},void 0,!0,void 0,this),D0(d$,{color:j===1?"yellow":void 0,bold:j===1,children:[j===1?"❯ ":" ","[E] Edit answers"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),D0(u$,{marginTop:1,children:D0(d$,{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(!A)return null;return D0(u$,{flexDirection:"column",borderStyle:"round",borderColor:G?"cyan":"gray",padding:1,width:Math.min(X-4,80),children:[D0(u$,{marginBottom:1,children:[D0(d$,{backgroundColor:"blue",color:"white",children:[" ",A.header," "]},void 0,!0,void 0,this),D0(d$,{children:[" ",A.question]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),L?D0(u$,{flexDirection:"column",marginTop:1,children:[D0(d$,{color:"yellow",children:"Enter your response:"},void 0,!1,void 0,this),D0(u$,{marginTop:1,children:[D0(d$,{color:"cyan",children:"❯ "},void 0,!1,void 0,this),D0(MV,{value:M,onChange:b,onSubmit:S,focus:G},void 0,!1,void 0,this)]},void 0,!0,void 0,this),D0(u$,{marginTop:1,children:D0(d$,{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):D0(u$,{flexDirection:"column",children:k.map((I,D)=>D0(jV,{option:I,index:D,isSelected:w.includes(I.value),isMultiSelect:A.multiSelect,isHighlighted:_===D},I.value,!1,void 0,this))},void 0,!1,void 0,this),!L&&D0(u$,{marginTop:1,flexDirection:"column",children:[D0(d$,{color:"gray",children:A.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),A.multiSelect&&w.length>0&&D0(d$,{color:"green",children:["Selected: ",w.join(", ")]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),$.length>1&&D0(u$,{marginTop:1,children:D0(d$,{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)});i3();import{Box as J3,Text as Q2,useInput as TV}from"ink";import EV from"ink-select-input";import{basename as IV}from"node:path";import{useEffect as FF,useMemo as U5,useState as QQ}from"react";import{jsxDEV as y$}from"react/jsx-dev-runtime";function vV($){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 PV($){return IV($)}var CV=({isSelected:$})=>y$(J3,{marginRight:1,children:y$(Q2,{color:$?"cyan":"gray",children:$?"❯":" "},void 0,!1,void 0,this)},void 0,!1,void 0,this),SV=({isSelected:$,label:Z})=>y$(Q2,{color:$?"cyan":"white",bold:$,children:Z},void 0,!1,void 0,this),B7=20,HF=({sessions:$,onSelect:Z,onCancel:Y})=>{let[Q,X]=QQ([]),[J,G]=QQ(!1),[q,K]=QQ(0),U=q1()==="session-selector",O=Q$(!1);TV((L,N)=>{if(N.ctrl&&L==="c"||N.meta&&L==="c"){O();return}if(N.escape&&Y){Y();return}if(N.leftArrow||L==="h"||L==="H"){if(q>0)K((M)=>M-1);return}if(N.rightArrow||L==="l"||L==="L"){if(q<_-1)K((M)=>M+1);return}},{isActive:U}),FF(()=>{if($){X($);return}(async()=>{G(!0);try{let N=await S$.listSessions();X(N)}catch(N){console.error("[SessionSelector] Failed to load sessions:",N),X([])}finally{G(!1)}})()},[$]);let F=$||Q,H=U5(()=>{return F.map((L)=>{let N=PV(L.projectPath),M=vV(L.lastMessageTime),b=L.gitBranch?` (${L.gitBranch})`:"",j=L.hasErrors?" ⚠️":"",T=L.relationType==="subagent"?" ↳ subagent":"";return{label:`\uD83D\uDCC5 ${M} | ${N}${b} | ${L.messageCount} 条消息${j}${T}`,value:L.sessionId}})},[F]),_=U5(()=>Math.max(1,Math.ceil(H.length/B7)),[H.length]),z=U5(()=>{let L=q*B7;return H.slice(L,L+B7)},[H,q]),w=U5(()=>({start:q*B7+1,end:Math.min((q+1)*B7,H.length)}),[q,H.length]);FF(()=>{K(0)},[F.length]);let B=(L)=>{Z(L.value)};if(J)return y$(J3,{flexDirection:"column",paddingX:2,paddingY:1,children:y$(Q2,{children:"⏳ 正在加载会话列表..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(F.length===0)return y$(J3,{flexDirection:"column",paddingX:2,paddingY:1,children:[y$(Q2,{color:"yellow",children:"⚠️ 没有找到历史会话"},void 0,!1,void 0,this),y$(Q2,{dimColor:!0,children:[`
2848
2848
  `,"提示: 开始一次对话后,会话历史将保存到 ~/.blade/projects/"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this);return y$(J3,{flexDirection:"column",paddingX:2,paddingY:1,children:[y$(Q2,{bold:!0,color:"cyan",children:"\uD83D\uDCC2 选择要恢复的会话:"},void 0,!1,void 0,this),y$(Q2,{dimColor:!0,children:[`
2849
2849
  `,"(←→ 翻页 | ↑↓ 选择 | Enter 确认 | Esc 取消)",`
2850
- `]},void 0,!0,void 0,this),y$(EV,{items:z,onSelect:B,indicatorComponent:CV,itemComponent:SV},void 0,!1,void 0,this),y$(J3,{marginTop:1,flexDirection:"column",children:[y$(Q2,{dimColor:!0,children:["第 ",q+1,"/",_," 页 · 共 ",F.length," 个会话 · 显示"," ",w.start,"-",w.end]},void 0,!0,void 0,this),_>1&&y$(J3,{marginTop:1,children:[y$(Q2,{color:q>0?"cyan":"gray",children:q>0?"◀ ← 上一页":" "},void 0,!1,void 0,this),y$(Q2,{children:" "},void 0,!1,void 0,this),y$(Q2,{color:q<_-1?"cyan":"gray",children:q<_-1?"下一页 → ▶":""},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};K2();import{Box as O$,Text as r0,useInput as kV}from"ink";import{jsxDEV as X0}from"react/jsx-dev-runtime";function _F({onCancel:$}){let Y=J$().getAll(),Q=Y.filter((q)=>q.source==="builtin"),X=Y.filter((q)=>q.source==="user"),J=Y.filter((q)=>q.source==="project"),G=Q$(!1,$);if(kV((q,K)=>{if(K.escape)$?.();else if(K.ctrl&&q==="c"||K.meta&&q==="c")G()}),Y.length===0)return X0(O$,{flexDirection:"column",paddingY:1,children:[X0(O$,{marginBottom:1,children:X0(r0,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this)},void 0,!1,void 0,this),X0(O$,{paddingLeft:2,children:X0(r0,{color:"gray",children:"没有找到任何 Skill"},void 0,!1,void 0,this)},void 0,!1,void 0,this),X0(O$,{marginTop:1,paddingLeft:2,children:X0(r0,{color:"gray",children:"配置文件位置: ~/.blade/skills/ 或 .blade/skills/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),X0(O$,{marginTop:1,children:X0(r0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return X0(O$,{flexDirection:"column",paddingY:1,children:[X0(O$,{marginBottom:1,children:[X0(r0,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this),X0(r0,{color:"gray",children:[" (找到 ",Y.length," 个)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),J.length>0&&X0(O$,{flexDirection:"column",marginBottom:1,children:[X0(O$,{paddingLeft:1,children:[X0(r0,{bold:!0,color:"yellow",children:"项目级"},void 0,!1,void 0,this),X0(r0,{color:"gray",children:" (.blade/skills/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J.map((q)=>{let W=q.description.length>80?`${q.description.substring(0,80)}...`:q.description;return X0(O$,{flexDirection:"column",paddingLeft:2,children:[X0(r0,{children:[X0(r0,{bold:!0,color:"green",children:["• ",q.name]},void 0,!0,void 0,this),X0(r0,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.allowedTools&&q.allowedTools.length>0&&X0(O$,{paddingLeft:2,children:X0(r0,{color:"gray",children:["工具: ",q.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),X0(O$,{paddingLeft:2,children:X0(r0,{color:"gray",dimColor:!0,children:q.path},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},q.name,!0,void 0,this)})]},void 0,!0,void 0,this),X.length>0&&X0(O$,{flexDirection:"column",marginBottom:1,children:[X0(O$,{paddingLeft:1,children:[X0(r0,{bold:!0,color:"yellow",children:"用户级"},void 0,!1,void 0,this),X0(r0,{color:"gray",children:" (~/.blade/skills/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X.map((q)=>{let W=q.description.length>80?`${q.description.substring(0,80)}...`:q.description;return X0(O$,{flexDirection:"column",paddingLeft:2,children:[X0(r0,{children:[X0(r0,{bold:!0,color:"green",children:["• ",q.name]},void 0,!0,void 0,this),X0(r0,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.allowedTools&&q.allowedTools.length>0&&X0(O$,{paddingLeft:2,children:X0(r0,{color:"gray",children:["工具: ",q.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),X0(O$,{paddingLeft:2,children:X0(r0,{color:"gray",dimColor:!0,children:q.path},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},q.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.length>0&&X0(O$,{flexDirection:"column",marginBottom:1,children:[X0(O$,{paddingLeft:1,children:[X0(r0,{bold:!0,color:"cyan",children:"内置"},void 0,!1,void 0,this),X0(r0,{color:"gray",children:" (builtin)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.map((q)=>{let W=q.description.length>80?`${q.description.substring(0,80)}...`:q.description;return X0(O$,{flexDirection:"column",paddingLeft:2,children:[X0(r0,{children:[X0(r0,{bold:!0,color:"green",children:["• ",q.name]},void 0,!0,void 0,this),X0(r0,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.userInvocable&&X0(O$,{paddingLeft:2,children:X0(r0,{color:"blue",children:["命令: /",q.name]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},q.name,!0,void 0,this)})]},void 0,!0,void 0,this),X0(O$,{marginTop:1,children:X0(r0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}j1();g1();import{Box as N4,Text as A1}from"ink";import zF,{useEffect as fV,useState as hV}from"react";import{jsxDEV as F$}from"react/jsx-dev-runtime";var xV={init:"\uD83D\uDCDD",requirements:"\uD83D\uDCCB",design:"\uD83C\uDFA8",tasks:"\uD83D\uDCCC",implementation:"\uD83D\uDD27",done:"✅"},O5=["init","requirements","design","tasks","implementation","done"],pV={pending:"○",in_progress:"◐",completed:"●",blocked:"✕"},mV={pending:"gray",in_progress:"yellow",completed:"green",blocked:"red"},BF=zF.memo(({expanded:$=!1,maxTasks:Z=5})=>{let[Y,Q]=hV(null);if(fV(()=>{let G=x0.getInstance();Q(G.getCurrentSpec());let q=setInterval(()=>{Q(G.getCurrentSpec())},1000);return()=>clearInterval(q)},[]),!Y)return null;let X=O5.indexOf(Y.phase),J=Y.tasks.length>0?Math.round(Y.tasks.filter((G)=>G.status==="completed").length/Y.tasks.length*100):0;return F$(N4,{flexDirection:"column",borderStyle:"round",borderColor:"blue",paddingX:1,marginBottom:1,children:[F$(N4,{flexDirection:"row",justifyContent:"space-between",children:[F$(A1,{color:"blue",bold:!0,children:["\uD83D\uDCCB Spec: ",Y.name]},void 0,!0,void 0,this),F$(A1,{color:"gray",children:[xV[Y.phase]," ",I$[Y.phase]]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),F$(N4,{flexDirection:"row",marginTop:1,children:[O5.map((G,q)=>{let K=q<X,W=q===X;return F$(N4,{flexDirection:"row",children:[F$(A1,{color:K?"green":W?"blue":"gray",children:K?"●":W?"◉":"○"},void 0,!1,void 0,this),q<O5.length-1&&F$(A1,{color:K?"green":"gray",children:"──"},void 0,!1,void 0,this)]},G,!0,void 0,this)}),F$(A1,{color:"gray",children:[" (",J,"%)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),F$(N4,{flexDirection:"row",marginTop:0,children:F$(A1,{color:"gray",dimColor:!0,children:O5.map((G,q)=>{let K=G.slice(0,3).toUpperCase();return q===X?`[${K}]`:` ${K} `}).join("")},void 0,!1,void 0,this)},void 0,!1,void 0,this),$&&Y.tasks.length>0&&F$(N4,{flexDirection:"column",marginTop:1,children:[F$(A1,{color:"gray",dimColor:!0,children:["─── Tasks (",Y.tasks.filter((G)=>G.status==="completed").length,"/",Y.tasks.length,") ───"]},void 0,!0,void 0,this),Y.tasks.slice(0,Z).map((G)=>F$(gV,{task:G,isCurrent:G.id===Y.currentTaskId},G.id,!1,void 0,this)),Y.tasks.length>Z&&F$(A1,{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&&F$(N4,{flexDirection:"row",marginTop:1,children:[F$(A1,{color:"gray",children:"Current: "},void 0,!1,void 0,this),F$(A1,{color:"yellow",children:Y.tasks.find((G)=>G.id===Y.currentTaskId)?.title||"Unknown"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}),gV=zF.memo(({task:$,isCurrent:Z})=>{let Y=pV[$.status]||"?",Q=mV[$.status]||"gray";return F$(N4,{flexDirection:"row",children:[F$(A1,{color:Q,children:[Y," "]},void 0,!0,void 0,this),F$(A1,{color:Z?"yellow":"white",bold:Z,children:$.title},void 0,!1,void 0,this),$.complexity&&F$(A1,{color:"gray",dimColor:!0,children:[" ","[",$.complexity,"]"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});import{Box as uV,Text as k2}from"ink";import dV,{useEffect as cV,useState as wF}from"react";import{jsxDEV as x1,Fragment as NF}from"react/jsx-dev-runtime";var LF=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];function lV($){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 AF=dV.memo(()=>{let $=w0((K)=>K.app.subagentProgress),Z=d0(),[Y,Q]=wF(0),[X,J]=wF(0);if(cV(()=>{if(!$||$.status!=="running"){Q(0),J(0);return}let K=setInterval(()=>{Q((U)=>(U+1)%LF.length)},80),W=setInterval(()=>{J(Date.now()-$.startTime)},1000);return()=>{clearInterval(K),clearInterval(W)}},[$]),!$)return null;let G=$.status==="running"?LF[Y]:$.status==="completed"?"✓":"✗",q=$.status==="running"?Z.colors.info:$.status==="completed"?Z.colors.success:Z.colors.error;return x1(uV,{paddingX:2,paddingY:0,flexDirection:"row",gap:1,children:[x1(k2,{color:q,bold:!0,children:G},void 0,!1,void 0,this),x1(k2,{color:Z.colors.muted,children:"Subagent"},void 0,!1,void 0,this),x1(k2,{color:Z.colors.text.primary,bold:!0,children:$.type},void 0,!1,void 0,this),x1(k2,{color:Z.colors.muted,children:"|"},void 0,!1,void 0,this),x1(k2,{color:Z.colors.text.secondary,children:$.description},void 0,!1,void 0,this),$.currentTool&&x1(NF,{children:[x1(k2,{color:Z.colors.muted,children:"|"},void 0,!1,void 0,this),x1(k2,{color:Z.colors.warning,children:$.currentTool},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$.status==="running"&&X>0&&x1(NF,{children:[x1(k2,{color:Z.colors.muted,children:"|"},void 0,!1,void 0,this),x1(k2,{color:Z.colors.info,children:lV(X)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});import{useMemoizedFn as iV}from"ahooks";import{Box as w2,Text as r,useInput as rV}from"ink";import aV from"ink-select-input";import{useState as bF}from"react";M0();R5();V4();import{jsxDEV as m}from"react/jsx-dev-runtime";var RF=A2.map(($)=>({label:$.label,value:$.id})),nV=({theme:$})=>{let{colors:Z}=$;return m(w2,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[m(r,{bold:!0,color:Z.text.primary,children:"代码预览"},void 0,!1,void 0,this),m(r,{children:" "},void 0,!1,void 0,this),m(r,{color:Z.syntax.comment,children:"# function"},void 0,!1,void 0,this),m(r,{children:[m(r,{color:Z.syntax.keyword,children:"def"},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.function,children:"fibonacci"},void 0,!1,void 0,this),m(r,{color:Z.text.primary,children:"("},void 0,!1,void 0,this),m(r,{color:Z.syntax.variable,children:"n"},void 0,!1,void 0,this),m(r,{color:Z.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(r,{children:[" ",m(r,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this),m(r,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.operator,children:"="},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.number,children:"0"},void 0,!1,void 0,this),m(r,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.number,children:"1"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(r,{children:[" ",m(r,{color:Z.syntax.keyword,children:"for"},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.variable,children:"_"},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.keyword,children:"in"},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.function,children:"range"},void 0,!1,void 0,this),m(r,{color:Z.text.primary,children:"("},void 0,!1,void 0,this),m(r,{color:Z.syntax.variable,children:"n"},void 0,!1,void 0,this),m(r,{color:Z.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(r,{children:[" ",m(r,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this),m(r,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.operator,children:"="},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this),m(r,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.operator,children:"+"},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(r,{children:[" ",m(r,{color:Z.syntax.keyword,children:"return"},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(r,{children:" "},void 0,!1,void 0,this),m(r,{color:Z.error,children:["- print(",m(r,{color:Z.syntax.string,children:'"Hello, "'},void 0,!1,void 0,this)," + name)"]},void 0,!0,void 0,this),m(r,{color:Z.success,children:["+ print(",m(r,{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)},oV=({theme:$})=>{let{colors:Z}=$;return m(w2,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[m(r,{children:" "},void 0,!1,void 0,this),m(r,{bold:!0,color:Z.text.primary,children:"颜色配置"},void 0,!1,void 0,this),m(r,{children:" "},void 0,!1,void 0,this),m(r,{children:[m(r,{color:Z.text.muted,children:"Primary: "},void 0,!1,void 0,this),m(r,{color:Z.primary,children:Z.primary},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(r,{children:[m(r,{color:Z.text.muted,children:"Success: "},void 0,!1,void 0,this),m(r,{color:Z.success,children:Z.success},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(r,{children:[m(r,{color:Z.text.muted,children:"Error: "},void 0,!1,void 0,this),m(r,{color:Z.error,children:Z.error},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(r,{children:[m(r,{color:Z.text.muted,children:"Warning: "},void 0,!1,void 0,this),m(r,{color:Z.warning,children:Z.warning},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(r,{children:[m(r,{color:Z.text.muted,children:"Info: "},void 0,!1,void 0,this),m(r,{color:Z.info,children:Z.info},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},VF=()=>{let $=W4(),Z=i$.getCurrentThemeName(),Y=A2.findIndex((_)=>_.label===Z),Q=Y>=0?A2[Y].theme:A2[0].theme,[X,J]=bF(Q),[G,q]=bF(!1),K=iV(async(_)=>{if(G)return;q(!0);try{await b0().setTheme(_.value),$.closeModal()}catch(z){console.error("❌ 主题切换失败:",z instanceof Error?z.message:z)}finally{q(!1)}}),W=(_)=>{let z=A2.find((w)=>w.id===_.value);if(z)J(z.theme)},O=q1()==="theme-selector",F=Q$(!1);rV((_,z)=>{if(z.ctrl&&_==="c"||z.meta&&_==="c"){F();return}if(z.escape&&!G)$.closeModal()},{isActive:O});let H=(_)=>{let{isSelected:z,label:w}=_,L=w===Z?"✓":" ";return m(r,{color:z?X.colors.primary:X.colors.text.primary,children:[L," ",w]},void 0,!0,void 0,this)};return m(w2,{flexDirection:"column",height:"100%",children:[m(w2,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:X.colors.border.light,children:m(r,{bold:!0,color:X.colors.primary,children:"\uD83C\uDFA8 主题选择器"},void 0,!1,void 0,this)},void 0,!1,void 0,this),m(w2,{flexDirection:"row",flexGrow:1,children:[m(w2,{width:"40%",borderStyle:"single",borderColor:X.colors.border.light,paddingX:1,children:m(w2,{flexDirection:"column",children:[m(w2,{paddingTop:1,paddingBottom:1,children:m(r,{bold:!0,color:X.colors.text.primary,children:["可用主题 (",RF.length,")"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),m(aV,{items:RF,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),m(w2,{width:"60%",flexDirection:"column",borderStyle:"single",borderColor:X.colors.border.light,children:[m(nV,{theme:X},void 0,!1,void 0,this),m(oV,{theme:X},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),m(w2,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:X.colors.border.light,children:m(r,{color:X.colors.text.muted,children:G?"正在保存...":"Enter: 选择主题 | Esc: 取消"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as m0}from"react/jsx-dev-runtime";var e$=x("UI"),MF=({debug:$,continue:Z,...Y})=>{if($)e$.debug("[Debug] BladeInterface props:",{permissionMode:Y.permissionMode,yolo:Y.yolo,maxTurns:Y.maxTurns,continue:Z});let Q=F5(!1),X=F5(!1),J=F5(!1),G=F5(null),q=QU(),K=XU(),W=x7(),U=qU(),O=GU(),F=W4(),H=K4(),_=FU(),z=a8(),w=U4(),{exit:B}=sV(),L=q==="ready",N=q==="needsSetup",M=q==="idle",{confirmationState:b,confirmationHandler:j,handleResponse:T}=vU(),{executeCommand:A,handleAbort:k}=yU(Y.systemPrompt,Y.appendSystemPrompt,j,Y.maxTurns),{getPreviousCommand:c,getNextCommand:o,addToHistory:S}=EU();dU();let y=CU("",0),l=t$(async()=>{let Y0=z,I0;if(Y0==="default")I0="autoEdit";else if(Y0==="autoEdit")I0="plan";else if(Y0==="plan")I0="spec";else if(Y0==="spec")I0="default";else I0="default";try{if(await b0().setPermissionMode(I0),I0==="spec")try{let L$=x0.getInstance();await L$.initialize(process.cwd());let N$=await L$.listSpecs();if(N$.length>0){let E$=N$[0];await L$.loadSpec(E$.name),H.addAssistantMessage(`\uD83D\uDCCB **已进入 Spec 模式**
2850
+ `]},void 0,!0,void 0,this),y$(EV,{items:z,onSelect:B,indicatorComponent:CV,itemComponent:SV},void 0,!1,void 0,this),y$(J3,{marginTop:1,flexDirection:"column",children:[y$(Q2,{dimColor:!0,children:["第 ",q+1,"/",_," 页 · 共 ",F.length," 个会话 · 显示"," ",w.start,"-",w.end]},void 0,!0,void 0,this),_>1&&y$(J3,{marginTop:1,children:[y$(Q2,{color:q>0?"cyan":"gray",children:q>0?"◀ ← 上一页":" "},void 0,!1,void 0,this),y$(Q2,{children:" "},void 0,!1,void 0,this),y$(Q2,{color:q<_-1?"cyan":"gray",children:q<_-1?"下一页 → ▶":""},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};K2();import{Box as O$,Text as r0,useInput as kV}from"ink";import{jsxDEV as X0}from"react/jsx-dev-runtime";function _F({onCancel:$}){let Y=J$().getAll(),Q=Y.filter((q)=>q.source==="builtin"),X=Y.filter((q)=>q.source==="user"),J=Y.filter((q)=>q.source==="project"),G=Q$(!1,$);if(kV((q,K)=>{if(K.escape)$?.();else if(K.ctrl&&q==="c"||K.meta&&q==="c")G()}),Y.length===0)return X0(O$,{flexDirection:"column",paddingY:1,children:[X0(O$,{marginBottom:1,children:X0(r0,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this)},void 0,!1,void 0,this),X0(O$,{paddingLeft:2,children:X0(r0,{color:"gray",children:"没有找到任何 Skill"},void 0,!1,void 0,this)},void 0,!1,void 0,this),X0(O$,{marginTop:1,paddingLeft:2,children:X0(r0,{color:"gray",children:"配置文件位置: ~/.blade/skills/ 或 .blade/skills/"},void 0,!1,void 0,this)},void 0,!1,void 0,this),X0(O$,{marginTop:1,children:X0(r0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return X0(O$,{flexDirection:"column",paddingY:1,children:[X0(O$,{marginBottom:1,children:[X0(r0,{bold:!0,color:"cyan",children:"\uD83D\uDCDA 所有 Skills"},void 0,!1,void 0,this),X0(r0,{color:"gray",children:[" (找到 ",Y.length," 个)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),J.length>0&&X0(O$,{flexDirection:"column",marginBottom:1,children:[X0(O$,{paddingLeft:1,children:[X0(r0,{bold:!0,color:"yellow",children:"项目级"},void 0,!1,void 0,this),X0(r0,{color:"gray",children:" (.blade/skills/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J.map((q)=>{let W=q.description.length>80?`${q.description.substring(0,80)}...`:q.description;return X0(O$,{flexDirection:"column",paddingLeft:2,children:[X0(r0,{children:[X0(r0,{bold:!0,color:"green",children:["• ",q.name]},void 0,!0,void 0,this),X0(r0,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.allowedTools&&q.allowedTools.length>0&&X0(O$,{paddingLeft:2,children:X0(r0,{color:"gray",children:["工具: ",q.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),X0(O$,{paddingLeft:2,children:X0(r0,{color:"gray",dimColor:!0,children:q.path},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},q.name,!0,void 0,this)})]},void 0,!0,void 0,this),X.length>0&&X0(O$,{flexDirection:"column",marginBottom:1,children:[X0(O$,{paddingLeft:1,children:[X0(r0,{bold:!0,color:"yellow",children:"用户级"},void 0,!1,void 0,this),X0(r0,{color:"gray",children:" (~/.blade/skills/)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),X.map((q)=>{let W=q.description.length>80?`${q.description.substring(0,80)}...`:q.description;return X0(O$,{flexDirection:"column",paddingLeft:2,children:[X0(r0,{children:[X0(r0,{bold:!0,color:"green",children:["• ",q.name]},void 0,!0,void 0,this),X0(r0,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.allowedTools&&q.allowedTools.length>0&&X0(O$,{paddingLeft:2,children:X0(r0,{color:"gray",children:["工具: ",q.allowedTools.join(", ")]},void 0,!0,void 0,this)},void 0,!1,void 0,this),X0(O$,{paddingLeft:2,children:X0(r0,{color:"gray",dimColor:!0,children:q.path},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},q.name,!0,void 0,this)})]},void 0,!0,void 0,this),Q.length>0&&X0(O$,{flexDirection:"column",marginBottom:1,children:[X0(O$,{paddingLeft:1,children:[X0(r0,{bold:!0,color:"cyan",children:"内置"},void 0,!1,void 0,this),X0(r0,{color:"gray",children:" (builtin)"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.map((q)=>{let W=q.description.length>80?`${q.description.substring(0,80)}...`:q.description;return X0(O$,{flexDirection:"column",paddingLeft:2,children:[X0(r0,{children:[X0(r0,{bold:!0,color:"green",children:["• ",q.name]},void 0,!0,void 0,this),X0(r0,{color:"gray",children:[" - ",W]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.userInvocable&&X0(O$,{paddingLeft:2,children:X0(r0,{color:"blue",children:["命令: /",q.name]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},q.name,!0,void 0,this)})]},void 0,!0,void 0,this),X0(O$,{marginTop:1,children:X0(r0,{dimColor:!0,children:"按 ESC 返回菜单"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}j1();g1();import{Box as N4,Text as A1}from"ink";import zF,{useEffect as fV,useState as hV}from"react";import{jsxDEV as F$}from"react/jsx-dev-runtime";var xV={init:"\uD83D\uDCDD",requirements:"\uD83D\uDCCB",design:"\uD83C\uDFA8",tasks:"\uD83D\uDCCC",implementation:"\uD83D\uDD27",done:"✅"},O5=["init","requirements","design","tasks","implementation","done"],pV={pending:"○",in_progress:"◐",completed:"●",blocked:"✕"},mV={pending:"gray",in_progress:"yellow",completed:"green",blocked:"red"},BF=zF.memo(({expanded:$=!1,maxTasks:Z=5})=>{let[Y,Q]=hV(null);if(fV(()=>{let G=x0.getInstance();Q(G.getCurrentSpec());let q=setInterval(()=>{Q(G.getCurrentSpec())},1000);return()=>clearInterval(q)},[]),!Y)return null;let X=O5.indexOf(Y.phase),J=Y.tasks.length>0?Math.round(Y.tasks.filter((G)=>G.status==="completed").length/Y.tasks.length*100):0;return F$(N4,{flexDirection:"column",borderStyle:"round",borderColor:"blue",paddingX:1,marginBottom:1,children:[F$(N4,{flexDirection:"row",justifyContent:"space-between",children:[F$(A1,{color:"blue",bold:!0,children:["\uD83D\uDCCB Spec: ",Y.name]},void 0,!0,void 0,this),F$(A1,{color:"gray",children:[xV[Y.phase]," ",I$[Y.phase]]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),F$(N4,{flexDirection:"row",marginTop:1,children:[O5.map((G,q)=>{let K=q<X,W=q===X;return F$(N4,{flexDirection:"row",children:[F$(A1,{color:K?"green":W?"blue":"gray",children:K?"●":W?"◉":"○"},void 0,!1,void 0,this),q<O5.length-1&&F$(A1,{color:K?"green":"gray",children:"──"},void 0,!1,void 0,this)]},G,!0,void 0,this)}),F$(A1,{color:"gray",children:[" (",J,"%)"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),F$(N4,{flexDirection:"row",marginTop:0,children:F$(A1,{color:"gray",dimColor:!0,children:O5.map((G,q)=>{let K=G.slice(0,3).toUpperCase();return q===X?`[${K}]`:` ${K} `}).join("")},void 0,!1,void 0,this)},void 0,!1,void 0,this),$&&Y.tasks.length>0&&F$(N4,{flexDirection:"column",marginTop:1,children:[F$(A1,{color:"gray",dimColor:!0,children:["─── Tasks (",Y.tasks.filter((G)=>G.status==="completed").length,"/",Y.tasks.length,") ───"]},void 0,!0,void 0,this),Y.tasks.slice(0,Z).map((G)=>F$(gV,{task:G,isCurrent:G.id===Y.currentTaskId},G.id,!1,void 0,this)),Y.tasks.length>Z&&F$(A1,{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&&F$(N4,{flexDirection:"row",marginTop:1,children:[F$(A1,{color:"gray",children:"Current: "},void 0,!1,void 0,this),F$(A1,{color:"yellow",children:Y.tasks.find((G)=>G.id===Y.currentTaskId)?.title||"Unknown"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}),gV=zF.memo(({task:$,isCurrent:Z})=>{let Y=pV[$.status]||"?",Q=mV[$.status]||"gray";return F$(N4,{flexDirection:"row",children:[F$(A1,{color:Q,children:[Y," "]},void 0,!0,void 0,this),F$(A1,{color:Z?"yellow":"white",bold:Z,children:$.title},void 0,!1,void 0,this),$.complexity&&F$(A1,{color:"gray",dimColor:!0,children:[" ","[",$.complexity,"]"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});import{Box as uV,Text as k2}from"ink";import dV,{useEffect as cV,useState as wF}from"react";import{jsxDEV as x1,Fragment as NF}from"react/jsx-dev-runtime";var LF=["⠋","⠙","⠹","⠸","⠼","⠴","⠦","⠧","⠇","⠏"];function lV($){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 AF=dV.memo(()=>{let $=w0((K)=>K.app.subagentProgress),Z=d0(),[Y,Q]=wF(0),[X,J]=wF(0);if(cV(()=>{if(!$||$.status!=="running"){Q(0),J(0);return}let K=setInterval(()=>{Q((U)=>(U+1)%LF.length)},80),W=setInterval(()=>{J(Date.now()-$.startTime)},1000);return()=>{clearInterval(K),clearInterval(W)}},[$]),!$)return null;let G=$.status==="running"?LF[Y]:$.status==="completed"?"✓":"✗",q=$.status==="running"?Z.colors.info:$.status==="completed"?Z.colors.success:Z.colors.error;return x1(uV,{paddingX:2,paddingY:0,flexDirection:"row",gap:1,children:[x1(k2,{color:q,bold:!0,children:G},void 0,!1,void 0,this),x1(k2,{color:Z.colors.muted,children:"Subagent"},void 0,!1,void 0,this),x1(k2,{color:Z.colors.text.primary,bold:!0,children:$.type},void 0,!1,void 0,this),x1(k2,{color:Z.colors.muted,children:"|"},void 0,!1,void 0,this),x1(k2,{color:Z.colors.text.secondary,children:$.description},void 0,!1,void 0,this),$.currentTool&&x1(NF,{children:[x1(k2,{color:Z.colors.muted,children:"|"},void 0,!1,void 0,this),x1(k2,{color:Z.colors.warning,children:$.currentTool},void 0,!1,void 0,this)]},void 0,!0,void 0,this),$.status==="running"&&X>0&&x1(NF,{children:[x1(k2,{color:Z.colors.muted,children:"|"},void 0,!1,void 0,this),x1(k2,{color:Z.colors.info,children:lV(X)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)});import{useMemoizedFn as iV}from"ahooks";import{Box as w2,Text as r,useInput as rV}from"ink";import aV from"ink-select-input";import{useState as bF}from"react";M0();R5();V4();import{jsxDEV as m}from"react/jsx-dev-runtime";var RF=A2.map(($)=>({label:$.label,value:$.id})),nV=({theme:$})=>{let{colors:Z}=$;return m(w2,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[m(r,{bold:!0,color:Z.text.primary,children:"代码预览"},void 0,!1,void 0,this),m(r,{children:" "},void 0,!1,void 0,this),m(r,{color:Z.syntax.comment,children:"# function"},void 0,!1,void 0,this),m(r,{children:[m(r,{color:Z.syntax.keyword,children:"def"},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.function,children:"fibonacci"},void 0,!1,void 0,this),m(r,{color:Z.text.primary,children:"("},void 0,!1,void 0,this),m(r,{color:Z.syntax.variable,children:"n"},void 0,!1,void 0,this),m(r,{color:Z.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(r,{children:[" ",m(r,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this),m(r,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.operator,children:"="},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.number,children:"0"},void 0,!1,void 0,this),m(r,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.number,children:"1"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(r,{children:[" ",m(r,{color:Z.syntax.keyword,children:"for"},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.variable,children:"_"},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.keyword,children:"in"},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.function,children:"range"},void 0,!1,void 0,this),m(r,{color:Z.text.primary,children:"("},void 0,!1,void 0,this),m(r,{color:Z.syntax.variable,children:"n"},void 0,!1,void 0,this),m(r,{color:Z.text.primary,children:"):"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(r,{children:[" ",m(r,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this),m(r,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.operator,children:"="},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this),m(r,{color:Z.syntax.operator,children:","},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.operator,children:"+"},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.variable,children:"b"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(r,{children:[" ",m(r,{color:Z.syntax.keyword,children:"return"},void 0,!1,void 0,this)," ",m(r,{color:Z.syntax.variable,children:"a"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(r,{children:" "},void 0,!1,void 0,this),m(r,{color:Z.error,children:["- print(",m(r,{color:Z.syntax.string,children:'"Hello, "'},void 0,!1,void 0,this)," + name)"]},void 0,!0,void 0,this),m(r,{color:Z.success,children:["+ print(",m(r,{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)},oV=({theme:$})=>{let{colors:Z}=$;return m(w2,{flexDirection:"column",paddingLeft:1,paddingTop:1,children:[m(r,{children:" "},void 0,!1,void 0,this),m(r,{bold:!0,color:Z.text.primary,children:"颜色配置"},void 0,!1,void 0,this),m(r,{children:" "},void 0,!1,void 0,this),m(r,{children:[m(r,{color:Z.text.muted,children:"Primary: "},void 0,!1,void 0,this),m(r,{color:Z.primary,children:Z.primary},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(r,{children:[m(r,{color:Z.text.muted,children:"Success: "},void 0,!1,void 0,this),m(r,{color:Z.success,children:Z.success},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(r,{children:[m(r,{color:Z.text.muted,children:"Error: "},void 0,!1,void 0,this),m(r,{color:Z.error,children:Z.error},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(r,{children:[m(r,{color:Z.text.muted,children:"Warning: "},void 0,!1,void 0,this),m(r,{color:Z.warning,children:Z.warning},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m(r,{children:[m(r,{color:Z.text.muted,children:"Info: "},void 0,!1,void 0,this),m(r,{color:Z.info,children:Z.info},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},VF=()=>{let $=W4(),Z=i$.getCurrentThemeName(),Y=A2.findIndex((_)=>_.label===Z),Q=Y>=0?A2[Y].theme:A2[0].theme,[X,J]=bF(Q),[G,q]=bF(!1),K=iV(async(_)=>{if(G)return;q(!0);try{await b0().setTheme(_.value),$.closeModal()}catch(z){console.error("❌ 主题切换失败:",z instanceof Error?z.message:z)}finally{q(!1)}}),W=(_)=>{let z=A2.find((w)=>w.id===_.value);if(z)J(z.theme)},O=q1()==="theme-selector",F=Q$(!1);rV((_,z)=>{if(z.ctrl&&_==="c"||z.meta&&_==="c"){F();return}if(z.escape&&!G)$.closeModal()},{isActive:O});let H=(_)=>{let{isSelected:z,label:w}=_,L=w===Z?"✓":" ";return m(r,{color:z?X.colors.primary:X.colors.text.primary,children:[L," ",w]},void 0,!0,void 0,this)};return m(w2,{flexDirection:"column",height:"100%",children:[m(w2,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:X.colors.border.light,children:m(r,{bold:!0,color:X.colors.primary,children:"\uD83C\uDFA8 主题选择器"},void 0,!1,void 0,this)},void 0,!1,void 0,this),m(w2,{flexDirection:"row",flexGrow:1,children:[m(w2,{width:"40%",borderStyle:"single",borderColor:X.colors.border.light,paddingX:1,children:m(w2,{flexDirection:"column",children:[m(w2,{paddingTop:1,paddingBottom:1,children:m(r,{bold:!0,color:X.colors.text.primary,children:["可用主题 (",RF.length,")"]},void 0,!0,void 0,this)},void 0,!1,void 0,this),m(aV,{items:RF,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),m(w2,{width:"60%",flexDirection:"column",borderStyle:"single",borderColor:X.colors.border.light,children:[m(nV,{theme:X},void 0,!1,void 0,this),m(oV,{theme:X},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),m(w2,{paddingX:2,paddingY:1,borderStyle:"single",borderColor:X.colors.border.light,children:m(r,{color:X.colors.text.muted,children:G?"正在保存...":"Enter: 选择主题 | Esc: 取消"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)};import{jsxDEV as m0}from"react/jsx-dev-runtime";var e$=x("UI"),MF=({debug:$,continue:Z,...Y})=>{if($)e$.debug("[Debug] BladeInterface props:",{permissionMode:Y.permissionMode,yolo:Y.yolo,maxTurns:Y.maxTurns,continue:Z});let Q=F5(!1),X=F5(!1),J=F5(!1),G=F5(null),q=QU(),K=XU(),W=x6(),U=qU(),O=GU(),F=W4(),H=K4(),_=FU(),z=a8(),w=U4(),{exit:B}=sV(),L=q==="ready",N=q==="needsSetup",M=q==="idle",{confirmationState:b,confirmationHandler:j,handleResponse:T}=vU(),{executeCommand:A,handleAbort:k}=yU(Y.systemPrompt,Y.appendSystemPrompt,j,Y.maxTurns),{getPreviousCommand:c,getNextCommand:o,addToHistory:S}=EU();dU();let y=CU("",0),l=t$(async()=>{let Y0=z,I0;if(Y0==="default")I0="autoEdit";else if(Y0==="autoEdit")I0="plan";else if(Y0==="plan")I0="spec";else if(Y0==="spec")I0="default";else I0="default";try{if(await b0().setPermissionMode(I0),I0==="spec")try{let L$=x0.getInstance();await L$.initialize(process.cwd());let N$=await L$.listSpecs();if(N$.length>0){let E$=N$[0];await L$.loadSpec(E$.name),H.addAssistantMessage(`\uD83D\uDCCB **已进入 Spec 模式**
2851
2851
 
2852
2852
  `+`检测到已存在的 Spec: **${E$.name}**
2853
2853
  `+`当前阶段: ${E$.phase}
@@ -2858,6 +2858,6 @@ ${Z0}
2858
2858
  `+"`提案 → 需求 → 设计 → 任务 → 实现`\n\n"+'例如:"实现用户认证功能" 或 "添加暗黑模式支持"')}catch(L$){e$.warn("Failed to initialize SpecManager:",L$),H.addAssistantMessage(`\uD83D\uDCCB **已进入 Spec 模式**
2859
2859
 
2860
2860
  `+`请告诉我你想实现什么功能,我会引导你完成整个工作流:
2861
- `+"`提案 → 需求 → 设计 → 任务 → 实现`\n\n"+'例如:"实现用户认证功能" 或 "添加暗黑模式支持"')}}catch(L$){e$.error("❌ 权限模式切换失败:",L$ instanceof Error?L$.message:L$)}}),I=t$(async(Y0)=>{try{await b0().addModel({name:Y0.name,provider:Y0.provider,apiKey:Y0.apiKey,baseUrl:Y0.baseUrl,model:Y0.model}),F.setInitializationStatus("ready")}catch(I0){e$.error("❌ 初始化配置保存失败:",I0 instanceof Error?I0.message:I0),F.setInitializationStatus("ready")}}),D=t$(()=>{if(W==="shortcuts")F.closeModal();else F.setActiveModal("shortcuts")}),{showSuggestions:V,suggestions:g,selectedSuggestionIndex:u}=uU(y,A,c,o,S,k,w,l,D,W==="shortcuts");W8(()=>{if(y.value&&W==="shortcuts")F.closeModal()},[y.value,W,F]);let v=t$(async()=>{J.current=!0;try{let Y0=await S$.listSessions();if(Y0.length===0){H.addAssistantMessage("没有找到历史会话,开始新对话。");return}let I0=Y0[0],L$=await S$.loadSession(I0.sessionId),N$=L$.map((E$,OQ)=>({id:`restored-${Date.now()}-${OQ}`,role:E$.role,content:typeof E$.content==="string"?E$.content:JSON.stringify(E$.content),timestamp:Date.now()-(L$.length-OQ)*1000,metadata:E$.metadata&&typeof E$.metadata==="object"?E$.metadata:void 0}));H.restoreSession(I0.sessionId,N$)}catch(Y0){e$.error("[BladeInterface] 继续会话失败:",Y0),H.addAssistantMessage("继续会话失败,开始新对话。")}}),Z0=t$(async()=>{J.current=!0;try{if(typeof Y.resume==="string"&&Y.resume!=="true"){let I0=await S$.loadSession(Y.resume),L$=I0.map((N$,E$)=>({id:`restored-${Date.now()}-${E$}`,role:N$.role,content:typeof N$.content==="string"?N$.content:JSON.stringify(N$.content),timestamp:Date.now()-(I0.length-E$)*1000,metadata:N$.metadata&&typeof N$.metadata==="object"?N$.metadata:void 0}));H.restoreSession(Y.resume,L$);return}let Y0=await S$.listSessions();if(Y0.length===0)e$.error("没有找到历史会话"),r8(1);F.showSessionSelector(Y0)}catch(Y0){e$.error("[BladeInterface] 加载会话失败:",Y0),r8(1)}});W8(()=>{if(Q.current)return;if(Z){Q.current=!0,v();return}if(Y.resume)Q.current=!0,Z0()},[Z,Y.resume,v,Z0]);let d=t$(async(Y0)=>{let I0=b.details?.type;if(I0==="enterPlanMode"&&Y0.approved)try{await b0().setPermissionMode("plan"),e$.debug("[BladeInterface] Entered Plan mode")}catch(L$){e$.error("[BladeInterface] Failed to enter Plan mode:",L$)}if(I0==="exitPlanMode"&&Y0.approved)e$.debug("[BladeInterface] ExitPlanMode approved, Store auto-synced");T(Y0)}),s=t$(()=>{H.addAssistantMessage("❌ 设置已取消"),H.addAssistantMessage("Blade 需要 API 配置才能正常工作。"),H.addAssistantMessage("您可以稍后运行 Blade 重新进入设置向导。"),r8(0)}),C=t$(()=>{F.closeModal()}),i=t$(async(Y0)=>{try{let I0=await S$.loadSession(Y0),L$=I0.map((N$,E$)=>({id:`restored-${Date.now()}-${E$}`,role:N$.role,content:typeof N$.content==="string"?N$.content:JSON.stringify(N$.content),timestamp:Date.now()-(I0.length-E$)*1000,metadata:N$.metadata&&typeof N$.metadata==="object"?N$.metadata:void 0}));H.restoreSession(Y0,L$),F.closeModal()}catch(I0){e$.error("[BladeInterface] Failed to restore session:",I0),F.closeModal()}}),n=t$(()=>{if(Y.resume)B();else F.closeModal()}),B0=t$((Y0)=>{F.showModelEditWizard(Y0)}),j0=t$((Y0)=>{H.addAssistantMessage(`✅ 已添加模型配置: ${Y0.name},并已切换到该模型`),C()}),K$=t$((Y0)=>{H.addAssistantMessage(`✅ 已更新模型配置: ${Y0.name}`),C()});W8(()=>{if(N){_.setFocus("model-config-wizard");return}if(b.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")},[N,b.isVisible,W,_.setFocus]),W8(()=>{if(!L||J.current)return;if($X().length>0){J.current=!0;return}J.current=!0,H.addAssistantMessage("请输入您的问题,我将为您提供帮助。")},[L]),W8(()=>{if(!K)return;if(G.current===K)return;if(G.current=K,q==="error")H.addAssistantMessage(`❌ 初始化失败: ${K}`);else H.addAssistantMessage(`❌ ${K}`),H.addAssistantMessage("请重新尝试设置,或检查文件权限")},[K,q,H.addAssistantMessage]);let $1=t$(async(Y0)=>{try{await A({displayText:Y0,text:Y0,images:[],parts:[{type:"text",text:Y0}]})}catch(I0){let L$=I0 instanceof Error?I0.message:"无法发送初始消息";H.addAssistantMessage(`❌ 初始消息发送失败:${L$}`)}});W8(()=>{let Y0=Y.initialMessage?.trim();if(!Y0||X.current||!L||N)return;X.current=!0,S(Y0),$1(Y0)},[Y.initialMessage,L,N,A,S]);let K1=t$(async(Y0)=>{try{await b0().setPermissionMode(Y0)}catch(I0){e$.error("❌ 权限模式初始化失败:",I0 instanceof Error?I0.message:I0)}});if(W8(()=>{let Y0=Y.permissionMode;if($)e$.debug("[Debug] permissionMode from CLI:",Y0),e$.debug("[Debug] current permissionMode:",z);if(!Y0||Y0===z)return;K1(Y0)},[Y.permissionMode,z]),M)return null;if(N)return m0(ZQ,{mode:"setup",onComplete:I,onCancel:s},void 0,!1,void 0,this);if($)e$.debug("[Debug] 渲染主界面,条件检查:",{confirmationVisible:b.isVisible,activeModal:W});let b1=W==="modelSelector",J0=O,W$=W==="modelAddWizard"?"add":W==="modelEditWizard"&&J0?"edit":null,A0=b1||Boolean(W$),X2=W==="agentsManager",T$=W==="agentCreationWizard",W1=W==="skillsManager",p1=W==="pluginsManager",w6=J0?{name:J0.name,provider:J0.provider,baseUrl:J0.baseUrl,apiKey:J0.apiKey,model:J0.model}:void 0,WQ=b.isVisible&&b.details?b.details.type==="askUserQuestion"&&b.details.questions?m0(OF,{questions:b.details.questions,onComplete:(Y0)=>d({approved:!0,answers:Y0}),onCancel:()=>d({approved:!1})},void 0,!1,void 0,this):m0(OO,{details:b.details,onResponse:d},void 0,!1,void 0,this):W==="themeSelector"?m0(VF,{},void 0,!1,void 0,this):W==="permissionsManager"?m0(KF,{onClose:C},void 0,!1,void 0,this):W==="sessionSelector"?m0(HF,{sessions:U,onSelect:i,onCancel:n},void 0,!1,void 0,this):W==="hooksManager"?m0(HO,{onClose:C},void 0,!1,void 0,this):null,UQ=Boolean(WQ);return m0(A4,{flexDirection:"column",width:"100%",overflow:"hidden",children:[WQ,m0(A4,{flexDirection:"column",display:UQ?"none":"flex",children:[z==="spec"&&m0(BF,{},void 0,!1,void 0,this),m0(pO,{},void 0,!1,void 0,this),m0(AF,{},void 0,!1,void 0,this),m0(vO,{paused:UQ},void 0,!1,void 0,this),m0(MO,{input:y.value,cursorPosition:y.cursorPosition,onChange:y.setValue,onChangeCursorPosition:y.setCursorPosition,onAddPasteMapping:y.addPasteMapping,onAddImagePasteMapping:y.addImagePasteMapping},void 0,!1,void 0,this),b1&&m0(A4,{marginTop:1,paddingX:2,children:m0(QF,{onClose:C,onEdit:B0},void 0,!1,void 0,this)},void 0,!1,void 0,this),W$&&m0(A4,{marginTop:1,paddingX:2,children:m0(ZQ,{mode:W$,modelId:J0?.id,initialConfig:W$==="edit"?w6:void 0,onComplete:W$==="edit"?K$:j0,onCancel:C},void 0,!1,void 0,this)},void 0,!1,void 0,this),X2&&m0(A4,{marginTop:1,paddingX:2,children:m0(aU,{onComplete:C,onCancel:C},void 0,!1,void 0,this)},void 0,!1,void 0,this),T$&&m0(A4,{marginTop:1,paddingX:2,children:m0(K6,{onComplete:C,onCancel:C},void 0,!1,void 0,this)},void 0,!1,void 0,this),W1&&m0(A4,{marginTop:1,paddingX:2,children:m0(_F,{onComplete:C,onCancel:C},void 0,!1,void 0,this)},void 0,!1,void 0,this),p1&&m0(A4,{marginTop:1,paddingX:2,children:m0(WF,{onComplete:C,onCancel:C},void 0,!1,void 0,this)},void 0,!1,void 0,this),m0(tU,{suggestions:g,selectedIndex:u,visible:V&&!A0},void 0,!1,void 0,this),m0(sU,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{Box as tV,Text as b4}from"ink";import eV from"react";import{jsxDEV as f2}from"react/jsx-dev-runtime";class H5 extends eV.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 f2(tV,{flexDirection:"column",padding:1,borderStyle:"round",borderColor:"red",children:[f2(b4,{color:"red",children:"\uD83D\uDCA5 应用发生错误"},void 0,!1,void 0,this),f2(b4,{children:" "},void 0,!1,void 0,this),f2(b4,{color:"red",children:this.state.error?.message},void 0,!1,void 0,this),f2(b4,{children:" "},void 0,!1,void 0,this),f2(b4,{color:"gray",children:"错误详情:"},void 0,!1,void 0,this),f2(b4,{color:"gray",children:this.state.error?.stack},void 0,!1,void 0,this),f2(b4,{children:" "},void 0,!1,void 0,this),f2(b4,{color:"yellow",children:"请重启应用或联系开发者"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return this.props.children}}import{Box as U8,Text as h2,useInput as $M}from"ink";import{useState as XQ}from"react";import{jsxDEV as c$}from"react/jsx-dev-runtime";var _5=[{key:"update",label:"Update now",description:`runs \`${_Y()}\``},{key:"skip",label:"Skip",description:""},{key:"skip_until_next",label:"Skip until next version",description:""}],DF=({versionInfo:$,onComplete:Z})=>{let[Y,Q]=XQ(0),[X,J]=XQ(!1),[G,q]=XQ(null);$M((W,U)=>{if(U.ctrl&&W==="c"){o4().shutdown("SIGINT",0);return}if(X||G)return;if(U.upArrow||W==="k")Q((O)=>O>0?O-1:_5.length-1);else if(U.downArrow||W==="j")Q((O)=>O<_5.length-1?O+1:0);else if(U.return)K(_5[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 cW();q(U.message),setTimeout(()=>{o4().shutdown("SIGINT",0)},1500);break}case"skip":Z();break;case"skip_until_next":if($.latestVersion)await dW($.latestVersion);Z();break}};if(G)return c$(U8,{flexDirection:"column",marginY:1,children:c$(h2,{children:G},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(X)return c$(U8,{flexDirection:"column",marginY:1,children:c$(h2,{color:"cyan",children:"Updating..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);return c$(U8,{flexDirection:"column",marginY:1,children:[c$(h2,{color:"yellow",bold:!0,children:["✨ Update available! ",c$(h2,{color:"gray",children:[$.currentVersion," ","→"," ",$.latestVersion]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),c$(U8,{marginTop:1,children:c$(h2,{color:"gray",children:["Release notes:"," ",c$(h2,{color:"cyan",underline:!0,children:$.releaseNotesUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),c$(U8,{flexDirection:"column",marginTop:1,children:_5.map((W,U)=>{let O=U===Y,F=O?"› ":" ",H=`${U+1}. `;return c$(U8,{children:c$(h2,{color:O?"cyan":void 0,children:[F,H,W.label,W.description&&c$(h2,{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),c$(U8,{marginTop:1,children:c$(h2,{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)};V4();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 z5}from"react/jsx-dev-runtime";function YM($){if(G0().config.actions.setConfig($),$.debug)console.log("[Debug] 模型配置检查通过,准备就绪");R2().setInitializationStatus("ready")}var yF=($)=>{let[Z,Y]=JQ(!1),[Q,X]=JQ(null),[J,G]=JQ(!1),q=jF(async()=>{let W=G0().config.config??O8,U=L5(W,$);if(YM(U),U.debug)console.error("[Debug] 运行时配置:",U);let O=U.theme;if(O&&i$.hasTheme(O)){if(i$.setTheme(O),$.debug)console.log(`✓ 已加载主题: ${O}`)}try{let F=Y$.loadFromStandardLocations();if($.debug&&F>0)console.log(`✓ 已加载 ${F} 个 subagents: ${Y$.getAllNames().join(", ")}`)}catch(F){if($.debug)console.warn("⚠️ Subagents 加载失败:",G3(F))}try{let F=y0.getInstance();if(F.loadConfig(U.hooks||{}),$.debug&&U.hooks?.enabled)console.log("✓ Hooks 系统已启用");let H=G0(),_=H.session.sessionId;if(MQ(_),F.isEnabled()){let z=H.config.config?.permissionMode||"default",w=!!$.resume,B=await F.executeSessionStartHooks({projectDir:process.cwd(),sessionId:_,permissionMode:z,isResume:w,resumeSessionId:typeof $.resume==="string"?$.resume:void 0});if(B.env){for(let[L,N]of Object.entries(B.env))process.env[L]=N;if($.debug)console.log("✓ SessionStart hooks 注入环境变量:",Object.keys(B.env).join(", "))}if(B.warning&&$.debug)console.warn("⚠️ SessionStart hooks 警告:",B.warning)}}catch(F){if($.debug)console.warn("⚠️ Hooks 初始化失败:",G3(F))}try{let F=await v4();if($.debug&&F.skills.length>0)console.log(`✓ 已加载 ${F.skills.length} 个 skills: ${F.skills.map((H)=>H.name).join(", ")}`);if(F.errors.length>0&&$.debug)for(let H of F.errors)console.warn(`⚠️ Skill 加载错误 (${H.path}): ${H.error}`)}catch(F){if($.debug)console.warn("⚠️ Skills 初始化失败:",G3(F))}try{let F=await FW(process.cwd());if($.debug&&F.commands.length>0)console.log(`✓ 已加载 ${F.commands.length} 个自定义命令: ${F.commands.map((H)=>H.name).join(", ")}`);if(F.errors.length>0&&$.debug)for(let H of F.errors)console.warn(`⚠️ 自定义命令加载错误 (${H.path}): ${H.error}`)}catch(F){if($.debug)console.warn("⚠️ 自定义命令初始化失败:",G3(F))}try{let H=await s$().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 Y4();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(F){if($.debug)console.warn("⚠️ 插件系统初始化失败:",G3(F))}oW(async()=>{C$.getInstance().killAll(),await e0.getInstance().disconnectAll(),y0.getInstance().cleanup()}),Y(!0)}),K=jF(async()=>{if($.versionCheckPromise){let W=await $.versionCheckPromise;if(W){X(W),G(!0);return}}await q()});if(ZM(()=>{K()},[]),J&&Q)return z5(H5,{children:z5(DF,{versionInfo:Q,onComplete:()=>{G(!1),q()}},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(!Z)return null;return z5(H5,{children:z5(MF,{...$},void 0,!1,void 0,this)},void 0,!1,void 0,this)};var KQ=CF(process.argv),PF=KQ.indexOf("--debug");if(PF!==-1){let $=KQ[PF+1],Z=$&&!$.startsWith("-")?$:!0;m1.setGlobalDebug(Z)}async function FM(){if(process.getuid&&process.getuid()===0){let Y=!!process.env.SUDO_USER,Q=!!process.env.container||!!process.env.DOCKER_CONTAINER||!!process.env.KUBERNETES_SERVICE_HOST,X=!!process.env.CI,J=!!process.env.BLADE_ALLOW_ROOT;if(Y&&!J)console.error(""),console.error("❌ 请不要使用 sudo 运行 blade"),console.error(""),console.error("原因:"),console.error(" 使用 sudo 会创建属于 root 的配置文件,"),console.error(" 导致普通用户无法访问。"),console.error(""),console.error("正确用法:"),console.error(" blade # 直接运行,不要加 sudo"),console.error(""),console.error("如果遇到权限错误,请运行:"),console.error(" sudo chown -R $USER:$USER ~/.blade/"),console.error(""),console.error("如果你确实需要以 root 运行(容器/CI),设置环境变量:"),console.error(" BLADE_ALLOW_ROOT=1 blade"),console.error(""),process.exit(1)}sW();let $=lW();if(await _W())return;if(KQ.includes("--acp")){let{runAcpIntegration:Y}=await Promise.resolve().then(() => (vF(),IF));await Y();return}let Z=OM(CF(process.argv)).scriptName(R4.scriptName).usage(R4.usage).version(R4.version).locale(R4.locale).showHelpOnFail(R4.showHelpOnFail).demandCommand(0,"").recommendCommands().strict(R4.strict).parserConfiguration({"populate--":!0}).options(BQ).middleware([YX,QX,XX]).command(MX).command(JX).command(iW).command(GX).command(aW).command(hW).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(`
2861
+ `+"`提案 → 需求 → 设计 → 任务 → 实现`\n\n"+'例如:"实现用户认证功能" 或 "添加暗黑模式支持"')}}catch(L$){e$.error("❌ 权限模式切换失败:",L$ instanceof Error?L$.message:L$)}}),I=t$(async(Y0)=>{try{await b0().addModel({name:Y0.name,provider:Y0.provider,apiKey:Y0.apiKey,baseUrl:Y0.baseUrl,model:Y0.model}),F.setInitializationStatus("ready")}catch(I0){e$.error("❌ 初始化配置保存失败:",I0 instanceof Error?I0.message:I0),F.setInitializationStatus("ready")}}),D=t$(()=>{if(W==="shortcuts")F.closeModal();else F.setActiveModal("shortcuts")}),{showSuggestions:V,suggestions:g,selectedSuggestionIndex:u}=uU(y,A,c,o,S,k,w,l,D,W==="shortcuts");W8(()=>{if(y.value&&W==="shortcuts")F.closeModal()},[y.value,W,F]);let v=t$(async()=>{J.current=!0;try{let Y0=await S$.listSessions();if(Y0.length===0){H.addAssistantMessage("没有找到历史会话,开始新对话。");return}let I0=Y0[0],L$=await S$.loadSession(I0.sessionId),N$=L$.map((E$,OQ)=>({id:`restored-${Date.now()}-${OQ}`,role:E$.role,content:typeof E$.content==="string"?E$.content:JSON.stringify(E$.content),timestamp:Date.now()-(L$.length-OQ)*1000,metadata:E$.metadata&&typeof E$.metadata==="object"?E$.metadata:void 0}));H.restoreSession(I0.sessionId,N$)}catch(Y0){e$.error("[BladeInterface] 继续会话失败:",Y0),H.addAssistantMessage("继续会话失败,开始新对话。")}}),Z0=t$(async()=>{J.current=!0;try{if(typeof Y.resume==="string"&&Y.resume!=="true"){let I0=await S$.loadSession(Y.resume),L$=I0.map((N$,E$)=>({id:`restored-${Date.now()}-${E$}`,role:N$.role,content:typeof N$.content==="string"?N$.content:JSON.stringify(N$.content),timestamp:Date.now()-(I0.length-E$)*1000,metadata:N$.metadata&&typeof N$.metadata==="object"?N$.metadata:void 0}));H.restoreSession(Y.resume,L$);return}let Y0=await S$.listSessions();if(Y0.length===0)e$.error("没有找到历史会话"),r8(1);F.showSessionSelector(Y0)}catch(Y0){e$.error("[BladeInterface] 加载会话失败:",Y0),r8(1)}});W8(()=>{if(Q.current)return;if(Z){Q.current=!0,v();return}if(Y.resume)Q.current=!0,Z0()},[Z,Y.resume,v,Z0]);let d=t$(async(Y0)=>{let I0=b.details?.type;if(I0==="enterPlanMode"&&Y0.approved)try{await b0().setPermissionMode("plan"),e$.debug("[BladeInterface] Entered Plan mode")}catch(L$){e$.error("[BladeInterface] Failed to enter Plan mode:",L$)}if(I0==="exitPlanMode"&&Y0.approved)e$.debug("[BladeInterface] ExitPlanMode approved, Store auto-synced");T(Y0)}),s=t$(()=>{H.addAssistantMessage("❌ 设置已取消"),H.addAssistantMessage("Blade 需要 API 配置才能正常工作。"),H.addAssistantMessage("您可以稍后运行 Blade 重新进入设置向导。"),r8(0)}),C=t$(()=>{F.closeModal()}),i=t$(async(Y0)=>{try{let I0=await S$.loadSession(Y0),L$=I0.map((N$,E$)=>({id:`restored-${Date.now()}-${E$}`,role:N$.role,content:typeof N$.content==="string"?N$.content:JSON.stringify(N$.content),timestamp:Date.now()-(I0.length-E$)*1000,metadata:N$.metadata&&typeof N$.metadata==="object"?N$.metadata:void 0}));H.restoreSession(Y0,L$),F.closeModal()}catch(I0){e$.error("[BladeInterface] Failed to restore session:",I0),F.closeModal()}}),n=t$(()=>{if(Y.resume)B();else F.closeModal()}),B0=t$((Y0)=>{F.showModelEditWizard(Y0)}),j0=t$((Y0)=>{H.addAssistantMessage(`✅ 已添加模型配置: ${Y0.name},并已切换到该模型`),C()}),K$=t$((Y0)=>{H.addAssistantMessage(`✅ 已更新模型配置: ${Y0.name}`),C()});W8(()=>{if(N){_.setFocus("model-config-wizard");return}if(b.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")},[N,b.isVisible,W,_.setFocus]),W8(()=>{if(!L||J.current)return;if($X().length>0){J.current=!0;return}J.current=!0,H.addAssistantMessage("请输入您的问题,我将为您提供帮助。")},[L]),W8(()=>{if(!K)return;if(G.current===K)return;if(G.current=K,q==="error")H.addAssistantMessage(`❌ 初始化失败: ${K}`);else H.addAssistantMessage(`❌ ${K}`),H.addAssistantMessage("请重新尝试设置,或检查文件权限")},[K,q,H.addAssistantMessage]);let $1=t$(async(Y0)=>{try{await A({displayText:Y0,text:Y0,images:[],parts:[{type:"text",text:Y0}]})}catch(I0){let L$=I0 instanceof Error?I0.message:"无法发送初始消息";H.addAssistantMessage(`❌ 初始消息发送失败:${L$}`)}});W8(()=>{let Y0=Y.initialMessage?.trim();if(!Y0||X.current||!L||N)return;X.current=!0,S(Y0),$1(Y0)},[Y.initialMessage,L,N,A,S]);let K1=t$(async(Y0)=>{try{await b0().setPermissionMode(Y0)}catch(I0){e$.error("❌ 权限模式初始化失败:",I0 instanceof Error?I0.message:I0)}});if(W8(()=>{let Y0=Y.permissionMode;if($)e$.debug("[Debug] permissionMode from CLI:",Y0),e$.debug("[Debug] current permissionMode:",z);if(!Y0||Y0===z)return;K1(Y0)},[Y.permissionMode,z]),M)return null;if(N)return m0(ZQ,{mode:"setup",onComplete:I,onCancel:s},void 0,!1,void 0,this);if($)e$.debug("[Debug] 渲染主界面,条件检查:",{confirmationVisible:b.isVisible,activeModal:W});let b1=W==="modelSelector",J0=O,W$=W==="modelAddWizard"?"add":W==="modelEditWizard"&&J0?"edit":null,A0=b1||Boolean(W$),X2=W==="agentsManager",T$=W==="agentCreationWizard",W1=W==="skillsManager",p1=W==="pluginsManager",w7=J0?{name:J0.name,provider:J0.provider,baseUrl:J0.baseUrl,apiKey:J0.apiKey,model:J0.model}:void 0,WQ=b.isVisible&&b.details?b.details.type==="askUserQuestion"&&b.details.questions?m0(OF,{questions:b.details.questions,onComplete:(Y0)=>d({approved:!0,answers:Y0}),onCancel:()=>d({approved:!1})},void 0,!1,void 0,this):m0(OO,{details:b.details,onResponse:d},void 0,!1,void 0,this):W==="themeSelector"?m0(VF,{},void 0,!1,void 0,this):W==="permissionsManager"?m0(KF,{onClose:C},void 0,!1,void 0,this):W==="sessionSelector"?m0(HF,{sessions:U,onSelect:i,onCancel:n},void 0,!1,void 0,this):W==="hooksManager"?m0(HO,{onClose:C},void 0,!1,void 0,this):null,UQ=Boolean(WQ);return m0(A4,{flexDirection:"column",width:"100%",overflow:"hidden",children:[WQ,m0(A4,{flexDirection:"column",display:UQ?"none":"flex",children:[z==="spec"&&m0(BF,{},void 0,!1,void 0,this),m0(pO,{},void 0,!1,void 0,this),m0(AF,{},void 0,!1,void 0,this),m0(vO,{paused:UQ},void 0,!1,void 0,this),m0(MO,{input:y.value,cursorPosition:y.cursorPosition,onChange:y.setValue,onChangeCursorPosition:y.setCursorPosition,onAddPasteMapping:y.addPasteMapping,onAddImagePasteMapping:y.addImagePasteMapping},void 0,!1,void 0,this),b1&&m0(A4,{marginTop:1,paddingX:2,children:m0(QF,{onClose:C,onEdit:B0},void 0,!1,void 0,this)},void 0,!1,void 0,this),W$&&m0(A4,{marginTop:1,paddingX:2,children:m0(ZQ,{mode:W$,modelId:J0?.id,initialConfig:W$==="edit"?w7:void 0,onComplete:W$==="edit"?K$:j0,onCancel:C},void 0,!1,void 0,this)},void 0,!1,void 0,this),X2&&m0(A4,{marginTop:1,paddingX:2,children:m0(aU,{onComplete:C,onCancel:C},void 0,!1,void 0,this)},void 0,!1,void 0,this),T$&&m0(A4,{marginTop:1,paddingX:2,children:m0(K7,{onComplete:C,onCancel:C},void 0,!1,void 0,this)},void 0,!1,void 0,this),W1&&m0(A4,{marginTop:1,paddingX:2,children:m0(_F,{onComplete:C,onCancel:C},void 0,!1,void 0,this)},void 0,!1,void 0,this),p1&&m0(A4,{marginTop:1,paddingX:2,children:m0(WF,{onComplete:C,onCancel:C},void 0,!1,void 0,this)},void 0,!1,void 0,this),m0(tU,{suggestions:g,selectedIndex:u,visible:V&&!A0},void 0,!1,void 0,this),m0(sU,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)};import{Box as tV,Text as b4}from"ink";import eV from"react";import{jsxDEV as f2}from"react/jsx-dev-runtime";class H5 extends eV.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 f2(tV,{flexDirection:"column",padding:1,borderStyle:"round",borderColor:"red",children:[f2(b4,{color:"red",children:"\uD83D\uDCA5 应用发生错误"},void 0,!1,void 0,this),f2(b4,{children:" "},void 0,!1,void 0,this),f2(b4,{color:"red",children:this.state.error?.message},void 0,!1,void 0,this),f2(b4,{children:" "},void 0,!1,void 0,this),f2(b4,{color:"gray",children:"错误详情:"},void 0,!1,void 0,this),f2(b4,{color:"gray",children:this.state.error?.stack},void 0,!1,void 0,this),f2(b4,{children:" "},void 0,!1,void 0,this),f2(b4,{color:"yellow",children:"请重启应用或联系开发者"},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return this.props.children}}import{Box as U8,Text as h2,useInput as $M}from"ink";import{useState as XQ}from"react";import{jsxDEV as c$}from"react/jsx-dev-runtime";var _5=[{key:"update",label:"Update now",description:`runs \`${_Y()}\``},{key:"skip",label:"Skip",description:""},{key:"skip_until_next",label:"Skip until next version",description:""}],DF=({versionInfo:$,onComplete:Z})=>{let[Y,Q]=XQ(0),[X,J]=XQ(!1),[G,q]=XQ(null);$M((W,U)=>{if(U.ctrl&&W==="c"){o4().shutdown("SIGINT",0);return}if(X||G)return;if(U.upArrow||W==="k")Q((O)=>O>0?O-1:_5.length-1);else if(U.downArrow||W==="j")Q((O)=>O<_5.length-1?O+1:0);else if(U.return)K(_5[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 cW();q(U.message),setTimeout(()=>{o4().shutdown("SIGINT",0)},1500);break}case"skip":Z();break;case"skip_until_next":if($.latestVersion)await dW($.latestVersion);Z();break}};if(G)return c$(U8,{flexDirection:"column",marginY:1,children:c$(h2,{children:G},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(X)return c$(U8,{flexDirection:"column",marginY:1,children:c$(h2,{color:"cyan",children:"Updating..."},void 0,!1,void 0,this)},void 0,!1,void 0,this);return c$(U8,{flexDirection:"column",marginY:1,children:[c$(h2,{color:"yellow",bold:!0,children:["✨ Update available! ",c$(h2,{color:"gray",children:[$.currentVersion," ","→"," ",$.latestVersion]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),c$(U8,{marginTop:1,children:c$(h2,{color:"gray",children:["Release notes:"," ",c$(h2,{color:"cyan",underline:!0,children:$.releaseNotesUrl},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),c$(U8,{flexDirection:"column",marginTop:1,children:_5.map((W,U)=>{let O=U===Y,F=O?"› ":" ",H=`${U+1}. `;return c$(U8,{children:c$(h2,{color:O?"cyan":void 0,children:[F,H,W.label,W.description&&c$(h2,{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),c$(U8,{marginTop:1,children:c$(h2,{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)};V4();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 z5}from"react/jsx-dev-runtime";function YM($){if(G0().config.actions.setConfig($),$.debug)console.log("[Debug] 模型配置检查通过,准备就绪");R2().setInitializationStatus("ready")}var yF=($)=>{let[Z,Y]=JQ(!1),[Q,X]=JQ(null),[J,G]=JQ(!1),q=jF(async()=>{let W=G0().config.config??O8,U=L5(W,$);if(YM(U),U.debug)console.error("[Debug] 运行时配置:",U);let O=U.theme;if(O&&i$.hasTheme(O)){if(i$.setTheme(O),$.debug)console.log(`✓ 已加载主题: ${O}`)}try{let F=Y$.loadFromStandardLocations();if($.debug&&F>0)console.log(`✓ 已加载 ${F} 个 subagents: ${Y$.getAllNames().join(", ")}`)}catch(F){if($.debug)console.warn("⚠️ Subagents 加载失败:",G3(F))}try{let F=y0.getInstance();if(F.loadConfig(U.hooks||{}),$.debug&&U.hooks?.enabled)console.log("✓ Hooks 系统已启用");let H=G0(),_=H.session.sessionId;if(MQ(_),F.isEnabled()){let z=H.config.config?.permissionMode||"default",w=!!$.resume,B=await F.executeSessionStartHooks({projectDir:process.cwd(),sessionId:_,permissionMode:z,isResume:w,resumeSessionId:typeof $.resume==="string"?$.resume:void 0});if(B.env){for(let[L,N]of Object.entries(B.env))process.env[L]=N;if($.debug)console.log("✓ SessionStart hooks 注入环境变量:",Object.keys(B.env).join(", "))}if(B.warning&&$.debug)console.warn("⚠️ SessionStart hooks 警告:",B.warning)}}catch(F){if($.debug)console.warn("⚠️ Hooks 初始化失败:",G3(F))}try{let F=await v4();if($.debug&&F.skills.length>0)console.log(`✓ 已加载 ${F.skills.length} 个 skills: ${F.skills.map((H)=>H.name).join(", ")}`);if(F.errors.length>0&&$.debug)for(let H of F.errors)console.warn(`⚠️ Skill 加载错误 (${H.path}): ${H.error}`)}catch(F){if($.debug)console.warn("⚠️ Skills 初始化失败:",G3(F))}try{let F=await FW(process.cwd());if($.debug&&F.commands.length>0)console.log(`✓ 已加载 ${F.commands.length} 个自定义命令: ${F.commands.map((H)=>H.name).join(", ")}`);if(F.errors.length>0&&$.debug)for(let H of F.errors)console.warn(`⚠️ 自定义命令加载错误 (${H.path}): ${H.error}`)}catch(F){if($.debug)console.warn("⚠️ 自定义命令初始化失败:",G3(F))}try{let H=await s$().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 Y4();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(F){if($.debug)console.warn("⚠️ 插件系统初始化失败:",G3(F))}oW(async()=>{C$.getInstance().killAll(),await e0.getInstance().disconnectAll(),y0.getInstance().cleanup()}),Y(!0)}),K=jF(async()=>{if($.versionCheckPromise){let W=await $.versionCheckPromise;if(W){X(W),G(!0);return}}await q()});if(ZM(()=>{K()},[]),J&&Q)return z5(H5,{children:z5(DF,{versionInfo:Q,onComplete:()=>{G(!1),q()}},void 0,!1,void 0,this)},void 0,!1,void 0,this);if(!Z)return null;return z5(H5,{children:z5(MF,{...$},void 0,!1,void 0,this)},void 0,!1,void 0,this)};var KQ=CF(process.argv),PF=KQ.indexOf("--debug");if(PF!==-1){let $=KQ[PF+1],Z=$&&!$.startsWith("-")?$:!0;m1.setGlobalDebug(Z)}async function FM(){if(process.getuid&&process.getuid()===0){let Y=!!process.env.SUDO_USER,Q=!!process.env.container||!!process.env.DOCKER_CONTAINER||!!process.env.KUBERNETES_SERVICE_HOST,X=!!process.env.CI,J=!!process.env.BLADE_ALLOW_ROOT;if(Y&&!J)console.error(""),console.error("❌ 请不要使用 sudo 运行 blade"),console.error(""),console.error("原因:"),console.error(" 使用 sudo 会创建属于 root 的配置文件,"),console.error(" 导致普通用户无法访问。"),console.error(""),console.error("正确用法:"),console.error(" blade # 直接运行,不要加 sudo"),console.error(""),console.error("如果遇到权限错误,请运行:"),console.error(" sudo chown -R $USER:$USER ~/.blade/"),console.error(""),console.error("如果你确实需要以 root 运行(容器/CI),设置环境变量:"),console.error(" BLADE_ALLOW_ROOT=1 blade"),console.error(""),process.exit(1)}sW();let $=lW();if(await _W())return;if(KQ.includes("--acp")){let{runAcpIntegration:Y}=await Promise.resolve().then(() => (vF(),IF));await Y();return}let Z=OM(CF(process.argv)).scriptName(R4.scriptName).usage(R4.usage).version(R4.version).locale(R4.locale).showHelpOnFail(R4.showHelpOnFail).demandCommand(0,"").recommendCommands().strict(R4.strict).parserConfiguration({"populate--":!0}).options(BQ).middleware([YX,QX,XX]).command(MX).command(JX).command(iW).command(GX).command(aW).command(hW).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(`
2862
2862
  Stack trace:`),console.error(Q.stack),process.exit(1);if(Y)console.error("❌ Invalid arguments:"),console.error(Y),console.error(`
2863
2863
  \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,WM(UM.createElement(yF,J),{patchConsole:!0,exitOnCtrlC:!1,alternateBuffer:!1})});try{await Z.parse()}catch(Y){console.error("❌ Parse error:",Y),process.exit(1)}}if(H$.main==H$.module)FM().catch(console.error);export{FM as main};