blade-code 0.7.0 → 0.7.1

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 (45) hide show
  1. package/dist/blade.js +2 -2
  2. package/dist/{chunk-x46rv9sv.js → chunk-0k8js58t.js} +1 -1
  3. package/dist/{chunk-fehae50v.js → chunk-0vd9antx.js} +1 -1
  4. package/dist/{chunk-96w1szbp.js → chunk-1dt2y16n.js} +1 -1
  5. package/dist/{chunk-kk8akm7s.js → chunk-2dvn9y9f.js} +1 -1
  6. package/dist/{chunk-sw6ngzbg.js → chunk-56frm8dx.js} +1 -1
  7. package/dist/{chunk-kpq18y6v.js → chunk-6jezjq4h.js} +1 -1
  8. package/dist/chunk-6k4vs71p.js +1 -0
  9. package/dist/chunk-70ya127f.js +1 -0
  10. package/dist/{chunk-c2b6ekqx.js → chunk-7v7s2aag.js} +1 -1
  11. package/dist/{chunk-wre40mf1.js → chunk-7ycmx7c2.js} +1 -1
  12. package/dist/{chunk-m22zeqdy.js → chunk-867h27ke.js} +2 -2
  13. package/dist/{chunk-v97f7je6.js → chunk-92qcc3gj.js} +246 -246
  14. package/dist/{chunk-gscq4fmx.js → chunk-a2nshjdc.js} +2 -2
  15. package/dist/{chunk-nsbhtvqd.js → chunk-a7dw8fwn.js} +1 -1
  16. package/dist/{chunk-2nnak657.js → chunk-a8eedntd.js} +1 -1
  17. package/dist/{chunk-pkzy724w.js → chunk-aam53te2.js} +2 -2
  18. package/dist/{chunk-q6c9qs9b.js → chunk-b0q2q0ax.js} +2 -2
  19. package/dist/{chunk-zmp3vdcj.js → chunk-bmxgshct.js} +1 -1
  20. package/dist/chunk-d3db8wrw.js +1 -0
  21. package/dist/chunk-dzmrdtpc.js +612 -0
  22. package/dist/{chunk-gertm8dw.js → chunk-e06p3dkw.js} +2 -2
  23. package/dist/{chunk-tn3xjczg.js → chunk-f8mjpmdx.js} +1 -1
  24. package/dist/{chunk-k4behavv.js → chunk-h7qab07x.js} +1 -1
  25. package/dist/{chunk-mnw1xcwn.js → chunk-k9h9bw13.js} +2 -2
  26. package/dist/chunk-m51xzgwt.js +1 -0
  27. package/dist/{chunk-6f63v1mk.js → chunk-qdnx9x5g.js} +2 -2
  28. package/dist/{chunk-rzz6r1g9.js → chunk-qds0yxfy.js} +2 -2
  29. package/dist/{chunk-e21htmg4.js → chunk-qyfdt8h1.js} +1 -1
  30. package/dist/{chunk-hscq9623.js → chunk-r6paqm6d.js} +1 -1
  31. package/dist/{chunk-vzebrztg.js → chunk-v0rjbvky.js} +1 -1
  32. package/dist/{chunk-gxnwrec6.js → chunk-v1d0d4b4.js} +2 -2
  33. package/dist/{chunk-93xhspe5.js → chunk-vs915jzz.js} +1 -1
  34. package/dist/{chunk-31chcjw6.js → chunk-xmdpc0y5.js} +2 -2
  35. package/dist/chunk-zbtb3jxm.js +1 -0
  36. package/dist/{chunk-pf33bn8s.js → chunk-zm4jr1k2.js} +1 -1
  37. package/dist/{chunk-ft5nt5b5.js → chunk-zvk6ktj1.js} +1 -1
  38. package/dist/{chunk-hc08zg54.js → chunk-zxddgwsb.js} +1 -1
  39. package/package.json +1 -1
  40. package/dist/chunk-64jv62vs.js +0 -1
  41. package/dist/chunk-p9s685ta.js +0 -1
  42. package/dist/chunk-phnararg.js +0 -1
  43. package/dist/chunk-ygta7118.js +0 -1
  44. package/dist/chunk-zd9stbct.js +0 -618
  45. package/dist/chunk-zjh9qqvq.js +0 -1
