blade-code 0.4.1 → 0.4.3

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 (64) hide show
  1. package/dist/blade.js +4 -3084
  2. package/dist/chunk-094ekgv6.js +41 -0
  3. package/dist/chunk-1dvhq0mn.js +2 -0
  4. package/dist/chunk-420vamtq.js +1 -0
  5. package/dist/chunk-52k9k0w8.js +1 -0
  6. package/dist/chunk-5mtjqqav.js +8 -0
  7. package/dist/chunk-5zkcs06z.js +3 -0
  8. package/dist/chunk-76emdpxa.js +76 -0
  9. package/dist/chunk-7g20yr9m.js +1 -0
  10. package/dist/chunk-7ycmx7c2.js +2 -0
  11. package/dist/chunk-80jc465v.js +13 -0
  12. package/dist/chunk-8jwqy5d0.js +49 -0
  13. package/dist/chunk-bhjw4b73.js +1 -0
  14. package/dist/chunk-c7e33j6k.js +6 -0
  15. package/dist/chunk-ehcjnwnr.js +582 -0
  16. package/dist/chunk-esnkk33h.js +21 -0
  17. package/dist/chunk-g5pasj7t.js +1 -0
  18. package/dist/chunk-gm59f5pe.js +1 -0
  19. package/dist/chunk-h3ccyfqj.js +1 -0
  20. package/dist/chunk-hbv7nxdh.js +6 -0
  21. package/dist/chunk-hhnst8br.js +4 -0
  22. package/dist/chunk-hwhz4m2c.js +157 -0
  23. package/dist/chunk-hwkdy2ez.js +2 -0
  24. package/dist/chunk-j2ag7hh6.js +2 -0
  25. package/dist/chunk-jz59sjzb.js +6 -0
  26. package/dist/chunk-njy55zd2.js +34 -0
  27. package/dist/chunk-p0n9ggyv.js +6 -0
  28. package/dist/chunk-phzbecpx.js +2 -0
  29. package/dist/chunk-q4hrt6r4.js +1 -0
  30. package/dist/chunk-qbm9qrtg.js +2063 -0
  31. package/dist/chunk-qwfywxs2.js +2 -0
  32. package/dist/chunk-set7v1rf.js +3 -0
  33. package/dist/chunk-tf0m57f5.js +4 -0
  34. package/dist/chunk-th432d0b.js +1 -0
  35. package/dist/chunk-vwn39c84.js +2 -0
  36. package/dist/chunk-y5g06jmk.js +24 -0
  37. package/dist/chunk-yddnm9n2.js +1 -0
  38. package/dist/chunk-yjs7nvr5.js +1 -0
  39. package/dist/chunk-zs7xeymy.js +1 -0
  40. package/dist/chunk-zszvkp6z.js +10 -0
  41. package/dist/web/assets/CodeBlockHighlighter-C86flFwh.js +1 -0
  42. package/dist/web/assets/FilePreview-R1mRzyRz.js +7 -0
  43. package/dist/web/assets/MarkdownRenderer-B46lJYAn.js +1 -0
  44. package/dist/web/assets/McpModal-QRv5Ij61.js +5 -0
  45. package/dist/web/assets/SettingsModal-D-mi6mUR.js +1 -0
  46. package/dist/web/assets/SettingsStore-Dmo3sZ_R.js +1 -0
  47. package/dist/web/assets/SkillsModal-DNXjbjEs.js +1 -0
  48. package/dist/web/assets/TerminalPanel-DG_Q4UKr.js +1 -0
  49. package/dist/web/assets/dialog-CsiChiYt.js +1 -0
  50. package/dist/web/assets/index-BeYCsOvo.js +10 -0
  51. package/dist/web/assets/index-DmXmCQOW.css +1 -0
  52. package/dist/web/assets/useRequest-BJp539HQ.js +1 -0
  53. package/dist/web/assets/vendor-icons-DlzC8I7m.js +166 -0
  54. package/dist/web/assets/vendor-markdown-DIcugY1e.js +36 -0
  55. package/dist/web/assets/vendor-monaco-w6PwaWGP.js +11 -0
  56. package/dist/web/assets/vendor-radix-CfxBc_4-.js +45 -0
  57. package/dist/web/assets/vendor-react-Dm1xU4bP.js +49 -0
  58. package/dist/web/assets/vendor-xterm-9CEnUXvW.css +32 -0
  59. package/dist/web/assets/vendor-xterm-DuYZoU4T.js +49 -0
  60. package/dist/web/index.html +2 -2
  61. package/package.json +4 -1
  62. package/dist/web/assets/index-CVfbjhXj.js +0 -11
  63. package/dist/web/assets/index-C_uNajWk.js +0 -360
  64. package/dist/web/assets/index-QhJxewcm.css +0 -32
