blade-code 0.10.36 → 0.10.37

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 (84) hide show
  1. package/dist/blade.js +2 -2
  2. package/dist/{chunk-qvdcesry.js → chunk-0dw58ycv.js} +2 -2
  3. package/dist/{chunk-ekzck3x7.js → chunk-0e4nc00e.js} +1 -1
  4. package/dist/{chunk-7c5tnz4y.js → chunk-0nvc6y56.js} +1 -1
  5. package/dist/chunk-15w4crsc.js +1 -0
  6. package/dist/{chunk-95n8g52h.js → chunk-232bcv23.js} +1 -1
  7. package/dist/{chunk-acw8q8w9.js → chunk-46r1m8yn.js} +1 -1
  8. package/dist/chunk-4mpx8rad.js +1 -0
  9. package/dist/{chunk-e23sz81n.js → chunk-5cjy9yj1.js} +1 -1
  10. package/dist/chunk-5ckfx738.js +1 -0
  11. package/dist/{chunk-1raz6s2b.js → chunk-61h0d0gq.js} +2 -2
  12. package/dist/chunk-73pqjvxk.js +1 -0
  13. package/dist/chunk-8bczq0xe.js +1 -0
  14. package/dist/{chunk-s4enbe93.js → chunk-8pcfmzq0.js} +36 -36
  15. package/dist/{chunk-y990fa4r.js → chunk-9hjhbsna.js} +41 -41
  16. package/dist/{chunk-6jpspf3v.js → chunk-ahkpjvaq.js} +1 -1
  17. package/dist/{chunk-qxvk42rf.js → chunk-ak37gg0n.js} +1 -1
  18. package/dist/{chunk-g510tpqt.js → chunk-asqah231.js} +1 -1
  19. package/dist/{chunk-phgqzja3.js → chunk-atdb1pks.js} +1 -1
  20. package/dist/{chunk-gy8esxaa.js → chunk-b6ve4vyt.js} +2 -2
  21. package/dist/{chunk-2mvp3rqw.js → chunk-cm4t4cz6.js} +2 -2
  22. package/dist/{chunk-6gcmfvfj.js → chunk-d63dczf8.js} +1 -1
  23. package/dist/{chunk-q15qd9x4.js → chunk-dgks1che.js} +1 -1
  24. package/dist/chunk-e6frdh2s.js +1 -0
  25. package/dist/{chunk-4bbnytq5.js → chunk-e6ttz45s.js} +1 -1
  26. package/dist/{chunk-n4555gej.js → chunk-e8wpd0s4.js} +1 -1
  27. package/dist/{chunk-xrhtwcd0.js → chunk-fj6frvhd.js} +1 -1
  28. package/dist/chunk-fjpqxdct.js +1 -0
  29. package/dist/{chunk-m2w03hpc.js → chunk-fqcf0n0h.js} +1 -1
  30. package/dist/{chunk-0m4s8r87.js → chunk-g5429yjs.js} +3 -3
  31. package/dist/{chunk-95k17p11.js → chunk-gh0vdddb.js} +1 -1
  32. package/dist/chunk-jd764yqg.js +5 -0
  33. package/dist/{chunk-8ft7j7aw.js → chunk-jsd6d2f5.js} +1 -1
  34. package/dist/{chunk-4s0c6tkd.js → chunk-jtjcg93t.js} +1 -1
  35. package/dist/chunk-jtv91ez8.js +2 -0
  36. package/dist/{chunk-cnctwxqn.js → chunk-jz6esh56.js} +1 -1
  37. package/dist/{chunk-250vpvr5.js → chunk-kw543czm.js} +1 -1
  38. package/dist/{chunk-0dj2qm8a.js → chunk-m0a2zdm8.js} +1 -1
  39. package/dist/chunk-m377j9bs.js +1 -0
  40. package/dist/chunk-mznx9gg6.js +1 -0
  41. package/dist/{chunk-09qkatb5.js → chunk-njb4rjhs.js} +1 -1
  42. package/dist/{chunk-qwrdss51.js → chunk-q0mwwhpw.js} +3 -3
  43. package/dist/{chunk-hq1wrf1g.js → chunk-qavfq2vp.js} +1 -1
  44. package/dist/{chunk-y9nq48st.js → chunk-qc5qwgpt.js} +2 -2
  45. package/dist/chunk-qzn3rb8r.js +1 -0
  46. package/dist/{chunk-cc7dmst6.js → chunk-r48jmc74.js} +2 -2
  47. package/dist/{chunk-rshbnfr8.js → chunk-r9pz4z1p.js} +3 -3
  48. package/dist/{chunk-5xc50n8e.js → chunk-rj1z55m8.js} +1 -1
  49. package/dist/{chunk-9g6rzbcv.js → chunk-rtzd076h.js} +1 -1
  50. package/dist/chunk-s3xfr72w.js +6 -0
  51. package/dist/{chunk-m6dh31kb.js → chunk-tczrjn95.js} +2 -2
  52. package/dist/{chunk-99ywfge1.js → chunk-v2wka1pq.js} +1 -1
  53. package/dist/chunk-vk3e2w5h.js +44 -0
  54. package/dist/chunk-vxxhd72z.js +1 -0
  55. package/dist/{chunk-ck5tvxkj.js → chunk-x4yfhp8j.js} +1 -1
  56. package/dist/chunk-xfrdwxde.js +1 -0
  57. package/dist/chunk-xsew6530.js +6 -0
  58. package/dist/{chunk-1t8ebwsp.js → chunk-y5jxkynb.js} +1 -1
  59. package/dist/web/assets/{ChatView-Dx9j7CGg.js → ChatView-BB4nYdEf.js} +12 -12
  60. package/dist/web/assets/{CodeBlockHighlighter-CZADKR6S.js → CodeBlockHighlighter-CAFugWXU.js} +1 -1
  61. package/dist/web/assets/{FilePreview-BOIDa_oJ.js → FilePreview-O5aDfFS4.js} +1 -1
  62. package/dist/web/assets/{MarkdownRenderer-DXsfHVUX.js → MarkdownRenderer-C_qekwq_.js} +3 -3
  63. package/dist/web/assets/{SettingsModal-lQveNhC6.js → SettingsModal-FADlD0Da.js} +1 -1
  64. package/dist/web/assets/{TaskSwitcher-BSrmpJ2u.js → TaskSwitcher-D3k3tRpI.js} +1 -1
  65. package/dist/web/assets/{TerminalPanel-BFre9Shc.js → TerminalPanel-DBmKVVbI.js} +1 -1
  66. package/dist/web/assets/{index-DGZjm9wT.js → index-CMIW4J1Q.js} +3 -3
  67. package/dist/web/index.html +1 -1
  68. package/package.json +1 -1
  69. package/dist/chunk-3pxn6gcj.js +0 -1
  70. package/dist/chunk-4f1g8f6q.js +0 -1
  71. package/dist/chunk-4vq34v09.js +0 -5
  72. package/dist/chunk-515mkr66.js +0 -44
  73. package/dist/chunk-5c5qh3ab.js +0 -1
  74. package/dist/chunk-5vkxcjn1.js +0 -1
  75. package/dist/chunk-738a282r.js +0 -1
  76. package/dist/chunk-8m87dnk2.js +0 -1
  77. package/dist/chunk-e5yage6p.js +0 -1
  78. package/dist/chunk-hh158y4e.js +0 -6
  79. package/dist/chunk-j2tmdkmw.js +0 -1
  80. package/dist/chunk-psgt2pq7.js +0 -6
  81. package/dist/chunk-q3r0zfec.js +0 -1
  82. package/dist/chunk-rv6kca90.js +0 -1
  83. package/dist/chunk-ve7kp9rr.js +0 -1
  84. package/dist/chunk-xf2kjb9a.js +0 -1