package/dist/blade.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{n as B}from"./chunk-pf33bn8s.js";import{aa as D,ba as F}from"./chunk-q6c9qs9b.js";import"./chunk-mnw1xcwn.js";import"./chunk-m22zeqdy.js";import"./chunk-rzz6r1g9.js";import{Cb as E,Eb as q}from"./chunk-wre40mf1.js";import{Nb as H}from"./chunk-mt1c5da4.js";import{Qb as J}from"./chunk-0afbeec0.js";var X=process.argv.slice(2),$=v(X),w=$!==null;if($!==null)H.setGlobalDebug($);function v(Q){for(let W=0;W<Q.length;W+=1){let T=Q[W];if(T==="--debug"||T==="-d"){let N=Q[W+1];return N&&!N.startsWith("-")?N:!0}if(T.startsWith("--debug="))return T.slice(8)||!0}return null}function C(Q){return Q.length===1&&(Q[0]==="--version"||Q[0]==="-V")}function z(Q,...W){return Q.some((T)=>W.some((N)=>T===N||T.startsWith(`${N}=`)))}async function f(){if(C(X)){let{getVersion:K}=await import("./chunk-64jv62vs.js");console.log(K());return}let Q=D(process.cwd());if(F(Q),E(q()),process.getuid&&process.getuid()===0){let K=!!process.env.SUDO_USER,U=!!process.env.BLADE_ALLOW_ROOT;if(K&&!U)console.error(""),console.error("Error: 请不要使用 sudo 运行 blade"),console.error(""),console.error("原因:"),console.error(" 使用 sudo 会创建属于 root 的配置文件,"),console.error(" 导致普通用户无法访问。"),console.error(""),console.error("正确用法:"),console.error(" blade # 直接运行,不要加 sudo"),console.error(""),console.error("如果遇到权限错误,请运行:"),console.error(" sudo chown -R $USER:$USER ~/.blade/"),console.error(""),console.error("如果你确实需要以 root 运行(容器/CI),设置环境变量:"),console.error(" BLADE_ALLOW_ROOT=1 blade"),console.error(""),process.exit(1)}if(z(X,"--headless")){let{handleHeadlessMode:K}=await import("./chunk-x46rv9sv.js");if(await K())return}if(B(),z(X,"--print","-p")){let{handlePrintMode:K}=await import("./chunk-2nnak657.js");if(await K())return}if(X.includes("--acp")){let{runAcpIntegration:K}=await import("./chunk-kpq18y6v.js");await K();return}let[{default:W},{hideBin:T},{cliConfig:N,globalOptions:G},{loadConfiguration:I,validateOutput:L,validatePermissions:M},{doctorCommands:_},{installCommands:y},{mcpCommands:R},{serveCommand:S},{updateCommands:k},{webCommand:O}]=await Promise.all([import("yargs"),import("yargs/helpers"),import("./chunk-p9s685ta.js"),import("./chunk-zjh9qqvq.js"),import("./chunk-hc08zg54.js"),import("./chunk-7z6ba6t9.js"),import("./chunk-zmp3vdcj.js"),import("./chunk-hscq9623.js"),import("./chunk-sw6ngzbg.js"),import("./chunk-kk8akm7s.js")]),x=W(T(process.argv)).scriptName(N.scriptName).usage(N.usage).version(N.version).locale(N.locale).showHelpOnFail(N.showHelpOnFail).demandCommand(0,"").recommendCommands().strict(N.strict).parserConfiguration({"populate--":!0}).options(G).middleware([I,M,L]).command(R).command(_).command(k).command(y).command(O).command(S).completion("completion",!1).help("help","Show help").alias("help","h").alias("version","V").fail((K,U,Z)=>{if(U){if(console.error("An error occurred:"),console.error(U.message),w&&U.stack)console.error(`
2
+ import{n as B}from"./chunk-zm4jr1k2.js";import{ba as D,ca as F}from"./chunk-b0q2q0ax.js";import"./chunk-k9h9bw13.js";import"./chunk-867h27ke.js";import"./chunk-qds0yxfy.js";import{vb as E,xb as q}from"./chunk-7ycmx7c2.js";import{Nb as H}from"./chunk-mt1c5da4.js";import{Qb as J}from"./chunk-0afbeec0.js";var X=process.argv.slice(2),$=v(X),w=$!==null;if($!==null)H.setGlobalDebug($);function v(Q){for(let W=0;W<Q.length;W+=1){let T=Q[W];if(T==="--debug"||T==="-d"){let N=Q[W+1];return N&&!N.startsWith("-")?N:!0}if(T.startsWith("--debug="))return T.slice(8)||!0}return null}function C(Q){return Q.length===1&&(Q[0]==="--version"||Q[0]==="-V")}function z(Q,...W){return Q.some((T)=>W.some((N)=>T===N||T.startsWith(`${N}=`)))}async function f(){if(C(X)){let{getVersion:K}=await import("./chunk-70ya127f.js");console.log(K());return}let Q=D(process.cwd());if(F(Q),E(q()),process.getuid&&process.getuid()===0){let K=!!process.env.SUDO_USER,U=!!process.env.BLADE_ALLOW_ROOT;if(K&&!U)console.error(""),console.error("Error: 请不要使用 sudo 运行 blade"),console.error(""),console.error("原因:"),console.error(" 使用 sudo 会创建属于 root 的配置文件,"),console.error(" 导致普通用户无法访问。"),console.error(""),console.error("正确用法:"),console.error(" blade # 直接运行,不要加 sudo"),console.error(""),console.error("如果遇到权限错误,请运行:"),console.error(" sudo chown -R $USER:$USER ~/.blade/"),console.error(""),console.error("如果你确实需要以 root 运行(容器/CI),设置环境变量:"),console.error(" BLADE_ALLOW_ROOT=1 blade"),console.error(""),process.exit(1)}if(z(X,"--headless")){let{handleHeadlessMode:K}=await import("./chunk-0k8js58t.js");if(await K())return}if(B(),z(X,"--print","-p")){let{handlePrintMode:K}=await import("./chunk-a8eedntd.js");if(await K())return}if(X.includes("--acp")){let{runAcpIntegration:K}=await import("./chunk-6jezjq4h.js");await K();return}let[{default:W},{hideBin:T},{cliConfig:N,globalOptions:G},{loadConfiguration:I,validateOutput:L,validatePermissions:M},{doctorCommands:_},{installCommands:y},{mcpCommands:R},{serveCommand:S},{updateCommands:k},{webCommand:O}]=await Promise.all([import("yargs"),import("yargs/helpers"),import("./chunk-zbtb3jxm.js"),import("./chunk-m51xzgwt.js"),import("./chunk-zxddgwsb.js"),import("./chunk-7z6ba6t9.js"),import("./chunk-bmxgshct.js"),import("./chunk-r6paqm6d.js"),import("./chunk-56frm8dx.js"),import("./chunk-2dvn9y9f.js")]),x=W(T(process.argv)).scriptName(N.scriptName).usage(N.usage).version(N.version).locale(N.locale).showHelpOnFail(N.showHelpOnFail).demandCommand(0,"").recommendCommands().strict(N.strict).parserConfiguration({"populate--":!0}).options(G).middleware([I,M,L]).command(R).command(_).command(k).command(y).command(O).command(S).completion("completion",!1).help("help","Show help").alias("help","h").alias("version","V").fail((K,U,Z)=>{if(U){if(console.error("An error occurred:"),console.error(U.message),w&&U.stack)console.error(`
3
3
  Stack trace:`),console.error(U.stack);else console.error(`
4
4
  Run with --debug to show the stack trace.`);process.exit(1)}if(K)console.error("Error: Invalid arguments:"),console.error(K),console.error(`
5
- Hint: Did you mean:`),Z.showHelp(),process.exit(1)}).command("$0",!1,()=>{},async(K)=>{let U=K._.slice(1),Z=U.length>0?U.join(" "):void 0,V=import("./chunk-phnararg.js").then(({checkVersionOnStartup:A})=>A()),[{render:b},{createElement:P},{AppWrapper:h}]=await Promise.all([import("ink"),import("react"),import("./chunk-gertm8dw.js")]),Y={...K,initialMessage:Z,debug:K.debug,print:Boolean(K.print),versionCheckPromise:V};delete Y._,delete Y.$0,delete Y.message,b(P(h,Y),{patchConsole:!0,exitOnCtrlC:!1,alternateBuffer:!1})});try{await x.parse()}catch(K){console.error("Error: Parse error:",K),process.exit(1)}}if(J.main==J.module)f().catch(console.error);export{f as main};
5
+ Hint: Did you mean:`),Z.showHelp(),process.exit(1)}).command("$0",!1,()=>{},async(K)=>{let U=K._.slice(1),Z=U.length>0?U.join(" "):void 0,V=import("./chunk-6k4vs71p.js").then(({checkVersionOnStartup:A})=>A()),[{render:b},{createElement:P},{AppWrapper:h}]=await Promise.all([import("ink"),import("react"),import("./chunk-e06p3dkw.js")]),Y={...K,initialMessage:Z,debug:K.debug,print:Boolean(K.print),versionCheckPromise:V};delete Y._,delete Y.$0,delete Y.message,b(P(h,Y),{patchConsole:!0,exitOnCtrlC:!1,alternateBuffer:!1})});try{await x.parse()}catch(K){console.error("Error: Parse error:",K),process.exit(1)}}if(J.main==J.module)f().catch(console.error);export{f as main};
@@ -1,4 +1,4 @@
1
- import{p as d,q as p,r as u,s as m}from"./chunk-tn3xjczg.js";import{t as c}from"./chunk-96w1szbp.js";import{v as z,w as g,x as v}from"./chunk-ft5nt5b5.js";import{y as h}from"./chunk-k4behavv.js";import{H as y,J as C,K as E,M as N,N as S}from"./chunk-v97f7je6.js";import"./chunk-e21htmg4.js";import"./chunk-pkzy724w.js";import"./chunk-q6c9qs9b.js";import"./chunk-31chcjw6.js";import"./chunk-gscq4fmx.js";import"./chunk-mnw1xcwn.js";import"./chunk-m22zeqdy.js";import{Za as F}from"./chunk-zd9stbct.js";import"./chunk-f76d6jxg.js";import"./chunk-rzz6r1g9.js";import"./chunk-vzebrztg.js";import{Db as O,Eb as w}from"./chunk-wre40mf1.js";import"./chunk-mt1c5da4.js";import"./chunk-0afbeec0.js";import bq from"yargs";import{hideBin as Dq}from"yargs/helpers";import{z as $}from"zod";import{z as Q}from"zod";var W=1,D=Q.object({event_version:Q.literal(W)}),o=D.extend({type:Q.literal("content_delta"),delta:Q.string()}),a=D.extend({type:Q.literal("thinking_delta"),delta:Q.string()}),e=D.extend({type:Q.literal("thinking"),content:Q.string()}),t=D.extend({type:Q.literal("stream_end")}),qq=D.extend({type:Q.literal("content"),content:Q.string()}),Gq=D.extend({type:Q.literal("tool_start"),tool_name:Q.string(),summary:Q.string(),target:Q.string().optional(),tool_kind:Q.enum(["readonly","write","execute"]).optional()}),Qq=D.extend({type:Q.literal("tool_result"),tool_name:Q.string(),summary:Q.string(),target:Q.string().optional(),tool_kind:Q.enum(["readonly","write","execute"]).optional(),success:Q.boolean().optional(),error_type:Q.string().optional(),error_message:Q.string().optional()}),Xq=D.extend({type:Q.literal("phase"),phase:Q.enum(["turn","searching","inspecting","target_hit","executing","completed"]),status:Q.enum(["ongoing","hit","done"]),message:Q.string(),turn:Q.number().optional(),tool_name:Q.string().optional(),target:Q.string().optional()}),Yq=D.extend({type:Q.literal("tool_detail"),tool_name:Q.string(),detail:Q.string()}),Zq=D.extend({type:Q.literal("task_update"),tasks:Q.array(N)}),$q=D.extend({type:Q.literal("token_usage"),input_tokens:Q.number(),output_tokens:Q.number(),total_tokens:Q.number(),max_context_tokens:Q.number()}),Uq=D.extend({type:Q.literal("compacting"),state:Q.enum(["started","completed"])}),Kq=D.extend({type:Q.literal("turn_limit"),turns_count:Q.number(),action:Q.literal("continue")}),Vq=D.extend({type:Q.literal("output"),content:Q.string(),exit_code:Q.number()}),_q=D.extend({type:Q.literal("error"),message:Q.string()}),Tq=Q.discriminatedUnion("type",[o,a,e,t,qq,Gq,Qq,Xq,Yq,Zq,$q,Uq,Kq,Vq,_q]);function k(G,Y){return{event_version:W,type:G,...Y}}function Aq(G){if(G?.signal)return{signal:G.signal,dispose:()=>{return}};let Y=new AbortController,Z=()=>Y.abort("interrupt");return process.once("SIGINT",Z),process.once("SIGTERM",Z),{signal:Y.signal,dispose:()=>{process.removeListener("SIGINT",Z),process.removeListener("SIGTERM",Z)}}}var Mq=$.enum(["text","jsonl"]),Rq=$.object({headless:$.boolean().optional(),message:$.string().optional(),_:$.array($.union([$.string(),$.number()])).optional(),model:$.string().optional(),systemPrompt:$.string().optional(),appendSystemPrompt:$.string().optional(),maxTurns:$.number().int().refine((G)=>G===-1||G>0,{message:"must be -1 or a positive integer"}).optional(),permissionMode:$.nativeEnum(O).optional(),mcpConfig:$.array($.string()).optional(),strictMcpConfig:$.boolean().optional(),sessionId:$.string().optional(),allowedTools:$.array($.string()).optional(),disallowedTools:$.array($.string()).optional(),agents:$.string().optional(),continue:$.boolean().optional(),resume:$.union([$.string(),$.boolean()]).optional(),forkSession:$.boolean().optional(),outputFormat:Mq.optional()});class l{openedThinking=!1;wroteAssistantContent=!1;markAssistantContent(){this.wroteAssistantContent=!0}setThinkingOpened(G){this.openedThinking=G}hasOpenThinking(){return this.openedThinking}completeStream(){let G={openedThinking:this.openedThinking,wroteAssistantContent:this.wroteAssistantContent};return this.openedThinking=!1,this.wroteAssistantContent=!1,G}}function jq(G){return G.issues.map((Y)=>`${Y.path.join(".")||"options"}: ${Y.message}`).join("; ")}function fq(G){let Y=Rq.safeParse(G);if(!Y.success)throw Error(`Invalid headless options: ${jq(Y.error)}`);return Y.data}function Bq(G){return G.command("* [message]","Run full agent loop without Ink UI and print events to the terminal",(Y)=>Y.positional("message",{describe:"Message to process",type:"string"}).option("headless",{type:"boolean",describe:"Run full agent loop without Ink UI and print events to the terminal"}).option("model",{describe:"Model ID for this run",type:"string"}).option("system-prompt",{describe:"Replace the default system prompt",type:"string"}).option("append-system-prompt",{describe:"Append a system prompt to 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"}).option("output-format",{alias:["outputFormat"],choices:["text","jsonl"],describe:"Headless output format",type:"string"}),async(Y)=>{if(!Y.headless)return;let Z=await Nq(Y);process.exit(Z)})}function A(G,Y=""){G.write(`${Y}
1
+ import{p as d,q as p,r as u,s as m}from"./chunk-f8mjpmdx.js";import{t as c}from"./chunk-1dt2y16n.js";import{v as z,w as g,x as v}from"./chunk-zvk6ktj1.js";import{y as h}from"./chunk-h7qab07x.js";import{H as y,J as C,K as E,M as N,N as S}from"./chunk-92qcc3gj.js";import"./chunk-a2nshjdc.js";import"./chunk-qyfdt8h1.js";import"./chunk-aam53te2.js";import"./chunk-b0q2q0ax.js";import"./chunk-k9h9bw13.js";import"./chunk-867h27ke.js";import"./chunk-xmdpc0y5.js";import{Za as F}from"./chunk-dzmrdtpc.js";import"./chunk-f76d6jxg.js";import"./chunk-qds0yxfy.js";import{wb as O,xb as w}from"./chunk-7ycmx7c2.js";import"./chunk-v0rjbvky.js";import"./chunk-mt1c5da4.js";import"./chunk-0afbeec0.js";import bq from"yargs";import{hideBin as Dq}from"yargs/helpers";import{z as $}from"zod";import{z as Q}from"zod";var W=1,D=Q.object({event_version:Q.literal(W)}),o=D.extend({type:Q.literal("content_delta"),delta:Q.string()}),a=D.extend({type:Q.literal("thinking_delta"),delta:Q.string()}),e=D.extend({type:Q.literal("thinking"),content:Q.string()}),t=D.extend({type:Q.literal("stream_end")}),qq=D.extend({type:Q.literal("content"),content:Q.string()}),Gq=D.extend({type:Q.literal("tool_start"),tool_name:Q.string(),summary:Q.string(),target:Q.string().optional(),tool_kind:Q.enum(["readonly","write","execute"]).optional()}),Qq=D.extend({type:Q.literal("tool_result"),tool_name:Q.string(),summary:Q.string(),target:Q.string().optional(),tool_kind:Q.enum(["readonly","write","execute"]).optional(),success:Q.boolean().optional(),error_type:Q.string().optional(),error_message:Q.string().optional()}),Xq=D.extend({type:Q.literal("phase"),phase:Q.enum(["turn","searching","inspecting","target_hit","executing","completed"]),status:Q.enum(["ongoing","hit","done"]),message:Q.string(),turn:Q.number().optional(),tool_name:Q.string().optional(),target:Q.string().optional()}),Yq=D.extend({type:Q.literal("tool_detail"),tool_name:Q.string(),detail:Q.string()}),Zq=D.extend({type:Q.literal("task_update"),tasks:Q.array(N)}),$q=D.extend({type:Q.literal("token_usage"),input_tokens:Q.number(),output_tokens:Q.number(),total_tokens:Q.number(),max_context_tokens:Q.number()}),Uq=D.extend({type:Q.literal("compacting"),state:Q.enum(["started","completed"])}),Kq=D.extend({type:Q.literal("turn_limit"),turns_count:Q.number(),action:Q.literal("continue")}),Vq=D.extend({type:Q.literal("output"),content:Q.string(),exit_code:Q.number()}),_q=D.extend({type:Q.literal("error"),message:Q.string()}),Tq=Q.discriminatedUnion("type",[o,a,e,t,qq,Gq,Qq,Xq,Yq,Zq,$q,Uq,Kq,Vq,_q]);function k(G,Y){return{event_version:W,type:G,...Y}}function Aq(G){if(G?.signal)return{signal:G.signal,dispose:()=>{return}};let Y=new AbortController,Z=()=>Y.abort("interrupt");return process.once("SIGINT",Z),process.once("SIGTERM",Z),{signal:Y.signal,dispose:()=>{process.removeListener("SIGINT",Z),process.removeListener("SIGTERM",Z)}}}var Mq=$.enum(["text","jsonl"]),Rq=$.object({headless:$.boolean().optional(),message:$.string().optional(),_:$.array($.union([$.string(),$.number()])).optional(),model:$.string().optional(),systemPrompt:$.string().optional(),appendSystemPrompt:$.string().optional(),maxTurns:$.number().int().refine((G)=>G===-1||G>0,{message:"must be -1 or a positive integer"}).optional(),permissionMode:$.nativeEnum(O).optional(),mcpConfig:$.array($.string()).optional(),strictMcpConfig:$.boolean().optional(),sessionId:$.string().optional(),allowedTools:$.array($.string()).optional(),disallowedTools:$.array($.string()).optional(),agents:$.string().optional(),continue:$.boolean().optional(),resume:$.union([$.string(),$.boolean()]).optional(),forkSession:$.boolean().optional(),outputFormat:Mq.optional()});class l{openedThinking=!1;wroteAssistantContent=!1;markAssistantContent(){this.wroteAssistantContent=!0}setThinkingOpened(G){this.openedThinking=G}hasOpenThinking(){return this.openedThinking}completeStream(){let G={openedThinking:this.openedThinking,wroteAssistantContent:this.wroteAssistantContent};return this.openedThinking=!1,this.wroteAssistantContent=!1,G}}function jq(G){return G.issues.map((Y)=>`${Y.path.join(".")||"options"}: ${Y.message}`).join("; ")}function fq(G){let Y=Rq.safeParse(G);if(!Y.success)throw Error(`Invalid headless options: ${jq(Y.error)}`);return Y.data}function Bq(G){return G.command("* [message]","Run full agent loop without Ink UI and print events to the terminal",(Y)=>Y.positional("message",{describe:"Message to process",type:"string"}).option("headless",{type:"boolean",describe:"Run full agent loop without Ink UI and print events to the terminal"}).option("model",{describe:"Model ID for this run",type:"string"}).option("system-prompt",{describe:"Replace the default system prompt",type:"string"}).option("append-system-prompt",{describe:"Append a system prompt to 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"}).option("output-format",{alias:["outputFormat"],choices:["text","jsonl"],describe:"Headless output format",type:"string"}),async(Y)=>{if(!Y.headless)return;let Z=await Nq(Y);process.exit(Z)})}function A(G,Y=""){G.write(`${Y}
2
2
  `)}function Iq(G){return`[task] [${G.status}] ${G.subject}`}function Jq(){return{requestConfirmation:async(G)=>({approved:!0,reason:"headless-auto-approved",scope:"session"})}}function xq(G){if(!(G instanceof Error))return"Unknown error";let q=G.lastError??G;if(q.responseBody)try{let V=JSON.parse(q.responseBody)?.error?.message;if(V)return q.statusCode?`${V} (HTTP ${q.statusCode})`:V}catch{}let X=G.message.match(/Last error:\s*(.+)$/);if(X)return X[1];return G.message}function Pq(G){return G==="jsonl"?"jsonl":"text"}function H(G,Y){let Z=(...q)=>{for(let X of q){let _=Y[X];if(typeof _==="string"&&_.trim()!=="")return _}return};switch(G){case"Read":case"Edit":case"Write":case"UndoEdit":return Z("file_path");case"NotebookEdit":return Z("notebook_path");case"Grep":return Z("path","pattern");case"Glob":return Z("pattern");case"WebFetch":return Z("url");case"WebSearch":return Z("query");case"Bash":return Z("command","description");case"Task":return Z("description");case"LSP":return Z("filePath","operation");case"EnterWorktree":return Z("name");case"ExitWorktree":return Z("action");default:return}}function Lq(G,Y,Z,q){let X=new Set(["Glob","Grep","WebSearch","LS"]),_=new Set(["Read","WebFetch"]);if(new Set(["Edit","Write","NotebookEdit","Bash","LSP","UndoEdit","EnterWorktree","ExitWorktree"]).has(G)&&!q.targetLocked)return{phase:"target_hit",status:"hit",message:`Target locked: ${Y}`,shouldLockTarget:!0};if(q.targetLocked)return{phase:"executing",status:"hit",message:Z?`Working within target: ${Y}`:`Executing: ${Y}`,shouldLockTarget:!1};if(X.has(G))return{phase:"searching",status:"ongoing",message:`Still searching: ${Y}`,shouldLockTarget:!1};if(_.has(G))return{phase:"inspecting",status:"ongoing",message:`Inspecting candidate: ${Y}`,shouldLockTarget:!1};return{phase:"executing",status:q.targetLocked?"hit":"ongoing",message:`Executing: ${Y}`,shouldLockTarget:!1}}function T(G,Y){let Z=(q,X)=>{G.stdout.write(`${JSON.stringify(k(q,X))}
3
3
  `)};return{contentDelta(q){if(Y==="jsonl"){Z("content_delta",{delta:q});return}G.stdout.write(q)},thinkingDelta(q,X){if(Y==="jsonl")return Z("thinking_delta",{delta:q}),X;if(!X)G.stderr.write("[thinking] ");return G.stderr.write(q),!0},thinking(q){if(Y==="jsonl"){Z("thinking",{content:q});return}A(G.stderr,`[thinking] ${q}`)},streamEnd(q,X){if(Y==="jsonl"){Z("stream_end",{});return}if(X)G.stderr.write(`
4
4
  `);if(q)G.stdout.write(`
@@ -1 +1 @@
1
- import{Aa as e,Ba as f,Ca as g,Da as h,Ea as i,Fa as j,Ga as k,Ha as l,Ia as m,wa as a,xa as b,ya as c,za as d}from"./chunk-mnw1xcwn.js";import"./chunk-m22zeqdy.js";import"./chunk-wre40mf1.js";import"./chunk-mt1c5da4.js";import"./chunk-0afbeec0.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};
1
+ import{Aa as k,Ba as l,Ca as m,qa as a,ra as b,sa as c,ta as d,ua as e,va as f,wa as g,xa as h,ya as i,za as j}from"./chunk-k9h9bw13.js";import"./chunk-867h27ke.js";import"./chunk-7ycmx7c2.js";import"./chunk-mt1c5da4.js";import"./chunk-0afbeec0.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};
@@ -1,2 +1,2 @@
1
- import{da as d,fa as h}from"./chunk-31chcjw6.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};
1
+ import{Ia as d,Ka as h}from"./chunk-xmdpc0y5.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
2
  export{q as t,w as u};
@@ -1,4 +1,4 @@
1
- import{a as Q,b as R,c as T,d as W}from"./chunk-6f63v1mk.js";import"./chunk-gxnwrec6.js";import"./chunk-v97f7je6.js";import"./chunk-e21htmg4.js";import"./chunk-pkzy724w.js";import"./chunk-q6c9qs9b.js";import{da as M}from"./chunk-31chcjw6.js";import"./chunk-gscq4fmx.js";import{Ca as J}from"./chunk-mnw1xcwn.js";import"./chunk-m22zeqdy.js";import"./chunk-zd9stbct.js";import"./chunk-f76d6jxg.js";import"./chunk-rzz6r1g9.js";import"./chunk-vzebrztg.js";import"./chunk-wre40mf1.js";import"./chunk-mt1c5da4.js";import"./chunk-0afbeec0.js";import b from"chalk";import H from"open";var $=`
1
+ import{f as Q,g as R,h as T,i as W}from"./chunk-qdnx9x5g.js";import"./chunk-v1d0d4b4.js";import"./chunk-92qcc3gj.js";import"./chunk-a2nshjdc.js";import"./chunk-qyfdt8h1.js";import"./chunk-aam53te2.js";import"./chunk-b0q2q0ax.js";import{wa as J}from"./chunk-k9h9bw13.js";import"./chunk-867h27ke.js";import{Ia as M}from"./chunk-xmdpc0y5.js";import"./chunk-dzmrdtpc.js";import"./chunk-f76d6jxg.js";import"./chunk-qds0yxfy.js";import"./chunk-7ycmx7c2.js";import"./chunk-v0rjbvky.js";import"./chunk-mt1c5da4.js";import"./chunk-0afbeec0.js";import b from"chalk";import H from"open";var $=`
2
2
  ____ _ _
3
3
  | __ )| | __ _ __| | ___
4
4
  | _ \\| |/ _\` |/ _\` |/ _ \\
@@ -1 +1 @@
1
- import{g as o}from"./chunk-c2b6ekqx.js";import"./chunk-0afbeec0.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};
1
+ import{a as o}from"./chunk-7v7s2aag.js";import"./chunk-0afbeec0.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};
@@ -1,4 +1,4 @@
1
- import{B as W,H as L,K as P,L as T,N as R,Q as U,T as M,V as h,W as j}from"./chunk-v97f7je6.js";import"./chunk-e21htmg4.js";import{_ as y}from"./chunk-pkzy724w.js";import"./chunk-q6c9qs9b.js";import"./chunk-31chcjw6.js";import"./chunk-gscq4fmx.js";import{Ba as A}from"./chunk-mnw1xcwn.js";import"./chunk-m22zeqdy.js";import{Za as f}from"./chunk-zd9stbct.js";import"./chunk-f76d6jxg.js";import"./chunk-rzz6r1g9.js";import"./chunk-vzebrztg.js";import{Eb as B}from"./chunk-wre40mf1.js";import{Ob as _}from"./chunk-mt1c5da4.js";import"./chunk-0afbeec0.js";import{Readable as v,Writable as c}from"node:stream";import*as w from"@agentclientprotocol/sdk";import{PROTOCOL_VERSION as u}from"@agentclientprotocol/sdk";import{nanoid as C}from"nanoid";import{nanoid as K}from"nanoid";var Y=_("Agent");function N(z){return Object.fromEntries(z.map((G)=>[G.name,G.value]))}function b(z){if("command"in z)return{type:"stdio",command:z.command,args:z.args,env:N(z.env)};return{type:z.type,url:z.url,headers:N(z.headers)}}function k(z){return Object.fromEntries(z.map((G)=>[G.name,b(G)]))}function S(z){if(typeof z==="string")return z?[{type:"text",text:z}]:[];return z.flatMap((G)=>{if(G.type==="text")return G.text?[{type:"text",text:G.text}]:[];let H=G.image_url.url,J=/^data:([^;,]+);base64,(.+)$/s.exec(H);if(!J)return[{type:"text",text:"[Image]"}];return[{type:"image",mimeType:J[1]??"image/png",data:J[2]??""}]})}class D{id;cwd;connection;clientCapabilities;options;agent=null;runtime=null;pendingPrompt=null;messages;mode="default";sessionApprovals=new Set;constructor(z,G,H,J,Q={}){this.id=z;this.cwd=G;this.connection=H;this.clientCapabilities=J;this.options=Q;this.messages=[...Q.initialMessages??[]]}async initialize(){Y.debug(`[AcpSession ${this.id}] Initializing...`),W.initializeSession(this.connection,this.id,this.clientCapabilities,this.cwd),Y.debug(`[AcpSession ${this.id}] ACP service context initialized`);let z=this.options.mcpServers?k(this.options.mcpServers):void 0;this.runtime=await L.create({sessionId:this.id,...z?{mcpServers:z}:{}}),this.agent=await R.createWithRuntime(this.runtime,{sessionId:this.id}),Y.debug(`[AcpSession ${this.id}] Agent created successfully`)}async replayHistory(){for(let z of this.messages){let G=z.role==="user"?"user_message_chunk":z.role==="assistant"?"agent_message_chunk":void 0;if(!G)continue;for(let H of S(z.content))await this.connection.sessionUpdate({sessionId:this.id,update:{sessionUpdate:G,content:H}})}}sendAvailableCommandsDelayed(){Y.debug(`[AcpSession ${this.id}] Scheduling available commands update (500ms delay)`),setTimeout(()=>{this.sendAvailableCommands()},500)}async handleSlashCommand(z,G){try{Y.debug(`[AcpSession ${this.id}] Executing slash command: ${z}`);let H={cwd:this.cwd,signal:G,acp:{sendMessage:(X)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:X}})},sendToolStart:(X,Z,E)=>{let $=`tool_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,F=this.mapToolKind(E);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:$,status:"in_progress",title:`${X}`,content:[{type:"content",content:{type:"text",text:JSON.stringify(Z,null,2)}}],kind:F})},sendToolResult:(X,Z)=>{if(Z.summary)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:Z.summary}})}}},J=await h(z,H),Q=J.content||J.message;if(Q)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:Q}});if(J.error)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`[FAIL] ${J.error}`}});return{stopReason:J.success?"end_turn":"cancelled"}}catch(H){return Y.error(`[AcpSession ${this.id}] Slash command error:`,H),this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`[FAIL] 命令执行失败: ${H instanceof Error?H.message:"未知错误"}`}}),{stopReason:"cancelled"}}}async sendAvailableCommands(){try{let z=j(),G=["model","permissions","theme","config","exit","ide"],J=z.filter((Q)=>!G.includes(Q.name)).map((Q)=>{let X;if(Q.usage){let Z=Q.usage.replace(/^\/\w+\s*/,"").trim();if(Z)X=Z}if(Q.aliases?.length){let Z=`Aliases: ${Q.aliases.join(", ")}`;X=X?`${X} | ${Z}`:Z}return{name:Q.name,description:Q.description,input:X?{hint:X}:void 0}});Y.info(`[AcpSession ${this.id}] Sending available commands: ${JSON.stringify(J.map((Q)=>Q.name))}`),this.sendUpdate({sessionUpdate:"available_commands_update",availableCommands:J}),Y.info(`[AcpSession ${this.id}] Sent ${J.length} available commands`)}catch(z){Y.error(`[AcpSession ${this.id}] Failed to send available commands:`,z)}}async prompt(z){W.setCurrentSession(this.id),this.pendingPrompt?.abort();let G=new AbortController;if(this.pendingPrompt=G,!this.agent)throw Error("Session not initialized");try{let H=this.resolvePrompt(z.prompt);if(Y.debug(`[AcpSession ${this.id}] Received prompt: ${H.slice(0,100)}...`),M(H))return await this.handleSlashCommand(H,G.signal);let J={sessionId:this.id,userId:"acp-user",workspaceRoot:this.cwd,messages:[...this.messages],signal:G.signal,permissionMode:this.mapModeToPermissionMode(),confirmationHandler:{requestConfirmation:async(Q)=>{return this.requestPermission(Q)}}};if(await f(this.agent.chatStream(H,J),async(Q)=>{switch(Q.kind){case"content_delta":this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:Q.delta}});break;case"thinking_delta":this.sendUpdate({sessionUpdate:"agent_thought_chunk",content:{type:"text",text:Q.delta}});break;case"tool_start":{let X=Q.toolCall,Z="function"in X?X.function.name:X.type,E=this.mapToolKind(Q.toolKind);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:X.id,status:"in_progress",title:`Executing ${Z}`,content:[],kind:E});break}case"tool_result":{let{toolCall:X,result:Z}=Q,E=[],$=Z.metadata;if($?.kind==="edit"&&typeof $.file_path==="string"&&typeof $.oldContent==="string"&&(typeof $.newContent==="string"||$.newContent===void 0))E.push({type:"diff",path:$.file_path,oldText:$.oldContent,newText:$.newContent??null});else{let V="function"in X?X.function.name:X.type,x=T(P(V,Z));E.push({type:"content",content:{type:"text",text:x}})}let F=Z.success?"completed":"failed";this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:X.id,status:F,content:E});break}case"task_update":this.sendPlanUpdate(Q.tasks);break;default:break}}),this.messages=[...J.messages],G.signal.aborted)return{stopReason:"cancelled"};return{stopReason:"end_turn"}}catch(H){if(G.signal.aborted||H instanceof Error&&H.name==="AbortError")return{stopReason:"cancelled"};throw Y.error(`[AcpSession ${this.id}] Prompt error:`,H),H}finally{if(this.pendingPrompt===G)this.pendingPrompt=null}}cancel(){if(Y.info(`[AcpSession ${this.id}] Cancel requested`),this.pendingPrompt)this.pendingPrompt.abort(),this.pendingPrompt=null,Y.info(`[AcpSession ${this.id}] Cancelled successfully`);else Y.warn(`[AcpSession ${this.id}] No pending prompt to cancel`)}async setMode(z){let G=["default","auto-edit","yolo","plan"];this.mode=G.includes(z)?z:"default",Y.info(`[AcpSession ${this.id}] Mode set to: ${this.mode}`),this.sendUpdate({sessionUpdate:"current_mode_update",currentModeId:this.mode})}mapModeToPermissionMode(){switch(this.mode){case"yolo":return"yolo";case"auto-edit":return"autoEdit";case"plan":return"plan";case"default":default:return"default"}}shouldAutoApprove(z){switch(this.mode){case"yolo":return!0;case"auto-edit":return z==="readonly"||z==="write";case"plan":return z==="readonly";case"default":default:return!1}}async setModel(z){if(Y.info(`[AcpSession ${this.id}] Model set to: ${z}`),this.pendingPrompt)throw Error("Cannot switch models while a prompt is active");if(!this.agent)throw Error("Session not initialized");await this.agent.switchModel(z)}async destroy(){if(this.cancel(),this.agent)await this.agent.destroy(),this.agent=null;if(this.runtime)await this.runtime.dispose(),this.runtime=null;W.destroySession(this.id),Y.debug(`[AcpSession ${this.id}] Destroyed`)}resolvePrompt(z){let G=[];for(let H of z)if(H.type==="text")G.push(H.text);else if(H.type==="image")G.push(`[Image: ${H.mimeType}]`);else if(H.type==="resource"){let J=H.resource;if("text"in J)G.push(`<file path="${J.uri}">
1
+ import{B as W,H as L,K as P,L as T,N as R,Q as U,T as M,V as h,W as j}from"./chunk-92qcc3gj.js";import"./chunk-a2nshjdc.js";import"./chunk-qyfdt8h1.js";import{$ as y}from"./chunk-aam53te2.js";import"./chunk-b0q2q0ax.js";import{va as A}from"./chunk-k9h9bw13.js";import"./chunk-867h27ke.js";import"./chunk-xmdpc0y5.js";import{Za as f}from"./chunk-dzmrdtpc.js";import"./chunk-f76d6jxg.js";import"./chunk-qds0yxfy.js";import{xb as B}from"./chunk-7ycmx7c2.js";import"./chunk-v0rjbvky.js";import{Ob as _}from"./chunk-mt1c5da4.js";import"./chunk-0afbeec0.js";import{Readable as v,Writable as c}from"node:stream";import*as w from"@agentclientprotocol/sdk";import{PROTOCOL_VERSION as u}from"@agentclientprotocol/sdk";import{nanoid as C}from"nanoid";import{nanoid as K}from"nanoid";var Y=_("Agent");function N(z){return Object.fromEntries(z.map((G)=>[G.name,G.value]))}function b(z){if("command"in z)return{type:"stdio",command:z.command,args:z.args,env:N(z.env)};return{type:z.type,url:z.url,headers:N(z.headers)}}function k(z){return Object.fromEntries(z.map((G)=>[G.name,b(G)]))}function S(z){if(typeof z==="string")return z?[{type:"text",text:z}]:[];return z.flatMap((G)=>{if(G.type==="text")return G.text?[{type:"text",text:G.text}]:[];let H=G.image_url.url,J=/^data:([^;,]+);base64,(.+)$/s.exec(H);if(!J)return[{type:"text",text:"[Image]"}];return[{type:"image",mimeType:J[1]??"image/png",data:J[2]??""}]})}class D{id;cwd;connection;clientCapabilities;options;agent=null;runtime=null;pendingPrompt=null;messages;mode="default";sessionApprovals=new Set;constructor(z,G,H,J,Q={}){this.id=z;this.cwd=G;this.connection=H;this.clientCapabilities=J;this.options=Q;this.messages=[...Q.initialMessages??[]]}async initialize(){Y.debug(`[AcpSession ${this.id}] Initializing...`),W.initializeSession(this.connection,this.id,this.clientCapabilities,this.cwd),Y.debug(`[AcpSession ${this.id}] ACP service context initialized`);let z=this.options.mcpServers?k(this.options.mcpServers):void 0;this.runtime=await L.create({sessionId:this.id,...z?{mcpServers:z}:{}}),this.agent=await R.createWithRuntime(this.runtime,{sessionId:this.id}),Y.debug(`[AcpSession ${this.id}] Agent created successfully`)}async replayHistory(){for(let z of this.messages){let G=z.role==="user"?"user_message_chunk":z.role==="assistant"?"agent_message_chunk":void 0;if(!G)continue;for(let H of S(z.content))await this.connection.sessionUpdate({sessionId:this.id,update:{sessionUpdate:G,content:H}})}}sendAvailableCommandsDelayed(){Y.debug(`[AcpSession ${this.id}] Scheduling available commands update (500ms delay)`),setTimeout(()=>{this.sendAvailableCommands()},500)}async handleSlashCommand(z,G){try{Y.debug(`[AcpSession ${this.id}] Executing slash command: ${z}`);let H={cwd:this.cwd,signal:G,acp:{sendMessage:(X)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:X}})},sendToolStart:(X,Z,E)=>{let $=`tool_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,F=this.mapToolKind(E);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:$,status:"in_progress",title:`${X}`,content:[{type:"content",content:{type:"text",text:JSON.stringify(Z,null,2)}}],kind:F})},sendToolResult:(X,Z)=>{if(Z.summary)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:Z.summary}})}}},J=await h(z,H),Q=J.content||J.message;if(Q)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:Q}});if(J.error)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`[FAIL] ${J.error}`}});return{stopReason:J.success?"end_turn":"cancelled"}}catch(H){return Y.error(`[AcpSession ${this.id}] Slash command error:`,H),this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`[FAIL] 命令执行失败: ${H instanceof Error?H.message:"未知错误"}`}}),{stopReason:"cancelled"}}}async sendAvailableCommands(){try{let z=j(),G=["model","permissions","theme","config","exit","ide"],J=z.filter((Q)=>!G.includes(Q.name)).map((Q)=>{let X;if(Q.usage){let Z=Q.usage.replace(/^\/\w+\s*/,"").trim();if(Z)X=Z}if(Q.aliases?.length){let Z=`Aliases: ${Q.aliases.join(", ")}`;X=X?`${X} | ${Z}`:Z}return{name:Q.name,description:Q.description,input:X?{hint:X}:void 0}});Y.info(`[AcpSession ${this.id}] Sending available commands: ${JSON.stringify(J.map((Q)=>Q.name))}`),this.sendUpdate({sessionUpdate:"available_commands_update",availableCommands:J}),Y.info(`[AcpSession ${this.id}] Sent ${J.length} available commands`)}catch(z){Y.error(`[AcpSession ${this.id}] Failed to send available commands:`,z)}}async prompt(z){W.setCurrentSession(this.id),this.pendingPrompt?.abort();let G=new AbortController;if(this.pendingPrompt=G,!this.agent)throw Error("Session not initialized");try{let H=this.resolvePrompt(z.prompt);if(Y.debug(`[AcpSession ${this.id}] Received prompt: ${H.slice(0,100)}...`),M(H))return await this.handleSlashCommand(H,G.signal);let J={sessionId:this.id,userId:"acp-user",workspaceRoot:this.cwd,messages:[...this.messages],signal:G.signal,permissionMode:this.mapModeToPermissionMode(),confirmationHandler:{requestConfirmation:async(Q)=>{return this.requestPermission(Q)}}};if(await f(this.agent.chatStream(H,J),async(Q)=>{switch(Q.kind){case"content_delta":this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:Q.delta}});break;case"thinking_delta":this.sendUpdate({sessionUpdate:"agent_thought_chunk",content:{type:"text",text:Q.delta}});break;case"tool_start":{let X=Q.toolCall,Z="function"in X?X.function.name:X.type,E=this.mapToolKind(Q.toolKind);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:X.id,status:"in_progress",title:`Executing ${Z}`,content:[],kind:E});break}case"tool_result":{let{toolCall:X,result:Z}=Q,E=[],$=Z.metadata;if($?.kind==="edit"&&typeof $.file_path==="string"&&typeof $.oldContent==="string"&&(typeof $.newContent==="string"||$.newContent===void 0))E.push({type:"diff",path:$.file_path,oldText:$.oldContent,newText:$.newContent??null});else{let V="function"in X?X.function.name:X.type,x=T(P(V,Z));E.push({type:"content",content:{type:"text",text:x}})}let F=Z.success?"completed":"failed";this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:X.id,status:F,content:E});break}case"task_update":this.sendPlanUpdate(Q.tasks);break;default:break}}),this.messages=[...J.messages],G.signal.aborted)return{stopReason:"cancelled"};return{stopReason:"end_turn"}}catch(H){if(G.signal.aborted||H instanceof Error&&H.name==="AbortError")return{stopReason:"cancelled"};throw Y.error(`[AcpSession ${this.id}] Prompt error:`,H),H}finally{if(this.pendingPrompt===G)this.pendingPrompt=null}}cancel(){if(Y.info(`[AcpSession ${this.id}] Cancel requested`),this.pendingPrompt)this.pendingPrompt.abort(),this.pendingPrompt=null,Y.info(`[AcpSession ${this.id}] Cancelled successfully`);else Y.warn(`[AcpSession ${this.id}] No pending prompt to cancel`)}async setMode(z){let G=["default","auto-edit","yolo","plan"];this.mode=G.includes(z)?z:"default",Y.info(`[AcpSession ${this.id}] Mode set to: ${this.mode}`),this.sendUpdate({sessionUpdate:"current_mode_update",currentModeId:this.mode})}mapModeToPermissionMode(){switch(this.mode){case"yolo":return"yolo";case"auto-edit":return"autoEdit";case"plan":return"plan";case"default":default:return"default"}}shouldAutoApprove(z){switch(this.mode){case"yolo":return!0;case"auto-edit":return z==="readonly"||z==="write";case"plan":return z==="readonly";case"default":default:return!1}}async setModel(z){if(Y.info(`[AcpSession ${this.id}] Model set to: ${z}`),this.pendingPrompt)throw Error("Cannot switch models while a prompt is active");if(!this.agent)throw Error("Session not initialized");await this.agent.switchModel(z)}async destroy(){if(this.cancel(),this.agent)await this.agent.destroy(),this.agent=null;if(this.runtime)await this.runtime.dispose(),this.runtime=null;W.destroySession(this.id),Y.debug(`[AcpSession ${this.id}] Destroyed`)}resolvePrompt(z){let G=[];for(let H of z)if(H.type==="text")G.push(H.text);else if(H.type==="image")G.push(`[Image: ${H.mimeType}]`);else if(H.type==="resource"){let J=H.resource;if("text"in J)G.push(`<file path="${J.uri}">
2
2
  ${J.text}
3
3
  </file>`)}else if(H.type==="resource_link")G.push(`[Resource: ${H.uri}]`);return G.join(`
4
4
  `)}sendUpdate(z){let G={sessionId:this.id,update:z};this.connection.sessionUpdate(G).catch((H)=>{Y.warn(`[AcpSession ${this.id}] Failed to send update:`,H)})}sendPlanUpdate(z){let G=z.map((H)=>({content:H.subject,priority:H.priority,status:H.status}));Y.debug(`[AcpSession ${this.id}] Sending plan update with ${G.length} entries`),this.sendUpdate({sessionUpdate:"plan",entries:G})}async requestPermission(z){let G=z.kind?.toLowerCase()||"execute";if(this.shouldAutoApprove(G))return Y.debug(`[AcpSession ${this.id}] Auto-approving ${G} in mode: ${this.mode}`),{approved:!0};if(this.mode==="plan"&&(G==="write"||G==="execute"))return Y.debug(`[AcpSession ${this.id}] Rejecting ${G} in plan mode`),{approved:!1,reason:"Write and execute operations are not allowed in Plan mode"};let H=`${G}:${z.title||"unknown"}`;if(this.sessionApprovals.has(H))return Y.debug(`[AcpSession ${this.id}] Using cached approval for: ${H}`),{approved:!0};try{let J=K(),Q=[];if(z.message)Q.push({type:"content",content:{type:"text",text:z.message}});if(z.risks&&z.risks.length>0)Q.push({type:"content",content:{type:"text",text:`Risks:
@@ -0,0 +1 @@
1
+ import{a,b,c,d,e}from"./chunk-7v7s2aag.js";import"./chunk-0afbeec0.js";export{b as setSkipUntilVersion,d as performUpgrade,c as getUpgradeCommand,e as checkVersionOnStartup,a as checkVersion};
@@ -0,0 +1 @@
1
+ import{Ha as a,Ia as b,Ja as c,Ka as d,La as e,Ma as f}from"./chunk-xmdpc0y5.js";import"./chunk-0afbeec0.js";export{b as getVersion,c as getPackageName,a as getPackageInfo,e as getFormattedVersion,d as getDescription,f as getCopyright};
@@ -1,2 +1,2 @@
1
1
  import{Qb as y}from"./chunk-0afbeec0.js";import*as j from"fs/promises";import*as $ from"path";import b from"semver";import{fileURLToPath as N}from"url";import{ProxyAgent as G,fetch as H}from"undici";function T(){return process.env.HTTPS_PROXY||process.env.HTTP_PROXY||process.env.https_proxy||process.env.http_proxy}function R(){let q=T();if(q)try{return new G(q)}catch(z){console.warn(`[proxyFetch] Invalid proxy URL: ${q}`)}return}async function K(q,z={}){let{timeout:W=30000,signal:Q,...B}=z;if(Q?.aborted)throw new DOMException("The operation was aborted.","AbortError");let J=R(),X=new AbortController,Y=!1,F=setTimeout(()=>{Y=!0,X.abort()},W),w=()=>X.abort();Q?.addEventListener("abort",w);try{let Z={method:B.method,headers:B.headers,body:B.body,signal:X.signal,dispatcher:J};return await H(q.toString(),Z)}catch(Z){if(Z instanceof Error&&Z.name==="AbortError"){if(Y)throw Error(`Request timeout after ${W}ms`);throw Z}throw Z}finally{clearTimeout(F),Q?.removeEventListener("abort",w)}}var D="blade-code",f="https://cdn.jsdelivr.net/npm/blade-code@latest/CHANGELOG.md",M=$.join(process.env.HOME||process.env.USERPROFILE||".",".blade"),S=$.join(M,"version-cache.json"),k=3600000,L=`https://registry.npmjs.org/${D}/latest`;async function x(){try{if(process.env.BLADE_VERSION)return process.env.BLADE_VERSION;let q=N(import.meta.url),z=$.dirname(q),W=[$.join(z,"..","..","package.json"),$.join(z,"..","package.json")];for(let Q of W)try{let B=await j.readFile(Q,"utf-8"),J=JSON.parse(B);if(J.name===D&&J.version)return J.version}catch{}return"unknown"}catch{return"unknown"}}async function I(){try{let q=await j.readFile(S,"utf-8"),z=JSON.parse(q);if(Date.now()-z.checkedAt<k)return z;return{...z,checkedAt:0}}catch{return null}}async function O(q){try{await j.mkdir(M,{recursive:!0,mode:493}),await j.writeFile(S,JSON.stringify(q,null,2))}catch{}}async function P(){try{let q=await K(L,{timeout:5000,headers:{Accept:"application/json"}});if(!q.ok)return null;return(await q.json()).version||null}catch{return null}}async function v(q=!1){let z=await x(),W=f;if(z==="unknown")return{currentVersion:z,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:W,error:"Unable to determine current version"};let Q=await I(),B=Q?.skipUntilVersion,J=null;if(!q&&Q&&Q.checkedAt>0)J=Q.latestVersion;else if(J=await P(),J)await O({latestVersion:J,checkedAt:Date.now(),skipUntilVersion:B});if(!J)return{currentVersion:z,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:W,error:"Unable to check for updates"};let X=b.gt(J,z),Y=X;if(X&&B)Y=b.gt(J,B);return{currentVersion:z,latestVersion:J,hasUpdate:X,shouldPrompt:Y,releaseNotesUrl:W}}async function u(q){let z=await I();await O({latestVersion:z?.latestVersion||q,checkedAt:z?.checkedAt||Date.now(),skipUntilVersion:q})}function g(){return`npm install -g ${D}@latest --registry https://registry.npmjs.org`}async function C(){let{spawn:q}=await import("child_process");return new Promise((z)=>{let W=g(),Q=q(W,{stdio:"inherit",shell:!0});Q.on("close",(B)=>{if(B===0)z({success:!0,message:"Upgrade successful! Please restart blade."});else z({success:!1,message:`Upgrade failed (exit code: ${B})`})}),Q.on("error",(B)=>{z({success:!1,message:`Upgrade failed: ${B.message}`})})})}async function d(){try{let q=await v();return q.shouldPrompt?q:null}catch{return null}}
2
- export{v as g,u as h,g as i,C as j,d as k};
2
+ export{v as a,u as b,g as c,C as d,d as e};
@@ -1,2 +1,2 @@
1
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 zb,J as Ab,$ as Bb,b as Cb,Q as Db,W as Eb};
2
+ export{Z as sb,J as tb,$ as ub,b as vb,Q as wb,W as xb};
@@ -1,4 +1,4 @@
1
- import{Eb as $}from"./chunk-wre40mf1.js";import{Ob as w}from"./chunk-mt1c5da4.js";var F={currentModelId:"",models:[],temperature:0,maxContextTokens:128000,maxOutputTokens:void 0,stream:!0,topP:0.9,topK:50,timeout:180000,theme:"dracula",uiTheme:"system",language:"zh-CN",fontSize:14,autoSaveSessions:!0,notifyBuild:!0,notifyErrors:!1,notifySounds:!1,privacyTelemetry:!1,privacyCrash:!0,debug:!1,mcpEnabled:!1,mcpServers:{},permissions:{allow:["Bash(pwd)","Bash(which *)","Bash(whoami)","Bash(hostname)","Bash(uname *)","Bash(date)","Bash(echo *)","Bash(ls *)","Bash(tree *)","Bash(git status)","Bash(git status -*)","Bash(git log *)","Bash(git diff *)","Bash(git show *)","Bash(git branch -* *)","Bash(git branch)","Bash(git tag -l *)","Bash(git tag --list *)","Bash(git stash list *)","Bash(git stash show *)","Bash(git rev-parse *)","Bash(git describe *)","Bash(git blame *)","Bash(git ls-files *)","Bash(git config --get *)","Bash(git config --list *)","Bash(git shortlog *)","Bash(git merge-base *)","Bash(git cat-file *)","Bash(git for-each-ref *)","Bash(git grep *)","Bash(git worktree list *)","Bash(git reflog show *)","Bash(git reflog)","Bash(git rev-list *)","Bash(git ls-remote *)","Bash(git remote -v)","Bash(git remote --verbose)","Bash(git remote)","Bash(gh pr view *)","Bash(gh pr list *)","Bash(gh pr diff *)","Bash(gh pr checks *)","Bash(gh pr status *)","Bash(gh issue view *)","Bash(gh issue list *)","Bash(gh issue status *)","Bash(gh run list *)","Bash(gh run view *)","Bash(gh repo view *)","Bash(gh auth status)","Bash(npm list *)","Bash(bun pm ls *)","Bash(npm view *)","Bash(npm outdated *)","Bash(pnpm list *)","Bash(yarn list *)","Bash(pip list *)","Bash(pip show *)"],ask:["Bash(curl *)","Bash(wget *)","Bash(aria2c *)","Bash(axel *)","Bash(rm -rf *)","Bash(rm -r *)","Bash(rm --recursive *)","Bash(nc *)","Bash(netcat *)","Bash(telnet *)","Bash(ncat *)"],deny:["Read(./.env)","Read(./.env.*)","Bash(rm -rf /)","Bash(rm -rf /*)","Bash(sudo *)","Bash(chmod 777 *)","Bash(bash *)","Bash(sh *)","Bash(zsh *)","Bash(fish *)","Bash(dash *)","Bash(eval *)","Bash(source *)","Bash(mkfs *)","Bash(fdisk *)","Bash(dd *)","Bash(format *)","Bash(parted *)","Bash(open http*)","Bash(open https*)","Bash(xdg-open http*)","Bash(xdg-open https*)"]},permissionMode:"default",hooks:{enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,PreToolUse:[],PostToolUse:[],PostToolUseFailure:[],PermissionRequest:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]},env:{},disableAllHooks:!1,maxTurns:-1};import{promises as T}from"fs";import{merge as _}from"lodash-es";import I from"os";import G from"path";var M={sonnet:"claude-sonnet-4-20250514",opus:"claude-opus-4-20250514",haiku:"claude-3-5-haiku-20241022",claude:"claude-sonnet-4-20250514",gpt4o:"gpt-4o",gpt4:"gpt-4o",o1:"o1",o3:"o3","o4-mini":"o4-mini",deepseek:"deepseek-chat","deepseek-v3":"deepseek-chat","deepseek-r1":"deepseek-reasoner","deepseek-v4":"deepseek-v4-0324",gemini:"gemini-2.5-pro",flash:"gemini-2.5-flash",qwen:"qwen3-235b-a22b","qwen-max":"qwen-max","qwen-plus":"qwen-plus"};function U(J){let q=J.toLowerCase().trim();return M[q]??J}class B{static instance=null;constructor(){}static getInstance(){if(!B.instance)B.instance=new B;return B.instance}static resetInstance(){B.instance=null}async initialize(J){try{let q=await this.loadConfigFiles(),H=await this.loadSettingsFiles(),K={...q,...H};if(J)K=this.mergeSettings(K,J);let Q=this.normalizeConfig(K),W={...F,...Q};if(this.resolveEnvInterpolation(W),process.env.BLADE_MODEL&&W.models?.length>0){let X=U(process.env.BLADE_MODEL),Y=W.models.find((Z)=>Z.id===X||Z.model===X||Z.id===process.env.BLADE_MODEL||Z.model===process.env.BLADE_MODEL);if(Y)W.currentModelId=Y.id}if(process.env.BLADE_API_KEY&&W.models?.length>0){let X=W.models.find((Y)=>Y.id===W.currentModelId);if(X)X.apiKey=process.env.BLADE_API_KEY}if(process.env.BLADE_BASE_URL&&W.models?.length>0){let X=W.models.find((Y)=>Y.id===W.currentModelId);if(X)X.baseUrl=process.env.BLADE_BASE_URL}if(process.env.BLADE_DEBUG)W.debug=process.env.BLADE_DEBUG==="1"||process.env.BLADE_DEBUG==="true"||process.env.BLADE_DEBUG;if(W.debug)console.log("[ConfigManager] Configuration loaded successfully");return W}catch(q){return console.error("[ConfigManager] Failed to initialize:",q),F}}async loadConfigFiles(){let J=G.join(I.homedir(),".blade","config.json"),q=G.join($(),".blade","config.json"),H={},K=await this.loadJsonFile(J);if(K)H={...H,...K};let Q=await this.loadJsonFile(q);if(Q){let W={...H.mcpServers||{},...Q.mcpServers||{}};if(H={...H,...Q},Object.keys(W).length>0)H.mcpServers=W}return H}async loadSettingsFiles(){let J=G.join(I.homedir(),".blade","settings.json"),q=G.join($(),".blade","settings.json"),H=G.join($(),".blade","settings.local.json"),K={},Q=await this.loadJsonFile(J);if(Q)K=this.mergeSettings(K,Q);let W=await this.loadJsonFile(q);if(W)K=this.mergeSettings(K,W);let X=await this.loadJsonFile(H);if(X)K=this.mergeSettings(K,X);return K}mergeSettings(J,q){let H={...JSON.parse(JSON.stringify(J)),...JSON.parse(JSON.stringify(q))};if(q.permissions)H.permissions={allow:Array.from(new Set([...J.permissions?.allow||[],...q.permissions.allow||[]])),ask:Array.from(new Set([...J.permissions?.ask||[],...q.permissions.ask||[]])),deny:Array.from(new Set([...J.permissions?.deny||[],...q.permissions.deny||[]]))};if(q.hooks)H.hooks=_({},H.hooks,q.hooks);if(q.env)H.env=_({},H.env,q.env);if(q.mcpServers)H.mcpServers={...H.mcpServers||{},...q.mcpServers};if(q.disableAllHooks!==void 0)H.disableAllHooks=q.disableAllHooks;if(q.permissionMode!==void 0)H.permissionMode=q.permissionMode;if(q.maxTurns!==void 0)H.maxTurns=q.maxTurns;return H}resolveEnvInterpolation(J){let q=/\$\{?([A-Z_][A-Z0-9_]*)(:-([^}]+))?\}?/g,H=(Q)=>{if(typeof Q==="string")return Q.replace(q,(W,X,Y,Z)=>{return process.env[X]||Z||W});if(Array.isArray(Q))return Q.map(H);if(typeof Q==="object"&&Q!==null){let W=Q;for(let[X,Y]of Object.entries(W))W[X]=H(Y);return W}return Q},K=J;for(let[Q,W]of Object.entries(K))K[Q]=H(W)}async loadJsonFile(J){try{if(await this.fileExists(J)){let q=await T.readFile(J,"utf-8");return JSON.parse(q)}}catch(q){console.warn(`[ConfigManager] Failed to load ${J}:`,q)}return null}async fileExists(J){try{return await T.access(J),!0}catch{return!1}}normalizeConfig(J){let q=JSON.parse(JSON.stringify(J)),H=(Q)=>Q.trim().replace(/^`|`$/g,""),K=(Q)=>{for(let[W,X]of Object.entries(Q))if(typeof X==="string")Q[W]=H(X);else if(Array.isArray(X))X.forEach((Y,Z)=>{if(typeof Y==="string")X[Z]=H(Y);else if(typeof Y==="object"&&Y!==null)K(Y)});else if(typeof X==="object"&&X!==null)K(X)};return K(q),q}validateConfig(J){let q=[],H=[];if(!J.models||J.models.length===0)q.push("没有可用的模型配置");if(J.models&&J.models.length>0){if(!J.currentModelId)q.push("未设置当前模型 ID");else if(!J.models.find((Q)=>Q.id===J.currentModelId))q.push(`当前模型 ID "${J.currentModelId}" 在 models 列表中不存在`);for(let K of J.models){let Q=`模型 "${K.name||K.id}"`;if(!K.apiKey)H.push(`${Q}: apiKey 为空`);if(!K.model)q.push(`${Q}: model 字段必填`);if(!K.provider)q.push(`${Q}: provider 字段必填`);if(K.baseUrl&&!K.baseUrl.startsWith("http"))H.push(`${Q}: baseUrl "${K.baseUrl}" 不是有效的 HTTP URL`)}}if(H.length>0)console.warn(`[ConfigManager] 配置警告:
1
+ import{xb as $}from"./chunk-7ycmx7c2.js";import{Ob as w}from"./chunk-mt1c5da4.js";var F={currentModelId:"",models:[],temperature:0,maxContextTokens:128000,maxOutputTokens:void 0,stream:!0,topP:0.9,topK:50,timeout:180000,theme:"dracula",uiTheme:"system",language:"zh-CN",fontSize:14,autoSaveSessions:!0,notifyBuild:!0,notifyErrors:!1,notifySounds:!1,privacyTelemetry:!1,privacyCrash:!0,debug:!1,mcpEnabled:!1,mcpServers:{},permissions:{allow:["Bash(pwd)","Bash(which *)","Bash(whoami)","Bash(hostname)","Bash(uname *)","Bash(date)","Bash(echo *)","Bash(ls *)","Bash(tree *)","Bash(git status)","Bash(git status -*)","Bash(git log *)","Bash(git diff *)","Bash(git show *)","Bash(git branch -* *)","Bash(git branch)","Bash(git tag -l *)","Bash(git tag --list *)","Bash(git stash list *)","Bash(git stash show *)","Bash(git rev-parse *)","Bash(git describe *)","Bash(git blame *)","Bash(git ls-files *)","Bash(git config --get *)","Bash(git config --list *)","Bash(git shortlog *)","Bash(git merge-base *)","Bash(git cat-file *)","Bash(git for-each-ref *)","Bash(git grep *)","Bash(git worktree list *)","Bash(git reflog show *)","Bash(git reflog)","Bash(git rev-list *)","Bash(git ls-remote *)","Bash(git remote -v)","Bash(git remote --verbose)","Bash(git remote)","Bash(gh pr view *)","Bash(gh pr list *)","Bash(gh pr diff *)","Bash(gh pr checks *)","Bash(gh pr status *)","Bash(gh issue view *)","Bash(gh issue list *)","Bash(gh issue status *)","Bash(gh run list *)","Bash(gh run view *)","Bash(gh repo view *)","Bash(gh auth status)","Bash(npm list *)","Bash(bun pm ls *)","Bash(npm view *)","Bash(npm outdated *)","Bash(pnpm list *)","Bash(yarn list *)","Bash(pip list *)","Bash(pip show *)"],ask:["Bash(curl *)","Bash(wget *)","Bash(aria2c *)","Bash(axel *)","Bash(rm -rf *)","Bash(rm -r *)","Bash(rm --recursive *)","Bash(nc *)","Bash(netcat *)","Bash(telnet *)","Bash(ncat *)"],deny:["Read(./.env)","Read(./.env.*)","Bash(rm -rf /)","Bash(rm -rf /*)","Bash(sudo *)","Bash(chmod 777 *)","Bash(bash *)","Bash(sh *)","Bash(zsh *)","Bash(fish *)","Bash(dash *)","Bash(eval *)","Bash(source *)","Bash(mkfs *)","Bash(fdisk *)","Bash(dd *)","Bash(format *)","Bash(parted *)","Bash(open http*)","Bash(open https*)","Bash(xdg-open http*)","Bash(xdg-open https*)"]},permissionMode:"default",hooks:{enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,PreToolUse:[],PostToolUse:[],PostToolUseFailure:[],PermissionRequest:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]},env:{},disableAllHooks:!1,maxTurns:-1};import{promises as T}from"fs";import{merge as _}from"lodash-es";import I from"os";import G from"path";var M={sonnet:"claude-sonnet-4-20250514",opus:"claude-opus-4-20250514",haiku:"claude-3-5-haiku-20241022",claude:"claude-sonnet-4-20250514",gpt4o:"gpt-4o",gpt4:"gpt-4o",o1:"o1",o3:"o3","o4-mini":"o4-mini",deepseek:"deepseek-chat","deepseek-v3":"deepseek-chat","deepseek-r1":"deepseek-reasoner","deepseek-v4":"deepseek-v4-0324",gemini:"gemini-2.5-pro",flash:"gemini-2.5-flash",qwen:"qwen3-235b-a22b","qwen-max":"qwen-max","qwen-plus":"qwen-plus"};function U(J){let q=J.toLowerCase().trim();return M[q]??J}class B{static instance=null;constructor(){}static getInstance(){if(!B.instance)B.instance=new B;return B.instance}static resetInstance(){B.instance=null}async initialize(J){try{let q=await this.loadConfigFiles(),H=await this.loadSettingsFiles(),K={...q,...H};if(J)K=this.mergeSettings(K,J);let Q=this.normalizeConfig(K),W={...F,...Q};if(this.resolveEnvInterpolation(W),process.env.BLADE_MODEL&&W.models?.length>0){let X=U(process.env.BLADE_MODEL),Y=W.models.find((Z)=>Z.id===X||Z.model===X||Z.id===process.env.BLADE_MODEL||Z.model===process.env.BLADE_MODEL);if(Y)W.currentModelId=Y.id}if(process.env.BLADE_API_KEY&&W.models?.length>0){let X=W.models.find((Y)=>Y.id===W.currentModelId);if(X)X.apiKey=process.env.BLADE_API_KEY}if(process.env.BLADE_BASE_URL&&W.models?.length>0){let X=W.models.find((Y)=>Y.id===W.currentModelId);if(X)X.baseUrl=process.env.BLADE_BASE_URL}if(process.env.BLADE_DEBUG)W.debug=process.env.BLADE_DEBUG==="1"||process.env.BLADE_DEBUG==="true"||process.env.BLADE_DEBUG;if(W.debug)console.log("[ConfigManager] Configuration loaded successfully");return W}catch(q){return console.error("[ConfigManager] Failed to initialize:",q),F}}async loadConfigFiles(){let J=G.join(I.homedir(),".blade","config.json"),q=G.join($(),".blade","config.json"),H={},K=await this.loadJsonFile(J);if(K)H={...H,...K};let Q=await this.loadJsonFile(q);if(Q){let W={...H.mcpServers||{},...Q.mcpServers||{}};if(H={...H,...Q},Object.keys(W).length>0)H.mcpServers=W}return H}async loadSettingsFiles(){let J=G.join(I.homedir(),".blade","settings.json"),q=G.join($(),".blade","settings.json"),H=G.join($(),".blade","settings.local.json"),K={},Q=await this.loadJsonFile(J);if(Q)K=this.mergeSettings(K,Q);let W=await this.loadJsonFile(q);if(W)K=this.mergeSettings(K,W);let X=await this.loadJsonFile(H);if(X)K=this.mergeSettings(K,X);return K}mergeSettings(J,q){let H={...JSON.parse(JSON.stringify(J)),...JSON.parse(JSON.stringify(q))};if(q.permissions)H.permissions={allow:Array.from(new Set([...J.permissions?.allow||[],...q.permissions.allow||[]])),ask:Array.from(new Set([...J.permissions?.ask||[],...q.permissions.ask||[]])),deny:Array.from(new Set([...J.permissions?.deny||[],...q.permissions.deny||[]]))};if(q.hooks)H.hooks=_({},H.hooks,q.hooks);if(q.env)H.env=_({},H.env,q.env);if(q.mcpServers)H.mcpServers={...H.mcpServers||{},...q.mcpServers};if(q.disableAllHooks!==void 0)H.disableAllHooks=q.disableAllHooks;if(q.permissionMode!==void 0)H.permissionMode=q.permissionMode;if(q.maxTurns!==void 0)H.maxTurns=q.maxTurns;return H}resolveEnvInterpolation(J){let q=/\$\{?([A-Z_][A-Z0-9_]*)(:-([^}]+))?\}?/g,H=(Q)=>{if(typeof Q==="string")return Q.replace(q,(W,X,Y,Z)=>{return process.env[X]||Z||W});if(Array.isArray(Q))return Q.map(H);if(typeof Q==="object"&&Q!==null){let W=Q;for(let[X,Y]of Object.entries(W))W[X]=H(Y);return W}return Q},K=J;for(let[Q,W]of Object.entries(K))K[Q]=H(W)}async loadJsonFile(J){try{if(await this.fileExists(J)){let q=await T.readFile(J,"utf-8");return JSON.parse(q)}}catch(q){console.warn(`[ConfigManager] Failed to load ${J}:`,q)}return null}async fileExists(J){try{return await T.access(J),!0}catch{return!1}}normalizeConfig(J){let q=JSON.parse(JSON.stringify(J)),H=(Q)=>Q.trim().replace(/^`|`$/g,""),K=(Q)=>{for(let[W,X]of Object.entries(Q))if(typeof X==="string")Q[W]=H(X);else if(Array.isArray(X))X.forEach((Y,Z)=>{if(typeof Y==="string")X[Z]=H(Y);else if(typeof Y==="object"&&Y!==null)K(Y)});else if(typeof X==="object"&&X!==null)K(X)};return K(q),q}validateConfig(J){let q=[],H=[];if(!J.models||J.models.length===0)q.push("没有可用的模型配置");if(J.models&&J.models.length>0){if(!J.currentModelId)q.push("未设置当前模型 ID");else if(!J.models.find((Q)=>Q.id===J.currentModelId))q.push(`当前模型 ID "${J.currentModelId}" 在 models 列表中不存在`);for(let K of J.models){let Q=`模型 "${K.name||K.id}"`;if(!K.apiKey)H.push(`${Q}: apiKey 为空`);if(!K.model)q.push(`${Q}: model 字段必填`);if(!K.provider)q.push(`${Q}: provider 字段必填`);if(K.baseUrl&&!K.baseUrl.startsWith("http"))H.push(`${Q}: baseUrl "${K.baseUrl}" 不是有效的 HTTP URL`)}}if(H.length>0)console.warn(`[ConfigManager] 配置警告:
2
2
  ${H.map((K)=>` ⚠ ${K}`).join(`
3
3
  `)}`);if(q.length>0)throw Error(`配置验证失败:
4
4
  ${q.map((K)=>` - ${K}`).join(`
@@ -23,4 +23,4 @@ ${q.map((K)=>` - ${K}`).join(`
23
23
  }
24
24
  ]
25
25
  }
26
- `)}}function j(J,q={}){let H={...J};if(q.debug!==void 0)H.debug=q.debug===""?!0:q.debug;if(q.model){if(!J.models.some((Q)=>Q.id===q.model))throw Error(`模型配置未找到: ${q.model}`);H.currentModelId=q.model}if(q.yolo===!0)H.permissionMode="yolo";else if(q.permissionMode!==void 0)H.permissionMode=q.permissionMode;if(q.maxTurns!==void 0)H.maxTurns=q.maxTurns;return H.systemPrompt=q.systemPrompt,H.appendSystemPrompt=q.appendSystemPrompt,H.model=q.model,H.resumeSessionId=q.sessionId,H.forkSession=q.forkSession,H.allowedTools=q.allowedTools,H.disallowedTools=q.disallowedTools,H.mcpConfigPaths=q.mcpConfig,H.strictMcpConfig=q.strictMcpConfig,H.addDirs=q.addDir,H.outputFormat=q.outputFormat,H.inputFormat=q.inputFormat,H.print=q.print,H.includePartialMessages=q.includePartialMessages,H.replayUserMessages=q.replayUserMessages,H.agentsConfig=q.agents,H.settingSources=q.settingSources,H}import{Mutex as A}from"async-mutex";import{merge as b}from"lodash-es";import{promises as N}from"node:fs";import E from"node:os";import V from"node:path";import x from"write-file-atomic";var L=w("Service"),R={models:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},currentModelId:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},temperature:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},maxContextTokens:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},maxOutputTokens:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},timeout:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},theme:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},uiTheme:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},language:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},debug:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},fontSize:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},autoSaveSessions:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},notifyBuild:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},notifyErrors:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},notifySounds:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},privacyTelemetry:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},privacyCrash:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},permissionMode:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},permissions:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!0},hooks:{target:"settings",defaultScope:"local",mergeStrategy:"deep-merge",persistable:!0},env:{target:"settings",defaultScope:"local",mergeStrategy:"deep-merge",persistable:!0},disableAllHooks:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!0},maxTurns:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!0},mcpServers:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},stream:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},topP:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},topK:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},mcpEnabled:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},systemPrompt:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},appendSystemPrompt:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},initialMessage:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},resumeSessionId:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},forkSession:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},allowedTools:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},disallowedTools:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},mcpConfigPaths:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},strictMcpConfig:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},addDirs:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},outputFormat:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},inputFormat:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},print:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},includePartialMessages:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},replayUserMessages:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},agentsConfig:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},settingSources:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1}},Hq=new Set(Object.entries(R).filter(([J,q])=>q.persistable).map(([J])=>J)),Jq=new Set(Object.entries(R).filter(([J,q])=>!q.persistable).map(([J])=>J));class z{static instance=null;pendingUpdates=new Map;timers=new Map;fileLocks=new Map;lastSaveError=null;debounceDelay=300;constructor(){}static getInstance(){if(!z.instance)z.instance=new z;return z.instance}static resetInstance(){if(z.instance)for(let J of z.instance.timers.values())clearTimeout(J);z.instance=null}async save(J,q={}){this.validatePersistableFields(J);let H=this.groupUpdatesByTarget(J,q.scope);if(q.immediate)await Promise.all(Array.from(H.entries()).map(([K,Q])=>this.flushTarget(K,Q)));else for(let[K,Q]of H)this.scheduleSave(K,Q)}async flush(){for(let q of this.timers.values())clearTimeout(q);this.timers.clear();let J=Array.from(this.pendingUpdates.entries()).map(([q,H])=>this.flushTarget(q,H));this.pendingUpdates.clear(),await Promise.all(J)}getLastSaveError(){return this.lastSaveError}clearLastSaveError(){this.lastSaveError=null}async appendPermissionRule(J,q={}){let H=q.scope??"local",K=this.resolveFilePath("settings",H);await this.flushTargetWithModifier(K,(Q)=>{let W=Q.permissions??{allow:[],ask:[],deny:[]},X={allow:this.dedupeArray([...W.allow||[],J]),ask:W.ask||[],deny:W.deny||[]};return{...Q,permissions:X}})}async appendLocalPermissionRule(J,q={}){await this.appendPermissionRule(J,{...q,scope:"local"})}validatePersistableFields(J){for(let q of Object.keys(J)){let H=R[q];if(!H)throw Error(`Unknown config field: ${q}`);if(!H.persistable)throw Error(`Field "${q}" is non-persistable and cannot be saved to config files. Non-persistable fields are runtime-only and only valid for the current session.`)}}groupUpdatesByTarget(J,q){let H=new Map;for(let[K,Q]of Object.entries(J)){let W=R[K];if(!W)continue;let X=q??W.defaultScope,Y=this.resolveFilePath(W.target,X);if(!H.has(Y))H.set(Y,{});H.get(Y)[K]=Q}return H}resolveFilePath(J,q){if(J==="config")return q==="global"?V.join(E.homedir(),".blade","config.json"):V.join($(),".blade","config.json");switch(q){case"local":return V.join($(),".blade","settings.local.json");case"project":return V.join($(),".blade","settings.json");case"global":return V.join(E.homedir(),".blade","settings.json");default:return V.join($(),".blade","settings.local.json")}}scheduleSave(J,q){let H=this.pendingUpdates.get(J)??{},K=this.mergePendingUpdates(H,q);this.pendingUpdates.set(J,K);let Q=this.timers.get(J);if(Q)clearTimeout(Q);let W=setTimeout(async()=>{let X=this.pendingUpdates.get(J);if(X){this.pendingUpdates.delete(J),this.timers.delete(J);try{await this.flushTarget(J,X),this.lastSaveError=null}catch(Y){let Z=Y instanceof Error?Y:Error(String(Y));this.lastSaveError=Z,L.error(`Failed to save config to ${J}:`,Z.message),L.error("Stack trace:",Z.stack)}}},this.debounceDelay);this.timers.set(J,W)}mergePendingUpdates(J,q){let H={...J};for(let[K,Q]of Object.entries(q)){let W=R[K];if(!W){H[K]=Q;continue}switch(W.mergeStrategy){case"replace":H[K]=Q;break;case"append-dedupe":this.applyAppendDedupe(H,K,Q);break;case"deep-merge":this.applyDeepMerge(H,K,Q);break}}return H}async flushTarget(J,q){let H=this.fileLocks.get(J);if(!H)H=new A,this.fileLocks.set(J,H);await H.runExclusive(async()=>{await this.performWrite(J,q)})}async flushTargetWithModifier(J,q){let H=this.fileLocks.get(J);if(!H)H=new A,this.fileLocks.set(J,H);await H.runExclusive(async()=>{await N.mkdir(V.dirname(J),{recursive:!0,mode:493});let K={};try{let W=await N.readFile(J,"utf-8");K=JSON.parse(W)}catch{K={}}let Q=q(K);await this.atomicWrite(J,Q)})}async performWrite(J,q){await N.mkdir(V.dirname(J),{recursive:!0,mode:493});let H={};try{let Q=await N.readFile(J,"utf-8");H=JSON.parse(Q)}catch{H={}}let K={...H};for(let[Q,W]of Object.entries(q)){let X=R[Q];if(!X){K[Q]=W;continue}switch(X.mergeStrategy){case"replace":K[Q]=W;break;case"append-dedupe":this.applyAppendDedupe(K,Q,W);break;case"deep-merge":this.applyDeepMerge(K,Q,W);break}}await this.atomicWrite(J,K)}applyAppendDedupe(J,q,H){if(q==="permissions"&&typeof H==="object"&&H!==null){let K=J[q]??{allow:[],ask:[],deny:[]},Q=H;J[q]={allow:this.dedupeArray([...K.allow||[],...Q.allow||[]]),ask:this.dedupeArray([...K.ask||[],...Q.ask||[]]),deny:this.dedupeArray([...K.deny||[],...Q.deny||[]])}}else if(Array.isArray(H)){let K=Array.isArray(J[q])?J[q]:[];J[q]=this.dedupeArray([...K,...H])}else J[q]=H}applyDeepMerge(J,q,H){if(typeof H==="object"&&H!==null&&!Array.isArray(H)){let K=typeof J[q]==="object"&&J[q]!==null?J[q]:{};J[q]=b({},K,H)}else J[q]=H}dedupeArray(J){return Array.from(new Set(J))}async atomicWrite(J,q){await x(J,JSON.stringify(q,null,2),{mode:384,encoding:"utf-8"})}}function S(){return z.getInstance()}export{F as Ja,B as Ka,j as La,S as Ma};
26
+ `)}}function j(J,q={}){let H={...J};if(q.debug!==void 0)H.debug=q.debug===""?!0:q.debug;if(q.model){if(!J.models.some((Q)=>Q.id===q.model))throw Error(`模型配置未找到: ${q.model}`);H.currentModelId=q.model}if(q.yolo===!0)H.permissionMode="yolo";else if(q.permissionMode!==void 0)H.permissionMode=q.permissionMode;if(q.maxTurns!==void 0)H.maxTurns=q.maxTurns;return H.systemPrompt=q.systemPrompt,H.appendSystemPrompt=q.appendSystemPrompt,H.model=q.model,H.resumeSessionId=q.sessionId,H.forkSession=q.forkSession,H.allowedTools=q.allowedTools,H.disallowedTools=q.disallowedTools,H.mcpConfigPaths=q.mcpConfig,H.strictMcpConfig=q.strictMcpConfig,H.addDirs=q.addDir,H.outputFormat=q.outputFormat,H.inputFormat=q.inputFormat,H.print=q.print,H.includePartialMessages=q.includePartialMessages,H.replayUserMessages=q.replayUserMessages,H.agentsConfig=q.agents,H.settingSources=q.settingSources,H}import{Mutex as A}from"async-mutex";import{merge as b}from"lodash-es";import{promises as N}from"node:fs";import E from"node:os";import V from"node:path";import x from"write-file-atomic";var L=w("Service"),R={models:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},currentModelId:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},temperature:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},maxContextTokens:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},maxOutputTokens:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},timeout:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},theme:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},uiTheme:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},language:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},debug:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},fontSize:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},autoSaveSessions:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},notifyBuild:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},notifyErrors:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},notifySounds:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},privacyTelemetry:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},privacyCrash:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},permissionMode:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},permissions:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!0},hooks:{target:"settings",defaultScope:"local",mergeStrategy:"deep-merge",persistable:!0},env:{target:"settings",defaultScope:"local",mergeStrategy:"deep-merge",persistable:!0},disableAllHooks:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!0},maxTurns:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!0},mcpServers:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!0},stream:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},topP:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},topK:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},mcpEnabled:{target:"config",defaultScope:"global",mergeStrategy:"replace",persistable:!1},systemPrompt:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},appendSystemPrompt:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},initialMessage:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},resumeSessionId:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},forkSession:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},allowedTools:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},disallowedTools:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},mcpConfigPaths:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},strictMcpConfig:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},addDirs:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},outputFormat:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},inputFormat:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},print:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},includePartialMessages:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},replayUserMessages:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},agentsConfig:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1},settingSources:{target:"settings",defaultScope:"local",mergeStrategy:"replace",persistable:!1}},Hq=new Set(Object.entries(R).filter(([J,q])=>q.persistable).map(([J])=>J)),Jq=new Set(Object.entries(R).filter(([J,q])=>!q.persistable).map(([J])=>J));class z{static instance=null;pendingUpdates=new Map;timers=new Map;fileLocks=new Map;lastSaveError=null;debounceDelay=300;constructor(){}static getInstance(){if(!z.instance)z.instance=new z;return z.instance}static resetInstance(){if(z.instance)for(let J of z.instance.timers.values())clearTimeout(J);z.instance=null}async save(J,q={}){this.validatePersistableFields(J);let H=this.groupUpdatesByTarget(J,q.scope);if(q.immediate)await Promise.all(Array.from(H.entries()).map(([K,Q])=>this.flushTarget(K,Q)));else for(let[K,Q]of H)this.scheduleSave(K,Q)}async flush(){for(let q of this.timers.values())clearTimeout(q);this.timers.clear();let J=Array.from(this.pendingUpdates.entries()).map(([q,H])=>this.flushTarget(q,H));this.pendingUpdates.clear(),await Promise.all(J)}getLastSaveError(){return this.lastSaveError}clearLastSaveError(){this.lastSaveError=null}async appendPermissionRule(J,q={}){let H=q.scope??"local",K=this.resolveFilePath("settings",H);await this.flushTargetWithModifier(K,(Q)=>{let W=Q.permissions??{allow:[],ask:[],deny:[]},X={allow:this.dedupeArray([...W.allow||[],J]),ask:W.ask||[],deny:W.deny||[]};return{...Q,permissions:X}})}async appendLocalPermissionRule(J,q={}){await this.appendPermissionRule(J,{...q,scope:"local"})}validatePersistableFields(J){for(let q of Object.keys(J)){let H=R[q];if(!H)throw Error(`Unknown config field: ${q}`);if(!H.persistable)throw Error(`Field "${q}" is non-persistable and cannot be saved to config files. Non-persistable fields are runtime-only and only valid for the current session.`)}}groupUpdatesByTarget(J,q){let H=new Map;for(let[K,Q]of Object.entries(J)){let W=R[K];if(!W)continue;let X=q??W.defaultScope,Y=this.resolveFilePath(W.target,X);if(!H.has(Y))H.set(Y,{});H.get(Y)[K]=Q}return H}resolveFilePath(J,q){if(J==="config")return q==="global"?V.join(E.homedir(),".blade","config.json"):V.join($(),".blade","config.json");switch(q){case"local":return V.join($(),".blade","settings.local.json");case"project":return V.join($(),".blade","settings.json");case"global":return V.join(E.homedir(),".blade","settings.json");default:return V.join($(),".blade","settings.local.json")}}scheduleSave(J,q){let H=this.pendingUpdates.get(J)??{},K=this.mergePendingUpdates(H,q);this.pendingUpdates.set(J,K);let Q=this.timers.get(J);if(Q)clearTimeout(Q);let W=setTimeout(async()=>{let X=this.pendingUpdates.get(J);if(X){this.pendingUpdates.delete(J),this.timers.delete(J);try{await this.flushTarget(J,X),this.lastSaveError=null}catch(Y){let Z=Y instanceof Error?Y:Error(String(Y));this.lastSaveError=Z,L.error(`Failed to save config to ${J}:`,Z.message),L.error("Stack trace:",Z.stack)}}},this.debounceDelay);this.timers.set(J,W)}mergePendingUpdates(J,q){let H={...J};for(let[K,Q]of Object.entries(q)){let W=R[K];if(!W){H[K]=Q;continue}switch(W.mergeStrategy){case"replace":H[K]=Q;break;case"append-dedupe":this.applyAppendDedupe(H,K,Q);break;case"deep-merge":this.applyDeepMerge(H,K,Q);break}}return H}async flushTarget(J,q){let H=this.fileLocks.get(J);if(!H)H=new A,this.fileLocks.set(J,H);await H.runExclusive(async()=>{await this.performWrite(J,q)})}async flushTargetWithModifier(J,q){let H=this.fileLocks.get(J);if(!H)H=new A,this.fileLocks.set(J,H);await H.runExclusive(async()=>{await N.mkdir(V.dirname(J),{recursive:!0,mode:493});let K={};try{let W=await N.readFile(J,"utf-8");K=JSON.parse(W)}catch{K={}}let Q=q(K);await this.atomicWrite(J,Q)})}async performWrite(J,q){await N.mkdir(V.dirname(J),{recursive:!0,mode:493});let H={};try{let Q=await N.readFile(J,"utf-8");H=JSON.parse(Q)}catch{H={}}let K={...H};for(let[Q,W]of Object.entries(q)){let X=R[Q];if(!X){K[Q]=W;continue}switch(X.mergeStrategy){case"replace":K[Q]=W;break;case"append-dedupe":this.applyAppendDedupe(K,Q,W);break;case"deep-merge":this.applyDeepMerge(K,Q,W);break}}await this.atomicWrite(J,K)}applyAppendDedupe(J,q,H){if(q==="permissions"&&typeof H==="object"&&H!==null){let K=J[q]??{allow:[],ask:[],deny:[]},Q=H;J[q]={allow:this.dedupeArray([...K.allow||[],...Q.allow||[]]),ask:this.dedupeArray([...K.ask||[],...Q.ask||[]]),deny:this.dedupeArray([...K.deny||[],...Q.deny||[]])}}else if(Array.isArray(H)){let K=Array.isArray(J[q])?J[q]:[];J[q]=this.dedupeArray([...K,...H])}else J[q]=H}applyDeepMerge(J,q,H){if(typeof H==="object"&&H!==null&&!Array.isArray(H)){let K=typeof J[q]==="object"&&J[q]!==null?J[q]:{};J[q]=b({},K,H)}else J[q]=H}dedupeArray(J){return Array.from(new Set(J))}async atomicWrite(J,q){await x(J,JSON.stringify(q,null,2),{mode:384,encoding:"utf-8"})}}function S(){return z.getInstance()}export{F as Da,B as Ea,j as Fa,S as Ga};