blade-code 0.7.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blade.js +2 -2
- package/dist/{chunk-x46rv9sv.js → chunk-0k8js58t.js} +1 -1
- package/dist/{chunk-fehae50v.js → chunk-0vd9antx.js} +1 -1
- package/dist/{chunk-96w1szbp.js → chunk-1dt2y16n.js} +1 -1
- package/dist/{chunk-kk8akm7s.js → chunk-2dvn9y9f.js} +1 -1
- package/dist/{chunk-sw6ngzbg.js → chunk-56frm8dx.js} +1 -1
- package/dist/{chunk-kpq18y6v.js → chunk-6jezjq4h.js} +1 -1
- package/dist/chunk-6k4vs71p.js +1 -0
- package/dist/chunk-70ya127f.js +1 -0
- package/dist/{chunk-c2b6ekqx.js → chunk-7v7s2aag.js} +1 -1
- package/dist/{chunk-wre40mf1.js → chunk-7ycmx7c2.js} +1 -1
- package/dist/{chunk-m22zeqdy.js → chunk-867h27ke.js} +2 -2
- package/dist/{chunk-v97f7je6.js → chunk-92qcc3gj.js} +246 -246
- package/dist/{chunk-gscq4fmx.js → chunk-a2nshjdc.js} +2 -2
- package/dist/{chunk-nsbhtvqd.js → chunk-a7dw8fwn.js} +1 -1
- package/dist/{chunk-2nnak657.js → chunk-a8eedntd.js} +1 -1
- package/dist/{chunk-pkzy724w.js → chunk-aam53te2.js} +2 -2
- package/dist/{chunk-q6c9qs9b.js → chunk-b0q2q0ax.js} +2 -2
- package/dist/{chunk-zmp3vdcj.js → chunk-bmxgshct.js} +1 -1
- package/dist/chunk-d3db8wrw.js +1 -0
- package/dist/chunk-dzmrdtpc.js +612 -0
- package/dist/{chunk-gertm8dw.js → chunk-e06p3dkw.js} +2 -2
- package/dist/{chunk-tn3xjczg.js → chunk-f8mjpmdx.js} +1 -1
- package/dist/{chunk-k4behavv.js → chunk-h7qab07x.js} +1 -1
- package/dist/{chunk-mnw1xcwn.js → chunk-k9h9bw13.js} +2 -2
- package/dist/chunk-m51xzgwt.js +1 -0
- package/dist/{chunk-6f63v1mk.js → chunk-qdnx9x5g.js} +2 -2
- package/dist/{chunk-rzz6r1g9.js → chunk-qds0yxfy.js} +2 -2
- package/dist/{chunk-e21htmg4.js → chunk-qyfdt8h1.js} +1 -1
- package/dist/{chunk-hscq9623.js → chunk-r6paqm6d.js} +1 -1
- package/dist/{chunk-vzebrztg.js → chunk-v0rjbvky.js} +1 -1
- package/dist/{chunk-gxnwrec6.js → chunk-v1d0d4b4.js} +2 -2
- package/dist/{chunk-93xhspe5.js → chunk-vs915jzz.js} +1 -1
- package/dist/{chunk-31chcjw6.js → chunk-xmdpc0y5.js} +2 -2
- package/dist/chunk-zbtb3jxm.js +1 -0
- package/dist/{chunk-pf33bn8s.js → chunk-zm4jr1k2.js} +1 -1
- package/dist/{chunk-ft5nt5b5.js → chunk-zvk6ktj1.js} +1 -1
- package/dist/{chunk-hc08zg54.js → chunk-zxddgwsb.js} +1 -1
- package/package.json +1 -1
- package/dist/chunk-64jv62vs.js +0 -1
- package/dist/chunk-p9s685ta.js +0 -1
- package/dist/chunk-phnararg.js +0 -1
- package/dist/chunk-ygta7118.js +0 -1
- package/dist/chunk-zd9stbct.js +0 -618
- package/dist/chunk-zjh9qqvq.js +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{b as v4,c as R4,d as y4}from"./chunk-7v7s2aag.js";import{j as m2,k as g2}from"./chunk-v1d0d4b4.js";import{l as D$,m as n$,o as W1}from"./chunk-zm4jr1k2.js";import{y as D4}from"./chunk-h7qab07x.js";import{C as a8,D as $J,E as f4,F as X8,G as E1,H as m6,J as C6,K as k6,N as f$,O as M8,P as V4,Q as l1,R as bJ,S as BJ,T as V6,U as j4,V as j6,X as OJ,z as KJ}from"./chunk-92qcc3gj.js";import{Y as S8}from"./chunk-a2nshjdc.js";import"./chunk-qyfdt8h1.js";import{$ as S4}from"./chunk-aam53te2.js";import"./chunk-b0q2q0ax.js";import{Ca as g0,da as O$,ea as h0,fa as h1,ga as RQ,ha as n1,ia as T$,ja as nJ,ka as gQ,la as V2,ma as tJ,oa as O4,qa as tQ,ra as H1,sa as k4,ta as w1,ua as B4,wa as d6}from"./chunk-k9h9bw13.js";import{Da as M4,Fa as C4}from"./chunk-867h27ke.js";import{Ma as M2}from"./chunk-xmdpc0y5.js";import{Qa as U4,Ra as T4,Za as l6}from"./chunk-dzmrdtpc.js";import"./chunk-f76d6jxg.js";import{pb as PQ,rb as L1}from"./chunk-qds0yxfy.js";import{ub as vJ,xb as w0}from"./chunk-7ycmx7c2.js";import{Ab as n2}from"./chunk-v0rjbvky.js";import{Lb as I4,Ob as j1}from"./chunk-mt1c5da4.js";import{Qb as s$}from"./chunk-0afbeec0.js";import{useMemoizedFn as lQ}from"ahooks";import{useEffect as d5,useState as rQ}from"react";import{useMemoizedFn as u0}from"ahooks";import{Box as a1}from"ink";import{useEffect as o1,useRef as T8}from"react";import{useShallow as sQ}from"zustand/react/shallow";import{useStore as x4}from"zustand";function $0($){return x4(tQ,$)}var d4=[],eQ=()=>$0(($)=>$.session.sessionId),$6=()=>$0(($)=>$.session.messages),Q6=()=>$0(($)=>$.session.clearCount),J6=()=>$0(($)=>$.session.isCompacting),Y6=()=>$0(($)=>$.session.tokenUsage.estimatedCostUsd),f1=()=>$0(($)=>$.session.actions),Z6=()=>$0(($)=>{let{inputTokens:Q,maxContextTokens:J}=$.session.tokenUsage;if(J<=0)return 100;let Y=Math.max(0,100-Q/J*100);return Math.round(Y)}),X6=()=>$0(($)=>$.app.initializationStatus),q6=()=>$0(($)=>$.app.initializationError),r$=()=>$0(($)=>$.app.activeModal),G6=()=>$0(($)=>$.app.tasks),U6=()=>$0(($)=>$.app.modelEditorTarget),K6=()=>$0(($)=>$.app.sessionSelectorData),O6=()=>$0(($)=>$.app.awaitingSecondCtrlC),D1=()=>$0(($)=>$.app.actions),a$=()=>$0(($)=>$.app.initializationStatus==="ready"),z6=()=>$0(($)=>$.app.tasks.length>0),_$=()=>$0(($)=>$.config.config?.permissionMode||"default"),_6=()=>$0(($)=>$.config.config?.models??d4),o$=()=>$0(($)=>{let Q=$.config.config;if(!Q)return;let J=Q.currentModelId;return Q.models.find((Z)=>Z.id===J)??Q.models[0]}),N6=()=>$0(($)=>$.config.config?.currentModelId),N0=()=>$0(($)=>{return h0.getTheme()}),F6=()=>$0(($)=>$.config.config?.theme??"default"),i0=()=>$0(($)=>$.focus.currentFocus),W6=()=>$0(($)=>$.focus.actions),V1=()=>$0(($)=>$.command.isProcessing),H6=()=>$0(($)=>$.command.actions),L6=()=>$0(($)=>$.command.pendingCommands),i$=()=>$0(($)=>$.app.thinkingModeEnabled),w6=()=>$0(($)=>$.session.currentThinkingContent),b6=()=>$0(($)=>$.session.thinkingExpanded),B6=()=>$0(($)=>$.session.currentStreamingMessageId),A6=()=>$0(sQ(($)=>({lines:$.session.currentStreamingLines,tail:$.session.currentStreamingTail,lineCount:$.session.currentStreamingLineCount,version:$.session.currentStreamingVersion}))),v6=()=>$0(($)=>$.session.finalizingStreamingMessageId),R6=()=>$0(($)=>$.session.historyExpanded),y6=()=>$0(($)=>$.session.expandedMessageCount),P6=()=>$0(sQ(($)=>{let Q=$.spec.currentSpec;if(!Q)return{phase:null,completed:0,total:0};let J=Q.tasks??[],Y=J.filter((Z)=>Z.status==="completed").length;return{phase:Q.phase,completed:Y,total:J.length}}));import{useMemoizedFn as x8}from"ahooks";import{useEffect as u6,useRef as q9}from"react";function l4($){if(!($ instanceof Error))return"未知错误";let Y=$.lastError??$;if(Y.responseBody)try{let X=JSON.parse(Y.responseBody)?.error?.message;if(X){let G=Y.statusCode?` (HTTP ${Y.statusCode})`:"";return`${X}${G}`}}catch{}let Z=$.message.match(/Last error:\s*(.+)$/);if(Z)return Z[1];return $.message}function r4($){if(!($ instanceof Error))return!1;return $.name==="AbortError"||$.message.includes("aborted")}function a4($){if(!($ instanceof Error))return!1;let Q=$.message;return Q.includes("can only concatenate str")||Q.includes("image_url")||Q.includes("multimodal")||Q.includes("vision")||Q.includes("does not support images")}function m8($){let Q=r4($),J=a4($),Y;if(J)Y="当前模型不支持图片理解功能。请切换到支持视觉能力的模型(如 Claude 4.5、GPT-5.2、Gemini 3 Pro、Qwen3-VL-Plus 等)后重试。";else Y=l4($);return{displayMessage:Y,isAbort:Q,isVisionNotSupported:J}}import{appendFileSync as o4,mkdirSync as i4,writeFileSync as n4}from"node:fs";import t4 from"node:os";import M6 from"node:path";var g8=M6.join(t4.homedir(),".blade","logs","stream-debug.log"),I6=!1;function s4(){if(I6)return;let $=M6.dirname(g8);i4($,{recursive:!0,mode:493}),n4(g8,`=== Stream Debug Log Started: ${new Date().toISOString()} ===
|
|
2
2
|
`),I6=!0}function p8($,Q,J){s4();let Y=new Date().toISOString(),Z=J?` | ${JSON.stringify(J)}`:"",q=`[${Y}] [${$}] ${Q}${Z}
|
|
3
3
|
`;o4(g8,q)}var S$=j1("UI");function S6($,Q){let J=!1;return(Y)=>{switch(Y.kind){case"content_delta":if(J||$.signal.aborted)break;Q.contentDeltaCount++,Q.contentDeltaTotalLen+=Y.delta.length,p8("loopEventHandler","onContentDelta",{callCount:Q.contentDeltaCount,deltaLen:Y.delta.length,totalLen:Q.contentDeltaTotalLen}),$.streamingBuffer.batchAppendContent(Y.delta);break;case"thinking_delta":if(J||$.signal.aborted)break;if($.thinkingModeEnabled)$.streamingBuffer.batchAppendThinking(Y.delta);break;case"stream_end":{if(S$.debug("[loopEventHandler] stream_end",{contentDeltaCount:Q.contentDeltaCount,contentDeltaTotalLen:Q.contentDeltaTotalLen,streamFinalized:J,signalAborted:$.signal.aborted}),p8("loopEventHandler","onStreamEnd",{contentDeltaCallCount:Q.contentDeltaCount,contentDeltaTotalLen:Q.contentDeltaTotalLen,streamFinalized:J,signalAborted:$.signal.aborted}),J||$.signal.aborted){J=!0;break}let{extraContent:Z,extraThinking:q}=$.streamingBuffer.drainPendingBuffers(),X=$.getStreamingMessageId();if(X){if(Z)n1(X,Z);T$(X)}$.sessionActions.finalizeStreamingMessage(Z,q),J=!0;break}case"model_fallback":J=!0,$.streamingBuffer.resetStreamingBuffers(),$.sessionActions.discardStreamingMessage(),$.sessionActions.setCurrentThinkingContent(null);break;case"tool_start":{let Z=Y.toolCall;if(!("function"in Z))break;if(S$.debug("[loopEventHandler] tool_start",{toolName:Z.function.name,toolKind:Y.toolKind}),["TaskCreate","TaskUpdate","TaskList"].includes(Z.function.name))break;try{let q=JSON.parse(Z.function.arguments),X=C6(Z.function.name,q);$.sessionActions.addToolMessage(X,{toolName:Z.function.name,phase:"start",summary:X,params:q})}catch(q){S$.error("[loopEventHandler] onToolStart error:",q)}break}case"tool_result":{let Z=Y.toolCall;if(!("function"in Z))break;S$.debug("[loopEventHandler] tool_result",{toolName:Z.function.name,success:Y.result.success});let q=k6(Z.function.name,Y.result);$.sessionActions.addToolMessage(q.summary,{toolName:Z.function.name,phase:"complete",summary:q.summary,detail:q.detail});break}case"token_usage":$.sessionActions.updateTokenUsage(Y.usage);break;case"compaction":if($.sessionActions.setCompacting(Y.phase==="start"),Y.phase==="end")$.sessionActions.resetTokenUsage();break;case"turn_start":S$.debug("[loopEventHandler] turn_start",{turn:Y.turn,maxTurns:Y.maxTurns}),$.sessionActions.updateTokenUsage({turnCount:Y.turn}),J=!1;break;case"task_update":$.appActions.setTasks(Y.tasks);break;case"subagent_spawned":case"subagent_completed":break;default:{let Z=Y}}}}function T6($){let{text:Q,images:J,parts:Y}=$;if(J.length===0)return Q;let Z=[];for(let q of Y)if(q.type==="text")Z.push({type:"text",text:q.text});else Z.push({type:"image_url",image_url:{url:`data:${q.mimeType};base64,${q.base64}`}});return Z}function f6($){return{role:$.role,content:$.content}}function D6($){if(!$.restoredContextMessages||$.restoredVisibleMessageCount<=0)return $.messages.map(f6);let Q=$.messages.slice($.restoredVisibleMessageCount).map(f6);return[...$.restoredContextMessages,...Q]}function e4($){return typeof $==="object"&&$!==null&&$.action==="invoke_skill"&&typeof $.skillName==="string"}function $9($){return typeof $==="object"&&$!==null&&$.action==="invoke_custom_command"&&typeof $.commandName==="string"&&typeof $.processedContent==="string"}function Q9($){return typeof $==="object"&&$!==null&&$.action==="invoke_plugin_command"&&typeof $.commandName==="string"&&typeof $.processedContent==="string"}function J9($){return typeof $==="object"&&$!==null&&$.action==="invoke_once_model"&&typeof $.modelId==="string"&&typeof $.prompt==="string"}function Y9($,Q,J,Y){switch($){case"show_theme_selector":return J.setActiveModal("themeSelector"),!0;case"show_model_selector":return J.setActiveModal("modelSelector"),!0;case"show_model_add_wizard":return J.setActiveModal("modelAddWizard"),!0;case"show_permissions_manager":return J.setActiveModal("permissionsManager"),!0;case"show_agents_manager":return J.setActiveModal("agentsManager"),!0;case"show_skills_manager":return J.setActiveModal("skillsManager"),!0;case"show_hooks_manager":return J.setActiveModal("hooksManager"),!0;case"show_plugins_manager":return J.setActiveModal("pluginsManager"),!0;case"show_agent_creation_wizard":return J.setActiveModal("agentCreationWizard"),!0;case"show_session_selector":{let Z=Q?.sessions;return J.showSessionSelector(Z),!0}case"clear_screen":return Y.clearMessages(),Y.setError(null),Y.resetTokenUsage(),J.setTasks([]),!0;case"compact_completed":case"compact_fallback":return Y.resetTokenUsage(),!0;case"exit_application":return W1(0),!0;default:return!1}}async function E6($,Q,J,Y,Z){let{text:q}=$;if(!V6(q))return{type:"not_slash"};let X={cwd:w0(),sessionId:Z,signal:Y},G=await j6(q,X);if(G.message){if(Y9(G.message,G.data,Q,J))return{type:"handled",commandResult:{success:!0}}}if(e4(G.data)){let{skillName:U,skillArgs:W}=G.data,O=W?`Please use the "${U}" skill to help me with: ${W}`:`Please use the "${U}" skill.`;return J.addUserMessage(O),{type:"continue_as_agent",result:{userDisplayMessage:O,agentInput:{displayText:O,text:O,images:[],parts:[{type:"text",text:O}]},userMessageAlreadyAdded:!0}}}if($9(G.data)){let{commandName:U,processedContent:W}=G.data;J.addUserMessage(q);let O=`# Custom Command: /${U}
|
|
4
4
|
|
|
@@ -21,7 +21,7 @@ ${O}
|
|
|
21
21
|
---
|
|
22
22
|
|
|
23
23
|
Remember: Follow the above instructions carefully to complete the user's request.`;return{type:"continue_as_agent",result:{userDisplayMessage:q,agentInput:{displayText:q,text:N,images:[],parts:[{type:"text",text:N}]},userMessageAlreadyAdded:!0}}}if(J9(G.data)){let{modelId:U,prompt:W}=G.data;return J.addUserMessage(W),{type:"continue_as_agent",result:{userDisplayMessage:W,agentInput:{displayText:W,text:W,images:[],parts:[{type:"text",text:W}]},userMessageAlreadyAdded:!0,onceModelId:U}}}if(!G.success&&G.error)return J.addAssistantMessage(`${G.error}`),{type:"handled",commandResult:{success:G.success,output:G.message,error:G.error,metadata:G.data}};let K=G.message;if(G.success&&typeof K==="string"&&K.trim()!=="")J.addAssistantMessage(K);return{type:"handled",commandResult:{success:G.success,output:G.message,error:G.error,metadata:G.data}}}import{useMemoizedFn as h6}from"ahooks";import{useEffect as Z9,useRef as u8}from"react";function g6($){let Q=u8(void 0),J=u8(void 0),Y=u8(void 0),Z=h6(async()=>{if(Y.current)return Y.current;let X=Q.current,G=J.current;if(!X&&!G)return;Q.current=void 0,J.current=void 0;let K=(async()=>{try{await X?.destroy()}finally{await G?.dispose()}})();Y.current=K;try{await K}finally{if(Y.current===K)Y.current=void 0}}),q=h6(async(X)=>{let G=X?.sessionId??$.sessionId,K=!!X?.modelId&&X.modelId!==$.modelId,U;if(!K&&G){if(J.current&&J.current.sessionId!==G)await Z();if(!J.current)J.current=await m6.create({sessionId:G,modelId:X?.modelId??$.modelId});else await J.current.refresh({modelId:X?.modelId??$.modelId});U=await f$.createWithRuntime(J.current,{sessionId:G,systemPrompt:X?.systemPrompt??$.systemPrompt,appendSystemPrompt:X?.appendSystemPrompt??$.appendSystemPrompt,maxTurns:X?.maxTurns??$.maxTurns,modelId:X?.modelId??$.modelId})}else U=await f$.create({systemPrompt:X?.systemPrompt??$.systemPrompt,appendSystemPrompt:X?.appendSystemPrompt??$.appendSystemPrompt,maxTurns:X?.maxTurns??$.maxTurns,modelId:X?.modelId??$.modelId});return Q.current=U,U});return Z9(()=>{let X=n$(Z);return()=>{X(),Z().catch(()=>{return})}},[Z]),{agentRef:Q,createAgent:q,cleanupAgent:Z}}import{useMemoizedFn as N$}from"ahooks";import{useEffect as X9,useRef as t$}from"react";function p6($){let Q=0;for(let J of $)if(J===`
|
|
24
|
-
`)Q++;return Q}function c6($,Q){let J=Q?.flushTimeout??300,Y=Q?.minLinesToFlush??5,Z=Q?.minCharsToFlush??400,q=t$(""),X=t$(null),G=t$(""),K=t$(null),U=N$(()=>{if(q.current){let H=q.current,w=$.appendAssistantContent(H);n1(w,H),q.current=""}if(X.current)clearTimeout(X.current),X.current=null}),W=N$(()=>{if(G.current)$.appendThinkingContent(G.current),G.current="";if(K.current)clearTimeout(K.current),K.current=null}),O=N$((H)=>{q.current+=H;let w=q.current;if(p6(w)>=Y||w.length>=Z){U();return}if(!X.current)X.current=setTimeout(U,J)}),N=N$((H)=>{G.current+=H;let w=G.current;if(p6(w)>=Y||w.length>=Z){W();return}if(!K.current)K.current=setTimeout(W,J)}),z=N$(()=>{if(q.current="",X.current)clearTimeout(X.current),X.current=null;if(G.current="",K.current)clearTimeout(K.current),K.current=null}),_=N$(()=>{if(X.current)clearTimeout(X.current),X.current=null;if(K.current)clearTimeout(K.current),K.current=null;let H=q.current,w=G.current;return q.current="",G.current="",{extraContent:H,extraThinking:w}});return X9(()=>{return()=>{z()}},[z]),{batchAppendContent:O,batchAppendThinking:N,flushContentBuffer:U,flushThinkingBuffer:W,resetStreamingBuffers:z,drainPendingBuffers:_}}var x6=j1("UI"),r6=($,Q,J,Y,Z)=>{let q=V1(),X=eQ(),G=_$(),K=i$(),U=f1(),W=D1(),O=H6(),N=q9(!1),{createAgent:z}=g6({sessionId:X,systemPrompt:$,appendSystemPrompt:Q,maxTurns:Y}),_=c6(U);u6(()=>{return()=>{_.resetStreamingBuffers()}},[_.resetStreamingBuffers]),u6(()=>{if(!K)U.setCurrentThinkingContent(null)},[K,U]);let H=x8(()=>{if(!q)return;Z?.();let{extraContent:F,extraThinking:P}=_.drainPendingBuffers();O.abort("user-cancel"),W.setTasks([]);let y=H1().session.currentStreamingMessageId;if(y){if(F)n1(y,F);T$(y)}if(U.finalizeStreamingMessage(F,P),!N.current)U.addAssistantMessage("任务已停止"),N.current=!0}),w=x8(async(F)=>{let P=!1,y,v=F;try{await d6();let A=O.getAbortController()??O.createAbortController(),b=await E6(F,W,U,A.signal,X);if(b.type==="handled")return b.commandResult;if(b.type==="continue_as_agent")P=b.result.userMessageAlreadyAdded,y=b.result.onceModelId,v=b.result.agentInput;let B=L1.getInstance(),C,V=await B.executeUserPromptSubmitHooks(v.text,{projectDir:w0(),sessionId:X,permissionMode:G,hasImages:v.images.length>0,imageCount:v.images.length});if(!V.proceed){if(V.warning)U.addAssistantMessage(`${V.warning}`);return{success:!1,error:"blocked by hook"}}if(V.updatedPrompt)v={...v,text:V.updatedPrompt,displayText:V.updatedPrompt,parts:[{type:"text",text:V.updatedPrompt}]};if(V.contextInjection)C=V.contextInjection;try{let{SpecManager:c}=await import("./chunk-
|
|
24
|
+
`)Q++;return Q}function c6($,Q){let J=Q?.flushTimeout??300,Y=Q?.minLinesToFlush??5,Z=Q?.minCharsToFlush??400,q=t$(""),X=t$(null),G=t$(""),K=t$(null),U=N$(()=>{if(q.current){let H=q.current,w=$.appendAssistantContent(H);n1(w,H),q.current=""}if(X.current)clearTimeout(X.current),X.current=null}),W=N$(()=>{if(G.current)$.appendThinkingContent(G.current),G.current="";if(K.current)clearTimeout(K.current),K.current=null}),O=N$((H)=>{q.current+=H;let w=q.current;if(p6(w)>=Y||w.length>=Z){U();return}if(!X.current)X.current=setTimeout(U,J)}),N=N$((H)=>{G.current+=H;let w=G.current;if(p6(w)>=Y||w.length>=Z){W();return}if(!K.current)K.current=setTimeout(W,J)}),z=N$(()=>{if(q.current="",X.current)clearTimeout(X.current),X.current=null;if(G.current="",K.current)clearTimeout(K.current),K.current=null}),_=N$(()=>{if(X.current)clearTimeout(X.current),X.current=null;if(K.current)clearTimeout(K.current),K.current=null;let H=q.current,w=G.current;return q.current="",G.current="",{extraContent:H,extraThinking:w}});return X9(()=>{return()=>{z()}},[z]),{batchAppendContent:O,batchAppendThinking:N,flushContentBuffer:U,flushThinkingBuffer:W,resetStreamingBuffers:z,drainPendingBuffers:_}}var x6=j1("UI"),r6=($,Q,J,Y,Z)=>{let q=V1(),X=eQ(),G=_$(),K=i$(),U=f1(),W=D1(),O=H6(),N=q9(!1),{createAgent:z}=g6({sessionId:X,systemPrompt:$,appendSystemPrompt:Q,maxTurns:Y}),_=c6(U);u6(()=>{return()=>{_.resetStreamingBuffers()}},[_.resetStreamingBuffers]),u6(()=>{if(!K)U.setCurrentThinkingContent(null)},[K,U]);let H=x8(()=>{if(!q)return;Z?.();let{extraContent:F,extraThinking:P}=_.drainPendingBuffers();O.abort("user-cancel"),W.setTasks([]);let y=H1().session.currentStreamingMessageId;if(y){if(F)n1(y,F);T$(y)}if(U.finalizeStreamingMessage(F,P),!N.current)U.addAssistantMessage("任务已停止"),N.current=!0}),w=x8(async(F)=>{let P=!1,y,v=F;try{await d6();let A=O.getAbortController()??O.createAbortController(),b=await E6(F,W,U,A.signal,X);if(b.type==="handled")return b.commandResult;if(b.type==="continue_as_agent")P=b.result.userMessageAlreadyAdded,y=b.result.onceModelId,v=b.result.agentInput;let B=L1.getInstance(),C,V=await B.executeUserPromptSubmitHooks(v.text,{projectDir:w0(),sessionId:X,permissionMode:G,hasImages:v.images.length>0,imageCount:v.images.length});if(!V.proceed){if(V.warning)U.addAssistantMessage(`${V.warning}`);return{success:!1,error:"blocked by hook"}}if(V.updatedPrompt)v={...v,text:V.updatedPrompt,displayText:V.updatedPrompt,parts:[{type:"text",text:V.updatedPrompt}]};if(V.contextInjection)C=V.contextInjection;try{let{SpecManager:c}=await import("./chunk-d3db8wrw.js"),I=c.getInstance().buildProgressContext();if(I)C=C?`${C}
|
|
25
25
|
|
|
26
26
|
${I}`:I}catch{}if(!P)U.addUserMessage(v.displayText);let l=T6(v),r=await z(y?{modelId:y}:void 0);if(A.signal.aborted)return x6.info("[handleCommandSubmit] Agent 创建期间已被中止"),{success:!1,error:"aborted"};let x=D6(H1().session);if(C)x.push({role:"system",content:`<user-prompt-submit-hook>
|
|
27
27
|
${C}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{O as c,P as g,Q as m,T as d,V as r}from"./chunk-
|
|
1
|
+
import{O as c,P as g,Q as m,T as d,V as r}from"./chunk-92qcc3gj.js";import{xb as n}from"./chunk-7ycmx7c2.js";async function h(){if((await c().initialize(n(),[])).plugins.length>0)await g()}async function R(e){let t=e.message||e._?.[0];if(typeof t==="string"&&t.trim())return t;let a=e.stdin??process.stdin;if(!a.isTTY){let u=[];for await(let l of a)u.push(l);return Buffer.concat(u).toString("utf-8").trim()}if(e.defaultMessage!==void 0)return e.defaultMessage;throw Error("No input provided")}async function x(e){if(!d(e))return{mode:"agent",content:e};let t=await r(e,{cwd:n(),workspaceRoot:n()});if(!t.success)return{mode:"output",content:`Error: ${t.error||"未知错误"}`,exitCode:1};let a=t.data;if(a?.action==="invoke_skill"){let{skillName:u,skillArgs:l}=a;return{mode:"agent",content:l?`Please use the "${u}" skill to help me with: ${l}`:`Please use the "${u}" skill.`}}if(a?.action==="invoke_custom_command"||a?.action==="invoke_plugin_command"){let u=a.processedContent;return{mode:"agent",content:`# Custom Command: /${a.commandName}
|
|
2
2
|
|
|
3
3
|
${u}`}}return{mode:"output",content:t.content||t.message||"",exitCode:0}}function i(e){if(!(e instanceof Error))return!1;return e.message.includes("未找到会话")||e.message.includes("ENOENT")||e.message.includes("no such file")}async function f(e){try{return await m.loadSession(e,n())}catch(t){if(i(t))return null;throw t}}async function _(e){if(e.resume===!0||e.resume==="true")throw Error("--resume without a session ID is only supported in interactive UI mode");if(typeof e.resume==="string"&&e.resume.length>0){if(e.forkSession)return m.forkSession(e.resume,{newSessionId:e.sessionId,targetProjectPath:n()});return{sessionId:e.resume,messages:await m.loadSession(e.resume)}}if(e.continue){let t=await m.listSessions();if(t.length>0){let a=t[0].sessionId;if(e.forkSession)return m.forkSession(a,{newSessionId:e.sessionId,targetProjectPath:n()});return{sessionId:a,messages:await m.loadSession(a)}}if(e.forkSession)throw Error("Cannot fork: no sessions are available to continue")}if(e.sessionId)return{sessionId:e.sessionId,messages:await f(e.sessionId)??[]};return{sessionId:`${e.fallbackSessionPrefix}-${Date.now()}`,messages:[]}}
|
|
4
4
|
export{h as p,R as q,x as r,_ as s};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{Z as H}from"./chunk-qyfdt8h1.js";import{z as k}from"zod";var K=k.string().min(1).max(128).regex(/^[A-Za-z0-9][A-Za-z0-9_-]*$/),G=k.array(k.string().trim().min(1).max(200)).max(128).transform((B)=>[...new Set(B)]),Q=k.object({description:k.string().trim().min(1).max(4096),prompt:k.string().trim().min(1).max(1e5),tools:G.optional(),disallowedTools:G.optional(),model:k.string().trim().min(1).max(200).optional(),permissionMode:k.enum(["default","acceptEdits","dontAsk","bypassPermissions","plan","ignore"]).optional(),maxTurns:k.number().int().positive().max(100).optional(),isolation:k.enum(["none","worktree"]).optional()}).strict();function V(B){let w;try{w=JSON.parse(B)}catch{throw Error("Invalid JSON provided to --agents")}if(w===null||Array.isArray(w)||typeof w!=="object")throw Error("--agents must be a JSON object");let E=Object.entries(w);if(E.length>64)throw Error("--agents supports at most 64 definitions");return E.map(([x,I])=>{if(!K.safeParse(x).success)throw Error(`Invalid --agents name "${x}": use letters, numbers, hyphens, or underscores`);let F=Q.safeParse(I);if(!F.success)throw Error(`Invalid --agents definition for "${x}"`);let q=F.data;return{name:x,description:q.description,systemPrompt:q.prompt,tools:q.tools,disallowedTools:q.disallowedTools,model:q.model,permissionMode:q.permissionMode===void 0?void 0:H(q.permissionMode),maxTurns:q.maxTurns,isolation:q.isolation,source:"flag"}})}
|
|
2
2
|
export{V as y};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{Ka as q0,Ma as A}from"./chunk-m22zeqdy.js";import{Ob as K0}from"./chunk-mt1c5da4.js";import{nanoid as i0}from"nanoid";import{devtools as o0,subscribeWithSelector as n0}from"zustand/middleware";import{createStore as s0}from"zustand/vanilla";var x0={name:"ayu-dark",colors:{primary:"#ffcc66",secondary:"#bae67e",accent:"#73d0ff",success:"#bae67e",warning:"#ffcc66",error:"#ff3333",info:"#73d0ff",light:"#f0f0f0",dark:"#000000",muted:"#5c6773",highlight:"#2d323b",text:{primary:"#e6e1cf",secondary:"#bae67e",muted:"#5c6773",light:"#ffffff"},background:{primary:"#0f1419",secondary:"#14191f",dark:"#000000"},border:{light:"#2d323b",dark:"#000000"},syntax:{comment:"#5c6773",string:"#bae67e",number:"#ffcc66",keyword:"#ff8f40",function:"#73d0ff",variable:"#e6e1cf",operator:"#f29e74",type:"#73d0ff",tag:"#ff8f40",attr:"#ffd580",default:"#e6e1cf"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(0, 0, 0, 0.2)",base:"0 1px 3px 0 rgba(0, 0, 0, 0.3), 0 1px 2px 0 rgba(0, 0, 0, 0.2)",lg:"0 10px 15px -3px rgba(0, 0, 0, 0.3), 0 4px 6px -2px rgba(0, 0, 0, 0.2)"}},B0={name:"dracula",colors:{primary:"#bd93f9",secondary:"#ffb86c",accent:"#ff79c6",success:"#50fa7b",warning:"#f1fa8c",error:"#ff5555",info:"#8be9fd",light:"#f8f8f2",dark:"#282a36",muted:"#6272a4",highlight:"#44475a",text:{primary:"#f8f8f2",secondary:"#f1fa8c",muted:"#6272a4",light:"#ffffff"},background:{primary:"#282a36",secondary:"#44475a",dark:"#21222c"},border:{light:"#44475a",dark:"#000000"},syntax:{comment:"#6272a4",string:"#f1fa8c",number:"#bd93f9",keyword:"#ff79c6",function:"#50fa7b",variable:"#f8f8f2",operator:"#ff79c6",type:"#8be9fd",tag:"#ff79c6",attr:"#50fa7b",default:"#f8f8f2"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(40, 42, 54, 0.2)",base:"0 1px 3px 0 rgba(40, 42, 54, 0.3), 0 1px 2px 0 rgba(40, 42, 54, 0.2)",lg:"0 10px 15px -3px rgba(40, 42, 54, 0.3), 0 4px 6px -2px rgba(40, 42, 54, 0.2)"}},w0={name:"monokai",colors:{primary:"#66d9ef",secondary:"#a6e22e",accent:"#f92672",success:"#a6e22e",warning:"#e6db74",error:"#f92672",info:"#66d9ef",light:"#f8f8f2",dark:"#272822",muted:"#75715e",highlight:"#3e3d32",text:{primary:"#f8f8f2",secondary:"#e6db74",muted:"#75715e",light:"#ffffff"},background:{primary:"#272822",secondary:"#3e3d32",dark:"#1e1f1c"},border:{light:"#3e3d32",dark:"#000000"},syntax:{comment:"#75715e",string:"#e6db74",number:"#ae81ff",keyword:"#f92672",function:"#a6e22e",variable:"#f8f8f2",operator:"#f92672",type:"#66d9ef",tag:"#f92672",attr:"#a6e22e",default:"#f8f8f2"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(39, 40, 34, 0.2)",base:"0 1px 3px 0 rgba(39, 40, 34, 0.3), 0 1px 2px 0 rgba(39, 40, 34, 0.2)",lg:"0 10px 15px -3px rgba(39, 40, 34, 0.3), 0 4px 6px -2px rgba(39, 40, 34, 0.2)"}},A0={name:"nord",colors:{primary:"#88c0d0",secondary:"#81a1c1",accent:"#b48ead",success:"#a3be8c",warning:"#ebcb8b",error:"#bf616a",info:"#88c0d0",light:"#eceff4",dark:"#2e3440",muted:"#4c566a",highlight:"#434c5e",text:{primary:"#eceff4",secondary:"#d8dee9",muted:"#4c566a",light:"#ffffff"},background:{primary:"#2e3440",secondary:"#3b4252",dark:"#242933"},border:{light:"#434c5e",dark:"#000000"},syntax:{comment:"#616e88",string:"#a3be8c",number:"#b48ead",keyword:"#81a1c1",function:"#88c0d0",variable:"#d8dee9",operator:"#81a1c1",type:"#8fbcbb",tag:"#81a1c1",attr:"#8fbcbb",default:"#eceff4"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(46, 52, 64, 0.2)",base:"0 1px 3px 0 rgba(46, 52, 64, 0.3), 0 1px 2px 0 rgba(46, 52, 64, 0.2)",lg:"0 10px 15px -3px rgba(46, 52, 64, 0.3), 0 4px 6px -2px rgba(46, 52, 64, 0.2)"}},D0={name:"solarized-light",colors:{primary:"#268bd2",secondary:"#2aa198",accent:"#d33682",success:"#859900",warning:"#cb4b16",error:"#dc322f",info:"#268bd2",light:"#fdf6e3",dark:"#073642",muted:"#93a1a1",highlight:"#eee8d5",text:{primary:"#586e75",secondary:"#657b83",muted:"#93a1a1",light:"#002b36"},background:{primary:"#fdf6e3",secondary:"#eee8d5",dark:"#073642"},border:{light:"#eee8d5",dark:"#073642"},syntax:{comment:"#93a1a1",string:"#2aa198",number:"#d33682",keyword:"#859900",function:"#268bd2",variable:"#657b83",operator:"#859900",type:"#b58900",tag:"#268bd2",attr:"#93a1a1",default:"#657b83"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(253, 246, 227, 0.2)",base:"0 1px 3px 0 rgba(253, 246, 227, 0.3), 0 1px 2px 0 rgba(253, 246, 227, 0.2)",lg:"0 10px 15px -3px rgba(253, 246, 227, 0.3), 0 4px 6px -2px rgba(253, 246, 227, 0.2)"}},L0={name:"solarized-dark",colors:{primary:"#268bd2",secondary:"#2aa198",accent:"#d33682",success:"#859900",warning:"#b58900",error:"#dc322f",info:"#268bd2",light:"#fdf6e3",dark:"#073642",muted:"#586e75",highlight:"#073642",text:{primary:"#839496",secondary:"#93a1a1",muted:"#586e75",light:"#fdf6e3"},background:{primary:"#002b36",secondary:"#073642",dark:"#001f29"},border:{light:"#073642",dark:"#000000"},syntax:{comment:"#586e75",string:"#2aa198",number:"#d33682",keyword:"#859900",function:"#268bd2",variable:"#839496",operator:"#859900",type:"#b58900",tag:"#268bd2",attr:"#93a1a1",default:"#839496"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(0, 43, 54, 0.2)",base:"0 1px 3px 0 rgba(0, 43, 54, 0.3), 0 1px 2px 0 rgba(0, 43, 54, 0.2)",lg:"0 10px 15px -3px rgba(0, 43, 54, 0.3), 0 4px 6px -2px rgba(0, 43, 54, 0.2)"}},v0={name:"tokyo-night",colors:{primary:"#7aa2f7",secondary:"#7dcfff",accent:"#bb9af7",success:"#9ece6a",warning:"#e0af68",error:"#f7768e",info:"#7aa2f7",light:"#c0caf5",dark:"#1a1b26",muted:"#565f89",highlight:"#292e42",text:{primary:"#a9b1d6",secondary:"#c0caf5",muted:"#565f89",light:"#ffffff"},background:{primary:"#1a1b26",secondary:"#292e42",dark:"#16161e"},border:{light:"#292e42",dark:"#000000"},syntax:{comment:"#565f89",string:"#9ece6a",number:"#ff9e64",keyword:"#bb9af7",function:"#7aa2f7",variable:"#c0caf5",operator:"#89ddff",type:"#7dcfff",tag:"#f7768e",attr:"#7aa2f7",default:"#a9b1d6"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(26, 27, 38, 0.2)",base:"0 1px 3px 0 rgba(26, 27, 38, 0.3), 0 1px 2px 0 rgba(26, 27, 38, 0.2)",lg:"0 10px 15px -3px rgba(26, 27, 38, 0.3), 0 4px 6px -2px rgba(26, 27, 38, 0.2)"}},E0={name:"github",colors:{primary:"#0969da",secondary:"#8250df",accent:"#bc4c00",success:"#1a7f37",warning:"#bc4c00",error:"#d1242f",info:"#0969da",light:"#f6f8fa",dark:"#24292f",muted:"#6e7781",highlight:"#ddf4ff",text:{primary:"#24292f",secondary:"#57606a",muted:"#6e7781",light:"#ffffff"},background:{primary:"#ffffff",secondary:"#f6f8fa",dark:"#24292f"},border:{light:"#d0d7de",dark:"#24292f"},syntax:{comment:"#6e7781",string:"#0a3069",number:"#0550ae",keyword:"#cf222e",function:"#8250df",variable:"#24292f",operator:"#cf222e",type:"#0550ae",tag:"#116329",attr:"#0550ae",default:"#24292f"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(255, 255, 255, 0.2)",base:"0 1px 3px 0 rgba(255, 255, 255, 0.3), 0 1px 2px 0 rgba(255, 255, 255, 0.2)",lg:"0 10px 15px -3px rgba(255, 255, 255, 0.3), 0 4px 6px -2px rgba(255, 255, 255, 0.2)"}},y0={name:"gruvbox",colors:{primary:"#83a598",secondary:"#8ec07c",accent:"#d3869b",success:"#b8bb26",warning:"#fabd2f",error:"#fb4934",info:"#83a598",light:"#fbf1c7",dark:"#282828",muted:"#928374",highlight:"#3c3836",text:{primary:"#ebdbb2",secondary:"#d5c4a1",muted:"#928374",light:"#ffffff"},background:{primary:"#282828",secondary:"#3c3836",dark:"#1d2021"},border:{light:"#3c3836",dark:"#000000"},syntax:{comment:"#928374",string:"#b8bb26",number:"#d3869b",keyword:"#fb4934",function:"#8ec07c",variable:"#ebdbb2",operator:"#fe8019",type:"#fabd2f",tag:"#fb4934",attr:"#b8bb26",default:"#ebdbb2"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(40, 40, 40, 0.2)",base:"0 1px 3px 0 rgba(40, 40, 40, 0.3), 0 1px 2px 0 rgba(40, 40, 40, 0.2)",lg:"0 10px 15px -3px rgba(40, 40, 40, 0.3), 0 4px 6px -2px rgba(40, 40, 40, 0.2)"}},R0={name:"one-dark",colors:{primary:"#61afef",secondary:"#c678dd",accent:"#e5c07b",success:"#98c379",warning:"#e5c07b",error:"#e06c75",info:"#56b6c2",light:"#abb2bf",dark:"#282c34",muted:"#5c6370",highlight:"#3e4451",text:{primary:"#abb2bf",secondary:"#c6c8d0",muted:"#5c6370",light:"#ffffff"},background:{primary:"#282c34",secondary:"#3e4451",dark:"#21252b"},border:{light:"#3e4451",dark:"#000000"},syntax:{comment:"#5c6370",string:"#98c379",number:"#d19a66",keyword:"#c678dd",function:"#61afef",variable:"#e06c75",operator:"#56b6c2",type:"#e5c07b",tag:"#e06c75",attr:"#d19a66",default:"#abb2bf"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(40, 44, 52, 0.2)",base:"0 1px 3px 0 rgba(40, 44, 52, 0.3), 0 1px 2px 0 rgba(40, 44, 52, 0.2)",lg:"0 10px 15px -3px rgba(40, 44, 52, 0.3), 0 4px 6px -2px rgba(40, 44, 52, 0.2)"}},P0={name:"catppuccin",colors:{primary:"#89b4fa",secondary:"#cba6f7",accent:"#f5c2e7",success:"#a6e3a1",warning:"#f9e2af",error:"#f38ba8",info:"#89dceb",light:"#cdd6f4",dark:"#11111b",muted:"#6c7086",highlight:"#181825",text:{primary:"#cdd6f4",secondary:"#bac2de",muted:"#6c7086",light:"#ffffff"},background:{primary:"#1e1e2e",secondary:"#181825",dark:"#11111b"},border:{light:"#181825",dark:"#000000"},syntax:{comment:"#6c7086",string:"#a6e3a1",number:"#fab387",keyword:"#cba6f7",function:"#89b4fa",variable:"#cdd6f4",operator:"#89dceb",type:"#f5c2e7",tag:"#f38ba8",attr:"#89b4fa",default:"#cdd6f4"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(30, 30, 46, 0.2)",base:"0 1px 3px 0 rgba(30, 30, 46, 0.3), 0 1px 2px 0 rgba(30, 30, 46, 0.2)",lg:"0 10px 15px -3px rgba(30, 30, 46, 0.3), 0 4px 6px -2px rgba(30, 30, 46, 0.2)"}},C0={name:"rose-pine",colors:{primary:"#9ccfd8",secondary:"#c4a7e7",accent:"#f6c177",success:"#31748f",warning:"#f6c177",error:"#eb6f92",info:"#9ccfd8",light:"#e0def4",dark:"#191724",muted:"#6e6a86",highlight:"#1f1d2e",text:{primary:"#e0def4",secondary:"#cecacd",muted:"#6e6a86",light:"#ffffff"},background:{primary:"#191724",secondary:"#1f1d2e",dark:"#12101a"},border:{light:"#1f1d2e",dark:"#000000"},syntax:{comment:"#6e6a86",string:"#9ccfd8",number:"#ea9a97",keyword:"#c4a7e7",function:"#31748f",variable:"#e0def4",operator:"#f6c177",type:"#9ccfd8",tag:"#eb6f92",attr:"#f6c177",default:"#e0def4"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(25, 23, 36, 0.2)",base:"0 1px 3px 0 rgba(25, 23, 36, 0.3), 0 1px 2px 0 rgba(25, 23, 36, 0.2)",lg:"0 10px 15px -3px rgba(25, 23, 36, 0.3), 0 4px 6px -2px rgba(25, 23, 36, 0.2)"}},I0={name:"kanagawa",colors:{primary:"#8ba4b0",secondary:"#a292a3",accent:"#c47fd5",success:"#76946a",warning:"#c0a36e",error:"#c34043",info:"#7e9cd8",light:"#dcd7ba",dark:"#1f1f28",muted:"#727169",highlight:"#2a2a37",text:{primary:"#dcd7ba",secondary:"#c8c093",muted:"#727169",light:"#ffffff"},background:{primary:"#1f1f28",secondary:"#2a2a37",dark:"#16161d"},border:{light:"#2a2a37",dark:"#000000"},syntax:{comment:"#727169",string:"#98bb6c",number:"#d27e99",keyword:"#957fb8",function:"#7e9cd8",variable:"#dcd7ba",operator:"#c0a36e",type:"#7aa89f",tag:"#c34043",attr:"#7fb4ca",default:"#dcd7ba"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(31, 31, 40, 0.2)",base:"0 1px 3px 0 rgba(31, 31, 40, 0.3), 0 1px 2px 0 rgba(31, 31, 40, 0.2)",lg:"0 10px 15px -3px rgba(31, 31, 40, 0.3), 0 4px 6px -2px rgba(31, 31, 40, 0.2)"}},t=[{id:"ayu-dark",label:"Ayu Dark",theme:x0,tags:["dark","popular"]},{id:"dracula",label:"Dracula",theme:B0,tags:["dark","popular"]},{id:"monokai",label:"Monokai",theme:w0,tags:["dark","classic"]},{id:"nord",label:"Nord",theme:A0,tags:["dark","minimal"]},{id:"solarized-light",label:"Solarized Light",theme:D0,tags:["light"]},{id:"solarized-dark",label:"Solarized Dark",theme:L0,tags:["dark"]},{id:"tokyo-night",label:"Tokyo Night",theme:v0,tags:["dark","popular"]},{id:"github",label:"GitHub",theme:E0,tags:["light","minimal"]},{id:"gruvbox",label:"Gruvbox",theme:y0,tags:["dark","warm"]},{id:"one-dark",label:"One Dark",theme:R0,tags:["dark","popular"]},{id:"catppuccin",label:"Catppuccin",theme:P0,tags:["dark","pastel"]},{id:"rose-pine",label:"Rose Pine",theme:C0,tags:["dark","elegant"]},{id:"kanagawa",label:"Kanagawa",theme:I0,tags:["dark","japanese"]}];var e={primary:"#0066cc",secondary:"#6c757d",accent:"#e83e8c",success:"#28a745",warning:"#ffc107",error:"#dc3545",info:"#17a2b8",light:"#f8f9fa",dark:"#343a40",muted:"#6c757d",highlight:"#fff3cd",text:{primary:"#212529",secondary:"#6c757d",muted:"#6c757d",light:"#ffffff"},background:{primary:"#ffffff",secondary:"#f8f9fa",dark:"#343a40"},border:{light:"#dee2e6",dark:"#495057"},syntax:{comment:"#6c757d",string:"#28a745",number:"#e83e8c",keyword:"#007bff",function:"#17a2b8",variable:"#495057",operator:"#ffc107",type:"#007bff",tag:"#dc3545",attr:"#ffc107",default:"#212529"}},p={name:"default",colors:e,spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(0, 0, 0, 0.05)",base:"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)",lg:"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"}},b0={...p,name:"dark",colors:{...e,text:{primary:"#ffffff",secondary:"#e2e8f0",muted:"#94a3b8",light:"#000000"},background:{primary:"#1e293b",secondary:"#334155",dark:"#0f172a"},border:{light:"#475569",dark:"#64748b"},syntax:{comment:"#94a3b8",string:"#34d399",number:"#f472b6",keyword:"#60a5fa",function:"#06b6d4",variable:"#e2e8f0",operator:"#fbbf24",type:"#60a5fa",tag:"#fb7185",attr:"#fbbf24",default:"#ffffff"}}};class Q0{currentTheme=p;themes=new Map;constructor(){this.themes.set("default",p),this.themes.set("dark",b0);for(let X of t)this.themes.set(X.id,X.theme)}setTheme(X){let Z=this.themes.get(X);if(Z)this.currentTheme=Z;else throw Error(`Theme '${X}' not found`)}getTheme(){return this.currentTheme}getAvailableThemes(){return Array.from(this.themes.keys())}getCurrentThemeName(){return this.currentTheme.name}getThemeByName(X){return this.themes.get(X)}hasTheme(X){return this.themes.has(X)}}var X0=new Q0;var M0={initializationStatus:"idle",initializationError:null,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null,tasks:[],awaitingSecondCtrlC:!1,thinkingModeEnabled:!1,subagentProgress:null},g=(X)=>({...M0,actions:{setInitializationStatus:(Z)=>{X((Q)=>({app:{...Q.app,initializationStatus:Z}}))},setInitializationError:(Z)=>{X((Q)=>({app:{...Q.app,initializationError:Z}}))},setActiveModal:(Z)=>{X((Q)=>({app:{...Q.app,activeModal:Z}}))},showSessionSelector:(Z)=>{X((Q)=>({app:{...Q.app,activeModal:"sessionSelector",sessionSelectorData:Z}}))},showModelEditWizard:(Z)=>{X((Q)=>({app:{...Q.app,activeModal:"modelEditWizard",modelEditorTarget:Z}}))},closeModal:()=>{X((Z)=>({app:{...Z.app,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null}}))},setTasks:(Z)=>{X((Q)=>({app:{...Q.app,tasks:Z}}))},updateTask:(Z)=>{X((Q)=>({app:{...Q.app,tasks:Q.app.tasks.map(($)=>$.id===Z.id?Z:$)}}))},setAwaitingSecondCtrlC:(Z)=>{X((Q)=>({app:{...Q.app,awaitingSecondCtrlC:Z}}))},setThinkingModeEnabled:(Z)=>{X((Q)=>({app:{...Q.app,thinkingModeEnabled:Z}}))},toggleThinkingMode:()=>{X((Z)=>({app:{...Z.app,thinkingModeEnabled:!Z.app.thinkingModeEnabled}}))},startSubagentProgress:(Z,Q,$)=>{X((Y)=>({app:{...Y.app,subagentProgress:{id:Z,type:Q,description:$,status:"running",startTime:Date.now()}}}))},updateSubagentTool:(Z)=>{X((Q)=>{if(!Q.app.subagentProgress)return Q;return{app:{...Q.app,subagentProgress:{...Q.app.subagentProgress,currentTool:Z}}}})},completeSubagentProgress:(Z)=>{X((Q)=>{if(!Q.app.subagentProgress)return Q;return{app:{...Q.app,subagentProgress:{...Q.app.subagentProgress,status:Z?"completed":"failed",currentTool:void 0}}}}),setTimeout(()=>{X((Q)=>({app:{...Q.app,subagentProgress:null}}))},1500)}}});var T0={isProcessing:!1,abortController:null,pendingCommands:[]},d=(X,Z)=>({...T0,actions:{setProcessing:(Q)=>{X(($)=>({command:{...$.command,isProcessing:Q}}))},createAbortController:()=>{let Q=Z().command.abortController;if(Q&&!Q.signal.aborted)Q.abort("interrupted-by-new-command");let $=new AbortController;return X((Y)=>({command:{...Y.command,abortController:$}})),$},getAbortController:()=>{return Z().command.abortController},clearAbortController:(Q)=>{let $=Z().command.abortController;if(Q!==void 0&&$!==Q)return;X((Y)=>({command:{...Y.command,abortController:null}}))},abort:(Q)=>{let{abortController:$}=Z().command;if($&&!$.signal.aborted)$.abort(Q??"user-cancel");X((Y)=>({command:{...Y.command,isProcessing:!1,pendingCommands:[]}}))},enqueueCommand:(Q)=>{X(($)=>({command:{...$.command,pendingCommands:[...$.command.pendingCommands,Q]}}))},dequeueCommand:()=>{let{pendingCommands:Q}=Z().command;if(Q.length===0)return;let[$,...Y]=Q;return X((V)=>({command:{...V.command,pendingCommands:Y}})),$},clearQueue:()=>{X((Q)=>({command:{...Q.command,pendingCommands:[]}}))}}});var N0={config:null},m=(X)=>({...N0,actions:{setConfig:(Z)=>{X((Q)=>({config:{...Q.config,config:Z}}))},updateConfig:(Z)=>{X((Q)=>{if(!Q.config.config)throw Error(`[ConfigSlice] Config not initialized. Cannot update: ${JSON.stringify(Z)}`);return{config:{...Q.config,config:{...Q.config.config,...Z}}}})}}});var u0={currentFocus:"main-input",previousFocus:null},r=(X)=>({...u0,actions:{setFocus:(Z)=>{X((Q)=>({focus:{...Q.focus,currentFocus:Z,previousFocus:Q.focus.currentFocus}}))},restorePreviousFocus:()=>{X((Z)=>({focus:{...Z.focus,currentFocus:Z.focus.previousFocus||"main-input",previousFocus:null}}))}}});import{nanoid as p0}from"nanoid";var c={"deepseek-chat":{input:0.27,output:1.1},"deepseek-coder":{input:0.14,output:0.28},"deepseek-reasoner":{input:0.55,output:2.19},"deepseek-v3":{input:0.27,output:1.1},"deepseek-v4":{input:0.27,output:1.1},"deepseek-v4-pro":{input:0.27,output:1.1},"deepseek-v4-0724":{input:0.27,output:1.1},"gpt-4o":{input:2.5,output:10},"gpt-4o-mini":{input:0.15,output:0.6},"gpt-4.1":{input:2,output:8},"gpt-4.1-mini":{input:0.4,output:1.6},"gpt-4.1-nano":{input:0.1,output:0.4},"gpt-4-turbo":{input:10,output:30},"gpt-4":{input:30,output:60},"gpt-3.5-turbo":{input:0.5,output:1.5},o1:{input:15,output:60},"o1-mini":{input:3,output:12},"o1-pro":{input:150,output:600},o3:{input:10,output:40},"o3-mini":{input:1.1,output:4.4},"o4-mini":{input:1.1,output:4.4},"claude-3.5-sonnet":{input:3,output:15,cacheRead:0.3,cacheWrite:3.75},"claude-3.5-haiku":{input:0.8,output:4,cacheRead:0.08,cacheWrite:1},"claude-sonnet-4":{input:3,output:15,cacheRead:0.3,cacheWrite:3.75},"claude-4-opus":{input:15,output:75,cacheRead:1.5,cacheWrite:18.75},"claude-opus-4":{input:15,output:75,cacheRead:1.5,cacheWrite:18.75},"qwen-plus":{input:0.8,output:2},"qwen-max":{input:2,output:6},"qwen-turbo":{input:0.3,output:0.6},"qwen3-235b":{input:2,output:8},"gemini-2.5-pro":{input:1.25,output:10},"gemini-2.5-flash":{input:0.15,output:0.6}};function h0(X){let Z=X.toLowerCase();if(c[Z])return c[Z];for(let[Q,$]of Object.entries(c))if(Z.includes(Q)||Q.includes(Z))return $;return}function Z0(X,Z,Q,$,Y){let V=h0(X);if(!V)return 0;let J=Z/1e6*V.input+Q/1e6*V.output;if($&&V.cacheRead)J+=$/1e6*V.cacheRead;if(Y&&V.cacheWrite)J+=Y/1e6*V.cacheWrite;return Math.round(J*1e6)/1e6}var K={codeBlock:/^```(\w+)?\s*$/,heading:/^ *(#{1,4}) +(.+)/,blockquote:/^(>+)\s?(.*)/,ulItem:/^([ \t]*)([-*+]) +(.+)/,olItem:/^([ \t]*)(\d+)\. +(.+)/,hr:/^ *([-*_] *){3,} *$/,table:/^\|(.+)\|$/,tableSeparator:/^\|[\s]*:?-+:?[\s]*(\|[\s]*:?-+:?[\s]*)+\|?$/,diffStart:/^<<<DIFF>>>$/,diffEnd:/^<<<\/DIFF>>>$/,commandMessage:/<command-message>(.*?)<\/command-message>/};function G1(X){let Z=[],Q=X.split(/\r?\n/),$=!1,Y=[],V=null,J=0,G=!1,U=[],H=[],W=!1,D=[],v=!1,O=[],z=0,j=!0;for(let L=0;L<Q.length;L++){let _=Q[L];if(W){if(_.match(K.diffEnd)){try{let B=JSON.parse(D.join(`
|
|
1
|
+
import{Ea as q0,Ga as A}from"./chunk-867h27ke.js";import{Ob as K0}from"./chunk-mt1c5da4.js";import{nanoid as i0}from"nanoid";import{devtools as o0,subscribeWithSelector as n0}from"zustand/middleware";import{createStore as s0}from"zustand/vanilla";var x0={name:"ayu-dark",colors:{primary:"#ffcc66",secondary:"#bae67e",accent:"#73d0ff",success:"#bae67e",warning:"#ffcc66",error:"#ff3333",info:"#73d0ff",light:"#f0f0f0",dark:"#000000",muted:"#5c6773",highlight:"#2d323b",text:{primary:"#e6e1cf",secondary:"#bae67e",muted:"#5c6773",light:"#ffffff"},background:{primary:"#0f1419",secondary:"#14191f",dark:"#000000"},border:{light:"#2d323b",dark:"#000000"},syntax:{comment:"#5c6773",string:"#bae67e",number:"#ffcc66",keyword:"#ff8f40",function:"#73d0ff",variable:"#e6e1cf",operator:"#f29e74",type:"#73d0ff",tag:"#ff8f40",attr:"#ffd580",default:"#e6e1cf"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(0, 0, 0, 0.2)",base:"0 1px 3px 0 rgba(0, 0, 0, 0.3), 0 1px 2px 0 rgba(0, 0, 0, 0.2)",lg:"0 10px 15px -3px rgba(0, 0, 0, 0.3), 0 4px 6px -2px rgba(0, 0, 0, 0.2)"}},B0={name:"dracula",colors:{primary:"#bd93f9",secondary:"#ffb86c",accent:"#ff79c6",success:"#50fa7b",warning:"#f1fa8c",error:"#ff5555",info:"#8be9fd",light:"#f8f8f2",dark:"#282a36",muted:"#6272a4",highlight:"#44475a",text:{primary:"#f8f8f2",secondary:"#f1fa8c",muted:"#6272a4",light:"#ffffff"},background:{primary:"#282a36",secondary:"#44475a",dark:"#21222c"},border:{light:"#44475a",dark:"#000000"},syntax:{comment:"#6272a4",string:"#f1fa8c",number:"#bd93f9",keyword:"#ff79c6",function:"#50fa7b",variable:"#f8f8f2",operator:"#ff79c6",type:"#8be9fd",tag:"#ff79c6",attr:"#50fa7b",default:"#f8f8f2"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(40, 42, 54, 0.2)",base:"0 1px 3px 0 rgba(40, 42, 54, 0.3), 0 1px 2px 0 rgba(40, 42, 54, 0.2)",lg:"0 10px 15px -3px rgba(40, 42, 54, 0.3), 0 4px 6px -2px rgba(40, 42, 54, 0.2)"}},w0={name:"monokai",colors:{primary:"#66d9ef",secondary:"#a6e22e",accent:"#f92672",success:"#a6e22e",warning:"#e6db74",error:"#f92672",info:"#66d9ef",light:"#f8f8f2",dark:"#272822",muted:"#75715e",highlight:"#3e3d32",text:{primary:"#f8f8f2",secondary:"#e6db74",muted:"#75715e",light:"#ffffff"},background:{primary:"#272822",secondary:"#3e3d32",dark:"#1e1f1c"},border:{light:"#3e3d32",dark:"#000000"},syntax:{comment:"#75715e",string:"#e6db74",number:"#ae81ff",keyword:"#f92672",function:"#a6e22e",variable:"#f8f8f2",operator:"#f92672",type:"#66d9ef",tag:"#f92672",attr:"#a6e22e",default:"#f8f8f2"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(39, 40, 34, 0.2)",base:"0 1px 3px 0 rgba(39, 40, 34, 0.3), 0 1px 2px 0 rgba(39, 40, 34, 0.2)",lg:"0 10px 15px -3px rgba(39, 40, 34, 0.3), 0 4px 6px -2px rgba(39, 40, 34, 0.2)"}},A0={name:"nord",colors:{primary:"#88c0d0",secondary:"#81a1c1",accent:"#b48ead",success:"#a3be8c",warning:"#ebcb8b",error:"#bf616a",info:"#88c0d0",light:"#eceff4",dark:"#2e3440",muted:"#4c566a",highlight:"#434c5e",text:{primary:"#eceff4",secondary:"#d8dee9",muted:"#4c566a",light:"#ffffff"},background:{primary:"#2e3440",secondary:"#3b4252",dark:"#242933"},border:{light:"#434c5e",dark:"#000000"},syntax:{comment:"#616e88",string:"#a3be8c",number:"#b48ead",keyword:"#81a1c1",function:"#88c0d0",variable:"#d8dee9",operator:"#81a1c1",type:"#8fbcbb",tag:"#81a1c1",attr:"#8fbcbb",default:"#eceff4"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(46, 52, 64, 0.2)",base:"0 1px 3px 0 rgba(46, 52, 64, 0.3), 0 1px 2px 0 rgba(46, 52, 64, 0.2)",lg:"0 10px 15px -3px rgba(46, 52, 64, 0.3), 0 4px 6px -2px rgba(46, 52, 64, 0.2)"}},D0={name:"solarized-light",colors:{primary:"#268bd2",secondary:"#2aa198",accent:"#d33682",success:"#859900",warning:"#cb4b16",error:"#dc322f",info:"#268bd2",light:"#fdf6e3",dark:"#073642",muted:"#93a1a1",highlight:"#eee8d5",text:{primary:"#586e75",secondary:"#657b83",muted:"#93a1a1",light:"#002b36"},background:{primary:"#fdf6e3",secondary:"#eee8d5",dark:"#073642"},border:{light:"#eee8d5",dark:"#073642"},syntax:{comment:"#93a1a1",string:"#2aa198",number:"#d33682",keyword:"#859900",function:"#268bd2",variable:"#657b83",operator:"#859900",type:"#b58900",tag:"#268bd2",attr:"#93a1a1",default:"#657b83"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(253, 246, 227, 0.2)",base:"0 1px 3px 0 rgba(253, 246, 227, 0.3), 0 1px 2px 0 rgba(253, 246, 227, 0.2)",lg:"0 10px 15px -3px rgba(253, 246, 227, 0.3), 0 4px 6px -2px rgba(253, 246, 227, 0.2)"}},L0={name:"solarized-dark",colors:{primary:"#268bd2",secondary:"#2aa198",accent:"#d33682",success:"#859900",warning:"#b58900",error:"#dc322f",info:"#268bd2",light:"#fdf6e3",dark:"#073642",muted:"#586e75",highlight:"#073642",text:{primary:"#839496",secondary:"#93a1a1",muted:"#586e75",light:"#fdf6e3"},background:{primary:"#002b36",secondary:"#073642",dark:"#001f29"},border:{light:"#073642",dark:"#000000"},syntax:{comment:"#586e75",string:"#2aa198",number:"#d33682",keyword:"#859900",function:"#268bd2",variable:"#839496",operator:"#859900",type:"#b58900",tag:"#268bd2",attr:"#93a1a1",default:"#839496"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(0, 43, 54, 0.2)",base:"0 1px 3px 0 rgba(0, 43, 54, 0.3), 0 1px 2px 0 rgba(0, 43, 54, 0.2)",lg:"0 10px 15px -3px rgba(0, 43, 54, 0.3), 0 4px 6px -2px rgba(0, 43, 54, 0.2)"}},v0={name:"tokyo-night",colors:{primary:"#7aa2f7",secondary:"#7dcfff",accent:"#bb9af7",success:"#9ece6a",warning:"#e0af68",error:"#f7768e",info:"#7aa2f7",light:"#c0caf5",dark:"#1a1b26",muted:"#565f89",highlight:"#292e42",text:{primary:"#a9b1d6",secondary:"#c0caf5",muted:"#565f89",light:"#ffffff"},background:{primary:"#1a1b26",secondary:"#292e42",dark:"#16161e"},border:{light:"#292e42",dark:"#000000"},syntax:{comment:"#565f89",string:"#9ece6a",number:"#ff9e64",keyword:"#bb9af7",function:"#7aa2f7",variable:"#c0caf5",operator:"#89ddff",type:"#7dcfff",tag:"#f7768e",attr:"#7aa2f7",default:"#a9b1d6"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(26, 27, 38, 0.2)",base:"0 1px 3px 0 rgba(26, 27, 38, 0.3), 0 1px 2px 0 rgba(26, 27, 38, 0.2)",lg:"0 10px 15px -3px rgba(26, 27, 38, 0.3), 0 4px 6px -2px rgba(26, 27, 38, 0.2)"}},E0={name:"github",colors:{primary:"#0969da",secondary:"#8250df",accent:"#bc4c00",success:"#1a7f37",warning:"#bc4c00",error:"#d1242f",info:"#0969da",light:"#f6f8fa",dark:"#24292f",muted:"#6e7781",highlight:"#ddf4ff",text:{primary:"#24292f",secondary:"#57606a",muted:"#6e7781",light:"#ffffff"},background:{primary:"#ffffff",secondary:"#f6f8fa",dark:"#24292f"},border:{light:"#d0d7de",dark:"#24292f"},syntax:{comment:"#6e7781",string:"#0a3069",number:"#0550ae",keyword:"#cf222e",function:"#8250df",variable:"#24292f",operator:"#cf222e",type:"#0550ae",tag:"#116329",attr:"#0550ae",default:"#24292f"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(255, 255, 255, 0.2)",base:"0 1px 3px 0 rgba(255, 255, 255, 0.3), 0 1px 2px 0 rgba(255, 255, 255, 0.2)",lg:"0 10px 15px -3px rgba(255, 255, 255, 0.3), 0 4px 6px -2px rgba(255, 255, 255, 0.2)"}},y0={name:"gruvbox",colors:{primary:"#83a598",secondary:"#8ec07c",accent:"#d3869b",success:"#b8bb26",warning:"#fabd2f",error:"#fb4934",info:"#83a598",light:"#fbf1c7",dark:"#282828",muted:"#928374",highlight:"#3c3836",text:{primary:"#ebdbb2",secondary:"#d5c4a1",muted:"#928374",light:"#ffffff"},background:{primary:"#282828",secondary:"#3c3836",dark:"#1d2021"},border:{light:"#3c3836",dark:"#000000"},syntax:{comment:"#928374",string:"#b8bb26",number:"#d3869b",keyword:"#fb4934",function:"#8ec07c",variable:"#ebdbb2",operator:"#fe8019",type:"#fabd2f",tag:"#fb4934",attr:"#b8bb26",default:"#ebdbb2"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(40, 40, 40, 0.2)",base:"0 1px 3px 0 rgba(40, 40, 40, 0.3), 0 1px 2px 0 rgba(40, 40, 40, 0.2)",lg:"0 10px 15px -3px rgba(40, 40, 40, 0.3), 0 4px 6px -2px rgba(40, 40, 40, 0.2)"}},R0={name:"one-dark",colors:{primary:"#61afef",secondary:"#c678dd",accent:"#e5c07b",success:"#98c379",warning:"#e5c07b",error:"#e06c75",info:"#56b6c2",light:"#abb2bf",dark:"#282c34",muted:"#5c6370",highlight:"#3e4451",text:{primary:"#abb2bf",secondary:"#c6c8d0",muted:"#5c6370",light:"#ffffff"},background:{primary:"#282c34",secondary:"#3e4451",dark:"#21252b"},border:{light:"#3e4451",dark:"#000000"},syntax:{comment:"#5c6370",string:"#98c379",number:"#d19a66",keyword:"#c678dd",function:"#61afef",variable:"#e06c75",operator:"#56b6c2",type:"#e5c07b",tag:"#e06c75",attr:"#d19a66",default:"#abb2bf"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(40, 44, 52, 0.2)",base:"0 1px 3px 0 rgba(40, 44, 52, 0.3), 0 1px 2px 0 rgba(40, 44, 52, 0.2)",lg:"0 10px 15px -3px rgba(40, 44, 52, 0.3), 0 4px 6px -2px rgba(40, 44, 52, 0.2)"}},P0={name:"catppuccin",colors:{primary:"#89b4fa",secondary:"#cba6f7",accent:"#f5c2e7",success:"#a6e3a1",warning:"#f9e2af",error:"#f38ba8",info:"#89dceb",light:"#cdd6f4",dark:"#11111b",muted:"#6c7086",highlight:"#181825",text:{primary:"#cdd6f4",secondary:"#bac2de",muted:"#6c7086",light:"#ffffff"},background:{primary:"#1e1e2e",secondary:"#181825",dark:"#11111b"},border:{light:"#181825",dark:"#000000"},syntax:{comment:"#6c7086",string:"#a6e3a1",number:"#fab387",keyword:"#cba6f7",function:"#89b4fa",variable:"#cdd6f4",operator:"#89dceb",type:"#f5c2e7",tag:"#f38ba8",attr:"#89b4fa",default:"#cdd6f4"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(30, 30, 46, 0.2)",base:"0 1px 3px 0 rgba(30, 30, 46, 0.3), 0 1px 2px 0 rgba(30, 30, 46, 0.2)",lg:"0 10px 15px -3px rgba(30, 30, 46, 0.3), 0 4px 6px -2px rgba(30, 30, 46, 0.2)"}},C0={name:"rose-pine",colors:{primary:"#9ccfd8",secondary:"#c4a7e7",accent:"#f6c177",success:"#31748f",warning:"#f6c177",error:"#eb6f92",info:"#9ccfd8",light:"#e0def4",dark:"#191724",muted:"#6e6a86",highlight:"#1f1d2e",text:{primary:"#e0def4",secondary:"#cecacd",muted:"#6e6a86",light:"#ffffff"},background:{primary:"#191724",secondary:"#1f1d2e",dark:"#12101a"},border:{light:"#1f1d2e",dark:"#000000"},syntax:{comment:"#6e6a86",string:"#9ccfd8",number:"#ea9a97",keyword:"#c4a7e7",function:"#31748f",variable:"#e0def4",operator:"#f6c177",type:"#9ccfd8",tag:"#eb6f92",attr:"#f6c177",default:"#e0def4"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(25, 23, 36, 0.2)",base:"0 1px 3px 0 rgba(25, 23, 36, 0.3), 0 1px 2px 0 rgba(25, 23, 36, 0.2)",lg:"0 10px 15px -3px rgba(25, 23, 36, 0.3), 0 4px 6px -2px rgba(25, 23, 36, 0.2)"}},I0={name:"kanagawa",colors:{primary:"#8ba4b0",secondary:"#a292a3",accent:"#c47fd5",success:"#76946a",warning:"#c0a36e",error:"#c34043",info:"#7e9cd8",light:"#dcd7ba",dark:"#1f1f28",muted:"#727169",highlight:"#2a2a37",text:{primary:"#dcd7ba",secondary:"#c8c093",muted:"#727169",light:"#ffffff"},background:{primary:"#1f1f28",secondary:"#2a2a37",dark:"#16161d"},border:{light:"#2a2a37",dark:"#000000"},syntax:{comment:"#727169",string:"#98bb6c",number:"#d27e99",keyword:"#957fb8",function:"#7e9cd8",variable:"#dcd7ba",operator:"#c0a36e",type:"#7aa89f",tag:"#c34043",attr:"#7fb4ca",default:"#dcd7ba"}},spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(31, 31, 40, 0.2)",base:"0 1px 3px 0 rgba(31, 31, 40, 0.3), 0 1px 2px 0 rgba(31, 31, 40, 0.2)",lg:"0 10px 15px -3px rgba(31, 31, 40, 0.3), 0 4px 6px -2px rgba(31, 31, 40, 0.2)"}},t=[{id:"ayu-dark",label:"Ayu Dark",theme:x0,tags:["dark","popular"]},{id:"dracula",label:"Dracula",theme:B0,tags:["dark","popular"]},{id:"monokai",label:"Monokai",theme:w0,tags:["dark","classic"]},{id:"nord",label:"Nord",theme:A0,tags:["dark","minimal"]},{id:"solarized-light",label:"Solarized Light",theme:D0,tags:["light"]},{id:"solarized-dark",label:"Solarized Dark",theme:L0,tags:["dark"]},{id:"tokyo-night",label:"Tokyo Night",theme:v0,tags:["dark","popular"]},{id:"github",label:"GitHub",theme:E0,tags:["light","minimal"]},{id:"gruvbox",label:"Gruvbox",theme:y0,tags:["dark","warm"]},{id:"one-dark",label:"One Dark",theme:R0,tags:["dark","popular"]},{id:"catppuccin",label:"Catppuccin",theme:P0,tags:["dark","pastel"]},{id:"rose-pine",label:"Rose Pine",theme:C0,tags:["dark","elegant"]},{id:"kanagawa",label:"Kanagawa",theme:I0,tags:["dark","japanese"]}];var e={primary:"#0066cc",secondary:"#6c757d",accent:"#e83e8c",success:"#28a745",warning:"#ffc107",error:"#dc3545",info:"#17a2b8",light:"#f8f9fa",dark:"#343a40",muted:"#6c757d",highlight:"#fff3cd",text:{primary:"#212529",secondary:"#6c757d",muted:"#6c757d",light:"#ffffff"},background:{primary:"#ffffff",secondary:"#f8f9fa",dark:"#343a40"},border:{light:"#dee2e6",dark:"#495057"},syntax:{comment:"#6c757d",string:"#28a745",number:"#e83e8c",keyword:"#007bff",function:"#17a2b8",variable:"#495057",operator:"#ffc107",type:"#007bff",tag:"#dc3545",attr:"#ffc107",default:"#212529"}},p={name:"default",colors:e,spacing:{xs:0.25,sm:0.5,md:1,lg:1.5,xl:2},typography:{fontSize:{xs:0.75,sm:0.875,base:1,lg:1.125,xl:1.25,"2xl":1.5,"3xl":1.875},fontWeight:{light:300,normal:400,medium:500,semibold:600,bold:700}},borderRadius:{sm:0.125,base:0.25,lg:0.5,xl:0.75},boxShadow:{sm:"0 1px 2px 0 rgba(0, 0, 0, 0.05)",base:"0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)",lg:"0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)"}},b0={...p,name:"dark",colors:{...e,text:{primary:"#ffffff",secondary:"#e2e8f0",muted:"#94a3b8",light:"#000000"},background:{primary:"#1e293b",secondary:"#334155",dark:"#0f172a"},border:{light:"#475569",dark:"#64748b"},syntax:{comment:"#94a3b8",string:"#34d399",number:"#f472b6",keyword:"#60a5fa",function:"#06b6d4",variable:"#e2e8f0",operator:"#fbbf24",type:"#60a5fa",tag:"#fb7185",attr:"#fbbf24",default:"#ffffff"}}};class Q0{currentTheme=p;themes=new Map;constructor(){this.themes.set("default",p),this.themes.set("dark",b0);for(let X of t)this.themes.set(X.id,X.theme)}setTheme(X){let Z=this.themes.get(X);if(Z)this.currentTheme=Z;else throw Error(`Theme '${X}' not found`)}getTheme(){return this.currentTheme}getAvailableThemes(){return Array.from(this.themes.keys())}getCurrentThemeName(){return this.currentTheme.name}getThemeByName(X){return this.themes.get(X)}hasTheme(X){return this.themes.has(X)}}var X0=new Q0;var M0={initializationStatus:"idle",initializationError:null,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null,tasks:[],awaitingSecondCtrlC:!1,thinkingModeEnabled:!1,subagentProgress:null},g=(X)=>({...M0,actions:{setInitializationStatus:(Z)=>{X((Q)=>({app:{...Q.app,initializationStatus:Z}}))},setInitializationError:(Z)=>{X((Q)=>({app:{...Q.app,initializationError:Z}}))},setActiveModal:(Z)=>{X((Q)=>({app:{...Q.app,activeModal:Z}}))},showSessionSelector:(Z)=>{X((Q)=>({app:{...Q.app,activeModal:"sessionSelector",sessionSelectorData:Z}}))},showModelEditWizard:(Z)=>{X((Q)=>({app:{...Q.app,activeModal:"modelEditWizard",modelEditorTarget:Z}}))},closeModal:()=>{X((Z)=>({app:{...Z.app,activeModal:"none",sessionSelectorData:void 0,modelEditorTarget:null}}))},setTasks:(Z)=>{X((Q)=>({app:{...Q.app,tasks:Z}}))},updateTask:(Z)=>{X((Q)=>({app:{...Q.app,tasks:Q.app.tasks.map(($)=>$.id===Z.id?Z:$)}}))},setAwaitingSecondCtrlC:(Z)=>{X((Q)=>({app:{...Q.app,awaitingSecondCtrlC:Z}}))},setThinkingModeEnabled:(Z)=>{X((Q)=>({app:{...Q.app,thinkingModeEnabled:Z}}))},toggleThinkingMode:()=>{X((Z)=>({app:{...Z.app,thinkingModeEnabled:!Z.app.thinkingModeEnabled}}))},startSubagentProgress:(Z,Q,$)=>{X((Y)=>({app:{...Y.app,subagentProgress:{id:Z,type:Q,description:$,status:"running",startTime:Date.now()}}}))},updateSubagentTool:(Z)=>{X((Q)=>{if(!Q.app.subagentProgress)return Q;return{app:{...Q.app,subagentProgress:{...Q.app.subagentProgress,currentTool:Z}}}})},completeSubagentProgress:(Z)=>{X((Q)=>{if(!Q.app.subagentProgress)return Q;return{app:{...Q.app,subagentProgress:{...Q.app.subagentProgress,status:Z?"completed":"failed",currentTool:void 0}}}}),setTimeout(()=>{X((Q)=>({app:{...Q.app,subagentProgress:null}}))},1500)}}});var T0={isProcessing:!1,abortController:null,pendingCommands:[]},d=(X,Z)=>({...T0,actions:{setProcessing:(Q)=>{X(($)=>({command:{...$.command,isProcessing:Q}}))},createAbortController:()=>{let Q=Z().command.abortController;if(Q&&!Q.signal.aborted)Q.abort("interrupted-by-new-command");let $=new AbortController;return X((Y)=>({command:{...Y.command,abortController:$}})),$},getAbortController:()=>{return Z().command.abortController},clearAbortController:(Q)=>{let $=Z().command.abortController;if(Q!==void 0&&$!==Q)return;X((Y)=>({command:{...Y.command,abortController:null}}))},abort:(Q)=>{let{abortController:$}=Z().command;if($&&!$.signal.aborted)$.abort(Q??"user-cancel");X((Y)=>({command:{...Y.command,isProcessing:!1,pendingCommands:[]}}))},enqueueCommand:(Q)=>{X(($)=>({command:{...$.command,pendingCommands:[...$.command.pendingCommands,Q]}}))},dequeueCommand:()=>{let{pendingCommands:Q}=Z().command;if(Q.length===0)return;let[$,...Y]=Q;return X((V)=>({command:{...V.command,pendingCommands:Y}})),$},clearQueue:()=>{X((Q)=>({command:{...Q.command,pendingCommands:[]}}))}}});var N0={config:null},m=(X)=>({...N0,actions:{setConfig:(Z)=>{X((Q)=>({config:{...Q.config,config:Z}}))},updateConfig:(Z)=>{X((Q)=>{if(!Q.config.config)throw Error(`[ConfigSlice] Config not initialized. Cannot update: ${JSON.stringify(Z)}`);return{config:{...Q.config,config:{...Q.config.config,...Z}}}})}}});var u0={currentFocus:"main-input",previousFocus:null},r=(X)=>({...u0,actions:{setFocus:(Z)=>{X((Q)=>({focus:{...Q.focus,currentFocus:Z,previousFocus:Q.focus.currentFocus}}))},restorePreviousFocus:()=>{X((Z)=>({focus:{...Z.focus,currentFocus:Z.focus.previousFocus||"main-input",previousFocus:null}}))}}});import{nanoid as p0}from"nanoid";var c={"deepseek-chat":{input:0.27,output:1.1},"deepseek-coder":{input:0.14,output:0.28},"deepseek-reasoner":{input:0.55,output:2.19},"deepseek-v3":{input:0.27,output:1.1},"deepseek-v4":{input:0.27,output:1.1},"deepseek-v4-pro":{input:0.27,output:1.1},"deepseek-v4-0724":{input:0.27,output:1.1},"gpt-4o":{input:2.5,output:10},"gpt-4o-mini":{input:0.15,output:0.6},"gpt-4.1":{input:2,output:8},"gpt-4.1-mini":{input:0.4,output:1.6},"gpt-4.1-nano":{input:0.1,output:0.4},"gpt-4-turbo":{input:10,output:30},"gpt-4":{input:30,output:60},"gpt-3.5-turbo":{input:0.5,output:1.5},o1:{input:15,output:60},"o1-mini":{input:3,output:12},"o1-pro":{input:150,output:600},o3:{input:10,output:40},"o3-mini":{input:1.1,output:4.4},"o4-mini":{input:1.1,output:4.4},"claude-3.5-sonnet":{input:3,output:15,cacheRead:0.3,cacheWrite:3.75},"claude-3.5-haiku":{input:0.8,output:4,cacheRead:0.08,cacheWrite:1},"claude-sonnet-4":{input:3,output:15,cacheRead:0.3,cacheWrite:3.75},"claude-4-opus":{input:15,output:75,cacheRead:1.5,cacheWrite:18.75},"claude-opus-4":{input:15,output:75,cacheRead:1.5,cacheWrite:18.75},"qwen-plus":{input:0.8,output:2},"qwen-max":{input:2,output:6},"qwen-turbo":{input:0.3,output:0.6},"qwen3-235b":{input:2,output:8},"gemini-2.5-pro":{input:1.25,output:10},"gemini-2.5-flash":{input:0.15,output:0.6}};function h0(X){let Z=X.toLowerCase();if(c[Z])return c[Z];for(let[Q,$]of Object.entries(c))if(Z.includes(Q)||Q.includes(Z))return $;return}function Z0(X,Z,Q,$,Y){let V=h0(X);if(!V)return 0;let J=Z/1e6*V.input+Q/1e6*V.output;if($&&V.cacheRead)J+=$/1e6*V.cacheRead;if(Y&&V.cacheWrite)J+=Y/1e6*V.cacheWrite;return Math.round(J*1e6)/1e6}var K={codeBlock:/^```(\w+)?\s*$/,heading:/^ *(#{1,4}) +(.+)/,blockquote:/^(>+)\s?(.*)/,ulItem:/^([ \t]*)([-*+]) +(.+)/,olItem:/^([ \t]*)(\d+)\. +(.+)/,hr:/^ *([-*_] *){3,} *$/,table:/^\|(.+)\|$/,tableSeparator:/^\|[\s]*:?-+:?[\s]*(\|[\s]*:?-+:?[\s]*)+\|?$/,diffStart:/^<<<DIFF>>>$/,diffEnd:/^<<<\/DIFF>>>$/,commandMessage:/<command-message>(.*?)<\/command-message>/};function G1(X){let Z=[],Q=X.split(/\r?\n/),$=!1,Y=[],V=null,J=0,G=!1,U=[],H=[],W=!1,D=[],v=!1,O=[],z=0,j=!0;for(let L=0;L<Q.length;L++){let _=Q[L];if(W){if(_.match(K.diffEnd)){try{let B=JSON.parse(D.join(`
|
|
2
2
|
`));Z.push({type:"diff",content:"",diffData:{patch:B.patch,startLine:B.startLine,matchLine:B.matchLine}})}catch(B){Z.push({type:"text",content:D.join(`
|
|
3
3
|
`)})}W=!1,D=[],j=!1;continue}D.push(_);continue}if(_.match(K.diffStart)){W=!0,D=[],j=!1;continue}if($){let B=_.match(K.codeBlock),E=_.trim()==="```";if(B&&B[1])J++,Y.push(_);else if(E)if(J>0)J--,Y.push(_);else{let _0=Y.join(`
|
|
4
4
|
`);Z.push({type:"code",content:_0,language:V||void 0}),$=!1,Y=[],V=null,J=0,j=!1}else Y.push(_);continue}let s=_.match(K.codeBlock);if(s){$=!0,V=s[1]||null,J=0,j=!1;continue}let b=_.match(K.table),O0=_.match(K.tableSeparator);if(b&&!G){if(L+1<Q.length){if(Q[L+1].match(K.tableSeparator)){G=!0,U=b[1].split("|").map((E)=>E.trim()).filter((E)=>E.length>0),H=[],j=!1;continue}}}if(G&&O0)continue;if(G&&b){let B=b[1].split("|").map((E)=>E.trim()).filter((E)=>E.length>0);while(B.length<U.length)B.push("");if(B.length>U.length)B.length=U.length;H.push(B);continue}if(G&&!b){if(U.length>0&&H.length>0)Z.push({type:"table",content:"",tableData:{headers:U,rows:H}});G=!1,U=[],H=[]}let f=_.match(K.blockquote);if(f){let B=f[1].length,E=f[2]||"";if(v&&B===z)O.push(E);else{if(v)Z.push({type:"blockquote",content:O.join(`
|
|
@@ -73,4 +73,4 @@ ${Q.structure}`);return $.length>0?$.join(`
|
|
|
73
73
|
`+`1. 配置文件格式正确 (~/.blade/config.json)
|
|
74
74
|
`+`2. 运行 blade 进行首次配置
|
|
75
75
|
`+"3. 配置文件权限正确")}finally{I=null}})(),I}var Z5=()=>q().config.config?.models??[],$5=()=>{let X=y();if(!X)return;let Z=X.currentModelId;return X.models.find(($)=>$.id===Z)??X.models[0]},Y5=(X)=>{let Z=y();if(!Z)return;return Z.models.find((Q)=>Q.id===X)},V5=()=>q().config.config?.mcpServers??{},J5=()=>q().app.thinkingModeEnabled,G5=()=>({setPermissionMode:async(X)=>{q().config.actions.updateConfig({permissionMode:X})},setTheme:async(X,Z={})=>{try{X0.setTheme(X)}catch{return}q().config.actions.updateConfig({theme:X}),await A().save({theme:X},{scope:"global",...Z})},setLanguage:async(X,Z={})=>{q().config.actions.updateConfig({language:X}),await A().save({language:X},{scope:"global",...Z})},setDebug:async(X,Z={})=>{q().config.actions.updateConfig({debug:X}),await A().save({debug:X},{scope:"global",...Z})},setTemperature:async(X,Z={})=>{q().config.actions.updateConfig({temperature:X}),await A().save({temperature:X},{scope:"global",...Z})},updateConfig:async(X,Z={})=>{let Q=y();if(!Q)throw Error("Config not initialized");let $={...Q};q().config.actions.updateConfig(X);try{await A().save(X,Z)}catch(Y){throw q().config.actions.setConfig($),Y}},flush:async()=>{await A().flush()},appendPermissionAllowRule:async(X,Z={})=>{let Q=y();if(!Q)throw Error("Config not initialized");let $=Q.permissions?.allow||[];if(!$.includes(X)){let Y=[...$,X];q().config.actions.updateConfig({permissions:{...Q.permissions,allow:Y}})}await A().appendPermissionRule(X,Z)},appendLocalPermissionAllowRule:async(X,Z={})=>{let Q=y();if(!Q)throw Error("Config not initialized");let $=Q.permissions?.allow||[];if(!$.includes(X)){let Y=[...$,X];q().config.actions.updateConfig({permissions:{...Q.permissions,allow:Y}})}await A().appendLocalPermissionRule(X,Z)},setCurrentModel:async(X,Z={})=>{let Q=y();if(!Q)throw Error("Config not initialized");if(!Q.models.find((Y)=>Y.id===X))throw Error(`Model not found: ${X}`);q().config.actions.updateConfig({currentModelId:X}),await A().save({currentModelId:X},{scope:"global",...Z})},addModel:async(X,Z={})=>{let Q=y();if(!Q)throw Error("Config not initialized");let $="id"in X?X:{id:i0(),...X},V={models:[...Q.models,$]};if(Q.models.length===0)V.currentModelId=$.id;return q().config.actions.updateConfig(V),await A().save(V,{scope:"global",...Z}),$},updateModel:async(X,Z,Q={})=>{let $=y();if(!$)throw Error("Config not initialized");let Y=$.models.findIndex((J)=>J.id===X);if(Y===-1)throw Error(`Model not found: ${X}`);let V=[...$.models];V[Y]={...V[Y],...Z},q().config.actions.updateConfig({models:V}),await A().save({models:V},{scope:"global",...Q})},removeModel:async(X,Z={})=>{let Q=y();if(!Q)throw Error("Config not initialized");if(Q.models.length===1)throw Error("Cannot remove the only model");let $=Q.models.filter((V)=>V.id!==X),Y={models:$};if(Q.currentModelId===X)Y.currentModelId=$[0].id;q().config.actions.updateConfig(Y),await A().save(Y,{scope:"global",...Z})},addMcpServer:async(X,Z,Q={})=>{let $=y();if(!$)throw Error("Config not initialized");let V={...$.mcpServers??{},[X]:Z};q().config.actions.updateConfig({mcpServers:V}),await A().save({mcpServers:V},{scope:"project",...Q})},removeMcpServer:async(X,Z={})=>{let Q=y();if(!Q)throw Error("Config not initialized");let Y={...Q.mcpServers??{}};delete Y[X],q().config.actions.updateConfig({mcpServers:Y}),await A().save({mcpServers:Y},{scope:"project",...Z})}});
|
|
76
|
-
export{t as
|
|
76
|
+
export{t as da,X0 as ea,K as fa,G1 as ga,H1 as ha,z1 as ia,W1 as ja,F1 as ka,K1 as la,q1 as ma,T as na,A1 as oa,N as pa,a0 as qa,q as ra,t1 as sa,e1 as ta,Q5 as ua,y as va,X5 as wa,Z5 as xa,$5 as ya,Y5 as za,V5 as Aa,J5 as Ba,G5 as Ca};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{v as a,w as b,x as c}from"./chunk-zvk6ktj1.js";import"./chunk-h7qab07x.js";import"./chunk-qyfdt8h1.js";import"./chunk-k9h9bw13.js";import"./chunk-867h27ke.js";import"./chunk-7ycmx7c2.js";import"./chunk-mt1c5da4.js";import"./chunk-0afbeec0.js";export{a as validatePermissions,c as validateOutput,b as loadConfiguration};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
2
|
-
`)}function Y0(V,$){let f=($??[]).filter((M)=>M.type==="image"&&typeof M.content==="string").map((M)=>({type:"image_url",image_url:{url:M.content}}));if(f.length===0)return V;let O=[];if(V.trim())O.push({type:"text",text:V});return O.push(...f),O}var Wf=()=>{let V=new ef,$=new Map;return V.get("/",async(f)=>{try{let O=await h.listSessions(),M=new Set(O.filter((G)=>G.relationType==="subagent").map((G)=>G.sessionId)),Q=Array.from(B.values()).filter((G)=>!M.has(G.id)&&G.relationType!=="subagent").map((G)=>({sessionId:G.id,projectPath:G.projectPath,title:G.title,parentId:void 0,relationType:void 0,status:void 0,agentType:void 0,model:void 0,messageCount:G.messages.length,firstMessageTime:G.createdAt.toISOString(),lastMessageTime:new Date().toISOString(),hasErrors:!1,isActive:!0})),J=new Set(Q.map((G)=>G.sessionId)),Z=O.filter((G)=>!B.has(G.sessionId)&&!J.has(G.sessionId)&&G.relationType!=="subagent"),j=new Set(J),Y=Z.filter((G)=>{if(j.has(G.sessionId))return!1;return j.add(G.sessionId),!0}),K=[...Q,...Y];return f.json(K)}catch(O){return E.error("[SessionRoutes] Failed to list sessions:",O),f.json([])}}),V.post("/",async(f)=>{try{let O=await f.req.json(),M=V0.safeParse(O);if(!M.success)throw new A("Invalid request body");let{title:Q,projectPath:J}=M.data,Z=d(12),j=J||f.get("directory")||X(),Y={id:Z,projectPath:j,title:Q||`Session ${Z.slice(0,6)}`,createdAt:new Date,messages:[]};return B.set(Z,Y),f.json({sessionId:Z,projectPath:j,title:Y.title,parentId:void 0,relationType:void 0,status:void 0,agentType:void 0,model:void 0,messageCount:0,firstMessageTime:Y.createdAt.toISOString(),lastMessageTime:Y.createdAt.toISOString(),hasErrors:!1})}catch(O){throw E.error("[SessionRoutes] Failed to create session:",O),O}}),V.get("/:sessionId",async(f)=>{let O=f.req.param("sessionId"),M=B.get(O);if(M)return f.json({sessionId:M.id,projectPath:M.projectPath,title:M.title,messageCount:M.messages.length,firstMessageTime:M.createdAt.toISOString(),lastMessageTime:new Date().toISOString(),hasErrors:!1,isActive:!0});try{let J=(await h.listSessions()).find((Z)=>Z.sessionId===O);if(!J)throw new P("Session",O);return f.json(J)}catch(Q){if(Q instanceof P)throw Q;throw E.error("[SessionRoutes] Failed to get session:",Q),Q}}),V.patch("/:sessionId",async(f)=>{let O=f.req.param("sessionId");try{let M=await f.req.json(),Q=M0.safeParse(M);if(!Q.success)throw new A("Invalid request body");let{title:J}=Q.data,Z=B.get(O);if(Z&&J)Z.title=J;return f.json({success:!0,title:J})}catch(M){throw E.error("[SessionRoutes] Failed to update session:",M),M}}),V.delete("/:sessionId",async(f)=>{let O=f.req.param("sessionId"),M=B.get(O);if(M?.currentRunId){let J=D.get(M.currentRunId);if(J)J.abortController.abort(),g.publish(O,"run.cancelled",{runId:J.id}),D.delete(M.currentRunId)}try{await h.deleteSession(O)}catch(J){E.warn("[SessionRoutes] Failed to delete session file:",J)}B.delete(O);let Q=$.get(O);if(Q){if(await Q.dispose(),$.delete(O),$.size===0)await T.getInstance().disconnectAll()}return f.json({success:!0})}),V.get("/:sessionId/message",async(f)=>{let O=f.req.param("sessionId");try{let M=await h.loadSession(O);return f.json(M)}catch(M){return E.error("[SessionRoutes] Failed to get messages:",M),f.json([])}}),V.get("/:sessionId/events",async(f)=>{let O=f.req.param("sessionId"),M=B.get(O);if(!M){let Q=f.get("directory")||X();M={id:O,projectPath:Q,title:`Session ${O.slice(0,6)}`,createdAt:new Date,messages:[]},B.set(O,M)}return f0(f,async(Q)=>{await Q.writeSSE({data:JSON.stringify({type:"connected",properties:{sessionId:O,timestamp:Date.now()}})});let Z=g.subscribe((Y)=>{if(Y.sessionId!==O)return;Q.writeSSE({data:JSON.stringify({type:Y.type,properties:{sessionId:Y.sessionId,...Y.properties}})}).catch(()=>{})}),j=setInterval(()=>{if(!Q.aborted)Q.writeSSE({data:JSON.stringify({type:"heartbeat",properties:{timestamp:Date.now()}})}).catch(()=>{})},15000);Q.onAbort(()=>{clearInterval(j),Z()});while(!0)if(await new Promise((Y)=>setTimeout(Y,1000)),Q.aborted)break})}),V.post("/:sessionId/message",async(f)=>{let O=f.req.param("sessionId"),M=await f.req.json(),Q=O0.safeParse(M);if(!Q.success)throw new A("Invalid message format");let{content:J,attachments:Z,permissionMode:j}=Q.data,Y=j||"default",K=f.get("directory")||X(),G=Y0(J,Z),x=B.get(O);if(!x){let N=await h.loadSession(O).catch(()=>[]);x={id:O,projectPath:K,title:`Session ${O.slice(0,6)}`,createdAt:new Date,messages:N},B.set(O,x)}let q=d(12),L=new AbortController,m={id:q,sessionId:O,status:"running",abortController:L,createdAt:new Date};return D.set(q,m),x.currentRunId=q,Z0(m,x,G,Y,$).catch((N)=>{E.error(`[SessionRoutes] Run ${q} failed:`,N)}),f.json({runId:q,status:"running"},202)}),V.post("/:sessionId/abort",async(f)=>{let O=f.req.param("sessionId"),M=B.get(O);if(M?.currentRunId){let Q=D.get(M.currentRunId);if(Q)Q.abortController.abort(),Q.status="cancelled",g.publish(O,"run.cancelled",{runId:Q.id})}return f.json({success:!0})}),V.get("/:sessionId/status",async(f)=>{let O=f.req.param("sessionId"),M=B.get(O);if(!M?.currentRunId)return f.json({sessionId:O,status:"idle"});let Q=D.get(M.currentRunId);return f.json({sessionId:O,runId:M.currentRunId,status:Q?.status||"idle"})}),V};async function Z0(V,$,f,O,M){let{abortController:Q,sessionId:J,id:Z}=V,j=d(12),Y=d(12),K=(G,x)=>{g.publish(J,G,x)};try{K("message.created",{messageId:j,role:"user",content:Q0(f)}),K("session.status",{status:"running"}),K("message.created",{messageId:Y,role:"assistant",content:""});let G=M.get(J);if(!G)G=await Ff.create({sessionId:J}),M.set(J,G);let x=await Bf.createWithRuntime(G,{sessionId:J}),q=async(N)=>{let F=d(12),l=300000;V.status="waiting_permission";let ff=new Promise((jf)=>{let rf=setTimeout(()=>{E.warn(`[SessionRoutes] Permission ${F} timed out after 300000ms`),K("permission.timeout",{requestId:F}),jf({approved:!1,reason:"timeout"})},300000);V.pendingPermission={permissionId:F,resolve:(lf)=>{clearTimeout(rf),jf(lf)},details:N}});K("permission.asked",{requestId:F,toolName:N.toolName,description:N.message,args:N.args,details:N}),E.info(`[SessionRoutes] Permission request created: ${F}, runId: ${Z}`);let Kf=await ff;return E.info(`[SessionRoutes] Permission response received: ${F}, approved: ${Kf.approved}`),V.status="running",V.pendingPermission=void 0,Kf},L={messages:[...$.messages],userId:"web-user",sessionId:J,workspaceRoot:$.projectPath,signal:Q.signal,permissionMode:O,confirmationHandler:{requestConfirmation:q}},m=await mf(x.chatStream(f,L,{stream:!0}),async(N)=>{switch(N.kind){case"content_delta":K("message.delta",{messageId:Y,delta:N.delta});break;case"thinking_delta":K("thinking.delta",{delta:N.delta});break;case"tool_start":if("function"in N.toolCall)K("tool.start",{messageId:Y,toolName:N.toolCall.function.name,toolCallId:N.toolCall.id,arguments:N.toolCall.function.arguments,toolKind:N.toolKind});break;case"tool_result":if("function"in N.toolCall)K("tool.result",{messageId:Y,toolName:N.toolCall.function.name,toolCallId:N.toolCall.id,success:N.result.success,summary:N.result.metadata?.summary,output:qf(Uf(N.toolCall.function.name,N.result)),metadata:J0(N.result.metadata)});break;case"token_usage":K("token.usage",{...N.usage});break;case"turn_start":K("turn.started",{turn:N.turn,maxTurns:N.maxTurns});break;case"compaction":K(N.phase==="start"?"compaction.started":"compaction.completed",{});break;case"model_fallback":K("model.fallback",{});break;case"task_update":K("task.updated",{tasks:N.tasks});break;default:break}});$.messages=[...L.messages],K("message.complete",{messageId:Y}),K("thinking.completed",{}),V.status="completed",K("session.completed",{runId:Z,outputTruncated:m.metadata?.outputTruncated??!1}),K("session.status",{status:"idle"})}catch(G){E.error("[SessionRoutes] Agent execution error:",G),V.status="failed",K("session.error",{error:G instanceof Error?G.message:"Unknown error"}),K("session.status",{status:"error"})}}function Af(V,$,f){E.info(`[SessionRoutes] Looking for permission ${$} in session ${V}`),E.info(`[SessionRoutes] Active runs: ${D.size}`);for(let[O,M]of D.entries())if(E.info(`[SessionRoutes] Checking run ${O}: sessionId=${M.sessionId}, pendingPermission=${M.pendingPermission?.permissionId}`),M.sessionId===V&&M.pendingPermission?.permissionId===$)return M.pendingPermission.resolve(f),E.info(`[SessionRoutes] Permission ${$} responded, runId: ${M.id}`),!0;return E.error(`[SessionRoutes] Permission not found: ${$}`),!1}var Vf=R("Service"),j0=C.object({approved:C.boolean(),remember:C.boolean().optional(),scope:C.enum(["once","session"]).optional(),targetMode:C.enum(["default","autoEdit","plan","spec","yolo"]).optional(),feedback:C.string().optional(),answers:C.record(C.union([C.string(),C.array(C.string())])).optional()}),Cf=()=>{let V=new K0;return V.post("/:permissionId",async($)=>{let f=$.req.param("permissionId"),O=$.req.query("sessionId");Vf.info(`[PermissionRoutes] Received permission response: permissionId=${f}, sessionId=${O}`);try{let M=await $.req.json(),Q=j0.safeParse(M);if(!Q.success)throw new A("Invalid permission response format");let{approved:J,remember:Z,scope:j,targetMode:Y,feedback:K,answers:G}=Q.data;if(!O)throw new A("sessionId query parameter is required");if(!Af(O,f,{approved:J,reason:K,scope:j,targetMode:Y,feedback:K,answers:G}))throw new P("Permission request",f);return Vf.info(`[PermissionRoutes] Permission ${f} ${J?"approved":"denied"}`),$.json({success:!0,approved:J,remember:Z})}catch(M){throw Vf.error("[PermissionRoutes] Failed to respond to permission:",M),M}}),V};import{Hono as G0}from"hono";var Hf=R("Service"),yf=()=>{let V=new G0;return V.get("/",async($)=>{try{let f=await zf();return $.json(f)}catch(f){return Hf.error("[ProviderRoutes] Failed to list providers:",f),$.json([])}}),V.get("/:provider/models",async($)=>{let f=$.req.param("provider");try{let O=await Tf(f);return $.json(O)}catch(O){return Hf.error("[ProviderRoutes] Failed to list models:",O),$.json([])}}),V};import{Hono as N0}from"hono";import*as y from"node:fs/promises";import{homedir as x0}from"node:os";import*as n from"node:path";var b=R("Service"),Of=n.join(x0(),".blade","skills-config.json");async function Df(){try{let V=await y.readFile(Of,"utf-8");return JSON.parse(V)}catch{return{disabled:[]}}}async function R0(V){await y.mkdir(n.dirname(Of),{recursive:!0}),await y.writeFile(Of,JSON.stringify(V,null,2))}async function X0(V,$){let f=await Df();if($)f.disabled=f.disabled.filter((O)=>O!==V);else if(!f.disabled.includes(V))f.disabled.push(V);await R0(f)}var I=null,E0=300000;async function m0(){if(I&&Date.now()-I.timestamp<E0)return I.data;try{let V=await fetch("https://api.github.com/repos/anthropics/skills/contents/skills",{headers:{Accept:"application/vnd.github.v3+json","User-Agent":"Blade-Skills-Catalog"}});if(!V.ok)return b.warn(`GitHub API returned ${V.status}`),I?.data||[];let $=await V.json(),f=[];for(let O of $){if(O.type!=="dir")continue;let M=`Official ${O.name} skill`;try{let Q=await fetch(`https://raw.githubusercontent.com/anthropics/skills/main/skills/${O.name}/SKILL.md`,{headers:{"User-Agent":"Blade-Skills-Catalog"}});if(Q.ok){let Z=(await Q.text()).match(/^#[^\n]*\n+([^\n#]+)/);if(Z)M=Z[1].trim().slice(0,100)}}catch{}f.push({name:O.name,description:M,tag:"Official",author:"Anthropic"})}return I={data:f,timestamp:Date.now()},f}catch(V){return b.warn("Failed to fetch skills catalog from GitHub:",V),I?.data||[]}}var bf=()=>{let V=new N0;return V.get("/",async($)=>{try{let f=t();await f.initialize();let O=f.getAll(),M=await Df(),Q=O.map((J)=>({id:J.name,name:J.name,enabled:!M.disabled.includes(J.name),description:J.description||"",version:J.version||"1.0.0",provider:"Local",location:J.source==="builtin"?"Built-in":J.basePath,capabilities:["prompts"],allowedTools:J.allowedTools||[]}));return $.json(Q)}catch(f){return b.error("[SkillsRoutes] Failed to get skills:",f),$.json([])}}),V.post("/:name/toggle",async($)=>{try{let f=$.req.param("name"),O=await $.req.json();return await X0(f,O.enabled),$.json({success:!0,enabled:O.enabled})}catch(f){return b.error("[SkillsRoutes] Failed to toggle skill:",f),$.json({success:!1,error:f.message},500)}}),V.delete("/:name",async($)=>{try{let f=$.req.param("name"),O=`${process.env.HOME}/.blade/skills/${f}`;return await y.rm(O,{recursive:!0,force:!0}),await t().refresh(),$.json({success:!0})}catch(f){return b.error("[SkillsRoutes] Failed to uninstall skill:",f),$.json({success:!1,error:f.message},500)}}),V.post("/install",async($)=>{try{let f=await $.req.json(),O=_f(),M=t(),Q=!1;if(f.source==="catalog"&&f.name){if(Q=await O.installOfficialSkill(f.name),!Q)return $.json({success:!1,error:"Failed to install skill from catalog"},500)}else if(f.source==="repo"&&f.url){if(Q=await O.installFromRepo(f.url,f.name),!Q)return $.json({success:!1,error:"Failed to install skill from repository. Make sure the repo contains a SKILL.md file."},500)}else if(f.source==="local"&&f.path){if(Q=await O.installFromLocal(f.path,f.name),!Q)return $.json({success:!1,error:"Failed to install skill from local path. Make sure the path exists and contains a SKILL.md file."},500)}else return $.json({success:!1,error:"Invalid install parameters. Required: source with corresponding url/path/name"},400);return await M.refresh(),$.json({success:!0})}catch(f){return b.error("[SkillsRoutes] Failed to install skill:",f),$.json({success:!1,error:f.message},500)}}),V.get("/catalog",async($)=>{try{let f=await m0();return $.json(f)}catch(f){return b.error("[SkillsRoutes] Failed to get catalog:",f),$.json([])}}),V};import F0 from"fast-glob";import{Hono as U0}from"hono";import{execSync as q0}from"node:child_process";import{readdir as B0}from"node:fs/promises";import i from"node:path";var r=R("Service"),W0=(V)=>{try{return q0("git rev-parse --abbrev-ref HEAD",{cwd:V,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||null}catch{return null}},A0=[...s.map((V)=>`${V}/**`),...s,...Mf.map((V)=>`**/${V}`)],C0=new Set(["/theme","/model","/permissions","/mcp","/skills","/exit","/resume","/ide","/login","/logout"]),Pf=()=>{let V=new U0;return V.get("/commands",async($)=>{try{let f=$.req.query("q")||"",O=Lf(f).filter((M)=>!C0.has(M.command));return $.json(O)}catch(f){return r.error("[SuggestionsRoutes] Failed to get command suggestions:",f),$.json([])}}),V.get("/files",async($)=>{try{let f=$.req.query("q")||"",O=$.get("directory")||X(),M=Math.min(Number($.req.query("limit"))||100,1000),J=(await F0("**/*",{cwd:O,dot:!1,followSymbolicLinks:!1,onlyFiles:!1,markDirectories:!0,unique:!0,ignore:A0})).map((Y)=>Y.replace(/\\/g,"/"));if(!f)return $.json(J.slice(0,M));let Z=f.toLowerCase(),j=J.filter((Y)=>Y.toLowerCase().includes(Z)).slice(0,M);return $.json(j)}catch(f){return r.error("[SuggestionsRoutes] Failed to get file suggestions:",f),$.json([])}}),V.get("/files/tree",async($)=>{try{let f=$.get("directory")||X(),O=$.req.query("path")||"",M=O?i.join(f,O):f,J=(await B0(M,{withFileTypes:!0})).map((Y)=>({name:Y.name,path:O?`${O}/${Y.name}`:Y.name,type:Y.isDirectory()?"dir":"file"}));J.sort((Y,K)=>{if(Y.type!==K.type)return Y.type==="dir"?-1:1;return Y.name.localeCompare(K.name)});let Z=new Set(s),j=J.filter((Y)=>{let K=Y.name;if(K.startsWith("."))return!1;if(Z.has(K))return!1;for(let G of Mf)if(K.match(new RegExp(G.replace("*",".*"))))return!1;return!0});return $.json(j)}catch(f){return r.error("[SuggestionsRoutes] Failed to get file tree:",f),$.json([])}}),V.get("/files/content",async($)=>{try{let f=$.req.query("path");if(!f)return $.json({error:"Missing file path"},400);let O=$.get("directory")||X(),M=i.resolve(O,f),Q=i.relative(O,M);if(Q.startsWith("..")||i.isAbsolute(Q))return $.json({error:"Invalid file path"},400);let J=wf(),Z=await J.stat(M);if(!Z?.isFile)return $.json({error:"File not found"},404);let j=200000,Y=await J.readTextFile(M),K=Y.length>j;return $.json({path:f,content:K?Y.slice(0,j):Y,truncated:K,size:Z.size})}catch(f){return r.error("[SuggestionsRoutes] Failed to get file content:",f),$.json({error:"Failed to read file"},500)}}),V.get("/git-info",async($)=>{try{let f=$.get("directory")||X(),O=W0(f);return $.json({branch:O})}catch(f){return r.error("[SuggestionsRoutes] Failed to get git info:",f),$.json({branch:null})}}),V};import{Hono as H0}from"hono";var _=R("Service"),v=new Map,kf=2097152,Sf=65536;function uf(){return typeof globalThis.Bun<"u"}async function z0(V,$,f){if(uf()){let{spawn:Q}=await import("bun-pty"),J=Q(V,$,{name:"xterm-256color",cwd:f.cwd,env:f.env});return{pid:J.pid,write:(Z)=>J.write(Z),resize:(Z,j)=>J.resize(Z,j),kill:()=>J.kill(),onData:(Z)=>J.onData(Z),onExit:(Z)=>J.onExit(Z)}}let M=(await import("node-pty")).spawn(V,$,{name:"xterm-256color",cwd:f.cwd,env:f.env,cols:80,rows:24});return{pid:M.pid,write:(Q)=>M.write(Q),resize:(Q,J)=>M.resize(Q,J),kill:()=>M.kill(),onData:(Q)=>{M.onData(Q)},onExit:(Q)=>{M.onExit(Q)}}}var Yf=void 0,Qf;if(uf())try{let{createBunWebSocket:V}=await import("hono/bun"),$=V();Qf=$.upgradeWebSocket,Yf=$.websocket}catch(V){_.warn("[Terminal] Failed to initialize Bun WebSocket support:",V)}async function hf(V,$){let f=`term-${Date.now()}`;_.info(`[Terminal] New connection: ${f}, cwd: ${V}`);let O=process.platform==="win32"?"powershell.exe":process.env.SHELL||"/bin/zsh",M=O.endsWith("sh")?["-l"]:[],Q=await z0(O,M,{cwd:V,env:{...process.env,TERM:"xterm-256color",COLORTERM:"truecolor"}}),J={id:f,process:Q,cwd:V,buffer:"",subscribers:new Set};if(v.set(f,J),J.subscribers.add($),Q.onData((Z)=>{let j=!1;for(let Y of J.subscribers)try{Y.send(Z),j=!0}catch{J.subscribers.delete(Y)}if(j)return;if(J.buffer+=Z,J.buffer.length>kf)J.buffer=J.buffer.slice(-kf)}),Q.onExit(({exitCode:Z})=>{_.info(`[Terminal] Process exited: ${f}, code: ${Z}`);for(let j of J.subscribers)try{j.close()}catch{}v.delete(f)}),J.buffer){let Z=J.buffer;J.buffer="";for(let j=0;j<Z.length;j+=Sf)$.send(Z.slice(j,j+Sf))}return{session:J,cleanup:()=>{if(_.info(`[Terminal] Connection closed: ${f}`),J.subscribers.delete($),J.subscribers.size===0){try{J.process.kill()}catch{}v.delete(f)}}}}function If(V,$){V.on("connection",async(f,O)=>{let M=new URL(O.url||"/",`http://${O.headers.host}`);if(!M.pathname.endsWith("/terminal/ws")){f.close();return}let Q=M.searchParams.get("cwd")||$()||X();try{let{session:J,cleanup:Z}=await hf(Q,{send:(j)=>f.send(j),close:()=>f.close()});f.on("message",(j)=>{try{J.process.write(String(j))}catch(Y){_.error("[Terminal] Failed to write to PTY:",Y)}}),f.on("close",Z),f.on("error",Z)}catch(J){_.error("[Terminal] Failed to spawn PTY:",J),f.close()}})}var vf=()=>{let V=new H0;if(V.get("/status",($)=>{let f=Array.from(v.values()).map((O)=>({id:O.id,cwd:O.cwd}));return $.json({active:f.length,terminals:f})}),V.post("/kill/:terminalId",($)=>{let f=$.req.param("terminalId"),O=v.get(f);if(O){try{O.process.kill()}catch{}for(let M of O.subscribers)M.close();return v.delete(f),$.json({success:!0})}return $.json({success:!1,error:"Terminal not found"},404)}),Qf)V.get("/ws",Qf(($)=>{let f=$.req.query("cwd")||$.get("directory")||X(),O;return{async onOpen(M,Q){try{O=await hf(f,{send:(J)=>Q.send(J),close:()=>Q.close()})}catch(J){_.error("[Terminal] Failed to spawn PTY:",J),Q.close()}},onMessage(M){if(!O)return;try{O.session.process.write(String(M.data))}catch(Q){_.error("[Terminal] Failed to write to PTY:",Q)}},onClose(){O?.cleanup()}}}));else V.get("/ws",($)=>{return $.json({message:"WebSocket endpoint - connect via ws:// protocol",hint:"Use WebSocket client to connect to this endpoint"})});return V};var W=R("Service"),Zf=[];function k0(){let V=b0(L0(import.meta.url)),$=[w(V,"web"),w(X(),"dist/web"),w(X(),"packages/cli/dist/web")];for(let f of $){let O=w(f,"index.html");if(gf(O)){if(e(O,"utf-8").includes("/assets/"))return W.debug(`[Server] Found web dist at: ${f}`),f}}return null}function S0(){let V=new T0;V.onError((f,O)=>{if(W.error("[Server] Request error:",f),f instanceof p)return O.json(f.toObject(),f.statusCode);let M=f instanceof Error?f.message:String(f);return O.json({error:{code:"INTERNAL_ERROR",message:M}},500)}),V.use(async(f,O)=>{let M=process.env.BLADE_SERVER_PASSWORD;if(!M)return O();let Q=f.req.path;if(Q==="/"||Q.startsWith("/assets/")||Q.endsWith(".html")||Q.endsWith(".js")||Q.endsWith(".css"))return O();let J=f.req.header("Authorization");if(!J?.startsWith("Basic "))return f.header("WWW-Authenticate",'Basic realm="Blade Server"'),f.json({error:{code:"UNAUTHORIZED",message:"Authentication required"}},401);let Z=Buffer.from(J.slice(6),"base64").toString(),[j,Y]=Z.split(":"),K=process.env.BLADE_SERVER_USERNAME??"blade";if(j!==K||Y!==M)return f.json({error:{code:"UNAUTHORIZED",message:"Invalid credentials"}},401);return O()}),V.use(async(f,O)=>{let M=f.req.path==="/health"||f.req.path==="/global/health"||f.req.path.startsWith("/assets/");if(!M)W.debug(`[Server] ${f.req.method} ${f.req.path}`);let Q=Date.now();if(await O(),!M){let J=Date.now()-Q;W.debug(`[Server] ${f.req.method} ${f.req.path} - ${f.res.status} (${J}ms)`)}}),V.use(y0({origin(f){if(!f)return;if(f.startsWith("http://localhost:"))return f;if(f.startsWith("http://127.0.0.1:"))return f;if(f==="tauri://localhost"||f==="http://tauri.localhost")return f;if(Zf.includes(f))return f;return}})),V.use(async(f,O)=>{let M=f.req.query("directory")||f.req.header("x-blade-directory")||X();try{M=decodeURIComponent(M)}catch{}return f.set("directory",M),O()}),V.route("/global",Nf()),V.route("/sessions",Wf()),V.route("/configs",Gf()),V.route("/permissions",Cf()),V.route("/providers",yf()),V.route("/models",Ef()),V.route("/suggestions",Pf()),V.route("/terminal",vf()),V.route("/mcp",xf()),V.route("/skills",bf()),V.get("/health",(f)=>{return f.json({healthy:!0,version:u()})});let $=k0();if($)W.info(`[Server] Serving static files from ${$}`),V.get("/assets/*",(f)=>{let O=w($,f.req.path);if(!gf(O))return f.json({error:{code:"NOT_FOUND",message:`File not found: ${f.req.path}`}},404);let M=e(O),Q=w0(O).toLowerCase(),Z={".js":"application/javascript",".css":"text/css",".html":"text/html",".json":"application/json",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".ico":"image/x-icon",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".eot":"application/vnd.ms-fontobject"}[Q]||"application/octet-stream";return new Response(M,{headers:{"Content-Type":Z,"Cache-Control":"public, max-age=31536000, immutable"}})}),V.get("/",(f)=>{let O=w($,"index.html"),M=e(O,"utf-8");return f.html(M)}),V.get("*",(f)=>{let O=f.req.path;if(O.includes("."))return f.json({error:{code:"NOT_FOUND",message:`File not found: ${O}`}},404);let M=w($,"index.html"),Q=e(M,"utf-8");return f.html(Q)});else W.warn('[Server] Web UI not found. Run "cd packages/cli/web && bun run build" to enable web interface.'),V.get("/",(f)=>{return f.json({message:"Blade API Server",version:u(),webUI:!1,hint:'Web UI not built. Run "cd packages/cli/web && bun run build" to enable.',endpoints:{health:"/health",sessions:"/sessions",configs:"/configs",permissions:"/permissions",providers:"/providers"}})}),V.all("*",(f)=>{return f.json({error:{code:"NOT_FOUND",message:`Route not found: ${f.req.path}`}},404)});return V}function u0(){let V=D0(),$=[];for(let f of Object.keys(V)){let O=V[f];if(!O)continue;for(let M of O){if(M.internal||M.family!=="IPv4")continue;if(M.address.startsWith("172."))continue;$.push(M.address)}}return $}function pf(){return typeof globalThis.Bun<"u"}function of(V,$){let f=globalThis.Bun,O=(Q)=>{try{return f.serve({hostname:$.hostname,port:Q,fetch:V.fetch,idleTimeout:0,websocket:Yf})}catch(J){W.error("Failed to start Bun server:",J);return}},M=$.port===0?O(4096)??O(0):O($.port);if(!M)throw Error(`Failed to start Bun server on port ${$.port}`);return{url:M.url,port:M.port,hostname:M.hostname,stop:async()=>{M.stop(!0)}}}function h0(V,$){return new Promise((f,O)=>{let M=_0(async(Y,K)=>{let G=new URL(Y.url||"/",`http://${Y.headers.host}`),x=new Headers;for(let[m,N]of Object.entries(Y.headers))if(N)if(Array.isArray(N))for(let F of N)x.append(m,F);else x.set(m,N);let q;if(Y.method!=="GET"&&Y.method!=="HEAD")q=(await new Promise((N)=>{let F=[];Y.on("data",(l)=>F.push(l)),Y.on("end",()=>N(Buffer.concat(F)))})).toString();let L=new Request(G.toString(),{method:Y.method,headers:x,body:q});try{let m=await V.fetch(L);if(K.statusCode=m.status,m.headers.forEach((N,F)=>{K.setHeader(F,N)}),m.body){let N=m.body.getReader(),F=async()=>{let{done:l,value:ff}=await N.read();if(l){K.end();return}return K.write(ff),F()};await F()}else{let N=await m.text();K.end(N)}}catch(m){W.error("[Server] Node request error:",m),K.statusCode=500,K.end(JSON.stringify({error:{code:"INTERNAL_ERROR",message:"Internal server error"}}))}}),Q=new P0({noServer:!0}),J=X();If(Q,()=>J),M.on("upgrade",(Y,K,G)=>{if(new URL(Y.url||"/",`http://${Y.headers.host}`).pathname==="/terminal/ws")Q.handleUpgrade(Y,K,G,(q)=>{Q.emit("connection",q,Y)});else K.destroy()});let Z=(Y)=>{return new Promise((K,G)=>{M.once("error",(x)=>{if(x.code==="EADDRINUSE")G(x);else G(x)}),M.listen(Y,$.hostname,()=>{let x=M.address();if(x&&typeof x==="object")K(x.port);else K(Y)})})};(async()=>{let Y;if($.port===0)try{Y=await Z(4096)}catch{Y=await Z(0)}else Y=await Z($.port);let K=new URL(`http://${$.hostname==="0.0.0.0"?"localhost":$.hostname}:${Y}`);f({url:K,port:Y,hostname:$.hostname,stop:async()=>{return new Promise((G)=>{Q.close(()=>{M.close(()=>G())})})}})})().catch(O)})}var df;((DV)=>{let V,$;function f(){if(!$)$=S0();return $}DV.getApp=f;function O(J){Zf=J.cors??[];let Z=f();if(pf())V=of(Z,J),W.info(`[Server] Blade server listening on ${V.url} (Bun runtime)`);else throw Error("Blade web server requires Bun runtime. Please run with Bun: `bun run blade web` or install Bun from https://bun.sh");let j=V;return{url:j.url,port:j.port,hostname:j.hostname,stop:async()=>{if(V)await V.stop(),V=void 0,$=void 0,W.info("[Server] Blade server stopped")}}}DV.listen=O;async function M(J){Zf=J.cors??[];let Z=f();if(pf())V=of(Z,J),W.info(`[Server] Blade server listening on ${V.url} (Bun runtime)`);else V=await h0(Z,J),W.info(`[Server] Blade server listening on ${V.url} (Node.js runtime)`);let j=V;return{url:j.url,port:j.port,hostname:j.hostname,stop:async()=>{if(V)await V.stop(),V=void 0,$=void 0,W.info("[Server] Blade server stopped")}}}DV.listenAsync=M;function Q(){return V!==void 0}DV.isRunning=Q})(df||={});export{I0 as a,v0 as b,u0 as c,df as d};
|
|
1
|
+
import{j as zf,k as Tf}from"./chunk-v1d0d4b4.js";import{A as wf,C as s,D as Mf,H as Ff,I as g,K as Uf,L as qf,N as Bf,Q as h,X as Lf}from"./chunk-92qcc3gj.js";import{$ as T}from"./chunk-aam53te2.js";import{Ca as z,va as S,xa as Rf,ya as Xf}from"./chunk-k9h9bw13.js";import{Ia as u}from"./chunk-xmdpc0y5.js";import{Oa as _f,Qa as t,Za as mf}from"./chunk-dzmrdtpc.js";import{xb as X}from"./chunk-7ycmx7c2.js";import{Ob as R}from"./chunk-mt1c5da4.js";import{Qb as Jf}from"./chunk-0afbeec0.js";var I0={port:{type:"number",describe:"Port to listen on (0 for auto)",default:0},hostname:{type:"string",describe:"Hostname to listen on",default:"127.0.0.1"},cors:{type:"array",describe:"Additional domains to allow for CORS",default:[]}};function v0(V){return{port:V.port??0,hostname:V.hostname??"127.0.0.1",cors:V.cors??[]}}import{Hono as T0}from"hono";import{cors as y0}from"hono/cors";import{existsSync as gf,readFileSync as e}from"node:fs";import{createServer as _0}from"node:http";import{networkInterfaces as D0}from"node:os";import{dirname as b0,extname as w0,join as w}from"node:path";import{fileURLToPath as L0}from"node:url";import{WebSocketServer as P0}from"ws";import{z as c}from"zod";class p extends Error{code;statusCode;constructor(V,$,f=500){super($);this.code=V;this.statusCode=f;this.name="BladeServerError"}toObject(){return{error:{code:this.code,message:this.message}}}}class P extends p{constructor(V,$){super("NOT_FOUND",$?`${V} not found: ${$}`:`${V} not found`,404)}}class A extends p{constructor(V){super("BAD_REQUEST",V,400)}}var g0=c.object({error:c.object({code:c.string(),message:c.string()})});import{Hono as cf}from"hono";import{z as k}from"zod";var $f=R("Service"),af=k.object({updates:k.record(k.any()),options:k.object({scope:k.enum(["local","project","global"]).optional(),immediate:k.boolean().optional()}).optional()}),Gf=()=>{let V=new cf;return V.get("/",async($)=>{try{let f=S();return $.json(f||{})}catch(f){return $f.error("[ConfigRoutes] Failed to get config:",f),$.json({})}}),V.put("/",async($)=>{try{let f=await $.req.json(),O=af.safeParse(f);if(!O.success)throw new A("Invalid config update format");let{updates:M,options:Q}=O.data;return await z().updateConfig(M,Q),$.json({success:!0,updates:M})}catch(f){throw $f.error("[ConfigRoutes] Failed to update config:",f),f}}),V.get("/permissions",async($)=>{try{let f=S();return $.json(f?.permissions||{})}catch(f){return $f.error("[ConfigRoutes] Failed to get permissions:",f),$.json({})}}),V};import{Hono as tf}from"hono";var Nf=()=>{let V=new tf;return V.get("/health",($)=>{return $.json({healthy:!0,version:u()})}),V.get("/info",($)=>{return $.json({version:u(),platform:process.platform,arch:process.arch,nodeVersion:process.version,cwd:X()})}),V};import{Hono as nf}from"hono";var o=R("Service"),xf=()=>{let V=new nf;return V.get("/",async($)=>{try{let O=T.getInstance().getAllServers(),M=Array.from(O.entries()).map(([Q,J])=>({id:Q,name:Q,status:J.status==="connected"?"connected":J.status==="connecting"?"connecting":J.lastError?"error":"offline",endpoint:J.config.command?`${J.config.command} ${(J.config.args||[]).join(" ")}`.trim():J.config.url||"Unknown",description:`MCP server: ${Q}`,tools:J.tools.map((Z)=>Z.name),connectedAt:J.connectedAt?.toISOString(),error:J.lastError?.message}));return $.json(M)}catch(f){return o.error("[McpRoutes] Failed to get MCP servers:",f),$.json([])}}),V.post("/:name/connect",async($)=>{try{let f=$.req.param("name");return await T.getInstance().connectServer(f),$.json({success:!0})}catch(f){return o.error("[McpRoutes] Failed to connect MCP server:",f),$.json({success:!1,error:f.message},500)}}),V.post("/:name/disconnect",async($)=>{try{let f=$.req.param("name");return await T.getInstance().disconnectServer(f),$.json({success:!0})}catch(f){return o.error("[McpRoutes] Failed to disconnect MCP server:",f),$.json({success:!1,error:f.message},500)}}),V.delete("/:name",async($)=>{try{let f=$.req.param("name");await T.getInstance().unregisterServer(f);let M=S();if(M?.mcpServers){let{[f]:Q,...J}=M.mcpServers;await z().updateConfig({mcpServers:J})}return $.json({success:!0})}catch(f){return o.error("[McpRoutes] Failed to delete MCP server:",f),$.json({success:!1,error:f.message},500)}}),V.post("/",async($)=>{try{let f=await $.req.json(),{name:O,config:M}=f;if(!O||!M)return $.json({success:!1,error:"Missing name or config"},400);await T.getInstance().registerServer(O,M);let J=S();return await z().updateConfig({mcpServers:{...J?.mcpServers,[O]:M}}),$.json({success:!0})}catch(f){return o.error("[McpRoutes] Failed to add MCP server:",f),$.json({success:!1,error:f.message},500)}}),V};import{Hono as sf}from"hono";var a=R("Service"),Ef=()=>{let V=new sf;return V.get("/",async($)=>{try{let f=Rf(),O=Xf();return $.json({configured:f,current:O})}catch(f){return a.error("[ModelsRoutes] Failed to get models:",f),$.json({configured:[],current:null})}}),V.post("/",async($)=>{try{let f=await $.req.json(),{provider:O,name:M,model:Q,baseUrl:J,apiKey:Z}=f;if(!Q)throw new A("model is required");let j=await z().addModel({provider:O||"openai-compatible",name:M||Q,model:Q,baseUrl:J||void 0,apiKey:Z||void 0});return $.json({success:!0,model:j})}catch(f){throw a.error("[ModelsRoutes] Failed to add model:",f),f}}),V.put("/:modelId",async($)=>{try{let f=$.req.param("modelId"),O=await $.req.json(),{baseUrl:M,apiKey:Q,model:J}=O;return await z().updateModel(f,{baseUrl:M||void 0,apiKey:Q||void 0,model:J||void 0}),$.json({success:!0})}catch(f){throw a.error("[ModelsRoutes] Failed to update model:",f),f}}),V.delete("/:modelId",async($)=>{try{let f=$.req.param("modelId");return await z().removeModel(f),$.json({success:!0})}catch(f){throw a.error("[ModelsRoutes] Failed to delete model:",f),f}}),V};import{Hono as K0}from"hono";import{z as C}from"zod";import{Hono as ef}from"hono";import{streamSSE as f0}from"hono/streaming";import{LRUCache as $0}from"lru-cache";import{nanoid as d}from"nanoid";import{z as U}from"zod";var E=R("Service"),V0=U.object({title:U.string().optional(),projectPath:U.string().optional()}),O0=U.object({content:U.string(),attachments:U.array(U.object({type:U.enum(["file","image","url"]),path:U.string().optional(),url:U.string().optional(),content:U.string().optional(),mimeType:U.string().optional(),name:U.string().optional()})).optional(),permissionMode:U.enum(["default","autoEdit","plan","spec","yolo"]).optional()}),M0=U.object({title:U.string().optional()}),B=new Map,D=new $0({max:100,ttl:1800000,dispose:(V,$)=>{if(V.status==="running"||V.status==="waiting_permission")V.abortController.abort(),E.debug(`[SessionRoutes] Run ${$} disposed due to cache eviction`)}}),J0=(V)=>{if(!V||typeof V!=="object")return V;let $={...V},f=200000;if(typeof $.oldContent==="string"&&$.oldContent.length>f)delete $.oldContent;if(typeof $.newContent==="string"&&$.newContent.length>f)delete $.newContent;return $};function Q0(V){if(typeof V==="string")return V;return V.filter(($)=>$.type==="text").map(($)=>$.text).join(`
|
|
2
|
+
`)}function Y0(V,$){let f=($??[]).filter((M)=>M.type==="image"&&typeof M.content==="string").map((M)=>({type:"image_url",image_url:{url:M.content}}));if(f.length===0)return V;let O=[];if(V.trim())O.push({type:"text",text:V});return O.push(...f),O}var Wf=()=>{let V=new ef,$=new Map;return V.get("/",async(f)=>{try{let O=await h.listSessions(),M=new Set(O.filter((G)=>G.relationType==="subagent").map((G)=>G.sessionId)),Q=Array.from(B.values()).filter((G)=>!M.has(G.id)&&G.relationType!=="subagent").map((G)=>({sessionId:G.id,projectPath:G.projectPath,title:G.title,parentId:void 0,relationType:void 0,status:void 0,agentType:void 0,model:void 0,messageCount:G.messages.length,firstMessageTime:G.createdAt.toISOString(),lastMessageTime:new Date().toISOString(),hasErrors:!1,isActive:!0})),J=new Set(Q.map((G)=>G.sessionId)),Z=O.filter((G)=>!B.has(G.sessionId)&&!J.has(G.sessionId)&&G.relationType!=="subagent"),j=new Set(J),Y=Z.filter((G)=>{if(j.has(G.sessionId))return!1;return j.add(G.sessionId),!0}),K=[...Q,...Y];return f.json(K)}catch(O){return E.error("[SessionRoutes] Failed to list sessions:",O),f.json([])}}),V.post("/",async(f)=>{try{let O=await f.req.json(),M=V0.safeParse(O);if(!M.success)throw new A("Invalid request body");let{title:Q,projectPath:J}=M.data,Z=d(12),j=J||f.get("directory")||X(),Y={id:Z,projectPath:j,title:Q||`Session ${Z.slice(0,6)}`,createdAt:new Date,messages:[]};return B.set(Z,Y),f.json({sessionId:Z,projectPath:j,title:Y.title,parentId:void 0,relationType:void 0,status:void 0,agentType:void 0,model:void 0,messageCount:0,firstMessageTime:Y.createdAt.toISOString(),lastMessageTime:Y.createdAt.toISOString(),hasErrors:!1})}catch(O){throw E.error("[SessionRoutes] Failed to create session:",O),O}}),V.get("/:sessionId",async(f)=>{let O=f.req.param("sessionId"),M=B.get(O);if(M)return f.json({sessionId:M.id,projectPath:M.projectPath,title:M.title,messageCount:M.messages.length,firstMessageTime:M.createdAt.toISOString(),lastMessageTime:new Date().toISOString(),hasErrors:!1,isActive:!0});try{let J=(await h.listSessions()).find((Z)=>Z.sessionId===O);if(!J)throw new P("Session",O);return f.json(J)}catch(Q){if(Q instanceof P)throw Q;throw E.error("[SessionRoutes] Failed to get session:",Q),Q}}),V.patch("/:sessionId",async(f)=>{let O=f.req.param("sessionId");try{let M=await f.req.json(),Q=M0.safeParse(M);if(!Q.success)throw new A("Invalid request body");let{title:J}=Q.data,Z=B.get(O);if(Z&&J)Z.title=J;return f.json({success:!0,title:J})}catch(M){throw E.error("[SessionRoutes] Failed to update session:",M),M}}),V.delete("/:sessionId",async(f)=>{let O=f.req.param("sessionId"),M=B.get(O);if(M?.currentRunId){let J=D.get(M.currentRunId);if(J)J.abortController.abort(),g.publish(O,"run.cancelled",{runId:J.id}),D.delete(M.currentRunId)}try{await h.deleteSession(O)}catch(J){E.warn("[SessionRoutes] Failed to delete session file:",J)}B.delete(O);let Q=$.get(O);if(Q){if(await Q.dispose(),$.delete(O),$.size===0)await T.getInstance().disconnectAll()}return f.json({success:!0})}),V.get("/:sessionId/message",async(f)=>{let O=f.req.param("sessionId");try{let M=await h.loadSession(O);return f.json(M)}catch(M){return E.error("[SessionRoutes] Failed to get messages:",M),f.json([])}}),V.get("/:sessionId/events",async(f)=>{let O=f.req.param("sessionId"),M=B.get(O);if(!M){let Q=f.get("directory")||X();M={id:O,projectPath:Q,title:`Session ${O.slice(0,6)}`,createdAt:new Date,messages:[]},B.set(O,M)}return f0(f,async(Q)=>{await Q.writeSSE({data:JSON.stringify({type:"connected",properties:{sessionId:O,timestamp:Date.now()}})});let Z=g.subscribe((Y)=>{if(Y.sessionId!==O)return;Q.writeSSE({data:JSON.stringify({type:Y.type,properties:{sessionId:Y.sessionId,...Y.properties}})}).catch(()=>{})}),j=setInterval(()=>{if(!Q.aborted)Q.writeSSE({data:JSON.stringify({type:"heartbeat",properties:{timestamp:Date.now()}})}).catch(()=>{})},15000);Q.onAbort(()=>{clearInterval(j),Z()});while(!0)if(await new Promise((Y)=>setTimeout(Y,1000)),Q.aborted)break})}),V.post("/:sessionId/message",async(f)=>{let O=f.req.param("sessionId"),M=await f.req.json(),Q=O0.safeParse(M);if(!Q.success)throw new A("Invalid message format");let{content:J,attachments:Z,permissionMode:j}=Q.data,Y=j||"default",K=f.get("directory")||X(),G=Y0(J,Z),x=B.get(O);if(!x){let N=await h.loadSession(O).catch(()=>[]);x={id:O,projectPath:K,title:`Session ${O.slice(0,6)}`,createdAt:new Date,messages:N},B.set(O,x)}let q=d(12),L=new AbortController,m={id:q,sessionId:O,status:"running",abortController:L,createdAt:new Date};return D.set(q,m),x.currentRunId=q,Z0(m,x,G,Y,$).catch((N)=>{E.error(`[SessionRoutes] Run ${q} failed:`,N)}),f.json({runId:q,status:"running"},202)}),V.post("/:sessionId/abort",async(f)=>{let O=f.req.param("sessionId"),M=B.get(O);if(M?.currentRunId){let Q=D.get(M.currentRunId);if(Q)Q.abortController.abort(),Q.status="cancelled",g.publish(O,"run.cancelled",{runId:Q.id})}return f.json({success:!0})}),V.get("/:sessionId/status",async(f)=>{let O=f.req.param("sessionId"),M=B.get(O);if(!M?.currentRunId)return f.json({sessionId:O,status:"idle"});let Q=D.get(M.currentRunId);return f.json({sessionId:O,runId:M.currentRunId,status:Q?.status||"idle"})}),V};async function Z0(V,$,f,O,M){let{abortController:Q,sessionId:J,id:Z}=V,j=d(12),Y=d(12),K=(G,x)=>{g.publish(J,G,x)};try{K("message.created",{messageId:j,role:"user",content:Q0(f)}),K("session.status",{status:"running"}),K("message.created",{messageId:Y,role:"assistant",content:""});let G=M.get(J);if(!G)G=await Ff.create({sessionId:J}),M.set(J,G);let x=await Bf.createWithRuntime(G,{sessionId:J}),q=async(N)=>{let F=d(12),l=300000;V.status="waiting_permission";let ff=new Promise((jf)=>{let rf=setTimeout(()=>{E.warn(`[SessionRoutes] Permission ${F} timed out after 300000ms`),K("permission.timeout",{requestId:F}),jf({approved:!1,reason:"timeout"})},300000);V.pendingPermission={permissionId:F,resolve:(lf)=>{clearTimeout(rf),jf(lf)},details:N}});K("permission.asked",{requestId:F,toolName:N.toolName,description:N.message,args:N.args,details:N}),E.info(`[SessionRoutes] Permission request created: ${F}, runId: ${Z}`);let Kf=await ff;return E.info(`[SessionRoutes] Permission response received: ${F}, approved: ${Kf.approved}`),V.status="running",V.pendingPermission=void 0,Kf},L={messages:[...$.messages],userId:"web-user",sessionId:J,workspaceRoot:$.projectPath,signal:Q.signal,permissionMode:O,confirmationHandler:{requestConfirmation:q}},m=await mf(x.chatStream(f,L,{stream:!0}),async(N)=>{switch(N.kind){case"content_delta":K("message.delta",{messageId:Y,delta:N.delta});break;case"thinking_delta":K("thinking.delta",{delta:N.delta});break;case"tool_start":if("function"in N.toolCall)K("tool.start",{messageId:Y,toolName:N.toolCall.function.name,toolCallId:N.toolCall.id,arguments:N.toolCall.function.arguments,toolKind:N.toolKind});break;case"tool_result":if("function"in N.toolCall)K("tool.result",{messageId:Y,toolName:N.toolCall.function.name,toolCallId:N.toolCall.id,success:N.result.success,summary:N.result.metadata?.summary,output:qf(Uf(N.toolCall.function.name,N.result)),metadata:J0(N.result.metadata)});break;case"token_usage":K("token.usage",{...N.usage});break;case"turn_start":K("turn.started",{turn:N.turn,maxTurns:N.maxTurns});break;case"compaction":K(N.phase==="start"?"compaction.started":"compaction.completed",{});break;case"model_fallback":K("model.fallback",{});break;case"task_update":K("task.updated",{tasks:N.tasks});break;default:break}});$.messages=[...L.messages],K("message.complete",{messageId:Y}),K("thinking.completed",{}),V.status="completed",K("session.completed",{runId:Z,outputTruncated:m.metadata?.outputTruncated??!1}),K("session.status",{status:"idle"})}catch(G){E.error("[SessionRoutes] Agent execution error:",G),V.status="failed",K("session.error",{error:G instanceof Error?G.message:"Unknown error"}),K("session.status",{status:"error"})}}function Af(V,$,f){E.info(`[SessionRoutes] Looking for permission ${$} in session ${V}`),E.info(`[SessionRoutes] Active runs: ${D.size}`);for(let[O,M]of D.entries())if(E.info(`[SessionRoutes] Checking run ${O}: sessionId=${M.sessionId}, pendingPermission=${M.pendingPermission?.permissionId}`),M.sessionId===V&&M.pendingPermission?.permissionId===$)return M.pendingPermission.resolve(f),E.info(`[SessionRoutes] Permission ${$} responded, runId: ${M.id}`),!0;return E.error(`[SessionRoutes] Permission not found: ${$}`),!1}var Vf=R("Service"),j0=C.object({approved:C.boolean(),remember:C.boolean().optional(),scope:C.enum(["once","session"]).optional(),targetMode:C.enum(["default","autoEdit","plan","spec","yolo"]).optional(),feedback:C.string().optional(),answers:C.record(C.union([C.string(),C.array(C.string())])).optional()}),Cf=()=>{let V=new K0;return V.post("/:permissionId",async($)=>{let f=$.req.param("permissionId"),O=$.req.query("sessionId");Vf.info(`[PermissionRoutes] Received permission response: permissionId=${f}, sessionId=${O}`);try{let M=await $.req.json(),Q=j0.safeParse(M);if(!Q.success)throw new A("Invalid permission response format");let{approved:J,remember:Z,scope:j,targetMode:Y,feedback:K,answers:G}=Q.data;if(!O)throw new A("sessionId query parameter is required");if(!Af(O,f,{approved:J,reason:K,scope:j,targetMode:Y,feedback:K,answers:G}))throw new P("Permission request",f);return Vf.info(`[PermissionRoutes] Permission ${f} ${J?"approved":"denied"}`),$.json({success:!0,approved:J,remember:Z})}catch(M){throw Vf.error("[PermissionRoutes] Failed to respond to permission:",M),M}}),V};import{Hono as G0}from"hono";var Hf=R("Service"),yf=()=>{let V=new G0;return V.get("/",async($)=>{try{let f=await zf();return $.json(f)}catch(f){return Hf.error("[ProviderRoutes] Failed to list providers:",f),$.json([])}}),V.get("/:provider/models",async($)=>{let f=$.req.param("provider");try{let O=await Tf(f);return $.json(O)}catch(O){return Hf.error("[ProviderRoutes] Failed to list models:",O),$.json([])}}),V};import{Hono as N0}from"hono";import*as y from"node:fs/promises";import{homedir as x0}from"node:os";import*as n from"node:path";var b=R("Service"),Of=n.join(x0(),".blade","skills-config.json");async function Df(){try{let V=await y.readFile(Of,"utf-8");return JSON.parse(V)}catch{return{disabled:[]}}}async function R0(V){await y.mkdir(n.dirname(Of),{recursive:!0}),await y.writeFile(Of,JSON.stringify(V,null,2))}async function X0(V,$){let f=await Df();if($)f.disabled=f.disabled.filter((O)=>O!==V);else if(!f.disabled.includes(V))f.disabled.push(V);await R0(f)}var I=null,E0=300000;async function m0(){if(I&&Date.now()-I.timestamp<E0)return I.data;try{let V=await fetch("https://api.github.com/repos/anthropics/skills/contents/skills",{headers:{Accept:"application/vnd.github.v3+json","User-Agent":"Blade-Skills-Catalog"}});if(!V.ok)return b.warn(`GitHub API returned ${V.status}`),I?.data||[];let $=await V.json(),f=[];for(let O of $){if(O.type!=="dir")continue;let M=`Official ${O.name} skill`;try{let Q=await fetch(`https://raw.githubusercontent.com/anthropics/skills/main/skills/${O.name}/SKILL.md`,{headers:{"User-Agent":"Blade-Skills-Catalog"}});if(Q.ok){let Z=(await Q.text()).match(/^#[^\n]*\n+([^\n#]+)/);if(Z)M=Z[1].trim().slice(0,100)}}catch{}f.push({name:O.name,description:M,tag:"Official",author:"Anthropic"})}return I={data:f,timestamp:Date.now()},f}catch(V){return b.warn("Failed to fetch skills catalog from GitHub:",V),I?.data||[]}}var bf=()=>{let V=new N0;return V.get("/",async($)=>{try{let f=t();await f.initialize();let O=f.getAll(),M=await Df(),Q=O.map((J)=>({id:J.name,name:J.name,enabled:!M.disabled.includes(J.name),description:J.description||"",version:J.version||"1.0.0",provider:"Local",location:J.source==="builtin"?"Built-in":J.basePath,capabilities:["prompts"],allowedTools:J.allowedTools||[]}));return $.json(Q)}catch(f){return b.error("[SkillsRoutes] Failed to get skills:",f),$.json([])}}),V.post("/:name/toggle",async($)=>{try{let f=$.req.param("name"),O=await $.req.json();return await X0(f,O.enabled),$.json({success:!0,enabled:O.enabled})}catch(f){return b.error("[SkillsRoutes] Failed to toggle skill:",f),$.json({success:!1,error:f.message},500)}}),V.delete("/:name",async($)=>{try{let f=$.req.param("name"),O=`${process.env.HOME}/.blade/skills/${f}`;return await y.rm(O,{recursive:!0,force:!0}),await t().refresh(),$.json({success:!0})}catch(f){return b.error("[SkillsRoutes] Failed to uninstall skill:",f),$.json({success:!1,error:f.message},500)}}),V.post("/install",async($)=>{try{let f=await $.req.json(),O=_f(),M=t(),Q=!1;if(f.source==="catalog"&&f.name){if(Q=await O.installOfficialSkill(f.name),!Q)return $.json({success:!1,error:"Failed to install skill from catalog"},500)}else if(f.source==="repo"&&f.url){if(Q=await O.installFromRepo(f.url,f.name),!Q)return $.json({success:!1,error:"Failed to install skill from repository. Make sure the repo contains a SKILL.md file."},500)}else if(f.source==="local"&&f.path){if(Q=await O.installFromLocal(f.path,f.name),!Q)return $.json({success:!1,error:"Failed to install skill from local path. Make sure the path exists and contains a SKILL.md file."},500)}else return $.json({success:!1,error:"Invalid install parameters. Required: source with corresponding url/path/name"},400);return await M.refresh(),$.json({success:!0})}catch(f){return b.error("[SkillsRoutes] Failed to install skill:",f),$.json({success:!1,error:f.message},500)}}),V.get("/catalog",async($)=>{try{let f=await m0();return $.json(f)}catch(f){return b.error("[SkillsRoutes] Failed to get catalog:",f),$.json([])}}),V};import F0 from"fast-glob";import{Hono as U0}from"hono";import{execSync as q0}from"node:child_process";import{readdir as B0}from"node:fs/promises";import i from"node:path";var r=R("Service"),W0=(V)=>{try{return q0("git rev-parse --abbrev-ref HEAD",{cwd:V,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||null}catch{return null}},A0=[...s.map((V)=>`${V}/**`),...s,...Mf.map((V)=>`**/${V}`)],C0=new Set(["/theme","/model","/permissions","/mcp","/skills","/exit","/resume","/ide","/login","/logout"]),Pf=()=>{let V=new U0;return V.get("/commands",async($)=>{try{let f=$.req.query("q")||"",O=Lf(f).filter((M)=>!C0.has(M.command));return $.json(O)}catch(f){return r.error("[SuggestionsRoutes] Failed to get command suggestions:",f),$.json([])}}),V.get("/files",async($)=>{try{let f=$.req.query("q")||"",O=$.get("directory")||X(),M=Math.min(Number($.req.query("limit"))||100,1000),J=(await F0("**/*",{cwd:O,dot:!1,followSymbolicLinks:!1,onlyFiles:!1,markDirectories:!0,unique:!0,ignore:A0})).map((Y)=>Y.replace(/\\/g,"/"));if(!f)return $.json(J.slice(0,M));let Z=f.toLowerCase(),j=J.filter((Y)=>Y.toLowerCase().includes(Z)).slice(0,M);return $.json(j)}catch(f){return r.error("[SuggestionsRoutes] Failed to get file suggestions:",f),$.json([])}}),V.get("/files/tree",async($)=>{try{let f=$.get("directory")||X(),O=$.req.query("path")||"",M=O?i.join(f,O):f,J=(await B0(M,{withFileTypes:!0})).map((Y)=>({name:Y.name,path:O?`${O}/${Y.name}`:Y.name,type:Y.isDirectory()?"dir":"file"}));J.sort((Y,K)=>{if(Y.type!==K.type)return Y.type==="dir"?-1:1;return Y.name.localeCompare(K.name)});let Z=new Set(s),j=J.filter((Y)=>{let K=Y.name;if(K.startsWith("."))return!1;if(Z.has(K))return!1;for(let G of Mf)if(K.match(new RegExp(G.replace("*",".*"))))return!1;return!0});return $.json(j)}catch(f){return r.error("[SuggestionsRoutes] Failed to get file tree:",f),$.json([])}}),V.get("/files/content",async($)=>{try{let f=$.req.query("path");if(!f)return $.json({error:"Missing file path"},400);let O=$.get("directory")||X(),M=i.resolve(O,f),Q=i.relative(O,M);if(Q.startsWith("..")||i.isAbsolute(Q))return $.json({error:"Invalid file path"},400);let J=wf(),Z=await J.stat(M);if(!Z?.isFile)return $.json({error:"File not found"},404);let j=200000,Y=await J.readTextFile(M),K=Y.length>j;return $.json({path:f,content:K?Y.slice(0,j):Y,truncated:K,size:Z.size})}catch(f){return r.error("[SuggestionsRoutes] Failed to get file content:",f),$.json({error:"Failed to read file"},500)}}),V.get("/git-info",async($)=>{try{let f=$.get("directory")||X(),O=W0(f);return $.json({branch:O})}catch(f){return r.error("[SuggestionsRoutes] Failed to get git info:",f),$.json({branch:null})}}),V};import{Hono as H0}from"hono";var _=R("Service"),v=new Map,kf=2097152,Sf=65536;function uf(){return typeof globalThis.Bun<"u"}async function z0(V,$,f){if(uf()){let{spawn:Q}=await import("bun-pty"),J=Q(V,$,{name:"xterm-256color",cwd:f.cwd,env:f.env});return{pid:J.pid,write:(Z)=>J.write(Z),resize:(Z,j)=>J.resize(Z,j),kill:()=>J.kill(),onData:(Z)=>J.onData(Z),onExit:(Z)=>J.onExit(Z)}}let M=(await import("node-pty")).spawn(V,$,{name:"xterm-256color",cwd:f.cwd,env:f.env,cols:80,rows:24});return{pid:M.pid,write:(Q)=>M.write(Q),resize:(Q,J)=>M.resize(Q,J),kill:()=>M.kill(),onData:(Q)=>{M.onData(Q)},onExit:(Q)=>{M.onExit(Q)}}}var Yf=void 0,Qf;if(uf())try{let{createBunWebSocket:V}=await import("hono/bun"),$=V();Qf=$.upgradeWebSocket,Yf=$.websocket}catch(V){_.warn("[Terminal] Failed to initialize Bun WebSocket support:",V)}async function hf(V,$){let f=`term-${Date.now()}`;_.info(`[Terminal] New connection: ${f}, cwd: ${V}`);let O=process.platform==="win32"?"powershell.exe":process.env.SHELL||"/bin/zsh",M=O.endsWith("sh")?["-l"]:[],Q=await z0(O,M,{cwd:V,env:{...process.env,TERM:"xterm-256color",COLORTERM:"truecolor"}}),J={id:f,process:Q,cwd:V,buffer:"",subscribers:new Set};if(v.set(f,J),J.subscribers.add($),Q.onData((Z)=>{let j=!1;for(let Y of J.subscribers)try{Y.send(Z),j=!0}catch{J.subscribers.delete(Y)}if(j)return;if(J.buffer+=Z,J.buffer.length>kf)J.buffer=J.buffer.slice(-kf)}),Q.onExit(({exitCode:Z})=>{_.info(`[Terminal] Process exited: ${f}, code: ${Z}`);for(let j of J.subscribers)try{j.close()}catch{}v.delete(f)}),J.buffer){let Z=J.buffer;J.buffer="";for(let j=0;j<Z.length;j+=Sf)$.send(Z.slice(j,j+Sf))}return{session:J,cleanup:()=>{if(_.info(`[Terminal] Connection closed: ${f}`),J.subscribers.delete($),J.subscribers.size===0){try{J.process.kill()}catch{}v.delete(f)}}}}function If(V,$){V.on("connection",async(f,O)=>{let M=new URL(O.url||"/",`http://${O.headers.host}`);if(!M.pathname.endsWith("/terminal/ws")){f.close();return}let Q=M.searchParams.get("cwd")||$()||X();try{let{session:J,cleanup:Z}=await hf(Q,{send:(j)=>f.send(j),close:()=>f.close()});f.on("message",(j)=>{try{J.process.write(String(j))}catch(Y){_.error("[Terminal] Failed to write to PTY:",Y)}}),f.on("close",Z),f.on("error",Z)}catch(J){_.error("[Terminal] Failed to spawn PTY:",J),f.close()}})}var vf=()=>{let V=new H0;if(V.get("/status",($)=>{let f=Array.from(v.values()).map((O)=>({id:O.id,cwd:O.cwd}));return $.json({active:f.length,terminals:f})}),V.post("/kill/:terminalId",($)=>{let f=$.req.param("terminalId"),O=v.get(f);if(O){try{O.process.kill()}catch{}for(let M of O.subscribers)M.close();return v.delete(f),$.json({success:!0})}return $.json({success:!1,error:"Terminal not found"},404)}),Qf)V.get("/ws",Qf(($)=>{let f=$.req.query("cwd")||$.get("directory")||X(),O;return{async onOpen(M,Q){try{O=await hf(f,{send:(J)=>Q.send(J),close:()=>Q.close()})}catch(J){_.error("[Terminal] Failed to spawn PTY:",J),Q.close()}},onMessage(M){if(!O)return;try{O.session.process.write(String(M.data))}catch(Q){_.error("[Terminal] Failed to write to PTY:",Q)}},onClose(){O?.cleanup()}}}));else V.get("/ws",($)=>{return $.json({message:"WebSocket endpoint - connect via ws:// protocol",hint:"Use WebSocket client to connect to this endpoint"})});return V};var W=R("Service"),Zf=[];function k0(){let V=b0(L0(import.meta.url)),$=[w(V,"web"),w(X(),"dist/web"),w(X(),"packages/cli/dist/web")];for(let f of $){let O=w(f,"index.html");if(gf(O)){if(e(O,"utf-8").includes("/assets/"))return W.debug(`[Server] Found web dist at: ${f}`),f}}return null}function S0(){let V=new T0;V.onError((f,O)=>{if(W.error("[Server] Request error:",f),f instanceof p)return O.json(f.toObject(),f.statusCode);let M=f instanceof Error?f.message:String(f);return O.json({error:{code:"INTERNAL_ERROR",message:M}},500)}),V.use(async(f,O)=>{let M=process.env.BLADE_SERVER_PASSWORD;if(!M)return O();let Q=f.req.path;if(Q==="/"||Q.startsWith("/assets/")||Q.endsWith(".html")||Q.endsWith(".js")||Q.endsWith(".css"))return O();let J=f.req.header("Authorization");if(!J?.startsWith("Basic "))return f.header("WWW-Authenticate",'Basic realm="Blade Server"'),f.json({error:{code:"UNAUTHORIZED",message:"Authentication required"}},401);let Z=Buffer.from(J.slice(6),"base64").toString(),[j,Y]=Z.split(":"),K=process.env.BLADE_SERVER_USERNAME??"blade";if(j!==K||Y!==M)return f.json({error:{code:"UNAUTHORIZED",message:"Invalid credentials"}},401);return O()}),V.use(async(f,O)=>{let M=f.req.path==="/health"||f.req.path==="/global/health"||f.req.path.startsWith("/assets/");if(!M)W.debug(`[Server] ${f.req.method} ${f.req.path}`);let Q=Date.now();if(await O(),!M){let J=Date.now()-Q;W.debug(`[Server] ${f.req.method} ${f.req.path} - ${f.res.status} (${J}ms)`)}}),V.use(y0({origin(f){if(!f)return;if(f.startsWith("http://localhost:"))return f;if(f.startsWith("http://127.0.0.1:"))return f;if(f==="tauri://localhost"||f==="http://tauri.localhost")return f;if(Zf.includes(f))return f;return}})),V.use(async(f,O)=>{let M=f.req.query("directory")||f.req.header("x-blade-directory")||X();try{M=decodeURIComponent(M)}catch{}return f.set("directory",M),O()}),V.route("/global",Nf()),V.route("/sessions",Wf()),V.route("/configs",Gf()),V.route("/permissions",Cf()),V.route("/providers",yf()),V.route("/models",Ef()),V.route("/suggestions",Pf()),V.route("/terminal",vf()),V.route("/mcp",xf()),V.route("/skills",bf()),V.get("/health",(f)=>{return f.json({healthy:!0,version:u()})});let $=k0();if($)W.info(`[Server] Serving static files from ${$}`),V.get("/assets/*",(f)=>{let O=w($,f.req.path);if(!gf(O))return f.json({error:{code:"NOT_FOUND",message:`File not found: ${f.req.path}`}},404);let M=e(O),Q=w0(O).toLowerCase(),Z={".js":"application/javascript",".css":"text/css",".html":"text/html",".json":"application/json",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".ico":"image/x-icon",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".eot":"application/vnd.ms-fontobject"}[Q]||"application/octet-stream";return new Response(M,{headers:{"Content-Type":Z,"Cache-Control":"public, max-age=31536000, immutable"}})}),V.get("/",(f)=>{let O=w($,"index.html"),M=e(O,"utf-8");return f.html(M)}),V.get("*",(f)=>{let O=f.req.path;if(O.includes("."))return f.json({error:{code:"NOT_FOUND",message:`File not found: ${O}`}},404);let M=w($,"index.html"),Q=e(M,"utf-8");return f.html(Q)});else W.warn('[Server] Web UI not found. Run "cd packages/cli/web && bun run build" to enable web interface.'),V.get("/",(f)=>{return f.json({message:"Blade API Server",version:u(),webUI:!1,hint:'Web UI not built. Run "cd packages/cli/web && bun run build" to enable.',endpoints:{health:"/health",sessions:"/sessions",configs:"/configs",permissions:"/permissions",providers:"/providers"}})}),V.all("*",(f)=>{return f.json({error:{code:"NOT_FOUND",message:`Route not found: ${f.req.path}`}},404)});return V}function u0(){let V=D0(),$=[];for(let f of Object.keys(V)){let O=V[f];if(!O)continue;for(let M of O){if(M.internal||M.family!=="IPv4")continue;if(M.address.startsWith("172."))continue;$.push(M.address)}}return $}function pf(){return typeof globalThis.Bun<"u"}function of(V,$){let f=globalThis.Bun,O=(Q)=>{try{return f.serve({hostname:$.hostname,port:Q,fetch:V.fetch,idleTimeout:0,websocket:Yf})}catch(J){W.error("Failed to start Bun server:",J);return}},M=$.port===0?O(4096)??O(0):O($.port);if(!M)throw Error(`Failed to start Bun server on port ${$.port}`);return{url:M.url,port:M.port,hostname:M.hostname,stop:async()=>{M.stop(!0)}}}function h0(V,$){return new Promise((f,O)=>{let M=_0(async(Y,K)=>{let G=new URL(Y.url||"/",`http://${Y.headers.host}`),x=new Headers;for(let[m,N]of Object.entries(Y.headers))if(N)if(Array.isArray(N))for(let F of N)x.append(m,F);else x.set(m,N);let q;if(Y.method!=="GET"&&Y.method!=="HEAD")q=(await new Promise((N)=>{let F=[];Y.on("data",(l)=>F.push(l)),Y.on("end",()=>N(Buffer.concat(F)))})).toString();let L=new Request(G.toString(),{method:Y.method,headers:x,body:q});try{let m=await V.fetch(L);if(K.statusCode=m.status,m.headers.forEach((N,F)=>{K.setHeader(F,N)}),m.body){let N=m.body.getReader(),F=async()=>{let{done:l,value:ff}=await N.read();if(l){K.end();return}return K.write(ff),F()};await F()}else{let N=await m.text();K.end(N)}}catch(m){W.error("[Server] Node request error:",m),K.statusCode=500,K.end(JSON.stringify({error:{code:"INTERNAL_ERROR",message:"Internal server error"}}))}}),Q=new P0({noServer:!0}),J=X();If(Q,()=>J),M.on("upgrade",(Y,K,G)=>{if(new URL(Y.url||"/",`http://${Y.headers.host}`).pathname==="/terminal/ws")Q.handleUpgrade(Y,K,G,(q)=>{Q.emit("connection",q,Y)});else K.destroy()});let Z=(Y)=>{return new Promise((K,G)=>{M.once("error",(x)=>{if(x.code==="EADDRINUSE")G(x);else G(x)}),M.listen(Y,$.hostname,()=>{let x=M.address();if(x&&typeof x==="object")K(x.port);else K(Y)})})};(async()=>{let Y;if($.port===0)try{Y=await Z(4096)}catch{Y=await Z(0)}else Y=await Z($.port);let K=new URL(`http://${$.hostname==="0.0.0.0"?"localhost":$.hostname}:${Y}`);f({url:K,port:Y,hostname:$.hostname,stop:async()=>{return new Promise((G)=>{Q.close(()=>{M.close(()=>G())})})}})})().catch(O)})}var df;((DV)=>{let V,$;function f(){if(!$)$=S0();return $}DV.getApp=f;function O(J){Zf=J.cors??[];let Z=f();if(pf())V=of(Z,J),W.info(`[Server] Blade server listening on ${V.url} (Bun runtime)`);else throw Error("Blade web server requires Bun runtime. Please run with Bun: `bun run blade web` or install Bun from https://bun.sh");let j=V;return{url:j.url,port:j.port,hostname:j.hostname,stop:async()=>{if(V)await V.stop(),V=void 0,$=void 0,W.info("[Server] Blade server stopped")}}}DV.listen=O;async function M(J){Zf=J.cors??[];let Z=f();if(pf())V=of(Z,J),W.info(`[Server] Blade server listening on ${V.url} (Bun runtime)`);else V=await h0(Z,J),W.info(`[Server] Blade server listening on ${V.url} (Node.js runtime)`);let j=V;return{url:j.url,port:j.port,hostname:j.hostname,stop:async()=>{if(V)await V.stop(),V=void 0,$=void 0,W.info("[Server] Blade server stopped")}}}DV.listenAsync=M;function Q(){return V!==void 0}DV.isRunning=Q})(df||={});export{I0 as f,v0 as g,u0 as h,df as i};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{Eb as n}from"./chunk-wre40mf1.js";import{Ob as r}from"./chunk-mt1c5da4.js";import{Qb as b}from"./chunk-0afbeec0.js";import{nanoid as A}from"nanoid";var N;((R)=>{R.PreToolUse="PreToolUse";R.PostToolUse="PostToolUse";R.PostToolUseFailure="PostToolUseFailure";R.PermissionRequest="PermissionRequest";R.UserPromptSubmit="UserPromptSubmit";R.SessionStart="SessionStart";R.SessionEnd="SessionEnd";R.Stop="Stop";R.SubagentStop="SubagentStop";R.Notification="Notification";R.Compaction="Compaction"})(N||={});var C;((W)=>{W.Approve="approve";W.Block="block";W.Async="async"})(C||={});var S;((W)=>{W.Allow="allow";W.Deny="deny";W.Ask="ask"})(S||={});var I={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:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]};function f(Q,Y){return{...Q,...Y,PreToolUse:Y.PreToolUse??Q.PreToolUse,PostToolUse:Y.PostToolUse??Q.PostToolUse,PostToolUseFailure:Y.PostToolUseFailure??Q.PostToolUseFailure,PermissionRequest:Y.PermissionRequest??Q.PermissionRequest,UserPromptSubmit:Y.UserPromptSubmit??Q.UserPromptSubmit,SessionStart:Y.SessionStart??Q.SessionStart,SessionEnd:Y.SessionEnd??Q.SessionEnd,Stop:Y.Stop??Q.Stop,SubagentStop:Y.SubagentStop??Q.SubagentStop,Notification:Y.Notification??Q.Notification,Compaction:Y.Compaction??Q.Compaction}}function x(){let Q={};if(process.env.BLADE_DISABLE_HOOKS==="true")Q.enabled=!1;if(process.env.BLADE_HOOK_TIMEOUT){let Y=parseInt(process.env.BLADE_HOOK_TIMEOUT,10);if(!isNaN(Y)&&Y>0)Q.defaultTimeout=Y}return Q}class z{executedHooks=new Map;canExecute(Q,Y){if(!this.executedHooks.has(Q))this.executedHooks.set(Q,new Set);if(this.executedHooks.get(Q).has(Y))return console.warn(`[HookGuard] Hook ${Y} for tool ${Q} already executed, skipping`),!1;return!0}markExecuted(Q,Y){let Z=this.executedHooks.get(Q);if(Z)Z.add(Y)}cleanup(Q){this.executedHooks.delete(Q)}cleanupAll(){this.executedHooks.clear()}}import{z as q}from"zod";var j=q.object({hook_event_name:q.nativeEnum(N),hook_execution_id:q.string(),timestamp:q.string(),project_dir:q.string(),session_id:q.string(),permission_mode:q.enum(["default","autoEdit","yolo","plan"]),_metadata:q.object({blade_version:q.string(),hook_timeout_ms:q.number()}).optional()}),o=j.extend({hook_event_name:q.literal("PreToolUse"),tool_name:q.string(),tool_use_id:q.string(),tool_input:q.record(q.unknown())}),e=j.extend({hook_event_name:q.literal("PostToolUse"),tool_name:q.string(),tool_use_id:q.string(),tool_input:q.record(q.unknown()),tool_response:q.unknown()}),t=j.extend({hook_event_name:q.literal("Stop"),reason:q.string().optional()}),QQ=j.extend({hook_event_name:q.literal("PostToolUseFailure"),tool_name:q.string(),tool_use_id:q.string(),tool_input:q.record(q.unknown()),error:q.string(),error_type:q.string().optional(),is_interrupt:q.boolean(),is_timeout:q.boolean()}),YQ=j.extend({hook_event_name:q.literal("PermissionRequest"),tool_name:q.string(),tool_use_id:q.string(),tool_input:q.record(q.unknown())}),ZQ=j.extend({hook_event_name:q.literal("UserPromptSubmit"),user_prompt:q.string(),has_images:q.boolean(),image_count:q.number()}),WQ=j.extend({hook_event_name:q.literal("SessionStart"),is_resume:q.boolean(),resume_session_id:q.string().optional()}),$Q=j.extend({hook_event_name:q.literal("SessionEnd"),reason:q.enum(["user_exit","error","max_turns","idle_timeout","ctrl_c","clear","logout","other"])}),qQ=j.extend({hook_event_name:q.literal("SubagentStop"),agent_type:q.string(),task_description:q.string().optional(),success:q.boolean(),result_summary:q.string().optional(),error:q.string().optional()}),XQ=j.extend({hook_event_name:q.literal("Notification"),notification_type:q.enum(["permission_prompt","idle_prompt","auth_success","elicitation_dialog","info","warning","error"]),title:q.string().optional(),message:q.string()}),JQ=j.extend({hook_event_name:q.literal("Compaction"),trigger:q.enum(["manual","auto"]),messages_before:q.number(),tokens_before:q.number()}),dQ=q.discriminatedUnion("hook_event_name",[o,e,t,QQ,YQ,ZQ,WQ,$Q,qQ,XQ,JQ]),GQ=q.object({hookEventName:q.literal("PreToolUse"),permissionDecision:q.nativeEnum(S).optional(),permissionDecisionReason:q.string().optional(),updatedInput:q.record(q.unknown()).optional()}),KQ=q.object({hookEventName:q.literal("PostToolUse"),additionalContext:q.string().optional(),updatedOutput:q.unknown().optional()}),VQ=q.object({hookEventName:q.literal("Stop"),continue:q.boolean().optional(),continueReason:q.string().optional()}),FQ=q.object({hookEventName:q.literal("SubagentStop"),continue:q.boolean().optional(),continueReason:q.string().optional(),additionalContext:q.string().optional()}),RQ=q.object({hookEventName:q.literal("PermissionRequest"),permissionDecision:q.enum(["approve","deny","ask"]).optional(),permissionDecisionReason:q.string().optional()}),DQ=q.object({hookEventName:q.literal("UserPromptSubmit"),updatedPrompt:q.string().optional(),contextInjection:q.string().optional()}),LQ=q.object({hookEventName:q.literal("SessionStart"),env:q.record(q.string()).optional()}),_Q=q.object({hookEventName:q.literal("Compaction"),blockCompaction:q.boolean().optional(),blockReason:q.string().optional()}),jQ=q.object({decision:q.object({behavior:q.nativeEnum(C)}).optional(),systemMessage:q.string().optional(),hookSpecificOutput:q.discriminatedUnion("hookEventName",[GQ,KQ,VQ,FQ,RQ,DQ,LQ,_Q]).optional(),suppressOutput:q.boolean().optional()}),AQ=q.object({type:q.literal("command"),command:q.string(),timeout:q.number().positive().optional(),statusMessage:q.string().optional()}),BQ=q.object({type:q.literal("prompt"),prompt:q.string(),model:q.string().optional(),timeout:q.number().positive().optional()}),OQ=q.discriminatedUnion("type",[AQ,BQ]),H=q.union([q.string(),q.array(q.string())]),UQ=q.object({tools:H.optional(),paths:H.optional(),commands:H.optional()}),_=q.object({name:q.string().optional(),matcher:UQ.optional(),hooks:q.array(OQ)}),mQ=q.object({enabled:q.boolean().optional(),defaultTimeout:q.number().positive().optional(),timeoutBehavior:q.enum(["ignore","deny","ask"]).optional(),failureBehavior:q.enum(["ignore","deny","ask"]).optional(),maxConcurrentHooks:q.number().positive().optional(),PreToolUse:q.array(_).optional(),PostToolUse:q.array(_).optional(),PostToolUseFailure:q.array(_).optional(),PermissionRequest:q.array(_).optional(),UserPromptSubmit:q.array(_).optional(),SessionStart:q.array(_).optional(),SessionEnd:q.array(_).optional(),Stop:q.array(_).optional(),SubagentStop:q.array(_).optional(),Notification:q.array(_).optional(),Compaction:q.array(_).optional()});function p(Q){let Y=jQ.safeParse(Q);if(Y.success)return{success:!0,data:Y.data};return{success:!1,error:Y.error}}class v{parse(Q,Y,Z){if(Q.timedOut){let $=Z?.timeoutBehavior||"ignore",X="Hook timeout";if($==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};else if($==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y}}let W=this.tryParseJSON(Q.stdout);if(W){let $=p(W);if(!$.success){let G="error"in $?$.error.message:"Unknown validation error",J=Z?.failureBehavior||"ignore",K=`Invalid hook output JSON: ${G}`;if(J==="deny")return{success:!1,blocking:!0,error:K,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};else if(J==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${K}. Continue?`,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};else return{success:!1,blocking:!1,warning:K,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y}}let X=$.data;if(X.decision?.behavior==="block")return{success:!1,blocking:!0,error:X.systemMessage||"Hook blocked execution",output:X,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};if(X.decision?.behavior==="async")return{success:!0,output:X,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};return{success:!0,output:X,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y}}return this.parseByExitCode(Q,Y,Z)}parseByExitCode(Q,Y,Z){let W=Q.exitCode;switch(W){case 0:return{success:!0,stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};case 2:return{success:!1,blocking:!0,error:Q.stderr||Q.stdout||"Hook returned exit code 2",stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};case 124:{let $=Z?.timeoutBehavior||"ignore",X="Hook timeout";if($==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};else if($==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y}}default:{let $=Z?.failureBehavior||"ignore",X=Q.stderr||Q.stdout||`Hook failed with exit code ${W}`;if($==="deny")return{success:!1,blocking:!0,error:X,stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};else if($==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${X}. Continue?`,stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};else return{success:!1,blocking:!1,warning:X,stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y}}}}tryParseJSON(Q){try{let Y=Q.trim();if(!Y)return null;let Z=Y.match(/^\s*(\{[\s\S]*\})\s*$/);if(!Z)return null;return JSON.parse(Z[1])}catch{return null}}}import{spawn as l}from"node:child_process";var PQ=500;function TQ(Q){return new Promise((Y)=>setTimeout(Y,Q))}function u(Q){return Q&&typeof Q==="object"&&"code"in Q?String(Q.code):void 0}function NQ(Q,Y){return new Promise((Z)=>{let W=["/PID",String(Q),"/T"];if(Y)W.push("/F");let $=l("taskkill",W,{stdio:"ignore",windowsHide:!0}),X=!1,G=(J)=>{if(X)return;X=!0,Z(J)};$.once("error",()=>G(!1)),$.once("close",(J)=>G(J===0))})}class a{child;state="owned";terminationPromise;terminationResult;platform;gracePeriodMs;killProcess;taskkill;wait;constructor(Q,Y={}){this.child=Q;this.platform=Y.platform??process.platform,this.gracePeriodMs=Y.gracePeriodMs??PQ,this.killProcess=Y.killProcess??process.kill.bind(process),this.taskkill=Y.taskkill??NQ,this.wait=Y.wait??TQ;let Z=()=>{if(this.state==="owned")this.state="released"};Q.once("close",Z),Q.once("error",Z)}release(){if(this.state==="owned")this.state="released"}terminate(){if(this.terminationPromise)return this.terminationPromise;if(this.terminationResult)return Promise.resolve(this.terminationResult);if(this.state==="released")return this.terminationResult={success:!0,alreadyExited:!0,forced:!1},Promise.resolve(this.terminationResult);return this.state="terminating",this.terminationPromise=this.terminateOwnedTree().then((Q)=>{return this.state="released",this.terminationResult=Q,Q}),this.terminationPromise}async terminateOwnedTree(){let Q=this.child.pid;if(!Q)return{success:!1,alreadyExited:!0,forced:!1};if(this.platform==="win32"){let W=await this.taskkill(Q,!1);await this.wait(this.gracePeriodMs);let $=await this.taskkill(Q,!0);if(!W&&!$)return{success:this.signalDirectChild("SIGKILL"),alreadyExited:!1,forced:!0};return{success:!0,alreadyExited:!1,forced:!0}}let Y=this.signalPosixTree(Q,"SIGTERM");await this.wait(this.gracePeriodMs);let Z=this.signalPosixTree(Q,"SIGKILL");return{success:Y||Z,alreadyExited:!1,forced:Z}}signalPosixTree(Q,Y){if(Q<=1||Q===process.pid)return this.signalDirectChild(Y);try{return this.killProcess(-Q,Y)}catch(Z){if(u(Z)==="ESRCH")return!0;return this.signalDirectChild(Y)}}signalDirectChild(Q){try{return this.child.kill(Q)}catch(Y){return u(Y)==="ESRCH"}}}function i(Q,Y,Z={}){let W=l(Q,Y,{...Z,detached:process.platform==="win32"?Z.detached:!0,windowsHide:Z.windowsHide??!0});return{child:W,processTree:new a(W)}}class g{content="";maxSize;constructor(Q){this.maxSize=Q}append(Q){if(this.content.length<this.maxSize){let Y=this.maxSize-this.content.length;this.content+=Q.substring(0,Y)}}getContent(){return this.content}isFull(){return this.content.length>=this.maxSize}}class d{MAX_STDOUT_SIZE=1048576;MAX_STDERR_SIZE=1048576;MAX_INPUT_SIZE=102400;async execute(Q,Y,Z,W){let $=JSON.stringify(Y);if($.length>this.MAX_INPUT_SIZE)throw Error(`Hook input too large: ${$.length} bytes (max ${this.MAX_INPUT_SIZE})`);let X=this.createSafeEnv(Y),{child:G,processTree:J}=i(Q,[],{shell:!0,env:X,cwd:Z.projectDir}),K=new g(this.MAX_STDOUT_SIZE),V=new g(this.MAX_STDERR_SIZE);G.stdout?.setEncoding("utf8"),G.stderr?.setEncoding("utf8"),G.stdout?.on("data",(D)=>{K.append(D)}),G.stderr?.on("data",(D)=>{V.append(D)});try{G.stdin?.write($),G.stdin?.end()}catch(D){throw await J.terminate(),Error(`Failed to write hook input: ${D}`)}return new Promise((D,R)=>{let L=!1,F=!1,B,O=()=>{return B??=J.terminate(),B},U=null,y=()=>{if(U&&Z.abortSignal)Z.abortSignal.removeEventListener("abort",U),U=null},M=setTimeout(()=>{L=!0,O()},W);if(G.on("close",async(w)=>{if(F)return;if(F=!0,clearTimeout(M),y(),L)await O();D({stdout:K.getContent(),stderr:V.getContent(),exitCode:L?124:w??1,timedOut:L})}),G.on("error",(w)=>{if(F)return;F=!0,clearTimeout(M),y(),R(w)}),Z.abortSignal){if(U=()=>{if(F)return;F=!0,clearTimeout(M),y(),O().then(()=>{D({stdout:K.getContent(),stderr:"Hook cancelled by abort signal",exitCode:1,timedOut:!1})})},Z.abortSignal.addEventListener("abort",U),Z.abortSignal.aborted)U()}})}createSafeEnv(Q){return{BLADE_PROJECT_DIR:Q.project_dir,BLADE_SESSION_ID:Q.session_id,BLADE_HOOK_EVENT:Q.hook_event_name,BLADE_TOOL_NAME:"tool_name"in Q?Q.tool_name:"",BLADE_TOOL_USE_ID:"tool_use_id"in Q?Q.tool_use_id:"",PATH:process.env.PATH||"",HOME:process.env.HOME||"",USER:process.env.USER||"",SHELL:process.env.SHELL||"/bin/sh"}}}class P extends Error{constructor(Q){super(Q);this.name="HttpHookSecurityError"}}function c(Q,Y={}){let Z;try{Z=new URL(Q)}catch{throw new P(`Invalid URL: ${Q}`)}if(Z.protocol!=="https:"&&Z.protocol!=="http:")throw new P(`Only http/https supported, got: ${Z.protocol}`);let W=Z.hostname.toLowerCase();if(bQ(W,Y.allowedHosts))return;if(Z.protocol==="http:"&&!Y.allowHttp)throw new P(`HTTP (non-TLS) blocked for ${W}; use https:// or add to allowedHosts`);if(yQ(W)&&!Y.allowLoopback)throw new P(`Loopback address blocked: ${W}; enable policy.allowLoopback or add to allowedHosts`);if(MQ(W)&&!Y.allowPrivateRanges)throw new P(`Private/link-local address blocked: ${W}; enable policy.allowPrivateRanges or add to allowedHosts`)}function bQ(Q,Y){if(!Y||Y.length===0)return!1;return Y.some((Z)=>{let W=Z.toLowerCase();if(W===Q)return!0;if(W.startsWith("*.")){let $=W.slice(1);return Q.endsWith($)&&Q.length>$.length}return!1})}function yQ(Q){if(Q==="localhost")return!0;if(Q==="::1"||Q==="[::1]")return!0;if(/^127\.\d+\.\d+\.\d+$/.test(Q))return!0;return!1}function MQ(Q){let Y=Q.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);if(!Y)return!1;let[Z,W]=Y.slice(1).map(Number);if(Z===10)return!0;if(Z===172&&W>=16&&W<=31)return!0;if(Z===192&&W===168)return!0;if(Z===169&&W===254)return!0;return!1}function s(Q){if(!Q)return{};let Y={};for(let[Z,W]of Object.entries(Q))Y[Z]=W.replace(/\$\{([A-Z_][A-Z0-9_]*)\}/gi,($,X)=>{return process.env[X]??`\${${X}}`});return Y}var wQ=r("Execution"),CQ={PreToolUse:'{ "permissionDecision": "approve" | "deny" | "ask", "permissionDecisionReason": "...", "updatedInput": { ... } }',PostToolUse:'{ "additionalContext": "注入到工具结果的额外信息", "updatedOutput": "修改后的工具输出" }',Stop:'{ "continue": true, "continueReason": "继续执行的原因" } // continue: true 表示阻止停止',SubagentStop:'{ "continue": true, "continueReason": "...", "additionalContext": "..." }',PermissionRequest:'{ "permissionDecision": "approve" | "deny" | "ask", "permissionDecisionReason": "..." }',UserPromptSubmit:'{ "updatedPrompt": "修改后的提示词", "contextInjection": "注入的上下文" }',Compaction:'{ "blockCompaction": true, "blockReason": "阻止压缩的原因" }'};class m{processExecutor=new d;outputParser=new v;chatServiceCache=new Map;async executePreToolHooks(Q,Y,Z){if(Q.length===0)return{decision:"allow"};let W="tool_input"in Y?Y.tool_input:{},$=[];for(let X of Q)try{let G={...Y,...W&&{tool_input:W}},J=await this.executeHook(X,G,Z);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)$.push(J.warning);continue}let K=J.output?.hookSpecificOutput;if(K&&"permissionDecision"in K){switch(K.permissionDecision){case"deny":return{decision:"deny",reason:K.permissionDecisionReason};case"ask":return{decision:"ask",reason:K.permissionDecisionReason};case"allow":break}if("updatedInput"in K&&K.updatedInput)W={...W,...K.updatedInput}}}catch(G){let J=G instanceof Error?G.message:String(G);if($.push(`Hook failed: ${J}`),Z.config.failureBehavior==="deny")return{decision:"deny",reason:J};else if(Z.config.failureBehavior==="ask")return{decision:"ask",reason:`Hook failed: ${J}. Continue?`}}return{decision:"allow",modifiedInput:W,warning:$.length>0?$.join(`
|
|
1
|
+
import{xb as n}from"./chunk-7ycmx7c2.js";import{Ob as r}from"./chunk-mt1c5da4.js";import{Qb as b}from"./chunk-0afbeec0.js";import{nanoid as A}from"nanoid";var N;((R)=>{R.PreToolUse="PreToolUse";R.PostToolUse="PostToolUse";R.PostToolUseFailure="PostToolUseFailure";R.PermissionRequest="PermissionRequest";R.UserPromptSubmit="UserPromptSubmit";R.SessionStart="SessionStart";R.SessionEnd="SessionEnd";R.Stop="Stop";R.SubagentStop="SubagentStop";R.Notification="Notification";R.Compaction="Compaction"})(N||={});var C;((W)=>{W.Approve="approve";W.Block="block";W.Async="async"})(C||={});var S;((W)=>{W.Allow="allow";W.Deny="deny";W.Ask="ask"})(S||={});var I={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:[],UserPromptSubmit:[],SessionStart:[],SessionEnd:[],Stop:[],SubagentStop:[],Notification:[],Compaction:[]};function f(Q,Y){return{...Q,...Y,PreToolUse:Y.PreToolUse??Q.PreToolUse,PostToolUse:Y.PostToolUse??Q.PostToolUse,PostToolUseFailure:Y.PostToolUseFailure??Q.PostToolUseFailure,PermissionRequest:Y.PermissionRequest??Q.PermissionRequest,UserPromptSubmit:Y.UserPromptSubmit??Q.UserPromptSubmit,SessionStart:Y.SessionStart??Q.SessionStart,SessionEnd:Y.SessionEnd??Q.SessionEnd,Stop:Y.Stop??Q.Stop,SubagentStop:Y.SubagentStop??Q.SubagentStop,Notification:Y.Notification??Q.Notification,Compaction:Y.Compaction??Q.Compaction}}function x(){let Q={};if(process.env.BLADE_DISABLE_HOOKS==="true")Q.enabled=!1;if(process.env.BLADE_HOOK_TIMEOUT){let Y=parseInt(process.env.BLADE_HOOK_TIMEOUT,10);if(!isNaN(Y)&&Y>0)Q.defaultTimeout=Y}return Q}class z{executedHooks=new Map;canExecute(Q,Y){if(!this.executedHooks.has(Q))this.executedHooks.set(Q,new Set);if(this.executedHooks.get(Q).has(Y))return console.warn(`[HookGuard] Hook ${Y} for tool ${Q} already executed, skipping`),!1;return!0}markExecuted(Q,Y){let Z=this.executedHooks.get(Q);if(Z)Z.add(Y)}cleanup(Q){this.executedHooks.delete(Q)}cleanupAll(){this.executedHooks.clear()}}import{z as q}from"zod";var j=q.object({hook_event_name:q.nativeEnum(N),hook_execution_id:q.string(),timestamp:q.string(),project_dir:q.string(),session_id:q.string(),permission_mode:q.enum(["default","autoEdit","yolo","plan"]),_metadata:q.object({blade_version:q.string(),hook_timeout_ms:q.number()}).optional()}),o=j.extend({hook_event_name:q.literal("PreToolUse"),tool_name:q.string(),tool_use_id:q.string(),tool_input:q.record(q.unknown())}),e=j.extend({hook_event_name:q.literal("PostToolUse"),tool_name:q.string(),tool_use_id:q.string(),tool_input:q.record(q.unknown()),tool_response:q.unknown()}),t=j.extend({hook_event_name:q.literal("Stop"),reason:q.string().optional()}),QQ=j.extend({hook_event_name:q.literal("PostToolUseFailure"),tool_name:q.string(),tool_use_id:q.string(),tool_input:q.record(q.unknown()),error:q.string(),error_type:q.string().optional(),is_interrupt:q.boolean(),is_timeout:q.boolean()}),YQ=j.extend({hook_event_name:q.literal("PermissionRequest"),tool_name:q.string(),tool_use_id:q.string(),tool_input:q.record(q.unknown())}),ZQ=j.extend({hook_event_name:q.literal("UserPromptSubmit"),user_prompt:q.string(),has_images:q.boolean(),image_count:q.number()}),WQ=j.extend({hook_event_name:q.literal("SessionStart"),is_resume:q.boolean(),resume_session_id:q.string().optional()}),$Q=j.extend({hook_event_name:q.literal("SessionEnd"),reason:q.enum(["user_exit","error","max_turns","idle_timeout","ctrl_c","clear","logout","other"])}),qQ=j.extend({hook_event_name:q.literal("SubagentStop"),agent_type:q.string(),task_description:q.string().optional(),success:q.boolean(),result_summary:q.string().optional(),error:q.string().optional()}),XQ=j.extend({hook_event_name:q.literal("Notification"),notification_type:q.enum(["permission_prompt","idle_prompt","auth_success","elicitation_dialog","info","warning","error"]),title:q.string().optional(),message:q.string()}),JQ=j.extend({hook_event_name:q.literal("Compaction"),trigger:q.enum(["manual","auto"]),messages_before:q.number(),tokens_before:q.number()}),dQ=q.discriminatedUnion("hook_event_name",[o,e,t,QQ,YQ,ZQ,WQ,$Q,qQ,XQ,JQ]),GQ=q.object({hookEventName:q.literal("PreToolUse"),permissionDecision:q.nativeEnum(S).optional(),permissionDecisionReason:q.string().optional(),updatedInput:q.record(q.unknown()).optional()}),KQ=q.object({hookEventName:q.literal("PostToolUse"),additionalContext:q.string().optional(),updatedOutput:q.unknown().optional()}),VQ=q.object({hookEventName:q.literal("Stop"),continue:q.boolean().optional(),continueReason:q.string().optional()}),FQ=q.object({hookEventName:q.literal("SubagentStop"),continue:q.boolean().optional(),continueReason:q.string().optional(),additionalContext:q.string().optional()}),RQ=q.object({hookEventName:q.literal("PermissionRequest"),permissionDecision:q.enum(["approve","deny","ask"]).optional(),permissionDecisionReason:q.string().optional()}),DQ=q.object({hookEventName:q.literal("UserPromptSubmit"),updatedPrompt:q.string().optional(),contextInjection:q.string().optional()}),LQ=q.object({hookEventName:q.literal("SessionStart"),env:q.record(q.string()).optional()}),_Q=q.object({hookEventName:q.literal("Compaction"),blockCompaction:q.boolean().optional(),blockReason:q.string().optional()}),jQ=q.object({decision:q.object({behavior:q.nativeEnum(C)}).optional(),systemMessage:q.string().optional(),hookSpecificOutput:q.discriminatedUnion("hookEventName",[GQ,KQ,VQ,FQ,RQ,DQ,LQ,_Q]).optional(),suppressOutput:q.boolean().optional()}),AQ=q.object({type:q.literal("command"),command:q.string(),timeout:q.number().positive().optional(),statusMessage:q.string().optional()}),BQ=q.object({type:q.literal("prompt"),prompt:q.string(),model:q.string().optional(),timeout:q.number().positive().optional()}),OQ=q.discriminatedUnion("type",[AQ,BQ]),H=q.union([q.string(),q.array(q.string())]),UQ=q.object({tools:H.optional(),paths:H.optional(),commands:H.optional()}),_=q.object({name:q.string().optional(),matcher:UQ.optional(),hooks:q.array(OQ)}),mQ=q.object({enabled:q.boolean().optional(),defaultTimeout:q.number().positive().optional(),timeoutBehavior:q.enum(["ignore","deny","ask"]).optional(),failureBehavior:q.enum(["ignore","deny","ask"]).optional(),maxConcurrentHooks:q.number().positive().optional(),PreToolUse:q.array(_).optional(),PostToolUse:q.array(_).optional(),PostToolUseFailure:q.array(_).optional(),PermissionRequest:q.array(_).optional(),UserPromptSubmit:q.array(_).optional(),SessionStart:q.array(_).optional(),SessionEnd:q.array(_).optional(),Stop:q.array(_).optional(),SubagentStop:q.array(_).optional(),Notification:q.array(_).optional(),Compaction:q.array(_).optional()});function p(Q){let Y=jQ.safeParse(Q);if(Y.success)return{success:!0,data:Y.data};return{success:!1,error:Y.error}}class v{parse(Q,Y,Z){if(Q.timedOut){let $=Z?.timeoutBehavior||"ignore",X="Hook timeout";if($==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};else if($==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y}}let W=this.tryParseJSON(Q.stdout);if(W){let $=p(W);if(!$.success){let G="error"in $?$.error.message:"Unknown validation error",J=Z?.failureBehavior||"ignore",K=`Invalid hook output JSON: ${G}`;if(J==="deny")return{success:!1,blocking:!0,error:K,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};else if(J==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${K}. Continue?`,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};else return{success:!1,blocking:!1,warning:K,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y}}let X=$.data;if(X.decision?.behavior==="block")return{success:!1,blocking:!0,error:X.systemMessage||"Hook blocked execution",output:X,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};if(X.decision?.behavior==="async")return{success:!0,output:X,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y};return{success:!0,output:X,stdout:Q.stdout,stderr:Q.stderr,exitCode:Q.exitCode,hook:Y}}return this.parseByExitCode(Q,Y,Z)}parseByExitCode(Q,Y,Z){let W=Q.exitCode;switch(W){case 0:return{success:!0,stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};case 2:return{success:!1,blocking:!0,error:Q.stderr||Q.stdout||"Hook returned exit code 2",stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};case 124:{let $=Z?.timeoutBehavior||"ignore",X="Hook timeout";if($==="deny")return{success:!1,blocking:!0,error:"Hook timeout",stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};else if($==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:"Hook timeout. Continue?",stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};else return{success:!1,blocking:!1,warning:"Hook timeout",stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y}}default:{let $=Z?.failureBehavior||"ignore",X=Q.stderr||Q.stdout||`Hook failed with exit code ${W}`;if($==="deny")return{success:!1,blocking:!0,error:X,stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};else if($==="ask")return{success:!1,blocking:!1,needsConfirmation:!0,warning:`${X}. Continue?`,stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y};else return{success:!1,blocking:!1,warning:X,stdout:Q.stdout,stderr:Q.stderr,exitCode:W,hook:Y}}}}tryParseJSON(Q){try{let Y=Q.trim();if(!Y)return null;let Z=Y.match(/^\s*(\{[\s\S]*\})\s*$/);if(!Z)return null;return JSON.parse(Z[1])}catch{return null}}}import{spawn as l}from"node:child_process";var PQ=500;function TQ(Q){return new Promise((Y)=>setTimeout(Y,Q))}function u(Q){return Q&&typeof Q==="object"&&"code"in Q?String(Q.code):void 0}function NQ(Q,Y){return new Promise((Z)=>{let W=["/PID",String(Q),"/T"];if(Y)W.push("/F");let $=l("taskkill",W,{stdio:"ignore",windowsHide:!0}),X=!1,G=(J)=>{if(X)return;X=!0,Z(J)};$.once("error",()=>G(!1)),$.once("close",(J)=>G(J===0))})}class a{child;state="owned";terminationPromise;terminationResult;platform;gracePeriodMs;killProcess;taskkill;wait;constructor(Q,Y={}){this.child=Q;this.platform=Y.platform??process.platform,this.gracePeriodMs=Y.gracePeriodMs??PQ,this.killProcess=Y.killProcess??process.kill.bind(process),this.taskkill=Y.taskkill??NQ,this.wait=Y.wait??TQ;let Z=()=>{if(this.state==="owned")this.state="released"};Q.once("close",Z),Q.once("error",Z)}release(){if(this.state==="owned")this.state="released"}terminate(){if(this.terminationPromise)return this.terminationPromise;if(this.terminationResult)return Promise.resolve(this.terminationResult);if(this.state==="released")return this.terminationResult={success:!0,alreadyExited:!0,forced:!1},Promise.resolve(this.terminationResult);return this.state="terminating",this.terminationPromise=this.terminateOwnedTree().then((Q)=>{return this.state="released",this.terminationResult=Q,Q}),this.terminationPromise}async terminateOwnedTree(){let Q=this.child.pid;if(!Q)return{success:!1,alreadyExited:!0,forced:!1};if(this.platform==="win32"){let W=await this.taskkill(Q,!1);await this.wait(this.gracePeriodMs);let $=await this.taskkill(Q,!0);if(!W&&!$)return{success:this.signalDirectChild("SIGKILL"),alreadyExited:!1,forced:!0};return{success:!0,alreadyExited:!1,forced:!0}}let Y=this.signalPosixTree(Q,"SIGTERM");await this.wait(this.gracePeriodMs);let Z=this.signalPosixTree(Q,"SIGKILL");return{success:Y||Z,alreadyExited:!1,forced:Z}}signalPosixTree(Q,Y){if(Q<=1||Q===process.pid)return this.signalDirectChild(Y);try{return this.killProcess(-Q,Y)}catch(Z){if(u(Z)==="ESRCH")return!0;return this.signalDirectChild(Y)}}signalDirectChild(Q){try{return this.child.kill(Q)}catch(Y){return u(Y)==="ESRCH"}}}function i(Q,Y,Z={}){let W=l(Q,Y,{...Z,detached:process.platform==="win32"?Z.detached:!0,windowsHide:Z.windowsHide??!0});return{child:W,processTree:new a(W)}}class g{content="";maxSize;constructor(Q){this.maxSize=Q}append(Q){if(this.content.length<this.maxSize){let Y=this.maxSize-this.content.length;this.content+=Q.substring(0,Y)}}getContent(){return this.content}isFull(){return this.content.length>=this.maxSize}}class d{MAX_STDOUT_SIZE=1048576;MAX_STDERR_SIZE=1048576;MAX_INPUT_SIZE=102400;async execute(Q,Y,Z,W){let $=JSON.stringify(Y);if($.length>this.MAX_INPUT_SIZE)throw Error(`Hook input too large: ${$.length} bytes (max ${this.MAX_INPUT_SIZE})`);let X=this.createSafeEnv(Y),{child:G,processTree:J}=i(Q,[],{shell:!0,env:X,cwd:Z.projectDir}),K=new g(this.MAX_STDOUT_SIZE),V=new g(this.MAX_STDERR_SIZE);G.stdout?.setEncoding("utf8"),G.stderr?.setEncoding("utf8"),G.stdout?.on("data",(D)=>{K.append(D)}),G.stderr?.on("data",(D)=>{V.append(D)});try{G.stdin?.write($),G.stdin?.end()}catch(D){throw await J.terminate(),Error(`Failed to write hook input: ${D}`)}return new Promise((D,R)=>{let L=!1,F=!1,B,O=()=>{return B??=J.terminate(),B},U=null,y=()=>{if(U&&Z.abortSignal)Z.abortSignal.removeEventListener("abort",U),U=null},M=setTimeout(()=>{L=!0,O()},W);if(G.on("close",async(w)=>{if(F)return;if(F=!0,clearTimeout(M),y(),L)await O();D({stdout:K.getContent(),stderr:V.getContent(),exitCode:L?124:w??1,timedOut:L})}),G.on("error",(w)=>{if(F)return;F=!0,clearTimeout(M),y(),R(w)}),Z.abortSignal){if(U=()=>{if(F)return;F=!0,clearTimeout(M),y(),O().then(()=>{D({stdout:K.getContent(),stderr:"Hook cancelled by abort signal",exitCode:1,timedOut:!1})})},Z.abortSignal.addEventListener("abort",U),Z.abortSignal.aborted)U()}})}createSafeEnv(Q){return{BLADE_PROJECT_DIR:Q.project_dir,BLADE_SESSION_ID:Q.session_id,BLADE_HOOK_EVENT:Q.hook_event_name,BLADE_TOOL_NAME:"tool_name"in Q?Q.tool_name:"",BLADE_TOOL_USE_ID:"tool_use_id"in Q?Q.tool_use_id:"",PATH:process.env.PATH||"",HOME:process.env.HOME||"",USER:process.env.USER||"",SHELL:process.env.SHELL||"/bin/sh"}}}class P extends Error{constructor(Q){super(Q);this.name="HttpHookSecurityError"}}function c(Q,Y={}){let Z;try{Z=new URL(Q)}catch{throw new P(`Invalid URL: ${Q}`)}if(Z.protocol!=="https:"&&Z.protocol!=="http:")throw new P(`Only http/https supported, got: ${Z.protocol}`);let W=Z.hostname.toLowerCase();if(bQ(W,Y.allowedHosts))return;if(Z.protocol==="http:"&&!Y.allowHttp)throw new P(`HTTP (non-TLS) blocked for ${W}; use https:// or add to allowedHosts`);if(yQ(W)&&!Y.allowLoopback)throw new P(`Loopback address blocked: ${W}; enable policy.allowLoopback or add to allowedHosts`);if(MQ(W)&&!Y.allowPrivateRanges)throw new P(`Private/link-local address blocked: ${W}; enable policy.allowPrivateRanges or add to allowedHosts`)}function bQ(Q,Y){if(!Y||Y.length===0)return!1;return Y.some((Z)=>{let W=Z.toLowerCase();if(W===Q)return!0;if(W.startsWith("*.")){let $=W.slice(1);return Q.endsWith($)&&Q.length>$.length}return!1})}function yQ(Q){if(Q==="localhost")return!0;if(Q==="::1"||Q==="[::1]")return!0;if(/^127\.\d+\.\d+\.\d+$/.test(Q))return!0;return!1}function MQ(Q){let Y=Q.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);if(!Y)return!1;let[Z,W]=Y.slice(1).map(Number);if(Z===10)return!0;if(Z===172&&W>=16&&W<=31)return!0;if(Z===192&&W===168)return!0;if(Z===169&&W===254)return!0;return!1}function s(Q){if(!Q)return{};let Y={};for(let[Z,W]of Object.entries(Q))Y[Z]=W.replace(/\$\{([A-Z_][A-Z0-9_]*)\}/gi,($,X)=>{return process.env[X]??`\${${X}}`});return Y}var wQ=r("Execution"),CQ={PreToolUse:'{ "permissionDecision": "approve" | "deny" | "ask", "permissionDecisionReason": "...", "updatedInput": { ... } }',PostToolUse:'{ "additionalContext": "注入到工具结果的额外信息", "updatedOutput": "修改后的工具输出" }',Stop:'{ "continue": true, "continueReason": "继续执行的原因" } // continue: true 表示阻止停止',SubagentStop:'{ "continue": true, "continueReason": "...", "additionalContext": "..." }',PermissionRequest:'{ "permissionDecision": "approve" | "deny" | "ask", "permissionDecisionReason": "..." }',UserPromptSubmit:'{ "updatedPrompt": "修改后的提示词", "contextInjection": "注入的上下文" }',Compaction:'{ "blockCompaction": true, "blockReason": "阻止压缩的原因" }'};class m{processExecutor=new d;outputParser=new v;chatServiceCache=new Map;async executePreToolHooks(Q,Y,Z){if(Q.length===0)return{decision:"allow"};let W="tool_input"in Y?Y.tool_input:{},$=[];for(let X of Q)try{let G={...Y,...W&&{tool_input:W}},J=await this.executeHook(X,G,Z);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)$.push(J.warning);continue}let K=J.output?.hookSpecificOutput;if(K&&"permissionDecision"in K){switch(K.permissionDecision){case"deny":return{decision:"deny",reason:K.permissionDecisionReason};case"ask":return{decision:"ask",reason:K.permissionDecisionReason};case"allow":break}if("updatedInput"in K&&K.updatedInput)W={...W,...K.updatedInput}}}catch(G){let J=G instanceof Error?G.message:String(G);if($.push(`Hook failed: ${J}`),Z.config.failureBehavior==="deny")return{decision:"deny",reason:J};else if(Z.config.failureBehavior==="ask")return{decision:"ask",reason:`Hook failed: ${J}. Continue?`}}return{decision:"allow",modifiedInput:W,warning:$.length>0?$.join(`
|
|
2
2
|
`):void 0}}async executePostToolHooks(Q,Y,Z){if(Q.length===0)return{};let W=Z.config.maxConcurrentHooks||5,$=await this.executeHooksConcurrently(Q,Y,Z,W),X=[],G=void 0,J=[];for(let K of $){if(!K.success&&K.warning){J.push(K.warning);continue}let V=K.output?.hookSpecificOutput;if(V&&"additionalContext"in V){if(V.additionalContext)X.push(V.additionalContext);if("updatedOutput"in V&&V.updatedOutput!==void 0)G=V.updatedOutput}}return{additionalContext:X.length>0?X.join(`
|
|
3
3
|
|
|
4
4
|
`):void 0,modifiedOutput:G,warning:J.length>0?J.join(`
|
|
@@ -21,7 +21,7 @@ import{Eb as n}from"./chunk-wre40mf1.js";import{Ob as r}from"./chunk-mt1c5da4.js
|
|
|
21
21
|
`):void 0}}async executeNotificationHooks(Q,Y,Z){let W="message"in Y?Y.message:"";if(Q.length===0)return{suppress:!1,message:W};let $=[],X=!1,G=W;for(let J of Q)try{let K=await this.executeHook(J,Y,Z);if(!K.success){if(K.warning)$.push(K.warning);continue}if(K.output?.suppressOutput){X=!0;break}if(K.stdout&&K.stdout.trim())G=K.stdout.trim()}catch(K){let V=K instanceof Error?K.message:String(K);$.push(`Hook failed: ${V}`)}return{suppress:X,message:G,warning:$.length>0?$.join(`
|
|
22
22
|
`):void 0}}async executeCompactionHooks(Q,Y,Z){if(Q.length===0)return{blockCompaction:!1};let W=[];for(let $ of Q)try{let X=await this.executeHook($,Y,Z);if(!X.success){if(X.warning)W.push(X.warning);continue}let G=X.output?.hookSpecificOutput;if(G&&"blockCompaction"in G&&G.blockCompaction)return{blockCompaction:!0,blockReason:G.blockReason,warning:W.length>0?W.join(`
|
|
23
23
|
`):void 0}}catch(X){let G=X instanceof Error?X.message:String(X);W.push(`Hook failed: ${G}`)}return{blockCompaction:!1,warning:W.length>0?W.join(`
|
|
24
|
-
`):void 0}}async executeHook(Q,Y,Z){if(Q.type==="command")return this.executeCommandHook(Q,Y,Z);if(Q.type==="prompt")return this.executePromptHook(Q,Y,Z);if(Q.type==="function")return this.executeFunctionHook(Q,Y,Z);if(Q.type==="http")return this.executeHttpHook(Q,Y,Z);throw Error(`Hook type ${Q.type} not supported`)}async executeCommandHook(Q,Y,Z){let W=(Q.timeout??Z.config.defaultTimeout??60)*1000;try{let $=await this.processExecutor.execute(Q.command,Y,Z,W);return this.outputParser.parse($,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch($){return{success:!1,blocking:!1,error:$ instanceof Error?$.message:String($),hook:Q}}}async executePromptHook(Q,Y,Z){let W=(Q.timeout??Z.config.defaultTimeout??60)*1000;try{let $=await this.getOrCreateChatService(Q.model),X="hook_event_name"in Y?String(Y.hook_event_name):"Unknown",G=this.buildPromptHookSystemMessage(Q,X),J=JSON.stringify(Y,null,2),K=new AbortController,V=setTimeout(()=>K.abort(),W),D;try{D=(await $.chat([{role:"system",content:G},{role:"user",content:J}],void 0,K.signal)).content}catch(L){if(K.signal.aborted||L instanceof Error&&L.name==="AbortError")return this.outputParser.parse({stdout:"",stderr:"",exitCode:0,timedOut:!0},Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior});throw L}finally{clearTimeout(V)}let R=this.extractJsonFromLLMResponse(D);return this.outputParser.parse({stdout:R,stderr:"",exitCode:0,timedOut:!1},Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch($){return wQ.warn(`[PromptHook] 执行失败: ${$ instanceof Error?$.message:String($)}`),{success:!1,blocking:!1,error:$ instanceof Error?$.message:String($),hook:Q}}}async executeFunctionHook(Q,Y,Z){let W=(Q.timeout??10)*1000;try{let $=await this.runFunctionWithTimeout(Q.handler,Y,Z,W);if($===void 0||$===null)return{success:!0,hook:Q};let X={stdout:JSON.stringify($),stderr:"",exitCode:0,timedOut:!1};return this.outputParser.parse(X,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch($){if($.isTimeout){let X={stdout:"",stderr:`Function hook timeout after ${W}ms`,exitCode:124,timedOut:!0};return this.outputParser.parse(X,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}return{success:!1,blocking:!1,error:$ instanceof Error?$.message:String($),hook:Q}}}runFunctionWithTimeout(Q,Y,Z,W){return new Promise(($,X)=>{let G=!1,J=setTimeout(()=>{if(G)return;G=!0;let V=Object.assign(Error(`Function hook timed out after ${W}ms`),{isTimeout:!0});X(V)},W),K=()=>{if(G)return;G=!0,clearTimeout(J),X(Error("Function hook aborted"))};Z.abortSignal?.addEventListener("abort",K,{once:!0}),Promise.resolve().then(()=>Q(Y,Z)).then((V)=>{if(G)return;G=!0,clearTimeout(J),Z.abortSignal?.removeEventListener("abort",K),$(V)},(V)=>{if(G)return;G=!0,clearTimeout(J),Z.abortSignal?.removeEventListener("abort",K),X(V)})})}async executeHttpHook(Q,Y,Z){let W=(Q.timeout??10)*1000,$=Q.maxResponseBytes??262144,X=Math.max(1,(Q.retries??0)+1);try{c(Q.url,Z.config.httpPolicy)}catch(V){return{success:!1,blocking:!0,error:V instanceof Error?V.message:String(V),hook:Q}}let G={"Content-Type":"application/json",...s(Q.headers)},J=JSON.stringify(Y),K;for(let V=0;V<X;V++){if(V>0){let F=Math.min(2**V*200,5000);await new Promise((B)=>setTimeout(B,F))}let D=new AbortController,R=setTimeout(()=>D.abort(),W),L=()=>D.abort();Z.abortSignal?.addEventListener("abort",L,{once:!0});try{let F=await fetch(Q.url,{method:"POST",headers:G,body:J,redirect:"manual",signal:D.signal});if(F.status>=300&&F.status<400){K=Error(`HTTP hook received redirect (${F.status}); redirects are disabled`);continue}if(!F.ok){if(K=Error(`HTTP hook returned ${F.status} ${F.statusText}`),F.status>=400&&F.status<500)break;continue}let O={stdout:await SQ(F,$),stderr:"",exitCode:0,timedOut:!1};return this.outputParser.parse(O,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch(F){let B=F.name==="AbortError"||F.code==="ABORT_ERR";if(B&&Z.abortSignal?.aborted){K=Error("HTTP hook aborted by caller");break}if(B){let O={stdout:"",stderr:`HTTP hook timeout after ${W}ms`,exitCode:124,timedOut:!0};if(V===X-1)return this.outputParser.parse(O,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior});K=Error(`HTTP hook timeout attempt ${V+1}`);continue}K=F}finally{clearTimeout(R),Z.abortSignal?.removeEventListener("abort",L)}}return{success:!1,blocking:!1,error:K?.message??"HTTP hook failed",hook:Q}}async getOrCreateChatService(Q){let Y=Q||"__default__",Z=this.chatServiceCache.get(Y);if(Z)return Z;let{ensureStoreInitialized:W,getCurrentModel:$,getModelById:X}=await import("./chunk-
|
|
24
|
+
`):void 0}}async executeHook(Q,Y,Z){if(Q.type==="command")return this.executeCommandHook(Q,Y,Z);if(Q.type==="prompt")return this.executePromptHook(Q,Y,Z);if(Q.type==="function")return this.executeFunctionHook(Q,Y,Z);if(Q.type==="http")return this.executeHttpHook(Q,Y,Z);throw Error(`Hook type ${Q.type} not supported`)}async executeCommandHook(Q,Y,Z){let W=(Q.timeout??Z.config.defaultTimeout??60)*1000;try{let $=await this.processExecutor.execute(Q.command,Y,Z,W);return this.outputParser.parse($,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch($){return{success:!1,blocking:!1,error:$ instanceof Error?$.message:String($),hook:Q}}}async executePromptHook(Q,Y,Z){let W=(Q.timeout??Z.config.defaultTimeout??60)*1000;try{let $=await this.getOrCreateChatService(Q.model),X="hook_event_name"in Y?String(Y.hook_event_name):"Unknown",G=this.buildPromptHookSystemMessage(Q,X),J=JSON.stringify(Y,null,2),K=new AbortController,V=setTimeout(()=>K.abort(),W),D;try{D=(await $.chat([{role:"system",content:G},{role:"user",content:J}],void 0,K.signal)).content}catch(L){if(K.signal.aborted||L instanceof Error&&L.name==="AbortError")return this.outputParser.parse({stdout:"",stderr:"",exitCode:0,timedOut:!0},Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior});throw L}finally{clearTimeout(V)}let R=this.extractJsonFromLLMResponse(D);return this.outputParser.parse({stdout:R,stderr:"",exitCode:0,timedOut:!1},Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch($){return wQ.warn(`[PromptHook] 执行失败: ${$ instanceof Error?$.message:String($)}`),{success:!1,blocking:!1,error:$ instanceof Error?$.message:String($),hook:Q}}}async executeFunctionHook(Q,Y,Z){let W=(Q.timeout??10)*1000;try{let $=await this.runFunctionWithTimeout(Q.handler,Y,Z,W);if($===void 0||$===null)return{success:!0,hook:Q};let X={stdout:JSON.stringify($),stderr:"",exitCode:0,timedOut:!1};return this.outputParser.parse(X,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch($){if($.isTimeout){let X={stdout:"",stderr:`Function hook timeout after ${W}ms`,exitCode:124,timedOut:!0};return this.outputParser.parse(X,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}return{success:!1,blocking:!1,error:$ instanceof Error?$.message:String($),hook:Q}}}runFunctionWithTimeout(Q,Y,Z,W){return new Promise(($,X)=>{let G=!1,J=setTimeout(()=>{if(G)return;G=!0;let V=Object.assign(Error(`Function hook timed out after ${W}ms`),{isTimeout:!0});X(V)},W),K=()=>{if(G)return;G=!0,clearTimeout(J),X(Error("Function hook aborted"))};Z.abortSignal?.addEventListener("abort",K,{once:!0}),Promise.resolve().then(()=>Q(Y,Z)).then((V)=>{if(G)return;G=!0,clearTimeout(J),Z.abortSignal?.removeEventListener("abort",K),$(V)},(V)=>{if(G)return;G=!0,clearTimeout(J),Z.abortSignal?.removeEventListener("abort",K),X(V)})})}async executeHttpHook(Q,Y,Z){let W=(Q.timeout??10)*1000,$=Q.maxResponseBytes??262144,X=Math.max(1,(Q.retries??0)+1);try{c(Q.url,Z.config.httpPolicy)}catch(V){return{success:!1,blocking:!0,error:V instanceof Error?V.message:String(V),hook:Q}}let G={"Content-Type":"application/json",...s(Q.headers)},J=JSON.stringify(Y),K;for(let V=0;V<X;V++){if(V>0){let F=Math.min(2**V*200,5000);await new Promise((B)=>setTimeout(B,F))}let D=new AbortController,R=setTimeout(()=>D.abort(),W),L=()=>D.abort();Z.abortSignal?.addEventListener("abort",L,{once:!0});try{let F=await fetch(Q.url,{method:"POST",headers:G,body:J,redirect:"manual",signal:D.signal});if(F.status>=300&&F.status<400){K=Error(`HTTP hook received redirect (${F.status}); redirects are disabled`);continue}if(!F.ok){if(K=Error(`HTTP hook returned ${F.status} ${F.statusText}`),F.status>=400&&F.status<500)break;continue}let O={stdout:await SQ(F,$),stderr:"",exitCode:0,timedOut:!1};return this.outputParser.parse(O,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior})}catch(F){let B=F.name==="AbortError"||F.code==="ABORT_ERR";if(B&&Z.abortSignal?.aborted){K=Error("HTTP hook aborted by caller");break}if(B){let O={stdout:"",stderr:`HTTP hook timeout after ${W}ms`,exitCode:124,timedOut:!0};if(V===X-1)return this.outputParser.parse(O,Q,{timeoutBehavior:Z.config.timeoutBehavior,failureBehavior:Z.config.failureBehavior});K=Error(`HTTP hook timeout attempt ${V+1}`);continue}K=F}finally{clearTimeout(R),Z.abortSignal?.removeEventListener("abort",L)}}return{success:!1,blocking:!1,error:K?.message??"HTTP hook failed",hook:Q}}async getOrCreateChatService(Q){let Y=Q||"__default__",Z=this.chatServiceCache.get(Y);if(Z)return Z;let{ensureStoreInitialized:W,getCurrentModel:$,getModelById:X}=await import("./chunk-0vd9antx.js"),{createChatServiceAsync:G}=await import("./chunk-vs915jzz.js");await W();let J=Q?X(Q)||$():$();if(!J)throw Error("PromptHook: 无法获取模型配置。请确保至少配置了一个模型。");let K=await G({provider:J.provider,apiKey:J.apiKey,baseUrl:J.baseUrl,model:J.model,temperature:J.temperature,maxContextTokens:J.maxContextTokens,maxOutputTokens:J.maxOutputTokens});return this.chatServiceCache.set(Y,K),K}buildPromptHookSystemMessage(Q,Y){let Z=CQ[Y]||"{ ... 根据事件类型返回相应字段 }";return`你是一个代码质量评估器,作为 Hook 在 ${Y} 事件中被触发。
|
|
25
25
|
|
|
26
26
|
`+`## 评估指令
|
|
27
27
|
${Q.prompt}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
function v(b){switch(b){case"default":case"ignore":case void 0:return"default";case"acceptEdits":return"autoEdit";case"dontAsk":case"bypassPermissions":return"yolo";case"plan":return"plan";default:return"default"}}
|
|
2
|
-
export{v as
|
|
2
|
+
export{v as Z};
|