blade-code 0.10.82 → 0.10.83

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 (102) hide show
  1. package/dist/blade.js +2 -2
  2. package/dist/{chunk-shq0pkxq.js → chunk-01zar8q6.js} +1 -1
  3. package/dist/{chunk-33bpwkyk.js → chunk-0q5bz3nm.js} +2 -2
  4. package/dist/{chunk-bpgyafzm.js → chunk-1htd858b.js} +2 -2
  5. package/dist/{chunk-zkhb55jz.js → chunk-272swnyr.js} +1 -1
  6. package/dist/chunk-2b7zryg3.js +118 -0
  7. package/dist/chunk-3p808rrt.js +1 -0
  8. package/dist/{chunk-mygw13zd.js → chunk-44dzrn0p.js} +1 -1
  9. package/dist/chunk-4pksah0q.js +1 -0
  10. package/dist/{chunk-3e0dry5e.js → chunk-4rq0jhf4.js} +3 -3
  11. package/dist/{chunk-n57jybv7.js → chunk-69rpb78b.js} +1 -1
  12. package/dist/{chunk-h0fh3j9w.js → chunk-6jsmac0q.js} +1 -1
  13. package/dist/{chunk-6at3v7hd.js → chunk-73j10ezs.js} +2 -2
  14. package/dist/chunk-7jp7e0zj.js +1 -0
  15. package/dist/{chunk-pfvgkexe.js → chunk-7m5q8vxf.js} +1 -1
  16. package/dist/{chunk-b9nhnzaj.js → chunk-7rfhmbqw.js} +1 -1
  17. package/dist/{chunk-qka2h00j.js → chunk-8215sm79.js} +12 -11
  18. package/dist/{chunk-sj0k8cdf.js → chunk-83caxxbt.js} +1 -1
  19. package/dist/{chunk-877traav.js → chunk-a14vnxrf.js} +1 -1
  20. package/dist/{chunk-bb1d4r3r.js → chunk-aqkexfag.js} +1 -1
  21. package/dist/{chunk-seamt0j3.js → chunk-b2p9qm6j.js} +2 -2
  22. package/dist/chunk-bd5e1n5z.js +1 -0
  23. package/dist/{chunk-6v2eawp6.js → chunk-cchk5xrs.js} +1 -1
  24. package/dist/{chunk-skw3b17a.js → chunk-d2pwwdab.js} +1 -1
  25. package/dist/chunk-d4k4v959.js +1 -0
  26. package/dist/{chunk-091qx62q.js → chunk-e1ry8aj5.js} +1 -1
  27. package/dist/{chunk-b9vm7gns.js → chunk-ffa6hhee.js} +2 -2
  28. package/dist/{chunk-8gfwva8m.js → chunk-fkwfymb6.js} +4 -4
  29. package/dist/{chunk-411ewxte.js → chunk-fs9j9gas.js} +2 -2
  30. package/dist/{chunk-jdb2mwbn.js → chunk-fv8b98tz.js} +2 -2
  31. package/dist/{chunk-e0ebj41c.js → chunk-g832dwdm.js} +2 -2
  32. package/dist/{chunk-c9e0fbyh.js → chunk-g9xjcfrf.js} +1 -1
  33. package/dist/{chunk-1mc7nfb4.js → chunk-gd2sw9zm.js} +1 -1
  34. package/dist/chunk-hg8d4vhj.js +2 -0
  35. package/dist/{chunk-eeb2945p.js → chunk-hjr9r44k.js} +1 -1
  36. package/dist/chunk-hqsqk5dp.js +1 -0
  37. package/dist/{chunk-fsm3fb2m.js → chunk-jf4bxxyf.js} +1 -1
  38. package/dist/{chunk-gre57x9m.js → chunk-jndq361v.js} +1 -1
  39. package/dist/chunk-js3j00ka.js +1 -0
  40. package/dist/{chunk-htsrecy5.js → chunk-k50z8903.js} +1 -1
  41. package/dist/{chunk-3kggy7we.js → chunk-m0a75642.js} +1 -1
  42. package/dist/{chunk-h6a0nct6.js → chunk-m5f934fh.js} +1 -1
  43. package/dist/chunk-mbt25rs5.js +1 -0
  44. package/dist/{chunk-5nfc0j4f.js → chunk-mgtcjwhy.js} +2 -2
  45. package/dist/{chunk-217cy9g5.js → chunk-mq2nx77s.js} +2 -2
  46. package/dist/{chunk-pajdvkxa.js → chunk-p9a3d507.js} +1 -1
  47. package/dist/{chunk-gdxm7yz5.js → chunk-q14mgye7.js} +2 -2
  48. package/dist/chunk-qb242y47.js +1 -0
  49. package/dist/{chunk-25yvyn7q.js → chunk-r4mjdkzv.js} +1 -1
  50. package/dist/{chunk-vpcpcwyq.js → chunk-r51ds5qw.js} +2 -2
  51. package/dist/{chunk-jwx10h5z.js → chunk-r77pcb0f.js} +2 -2
  52. package/dist/chunk-rmqksw1e.js +1 -0
  53. package/dist/{chunk-0a0sj79a.js → chunk-rwvaapta.js} +2 -2
  54. package/dist/{chunk-0141jad7.js → chunk-sb84vdcf.js} +1 -1
  55. package/dist/{chunk-0ra945vt.js → chunk-shr5cg46.js} +2 -2
  56. package/dist/{chunk-qxn5bg5k.js → chunk-sk8h4m9m.js} +1 -1
  57. package/dist/{chunk-h3w814js.js → chunk-skg520wq.js} +2 -2
  58. package/dist/{chunk-jzvbjn6e.js → chunk-sr4zv59p.js} +1 -1
  59. package/dist/{chunk-5nezhmnq.js → chunk-t1633e8m.js} +2 -2
  60. package/dist/{chunk-sghq0p21.js → chunk-t5ysd5z8.js} +1 -1
  61. package/dist/{chunk-cvy0pd00.js → chunk-t6phsb5h.js} +2 -2
  62. package/dist/{chunk-ky9q53m7.js → chunk-tpxs85cg.js} +1 -1
  63. package/dist/chunk-w2sb1hy9.js +1 -0
  64. package/dist/{chunk-7nx0pzfk.js → chunk-ww51801m.js} +1 -1
  65. package/dist/chunk-x2rraka3.js +1 -0
  66. package/dist/{chunk-n94a42wh.js → chunk-xepdd9yj.js} +1 -1
  67. package/dist/chunk-xj65p2sn.js +1 -0
  68. package/dist/chunk-xp3ad15c.js +10 -0
  69. package/dist/{chunk-rkp180w6.js → chunk-xy67pj74.js} +325 -320
  70. package/dist/{chunk-bhe154zk.js → chunk-xzgqyzmy.js} +52 -52
  71. package/dist/chunk-znhjr51w.js +1 -0
  72. package/dist/chunk-zp27f256.js +6 -0
  73. package/dist/web/assets/{ChatView-tu6nu0Yw.js → ChatView-DRn47Y3l.js} +3 -3
  74. package/dist/web/assets/{CodeBlockHighlighter-DFj0ZWq6.js → CodeBlockHighlighter-DxATdO6i.js} +1 -1
  75. package/dist/web/assets/{FilePreview-CLJNHlXO.js → FilePreview-D21mo4fn.js} +1 -1
  76. package/dist/web/assets/{KanbanBoard-B63UlcNr.js → KanbanBoard-DEUuLh0H.js} +1 -1
  77. package/dist/web/assets/{MarkdownRenderer-D7ap0LLK.js → MarkdownRenderer-BA9VgOyM.js} +3 -3
  78. package/dist/web/assets/{SettingsModal-B8Gp0bXw.js → SettingsModal-CXq3qDgQ.js} +1 -1
  79. package/dist/web/assets/{TaskSwitcher-gxALR-zu.js → TaskSwitcher-CUcZEUQH.js} +1 -1
  80. package/dist/web/assets/{TerminalPanel-dnC4oh4w.js → TerminalPanel-CcC6f3H_.js} +1 -1
  81. package/dist/web/assets/{index-Dn4vZglG.js → index-CfVQVVVI.js} +3 -3
  82. package/dist/web/assets/{teamService-CoJLtqAq.js → teamService-BX1zdQBb.js} +1 -1
  83. package/dist/web/index.html +1 -1
  84. package/package.json +1 -1
  85. package/dist/chunk-0wk1byp5.js +0 -1
  86. package/dist/chunk-3n08j1xh.js +0 -1
  87. package/dist/chunk-4mpwdcfd.js +0 -10
  88. package/dist/chunk-6adxyred.js +0 -1
  89. package/dist/chunk-7t41dza5.js +0 -1
  90. package/dist/chunk-c3vqqs0r.js +0 -1
  91. package/dist/chunk-gn6ftvjy.js +0 -1
  92. package/dist/chunk-gw1za0rb.js +0 -1
  93. package/dist/chunk-h9xayrwp.js +0 -1
  94. package/dist/chunk-jdzgkdse.js +0 -1
  95. package/dist/chunk-kpfbbh24.js +0 -1
  96. package/dist/chunk-m0dt3w7w.js +0 -112
  97. package/dist/chunk-ndnjmy45.js +0 -1
  98. package/dist/chunk-qky3qehm.js +0 -6
  99. package/dist/chunk-qvtstj28.js +0 -1
  100. package/dist/chunk-reakyamv.js +0 -2
  101. package/dist/chunk-rpbyc2k4.js +0 -1
  102. package/dist/chunk-xqnfzt9g.js +0 -1