@@ -0,0 +1,41 @@
1
+ import{xb as l}from"./chunk-7ycmx7c2.js";import{Bb as x}from"./chunk-set7v1rf.js";import{Db as N}from"./chunk-j2ag7hh6.js";import{nanoid as j}from"nanoid";var U;((R)=>{R.PreToolUse="PreToolUse";R.PostToolUse="PostToolUse";R.PostToolUseFailure="PostToolUseFailure";R.PermissionRequest="PermissionRequest";R.UserPromptSubmit="UserPromptSubmit";R.SessionStart="SessionStart";R.SessionEnd="SessionEnd";R.Stop="Stop";R.SubagentStop="SubagentStop";R.Notification="Notification";R.Compaction="Compaction"})(U||={});var w;((W)=>{W.Approve="approve";W.Block="block";W.Async="async"})(w||={});var M;((W)=>{W.Allow="allow";W.Deny="deny";W.Ask="ask"})(M||={});var C={enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,PreToolUse:[],PostToolUse:[{name:"builtin:code-review-sensor",matcher:{tools:"Edit|Write"},hooks:[{type:"prompt",prompt:"审查此代码变更,重点检查:"+"1) 安全漏洞(命令注入、XSS、SQL 注入、硬编码密钥/密码)"+"2) 明显的逻辑错误(无限循环、off-by-one、空引用)"+"3) 类型安全问题。"+"如果发现严重问题,将问题描述放在 hookSpecificOutput.additionalContext 中。"+"如果没有严重问题,返回 approve。",model:void 0,timeout:15}]}],PostToolUseFailure:[],PermissionRequest:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]};function S(Q,Y){return{...Q,...Y,PreToolUse:Y.PreToolUse??Q.PreToolUse,PostToolUse:Y.PostToolUse??Q.PostToolUse,PostToolUseFailure:Y.PostToolUseFailure??Q.PostToolUseFailure,PermissionRequest:Y.PermissionRequest??Q.PermissionRequest,UserPromptSubmit:Y.UserPromptSubmit??Q.UserPromptSubmit,SessionStart:Y.SessionStart??Q.SessionStart,SessionEnd:Y.SessionEnd??Q.SessionEnd,Stop:Y.Stop??Q.Stop,SubagentStop:Y.SubagentStop??Q.SubagentStop,Notification:Y.Notification??Q.Notification,Compaction:Y.Compaction??Q.Compaction}}function m(){let Q={};if(process.env.BLADE_DISABLE_HOOKS==="true")Q.enabled=!1;if(process.env.BLADE_HOOK_TIMEOUT){let Y=parseInt(process.env.BLADE_HOOK_TIMEOUT,10);if(!isNaN(Y)&&Y>0)Q.defaultTimeout=Y}return Q}class E{executedHooks=new Map;canExecute(Q,Y){if(!this.executedHooks.has(Q))this.executedHooks.set(Q,new Set);if(this.executedHooks.get(Q).has(Y))return console.warn(`[HookGuard] Hook ${Y} for tool ${Q} already executed, skipping`),!1;return!0}markExecuted(Q,Y){let Z=this.executedHooks.get(Q);if(Z)Z.add(Y)}cleanup(Q){this.executedHooks.delete(Q)}cleanupAll(){this.executedHooks.clear()}}import{z as $}from"zod";var L=$.object({hook_event_name:$.nativeEnum(U),hook_execution_id:$.string(),timestamp:$.string(),project_dir:$.string(),session_id:$.string(),permission_mode:$.enum(["default","autoEdit","yolo","plan"]),_metadata:$.object({blade_version:$.string(),hook_timeout_ms:$.number()}).optional()}),u=L.extend({hook_event_name:$.literal("PreToolUse"),tool_name:$.string(),tool_use_id:$.string(),tool_input:$.record($.unknown())}),i=L.extend({hook_event_name:$.literal("PostToolUse"),tool_name:$.string(),tool_use_id:$.string(),tool_input:$.record($.unknown()),tool_response:$.unknown()}),a=L.extend({hook_event_name:$.literal("Stop"),reason:$.string().optional()}),c=L.extend({hook_event_name:$.literal("PostToolUseFailure"),tool_name:$.string(),tool_use_id:$.string(),tool_input:$.record($.unknown()),error:$.string(),error_type:$.string().optional(),is_interrupt:$.boolean(),is_timeout:$.boolean()}),s=L.extend({hook_event_name:$.literal("PermissionRequest"),tool_name:$.string(),tool_use_id:$.string(),tool_input:$.record($.unknown())}),r=L.extend({hook_event_name:$.literal("UserPromptSubmit"),user_prompt:$.string(),has_images:$.boolean(),image_count:$.number()}),n=L.extend({hook_event_name:$.literal("SessionStart"),is_resume:$.boolean(),resume_session_id:$.string().optional()}),o=L.extend({hook_event_name:$.literal("SessionEnd"),reason:$.enum(["user_exit","error","max_turns","idle_timeout","ctrl_c","clear","logout","other"])}),e=L.extend({hook_event_name:$.literal("SubagentStop"),agent_type:$.string(),task_description:$.string().optional(),success:$.boolean(),result_summary:$.string().optional(),error:$.string().optional()}),t=L.extend({hook_event_name:$.literal("Notification"),notification_type:$.enum(["permission_prompt","idle_prompt","auth_success","elicitation_dialog","info","warning","error"]),title:$.string().optional(),message:$.string()}),QQ=L.extend({hook_event_name:$.literal("Compaction"),trigger:$.enum(["manual","auto"]),messages_before:$.number(),tokens_before:$.number()}),CQ=$.discriminatedUnion("hook_event_name",[u,i,a,c,s,r,n,o,e,t,QQ]),YQ=$.object({hookEventName:$.literal("PreToolUse"),permissionDecision:$.nativeEnum(M).optional(),permissionDecisionReason:$.string().optional(),updatedInput:$.record($.unknown()).optional()}),ZQ=$.object({hookEventName:$.literal("PostToolUse"),additionalContext:$.string().optional(),updatedOutput:$.unknown().optional()}),WQ=$.object({hookEventName:$.literal("Stop"),continue:$.boolean().optional(),continueReason:$.string().optional()}),XQ=$.object({hookEventName:$.literal("SubagentStop"),continue:$.boolean().optional(),continueReason:$.string().optional(),additionalContext:$.string().optional()}),$Q=$.object({hookEventName:$.literal("PermissionRequest"),permissionDecision:$.enum(["approve","deny","ask"]).optional(),permissionDecisionReason:$.string().optional()}),qQ=$.object({hookEventName:$.literal("UserPromptSubmit"),updatedPrompt:$.string().optional(),contextInjection:$.string().optional()}),JQ=$.object({hookEventName:$.literal("SessionStart"),env:$.record($.string()).optional()}),GQ=$.object({hookEventName:$.literal("Compaction"),blockCompaction:$.boolean().optional(),blockReason:$.string().optional()}),FQ=$.object({decision:$.object({behavior:$.nativeEnum(w)}).optional(),systemMessage:$.string().optional(),hookSpecificOutput:$.discriminatedUnion("hookEventName",[YQ,ZQ,WQ,XQ,$Q,qQ,JQ,GQ]).optional(),suppressOutput:$.boolean().optional()}),KQ=$.object({type:$.literal("command"),command:$.string(),timeout:$.number().positive().optional(),statusMessage:$.string().optional()}),VQ=$.object({type:$.literal("prompt"),prompt:$.string(),model:$.string().optional(),timeout:$.number().positive().optional()}),RQ=$.discriminatedUnion("type",[KQ,VQ]),I=$.union([$.string(),$.array($.string())]),_Q=$.object({tools:I.optional(),paths:I.optional(),commands:I.optional()}),D=$.object({name:$.string().optional(),matcher:_Q.optional(),hooks:$.array(RQ)}),SQ=$.object({enabled:$.boolean().optional(),defaultTimeout:$.number().positive().optional(),timeoutBehavior:$.enum(["ignore","deny","ask"]).optional(),failureBehavior:$.enum(["ignore","deny","ask"]).optional(),maxConcurrentHooks:$.number().positive().optional(),PreToolUse:$.array(D).optional(),PostToolUse:$.array(D).optional(),PostToolUseFailure:$.array(D).optional(),PermissionRequest:$.array(D).optional(),UserPromptSubmit:$.array(D).optional(),SessionStart:$.array(D).optional(),SessionEnd:$.array(D).optional(),Stop:$.array(D).optional(),SubagentStop:$.array(D).optional(),Notification:$.array(D).optional(),Compaction:$.array(D).optional()});function k(Q){let Y=FQ.safeParse(Q);if(Y.success)return{success:!0,data:Y.data};return{success:!1,error:Y.error}}class f{parse(Q,Y,Z){if(Q.timedOut){let X=Z?.timeoutBehavior||"ignore",q="Hook timeout";if(X==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y}}let W=this.tryParseJSON(Q.stdout);if(W){let X=k(W);if(!X.success){let J="error"in X?X.error.message:"Unknown validation error",G=Z?.failureBehavior||"ignore",F=`Invalid hook output JSON: ${J}`;if(G==="deny")return{success:!1,blocking:!0,error:F,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};else if(G==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${F}. Continue?`,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};else return{success:!1,blocking:!1,warning:F,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y}}let q=X.data;if(q.decision?.behavior==="block")return{success:!1,blocking:!0,error:q.systemMessage||"Hook blocked execution",output:q,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};if(q.decision?.behavior==="async")return{success:!0,output:q,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};return{success:!0,output:q,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y}}return this.parseByExitCode(Q,Y,Z)}parseByExitCode(Q,Y,Z){let W=Q.exitCode;switch(W){case 0:return{success:!0,stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};case 2:return{success:!1,blocking:!0,error:Q.stderr||Q.stdout||"Hook returned exit code 2",stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};case 124:{let X=Z?.timeoutBehavior||"ignore",q="Hook timeout";if(X==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y}}default:{let X=Z?.failureBehavior||"ignore",q=Q.stderr||Q.stdout||`Hook failed with exit code ${W}`;if(X==="deny")return{success:!1,blocking:!0,error:q,stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};else if(X==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${q}. Continue?`,stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};else return{success:!1,blocking:!1,warning:q,stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y}}}}tryParseJSON(Q){try{let Y=Q.trim();if(!Y)return null;let Z=Y.match(/^\s*(\{[\s\S]*\})\s*$/);if(!Z)return null;return JSON.parse(Z[1])}catch{return null}}}import{spawn as DQ}from"child_process";class z{content="";maxSize;constructor(Q){this.maxSize=Q}append(Q){if(this.content.length<this.maxSize){let Y=this.maxSize-this.content.length;this.content+=Q.substring(0,Y)}}getContent(){return this.content}isFull(){return this.content.length>=this.maxSize}}class H{MAX_STDOUT_SIZE=1048576;MAX_STDERR_SIZE=1048576;MAX_INPUT_SIZE=102400;async execute(Q,Y,Z,W){let X=JSON.stringify(Y);if(X.length>this.MAX_INPUT_SIZE)throw Error(`Hook input too large: ${X.length} bytes (max ${this.MAX_INPUT_SIZE})`);let q=this.createSafeEnv(Y),J=DQ(Q,[],{shell:!0,env:q,cwd:Z.projectDir,timeout:W}),G=new z(this.MAX_STDOUT_SIZE),F=new z(this.MAX_STDERR_SIZE);J.stdout.setEncoding("utf8"),J.stderr.setEncoding("utf8"),J.stdout.on("data",(K)=>{G.append(K)}),J.stderr.on("data",(K)=>{F.append(K)});try{J.stdin.write(X),J.stdin.end()}catch(K){throw J.kill("SIGTERM"),Error(`Failed to write hook input: ${K}`)}return new Promise((K,O)=>{let R=!1,_=!1,V=null,A=()=>{if(V&&Z.abortSignal)Z.abortSignal.removeEventListener("abort",V),V=null},B=setTimeout(()=>{R=!0,J.kill("SIGKILL")},W);if(J.on("close",(b)=>{if(_)return;_=!0,clearTimeout(B),A(),K({stdout:G.getContent(),stderr:F.getContent(),exitCode:R?124:b??1,timedOut:R})}),J.on("error",(b)=>{if(_)return;_=!0,clearTimeout(B),A(),O(b)}),Z.abortSignal)V=()=>{if(_)return;_=!0,clearTimeout(B),A(),J.kill("SIGTERM"),K({stdout:G.getContent(),stderr:"Hook cancelled by abort signal",exitCode:1,timedOut:!1})},Z.abortSignal.addEventListener("abort",V)})}createSafeEnv(Q){return{BLADE_PROJECT_DIR:Q.project_dir,BLADE_SESSION_ID:Q.session_id,BLADE_HOOK_EVENT:Q.hook_event_name,BLADE_TOOL_NAME:"tool_name"in Q?Q.tool_name:"",BLADE_TOOL_USE_ID:"tool_use_id"in Q?Q.tool_use_id:"",PATH:process.env.PATH||"",HOME:process.env.HOME||"",USER:process.env.USER||"",SHELL:process.env.SHELL||"/bin/sh"}}}class P extends Error{constructor(Q){super(Q);this.name="HttpHookSecurityError"}}function h(Q,Y={}){let Z;try{Z=new URL(Q)}catch{throw new P(`Invalid URL: ${Q}`)}if(Z.protocol!=="https:"&&Z.protocol!=="http:")throw new P(`Only http/https supported, got: ${Z.protocol}`);let W=Z.hostname.toLowerCase();if(LQ(W,Y.allowedHosts))return;if(Z.protocol==="http:"&&!Y.allowHttp)throw new P(`HTTP (non-TLS) blocked for ${W}; use https:// or add to allowedHosts`);if(jQ(W)&&!Y.allowLoopback)throw new P(`Loopback address blocked: ${W}; enable policy.allowLoopback or add to allowedHosts`);if(AQ(W)&&!Y.allowPrivateRanges)throw new P(`Private/link-local address blocked: ${W}; enable policy.allowPrivateRanges or add to allowedHosts`)}function LQ(Q,Y){if(!Y||Y.length===0)return!1;return Y.some((Z)=>{let W=Z.toLowerCase();if(W===Q)return!0;if(W.startsWith("*.")){let X=W.slice(1);return Q.endsWith(X)&&Q.length>X.length}return!1})}function jQ(Q){if(Q==="localhost")return!0;if(Q==="::1"||Q==="[::1]")return!0;if(/^127\.\d+\.\d+\.\d+$/.test(Q))return!0;return!1}function AQ(Q){let Y=Q.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);if(!Y)return!1;let[Z,W]=Y.slice(1).map(Number);if(Z===10)return!0;if(Z===172&&W>=16&&W<=31)return!0;if(Z===192&&W===168)return!0;if(Z===169&&W===254)return!0;return!1}function p(Q){if(!Q)return{};let Y={};for(let[Z,W]of Object.entries(Q))Y[Z]=W.replace(/\$\{([A-Z_][A-Z0-9_]*)\}/gi,(X,q)=>{return process.env[q]??`\${${q}}`});return Y}var OQ=x("Execution"),BQ={PreToolUse:'{ "permissionDecision": "approve" | "deny" | "ask", "permissionDecisionReason": "...", "updatedInput": { ... } }',PostToolUse:'{ "additionalContext": "注入到工具结果的额外信息", "updatedOutput": "修改后的工具输出" }',Stop:'{ "continue": true, "continueReason": "继续执行的原因" } // continue: true 表示阻止停止',SubagentStop:'{ "continue": true, "continueReason": "...", "additionalContext": "..." }',PermissionRequest:'{ "permissionDecision": "approve" | "deny" | "ask", "permissionDecisionReason": "..." }',UserPromptSubmit:'{ "updatedPrompt": "修改后的提示词", "contextInjection": "注入的上下文" }',Compaction:'{ "blockCompaction": true, "blockReason": "阻止压缩的原因" }'};class v{processExecutor=new H;outputParser=new f;chatServiceCache=new Map;async executePreToolHooks(Q,Y,Z){if(Q.length===0)return{decision:"allow"};let W="tool_input"in Y?Y.tool_input:{},X=[];for(let q of Q)try{let J={...Y,...W&&{tool_input:W}},G=await this.executeHook(q,J,Z);if(!G.success){if(G.blocking)return{decision:"deny",reason:G.error};if(G.needsConfirmation)return{decision:"ask",reason:G.warning||G.error};if(G.warning)X.push(G.warning);continue}let F=G.output?.hookSpecificOutput;if(F&&"permissionDecision"in F){switch(F.permissionDecision){case"deny":return{decision:"deny",reason:F.permissionDecisionReason};case"ask":return{decision:"ask",reason:F.permissionDecisionReason};case"allow":break}if("updatedInput"in F&&F.updatedInput)W={...W,...F.updatedInput}}}catch(J){let G=J instanceof Error?J.message:String(J);if(X.push(`Hook failed: ${G}`),Z.config.failureBehavior==="deny")return{decision:"deny",reason:G};else if(Z.config.failureBehavior==="ask")return{decision:"ask",reason:`Hook failed: ${G}. Continue?`}}return{decision:"allow",modifiedInput:W,warning:X.length>0?X.join(`
2
+ `):void 0}}async executePostToolHooks(Q,Y,Z){if(Q.length===0)return{};let W=Z.config.maxConcurrentHooks||5,X=await this.executeHooksConcurrently(Q,Y,Z,W),q=[],J=void 0,G=[];for(let F of X){if(!F.success&&F.warning){G.push(F.warning);continue}let K=F.output?.hookSpecificOutput;if(K&&"additionalContext"in K){if(K.additionalContext)q.push(K.additionalContext);if("updatedOutput"in K&&K.updatedOutput!==void 0)J=K.updatedOutput}}return{additionalContext:q.length>0?q.join(`
3
+
4
+ `):void 0,modifiedOutput:J,warning:G.length>0?G.join(`
5
+ `):void 0}}async executeStopHooks(Q,Y,Z){if(Q.length===0)return{shouldStop:!0};let W=[];for(let X of Q)try{let q=await this.executeHook(X,Y,Z);if(!q.success){if(q.warning)W.push(q.warning);continue}let J=q.output?.hookSpecificOutput;if(J&&"continue"in J&&J.continue===!1)return{shouldStop:!1,continueReason:J.continueReason,warning:W.length>0?W.join(`
6
+ `):void 0}}catch(q){let J=q instanceof Error?q.message:String(q);W.push(`Hook failed: ${J}`)}return{shouldStop:!0,warning:W.length>0?W.join(`
7
+ `):void 0}}async executeSubagentStopHooks(Q,Y,Z){if(Q.length===0)return{shouldStop:!0};let W=[],X=[];for(let q of Q)try{let J=await this.executeHook(q,Y,Z);if(!J.success){if(J.warning)W.push(J.warning);continue}let G=J.output?.hookSpecificOutput;if(G&&"continue"in G){if(G.continue===!1)return{shouldStop:!1,continueReason:G.continueReason,warning:W.length>0?W.join(`
8
+ `):void 0};if("additionalContext"in G&&G.additionalContext)X.push(G.additionalContext)}}catch(J){let G=J instanceof Error?J.message:String(J);W.push(`Hook failed: ${G}`)}return{shouldStop:!0,additionalContext:X.length>0?X.join(`
9
+
10
+ `):void 0,warning:W.length>0?W.join(`
11
+ `):void 0}}async executePermissionRequestHooks(Q,Y,Z){if(Q.length===0)return{decision:"ask"};let W=[];for(let X of Q)try{let q=await this.executeHook(X,Y,Z);if(!q.success){if(q.warning)W.push(q.warning);continue}let J=q.output?.hookSpecificOutput;if(J&&"permissionDecision"in J){let G=J.permissionDecision;if(G==="approve"||G==="deny")return{decision:G,reason:J.permissionDecisionReason,warning:W.length>0?W.join(`
12
+ `):void 0}}}catch(q){let J=q instanceof Error?q.message:String(q);W.push(`Hook failed: ${J}`)}return{decision:"ask",warning:W.length>0?W.join(`
13
+ `):void 0}}async executeUserPromptSubmitHooks(Q,Y,Z){if(Q.length===0)return{proceed:!0};let W=[],X=[],q;for(let J of Q)try{let G=await this.executeHook(J,Y,Z);if(!G.success){if(G.blocking)return{proceed:!1,warning:G.error};if(G.warning)W.push(G.warning);continue}if(G.stdout&&G.stdout.trim())X.push(G.stdout.trim());let F=G.output?.hookSpecificOutput;if(F&&"updatedPrompt"in F){if(F.updatedPrompt)q=F.updatedPrompt;if(F.contextInjection)X.push(F.contextInjection)}}catch(G){let F=G instanceof Error?G.message:String(G);W.push(`Hook failed: ${F}`)}return{proceed:!0,updatedPrompt:q,contextInjection:X.length>0?X.join(`
14
+
15
+ `):void 0,warning:W.length>0?W.join(`
16
+ `):void 0}}async executeSessionStartHooks(Q,Y,Z){if(Q.length===0)return{proceed:!0};let W=[],X={};for(let q of Q)try{let J=await this.executeHook(q,Y,Z);if(!J.success){if(J.blocking)return{proceed:!1,warning:J.error};if(J.warning)W.push(J.warning);continue}let G=J.output?.hookSpecificOutput;if(G&&"env"in G&&G.env)Object.assign(X,G.env)}catch(J){let G=J instanceof Error?J.message:String(J);W.push(`Hook failed: ${G}`)}return{proceed:!0,env:Object.keys(X).length>0?X:void 0,warning:W.length>0?W.join(`
17
+ `):void 0}}async executeSessionEndHooks(Q,Y,Z){if(Q.length===0)return{};let W=[],X=Z.config.maxConcurrentHooks||5,q=await this.executeHooksConcurrently(Q,Y,Z,X);for(let J of q)if(!J.success&&J.warning)W.push(J.warning);return{warning:W.length>0?W.join(`
18
+ `):void 0}}async executePostToolUseFailureHooks(Q,Y,Z){if(Q.length===0)return{};let W=[],X=[],q=Z.config.maxConcurrentHooks||5,J=await this.executeHooksConcurrently(Q,Y,Z,q);for(let G of J){if(!G.success&&G.warning){W.push(G.warning);continue}if(G.stdout&&G.stdout.trim())X.push(G.stdout.trim())}return{additionalContext:X.length>0?X.join(`
19
+
20
+ `):void 0,warning:W.length>0?W.join(`
21
+ `):void 0}}async executeNotificationHooks(Q,Y,Z){let W="message"in Y?Y.message:"";if(Q.length===0)return{suppress:!1,message:W};let X=[],q=!1,J=W;for(let G of Q)try{let F=await this.executeHook(G,Y,Z);if(!F.success){if(F.warning)X.push(F.warning);continue}if(F.output?.suppressOutput){q=!0;break}if(F.stdout&&F.stdout.trim())J=F.stdout.trim()}catch(F){let K=F instanceof Error?F.message:String(F);X.push(`Hook failed: ${K}`)}return{suppress:q,message:J,warning:X.length>0?X.join(`
22
+ `):void 0}}async executeCompactionHooks(Q,Y,Z){if(Q.length===0)return{blockCompaction:!1};let W=[];for(let X of Q)try{let q=await this.executeHook(X,Y,Z);if(!q.success){if(q.warning)W.push(q.warning);continue}let J=q.output?.hookSpecificOutput;if(J&&"blockCompaction"in J&&J.blockCompaction)return{blockCompaction:!0,blockReason:J.blockReason,warning:W.length>0?W.join(`
23
+ `):void 0}}catch(q){let J=q instanceof Error?q.message:String(q);W.push(`Hook failed: ${J}`)}return{blockCompaction:!1,warning:W.length>0?W.join(`
24
+ `):void 0}}async executeHook(Q,Y,Z){if(Q.type==="command")return this.executeCommandHook(Q,Y,Z);if(Q.type==="prompt")return this.executePromptHook(Q,Y,Z);if(Q.type==="function")return this.executeFunctionHook(Q,Y,Z);if(Q.type==="http")return this.executeHttpHook(Q,Y,Z);throw Error(`Hook type ${Q.type} not supported`)}async executeCommandHook(Q,Y,Z){let W=(Q.timeout??Z.config.defaultTimeout??60)*1000;try{let X=await this.processExecutor.execute(Q.command,Y,Z,W);return this.outputParser.parse(X,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch(X){return{success:!1,blocking:!1,error:X instanceof Error?X.message:String(X),hook:Q}}}async executePromptHook(Q,Y,Z){let W=(Q.timeout??Z.config.defaultTimeout??60)*1000;try{let X=await this.getOrCreateChatService(Q.model),q="hook_event_name"in Y?String(Y.hook_event_name):"Unknown",J=this.buildPromptHookSystemMessage(Q,q),G=JSON.stringify(Y,null,2),F=new AbortController,K=setTimeout(()=>F.abort(),W),O;try{O=(await X.chat([{role:"system",content:J},{role:"user",content:G}],void 0,F.signal)).content}catch(_){if(F.signal.aborted||_ instanceof Error&&_.name==="AbortError")return this.outputParser.parse({stdout:"",stderr:"",exitCode:0,timedOut:!0},Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior});throw _}finally{clearTimeout(K)}let R=this.extractJsonFromLLMResponse(O);return this.outputParser.parse({stdout:R,stderr:"",exitCode:0,timedOut:!1},Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch(X){return OQ.warn(`[PromptHook] 执行失败: ${X instanceof Error?X.message:String(X)}`),{success:!1,blocking:!1,error:X instanceof Error?X.message:String(X),hook:Q}}}async executeFunctionHook(Q,Y,Z){let W=(Q.timeout??10)*1000;try{let X=await this.runFunctionWithTimeout(Q.handler,Y,Z,W);if(X===void 0||X===null)return{success:!0,hook:Q};let q={stdout:JSON.stringify(X),stderr:"",exitCode:0,timedOut:!1};return this.outputParser.parse(q,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch(X){if(X.isTimeout){let q={stdout:"",stderr:`Function hook timeout after ${W}ms`,exitCode:124,timedOut:!0};return this.outputParser.parse(q,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}return{success:!1,blocking:!1,error:X instanceof Error?X.message:String(X),hook:Q}}}runFunctionWithTimeout(Q,Y,Z,W){return new Promise((X,q)=>{let J=!1,G=setTimeout(()=>{if(J)return;J=!0;let K=Object.assign(Error(`Function hook timed out after ${W}ms`),{isTimeout:!0});q(K)},W),F=()=>{if(J)return;J=!0,clearTimeout(G),q(Error("Function hook aborted"))};Z.abortSignal?.addEventListener("abort",F,{once:!0}),Promise.resolve().then(()=>Q(Y,Z)).then((K)=>{if(J)return;J=!0,clearTimeout(G),Z.abortSignal?.removeEventListener("abort",F),X(K)},(K)=>{if(J)return;J=!0,clearTimeout(G),Z.abortSignal?.removeEventListener("abort",F),q(K)})})}async executeHttpHook(Q,Y,Z){let W=(Q.timeout??10)*1000,X=Q.maxResponseBytes??262144,q=Math.max(1,(Q.retries??0)+1);try{h(Q.url,Z.config.httpPolicy)}catch(K){return{success:!1,blocking:!0,error:K instanceof Error?K.message:String(K),hook:Q}}let J={"Content-Type":"application/json",...p(Q.headers)},G=JSON.stringify(Y),F;for(let K=0;K<q;K++){if(K>0){let V=Math.min(2**K*200,5000);await new Promise((A)=>setTimeout(A,V))}let O=new AbortController,R=setTimeout(()=>O.abort(),W),_=()=>O.abort();Z.abortSignal?.addEventListener("abort",_,{once:!0});try{let V=await fetch(Q.url,{method:"POST",headers:J,body:G,redirect:"manual",signal:O.signal});if(V.status>=300&&V.status<400){F=Error(`HTTP hook received redirect (${V.status}); redirects are disabled`);continue}if(!V.ok){if(F=Error(`HTTP hook returned ${V.status} ${V.statusText}`),V.status>=400&&V.status<500)break;continue}let B={stdout:await PQ(V,X),stderr:"",exitCode:0,timedOut:!1};return this.outputParser.parse(B,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch(V){let A=V.name==="AbortError"||V.code==="ABORT_ERR";if(A&&Z.abortSignal?.aborted){F=Error("HTTP hook aborted by caller");break}if(A){let B={stdout:"",stderr:`HTTP hook timeout after ${W}ms`,exitCode:124,timedOut:!0};if(K===q-1)return this.outputParser.parse(B,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior});F=Error(`HTTP hook timeout attempt ${K+1}`);continue}F=V}finally{clearTimeout(R),Z.abortSignal?.removeEventListener("abort",_)}}return{success:!1,blocking:!1,error:F?.message??"HTTP hook failed",hook:Q}}async getOrCreateChatService(Q){let Y=Q||"__default__",Z=this.chatServiceCache.get(Y);if(Z)return Z;let{ensureStoreInitialized:W,getCurrentModel:X,getModelById:q}=await import("./chunk-420vamtq.js"),{createChatServiceAsync:J}=await import("./chunk-52k9k0w8.js");await W();let G=Q?q(Q)||X():X();if(!G)throw Error("PromptHook: 无法获取模型配置。请确保至少配置了一个模型。");let F=await J({provider:G.provider,apiKey:G.apiKey,baseUrl:G.baseUrl,model:G.model,temperature:G.temperature,maxContextTokens:G.maxContextTokens,maxOutputTokens:G.maxOutputTokens});return this.chatServiceCache.set(Y,F),F}buildPromptHookSystemMessage(Q,Y){let Z=BQ[Y]||"{ ... 根据事件类型返回相应字段 }";return`你是一个代码质量评估器,作为 Hook 在 ${Y} 事件中被触发。
25
+
26
+ `+`## 评估指令
27
+ ${Q.prompt}
28
+
29
+ `+`## 输出格式
30
+ `+`必须返回一个 JSON 对象(不要包含任何其他文本):
31
+ `+`{
32
+ "decision": { "behavior": "approve" | "block" },
33
+ `+` "systemMessage": "可选的说明信息",
34
+ `+` "hookSpecificOutput": ${Z}
35
+ }
36
+
37
+ `+`重要规则:
38
+ `+`- 只输出 JSON,不要包含 markdown 代码块或其他文本
39
+ `+`- 如果没有发现问题,使用 "approve"
40
+ `+'- 只在发现严重问题时使用 "block"'}extractJsonFromLLMResponse(Q){let Y=Q.trim(),Z=Y.match(/^```(?:json)?\s*\n?([\s\S]*?)\n?\s*```$/);if(Z)return Z[1].trim();return Y}async executeHooksConcurrently(Q,Y,Z,W){let X=[],q=new Set;for(let J of Q){if(q.size>=W)await Promise.race(q);let G=this.executeHook(J,Y,Z).catch((K)=>({success:!1,blocking:!1,error:K instanceof Error?K.message:String(K),hook:J})),F=G.then(()=>{q.delete(F)}).catch(()=>{q.delete(F)});q.add(F),X.push(G)}return Promise.all(X)}}async function PQ(Q,Y){let Z=Q.body?.getReader();if(!Z)return"";let W=new TextDecoder,X=0,q="";while(!0){let{value:J,done:G}=await Z.read();if(G)break;if(X+=J.byteLength,X>Y){try{Z.cancel()}catch{}q+=W.decode(J.slice(0,Y-(X-J.byteLength)));break}q+=W.decode(J,{stream:!0})}return q+=W.decode(),q}import g from"picomatch";var TQ=/^([A-Za-z0-9_|]+)\((.+)\)$/;class d{matches(Q,Y){if(!Q)return!0;if(Q.tools&&Y.toolName){if(!this.matchTools(Q.tools,Y))return!1}if(Q.paths&&Y.filePath){if(!this.matchPaths(Q.paths,Y.filePath))return!1}if(Q.commands&&Y.command){if(!this.matchCommands(Q.commands,Y.command))return!1}return!0}matchTools(Q,Y){if(Array.isArray(Q))return Q.some((Z)=>this.matchToolWithParams(Z,Y));return this.matchToolWithParams(Q,Y)}matchPaths(Q,Y){if(Array.isArray(Q))return Q.some((W)=>{return g(W)(Y)});return g(Q)(Y)}matchCommands(Q,Y){if(Array.isArray(Q))return Q.some((Z)=>this.matchPattern(Y,Z));return this.matchPattern(Y,Q)}matchToolWithParams(Q,Y){let{toolName:Z,command:W,filePath:X}=Y,q=TQ.exec(Q);if(!q)return this.matchPattern(Z,Q);let[,J,G]=q;if(!this.matchPattern(Z,J))return!1;let F=this.getArgValue(Z,W,X);if(!F)return!1;return this.matchGlobOrPattern(F,G)}getArgValue(Q,Y,Z){if(Q==="Bash"||Q==="BashTool")return Y;if(["Read","Edit","Write","Glob","Grep"].includes(Q))return Z;return Y||Z}matchGlobOrPattern(Q,Y){if(/[*?[\]{}!]/.test(Y))try{return g(Y,{bash:!0,dot:!0})(Q)}catch{}if(Y.endsWith("*")){let Z=Y.slice(0,-1);return Q.startsWith(Z)}return Q===Y}matchPattern(Q,Y){if(Y==="*")return!0;if(!Y.includes("|")&&!/[.*+?^${}()|[\]\\]/.test(Y))return Q===Y;if(Y.includes("|"))return Y.split("|").map((W)=>W.trim()).includes(Q);try{return new RegExp(Y).test(Q)}catch{return Q===Y}}}class T{static instance=null;config=C;executor=new v;guard=new E;matcher=new d;sessionDisabled=!1;constructor(){}static getInstance(){if(!T.instance)T.instance=new T;return T.instance}loadConfig(Q){let Y=S(C,Q),Z=m();Y=S(Y,Z),this.config=Y}isEnabled(){if(!this.config.enabled)return!1;if(this.sessionDisabled)return!1;return!0}disable(){this.sessionDisabled=!0,console.log("[HookManager] Hooks disabled for this session")}enable(){this.sessionDisabled=!1,console.log("[HookManager] Hooks enabled for this session")}getConfig(){return this.config}registerFunction(Q,Y,Z,W){let X={type:"function",handler:Z,timeout:W?.timeout},q={name:W?.name??`inline-${Q}-${Date.now()}`,matcher:Y,hooks:[X]},J=this.config[Q]??[];return this.config[Q]=[...J,q],()=>{let G=this.config[Q];if(!G)return;this.config[Q]=G.filter((F)=>F!==q)}}async reloadConfig(){let Q=await import("node:fs/promises"),Y=await import("node:path");try{let Z=Y.join(l(),".blade","settings.local.json"),W=await Q.readFile(Z,"utf-8"),X=JSON.parse(W);if(X.hooks)this.loadConfig(X.hooks)}catch{}}async executePreToolHooks(Q,Y,Z,W){if(!this.isEnabled())return{decision:"allow"};if(W.permissionMode==="plan")return{decision:"allow"};if(!this.guard.canExecute(Y,"PreToolUse"))return{decision:"allow"};let X={hook_event_name:"PreToolUse",hook_execution_id:j(),timestamp:new Date().toISOString(),tool_name:Q,tool_use_id:Y,tool_input:Z,project_dir:W.projectDir,session_id:W.sessionId,permission_mode:W.permissionMode},q=this.getMatchingHooks("PreToolUse",{toolName:Q,filePath:this.extractFilePath(Z),command:this.extractCommand(Q,Z)});if(q.length===0)return{decision:"allow"};let J={projectDir:W.projectDir,sessionId:W.sessionId,permissionMode:W.permissionMode,config:this.config,abortSignal:W.abortSignal};try{let G=await this.executor.executePreToolHooks(q,X,J);if(this.guard.markExecuted(Y,"PreToolUse"),W.permissionMode==="yolo"){if(G.decision==="deny")return G;return{decision:"allow",modifiedInput:G.modifiedInput,warning:G.warning,reason:G.reason}}return G}catch(G){return console.error("[HookManager] Error executing PreToolUse hooks:",G),{decision:"allow",warning:`Hook execution failed: ${G instanceof Error?G.message:String(G)}`}}}async executePostToolHooks(Q,Y,Z,W,X){if(!this.isEnabled())return{};if(X.permissionMode==="plan")return{};if(!this.guard.canExecute(Y,"PostToolUse"))return{};let q={hook_event_name:"PostToolUse",hook_execution_id:j(),timestamp:new Date().toISOString(),tool_name:Q,tool_use_id:Y,tool_input:Z,tool_response:W,project_dir:X.projectDir,session_id:X.sessionId,permission_mode:X.permissionMode},J=this.getMatchingHooks("PostToolUse",{toolName:Q,filePath:this.extractFilePath(Z),command:this.extractCommand(Q,Z)});if(J.length===0)return{};let G={projectDir:X.projectDir,sessionId:X.sessionId,permissionMode:X.permissionMode,config:this.config,abortSignal:X.abortSignal};try{let F=await this.executor.executePostToolHooks(J,q,G);return this.guard.markExecuted(Y,"PostToolUse"),F}catch(F){return console.error("[HookManager] Error executing PostToolUse hooks:",F),{warning:`Hook execution failed: ${F instanceof Error?F.message:String(F)}`}}finally{this.guard.cleanup(Y)}}async executeStopHooks(Q){if(!this.isEnabled())return{shouldStop:!0};let Y={hook_event_name:"Stop",hook_execution_id:j(),timestamp:new Date().toISOString(),project_dir:Q.projectDir,session_id:Q.sessionId,permission_mode:Q.permissionMode,reason:Q.reason},Z=this.getMatchingHooks("Stop",{});if(Z.length===0)return{shouldStop:!0};let W={projectDir:Q.projectDir,sessionId:Q.sessionId,permissionMode:Q.permissionMode,config:this.config,abortSignal:Q.abortSignal};try{return await this.executor.executeStopHooks(Z,Y,W)}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(Q,Y){if(!this.isEnabled())return{shouldStop:!0};let Z={hook_event_name:"SubagentStop",hook_execution_id:j(),timestamp:new Date().toISOString(),project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode,agent_type:Q,task_description:Y.taskDescription,success:Y.success,result_summary:Y.resultSummary,error:Y.error},W=this.getMatchingHooks("SubagentStop",{});if(W.length===0)return{shouldStop:!0};let X={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:this.config,abortSignal:Y.abortSignal};try{return await this.executor.executeSubagentStopHooks(W,Z,X)}catch(q){return console.error("[HookManager] Error executing SubagentStop hooks:",q),{shouldStop:!0,warning:`Hook execution failed: ${q instanceof Error?q.message:String(q)}`}}}async executePermissionRequestHooks(Q,Y,Z,W){if(!this.isEnabled())return{decision:"ask"};let X={hook_event_name:"PermissionRequest",hook_execution_id:j(),timestamp:new Date().toISOString(),tool_name:Q,tool_use_id:Y,tool_input:Z,project_dir:W.projectDir,session_id:W.sessionId,permission_mode:W.permissionMode},q=this.getMatchingHooks("PermissionRequest",{toolName:Q,filePath:this.extractFilePath(Z),command:this.extractCommand(Q,Z)});if(q.length===0)return{decision:"ask"};let J={projectDir:W.projectDir,sessionId:W.sessionId,permissionMode:W.permissionMode,config:this.config,abortSignal:W.abortSignal};try{return await this.executor.executePermissionRequestHooks(q,X,J)}catch(G){return console.error("[HookManager] Error executing PermissionRequest hooks:",G),{decision:"ask",warning:`Hook execution failed: ${G instanceof Error?G.message:String(G)}`}}}async executeUserPromptSubmitHooks(Q,Y){if(!this.isEnabled())return{proceed:!0};let Z={hook_event_name:"UserPromptSubmit",hook_execution_id:j(),timestamp:new Date().toISOString(),user_prompt:Q,has_images:Y.hasImages,image_count:Y.imageCount,project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode},W=this.getMatchingHooks("UserPromptSubmit",{});if(W.length===0)return{proceed:!0};let X={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:this.config,abortSignal:Y.abortSignal};try{return await this.executor.executeUserPromptSubmitHooks(W,Z,X)}catch(q){return console.error("[HookManager] Error executing UserPromptSubmit hooks:",q),{proceed:!0,warning:`Hook execution failed: ${q instanceof Error?q.message:String(q)}`}}}async executeSessionStartHooks(Q){if(!this.isEnabled())return{proceed:!0};let Y={hook_event_name:"SessionStart",hook_execution_id:j(),timestamp:new Date().toISOString(),project_dir:Q.projectDir,session_id:Q.sessionId,permission_mode:Q.permissionMode,is_resume:Q.isResume,resume_session_id:Q.resumeSessionId},Z=this.getMatchingHooks("SessionStart",{});if(Z.length===0)return{proceed:!0};let W={projectDir:Q.projectDir,sessionId:Q.sessionId,permissionMode:Q.permissionMode,config:this.config,abortSignal:Q.abortSignal};try{return await this.executor.executeSessionStartHooks(Z,Y,W)}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(Q,Y){if(!this.isEnabled())return{};let Z={hook_event_name:"SessionEnd",hook_execution_id:j(),timestamp:new Date().toISOString(),project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode,reason:Q},W=this.getMatchingHooks("SessionEnd",{});if(W.length===0)return{};let X={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:this.config,abortSignal:Y.abortSignal};try{return await this.executor.executeSessionEndHooks(W,Z,X),{}}catch(q){return console.error("[HookManager] Error executing SessionEnd hooks:",q),{warning:`Hook execution failed: ${q instanceof Error?q.message:String(q)}`}}}async executePostToolUseFailureHooks(Q,Y,Z,W,X){if(!this.isEnabled())return{};let q={hook_event_name:"PostToolUseFailure",hook_execution_id:j(),timestamp:new Date().toISOString(),tool_name:Q,tool_use_id:Y,tool_input:Z,error:W,error_type:X.errorType,is_interrupt:X.isInterrupt,is_timeout:X.isTimeout,project_dir:X.projectDir,session_id:X.sessionId,permission_mode:X.permissionMode},J=this.getMatchingHooks("PostToolUseFailure",{toolName:Q,filePath:this.extractFilePath(Z),command:this.extractCommand(Q,Z)});if(J.length===0)return{};let G={projectDir:X.projectDir,sessionId:X.sessionId,permissionMode:X.permissionMode,config:this.config,abortSignal:X.abortSignal};try{return await this.executor.executePostToolUseFailureHooks(J,q,G)}catch(F){return console.error("[HookManager] Error executing PostToolUseFailure hooks:",F),{warning:`Hook execution failed: ${F instanceof Error?F.message:String(F)}`}}}async executeNotificationHooks(Q,Y,Z){if(!this.isEnabled())return{suppress:!1,message:Y};let W={hook_event_name:"Notification",hook_execution_id:j(),timestamp:new Date().toISOString(),project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode,notification_type:Q,title:Z.title,message:Y},X=this.getMatchingHooks("Notification",{});if(X.length===0)return{suppress:!1,message:Y};let q={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:this.config,abortSignal:Z.abortSignal};try{return await this.executor.executeNotificationHooks(X,W,q)}catch(J){return console.error("[HookManager] Error executing Notification hooks:",J),{suppress:!1,message:Y,warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executeCompactionHooks(Q,Y){if(!this.isEnabled())return{blockCompaction:!1};let Z={hook_event_name:"Compaction",hook_execution_id:j(),timestamp:new Date().toISOString(),project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode,trigger:Q,messages_before:Y.messagesBefore,tokens_before:Y.tokensBefore},W=this.getMatchingHooks("Compaction",{});if(W.length===0)return{blockCompaction:!1};let X={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:this.config,abortSignal:Y.abortSignal};try{return await this.executor.executeCompactionHooks(W,Z,X)}catch(q){return console.error("[HookManager] Error executing Compaction hooks:",q),{blockCompaction:!1,warning:`Hook execution failed: ${q instanceof Error?q.message:String(q)}`}}}getMatchingHooks(Q,Y){let Z=this.config[Q]||[],W=[];for(let X of Z)if(this.matcher.matches(X.matcher,Y))W.push(...X.hooks);return W}extractFilePath(Q){let Y=["file_path","path","filePath","source","target"];for(let Z of Y){let W=Q[Z];if(typeof W==="string")return W}return}extractCommand(Q,Y){if(Q==="Bash"||Q==="BashTool"){let Z=Y.command;if(typeof Z==="string")return Z}return}cleanup(){this.guard.cleanupAll()}}
41
+ export{U as mb,T as nb};
@@ -0,0 +1,2 @@
1
+ import{ba as d,da as h}from"./chunk-phzbecpx.js";var q={debug:{alias:"d",type:"string",describe:'Enable debug mode with optional category filtering (e.g., "agent,ui" or "!chat,!loop")',group:"Debug Options:"},model:{type:"string",describe:"Override the current run model using a model config ID (TUI / print / headless)",group:"AI Options:"},print:{alias:"p",type:"boolean",describe:"Print response and exit (useful for pipes)",group:"Output Options:"},headless:{type:"boolean",describe:"Run full agent loop without Ink UI and print all events to the terminal",group:"Output Options:"},"output-format":{alias:["outputFormat"],type:"string",choices:["text","json","stream-json","jsonl"],default:"text",describe:"Output format: --print supports text|json|stream-json; --headless supports text|jsonl",group:"Output Options:"},"include-partial-messages":{alias:["includePartialMessages"],type:"boolean",describe:"Include partial message chunks as they arrive",group:"Output Options:"},"input-format":{alias:["inputFormat"],type:"string",choices:["text","stream-json"],default:"text",describe:"Input format",group:"Input Options:"},"replay-user-messages":{alias:["replayUserMessages"],type:"boolean",describe:"Re-emit user messages from stdin",group:"Input Options:"},"allowed-tools":{alias:["allowedTools"],type:"array",string:!0,describe:"Comma or space-separated list of tool names to allow",group:"Security Options:"},"disallowed-tools":{alias:["disallowedTools"],type:"array",string:!0,describe:"Comma or space-separated list of tool names to deny",group:"Security Options:"},"mcp-config":{alias:["mcpConfig"],type:"array",string:!0,describe:"Load MCP servers from JSON files or strings",group:"MCP Options:"},"system-prompt":{alias:["systemPrompt"],type:"string",describe:"System prompt to use for the session (replaces default)",group:"AI Options:"},"append-system-prompt":{alias:["appendSystemPrompt"],type:"string",describe:"Append a system prompt to the default system prompt",group:"AI Options:"},"max-turns":{alias:["maxTurns"],type:"number",describe:"Maximum conversation turns (-1: unlimited, 0: disable chat, N>0: limit to N turns)",group:"AI Options:",default:void 0},"permission-mode":{alias:["permissionMode"],type:"string",choices:["default","autoEdit","yolo","plan"],describe:"Permission mode (default: ask for non-read tools, autoEdit: auto-approve edits, yolo: auto-approve all, plan: reserved)",group:"Security Options:"},yolo:{type:"boolean",describe:"Auto-approve all tools (shortcut for --permission-mode=yolo)",group:"Security Options:"},continue:{alias:"c",type:"boolean",describe:"Continue the most recent conversation",group:"Session Options:"},resume:{alias:"r",describe:"Resume a conversation - provide a session ID or interactively select a conversation to resume",group:"Session Options:",coerce:(b)=>{if(b===void 0||b===!0||b==="")return"true";return String(b)}},"fork-session":{alias:["forkSession"],type:"boolean",describe:"Create a new session ID when resuming",group:"Session Options:"},settings:{type:"string",describe:"Path to a settings JSON file or JSON string",group:"Configuration:"},"add-dir":{alias:["addDir"],type:"array",string:!0,describe:"Additional directories to allow tool access to",group:"Security Options:"},ide:{type:"boolean",describe:"Automatically connect to IDE on startup",group:"Integration:"},acp:{type:"boolean",describe:"Run in ACP (Agent Client Protocol) mode for IDE integration",group:"Integration:"},"strict-mcp-config":{alias:["strictMcpConfig"],type:"boolean",describe:"Only use MCP servers from --mcp-config",group:"MCP Options:"},"session-id":{alias:["sessionId"],type:"string",describe:"Use a specific session ID for the conversation",group:"Session Options:"},agents:{type:"string",describe:"JSON object defining custom agents",group:"AI Options:"},"setting-sources":{alias:["settingSources"],type:"string",describe:"Comma-separated list of setting sources to load",group:"Configuration:"},"plugin-dir":{alias:["pluginDir"],type:"array",string:!0,describe:"Load plugins from specified directories",group:"Plugin Options:"}},w={scriptName:"blade",usage:"$0 [command] [options]",description:h(),version:d(),locale:"en",showHelpOnFail:!0,demandCommand:!1,recommendCommands:!0,strict:!1};
2
+ export{q as t,w as u};
@@ -0,0 +1 @@
1
+ import{Aa as g,Ba as h,Ca as i,Da as j,Ea as k,Fa as l,Ga as m,ua as a,va as b,wa as c,xa as d,ya as e,za as f}from"./chunk-76emdpxa.js";import"./chunk-y5g06jmk.js";import"./chunk-7ycmx7c2.js";import"./chunk-set7v1rf.js";import"./chunk-j2ag7hh6.js";export{a as vanillaStore,c as sessionActions,l as getThinkingModeEnabled,b as getState,j as getModelById,e as getMessages,k as getMcpServers,i as getCurrentModel,f as getConfig,h as getAllModels,g as ensureStoreInitialized,m as configActions,d as appActions};
@@ -0,0 +1 @@
1
+ import{rb as a}from"./chunk-5mtjqqav.js";import"./chunk-set7v1rf.js";import"./chunk-j2ag7hh6.js";export{a as createChatServiceAsync};
@@ -0,0 +1,8 @@
1
+ import{Bb as R}from"./chunk-set7v1rf.js";var C=["anthropic","openai","deepseek","google-generative-ai","groq","openrouter"],b={anthropic:"",openai:"","google-generative-ai":"",deepseek:"",groq:"",openrouter:"",azure:"",ollama:"",together:"",fireworks:"",mistral:"",cohere:"",perplexity:"",xai:"",default:""},f={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"},h={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"}},V=(F)=>{return h[F]||{}};import{createAnthropic as A}from"@ai-sdk/anthropic";import{createAzure as E}from"@ai-sdk/azure";import{createDeepSeek as k}from"@ai-sdk/deepseek";import{createGoogleGenerativeAI as P}from"@ai-sdk/google";import{createOpenAI as x}from"@ai-sdk/openai";import{createOpenAICompatible as z}from"@ai-sdk/openai-compatible";import{generateText as H,jsonSchema as T,streamText as K}from"ai";var B=R("Chat");function O(F){let q=new Set;for(let W of F)if(W.role==="assistant"&&W.tool_calls)for(let Q of W.tool_calls)q.add(Q.id);return F.filter((W)=>{if(W.role==="tool"){if(!W.tool_call_id)return!1;return q.has(W.tool_call_id)}return!0})}function N(F){if(typeof F==="string")return F;return F.filter((q)=>q.type==="text").map((q)=>q.text).join(`
2
+ `)}function L(F){let q=F;return q.text??q.textDelta??q.delta}function U(F,q={}){try{return JSON.parse(F)}catch{return B.warn("[VercelAIChatService] Failed to parse JSON, using fallback",{str:F}),q}}class D{model;config;constructor(F){this.config=F,this.model=this.createModel(F),B.debug("[VercelAIChatService] Initialized",{provider:F.provider,model:F.model})}createModel(F){let{provider:q,apiKey:W,baseUrl:Q,model:X,customHeaders:Z,apiVersion:$}=F;switch(q){case"openai":return x({apiKey:W,baseURL:Q||void 0,headers:Z})(X);case"anthropic":return A({apiKey:W,baseURL:Q||void 0,headers:Z})(X);case"gemini":{if(Q&&!this.isGeminiOfficialUrl(Q))return z({name:"gemini",apiKey:W,baseURL:Q,headers:Z})(X);return P({apiKey:W,baseURL:Q||void 0})(X)}case"google":case"google-generative-ai":case"google-vertex":{if(Q&&!this.isGeminiOfficialUrl(Q))return z({name:q,apiKey:W,baseURL:Q,headers:Z})(X);return P({apiKey:W,baseURL:Q||void 0})(X)}case"azure-openai":{let Y=this.extractAzureResourceName(Q);if(Y)return E({apiKey:W,resourceName:Y,apiVersion:$||"2024-08-01-preview"})(X);let J=this.buildAzureBaseUrl(Q,X);return z({name:"azure-openai",apiKey:W,baseURL:J,headers:{...Z,"api-key":W},queryParams:{"api-version":$||"2024-08-01-preview"}})(X)}case"azure":{let Y=this.extractAzureResourceName(Q);if(Y)return E({apiKey:W,resourceName:Y,apiVersion:$||"2024-08-01-preview"})(X);let J=this.buildAzureBaseUrl(Q,X);return z({name:"azure-openai",apiKey:W,baseURL:J,headers:{...Z,"api-key":W},queryParams:{"api-version":$||"2024-08-01-preview"}})(X)}case"deepseek":return k({apiKey:W,baseURL:Q||void 0,headers:Z})(X);default:return z({name:q,apiKey:W,baseURL:Q,headers:Z})(X)}}extractAzureResourceName(F){if(!F)return;let q=F.match(/https:\/\/([^.]+)\.openai\.azure(?:\.com|\.us|\.cn|\.de)/);return q?q[1]:void 0}buildAzureBaseUrl(F,q){if(!F)return"";let W=F.replace(/\/$/,"").replace(/\?.*$/,"");if(W.includes("/openai/deployments/"))return W;return`${W}/openai/deployments/${q}`}isGeminiOfficialUrl(F){return F.includes("generativelanguage.googleapis.com")||F.includes("aiplatform.googleapis.com")}needsThinkingReplayMetadata(){return/deepseek/i.test([this.config.provider,this.config.model,this.config.baseUrl].join(" "))}getThinkingReplayProviderOptions(F){let q=F?.trim();if(!q||!this.needsThinkingReplayMetadata())return;return{openaiCompatible:{reasoning_content:q}}}shouldFlattenDeepSeekThinkingToolHistory(){return this.needsThinkingReplayMetadata()}flattenDeepSeekThinkingToolHistory(F){let q=[],W,Q=()=>{if(!W)return;q.push({role:"assistant",content:N(W.content).trim()||"I will use the requested tool and continue from its result."}),W=void 0};for(let X of F){if(X.role==="system"){Q(),q.push({role:"user",content:`<system>
3
+ ${N(X.content)}
4
+ </system>`});continue}if(X.role==="assistant"&&X.tool_calls&&X.tool_calls.length>0&&X.reasoningContent?.trim()){Q(),W=X;continue}if(X.role==="tool"&&W){let Z=W.tool_calls?.find((Y)=>Y.id===X.tool_call_id),$=Z?.type==="function"?Z.function:void 0;q.push({role:"user",content:`Tool result for ${X.name||$?.name||"tool"}${$?.arguments?`(${$.arguments})`:""}:
5
+ ${N(X.content)}
6
+
7
+ Continue from this tool result.`});continue}Q(),q.push(X)}return Q(),q}convertMessages(F){let q=[],W=this.shouldFlattenDeepSeekThinkingToolHistory()?this.flattenDeepSeekThinkingToolHistory(F):F;for(let Q of W)if(Q.role==="system")if(Array.isArray(Q.content)){let X=Q.content.find(($)=>$.type==="text"),Z={role:"system",content:N(Q.content)};if(X?.providerOptions)Z.providerOptions=X.providerOptions;q.push(Z)}else q.push({role:"system",content:Q.content});else if(Q.role==="user")if(Array.isArray(Q.content)){let X=Q.content.map((Z)=>{if(Z.type==="text"){let $={type:"text",text:Z.text};if(Z.providerOptions)$.providerOptions=Z.providerOptions;return $}return{type:"image",image:Z.image_url.url}});q.push({role:"user",content:X})}else q.push({role:"user",content:Q.content});else if(Q.role==="assistant")if(Q.tool_calls&&Q.tool_calls.length>0){let X=Q.tool_calls.map((J)=>{let j=J.function;return{type:"tool-call",toolCallId:J.id,toolName:j?.name||"",input:U(j?.arguments||"{}",{})}}),Z=N(Q.content),$=Q.reasoningContent?.trim()?[{type:"reasoning",text:Q.reasoningContent}]:[],Y=this.getThinkingReplayProviderOptions(Q.reasoningContent);if(Z){let J={role:"assistant",content:[...$,{type:"text",text:Z},...X]};if(Y)J.providerOptions=Y;q.push(J)}else if($.length>0){let J={role:"assistant",content:[...$,...X]};if(Y)J.providerOptions=Y;q.push(J)}else q.push({role:"assistant",content:X})}else if(Q.reasoningContent?.trim()){let X=N(Q.content),Z=[{type:"reasoning",text:Q.reasoningContent}];if(X)Z.push({type:"text",text:X});let $={role:"assistant",content:Z},Y=this.getThinkingReplayProviderOptions(Q.reasoningContent);if(Y)$.providerOptions=Y;q.push($)}else q.push({role:"assistant",content:N(Q.content)});else if(Q.role==="tool")q.push({role:"tool",content:[{type:"tool-result",toolCallId:Q.tool_call_id,toolName:Q.name||"unknown",output:{type:"text",value:N(Q.content)}}]});return q}convertTools(F){if(!F||F.length===0)return;let q={};for(let W of F)q[W.name]={description:W.description,inputSchema:T(W.parameters)};return q}convertToolCalls(F){return F.map((q)=>({id:q.toolCallId,type:"function",function:{name:q.toolName,arguments:JSON.stringify(q.args??q.input??{})}}))}convertUsage(F,q){if(!F)return;let W=F.promptTokens??F.inputTokens??0,Q=F.completionTokens??F.outputTokens??0,X={promptTokens:W,completionTokens:Q,totalTokens:F.totalTokens??W+Q};if(q?.anthropic){if(q.anthropic.cacheCreationInputTokens!==void 0)X.cacheCreationInputTokens=q.anthropic.cacheCreationInputTokens;if(q.anthropic.cacheReadInputTokens!==void 0)X.cacheReadInputTokens=q.anthropic.cacheReadInputTokens}return X}isFallbackableError(F){if(!(F instanceof Error))return!1;let W=F.message.toLowerCase().match(/status[:\s]*(\d{3})/),Q=W?parseInt(W[1],10):F.status;return Q!==void 0&&[429,529,503].includes(Q)}async chat(F,q,W){let Q=Date.now();B.debug("[VercelAIChatService] Starting chat request");let X=O(F),Z=this.convertMessages(X),$=this.convertTools(q);try{let Y=await H({model:this.model,messages:Z,tools:$,maxOutputTokens:this.config.maxOutputTokens,temperature:this.config.temperature??0,abortSignal:W,...{allowSystemInMessages:!0}}),J=Date.now()-Q;B.debug("[VercelAIChatService] Response received in",J,"ms");let j=Y.toolCalls&&Y.toolCalls.length>0?this.convertToolCalls(Y.toolCalls):void 0,w=Array.isArray(Y.reasoning)?Y.reasoning.map((_)=>_.text).join(""):void 0;return{content:Y.text,reasoningContent:w,toolCalls:j,usage:this.convertUsage(Y.usage,Y.providerMetadata),finishReason:Y.finishReason}}catch(Y){let J=Date.now()-Q;if(B.error("[VercelAIChatService] Chat failed after",J,"ms"),this.isFallbackableError(Y)&&this.config.fallbackModel){B.warn(`[VercelAIChatService] Switching to fallback model (non-stream): ${this.config.fallbackModel}`);let j={...this.config,model:this.config.fallbackModel},w=this.createModel(j);try{let _=await H({model:w,messages:Z,tools:$,maxOutputTokens:this.config.maxOutputTokens,temperature:this.config.temperature??0,abortSignal:W,...{allowSystemInMessages:!0}}),S=_.toolCalls&&_.toolCalls.length>0?this.convertToolCalls(_.toolCalls):void 0,G=Array.isArray(_.reasoning)?_.reasoning.map((I)=>I.text).join(""):void 0;return{content:_.text||"",reasoningContent:G,toolCalls:S,usage:this.convertUsage(_.usage,_.providerMetadata),finishReason:_.finishReason}}catch(_){throw Error(`Fallback model (${this.config.fallbackModel}) also failed: ${_ instanceof Error?_.message:_}`,{cause:Y})}}throw Y}}async*streamChat(F,q,W){let Q=Date.now();B.debug("[VercelAIChatService] Starting stream request");let X=O(F),Z=this.convertMessages(X),$=this.convertTools(q);try{let Y=K({model:this.model,messages:Z,tools:$,maxOutputTokens:this.config.maxOutputTokens,temperature:this.config.temperature??0,abortSignal:W,...{allowSystemInMessages:!0}});B.debug("[VercelAIChatService] Stream started");let J=0;for await(let w of Y.fullStream)switch(w.type){case"text-delta":yield{content:L(w)};break;case"reasoning-delta":yield{reasoningContent:L(w)};break;case"tool-call":yield{toolCalls:[{index:J++,id:w.toolCallId,type:"function",function:{name:w.toolName,arguments:JSON.stringify(w.args??w.input??{})}}]};break;case"finish":yield{finishReason:w.finishReason,usage:this.convertUsage(w.totalUsage,w.providerMetadata)};break}let j=Date.now()-Q;B.debug("[VercelAIChatService] Stream completed in",j,"ms")}catch(Y){let J=Date.now()-Q;if(B.error("[VercelAIChatService] Stream failed after",J,"ms"),this.isFallbackableError(Y)&&this.config.fallbackModel){B.warn(`[VercelAIChatService] Switching to fallback model: ${this.config.fallbackModel}`),yield{modelFallback:!0};let j={...this.config,model:this.config.fallbackModel},w=this.createModel(j);try{let _=K({model:w,messages:Z,tools:$,maxOutputTokens:this.config.maxOutputTokens,temperature:this.config.temperature??0,abortSignal:W,...{allowSystemInMessages:!0}}),S=0;for await(let G of _.fullStream)switch(G.type){case"text-delta":yield{content:L(G)};break;case"reasoning-delta":yield{reasoningContent:L(G)};break;case"tool-call":yield{toolCalls:[{index:S++,id:G.toolCallId,type:"function",function:{name:G.toolName,arguments:JSON.stringify(G.args??G.input??{})}}]};break;case"finish":yield{finishReason:G.finishReason,usage:this.convertUsage(G.totalUsage,G.providerMetadata)};break}return}catch(_){throw Error(`Fallback model (${this.config.fallbackModel}) also failed: ${_ instanceof Error?_.message:_}`,{cause:Y})}}throw Y}}getConfig(){return{...this.config}}updateConfig(F){B.debug("[VercelAIChatService] Updating configuration"),this.config={...this.config,...F},this.model=this.createModel(this.config),B.debug("[VercelAIChatService] Configuration updated")}}var M=R("Service");async function s(F){let q=F;if(q.provider){let W=V(q.provider);if(Object.keys(W).length>0)q={...q,customHeaders:{...W,...q.customHeaders}},M.debug(`Injected ${q.provider} specific headers:`,Object.keys(W))}return v(q)}function v(F){return new D(F)}
8
+ export{C as ob,b as pb,f as qb,s as rb};
@@ -0,0 +1,3 @@
1
+ import{Ia as t}from"./chunk-y5g06jmk.js";import{xb as r}from"./chunk-7ycmx7c2.js";import"./chunk-set7v1rf.js";import{Db as s}from"./chunk-j2ag7hh6.js";var m={command:"doctor",describe:"Check the health of your Blade installation",handler:async()=>{console.log(`Running Blade health check...
2
+ `);let e=0;try{await t.getInstance().initialize(),console.log("[OK] Configuration: OK")}catch(o){console.log("[FAIL] Configuration: FAILED"),console.log(` Error: ${o instanceof Error?o.message:"未知错误"}`),e++}let n=process.version;if(parseInt(n.slice(1).split(".")[0])>=18)console.log(`[OK] Node.js version: ${n}`);else console.log(`[WARN] Node.js version: ${n} (recommended: v18+)`),e++;try{let o=await import("fs/promises"),i=r();await o.access(i,(await import("fs")).constants.R_OK|(await import("fs")).constants.W_OK),console.log("[OK] File system permissions: OK")}catch(o){console.log("[FAIL] File system permissions: FAILED"),console.log(" Error: Cannot read/write in current directory"),e++}try{await import("ink"),console.log("[OK] Dependencies: OK")}catch(o){console.log("[FAIL] Dependencies: FAILED"),console.log(" Error: Missing required dependencies"),e++}if(console.log(`
3
+ Health Check Summary:`),e===0)console.log("All checks passed! Blade is ready to use.");else console.log(`Warning: Found ${e} issue(s). Please resolve them for optimal performance.`),process.exit(1)}};export{m as doctorCommands};
@@ -0,0 +1,76 @@
1
+ import{Ia as KQ,Ka as A}from"./chunk-y5g06jmk.js";import{Bb as FQ}from"./chunk-set7v1rf.js";import{nanoid as rQ}from"nanoid";import{devtools as lQ,subscribeWithSelector as cQ}from"zustand/middleware";import{createStore as iQ}from"zustand/vanilla";var OQ={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)"}},xQ={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)"}},BQ={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)"}},wQ={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)"}},_Q={name:"solarized-light",colors:{primary:"#268bd2",secondary:"#2aa198",accent:"#d33682",success:"#859900",warning:"#cb4b16",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)"}},AQ={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)"}},DQ={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)"}},LQ={name:"github",colors:{primary:"#0969da",secondary:"#8250df",accent:"#bc4c00",success:"#1a7f37",warning:"#bc4c00",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)"}},vQ={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)"}},EQ={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)"}},yQ={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)"}},CQ={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)"}},PQ={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)"}},a=[{id:"ayu-dark",label:"Ayu Dark",theme:OQ,tags:["dark","popular"]},{id:"dracula",label:"Dracula",theme:xQ,tags:["dark","popular"]},{id:"monokai",label:"Monokai",theme:BQ,tags:["dark","classic"]},{id:"nord",label:"Nord",theme:wQ,tags:["dark","minimal"]},{id:"solarized-light",label:"Solarized Light",theme:_Q,tags:["light"]},{id:"solarized-dark",label:"Solarized Dark",theme:AQ,tags:["dark"]},{id:"tokyo-night",label:"Tokyo Night",theme:DQ,tags:["dark","popular"]},{id:"github",label:"GitHub",theme:LQ,tags:["light","minimal"]},{id:"gruvbox",label:"Gruvbox",theme:vQ,tags:["dark","warm"]},{id:"one-dark",label:"One Dark",theme:EQ,tags:["dark","popular"]},{id:"catppuccin",label:"Catppuccin",theme:yQ,tags:["dark","pastel"]},{id:"rose-pine",label:"Rose Pine",theme:CQ,tags:["dark","elegant"]},{id:"kanagawa",label:"Kanagawa",theme:PQ,tags:["dark","japanese"]}];var t={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"}},p={name:"default",colors:t,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)"}},RQ={...p,name:"dark",colors:{...t,text:{primary:"#ffffff",secondary:"#e2e8f0",muted:"#94a3b8",light:"#000000"},background:{primary:"#1e293b",secondary:"#334155",dark:"#0f172a"},border:{light:"#475569",dark:"#64748b"},syntax:{comment:"#94a3b8",string:"#34d399",number:"#f472b6",keyword:"#60a5fa",function:"#06b6d4",variable:"#e2e8f0",operator:"#fbbf24",type:"#60a5fa",tag:"#fb7185",attr:"#fbbf24",default:"#ffffff"}}};class e{currentTheme=p;themes=new Map;constructor(){this.themes.set("default",p),this.themes.set("dark",RQ);for(let Q of a)this.themes.set(Q.id,Q.theme)}setTheme(Q){let Z=this.themes.get(Q);if(Z)this.currentTheme=Z;else throw Error(`Theme '${Q}' not found`)}getTheme(){return this.currentTheme}getAvailableThemes(){return Array.from(this.themes.keys())}getCurrentThemeName(){return this.currentTheme.name}getThemeByName(Q){return this.themes.get(Q)}hasTheme(Q){return this.themes.has(Q)}}var QQ=new e;var IQ={initializationStatus:"idle",initializationError:null,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null,tasks:[],awaitingSecondCtrlC:!1,thinkingModeEnabled:!1,subagentProgress:null},g=(Q)=>({...IQ,actions:{setInitializationStatus:(Z)=>{Q((X)=>({app:{...X.app,initializationStatus:Z}}))},setInitializationError:(Z)=>{Q((X)=>({app:{...X.app,initializationError:Z}}))},setActiveModal:(Z)=>{Q((X)=>({app:{...X.app,activeModal:Z}}))},showSessionSelector:(Z)=>{Q((X)=>({app:{...X.app,activeModal:"sessionSelector",sessionSelectorData:Z}}))},showModelEditWizard:(Z)=>{Q((X)=>({app:{...X.app,activeModal:"modelEditWizard",modelEditorTarget:Z}}))},closeModal:()=>{Q((Z)=>({app:{...Z.app,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null}}))},setTasks:(Z)=>{Q((X)=>({app:{...X.app,tasks:Z}}))},updateTask:(Z)=>{Q((X)=>({app:{...X.app,tasks:X.app.tasks.map(($)=>$.id===Z.id?Z:$)}}))},setAwaitingSecondCtrlC:(Z)=>{Q((X)=>({app:{...X.app,awaitingSecondCtrlC:Z}}))},setThinkingModeEnabled:(Z)=>{Q((X)=>({app:{...X.app,thinkingModeEnabled:Z}}))},toggleThinkingMode:()=>{Q((Z)=>({app:{...Z.app,thinkingModeEnabled:!Z.app.thinkingModeEnabled}}))},startSubagentProgress:(Z,X,$)=>{Q((Y)=>({app:{...Y.app,subagentProgress:{id:Z,type:X,description:$,status:"running",startTime:Date.now()}}}))},updateSubagentTool:(Z)=>{Q((X)=>{if(!X.app.subagentProgress)return X;return{app:{...X.app,subagentProgress:{...X.app.subagentProgress,currentTool:Z}}}})},completeSubagentProgress:(Z)=>{Q((X)=>{if(!X.app.subagentProgress)return X;return{app:{...X.app,subagentProgress:{...X.app.subagentProgress,status:Z?"completed":"failed",currentTool:void 0}}}}),setTimeout(()=>{Q((X)=>({app:{...X.app,subagentProgress:null}}))},1500)}}});var TQ={isProcessing:!1,abortController:null,pendingCommands:[]},d=(Q,Z)=>({...TQ,actions:{setProcessing:(X)=>{Q(($)=>({command:{...$.command,isProcessing:X}}))},createAbortController:()=>{let X=Z().command.abortController;if(X&&!X.signal.aborted)X.abort("interrupted-by-new-command");let $=new AbortController;return Q((Y)=>({command:{...Y.command,abortController:$}})),$},getAbortController:()=>{return Z().command.abortController},clearAbortController:(X)=>{let $=Z().command.abortController;if(X!==void 0&&$!==X)return;Q((Y)=>({command:{...Y.command,abortController:null}}))},abort:(X)=>{let{abortController:$}=Z().command;if($&&!$.signal.aborted)$.abort(X??"user-cancel");Q((Y)=>({command:{...Y.command,isProcessing:!1,pendingCommands:[]}}))},enqueueCommand:(X)=>{Q(($)=>({command:{...$.command,pendingCommands:[...$.command.pendingCommands,X]}}))},dequeueCommand:()=>{let{pendingCommands:X}=Z().command;if(X.length===0)return;let[$,...Y]=X;return Q((V)=>({command:{...V.command,pendingCommands:Y}})),$},clearQueue:()=>{Q((X)=>({command:{...X.command,pendingCommands:[]}}))}}});var MQ={config:null},m=(Q)=>({...MQ,actions:{setConfig:(Z)=>{Q((X)=>({config:{...X.config,config:Z}}))},updateConfig:(Z)=>{Q((X)=>{if(!X.config.config)throw Error(`[ConfigSlice] Config not initialized. Cannot update: ${JSON.stringify(Z)}`);return{config:{...X.config,config:{...X.config.config,...Z}}}})}}});var bQ={currentFocus:"main-input",previousFocus:null},r=(Q)=>({...bQ,actions:{setFocus:(Z)=>{Q((X)=>({focus:{...X.focus,currentFocus:Z,previousFocus:X.focus.currentFocus}}))},restorePreviousFocus:()=>{Q((Z)=>({focus:{...Z.focus,currentFocus:Z.focus.previousFocus||"main-input",previousFocus:null}}))}}});import{nanoid as fQ}from"nanoid";var W={codeBlock:/^```(\w+)?\s*$/,heading:/^ *(#{1,4}) +(.+)/,blockquote:/^(>+)\s?(.*)/,ulItem:/^([ \t]*)([-*+]) +(.+)/,olItem:/^([ \t]*)(\d+)\. +(.+)/,hr:/^ *([-*_] *){3,} *$/,table:/^\|(.+)\|$/,tableSeparator:/^\|[\s]*:?-+:?[\s]*(\|[\s]*:?-+:?[\s]*)+\|?$/,diffStart:/^<<<DIFF>>>$/,diffEnd:/^<<<\/DIFF>>>$/,commandMessage:/<command-message>(.*?)<\/command-message>/};function $X(Q){let Z=[],X=Q.split(/\r?\n/),$=!1,Y=[],V=null,J=0,U=!1,G=[],z=[],K=!1,E=[],y=!1,B=[],H=0,j=!0;for(let D=0;D<X.length;D++){let O=X[D];if(K){if(O.match(W.diffEnd)){try{let w=JSON.parse(E.join(`
2
+ `));Z.push({type:"diff",content:"",diffData:{patch:w.patch,startLine:w.startLine,matchLine:w.matchLine}})}catch(w){Z.push({type:"text",content:E.join(`
3
+ `)})}K=!1,E=[],j=!1;continue}E.push(O);continue}if(O.match(W.diffStart)){K=!0,E=[],j=!1;continue}if($){let w=O.match(W.codeBlock),L=O.trim()==="```";if(w&&w[1])J++,Y.push(O);else if(L)if(J>0)J--,Y.push(O);else{let qQ=Y.join(`
4
+ `);Z.push({type:"code",content:qQ,language:V||void 0}),$=!1,Y=[],V=null,J=0,j=!1}else Y.push(O);continue}let n=O.match(W.codeBlock);if(n){$=!0,V=n[1]||null,J=0,j=!1;continue}let T=O.match(W.table),WQ=O.match(W.tableSeparator);if(T&&!U){if(D+1<X.length){if(X[D+1].match(W.tableSeparator)){U=!0,G=T[1].split("|").map((L)=>L.trim()).filter((L)=>L.length>0),z=[],j=!1;continue}}}if(U&&WQ)continue;if(U&&T){let w=T[1].split("|").map((L)=>L.trim()).filter((L)=>L.length>0);while(w.length<G.length)w.push("");if(w.length>G.length)w.length=G.length;z.push(w);continue}if(U&&!T){if(G.length>0&&z.length>0)Z.push({type:"table",content:"",tableData:{headers:G,rows:z}});U=!1,G=[],z=[]}let S=O.match(W.blockquote);if(S){let w=S[1].length,L=S[2]||"";if(y&&w===H)B.push(L);else{if(y)Z.push({type:"blockquote",content:B.join(`
5
+ `),blockquoteLevel:H,blockquoteLines:[...B]});y=!0,H=w,B=[L]}j=!1;continue}if(y)Z.push({type:"blockquote",content:B.join(`
6
+ `),blockquoteLevel:H,blockquoteLines:[...B]}),y=!1,B=[],H=0;let u=O.match(W.heading);if(u){Z.push({type:"heading",content:u[2],level:u[1].length}),j=!1;continue}let h=O.match(W.ulItem);if(h){Z.push({type:"list",content:h[3],listType:"ul",marker:h[2],indentation:h[1].length}),j=!1;continue}let k=O.match(W.olItem);if(k){Z.push({type:"list",content:k[3],listType:"ol",marker:k[2],indentation:k[1].length}),j=!1;continue}if(O.match(W.hr)){Z.push({type:"hr",content:""}),j=!1;continue}if(O.trim().length===0){if(!j)Z.push({type:"empty",content:""}),j=!0;continue}let s=O.match(W.commandMessage);if(s){Z.push({type:"command-message",content:s[1]}),j=!1;continue}Z.push({type:"text",content:O}),j=!1}if($){let D=Y.join(`
7
+ `);Z.push({type:"code",content:D,language:V||void 0})}if(U&&G.length>0&&z.length>0)Z.push({type:"table",content:"",tableData:{headers:G,rows:z}});if(y&&B.length>0)Z.push({type:"blockquote",content:B.join(`
8
+ `),blockquoteLevel:H,blockquoteLines:[...B]});while(Z.length>0&&Z[Z.length-1].type==="empty")Z.pop();return Z}var C=new Map;function NQ(){return{inCodeBlock:!1,codeBlockContent:[],codeBlockLang:null,codeBlockDepth:0,inTable:!1,tableHeaders:[],tableRows:[],inDiff:!1,diffContent:[],inBlockquote:!1,blockquoteLines:[],blockquoteLevel:0,lastLineEmpty:!0,pendingTableHeader:null}}function hQ(Q){let Z=C.get(Q);if(Z)return Z;let X={state:NQ(),blocks:[],pendingLine:"",finalized:!1};return C.set(Q,X),X}function XQ(Q){return Q.endsWith("\r")?Q.slice(0,-1):Q}function ZQ(Q,Z){if(Q.tableHeaders.length>0&&Q.tableRows.length>0)Z.push({type:"table",content:"",tableData:{headers:Q.tableHeaders,rows:Q.tableRows}});Q.inTable=!1,Q.tableHeaders=[],Q.tableRows=[]}function l(Q,Z){if(Q.blockquoteLines.length>0)Z.push({type:"blockquote",content:Q.blockquoteLines.join(`
9
+ `),blockquoteLevel:Q.blockquoteLevel,blockquoteLines:[...Q.blockquoteLines]});Q.inBlockquote=!1,Q.blockquoteLines=[],Q.blockquoteLevel=0}function $Q(Q,Z){let X=Q.codeBlockContent.join(`
10
+ `);Z.push({type:"code",content:X,language:Q.codeBlockLang||void 0}),Q.inCodeBlock=!1,Q.codeBlockContent=[],Q.codeBlockLang=null,Q.codeBlockDepth=0,Q.lastLineEmpty=!1}function c(Q,Z,X=!0){let{state:$,blocks:Y}=Z;if($.pendingTableHeader!==null){if(Q.match(W.tableSeparator)){$.inTable=!0,$.tableHeaders=$.pendingTableHeader.slice(1,-1).split("|").map((H)=>H.trim()).filter((H)=>H.length>0),$.tableRows=[],$.pendingTableHeader=null,$.lastLineEmpty=!1;return}Y.push({type:"text",content:$.pendingTableHeader}),$.pendingTableHeader=null,$.lastLineEmpty=!1}if($.inDiff){if(Q.match(W.diffEnd)){try{let H=JSON.parse($.diffContent.join(`
11
+ `));Y.push({type:"diff",content:"",diffData:{patch:H.patch,startLine:H.startLine,matchLine:H.matchLine}})}catch(H){Y.push({type:"text",content:$.diffContent.join(`
12
+ `)})}$.inDiff=!1,$.diffContent=[],$.lastLineEmpty=!1;return}$.diffContent.push(Q);return}if(Q.match(W.diffStart)){$.inDiff=!0,$.diffContent=[],$.lastLineEmpty=!1;return}if($.inCodeBlock){let H=Q.match(W.codeBlock),j=Q.trim()==="```";if(H&&H[1])$.codeBlockDepth++,$.codeBlockContent.push(Q);else if(j)if($.codeBlockDepth>0)$.codeBlockDepth--,$.codeBlockContent.push(Q);else $Q($,Y);else $.codeBlockContent.push(Q);return}let V=Q.match(W.codeBlock);if(V){$.inCodeBlock=!0,$.codeBlockLang=V[1]||null,$.codeBlockDepth=0,$.lastLineEmpty=!1;return}let J=Q.match(W.table),U=Q.match(W.tableSeparator);if(J&&!$.inTable){$.pendingTableHeader=Q;return}if($.inTable&&U)return;if($.inTable&&J){let H=J[1].split("|").map((j)=>j.trim()).filter((j)=>j.length>0);while(H.length<$.tableHeaders.length)H.push("");if(H.length>$.tableHeaders.length)H.length=$.tableHeaders.length;$.tableRows.push(H);return}if($.inTable&&!J){if(ZQ($,Y),X){c(Q,Z,!1);return}}let G=Q.match(W.blockquote);if(G){let H=G[1].length,j=G[2]||"";if($.inBlockquote&&H===$.blockquoteLevel)$.blockquoteLines.push(j);else{if($.inBlockquote)l($,Y);$.inBlockquote=!0,$.blockquoteLevel=H,$.blockquoteLines=[j]}$.lastLineEmpty=!1;return}if($.inBlockquote)l($,Y);let z=Q.match(W.heading);if(z){Y.push({type:"heading",content:z[2],level:z[1].length}),$.lastLineEmpty=!1;return}let K=Q.match(W.ulItem);if(K){Y.push({type:"list",content:K[3],listType:"ul",marker:K[2],indentation:K[1].length}),$.lastLineEmpty=!1;return}let E=Q.match(W.olItem);if(E){Y.push({type:"list",content:E[3],listType:"ol",marker:E[2],indentation:E[1].length}),$.lastLineEmpty=!1;return}if(Q.match(W.hr)){Y.push({type:"hr",content:""}),$.lastLineEmpty=!1;return}if(Q.trim().length===0){if(!$.lastLineEmpty)Y.push({type:"empty",content:""}),$.lastLineEmpty=!0;return}let B=Q.match(W.commandMessage);if(B){Y.push({type:"command-message",content:B[1]}),$.lastLineEmpty=!1;return}Y.push({type:"text",content:Q}),$.lastLineEmpty=!1}function JX(Q,Z){if(!Q||!Z)return;let X=hQ(Q);if(X.finalized)return;let $=X.pendingLine+Z,Y=$.split(`
13
+ `),V=$.endsWith(`
14
+ `),J=V?Y:Y.slice(0,-1);X.pendingLine=V?"":Y[Y.length-1]??"";for(let U of J)c(XQ(U),X)}function UX(Q){let Z=C.get(Q);if(!Z||Z.finalized)return;if(Z.pendingLine)c(XQ(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)$Q(Z.state,Z.blocks);if(Z.state.inTable)ZQ(Z.state,Z.blocks);if(Z.state.inBlockquote)l(Z.state,Z.blocks);if(Z.state.inDiff)Z.blocks.push({type:"text",content:Z.state.diffContent.join(`
15
+ `)}),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 GX(Q){let Z=C.get(Q);if(!Z||!Z.finalized)return null;return Z.blocks}function jX(Q){let Z=C.get(Q);if(!Z)return null;return Z.blocks}function kQ(Q){let Z=C.get(Q);if(!Z)return null;let X=[],$=Z.state;if($.inDiff)X.push("<<<DIFF>>>"),X.push(...$.diffContent);else if($.inCodeBlock){let Y=$.codeBlockLang?`\`\`\`${$.codeBlockLang}`:"```";X.push(Y),X.push(...$.codeBlockContent)}else if($.inTable){if($.tableHeaders.length>0){X.push(`| ${$.tableHeaders.join(" | ")} |`),X.push(`| ${$.tableHeaders.map(()=>"---").join(" | ")} |`);for(let Y of $.tableRows)X.push(`| ${Y.join(" | ")} |`)}}else if($.inBlockquote){let Y=">".repeat($.blockquoteLevel)+" ";for(let V of $.blockquoteLines)X.push(Y+V)}else if($.pendingTableHeader)X.push($.pendingTableHeader);if(Z.pendingLine)X.push(Z.pendingLine);return X.length>0?X:null}function HX(Q){let Z=C.get(Q);if(!Z)return null;let X="text";if(Z.state.inDiff)X="diff";else if(Z.state.inCodeBlock)X="code";else if(Z.state.inTable||Z.state.pendingTableHeader)X="table";let $=kQ(Q);if(!$||$.length===0)return null;return{lines:$,mode:X}}function zX(Q){C.delete(Q)}function f(){C.clear()}var YQ=2000,M=[];function SQ(){let Q=M;return M=[],Q}var JQ={inputTokens:0,outputTokens:0,totalTokens:0,maxContextTokens:200000},VQ={sessionId:fQ(),messages:[],restoredContextMessages:null,restoredVisibleMessageCount:0,isCompacting:!1,currentCommand:null,error:null,isActive:!0,tokenUsage:{...JQ},currentThinkingContent:null,thinkingExpanded:!1,clearCount:0,historyExpanded:!1,expandedMessageCount:100,currentStreamingMessageId:null,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,finalizingStreamingMessageId:null},i=(Q,Z)=>({...VQ,actions:{addMessage:(X)=>{Q(($)=>({session:{...$.session,messages:[...$.session.messages,X],error:null}}))},addUserMessage:(X)=>{let $={id:`user-${Date.now()}-${Math.random()}`,role:"user",content:X,timestamp:Date.now()};Z().session.actions.addMessage($)},addAssistantMessage:(X,$)=>{let Y={id:`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:X,timestamp:Date.now(),thinkingContent:$};Z().session.actions.addMessage(Y)},addAssistantMessageAndClearThinking:(X)=>{let $=Z().session.currentThinkingContent,Y={id:`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:X,timestamp:Date.now(),thinkingContent:$||void 0};Q((V)=>({session:{...V.session,messages:[...V.session.messages,Y],currentThinkingContent:null,error:null}}))},addToolMessage:(X,$)=>{let Y={id:`tool-${Date.now()}-${Math.random()}`,role:"tool",content:X,timestamp:Date.now(),metadata:$};Z().session.actions.addMessage(Y)},setCompacting:(X)=>{Q(($)=>({session:{...$.session,isCompacting:X}}))},setCommand:(X)=>{Q(($)=>({session:{...$.session,currentCommand:X}}))},setError:(X)=>{Q(($)=>({session:{...$.session,error:X}}))},clearMessages:()=>{f(),Q((X)=>({session:{...X.session,messages:[],restoredContextMessages:null,restoredVisibleMessageCount:0,error:null,clearCount:X.session.clearCount+1}}))},resetSession:()=>{f(),Q((X)=>({session:{...X.session,...VQ,sessionId:X.session.sessionId,isActive:!0}}))},restoreSession:(X,$,Y)=>{f(),Q((V)=>({session:{...V.session,sessionId:X,messages:$,restoredContextMessages:Y??null,restoredVisibleMessageCount:Y?$.length:0,error:null,isActive:!0}}))},updateTokenUsage:(X)=>{Q(($)=>({session:{...$.session,tokenUsage:{...$.session.tokenUsage,...X}}}))},resetTokenUsage:()=>{Q((X)=>({session:{...X.session,tokenUsage:{...JQ}}}))},setCurrentThinkingContent:(X)=>{if(Z().session.currentThinkingContent===X)return;Q(($)=>({session:{...$.session,currentThinkingContent:X}}))},appendThinkingContent:(X)=>{Q(($)=>({session:{...$.session,currentThinkingContent:($.session.currentThinkingContent||"")+X}}))},setThinkingExpanded:(X)=>{Q(($)=>({session:{...$.session,thinkingExpanded:X}}))},toggleThinkingExpanded:()=>{Q((X)=>({session:{...X.session,thinkingExpanded:!X.session.thinkingExpanded}}))},setHistoryExpanded:(X)=>{Q(($)=>({session:{...$.session,historyExpanded:X}}))},toggleHistoryExpanded:()=>{Q((X)=>({session:{...X.session,historyExpanded:!X.session.historyExpanded}}))},setExpandedMessageCount:(X)=>{Q(($)=>({session:{...$.session,expandedMessageCount:X}}))},incrementClearCount:()=>{Q((X)=>({session:{...X.session,clearCount:X.session.clearCount+1}}))},startStreamingAssistantMessage:()=>{let X=`assistant-${Date.now()}-${Math.random()}`,$={id:X,role:"assistant",content:"",timestamp:Date.now()};return M=[],Q((Y)=>({session:{...Y.session,messages:[...Y.session.messages,$],currentStreamingMessageId:X,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,error:null}})),X},appendAssistantContent:(X)=>{let $=Z().session.currentStreamingMessageId,Y=$??`assistant-${Date.now()}-${Math.random()}`;return M.push(X),Q((V)=>{let J=(D)=>D.endsWith("\r")?D.slice(0,-1):D,U=$?V.session.currentStreamingLines:[],G=$?V.session.currentStreamingTail:"",z=$?V.session.currentStreamingLineCount:0,K=$?V.session.currentStreamingVersion:0,y=(G+X).split(`
16
+ `),B=y.slice(0,-1).map(J),H=J(y[y.length-1]??""),j=U;if(B.length>0){if(j=[...U,...B],j.length>YQ){let D=j.length-YQ;j=j.slice(D)}}return{session:{...V.session,currentStreamingMessageId:Y,currentStreamingLines:j,currentStreamingTail:H,currentStreamingLineCount:z+B.length,currentStreamingVersion:K+1,error:null}}}),Y},finalizeStreamingMessage:(X,$)=>{let Y=SQ();Q((V)=>{let J=V.session.currentStreamingMessageId,G=Y.join("")+(X||""),z=(V.session.currentThinkingContent||"")+($||"");if(G.length>0){let K={id:J||`assistant-${Date.now()}-${Math.random()}`,role:"assistant",content:G,timestamp:Date.now(),thinkingContent:z||void 0};return{session:{...V.session,messages:[...V.session.messages,K],currentStreamingMessageId:null,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,currentThinkingContent:null,finalizingStreamingMessageId:K.id}}}return{session:{...V.session,currentStreamingMessageId:null,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,currentThinkingContent:null,finalizingStreamingMessageId:null}}})},clearFinalizingStreamingMessageId:()=>{Q((X)=>({session:{...X.session,finalizingStreamingMessageId:null}}))},discardStreamingMessage:()=>{M=[],Q((X)=>({session:{...X.session,currentStreamingMessageId:null,currentStreamingChunks:[],currentStreamingLines:[],currentStreamingTail:"",currentStreamingLineCount:0,currentStreamingVersion:0,finalizingStreamingMessageId:null}}))}}});import{nanoid as mQ}from"nanoid";import{promises as _}from"node:fs";import*as F from"node:path";import{fileURLToPath as uQ}from"node:url";import{nanoid as pQ}from"nanoid";var UQ={proposal:"proposal.md",spec:"spec.md",requirements:"requirements.md",design:"design.md",tasks:"tasks.md",meta:".meta.json"},P={SPECS:"specs",CHANGES:"changes",ARCHIVE:"archive",STEERING:"steering",SPEC_DELTA:"specs"},R={CONSTITUTION:"constitution.md",PRODUCT:"product.md",TECH:"tech.md",STRUCTURE:"structure.md"};var b={init:["requirements"],requirements:["design","tasks"],design:["tasks"],tasks:["implementation"],implementation:["done","tasks"],done:[]},OX={init:"初始化",requirements:"需求定义",design:"架构设计",tasks:"任务分解",implementation:"实现中",done:"已完成"},GQ={init:"proposal",requirements:"requirements",design:"design",tasks:"tasks",implementation:"tasks",done:null};var gQ=uQ(import.meta.url),dQ=F.dirname(gQ),jQ=F.join(dQ,"templates");class N{workspaceRoot;bladeDir;constructor(Q){this.workspaceRoot=Q,this.bladeDir=F.join(Q,".blade")}getSpecsDir(){return F.join(this.bladeDir,P.SPECS)}getChangesDir(){return F.join(this.bladeDir,P.CHANGES)}getArchiveDir(){return F.join(this.bladeDir,P.ARCHIVE)}getSteeringDir(){return F.join(this.bladeDir,P.STEERING)}getChangePath(Q){return F.join(this.getChangesDir(),Q)}getChangeFilePath(Q,Z){return F.join(this.getChangePath(Q),UQ[Z])}async initializeDirectories(){await _.mkdir(this.getChangesDir(),{recursive:!0,mode:493})}async createChangeDir(Q){let Z=this.getChangePath(Q);return await _.mkdir(Z,{recursive:!0,mode:493}),await _.mkdir(F.join(Z,P.SPEC_DELTA),{recursive:!0,mode:493}),Z}async readFile(Q){try{return await _.readFile(Q,"utf-8")}catch(Z){if(Z.code==="ENOENT")return null;throw Z}}async writeFile(Q,Z){let X=F.dirname(Q);await _.mkdir(X,{recursive:!0,mode:493}),await _.writeFile(Q,Z,"utf-8")}async fileExists(Q){try{return await _.access(Q),!0}catch{return!1}}async dirExists(Q){try{return(await _.stat(Q)).isDirectory()}catch{return!1}}createMetadata(Q,Z){let X=new Date().toISOString();return{id:pQ(),name:Q,description:Z,phase:"init",createdAt:X,updatedAt:X,tasks:[]}}async readMetadata(Q){let Z=this.getChangeFilePath(Q,"meta"),X=await this.readFile(Z);if(!X)return null;try{return JSON.parse(X)}catch{return null}}async writeMetadata(Q,Z){let X=this.getChangeFilePath(Q,"meta");Z.updatedAt=new Date().toISOString(),await this.writeFile(X,JSON.stringify(Z,null,2))}async updatePhase(Q,Z){let X=await this.readMetadata(Q);if(!X)return null;return X.phase=Z,await this.writeMetadata(Q,X),X}async readSpecFile(Q,Z){let X=this.getChangeFilePath(Q,Z);return this.readFile(X)}async writeSpecFile(Q,Z,X){let $=this.getChangeFilePath(Q,Z);await this.writeFile($,X);let Y=await this.readMetadata(Q);if(Y)await this.writeMetadata(Q,Y)}async getPhaseContent(Q,Z){let X=GQ[Z];if(!X)return null;return this.readSpecFile(Q,X)}async readSteeringContext(){let Q=this.getSteeringDir(),[Z,X,$,Y]=await Promise.all([this.readFile(F.join(Q,R.CONSTITUTION)),this.readFile(F.join(Q,R.PRODUCT)),this.readFile(F.join(Q,R.TECH)),this.readFile(F.join(Q,R.STRUCTURE))]);return{constitution:Z||void 0,product:X||void 0,tech:$||void 0,structure:Y||void 0}}async writeSteeringFile(Q,Z){let X=F.join(this.getSteeringDir(),R[Q]);await this.writeFile(X,Z)}async hasSteeringDocs(){let Q=this.getSteeringDir();if(!await this.dirExists(Q))return!1;return(await _.readdir(Q)).length>0}async listActiveChanges(){let Q=this.getChangesDir();if(!await this.dirExists(Q))return[];return(await _.readdir(Q,{withFileTypes:!0})).filter((X)=>X.isDirectory()).map((X)=>X.name)}async listArchivedChanges(){let Q=this.getArchiveDir();if(!await this.dirExists(Q))return[];return(await _.readdir(Q,{withFileTypes:!0})).filter((X)=>X.isDirectory()).map((X)=>X.name)}async changeExists(Q){return this.dirExists(this.getChangePath(Q))}async archiveChange(Q){let Z=this.getChangePath(Q),X=F.join(this.getArchiveDir(),Q);await _.mkdir(F.dirname(X),{recursive:!0,mode:493}),await _.rename(Z,X)}async restoreChange(Q){let Z=F.join(this.getArchiveDir(),Q),X=this.getChangePath(Q);await _.rename(Z,X)}async listSpecDomains(){let Q=this.getSpecsDir();if(!await this.dirExists(Q))return[];return(await _.readdir(Q,{withFileTypes:!0})).filter((X)=>X.isDirectory()).map((X)=>X.name)}async readAuthorativeSpec(Q){let Z=F.join(this.getSpecsDir(),Q,"spec.md");return this.readFile(Z)}async writeAuthorativeSpec(Q,Z){let X=F.join(this.getSpecsDir(),Q,"spec.md");await this.writeFile(X,Z)}async mergeSpecDeltas(Q){let Z=F.join(this.getChangePath(Q),P.SPEC_DELTA);if(!await this.dirExists(Z))return[];let X=[],$=await _.readdir(Z,{withFileTypes:!0});for(let Y of $){if(!Y.isDirectory())continue;let V=F.join(Z,Y.name,"spec.md"),J=await this.readFile(V);if(J){let U=await this.readAuthorativeSpec(Y.name),G=U?`${U}
17
+
18
+ ---
19
+
20
+ <!-- Merged from ${Q} -->
21
+
22
+ ${J}`:J;await this.writeAuthorativeSpec(Y.name,G),X.push(Y.name)}}return X}static TEMPLATE_NAMES={proposal:"proposal.md.template",spec:"spec.md.template",requirements:"requirements.md.template",design:"design.md.template",tasks:"tasks.md.template",meta:""};static STEERING_TEMPLATE_NAMES={CONSTITUTION:"steering/constitution.md.template",PRODUCT:"steering/product.md.template",TECH:"steering/tech.md.template",STRUCTURE:"steering/structure.md.template"};async readTemplate(Q){let Z=N.TEMPLATE_NAMES[Q];if(!Z)return null;let X=F.join(jQ,Z);return this.readFile(X)}async readSteeringTemplate(Q){let Z=N.STEERING_TEMPLATE_NAMES[Q],X=F.join(jQ,Z);return this.readFile(X)}fillTemplate(Q,Z){let X=Q;for(let[$,Y]of Object.entries(Z))X=X.replace(new RegExp(`\\{\\{${$}\\}\\}`,"g"),Y);return X}async createFromTemplate(Q,Z,X){let $=await this.readTemplate(Z);if(!$)return null;let Y=this.fillTemplate($,{name:Q,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString(),...X});return await this.writeSpecFile(Q,Z,Y),Y}async createSteeringFromTemplate(Q,Z={}){let X=await this.readSteeringTemplate(Q);if(!X)return null;let $=this.fillTemplate(X,{createdAt:new Date().toISOString(),...Z});return await this.writeSteeringFile(Q,$),$}async initializeSteeringDocs(){let Q=[],Z=this.getSteeringDir();for(let[X,$]of Object.entries(R)){let Y=F.join(Z,$);if(!await this.fileExists(Y))await this.createSteeringFromTemplate(X),Q.push($)}return Q}}class x{static instance=null;fileManager=null;workspaceRoot=null;constructor(){}static getInstance(){if(!x.instance)x.instance=new x;return x.instance}static resetInstance(){x.instance=null}async initialize(Q){if(this.workspaceRoot===Q&&this.fileManager)return;this.workspaceRoot=Q,this.fileManager=new N(Q),await this.fileManager.initializeDirectories()}getFileManager(){if(!this.fileManager)throw Error("SpecService not initialized. Call initialize() first.");return this.fileManager}async readSteeringContext(){return this.getFileManager().readSteeringContext()}async readSpecMetadata(Q){return this.getFileManager().readMetadata(Q)}async specExists(Q){return this.getFileManager().changeExists(Q)}getSpecPath(Q){return this.getFileManager().getChangePath(Q)}async createSpec(Q,Z){let X=this.getFileManager();if(await X.changeExists(Q))return{success:!1,message:`Spec "${Q}" already exists`,error:"SPEC_EXISTS"};let $=await X.createChangeDir(Q),Y=X.createMetadata(Q,Z);await X.writeMetadata(Q,Y);let V=this.generateProposalTemplate(Q,Z);return await X.writeSpecFile(Q,"proposal",V),{success:!0,message:`Spec "${Q}" created successfully`,data:{spec:Y,path:$}}}async loadSpec(Q){let Z=this.getFileManager(),X=await Z.readMetadata(Q);if(!X)return{success:!1,message:`Spec "${Q}" not found`,error:"SPEC_NOT_FOUND"};let $=Z.getChangePath(Q);return{success:!0,message:`Spec "${Q}" loaded successfully`,data:{spec:X,path:$}}}canTransitionPhase(Q,Z){return b[Q].includes(Z)}getAllowedTransitions(Q){return b[Q]}async updatePhase(Q,Z){return this.getFileManager().updatePhase(Q,Z)}createTask(Q,Z,X){return{id:mQ(8),title:Q,description:Z,status:"pending",dependencies:X?.dependencies||[],affectedFiles:X?.affectedFiles||[],complexity:X?.complexity||"medium"}}async saveMetadata(Q,Z){await this.getFileManager().writeMetadata(Q,Z)}getNextTask(Q){return Q.find((Z)=>{if(Z.status!=="pending")return!1;return Z.dependencies.every((X)=>{return Q.find((Y)=>Y.id===X)?.status==="completed"})})||null}getTaskProgress(Q){if(Q.length===0)return{total:0,completed:0,percentage:0};let Z=Q.length,X=Q.filter((Y)=>Y.status==="completed").length,$=Math.round(X/Z*100);return{total:Z,completed:X,percentage:$}}async listActiveSpecs(){return this.getFileManager().listActiveChanges()}async listArchivedSpecs(){return this.getFileManager().listArchivedChanges()}async archiveSpec(Q){let Z=this.getFileManager();return await Z.mergeSpecDeltas(Q),await Z.updatePhase(Q,"done"),await Z.archiveChange(Q),{success:!0,message:`Spec "${Q}" archived successfully`}}async validateSpec(Q){let Z=this.getFileManager(),X=[],$=[],[Y,V,J,U,G]=await Promise.all([Z.readSpecFile(Q.name,"proposal"),Z.readSpecFile(Q.name,"spec"),Z.readSpecFile(Q.name,"requirements"),Z.readSpecFile(Q.name,"design"),Z.readSpecFile(Q.name,"tasks")]),z={proposal:!!Y,spec:!!V,requirements:!!J,design:!!U,tasks:!!G};if(Q.phase==="requirements"&&!z.requirements)X.push({severity:"warning",file:"requirements",message:"Requirements document is missing"}),$.push("Generate requirements using EARS format");if(Q.phase==="design"&&!z.design)X.push({severity:"warning",file:"design",message:"Design document is missing"}),$.push("Create architecture diagrams and API contracts");if(Q.phase==="tasks"&&Q.tasks.length===0)X.push({severity:"warning",file:"tasks",message:"No tasks defined"}),$.push("Break down the spec into atomic tasks");if(Q.phase==="implementation"){let K=this.getTaskProgress(Q.tasks);if(K.completed<K.total)X.push({severity:"info",file:"tasks",message:`${K.total-K.completed} tasks remaining`})}return{valid:X.filter((K)=>K.severity==="error").length===0,phase:Q.phase,completeness:z,issues:X,suggestions:$}}generateProposalTemplate(Q,Z){return`# ${Q}
23
+
24
+ ## Summary
25
+
26
+ ${Z}
27
+
28
+ ## Background
29
+
30
+ <!-- Why is this change needed? What problem does it solve? -->
31
+
32
+ ## Goals
33
+
34
+ <!-- What are the specific objectives of this change? -->
35
+
36
+ - [ ] Goal 1
37
+ - [ ] Goal 2
38
+
39
+ ## Non-Goals
40
+
41
+ <!-- What is explicitly out of scope? -->
42
+
43
+ ## Risks and Mitigations
44
+
45
+ <!-- What could go wrong? How will you address it? -->
46
+
47
+ | Risk | Mitigation |
48
+ |------|------------|
49
+ | | |
50
+
51
+ ## Open Questions
52
+
53
+ <!-- What needs to be clarified before proceeding? -->
54
+
55
+ 1.
56
+ `}}var HQ=FQ("Spec"),zQ={currentSpec:null,specPath:null,isActive:!1,steeringContext:null,recentSpecs:[],isLoading:!1,error:null,workspaceRoot:null},o=(Q,Z)=>({...zQ,actions:{initialize:async(X)=>{let $=x.getInstance();await $.initialize(X);let Y=await $.readSteeringContext();Q((V)=>({spec:{...V.spec,workspaceRoot:X,steeringContext:Y}}))},createSpec:async(X,$)=>{let V=await x.getInstance().createSpec(X,$);if(V.success&&V.data){let{spec:J,path:U}=V.data,G=Z().spec.recentSpecs.filter((z)=>z!==X);G.unshift(X),Q((z)=>({spec:{...z.spec,currentSpec:J,specPath:U,isActive:!0,recentSpecs:G.slice(0,10)}}))}return V},loadSpec:async(X)=>{let Y=await x.getInstance().loadSpec(X);if(Y.success&&Y.data){let{spec:V,path:J}=Y.data,U=Z().spec.recentSpecs.filter((G)=>G!==X);U.unshift(X),Q((G)=>({spec:{...G.spec,currentSpec:V,specPath:J,isActive:!0,recentSpecs:U.slice(0,10)}}))}return Y},closeSpec:()=>{Q((X)=>({spec:{...X.spec,currentSpec:null,specPath:null,isActive:!1}}))},exitSpecMode:()=>{Z().spec.actions.closeSpec()},transitionPhase:async(X)=>{let $=Z().spec.currentSpec;if(!$)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let Y=x.getInstance();if(!Y.canTransitionPhase($.phase,X))return{success:!1,message:`Cannot transition from "${$.phase}" to "${X}"`,error:"INVALID_TRANSITION"};let V=await Y.updatePhase($.name,X);if(!V)return{success:!1,message:"Failed to update phase",error:"UPDATE_FAILED"};if(Q((J)=>({spec:{...J.spec,currentSpec:V}})),X==="done")try{let{config:J}=Z();if(J.actions)J.actions.updateConfig({permissionMode:"default"});HQ.info("Spec 已完成,已自动退出 Spec 模式")}catch(J){HQ.error("自动退出 Spec 模式失败:",J)}return{success:!0,message:`Transitioned to "${X}" phase`,data:{spec:V,phase:X}}},getAllowedTransitions:()=>{let X=Z().spec.currentSpec;if(!X)return[];return b[X.phase]},addTask:async(X,$,Y)=>{let V=Z().spec.currentSpec;if(!V)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let J=x.getInstance(),U=J.createTask(X,$,Y),G={...V,tasks:[...V.tasks,U],updatedAt:new Date().toISOString()};return await J.saveMetadata(V.name,G),Q((z)=>({spec:{...z.spec,currentSpec:G}})),{success:!0,message:`Task "${X}" added`,data:{task:U}}},updateTaskStatus:async(X,$)=>{let Y=Z().spec.currentSpec;if(!Y)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let V=Y.tasks.find((K)=>K.id===X);if(!V)return{success:!1,message:`Task "${X}" not found`,error:"TASK_NOT_FOUND"};let J={...V,status:$,completedAt:$==="completed"?new Date().toISOString():V.completedAt},U=Y.tasks.map((K)=>K.id===X?J:K),G={...Y,tasks:U,currentTaskId:$==="in_progress"?X:Y.currentTaskId===X?void 0:Y.currentTaskId,updatedAt:new Date().toISOString()};return await x.getInstance().saveMetadata(Y.name,G),Q((K)=>({spec:{...K.spec,currentSpec:G}})),{success:!0,message:`Task status updated to "${$}"`,data:{task:J}}},getNextTask:()=>{let X=Z().spec.currentSpec;if(!X)return null;return x.getInstance().getNextTask(X.tasks)},getTaskProgress:()=>{let X=Z().spec.currentSpec;if(!X)return{total:0,completed:0,percentage:0};return x.getInstance().getTaskProgress(X.tasks)},listSpecs:async(X)=>{let $=x.getInstance(),Y=[],V=await $.listActiveSpecs();for(let J of V){let U=await $.readSpecMetadata(J);if(!U)continue;if(X?.phase&&U.phase!==X.phase)continue;if(X?.tags&&!X.tags.some((z)=>U.tags?.includes(z)))continue;if(X?.query&&!U.name.toLowerCase().includes(X.query.toLowerCase())&&!U.description.toLowerCase().includes(X.query.toLowerCase()))continue;let G=$.getTaskProgress(U.tasks);Y.push({name:U.name,description:U.description,phase:U.phase,updatedAt:U.updatedAt,path:$.getSpecPath(J),isArchived:!1,taskProgress:{total:G.total,completed:G.completed}})}if(X?.includeArchived){let J=await $.listArchivedSpecs();for(let U of J)Y.push({name:U,description:"(archived)",phase:"done",updatedAt:"",path:`archive/${U}`,isArchived:!0,taskProgress:{total:0,completed:0}})}return Y.sort((J,U)=>{if(J.isArchived!==U.isArchived)return J.isArchived?1:-1;return new Date(U.updatedAt).getTime()-new Date(J.updatedAt).getTime()}),Y},archiveCurrentSpec:async()=>{let X=Z().spec.currentSpec;if(!X)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let Y=await x.getInstance().archiveSpec(X.name);if(Y.success)Z().spec.actions.closeSpec();return Y},validateCurrentSpec:async()=>{let X=Z().spec.currentSpec;if(!X)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>"]};return x.getInstance().validateSpec(X)},getSteeringContextString:async()=>{let X=Z().spec.steeringContext;if(!X)return null;let $=[];if(X.constitution)$.push(`## Constitution (Project Governance)
57
+
58
+ ${X.constitution}`);if(X.product)$.push(`## Product Vision
59
+
60
+ ${X.product}`);if(X.tech)$.push(`## Technology Stack
61
+
62
+ ${X.tech}`);if(X.structure)$.push(`## Code Structure
63
+
64
+ ${X.structure}`);return $.length>0?$.join(`
65
+
66
+ ---
67
+
68
+ `):null},setError:(X)=>{Q(($)=>({spec:{...$.spec,error:X}}))},setLoading:(X)=>{Q(($)=>({spec:{...$.spec,isLoading:X}}))},reset:()=>{Q((X)=>({spec:{...zQ,actions:X.spec.actions}}))}}});var oQ=iQ()(lQ(cQ((...Q)=>({session:i(...Q),app:g(...Q),config:m(...Q),focus:r(...Q),command:d(...Q),spec:o(...Q)})),{name:"BladeStore",enabled:!0})),q=()=>oQ.getState(),iX=()=>q().session.actions,oX=()=>q().app.actions,nX=()=>q().session.messages,v=()=>q().config.config,I=null;async function sX(){if(v()!==null)return;if(I)return I;return I=(async()=>{try{let X=await KQ.getInstance().initialize();q().config.actions.setConfig(X)}catch(Z){throw I=null,Error(`[FAIL] Store 未初始化且无法自动初始化
69
+
70
+ `+`原因: ${Z instanceof Error?Z.message:"未知错误"}
71
+
72
+ `+`请确保:
73
+ `+`1. 配置文件格式正确 (~/.blade/config.json)
74
+ `+`2. 运行 blade 进行首次配置
75
+ `+"3. 配置文件权限正确")}finally{I=null}})(),I}var aX=()=>q().config.config?.models??[],tX=()=>{let Q=v();if(!Q)return;let Z=Q.currentModelId;return Q.models.find(($)=>$.id===Z)??Q.models[0]},eX=(Q)=>{let Z=v();if(!Z)return;return Z.models.find((X)=>X.id===Q)},QZ=()=>q().config.config?.mcpServers??{},XZ=()=>q().app.thinkingModeEnabled,ZZ=()=>({setPermissionMode:async(Q)=>{q().config.actions.updateConfig({permissionMode:Q})},setTheme:async(Q,Z={})=>{try{QQ.setTheme(Q)}catch{return}q().config.actions.updateConfig({theme:Q}),await A().save({theme:Q},{scope:"global",...Z})},setLanguage:async(Q,Z={})=>{q().config.actions.updateConfig({language:Q}),await A().save({language:Q},{scope:"global",...Z})},setDebug:async(Q,Z={})=>{q().config.actions.updateConfig({debug:Q}),await A().save({debug:Q},{scope:"global",...Z})},setTemperature:async(Q,Z={})=>{q().config.actions.updateConfig({temperature:Q}),await A().save({temperature:Q},{scope:"global",...Z})},updateConfig:async(Q,Z={})=>{let X=v();if(!X)throw Error("Config not initialized");let $={...X};q().config.actions.updateConfig(Q);try{await A().save(Q,Z)}catch(Y){throw q().config.actions.setConfig($),Y}},flush:async()=>{await A().flush()},appendPermissionAllowRule:async(Q,Z={})=>{let X=v();if(!X)throw Error("Config not initialized");let $=X.permissions?.allow||[];if(!$.includes(Q)){let Y=[...$,Q];q().config.actions.updateConfig({permissions:{...X.permissions,allow:Y}})}await A().appendPermissionRule(Q,Z)},appendLocalPermissionAllowRule:async(Q,Z={})=>{let X=v();if(!X)throw Error("Config not initialized");let $=X.permissions?.allow||[];if(!$.includes(Q)){let Y=[...$,Q];q().config.actions.updateConfig({permissions:{...X.permissions,allow:Y}})}await A().appendLocalPermissionRule(Q,Z)},setCurrentModel:async(Q,Z={})=>{let X=v();if(!X)throw Error("Config not initialized");if(!X.models.find((Y)=>Y.id===Q))throw Error(`Model not found: ${Q}`);q().config.actions.updateConfig({currentModelId:Q}),await A().save({currentModelId:Q},{scope:"global",...Z})},addModel:async(Q,Z={})=>{let X=v();if(!X)throw Error("Config not initialized");let $="id"in Q?Q:{id:rQ(),...Q},V={models:[...X.models,$]};if(X.models.length===0)V.currentModelId=$.id;return q().config.actions.updateConfig(V),await A().save(V,{scope:"global",...Z}),$},updateModel:async(Q,Z,X={})=>{let $=v();if(!$)throw Error("Config not initialized");let Y=$.models.findIndex((J)=>J.id===Q);if(Y===-1)throw Error(`Model not found: ${Q}`);let V=[...$.models];V[Y]={...V[Y],...Z},q().config.actions.updateConfig({models:V}),await A().save({models:V},{scope:"global",...X})},removeModel:async(Q,Z={})=>{let X=v();if(!X)throw Error("Config not initialized");if(X.models.length===1)throw Error("Cannot remove the only model");let $=X.models.filter((V)=>V.id!==Q),Y={models:$};if(X.currentModelId===Q)Y.currentModelId=$[0].id;q().config.actions.updateConfig(Y),await A().save(Y,{scope:"global",...Z})},addMcpServer:async(Q,Z,X={})=>{let $=v();if(!$)throw Error("Config not initialized");let V={...$.mcpServers??{},[Q]:Z};q().config.actions.updateConfig({mcpServers:V}),await A().save({mcpServers:V},{scope:"project",...X})},removeMcpServer:async(Q,Z={})=>{let X=v();if(!X)throw Error("Config not initialized");let Y={...X.mcpServers??{}};delete Y[Q],q().config.actions.updateConfig({mcpServers:Y}),await A().save({mcpServers:Y},{scope:"project",...Z})}});
76
+ export{a as ha,QQ as ia,W as ja,$X as ka,JX as la,UX as ma,GX as na,jX as oa,HX as pa,zX as qa,b as ra,OX as sa,N as ta,oQ as ua,q as va,iX as wa,oX as xa,nX as ya,v as za,sX as Aa,aX as Ba,tX as Ca,eX as Da,QZ as Ea,XZ as Fa,ZZ as Ga};
@@ -0,0 +1 @@
1
+ import{aa as a,ba as b,ca as c,da as d,ea as e,fa as f}from"./chunk-phzbecpx.js";import"./chunk-j2ag7hh6.js";export{b as getVersion,c as getPackageName,a as getPackageInfo,e as getFormattedVersion,d as getDescription,f as getCopyright};
@@ -0,0 +1,2 @@
1
+ import{realpathSync as G}from"fs";import{cwd as K}from"process";var D=null;function N(){let q="";if(typeof process<"u"&&typeof process.cwd==="function"&&typeof G==="function"){let F=K();try{q=G(F).normalize("NFC")}catch{q=F.normalize("NFC")}}return{cwd:q,originalCwd:q,projectRoot:q}}function B(){if(!D)D=N();return D}function H(){return B().cwd}function Z(q){B().cwd=q.normalize("NFC")}function J(){return B().originalCwd}function $(){return B().projectRoot}function b(q){B().projectRoot=q.normalize("NFC")}var Q;((x)=>{x.DEFAULT="default";x.AUTO_EDIT="autoEdit";x.YOLO="yolo";x.PLAN="plan";x.SPEC="spec"})(Q||={});import{AsyncLocalStorage as R}from"async_hooks";var U=new R;function V(){return U.getStore()??H()}function W(){try{return V()}catch{return J()}}
2
+ export{Z as sb,J as tb,$ as ub,b as vb,Q as wb,W as xb};
@@ -0,0 +1,13 @@
1
+ import{Y as O}from"./chunk-njy55zd2.js";import"./chunk-phzbecpx.js";import{Ea as J,Ga as L}from"./chunk-76emdpxa.js";import"./chunk-y5g06jmk.js";import"./chunk-yddnm9n2.js";import{xb as H}from"./chunk-7ycmx7c2.js";import"./chunk-set7v1rf.js";import"./chunk-j2ag7hh6.js";import P from"os";import E from"path";function _(q){return typeof q==="string"?q:void 0}function T(q){if(!Array.isArray(q))return;let z=[];for(let F of q)if(typeof F==="string")z.push(F);else if(F!=null)z.push(String(F));return z}function G(){console.log(`
2
+ blade mcp
3
+ `),console.log(`管理 MCP 服务器
4
+ `),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 字符串添加服务器
5
+ `),console.log("Options:"),console.log(` -h, --help 显示帮助信息 [boolean]
6
+ `),console.log("Examples:"),console.log(" blade mcp list"),console.log(" blade mcp add github npx -y @modelcontextprotocol/server-github"),console.log(" blade mcp add api --transport http http://localhost:3000"),console.log(` blade mcp remove github
7
+ `),console.log(`使用 blade mcp <command> --help 查看各子命令的详细帮助
8
+ `)}function b(q){return q.reduce((z,F)=>{let[K,...B]=F.split("=");return z[K]=B.join("="),z},{})}function R(q){return q.reduce((z,F)=>{let[K,...B]=F.split(":");return z[K.trim()]=B.join(":").trim(),z},{})}var M={command:"add <name> [commandOrUrl] [args...]",describe:"添加 MCP 服务器",builder:(q)=>{return q.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(q)=>{try{let{name:z,commandOrUrl:F,args:K,transport:B,env:Q,header:V,timeout:W}=q,Y=q.global===!0,$=_(z),Z=_(F),N=T(K)||[],k=T(Q),w=T(V),D=typeof W==="number"?W:void 0,I=B==="stdio"||B==="sse"||B==="http"?B:"stdio",x=q["--"];if(Array.isArray(x)&&x.length>0)Z=String(x[0]),N=x.slice(1).map((j)=>String(j));if(!$||!Z)console.error("Error: 缺少必需参数: name 和 commandOrUrl"),console.log(`
9
+ Tip: 用法:`),console.log(" blade mcp add <name> <command> [args...]"),console.log(" blade mcp add <name> -- <command> [args...]"),console.log(`
10
+ 示例:`),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 X={type:I};if(I==="stdio"){if(X.command=Z,X.args=N,k)X.env=b(k)}else if(X.url=Z,w)X.headers=R(w);if(D!==void 0)X.timeout=D;await L().addMcpServer($,X,{scope:Y?"global":"project"});let U=Y?E.join(P.homedir(),".blade","config.json"):E.join(H(),".blade","config.json");console.log(`MCP 服务器 "${$}" 已添加`),console.log(` 配置文件: ${U}`)}catch(z){console.error(`Error: 添加失败: ${z instanceof Error?z.message:"未知错误"}`),process.exit(1)}}},C={command:"remove <name>",describe:"删除 MCP 服务器",aliases:["rm"],builder:(q)=>{return q.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(q)=>{try{let z=J(),F=q.global===!0,K=_(q.name);if(!K)console.error("Error: 缺少必需参数: name"),process.exit(1);if(!z[K])console.error(`Error: 服务器 "${K}" 不存在`),process.exit(1);await L().removeMcpServer(K,{scope:F?"global":"project"}),console.log(`MCP 服务器 "${K}" 已删除`)}catch(z){console.error(`Error: 删除失败: ${z instanceof Error?z.message:"未知错误"}`),process.exit(1)}}},A={command:"list",describe:"列出所有 MCP 服务器并检查健康状态",aliases:["ls"],handler:async()=>{try{let q=J();if(console.log(""),Object.keys(q).length===0){console.log("暂无配置的 MCP 服务器");return}console.log(`检查 MCP 服务器健康状态...
11
+ `);let z=O.getInstance(),F=Object.entries(q).map(async([B,Q])=>{try{let V=z.getServerStatus(B);if(!V)await z.registerServer(B,Q),V=z.getServerStatus(B);else if(V.status==="disconnected")await z.connectServer(B);return{name:B,config:Q,serverInfo:V}}catch(V){return{name:B,config:Q,serverInfo:null,error:V}}}),K=await Promise.all(F);for(let{name:B,config:Q,serverInfo:V,error:W}of K){let Y=V?.status||"disconnected",$=Y==="connected"?"[OK]":"[FAIL]",Z=Y==="connected"?"Connected":"Failed";if(console.log(`${B}: ${Q.type==="stdio"?Q.command:Q.url} - ${$} ${Z}`),W&&Y!=="connected")console.log(` 错误: ${W instanceof Error?W.message:String(W)}`)}console.log("");for(let{name:B}of K)try{await z.unregisterServer(B)}catch(Q){}process.exit(0)}catch(q){console.error(`Error: 列表获取失败: ${q instanceof Error?q.message:"未知错误"}`),process.exit(1)}}},h={command:"get <name>",describe:"获取服务器详情",builder:(q)=>{return q.positional("name",{type:"string",describe:"服务器名称",demandOption:!0}).example([["$0 mcp get github","Get details of the specified server"]])},handler:async(q)=>{try{let z=J(),F=_(q.name);if(!F)console.error("Error: 缺少必需参数: name"),process.exit(1);let K=z[F];if(!K)console.error(`Error: 服务器 "${F}" 不存在`),process.exit(1);console.log(`
12
+ 服务器: ${F}
13
+ `),console.log(JSON.stringify(K,null,2))}catch(z){console.error(`Error: 获取失败: ${z instanceof Error?z.message:"未知错误"}`),process.exit(1)}}},d={command:"add-json <name> <json>",describe:"从 JSON 字符串添加服务器",builder:(q)=>{return q.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(q)=>{try{let z=_(q.json),F=_(q.name);if(!z||!F)throw Error("缺少必需参数: name 或 json");let K=JSON.parse(z),B=q.global===!0;if(!K.type)throw Error('配置必须包含 "type" 字段');await L().addMcpServer(F,K,{scope:B?"global":"project"});let Q=B?E.join(P.homedir(),".blade","config.json"):E.join(H(),".blade","config.json");console.log(`MCP 服务器 "${F}" 已添加`),console.log(` 配置文件: ${Q}`)}catch(z){console.error(`Error: 添加失败: ${z instanceof Error?z.message:"未知错误"}`),process.exit(1)}}},i={command:"mcp",describe:"管理 MCP 服务器",builder:(q)=>{return q.command(M).command(C).command(A).command(h).command(d).demandCommand(0).help(!1).option("help",{alias:"h",type:"boolean",describe:"显示帮助信息"})},handler:(q)=>{let z=["add","remove","list","ls","get","add-json"];if(!(Array.isArray(q._)?q._:[]).some((B)=>typeof B==="string"&&z.includes(B))||q.help)G(),process.exit(0)}};export{i as mcpCommands};
@@ -0,0 +1,49 @@
1
+ import{Ga as F,ra as $,ta as E,ua as q}from"./chunk-76emdpxa.js";import{Bb as w}from"./chunk-set7v1rf.js";import{nanoid as O}from"nanoid";var Z=w("Spec");class X{static instance=null;fileManager=null;constructor(){}static getInstance(){if(!X.instance)X.instance=new X;return X.instance}static resetInstance(){X.instance=null}getStoreState(){return q.getState().spec}updateStoreState(z){q.setState((B)=>({spec:{...B.spec,...z}}))}async initialize(z){if(this.fileManager){Z.debug("SpecManager already initialized, skipping...");return}this.fileManager=new E(z),await this.fileManager.initializeDirectories();let B=await this.fileManager.readSteeringContext();this.updateStoreState({steeringContext:B}),Z.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 z=this.getStoreState().steeringContext;if(!z)return null;let B=[];if(z.constitution)B.push(`## Constitution (Project Governance)
2
+
3
+ ${z.constitution}`);if(z.product)B.push(`## Product Vision
4
+
5
+ ${z.product}`);if(z.tech)B.push(`## Technology Stack
6
+
7
+ ${z.tech}`);if(z.structure)B.push(`## Code Structure
8
+
9
+ ${z.structure}`);return B.length>0?B.join(`
10
+
11
+ ---
12
+
13
+ `):null}async createSpec(z,B){let D=this.getFileManager();if(await D.changeExists(z))return{success:!1,message:`Spec "${z}" already exists`,error:"SPEC_EXISTS"};let K=await D.createChangeDir(z),J=D.createMetadata(z,B);await D.writeMetadata(z,J);let G=this.generateProposalTemplate(z,B);await D.writeSpecFile(z,"proposal",G);let U=this.getStoreState().recentSpecs.filter((Q)=>Q!==z);return U.unshift(z),this.updateStoreState({currentSpec:J,specPath:K,isActive:!0,recentSpecs:U.slice(0,10)}),{success:!0,message:`Spec "${z}" created successfully`,data:{spec:J,path:K}}}async loadSpec(z){let B=this.getFileManager(),D=await B.readMetadata(z);if(!D)return{success:!1,message:`Spec "${z}" not found`,error:"SPEC_NOT_FOUND"};let K=B.getChangePath(z),J=this.getStoreState().recentSpecs.filter((G)=>G!==z);return J.unshift(z),this.updateStoreState({currentSpec:D,specPath:K,isActive:!0,recentSpecs:J.slice(0,10)}),{success:!0,message:`Spec "${z}" loaded successfully`,data:{spec:D,path:K}}}closeSpec(){this.updateStoreState({currentSpec:null,specPath:null,isActive:!1})}exitSpecMode(){this.closeSpec()}async transitionPhase(z){let B=this.getCurrentSpec();if(!B)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};if(!$[B.phase].includes(z))return{success:!1,message:`Cannot transition from "${B.phase}" to "${z}"`,error:"INVALID_TRANSITION"};let J=await this.getFileManager().updatePhase(B.name,z);if(!J)return{success:!1,message:"Failed to update phase",error:"UPDATE_FAILED"};if(this.updateStoreState({currentSpec:J}),z==="done")try{await F().setPermissionMode("default"),Z.info("Spec 已完成,已自动退出 Spec 模式")}catch(G){Z.error("自动退出 Spec 模式失败:",G)}return{success:!0,message:`Transitioned to "${z}" phase`,data:{spec:J,phase:z}}}getAllowedTransitions(){let z=this.getCurrentSpec();if(!z)return[];return $[z.phase]}async addTask(z,B,D){let K=this.getCurrentSpec();if(!K)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let J={id:O(8),title:z,description:B,status:"pending",dependencies:D?.dependencies||[],affectedFiles:D?.affectedFiles||[],complexity:D?.complexity||"medium"},G={...K,tasks:[...K.tasks,J],updatedAt:new Date().toISOString()};return await this.getFileManager().writeMetadata(K.name,G),this.updateStoreState({currentSpec:G}),{success:!0,message:`Task "${z}" added`,data:{task:J}}}async updateTaskStatus(z,B){let D=this.getCurrentSpec();if(!D)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let K=D.tasks.find((Q)=>Q.id===z);if(!K)return{success:!1,message:`Task "${z}" not found`,error:"TASK_NOT_FOUND"};let J={...K,status:B,completedAt:B==="completed"?new Date().toISOString():K.completedAt},G=D.tasks.map((Q)=>Q.id===z?J:Q),U={...D,tasks:G,currentTaskId:B==="in_progress"?z:D.currentTaskId===z?void 0:D.currentTaskId,updatedAt:new Date().toISOString()};return await this.getFileManager().writeMetadata(D.name,U),this.updateStoreState({currentSpec:U}),{success:!0,message:`Task status updated to "${B}"`,data:{task:J}}}getNextTask(){let z=this.getCurrentSpec();if(!z)return null;return z.tasks.find((B)=>{if(B.status!=="pending")return!1;return B.dependencies.every((D)=>{return z.tasks.find((J)=>J.id===D)?.status==="completed"})})||null}getTaskProgress(){let z=this.getCurrentSpec();if(!z||z.tasks.length===0)return{total:0,completed:0,percentage:0};let B=z.tasks.length,D=z.tasks.filter((J)=>J.status==="completed").length,K=Math.round(D/B*100);return{total:B,completed:D,percentage:K}}async listSpecs(z){let B=this.getFileManager(),D=[],K=await B.listActiveChanges();for(let J of K){let G=await B.readMetadata(J);if(!G)continue;if(z?.phase&&G.phase!==z.phase)continue;if(z?.tags&&!z.tags.some((Q)=>G.tags?.includes(Q)))continue;if(z?.query&&!G.name.toLowerCase().includes(z.query.toLowerCase())&&!G.description.toLowerCase().includes(z.query.toLowerCase()))continue;let U=this.calculateTaskProgress(G.tasks);D.push({name:G.name,description:G.description,phase:G.phase,updatedAt:G.updatedAt,path:B.getChangePath(J),isArchived:!1,taskProgress:U})}if(z?.includeArchived){let J=await B.listArchivedChanges();for(let G of J)D.push({name:G,description:"(archived)",phase:"done",updatedAt:"",path:`${B.getArchiveDir()}/${G}`,isArchived:!0,taskProgress:{total:0,completed:0}})}return D.sort((J,G)=>{if(J.isArchived!==G.isArchived)return J.isArchived?1:-1;return new Date(G.updatedAt).getTime()-new Date(J.updatedAt).getTime()}),D}async archiveCurrentSpec(){let z=this.getCurrentSpec();if(!z)return{success:!1,message:"No active spec",error:"NO_ACTIVE_SPEC"};let B=this.getFileManager(),D=await B.mergeSpecDeltas(z.name);return await B.updatePhase(z.name,"done"),await B.archiveChange(z.name),this.closeSpec(),{success:!0,message:`Spec "${z.name}" archived successfully`,data:{spec:{...z,phase:"done"}}}}async validateCurrentSpec(){let z=this.getCurrentSpec();if(!z)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 B=this.getFileManager(),D=[],K=[],[J,G,U,Q,V]=await Promise.all([B.readSpecFile(z.name,"proposal"),B.readSpecFile(z.name,"spec"),B.readSpecFile(z.name,"requirements"),B.readSpecFile(z.name,"design"),B.readSpecFile(z.name,"tasks")]),Y={proposal:!!J,spec:!!G,requirements:!!U,design:!!Q,tasks:!!V};if(z.phase==="requirements"&&!Y.requirements)D.push({severity:"warning",file:"requirements",message:"Requirements document is missing"}),K.push("Generate requirements using EARS format");if(z.phase==="design"&&!Y.design)D.push({severity:"warning",file:"design",message:"Design document is missing"}),K.push("Create architecture diagrams and API contracts");if(z.phase==="tasks"&&z.tasks.length===0)D.push({severity:"warning",file:"tasks",message:"No tasks defined"}),K.push("Break down the spec into atomic tasks");if(z.phase==="implementation"){let W=this.getTaskProgress();if(W.completed<W.total)D.push({severity:"info",file:"tasks",message:`${W.total-W.completed} tasks remaining`})}return{valid:D.filter((W)=>W.severity==="error").length===0,phase:z.phase,completeness:Y,issues:D,suggestions:K}}buildProgressContext(){if(!this.isActive())return null;let z=this.getCurrentSpec();if(!z||z.phase!=="implementation")return null;let B=z.tasks;if(B.length===0)return null;let D=B.filter((V)=>V.status==="completed").length,K=B.filter((V)=>V.status==="skipped").length,J=B.length,G=z.currentTaskId?B.find((V)=>V.id===z.currentTaskId):B.find((V)=>V.status==="in_progress"),U=B.find((V)=>{if(V.status!=="pending")return!1;return V.dependencies.every((Y)=>{return B.find((H)=>H.id===Y)?.status==="completed"})}),Q=[`当前正在执行 Spec: ${z.name} (${z.phase} 阶段)`,`进度: ${D}/${J} 任务已完成${K>0?`,${K} 个已跳过`:""}`];if(G)Q.push(`当前任务: #${B.indexOf(G)+1} - ${G.title}${G.description?` (${G.description})`:""}`);if(U&&U!==G)Q.push(`下一个任务: #${B.indexOf(U)+1} - ${U.title}`);if(D+K>=J)Q.push("所有任务已完成,可以进入验证和归档阶段。");return Q.join(`
14
+ `)}generateProposalTemplate(z,B){return`# ${z}
15
+
16
+ ## Summary
17
+
18
+ ${B}
19
+
20
+ ## Background
21
+
22
+ <!-- Why is this change needed? What problem does it solve? -->
23
+
24
+ ## Goals
25
+
26
+ <!-- What are the specific objectives of this change? -->
27
+
28
+ - [ ] Goal 1
29
+ - [ ] Goal 2
30
+
31
+ ## Non-Goals
32
+
33
+ <!-- What is explicitly out of scope? -->
34
+
35
+ ## Risks and Mitigations
36
+
37
+ <!-- What could go wrong? How will you address it? -->
38
+
39
+ | Risk | Mitigation |
40
+ |------|------------|
41
+ | | |
42
+
43
+ ## Open Questions
44
+
45
+ <!-- What needs to be clarified before proceeding? -->
46
+
47
+ 1.
48
+ `}calculateTaskProgress(z){let B=z.length,D=z.filter((K)=>K.status==="completed").length;return{total:B,completed:D}}}
49
+ export{X as ga};
@@ -0,0 +1 @@
1
+ import{g as o}from"./chunk-qwfywxs2.js";import"./chunk-j2ag7hh6.js";import{execSync as r}from"child_process";var l={command:"update",describe:"Check for updates and install if available",handler:async()=>{console.log("Checking for updates...");try{let e=await o(!0);if(console.log(`Current version: ${e.currentVersion}`),e.error){console.log(`Warning: ${e.error}`);return}if(e.latestVersion)console.log(`Latest version: ${e.latestVersion}`);if(e.hasUpdate&&e.latestVersion){console.log(""),console.log(`\x1B[33mUpdate available: ${e.currentVersion} -> ${e.latestVersion}\x1B[0m`),console.log(""),console.log("Updating...");try{r("npm install -g blade-code@latest --registry https://registry.npmjs.org",{stdio:"inherit"}),console.log(""),console.log("Update complete!")}catch(t){console.error("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(e){console.error(`Error: Failed to check for updates: ${e instanceof Error?e.message:"未知错误"}`),process.exit(1)}}};export{l as updateCommands};
@@ -0,0 +1,6 @@
1
+ import{p as _,q as x,r as E,s as N}from"./chunk-hhnst8br.js";import{t as A}from"./chunk-1dvhq0mn.js";import{v as B,w as D,x as L}from"./chunk-jz59sjzb.js";import{G as $,M as b}from"./chunk-qbm9qrtg.js";import"./chunk-njy55zd2.js";import"./chunk-esnkk33h.js";import"./chunk-phzbecpx.js";import"./chunk-8jwqy5d0.js";import"./chunk-76emdpxa.js";import"./chunk-y5g06jmk.js";import{Sa as Z}from"./chunk-ehcjnwnr.js";import"./chunk-yddnm9n2.js";import"./chunk-094ekgv6.js";import"./chunk-5mtjqqav.js";import{wb as X,xb as Y}from"./chunk-7ycmx7c2.js";import"./chunk-set7v1rf.js";import"./chunk-j2ag7hh6.js";import f from"yargs";import{hideBin as h}from"yargs/helpers";var R=new Set(Object.values(X));function W(k){if(k&&R.has(k))return k;return}function w(k){return k.command("* [message]","Print response and exit (useful for pipes)",(F)=>F.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(F)=>{if(!F.p)return;let q=await M(F);process.exit(q)})}async function M(k,F=process){let q;try{await _();let J=await x({message:k.message,_:k._,defaultMessage:"Hello"}),G=await E(J);if(G.mode==="output"){if(G.content)F.stdout.write(`${G.content}
2
+ `);return G.exitCode??0}let Q=G.content,{sessionId:K,messages:T}=await N({sessionId:k.sessionId,continue:k.continue,resume:k.resume,fallbackSessionPrefix:"print"});q=await $.create({sessionId:K,modelId:k.model,mcpConfig:k.mcpConfig,strictMcpConfig:k.strictMcpConfig});let U=await b.createWithRuntime(q,{sessionId:K,systemPrompt:k.systemPrompt,appendSystemPrompt:k.appendSystemPrompt,maxTurns:k.maxTurns,modelId:k.model,permissionMode:W(k.permissionMode),toolWhitelist:k.allowedTools,toolBlacklist:k.disallowedTools,mcpConfig:k.mcpConfig,strictMcpConfig:k.strictMcpConfig}),H=(await Z(U.chatStream(Q,{messages:[...T],userId:"cli-user",sessionId:K,workspaceRoot:Y(),permissionMode:W(k.permissionMode)}))).finalMessage||"";if(k.outputFormat==="json")F.stdout.write(`${JSON.stringify({response:H,input:Q,model:k.model,timestamp:new Date().toISOString()},null,2)}
3
+ `);else if(k.outputFormat==="stream-json")F.stdout.write(`${JSON.stringify({type:"response",content:H})}
4
+ `);else F.stdout.write(`${H}
5
+ `);return 0}catch(J){return F.stderr.write(`Error: ${J instanceof Error?J.message:"未知错误"}
6
+ `),1}finally{await q?.dispose()}}async function m(){if(process.argv.slice(2).findIndex((q)=>q==="--print"||q==="-p")===-1)return!1;try{let{print:q,"output-format":J,"include-partial-messages":G,"input-format":Q,"system-prompt":K,"append-system-prompt":T,"max-turns":U,...V}=A,H=f(h(process.argv)).scriptName("blade").strict(!1).options(V).middleware([B,D,L]);return w(H),await H.parse(),!0}catch(q){console.error(`Print mode error: ${q instanceof Error?q.message:"未知错误"}`),process.exit(1)}}export{M as runPrint,m as handlePrintMode};