@@ -0,0 +1,5 @@
1
+ import{Rf as ye,Sf as Re,Tf as K,Uf as ke}from"./chunk-jtv91ez8.js";import{Yf as C}from"./chunk-0dw58ycv.js";import{ag as ue,cg as X}from"./chunk-cm4t4cz6.js";import{fg as he}from"./chunk-asqah231.js";var Se={openrouter:{"HTTP-Referer":"https://github.com/echoVic/blade-code","X-Title":"Blade"},cerebras:{"X-Cerebras-3rd-Party-Integration":"blade"}},ne=(e)=>Se[e]||{};var De=new Set(["user-cancel","interrupt","sibling-error","timeout"]);function Y(e){return typeof e==="string"&&De.has(e)}function dt(e){if(!e.aborted)return;if(Y(e.reason))return e.reason;return"user-cancel"}function lt(e){if(Y(e))return!0;if(!(e instanceof Error))return!1;if(e.name==="AbortError")return!0;if(e instanceof DOMException&&e.name==="AbortError")return!0;if(e.message.includes("aborted"))return!0;return!1}function oe(...e){let t=e.filter(Boolean);if(t.length===0)return new AbortController().signal;if(t.length===1)return t[0];let n=AbortSignal;if(typeof n.any==="function")return n.any(t);for(let i of t)if(i.aborted)return i;let r=new AbortController,o=new Map;for(let i of t){let u=()=>{r.abort(i.reason);for(let[c,a]of o)c.removeEventListener("abort",a)};o.set(i,u)}for(let[i,u]of o)i.addEventListener("abort",u,{once:!0});return r.signal}function B(e,t,n){let r=n?.throwOnAbort??!1;if(t?.aborted){if(r)return Promise.reject(new DOMException("Aborted","AbortError"));return Promise.resolve()}return new Promise((o,i)=>{let u,c=setTimeout(()=>{if(t&&u)t.removeEventListener("abort",u);o()},e);if(t)u=()=>{if(clearTimeout(c),r)i(new DOMException("Aborted","AbortError"));else o()},t.addEventListener("abort",u,{once:!0})})}var Oe=C("Chat"),Ne={input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}};function z(e){if(typeof e==="string")return e;return e.filter((t)=>t.type==="text").map((t)=>t.text).join(`
2
+ `)}function Ue(e){if(!e)return{};try{let t=JSON.parse(e);return t&&typeof t==="object"&&!Array.isArray(t)?t:{}}catch{return Oe.warn("[PiAIChatService] Invalid historical tool arguments",{value:e}),{}}}function Be(e){let t=e.match(/^data:([^;,]+);base64,(.+)$/s);return t?{mimeType:t[1],data:t[2]}:void 0}async function Le(e,t){let n=Be(e);if(n)return{type:"image",...n};if(!/^https?:\/\//i.test(e))return{type:"text",text:`[Unsupported image source: ${e}]`};let r=await fetch(e,{signal:t});if(!r.ok)throw Error(`Failed to load image ${e}: HTTP ${r.status}`);return{type:"image",mimeType:r.headers.get("content-type")?.split(";")[0]??"image/png",data:Buffer.from(await r.arrayBuffer()).toString("base64")}}async function ie(e,t,n,r,o){let i=e.filter((a)=>a.role==="system").map((a)=>z(a.content)).filter(Boolean).join(`
3
+
4
+ `),u=[];for(let a of e){if(a.role==="system")continue;if(a.role==="user"){let s=t.input.includes("image"),d=typeof a.content==="string"?a.content:await Promise.all(a.content.map((f)=>f.type==="text"?Promise.resolve({type:"text",text:f.text}):s?Le(f.image_url.url,r):Promise.resolve({type:"text",text:"[Image omitted: current model does not support image input]"})));u.push({role:"user",content:d,timestamp:Date.now()});continue}if(a.role==="assistant"){let s=[];if(a.reasoningContent?.trim())s.push({type:"thinking",thinking:a.reasoningContent});let d=z(a.content);if(d)s.push({type:"text",text:d});for(let f of a.tool_calls??[]){if(!("function"in f))continue;s.push({type:"toolCall",id:f.id,name:f.function.name,arguments:Ue(f.function.arguments)})}u.push({role:"assistant",content:s,api:t.api,provider:t.provider,model:t.id,usage:Ne,stopReason:a.tool_calls?.length?"toolUse":"stop",timestamp:Date.now()});continue}u.push({role:"toolResult",toolCallId:a.tool_call_id??"",toolName:a.name??"unknown",content:[{type:"text",text:z(a.content)}],isError:!1,timestamp:Date.now()})}let c=n?.filter((a)=>!o||a.name===o).map((a)=>({name:a.name,description:a.description,parameters:a.parameters,constrainedSampling:a.constrainedSampling}));return{...i?{systemPrompt:i}:{},messages:u,...c?.length?{tools:c}:{}}}function se(e){let t=[];for(let n=0;n<e.length;n++){let r=e[n];if(r.role==="tool")continue;let o=r.role==="assistant"&&r.tool_calls?.length?r.tool_calls:void 0;if(!o){t.push(r);continue}let i=[],u=n+1;while(u<e.length&&e[u].role==="tool")i.push(e[u++]);let c=new Set(o.map((d)=>d.id)),a=i.filter((d)=>d.tool_call_id&&c.has(d.tool_call_id)),s=new Set(a.map((d)=>d.tool_call_id));if(c.size===o.length&&a.length===c.size&&s.size===c.size)t.push(r,...a);n=u-1}return t}function ae(e){return e.some((t)=>t.role==="assistant"&&Boolean(t.tool_calls?.length)&&!t.reasoningContent?.trim())}function ce(e,t){return{...e,...t.baseUrl?{baseUrl:ue(e.api,t.baseUrl)}:{},...t.maxOutputTokens?{maxTokens:t.maxOutputTokens}:{}}}function H(e){let t=e.modelCatalog??X();return{models:t.models,model:ce(t.getModel(e.provider,e.model),e)}}function de(e,t){let n=e.modelCatalog??X();return ce(n.getModel(t.provider,t.model),e)}var fe=new WeakSet;class D extends Error{budgetMs;elapsedMs;code="PROVIDER_RECOVERY_BUDGET_EXCEEDED";constructor(e,t){super(`Provider recovery budget exhausted after ${e}ms`);this.budgetMs=e;this.elapsedMs=t;this.name="ProviderRecoveryBudgetExceededError"}}var je=["gousagelimiterror","freeusagelimiterror","monthly usage limit reached","available balance","insufficient_quota","out of budget","quota exceeded","billing"],Ve=["prompt_too_long","prompt is too long","maximum context length","context length exceeded","context_length_exceeded","request too large"],We=["econnreset","econnrefused","enotfound","eai_again","etimedout","fetch failed","network error","connection error","connection refused","connection lost","other side closed","socket hang up","socket connection was closed","upstream connect","reset before headers","websocket closed","websocket error","http2 request did not get a response"];function pe(e){return(e instanceof Error?e.message:String(e)).toLowerCase()}function Ye(e){let t=pe(e);return Ve.some((n)=>t.includes(n))}function G(e){if(e!==null&&typeof e==="object")fe.add(e)}function Et(e){return e!==null&&typeof e==="object"&&fe.has(e)}function ze(e){return e!==null&&typeof e==="object"&&"code"in e?e.code:void 0}function Xe(e){if(e===null||typeof e!=="object")return;let t=e;for(let n of["status","statusCode"]){let r=t[n];if(typeof r==="number"&&Number.isInteger(r))return r}return}function He(e){let t=e.match(/^(?:error:\s*)?(\d{3})\b/),n=e.match(/\b(?:status(?:\s+code)?|http)[:\s]+(\d{3})\b/),r=Number(t?.[1]??n?.[1]);return Number.isInteger(r)?r:void 0}function O(e,t){let n=pe(e),r=ze(e);if(r==="STREAM_IDLE_TIMEOUT"||r==="PROVIDER_RECOVERY_BUDGET_EXCEEDED"||e instanceof Error&&e.name==="AbortError"||n.includes("request aborted")||n==="aborted")return{retryable:!1};if(je.some((i)=>n.includes(i))||Ye(e))return{retryable:!1};if(t?.shouldRetry==="false")return{retryable:!1,statusCode:t.statusCode};let o=t?.statusCode??Xe(e)??He(n);if(t?.shouldRetry==="true")return{retryable:!0,reason:o===429?"rate_limit":o===408||o===409?"timeout":"server_error",statusCode:o};if(o===429)return{retryable:!0,reason:"rate_limit",statusCode:o};if(o===408||o===409)return{retryable:!0,reason:"timeout",statusCode:o};if(o!==void 0&&o>=500&&o<=599)return{retryable:!0,reason:"server_error",statusCode:o};if(r==="PROVIDER_STREAM_CLOSED"||n.includes("stream closed before completion")||n.includes("ended without")||n.includes("stream ended before"))return{retryable:!0,reason:"stream_closed",statusCode:o};if(We.some((i)=>n.includes(i)))return{retryable:!0,reason:"transport",statusCode:o};if(n.includes("timeout")||n.includes("timed out")||n.includes("temporarily unavailable")||n.includes("upstream_error")||n.includes("overloaded")||n.includes("rate limit")||n.includes("too many requests")||n.includes("service unavailable")||n.includes("server error")||n.includes("internal error")||n.includes("please retry")||n.includes("try your request again"))return{retryable:!0,reason:n.includes("rate")||n.includes("too many")?"rate_limit":n.includes("timeout")||n.includes("timed out")?"timeout":"server_error",statusCode:o};return{retryable:!1,statusCode:o}}function Ge(e,t){if(!e)return;if(e.retryAfterMs!==void 0){let o=Number.parseFloat(e.retryAfterMs);if(Number.isFinite(o))return Math.max(0,o)}if(e.retryAfter===void 0)return;let n=Number.parseFloat(e.retryAfter);if(Number.isFinite(n))return Math.max(0,n*1000);let r=Date.parse(e.retryAfter);return Number.isFinite(r)?Math.max(0,r-t):void 0}function le(e,t,n={}){let r=n.now??Date.now(),o=n.maxDelayMs??60000,i=Ge(t,r);if(i!==void 0)return Math.min(Math.ceil(i),o);let u=Math.max(0,e-1),c=n.maxExponentialDelayMs??8000,a=Math.min(500*2**u,c),s=Math.max(0,Math.min(1,n.random??Math.random())),d=a*(0.75+s*0.25);return Math.min(Math.round(d),o)}function xe(e,t){let n=e.onPayload;e.onPayload=async(r,o)=>{let i=n?await n(r,o):r;return t(i===void 0?r:i,o)}}function $e(e){if(!e.reasoningEnabled)return;return e.reasoningEffort??e.reasoningLevel??"high"}function Fe(e){switch(e){case"minimal":return"MINIMAL";case"low":return"LOW";case"medium":return"MEDIUM";default:return"HIGH"}}function Ke(e,t,n,r){let o=r?void 0:$e(n);if(!o){if(t.api==="anthropic-messages")e.thinkingEnabled=!1;if(t.api==="google-generative-ai"||t.api==="google-vertex")e.thinking={enabled:!1};return}switch(t.api){case"anthropic-messages":e.thinkingEnabled=!0,e.effort=o;break;case"google-generative-ai":case"google-vertex":e.thinking={enabled:!0,level:Fe(o)};break;case"mistral-conversations":e.reasoningEffort="high";break;case"bedrock-converse-stream":case"pi-messages":e.reasoning=o;break;default:e.reasoningEffort=o}}function Je(e,t,n){if(!n)return;switch(t){case"anthropic-messages":case"bedrock-converse-stream":e.toolChoice={type:"tool",name:n};break;case"openai-completions":case"mistral-conversations":case"pi-messages":e.toolChoice={type:"function",function:{name:n}};break;case"openai-responses":case"openai-codex-responses":case"azure-openai-responses":e.toolChoice={type:"function",name:n};break;case"google-generative-ai":case"google-vertex":e.toolChoice="any";break}}function Ze(e,t,n){let r=n.serviceTier;if(!r)return;if(t.api==="openai-responses"||t.api==="openai-codex-responses"||t.api==="azure-openai-responses"){e.serviceTier=r;return}if(t.api!=="openai-completions"&&!(t.api==="anthropic-messages"&&r==="fast"))return;xe(e,(o)=>{if(!o||typeof o!=="object"||Array.isArray(o))return o;return t.api==="anthropic-messages"?{...o,speed:"fast"}:{...o,service_tier:r}})}function Qe(e,t,n){let r=n.responseVerbosity;if(!r)return;if(he(t,r),t.api==="openai-codex-responses"){e.textVerbosity=r;return}xe(e,(o)=>{if(!o||typeof o!=="object"||Array.isArray(o))return o;if(t.api==="openai-completions")return{...o,verbosity:r};let i="text"in o&&o.text&&typeof o.text==="object"&&!Array.isArray(o.text)?o.text:{};return{...o,text:{...i,verbosity:r}}})}function Me(e,t,n,r,o=!1){let i={apiKey:e.apiKey,headers:e.customHeaders,signal:n,temperature:r?.temperature??e.temperature??0,maxTokens:r?.maxOutputTokens??e.maxOutputTokens,timeoutMs:e.timeout,maxRetries:0,cacheRetention:e.enablePromptCaching?"short":"none"};if(Ke(i,t,e,o),Je(i,t.api,r?.toolChoice?.toolName),Ze(i,t,e),Qe(i,t,e),t.api==="azure-openai-responses")i.azureBaseUrl=e.baseUrl,i.azureApiVersion=e.apiVersion,i.azureDeploymentName=t.id;return i}function me(e,t){let n=t.get("x-should-retry");return{statusCode:e,...t.get("retry-after")!==null?{retryAfter:t.get("retry-after")??void 0}:{},...t.get("retry-after-ms")!==null?{retryAfterMs:t.get("retry-after-ms")??void 0}:{},...n==="true"||n==="false"?{shouldRetry:n}:{}}}var qe=new Set(["anthropic-messages","openai-completions","openai-responses","openai-codex-responses","azure-openai-responses","pi-messages"]);function be(e,t,n){let r=e.onResponse;if(e.onResponse=async(i,u)=>{let c=new Headers(i.headers);n(me(i.status,c)),await r?.(i,u)},!qe.has(t.api)||typeof globalThis.fetch!=="function")return;let o=typeof e.fetch==="function"?e.fetch:globalThis.fetch.bind(globalThis);e.fetch=async(i,u)=>{let c=await o(i,u);return n(me(c.status,c.headers)),c}}function _e(e){return{promptTokens:e.input+e.cacheRead+e.cacheWrite,completionTokens:e.output,totalTokens:e.totalTokens,costUsd:e.cost.total,...e.reasoning!==void 0?{reasoningTokens:e.reasoning}:{},...e.cacheWrite>0?{cacheCreationInputTokens:e.cacheWrite}:{},...e.cacheRead>0?{cacheReadInputTokens:e.cacheRead}:{}}}var F=300000,et=30000;class Te extends Error{timeoutMs;code="STREAM_IDLE_TIMEOUT";constructor(e){super(`Provider stream idle timeout after ${e}ms without an event`);this.timeoutMs=e;this.name="StreamIdleTimeoutError"}}class Ee extends Error{code="PROVIDER_STREAM_CLOSED";constructor(){super("Provider stream closed before completion");this.name="ProviderStreamClosedError"}}function $(e){return e.reason instanceof Error?e.reason:new DOMException("Aborted","AbortError")}function tt(e){return e.idleTimeoutMs&&e.idleTimeoutMs>0?e.idleTimeoutMs:F}function nt(e,t){if(t===0)return;let n=t!==void 0&&t>0?t:et;return Math.max(1,Math.min(n,Math.floor(e/2)))}function ot(e,t,n){if(n?.aborted)return Promise.reject($(n));return new Promise((r,o)=>{let i=!1,u=()=>{clearTimeout(d),n?.removeEventListener("abort",s)},c=(f)=>{if(i)return;i=!0,u(),r(f)},a=(f)=>{if(i)return;i=!0,u(),o(f instanceof Error?f:Error(String(f)))},s=()=>{if(n)a($(n))},d=setTimeout(()=>c({kind:"timer"}),Math.max(0,t));if(n?.addEventListener("abort",s,{once:!0}),n?.aborted){s();return}e.then((f)=>c({kind:"next",result:f}),a)})}async function*rt(e,t,n){let r=tt(t),o=nt(r,t.stallWarningMs);if(t.signal?.aborted)throw $(t.signal);let i=Date.now(),u=Promise.resolve().then(()=>e.next()),c;for(;;){let s=await ot(u,(c?r:o??r)-(Date.now()-i),t.signal);if(s.kind==="next"){if(c)yield{...c,phase:"recovered",durationMs:Math.max(c.durationMs,Date.now()-i)};return s.result}if(!c&&o!==void 0){n.stallCount++,c={phase:"detected",stallCount:n.stallCount,durationMs:o,warningAfterMs:o,timeoutMs:r,outputStarted:n.outputStarted},yield c;continue}let d=new Te(r);throw t.abort?.(d),d}}async function*Pe(e,t,n,r,o={}){let u=e.stream(t,n,r)[Symbol.asyncIterator](),c=0,a=!1,s={stallCount:0,outputStarted:!1};try{while(!0){let d=rt(u,o,s),f=await d.next();while(!f.done)yield{providerStall:f.value},f=await d.next();let x=f.value;if(x.done)throw new Ee;let l=x.value;switch(l.type){case"text_delta":s.outputStarted=!0,yield{content:l.delta};break;case"thinking_delta":s.outputStarted=!0,yield{reasoningContent:l.delta};break;case"toolcall_end":s.outputStarted=!0,yield{toolCalls:[{index:c++,id:l.toolCall.id,type:"function",function:{name:l.toolCall.name,arguments:JSON.stringify(l.toolCall.arguments)}}]};break;case"done":a=!0,yield{finishReason:l.reason,usage:_e(l.message.usage)};return;case"error":throw Error(l.error.errorMessage??`Request ${l.reason==="aborted"?"aborted":"failed"}`)}}}finally{if(!a)Promise.resolve(u.return?.()).catch(()=>{return})}}var we=C("Chat");function it(e){return Boolean(e&&e.role==="user"&&Array.isArray(e.content)&&e.content.some((t)=>t.type==="image_url"))}class J{config;models;model;constructor(e){let t=H(e);this.config={...e,maxContextTokens:t.model.contextWindow,maxOutputTokens:e.maxOutputTokens??t.model.maxTokens},this.models=t.models,this.model=t.model,we.debug("[PiAIChatService] Initialized",{provider:this.model.provider,model:this.model.id,api:this.model.api})}async chat(e,t,n,r){let o="",i="",u=[],c,a;for await(let s of this.streamChat(e,t,n,r)){o+=s.content??"",i+=s.reasoningContent??"";for(let d of s.toolCalls??[])if(d.id&&d.type==="function"&&d.function?.name)u.push(d);c=s.usage??c,a=s.finishReason??a}return{content:o,...i?{reasoningContent:i}:{},...u.length>0?{toolCalls:u}:{},usage:c,finishReason:a}}async*streamChat(e,t,n,r){let o=r?.toolChoice?.toolName;if(o&&!t?.some((p)=>p.name===o))throw Error(`Required tool is unavailable: ${o}`);let i=se(e);if(i.some((p)=>it(p))&&!this.model.input.includes("image"))throw Error(`${this.model.name} does not support image input`);let u=Boolean(o)||ae(i),c=await ie(i,this.model,t,n,o),a=r?.providerRecovery;if(a&&!ke(a.budgetMs))throw Error("Invalid bounded foreground Provider recovery budget");let s=a?.mode==="bounded_foreground"&&a.budgetMs>0?{budgetMs:a.budgetMs,startedAt:void 0}:void 0,d=s?"bounded_foreground":"standard",f=this.config.maxRetries??2,x=this.config.maxRetries??(s?ye:2),l=s!==void 0&&this.config.maxRetries===void 0,k=0,g,I=(p=Date.now())=>{if(!s)return;let _=s.startedAt===void 0?0:Math.min(s.budgetMs,Math.max(0,p-s.startedAt));return{recoveryBudgetMs:s.budgetMs,recoveryElapsedMs:_,recoveryRemainingMs:Math.max(0,s.budgetMs-_)}},P=()=>({mode:d,...I()??{}}),ge=()=>{if(s&&s.startedAt===void 0)s.startedAt=Date.now()},L=()=>{let p=I();return new D(s?.budgetMs??0,p?.recoveryElapsedMs??0)},v=()=>!l||k<x+1,Ce=(p)=>{if(!v())throw L();if(l)k++;g=void 0;let _=new AbortController,w=n?oe(n,_.signal):_.signal,b;if(s?.startedAt!==void 0){let m=I()?.recoveryRemainingMs??0;if(m<=0)throw L();let T=new D(s.budgetMs,s.budgetMs);b=setTimeout(()=>_.abort(T),m),b.unref?.()}let y=Me(this.config,p,w,r,u);be(y,p,(m)=>{g=m});let R=Pe(this.models,p,c,y,{idleTimeoutMs:this.config.streamIdleTimeout??F,signal:w,abort:(m)=>_.abort(m)});return async function*(){try{yield*R}finally{if(b)clearTimeout(b)}}()},Z=this,Q=async function*(p,_,w,b){let y,R=!1,m,T;for(let E=0;E<=w;E++){if(!v())break;try{let M=!1;for await(let h of Ce(p)){if(h.providerStall){yield h;continue}let V=l?k-1:E;if(V>0&&m&&!M)M=!0,yield{providerRetry:{phase:"recovered",attempt:V,maxRetries:x,reason:m,...T!==void 0?{statusCode:T}:{},...P()}};R=!0,_(),yield h}return}catch(M){if(y=M,Z.logIdleTimeout(M,R,p),await Z.handleAbort(n),M instanceof D){if(R)throw G(M),M;throw yield{providerRetry:{phase:"exhausted",attempt:l?Math.max(0,k-1):E,maxRetries:x,reason:m??"timeout",...T!==void 0?{statusCode:T}:{},...P(),exhaustedBy:"recovery_budget"}},M}let h=O(M,g);if(R)throw G(M),M;if(!h.retryable||!h.reason){if(E>0&&m)yield{providerRetry:{phase:"exhausted",attempt:l?Math.max(0,k-1):E,maxRetries:x,reason:m,...T!==void 0?{statusCode:T}:{},...P()}};throw M}if(m=h.reason,T=h.statusCode,E<w&&v()){ge();let ee=l?k:E+1,W=le(ee,g,s?{maxDelayMs:K,maxExponentialDelayMs:K}:void 0),ve=I(),A=s?Math.min(W,ve?.recoveryRemainingMs??W):W,U={attempt:ee,maxRetries:x,reason:h.reason,...h.statusCode!==void 0?{statusCode:h.statusCode}:{}};if(yield{providerRetry:{phase:"scheduled",...U,delayMs:A,nextRetryAt:Date.now()+A,...P()}},s){let S=A;while(S>0){let te=Math.min(S,Re);if(await B(te,n,{throwOnAbort:!0}),S-=te,(I()?.recoveryRemainingMs??0)<=0){let Ae=L();throw yield{providerRetry:{phase:"exhausted",...U,...P(),exhaustedBy:"recovery_budget"}},Ae}if(S>0)yield{providerRetry:{phase:"waiting",...U,delayMs:A,nextRetryAt:Date.now()+S,...P()}}}}else await B(A,n,{throwOnAbort:!0});yield{providerRetry:{phase:"attempt",...U,...P()}}}else yield{providerRetry:{phase:"exhausted",attempt:l?Math.max(0,k-1):E,maxRetries:x,reason:h.reason,...h.statusCode!==void 0?{statusCode:h.statusCode}:{},...P(),...s&&(b||!v())?{exhaustedBy:"attempt_limit"}:{}}}}}throw y},j,q=!1,N=this.config.fallbackModels??[],Ie=s&&N.length>0?Math.min(f,x):x;try{for await(let p of Q(this.model,()=>{q=!0},Ie,N.length===0))yield p;return}catch(p){if(j=p,q||!O(p,g).retryable)throw p}for(let[p,_]of N.entries()){if(!v())break;yield{modelFallback:!0};let w=!1;try{let b=de(this.config,_),y=p===N.length-1,R=s&&!y?Math.min(f,x):x;for await(let m of Q(b,()=>{w=!0},R,y))yield m;return}catch(b){if(j=b,w||!O(b,g).retryable)throw b}}throw j}async handleAbort(e){if(e?.aborted)await B(0,e,{throwOnAbort:!0})}logIdleTimeout(e,t,n){if(e===null||typeof e!=="object"||!("code"in e)||e.code!=="STREAM_IDLE_TIMEOUT"||!("timeoutMs"in e)||typeof e.timeoutMs!=="number")return;we.warn("[PiAIChatService] Provider stream idle timeout",{provider:n.provider,model:n.id,timeoutMs:e.timeoutMs,replayBoundaryCrossed:t})}getConfig(){return{...this.config}}updateConfig(e){let t={...this.config,...e},n=H(t);this.config={...t,maxContextTokens:n.model.contextWindow,maxOutputTokens:t.maxOutputTokens??n.model.maxTokens},this.models=n.models,this.model=n.model}}var st=C("Service");async function Wt(e){let t=e;if(t.provider){let n=ne(t.provider);if(Object.keys(n).length>0)t={...t,customHeaders:{...n,...t.customHeaders}},st.debug(`Injected ${t.provider} specific headers:`,Object.keys(n))}return at(t)}function at(e){return new J(e)}
5
+ export{dt as Hd,lt as Id,oe as Jd,Ye as Kd,Et as Ld,J as Md,Wt as Nd};
@@ -1,2 +1,2 @@
1
- import{dg as S}from"./chunk-gy8esxaa.js";import{ug as f}from"./chunk-4s0c6tkd.js";import*as $ from"fs/promises";import*as K from"path";import j from"semver";import{ProxyAgent as H,fetch as I}from"undici";function R(){return process.env.HTTPS_PROXY||process.env.HTTP_PROXY||process.env.https_proxy||process.env.http_proxy}function N(){let q=R();if(q)try{return new H(q)}catch(z){console.warn(`[proxyFetch] Invalid proxy URL: ${q}`)}return}async function M(q,z={}){let{timeout:W=30000,signal:Q,...B}=z;if(Q?.aborted)throw new DOMException("The operation was aborted.","AbortError");let J=N(),X=new AbortController,Y=!1,F=setTimeout(()=>{Y=!0,X.abort()},W),b=()=>X.abort();Q?.addEventListener("abort",b);try{let Z={method:B.method,headers:B.headers,body:B.body,signal:X.signal,dispatcher:J};return await I(q.toString(),Z)}catch(Z){if(Z instanceof Error&&Z.name==="AbortError"){if(Y)throw Error(`Request timeout after ${W}ms`);throw Z}throw Z}finally{clearTimeout(F),Q?.removeEventListener("abort",b)}}var w="blade-code",y="https://cdn.jsdelivr.net/npm/blade-code@latest/CHANGELOG.md",G=K.join(process.env.HOME||process.env.USERPROFILE||".",".blade"),O=K.join(G,"version-cache.json"),P=3600000,k=`https://registry.npmjs.org/${w}/latest`;async function L(){try{if(process.env.BLADE_VERSION)return process.env.BLADE_VERSION;return S()}catch{return"unknown"}}async function T(){try{let q=await $.readFile(O,"utf-8"),z=JSON.parse(q);if(Date.now()-z.checkedAt<P)return z;return{...z,checkedAt:0}}catch{return null}}async function D(q){try{await $.mkdir(G,{recursive:!0,mode:493}),await $.writeFile(O,JSON.stringify(q,null,2))}catch{}}async function x(){try{let q=await M(k,{timeout:5000,headers:{Accept:"application/json"}});if(!q.ok)return null;return(await q.json()).version||null}catch{return null}}async function _(q=!1){let z=await L(),W=y;if(z==="unknown")return{currentVersion:z,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:W,error:"Unable to determine current version"};let Q=await T(),B=Q?.skipUntilVersion,J=null;if(!q&&Q?.latestVersion&&Q.checkedAt>0)J=Q.latestVersion;else if(J=await x(),J)await D({latestVersion:J,checkedAt:Date.now(),skipUntilVersion:B});else if(Q?.latestVersion)await D({checkedAt:0,skipUntilVersion:B});if(!J||!j.valid(J))return{currentVersion:z,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:W,error:"Unable to check for updates"};if(j.lt(J,z))J=z,await D({latestVersion:J,checkedAt:Date.now(),skipUntilVersion:B});let X=j.gt(J,z),Y=X;if(X&&B)Y=j.gt(J,B);return{currentVersion:z,latestVersion:J,hasUpdate:X,shouldPrompt:Y,releaseNotesUrl:W}}async function u(q){let z=await T();await D({latestVersion:z?.latestVersion??q,checkedAt:z?.checkedAt||Date.now(),skipUntilVersion:q})}function g(){return`npm install -g ${w}@latest --registry https://registry.npmjs.org`}async function C(){let{spawn:q}=await import("child_process");return new Promise((z)=>{let W=g(),Q=q(W,{stdio:"inherit",shell:!0});Q.on("close",(B)=>{if(B===0)z({success:!0,message:"Upgrade successful! Please restart blade."});else z({success:!1,message:`Upgrade failed (exit code: ${B})`})}),Q.on("error",(B)=>{z({success:!1,message:`Upgrade failed: ${B.message}`})})})}async function V(){try{let q=await _();return q.shouldPrompt?q:null}catch{return null}}
1
+ import{kg as S}from"./chunk-b6ve4vyt.js";import{Bg as f}from"./chunk-jtjcg93t.js";import*as $ from"fs/promises";import*as K from"path";import j from"semver";import{ProxyAgent as H,fetch as I}from"undici";function R(){return process.env.HTTPS_PROXY||process.env.HTTP_PROXY||process.env.https_proxy||process.env.http_proxy}function N(){let q=R();if(q)try{return new H(q)}catch(z){console.warn(`[proxyFetch] Invalid proxy URL: ${q}`)}return}async function M(q,z={}){let{timeout:W=30000,signal:Q,...B}=z;if(Q?.aborted)throw new DOMException("The operation was aborted.","AbortError");let J=N(),X=new AbortController,Y=!1,F=setTimeout(()=>{Y=!0,X.abort()},W),b=()=>X.abort();Q?.addEventListener("abort",b);try{let Z={method:B.method,headers:B.headers,body:B.body,signal:X.signal,dispatcher:J};return await I(q.toString(),Z)}catch(Z){if(Z instanceof Error&&Z.name==="AbortError"){if(Y)throw Error(`Request timeout after ${W}ms`);throw Z}throw Z}finally{clearTimeout(F),Q?.removeEventListener("abort",b)}}var w="blade-code",y="https://cdn.jsdelivr.net/npm/blade-code@latest/CHANGELOG.md",G=K.join(process.env.HOME||process.env.USERPROFILE||".",".blade"),O=K.join(G,"version-cache.json"),P=3600000,k=`https://registry.npmjs.org/${w}/latest`;async function L(){try{if(process.env.BLADE_VERSION)return process.env.BLADE_VERSION;return S()}catch{return"unknown"}}async function T(){try{let q=await $.readFile(O,"utf-8"),z=JSON.parse(q);if(Date.now()-z.checkedAt<P)return z;return{...z,checkedAt:0}}catch{return null}}async function D(q){try{await $.mkdir(G,{recursive:!0,mode:493}),await $.writeFile(O,JSON.stringify(q,null,2))}catch{}}async function x(){try{let q=await M(k,{timeout:5000,headers:{Accept:"application/json"}});if(!q.ok)return null;return(await q.json()).version||null}catch{return null}}async function _(q=!1){let z=await L(),W=y;if(z==="unknown")return{currentVersion:z,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:W,error:"Unable to determine current version"};let Q=await T(),B=Q?.skipUntilVersion,J=null;if(!q&&Q?.latestVersion&&Q.checkedAt>0)J=Q.latestVersion;else if(J=await x(),J)await D({latestVersion:J,checkedAt:Date.now(),skipUntilVersion:B});else if(Q?.latestVersion)await D({checkedAt:0,skipUntilVersion:B});if(!J||!j.valid(J))return{currentVersion:z,latestVersion:null,hasUpdate:!1,shouldPrompt:!1,releaseNotesUrl:W,error:"Unable to check for updates"};if(j.lt(J,z))J=z,await D({latestVersion:J,checkedAt:Date.now(),skipUntilVersion:B});let X=j.gt(J,z),Y=X;if(X&&B)Y=j.gt(J,B);return{currentVersion:z,latestVersion:J,hasUpdate:X,shouldPrompt:Y,releaseNotesUrl:W}}async function u(q){let z=await T();await D({latestVersion:z?.latestVersion??q,checkedAt:z?.checkedAt||Date.now(),skipUntilVersion:q})}function g(){return`npm install -g ${w}@latest --registry https://registry.npmjs.org`}async function C(){let{spawn:q}=await import("child_process");return new Promise((z)=>{let W=g(),Q=q(W,{stdio:"inherit",shell:!0});Q.on("close",(B)=>{if(B===0)z({success:!0,message:"Upgrade successful! Please restart blade."});else z({success:!1,message:`Upgrade failed (exit code: ${B})`})}),Q.on("error",(B)=>{z({success:!1,message:`Upgrade failed: ${B.message}`})})})}async function V(){try{let q=await _();return q.shouldPrompt?q:null}catch{return null}}
2
2
  export{_ as a,u as b,g as c,C as d,V as e};
@@ -1,2 +1,2 @@
1
1
  import{createRequire as a}from"node:module";var c=a(import.meta.url);
2
- export{c as ug};
2
+ export{c as Bg};
@@ -0,0 +1,2 @@
1
+ var j=600000,m=30000,p=3600000,q=12,t=15000,w=60000;function x(h){return h===0||typeof h==="number"&&Number.isSafeInteger(h)&&h>=30000&&h<=3600000}
2
+ export{j as Of,m as Pf,p as Qf,q as Rf,t as Sf,w as Tf,x as Uf};
@@ -1 +1 @@
1
- import{rc as a,sc as b,tc as c,uc as d,vc as e,wc as f,xc as g}from"./chunk-6gcmfvfj.js";import"./chunk-qgez5vw6.js";import"./chunk-phgqzja3.js";import"./chunk-3rjmkaey.js";import"./chunk-zwt7f9ab.js";import"./chunk-v11r4ahz.js";import"./chunk-thstqcg3.js";import"./chunk-6360fg4j.js";import"./chunk-qvdcesry.js";import"./chunk-g510tpqt.js";import"./chunk-gy8esxaa.js";import"./chunk-y9nq48st.js";import"./chunk-4s0c6tkd.js";export{b as __setSessionSnapshotIOForTesting,c as __resetSessionSnapshotIOForTesting,g as SessionService,d as SessionMissingCreationError,e as SessionArchivedError,f as SessionArchiveConflictError,a as STALE_EMPTY_SESSION_AGE_MS};
1
+ import{rc as a,sc as b,tc as c,uc as d,vc as e,wc as f,xc as g}from"./chunk-d63dczf8.js";import"./chunk-qgez5vw6.js";import"./chunk-atdb1pks.js";import"./chunk-3rjmkaey.js";import"./chunk-zwt7f9ab.js";import"./chunk-v11r4ahz.js";import"./chunk-thstqcg3.js";import"./chunk-6360fg4j.js";import"./chunk-0dw58ycv.js";import"./chunk-asqah231.js";import"./chunk-b6ve4vyt.js";import"./chunk-qc5qwgpt.js";import"./chunk-jtjcg93t.js";export{b as __setSessionSnapshotIOForTesting,c as __resetSessionSnapshotIOForTesting,g as SessionService,d as SessionMissingCreationError,e as SessionArchivedError,f as SessionArchiveConflictError,a as STALE_EMPTY_SESSION_AGE_MS};
@@ -1 +1 @@
1
- import"./chunk-4s0c6tkd.js";var d={command:"install [target]",describe:"Install Blade native build. Use [target] to specify version (stable, latest, or specific version)",builder:(b)=>{return b.positional("target",{describe:"Version to install",type:"string",default:"stable",choices:["stable","latest"]}).option("force",{type:"boolean",describe:"Force reinstall",default:!1}).example([["$0 install","Install stable version"],["$0 install latest","Install latest version"],["$0 install --force","Force reinstall stable version"]])},handler:async(b)=>{console.log(`Installing Blade ${b.target}...`);try{if(b.force)console.log("Force reinstall enabled");console.log("Downloading..."),console.log("Installing..."),console.log("Installation completed successfully")}catch(c){console.error(`Error: Installation failed: ${c instanceof Error?c.message:"未知错误"}`),process.exit(1)}}};export{d as installCommands};
1
+ import"./chunk-jtjcg93t.js";var d={command:"install [target]",describe:"Install Blade native build. Use [target] to specify version (stable, latest, or specific version)",builder:(b)=>{return b.positional("target",{describe:"Version to install",type:"string",default:"stable",choices:["stable","latest"]}).option("force",{type:"boolean",describe:"Force reinstall",default:!1}).example([["$0 install","Install stable version"],["$0 install latest","Install latest version"],["$0 install --force","Force reinstall stable version"]])},handler:async(b)=>{console.log(`Installing Blade ${b.target}...`);try{if(b.force)console.log("Force reinstall enabled");console.log("Downloading..."),console.log("Installing..."),console.log("Installation completed successfully")}catch(c){console.error(`Error: Installation failed: ${c instanceof Error?c.message:"未知错误"}`),process.exit(1)}}};export{d as installCommands};
@@ -1,2 +1,2 @@
1
1
  import{promises as A}from"node:fs";import q from"node:path";var J=new Map;async function L(B){let b=B;while(!0){try{return await A.lstat(q.join(b,".git")),b}catch(H){if(H.code!=="ENOENT")return}let E=q.dirname(b);if(E===b)return;b=E}}async function M(B){let b=q.join(B,".git"),E=await A.lstat(b);if(E.isDirectory())return B;if(!E.isFile())return;let H=await A.readFile(b,"utf8"),F=/^gitdir:\s*(.+)\s*$/im.exec(H);if(!F)return;let z=await A.realpath(q.isAbsolute(F[1])?F[1]:q.resolve(B,F[1])),I=z;try{let x=(await A.readFile(q.join(z,"commondir"),"utf8")).trim();if(x)I=await A.realpath(q.resolve(z,x))}catch(x){if(x.code!=="ENOENT")throw x}return q.basename(I)===".git"?A.realpath(q.dirname(I)):void 0}async function S(B){if(!q.isAbsolute(B))throw Error("Workspace path must be absolute");let b=await A.realpath(B),E=J.get(b);if(E)return E;let H=b;try{let z=await L(b);if(z){let I=await M(z),x=q.relative(z,b);if(I&&(x===""||!x.startsWith(`..${q.sep}`)&&x!==".."&&!q.isAbsolute(x))){let K=q.resolve(I,x);H=await A.realpath(K).catch(()=>K)}}}catch{}let F={projectPath:b,trustRoot:H};if(J.size>=512){let z=J.keys().next().value;if(z)J.delete(z)}return J.set(b,F),F}
2
- export{S as jg};
2
+ export{S as qg};
@@ -0,0 +1 @@
1
+ import{f as a,g as i,h as l,i as m}from"./chunk-r9pz4z1p.js";import"./chunk-ak37gg0n.js";import"./chunk-e6ttz45s.js";import"./chunk-232bcv23.js";import"./chunk-dgks1che.js";import"./chunk-g5429yjs.js";import"./chunk-0nvc6y56.js";import"./chunk-gh0vdddb.js";import"./chunk-9hjhbsna.js";import"./chunk-5cgyevqj.js";import"./chunk-d63dczf8.js";import"./chunk-qgez5vw6.js";import"./chunk-atdb1pks.js";import{$c as n}from"./chunk-x4yfhp8j.js";import"./chunk-0evyrnx0.js";import{vd as s}from"./chunk-5cjy9yj1.js";import"./chunk-v508x7cg.js";import"./chunk-atsw605q.js";import"./chunk-jd764yqg.js";import"./chunk-ahkpjvaq.js";import"./chunk-3rjmkaey.js";import"./chunk-46r1m8yn.js";import"./chunk-rtzd076h.js";import"./chunk-hq18c6r9.js";import"./chunk-zwt7f9ab.js";import"./chunk-ckfc7j7m.js";import"./chunk-r48jmc74.js";import"./chunk-v11r4ahz.js";import"./chunk-vk3e2w5h.js";import"./chunk-a7pvtxvz.js";import"./chunk-93jx06kq.js";import"./chunk-thstqcg3.js";import"./chunk-6360fg4j.js";import"./chunk-jtv91ez8.js";import"./chunk-0dw58ycv.js";import"./chunk-cm4t4cz6.js";import"./chunk-asqah231.js";import"./chunk-b6ve4vyt.js";import"./chunk-tczrjn95.js";import"./chunk-m0a2zdm8.js";import"./chunk-qc5qwgpt.js";import"./chunk-jtjcg93t.js";import v from"chalk";var C={command:"serve",describe:"Start a headless Blade server (no browser)",builder:a,handler:async(p)=>{let r=i(p);if(await s(),!process.env.BLADE_SERVER_PASSWORD)console.log(v.yellow("Warning: BLADE_SERVER_PASSWORD is not set; server is unsecured."));let e=await m.listenAsync(r);if(console.log(`Blade server listening on http://${e.hostname}:${e.port}`),r.hostname==="0.0.0.0"){let o=l();for(let g of o)console.log(` Network: http://${g}:${e.port}`)}let t,c=new Promise((o)=>{t=o}),d=n(async()=>{await e.stop(),t()});try{await c}finally{d(),await e.stop()}}};export{C as serveCommand};
@@ -0,0 +1 @@
1
+ import{me as a,ne as b,oe as c,pe as d,qe as e}from"./chunk-rtzd076h.js";import"./chunk-hq18c6r9.js";import"./chunk-zwt7f9ab.js";import"./chunk-ckfc7j7m.js";import"./chunk-r48jmc74.js";import"./chunk-v11r4ahz.js";import"./chunk-vk3e2w5h.js";import"./chunk-a7pvtxvz.js";import"./chunk-93jx06kq.js";import"./chunk-thstqcg3.js";import"./chunk-6360fg4j.js";import"./chunk-jtv91ez8.js";import"./chunk-0dw58ycv.js";import"./chunk-cm4t4cz6.js";import"./chunk-asqah231.js";import"./chunk-b6ve4vyt.js";import"./chunk-tczrjn95.js";import"./chunk-m0a2zdm8.js";import"./chunk-qc5qwgpt.js";import"./chunk-jtjcg93t.js";export{d as snapshotWorkspaceAgentResources,c as resolveWorkspaceAgentResources,e as resetWorkspaceAgentResources,a as refreshWorkspaceCommunicationStyles,b as configureInvocationPluginDirs};
@@ -1,4 +1,4 @@
1
- import{f as T,g as W,h as X,i as Y}from"./chunk-rshbnfr8.js";import"./chunk-qxvk42rf.js";import"./chunk-4bbnytq5.js";import"./chunk-95n8g52h.js";import"./chunk-q15qd9x4.js";import"./chunk-0m4s8r87.js";import"./chunk-7c5tnz4y.js";import"./chunk-95k17p11.js";import"./chunk-y990fa4r.js";import"./chunk-5cgyevqj.js";import"./chunk-6gcmfvfj.js";import"./chunk-qgez5vw6.js";import"./chunk-phgqzja3.js";import{$c as R}from"./chunk-ck5tvxkj.js";import"./chunk-0evyrnx0.js";import{vd as Q}from"./chunk-e23sz81n.js";import"./chunk-v508x7cg.js";import"./chunk-atsw605q.js";import"./chunk-4vq34v09.js";import"./chunk-6jpspf3v.js";import"./chunk-3rjmkaey.js";import"./chunk-acw8q8w9.js";import"./chunk-9g6rzbcv.js";import"./chunk-hq18c6r9.js";import"./chunk-zwt7f9ab.js";import"./chunk-ckfc7j7m.js";import"./chunk-cc7dmst6.js";import"./chunk-v11r4ahz.js";import"./chunk-515mkr66.js";import"./chunk-a7pvtxvz.js";import"./chunk-93jx06kq.js";import"./chunk-thstqcg3.js";import"./chunk-6360fg4j.js";import"./chunk-qvdcesry.js";import"./chunk-2mvp3rqw.js";import"./chunk-g510tpqt.js";import{dg as M}from"./chunk-gy8esxaa.js";import"./chunk-m6dh31kb.js";import"./chunk-0dj2qm8a.js";import"./chunk-y9nq48st.js";import"./chunk-4s0c6tkd.js";import m from"chalk";import K from"open";var A=`
1
+ import{f as T,g as W,h as X,i as Y}from"./chunk-r9pz4z1p.js";import"./chunk-ak37gg0n.js";import"./chunk-e6ttz45s.js";import"./chunk-232bcv23.js";import"./chunk-dgks1che.js";import"./chunk-g5429yjs.js";import"./chunk-0nvc6y56.js";import"./chunk-gh0vdddb.js";import"./chunk-9hjhbsna.js";import"./chunk-5cgyevqj.js";import"./chunk-d63dczf8.js";import"./chunk-qgez5vw6.js";import"./chunk-atdb1pks.js";import{$c as R}from"./chunk-x4yfhp8j.js";import"./chunk-0evyrnx0.js";import{vd as Q}from"./chunk-5cjy9yj1.js";import"./chunk-v508x7cg.js";import"./chunk-atsw605q.js";import"./chunk-jd764yqg.js";import"./chunk-ahkpjvaq.js";import"./chunk-3rjmkaey.js";import"./chunk-46r1m8yn.js";import"./chunk-rtzd076h.js";import"./chunk-hq18c6r9.js";import"./chunk-zwt7f9ab.js";import"./chunk-ckfc7j7m.js";import"./chunk-r48jmc74.js";import"./chunk-v11r4ahz.js";import"./chunk-vk3e2w5h.js";import"./chunk-a7pvtxvz.js";import"./chunk-93jx06kq.js";import"./chunk-thstqcg3.js";import"./chunk-6360fg4j.js";import"./chunk-jtv91ez8.js";import"./chunk-0dw58ycv.js";import"./chunk-cm4t4cz6.js";import"./chunk-asqah231.js";import{kg as M}from"./chunk-b6ve4vyt.js";import"./chunk-tczrjn95.js";import"./chunk-m0a2zdm8.js";import"./chunk-qc5qwgpt.js";import"./chunk-jtjcg93t.js";import m from"chalk";import K from"open";var A=`
2
2
  ____ _ _
3
3
  | __ )| | __ _ __| | ___
4
4
  | _ \\| |/ _\` |/ _\` |/ _ \\
@@ -1,5 +1,5 @@
1
- import{s as T}from"./chunk-95n8g52h.js";import{t as jz,u as t,v as s,w as e,x as zz,y as Hz}from"./chunk-q15qd9x4.js";import{C as P,L as r,O as a,P as o,S as n,ea as Jz,fa as Qz,ga as Zz,ha as $z}from"./chunk-0m4s8r87.js";import{ra as _z}from"./chunk-7c5tnz4y.js";import"./chunk-95k17p11.js";import{Va as m,ib as l,rb as i}from"./chunk-y990fa4r.js";import{Ab as h}from"./chunk-5cgyevqj.js";import{Tb as g,_b as c,bc as v,jc as S,kc as p,mc as q,pc as d,uc as N,xc as _}from"./chunk-6gcmfvfj.js";import"./chunk-qgez5vw6.js";import"./chunk-phgqzja3.js";import{$c as Gz}from"./chunk-ck5tvxkj.js";import"./chunk-0evyrnx0.js";import"./chunk-e23sz81n.js";import"./chunk-v508x7cg.js";import{Gd as Lz}from"./chunk-atsw605q.js";import"./chunk-4vq34v09.js";import"./chunk-6jpspf3v.js";import{Rd as Bz}from"./chunk-3rjmkaey.js";import"./chunk-acw8q8w9.js";import"./chunk-9g6rzbcv.js";import"./chunk-hq18c6r9.js";import{we as Uz}from"./chunk-zwt7f9ab.js";import"./chunk-ckfc7j7m.js";import"./chunk-cc7dmst6.js";import"./chunk-v11r4ahz.js";import"./chunk-515mkr66.js";import"./chunk-a7pvtxvz.js";import"./chunk-93jx06kq.js";import{Hf as y,If as u,Jf as I}from"./chunk-thstqcg3.js";import{Nf as Xz}from"./chunk-6360fg4j.js";import{Rf as x}from"./chunk-qvdcesry.js";import"./chunk-2mvp3rqw.js";import{$f as Fz,Yf as Yz}from"./chunk-g510tpqt.js";import"./chunk-gy8esxaa.js";import"./chunk-m6dh31kb.js";import"./chunk-0dj2qm8a.js";import"./chunk-y9nq48st.js";import"./chunk-4s0c6tkd.js";import{Readable as Ez,Writable as qz}from"node:stream";import*as b from"@agentclientprotocol/sdk";import Wz from"node:path";import{PROTOCOL_VERSION as Pz}from"@agentclientprotocol/sdk";import{RequestError as Az}from"@agentclientprotocol/sdk";import{nanoid as M}from"nanoid";var U=x("Agent");function f(z){if(!z)return{};return Object.fromEntries(z.map((J)=>[J.name,J.value]))}function Kz(z){if("command"in z)return{type:"stdio",command:z.command,args:z.args,env:f(z.env)};if("url"in z)return{type:z.type,url:z.url,headers:f("headers"in z?z.headers:void 0)};return null}function Rz(z){let J={};for(let H of z){let D=Kz(H);if(D)J[H.name]=D}return J}function Dz(z){if(typeof z==="string")return z?[{type:"text",text:z}]:[];return z.flatMap((J)=>{if(J.type==="text")return J.text?[{type:"text",text:J.text}]:[];let H=J.image_url.url,D=/^data:([^;,]+);base64,(.+)$/s.exec(H);if(!D)return[{type:"text",text:"[Image]"}];return[{type:"image",mimeType:D[1]??"image/png",data:D[2]??""}]})}function Nz(z){let J=p(z.metadata);return J?[{type:"text",text:S(J)}]:Dz(z.content)}function Oz(z){return[`Status: ${z.status}`,`Exit code: ${z.exitCode??"null"}`,`Duration: ${(z.durationMs/1000).toFixed(3)} seconds`].join(`
2
- `)}class E{id;cwd;connection;clientCapabilities;options;agent=null;runtime=null;pendingPrompt=null;pendingPromptCompletion=null;pendingUserShell=null;pendingUserShellCompletion=null;pendingResumeRequested=!1;availableCommandsTimer=null;taskStatusUnsubscribe;destroyed=!1;destroyFinished=!1;destroyPromise;messages;contextMessages;mode;updateEgress;constructor(z,J,H,D,W={}){this.id=z;this.cwd=J;this.connection=H;this.clientCapabilities=D;this.options=W;this.messages=[...W.initialMessages??[]],this.contextMessages=[...this.messages],this.mode=this.mapPermissionModeToMode(W.permissionMode),this.updateEgress=new Hz({maxPendingItems:t,maxPendingBytes:s,writeTimeoutMs:e,signal:H.signal,sizeOf:(Q)=>Buffer.byteLength(JSON.stringify(Q)),write:async(Q)=>{await H.sessionUpdate(Q)},onFailure:(Q)=>this.handleUpdateEgressFailure(Q)})}async refreshPersistedMessages(){let[z,J]=await Promise.all([_.loadSession(this.id,this.cwd),_.loadSessionModelContext(this.id,this.cwd)]);if(z.length>0)this.messages=z;if(J.length>0)this.contextMessages=J}async loadModelContextOr(z){let J=await _.loadSessionModelContext(this.id,this.cwd);return J.length>0?J:[...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 n.createWithRuntime(this.runtime,{sessionId:this.id,...this.options.taskWorktree?{toolBlacklist:["EnterWorktree","ExitWorktree"]}:{}})}async initialize(){if(U.debug(`[AcpSession ${this.id}] Initializing...`),await _.setSessionPermissionMode(this.id,this.cwd,this.mapModeToPermissionMode()??"default"),P.initializeSession(this.connection,this.id,this.clientCapabilities,this.cwd,async(Q)=>{await this.sendUpdateAndWait(Q)}),U.debug(`[AcpSession ${this.id}] ACP service context initialized`),await i.resolvePendingWithHandler(this.cwd,this.id,{requestConfirmation:(Q)=>this.requestPermission(Q)}))await this.refreshPersistedMessages();else if((this.options.initialMessages?.length??0)>0)this.contextMessages=await this.loadModelContextOr(this.options.initialMessages??[]);let J=this.options.mcpServers?Rz(this.options.mcpServers):void 0,H=P.getInstance().getTerminalService(this.id);if(this.runtime=await r.create({sessionId:this.id,workspaceRoot:this.cwd,permissionMode:this.mapModeToPermissionMode(),...J?{mcpServers:J}:{},...this.options.taskWorktree?{taskWorktree:this.options.taskWorktree}:{},...this.options.taskIsolation?{taskIsolation:this.options.taskIsolation}:{},userShellExecutor:{execute:async(Q,Z)=>{let X=await H.execute(Q,{cwd:Z.cwd,env:Z.env,timeout:Z.timeoutMs,signal:Z.signal,allowLocalFallback:!1,onOutput:(Y)=>Z.onOutput?.("stdout",Y)});return{exitCode:X.exitCode,stdout:X.stdout,stderr:X.stderr,...X.error?{error:X.error}:{},timedOut:X.failureKind==="timeout",aborted:X.failureKind==="aborted"}}},...(this.options.initialMessages?.length??0)>0?{sessionStart:{isResume:!0,resumeSessionId:this.id}}:{}}),await T.recoverInterrupted(this.cwd,this.id,this.runtime))await this.refreshPersistedMessages();this.agent=await this.createAgent(),await Qz(this.cwd),U.debug(`[AcpSession ${this.id}] Agent created successfully`),this.taskStatusUnsubscribe?.(),this.taskStatusUnsubscribe=m.subscribe((Q)=>{if(Q.sessionId!==this.id||Q.projectPath!==this.cwd)return;if(Q.type==="subagent.completion.queued"){this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:new Date().toISOString(),_meta:{"blade/backgroundSubagentCompletion":Q.properties}}),this.schedulePendingResume();return}if(Q.type==="task.delivery"){if(!Q.properties.taskDelivery||typeof Q.properties.taskDelivery!=="object")return;this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:typeof Q.properties.updatedAt==="string"?Q.properties.updatedAt:new Date().toISOString(),_meta:{"blade/taskDelivery":Q.properties.taskDelivery,...Q.properties.taskWorktreeRemoved===!0?{"blade/taskWorktreeRemoved":!0}:{}}});return}if(Q.type!=="task.status")return;this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:typeof Q.properties.updatedAt==="string"?Q.properties.updatedAt:new Date().toISOString(),_meta:{"blade/taskStatus":Q.properties.taskStatus,...typeof Q.properties.taskStatusReason==="string"?{"blade/taskStatusReason":Q.properties.taskStatusReason}:{},...Q.properties.taskFailure&&typeof Q.properties.taskFailure==="object"?{"blade/taskFailure":Q.properties.taskFailure}:{},...typeof Q.properties.taskStartedAt==="string"?{"blade/taskStartedAt":Q.properties.taskStartedAt}:{},...typeof Q.properties.taskCompletedAt==="string"?{"blade/taskCompletedAt":Q.properties.taskCompletedAt}:{},...Q.properties.taskDiffStat&&typeof Q.properties.taskDiffStat==="object"?{"blade/taskDiffStat":Q.properties.taskDiffStat}:{},...typeof Q.properties.taskQueuePosition==="number"?{"blade/taskQueuePosition":Q.properties.taskQueuePosition}:{},...typeof Q.properties.taskQueueDepth==="number"?{"blade/taskQueueDepth":Q.properties.taskQueueDepth}:{},...typeof Q.properties.taskConcurrencyLimit==="number"?{"blade/taskConcurrencyLimit":Q.properties.taskConcurrencyLimit}:{},...typeof Q.properties.taskInFlight==="number"?{"blade/taskInFlight":Q.properties.taskInFlight}:{}}})});let W=await this.runtime.getGoal();if(this.runtime.getPendingSteeringCount()>0||W?.status==="active"||W?.status==="verifying")if(this.options.initialMessages===void 0)this.schedulePendingResume();else this.pendingResumeRequested=!0}async replayHistory(){for(let J of this.messages){if(!this.canSendUpdates())return;let H=J.role==="user"?"user_message_chunk":J.role==="assistant"?"agent_message_chunk":void 0;if(!H)continue;for(let D of Nz(J)){if(!this.canSendUpdates())return;if(!await this.sendUpdateAndWait({sessionUpdate:H,content:D}))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);U.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,J){try{U.debug(`[AcpSession ${this.id}] Executing slash command: ${z}`);let H={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(Z)=>{if(!this.runtime)throw Error("Session runtime is unavailable");let X=await this.runtime.rewindSession(Z);return this.messages=[...X.messages],this.contextMessages=await this.loadModelContextOr(X.messages),await this.agent?.destroy(),this.agent=await this.createAgent(),X}},reasoning:{get:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getReasoningConfiguration()},set:async(Z)=>{if(await this.setReasoningEffort(Z),!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(Z)=>{if(await this.setServiceTier(Z),!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(Z)=>{if(await this.setResponseVerbosity(Z),!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(Z)=>{if(await this.setCommunicationStyle(Z),!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(Z,X)=>{if(!this.runtime)throw Error("Session runtime is unavailable");let Y=!1,F,L=(A)=>{this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:A.id,status:A.status==="completed"?"completed":"failed",content:[{type:"content",content:{type:"text",text:A.result?.message||A.result?.error||`Subagent ${A.status}`}}]})},B=this.runtime.resumeSubagent({agentId:Z,prompt:X,onCompleted:(A)=>{if(Y)L(A);else F=A}});if(this.sendUpdate({sessionUpdate:"tool_call",toolCallId:B.session.id,status:"in_progress",title:`Resuming ${B.session.subagentType} subagent`,content:[{type:"content",content:{type:"text",text:`Resumed from ${B.source.id} at depth ${B.session.resumeDepth}`}}],kind:this.mapToolKind("readonly")}),Y=!0,F)L(F);return B}},mcp:{getCatalog:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpContentCatalog()},refresh:async(Z)=>{if(!this.runtime)throw Error("Session runtime is unavailable");await this.runtime.refreshMcpContentCatalogs(Z)},getPrompt:async(Z,X,Y)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpPrompt(Z,X,Y)},complete:async(Z,X,Y)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.completeMcpArgument(Z,X,Y)},listTasks:async(Z)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.listMcpTasks(Z)},getTask:async(Z)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpTask(Z)},cancelTask:async(Z,X)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.cancelMcpTask(Z,X)},getLogs:async(Z,X)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpLogs(Z,X)},setLoggingLevel:async(Z,X)=>{if(!this.runtime)throw Error("Session runtime is unavailable");await this.runtime.setMcpLoggingLevel(Z,X)},getInstructions:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpInstructions()}},codeReview:{run:async(Z,X)=>{if(!this.runtime)throw Error("Session runtime is unavailable");let Y=await T.start({sessionId:this.id,projectPath:this.cwd,runtime:this.runtime,request:Z,signal:X,onEvent:(B)=>{if(B.kind==="tool_start")this.sendUpdate({sessionUpdate:"tool_call",toolCallId:B.toolCall.id,status:"in_progress",title:`Review: ${B.toolCall.function.name}`,content:[],kind:this.mapToolKind(B.toolKind)});else if(B.kind==="tool_result")this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:B.toolCall.id,status:B.result.success?"completed":"failed",content:[]})}}),F=await Y.completion,L=(await T.list(this.cwd,this.id)).find((B)=>B.start.reviewId===Y.reviewId);if(!L)throw Error(`Review not found: ${Y.reviewId}`);return await this.refreshPersistedMessages(),{reviewId:Y.reviewId,status:F.status,findings:F.findings.length,content:g(L.start,F)}}},signal:J,acp:{sendMessage:(Z)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:Z}})},sendToolStart:(Z,X,Y)=>{let F=`tool_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,L=this.mapToolKind(Y);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:F,status:"in_progress",title:`${Z}`,content:[{type:"content",content:{type:"text",text:JSON.stringify(X,null,2)}}],kind:L})},sendToolResult:(Z,X)=>{if(X.summary)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:X.summary}})}}},D=await Zz(z,H),W=D.data?.action;if(W==="start_goal"||W==="resume_goal")this.schedulePendingResume();if(W==="rewind_session"&&Array.isArray(D.data?.messages))this.messages=[...D.data.messages],this.contextMessages=await this.loadModelContextOr(D.data.messages);if((D.message==="compact_completed"||D.message==="compact_fallback")&&D.data?.compactedMessages){this.contextMessages=[...D.data.compactedMessages];let Z=await _.loadSession(this.id,this.cwd);if(Z.length>0)this.messages=Z}let Q=D.content||D.message;if(Q)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:Q}});if(D.error)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`[FAIL] ${D.error}`}});return await this.flushUpdates(),{stopReason:D.success?"end_turn":"cancelled"}}catch(H){return U.error(`[AcpSession ${this.id}] Slash command error:`,H),this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`[FAIL] 命令执行失败: ${H instanceof Error?H.message:"未知错误"}`}}),{stopReason:"cancelled"}}}async sendAvailableCommands(){try{let z=$z(this.cwd),J=["model","permissions","theme","config","exit","ide"],D=z.filter((W)=>!J.includes(W.name)).map((W)=>{let Q;if(W.usage){let Z=W.usage.replace(/^\/\w+\s*/,"").trim();if(Z)Q=Z}if(W.aliases?.length){let Z=`Aliases: ${W.aliases.join(", ")}`;Q=Q?`${Q} | ${Z}`:Z}return{name:W.name,description:W.description,input:Q?{hint:Q}:void 0}});U.info(`[AcpSession ${this.id}] Sending available commands: ${JSON.stringify(D.map((W)=>W.name))}`),this.sendUpdate({sessionUpdate:"available_commands_update",availableCommands:D}),U.info(`[AcpSession ${this.id}] Sent ${D.length} available commands`)}catch(z){U.error(`[AcpSession ${this.id}] Failed to send available commands:`,z)}}async prompt(z,J={}){if(P.setCurrentSession(this.id),!this.agent||!this.runtime)throw Error("Session not initialized");let H=this.resolvePrompt(z.prompt),D=H.content,W=H.displayText,Q=z._meta?.outputSchema??(J.pendingInputOnly?this.runtime.getPendingSteeringMessages().find((L)=>L.outputSchema)?.outputSchema:void 0),Z;if(Q!==void 0)Z=d(Q).schema;if(W.trimStart().startsWith("!")){if(Z)throw Error("Output schemas cannot be combined with user shell commands");return this.handleUserShellCommand(W)}if(this.pendingPrompt){if(Z)throw Error("Wait for the active turn to finish before setting an output schema");if(/^\/goal(?:\s|$)/i.test(W.trim()))return this.handleSlashCommand(W,this.pendingPrompt.signal);let L=await this.runtime.enqueueSteering(D,{allowBeforeTurn:!0});if(!L.accepted)throw Error(L.reason==="queue_full"?"Active turn steering queue is full":"Active turn is no longer steerable");if(U.debug(`[AcpSession ${this.id}] Queued steering for active turn (${L.queued})`),L.delivery==="next_turn")this.schedulePendingResume();return{stopReason:"end_turn"}}let X=new AbortController,Y,F=new Promise((L)=>{Y=L});this.pendingPrompt=X,this.pendingPromptCompletion=F;try{if(U.debug(`[AcpSession ${this.id}] Received prompt: ${W.slice(0,100)}...`),Jz(W)){if(Z)throw Error("Output schemas cannot be combined with slash commands");return await this.handleSlashCommand(W,X.signal)}let L={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($)}}},B=await l(this.agent.chatStream(D,L,{pendingInputOnly:J.pendingInputOnly,goalContinuationOnly:J.goalContinuationOnly,outputSchema:Z}),async($)=>{switch($.kind){case"content_delta":if(Z)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 G=$.toolCall,K=G.function.name;if(K===q)break;let R=this.mapToolKind($.toolKind),j=`Executing ${K}`;if(K==="Task"&&"function"in G)try{let O=JSON.parse(G.function.arguments),V=O.resume_from??O.resume;if(typeof V==="string")j=`Resuming ${String(O.subagent_type||"subagent")} from ${V}`}catch{}this.sendUpdate({sessionUpdate:"tool_call",toolCallId:G.id,status:"in_progress",title:j,content:[],kind:R});break}case"tool_progress":{let G=$.toolCall;if(G.function.name===q)break;this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:G.id,status:"in_progress",content:[{type:"content",content:{type:"text",text:$.update.message}}]});break}case"tool_result":{let G=$.toolCall;if(G.function.name===q)break;let K=$.result,R=[],j=K.metadata;if(j?.kind==="patch"&&Array.isArray(j.changes))for(let V of j.changes){if(!V||typeof V!=="object"||!("path"in V)||typeof V.path!=="string")continue;R.push({type:"diff",path:V.path,oldText:"oldContent"in V&&typeof V.oldContent==="string"?V.oldContent:null,newText:"newContent"in V&&typeof V.newContent==="string"?V.newContent:null})}else if(j?.kind==="edit"&&typeof j.file_path==="string"&&typeof j.oldContent==="string"&&(typeof j.newContent==="string"||j.newContent===void 0))R.push({type:"diff",path:j.file_path,oldText:j.oldContent,newText:j.newContent??null});else{let V=G.function.name,Vz=o(v(a(V,K),c));R.push({type:"content",content:{type:"text",text:Vz}})}if(G.function.name==="Task"&&(j?.verificationVerdict==="pass"||j?.verificationVerdict==="fail"||j?.verificationVerdict==="partial"))R.unshift({type:"content",content:{type:"text",text:`Verification result: ${j.verificationVerdict.toUpperCase()}`}});let O=K.success?"completed":"failed";this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:G.id,status:O,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 T}from"./chunk-232bcv23.js";import{t as jz,u as t,v as s,w as e,x as zz,y as Hz}from"./chunk-dgks1che.js";import{C as P,L as r,O as a,P as o,S as n,ea as Jz,fa as Qz,ga as Zz,ha as $z}from"./chunk-g5429yjs.js";import{ra as _z}from"./chunk-0nvc6y56.js";import"./chunk-gh0vdddb.js";import{Va as m,ib as l,rb as i}from"./chunk-9hjhbsna.js";import{Ab as h}from"./chunk-5cgyevqj.js";import{Tb as g,_b as c,bc as p,jc as S,kc as v,mc as q,pc as d,uc as N,xc as _}from"./chunk-d63dczf8.js";import"./chunk-qgez5vw6.js";import"./chunk-atdb1pks.js";import{$c as Gz}from"./chunk-x4yfhp8j.js";import"./chunk-0evyrnx0.js";import"./chunk-5cjy9yj1.js";import"./chunk-v508x7cg.js";import{Gd as Lz}from"./chunk-atsw605q.js";import"./chunk-jd764yqg.js";import"./chunk-ahkpjvaq.js";import{Rd as Bz}from"./chunk-3rjmkaey.js";import"./chunk-46r1m8yn.js";import"./chunk-rtzd076h.js";import"./chunk-hq18c6r9.js";import{we as Uz}from"./chunk-zwt7f9ab.js";import"./chunk-ckfc7j7m.js";import"./chunk-r48jmc74.js";import"./chunk-v11r4ahz.js";import"./chunk-vk3e2w5h.js";import"./chunk-a7pvtxvz.js";import"./chunk-93jx06kq.js";import{Hf as y,If as u,Jf as I}from"./chunk-thstqcg3.js";import{Nf as Xz}from"./chunk-6360fg4j.js";import"./chunk-jtv91ez8.js";import{Yf as x}from"./chunk-0dw58ycv.js";import"./chunk-cm4t4cz6.js";import{dg as Yz,gg as Fz}from"./chunk-asqah231.js";import"./chunk-b6ve4vyt.js";import"./chunk-tczrjn95.js";import"./chunk-m0a2zdm8.js";import"./chunk-qc5qwgpt.js";import"./chunk-jtjcg93t.js";import{Readable as Ez,Writable as qz}from"node:stream";import*as b from"@agentclientprotocol/sdk";import Wz from"node:path";import{PROTOCOL_VERSION as Pz}from"@agentclientprotocol/sdk";import{RequestError as Az}from"@agentclientprotocol/sdk";import{nanoid as M}from"nanoid";var U=x("Agent");function f(z){if(!z)return{};return Object.fromEntries(z.map((J)=>[J.name,J.value]))}function Kz(z){if("command"in z)return{type:"stdio",command:z.command,args:z.args,env:f(z.env)};if("url"in z)return{type:z.type,url:z.url,headers:f("headers"in z?z.headers:void 0)};return null}function Rz(z){let J={};for(let H of z){let D=Kz(H);if(D)J[H.name]=D}return J}function Dz(z){if(typeof z==="string")return z?[{type:"text",text:z}]:[];return z.flatMap((J)=>{if(J.type==="text")return J.text?[{type:"text",text:J.text}]:[];let H=J.image_url.url,D=/^data:([^;,]+);base64,(.+)$/s.exec(H);if(!D)return[{type:"text",text:"[Image]"}];return[{type:"image",mimeType:D[1]??"image/png",data:D[2]??""}]})}function Nz(z){let J=v(z.metadata);return J?[{type:"text",text:S(J)}]:Dz(z.content)}function Oz(z){return[`Status: ${z.status}`,`Exit code: ${z.exitCode??"null"}`,`Duration: ${(z.durationMs/1000).toFixed(3)} seconds`].join(`
2
+ `)}class E{id;cwd;connection;clientCapabilities;options;agent=null;runtime=null;pendingPrompt=null;pendingPromptCompletion=null;pendingUserShell=null;pendingUserShellCompletion=null;pendingResumeRequested=!1;availableCommandsTimer=null;taskStatusUnsubscribe;destroyed=!1;destroyFinished=!1;destroyPromise;messages;contextMessages;mode;updateEgress;constructor(z,J,H,D,W={}){this.id=z;this.cwd=J;this.connection=H;this.clientCapabilities=D;this.options=W;this.messages=[...W.initialMessages??[]],this.contextMessages=[...this.messages],this.mode=this.mapPermissionModeToMode(W.permissionMode),this.updateEgress=new Hz({maxPendingItems:t,maxPendingBytes:s,writeTimeoutMs:e,signal:H.signal,sizeOf:(Q)=>Buffer.byteLength(JSON.stringify(Q)),write:async(Q)=>{await H.sessionUpdate(Q)},onFailure:(Q)=>this.handleUpdateEgressFailure(Q)})}async refreshPersistedMessages(){let[z,J]=await Promise.all([_.loadSession(this.id,this.cwd),_.loadSessionModelContext(this.id,this.cwd)]);if(z.length>0)this.messages=z;if(J.length>0)this.contextMessages=J}async loadModelContextOr(z){let J=await _.loadSessionModelContext(this.id,this.cwd);return J.length>0?J:[...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 n.createWithRuntime(this.runtime,{sessionId:this.id,...this.options.taskWorktree?{toolBlacklist:["EnterWorktree","ExitWorktree"]}:{}})}async initialize(){if(U.debug(`[AcpSession ${this.id}] Initializing...`),await _.setSessionPermissionMode(this.id,this.cwd,this.mapModeToPermissionMode()??"default"),P.initializeSession(this.connection,this.id,this.clientCapabilities,this.cwd,async(Q)=>{await this.sendUpdateAndWait(Q)}),U.debug(`[AcpSession ${this.id}] ACP service context initialized`),await i.resolvePendingWithHandler(this.cwd,this.id,{requestConfirmation:(Q)=>this.requestPermission(Q)}))await this.refreshPersistedMessages();else if((this.options.initialMessages?.length??0)>0)this.contextMessages=await this.loadModelContextOr(this.options.initialMessages??[]);let J=this.options.mcpServers?Rz(this.options.mcpServers):void 0,H=P.getInstance().getTerminalService(this.id);if(this.runtime=await r.create({sessionId:this.id,workspaceRoot:this.cwd,permissionMode:this.mapModeToPermissionMode(),...J?{mcpServers:J}:{},...this.options.taskWorktree?{taskWorktree:this.options.taskWorktree}:{},...this.options.taskIsolation?{taskIsolation:this.options.taskIsolation}:{},userShellExecutor:{execute:async(Q,Z)=>{let X=await H.execute(Q,{cwd:Z.cwd,env:Z.env,timeout:Z.timeoutMs,signal:Z.signal,allowLocalFallback:!1,onOutput:(Y)=>Z.onOutput?.("stdout",Y)});return{exitCode:X.exitCode,stdout:X.stdout,stderr:X.stderr,...X.error?{error:X.error}:{},timedOut:X.failureKind==="timeout",aborted:X.failureKind==="aborted"}}},...(this.options.initialMessages?.length??0)>0?{sessionStart:{isResume:!0,resumeSessionId:this.id}}:{}}),await T.recoverInterrupted(this.cwd,this.id,this.runtime))await this.refreshPersistedMessages();this.agent=await this.createAgent(),await Qz(this.cwd),U.debug(`[AcpSession ${this.id}] Agent created successfully`),this.taskStatusUnsubscribe?.(),this.taskStatusUnsubscribe=m.subscribe((Q)=>{if(Q.sessionId!==this.id||Q.projectPath!==this.cwd)return;if(Q.type==="subagent.completion.queued"){this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:new Date().toISOString(),_meta:{"blade/backgroundSubagentCompletion":Q.properties}}),this.schedulePendingResume();return}if(Q.type==="task.delivery"){if(!Q.properties.taskDelivery||typeof Q.properties.taskDelivery!=="object")return;this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:typeof Q.properties.updatedAt==="string"?Q.properties.updatedAt:new Date().toISOString(),_meta:{"blade/taskDelivery":Q.properties.taskDelivery,...Q.properties.taskWorktreeRemoved===!0?{"blade/taskWorktreeRemoved":!0}:{}}});return}if(Q.type!=="task.status")return;this.sendUpdate({sessionUpdate:"session_info_update",updatedAt:typeof Q.properties.updatedAt==="string"?Q.properties.updatedAt:new Date().toISOString(),_meta:{"blade/taskStatus":Q.properties.taskStatus,...typeof Q.properties.taskStatusReason==="string"?{"blade/taskStatusReason":Q.properties.taskStatusReason}:{},...Q.properties.taskFailure&&typeof Q.properties.taskFailure==="object"?{"blade/taskFailure":Q.properties.taskFailure}:{},...typeof Q.properties.taskStartedAt==="string"?{"blade/taskStartedAt":Q.properties.taskStartedAt}:{},...typeof Q.properties.taskCompletedAt==="string"?{"blade/taskCompletedAt":Q.properties.taskCompletedAt}:{},...Q.properties.taskDiffStat&&typeof Q.properties.taskDiffStat==="object"?{"blade/taskDiffStat":Q.properties.taskDiffStat}:{},...typeof Q.properties.taskQueuePosition==="number"?{"blade/taskQueuePosition":Q.properties.taskQueuePosition}:{},...typeof Q.properties.taskQueueDepth==="number"?{"blade/taskQueueDepth":Q.properties.taskQueueDepth}:{},...typeof Q.properties.taskConcurrencyLimit==="number"?{"blade/taskConcurrencyLimit":Q.properties.taskConcurrencyLimit}:{},...typeof Q.properties.taskInFlight==="number"?{"blade/taskInFlight":Q.properties.taskInFlight}:{}}})});let W=await this.runtime.getGoal();if(this.runtime.getPendingSteeringCount()>0||W?.status==="active"||W?.status==="verifying")if(this.options.initialMessages===void 0)this.schedulePendingResume();else this.pendingResumeRequested=!0}async replayHistory(){for(let J of this.messages){if(!this.canSendUpdates())return;let H=J.role==="user"?"user_message_chunk":J.role==="assistant"?"agent_message_chunk":void 0;if(!H)continue;for(let D of Nz(J)){if(!this.canSendUpdates())return;if(!await this.sendUpdateAndWait({sessionUpdate:H,content:D}))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);U.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,J){try{U.debug(`[AcpSession ${this.id}] Executing slash command: ${z}`);let H={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(Z)=>{if(!this.runtime)throw Error("Session runtime is unavailable");let X=await this.runtime.rewindSession(Z);return this.messages=[...X.messages],this.contextMessages=await this.loadModelContextOr(X.messages),await this.agent?.destroy(),this.agent=await this.createAgent(),X}},reasoning:{get:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getReasoningConfiguration()},set:async(Z)=>{if(await this.setReasoningEffort(Z),!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(Z)=>{if(await this.setServiceTier(Z),!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(Z)=>{if(await this.setResponseVerbosity(Z),!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(Z)=>{if(await this.setCommunicationStyle(Z),!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(Z,X)=>{if(!this.runtime)throw Error("Session runtime is unavailable");let Y=!1,F,L=(A)=>{this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:A.id,status:A.status==="completed"?"completed":"failed",content:[{type:"content",content:{type:"text",text:A.result?.message||A.result?.error||`Subagent ${A.status}`}}]})},B=this.runtime.resumeSubagent({agentId:Z,prompt:X,onCompleted:(A)=>{if(Y)L(A);else F=A}});if(this.sendUpdate({sessionUpdate:"tool_call",toolCallId:B.session.id,status:"in_progress",title:`Resuming ${B.session.subagentType} subagent`,content:[{type:"content",content:{type:"text",text:`Resumed from ${B.source.id} at depth ${B.session.resumeDepth}`}}],kind:this.mapToolKind("readonly")}),Y=!0,F)L(F);return B}},mcp:{getCatalog:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpContentCatalog()},refresh:async(Z)=>{if(!this.runtime)throw Error("Session runtime is unavailable");await this.runtime.refreshMcpContentCatalogs(Z)},getPrompt:async(Z,X,Y)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpPrompt(Z,X,Y)},complete:async(Z,X,Y)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.completeMcpArgument(Z,X,Y)},listTasks:async(Z)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.listMcpTasks(Z)},getTask:async(Z)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpTask(Z)},cancelTask:async(Z,X)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.cancelMcpTask(Z,X)},getLogs:async(Z,X)=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpLogs(Z,X)},setLoggingLevel:async(Z,X)=>{if(!this.runtime)throw Error("Session runtime is unavailable");await this.runtime.setMcpLoggingLevel(Z,X)},getInstructions:async()=>{if(!this.runtime)throw Error("Session runtime is unavailable");return this.runtime.getMcpInstructions()}},codeReview:{run:async(Z,X)=>{if(!this.runtime)throw Error("Session runtime is unavailable");let Y=await T.start({sessionId:this.id,projectPath:this.cwd,runtime:this.runtime,request:Z,signal:X,onEvent:(B)=>{if(B.kind==="tool_start")this.sendUpdate({sessionUpdate:"tool_call",toolCallId:B.toolCall.id,status:"in_progress",title:`Review: ${B.toolCall.function.name}`,content:[],kind:this.mapToolKind(B.toolKind)});else if(B.kind==="tool_result")this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:B.toolCall.id,status:B.result.success?"completed":"failed",content:[]})}}),F=await Y.completion,L=(await T.list(this.cwd,this.id)).find((B)=>B.start.reviewId===Y.reviewId);if(!L)throw Error(`Review not found: ${Y.reviewId}`);return await this.refreshPersistedMessages(),{reviewId:Y.reviewId,status:F.status,findings:F.findings.length,content:g(L.start,F)}}},signal:J,acp:{sendMessage:(Z)=>{this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:Z}})},sendToolStart:(Z,X,Y)=>{let F=`tool_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,L=this.mapToolKind(Y);this.sendUpdate({sessionUpdate:"tool_call",toolCallId:F,status:"in_progress",title:`${Z}`,content:[{type:"content",content:{type:"text",text:JSON.stringify(X,null,2)}}],kind:L})},sendToolResult:(Z,X)=>{if(X.summary)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:X.summary}})}}},D=await Zz(z,H),W=D.data?.action;if(W==="start_goal"||W==="resume_goal")this.schedulePendingResume();if(W==="rewind_session"&&Array.isArray(D.data?.messages))this.messages=[...D.data.messages],this.contextMessages=await this.loadModelContextOr(D.data.messages);if((D.message==="compact_completed"||D.message==="compact_fallback")&&D.data?.compactedMessages){this.contextMessages=[...D.data.compactedMessages];let Z=await _.loadSession(this.id,this.cwd);if(Z.length>0)this.messages=Z}let Q=D.content||D.message;if(Q)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:Q}});if(D.error)this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`[FAIL] ${D.error}`}});return await this.flushUpdates(),{stopReason:D.success?"end_turn":"cancelled"}}catch(H){return U.error(`[AcpSession ${this.id}] Slash command error:`,H),this.sendUpdate({sessionUpdate:"agent_message_chunk",content:{type:"text",text:`[FAIL] 命令执行失败: ${H instanceof Error?H.message:"未知错误"}`}}),{stopReason:"cancelled"}}}async sendAvailableCommands(){try{let z=$z(this.cwd),J=["model","permissions","theme","config","exit","ide"],D=z.filter((W)=>!J.includes(W.name)).map((W)=>{let Q;if(W.usage){let Z=W.usage.replace(/^\/\w+\s*/,"").trim();if(Z)Q=Z}if(W.aliases?.length){let Z=`Aliases: ${W.aliases.join(", ")}`;Q=Q?`${Q} | ${Z}`:Z}return{name:W.name,description:W.description,input:Q?{hint:Q}:void 0}});U.info(`[AcpSession ${this.id}] Sending available commands: ${JSON.stringify(D.map((W)=>W.name))}`),this.sendUpdate({sessionUpdate:"available_commands_update",availableCommands:D}),U.info(`[AcpSession ${this.id}] Sent ${D.length} available commands`)}catch(z){U.error(`[AcpSession ${this.id}] Failed to send available commands:`,z)}}async prompt(z,J={}){if(P.setCurrentSession(this.id),!this.agent||!this.runtime)throw Error("Session not initialized");let H=this.resolvePrompt(z.prompt),D=H.content,W=H.displayText,Q=z._meta?.outputSchema??(J.pendingInputOnly?this.runtime.getPendingSteeringMessages().find((L)=>L.outputSchema)?.outputSchema:void 0),Z;if(Q!==void 0)Z=d(Q).schema;if(W.trimStart().startsWith("!")){if(Z)throw Error("Output schemas cannot be combined with user shell commands");return this.handleUserShellCommand(W)}if(this.pendingPrompt){if(Z)throw Error("Wait for the active turn to finish before setting an output schema");if(/^\/goal(?:\s|$)/i.test(W.trim()))return this.handleSlashCommand(W,this.pendingPrompt.signal);let L=await this.runtime.enqueueSteering(D,{allowBeforeTurn:!0});if(!L.accepted)throw Error(L.reason==="queue_full"?"Active turn steering queue is full":"Active turn is no longer steerable");if(U.debug(`[AcpSession ${this.id}] Queued steering for active turn (${L.queued})`),L.delivery==="next_turn")this.schedulePendingResume();return{stopReason:"end_turn"}}let X=new AbortController,Y,F=new Promise((L)=>{Y=L});this.pendingPrompt=X,this.pendingPromptCompletion=F;try{if(U.debug(`[AcpSession ${this.id}] Received prompt: ${W.slice(0,100)}...`),Jz(W)){if(Z)throw Error("Output schemas cannot be combined with slash commands");return await this.handleSlashCommand(W,X.signal)}let L={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($)}}},B=await l(this.agent.chatStream(D,L,{pendingInputOnly:J.pendingInputOnly,goalContinuationOnly:J.goalContinuationOnly,outputSchema:Z}),async($)=>{switch($.kind){case"content_delta":if(Z)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 G=$.toolCall,K=G.function.name;if(K===q)break;let R=this.mapToolKind($.toolKind),j=`Executing ${K}`;if(K==="Task"&&"function"in G)try{let O=JSON.parse(G.function.arguments),V=O.resume_from??O.resume;if(typeof V==="string")j=`Resuming ${String(O.subagent_type||"subagent")} from ${V}`}catch{}this.sendUpdate({sessionUpdate:"tool_call",toolCallId:G.id,status:"in_progress",title:j,content:[],kind:R});break}case"tool_progress":{let G=$.toolCall;if(G.function.name===q)break;this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:G.id,status:"in_progress",content:[{type:"content",content:{type:"text",text:$.update.message}}]});break}case"tool_result":{let G=$.toolCall;if(G.function.name===q)break;let K=$.result,R=[],j=K.metadata;if(j?.kind==="patch"&&Array.isArray(j.changes))for(let V of j.changes){if(!V||typeof V!=="object"||!("path"in V)||typeof V.path!=="string")continue;R.push({type:"diff",path:V.path,oldText:"oldContent"in V&&typeof V.oldContent==="string"?V.oldContent:null,newText:"newContent"in V&&typeof V.newContent==="string"?V.newContent:null})}else if(j?.kind==="edit"&&typeof j.file_path==="string"&&typeof j.oldContent==="string"&&(typeof j.newContent==="string"||j.newContent===void 0))R.push({type:"diff",path:j.file_path,oldText:j.oldContent,newText:j.newContent??null});else{let V=G.function.name,Vz=o(p(a(V,K),c));R.push({type:"content",content:{type:"text",text:Vz}})}if(G.function.name==="Task"&&(j?.verificationVerdict==="pass"||j?.verificationVerdict==="fail"||j?.verificationVerdict==="partial"))R.unshift({type:"content",content:{type:"text",text:`Verification result: ${j.verificationVerdict.toUpperCase()}`}});let O=K.success?"completed":"failed";this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:G.id,status:O,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,7 +7,7 @@ import{s as T}from"./chunk-95n8g52h.js";import{t as jz,u as t,v as s,w as e,x as
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_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}:{}}}});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 G of $.messages){if(!G.recovered||G.persisted)continue;for(let K of Dz(G.content))this.sendUpdate({sessionUpdate:"user_message_chunk",content:K})}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_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 G of $.messages){if(!G.recovered||G.persisted)continue;for(let K of Dz(G.content))this.sendUpdate({sessionUpdate:"user_message_chunk",content:K})}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
12
  `}});break;case"goal_continuation_started":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}:{},...$.postTokens!==void 0?{postTokens:$.postTokens}:{}}}});break;default:break}if(!await this.flushUpdates())X.abort("acp-egress-failed")});if(!await this.flushUpdates())X.abort("acp-egress-failed");this.contextMessages=[...L.messages];let A=await _.loadSession(this.id,this.cwd);if(this.messages=A.length>0?A:[...L.messages],!B.success){let $=B.error?.type??"unknown";throw Az.internalError({failureType:$},`Agent turn failed (${$})`)}if(X.signal.aborted)return{stopReason:"cancelled"};let C={...B.metadata?.structuredOutput?{structuredOutput:B.metadata.structuredOutput,outputSchemaDigest:B.metadata.structuredOutputSchemaDigest}:{},...B.metadata?.goalCompletionVerified?{goalCompletion:{verified:!0,verdict:B.metadata.goalVerificationVerdict,...B.metadata.goalVerifierSessionId?{verifierSessionId:B.metadata.goalVerifierSessionId}:{},...B.metadata.goalVerificationEvidenceSha256?{evidenceSha256:B.metadata.goalVerificationEvidenceSha256}:{}}}:{}};return{stopReason:"end_turn",...Object.keys(C).length>0?{_meta:C}:{}}}catch(L){if(X.signal.aborted||L instanceof Error&&L.name==="AbortError")return{stopReason:"cancelled"};throw U.error(`[AcpSession ${this.id}] Prompt error:`,L),L}finally{if(Y(),this.pendingPromptCompletion===F)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 J=z.trimStart().slice(1).trim();if(!J)throw Error("User shell command cannot be empty");let H=new AbortController,D,W=new Promise((X)=>{D=X});this.pendingUserShell=H,this.pendingUserShellCompletion=W;let Q,Z="";try{let X=await this.runtime.executeUserShellCommand(J,{signal:H.signal,onEvent:async(F)=>{if(Q=F.executionId,F.type==="started"){this.sendUpdate({sessionUpdate:"tool_call",toolCallId:F.executionId,status:"in_progress",title:`! ${F.command}`,content:[],kind:"execute"});return}if(F.type==="output"){Z+=F.chunk,this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:F.executionId,status:"in_progress",content:[{type:"content",content:{type:"text",text:F.chunk}}]});return}let L=S(F.record);this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:F.executionId,status:F.record.status==="completed"?"completed":"failed",content:[{type:"content",content:{type:"text",text:Z?Oz(F.record):L}}]})}}),Y={role:"user",content:X.modelContent,metadata:{userShellCommand:JSON.parse(JSON.stringify(X.record))}};if(this.messages.push(Y),this.contextMessages.push(Y),X.delivery==="next_turn")this.schedulePendingResume();if(!await this.flushUpdates())return H.abort("acp-egress-failed"),{stopReason:"cancelled"};return{stopReason:X.record.status==="aborted"?"cancelled":"end_turn"}}catch(X){if(Q)this.sendUpdate({sessionUpdate:"tool_call_update",toolCallId:Q,status:"failed",content:[{type:"content",content:{type:"text",text:X instanceof Error?X.message:String(X)}}]});if(H.signal.aborted)return{stopReason:"cancelled"};throw X}finally{if(D(),this.pendingUserShellCompletion===W)this.pendingUserShellCompletion=null;if(this.pendingUserShell===H)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,J=z?null:await this.runtime.getGoal(),H=J?.status==="active"||J?.status==="verifying";if(!z&&!H){this.pendingResumeRequested=!1;return}this.pendingResumeRequested=!1,await this.prompt({sessionId:this.id,prompt:[]},{pendingInputOnly:z,goalContinuationOnly:H}).catch((D)=>{U.error(`[AcpSession ${this.id}] Failed to resume pending input:`,D)})}cancel(){U.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(!z)U.warn(`[AcpSession ${this.id}] No pending prompt to cancel`)}async setMode(z){let H=["default","auto-edit","yolo","plan"].includes(z)?z:"default",D=this.mapModeIdToPermissionMode(H);await _.setSessionPermissionMode(this.id,this.cwd,D),this.mode=H,U.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(U.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 J=this.runtime.getCurrentModelId();await this.agent.switchModel(z);try{try{await _.updateSessionMetadata(this.id,this.cwd,{selectedModelId:z})}catch(H){if(!(H instanceof N)&&H.code!=="ENOENT")throw H;await _.createSessionMetadata(this.id,this.cwd,{taskStatus:"completed",selectedModelId:z})}}catch(H){if(J&&J!==z)await this.agent.switchModel(J).catch((D)=>{U.error(`[AcpSession ${this.id}] Failed to roll back a non-durable model switch:`,D)});throw H}}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 J=this.runtime.getReasoningConfiguration();try{this.runtime.resolveReasoningConfiguration(z)}catch(H){throw Error(H instanceof Error?H.message:"Invalid reasoning effort")}if(J.selection===z)return;await this.runtime.refresh({reasoningEffort:z});try{try{await _.updateSessionMetadata(this.id,this.cwd,{reasoningEffort:z})}catch(H){if(!(H instanceof N)&&H.code!=="ENOENT")throw H;await _.createSessionMetadata(this.id,this.cwd,{taskStatus:"completed",selectedModelId:this.runtime.getCurrentModelId(),reasoningEffort:z})}}catch(H){throw await this.runtime.refresh({reasoningEffort:J.selection}),H}}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 J=this.runtime.getServiceTierConfiguration();try{this.runtime.resolveServiceTierConfiguration(z)}catch(H){throw Error(H instanceof Error?H.message:"Invalid service tier")}if(J.selection===z)return;await this.runtime.refresh({serviceTier:z});try{try{await _.updateSessionMetadata(this.id,this.cwd,{serviceTier:z})}catch(H){if(!(H instanceof N)&&H.code!=="ENOENT")throw H;await _.createSessionMetadata(this.id,this.cwd,{taskStatus:"completed",selectedModelId:this.runtime.getCurrentModelId(),serviceTier:z})}}catch(H){throw await this.runtime.refresh({serviceTier:J.selection}),H}}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 J=this.runtime.getResponseVerbosityConfiguration();try{this.runtime.resolveResponseVerbosityConfiguration(z)}catch(H){throw Error(H instanceof Error?H.message:"Invalid response verbosity")}if(J.selection===z)return;await this.runtime.refresh({responseVerbosity:z});try{try{await _.updateSessionMetadata(this.id,this.cwd,{responseVerbosity:z})}catch(H){if(!(H instanceof N)&&H.code!=="ENOENT")throw H;await _.createSessionMetadata(this.id,this.cwd,{taskStatus:"completed",selectedModelId:this.runtime.getCurrentModelId(),responseVerbosity:z})}}catch(H){throw await this.runtime.refresh({responseVerbosity:J.selection}),H}}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 J=this.runtime.getCommunicationStyleConfiguration(),H=this.runtime.resolveCommunicationStyleConfiguration(z);if(H.source!=="built-in"&&!H.contentSha256)throw Error("Custom communication style has no provenance");if(J.selection===z)return;await this.runtime.refresh({communicationStyle:z});try{try{await _.updateSessionMetadata(this.id,this.cwd,{communicationStyle:z,communicationStyleDigest:H.source==="built-in"?null:H.contentSha256})}catch(D){if(!(D instanceof N)&&D.code!=="ENOENT")throw D;await _.createSessionMetadata(this.id,this.cwd,{taskStatus:"completed",selectedModelId:this.runtime.getCurrentModelId(),communicationStyle:z,...H.source!=="built-in"&&H.contentSha256?{communicationStyleDigest:H.contentSha256}:{}})}}catch(D){throw await this.runtime.refresh({communicationStyle:J.selection}),D}}getModelConfiguration(){if(!this.runtime)return;let z=this.runtime.getConfig();return{currentModelId:this.runtime.getCurrentModelId()??z.currentModelId,models:z.models.map((J)=>structuredClone(J)),modelProviders:structuredClone(z.modelProviders),reasoning:this.runtime.getReasoningConfiguration(),serviceTier:this.runtime.getServiceTierConfiguration(),responseVerbosity:this.runtime.getResponseVerbosityConfiguration(),communicationStyle:this.runtime.getCommunicationStyleConfiguration()}}getMode(){return this.mode}destroy(){if(this.destroyPromise)return this.destroyFinished?Promise.resolve():this.destroyPromise;return this.destroyPromise=this.destroyOwnedResources().finally(()=>{this.destroyFinished=!0}),this.destroyPromise}async destroyOwnedResources(){if(this.destroyed=!0,this.updateEgress.close(new zz("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,H=this.pendingPromptCompletion,D=this.pendingUserShellCompletion;this.agent=null,this.runtime=null;let W,Q=async(Z)=>{try{await Z()}catch(X){W??=X}};if(await Q(()=>this.cancel()),H)await Q(()=>H);if(D)await Q(()=>D);if(z)await Q(()=>z.destroy());if(J)await Q(()=>J.dispose());if(await Q(()=>P.destroySession(this.id)),U.debug(`[AcpSession ${this.id}] Destroyed`),W!==void 0)throw W}resolvePrompt(z){let J=[],H=[],D=0,W=0,Q=0,Z=(Y)=>{if(H.length>0)H.push({type:"text",text:`
13
13
  `}),Q+=1;if(H.push(Y),Y.type==="text")Q+=Y.text.length};for(let Y of z)if(Y.type==="text")J.push(Y.text),Z({type:"text",text:Y.text});else if(Y.type==="image"){let F=`data:${Y.mimeType};base64,${Y.data}`;D+=1,W+=F.length,J.push(`[Image: ${Y.mimeType}]`),Z({type:"image_url",image_url:{url:F}})}else if(Y.type==="resource"){let F=Y.resource;if("text"in F){let L=`<file path="${F.uri}">
@@ -1,4 +1,4 @@
1
- import{ra as H}from"./chunk-7c5tnz4y.js";import"./chunk-5cgyevqj.js";import"./chunk-qgez5vw6.js";import{Fd as T,zd as $}from"./chunk-e23sz81n.js";import"./chunk-v508x7cg.js";import"./chunk-atsw605q.js";import"./chunk-cc7dmst6.js";import"./chunk-v11r4ahz.js";import"./chunk-515mkr66.js";import"./chunk-a7pvtxvz.js";import"./chunk-93jx06kq.js";import"./chunk-thstqcg3.js";import{Nf as k}from"./chunk-6360fg4j.js";import"./chunk-qvdcesry.js";import"./chunk-2mvp3rqw.js";import"./chunk-g510tpqt.js";import"./chunk-gy8esxaa.js";import"./chunk-m6dh31kb.js";import"./chunk-0dj2qm8a.js";import"./chunk-y9nq48st.js";import"./chunk-4s0c6tkd.js";import U from"os";import J from"path";function X(z){return typeof z==="string"?z:void 0}function N(z){if(!Array.isArray(z))return;let q=[];for(let K of z)if(typeof K==="string")q.push(K);else if(K!=null)q.push(String(K));return q}function b(){console.log(`
1
+ import{ra as H}from"./chunk-0nvc6y56.js";import"./chunk-5cgyevqj.js";import"./chunk-qgez5vw6.js";import{Fd as T,zd as $}from"./chunk-5cjy9yj1.js";import"./chunk-v508x7cg.js";import"./chunk-atsw605q.js";import"./chunk-r48jmc74.js";import"./chunk-v11r4ahz.js";import"./chunk-vk3e2w5h.js";import"./chunk-a7pvtxvz.js";import"./chunk-93jx06kq.js";import"./chunk-thstqcg3.js";import{Nf as k}from"./chunk-6360fg4j.js";import"./chunk-jtv91ez8.js";import"./chunk-0dw58ycv.js";import"./chunk-cm4t4cz6.js";import"./chunk-asqah231.js";import"./chunk-b6ve4vyt.js";import"./chunk-tczrjn95.js";import"./chunk-m0a2zdm8.js";import"./chunk-qc5qwgpt.js";import"./chunk-jtjcg93t.js";import U from"os";import J from"path";function X(z){return typeof z==="string"?z:void 0}function N(z){if(!Array.isArray(z))return;let q=[];for(let K of z)if(typeof K==="string")q.push(K);else if(K!=null)q.push(String(K));return q}function b(){console.log(`
2
2
  blade mcp
3
3
  `),console.log(`管理 MCP 服务器
4
4
  `),console.log("Commands:"),console.log(" blade mcp add <name> <commandOrUrl> [args...] 添加 MCP 服务器"),console.log(" blade mcp remove <name> 删除 MCP 服务器 [aliases: rm]"),console.log(" blade mcp list 列出所有 MCP 服务器并检查健康状态 [aliases: ls]"),console.log(" blade mcp get <name> 获取服务器详情"),console.log(" blade mcp login <name> 登录远程 MCP OAuth"),console.log(" blade mcp logout <name> 清除远程 MCP OAuth 凭证"),console.log(` blade mcp add-json <name> <json> 从 JSON 字符串添加服务器
@@ -1,2 +1,2 @@
1
- import{ug as F}from"./chunk-4s0c6tkd.js";import{execSync as G}from"node:child_process";import*as C from"node:os";import*as v from"node:path";function H(k){return v.resolve(k).replace(/[/\\]/g,"-").replace(/:/g,"_")}function M(k){let q=k.replace(/_/g,":");if(q.startsWith("-"))q="/"+q.slice(1);return q.replace(/-/g,"/")}function z(k){let q=H(k);return v.join(E(),"projects",q)}function J(k){return typeof k==="string"&&k!=="."&&k!==".."&&/^[A-Za-z0-9_-][A-Za-z0-9._-]{0,199}$/.test(k)}function A(k){if(!J(k))throw Error(`Invalid session ID: ${k}`)}function N(k,q){return A(q),v.join(z(k),`${q}.jsonl`)}function O(k,q){return A(q),v.join(z(k),`${q}.inbox.json`)}function Q(k,q){return A(q),v.join(z(k),`${q}.goal.json`)}function T(k){try{return G("git rev-parse --abbrev-ref HEAD",{cwd:k,encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()||void 0}catch{return}}function E(){return process.env.BLADE_STORAGE_ROOT||v.join(C.homedir(),".blade")}async function U(){let{readdir:k}=await import("node:fs/promises");try{let q=v.join(E(),"projects");return(await k(q,{withFileTypes:!0})).filter((w)=>w.isDirectory()).map((w)=>w.name)}catch{return[]}}
2
- export{M as kg,z as lg,J as mg,A as ng,N as og,O as pg,Q as qg,T as rg,E as sg,U as tg};
1
+ import{Bg as F}from"./chunk-jtjcg93t.js";import{execSync as G}from"node:child_process";import*as C from"node:os";import*as v from"node:path";function H(k){return v.resolve(k).replace(/[/\\]/g,"-").replace(/:/g,"_")}function M(k){let q=k.replace(/_/g,":");if(q.startsWith("-"))q="/"+q.slice(1);return q.replace(/-/g,"/")}function z(k){let q=H(k);return v.join(E(),"projects",q)}function J(k){return typeof k==="string"&&k!=="."&&k!==".."&&/^[A-Za-z0-9_-][A-Za-z0-9._-]{0,199}$/.test(k)}function A(k){if(!J(k))throw Error(`Invalid session ID: ${k}`)}function N(k,q){return A(q),v.join(z(k),`${q}.jsonl`)}function O(k,q){return A(q),v.join(z(k),`${q}.inbox.json`)}function Q(k,q){return A(q),v.join(z(k),`${q}.goal.json`)}function T(k){try{return G("git rev-parse --abbrev-ref HEAD",{cwd:k,encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim()||void 0}catch{return}}function E(){return process.env.BLADE_STORAGE_ROOT||v.join(C.homedir(),".blade")}async function U(){let{readdir:k}=await import("node:fs/promises");try{let q=v.join(E(),"projects");return(await k(q,{withFileTypes:!0})).filter((w)=>w.isDirectory()).map((w)=>w.name)}catch{return[]}}
2
+ export{M as rg,z as sg,J as tg,A as ug,N as vg,O as wg,Q as xg,T as yg,E as zg,U as Ag};
@@ -0,0 +1 @@
1
+ import{jg as a,kg as b,lg as c,mg as d,ng as e,og as f}from"./chunk-b6ve4vyt.js";import"./chunk-jtjcg93t.js";export{b as getVersion,c as getPackageName,a as getPackageInfo,e as getFormattedVersion,d as getDescription,f as getCopyright};
@@ -1,4 +1,4 @@
1
- import{Ie as YO}from"./chunk-v11r4ahz.js";import{Bf as qO,Df as S,Gf as y}from"./chunk-93jx06kq.js";import{Nf as K}from"./chunk-6360fg4j.js";import{Rf as XO}from"./chunk-qvdcesry.js";import{jg as n}from"./chunk-0dj2qm8a.js";import{sg as r}from"./chunk-y9nq48st.js";import{ug as w}from"./chunk-4s0c6tkd.js";var N;((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"})(N||={});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 _ from"node:path";import{nanoid as z}from"nanoid";var C={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 jO from"node:path";import{createHash as JO}from"node:crypto";import{constants as s,promises as j}from"node:fs";import h from"node:path";import{Mutex as WO}from"async-mutex";import SO from"write-file-atomic";var k=1,GO=1048576,VO=/^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 LO(O){let q={};for(let Q of Object.values(N)){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(N))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(LO(O)));return`sha256:${JO("sha256").update(q).digest("hex")}`}class A{static instance=null;mutex=new WO;filePath;constructor(O=h.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 J;try{J=await this.readStore()}catch(G){return{...X,state:"error",error:G instanceof Error?G.message:"Hook trust store is unavailable"}}let W=J.projects[Z];if(!W)return{...X,state:"untrusted"};return{...X,state:W.digest===$?"trusted":"modified",trustedDigest:W.digest,trustedAt:W.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:k,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>GO)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!==k)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(!h.isAbsolute(Y)||!D($)||typeof $.digest!=="string"||!VO.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:k,projects:Z}}async writeStore(O){let q=h.dirname(this.filePath);await j.mkdir(q,{recursive:!0,mode:448}),await j.chmod(q,448),await SO(this.filePath,`${JSON.stringify(O,null,2)}
1
+ import{Ie as YO}from"./chunk-v11r4ahz.js";import{Bf as qO,Df as S,Gf as y}from"./chunk-93jx06kq.js";import{Nf as K}from"./chunk-6360fg4j.js";import{Yf as XO}from"./chunk-0dw58ycv.js";import{qg as n}from"./chunk-m0a2zdm8.js";import{zg as r}from"./chunk-qc5qwgpt.js";import{Bg as w}from"./chunk-jtjcg93t.js";var N;((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"})(N||={});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 _ from"node:path";import{nanoid as z}from"nanoid";var C={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 jO from"node:path";import{createHash as JO}from"node:crypto";import{constants as s,promises as j}from"node:fs";import h from"node:path";import{Mutex as WO}from"async-mutex";import SO from"write-file-atomic";var k=1,GO=1048576,VO=/^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 LO(O){let q={};for(let Q of Object.values(N)){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(N))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(LO(O)));return`sha256:${JO("sha256").update(q).digest("hex")}`}class A{static instance=null;mutex=new WO;filePath;constructor(O=h.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 J;try{J=await this.readStore()}catch(G){return{...X,state:"error",error:G instanceof Error?G.message:"Hook trust store is unavailable"}}let W=J.projects[Z];if(!W)return{...X,state:"untrusted"};return{...X,state:W.digest===$?"trusted":"modified",trustedDigest:W.digest,trustedAt:W.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:k,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>GO)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!==k)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(!h.isAbsolute(Y)||!D($)||typeof $.digest!=="string"||!VO.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:k,projects:Z}}async writeStore(O){let q=h.dirname(this.filePath);await j.mkdir(q,{recursive:!0,mode:448}),await j.chmod(q,448),await SO(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(zO(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(BO(Z)&&!q.allowLoopback)throw new T(`Loopback address blocked: ${Z}; enable policy.allowLoopback or add to allowedHosts`);if(AO(Z)&&!q.allowPrivateRanges)throw new T(`Private/link-local address blocked: ${Z}; enable policy.allowPrivateRanges or add to allowedHosts`)}function zO(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 BO(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 AO(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 KO=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()))}),PO=S.Object({hookEventName:S.Literal("PostToolUse"),additionalContext:S.Optional(S.String()),updatedOutput:S.Optional(S.Unknown())}),_O=S.Object({hookEventName:S.Literal("Stop"),continue:S.Optional(S.Boolean()),continueReason:S.Optional(S.String())}),UO=S.Object({hookEventName:S.Literal("SubagentStop"),continue:S.Optional(S.Boolean()),continueReason:S.Optional(S.String()),additionalContext:S.Optional(S.String())}),bO=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}),NO=S.Object({hookEventName:S.Literal("Elicitation"),action:S.Optional(y(["accept","decline","cancel"])),content:S.Optional(QO)}),MO=S.Object({hookEventName:S.Literal("ElicitationResult"),action:S.Optional(y(["accept","decline","cancel"])),content:S.Optional(QO)}),TO=S.Object({hookEventName:S.Literal("UserPromptSubmit"),updatedPrompt:S.Optional(S.String()),contextInjection:S.Optional(S.String())}),wO=S.Object({hookEventName:S.Literal("SessionStart"),env:S.Optional(S.Record(S.String(),S.String()))}),CO=S.Object({hookEventName:S.Literal("Compaction"),blockCompaction:S.Optional(S.Boolean()),blockReason:S.Optional(S.String())}),EO=S.Object({decision:S.Optional(S.Object({behavior:S.Enum(v)})),systemMessage:S.Optional(S.String()),hookSpecificOutput:S.Optional(S.Union([KO,PO,_O,UO,bO,NO,MO,TO,wO,CO])),suppressOutput:S.Optional(S.Boolean())});function ZO(O){return qO(EO,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",J=Q?.failureBehavior||"ignore",W=`Invalid hook output JSON: ${X}`;if(J==="deny")return{success:!1,blocking:!0,error:W,stdout:O.stdout,stderr:O.stderr,exitCode:O.exitCode,hook:q};else if(J==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${W}. Continue?`,stdout:O.stdout,stderr:O.stderr,exitCode:O.exitCode,hook:q};else return{success:!1,blocking:!1,warning:W,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 l{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 u{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:J}=YO(O,[],{shell:!0,env:$,cwd:Q.projectDir}),W=new l(this.MAX_STDOUT_SIZE),G=new l(this.MAX_STDERR_SIZE);X.stdout?.setEncoding("utf8"),X.stderr?.setEncoding("utf8"),X.stdout?.on("data",(L)=>{W.append(L)}),X.stderr?.on("data",(L)=>{G.append(L)});try{X.stdin?.write(Y),X.stdin?.end()}catch(L){throw await J.terminate(),Error(`Failed to write hook input: ${L}`)}return new Promise((L,R)=>{let F=!1,V=!1,B,P=()=>{return B??=J.terminate(),B},b=null,H=()=>{if(b&&Q.abortSignal)Q.abortSignal.removeEventListener("abort",b),b=null},I=setTimeout(()=>{F=!0,P()},Z);if(X.on("close",async(f)=>{if(V)return;if(V=!0,clearTimeout(I),H(),F)await P();L({stdout:W.getContent(),stderr:G.getContent(),exitCode:F?124:f??1,timedOut:F})}),X.on("error",(f)=>{if(V)return;V=!0,clearTimeout(I),H(),R(f)}),Q.abortSignal){if(b=()=>{if(V)return;V=!0,clearTimeout(I),H(),P().then(()=>{L({stdout:W.getContent(),stderr:"Hook cancelled by abort signal",exitCode:1,timedOut:!1})})},Q.abortSignal.addEventListener("abort",b),Q.abortSignal.aborted)b()}})}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"),DO={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 u;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}},J=await this.executeHook($,X,Q);if(!J.success){if(J.blocking)return{decision:"deny",reason:J.error};if(J.needsConfirmation)return{decision:"ask",reason:J.warning||J.error};if(J.warning)Y.push(J.warning);continue}let W=J.output?.hookSpecificOutput;if(W&&"permissionDecision"in W){switch(W.permissionDecision){case"deny":return{decision:"deny",reason:W.permissionDecisionReason};case"ask":return{decision:"ask",reason:W.permissionDecisionReason};case"allow":break}if("updatedInput"in W&&W.updatedInput)Z={...Z,...W.updatedInput}}}catch(X){let J=X instanceof Error?X.message:String(X);if(Y.push(`Hook failed: ${J}`),Q.config.failureBehavior==="deny")return{decision:"deny",reason:J};else if(Q.config.failureBehavior==="ask")return{decision:"ask",reason:`Hook failed: ${J}. 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,J=[];for(let W of Y){if(!W.success&&W.warning){J.push(W.warning);continue}let G=W.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{Ie as YO}from"./chunk-v11r4ahz.js";import{Bf as qO,Df as S,Gf 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 J of O)try{let W=await this.executeHook(J,q,Q);if(!W.success){if(W.warning)Y.push(W.warning);continue}if(W.output?.suppressOutput){$=!0;break}if(W.stdout&&W.stdout.trim())X=W.stdout.trim()}catch(W){let G=W instanceof Error?W.message:String(W);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,$),J=JSON.stringify(q,null,2),W=new AbortController,G=setTimeout(()=>W.abort(),Z),L;try{L=(await Y.chat([{role:"system",content:X},{role:"user",content:J}],void 0,W.signal)).content}catch(F){if(W.signal.aborted||F instanceof Error&&F.name==="AbortError")return this.outputParser.parse({stdout:"",stderr:"",exitCode:0,timedOut:!0},O,{timeoutBehavior:Q.config.timeoutBehavior,failureBehavior:Q.config.failureBehavior});throw F}finally{clearTimeout(G)}let R=this.extractJsonFromLLMResponse(L);return this.outputParser.parse({stdout:R,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,J=setTimeout(()=>{if(X)return;X=!0;let G=Object.assign(Error(`Function hook timed out after ${Z}ms`),{isTimeout:!0});$(G)},Z),W=()=>{if(X)return;X=!0,clearTimeout(J),$(Error("Function hook aborted"))};Q.abortSignal?.addEventListener("abort",W,{once:!0}),Promise.resolve().then(()=>O(q,Q)).then((G)=>{if(X)return;X=!0,clearTimeout(J),Q.abortSignal?.removeEventListener("abort",W),Y(G)},(G)=>{if(X)return;X=!0,clearTimeout(J),Q.abortSignal?.removeEventListener("abort",W),$(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)},J=JSON.stringify(q),W;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,R=setTimeout(()=>L.abort(),Z),F=()=>L.abort();Q.abortSignal?.addEventListener("abort",F,{once:!0});try{let V=await fetch(O.url,{method:"POST",headers:X,body:J,redirect:"manual",signal:L.signal});if(V.status>=300&&V.status<400){W=Error(`HTTP hook received redirect (${V.status}); redirects are disabled`);continue}if(!V.ok){if(W=Error(`HTTP hook returned ${V.status} ${V.statusText}`),V.status>=400&&V.status<500)break;continue}let P={stdout:await yO(V,Y),stderr:"",exitCode:0,timedOut:!1};return this.outputParser.parse(P,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){W=Error("HTTP hook aborted by caller");break}if(B){let P={stdout:"",stderr:`HTTP hook timeout after ${Z}ms`,exitCode:124,timedOut:!0};if(G===$-1)return this.outputParser.parse(P,O,{timeoutBehavior:Q.config.timeoutBehavior,failureBehavior:Q.config.failureBehavior});W=Error(`HTTP hook timeout attempt ${G+1}`);continue}W=V}finally{clearTimeout(R),Q.abortSignal?.removeEventListener("abort",F)}}return{success:!1,blocking:!1,error:W?.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-e5yage6p.js"),{createChatServiceAsync:J}=await import("./chunk-8m87dnk2.js"),{resolveModelConfig:W}=await import("./chunk-j2tmdkmw.js"),{resolveWorkspaceModelResources:G}=await import("./chunk-5vkxcjn1.js");await $();let L=X();if(!L)throw Error("PromptHook: 配置未初始化");let R=this.sessionModelResources.get(Q)??await G(q.projectDir,L),F=O?R.config.models.find((B)=>B.id===O):R.config.models.find((B)=>B.id===R.config.currentModelId)??R.config.models[0];if(!F)throw Error("PromptHook: 无法获取模型配置。请确保至少配置了一个模型。");let V=await J(W(F,R.config,"off",R.catalog).chat);return this.chatServiceCache.set(Z,V),V}sessionResourceKey(O,q){return`${O}\x00${jO.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=DO[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,$),J=JSON.stringify(q,null,2),W=new AbortController,G=setTimeout(()=>W.abort(),Z),L;try{L=(await Y.chat([{role:"system",content:X},{role:"user",content:J}],void 0,W.signal)).content}catch(F){if(W.signal.aborted||F instanceof Error&&F.name==="AbortError")return this.outputParser.parse({stdout:"",stderr:"",exitCode:0,timedOut:!0},O,{timeoutBehavior:Q.config.timeoutBehavior,failureBehavior:Q.config.failureBehavior});throw F}finally{clearTimeout(G)}let R=this.extractJsonFromLLMResponse(L);return this.outputParser.parse({stdout:R,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,J=setTimeout(()=>{if(X)return;X=!0;let G=Object.assign(Error(`Function hook timed out after ${Z}ms`),{isTimeout:!0});$(G)},Z),W=()=>{if(X)return;X=!0,clearTimeout(J),$(Error("Function hook aborted"))};Q.abortSignal?.addEventListener("abort",W,{once:!0}),Promise.resolve().then(()=>O(q,Q)).then((G)=>{if(X)return;X=!0,clearTimeout(J),Q.abortSignal?.removeEventListener("abort",W),Y(G)},(G)=>{if(X)return;X=!0,clearTimeout(J),Q.abortSignal?.removeEventListener("abort",W),$(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)},J=JSON.stringify(q),W;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,R=setTimeout(()=>L.abort(),Z),F=()=>L.abort();Q.abortSignal?.addEventListener("abort",F,{once:!0});try{let V=await fetch(O.url,{method:"POST",headers:X,body:J,redirect:"manual",signal:L.signal});if(V.status>=300&&V.status<400){W=Error(`HTTP hook received redirect (${V.status}); redirects are disabled`);continue}if(!V.ok){if(W=Error(`HTTP hook returned ${V.status} ${V.statusText}`),V.status>=400&&V.status<500)break;continue}let P={stdout:await yO(V,Y),stderr:"",exitCode:0,timedOut:!1};return this.outputParser.parse(P,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){W=Error("HTTP hook aborted by caller");break}if(B){let P={stdout:"",stderr:`HTTP hook timeout after ${Z}ms`,exitCode:124,timedOut:!0};if(G===$-1)return this.outputParser.parse(P,O,{timeoutBehavior:Q.config.timeoutBehavior,failureBehavior:Q.config.failureBehavior});W=Error(`HTTP hook timeout attempt ${G+1}`);continue}W=V}finally{clearTimeout(R),Q.abortSignal?.removeEventListener("abort",F)}}return{success:!1,blocking:!1,error:W?.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-e6frdh2s.js"),{createChatServiceAsync:J}=await import("./chunk-vxxhd72z.js"),{resolveModelConfig:W}=await import("./chunk-4mpx8rad.js"),{resolveWorkspaceModelResources:G}=await import("./chunk-15w4crsc.js");await $();let L=X();if(!L)throw Error("PromptHook: 配置未初始化");let R=this.sessionModelResources.get(Q)??await G(q.projectDir,L),F=O?R.config.models.find((B)=>B.id===O):R.config.models.find((B)=>B.id===R.config.currentModelId)??R.config.models[0];if(!F)throw Error("PromptHook: 无法获取模型配置。请确保至少配置了一个模型。");let V=await J(W(F,R.config,"off",R.catalog).chat);return this.chatServiceCache.set(Z,V),V}sessionResourceKey(O,q){return`${O}\x00${jO.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=DO[q]||"{ ... 根据事件类型返回相应字段 }";return`你是一个代码质量评估器,作为 Hook 在 ${q} 事件中被触发。
29
29
 
30
30
  `+`## 评估指令
31
31
  ${O.prompt}