@@ -1,4 +1,4 @@
1
- import{vf as YO}from"./chunk-zkhb55jz.js";import{Cg as qO,Eg as S,Hg as y}from"./chunk-qxn5bg5k.js";import{Og as P}from"./chunk-0141jad7.js";import{oh as XO}from"./chunk-b9vm7gns.js";import{Kh as n}from"./chunk-sj0k8cdf.js";import{Uh as r}from"./chunk-0ra945vt.js";import{Wh as w}from"./chunk-h0fh3j9w.js";var b;((V)=>{V.PreToolUse="PreToolUse";V.PostToolUse="PostToolUse";V.PostToolUseFailure="PostToolUseFailure";V.PermissionRequest="PermissionRequest";V.Elicitation="Elicitation";V.ElicitationResult="ElicitationResult";V.UserPromptSubmit="UserPromptSubmit";V.SessionStart="SessionStart";V.SessionEnd="SessionEnd";V.Stop="Stop";V.SubagentStop="SubagentStop";V.Notification="Notification";V.Compaction="Compaction"})(b||={});var v;((Z)=>{Z.Approve="approve";Z.Block="block";Z.Async="async"})(v||={});var m;((Z)=>{Z.Allow="allow";Z.Deny="deny";Z.Ask="ask"})(m||={});import C from"node:path";import{LRUCache as fO}from"lru-cache";import{nanoid as R}from"nanoid";var N={enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,httpPolicy:{},PreToolUse:[],PostToolUse:[{name:"builtin:code-review-sensor",matcher:{tools:"Edit|Write"},hooks:[{type:"prompt",prompt:"审查此代码变更,重点检查:"+"1) 安全漏洞(命令注入、XSS、SQL 注入、硬编码密钥/密码)"+"2) 明显的逻辑错误(无限循环、off-by-one、空引用)"+"3) 类型安全问题。"+"如果发现严重问题,将问题描述放在 hookSpecificOutput.additionalContext 中。"+"如果没有严重问题,返回 approve。",model:void 0,timeout:15}]}],PostToolUseFailure:[],PermissionRequest:[],Elicitation:[],ElicitationResult:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]};function E(O,q){return{...O,...q,PreToolUse:q.PreToolUse??O.PreToolUse,PostToolUse:q.PostToolUse??O.PostToolUse,PostToolUseFailure:q.PostToolUseFailure??O.PostToolUseFailure,PermissionRequest:q.PermissionRequest??O.PermissionRequest,Elicitation:q.Elicitation??O.Elicitation,ElicitationResult:q.ElicitationResult??O.ElicitationResult,UserPromptSubmit:q.UserPromptSubmit??O.UserPromptSubmit,SessionStart:q.SessionStart??O.SessionStart,SessionEnd:q.SessionEnd??O.SessionEnd,Stop:q.Stop??O.Stop,SubagentStop:q.SubagentStop??O.SubagentStop,Notification:q.Notification??O.Notification,Compaction:q.Compaction??O.Compaction}}function c(){let O={};if(process.env.BLADE_DISABLE_HOOKS==="true")O.enabled=!1;if(process.env.BLADE_HOOK_TIMEOUT){let q=parseInt(process.env.BLADE_HOOK_TIMEOUT,10);if(!isNaN(q)&&q>0)O.defaultTimeout=q}return O}class d{executedHooks=new Map;canExecute(O,q){if(!this.executedHooks.has(O))this.executedHooks.set(O,new Set);if(this.executedHooks.get(O).has(q))return console.warn(`[HookGuard] Hook ${q} for tool ${O} already executed, skipping`),!1;return!0}markExecuted(O,q){let Q=this.executedHooks.get(O);if(Q)Q.add(q)}cleanup(O){this.executedHooks.delete(O)}cleanupAll(){this.executedHooks.clear()}}import DO from"node:path";import{createHash as JO}from"node:crypto";import{constants as s,promises as j}from"node:fs";import k from"node:path";import{Mutex as SO}from"async-mutex";import GO from"write-file-atomic";var h=1,VO=1048576,LO=/^sha256:[0-9a-f]{64}$/;class o extends Error{constructor(){super("Hook configuration changed after review; reload before trusting");this.name="HookTrustDigestMismatchError"}}function D(O){return O!==null&&typeof O==="object"&&!Array.isArray(O)}function M(O){if(O===void 0||typeof O==="function")return;if(Array.isArray(O))return O.map(M).filter((Q)=>Q!==void 0);if(!D(O))return O;if(O.type==="function")return;let q={};for(let Q of Object.keys(O).sort()){let Z=M(O[Q]);if(Z!==void 0)q[Q]=Z}return q}function zO(O){let q={};for(let Q of Object.values(b)){let Y=(O[Q]??[]).map(($)=>M({...$,hooks:$.hooks.map((X)=>X.source?{...X,source:{kind:X.source.kind,pluginName:X.source.pluginName,pluginSource:X.source.pluginSource}}:X)})).filter(($)=>$!==void 0);if(Y.length>0)q[Q]=Y}return{defaultTimeout:O.defaultTimeout,timeoutBehavior:O.timeoutBehavior,failureBehavior:O.failureBehavior,maxConcurrentHooks:O.maxConcurrentHooks,httpPolicy:M(O.httpPolicy??{}),events:q}}function FO(O){if(O.type==="command")return O.command.slice(0,2048);if(O.type==="prompt")return O.prompt.slice(0,512);if(O.type==="http")try{let q=new URL(O.url);return`${q.origin}${q.pathname}`.slice(0,2048)}catch{return O.url.slice(0,2048)}return"in-process function"}function t(O){let q=[];for(let Q of Object.values(b))for(let Z of O[Q]??[]){let Y=Z.matcher?JSON.stringify(M(Z.matcher)):void 0;for(let $ of Z.hooks){if($.type==="function")continue;q.push({event:Q,matcher:Y,name:Z.name,type:$.type,target:FO($),...$.source?{pluginName:$.source.pluginName,pluginSource:$.source.pluginSource}:{}})}}return q}function RO(O){if(t(O).length===0)return null;let q=JSON.stringify(M(zO(O)));return`sha256:${JO("sha256").update(q).digest("hex")}`}class A{static instance=null;mutex=new SO;filePath;constructor(O=k.join(r(),"hook-trust.json")){this.filePath=O}static getInstance(){if(!A.instance)A.instance=new A;return A.instance}static resetInstance(){A.instance=null}async getStatus(O,q){let{projectPath:Q,trustRoot:Z}=await n(O),Y=t(q),$=RO(q),X={projectPath:Q,trustRoot:Z,enabled:q.enabled===!0,configuredHooks:Y.length,currentDigest:$,definitions:Y};if(!q.enabled)return{...X,state:"disabled"};if(!$)return{...X,state:"not_required"};let W;try{W=await this.readStore()}catch(G){return{...X,state:"error",error:G instanceof Error?G.message:"Hook trust store is unavailable"}}let J=W.projects[Z];if(!J)return{...X,state:"untrusted"};return{...X,state:J.digest===$?"trusted":"modified",trustedDigest:J.digest,trustedAt:J.trustedAt}}async trust(O,q,Q){return this.mutex.runExclusive(async()=>{let Z=await this.getStatus(O,q);if(!Z.currentDigest)throw Error("No configured external hooks require trust");if(Q!==void 0&&Q!==Z.currentDigest)throw new o;let Y=await this.readStore();return Y.projects[Z.trustRoot]={digest:Z.currentDigest,trustedAt:new Date().toISOString()},await this.writeStore(Y),this.getStatus(O,q)})}async revoke(O,q){return this.mutex.runExclusive(async()=>{let Q=await this.getStatus(O,q),Z=await this.readStore();if(Q.trustRoot in Z.projects)delete Z.projects[Q.trustRoot],await this.writeStore(Z);return this.getStatus(O,q)})}async readStore(){let O;try{O=await j.open(this.filePath,s.O_RDONLY|s.O_NOFOLLOW)}catch(Y){if(Y.code==="ENOENT")return{version:h,projects:{}};throw Error("Hook trust store must be a regular file")}let q;try{let Y=await O.stat();if(!Y.isFile())throw Error("Hook trust store must be a regular file");if(Y.size>VO)throw Error("Hook trust store exceeds the maximum supported size");if(process.getuid&&Y.uid!==process.getuid())throw Error("Hook trust store must be owned by the current user");if((Y.mode&511)!==384)throw Error("Hook trust store permissions must be 0600");q=await O.readFile("utf8")}finally{await O.close()}let Q=JSON.parse(q);if(!D(Q)||Q.version!==h)throw Error("Hook trust store version must be 1");if(Object.keys(Q).some((Y)=>Y!=="version"&&Y!=="projects")||!D(Q.projects))throw Error("Hook trust store contains unsupported fields");let Z={};for(let[Y,$]of Object.entries(Q.projects)){if(!k.isAbsolute(Y)||!D($)||typeof $.digest!=="string"||!LO.test($.digest)||typeof $.trustedAt!=="string"||!Number.isFinite(Date.parse($.trustedAt))||Object.keys($).some((X)=>X!=="digest"&&X!=="trustedAt"))throw Error("Hook trust store contains an invalid project entry");Z[Y]={digest:$.digest,trustedAt:$.trustedAt}}return{version:h,projects:Z}}async writeStore(O){let q=k.dirname(this.filePath);await j.mkdir(q,{recursive:!0,mode:448}),await j.chmod(q,448),await GO(this.filePath,`${JSON.stringify(O,null,2)}
1
+ import{yf as YO}from"./chunk-272swnyr.js";import{Fg as qO,Hg as S,Kg as y}from"./chunk-sk8h4m9m.js";import{Tg as P}from"./chunk-sb84vdcf.js";import{th as XO}from"./chunk-ffa6hhee.js";import{Ph as n}from"./chunk-83caxxbt.js";import{Zh as r}from"./chunk-shr5cg46.js";import{$h as w}from"./chunk-6jsmac0q.js";var b;((V)=>{V.PreToolUse="PreToolUse";V.PostToolUse="PostToolUse";V.PostToolUseFailure="PostToolUseFailure";V.PermissionRequest="PermissionRequest";V.Elicitation="Elicitation";V.ElicitationResult="ElicitationResult";V.UserPromptSubmit="UserPromptSubmit";V.SessionStart="SessionStart";V.SessionEnd="SessionEnd";V.Stop="Stop";V.SubagentStop="SubagentStop";V.Notification="Notification";V.Compaction="Compaction"})(b||={});var v;((Z)=>{Z.Approve="approve";Z.Block="block";Z.Async="async"})(v||={});var m;((Z)=>{Z.Allow="allow";Z.Deny="deny";Z.Ask="ask"})(m||={});import C from"node:path";import{LRUCache as fO}from"lru-cache";import{nanoid as R}from"nanoid";var N={enabled:!1,defaultTimeout:60,timeoutBehavior:"ignore",failureBehavior:"ignore",maxConcurrentHooks:5,httpPolicy:{},PreToolUse:[],PostToolUse:[{name:"builtin:code-review-sensor",matcher:{tools:"Edit|Write"},hooks:[{type:"prompt",prompt:"审查此代码变更,重点检查:"+"1) 安全漏洞(命令注入、XSS、SQL 注入、硬编码密钥/密码)"+"2) 明显的逻辑错误(无限循环、off-by-one、空引用)"+"3) 类型安全问题。"+"如果发现严重问题,将问题描述放在 hookSpecificOutput.additionalContext 中。"+"如果没有严重问题,返回 approve。",model:void 0,timeout:15}]}],PostToolUseFailure:[],PermissionRequest:[],Elicitation:[],ElicitationResult:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]};function E(O,q){return{...O,...q,PreToolUse:q.PreToolUse??O.PreToolUse,PostToolUse:q.PostToolUse??O.PostToolUse,PostToolUseFailure:q.PostToolUseFailure??O.PostToolUseFailure,PermissionRequest:q.PermissionRequest??O.PermissionRequest,Elicitation:q.Elicitation??O.Elicitation,ElicitationResult:q.ElicitationResult??O.ElicitationResult,UserPromptSubmit:q.UserPromptSubmit??O.UserPromptSubmit,SessionStart:q.SessionStart??O.SessionStart,SessionEnd:q.SessionEnd??O.SessionEnd,Stop:q.Stop??O.Stop,SubagentStop:q.SubagentStop??O.SubagentStop,Notification:q.Notification??O.Notification,Compaction:q.Compaction??O.Compaction}}function c(){let O={};if(process.env.BLADE_DISABLE_HOOKS==="true")O.enabled=!1;if(process.env.BLADE_HOOK_TIMEOUT){let q=parseInt(process.env.BLADE_HOOK_TIMEOUT,10);if(!isNaN(q)&&q>0)O.defaultTimeout=q}return O}class d{executedHooks=new Map;canExecute(O,q){if(!this.executedHooks.has(O))this.executedHooks.set(O,new Set);if(this.executedHooks.get(O).has(q))return console.warn(`[HookGuard] Hook ${q} for tool ${O} already executed, skipping`),!1;return!0}markExecuted(O,q){let Q=this.executedHooks.get(O);if(Q)Q.add(q)}cleanup(O){this.executedHooks.delete(O)}cleanupAll(){this.executedHooks.clear()}}import DO from"node:path";import{createHash as JO}from"node:crypto";import{constants as s,promises as j}from"node:fs";import k from"node:path";import{Mutex as SO}from"async-mutex";import GO from"write-file-atomic";var h=1,VO=1048576,LO=/^sha256:[0-9a-f]{64}$/;class o extends Error{constructor(){super("Hook configuration changed after review; reload before trusting");this.name="HookTrustDigestMismatchError"}}function D(O){return O!==null&&typeof O==="object"&&!Array.isArray(O)}function M(O){if(O===void 0||typeof O==="function")return;if(Array.isArray(O))return O.map(M).filter((Q)=>Q!==void 0);if(!D(O))return O;if(O.type==="function")return;let q={};for(let Q of Object.keys(O).sort()){let Z=M(O[Q]);if(Z!==void 0)q[Q]=Z}return q}function zO(O){let q={};for(let Q of Object.values(b)){let Y=(O[Q]??[]).map(($)=>M({...$,hooks:$.hooks.map((X)=>X.source?{...X,source:{kind:X.source.kind,pluginName:X.source.pluginName,pluginSource:X.source.pluginSource}}:X)})).filter(($)=>$!==void 0);if(Y.length>0)q[Q]=Y}return{defaultTimeout:O.defaultTimeout,timeoutBehavior:O.timeoutBehavior,failureBehavior:O.failureBehavior,maxConcurrentHooks:O.maxConcurrentHooks,httpPolicy:M(O.httpPolicy??{}),events:q}}function FO(O){if(O.type==="command")return O.command.slice(0,2048);if(O.type==="prompt")return O.prompt.slice(0,512);if(O.type==="http")try{let q=new URL(O.url);return`${q.origin}${q.pathname}`.slice(0,2048)}catch{return O.url.slice(0,2048)}return"in-process function"}function t(O){let q=[];for(let Q of Object.values(b))for(let Z of O[Q]??[]){let Y=Z.matcher?JSON.stringify(M(Z.matcher)):void 0;for(let $ of Z.hooks){if($.type==="function")continue;q.push({event:Q,matcher:Y,name:Z.name,type:$.type,target:FO($),...$.source?{pluginName:$.source.pluginName,pluginSource:$.source.pluginSource}:{}})}}return q}function RO(O){if(t(O).length===0)return null;let q=JSON.stringify(M(zO(O)));return`sha256:${JO("sha256").update(q).digest("hex")}`}class A{static instance=null;mutex=new SO;filePath;constructor(O=k.join(r(),"hook-trust.json")){this.filePath=O}static getInstance(){if(!A.instance)A.instance=new A;return A.instance}static resetInstance(){A.instance=null}async getStatus(O,q){let{projectPath:Q,trustRoot:Z}=await n(O),Y=t(q),$=RO(q),X={projectPath:Q,trustRoot:Z,enabled:q.enabled===!0,configuredHooks:Y.length,currentDigest:$,definitions:Y};if(!q.enabled)return{...X,state:"disabled"};if(!$)return{...X,state:"not_required"};let W;try{W=await this.readStore()}catch(G){return{...X,state:"error",error:G instanceof Error?G.message:"Hook trust store is unavailable"}}let J=W.projects[Z];if(!J)return{...X,state:"untrusted"};return{...X,state:J.digest===$?"trusted":"modified",trustedDigest:J.digest,trustedAt:J.trustedAt}}async trust(O,q,Q){return this.mutex.runExclusive(async()=>{let Z=await this.getStatus(O,q);if(!Z.currentDigest)throw Error("No configured external hooks require trust");if(Q!==void 0&&Q!==Z.currentDigest)throw new o;let Y=await this.readStore();return Y.projects[Z.trustRoot]={digest:Z.currentDigest,trustedAt:new Date().toISOString()},await this.writeStore(Y),this.getStatus(O,q)})}async revoke(O,q){return this.mutex.runExclusive(async()=>{let Q=await this.getStatus(O,q),Z=await this.readStore();if(Q.trustRoot in Z.projects)delete Z.projects[Q.trustRoot],await this.writeStore(Z);return this.getStatus(O,q)})}async readStore(){let O;try{O=await j.open(this.filePath,s.O_RDONLY|s.O_NOFOLLOW)}catch(Y){if(Y.code==="ENOENT")return{version:h,projects:{}};throw Error("Hook trust store must be a regular file")}let q;try{let Y=await O.stat();if(!Y.isFile())throw Error("Hook trust store must be a regular file");if(Y.size>VO)throw Error("Hook trust store exceeds the maximum supported size");if(process.getuid&&Y.uid!==process.getuid())throw Error("Hook trust store must be owned by the current user");if((Y.mode&511)!==384)throw Error("Hook trust store permissions must be 0600");q=await O.readFile("utf8")}finally{await O.close()}let Q=JSON.parse(q);if(!D(Q)||Q.version!==h)throw Error("Hook trust store version must be 1");if(Object.keys(Q).some((Y)=>Y!=="version"&&Y!=="projects")||!D(Q.projects))throw Error("Hook trust store contains unsupported fields");let Z={};for(let[Y,$]of Object.entries(Q.projects)){if(!k.isAbsolute(Y)||!D($)||typeof $.digest!=="string"||!LO.test($.digest)||typeof $.trustedAt!=="string"||!Number.isFinite(Date.parse($.trustedAt))||Object.keys($).some((X)=>X!=="digest"&&X!=="trustedAt"))throw Error("Hook trust store contains an invalid project entry");Z[Y]={digest:$.digest,trustedAt:$.trustedAt}}return{version:h,projects:Z}}async writeStore(O){let q=k.dirname(this.filePath);await j.mkdir(q,{recursive:!0,mode:448}),await j.chmod(q,448),await GO(this.filePath,`${JSON.stringify(O,null,2)}
2
2
  `,{mode:384}),await j.chmod(this.filePath,384)}}class T extends Error{constructor(O){super(O);this.name="HttpHookSecurityError"}}function e(O,q={}){let Q;try{Q=new URL(O)}catch{throw new T(`Invalid URL: ${O}`)}if(Q.protocol!=="https:"&&Q.protocol!=="http:")throw new T(`Only http/https supported, got: ${Q.protocol}`);let Z=Q.hostname.toLowerCase();if(BO(Z,q.allowedHosts))return;if(Q.protocol==="http:"&&!q.allowHttp)throw new T(`HTTP (non-TLS) blocked for ${Z}; use https:// or add to allowedHosts`);if(AO(Z)&&!q.allowLoopback)throw new T(`Loopback address blocked: ${Z}; enable policy.allowLoopback or add to allowedHosts`);if(PO(Z)&&!q.allowPrivateRanges)throw new T(`Private/link-local address blocked: ${Z}; enable policy.allowPrivateRanges or add to allowedHosts`)}function BO(O,q){if(!q||q.length===0)return!1;return q.some((Q)=>{let Z=Q.toLowerCase();if(Z===O)return!0;if(Z.startsWith("*.")){let Y=Z.slice(1);return O.endsWith(Y)&&O.length>Y.length}return!1})}function AO(O){if(O==="localhost")return!0;if(O==="::1"||O==="[::1]")return!0;if(/^127\.\d+\.\d+\.\d+$/.test(O))return!0;return!1}function PO(O){let q=O.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);if(!q)return!1;let[Q,Z]=q.slice(1).map(Number);if(Q===10)return!0;if(Q===172&&Z>=16&&Z<=31)return!0;if(Q===192&&Z===168)return!0;if(Q===169&&Z===254)return!0;return!1}function OO(O){if(!O)return{};let q={};for(let[Q,Z]of Object.entries(O))q[Q]=Z.replace(/\$\{([A-Z_][A-Z0-9_]*)\}/gi,(Y,$)=>{return process.env[$]??`\${${$}}`});return q}var UO=S.Object({hookEventName:S.Literal("PreToolUse"),permissionDecision:S.Optional(S.Enum(m)),permissionDecisionReason:S.Optional(S.String()),updatedInput:S.Optional(S.Record(S.String(),S.Unknown()))}),_O=S.Object({hookEventName:S.Literal("PostToolUse"),additionalContext:S.Optional(S.String()),updatedOutput:S.Optional(S.Unknown())}),KO=S.Object({hookEventName:S.Literal("Stop"),continue:S.Optional(S.Boolean()),continueReason:S.Optional(S.String())}),bO=S.Object({hookEventName:S.Literal("SubagentStop"),continue:S.Optional(S.Boolean()),continueReason:S.Optional(S.String()),additionalContext:S.Optional(S.String())}),NO=S.Object({hookEventName:S.Literal("PermissionRequest"),permissionDecision:S.Optional(y(["approve","deny","ask"])),permissionDecisionReason:S.Optional(S.String())}),QO=S.Record(S.String(),S.Union([S.String(),S.Number(),S.Boolean(),S.Array(S.String(),{maxItems:100})]),{maxProperties:32}),MO=S.Object({hookEventName:S.Literal("Elicitation"),action:S.Optional(y(["accept","decline","cancel"])),content:S.Optional(QO)}),TO=S.Object({hookEventName:S.Literal("ElicitationResult"),action:S.Optional(y(["accept","decline","cancel"])),content:S.Optional(QO)}),wO=S.Object({hookEventName:S.Literal("UserPromptSubmit"),updatedPrompt:S.Optional(S.String()),contextInjection:S.Optional(S.String())}),CO=S.Object({hookEventName:S.Literal("SessionStart"),env:S.Optional(S.Record(S.String(),S.String()))}),EO=S.Object({hookEventName:S.Literal("Compaction"),blockCompaction:S.Optional(S.Boolean()),blockReason:S.Optional(S.String())}),jO=S.Object({decision:S.Optional(S.Object({behavior:S.Enum(v)})),systemMessage:S.Optional(S.String()),hookSpecificOutput:S.Optional(S.Union([UO,_O,KO,bO,NO,MO,TO,wO,CO,EO])),suppressOutput:S.Optional(S.Boolean())});function ZO(O){return qO(jO,O)}class p{parse(O,q,Q){if(O.timedOut){let Y=Q?.timeoutBehavior||"ignore",$="Hook timeout";if(Y==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:O.stdout,stderr:O.stderr,exitCode:O.exitCode,hook:q};else if(Y==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:O.stdout,stderr:O.stderr,exitCode:O.exitCode,hook:q};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:O.stdout,stderr:O.stderr,exitCode:O.exitCode,hook:q}}let Z=this.tryParseJSON(O.stdout);if(Z){let Y=ZO(Z);if(!Y.success){let X="error"in Y?Y.error.message:"Unknown validation error",W=Q?.failureBehavior||"ignore",J=`Invalid hook output JSON: ${X}`;if(W==="deny")return{success:!1,blocking:!0,error:J,stdout:O.stdout,stderr:O.stderr,exitCode:O.exitCode,hook:q};else if(W==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${J}. Continue?`,stdout:O.stdout,stderr:O.stderr,exitCode:O.exitCode,hook:q};else return{success:!1,blocking:!1,warning:J,stdout:O.stdout,stderr:O.stderr,exitCode:O.exitCode,hook:q}}let $=Y.data;if($.decision?.behavior==="block")return{success:!1,blocking:!0,error:$.systemMessage||"Hook blocked execution",output:$,stdout:O.stdout,stderr:O.stderr,exitCode:O.exitCode,hook:q};if($.decision?.behavior==="async")return{success:!0,output:$,stdout:O.stdout,stderr:O.stderr,exitCode:O.exitCode,hook:q};return{success:!0,output:$,stdout:O.stdout,stderr:O.stderr,exitCode:O.exitCode,hook:q}}return this.parseByExitCode(O,q,Q)}parseByExitCode(O,q,Q){let Z=O.exitCode;switch(Z){case 0:return{success:!0,stdout:O.stdout,stderr:O.stderr,exitCode:Z,hook:q};case 2:return{success:!1,blocking:!0,error:O.stderr||O.stdout||"Hook returned exit code 2",stdout:O.stdout,stderr:O.stderr,exitCode:Z,hook:q};case 124:{let Y=Q?.timeoutBehavior||"ignore",$="Hook timeout";if(Y==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:O.stdout,stderr:O.stderr,exitCode:Z,hook:q};else if(Y==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:O.stdout,stderr:O.stderr,exitCode:Z,hook:q};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:O.stdout,stderr:O.stderr,exitCode:Z,hook:q}}default:{let Y=Q?.failureBehavior||"ignore",$=O.stderr||O.stdout||`Hook failed with exit code ${Z}`;if(Y==="deny")return{success:!1,blocking:!0,error:$,stdout:O.stdout,stderr:O.stderr,exitCode:Z,hook:q};else if(Y==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${$}. Continue?`,stdout:O.stdout,stderr:O.stderr,exitCode:Z,hook:q};else return{success:!1,blocking:!1,warning:$,stdout:O.stdout,stderr:O.stderr,exitCode:Z,hook:q}}}}tryParseJSON(O){try{let q=O.trim();if(!q)return null;let Q=q.match(/^\s*(\{[\s\S]*\})\s*$/);if(!Q)return null;return JSON.parse(Q[1])}catch{return null}}}class u{content="";maxSize;constructor(O){this.maxSize=O}append(O){if(this.content.length<this.maxSize){let q=this.maxSize-this.content.length;this.content+=O.substring(0,q)}}getContent(){return this.content}isFull(){return this.content.length>=this.maxSize}}class l{MAX_STDOUT_SIZE=1048576;MAX_STDERR_SIZE=1048576;MAX_INPUT_SIZE=102400;async execute(O,q,Q,Z){let Y=JSON.stringify(q);if(Y.length>this.MAX_INPUT_SIZE)throw Error(`Hook input too large: ${Y.length} bytes (max ${this.MAX_INPUT_SIZE})`);let $=this.createSafeEnv(q,Q.environment),{child:X,processTree:W}=YO(O,[],{shell:!0,env:$,cwd:Q.projectDir}),J=new u(this.MAX_STDOUT_SIZE),G=new u(this.MAX_STDERR_SIZE);X.stdout?.setEncoding("utf8"),X.stderr?.setEncoding("utf8"),X.stdout?.on("data",(L)=>{J.append(L)}),X.stderr?.on("data",(L)=>{G.append(L)});try{X.stdin?.write(Y),X.stdin?.end()}catch(L){throw await W.terminate(),Error(`Failed to write hook input: ${L}`)}return new Promise((L,F)=>{let z=!1,V=!1,B,U=()=>{return B??=W.terminate(),B},K=null,H=()=>{if(K&&Q.abortSignal)Q.abortSignal.removeEventListener("abort",K),K=null},I=setTimeout(()=>{z=!0,U()},Z);if(X.on("close",async(f)=>{if(V)return;if(V=!0,clearTimeout(I),H(),z)await U();L({stdout:J.getContent(),stderr:G.getContent(),exitCode:z?124:f??1,timedOut:z})}),X.on("error",(f)=>{if(V)return;V=!0,clearTimeout(I),H(),F(f)}),Q.abortSignal){if(K=()=>{if(V)return;V=!0,clearTimeout(I),H(),U().then(()=>{L({stdout:J.getContent(),stderr:"Hook cancelled by abort signal",exitCode:1,timedOut:!1})})},Q.abortSignal.addEventListener("abort",K),Q.abortSignal.aborted)K()}})}createSafeEnv(O,q={}){return{...q,PATH:q.PATH??process.env.PATH??"",HOME:q.HOME??process.env.HOME??"",USER:q.USER??process.env.USER??"",SHELL:q.SHELL??process.env.SHELL??"/bin/sh",BLADE_PROJECT_DIR:O.project_dir,BLADE_SESSION_ID:O.session_id,BLADE_HOOK_EVENT:O.hook_event_name,BLADE_TOOL_NAME:"tool_name"in O?O.tool_name:"",BLADE_TOOL_USE_ID:"tool_use_id"in O?O.tool_use_id:""}}}var $O=XO("Execution"),yO={PreToolUse:'{ "permissionDecision": "approve" | "deny" | "ask", "permissionDecisionReason": "...", "updatedInput": { ... } }',PostToolUse:'{ "additionalContext": "注入到工具结果的额外信息", "updatedOutput": "修改后的工具输出" }',Stop:'{ "continue": true, "continueReason": "继续执行的原因" } // continue: true 表示阻止停止',SubagentStop:'{ "continue": true, "continueReason": "...", "additionalContext": "..." }',PermissionRequest:'{ "permissionDecision": "approve" | "deny" | "ask", "permissionDecisionReason": "..." }',Elicitation:'{ "action": "accept" | "decline" | "cancel", "content": { "field": "value" } }',ElicitationResult:'{ "action": "accept" | "decline" | "cancel", "content": { "field": "value" } }',UserPromptSubmit:'{ "updatedPrompt": "修改后的提示词", "contextInjection": "注入的上下文" }',Compaction:'{ "blockCompaction": true, "blockReason": "阻止压缩的原因" }'};class x{processExecutor=new l;outputParser=new p;chatServiceCache=new Map;sessionModelResources=new Map;sessionEnvironments=new Map;trustWarnings=new Set;bindSessionModelResources(O,q,Q){for(let Z of q)this.sessionModelResources.set(this.sessionResourceKey(O,Z),Q),this.sessionEnvironments.set(this.sessionResourceKey(O,Z),Q.config.env)}bindSessionEnvironment(O,q,Q){for(let Z of q)this.sessionEnvironments.set(this.sessionResourceKey(O,Z),Q)}async unbindSessionModelResources(O,q){for(let Q of q){let Z=this.sessionResourceKey(O,Q);this.sessionModelResources.delete(Z),this.sessionEnvironments.delete(Z);let Y=`${Z}\x00`;for(let[$,X]of this.chatServiceCache){if(!$.startsWith(Y))continue;this.chatServiceCache.delete($),await X.dispose?.()}}}async executePreToolHooks(O,q,Q){if(O.length===0)return{decision:"allow"};let Z="tool_input"in q?q.tool_input:{},Y=[];for(let $ of O)try{let X={...q,...Z&&{tool_input:Z}},W=await this.executeHook($,X,Q);if(!W.success){if(W.blocking)return{decision:"deny",reason:W.error};if(W.needsConfirmation)return{decision:"ask",reason:W.warning||W.error};if(W.warning)Y.push(W.warning);continue}let J=W.output?.hookSpecificOutput;if(J&&"permissionDecision"in J){switch(J.permissionDecision){case"deny":return{decision:"deny",reason:J.permissionDecisionReason};case"ask":return{decision:"ask",reason:J.permissionDecisionReason};case"allow":break}if("updatedInput"in J&&J.updatedInput)Z={...Z,...J.updatedInput}}}catch(X){let W=X instanceof Error?X.message:String(X);if(Y.push(`Hook failed: ${W}`),Q.config.failureBehavior==="deny")return{decision:"deny",reason:W};else if(Q.config.failureBehavior==="ask")return{decision:"ask",reason:`Hook failed: ${W}. Continue?`}}return{decision:"allow",modifiedInput:Z,warning:Y.length>0?Y.join(`
3
3
  `):void 0}}async executePostToolHooks(O,q,Q){if(O.length===0)return{};let Z=Q.config.maxConcurrentHooks||5,Y=await this.executeHooksConcurrently(O,q,Q,Z),$=[],X=void 0,W=[];for(let J of Y){if(!J.success&&J.warning){W.push(J.warning);continue}let G=J.output?.hookSpecificOutput;if(G&&"additionalContext"in G){if(G.additionalContext)$.push(G.additionalContext);if("updatedOutput"in G&&G.updatedOutput!==void 0)X=G.updatedOutput}}return{additionalContext:$.length>0?$.join(`
4
4
 
@@ -25,7 +25,7 @@ import{vf as YO}from"./chunk-zkhb55jz.js";import{Cg as qO,Eg as S,Hg as y}from".
25
25
  `):void 0}}async executeNotificationHooks(O,q,Q){let Z="message"in q?q.message:"";if(O.length===0)return{suppress:!1,message:Z};let Y=[],$=!1,X=Z;for(let W of O)try{let J=await this.executeHook(W,q,Q);if(!J.success){if(J.warning)Y.push(J.warning);continue}if(J.output?.suppressOutput){$=!0;break}if(J.stdout&&J.stdout.trim())X=J.stdout.trim()}catch(J){let G=J instanceof Error?J.message:String(J);Y.push(`Hook failed: ${G}`)}return{suppress:$,message:X,warning:Y.length>0?Y.join(`
26
26
  `):void 0}}async executeCompactionHooks(O,q,Q){if(O.length===0)return{blockCompaction:!1};let Z=[];for(let Y of O)try{let $=await this.executeHook(Y,q,Q);if(!$.success){if($.warning)Z.push($.warning);continue}let X=$.output?.hookSpecificOutput;if(X&&"blockCompaction"in X&&X.blockCompaction)return{blockCompaction:!0,blockReason:X.blockReason,warning:Z.length>0?Z.join(`
27
27
  `):void 0}}catch($){let X=$ instanceof Error?$.message:String($);Z.push(`Hook failed: ${X}`)}return{blockCompaction:!1,warning:Z.length>0?Z.join(`
28
- `):void 0}}async executeHook(O,q,Q){if(O.type!=="function"){let Y=await A.getInstance().getStatus(Q.projectDir,Q.config);if(Y.state!=="trusted"){let $=`${Y.trustRoot}:${Y.currentDigest}:${Y.state}`;if(!this.trustWarnings.has($)){if(this.trustWarnings.size>=512)this.trustWarnings.clear();this.trustWarnings.add($),$O.warn(`[HookTrust] Skipping configured hooks for ${Y.trustRoot}: ${Y.state}`)}return{success:!0,hook:O,warning:`Hook skipped: project hook trust is ${Y.state}`}}}let Z=this.withHookEnvironment(Q,O);if(O.type==="command")return this.executeCommandHook(O,q,Z);if(O.type==="prompt")return this.executePromptHook(O,q,Z);if(O.type==="function")return this.executeFunctionHook(O,q,Z);if(O.type==="http")return this.executeHttpHook(O,q,Z);throw Error(`Hook type ${O.type} not supported`)}async executeCommandHook(O,q,Q){let Z=(O.timeout??Q.config.defaultTimeout??60)*1000;try{let Y=await this.processExecutor.execute(O.command,q,Q,Z);return this.outputParser.parse(Y,O,{timeoutBehavior:Q.config.timeoutBehavior,failureBehavior:Q.config.failureBehavior})}catch(Y){return{success:!1,blocking:!1,error:Y instanceof Error?Y.message:String(Y),hook:O}}}async executePromptHook(O,q,Q){let Z=(O.timeout??Q.config.defaultTimeout??60)*1000;try{let Y=await this.getOrCreateChatService(O.model,Q),$="hook_event_name"in q?String(q.hook_event_name):"Unknown",X=this.buildPromptHookSystemMessage(O,$),W=JSON.stringify(q,null,2),J=new AbortController,G=setTimeout(()=>J.abort(),Z),L;try{L=(await Y.chat([{role:"system",content:X},{role:"user",content:W}],void 0,J.signal,{providerAdmission:{sessionId:Q.sessionId,ownerId:Q.sessionId,requestClass:"background"}})).content}catch(z){if(J.signal.aborted||z instanceof Error&&z.name==="AbortError")return this.outputParser.parse({stdout:"",stderr:"",exitCode:0,timedOut:!0},O,{timeoutBehavior:Q.config.timeoutBehavior,failureBehavior:Q.config.failureBehavior});throw z}finally{clearTimeout(G)}let F=this.extractJsonFromLLMResponse(L);return this.outputParser.parse({stdout:F,stderr:"",exitCode:0,timedOut:!1},O,{timeoutBehavior:Q.config.timeoutBehavior,failureBehavior:Q.config.failureBehavior})}catch(Y){return $O.warn(`[PromptHook] 执行失败: ${Y instanceof Error?Y.message:String(Y)}`),{success:!1,blocking:!1,error:Y instanceof Error?Y.message:String(Y),hook:O}}}async executeFunctionHook(O,q,Q){let Z=(O.timeout??10)*1000;try{let Y=await this.runFunctionWithTimeout(O.handler,q,Q,Z);if(Y===void 0||Y===null)return{success:!0,hook:O};let $={stdout:JSON.stringify(Y),stderr:"",exitCode:0,timedOut:!1};return this.outputParser.parse($,O,{timeoutBehavior:Q.config.timeoutBehavior,failureBehavior:Q.config.failureBehavior})}catch(Y){if(Y.isTimeout){let $={stdout:"",stderr:`Function hook timeout after ${Z}ms`,exitCode:124,timedOut:!0};return this.outputParser.parse($,O,{timeoutBehavior:Q.config.timeoutBehavior,failureBehavior:Q.config.failureBehavior})}return{success:!1,blocking:!1,error:Y instanceof Error?Y.message:String(Y),hook:O}}}runFunctionWithTimeout(O,q,Q,Z){return new Promise((Y,$)=>{let X=!1,W=setTimeout(()=>{if(X)return;X=!0;let G=Object.assign(Error(`Function hook timed out after ${Z}ms`),{isTimeout:!0});$(G)},Z),J=()=>{if(X)return;X=!0,clearTimeout(W),$(Error("Function hook aborted"))};Q.abortSignal?.addEventListener("abort",J,{once:!0}),Promise.resolve().then(()=>O(q,Q)).then((G)=>{if(X)return;X=!0,clearTimeout(W),Q.abortSignal?.removeEventListener("abort",J),Y(G)},(G)=>{if(X)return;X=!0,clearTimeout(W),Q.abortSignal?.removeEventListener("abort",J),$(G)})})}async executeHttpHook(O,q,Q){let Z=(O.timeout??10)*1000,Y=O.maxResponseBytes??262144,$=Math.max(1,(O.retries??0)+1);try{e(O.url,Q.config.httpPolicy)}catch(G){return{success:!1,blocking:!0,error:G instanceof Error?G.message:String(G),hook:O}}let X={"Content-Type":"application/json",...OO(O.headers)},W=JSON.stringify(q),J;for(let G=0;G<$;G++){if(G>0){let V=Math.min(2**G*200,5000);await new Promise((B)=>setTimeout(B,V))}let L=new AbortController,F=setTimeout(()=>L.abort(),Z),z=()=>L.abort();Q.abortSignal?.addEventListener("abort",z,{once:!0});try{let V=await fetch(O.url,{method:"POST",headers:X,body:W,redirect:"manual",signal:L.signal});if(V.status>=300&&V.status<400){J=Error(`HTTP hook received redirect (${V.status}); redirects are disabled`);continue}if(!V.ok){if(J=Error(`HTTP hook returned ${V.status} ${V.statusText}`),V.status>=400&&V.status<500)break;continue}let U={stdout:await HO(V,Y),stderr:"",exitCode:0,timedOut:!1};return this.outputParser.parse(U,O,{timeoutBehavior:Q.config.timeoutBehavior,failureBehavior:Q.config.failureBehavior})}catch(V){let B=V.name==="AbortError"||V.code==="ABORT_ERR";if(B&&Q.abortSignal?.aborted){J=Error("HTTP hook aborted by caller");break}if(B){let U={stdout:"",stderr:`HTTP hook timeout after ${Z}ms`,exitCode:124,timedOut:!0};if(G===$-1)return this.outputParser.parse(U,O,{timeoutBehavior:Q.config.timeoutBehavior,failureBehavior:Q.config.failureBehavior});J=Error(`HTTP hook timeout attempt ${G+1}`);continue}J=V}finally{clearTimeout(F),Q.abortSignal?.removeEventListener("abort",z)}}return{success:!1,blocking:!1,error:J?.message??"HTTP hook failed",hook:O}}async getOrCreateChatService(O,q){let Q=this.sessionResourceKey(q.sessionId,q.projectDir),Z=`${Q}\x00${O||"__default__"}`,Y=this.chatServiceCache.get(Z);if(Y)return Y;let{ensureStoreInitialized:$,getConfig:X}=await import("./chunk-7t41dza5.js"),{createChatServiceAsync:W}=await import("./chunk-gn6ftvjy.js"),{resolveModelConfig:J}=await import("./chunk-rpbyc2k4.js"),{resolveWorkspaceModelResources:G}=await import("./chunk-xqnfzt9g.js");await $();let L=X();if(!L)throw Error("PromptHook: 配置未初始化");let F=this.sessionModelResources.get(Q)??await G(q.projectDir,L),z=O?F.config.models.find((B)=>B.id===O):F.config.models.find((B)=>B.id===F.config.currentModelId)??F.config.models[0];if(!z)throw Error("PromptHook: 无法获取模型配置。请确保至少配置了一个模型。");let V=await W(J(z,F.config,"off",F.catalog).chat);return this.chatServiceCache.set(Z,V),V}sessionResourceKey(O,q){return`${O}\x00${DO.resolve(q)}`}withSessionEnvironment(O){let q=this.sessionEnvironments.get(this.sessionResourceKey(O.sessionId,O.projectDir));return q?{...O,environment:q}:O}withHookEnvironment(O,q){let Q=this.withSessionEnvironment(O);if(!q.source)return Q;return{...Q,environment:{...Q.environment,BLADE_PLUGIN_ROOT:q.source.pluginRoot,CLAUDE_PLUGIN_ROOT:q.source.pluginRoot,BLADE_PLUGIN_NAME:q.source.pluginName}}}buildPromptHookSystemMessage(O,q){let Q=yO[q]||"{ ... 根据事件类型返回相应字段 }";return`你是一个代码质量评估器,作为 Hook 在 ${q} 事件中被触发。
28
+ `):void 0}}async executeHook(O,q,Q){if(O.type!=="function"){let Y=await A.getInstance().getStatus(Q.projectDir,Q.config);if(Y.state!=="trusted"){let $=`${Y.trustRoot}:${Y.currentDigest}:${Y.state}`;if(!this.trustWarnings.has($)){if(this.trustWarnings.size>=512)this.trustWarnings.clear();this.trustWarnings.add($),$O.warn(`[HookTrust] Skipping configured hooks for ${Y.trustRoot}: ${Y.state}`)}return{success:!0,hook:O,warning:`Hook skipped: project hook trust is ${Y.state}`}}}let Z=this.withHookEnvironment(Q,O);if(O.type==="command")return this.executeCommandHook(O,q,Z);if(O.type==="prompt")return this.executePromptHook(O,q,Z);if(O.type==="function")return this.executeFunctionHook(O,q,Z);if(O.type==="http")return this.executeHttpHook(O,q,Z);throw Error(`Hook type ${O.type} not supported`)}async executeCommandHook(O,q,Q){let Z=(O.timeout??Q.config.defaultTimeout??60)*1000;try{let Y=await this.processExecutor.execute(O.command,q,Q,Z);return this.outputParser.parse(Y,O,{timeoutBehavior:Q.config.timeoutBehavior,failureBehavior:Q.config.failureBehavior})}catch(Y){return{success:!1,blocking:!1,error:Y instanceof Error?Y.message:String(Y),hook:O}}}async executePromptHook(O,q,Q){let Z=(O.timeout??Q.config.defaultTimeout??60)*1000;try{let Y=await this.getOrCreateChatService(O.model,Q),$="hook_event_name"in q?String(q.hook_event_name):"Unknown",X=this.buildPromptHookSystemMessage(O,$),W=JSON.stringify(q,null,2),J=new AbortController,G=setTimeout(()=>J.abort(),Z),L;try{L=(await Y.chat([{role:"system",content:X},{role:"user",content:W}],void 0,J.signal,{providerAdmission:{sessionId:Q.sessionId,ownerId:Q.sessionId,requestClass:"background"}})).content}catch(z){if(J.signal.aborted||z instanceof Error&&z.name==="AbortError")return this.outputParser.parse({stdout:"",stderr:"",exitCode:0,timedOut:!0},O,{timeoutBehavior:Q.config.timeoutBehavior,failureBehavior:Q.config.failureBehavior});throw z}finally{clearTimeout(G)}let F=this.extractJsonFromLLMResponse(L);return this.outputParser.parse({stdout:F,stderr:"",exitCode:0,timedOut:!1},O,{timeoutBehavior:Q.config.timeoutBehavior,failureBehavior:Q.config.failureBehavior})}catch(Y){return $O.warn(`[PromptHook] 执行失败: ${Y instanceof Error?Y.message:String(Y)}`),{success:!1,blocking:!1,error:Y instanceof Error?Y.message:String(Y),hook:O}}}async executeFunctionHook(O,q,Q){let Z=(O.timeout??10)*1000;try{let Y=await this.runFunctionWithTimeout(O.handler,q,Q,Z);if(Y===void 0||Y===null)return{success:!0,hook:O};let $={stdout:JSON.stringify(Y),stderr:"",exitCode:0,timedOut:!1};return this.outputParser.parse($,O,{timeoutBehavior:Q.config.timeoutBehavior,failureBehavior:Q.config.failureBehavior})}catch(Y){if(Y.isTimeout){let $={stdout:"",stderr:`Function hook timeout after ${Z}ms`,exitCode:124,timedOut:!0};return this.outputParser.parse($,O,{timeoutBehavior:Q.config.timeoutBehavior,failureBehavior:Q.config.failureBehavior})}return{success:!1,blocking:!1,error:Y instanceof Error?Y.message:String(Y),hook:O}}}runFunctionWithTimeout(O,q,Q,Z){return new Promise((Y,$)=>{let X=!1,W=setTimeout(()=>{if(X)return;X=!0;let G=Object.assign(Error(`Function hook timed out after ${Z}ms`),{isTimeout:!0});$(G)},Z),J=()=>{if(X)return;X=!0,clearTimeout(W),$(Error("Function hook aborted"))};Q.abortSignal?.addEventListener("abort",J,{once:!0}),Promise.resolve().then(()=>O(q,Q)).then((G)=>{if(X)return;X=!0,clearTimeout(W),Q.abortSignal?.removeEventListener("abort",J),Y(G)},(G)=>{if(X)return;X=!0,clearTimeout(W),Q.abortSignal?.removeEventListener("abort",J),$(G)})})}async executeHttpHook(O,q,Q){let Z=(O.timeout??10)*1000,Y=O.maxResponseBytes??262144,$=Math.max(1,(O.retries??0)+1);try{e(O.url,Q.config.httpPolicy)}catch(G){return{success:!1,blocking:!0,error:G instanceof Error?G.message:String(G),hook:O}}let X={"Content-Type":"application/json",...OO(O.headers)},W=JSON.stringify(q),J;for(let G=0;G<$;G++){if(G>0){let V=Math.min(2**G*200,5000);await new Promise((B)=>setTimeout(B,V))}let L=new AbortController,F=setTimeout(()=>L.abort(),Z),z=()=>L.abort();Q.abortSignal?.addEventListener("abort",z,{once:!0});try{let V=await fetch(O.url,{method:"POST",headers:X,body:W,redirect:"manual",signal:L.signal});if(V.status>=300&&V.status<400){J=Error(`HTTP hook received redirect (${V.status}); redirects are disabled`);continue}if(!V.ok){if(J=Error(`HTTP hook returned ${V.status} ${V.statusText}`),V.status>=400&&V.status<500)break;continue}let U={stdout:await HO(V,Y),stderr:"",exitCode:0,timedOut:!1};return this.outputParser.parse(U,O,{timeoutBehavior:Q.config.timeoutBehavior,failureBehavior:Q.config.failureBehavior})}catch(V){let B=V.name==="AbortError"||V.code==="ABORT_ERR";if(B&&Q.abortSignal?.aborted){J=Error("HTTP hook aborted by caller");break}if(B){let U={stdout:"",stderr:`HTTP hook timeout after ${Z}ms`,exitCode:124,timedOut:!0};if(G===$-1)return this.outputParser.parse(U,O,{timeoutBehavior:Q.config.timeoutBehavior,failureBehavior:Q.config.failureBehavior});J=Error(`HTTP hook timeout attempt ${G+1}`);continue}J=V}finally{clearTimeout(F),Q.abortSignal?.removeEventListener("abort",z)}}return{success:!1,blocking:!1,error:J?.message??"HTTP hook failed",hook:O}}async getOrCreateChatService(O,q){let Q=this.sessionResourceKey(q.sessionId,q.projectDir),Z=`${Q}\x00${O||"__default__"}`,Y=this.chatServiceCache.get(Z);if(Y)return Y;let{ensureStoreInitialized:$,getConfig:X}=await import("./chunk-js3j00ka.js"),{createChatServiceAsync:W}=await import("./chunk-xj65p2sn.js"),{resolveModelConfig:J}=await import("./chunk-x2rraka3.js"),{resolveWorkspaceModelResources:G}=await import("./chunk-rmqksw1e.js");await $();let L=X();if(!L)throw Error("PromptHook: 配置未初始化");let F=this.sessionModelResources.get(Q)??await G(q.projectDir,L),z=O?F.config.models.find((B)=>B.id===O):F.config.models.find((B)=>B.id===F.config.currentModelId)??F.config.models[0];if(!z)throw Error("PromptHook: 无法获取模型配置。请确保至少配置了一个模型。");let V=await W(J(z,F.config,"off",F.catalog).chat);return this.chatServiceCache.set(Z,V),V}sessionResourceKey(O,q){return`${O}\x00${DO.resolve(q)}`}withSessionEnvironment(O){let q=this.sessionEnvironments.get(this.sessionResourceKey(O.sessionId,O.projectDir));return q?{...O,environment:q}:O}withHookEnvironment(O,q){let Q=this.withSessionEnvironment(O);if(!q.source)return Q;return{...Q,environment:{...Q.environment,BLADE_PLUGIN_ROOT:q.source.pluginRoot,CLAUDE_PLUGIN_ROOT:q.source.pluginRoot,BLADE_PLUGIN_NAME:q.source.pluginName}}}buildPromptHookSystemMessage(O,q){let Q=yO[q]||"{ ... 根据事件类型返回相应字段 }";return`你是一个代码质量评估器,作为 Hook 在 ${q} 事件中被触发。
29
29
 
30
30
  `+`## 评估指令
31
31
  ${O.prompt}
@@ -42,4 +42,4 @@ ${O.prompt}
42
42
  `+`- 只输出 JSON,不要包含 markdown 代码块或其他文本
43
43
  `+`- 如果没有发现问题,使用 "approve"
44
44
  `+'- 只在发现严重问题时使用 "block"'}extractJsonFromLLMResponse(O){let q=O.trim(),Q=q.match(/^```(?:json)?\s*\n?([\s\S]*?)\n?\s*```$/);if(Q)return Q[1].trim();return q}async executeHooksConcurrently(O,q,Q,Z){let Y=[],$=new Set;for(let X of O){if($.size>=Z)await Promise.race($);let W=this.executeHook(X,q,Q).catch((G)=>({success:!1,blocking:!1,error:G instanceof Error?G.message:String(G),hook:X})),J=W.then(()=>{$.delete(J)}).catch(()=>{$.delete(J)});$.add(J),Y.push(W)}return Promise.all(Y)}}async function HO(O,q){let Q=O.body?.getReader();if(!Q)return"";let Z=new TextDecoder,Y=0,$="";while(!0){let{value:X,done:W}=await Q.read();if(W)break;if(Y+=X.byteLength,Y>q){try{Q.cancel()}catch{}$+=Z.decode(X.slice(0,q-(Y-X.byteLength)));break}$+=Z.decode(X,{stream:!0})}return $+=Z.decode(),$}import a from"picomatch";var IO=/^([A-Za-z0-9_|]+)\((.+)\)$/;class i{matches(O,q){if(!O)return!0;if(O.tools&&q.toolName){if(!this.matchTools(O.tools,q))return!1}if(O.paths){let Q=q.filePaths??(q.filePath?[q.filePath]:[]);if(Q.length===0||!Q.some((Z)=>this.matchPaths(O.paths,Z)))return!1}if(O.commands&&q.command){if(!this.matchCommands(O.commands,q.command))return!1}return!0}matchTools(O,q){if(Array.isArray(O))return O.some((Q)=>this.matchToolWithParams(Q,q));return this.matchToolWithParams(O,q)}matchPaths(O,q){if(Array.isArray(O))return O.some((Z)=>{return a(Z)(q)});return a(O)(q)}matchCommands(O,q){if(Array.isArray(O))return O.some((Q)=>this.matchPattern(q,Q));return this.matchPattern(q,O)}matchToolWithParams(O,q){let{toolName:Q,command:Z,filePath:Y}=q,$=IO.exec(O);if(!$)return this.matchPattern(Q,O);let[,X,W]=$;if(!this.matchPattern(Q,X))return!1;let J=this.getArgValues(Q,Z,q.filePaths??(Y?[Y]:[]));if(J.length===0)return!1;return J.some((G)=>this.matchGlobOrPattern(G,W))}getArgValues(O,q,Q=[]){if(O==="Bash"||O==="BashTool")return q?[q]:[];if(["Read","Edit","Write","ApplyPatch","Glob","Grep"].includes(O))return Q;return q?[q]:Q}matchGlobOrPattern(O,q){if(/[*?[\]{}!]/.test(q))try{return a(q,{bash:!0,dot:!0})(O)}catch{}if(q.endsWith("*")){let Q=q.slice(0,-1);return O.startsWith(Q)}return O===q}matchPattern(O,q){if(q==="*")return!0;if(!q.includes("|")&&!/[.*+?^${}()|[\]\\]/.test(q))return O===q;if(q.includes("|"))return q.split("|").map((Z)=>Z.trim()).includes(O);try{return new RegExp(q).test(O)}catch{return O===q}}}var WO=64;class _{static instance=null;config=N;executor=new x;guard=new d;matcher=new i;processDisabled=!1;disabledSessions=new Set;sessionStateAliases=new Map;projectConfigs=new fO({max:WO});sessionConfigs=new Map;managedFunctionMatchers={};constructor(){}static getInstance(){if(!_.instance)_.instance=new _;return _.instance}bindSessionModelResources(O,q,Q){this.executor.bindSessionModelResources(O,q,Q)}bindSessionEnvironment(O,q,Q){this.executor.bindSessionEnvironment(O,q,Q)}bindSessionConfig(O,q,Q){let Z=this.sessionConfigKey(O,q[0]??P()),Y=this.disabledSessions.has(Z);for(let $ of q){let X=this.sessionConfigKey(O,$);if(Y||=this.disabledSessions.has(X),this.sessionStateAliases.set(X,Z),this.sessionConfigs.set(X,this.snapshotConfig(Q)),X!==Z)this.disabledSessions.delete(X)}if(Y)this.disabledSessions.add(Z)}async unbindSessionModelResources(O,q){let Q=`${O}\x00`;for(let Z of this.sessionConfigs.keys()){if(!Z.startsWith(Q))continue;this.sessionConfigs.delete(Z)}for(let Z of this.sessionStateAliases.keys()){if(!Z.startsWith(Q))continue;this.sessionStateAliases.delete(Z)}for(let Z of this.disabledSessions){if(!Z.startsWith(Q))continue;this.disabledSessions.delete(Z)}await this.executor.unbindSessionModelResources(O,q)}static resetInstance(){_.instance?.cleanup(),_.instance=null}loadConfig(O,q=P()){let Q=E(N,O),Z=c();Q=E(Q,Z),this.storeProjectConfig(q,Q)}isEnabled(O=P(),q){if(!(q?this.getExecutionConfig(q,O):this.getConfig(O)).enabled)return!1;if(this.processDisabled)return!1;if(q&&this.disabledSessions.has(this.sessionStateKey(q,O)))return!1;return!0}disable(){this.processDisabled=!0,console.log("[HookManager] Hooks disabled for this process")}enable(){this.processDisabled=!1,console.log("[HookManager] Hooks enabled for this process")}disableSession(O,q){this.disabledSessions.add(this.sessionStateKey(O,q))}enableSession(O,q){this.disabledSessions.delete(this.sessionStateKey(O,q))}isSessionEnabled(O,q){return this.isEnabled(q,O)}isSessionPaused(O,q){return this.disabledSessions.has(this.sessionStateKey(O,q))}getConfig(O=P()){let q=C.resolve(O),Q=this.projectConfigs.get(q);if(Q)return Q;if(q===C.resolve(P()))return this.config;return{...N,enabled:!1}}getExecutionConfig(O,q){return this.sessionConfigs.get(this.sessionConfigKey(O,q))??this.getConfig(q)}isExecutionEnabled(O,q,Q){return O.enabled===!0&&!this.processDisabled&&!this.disabledSessions.has(this.sessionStateKey(q,Q))}sessionStateKey(O,q){let Q=this.sessionConfigKey(O,q);return this.sessionStateAliases.get(Q)??Q}sessionConfigKey(O,q){return`${O}\x00${C.resolve(q)}`}snapshotConfig(O){let q=E(N,O);for(let Q of Object.values(b))q[Q]=(O[Q]??[]).map((Z)=>({...Z,matcher:Z.matcher?{...Z.matcher}:void 0,hooks:Z.hooks.map((Y)=>({...Y}))}));return q}storeProjectConfig(O,q){let Q=C.resolve(O);if(Q===C.resolve(P())){this.config=q,this.projectConfigs.delete(Q);return}this.projectConfigs.set(Q,q)}inheritProjectConfig(O,q,Q){let Z=Q?this.getExecutionConfig(Q,O):this.getConfig(O);if(this.storeProjectConfig(q,this.snapshotConfig(Z)),!Q)return;let Y=this.sessionConfigKey(Q,O),$=this.sessionConfigKey(Q,q),X=this.sessionStateAliases.get(Y)??Y,W=this.disabledSessions.has(X)||this.disabledSessions.has($);if(this.sessionConfigs.set($,this.snapshotConfig(Z)),this.sessionStateAliases.set($,X),$!==X)this.disabledSessions.delete($);if(W)this.disabledSessions.add(X)}getResidencyStats(){return{projectCapacity:WO,projectConfigs:this.projectConfigs.size,sessionConfigs:this.sessionConfigs.size,sessionAliases:this.sessionStateAliases.size}}getTrustStatus(O=P()){return A.getInstance().getStatus(O,this.getConfig(O))}trustProject(O=P(),q){return A.getInstance().trust(O,this.getConfig(O),q)}revokeProjectTrust(O=P()){return A.getInstance().revoke(O,this.getConfig(O))}registerFunction(O,q,Q,Z){let Y={type:"function",handler:Q,timeout:Z?.timeout},$={name:Z?.name??`inline-${O}-${Date.now()}`,matcher:q,hooks:[Y]};if(Z?.projectDir){let W=C.resolve(Z.projectDir),J=this.getConfig(W),G=J[O]??[];return J[O]=[...G,$],this.storeProjectConfig(W,J),()=>{let L=J[O];if(!L)return;J[O]=L.filter((F)=>F!==$)}}let X=this.managedFunctionMatchers[O]??[];return this.managedFunctionMatchers[O]=[...X,$],()=>{let W=this.managedFunctionMatchers[O]??[];this.managedFunctionMatchers[O]=W.filter((J)=>J!==$)}}async reloadConfig(O=P()){let q=await import("node:fs/promises"),Q=await import("node:path");try{let Z=Q.join(O,".blade","settings.local.json"),Y=await q.readFile(Z,"utf-8"),$=JSON.parse(Y);if($.hooks)this.loadConfig($.hooks,O)}catch{}}async executePreToolHooks(O,q,Q,Z){let Y=this.getExecutionConfig(Z.sessionId,Z.projectDir);if(!this.isExecutionEnabled(Y,Z.sessionId,Z.projectDir))return{decision:"allow"};if(Z.permissionMode==="plan")return{decision:"allow"};if(!this.guard.canExecute(q,"PreToolUse"))return{decision:"allow"};let $={hook_event_name:"PreToolUse",hook_execution_id:R(),timestamp:new Date().toISOString(),tool_name:O,tool_use_id:q,tool_input:Q,project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode},X=this.getMatchingHooks("PreToolUse",{toolName:O,filePath:this.extractFilePaths(Q)[0],filePaths:this.extractFilePaths(Q),command:this.extractCommand(O,Q)},Y);if(X.length===0)return{decision:"allow"};let W={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:Y,abortSignal:Z.abortSignal};try{let J=await this.executor.executePreToolHooks(X,$,W);if(this.guard.markExecuted(q,"PreToolUse"),Z.permissionMode==="yolo"){if(J.decision==="deny")return J;return{decision:"allow",modifiedInput:J.modifiedInput,warning:J.warning,reason:J.reason}}return J}catch(J){return console.error("[HookManager] Error executing PreToolUse hooks:",J),{decision:"allow",warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executePostToolHooks(O,q,Q,Z,Y){let $=this.getExecutionConfig(Y.sessionId,Y.projectDir);if(!this.isExecutionEnabled($,Y.sessionId,Y.projectDir))return{};if(Y.permissionMode==="plan")return{};if(!this.guard.canExecute(q,"PostToolUse"))return{};let X={hook_event_name:"PostToolUse",hook_execution_id:R(),timestamp:new Date().toISOString(),tool_name:O,tool_use_id:q,tool_input:Q,tool_response:Z,project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode},W=this.getMatchingHooks("PostToolUse",{toolName:O,filePath:this.extractFilePaths(Q)[0],filePaths:this.extractFilePaths(Q),command:this.extractCommand(O,Q)},$);if(W.length===0)return{};let J={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:$,abortSignal:Y.abortSignal};try{let G=await this.executor.executePostToolHooks(W,X,J);return this.guard.markExecuted(q,"PostToolUse"),G}catch(G){return console.error("[HookManager] Error executing PostToolUse hooks:",G),{warning:`Hook execution failed: ${G instanceof Error?G.message:String(G)}`}}finally{this.guard.cleanup(q)}}async executeStopHooks(O){let q=this.getExecutionConfig(O.sessionId,O.projectDir);if(!this.isExecutionEnabled(q,O.sessionId,O.projectDir))return{shouldStop:!0};let Q={hook_event_name:"Stop",hook_execution_id:R(),timestamp:new Date().toISOString(),project_dir:O.projectDir,session_id:O.sessionId,permission_mode:O.permissionMode,reason:O.reason},Z=this.getMatchingHooks("Stop",{},q);if(Z.length===0)return{shouldStop:!0};let Y={projectDir:O.projectDir,sessionId:O.sessionId,permissionMode:O.permissionMode,config:q,abortSignal:O.abortSignal};try{return await this.executor.executeStopHooks(Z,Q,Y)}catch($){return console.error("[HookManager] Error executing Stop hooks:",$),{shouldStop:!0,warning:`Hook execution failed: ${$ instanceof Error?$.message:String($)}`}}}async executeSubagentStopHooks(O,q){let Q=this.getExecutionConfig(q.sessionId,q.projectDir);if(!this.isExecutionEnabled(Q,q.sessionId,q.projectDir))return{shouldStop:!0};let Z={hook_event_name:"SubagentStop",hook_execution_id:R(),timestamp:new Date().toISOString(),project_dir:q.projectDir,session_id:q.sessionId,permission_mode:q.permissionMode,agent_type:O,task_description:q.taskDescription,success:q.success,result_summary:q.resultSummary,error:q.error},Y=this.getMatchingHooks("SubagentStop",{},Q);if(Y.length===0)return{shouldStop:!0};let $={projectDir:q.projectDir,sessionId:q.sessionId,permissionMode:q.permissionMode,config:Q,abortSignal:q.abortSignal};try{return await this.executor.executeSubagentStopHooks(Y,Z,$)}catch(X){return console.error("[HookManager] Error executing SubagentStop hooks:",X),{shouldStop:!0,warning:`Hook execution failed: ${X instanceof Error?X.message:String(X)}`}}}async executePermissionRequestHooks(O,q,Q,Z){let Y=this.getExecutionConfig(Z.sessionId,Z.projectDir);if(!this.isExecutionEnabled(Y,Z.sessionId,Z.projectDir))return{decision:"ask"};let $={hook_event_name:"PermissionRequest",hook_execution_id:R(),timestamp:new Date().toISOString(),tool_name:O,tool_use_id:q,tool_input:Q,project_dir:Z.projectDir,session_id:Z.sessionId,permission_mode:Z.permissionMode},X=this.getMatchingHooks("PermissionRequest",{toolName:O,filePath:this.extractFilePaths(Q)[0],filePaths:this.extractFilePaths(Q),command:this.extractCommand(O,Q)},Y);if(X.length===0)return{decision:"ask"};let W={projectDir:Z.projectDir,sessionId:Z.sessionId,permissionMode:Z.permissionMode,config:Y,abortSignal:Z.abortSignal};try{return await this.executor.executePermissionRequestHooks(X,$,W)}catch(J){return console.error("[HookManager] Error executing PermissionRequest hooks:",J),{decision:"ask",warning:`Hook execution failed: ${J instanceof Error?J.message:String(J)}`}}}async executeUserPromptSubmitHooks(O,q){let Q=this.getExecutionConfig(q.sessionId,q.projectDir);if(!this.isExecutionEnabled(Q,q.sessionId,q.projectDir))return{proceed:!0};let Z={hook_event_name:"UserPromptSubmit",hook_execution_id:R(),timestamp:new Date().toISOString(),user_prompt:O,has_images:q.hasImages,image_count:q.imageCount,project_dir:q.projectDir,session_id:q.sessionId,permission_mode:q.permissionMode},Y=this.getMatchingHooks("UserPromptSubmit",{},Q);if(Y.length===0)return{proceed:!0};let $={projectDir:q.projectDir,sessionId:q.sessionId,permissionMode:q.permissionMode,config:Q,abortSignal:q.abortSignal};try{return await this.executor.executeUserPromptSubmitHooks(Y,Z,$)}catch(X){return console.error("[HookManager] Error executing UserPromptSubmit hooks:",X),{proceed:!0,warning:`Hook execution failed: ${X instanceof Error?X.message:String(X)}`}}}async executeSessionStartHooks(O){let q=this.getExecutionConfig(O.sessionId,O.projectDir);if(!this.isExecutionEnabled(q,O.sessionId,O.projectDir))return{proceed:!0};let Q={hook_event_name:"SessionStart",hook_execution_id:R(),timestamp:new Date().toISOString(),project_dir:O.projectDir,session_id:O.sessionId,permission_mode:O.permissionMode,is_resume:O.isResume,resume_session_id:O.resumeSessionId},Z=this.getMatchingHooks("SessionStart",{},q);if(Z.length===0)return{proceed:!0};let Y={projectDir:O.projectDir,sessionId:O.sessionId,permissionMode:O.permissionMode,config:q,abortSignal:O.abortSignal};try{return await this.executor.executeSessionStartHooks(Z,Q,Y)}catch($){return console.error("[HookManager] Error executing SessionStart hooks:",$),{proceed:!0,warning:`Hook execution failed: ${$ instanceof Error?$.message:String($)}`}}}async executeSessionEndHooks(O,q){let Q=this.getExecutionConfig(q.sessionId,q.projectDir);if(!this.isExecutionEnabled(Q,q.sessionId,q.projectDir))return{};let Z={hook_event_name:"SessionEnd",hook_execution_id:R(),timestamp:new Date().toISOString(),project_dir:q.projectDir,session_id:q.sessionId,permission_mode:q.permissionMode,reason:O},Y=this.getMatchingHooks("SessionEnd",{},Q);if(Y.length===0)return{};let $={projectDir:q.projectDir,sessionId:q.sessionId,permissionMode:q.permissionMode,config:Q,abortSignal:q.abortSignal};try{return await this.executor.executeSessionEndHooks(Y,Z,$),{}}catch(X){return console.error("[HookManager] Error executing SessionEnd hooks:",X),{warning:`Hook execution failed: ${X instanceof Error?X.message:String(X)}`}}}async executePostToolUseFailureHooks(O,q,Q,Z,Y){let $=this.getExecutionConfig(Y.sessionId,Y.projectDir);if(!this.isExecutionEnabled($,Y.sessionId,Y.projectDir))return{};let X={hook_event_name:"PostToolUseFailure",hook_execution_id:R(),timestamp:new Date().toISOString(),tool_name:O,tool_use_id:q,tool_input:Q,error:Z,error_type:Y.errorType,is_interrupt:Y.isInterrupt,is_timeout:Y.isTimeout,project_dir:Y.projectDir,session_id:Y.sessionId,permission_mode:Y.permissionMode},W=this.getMatchingHooks("PostToolUseFailure",{toolName:O,filePath:this.extractFilePaths(Q)[0],filePaths:this.extractFilePaths(Q),command:this.extractCommand(O,Q)},$);if(W.length===0)return{};let J={projectDir:Y.projectDir,sessionId:Y.sessionId,permissionMode:Y.permissionMode,config:$,abortSignal:Y.abortSignal};try{return await this.executor.executePostToolUseFailureHooks(W,X,J)}catch(G){return console.error("[HookManager] Error executing PostToolUseFailure hooks:",G),{warning:`Hook execution failed: ${G instanceof Error?G.message:String(G)}`}}}async executeNotificationHooks(O,q,Q){let Z=this.getExecutionConfig(Q.sessionId,Q.projectDir);if(!this.isExecutionEnabled(Z,Q.sessionId,Q.projectDir))return{suppress:!1,message:q};let Y={hook_event_name:"Notification",hook_execution_id:R(),timestamp:new Date().toISOString(),project_dir:Q.projectDir,session_id:Q.sessionId,permission_mode:Q.permissionMode,notification_type:O,title:Q.title,message:q},$=this.getMatchingHooks("Notification",{},Z);if($.length===0)return{suppress:!1,message:q};let X={projectDir:Q.projectDir,sessionId:Q.sessionId,permissionMode:Q.permissionMode,config:Z,abortSignal:Q.abortSignal};try{return await this.executor.executeNotificationHooks($,Y,X)}catch(W){return console.error("[HookManager] Error executing Notification hooks:",W),{suppress:!1,message:q,warning:`Hook execution failed: ${W instanceof Error?W.message:String(W)}`}}}async executeElicitationHooks(O,q){let Q=this.getExecutionConfig(q.sessionId,q.projectDir);if(!this.isExecutionEnabled(Q,q.sessionId,q.projectDir))return{};let Z={hook_event_name:"Elicitation",hook_execution_id:R(),timestamp:new Date().toISOString(),project_dir:q.projectDir,session_id:q.sessionId,permission_mode:q.permissionMode,server_name:O.serverName,mode:O.mode,message:O.message,requested_schema:O.requestedSchema,url:O.url,elicitation_id:O.elicitationId};return this.executeElicitationHookChain("Elicitation",Z,q,Q)}async executeElicitationResultHooks(O,q,Q){let Z=this.getExecutionConfig(Q.sessionId,Q.projectDir);if(!this.isExecutionEnabled(Z,Q.sessionId,Q.projectDir))return{};let Y={hook_event_name:"ElicitationResult",hook_execution_id:R(),timestamp:new Date().toISOString(),project_dir:Q.projectDir,session_id:Q.sessionId,permission_mode:Q.permissionMode,server_name:O.serverName,mode:O.mode,elicitation_id:O.elicitationId,action:q.action,content:q.content};return this.executeElicitationHookChain("ElicitationResult",Y,Q,Z)}async executeElicitationHookChain(O,q,Q,Z){let Y=this.getMatchingHooks(O,{},Z);if(Y.length===0)return{};let $={projectDir:Q.projectDir,sessionId:Q.sessionId,permissionMode:Q.permissionMode,config:Z,abortSignal:Q.abortSignal};try{return await this.executor.executeElicitationHooks(Y,q,$)}catch(X){return{warning:`Hook execution failed: ${X instanceof Error?X.message:String(X)}`}}}async executeCompactionHooks(O,q){let Q=this.getExecutionConfig(q.sessionId,q.projectDir);if(!this.isExecutionEnabled(Q,q.sessionId,q.projectDir))return{blockCompaction:!1};let Z={hook_event_name:"Compaction",hook_execution_id:R(),timestamp:new Date().toISOString(),project_dir:q.projectDir,session_id:q.sessionId,permission_mode:q.permissionMode,trigger:O,messages_before:q.messagesBefore,tokens_before:q.tokensBefore},Y=this.getMatchingHooks("Compaction",{},Q);if(Y.length===0)return{blockCompaction:!1};let $={projectDir:q.projectDir,sessionId:q.sessionId,permissionMode:q.permissionMode,config:Q,abortSignal:q.abortSignal};try{return await this.executor.executeCompactionHooks(Y,Z,$)}catch(X){return console.error("[HookManager] Error executing Compaction hooks:",X),{blockCompaction:!1,warning:`Hook execution failed: ${X instanceof Error?X.message:String(X)}`}}}getMatchingHooks(O,q,Q){let Z=[...Q[O]??[],...this.managedFunctionMatchers[O]??[]],Y=[];for(let $ of Z)if(this.matcher.matches($.matcher,q))Y.push(...$.hooks);return Y}extractFilePaths(O){let q=[],Q=["file_path","path","filePath","source","target"];for(let Z of Q){let Y=O[Z];if(typeof Y==="string")q.push(Y)}if(typeof O.patch==="string"){for(let Z of O.patch.matchAll(/^\*\*\* (?:Add|Delete|Update) File: (.+)$/gm))if(Z[1])q.push(Z[1]);for(let Z of O.patch.matchAll(/^\*\*\* Move to: (.+)$/gm))if(Z[1])q.push(Z[1])}return[...new Set(q)]}extractCommand(O,q){if(O==="Bash"||O==="BashTool"){let Q=q.command;if(typeof Q==="string")return Q}return}cleanup(){this.guard.cleanupAll(),this.config=N,this.processDisabled=!1,this.disabledSessions.clear(),this.sessionStateAliases.clear(),this.projectConfigs.clear(),this.sessionConfigs.clear(),this.managedFunctionMatchers={}}}
45
- export{b as pf,o as qf,_ as rf};
45
+ export{b as sf,o as tf,_ as uf};
@@ -1,2 +1,2 @@
1
- import{K as I}from"./chunk-rkp180w6.js";import{Vc as M}from"./chunk-m0dt3w7w.js";import P from"node:path";function w(s){let a=s.replace(/\s+/g," ").trim();return a.length<=72?a:`${a.slice(0,69)}...`}function W(s){let a=s.replace(/\s+/g," ").trim();return a.length<=500?a:`${a.slice(0,497)}...`}function A(s){return`task/${s.replace(/[^a-zA-Z0-9_-]/g,"-").slice(0,40)}`}class C{static async createSessionTask(s){if(!s.prompt.trim())throw Error("Task prompt must not be blank");if(!P.isAbsolute(s.sourceProjectPath))throw Error("Task source project path must be absolute");let a=P.resolve(s.sourceProjectPath),t;try{return t=s.isolation==="worktree"?await I.enter({sessionId:s.sessionId,workspaceRoot:a,name:A(s.sessionId)}):void 0,{metadata:await M.createSessionMetadata(s.sessionId,t?.workspaceRoot??a,{title:s.title?.trim()||w(s.prompt),taskPromptSummary:W(s.prompt),taskPriority:s.taskPriority,taskKind:s.taskKind,taskDueAt:s.taskDueAt,taskDispatch:s.dispatch,taskModelId:s.dispatch?.modelId,selectedModelId:s.dispatch?.modelId,permissionMode:s.dispatch?.permissionMode,reasoningEffort:s.dispatch?.reasoningEffort,serviceTier:s.dispatch?.serviceTier,responseVerbosity:s.dispatch?.responseVerbosity,communicationStyle:s.dispatch?.communicationStyle,communicationStyleDigest:s.dispatch?.communicationStyleDigest,projectInstructionsDigest:s.dispatch?.projectInstructionsDigest,taskRetriedFrom:s.retriedFrom,taskIsolation:s.isolation,taskSourceProjectPath:a,taskWorktree:t}),taskWorktree:t}}catch(k){if(t)await I.exit({sessionId:s.sessionId,action:"remove",discardChanges:!0}).catch(()=>{return});throw k}}}var $=256,V=8388608,x=30000;class i extends Error{kind;pendingItems;pendingBytes;constructor(s,a,t){super(a,t);this.kind=s;this.name="BoundedSerialEgressError",this.pendingItems=t?.pendingItems,this.pendingBytes=t?.pendingBytes}}function T(s){s.catch(()=>{return})}class K{options;pending=[];flushWaiters=[];pendingBytes=0;nextSequence=0;completedSequence=0;draining=!1;closed=!1;failure;activeWriteAbort;activeWriteStop;activeWriteTimeout;constructor(s){this.options=s;if(this.assertPositiveInteger(s.maxPendingItems,"maxPendingItems"),this.assertPositiveInteger(s.maxPendingBytes,"maxPendingBytes"),this.assertPositiveInteger(s.writeTimeoutMs,"writeTimeoutMs"),s.signal?.addEventListener("abort",this.handleAbort,{once:!0}),s.signal?.aborted)this.handleAbort()}offer(s){if(this.closed)return{accepted:!1,error:this.failure??new i("closed","Egress is already closed")};let a;try{a=this.options.sizeOf(s)}catch(h){return this.rejectAdmission(new i("invalid_size","Egress size calculation failed",{cause:h}))}if(!Number.isSafeInteger(a)||a<0)return this.rejectAdmission(new i("invalid_size","Egress size must be a non-negative safe integer"));if(a>this.options.maxPendingBytes)return this.rejectAdmission(new i("oversized",`Egress value requires ${a} bytes; limit is ${this.options.maxPendingBytes}`));if(this.pending.length>=this.options.maxPendingItems||this.pendingBytes+a>this.options.maxPendingBytes)return this.rejectAdmission(new i("overflow",`Egress pending limit exceeded (${this.pending.length} items, ${this.pendingBytes} bytes)`));let t,k,c=new Promise((h,m)=>{t=h,k=m});return T(c),this.nextSequence+=1,this.pending.push({value:s,bytes:a,sequence:this.nextSequence,resolve:t,reject:k,completion:c}),this.pendingBytes+=a,this.startDrain(),{accepted:!0,completion:c}}flush(){if(this.failure){let c=Promise.reject(this.failure);return T(c),c}let s=this.nextSequence;if(s<=this.completedSequence)return Promise.resolve();let a,t,k=new Promise((c,h)=>{a=c,t=h});return T(k),this.flushWaiters.push({targetSequence:s,resolve:a,reject:t}),k}close(s){let a=s instanceof i?s:new i("closed","Egress was closed",{cause:s});this.fail(a)}stats(){return{closed:this.closed,pendingItems:this.pending.length,pendingBytes:this.pendingBytes}}handleAbort=()=>{this.fail(new i("aborted","Egress was aborted",{cause:this.options.signal?.reason}))};rejectAdmission(s){return this.fail(s),{accepted:!1,error:s}}startDrain(){if(this.draining||this.closed)return;this.draining=!0;let s=this.drain();T(s)}async drain(){try{while(!this.closed){let s=this.pending[0];if(!s)return;try{await this.writeOne(s.value)}catch(a){this.fail(this.normalizeWriteError(a));return}if(this.closed||this.pending[0]!==s)return;this.pending.shift(),this.pendingBytes-=s.bytes,this.completedSequence=s.sequence,s.resolve(),this.settleFlushWaiters()}}finally{if(this.draining=!1,!this.closed&&this.pending.length>0)this.startDrain()}}async writeOne(s){let a=new AbortController;this.activeWriteAbort=a;let t,k,c=new Promise((S,f)=>{k=f});T(c),this.activeWriteStop=k;let h=Promise.resolve().then(()=>this.options.write(s,a.signal));T(h);let m=new Promise((S,f)=>{t=setTimeout(()=>{let D=new i("write_timeout",`Egress write timed out after ${this.options.writeTimeoutMs}ms`);a.abort(D),f(D)},this.options.writeTimeoutMs),this.activeWriteTimeout=t});T(m);try{await Promise.race([h,m,c])}finally{if(t!==void 0)clearTimeout(t);if(this.activeWriteTimeout===t)this.activeWriteTimeout=void 0;if(this.activeWriteAbort===a)this.activeWriteAbort=void 0;if(this.activeWriteStop===k)this.activeWriteStop=void 0}}normalizeWriteError(s){if(s instanceof i)return s;return new i("write_failed","Egress write failed",{cause:s})}fail(s){if(this.closed)return;if(s.pendingItems??=this.pending.length,s.pendingBytes??=this.pendingBytes,this.closed=!0,this.failure=s,this.options.signal?.removeEventListener("abort",this.handleAbort),this.activeWriteTimeout!==void 0)clearTimeout(this.activeWriteTimeout),this.activeWriteTimeout=void 0;this.activeWriteAbort?.abort(s),this.activeWriteStop?.(s),this.activeWriteAbort=void 0,this.activeWriteStop=void 0;let a=this.pending.splice(0);this.pendingBytes=0;for(let t of a)t.reject(s);for(let t of this.flushWaiters.splice(0))t.reject(s);try{this.options.onFailure?.(s)}catch{}}settleFlushWaiters(){for(let s=0;s<this.flushWaiters.length;){let a=this.flushWaiters[s];if(a.targetSequence>this.completedSequence){s+=1;continue}this.flushWaiters.splice(s,1),a.resolve()}}assertPositiveInteger(s,a){if(!Number.isSafeInteger(s)||s<=0)throw RangeError(`${a} must be a positive safe integer`)}}
1
+ import{K as I}from"./chunk-xy67pj74.js";import{Yc as M}from"./chunk-2b7zryg3.js";import P from"node:path";function w(s){let a=s.replace(/\s+/g," ").trim();return a.length<=72?a:`${a.slice(0,69)}...`}function W(s){let a=s.replace(/\s+/g," ").trim();return a.length<=500?a:`${a.slice(0,497)}...`}function A(s){return`task/${s.replace(/[^a-zA-Z0-9_-]/g,"-").slice(0,40)}`}class C{static async createSessionTask(s){if(!s.prompt.trim())throw Error("Task prompt must not be blank");if(!P.isAbsolute(s.sourceProjectPath))throw Error("Task source project path must be absolute");let a=P.resolve(s.sourceProjectPath),t;try{return t=s.isolation==="worktree"?await I.enter({sessionId:s.sessionId,workspaceRoot:a,name:A(s.sessionId)}):void 0,{metadata:await M.createSessionMetadata(s.sessionId,t?.workspaceRoot??a,{title:s.title?.trim()||w(s.prompt),taskPromptSummary:W(s.prompt),taskPriority:s.taskPriority,taskKind:s.taskKind,taskDueAt:s.taskDueAt,taskDispatch:s.dispatch,taskModelId:s.dispatch?.modelId,selectedModelId:s.dispatch?.modelId,permissionMode:s.dispatch?.permissionMode,reasoningEffort:s.dispatch?.reasoningEffort,serviceTier:s.dispatch?.serviceTier,responseVerbosity:s.dispatch?.responseVerbosity,communicationStyle:s.dispatch?.communicationStyle,communicationStyleDigest:s.dispatch?.communicationStyleDigest,projectInstructionsDigest:s.dispatch?.projectInstructionsDigest,taskRetriedFrom:s.retriedFrom,taskIsolation:s.isolation,taskSourceProjectPath:a,taskWorktree:t}),taskWorktree:t}}catch(k){if(t)await I.exit({sessionId:s.sessionId,action:"remove",discardChanges:!0}).catch(()=>{return});throw k}}}var $=256,V=8388608,x=30000;class i extends Error{kind;pendingItems;pendingBytes;constructor(s,a,t){super(a,t);this.kind=s;this.name="BoundedSerialEgressError",this.pendingItems=t?.pendingItems,this.pendingBytes=t?.pendingBytes}}function T(s){s.catch(()=>{return})}class K{options;pending=[];flushWaiters=[];pendingBytes=0;nextSequence=0;completedSequence=0;draining=!1;closed=!1;failure;activeWriteAbort;activeWriteStop;activeWriteTimeout;constructor(s){this.options=s;if(this.assertPositiveInteger(s.maxPendingItems,"maxPendingItems"),this.assertPositiveInteger(s.maxPendingBytes,"maxPendingBytes"),this.assertPositiveInteger(s.writeTimeoutMs,"writeTimeoutMs"),s.signal?.addEventListener("abort",this.handleAbort,{once:!0}),s.signal?.aborted)this.handleAbort()}offer(s){if(this.closed)return{accepted:!1,error:this.failure??new i("closed","Egress is already closed")};let a;try{a=this.options.sizeOf(s)}catch(h){return this.rejectAdmission(new i("invalid_size","Egress size calculation failed",{cause:h}))}if(!Number.isSafeInteger(a)||a<0)return this.rejectAdmission(new i("invalid_size","Egress size must be a non-negative safe integer"));if(a>this.options.maxPendingBytes)return this.rejectAdmission(new i("oversized",`Egress value requires ${a} bytes; limit is ${this.options.maxPendingBytes}`));if(this.pending.length>=this.options.maxPendingItems||this.pendingBytes+a>this.options.maxPendingBytes)return this.rejectAdmission(new i("overflow",`Egress pending limit exceeded (${this.pending.length} items, ${this.pendingBytes} bytes)`));let t,k,c=new Promise((h,m)=>{t=h,k=m});return T(c),this.nextSequence+=1,this.pending.push({value:s,bytes:a,sequence:this.nextSequence,resolve:t,reject:k,completion:c}),this.pendingBytes+=a,this.startDrain(),{accepted:!0,completion:c}}flush(){if(this.failure){let c=Promise.reject(this.failure);return T(c),c}let s=this.nextSequence;if(s<=this.completedSequence)return Promise.resolve();let a,t,k=new Promise((c,h)=>{a=c,t=h});return T(k),this.flushWaiters.push({targetSequence:s,resolve:a,reject:t}),k}close(s){let a=s instanceof i?s:new i("closed","Egress was closed",{cause:s});this.fail(a)}stats(){return{closed:this.closed,pendingItems:this.pending.length,pendingBytes:this.pendingBytes}}handleAbort=()=>{this.fail(new i("aborted","Egress was aborted",{cause:this.options.signal?.reason}))};rejectAdmission(s){return this.fail(s),{accepted:!1,error:s}}startDrain(){if(this.draining||this.closed)return;this.draining=!0;let s=this.drain();T(s)}async drain(){try{while(!this.closed){let s=this.pending[0];if(!s)return;try{await this.writeOne(s.value)}catch(a){this.fail(this.normalizeWriteError(a));return}if(this.closed||this.pending[0]!==s)return;this.pending.shift(),this.pendingBytes-=s.bytes,this.completedSequence=s.sequence,s.resolve(),this.settleFlushWaiters()}}finally{if(this.draining=!1,!this.closed&&this.pending.length>0)this.startDrain()}}async writeOne(s){let a=new AbortController;this.activeWriteAbort=a;let t,k,c=new Promise((S,f)=>{k=f});T(c),this.activeWriteStop=k;let h=Promise.resolve().then(()=>this.options.write(s,a.signal));T(h);let m=new Promise((S,f)=>{t=setTimeout(()=>{let D=new i("write_timeout",`Egress write timed out after ${this.options.writeTimeoutMs}ms`);a.abort(D),f(D)},this.options.writeTimeoutMs),this.activeWriteTimeout=t});T(m);try{await Promise.race([h,m,c])}finally{if(t!==void 0)clearTimeout(t);if(this.activeWriteTimeout===t)this.activeWriteTimeout=void 0;if(this.activeWriteAbort===a)this.activeWriteAbort=void 0;if(this.activeWriteStop===k)this.activeWriteStop=void 0}}normalizeWriteError(s){if(s instanceof i)return s;return new i("write_failed","Egress write failed",{cause:s})}fail(s){if(this.closed)return;if(s.pendingItems??=this.pending.length,s.pendingBytes??=this.pendingBytes,this.closed=!0,this.failure=s,this.options.signal?.removeEventListener("abort",this.handleAbort),this.activeWriteTimeout!==void 0)clearTimeout(this.activeWriteTimeout),this.activeWriteTimeout=void 0;this.activeWriteAbort?.abort(s),this.activeWriteStop?.(s),this.activeWriteAbort=void 0,this.activeWriteStop=void 0;let a=this.pending.splice(0);this.pendingBytes=0;for(let t of a)t.reject(s);for(let t of this.flushWaiters.splice(0))t.reject(s);try{this.options.onFailure?.(s)}catch{}}settleFlushWaiters(){for(let s=0;s<this.flushWaiters.length;){let a=this.flushWaiters[s];if(a.targetSequence>this.completedSequence){s+=1;continue}this.flushWaiters.splice(s,1),a.resolve()}}assertPositiveInteger(s,a){if(!Number.isSafeInteger(s)||s<=0)throw RangeError(`${a} must be a positive safe integer`)}}
2
2
  export{C as v,$ as w,V as x,x as y,i as z,K as A};
@@ -1,2 +1,2 @@
1
1
  import{createRequire as a}from"node:module";var c=a(import.meta.url);
2
- export{c as Wh};
2
+ export{c as $h};
@@ -1,2 +1,2 @@
1
- import{yg as F}from"./chunk-cvy0pd00.js";import{th as D,uh as E}from"./chunk-5nezhmnq.js";import G from"node:path";function A(b){if(Array.isArray(b))return b.map((q)=>A(q));if(b!==null&&typeof b==="object"&&Object.getPrototypeOf(b)===Object.prototype)return Object.fromEntries(Object.entries(b).map(([q,w])=>[q,A(w)]));return b}function H(b){return A(b)}function I(b,q){let w=new D(q?.credentials??E().credentials);return w.configureModelProviders(b.modelProviders,b.models),w}async function Q(b,q){let w=G.resolve(b),x=F.getInstance(),[J,K]=await Promise.all([x.loadWorkspaceModelConfig(w,q),x.loadWorkspaceRuntimeSettings(w,q)]),z={...H(q),...J,...K},B=I(z);return x.validateConfig(z,B),{projectRoot:w,config:z,catalog:B}}function T(b){let q=H(b.config);return{projectRoot:G.resolve(b.projectRoot),config:q,catalog:I(q,b.catalog)}}
2
- export{H as ve,Q as we,T as xe};
1
+ import{Bg as F}from"./chunk-t6phsb5h.js";import{yh as D,zh as E}from"./chunk-t1633e8m.js";import G from"node:path";function A(b){if(Array.isArray(b))return b.map((q)=>A(q));if(b!==null&&typeof b==="object"&&Object.getPrototypeOf(b)===Object.prototype)return Object.fromEntries(Object.entries(b).map(([q,w])=>[q,A(w)]));return b}function H(b){return A(b)}function I(b,q){let w=new D(q?.credentials??E().credentials);return w.configureModelProviders(b.modelProviders,b.models),w}async function Q(b,q){let w=G.resolve(b),x=F.getInstance(),[J,K]=await Promise.all([x.loadWorkspaceModelConfig(w,q),x.loadWorkspaceRuntimeSettings(w,q)]),z={...H(q),...J,...K},B=I(z);return x.validateConfig(z,B),{projectRoot:w,config:z,catalog:B}}function T(b){let q=H(b.config);return{projectRoot:G.resolve(b.projectRoot),config:q,catalog:I(q,b.catalog)}}
2
+ export{H as ye,Q as ze,T as Ae};
@@ -0,0 +1 @@
1
+ import{Mh as a,Nh as b,Oh as c}from"./chunk-rwvaapta.js";import"./chunk-83caxxbt.js";import"./chunk-shr5cg46.js";import"./chunk-6jsmac0q.js";export{b as isWorkspaceTrusted,c as WorkspaceTrustService,a as MAX_RESIDENT_WORKSPACE_TRUST_STATUSES};
@@ -1,2 +1,2 @@
1
1
  var F;((D)=>{D.DEFAULT="default";D.AUTO_EDIT="autoEdit";D.YOLO="yolo";D.PLAN="plan"})(F||={});import{Mutex as G}from"async-mutex";class H{entries=new Map;async runExclusive(C,E){let B=this.entries.get(C);if(!B)B={mutex:new G,operations:0},this.entries.set(C,B);B.operations++;try{return await B.mutex.runExclusive(E)}finally{if(B.operations--,B.operations===0&&this.entries.get(C)===B)this.entries.delete(C)}}getStats(){let C=0;for(let E of this.entries.values())C+=E.operations;return{keys:this.entries.size,operations:C}}}
2
- export{F as Ag,H as Bg};
2
+ export{F as Dg,H as Eg};
@@ -1,2 +1,2 @@
1
1
  function v(b){switch(b){case"default":case"ignore":case void 0:return"default";case"acceptEdits":return"autoEdit";case"dontAsk":case"bypassPermissions":return"yolo";case"plan":return"plan";default:return"default"}}
2
- export{v as of};
2
+ export{v as rf};
@@ -1,5 +1,5 @@
1
- import{s as yz,t as hz}from"./chunk-sghq0p21.js";import{u as b}from"./chunk-bb1d4r3r.js";import{A as Bz,v as Tz,w as jz,x as Xz,y as Dz,z as Lz}from"./chunk-n57jybv7.js";import{E as N,L as Zz,M as $z,Q as Qz,T as Wz,U as Yz,Y as Hz,ma as Gz,na as Fz,oa as Uz,pa as Vz}from"./chunk-rkp180w6.js";import{za as bz}from"./chunk-pajdvkxa.js";import{Ba as Jz}from"./chunk-ky9q53m7.js";import{Eb as zz,jb as t,vb as e}from"./chunk-bhe154zk.js";import{Pb as k}from"./chunk-r8wbvxn7.js";import{Bc as o,Hc as I,Ic as n,Kc as x,Nc as s,Sc as P,Vc as F,gc as v,qc as l,rc as i,wc as r,zc as a}from"./chunk-m0dt3w7w.js";import"./chunk-skw3b17a.js";import"./chunk-jwx10h5z.js";import{yd as Sz}from"./chunk-vpcpcwyq.js";import"./chunk-h3w814js.js";import{Td as qz,Ud as Nz}from"./chunk-gdxm7yz5.js";import"./chunk-v508x7cg.js";import{de as C}from"./chunk-c9e0fbyh.js";import{ie as d}from"./chunk-seamt0j3.js";import"./chunk-33bpwkyk.js";import{te as Ez}from"./chunk-mygw13zd.js";import"./chunk-6at3v7hd.js";import"./chunk-e0ebj41c.js";import"./chunk-jzvbjn6e.js";import{jf as xz}from"./chunk-7nx0pzfk.js";import"./chunk-b9nhnzaj.js";import"./chunk-3e0dry5e.js";import"./chunk-zkhb55jz.js";import{bg as Rz,eg as Pz}from"./chunk-cvy0pd00.js";import"./chunk-pfvgkexe.js";import"./chunk-qxn5bg5k.js";import{Ig as S,Jg as m,Kg as M}from"./chunk-reakyamv.js";import{Og as _z}from"./chunk-0141jad7.js";import"./chunk-eeb2945p.js";import{oh as T}from"./chunk-b9vm7gns.js";import"./chunk-5nezhmnq.js";import{vh as Oz,yh as Az}from"./chunk-h6a0nct6.js";import"./chunk-411ewxte.js";import"./chunk-0a0sj79a.js";import"./chunk-sj0k8cdf.js";import{Uh as p}from"./chunk-0ra945vt.js";import"./chunk-h0fh3j9w.js";import{Readable as dz,Writable as vz}from"node:stream";import*as y from"@agentclientprotocol/sdk";import Kz from"node:path";import{PROTOCOL_VERSION as pz,RequestError as mz}from"@agentclientprotocol/sdk";import{RequestError as Iz}from"@agentclientprotocol/sdk";import{nanoid as h}from"nanoid";var G=T("Agent");function c(z){if(!z)return{};return Object.fromEntries(z.map((Z)=>[Z.name,Z.value]))}function Cz(z){if("command"in z)return{type:"stdio",command:z.command,args:z.args,env:c(z.env)};if("url"in z)return{type:z.type,url:z.url,headers:c("headers"in z?z.headers:void 0)};return null}function fz(z){let Z={};for(let J of z){let Y=Cz(J);if(Y)Z[J.name]=Y}return Z}function wz(z){if(typeof z==="string")return z?[{type:"text",text:z}]:[];return z.flatMap((Z)=>{if(Z.type==="text")return Z.text?[{type:"text",text:Z.text}]:[];let J=Z.image_url.url,Y=/^data:([^;,]+);base64,(.+)$/s.exec(J);if(!Y)return[{type:"text",text:"[Image]"}];return[{type:"image",mimeType:Y[1]??"image/png",data:Y[2]??""}]})}function uz(z){let Z=n(z.metadata);return Z?[{type:"text",text:I(Z)}]:wz(z.content)}function gz(z){return[`Status: ${z.status}`,`Exit code: ${z.exitCode??"null"}`,`Duration: ${(z.durationMs/1000).toFixed(3)} seconds`].join(`
2
- `)}function cz(z){if(!d(z)||z.reason!=="queue_full"||z.resource!=="pending_count"&&z.resource!=="pending_bytes")return;return{...l("capacity"),resource:z.resource}}class E{id;cwd;connection;clientCapabilities;options;agent=null;runtime=null;pendingPrompt=null;pendingPromptCompletion=null;pendingUserShell=null;pendingUserShellCompletion=null;pendingSideConversation=null;pendingSideConversationCompletion=null;pendingResumeRequested=!1;availableCommandsTimer=null;taskStatusUnsubscribe;destroyed=!1;destroyFinished=!1;destroyPromise;messages;contextMessages;mode;updateEgress;constructor(z,Z,J,Y,H={}){this.id=z;this.cwd=Z;this.connection=J;this.clientCapabilities=Y;this.options=H;this.messages=[...H.initialMessages??[]],this.contextMessages=[...this.messages],this.mode=this.mapPermissionModeToMode(H.permissionMode),this.updateEgress=new Bz({maxPendingItems:jz,maxPendingBytes:Xz,writeTimeoutMs:Dz,signal:J.signal,sizeOf:(W)=>Buffer.byteLength(JSON.stringify(W)),write:async(W)=>{await J.sessionUpdate(W)},onFailure:(W)=>this.handleUpdateEgressFailure(W)})}async refreshPersistedMessages(){let[z,Z]=await Promise.all([F.loadSession(this.id,this.cwd),F.loadSessionModelContext(this.id,this.cwd)]);if(z.length>0)this.messages=z;if(Z.length>0)this.contextMessages=Z}async loadModelContextOr(z){let Z=await F.loadSessionModelContext(this.id,this.cwd);return Z.length>0?Z:[...z]}mapPermissionModeToMode(z){switch(z){case"yolo":return"yolo";case"autoEdit":return"auto-edit";case"plan":return"plan";case"default":default:return"default"}}createAgent(){if(!this.runtime)throw Error("Session runtime is unavailable");return Hz.createWithRuntime(this.runtime,{sessionId:this.id,...this.options.taskWorktree?{toolBlacklist:["EnterWorktree","ExitWorktree"]}:{}})}async initialize(){if(G.debug(`[AcpSession ${this.id}] Initializing...`),await F.setSessionPermissionMode(this.id,this.cwd,this.mapModeToPermissionMode()??"default"),N.initializeSession(this.connection,this.id,this.clientCapabilities,this.cwd,async(W)=>{await this.sendUpdateAndWait(W)}),G.debug(`[AcpSession ${this.id}] ACP service context initialized`),await zz.resolvePendingWithHandler(this.cwd,this.id,{requestConfirmation:(W)=>this.requestPermission(W)}))await this.refreshPersistedMessages();else if((this.options.initialMessages?.length??0)>0)this.contextMessages=await this.loadModelContextOr(this.options.initialMessages??[]);let Z=this.options.mcpServers?fz(this.options.mcpServers):void 0,J=N.getInstance().getTerminalService(this.id);if(this.runtime=await Qz.create({sessionId:this.id,workspaceRoot:this.cwd,permissionMode:this.mapModeToPermissionMode(),...Z?{mcpServers:Z}:{},...this.options.taskWorktree?{taskWorktree:this.options.taskWorktree}:{},...this.options.taskIsolation?{taskIsolation:this.options.taskIsolation}:{},userShellExecutor:{execute:async(W,Q)=>{let j=await J.execute(W,{cwd:Q.cwd,env:Q.env,timeout:Q.timeoutMs,signal:Q.signal,allowLocalFallback:!1,onOutput:(X)=>Q.onOutput?.("stdout",X)});return{exitCode:j.exitCode,stdout:j.stdout,stderr:j.stderr,...j.error?{error:j.error}:{},timedOut:j.failureKind==="timeout",aborted:j.failureKind==="aborted"}}},...(this.options.initialMessages?.length??0)>0?{sessionStart:{isResume:!0,resumeSessionId:this.id}}:{}}),await b.recoverInterrupted(this.cwd,this.id,this.runtime))await this.refreshPersistedMessages();this.agent=await this.createAgent(),await Fz(this.cwd),G.debug(`[AcpSession ${this.id}] Agent created successfully`),this.taskStatusUnsubscribe?.(),this.taskStatusUnsubscribe=t.subscribe((W)=>{if(W.sessionId!==this.id||W.projectPath!==this.cwd)return;if(W.type==="subagent.completion.queued"){this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:new Date().toISOString(),_meta:{"blade/backgroundSubagentCompletion":W.properties}}),this.schedulePendingResume();return}if(W.type==="task.delivery"){if(!W.properties.taskDelivery||typeof W.properties.taskDelivery!=="object")return;this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:typeof W.properties.updatedAt==="string"?W.properties.updatedAt:new Date().toISOString(),_meta:{"blade/taskDelivery":W.properties.taskDelivery,...W.properties.taskWorktreeRemoved===!0?{"blade/taskWorktreeRemoved":!0}:{}}});return}if(W.type.startsWith("team.")){let{teamName:Q,messageId:j,content:X}=W.properties,D=W.properties.metadata;if(W.type==="team.message.received"&&typeof Q==="string"&&typeof j==="string"&&typeof X==="string"&&$z(D,{messageId:j,teamName:Q}))(async()=>{let L=await this.runtime?.enqueueSteering(X,{allowBeforeTurn:!0,messageId:j,origin:"team_message",metadata:D});if(!L?.accepted)return;if(await new Zz(Q,p()).markDelivered([j]),L.delivery==="next_turn")this.schedulePendingResume()})().catch((L)=>{G.warn(`[AcpSession ${this.id}] Failed to deliver teammate message`,L)});this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:new Date().toISOString(),_meta:{"blade/teamEvent":{type:W.type,...W.properties}}});return}if(W.type!=="task.status")return;this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:typeof W.properties.updatedAt==="string"?W.properties.updatedAt:new Date().toISOString(),_meta:{"blade/taskStatus":W.properties.taskStatus,...typeof W.properties.taskStatusReason==="string"?{"blade/taskStatusReason":W.properties.taskStatusReason}:{},...W.properties.taskFailure&&typeof W.properties.taskFailure==="object"?{"blade/taskFailure":W.properties.taskFailure}:{},...typeof W.properties.taskStartedAt==="string"?{"blade/taskStartedAt":W.properties.taskStartedAt}:{},...typeof W.properties.taskCompletedAt==="string"?{"blade/taskCompletedAt":W.properties.taskCompletedAt}:{},...W.properties.taskDiffStat&&typeof W.properties.taskDiffStat==="object"?{"blade/taskDiffStat":W.properties.taskDiffStat}:{},...typeof W.properties.taskQueuePosition==="number"?{"blade/taskQueuePosition":W.properties.taskQueuePosition}:{},...typeof W.properties.taskQueueDepth==="number"?{"blade/taskQueueDepth":W.properties.taskQueueDepth}:{},...typeof W.properties.taskConcurrencyLimit==="number"?{"blade/taskConcurrencyLimit":W.properties.taskConcurrencyLimit}:{},...typeof W.properties.taskInFlight==="number"?{"blade/taskInFlight":W.properties.taskInFlight}:{}}})});let H=await this.runtime.getGoal();if(this.runtime.getPendingSteeringCount()>0||H?.status==="active"||H?.status==="verifying")if(this.options.initialMessages===void 0)this.schedulePendingResume();else this.pendingResumeRequested=!0}async replayHistory(){for(let Z of this.messages){if(!this.canSendUpdates())return;if(!o(Z))continue;let J=Z.role==="user"?"user_message_chunk":Z.role==="assistant"?"agent_message_chunk":void 0;if(!J)continue;for(let Y of uz(Z)){if(!this.canSendUpdates())return;if(!await this.sendUpdateAndWait({sessionUpdate:J,content:Y}))return}}let z=await this.runtime?.getGoal();if(z&&!await this.sendUpdateAndWait(this.goalSessionUpdate(z)))return;if(this.pendingResumeRequested)this.schedulePendingResume()}sendAvailableCommandsDelayed(){if(this.destroyed||this.connection.signal.aborted)return;if(this.availableCommandsTimer!==null)clearTimeout(this.availableCommandsTimer);G.debug(`[AcpSession ${this.id}] Scheduling available commands update (500ms delay)`),this.availableCommandsTimer=setTimeout(()=>{if(this.availableCommandsTimer=null,this.destroyed||this.connection.signal.aborted)return;this.sendAvailableCommands()},500)}async handleSlashCommand(z,Z){try{G.debug(`[AcpSession ${this.id}] Executing slash command: ${z}`);let J={cwd:this.cwd,surface:"acp",workspaceRoot:this.cwd,sessionId:this.id,messages:[...this.contextMessages],rewind:{listCheckpoints:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.listRewindCheckpoints()},execute:async(Q)=>{if(!this.runtime)throw Error("Session runtime is unavailable");let j=await this.runtime.rewindSession(Q);return this.messages=[...j.messages],this.contextMessages=await this.loadModelContextOr(j.messages),await this.agent?.destroy(),this.agent=await this.createAgent(),j}},reasoning:{get:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getReasoningConfiguration()},set:async(Q)=>{if(await this.setReasoningEffort(Q),!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getReasoningConfiguration()}},serviceTier:{get:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getServiceTierConfiguration()},set:async(Q)=>{if(await this.setServiceTier(Q),!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getServiceTierConfiguration()}},responseVerbosity:{get:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getResponseVerbosityConfiguration()},set:async(Q)=>{if(await this.setResponseVerbosity(Q),!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getResponseVerbosityConfiguration()}},communicationStyle:{get:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getCommunicationStyleConfiguration()},set:async(Q)=>{if(await this.setCommunicationStyle(Q),!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getCommunicationStyleConfiguration()}},subagents:{list:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.listSubagents()},resume:async(Q,j)=>{if(!this.runtime)throw Error("Session runtime is unavailable");let X=!1,D,L=(B)=>{this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:B.id,status:B.status==="completed"?"completed":"failed",content:[{type:"content",content:{type:"text",text:B.result?.message||B.result?.error||`Subagent ${B.status}`}}]})},U=this.runtime.resumeSubagent({agentId:Q,prompt:j,onCompleted:(B)=>{if(X)L(B);else D=B}});if(this.sendUpdate({sessionUpdate:"tool_call",toolCallId:U.session.id,status:"in_progress",title:`Resuming ${U.session.subagentType} subagent`,content:[{type:"content",content:{type:"text",text:`Resumed from ${U.source.id} at depth ${U.session.resumeDepth}`}}],kind:this.mapToolKind("readonly")}),X=!0,D)L(D);return U}},mcp:{getCatalog:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpContentCatalog()},refresh:async(Q)=>{if(!this.runtime)throw Error("Session runtime is unavailable");await this.runtime.refreshMcpContentCatalogs(Q)},getPrompt:async(Q,j,X)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpPrompt(Q,j,X)},complete:async(Q,j,X)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.completeMcpArgument(Q,j,X)},listTasks:async(Q)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.listMcpTasks(Q)},getTask:async(Q)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpTask(Q)},cancelTask:async(Q,j)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.cancelMcpTask(Q,j)},getLogs:async(Q,j)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpLogs(Q,j)},setLoggingLevel:async(Q,j)=>{if(!this.runtime)throw Error("Session runtime is unavailable");await this.runtime.setMcpLoggingLevel(Q,j)},getInstructions:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpInstructions()}},sideConversation:{ask:async(Q,j)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.askSideQuestion(Q,{signal:j})}},codeReview:{run:async(Q,j)=>{if(!this.runtime)throw Error("Session runtime is unavailable");let X=await b.start({sessionId:this.id,projectPath:this.cwd,runtime:this.runtime,request:Q,signal:j,onEvent:(U)=>{if(U.kind==="tool_start")this.sendUpdate({sessionUpdate:"tool_call",toolCallId:U.toolCall.id,status:"in_progress",title:`Review: ${U.toolCall.function.name}`,content:[],kind:this.mapToolKind(U.toolKind)});else if(U.kind==="tool_result")this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:U.toolCall.id,status:U.result.success?"completed":"failed",content:[]})}}),D=await X.completion,L=(await b.list(this.cwd,this.id)).find((U)=>U.start.reviewId===X.reviewId);if(!L)throw Error(`Review not found: ${X.reviewId}`);return await this.refreshPersistedMessages(),{reviewId:X.reviewId,status:D.status,findings:D.findings.length,content:v(L.start,D)}}},signal:Z,acp:{sendMessage:(Q)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:Q}})},sendToolStart:(Q,j,X)=>{let D=`tool_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,L=this.mapToolKind(X);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:D,status:"in_progress",title:`${Q}`,content:[{type:"content",content:{type:"text",text:JSON.stringify(j,null,2)}}],kind:L})},sendToolResult:(Q,j)=>{if(j.summary)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:j.summary}})}}},Y=await Uz(z,J),H=Y.data?.action;if(H==="start_goal"||H==="resume_goal")this.schedulePendingResume();if(H==="rewind_session"&&Array.isArray(Y.data?.messages))this.messages=[...Y.data.messages],this.contextMessages=await this.loadModelContextOr(Y.data.messages);if((Y.message==="compact_completed"||Y.message==="compact_fallback")&&Y.data?.compactedMessages){this.contextMessages=[...Y.data.compactedMessages];let Q=await F.loadSession(this.id,this.cwd);if(Q.length>0)this.messages=Q}let W=Y.content||Y.message;if(W)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:W}});if(Y.error)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`[FAIL] ${Y.error}`}});return await this.flushUpdates(),{stopReason:Y.success?"end_turn":"cancelled"}}catch(J){if(Z.aborted||J instanceof Error&&J.name==="AbortError")return{stopReason:"cancelled"};return G.error(`[AcpSession ${this.id}] Slash command error:`,J),this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`[FAIL] 命令执行失败: ${J instanceof Error?J.message:"未知错误"}`}}),{stopReason:"cancelled"}}}async handleSideConversationCommand(z){if(this.pendingSideConversation)throw Error("A side conversation is already running");let Z=new AbortController,J,Y=new Promise((H)=>{J=H});this.pendingSideConversation=Z,this.pendingSideConversationCompletion=Y;try{return await this.handleSlashCommand(z,Z.signal)}catch(H){if(Z.signal.aborted||H instanceof Error&&H.name==="AbortError")return{stopReason:"cancelled"};throw H}finally{if(J(),this.pendingSideConversationCompletion===Y)this.pendingSideConversationCompletion=null;if(this.pendingSideConversation===Z)this.pendingSideConversation=null}}async sendAvailableCommands(){try{let z=Vz(this.cwd,this.runtime?.getAgentResources()),Z=["model","permissions","theme","config","exit","ide"],Y=z.filter((H)=>!Z.includes(H.name)&&(H.name!=="team"||this.runtime?.getConfig().agentTeamsEnabled===!0)).map((H)=>{let W;if(H.usage){let Q=H.usage.replace(/^\/\w+\s*/,"").trim();if(Q)W=Q}if(H.aliases?.length){let Q=`Aliases: ${H.aliases.join(", ")}`;W=W?`${W} | ${Q}`:Q}return{name:H.name,description:H.description,input:W?{hint:W}:void 0}});G.info(`[AcpSession ${this.id}] Sending available commands: ${JSON.stringify(Y.map((H)=>H.name))}`),this.sendUpdate({sessionUpdate:"available_commands_update",availableCommands:Y}),G.info(`[AcpSession ${this.id}] Sent ${Y.length} available commands`)}catch(z){G.error(`[AcpSession ${this.id}] Failed to send available commands:`,z)}}async prompt(z,Z={}){if(N.setCurrentSession(this.id),!this.agent||!this.runtime)throw Error("Session not initialized");let J=this.resolvePrompt(z.prompt),Y=J.content,H=J.displayText,W=z._meta?.outputSchema??(Z.pendingInputOnly?this.runtime.getPendingSteeringMessages().find((B)=>B.outputSchema)?.outputSchema:void 0),Q;if(W!==void 0)Q=s(W).schema;if(H.trimStart().startsWith("!")){if(Q)throw Error("Output schemas cannot be combined with user shell commands");return this.handleUserShellCommand(H)}let j=Jz(H);if(j){if(Q)throw Error("Output schemas cannot be combined with slash commands");if(Array.isArray(Y)&&Y.some((B)=>B.type==="image_url"))throw Error("Side conversations do not accept image attachments");return this.handleSideConversationCommand(j.question?`/btw ${j.question}`:"/btw")}if(this.pendingPrompt){if(Q)throw Error("Wait for the active turn to finish before setting an output schema");if(/^\/goal(?:\s|$)/i.test(H.trim()))return this.handleSlashCommand(H,this.pendingPrompt.signal);let B=await this.runtime.enqueueSteering(Y,{allowBeforeTurn:!0});if(!B.accepted)throw Error(B.reason==="queue_full"?"Active turn steering queue is full":"Active turn is no longer steerable");if(G.debug(`[AcpSession ${this.id}] Queued steering for active turn (${B.queued})`),B.delivery==="next_turn")this.schedulePendingResume();return{stopReason:"end_turn"}}let X=new AbortController,D=!1,L,U=new Promise((B)=>{L=B});this.pendingPrompt=X,this.pendingPromptCompletion=U;try{if(G.debug(`[AcpSession ${this.id}] Received prompt: ${H.slice(0,100)}...`),Gz(H)){if(Q)throw Error("Output schemas cannot be combined with slash commands");return await this.handleSlashCommand(H,X.signal)}let B={sessionId:this.id,userId:"acp-user",workspaceRoot:this.cwd,messages:[...this.contextMessages],signal:X.signal,permissionMode:this.mapModeToPermissionMode(),onPermissionModeChange:async($)=>{this.mode=this.mapPermissionModeToMode($),this.sendUpdate({sessionUpdate:"current_mode_update",currentModeId:this.mode})},...this.options.taskWorktree?{worktreeActive:!0}:{},confirmationHandler:{requestConfirmation:async($)=>{return this.requestPermission($)}}},A=await e(this.agent.chatStream(Y,B,{pendingInputOnly:Z.pendingInputOnly,goalContinuationOnly:Z.goalContinuationOnly,outputSchema:Q}),async($)=>{switch($.kind){case"content_delta":if(Q)break;this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:$.delta}});break;case"thinking_delta":this.sendUpdate({sessionUpdate:"agent_thought_chunk",content:{type:"text",text:$.delta}});break;case"tool_start":{let V=$.toolCall,O=V.function.name;if(O===x)break;let R=this.mapToolKind($.toolKind),w=`Executing ${O}`;if(O==="Task"&&"function"in V)try{let q=JSON.parse(V.function.arguments),K=q.resume_from??q.resume;if(typeof K==="string")w=`Resuming ${String(q.subagent_type||"subagent")} from ${K}`}catch{}this.sendUpdate({sessionUpdate:"tool_call",toolCallId:V.id,status:"in_progress",title:w,content:[],kind:R});break}case"tool_progress":{let V=$.toolCall;if(V.function.name===x)break;this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:V.id,status:"in_progress",content:[{type:"content",content:{type:"text",text:$.update.message}}]});break}case"tool_result":{let V=$.toolCall;if(V.function.name===x)break;let O=$.result,R=[],w=O.metadata;if(w?.kind==="patch"&&Array.isArray(w.changes))for(let K of w.changes){if(!K||typeof K!=="object"||!("path"in K)||typeof K.path!=="string")continue;R.push({type:"diff",path:K.path,oldText:"oldContent"in K&&typeof K.oldContent==="string"?K.oldContent:null,newText:"newContent"in K&&typeof K.newContent==="string"?K.newContent:null})}else if(w?.kind==="edit"&&typeof w.file_path==="string"&&typeof w.oldContent==="string"&&(typeof w.newContent==="string"||w.newContent===void 0))R.push({type:"diff",path:w.file_path,oldText:w.oldContent,newText:w.newContent??null});else{let K=V.function.name,Mz=Yz(a(Wz(K,O),r));R.push({type:"content",content:{type:"text",text:Mz}})}if(V.function.name==="Task"&&(w?.verificationVerdict==="pass"||w?.verificationVerdict==="fail"||w?.verificationVerdict==="partial"))R.unshift({type:"content",content:{type:"text",text:`Verification result: ${w.verificationVerdict.toUpperCase()}`}});let q=O.success?"completed":"failed";this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:V.id,status:q,content:R});break}case"structured_output":this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:JSON.stringify($.output)}});break;case"mcp_catalog_changed":this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`MCP catalog r${$.revision} (${$.serverName}): +${$.added.length} -${$.removed.length} ~${$.updated.length}
1
+ import{s as hz,t as Sz}from"./chunk-t5ysd5z8.js";import{u as b}from"./chunk-aqkexfag.js";import{A as Gz,v as yz,w as Xz,x as Dz,y as Lz,z as Bz}from"./chunk-69rpb78b.js";import{E as N,L as $z,M as Qz,Q as Wz,T as Yz,U as Hz,Y as jz,ma as Fz,na as Uz,oa as Vz,pa as wz}from"./chunk-xy67pj74.js";import{za as Tz}from"./chunk-p9a3d507.js";import{Ba as Zz}from"./chunk-tpxs85cg.js";import{Eb as Jz,jb as e,vb as zz}from"./chunk-xzgqyzmy.js";import{Pb as I}from"./chunk-r8wbvxn7.js";import{Cc as o,Ec as n,Kc as C,Lc as s,Nc as x,Qc as t,Vc as q,Yc as U,jc as l,tc as i,uc as r,zc as a}from"./chunk-2b7zryg3.js";import"./chunk-d2pwwdab.js";import"./chunk-r77pcb0f.js";import{Bd as Mz}from"./chunk-r51ds5qw.js";import"./chunk-skg520wq.js";import{Wd as Nz,Xd as Ez}from"./chunk-q14mgye7.js";import"./chunk-v508x7cg.js";import{ge as f}from"./chunk-g9xjcfrf.js";import{le as v}from"./chunk-b2p9qm6j.js";import"./chunk-0q5bz3nm.js";import{we as xz}from"./chunk-44dzrn0p.js";import"./chunk-73j10ezs.js";import"./chunk-g832dwdm.js";import"./chunk-sr4zv59p.js";import{mf as bz}from"./chunk-ww51801m.js";import"./chunk-7rfhmbqw.js";import"./chunk-4rq0jhf4.js";import"./chunk-272swnyr.js";import{eg as qz,hg as Pz}from"./chunk-t6phsb5h.js";import"./chunk-7m5q8vxf.js";import"./chunk-sk8h4m9m.js";import{Lg as S,Mg as d,Og as M,Pg as k}from"./chunk-hg8d4vhj.js";import{Tg as Oz}from"./chunk-sb84vdcf.js";import"./chunk-hjr9r44k.js";import{th as T}from"./chunk-ffa6hhee.js";import"./chunk-t1633e8m.js";import{Ah as Az,Dh as Rz}from"./chunk-m5f934fh.js";import"./chunk-fs9j9gas.js";import"./chunk-rwvaapta.js";import"./chunk-83caxxbt.js";import{Zh as m}from"./chunk-shr5cg46.js";import"./chunk-6jsmac0q.js";import{Readable as vz,Writable as lz}from"node:stream";import*as y from"@agentclientprotocol/sdk";import _z from"node:path";import{PROTOCOL_VERSION as mz,RequestError as dz}from"@agentclientprotocol/sdk";import{RequestError as Cz}from"@agentclientprotocol/sdk";import{nanoid as h}from"nanoid";var G=T("Agent");function p(z){if(!z)return{};return Object.fromEntries(z.map((Z)=>[Z.name,Z.value]))}function fz(z){if("command"in z)return{type:"stdio",command:z.command,args:z.args,env:p(z.env)};if("url"in z)return{type:z.type,url:z.url,headers:p("headers"in z?z.headers:void 0)};return null}function uz(z){let Z={};for(let J of z){let Y=fz(J);if(Y)Z[J.name]=Y}return Z}function Kz(z){if(typeof z==="string")return z?[{type:"text",text:z}]:[];return z.flatMap((Z)=>{if(Z.type==="text")return Z.text?[{type:"text",text:Z.text}]:[];let J=Z.image_url.url,Y=/^data:([^;,]+);base64,(.+)$/s.exec(J);if(!Y)return[{type:"text",text:"[Image]"}];return[{type:"image",mimeType:Y[1]??"image/png",data:Y[2]??""}]})}function gz(z){let Z=s(z.metadata);return Z?[{type:"text",text:C(Z)}]:Kz(z.content)}function cz(z){return[`Status: ${z.status}`,`Exit code: ${z.exitCode??"null"}`,`Duration: ${(z.durationMs/1000).toFixed(3)} seconds`].join(`
2
+ `)}function pz(z){if(!v(z)||z.reason!=="queue_full"||z.resource!=="pending_count"&&z.resource!=="pending_bytes")return;return{...i("capacity"),resource:z.resource}}class E{id;cwd;connection;clientCapabilities;options;agent=null;runtime=null;pendingPrompt=null;pendingPromptCompletion=null;pendingUserShell=null;pendingUserShellCompletion=null;pendingSideConversation=null;pendingSideConversationCompletion=null;pendingResumeRequested=!1;availableCommandsTimer=null;taskStatusUnsubscribe;destroyed=!1;destroyFinished=!1;destroyPromise;messages;contextMessages;mode;updateEgress;constructor(z,Z,J,Y,H={}){this.id=z;this.cwd=Z;this.connection=J;this.clientCapabilities=Y;this.options=H;this.messages=[...H.initialMessages??[]],this.contextMessages=[...this.messages],this.mode=this.mapPermissionModeToMode(H.permissionMode),this.updateEgress=new Gz({maxPendingItems:Xz,maxPendingBytes:Dz,writeTimeoutMs:Lz,signal:J.signal,sizeOf:(W)=>Buffer.byteLength(JSON.stringify(W)),write:async(W)=>{await J.sessionUpdate(W)},onFailure:(W)=>this.handleUpdateEgressFailure(W)})}async refreshPersistedMessages(){let[z,Z]=await Promise.all([U.loadSession(this.id,this.cwd),U.loadSessionModelContext(this.id,this.cwd)]);if(z.length>0)this.messages=z;if(Z.length>0)this.contextMessages=Z}async loadModelContextOr(z){let Z=await U.loadSessionModelContext(this.id,this.cwd);return Z.length>0?Z:[...z]}mapPermissionModeToMode(z){switch(z){case"yolo":return"yolo";case"autoEdit":return"auto-edit";case"plan":return"plan";case"default":default:return"default"}}createAgent(){if(!this.runtime)throw Error("Session runtime is unavailable");return jz.createWithRuntime(this.runtime,{sessionId:this.id,...this.options.taskWorktree?{toolBlacklist:["EnterWorktree","ExitWorktree"]}:{}})}async initialize(){if(G.debug(`[AcpSession ${this.id}] Initializing...`),await U.setSessionPermissionMode(this.id,this.cwd,this.mapModeToPermissionMode()??"default"),N.initializeSession(this.connection,this.id,this.clientCapabilities,this.cwd,async(W)=>{await this.sendUpdateAndWait(W)}),G.debug(`[AcpSession ${this.id}] ACP service context initialized`),await Jz.resolvePendingWithHandler(this.cwd,this.id,{requestConfirmation:(W)=>this.requestPermission(W)}))await this.refreshPersistedMessages();else if((this.options.initialMessages?.length??0)>0)this.contextMessages=await this.loadModelContextOr(this.options.initialMessages??[]);let Z=this.options.mcpServers?uz(this.options.mcpServers):void 0,J=N.getInstance().getTerminalService(this.id);if(this.runtime=await Wz.create({sessionId:this.id,workspaceRoot:this.cwd,permissionMode:this.mapModeToPermissionMode(),...Z?{mcpServers:Z}:{},...this.options.taskWorktree?{taskWorktree:this.options.taskWorktree}:{},...this.options.taskIsolation?{taskIsolation:this.options.taskIsolation}:{},userShellExecutor:{execute:async(W,Q)=>{let j=await J.execute(W,{cwd:Q.cwd,env:Q.env,timeout:Q.timeoutMs,signal:Q.signal,allowLocalFallback:!1,onOutput:(D)=>Q.onOutput?.("stdout",D)});return{exitCode:j.exitCode,stdout:j.stdout,stderr:j.stderr,...j.error?{error:j.error}:{},timedOut:j.failureKind==="timeout",aborted:j.failureKind==="aborted"}}},...(this.options.initialMessages?.length??0)>0?{sessionStart:{isResume:!0,resumeSessionId:this.id}}:{}}),await b.recoverInterrupted(this.cwd,this.id,this.runtime))await this.refreshPersistedMessages();this.agent=await this.createAgent(),await Uz(this.cwd),G.debug(`[AcpSession ${this.id}] Agent created successfully`),this.taskStatusUnsubscribe?.(),this.taskStatusUnsubscribe=e.subscribe((W)=>{if(W.sessionId!==this.id||W.projectPath!==this.cwd)return;if(W.type==="subagent.completion.queued"){this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:new Date().toISOString(),_meta:{"blade/backgroundSubagentCompletion":W.properties}}),this.schedulePendingResume();return}if(W.type==="task.delivery"){if(!W.properties.taskDelivery||typeof W.properties.taskDelivery!=="object")return;this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:typeof W.properties.updatedAt==="string"?W.properties.updatedAt:new Date().toISOString(),_meta:{"blade/taskDelivery":W.properties.taskDelivery,...W.properties.taskWorktreeRemoved===!0?{"blade/taskWorktreeRemoved":!0}:{}}});return}if(W.type.startsWith("team.")){let{teamName:Q,messageId:j,content:D}=W.properties,X=W.properties.metadata;if(W.type==="team.message.received"&&typeof Q==="string"&&typeof j==="string"&&typeof D==="string"&&Qz(X,{messageId:j,teamName:Q}))(async()=>{let L=await this.runtime?.enqueueSteering(D,{allowBeforeTurn:!0,messageId:j,origin:"team_message",metadata:X});if(!L?.accepted)return;if(await new $z(Q,m()).markDelivered([j]),L.delivery==="next_turn")this.schedulePendingResume()})().catch((L)=>{G.warn(`[AcpSession ${this.id}] Failed to deliver teammate message`,L)});this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:new Date().toISOString(),_meta:{"blade/teamEvent":{type:W.type,...W.properties}}});return}if(W.type!=="task.status")return;this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:typeof W.properties.updatedAt==="string"?W.properties.updatedAt:new Date().toISOString(),_meta:{"blade/taskStatus":W.properties.taskStatus,...typeof W.properties.taskStatusReason==="string"?{"blade/taskStatusReason":W.properties.taskStatusReason}:{},...W.properties.taskFailure&&typeof W.properties.taskFailure==="object"?{"blade/taskFailure":W.properties.taskFailure}:{},...typeof W.properties.taskStartedAt==="string"?{"blade/taskStartedAt":W.properties.taskStartedAt}:{},...typeof W.properties.taskCompletedAt==="string"?{"blade/taskCompletedAt":W.properties.taskCompletedAt}:{},...W.properties.taskDiffStat&&typeof W.properties.taskDiffStat==="object"?{"blade/taskDiffStat":W.properties.taskDiffStat}:{},...typeof W.properties.taskQueuePosition==="number"?{"blade/taskQueuePosition":W.properties.taskQueuePosition}:{},...typeof W.properties.taskQueueDepth==="number"?{"blade/taskQueueDepth":W.properties.taskQueueDepth}:{},...typeof W.properties.taskConcurrencyLimit==="number"?{"blade/taskConcurrencyLimit":W.properties.taskConcurrencyLimit}:{},...typeof W.properties.taskInFlight==="number"?{"blade/taskInFlight":W.properties.taskInFlight}:{}}})});let H=await this.runtime.getGoal();if(this.runtime.getPendingSteeringCount()>0||H?.status==="active"||H?.status==="verifying")if(this.options.initialMessages===void 0)this.schedulePendingResume();else this.pendingResumeRequested=!0}async replayHistory(){for(let Z of this.messages){if(!this.canSendUpdates())return;if(!n(Z))continue;let J=Z.role==="user"?"user_message_chunk":Z.role==="assistant"?"agent_message_chunk":void 0;if(!J)continue;for(let Y of gz(Z)){if(!this.canSendUpdates())return;if(!await this.sendUpdateAndWait({sessionUpdate:J,content:Y}))return}}let z=await this.runtime?.getGoal();if(z&&!await this.sendUpdateAndWait(this.goalSessionUpdate(z)))return;if(this.pendingResumeRequested)this.schedulePendingResume()}sendAvailableCommandsDelayed(){if(this.destroyed||this.connection.signal.aborted)return;if(this.availableCommandsTimer!==null)clearTimeout(this.availableCommandsTimer);G.debug(`[AcpSession ${this.id}] Scheduling available commands update (500ms delay)`),this.availableCommandsTimer=setTimeout(()=>{if(this.availableCommandsTimer=null,this.destroyed||this.connection.signal.aborted)return;this.sendAvailableCommands()},500)}async handleSlashCommand(z,Z){try{G.debug(`[AcpSession ${this.id}] Executing slash command: ${z}`);let J={cwd:this.cwd,surface:"acp",workspaceRoot:this.cwd,sessionId:this.id,messages:[...this.contextMessages],rewind:{listCheckpoints:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.listRewindCheckpoints()},execute:async(Q)=>{if(!this.runtime)throw Error("Session runtime is unavailable");let j=await this.runtime.rewindSession(Q);return this.messages=[...j.messages],this.contextMessages=await this.loadModelContextOr(j.messages),await this.agent?.destroy(),this.agent=await this.createAgent(),j}},reasoning:{get:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getReasoningConfiguration()},set:async(Q)=>{if(await this.setReasoningEffort(Q),!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getReasoningConfiguration()}},serviceTier:{get:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getServiceTierConfiguration()},set:async(Q)=>{if(await this.setServiceTier(Q),!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getServiceTierConfiguration()}},responseVerbosity:{get:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getResponseVerbosityConfiguration()},set:async(Q)=>{if(await this.setResponseVerbosity(Q),!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getResponseVerbosityConfiguration()}},communicationStyle:{get:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getCommunicationStyleConfiguration()},set:async(Q)=>{if(await this.setCommunicationStyle(Q),!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getCommunicationStyleConfiguration()}},subagents:{list:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.listSubagents()},resume:async(Q,j)=>{if(!this.runtime)throw Error("Session runtime is unavailable");let D=!1,X,L=(B)=>{this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:B.id,status:B.status==="completed"?"completed":"failed",content:[{type:"content",content:{type:"text",text:B.result?.message||B.result?.error||`Subagent ${B.status}`}}]})},F=this.runtime.resumeSubagent({agentId:Q,prompt:j,onCompleted:(B)=>{if(D)L(B);else X=B}});if(this.sendUpdate({sessionUpdate:"tool_call",toolCallId:F.session.id,status:"in_progress",title:`Resuming ${F.session.subagentType} subagent`,content:[{type:"content",content:{type:"text",text:`Resumed from ${F.source.id} at depth ${F.session.resumeDepth}`}}],kind:this.mapToolKind("readonly")}),D=!0,X)L(X);return F}},mcp:{getCatalog:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpContentCatalog()},refresh:async(Q)=>{if(!this.runtime)throw Error("Session runtime is unavailable");await this.runtime.refreshMcpContentCatalogs(Q)},getPrompt:async(Q,j,D)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpPrompt(Q,j,D)},complete:async(Q,j,D)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.completeMcpArgument(Q,j,D)},listTasks:async(Q)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.listMcpTasks(Q)},getTask:async(Q)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpTask(Q)},cancelTask:async(Q,j)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.cancelMcpTask(Q,j)},getLogs:async(Q,j)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpLogs(Q,j)},setLoggingLevel:async(Q,j)=>{if(!this.runtime)throw Error("Session runtime is unavailable");await this.runtime.setMcpLoggingLevel(Q,j)},getInstructions:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpInstructions()}},sideConversation:{ask:async(Q,j)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.askSideQuestion(Q,{signal:j})}},codeReview:{run:async(Q,j)=>{if(!this.runtime)throw Error("Session runtime is unavailable");let D=await b.start({sessionId:this.id,projectPath:this.cwd,runtime:this.runtime,request:Q,signal:j,onEvent:(F)=>{if(F.kind==="tool_start")this.sendUpdate({sessionUpdate:"tool_call",toolCallId:F.toolCall.id,status:"in_progress",title:`Review: ${F.toolCall.function.name}`,content:[],kind:this.mapToolKind(F.toolKind)});else if(F.kind==="tool_result")this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:F.toolCall.id,status:F.result.success?"completed":"failed",content:[]})}}),X=await D.completion,L=(await b.list(this.cwd,this.id)).find((F)=>F.start.reviewId===D.reviewId);if(!L)throw Error(`Review not found: ${D.reviewId}`);return await this.refreshPersistedMessages(),{reviewId:D.reviewId,status:X.status,findings:X.findings.length,content:l(L.start,X)}}},signal:Z,acp:{sendMessage:(Q)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:Q}})},sendToolStart:(Q,j,D)=>{let X=`tool_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,L=this.mapToolKind(D);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:X,status:"in_progress",title:`${Q}`,content:[{type:"content",content:{type:"text",text:JSON.stringify(j,null,2)}}],kind:L})},sendToolResult:(Q,j)=>{if(j.summary)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:j.summary}})}}},Y=await Vz(z,J),H=Y.data?.action;if(H==="start_goal"||H==="resume_goal")this.schedulePendingResume();if(H==="rewind_session"&&Array.isArray(Y.data?.messages))this.messages=[...Y.data.messages],this.contextMessages=await this.loadModelContextOr(Y.data.messages);if((Y.message==="compact_completed"||Y.message==="compact_fallback")&&Y.data?.compactedMessages){this.contextMessages=[...Y.data.compactedMessages];let Q=await U.loadSession(this.id,this.cwd);if(Q.length>0)this.messages=Q}let W=Y.content||Y.message;if(W)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:W}});if(Y.error)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`[FAIL] ${Y.error}`}});return await this.flushUpdates(),{stopReason:Y.success?"end_turn":"cancelled"}}catch(J){if(Z.aborted||J instanceof Error&&J.name==="AbortError")return{stopReason:"cancelled"};return G.error(`[AcpSession ${this.id}] Slash command error:`,J),this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`[FAIL] 命令执行失败: ${J instanceof Error?J.message:"未知错误"}`}}),{stopReason:"cancelled"}}}async handleSideConversationCommand(z){if(this.pendingSideConversation)throw Error("A side conversation is already running");let Z=new AbortController,J,Y=new Promise((H)=>{J=H});this.pendingSideConversation=Z,this.pendingSideConversationCompletion=Y;try{return await this.handleSlashCommand(z,Z.signal)}catch(H){if(Z.signal.aborted||H instanceof Error&&H.name==="AbortError")return{stopReason:"cancelled"};throw H}finally{if(J(),this.pendingSideConversationCompletion===Y)this.pendingSideConversationCompletion=null;if(this.pendingSideConversation===Z)this.pendingSideConversation=null}}async sendAvailableCommands(){try{let z=wz(this.cwd,this.runtime?.getAgentResources()),Z=["model","permissions","theme","config","exit","ide"],Y=z.filter((H)=>!Z.includes(H.name)&&(H.name!=="team"||this.runtime?.getConfig().agentTeamsEnabled===!0)).map((H)=>{let W;if(H.usage){let Q=H.usage.replace(/^\/\w+\s*/,"").trim();if(Q)W=Q}if(H.aliases?.length){let Q=`Aliases: ${H.aliases.join(", ")}`;W=W?`${W} | ${Q}`:Q}return{name:H.name,description:H.description,input:W?{hint:W}:void 0}});G.info(`[AcpSession ${this.id}] Sending available commands: ${JSON.stringify(Y.map((H)=>H.name))}`),this.sendUpdate({sessionUpdate:"available_commands_update",availableCommands:Y}),G.info(`[AcpSession ${this.id}] Sent ${Y.length} available commands`)}catch(z){G.error(`[AcpSession ${this.id}] Failed to send available commands:`,z)}}async prompt(z,Z={}){if(N.setCurrentSession(this.id),!this.agent||!this.runtime)throw Error("Session not initialized");let J=this.resolvePrompt(z.prompt),Y=J.content,H=J.displayText,W=z._meta?.outputSchema??(Z.pendingInputOnly?this.runtime.getPendingSteeringMessages().find((B)=>B.outputSchema)?.outputSchema:void 0),Q;if(W!==void 0)Q=t(W).schema;if(H.trimStart().startsWith("!")){if(Q)throw Error("Output schemas cannot be combined with user shell commands");return this.handleUserShellCommand(H)}let j=Zz(H);if(j){if(Q)throw Error("Output schemas cannot be combined with slash commands");if(Array.isArray(Y)&&Y.some((B)=>B.type==="image_url"))throw Error("Side conversations do not accept image attachments");return this.handleSideConversationCommand(j.question?`/btw ${j.question}`:"/btw")}if(this.pendingPrompt){if(Q)throw Error("Wait for the active turn to finish before setting an output schema");if(/^\/goal(?:\s|$)/i.test(H.trim()))return this.handleSlashCommand(H,this.pendingPrompt.signal);let B=await this.runtime.enqueueSteering(Y,{allowBeforeTurn:!0});if(!B.accepted)throw Error(B.reason==="queue_full"?"Active turn steering queue is full":"Active turn is no longer steerable");if(G.debug(`[AcpSession ${this.id}] Queued steering for active turn (${B.queued})`),B.delivery==="next_turn")this.schedulePendingResume();return{stopReason:"end_turn"}}let D=new AbortController,X=!1,L,F=new Promise((B)=>{L=B});this.pendingPrompt=D,this.pendingPromptCompletion=F;try{if(G.debug(`[AcpSession ${this.id}] Received prompt: ${H.slice(0,100)}...`),Fz(H)){if(Q)throw Error("Output schemas cannot be combined with slash commands");return await this.handleSlashCommand(H,D.signal)}let B={sessionId:this.id,userId:"acp-user",workspaceRoot:this.cwd,messages:[...this.contextMessages],signal:D.signal,permissionMode:this.mapModeToPermissionMode(),onPermissionModeChange:async($)=>{this.mode=this.mapPermissionModeToMode($),this.sendUpdate({sessionUpdate:"current_mode_update",currentModeId:this.mode})},...this.options.taskWorktree?{worktreeActive:!0}:{},confirmationHandler:{requestConfirmation:async($)=>{return this.requestPermission($)}}},A=await zz(this.agent.chatStream(Y,B,{pendingInputOnly:Z.pendingInputOnly,goalContinuationOnly:Z.goalContinuationOnly,outputSchema:Q}),async($)=>{switch($.kind){case"content_delta":if(Q)break;this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:$.delta}});break;case"thinking_delta":this.sendUpdate({sessionUpdate:"agent_thought_chunk",content:{type:"text",text:$.delta}});break;case"tool_start":{let V=$.toolCall,O=V.function.name;if(O===x)break;let R=this.mapToolKind($.toolKind),w=`Executing ${O}`;if(O==="Task"&&"function"in V)try{let P=JSON.parse(V.function.arguments),K=P.resume_from??P.resume;if(typeof K==="string")w=`Resuming ${String(P.subagent_type||"subagent")} from ${K}`}catch{}this.sendUpdate({sessionUpdate:"tool_call",toolCallId:V.id,status:"in_progress",title:w,content:[],kind:R});break}case"tool_progress":{let V=$.toolCall;if(V.function.name===x)break;this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:V.id,status:"in_progress",content:[{type:"content",content:{type:"text",text:$.update.message}}]});break}case"tool_result":{let V=$.toolCall;if(V.function.name===x)break;let O=$.result,R=[],w=O.metadata;if(w?.kind==="patch"&&Array.isArray(w.changes))for(let K of w.changes){if(!K||typeof K!=="object"||!("path"in K)||typeof K.path!=="string")continue;R.push({type:"diff",path:K.path,oldText:"oldContent"in K&&typeof K.oldContent==="string"?K.oldContent:null,newText:"newContent"in K&&typeof K.newContent==="string"?K.newContent:null})}else if(w?.kind==="edit"&&typeof w.file_path==="string"&&typeof w.oldContent==="string"&&(typeof w.newContent==="string"||w.newContent===void 0))R.push({type:"diff",path:w.file_path,oldText:w.oldContent,newText:w.newContent??null});else{let K=V.function.name,kz=Hz(o(Yz(K,O),a));R.push({type:"content",content:{type:"text",text:kz}})}if(V.function.name==="Task"&&(w?.verificationVerdict==="pass"||w?.verificationVerdict==="fail"||w?.verificationVerdict==="partial"))R.unshift({type:"content",content:{type:"text",text:`Verification result: ${w.verificationVerdict.toUpperCase()}`}});let P=O.success?"completed":"failed";this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:V.id,status:P,content:R});break}case"structured_output":this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:JSON.stringify($.output)}});break;case"mcp_catalog_changed":this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`MCP catalog r${$.revision} (${$.serverName}): +${$.added.length} -${$.removed.length} ~${$.updated.length}
3
3
  `}});break;case"mcp_content_changed":this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`MCP ${$.contentKind} r${$.revision} (${$.serverName}): +${$.added.length} -${$.removed.length} ~${$.updated.length}
4
4
  `}});break;case"mcp_resource_updated":this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`MCP resource updated r${$.revision} (${$.serverName}): ${$.uri}
5
5
  `}});break;case"mcp_connection_changed":this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`MCP connection r${$.revision} (${$.serverName}): ${$.phase} ${$.attempt}/${$.maxAttempts}
@@ -7,16 +7,17 @@ import{s as yz,t as hz}from"./chunk-sghq0p21.js";import{u as b}from"./chunk-bb1d
7
7
  `}});break;case"mcp_instructions_changed":this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`MCP instructions r${$.revision} (${$.serverName}): ${$.action}${$.detailsOmitted?" details-omitted":""}
8
8
  `}});break;case"mcp_task_changed":this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`MCP task r${$.revision} ${$.taskId} (${$.serverName}/${$.toolName}): ${$.status}${$.hasResult?" result-available":""}
9
9
  `}});break;case"project_rules_loaded":this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`Project rules loaded: ${$.files.length}${$.blockedWrite?" (write retry required)":""}
10
- `}});break;case"provider_admission":D=$.phase!=="admitted",this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:new Date().toISOString(),_meta:{"blade/providerAdmission":$.phase!=="admitted"?{phase:$.phase,requestClass:$.requestClass,resource:$.resource,scope:$.scope,...$.reason!==void 0?{reason:$.reason}:{},queuePosition:$.queuePosition,queueDepth:$.queueDepth,inFlight:$.inFlight,limit:$.limit,waitMs:$.waitMs,maxWaitMs:$.maxWaitMs,...$.recoveryRemainingMs!==void 0?{recoveryRemainingMs:$.recoveryRemainingMs}:{}}:null}});break;case"provider_circuit":this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:new Date().toISOString(),_meta:{"blade/providerCircuit":{phase:$.phase,reason:$.reason,...$.statusCode!==void 0?{statusCode:$.statusCode}:{},...$.retryAfterMs!==void 0?{retryAfterMs:$.retryAfterMs}:{},...$.nextProbeAt!==void 0?{nextProbeAt:$.nextProbeAt}:{},openDurationMs:$.openDurationMs,...$.sampleCount!==void 0?{sampleCount:$.sampleCount}:{},...$.failureCount!==void 0?{failureCount:$.failureCount}:{},...$.recoveryRemainingMs!==void 0?{recoveryRemainingMs:$.recoveryRemainingMs}:{}}}});break;case"provider_retry":this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:new Date().toISOString(),_meta:{"blade/providerRetry":{phase:$.phase,attempt:$.attempt,maxRetries:$.maxRetries,reason:$.reason,...$.statusCode!==void 0?{statusCode:$.statusCode}:{},...$.delayMs!==void 0?{delayMs:$.delayMs}:{},...$.nextRetryAt!==void 0?{nextRetryAt:$.nextRetryAt}:{},...$.mode!==void 0?{mode:$.mode}:{},...$.recoveryBudgetMs!==void 0?{recoveryBudgetMs:$.recoveryBudgetMs}:{},...$.recoveryElapsedMs!==void 0?{recoveryElapsedMs:$.recoveryElapsedMs}:{},...$.recoveryRemainingMs!==void 0?{recoveryRemainingMs:$.recoveryRemainingMs}:{},...$.exhaustedBy!==void 0?{exhaustedBy:$.exhaustedBy}:{}}}});break;case"provider_stall":this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:new Date().toISOString(),_meta:{"blade/providerStall":{phase:$.phase,stallCount:$.stallCount,durationMs:$.durationMs,warningAfterMs:$.warningAfterMs,timeoutMs:$.timeoutMs,outputStarted:$.outputStarted}}});break;case"action_stationarity":this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:new Date().toISOString(),_meta:{"blade/actionStationarity":{phase:$.phase,toolName:$.toolName,runLength:$.runLength,nudgeThreshold:$.nudgeThreshold,haltThreshold:$.haltThreshold,progressAware:$.progressAware}}});break;case"task_update":this.sendPlanUpdate($.tasks);break;case"steering_applied":break;case"follow_up_started":for(let V of $.messages){if(!V.recovered||V.persisted)continue;for(let O of wz(V.content))this.sendUpdate({sessionUpdate:"user_message_chunk",content:O})}if($.recovered>0)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`[Resuming ${$.recovered} queued instruction${$.recovered===1?"":"s"} recovered after restart]
10
+ `}});break;case"provider_admission":X=$.phase!=="admitted",this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:new Date().toISOString(),_meta:{"blade/providerAdmission":$.phase!=="admitted"?{phase:$.phase,requestClass:$.requestClass,resource:$.resource,scope:$.scope,...$.reason!==void 0?{reason:$.reason}:{},queuePosition:$.queuePosition,queueDepth:$.queueDepth,inFlight:$.inFlight,limit:$.limit,waitMs:$.waitMs,maxWaitMs:$.maxWaitMs,...$.recoveryRemainingMs!==void 0?{recoveryRemainingMs:$.recoveryRemainingMs}:{}}:null}});break;case"provider_circuit":this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:new Date().toISOString(),_meta:{"blade/providerCircuit":{phase:$.phase,reason:$.reason,...$.statusCode!==void 0?{statusCode:$.statusCode}:{},...$.retryAfterMs!==void 0?{retryAfterMs:$.retryAfterMs}:{},...$.nextProbeAt!==void 0?{nextProbeAt:$.nextProbeAt}:{},openDurationMs:$.openDurationMs,...$.sampleCount!==void 0?{sampleCount:$.sampleCount}:{},...$.failureCount!==void 0?{failureCount:$.failureCount}:{},...$.recoveryRemainingMs!==void 0?{recoveryRemainingMs:$.recoveryRemainingMs}:{}}}});break;case"provider_retry":this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:new Date().toISOString(),_meta:{"blade/providerRetry":{phase:$.phase,attempt:$.attempt,maxRetries:$.maxRetries,reason:$.reason,...$.statusCode!==void 0?{statusCode:$.statusCode}:{},...$.delayMs!==void 0?{delayMs:$.delayMs}:{},...$.nextRetryAt!==void 0?{nextRetryAt:$.nextRetryAt}:{},...$.mode!==void 0?{mode:$.mode}:{},...$.recoveryBudgetMs!==void 0?{recoveryBudgetMs:$.recoveryBudgetMs}:{},...$.recoveryElapsedMs!==void 0?{recoveryElapsedMs:$.recoveryElapsedMs}:{},...$.recoveryRemainingMs!==void 0?{recoveryRemainingMs:$.recoveryRemainingMs}:{},...$.exhaustedBy!==void 0?{exhaustedBy:$.exhaustedBy}:{}}}});break;case"provider_stall":this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:new Date().toISOString(),_meta:{"blade/providerStall":{phase:$.phase,stallCount:$.stallCount,durationMs:$.durationMs,warningAfterMs:$.warningAfterMs,timeoutMs:$.timeoutMs,outputStarted:$.outputStarted}}});break;case"action_stationarity":this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:new Date().toISOString(),_meta:{"blade/actionStationarity":{phase:$.phase,toolName:$.toolName,runLength:$.runLength,nudgeThreshold:$.nudgeThreshold,haltThreshold:$.haltThreshold,progressAware:$.progressAware}}});break;case"task_update":this.sendPlanUpdate($.tasks);break;case"steering_applied":break;case"follow_up_started":for(let V of $.messages){if(!V.recovered||V.persisted)continue;for(let O of Kz(V.content))this.sendUpdate({sessionUpdate:"user_message_chunk",content:O})}if($.recovered>0)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`[Resuming ${$.recovered} queued instruction${$.recovered===1?"":"s"} recovered after restart]
11
11
  `}});break;case"goal_updated":if($.goal)this.sendUpdate(this.goalSessionUpdate($.goal));if($.goal&&$.goal.status!=="active")this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`[Goal ${$.goal.status}: ${$.goal.objective}]
12
- `}});break;case"goal_continuation_started":this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:new Date().toISOString(),_meta:{"blade/goalContinuation":{goalId:$.goal.goalId,continuation:$.continuation,...$.prematureStopPattern?{prematureStopPattern:$.prematureStopPattern}:{},...$.prematureStopCount!==void 0?{prematureStopCount:$.prematureStopCount}:{}}}});break;case"compaction":this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:new Date().toISOString(),_meta:{"blade/compaction":{phase:$.phase,...$.reason?{reason:$.reason}:{},...$.strategy?{strategy:$.strategy}:{},...$.outcome?{outcome:$.outcome}:{},...$.preTokens!==void 0?{preTokens:$.preTokens}:{},...$.preTokenSource?{preTokenSource:$.preTokenSource}:{},...$.estimatedPendingTokens!==void 0?{estimatedPendingTokens:$.estimatedPendingTokens}:{},...$.postTokens!==void 0?{postTokens:$.postTokens}:{},...$.sampleAttempts!==void 0?{sampleAttempts:$.sampleAttempts}:{},...$.inputReductions!==void 0?{inputReductions:$.inputReductions}:{},...$.messagesOmitted!==void 0?{messagesOmitted:$.messagesOmitted}:{},...$.filesOmitted!==void 0?{filesOmitted:$.filesOmitted}:{},...$.imagesOmitted!==void 0?{imagesOmitted:$.imagesOmitted}:{},...$.fallbackTargetTokens!==void 0?{fallbackTargetTokens:$.fallbackTargetTokens}:{},...$.fallbackMessagesOmitted!==void 0?{fallbackMessagesOmitted:$.fallbackMessagesOmitted}:{},...$.fallbackMessagesTruncated!==void 0?{fallbackMessagesTruncated:$.fallbackMessagesTruncated}:{},...$.failureReason?{failureReason:$.failureReason}:{}}}});break;default:break}if(!await this.flushUpdates())X.abort("acp-egress-failed")});if(!await this.flushUpdates())X.abort("acp-egress-failed");this.contextMessages=[...B.messages];let u=await F.loadSession(this.id,this.cwd);if(this.messages=u.length>0?u:[...B.messages],!A.success){let $=A.error?.type??"unknown",V=A.error?.details??A.error?.message??"Agent execution failed",O=cz(V)??i(V);throw Iz.internalError({failureType:$,taskFailure:{code:O.code,retryable:O.retryable,...O.resource?{resource:O.resource}:{}}},`Agent turn failed (${$})`)}if(X.signal.aborted)return{stopReason:"cancelled"};let g={...A.metadata?.structuredOutput?{structuredOutput:A.metadata.structuredOutput,outputSchemaDigest:A.metadata.structuredOutputSchemaDigest}:{},...A.metadata?.goalCompletionVerified?{goalCompletion:{verified:!0,verdict:A.metadata.goalVerificationVerdict,...A.metadata.goalVerifierSessionId?{verifierSessionId:A.metadata.goalVerifierSessionId}:{},...A.metadata.goalVerificationEvidenceSha256?{evidenceSha256:A.metadata.goalVerificationEvidenceSha256}:{}}}:{}};return{stopReason:"end_turn",...Object.keys(g).length>0?{_meta:g}:{}}}catch(B){if(X.signal.aborted||B instanceof Error&&B.name==="AbortError")return{stopReason:"cancelled"};throw G.error(`[AcpSession ${this.id}] Prompt error:`,B),B}finally{if(D&&!this.destroyed)this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:new Date().toISOString(),_meta:{"blade/providerAdmission":null}}),await this.flushUpdates();if(L(),this.pendingPromptCompletion===U)this.pendingPromptCompletion=null;if(this.pendingPrompt===X){if(this.pendingPrompt=null,!this.destroyed&&this.pendingResumeRequested)this.schedulePendingResume()}}}async handleUserShellCommand(z){if(!this.runtime)throw Error("Session runtime is unavailable");if(this.pendingUserShell)throw Error("A user shell command is already running");let Z=z.trimStart().slice(1).trim();if(!Z)throw Error("User shell command cannot be empty");let J=new AbortController,Y,H=new Promise((j)=>{Y=j});this.pendingUserShell=J,this.pendingUserShellCompletion=H;let W,Q="";try{let j=await this.runtime.executeUserShellCommand(Z,{signal:J.signal,onEvent:async(D)=>{if(W=D.executionId,D.type==="started"){this.sendUpdate({sessionUpdate:"tool_call",toolCallId:D.executionId,status:"in_progress",title:`! ${D.command}`,content:[],kind:"execute"});return}if(D.type==="output"){Q+=D.chunk,this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:D.executionId,status:"in_progress",content:[{type:"content",content:{type:"text",text:D.chunk}}]});return}let L=I(D.record);this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:D.executionId,status:D.record.status==="completed"?"completed":"failed",content:[{type:"content",content:{type:"text",text:Q?gz(D.record):L}}]})}}),X={role:"user",content:j.modelContent,metadata:{userShellCommand:JSON.parse(JSON.stringify(j.record))}};if(this.messages.push(X),this.contextMessages.push(X),j.delivery==="next_turn")this.schedulePendingResume();if(!await this.flushUpdates())return J.abort("acp-egress-failed"),{stopReason:"cancelled"};return{stopReason:j.record.status==="aborted"?"cancelled":"end_turn"}}catch(j){if(W)this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:W,status:"failed",content:[{type:"content",content:{type:"text",text:j instanceof Error?j.message:String(j)}}]});if(J.signal.aborted)return{stopReason:"cancelled"};throw j}finally{if(Y(),this.pendingUserShellCompletion===H)this.pendingUserShellCompletion=null;if(this.pendingUserShell===J)this.pendingUserShell=null}}schedulePendingResume(){if(this.destroyed||this.connection.signal.aborted)return;this.pendingResumeRequested=!0,queueMicrotask(()=>{this.resumePendingIfIdle()})}async resumePendingIfIdle(){if(this.destroyed||this.connection.signal.aborted)return;if(this.pendingPrompt||this.pendingUserShell||!this.runtime||!this.agent)return;let z=this.runtime.getPendingSteeringCount()>0,Z=z?null:await this.runtime.getGoal(),J=Z?.status==="active"||Z?.status==="verifying";if(!z&&!J){this.pendingResumeRequested=!1;return}this.pendingResumeRequested=!1,await this.prompt({sessionId:this.id,prompt:[]},{pendingInputOnly:z,goalContinuationOnly:J}).catch((Y)=>{G.error(`[AcpSession ${this.id}] Failed to resume pending input:`,Y)})}cancel(){G.info(`[AcpSession ${this.id}] Cancel requested`),this.pendingResumeRequested=!1;let z=!1;if(this.pendingPrompt)this.pendingPrompt.abort(),this.pendingPrompt=null,z=!0;if(this.pendingUserShell)this.pendingUserShell.abort(),this.pendingUserShell=null,z=!0;if(this.pendingSideConversation)this.pendingSideConversation.abort(),this.pendingSideConversation=null,z=!0;if(!z)G.warn(`[AcpSession ${this.id}] No pending prompt to cancel`)}async setMode(z){let J=["default","auto-edit","yolo","plan"].includes(z)?z:"default",Y=this.mapModeIdToPermissionMode(J);await F.setSessionPermissionMode(this.id,this.cwd,Y),this.mode=J,G.info(`[AcpSession ${this.id}] Mode set to: ${this.mode}`),this.sendUpdate({sessionUpdate:"current_mode_update",currentModeId:this.mode})}mapModeToPermissionMode(){return this.mapModeIdToPermissionMode(this.mode)}mapModeIdToPermissionMode(z){switch(z){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(G.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");if(!this.runtime)throw Error("Session runtime is unavailable");let Z=this.runtime.getCurrentModelId();await this.agent.switchModel(z);try{try{await F.updateSessionMetadata(this.id,this.cwd,{selectedModelId:z})}catch(J){if(!(J instanceof P)&&J.code!=="ENOENT")throw J;await F.createSessionMetadata(this.id,this.cwd,{taskStatus:"completed",selectedModelId:z})}}catch(J){if(Z&&Z!==z)await this.agent.switchModel(Z).catch((Y)=>{G.error(`[AcpSession ${this.id}] Failed to roll back a non-durable model switch:`,Y)});throw J}}getCurrentModelId(){return this.runtime?.getCurrentModelId()}async setReasoningEffort(z){if(this.pendingPrompt)throw Error("Cannot switch reasoning effort while a prompt is active");if(!this.runtime)throw Error("Session runtime is unavailable");let Z=this.runtime.getReasoningConfiguration();try{this.runtime.resolveReasoningConfiguration(z)}catch(J){throw Error(J instanceof Error?J.message:"Invalid reasoning effort")}if(Z.selection===z)return;await this.runtime.refresh({reasoningEffort:z});try{try{await F.updateSessionMetadata(this.id,this.cwd,{reasoningEffort:z})}catch(J){if(!(J instanceof P)&&J.code!=="ENOENT")throw J;await F.createSessionMetadata(this.id,this.cwd,{taskStatus:"completed",selectedModelId:this.runtime.getCurrentModelId(),reasoningEffort:z})}}catch(J){throw await this.runtime.refresh({reasoningEffort:Z.selection}),J}}async setServiceTier(z){if(this.pendingPrompt)throw Error("Cannot switch service tier while a prompt is active");if(!this.runtime)throw Error("Session runtime is unavailable");let Z=this.runtime.getServiceTierConfiguration();try{this.runtime.resolveServiceTierConfiguration(z)}catch(J){throw Error(J instanceof Error?J.message:"Invalid service tier")}if(Z.selection===z)return;await this.runtime.refresh({serviceTier:z});try{try{await F.updateSessionMetadata(this.id,this.cwd,{serviceTier:z})}catch(J){if(!(J instanceof P)&&J.code!=="ENOENT")throw J;await F.createSessionMetadata(this.id,this.cwd,{taskStatus:"completed",selectedModelId:this.runtime.getCurrentModelId(),serviceTier:z})}}catch(J){throw await this.runtime.refresh({serviceTier:Z.selection}),J}}async setResponseVerbosity(z){if(this.pendingPrompt)throw Error("Cannot switch response verbosity while a prompt is active");if(!this.runtime)throw Error("Session runtime is unavailable");let Z=this.runtime.getResponseVerbosityConfiguration();try{this.runtime.resolveResponseVerbosityConfiguration(z)}catch(J){throw Error(J instanceof Error?J.message:"Invalid response verbosity")}if(Z.selection===z)return;await this.runtime.refresh({responseVerbosity:z});try{try{await F.updateSessionMetadata(this.id,this.cwd,{responseVerbosity:z})}catch(J){if(!(J instanceof P)&&J.code!=="ENOENT")throw J;await F.createSessionMetadata(this.id,this.cwd,{taskStatus:"completed",selectedModelId:this.runtime.getCurrentModelId(),responseVerbosity:z})}}catch(J){throw await this.runtime.refresh({responseVerbosity:Z.selection}),J}}async setCommunicationStyle(z){if(this.pendingPrompt)throw Error("Cannot switch communication style while a prompt is active");if(!this.runtime)throw Error("Session runtime is unavailable");let Z=this.runtime.getCommunicationStyleConfiguration(),J=this.runtime.resolveCommunicationStyleConfiguration(z);if(J.source!=="built-in"&&!J.contentSha256)throw Error("Custom communication style has no provenance");if(Z.selection===z)return;await this.runtime.refresh({communicationStyle:z});try{try{await F.updateSessionMetadata(this.id,this.cwd,{communicationStyle:z,communicationStyleDigest:J.source==="built-in"?null:J.contentSha256})}catch(Y){if(!(Y instanceof P)&&Y.code!=="ENOENT")throw Y;await F.createSessionMetadata(this.id,this.cwd,{taskStatus:"completed",selectedModelId:this.runtime.getCurrentModelId(),communicationStyle:z,...J.source!=="built-in"&&J.contentSha256?{communicationStyleDigest:J.contentSha256}:{}})}}catch(Y){throw await this.runtime.refresh({communicationStyle:Z.selection}),Y}}getModelConfiguration(){if(!this.runtime)return;let z=this.runtime.getConfig();return{currentModelId:this.runtime.getCurrentModelId()??z.currentModelId,models:z.models.map((Z)=>structuredClone(Z)),modelProviders:structuredClone(z.modelProviders),reasoning:this.runtime.getReasoningConfiguration(),serviceTier:this.runtime.getServiceTierConfiguration(),responseVerbosity:this.runtime.getResponseVerbosityConfiguration(),communicationStyle:this.runtime.getCommunicationStyleConfiguration()}}getMode(){return this.mode}isIdleForResidency(){return!this.destroyed&&this.pendingPrompt===null&&this.pendingUserShell===null&&this.pendingSideConversation===null&&(this.runtime?.isIdleForResidency()??!1)}destroy(z={}){if(this.destroyPromise)return this.destroyFinished?Promise.resolve():this.destroyPromise;return this.destroyPromise=this.destroyOwnedResources(z.discardPendingInput===!0).finally(()=>{this.destroyFinished=!0}),this.destroyPromise}async destroyOwnedResources(z){if(this.destroyed=!0,this.updateEgress.close(new Lz("closed","ACP Session was destroyed")),this.availableCommandsTimer!==null)clearTimeout(this.availableCommandsTimer),this.availableCommandsTimer=null;this.taskStatusUnsubscribe?.(),this.taskStatusUnsubscribe=void 0;let Z=this.agent,J=this.runtime,Y=this.pendingPromptCompletion,H=this.pendingUserShellCompletion,W=this.pendingSideConversationCompletion;this.agent=null,this.runtime=null;let Q,j=async(X)=>{try{await X()}catch(D){Q??=D}};if(await j(()=>this.cancel()),Y)await j(()=>Y);if(H)await j(()=>H);if(W)await j(()=>W);if(z&&Y&&J)await j(()=>J.discardPendingInput());if(Z)await j(()=>Z.destroy());if(J)await j(()=>J.dispose());if(await j(()=>N.destroySession(this.id)),G.debug(`[AcpSession ${this.id}] Destroyed`),Q!==void 0)throw Q}resolvePrompt(z){let Z=[],J=[],Y=0,H=0,W=0,Q=(X)=>{if(J.length>0)J.push({type:"text",text:`
13
- `}),W+=1;if(J.push(X),X.type==="text")W+=X.text.length};for(let X of z)if(X.type==="text")Z.push(X.text),Q({type:"text",text:X.text});else if(X.type==="image"){let D=`data:${X.mimeType};base64,${X.data}`;Y+=1,H+=D.length,Z.push(`[Image: ${X.mimeType}]`),Q({type:"image_url",image_url:{url:D}})}else if(X.type==="resource"){let D=X.resource;if("text"in D){let L=`<file path="${D.uri}">
14
- ${D.text}
15
- </file>`;Z.push(L),Q({type:"text",text:L})}}else if(X.type==="resource_link"){let D=`[Resource: ${X.uri}]`;Z.push(D),Q({type:"text",text:D})}if(Y>S)throw Error(`ACP prompt contains more than ${S} images`);if(H>m)throw Error("ACP prompt images exceed the 5 MiB limit");if(W>M)throw Error(`ACP prompt text exceeds ${M} characters`);let j=Z.join(`
16
- `);return{content:Y>0?J:j,displayText:j}}canSendUpdates(){return!this.destroyed&&!this.connection.signal.aborted&&!this.updateEgress.stats().closed}async sendUpdateAndWait(z){if(!this.canSendUpdates())return!1;let Z=this.updateEgress.offer({sessionId:this.id,update:z});if(!Z.accepted)return!1;try{return await Z.completion,this.canSendUpdates()}catch{return!1}}goalSessionUpdate(z){return{sessionUpdate:"session_info_update",updatedAt:z.updatedAt,_meta:{"blade/goal":{goalId:z.goalId,status:z.status,verificationAttempt:z.completionVerification?.attempt,verificationStatus:z.completionVerification?.status,verifierSessionId:z.completionVerification?.verifierSessionId,verificationEvidenceSha256:z.completionVerification?.evidenceSha256,verificationSummary:z.completionVerification?.summary,verificationStallCount:z.verificationStall?.consecutiveCount}}}}sendUpdate(z){if(!this.canSendUpdates())return;this.updateEgress.offer({sessionId:this.id,update:z})}async flushUpdates(){if(!this.canSendUpdates())return!1;try{return await this.updateEgress.flush(),this.canSendUpdates()}catch{return!1}}handleUpdateEgressFailure(z){if(this.destroyed)return;G.warn(`[AcpSession ${this.id}] Update egress closed: kind=${z.kind}`),this.pendingPrompt?.abort("acp-egress-failed"),this.pendingUserShell?.abort("acp-egress-failed"),this.pendingSideConversation?.abort("acp-egress-failed")}sendPlanUpdate(z){let Z=z.map((J)=>({content:J.subject,priority:J.priority,status:J.status}));G.debug(`[AcpSession ${this.id}] Sending plan update with ${Z.length} entries`),this.sendUpdate({sessionUpdate:"plan",entries:Z})}async requestPermission(z){let Z=this.pendingPrompt?.signal;if(z.type==="askUserQuestion")return this.requestUserQuestions(z,Z);if(z.type==="mcpElicitation")return this.requestMcpElicitation(z,Z);let J=z.kind?.toLowerCase()||"execute";if(z.type!=="mcpSampling"&&this.shouldAutoApprove(J))return G.debug(`[AcpSession ${this.id}] Auto-approving ${J} in mode: ${this.mode}`),{approved:!0};if(this.mode==="plan"&&(J==="write"||J==="execute"))return G.debug(`[AcpSession ${this.id}] Rejecting ${J} in plan mode`),{approved:!1,reason:"Write and execute operations are not allowed in Plan mode"};try{let Y=h(),H=[];if(z.message)H.push({type:"content",content:{type:"text",text:z.message}});if(z.details)H.push({type:"content",content:{type:"text",text:z.details}});if(z.risks&&z.risks.length>0)H.push({type:"content",content:{type:"text",text:`Risks:
12
+ `}});break;case"goal_continuation_started":this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:new Date().toISOString(),_meta:{"blade/goalContinuation":{goalId:$.goal.goalId,continuation:$.continuation,...$.prematureStopPattern?{prematureStopPattern:$.prematureStopPattern}:{},...$.prematureStopCount!==void 0?{prematureStopCount:$.prematureStopCount}:{}}}});break;case"compaction":this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:new Date().toISOString(),_meta:{"blade/compaction":{phase:$.phase,...$.reason?{reason:$.reason}:{},...$.strategy?{strategy:$.strategy}:{},...$.outcome?{outcome:$.outcome}:{},...$.preTokens!==void 0?{preTokens:$.preTokens}:{},...$.preTokenSource?{preTokenSource:$.preTokenSource}:{},...$.estimatedPendingTokens!==void 0?{estimatedPendingTokens:$.estimatedPendingTokens}:{},...$.postTokens!==void 0?{postTokens:$.postTokens}:{},...$.sampleAttempts!==void 0?{sampleAttempts:$.sampleAttempts}:{},...$.inputReductions!==void 0?{inputReductions:$.inputReductions}:{},...$.messagesOmitted!==void 0?{messagesOmitted:$.messagesOmitted}:{},...$.filesOmitted!==void 0?{filesOmitted:$.filesOmitted}:{},...$.imagesOmitted!==void 0?{imagesOmitted:$.imagesOmitted}:{},...$.fallbackTargetTokens!==void 0?{fallbackTargetTokens:$.fallbackTargetTokens}:{},...$.fallbackMessagesOmitted!==void 0?{fallbackMessagesOmitted:$.fallbackMessagesOmitted}:{},...$.fallbackMessagesTruncated!==void 0?{fallbackMessagesTruncated:$.fallbackMessagesTruncated}:{},...$.failureReason?{failureReason:$.failureReason}:{}}}});break;default:break}if(!await this.flushUpdates())D.abort("acp-egress-failed")});if(!await this.flushUpdates())D.abort("acp-egress-failed");this.contextMessages=[...B.messages];let g=await U.loadSession(this.id,this.cwd);if(this.messages=g.length>0?g:[...B.messages],!A.success){let $=A.error?.type??"unknown",V=A.error?.details??A.error?.message??"Agent execution failed",O=pz(V)??r(V);throw Cz.internalError({failureType:$,taskFailure:{code:O.code,retryable:O.retryable,...O.resource?{resource:O.resource}:{}}},`Agent turn failed (${$})`)}if(D.signal.aborted)return{stopReason:"cancelled"};let c={...A.metadata?.structuredOutput?{structuredOutput:A.metadata.structuredOutput,outputSchemaDigest:A.metadata.structuredOutputSchemaDigest}:{},...A.metadata?.goalCompletionVerified?{goalCompletion:{verified:!0,verdict:A.metadata.goalVerificationVerdict,...A.metadata.goalVerifierSessionId?{verifierSessionId:A.metadata.goalVerifierSessionId}:{},...A.metadata.goalVerificationEvidenceSha256?{evidenceSha256:A.metadata.goalVerificationEvidenceSha256}:{}}}:{}};return{stopReason:"end_turn",...Object.keys(c).length>0?{_meta:c}:{}}}catch(B){if(D.signal.aborted||B instanceof Error&&B.name==="AbortError")return{stopReason:"cancelled"};throw G.error(`[AcpSession ${this.id}] Prompt error:`,B),B}finally{if(X&&!this.destroyed)this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:new Date().toISOString(),_meta:{"blade/providerAdmission":null}}),await this.flushUpdates();if(L(),this.pendingPromptCompletion===F)this.pendingPromptCompletion=null;if(this.pendingPrompt===D){if(this.pendingPrompt=null,!this.destroyed&&this.pendingResumeRequested)this.schedulePendingResume()}}}async handleUserShellCommand(z){if(!this.runtime)throw Error("Session runtime is unavailable");if(this.pendingUserShell)throw Error("A user shell command is already running");let Z=z.trimStart().slice(1).trim();if(!Z)throw Error("User shell command cannot be empty");let J=new AbortController,Y,H=new Promise((j)=>{Y=j});this.pendingUserShell=J,this.pendingUserShellCompletion=H;let W,Q="";try{let j=await this.runtime.executeUserShellCommand(Z,{signal:J.signal,onEvent:async(X)=>{if(W=X.executionId,X.type==="started"){this.sendUpdate({sessionUpdate:"tool_call",toolCallId:X.executionId,status:"in_progress",title:`! ${X.command}`,content:[],kind:"execute"});return}if(X.type==="output"){Q+=X.chunk,this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:X.executionId,status:"in_progress",content:[{type:"content",content:{type:"text",text:X.chunk}}]});return}let L=C(X.record);this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:X.executionId,status:X.record.status==="completed"?"completed":"failed",content:[{type:"content",content:{type:"text",text:Q?cz(X.record):L}}]})}}),D={role:"user",content:j.modelContent,metadata:{userShellCommand:JSON.parse(JSON.stringify(j.record))}};if(this.messages.push(D),this.contextMessages.push(D),j.delivery==="next_turn")this.schedulePendingResume();if(!await this.flushUpdates())return J.abort("acp-egress-failed"),{stopReason:"cancelled"};return{stopReason:j.record.status==="aborted"?"cancelled":"end_turn"}}catch(j){if(W)this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:W,status:"failed",content:[{type:"content",content:{type:"text",text:j instanceof Error?j.message:String(j)}}]});if(J.signal.aborted)return{stopReason:"cancelled"};throw j}finally{if(Y(),this.pendingUserShellCompletion===H)this.pendingUserShellCompletion=null;if(this.pendingUserShell===J)this.pendingUserShell=null}}schedulePendingResume(){if(this.destroyed||this.connection.signal.aborted)return;this.pendingResumeRequested=!0,queueMicrotask(()=>{this.resumePendingIfIdle()})}async resumePendingIfIdle(){if(this.destroyed||this.connection.signal.aborted)return;if(this.pendingPrompt||this.pendingUserShell||!this.runtime||!this.agent)return;let z=this.runtime.getPendingSteeringCount()>0,Z=z?null:await this.runtime.getGoal(),J=Z?.status==="active"||Z?.status==="verifying";if(!z&&!J){this.pendingResumeRequested=!1;return}this.pendingResumeRequested=!1,await this.prompt({sessionId:this.id,prompt:[]},{pendingInputOnly:z,goalContinuationOnly:J}).catch((Y)=>{G.error(`[AcpSession ${this.id}] Failed to resume pending input:`,Y)})}cancel(){G.info(`[AcpSession ${this.id}] Cancel requested`),this.pendingResumeRequested=!1;let z=!1;if(this.pendingPrompt)this.pendingPrompt.abort(),this.pendingPrompt=null,z=!0;if(this.pendingUserShell)this.pendingUserShell.abort(),this.pendingUserShell=null,z=!0;if(this.pendingSideConversation)this.pendingSideConversation.abort(),this.pendingSideConversation=null,z=!0;if(!z)G.warn(`[AcpSession ${this.id}] No pending prompt to cancel`)}async setMode(z){let J=["default","auto-edit","yolo","plan"].includes(z)?z:"default",Y=this.mapModeIdToPermissionMode(J);await U.setSessionPermissionMode(this.id,this.cwd,Y),this.mode=J,G.info(`[AcpSession ${this.id}] Mode set to: ${this.mode}`),this.sendUpdate({sessionUpdate:"current_mode_update",currentModeId:this.mode})}mapModeToPermissionMode(){return this.mapModeIdToPermissionMode(this.mode)}mapModeIdToPermissionMode(z){switch(z){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(G.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");if(!this.runtime)throw Error("Session runtime is unavailable");let Z=this.runtime.getCurrentModelId();await this.agent.switchModel(z);try{try{await U.updateSessionMetadata(this.id,this.cwd,{selectedModelId:z})}catch(J){if(!(J instanceof q)&&J.code!=="ENOENT")throw J;await U.createSessionMetadata(this.id,this.cwd,{taskStatus:"completed",selectedModelId:z})}}catch(J){if(Z&&Z!==z)await this.agent.switchModel(Z).catch((Y)=>{G.error(`[AcpSession ${this.id}] Failed to roll back a non-durable model switch:`,Y)});throw J}}getCurrentModelId(){return this.runtime?.getCurrentModelId()}async setReasoningEffort(z){if(this.pendingPrompt)throw Error("Cannot switch reasoning effort while a prompt is active");if(!this.runtime)throw Error("Session runtime is unavailable");let Z=this.runtime.getReasoningConfiguration();try{this.runtime.resolveReasoningConfiguration(z)}catch(J){throw Error(J instanceof Error?J.message:"Invalid reasoning effort")}if(Z.selection===z)return;await this.runtime.refresh({reasoningEffort:z});try{try{await U.updateSessionMetadata(this.id,this.cwd,{reasoningEffort:z})}catch(J){if(!(J instanceof q)&&J.code!=="ENOENT")throw J;await U.createSessionMetadata(this.id,this.cwd,{taskStatus:"completed",selectedModelId:this.runtime.getCurrentModelId(),reasoningEffort:z})}}catch(J){throw await this.runtime.refresh({reasoningEffort:Z.selection}),J}}async setServiceTier(z){if(this.pendingPrompt)throw Error("Cannot switch service tier while a prompt is active");if(!this.runtime)throw Error("Session runtime is unavailable");let Z=this.runtime.getServiceTierConfiguration();try{this.runtime.resolveServiceTierConfiguration(z)}catch(J){throw Error(J instanceof Error?J.message:"Invalid service tier")}if(Z.selection===z)return;await this.runtime.refresh({serviceTier:z});try{try{await U.updateSessionMetadata(this.id,this.cwd,{serviceTier:z})}catch(J){if(!(J instanceof q)&&J.code!=="ENOENT")throw J;await U.createSessionMetadata(this.id,this.cwd,{taskStatus:"completed",selectedModelId:this.runtime.getCurrentModelId(),serviceTier:z})}}catch(J){throw await this.runtime.refresh({serviceTier:Z.selection}),J}}async setResponseVerbosity(z){if(this.pendingPrompt)throw Error("Cannot switch response verbosity while a prompt is active");if(!this.runtime)throw Error("Session runtime is unavailable");let Z=this.runtime.getResponseVerbosityConfiguration();try{this.runtime.resolveResponseVerbosityConfiguration(z)}catch(J){throw Error(J instanceof Error?J.message:"Invalid response verbosity")}if(Z.selection===z)return;await this.runtime.refresh({responseVerbosity:z});try{try{await U.updateSessionMetadata(this.id,this.cwd,{responseVerbosity:z})}catch(J){if(!(J instanceof q)&&J.code!=="ENOENT")throw J;await U.createSessionMetadata(this.id,this.cwd,{taskStatus:"completed",selectedModelId:this.runtime.getCurrentModelId(),responseVerbosity:z})}}catch(J){throw await this.runtime.refresh({responseVerbosity:Z.selection}),J}}async setCommunicationStyle(z){if(this.pendingPrompt)throw Error("Cannot switch communication style while a prompt is active");if(!this.runtime)throw Error("Session runtime is unavailable");let Z=this.runtime.getCommunicationStyleConfiguration(),J=this.runtime.resolveCommunicationStyleConfiguration(z);if(J.source!=="built-in"&&!J.contentSha256)throw Error("Custom communication style has no provenance");if(Z.selection===z)return;await this.runtime.refresh({communicationStyle:z});try{try{await U.updateSessionMetadata(this.id,this.cwd,{communicationStyle:z,communicationStyleDigest:J.source==="built-in"?null:J.contentSha256})}catch(Y){if(!(Y instanceof q)&&Y.code!=="ENOENT")throw Y;await U.createSessionMetadata(this.id,this.cwd,{taskStatus:"completed",selectedModelId:this.runtime.getCurrentModelId(),communicationStyle:z,...J.source!=="built-in"&&J.contentSha256?{communicationStyleDigest:J.contentSha256}:{}})}}catch(Y){throw await this.runtime.refresh({communicationStyle:Z.selection}),Y}}getModelConfiguration(){if(!this.runtime)return;let z=this.runtime.getConfig();return{currentModelId:this.runtime.getCurrentModelId()??z.currentModelId,models:z.models.map((Z)=>structuredClone(Z)),modelProviders:structuredClone(z.modelProviders),reasoning:this.runtime.getReasoningConfiguration(),serviceTier:this.runtime.getServiceTierConfiguration(),responseVerbosity:this.runtime.getResponseVerbosityConfiguration(),communicationStyle:this.runtime.getCommunicationStyleConfiguration()}}getMode(){return this.mode}isIdleForResidency(){return!this.destroyed&&this.pendingPrompt===null&&this.pendingUserShell===null&&this.pendingSideConversation===null&&(this.runtime?.isIdleForResidency()??!1)}destroy(z={}){if(this.destroyPromise)return this.destroyFinished?Promise.resolve():this.destroyPromise;return this.destroyPromise=this.destroyOwnedResources(z.discardPendingInput===!0).finally(()=>{this.destroyFinished=!0}),this.destroyPromise}async destroyOwnedResources(z){if(this.destroyed=!0,this.updateEgress.close(new Bz("closed","ACP Session was destroyed")),this.availableCommandsTimer!==null)clearTimeout(this.availableCommandsTimer),this.availableCommandsTimer=null;this.taskStatusUnsubscribe?.(),this.taskStatusUnsubscribe=void 0;let Z=this.agent,J=this.runtime,Y=this.pendingPromptCompletion,H=this.pendingUserShellCompletion,W=this.pendingSideConversationCompletion;this.agent=null,this.runtime=null;let Q,j=async(D)=>{try{await D()}catch(X){Q??=X}};if(await j(()=>this.cancel()),Y)await j(()=>Y);if(H)await j(()=>H);if(W)await j(()=>W);if(z&&Y&&J)await j(()=>J.discardPendingInput());if(Z)await j(()=>Z.destroy());if(J)await j(()=>J.dispose());if(await j(()=>N.destroySession(this.id)),G.debug(`[AcpSession ${this.id}] Destroyed`),Q!==void 0)throw Q}resolvePrompt(z){let Z=[],J=[],Y=0,H=0,W=0,Q=(X)=>{if(J.length>0)J.push({type:"text",text:`
13
+ `}),W+=1;if(J.push(X),X.type==="text")W+=X.text.length};for(let X of z)if(X.type==="text")Z.push(X.text),Q({type:"text",text:X.text});else if(X.type==="image"){let L=`data:${X.mimeType};base64,${X.data}`;Y+=1,H+=L.length,Z.push(`[Image: ${X.mimeType}]`),Q({type:"image_url",image_url:{url:L}})}else if(X.type==="resource"){let L=X.resource;if("text"in L){let F=`<file path="${L.uri}">
14
+ ${L.text}
15
+ </file>`;Z.push(F),Q({type:"text",text:F})}}else if(X.type==="resource_link"){let L=`[Resource: ${X.uri}]`;Z.push(L),Q({type:"text",text:L})}if(Y>S)throw Error(`ACP prompt contains more than ${S} images`);if(H>d)throw Error("ACP prompt images exceed the 5 MiB limit");if(W>M)throw Error(`ACP prompt text exceeds ${M} characters`);if(Buffer.byteLength(Z.join(`
16
+ `),"utf8")>k)throw Error(`ACP prompt text exceeds ${k} bytes`);let D=Z.join(`
17
+ `);return{content:Y>0?J:D,displayText:D}}canSendUpdates(){return!this.destroyed&&!this.connection.signal.aborted&&!this.updateEgress.stats().closed}async sendUpdateAndWait(z){if(!this.canSendUpdates())return!1;let Z=this.updateEgress.offer({sessionId:this.id,update:z});if(!Z.accepted)return!1;try{return await Z.completion,this.canSendUpdates()}catch{return!1}}goalSessionUpdate(z){return{sessionUpdate:"session_info_update",updatedAt:z.updatedAt,_meta:{"blade/goal":{goalId:z.goalId,status:z.status,verificationAttempt:z.completionVerification?.attempt,verificationStatus:z.completionVerification?.status,verifierSessionId:z.completionVerification?.verifierSessionId,verificationEvidenceSha256:z.completionVerification?.evidenceSha256,verificationSummary:z.completionVerification?.summary,verificationStallCount:z.verificationStall?.consecutiveCount}}}}sendUpdate(z){if(!this.canSendUpdates())return;this.updateEgress.offer({sessionId:this.id,update:z})}async flushUpdates(){if(!this.canSendUpdates())return!1;try{return await this.updateEgress.flush(),this.canSendUpdates()}catch{return!1}}handleUpdateEgressFailure(z){if(this.destroyed)return;G.warn(`[AcpSession ${this.id}] Update egress closed: kind=${z.kind}`),this.pendingPrompt?.abort("acp-egress-failed"),this.pendingUserShell?.abort("acp-egress-failed"),this.pendingSideConversation?.abort("acp-egress-failed")}sendPlanUpdate(z){let Z=z.map((J)=>({content:J.subject,priority:J.priority,status:J.status}));G.debug(`[AcpSession ${this.id}] Sending plan update with ${Z.length} entries`),this.sendUpdate({sessionUpdate:"plan",entries:Z})}async requestPermission(z){let Z=this.pendingPrompt?.signal;if(z.type==="askUserQuestion")return this.requestUserQuestions(z,Z);if(z.type==="mcpElicitation")return this.requestMcpElicitation(z,Z);let J=z.kind?.toLowerCase()||"execute";if(z.type!=="mcpSampling"&&this.shouldAutoApprove(J))return G.debug(`[AcpSession ${this.id}] Auto-approving ${J} in mode: ${this.mode}`),{approved:!0};if(this.mode==="plan"&&(J==="write"||J==="execute"))return G.debug(`[AcpSession ${this.id}] Rejecting ${J} in plan mode`),{approved:!1,reason:"Write and execute operations are not allowed in Plan mode"};try{let Y=h(),H=[];if(z.message)H.push({type:"content",content:{type:"text",text:z.message}});if(z.details)H.push({type:"content",content:{type:"text",text:z.details}});if(z.risks&&z.risks.length>0)H.push({type:"content",content:{type:"text",text:`Risks:
17
18
  - ${z.risks.join(`
18
- - `)}`}});let W=this.mapToolKind(J),Q={sessionId:this.id,options:z.type==="mcpSampling"?[{optionId:"allow_once",name:"Allow this sampling request",kind:"allow_once"},{optionId:"reject_once",name:"Deny",kind:"reject_once"}]:[{optionId:"allow_once",name:"Allow once",kind:"allow_once"},{optionId:"allow_always",name:"Always allow",kind:"allow_always"},{optionId:"reject_once",name:"Deny once",kind:"reject_once"},{optionId:"reject_always",name:"Always deny",kind:"reject_always"}],toolCall:{toolCallId:Y,status:"pending",title:z.title||"Permission Required",content:H,kind:W}},j=await this.waitForClientInteraction(this.connection.requestPermission(Q),Z);if(!j)return{approved:!1,reason:k};let X=j.outcome;if(X.outcome==="cancelled")return{approved:!1,reason:"User cancelled the permission request"};let D=X.optionId;if(D==="allow_always")return{approved:!0,scope:"project"};if(D==="reject_always")return{approved:!1,scope:"project",reason:"User permanently denied the permission request"};let L=D==="allow_once";return{approved:L,scope:"once",reason:L?void 0:"User denied the operation"}}catch(Y){return G.warn(`[AcpSession ${this.id}] Permission request failed:`,Y),{approved:!1,reason:"Permission request failed"}}}async requestUserQuestions(z,Z){let J=z.questions??[];if(J.length===0)return{approved:!1,reason:"No structured questions were provided"};if(J.some((H)=>H.multiSelect))return{approved:!1,reason:"ACP does not support multi-select question responses"};let Y={};try{for(let[H,W]of J.entries()){let Q=W.options.map((L,U)=>`answer:${H}:${U}`),j=`answer:${H}:cancel`,X=await this.waitForClientInteraction(this.connection.requestPermission({sessionId:this.id,options:[...W.options.map((L,U)=>({optionId:Q[U],name:L.label,kind:"allow_once"})),{optionId:j,name:"Cancel",kind:"reject_once"}],toolCall:{toolCallId:h(),status:"pending",title:W.header,kind:"think",content:[{type:"content",content:{type:"text",text:[W.question,...W.options.map((L)=>`${L.label}: ${L.description}`)].join(`
19
- `)}}]}}),Z);if(!X)return{approved:!1,reason:k};if(X.outcome.outcome!=="selected")return{approved:!1,reason:"User cancelled the question prompt"};let D=Q.indexOf(X.outcome.optionId);if(D<0)return{approved:!1,reason:"User cancelled the question prompt"};Y[W.header]=W.options[D].label}return{approved:!0,answers:Y}}catch(H){return G.warn(`[AcpSession ${this.id}] Question request failed:`,H),{approved:!1,reason:"Question request failed"}}}async requestMcpElicitation(z,Z){let J=z.mcpElicitation;if(!J)return{approved:!1,reason:"MCP elicitation details are missing",elicitation:{action:"cancel"}};try{if(J.mode==="url"){let H=await this.requestElicitationChoice("MCP external authorization",[J.message,`Server: ${J.serverName}`,`Domain: ${J.domain??"unknown"}`,`URL: ${J.url??""}`,"Open this URL yourself only if you trust the MCP server."].join(`
19
+ - `)}`}});let W=this.mapToolKind(J),Q={sessionId:this.id,options:z.type==="mcpSampling"?[{optionId:"allow_once",name:"Allow this sampling request",kind:"allow_once"},{optionId:"reject_once",name:"Deny",kind:"reject_once"}]:[{optionId:"allow_once",name:"Allow once",kind:"allow_once"},{optionId:"allow_always",name:"Always allow",kind:"allow_always"},{optionId:"reject_once",name:"Deny once",kind:"reject_once"},{optionId:"reject_always",name:"Always deny",kind:"reject_always"}],toolCall:{toolCallId:Y,status:"pending",title:z.title||"Permission Required",content:H,kind:W}},j=await this.waitForClientInteraction(this.connection.requestPermission(Q),Z);if(!j)return{approved:!1,reason:I};let D=j.outcome;if(D.outcome==="cancelled")return{approved:!1,reason:"User cancelled the permission request"};let X=D.optionId;if(X==="allow_always")return{approved:!0,scope:"project"};if(X==="reject_always")return{approved:!1,scope:"project",reason:"User permanently denied the permission request"};let L=X==="allow_once";return{approved:L,scope:"once",reason:L?void 0:"User denied the operation"}}catch(Y){return G.warn(`[AcpSession ${this.id}] Permission request failed:`,Y),{approved:!1,reason:"Permission request failed"}}}async requestUserQuestions(z,Z){let J=z.questions??[];if(J.length===0)return{approved:!1,reason:"No structured questions were provided"};if(J.some((H)=>H.multiSelect))return{approved:!1,reason:"ACP does not support multi-select question responses"};let Y={};try{for(let[H,W]of J.entries()){let Q=W.options.map((L,F)=>`answer:${H}:${F}`),j=`answer:${H}:cancel`,D=await this.waitForClientInteraction(this.connection.requestPermission({sessionId:this.id,options:[...W.options.map((L,F)=>({optionId:Q[F],name:L.label,kind:"allow_once"})),{optionId:j,name:"Cancel",kind:"reject_once"}],toolCall:{toolCallId:h(),status:"pending",title:W.header,kind:"think",content:[{type:"content",content:{type:"text",text:[W.question,...W.options.map((L)=>`${L.label}: ${L.description}`)].join(`
20
+ `)}}]}}),Z);if(!D)return{approved:!1,reason:I};if(D.outcome.outcome!=="selected")return{approved:!1,reason:"User cancelled the question prompt"};let X=Q.indexOf(D.outcome.optionId);if(X<0)return{approved:!1,reason:"User cancelled the question prompt"};Y[W.header]=W.options[X].label}return{approved:!0,answers:Y}}catch(H){return G.warn(`[AcpSession ${this.id}] Question request failed:`,H),{approved:!1,reason:"Question request failed"}}}async requestMcpElicitation(z,Z){let J=z.mcpElicitation;if(!J)return{approved:!1,reason:"MCP elicitation details are missing",elicitation:{action:"cancel"}};try{if(J.mode==="url"){let H=await this.requestElicitationChoice("MCP external authorization",[J.message,`Server: ${J.serverName}`,`Domain: ${J.domain??"unknown"}`,`URL: ${J.url??""}`,"Open this URL yourself only if you trust the MCP server."].join(`
20
21
  `),[{id:"accept",label:"I will open this URL"},{id:"decline",label:"Decline"}],Z);if(H==="accept")return{approved:!0,elicitation:{action:"accept"}};return{approved:!1,reason:H==="decline"?"User declined URL":"User cancelled",elicitation:{action:H==="decline"?"decline":"cancel"}}}let Y=Object.create(null);for(let H of J.fields??[]){let W=await this.collectAcpElicitationField(H,Z);if(W.cancelled)return{approved:!1,reason:W.reason,elicitation:{action:"cancel"}};if(W.value!==void 0)Y[H.name]=W.value}return{approved:!0,elicitation:{action:"accept",content:Y}}}catch(Y){return G.warn(`[AcpSession ${this.id}] MCP elicitation failed:`,Y),{approved:!1,reason:"MCP elicitation failed",elicitation:{action:"cancel"}}}}async collectAcpElicitationField(z,Z){if(z.type==="select"||z.type==="boolean"){let J=z.type==="boolean"?[{id:"true",label:"Yes",value:!0},{id:"false",label:"No",value:!1}]:(z.options??[]).map((W,Q)=>({id:`option:${Q}`,label:W.label,value:W.value})),Y=await this.requestElicitationChoice(z.title,[z.description,z.required?"Required":"Optional"].filter(Boolean).join(`
21
22
  `),[...J.map((W)=>({id:W.id,label:W.label})),...!z.required?[{id:"skip",label:"Skip"}]:[]],Z);if(Y==="skip")return{cancelled:!1};let H=J.find((W)=>W.id===Y);if(!H)return{cancelled:!0,reason:"User cancelled MCP elicitation"};return{cancelled:!1,value:H.value}}if(z.defaultValue!==void 0){let J=await this.requestElicitationChoice(z.title,[z.description,`ACP cannot collect ${z.type} input. Use the server default: ${String(z.defaultValue)}?`].filter(Boolean).join(`
22
- `),[{id:"default",label:"Use default"},...!z.required?[{id:"skip",label:"Skip"}]:[]],Z);if(J==="default")return{cancelled:!1,value:z.defaultValue};if(J==="skip")return{cancelled:!1};return{cancelled:!0,reason:"User cancelled MCP elicitation"}}if(!z.required)return{cancelled:!1};return{cancelled:!0,reason:`ACP cannot collect required ${z.type} field "${z.name}"`}}async requestElicitationChoice(z,Z,J,Y){let H=await this.waitForClientInteraction(this.connection.requestPermission({sessionId:this.id,options:[...J.map((W)=>({optionId:W.id,name:W.label,kind:"allow_once"})),{optionId:"cancel",name:"Cancel",kind:"reject_once"}],toolCall:{toolCallId:h(),status:"pending",title:z,kind:"think",content:[{type:"content",content:{type:"text",text:Z}}]}}),Y);return H?.outcome.outcome==="selected"?H.outcome.optionId:void 0}async waitForClientInteraction(z,Z){if(!Z)return z;if(Z.aborted)return;return new Promise((J,Y)=>{let H=!1,W=(j)=>{if(H)return;H=!0,Z.removeEventListener("abort",Q),j()},Q=()=>W(()=>J(void 0));if(Z.addEventListener("abort",Q,{once:!0}),Z.aborted)Q();z.then((j)=>W(()=>J(j)),(j)=>W(()=>Y(j)))})}mapToolKind(z){return{readonly:"read",write:"edit",execute:"execute",read:"read",edit:"edit",delete:"delete",move:"move",search:"search",think:"think",fetch:"fetch"}[z||""]||"other"}}var _=T("Agent");class f{connection;sessions=new Map;sessionLoadQueues=new Map;runtimeResidencyValue;clientCapabilities;destroyed=!1;destroyPromise;constructor(z){this.connection=z}get runtimeResidency(){if(!this.runtimeResidencyValue){let z=qz();this.runtimeResidencyValue=new hz({maxResident:z?.maxResidentSessionRuntimes??Rz,idleMs:z?.sessionRuntimeIdleMs??Pz})}return this.runtimeResidencyValue}async reserveSessionRuntime(z){try{return await this.runtimeResidency.reserve(z,{surface:"acp",allowEviction:!1})}catch(Z){if(Z instanceof yz)throw mz.internalError({resource:Z.resource,limit:Z.limit,retryable:Z.retryable},Z.message);throw Z}}async initialize(z){return _.info("[BladeAgent] Initializing ACP connection"),_.debug(`[BladeAgent] Client capabilities: ${JSON.stringify(z.clientCapabilities)}`),this.clientCapabilities=z.clientCapabilities,await Nz(),{protocolVersion:pz,agentCapabilities:{loadSession:!0,sessionCapabilities:{list:{},fork:{},close:{}},promptCapabilities:{image:!0,audio:!1,embeddedContext:!0},mcpCapabilities:{http:!0,sse:!0}}}}async authenticate(z){return}async newSession(z){this.assertNotDestroyed();let Z=C("acp"),J=await this.reserveSessionRuntime(Z),Y=z.cwd||_z(),H=z._meta?.["blade/taskIsolation"],W=H==="local"||H==="worktree"?H:void 0,Q=z._meta?.["blade/taskPrompt"],j;try{let X=W?await Tz.createSessionTask({sessionId:Z,prompt:typeof Q==="string"&&Q.trim()?Q:"ACP task session",sourceProjectPath:Y,isolation:W}):void 0,D=X?.metadata.projectPath??Y;return _.info(`[BladeAgent] Creating new session: ${Z}`),_.debug(`[BladeAgent] Session cwd: ${D}`),j=new E(Z,D,this.connection,this.clientCapabilities,{mcpServers:z.mcpServers,...X?.taskWorktree?{taskWorktree:X.taskWorktree}:{},...X?.metadata.taskIsolation?{taskIsolation:X.metadata.taskIsolation}:{}}),await j.initialize(),this.assertNotDestroyed(),this.commitSession(Z,j,J),_.info(`[BladeAgent] Session ${Z} created, scheduling available commands update`),j.sendAvailableCommandsDelayed(),this.buildChildSessionResponse(Z,X?.metadata,j.getModelConfiguration())}catch(X){throw J.cancel(),await j?.destroy().catch(()=>{return}),X}}async listSessions(z){if(z.cwd!=null&&!Kz.isAbsolute(z.cwd))throw Error("ACP session list cwd must be absolute");let Z=await F.listSessionPage({cwd:z.cwd??void 0,cursor:z.cursor??void 0,limit:50,includeSubagents:!1});return{sessions:Z.sessions.map((J)=>({sessionId:J.sessionId,cwd:J.projectPath,title:J.title??null,updatedAt:J.lastMessageTime,_meta:{"blade/taskStatus":J.taskStatus,...J.taskStatusReason?{"blade/taskStatusReason":J.taskStatusReason}:{},...J.taskFailure?{"blade/taskFailure":J.taskFailure}:{},...J.taskStartedAt?{"blade/taskStartedAt":J.taskStartedAt}:{},...J.taskCompletedAt?{"blade/taskCompletedAt":J.taskCompletedAt}:{},...J.taskModelId?{"blade/taskModelId":J.taskModelId}:{},...J.taskRetryAvailable?{"blade/taskRetryAvailable":!0}:{},...J.taskRetriedFrom?{"blade/taskRetriedFrom":J.taskRetriedFrom}:{},...J.taskDelivery?{"blade/taskDelivery":J.taskDelivery}:{},...J.taskIsolation?{"blade/taskIsolation":J.taskIsolation}:{},...J.taskSourceProjectPath?{"blade/taskSourceProjectPath":J.taskSourceProjectPath}:{},...J.taskWorktreeBranch?{"blade/taskWorktreeBranch":J.taskWorktreeBranch}:{},...J.taskBaseCommit?{"blade/taskBaseCommit":J.taskBaseCommit}:{},...J.taskDiffStat?{"blade/taskDiffStat":J.taskDiffStat}:{},...J.taskQueuePosition?{"blade/taskQueuePosition":J.taskQueuePosition}:{},...J.taskQueueDepth!==void 0?{"blade/taskQueueDepth":J.taskQueueDepth}:{},...J.taskConcurrencyLimit!==void 0?{"blade/taskConcurrencyLimit":J.taskConcurrencyLimit}:{}}})),nextCursor:Z.nextCursor}}async unstable_forkSession(z){if(this.assertNotDestroyed(),!Kz.isAbsolute(z.cwd))throw Error("ACP session fork cwd must be absolute");let Z=C("fork"),J=await this.reserveSessionRuntime(Z),Y;try{let H=await F.forkSession(z.sessionId,{sourceProjectPath:z.cwd,targetProjectPath:z.cwd,newSessionId:Z});return this.assertNotDestroyed(),Y=new E(H.sessionId,z.cwd,this.connection,this.clientCapabilities,{initialMessages:H.messages,permissionMode:H.metadata.permissionMode,mcpServers:z.mcpServers}),await Y.initialize(),this.assertNotDestroyed(),this.commitSession(H.sessionId,Y,J),Y.sendAvailableCommandsDelayed(),this.buildChildSessionResponse(H.sessionId,H.metadata,Y.getModelConfiguration())}catch(H){throw J.cancel(),await Y?.destroy().catch(()=>{return}),H}}async loadSession(z){this.assertNotDestroyed(),_.info(`[BladeAgent] Loading session: ${z.sessionId}`);let J=(this.sessionLoadQueues.get(z.sessionId)??Promise.resolve()).then(()=>this.replaceSession(z)),Y=J.then(()=>{return},()=>{return});this.sessionLoadQueues.set(z.sessionId,Y);try{return await J}finally{if(this.sessionLoadQueues.get(z.sessionId)===Y)this.sessionLoadQueues.delete(z.sessionId)}}async replaceSession(z){this.assertNotDestroyed(),await F.assertSessionWritable(z.sessionId,z.cwd),await this.closeResidentSession(z.sessionId);let Z=await this.reserveSessionRuntime(z.sessionId),J;try{let[Y,H]=await Promise.all([F.loadSession(z.sessionId,z.cwd),F.findSessionMetadata(z.sessionId,z.cwd)]);if(!H)throw Error(`Session not found: ${z.sessionId}`);return J=new E(z.sessionId,z.cwd,this.connection,this.clientCapabilities,{initialMessages:Y,permissionMode:H.permissionMode,mcpServers:z.mcpServers}),await J.initialize(),await J.replayHistory(),this.assertNotDestroyed(),this.commitSession(z.sessionId,J,Z),J.sendAvailableCommandsDelayed(),this.buildSessionSetup(J.getModelConfiguration(),J.getMode())}catch(Y){throw Z.cancel(),await J?.destroy().catch(()=>{return}),Y}}commitSession(z,Z,J){let Y=J.commit({key:z,surface:"acp",value:Z,canEvict:()=>Z.isIdleForResidency(),dispose:async()=>{if(this.sessions.get(z)===Z)this.sessions.delete(z);await Z.destroy()}});this.sessions.set(z,Z),Y.release()}async closeResidentSession(z,Z={}){let J=this.sessions.get(z);if(!J)return;let Y=this.runtimeResidency.owns(z,J),H;try{await J.destroy(Z)}catch(Q){H=Q}let W=await this.runtimeResidency.forget(z,J);if(this.sessions.get(z)===J)this.sessions.delete(z);if(Y&&!W&&H===void 0)throw Error(`ACP Session is still active: ${z}`);if(H!==void 0)throw H}buildChildSessionResponse(z,Z,J){return{sessionId:z,...this.buildSessionSetup(J,Z?.permissionMode==="autoEdit"?"auto-edit":Z?.permissionMode),...Z?{_meta:{"blade/taskIsolation":Z.taskIsolation,"blade/taskSourceProjectPath":Z.taskSourceProjectPath,"blade/taskProjectPath":Z.projectPath,...Z.taskModelId?{"blade/taskModelId":Z.taskModelId}:{},...Z.taskRetryAvailable?{"blade/taskRetryAvailable":!0}:{},...Z.taskRetriedFrom?{"blade/taskRetriedFrom":Z.taskRetriedFrom}:{},...Z.taskDelivery?{"blade/taskDelivery":Z.taskDelivery}:{},...Z.taskWorktreeBranch?{"blade/taskWorktreeBranch":Z.taskWorktreeBranch}:{},...Z.taskBaseCommit?{"blade/taskBaseCommit":Z.taskBaseCommit}:{}}}:{}}}assertNotDestroyed(){if(this.destroyed)throw Error("BladeAgent is destroyed")}getRuntimeResidencyStats(){return this.runtimeResidency.getStats()}buildSessionSetup(z,Z="default"){let J=z?.models??[],Y=(z?.currentModelId&&J.some((Q)=>Q.id===z.currentModelId)?z.currentModelId:void 0)??J[0]?.id,H=[{id:"default",name:"Default",description:"Ask for confirmation before all file edits and commands"},{id:"auto-edit",name:"Auto Edit",description:"Auto-approve file edits, ask for shell commands"},{id:"yolo",name:"Full Auto",description:"Auto-approve everything without confirmation"},{id:"plan",name:"Plan Only",description:"Read-only mode, no file changes or commands"}],W=[];if(J.length>0)W.push({type:"select",id:"model",name:"Model",description:"Active language model",category:"model",currentValue:Y,options:J.map((Q)=>({value:Q.id,name:Q.displayName??Q.model,description:`${z?.modelProviders[Q.provider]?.name??Q.provider} · ${Q.model}`}))});if(z?.reasoning)W.push({type:"select",id:"reasoning_effort",name:"Reasoning effort",description:"Session-owned model reasoning intensity",category:"model",currentValue:z.reasoning.selection,options:[{value:"auto",name:"Auto",description:`Resolve near high for this model (currently ${z.reasoning.effective})`},...z.reasoning.supported.map((Q)=>({value:Q,name:Q[0].toUpperCase()+Q.slice(1),description:Q==="off"?"Disable model reasoning":`Use ${Q} reasoning effort`}))]});if(z?.serviceTier)W.push({type:"select",id:"service_tier",name:"Service tier",description:"Session-owned provider latency and pricing tier",category:"model",currentValue:z.serviceTier.selection,options:[{value:"auto",name:"Auto",description:"Use the provider or model default tier"},...z.serviceTier.supported.map((Q)=>({value:Q,name:Q[0].toUpperCase()+Q.slice(1),description:Q==="fast"?"Use the provider priority tier":Q==="flex"?"Use the lower-cost flexible tier":"Use the standard provider tier"}))]});if(z?.responseVerbosity)W.push({type:"select",id:"response_verbosity",name:"Response verbosity",description:"Session-owned model response detail",category:"model",currentValue:z.responseVerbosity.selection,options:[{value:"auto",name:"Auto",description:"Use the provider or model default verbosity"},...z.responseVerbosity.supported.map((Q)=>({value:Q,name:Q[0].toUpperCase()+Q.slice(1),description:`Use ${Q} response verbosity`}))]});if(z?.communicationStyle)W.push({type:"select",id:"communication_style",name:"Communication style",description:"Session-owned tone and explanatory framing",category:"model",currentValue:z.communicationStyle.selection,options:z.communicationStyle.supported.map((Q)=>({value:Q.id,name:Q.name,description:`${Q.description} · ${Q.source}`}))});return{modes:{availableModes:H,currentModeId:Z},configOptions:W.length>0?W:void 0}}async closeSession(z){this.assertNotDestroyed();let J=(this.sessionLoadQueues.get(z.sessionId)??Promise.resolve()).then(()=>this.closeResidentSession(z.sessionId,{discardPendingInput:!0})),Y=J.then(()=>{return},()=>{return});this.sessionLoadQueues.set(z.sessionId,Y);try{await J}finally{if(this.sessionLoadQueues.get(z.sessionId)===Y)this.sessionLoadQueues.delete(z.sessionId)}}async prompt(z){let Z=this.runtimeResidency.acquire(z.sessionId);if(!Z)throw Error(`Session not found: ${z.sessionId}`);try{return await Z.value.prompt(z)}finally{Z.release()}}async cancel(z){_.info(`[BladeAgent] Cancel notification received for session: ${z.sessionId}`);let Z=this.runtimeResidency.acquire(z.sessionId);if(Z){_.info("[BladeAgent] Found session, calling session.cancel()");try{Z.value.cancel()}finally{Z.release()}}else _.warn(`[BladeAgent] Session not found for cancel: ${z.sessionId}`)}async setSessionMode(z){_.info(`[BladeAgent] Setting session mode: ${z.modeId}`);let Z=this.runtimeResidency.acquire(z.sessionId);if(Z)try{await Z.value.setMode(z.modeId)}finally{Z.release()}return{}}async setSessionConfigOption(z){let Z=this.runtimeResidency.acquire(z.sessionId);if(!Z)throw Error(`Session not found: ${z.sessionId}`);try{let J=Z.value;if(z.configId==="model"&&"value"in z&&typeof z.value==="string")_.info(`[BladeAgent] Setting session model: ${z.value}`),await J.setModel(z.value);else if(z.configId==="reasoning_effort"&&"value"in z&&Ez(z.value))_.info(`[BladeAgent] Setting reasoning effort: ${z.value}`),await J.setReasoningEffort(z.value);else if(z.configId==="service_tier"&&"value"in z&&Az(z.value))_.info(`[BladeAgent] Setting service tier: ${z.value}`),await J.setServiceTier(z.value);else if(z.configId==="response_verbosity"&&"value"in z&&Oz(z.value))_.info(`[BladeAgent] Setting response verbosity: ${z.value}`),await J.setResponseVerbosity(z.value);else if(z.configId==="communication_style"&&"value"in z&&xz(z.value))_.info(`[BladeAgent] Setting communication style: ${z.value}`),await J.setCommunicationStyle(z.value);else throw Error(`Invalid session config option: ${z.configId}`);return{configOptions:this.buildSessionSetup(J.getModelConfiguration(),J.getMode()).configOptions??[]}}finally{Z.release()}}destroy(){if(this.destroyPromise)return this.destroyPromise;return this.destroyPromise=this.destroyOwnedResources(),this.destroyPromise}async destroyOwnedResources(){this.destroyed=!0,await Promise.all([...this.sessionLoadQueues.values()]),this.sessionLoadQueues.clear();let z;for(let Z of[...this.sessions.keys()])try{await this.closeResidentSession(Z)}catch(J){z??=J}try{await this.runtimeResidency.disposeAll()}catch(Z){z??=Z}this.sessions.clear();try{await bz.getInstance().disconnectAll()}catch(Z){z??=Z}if(z!==void 0)throw z}}async function gJ(){let z=vz.toWeb(process.stdout),Z=dz.toWeb(process.stdin),J=y.ndJsonStream(z,Z),Y,H=new y.AgentSideConnection((Q)=>{return Y=new f(Q),Y},J),W=Sz(async()=>{await Y?.destroy()});try{await H.closed}finally{W(),await Y?.destroy()}}export{gJ as runAcpIntegration};
23
+ `),[{id:"default",label:"Use default"},...!z.required?[{id:"skip",label:"Skip"}]:[]],Z);if(J==="default")return{cancelled:!1,value:z.defaultValue};if(J==="skip")return{cancelled:!1};return{cancelled:!0,reason:"User cancelled MCP elicitation"}}if(!z.required)return{cancelled:!1};return{cancelled:!0,reason:`ACP cannot collect required ${z.type} field "${z.name}"`}}async requestElicitationChoice(z,Z,J,Y){let H=await this.waitForClientInteraction(this.connection.requestPermission({sessionId:this.id,options:[...J.map((W)=>({optionId:W.id,name:W.label,kind:"allow_once"})),{optionId:"cancel",name:"Cancel",kind:"reject_once"}],toolCall:{toolCallId:h(),status:"pending",title:z,kind:"think",content:[{type:"content",content:{type:"text",text:Z}}]}}),Y);return H?.outcome.outcome==="selected"?H.outcome.optionId:void 0}async waitForClientInteraction(z,Z){if(!Z)return z;if(Z.aborted)return;return new Promise((J,Y)=>{let H=!1,W=(j)=>{if(H)return;H=!0,Z.removeEventListener("abort",Q),j()},Q=()=>W(()=>J(void 0));if(Z.addEventListener("abort",Q,{once:!0}),Z.aborted)Q();z.then((j)=>W(()=>J(j)),(j)=>W(()=>Y(j)))})}mapToolKind(z){return{readonly:"read",write:"edit",execute:"execute",read:"read",edit:"edit",delete:"delete",move:"move",search:"search",think:"think",fetch:"fetch"}[z||""]||"other"}}var _=T("Agent");class u{connection;sessions=new Map;sessionLoadQueues=new Map;runtimeResidencyValue;clientCapabilities;destroyed=!1;destroyPromise;constructor(z){this.connection=z}get runtimeResidency(){if(!this.runtimeResidencyValue){let z=Nz();this.runtimeResidencyValue=new Sz({maxResident:z?.maxResidentSessionRuntimes??qz,idleMs:z?.sessionRuntimeIdleMs??Pz})}return this.runtimeResidencyValue}async reserveSessionRuntime(z){try{return await this.runtimeResidency.reserve(z,{surface:"acp",allowEviction:!1})}catch(Z){if(Z instanceof hz)throw dz.internalError({resource:Z.resource,limit:Z.limit,retryable:Z.retryable},Z.message);throw Z}}async initialize(z){return _.info("[BladeAgent] Initializing ACP connection"),_.debug(`[BladeAgent] Client capabilities: ${JSON.stringify(z.clientCapabilities)}`),this.clientCapabilities=z.clientCapabilities,await Ez(),{protocolVersion:mz,agentCapabilities:{loadSession:!0,sessionCapabilities:{list:{},fork:{},close:{}},promptCapabilities:{image:!0,audio:!1,embeddedContext:!0},mcpCapabilities:{http:!0,sse:!0}}}}async authenticate(z){return}async newSession(z){this.assertNotDestroyed();let Z=f("acp"),J=await this.reserveSessionRuntime(Z),Y=z.cwd||Oz(),H=z._meta?.["blade/taskIsolation"],W=H==="local"||H==="worktree"?H:void 0,Q=z._meta?.["blade/taskPrompt"],j;try{let D=W?await yz.createSessionTask({sessionId:Z,prompt:typeof Q==="string"&&Q.trim()?Q:"ACP task session",sourceProjectPath:Y,isolation:W}):void 0,X=D?.metadata.projectPath??Y;return _.info(`[BladeAgent] Creating new session: ${Z}`),_.debug(`[BladeAgent] Session cwd: ${X}`),j=new E(Z,X,this.connection,this.clientCapabilities,{mcpServers:z.mcpServers,...D?.taskWorktree?{taskWorktree:D.taskWorktree}:{},...D?.metadata.taskIsolation?{taskIsolation:D.metadata.taskIsolation}:{}}),await j.initialize(),this.assertNotDestroyed(),this.commitSession(Z,j,J),_.info(`[BladeAgent] Session ${Z} created, scheduling available commands update`),j.sendAvailableCommandsDelayed(),this.buildChildSessionResponse(Z,D?.metadata,j.getModelConfiguration())}catch(D){throw J.cancel(),await j?.destroy().catch(()=>{return}),D}}async listSessions(z){if(z.cwd!=null&&!_z.isAbsolute(z.cwd))throw Error("ACP session list cwd must be absolute");let Z=await U.listSessionPage({cwd:z.cwd??void 0,cursor:z.cursor??void 0,limit:50,includeSubagents:!1});return{sessions:Z.sessions.map((J)=>({sessionId:J.sessionId,cwd:J.projectPath,title:J.title??null,updatedAt:J.lastMessageTime,_meta:{"blade/taskStatus":J.taskStatus,...J.taskStatusReason?{"blade/taskStatusReason":J.taskStatusReason}:{},...J.taskFailure?{"blade/taskFailure":J.taskFailure}:{},...J.taskStartedAt?{"blade/taskStartedAt":J.taskStartedAt}:{},...J.taskCompletedAt?{"blade/taskCompletedAt":J.taskCompletedAt}:{},...J.taskModelId?{"blade/taskModelId":J.taskModelId}:{},...J.taskRetryAvailable?{"blade/taskRetryAvailable":!0}:{},...J.taskRetriedFrom?{"blade/taskRetriedFrom":J.taskRetriedFrom}:{},...J.taskDelivery?{"blade/taskDelivery":J.taskDelivery}:{},...J.taskIsolation?{"blade/taskIsolation":J.taskIsolation}:{},...J.taskSourceProjectPath?{"blade/taskSourceProjectPath":J.taskSourceProjectPath}:{},...J.taskWorktreeBranch?{"blade/taskWorktreeBranch":J.taskWorktreeBranch}:{},...J.taskBaseCommit?{"blade/taskBaseCommit":J.taskBaseCommit}:{},...J.taskDiffStat?{"blade/taskDiffStat":J.taskDiffStat}:{},...J.taskQueuePosition?{"blade/taskQueuePosition":J.taskQueuePosition}:{},...J.taskQueueDepth!==void 0?{"blade/taskQueueDepth":J.taskQueueDepth}:{},...J.taskConcurrencyLimit!==void 0?{"blade/taskConcurrencyLimit":J.taskConcurrencyLimit}:{}}})),nextCursor:Z.nextCursor}}async unstable_forkSession(z){if(this.assertNotDestroyed(),!_z.isAbsolute(z.cwd))throw Error("ACP session fork cwd must be absolute");let Z=f("fork"),J=await this.reserveSessionRuntime(Z),Y;try{let H=await U.forkSession(z.sessionId,{sourceProjectPath:z.cwd,targetProjectPath:z.cwd,newSessionId:Z});return this.assertNotDestroyed(),Y=new E(H.sessionId,z.cwd,this.connection,this.clientCapabilities,{initialMessages:H.messages,permissionMode:H.metadata.permissionMode,mcpServers:z.mcpServers}),await Y.initialize(),this.assertNotDestroyed(),this.commitSession(H.sessionId,Y,J),Y.sendAvailableCommandsDelayed(),this.buildChildSessionResponse(H.sessionId,H.metadata,Y.getModelConfiguration())}catch(H){throw J.cancel(),await Y?.destroy().catch(()=>{return}),H}}async loadSession(z){this.assertNotDestroyed(),_.info(`[BladeAgent] Loading session: ${z.sessionId}`);let J=(this.sessionLoadQueues.get(z.sessionId)??Promise.resolve()).then(()=>this.replaceSession(z)),Y=J.then(()=>{return},()=>{return});this.sessionLoadQueues.set(z.sessionId,Y);try{return await J}finally{if(this.sessionLoadQueues.get(z.sessionId)===Y)this.sessionLoadQueues.delete(z.sessionId)}}async replaceSession(z){this.assertNotDestroyed(),await U.assertSessionWritable(z.sessionId,z.cwd),await this.closeResidentSession(z.sessionId);let Z=await this.reserveSessionRuntime(z.sessionId),J;try{let[Y,H]=await Promise.all([U.loadSession(z.sessionId,z.cwd),U.findSessionMetadata(z.sessionId,z.cwd)]);if(!H)throw Error(`Session not found: ${z.sessionId}`);return J=new E(z.sessionId,z.cwd,this.connection,this.clientCapabilities,{initialMessages:Y,permissionMode:H.permissionMode,mcpServers:z.mcpServers}),await J.initialize(),await J.replayHistory(),this.assertNotDestroyed(),this.commitSession(z.sessionId,J,Z),J.sendAvailableCommandsDelayed(),this.buildSessionSetup(J.getModelConfiguration(),J.getMode())}catch(Y){throw Z.cancel(),await J?.destroy().catch(()=>{return}),Y}}commitSession(z,Z,J){let Y=J.commit({key:z,surface:"acp",value:Z,canEvict:()=>Z.isIdleForResidency(),dispose:async()=>{if(this.sessions.get(z)===Z)this.sessions.delete(z);await Z.destroy()}});this.sessions.set(z,Z),Y.release()}async closeResidentSession(z,Z={}){let J=this.sessions.get(z);if(!J)return;let Y=this.runtimeResidency.owns(z,J),H;try{await J.destroy(Z)}catch(Q){H=Q}let W=await this.runtimeResidency.forget(z,J);if(this.sessions.get(z)===J)this.sessions.delete(z);if(Y&&!W&&H===void 0)throw Error(`ACP Session is still active: ${z}`);if(H!==void 0)throw H}buildChildSessionResponse(z,Z,J){return{sessionId:z,...this.buildSessionSetup(J,Z?.permissionMode==="autoEdit"?"auto-edit":Z?.permissionMode),...Z?{_meta:{"blade/taskIsolation":Z.taskIsolation,"blade/taskSourceProjectPath":Z.taskSourceProjectPath,"blade/taskProjectPath":Z.projectPath,...Z.taskModelId?{"blade/taskModelId":Z.taskModelId}:{},...Z.taskRetryAvailable?{"blade/taskRetryAvailable":!0}:{},...Z.taskRetriedFrom?{"blade/taskRetriedFrom":Z.taskRetriedFrom}:{},...Z.taskDelivery?{"blade/taskDelivery":Z.taskDelivery}:{},...Z.taskWorktreeBranch?{"blade/taskWorktreeBranch":Z.taskWorktreeBranch}:{},...Z.taskBaseCommit?{"blade/taskBaseCommit":Z.taskBaseCommit}:{}}}:{}}}assertNotDestroyed(){if(this.destroyed)throw Error("BladeAgent is destroyed")}getRuntimeResidencyStats(){return this.runtimeResidency.getStats()}buildSessionSetup(z,Z="default"){let J=z?.models??[],Y=(z?.currentModelId&&J.some((Q)=>Q.id===z.currentModelId)?z.currentModelId:void 0)??J[0]?.id,H=[{id:"default",name:"Default",description:"Ask for confirmation before all file edits and commands"},{id:"auto-edit",name:"Auto Edit",description:"Auto-approve file edits, ask for shell commands"},{id:"yolo",name:"Full Auto",description:"Auto-approve everything without confirmation"},{id:"plan",name:"Plan Only",description:"Read-only mode, no file changes or commands"}],W=[];if(J.length>0)W.push({type:"select",id:"model",name:"Model",description:"Active language model",category:"model",currentValue:Y,options:J.map((Q)=>({value:Q.id,name:Q.displayName??Q.model,description:`${z?.modelProviders[Q.provider]?.name??Q.provider} · ${Q.model}`}))});if(z?.reasoning)W.push({type:"select",id:"reasoning_effort",name:"Reasoning effort",description:"Session-owned model reasoning intensity",category:"model",currentValue:z.reasoning.selection,options:[{value:"auto",name:"Auto",description:`Resolve near high for this model (currently ${z.reasoning.effective})`},...z.reasoning.supported.map((Q)=>({value:Q,name:Q[0].toUpperCase()+Q.slice(1),description:Q==="off"?"Disable model reasoning":`Use ${Q} reasoning effort`}))]});if(z?.serviceTier)W.push({type:"select",id:"service_tier",name:"Service tier",description:"Session-owned provider latency and pricing tier",category:"model",currentValue:z.serviceTier.selection,options:[{value:"auto",name:"Auto",description:"Use the provider or model default tier"},...z.serviceTier.supported.map((Q)=>({value:Q,name:Q[0].toUpperCase()+Q.slice(1),description:Q==="fast"?"Use the provider priority tier":Q==="flex"?"Use the lower-cost flexible tier":"Use the standard provider tier"}))]});if(z?.responseVerbosity)W.push({type:"select",id:"response_verbosity",name:"Response verbosity",description:"Session-owned model response detail",category:"model",currentValue:z.responseVerbosity.selection,options:[{value:"auto",name:"Auto",description:"Use the provider or model default verbosity"},...z.responseVerbosity.supported.map((Q)=>({value:Q,name:Q[0].toUpperCase()+Q.slice(1),description:`Use ${Q} response verbosity`}))]});if(z?.communicationStyle)W.push({type:"select",id:"communication_style",name:"Communication style",description:"Session-owned tone and explanatory framing",category:"model",currentValue:z.communicationStyle.selection,options:z.communicationStyle.supported.map((Q)=>({value:Q.id,name:Q.name,description:`${Q.description} · ${Q.source}`}))});return{modes:{availableModes:H,currentModeId:Z},configOptions:W.length>0?W:void 0}}async closeSession(z){this.assertNotDestroyed();let J=(this.sessionLoadQueues.get(z.sessionId)??Promise.resolve()).then(()=>this.closeResidentSession(z.sessionId,{discardPendingInput:!0})),Y=J.then(()=>{return},()=>{return});this.sessionLoadQueues.set(z.sessionId,Y);try{await J}finally{if(this.sessionLoadQueues.get(z.sessionId)===Y)this.sessionLoadQueues.delete(z.sessionId)}}async prompt(z){let Z=this.runtimeResidency.acquire(z.sessionId);if(!Z)throw Error(`Session not found: ${z.sessionId}`);try{return await Z.value.prompt(z)}finally{Z.release()}}async cancel(z){_.info(`[BladeAgent] Cancel notification received for session: ${z.sessionId}`);let Z=this.runtimeResidency.acquire(z.sessionId);if(Z){_.info("[BladeAgent] Found session, calling session.cancel()");try{Z.value.cancel()}finally{Z.release()}}else _.warn(`[BladeAgent] Session not found for cancel: ${z.sessionId}`)}async setSessionMode(z){_.info(`[BladeAgent] Setting session mode: ${z.modeId}`);let Z=this.runtimeResidency.acquire(z.sessionId);if(Z)try{await Z.value.setMode(z.modeId)}finally{Z.release()}return{}}async setSessionConfigOption(z){let Z=this.runtimeResidency.acquire(z.sessionId);if(!Z)throw Error(`Session not found: ${z.sessionId}`);try{let J=Z.value;if(z.configId==="model"&&"value"in z&&typeof z.value==="string")_.info(`[BladeAgent] Setting session model: ${z.value}`),await J.setModel(z.value);else if(z.configId==="reasoning_effort"&&"value"in z&&xz(z.value))_.info(`[BladeAgent] Setting reasoning effort: ${z.value}`),await J.setReasoningEffort(z.value);else if(z.configId==="service_tier"&&"value"in z&&Rz(z.value))_.info(`[BladeAgent] Setting service tier: ${z.value}`),await J.setServiceTier(z.value);else if(z.configId==="response_verbosity"&&"value"in z&&Az(z.value))_.info(`[BladeAgent] Setting response verbosity: ${z.value}`),await J.setResponseVerbosity(z.value);else if(z.configId==="communication_style"&&"value"in z&&bz(z.value))_.info(`[BladeAgent] Setting communication style: ${z.value}`),await J.setCommunicationStyle(z.value);else throw Error(`Invalid session config option: ${z.configId}`);return{configOptions:this.buildSessionSetup(J.getModelConfiguration(),J.getMode()).configOptions??[]}}finally{Z.release()}}destroy(){if(this.destroyPromise)return this.destroyPromise;return this.destroyPromise=this.destroyOwnedResources(),this.destroyPromise}async destroyOwnedResources(){this.destroyed=!0,await Promise.all([...this.sessionLoadQueues.values()]),this.sessionLoadQueues.clear();let z;for(let Z of[...this.sessions.keys()])try{await this.closeResidentSession(Z)}catch(J){z??=J}try{await this.runtimeResidency.disposeAll()}catch(Z){z??=Z}this.sessions.clear();try{await Tz.getInstance().disconnectAll()}catch(Z){z??=Z}if(z!==void 0)throw z}}async function cJ(){let z=lz.toWeb(process.stdout),Z=vz.toWeb(process.stdin),J=y.ndJsonStream(z,Z),Y,H=new y.AgentSideConnection((Q)=>{return Y=new u(Q),Y},J),W=Mz(async()=>{await Y?.destroy()});try{await H.closed}finally{W(),await Y?.destroy()}}export{cJ as runAcpIntegration};
@@ -1,2 +1,2 @@
1
1
  import{promises as B}from"node:fs";import q from"node:path";import{LRUCache as H}from"lru-cache";var K=512,Z=new H({max:K});async function L(x){let b=x;while(!0){try{return await B.lstat(q.join(b,".git")),b}catch(V){if(V.code!=="ENOENT")return}let F=q.dirname(b);if(F===b)return;b=F}}async function M(x){let b=q.join(x,".git"),F=await B.lstat(b);if(F.isDirectory())return x;if(!F.isFile())return;let V=await B.readFile(b,"utf8"),J=/^gitdir:\s*(.+)\s*$/im.exec(V);if(!J)return;let Q=await B.realpath(q.isAbsolute(J[1])?J[1]:q.resolve(x,J[1])),Y=Q;try{let z=(await B.readFile(q.join(Q,"commondir"),"utf8")).trim();if(z)Y=await B.realpath(q.resolve(Q,z))}catch(z){if(z.code!=="ENOENT")throw z}return q.basename(Y)===".git"?B.realpath(q.dirname(Y)):void 0}async function N(x){if(!q.isAbsolute(x))throw Error("Workspace path must be absolute");let b=await B.realpath(x),F=Z.get(b);if(F)return F;let V=b;try{let Q=await L(b);if(Q){let Y=await M(Q),z=q.relative(Q,b);if(Y&&(z===""||!z.startsWith(`..${q.sep}`)&&z!==".."&&!q.isAbsolute(z))){let $=q.resolve(Y,z);V=await B.realpath($).catch(()=>$)}}}catch{}let J={projectPath:b,trustRoot:V};return Z.set(b,J),J}async function S(x){if(!q.isAbsolute(x))throw Error("Workspace path must be absolute");let b=await B.realpath(x);Z.delete(b)}
2
- export{N as Kh,S as Lh};
2
+ export{N as Ph,S as Qh};