openclaw-code-agent 4.4.0 → 4.4.2
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/index.js +161 -163
- package/openclaw.plugin.json +1 -1
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
var
|
|
2
|
-
`)}var
|
|
3
|
-
`)}}function
|
|
4
|
-
${
|
|
5
|
-
`)}async handleLine(e){let n=Al(e);n&&await xl(n,{pending:this.pending,onNotification:this.onNotification,onRequest:this.onRequest,respond:r=>this.write(r)})}flushPending(e){for(let[n,r]of this.pending)clearTimeout(r.timer),r.reject(e),this.pending.delete(n)}}});function W(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:null}function U(t,e,n){for(let r of e){let i=t?.[r];if(typeof i!="string")continue;let o=n?.trim===!1?i:i.trim();if(o)return o}}function Il(t){return t instanceof Error?t.message:String(t)}function Do(t){return t?t.split(",").map(e=>e.trim()).filter(Boolean):[]}function Te(t){if(typeof t=="string")return t;if(Array.isArray(t))return t.map(n=>Te(n)).join("");let e=W(t);if(!e)return"";for(let n of["delta","text","content","message","input","output","parts"]){let r=Te(e[n]);if(r)return r}for(let n of["item","turn","thread","response","result","data"]){let r=Te(e[n]);if(r)return r}return""}function At(t){let e=W(t);if(!e)return{};let n=W(e.thread)??W(e.session),r=W(e.turn)??W(e.run),i=W(e.item),o=W(e.serverRequest);return{threadId:U(e,["threadId","thread_id","conversationId","conversation_id"])??U(n,["id","threadId","thread_id","conversationId"]),runId:U(e,["turnId","turn_id","runId","run_id"])??U(r,["id","turnId","turn_id","runId","run_id"]),requestId:U(e,["requestId","request_id","serverRequestId"])??U(o,["id","requestId","request_id"]),itemId:U(e,["itemId","item_id"])??U(i,["id","itemId","item_id"])}}function un(t,e,n=0){if(n>6)return;if(Array.isArray(t)){for(let o of t){let s=un(o,e,n+1);if(s)return s}return}let r=W(t);if(!r)return;let i=U(r,e);if(i)return i;for(let o of Object.values(r)){let s=un(o,e,n+1);if(s)return s}}function xt(t){return{threadId:At(t).threadId,cwd:un(t,["cwd","workdir","directory"])}}function Oo(t){let e=t?.trim();return!!(e&&/[/\\]worktrees[/\\][^/\\]+[/\\][^/\\]+/.test(e))}function Wo(t){let e=t?.trim();if(!e)return;let n=e.split(/[/\\]+/).filter(Boolean),r=n.lastIndexOf("worktrees");if(!(r<0||r+1>=n.length))return n[r+1]}function cn(t){let e=W(t);if(!e)return;let n=W(e.item)??e;return U(n,["id","itemId","item_id","messageId","message_id"])}function Tl(t,e=!1){let n=W(t);if(!n)return"";let r=W(n.item)??n;return U(r,["type"])?.toLowerCase()!=="agentmessage"?"":e?Te(r):U(r,["text"],{trim:!1})??Te(r)}function No(t,e){let n=t.trim().toLowerCase();return n==="item/agentmessage/delta"?{mode:"delta",text:Te(e),itemId:cn(e)}:n==="item/completed"?{mode:"snapshot",text:Tl(e),itemId:cn(e)}:{mode:"ignore",text:""}}function Lo(t){return{itemId:cn(t),delta:Te(t)}}function Bo(t){let e=W(t),n=W(e?.plan),i=(Array.isArray(e?.plan)?e.plan:Array.isArray(n?.steps)?n.steps:[]).map(o=>{let s=W(o),a=U(s,["step","title","text"]);if(!a)return null;let d=U(s,["status"])?.toLowerCase()??"pending";return{step:a,status:d==="inprogress"||d==="in_progress"?"inProgress":d==="completed"?"completed":"pending"}}).filter(Boolean);return{explanation:U(n,["explanation"])??U(e,["explanation"]),steps:i}}function Fo(t){let e=W(t);if(!e)return{};let n=W(e.item)??e;return U(n,["type"])?.toLowerCase()!=="plan"?{}:{itemId:cn(n),text:U(n,["text"],{trim:!1})??Te(n)}}function qo(t,e){let n=t.trim().toLowerCase();if(n==="turn/failed")return"failed";if(n==="turn/cancelled")return"interrupted";let r=W(e)??{},i=W(r.turn)??r,o=U(i,["status"])?.toLowerCase();return o==="failed"?"failed":o==="interrupted"||o==="cancelled"?"interrupted":"completed"}function Ko(t,e){let n=W(e)??{},r=W(n.turn)??n,i=W(r.error)??W(n.error);if(i)return U(i,["message","text","summary","reason"])}function Cl(t,e){let n=Il(t).toLowerCase();return n.includes("method not found")||n.includes("unknown method")?!0:n.includes("unknown variant")?e?n.includes(`unknown variant \`${e.toLowerCase()}\``):!0:!1}function _l(t){return Ml.has(t.trim().toLowerCase())}function $l(t){let e=W(t);return e?!!U(e,["threadId","thread_id"]):!1}async function It(t){if(t.payloads.length===0)throw new Error(`codex app server request skipped: no payloads for ${t.methods.join(", ")||"<none>"}`);let e;for(let n of t.methods)for(let r of t.payloads){if(_l(n)&&!$l(r))throw new Error(`codex app server request missing threadId: ${n}`);try{return await t.client.request(n,r,t.timeoutMs)}catch(i){if(e=i,!Cl(i,n))continue}}throw e instanceof Error?e:new Error(String(e))}function Uo(t){let e={cwd:t.cwd};return t.model?.trim()&&(e.model=t.model.trim()),t.reasoningEffort?.trim()&&(e.reasoningEffort=t.reasoningEffort.trim()),t.fastMode===!0&&(e.service_tier="fast"),t.approvalPolicy?.trim()&&(e.approvalPolicy=t.approvalPolicy.trim()),t.sandbox?.trim()&&(e.sandbox=t.sandbox.trim()),[e]}function Vo(t){let e={threadId:t.threadId,persistExtendedHistory:!1};return t.model?.trim()&&(e.model=t.model.trim()),t.reasoningEffort?.trim()&&(e.reasoningEffort=t.reasoningEffort.trim()),t.fastMode===!0&&(e.service_tier="fast"),t.cwd?.trim()&&(e.cwd=t.cwd.trim()),t.approvalPolicy?.trim()&&(e.approvalPolicy=t.approvalPolicy.trim()),t.sandbox?.trim()&&(e.sandbox=t.sandbox.trim()),[e]}function El(t){return[{type:"text",text:t}]}function Dl(t,e,n,r){let i=e?.trim(),o=n?.trim(),s=r?.trim();if(t!=="plan")return i||o||s?{mode:"default",settings:{...i?{model:i}:{},...o?{reasoningEffort:o}:{},developerInstructions:s??null}}:void 0;if(!(!i&&!o&&!s))return{mode:"plan",settings:{...i?{model:i}:{},...o?{reasoningEffort:o}:{},developerInstructions:s??null}}}function Ho(t){let e={threadId:t.threadId,input:El(t.prompt)};t.model?.trim()&&(e.model=t.model.trim()),t.fastMode===!0&&(e.service_tier="fast"),t.approvalPolicy?.trim()&&(e.approvalPolicy=t.approvalPolicy.trim()),t.sandbox?.trim()&&(e.sandbox=t.sandbox.trim());let n=Dl(t.permissionMode??"default",t.model,t.reasoningEffort,t.systemPrompt);return n?[{...e,collaborationMode:n}]:[e]}function Go(t){return[{threadId:t.threadId,turnId:t.turnId}]}function Ol(t){let e=W(t);if(!e)return[];let n=e.options??e.choices??e.availableDecisions??e.decisions;return Array.isArray(n)?n.map(r=>typeof r=="string"?r.trim():U(W(r),["label","title","text","value","name","id"])??"").filter(Boolean):[]}function Wl(t){let e=t.trim().toLowerCase();return e.includes("session")?"acceptForSession":/cancel|abort|stop/.test(e)?"cancel":/deny|decline|reject|block|no/.test(e)?"decline":/approve|allow|accept|yes/.test(e)?"accept":t.trim()}function jo(t,e,n){let r=t.trim().toLowerCase(),i=Ol(n),o=un(n,["question","prompt","message","text","summary","reason"])??void 0,s=r.includes("requestapproval"),a=s?i.map(d=>({kind:"approval",label:d,decision:Wl(d),responseDecision:d})):i.map(d=>({kind:"option",label:d,value:d}));return{requestId:e,kind:s?"approval":"question",promptText:o,options:i,actions:a,allowsFreeText:!0}}function zo(t){let e=t.trim().toLowerCase();return e.includes("requestuserinput")||e.includes("requestapproval")}function mi(t,e){let n=t==="bypassPermissions"?"never":e?.trim()||"never";return{approvalPolicy:n,sandbox:n==="never"?"danger-full-access":void 0}}var Ml,Jo=H(()=>{Ml=new Set(["thread/resume","turn/start","turn/steer","turn/interrupt"])});function Qo(t){return t instanceof Error?t.message:String(t)}function ql(t){if(typeof t=="string")return t;if(!t||typeof t!="object")return String(t);let e=t;return typeof e.message?.content=="string"?e.message.content:typeof e.text=="string"?e.text:String(t)}var Nl,We,Ll,Bl,Fl,pn,Yo=H(()=>{Eo();sn();Jo();Nl="1.0",We=6e4,Ll="OPENCLAW_CODEX_APP_SERVER_COMMAND",Bl="OPENCLAW_CODEX_APP_SERVER_ARGS",Fl="OPENCLAW_CODEX_APP_SERVER_TIMEOUT_MS";pn=class{constructor(e={}){this.deps=e}deps;name="codex";backendKind="codex-app-server";supportedPermissionModes=["default","plan","bypassPermissions"];capabilities={nativePendingInput:!0,nativePlanArtifacts:!0,worktrees:"native-restore"};launch(e){let n={command:process.env[Ll]?.trim()||"codex",args:Do(process.env[Bl]),requestTimeoutMs:Number.parseInt(process.env[Fl]??String(We),10)||We},r=this.deps.createClient?.(n)??new ln(n.command,n.args,n.requestTimeoutMs),i=new xe,o=e.resumeSessionId,s,a=e.backendRef?.worktreePath,d=e.backendRef?.worktreeId,l=e.permissionMode??"default",u,c=0,p="",f=[],g,h=new Map,y=new Set,S=M=>{let I=M?.trim();if(!I)return;let T=e.originalWorkdir?.trim()||e.cwd.trim();e.worktreeStrategy&&e.worktreeStrategy!=="off"&&I!==T&&Oo(I)&&(a=I,d=Wo(I))},P=()=>{o&&i.enqueue(Ye({kind:"codex-app-server",conversationId:o,...s?{runId:s}:{},...d?{worktreeId:d}:{},...a?{worktreePath:a}:{}}))};r.setNotificationHandler(async(M,I)=>{let T=M.trim().toLowerCase(),L=At(I),te=xt(I);if(L.threadId&&o&&L.threadId!==o)return;if(L.threadId&&(o=L.threadId),L.runId&&(s=L.runId),S(te.cwd),(L.threadId||L.runId||te.cwd)&&P(),T==="serverrequest/resolved"){u&&(i.enqueue(Ie(u.requestId)),u=void 0);return}if(T==="turn/plan/updated"){let j=Bo(I);p=j.explanation??p,j.steps.length>0&&(f=j.steps);return}if(T==="item/plan/delta"){let j=Lo(I);if(j.itemId&&j.delta){let de=h.get(j.itemId)??"";h.set(j.itemId,`${de}${j.delta}`)}return}if(T==="item/completed"){let j=Fo(I);if(j.text?.trim()){let de={explanation:p||void 0,steps:f,markdown:j.text.trim()};i.enqueue(on(de,!0));return}}let B=No(T,I);if(B.mode==="delta"&&B.text){B.itemId&&y.add(B.itemId),i.enqueue(De(B.text));return}B.mode==="snapshot"&&B.text&&(!B.itemId||!y.has(B.itemId))&&i.enqueue(De(B.text)),(T==="turn/completed"||T==="turn/failed"||T==="turn/cancelled")&&g&&(g.method=M,g.params=I,g.resolve())}),r.setRequestHandler(async(M,I)=>{if(!zo(M))return{};let T=At(I),L=xt(I);if(T.threadId&&o&&T.threadId!==o)return{};T.threadId&&(o=T.threadId),T.runId&&(s=T.runId),S(L.cwd),(T.threadId||T.runId||L.cwd)&&P();let te=T.requestId??`${o??"codex"}-${Date.now().toString(36)}`,B=jo(M,te,I),j=M.trim().toLowerCase(),de=B.options,He=B.actions??[],ei=await new Promise(ti=>{u={requestId:te,methodLower:j,state:B,options:de,actions:He,resolveResponse:ti},i.enqueue(Oe(B))});return u=void 0,i.enqueue(Ie(te)),ei});let b=async()=>{await r.connect(),await r.request("initialize",{protocolVersion:Nl,clientInfo:{name:"openclaw-code-agent",version:"3.1.0"},capabilities:{experimentalApi:!0}},We),await r.notify("initialized",{})},R=async()=>{let M=mi(l,e.codexApprovalPolicy);if(o){let L=await It({client:r,methods:["thread/resume"],payloads:Vo({threadId:o,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:M.approvalPolicy,sandbox:M.sandbox}),timeoutMs:We}),te=xt(L);o=te.threadId??o,S(te.cwd),P();return}let I=await It({client:r,methods:["thread/start","thread/new"],payloads:Uo({cwd:e.cwd,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:M.approvalPolicy,sandbox:M.sandbox}),timeoutMs:We}),T=xt(I);if(o=T.threadId,!o)throw new Error("Codex App Server did not return a thread id.");S(T.cwd),P()},N=async M=>{await R(),i.enqueue(Ze()),c+=1,p="",f=[],h.clear(),y.clear();let I="",T,L,te=new Promise(B=>{L=B});g={resolve:L};try{let B=mi(l,e.codexApprovalPolicy),j=await It({client:r,methods:["turn/start"],payloads:Ho({threadId:o,prompt:M,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,systemPrompt:e.systemPrompt,permissionMode:l,approvalPolicy:B.approvalPolicy,sandbox:B.sandbox}),timeoutMs:We}),de=At(j);de.runId&&(s=de.runId,P()),await te,I=g?.method??"turn/failed",T=g?.params;let He=qo(I,T);i.enqueue(Pe({success:He==="completed",outcome:He,duration_ms:0,total_cost_usd:0,num_turns:c,result:Ko(I,T),session_id:o}))}catch(B){i.enqueue(Pe({success:!1,duration_ms:0,total_cost_usd:0,num_turns:c,result:Qo(B),session_id:o??""}))}finally{g=void 0}},fe=async M=>u?(u.methodLower.includes("requestapproval")?u.resolveResponse({decision:M.trim()||"decline"}):u.resolveResponse({text:M.trim()}),!0):!1,ge=async M=>{let I=u;if(!I)return!1;let T=I.actions[M];if(T?.kind==="approval")return I.resolveResponse({decision:T.responseDecision,...T.proposedExecpolicyAmendment?{proposedExecpolicyAmendment:T.proposedExecpolicyAmendment}:{}}),!0;let L=I.options[M];return L?(I.methodLower.includes("requestapproval")?I.resolveResponse({decision:L}):I.resolveResponse({option:L,index:M}),!0):!1},Re=typeof e.prompt=="string"?(async function*(){yield{type:"user",text:e.prompt,session_id:e.resumeSessionId??""}})():e.prompt;return(async()=>{try{await b();for await(let M of Re){let I=ql(M).trim();!I||await fe(I)||await N(I)}}catch(M){i.enqueue(Pe({success:!1,duration_ms:0,total_cost_usd:0,num_turns:c,result:Qo(M),session_id:o??e.resumeSessionId??""}))}finally{await r.close().catch(()=>{}),i.close()}})(),{messages:i.messages(),async setPermissionMode(M){l=M,i.enqueue(Xe(M))},async submitPendingInputOption(M){return ge(M)},async submitPendingInputText(M){return fe(M)},async interrupt(){!o||!s||await It({client:r,methods:["turn/interrupt"],payloads:Go({threadId:o,turnId:s}),timeoutMs:We}).catch(()=>{})}}}buildUserMessage(e,n){return{type:"user",text:e,session_id:n}}}});import{spawn as Kl}from"node:child_process";import{constants as Ul,accessSync as Vl}from"node:fs";import{createServer as Hl}from"node:net";import{delimiter as Gl,dirname as fi,join as Xo,sep as jl}from"node:path";function Tt(t){return t instanceof Error?t.message:String(t)}function Zl(t){try{return Vl(t,Ul.X_OK),!0}catch{return!1}}function Xl(t){return t.includes("/")||jl==="\\"&&t.includes("\\")}function eu(t){let e=(t??"").split(Gl).map(r=>r.trim()).filter(Boolean),n=[...e];for(let r of e)r.replaceAll("\\","/").endsWith("/opt/node/bin")&&n.push(Xo(fi(fi(fi(r))),"bin"));return n.push("/home/linuxbrew/.linuxbrew/bin","/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin"),[...new Set(n)]}function tu(t,e=process.env.PATH){if(Xl(t))return t;for(let n of eu(e)){let r=Xo(n,t);if(Zl(r))return r}return t}function z(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function nu(t){if(typeof t=="string")return t;if(!z(t))return String(t);if(typeof t.text=="string")return t.text;let e=z(t.message)?t.message:void 0;return typeof e?.content=="string"?e.content:String(t)}function es(t){let e=t?.trim();if(!e)return;let n=e.indexOf("/");if(!(n<=0||n===e.length-1))return{providerID:e.slice(0,n),modelID:e.slice(n+1)}}function ru(t){let e=es(t);return e?{id:e.modelID,providerID:e.providerID}:void 0}function Zo(t){let e=t??"default",n=e==="plan"?"deny":e==="bypassPermissions"?"allow":"ask";return Yl.map(r=>({permission:r,pattern:"*",action:n}))}function gi(){let t=process.env.OPENCODE_SERVER_PASSWORD;if(!t)return{};let e=process.env.OPENCODE_SERVER_USERNAME||"opencode";return{Authorization:`Basic ${Buffer.from(`${e}:${t}`).toString("base64")}`}}async function iu(){return new Promise((t,e)=>{let n=Hl();n.once("error",e),n.listen(0,"127.0.0.1",()=>{let r=n.address();n.close(()=>{r&&typeof r=="object"?t(r.port):e(new Error("Could not allocate local OpenCode server port."))})})})}async function ts(t){await new Promise(e=>setTimeout(e,t))}async function mn(t,e){if(e.signal?.aborted)throw new Error(e.abortMessage??"Operation was aborted.");return await new Promise((n,r)=>{let i=!1,o=()=>{clearTimeout(d),e.signal?.removeEventListener("abort",a)},s=l=>{i||(i=!0,o(),l())},a=()=>{s(()=>r(new Error(e.abortMessage??"Operation was aborted.")))},d=setTimeout(()=>{s(()=>{e.onTimeout?.(),r(new Error(e.timeoutMessage))})},e.timeoutMs);e.signal?.addEventListener("abort",a,{once:!0}),t.then(l=>s(()=>n(l)),l=>s(()=>r(l)))})}async function et(t){t.exitCode===null&&await new Promise(e=>{let n,r=setTimeout(()=>{t.exitCode===null&&t.kill("SIGKILL"),n=setTimeout(e,1e3)},2e3);t.once("exit",()=>{clearTimeout(r),n&&clearTimeout(n),e()}),t.kill("SIGTERM")})}function ou(t){return t.headers.get("content-type")?.toLowerCase()??""}function yi(t){return t.replace(/\s+/g," ").trim().slice(0,300)}function su(t,e){return t.includes("text/html")||/^\s*<!doctype html\b/i.test(e)||/^\s*<html[\s>]/i.test(e)}function au(t,e,n,r){let i=n?`content-type ${n}`:"missing content-type",o=yi(r),s=su(n,r)?" (looks like the OpenCode web UI HTML app shell)":"";return`OpenCode ${t} ${e} expected JSON API response but received ${i}${s}${o?`: ${o}`:""}`}function du(t,e,n){let r=es(e);return{...r?{model:{providerID:r.providerID,modelID:r.modelID}}:{},...n?.trim()?{system:n.trim()}:{},parts:[{type:"text",text:t}]}}function lu(t,e){if(!z(t))return!1;if(!(e in t))return!0;let n=t[e];return z(n)&&n.type==="idle"}async function uu(t){let e=await iu(),n=process.env[zl]?.trim()||"opencode",r=tu(n),i=["serve","--hostname","127.0.0.1","--port",String(e),"--print-logs"],o=t.fetch??fetch,s=Math.min(t.requestTimeoutMs??vi,1e4),a=t.startupTimeoutMs??Jl,d=Kl(r,i,{cwd:t.cwd,stdio:["ignore","pipe","pipe"]}),l=`http://127.0.0.1:${e}`,u="",c="",p,f=(S,P)=>{let b=S+String(P);return b.length>8e3?b.slice(-8e3):b};d.stdout.on("data",S=>{u=f(u,S)}),d.stderr.on("data",S=>{c=f(c,S)}),d.once("error",S=>{p=S});let g=()=>` Command: ${n===r?r:`${r} (resolved from ${n})`} ${i.join(" ")}. Cwd: ${t.cwd}. Port: ${e}. PATH: ${process.env.PATH??""}.`,h=()=>{let S=[u.trim(),c.trim()].filter(Boolean).join(`
|
|
6
|
-
`).trim();return`${g()}${
|
|
7
|
-
${
|
|
8
|
-
`).trim();!u||u==="[DONE]"||await e(JSON.parse(u))};for(;;){let{done:l,value:u}=await i.read();if(l)break;s+=o.decode(u,{stream:!0});let c=/\r?\n\r?\n/.exec(s);for(;c;){let p=s.slice(0,c.index);s=s.slice(c.index+c[0].length),await a(p),c=/\r?\n\r?\n/.exec(s)}}let d=s.trim();d&&await a(d)}};fn=class{constructor(e={}){this.deps=e}deps;name="opencode";backendKind="opencode-server";supportedPermissionModes=["default","plan","bypassPermissions"];capabilities={nativePendingInput:!0,nativePlanArtifacts:!1,worktrees:"plugin-managed"};launch(e){let n=new xe,r=this.deps.fetch??fetch,i,o,s,a=e.resumeSessionId,d=0,l=e.permissionMode??"default",u,c=!e.resumeSessionId,p=!1,f=!1,g=new AbortController,h,y=!1,S=!1,P=!1,b=!1,R=!1,N,fe=new Set,ge=A=>b?!1:(b=!0,n.enqueue(Pe(A)),!0),Re=(A,w,G)=>ge({success:A,outcome:w,duration_ms:0,total_cost_usd:0,num_turns:d,result:G,session_id:a??""}),M=()=>{a&&N!==a&&(N=a,n.enqueue(Ye({kind:"opencode-server",conversationId:a})))},I=A=>{A&&fe.has(A)||(A&&fe.add(A),n.enqueue(Ie(A)),A&&u?.requestId===A&&(u=void 0))},T=async()=>{if(o)return o;s??=(async()=>{let A=await(this.deps.createServer??cu)({cwd:e.cwd,signal:e.abortController?.signal,fetch:r,requestTimeoutMs:this.deps.requestTimeoutMs,startupTimeoutMs:this.deps.startupTimeoutMs});if(R||e.abortController?.signal.aborted)throw await A.close().catch(()=>{}),new Error("OpenCode startup was interrupted before session creation.");return i=A,o=new Si(A.baseUrl,r,this.deps.requestTimeoutMs),o})();try{return await s}catch(A){throw s=void 0,A}},L=async(A,w)=>{!o||!a||await o.request("POST",`/permission/${encodeURIComponent(A)}/reply`,{reply:w})},te=async(A,w)=>{!o||!a||await o.request("POST",`/question/${encodeURIComponent(A)}/reply`,{answers:[[w]]})},B=async A=>{let w=pu(A),G=mu(w.properties);if(!(G&&G!==a)){if((w.type==="session.next.text.delta"||w.type==="message.part.delta")&&w.properties.field!=="reasoning"&&typeof w.properties.delta=="string"){n.enqueue(De(w.properties.delta));return}if(w.type==="session.next.tool.called"||w.type==="message.part.updated"){let _=z(w.properties.part)?w.properties.part:void 0;if(w.type==="message.part.updated"&&_?.type!=="tool"){n.enqueue({type:"activity"});return}let X=typeof w.properties.tool=="string"?w.properties.tool:typeof _?.tool=="string"?_.tool:"tool";n.enqueue(rn(X,w.properties.input));return}if(w.type==="session.next.step.failed"||w.type==="session.error"){let _=z(w.properties.error)&&typeof w.properties.error.message=="string"?w.properties.error.message:`${w.type} failed`;S&&!P&&(h?.abort(),Re(!1,"failed",_));return}if(w.type==="permission.asked"){if(l==="bypassPermissions"){let X=typeof w.properties.id=="string"?w.properties.id:void 0;X&&(await L(X,"once").catch(()=>{}),I(X));return}let _=fu(w.properties);u={requestId:_.requestId,kind:"approval",options:_.options,actions:_.actions??[]},n.enqueue(Oe(_));return}if(w.type==="permission.replied"){let _=typeof w.properties.requestID=="string"?w.properties.requestID:void 0;I(_);return}if(w.type==="question.asked"){let _=gu(w.properties);u={requestId:_.requestId,kind:"question",options:_.options,actions:[]},n.enqueue(Oe(_));return}if(w.type==="question.replied"||w.type==="question.rejected"){let _=typeof w.properties.requestID=="string"?w.properties.requestID:void 0;I(_);return}(w.type?.startsWith("session.next.")||w.type?.startsWith("message.")||w.type==="session.status"||w.type==="session.idle")&&n.enqueue({type:"activity"})}},j=()=>{y||!o||(y=!0,o.streamEvents(B,g.signal).catch(A=>{!g.signal.aborted&&S&&!P&&(h?.abort(),Re(!1,"failed",Tt(A)))}).finally(()=>{y=!1}))},de=async(A,w)=>await A.request("GET",`/session/${encodeURIComponent(w)}/message`),He=async(A,w,G,_,X)=>{await A.request("POST",`/session/${encodeURIComponent(w)}/prompt_async`,du(G,e.model,_),{signal:X})},ei=async(A,w,G,_)=>{let X=Date.now(),Xt=!1,Ge=this.deps.turnTimeoutMs??Ql;for(;;){if(_.aborted)throw new Error("wait aborted");let Jd=await A.request("GET","/session/status",void 0,{signal:_,timeoutMs:Math.min(this.deps.requestTimeoutMs??vi,1e4)}),Ro=lu(Jd,w);Ro||(Xt=!0);let Qd=await de(A,w).catch(()=>{}),Yd=ki(Qd);if(Ro&&(Xt||Yd.count>G))return;if(Date.now()-X>Ge)throw new Error(`Timed out waiting for OpenCode session ${w} to become idle after ${Ge}ms.`);await ts(250)}},ti=async()=>{let A=await T();if(a){if(e.forkSession&&!p){let _=await A.request("POST",`/session/${encodeURIComponent(a)}/fork`,{});if(!_.id)throw new Error("OpenCode fork did not return a session id.");a=_.id,p=!0,c=!0}else c||(await de(A,a),c=!0);return M(),j(),a}let w=ru(e.model),G=await A.request("POST","/session",{...w?{model:w}:{},metadata:{client:"openclaw-code-agent"},permission:Zo(l)});if(!G.id)throw new Error("OpenCode did not return a session id.");return a=G.id,c=!0,M(),j(),a},bo=async(A,w,G=A?"completed":"failed")=>{let _=w;if(A&&o&&a){let X=await de(o,a).catch(()=>{});_=_??hu(X)}Re(A,G,_)},jd=async A=>{S=!0,P=!1,b=!1;try{let w=await T();if(R)return;let G=await ti();if(R)return;n.enqueue(Ze()),d+=1;let _=f?void 0:e.systemPrompt,X=await de(w,G).catch(()=>{}),Xt=ki(X).count,Ge=new AbortController;h=Ge,await He(w,G,A,_,Ge.signal),f=!0,await ei(w,G,Xt,Ge.signal),h=void 0,P=!0,await bo(!0)}catch(w){h=void 0,await bo(!1,Tt(w))}finally{S=!1,P=!1}},zd=typeof e.prompt=="string"?(async function*(){yield{type:"user",text:e.prompt,session_id:e.resumeSessionId??""}})():e.prompt;return(async()=>{try{for await(let A of zd){if(R)break;let w=nu(A).trim();if(w){if(u?.kind==="question"){await te(u.requestId,w),I(u.requestId);continue}if(await jd(w),R)break}}}catch(A){R||(S||(b=!1),Re(!1,"failed",Tt(A)))}finally{g.abort(),await i?.close().catch(()=>{}),n.close()}})(),{messages:n.messages(),async setPermissionMode(A){a&&await(await T()).request("PATCH",`/session/${encodeURIComponent(a)}`,{permission:Zo(A)}),l=A,n.enqueue(Xe(A))},async submitPendingInputOption(A){let w=u;if(!w)return!1;if(w.kind==="approval"){let _=w.actions[A],X=_?.kind==="approval"?_.responseDecision:void 0;return X?(await L(w.requestId,X),I(w.requestId),!0):!1}let G=w.options[A];return G?(await te(w.requestId,G),I(w.requestId),!0):!1},async submitPendingInputText(A){let w=u;return!w||w.kind!=="question"?!1:(await te(w.requestId,A),I(w.requestId),!0)},async interrupt(){if(R=!0,g.abort(),h?.abort(),S||(b=!1),Re(!1,"interrupted"),!o){await i?.close().catch(()=>{});return}if(!a)return;await o.request("POST",`/session/${encodeURIComponent(a)}/abort`).catch(()=>{})}}}buildUserMessage(e,n){return{type:"user",text:e,session_id:n}}}});function Pi(t){wi.set(t.name,t)}function Ct(t){let e=wi.get(t);if(!e)throw new Error(`Unknown agent harness: "${t}". Available: ${[...wi.keys()].join(", ")}`);return e}function rs(){return Ct(ne())}var wi,bi=H(()=>{$o();Yo();ns();Y();wi=new Map;Pi(new an);Pi(new pn);Pi(new fn)});function x(t){return t.backendRef?.conversationId??t.harnessSessionId}function D(t){return t.id??t.sessionId??t.name??x(t)??t.harnessSessionId}function yu(t){return t.harnessSessionId}function re(t){let e=[D(t),x(t),yu(t)].filter(n=>!!n);return[...new Set(e)]}function Ri(t){return t.harnessName??t.persistedHarness??ne()}function Mt(t){if(t.backendRef?.kind==="codex-app-server")return"native-restore";try{return Ct(Ri(t)).capabilities.worktrees}catch{return"plugin-managed"}}function Ai(t){return t==="native-execution"}function gn(t){return t==="native-restore"}function Su(t){return!!(t.backendRef?.worktreePath||t.backendRef?.worktreeId)}function ie(t){let e=Mt(t);return(Ai(e)||gn(e))&&Su(t)}var V=H(()=>{Y();bi()});import{execFileSync as Q}from"child_process";import*as En from"fs";import{tmpdir as Vu}from"os";import{dirname as As,join as Hu}from"path";function Gu(t){try{return Q("git",["rev-parse","--show-toplevel"],{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function Dn(t){if(process.env.OPENCLAW_WORKTREE_DIR)return process.env.OPENCLAW_WORKTREE_DIR;if(C.worktreeDir)return C.worktreeDir;if(t){let e=Gu(t);if(e)return Hu(e,".worktrees")}return Vu()}function xs(t){return t.replace(/[^a-zA-Z0-9._-]/g,"-").replace(/\.{2,}/g,"-").replace(/^[-.]|[-.]$/g,"").slice(0,100)||"session"}function On(t){try{let e=Q("git",["-C",t,"rev-parse","--git-common-dir"],{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();return e&&e.endsWith("/.git")?As(e):void 0}catch{return}}function ju(){if(_n!==void 0)return _n;try{return Q("git",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),_n=!0,!0}catch{return _n=!1,!1}}function Ce(){if($n!==void 0)return $n;try{return Q("gh",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),$n=!0,!0}catch{return $n=!1,!1}}function Mi(t){if(!ju())return!1;try{return Q("git",["rev-parse","--git-dir"],{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function Is(t){try{let e=Ju(t);if(!e)return`${Dn(t)}`,!0;let n=En.statfsSync(e),r=n.bavail*n.bsize;return Qu(r)}catch(e){return`${e instanceof Error?e.message:String(e)}`,!0}}function Ot(t,e){try{return Q("git",["-C",t,"rev-parse","--verify",e],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function zu(t){let e=t;for(;;){if(En.existsSync(e))return e;let n=As(e);if(n===e)return;e=n}}function Ju(t){return zu(Dn(t))}function Qu(t){return t>=104857600}function ke(t){let e=process.env.OPENCLAW_WORKTREE_BASE_BRANCH?.trim();if(e)return e;try{let r=Q("git",["-C",t,"rev-parse","--abbrev-ref","origin/HEAD"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().replace(/^origin\//,"");if(r)return r}catch{}try{return Q("git",["-C",t,"rev-parse","--verify","main"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),"main"}catch{}try{return Q("git",["-C",t,"rev-parse","--verify","master"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),"master"}catch{return"main"}}function Wn(t){try{let n=Q("git",["-C",t,"rev-parse","--abbrev-ref","HEAD"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();if(n==="HEAD"){`${t}`;return}return n||void 0}catch{return}}function Wt(t,e,n){try{let r=Q("git",["-C",t,"rev-list","--count",`${n}..${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});return parseInt(r.trim(),10)>0}catch{return!1}}function Ts(t,e,n){try{let r=Q("git",["-C",t,"rev-list","--left-right","--count",`${e}...${n}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),[i,o]=r.split(/\s+/);return{ahead:parseInt(i??"0",10)||0,behind:parseInt(o??"0",10)||0}}catch{return}}function Cs(t,e,n){try{return Q("git",["-C",t,"merge-base","--is-ancestor",e,n],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function Ms(t,e,n){try{let r=Q("git",["-C",t,"merge-tree","--write-tree",n,e],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),i=Q("git",["-C",t,"rev-parse",`${n}^{tree}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();return!!r&&r===i}catch{return!1}}function ve(t,e){try{return Q("git",["-C",t,"branch","-D",e],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch(n){return`${e}${n instanceof Error?n.message:String(n)}`,!1}}function _s(t,e){if(e)return e;let n;try{n=Q("git",["-C",t,"remote","get-url","origin"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{}try{let r=Q("git",["-C",t,"remote","get-url","upstream"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();if(r&&r!==n){let i=r.match(/[:/]([^/]+\/[^/]+?)(?:\.git)?$/);if(i)return i[1]}}catch{}}var _n,$n,Nt=H(()=>{Y()});import{execFileSync as ot}from"child_process";import{appendFileSync as Yu,existsSync as Ds,mkdirSync as $s,readFileSync as Zu,rmSync as _i}from"fs";import{relative as Xu,sep as Es}from"path";function ec(t,e){return!!(t&&typeof t=="object"&&"code"in t&&t.code===e)}function tc(t){try{return ot("git",["-C",t,"rev-parse","--show-toplevel"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function nc(t,e){let n=tc(t);if(!n)return;let r=Xu(n,e);if(!r||r.startsWith("..")||r.includes(`..${Es}`))return;let i=`${n}/.git/info/exclude`,o=`${r.split(Es).join("/").replace(/\/$/,"")}/`;try{let s=Ds(i)?Zu(i,"utf-8"):"";s.split(/\r?\n/).map(d=>d.trim()).some(d=>d===o||d===`/${o}`)||Yu(i,`${s.endsWith(`
|
|
1
|
+
var ll=Object.defineProperty;var j=(t,e)=>()=>(t&&(e=t(t=0)),e);var ul=(t,e)=>{for(var n in e)ll(t,n,{get:e[n],enumerable:!0})};function At(t,e){return e?{...e,...t}:t}function cl(t){return{...t,[mo]:!0}}function pl(t){return{const:t,type:typeof t}}var mo,m,X=j(()=>{mo=Symbol("optionalSchema");m={Object(t,e){let n=Object.entries(t).filter(([,o])=>!o[mo]).map(([o])=>o),r=Object.fromEntries(Object.entries(t).map(([o,i])=>{let{[mo]:s,...a}=i;return[o,a]}));return{...e,type:"object",...n.length>0?{required:n}:{},properties:r}},String(t){return At({type:"string"},t)},Number(t){return At({type:"number"},t)},Boolean(t){return At({type:"boolean"},t)},Array(t,e){return At({type:"array",items:t},e)},Literal:pl,Union(t,e){return At({anyOf:t},e)},Optional:cl}});function fo(t){v=t}function go(t){q=t}var v,q,O=j(()=>{v=null,q=null});function qi(t){let e=t.chatId.trim(),n=t.topicId.trim();return!/^-?\d+$/.test(e)||!/^\d+$/.test(n)?null:`${e}:topic:${n}`}function Sl(t){let e=t.conversationId.trim(),n=e.match(/^(-?\d+):topic:(\d+)$/i);if(n?.[1]&&n[2]){let i=qi({chatId:n[1],topicId:n[2]});return i?{chatId:n[1],topicId:n[2],canonicalConversationId:i}:null}if(!/^\d+$/.test(e))return null;let r=t.parentConversationId?.trim();if(!r||!/^-?\d+$/.test(r))return null;let o=qi({chatId:r,topicId:e});return o?{chatId:r,topicId:e,canonicalConversationId:o}:null}function yl(t){if(!t)return;let e=t.match(/^agent:[^:]+:discord:(direct|dm|channel|group):/i);if(!e?.[1])return;let n=e[1].toLowerCase();return n==="direct"||n==="dm"?"user":"channel"}function kl(t,e){if(!/^\d+$/.test(t))return t;let n=yl(e);return n?`${n}:${t}`:`channel:${t}`}function vl(t){if(!(!t?.provider||!t.target)&&!(t.provider==="system"||t.target==="system"))return t.accountId?`${t.provider}|${t.accountId}|${t.target}`:`${t.provider}|${t.target}`}function wl(t){let e=t.toLowerCase(),n=[":thread:",":topic:"];for(let r of n){let o=e.lastIndexOf(r);if(o===-1)continue;let i=t.slice(0,o).trim(),s=t.slice(o+r.length).trim()||void 0;return{id:i||t,threadId:s}}return{id:t}}function Pl(t){let e=t?.trim();if(!e)return;let n=e.split(":").filter(Boolean);if(n[0]?.trim().toLowerCase()==="agent")for(let r=2;r<=n.length-3;r+=1){let o=n[r]?.trim().toLowerCase();if(!o||!hl.has(o))continue;let i=n[r+1]?.trim().toLowerCase(),s=n.slice(r+2).join(":").trim();if(!(!i||!s))return{provider:o,kind:i,rawId:s}}}function bl(t,e=Sl){try{return e({conversationId:t})}catch{return null}}function ho(t){return{provider:"system",target:"system",sessionKey:t?.trim()||void 0}}function So(t,e){return{...t,threadId:e??t.threadId}}function Rl(t,e,n){return t==="telegram"&&n?.provider==="telegram"&&!!n.target&&e!==n.target}function Il(t){let e=t?.trim();if(!e)return;let n=Pl(e);if(!n)return;let{provider:r,kind:o,rawId:i}=n,s=wl(i),a=null;if(r==="telegram")try{a=Al.safeParseTelegramTopicConversation(i)}catch{a=null}let d=a?.chatId??s.id,l=a?.topicId??s.threadId,u=r==="discord"?o==="direct"||o==="dm"?`user:${d}`:`channel:${d}`:d;return{provider:r,target:u,threadId:l,sessionKey:e}}function yo(t){let e=t?.match(/:topic:(\d+)$/);return e?parseInt(e[1],10):void 0}function Ki(t){return!!(t?.provider&&t.target&&t.provider!=="system"&&t.target!=="system")}function Rt(t,e,n){let r=Il(n),o=e!=null?String(e):void 0,i=t?.trim();if(!i||i.toLowerCase()==="unknown")return r?So(r,o):ho(n);let s=i.split("|").map(g=>g.trim());if(s.length<2)return r?So(r,o):ho(n);let[a,d,l]=s,u=s.length>=3?l:d,c=s.length>=3?d:void 0,p=a?.toLowerCase();if(!p||!u)return r?So(r,o):ho(n);let f=p==="discord"?kl(u,n):u;return Rl(p,f,r)?{provider:p,accountId:c,target:r.target,threadId:o??r.threadId,sessionKey:n?.trim()||void 0}:{provider:p,accountId:c,target:f,threadId:o??(r?.provider===p?r.threadId:void 0),sessionKey:n?.trim()||void 0}}function Ne(t){return Rt(vl(t.route)??t.originChannel,t.route?.threadId??t.originThreadId,t.route?.sessionKey??t.originSessionKey)??t.route}function Re(t){let e=Ne(t);return Ki(e)?e:void 0}function xl(t){return Object.fromEntries(Object.entries(t).filter(e=>!!e[1]))}function It(t){let e=Ne(t);if(!Ki(e))return"";let n=xl({provider:e?.provider,accountId:e?.accountId,target:e?.target,threadId:e?.threadId??(t.originThreadId!=null?String(t.originThreadId):void 0),sessionKey:e?.sessionKey??t.originSessionKey});return Object.keys(n).length===0?"":["Session origin route (authoritative for human follow-ups):",`originRoute: ${JSON.stringify(n)}`,"Routing rule: Send any human follow-up for this wake to originRoute. If originRoute differs from the current chat, do not use a plain final assistant reply; use a routed send path that preserves provider/target/threadId."].join(`
|
|
2
|
+
`)}var hl,Al,ve=j(()=>{hl=new Set(["telegram","discord","slack","system","mattermost","feishu","line","whatsapp","signal","matrix","googlechat","bluebubbles","imessage","msteams"]);Al={safeParseTelegramTopicConversation:bl}});import{readFileSync as Tl}from"fs";import{homedir as Cl}from"os";import{join as Ml}from"path";function Vi(){if(xt!==void 0)return xt;try{let t=Tl(Ml(Cl(),".claude.json"),"utf-8");xt=JSON.parse(t).mcpServers??{}}catch{xt={}}return xt}function Gi(t){let e=t.defaultHarness??Ui,n={};for(let[r,o]of Object.entries(Tt)){let i={...o};o.allowedModels&&(i.allowedModels=[...o.allowedModels]),n[r]=i}for(let[r,o]of Object.entries(t.harnesses??{})){let i=n[r]??{},s={...i,defaultModel:o.defaultModel??i.defaultModel,reasoningEffort:o.reasoningEffort??i.reasoningEffort,fastMode:o.fastMode??i.fastMode};o.allowedModels!==void 0?s.allowedModels=o.allowedModels?[...o.allowedModels]:o.allowedModels:o.defaultModel!==void 0&&(s.allowedModels=void 0),n[r]=s}if(t.defaultModel!==void 0){let r=n[e]??{};n[e]={...r,defaultModel:t.harnesses?.[e]?.defaultModel??t.defaultModel,allowedModels:t.harnesses?.[e]?.allowedModels!==void 0?r.allowedModels:t.allowedModels},`${e}`}if(t.model!==void 0){let r=n.codex??{};n.codex={...r,defaultModel:t.harnesses?.codex?.defaultModel??t.model,allowedModels:t.harnesses?.codex?.allowedModels!==void 0?r.allowedModels:t.allowedModels}}if(t.reasoningEffort!==void 0){let r=n.codex??{};n.codex={...r,reasoningEffort:t.harnesses?.codex?.reasoningEffort??t.reasoningEffort}}if(t.allowedModels!==void 0)for(let[r,o]of Object.entries(n))t.harnesses?.[r]?.allowedModels===void 0&&(n[r]={...o,allowedModels:void 0});E={maxSessions:t.maxSessions??20,defaultWorkdir:t.defaultWorkdir,idleTimeoutMinutes:t.idleTimeoutMinutes??15,sessionGcAgeMinutes:t.sessionGcAgeMinutes??1440,maxPersistedSessions:t.maxPersistedSessions??1e4,fallbackChannel:t.fallbackChannel,agentChannels:t.agentChannels,maxAutoResponds:t.maxAutoResponds??10,permissionMode:t.permissionMode??"plan",planApproval:t.planApproval??"delegate",defaultHarness:e,harnesses:n,allowedModels:t.allowedModels,defaultWorktreeStrategy:t.defaultWorktreeStrategy??"delegate",worktreeDir:t.worktreeDir}}function se(){return E.defaultHarness??Ui}function wo(t){let e=Tt[t],n=E.harnesses[t];return{...e,...n,allowedModels:n?.allowedModels??e?.allowedModels}}function Ze(t){return wo(t).defaultModel}function sn(t){return E.harnesses[t]?.allowedModels??E.allowedModels}function Ce(t){return wo(t).reasoningEffort}function Xe(t){return t==="codex"?wo(t).fastMode:void 0}function Pe(t){return t==null?void 0:String(t).trim()||void 0}function Po(t){return{channel:Pe(t?.deliveryContext?.channel),to:Pe(t?.deliveryContext?.to),accountId:Pe(t?.deliveryContext?.accountId),threadId:Pe(t?.deliveryContext?.threadId)}}function Hi(t,e,n){if(!(!t||!e))return n?`${t}|${n}|${e}`:`${t}|${e}`}function ko(t){return Pe(t?.requesterSenderId??t?.senderId)}function vo(t){return(Pe(t.deliveryContext?.channel)??t.messageChannel??t.channel)?.toLowerCase()!=="telegram"?!1:!!yo(t.sessionKey)}function an(t){let e=Po(t),n=Hi(e.channel,e.to,e.accountId);if(n)return n;if(t.messageChannel){let r=t.messageChannel.split("|");if(r.length>=3)return t.messageChannel;if(t.agentAccountId&&r.length>=2)return`${r[0]}|${t.agentAccountId}|${r.slice(1).join("|")}`;let o=Pe(t.chatId);if(r.length===1&&o)return`${r[0]}|${o}`;let i=ko(t);if(r.length===1&&i&&!vo(t))return`${r[0]}|${i}`}if(t.workspaceDir){let r=Mt(t.workspaceDir);if(r)return r}if(t.messageChannel&&t.messageChannel.includes("|"))return t.messageChannel}function Ct(t,e){if(e&&String(e).includes("|"))return String(e);let n=Po(t),r=Hi(n.channel,n.to,n.accountId);if(r)return r;if(t?.channelId&&String(t.channelId).includes("|"))return String(t.channelId);if(t?.messageChannel){let a=String(t.messageChannel);if(a.includes("|"))return a;let d=Pe(t.chatId);if(d)return`${a}|${d}`;let l=ko(t);if(l&&!vo(t))return`${a}|${l}`}let o=Pe(t?.channel),i=Pe(t?.chatId);if(o&&i)return`${o}|${i}`;let s=ko(t);return o&&s&&!vo(t)?`${o}|${s}`:t?.id&&/^-?\d+$/.test(String(t.id))?`telegram|${t.id}`:E.fallbackChannel??"unknown"}function bo(t){return Po(t).threadId??t?.messageThreadId??void 0}function et(t,e,n){return Rt(Ct(t,e),bo(t),n??t?.sessionKey)}function Mt(t){let e=E.agentChannels;if(!e)return;let n=i=>i.replace(/\/+$/,""),r=n(t),o=Object.entries(e).sort((i,s)=>s[0].length-i[0].length);for(let[i,s]of o)if(r===n(i)||r.startsWith(n(i)+"/"))return s}function ji(t){return yo(t)}var xt,Ui,Tt,E,te=j(()=>{ve();Ui="claude-code",Tt={"claude-code":{defaultModel:"anthropic/claude-sonnet-4-7",allowedModels:["sonnet","opus"]},codex:{defaultModel:"gpt-5.5",allowedModels:["gpt-5.5","gpt-5.5-pro"],reasoningEffort:"medium"},opencode:{}};E={maxSessions:20,idleTimeoutMinutes:15,sessionGcAgeMinutes:1440,maxPersistedSessions:1e4,maxAutoResponds:10,permissionMode:"plan",planApproval:"delegate",defaultWorktreeStrategy:"delegate",harnesses:{"claude-code":{...Tt["claude-code"]},codex:{...Tt.codex},opencode:{...Tt.opencode}}}});function nt(t){return{type:"backend_ref",ref:t}}function rt(t){return{type:"run_started",...t?{runId:t}:{}}}function Le(t){return{type:"text_delta",text:t}}function dn(t,e){return{type:"tool_call",name:t,input:e}}function Be(t){return{type:"pending_input",state:t}}function _e(t){return t?{type:"pending_input_resolved",requestId:t}:{type:"pending_input_resolved"}}function ln(t,e){return{type:"plan_artifact",artifact:t,finalized:e}}function ot(t){return t?{type:"settings_changed",permissionMode:t}:{type:"settings_changed"}}function Ie(t){return{type:"run_completed",data:t}}var Me,un=j(()=>{Me=class{queue=[];resolvePending=null;done=!1;enqueue(e){this.queue.push(e),this.flush()}close(){this.done=!0,this.flush()}flush(){this.resolvePending&&(this.resolvePending(),this.resolvePending=null)}messages(){let e=this;return(async function*(){for(;;){for(;e.queue.length>0;)yield e.queue.shift();if(e.done)return;await new Promise(n=>{e.resolvePending=n})}})()}}});import*as pn from"@anthropic-ai/claude-agent-sdk";function _l(t){if(typeof t.result=="string"&&t.result.length>0)return t.result;if(Array.isArray(t.errors)){let e=t.errors.filter(n=>typeof n=="string"&&n.length>0);if(e.length>0)return e.join(`
|
|
3
|
+
`)}}function El(t,e,n){let o=(Array.isArray(n.questions)?n.questions:[])[0]??{},i=typeof o.question=="string"?o.question:void 0,s=Array.isArray(o.options)?o.options.map(a=>{if(!a||typeof a!="object")return"";let d=a.label;return typeof d=="string"?d:""}).filter(Boolean):[];return{requestId:`${t||"claude"}-ask-${e}`,kind:"question",promptText:i,options:s,allowsFreeText:s.length===0||o.multiSelect===!0}}var cn,zi=j(()=>{un();cn=class{constructor(e={}){this.deps=e}deps;name="claude-code";backendKind="claude-code";supportedPermissionModes=["default","plan","bypassPermissions"];capabilities={nativePendingInput:!1,nativePlanArtifacts:!1,worktrees:"plugin-managed"};launch(e){let n=new Me,r=!1,o="",i=!1,s=0,a=e.resumeSessionId??"",d=e.canUseTool,l={cwd:e.cwd,model:e.model,...e.reasoningEffort?{effort:e.reasoningEffort}:{},permissionMode:e.permissionMode,allowDangerouslySkipPermissions:!0,allowedTools:e.allowedTools,systemPrompt:e.systemPrompt,includePartialMessages:!0,abortController:e.abortController,mcpServers:e.mcpServers,...d?{canUseTool:async(g,h)=>{if(g!=="AskUserQuestion")return{behavior:"allow"};let y=El(a,++s,h);n.enqueue(Be(y));try{let k=await d(g,h);return n.enqueue(_e(y.requestId)),k}catch(k){throw n.enqueue(_e(y.requestId)),k}}}:{}};e.resumeSessionId&&(l.resume=e.resumeSessionId,l.forkSession=e.forkSession??!1);let u=e.prompt,c=this.deps.query??pn.query,p=this.deps.startup??pn.startup,f=(async()=>{if(typeof p!="function")return c({prompt:u,options:l});let g=await p({options:l});try{return g.query(u)}catch(h){throw await g.close?.(),h}})();return(async()=>{try{let g=await f;for await(let h of g){let y=h;if(y.type==="system"&&y.subtype==="init"){a=y.session_id??a,n.enqueue(nt({kind:"claude-code",conversationId:a}));continue}if(y.type==="system"&&y.subtype==="status"&&y.permissionMode){n.enqueue(ot(y.permissionMode));continue}if(y.type==="assistant"){r||(r=!0,n.enqueue(rt()));for(let k of y.message?.content??[]){if(k.type==="text"){o+=o?`
|
|
4
|
+
${k.text}`:k.text,n.enqueue(Le(k.text));continue}k.type==="tool_use"&&((k.name==="ExitPlanMode"||k.name==="set_permission_mode")&&(i=!0),k.name!=="AskUserQuestion"&&n.enqueue(dn(k.name,k.input)))}continue}if(y.type==="result"){let k=o.trim();if(k&&(e.permissionMode==="plan"||i)){let R={explanation:void 0,steps:[],markdown:k};n.enqueue(ln(R,!0))}n.enqueue(Ie({success:y.subtype==="success",duration_ms:y.duration_ms??0,total_cost_usd:y.total_cost_usd??0,num_turns:y.num_turns??0,result:_l(y),session_id:y.session_id??a})),o="",i=!1,r=!1}}}finally{n.close()}})().catch(g=>{n.enqueue(Ie({success:!1,duration_ms:0,total_cost_usd:0,num_turns:0,result:g instanceof Error?g.message:String(g),session_id:a})),n.close()}),{messages:n.messages(),async setPermissionMode(g){let h=await f;typeof h.setPermissionMode=="function"&&await h.setPermissionMode(g)},async streamInput(g){let h=await f;typeof h.streamInput=="function"&&await h.streamInput(g)},async interrupt(){let g=await f;typeof g.interrupt=="function"&&await g.interrupt()}}}buildUserMessage(e,n){return{type:"user",message:{role:"user",content:e},parent_tool_use_id:null,session_id:n}}}});import{spawn as $l}from"node:child_process";import Dl from"node:readline";function Ol(t){return t instanceof Error?t.message:String(t)}function Wl(t){try{let e=JSON.parse(t);return!e||typeof e!="object"||Array.isArray(e)?null:e}catch{return null}}async function Nl(t,e){if(t.id!=null&&(Object.hasOwn(t,"result")||Object.hasOwn(t,"error"))){let r=String(t.id),o=e.pending.get(r);if(!o)return;if(clearTimeout(o.timer),e.pending.delete(r),t.error){o.reject(new Error(`codex app server rpc error (${t.error.code??"unknown"}): ${t.error.message??"unknown error"}`));return}o.resolve(t.result);return}let n=t.method?.trim();if(n){if(t.id==null){await e.onNotification(n,t.params);return}try{let r=await e.onRequest(n,t.params);e.respond({jsonrpc:"2.0",id:t.id,result:r??{}})}catch(r){e.respond({jsonrpc:"2.0",id:t.id,error:{code:-32603,message:Ol(r)}})}}}var mn,Qi=j(()=>{mn=class{constructor(e,n,r){this.command=e;this.args=n;this.requestTimeoutMs=r}command;args;requestTimeoutMs;process=null;pending=new Map;counter=0;onNotification=()=>{};onRequest=async()=>({});setNotificationHandler(e){this.onNotification=e}setRequestHandler(e){this.onRequest=e}async connect(){if(this.process)return;let e=$l(this.command,["app-server",...this.args],{stdio:["pipe","pipe","pipe"],env:process.env});if(!e.stdin||!e.stdout||!e.stderr)throw new Error("codex app server stdio pipes unavailable");this.process=e,Dl.createInterface({input:e.stdout}).on("line",r=>{this.handleLine(r)}),e.stderr.on("data",()=>{}),e.on("close",()=>{this.flushPending(new Error("codex app server stdio closed")),this.process=null})}async close(){this.flushPending(new Error("codex app server stdio closed"));let e=this.process;this.process=null,e&&e.kill()}async notify(e,n){this.write({jsonrpc:"2.0",method:e,params:n??{}})}async request(e,n,r){let o=`rpc-${++this.counter}`,i=new Promise((s,a)=>{let d=setTimeout(()=>{this.pending.delete(o),a(new Error(`codex app server timeout: ${e}`))},Math.max(100,r??this.requestTimeoutMs));d.unref?.(),this.pending.set(o,{resolve:s,reject:a,timer:d})});return this.write({jsonrpc:"2.0",id:o,method:e,params:n??{}}),await i}write(e){if(!this.process?.stdin)throw new Error("codex app server stdio not connected");this.process.stdin.write(`${JSON.stringify(e)}
|
|
5
|
+
`)}async handleLine(e){let n=Wl(e);n&&await Nl(n,{pending:this.pending,onNotification:this.onNotification,onRequest:this.onRequest,respond:r=>this.write(r)})}flushPending(e){for(let[n,r]of this.pending)clearTimeout(r.timer),r.reject(e),this.pending.delete(n)}}});function L(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:null}function z(t,e,n){for(let r of e){let o=t?.[r];if(typeof o!="string")continue;let i=n?.trim===!1?o:o.trim();if(i)return i}}function Ll(t){return t instanceof Error?t.message:String(t)}function Ji(t){return t?t.split(",").map(e=>e.trim()).filter(Boolean):[]}function Ee(t){if(typeof t=="string")return t;if(Array.isArray(t))return t.map(n=>Ee(n)).join("");let e=L(t);if(!e)return"";for(let n of["delta","text","content","message","input","output","parts"]){let r=Ee(e[n]);if(r)return r}for(let n of["item","turn","thread","response","result","data"]){let r=Ee(e[n]);if(r)return r}return""}function _t(t){let e=L(t);if(!e)return{};let n=L(e.thread)??L(e.session),r=L(e.turn)??L(e.run),o=L(e.item),i=L(e.serverRequest);return{threadId:z(e,["threadId","thread_id","conversationId","conversation_id"])??z(n,["id","threadId","thread_id","conversationId"]),runId:z(e,["turnId","turn_id","runId","run_id"])??z(r,["id","turnId","turn_id","runId","run_id"]),requestId:z(e,["requestId","request_id","serverRequestId"])??z(i,["id","requestId","request_id"]),itemId:z(e,["itemId","item_id"])??z(o,["id","itemId","item_id"])}}function fn(t,e,n=0){if(n>6)return;if(Array.isArray(t)){for(let i of t){let s=fn(i,e,n+1);if(s)return s}return}let r=L(t);if(!r)return;let o=z(r,e);if(o)return o;for(let i of Object.values(r)){let s=fn(i,e,n+1);if(s)return s}}function Et(t){return{threadId:_t(t).threadId,cwd:fn(t,["cwd","workdir","directory"])}}function Yi(t){let e=t?.trim();return!!(e&&/[/\\]worktrees[/\\][^/\\]+[/\\][^/\\]+/.test(e))}function Zi(t){let e=t?.trim();if(!e)return;let n=e.split(/[/\\]+/).filter(Boolean),r=n.lastIndexOf("worktrees");if(!(r<0||r+1>=n.length))return n[r+1]}function gn(t){let e=L(t);if(!e)return;let n=L(e.item)??e;return z(n,["id","itemId","item_id","messageId","message_id"])}function Bl(t,e=!1){let n=L(t);if(!n)return"";let r=L(n.item)??n;return z(r,["type"])?.toLowerCase()!=="agentmessage"?"":e?Ee(r):z(r,["text"],{trim:!1})??Ee(r)}function Xi(t,e){let n=t.trim().toLowerCase();return n==="item/agentmessage/delta"?{mode:"delta",text:Ee(e),itemId:gn(e)}:n==="item/completed"?{mode:"snapshot",text:Bl(e),itemId:gn(e)}:{mode:"ignore",text:""}}function es(t){return{itemId:gn(t),delta:Ee(t)}}function ts(t){let e=L(t),n=L(e?.plan),o=(Array.isArray(e?.plan)?e.plan:Array.isArray(n?.steps)?n.steps:[]).map(i=>{let s=L(i),a=z(s,["step","title","text"]);if(!a)return null;let d=z(s,["status"])?.toLowerCase()??"pending";return{step:a,status:d==="inprogress"||d==="in_progress"?"inProgress":d==="completed"?"completed":"pending"}}).filter(Boolean);return{explanation:z(n,["explanation"])??z(e,["explanation"]),steps:o}}function ns(t){let e=L(t);if(!e)return{};let n=L(e.item)??e;return z(n,["type"])?.toLowerCase()!=="plan"?{}:{itemId:gn(n),text:z(n,["text"],{trim:!1})??Ee(n)}}function rs(t,e){let n=t.trim().toLowerCase();if(n==="turn/failed")return"failed";if(n==="turn/cancelled")return"interrupted";let r=L(e)??{},o=L(r.turn)??r,i=z(o,["status"])?.toLowerCase();return i==="failed"?"failed":i==="interrupted"||i==="cancelled"?"interrupted":"completed"}function os(t,e){let n=L(e)??{},r=L(n.turn)??n,o=L(r.error)??L(n.error);if(o)return z(o,["message","text","summary","reason"])}function Fl(t,e){let n=Ll(t).toLowerCase();return n.includes("method not found")||n.includes("unknown method")?!0:n.includes("unknown variant")?e?n.includes(`unknown variant \`${e.toLowerCase()}\``):!0:!1}function Kl(t){return ql.has(t.trim().toLowerCase())}function Ul(t){let e=L(t);return e?!!z(e,["threadId","thread_id"]):!1}async function $t(t){if(t.payloads.length===0)throw new Error(`codex app server request skipped: no payloads for ${t.methods.join(", ")||"<none>"}`);let e;for(let n of t.methods)for(let r of t.payloads){if(Kl(n)&&!Ul(r))throw new Error(`codex app server request missing threadId: ${n}`);try{return await t.client.request(n,r,t.timeoutMs)}catch(o){if(e=o,!Fl(o,n))continue}}throw e instanceof Error?e:new Error(String(e))}function is(t){let e={cwd:t.cwd};return t.model?.trim()&&(e.model=t.model.trim()),t.reasoningEffort?.trim()&&(e.reasoningEffort=t.reasoningEffort.trim()),t.fastMode===!0&&(e.service_tier="fast"),t.approvalPolicy?.trim()&&(e.approvalPolicy=t.approvalPolicy.trim()),t.sandbox?.trim()&&(e.sandbox=t.sandbox.trim()),[e]}function ss(t){let e={threadId:t.threadId,persistExtendedHistory:!1};return t.model?.trim()&&(e.model=t.model.trim()),t.reasoningEffort?.trim()&&(e.reasoningEffort=t.reasoningEffort.trim()),t.fastMode===!0&&(e.service_tier="fast"),t.cwd?.trim()&&(e.cwd=t.cwd.trim()),t.approvalPolicy?.trim()&&(e.approvalPolicy=t.approvalPolicy.trim()),t.sandbox?.trim()&&(e.sandbox=t.sandbox.trim()),[e]}function Vl(t){return[{type:"text",text:t}]}function Gl(t,e,n,r){let o=e?.trim(),i=n?.trim(),s=r?.trim();if(t!=="plan")return o||i||s?{mode:"default",settings:{...o?{model:o}:{},...i?{reasoningEffort:i}:{},developerInstructions:s??null}}:void 0;if(!(!o&&!i&&!s))return{mode:"plan",settings:{...o?{model:o}:{},...i?{reasoningEffort:i}:{},developerInstructions:s??null}}}function as(t){let e={threadId:t.threadId,input:Vl(t.prompt)};t.model?.trim()&&(e.model=t.model.trim()),t.fastMode===!0&&(e.service_tier="fast"),t.approvalPolicy?.trim()&&(e.approvalPolicy=t.approvalPolicy.trim()),t.sandbox?.trim()&&(e.sandbox=t.sandbox.trim());let n=Gl(t.permissionMode??"default",t.model,t.reasoningEffort,t.systemPrompt);return n?[{...e,collaborationMode:n}]:[e]}function ds(t){return[{threadId:t.threadId,turnId:t.turnId}]}function Hl(t){let e=L(t);if(!e)return[];let n=e.options??e.choices??e.availableDecisions??e.decisions;return Array.isArray(n)?n.map(r=>typeof r=="string"?r.trim():z(L(r),["label","title","text","value","name","id"])??"").filter(Boolean):[]}function jl(t){let e=t.trim().toLowerCase();return e.includes("session")?"acceptForSession":/cancel|abort|stop/.test(e)?"cancel":/deny|decline|reject|block|no/.test(e)?"decline":/approve|allow|accept|yes/.test(e)?"accept":t.trim()}function ls(t,e,n){let r=t.trim().toLowerCase(),o=Hl(n),i=fn(n,["question","prompt","message","text","summary","reason"])??void 0,s=r.includes("requestapproval"),a=s?o.map(d=>({kind:"approval",label:d,decision:jl(d),responseDecision:d})):o.map(d=>({kind:"option",label:d,value:d}));return{requestId:e,kind:s?"approval":"question",promptText:i,options:o,actions:a,allowsFreeText:!0}}function us(t){let e=t.trim().toLowerCase();return e.includes("requestuserinput")||e.includes("requestapproval")}function Ao(t,e){let n=t==="bypassPermissions"?"never":e?.trim()||"never";return{approvalPolicy:n,sandbox:n==="never"?"danger-full-access":void 0}}var ql,cs=j(()=>{ql=new Set(["thread/resume","turn/start","turn/steer","turn/interrupt"])});function ps(t){return t instanceof Error?t.message:String(t)}function Zl(t){if(typeof t=="string")return t;if(!t||typeof t!="object")return String(t);let e=t;return typeof e.message?.content=="string"?e.message.content:typeof e.text=="string"?e.text:String(t)}var zl,Fe,Ql,Jl,Yl,hn,ms=j(()=>{Qi();un();cs();zl="1.0",Fe=6e4,Ql="OPENCLAW_CODEX_APP_SERVER_COMMAND",Jl="OPENCLAW_CODEX_APP_SERVER_ARGS",Yl="OPENCLAW_CODEX_APP_SERVER_TIMEOUT_MS";hn=class{constructor(e={}){this.deps=e}deps;name="codex";backendKind="codex-app-server";supportedPermissionModes=["default","plan","bypassPermissions"];capabilities={nativePendingInput:!0,nativePlanArtifacts:!0,worktrees:"native-restore"};launch(e){let n={command:process.env[Ql]?.trim()||"codex",args:Ji(process.env[Jl]),requestTimeoutMs:Number.parseInt(process.env[Yl]??String(Fe),10)||Fe},r=this.deps.createClient?.(n)??new mn(n.command,n.args,n.requestTimeoutMs),o=new Me,i=e.resumeSessionId,s,a=e.backendRef?.worktreePath,d=e.backendRef?.worktreeId,l=e.permissionMode??"default",u,c=0,p="",f=[],g,h=new Map,y=new Set,k=T=>{let _=T?.trim();if(!_)return;let M=e.originalWorkdir?.trim()||e.cwd.trim();e.worktreeStrategy&&e.worktreeStrategy!=="off"&&_!==M&&Yi(_)&&(a=_,d=Zi(_))},R=()=>{i&&o.enqueue(nt({kind:"codex-app-server",conversationId:i,...s?{runId:s}:{},...d?{worktreeId:d}:{},...a?{worktreePath:a}:{}}))};r.setNotificationHandler(async(T,_)=>{let M=T.trim().toLowerCase(),F=_t(_),ue=Et(_);if(F.threadId&&i&&F.threadId!==i)return;if(F.threadId&&(i=F.threadId),F.runId&&(s=F.runId),k(ue.cwd),(F.threadId||F.runId||ue.cwd)&&R(),M==="serverrequest/resolved"){u&&(o.enqueue(_e(u.requestId)),u=void 0);return}if(M==="turn/plan/updated"){let Z=ts(_);p=Z.explanation??p,Z.steps.length>0&&(f=Z.steps);return}if(M==="item/plan/delta"){let Z=es(_);if(Z.itemId&&Z.delta){let ke=h.get(Z.itemId)??"";h.set(Z.itemId,`${ke}${Z.delta}`)}return}if(M==="item/completed"){let Z=ns(_);if(Z.text?.trim()){let ke={explanation:p||void 0,steps:f,markdown:Z.text.trim()};o.enqueue(ln(ke,!0));return}}let B=Xi(M,_);if(B.mode==="delta"&&B.text){B.itemId&&y.add(B.itemId),o.enqueue(Le(B.text));return}B.mode==="snapshot"&&B.text&&(!B.itemId||!y.has(B.itemId))&&o.enqueue(Le(B.text)),(M==="turn/completed"||M==="turn/failed"||M==="turn/cancelled")&&g&&(g.method=T,g.params=_,g.resolve())}),r.setRequestHandler(async(T,_)=>{if(!us(T))return{};let M=_t(_),F=Et(_);if(M.threadId&&i&&M.threadId!==i)return{};M.threadId&&(i=M.threadId),M.runId&&(s=M.runId),k(F.cwd),(M.threadId||M.runId||F.cwd)&&R();let ue=M.requestId??`${i??"codex"}-${Date.now().toString(36)}`,B=ls(T,ue,_),Z=T.trim().toLowerCase(),ke=B.options,Ae=B.actions??[],lo=await new Promise(uo=>{u={requestId:ue,methodLower:Z,state:B,options:ke,actions:Ae,resolveResponse:uo},o.enqueue(Be(B))});return u=void 0,o.enqueue(_e(ue)),lo});let b=async()=>{await r.connect(),await r.request("initialize",{protocolVersion:zl,clientInfo:{name:"openclaw-code-agent",version:"3.1.0"},capabilities:{experimentalApi:!0}},Fe),await r.notify("initialized",{})},A=async()=>{let T=Ao(l,e.codexApprovalPolicy);if(i){let F=await $t({client:r,methods:["thread/resume"],payloads:ss({threadId:i,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:T.approvalPolicy,sandbox:T.sandbox}),timeoutMs:Fe}),ue=Et(F);i=ue.threadId??i,k(ue.cwd),R();return}let _=await $t({client:r,methods:["thread/start","thread/new"],payloads:is({cwd:e.cwd,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,approvalPolicy:T.approvalPolicy,sandbox:T.sandbox}),timeoutMs:Fe}),M=Et(_);if(i=M.threadId,!i)throw new Error("Codex App Server did not return a thread id.");k(M.cwd),R()},N=async T=>{await A(),o.enqueue(rt()),c+=1,p="",f=[],h.clear(),y.clear();let _="",M,F,ue=new Promise(B=>{F=B});g={resolve:F};try{let B=Ao(l,e.codexApprovalPolicy),Z=await $t({client:r,methods:["turn/start"],payloads:as({threadId:i,prompt:T,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,systemPrompt:e.systemPrompt,permissionMode:l,approvalPolicy:B.approvalPolicy,sandbox:B.sandbox}),timeoutMs:Fe}),ke=_t(Z);ke.runId&&(s=ke.runId,R()),await ue,_=g?.method??"turn/failed",M=g?.params;let Ae=rs(_,M);o.enqueue(Ie({success:Ae==="completed",outcome:Ae,duration_ms:0,total_cost_usd:0,num_turns:c,result:os(_,M),session_id:i}))}catch(B){o.enqueue(Ie({success:!1,duration_ms:0,total_cost_usd:0,num_turns:c,result:ps(B),session_id:i??""}))}finally{g=void 0}},S=async T=>u?(u.methodLower.includes("requestapproval")?u.resolveResponse({decision:T.trim()||"decline"}):u.resolveResponse({text:T.trim()}),!0):!1,I=async T=>{let _=u;if(!_)return!1;let M=_.actions[T];if(M?.kind==="approval")return _.resolveResponse({decision:M.responseDecision,...M.proposedExecpolicyAmendment?{proposedExecpolicyAmendment:M.proposedExecpolicyAmendment}:{}}),!0;let F=_.options[T];return F?(_.methodLower.includes("requestapproval")?_.resolveResponse({decision:F}):_.resolveResponse({option:F,index:T}),!0):!1},J=typeof e.prompt=="string"?(async function*(){yield{type:"user",text:e.prompt,session_id:e.resumeSessionId??""}})():e.prompt;return(async()=>{try{await b();for await(let T of J){let _=Zl(T).trim();!_||await S(_)||await N(_)}}catch(T){o.enqueue(Ie({success:!1,duration_ms:0,total_cost_usd:0,num_turns:c,result:ps(T),session_id:i??e.resumeSessionId??""}))}finally{await r.close().catch(()=>{}),o.close()}})(),{messages:o.messages(),async setPermissionMode(T){l=T,o.enqueue(ot(T))},async submitPendingInputOption(T){return I(T)},async submitPendingInputText(T){return S(T)},async interrupt(){!i||!s||await $t({client:r,methods:["turn/interrupt"],payloads:ds({threadId:i,turnId:s}),timeoutMs:Fe}).catch(()=>{})}}}buildUserMessage(e,n){return{type:"user",text:e,session_id:n}}}});import{spawn as Xl}from"node:child_process";import{constants as eu,accessSync as tu}from"node:fs";import{createServer as nu}from"node:net";import{delimiter as ru,dirname as Ro,join as gs,sep as ou}from"node:path";function st(t){return t instanceof Error?t.message:String(t)}function lu(t){try{return tu(t,eu.X_OK),!0}catch{return!1}}function uu(t){return t.includes("/")||ou==="\\"&&t.includes("\\")}function cu(t){let e=(t??"").split(ru).map(r=>r.trim()).filter(Boolean),n=[...e];for(let r of e)r.replaceAll("\\","/").endsWith("/opt/node/bin")&&n.push(gs(Ro(Ro(Ro(r))),"bin"));return n.push("/home/linuxbrew/.linuxbrew/bin","/opt/homebrew/bin","/usr/local/bin","/usr/bin","/bin"),[...new Set(n)]}function pu(t,e=process.env.PATH){if(uu(t))return t;for(let n of cu(e)){let r=gs(n,t);if(lu(r))return r}return t}function Y(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function mu(t){if(typeof t=="string")return t;if(!Y(t))return String(t);if(typeof t.text=="string")return t.text;let e=Y(t.message)?t.message:void 0;return typeof e?.content=="string"?e.content:String(t)}function hs(t){let e=t?.trim();if(!e)return;let n=e.indexOf("/");if(!(n<=0||n===e.length-1))return{providerID:e.slice(0,n),modelID:e.slice(n+1)}}function fu(t){let e=hs(t);return e?{id:e.modelID,providerID:e.providerID}:void 0}function fs(t){let e=t??"default",n=e==="plan"?"deny":e==="bypassPermissions"?"allow":"ask";return du.map(r=>({permission:r,pattern:"*",action:n}))}function Io(){let t=process.env.OPENCODE_SERVER_PASSWORD;if(!t)return{};let e=process.env.OPENCODE_SERVER_USERNAME||"opencode";return{Authorization:`Basic ${Buffer.from(`${e}:${t}`).toString("base64")}`}}async function gu(){return new Promise((t,e)=>{let n=nu();n.once("error",e),n.listen(0,"127.0.0.1",()=>{let r=n.address();n.close(()=>{r&&typeof r=="object"?t(r.port):e(new Error("Could not allocate local OpenCode server port."))})})})}async function Ss(t){await new Promise(e=>setTimeout(e,t))}async function Sn(t,e){if(e.signal?.aborted)throw new Error(e.abortMessage??"Operation was aborted.");return await new Promise((n,r)=>{let o=!1,i=()=>{clearTimeout(d),e.signal?.removeEventListener("abort",a)},s=l=>{o||(o=!0,i(),l())},a=()=>{s(()=>r(new Error(e.abortMessage??"Operation was aborted.")))},d=setTimeout(()=>{s(()=>{e.onTimeout?.(),r(new Error(e.timeoutMessage))})},e.timeoutMs);e.signal?.addEventListener("abort",a,{once:!0}),t.then(l=>s(()=>n(l)),l=>s(()=>r(l)))})}async function it(t){t.exitCode===null&&await new Promise(e=>{let n,r=setTimeout(()=>{t.exitCode===null&&t.kill("SIGKILL"),n=setTimeout(e,1e3)},2e3);t.once("exit",()=>{clearTimeout(r),n&&clearTimeout(n),e()}),t.kill("SIGTERM")})}function hu(t){return t.headers.get("content-type")?.toLowerCase()??""}function To(t){return t.replace(/\s+/g," ").trim().slice(0,300)}function Su(t,e){return t.includes("text/html")||/^\s*<!doctype html\b/i.test(e)||/^\s*<html[\s>]/i.test(e)}function yu(t,e,n,r){let o=n?`content-type ${n}`:"missing content-type",i=To(r),s=Su(n,r)?" (looks like the OpenCode web UI HTML app shell)":"";return`OpenCode ${t} ${e} expected JSON API response but received ${o}${s}${i?`: ${i}`:""}`}function ku(t,e,n){let r=hs(e);return{...r?{model:{providerID:r.providerID,modelID:r.modelID}}:{},...n?.trim()?{system:n.trim()}:{},parts:[{type:"text",text:t}]}}function vu(t,e){if(!Y(t))return!1;if(!(e in t))return!0;let n=t[e];return Y(n)&&n.type==="idle"}function wu(t){return t.type==="session.idle"?!0:t.type!=="session.status"?!1:(t.properties.status??t.properties.type)==="idle"}async function Pu(t){let e=await gu(),n=process.env[iu]?.trim()||"opencode",r=pu(n),o=["serve","--hostname","127.0.0.1","--port",String(e),"--print-logs"],i=t.fetch??fetch,s=Math.min(t.requestTimeoutMs??_o,1e4),a=t.startupTimeoutMs??su,d=Xl(r,o,{cwd:t.cwd,stdio:["ignore","pipe","pipe"]}),l=`http://127.0.0.1:${e}`,u="",c="",p,f=(k,R)=>{let b=k+String(R);return b.length>8e3?b.slice(-8e3):b};d.stdout.on("data",k=>{u=f(u,k)}),d.stderr.on("data",k=>{c=f(c,k)}),d.once("error",k=>{p=k});let g=()=>` Command: ${n===r?r:`${r} (resolved from ${n})`} ${o.join(" ")}. Cwd: ${t.cwd}. Port: ${e}. PATH: ${process.env.PATH??""}.`,h=()=>{let k=[u.trim(),c.trim()].filter(Boolean).join(`
|
|
6
|
+
`).trim();return`${g()}${k?` Output:
|
|
7
|
+
${k}`:""}`},y=()=>{it(d)};if(t.signal?.aborted)throw await it(d),new Error(`OpenCode server startup aborted before readiness.${h()}`);t.signal?.addEventListener("abort",y,{once:!0});try{let k=Date.now();for(;Date.now()-k<a;){if(t.signal?.aborted)throw await it(d),new Error(`OpenCode server startup aborted before readiness.${h()}`);if(p)throw new Error(`OpenCode server failed to start: ${p.message}${h()}`);if(d.exitCode!==null)throw new Error(`OpenCode server exited before readiness.${h()}`);try{if(await Au({baseUrl:l,fetchImpl:i,requestTimeoutMs:s,startupSignal:t.signal,timeoutMessage:`OpenCode GET /api/health timed out after ${s}ms during server readiness.${h()}`,abortMessage:`OpenCode server startup aborted before readiness.${h()}`}))return{baseUrl:l,close:async()=>{await it(d)}}}catch{if(t.signal?.aborted)throw await it(d),new Error(`OpenCode server startup aborted before readiness.${h()}`)}await Ss(100)}throw await it(d),new Error(`Timed out waiting for OpenCode server readiness.${h()}`)}finally{t.signal?.removeEventListener("abort",y)}}async function bu(t){for(let e=1;;e+=1)try{return await Pu(t)}catch(n){if(e>=3||!/EADDRINUSE|address already in use|bind: address already in use/i.test(st(n)))throw n}}async function Au(t){let e=new AbortController,n=()=>e.abort();t.startupSignal?.aborted?e.abort():t.startupSignal?.addEventListener("abort",n,{once:!0});try{return(await Sn(t.fetchImpl(`${t.baseUrl}/api/health`,{headers:Io(),signal:e.signal}),{timeoutMs:t.requestTimeoutMs,timeoutMessage:t.timeoutMessage,signal:t.startupSignal,abortMessage:t.abortMessage,onTimeout:()=>e.abort()})).ok}finally{t.startupSignal?.removeEventListener("abort",n)}}function Ru(t){let e=Y(t)&&Y(t.payload)?t.payload:t;return Y(e)?e.type==="sync"?{type:typeof e.name=="string"?e.name.replace(/\.\d+$/,""):void 0,properties:Y(e.data)?e.data:{}}:{type:typeof e.type=="string"?e.type:void 0,properties:Y(e.properties)?e.properties:e}:{properties:{}}}function Iu(t){return typeof t.sessionID=="string"?t.sessionID:void 0}function xu(t){let e=typeof t.id=="string"?t.id:"opencode-permission",n=typeof t.permission=="string"?t.permission:"permission",r=Array.isArray(t.patterns)?t.patterns.filter(s=>typeof s=="string"):[],o=r.length>0?`OpenCode requests ${n} permission for ${r.join(", ")}.`:`OpenCode requests ${n} permission.`,i=[{kind:"approval",label:"Allow once",decision:"accept",responseDecision:"once"},{kind:"approval",label:"Always allow",decision:"acceptForSession",responseDecision:"always"},{kind:"approval",label:"Reject",decision:"decline",responseDecision:"reject"}];return{requestId:e,kind:"approval",promptText:o,options:i.map(s=>s.label),actions:i,responseMode:"structured"}}function Tu(t){let e=typeof t.id=="string"?t.id:"opencode-question",n=typeof t.question=="string"?t.question:typeof t.prompt=="string"?t.prompt:"OpenCode is asking for input.",r=Array.isArray(t.options)?t.options.map(o=>typeof o=="string"?o:Y(o)&&typeof o.label=="string"?o.label:"").filter(Boolean):[];return{requestId:e,kind:"question",promptText:n,options:r,allowsFreeText:!0}}function Cu(t){return Mo(t).result}function Mo(t){let e=Array.isArray(t)?t:Y(t)&&Array.isArray(t.messages)?t.messages:Y(t)&&Array.isArray(t.items)?t.items:[],n=[];for(let r of e){let o=Y(r)&&Y(r.info)?r.info:r;if(!Y(o)||(typeof o.role=="string"?o.role:o.type)!=="assistant")continue;let s=Array.isArray(o.content)?o.content:[],a=Y(r)&&Array.isArray(r.parts)?r.parts:[];for(let d of[...s,...a])Y(d)&&d.type==="text"&&typeof d.text=="string"&&n.push(d.text)}return{count:n.length,result:n.at(-1)}}var iu,su,_o,au,du,xo,Co,yn,ys=j(()=>{un();iu="OPENCLAW_OPENCODE_COMMAND",su=15e3,_o=6e4,au=15*6e4,du=["edit","bash","task","todowrite","external_directory"];xo=class extends Error{constructor(n,r,o,i){super(`OpenCode ${n} ${r} failed with ${o}${i?`: ${i}`:""}`);this.method=n;this.path=r;this.status=o;this.body=i}method;path;status;body};Co=class{constructor(e,n,r=_o){this.baseUrl=e;this.fetchImpl=n;this.requestTimeoutMs=r}baseUrl;fetchImpl;requestTimeoutMs;async request(e,n,r,o={}){let i=new AbortController,s=!1,a=!1,d=o.timeoutMs??this.requestTimeoutMs,l=`OpenCode ${e} ${n} timed out after ${d}ms.`,u=`OpenCode ${e} ${n} was aborted.`,c=()=>{s=!0,i.abort()};o.signal?.aborted?(s=!0,i.abort()):o.signal?.addEventListener("abort",c,{once:!0});try{let p=await Sn(this.fetchImpl(`${this.baseUrl}${n}`,{method:e,headers:{...Io(),...r===void 0?{}:{"content-type":"application/json"}},body:r===void 0?void 0:JSON.stringify(r),signal:i.signal}),{timeoutMs:d,timeoutMessage:l,signal:o.signal,abortMessage:u,onTimeout:()=>{a=!0,i.abort()}});if(!p.ok){let h=await Sn(p.text(),{timeoutMs:d,timeoutMessage:l,signal:o.signal,abortMessage:u,onTimeout:()=>{a=!0,i.abort()}}).catch(()=>"");throw new xo(e,n,p.status,To(h))}if(p.status===204)return;let f=await Sn(p.text(),{timeoutMs:d,timeoutMessage:l,signal:o.signal,abortMessage:u,onTimeout:()=>{a=!0,i.abort()}});if(!f)return;let g=hu(p);if(!g.includes("application/json")&&!g.includes("+json"))throw new Error(yu(e,n,g,f));try{return JSON.parse(f)}catch(h){let y=To(f);throw new Error(`OpenCode ${e} ${n} returned invalid JSON: ${st(h)}${y?`: ${y}`:""}`)}}catch(p){if(i.signal.aborted){if(a)throw new Error(`OpenCode ${e} ${n} timed out after ${d}ms.`);if(s)throw new Error(`OpenCode ${e} ${n} was aborted.`)}throw p}finally{o.signal?.removeEventListener("abort",c)}}async streamEvents(e,n){let r=await this.fetchImpl(`${this.baseUrl}/event`,{headers:Io(),signal:n});if(!r.ok)throw new Error(`OpenCode event stream failed with ${r.status}`);if(!r.body)return;let o=r.body.getReader(),i=new TextDecoder,s="",a=async l=>{let u=l.split(/\r?\n/).filter(c=>c.startsWith("data:")).map(c=>c.slice(5).trimStart()).join(`
|
|
8
|
+
`).trim();!u||u==="[DONE]"||await e(JSON.parse(u))};for(;;){let{done:l,value:u}=await o.read();if(l)break;s+=i.decode(u,{stream:!0});let c=/\r?\n\r?\n/.exec(s);for(;c;){let p=s.slice(0,c.index);s=s.slice(c.index+c[0].length),await a(p),c=/\r?\n\r?\n/.exec(s)}}let d=s.trim();d&&await a(d)}};yn=class{constructor(e={}){this.deps=e}deps;name="opencode";backendKind="opencode-server";supportedPermissionModes=["default","plan","bypassPermissions"];capabilities={nativePendingInput:!0,nativePlanArtifacts:!1,worktrees:"plugin-managed"};launch(e){let n=new Me,r=this.deps.fetch??fetch,o,i,s,a=e.resumeSessionId,d=0,l=e.permissionMode??"default",u,c=!e.resumeSessionId,p=!1,f=!1,g=new AbortController,h,y=!1,k=!1,R=!1,b=!1,A=!1,N=!1,S,I=new Set,J=x=>b?!1:(b=!0,n.enqueue(Ie(x)),!0),T=(x,P,V)=>J({success:x,outcome:P,duration_ms:0,total_cost_usd:0,num_turns:d,result:V,session_id:a??""}),_=()=>{a&&S!==a&&(S=a,n.enqueue(nt({kind:"opencode-server",conversationId:a})))},M=x=>{x&&I.has(x)||(x&&I.add(x),n.enqueue(_e(x)),x&&u?.requestId===x&&(u=void 0))},F=async()=>{if(i)return i;s??=(async()=>{let x=await(this.deps.createServer??bu)({cwd:e.cwd,signal:e.abortController?.signal,fetch:r,requestTimeoutMs:this.deps.requestTimeoutMs,startupTimeoutMs:this.deps.startupTimeoutMs});if(A||e.abortController?.signal.aborted)throw await x.close().catch(()=>{}),new Error("OpenCode startup was interrupted before session creation.");return o=x,i=new Co(x.baseUrl,r,this.deps.requestTimeoutMs),i})();try{return await s}catch(x){throw s=void 0,x}},ue=async(x,P)=>{!i||!a||await i.request("POST",`/permission/${encodeURIComponent(x)}/reply`,{reply:P})},B=async(x,P)=>{!i||!a||await i.request("POST",`/question/${encodeURIComponent(x)}/reply`,{answers:[[P]]})},Z=async x=>{let P=Ru(x),V=Iu(P.properties);if(!(V&&V!==a)){if((P.type==="session.next.text.delta"||P.type==="message.part.delta")&&P.properties.field!=="reasoning"&&typeof P.properties.delta=="string"){n.enqueue(Le(P.properties.delta));return}if(P.type==="session.next.tool.called"||P.type==="message.part.updated"){let $=Y(P.properties.part)?P.properties.part:void 0;if(P.type==="message.part.updated"&&$?.type!=="tool"){n.enqueue({type:"activity"});return}let oe=typeof P.properties.tool=="string"?P.properties.tool:typeof $?.tool=="string"?$.tool:"tool";n.enqueue(dn(oe,P.properties.input));return}if(P.type==="session.next.step.failed"||P.type==="session.error"){let $=Y(P.properties.error)&&typeof P.properties.error.message=="string"?P.properties.error.message:`${P.type} failed`;k&&!R&&(h?.abort(),T(!1,"failed",$));return}if(P.type==="permission.asked"){if(l==="bypassPermissions"){let oe=typeof P.properties.id=="string"?P.properties.id:void 0;oe&&(await ue(oe,"once").catch(()=>{}),M(oe));return}let $=xu(P.properties);u={requestId:$.requestId,kind:"approval",options:$.options,actions:$.actions??[]},n.enqueue(Be($));return}if(P.type==="permission.replied"){let $=typeof P.properties.requestID=="string"?P.properties.requestID:void 0;M($);return}if(P.type==="question.asked"){let $=Tu(P.properties);u={requestId:$.requestId,kind:"question",options:$.options,actions:[]},n.enqueue(Be($));return}if(P.type==="question.replied"||P.type==="question.rejected"){let $=typeof P.properties.requestID=="string"?P.properties.requestID:void 0;M($);return}(P.type?.startsWith("session.next.")||P.type?.startsWith("message.")||P.type==="session.status"||P.type==="session.idle")&&(wu(P)&&(N=!0),n.enqueue({type:"activity"}))}},ke=()=>{y||!i||(y=!0,i.streamEvents(Z,g.signal).catch(x=>{!g.signal.aborted&&k&&!R&&(h?.abort(),T(!1,"failed",st(x)))}).finally(()=>{y=!1}))},Ae=async(x,P)=>await x.request("GET",`/session/${encodeURIComponent(P)}/message`),lo=async(x,P,V,$,oe)=>{await x.request("POST",`/session/${encodeURIComponent(P)}/prompt_async`,ku(V,e.model,$),{signal:oe})},uo=async(x,P,V,$)=>{let oe=Date.now(),rn=!1,Ye=V,Li,co=0,Pt,Bi=this.deps.turnTimeoutMs??au;for(;;){if($.aborted)throw new Error("wait aborted");let dl=await Ae(x,P).catch(()=>{}),Te=Mo(dl),Fi=Te.count>V&&!!Te.result;Fi&&Te.count===Ye&&Te.result===Li?co+=1:(co=Fi?1:0,Ye=Te.count,Li=Te.result);let po=!1;try{let bt=await x.request("GET","/session/status",void 0,{signal:$,timeoutMs:Math.min(this.deps.requestTimeoutMs??_o,1e4)});po=vu(bt,P),Pt=void 0,po||(rn=!0)}catch(bt){if($.aborted)throw new Error("wait aborted");Pt=st(bt)}if(po&&(rn||Te.count>V)||N&&Te.count>V||co>=2&&Pt)return;if(Date.now()-oe>Bi){let bt=Pt?` Last status error: ${Pt}`:"";throw new Error(`Timed out waiting for OpenCode session ${P} to become idle after ${Bi}ms.${bt}`)}await Ss(250)}},il=async()=>{let x=await F();if(a){if(e.forkSession&&!p){let $=await x.request("POST",`/session/${encodeURIComponent(a)}/fork`,{});if(!$.id)throw new Error("OpenCode fork did not return a session id.");a=$.id,p=!0,c=!0}else c||(await Ae(x,a),c=!0);return _(),ke(),a}let P=fu(e.model),V=await x.request("POST","/session",{...P?{model:P}:{},metadata:{client:"openclaw-code-agent"},permission:fs(l)});if(!V.id)throw new Error("OpenCode did not return a session id.");return a=V.id,c=!0,_(),ke(),a},Ni=async(x,P,V=x?"completed":"failed")=>{let $=P;if(x&&i&&a){let oe=await Ae(i,a).catch(()=>{});$=$??Cu(oe)}T(x,V,$)},sl=async x=>{k=!0,R=!1,b=!1,N=!1;try{let P=await F();if(A)return;let V=await il();if(A)return;n.enqueue(rt()),d+=1;let $=f?void 0:e.systemPrompt,oe=await Ae(P,V).catch(()=>{}),rn=Mo(oe).count,Ye=new AbortController;h=Ye,await lo(P,V,x,$,Ye.signal),f=!0,await uo(P,V,rn,Ye.signal),h=void 0,R=!0,await Ni(!0)}catch(P){h=void 0,await Ni(!1,st(P))}finally{k=!1,R=!1}},al=typeof e.prompt=="string"?(async function*(){yield{type:"user",text:e.prompt,session_id:e.resumeSessionId??""}})():e.prompt;return(async()=>{try{for await(let x of al){if(A)break;let P=mu(x).trim();if(P){if(u?.kind==="question"){await B(u.requestId,P),M(u.requestId);continue}if(await sl(P),A)break}}}catch(x){A||(k||(b=!1),T(!1,"failed",st(x)))}finally{g.abort(),await o?.close().catch(()=>{}),n.close()}})(),{messages:n.messages(),async setPermissionMode(x){a&&await(await F()).request("PATCH",`/session/${encodeURIComponent(a)}`,{permission:fs(x)}),l=x,n.enqueue(ot(x))},async submitPendingInputOption(x){let P=u;if(!P)return!1;if(P.kind==="approval"){let $=P.actions[x],oe=$?.kind==="approval"?$.responseDecision:void 0;return oe?(await ue(P.requestId,oe),M(P.requestId),!0):!1}let V=P.options[x];return V?(await B(P.requestId,V),M(P.requestId),!0):!1},async submitPendingInputText(x){let P=u;return!P||P.kind!=="question"?!1:(await B(P.requestId,x),M(P.requestId),!0)},async interrupt(){if(A=!0,g.abort(),h?.abort(),k||(b=!1),T(!1,"interrupted"),!i){await o?.close().catch(()=>{});return}if(!a)return;await i.request("POST",`/session/${encodeURIComponent(a)}/abort`).catch(()=>{})}}}buildUserMessage(e,n){return{type:"user",text:e,session_id:n}}}});function $o(t){Eo.set(t.name,t)}function Dt(t){let e=Eo.get(t);if(!e)throw new Error(`Unknown agent harness: "${t}". Available: ${[...Eo.keys()].join(", ")}`);return e}function ks(){return Dt(se())}var Eo,Do=j(()=>{zi();ms();ys();te();Eo=new Map;$o(new cn);$o(new hn);$o(new yn)});function C(t){return t.backendRef?.conversationId??t.harnessSessionId}function W(t){return t.id??t.sessionId??t.name??C(t)??t.harnessSessionId}function Mu(t){return t.harnessSessionId}function ae(t){let e=[W(t),C(t),Mu(t)].filter(n=>!!n);return[...new Set(e)]}function Oo(t){return t.harnessName??t.persistedHarness??se()}function Ot(t){if(t.backendRef?.kind==="codex-app-server")return"native-restore";try{return Dt(Oo(t)).capabilities.worktrees}catch{return"plugin-managed"}}function Wo(t){return t==="native-execution"}function kn(t){return t==="native-restore"}function _u(t){return!!(t.backendRef?.worktreePath||t.backendRef?.worktreeId)}function ne(t){let e=Ot(t);return(Wo(e)||kn(e))&&_u(t)}var Q=j(()=>{te();Do()});import{execFileSync as ee}from"child_process";import*as Nn from"fs";import{tmpdir as rc}from"os";import{dirname as qs,join as oc}from"path";function ic(t){try{return ee("git",["rev-parse","--show-toplevel"],{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function Ln(t){if(process.env.OPENCLAW_WORKTREE_DIR)return process.env.OPENCLAW_WORKTREE_DIR;if(E.worktreeDir)return E.worktreeDir;if(t){let e=ic(t);if(e)return oc(e,".worktrees")}return rc()}function Ks(t){return t.replace(/[^a-zA-Z0-9._-]/g,"-").replace(/\.{2,}/g,"-").replace(/^[-.]|[-.]$/g,"").slice(0,100)||"session"}function Bn(t){try{let e=ee("git",["-C",t,"rev-parse","--git-common-dir"],{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();return e&&e.endsWith("/.git")?qs(e):void 0}catch{return}}function sc(){if(On!==void 0)return On;try{return ee("git",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),On=!0,!0}catch{return On=!1,!1}}function $e(){if(Wn!==void 0)return Wn;try{return ee("gh",["--version"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Wn=!0,!0}catch{return Wn=!1,!1}}function qo(t){if(!sc())return!1;try{return ee("git",["rev-parse","--git-dir"],{cwd:t,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function Us(t){try{let e=dc(t);if(!e)return`${Ln(t)}`,!0;let n=Nn.statfsSync(e),r=n.bavail*n.bsize;return lc(r)}catch(e){return`${e instanceof Error?e.message:String(e)}`,!0}}function Ft(t,e){try{return ee("git",["-C",t,"rev-parse","--verify",e],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function ac(t){let e=t;for(;;){if(Nn.existsSync(e))return e;let n=qs(e);if(n===e)return;e=n}}function dc(t){return ac(Ln(t))}function lc(t){return t>=104857600}function be(t){let e=process.env.OPENCLAW_WORKTREE_BASE_BRANCH?.trim();if(e)return e;try{let r=ee("git",["-C",t,"rev-parse","--abbrev-ref","origin/HEAD"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().replace(/^origin\//,"");if(r)return r}catch{}try{return ee("git",["-C",t,"rev-parse","--verify","main"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),"main"}catch{}try{return ee("git",["-C",t,"rev-parse","--verify","master"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),"master"}catch{return"main"}}function ut(t){try{let n=ee("git",["-C",t,"rev-parse","--abbrev-ref","HEAD"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();if(n==="HEAD"){`${t}`;return}return n||void 0}catch{return}}function qt(t,e,n){try{let r=ee("git",["-C",t,"rev-list","--count",`${n}..${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});return parseInt(r.trim(),10)>0}catch{return!1}}function Vs(t,e,n){try{let r=ee("git",["-C",t,"rev-list","--left-right","--count",`${e}...${n}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),[o,i]=r.split(/\s+/);return{ahead:parseInt(o??"0",10)||0,behind:parseInt(i??"0",10)||0}}catch{return}}function ct(t,e,n){try{return ee("git",["-C",t,"merge-base","--is-ancestor",e,n],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}function Gs(t,e,n){try{let r=ee("git",["-C",t,"merge-tree","--write-tree",n,e],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),o=ee("git",["-C",t,"rev-parse",`${n}^{tree}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();return!!r&&r===o}catch{return!1}}function ge(t,e){try{return ee("git",["-C",t,"branch","-D",e],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch(n){return`${e}${n instanceof Error?n.message:String(n)}`,!1}}function Hs(t,e){if(e)return e;let n;try{n=ee("git",["-C",t,"remote","get-url","origin"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{}try{let r=ee("git",["-C",t,"remote","get-url","upstream"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();if(r&&r!==n){let o=r.match(/[:/]([^/]+\/[^/]+?)(?:\.git)?$/);if(o)return o[1]}}catch{}}var On,Wn,Kt=j(()=>{te()});import{execFileSync as pt}from"child_process";import{appendFileSync as uc,existsSync as Qs,mkdirSync as js,readFileSync as cc,rmSync as Ko}from"fs";import{relative as pc,sep as zs}from"path";function mc(t,e){return!!(t&&typeof t=="object"&&"code"in t&&t.code===e)}function fc(t){try{return pt("git",["-C",t,"rev-parse","--show-toplevel"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{return}}function gc(t,e){let n=fc(t);if(!n)return;let r=pc(n,e);if(!r||r.startsWith("..")||r.includes(`..${zs}`))return;let o=`${n}/.git/info/exclude`,i=`${r.split(zs).join("/").replace(/\/$/,"")}/`;try{let s=Qs(o)?cc(o,"utf-8"):"";s.split(/\r?\n/).map(d=>d.trim()).some(d=>d===i||d===`/${i}`)||uc(o,`${s.endsWith(`
|
|
9
9
|
`)||s.length===0?"":`
|
|
10
|
-
`}${
|
|
11
|
-
`,"utf-8")}catch(s){`${
|
|
12
|
-
`).map(n=>n.trim()).filter(Boolean):[]}catch{return[]}}function
|
|
13
|
-
`).map(
|
|
14
|
-
`).filter(Boolean).map(
|
|
15
|
-
`).some(n=>n.length>0&&!n.startsWith("??")&&!n.startsWith("!!"))}catch{return!1}}function
|
|
16
|
-
`)}}F("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),F("git",["-C",t,"merge","--ff-only",e],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});let u=!1;if(o)try{F("git",["-C",t,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch{u=!0}return{success:!0,fastForward:!0,stashed:o||void 0,stashRef:s,stashPopConflict:u||void 0}}catch(d){try{F("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch{}return a(t),{success:!1,error:d instanceof Error?d.message:String(d),stashed:o||void 0,stashRef:s}}}var Ws=H(()=>{});import{execFileSync as Fn}from"child_process";function Ns(t,e,n,r,i,o){if(!Ce())return{success:!1,error:"GitHub CLI (gh) is not available"};try{let s;if(o)try{let c=Fn("git",["-C",t,"remote","get-url","origin"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().match(/[:/]([^/]+)\/[^/]+(?:\.git)?$/);c&&(s=c[1])}catch{}let a=["pr","create","--base",n];return o&&a.push("--repo",o),s?a.push("--head",`${s}:${e}`):a.push("--head",e),r&&i?a.push("--title",r,"--body",i):a.push("--fill-verbose"),{success:!0,prUrl:Fn("gh",a,{cwd:t,timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()}}catch(s){return{success:!1,error:s instanceof Error?s.message:String(s)}}}function Lt(t,e,n){if(!Ce())return{exists:!1,state:"none"};try{let r=["pr","list","--head",e,"--state","all","--json","url,number,title,state","--jq",".[0]"];n&&r.push("--repo",n);let o=Fn("gh",r,{cwd:t,timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();if(!o)return{exists:!1,state:"none"};let s=JSON.parse(o),a=s.state.toLowerCase();return{exists:!0,state:a==="open"?"open":a==="merged"?"merged":a==="closed"?"closed":"none",url:s.url,number:s.number,title:s.title}}catch(r){return`${e}${r instanceof Error?r.message:String(r)}`,{exists:!1,state:"none"}}}function Ls(t,e,n,r){if(!Ce())return!1;try{let i=["pr","comment",String(e),"--body",n];return r&&i.push("--repo",r),Fn("gh",i,{cwd:t,timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch(i){return`${e}${i instanceof Error?i.message:String(i)}`,!1}}function Be(t){if(t.kind==="merge"){let e=t.filesChanged!==void 0?` (${t.filesChanged} files, +${t.insertions??0}/-${t.deletions??0})`:"";return`✅ Merged: ${t.branch} → ${t.base??"main"}${e}`}return t.kind==="pr-updated"?`✅ PR updated: ${t.prUrl??""}`:t.targetRepo?`✅ PR opened against ${t.targetRepo}: ${t.prUrl??""}`:`✅ PR opened: ${t.prUrl??""}`}var Di=H(()=>{Nt()});import{existsSync as Oi}from"fs";function Bs(){return new Date().toISOString()}function ic(t){return t.worktreeLifecycle??{state:t.worktreePath||t.worktreeBranch?"provisioned":"none",updatedAt:Bs(),baseBranch:t.worktreeBaseBranch,targetRepo:t.worktreePrTargetRepo,pushRemote:t.worktreePushRemote}}function oc(t){return t.worktreeLifecycle?.baseBranch??t.worktreeBaseBranch??(Oi(t.workdir)?ke(t.workdir):void 0)}function Fe(t,e={}){let n=ic(t),r=Bs(),i=new Set,o=Oi(t.workdir),s=!!(t.worktreePath&&Oi(t.worktreePath)),a=t.worktreeBranch,d=oc(t),l=!1,u=!1,c=!1,p=!1,f,g,h=t.worktreePrUrl?"open":"none",y=t.worktreePrUrl,S=t.worktreePrNumber;if(o||i.add("repo_missing"),a||i.add("branch_missing"),!s&&t.worktreePath&&i.add("worktree_missing"),e.activeSession&&i.add("active_session"),n.state==="pending_decision"&&i.add("pending_decision"),n.state==="merge_conflict_resolving"&&i.add("merge_conflict_resolving"),o&&a&&(l=Ot(t.workdir,a),l||i.add("branch_missing")),s&&t.worktreePath&&(u=at(t.worktreePath),u&&i.add("dirty_worktree_entries")),o&&l&&d){let ge=Ts(t.workdir,a,d);f=ge?.ahead,g=ge?.behind,c=Cs(t.workdir,a,d),c?i.add("topology_merged"):(p=Ms(t.workdir,a,d),p&&i.add("merge_noop_content_already_on_base"),!p&&(f??0)>0&&i.add("unique_content"))}else d||i.add("base_branch_missing");if(e.includePrSync&&o&&a){let ge=Lt(t.workdir,a,t.worktreePrTargetRepo??n.targetRepo);h=ge.state,y=ge.url??y,S=ge.number??S}h==="open"&&i.add("pr_open"),h==="merged"&&!c&&!p&&i.add("pr_merged_not_reflected_locally");let P=n.state;c?P="merged":p?P="released":!l&&n.state==="pending_decision"&&(P="cleanup_failed");let b=P==="merged"||P==="released",R=e.activeSession||u||!b&&n.state==="pending_decision"||n.state==="merge_conflict_resolving"||n.state==="pr_open"||h==="open"||i.has("pr_merged_not_reflected_locally"),N=!R&&(P==="merged"||P==="released"||n.state==="dismissed"||n.state==="no_change"),fe={checkedAt:r,repoExists:o,branchExists:l,worktreeExists:s,activeSession:e.activeSession===!0,dirtyTracked:u,topologyMerged:c,releaseNoopMerge:p,branchAheadCount:f,baseAheadCount:g,prState:h,prUrl:y,prNumber:S,reasons:[...i]};return{lifecycle:n,evidence:fe,derivedState:P,cleanupSafe:N,preserve:R,reasons:[...i]}}var Bt=H(()=>{Nt();Di();Ei()});var ue=H(()=>{Nt();Ei();Ws();Di();Bt()});function dt(t,e){let n=t.resolve(e),r=t.getPersistedSession(e),i=n?D(n):r?D(r):void 0;return{activeSession:n,persistedSession:r,persistedRef:i,sessionName:n?.name??r?.name??e,prompt:n?.prompt??r?.prompt,worktreePath:n?.worktreePath??r?.worktreePath,originalWorkdir:n?.originalWorkdir??r?.workdir,branchName:n?.worktreeBranch??r?.worktreeBranch,notificationTarget:n??(r?{id:i??e,name:r.name,harnessSessionId:r.harnessSessionId,backendRef:r.backendRef,route:r.route,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey,goalTaskId:r.goalTaskId}:void 0)}}function qt(t){return[...t.persistedSession?re(t.persistedSession):[],...t.activeSession?re(t.activeSession):[]].filter((e,n,r)=>r.indexOf(e)===n)}function Vc(t,e){let n=[e.id,e.backendConversationId,e.harnessSessionId,e.name],r,i;for(let o of n)if(o&&(r??=t.resolve(o),i??=t.getPersistedSession(o),r&&i))break;return{activeSession:r,persistedSession:i}}function Qn(t,e,n={}){let{activeSession:r,persistedSession:i}=Vc(t,e),o=Fe({workdir:e.workdir,worktreePath:e.worktreePath,worktreeBranch:e.worktreeBranch,worktreeBaseBranch:n.baseBranch??i?.worktreeBaseBranch,worktreePrTargetRepo:i?.worktreePrTargetRepo,worktreePushRemote:i?.worktreePushRemote,worktreePrUrl:i?.worktreePrUrl,worktreePrNumber:i?.worktreePrNumber,worktreeLifecycle:i?.worktreeLifecycle},{activeSession:!!(r&&(r.status==="starting"||r.status==="running")),includePrSync:!!(i?.worktreeLifecycle?.state==="pr_open"||i?.worktreePrUrl)});return{activeSession:r,persistedSession:i,resolvedLifecycle:o}}function Yn(t){let e=t.list("all").filter(i=>i.worktreePath),n=t.listPersistedSessions().filter(i=>i.worktreePath),r=new Map;for(let i of n){if(!i.worktreePath)continue;let o=x(i),s=i.sessionId??o??i.harnessSessionId;s&&r.set(s,{id:i.sessionId??o??i.harnessSessionId,name:i.name,worktreePath:i.worktreePath,worktreeBranch:i.worktreeBranch,worktreeStrategy:i.worktreeStrategy,workdir:i.workdir,worktreeMerged:i.worktreeMerged,worktreeMergedAt:i.worktreeMergedAt,worktreePrUrl:i.worktreePrUrl,backendConversationId:o,harnessSessionId:i.harnessSessionId})}for(let i of e)i.worktreePath&&r.set(i.id,{id:i.id,name:i.name,worktreePath:i.worktreePath,worktreeBranch:i.worktreeBranch,worktreeStrategy:i.worktreeStrategy,workdir:i.originalWorkdir??i.workdir,worktreeMerged:void 0,worktreeMergedAt:void 0,worktreePrUrl:void 0,backendConversationId:x(i),harnessSessionId:i.harnessSessionId});return Array.from(r.values())}function Zn(t,e){return t.id===e||t.name===e||t.backendConversationId===e||t.harnessSessionId===e}function Ke(t){switch(t){case"none":return"none";case"provisioned":return"active";case"pending_decision":return"needs decision";case"merge_conflict_resolving":return"conflict resolving";case"pr_open":return"pr open";case"merged":return"merged";case"released":return"released";case"dismissed":return"dismissed";case"no_change":return"no change";case"cleanup_failed":return"cleanup failed";default:return t}}function Xn(t){switch(t){case"active_session":return"active session";case"pending_decision":return"pending decision";case"merge_conflict_resolving":return"conflict resolving";case"dirty_tracked_changes":case"dirty_worktree_entries":return"dirty worktree";case"unique_content":return"still has unique content";case"topology_merged":return"merged by ancestry";case"merge_noop_content_already_on_base":return"content already on base";case"pr_open":return"PR open";case"pr_merged_not_reflected_locally":return"merged PR not reflected locally";case"repo_missing":return"repo missing";case"branch_missing":return"branch missing";case"worktree_missing":return"worktree missing";case"base_branch_missing":return"base branch missing";default:return t.replaceAll("_"," ")}}var Kt=H(()=>{V();Bt()});function nr(t,e){return{...e,baseBranch:e.baseBranch??t.worktreeBaseBranch,targetRepo:e.targetRepo??t.worktreePrTargetRepo,pushRemote:e.pushRemote??t.worktreePushRemote}}function rr(t,e={}){let n=e.updatedAt??new Date().toISOString(),r={pendingWorktreeDecisionSince:e.pendingSince??n,lastWorktreeReminderAt:void 0,lifecycle:"awaiting_worktree_decision",worktreeState:"pending_decision",worktreeLifecycle:nr(t,{state:"pending_decision",updatedAt:n,notes:e.notes})};return e.clearResolverSessionId&&(r.autoMergeResolverSessionId=void 0),r}function ra(t,e,n,r={}){let i=r.updatedAt??new Date().toISOString();return{autoMergeConflictResolutionAttemptCount:n,autoMergeResolverSessionId:e,pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,lifecycle:"terminal",worktreeState:"merge_conflict_resolving",worktreeLifecycle:nr(t,{state:"merge_conflict_resolving",updatedAt:i,notes:r.notes})}}function ir(t,e={}){let n=e.updatedAt??new Date().toISOString(),r=e.resolvedAt??n,i={worktreeMerged:!0,worktreeMergedAt:e.mergedAt??r,lifecycle:"terminal",worktreeState:"merged",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeLifecycle:nr(t,{state:"merged",updatedAt:n,resolvedAt:r,resolutionSource:e.resolutionSource??"agent_merge"})};return e.clearResolverSessionId&&(i.autoMergeResolverSessionId=void 0),i}function ia(t,e){let n=e.updatedAt??new Date().toISOString(),r={worktreePrUrl:e.prUrl,lifecycle:"terminal",worktreeState:"pr_open",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,worktreeLifecycle:nr(t,{state:"pr_open",updatedAt:n,resolutionSource:"agent_pr",baseBranch:e.baseBranch,targetRepo:e.targetRepo})};return e.prNumber!==void 0&&(r.worktreePrNumber=e.prNumber),e.disposition!==void 0&&(r.worktreeDisposition=e.disposition),r}var or=H(()=>{});var ma={};Xd(ma,{buildPrCompletionWakeOutcomeKey:()=>Vi,buildPrMetadata:()=>ca,buildPrOutcomeDetailLines:()=>Ui,formatPrBody:()=>pa,makeAgentPrTool:()=>Vt});import{existsSync as jc}from"fs";function zc(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function Ui(t){return[t.action==="opened"?`Opened PR for branch ${t.branchName} into ${t.baseBranch}.`:`Updated PR for branch ${t.branchName} into ${t.baseBranch}.`,...t.prUrl?[`PR URL: ${t.prUrl}.`]:[],...t.prNumber?[`PR number: #${t.prNumber}.`]:[],...t.targetRepo?[`Target repository: ${t.targetRepo}.`]:[],...t.commits!==void 0?[`Pushed ${t.commits} new commits (+${t.insertions??0}/-${t.deletions??0}).`]:[]]}function Vi(t){let e=t.prNumber!==void 0?`#${t.prNumber}`:t.prUrl??"unknown-pr",n=t.diffSummary?.commitMessages.map(i=>i.hash.trim()).filter(Boolean).join(","),r=t.action==="updated"?n||[`commits:${t.diffSummary?.commits??"unknown"}`,`insertions:${t.diffSummary?.insertions??"unknown"}`,`deletions:${t.diffSummary?.deletions??"unknown"}`].join(","):"created";return["worktree-pr",t.action,t.targetRepo??"default-repo",e,t.branchName,r].join(":")}function la(t,e={preserveBlankLines:!0}){return t?.replace(/\r\n/g,`
|
|
10
|
+
`}${i}
|
|
11
|
+
`,"utf-8")}catch(s){`${i}${o}${s instanceof Error?s.message:String(s)}`}}function Uo(t,e,n={}){let r=Ks(e),o=Ln(t);gc(t,o),js(o,{recursive:!0});let i=n.allowExistingBranch===!0,s,a,d=10,l=!1;for(let c=0;c<d;c++){let p=c===0?"":`-${Math.random().toString(16).slice(2,6)}`,f=`${o}/openclaw-worktree-${r}${p}`,g=`agent/${r}${p}`;if(!i&&Ft(t,g))continue;let h=!1;do{h=!1;try{js(f,{recursive:!1}),s=f,a=g;break}catch(y){if(mc(y,"EEXIST")){if(i&&c===0&&!l)try{Ko(f,{recursive:!0,force:!0}),l=!0,h=!0}catch(k){throw new Error(`Failed to recreate existing worktree branch ${g}: could not clear blocked path ${f}: ${k instanceof Error?k.message:String(k)}`)}else if(i&&c===0)throw new Error(`Failed to recreate existing worktree branch ${g}: path ${f} remains blocked after one cleanup attempt`);continue}throw y}}while(h);if(s&&a)break}if(!s||!a)throw new Error(`Failed to create unique worktree directory and branch after ${d} attempts`);let u=Ft(t,a);try{u?pt("git",["-C",t,"worktree","add",s,a],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}):pt("git",["-C",t,"worktree","add","-b",a,s],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(c){try{Ko(s,{recursive:!0,force:!0})}catch{}throw c}return s}function Ve(t){if(!Qs(t))return[];try{let e=pt("git",["-C",t,"status","--porcelain","--untracked-files=all"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();return e?e.split(`
|
|
12
|
+
`).map(n=>n.trim()).filter(Boolean):[]}catch{return[]}}function mt(t){return Ve(t).length>0}function de(t,e,n={}){let r=n.destructive===!0,o=Ve(e);if(o.length>0&&!r)return`${e}${o[0]}`,!1;try{return pt("git",["-C",t,"worktree","remove",...r?["--force"]:[],e],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch(i){if(`${e}${i instanceof Error?i.message:String(i)}`,!r)return!1;try{return Ko(e,{recursive:!0,force:!0}),`${e}`,!0}catch(s){return console.error(`[worktree] Both git worktree remove and rmSync failed for ${e}: ${s instanceof Error?s.message:String(s)}`),!1}}}function Fn(t){try{pt("git",["-C",t,"worktree","prune"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch{}}var Vo=j(()=>{Kt()});import{execFileSync as K}from"child_process";import{existsSync as hc}from"fs";function xe(t,e,n){try{let r=K("git",["-C",t,"rev-list","--count",`${n}..${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),o=parseInt(r.trim(),10),s=K("git",["-C",t,"diff","--shortstat",`${n}...${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim(),a=0,d=0,l=0,u=s.match(/(\d+)\s+files?\s+changed/);u&&(a=parseInt(u[1],10));let c=s.match(/(\d+)\s+insertions?\(/);c&&(d=parseInt(c[1],10));let p=s.match(/(\d+)\s+deletions?\(/);p&&(l=parseInt(p[1],10));let g=K("git",["-C",t,"diff","--name-only","--diff-filter=ACMR",`${n}...${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().split(`
|
|
13
|
+
`).map(k=>k.trim()).filter(Boolean),y=K("git",["-C",t,"log",`${n}..${e}`,"--format=%h|%s|%an","-n","5"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().split(`
|
|
14
|
+
`).filter(Boolean).map(k=>{let[R,b,A]=k.split("|");return{hash:R||"",message:b||"",author:A||""}});return{commits:o,filesChanged:a,insertions:d,deletions:l,changedFiles:g,commitMessages:y}}catch(r){`${r instanceof Error?r.message:String(r)}`;return}}function qn(t,e,n="origin"){try{return K("git",["-C",t,"push",n,e],{timeout:6e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch(r){return`${e}${r instanceof Error?r.message:String(r)}`,!1}}function Js(t){try{return K("git",["-C",t,"status","--porcelain"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).split(`
|
|
15
|
+
`).some(n=>n.length>0&&!n.startsWith("??")&&!n.startsWith("!!"))}catch{return!1}}function Kn(t,e,n,r="merge",o){let i=!1,s,a=d=>{if(i)try{K("git",["-C",d,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch{}};try{if(r==="squash"){if(K("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Js(t)){let p;try{p=K("git",["-C",t,"stash","push","-m",`pre-merge stash before ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(f){return{success:!1,dirtyError:!0,error:`Auto-stash failed: ${f instanceof Error?f.message:String(f)}. Commit or stash changes manually, then retry.`}}if(!p.includes("No local changes to save")){i=!0;try{s=K("git",["-C",t,"stash","list","--format=%gd","-n","1"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{}}}K("git",["-C",t,"merge","--squash",e],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),K("git",["-C",t,"commit","-m",`Squash merge ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});let c=!1;if(i)try{K("git",["-C",t,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch{c=!0}return{success:!0,stashed:i||void 0,stashRef:s,stashPopConflict:c||void 0}}let d=o&&hc(o),l=d?o:t;if(d||K("git",["-C",t,"checkout",e],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),Js(t)){let c;try{c=K("git",["-C",t,"stash","push","-m",`pre-merge stash before ${e}`],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch(p){try{K("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch{}return{success:!1,dirtyError:!0,error:`Auto-stash failed: ${p instanceof Error?p.message:String(p)}. Commit or stash changes manually, then retry.`}}if(!c.includes("No local changes to save")){i=!0;try{s=K("git",["-C",t,"stash","list","--format=%gd","-n","1"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()||void 0}catch{}}}try{K("git",["-C",l,"rebase",n],{timeout:6e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch{try{K("git",["-C",l,"rebase","--abort"],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch{}try{K("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch{}return a(t),{success:!1,rebaseConflict:!0,stashed:i||void 0,stashRef:s,error:[`Rebase of ${e} onto ${n} hit conflicts.`,"To resolve manually:",` cd ${l}`,` git rebase ${n}`," # resolve conflicts in each file, then:"," git add <file>"," git rebase --continue"," # repeat until rebase finishes, then re-run agent_merge."].join(`
|
|
16
|
+
`)}}K("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),K("git",["-C",t,"merge","--ff-only",e],{timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});let u=!1;if(i)try{K("git",["-C",t,"stash","pop"],{timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch{u=!0}return{success:!0,fastForward:!0,stashed:i||void 0,stashRef:s,stashPopConflict:u||void 0}}catch(d){try{K("git",["-C",t,"checkout",n],{timeout:15e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]})}catch{}return a(t),{success:!1,error:d instanceof Error?d.message:String(d),stashed:i||void 0,stashRef:s}}}var Ys=j(()=>{});import{execFileSync as Un}from"child_process";function Zs(t,e,n,r,o,i){if(!$e())return{success:!1,error:"GitHub CLI (gh) is not available"};try{let s;if(i)try{let c=Un("git",["-C",t,"remote","get-url","origin"],{timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim().match(/[:/]([^/]+)\/[^/]+(?:\.git)?$/);c&&(s=c[1])}catch{}let a=["pr","create","--base",n];return i&&a.push("--repo",i),s?a.push("--head",`${s}:${e}`):a.push("--head",e),r&&o?a.push("--title",r,"--body",o):a.push("--fill-verbose"),{success:!0,prUrl:Un("gh",a,{cwd:t,timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim()}}catch(s){return{success:!1,error:s instanceof Error?s.message:String(s)}}}function Ut(t,e,n){if(!$e())return{exists:!1,state:"none"};try{let r=["pr","list","--head",e,"--state","all","--json","url,number,title,state","--jq",".[0]"];n&&r.push("--repo",n);let i=Un("gh",r,{cwd:t,timeout:1e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();if(!i)return{exists:!1,state:"none"};let s=JSON.parse(i),a=s.state.toLowerCase();return{exists:!0,state:a==="open"?"open":a==="merged"?"merged":a==="closed"?"closed":"none",url:s.url,number:s.number,title:s.title}}catch(r){return`${e}${r instanceof Error?r.message:String(r)}`,{exists:!1,state:"none"}}}function Xs(t,e,n,r){if(!$e())return!1;try{let o=["pr","comment",String(e),"--body",n];return r&&o.push("--repo",r),Un("gh",o,{cwd:t,timeout:3e4,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch(o){return`${e}${o instanceof Error?o.message:String(o)}`,!1}}function Ge(t){if(t.kind==="merge"){let e=t.filesChanged!==void 0?` (${t.filesChanged} files, +${t.insertions??0}/-${t.deletions??0})`:"";return`✅ Merged: ${t.branch} → ${t.base??"main"}${e}`}return t.kind==="pr-updated"?`✅ PR updated: ${t.prUrl??""}`:t.targetRepo?`✅ PR opened against ${t.targetRepo}: ${t.prUrl??""}`:`✅ PR opened: ${t.prUrl??""}`}var Go=j(()=>{Kt()});import{existsSync as Ho}from"fs";function ea(){return new Date().toISOString()}function Sc(t){return t.worktreeLifecycle??{state:t.worktreePath||t.worktreeBranch?"provisioned":"none",updatedAt:ea(),baseBranch:t.worktreeBaseBranch,targetRepo:t.worktreePrTargetRepo,pushRemote:t.worktreePushRemote}}function yc(t){return t.worktreeLifecycle?.baseBranch??t.worktreeBaseBranch??(Ho(t.workdir)?be(t.workdir):void 0)}function He(t,e={}){let n=Sc(t),r=ea(),o=new Set,i=Ho(t.workdir),s=!!(t.worktreePath&&Ho(t.worktreePath)),a=t.worktreeBranch,d=yc(t),l=!1,u=!1,c=!1,p=!1,f,g,h=t.worktreePrUrl?"open":"none",y=t.worktreePrUrl,k=t.worktreePrNumber;if(i||o.add("repo_missing"),a||o.add("branch_missing"),!s&&t.worktreePath&&o.add("worktree_missing"),e.activeSession&&o.add("active_session"),n.state==="pending_decision"&&o.add("pending_decision"),n.state==="merge_conflict_resolving"&&o.add("merge_conflict_resolving"),i&&a&&(l=Ft(t.workdir,a),l||o.add("branch_missing")),s&&t.worktreePath&&(u=mt(t.worktreePath),u&&o.add("dirty_worktree_entries")),i&&l&&d){let T=Vs(t.workdir,a,d);f=T?.ahead,g=T?.behind,c=ct(t.workdir,a,d),c?o.add("topology_merged"):(p=Gs(t.workdir,a,d),p&&o.add("merge_noop_content_already_on_base"),!p&&(f??0)>0&&o.add("unique_content"))}else d||o.add("base_branch_missing");if(e.includePrSync&&i&&a){let T=Ut(t.workdir,a,t.worktreePrTargetRepo??n.targetRepo);h=T.state,y=T.url??y,k=T.number??k}h==="open"&&o.add("pr_open"),h==="merged"&&!c&&!p&&o.add("pr_merged_not_reflected_locally");let R;c?R="merged":p&&(R="released");let b=e.activeSession||u,A=n.state;!b&&R?A=R:!l&&n.state==="pending_decision"&&(A="cleanup_failed");let N=A==="merged"||A==="released",S=e.activeSession||u||!N&&n.state==="pending_decision"||n.state==="merge_conflict_resolving"||n.state==="pr_open"||h==="open"||o.has("pr_merged_not_reflected_locally"),I=!S&&(A==="merged"||A==="released"||n.state==="dismissed"||n.state==="no_change"),J={checkedAt:r,repoExists:i,branchExists:l,worktreeExists:s,activeSession:e.activeSession===!0,dirtyTracked:u,topologyMerged:c,releaseNoopMerge:p,branchAheadCount:f,baseAheadCount:g,prState:h,prUrl:y,prNumber:k,reasons:[...o]};return{lifecycle:n,evidence:J,derivedState:A,cleanupSafe:I,preserve:S,reasons:[...o]}}var Vt=j(()=>{Kt();Go();Vo()});var me=j(()=>{Kt();Vo();Ys();Go();Vt()});function ft(t,e){let n=t.resolve(e),r=t.getPersistedSession(e),o=n?W(n):r?W(r):void 0;return{activeSession:n,persistedSession:r,persistedRef:o,sessionName:n?.name??r?.name??e,prompt:n?.prompt??r?.prompt,worktreePath:n?.worktreePath??r?.worktreePath,originalWorkdir:n?.originalWorkdir??r?.workdir,branchName:n?.worktreeBranch??r?.worktreeBranch,notificationTarget:n??(r?{id:o??e,name:r.name,harnessSessionId:r.harnessSessionId,backendRef:r.backendRef,route:r.route,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey,goalTaskId:r.goalTaskId}:void 0)}}function Ht(t){return[...t.persistedSession?ae(t.persistedSession):[],...t.activeSession?ae(t.activeSession):[]].filter((e,n,r)=>r.indexOf(e)===n)}function rp(t,e){let n=[e.id,e.backendConversationId,e.harnessSessionId,e.name],r,o;for(let i of n)if(i&&(r??=t.resolve(i),o??=t.getPersistedSession(i),r&&o))break;return{activeSession:r,persistedSession:o}}function Xn(t,e,n={}){let{activeSession:r,persistedSession:o}=rp(t,e),i=He({workdir:e.workdir,worktreePath:e.worktreePath,worktreeBranch:e.worktreeBranch,worktreeBaseBranch:n.baseBranch??o?.worktreeBaseBranch,worktreePrTargetRepo:o?.worktreePrTargetRepo,worktreePushRemote:o?.worktreePushRemote,worktreePrUrl:o?.worktreePrUrl,worktreePrNumber:o?.worktreePrNumber,worktreeLifecycle:o?.worktreeLifecycle},{activeSession:!!(r&&(r.status==="starting"||r.status==="running")),includePrSync:!!(o?.worktreeLifecycle?.state==="pr_open"||o?.worktreePrUrl)});return{activeSession:r,persistedSession:o,resolvedLifecycle:i}}function er(t){let e=t.list("all").filter(o=>o.worktreePath),n=t.listPersistedSessions().filter(o=>o.worktreePath),r=new Map;for(let o of n){if(!o.worktreePath)continue;let i=C(o),s=o.sessionId??i??o.harnessSessionId;s&&r.set(s,{id:o.sessionId??i??o.harnessSessionId,name:o.name,worktreePath:o.worktreePath,worktreeBranch:o.worktreeBranch,worktreeStrategy:o.worktreeStrategy,workdir:o.workdir,worktreeMerged:o.worktreeMerged,worktreeMergedAt:o.worktreeMergedAt,worktreePrUrl:o.worktreePrUrl,backendConversationId:i,harnessSessionId:o.harnessSessionId})}for(let o of e)o.worktreePath&&r.set(o.id,{id:o.id,name:o.name,worktreePath:o.worktreePath,worktreeBranch:o.worktreeBranch,worktreeStrategy:o.worktreeStrategy,workdir:o.originalWorkdir??o.workdir,worktreeMerged:void 0,worktreeMergedAt:void 0,worktreePrUrl:void 0,backendConversationId:C(o),harnessSessionId:o.harnessSessionId});return Array.from(r.values())}function tr(t,e){return t.id===e||t.name===e||t.backendConversationId===e||t.harnessSessionId===e}function ze(t){switch(t){case"none":return"none";case"provisioned":return"active";case"pending_decision":return"needs decision";case"merge_conflict_resolving":return"conflict resolving";case"pr_open":return"pr open";case"merged":return"merged";case"released":return"released";case"dismissed":return"dismissed";case"no_change":return"no change";case"cleanup_failed":return"cleanup failed";default:return t}}function nr(t){switch(t){case"active_session":return"active session";case"pending_decision":return"pending decision";case"merge_conflict_resolving":return"conflict resolving";case"dirty_tracked_changes":case"dirty_worktree_entries":return"dirty worktree";case"unique_content":return"still has unique content";case"topology_merged":return"merged by ancestry";case"merge_noop_content_already_on_base":return"content already on base";case"pr_open":return"PR open";case"pr_merged_not_reflected_locally":return"merged PR not reflected locally";case"repo_missing":return"repo missing";case"branch_missing":return"branch missing";case"worktree_missing":return"worktree missing";case"base_branch_missing":return"base branch missing";default:return t.replaceAll("_"," ")}}var jt=j(()=>{Q();Vt()});function wa(t,e={preserveBlankLines:!0}){return t?.replace(/\r\n/g,`
|
|
17
17
|
`).split(`
|
|
18
|
-
`).map(r=>r.trim()).reduce((r,
|
|
19
|
-
`:" ").replace(/[ \t]+/g," ").trim()||void 0}function
|
|
20
|
-
`)}function
|
|
18
|
+
`).map(r=>r.trim()).reduce((r,o)=>o?(r.push(o),r):(e.preserveBlankLines&&r[r.length-1]!==""&&r.push(o),r),[]).join(e.preserveBlankLines?`
|
|
19
|
+
`:" ").replace(/[ \t]+/g," ").trim()||void 0}function sp(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function ei(t){return t.replace(/\b[A-Za-z0-9_-]*(?:api[_-]?key|token|secret|password|passwd|pwd|credential|credentials|authorization|auth)[A-Za-z0-9_-]*\b\s*[:=]\s*["']?[^"'\s,;)]+/gi,"[redacted credential]").replace(/\b(?:api key|token|secret|password|credential|credentials)\s+\[redacted credential\]/gi,"[redacted credential]").replace(/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{16,}\b/g,"[redacted token]").replace(/\bgithub_pat_[A-Za-z0-9_]{20,}\b/g,"[redacted token]").replace(/\bsk-[A-Za-z0-9_-]{20,}\b/g,"[redacted token]").replace(/\bxox[baprs]-[A-Za-z0-9-]{20,}\b/g,"[redacted token]").replace(/\bAKIA[0-9A-Z]{16}\b/g,"[redacted token]").replace(/\beyJ[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{10,}\b/g,"[redacted token]").replace(/\bhttps?:\/\/\S+/gi,"[redacted link]").replace(/\b[A-Z]:\\(?:Users|Documents and Settings)\\[^\s`'")]+/gi,"[redacted path]").replace(/(?:^|[\s(])\/(?:home|Users|var|etc|private|tmp)\/[^\s`'").]+/g,e=>`${e.startsWith(" ")||e.startsWith("(")?e[0]:""}[redacted path]`).replace(new RegExp("\\b[A-Za-z0-9_-]{32,}\\b","g"),"[redacted token]")}function ya(t){return/\b[A-Za-z0-9_-]*(?:api[_-]?key|token|secret|password|passwd|pwd|credential|credentials|authorization|auth)[A-Za-z0-9_-]*\b\s*[:=]\s*["']?[^"'\s,;)]+/i.test(t)||/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{16,}\b/.test(t)||/\bgithub_pat_[A-Za-z0-9_]{20,}\b/.test(t)||/\bsk-[A-Za-z0-9_-]{20,}\b/.test(t)||/\bxox[baprs]-[A-Za-z0-9-]{20,}\b/.test(t)||/\bAKIA[0-9A-Z]{16}\b/.test(t)||/\beyJ[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{10,}\b/.test(t)||/\bhttps?:\/\/\S+/i.test(t)||/\b[A-Z]:\\(?:Users|Documents and Settings)\\[^\s`'")]+/i.test(t)||/(?:^|[\s(])\/(?:home|Users|var|etc|private|tmp)\/[^\s`'").]+/.test(t)||new RegExp("\\b[A-Za-z0-9_-]{32,}\\b").test(t)}function ap(t){let e=wa(t);if(!e)return;let n=e.match(/^[^.!?]+[.!?]/)?.[0]??e,r=ei(n).replace(/\s+/g," ").trim();return r?sp(r,180):void 0}function Pa(t){return ei(t.trim()).replace(/\s+/g," ").trim()}function dp(t,e){return t?.commitMessages.map(n=>Pa(n.message)).filter(Boolean).slice(0,e)??[]}function lp(){return["Not recorded by agent_pr. Review CI/checks and session output before merging."]}function up(){return["Generated PR metadata omits full task prompts and redacts sensitive-looking prompt details.","Review touched areas for behavior, security, and privacy impact."]}function cp(t){let e=ap(t.prompt),n=t.diffSummary;return{sessionName:t.sessionName,objective:e,stats:n?{commits:n.commits,filesChanged:n.filesChanged,insertions:n.insertions,deletions:n.deletions}:void 0,changedFiles:n?.changedFiles??[],commitSubjects:dp(n,5),validation:lp(),notes:up()}}function ir(t,e,n){return Array.isArray(t)&&t.length>0&&t.length<=e&&t.every(r=>typeof r=="string"&&r.trim().length>0&&r.length<=n)}function pp(t,e){let n=wa(t);if(!n)return[];let r=e?.toLowerCase();return n.split(/[.!?\n]/).map(o=>o.trim()).filter(o=>o.length>=24).filter(o=>!r||o.toLowerCase()!==r.replace(/[.!?]$/,"")).map(o=>o.toLowerCase())}function ka(t,e,n){let r=t.toLowerCase();return pp(e,n.objective).some(o=>r.includes(o))}function va(t){return/^(?:node|next|nuxt|vue|express|nest|three|d3|chart|ember|backbone|require)\.js$/i.test(t)}function mp(t,e){let n=new Set(e.changedFiles);if([...t.matchAll(/(?:^|[^\w.-])((?:\.?[\w-][\w.-]*\/)+(?:\.?[\w-][\w.-]*))(?![\w.-])/g)].map(p=>p[1]).some(p=>/\.[A-Za-z0-9]+$/.test(p)&&!n.has(p)))return!0;let o=new Set(e.changedFiles.filter(p=>!p.includes("/"))),i=String.raw`\.[a-z0-9][\w.-]*`,s=t.matchAll(new RegExp(`[\\\`"'](${i})[\\\`"']`,"g"));for(let p of s)if(!o.has(p[1]))return!0;let a=t.matchAll(new RegExp(String.raw`\b(?:file|files|path|paths|changed|changes|updated?|updates?|modified?|modifies|touched?|touches|added?|adds?|removed?|removes?|deleted?|deletes?)\s+(?:the\s+)?(${i})(?![\w.-])`,"gi"));for(let p of a)if(!o.has(p[1]))return!0;if(o.size===0)return!1;let d=new Set([...o].map(p=>p.match(/\.([A-Za-z0-9]+)$/)?.[1]?.toLowerCase()).filter(p=>!!p)),l=String.raw`[A-Za-z0-9][\w.-]*\.([A-Za-z0-9]+)`,u=t.matchAll(new RegExp(`[\\\`"'](${l})[\\\`"']`,"g"));for(let p of u){let f=p[1],g=p[2]?.toLowerCase();if(g!==void 0&&d.has(g)&&!o.has(f)&&!va(f))return!0}return[...t.matchAll(new RegExp(String.raw`\b(?:file|files|path|paths|changed|changes|updated?|updates?|modified?|modifies|touched?|touches|added?|adds?|removed?|removes?|deleted?|deletes?)\s+(?:the\s+)?(${l})\b`,"gi"))].some(p=>{let f=p[1],g=p[2]?.toLowerCase();return g!==void 0&&d.has(g)&&!o.has(f)&&!va(f)})}function zt(t){return ei(t).replace(/\s+/g," ").trim()}function fp(t,e,n){if(!t||typeof t!="object")return;let r=t;if(typeof r.title!="string"||r.title.trim().length===0||r.title.length>90||!ir(r.summary,5,180)||!ir(r.changes,10,160)||!ir(r.validation,5,160)||!ir(r.notes,5,180)||[r.title,...r.summary,...r.changes,...r.validation,...r.notes].some(a=>ya(a)||ka(a,n,e)))return;let i={title:zt(r.title),summary:r.summary.map(zt),changes:r.changes.map(zt),validation:r.validation.map(zt),notes:r.notes.map(zt)},s=[i.title,...i.summary,...i.changes,...i.validation,...i.notes];if(!s.some(a=>!a||ya(a)||ka(a,n,e))&&!s.some(a=>mp(a,e)))return i}async function sr(t){let e=cp(t);if(!t.provider)return{ok:!1,error:"PR metadata generation requires an LLM metadata provider. Pass explicit title and body, or configure a provider before creating the PR.",evidence:e};try{let n=await t.provider.generatePrMetadata(e),r=fp(n,e,t.prompt);return r?{ok:!0,metadata:r,evidence:e}:{ok:!1,error:"LLM-generated PR metadata failed schema or safety validation. Pass explicit title/body or retry after correcting the provider output.",evidence:e}}catch(n){return`${n instanceof Error?n.message:String(n)}`,{ok:!1,error:"PR metadata provider failed. Pass explicit title/body or retry after the provider is healthy.",evidence:e}}}function ar(t){let e=[`OpenClaw Code Agent session: ${t.sessionName}`,"","## Summary",...t.metadata.summary.map(n=>`- ${n}`),"","## Changes",...t.metadata.changes.map(n=>`- ${n}`),""];if(t.diffSummary){let n=t.diffSummary.commitMessages.slice(0,5).map(o=>`- ${o.hash} ${Pa(o.message)} (${o.author})`),r=t.diffSummary.commits>5?[`- ...and ${t.diffSummary.commits-5} more`]:[];n.length>0&&e.push("## Commits",...n,...r,"")}return e.push("## Validation",...t.metadata.validation.map(n=>`- ${n}`),"","## Notes / Risks",...t.metadata.notes.map(n=>`- ${n}`),""),e.push("---","Generated with [openclaw-code-agent](https://github.com/goldmar/openclaw-code-agent)"),e.join(`
|
|
20
|
+
`)}var ti=j(()=>{});function dr(t,e){return{...e,baseBranch:e.baseBranch??t.worktreeBaseBranch,targetRepo:e.targetRepo??t.worktreePrTargetRepo,pushRemote:e.pushRemote??t.worktreePushRemote}}function lr(t,e={}){let n=e.updatedAt??new Date().toISOString(),r={pendingWorktreeDecisionSince:e.pendingSince??n,lastWorktreeReminderAt:void 0,lifecycle:"awaiting_worktree_decision",worktreeState:"pending_decision",worktreeLifecycle:dr(t,{state:"pending_decision",updatedAt:n,notes:e.notes})};return e.clearResolverSessionId&&(r.autoMergeResolverSessionId=void 0),r}function ba(t,e,n,r={}){let o=r.updatedAt??new Date().toISOString();return{autoMergeConflictResolutionAttemptCount:n,autoMergeResolverSessionId:e,pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,lifecycle:"terminal",worktreeState:"merge_conflict_resolving",worktreeLifecycle:dr(t,{state:"merge_conflict_resolving",updatedAt:o,notes:r.notes})}}function ur(t,e={}){let n=e.updatedAt??new Date().toISOString(),r=e.resolvedAt??n,o={worktreeMerged:!0,worktreeMergedAt:e.mergedAt??r,lifecycle:"terminal",worktreeState:"merged",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeLifecycle:dr(t,{state:"merged",updatedAt:n,resolvedAt:r,resolutionSource:e.resolutionSource??"agent_merge"})};return e.clearResolverSessionId&&(o.autoMergeResolverSessionId=void 0),o}function Aa(t,e){let n=e.updatedAt??new Date().toISOString(),r={worktreePrUrl:e.prUrl,lifecycle:"terminal",worktreeState:"pr_open",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,worktreeLifecycle:dr(t,{state:"pr_open",updatedAt:n,resolutionSource:"agent_pr",baseBranch:e.baseBranch,targetRepo:e.targetRepo})};return e.prNumber!==void 0&&(r.worktreePrNumber=e.prNumber),e.disposition!==void 0&&(r.worktreeDisposition=e.disposition),r}var cr=j(()=>{});var Ra={};ul(Ra,{buildPrCompletionWakeOutcomeKey:()=>ri,buildPrMetadata:()=>sr,buildPrOutcomeDetailLines:()=>ni,formatPrBody:()=>ar,makeAgentPrTool:()=>Qt});import{existsSync as gp}from"fs";function hp(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function ni(t){return[t.action==="opened"?`Opened PR for branch ${t.branchName} into ${t.baseBranch}.`:`Updated PR for branch ${t.branchName} into ${t.baseBranch}.`,...t.prUrl?[`PR URL: ${t.prUrl}.`]:[],...t.prNumber?[`PR number: #${t.prNumber}.`]:[],...t.targetRepo?[`Target repository: ${t.targetRepo}.`]:[],...t.commits!==void 0?[`Pushed ${t.commits} new commits (+${t.insertions??0}/-${t.deletions??0}).`]:[]]}function ri(t){let e=t.prNumber!==void 0?`#${t.prNumber}`:t.prUrl??"unknown-pr",n=t.diffSummary?.commitMessages.map(o=>o.hash.trim()).filter(Boolean).join(","),r=t.action==="updated"?n||[`commits:${t.diffSummary?.commits??"unknown"}`,`insertions:${t.diffSummary?.insertions??"unknown"}`,`deletions:${t.diffSummary?.deletions??"unknown"}`].join(","):"created";return["worktree-pr",t.action,t.targetRepo??"default-repo",e,t.branchName,r].join(":")}function Qt(t,e={}){return{name:"agent_pr",description:"Create or update a GitHub PR for a worktree branch. Handles full PR lifecycle: creates new PRs, updates existing open PRs with comments, and handles merged/closed PRs. Pushes the branch, syncs PR state, and persists metadata.",parameters:m.Object({session:m.String({description:"Session name or ID to create/update PR for"}),title:m.Optional(m.String({description:"PR title (default: auto-generated from session name)"})),body:m.Optional(m.String({description:"PR body (default: auto-generated from commit summary)"})),base_branch:m.Optional(m.String({description:"Base branch for the PR (default: detected from repo)"})),force_new:m.Optional(m.Boolean({description:"Force creation of a new PR even if one exists (default: false)"})),target_repo:m.Optional(m.String({description:"Target repository for cross-repo PRs (e.g. 'openai/codex'). Auto-detected from 'upstream' remote if not set."}))}),async execute(n,r){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}],meta:{success:!1,state:"error"}};if(!hp(r))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, title?, body?, base_branch?, force_new? }."}],meta:{success:!1,state:"error"}};if(!$e())return{content:[{type:"text",text:"Error: GitHub CLI (gh) is not available. Install it and authenticate to create PRs."}],meta:{success:!1,state:"error"}};let o=ft(v,r.session),i=o.activeSession,s=o.persistedSession;if(!i&&!s)return{content:[{type:"text",text:`Error: Session "${r.session}" not found.`}],meta:{success:!1,state:"error"}};let{worktreePath:a,originalWorkdir:d,sessionName:l,branchName:u}=o;if(!a||!d)return{content:[{type:"text",text:`Error: Session "${r.session}" does not have a worktree.`}],meta:{success:!1,state:"error"}};if(!u)return{content:[{type:"text",text:`Error: Cannot determine branch name for worktree ${a}. The worktree may have been removed and no persisted branch name is available.`}],meta:{success:!1,state:"error"}};gp(a)||`${a}${u}${d}`;let c=r.base_branch??be(d),p=h=>{let y=Aa({worktreeBaseBranch:s?.worktreeBaseBranch??i?.worktreeBaseBranch??c,worktreePrTargetRepo:s?.worktreePrTargetRepo??i?.worktreePrTargetRepo,worktreePushRemote:s?.worktreePushRemote??i?.worktreePushRemote},{prUrl:h.prUrl,prNumber:h.prNumber,baseBranch:c,targetRepo:h.targetRepo,disposition:h.disposition});for(let k of Ht(o))v.updatePersistedSession(k,y)},f=Hs(d,r.target_repo??s?.worktreePrTargetRepo);if(!qn(d,u))return{content:[{type:"text",text:`❌ Failed to push ${u} — cannot create/update PR`}],meta:{success:!1,state:"error"}};let g=Ut(d,u,f);if(r.force_new&&g.exists)return{content:[{type:"text",text:`⚠️ Cannot create new PR: A PR already exists for ${u} (${g.state}).
|
|
21
21
|
|
|
22
22
|
Existing PR: ${g.url}
|
|
23
23
|
|
|
24
|
-
To create a new PR, you must first close/merge the existing PR manually or use a different branch.`}],meta:{success:!1,state:"error"}};if(g.exists&&g.state==="open"){let h=
|
|
25
|
-
`),
|
|
26
|
-
...and ${h.commits-5} more commits`:"",
|
|
27
|
-
`);if(
|
|
24
|
+
To create a new PR, you must first close/merge the existing PR manually or use a different branch.`}],meta:{success:!1,state:"error"}};if(g.exists&&g.state==="open"){let h=xe(d,u,c);if(h&&h.commits>0){let y=h.commitMessages.slice(0,5).map(A=>`• ${A.hash} ${A.message} (${A.author})`).join(`
|
|
25
|
+
`),k=h.commits>5?`
|
|
26
|
+
...and ${h.commits-5} more commits`:"",R=["🔄 **New commits pushed**","",`${h.commits} new commits (+${h.insertions} / -${h.deletions})`,"","### Latest commits:",y+k,"","---","🤖 [openclaw-code-agent](https://github.com/goldmar/openclaw-code-agent)"].join(`
|
|
27
|
+
`);if(Xs(d,g.number,R,f)){p({prUrl:g.url,prNumber:g.number,targetRepo:f});let A=Ge({kind:"pr-updated",branch:u,prUrl:g.url});return v.notifyWorktreeOutcome(o.notificationTarget,A,{completionWakeOutcomeKey:ri({action:"updated",branchName:u,prUrl:g.url,prNumber:g.number,targetRepo:f,diffSummary:h}),detailLines:ni({action:"updated",branchName:u,baseBranch:c,prUrl:g.url,prNumber:g.number,targetRepo:f,commits:h.commits,insertions:h.insertions,deletions:h.deletions})}),{content:[{type:"text",text:`${A}
|
|
28
28
|
|
|
29
29
|
📝 Added comment detailing ${h.commits} new commits (+${h.insertions} / -${h.deletions})`}],meta:{success:!0,state:"pr_updated"}}}else return{content:[{type:"text",text:`⚠️ Pushed to ${g.url} but failed to add comment.
|
|
30
30
|
|
|
31
31
|
${h.commits} new commits (+${h.insertions} / -${h.deletions})`}],meta:{success:!0,state:"pr_open"}}}else return p({prUrl:g.url,prNumber:g.number,targetRepo:f}),{content:[{type:"text",text:`ℹ️ PR already exists and is up to date: ${g.url}
|
|
32
32
|
|
|
33
|
-
No new commits to push.`}],meta:{success:!0,state:"pr_open"}}}else if(g.exists&&g.state==="merged"){let h={...
|
|
33
|
+
No new commits to push.`}],meta:{success:!0,state:"pr_open"}}}else if(g.exists&&g.state==="merged"){let h={...ur({worktreeBaseBranch:s?.worktreeBaseBranch??i?.worktreeBaseBranch??c,worktreePrTargetRepo:s?.worktreePrTargetRepo??i?.worktreePrTargetRepo,worktreePushRemote:s?.worktreePushRemote??i?.worktreePushRemote},{resolutionSource:"agent_pr",clearResolverSessionId:!0}),worktreePrUrl:g.url,worktreePrNumber:g.number,worktreeDisposition:"merged",worktreeDecisionSnoozedUntil:void 0};for(let y of Ht(o))v.updatePersistedSession(y,h);return{content:[{type:"text",text:`✅ PR was already merged: ${g.url}
|
|
34
34
|
|
|
35
35
|
The worktree branch ${u} can be cleaned up with agent_merge(delete_branch=true).`}],meta:{success:!0,state:"merged"}}}else{if(g.exists&&g.state==="closed")return{content:[{type:"text",text:`⚠️ A PR exists but was closed without merging: ${g.url}
|
|
36
36
|
|
|
@@ -40,206 +40,204 @@ What would you like to do?
|
|
|
40
40
|
2. Close and delete the branch with agent_merge(delete_branch=true), then start a new session/worktree
|
|
41
41
|
3. Manually delete the closed PR on GitHub, then call agent_pr(force_new=true) to create a fresh PR
|
|
42
42
|
|
|
43
|
-
(This tool cannot automatically reopen or recreate PRs to avoid unintended actions.)`}],meta:{success:!1,state:"closed"}};{let h=!r.title||!r.body?
|
|
44
|
-
`)}function
|
|
45
|
-
`).map(n=>n.trim()).filter(Boolean)??[];if(e.length!==0)for(let n of e){let r=n.match(/^(Workdir|Repo):\s*(.+)$/),
|
|
46
|
-
`)}function
|
|
47
|
-
`):"",
|
|
48
|
-
`):"";return{kind:"blocked",text:["Resume-first protection blocked a fresh launch.","",N,
|
|
43
|
+
(This tool cannot automatically reopen or recreate PRs to avoid unintended actions.)`}],meta:{success:!1,state:"closed"}};{let h=!r.title||!r.body?xe(d,u,c):void 0,y;if(!r.title||!r.body){let A=await sr({sessionName:l,prompt:o.prompt,diffSummary:h,provider:e.metadataProvider});if(A.ok===!1)return{content:[{type:"text",text:`❌ ${A.error}`}],meta:{success:!1,state:"error"}};y=A.metadata}let k=r.title??y.title,R=r.body;R||(R=ar({sessionName:l,metadata:y,diffSummary:h}));let b=Zs(d,u,c,k,R,f);if(b.success&&b.prUrl){let A=Ut(d,u,f);p({prUrl:b.prUrl,prNumber:A.number,targetRepo:f,disposition:"pr-opened"});let N=Ge({kind:"pr-opened",branch:u,targetRepo:f,prUrl:b.prUrl});return v.notifyWorktreeOutcome(o.notificationTarget,N,{completionWakeOutcomeKey:ri({action:"opened",branchName:u,prUrl:b.prUrl,prNumber:A.number,targetRepo:f}),detailLines:ni({action:"opened",branchName:u,baseBranch:c,prUrl:b.prUrl,prNumber:A.number,targetRepo:f})}),{content:[{type:"text",text:N}],meta:{success:!0,state:"created"}}}else return{content:[{type:"text",text:`❌ Failed to create PR: ${b.error??"unknown error"}`}],meta:{success:!1,state:"error"}}}}}}}var pr=j(()=>{X();O();me();ti();cr();jt();ti()});import{readdirSync as Tg,statSync as Cg,rmSync as Mg}from"fs";import{execFileSync as _g}from"child_process";import{join as ol}from"path";X();O();function ml(t){return t.length>80?`${t.slice(0,80)}...`:t}function fl(t){return t.worktreePath?!t.originalWorkdir||t.originalWorkdir===t.worktreePath?`${t.worktreePath} (worktree)`:`${t.worktreePath} (worktree of ${t.originalWorkdir})`:t.workdir}function gl(t){let e=["Session launched successfully.",` Name: ${t.sessionName}`,` ID: ${t.sessionId}`,` Harness: ${t.harness}`,` Permission mode: ${t.permissionMode}`,` Plan approval: ${t.planApproval}`,` Worktree strategy: ${t.worktreeStrategy??"off"}`,` Resolved workdir: ${fl(t)}`,` Model: ${t.model??"default"}`,` Prompt: "${ml(t.prompt)}"`];return t.reasoningEffort&&e.push(` Reasoning effort: ${t.reasoningEffort}`),t.fastMode&&e.push(" Fast mode: enabled"),t.resumeSessionId?e.push(` Resume: ${t.resumeSessionId}${t.forkSession?" (forked)":""}`):t.forceNewSession&&e.push(" Force new session: true"),t.clearedPersistedCodexResume&&e.push(" Thread state: historical Codex state cleared; starting a fresh thread."),e.push(" Mode: multi-turn (use agent_respond to send follow-up messages)"),e.push("","Use agent_sessions to check status, agent_output to see output."),e.join(`
|
|
44
|
+
`)}function on(t,e){return gl({...t,sessionId:e.id,sessionName:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,worktreeStrategy:e.worktreeStrategy??"off",worktreePath:e.worktreePath,originalWorkdir:e.originalWorkdir})}te();function tt(t){let{requestedResumeSessionId:e,activeSession:n,persistedSession:r}=t;return e?n?{resumeSessionId:e,clearedPersistedCodexResume:!1}:r?.harness==="codex"&&r.backendRef?.kind!=="codex-app-server"?{resumeSessionId:void 0,clearedPersistedCodexResume:!0}:{resumeSessionId:e,clearedPersistedCodexResume:!1}:{resumeSessionId:void 0,clearedPersistedCodexResume:!1}}Q();function vn(t){return"id"in t?t.id:t.sessionId}function Wt(t){return t.status==="completed"||t.killReason==="done"}function Eu(t){return!Wt(t)||!C(t)?!1:t.backendRef?.kind==="codex-app-server"||t.backendRef?.kind==="opencode-server"}function $u(t){return(t.killReason==="shutdown"||t.killReason==="startup-timeout")&&!C(t)}function Nt(t){if(t.status==="running")return{kind:"direct",reason:"already_running"};let e=vn(t);if(Wt(t)&&!Eu(t))return{kind:"unavailable",reason:"completed",stableSessionId:e};let n=C(t);if(n){let r="harnessName"in t?void 0:t,{resumeSessionId:o,clearedPersistedCodexResume:i}=tt({requestedResumeSessionId:n,activeSession:"harnessName"in t?{harnessSessionId:n}:void 0,persistedSession:r?{harness:r.harness,backendRef:r.backendRef}:void 0});return o?{kind:"resume",resumeSessionId:o,stableSessionId:e,clearedPersistedCodexResume:i}:{kind:"unavailable",reason:"legacy_non_resumable",stableSessionId:e,clearedPersistedCodexResume:i}}return $u(t)?{kind:"relaunch",stableSessionId:e}:{kind:"unavailable",reason:"missing_backend_state",stableSessionId:e}}te();import{existsSync as bs}from"fs";function wn(t,e){if(!e||e.length===0)return!0;if(!t)return!1;let n=t.toLowerCase();return e.some(r=>n.includes(r.toLowerCase()))}Q();function vs(t){return t==null?void 0:String(t).trim()||void 0}function Du(t){return t.trim().replace(/^['"`](.*)['"`]$/s,"$1").trim()}function Ou(t){let e=t.split(/\n\s*\n/,1)[0]?.split(`
|
|
45
|
+
`).map(n=>n.trim()).filter(Boolean)??[];if(e.length!==0)for(let n of e){let r=n.match(/^(Workdir|Repo):\s*(.+)$/),o=Du(r?.[2]??"");if(o.startsWith("/")&&bs(o))return o}}function ws(t,e){return t.workdir!==e.workdir?!1:e.originSessionKey&&t.originSessionKey?t.originSessionKey===e.originSessionKey:!e.originChannel||!t.originChannel?!1:t.originChannel===e.originChannel&&vs(t.originThreadId)===vs(e.originThreadId)}function Ps(t){return t.slice(0,3).map(e=>` - ${e.name} [${e.ref}] | status=${e.status}${e.lifecycle?` | lifecycle=${e.lifecycle}`:""}`).join(`
|
|
46
|
+
`)}function Wu(t,e){let n=[],r=[],o=new Set;for(let i of t.list?.("all")??[]){if(!ws(i,e))continue;let s=i.id;if(!o.has(s)){if(o.add(s),i.isExplicitlyResumable){n.push({ref:i.id,name:i.name,status:i.status,lifecycle:i.lifecycle,resumable:!0});continue}(i.status==="starting"||i.status==="running")&&r.push({ref:i.id,name:i.name,status:i.status,lifecycle:i.lifecycle,resumable:!1})}}for(let i of t.listPersistedSessions?.()??[]){if(!i.resumable||!ws(i,e))continue;let s=W(i)??i.harnessSessionId,a=i.sessionId??C(i)??i.harnessSessionId;!s||!a||o.has(a)||(o.add(a),n.push({ref:s,name:i.name,status:i.status,lifecycle:i.lifecycle,resumable:!0}))}return{resumable:n,active:r}}function Pn(t,e,n){let r=t.workdir||Ou(t.prompt)||e.workspaceDir||E.defaultWorkdir||process.cwd();if(!bs(r))return{kind:"error",text:`Error: Working directory does not exist: ${r}`};let o=t.harness??se(),i=Ze(o),s=t.model??i,a=t.model!==void 0,d=sn(o);if(!s&&(o!=="opencode"||d&&d.length>0))return{kind:"error",text:`Error: No default model configured for harness "${o}". Set plugins.entries["openclaw-code-agent"].config.harnesses.${o}.defaultModel or pass model explicitly.`};if(s&&d&&d.length>0&&!wn(s,d))return{kind:"error",text:a?`Error: Model "${s}" is not allowed. Permitted models: ${d.join(", ")}`:`Error: Default model "${s||"undefined"}" is not in allowedModels (${d.join(", ")}). Update your plugin config to set a compatible defaultModel.`};let l=an(e),u=Ct(e,l||Mt(r)),c=e.sessionKey||void 0,p=ji(c)??bo(e);if(!t.resume_session_id&&!t.force_new_session){let A=Wu(n,{workdir:r,originSessionKey:c,originChannel:u,originThreadId:p});if(A.resumable.length>0||A.active.length>0){let N=A.resumable.length>0?["Linked resumable session(s) already exist for this thread/workdir:",Ps(A.resumable),"","Resume the latest one with:",` agent_respond(session='${A.resumable[0].ref}', message='<next instruction>')`,"Fork from it with:",` agent_launch(prompt='<new task>', resume_session_id='${A.resumable[0].ref}', fork_session=true)`].join(`
|
|
47
|
+
`):"",S=A.active.length>0?[A.resumable.length>0?"Linked active session(s):":"Linked active session(s) already exist for this thread/workdir:",Ps(A.active),"","Send a follow-up instead of launching a duplicate:",` agent_respond(session='${A.active[0].ref}', message='<next instruction>')`].join(`
|
|
48
|
+
`):"";return{kind:"blocked",text:["Resume-first protection blocked a fresh launch.","",N,S,["If you intentionally want a brand-new independent session here, call:"," agent_launch(prompt='<new task>', force_new_session=true)"].join(`
|
|
49
49
|
`)].filter(Boolean).join(`
|
|
50
50
|
|
|
51
|
-
`)}}}let f=t.resume_session_id,g=f?n.resolve?.(f):void 0,h=f?n.getPersistedSession?.(f):void 0;if(f){let
|
|
52
|
-
`)}function
|
|
53
|
-
`)}function
|
|
54
|
-
`),r=[],
|
|
55
|
-
`)}function
|
|
56
|
-
`),r=[],
|
|
57
|
-
`)}var Ne,Dt,tt=!1;function ps(t){try{return t?.config?.current?.()}catch{return}}function nt(t,e){if(t&&typeof t=="object"){Ne=t,arguments.length>=2?(Dt=e,tt=!0):tt||(Dt=ps(Ne),tt=!0);return}Ne=void 0,Dt=void 0,tt=!1}function Pn(){return Ne}function ms(){return Ne?.tasks?.managedFlows??Ne?.taskFlow}function fs(){return tt||(Dt=ps(Ne),tt=!0),Dt}var xu="openclaw-code-agent",Iu=160,bn={create(){},progress(){},finalize(){}};function Rn(t,e){let n=e instanceof Error?e.message:String(e);`${t}${n}`}function Tu(t,e){if(e.applied===!1){let n=e.code?` (${e.code})`:"";`${t}${n}`}}function Cu(t){let e=t.prompt.trim().replace(/\s+/g," ");return Z(e||t.name,Iu)}function Mu(t){if(t.status==="starting"||t.lifecycle==="starting")return"Starting";if(t.lifecycle==="active")return"Running";if(t.lifecycle==="awaiting_plan_decision")return"Waiting for plan approval";if(t.lifecycle==="awaiting_user_input")return"Waiting for input";if(t.lifecycle==="awaiting_worktree_decision")return"Waiting for worktree decision";if(t.lifecycle==="suspended")return"Suspended after idle timeout"}function _u(t){if(t.status==="completed")return"succeeded";if(t.status==="failed")return"failed";if(t.status==="killed")return t.killReason==="idle-timeout"||t.killReason==="startup-timeout"?"timed_out":"cancelled"}function xi(t,e){return t==="completed"?"Completed":t==="failed"?"Failed":e==="idle-timeout"?"Timed out after idle timeout":e==="startup-timeout"?"Timed out during startup":e==="shutdown"?"Cancelled during shutdown":e==="user"?"Cancelled by user":"Cancelled"}function $u(t){return t.lifecycle==="awaiting_plan_decision"||t.lifecycle==="awaiting_user_input"||t.lifecycle==="awaiting_worktree_decision"||t.lifecycle==="suspended"}function Ii(t,e,n){return{phase:e,integration:"phase-1-managed-task-flow",sessionId:t.id,sessionName:t.name,sessionStatus:t.status,sessionLifecycle:t.lifecycle,summary:n}}function Eu(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.createManaged=="function"&&typeof e.resume=="function"&&typeof e.setWaiting=="function"&&typeof e.finish=="function"&&typeof e.fail=="function"}function gs(t,e){if(e.applied)return e.flow;let n=e.current;return n?.flowId&&typeof n.revision=="number"?n:t}var Ti=class{constructor(e){this.taskFlow=e}taskFlow;flow;finalized=!1;lastProgressKey;create(e){if(this.flow||this.finalized)return;let n="Starting",r=Date.now();try{this.flow=this.taskFlow.createManaged({controllerId:xu,goal:Cu(e),status:"running",notifyPolicy:"silent",currentStep:n,stateJson:Ii(e,"created",n),createdAt:e.startedAt,updatedAt:r}),this.lastProgressKey=this.progressKey(e,n)}catch(i){Rn("create",i)}}progress(e){if(!this.flow||this.finalized)return;let n=Mu(e);if(!n)return;let r=this.progressKey(e,n);if(r!==this.lastProgressKey)try{let i=Ii(e,"progress",n),o=Date.now(),s=$u(e)?this.taskFlow.setWaiting({flowId:this.flow.flowId,expectedRevision:this.flow.revision,currentStep:n,stateJson:i,waitJson:{reason:n,sessionId:e.id},blockedSummary:n,updatedAt:o}):this.taskFlow.resume({flowId:this.flow.flowId,expectedRevision:this.flow.revision,status:"running",currentStep:n,stateJson:i,updatedAt:o});this.flow=gs(this.flow,s),this.lastProgressKey=r}catch(i){Rn("progress",i)}}finalize(e){if(!this.flow||this.finalized)return;let n=_u(e);if(!n)return;let r=n==="succeeded"?"Completed":n==="failed"?"Failed":xi(e.status,e.killReason);try{let i=e.completedAt??Date.now(),o={...Ii(e,"terminal",r),terminalStatus:n,terminalSummary:xi(e.status,e.killReason),...e.status==="failed"&&e.error?{error:e.error}:{}},s=n==="succeeded"?this.taskFlow.finish({flowId:this.flow.flowId,expectedRevision:this.flow.revision,stateJson:o,updatedAt:i,endedAt:i}):this.taskFlow.fail({flowId:this.flow.flowId,expectedRevision:this.flow.revision,stateJson:o,blockedSummary:xi(e.status,e.killReason),updatedAt:i,endedAt:i});Tu("finalize",s),this.flow=gs(this.flow,s),this.finalized=!0}catch(i){Rn("finalize",i)}}progressKey(e,n){return`${e.status}:${e.lifecycle}:${n}`}};function An(t){if(!t.sessionKey?.trim())return bn;try{let e=ms()?.fromToolContext;if(typeof e!="function")return bn;let n=e(t);return Eu(n)?new Ti(n):bn}catch(e){return Rn("resolve",e),bn}}function Du(t){return t instanceof Error?t.message:String(t)}function hs(t,e){return t?("id"in t?t.id:t.sessionId)??e??"unknown-session":e??"unknown-session"}function Ou(t){return!t||typeof t!="object"?!1:typeof t.prompt=="string"}function Wu(t){return!!t&&typeof t=="object"&&typeof t.formatLaunchResult=="function"}function ys(t){return{name:"agent_launch",description:"Launch a coding agent session in background to execute a development task. Sessions are multi-turn — they stay open for follow-up messages via agent_respond. Supports resuming previous sessions. Returns a session ID and name for tracking.",parameters:m.Object({prompt:m.String({description:"The task prompt to execute"}),name:m.Optional(m.String({description:"Short human-readable name for the session (kebab-case, e.g. 'fix-auth'). Auto-generated from prompt if omitted."})),workdir:m.Optional(m.String({description:"Working directory (defaults to cwd)"})),model:m.Optional(m.String({description:"Model name to use"})),system_prompt:m.Optional(m.String({description:"Additional system prompt"})),allowed_tools:m.Optional(m.Array(m.String(),{description:"List of allowed tools"})),resume_session_id:m.Optional(m.String({description:"Session reference to continue or fork from. Prefer the plugin session ID shown by agent_launch or agent_sessions; persisted backend conversation IDs also resolve when available."})),fork_session:m.Optional(m.Boolean({description:"When resuming, fork to a new session instead of continuing the existing one. Use with resume_session_id."})),force_new_session:m.Optional(m.Boolean({description:"Bypass resume-first protection and start a brand-new linked session even when a resumable or active linked session already exists."})),permission_mode:m.Optional(m.Union([m.Literal("default"),m.Literal("plan"),m.Literal("bypassPermissions")],{description:"Permission mode: 'default' (plugin-managed interactive execution), 'plan' (present the plan first and block implementation until approval), 'bypassPermissions' (fully autonomous execution). Defaults to plugin config ('plan' by default)."})),plan_approval:m.Optional(m.Union([m.Literal("ask"),m.Literal("delegate"),m.Literal("approve")],{description:"Plan approval policy for this session: 'ask' (send the full plan to the user with Approve/Revise/Reject buttons), 'delegate' (orchestrator must review the full plan, then either approve directly or escalate back to the user with the same buttons), 'approve' (auto-approve after verification). Overrides the plugin-level planApproval setting."})),harness:m.Optional(m.String({description:"Agent harness to use ('claude-code', 'codex', or experimental 'opencode'). Defaults to the plugin defaultHarness."})),worktree_strategy:m.Optional(m.Union([m.Literal("off"),m.Literal("manual"),m.Literal("ask"),m.Literal("delegate"),m.Literal("auto-merge"),m.Literal("auto-pr")],{description:"Worktree strategy: 'off' (no worktree), 'manual' (create worktree but no auto merge-back), 'ask' (prompt user with Merge/Open PR/Later/Discard buttons), 'delegate' (orchestrator decides), 'auto-merge' (merge automatically), 'auto-pr' (open/update a PR automatically). Defaults to the plugin config when unset."})),worktree_base_branch:m.Optional(m.String({description:"Base branch for worktree merge/PR operations (default: auto-detected or 'main')"})),worktree_pr_target_repo:m.Optional(m.String({description:"Target repository for cross-repo PRs (e.g. 'openai/codex' for fork-to-upstream workflow). If not set, auto-detected from 'upstream' remote or defaults to 'origin'."}))}),async execute(e,n){if(!k)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!Ou(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected at least { prompt }."}]};n.agentId&&`${n.agentId}${t.agentId}`;try{let r=Sn(n,t,k);if(r.kind!=="resolved")return{content:[{type:"text",text:r.text}]};let{workdir:i,harness:o,resolvedModel:s,permissionMode:a,planApproval:d,originChannel:l,originThreadId:u,originSessionKey:c,route:p,resumeSessionId:f,resolvedResumeId:g,clearedPersistedCodexResume:h,reasoningEffort:y,fastMode:S}=r,P=n.resume_session_id?k.resolve(n.resume_session_id)??k.getPersistedSession(n.resume_session_id):void 0,b=!n.fork_session&&P?$t(P):void 0;if(b?.kind==="direct")return{content:[{type:"text",text:`Session ${P.name} [${hs(P,n.resume_session_id)}] is already running. Use agent_respond(session='${n.resume_session_id}', message='<next instruction>') instead of agent_launch(resume_session_id=...).`}]};if(b?.kind==="unavailable")return{content:[{type:"text",text:`Resume unavailable for session ${P.name} [${hs(P,n.resume_session_id)}] (${b.reason}). Use agent_launch(prompt='<new task>') for a fresh session or set fork_session=true to fork from prior context.`}]};let R=k.spawn({prompt:n.prompt,sessionIdOverride:n.fork_session?void 0:b?.kind==="resume"||b?.kind==="relaunch"?b.stableSessionId:void 0,name:n.name,workdir:i,model:s,reasoningEffort:y,fastMode:S,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,resumeSessionId:b?.kind==="resume"?b.resumeSessionId:f,resumeWorktreeFrom:g,forkSession:f?n.fork_session:!1,multiTurn:!0,permissionMode:a,planApproval:d,codexApprovalPolicy:o==="codex"?"never":void 0,originChannel:l,originThreadId:u,originAgentId:t.agentId||void 0,originSessionKey:c,route:p,harness:o,taskLifecycle:An(t),worktreeStrategy:n.worktree_strategy,worktreeBaseBranch:n.worktree_base_branch,worktreePrTargetRepo:n.worktree_pr_target_repo});return{content:[{type:"text",text:Wu(k)?k.formatLaunchResult({prompt:n.prompt,workdir:i,harness:o,permissionMode:a??C.permissionMode,planApproval:d,forceNewSession:n.force_new_session,resumeSessionId:n.resume_session_id,forkSession:n.fork_session,clearedPersistedCodexResume:h},R):en({prompt:n.prompt,workdir:i,harness:o,permissionMode:a??C.permissionMode,planApproval:d,resumeSessionId:n.resume_session_id,forkSession:n.fork_session,forceNewSession:n.force_new_session,clearedPersistedCodexResume:h},{id:R.id,name:R.name,model:R.model,reasoningEffort:R.reasoningEffort??Ae(o),fastMode:R.fastMode??S,worktreeStrategy:R.worktreeStrategy??n.worktree_strategy??C.defaultWorktreeStrategy??"off",worktreePath:R.worktreePath,originalWorkdir:R.originalWorkdir})}]}}catch(r){let i=Du(r),o=i.includes("Max sessions")?"":`
|
|
58
|
-
|
|
59
|
-
Use agent_sessions to see active sessions and their status.`;return{content:[{type:"text",text:`Error launching session: ${
|
|
60
|
-
`),[r="",...
|
|
61
|
-
${e}`:e,this.deps.emitOutput(e)}noteToolCall(e){let{name:n,input:r,currentPermissionMode:i,permissionMode:o,planModeApproved:s}=e;if(n==="Write"){let a=r;typeof a?.file_path=="string"&&a.file_path.includes("/.claude/plans/")&&this.deps.setPlanFilePath(a.file_path)}n==="AskUserQuestion"?(this.lastTurnHadQuestion=!0,this.deps.applyInputRequested(),(i==="plan"||o==="plan")&&!s&&this.deps.markPendingPlanApproval("plan-mode")):(n==="ExitPlanMode"||n==="set_permission_mode")&&!s&&(this.lastTurnHadQuestion=!0,this.deps.markPendingPlanApproval("plan-mode")),this.deps.emitToolUse(n,r)}notePendingInput(){this.lastTurnHadQuestion=!0,this.deps.applyInputRequested(),this.waitingForInputFired||(this.waitingForInputFired=!0,this.deps.emitTurnEnd(!0))}clearResolvedPendingInput(e,n){if(!(!e||n?.requestId===e))return n}notePlanArtifact(e,n){if(this.currentTurnPlanArtifact=e,this.deps.setLatestPlanArtifact(e),!n)return;let r=e.markdown.trim();!r||this.currentTurnText.trim()===r||(this.deps.appendOutput(r),this.currentTurnText=r,this.deps.emitOutput(r))}noteSettingsChanged(e){let{oldMode:n,permissionMode:r,planModeApproved:i}=e;if(r)return r!=="plan"&&n==="plan"&&!i&&(this.deps.markPendingPlanApproval("plan-mode"),this.lastTurnHadQuestion=!0),r}finishSuccessfulTurn(e){let{currentPermissionMode:n,permissionMode:r,pendingPlanApproval:i,planModeApproved:o,pendingInputState:s,hasPendingMessages:a}=e,d=i;(n==="plan"||r==="plan")&&!d&&!o&&(this.deps.markPendingPlanApproval("plan-mode"),d=!0);let l=d||this.lastTurnHadQuestion||!!s;if(this.turnInProgress=a,l&&!this.waitingForInputFired)this.waitingForInputFired=!0,d||this.deps.markAwaitingUserInput(),this.deps.emitTurnEnd(!0);else if(!a&&!l){if(this.deps.queueWorktreeFinalizationPrompt?.()){this.turnInProgress=!0;return}this.deps.completeTurn(),this.deps.emitTurnEnd(!1)}}finishTerminalTurn(){this.turnInProgress=!1}finishInterruptedTurn(e){this.turnInProgress=e,this.waitingForInputFired=!1,this.lastTurnHadQuestion=!1,this.currentTurnText="",this.currentTurnPlanArtifact=void 0}resetAfterRun(){this.lastTurnHadQuestion=!1,this.currentTurnText="",this.currentTurnPlanArtifact=void 0}};var Mn=class{constructor(e){this.deps=e}deps;applyMessage(e,n){if(e.type==="backend_ref"){this.deps.clearStartupTimer(),this.deps.assignBackendRef({...e.ref}),this.deps.transitionRunning();return}if(e.type==="run_started"){e.runId&&this.deps.noteRunStarted(e.runId);return}if(e.type==="text_delta"){this.deps.noteTextDelta(e.text,n.pendingPlanApproval);return}if(e.type==="tool_call"){this.deps.noteToolCall({name:e.name,input:e.input,currentPermissionMode:n.currentPermissionMode,permissionMode:n.permissionMode,planModeApproved:n.planModeApproved});return}if(e.type==="pending_input"){this.deps.setPendingInputState(e.state),this.deps.notePendingInput();return}if(e.type==="pending_input_resolved"){this.deps.setPendingInputState(this.deps.clearResolvedPendingInput(e.requestId,n.pendingInputState));return}if(e.type==="plan_artifact"){this.deps.notePlanArtifact(e);return}if(e.type==="settings_changed"){let r=this.deps.noteSettingsChanged({oldMode:n.currentPermissionMode,permissionMode:e.permissionMode,planModeApproved:n.planModeApproved});r&&this.deps.setCurrentPermissionMode(r);return}if(e.type==="run_completed"){this.deps.handleRunCompleted(e.data);return}e.type}};ue();var ac=120*1e3;function qn(t){return t instanceof Error?t.message:String(t)}var Kn=class extends sc{id;name;harnessSessionId;backendRef;harness;harnessHandle;prompt;workdir;model;reasoningEffort;fastMode;systemPrompt;allowedTools;permissionMode;requestedPermissionMode;planApproval;codexApprovalPolicy;currentPermissionMode;pendingModeSwitch;resumeSessionId;forkSession;worktreePath;originalWorkdir;worktreeBranch;worktreeStrategy;worktreeBaseBranch;worktreePrTargetRepo;autoMergeParentSessionId;autoMergeConflictResolutionAttemptCount;autoMergeResolverSessionId;worktreePushRemote;worktreeDisposition;worktreePrUrl;worktreePrNumber;worktreeMerged;worktreeMergedAt;worktreeLifecycle;worktreeState="none";multiTurn;goalTaskId;messageStream;_status="starting";error;startedAt;completedAt;abortController;outputBuffer=[];result;costUsd=0;originChannel;originThreadId;originAgentId;originSessionKey;route;pendingInputState;pendingPlanApproval=!1;planApprovalContext;planDecisionVersion=0;actionablePlanDecisionVersion;canonicalPlanPromptVersion;approvalPromptRequiredVersion;approvalPromptVersion;approvalPromptStatus="not_sent";approvalPromptTransport="none";approvalPromptMessageKind="none";approvalPromptLastAttemptAt;approvalPromptDeliveredAt;approvalPromptFailedAt;planFilePath;killReason="unknown";planModeApproved=!1;turnRuntime;harnessEvents;worktreeFinalizationPromptIssued=!1;lifecycle="starting";approvalState="not_required";approvalExecutionState="not_plan_gated";approvalRationale;latestPlanArtifact;latestPlanArtifactVersion;runtimeState="live";deliveryState="idle";canUseTool;autoRespondCount=0;timers=new Tn;constructor(e,n){super(),this.id=e.sessionIdOverride??xn(8),this.name=n,this.harness=e.harness?Ct(e.harness):rs(),this.prompt=e.prompt,this.workdir=e.workdir,this.model=e.model??je(this.harness.name),this.reasoningEffort=e.reasoningEffort??Ae(this.harness.name),this.fastMode=this.harness.name==="codex"?e.fastMode??ze(this.harness.name):void 0,this.systemPrompt=e.systemPrompt,this.allowedTools=e.allowedTools,this.permissionMode=e.permissionMode??C.permissionMode,this.requestedPermissionMode=e.requestedPermissionMode??this.permissionMode,this.planApproval=e.planApproval??C.planApproval,this.codexApprovalPolicy=this.harness.name==="codex"?"never":void 0,this.currentPermissionMode=this.permissionMode,this.originChannel=e.originChannel,this.originThreadId=e.originThreadId,this.originAgentId=e.originAgentId,this.originSessionKey=e.originSessionKey,this.route=e.route?{...e.route}:void 0,this.backendRef=e.backendRef?{...e.backendRef}:void 0,this.resumeSessionId=e.resumeSessionId,this.forkSession=e.forkSession,this.multiTurn=e.multiTurn??!0,this.goalTaskId=e.goalTaskId,this.worktreeStrategy=e.worktreeStrategy,this.worktreeBaseBranch=e.worktreeBaseBranch,e.worktreePrTargetRepo&&(this.worktreePrTargetRepo=e.worktreePrTargetRepo),e.autoMergeParentSessionId&&(this.autoMergeParentSessionId=e.autoMergeParentSessionId),e.autoMergeConflictResolutionAttemptCount!==void 0&&(this.autoMergeConflictResolutionAttemptCount=e.autoMergeConflictResolutionAttemptCount),e.autoMergeResolverSessionId&&(this.autoMergeResolverSessionId=e.autoMergeResolverSessionId),this.canUseTool=e.canUseTool,this.startedAt=Date.now(),this.abortController=new AbortController,this.turnRuntime=new Cn({appendOutput:r=>Rs(this.outputBuffer,this.id,r),emitOutput:r=>this.emit("output",this,r),emitToolUse:(r,i)=>this.emit("toolUse",this,r,i),emitTurnEnd:r=>this.emit("turnEnd",this,r),markPendingPlanApproval:r=>this.markPendingPlanApproval(r),markAwaitingUserInput:()=>this.markAwaitingUserInput(),applyInputRequested:()=>this.applyControlEvent({type:"input.requested"}),completeTurn:()=>{this.applyControlEvent({type:"terminal.entered"}),this.complete("done")},queueWorktreeFinalizationPrompt:()=>this.queueWorktreeFinalizationPrompt(),setPlanFilePath:r=>{this.planFilePath=r},setLatestPlanArtifact:r=>{this.latestPlanArtifact=r;let i=this.pendingPlanApproval?this.actionablePlanDecisionVersion??this.planDecisionVersion:void 0;this.latestPlanArtifactVersion=i&&i>0?i:void 0}}),this.harnessEvents=new Mn({clearStartupTimer:()=>this.clearTimer("startup"),assignBackendRef:r=>{this.backendRef=r,this.harnessSessionId=r.conversationId,r.worktreePath&&(this.worktreePath=r.worktreePath,this.originalWorkdir??=this.workdir,this.worktreeBranch??=Wn(r.worktreePath),this.worktreeStrategy&&this.worktreeStrategy!=="off"&&this.applyControlEvent({type:"worktree.state_set",worktreeState:"provisioned"}))},noteRunStarted:r=>{this.backendRef&&(this.backendRef={...this.backendRef,runId:r})},transitionRunning:()=>{this._status==="starting"&&this.transition("running")},noteTextDelta:(r,i)=>this.turnRuntime.noteTextDelta(r,i),noteToolCall:r=>this.turnRuntime.noteToolCall(r),setPendingInputState:r=>{this.pendingInputState=r},notePendingInput:()=>this.turnRuntime.notePendingInput(),clearResolvedPendingInput:(r,i)=>this.turnRuntime.clearResolvedPendingInput(r,i),notePlanArtifact:r=>this.turnRuntime.notePlanArtifact(r.artifact,r.finalized),noteSettingsChanged:r=>this.turnRuntime.noteSettingsChanged(r),setCurrentPermissionMode:r=>{this.currentPermissionMode=r,this.applyControlEvent({type:"permission.mode_changed",currentPermissionMode:r})},handleRunCompleted:r=>{let i=r.outcome??(r.success?"completed":"failed");this.result={subtype:i==="interrupted"?"interrupted":r.success?"success":"error",duration_ms:r.duration_ms,total_cost_usd:r.total_cost_usd,num_turns:r.num_turns,result:r.result,is_error:i==="failed",session_id:r.session_id},this.costUsd=r.total_cost_usd;let o=this.multiTurn&&this.messageStream&&i==="interrupted",s=this.multiTurn&&this.messageStream&&i==="completed";o?(this.resetIdleTimer(),this.turnRuntime.finishInterruptedTurn(this.messageStream?.hasPending()===!0)):s?(this.resetIdleTimer(),this.turnRuntime.finishSuccessfulTurn({currentPermissionMode:this.currentPermissionMode,permissionMode:this.permissionMode,pendingPlanApproval:this.pendingPlanApproval,planModeApproved:this.planModeApproved,pendingInputState:this.pendingInputState,hasPendingMessages:this.messageStream?.hasPending()===!0})):(this.turnRuntime.finishTerminalTurn(),this.transitionToTerminal(i==="completed"?"completed":"failed")),this.turnRuntime.resetAfterRun(),this.pendingInputState=void 0}}),this.applyControlEvent({type:"initialize",hasWorktree:!!(this.worktreeStrategy&&this.worktreeStrategy!=="off")}),(e.planModeApproved!==void 0||e.approvalState!==void 0||e.approvalExecutionState!==void 0||e.approvalRationale!==void 0||e.pendingPlanApproval!==void 0||e.planApprovalContext!==void 0||e.planDecisionVersion!==void 0||e.actionablePlanDecisionVersion!==void 0||e.canonicalPlanPromptVersion!==void 0||e.approvalPromptRequiredVersion!==void 0||e.approvalPromptVersion!==void 0||e.approvalPromptStatus!==void 0||e.approvalPromptTransport!==void 0||e.approvalPromptMessageKind!==void 0||e.approvalPromptLastAttemptAt!==void 0||e.approvalPromptDeliveredAt!==void 0||e.approvalPromptFailedAt!==void 0)&&this.applyControlPatch({...e.planModeApproved!==void 0?{planModeApproved:e.planModeApproved}:{},...e.approvalState!==void 0?{approvalState:e.approvalState}:{},...e.approvalExecutionState!==void 0?{approvalExecutionState:e.approvalExecutionState}:{},...e.pendingPlanApproval!==void 0?{pendingPlanApproval:e.pendingPlanApproval}:{},...e.planApprovalContext!==void 0?{planApprovalContext:e.planApprovalContext}:{},...e.planDecisionVersion!==void 0?{planDecisionVersion:e.planDecisionVersion}:{},...e.actionablePlanDecisionVersion!==void 0?{actionablePlanDecisionVersion:e.actionablePlanDecisionVersion}:{},...e.canonicalPlanPromptVersion!==void 0?{canonicalPlanPromptVersion:e.canonicalPlanPromptVersion}:{},...e.approvalPromptRequiredVersion!==void 0?{approvalPromptRequiredVersion:e.approvalPromptRequiredVersion}:{},...e.approvalPromptVersion!==void 0?{approvalPromptVersion:e.approvalPromptVersion}:{},...e.approvalPromptStatus!==void 0?{approvalPromptStatus:e.approvalPromptStatus}:{},...e.approvalPromptTransport!==void 0?{approvalPromptTransport:e.approvalPromptTransport}:{},...e.approvalPromptMessageKind!==void 0?{approvalPromptMessageKind:e.approvalPromptMessageKind}:{},...e.approvalPromptLastAttemptAt!==void 0?{approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt}:{},...e.approvalPromptDeliveredAt!==void 0?{approvalPromptDeliveredAt:e.approvalPromptDeliveredAt}:{},...e.approvalPromptFailedAt!==void 0?{approvalPromptFailedAt:e.approvalPromptFailedAt}:{}}),this.approvalRationale=e.approvalRationale}get status(){return this._status}get harnessName(){return this.harness.name}get backendKind(){return this.harness.backendKind}get backendCapabilities(){return this.harness.capabilities}get backendConversationId(){return x(this)}get waitingForInputFired(){return this.turnRuntime.waitingForInputFired}set waitingForInputFired(e){this.turnRuntime.waitingForInputFired=e}get lastTurnHadQuestion(){return this.turnRuntime.lastTurnHadQuestion}set lastTurnHadQuestion(e){this.turnRuntime.lastTurnHadQuestion=e}get turnInProgress(){return this.turnRuntime.turnInProgress}set turnInProgress(e){this.turnRuntime.turnInProgress=e}get currentTurnText(){return this.turnRuntime.currentTurnText}set currentTurnText(e){this.turnRuntime.currentTurnText=e}get currentTurnPlanArtifact(){return this.turnRuntime.currentTurnPlanArtifact}set currentTurnPlanArtifact(e){this.turnRuntime.currentTurnPlanArtifact=e}get duration(){return(this.completedAt??Date.now())-this.startedAt}get phase(){return this.lifecycle}get isExplicitlyResumable(){return this.status!=="running"&&this.status!=="completed"&&this.killReason!=="done"&&!!this.backendConversationId}transition(e){if(!vs[this._status].includes(e))throw new Error(`Session state error: cannot transition from ${this._status} to ${e}. This is an internal error — please report it.`);let n=this._status;this._status=e,this.applyControlEvent({type:"status.transition",status:e}),this.emit("statusChange",this,e,n)}setTimer(e,n,r){this.timers.set(e,n,r)}clearTimer(e){this.timers.clear(e)}clearAllTimers(){this.timers.clearAll()}markPendingPlanApproval(e){let n=this.latestPlanArtifactVersion;this.approvalRationale=void 0,this.applyControlEvent({type:"plan.requested",context:e});let r=this.actionablePlanDecisionVersion??this.planDecisionVersion;this.currentTurnPlanArtifact&&r>0?(this.latestPlanArtifact=this.currentTurnPlanArtifact,this.latestPlanArtifactVersion=r):n!==r&&(this.latestPlanArtifact=void 0,this.latestPlanArtifactVersion=void 0)}clearPendingPlanApproval(){this.applyControlEvent({type:"plan.cleared"})}markAwaitingUserInput(){this.applyControlEvent({type:"input.requested"})}queueWorktreeFinalizationPrompt(){if(!this.multiTurn||!this.messageStream||!this.worktreePath||!this.worktreeStrategy||this.worktreeStrategy==="off"||this.worktreeFinalizationPromptIssued)return!1;let e=st(this.worktreePath);if(e.length===0)return!1;this.worktreeFinalizationPromptIssued=!0;let n=e.slice(0,20).map(o=>`- ${o}`).join(`
|
|
51
|
+
`)}}}let f=t.resume_session_id,g=f?n.resolve?.(f):void 0,h=f?n.getPersistedSession?.(f):void 0;if(f){let A=n.resolveBackendConversationId?.(f)??n.resolveHarnessSessionId?.(f);if(!A)return{kind:"error",text:`Error: Could not resolve resume_session_id "${f}" to a session ID. Use agent_sessions to list available sessions.`};f=A}let{resumeSessionId:y,clearedPersistedCodexResume:k}=tt({requestedResumeSessionId:f,activeSession:g?{harnessSessionId:g.backendConversationId??g.harnessSessionId}:void 0,persistedSession:h?{harness:h.harness,backendRef:h.backendRef}:void 0}),R=t.permission_mode??E.permissionMode,b=t.plan_approval??E.planApproval;return{kind:"resolved",workdir:r,harness:o,resolvedModel:s,permissionMode:R,planApproval:b,originChannel:u,originThreadId:p,originSessionKey:c,route:et(e,u,c),resumeSessionId:y,resolvedResumeId:f,clearedPersistedCodexResume:k,reasoningEffort:Ce(o),fastMode:Xe(o)}}Q();function Lt(t){let e=t.harness?.trim(),n=t.model?.trim();return e&&n?`${e} | ${n}`:e?`${e} | default`:n}function bn(t){let e=Lt(t);return e?` | ${e}`:""}function we(t){let e=Math.floor(t/1e3),n=Math.floor(e/60),r=e%60;return n>0?`${n}m${r}s`:`${r}s`}var Nu=new Set(["a","an","the","is","are","was","were","be","been","being","have","has","had","do","does","did","will","would","could","should","may","might","shall","can","need","must","i","me","my","we","our","you","your","it","its","he","she","to","of","in","for","on","with","at","by","from","as","into","through","about","that","this","these","those","and","or","but","if","then","so","not","no","please","just","also","very","all","some","any","each","make","write","create","build","implement","add","update"]);function Rs(t){let n=t.toLowerCase().replace(/[^a-z0-9\s-]/g," ").split(/\s+/).filter(r=>r.length>1&&!Nu.has(r)).slice(0,3);return n.length===0?"session":n.join("-")}var As={starting:"🟡",running:"🟢",completed:"✅",failed:"❌",killed:"⛔",awaiting_plan_decision:"📋",awaiting_user_input:"❓",awaiting_worktree_decision:"🌿",suspended:"⏸️",terminal:"🏁"};function Lu(t){let e=t.worktreeLifecycle?.state??t.worktreeState;return t.worktreeMerged||e==="merged"?"[merged ✓]":e==="released"?"[released]":t.worktreePrUrl?`[PR: ${t.worktreePrUrl}]`:e==="pr_open"?"[PR open]":e==="dismissed"?"[dismissed]":e==="no_change"?"[no change]":"[not merged]"}function Is(t){let e=As[t.phase]??As[t.status]??"❓",n=we(t.duration),r=t.multiTurn?"multi-turn":"single",o=t.prompt.length>80?t.prompt.slice(0,80)+"...":t.prompt,i=t.costUsd>0?` | $${t.costUsd.toFixed(2)}`:"",s=[`${e} ${t.name} [${t.id}] (${n}${i}) — ${r}`,` 📁 ${t.workdir}`,` 📝 "${o}"`];t.worktreePath&&t.worktreeBranch&&s.push(` 🌿 Worktree: ${t.worktreeBranch} ${Lu(t)}`),t.phase!==t.status&&s.push(` ⚙️ Phase: ${t.phase}`),t.lifecycle&&t.lifecycle!==t.phase&&s.push(` 🔄 Lifecycle: ${t.lifecycle}`),(t.requestedPermissionMode||t.currentPermissionMode||t.approvalExecutionState)&&s.push(` 🔐 Approval: ${t.approvalExecutionState??"unknown"} (requested=${t.requestedPermissionMode??"unknown"}, effective=${t.currentPermissionMode??"unknown"})`),t.resumable&&s.push(" ↩️ Resumable: yes"),t.recovered&&s.push(" ♻️ Recovered: persisted metadata only; no live process to kill"),t.harness?s.push(` 🧰 Harness | model: ${Lt({harness:t.harness,model:t.model})}`):t.model&&s.push(` 🧰 Harness | model: ${t.model}`);let a=C(t);return a&&s.push(` 🔗 Backend ID: ${a}`),t.resumeSessionId&&s.push(` ↩️ Resumed from: ${t.resumeSessionId}${t.forkSession?" (forked)":""}`),s.join(`
|
|
52
|
+
`)}function An(t,e){let n=t.sessionsWithDuration>0?t.totalDurationMs/t.sessionsWithDuration:0,{completed:r,failed:o,killed:i}=t.sessionsByStatus,s=["📊 OpenClaw Code Agent Stats","","📋 Sessions",` Launched: ${t.totalLaunched}`,` Running: ${e}`,` Completed: ${r}`,` Failed: ${o}`,` Killed: ${i}`,"",`⏱️ Average duration: ${n>0?we(n):"n/a"}`];if(t.mostExpensive){let a=t.mostExpensive;s.push("","🏆 Notable session",` ${a.name} [${a.id}]`,` 📝 "${a.prompt}"`)}return s.join(`
|
|
53
|
+
`)}function re(t,e){return e<=0?"":t.length<=e?t:e<=3?".".repeat(e):t.slice(0,e-3)+"..."}function Rn(t,e){let n=t.split(`
|
|
54
|
+
`),r=[],o=0;for(let i=n.length-1;i>=0;i--){let s=n[i].length+(r.length>0?1:0);if(o+s>e&&r.length>0)break;r.unshift(n[i]),o+=s}return r.join(`
|
|
55
|
+
`)}function xs(t,e){let n=t.split(`
|
|
56
|
+
`),r=[],o=0;for(let i=0;i<n.length;i++){let s=n[i].length+(r.length>0?1:0);if(o+s>e&&r.length>0)break;r.push(n[i]),o+=s}return r.join(`
|
|
57
|
+
`)}var qe,Bt,at=!1;function Ts(t){try{return t?.config?.current?.()}catch{return}}function dt(t,e){if(t&&typeof t=="object"){qe=t,arguments.length>=2?(Bt=e,at=!0):at||(Bt=Ts(qe),at=!0);return}qe=void 0,Bt=void 0,at=!1}function In(){return qe}function Cs(){return qe?.tasks?.managedFlows??qe?.taskFlow}function Ms(){return at||(Bt=Ts(qe),at=!0),Bt}var Bu="openclaw-code-agent",Fu=160,xn={create(){},progress(){},finalize(){}};function Tn(t,e){let n=e instanceof Error?e.message:String(e);`${t}${n}`}function qu(t,e){if(e.applied===!1){let n=e.code?` (${e.code})`:"";`${t}${n}`}}function Ku(t){let e=t.prompt.trim().replace(/\s+/g," ");return re(e||t.name,Fu)}function Uu(t){if(t.status==="starting"||t.lifecycle==="starting")return"Starting";if(t.lifecycle==="active")return"Running";if(t.lifecycle==="awaiting_plan_decision")return"Waiting for plan approval";if(t.lifecycle==="awaiting_user_input")return"Waiting for input";if(t.lifecycle==="awaiting_worktree_decision")return"Waiting for worktree decision";if(t.lifecycle==="suspended")return"Suspended after idle timeout"}function Vu(t){if(t.status==="completed")return"succeeded";if(t.status==="failed")return"failed";if(t.status==="killed")return t.killReason==="idle-timeout"||t.killReason==="startup-timeout"?"timed_out":"cancelled"}function No(t,e){return t==="completed"?"Completed":t==="failed"?"Failed":e==="idle-timeout"?"Timed out after idle timeout":e==="startup-timeout"?"Timed out during startup":e==="shutdown"?"Cancelled during shutdown":e==="user"?"Cancelled by user":"Cancelled"}function Gu(t){return t.lifecycle==="awaiting_plan_decision"||t.lifecycle==="awaiting_user_input"||t.lifecycle==="awaiting_worktree_decision"||t.lifecycle==="suspended"}function Lo(t,e,n){return{phase:e,integration:"phase-1-managed-task-flow",sessionId:t.id,sessionName:t.name,sessionStatus:t.status,sessionLifecycle:t.lifecycle,summary:n}}function Hu(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.createManaged=="function"&&typeof e.resume=="function"&&typeof e.setWaiting=="function"&&typeof e.finish=="function"&&typeof e.fail=="function"}function _s(t,e){if(e.applied)return e.flow;let n=e.current;return n?.flowId&&typeof n.revision=="number"?n:t}var Bo=class{constructor(e){this.taskFlow=e}taskFlow;flow;finalized=!1;lastProgressKey;create(e){if(this.flow||this.finalized)return;let n="Starting",r=Date.now();try{this.flow=this.taskFlow.createManaged({controllerId:Bu,goal:Ku(e),status:"running",notifyPolicy:"silent",currentStep:n,stateJson:Lo(e,"created",n),createdAt:e.startedAt,updatedAt:r}),this.lastProgressKey=this.progressKey(e,n)}catch(o){Tn("create",o)}}progress(e){if(!this.flow||this.finalized)return;let n=Uu(e);if(!n)return;let r=this.progressKey(e,n);if(r!==this.lastProgressKey)try{let o=Lo(e,"progress",n),i=Date.now(),s=Gu(e)?this.taskFlow.setWaiting({flowId:this.flow.flowId,expectedRevision:this.flow.revision,currentStep:n,stateJson:o,waitJson:{reason:n,sessionId:e.id},blockedSummary:n,updatedAt:i}):this.taskFlow.resume({flowId:this.flow.flowId,expectedRevision:this.flow.revision,status:"running",currentStep:n,stateJson:o,updatedAt:i});this.flow=_s(this.flow,s),this.lastProgressKey=r}catch(o){Tn("progress",o)}}finalize(e){if(!this.flow||this.finalized)return;let n=Vu(e);if(!n)return;let r=n==="succeeded"?"Completed":n==="failed"?"Failed":No(e.status,e.killReason);try{let o=e.completedAt??Date.now(),i={...Lo(e,"terminal",r),terminalStatus:n,terminalSummary:No(e.status,e.killReason),...e.status==="failed"&&e.error?{error:e.error}:{}},s=n==="succeeded"?this.taskFlow.finish({flowId:this.flow.flowId,expectedRevision:this.flow.revision,stateJson:i,updatedAt:o,endedAt:o}):this.taskFlow.fail({flowId:this.flow.flowId,expectedRevision:this.flow.revision,stateJson:i,blockedSummary:No(e.status,e.killReason),updatedAt:o,endedAt:o});qu("finalize",s),this.flow=_s(this.flow,s),this.finalized=!0}catch(o){Tn("finalize",o)}}progressKey(e,n){return`${e.status}:${e.lifecycle}:${n}`}};function Cn(t){if(!t.sessionKey?.trim())return xn;try{let e=Cs()?.fromToolContext;if(typeof e!="function")return xn;let n=e(t);return Hu(n)?new Bo(n):xn}catch(e){return Tn("resolve",e),xn}}function ju(t){return t instanceof Error?t.message:String(t)}function Es(t,e){return t?("id"in t?t.id:t.sessionId)??e??"unknown-session":e??"unknown-session"}function zu(t){return!t||typeof t!="object"?!1:typeof t.prompt=="string"}function Qu(t){return!!t&&typeof t=="object"&&typeof t.formatLaunchResult=="function"}function $s(t){return{name:"agent_launch",description:"Launch a coding agent session in background to execute a development task. Sessions are multi-turn — they stay open for follow-up messages via agent_respond. Supports resuming previous sessions. Returns a session ID and name for tracking.",parameters:m.Object({prompt:m.String({description:"The task prompt to execute"}),name:m.Optional(m.String({description:"Short human-readable name for the session (kebab-case, e.g. 'fix-auth'). Auto-generated from prompt if omitted."})),workdir:m.Optional(m.String({description:"Working directory (defaults to cwd)"})),model:m.Optional(m.String({description:"Model name to use"})),system_prompt:m.Optional(m.String({description:"Additional system prompt"})),allowed_tools:m.Optional(m.Array(m.String(),{description:"List of allowed tools"})),resume_session_id:m.Optional(m.String({description:"Session reference to continue or fork from. Prefer the plugin session ID shown by agent_launch or agent_sessions; persisted backend conversation IDs also resolve when available."})),fork_session:m.Optional(m.Boolean({description:"When resuming, fork to a new session instead of continuing the existing one. Use with resume_session_id."})),force_new_session:m.Optional(m.Boolean({description:"Bypass resume-first protection and start a brand-new linked session even when a resumable or active linked session already exists."})),permission_mode:m.Optional(m.Union([m.Literal("default"),m.Literal("plan"),m.Literal("bypassPermissions")],{description:"Permission mode: 'default' (plugin-managed interactive execution), 'plan' (present the plan first and block implementation until approval), 'bypassPermissions' (fully autonomous execution). Defaults to plugin config ('plan' by default)."})),plan_approval:m.Optional(m.Union([m.Literal("ask"),m.Literal("delegate"),m.Literal("approve")],{description:"Plan approval policy for this session: 'ask' (send the full plan to the user with Approve/Revise/Reject buttons), 'delegate' (orchestrator must review the full plan, then either approve directly or escalate back to the user with the same buttons), 'approve' (auto-approve after verification). Overrides the plugin-level planApproval setting."})),harness:m.Optional(m.String({description:"Agent harness to use ('claude-code', 'codex', or experimental 'opencode'). Defaults to the plugin defaultHarness."})),worktree_strategy:m.Optional(m.Union([m.Literal("off"),m.Literal("manual"),m.Literal("ask"),m.Literal("delegate"),m.Literal("auto-merge"),m.Literal("auto-pr")],{description:"Worktree strategy: 'off' (no worktree), 'manual' (create worktree but no auto merge-back), 'ask' (prompt user with Merge/Open PR/Later/Discard buttons), 'delegate' (orchestrator decides), 'auto-merge' (merge automatically), 'auto-pr' (open/update a PR automatically). Defaults to the plugin config when unset."})),worktree_base_branch:m.Optional(m.String({description:"Base branch for worktree merge/PR operations (default: auto-detected or 'main')"})),worktree_pr_target_repo:m.Optional(m.String({description:"Target repository for cross-repo PRs (e.g. 'openai/codex' for fork-to-upstream workflow). If not set, auto-detected from 'upstream' remote or defaults to 'origin'."}))}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!zu(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected at least { prompt }."}]};n.agentId&&`${n.agentId}${t.agentId}`;try{let r=Pn(n,t,v);if(r.kind!=="resolved")return{content:[{type:"text",text:r.text}]};let{workdir:o,harness:i,resolvedModel:s,permissionMode:a,planApproval:d,originChannel:l,originThreadId:u,originSessionKey:c,route:p,resumeSessionId:f,resolvedResumeId:g,clearedPersistedCodexResume:h,reasoningEffort:y,fastMode:k}=r,R=n.resume_session_id?v.resolve(n.resume_session_id)??v.getPersistedSession(n.resume_session_id):void 0,b=!n.fork_session&&R?Nt(R):void 0;if(b?.kind==="direct")return{content:[{type:"text",text:`Session ${R.name} [${Es(R,n.resume_session_id)}] is already running. Use agent_respond(session='${n.resume_session_id}', message='<next instruction>') instead of agent_launch(resume_session_id=...).`}]};if(b?.kind==="unavailable")return{content:[{type:"text",text:`Resume unavailable for session ${R.name} [${Es(R,n.resume_session_id)}] (${b.reason}). Use agent_launch(prompt='<new task>') for a fresh session or set fork_session=true to fork from prior context.`}]};let A=v.spawn({prompt:n.prompt,sessionIdOverride:n.fork_session?void 0:b?.kind==="resume"||b?.kind==="relaunch"?b.stableSessionId:void 0,name:n.name,workdir:o,model:s,reasoningEffort:y,fastMode:k,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,resumeSessionId:b?.kind==="resume"?b.resumeSessionId:f,resumeWorktreeFrom:g,forkSession:f?n.fork_session:!1,multiTurn:!0,permissionMode:a,planApproval:d,codexApprovalPolicy:i==="codex"?"never":void 0,originChannel:l,originThreadId:u,originAgentId:t.agentId||void 0,originSessionKey:c,route:p,harness:i,taskLifecycle:Cn(t),worktreeStrategy:n.worktree_strategy,worktreeBaseBranch:n.worktree_base_branch,worktreePrTargetRepo:n.worktree_pr_target_repo});return{content:[{type:"text",text:Qu(v)?v.formatLaunchResult({prompt:n.prompt,workdir:o,harness:i,permissionMode:a??E.permissionMode,planApproval:d,forceNewSession:n.force_new_session,resumeSessionId:n.resume_session_id,forkSession:n.fork_session,clearedPersistedCodexResume:h},A):on({prompt:n.prompt,workdir:o,harness:i,permissionMode:a??E.permissionMode,planApproval:d,resumeSessionId:n.resume_session_id,forkSession:n.fork_session,forceNewSession:n.force_new_session,clearedPersistedCodexResume:h},{id:A.id,name:A.name,model:A.model,reasoningEffort:A.reasoningEffort??Ce(i),fastMode:A.fastMode??k,worktreeStrategy:A.worktreeStrategy??n.worktree_strategy??E.defaultWorktreeStrategy??"off",worktreePath:A.worktreePath,originalWorkdir:A.originalWorkdir})}]}}catch(r){let o=ju(r),i=o.includes("Max sessions")?"":`
|
|
58
|
+
|
|
59
|
+
Use agent_sessions to see active sessions and their status.`;return{content:[{type:"text",text:`Error launching session: ${o}${i}`}]}}}}}X();O();te();import{existsSync as jo,readFileSync as na}from"fs";import{EventEmitter as kc}from"events";import{webcrypto as Os}from"node:crypto";var Ds="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";var Ju=128,Ke,lt;function Yu(t){if(t<0||t>1024)throw new RangeError("Wrong ID size");!Ke||Ke.length<t?(Ke=Buffer.allocUnsafe(t*Ju),Os.getRandomValues(Ke),lt=0):lt+t>Ke.length&&(Os.getRandomValues(Ke),lt=0),lt+=t}function Mn(t=21){Yu(t|=0);let e="";for(let n=lt-t;n<lt;n++)e+=Ds[Ke[n]&63];return e}Do();te();Q();var Ws={starting:["running","failed","killed"],running:["completed","failed","killed"],completed:[],failed:[],killed:[]};function G(t,e){return Object.hasOwn(t,e)}var Ns=new Set(["merged","released","pr_open","dismissed","cleanup_failed"]);function Zu(t){return t.requestedPermissionMode!=="plan"?"not_plan_gated":t.pendingPlanApproval?"awaiting_approval":t.planModeApproved?"approved_then_implemented":t.currentPermissionMode!=="plan"?"implemented_without_required_approval":"awaiting_plan_output"}function ie(t){return{...t,approvalExecutionState:Zu(t)}}function Fo(t,e){switch(e.type){case"initialize":return ie({...t,worktreeState:e.hasWorktree&&t.worktreeState==="none"?"provisioned":t.worktreeState,lifecycle:t.status==="starting"?"starting":t.lifecycle,runtimeState:t.status==="starting"?"live":t.runtimeState});case"status.transition":return e.status==="starting"?ie({...t,status:e.status,lifecycle:"starting",runtimeState:"live"}):e.status==="running"?ie({...t,status:e.status,lifecycle:t.lifecycle==="starting"||t.lifecycle==="suspended"?"active":t.lifecycle,runtimeState:"live"}):ie({...t,status:e.status,runtimeState:"stopped",lifecycle:t.lifecycle==="suspended"?"suspended":"terminal"});case"permission.mode_changed":return ie({...t,currentPermissionMode:e.currentPermissionMode});case"turn.started":return ie({...t,lifecycle:"active",runtimeState:"live"});case"input.requested":return ie({...t,lifecycle:t.pendingPlanApproval?"awaiting_plan_decision":"awaiting_user_input"});case"plan.requested":if(t.planModeApproved)return t;{let n=t.pendingPlanApproval&&t.approvalState==="pending"&&t.planApprovalContext===e.context,r=t.pendingPlanApproval&&t.approvalState==="changes_requested"&&t.planApprovalContext===e.context&&t.planDecisionVersion>0,o=!t.pendingPlanApproval&&t.approvalState==="changes_requested"&&t.planApprovalContext===e.context&&t.planDecisionVersion>0,i=n||r||o?t.planDecisionVersion:t.planDecisionVersion+1;return ie({...t,pendingPlanApproval:!0,planApprovalContext:e.context,approvalState:"pending",planDecisionVersion:i,actionablePlanDecisionVersion:i,canonicalPlanPromptVersion:n?t.canonicalPlanPromptVersion:void 0,approvalPromptRequiredVersion:n?t.approvalPromptRequiredVersion:void 0,approvalPromptVersion:n?t.approvalPromptVersion:void 0,approvalPromptStatus:n?t.approvalPromptStatus:"not_sent",approvalPromptTransport:n?t.approvalPromptTransport:"none",approvalPromptMessageKind:n?t.approvalPromptMessageKind:"none",approvalPromptLastAttemptAt:n?t.approvalPromptLastAttemptAt:void 0,approvalPromptDeliveredAt:n?t.approvalPromptDeliveredAt:void 0,approvalPromptFailedAt:n?t.approvalPromptFailedAt:void 0,lifecycle:"awaiting_plan_decision"})}case"plan.cleared":return ie({...t,pendingPlanApproval:!1,planApprovalContext:void 0,actionablePlanDecisionVersion:void 0,approvalState:t.approvalState==="pending"?"not_required":t.approvalState});case"plan.approved":return ie({...t,pendingPlanApproval:!1,planApprovalContext:void 0,actionablePlanDecisionVersion:void 0,planModeApproved:!0,approvalState:"approved",planDecisionVersion:t.planDecisionVersion+1,approvalPromptVersion:void 0,approvalPromptStatus:"not_sent",lifecycle:t.status==="running"?"active":t.lifecycle});case"plan.changes_requested":return ie({...t,pendingPlanApproval:!0,approvalState:"changes_requested",planDecisionVersion:t.planDecisionVersion+1,actionablePlanDecisionVersion:void 0,canonicalPlanPromptVersion:void 0,approvalPromptRequiredVersion:void 0,approvalPromptVersion:void 0,approvalPromptStatus:"not_sent",approvalPromptTransport:"none",approvalPromptMessageKind:"none",approvalPromptLastAttemptAt:void 0,approvalPromptDeliveredAt:void 0,approvalPromptFailedAt:void 0,lifecycle:"awaiting_plan_decision"});case"terminal.entered":return ie({...t,lifecycle:e.suspended?"suspended":"terminal",runtimeState:"stopped"});case"worktree.decision_requested":return ie({...t,lifecycle:"awaiting_worktree_decision",worktreeState:"pending_decision"});case"worktree.state_set":return ie({...t,worktreeState:e.worktreeState,lifecycle:e.worktreeState==="pending_decision"?"awaiting_worktree_decision":Ns.has(e.worktreeState)?"terminal":t.lifecycle});case"delivery.state_set":return ie({...t,deliveryState:e.deliveryState})}}function Ls(t,e){let n={...t,...G(e,"lifecycle")?{lifecycle:e.lifecycle}:{},...G(e,"approvalState")?{approvalState:e.approvalState}:{},...G(e,"approvalExecutionState")?{approvalExecutionState:e.approvalExecutionState}:{},...G(e,"worktreeState")?{worktreeState:e.worktreeState}:{},...G(e,"runtimeState")?{runtimeState:e.runtimeState}:{},...G(e,"deliveryState")?{deliveryState:e.deliveryState}:{},...G(e,"requestedPermissionMode")?{requestedPermissionMode:e.requestedPermissionMode}:{},...G(e,"currentPermissionMode")?{currentPermissionMode:e.currentPermissionMode}:{},...G(e,"pendingPlanApproval")?{pendingPlanApproval:e.pendingPlanApproval}:{},...G(e,"planApprovalContext")?{planApprovalContext:e.planApprovalContext}:{},...G(e,"planDecisionVersion")?{planDecisionVersion:e.planDecisionVersion}:{},...G(e,"actionablePlanDecisionVersion")?{actionablePlanDecisionVersion:e.actionablePlanDecisionVersion}:{},...G(e,"canonicalPlanPromptVersion")?{canonicalPlanPromptVersion:e.canonicalPlanPromptVersion}:{},...G(e,"approvalPromptRequiredVersion")?{approvalPromptRequiredVersion:e.approvalPromptRequiredVersion}:{},...G(e,"approvalPromptVersion")?{approvalPromptVersion:e.approvalPromptVersion}:{},...G(e,"approvalPromptStatus")?{approvalPromptStatus:e.approvalPromptStatus}:{},...G(e,"approvalPromptTransport")?{approvalPromptTransport:e.approvalPromptTransport}:{},...G(e,"approvalPromptMessageKind")?{approvalPromptMessageKind:e.approvalPromptMessageKind}:{},...G(e,"approvalPromptLastAttemptAt")?{approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt}:{},...G(e,"approvalPromptDeliveredAt")?{approvalPromptDeliveredAt:e.approvalPromptDeliveredAt}:{},...G(e,"approvalPromptFailedAt")?{approvalPromptFailedAt:e.approvalPromptFailedAt}:{},...G(e,"planModeApproved")?{planModeApproved:e.planModeApproved}:{}};return e.approvalState==="changes_requested"&&e.pendingPlanApproval===void 0&&(n={...n,pendingPlanApproval:!1}),n.pendingPlanApproval?n={...n,approvalState:"pending",actionablePlanDecisionVersion:n.actionablePlanDecisionVersion??n.planDecisionVersion,lifecycle:"awaiting_plan_decision"}:n.approvalState==="changes_requested"&&(n={...n,actionablePlanDecisionVersion:void 0,lifecycle:"awaiting_user_input"}),G(e,"pendingWorktreeDecisionSince")&&e.pendingWorktreeDecisionSince!==void 0||n.worktreeState==="pending_decision"?n=Fo(n,{type:"worktree.decision_requested"}):Ns.has(n.worktreeState)&&(n={...n,lifecycle:"terminal"}),ie(n)}var _n=class{queue=[];resolve=null;done=!1;hasPending(){return this.queue.length>0}push(e){this.queue.push(e),this.resolve&&(this.resolve(),this.resolve=null)}end(){this.done=!0,this.resolve&&(this.resolve(),this.resolve=null)}async*[Symbol.asyncIterator](){for(;;){for(;this.queue.length>0;)yield this.queue.shift();if(this.done)return;await new Promise(e=>{this.resolve=e})}}};import{appendFileSync as Xu}from"fs";import{tmpdir as ec}from"os";import{join as tc}from"path";var Bs=2e3;function Ue(t){return tc(ec(),`openclaw-agent-${t}.txt`)}function nc(t,e){if(!e)return;let n=e.split(`
|
|
60
|
+
`),[r="",...o]=n;t.length===0?t.push(r):t[t.length-1]+=r;for(let i of o)t.push(i)}function Fs(t,e,n){nc(t,n),t.length>Bs&&t.splice(0,t.length-Bs);try{Xu(Ue(e),n,"utf-8")}catch{}return t}var En=class{timers=new Map;get size(){return this.timers.size}set(e,n,r){this.clear(e);let o=setTimeout(r,n);o.unref?.(),this.timers.set(e,o)}clear(e){let n=this.timers.get(e);n&&(clearTimeout(n),this.timers.delete(e))}clearAll(){for(let e of this.timers.values())clearTimeout(e);this.timers.clear()}};var $n=class{constructor(e){this.deps=e}deps;waitingForInputFired=!1;lastTurnHadQuestion=!1;turnInProgress=!0;currentTurnText="";currentTurnPlanArtifact;beginUserTurn(){this.waitingForInputFired=!1,this.turnInProgress=!0,this.currentTurnText="",this.currentTurnPlanArtifact=void 0,this.lastTurnHadQuestion=!1}noteTextDelta(e,n){this.waitingForInputFired=!1,n||(this.lastTurnHadQuestion=!1),this.deps.appendOutput(e),this.currentTurnText+=this.currentTurnText?`
|
|
61
|
+
${e}`:e,this.deps.emitOutput(e)}noteToolCall(e){let{name:n,input:r,currentPermissionMode:o,permissionMode:i,planModeApproved:s}=e;if(n==="Write"){let a=r;typeof a?.file_path=="string"&&a.file_path.includes("/.claude/plans/")&&this.deps.setPlanFilePath(a.file_path)}n==="AskUserQuestion"?(this.lastTurnHadQuestion=!0,this.deps.applyInputRequested(),(o==="plan"||i==="plan")&&!s&&this.deps.markPendingPlanApproval("plan-mode")):(n==="ExitPlanMode"||n==="set_permission_mode")&&!s&&(this.lastTurnHadQuestion=!0,this.deps.markPendingPlanApproval("plan-mode")),this.deps.emitToolUse(n,r)}notePendingInput(){this.lastTurnHadQuestion=!0,this.deps.applyInputRequested(),this.waitingForInputFired||(this.waitingForInputFired=!0,this.deps.emitTurnEnd(!0))}clearResolvedPendingInput(e,n){if(!(!e||n?.requestId===e))return n}notePlanArtifact(e,n){if(this.currentTurnPlanArtifact=e,this.deps.setLatestPlanArtifact(e),!n)return;let r=e.markdown.trim();!r||this.currentTurnText.trim()===r||(this.deps.appendOutput(r),this.currentTurnText=r,this.deps.emitOutput(r))}noteSettingsChanged(e){let{oldMode:n,permissionMode:r,planModeApproved:o}=e;if(r)return r!=="plan"&&n==="plan"&&!o&&(this.deps.markPendingPlanApproval("plan-mode"),this.lastTurnHadQuestion=!0),r}finishSuccessfulTurn(e){let{currentPermissionMode:n,permissionMode:r,pendingPlanApproval:o,planModeApproved:i,pendingInputState:s,hasPendingMessages:a}=e,d=o;(n==="plan"||r==="plan")&&!d&&!i&&(this.deps.markPendingPlanApproval("plan-mode"),d=!0);let l=d||this.lastTurnHadQuestion||!!s;if(this.turnInProgress=a,l&&!this.waitingForInputFired)this.waitingForInputFired=!0,d||this.deps.markAwaitingUserInput(),this.deps.emitTurnEnd(!0);else if(!a&&!l){if(this.deps.queueWorktreeFinalizationPrompt?.()){this.turnInProgress=!0;return}this.deps.completeTurn(),this.deps.emitTurnEnd(!1)}}finishTerminalTurn(){this.turnInProgress=!1}finishInterruptedTurn(e){this.turnInProgress=e,this.waitingForInputFired=!1,this.lastTurnHadQuestion=!1,this.currentTurnText="",this.currentTurnPlanArtifact=void 0}resetAfterRun(){this.lastTurnHadQuestion=!1,this.currentTurnText="",this.currentTurnPlanArtifact=void 0}};var Dn=class{constructor(e){this.deps=e}deps;applyMessage(e,n){if(e.type==="backend_ref"){this.deps.clearStartupTimer(),this.deps.assignBackendRef({...e.ref}),this.deps.transitionRunning();return}if(e.type==="run_started"){e.runId&&this.deps.noteRunStarted(e.runId);return}if(e.type==="text_delta"){this.deps.noteTextDelta(e.text,n.pendingPlanApproval);return}if(e.type==="tool_call"){this.deps.noteToolCall({name:e.name,input:e.input,currentPermissionMode:n.currentPermissionMode,permissionMode:n.permissionMode,planModeApproved:n.planModeApproved});return}if(e.type==="pending_input"){this.deps.setPendingInputState(e.state),this.deps.notePendingInput();return}if(e.type==="pending_input_resolved"){this.deps.setPendingInputState(this.deps.clearResolvedPendingInput(e.requestId,n.pendingInputState));return}if(e.type==="plan_artifact"){this.deps.notePlanArtifact(e);return}if(e.type==="settings_changed"){let r=this.deps.noteSettingsChanged({oldMode:n.currentPermissionMode,permissionMode:e.permissionMode,planModeApproved:n.planModeApproved});r&&this.deps.setCurrentPermissionMode(r);return}if(e.type==="run_completed"){this.deps.handleRunCompleted(e.data);return}e.type}};me();var vc=120*1e3;function Vn(t){return t instanceof Error?t.message:String(t)}var Gn=class extends kc{id;name;harnessSessionId;backendRef;harness;harnessHandle;prompt;workdir;model;reasoningEffort;fastMode;systemPrompt;allowedTools;permissionMode;requestedPermissionMode;planApproval;codexApprovalPolicy;currentPermissionMode;pendingModeSwitch;resumeSessionId;forkSession;worktreePath;originalWorkdir;worktreeBranch;worktreeStrategy;worktreeBaseBranch;worktreePrTargetRepo;autoMergeParentSessionId;autoMergeConflictResolutionAttemptCount;autoMergeResolverSessionId;worktreePushRemote;worktreeDisposition;worktreePrUrl;worktreePrNumber;worktreeMerged;worktreeMergedAt;worktreeLifecycle;worktreeState="none";multiTurn;goalTaskId;messageStream;_status="starting";error;startedAt;completedAt;abortController;outputBuffer=[];result;costUsd=0;originChannel;originThreadId;originAgentId;originSessionKey;route;pendingInputState;pendingPlanApproval=!1;planApprovalContext;planDecisionVersion=0;actionablePlanDecisionVersion;canonicalPlanPromptVersion;approvalPromptRequiredVersion;approvalPromptVersion;approvalPromptStatus="not_sent";approvalPromptTransport="none";approvalPromptMessageKind="none";approvalPromptLastAttemptAt;approvalPromptDeliveredAt;approvalPromptFailedAt;planFilePath;killReason="unknown";planModeApproved=!1;turnRuntime;harnessEvents;worktreeFinalizationPromptIssued=!1;lifecycle="starting";approvalState="not_required";approvalExecutionState="not_plan_gated";approvalRationale;latestPlanArtifact;latestPlanArtifactVersion;runtimeState="live";deliveryState="idle";canUseTool;autoRespondCount=0;timers=new En;constructor(e,n){super(),this.id=e.sessionIdOverride??Mn(8),this.name=n,this.harness=e.harness?Dt(e.harness):ks(),this.prompt=e.prompt,this.workdir=e.workdir,this.model=e.model??Ze(this.harness.name),this.reasoningEffort=e.reasoningEffort??Ce(this.harness.name),this.fastMode=this.harness.name==="codex"?e.fastMode??Xe(this.harness.name):void 0,this.systemPrompt=e.systemPrompt,this.allowedTools=e.allowedTools,this.permissionMode=e.permissionMode??E.permissionMode,this.requestedPermissionMode=e.requestedPermissionMode??this.permissionMode,this.planApproval=e.planApproval??E.planApproval,this.codexApprovalPolicy=this.harness.name==="codex"?"never":void 0,this.currentPermissionMode=this.permissionMode,this.originChannel=e.originChannel,this.originThreadId=e.originThreadId,this.originAgentId=e.originAgentId,this.originSessionKey=e.originSessionKey,this.route=e.route?{...e.route}:void 0,this.backendRef=e.backendRef?{...e.backendRef}:void 0,this.resumeSessionId=e.resumeSessionId,this.forkSession=e.forkSession,this.multiTurn=e.multiTurn??!0,this.goalTaskId=e.goalTaskId,this.worktreeStrategy=e.worktreeStrategy,this.worktreeBaseBranch=e.worktreeBaseBranch,e.worktreePrTargetRepo&&(this.worktreePrTargetRepo=e.worktreePrTargetRepo),e.autoMergeParentSessionId&&(this.autoMergeParentSessionId=e.autoMergeParentSessionId),e.autoMergeConflictResolutionAttemptCount!==void 0&&(this.autoMergeConflictResolutionAttemptCount=e.autoMergeConflictResolutionAttemptCount),e.autoMergeResolverSessionId&&(this.autoMergeResolverSessionId=e.autoMergeResolverSessionId),this.canUseTool=e.canUseTool,this.startedAt=Date.now(),this.abortController=new AbortController,this.turnRuntime=new $n({appendOutput:r=>Fs(this.outputBuffer,this.id,r),emitOutput:r=>this.emit("output",this,r),emitToolUse:(r,o)=>this.emit("toolUse",this,r,o),emitTurnEnd:r=>this.emit("turnEnd",this,r),markPendingPlanApproval:r=>this.markPendingPlanApproval(r),markAwaitingUserInput:()=>this.markAwaitingUserInput(),applyInputRequested:()=>this.applyControlEvent({type:"input.requested"}),completeTurn:()=>{this.applyControlEvent({type:"terminal.entered"}),this.complete("done")},queueWorktreeFinalizationPrompt:()=>this.queueWorktreeFinalizationPrompt(),setPlanFilePath:r=>{this.planFilePath=r},setLatestPlanArtifact:r=>{this.latestPlanArtifact=r;let o=this.pendingPlanApproval?this.actionablePlanDecisionVersion??this.planDecisionVersion:void 0;this.latestPlanArtifactVersion=o&&o>0?o:void 0}}),this.harnessEvents=new Dn({clearStartupTimer:()=>this.clearTimer("startup"),assignBackendRef:r=>{this.backendRef=r,this.harnessSessionId=r.conversationId,r.worktreePath&&(this.worktreePath=r.worktreePath,this.originalWorkdir??=this.workdir,this.worktreeBranch??=ut(r.worktreePath),this.worktreeStrategy&&this.worktreeStrategy!=="off"&&this.applyControlEvent({type:"worktree.state_set",worktreeState:"provisioned"}))},noteRunStarted:r=>{this.backendRef&&(this.backendRef={...this.backendRef,runId:r})},transitionRunning:()=>{this._status==="starting"&&this.transition("running")},noteTextDelta:(r,o)=>this.turnRuntime.noteTextDelta(r,o),noteToolCall:r=>this.turnRuntime.noteToolCall(r),setPendingInputState:r=>{this.pendingInputState=r},notePendingInput:()=>this.turnRuntime.notePendingInput(),clearResolvedPendingInput:(r,o)=>this.turnRuntime.clearResolvedPendingInput(r,o),notePlanArtifact:r=>this.turnRuntime.notePlanArtifact(r.artifact,r.finalized),noteSettingsChanged:r=>this.turnRuntime.noteSettingsChanged(r),setCurrentPermissionMode:r=>{this.currentPermissionMode=r,this.applyControlEvent({type:"permission.mode_changed",currentPermissionMode:r})},handleRunCompleted:r=>{let o=r.outcome??(r.success?"completed":"failed");this.result={subtype:o==="interrupted"?"interrupted":r.success?"success":"error",duration_ms:r.duration_ms,total_cost_usd:r.total_cost_usd,num_turns:r.num_turns,result:r.result,is_error:o==="failed",session_id:r.session_id},this.costUsd=r.total_cost_usd;let i=this.multiTurn&&this.messageStream&&o==="interrupted",s=this.multiTurn&&this.messageStream&&o==="completed";i?(this.resetIdleTimer(),this.turnRuntime.finishInterruptedTurn(this.messageStream?.hasPending()===!0)):s?(this.resetIdleTimer(),this.turnRuntime.finishSuccessfulTurn({currentPermissionMode:this.currentPermissionMode,permissionMode:this.permissionMode,pendingPlanApproval:this.pendingPlanApproval,planModeApproved:this.planModeApproved,pendingInputState:this.pendingInputState,hasPendingMessages:this.messageStream?.hasPending()===!0})):(this.turnRuntime.finishTerminalTurn(),this.transitionToTerminal(o==="completed"?"completed":"failed")),this.turnRuntime.resetAfterRun(),this.pendingInputState=void 0}}),this.applyControlEvent({type:"initialize",hasWorktree:!!(this.worktreeStrategy&&this.worktreeStrategy!=="off")}),(e.planModeApproved!==void 0||e.approvalState!==void 0||e.approvalExecutionState!==void 0||e.approvalRationale!==void 0||e.pendingPlanApproval!==void 0||e.planApprovalContext!==void 0||e.planDecisionVersion!==void 0||e.actionablePlanDecisionVersion!==void 0||e.canonicalPlanPromptVersion!==void 0||e.approvalPromptRequiredVersion!==void 0||e.approvalPromptVersion!==void 0||e.approvalPromptStatus!==void 0||e.approvalPromptTransport!==void 0||e.approvalPromptMessageKind!==void 0||e.approvalPromptLastAttemptAt!==void 0||e.approvalPromptDeliveredAt!==void 0||e.approvalPromptFailedAt!==void 0)&&this.applyControlPatch({...e.planModeApproved!==void 0?{planModeApproved:e.planModeApproved}:{},...e.approvalState!==void 0?{approvalState:e.approvalState}:{},...e.approvalExecutionState!==void 0?{approvalExecutionState:e.approvalExecutionState}:{},...e.pendingPlanApproval!==void 0?{pendingPlanApproval:e.pendingPlanApproval}:{},...e.planApprovalContext!==void 0?{planApprovalContext:e.planApprovalContext}:{},...e.planDecisionVersion!==void 0?{planDecisionVersion:e.planDecisionVersion}:{},...e.actionablePlanDecisionVersion!==void 0?{actionablePlanDecisionVersion:e.actionablePlanDecisionVersion}:{},...e.canonicalPlanPromptVersion!==void 0?{canonicalPlanPromptVersion:e.canonicalPlanPromptVersion}:{},...e.approvalPromptRequiredVersion!==void 0?{approvalPromptRequiredVersion:e.approvalPromptRequiredVersion}:{},...e.approvalPromptVersion!==void 0?{approvalPromptVersion:e.approvalPromptVersion}:{},...e.approvalPromptStatus!==void 0?{approvalPromptStatus:e.approvalPromptStatus}:{},...e.approvalPromptTransport!==void 0?{approvalPromptTransport:e.approvalPromptTransport}:{},...e.approvalPromptMessageKind!==void 0?{approvalPromptMessageKind:e.approvalPromptMessageKind}:{},...e.approvalPromptLastAttemptAt!==void 0?{approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt}:{},...e.approvalPromptDeliveredAt!==void 0?{approvalPromptDeliveredAt:e.approvalPromptDeliveredAt}:{},...e.approvalPromptFailedAt!==void 0?{approvalPromptFailedAt:e.approvalPromptFailedAt}:{}}),this.approvalRationale=e.approvalRationale}get status(){return this._status}get harnessName(){return this.harness.name}get backendKind(){return this.harness.backendKind}get backendCapabilities(){return this.harness.capabilities}get backendConversationId(){return C(this)}approvalSnapshot(){return{requestedPermissionMode:this.requestedPermissionMode,currentPermissionMode:this.currentPermissionMode,approvalExecutionState:this.approvalExecutionState,approvalRationale:this.approvalRationale,planModeApproved:this.controlStateSnapshot().planModeApproved,pendingPlanApproval:this.pendingPlanApproval,planApprovalContext:this.planApprovalContext,planDecisionVersion:this.planDecisionVersion,actionablePlanDecisionVersion:this.actionablePlanDecisionVersion,canonicalPlanPromptVersion:this.canonicalPlanPromptVersion,approvalPromptRequiredVersion:this.approvalPromptRequiredVersion,approvalPromptVersion:this.approvalPromptVersion,approvalPromptStatus:this.approvalPromptStatus,approvalPromptTransport:this.approvalPromptTransport,approvalPromptMessageKind:this.approvalPromptMessageKind,approvalPromptLastAttemptAt:this.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:this.approvalPromptDeliveredAt,approvalPromptFailedAt:this.approvalPromptFailedAt,planApproval:this.planApproval,codexApprovalPolicy:this.codexApprovalPolicy}}worktreeSnapshot(){return{worktreePath:this.worktreePath,worktreeBranch:this.worktreeBranch,worktreeStrategy:this.worktreeStrategy,worktreeBaseBranch:this.worktreeBaseBranch,worktreePrTargetRepo:this.worktreePrTargetRepo,autoMergeParentSessionId:this.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:this.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:this.autoMergeResolverSessionId,worktreeLifecycle:this.worktreeLifecycle}}backendSnapshot(){return{harnessSessionId:this.harnessSessionId,backendRef:this.backendRef,harness:this.harnessName,backendKind:this.backendKind,backendConversationId:this.backendConversationId}}routingSnapshot(){return{route:this.route,originAgentId:this.originAgentId,originChannel:this.originChannel,originThreadId:this.originThreadId,originSessionKey:this.originSessionKey}}get waitingForInputFired(){return this.turnRuntime.waitingForInputFired}set waitingForInputFired(e){this.turnRuntime.waitingForInputFired=e}get lastTurnHadQuestion(){return this.turnRuntime.lastTurnHadQuestion}set lastTurnHadQuestion(e){this.turnRuntime.lastTurnHadQuestion=e}get turnInProgress(){return this.turnRuntime.turnInProgress}set turnInProgress(e){this.turnRuntime.turnInProgress=e}get currentTurnText(){return this.turnRuntime.currentTurnText}set currentTurnText(e){this.turnRuntime.currentTurnText=e}get currentTurnPlanArtifact(){return this.turnRuntime.currentTurnPlanArtifact}set currentTurnPlanArtifact(e){this.turnRuntime.currentTurnPlanArtifact=e}get duration(){return(this.completedAt??Date.now())-this.startedAt}get phase(){return this.lifecycle}get isExplicitlyResumable(){return this.status!=="running"&&this.status!=="completed"&&this.killReason!=="done"&&!!this.backendConversationId}transition(e){if(!Ws[this._status].includes(e))throw new Error(`Session state error: cannot transition from ${this._status} to ${e}. This is an internal error — please report it.`);let n=this._status;this._status=e,this.applyControlEvent({type:"status.transition",status:e}),this.emit("statusChange",this,e,n)}setTimer(e,n,r){this.timers.set(e,n,r)}clearTimer(e){this.timers.clear(e)}clearAllTimers(){this.timers.clearAll()}markPendingPlanApproval(e){let n=this.latestPlanArtifactVersion;this.approvalRationale=void 0,this.applyControlEvent({type:"plan.requested",context:e});let r=this.actionablePlanDecisionVersion??this.planDecisionVersion;this.currentTurnPlanArtifact&&r>0?(this.latestPlanArtifact=this.currentTurnPlanArtifact,this.latestPlanArtifactVersion=r):n!==r&&(this.latestPlanArtifact=void 0,this.latestPlanArtifactVersion=void 0)}clearPendingPlanApproval(){this.applyControlEvent({type:"plan.cleared"})}markAwaitingUserInput(){this.applyControlEvent({type:"input.requested"})}queueWorktreeFinalizationPrompt(){if(!this.multiTurn||!this.messageStream||!this.worktreePath||!this.worktreeStrategy||this.worktreeStrategy==="off"||this.worktreeFinalizationPromptIssued)return!1;let e=Ve(this.worktreePath);if(e.length===0)return!1;this.worktreeFinalizationPromptIssued=!0;let n=e.slice(0,20).map(i=>`- ${i}`).join(`
|
|
62
62
|
`),r=e.length>20?`
|
|
63
|
-
- ...and ${e.length-20} more`:"",
|
|
64
|
-
`);return this.messageStream.push(this.harness.buildUserMessage(
|
|
63
|
+
- ...and ${e.length-20} more`:"",o=["Your worktree still has uncommitted changes, so this session cannot finish yet.","",`Worktree: ${this.worktreePath}`,`Branch: ${this.worktreeBranch??"(unknown)"}`,"","Dirty entries:",`${n}${r}`,"","Before finishing, run `git status --short` in the worktree and do exactly one of these:","1. If these are real task changes, commit them on the worktree branch with `git add` and `git commit`.","2. If these are temporary or unrelated artifacts, remove or restore them so the worktree is clean.","3. If no repository changes were intended, leave the worktree clean and say that no changes were needed.","","Do not finish again until `git status --short` is clean or all real task changes are committed."].join(`
|
|
64
|
+
`);return this.messageStream.push(this.harness.buildUserMessage(o,this.backendConversationId??"")),!0}async start(){try{let e;this.multiTurn?(this.messageStream=new _n,this.messageStream.push(this.harness.buildUserMessage(this.prompt,"")),e=this.messageStream):e=this.prompt;let n=this.harness.launch({prompt:e,cwd:this.workdir,model:this.model,reasoningEffort:this.reasoningEffort,fastMode:this.fastMode,permissionMode:this.permissionMode,codexApprovalPolicy:this.codexApprovalPolicy,systemPrompt:this.systemPrompt,allowedTools:this.allowedTools,resumeSessionId:this.resumeSessionId,forkSession:this.forkSession,backendRef:this.backendRef,worktreeStrategy:this.worktreeStrategy,originalWorkdir:this.originalWorkdir??this.workdir,abortController:this.abortController,mcpServers:Vi(),canUseTool:this.canUseTool});this.harnessHandle=n,this.setTimer("startup",vc,()=>{this._status==="starting"&&this.kill("startup-timeout")})}catch(e){let n=e instanceof Error?e.message:String(e);this.transitionToTerminal("failed",{error:n});return}this.consumeMessages(this.harnessHandle.messages).catch(e=>{let n=e instanceof Error?e.message:String(e),r=e instanceof Error?e.stack:void 0;console.error(`[Session ${this.id}] consumeMessages error: ${n}`,r),this.isActive&&this.transitionToTerminal("failed",{error:n})})}async sendMessage(e){if(this._status!=="running")throw new Error(`Session is not running (status: ${this._status})`);this.resetIdleTimer(),this.turnRuntime.beginUserTurn(),this.applyControlEvent({type:"turn.started"});let n=e;if(this.pendingModeSwitch){let r=this.pendingModeSwitch,o=!1,i=!1;if(this.harnessHandle?.setPermissionMode)try{await this.harnessHandle.setPermissionMode(r),this.currentPermissionMode=r,this.applyControlEvent({type:"permission.mode_changed",currentPermissionMode:r}),this.pendingModeSwitch=void 0,i=!0,o=!0}catch(s){throw console.error(`[Session ${this.id}] setPermissionMode(${r}) FAILED: ${Vn(s)}`),this.markPendingPlanApproval(this.planApprovalContext??"plan-mode"),new Error(`Failed to switch permission mode to ${r}: ${Vn(s)}`)}else this.pendingModeSwitch=void 0,i=!0,o=!0,`${this.id}${this.currentPermissionMode}`;i&&(this.clearPendingPlanApproval(),r!=="plan"&&this.applyControlEvent({type:"plan.approved"})),o&&(n=`[SYSTEM: The user has approved your plan. Exit plan mode immediately and implement the changes with full permissions. Do not ask for further confirmation.]
|
|
65
65
|
|
|
66
66
|
${e}`)}else if((this.pendingPlanApproval||this.approvalState==="changes_requested")&&!this.planModeApproved&&(this.approvalState!=="changes_requested"&&this.applyControlEvent({type:"plan.changes_requested"}),n=`[SYSTEM: The user wants changes to your plan. Revise the plan based on their feedback below, then re-submit your revised plan for approval. Do NOT start implementing yet.]
|
|
67
67
|
|
|
68
|
-
${e}`,this.harnessHandle?.setPermissionMode))try{await this.harnessHandle.setPermissionMode("plan"),this.currentPermissionMode="plan",this.applyControlEvent({type:"permission.mode_changed",currentPermissionMode:"plan"})}catch(r){`${this.id}${
|
|
69
|
-
`);return e.at(-1)===""&&e.pop(),e}function
|
|
70
|
-
`)}function
|
|
71
|
-
`)}function
|
|
68
|
+
${e}`,this.harnessHandle?.setPermissionMode))try{await this.harnessHandle.setPermissionMode("plan"),this.currentPermissionMode="plan",this.applyControlEvent({type:"permission.mode_changed",currentPermissionMode:"plan"})}catch(r){`${this.id}${Vn(r)}`}if(this.multiTurn&&this.messageStream)this.messageStream.push(this.harness.buildUserMessage(n,this.backendConversationId??""));else if(this.harnessHandle?.streamInput){let r=this.harness.buildUserMessage(n,this.backendConversationId??"");async function*o(){yield r}await this.harnessHandle.streamInput(o())}else throw new Error("Session does not support follow-up messages (launched in single-turn mode).")}async interrupt(){return!this.turnInProgress||!this.harnessHandle?.interrupt?!1:(await this.harnessHandle.interrupt(),!0)}async submitPendingInputOption(e){if(!this.pendingInputState||!this.harnessHandle?.submitPendingInputOption)return!1;let n=await this.harnessHandle.submitPendingInputOption(e);return n&&(this.waitingForInputFired=!1),n}async submitPendingInputText(e){if(!this.pendingInputState||!this.harnessHandle?.submitPendingInputText)return!1;let n=await this.harnessHandle.submitPendingInputText(e);return n&&(this.waitingForInputFired=!1),n}switchPermissionMode(e){this.pendingModeSwitch=e}get isActive(){return this._status==="starting"||this._status==="running"}kill(e){this.transitionToTerminal("killed",{reason:e})}complete(e="done"){this.transitionToTerminal("completed",{reason:e})}incrementAutoRespond(){this.autoRespondCount++}resetAutoRespond(){this.autoRespondCount=0}getOutput(e){return e===void 0?this.outputBuffer.slice():this.outputBuffer.slice(-e)}resetIdleTimer(){if(!this.multiTurn)return;let e=(E.idleTimeoutMinutes??15)*60*1e3;this.setTimer("idle",e,()=>{this._status==="running"&&(this.applyControlEvent({type:"terminal.entered",suspended:!0}),this.kill("idle-timeout"))})}teardown(){this.clearAllTimers(),this.completedAt||(this.completedAt=Date.now()),this.messageStream&&this.messageStream.end(),this.harnessHandle?.interrupt&&this.harnessHandle.interrupt().catch(e=>{`${this.id}${Vn(e)}`}),this.abortController.abort(),this.applyControlEvent({type:"terminal.entered",suspended:this.lifecycle==="suspended"})}transitionToTerminal(e,n={}){this.isActive&&(this.turnInProgress=!1,n.reason&&(this.killReason=n.reason),n.error!==void 0&&(this.error=n.error),this.completedAt=Date.now(),this.applyControlEvent({type:"terminal.entered",suspended:e==="killed"&&n.reason==="idle-timeout"}),this.transition(e),this.teardown())}async consumeMessages(e){for await(let n of e){if(!this.isActive)break;this.resetIdleTimer(),this.harnessEvents.applyMessage(n,{pendingPlanApproval:this.pendingPlanApproval,currentPermissionMode:this.currentPermissionMode,permissionMode:this.permissionMode,planModeApproved:this.planModeApproved,pendingInputState:this.pendingInputState})}}controlStateSnapshot(){return{status:this._status,lifecycle:this.lifecycle,approvalState:this.approvalState,approvalExecutionState:this.approvalExecutionState,worktreeState:this.worktreeState,runtimeState:this.runtimeState,deliveryState:this.deliveryState,requestedPermissionMode:this.requestedPermissionMode,currentPermissionMode:this.currentPermissionMode,pendingPlanApproval:this.pendingPlanApproval,planApprovalContext:this.planApprovalContext,planDecisionVersion:this.planDecisionVersion,actionablePlanDecisionVersion:this.actionablePlanDecisionVersion,canonicalPlanPromptVersion:this.canonicalPlanPromptVersion,approvalPromptRequiredVersion:this.approvalPromptRequiredVersion,approvalPromptVersion:this.approvalPromptVersion,approvalPromptStatus:this.approvalPromptStatus,approvalPromptTransport:this.approvalPromptTransport,approvalPromptMessageKind:this.approvalPromptMessageKind,approvalPromptLastAttemptAt:this.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:this.approvalPromptDeliveredAt,approvalPromptFailedAt:this.approvalPromptFailedAt,planModeApproved:this.planModeApproved}}applyControlEvent(e){let n=Fo(this.controlStateSnapshot(),e);this.applyControlState(n)}applyControlPatch(e){let n=Ls(this.controlStateSnapshot(),e);this.applyControlState(n)}setControlField(e,n){this.applyControlPatch({[e]:n})}applyControlState(e){let n=this.lifecycle;this.lifecycle=e.lifecycle,this.approvalState=e.approvalState,this.approvalExecutionState=e.approvalExecutionState,this.worktreeState=e.worktreeState,this.runtimeState=e.runtimeState,this.deliveryState=e.deliveryState,this.pendingPlanApproval=e.pendingPlanApproval,this.planApprovalContext=e.planApprovalContext,this.planDecisionVersion=e.planDecisionVersion,this.actionablePlanDecisionVersion=e.actionablePlanDecisionVersion,this.canonicalPlanPromptVersion=e.canonicalPlanPromptVersion,this.approvalPromptRequiredVersion=e.approvalPromptRequiredVersion,this.approvalPromptVersion=e.approvalPromptVersion,this.approvalPromptStatus=e.approvalPromptStatus,this.approvalPromptTransport=e.approvalPromptTransport,this.approvalPromptMessageKind=e.approvalPromptMessageKind,this.approvalPromptLastAttemptAt=e.approvalPromptLastAttemptAt,this.approvalPromptDeliveredAt=e.approvalPromptDeliveredAt,this.approvalPromptFailedAt=e.approvalPromptFailedAt,this.planModeApproved=e.planModeApproved,n!==this.lifecycle&&this.emit("lifecycleChange",this,this.lifecycle,n)}};var wc=50,Pc=1,bc=new Set(["starting","running","completed","failed","killed"]),Ac=5,Rc=1440*60*1e3,Hn=new Set(["merged","released","dismissed","no_change"]);function Ic(t){let e=Number(t);return!Number.isFinite(e)||e<Pc?wc:Math.floor(e)}function xc(t){return typeof t=="string"&&bc.has(t)}function Tc(t){let e=t.split(`
|
|
69
|
+
`);return e.at(-1)===""&&e.pop(),e}function zo(t){return t.backendRef?.conversationId??t.harnessSessionId}function Cc(t,e){return e&&Hn.has(e)&&(!t||!Hn.has(t))?e:t??e}function Mc(t,e){return e&&Hn.has(e.state)&&(!t||!Hn.has(t.state))?e:t??e}function ra(t,e,n){let r=na(t,"utf-8"),o=Tc(r);return e.full?o:o.slice(-n)}function _c(t,e,n){if(t.status!=="starting"&&t.status!=="running")return null;let r=Ue(t.id);if(!jo(r))return null;try{return ra(r,e,n)}catch{return null}}function Ec(t){let e=we(t.duration),n=` | Cost: $${t.costUsd.toFixed(4)}`,r=t.phase?` | Phase: ${t.phase}`:"",o=t.lifecycle&&t.lifecycle!==t.phase?` | Lifecycle: ${t.lifecycle}`:"";return[`Session: ${t.name} [${t.id}] | Status: ${t.status.toUpperCase()}${r}${o}${n} | Duration: ${e}`,`${"─".repeat(60)}`].join(`
|
|
70
|
+
`)}function oa(t,e){let n=t.name||t.sessionId||zo(t)||"unknown",r=t.lifecycle?` | Phase: ${t.lifecycle}`:"";return[`Session: ${n} | Status: ${t.status.toUpperCase()}${r} | Cost: $${t.costUsd.toFixed(4)}`,e,`${"─".repeat(60)}`].join(`
|
|
71
|
+
`)}function $c(t){return`(retrieved from ${t.outputPath} — evicted from runtime cache — showing persisted output)`}function Dc(t){return t.outputPath?`(persisted session metadata recovered; output file is unavailable at ${t.outputPath})`:"(persisted session metadata recovered; no output file was recorded before the runtime was interrupted)"}function ta(t,e){let n=oa(t,Dc(t)),r=zo(t),o=r?`
|
|
72
72
|
Backend session: ${r}`:"";return`${n}
|
|
73
|
-
(no persisted output available: ${e})${
|
|
73
|
+
(no persisted output available: ${e})${o}`}function Oc(t){let e=[];return t.error&&e.push(`Error: ${t.error}`),t.result?.result&&e.push(`Result: ${t.result.result}`),t.result&&e.push(`Result status: ${t.result.subtype}`),e.length>0?`
|
|
74
74
|
(no output yet)
|
|
75
75
|
${e.join(`
|
|
76
76
|
`)}`:`
|
|
77
|
-
(no output yet)`}function
|
|
78
|
-
`),c=
|
|
77
|
+
(no output yet)`}function jn(t,e,n={}){let r=Ic(n.lines),o=t.resolve(e);if(!o){let l=t.getPersistedSession(e);if(l?.outputPath&&jo(l.outputPath))try{let u=ra(l.outputPath,n,r).join(`
|
|
78
|
+
`),c=oa(l,$c(l));return u?`${c}
|
|
79
79
|
${u}`:`${c}
|
|
80
|
-
(output file was empty)`}catch(u){let c=u instanceof Error?u.message:String(u);return`Error: Session "${e}" was cleaned up (expired) and output file could not be read: ${c}`}return l?.outputPath?
|
|
80
|
+
(output file was empty)`}catch(u){let c=u instanceof Error?u.message:String(u);return`Error: Session "${e}" was cleaned up (expired) and output file could not be read: ${c}`}return l?.outputPath?ta(l,`output file is missing at ${l.outputPath}`):l?ta(l,"no outputPath is stored for this recovered session"):`Error: Session "${e}" not found.`}let i=_c(o,n,r),s=i&&i.length>0?i:n.full?o.getOutput():o.getOutput(r),a=Ec(o),d=s.length===0?`${a}${Oc(o)}`:`${a}
|
|
81
81
|
${s.join(`
|
|
82
|
-
`)}`;if(
|
|
82
|
+
`)}`;if(o.pendingPlanApproval&&o.planFilePath)try{if(jo(o.planFilePath)){let l=na(o.planFilePath,"utf-8"),u="─".repeat(60);return`${d}
|
|
83
83
|
${u}
|
|
84
|
-
Plan file: ${
|
|
84
|
+
Plan file: ${o.planFilePath}
|
|
85
85
|
${u}
|
|
86
|
-
${l}`}}catch{}return d}function
|
|
86
|
+
${l}`}}catch{}return d}function zn(t,e="all",n,r={}){let o=t.listPersistedSessions()??[],s=Wc(t.list("all"),o);if(e!=="all"&&(s=s.filter(a=>a.status===e)),n&&(s=s.filter(a=>a.originChannel===n)),r.full){let a=Date.now()-Rc;s=s.filter(d=>(d.startedAt??0)>=a)}else s=s.slice(0,Ac);return s.length===0?"No sessions found.":s.map(a=>Is(a)).join(`
|
|
87
87
|
|
|
88
|
-
`)}function
|
|
88
|
+
`)}function Wc(t,e){let n=new Map;for(let r of e){if(!xc(r.status))continue;let o=r.completedAt??Date.now(),i=r.createdAt??o,s=zo(r),a=r.sessionId??`persisted:${s??r.harnessSessionId}`;n.set(a,{id:r.sessionId??s??r.harnessSessionId,name:r.name||r.sessionId||s||r.harnessSessionId,status:r.status,startedAt:r.createdAt??0,completedAt:r.completedAt,duration:Math.max(0,o-i),prompt:r.prompt??"",workdir:r.workdir??"(unknown)",costUsd:r.costUsd??0,multiTurn:!0,phase:r.lifecycle??r.status,lifecycle:r.lifecycle,resumable:r.resumable,harness:r.harness,model:r.model,backendRef:r.backendRef,harnessSessionId:r.harnessSessionId,requestedPermissionMode:r.requestedPermissionMode,currentPermissionMode:r.currentPermissionMode,approvalExecutionState:r.approvalExecutionState,originChannel:r.originChannel,originThreadId:r.originThreadId,worktreePath:r.worktreePath,worktreeBranch:r.worktreeBranch,worktreeStrategy:r.worktreeStrategy,worktreeState:r.worktreeState,worktreeLifecycle:r.worktreeLifecycle,worktreeMerged:r.worktreeMerged,worktreeMergedAt:r.worktreeMergedAt,worktreePrUrl:r.worktreePrUrl,recovered:!0})}for(let r of t){let o=n.get(r.id);n.set(r.id,{id:r.id,name:r.name,status:r.status,startedAt:r.startedAt,completedAt:r.completedAt,duration:r.duration,prompt:r.prompt,workdir:r.originalWorkdir??r.workdir,costUsd:r.costUsd,multiTurn:r.multiTurn,phase:r.phase,lifecycle:r.lifecycle,resumable:r.isExplicitlyResumable,harness:r.harnessName,model:r.model,backendRef:r.backendRef,harnessSessionId:r.harnessSessionId,requestedPermissionMode:r.requestedPermissionMode,currentPermissionMode:r.currentPermissionMode,approvalExecutionState:r.approvalExecutionState,originChannel:r.originChannel,originThreadId:r.originThreadId,worktreePath:r.worktreePath,worktreeBranch:r.worktreeBranch,worktreeStrategy:r.worktreeStrategy,worktreeState:Cc(r.worktreeState,o?.worktreeState),worktreeLifecycle:Mc(r.worktreeLifecycle,o?.worktreeLifecycle),worktreeMerged:r.worktreeMerged??o?.worktreeMerged,worktreeMergedAt:r.worktreeMergedAt??o?.worktreeMergedAt,worktreePrUrl:r.worktreePrUrl??o?.worktreePrUrl,recovered:!1})}return[...n.values()].sort((r,o)=>(o.startedAt??0)-(r.startedAt??0))}function Nc(t){if(!t||typeof t!="object")return"all";let e=t.status;switch(e){case"running":case"completed":case"failed":case"killed":case"all":return e;default:return"all"}}function ia(t){return{name:"agent_sessions",description:"List coding agent sessions with their status and progress. By default, shows the 5 most recent sessions; set `full` to show all sessions from the last 24 hours.",parameters:m.Object({status:m.Optional(m.Union([m.Literal("all"),m.Literal("running"),m.Literal("completed"),m.Literal("failed"),m.Literal("killed")],{description:'Filter by status (default "all")'})),full:m.Optional(m.Boolean({description:"Show all sessions from the last 24h instead of just the most recent 5"}))}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let r=Nc(n),o=t?.workspaceDir?Mt(t.workspaceDir):void 0,i=!!(n&&typeof n=="object"&&n.full===!0);return{content:[{type:"text",text:zn(v,r,o,{full:i})}]}}}}X();O();function Qn(t,e,n){let r=t.resolve(e);if(!r){let o=t.getPersistedSession(e);if(!o)return`Error: Session "${e}" not found.`;if(o.status==="killed"&&o.lifecycle==="suspended"){let i=n==="completed";if(t.updatePersistedSession(e,{status:i?"completed":"killed",lifecycle:"terminal",runtimeState:"stopped",resumable:!1,killReason:i?"done":"user"}))return i?`Recovered session ${o.name} [${o.sessionId??o.harnessSessionId}] marked as completed. No live process was running.`:`Recovered session ${o.name} [${o.sessionId??o.harnessSessionId}] dismissed. No live process was running.`}return`Session ${o.name} [${o.sessionId??o.harnessSessionId}] is a persisted ${o.status} record with no live process to kill.`}return r.status==="completed"||r.status==="failed"||r.status==="killed"?`Session ${r.name} [${r.id}] is already ${r.status}. No action needed.`:n==="completed"?(r.complete(),`Session ${r.name} [${r.id}] marked as completed.`):(t.kill(r.id),`Session ${r.name} [${r.id}] has been terminated.`)}function Lc(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session!="string"?!1:e.reason===void 0?!0:e.reason==="completed"||e.reason==="killed"}function sa(t){return{name:"agent_kill",description:"Terminate or complete a running coding agent session by name or ID. Use reason='completed' to mark a session as successfully completed instead of killed.",parameters:m.Object({session:m.String({description:"Session name or ID to terminate"}),reason:m.Optional(m.Union([m.Literal("completed"),m.Literal("killed")],{description:"Reason for closing the session. 'completed' marks it as successfully done (sends ✅ notification). 'killed' (default) terminates it."}))}),async execute(e,n){return v?Lc(n)?{content:[{type:"text",text:Qn(v,n.session,n.reason)}]}:{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, reason? }."}]}:{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]}}}}X();O();function Bc(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function Jn(t){return{name:"agent_output",description:"Show recent output from a coding agent session (by name or ID).",parameters:m.Object({session:m.String({description:"Session name or ID to get output from"}),lines:m.Optional(m.Number({description:"Number of recent lines to show (default 50)"})),full:m.Optional(m.Boolean({description:"Show all available output"}))}),async execute(e,n){return v?Bc(n)?{content:[{type:"text",text:jn(v,n.session,{full:n.full,lines:n.lines})}]}:{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, lines?, full? }."}]}:{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]}}}}X();O();te();Q();var Fc=10;function Jo(t){return t instanceof Error?t.message:String(t)}function je(t){return W(t)??t.harnessSessionId??"unknown-session"}function qc(t){if(!(!t.worktreeStrategy||t.worktreeStrategy==="off"))return vn(t)??W(t)??C(t)}function aa(t){return t.status!=="running"&&!!t.pendingPlanApproval&&!!C(t)}function Kc(t){let e=t.trim().toLowerCase().replace(/[.!?]+$/g,"").trim();if(e==="approve"||e==="approved")return"approve";if(e==="revise"||e==="request changes"||e==="changes requested")return"revise";if(e==="reject"||e==="rejected")return"reject"}function Gt(t,e,n){let r=e==="completed"?`This session is closed by default. Launch a fresh session, or fork from prior context with agent_launch(resume_session_id='${je(t)}', fork_session=true, prompt='<new task>').`:e==="legacy_non_resumable"?`Persisted historical backend state is intentionally non-resumable here. Launch fresh, or fork with agent_launch(resume_session_id='${je(t)}', fork_session=true, prompt='<new task>').`:e==="missing_backend_state"?`No resumable backend state is available. Launch a fresh session, or fork from prior context with agent_launch(resume_session_id='${je(t)}', fork_session=true, prompt='<new task>').`:`Use agent_respond(session='${je(t)}', message='<next instruction>') to continue the running session.`,o=n?` ${n}`:"";return{text:`Resume unavailable for session ${t.name} [${je(t)}] (${e}).${o} ${r}`,isError:!0}}async function da(t,e,n){try{let r={prompt:e.prompt,sessionIdOverride:vn(e),workdir:e.workdir,name:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,worktreeStrategy:e.worktreeStrategy,multiTurn:!0,originChannel:e.originChannel,originThreadId:e.originThreadId,originAgentId:e.originAgentId,originSessionKey:e.originSessionKey,route:e.route,permissionMode:e.currentPermissionMode,requestedPermissionMode:e.requestedPermissionMode??e.currentPermissionMode,planApproval:e.planApproval,codexApprovalPolicy:e.codexApprovalPolicy,harness:"harnessName"in e?e.harnessName:e.harness},o=await t.spawnAndAwaitRunning(r,{notifyLaunch:!1});return t.notifySession(o,`▶️ [${o.name}] Relaunched fresh`),{text:`Session ${e.name} was relaunched fresh — it was killed during startup before the harness initialized. New session: ${o.name} [${o.id}].`}}catch(r){return{text:`Error relaunching session ${e.name} [${je(e)}]: ${Jo(r)}`,isError:!0}}}var Uc=`[SYSTEM: The user has approved your plan. Exit plan mode immediately and implement the changes with full permissions. Do not ask for further confirmation.]
|
|
89
89
|
|
|
90
|
-
`;function
|
|
91
|
-
`)}}let l=!1;e.interrupt&&(l=await n.interrupt());let u=!!(e.approve&&
|
|
90
|
+
`;function la(t){let e=t?.replace(/\s+/g," ").trim();if(e)return re(e,240)}function Qo(t){if(t.approvalState==="changes_requested"&&!Yn(t))return`Plan changes were already requested for session ${t.name}. Wait for the revised plan before approving.`;if(t.approvalState==="rejected")return`Plan for session ${t.name} was already rejected.`}function Yn(t){return t.pendingPlanApproval?(t.approvalState==="changes_requested"?t.actionablePlanDecisionVersion:t.actionablePlanDecisionVersion??t.planDecisionVersion)>0:!1}function Vc(t){return Qo(t)?!1:Yn(t)||t.currentPermissionMode==="plan"}function Gc(t,e){let n=t.updatePersistedSession;if(typeof n!="function")return;let r=e.controlStateSnapshot();n.call(t,e.id,{lifecycle:r.lifecycle,approvalState:r.approvalState,approvalExecutionState:r.approvalExecutionState,runtimeState:r.runtimeState,requestedPermissionMode:r.requestedPermissionMode,currentPermissionMode:r.currentPermissionMode,pendingPlanApproval:r.pendingPlanApproval,planApprovalContext:r.planApprovalContext,planDecisionVersion:r.planDecisionVersion,actionablePlanDecisionVersion:r.actionablePlanDecisionVersion,planModeApproved:r.planModeApproved,approvalRationale:e.approvalRationale})}function Hc(t){return(t.planDecisionVersion??0)+1}function ua(t,e){let n={approvalState:e,lifecycle:e==="rejected"?"terminal":"awaiting_user_input",pendingPlanApproval:!1,planApprovalContext:void 0,planDecisionVersion:Hc(t),actionablePlanDecisionVersion:void 0,canonicalPlanPromptVersion:void 0,approvalPromptRequiredVersion:void 0,approvalPromptVersion:void 0,approvalPromptStatus:"not_sent",approvalPromptTransport:"none",approvalPromptMessageKind:"none",approvalPromptLastAttemptAt:void 0,approvalPromptDeliveredAt:void 0,approvalPromptFailedAt:void 0};return e==="rejected"&&(n.runtimeState="stopped"),n}function ca(t,e){let n=t;typeof n.applyControlPatch=="function"&&n.applyControlPatch(e),Object.assign(t,e)}function Yo(t,e){let n=t.resolve(e),r=n?void 0:t.getPersistedSession(e),o=n??r,i=o?.name??e;if(t.clearPlanDecisionTokens?.(e),!o)return{text:`Plan rejected for [${i}].`,isError:!1};let s=ua(o,"rejected");return n?(ca(n,s),t.updatePersistedSession?.(e,s),t.kill(n.id,"user"),{text:`Plan rejected for [${n.name}]. Session stopped.`}):(t.updatePersistedSession?.(e,s),{text:`Plan rejected for [${i}]. Session remains stopped.`})}function Zo(t,e){let n=t.resolve(e),r=n?void 0:t.getPersistedSession(e),o=n??r,i=o?.name??e;if(t.clearPlanDecisionTokens?.(e),o){let s=ua(o,"changes_requested");n&&ca(n,s),t.updatePersistedSession?.(e,s)}return{text:`Type your revision feedback for [${i}] and I'll forward it to the agent.`}}async function jc(t,e,n,r={}){let o=Nt(e);if(!(o.kind==="resume"||aa(e)))return;let s=!!(r.approve&&Vc(e)),a=s?la(r.approvalRationale):void 0;try{if(o.kind!=="resume")return o.kind==="relaunch"?da(t,e,n):Gt(e,o.reason);let d={prompt:s?Uc+n:n,sessionIdOverride:o.stableSessionId,workdir:e.workdir,name:e.name,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,resumeSessionId:o.resumeSessionId,resumeWorktreeFrom:qc(e),worktreeStrategy:e.worktreeStrategy,worktreeBaseBranch:e.worktreeBaseBranch,worktreePrTargetRepo:e.worktreePrTargetRepo,multiTurn:!0,originChannel:e.originChannel,originThreadId:e.originThreadId,originAgentId:e.originAgentId,originSessionKey:e.originSessionKey,route:e.route,permissionMode:s?"bypassPermissions":e.currentPermissionMode,requestedPermissionMode:e.requestedPermissionMode??e.currentPermissionMode,planApproval:e.planApproval,codexApprovalPolicy:e.codexApprovalPolicy,pendingPlanApproval:s?!1:e.pendingPlanApproval,planApprovalContext:e.planApprovalContext,planDecisionVersion:e.planDecisionVersion,actionablePlanDecisionVersion:s?void 0:e.actionablePlanDecisionVersion,canonicalPlanPromptVersion:e.canonicalPlanPromptVersion,approvalPromptRequiredVersion:e.approvalPromptRequiredVersion,approvalPromptVersion:e.approvalPromptVersion,approvalPromptStatus:e.approvalPromptStatus,approvalPromptTransport:e.approvalPromptTransport,approvalPromptMessageKind:e.approvalPromptMessageKind,approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:e.approvalPromptDeliveredAt,approvalPromptFailedAt:e.approvalPromptFailedAt,...s?{approvalState:"approved",approvalExecutionState:"approved_then_implemented",approvalRationale:a,planModeApproved:!0}:{},harness:"harnessName"in e?e.harnessName:e.harness},l=await t.spawnAndAwaitRunning(d,{notifyLaunch:!1});return s?(t.notifySession(l,`👍 [${l.name}] Plan approved (resumed)`,"plan-approved"),{text:`Plan approved for session ${l.name} [${l.id}]. Session resumed in bypassPermissions mode. Use agent_output to see the response.`}):(t.notifySession(l,`▶️ [${l.name}] Auto-resumed`),{text:`Auto-resumed session ${l.name} [${l.id}]. Use agent_output to see the response.`})}catch(d){return Gt(e,"missing_backend_state",`Backend resume failed: ${Jo(d)}`)}}async function he(t,e){let n=t.resolve(e.session),r=n?void 0:t.getPersistedSession(e.session);if(!n&&!r)return{text:`Error: Session "${e.session}" not found.`,isError:!0};let o=n??r,i=o.status==="running"?{kind:"direct"}:Nt(o),s=!e.approve&&o.lifecycle==="awaiting_plan_decision"&&o.pendingPlanApproval&&e.userInitiated?Kc(e.message):void 0;if(s==="approve")return he(t,{...e,message:"Approved. Go ahead.",approve:!0});if(s==="revise")return Zo(t,n?.id??r?.sessionId??e.session);if(s==="reject")return Yo(t,n?.id??r?.sessionId??e.session);if(e.approve){let d=Qo(o);if(d)return{text:d,isError:!0}}if(i.kind==="resume"||aa(o)){let d=await jc(t,o,e.message,{approve:e.approve,approvalRationale:e.approvalRationale});if(d)return d}else{if(i.kind==="relaunch")return da(t,o,e.message);if(i.kind==="unavailable")return Gt(o,i.reason)}if(!n)return Wt(r)?Gt(r,"completed"):{text:`Error: Session ${r.name} [${je(r)}] is not running (status: ${r.status}). Cannot send a message to a non-running session.`,isError:!0};if(n.status!=="running")return Wt(n)?Gt(n,"completed"):{text:`Error: Session ${n.name} [${n.id}] is not running (status: ${n.status}). Cannot send a message to a non-running session.`,isError:!0};let a=E.maxAutoResponds??Fc;if(e.userInitiated)n.resetAutoRespond();else if(n.autoRespondCount>=a)return{text:`⚠️ Auto-respond limit reached (${n.autoRespondCount}/${a}). Ask the user to provide the answer for session ${n.name}. Then call agent_respond with their answer and set userInitiated: true to reset the counter.`};try{if(e.approve){let g=Qo(n);if(g)return{text:g,isError:!0}}if(!e.approve&&n.pendingInputState?.allowsFreeText&&await n.submitPendingInputText?.(e.message)===!0){if(e.userInitiated){let h=re(e.message,100);t.notifySession(n,`↪️ [${n.name}] "${h}"`,"agent-respond")}e.userInitiated||n.incrementAutoRespond();let g=re(e.message,80);return{text:[`Pending input answered for session ${n.name} [${n.id}].`,` Message: "${g}"`,"Use agent_output to see the response."].join(`
|
|
91
|
+
`)}}let l=!1;e.interrupt&&(l=await n.interrupt());let u=!!(e.approve&&Yn(n)),c=u?la(e.approvalRationale):void 0,p="";if(e.approve&&Yn(n)?(n.switchPermissionMode("bypassPermissions"),n.approvalRationale=c):e.approve&&n.currentPermissionMode==="default"?n.switchPermissionMode("bypassPermissions"):e.approve&&n.currentPermissionMode==="bypassPermissions"?p=`
|
|
92
92
|
ℹ️ approve=true was set but session is already in bypassPermissions mode.`:e.approve?p=`
|
|
93
93
|
⚠️ approve=true was set but session has no pending plan approval.`:(n.pendingPlanApproval||n.approvalState==="changes_requested")&&(p=`
|
|
94
|
-
ℹ️ Session has a pending plan — sending as revision feedback. The agent will revise and re-submit. Set approve=true to approve instead.`),await n.sendMessage(e.message),u
|
|
95
|
-
`)}}catch(d){return{text:`Error sending message to session ${n.name} [${n.id}]: ${Bi(d)}`,isError:!0}}}function Oc(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.message=="string"&&(e.approval_rationale===void 0||typeof e.approval_rationale=="string")}function Ys(t){return{name:"agent_respond",description:"Send a follow-up message to a running coding agent session. The session must be running. All sessions are multi-turn.",parameters:m.Object({session:m.String({description:"Session name or ID to respond to"}),message:m.String({description:"The message to send to the session"}),interrupt:m.Optional(m.Boolean({description:"If true, interrupt the current turn before sending the message. Useful to redirect the session mid-response."})),userInitiated:m.Optional(m.Boolean({description:"Set to true when the message comes from the user (not auto-generated). Resets the auto-respond counter and bypasses the auto-respond limit."})),approve:m.Optional(m.Boolean({description:"Set to true to escalate session permissions to bypassPermissions. Works in two scenarios: (1) approve a pending plan in plan mode, or (2) escalate a default-mode session to skip remaining OpenClaw approval checkpoints. No-op if already in bypassPermissions mode. In plan mode without a pending plan, this flag is ignored."})),approval_rationale:m.Optional(m.String({description:"Optional structured rationale for a direct delegated plan approval. Use this instead of embedding the rationale in message text when approve=true for a pending plan."}))}),async execute(e,n){if(!k)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!Oc(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, message, interrupt?, userInitiated?, approve?, approval_rationale? }."}]};let r=await pe(k,{session:n.session,message:n.message,interrupt:n.interrupt,userInitiated:n.userInitiated,approve:n.approve,approvalRationale:n.approval_rationale});return{isError:r.isError??!1,content:[{type:"text",text:r.text}]}}}}J();E();function Wc(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.summary=="string"}function Zs(t){return{name:"agent_request_plan_approval",description:"Send a plan-approval decision prompt to the user for a session that is already waiting on plan approval. Reuses the plugin's Approve/Revise/Reject buttons so the user can decide directly from the message.",parameters:m.Object({session:m.String({description:"Session name or ID awaiting plan approval"}),summary:m.String({description:"Concise user-facing summary of scope, risk, and any concerns that should accompany the approval buttons"})}),async execute(e,n){if(!k)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!Wc(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, summary }."}]};let r=k.requestPlanApprovalFromUser(n.session,n.summary);return{isError:r.startsWith("Error:"),content:[{type:"text",text:r}]}}}}J();E();function Nc(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.summary=="string"}function Xs(t){return{name:"agent_request_worktree_decision",description:"Send a worktree Merge/Open PR/Later/Discard decision prompt to the user for a delegated worktree session that is awaiting human choice.",parameters:m.Object({session:m.String({description:"Delegated session name or ID awaiting a worktree decision"}),summary:m.String({description:"Concise user-facing summary of scope, risk, and why human choice is needed"})}),async execute(e,n){if(!k)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!Nc(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, summary }."}]};let r=k.requestWorktreeDecisionFromUser(n.session,n.summary);return{isError:r.startsWith("Error:"),content:[{type:"text",text:r}]}}}}J();E();Y();var Ki=["off","manual","ask","delegate","auto-merge","auto-pr"],Jn=new Set(Ki),Lc=["low","medium","high","xhigh","max"],ea=new Set(Lc);function Bc(t){return typeof t=="string"&&Jn.has(t)}var Fc=m.Union(Ki.map(t=>m.Literal(t)),{description:"Optional worktree strategy for the planning session. Use auto-pr when the follow-up should branch and open/update a PR after approved implementation."});function qc(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.offer_id=="string"&&typeof e.offer_text=="string"&&typeof e.plan_prompt=="string"&&typeof e.plan_workdir=="string"&&(e.plan_worktree_strategy==null||Bc(e.plan_worktree_strategy))&&(e.plan_name==null||typeof e.plan_name=="string")&&(e.target_channel==null||typeof e.target_channel=="string")&&(e.target_thread_id==null||typeof e.target_thread_id=="string"||typeof e.target_thread_id=="number")&&(e.target_session_key==null||typeof e.target_session_key=="string")}function Kc(t,e){let n=Je(t,e.target_channel,e.target_session_key);if(n)return e.target_thread_id!=null&&(n.threadId=String(e.target_thread_id)),n}async function Uc(t,e){if(!k)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let n=Kc(t,e);return!n?.provider||!n.target?{content:[{type:"text",text:"Error: Could not resolve a direct delivery route for the plan offer."}]}:(k.sendPlanOffer({offerId:e.offer_id,route:n,text:e.offer_text,planName:e.plan_name??e.offer_id,planPrompt:e.plan_prompt,planWorkdir:e.plan_workdir,planWorktreeStrategy:e.plan_worktree_strategy}),{content:[{type:"text",text:`Interactive plan offer queued for ${n.provider}|${n.target}${n.threadId?`#${n.threadId}`:""}.`}]})}function ta(t){return{name:"agent_send_plan_offer",description:"Post a user-facing message to the current or explicit chat route with human-gated Start Plan and Dismiss inline buttons. Use this when an external workflow wants the user to open a plan-only code-agent session from the message.",parameters:m.Object({offer_id:m.String({description:"Stable offer identifier, for example 'plugin-readiness-v2026.5.5'."}),offer_text:m.String({description:"Final user-facing text to deliver."}),plan_prompt:m.String({description:"Prompt to seed into the plan-only session when the user clicks Start Plan."}),plan_workdir:m.String({description:"Working directory for the planning session."}),plan_worktree_strategy:m.Optional(Fc),plan_name:m.Optional(m.String({description:"Optional explicit session name for the planning session."})),target_channel:m.Optional(m.String({description:"Optional explicit route like 'telegram|<chat-id>'."})),target_thread_id:m.Optional(m.Union([m.String(),m.Number()],{description:"Optional explicit topic/thread id."})),target_session_key:m.Optional(m.String({description:"Optional explicit session key for wake routing."}))}),async execute(e,n){return qc(n)?Uc(t,n):{content:[{type:"text",text:"Error: Invalid parameters. Expected { offer_id, offer_text, plan_prompt, plan_workdir }."}]}}}}J();E();function na(t){return{name:"agent_stats",description:"Show OpenClaw Code Agent usage metrics: session counts by status, average duration, and notable sessions.",parameters:m.Object({}),async execute(e,n){if(!k)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let r=k.getMetrics(),i=k.list("running").length;return{content:[{type:"text",text:vn(r,i)}]}}}}J();Y();E();ue();Kt();import{existsSync as er}from"fs";function Hc(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function Gc(t){return t.mergeResult.stashPopConflict?[`Pre-merge stash pop conflicted; run git stash show ${t.mergeResult.stashRef??"stash@{0}"} in ${t.repoDir} to review stashed changes.`]:t.mergeResult.stashed?[`Pre-existing changes on ${t.baseBranch} were auto-stashed and restored.`]:[]}function tr(t){return{name:"agent_merge",description:"Merge a worktree branch back to the base branch. Resolves session (active or persisted), gets worktree path, and performs the merge. On conflict, spawns a conflict-resolver session using the configured default harness.",parameters:m.Object({session:m.String({description:"Session name or ID to merge"}),base_branch:m.Optional(m.String({description:"Base branch to merge into (default: main)"})),strategy:m.Optional(m.Union([m.Literal("merge"),m.Literal("squash")],{description:"Merge strategy: 'merge' (default, fast-forward if possible; merge commit if branches have diverged) or 'squash' (squashes all commits into one)"})),push:m.Optional(m.Boolean({description:"Push the base branch after successful merge (default: false)"})),delete_branch:m.Optional(m.Boolean({description:"Delete the worktree branch after successful merge (default: true)"}))}),async execute(e,n){if(!k)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!Hc(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, base_branch?, strategy?, push?, delete_branch? }."}]};let r=dt(k,n.session),i=r.activeSession,o=r.persistedSession;if(!i&&!o)return{content:[{type:"text",text:`Error: Session "${n.session}" not found.`}]};let{worktreePath:s,originalWorkdir:a,branchName:d}=r;if(!s||!a)return{content:[{type:"text",text:`Error: Session "${n.session}" does not have a worktree.`}]};if(!d)return{content:[{type:"text",text:`Error: Cannot determine branch name for worktree at ${s}. The worktree may have been removed and no persisted branch name is available.`}]};er(s)||`${s}${a}`;let l=a;if(!er(a))return{content:[{type:"text",text:`Error: originalWorkdir "${a}" does not exist.`}]};let u=n.base_branch??ke(l),c=u,p=n.strategy??"merge",f=n.push===!0,g=n.delete_branch!==!1;if(o?.worktreeLifecycle?.state==="merged"||o?.worktreeMerged)return{content:[{type:"text",text:`ℹ️ Session "${n.session}" is already merged.`}]};if(er(s)&&!Wt(l,d,c)&&at(s))return{content:[{type:"text",text:[`❌ Merge blocked: session "${n.session}" has uncommitted worktree changes but branch ${d} has no commits ahead of ${c}.`,`Worktree: ${s}`,"Resume or inspect the session, then commit real task changes or clean temporary files before retrying agent_merge."].join(`
|
|
96
|
-
`)}]};let h={content:[{type:"text",text:"❌ Merge did not run (internal error)"}]},y=r.persistedRef;return await
|
|
97
|
-
⚠️ Pre-merge stash pop conflicted — run \`git stash show ${b.stashRef??"stash@{0}"}\` in ${l} to review stashed changes.`:b.stashed&&(
|
|
98
|
-
(Pre-existing changes on ${c} were auto-stashed and restored.)`),h={content:[{type:"text",text:
|
|
99
|
-
|
|
100
|
-
${b.error}`}]};else if(b.conflictFiles&&b.conflictFiles.length>0){let
|
|
101
|
-
`);try{let N=
|
|
102
|
-
`)}]}}}}
|
|
103
|
-
`).trim()}]}}}}
|
|
104
|
-
`)}function
|
|
105
|
-
`).map(n=>`${e}${n}`)}function
|
|
106
|
-
`);return
|
|
107
|
-
`)}function
|
|
108
|
-
`)}
|
|
109
|
-
|
|
110
|
-
`)}]}}}}J();E();function pp(t){return!!t&&typeof t=="object"&&typeof t.task=="string"}function ka(t){return{name:"goal_stop",description:"Stop an explicit goal task and kill its underlying agent session.",parameters:m.Object({task:m.String({description:"Goal task name or ID"})}),async execute(e,n){if(!O)return{content:[{type:"text",text:"Error: GoalController not initialized. The code-agent service must be running."}]};if(!pp(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { task }."}]};let r=O.stopTask(n.task);return r?{content:[{type:"text",text:r.action==="already_terminal"?`Task is already ${r.task.status}.`:`Task "${r.task.name}" (${r.task.id}) stopped.`}]}:{content:[{type:"text",text:`Error: Goal task "${n.task}" not found.`}]}}}}J();E();function mp(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.task=="string"&&typeof e.goal=="string"}function ji(t,e){switch(t.action){case"updated":return`Task "${t.task.name}" (${t.task.id}) goal updated.`;case"not_found":return`Error: Goal task "${e}" not found.`;case"invalid_goal":return"Error: replacement goal must not be empty.";case"not_editable":return t.task.status!=="waiting_for_user"?`Task is already ${t.task.status}.`:`Error: Goal task "${t.task.name}" is ${t.task.status} and cannot be edited.`}}function va(t){return{name:"goal_edit",description:"Edit the goal text for an active goal task without stopping or relaunching its session.",parameters:m.Object({task:m.String({description:"Goal task name or ID"}),goal:m.String({description:"Replacement goal text"})}),async execute(e,n){if(!O)return{content:[{type:"text",text:"Error: GoalController not initialized. The code-agent service must be running."}]};if(!mp(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { task, goal }."}]};let r=O.editTask(n.task,n.goal);return{content:[{type:"text",text:ji(r,n.task)}]}}}}E();ar();import{createHash as fp}from"crypto";var ce="code-agent";var gp=new Set(["1","true","yes","on"]);function hp(){let t=process.env.OPENCLAW_CODE_AGENT_BUTTON_DIAGNOSTICS?.trim().toLowerCase();return!!(t&&gp.has(t))}function ct(t){if(!(typeof t!="string"||t.length===0))return fp("sha256").update(t).digest("hex").slice(0,12)}function wa(t){return typeof t.callbackData=="string"?t.callbackData:typeof t.value=="string"?t.value:void 0}function K(t){let e=(t??[]).filter(r=>Array.isArray(r)&&r.length>0),n=e.flat();return{buttonRows:e.length||void 0,buttonCount:n.length||void 0,buttonLabels:n.length>0?n.map(r=>typeof r.label=="string"?r.label:void 0):void 0,callbackByteLengths:n.length>0?n.map(r=>{let i=wa(r);return i?Buffer.byteLength(i,"utf8"):void 0}):void 0,callbackHashes:n.length>0?n.map(r=>ct(wa(r))):void 0,buttonStyles:n.length>0?n.map(r=>typeof r.style=="string"?r.style:void 0):void 0}}function Me(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function ba(t){let e=Me(t),n=Array.isArray(e?.blocks)?e.blocks:void 0;if(n)return n.map(r=>Me(r)?.type).filter(r=>typeof r=="string"&&r.length>0)}function Ra(t){let e=Me(t),n=Array.isArray(e?.blocks)?e.blocks:void 0;if(!n)return;let r=n.map(i=>{let o=Me(i);return o?.type!=="buttons"||!Array.isArray(o.buttons)?[]:o.buttons}).filter(i=>i.length>0);return r.length>0?r:void 0}function Ji(t){let e=Ra(t);return{presentationBlockTypes:ba(t),...K(e)}}function Qi(t){let e=Me(t),n=e?.interactive,r=Me(e?.channelData),i=Me(r?.telegram),o=Array.isArray(i?.buttons)?i.buttons:void 0;return{renderedPayloadKeys:e?Object.keys(e).sort():void 0,interactiveBlockTypes:ba(n),...Pa("interactive",K(Ra(n))),...Pa("telegramChannelData",K(o)),hasPresentation:!!e?.presentation,hasInteractive:!!n,hasTelegramChannelDataButtons:!!o?.some(s=>s.length>0)}}function Aa(t){let e=Me(t);return e?{sendResultKeys:Object.keys(e).sort(),messageId:zi(e.messageId),chatId:zi(e.chatId),telegramThreadId:zi(e.messageThreadId??e.threadId),channel:typeof e.channel=="string"?e.channel:void 0}:{sendResultType:typeof t}}function zi(t){return typeof t=="string"||typeof t=="number"?t:void 0}function Pa(t,e){let n={};for(let[r,i]of Object.entries(e))i!==void 0&&(n[`${t}${r.charAt(0).toUpperCase()}${r.slice(1)}`]=i);return n}function $(t,e){if(!hp())return;let n=Object.fromEntries(Object.entries(e).filter(([,r])=>r!==void 0));`${JSON.stringify({event:t,callbackNamespace:ce,...n})}`}function yp(t){let e=t.trim().replace(new RegExp(`^${ce}:`),"");return e||null}async function cr(t,e,n=!1){try{return(await oe(t,{text:e,alreadyAcknowledged:n})).textDelivered}catch(r){let i=r instanceof Error?r.message:String(r);return`${i}`,!1}}function pr(t){if(t&&typeof t=="object"&&"content"in t&&Array.isArray(t.content)){let e=t.content[0];return typeof e?.text=="string"?e.text:"(done)"}return"(done)"}function xa(t){if(t&&typeof t=="object"&&"meta"in t){let e=t.meta;if(typeof e?.success=="boolean")return e.success}return Yi(pr(t))}function Yi(t){return!/^\s*(?:Error\b:?|❌|⚠️)/.test(t)}function Sp(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"}function kp(t,e){if(Sp(t.kind)){if(!e)return"This plan decision is stale because the session is no longer available.";if(t.planDecisionVersion!=null&&(e.actionablePlanDecisionVersion??e.planDecisionVersion)!=null&&t.planDecisionVersion!==(e.actionablePlanDecisionVersion??e.planDecisionVersion))return"This plan decision is stale because a newer plan review state already exists.";if(!e.pendingPlanApproval)return"This plan is no longer awaiting approval.";if(t.kind==="plan-approve"&&e.approvalState==="changes_requested"&&!e.pendingPlanApproval)return"Changes were already requested for this plan. Wait for the revised plan before approving.";if(t.kind==="plan-request-changes"&&e.approvalState==="changes_requested")return"Changes were already requested for this plan. Send your feedback to the agent instead."}}function vp(t){let e="callback"in t?t.callback?.payload??t.callback?.data:void 0,n="interaction"in t?t.interaction?.payload:void 0;return e??n??""}function Ht(t){let e=t instanceof Error?t.message:String(t);return/message is not modified/i.test(e)}function wp(t){let e=t instanceof Error?t.message:String(t);return/empty message/i.test(e)}async function oe(t,e={}){let n=t.respond,{alreadyAcknowledged:r=!1,forceTelegramMarkupEdit:i=!1,text:o}=e;if(t.channel==="telegram"){if(typeof o=="string"&&typeof n.editMessage=="function")try{return await n.editMessage({text:o,buttons:[]}),typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!0}}catch(a){if(Ht(a))return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!0};let d=a instanceof Error?a.message:String(a);`${d}`}if(i&&typeof n.editButtons=="function")try{return await n.editButtons({buttons:[]}),typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1}}catch(a){if(Ht(a))return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1};let d=a instanceof Error?a.message:String(a);`${d}`}let s="callback"in t&&typeof t.callback?.messageText=="string"?t.callback.messageText:void 0;if(i&&typeof s=="string"&&typeof n.editMessage=="function")try{return await n.editMessage({text:s,buttons:[]}),typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1}}catch(a){if(Ht(a))return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1};let d=a instanceof Error?a.message:String(a);`${d}`}return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1}}if(typeof n.clearComponents=="function")try{return await n.clearComponents(typeof o=="string"?{text:o}:void 0),{textDelivered:typeof o=="string"}}catch(s){if(Ht(s))return{textDelivered:typeof o=="string"};if(wp(s)){if(typeof o!="string"&&r)return{textDelivered:!1};if(typeof o!="string"&&typeof n.acknowledge=="function")return await n.acknowledge(),{textDelivered:!1};typeof o!="string"&&n.acknowledge}else{if(typeof o!="string")throw s;{let a=s instanceof Error?s.message:String(s);`${a}`}}}if(typeof o=="string"&&typeof n.editMessage=="function"){try{await n.editMessage({text:o})}catch(s){if(Ht(s))return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!0};let a=s instanceof Error?s.message:String(s);return`${a}`,typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1}}return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!0}}return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1}}async function Pp(t){let e=t.respond;if(typeof e.acknowledge!="function")return!1;try{return await e.acknowledge(),!0}catch(n){let r=n instanceof Error?n.message:String(n);return`${r}`,!1}}async function q(t,e){if(t.channel==="telegram"){await t.respond.reply({text:e});return}await t.respond.reply({text:e,ephemeral:!0})}function Ia(t="telegram"){return $("callback_handler_registered",{channel:t,namespace:ce}),{channel:t,namespace:ce,handler:async e=>{let n=await Pp(e);if(!e.auth.isAuthorizedSender)return await q(e,"⛔ Unauthorized."),{handled:!0};let r=vp(e),i=yp(r);if($("callback_received",{channel:e.channel,namespace:ce,payloadByteLength:Buffer.byteLength(r,"utf8"),tokenHash:ct(i),isAuthorizedSender:e.auth.isAuthorizedSender}),!i)return await q(e,"⚠️ Unrecognized callback payload."),{handled:!0};if(!k)return await q(e,"⚠️ Code agent service not running."),{handled:!0};let o=k.getActionToken(i);if($("callback_token_lookup_completed",{channel:e.channel,namespace:ce,tokenHash:ct(i),tokenFound:!!o,actionKind:o?.kind,sessionId:o?.sessionId,planDecisionVersion:o?.planDecisionVersion}),!o)return await oe(e,{alreadyAcknowledged:n}),e.channel!=="telegram"&&await q(e,"⚠️ This action is stale or has already been used."),{handled:!0};let s=o.sessionId,a=k.resolve?.(s)??k.getPersistedSession?.(s),d=a?.name??s,l=kp(o,a);if($("callback_plan_validation_completed",{channel:e.channel,namespace:ce,tokenHash:ct(i),actionKind:o.kind,sessionId:s,sessionName:d,planDecisionVersion:o.planDecisionVersion,valid:!l}),l)return await oe(e,{alreadyAcknowledged:n}),await q(e,`⚠️ ${l}`),{handled:!0};let u=k.consumeActionToken(i);if($("callback_token_consume_completed",{channel:e.channel,namespace:ce,tokenHash:ct(i),consumed:!!u,actionKind:u?.kind,sessionId:u?.sessionId,planDecisionVersion:u?.planDecisionVersion}),!u)return await oe(e,{alreadyAcknowledged:n,forceTelegramMarkupEdit:o.kind==="plan-offer-start"||o.kind==="plan-offer-dismiss"}),e.channel!=="telegram"&&await q(e,"⚠️ This action is stale or has already been used."),{handled:!0};switch(u.kind){case"worktree-merge":{let c=await tr().execute("callback",{session:s}),p=pr(c);xa(c)&&await cr(e,`✅ Merge selected for [${d}]`,n),await q(e,p);break}case"worktree-decide-later":{let c=k.snoozeWorktreeDecision(s,{notifyUser:!1});if(Yi(c)){let f=`⏭️ Snoozed 24h for [${d}]`;await cr(e,f,n)||await q(e,f)}else await q(e,c);break}case"worktree-dismiss":{let c=await k.dismissWorktree(s),p=Yi(c);p&&await cr(e,`🗑️ Discarded for [${d}]`,n),await q(e,p?"✅ Discarded":c);break}case"worktree-create-pr":case"worktree-update-pr":{let c=await Vt().execute("callback",{session:s}),p=pr(c);xa(c)&&await cr(e,o.kind==="worktree-update-pr"?`📬 PR update selected for [${d}]`:`📬 PR selected for [${d}]`,n),await q(e,p);break}case"worktree-view-pr":{await oe(e,{alreadyAcknowledged:n});let c=k.getPersistedSession?.(s),p=o.targetUrl??c?.worktreePrUrl;await q(e,p?`PR: ${p}`:"⚠️ PR URL is no longer available.");break}case"plan-approve":{await oe(e,{alreadyAcknowledged:n}),k.clearPlanDecisionTokens(s);let c=await pe(k,{session:s,message:"Approved. Go ahead.",approve:!0,userInitiated:!0});c.isError&&await q(e,`⚠️ ${c.text}`);break}case"plan-reject":{await oe(e,{alreadyAcknowledged:n});let c=Fi(k,s);await q(e,`❌ ${c.text}`);break}case"plan-request-changes":{await oe(e,{alreadyAcknowledged:n});let c=qi(k,s);await q(e,`✏️ ${c.text}`);break}case"plan-offer-start":{if(!u.launchPrompt||!u.launchWorkdir){await oe(e,{alreadyAcknowledged:n,forceTelegramMarkupEdit:!0}),await q(e,"⚠️ This action is missing the plan launch context.");break}let c;try{c=k.launchPlanOffer({route:u.route,prompt:u.launchPrompt,workdir:u.launchWorkdir,name:u.launchName,worktreeStrategy:u.launchWorktreeStrategy})}catch(p){let f=p instanceof Error?p.message:String(p);await q(e,`⚠️ Failed to start planning session: ${f}`);break}await oe(e,{alreadyAcknowledged:n,forceTelegramMarkupEdit:!0}),await q(e,`▶️ Planning session started: ${c.name} [${c.id}]`);break}case"plan-offer-dismiss":{await oe(e,{alreadyAcknowledged:n,forceTelegramMarkupEdit:!0}),await q(e,"✅ Dismissed.");break}case"session-restart":case"session-resume":{await oe(e,{alreadyAcknowledged:n});let c=await pe(k,{session:s,message:"Continue where you left off.",userInitiated:!0});await q(e,c.isError?`⚠️ ${c.text}`:`▶️ ${c.text}`);break}case"view-output":{await oe(e,{alreadyAcknowledged:n});let c=await jn().execute("callback",{session:s,lines:50});await q(e,pr(c));break}case"question-answer":{if(await oe(e,{alreadyAcknowledged:n}),o.optionIndex==null){await q(e,"⚠️ Invalid question-answer action.");break}await k.resolvePendingInputOption(s,o.optionIndex),await q(e,"✅ Answer submitted.");break}default:{await oe(e,{alreadyAcknowledged:n}),await q(e,"⚠️ Unknown callback action.");break}}return{handled:!0}}}}E();Y();function pt(t){return Ta(t).map(e=>e.value)}function Ta(t){return Array.from(t.matchAll(/"[^"]*"|'[^']*'|\S+/g),e=>{let n=e[0],r=e.index??0;return{value:bp(n),raw:n,start:r,end:r+n.length}})}function Gt(t){let[e]=Ta(t);if(e)return{value:e.value,rest:t.slice(e.end).trimStart()}}function bp(t){return t.length>1&&(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))?t.slice(1,-1):t}function Rp(t){return t instanceof Error?t.message:String(t)}function Ap(t){let e=pt(t),n,r=e;return e[0]==="--name"&&e[1]&&(n=e[1],r=e.slice(2)),{name:n,prompt:r.join(" ").trim()}}function Ca(t){t.registerCommand({name:"agent",description:"Launch a coding agent session. Usage: /agent [--name <name>] <prompt>",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!k)return{text:"Error: SessionManager not initialized. The code-agent service must be running."};let n=(e.args??"").trim();if(!n)return{text:"Usage: /agent [--name <name>] <prompt>"};let{name:r,prompt:i}=Ap(n);if(!i)return{text:"Usage: /agent [--name <name>] <prompt>"};try{let o=Sn({prompt:i,name:r},e,k);if(o.kind!=="resolved")return{text:o.text};let s=k.spawn({prompt:i,name:r,workdir:o.workdir,model:o.resolvedModel,reasoningEffort:o.reasoningEffort,fastMode:o.fastMode,codexApprovalPolicy:o.harness==="codex"?"never":void 0,originChannel:o.originChannel,originThreadId:o.originThreadId,originAgentId:e.agentId||void 0,originSessionKey:o.originSessionKey,route:o.route,harness:o.harness,permissionMode:o.permissionMode,planApproval:o.planApproval,taskLifecycle:An(e)});return{text:k.formatLaunchResult({prompt:i,workdir:o.workdir,harness:o.harness,permissionMode:o.permissionMode??C.permissionMode,planApproval:o.planApproval},s)}}catch(o){let s=Rp(o),a=s.includes("Max sessions")?"":`
|
|
111
|
-
|
|
112
|
-
Use /agent_sessions to see active sessions.`;return{text:`Error launching session: ${s}${a}`}}}})}
|
|
113
|
-
/agent_respond --interrupt <id-or-name> <message>`};let r=!1,
|
|
114
|
-
|
|
115
|
-
`)}}})}E();function La(t){t.registerCommand({name:"goal_stop",description:"Stop a goal task. Usage: /goal_stop <task-id-or-name>",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!O)return{text:"Error: GoalController not initialized. The code-agent service must be running."};let n=(e.args??"").trim();if(!n)return{text:"Usage: /goal_stop <task-id-or-name>"};let r=O.stopTask(n);return r?r.action==="already_terminal"?{text:`Task is already ${r.task.status}.`}:{text:`Task "${r.task.name}" (${r.task.id}) stopped.`}:{text:`Error: Goal task "${n}" not found.`}}})}E();var Ba="Usage: /goal_edit <task-id-or-name> <replacement-goal>";function Fa(t){t.registerCommand({name:"goal_edit",description:"Edit a running goal task. Usage: /goal_edit <task-id-or-name> <replacement-goal>",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!O)return{text:"Error: GoalController not initialized. The code-agent service must be running."};let n=(e.args??"").trim();if(!n)return{text:Ba};let r=Gt(n),i=r?.value.trim(),o=r?.rest.trim();if(!i||!o)return{text:Ba};let s=O.editTask(i,o);return{text:ji(s,i)}}})}import{execFile as Bp}from"child_process";import{createHash as Qa}from"crypto";import{existsSync as Ip,mkdirSync as Tp,readFileSync as Cp,renameSync as Mp,writeFileSync as _p}from"fs";import{homedir as $p}from"os";import{dirname as Ep,join as qa}from"path";function Dp(t){let e=t.OPENCLAW_HOME?.trim();return e||qa($p(),".openclaw")}function Op(t){let e=t.OPENCLAW_CODE_AGENT_GOAL_TASKS_PATH?.trim();return e||qa(Dp(t),"code-agent-goal-tasks.json")}function Wp(t){return t instanceof Error?t.message:String(t)}function Np(t){if(!t||typeof t!="object")return;let e=t;if(!(typeof e.provider!="string"||typeof e.target!="string"))return{provider:e.provider,target:e.target,accountId:typeof e.accountId=="string"?e.accountId:void 0,threadId:typeof e.threadId=="string"?e.threadId:void 0,sessionKey:typeof e.sessionKey=="string"?e.sessionKey:void 0}}function Lp(t){if(!t||typeof t!="object")return;let e=t;if(typeof e.id!="string"||typeof e.name!="string"||typeof e.goal!="string"||typeof e.workdir!="string"||typeof e.status!="string")return;let n=e.status,r=n==="running"||n==="waiting_for_session"?"waiting_for_session":n;return{id:e.id,name:e.name,goal:e.goal,workdir:e.workdir,status:r,createdAt:typeof e.createdAt=="number"?e.createdAt:Date.now(),updatedAt:typeof e.updatedAt=="number"?e.updatedAt:Date.now(),iteration:typeof e.iteration=="number"?e.iteration:0,maxIterations:typeof e.maxIterations=="number"?e.maxIterations:8,sessionId:typeof e.sessionId=="string"?e.sessionId:void 0,sessionName:typeof e.sessionName=="string"?e.sessionName:void 0,harnessSessionId:typeof e.harnessSessionId=="string"?e.harnessSessionId:void 0,model:typeof e.model=="string"?e.model:void 0,reasoningEffort:typeof e.reasoningEffort=="string"?e.reasoningEffort:void 0,fastMode:e.fastMode===!0?!0:void 0,systemPrompt:typeof e.systemPrompt=="string"?e.systemPrompt:void 0,allowedTools:Array.isArray(e.allowedTools)?e.allowedTools.filter(i=>typeof i=="string"):void 0,originChannel:typeof e.originChannel=="string"?e.originChannel:void 0,originThreadId:typeof e.originThreadId=="string"||typeof e.originThreadId=="number"?e.originThreadId:void 0,originAgentId:typeof e.originAgentId=="string"?e.originAgentId:void 0,originSessionKey:typeof e.originSessionKey=="string"?e.originSessionKey:void 0,route:Np(e.route),harness:typeof e.harness=="string"?e.harness:void 0,permissionMode:typeof e.permissionMode=="string"?e.permissionMode:void 0,loopMode:e.loopMode==="ralph"?"ralph":"verifier",completionPromise:typeof e.completionPromise=="string"?e.completionPromise:void 0,verifierCommands:Array.isArray(e.verifierCommands)?e.verifierCommands.filter(i=>!!i&&typeof i=="object"&&typeof i.label=="string"&&typeof i.command=="string"):[],lastVerifierSummary:typeof e.lastVerifierSummary=="string"?e.lastVerifierSummary:void 0,lastVerifierFingerprint:typeof e.lastVerifierFingerprint=="string"?e.lastVerifierFingerprint:void 0,repeatedFailureCount:typeof e.repeatedFailureCount=="number"?e.repeatedFailureCount:0,waitingForUserReason:typeof e.waitingForUserReason=="string"?e.waitingForUserReason:void 0,failureReason:typeof e.failureReason=="string"?e.failureReason:void 0}}var mr=class{path;tasks=new Map;constructor(e=process.env){this.path=Op(e),this.load()}load(){try{if(!Ip(this.path))return;let e=Cp(this.path,"utf8"),n=JSON.parse(e);if(!Array.isArray(n))return;for(let r of n){let i=Lp(r);i&&this.tasks.set(i.id,i)}this.save()}catch{}}save(){try{Tp(Ep(this.path),{recursive:!0});let e=`${this.path}.tmp`;_p(e,JSON.stringify([...this.tasks.values()],null,2),"utf8"),Mp(e,this.path)}catch(e){`${this.path}${Wp(e)}`}}upsert(e){this.tasks.set(e.id,e),this.save()}get(e){let n=this.tasks.get(e);return n||[...this.tasks.values()].find(r=>r.name===e)}list(){return[...this.tasks.values()].sort((e,n)=>n.createdAt-e.createdAt)}};he();var Fp=8,Ya=600*1e3,qp=4e3,Zi=1200,Kp="DONE",Up=["BASH_ENV","ENV"];function Vp(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,48)||"goal-task"}function mt(t,e){return t.length<=e?t:`${t.slice(0,e-3)}...`}function _e(t,e=20){let n=t.split(/\r?\n/).map(r=>r.trimEnd()).filter(r=>r.trim().length>0);return n.length<=e?n.join(`
|
|
94
|
+
ℹ️ Session has a pending plan — sending as revision feedback. The agent will revise and re-submit. Set approve=true to approve instead.`),await n.sendMessage(e.message),u&&Gc(t,n),u)t.notifySession(n,`👍 [${n.name}] Plan approved`,"plan-approved");else if(e.userInitiated){let g=re(e.message,100);t.notifySession(n,`↪️ [${n.name}] "${g}"`,"agent-respond")}e.userInitiated||n.incrementAutoRespond();let f=re(e.message,80);return u?{text:`Plan approved for session ${n.name} [${n.id}]. Use agent_output to see the response.`}:{text:[`Message sent to session ${n.name} [${n.id}].`,l?" (redirected active turn first)":e.interrupt?" (no active turn to interrupt)":"",` Message: "${f}"`,p,"Use agent_output to see the response."].filter(Boolean).join(`
|
|
95
|
+
`)}}catch(d){return{text:`Error sending message to session ${n.name} [${n.id}]: ${Jo(d)}`,isError:!0}}}function zc(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.message=="string"&&(e.approval_rationale===void 0||typeof e.approval_rationale=="string")}function pa(t){return{name:"agent_respond",description:"Send a follow-up message to a running coding agent session. The session must be running. All sessions are multi-turn.",parameters:m.Object({session:m.String({description:"Session name or ID to respond to"}),message:m.String({description:"The message to send to the session"}),interrupt:m.Optional(m.Boolean({description:"If true, interrupt the current turn before sending the message. Useful to redirect the session mid-response."})),userInitiated:m.Optional(m.Boolean({description:"Set to true when the message comes from the user (not auto-generated). Resets the auto-respond counter and bypasses the auto-respond limit."})),approve:m.Optional(m.Boolean({description:"Set to true to escalate session permissions to bypassPermissions. Works in two scenarios: (1) approve a pending plan in plan mode, or (2) escalate a default-mode session to skip remaining OpenClaw approval checkpoints. No-op if already in bypassPermissions mode. In plan mode without a pending plan, this flag is ignored."})),approval_rationale:m.Optional(m.String({description:"Optional structured rationale for a direct delegated plan approval. Use this instead of embedding the rationale in message text when approve=true for a pending plan."}))}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!zc(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, message, interrupt?, userInitiated?, approve?, approval_rationale? }."}]};let r=await he(v,{session:n.session,message:n.message,interrupt:n.interrupt,userInitiated:n.userInitiated,approve:n.approve,approvalRationale:n.approval_rationale});return{isError:r.isError??!1,content:[{type:"text",text:r.text}]}}}}X();O();function Qc(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.summary=="string"}function ma(t){return{name:"agent_request_plan_approval",description:"Send a plan-approval decision prompt to the user for a session that is already waiting on plan approval. Reuses the plugin's Approve/Revise/Reject buttons so the user can decide directly from the message.",parameters:m.Object({session:m.String({description:"Session name or ID awaiting plan approval"}),summary:m.String({description:"Concise user-facing summary of scope, risk, and any concerns that should accompany the approval buttons"})}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!Qc(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, summary }."}]};let r=v.requestPlanApprovalFromUser(n.session,n.summary);return{isError:r.startsWith("Error:"),content:[{type:"text",text:r}]}}}}X();O();function Jc(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.session=="string"&&typeof e.summary=="string"}function fa(t){return{name:"agent_request_worktree_decision",description:"Send a worktree Merge/Open PR/Later/Discard decision prompt to the user for a delegated worktree session that is awaiting human choice.",parameters:m.Object({session:m.String({description:"Delegated session name or ID awaiting a worktree decision"}),summary:m.String({description:"Concise user-facing summary of scope, risk, and why human choice is needed"})}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!Jc(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, summary }."}]};let r=v.requestWorktreeDecisionFromUser(n.session,n.summary);return{isError:r.startsWith("Error:"),content:[{type:"text",text:r}]}}}}X();O();te();var Xo=["off","manual","ask","delegate","auto-merge","auto-pr"],Zn=new Set(Xo),Yc=["low","medium","high","xhigh","max"],ga=new Set(Yc);function Zc(t){return typeof t=="string"&&Zn.has(t)}var Xc=m.Union(Xo.map(t=>m.Literal(t)),{description:"Optional worktree strategy for the planning session. Use auto-pr when the follow-up should branch and open/update a PR after approved implementation."});function ep(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.offer_id=="string"&&typeof e.offer_text=="string"&&typeof e.plan_prompt=="string"&&typeof e.plan_workdir=="string"&&(e.plan_worktree_strategy==null||Zc(e.plan_worktree_strategy))&&(e.plan_name==null||typeof e.plan_name=="string")&&(e.target_channel==null||typeof e.target_channel=="string")&&(e.target_thread_id==null||typeof e.target_thread_id=="string"||typeof e.target_thread_id=="number")&&(e.target_session_key==null||typeof e.target_session_key=="string")}function tp(t,e){let n=et(t,e.target_channel,e.target_session_key);if(n)return e.target_thread_id!=null&&(n.threadId=String(e.target_thread_id)),n}async function np(t,e){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let n=tp(t,e);return!n?.provider||!n.target?{content:[{type:"text",text:"Error: Could not resolve a direct delivery route for the plan offer."}]}:(v.sendPlanOffer({offerId:e.offer_id,route:n,text:e.offer_text,planName:e.plan_name??e.offer_id,planPrompt:e.plan_prompt,planWorkdir:e.plan_workdir,planWorktreeStrategy:e.plan_worktree_strategy}),{content:[{type:"text",text:`Interactive plan offer queued for ${n.provider}|${n.target}${n.threadId?`#${n.threadId}`:""}.`}]})}function ha(t){return{name:"agent_send_plan_offer",description:"Post a user-facing message to the current or explicit chat route with human-gated Start Plan and Dismiss inline buttons. Use this when an external workflow wants the user to open a plan-only code-agent session from the message.",parameters:m.Object({offer_id:m.String({description:"Stable offer identifier, for example 'plugin-readiness-v2026.5.5'."}),offer_text:m.String({description:"Final user-facing text to deliver."}),plan_prompt:m.String({description:"Prompt to seed into the plan-only session when the user clicks Start Plan."}),plan_workdir:m.String({description:"Working directory for the planning session."}),plan_worktree_strategy:m.Optional(Xc),plan_name:m.Optional(m.String({description:"Optional explicit session name for the planning session."})),target_channel:m.Optional(m.String({description:"Optional explicit route like 'telegram|<chat-id>'."})),target_thread_id:m.Optional(m.Union([m.String(),m.Number()],{description:"Optional explicit topic/thread id."})),target_session_key:m.Optional(m.String({description:"Optional explicit session key for wake routing."}))}),async execute(e,n){return ep(n)?np(t,n):{content:[{type:"text",text:"Error: Invalid parameters. Expected { offer_id, offer_text, plan_prompt, plan_workdir }."}]}}}}X();O();function Sa(t){return{name:"agent_stats",description:"Show OpenClaw Code Agent usage metrics: session counts by status, average duration, and notable sessions.",parameters:m.Object({}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};let r=v.getMetrics(),o=v.list("running").length;return{content:[{type:"text",text:An(r,o)}]}}}}X();te();O();me();jt();import{existsSync as rr}from"fs";function op(t){return!t||typeof t!="object"?!1:typeof t.session=="string"}function ip(t){return t.mergeResult.stashPopConflict?[`Pre-merge stash pop conflicted; run git stash show ${t.mergeResult.stashRef??"stash@{0}"} in ${t.repoDir} to review stashed changes.`]:t.mergeResult.stashed?[`Pre-existing changes on ${t.baseBranch} were auto-stashed and restored.`]:[]}function or(t){return{name:"agent_merge",description:"Merge a worktree branch back to the base branch. Resolves session (active or persisted), gets worktree path, and performs the merge. On conflict, spawns a conflict-resolver session using the configured default harness.",parameters:m.Object({session:m.String({description:"Session name or ID to merge"}),base_branch:m.Optional(m.String({description:"Base branch to merge into (default: main)"})),strategy:m.Optional(m.Union([m.Literal("merge"),m.Literal("squash")],{description:"Merge strategy: 'merge' (default, fast-forward if possible; merge commit if branches have diverged) or 'squash' (squashes all commits into one)"})),push:m.Optional(m.Boolean({description:"Push the base branch after successful merge (default: false)"})),delete_branch:m.Optional(m.Boolean({description:"Delete the worktree branch after successful merge (default: true)"}))}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!op(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session, base_branch?, strategy?, push?, delete_branch? }."}]};let r=ft(v,n.session),o=r.activeSession,i=r.persistedSession;if(!o&&!i)return{content:[{type:"text",text:`Error: Session "${n.session}" not found.`}]};let{worktreePath:s,originalWorkdir:a,branchName:d}=r;if(!s||!a)return{content:[{type:"text",text:`Error: Session "${n.session}" does not have a worktree.`}]};if(!d)return{content:[{type:"text",text:`Error: Cannot determine branch name for worktree at ${s}. The worktree may have been removed and no persisted branch name is available.`}]};rr(s)||`${s}${a}`;let l=a;if(!rr(a))return{content:[{type:"text",text:`Error: originalWorkdir "${a}" does not exist.`}]};let u=n.base_branch??be(l),c=u,p=n.strategy??"merge",f=n.push===!0,g=n.delete_branch!==!1;if(i?.worktreeLifecycle?.state==="merged"||i?.worktreeMerged)return{content:[{type:"text",text:`ℹ️ Session "${n.session}" is already merged.`}]};if(rr(s)&&!qt(l,d,c)&&mt(s))return{content:[{type:"text",text:[`❌ Merge blocked: session "${n.session}" has uncommitted worktree changes but branch ${d} has no commits ahead of ${c}.`,`Worktree: ${s}`,"Resume or inspect the session, then commit real task changes or clean temporary files before retrying agent_merge."].join(`
|
|
96
|
+
`)}]};let h={content:[{type:"text",text:"❌ Merge did not run (internal error)"}]},y=r.persistedRef;return await v.enqueueMerge(l,async()=>{let k=v.getPersistedSession(n.session);if(k?.worktreeLifecycle?.state==="merged"||k?.worktreeMerged){h={content:[{type:"text",text:`ℹ️ Session "${n.session}" was already merged while waiting in queue.`}]};return}let R=xe(l,d,u),b=Kn(l,d,c,p,s);if(b.success){let A=ip({mergeResult:b,repoDir:l,baseBranch:c});if(f&&!qn(l,c)){let M=`⚠️ Merged ${d} → ${c} locally, but failed to push ${c}`;v.notifyWorktreeOutcome(r.notificationTarget,M,{detailLines:[`Branch ${d} was merged into ${c} in the local repository.`,`Pushing ${c} failed; remote state may not include the merge.`,"Cleanup was skipped so the branch/worktree remains available for follow-up.",...A]}),h={content:[{type:"text",text:M}]};return}g&&ge(l,d);let N=!1;if(rr(s)&&(N=de(l,s),Fn(l)),k)for(let M of Ht({...r,persistedSession:k}))v.updatePersistedSession(M,{worktreeMerged:!0,worktreeMergedAt:new Date().toISOString(),pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,lifecycle:"terminal",worktreeState:"merged",worktreeDisposition:"merged",worktreeLifecycle:{state:"merged",updatedAt:new Date().toISOString(),resolvedAt:new Date().toISOString(),resolutionSource:"agent_merge",baseBranch:u,targetRepo:k.worktreePrTargetRepo,pushRemote:k.worktreePushRemote}});let S=Ge({kind:"merge",branch:d,base:u,filesChanged:R?.filesChanged,insertions:R?.insertions,deletions:R?.deletions});v.notifyWorktreeOutcome(r.notificationTarget,S,{detailLines:[b.fastForward?"Merge type: fast-forward.":"Merge type: merge commit.",f?`Pushed ${c}.`:`Did not push ${c}; push was not requested.`,g?N?"Branch and worktree cleaned up.":"Branch deleted; worktree cleanup skipped.":"Branch/worktree cleanup was not requested.",...A]});let _=`✅ ${b.fastForward?"⚡ Fast-forward":"🔀 Merge commit"}: ${d} → ${c}.${f?" Pushed.":""}${g?N?" Branch and worktree cleaned up.":" Branch deleted; worktree cleanup skipped.":""}`;b.stashPopConflict?_+=`
|
|
97
|
+
⚠️ Pre-merge stash pop conflicted — run \`git stash show ${b.stashRef??"stash@{0}"}\` in ${l} to review stashed changes.`:b.stashed&&(_+=`
|
|
98
|
+
(Pre-existing changes on ${c} were auto-stashed and restored.)`),h={content:[{type:"text",text:_}]}}else if(b.rebaseConflict)h={content:[{type:"text",text:`⚠️ Rebase conflicts — manual resolution required:
|
|
99
|
+
|
|
100
|
+
${b.error}`}]};else if(b.conflictFiles&&b.conflictFiles.length>0){let A=["Resolve merge conflicts in the following files and commit the resolution:","",...b.conflictFiles.map(N=>`- ${N}`),"",`After resolving, commit with message: "Resolve merge conflicts from ${d}"`].join(`
|
|
101
|
+
`);try{let N=v.spawn({prompt:A,workdir:l,name:`${n.session}-conflict-resolver`,harness:se(),permissionMode:"bypassPermissions",multiTurn:!0,route:o?.route??i?.route,originChannel:o?.originChannel??i?.originChannel,originThreadId:o?.originThreadId??i?.originThreadId,originAgentId:o?.originAgentId??i?.originAgentId,originSessionKey:o?.originSessionKey??i?.originSessionKey});h={content:[{type:"text",text:`⚠️ Merge conflicts in ${b.conflictFiles.length} file(s) — spawned conflict resolver session: ${N.name}`}]}}catch(N){h={content:[{type:"text",text:`❌ Merge conflicts detected, but failed to spawn resolver: ${N instanceof Error?N.message:String(N)}`}]}}}else h={content:[{type:"text",text:b.dirtyError?`❌ Merge blocked: ${b.error}`:`❌ Merge failed: ${b.error??"unknown error"}`}]}}),h}}}pr();X();O();Q();me();jt();function Sp(t){return!!t&&typeof t=="object"}function Ia(t){return{name:"agent_worktree_cleanup",description:"Manage worktree cleanup with lifecycle-aware safety rules. Use preview_safe to list what Clean all safe would remove, clean_safe to execute it, or preview_all to see both safe and retained sandboxes with kept reasons.",parameters:m.Object({workdir:m.Optional(m.String({description:"Restrict cleanup to sessions rooted in this repository"})),base_branch:m.Optional(m.String({description:"Override base branch for lifecycle resolution"})),mode:m.Optional(m.Union([m.Literal("preview_safe"),m.Literal("clean_safe"),m.Literal("preview_all")],{description:"Cleanup mode. preview_safe shows what Clean all safe would remove, clean_safe performs that cleanup, preview_all shows both safe and retained worktrees. Defaults to preview_safe when dry_run=true, otherwise clean_safe."})),skip_session_check:m.Optional(m.Boolean({description:"Deprecated. Safe cleanup never removes live sessions."})),force:m.Optional(m.Boolean({description:"Deprecated alias for skip_session_check."})),dry_run:m.Optional(m.Boolean({description:"Show what would be cleaned without deleting anything."})),session:m.Optional(m.String({description:"Session name or ID to clean or dismiss."})),dismiss_session:m.Optional(m.Boolean({description:"When true and session is provided, permanently dismiss the worktree."}))}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!Sp(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { workdir?, base_branch?, mode?, dry_run?, session?, dismiss_session? }."}]};let r=n.session,o=n.mode??(n.dry_run===!0?"preview_safe":"clean_safe"),i=o!=="clean_safe",s=o==="preview_all"||o==="clean_safe";if(r&&n.dismiss_session===!0)return{content:[{type:"text",text:await v.dismissWorktree(r)}]};let a=er(v);if(r&&(a=a.filter(f=>tr(f,r)),a.length===0)){let f=ft(v,r);if(!f.persistedSession&&!f.activeSession)return{content:[{type:"text",text:`Error: Session "${r}" not found.`}]}}if(n.workdir&&(a=a.filter(f=>f.workdir===n.workdir)),a.length===0)return{content:[{type:"text",text:"No managed worktrees matched the requested scope."}]};let d=[],l=[],u=[],c=[];for(let f of a){let{persistedSession:g,activeSession:h,resolvedLifecycle:y}=Xn(v,f,{baseBranch:n.base_branch});if(!y.cleanupSafe){if(s){let k=y.reasons.length>0?y.reasons.map(nr).join(", "):ze(y.derivedState);l.push(`${f.name} [kept: ${k}]`)}continue}if(d.push(`${f.name} (${ze(y.derivedState)})`),!i)try{let k=f.workdir;if(!((g??h)&&ne(g??h))&&f.worktreePath&&de(k,f.worktreePath,{destructive:!1}),f.worktreeBranch&&ge(k,f.worktreeBranch),g){let b=y.derivedState==="merged"||y.derivedState==="released"?y.derivedState:y.lifecycle.state;v.updatePersistedSession(f.id,{worktreePath:void 0,worktreeBranch:void 0,lifecycle:"terminal",worktreeState:"none",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeMerged:b==="merged"?!0:g.worktreeMerged,worktreeMergedAt:b==="merged"?g.worktreeMergedAt??new Date().toISOString():g.worktreeMergedAt,worktreeLifecycle:{...g.worktreeLifecycle??y.lifecycle,state:b,updatedAt:new Date().toISOString(),resolvedAt:g.worktreeLifecycle?.resolvedAt??new Date().toISOString(),resolutionSource:g.worktreeLifecycle?.resolutionSource??"maintenance",baseBranch:n.base_branch??y.lifecycle.baseBranch??g.worktreeBaseBranch,targetRepo:g.worktreePrTargetRepo,pushRemote:g.worktreePushRemote,notes:y.reasons}})}u.push(`${f.name} (${ze(y.derivedState)})`)}catch(k){c.push(`${f.name}: ${k instanceof Error?k.message:String(k)}`)}}let p=[o==="clean_safe"?"Clean all safe:":o==="preview_all"?"Worktree lifecycle review:":"Clean all safe preview:"];return p.push(` SAFE ${i?"NOW":"FOUND"} (${d.length}): ${d.join(", ")||"(none)"}`),s&&p.push(` KEPT (${l.length}): ${l.join(", ")||"(none)"}`),i||(p.push(` CLEANED (${u.length}): ${u.join(", ")||"(none)"}`),p.push(` FAILURES (${c.length}): ${c.join(", ")||"(none)"}`)),{content:[{type:"text",text:p.join(`
|
|
102
|
+
`)}]}}}}X();O();jt();function yp(t){return!0}function xa(t){return{name:"agent_worktree_status",description:"Show lifecycle-first worktree status for coding agent sessions. Displays product-facing lifecycle state, released handling, cleanup safety, and retained reasons.",parameters:m.Object({session:m.Optional(m.String({description:"Session name or ID to show status for (optional, shows all if omitted)"}))}),async execute(e,n){if(!v)return{content:[{type:"text",text:"Error: SessionManager not initialized. The code-agent service must be running."}]};if(!yp(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { session? }."}]};let r=n.session,o=er(v);if(r&&(o=o.filter(s=>tr(s,r)),o.length===0))return{content:[{type:"text",text:`Error: Session "${r}" not found or has no worktree.`}]};if(o.length===0)return{content:[{type:"text",text:"No sessions with worktrees found."}]};let i=[];for(let s of o){let{persistedSession:a,resolvedLifecycle:d}=Xn(v,s),l=d.cleanupSafe?"safe now":d.preserve?"preserve":"blocked";i.push(`Session: ${s.name} [${s.id}]`),i.push(` Branch: ${s.worktreeBranch??"(unknown)"} → ${d.lifecycle.baseBranch??a?.worktreeBaseBranch??"main"}`),i.push(` Repo: ${s.workdir}`),i.push(` Lifecycle:${ze(d.lifecycle.state)}`),d.derivedState!==d.lifecycle.state&&i.push(` Derived: ${ze(d.derivedState)}`),i.push(` Cleanup: ${l}`),d.evidence.prUrl&&i.push(` PR: ${d.evidence.prUrl} (${d.evidence.prState??"unknown"})`),(d.evidence.branchAheadCount!=null||d.evidence.baseAheadCount!=null)&&i.push(` Ahead: ${d.evidence.branchAheadCount??0} ahead / ${d.evidence.baseAheadCount??0} behind`),i.push(` Reasons: ${d.reasons.length>0?d.reasons.map(nr).join(", "):"none"}`),i.push("")}return{content:[{type:"text",text:i.join(`
|
|
103
|
+
`).trim()}]}}}}X();O();te();import{existsSync as kp}from"fs";function vp(t=[]){return t.map((e,n)=>({label:`check-${n+1}`,command:e.trim()})).filter(e=>e.command.length>0)}function mr(t,e){let n=t.goal.trim();if(!n)return{kind:"error",text:"Error: goal must not be empty."};let r=t.workdir||e.workspaceDir||E.defaultWorkdir||process.cwd();if(!kp(r))return{kind:"error",text:`Error: Working directory does not exist: ${r}`};let o=vp(t.verifierCommands),i=t.goalMode??(o.length>0?"verifier":"ralph");if(i==="verifier"&&o.length===0)return{kind:"error",text:"Error: verifier mode requires at least one non-empty verifier command."};let s=t.harness??se(),a=t.model??Ze(s),d=sn(s);if(!a&&(s!=="opencode"||d&&d.length>0))return{kind:"error",text:`Error: No default model configured for harness "${s}". Set plugins.entries["openclaw-code-agent"].config.harnesses.${s}.defaultModel or pass model explicitly.`};if(a&&!wn(a,d))return{kind:"error",text:`Error: Model "${a}" is not allowed. Permitted models: ${d?.join(", ")}`};let l=e.sessionKey||void 0,u=an(e),c=Ct(e,u),p=et(e,c,l);return{kind:"resolved",goal:n,name:t.name,workdir:r,model:a,reasoningEffort:Ce(s),fastMode:Xe(s),systemPrompt:t.systemPrompt,allowedTools:t.allowedTools,maxIterations:t.maxIterations,permissionMode:t.permissionMode??"bypassPermissions",harness:s,loopMode:i,completionPromise:t.completionPromise,originChannel:c,originThreadId:p?.threadId,originAgentId:e.agentId||void 0,originSessionKey:l,route:p,verifierCommands:o}}function fr(t,e){return["Goal task launched.",` Name: ${t.name}`,` ID: ${t.id}`,` Dir: ${t.workdir}`,` Session: ${t.sessionName} [${t.sessionId}]`,` Harness: ${e.harness}`,` Model: ${e.model??"default"}`,...e.fastMode?[" Fast mode: enabled"]:[],` Loop mode: ${t.loopMode}`,` Max controller iterations: ${t.maxIterations}`,` Goal: "${e.goal.length>100?`${e.goal.slice(0,100)}...`:e.goal}"`,...t.loopMode==="ralph"?[` Completion promise: ${t.completionPromise}`]:[" Verifiers:",...e.verifierCommands.map(r=>` - ${r.command}`)],"","Controller iteration progress advances only when the goal controller starts another agent turn; internal agent review passes are reported in the completion summary.","","Use goal_status to follow progress or goal_stop to terminate the task."].join(`
|
|
104
|
+
`)}function wp(t){return!t||typeof t!="object"?!1:typeof t.goal=="string"}function Ta(t){return{name:"goal_launch",description:"Launch an explicit goal loop. Use this only when the user specifically asks for a goal task, Ralph-style autonomous loop, iterative loop, autonomous repair loop, or keep-going-until-checks-pass workflow. This is not the default session path.",parameters:m.Object({goal:m.String({description:"End goal for the autonomous task"}),verifier_commands:m.Optional(m.Array(m.String({description:"Shell command that must pass for the goal to be considered complete"}),{minItems:1,description:"Verifier commands run after each coding turn"})),name:m.Optional(m.String({description:"Short task name (kebab-case preferred)"})),workdir:m.Optional(m.String({description:"Working directory (defaults to cwd / configured workspace)"})),model:m.Optional(m.String({description:"Model name to use"})),system_prompt:m.Optional(m.String({description:"Additional system prompt"})),allowed_tools:m.Optional(m.Array(m.String(),{description:"Allowed tools for the underlying agent session"})),max_iterations:m.Optional(m.Number({description:"Maximum verifier-driven repair iterations",minimum:1})),goal_mode:m.Optional(m.Union([m.Literal("ralph"),m.Literal("verifier")],{description:"Loop strategy. 'ralph' repeats until a completion promise appears. 'verifier' repeats until verifier commands pass. Defaults to 'ralph' when no verifiers are provided, otherwise 'verifier'."})),completion_promise:m.Optional(m.String({description:"Exact completion promise for Ralph-mode loops. Defaults to 'DONE'."})),permission_mode:m.Optional(m.Union([m.Literal("default"),m.Literal("plan"),m.Literal("bypassPermissions")],{description:"Permission mode for the underlying agent session. Defaults to bypassPermissions for autonomous goal loops."})),harness:m.Optional(m.String({description:"Agent harness to use ('claude-code', 'codex', or experimental 'opencode')."}))}),async execute(e,n){if(!q)return{content:[{type:"text",text:"Error: GoalController not initialized. The code-agent service must be running."}]};if(!wp(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected at least { goal }."}]};let r=mr({goal:n.goal,verifierCommands:n.verifier_commands,name:n.name,workdir:n.workdir,model:n.model,systemPrompt:n.system_prompt,allowedTools:n.allowed_tools,maxIterations:n.max_iterations,permissionMode:n.permission_mode,harness:n.harness,goalMode:n.goal_mode,completionPromise:n.completion_promise},t);if(r.kind!=="resolved")return{content:[{type:"text",text:r.text}]};try{let o=await q.launchTask({goal:r.goal,name:r.name,workdir:r.workdir,model:r.model,reasoningEffort:r.reasoningEffort,fastMode:r.fastMode,systemPrompt:r.systemPrompt,allowedTools:r.allowedTools,maxIterations:r.maxIterations,permissionMode:r.permissionMode,loopMode:r.loopMode,completionPromise:r.completionPromise,originChannel:r.originChannel,originThreadId:r.originThreadId,originAgentId:r.originAgentId,originSessionKey:r.originSessionKey,route:r.route,harness:r.harness,verifierCommands:r.verifierCommands});return{content:[{type:"text",text:fr(o,r)}]}}catch(o){return{content:[{type:"text",text:`Error launching goal task: ${o instanceof Error?o.message:String(o)}`}]}}}}}X();function oi(t,e){return t.split(`
|
|
105
|
+
`).map(n=>`${e}${n}`)}function Ca(t,e){return t.length<=e?t:`${t.slice(0,e-3).trimEnd()}...`}function Pp(t,e=8,n=600){let r=t.map(i=>i.trimEnd()).filter(i=>i.trim().length>0);if(r.length===0)return;let o=r.slice(-e).join(`
|
|
106
|
+
`);return o.length<=n?o:`...${o.slice(-(n-3))}`}function bp(t,e){let n=e?.trim(),r=(t??"").split(/\r?\n/).map(o=>o.trim().replace(/^[-*]\s+/,"")).filter(o=>o.length>0).filter(o=>!(n&&o===n)).filter(o=>!/^<promise>.*<\/promise>$/.test(o));return r.length===0?[]:r.slice(-3).map(o=>Ca(o,180))}function Ap(t){let e=(t??"").split(/\r?\n/).map(n=>n.trim()).filter(n=>n.length>0);return e.length===0?[]:e.slice(0,2).map(n=>Ca(n,180))}function gr(t){let e=[],n=Ap(t.verifierSummary),r=bp(t.output,t.completionPromise);if(n.length===0&&r.length===0)return;t.completionDetected===!0&&e.push("Completion was claimed, but the loop is continuing after verification.");for(let i of n)e.push(`Verifier: ${i}`);let o=Math.max(0,3-e.length);if(o>0)for(let i of r.slice(-o))e.push(`Agent: ${i}`);return["Iteration summary:",...e.map(i=>`- ${i}`)].join(`
|
|
107
|
+
`)}function ii(t){if(t)return{phase:t.phase,awaitingInput:t.isAwaitingInput??!!t.pendingInputState,latestOutput:Pp(t.getOutput(20))}}function si(t,e,n){let r=t.loopMode??"verifier",o=[`${t.name} [${t.id}]`,` Status: ${t.status}`,...r==="ralph"?[" Loop mode: ralph",` Iteration: ${t.iteration}/${t.maxIterations}`]:[` Repair iteration: ${t.iteration}/${t.maxIterations}`],` Workdir: ${t.workdir}`];return r==="ralph"&&t.completionPromise&&o.push(` Completion promise: ${t.completionPromise}`),t.sessionId&&o.push(` Session: ${t.sessionName??"(unknown)"} [${t.sessionId}]`),e?.phase&&o.push(` Phase: ${e.phase}`),e?.awaitingInput!==void 0&&o.push(` Awaiting input: ${e.awaitingInput?"yes":"no"}`),n&&o.push(...oi(n," ")),t.lastVerifierSummary&&(o.push(" Last verifier:"),o.push(...oi(t.lastVerifierSummary," "))),e?.latestOutput&&(o.push(" Latest activity:"),o.push(...oi(e.latestOutput," "))),t.waitingForUserReason&&o.push(` Waiting on user: ${t.waitingForUserReason}`),t.failureReason&&o.push(` Failure: ${t.failureReason}`),o.join(`
|
|
108
|
+
`)}var Se="Error: GoalController not initialized. The code-agent service must be running.";function hr(t,e,n){let r=n?.trim();if(r){let i=t.getTask(r);if(!i)return`Error: Goal task "${r}" not found.`;let s=i.sessionId?e(i.sessionId):void 0;return si(i,ii(s))}let o=t.listTasks();return o.length===0?"No goal tasks found.":o.map(i=>{let s=i.sessionId?e(i.sessionId):void 0;return si(i,ii(s))}).join(`
|
|
109
|
+
|
|
110
|
+
`)}function Sr(t,e){return t?t.action==="already_terminal"?`Task is already ${t.task.status}.`:`Task "${t.task.name}" (${t.task.id}) stopped.`:`Error: Goal task "${e}" not found.`}function yr(t,e){switch(t.action){case"updated":return`Task "${t.task.name}" (${t.task.id}) goal updated.`;case"not_found":return`Error: Goal task "${e}" not found.`;case"invalid_goal":return"Error: replacement goal must not be empty.";case"not_editable":return t.task.status!=="waiting_for_user"?`Task is already ${t.task.status}.`:`Error: Goal task "${t.task.name}" is ${t.task.status} and cannot be edited.`}}O();function Ma(t){return{name:"goal_status",description:"Show status for explicit goal tasks managed by the goal controller. Use this to inspect one goal task or list all goal tasks.",parameters:m.Object({task:m.Optional(m.String({description:"Task name or ID. Omit to list all tasks."}))}),async execute(e,n){if(!q)return{content:[{type:"text",text:Se}]};let r=n&&typeof n=="object"&&typeof n.task=="string"?n.task:void 0;return{content:[{type:"text",text:hr(q,o=>v?.resolve(o),r)}]}}}}X();O();function Rp(t){return!!t&&typeof t=="object"&&typeof t.task=="string"}function _a(t){return{name:"goal_stop",description:"Stop an explicit goal task and kill its underlying agent session.",parameters:m.Object({task:m.String({description:"Goal task name or ID"})}),async execute(e,n){if(!q)return{content:[{type:"text",text:Se}]};if(!Rp(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { task }."}]};let r=q.stopTask(n.task);return{content:[{type:"text",text:Sr(r,n.task)}]}}}}X();O();function Ip(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.task=="string"&&typeof e.goal=="string"}function Ea(t){return{name:"goal_edit",description:"Edit the goal text for an active goal task without stopping or relaunching its session.",parameters:m.Object({task:m.String({description:"Goal task name or ID"}),goal:m.String({description:"Replacement goal text"})}),async execute(e,n){if(!q)return{content:[{type:"text",text:Se}]};if(!Ip(n))return{content:[{type:"text",text:"Error: Invalid parameters. Expected { task, goal }."}]};let r=q.editTask(n.task,n.goal);return{content:[{type:"text",text:yr(r,n.task)}]}}}}O();pr();import{createHash as xp}from"crypto";var fe="code-agent";var Tp=new Set(["1","true","yes","on"]);function di(){let t=process.env.OPENCLAW_CODE_AGENT_BUTTON_DIAGNOSTICS?.trim().toLowerCase();return!!(t&&Tp.has(t))}function gt(t){if(!(typeof t!="string"||t.length===0))return xp("sha256").update(t).digest("hex").slice(0,12)}function $a(t){return typeof t.callbackData=="string"?t.callbackData:typeof t.value=="string"?t.value:void 0}function H(t){let e=(t??[]).filter(r=>Array.isArray(r)&&r.length>0),n=e.flat();return{buttonRows:e.length||void 0,buttonCount:n.length||void 0,buttonLabels:n.length>0?n.map(r=>typeof r.label=="string"?r.label:void 0):void 0,callbackByteLengths:n.length>0?n.map(r=>{let o=$a(r);return o?Buffer.byteLength(o,"utf8"):void 0}):void 0,callbackHashes:n.length>0?n.map(r=>gt($a(r))):void 0,buttonStyles:n.length>0?n.map(r=>typeof r.style=="string"?r.style:void 0):void 0}}function De(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function Oa(t){let e=De(t),n=Array.isArray(e?.blocks)?e.blocks:void 0;if(n)return n.map(r=>De(r)?.type).filter(r=>typeof r=="string"&&r.length>0)}function Wa(t){let e=De(t),n=Array.isArray(e?.blocks)?e.blocks:void 0;if(!n)return;let r=n.map(o=>{let i=De(o);return i?.type!=="buttons"||!Array.isArray(i.buttons)?[]:i.buttons}).filter(o=>o.length>0);return r.length>0?r:void 0}function li(t){let e=Wa(t);return{presentationBlockTypes:Oa(t),...H(e)}}function ui(t){let e=De(t),n=e?.interactive,r=De(e?.channelData),o=De(r?.telegram),i=Array.isArray(o?.buttons)?o.buttons:void 0;return{renderedPayloadKeys:e?Object.keys(e).sort():void 0,interactiveBlockTypes:Oa(n),...Da("interactive",H(Wa(n))),...Da("telegramChannelData",H(i)),hasPresentation:!!e?.presentation,hasInteractive:!!n,hasTelegramChannelDataButtons:!!i?.some(s=>s.length>0)}}function Na(t){let e=De(t);return e?{sendResultKeys:Object.keys(e).sort(),messageId:ai(e.messageId),chatId:ai(e.chatId),telegramThreadId:ai(e.messageThreadId??e.threadId),channel:typeof e.channel=="string"?e.channel:void 0}:{sendResultType:typeof t}}function ai(t){return typeof t=="string"||typeof t=="number"?t:void 0}function Da(t,e){let n={};for(let[r,o]of Object.entries(e))o!==void 0&&(n[`${t}${r.charAt(0).toUpperCase()}${r.slice(1)}`]=o);return n}function D(t,e){if(!di())return;let n=Object.fromEntries(Object.entries(e).filter(([,r])=>r!==void 0));`${JSON.stringify({event:t,callbackNamespace:fe,...n})}`}function Cp(t){let e=t.trim().replace(new RegExp(`^${fe}:`),"");return e||null}async function kr(t,e,n=!1){try{return(await le(t,{text:e,alreadyAcknowledged:n})).textDelivered}catch(r){let o=r instanceof Error?r.message:String(r);return`${o}`,!1}}function vr(t){if(t&&typeof t=="object"&&"content"in t&&Array.isArray(t.content)){let e=t.content[0];return typeof e?.text=="string"?e.text:"(done)"}return"(done)"}function La(t){if(t&&typeof t=="object"&&"meta"in t){let e=t.meta;if(typeof e?.success=="boolean")return e.success}return ci(vr(t))}function ci(t){return!/^\s*(?:Error\b:?|❌|⚠️)/.test(t)}function Mp(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"}function _p(t,e){if(Mp(t.kind)){if(!e)return"This plan decision is stale because the session is no longer available.";if(t.planDecisionVersion!=null&&(e.actionablePlanDecisionVersion??e.planDecisionVersion)!=null&&t.planDecisionVersion!==(e.actionablePlanDecisionVersion??e.planDecisionVersion))return"This plan decision is stale because a newer plan review state already exists.";if(!e.pendingPlanApproval)return"This plan is no longer awaiting approval.";if(t.kind==="plan-approve"&&e.approvalState==="changes_requested"&&!e.pendingPlanApproval)return"Changes were already requested for this plan. Wait for the revised plan before approving.";if(t.kind==="plan-request-changes"&&e.approvalState==="changes_requested")return"Changes were already requested for this plan. Send your feedback to the agent instead."}}function Ep(t){let e="callback"in t?t.callback?.payload??t.callback?.data:void 0,n="interaction"in t?t.interaction?.payload:void 0;return e??n??""}function Jt(t){let e=t instanceof Error?t.message:String(t);return/message is not modified/i.test(e)}function $p(t){let e=t instanceof Error?t.message:String(t);return/empty message/i.test(e)}async function le(t,e={}){let n=t.respond,{alreadyAcknowledged:r=!1,forceTelegramMarkupEdit:o=!1,text:i}=e;if(t.channel==="telegram"){if(typeof i=="string"&&typeof n.editMessage=="function")try{return await n.editMessage({text:i,buttons:[]}),typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!0}}catch(a){if(Jt(a))return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!0};let d=a instanceof Error?a.message:String(a);`${d}`}if(o&&typeof n.editButtons=="function")try{return await n.editButtons({buttons:[]}),typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1}}catch(a){if(Jt(a))return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1};let d=a instanceof Error?a.message:String(a);`${d}`}let s="callback"in t&&typeof t.callback?.messageText=="string"?t.callback.messageText:void 0;if(o&&typeof s=="string"&&typeof n.editMessage=="function")try{return await n.editMessage({text:s,buttons:[]}),typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1}}catch(a){if(Jt(a))return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1};let d=a instanceof Error?a.message:String(a);`${d}`}return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1}}if(typeof n.clearComponents=="function")try{return await n.clearComponents(typeof i=="string"?{text:i}:void 0),{textDelivered:typeof i=="string"}}catch(s){if(Jt(s))return{textDelivered:typeof i=="string"};if($p(s)){if(typeof i!="string"&&r)return{textDelivered:!1};if(typeof i!="string"&&typeof n.acknowledge=="function")return await n.acknowledge(),{textDelivered:!1};typeof i!="string"&&n.acknowledge}else{if(typeof i!="string")throw s;{let a=s instanceof Error?s.message:String(s);`${a}`}}}if(typeof i=="string"&&typeof n.editMessage=="function"){try{await n.editMessage({text:i})}catch(s){if(Jt(s))return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!0};let a=s instanceof Error?s.message:String(s);return`${a}`,typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1}}return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!0}}return typeof n.clearButtons=="function"&&await n.clearButtons(),{textDelivered:!1}}async function Dp(t){let e=t.respond;if(typeof e.acknowledge!="function")return!1;try{return await e.acknowledge(),!0}catch(n){let r=n instanceof Error?n.message:String(n);return`${r}`,!1}}async function U(t,e){if(t.channel==="telegram"){await t.respond.reply({text:e});return}await t.respond.reply({text:e,ephemeral:!0})}function Ba(t="telegram"){return D("callback_handler_registered",{channel:t,namespace:fe}),{channel:t,namespace:fe,handler:async e=>{let n=await Dp(e);if(!e.auth.isAuthorizedSender)return await U(e,"⛔ Unauthorized."),{handled:!0};let r=Ep(e),o=Cp(r);if(D("callback_received",{channel:e.channel,namespace:fe,payloadByteLength:Buffer.byteLength(r,"utf8"),tokenHash:gt(o),isAuthorizedSender:e.auth.isAuthorizedSender}),!o)return await U(e,"⚠️ Unrecognized callback payload."),{handled:!0};if(!v)return await U(e,"⚠️ Code agent service not running."),{handled:!0};let i=v.getActionToken(o);if(D("callback_token_lookup_completed",{channel:e.channel,namespace:fe,tokenHash:gt(o),tokenFound:!!i,actionKind:i?.kind,sessionId:i?.sessionId,planDecisionVersion:i?.planDecisionVersion}),!i)return await le(e,{alreadyAcknowledged:n}),e.channel!=="telegram"&&await U(e,"⚠️ This action is stale or has already been used."),{handled:!0};let s=i.sessionId,a=v.resolve?.(s)??v.getPersistedSession?.(s),d=a?.name??s,l=_p(i,a);if(D("callback_plan_validation_completed",{channel:e.channel,namespace:fe,tokenHash:gt(o),actionKind:i.kind,sessionId:s,sessionName:d,planDecisionVersion:i.planDecisionVersion,valid:!l}),l)return await le(e,{alreadyAcknowledged:n}),await U(e,`⚠️ ${l}`),{handled:!0};let u=v.consumeActionToken(o);if(D("callback_token_consume_completed",{channel:e.channel,namespace:fe,tokenHash:gt(o),consumed:!!u,actionKind:u?.kind,sessionId:u?.sessionId,planDecisionVersion:u?.planDecisionVersion}),!u)return await le(e,{alreadyAcknowledged:n,forceTelegramMarkupEdit:i.kind==="plan-offer-start"||i.kind==="plan-offer-dismiss"}),e.channel!=="telegram"&&await U(e,"⚠️ This action is stale or has already been used."),{handled:!0};switch(u.kind){case"worktree-merge":{let c=await or().execute("callback",{session:s}),p=vr(c);La(c)&&await kr(e,`✅ Merge selected for [${d}]`,n),await U(e,p);break}case"worktree-decide-later":{let c=v.snoozeWorktreeDecision(s,{notifyUser:!1});if(ci(c)){let f=`⏭️ Snoozed 24h for [${d}]`;await kr(e,f,n)||await U(e,f)}else await U(e,c);break}case"worktree-dismiss":{let c=await v.dismissWorktree(s),p=ci(c);p&&await kr(e,`🗑️ Discarded for [${d}]`,n),await U(e,p?"✅ Discarded":c);break}case"worktree-create-pr":case"worktree-update-pr":{let c=await Qt().execute("callback",{session:s}),p=vr(c);La(c)&&await kr(e,i.kind==="worktree-update-pr"?`📬 PR update selected for [${d}]`:`📬 PR selected for [${d}]`,n),await U(e,p);break}case"worktree-view-pr":{await le(e,{alreadyAcknowledged:n});let c=v.getPersistedSession?.(s),p=i.targetUrl??c?.worktreePrUrl;await U(e,p?`PR: ${p}`:"⚠️ PR URL is no longer available.");break}case"plan-approve":{await le(e,{alreadyAcknowledged:n}),v.clearPlanDecisionTokens(s);let c=await he(v,{session:s,message:"Approved. Go ahead.",approve:!0,userInitiated:!0});c.isError&&await U(e,`⚠️ ${c.text}`);break}case"plan-reject":{await le(e,{alreadyAcknowledged:n});let c=Yo(v,s);await U(e,`❌ ${c.text}`);break}case"plan-request-changes":{await le(e,{alreadyAcknowledged:n});let c=Zo(v,s);await U(e,`✏️ ${c.text}`);break}case"plan-offer-start":{if(!u.launchPrompt||!u.launchWorkdir){await le(e,{alreadyAcknowledged:n,forceTelegramMarkupEdit:!0}),await U(e,"⚠️ This action is missing the plan launch context.");break}let c;try{c=v.launchPlanOffer({route:u.route,prompt:u.launchPrompt,workdir:u.launchWorkdir,name:u.launchName,worktreeStrategy:u.launchWorktreeStrategy})}catch(p){let f=p instanceof Error?p.message:String(p);await U(e,`⚠️ Failed to start planning session: ${f}`);break}await le(e,{alreadyAcknowledged:n,forceTelegramMarkupEdit:!0}),await U(e,`▶️ Planning session started: ${c.name} [${c.id}]`);break}case"plan-offer-dismiss":{await le(e,{alreadyAcknowledged:n,forceTelegramMarkupEdit:!0}),await U(e,"✅ Dismissed.");break}case"session-restart":case"session-resume":{await le(e,{alreadyAcknowledged:n});let c=await he(v,{session:s,message:"Continue where you left off.",userInitiated:!0});await U(e,c.isError?`⚠️ ${c.text}`:`▶️ ${c.text}`);break}case"view-output":{await le(e,{alreadyAcknowledged:n});let c=await Jn().execute("callback",{session:s,lines:50});await U(e,vr(c));break}case"question-answer":{if(await le(e,{alreadyAcknowledged:n}),i.optionIndex==null){await U(e,"⚠️ Invalid question-answer action.");break}await v.resolvePendingInputOption(s,i.optionIndex),await U(e,"✅ Answer submitted.");break}default:{await le(e,{alreadyAcknowledged:n}),await U(e,"⚠️ Unknown callback action.");break}}return{handled:!0}}}}O();te();function ht(t){return Fa(t).map(e=>e.value)}function Fa(t){return Array.from(t.matchAll(/"[^"]*"|'[^']*'|\S+/g),e=>{let n=e[0],r=e.index??0;return{value:Op(n),raw:n,start:r,end:r+n.length}})}function Yt(t){let[e]=Fa(t);if(e)return{value:e.value,rest:t.slice(e.end).trimStart()}}function Op(t){return t.length>1&&(t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'"))?t.slice(1,-1):t}function Wp(t){return t instanceof Error?t.message:String(t)}function Np(t){let e=ht(t),n,r=e;return e[0]==="--name"&&e[1]&&(n=e[1],r=e.slice(2)),{name:n,prompt:r.join(" ").trim()}}function qa(t){t.registerCommand({name:"agent",description:"Launch a coding agent session. Usage: /agent [--name <name>] <prompt>",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!v)return{text:"Error: SessionManager not initialized. The code-agent service must be running."};let n=(e.args??"").trim();if(!n)return{text:"Usage: /agent [--name <name>] <prompt>"};let{name:r,prompt:o}=Np(n);if(!o)return{text:"Usage: /agent [--name <name>] <prompt>"};try{let i=Pn({prompt:o,name:r},e,v);if(i.kind!=="resolved")return{text:i.text};let s=v.spawn({prompt:o,name:r,workdir:i.workdir,model:i.resolvedModel,reasoningEffort:i.reasoningEffort,fastMode:i.fastMode,codexApprovalPolicy:i.harness==="codex"?"never":void 0,originChannel:i.originChannel,originThreadId:i.originThreadId,originAgentId:e.agentId||void 0,originSessionKey:i.originSessionKey,route:i.route,harness:i.harness,permissionMode:i.permissionMode,planApproval:i.planApproval,taskLifecycle:Cn(e)});return{text:v.formatLaunchResult({prompt:o,workdir:i.workdir,harness:i.harness,permissionMode:i.permissionMode??E.permissionMode,planApproval:i.planApproval},s)}}catch(i){let s=Wp(i),a=s.includes("Max sessions")?"":`
|
|
111
|
+
|
|
112
|
+
Use /agent_sessions to see active sessions.`;return{text:`Error launching session: ${s}${a}`}}}})}O();function Ka(t){t.registerCommand({name:"agent_sessions",description:"List coding agent sessions. Usage: /agent_sessions [--full]",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!v)return{text:"Error: SessionManager not initialized. The code-agent service must be running."};let n=(e.args??"").split(/\s+/).includes("--full");return{text:zn(v,"all",void 0,{full:n})}}})}O();function Ua(t){t.registerCommand({name:"agent_kill",description:"Kill a coding agent session by name or ID",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!v)return{text:"Error: SessionManager not initialized. The code-agent service must be running."};let n=e.args?.trim();return n?{text:Qn(v,n,"killed")}:{text:"Usage: /agent_kill <name-or-id>"}}})}O();function Va(t){t.registerCommand({name:"agent_respond",description:"Send a follow-up message to a running coding agent session. Usage: /agent_respond <id-or-name> <message>",acceptsArgs:!0,requireAuth:!0,handler:async e=>{if(!v)return{text:"Error: SessionManager not initialized. The code-agent service must be running."};let n=(e.args??"").trim();if(!n)return{text:`Usage: /agent_respond <id-or-name> <message>
|
|
113
|
+
/agent_respond --interrupt <id-or-name> <message>`};let r=!1,o=n,i=Yt(o);i?.value==="--interrupt"&&(r=!0,o=i.rest);let s=Yt(o);if(!s)return{text:"Error: Missing message. Usage: /agent_respond <id-or-name> <message>"};let a=s.value,d=s.rest;return d.trim()?{text:(await he(v,{session:a,message:d,interrupt:r,userInitiated:!0})).text}:{text:"Error: Empty message. Usage: /agent_respond <id-or-name> <message>"}}})}O();function Ga(t){t.registerCommand({name:"agent_stats",description:"Show OpenClaw Code Agent usage metrics",acceptsArgs:!1,requireAuth:!0,handler:()=>{if(!v)return{text:"Error: SessionManager not initialized. The code-agent service must be running."};let e=v.getMetrics(),n=v.list("running").length;return{text:An(e,n)}}})}O();var Lp=50;function Ha(t){t.registerCommand({name:"agent_output",description:"Show recent output from a coding agent session. Usage: /agent_output <id-or-name> [--full] [--lines N]",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!v)return{text:"Error: SessionManager not initialized. The code-agent service must be running."};let n=(e.args??"").trim();if(!n)return{text:"Usage: /agent_output <id-or-name> [--full] [--lines N]"};let r=ht(n),o="",i=!1,s=Lp;for(let d=0;d<r.length;d++)if(r[d]==="--full")i=!0;else if(r[d]==="--lines"&&d+1<r.length){let l=parseInt(r[d+1],10);!isNaN(l)&&l>0&&(s=l),d++}else o||(o=r[d]);return o?{text:jn(v,o,{full:i,lines:s})}:{text:"Usage: /agent_output <id-or-name> [--full] [--lines N]"}}})}O();var ja="Usage: /goal [--name <name>] [--workdir <dir>] [--model <model>] [--harness <name>] [--mode <ralph|verifier>] [--completion-promise <text>] [--max-iterations N] [--verify <cmd> ...] <goal>";function za(t){t.registerCommand({name:"goal",description:"Launch an explicit goal task (Ralph-style completion loop or verifier-driven loop)",acceptsArgs:!0,requireAuth:!0,handler:async e=>{if(!q)return{text:"Error: GoalController not initialized. The code-agent service must be running."};let n=(e.args??"").trim();if(!n)return{text:ja};let r=ht(n),o,i,s,a,d="bypassPermissions",l,u,c,p=[],f=[];for(let y=0;y<r.length;y++){let k=r[y];if(k==="--name"&&y+1<r.length)o=r[++y];else if(k==="--workdir"&&y+1<r.length)i=r[++y];else if(k==="--model"&&y+1<r.length)s=r[++y];else if(k==="--max-iterations"&&y+1<r.length){let R=parseInt(r[++y],10);!Number.isNaN(R)&&R>0&&(a=R)}else if(k==="--permission-mode"&&y+1<r.length){let R=r[++y];if(R==="default"||R==="plan"||R==="bypassPermissions")d=R;else return{text:`Error: Invalid permission mode "${R}".`}}else if(k==="--harness"&&y+1<r.length)l=r[++y];else if(k==="--mode"&&y+1<r.length){let R=r[++y];if(R==="ralph"||R==="verifier")u=R;else return{text:`Error: Invalid goal mode "${R}". Use ralph or verifier.`}}else if(k==="--completion-promise"&&y+1<r.length)c=r[++y];else if(k==="--verify"&&y+1<r.length){let R=r[++y].trim();if(!R)return{text:"Error: --verify commands must not be empty."};p.push(R)}else f.push(k)}let g=f.join(" ").trim();if(!g)return{text:ja};let h=mr({goal:g,verifierCommands:p,name:o,workdir:i,model:s,maxIterations:a,permissionMode:d,harness:l,goalMode:u,completionPromise:c},e);if(h.kind!=="resolved")return{text:h.text};try{let y=await q.launchTask({goal:h.goal,name:h.name,workdir:h.workdir,model:h.model,reasoningEffort:h.reasoningEffort,fastMode:h.fastMode,maxIterations:h.maxIterations,permissionMode:h.permissionMode,harness:h.harness,loopMode:h.loopMode,completionPromise:h.completionPromise,originChannel:h.originChannel,originThreadId:h.originThreadId,originAgentId:h.originAgentId,originSessionKey:h.originSessionKey,route:h.route,verifierCommands:h.verifierCommands});return{text:fr(y,h)}}catch(y){return{text:`Error launching goal task: ${y instanceof Error?y.message:String(y)}`}}}})}O();function Qa(t){t.registerCommand({name:"goal_status",description:"Show one goal task or list all explicit goal tasks. Usage: /goal_status [<task-id-or-name>]",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!q)return{text:Se};let n=(e.args??"").trim();return{text:hr(q,r=>v?.resolve(r),n)}}})}O();function Ja(t){t.registerCommand({name:"goal_stop",description:"Stop a goal task. Usage: /goal_stop <task-id-or-name>",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!q)return{text:Se};let n=(e.args??"").trim();if(!n)return{text:"Usage: /goal_stop <task-id-or-name>"};let r=q.stopTask(n);return{text:Sr(r,n)}}})}O();var Ya="Usage: /goal_edit <task-id-or-name> <replacement-goal>";function Za(t){t.registerCommand({name:"goal_edit",description:"Edit a running goal task. Usage: /goal_edit <task-id-or-name> <replacement-goal>",acceptsArgs:!0,requireAuth:!0,handler:e=>{if(!q)return{text:Se};let n=(e.args??"").trim();if(!n)return{text:Ya};let r=Yt(n),o=r?.value.trim(),i=r?.rest.trim();if(!o||!i)return{text:Ya};let s=q.editTask(o,i);return{text:yr(s,o)}}})}import{execFile as Yp}from"child_process";import{createHash as dd}from"crypto";import{existsSync as Bp,mkdirSync as Fp,readFileSync as qp,renameSync as Kp,writeFileSync as Up}from"fs";import{homedir as Vp}from"os";import{dirname as Gp,join as Xa}from"path";function Hp(t){let e=t.OPENCLAW_HOME?.trim();return e||Xa(Vp(),".openclaw")}function jp(t){let e=t.OPENCLAW_CODE_AGENT_GOAL_TASKS_PATH?.trim();return e||Xa(Hp(t),"code-agent-goal-tasks.json")}function zp(t){return t instanceof Error?t.message:String(t)}function Qp(t){if(!t||typeof t!="object")return;let e=t;if(!(typeof e.provider!="string"||typeof e.target!="string"))return{provider:e.provider,target:e.target,accountId:typeof e.accountId=="string"?e.accountId:void 0,threadId:typeof e.threadId=="string"?e.threadId:void 0,sessionKey:typeof e.sessionKey=="string"?e.sessionKey:void 0}}function Jp(t){if(!t||typeof t!="object")return;let e=t;if(typeof e.id!="string"||typeof e.name!="string"||typeof e.goal!="string"||typeof e.workdir!="string"||typeof e.status!="string")return;let n=e.status,r=n==="running"||n==="waiting_for_session"?"waiting_for_session":n;return{id:e.id,name:e.name,goal:e.goal,workdir:e.workdir,status:r,createdAt:typeof e.createdAt=="number"?e.createdAt:Date.now(),updatedAt:typeof e.updatedAt=="number"?e.updatedAt:Date.now(),iteration:typeof e.iteration=="number"?e.iteration:0,maxIterations:typeof e.maxIterations=="number"?e.maxIterations:8,sessionId:typeof e.sessionId=="string"?e.sessionId:void 0,sessionName:typeof e.sessionName=="string"?e.sessionName:void 0,harnessSessionId:typeof e.harnessSessionId=="string"?e.harnessSessionId:void 0,model:typeof e.model=="string"?e.model:void 0,reasoningEffort:typeof e.reasoningEffort=="string"?e.reasoningEffort:void 0,fastMode:e.fastMode===!0?!0:void 0,systemPrompt:typeof e.systemPrompt=="string"?e.systemPrompt:void 0,allowedTools:Array.isArray(e.allowedTools)?e.allowedTools.filter(o=>typeof o=="string"):void 0,originChannel:typeof e.originChannel=="string"?e.originChannel:void 0,originThreadId:typeof e.originThreadId=="string"||typeof e.originThreadId=="number"?e.originThreadId:void 0,originAgentId:typeof e.originAgentId=="string"?e.originAgentId:void 0,originSessionKey:typeof e.originSessionKey=="string"?e.originSessionKey:void 0,route:Qp(e.route),harness:typeof e.harness=="string"?e.harness:void 0,permissionMode:typeof e.permissionMode=="string"?e.permissionMode:void 0,loopMode:e.loopMode==="ralph"?"ralph":"verifier",completionPromise:typeof e.completionPromise=="string"?e.completionPromise:void 0,verifierCommands:Array.isArray(e.verifierCommands)?e.verifierCommands.filter(o=>!!o&&typeof o=="object"&&typeof o.label=="string"&&typeof o.command=="string"):[],lastVerifierSummary:typeof e.lastVerifierSummary=="string"?e.lastVerifierSummary:void 0,lastVerifierFingerprint:typeof e.lastVerifierFingerprint=="string"?e.lastVerifierFingerprint:void 0,repeatedFailureCount:typeof e.repeatedFailureCount=="number"?e.repeatedFailureCount:0,waitingForUserReason:typeof e.waitingForUserReason=="string"?e.waitingForUserReason:void 0,failureReason:typeof e.failureReason=="string"?e.failureReason:void 0}}var wr=class{path;tasks=new Map;constructor(e=process.env){this.path=jp(e),this.load()}load(){try{if(!Bp(this.path))return;let e=qp(this.path,"utf8"),n=JSON.parse(e);if(!Array.isArray(n))return;for(let r of n){let o=Jp(r);o&&this.tasks.set(o.id,o)}this.save()}catch{}}save(){try{Fp(Gp(this.path),{recursive:!0});let e=`${this.path}.tmp`;Up(e,JSON.stringify([...this.tasks.values()],null,2),"utf8"),Kp(e,this.path)}catch(e){`${this.path}${zp(e)}`}}upsert(e){this.tasks.set(e.id,e),this.save()}get(e){let n=this.tasks.get(e);return n||[...this.tasks.values()].find(r=>r.name===e)}list(){return[...this.tasks.values()].sort((e,n)=>n.createdAt-e.createdAt)}};ve();var Zp=8,ld=600*1e3,Xp=4e3,pi=1200,em="DONE",tm=["BASH_ENV","ENV"];function nm(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,48)||"goal-task"}function St(t,e){return t.length<=e?t:`${t.slice(0,e-3)}...`}function Oe(t,e=20){let n=t.split(/\r?\n/).map(r=>r.trimEnd()).filter(r=>r.trim().length>0);return n.length<=e?n.join(`
|
|
116
114
|
`):n.slice(-e).join(`
|
|
117
|
-
`)}function
|
|
118
|
-
`):void 0}function
|
|
119
|
-
`);return
|
|
115
|
+
`)}function rm(t){let e=(t??"").split(/\r?\n/).map(n=>n.trim()).filter(n=>n.length>0).filter(n=>!/^Iteration summary:$/i.test(n)).map(n=>n.replace(/^[-*]\s+/,""));return e.length>0?e.join(`
|
|
116
|
+
`):void 0}function ed(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function td(t){let e=t?.trim();return e&&e.length>0?e:em}function om(t){return t.route??Rt(t.originChannel,t.originThreadId,t.originSessionKey)}function mi(t){return t.map((e,n)=>({label:e.label.trim()||`check-${n+1}`,command:e.command.trim(),timeoutMs:e.timeoutMs??ld})).filter(e=>e.command.length>0)}function im(t){return t.loopMode==="verifier"}function sm(t){return mi(t.verifierCommands).length>0}function nd(t){return im(t)&&!sm(t)}function Pr(){return"Verifier-mode goal tasks require at least one verifier command."}function rd(t){let e=t.steps.filter(n=>!n.ok).map(n=>`${n.label}:${n.exitCode}:${Oe(n.output,12)}`).join(`
|
|
117
|
+
`);return dd("sha1").update(e).digest("hex")}function am(t){return dd("sha1").update(Oe(t,24)).digest("hex")}function od(t){let e=t.toLowerCase().replace(/\s+/g," ").trim();if(!e)return;if(/\b(can i|may i|should i|do you want me to|would you like me to)\b/.test(e)&&/\b(read|write|edit|modify|change|inspect|search|run|execute|install|delete|move|rename|open)\b/.test(e))return"Yes, proceed.";if(/\b(should i continue|shall i continue|want me to continue|should i proceed|shall i proceed|can i proceed|go ahead)\b/.test(e))return"Yes, continue."}function dm(t){if(t.loopMode==="ralph")return["You are working inside a Ralph Wiggum-style autonomous loop.","","Goal:",t.goal,"","Loop rules:","- Keep making concrete progress toward the goal in this repository.","- An external controller will continue looping until you emit the completion promise or the iteration budget is exhausted.",`- When the goal is truly complete, output this exact marker on its own line: <promise>${t.completionPromise}</promise>`,"- Do not output that completion marker early, approximately, or with altered spelling.","- If you are not done yet, do not emit the completion marker.","- Do not ask to stop or wait for confirmation unless blocked by a real product, architecture, credential, or approval decision.","- Re-run useful local checks before ending each turn.",t.verifierCommands.length>0?"- External verifier commands will also be run after you claim completion.":"- There may not be external verifiers, so your completion promise is the success gate."].join(`
|
|
120
118
|
`);let e=t.verifierCommands.map(n=>`- ${n.label}: ${n.command}`).join(`
|
|
121
119
|
`);return["You are working on an autonomous goal-driven task.","","Goal:",t.goal,"","Working rules:","- Make concrete progress toward the goal in this repository.","- An external controller will run these verifier commands after your turn:",e,"- If any verifier fails, you will receive the exact failures and must continue fixing the remaining gaps.","- Do not stop early just because you think the task is probably done.","- Do not ask for confirmation unless you are blocked by a real product, architecture, or credential decision.","- Before ending a turn, run any local checks you think are useful."].join(`
|
|
122
|
-
`)}function
|
|
120
|
+
`)}function id(t){return t.loopMode==="ralph"?["The OpenClaw gateway restarted while this Ralph-style goal task was running.","Resume from the prior session context and continue immediately.","","Goal:",t.goal,"","Instructions:","- Continue from the current repo state and prior session context without restarting from scratch.",`- Only emit <promise>${t.completionPromise}</promise> when the goal is actually complete.`,"- The external controller will keep looping until that marker appears or the iteration budget is exhausted.","- Do not ask for confirmation just because the gateway restarted."].join(`
|
|
123
121
|
`):["The OpenClaw gateway restarted while this autonomous goal task was running.","Resume from the prior session context and continue toward the same goal immediately.","","Goal:",t.goal,"","Instructions:","- Re-orient yourself from the existing repo state and prior session context.","- Continue the task without restarting from scratch unless the prior approach is clearly invalid.","- The external controller will continue running verifier commands after your turns.","- Do not ask for confirmation just because the gateway restarted."].join(`
|
|
124
|
-
`)}function
|
|
122
|
+
`)}function lm(t,e){let n=e.steps.filter(o=>!o.ok).map(o=>[`- ${o.label} failed (exit ${o.exitCode})`,Oe(o.output,18)].join(`
|
|
125
123
|
`)).join(`
|
|
126
124
|
|
|
127
125
|
`);return["The external verifier did not pass.",t.repeatedFailureCount>=2?"The same verifier fingerprint has repeated. Use a different debugging strategy than your previous attempt.":"Fix only the remaining issues from the verifier output below.","","Goal:",t.goal,"","Verifier failures:",n,"","Instructions:","- Continue from the current code state and prior session context.","- Make the minimum necessary changes to satisfy the remaining verifier failures.","- Re-run relevant checks yourself before ending the turn.","- Do not ask for confirmation unless you are truly blocked on a human decision."].join(`
|
|
128
|
-
`)}function
|
|
129
|
-
`)}function
|
|
126
|
+
`)}function um(t,e){let n=Oe(e,18)||"(no meaningful output)",r=t.repeatedFailureCount>=2?"The loop has repeated without converging. Use a different strategy than the previous attempt.":"Continue from the current repo state and prior session context.";return["Continue the same Ralph-style goal task.","","Goal:",t.goal,"","Status:",`- The last turn ended without the completion promise <promise>${t.completionPromise}</promise>.`,`- Current iteration: ${t.iteration}/${t.maxIterations}.`,`- ${r}`,"","Latest output / blockers:",n,"","Instructions:","- Keep working until the goal is actually complete.",`- Only emit <promise>${t.completionPromise}</promise> when all requested work is done.`,"- If you are not done, do not emit the completion promise.",t.verifierCommands.length>0?"- If you believe you are done, make sure the expected verifiers are likely to pass before emitting the completion promise.":"- There may not be external verifiers, so your completion promise is the success signal."].join(`
|
|
127
|
+
`)}function cm(t,e){let n=e.steps.filter(r=>!r.ok).map(r=>[`- ${r.label} failed (exit ${r.exitCode})`,Oe(r.output,18)].join(`
|
|
130
128
|
`)).join(`
|
|
131
129
|
|
|
132
130
|
`);return["You emitted the completion promise, but the external verifiers did not pass.","","Goal:",t.goal,"","Verifier failures:",n,"","Instructions:","- Continue from the current repo state and fix only the remaining gaps.",`- Do not emit <promise>${t.completionPromise}</promise> again until the goal is fully complete and the failing checks are addressed.`,"- Re-run relevant checks yourself before ending the turn."].join(`
|
|
133
|
-
`)}function
|
|
134
|
-
`)}function
|
|
135
|
-
${s}`:""}`.trim();n({label:e.label,command:e.command,ok:!
|
|
131
|
+
`)}function pm(t,e){let n=e.trim();if(!n)return!1;let r=new RegExp(`(^|\\n)\\s*${ed(n)}\\s*(\\n|$)`,"i"),o=new RegExp(`<promise>\\s*${ed(n)}\\s*<\\/promise>`,"i");return r.test(t)||o.test(t)}function sd(t){return t.steps.map(e=>`${e.ok?"PASS":"FAIL"} ${e.label} (exit ${e.exitCode}, ${Math.round(e.durationMs)}ms)`).join(`
|
|
132
|
+
`)}function Qe(t){return t instanceof Error?t.message:String(t)}function ad(t){return t==="succeeded"||t==="failed"||t==="stopped"}function mm(t){return St(t.error?.trim()||"Underlying session failed.",pi)}function fm(t=process.env){let e={...t};for(let n of tm)delete e[n];return e}function gm(t,e){return new Promise(n=>{let r=Date.now();Yp("bash",["-lc",e.command],{cwd:t,timeout:e.timeoutMs??ld,maxBuffer:1024*1024,env:fm()},(o,i,s)=>{let a=Date.now()-r,d=typeof o?.code=="number"?o.code:o?1:0,l=`${i??""}${s?`
|
|
133
|
+
${s}`:""}`.trim();n({label:e.label,command:e.command,ok:!o,exitCode:d,durationMs:a,output:St(l||"(no output)",Xp)})})})}var br=class{store;sessionManager;restorePromise=null;inFlight=new Set;observerDisposers=new Map;scheduledEvaluations=new Map;dirtyEvaluations=new Set;dirtyEvaluationSessionIds=new Map;started=!1;constructor(e){this.sessionManager=e,this.store=new wr}start(){this.started||(this.started=!0,!this.restorePromise&&(this.restorePromise=this.restoreRecoverableTasks().catch(e=>{`${Qe(e)}`}).finally(()=>{this.restorePromise=null})))}stop(){this.started=!1,this.clearScheduledEvaluations(),this.detachSessionObservers(),this.captureRecoverableTasks(),this.store.save()}listTasks(){return this.store.list()}getTask(e){return this.store.get(e)}async launchTask(e){let n=e.loopMode??"verifier",r=mi(e.verifierCommands);if(n==="verifier"&&r.length===0)throw new Error(Pr());let i={id:Mn(8),name:nm(e.name??e.goal),goal:e.goal.trim(),workdir:e.workdir,status:"waiting_for_session",createdAt:Date.now(),updatedAt:Date.now(),iteration:0,maxIterations:e.maxIterations??Zp,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,systemPrompt:e.systemPrompt,allowedTools:e.allowedTools,originChannel:e.originChannel,originThreadId:e.originThreadId,originAgentId:e.originAgentId,originSessionKey:e.originSessionKey,route:e.route,harness:e.harness,permissionMode:e.permissionMode??"bypassPermissions",loopMode:n,completionPromise:td(e.completionPromise),verifierCommands:r,repeatedFailureCount:0},s=await this.spawnTaskSession(i,dm(i));return this.attachSessionObservers(i,s),i.sessionId=s.id,i.sessionName=s.name,i.harnessSessionId=s.harnessSessionId,i.status="running",i.updatedAt=Date.now(),this.store.upsert(i),this.scheduleTaskEvaluation(i.id,"launch",s.id),this.notify(i,`🎯 [${i.name}] Goal task started
|
|
136
134
|
|
|
137
135
|
Goal:
|
|
138
|
-
${
|
|
136
|
+
${St(i.goal,500)}`,"goal-task-started"),i}stopTask(e){let n=this.store.get(e);if(n)return ad(n.status)?{task:n,action:"already_terminal"}:(n.sessionId&&this.sessionManager.kill(n.sessionId,"user"),this.markTaskStopped(n,"Stopped by user."),{task:n,action:"stopped"})}editTask(e,n){let r=n.trim();if(!r)return{action:"invalid_goal"};let o=this.store.get(e);if(!o)return{action:"not_found"};if(ad(o.status)||o.status==="waiting_for_user")return{action:"not_editable",task:o};let i=o.goal;return o.goal=r,o.updatedAt=Date.now(),this.store.upsert(o),this.notify(o,`✏️ [${o.name}] Goal task edited
|
|
139
137
|
|
|
140
138
|
Goal:
|
|
141
|
-
${
|
|
142
|
-
`));return this.attachSessionObservers(e,
|
|
139
|
+
${St(o.goal,500)}`,"goal-task-edited"),{action:"updated",task:o,previousGoal:i}}async spawnTaskSession(e,n){return this.spawnManagedTaskSession(e,n)}async spawnManagedTaskSession(e,n,r){let o=r?this.sessionManager.resolveHarnessSessionId(r)??r:void 0,i=r?this.sessionManager.resolve(r):void 0,s=o?this.sessionManager.getPersistedSession(o)??this.sessionManager.getPersistedSession(r??o):void 0,{resumeSessionId:a}=tt({requestedResumeSessionId:o,activeSession:i?{harnessSessionId:i.harnessSessionId}:void 0,persistedSession:s?{harness:s.harness,backendRef:s.backendRef}:void 0}),d={prompt:n,name:e.name,workdir:e.workdir,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,systemPrompt:e.systemPrompt,allowedTools:e.allowedTools,originChannel:e.originChannel,originThreadId:e.originThreadId,originAgentId:e.originAgentId,originSessionKey:e.originSessionKey,route:om(e),permissionMode:e.permissionMode,multiTurn:!0,goalTaskId:e.id,harness:e.harness,resumeSessionId:a,resumeWorktreeFrom:o,worktreeStrategy:"off"};return this.sessionManager.spawnAndAwaitRunning(d,{notifyLaunch:!1})}async resumeTaskSession(e,n,r){if(!r.harnessSessionId){let i=await this.spawnTaskSession(e,["The previous session ended without a resumable harness session id.","Continue working on the same goal.","",n].join(`
|
|
140
|
+
`));return this.attachSessionObservers(e,i),i}let o=await this.spawnManagedTaskSession(e,n,r.harnessSessionId);return this.attachSessionObservers(e,o),o}resolveResumeSessionId(e){if(e.harnessSessionId)return e.harnessSessionId;if(e.sessionId){let r=this.sessionManager.resolveHarnessSessionId(e.sessionId);if(r)return r}let n=this.sessionManager.resolveHarnessSessionId(e.name);if(n)return n}captureRecoverableTasks(){for(let e of this.store.list()){if(e.status!=="running"&&e.status!=="waiting_for_session")continue;let n=e.sessionId?this.sessionManager.resolve(e.sessionId):void 0;n&&(e.sessionId=n.id,e.sessionName=n.name,e.harnessSessionId=n.harnessSessionId??e.harnessSessionId,e.route=n.route??e.route,e.updatedAt=Date.now(),e.status="waiting_for_session",this.store.upsert(e))}}async restoreRecoverableTasks(){for(let e of this.store.list()){if(!this.started)break;if(e.status==="waiting_for_user"){this.markTaskFailed(e,"Goal task was waiting for user input and cannot continue autonomously");continue}if(e.status!=="waiting_for_session"&&e.status!=="running")continue;if(nd(e)){this.markTaskFailed(e,Pr());continue}if(e.sessionId){let r=this.sessionManager.resolve(e.sessionId);if(r&&(r.status==="starting"||r.status==="running"))continue}let n=this.resolveResumeSessionId(e);if(!n){this.markTaskFailed(e,"Goal task could not be resumed after gateway restart because no resumable session id was available.");continue}try{let r=await this.spawnManagedTaskSession(e,id(e),n);if(!this.started){e.sessionId=r.id,e.sessionName=r.name,e.harnessSessionId=r.harnessSessionId??n,e.route=r.route??e.route,e.status="waiting_for_session",e.updatedAt=Date.now(),this.store.upsert(e),this.sessionManager.kill(r.id,"shutdown");break}this.attachSessionObservers(e,r),e.sessionId=r.id,e.sessionName=r.name,e.harnessSessionId=r.harnessSessionId??n,e.route=r.route??e.route,e.status="running",e.updatedAt=Date.now(),this.store.upsert(e),this.notifyIterationStatus(e,`🔄 [${e.name}] Goal task resumed after gateway restart`,r),this.scheduleTaskEvaluation(e.id,"restore",r.id)}catch(r){this.markTaskFailed(e,`Failed to resume the goal task after gateway restart: ${Qe(r)}`)}}}async runVerifiers(e){let n=mi(e.verifierCommands);if(n.length===0){let s={status:"fail",steps:[{label:"verifier-config",command:"(none configured)",ok:!1,exitCode:1,durationMs:0,output:Pr()}],summary:"",fingerprint:""};return s.fingerprint=rd(s),s.summary=sd(s),s}let r=[];for(let s of n)r.push(await gm(e.workdir,s));let i={status:r.every(s=>s.ok)?"pass":"fail",steps:r,summary:"",fingerprint:""};return i.fingerprint=rd(i),i.summary=sd(i),i}notify(e,n,r){this.sessionManager.emitGoalTaskUpdate(e,n,r)}notifyIterationStatus(e,n,r,o){let i=e.loopMode==="ralph"?"iteration":"repair iteration",s=/\b(?:repair\s+)?iteration\s+\d+\/\d+\b/i.test(n)?n:`${n} ${i} ${e.iteration}/${e.maxIterations}`,a=rm(o),d=a?`${s}
|
|
143
141
|
|
|
144
|
-
${a}`:s;this.notify(e,d,"goal-task-progress")}setTaskRunningWithSession(e,n){e.sessionId=n.id,e.sessionName=n.name,e.harnessSessionId=n.harnessSessionId,e.route=n.route??e.route,e.status="running",e.waitingForUserReason=void 0,e.updatedAt=Date.now(),this.store.upsert(e)}attachSessionObservers(e,n){if(this.observerDisposers.has(n.id))return;let r=(
|
|
142
|
+
${a}`:s;this.notify(e,d,"goal-task-progress")}setTaskRunningWithSession(e,n){e.sessionId=n.id,e.sessionName=n.name,e.harnessSessionId=n.harnessSessionId,e.route=n.route??e.route,e.status="running",e.waitingForUserReason=void 0,e.updatedAt=Date.now(),this.store.upsert(e)}attachSessionObservers(e,n){if(this.observerDisposers.has(n.id))return;let r=(i,s)=>{(s==="completed"||s==="failed"||s==="killed")&&(this.removeSessionObserver(n.id),this.scheduleTaskEvaluation(e.id,`status:${s}`,n.id))},o=()=>{let i=this.store.get(e.id);i&&(i.sessionId=n.id,i.sessionName=n.name,i.harnessSessionId=n.harnessSessionId,i.route=n.route??i.route,i.updatedAt=Date.now(),i.status==="waiting_for_session"&&(i.status="running"),this.store.upsert(i),this.notifyIterationStatus(i,`🔄 [${i.name}] Coding turn complete`,n),this.scheduleTaskEvaluation(e.id,"turnEnd",n.id))};n.on("statusChange",r),n.on("turnEnd",o),this.observerDisposers.set(n.id,()=>{n.off?.("statusChange",r),n.off?.("turnEnd",o),n.removeListener?.("statusChange",r),n.removeListener?.("turnEnd",o)})}scheduleTaskEvaluation(e,n,r){if(!this.started)return;let o=this.scheduledEvaluations.get(e);if(o){!o.sessionId&&r&&(o.sessionId=r);return}let i={timer:setTimeout(()=>{this.scheduledEvaluations.delete(e),this.evaluateTask(e,n,i.sessionId).catch(s=>{`${n}${Qe(s)}`})},0),sessionId:r};i.timer.unref?.(),this.scheduledEvaluations.set(e,i)}clearScheduledEvaluations(){for(let e of this.scheduledEvaluations.values())clearTimeout(e.timer);this.scheduledEvaluations.clear(),this.dirtyEvaluations.clear(),this.dirtyEvaluationSessionIds.clear()}detachSessionObservers(){for(let e of[...this.observerDisposers.keys()])this.removeSessionObserver(e)}removeSessionObserver(e){let n=this.observerDisposers.get(e);n&&(this.observerDisposers.delete(e),n())}markTaskFailed(e,n){e.status="failed",e.failureReason=St(n,pi),e.updatedAt=Date.now(),this.store.upsert(e),this.notify(e,`❌ [${e.name}] Goal task failed
|
|
145
143
|
|
|
146
144
|
${e.failureReason}`,"goal-task-failed")}markTaskFailedWaitingForUser(e,n){this.markTaskFailed(e,`Goal task was waiting for user input and cannot continue autonomously: ${n}`)}markTaskSucceeded(e,n){e.status="succeeded",e.lastVerifierSummary=n,e.updatedAt=Date.now(),this.store.upsert(e),this.notify(e,`✅ [${e.name}] Goal task succeeded
|
|
147
145
|
|
|
148
|
-
${n}`,"goal-task-succeeded")}markTaskStopped(e,n){e.status="stopped",e.failureReason=
|
|
146
|
+
${n}`,"goal-task-succeeded")}markTaskStopped(e,n){e.status="stopped",e.failureReason=St(n,pi),e.updatedAt=Date.now(),this.store.upsert(e),this.notify(e,`⛔ [${e.name}] Goal task stopped
|
|
149
147
|
|
|
150
|
-
${e.failureReason}`,"goal-task-stopped")}async handleRunningSession(e,n){if(n.pendingPlanApproval){let s=await
|
|
151
|
-
`),
|
|
152
|
-
`);if(n.pendingPlanApproval){let a=await
|
|
148
|
+
${e.failureReason}`,"goal-task-stopped")}async handleRunningSession(e,n){if(n.pendingPlanApproval){let s=await he(this.sessionManager,{session:n.id,message:"Approved. Implement the plan.",approve:!0,userInitiated:!1});s.isError&&this.markTaskFailed(e,s.text);return}if(!n.pendingInputState){this.setTaskRunningWithSession(e,n);return}let r=n.getOutput(30).join(`
|
|
149
|
+
`),o=od(r);if(!o){this.markTaskFailedWaitingForUser(e,Oe(r,24)||"The session is waiting for user input.");return}let i=await he(this.sessionManager,{session:n.id,message:o,userInitiated:!1});if(i.isError||i.text.includes("Auto-respond limit reached")){this.markTaskFailedWaitingForUser(e,i.text);return}e.status="running",e.waitingForUserReason=void 0,e.updatedAt=Date.now(),this.store.upsert(e)}async resumeAfterIdleTimeout(e,n,r){try{let o=await this.resumeTaskSession(e,r,n);this.setTaskRunningWithSession(e,o),this.notifyIterationStatus(e,`🔄 [${e.name}] Goal task resumed after idle timeout`,o),this.scheduleTaskEvaluation(e.id,"idle-timeout-resume",o.id)}catch(o){this.markTaskFailed(e,`Failed to resume the goal task after idle timeout: ${Qe(o)}`)}}async handleTerminalSession(e,n){if(n.status==="failed"){this.markTaskFailed(e,mm(n));return}if(n.status==="killed"&&n.killReason==="user"){this.markTaskStopped(e,"Stopped by user.");return}if(n.status==="killed"&&n.killReason==="idle-timeout"){let s=n.getOutput(60).join(`
|
|
150
|
+
`);if(n.pendingPlanApproval){let a=await he(this.sessionManager,{session:n.id,message:"Approved. Implement the plan.",approve:!0,userInitiated:!1});if(a.isError){this.markTaskFailed(e,a.text);return}let d=this.sessionManager.resolve(n.id);if(!d){this.markTaskFailed(e,"Failed to resolve the resumed goal task session after idle timeout plan approval.");return}this.attachSessionObservers(e,d),this.setTaskRunningWithSession(e,d),this.notifyIterationStatus(e,`🔄 [${e.name}] Goal task resumed after idle timeout`,d),this.scheduleTaskEvaluation(e.id,"idle-timeout-plan-resume",d.id);return}if(n.pendingInputState){let a=od(s);if(!a){this.markTaskFailed(e,`Goal task was waiting for user input and cannot continue autonomously: ${Oe(s,24)||"The goal task hit idle timeout while waiting for user input."}`);return}await this.resumeAfterIdleTimeout(e,n,["The previous session hit idle timeout while waiting for a response.",`Use this response and continue the goal: ${a}`].join(`
|
|
153
151
|
|
|
154
|
-
`));return}await this.resumeAfterIdleTimeout(e,n,
|
|
155
|
-
`),a=
|
|
152
|
+
`));return}await this.resumeAfterIdleTimeout(e,n,id(e));return}if(n.status==="killed"&&n.killReason!=="done"){this.markTaskFailed(e,`Underlying session was killed (${n.killReason}).`);return}if(e.loopMode==="ralph"){let s=n.getOutput(200).join(`
|
|
153
|
+
`),a=td(e.completionPromise);if(pm(s,a)){if(e.verifierCommands.length===0){this.markTaskSucceeded(e,`Completion promise "${a}" detected in agent output.`);return}let p=await this.runVerifiers(e);if(e.lastVerifierSummary=p.summary,e.updatedAt=Date.now(),p.status==="pass"){this.markTaskSucceeded(e,[`Completion promise "${a}" detected.`,p.summary].join(`
|
|
156
154
|
`));return}if(e.lastVerifierFingerprint===p.fingerprint?e.repeatedFailureCount+=1:e.repeatedFailureCount=1,e.lastVerifierFingerprint=p.fingerprint,e.iteration+1>=e.maxIterations){this.markTaskFailed(e,[`Goal task emitted completion promise but verifiers still failed before hitting the iteration budget (${e.maxIterations}).`,p.summary].join(`
|
|
157
|
-
`));return}e.iteration+=1;let f=
|
|
158
|
-
`));return}e.iteration+=1;let u=
|
|
159
|
-
`));return}e.iteration+=1;let
|
|
160
|
-
`);return(t??"")+i}function um(t,e){let n=t.resumeWorktreeFrom??t.resumeSessionId;if(!n)return{};let r=e(n);if(!r)return{};let i=!!r.harness||!!r.backendRef,o=(()=>{if(r.workdir&&r.workdir!==r.worktreePath)return r.workdir;if(r.worktreePath){let a=On(r.worktreePath);return r.workdir&&a&&hr(r.workdir,a)?r.workdir:a??r.workdir}return r.workdir})();if(t.worktreeStrategy||(r.worktreeLifecycle?.state==="pr_open"||r.worktreePrUrl?t.worktreeStrategy="auto-pr":r.worktreeStrategy&&(t.worktreeStrategy=r.worktreeStrategy)),!t.planApproval&&r.planApproval&&(t.planApproval=r.planApproval),!r.worktreePath){let a=i&&gn(Mt({persistedHarness:r.harness,backendRef:r.backendRef}));return{originalWorkdir:o,canCreateManagedWorktreeForResumeWithoutPersistedPath:a}}if(!r.worktreeBranch)throw new Error(`Cannot resume session "${n}": persisted worktree metadata is missing worktreeBranch.`);let s=gn(Mt({persistedHarness:r.harness,backendRef:r.backendRef}))&&!!r.backendRef?.worktreePath;if(am(r.worktreePath))return`${r.worktreePath}`,{actualWorkdir:r.worktreePath,originalWorkdir:o??r.worktreePath,worktreePath:r.worktreePath,worktreeBranchName:r.worktreeBranch};if(!o)return`${r.worktreePath}`,{clearedResumeSessionId:!!t.resumeSessionId,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom};if(s)return`${r.worktreePath}`,{actualWorkdir:o,originalWorkdir:o,worktreeBranchName:r.worktreeBranch,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom,restoredMissingNativeBackendWorktree:!0};try{Nn(o);let a=$i(o,r.worktreeBranch.replace(/^agent\//,""),{allowExistingBranch:!0});return`${r.worktreeBranch}${a}`,{actualWorkdir:a,originalWorkdir:o,worktreePath:a,worktreeBranchName:r.worktreeBranch}}catch(a){return`${Xa(a)}`,{actualWorkdir:o,originalWorkdir:o,clearedResumeSessionId:!!t.resumeSessionId,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom,failedResumeWorktreeRestore:!0}}}function ed(t,e,n){let{actualWorkdir:r,originalWorkdir:i,worktreePath:o,worktreeBranchName:s,clearedResumeSessionId:a,clearedResumeWorktreeFrom:d,restoredMissingNativeBackendWorktree:l,canCreateManagedWorktreeForResumeWithoutPersistedPath:u,failedResumeWorktreeRestore:c}=um(t,n);a&&(t.resumeSessionId=void 0),d&&(t.resumeWorktreeFrom=void 0),r??=t.workdir,i??=t.workdir;let p=!!(t.resumeSessionId??t.resumeWorktreeFrom),f=t.worktreeStrategy??C.defaultWorktreeStrategy;f&&(t.worktreeStrategy=f);let g=dm(t),y=(!p||!!u)&&!l&&!o&&f&&f!=="off"&&!g;if(c&&f&&f!=="off")throw new Error(`Cannot launch session "${e}": worktree strategy "${f}" was requested, but no isolated worktree was prepared. Launch with worktree_strategy "off" only when running in the base checkout is intentional.`);if(g&&!Mi(i))throw new Error(`Cannot launch session "${e}": worktree strategy "${f}" requires a git worktree, but "${i}" is not a git repository.`);if(y&&Mi(i)){if(!Is(i))throw new Error(`Cannot launch session "${e}": insufficient space for worktree creation.`);try{if(o=$i(i,e),r=o,s=Wn(o),!s)throw new Error(`created worktree at ${o} but failed to resolve branch name`);`${o}`}catch(S){throw new Error(`Cannot launch session "${e}": worktree creation failed: ${Xa(S)}`)}}else if(y)throw new Error(`Cannot launch session "${e}": worktree strategy "${f}" requires a git worktree, but "${i}" is not a git repository.`);if(p&&o&&(r=o),f&&f!=="off"&&!o)throw new Error(`Cannot launch session "${e}": worktree strategy "${f}" was requested, but no isolated worktree was prepared. Launch with worktree_strategy "off" only when running in the base checkout is intentional.`);return{actualWorkdir:r,originalWorkdir:i,effectiveSystemPrompt:o&&s?lm(t.systemPrompt,i,o,s):t.systemPrompt,worktreePath:o,worktreeBranchName:s,clearedResumeSessionId:a,clearedResumeWorktreeFrom:d,restoredMissingNativeBackendWorktree:l,failedResumeWorktreeRestore:c}}var yr=class{constructor(e){this.getPersistedSession=e}getPersistedSession;prepareSpawn(e,n){return ed(e,n,this.getPersistedSession)}hydrateSpawnedSession(e,n,r){r.worktreeStrategy&&r.worktreeStrategy!=="off"&&(e.originalWorkdir=n.originalWorkdir),n.worktreePath&&(e.worktreePath=n.worktreePath,e.worktreeBranch=n.worktreeBranchName,e.worktreeState="provisioned"),r.worktreePrTargetRepo&&(e.worktreePrTargetRepo=r.worktreePrTargetRepo)}};V();var Sr=class{constructor(e){this.deps=e}deps;applySessionPatch(e,n){let r=this.normalizeCompletionWakePatch(n),i=this.deps.store.getPersistedSession(e);i&&(Object.assign(i,r),this.deps.store.assertPersistedEntry(i));let o=this.findActiveSessionForRef(e,i);return o&&this.applyPatchToActiveSession(o,r),!i&&!o?!1:(i&&this.deps.store.saveIndex(),!0)}normalizeCompletionWakePatch(e){return"completionWakeSucceededAt"in e&&e.completionWakeSucceededAt||"completionWakeSkippedAt"in e&&e.completionWakeSkippedAt?{...e,completionWakeSummaryRequired:void 0}:e}matchesExistingSession(e,n){if(!n)return!1;let r=x(e),i=x(n);return!!(n.sessionId&&e.id===n.sessionId||i&&i===r||n?.harnessSessionId&&e.harnessSessionId===n.harnessSessionId||n?.name&&e.name===n.name)}findActiveSessionForRef(e,n){let r=this.deps.resolveSession(e);if(r)return r;for(let i of this.deps.sessions.values())if(D(i)===e||x(i)===e||i.harnessSessionId===e||this.matchesExistingSession(i,n))return i}applyPatchToActiveSession(e,n){this.applyControlStatePatch(e,n),this.applySessionMetadataPatch(e,n),this.applyWorktreeMetadataPatch(e,n)}applyControlStatePatch(e,n){let r={lifecycle:n.lifecycle,approvalState:n.approvalState,approvalExecutionState:n.approvalExecutionState,worktreeState:n.worktreeState,runtimeState:n.runtimeState,deliveryState:n.deliveryState,requestedPermissionMode:n.requestedPermissionMode,currentPermissionMode:n.currentPermissionMode,pendingPlanApproval:n.pendingPlanApproval,planApprovalContext:n.planApprovalContext,planDecisionVersion:n.planDecisionVersion,actionablePlanDecisionVersion:n.actionablePlanDecisionVersion,canonicalPlanPromptVersion:n.canonicalPlanPromptVersion,approvalPromptRequiredVersion:n.approvalPromptRequiredVersion,approvalPromptVersion:n.approvalPromptVersion,approvalPromptStatus:n.approvalPromptStatus,approvalPromptTransport:n.approvalPromptTransport,approvalPromptMessageKind:n.approvalPromptMessageKind,approvalPromptLastAttemptAt:n.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:n.approvalPromptDeliveredAt,approvalPromptFailedAt:n.approvalPromptFailedAt,planModeApproved:n.planModeApproved,pendingWorktreeDecisionSince:n.pendingWorktreeDecisionSince};if(typeof e.applyControlPatch=="function"){e.applyControlPatch(r);return}this.assignIfDefined(e,"lifecycle",n.lifecycle),this.assignIfDefined(e,"approvalState",n.approvalState),this.assignIfDefined(e,"approvalExecutionState",n.approvalExecutionState),this.assignIfDefined(e,"worktreeState",n.worktreeState),this.assignIfDefined(e,"runtimeState",n.runtimeState),this.assignIfDefined(e,"deliveryState",n.deliveryState),this.assignIfDefined(e,"requestedPermissionMode",n.requestedPermissionMode),this.assignIfDefined(e,"currentPermissionMode",n.currentPermissionMode),this.assignIfDefined(e,"pendingPlanApproval",n.pendingPlanApproval),this.assignIfDefined(e,"planApprovalContext",n.planApprovalContext),this.assignIfDefined(e,"planDecisionVersion",n.planDecisionVersion),this.assignIfDefined(e,"actionablePlanDecisionVersion",n.actionablePlanDecisionVersion),this.assignIfDefined(e,"canonicalPlanPromptVersion",n.canonicalPlanPromptVersion),this.assignIfDefined(e,"approvalPromptRequiredVersion",n.approvalPromptRequiredVersion),this.assignIfDefined(e,"approvalPromptVersion",n.approvalPromptVersion),this.assignIfDefined(e,"approvalPromptStatus",n.approvalPromptStatus),this.assignIfDefined(e,"approvalPromptTransport",n.approvalPromptTransport),this.assignIfDefined(e,"approvalPromptMessageKind",n.approvalPromptMessageKind),this.assignIfDefined(e,"approvalPromptLastAttemptAt",n.approvalPromptLastAttemptAt),this.assignIfDefined(e,"approvalPromptDeliveredAt",n.approvalPromptDeliveredAt),this.assignIfDefined(e,"approvalPromptFailedAt",n.approvalPromptFailedAt),this.setControlFieldIfDefined(e,"planModeApproved",n.planModeApproved)}applySessionMetadataPatch(e,n){this.assignIfDefined(e,"approvalRationale",n.approvalRationale)}applyWorktreeMetadataPatch(e,n){this.assignIfDefined(e,"worktreePath",n.worktreePath),this.assignIfDefined(e,"worktreeBranch",n.worktreeBranch),this.assignIfDefined(e,"worktreePrUrl",n.worktreePrUrl),this.assignIfDefined(e,"worktreePrNumber",n.worktreePrNumber),this.assignIfDefined(e,"worktreeMerged",n.worktreeMerged),this.assignIfDefined(e,"worktreeMergedAt",n.worktreeMergedAt),this.assignIfDefined(e,"worktreeDisposition",n.worktreeDisposition),this.assignIfDefined(e,"worktreePrTargetRepo",n.worktreePrTargetRepo),this.assignIfDefined(e,"worktreePushRemote",n.worktreePushRemote),this.assignIfDefined(e,"worktreeLifecycle",n.worktreeLifecycle),"autoMergeParentSessionId"in n&&(e.autoMergeParentSessionId=n.autoMergeParentSessionId),"autoMergeConflictResolutionAttemptCount"in n&&(e.autoMergeConflictResolutionAttemptCount=n.autoMergeConflictResolutionAttemptCount),"autoMergeResolverSessionId"in n&&(e.autoMergeResolverSessionId=n.autoMergeResolverSessionId)}assignIfDefined(e,n,r){r!==void 0&&(e[n]=r)}setControlFieldIfDefined(e,n,r){r!==void 0&&e.setControlField?.(n,r)}};V();var cm=new Set(["starting","running"]),kr=class{constructor(e,n){this.sessions=e;this.store=n}sessions;store;resolveActive(e){let n=this.sessions.get(e);return n||(this.findPreferredMatch(e,r=>r.name===e)??this.findPreferredMatch(e,r=>x(r)===e)??this.findPreferredMatch(e,r=>r.harnessSessionId===e))}getPersistedSession(e){return this.store.getPersistedSession(e)}resolveBackendConversationId(e){let n=this.resolveActive(e);return this.store.resolveBackendConversationId(e,n?x(n)??n.harnessSessionId:void 0)}findPreferredMatch(e,n){let r,i;for(let o of this.sessions.values())n(o,e)&&((!i||o.startedAt>i.startedAt)&&(i=o),cm.has(o.status)&&(!r||o.startedAt>r.startedAt)&&(r=o));return r??i}};V();V();ue();var td=new Set(["merged","released","pr_open","dismissed","cleanup_failed"]),vr=class{constructor(e){this.deps=e}deps;async plan(e){let n=D(e)??e.harnessSessionId;if(this.deps.isAlreadyMerged(n))return`${e.name}`,{kind:"skip",result:{notificationSent:!0,worktreeRemoved:!1}};let r=td.has(e.worktreeState)?e.worktreeState:e.worktreeLifecycle?.state&&td.has(e.worktreeLifecycle.state)?e.worktreeLifecycle.state:void 0;if(r&&!(r==="pr_open"&&e.worktreeStrategy==="auto-pr"))return`${e.name}${e.worktreeLifecycle?.state??e.worktreeState}`,{kind:"skip",result:{notificationSent:!0,worktreeRemoved:!1}};if(e.status!=="completed")return{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}};if(!this.deps.shouldRunWorktreeStrategy(e))return`${e.name}${e.phase}`,{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}};let i=e.worktreeStrategy;if(!i||i==="off"||i==="manual")return{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}};let o=e.worktreePath,s=this.deps.resolveWorktreeRepoDir(e.originalWorkdir,o),a=e.worktreeBranch;if(!s)return{kind:"notify",label:"worktree-missing-repo-dir",message:`⚠️ [${e.name}] Cannot determine the original repo for worktree ${o}. Manual inspection is required.`};if(!a)return{kind:"notify",label:"worktree-no-branch-name",message:`⚠️ [${e.name}] Cannot determine branch name for worktree ${o}. The worktree may have been removed or is in detached HEAD state. Manual cleanup may be needed.`};let d=e.worktreeBaseBranch??ke(s),l=this.deps.getWorktreeCompletionState(s,o,a,d);if(l==="no-change")return{kind:"no-change",repoDir:s,worktreePath:o,nativeBackendWorktree:ie(e)};if(l==="base-advanced")return{kind:"notify",label:"worktree-no-commits-ahead",message:`⚠️ [${e.name}] Auto-merge: branch '${a}' has no commits ahead of '${d}', but '${d}' has new commits — commits likely landed outside the worktree branch. Verify that commits were not made directly to '${d}' instead of the worktree branch. Worktree: ${o}`};if(l==="dirty-uncommitted")return{kind:"dirty-uncommitted",worktreePath:o,branchName:a,baseBranch:d};let u=be(s,a,d);return u?{kind:"decision",strategy:i,repoDir:s,worktreePath:o,branchName:a,baseBranch:d,diffSummary:u,sessionRef:n??void 0}:(`${a}`,{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}})}};or();function pm(t){if(t.requestedPermissionMode==="plan"){if(t.approvalExecutionState==="approved_then_implemented"){if(t.planApproval==="ask"&&t.approvalPromptStatus==="delivered"&&t.approvalPromptMessageKind==="canonical_buttons"&&t.approvalPromptDeliveredAt)return"Approval interpretation: canonical Approve/Revise/Reject buttons were delivered, and implementation after approval was expected.";if(t.approvalState==="approved")return"Approval interpretation: explicit plan approval was recorded before implementation, so leaving plan-only mode was expected."}if(t.approvalExecutionState==="implemented_without_required_approval")return"Approval interpretation: implementation left plan-only mode without a recorded approval."}}function mm(){return/https?:\/\/github\.com\/[^\s)]+\/[^\s)]+\/pull\/(\d+)(?=[\s).,;:]|$)/gi}function fm(){return/https?:\/\/\S+/gi}function wr(t){let e=pm(t);return[`Requested permission mode: ${t.requestedPermissionMode??"unknown"}`,`Effective permission mode: ${t.currentPermissionMode??"unknown"}`,`Deterministic approval/execution state: ${t.approvalExecutionState??"unknown"}`,...e?[e]:[]]}function jt(t){switch(t){case"user":return"Stopped by user";case"shutdown":return"Stopped by shutdown";case"startup-timeout":return"Stopped by startup timeout";case"unknown":case void 0:return"Stopped unexpectedly";default:return"Stopped"}}function gm(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToOrdinaryTerminalCompletions:!0}}function hm(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToWorktreeTerminalOutcomes:!0}}function ym(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToGoalTaskCompletions:!0}}function eo(t){let{sessionId:e,canonicalStatusDetail:n,canonicalStatusDelivered:r=!0,hasOriginRouteBlock:i=!1}=t,o=i?["7. Before sending that follow-up, honor the Session origin route block above. If originRoute differs from the current chat, do NOT use a plain final assistant reply; use a routed send path that preserves provider/target/threadId."]:[],s=i?8:7,a=i?9:8;return["[ACTION REQUIRED] Follow your autonomy rules for session completion:",`1. Use agent_output(session='${e}', full=true) to read the full result.`,"2. If this is part of a multi-phase pipeline, launch the next phase NOW — do not wait for user input.",`3. ${n??(r?"The plugin already sent the canonical completion status to the user.":"The plugin did not confirm delivery of the canonical completion status to the user.")}`,"4. Treat the completed session output as source material, not visible delivery. A meaningful final summary inside agent_output is not enough to skip, because the user may only have seen the plugin's terse status line.","5. If the visible result is only the plugin's terse status line, use the full output to send the user one short factual completion summary for this completed session. Do this even when agent_output already contains a good final summary.","6. This requirement applies to ordinary terminal/manual completions too, not just delegated worktree decisions.",...o,`${s}. That follow-up belongs to you alone; keep it brief, concrete, and grounded in reliable result data. Send at most one orchestrator-owned human summary for this terminal/worktree outcome.`,...r?[`${a}. Do NOT repeat the plugin's status line, and do NOT rely on the plugin to summarize the completed work for you.`]:[`${a}. Because canonical status delivery was not confirmed, account for that gap yourself when you follow up; do NOT assume the plugin already reached the user.`],`${a+1}. Send a normal concise final response after any routed follow-up is visibly sent. Do not use marker text, do not answer NO_REPLY, and do not ask the user whether they want the summary.`]}function Sm(t){let{contract:e,canonicalStatusDelivered:n}=t;return["Completion diagnostics:",`- Canonical completion status delivered to user: ${n?"yes":"no"}`,`- Plugin requested short factual follow-up summary: ${e.requiresShortFactualSummary?"yes":"no"}`,`- Contract applies to ordinary terminal/manual completions: ${e.appliesToOrdinaryTerminalCompletions?"yes":"no"}`]}function to(t){let{session:e,originThreadLine:n,preview:r}=t,i=!!n.trim(),o=`$${(e.costUsd??0).toFixed(2)}`,s=ye(e.duration),a=gm(),d=l=>["Coding agent session completed.",`Name: ${e.name} | ID: ${e.id}`,`Status: ${e.status}`,...i?[n]:[],...wr(e),"","Output preview:",r,"",...Sm({contract:a,canonicalStatusDelivered:l}),"",...eo({sessionId:e.id,canonicalStatusDelivered:l,hasOriginRouteBlock:i})].join(`
|
|
161
|
-
`);return{userMessage:`✅ [${e.name}] Completed | ${
|
|
162
|
-
`)}function
|
|
163
|
-
`)}function
|
|
164
|
-
`),wakeMessage:["Coding agent session failed.",`Name: ${e.name} | ID: ${e.id}`,`Status: ${e.status}`,n,...
|
|
165
|
-
`),buttons:s}}function
|
|
166
|
-
`)}}function
|
|
167
|
-
`)}function
|
|
168
|
-
`)}function
|
|
169
|
-
`)}var
|
|
170
|
-
`).map(e=>e.trim()).filter(Boolean).map(
|
|
171
|
-
`).map(e=>e.trim()).filter(Boolean).map(
|
|
155
|
+
`));return}e.iteration+=1;let f=cm(e,p),g=gr({output:s,verifierSummary:p.summary,completionPromise:a,completionDetected:!0});try{let h=await this.resumeTaskSession(e,f,n);this.setTaskRunningWithSession(e,h),this.notifyIterationStatus(e,`🔁 [${e.name}] Completion claimed but verifiers still failed`,void 0,g),this.scheduleTaskEvaluation(e.id,"ralph-verifier-resume",h.id)}catch(h){this.markTaskFailed(e,`Failed to resume the Ralph goal task after verifier failure: ${Qe(h)}`)}return}let l=am(s);if(e.lastVerifierFingerprint===l?e.repeatedFailureCount+=1:e.repeatedFailureCount=1,e.lastVerifierFingerprint=l,e.iteration+1>=e.maxIterations){this.markTaskFailed(e,[`Completion promise "${a}" was not emitted before hitting the iteration budget (${e.maxIterations}).`,"Latest output:",Oe(s,20)||"(no output)"].join(`
|
|
156
|
+
`));return}e.iteration+=1;let u=um(e,s),c=gr({output:s,completionPromise:a,completionDetected:!1});try{let p=await this.resumeTaskSession(e,u,n);this.setTaskRunningWithSession(e,p),this.notifyIterationStatus(e,`🔁 [${e.name}] Continued`,void 0,c),this.scheduleTaskEvaluation(e.id,"ralph-continue",p.id)}catch(p){this.markTaskFailed(e,`Failed to continue the Ralph goal task: ${Qe(p)}`)}return}let r=await this.runVerifiers(e);if(e.lastVerifierSummary=r.summary,e.updatedAt=Date.now(),r.status==="pass"){this.markTaskSucceeded(e,r.summary);return}if(e.lastVerifierFingerprint===r.fingerprint?e.repeatedFailureCount+=1:e.repeatedFailureCount=1,e.lastVerifierFingerprint=r.fingerprint,e.iteration+1>=e.maxIterations){this.markTaskFailed(e,[`Verifier did not pass before hitting the iteration budget (${e.maxIterations}).`,r.summary].join(`
|
|
157
|
+
`));return}e.iteration+=1;let o=lm(e,r),i=gr({verifierSummary:r.summary});try{let s=await this.resumeTaskSession(e,o,n);this.setTaskRunningWithSession(e,s),this.notifyIterationStatus(e,`🔁 [${e.name}] Repair iteration started after verifier failure`,void 0,i),this.scheduleTaskEvaluation(e.id,"repair-resume",s.id)}catch(s){this.markTaskFailed(e,`Failed to resume the goal task: ${Qe(s)}`)}}async evaluateTask(e,n,r){this.restorePromise&&await this.restorePromise;let o=this.store.get(e);o&&await this.reconcileTask(o,n,r)}async reconcileTask(e,n="manual",r){if(!(e.status==="succeeded"||e.status==="failed"||e.status==="stopped")){if(this.inFlight.has(e.id)){this.dirtyEvaluations.add(e.id),!this.dirtyEvaluationSessionIds.get(e.id)&&r?this.dirtyEvaluationSessionIds.set(e.id,r):this.dirtyEvaluationSessionIds.has(e.id)||this.dirtyEvaluationSessionIds.set(e.id,r);return}this.inFlight.add(e.id);try{if(r&&e.sessionId&&e.sessionId!==r){let i=this.sessionManager.resolve(r);if(i&&(i.status==="completed"||i.status==="failed"||i.status==="killed"))return}let o=r?this.sessionManager.resolve(r)??(e.sessionId?this.sessionManager.resolve(e.sessionId):void 0):e.sessionId?this.sessionManager.resolve(e.sessionId):void 0;if(e.status==="waiting_for_user"){this.markTaskFailed(e,"Goal task was waiting for user input and cannot continue autonomously");return}if(nd(e)){this.markTaskFailed(e,Pr());return}if(!o){this.markTaskFailed(e,"Underlying session could not be found.");return}if(e.sessionName=o.name,e.harnessSessionId=o.harnessSessionId,e.route=o.route??e.route,e.updatedAt=Date.now(),this.store.upsert(e),o.status==="starting"||o.status==="running"){await this.handleRunningSession(e,o);return}await this.handleTerminalSession(e,o)}finally{if(this.inFlight.delete(e.id),this.dirtyEvaluations.has(e.id)){this.dirtyEvaluations.delete(e.id);let o=this.dirtyEvaluationSessionIds.get(e.id);this.dirtyEvaluationSessionIds.delete(e.id),this.scheduleTaskEvaluation(e.id,`${n}:dirty`,o)}}}}};te();import{existsSync as hm,realpathSync as Sm}from"fs";import{resolve as ym}from"path";function ud(t){if(!t)return;let e=ym(t);try{if(hm(e))return Sm.native(e)}catch{}return e}function Ar(t,e){return!t||!e?!1:ud(t)===ud(e)}Q();te();import{existsSync as km}from"fs";Q();me();function cd(t){return t instanceof Error?t.message:String(t)}function vm(t){let e=t.worktreeStrategy??E.defaultWorktreeStrategy;return!!e&&e!=="off"&&Wo(Ot({harnessName:t.harness??se(),backendRef:t.backendRef}))}function wm(t,e,n,r){let o=["","You are working in a git worktree.",`Worktree path: ${n}`,`Branch: ${r}`,"",`IMPORTANT: ALL file edits must be made within this worktree at ${n}.`,`Do NOT edit files directly in ${e} (the original workspace).`,`If your task references files by absolute path under ${e}, rewrite those`,"paths relative to your current working directory. For example:",` "${e}/src/file.py" → use relative path "src/file.py"`,"","Before finishing, run `git status --short` in this worktree.","If you made actual task changes, commit all of them to this branch before finishing.","Use `git add` and `git commit`. If no repository changes are needed, leave the worktree clean before finishing.","Do NOT run `git checkout`, `git switch`, or `git reset --hard` as these will detach or corrupt the worktree HEAD.","","When making changes, please note:","- Do NOT commit planning documents, investigation notes, or analysis artifacts to this branch","- Only commit actual code, configuration, tests, and documentation changes that were explicitly requested as part of the task"].join(`
|
|
158
|
+
`);return(t??"")+o}function Pm(t,e){let n=t.resumeWorktreeFrom??t.resumeSessionId;if(!n)return{};let r=e(n);if(!r)return{};let o=!!r.harness||!!r.backendRef,i=(()=>{if(r.workdir&&r.workdir!==r.worktreePath)return r.workdir;if(r.worktreePath){let a=Bn(r.worktreePath);return r.workdir&&a&&Ar(r.workdir,a)?r.workdir:a??r.workdir}return r.workdir})();if(t.worktreeStrategy||(r.worktreeLifecycle?.state==="pr_open"||r.worktreePrUrl?t.worktreeStrategy="auto-pr":r.worktreeStrategy&&(t.worktreeStrategy=r.worktreeStrategy)),!t.planApproval&&r.planApproval&&(t.planApproval=r.planApproval),!r.worktreePath){let a=o&&kn(Ot({persistedHarness:r.harness,backendRef:r.backendRef}));return{originalWorkdir:i,canCreateManagedWorktreeForResumeWithoutPersistedPath:a}}if(!r.worktreeBranch)throw new Error(`Cannot resume session "${n}": persisted worktree metadata is missing worktreeBranch.`);let s=kn(Ot({persistedHarness:r.harness,backendRef:r.backendRef}))&&!!r.backendRef?.worktreePath;if(km(r.worktreePath))return`${r.worktreePath}`,{actualWorkdir:r.worktreePath,originalWorkdir:i??r.worktreePath,worktreePath:r.worktreePath,worktreeBranchName:r.worktreeBranch};if(!i)return`${r.worktreePath}`,{clearedResumeSessionId:!!t.resumeSessionId,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom};if(s)return`${r.worktreePath}`,{actualWorkdir:i,originalWorkdir:i,worktreeBranchName:r.worktreeBranch,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom,restoredMissingNativeBackendWorktree:!0};try{Fn(i);let a=Uo(i,r.worktreeBranch.replace(/^agent\//,""),{allowExistingBranch:!0});return`${r.worktreeBranch}${a}`,{actualWorkdir:a,originalWorkdir:i,worktreePath:a,worktreeBranchName:r.worktreeBranch}}catch(a){return`${cd(a)}`,{actualWorkdir:i,originalWorkdir:i,clearedResumeSessionId:!!t.resumeSessionId,clearedResumeWorktreeFrom:!!t.resumeWorktreeFrom,failedResumeWorktreeRestore:!0}}}function pd(t,e,n){let{actualWorkdir:r,originalWorkdir:o,worktreePath:i,worktreeBranchName:s,clearedResumeSessionId:a,clearedResumeWorktreeFrom:d,restoredMissingNativeBackendWorktree:l,canCreateManagedWorktreeForResumeWithoutPersistedPath:u,failedResumeWorktreeRestore:c}=Pm(t,n);a&&(t.resumeSessionId=void 0),d&&(t.resumeWorktreeFrom=void 0),r??=t.workdir,o??=t.workdir;let p=!!(t.resumeSessionId??t.resumeWorktreeFrom),f=t.worktreeStrategy??E.defaultWorktreeStrategy;f&&(t.worktreeStrategy=f);let g=vm(t),y=(!p||!!u)&&!l&&!i&&f&&f!=="off"&&!g;if(c&&f&&f!=="off")throw new Error(`Cannot launch session "${e}": worktree strategy "${f}" was requested, but no isolated worktree was prepared. Launch with worktree_strategy "off" only when running in the base checkout is intentional.`);if(g&&!qo(o))throw new Error(`Cannot launch session "${e}": worktree strategy "${f}" requires a git worktree, but "${o}" is not a git repository.`);if(y&&qo(o)){if(!Us(o))throw new Error(`Cannot launch session "${e}": insufficient space for worktree creation.`);try{if(i=Uo(o,e),r=i,s=ut(i),!s)throw new Error(`created worktree at ${i} but failed to resolve branch name`);`${i}`}catch(k){throw new Error(`Cannot launch session "${e}": worktree creation failed: ${cd(k)}`)}}else if(y)throw new Error(`Cannot launch session "${e}": worktree strategy "${f}" requires a git worktree, but "${o}" is not a git repository.`);if(p&&i&&(r=i),f&&f!=="off"&&!i)throw new Error(`Cannot launch session "${e}": worktree strategy "${f}" was requested, but no isolated worktree was prepared. Launch with worktree_strategy "off" only when running in the base checkout is intentional.`);return{actualWorkdir:r,originalWorkdir:o,effectiveSystemPrompt:i&&s?wm(t.systemPrompt,o,i,s):t.systemPrompt,worktreePath:i,worktreeBranchName:s,clearedResumeSessionId:a,clearedResumeWorktreeFrom:d,restoredMissingNativeBackendWorktree:l,failedResumeWorktreeRestore:c}}var Rr=class{constructor(e){this.getPersistedSession=e}getPersistedSession;prepareSpawn(e,n){return pd(e,n,this.getPersistedSession)}hydrateSpawnedSession(e,n,r){r.worktreeStrategy&&r.worktreeStrategy!=="off"&&(e.originalWorkdir=n.originalWorkdir),n.worktreePath&&(e.worktreePath=n.worktreePath,e.worktreeBranch=n.worktreeBranchName,e.worktreeState="provisioned"),r.worktreePrTargetRepo&&(e.worktreePrTargetRepo=r.worktreePrTargetRepo)}};Q();var Ir=class{constructor(e){this.deps=e}deps;applySessionPatch(e,n){let r=this.normalizeCompletionWakePatch(n),o=this.deps.store.getPersistedSession(e);o&&(Object.assign(o,r),this.deps.store.assertPersistedEntry(o));let i=this.findActiveSessionForRef(e,o);return i&&this.applyPatchToActiveSession(i,r),!o&&!i?!1:(o&&this.deps.store.saveIndex(),!0)}normalizeCompletionWakePatch(e){return"completionWakeSucceededAt"in e&&e.completionWakeSucceededAt||"completionWakeSkippedAt"in e&&e.completionWakeSkippedAt?{...e,completionWakeSummaryRequired:void 0}:e}matchesExistingSession(e,n){if(!n)return!1;let r=C(e),o=C(n);return!!(n.sessionId&&e.id===n.sessionId||o&&o===r||n?.harnessSessionId&&e.harnessSessionId===n.harnessSessionId||n?.name&&e.name===n.name)}findActiveSessionForRef(e,n){let r=this.deps.resolveSession(e);if(r)return r;for(let o of this.deps.sessions.values())if(W(o)===e||C(o)===e||o.harnessSessionId===e||this.matchesExistingSession(o,n))return o}applyPatchToActiveSession(e,n){this.applyControlStatePatch(e,n),this.applySessionMetadataPatch(e,n),this.applyWorktreeMetadataPatch(e,n)}applyControlStatePatch(e,n){let r={};if(this.copyControlPatchField(r,n,"lifecycle"),this.copyControlPatchField(r,n,"approvalState"),this.copyControlPatchField(r,n,"approvalExecutionState"),this.copyControlPatchField(r,n,"worktreeState"),this.copyControlPatchField(r,n,"runtimeState"),this.copyControlPatchField(r,n,"deliveryState"),this.copyControlPatchField(r,n,"requestedPermissionMode"),this.copyControlPatchField(r,n,"currentPermissionMode"),this.copyControlPatchField(r,n,"pendingPlanApproval"),this.copyControlPatchField(r,n,"planApprovalContext"),this.copyControlPatchField(r,n,"planDecisionVersion"),this.copyControlPatchField(r,n,"actionablePlanDecisionVersion"),this.copyControlPatchField(r,n,"canonicalPlanPromptVersion"),this.copyControlPatchField(r,n,"approvalPromptRequiredVersion"),this.copyControlPatchField(r,n,"approvalPromptVersion"),this.copyControlPatchField(r,n,"approvalPromptStatus"),this.copyControlPatchField(r,n,"approvalPromptTransport"),this.copyControlPatchField(r,n,"approvalPromptMessageKind"),this.copyControlPatchField(r,n,"approvalPromptLastAttemptAt"),this.copyControlPatchField(r,n,"approvalPromptDeliveredAt"),this.copyControlPatchField(r,n,"approvalPromptFailedAt"),this.copyControlPatchField(r,n,"planModeApproved"),this.copyControlPatchField(r,n,"pendingWorktreeDecisionSince"),typeof e.applyControlPatch=="function"){e.applyControlPatch(r);return}this.assignIfPresent(e,"lifecycle",n,"lifecycle"),this.assignIfPresent(e,"approvalState",n,"approvalState"),this.assignIfPresent(e,"approvalExecutionState",n,"approvalExecutionState"),this.assignIfPresent(e,"worktreeState",n,"worktreeState"),this.assignIfPresent(e,"runtimeState",n,"runtimeState"),this.assignIfPresent(e,"deliveryState",n,"deliveryState"),this.assignIfPresent(e,"requestedPermissionMode",n,"requestedPermissionMode"),this.assignIfPresent(e,"currentPermissionMode",n,"currentPermissionMode"),this.assignIfPresent(e,"pendingPlanApproval",n,"pendingPlanApproval"),this.assignIfPresent(e,"planApprovalContext",n,"planApprovalContext"),this.assignIfPresent(e,"planDecisionVersion",n,"planDecisionVersion"),this.assignIfPresent(e,"actionablePlanDecisionVersion",n,"actionablePlanDecisionVersion"),this.assignIfPresent(e,"canonicalPlanPromptVersion",n,"canonicalPlanPromptVersion"),this.assignIfPresent(e,"approvalPromptRequiredVersion",n,"approvalPromptRequiredVersion"),this.assignIfPresent(e,"approvalPromptVersion",n,"approvalPromptVersion"),this.assignIfPresent(e,"approvalPromptStatus",n,"approvalPromptStatus"),this.assignIfPresent(e,"approvalPromptTransport",n,"approvalPromptTransport"),this.assignIfPresent(e,"approvalPromptMessageKind",n,"approvalPromptMessageKind"),this.assignIfPresent(e,"approvalPromptLastAttemptAt",n,"approvalPromptLastAttemptAt"),this.assignIfPresent(e,"approvalPromptDeliveredAt",n,"approvalPromptDeliveredAt"),this.assignIfPresent(e,"approvalPromptFailedAt",n,"approvalPromptFailedAt"),this.setControlFieldIfPresent(e,"planModeApproved",n)}applySessionMetadataPatch(e,n){this.assignIfDefined(e,"approvalRationale",n.approvalRationale)}applyWorktreeMetadataPatch(e,n){this.assignIfDefined(e,"worktreePath",n.worktreePath),this.assignIfDefined(e,"worktreeBranch",n.worktreeBranch),this.assignIfDefined(e,"worktreePrUrl",n.worktreePrUrl),this.assignIfDefined(e,"worktreePrNumber",n.worktreePrNumber),this.assignIfDefined(e,"worktreeMerged",n.worktreeMerged),this.assignIfDefined(e,"worktreeMergedAt",n.worktreeMergedAt),this.assignIfDefined(e,"worktreeDisposition",n.worktreeDisposition),this.assignIfDefined(e,"worktreePrTargetRepo",n.worktreePrTargetRepo),this.assignIfDefined(e,"worktreePushRemote",n.worktreePushRemote),this.assignIfDefined(e,"worktreeLifecycle",n.worktreeLifecycle),"autoMergeParentSessionId"in n&&(e.autoMergeParentSessionId=n.autoMergeParentSessionId),"autoMergeConflictResolutionAttemptCount"in n&&(e.autoMergeConflictResolutionAttemptCount=n.autoMergeConflictResolutionAttemptCount),"autoMergeResolverSessionId"in n&&(e.autoMergeResolverSessionId=n.autoMergeResolverSessionId)}assignIfDefined(e,n,r){r!==void 0&&(e[n]=r)}assignIfPresent(e,n,r,o){Object.hasOwn(r,o)&&(e[n]=r[o])}copyControlPatchField(e,n,r){Object.hasOwn(n,r)&&(e[r]=n[r])}setControlFieldIfPresent(e,n,r){Object.hasOwn(r,n)&&e.setControlField?.(n,r[n])}};Q();var bm=new Set(["starting","running"]),xr=class{constructor(e,n){this.sessions=e;this.store=n}sessions;store;resolveActive(e){let n=this.sessions.get(e);return n||(this.findPreferredMatch(e,r=>r.name===e)??this.findPreferredMatch(e,r=>C(r)===e)??this.findPreferredMatch(e,r=>r.harnessSessionId===e))}getPersistedSession(e){return this.store.getPersistedSession(e)}resolveBackendConversationId(e){let n=this.resolveActive(e);return this.store.resolveBackendConversationId(e,n?C(n)??n.harnessSessionId:void 0)}findPreferredMatch(e,n){let r,o;for(let i of this.sessions.values())n(i,e)&&((!o||i.startedAt>o.startedAt)&&(o=i),bm.has(i.status)&&(!r||i.startedAt>r.startedAt)&&(r=i));return r??o}};Q();Q();me();var md=new Set(["merged","released","pr_open","dismissed","cleanup_failed"]),Tr=class{constructor(e){this.deps=e}deps;async plan(e){let n=W(e)??e.harnessSessionId;if(this.deps.isAlreadyMerged(n))return`${e.name}`,{kind:"skip",result:{notificationSent:!0,worktreeRemoved:!1}};let r=md.has(e.worktreeState)?e.worktreeState:e.worktreeLifecycle?.state&&md.has(e.worktreeLifecycle.state)?e.worktreeLifecycle.state:void 0;if(r&&!(r==="pr_open"&&e.worktreeStrategy==="auto-pr"))return`${e.name}${e.worktreeLifecycle?.state??e.worktreeState}`,{kind:"skip",result:{notificationSent:!0,worktreeRemoved:!1}};if(e.status!=="completed")return{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}};if(!this.deps.shouldRunWorktreeStrategy(e))return`${e.name}${e.phase}`,{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}};let o=e.worktreeStrategy;if(!o||o==="off"||o==="manual")return{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}};let i=e.worktreePath,s=this.deps.resolveWorktreeRepoDir(e.originalWorkdir,i),a=e.worktreeBranch;if(!s)return{kind:"notify",label:"worktree-missing-repo-dir",message:`⚠️ [${e.name}] Cannot determine the original repo for worktree ${i}. Manual inspection is required.`};if(!a)return{kind:"notify",label:"worktree-no-branch-name",message:`⚠️ [${e.name}] Cannot determine branch name for worktree ${i}. The worktree may have been removed or is in detached HEAD state. Manual cleanup may be needed.`};let d=e.worktreeBaseBranch??be(s),l=this.deps.getWorktreeCompletionState(s,i,a,d);if(l==="no-change")return{kind:"no-change",repoDir:s,worktreePath:i,nativeBackendWorktree:ne(e)};if(l==="merged")return{kind:"merged",repoDir:s,worktreePath:i,branchName:a,nativeBackendWorktree:ne(e)};if(l==="base-advanced")return{kind:"notify",label:"worktree-no-commits-ahead",message:`⚠️ [${e.name}] Auto-merge: branch '${a}' has no commits ahead of '${d}', but '${d}' has new commits — commits likely landed outside the worktree branch. Verify that commits were not made directly to '${d}' instead of the worktree branch. Worktree: ${i}`};if(l==="dirty-uncommitted")return{kind:"dirty-uncommitted",worktreePath:i,branchName:a,baseBranch:d};let u=xe(s,a,d);return u?{kind:"decision",strategy:o,repoDir:s,worktreePath:i,branchName:a,baseBranch:d,diffSummary:u,sessionRef:n??void 0}:(`${a}`,{kind:"skip",result:{notificationSent:!1,worktreeRemoved:!1}})}};cr();function Am(t){if(t.requestedPermissionMode==="plan"){if(t.approvalExecutionState==="approved_then_implemented"){if(t.planApproval==="ask"&&t.approvalPromptStatus==="delivered"&&t.approvalPromptMessageKind==="canonical_buttons"&&t.approvalPromptDeliveredAt)return"Approval interpretation: canonical Approve/Revise/Reject buttons were delivered, and implementation after approval was expected.";if(t.approvalState==="approved")return"Approval interpretation: explicit plan approval was recorded before implementation, so leaving plan-only mode was expected."}if(t.approvalExecutionState==="implemented_without_required_approval")return"Approval interpretation: implementation left plan-only mode without a recorded approval."}}function Rm(){return/https?:\/\/github\.com\/[^\s)]+\/[^\s)]+\/pull\/(\d+)(?=[\s).,;:]|$)/gi}function Im(){return/https?:\/\/\S+/gi}function Cr(t){let e=Am(t);return[`Requested permission mode: ${t.requestedPermissionMode??"unknown"}`,`Effective permission mode: ${t.currentPermissionMode??"unknown"}`,`Deterministic approval/execution state: ${t.approvalExecutionState??"unknown"}`,...e?[e]:[]]}function fi(t){switch(t){case"user":return"Stopped by user";case"shutdown":return"Stopped by shutdown";case"startup-timeout":return"Stopped by startup timeout";case"unknown":case void 0:return"Stopped unexpectedly";default:return"Stopped"}}function xm(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToOrdinaryTerminalCompletions:!0}}function Tm(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToWorktreeTerminalOutcomes:!0}}function Cm(){return{requiresShortFactualSummary:!0,owner:"agent",appliesToGoalTaskCompletions:!0}}function gi(t){let{sessionId:e,canonicalStatusDetail:n,canonicalStatusDelivered:r=!0,hasOriginRouteBlock:o=!1}=t,i=o?["7. Before sending that follow-up, honor the Session origin route block above. If originRoute differs from the current chat, do NOT use a plain final assistant reply; use a routed send path that preserves provider/target/threadId."]:[],s=o?8:7,a=o?9:8;return["[ACTION REQUIRED] Follow your autonomy rules for session completion:",`1. Use agent_output(session='${e}', full=true) to read the full result.`,"2. If this is part of a multi-phase pipeline, launch the next phase NOW — do not wait for user input.",`3. ${n??(r?"The plugin already sent the canonical completion status to the user.":"The plugin did not confirm delivery of the canonical completion status to the user.")}`,"4. Treat the completed session output as source material, not visible delivery. A meaningful final summary inside agent_output is not enough to skip, because the user may only have seen the plugin's terse status line.","5. If the visible result is only the plugin's terse status line, use the full output to send the user one short factual completion summary for this completed session. Do this even when agent_output already contains a good final summary.","6. This requirement applies to ordinary terminal/manual completions too, not just delegated worktree decisions.",...i,`${s}. That follow-up belongs to you alone; keep it brief, concrete, and grounded in reliable result data. Send at most one orchestrator-owned human summary for this terminal/worktree outcome.`,...r?[`${a}. Do NOT repeat the plugin's status line, and do NOT rely on the plugin to summarize the completed work for you.`]:[`${a}. Because canonical status delivery was not confirmed, account for that gap yourself when you follow up; do NOT assume the plugin already reached the user.`],`${a+1}. Send a normal concise final response after any routed follow-up is visibly sent. Do not use marker text, do not answer NO_REPLY, and do not ask the user whether they want the summary.`]}function Mm(t){let{contract:e,canonicalStatusDelivered:n}=t;return["Completion diagnostics:",`- Canonical completion status delivered to user: ${n?"yes":"no"}`,`- Plugin requested short factual follow-up summary: ${e.requiresShortFactualSummary?"yes":"no"}`,`- Contract applies to ordinary terminal/manual completions: ${e.appliesToOrdinaryTerminalCompletions?"yes":"no"}`]}function hi(t){let{session:e,originThreadLine:n,preview:r}=t,o=!!n.trim(),i=`$${(e.costUsd??0).toFixed(2)}`,s=we(e.duration),a=xm(),d=l=>["Coding agent session completed.",`Name: ${e.name} | ID: ${e.id}`,`Status: ${e.status}`,...o?[n]:[],...Cr(e),"","Output preview:",r,"",...Mm({contract:a,canonicalStatusDelivered:l}),"",...gi({sessionId:e.id,canonicalStatusDelivered:l,hasOriginRouteBlock:o})].join(`
|
|
159
|
+
`);return{userMessage:`✅ [${e.name}] Completed | ${i} | ${s}${bn({harness:e.harnessName,model:e.model})}`,wakeMessageOnNotifySuccess:d(!0),wakeMessageOnNotifyFailed:d(!1),followupContract:a}}function yt(t){let e=Tm(),n=!!t.originThreadLine.trim(),r=(t.detailLines??[]).map(i=>fd(i).trim()).filter(i=>i.length>0),o=fd(t.outcomeLine);return["Worktree follow-through outcome recorded.",`Name: ${t.sessionName??"unknown"} | ID: ${t.sessionId}`,...n?[t.originThreadLine]:[],"","Canonical outcome status:",o,...r.length>0?["","Outcome details:",...r.map(i=>`- ${i}`)]:[],"","Completion diagnostics:",`- Canonical worktree status delivered to user: ${t.canonicalStatusDelivered?"yes":"no"}`,`- Plugin requested short factual follow-up summary: ${e.requiresShortFactualSummary?"yes":"no"}`,`- Contract applies to worktree terminal outcomes: ${e.appliesToWorktreeTerminalOutcomes?"yes":"no"}`,"","[ACTION REQUIRED] Follow your autonomy rules for worktree follow-through:",`1. Use agent_output(session='${t.sessionId}', full=true) to read the full result if output is available.`,"2. Treat the completed session output as source material, not visible delivery. A meaningful final summary inside agent_output is not enough to skip, because the user may only have seen the plugin's terse status line.","3. Use the full output plus the canonical outcome facts above to send the user one short factual outcome summary. Do this even when agent_output already contains a good final summary.","4. If full output is unavailable or not meaningful, say only what is proven by the merge/PR facts above; do not invent task details.","5. Mention blockers such as push failure when present; do not describe a local-only merge as pushed.","6. Do not include raw PR URLs in the follow-up summary. The plugin already posted the PR link in the canonical status; refer to PRs by number, repo, and branch instead.",...n?["7. Before sending that follow-up, honor the Session origin route block above. If originRoute differs from the current chat, do NOT use a plain final assistant reply; use a routed send path that preserves provider/target/threadId."]:[],`${n?8:7}. Do NOT repeat only the plugin status line; keep the follow-up brief, concrete, and non-duplicative. Send at most one human-visible summary for this terminal/worktree outcome, counting summaries already sent by the foreground assistant turn or routed message tools.`,`${n?9:8}. Send a normal concise final response after any routed follow-up is visibly sent. Do not use marker text, do not answer NO_REPLY, and do not ask the user whether they want the summary.`].join(`
|
|
160
|
+
`)}function Si(t){let e=Cm(),n=!!t.originThreadLine.trim();return["Goal task succeeded.",`Task: ${t.taskName}`,`Name: ${t.sessionName??t.taskName} | ID: ${t.sessionId}`,...n?[t.originThreadLine]:[],"","Canonical goal status:",t.summary,"","Completion diagnostics:",`- Canonical goal success status delivered to user: ${t.canonicalStatusDelivered?"yes":"no"}`,`- Plugin requested short factual follow-up summary: ${e.requiresShortFactualSummary?"yes":"no"}`,`- Contract applies to goal task completions: ${e.appliesToGoalTaskCompletions?"yes":"no"}`,"","[ACTION REQUIRED] Follow your autonomy rules for goal task completion:",`1. Use agent_output(session='${t.sessionId}', full=true) to read the full result if output is available.`,"2. Treat the completed session output as source material, not visible delivery. A meaningful final summary inside agent_output is not enough to skip, because the user may only have seen the plugin's terse goal status line.","3. Send the user one short factual completion summary grounded in the full output plus the canonical goal status above. Do this even when agent_output already contains a good final summary.","4. If full output is unavailable or not meaningful, say only what is proven by the goal status above; do not invent task details.",...n?["5. Before sending that follow-up, honor the Session origin route block above. If originRoute differs from the current chat, do NOT use a plain final assistant reply; use a routed send path that preserves provider/target/threadId."]:[],`${n?6:5}. Do NOT repeat only the plugin status line; keep the follow-up brief, concrete, and non-duplicative. Send at most one human-visible summary for this goal success outcome, counting summaries already sent by the foreground assistant turn or routed message tools.`,`${n?7:6}. Send a normal concise final response after any routed follow-up is visibly sent. Do not use marker text, do not answer NO_REPLY, and do not ask the user whether they want the summary.`].join(`
|
|
161
|
+
`)}function fd(t){return t.replace(Rm(),"PR #$1").replace(Im(),"[link omitted]")}function yi(t){let{session:e,originThreadLine:n,errorSummary:r,preview:o,worktreeAutoCleaned:i,failedButtons:s}=t,a=o.trim()?["","Output preview:",o]:[],d=i?["","Note: Worktree and branch were auto-removed (zero cost, startup failure)."]:[],l=`$${(e.costUsd??0).toFixed(2)}`,u=we(e.duration);return{userMessage:[`❌ [${e.name}] Failed | ${l} | ${u}${bn({harness:e.harnessName,model:e.model})}`,` ⚠️ ${r}`].join(`
|
|
162
|
+
`),wakeMessage:["Coding agent session failed.",`Name: ${e.name} | ID: ${e.id}`,`Status: ${e.status}`,n,...Cr(e),...e.harnessSessionId?[`Backend conversation ID: ${e.harnessSessionId}`]:[],"","Failure summary:",r,...a,...d,"","[ACTION REQUIRED] Follow your autonomy rules for session failure:",`1. Use agent_output(session='${e.id}', full=true) to inspect the full failure context.`,`2. Continue the same session with agent_respond(session='${e.id}', message='<next instruction>').`,` If you intentionally want to fork or switch harnesses, launch a new session with agent_launch(resume_session_id='${e.id}', fork_session=true, ...)`," If the failure is a launch/config issue, relaunch fresh with agent_launch(prompt=...).","3. Notify the user with the failure cause and the next action you are taking."].join(`
|
|
163
|
+
`),buttons:s}}function ki(t){let{session:e,originThreadLine:n,preview:r}=t,o=`$${(e.costUsd??0).toFixed(2)}`;return{userMessage:`⏸️ [${e.name}] Turn completed | ${o}${bn({harness:e.harnessName,model:e.model})}`,wakeMessage:["Coding agent session turn ended.",`Name: ${e.name}`,`ID: ${e.id}`,`Status: ${e.status}`,`Lifecycle: ${e.lifecycle}`,"","Last output (~20 lines):",r,...n?["",n]:[]].join(`
|
|
164
|
+
`)}}function vi(t){let{sessionName:e,sessionId:n,branchName:r,baseBranch:o,promptSnippet:i,commitLines:s,moreNote:a,originThreadLine:d,diffSummary:l}=t,u=!!d?.trim();return[`[DELEGATED WORKTREE DECISION] Session "${e}" completed with changes.`,"",`Session ID: ${n}`,`Branch: ${r} → ${o}`,`Commits: ${l.commits} | Files: ${l.filesChanged} | +${l.insertions} / -${l.deletions}`,...u?[d]:[],"",...s,...a?[a]:[],"","Original task prompt (first 500 chars):",i,"","You own the next step for this worktree.",`- Merge immediately with agent_merge(session="${e}", base_branch="${o}") if the changes are clearly in-scope and low-risk.`,`- If a PR is safer or human choice is needed, call agent_request_worktree_decision(session="${e}", summary="...") so the user gets the canonical Merge/Open PR/Later/Discard buttons.`,`- If scope or risk is unclear, call agent_request_worktree_decision(session="${e}", summary="...") with a concise risk summary instead of sending a plain-text-only question.`,"- Never call agent_pr() autonomously in delegate mode.","- After deciding, notify the user briefly with what you did and why.",...u?["- Send any human follow-up to the Session origin route above; if it differs from the current chat, do not use a plain final assistant reply."]:[]].join(`
|
|
165
|
+
`)}function wi(t,e){return[`[DELEGATED WORKTREE DECISION REMINDER] Session "${t.name}" still has an unresolved worktree decision.`,"",`Session ID: ${t.sessionId??t.harnessSessionId}`,`Branch: ${t.worktreeBranch??"unknown"}`,`Pending: ${e}h`,"","Resolve it now:",`- agent_merge(session="${t.name}") if the diff is clearly safe and in scope`,"- If a PR is safer, ask the user before agent_pr()","- If scope or risk is unclear, ask the user for guidance","- Never call agent_pr() autonomously in delegate mode"].join(`
|
|
166
|
+
`)}function Pi(t){let{sessionName:e,sessionId:n,cleanupSummary:r,preview:o,originThreadLine:i,requestedPermissionMode:s,currentPermissionMode:a,approvalExecutionState:d,approvalState:l,planApproval:u,approvalPromptStatus:c,approvalPromptMessageKind:p,approvalPromptDeliveredAt:f}=t,g=o.trim()?["","Output preview:",o]:[],h=!!i?.trim();return["Coding agent session completed with no repository changes.",`Name: ${e} | ID: ${n}`,`Worktree outcome: ${r}`,...h?[i]:[],...Cr({requestedPermissionMode:s,currentPermissionMode:a,approvalExecutionState:d,approvalState:l,planApproval:u,approvalPromptStatus:c,approvalPromptMessageKind:p,approvalPromptDeliveredAt:f}),...g,"",...gi({sessionId:n,canonicalStatusDetail:"The plugin already sent the canonical completion status to the user, including that no repo changes were kept.",hasOriginRouteBlock:h})].join(`
|
|
167
|
+
`)}var Sd=3200,bi=3e3,_m=2400,Em=120,$m=5,Dm=280,gd=1400,hd="- Additional plan details omitted for brevity.";function yd(t){return t.replace(/^#{1,6}\s+/,"").replace(/^[-*+]\s+/,"").replace(/^\d+[.)]\s+/,"").replace(/^`([^`]+)`$/,"$1").trim()}function Om(t){return t.split(`
|
|
168
|
+
`).map(e=>e.trim()).filter(Boolean).map(yd).map(e=>re(e,220)).filter(e=>e.length>0).filter(e=>!/^(plan|proposed plan|implementation plan|review summary|full plan)[:]?$/i.test(e)).filter(e=>!/^(should|can|could|would|will)\b.*\?$/i.test(e)).filter(e=>!/^(thinking|checking|considering|analyzing)\b/i.test(e))}function Wm(t){return t.split(`
|
|
169
|
+
`).map(e=>e.trim()).filter(Boolean).map(yd).filter(e=>e.length>0).filter(e=>!/^(plan|proposed plan|implementation plan|review summary|summary|why this was escalated|full plan)[:]?$/i.test(e)).filter(e=>!/^(should|can|could|would|will)\b.*\?$/i.test(e)).filter(e=>!/^(thinking|checking|considering|analyzing)\b/i.test(e))}function Ai(t){let e=Om(t);return e.length===0?`Review summary:
|
|
172
170
|
- Plan details are available in the full session output.`:["Review summary:",...e.slice(0,6).map(n=>`- ${n}`)].join(`
|
|
173
|
-
`)}function
|
|
174
|
-
`).length>
|
|
175
|
-
`).length>
|
|
176
|
-
`)}function
|
|
177
|
-
`),r=[],
|
|
178
|
-
${s}`:s;if(a.length>e){
|
|
171
|
+
`)}function Nm(t){let e=[],n=!1;for(let o of t){let i=o.replace(/\s+/g," ").trim();if(!i)continue;let s=re(i,Dm);s.length<i.length&&(n=!0);let a=`- ${s}`;if(e.length>=$m||[...e,a].join(`
|
|
172
|
+
`).length>gd){n=!0;break}e.push(a)}if(e.length===0)return["- Plan details are available in the full session output."];if(!n)return e;let r=[...e];for(;r.length>0&&[...r,hd].join(`
|
|
173
|
+
`).length>gd;)r.pop();return[...r,hd]}function Ri(t){return Nm(Wm(t)).join(`
|
|
174
|
+
`)}function Lm(t,e){let n=[],r=t.trim();for(;r.length>e;){let o=r.lastIndexOf(" ",e);o<Math.floor(e*.6)&&(o=e),n.push(r.slice(0,o).trimEnd()),r=r.slice(o).trimStart()}return r.length>0&&n.push(r),n}function Bm(t,e){let n=t.split(`
|
|
175
|
+
`),r=[],o="",i=()=>{o.trim().length>0&&(r.push(o.trimEnd()),o="")};for(let s of n){if(s.length>e){i();for(let d of Lm(s,e))r.push(d);continue}let a=o.length>0?`${o}
|
|
176
|
+
${s}`:s;if(a.length>e){i(),o=s;continue}o=a}return i(),r}function kd(t){return re(t.trim(),Em)}function vd(t,e){return e?t?`
|
|
179
177
|
|
|
180
178
|
Choose Approve, Revise, or Reject below.`:`
|
|
181
179
|
|
|
182
180
|
Approval is still pending for this plan version.`:`
|
|
183
181
|
|
|
184
|
-
Continued in next message.`}function
|
|
182
|
+
Continued in next message.`}function Fm(t){let{sessionName:e,actionableVersion:n,fullPlanText:r,hasButtons:o}=t,i=`📋 [${e}] Plan v${n??"?"} ready for approval:`,s=`
|
|
185
183
|
|
|
186
184
|
Full plan (truncated):
|
|
187
|
-
`,a=
|
|
188
|
-
`),h=
|
|
189
|
-
${c}${h}`}),l=d.reduce((c,p)=>Math.max(c,p.length),0);if(l<=
|
|
190
|
-
${r}`:
|
|
185
|
+
`,a=vd(o,!0),d=Math.max(0,bi-i.length-s.length-a.length);return`${i}${s}${re(r,d)}${a}`}function qm(t){let{sessionName:e,actionableVersion:n,fullPlanText:r,hasButtons:o}=t,i=kd(e),s=_m;for(;s>0;){let a=Bm(r,s),d=a.map((c,p)=>{let f=a.length,g=[`📋 [${i}] Plan v${n??"?"} ready for approval (${p+1}/${f}):`,"",p===0?"Full plan:":""].filter(Boolean).join(`
|
|
186
|
+
`),h=vd(o,p===f-1);return`${g}
|
|
187
|
+
${c}${h}`}),l=d.reduce((c,p)=>Math.max(c,p.length),0);if(l<=bi)return d;let u=l-bi;s-=Math.max(u,50)}return[Fm({sessionName:i,actionableVersion:n,fullPlanText:r,hasButtons:o})]}function Ii(t){let{preview:e,artifact:n}=t,r=n?.markdown?.trim();return r&&r.length<=Sd?`Full plan:
|
|
188
|
+
${r}`:Ai(r||e)}function wd(t){let{sessionName:e,actionableVersion:n,preview:r,artifact:o,hasButtons:i}=t,s=o?.markdown?.trim(),a=kd(e);if(s){let l=`📋 [${a}] Plan v${n??"?"} ready for approval:
|
|
191
189
|
|
|
192
190
|
Full plan:
|
|
193
191
|
${s}
|
|
194
192
|
|
|
195
|
-
${
|
|
196
|
-
${s}`}:{displayMode:"chunked-full-plan",userMessages:
|
|
193
|
+
${i?"Choose Approve, Revise, or Reject below.":"Approval is still pending for this plan version."}`;return l.length<=Sd?{displayMode:"single-full-plan",userMessages:[l],reviewSummary:`Full plan:
|
|
194
|
+
${s}`}:{displayMode:"chunked-full-plan",userMessages:qm({sessionName:e,actionableVersion:n,fullPlanText:s,hasButtons:i}),reviewSummary:Ai(s)}}let d=Ai(r);return{displayMode:"summary",userMessages:[`📋 [${a}] Plan v${n??"?"} ready for approval:
|
|
197
195
|
|
|
198
196
|
${d}
|
|
199
197
|
|
|
200
|
-
${
|
|
201
|
-
`).map(a=>a.trimEnd());for(;
|
|
202
|
-
`).trim();if(!(!s||s===r))return s.length>
|
|
198
|
+
${i?"Choose Approve, Revise, or Reject below.":"Approval is still pending for this plan version."}`],reviewSummary:d}}var Pd=700;function Km(t){let e=t?.trim();return e||void 0}function Um(t,e){let n=e?.trim();if(!n)return;if(!t)return n;let r=t.trim(),o=n.split(`
|
|
199
|
+
`).map(a=>a.trimEnd());for(;o.length>0&&!o[o.length-1]?.trim();)o.pop();for(;o.length>0&&o[o.length-1]?.trim()===r;)o.pop();let s=o.filter((a,d,l)=>{let u=a.trim();return!u||u!==r?!0:!l.some((p,f)=>f!==d&&p.trim().length>0&&p.trim()!==r)}).join(`
|
|
200
|
+
`).trim();if(!(!s||s===r))return s.length>Pd?Rn(s,Pd):s}function Vm(t){let e=Km(t.questionText)??"The session is waiting for your reply.",n=Um(e,t.contextPreview);return n?[`❓ [${t.sessionName}] Question waiting for reply:`,"","Question:",e,"","Recent context:",n].join(`
|
|
203
201
|
`):`❓ [${t.sessionName}] Question waiting for reply:
|
|
204
202
|
|
|
205
|
-
${e}`}function
|
|
206
|
-
`)}function
|
|
207
|
-
`)}:b==="ask"?{label:"plan-approval",userMessage:y,userMessages:
|
|
208
|
-
`),buttons:
|
|
209
|
-
`)}}let
|
|
210
|
-
`),buttons:l}}var
|
|
211
|
-
`).map(n=>n.replace(/^[-*•]\s+/,"").trim()).filter(Boolean).slice(0,
|
|
212
|
-
`)}function
|
|
203
|
+
${e}`}function Gm(t,e){return e!=null&&t.approvalPromptRequiredVersion===e&&(t.approvalPromptStatus==="delivered"||t.approvalPromptStatus==="fallback_delivered")}function Zt(t){let{session:e,summary:n}=t,r=e.actionablePlanDecisionVersion??e.planDecisionVersion;return[`📋 [${e.name}] Plan v${r??"?"} needs your decision.`,"","Interactive Approve / Revise / Reject buttons could not be delivered, so reply here instead:",'- Reply "approve" to approve and start implementation','- Reply "reject" to reject and stop the session',"- Any other reply will be sent back as revision feedback","","Why this was escalated:","",n].join(`
|
|
204
|
+
`)}function xi(t){let{session:e,preview:n,questionText:r,questionContextPreview:o,planArtifact:i,originThreadLine:s,planApprovalMode:a,planApprovalButtons:d,questionButtons:l}=t,u=e.pendingPlanApproval,c=e.actionablePlanDecisionVersion??e.planDecisionVersion,p=Gm(e,c),f=a??"delegate",g=u&&f==="ask"&&!p?wd({sessionName:e.name,actionableVersion:c,preview:n,artifact:i,hasButtons:!!d}):void 0,h=u?g?.reviewSummary??Ii({preview:n,artifact:i}):void 0,y=u?g&&g.userMessages.length===1?g.userMessages[0]:void 0:Vm({sessionName:e.name,questionText:r??n,contextPreview:o}),k=u&&g&&g.userMessages.length>1?g.userMessages.map((b,A,N)=>({text:b,buttons:A===N.length-1?d:void 0})):void 0;if(u){let b=f,A="Permission mode: plan → will switch to bypassPermissions on approval";return b==="delegate"?{label:"plan-approval",userMessage:y,userMessages:k,planReviewSummary:h,wakeMessage:["[DELEGATED PLAN APPROVAL] Coding agent session has finished its plan and is requesting approval to implement.",`Name: ${e.name} | ID: ${e.id} | Plan v${c??"?"}`,s,A,"","⚠️ YOU MUST COMPLETE THESE STEPS IN ORDER. Do NOT skip any step.","","━━━ STEP 1 (MANDATORY): Read the full plan ━━━",`Call agent_output(session='${e.id}', full=true) to read the FULL plan output.`,"The preview below is truncated — you MUST read the full output before making any decision.","","Preview (truncated):",n,"","━━━ STEP 2 (MANDATORY): Review privately ━━━","You are the delegated decision-maker. Review the plan yourself before involving the user.","If you approve directly, you own the user-facing explanation of what was approved and why.","Keep it short and user-facing: one sentence is usually enough.","","━━━ STEP 3 (ONLY AFTER steps 1 and 2): Decide ━━━","Choose ONE:","","APPROVE the plan directly if ALL of the following are true:","- You have read the FULL plan (not just the preview)","- The plan scope matches the original task request","- The changes are low-risk (no destructive operations, no credential handling, no production deployments)","- The plan is clear and well-scoped (no ambiguous requirements or open design questions)","- No architectural decisions that the user should weigh in on","- The working directory and codebase are correct","","ESCALATE to the user and WAIT if ANY of the following are true:","- The plan involves destructive operations (deleting files, dropping tables, force-pushing)","- The plan involves credentials, secrets, or production environments","- The plan requires architectural decisions not covered by the original task","- The scope has expanded beyond the original request","- The requirements are ambiguous or the plan makes assumptions the user should confirm","- You are unsure — when in doubt, always escalate","",`If approving: call agent_respond(session='${e.id}', message='Approved. Go ahead.', approve=true, approval_rationale='<brief reason>').`,"That rationale should say why approval was safe: for example scope match, low risk, or no meaningful ambiguity.","After approving directly, send the user a short plain-text follow-up explaining what was approved and why.","The plugin's thumbs-up line is only the minimal approval acknowledgment, not the explanation.",`If escalating: call agent_request_plan_approval(session='${e.id}', summary='...') exactly once so the plugin posts the single canonical Approve / Revise / Reject prompt.`,"That summary must concisely explain why this was escalated, plus changed files/components, risk level and why, scope match/expansion, and any concerns or assumptions.","After the canonical prompt exists, WAIT for the user's button click or explicit response and do NOT send a second plain-text recap.",`To request changes without user escalation: call agent_respond(session='${e.id}', message='<your feedback>') and do NOT set approve=true. The agent will revise the plan.`].join(`
|
|
205
|
+
`)}:b==="ask"?{label:"plan-approval",userMessage:y,userMessages:k,planReviewSummary:h,wakeMessage:["[USER APPROVAL REQUESTED] Coding agent session has finished its plan. The user has been notified via Telegram and must approve directly.",`Name: ${e.name} | ID: ${e.id} | Plan v${c??"?"}`,s,A,"","DO NOT approve this plan yourself. Wait for the user's explicit approval or rejection.","Once the user responds, forward their decision:",` To approve: agent_respond(session='${e.id}', message='Approved. Go ahead.', approve=true)`,` To request changes: agent_respond(session='${e.id}', message='<user feedback>')`,"","Preview (truncated):",n].join(`
|
|
206
|
+
`),buttons:k?void 0:d}:{label:"plan-approval",userMessage:y,planReviewSummary:h,wakeMessage:["[AUTO-APPROVE] Session has a plan ready. Approve it now:",`agent_respond(session='${e.id}', message='Approved. Go ahead.', approve=true)`].join(`
|
|
207
|
+
`)}}let R=e.multiTurn?"Multi-turn session":"Session";return{label:"waiting",userMessage:y,wakeMessage:[`[SYSTEM INSTRUCTION: Follow your auto-respond rules strictly. If this is a permission request or "should I continue?" → auto-respond. For ALL other questions → forward the agent's EXACT question to the user. Do NOT add your own analysis, commentary, or interpretation. Do NOT "nudge" or "poke" the session.]`,"",`${R} is waiting for a genuine user reply.`,`Name: ${e.name} | ID: ${e.id}`,s,"","Last output:",n,"",`Use agent_respond(session='${e.id}', message='...') to send a reply, or agent_output(session='${e.id}', full: true) to see full context before deciding.`].join(`
|
|
208
|
+
`),buttons:l}}var bd=3,Hm=180,jm=4e3,Ad=32;function Rd(){let t=In(),e=Zm(t);if(e)return{async generateWorktreeDecisionSummary(n){if(typeof e.generateWorktreeDecisionSummary=="function")return await e.generateWorktreeDecisionSummary(n);if(typeof e.summarizeWorktreeDecision=="function")return await e.summarizeWorktreeDecision(n);let r=Xm(n);if(typeof e.generateObject=="function")return await e.generateObject({task:"openclaw-code-agent.worktree-decision-summary",prompt:r,input:n});if(typeof e.generateText=="function")return await e.generateText({task:"openclaw-code-agent.worktree-decision-summary",prompt:r});if(typeof e.complete=="function")return await e.complete({prompt:r})}}}function zm(t){let e=[],n=t.changedFiles.slice(0,3).map(o=>`\`${o}\``);if(n.length>0){let o=t.changedFiles.length-n.length;e.push(o>0?`Touches ${n.join(", ")} and ${o} more file${o===1?"":"s"}`:`Touches ${n.join(", ")}`)}let r=[...new Set(t.commitMessages.map(o=>o.message.trim()).filter(Boolean))].slice(0,2);return r.length>0&&e.push(`Recent work: ${r.join("; ")}`),e}async function Id(t){let e=Qm(t),n=zm(t.diffSummary??{changedFiles:e.changedFiles,commitMessages:e.commitSubjects.map(r=>({message:r}))});if(!t.provider)return{source:"fallback",lines:n,evidence:e,error:"LLM summary provider unavailable."};try{let r=await t.provider.generateWorktreeDecisionSummary(e),o=Jm(r);return o.length>0?{source:"llm",lines:o,evidence:e}:{source:"fallback",lines:n,evidence:e,error:"LLM-generated worktree summary failed schema validation."}}catch(r){let o=r instanceof Error?r.message:String(r);return`${o}`,{source:"fallback",lines:n,evidence:e,error:"LLM summary provider failed."}}}function Qm(t){let e=t.diffSummary;return{sessionName:t.sessionName,objective:ef(t.prompt),stats:e?{commits:e.commits,filesChanged:e.filesChanged,insertions:e.insertions,deletions:e.deletions}:void 0,changedFiles:e?.changedFiles??[],commitSubjects:e?.commitMessages.map(n=>xd(n.message)).filter(Boolean).slice(0,8)??[],outputPreview:Td(Cd(t.outputPreview??""),jm)}}function Jm(t){let e=Ym(t),n=Array.isArray(e)?e:e&&typeof e=="object"&&Array.isArray(e.summary)?e.summary:void 0;if(!n||n.length===0||n.length>bd)return[];let r=n.map(o=>typeof o=="string"?xd(o):"").filter(Boolean);return r.length!==n.length?[]:r.some(o=>o.length>Hm)?[]:r.some(tf)?[]:r}function Ym(t){if(typeof t!="string")return t;let e=t.trim();if(e)try{return JSON.parse(e)}catch{return{summary:e.split(`
|
|
209
|
+
`).map(n=>n.replace(/^[-*•]\s+/,"").trim()).filter(Boolean).slice(0,bd)}}}function Zm(t){return[t?.worktreeDecisionSummary,t?.llm,t?.ai,t?.model,t?.models].find(n=>!!(n&&typeof n=="object"&&(typeof n.generateWorktreeDecisionSummary=="function"||typeof n.summarizeWorktreeDecision=="function"||typeof n.generateObject=="function"||typeof n.generateText=="function"||typeof n.complete=="function")))}function Xm(t){return["Summarize the completed OpenClaw Code Agent work for a worktree decision notification.",'Return only JSON with shape {"summary":["..."]}.',"Write 1-3 concise, user-facing bullets that help a human choose Merge, Open PR, Later, or Discard.","Do not mention that you are summarizing. Do not invent changes not supported by the evidence.","","Evidence:",JSON.stringify(t,null,2)].join(`
|
|
210
|
+
`)}function ef(t){let e=t?.replace(/\r\n/g,`
|
|
213
211
|
`).split(`
|
|
214
|
-
`).map(
|
|
212
|
+
`).map(o=>o.trim()).filter(Boolean).join(" ");if(!e)return;let n=e.match(/^[^.!?]+[.!?]/)?.[0]??e,r=Cd(n).replace(/\s+/g," ").trim();return r?Td(r,180):void 0}function xd(t){return t.replace(/^[-*•]\s+/,"").replace(/\s+/g," ").trim()}function Td(t,e){return t.length<=e?t:`${t.slice(0,Math.max(0,e-3)).trimEnd()}...`}function Cd(t){return t.replace(/\b[A-Za-z0-9_-]*(?:api[_-]?key|token|secret|password|passwd|pwd|credential|credentials|authorization|auth)[A-Za-z0-9_-]*\b\s*[:=]\s*["']?[^"'\s,;)]+/gi,"[redacted credential]").replace(/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{16,}\b/g,"[redacted token]").replace(/\bgithub_pat_[A-Za-z0-9_]{20,}\b/g,"[redacted token]").replace(/\bsk-[A-Za-z0-9_-]{20,}\b/g,"[redacted token]").replace(/\bhttps?:\/\/\S+/gi,"[redacted link]").replace(new RegExp(`\\b[A-Za-z0-9_-]{${Ad},}\\b`,"g"),"[redacted token]")}function tf(t){return/\b[A-Za-z0-9_-]*(?:api[_-]?key|token|secret|password|passwd|pwd|credential|credentials|authorization|auth)[A-Za-z0-9_-]*\b\s*[:=]\s*["']?[^"'\s,;)]+/i.test(t)||/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{16,}\b/.test(t)||/\bgithub_pat_[A-Za-z0-9_]{20,}\b/.test(t)||/\bsk-[A-Za-z0-9_-]{20,}\b/.test(t)||/\bhttps?:\/\/\S+/i.test(t)||new RegExp(`\\b[A-Za-z0-9_-]{${Ad},}\\b`).test(t)}me();var Mr=class{constructor(e){this.deps=e;this.actions=new Tr({shouldRunWorktreeStrategy:e.shouldRunWorktreeStrategy,isAlreadyMerged:e.isAlreadyMerged,resolveWorktreeRepoDir:e.resolveWorktreeRepoDir,getWorktreeCompletionState:e.getWorktreeCompletionState})}deps;actions;buildConflictResolverPrompt(e){return["Resolve the git rebase conflict for the auto-merge worktree and finish the rebase cleanly.","",`Original session: ${e.session.name} [${e.session.id}]`,`Repository root: ${e.repoDir}`,`Conflicted worktree: ${e.worktreePath}`,`Branch: ${e.branchName}`,`Base branch: ${e.baseBranch}`,"","Requirements:","- Work only inside the conflicted worktree.","- Inspect the current rebase state and resolve only the necessary conflict hunks.","- Make only minimal follow-up edits needed to keep the rebased branch correct.","- Continue the rebase until it completes successfully.","- Run relevant local verification before you finish.","- Do not broaden scope or start unrelated refactors.",`- Stop only when the branch is cleanly rebased onto ${e.baseBranch}.`,e.mergeError?"":void 0,e.mergeError?"Rebase failure details:":void 0,e.mergeError].filter(n=>typeof n=="string").join(`
|
|
215
213
|
`)}notifyAutoMergeConflictEscalation(e,n,r){this.deps.dispatchSessionNotification(e,{label:"worktree-merge-conflict-escalated",idempotencyKey:`worktree-merge-conflict-escalated:${e.id}:${n}`,userMessage:[`⚠️ [${e.name}] Auto-merge could not finish after one conflict-resolution attempt.`,`Branch \`${n}\` was preserved for manual follow-up.`,"",r].join(`
|
|
216
|
-
`),buttons:[[this.deps.makeOpenPrButton(e.id)]]})}updatePersistedSessionFor(e,n){for(let r of
|
|
217
|
-
`)}),{notificationSent:!0,worktreeRemoved:!1}}handleAutoMergeSuccess(e,n,r,i,
|
|
214
|
+
`),buttons:[[this.deps.makeOpenPrButton(e.id)]]})}updatePersistedSessionFor(e,n){for(let r of ae(e))this.deps.updatePersistedSession(r,n)}markPendingDecision(e,n={}){this.updatePersistedSessionFor(e,lr(e,n))}markAutoMergeConflictResolving(e,n,r){this.updatePersistedSessionFor(e,ba(e,n,r,{notes:[`resolver_session:${n}`]}))}markMerged(e){this.updatePersistedSessionFor(e,ur(e,{clearResolverSessionId:!0}))}markReleased(e,n=[]){let r=new Date().toISOString();this.updatePersistedSessionFor(e,{lifecycle:"terminal",worktreeState:"released",pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0,worktreeLifecycle:{state:"released",updatedAt:r,resolvedAt:r,resolutionSource:"lifecycle_resolver",baseBranch:e.worktreeBaseBranch,targetRepo:e.worktreePrTargetRepo,pushRemote:e.worktreePushRemote,notes:n}})}async handleWorktreeStrategy(e){let n=await this.actions.plan(e);if(n.kind==="skip")return n.result;if(n.kind==="notify")return this.deps.dispatchSessionNotification(e,{label:n.label,idempotencyKey:["worktree-action",e.id,n.label,e.completedAt??"unknown",e.worktreeBranch??"unknown",e.worktreePath??"unknown"].join(":"),userMessage:n.message}),{notificationSent:!0,worktreeRemoved:!1};if(n.kind==="dirty-uncommitted")return this.handleDirtyUncommittedCompletion(e,n.worktreePath,n.branchName,n.baseBranch);if(n.kind==="no-change")return this.handleNoChange(e,n.repoDir,n.worktreePath,n.nativeBackendWorktree);if(n.kind==="merged"){let r=n.nativeBackendWorktree?!0:de(n.repoDir,n.worktreePath);return ge(n.repoDir,n.branchName),this.markMerged(e),{notificationSent:!1,worktreeRemoved:r}}return n.strategy==="ask"?await this.handleAskStrategy(e,n.branchName,n.baseBranch,n.diffSummary):n.strategy==="delegate"?this.handleDelegateStrategy(e,n.branchName,n.baseBranch,n.diffSummary):n.strategy==="auto-merge"?(await this.handleAutoMergeStrategy(e,n.repoDir,n.worktreePath,n.branchName,n.baseBranch,n.diffSummary,n.sessionRef),{notificationSent:!0,worktreeRemoved:!1}):n.strategy==="auto-pr"?this.handleAutoPrStrategy(e,n.repoDir,n.worktreePath,n.branchName,n.baseBranch):{notificationSent:!1,worktreeRemoved:!1}}async handleNoChange(e,n,r,o=ne(e)){let i=o?!0:de(n,r);return i?(e.worktreePath=void 0,this.updatePersistedSessionFor(e,{worktreePath:void 0,worktreeDisposition:"no-change-cleaned",worktreeState:"none",worktreeLifecycle:{state:"no_change",updatedAt:new Date().toISOString(),resolvedAt:new Date().toISOString(),resolutionSource:"strategy_no_change",baseBranch:e.worktreeBaseBranch,targetRepo:e.worktreePrTargetRepo,pushRemote:e.worktreePushRemote}}),this.deps.dispatchSessionNotification(e,this.deps.worktreeMessages.buildNoChangeNotification({session:e,nativeBackendWorktree:o,cleanupSucceeded:!0,worktreePath:r,preview:this.deps.getOutputPreview(e),originThreadLine:this.deps.originThreadLine(e)}))):this.deps.dispatchSessionNotification(e,this.deps.worktreeMessages.buildNoChangeNotification({session:e,nativeBackendWorktree:o,cleanupSucceeded:!1,worktreePath:r,preview:this.deps.getOutputPreview(e),originThreadLine:this.deps.originThreadLine(e)})),{notificationSent:!0,worktreeRemoved:i}}async handleAskStrategy(e,n,r,o){let i=await Id({sessionName:e.name,prompt:e.prompt,diffSummary:o,outputPreview:this.deps.getOutputPreview(e,4e3),provider:this.deps.worktreeSummaryProvider});return this.deps.dispatchSessionNotification(e,this.deps.worktreeMessages.buildAskNotification({session:e,branchName:n,baseBranch:r,diffSummary:o,summaryLines:i.lines,buttons:this.deps.getWorktreeDecisionButtons(e.id)})),this.markPendingDecision(e),{notificationSent:!0,worktreeRemoved:!1}}handleDelegateStrategy(e,n,r,o){return this.deps.dispatchSessionNotification(e,this.deps.worktreeMessages.buildDelegateNotification({session:e,branchName:n,baseBranch:r,diffSummary:o,originThreadLine:this.deps.originThreadLine(e)})),this.markPendingDecision(e),{notificationSent:!0,worktreeRemoved:!1}}handleDirtyUncommittedCompletion(e,n,r,o){this.markPendingDecision(e,{notes:["dirty_uncommitted_completion"]});let i=Ve(n),s=i.slice(0,20).map(d=>`- ${d}`),a=i.length>20?[`- ...and ${i.length-20} more`]:[];return this.deps.dispatchSessionNotification(e,{label:"worktree-dirty-uncommitted",idempotencyKey:`worktree-dirty-uncommitted:${e.id}:${r}:${o}`,userMessage:[`⚠️ [${e.name}] Session completed with uncommitted worktree changes.`,"",`Branch \`${r}\` has no commits ahead of \`${o}\`, so merge/PR follow-through is blocked until the worktree is fixed.`,`Worktree: ${n}`,"",...s.length>0?["Dirty entries:",...s,...a,""]:[],"Resume the session or inspect the worktree, then commit real task changes or clean temporary files. Discard only if these local changes should be permanently removed."].join(`
|
|
215
|
+
`)}),{notificationSent:!0,worktreeRemoved:!1}}handleAutoMergeSuccess(e,n,r,o,i,s){ge(n,r),this.markMerged(e);let a=Ge({kind:"merge",branch:r,base:o,filesChanged:i.filesChanged,insertions:i.insertions,deletions:i.deletions}),d=a;s.stashPopConflict?d+=`
|
|
218
216
|
⚠️ Pre-merge stash pop conflicted — run \`git stash show ${s.stashRef??"stash@{0}"}\` in ${n} to review stashed changes.`:s.stashed&&(d+=`
|
|
219
|
-
(Pre-existing changes on ${
|
|
220
|
-
`),buttons:[[this.deps.makeOpenPrButton(e.id)]]})}async handleAutoMergeStrategy(e,n,r,i,o,s,a=D(e)??e.harnessSessionId){this.deps.isAlreadyMerged(a)||e.autoMergeResolverSessionId||await this.deps.enqueueMerge(n,async()=>{if(this.deps.isAlreadyMerged(a))return;let d=this.deps.mergeBranch(n,i,o,"merge",r);if(d.success){this.handleAutoMergeSuccess(e,n,i,o,s,d);return}if(d.rebaseConflict){await this.handleInitialAutoMergeConflict(e,n,r,i,o,d.error);return}let l=d.dirtyError?`❌ [${e.name}] Merge blocked: ${d.error}`:`❌ [${e.name}] Merge failed: ${d.error??"unknown error"}`;if(e.worktreeState==="merge_conflict_resolving"||e.worktreeLifecycle?.state==="merge_conflict_resolving"){this.handleAutoMergeRetryFailure(e,i,r,l);return}this.deps.dispatchSessionNotification(e,{label:"worktree-merge-error",idempotencyKey:`worktree-merge-error:${e.id}:${i}`,userMessage:l})},()=>{this.deps.dispatchSessionNotification(e,{label:"worktree-merge-queued",idempotencyKey:`worktree-merge-queued:${e.id}:${i}`,userMessage:`🕐 [${e.name}] Merge queued — another merge for this repo is in progress. Will notify when complete.`})})}async handleAutoPrStrategy(e,n){return this.updatePersistedSessionFor(e,{lifecycle:"terminal",worktreeState:"pr_in_progress"}),(await this.deps.runAutoPr(e,n)).success||(this.markPendingDecision(e),this.deps.dispatchSessionNotification(e,{label:"worktree-auto-pr-failed",idempotencyKey:`worktree-auto-pr-failed:${e.id}:${n}`,userMessage:`⚠️ [${e.name}] Auto-PR did not complete. The worktree is preserved for an explicit merge or PR decision.`,buttons:this.deps.getWorktreeDecisionButtons(e.id)})),{notificationSent:!0,worktreeRemoved:!1}}};import{existsSync as Rf,writeFileSync as Af}from"fs";he();import{randomUUID as Vm}from"crypto";function Hm(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"}var br=class{constructor(e,n){this.onChange=e;this.retentionMs=n}onChange;retentionMs;tokens=new Map;afterChange;replaceAll(e){this.tokens.clear();for(let n of e)this.tokens.set(n.id,n)}clear(){this.tokens.clear(),this.notifyChanged()}listForPersistence(){return[...this.tokens.values()]}createActionToken(e,n,r={}){let i={id:Vm(),sessionId:e,kind:n,createdAt:Date.now(),...r};return this.tokens.set(i.id,i),this.notifyChanged(),i}getActionToken(e){let n=this.tokens.get(e);if(n){if(n.expiresAt!=null&&n.expiresAt<=Date.now()){this.tokens.delete(e),this.notifyChanged();return}return n}}consumeActionToken(e){let n=this.getActionToken(e);if(!(!n||n.consumedAt!=null))return n.consumedAt=Date.now(),this.notifyChanged(),n}deleteActionTokensForSession(e){let n=!1;for(let[r,i]of this.tokens)i.sessionId===e&&(this.tokens.delete(r),n=!0);n&&this.notifyChanged()}deletePlanDecisionTokensForSession(e,n){let r=!1;for(let[i,o]of this.tokens)o.sessionId!==e||!Hm(o.kind)||n!=null&&o.planDecisionVersion===n||(this.tokens.delete(i),r=!0);r&&this.notifyChanged()}purgeExpiredActionTokens(e=Date.now()){let n=!1;for(let[r,i]of this.tokens){let o=i.expiresAt!=null&&i.expiresAt<=e,s=i.consumedAt!=null&&e-i.consumedAt>this.retentionMs;(o||s)&&(this.tokens.delete(r),n=!0)}n&&this.notifyChanged()}nextExpiryAt(){let e;for(let n of this.tokens.values()){let r=[n.expiresAt,n.consumedAt!=null?n.consumedAt+this.retentionMs:void 0].filter(i=>i!=null&&Number.isFinite(i));for(let i of r)(e==null||i<e)&&(e=i)}return e}setAfterChangeListener(e){this.afterChange=e}notifyChanged(){this.onChange(),this.afterChange?.()}};V();V();var Rr=class{constructor(e){this.indexes=e}indexes;hasRecordedSession(e){return this.indexes.idIndex.has(e)}getLatestPersistedByName(e){let n,r=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY,o=Number.NEGATIVE_INFINITY,s=0;for(let a of this.indexes.persisted.values()){if(a.name!==e){s++;continue}let d=a.createdAt??Number.NEGATIVE_INFINITY,l=a.completedAt??Number.NEGATIVE_INFINITY;(d>r||d===r&&l>i||d===r&&l===i&&s>o)&&(n=a,r=d,i=l,o=s),s++}return n}resolveBackendConversationId(e,n){if(n)return n;let r=this.indexes.idIndex.get(e);if(r){let s=this.indexes.persisted.get(r);return(s?x(s):void 0)??r}let i=this.getLatestPersistedByName(e);if(i)return x(i)??i.harnessSessionId;let o=this.indexes.backendIdIndex.get(e);if(o){let s=this.indexes.persisted.get(o);return(s?x(s):void 0)??o}if(this.indexes.persisted.has(e)){let s=this.indexes.persisted.get(e);return s?x(s)??e:e}if(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e))return e}resolveHarnessSessionId(e,n){return this.resolveBackendConversationId(e,n)}getPersistedSession(e){let n=this.indexes.idIndex.get(e);if(n)return this.indexes.persisted.get(n);let r=this.getLatestPersistedByName(e);if(r)return r;let i=this.indexes.backendIdIndex.get(e);return i?this.indexes.persisted.get(i):this.indexes.persisted.get(e)}listPersistedSessions(){return[...this.indexes.persisted.values()].sort((e,n)=>(n.completedAt??0)-(e.completedAt??0))}};import{existsSync as kf,mkdirSync as vf,readFileSync as wf,readdirSync as go,renameSync as Rd,statSync as Ad,unlinkSync as xd,writeFileSync as Id}from"fs";import{tmpdir as ho}from"os";import{dirname as Pf,join as Tr}from"path";import{homedir as Gm}from"node:os";import{join as jm}from"node:path";function Sd(t){let e=t.OPENCLAW_HOME?.trim();if(e)return e;let n=t.HOME?.trim()||Gm();return jm(n,".openclaw")}he();var Ar=6,zm=new Set(["running","completed","failed","killed"]);function Ve(t){return!!t&&typeof t=="object"}function gt(t,e=""){return typeof t=="string"&&t.trim().length>0?t:e}function v(t){return typeof t=="string"&&t.trim().length>0?t:void 0}function se(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}function Jm(t){return typeof t=="string"&&ea.has(t)?t:void 0}function kd(t){return t==="default"||t==="plan"||t==="bypassPermissions"?t:void 0}function Qm(t){return t==="never"||t==="on-request"?"never":void 0}function Ym(t){return t==="approve"||t==="ask"||t==="delegate"?t:void 0}function Zm(t){if(t==="plan-mode"||t==="codex-first-turn-plan"||t==="soft-plan")return"plan-mode"}function vd(t){return typeof t=="string"&&Jn.has(t)?t:void 0}function Xm(t){return t==="user"||t==="idle-timeout"||t==="startup-timeout"||t==="shutdown"||t==="done"||t==="unknown"?t:void 0}function ef(t){return t==="starting"||t==="active"||t==="awaiting_plan_decision"||t==="awaiting_user_input"||t==="awaiting_worktree_decision"||t==="suspended"||t==="terminal"?t:void 0}function tf(t){return t==="not_required"||t==="pending"||t==="approved"||t==="changes_requested"||t==="rejected"?t:void 0}function nf(t){return t==="none"||t==="provisioned"||t==="pending_decision"||t==="merge_conflict_resolving"||t==="merge_in_progress"||t==="pr_in_progress"||t==="merged"||t==="released"||t==="pr_open"||t==="dismissed"||t==="cleanup_failed"?t:void 0}function rf(t){return t==="none"||t==="provisioned"||t==="pending_decision"||t==="merge_conflict_resolving"||t==="pr_open"||t==="merged"||t==="released"||t==="dismissed"||t==="no_change"||t==="cleanup_failed"?t:void 0}function of(t){return t==="live"||t==="stopped"?t:void 0}function sf(t){return t==="not_sent"||t==="sending"||t==="delivered"||t==="fallback_delivered"||t==="failed"?t:void 0}function af(t){return t==="direct-telegram"?"direct-message":t==="none"||t==="direct-message"||t==="wake-only"?t:void 0}function df(t){return t==="none"||t==="canonical_buttons"||t==="explicit_fallback_text"?t:void 0}function lf(t){return t==="idle"||t==="notifying"||t==="wake_pending"||t==="failed"?t:void 0}function uf(t){return t==="in_flight"||t==="delivered"?t:void 0}function cf(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!Ve(n))return;let r=v(n.key),i=uf(n.status),o=v(n.recordedAt);if(!(!r||!i||!o||!Number.isFinite(Date.parse(o))))return{key:r,status:i,recordedAt:o,label:v(n.label)}}).filter(n=>!!n);return e.length>0?e.slice(-64):void 0}function pf(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!Ve(n))return;let r=v(n.key),i=v(n.recordedAt);if(!(!r||!i||!Number.isFinite(Date.parse(i))))return{key:r,recordedAt:i,label:v(n.label),skipReason:v(n.skipReason)}}).filter(n=>!!n);return e.length>0?e.slice(-1024):void 0}function mf(t){return t==="awaiting_plan_output"||t==="awaiting_approval"||t==="approved_then_implemented"||t==="implemented_without_required_approval"||t==="not_plan_gated"?t:void 0}function ff(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"||t==="plan-offer-start"||t==="plan-offer-dismiss"||t==="worktree-merge"||t==="worktree-create-pr"||t==="worktree-update-pr"||t==="worktree-view-pr"||t==="worktree-decide-later"||t==="worktree-dismiss"||t==="session-resume"||t==="session-restart"||t==="view-output"||t==="question-answer"?t:void 0}function wd(t){if(!Ve(t))return;let e=v(t.provider),n=v(t.accountId),r=v(t.target),i=v(t.threadId),o=v(t.sessionKey);if(!(!e||!r))return{provider:e,accountId:n,target:r,threadId:i,sessionKey:o}}function gf(t,e,n){if(Ve(t)){let r=v(t.kind),i=v(t.conversationId);if(i&&(r==="claude-code"||r==="codex-app-server"||r==="opencode-server"))return{kind:r,conversationId:i,runId:v(t.runId),worktreeId:v(t.worktreeId),worktreePath:v(t.worktreePath)}}if(e==="claude-code")return{kind:"claude-code",conversationId:n}}function hf(t){if(!Ve(t))return;let e=rf(t.state),n=v(t.updatedAt);if(!e||!n)return;let r=v(t.resolutionSource);return{state:e,updatedAt:n,resolvedAt:v(t.resolvedAt),resolutionSource:r==="agent_merge"||r==="agent_pr"||r==="strategy_no_change"||r==="lifecycle_resolver"||r==="dismiss"||r==="maintenance"?r:void 0,baseBranch:v(t.baseBranch),targetRepo:v(t.targetRepo),pushRemote:v(t.pushRemote),notes:Array.isArray(t.notes)?t.notes.filter(i=>typeof i=="string"&&i.length>0):void 0}}function yf(t){let e=new Date(0).toISOString(),n=v(t.worktreeMergedAt)??v(t.worktreeDismissedAt)??v(t.pendingWorktreeDecisionSince)??e;if(t.worktreeMerged===!0)return{state:"merged",updatedAt:n,resolvedAt:v(t.worktreeMergedAt)??n,resolutionSource:"agent_merge",baseBranch:v(t.worktreeBaseBranch),targetRepo:v(t.worktreePrTargetRepo),pushRemote:v(t.worktreePushRemote)};if(t.worktreeDisposition==="dismissed")return{state:"dismissed",updatedAt:n,resolvedAt:v(t.worktreeDismissedAt)??n,resolutionSource:"dismiss",baseBranch:v(t.worktreeBaseBranch),targetRepo:v(t.worktreePrTargetRepo),pushRemote:v(t.worktreePushRemote)};if(t.worktreeDisposition==="no-change-cleaned")return{state:"no_change",updatedAt:n,resolvedAt:n,resolutionSource:"strategy_no_change",baseBranch:v(t.worktreeBaseBranch),targetRepo:v(t.worktreePrTargetRepo),pushRemote:v(t.worktreePushRemote)};if(t.worktreeDisposition==="pr-opened"||t.worktreeState==="pr_open")return{state:"pr_open",updatedAt:n,baseBranch:v(t.worktreeBaseBranch),targetRepo:v(t.worktreePrTargetRepo),pushRemote:v(t.worktreePushRemote)};if(t.pendingWorktreeDecisionSince||t.worktreeState==="pending_decision")return{state:"pending_decision",updatedAt:n,baseBranch:v(t.worktreeBaseBranch),targetRepo:v(t.worktreePrTargetRepo),pushRemote:v(t.worktreePushRemote)};if(t.worktreeState==="merge_conflict_resolving")return{state:"merge_conflict_resolving",updatedAt:n,baseBranch:v(t.worktreeBaseBranch),targetRepo:v(t.worktreePrTargetRepo),pushRemote:v(t.worktreePushRemote)};if(v(t.worktreePath)||v(t.worktreeBranch))return{state:"provisioned",updatedAt:n,baseBranch:v(t.worktreeBaseBranch),targetRepo:v(t.worktreePrTargetRepo),pushRemote:v(t.worktreePushRemote)}}function Sf(t){if(typeof t=="string"&&zm.has(t))return t==="running"?"killed":t}function Pd(t){if(!Ve(t))return;let e=gt(t.harnessSessionId);if(!e)return;let n=Sf(t.status);if(!n)return;let r=t.status==="running",i=v(t.worktreePath),o=v(t.worktreeBranch),s=v(t.originChannel),a=typeof t.originThreadId=="string"||typeof t.originThreadId=="number"?t.originThreadId:void 0,d=v(t.originSessionKey),l=wd(t.route);if(!l)return;let u=Ee({route:l,originChannel:s,originThreadId:a,originSessionKey:d});if(!u||i&&!o)return;let c=v(t.harness),p=gf(t.backendRef,c,e),f=hf(t.worktreeLifecycle)??yf(t),g=v(t.completionWakeSucceededAt),h=v(t.completionWakeSkippedAt),y=t.completionWakeSummaryRequired===!0&&!h?!0:void 0;return{sessionId:v(t.sessionId),harnessSessionId:e,backendRef:p,name:gt(t.name,e),prompt:gt(t.prompt),workdir:gt(t.workdir,"(unknown)"),model:v(t.model),reasoningEffort:Jm(t.reasoningEffort),fastMode:t.fastMode===!0?!0:void 0,createdAt:se(t.createdAt),completedAt:se(t.completedAt),status:n,lifecycle:r?"suspended":ef(t.lifecycle),approvalState:tf(t.approvalState),worktreeState:nf(t.worktreeState),runtimeState:r?"stopped":of(t.runtimeState),deliveryState:lf(t.deliveryState),notificationDedupe:cf(t.notificationDedupe),completionSummaryDedupe:pf(t.completionSummaryDedupe),completionWakeIssuedAt:v(t.completionWakeIssuedAt),completionWakeSucceededAt:g,completionWakeFailedAt:v(t.completionWakeFailedAt),completionWakeSkippedAt:h,completionWakeSkipReason:v(t.completionWakeSkipReason),completionWakeSummaryRequired:y,killReason:Xm(t.killReason),costUsd:typeof t.costUsd=="number"&&Number.isFinite(t.costUsd)?t.costUsd:0,originAgentId:v(t.originAgentId),originChannel:s,originThreadId:a,originSessionKey:d,route:u,outputPath:v(t.outputPath),harness:c,goalTaskId:v(t.goalTaskId),requestedPermissionMode:kd(t.requestedPermissionMode),currentPermissionMode:kd(t.currentPermissionMode),approvalExecutionState:mf(t.approvalExecutionState),approvalRationale:v(t.approvalRationale),planModeApproved:t.planModeApproved===!0,pendingPlanApproval:t.pendingPlanApproval===!0,planApprovalContext:Zm(t.planApprovalContext),planDecisionVersion:se(t.planDecisionVersion),actionablePlanDecisionVersion:se(t.actionablePlanDecisionVersion),canonicalPlanPromptVersion:se(t.canonicalPlanPromptVersion),approvalPromptRequiredVersion:se(t.approvalPromptRequiredVersion),approvalPromptVersion:se(t.approvalPromptVersion),approvalPromptStatus:sf(t.approvalPromptStatus),approvalPromptTransport:af(t.approvalPromptTransport),approvalPromptMessageKind:df(t.approvalPromptMessageKind),approvalPromptLastAttemptAt:v(t.approvalPromptLastAttemptAt),approvalPromptDeliveredAt:v(t.approvalPromptDeliveredAt),approvalPromptFailedAt:v(t.approvalPromptFailedAt),planApproval:Ym(t.planApproval),codexApprovalPolicy:Qm(t.codexApprovalPolicy),worktreePath:i,worktreeBranch:o,worktreeStrategy:vd(t.worktreeStrategy),worktreeMerged:typeof t.worktreeMerged=="boolean"?t.worktreeMerged:void 0,worktreeMergedAt:v(t.worktreeMergedAt),worktreePrUrl:v(t.worktreePrUrl),worktreePrNumber:se(t.worktreePrNumber),pendingWorktreeDecisionSince:v(t.pendingWorktreeDecisionSince),lastWorktreeReminderAt:v(t.lastWorktreeReminderAt),worktreeBaseBranch:v(t.worktreeBaseBranch),worktreePrTargetRepo:v(t.worktreePrTargetRepo),autoMergeParentSessionId:v(t.autoMergeParentSessionId),autoMergeConflictResolutionAttemptCount:se(t.autoMergeConflictResolutionAttemptCount),autoMergeResolverSessionId:v(t.autoMergeResolverSessionId),worktreePushRemote:v(t.worktreePushRemote),worktreeDecisionSnoozedUntil:v(t.worktreeDecisionSnoozedUntil),worktreeDisposition:t.worktreeDisposition==="active"||t.worktreeDisposition==="pr-opened"||t.worktreeDisposition==="merged"||t.worktreeDisposition==="dismissed"||t.worktreeDisposition==="no-change-cleaned"?t.worktreeDisposition:void 0,worktreeDismissedAt:v(t.worktreeDismissedAt),worktreeLifecycle:f,resumable:r?!0:t.resumable===!0}}function bd(t){if(!Ve(t))return;let e=ff(t.kind),n=gt(t.id),r=gt(t.sessionId),i=se(t.createdAt);if(!(!n||!r||!e||i==null))return{id:n,sessionId:r,kind:e,createdAt:i,planDecisionVersion:se(t.planDecisionVersion),expiresAt:se(t.expiresAt),consumedAt:se(t.consumedAt),optionIndex:se(t.optionIndex),label:v(t.label),targetUrl:v(t.targetUrl),route:wd(t.route),launchName:v(t.launchName),launchPrompt:v(t.launchPrompt),launchWorkdir:v(t.launchWorkdir),launchWorktreeStrategy:vd(t.launchWorktreeStrategy)}}function xr(t){if(!t.backendRef?.kind||!t.backendRef.conversationId)throw new Error(`Persisted session ${t.harnessSessionId} is missing required backend ref metadata.`);if(!t.route?.provider||!t.route.target)throw new Error(`Persisted session ${t.harnessSessionId} is missing required route metadata.`);if(t.worktreePath&&!t.worktreeBranch)throw new Error(`Persisted session ${t.harnessSessionId} is missing required worktreeBranch metadata.`)}function fo(t){return!!t&&typeof t=="object"}function yo(t){return t instanceof Error?t.message:String(t)}function Td(t){let e=t.OPENCLAW_CODE_AGENT_SESSIONS_PATH?.trim();return e||Tr(Sd(t),"code-agent-sessions.json")}function Cd(t,e,n){try{vf(Pf(t),{recursive:!0});let r=t+".tmp";Id(r,JSON.stringify({schemaVersion:Ar,sessions:e,actionTokens:n},null,2),"utf-8"),Rd(r,t)}catch(r){`${yo(r)}`}}function Ir(t,e){try{if(!kf(t))return;let n=`${t}.legacy-${Date.now()}.json`;Rd(t,n),`${e}${n}`}catch(n){`${yo(n)}`}}function bf(t,e){try{if(e.length===0)return;let n=`${t}.codex-sdk-legacy-${Date.now()}.json`;Id(n,JSON.stringify(e,null,2),"utf-8"),`${e.length}${n}`}catch(n){`${yo(n)}`}}function Md(t,e){try{let n=ho(),r=go(n).filter(i=>i.startsWith("openclaw-agent-")&&i.endsWith(".txt"));for(let i of r)try{let o=Tr(n,i),s=Ad(o).mtimeMs;t-s>e&&xd(o)}catch{}}catch{}}function _d(t,e){try{let n=ho(),r=go(n).filter(o=>o.startsWith("openclaw-agent-")&&o.endsWith(".txt")),i;for(let o of r)try{let s=Tr(n,o),a=Ad(s).mtimeMs+e;if(a<=t)return t;i=i==null?a:Math.min(i,a)}catch{}return i}catch{return}}function $d(t){try{let e=new Set(t),n=ho(),r=go(n).filter(i=>i.startsWith("openclaw-agent-")&&i.endsWith(".txt"));for(let i of r){let o=Tr(n,i);if(!e.has(o))try{xd(o)}catch{}}}catch{}}function Ed(t){let{indexPath:e,clearAll:n,indexPersistedEntry:r,setActionToken:i,purgeExpiredActionTokens:o,saveIndex:s}=t;try{let a=wf(e,"utf-8"),d=JSON.parse(a);if(Array.isArray(d)){Ir(e,"legacy array store"),s();return}if(!fo(d)||d.schemaVersion!==Ar&&d.schemaVersion!==4){Ir(e,`schema mismatch (expected v${Ar})`),s();return}let l=Array.isArray(d.sessions)?d.sessions:[],u=[];for(let p of l){if(fo(p)&&p.harness==="codex"){let g=fo(p.backendRef)?p.backendRef:void 0;if((typeof g?.kind=="string"?g.kind:void 0)!=="codex-app-server"){u.push(p);continue}}let f=Pd(p);if(!f){n(),Ir(e,"invalid v4 session entry"),s();return}r(f)}u.length>0&&(bf(e,u),s());let c=Array.isArray(d.actionTokens)?d.actionTokens:[];for(let p of c){let f=bd(p);if(!f){n(),Ir(e,"invalid v4 action token"),s();return}i(f)}o()}catch{}}var xf=new Set(["completed","failed","killed"]),So=1440*60*1e3;function If(t){return t instanceof Error?t.message:String(t)}var Cr=class{persisted=new Map;idIndex=new Map;nameIndex=new Map;backendIdIndex=new Map;actionTokens;actionTokenStore;indexPath;queries;constructor(e={}){let n=e.env??process.env;this.indexPath=e.indexPath??Td(n),this.actionTokenStore=new br(()=>this.saveIndex(),So),this.actionTokens=this.actionTokenStore.tokens,this.queries=new Rr({persisted:this.persisted,idIndex:this.idIndex,nameIndex:this.nameIndex,backendIdIndex:this.backendIdIndex}),n.OPENCLAW_DEBUG_SESSION_STORE==="1"&&`${this.indexPath}`,this.loadIndex()}loadIndex(){Ed({indexPath:this.indexPath,clearAll:()=>{this.persisted.clear(),this.idIndex.clear(),this.nameIndex.clear(),this.backendIdIndex.clear(),this.actionTokenStore.clear()},indexPersistedEntry:e=>this.indexPersistedEntry(e),setActionToken:e=>{this.actionTokens.set(e.id,e)},purgeExpiredActionTokens:()=>this.actionTokenStore.purgeExpiredActionTokens(),saveIndex:()=>this.saveIndex()})}saveIndex(){Cd(this.indexPath,[...this.persisted.values()],this.actionTokenStore.listForPersistence())}assertPersistedEntry(e){xr(e)}getEntryStorageKey(e){return e.harnessSessionId}buildPersistedBackendRef(e){let n=Ri(e),r=n==="codex"?"codex-app-server":n==="opencode"?"opencode-server":"claude-code";return e.backendRef??{kind:e.backendKind??r,conversationId:e.harnessSessionId}}indexPersistedEntry(e){let n=this.getEntryStorageKey(e);this.persisted.set(n,e),e.sessionId&&this.idIndex.set(e.sessionId,n),e.name&&this.nameIndex.set(e.name,n);let r=x(e);r&&this.backendIdIndex.set(r,n)}removePersistedIndexes(e){let n=this.getEntryStorageKey(e);this.persisted.delete(n);for(let[r,i]of this.idIndex)i===n&&this.idIndex.delete(r);for(let[r,i]of this.nameIndex)i===n&&this.nameIndex.delete(r);for(let[r,i]of this.backendIdIndex)i===n&&this.backendIdIndex.delete(r)}markRunning(e){if(!e.harnessSessionId)return;let n=typeof e.controlStateSnapshot=="function"?e.controlStateSnapshot():{planModeApproved:!1},r=Ee({route:e.route,originChannel:e.originChannel,originThreadId:e.originThreadId,originSessionKey:e.originSessionKey});if(!r)return;let i={sessionId:e.id,harnessSessionId:e.harnessSessionId,backendRef:this.buildPersistedBackendRef(e),name:e.name,prompt:e.prompt,workdir:e.originalWorkdir??e.workdir,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,createdAt:e.startedAt,status:"running",lifecycle:e.lifecycle,approvalState:e.approvalState,worktreeState:e.worktreeState,runtimeState:e.runtimeState,deliveryState:e.deliveryState,notificationDedupe:this.getExistingNotificationDedupe(e),costUsd:0,originAgentId:e.originAgentId,originChannel:e.originChannel,originThreadId:e.originThreadId,originSessionKey:e.originSessionKey,route:r,harness:e.harnessName,requestedPermissionMode:e.requestedPermissionMode,currentPermissionMode:e.currentPermissionMode,approvalExecutionState:e.approvalExecutionState,approvalRationale:e.approvalRationale,planModeApproved:n.planModeApproved,pendingPlanApproval:e.pendingPlanApproval,planApprovalContext:e.planApprovalContext,planDecisionVersion:e.planDecisionVersion,actionablePlanDecisionVersion:e.actionablePlanDecisionVersion,canonicalPlanPromptVersion:e.canonicalPlanPromptVersion,approvalPromptRequiredVersion:e.approvalPromptRequiredVersion,approvalPromptVersion:e.approvalPromptVersion,approvalPromptStatus:e.approvalPromptStatus,approvalPromptTransport:e.approvalPromptTransport,approvalPromptMessageKind:e.approvalPromptMessageKind,approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:e.approvalPromptDeliveredAt,approvalPromptFailedAt:e.approvalPromptFailedAt,planApproval:e.planApproval,codexApprovalPolicy:e.codexApprovalPolicy,worktreePath:e.worktreePath,worktreeBranch:e.worktreeBranch,worktreeStrategy:e.worktreeStrategy,worktreeBaseBranch:e.worktreeBaseBranch,worktreePrTargetRepo:e.worktreePrTargetRepo,autoMergeParentSessionId:e.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:e.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:e.autoMergeResolverSessionId,worktreeLifecycle:e.worktreeLifecycle,resumable:e.isExplicitlyResumable};xr(i),this.indexPersistedEntry(i),this.saveIndex()}hasRecordedSession(e){return this.queries.hasRecordedSession(e)}persistTerminal(e){if(!e.harnessSessionId)return;let n=typeof e.controlStateSnapshot=="function"?e.controlStateSnapshot():{planModeApproved:!1},r=Ee({route:e.route,originChannel:e.originChannel,originThreadId:e.originThreadId,originSessionKey:e.originSessionKey});if(!r)return;let i;try{let s=it(e.id);if(Rf(s))i=s;else{let a=e.getOutput().join(`
|
|
221
|
-
`);a.length>0&&(Af(s,a,"utf-8"),i=s)}}catch(s){`${e.id}${If(s)}`}let o={sessionId:e.id,harnessSessionId:e.harnessSessionId,backendRef:this.buildPersistedBackendRef(e),name:e.name,prompt:e.prompt,workdir:e.originalWorkdir??e.workdir,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,createdAt:e.startedAt,completedAt:e.completedAt,status:e.status,lifecycle:e.lifecycle,approvalState:e.approvalState,worktreeState:e.worktreeState,runtimeState:e.runtimeState,deliveryState:e.deliveryState,notificationDedupe:this.getExistingNotificationDedupe(e),killReason:e.killReason,costUsd:e.costUsd,originAgentId:e.originAgentId,originChannel:e.originChannel,originThreadId:e.originThreadId,originSessionKey:e.originSessionKey,route:r,outputPath:i,harness:e.harnessName,goalTaskId:e.goalTaskId,requestedPermissionMode:e.requestedPermissionMode,currentPermissionMode:e.currentPermissionMode,approvalExecutionState:e.approvalExecutionState,approvalRationale:e.approvalRationale,planModeApproved:n.planModeApproved,pendingPlanApproval:e.pendingPlanApproval,planApprovalContext:e.planApprovalContext,planDecisionVersion:e.planDecisionVersion,actionablePlanDecisionVersion:e.actionablePlanDecisionVersion,canonicalPlanPromptVersion:e.canonicalPlanPromptVersion,approvalPromptRequiredVersion:e.approvalPromptRequiredVersion,approvalPromptVersion:e.approvalPromptVersion,approvalPromptStatus:e.approvalPromptStatus,approvalPromptTransport:e.approvalPromptTransport,approvalPromptMessageKind:e.approvalPromptMessageKind,approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:e.approvalPromptDeliveredAt,approvalPromptFailedAt:e.approvalPromptFailedAt,planApproval:e.planApproval,codexApprovalPolicy:e.codexApprovalPolicy,worktreePath:e.worktreePath,worktreeBranch:e.worktreeBranch,worktreeStrategy:e.worktreeStrategy,worktreeBaseBranch:e.worktreeBaseBranch,worktreePrTargetRepo:e.worktreePrTargetRepo,autoMergeParentSessionId:e.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:e.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:e.autoMergeResolverSessionId,worktreeLifecycle:e.worktreeLifecycle,resumable:e.isExplicitlyResumable};xr(o),this.indexPersistedEntry(o),this.saveIndex()}getExistingNotificationDedupe(e){return this.getPersistedSession(e.id)?.notificationDedupe??(e.harnessSessionId?this.getPersistedSession(e.harnessSessionId)?.notificationDedupe:void 0)??(x(e)?this.getPersistedSession(x(e))?.notificationDedupe:void 0)}getLatestPersistedByName(e){return this.queries.getLatestPersistedByName(e)}resolveBackendConversationId(e,n){return this.queries.resolveBackendConversationId(e,n)}resolveHarnessSessionId(e,n){return this.queries.resolveHarnessSessionId(e,n)}getPersistedSession(e){return this.queries.getPersistedSession(e)}listPersistedSessions(){return this.queries.listPersistedSessions()}cleanupTmpOutputFiles(e){this.actionTokenStore.purgeExpiredActionTokens(e),Md(e,So)}getNextTmpOutputCleanupAt(e){return _d(e,So)}evictOldestPersisted(e){let n=this.listPersistedSessions();if(n.length<=e)return[];let r=n.slice(e);for(let i of r)this.removePersistedIndexes(i);return this.saveIndex(),r}shouldGcActiveSession(e,n,r){return!e.completedAt||!xf.has(e.status)?!1:n-e.completedAt>r}getActionToken(e){return this.actionTokenStore.getActionToken(e)}consumeActionToken(e){return this.actionTokenStore.consumeActionToken(e)}deleteActionTokensForSession(e){this.actionTokenStore.deleteActionTokensForSession(e)}purgeExpiredActionTokens(e=Date.now()){this.actionTokenStore.purgeExpiredActionTokens(e)}getNextActionTokenExpiry(){return this.actionTokenStore.nextExpiryAt()}onActionTokensChanged(e){this.actionTokenStore.setAfterChangeListener(e)}hasOutputPathReference(e){for(let n of this.persisted.values())if(n.outputPath===e)return!0;return!1}getReferencedOutputPaths(){return[...new Set([...this.persisted.values()].map(e=>e.outputPath).filter(e=>typeof e=="string"&&e.length>0))]}cleanupOrphanOutputFiles(){$d(this.getReferencedOutputPaths())}};var Tf=new Set(["completed","failed","killed"]),Mr=class{metrics={totalCostUsd:0,costPerDay:new Map,sessionsByStatus:{completed:0,failed:0,killed:0},totalLaunched:0,totalDurationMs:0,sessionsWithDuration:0,mostExpensive:null};incrementLaunched(){this.metrics.totalLaunched++}recordSession(e){let n=e.costUsd??0,r=e.status;this.metrics.totalCostUsd+=n;let i=new Date(e.completedAt??e.startedAt).toISOString().slice(0,10);if(this.metrics.costPerDay.set(i,(this.metrics.costPerDay.get(i)??0)+n),Tf.has(r)&&this.metrics.sessionsByStatus[r]++,e.completedAt){let o=e.completedAt-e.startedAt;this.metrics.totalDurationMs+=o,this.metrics.sessionsWithDuration++}(!this.metrics.mostExpensive||n>this.metrics.mostExpensive.costUsd)&&(this.metrics.mostExpensive={id:e.id,name:e.name,costUsd:n,prompt:Z(e.prompt,80)})}getMetrics(){return{totalCostUsd:this.metrics.totalCostUsd,costPerDay:new Map(this.metrics.costPerDay),sessionsByStatus:{...this.metrics.sessionsByStatus},totalLaunched:this.metrics.totalLaunched,totalDurationMs:this.metrics.totalDurationMs,sessionsWithDuration:this.metrics.sessionsWithDuration,mostExpensive:this.metrics.mostExpensive?{...this.metrics.mostExpensive}:null}}};import*as Wd from"child_process";var Dd=5e3,Cf=64,Mf={primary:"primary",success:"success",positive:"success",danger:"danger",destructive:"danger",negative:"danger"},_f={execFile:Wd.execFile},$e=class extends Error{constructor(e){super(e),this.name="MissingRuntimeDirectNotificationCapabilityError"}},_r=class{constructor(e=_f.execFile){this.execFile=e}execFile;async send(e,n,r){$("direct_send_started",{...me(e),messageTextLength:n.length,...K(r)});try{await this.sendViaRuntime(e,n,r),$("direct_send_succeeded",{...me(e),deliveryPath:"runtime",...K(r)});return}catch(i){if(!(i instanceof $e))throw $("direct_send_failed",{...me(e),deliveryPath:"runtime",...K(r),error:ko(i)}),i;$("direct_send_runtime_capability_missing",{...me(e),deliveryPath:"runtime",...K(r),reason:i.message}),await this.sendViaBoundedCliFallback(e,n,r,i.message),$("direct_send_succeeded",{...me(e),deliveryPath:"cli-fallback",...K(r)})}}async sendViaRuntime(e,n,r){let i=Pn(),o=fs(),s=i?.channel?.outbound?.loadAdapter;if(!i)throw new $e("OpenClaw plugin runtime is unavailable for direct notification delivery");if(o==null)throw new $e("OpenClaw runtime config snapshot is unavailable for direct notification delivery");if(!i.channel)throw new $e(`OpenClaw plugin runtime channel surface is unavailable for direct notification delivery (runtimeVersion=${vo(i)})`);if(!i.channel.outbound)throw new $e(`OpenClaw plugin runtime channel outbound surface is unavailable for direct notification delivery (runtimeVersion=${vo(i)})`);if(!s)throw new $e(`OpenClaw plugin runtime channel outbound loadAdapter is unavailable for direct notification delivery (runtimeVersion=${vo(i)})`);let a=await s(e.channel);if(!a)throw new Error(`OpenClaw outbound adapter for channel "${e.channel}" is unavailable`);let d=$r(r);if($("runtime_adapter_loaded",{...me(e),adapterHasRenderPresentation:typeof a.renderPresentation=="function",adapterHasSendPayload:typeof a.sendPayload=="function",adapterHasSendText:typeof a.sendText=="function",...K(r),...d?Ji(d):{}}),d){await this.sendPresentation(a,o,e,n,d);return}if(!a.sendText)throw new Error(`OpenClaw outbound adapter for channel "${e.channel}" cannot send text`);await a.sendText({cfg:o,to:e.target,text:n,accountId:e.accountId,threadId:e.threadId})}async sendPresentation(e,n,r,i,o){let s=Ef(o),a={text:i,presentation:o,interactive:s};$("presentation_render_started",{...me(r),messageTextLength:i.length,adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...Ji(o)});let d={cfg:n,to:r.target,text:i,payload:a,accountId:r.accountId,threadId:r.threadId},l=e.renderPresentation?await e.renderPresentation({payload:a,presentation:o,ctx:d}):a,u=Of(l,s,r.channel);if($("presentation_render_completed",{...me(r),adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...Qi(u)}),!u||typeof u!="object"||!e.sendPayload)throw new Error(`OpenClaw outbound adapter for channel "${r.channel}" cannot preserve interactive presentation`);let c=await e.sendPayload({...d,payload:u});$("presentation_send_payload_completed",{...me(r),...Qi(u),...Aa(c)})}sendViaBoundedCliFallback(e,n,r,i){return new Promise((o,s)=>{let a=$f(e,n,r);$("direct_send_cli_fallback_started",{...me(e),deliveryPath:"cli-fallback",reason:i,messageTextLength:n.length,...K(r)}),this.execFile("openclaw",a,{timeout:Dd,killSignal:"SIGKILL"},(d,l,u)=>{if(!d){$("direct_send_cli_fallback_completed",{...me(e),deliveryPath:"cli-fallback",...K(r)}),o();return}let c=u?.trim()?` | stderr: ${u.trim()}`:"";$("direct_send_cli_fallback_failed",{...me(e),deliveryPath:"cli-fallback",...K(r),error:ko(d),stderrLength:u?.length}),s(new Error(`${i}; bounded openclaw message send fallback failed within ${Dd}ms timeout: ${ko(d)}${c}`))})})}};function me(t){return{channel:t.channel,target:t.target,accountId:t.accountId,threadId:t.threadId,sessionKey:t.sessionKey}}function $f(t,e,n){let r=$r(n),i=["message","send","--channel",t.channel,"--target",t.target,"--message",e];return t.accountId&&i.push("--account",t.accountId),t.threadId&&i.push("--thread-id",t.threadId),r&&i.push("--presentation",JSON.stringify(r)),i}function ko(t){return t instanceof Error?t.message:String(t)}function vo(t){if(!t||typeof t!="object")return"unknown";let e=t.version;return typeof e=="string"&&e.trim()?e:"unknown"}function $r(t){let e=(t??[]).filter(n=>Array.isArray(n)&&n.length>0).map(n=>({type:"buttons",buttons:n.map(r=>({label:r.label,value:Ff(r.callbackData),...r.style?{style:r.style}:{}}))}));return e.length>0?{blocks:e}:void 0}function Ef(t){let e=t.blocks.filter(n=>n.type==="buttons"&&n.buttons.length>0).map(n=>({type:"buttons",buttons:n.buttons.map(r=>({label:r.label,value:r.value,...r.style?{style:r.style}:{}}))}));return e.length>0?{blocks:e}:void 0}function Df(t){if(!t||typeof t!="object"||Array.isArray(t))return!1;let e=t.interactive;if(!e||typeof e!="object"||Array.isArray(e))return!1;let n=e.blocks;return Array.isArray(n)&&n.some(r=>{if(!r||typeof r!="object"||Array.isArray(r))return!1;let i=r;return i.type==="buttons"&&Array.isArray(i.buttons)&&i.buttons.length>0})}function Of(t,e,n){if(!e)return t;let r=Df(t)?t:Wf(t,e);return n!=="telegram"?r:Nf(r,e)}function Wf(t,e){return!t||typeof t!="object"||Array.isArray(t)?t:{...t,interactive:e}}function Nf(t,e){if(!t||typeof t!="object"||Array.isArray(t))return t;let n=t,r=Od(n.channelData),i=Od(r?.telegram),o=Bf(i?.buttons);if(o)return{...n,channelData:{...r??{},telegram:{...i??{},buttons:o}}};let s=Lf(e);return s?{...n,channelData:{...r??{},telegram:{...i??{},buttons:s}}}:t}function Lf(t){let e=t.blocks.filter(n=>n.type==="buttons"&&n.buttons.length>0).map(n=>n.buttons.filter(r=>typeof r.value=="string"&&r.value.trim().length>0&&Buffer.byteLength(r.value,"utf8")<=Cf).map(r=>({text:r.label,callback_data:r.value,...Nd(r.style)}))).filter(n=>n.length>0);return e.length>0?e:void 0}function Bf(t){if(!Array.isArray(t))return;let e=t.map(n=>Array.isArray(n)?n.map(r=>{if(!r||typeof r!="object"||Array.isArray(r))return;let{style:i,...o}=r;if(!(typeof o.text!="string"||o.text.trim().length===0))return{...o,...Nd(i)}}).filter(r=>!!r):[]).filter(n=>n.length>0);return e.length>0?e:void 0}function Nd(t){if(typeof t!="string")return{};let e=t.trim().toLowerCase(),n=Mf[e];return n?{style:n}:{}}function Od(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function Ff(t){return t.startsWith(`${ce}:`)?t:`${ce}:${t}`}import*as Ld from"child_process";var ht=class{tails=new Map;enqueue(e,n,r){let i=this.tails.get(e);i!==void 0&&r?.();let s=(i?.catch(()=>{})??Promise.resolve()).then(()=>n()),a=s.catch(()=>{});return this.tails.set(e,a),a.finally(()=>{this.tails.get(e)===a&&this.tails.delete(e)}),s}clear(){this.tails.clear()}};var wo=3e4,qf=2e3,Kf=2e4,ae=4;function Jt(t){return t instanceof Error?t.message:String(t)}function Uf(){return new Error(`Dispatch timed out after ${wo}ms`)}function Vf(t){if(!(t instanceof Error))return!1;let e=t;return e.killed===!0&&e.signal==="SIGKILL"}var Hf={execFile:Ld.execFile},Er=class{pendingRetryTimers=new Map;orderedDispatches=new ht;disposed=!1;clearPendingRetries(){for(let e of this.pendingRetryTimers.values())for(let n of e)clearTimeout(n.timer),n.onCleared?.();this.pendingRetryTimers.clear()}clearRetryTimersForSession(e){let n=this.pendingRetryTimers.get(e);if(n){for(let r of n)clearTimeout(r.timer),r.onCleared?.();this.pendingRetryTimers.delete(e)}}dispose(){this.disposed=!0,this.clearPendingRetries(),this.orderedDispatches.clear()}execute(e,n,r=1){if(!this.disposed){if(r===1&&n.orderingKey){this.enqueueOrderedDispatch(n.orderingKey,i=>this.executeNow(e,n,i,r));return}this.executeNow(e,n,void 0,r)}}executePromise(e,n,r=1){if(!this.disposed){if(r===1&&n.orderingKey){this.enqueueOrderedDispatch(n.orderingKey,i=>this.executePromiseNow(e,n,i,r));return}this.executePromiseNow(e,n,void 0,r)}}executeNow(e,n,r,i=1){if(this.disposed||n.shouldContinue?.()===!1){r?.();return}let o=Date.now();i===1&&n.onStarted?.(),this.log("info","dispatch_started",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:i,maxAttempts:ae}),Hf.execFile("openclaw",e,{timeout:wo,killSignal:"SIGKILL"},(s,a,d)=>{if(this.disposed){r?.();return}let l=Date.now()-o;if(!s){let g=n.successValidator?.(a??"");if(g?.outcome==="failure"){this.log("error","dispatch_success_validation_failed",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:i,maxAttempts:ae,elapsedMs:l,error:g.reason,terminal:!0}),n.onFinalFailure?.(),r?.();return}if(g?.outcome==="skipped"){this.log("info","dispatch_skipped",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:i,maxAttempts:ae,elapsedMs:l,reason:g.reason}),n.shouldContinue?.()!==!1&&n.onSkipped?.(g.reason),r?.();return}this.log("info","dispatch_succeeded",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:i,maxAttempts:ae,elapsedMs:l}),n.shouldContinue?.()!==!1&&n.onSuccess?.(),r?.();return}let u=d?.trim()?` | stderr: ${d.trim()}`:"";if(n.target==="message.send"&&Vf(s)){this.log("error","dispatch_failed",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:i,maxAttempts:ae,elapsedMs:l,error:`${Jt(s)}${u}`,terminal:!0,ambiguousResult:!0}),n.onAmbiguousResult?.(),r?.();return}if(i>=ae||n.terminalOnFailure===!0){this.log("error","dispatch_failed",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:i,maxAttempts:ae,elapsedMs:l,error:`${Jt(s)}${u}`,terminal:!0}),n.onFinalFailure?.(),r?.();return}let p=this.retryDelayMs(i);this.log("error","dispatch_retry_scheduled",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:i,maxAttempts:ae,elapsedMs:l,retryDelayMs:p,error:`${Jt(s)}${u}`});let f={timer:setTimeout(()=>{let g=this.pendingRetryTimers.get(n.sessionId);if(g&&(g.delete(f),g.size===0&&this.pendingRetryTimers.delete(n.sessionId)),n.shouldContinue?.()===!1){r?.();return}this.executeNow(e,n,r,i+1)},p),onCleared:r};f.timer.unref?.(),this.pendingRetryTimers.has(n.sessionId)||this.pendingRetryTimers.set(n.sessionId,new Set),this.pendingRetryTimers.get(n.sessionId).add(f)})}executePromiseNow(e,n,r,i=1){if(this.disposed||n.shouldContinue?.()===!1){r?.();return}let o=Date.now();i===1&&n.onStarted?.(),this.log("info","dispatch_started",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:i,maxAttempts:ae}),this.executePromiseWithTimeout(e).then(()=>{if(this.disposed){r?.();return}let s=Date.now()-o;this.log("info","dispatch_succeeded",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:i,maxAttempts:ae,elapsedMs:s}),n.shouldContinue?.()!==!1&&n.onSuccess?.(),r?.()}).catch(s=>{if(this.disposed){r?.();return}let a=Date.now()-o;if(i>=ae||n.terminalOnFailure===!0){this.log("error","dispatch_failed",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:i,maxAttempts:ae,elapsedMs:a,error:Jt(s),terminal:!0,...n.terminalOnFailure===!0&&i<ae?{terminalReason:"non_retryable"}:{}}),n.onFinalFailure?.(),r?.();return}let d=this.retryDelayMs(i);this.log("error","dispatch_retry_scheduled",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:i,maxAttempts:ae,elapsedMs:a,retryDelayMs:d,error:Jt(s)});let l={timer:setTimeout(()=>{let u=this.pendingRetryTimers.get(n.sessionId);if(u&&(u.delete(l),u.size===0&&this.pendingRetryTimers.delete(n.sessionId)),n.shouldContinue?.()===!1){r?.();return}this.executePromiseNow(e,n,r,i+1)},d),onCleared:r};l.timer.unref?.(),this.pendingRetryTimers.has(n.sessionId)||this.pendingRetryTimers.set(n.sessionId,new Set),this.pendingRetryTimers.get(n.sessionId).add(l)})}executePromiseWithTimeout(e){return new Promise((n,r)=>{let i=!1,o=setTimeout(()=>{i||(i=!0,r(Uf()))},wo);o.unref?.(),Promise.resolve().then(e).then(()=>{i||(i=!0,clearTimeout(o),n())}).catch(s=>{i||(i=!0,clearTimeout(o),r(s))})})}retryDelayMs(e){let n=Math.max(0,e-1),r=qf*2**n;return Math.min(r,Kf)}enqueueOrderedDispatch(e,n){this.orderedDispatches.enqueue(e,async()=>{this.disposed||await new Promise(r=>{let i=!1;n(()=>{i||(i=!0,r())})})})}log(e,n,r){let i=`[WakeDispatcher] ${JSON.stringify({event:n,...r})}`;if(e==="error"){console.error(i);return}}};he();var Dr=class{resolve(e){let n=we(e);if(!(!n?.provider||!n.target))return{channel:n.provider,target:n.target,accountId:n.accountId,threadId:n.threadId,sessionKey:n.sessionKey}}summary(e){if(!e)return"system";let n=e.accountId?`|${e.accountId}`:"",r=e.threadId?`#${e.threadId}`:"";return`${e.channel}${n}|${e.target}${r}`}};import{randomUUID as Gf}from"crypto";var Or=class{constructor(e={}){this.options=e}options;buildChatSendArgs(e,n,r,i=Gf()){return["gateway","call","chat.send","--expect-final","--timeout","30000","--params",JSON.stringify({sessionKey:e,message:n,deliver:r,idempotencyKey:i})]}buildDirectNotificationArgs(e,n,r){let i=$r(r),o=["message","send","--channel",e.channel,"--target",e.target,"--message",n];return e.accountId&&o.push("--account",e.accountId),e.threadId&&o.push("--thread-id",e.threadId),i&&o.push("--presentation",JSON.stringify(i)),o}buildSystemEventArgs(e){return["system","event","--text",e,"--mode","now"]}};function jf(t){let e=zf(t).trim();return e?/^NO_REPLY$/i.test(e)?{outcome:"failure",reason:"completion follow-up wake ended with NO_REPLY"}:{outcome:"success"}:{outcome:"failure",reason:"completion follow-up wake produced no final response"}}function zf(t){let e=t.trim();if(!e)return"";try{return Po(JSON.parse(e)).trim()}catch{return e}}function Po(t){if(typeof t=="string")return t;if(Array.isArray(t))return t.map(r=>Po(r)).filter(Boolean).join(`
|
|
222
|
-
`);if(!t||typeof t!="object")return"";let e=t,n=["final","finalResponse","final_response","assistantFinal","assistant_final","response","text","content"];for(let r of n){let i=e[r];if(typeof i=="string"&&i.trim())return i}for(let r of["result","message","data"]){let i=Po(e[r]);if(i.trim())return i}return""}var Wr=class{routes=new Dr;transport;directNotifications;executor=new Er;constructor(e={}){this.transport=e.transport??new Or(e.transportOptions),this.directNotifications=e.directNotifications===void 0?new _r:e.directNotifications}clearPendingRetries(){this.executor.clearPendingRetries()}clearRetryTimersForSession(e){this.executor.clearRetryTimersForSession(e)}dispose(){this.executor.dispose()}buildDispatchContext(e){let n=e.buttons??[],r=n.flat();return{transportRoute:e.routeSummary,transportChannel:e.route?.channel??"system",transportTarget:e.route?.target??"system",transportAccountId:e.route?.accountId,transportThreadId:e.route?.threadId,transportSessionKey:e.route?.sessionKey,messageTextLength:e.text.length,buttonsPresent:r.length>0,buttonRows:n.length||void 0,buttonCount:r.length||void 0,buttonLabels:r.length>0?r.map(i=>i.label):void 0,maxCallbackDataLength:r.length>0?Math.max(...r.map(i=>i.callbackData.length)):void 0}}sendWake(e,n,r,i,o,s,a,d,l,u){let c=this.routes.resolve(e),p=a;if(p?.()===!1)return;let f=c?.sessionKey?.trim();if(!f){this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-system`,sessionId:e.id,target:"system.event",phase:i,routeSummary:"system",messageKind:"wake",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n}),onSuccess:s,onSkipped:l,onFinalFailure:o,successValidator:d,shouldContinue:p});return}this.executor.execute(this.transport.buildChatSendArgs(f,n,!0,u),{label:r,sessionId:e.id,target:"chat.send",phase:i,routeSummary:`session:${f}`,messageKind:"wake",dispatchContext:this.buildDispatchContext({routeSummary:`session:${f}`,route:c,text:n}),onSuccess:s,onSkipped:l,successValidator:d,shouldContinue:p,onFinalFailure:()=>{p?.()!==!1&&this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-fallback`,sessionId:e.id,target:"system.event",phase:i,routeSummary:"system",messageKind:"wake",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n}),onSuccess:s,onSkipped:l,onFinalFailure:o,successValidator:d,shouldContinue:p})}})}sendUserNotification(e,n,r,i,o,s,a=!1,d){if(d?.()===!1)return;let l=!!i?.some(g=>Array.isArray(g)&&g.length>0),u=this.routes.resolve(e);$("wake_notify_selected",{sessionId:e.id,sessionName:e.name,label:r,messageTextLength:n.length,requireDirectDelivery:a,hasDirectNotificationTransport:!!this.directNotifications,routeSummary:u?this.routes.summary(u):"system",channel:u?.channel,target:u?.target,accountId:u?.accountId,threadId:u?.threadId,sessionKey:u?.sessionKey,...K(i)});let c=u?`notify:${u.channel}|${u.accountId??""}|${u.target}|${u.threadId??""}`:`notify:system:${e.id}`;if(!u){if($("wake_notify_no_direct_route",{sessionId:e.id,sessionName:e.name,label:r,requireDirectDelivery:a,hasInteractiveButtons:l,...K(i)}),a){`${r}${e.id}`,o?.();return}if(l){`${r}${e.id}`,o?.();return}this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-notify-system`,sessionId:e.id,target:"system.event",phase:"notify",routeSummary:"system",messageKind:"notify",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n,buttons:i}),orderingKey:c,onSuccess:s,onFinalFailure:o,shouldContinue:d});return}let p=()=>{if($("wake_notify_direct_failed",{sessionId:e.id,sessionName:e.name,label:r,requireDirectDelivery:a,hasInteractiveButtons:l,channel:u.channel,target:u.target,accountId:u.accountId,threadId:u.threadId,sessionKey:u.sessionKey,...K(i)}),a){`${r}${e.id}`,o?.();return}if(l){`${r}${e.id}`,o?.();return}this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-notify-fallback`,sessionId:e.id,target:"system.event",phase:"notify",routeSummary:"system",messageKind:"notify",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n}),orderingKey:c,onSuccess:s,onFinalFailure:o,shouldContinue:d})},f={label:`${r}-notify`,sessionId:e.id,target:"message.send",phase:"notify",routeSummary:this.routes.summary(u),messageKind:"notify",dispatchContext:this.buildDispatchContext({routeSummary:this.routes.summary(u),route:u,text:n,buttons:i}),orderingKey:c,onSuccess:s,onAmbiguousResult:p,onFinalFailure:p,terminalOnFailure:this.directNotifications?!0:void 0,shouldContinue:d};if(this.directNotifications){$("wake_notify_dispatching_direct_runtime",{sessionId:e.id,sessionName:e.name,label:r,channel:u.channel,target:u.target,accountId:u.accountId,threadId:u.threadId,sessionKey:u.sessionKey,...K(i)}),this.executor.executePromise(()=>this.directNotifications.send(u,n,i),f);return}$("wake_notify_dispatching_cli_message_send",{sessionId:e.id,sessionName:e.name,label:r,channel:u.channel,target:u.target,accountId:u.accountId,threadId:u.threadId,sessionKey:u.sessionKey,...K(i)}),this.executor.execute(this.transport.buildDirectNotificationArgs(u,n,i),f)}sendUserNotificationSequence(e,n,r,i,o,s=!1,a){let d=n.map(u=>({text:u.text.trim(),buttons:u.buttons})).filter(u=>u.text.length>0);if(d.length===0){i?.();return}$("wake_notify_sequence_started",{sessionId:e.id,sessionName:e.name,label:r,chunkCount:d.length,buttonChunkIndexes:d.map((u,c)=>u.buttons?.some(p=>Array.isArray(p)&&p.length>0)?c+1:void 0).filter(u=>typeof u=="number"),requireDirectDelivery:s});let l=u=>{if(a?.()===!1)return;let c=d[u];if(!c){$("wake_notify_sequence_succeeded",{sessionId:e.id,sessionName:e.name,label:r,chunkCount:d.length}),o?.();return}let p=u===0?i:o;$("wake_notify_sequence_chunk_selected",{sessionId:e.id,sessionName:e.name,label:r,chunkIndex:u+1,chunkCount:d.length,messageTextLength:c.text.length,failureHandler:u===0?"all-failed":"sequence-success",...K(c.buttons)}),this.sendUserNotification(e,c.text,`${r}-part-${u+1}`,c.buttons,p,()=>l(u+1),s,a)};l(0)}dispatchSessionNotification(e,n){let r=n.hooks,i=n.wakeMessageOnNotifySuccess!=null||n.wakeMessageOnNotifyFailed!=null,o=n.notifyUser??(n.wakeMessage?"on-wake-fallback":"always"),s=(n.userMessages?.length?n.userMessages:n.userMessage?.trim()?[{text:n.userMessage.trim(),buttons:n.buttons}]:[]).map(c=>({text:c.text.trim(),buttons:c.buttons})).filter(c=>c.text.length>0),a=s[0]?.text,d=n.wakeMessage?.trim(),l=n.shouldDispatch,u=n.completionWakeSummaryRequired===!0?jf:void 0;if(i){let c=n.wakeMessageOnNotifySuccess?.trim(),p=n.wakeMessageOnNotifyFailed?.trim(),f=S=>{S&&l?.()!==!1&&(r?.onWakeStarted?.(),this.sendWake(e,S,`${n.label}-wake`,"wake",r?.onWakeFailed,r?.onWakeSucceeded,l,u,r?.onWakeSkipped,n.idempotencyKey))},g=S=>{if(S){if(n.deferConditionalWakeUntilNextTick===!0||n.deferConditionalWakeMs!==void 0){let P=Math.max(0,Math.floor(n.deferConditionalWakeMs??0));setTimeout(()=>f(S),P).unref?.();return}f(S)}},h=()=>{l?.()!==!1&&(r?.onNotifySucceeded?.(),c&&g(c))},y=p?()=>{l?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.(),g(p))}:()=>{l?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())};if(s.length>0){if(l?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,y,h,n.requireDirectUserNotification===!0,l)}else y();return}if(o==="always"&&s.length>0){if(l?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,()=>{l?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())},()=>{l?.()!==!1&&r?.onNotifySucceeded?.()},n.requireDirectUserNotification===!0,l)}if(d&&l?.()!==!1){if(r?.onWakeStarted?.(),o==="on-wake-fallback"&&s.length>0&&!this.routes.resolve(e)?.sessionKey){if(l?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,()=>{l?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())},()=>{l?.()!==!1&&r?.onNotifySucceeded?.()},!1,l)}this.sendWake(e,d,`${n.label}-wake`,"wake",r?.onWakeFailed,r?.onWakeSucceeded,l,u,r?.onWakeSkipped,n.idempotencyKey)}}};var Nr=class{constructor(e,n){this.actionTokens=e;this.isGitHubCliAvailable=n}actionTokens;isGitHubCliAvailable;createActionToken(e,n,r={}){return this.actionTokens.createActionToken(e,n,{expiresAt:Date.now()+10080*60*1e3,...r})}consumeActionToken(e){return this.actionTokens.consumeActionToken(e)}getActionToken(e){return this.actionTokens.getActionToken(e)}clearPlanDecisionTokens(e,n){this.actionTokens.deletePlanDecisionTokensForSession(e,n)}makeActionButton(e,n,r,i={}){let o=this.createActionToken(e,n,{label:r,...i});return{label:r,callbackData:o.id,style:this.resolveButtonStyle(n)}}resolveButtonStyle(e){switch(e){case"plan-approve":case"worktree-create-pr":case"worktree-update-pr":case"plan-offer-start":return"primary";case"worktree-merge":case"session-resume":case"session-restart":return"success";case"plan-reject":case"worktree-dismiss":return"danger";default:return"secondary"}}getWorktreeDecisionButtons(e,n){if(!n)return[];let r=[],i=[this.makeActionButton(e,"worktree-merge","Merge")];if(this.isGitHubCliAvailable())n.worktreePrUrl?(i.push(this.makeActionButton(e,"worktree-view-pr","View PR",{targetUrl:n.worktreePrUrl})),r.push(i),r.push([this.makeActionButton(e,"worktree-update-pr","Sync PR"),this.makeActionButton(e,"worktree-decide-later","Later")])):(i.push(this.makeActionButton(e,"worktree-create-pr","Open PR")),r.push(i),r.push([this.makeActionButton(e,"worktree-decide-later","Later"),this.makeActionButton(e,"worktree-dismiss","Discard")]));else return r.push([...i,this.makeActionButton(e,"worktree-decide-later","Later")]),r.push([this.makeActionButton(e,"worktree-dismiss","Discard")]),r;return n.worktreePrUrl&&r.push([this.makeActionButton(e,"worktree-dismiss","Discard")]),r}getPlanApprovalButtons(e,n){let r=[[this.makeActionButton(e,"plan-approve","Approve",{planDecisionVersion:n?.planDecisionVersion}),this.makeActionButton(e,"plan-request-changes","Revise",{planDecisionVersion:n?.planDecisionVersion}),this.makeActionButton(e,"plan-reject","Reject",{planDecisionVersion:n?.planDecisionVersion})]];return $("plan_approval_buttons_created",{sessionId:e,planDecisionVersion:n?.planDecisionVersion,...K(r)}),r}getResumeButtons(e,n){let r=[];return n.isExplicitlyResumable&&r.push(this.makeActionButton(e,"session-resume","Resume")),r.push(this.makeActionButton(e,"view-output","View output")),[r]}getQuestionButtons(e,n){if(n.length!==0)return[n.map((r,i)=>this.makeActionButton(e,"question-answer",r.label,{optionIndex:i}))]}getPlanOfferButtons(e){let{offerId:n,route:r,planName:i,planPrompt:o,planWorkdir:s,planWorktreeStrategy:a}=e,d=[[this.makeActionButton(n,"plan-offer-start","Start Plan",{route:r,launchName:i,launchPrompt:o,launchWorkdir:s,launchWorktreeStrategy:a}),this.makeActionButton(n,"plan-offer-dismiss","Dismiss",{route:r})]];return $("plan_offer_buttons_created",{offerId:n,planName:i,channel:r.provider,target:r.target,accountId:r.accountId,threadId:r.threadId,sessionKey:r.sessionKey,planPromptLength:o.length,planWorkdirLength:s.length,planWorktreeStrategy:a,...K(d)}),d}};V();he();import{createHash as Zf}from"crypto";var Jf="duplicate notification already delivered or in flight",Lr=class{maxRecords;inFlightTtlMs;now;inFlight=new Set;delivered=new Set;constructor(e={}){this.maxRecords=Math.max(1,Math.floor(e.maxRecords??64)),this.inFlightTtlMs=Math.max(1,Math.floor(e.inFlightTtlMs??6e5)),this.now=e.now??(()=>new Date)}claim(e,n,r){if(!e)return{allowed:!0};let i=this.now(),o=this.prune(n??[],i),s=o.find(a=>a.key===e);return this.delivered.has(e)||this.inFlight.has(e)||s?.status==="delivered"||s?.status==="in_flight"&&this.isFreshInFlight(s,i)?{allowed:!1,records:o,reason:Jf}:(this.inFlight.add(e),this.delivered.delete(e),{allowed:!0,records:this.upsert(o,{key:e,status:"in_flight",recordedAt:i.toISOString(),label:r})})}deliveredRecords(e,n,r){if(!e)return;let i=this.now();return this.inFlight.delete(e),this.delivered.add(e),this.upsert(this.prune(n??[],i),{key:e,status:"delivered",recordedAt:i.toISOString(),label:r})}releasedRecords(e,n){if(!e)return;let r=this.now();return this.inFlight.delete(e),this.prune(n??[],r).filter(i=>!(i.key===e&&i.status==="in_flight"))}prune(e,n){let r=e.filter(i=>i.status==="delivered"?!0:this.isFreshInFlight(i,n));return r.slice(Math.max(0,r.length-this.maxRecords))}isFreshInFlight(e,n){let r=Date.parse(e.recordedAt);return Number.isFinite(r)?n.getTime()-r<this.inFlightTtlMs:!1}upsert(e,n){let i=[...e.filter(o=>o.key!==n.key),n];return i.slice(Math.max(0,i.length-this.maxRecords))}};he();V();he();import{createHash as Qf}from"crypto";var Yf=1024,Qt="duplicate completion follow-up wake already handled",Br="prior human-visible summary already delivered",Fr=class{inFlight=new Set;completed=new Map;claimKeysByPrimary=new Map;maxCompletedKeys;constructor(e={}){this.maxCompletedKeys=Math.max(1,Math.floor(e.maxCompletedKeys??Yf))}decide(e,n,r){if(n?.required!==!0)return{required:!1,allowed:!1,explicit:!1};let i=this.buildKeySet(e,n);if(!i)return{required:!0,allowed:!0,explicit:!1};let o=this.normalizeRecords(r),s=new Map(o.map(u=>[u.key,u])),a=i.decisionKeys.find(u=>this.inFlight.has(u)||this.completed.has(u)||s.has(u)),d=a?this.completed.get(a):void 0,l=a?s.get(a):void 0;return a?{required:!0,allowed:!1,explicit:i.explicit,dedupeKey:i.primary,skipReason:d?.skipReason??l?.skipReason??Qt}:(this.registerClaim(i.primary,i.claimKeys),{required:!0,allowed:!0,key:i.primary,explicit:i.explicit})}recordVisibleDelivery(e,n,r,i){if(n.required!==!0)return{required:!1,allowed:!1,explicit:!1};let o=this.buildKeySet(e,n);if(!o)return{required:!0,allowed:!0,explicit:!1};let s=this.normalizeRecords(r),a=new Map(s.map(p=>[p.key,p])),d=o.decisionKeys.find(p=>this.completed.has(p)||a.has(p)),l=d?this.completed.get(d):void 0,u=d?a.get(d):void 0;if(l||u)return{required:!0,allowed:!1,explicit:o.explicit,dedupeKey:o.primary,skipReason:l?.skipReason??u?.skipReason};this.finishKeys(o.primary,o.claimKeys,!0,Br);let c=this.deliveredRecords(o.claimKeys,s,i,Br);return{required:!0,allowed:!0,key:o.primary,explicit:o.explicit,records:c}}finish(e,n,r=Qt){if(!e)return;let i=this.claimKeysByPrimary.get(e)??[e];this.finishKeys(e,i,n,r)}completionRecordsAfterDelivery(e,n,r,i=Qt){if(!e)return;let o=this.claimKeysByPrimary.get(e)??[e];return this.deliveredRecords(o,n,r,i)}registerClaim(e,n){for(let r of n)this.inFlight.add(r);for(this.claimKeysByPrimary.delete(e),this.claimKeysByPrimary.set(e,n);this.claimKeysByPrimary.size>this.maxCompletedKeys;){let r=this.claimKeysByPrimary.keys().next().value;if(r===void 0)break;let i=this.claimKeysByPrimary.get(r)??[r];for(let o of i)this.inFlight.delete(o);this.claimKeysByPrimary.delete(r)}}finishKeys(e,n,r,i=Qt){for(let o of n)this.inFlight.delete(o);if(this.claimKeysByPrimary.delete(e),!!r){for(let o of n)this.completed.get(o)?.skipReason===Br&&i!==Br||(this.completed.delete(o),this.completed.set(o,{skipReason:i}));for(;this.completed.size>this.maxCompletedKeys;){let o=this.completed.keys().next().value;if(o===void 0)break;this.completed.delete(o)}}}buildKeySet(e,n){let r=this.getDeliveryRef(e);if(!r)return;let i=this.normalizeOutcomeKey(e,n.outcomeKey?.trim());if(i){let a=`${this.buildVisibleScope(r,e)}:outcome:${this.digest(i)}`,d=this.isGoalLike(e,n,i),l=this.buildSessionAliasKeys(r,e,"visible-summary"),u=this.buildSessionAliasKeys(r,e,"goal-summary"),c=this.isTerminalLike(n,i);return{primary:a,explicit:!0,claimKeys:[a,...l,...d?u:[]],decisionKeys:[a,...d||c?l:[],...u]}}let o=n.fallbackFingerprint?.trim();if(!o)return;let s=`${r}:${n.producer}:${this.digest(o)}`;return{primary:s,explicit:!1,claimKeys:[s],decisionKeys:[s]}}isGoalLike(e,n,r){return!!e.goalTaskId?.trim()||n.producer==="goal"||/^goal:/i.test(r)}isTerminalLike(e,n){return e.producer==="terminal"||/^terminal:/i.test(n)}normalizeOutcomeKey(e,n){let r=e.goalTaskId?.trim();if(r)return`goal:${r}`;let i=this.normalizeWorktreePrOutcomeKey(n);return i||n}normalizeWorktreePrOutcomeKey(e){if(!e)return;let n=e.split(":");if(n[0]!=="worktree-pr"||n.length<5)return;let r=n[1]?.trim().toLowerCase();if(!r||!/^(?:draft-)?(?:opened|updated)$/.test(r))return;let i=n[2]?.trim()||"default-repo",o=n[3]?.trim();if(!o)return;let s=this.normalizePrIdentity(o),a=n[4]?.trim();if(!(!s||!a))return["worktree-pr",i.toLowerCase(),s,a].join(":")}normalizePrIdentity(e){let n=e.match(/#?(\d+)$/);if(n?.[1])return`#${n[1]}`;let r=e.match(/\/pull\/(\d+)(?:\b|\/|$)/);if(r?.[1])return`#${r[1]}`;let i=e.trim();return i||void 0}buildVisibleScope(e,n){let r=we(n);return r?`route:${this.digest(JSON.stringify({provider:r.provider,accountId:r.accountId,target:r.target,threadId:r.threadId}))}`:e}buildSessionAliasKeys(e,n,r){let i=this.buildVisibleScope(e,n),o=["id"in n?n.id:void 0,"sessionId"in n?n.sessionId:void 0,n.name,x(n),n.harnessSessionId,e].map(s=>s?.trim()).filter(s=>!!s);return[...new Set(o)].map(s=>`${i}:session:${this.digest(s)}:${r}`)}getDeliveryRef(e){return D(e)??x(e)??""}digest(e){return Qf("sha256").update(e).digest("hex").slice(0,16)}normalizeRecords(e){return e?.length?e.filter(n=>n.key.trim()&&Number.isFinite(Date.parse(n.recordedAt))).slice(-this.maxCompletedKeys):[]}deliveredRecords(e,n,r,i=Qt){let o=new Date().toISOString(),d=[...this.normalizeRecords(n).filter(l=>!e.includes(l.key)),...e.map(l=>({key:l,recordedAt:o,label:r,skipReason:i}))];return d.slice(Math.max(0,d.length-this.maxCompletedKeys))}};var Xf=2e3;function eg(t){process.stderr.write(`[SessionNotification] ${JSON.stringify(t)}
|
|
223
|
-
`)}var
|
|
217
|
+
(Pre-existing changes on ${o} were auto-stashed and restored.)`);let l=[s.fastForward?"Merge type: fast-forward.":"Merge type: merge commit.",`Auto-merge landed ${r} into ${o}.`,"Local worktree branch cleanup was requested.",...s.stashPopConflict?[`Pre-merge stash pop conflicted; run git stash show ${s.stashRef??"stash@{0}"} in ${n} to review stashed changes.`]:[],...!s.stashPopConflict&&s.stashed?[`Pre-existing changes on ${o} were auto-stashed and restored.`]:[]];this.deps.dispatchSessionNotification(e,{label:"worktree-merge-success",idempotencyKey:`worktree-merge-success:${e.id}:${r}:${o}`,userMessage:d,notifyUser:"always",completionSummary:{required:!0,producer:"worktree",outcomeKey:`terminal:${e.id}`},completionWakeSummaryRequired:!0,completionWakeOutcomeKey:`terminal:${e.id}`,deferConditionalWakeUntilNextTick:!0,wakeMessageOnNotifySuccess:yt({sessionId:e.id,sessionName:e.name,outcomeLine:a,originThreadLine:this.deps.originThreadLine(e),detailLines:l,canonicalStatusDelivered:!0}),wakeMessageOnNotifyFailed:yt({sessionId:e.id,sessionName:e.name,outcomeLine:a,originThreadLine:this.deps.originThreadLine(e),detailLines:l,canonicalStatusDelivered:!1})})}async handleInitialAutoMergeConflict(e,n,r,o,i,s){let a=e.autoMergeConflictResolutionAttemptCount??0;if(a>=1){this.markPendingDecision(e,{notes:["auto_merge_conflict_retry_exhausted"],clearResolverSessionId:!0}),this.notifyAutoMergeConflictEscalation(e,o,`The rebased branch still conflicts with \`${i}\`. Open a PR or resolve manually in ${r}.`);return}let d=this.buildConflictResolverPrompt({session:e,repoDir:n,worktreePath:r,branchName:o,baseBranch:i,mergeError:s});try{let l=await this.deps.spawnConflictResolver({session:e,repoDir:n,worktreePath:r,branchName:o,baseBranch:i,prompt:d});this.markAutoMergeConflictResolving(e,l.id,a+1),this.deps.dispatchSessionNotification(e,{label:"worktree-merge-conflict-resolving",idempotencyKey:`worktree-merge-conflict-resolving:${e.id}:${o}:${l.id}`,userMessage:`⚠️ [${e.name}] Auto-merge hit a rebase conflict. Started resolver session ${l.name} and will retry automatically if it succeeds.`})}catch(l){this.markPendingDecision(e,{notes:["auto_merge_conflict_resolver_spawn_failed"]}),this.deps.dispatchSessionNotification(e,{label:"worktree-merge-conflict-spawn-failed",idempotencyKey:`worktree-merge-conflict-spawn-failed:${e.id}:${o}`,userMessage:`❌ [${e.name}] Auto-merge hit a rebase conflict and failed to start the resolver: ${l instanceof Error?l.message:String(l)}`,buttons:[[this.deps.makeOpenPrButton(e.id)]]})}}handleAutoMergeRetryFailure(e,n,r,o){this.markPendingDecision(e,{notes:["auto_merge_conflict_retry_failed"],clearResolverSessionId:!0}),this.deps.dispatchSessionNotification(e,{label:"worktree-merge-error",idempotencyKey:`worktree-merge-error:${e.id}:${n}`,userMessage:[o,"","Auto-merge retry did not complete after conflict resolution.",`Branch \`${n}\` was preserved for manual follow-up in ${r}.`].join(`
|
|
218
|
+
`),buttons:[[this.deps.makeOpenPrButton(e.id)]]})}async handleAutoMergeStrategy(e,n,r,o,i,s,a=W(e)??e.harnessSessionId){this.deps.isAlreadyMerged(a)||e.autoMergeResolverSessionId||await this.deps.enqueueMerge(n,async()=>{if(this.deps.isAlreadyMerged(a))return;let d=this.deps.mergeBranch(n,o,i,"merge",r);if(d.success){this.handleAutoMergeSuccess(e,n,o,i,s,d);return}if(d.rebaseConflict){await this.handleInitialAutoMergeConflict(e,n,r,o,i,d.error);return}let l=d.dirtyError?`❌ [${e.name}] Merge blocked: ${d.error}`:`❌ [${e.name}] Merge failed: ${d.error??"unknown error"}`;if(e.worktreeState==="merge_conflict_resolving"||e.worktreeLifecycle?.state==="merge_conflict_resolving"){this.handleAutoMergeRetryFailure(e,o,r,l);return}this.deps.dispatchSessionNotification(e,{label:"worktree-merge-error",idempotencyKey:`worktree-merge-error:${e.id}:${o}`,userMessage:l})},()=>{this.deps.dispatchSessionNotification(e,{label:"worktree-merge-queued",idempotencyKey:`worktree-merge-queued:${e.id}:${o}`,userMessage:`🕐 [${e.name}] Merge queued — another merge for this repo is in progress. Will notify when complete.`})})}async handleAutoPrStrategy(e,n,r,o,i){if(this.updatePersistedSessionFor(e,{lifecycle:"terminal",worktreeState:"pr_in_progress"}),!(await this.deps.runAutoPr(e,i)).success){let a=ut(n);if(!!(a&&a!==o&&ct(n,o,a)&&Ve(r).length===0)){let l=ne(e)?!0:de(n,r);return l&&(e.worktreePath=void 0,this.updatePersistedSessionFor(e,{worktreePath:void 0})),ge(n,o),this.markReleased(e,[`released_by_branch:${a}`]),{notificationSent:!1,worktreeRemoved:l}}this.markPendingDecision(e),this.deps.dispatchSessionNotification(e,{label:"worktree-auto-pr-failed",idempotencyKey:`worktree-auto-pr-failed:${e.id}:${i}`,userMessage:`⚠️ [${e.name}] Auto-PR did not complete. The worktree is preserved for an explicit merge or PR decision.`,buttons:this.deps.getWorktreeDecisionButtons(e.id)})}return{notificationSent:!0,worktreeRemoved:!1}}};import{existsSync as Wf,writeFileSync as Nf}from"fs";ve();import{randomUUID as nf}from"crypto";function rf(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"}var _r=class{constructor(e,n){this.onChange=e;this.retentionMs=n}onChange;retentionMs;tokens=new Map;afterChange;replaceAll(e){this.tokens.clear();for(let n of e)this.tokens.set(n.id,n)}clear(){this.tokens.clear(),this.notifyChanged()}listForPersistence(){return[...this.tokens.values()]}createActionToken(e,n,r={}){let o={id:nf(),sessionId:e,kind:n,createdAt:Date.now(),...r};return this.tokens.set(o.id,o),this.notifyChanged(),o}getActionToken(e){let n=this.tokens.get(e);if(n){if(n.expiresAt!=null&&n.expiresAt<=Date.now()){this.tokens.delete(e),this.notifyChanged();return}return n}}consumeActionToken(e){let n=this.getActionToken(e);if(!(!n||n.consumedAt!=null))return n.consumedAt=Date.now(),this.notifyChanged(),n}deleteActionTokensForSession(e){let n=!1;for(let[r,o]of this.tokens)o.sessionId===e&&(this.tokens.delete(r),n=!0);n&&this.notifyChanged()}deletePlanDecisionTokensForSession(e,n){let r=!1;for(let[o,i]of this.tokens)i.sessionId!==e||!rf(i.kind)||n!=null&&i.planDecisionVersion===n||(this.tokens.delete(o),r=!0);r&&this.notifyChanged()}purgeExpiredActionTokens(e=Date.now()){let n=!1;for(let[r,o]of this.tokens){let i=o.expiresAt!=null&&o.expiresAt<=e,s=o.consumedAt!=null&&e-o.consumedAt>this.retentionMs;(i||s)&&(this.tokens.delete(r),n=!0)}n&&this.notifyChanged()}nextExpiryAt(){let e;for(let n of this.tokens.values()){let r=[n.expiresAt,n.consumedAt!=null?n.consumedAt+this.retentionMs:void 0].filter(o=>o!=null&&Number.isFinite(o));for(let o of r)(e==null||o<e)&&(e=o)}return e}setAfterChangeListener(e){this.afterChange=e}notifyChanged(){this.onChange(),this.afterChange?.()}};Q();Q();var Er=class{constructor(e){this.indexes=e}indexes;hasRecordedSession(e){return this.indexes.idIndex.has(e)}getLatestPersistedByName(e){let n,r=Number.NEGATIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY,s=0;for(let a of this.indexes.persisted.values()){if(a.name!==e){s++;continue}let d=a.createdAt??Number.NEGATIVE_INFINITY,l=a.completedAt??Number.NEGATIVE_INFINITY;(d>r||d===r&&l>o||d===r&&l===o&&s>i)&&(n=a,r=d,o=l,i=s),s++}return n}resolveBackendConversationId(e,n){if(n)return n;let r=this.indexes.idIndex.get(e);if(r){let s=this.indexes.persisted.get(r);return(s?C(s):void 0)??r}let o=this.getLatestPersistedByName(e);if(o)return C(o)??o.harnessSessionId;let i=this.indexes.backendIdIndex.get(e);if(i){let s=this.indexes.persisted.get(i);return(s?C(s):void 0)??i}if(this.indexes.persisted.has(e)){let s=this.indexes.persisted.get(e);return s?C(s)??e:e}if(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e))return e}resolveHarnessSessionId(e,n){return this.resolveBackendConversationId(e,n)}getPersistedSession(e){let n=this.indexes.idIndex.get(e);if(n)return this.indexes.persisted.get(n);let r=this.getLatestPersistedByName(e);if(r)return r;let o=this.indexes.backendIdIndex.get(e);return o?this.indexes.persisted.get(o):this.indexes.persisted.get(e)}listPersistedSessions(){return[...this.indexes.persisted.values()].sort((e,n)=>(n.completedAt??0)-(e.completedAt??0))}};import{existsSync as _f,mkdirSync as Ef,readFileSync as $f,readdirSync as Ci,renameSync as Wd,statSync as Nd,unlinkSync as Ld,writeFileSync as Bd}from"fs";import{tmpdir as Mi}from"os";import{dirname as Df,join as Wr}from"path";import{homedir as of}from"node:os";import{join as sf}from"node:path";function Md(t){let e=t.OPENCLAW_HOME?.trim();if(e)return e;let n=t.HOME?.trim()||of();return sf(n,".openclaw")}ve();var $r=6,af=new Set(["running","completed","failed","killed"]);function Je(t){return!!t&&typeof t=="object"}function kt(t,e=""){return typeof t=="string"&&t.trim().length>0?t:e}function w(t){return typeof t=="string"&&t.trim().length>0?t:void 0}function ce(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}function df(t){return typeof t=="string"&&ga.has(t)?t:void 0}function _d(t){return t==="default"||t==="plan"||t==="bypassPermissions"?t:void 0}function lf(t){return t==="never"||t==="on-request"?"never":void 0}function uf(t){return t==="approve"||t==="ask"||t==="delegate"?t:void 0}function cf(t){if(t==="plan-mode"||t==="codex-first-turn-plan"||t==="soft-plan")return"plan-mode"}function Ed(t){return typeof t=="string"&&Zn.has(t)?t:void 0}function pf(t){return t==="user"||t==="idle-timeout"||t==="startup-timeout"||t==="shutdown"||t==="done"||t==="unknown"?t:void 0}function mf(t){return t==="starting"||t==="active"||t==="awaiting_plan_decision"||t==="awaiting_user_input"||t==="awaiting_worktree_decision"||t==="suspended"||t==="terminal"?t:void 0}function ff(t){return t==="not_required"||t==="pending"||t==="approved"||t==="changes_requested"||t==="rejected"?t:void 0}function gf(t){return t==="none"||t==="provisioned"||t==="pending_decision"||t==="merge_conflict_resolving"||t==="merge_in_progress"||t==="pr_in_progress"||t==="merged"||t==="released"||t==="pr_open"||t==="dismissed"||t==="cleanup_failed"?t:void 0}function hf(t){return t==="none"||t==="provisioned"||t==="pending_decision"||t==="merge_conflict_resolving"||t==="pr_open"||t==="merged"||t==="released"||t==="dismissed"||t==="no_change"||t==="cleanup_failed"?t:void 0}function Sf(t){return t==="live"||t==="stopped"?t:void 0}function yf(t){return t==="not_sent"||t==="sending"||t==="delivered"||t==="fallback_delivered"||t==="failed"?t:void 0}function kf(t){return t==="direct-telegram"?"direct-message":t==="none"||t==="direct-message"||t==="wake-only"?t:void 0}function vf(t){return t==="none"||t==="canonical_buttons"||t==="explicit_fallback_text"?t:void 0}function wf(t){return t==="idle"||t==="notifying"||t==="wake_pending"||t==="failed"?t:void 0}function Pf(t){return t==="in_flight"||t==="delivered"?t:void 0}function bf(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!Je(n))return;let r=w(n.key),o=Pf(n.status),i=w(n.recordedAt);if(!(!r||!o||!i||!Number.isFinite(Date.parse(i))))return{key:r,status:o,recordedAt:i,label:w(n.label)}}).filter(n=>!!n);return e.length>0?e.slice(-64):void 0}function Af(t){if(!Array.isArray(t))return;let e=t.map(n=>{if(!Je(n))return;let r=w(n.key),o=w(n.recordedAt);if(!(!r||!o||!Number.isFinite(Date.parse(o))))return{key:r,recordedAt:o,label:w(n.label),skipReason:w(n.skipReason)}}).filter(n=>!!n);return e.length>0?e.slice(-1024):void 0}function Rf(t){return t==="awaiting_plan_output"||t==="awaiting_approval"||t==="approved_then_implemented"||t==="implemented_without_required_approval"||t==="not_plan_gated"?t:void 0}function If(t){return t==="plan-approve"||t==="plan-request-changes"||t==="plan-reject"||t==="plan-offer-start"||t==="plan-offer-dismiss"||t==="worktree-merge"||t==="worktree-create-pr"||t==="worktree-update-pr"||t==="worktree-view-pr"||t==="worktree-decide-later"||t==="worktree-dismiss"||t==="session-resume"||t==="session-restart"||t==="view-output"||t==="question-answer"?t:void 0}function $d(t){if(!Je(t))return;let e=w(t.provider),n=w(t.accountId),r=w(t.target),o=w(t.threadId),i=w(t.sessionKey);if(!(!e||!r))return{provider:e,accountId:n,target:r,threadId:o,sessionKey:i}}function xf(t,e,n){if(Je(t)){let r=w(t.kind),o=w(t.conversationId);if(o&&(r==="claude-code"||r==="codex-app-server"||r==="opencode-server"))return{kind:r,conversationId:o,runId:w(t.runId),worktreeId:w(t.worktreeId),worktreePath:w(t.worktreePath)}}if(e==="claude-code")return{kind:"claude-code",conversationId:n}}function Tf(t){if(!Je(t))return;let e=hf(t.state),n=w(t.updatedAt);if(!e||!n)return;let r=w(t.resolutionSource);return{state:e,updatedAt:n,resolvedAt:w(t.resolvedAt),resolutionSource:r==="agent_merge"||r==="agent_pr"||r==="strategy_no_change"||r==="lifecycle_resolver"||r==="dismiss"||r==="maintenance"?r:void 0,baseBranch:w(t.baseBranch),targetRepo:w(t.targetRepo),pushRemote:w(t.pushRemote),notes:Array.isArray(t.notes)?t.notes.filter(o=>typeof o=="string"&&o.length>0):void 0}}function Cf(t){let e=new Date(0).toISOString(),n=w(t.worktreeMergedAt)??w(t.worktreeDismissedAt)??w(t.pendingWorktreeDecisionSince)??e;if(t.worktreeMerged===!0)return{state:"merged",updatedAt:n,resolvedAt:w(t.worktreeMergedAt)??n,resolutionSource:"agent_merge",baseBranch:w(t.worktreeBaseBranch),targetRepo:w(t.worktreePrTargetRepo),pushRemote:w(t.worktreePushRemote)};if(t.worktreeDisposition==="dismissed")return{state:"dismissed",updatedAt:n,resolvedAt:w(t.worktreeDismissedAt)??n,resolutionSource:"dismiss",baseBranch:w(t.worktreeBaseBranch),targetRepo:w(t.worktreePrTargetRepo),pushRemote:w(t.worktreePushRemote)};if(t.worktreeDisposition==="no-change-cleaned")return{state:"no_change",updatedAt:n,resolvedAt:n,resolutionSource:"strategy_no_change",baseBranch:w(t.worktreeBaseBranch),targetRepo:w(t.worktreePrTargetRepo),pushRemote:w(t.worktreePushRemote)};if(t.worktreeDisposition==="pr-opened"||t.worktreeState==="pr_open")return{state:"pr_open",updatedAt:n,baseBranch:w(t.worktreeBaseBranch),targetRepo:w(t.worktreePrTargetRepo),pushRemote:w(t.worktreePushRemote)};if(t.pendingWorktreeDecisionSince||t.worktreeState==="pending_decision")return{state:"pending_decision",updatedAt:n,baseBranch:w(t.worktreeBaseBranch),targetRepo:w(t.worktreePrTargetRepo),pushRemote:w(t.worktreePushRemote)};if(t.worktreeState==="merge_conflict_resolving")return{state:"merge_conflict_resolving",updatedAt:n,baseBranch:w(t.worktreeBaseBranch),targetRepo:w(t.worktreePrTargetRepo),pushRemote:w(t.worktreePushRemote)};if(w(t.worktreePath)||w(t.worktreeBranch))return{state:"provisioned",updatedAt:n,baseBranch:w(t.worktreeBaseBranch),targetRepo:w(t.worktreePrTargetRepo),pushRemote:w(t.worktreePushRemote)}}function Mf(t){if(typeof t=="string"&&af.has(t))return t==="running"?"killed":t}function Dd(t){if(!Je(t))return;let e=kt(t.harnessSessionId);if(!e)return;let n=Mf(t.status);if(!n)return;let r=t.status==="running",o=w(t.worktreePath),i=w(t.worktreeBranch),s=w(t.originChannel),a=typeof t.originThreadId=="string"||typeof t.originThreadId=="number"?t.originThreadId:void 0,d=w(t.originSessionKey),l=$d(t.route);if(!l)return;let u=Ne({route:l,originChannel:s,originThreadId:a,originSessionKey:d});if(!u||o&&!i)return;let c=w(t.harness),p=xf(t.backendRef,c,e),f=Tf(t.worktreeLifecycle)??Cf(t),g=w(t.completionWakeSucceededAt),h=w(t.completionWakeSkippedAt),y=t.completionWakeSummaryRequired===!0&&!h?!0:void 0;return{sessionId:w(t.sessionId),harnessSessionId:e,backendRef:p,name:kt(t.name,e),prompt:kt(t.prompt),workdir:kt(t.workdir,"(unknown)"),model:w(t.model),reasoningEffort:df(t.reasoningEffort),fastMode:t.fastMode===!0?!0:void 0,createdAt:ce(t.createdAt),completedAt:ce(t.completedAt),status:n,lifecycle:r?"suspended":mf(t.lifecycle),approvalState:ff(t.approvalState),worktreeState:gf(t.worktreeState),runtimeState:r?"stopped":Sf(t.runtimeState),deliveryState:wf(t.deliveryState),notificationDedupe:bf(t.notificationDedupe),completionSummaryDedupe:Af(t.completionSummaryDedupe),completionWakeIssuedAt:w(t.completionWakeIssuedAt),completionWakeSucceededAt:g,completionWakeFailedAt:w(t.completionWakeFailedAt),completionWakeSkippedAt:h,completionWakeSkipReason:w(t.completionWakeSkipReason),completionWakeSummaryRequired:y,killReason:pf(t.killReason),costUsd:typeof t.costUsd=="number"&&Number.isFinite(t.costUsd)?t.costUsd:0,originAgentId:w(t.originAgentId),originChannel:s,originThreadId:a,originSessionKey:d,route:u,outputPath:w(t.outputPath),harness:c,goalTaskId:w(t.goalTaskId),requestedPermissionMode:_d(t.requestedPermissionMode),currentPermissionMode:_d(t.currentPermissionMode),approvalExecutionState:Rf(t.approvalExecutionState),approvalRationale:w(t.approvalRationale),planModeApproved:t.planModeApproved===!0,pendingPlanApproval:t.pendingPlanApproval===!0,planApprovalContext:cf(t.planApprovalContext),planDecisionVersion:ce(t.planDecisionVersion),actionablePlanDecisionVersion:ce(t.actionablePlanDecisionVersion),canonicalPlanPromptVersion:ce(t.canonicalPlanPromptVersion),approvalPromptRequiredVersion:ce(t.approvalPromptRequiredVersion),approvalPromptVersion:ce(t.approvalPromptVersion),approvalPromptStatus:yf(t.approvalPromptStatus),approvalPromptTransport:kf(t.approvalPromptTransport),approvalPromptMessageKind:vf(t.approvalPromptMessageKind),approvalPromptLastAttemptAt:w(t.approvalPromptLastAttemptAt),approvalPromptDeliveredAt:w(t.approvalPromptDeliveredAt),approvalPromptFailedAt:w(t.approvalPromptFailedAt),planApproval:uf(t.planApproval),codexApprovalPolicy:lf(t.codexApprovalPolicy),worktreePath:o,worktreeBranch:i,worktreeStrategy:Ed(t.worktreeStrategy),worktreeMerged:typeof t.worktreeMerged=="boolean"?t.worktreeMerged:void 0,worktreeMergedAt:w(t.worktreeMergedAt),worktreePrUrl:w(t.worktreePrUrl),worktreePrNumber:ce(t.worktreePrNumber),pendingWorktreeDecisionSince:w(t.pendingWorktreeDecisionSince),lastWorktreeReminderAt:w(t.lastWorktreeReminderAt),worktreeBaseBranch:w(t.worktreeBaseBranch),worktreePrTargetRepo:w(t.worktreePrTargetRepo),autoMergeParentSessionId:w(t.autoMergeParentSessionId),autoMergeConflictResolutionAttemptCount:ce(t.autoMergeConflictResolutionAttemptCount),autoMergeResolverSessionId:w(t.autoMergeResolverSessionId),worktreePushRemote:w(t.worktreePushRemote),worktreeDecisionSnoozedUntil:w(t.worktreeDecisionSnoozedUntil),worktreeDisposition:t.worktreeDisposition==="active"||t.worktreeDisposition==="pr-opened"||t.worktreeDisposition==="merged"||t.worktreeDisposition==="dismissed"||t.worktreeDisposition==="no-change-cleaned"?t.worktreeDisposition:void 0,worktreeDismissedAt:w(t.worktreeDismissedAt),worktreeLifecycle:f,resumable:r?!0:t.resumable===!0}}function Od(t){if(!Je(t))return;let e=If(t.kind),n=kt(t.id),r=kt(t.sessionId),o=ce(t.createdAt);if(!(!n||!r||!e||o==null))return{id:n,sessionId:r,kind:e,createdAt:o,planDecisionVersion:ce(t.planDecisionVersion),expiresAt:ce(t.expiresAt),consumedAt:ce(t.consumedAt),optionIndex:ce(t.optionIndex),label:w(t.label),targetUrl:w(t.targetUrl),route:$d(t.route),launchName:w(t.launchName),launchPrompt:w(t.launchPrompt),launchWorkdir:w(t.launchWorkdir),launchWorktreeStrategy:Ed(t.launchWorktreeStrategy)}}function Dr(t){if(!t.backendRef?.kind||!t.backendRef.conversationId)throw new Error(`Persisted session ${t.harnessSessionId} is missing required backend ref metadata.`);if(!t.route?.provider||!t.route.target)throw new Error(`Persisted session ${t.harnessSessionId} is missing required route metadata.`);if(t.worktreePath&&!t.worktreeBranch)throw new Error(`Persisted session ${t.harnessSessionId} is missing required worktreeBranch metadata.`)}function Ti(t){return!!t&&typeof t=="object"}function _i(t){return t instanceof Error?t.message:String(t)}function Fd(t){let e=t.OPENCLAW_CODE_AGENT_SESSIONS_PATH?.trim();return e||Wr(Md(t),"code-agent-sessions.json")}function qd(t,e,n){try{Ef(Df(t),{recursive:!0});let r=t+".tmp";Bd(r,JSON.stringify({schemaVersion:$r,sessions:e,actionTokens:n},null,2),"utf-8"),Wd(r,t)}catch(r){`${_i(r)}`}}function Or(t,e){try{if(!_f(t))return;let n=`${t}.legacy-${Date.now()}.json`;Wd(t,n),`${e}${n}`}catch(n){`${_i(n)}`}}function Of(t,e){try{if(e.length===0)return;let n=`${t}.codex-sdk-legacy-${Date.now()}.json`;Bd(n,JSON.stringify(e,null,2),"utf-8"),`${e.length}${n}`}catch(n){`${_i(n)}`}}function Kd(t,e){try{let n=Mi(),r=Ci(n).filter(o=>o.startsWith("openclaw-agent-")&&o.endsWith(".txt"));for(let o of r)try{let i=Wr(n,o),s=Nd(i).mtimeMs;t-s>e&&Ld(i)}catch{}}catch{}}function Ud(t,e){try{let n=Mi(),r=Ci(n).filter(i=>i.startsWith("openclaw-agent-")&&i.endsWith(".txt")),o;for(let i of r)try{let s=Wr(n,i),a=Nd(s).mtimeMs+e;if(a<=t)return t;o=o==null?a:Math.min(o,a)}catch{}return o}catch{return}}function Vd(t){try{let e=new Set(t),n=Mi(),r=Ci(n).filter(o=>o.startsWith("openclaw-agent-")&&o.endsWith(".txt"));for(let o of r){let i=Wr(n,o);if(!e.has(i))try{Ld(i)}catch{}}}catch{}}function Gd(t){let{indexPath:e,clearAll:n,indexPersistedEntry:r,setActionToken:o,purgeExpiredActionTokens:i,saveIndex:s}=t;try{let a=$f(e,"utf-8"),d=JSON.parse(a);if(Array.isArray(d)){Or(e,"legacy array store"),s();return}if(!Ti(d)||d.schemaVersion!==$r&&d.schemaVersion!==4){Or(e,`schema mismatch (expected v${$r})`),s();return}let l=Array.isArray(d.sessions)?d.sessions:[],u=[];for(let p of l){if(Ti(p)&&p.harness==="codex"){let g=Ti(p.backendRef)?p.backendRef:void 0;if((typeof g?.kind=="string"?g.kind:void 0)!=="codex-app-server"){u.push(p);continue}}let f=Dd(p);if(!f){n(),Or(e,"invalid v4 session entry"),s();return}r(f)}u.length>0&&(Of(e,u),s());let c=Array.isArray(d.actionTokens)?d.actionTokens:[];for(let p of c){let f=Od(p);if(!f){n(),Or(e,"invalid v4 action token"),s();return}o(f)}i()}catch{}}var Lf=new Set(["completed","failed","killed"]),Ei=1440*60*1e3;function Bf(t){return t instanceof Error?t.message:String(t)}var Nr=class{persisted=new Map;idIndex=new Map;nameIndex=new Map;backendIdIndex=new Map;actionTokens;actionTokenStore;indexPath;queries;constructor(e={}){let n=e.env??process.env;this.indexPath=e.indexPath??Fd(n),this.actionTokenStore=new _r(()=>this.saveIndex(),Ei),this.actionTokens=this.actionTokenStore.tokens,this.queries=new Er({persisted:this.persisted,idIndex:this.idIndex,nameIndex:this.nameIndex,backendIdIndex:this.backendIdIndex}),n.OPENCLAW_DEBUG_SESSION_STORE==="1"&&`${this.indexPath}`,this.loadIndex()}loadIndex(){Gd({indexPath:this.indexPath,clearAll:()=>{this.persisted.clear(),this.idIndex.clear(),this.nameIndex.clear(),this.backendIdIndex.clear(),this.actionTokenStore.clear()},indexPersistedEntry:e=>this.indexPersistedEntry(e),setActionToken:e=>{this.actionTokens.set(e.id,e)},purgeExpiredActionTokens:()=>this.actionTokenStore.purgeExpiredActionTokens(),saveIndex:()=>this.saveIndex()})}saveIndex(){qd(this.indexPath,[...this.persisted.values()],this.actionTokenStore.listForPersistence())}assertPersistedEntry(e){Dr(e)}getEntryStorageKey(e){return e.harnessSessionId}buildPersistedBackendRef(e){let n=Oo(e),r=n==="codex"?"codex-app-server":n==="opencode"?"opencode-server":"claude-code";return e.backendRef??{kind:e.backendKind??r,conversationId:e.harnessSessionId}}getSessionApprovalSnapshot(e){if(typeof e.approvalSnapshot=="function")return e.approvalSnapshot();let n=typeof e.controlStateSnapshot=="function"?e.controlStateSnapshot():{planModeApproved:!1};return{requestedPermissionMode:e.requestedPermissionMode,currentPermissionMode:e.currentPermissionMode,approvalExecutionState:e.approvalExecutionState,approvalRationale:e.approvalRationale,planModeApproved:n.planModeApproved,pendingPlanApproval:e.pendingPlanApproval,planApprovalContext:e.planApprovalContext,planDecisionVersion:e.planDecisionVersion,actionablePlanDecisionVersion:e.actionablePlanDecisionVersion,canonicalPlanPromptVersion:e.canonicalPlanPromptVersion,approvalPromptRequiredVersion:e.approvalPromptRequiredVersion,approvalPromptVersion:e.approvalPromptVersion,approvalPromptStatus:e.approvalPromptStatus,approvalPromptTransport:e.approvalPromptTransport,approvalPromptMessageKind:e.approvalPromptMessageKind,approvalPromptLastAttemptAt:e.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:e.approvalPromptDeliveredAt,approvalPromptFailedAt:e.approvalPromptFailedAt,planApproval:e.planApproval,codexApprovalPolicy:e.codexApprovalPolicy}}getSessionRoutingSnapshot(e){return typeof e.routingSnapshot=="function"?e.routingSnapshot():{route:e.route,originAgentId:e.originAgentId,originChannel:e.originChannel,originThreadId:e.originThreadId,originSessionKey:e.originSessionKey}}getSessionWorktreeSnapshot(e){return typeof e.worktreeSnapshot=="function"?e.worktreeSnapshot():{worktreePath:e.worktreePath,worktreeBranch:e.worktreeBranch,worktreeStrategy:e.worktreeStrategy,worktreeBaseBranch:e.worktreeBaseBranch,worktreePrTargetRepo:e.worktreePrTargetRepo,autoMergeParentSessionId:e.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:e.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:e.autoMergeResolverSessionId,worktreeLifecycle:e.worktreeLifecycle}}indexPersistedEntry(e){let n=this.getEntryStorageKey(e);this.persisted.set(n,e),e.sessionId&&this.idIndex.set(e.sessionId,n),e.name&&this.nameIndex.set(e.name,n);let r=C(e);r&&this.backendIdIndex.set(r,n)}removePersistedIndexes(e){let n=this.getEntryStorageKey(e);this.persisted.delete(n);for(let[r,o]of this.idIndex)o===n&&this.idIndex.delete(r);for(let[r,o]of this.nameIndex)o===n&&this.nameIndex.delete(r);for(let[r,o]of this.backendIdIndex)o===n&&this.backendIdIndex.delete(r)}markRunning(e){if(!e.harnessSessionId)return;let n=this.getSessionApprovalSnapshot(e),r=this.getSessionRoutingSnapshot(e),o=this.getSessionWorktreeSnapshot(e),i=Ne({route:r.route,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey});if(!i)return;let s={sessionId:e.id,harnessSessionId:e.harnessSessionId,backendRef:this.buildPersistedBackendRef(e),name:e.name,prompt:e.prompt,workdir:e.originalWorkdir??e.workdir,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,createdAt:e.startedAt,status:"running",lifecycle:e.lifecycle,approvalState:e.approvalState,worktreeState:e.worktreeState,runtimeState:e.runtimeState,deliveryState:e.deliveryState,notificationDedupe:this.getExistingNotificationDedupe(e),costUsd:0,originAgentId:r.originAgentId,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey,route:i,outputPath:Ue(e.id),harness:e.harnessName,requestedPermissionMode:n.requestedPermissionMode,currentPermissionMode:n.currentPermissionMode,approvalExecutionState:n.approvalExecutionState,approvalRationale:n.approvalRationale,planModeApproved:n.planModeApproved,pendingPlanApproval:n.pendingPlanApproval,planApprovalContext:n.planApprovalContext,planDecisionVersion:n.planDecisionVersion,actionablePlanDecisionVersion:n.actionablePlanDecisionVersion,canonicalPlanPromptVersion:n.canonicalPlanPromptVersion,approvalPromptRequiredVersion:n.approvalPromptRequiredVersion,approvalPromptVersion:n.approvalPromptVersion,approvalPromptStatus:n.approvalPromptStatus,approvalPromptTransport:n.approvalPromptTransport,approvalPromptMessageKind:n.approvalPromptMessageKind,approvalPromptLastAttemptAt:n.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:n.approvalPromptDeliveredAt,approvalPromptFailedAt:n.approvalPromptFailedAt,planApproval:n.planApproval,codexApprovalPolicy:n.codexApprovalPolicy,worktreePath:o.worktreePath,worktreeBranch:o.worktreeBranch,worktreeStrategy:o.worktreeStrategy,worktreeBaseBranch:o.worktreeBaseBranch,worktreePrTargetRepo:o.worktreePrTargetRepo,autoMergeParentSessionId:o.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:o.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:o.autoMergeResolverSessionId,worktreeLifecycle:o.worktreeLifecycle,resumable:e.isExplicitlyResumable};Dr(s),this.indexPersistedEntry(s),this.saveIndex()}hasRecordedSession(e){return this.queries.hasRecordedSession(e)}persistTerminal(e){if(!e.harnessSessionId)return;let n=this.getSessionApprovalSnapshot(e),r=this.getSessionRoutingSnapshot(e),o=this.getSessionWorktreeSnapshot(e),i=Ne({route:r.route,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey});if(!i)return;let s;try{let d=Ue(e.id);if(Wf(d))s=d;else{let l=e.getOutput().join(`
|
|
219
|
+
`);l.length>0&&(Nf(d,l,"utf-8"),s=d)}}catch(d){`${e.id}${Bf(d)}`}let a={sessionId:e.id,harnessSessionId:e.harnessSessionId,backendRef:this.buildPersistedBackendRef(e),name:e.name,prompt:e.prompt,workdir:e.originalWorkdir??e.workdir,model:e.model,reasoningEffort:e.reasoningEffort,fastMode:e.fastMode,createdAt:e.startedAt,completedAt:e.completedAt,status:e.status,lifecycle:e.lifecycle,approvalState:e.approvalState,worktreeState:e.worktreeState,runtimeState:e.runtimeState,deliveryState:e.deliveryState,notificationDedupe:this.getExistingNotificationDedupe(e),killReason:e.killReason,costUsd:e.costUsd,originAgentId:r.originAgentId,originChannel:r.originChannel,originThreadId:r.originThreadId,originSessionKey:r.originSessionKey,route:i,outputPath:s,harness:e.harnessName,goalTaskId:e.goalTaskId,requestedPermissionMode:n.requestedPermissionMode,currentPermissionMode:n.currentPermissionMode,approvalExecutionState:n.approvalExecutionState,approvalRationale:n.approvalRationale,planModeApproved:n.planModeApproved,pendingPlanApproval:n.pendingPlanApproval,planApprovalContext:n.planApprovalContext,planDecisionVersion:n.planDecisionVersion,actionablePlanDecisionVersion:n.actionablePlanDecisionVersion,canonicalPlanPromptVersion:n.canonicalPlanPromptVersion,approvalPromptRequiredVersion:n.approvalPromptRequiredVersion,approvalPromptVersion:n.approvalPromptVersion,approvalPromptStatus:n.approvalPromptStatus,approvalPromptTransport:n.approvalPromptTransport,approvalPromptMessageKind:n.approvalPromptMessageKind,approvalPromptLastAttemptAt:n.approvalPromptLastAttemptAt,approvalPromptDeliveredAt:n.approvalPromptDeliveredAt,approvalPromptFailedAt:n.approvalPromptFailedAt,planApproval:n.planApproval,codexApprovalPolicy:n.codexApprovalPolicy,worktreePath:o.worktreePath,worktreeBranch:o.worktreeBranch,worktreeStrategy:o.worktreeStrategy,worktreeBaseBranch:o.worktreeBaseBranch,worktreePrTargetRepo:o.worktreePrTargetRepo,autoMergeParentSessionId:o.autoMergeParentSessionId,autoMergeConflictResolutionAttemptCount:o.autoMergeConflictResolutionAttemptCount,autoMergeResolverSessionId:o.autoMergeResolverSessionId,worktreeLifecycle:o.worktreeLifecycle,resumable:e.isExplicitlyResumable};Dr(a),this.indexPersistedEntry(a),this.saveIndex()}getExistingNotificationDedupe(e){return this.getPersistedSession(e.id)?.notificationDedupe??(e.harnessSessionId?this.getPersistedSession(e.harnessSessionId)?.notificationDedupe:void 0)??(C(e)?this.getPersistedSession(C(e))?.notificationDedupe:void 0)}getLatestPersistedByName(e){return this.queries.getLatestPersistedByName(e)}resolveBackendConversationId(e,n){return this.queries.resolveBackendConversationId(e,n)}resolveHarnessSessionId(e,n){return this.queries.resolveHarnessSessionId(e,n)}getPersistedSession(e){return this.queries.getPersistedSession(e)}listPersistedSessions(){return this.queries.listPersistedSessions()}cleanupTmpOutputFiles(e){this.actionTokenStore.purgeExpiredActionTokens(e),Kd(e,Ei)}getNextTmpOutputCleanupAt(e){return Ud(e,Ei)}evictOldestPersisted(e){let n=this.listPersistedSessions();if(n.length<=e)return[];let r=n.slice(e);for(let o of r)this.removePersistedIndexes(o);return this.saveIndex(),r}shouldGcActiveSession(e,n,r){return!e.completedAt||!Lf.has(e.status)?!1:n-e.completedAt>r}getActionToken(e){return this.actionTokenStore.getActionToken(e)}consumeActionToken(e){return this.actionTokenStore.consumeActionToken(e)}deleteActionTokensForSession(e){this.actionTokenStore.deleteActionTokensForSession(e)}purgeExpiredActionTokens(e=Date.now()){this.actionTokenStore.purgeExpiredActionTokens(e)}getNextActionTokenExpiry(){return this.actionTokenStore.nextExpiryAt()}onActionTokensChanged(e){this.actionTokenStore.setAfterChangeListener(e)}hasOutputPathReference(e){for(let n of this.persisted.values())if(n.outputPath===e)return!0;return!1}getReferencedOutputPaths(){return[...new Set([...this.persisted.values()].map(e=>e.outputPath).filter(e=>typeof e=="string"&&e.length>0))]}cleanupOrphanOutputFiles(){Vd(this.getReferencedOutputPaths())}};var Ff=new Set(["completed","failed","killed"]),Lr=class{metrics={totalCostUsd:0,costPerDay:new Map,sessionsByStatus:{completed:0,failed:0,killed:0},totalLaunched:0,totalDurationMs:0,sessionsWithDuration:0,mostExpensive:null};incrementLaunched(){this.metrics.totalLaunched++}recordSession(e){let n=e.costUsd??0,r=e.status;this.metrics.totalCostUsd+=n;let o=new Date(e.completedAt??e.startedAt).toISOString().slice(0,10);if(this.metrics.costPerDay.set(o,(this.metrics.costPerDay.get(o)??0)+n),Ff.has(r)&&this.metrics.sessionsByStatus[r]++,e.completedAt){let i=e.completedAt-e.startedAt;this.metrics.totalDurationMs+=i,this.metrics.sessionsWithDuration++}(!this.metrics.mostExpensive||n>this.metrics.mostExpensive.costUsd)&&(this.metrics.mostExpensive={id:e.id,name:e.name,costUsd:n,prompt:re(e.prompt,80)})}getMetrics(){return{totalCostUsd:this.metrics.totalCostUsd,costPerDay:new Map(this.metrics.costPerDay),sessionsByStatus:{...this.metrics.sessionsByStatus},totalLaunched:this.metrics.totalLaunched,totalDurationMs:this.metrics.totalDurationMs,sessionsWithDuration:this.metrics.sessionsWithDuration,mostExpensive:this.metrics.mostExpensive?{...this.metrics.mostExpensive}:null}}};import*as zd from"child_process";var Hd=5e3,qf=64,Kf={primary:"primary",success:"success",positive:"success",danger:"danger",destructive:"danger",negative:"danger"},Uf={execFile:zd.execFile},We=class extends Error{constructor(e){super(e),this.name="MissingRuntimeDirectNotificationCapabilityError"}},Br=class{constructor(e=Uf.execFile){this.execFile=e}execFile;async send(e,n,r){D("direct_send_started",{...ye(e),messageTextLength:n.length,...H(r)});try{await this.sendViaRuntime(e,n,r),D("direct_send_succeeded",{...ye(e),deliveryPath:"runtime",...H(r)});return}catch(o){if(!(o instanceof We))throw D("direct_send_failed",{...ye(e),deliveryPath:"runtime",...H(r),error:$i(o)}),o;D("direct_send_runtime_capability_missing",{...ye(e),deliveryPath:"runtime",...H(r),reason:o.message}),await this.sendViaBoundedCliFallback(e,n,r,o.message),D("direct_send_succeeded",{...ye(e),deliveryPath:"cli-fallback",...H(r)})}}async sendViaRuntime(e,n,r){let o=In(),i=Ms(),s=o?.channel?.outbound?.loadAdapter;if(!o)throw new We("OpenClaw plugin runtime is unavailable for direct notification delivery");if(i==null)throw new We("OpenClaw runtime config snapshot is unavailable for direct notification delivery");if(!o.channel)throw new We(`OpenClaw plugin runtime channel surface is unavailable for direct notification delivery (runtimeVersion=${Di(o)})`);if(!o.channel.outbound)throw new We(`OpenClaw plugin runtime channel outbound surface is unavailable for direct notification delivery (runtimeVersion=${Di(o)})`);if(!s)throw new We(`OpenClaw plugin runtime channel outbound loadAdapter is unavailable for direct notification delivery (runtimeVersion=${Di(o)})`);let a=await s(e.channel);if(!a)throw new Error(`OpenClaw outbound adapter for channel "${e.channel}" is unavailable`);let d=Fr(r);if(D("runtime_adapter_loaded",{...ye(e),adapterHasRenderPresentation:typeof a.renderPresentation=="function",adapterHasSendPayload:typeof a.sendPayload=="function",adapterHasSendText:typeof a.sendText=="function",...H(r),...d?li(d):{}}),d){await this.sendPresentation(a,i,e,n,d);return}if(!a.sendText)throw new Error(`OpenClaw outbound adapter for channel "${e.channel}" cannot send text`);await a.sendText({cfg:i,to:e.target,text:n,accountId:e.accountId,threadId:e.threadId})}async sendPresentation(e,n,r,o,i){let s=Gf(i),a={text:o,presentation:i,interactive:s};D("presentation_render_started",{...ye(r),messageTextLength:o.length,adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...li(i)});let d={cfg:n,to:r.target,text:o,payload:a,accountId:r.accountId,threadId:r.threadId},l=e.renderPresentation?await e.renderPresentation({payload:a,presentation:i,ctx:d}):a,u=jf(l,s,r.channel);if(D("presentation_render_completed",{...ye(r),adapterHasRenderPresentation:typeof e.renderPresentation=="function",adapterHasSendPayload:typeof e.sendPayload=="function",...ui(u)}),!u||typeof u!="object"||!e.sendPayload)throw new Error(`OpenClaw outbound adapter for channel "${r.channel}" cannot preserve interactive presentation`);let c=await e.sendPayload({...d,payload:u});D("presentation_send_payload_completed",{...ye(r),...ui(u),...Na(c)})}sendViaBoundedCliFallback(e,n,r,o){return new Promise((i,s)=>{let a=Vf(e,n,r);D("direct_send_cli_fallback_started",{...ye(e),deliveryPath:"cli-fallback",reason:o,messageTextLength:n.length,...H(r)}),this.execFile("openclaw",a,{timeout:Hd,killSignal:"SIGKILL"},(d,l,u)=>{if(!d){D("direct_send_cli_fallback_completed",{...ye(e),deliveryPath:"cli-fallback",...H(r)}),i();return}let c=u?.trim()?` | stderr: ${u.trim()}`:"";D("direct_send_cli_fallback_failed",{...ye(e),deliveryPath:"cli-fallback",...H(r),error:$i(d),stderrLength:u?.length}),s(new Error(`${o}; bounded openclaw message send fallback failed within ${Hd}ms timeout: ${$i(d)}${c}`))})})}};function ye(t){return{channel:t.channel,target:t.target,accountId:t.accountId,threadId:t.threadId,sessionKey:t.sessionKey}}function Vf(t,e,n){let r=Fr(n),o=["message","send","--channel",t.channel,"--target",t.target,"--message",e];return t.accountId&&o.push("--account",t.accountId),t.threadId&&o.push("--thread-id",t.threadId),r&&o.push("--presentation",JSON.stringify(r)),o}function $i(t){return t instanceof Error?t.message:String(t)}function Di(t){if(!t||typeof t!="object")return"unknown";let e=t.version;return typeof e=="string"&&e.trim()?e:"unknown"}function Fr(t){let e=(t??[]).filter(n=>Array.isArray(n)&&n.length>0).map(n=>({type:"buttons",buttons:n.map(r=>({label:r.label,value:Zf(r.callbackData),...r.style?{style:r.style}:{}}))}));return e.length>0?{blocks:e}:void 0}function Gf(t){let e=t.blocks.filter(n=>n.type==="buttons"&&n.buttons.length>0).map(n=>({type:"buttons",buttons:n.buttons.map(r=>({label:r.label,value:r.value,...r.style?{style:r.style}:{}}))}));return e.length>0?{blocks:e}:void 0}function Hf(t){if(!t||typeof t!="object"||Array.isArray(t))return!1;let e=t.interactive;if(!e||typeof e!="object"||Array.isArray(e))return!1;let n=e.blocks;return Array.isArray(n)&&n.some(r=>{if(!r||typeof r!="object"||Array.isArray(r))return!1;let o=r;return o.type==="buttons"&&Array.isArray(o.buttons)&&o.buttons.length>0})}function jf(t,e,n){if(!e)return t;let r=Hf(t)?t:zf(t,e);return n!=="telegram"?r:Qf(r,e)}function zf(t,e){return!t||typeof t!="object"||Array.isArray(t)?t:{...t,interactive:e}}function Qf(t,e){if(!t||typeof t!="object"||Array.isArray(t))return t;let n=t,r=jd(n.channelData),o=jd(r?.telegram),i=Yf(o?.buttons);if(i)return{...n,channelData:{...r??{},telegram:{...o??{},buttons:i}}};let s=Jf(e);return s?{...n,channelData:{...r??{},telegram:{...o??{},buttons:s}}}:t}function Jf(t){let e=t.blocks.filter(n=>n.type==="buttons"&&n.buttons.length>0).map(n=>n.buttons.filter(r=>typeof r.value=="string"&&r.value.trim().length>0&&Buffer.byteLength(r.value,"utf8")<=qf).map(r=>({text:r.label,callback_data:r.value,...Qd(r.style)}))).filter(n=>n.length>0);return e.length>0?e:void 0}function Yf(t){if(!Array.isArray(t))return;let e=t.map(n=>Array.isArray(n)?n.map(r=>{if(!r||typeof r!="object"||Array.isArray(r))return;let{style:o,...i}=r;if(!(typeof i.text!="string"||i.text.trim().length===0))return{...i,...Qd(o)}}).filter(r=>!!r):[]).filter(n=>n.length>0);return e.length>0?e:void 0}function Qd(t){if(typeof t!="string")return{};let e=t.trim().toLowerCase(),n=Kf[e];return n?{style:n}:{}}function jd(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function Zf(t){return t.startsWith(`${fe}:`)?t:`${fe}:${t}`}import*as Jd from"child_process";var vt=class{tails=new Map;enqueue(e,n,r){let o=this.tails.get(e);o!==void 0&&r?.();let s=(o?.catch(()=>{})??Promise.resolve()).then(()=>n()),a=s.catch(()=>{});return this.tails.set(e,a),a.finally(()=>{this.tails.get(e)===a&&this.tails.delete(e)}),s}clear(){this.tails.clear()}};var Oi=3e4,Xf=2e3,eg=2e4,pe=4;function Xt(t){return t instanceof Error?t.message:String(t)}function tg(){return new Error(`Dispatch timed out after ${Oi}ms`)}function ng(t){if(!(t instanceof Error))return!1;let e=t;return e.killed===!0&&e.signal==="SIGKILL"}var rg={execFile:Jd.execFile},qr=class{pendingRetryTimers=new Map;orderedDispatches=new vt;disposed=!1;clearPendingRetries(){for(let e of this.pendingRetryTimers.values())for(let n of e)clearTimeout(n.timer),n.onCleared?.();this.pendingRetryTimers.clear()}clearRetryTimersForSession(e){let n=this.pendingRetryTimers.get(e);if(n){for(let r of n)clearTimeout(r.timer),r.onCleared?.();this.pendingRetryTimers.delete(e)}}dispose(){this.disposed=!0,this.clearPendingRetries(),this.orderedDispatches.clear()}execute(e,n,r=1){if(!this.disposed){if(r===1&&n.orderingKey){this.enqueueOrderedDispatch(n.orderingKey,o=>this.executeNow(e,n,o,r));return}this.executeNow(e,n,void 0,r)}}executePromise(e,n,r=1){if(!this.disposed){if(r===1&&n.orderingKey){this.enqueueOrderedDispatch(n.orderingKey,o=>this.executePromiseNow(e,n,o,r));return}this.executePromiseNow(e,n,void 0,r)}}executeNow(e,n,r,o=1){if(this.disposed||n.shouldContinue?.()===!1){r?.();return}let i=Date.now();o===1&&n.onStarted?.(),this.log("info","dispatch_started",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:o,maxAttempts:pe}),rg.execFile("openclaw",e,{timeout:Oi,killSignal:"SIGKILL"},(s,a,d)=>{if(this.disposed){r?.();return}let l=Date.now()-i;if(!s){let g=n.successValidator?.(a??"");if(g?.outcome==="failure"){this.log("error","dispatch_success_validation_failed",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:o,maxAttempts:pe,elapsedMs:l,error:g.reason,terminal:!0}),n.onFinalFailure?.(),r?.();return}if(g?.outcome==="skipped"){this.log("info","dispatch_skipped",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:o,maxAttempts:pe,elapsedMs:l,reason:g.reason}),n.shouldContinue?.()!==!1&&n.onSkipped?.(g.reason),r?.();return}this.log("info","dispatch_succeeded",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:o,maxAttempts:pe,elapsedMs:l}),n.shouldContinue?.()!==!1&&n.onSuccess?.(),r?.();return}let u=d?.trim()?` | stderr: ${d.trim()}`:"";if(n.target==="message.send"&&ng(s)){this.log("error","dispatch_failed",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:o,maxAttempts:pe,elapsedMs:l,error:`${Xt(s)}${u}`,terminal:!0,ambiguousResult:!0}),n.onAmbiguousResult?.(),r?.();return}if(o>=pe||n.terminalOnFailure===!0){this.log("error","dispatch_failed",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:o,maxAttempts:pe,elapsedMs:l,error:`${Xt(s)}${u}`,terminal:!0}),n.onFinalFailure?.(),r?.();return}let p=this.retryDelayMs(o);this.log("error","dispatch_retry_scheduled",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:o,maxAttempts:pe,elapsedMs:l,retryDelayMs:p,error:`${Xt(s)}${u}`});let f={timer:setTimeout(()=>{let g=this.pendingRetryTimers.get(n.sessionId);if(g&&(g.delete(f),g.size===0&&this.pendingRetryTimers.delete(n.sessionId)),n.shouldContinue?.()===!1){r?.();return}this.executeNow(e,n,r,o+1)},p),onCleared:r};f.timer.unref?.(),this.pendingRetryTimers.has(n.sessionId)||this.pendingRetryTimers.set(n.sessionId,new Set),this.pendingRetryTimers.get(n.sessionId).add(f)})}executePromiseNow(e,n,r,o=1){if(this.disposed||n.shouldContinue?.()===!1){r?.();return}let i=Date.now();o===1&&n.onStarted?.(),this.log("info","dispatch_started",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:o,maxAttempts:pe}),this.executePromiseWithTimeout(e).then(()=>{if(this.disposed){r?.();return}let s=Date.now()-i;this.log("info","dispatch_succeeded",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:o,maxAttempts:pe,elapsedMs:s}),n.shouldContinue?.()!==!1&&n.onSuccess?.(),r?.()}).catch(s=>{if(this.disposed){r?.();return}let a=Date.now()-i;if(o>=pe||n.terminalOnFailure===!0){this.log("error","dispatch_failed",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:o,maxAttempts:pe,elapsedMs:a,error:Xt(s),terminal:!0,...n.terminalOnFailure===!0&&o<pe?{terminalReason:"non_retryable"}:{}}),n.onFinalFailure?.(),r?.();return}let d=this.retryDelayMs(o);this.log("error","dispatch_retry_scheduled",{label:n.label,sessionId:n.sessionId,target:n.target,phase:n.phase,messageKind:n.messageKind,route:n.routeSummary,...n.dispatchContext,attempt:o,maxAttempts:pe,elapsedMs:a,retryDelayMs:d,error:Xt(s)});let l={timer:setTimeout(()=>{let u=this.pendingRetryTimers.get(n.sessionId);if(u&&(u.delete(l),u.size===0&&this.pendingRetryTimers.delete(n.sessionId)),n.shouldContinue?.()===!1){r?.();return}this.executePromiseNow(e,n,r,o+1)},d),onCleared:r};l.timer.unref?.(),this.pendingRetryTimers.has(n.sessionId)||this.pendingRetryTimers.set(n.sessionId,new Set),this.pendingRetryTimers.get(n.sessionId).add(l)})}executePromiseWithTimeout(e){return new Promise((n,r)=>{let o=!1,i=setTimeout(()=>{o||(o=!0,r(tg()))},Oi);i.unref?.(),Promise.resolve().then(e).then(()=>{o||(o=!0,clearTimeout(i),n())}).catch(s=>{o||(o=!0,clearTimeout(i),r(s))})})}retryDelayMs(e){let n=Math.max(0,e-1),r=Xf*2**n;return Math.min(r,eg)}enqueueOrderedDispatch(e,n){this.orderedDispatches.enqueue(e,async()=>{this.disposed||await new Promise(r=>{let o=!1;n(()=>{o||(o=!0,r())})})})}log(e,n,r){let o=`[WakeDispatcher] ${JSON.stringify({event:n,...r})}`;if(e==="error"){console.error(o);return}}};ve();var Kr=class{resolve(e){let n=Re(e);if(!(!n?.provider||!n.target))return{channel:n.provider,target:n.target,accountId:n.accountId,threadId:n.threadId,sessionKey:n.sessionKey}}summary(e){if(!e)return"system";let n=e.accountId?`|${e.accountId}`:"",r=e.threadId?`#${e.threadId}`:"";return`${e.channel}${n}|${e.target}${r}`}};import{randomUUID as og}from"crypto";var Ur=class{constructor(e={}){this.options=e}options;buildChatSendArgs(e,n,r,o=og()){return["gateway","call","chat.send","--expect-final","--timeout","30000","--params",JSON.stringify({sessionKey:e,message:n,deliver:r,idempotencyKey:o})]}buildDirectNotificationArgs(e,n,r){let o=Fr(r),i=["message","send","--channel",e.channel,"--target",e.target,"--message",n];return e.accountId&&i.push("--account",e.accountId),e.threadId&&i.push("--thread-id",e.threadId),o&&i.push("--presentation",JSON.stringify(o)),i}buildSystemEventArgs(e){return["system","event","--text",e,"--mode","now"]}};function ig(t){let e=sg(t).trim();return e?/^NO_REPLY$/i.test(e)?{outcome:"failure",reason:"completion follow-up wake ended with NO_REPLY"}:{outcome:"success"}:{outcome:"failure",reason:"completion follow-up wake produced no final response"}}function sg(t){let e=t.trim();if(!e)return"";try{return Wi(JSON.parse(e)).trim()}catch{return e}}function Wi(t){if(typeof t=="string")return t;if(Array.isArray(t))return t.map(r=>Wi(r)).filter(Boolean).join(`
|
|
220
|
+
`);if(!t||typeof t!="object")return"";let e=t,n=["final","finalResponse","final_response","assistantFinal","assistant_final","response","text","content"];for(let r of n){let o=e[r];if(typeof o=="string"&&o.trim())return o}for(let r of["result","message","data"]){let o=Wi(e[r]);if(o.trim())return o}return""}var Vr=class{routes=new Kr;transport;directNotifications;executor=new qr;constructor(e={}){this.transport=e.transport??new Ur(e.transportOptions),this.directNotifications=e.directNotifications===void 0?new Br:e.directNotifications}clearPendingRetries(){this.executor.clearPendingRetries()}clearRetryTimersForSession(e){this.executor.clearRetryTimersForSession(e)}dispose(){this.executor.dispose()}buildDispatchContext(e){let n=e.buttons??[],r=n.flat();return{transportRoute:e.routeSummary,transportChannel:e.route?.channel??"system",transportTarget:e.route?.target??"system",transportAccountId:e.route?.accountId,transportThreadId:e.route?.threadId,transportSessionKey:e.route?.sessionKey,messageTextLength:e.text.length,buttonsPresent:r.length>0,buttonRows:n.length||void 0,buttonCount:r.length||void 0,buttonLabels:r.length>0?r.map(o=>o.label):void 0,maxCallbackDataLength:r.length>0?Math.max(...r.map(o=>o.callbackData.length)):void 0}}sendWake(e,n,r,o,i,s,a,d,l,u){let c=this.routes.resolve(e),p=a;if(p?.()===!1)return;let f=c?.sessionKey?.trim();if(!f){this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-system`,sessionId:e.id,target:"system.event",phase:o,routeSummary:"system",messageKind:"wake",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n}),onSuccess:s,onSkipped:l,onFinalFailure:i,successValidator:d,shouldContinue:p});return}this.executor.execute(this.transport.buildChatSendArgs(f,n,!0,u),{label:r,sessionId:e.id,target:"chat.send",phase:o,routeSummary:`session:${f}`,messageKind:"wake",dispatchContext:this.buildDispatchContext({routeSummary:`session:${f}`,route:c,text:n}),onSuccess:s,onSkipped:l,successValidator:d,shouldContinue:p,onFinalFailure:()=>{p?.()!==!1&&this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-fallback`,sessionId:e.id,target:"system.event",phase:o,routeSummary:"system",messageKind:"wake",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n}),onSuccess:s,onSkipped:l,onFinalFailure:i,successValidator:d,shouldContinue:p})}})}sendUserNotification(e,n,r,o,i,s,a=!1,d){if(d?.()===!1)return;let l=!!o?.some(g=>Array.isArray(g)&&g.length>0),u=this.routes.resolve(e);D("wake_notify_selected",{sessionId:e.id,sessionName:e.name,label:r,messageTextLength:n.length,requireDirectDelivery:a,hasDirectNotificationTransport:!!this.directNotifications,routeSummary:u?this.routes.summary(u):"system",channel:u?.channel,target:u?.target,accountId:u?.accountId,threadId:u?.threadId,sessionKey:u?.sessionKey,...H(o)});let c=u?`notify:${u.channel}|${u.accountId??""}|${u.target}|${u.threadId??""}`:`notify:system:${e.id}`;if(!u){if(D("wake_notify_no_direct_route",{sessionId:e.id,sessionName:e.name,label:r,requireDirectDelivery:a,hasInteractiveButtons:l,...H(o)}),a){`${r}${e.id}`,i?.();return}if(l){`${r}${e.id}`,i?.();return}this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-notify-system`,sessionId:e.id,target:"system.event",phase:"notify",routeSummary:"system",messageKind:"notify",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n,buttons:o}),orderingKey:c,onSuccess:s,onFinalFailure:i,shouldContinue:d});return}let p=()=>{if(D("wake_notify_direct_failed",{sessionId:e.id,sessionName:e.name,label:r,requireDirectDelivery:a,hasInteractiveButtons:l,channel:u.channel,target:u.target,accountId:u.accountId,threadId:u.threadId,sessionKey:u.sessionKey,...H(o)}),a){`${r}${e.id}`,i?.();return}if(l){`${r}${e.id}`,i?.();return}this.executor.execute(this.transport.buildSystemEventArgs(n),{label:`${r}-notify-fallback`,sessionId:e.id,target:"system.event",phase:"notify",routeSummary:"system",messageKind:"notify",dispatchContext:this.buildDispatchContext({routeSummary:"system",text:n}),orderingKey:c,onSuccess:s,onFinalFailure:i,shouldContinue:d})},f={label:`${r}-notify`,sessionId:e.id,target:"message.send",phase:"notify",routeSummary:this.routes.summary(u),messageKind:"notify",dispatchContext:this.buildDispatchContext({routeSummary:this.routes.summary(u),route:u,text:n,buttons:o}),orderingKey:c,onSuccess:s,onAmbiguousResult:p,onFinalFailure:p,terminalOnFailure:this.directNotifications?!0:void 0,shouldContinue:d};if(this.directNotifications){D("wake_notify_dispatching_direct_runtime",{sessionId:e.id,sessionName:e.name,label:r,channel:u.channel,target:u.target,accountId:u.accountId,threadId:u.threadId,sessionKey:u.sessionKey,...H(o)}),this.executor.executePromise(()=>this.directNotifications.send(u,n,o),f);return}D("wake_notify_dispatching_cli_message_send",{sessionId:e.id,sessionName:e.name,label:r,channel:u.channel,target:u.target,accountId:u.accountId,threadId:u.threadId,sessionKey:u.sessionKey,...H(o)}),this.executor.execute(this.transport.buildDirectNotificationArgs(u,n,o),f)}sendUserNotificationSequence(e,n,r,o,i,s=!1,a){let d=n.map(u=>({text:u.text.trim(),buttons:u.buttons})).filter(u=>u.text.length>0);if(d.length===0){o?.();return}D("wake_notify_sequence_started",{sessionId:e.id,sessionName:e.name,label:r,chunkCount:d.length,buttonChunkIndexes:d.map((u,c)=>u.buttons?.some(p=>Array.isArray(p)&&p.length>0)?c+1:void 0).filter(u=>typeof u=="number"),requireDirectDelivery:s});let l=u=>{if(a?.()===!1)return;let c=d[u];if(!c){D("wake_notify_sequence_succeeded",{sessionId:e.id,sessionName:e.name,label:r,chunkCount:d.length}),i?.();return}let p=u===0?o:i;D("wake_notify_sequence_chunk_selected",{sessionId:e.id,sessionName:e.name,label:r,chunkIndex:u+1,chunkCount:d.length,messageTextLength:c.text.length,failureHandler:u===0?"all-failed":"sequence-success",...H(c.buttons)}),this.sendUserNotification(e,c.text,`${r}-part-${u+1}`,c.buttons,p,()=>l(u+1),s,a)};l(0)}dispatchSessionNotification(e,n){let r=n.hooks,o=n.wakeMessageOnNotifySuccess!=null||n.wakeMessageOnNotifyFailed!=null,i=n.notifyUser??(n.wakeMessage?"on-wake-fallback":"always"),s=(n.userMessages?.length?n.userMessages:n.userMessage?.trim()?[{text:n.userMessage.trim(),buttons:n.buttons}]:[]).map(c=>({text:c.text.trim(),buttons:c.buttons})).filter(c=>c.text.length>0),a=s[0]?.text,d=n.wakeMessage?.trim(),l=n.shouldDispatch,u=n.completionWakeSummaryRequired===!0?ig:void 0;if(o){let c=n.wakeMessageOnNotifySuccess?.trim(),p=n.wakeMessageOnNotifyFailed?.trim(),f=k=>{k&&l?.()!==!1&&(r?.onWakeStarted?.(),this.sendWake(e,k,`${n.label}-wake`,"wake",r?.onWakeFailed,r?.onWakeSucceeded,l,u,r?.onWakeSkipped,n.idempotencyKey))},g=k=>{if(k){if(n.deferConditionalWakeUntilNextTick===!0||n.deferConditionalWakeMs!==void 0){let R=Math.max(0,Math.floor(n.deferConditionalWakeMs??0));setTimeout(()=>f(k),R).unref?.();return}f(k)}},h=()=>{l?.()!==!1&&(r?.onNotifySucceeded?.(),c&&g(c))},y=p?()=>{l?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.(),g(p))}:()=>{l?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())};if(s.length>0){if(l?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,y,h,n.requireDirectUserNotification===!0,l)}else y();return}if(i==="always"&&s.length>0){if(l?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,()=>{l?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())},()=>{l?.()!==!1&&r?.onNotifySucceeded?.()},n.requireDirectUserNotification===!0,l)}if(d&&l?.()!==!1){if(r?.onWakeStarted?.(),i==="on-wake-fallback"&&s.length>0&&!this.routes.resolve(e)?.sessionKey){if(l?.()===!1)return;r?.onNotifyStarted?.(),this.sendUserNotificationSequence(e,s,n.label,()=>{l?.()!==!1&&(r?.onNotifyFailed?.(),n.onUserNotifyFailed?.())},()=>{l?.()!==!1&&r?.onNotifySucceeded?.()},!1,l)}this.sendWake(e,d,`${n.label}-wake`,"wake",r?.onWakeFailed,r?.onWakeSucceeded,l,u,r?.onWakeSkipped,n.idempotencyKey)}}};var Gr=class{constructor(e,n){this.actionTokens=e;this.isGitHubCliAvailable=n}actionTokens;isGitHubCliAvailable;createActionToken(e,n,r={}){return this.actionTokens.createActionToken(e,n,{expiresAt:Date.now()+10080*60*1e3,...r})}consumeActionToken(e){return this.actionTokens.consumeActionToken(e)}getActionToken(e){return this.actionTokens.getActionToken(e)}clearPlanDecisionTokens(e,n){this.actionTokens.deletePlanDecisionTokensForSession(e,n)}makeActionButton(e,n,r,o={}){let i=this.createActionToken(e,n,{label:r,...o});return{label:r,callbackData:i.id,style:this.resolveButtonStyle(n)}}resolveButtonStyle(e){switch(e){case"plan-approve":case"worktree-create-pr":case"worktree-update-pr":case"plan-offer-start":return"primary";case"worktree-merge":case"session-resume":case"session-restart":return"success";case"plan-reject":case"worktree-dismiss":return"danger";default:return"secondary"}}getWorktreeDecisionButtons(e,n){if(!n)return[];let r=[],o=[this.makeActionButton(e,"worktree-merge","Merge")];if(this.isGitHubCliAvailable())n.worktreePrUrl?(o.push(this.makeActionButton(e,"worktree-view-pr","View PR",{targetUrl:n.worktreePrUrl})),r.push(o),r.push([this.makeActionButton(e,"worktree-update-pr","Sync PR"),this.makeActionButton(e,"worktree-decide-later","Later")])):(o.push(this.makeActionButton(e,"worktree-create-pr","Open PR")),r.push(o),r.push([this.makeActionButton(e,"worktree-decide-later","Later"),this.makeActionButton(e,"worktree-dismiss","Discard")]));else return r.push([...o,this.makeActionButton(e,"worktree-decide-later","Later")]),r.push([this.makeActionButton(e,"worktree-dismiss","Discard")]),r;return n.worktreePrUrl&&r.push([this.makeActionButton(e,"worktree-dismiss","Discard")]),r}getPlanApprovalButtons(e,n){let r=[[this.makeActionButton(e,"plan-approve","Approve",{planDecisionVersion:n?.planDecisionVersion}),this.makeActionButton(e,"plan-request-changes","Revise",{planDecisionVersion:n?.planDecisionVersion}),this.makeActionButton(e,"plan-reject","Reject",{planDecisionVersion:n?.planDecisionVersion})]];return D("plan_approval_buttons_created",{sessionId:e,planDecisionVersion:n?.planDecisionVersion,...H(r)}),r}getResumeButtons(e,n){let r=[];return n.isExplicitlyResumable&&r.push(this.makeActionButton(e,"session-resume","Resume")),r.push(this.makeActionButton(e,"view-output","View output")),[r]}getQuestionButtons(e,n){if(n.length!==0)return[n.map((r,o)=>this.makeActionButton(e,"question-answer",r.label,{optionIndex:o}))]}getPlanOfferButtons(e){let{offerId:n,route:r,planName:o,planPrompt:i,planWorkdir:s,planWorktreeStrategy:a}=e,d=[[this.makeActionButton(n,"plan-offer-start","Start Plan",{route:r,launchName:o,launchPrompt:i,launchWorkdir:s,launchWorktreeStrategy:a}),this.makeActionButton(n,"plan-offer-dismiss","Dismiss",{route:r})]];return D("plan_offer_buttons_created",{offerId:n,planName:o,channel:r.provider,target:r.target,accountId:r.accountId,threadId:r.threadId,sessionKey:r.sessionKey,planPromptLength:i.length,planWorkdirLength:s.length,planWorktreeStrategy:a,...H(d)}),d}};Q();ve();import{createHash as ug}from"crypto";var ag="duplicate notification already delivered or in flight",Hr=class{maxRecords;inFlightTtlMs;now;inFlight=new Set;delivered=new Set;constructor(e={}){this.maxRecords=Math.max(1,Math.floor(e.maxRecords??64)),this.inFlightTtlMs=Math.max(1,Math.floor(e.inFlightTtlMs??6e5)),this.now=e.now??(()=>new Date)}claim(e,n,r){if(!e)return{allowed:!0};let o=this.now(),i=this.prune(n??[],o),s=i.find(a=>a.key===e);return this.delivered.has(e)||this.inFlight.has(e)||s?.status==="delivered"||s?.status==="in_flight"&&this.isFreshInFlight(s,o)?{allowed:!1,records:i,reason:ag}:(this.inFlight.add(e),this.delivered.delete(e),{allowed:!0,records:this.upsert(i,{key:e,status:"in_flight",recordedAt:o.toISOString(),label:r})})}deliveredRecords(e,n,r){if(!e)return;let o=this.now();return this.inFlight.delete(e),this.delivered.add(e),this.upsert(this.prune(n??[],o),{key:e,status:"delivered",recordedAt:o.toISOString(),label:r})}releasedRecords(e,n){if(!e)return;let r=this.now();return this.inFlight.delete(e),this.prune(n??[],r).filter(o=>!(o.key===e&&o.status==="in_flight"))}prune(e,n){let r=e.filter(o=>o.status==="delivered"?!0:this.isFreshInFlight(o,n));return r.slice(Math.max(0,r.length-this.maxRecords))}isFreshInFlight(e,n){let r=Date.parse(e.recordedAt);return Number.isFinite(r)?n.getTime()-r<this.inFlightTtlMs:!1}upsert(e,n){let o=[...e.filter(i=>i.key!==n.key),n];return o.slice(Math.max(0,o.length-this.maxRecords))}};ve();Q();ve();import{createHash as dg}from"crypto";var lg=1024,en="duplicate completion follow-up wake already handled",jr="prior human-visible summary already delivered",zr=class{inFlight=new Set;completed=new Map;claimKeysByPrimary=new Map;maxCompletedKeys;constructor(e={}){this.maxCompletedKeys=Math.max(1,Math.floor(e.maxCompletedKeys??lg))}decide(e,n,r){if(n?.required!==!0)return{required:!1,allowed:!1,explicit:!1};let o=this.buildKeySet(e,n);if(!o)return{required:!0,allowed:!0,explicit:!1};let i=this.normalizeRecords(r),s=new Map(i.map(u=>[u.key,u])),a=o.decisionKeys.find(u=>this.inFlight.has(u)||this.completed.has(u)||s.has(u)),d=a?this.completed.get(a):void 0,l=a?s.get(a):void 0;return a?{required:!0,allowed:!1,explicit:o.explicit,dedupeKey:o.primary,skipReason:d?.skipReason??l?.skipReason??en}:(this.registerClaim(o.primary,o.claimKeys),{required:!0,allowed:!0,key:o.primary,explicit:o.explicit})}recordVisibleDelivery(e,n,r,o){if(n.required!==!0)return{required:!1,allowed:!1,explicit:!1};let i=this.buildKeySet(e,n);if(!i)return{required:!0,allowed:!0,explicit:!1};let s=this.normalizeRecords(r),a=new Map(s.map(p=>[p.key,p])),d=i.decisionKeys.find(p=>this.completed.has(p)||a.has(p)),l=d?this.completed.get(d):void 0,u=d?a.get(d):void 0;if(l||u)return{required:!0,allowed:!1,explicit:i.explicit,dedupeKey:i.primary,skipReason:l?.skipReason??u?.skipReason};this.finishKeys(i.primary,i.claimKeys,!0,jr);let c=this.deliveredRecords(i.claimKeys,s,o,jr);return{required:!0,allowed:!0,key:i.primary,explicit:i.explicit,records:c}}finish(e,n,r=en){if(!e)return;let o=this.claimKeysByPrimary.get(e)??[e];this.finishKeys(e,o,n,r)}completionRecordsAfterDelivery(e,n,r,o=en){if(!e)return;let i=this.claimKeysByPrimary.get(e)??[e];return this.deliveredRecords(i,n,r,o)}registerClaim(e,n){for(let r of n)this.inFlight.add(r);for(this.claimKeysByPrimary.delete(e),this.claimKeysByPrimary.set(e,n);this.claimKeysByPrimary.size>this.maxCompletedKeys;){let r=this.claimKeysByPrimary.keys().next().value;if(r===void 0)break;let o=this.claimKeysByPrimary.get(r)??[r];for(let i of o)this.inFlight.delete(i);this.claimKeysByPrimary.delete(r)}}finishKeys(e,n,r,o=en){for(let i of n)this.inFlight.delete(i);if(this.claimKeysByPrimary.delete(e),!!r){for(let i of n)this.completed.get(i)?.skipReason===jr&&o!==jr||(this.completed.delete(i),this.completed.set(i,{skipReason:o}));for(;this.completed.size>this.maxCompletedKeys;){let i=this.completed.keys().next().value;if(i===void 0)break;this.completed.delete(i)}}}buildKeySet(e,n){let r=this.getDeliveryRef(e);if(!r)return;let o=this.normalizeOutcomeKey(e,n.outcomeKey?.trim());if(o){let a=`${this.buildVisibleScope(r,e)}:outcome:${this.digest(o)}`,d=this.isGoalLike(e,n,o),l=this.buildSessionAliasKeys(r,e,"visible-summary"),u=this.buildSessionAliasKeys(r,e,"goal-summary"),c=this.isTerminalLike(n,o);return{primary:a,explicit:!0,claimKeys:[a,...l,...d?u:[]],decisionKeys:[a,...d||c?l:[],...u]}}let i=n.fallbackFingerprint?.trim();if(!i)return;let s=`${r}:${n.producer}:${this.digest(i)}`;return{primary:s,explicit:!1,claimKeys:[s],decisionKeys:[s]}}isGoalLike(e,n,r){return!!e.goalTaskId?.trim()||n.producer==="goal"||/^goal:/i.test(r)}isTerminalLike(e,n){return e.producer==="terminal"||/^terminal:/i.test(n)}normalizeOutcomeKey(e,n){let r=e.goalTaskId?.trim();if(r)return`goal:${r}`;let o=this.normalizeWorktreePrOutcomeKey(n);return o||n}normalizeWorktreePrOutcomeKey(e){if(!e)return;let n=e.split(":");if(n[0]!=="worktree-pr"||n.length<5)return;let r=n[1]?.trim().toLowerCase();if(!r||!/^(?:draft-)?(?:opened|updated)$/.test(r))return;let o=n[2]?.trim()||"default-repo",i=n[3]?.trim();if(!i)return;let s=this.normalizePrIdentity(i),a=n[4]?.trim();if(!(!s||!a))return["worktree-pr",o.toLowerCase(),s,a].join(":")}normalizePrIdentity(e){let n=e.match(/#?(\d+)$/);if(n?.[1])return`#${n[1]}`;let r=e.match(/\/pull\/(\d+)(?:\b|\/|$)/);if(r?.[1])return`#${r[1]}`;let o=e.trim();return o||void 0}buildVisibleScope(e,n){let r=Re(n);return r?`route:${this.digest(JSON.stringify({provider:r.provider,accountId:r.accountId,target:r.target,threadId:r.threadId}))}`:e}buildSessionAliasKeys(e,n,r){let o=this.buildVisibleScope(e,n),i=["id"in n?n.id:void 0,"sessionId"in n?n.sessionId:void 0,n.name,C(n),n.harnessSessionId,e].map(s=>s?.trim()).filter(s=>!!s);return[...new Set(i)].map(s=>`${o}:session:${this.digest(s)}:${r}`)}getDeliveryRef(e){return W(e)??C(e)??""}digest(e){return dg("sha256").update(e).digest("hex").slice(0,16)}normalizeRecords(e){return e?.length?e.filter(n=>n.key.trim()&&Number.isFinite(Date.parse(n.recordedAt))).slice(-this.maxCompletedKeys):[]}deliveredRecords(e,n,r,o=en){let i=new Date().toISOString(),d=[...this.normalizeRecords(n).filter(l=>!e.includes(l.key)),...e.map(l=>({key:l,recordedAt:i,label:r,skipReason:o}))];return d.slice(Math.max(0,d.length-this.maxCompletedKeys))}};var cg=2e3,pg=new Set(["1","true","yes","on"]);function mg(){let t=process.env.OPENCLAW_CODE_AGENT_NOTIFICATION_DIAGNOSTICS?.trim().toLowerCase();return!!(t&&pg.has(t))||di()}function fg(t){mg()&&process.stderr.write(`[SessionNotification] ${JSON.stringify(t)}
|
|
221
|
+
`)}var Qr=class{constructor(e,n,r={}){this.wakeDispatcher=e;this.applyPersistedPatch=n;this.completionSummaries=new zr({maxCompletedKeys:r.maxCompletedCompletionWakeKeys}),this.notificationDedupe=new Hr({maxRecords:r.maxNotificationDedupeRecords}),this.getPersistedSession=r.getPersistedSession}wakeDispatcher;applyPersistedPatch;completionSummaries;notificationDedupe;getPersistedSession;dispatch(e,n){let r=this.getDeliveryRef(e),o=this.getPersistedSession?.(r),i=this.buildNotificationDedupeKey(e,n),s=this.notificationDedupe.claim(i,o?.notificationDedupe,n.label);if(s.records&&this.applyNotificationDedupePatch(r,s.records),!s.allowed){this.logNotificationDecision({session:e,request:n,deliveryRef:r,dedupeKey:i,decision:"skip",reason:s.reason??"duplicate notification skipped",deliveryPath:"notify"}),n.hooks?.onDuplicateSkipped?.(s.reason??"duplicate notification skipped");return}let a=this.buildCompletionSummaryFact(n),d=n.completionSummaryOwner==="foreground"&&a?.required===!0,l=d?this.completionSummaries.recordVisibleDelivery(e,a,o?.completionSummaryDedupe,n.label):this.completionSummaries.decide(e,a,o?.completionSummaryDedupe);l.records&&this.applyCompletionSummaryDedupePatch(r,l.records);let u=d?this.withoutCompletionWake(n):n;if(l.required&&!l.allowed)if(this.logNotificationDecision({session:e,request:n,deliveryRef:r,dedupeKey:l.dedupeKey??l.key,outcomeKey:a?.outcomeKey,decision:d?"skip":l.explicit?"send_without_followup":"skip",reason:l.skipReason??"completion follow-up wake suppressed",deliveryPath:d?"foreground-summary":"wake",followupKind:a?.producer}),n.hooks?.onWakeSkipped?.(l.skipReason??"completion follow-up wake suppressed"),d){this.releaseNotificationDedupe(r,i);return}else if(l.explicit)u=this.withoutCompletionWake(n);else{this.releaseNotificationDedupe(r,i);return}a?.required===!0&&this.logNotificationDecision({session:e,request:u,deliveryRef:r,dedupeKey:l.dedupeKey??l.key,outcomeKey:a.outcomeKey,decision:d?"record_visible":u.completionWakeSummaryRequired===!0?"send_with_followup":"send_without_followup",reason:d?"foreground summary owns completion follow-up":void 0,deliveryPath:d?"foreground-summary":"wake",followupKind:a.producer});let c=this.buildCompletionWakePatch(u),p=!!(u.wakeMessage?.trim()||u.wakeMessageOnNotifySuccess?.trim()),f=!!(u.wakeMessage?.trim()||u.wakeMessageOnNotifyFailed?.trim()),g=!1,h=!1,y=()=>{h||(h=!0,g||(this.releaseNotificationDedupe(r,i),g=!0),this.completionSummaries.finish(l.key,!1))},k=u.shouldDispatch?()=>{let b=u.shouldDispatch?.()!==!1;return b||y(),b}:void 0,R={onNotifyStarted:()=>{this.applyDeliveryState(r,"notifying"),u.hooks?.onNotifyStarted?.()},onNotifySucceeded:()=>{g=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.applyNotifyDeliveryState(r,p?"wake_pending":"idle",p?c:void 0),p||this.completionSummaries.finish(l.key,!1),u.hooks?.onNotifySucceeded?.()},onNotifyFailed:()=>{this.applyNotifyDeliveryState(r,f?"wake_pending":"failed",f?c:void 0),f||(this.completionSummaries.finish(l.key,!1),this.releaseNotificationDedupe(r,i),g=!0),u.hooks?.onNotifyFailed?.()},onWakeStarted:()=>{this.applyPersistedPatchWithCompletionWake(r,"wake_pending",c,{completionWakeIssuedAt:new Date().toISOString(),completionWakeSucceededAt:void 0,completionWakeFailedAt:void 0,completionWakeSkippedAt:void 0,completionWakeSkipReason:void 0}),u.hooks?.onWakeStarted?.()},onWakeSucceeded:()=>{g=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.markCompletionSummaryDelivered(r,l.key,u.label),this.applyPersistedPatchWithCompletionWake(r,"idle",this.buildCompletionWakeSucceededPatch(c),{completionWakeSucceededAt:new Date().toISOString(),completionWakeFailedAt:void 0,completionWakeSkippedAt:void 0,completionWakeSkipReason:void 0}),this.completionSummaries.finish(l.key,!0),u.hooks?.onWakeSucceeded?.()},onWakeSkipped:b=>{if(h){u.hooks?.onWakeSkipped?.(b);return}g=!0,this.markNotificationDedupeDelivered(r,i,u.label),this.markCompletionSummaryDelivered(r,l.key,u.label,b),this.applyPersistedPatchWithCompletionWake(r,"idle",this.buildCompletionWakeSucceededPatch(c),{completionWakeSucceededAt:void 0,completionWakeFailedAt:void 0,completionWakeSkippedAt:new Date().toISOString(),completionWakeSkipReason:b}),this.completionSummaries.finish(l.key,!0),u.hooks?.onWakeSkipped?.(b)},onWakeFailed:()=>{this.applyPersistedPatchWithCompletionWake(r,"failed",c,{completionWakeFailedAt:new Date().toISOString()}),this.completionSummaries.finish(l.key,!1),this.releaseNotificationDedupe(r,i),g=!0,u.hooks?.onWakeFailed?.()}};this.wakeDispatcher.dispatchSessionNotification(e,{...u,idempotencyKey:i??u.idempotencyKey,shouldDispatch:k,hooks:R})}notifyWorktreeOutcome(e,n,r={}){let o=this.getDeliveryRef(e),i=l=>yt({sessionId:o,sessionName:e.name,outcomeLine:n,originThreadLine:It(e),detailLines:r.detailLines,canonicalStatusDelivered:l}),s=r.summaryWakeRequired??!0,a={required:s,producer:"worktree-pr",outcomeKey:r.completionWakeOutcomeKey??`terminal:${o}`},d=r.completionSummaryOwner!=="foreground";if(s&&!d){let l=this.getDeliveryRef(e),u=this.completionSummaries.recordVisibleDelivery(e,a,l?this.getPersistedSession?.(l)?.completionSummaryDedupe:void 0,"worktree-outcome");u.records&&this.applyCompletionSummaryDedupePatch(l,u.records)}this.dispatch(e,{label:"worktree-outcome",userMessage:n,notifyUser:"always",requireDirectUserNotification:!0,completionSummary:{...a,required:s&&d},completionWakeSummaryRequired:s&&d,completionWakeOutcomeKey:r.completionWakeOutcomeKey??`terminal:${o}`,idempotencyKey:`worktree-outcome:${r.completionWakeOutcomeKey??n}`,deferConditionalWakeUntilNextTick:!0,deferConditionalWakeMs:cg,wakeMessageOnNotifySuccess:s&&d?i(!0):void 0,wakeMessageOnNotifyFailed:s&&d?i(!1):void 0})}dispose(){this.wakeDispatcher.dispose()}getDeliveryRef(e){return W(e)??C(e)??""}applyDeliveryState(e,n){!e||!n||this.applyPersistedPatch(e,{deliveryState:n})}applyNotifyDeliveryState(e,n,r){!e||!n||this.applyPersistedPatch(e,r?{deliveryState:n,...r}:{deliveryState:n})}applyPersistedPatchWithCompletionWake(e,n,r,o){!e||!n||this.applyPersistedPatch(e,r?{deliveryState:n,...r,...o}:{deliveryState:n})}buildCompletionWakePatch(e){if(e.completionWakeSummaryRequired===!0)return{completionWakeSummaryRequired:!0}}buildCompletionWakeSucceededPatch(e){if(e)return{completionWakeSummaryRequired:void 0}}withoutCompletionWake(e){return{...e,completionSummary:e.completionSummary?{...e.completionSummary,required:!1}:void 0,wakeMessage:void 0,wakeMessageOnNotifySuccess:void 0,wakeMessageOnNotifyFailed:void 0,completionWakeSummaryRequired:!1}}buildCompletionSummaryFact(e){if(e.completionSummary)return e.completionSummary;if(e.completionWakeSummaryRequired!==!0)return;let n=[e.wakeMessage,e.wakeMessageOnNotifySuccess,e.wakeMessageOnNotifyFailed].map(r=>r?.trim()).filter(r=>!!r);return{required:!0,producer:"legacy",outcomeKey:e.completionWakeOutcomeKey,fallbackFingerprint:n.length>0?`${e.label}
|
|
224
222
|
${n.join(`
|
|
225
223
|
---completion-wake---
|
|
226
|
-
`)}`:void 0}}buildNotificationDedupeKey(e,n){let r=n.idempotencyKey?.trim();if(!r)return;let
|
|
227
|
-
`);return new Promise((p,f)=>{let g=setTimeout(()=>{this.pendingQuestions.delete(e.id),f(new Error(`AskUserQuestion timed out after 600s for session "${e.name}"`))},6e5);g.unref?.(),this.pendingQuestions.set(e.id,{resolve:p,reject:f,questions:
|
|
228
|
-
`),wakeMessageOnNotifyFailed:c})})}resolveAskUserQuestion(e,n){let r=this.pendingQuestions.get(e);if(!r){`${e}`;return}clearTimeout(r.timeoutHandle),this.pendingQuestions.delete(e);let
|
|
229
|
-
`);this.dispatchNotification(r,{label:`worktree-stale-reminder-${e.name}`,userMessage:
|
|
230
|
-
`)}function
|
|
231
|
-
`)}import{existsSync as
|
|
224
|
+
`)}`:void 0}}buildNotificationDedupeKey(e,n){let r=n.idempotencyKey?.trim();if(!r)return;let o=this.getDeliveryRef(e);if(!o)return;let i=Re(e),s=i?{provider:i.provider,accountId:i.accountId,target:i.target,threadId:i.threadId}:{deliveryRef:o};return`notification:${this.digest(JSON.stringify({scope:s,semanticKey:r}))}`}markNotificationDedupeDelivered(e,n,r){let o=this.notificationDedupe.deliveredRecords(n,e?this.getPersistedSession?.(e)?.notificationDedupe:void 0,r);o&&this.applyNotificationDedupePatch(e,o)}releaseNotificationDedupe(e,n){let r=this.notificationDedupe.releasedRecords(n,e?this.getPersistedSession?.(e)?.notificationDedupe:void 0);r&&this.applyNotificationDedupePatch(e,r)}applyNotificationDedupePatch(e,n){this.getPersistedSession&&e&&this.applyPersistedPatch(e,{notificationDedupe:n})}markCompletionSummaryDelivered(e,n,r,o){let i=this.completionSummaries.completionRecordsAfterDelivery(n,e?this.getPersistedSession?.(e)?.completionSummaryDedupe:void 0,r,o);i&&this.applyCompletionSummaryDedupePatch(e,i)}applyCompletionSummaryDedupePatch(e,n){this.getPersistedSession&&e&&this.applyPersistedPatch(e,{completionSummaryDedupe:n})}logNotificationDecision(e){let n=Re(e.session);fg({event:"oca_notification_decision",sessionId:"id"in e.session?e.session.id:e.session.sessionId,sessionName:e.session.name,harnessSessionId:e.session.harnessSessionId,originRoute:n?{provider:n.provider,accountId:n.accountId,target:n.target,threadId:n.threadId,sessionKey:n.sessionKey}:void 0,outcomeType:e.outcomeKey?.split(":").slice(0,2).join(":")??e.request.label,notificationKind:e.request.label,followupKind:e.followupKind,dedupeKey:e.dedupeKey,deliveryPath:e.deliveryPath,decision:e.decision,reason:e.reason,completionWakeSummaryRequired:e.request.completionWakeSummaryRequired,deliveryRef:e.deliveryRef})}digest(e){return ug("sha256").update(e).digest("hex").slice(0,16)}};me();import{existsSync as gg}from"fs";var Jr=class{getCompletionState(e,n,r,o){return qt(e,r,o)?"has-commits":qt(e,o,r)?ct(e,r,o)?"merged":"base-advanced":mt(n)?"dirty-uncommitted":"no-change"}isResolvedWorktreeEligibleForCleanup(e,n,r){if(!e.worktreePath||!e.workdir||!gg(e.worktreePath)||e.pendingWorktreeDecisionSince||e.worktreeState==="pending_decision")return!1;let o=e.worktreeMergedAt??e.worktreeDismissedAt??e.completedAt??e.createdAt,i=typeof o=="string"?new Date(o).getTime():Number(o??0);return!!i&&n-i>=r}};var Yr=class{constructor(e,n,r,o){this.pendingQuestions=e;this.dispatchSessionNotification=n;this.clearWaitingTimestamp=r;this.getQuestionButtons=o}pendingQuestions;dispatchSessionNotification;clearWaitingTimestamp;getQuestionButtons;async handleAskUserQuestion(e,n){let i=n?.questions??[];if(i.length===0)throw new Error("AskUserQuestion: no questions in input");let s=i[0],a=s.options??[],d=this.getQuestionButtons(e.id,a),l=`❓ [${e.name}] ${s.question}`,u=e.pendingInputState?.requestId??`${s.question}:${a.map(p=>p.label).join("|")}`,c=[`[ASK USER QUESTION] Session "${e.name}" has a question requiring user input.`,"",`Question: ${s.question}`,...a.length>0?["Options:",...a.map((p,f)=>` ${f+1}. ${p.label}`)]:[],"",`Send the question to the user and call agent_respond(session="${e.id}", message="<answer>") with their answer.`].join(`
|
|
225
|
+
`);return new Promise((p,f)=>{let g=setTimeout(()=>{this.pendingQuestions.delete(e.id),f(new Error(`AskUserQuestion timed out after 600s for session "${e.name}"`))},6e5);g.unref?.(),this.pendingQuestions.set(e.id,{resolve:p,reject:f,questions:i,timeoutHandle:g}),this.dispatchSessionNotification(e,{label:"ask-user-question",idempotencyKey:`ask-user-question:${e.id}:${u}`,userMessage:l,notifyUser:"always",buttons:d,wakeMessageOnNotifySuccess:["AskUserQuestion delivered to the user.",`Session: ${e.name} | ID: ${e.id}`,`Question: ${s.question}`,"Await their selection — do NOT answer this question yourself."].join(`
|
|
226
|
+
`),wakeMessageOnNotifyFailed:c})})}resolveAskUserQuestion(e,n){let r=this.pendingQuestions.get(e);if(!r){`${e}`;return}clearTimeout(r.timeoutHandle),this.pendingQuestions.delete(e);let o=r.questions[0],i=o.options??[],s=i[n];if(!s){r.reject(new Error(`AskUserQuestion: invalid option index ${n} (${i.length} options available)`));return}this.clearWaitingTimestamp(e),r.resolve({behavior:"allow",updatedInput:{questions:r.questions,answers:{[o.question]:s.label}}})}dispose(){for(let e of this.pendingQuestions.values())clearTimeout(e.timeoutHandle),e.reject(new Error("SessionManager disposed before AskUserQuestion resolved."));this.pendingQuestions.clear()}};Q();Vt();var Zr=class t{constructor(e,n,r,o){this.buildRoutingProxy=e;this.dispatchNotification=n;this.updatePersistedSession=r;this.getWorktreeDecisionButtons=o}buildRoutingProxy;dispatchNotification;updatePersistedSession;getWorktreeDecisionButtons;static REMINDER_THRESHOLD_MS=10800*1e3;static REMINDER_INTERVAL_MS=10800*1e3;getNextReminderAt(e){let n=new Date(e.pendingWorktreeDecisionSince).getTime();if(this.getWorktreeDecisionReminderStatus(e,n)!=="pending")return;let r=[n+t.REMINDER_THRESHOLD_MS];if(e.worktreeDecisionSnoozedUntil){let o=new Date(e.worktreeDecisionSnoozedUntil).getTime();Number.isFinite(o)&&r.push(o)}if(e.lastWorktreeReminderAt){let o=new Date(e.lastWorktreeReminderAt).getTime();Number.isFinite(o)&&r.push(o+t.REMINDER_INTERVAL_MS)}return Math.max(...r)}sendReminderIfDue(e,n=Date.now()){this.clearResolvedReminderState(e);let r=this.getNextReminderAt(e);if(r==null||r>n)return!1;let o=n-new Date(e.pendingWorktreeDecisionSince).getTime(),i=Math.floor(Math.max(0,o)/(3600*1e3));try{this.sendReminderNotification(e,i)}catch(s){return`${e.name}${s instanceof Error?s.message:String(s)}`,!1}for(let s of ae(e))this.updatePersistedSession(s,{lastWorktreeReminderAt:new Date(n).toISOString()});return!0}sendReminderNotification(e,n){let r=this.buildRoutingProxy({id:e.sessionId??e.name??C(e)??e.harnessSessionId,sessionId:e.sessionId,harnessSessionId:e.harnessSessionId,backendRef:e.backendRef,route:e.route});if(e.worktreeStrategy==="delegate"){this.dispatchNotification(r,{label:`worktree-stale-reminder-${e.name}`,wakeMessage:wi(e,n),notifyUser:"never"});return}let o=[`⏰ Reminder: branch \`${e.worktreeBranch??"unknown"}\` is still waiting for a merge decision.`,`Session: ${e.name} | Pending: ${n}h`,"",`agent_merge(session="${e.name}") or agent_pr(session="${e.name}") or agent_worktree_cleanup() to resolve.`].join(`
|
|
227
|
+
`);this.dispatchNotification(r,{label:`worktree-stale-reminder-${e.name}`,userMessage:o,notifyUser:"always",buttons:this.getWorktreeDecisionButtons(W(e)??e.harnessSessionId)})}clearResolvedReminderState(e){if(!e.pendingWorktreeDecisionSince&&!e.lastWorktreeReminderAt&&!e.worktreeDecisionSnoozedUntil||this.getWorktreeDecisionReminderStatus(e)!=="resolved")return!1;let n=!1;for(let r of ae(e))n=this.updatePersistedSession(r,{pendingWorktreeDecisionSince:void 0,lastWorktreeReminderAt:void 0,worktreeDecisionSnoozedUntil:void 0})||n;return n}getWorktreeDecisionReminderStatus(e,n){if(!e.pendingWorktreeDecisionSince)return"inactive";let r=n??new Date(e.pendingWorktreeDecisionSince).getTime();if(!Number.isFinite(r))return"inactive";if(e.worktreeMerged||e.worktreePrUrl||e.lifecycle==="terminal")return"resolved";let o=new Set(["merged","released","dismissed","none","cleanup_failed"]);if(e.worktreeState&&o.has(e.worktreeState))return"resolved";let i=new Set(["merged","released","dismissed","no_change","none","cleanup_failed"]);if(e.worktreeLifecycle?.state&&i.has(e.worktreeLifecycle.state))return"resolved";let s=e.worktreeState==="pending_decision"||e.lifecycle==="awaiting_worktree_decision"||e.worktreeLifecycle?.state==="pending_decision",a=e.worktreeState==null&&e.lifecycle==null&&e.worktreeLifecycle?.state==null&&!e.worktreeMerged&&!e.worktreePrUrl;if(!s&&!a)return"inactive";let d=He(e,{activeSession:!1,includePrSync:!1});return d.derivedState==="merged"||d.derivedState==="released"||d.derivedState==="cleanup_failed"?"resolved":"pending"}};me();Q();ve();function tn(t,e){return e!=null&&t.approvalPromptRequiredVersion===e&&hg(t.approvalPromptStatus)}function hg(t){return t==="delivered"||t==="fallback_delivered"}function nn(t,e){return!t||e==null?!1:!!(t.pendingPlanApproval&&t.approvalState==="pending"&&t.lifecycle==="awaiting_plan_decision"&&(t.actionablePlanDecisionVersion??t.planDecisionVersion)===e)}function wt(t,e,n=!1){let r="id"in t?t.id:t.sessionId??"unknown-session";return[n?"Plan review fallback text delivered to the user because interactive buttons could not be delivered.":"Plan approval buttons delivered to the user.",`Session: ${t.name??"unknown"} | ID: ${r} | Plan v${e??"?"}`,`Wait for their ${n?"explicit reply":"button callback"} — do NOT approve or reject this plan yourself.`].join(`
|
|
228
|
+
`)}function Xr(t){let e="id"in t.session?t.session.id:t.session.sessionId??"unknown-session",n=t.originThreadLine??(t.session.originThreadId!=null?`Origin thread: ${t.session.originThreadId}`:"");return["[PLAN APPROVAL DELIVERY FAILED] The plugin could not deliver the canonical plan review buttons or the explicit fallback text to the user.",`Name: ${t.session.name??"unknown"} | ID: ${e} | Plan v${t.planDecisionVersion??"?"}`,n,"","No user-visible actionable review prompt is confirmed for this plan version.","Intervene manually before assuming the user saw the plan review request."].filter(Boolean).join(`
|
|
229
|
+
`)}import{existsSync as Sg,readFileSync as yg}from"fs";function kg(t,e){if(t.latestPlanArtifactVersion===e&&t.latestPlanArtifact)return t.latestPlanArtifact;let n=t.planFilePath?.trim();if(!(!n||!Sg(n)))try{let r=yg(n,"utf-8").trim();return r?{markdown:r,steps:[]}:void 0}catch{return}}var eo=class{constructor(e){this.deps=e}deps;dispatchPlanApprovalFallback(e,n,r){let o=new Date().toISOString();this.deps.dispatchSessionNotification(e,{label:"plan-approval-fallback",idempotencyKey:`plan-approval:${e.id}:v${n??"unknown"}:fallback`,userMessage:Zt({session:e,summary:r}),notifyUser:"always",shouldDispatch:()=>nn(e,n),hooks:{onNotifyStarted:()=>{this.deps.updatePersistedSession(e.id,{approvalPromptRequiredVersion:n,approvalPromptVersion:n,approvalPromptStatus:"sending",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"explicit_fallback_text",approvalPromptLastAttemptAt:o})},onNotifySucceeded:()=>{this.deps.updatePersistedSession(e.id,{approvalPromptRequiredVersion:n,approvalPromptVersion:n,approvalPromptStatus:"fallback_delivered",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"explicit_fallback_text",approvalPromptLastAttemptAt:o,approvalPromptDeliveredAt:new Date().toISOString(),approvalPromptFailedAt:void 0})},onNotifyFailed:()=>{this.deps.updatePersistedSession(e.id,{approvalPromptRequiredVersion:n,approvalPromptVersion:n,approvalPromptStatus:"failed",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"explicit_fallback_text",approvalPromptLastAttemptAt:o,approvalPromptFailedAt:new Date().toISOString()})}},wakeMessageOnNotifySuccess:wt(e,n,!0),wakeMessageOnNotifyFailed:Xr({session:e,planDecisionVersion:n,originThreadLine:this.deps.originThreadLine(e)})})}logCompletionWakeDiagnostic(e){JSON.stringify({event:e.event,sessionId:e.session.id,sessionName:e.session.name,canonicalStatusDelivered:e.canonicalStatusDelivered,requestedShortFactualSummary:e.followupSummaryRequired,completionKind:"terminal"})}shouldRequestCompletionFollowup(e){return e.originSessionKey?.trim()?.startsWith("agent:main:cron:")?!1:!!Re(e)}handleTurnEnd(e,n){if(e.status!=="running"){`${e.id}${e.status}`;return}if(!e.goalTaskId){if(n||e.pendingPlanApproval){this.emitWaitingForInput(e);return}if(e.worktreeStrategy==="ask"||e.worktreeStrategy==="delegate"){`${e.id}${e.worktreeStrategy}`;return}this.deps.shouldEmitTurnCompleteWake(e)&&this.emitTurnComplete(e)}}async handleSessionTerminal(e){if(this.deps.persistSession(e),this.deps.clearWaitingTimestamp(e.id),e.goalTaskId){this.deps.clearRetryTimersForSession(e.id);return}let n={notificationSent:!1,worktreeRemoved:!1};e.worktreePath&&e.originalWorkdir&&(n=await this.deps.handleWorktreeStrategy(e));let r=!1;if(e.worktreePath&&e.originalWorkdir&&e.status==="failed"&&e.costUsd===0&&e.duration<3e4){let a=this.deps.resolveWorktreeRepoDir(e.originalWorkdir,e.worktreePath),d=e.worktreeBranch,l=ne(e);`${e.name}${e.costUsd.toFixed(2)}${e.duration}`;let u=!1;if(a&&!l&&(u=de(a,e.worktreePath)),a&&d&&!l&&u&&ge(a,d),u){for(let c of ae(e))this.deps.updatePersistedSession(c,{worktreePath:void 0,worktreeBranch:void 0});r=!0}}let o=e.worktreeStrategy&&e.worktreeStrategy!=="off"&&e.worktreeStrategy!=="manual";if(!r&&e.worktreePath&&e.originalWorkdir){let a=this.deps.resolveWorktreeRepoDir(e.originalWorkdir,e.worktreePath),d=ne(e);n.worktreeRemoved?`${e.name}`:o?`${e.name}${e.worktreeStrategy}`:a&&!d&&de(a,e.worktreePath)}if(n.notificationSent){`${e.id}`;return}if(e.killReason==="done"){if(this.deps.hasTurnCompleteWakeMarker(e.id)||!this.deps.shouldEmitTerminalWake(e))return;this.emitCompleted(e);return}if(e.status==="completed"){if(!this.deps.shouldEmitTerminalWake(e))return;this.emitCompleted(e);return}if(e.status==="failed"){if(!this.deps.shouldEmitTerminalWake(e))return;let a=e.error||e.result?.is_error&&e.result.result||e.result?.result||this.deps.extractLastOutputLine(e)||`Session failed with no error details (session=${e.id}, subtype=${e.result?.subtype??"none"}, turns=${e.result?.num_turns??0})`;this.emitFailed(e,re(a,200),r);return}let i=`$${(e.costUsd??0).toFixed(2)}`,s=e.duration;if(e.killReason==="idle-timeout"){let a=e.pendingPlanApproval?this.deps.resolvePlanApprovalMode(e):void 0;if(e.pendingPlanApproval){let d=e.actionablePlanDecisionVersion??e.planDecisionVersion,l=tn(e,d);if(a==="delegate"){this.deps.dispatchSessionNotification(e,{label:"plan-approval-timeout",idempotencyKey:`plan-approval-timeout:${e.id}:v${d??"unknown"}:delegate`,wakeMessage:["[DELEGATED PLAN APPROVAL REMINDER] Plan review is still pending after the session hit idle timeout.",`Name: ${e.name} | ID: ${e.id}`,this.deps.originThreadLine(e),"The agent already produced a plan and is waiting for a delegated decision.","Review privately first. Approve directly with agent_respond(..., approve=true, approval_rationale='...') if the plan is clearly within scope and low risk.","Escalate only if needed via agent_request_plan_approval(summary='...').","If you approve directly, follow up with a short user-facing explanation; the plugin's thumbs-up line is only the minimal approval acknowledgment.","If a canonical approval prompt was already posted for this plan version, do not restate it in plain text."].join(`
|
|
232
230
|
`),notifyUser:"never"}),this.deps.clearRetryTimersForSession(e.id);return}if(a==="ask"&&l){this.deps.dispatchSessionNotification(e,{label:"plan-approval-timeout",idempotencyKey:`plan-approval-timeout:${e.id}:v${d??"unknown"}:already-delivered`,notifyUser:"never",wakeMessage:["[PLAN APPROVAL REMINDER] The user already has an actionable plan review prompt for this plan version.",`Name: ${e.name} | ID: ${e.id} | Plan v${d??"?"}`,this.deps.originThreadLine(e),"Do NOT post another approval summary unless canonical delivery is known to be missing."].join(`
|
|
233
|
-
`)}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.dispatchSessionNotification(e,{label:"plan-approval-timeout",idempotencyKey:`plan-approval-timeout:${e.id}:v${d??"unknown"}:user-prompt`,userMessage:[`📋 [${e.name}] Plan v${d??"?"} still awaiting approval after idle timeout | ${
|
|
234
|
-
`),notifyUser:"always",buttons:a==="ask"&&!l?this.deps.getPlanApprovalButtons(e.id,{...e,planDecisionVersion:d}):void 0}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.dispatchSessionNotification(e,{label:"suspended",idempotencyKey:`suspended:${e.id}:${e.killReason??"idle-timeout"}:${e.completedAt??"unknown"}`,userMessage:`💤 [${e.name}] Suspended after idle timeout | ${o} | ${ye(s)}`,notifyUser:"always",buttons:this.deps.getResumeButtons(e.id,e)}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.notifySession(e,`⛔ [${e.name}] ${jt(e.killReason)} | ${o} | ${ye(s)}`),this.deps.clearRetryTimersForSession(e.id)}emitWaitingForInput(e){if(!this.deps.debounceWaitingEvent(e.id))return;let n=e.pendingPlanApproval?this.deps.resolvePlanApprovalMode(e):void 0,r=e.actionablePlanDecisionVersion??e.planDecisionVersion,i=e.pendingPlanApproval&&n==="ask"&&Yt(e,r),o=e.pendingPlanApproval?void 0:this.deps.getOutputPreview(e),s=!e.pendingPlanApproval&&e.pendingInputState?.promptText?e.pendingInputState.promptText:!e.pendingPlanApproval&&o!==void 0?o:this.deps.getOutputPreview(e,e.pendingPlanApproval&&n!=="delegate"?Number.POSITIVE_INFINITY:void 0),a=e.pendingPlanApproval&&n==="ask"&&!i?this.deps.getPlanApprovalButtons(e.id,{...e,planDecisionVersion:r}):!e.pendingPlanApproval&&e.pendingInputState?.options.length?this.deps.getQuestionButtons(e.id,e.pendingInputState.options.map(c=>({label:c}))):void 0,d=og(e,r),l=mo({session:e,preview:s,questionText:e.pendingPlanApproval?void 0:e.pendingInputState?.promptText,questionContextPreview:o,planArtifact:d,originThreadLine:this.deps.originThreadLine(e),planApprovalMode:n,planApprovalButtons:a,questionButtons:e.pendingPlanApproval?void 0:a}),u=l.planReviewSummary??s;if(l.label==="plan-approval"&&n==="ask"&&i){this.deps.dispatchSessionNotification(e,{label:l.label,idempotencyKey:`plan-approval:${e.id}:v${r??"unknown"}:canonical`,userMessage:l.userMessage,userMessages:l.userMessages,notifyUser:"never",buttons:l.buttons,wakeMessage:l.wakeMessage});return}if(l.label==="plan-approval"&&n==="ask"){this.deps.dispatchSessionNotification(e,{label:l.label,idempotencyKey:`plan-approval:${e.id}:v${r??"unknown"}:canonical`,userMessage:l.userMessage,userMessages:l.userMessages,notifyUser:"always",buttons:l.buttons,hooks:{onNotifyStarted:()=>{this.deps.updatePersistedSession(e.id,{approvalPromptRequiredVersion:r,approvalPromptVersion:r,approvalPromptStatus:"sending",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptLastAttemptAt:new Date().toISOString()})},onNotifySucceeded:()=>{this.deps.updatePersistedSession(e.id,{canonicalPlanPromptVersion:r,approvalPromptRequiredVersion:r,approvalPromptVersion:r,approvalPromptStatus:"delivered",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptDeliveredAt:new Date().toISOString(),approvalPromptFailedAt:void 0})},onNotifyFailed:()=>{this.deps.updatePersistedSession(e.id,{approvalPromptRequiredVersion:r,approvalPromptVersion:r,approvalPromptStatus:"failed",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptFailedAt:new Date().toISOString()})}},shouldDispatch:()=>Zt(e,r),onUserNotifyFailed:()=>this.dispatchPlanApprovalFallback(e,r,u),wakeMessageOnNotifySuccess:yt(e,r)});return}if(l.label==="plan-approval"){this.deps.dispatchSessionNotification(e,{label:l.label,idempotencyKey:`plan-approval:${e.id}:v${r??"unknown"}:wake-only`,userMessage:l.userMessage,wakeMessage:l.wakeMessage,notifyUser:"never",buttons:l.buttons});return}this.deps.dispatchSessionNotification(e,{label:l.label,idempotencyKey:`waiting:${e.id}:${e.pendingInputState?.requestId??`${l.label}:${l.userMessage}`}`,userMessage:l.userMessage,notifyUser:"always",buttons:l.buttons,wakeMessageOnNotifyFailed:l.wakeMessage})}emitTurnComplete(e){`${e.id}${e.result?.num_turns??0}${e.worktreeStrategy??"none"}`;let n=io({session:e,originThreadLine:this.deps.originThreadLine(e),preview:this.deps.getOutputPreview(e)});this.deps.dispatchSessionNotification(e,{label:"turn-complete",idempotencyKey:`turn-complete:${e.id}:${e.result?.num_turns??0}`,userMessage:n.userMessage,wakeMessage:n.wakeMessage,notifyUser:"always",onUserNotifyFailed:()=>{`${e.id}`,this.deps.shouldEmitTerminalWake(e)&&this.emitCompleted(e)}})}emitCompleted(e){let n=this.deps.getOutputPreview(e),r=this.shouldRequestCompletionFollowup(e),i=to({session:e,originThreadLine:this.deps.originThreadLine(e),preview:n}),o;this.deps.dispatchSessionNotification(e,{label:"completed",idempotencyKey:`terminal-completed:${e.id}`,userMessage:i.userMessage,notifyUser:"always",completionSummary:{required:r,producer:"terminal",outcomeKey:`terminal:${e.id}`},completionWakeSummaryRequired:r,completionWakeOutcomeKey:`terminal:${e.id}`,requireDirectUserNotification:!0,wakeMessageOnNotifySuccess:r?i.wakeMessageOnNotifySuccess:void 0,wakeMessageOnNotifyFailed:r?i.wakeMessageOnNotifyFailed:void 0,hooks:{onNotifySucceeded:()=>{o=!0,this.logCompletionWakeDiagnostic({session:e,event:"completion_notify_succeeded",canonicalStatusDelivered:o,followupSummaryRequired:r})},onNotifyFailed:()=>{o=!1,this.logCompletionWakeDiagnostic({session:e,event:"completion_notify_failed",canonicalStatusDelivered:o,followupSummaryRequired:r})},onWakeSucceeded:()=>{this.logCompletionWakeDiagnostic({session:e,event:"completion_wake_succeeded",canonicalStatusDelivered:o,followupSummaryRequired:r})}}})}emitFailed(e,n,r){let i=ro({session:e,originThreadLine:this.deps.originThreadLine(e),errorSummary:n,preview:this.deps.getOutputPreview(e),worktreeAutoCleaned:r,failedButtons:this.deps.getResumeButtons(e.id,e)});this.deps.dispatchSessionNotification(e,{label:"failed",idempotencyKey:`terminal-failed:${e.id}:${n}`,userMessage:i.userMessage,wakeMessage:i.wakeMessage,notifyUser:"always",buttons:i.buttons})}};V();ue();import{existsSync as sg}from"fs";var jr=class{constructor(e){this.deps=e}deps;async dismissWorktree(e){let n=this.deps.getPersistedSession(e),r=this.deps.resolveActiveSession(e),i=r??n;if(!i)return`Error: Session "${e}" not found.`;let o=r?.worktreePath??n?.worktreePath,s=this.deps.resolveWorktreeRepoDir(r?.originalWorkdir??n?.workdir,o),a=r?.worktreeBranch??n?.worktreeBranch,d=r?.name??n?.name??e;if(!s)return`Error: No workdir found for session "${e}".`;let l=ie(i);!l&&o&&sg(o)&&le(s,o,{destructive:!0}),a&&ve(s,a);for(let c of re(r??n))this.deps.updatePersistedSession(c,{worktreeDisposition:"dismissed",worktreeDismissedAt:new Date().toISOString(),pendingWorktreeDecisionSince:void 0,worktreeState:"dismissed",lifecycle:"terminal",worktreePath:void 0,worktreeBranch:void 0,worktreeLifecycle:{state:"dismissed",updatedAt:new Date().toISOString(),resolvedAt:new Date().toISOString(),resolutionSource:"dismiss",baseBranch:n?.worktreeLifecycle?.baseBranch,targetRepo:n?.worktreePrTargetRepo,pushRemote:n?.worktreePushRemote}});let u=l?`🗑️ [${d}] Branch \`${a??"unknown"}\` dismissed. Native backend worktree released for backend cleanup.`:`🗑️ [${d}] Branch \`${a??"unknown"}\` dismissed and permanently deleted.`;return this.deps.dispatchNotification(this.deps.buildRoutingProxy({id:D(r??n??{id:e})??e,sessionId:n?.sessionId,harnessSessionId:r?.harnessSessionId??n?.harnessSessionId,backendRef:r?.backendRef??n?.backendRef,route:r?.route??n?.route}),{label:"worktree-dismissed",idempotencyKey:`worktree-dismissed:${D(r??n??{id:e})??e}:${a??"unknown"}`,userMessage:u,notifyUser:"always"}),u}snoozeWorktreeDecision(e,n={}){let r=this.deps.getPersistedSession(e);if(!r)return`Error: Session "${e}" not found.`;let i=Date.now(),o=new Date(i+1440*60*1e3).toISOString();for(let d of re(r))this.deps.updatePersistedSession(d,{worktreeDecisionSnoozedUntil:o,lastWorktreeReminderAt:new Date(i).toISOString()});let a=`⏭️ Reminder snoozed 24h for \`${r.worktreeBranch??"unknown"}\` (session: ${r.name})`;return n.notifyUser!==!1&&this.deps.dispatchNotification(this.deps.buildRoutingProxy({id:D(r)??x(r)??r.harnessSessionId,sessionId:r.sessionId,harnessSessionId:r.harnessSessionId,backendRef:r.backendRef,route:r.route}),{label:"worktree-snoozed",idempotencyKey:`worktree-snoozed:${D(r)??x(r)??r.harnessSessionId}:${o}`,userMessage:a,notifyUser:"always"}),a}};var Bd=new Set(["starting","running"]),zr=class{sessions=new Map;activeSessionCount(){return[...this.sessions.values()].filter(e=>Bd.has(e.status)).length}uniqueName(e){let n=new Set([...this.sessions.values()].filter(i=>Bd.has(i.status)).map(i=>i.name));if(!n.has(e))return e;let r=2;for(;n.has(`${e}-${r}`);)r+=1;return`${e}-${r}`}add(e){this.sessions.set(e.id,e)}remove(e){this.sessions.delete(e)}get(e){return this.sessions.get(e)}list(){return[...this.sessions.values()]}};var Jr=class{constructor(e){this.deps=e}deps;initializeSession(e,n,r,i={}){if(this.deps.hydrateSpawnedSession(e,n,r),r.taskLifecycle?.create(e),e.on("statusChange",(o,s)=>{s==="running"?(e.harnessSessionId&&this.deps.markRunning(e),r.taskLifecycle?.progress(e)):(s==="completed"||s==="failed"||s==="killed")&&(r.taskLifecycle?.finalize(e),this.deps.handleTerminal(e).catch(a=>{console.error(`[SessionRuntimeBootstrap] handleTerminal threw for session ${e.id}:`,a)}))}),e.on("lifecycleChange",(o,s)=>{r.taskLifecycle?.progress(e)}),e.on("turnEnd",(o,s)=>{this.deps.handleTurnEnd(e,s)}),e.start(),i.notifyLaunch!==!1){let o=this.deps.formatLaunchWorkdirLabel(e),s=`🚀 [${e.name}] Launched | ${o} | ${Et({harness:e.harnessName,model:e.model})??"default"}`;this.deps.notifySession(e,s,"launch")}return e}};var Qr=class{buildNoChangeNotification(e){let{session:n,nativeBackendWorktree:r,cleanupSucceeded:i,worktreePath:o,preview:s,originThreadLine:a}=e,d=i?r?"native backend worktree released for backend cleanup":"worktree cleaned up":`cleanup failed; worktree still exists at ${o}`;return{label:i?"worktree-no-changes":"worktree-no-changes-cleanup-failed",idempotencyKey:`worktree-no-change:${n.id}:${i?"cleaned":"cleanup-failed"}`,userMessage:i?r?`ℹ️ [${n.name}] Session completed with no changes — native backend worktree released for backend cleanup`:`ℹ️ [${n.name}] Session completed with no changes — worktree cleaned up`:`⚠️ [${n.name}] Session completed with no changes, but worktree cleanup failed. Worktree still exists at ${o}`,wakeMessage:ao({sessionName:n.name,sessionId:n.id,cleanupSummary:d,preview:s,originThreadLine:a,requestedPermissionMode:n.requestedPermissionMode,currentPermissionMode:n.currentPermissionMode,approvalExecutionState:n.approvalExecutionState,approvalState:n.approvalState,planApproval:n.planApproval,approvalPromptStatus:n.approvalPromptStatus,approvalPromptMessageKind:n.approvalPromptMessageKind,approvalPromptDeliveredAt:n.approvalPromptDeliveredAt}),notifyUser:"always"}}buildAskNotification(e){let{session:n,branchName:r,baseBranch:i,diffSummary:o,buttons:s,summaryLines:a=[]}=e,d=o.commitMessages.slice(0,5).map(c=>`• ${c.hash} ${c.message} (${c.author})`),l=o.commits>5?`...and ${o.commits-5} more`:"",u=n.worktreePrTargetRepo?`Branch: \`${r}\` → \`${i}\` | PR target: ${n.worktreePrTargetRepo}`:`Branch: \`${r}\` → \`${i}\``;return{label:"worktree-merge-ask",idempotencyKey:["worktree-decision",n.id,r,i,o.commits,o.commitMessages.map(c=>c.hash).join(",")].join(":"),userMessage:[`🔀 Worktree decision required for session \`${n.name}\``,"",u,`Commits: ${o.commits} | Files: ${o.filesChanged} | +${o.insertions} / -${o.deletions}`,"",...a.length>0?["Summary:",...a.map(c=>`- ${c}`),""]:[],"Recent commits:",...d,...l?[l]:[],"",`⚠️ Discard will permanently delete branch \`${r}\` and all local changes. This cannot be undone.`].join(`
|
|
231
|
+
`)}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.dispatchSessionNotification(e,{label:"plan-approval-timeout",idempotencyKey:`plan-approval-timeout:${e.id}:v${d??"unknown"}:user-prompt`,userMessage:[`📋 [${e.name}] Plan v${d??"?"} still awaiting approval after idle timeout | ${i} | ${we(s)}`,"","The agent already produced a plan and is waiting for your decision.","Approve resumes the session and starts implementation.","Revise resumes it in plan mode so it can update the plan first.","Reject keeps the session stopped."].join(`
|
|
232
|
+
`),notifyUser:"always",buttons:a==="ask"&&!l?this.deps.getPlanApprovalButtons(e.id,{...e,planDecisionVersion:d}):void 0}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.dispatchSessionNotification(e,{label:"suspended",idempotencyKey:`suspended:${e.id}:${e.killReason??"idle-timeout"}:${e.completedAt??"unknown"}`,userMessage:`💤 [${e.name}] Suspended after idle timeout | ${i} | ${we(s)}`,notifyUser:"always",buttons:this.deps.getResumeButtons(e.id,e)}),this.deps.clearRetryTimersForSession(e.id);return}this.deps.notifySession(e,`⛔ [${e.name}] ${fi(e.killReason)} | ${i} | ${we(s)}`),this.deps.clearRetryTimersForSession(e.id)}emitWaitingForInput(e){if(!this.deps.debounceWaitingEvent(e.id))return;let n=e.pendingPlanApproval?this.deps.resolvePlanApprovalMode(e):void 0,r=e.actionablePlanDecisionVersion??e.planDecisionVersion,o=e.pendingPlanApproval&&n==="ask"&&tn(e,r),i=e.pendingPlanApproval?void 0:this.deps.getOutputPreview(e),s=!e.pendingPlanApproval&&e.pendingInputState?.promptText?e.pendingInputState.promptText:!e.pendingPlanApproval&&i!==void 0?i:this.deps.getOutputPreview(e,e.pendingPlanApproval&&n!=="delegate"?Number.POSITIVE_INFINITY:void 0),a=e.pendingPlanApproval&&n==="ask"&&!o?this.deps.getPlanApprovalButtons(e.id,{...e,planDecisionVersion:r}):!e.pendingPlanApproval&&e.pendingInputState?.options.length?this.deps.getQuestionButtons(e.id,e.pendingInputState.options.map(c=>({label:c}))):void 0,d=kg(e,r),l=xi({session:e,preview:s,questionText:e.pendingPlanApproval?void 0:e.pendingInputState?.promptText,questionContextPreview:i,planArtifact:d,originThreadLine:this.deps.originThreadLine(e),planApprovalMode:n,planApprovalButtons:a,questionButtons:e.pendingPlanApproval?void 0:a}),u=l.planReviewSummary??s;if(l.label==="plan-approval"&&n==="ask"&&o){this.deps.dispatchSessionNotification(e,{label:l.label,idempotencyKey:`plan-approval:${e.id}:v${r??"unknown"}:canonical`,userMessage:l.userMessage,userMessages:l.userMessages,notifyUser:"never",buttons:l.buttons,wakeMessage:l.wakeMessage});return}if(l.label==="plan-approval"&&n==="ask"){this.deps.dispatchSessionNotification(e,{label:l.label,idempotencyKey:`plan-approval:${e.id}:v${r??"unknown"}:canonical`,userMessage:l.userMessage,userMessages:l.userMessages,notifyUser:"always",buttons:l.buttons,hooks:{onNotifyStarted:()=>{this.deps.updatePersistedSession(e.id,{approvalPromptRequiredVersion:r,approvalPromptVersion:r,approvalPromptStatus:"sending",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptLastAttemptAt:new Date().toISOString()})},onNotifySucceeded:()=>{this.deps.updatePersistedSession(e.id,{canonicalPlanPromptVersion:r,approvalPromptRequiredVersion:r,approvalPromptVersion:r,approvalPromptStatus:"delivered",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptDeliveredAt:new Date().toISOString(),approvalPromptFailedAt:void 0})},onNotifyFailed:()=>{this.deps.updatePersistedSession(e.id,{approvalPromptRequiredVersion:r,approvalPromptVersion:r,approvalPromptStatus:"failed",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptFailedAt:new Date().toISOString()})}},shouldDispatch:()=>nn(e,r),onUserNotifyFailed:()=>this.dispatchPlanApprovalFallback(e,r,u),wakeMessageOnNotifySuccess:wt(e,r)});return}if(l.label==="plan-approval"){this.deps.dispatchSessionNotification(e,{label:l.label,idempotencyKey:`plan-approval:${e.id}:v${r??"unknown"}:wake-only`,userMessage:l.userMessage,wakeMessage:l.wakeMessage,notifyUser:"never",buttons:l.buttons});return}this.deps.dispatchSessionNotification(e,{label:l.label,idempotencyKey:`waiting:${e.id}:${e.pendingInputState?.requestId??`${l.label}:${l.userMessage}`}`,userMessage:l.userMessage,notifyUser:"always",buttons:l.buttons,wakeMessageOnNotifyFailed:l.wakeMessage})}emitTurnComplete(e){`${e.id}${e.result?.num_turns??0}${e.worktreeStrategy??"none"}`;let n=ki({session:e,originThreadLine:this.deps.originThreadLine(e),preview:this.deps.getOutputPreview(e)});this.deps.dispatchSessionNotification(e,{label:"turn-complete",idempotencyKey:`turn-complete:${e.id}:${e.result?.num_turns??0}`,userMessage:n.userMessage,wakeMessage:n.wakeMessage,notifyUser:"always",onUserNotifyFailed:()=>{`${e.id}`,this.deps.shouldEmitTerminalWake(e)&&this.emitCompleted(e)}})}emitCompleted(e){let n=this.deps.getOutputPreview(e),r=this.shouldRequestCompletionFollowup(e),o=hi({session:e,originThreadLine:this.deps.originThreadLine(e),preview:n}),i;this.deps.dispatchSessionNotification(e,{label:"completed",idempotencyKey:`terminal-completed:${e.id}`,userMessage:o.userMessage,notifyUser:"always",completionSummary:{required:r,producer:"terminal",outcomeKey:`terminal:${e.id}`},completionWakeSummaryRequired:r,completionWakeOutcomeKey:`terminal:${e.id}`,requireDirectUserNotification:!0,wakeMessageOnNotifySuccess:r?o.wakeMessageOnNotifySuccess:void 0,wakeMessageOnNotifyFailed:r?o.wakeMessageOnNotifyFailed:void 0,hooks:{onNotifySucceeded:()=>{i=!0,this.logCompletionWakeDiagnostic({session:e,event:"completion_notify_succeeded",canonicalStatusDelivered:i,followupSummaryRequired:r})},onNotifyFailed:()=>{i=!1,this.logCompletionWakeDiagnostic({session:e,event:"completion_notify_failed",canonicalStatusDelivered:i,followupSummaryRequired:r})},onWakeSucceeded:()=>{this.logCompletionWakeDiagnostic({session:e,event:"completion_wake_succeeded",canonicalStatusDelivered:i,followupSummaryRequired:r})}}})}emitFailed(e,n,r){let o=yi({session:e,originThreadLine:this.deps.originThreadLine(e),errorSummary:n,preview:this.deps.getOutputPreview(e),worktreeAutoCleaned:r,failedButtons:this.deps.getResumeButtons(e.id,e)});this.deps.dispatchSessionNotification(e,{label:"failed",idempotencyKey:`terminal-failed:${e.id}:${n}`,userMessage:o.userMessage,wakeMessage:o.wakeMessage,notifyUser:"always",buttons:o.buttons})}};Q();me();import{existsSync as vg}from"fs";var to=class{constructor(e){this.deps=e}deps;async dismissWorktree(e){let n=this.deps.getPersistedSession(e),r=this.deps.resolveActiveSession(e),o=r??n;if(!o)return`Error: Session "${e}" not found.`;let i=r?.worktreePath??n?.worktreePath,s=this.deps.resolveWorktreeRepoDir(r?.originalWorkdir??n?.workdir,i),a=r?.worktreeBranch??n?.worktreeBranch,d=r?.name??n?.name??e;if(!s)return`Error: No workdir found for session "${e}".`;let l=ne(o);!l&&i&&vg(i)&&de(s,i,{destructive:!0}),a&&ge(s,a);for(let c of ae(r??n))this.deps.updatePersistedSession(c,{worktreeDisposition:"dismissed",worktreeDismissedAt:new Date().toISOString(),pendingWorktreeDecisionSince:void 0,worktreeState:"dismissed",lifecycle:"terminal",worktreePath:void 0,worktreeBranch:void 0,worktreeLifecycle:{state:"dismissed",updatedAt:new Date().toISOString(),resolvedAt:new Date().toISOString(),resolutionSource:"dismiss",baseBranch:n?.worktreeLifecycle?.baseBranch,targetRepo:n?.worktreePrTargetRepo,pushRemote:n?.worktreePushRemote}});let u=l?`🗑️ [${d}] Branch \`${a??"unknown"}\` dismissed. Native backend worktree released for backend cleanup.`:`🗑️ [${d}] Branch \`${a??"unknown"}\` dismissed and permanently deleted.`;return this.deps.dispatchNotification(this.deps.buildRoutingProxy({id:W(r??n??{id:e})??e,sessionId:n?.sessionId,harnessSessionId:r?.harnessSessionId??n?.harnessSessionId,backendRef:r?.backendRef??n?.backendRef,route:r?.route??n?.route}),{label:"worktree-dismissed",idempotencyKey:`worktree-dismissed:${W(r??n??{id:e})??e}:${a??"unknown"}`,userMessage:u,notifyUser:"always"}),u}snoozeWorktreeDecision(e,n={}){let r=this.deps.getPersistedSession(e);if(!r)return`Error: Session "${e}" not found.`;let o=Date.now(),i=new Date(o+1440*60*1e3).toISOString();for(let d of ae(r))this.deps.updatePersistedSession(d,{worktreeDecisionSnoozedUntil:i,lastWorktreeReminderAt:new Date(o).toISOString()});let a=`⏭️ Reminder snoozed 24h for \`${r.worktreeBranch??"unknown"}\` (session: ${r.name})`;return n.notifyUser!==!1&&this.deps.dispatchNotification(this.deps.buildRoutingProxy({id:W(r)??C(r)??r.harnessSessionId,sessionId:r.sessionId,harnessSessionId:r.harnessSessionId,backendRef:r.backendRef,route:r.route}),{label:"worktree-snoozed",idempotencyKey:`worktree-snoozed:${W(r)??C(r)??r.harnessSessionId}:${i}`,userMessage:a,notifyUser:"always"}),a}};var Yd=new Set(["starting","running"]),no=class{sessions=new Map;activeSessionCount(){return[...this.sessions.values()].filter(e=>Yd.has(e.status)).length}uniqueName(e){let n=new Set([...this.sessions.values()].filter(o=>Yd.has(o.status)).map(o=>o.name));if(!n.has(e))return e;let r=2;for(;n.has(`${e}-${r}`);)r+=1;return`${e}-${r}`}add(e){this.sessions.set(e.id,e)}remove(e){this.sessions.delete(e)}get(e){return this.sessions.get(e)}list(){return[...this.sessions.values()]}};var ro=class{constructor(e){this.deps=e}deps;initializeSession(e,n,r,o={}){if(this.deps.hydrateSpawnedSession(e,n,r),r.taskLifecycle?.create(e),e.on("statusChange",(i,s)=>{s==="running"?(e.harnessSessionId&&this.deps.markRunning(e),r.taskLifecycle?.progress(e)):(s==="completed"||s==="failed"||s==="killed")&&(r.taskLifecycle?.finalize(e),this.deps.handleTerminal(e).catch(a=>{console.error(`[SessionRuntimeBootstrap] handleTerminal threw for session ${e.id}:`,a)}))}),e.on("lifecycleChange",(i,s)=>{r.taskLifecycle?.progress(e)}),e.on("turnEnd",(i,s)=>{this.deps.handleTurnEnd(e,s)}),e.start(),o.notifyLaunch!==!1){let i=this.deps.formatLaunchWorkdirLabel(e),s=`🚀 [${e.name}] Launched | ${i} | ${Lt({harness:e.harnessName,model:e.model})??"default"}`;this.deps.notifySession(e,s,"launch")}return e}};var oo=class{buildNoChangeNotification(e){let{session:n,nativeBackendWorktree:r,cleanupSucceeded:o,worktreePath:i,preview:s,originThreadLine:a}=e,d=o?r?"native backend worktree released for backend cleanup":"worktree cleaned up":`cleanup failed; worktree still exists at ${i}`;return{label:o?"worktree-no-changes":"worktree-no-changes-cleanup-failed",idempotencyKey:`worktree-no-change:${n.id}:${o?"cleaned":"cleanup-failed"}`,userMessage:o?r?`ℹ️ [${n.name}] Session completed with no changes — native backend worktree released for backend cleanup`:`ℹ️ [${n.name}] Session completed with no changes — worktree cleaned up`:`⚠️ [${n.name}] Session completed with no changes, but worktree cleanup failed. Worktree still exists at ${i}`,wakeMessage:Pi({sessionName:n.name,sessionId:n.id,cleanupSummary:d,preview:s,originThreadLine:a,requestedPermissionMode:n.requestedPermissionMode,currentPermissionMode:n.currentPermissionMode,approvalExecutionState:n.approvalExecutionState,approvalState:n.approvalState,planApproval:n.planApproval,approvalPromptStatus:n.approvalPromptStatus,approvalPromptMessageKind:n.approvalPromptMessageKind,approvalPromptDeliveredAt:n.approvalPromptDeliveredAt}),notifyUser:"always"}}buildAskNotification(e){let{session:n,branchName:r,baseBranch:o,diffSummary:i,buttons:s,summaryLines:a=[]}=e,d=i.commitMessages.slice(0,5).map(c=>`• ${c.hash} ${c.message} (${c.author})`),l=i.commits>5?`...and ${i.commits-5} more`:"",u=n.worktreePrTargetRepo?`Branch: \`${r}\` → \`${o}\` | PR target: ${n.worktreePrTargetRepo}`:`Branch: \`${r}\` → \`${o}\``;return{label:"worktree-merge-ask",idempotencyKey:["worktree-decision",n.id,r,o,i.commits,i.commitMessages.map(c=>c.hash).join(",")].join(":"),userMessage:[`🔀 Worktree decision required for session \`${n.name}\``,"",u,`Commits: ${i.commits} | Files: ${i.filesChanged} | +${i.insertions} / -${i.deletions}`,"",...a.length>0?["Summary:",...a.map(c=>`- ${c}`),""]:[],"Recent commits:",...d,...l?[l]:[],"",`⚠️ Discard will permanently delete branch \`${r}\` and all local changes. This cannot be undone.`].join(`
|
|
235
233
|
`),notifyUser:"always",buttons:s,wakeMessageOnNotifySuccess:["Worktree decision buttons delivered to the user.",`Session: ${n.name} | ID: ${n.id}`,u,"Wait for their button callback — do NOT act on this worktree yourself."].join(`
|
|
236
|
-
`),wakeMessageOnNotifyFailed:[`🔀 Worktree decision required for session \`${n.name}\``,"",u,`Commits: ${
|
|
237
|
-
`)}}buildDelegateNotification(e){let{session:n,branchName:r,baseBranch:
|
|
238
|
-
`),wakeMessage:
|
|
239
|
-
`):
|
|
240
|
-
`).trim();return n?
|
|
241
|
-
`):""}function
|
|
242
|
-
`)?n:void 0}he();ue();Y();import{unlinkSync as lg}from"fs";var Yr=class t{timers=new Map;disposed=!1;static MAX_DELAY_MS=2147483647;schedule(e,n,r){if(this.disposed)return;this.cancel(e);let i=Math.max(0,n-Date.now()),o=setTimeout(()=>{if(this.timers.delete(e),!this.disposed){if(n-Date.now()>0){this.schedule(e,n,r);return}r()}},Math.min(i,t.MAX_DELAY_MS));o.unref?.(),this.timers.set(e,o)}cancel(e){let n=this.timers.get(e);n&&(clearTimeout(n),this.timers.delete(e))}cancelPrefix(e){for(let n of this.timers.keys())n.startsWith(e)&&this.cancel(n)}dispose(){this.disposed=!0;for(let e of this.timers.values())clearTimeout(e);this.timers.clear()}};V();Bt();ue();var Kd=10080*60*1e3,ug=300*1e3,Ud="tmp-output:cleanup";function cg(t){return t instanceof Error?t.message:String(t)}var Zr=class{constructor(e){this.deps=e}deps;scheduler=new Yr;schedule(e,n,r){this.scheduler.schedule(e,n,r)}cancel(e){this.scheduler.cancel(e)}cancelPrefix(e){this.scheduler.cancelPrefix(e)}bootstrapMaintenanceSchedules(){let e=Date.now();this.deps.store.cleanupTmpOutputFiles(e);for(let n of this.deps.store.listPersistedSessions())this.syncPersistedSessionMaintenance(n);this.syncActionTokenExpiryDeadline(),this.deps.store.cleanupOrphanOutputFiles(),this.syncTmpOutputCleanupDeadline(e)}syncRuntimeGcDeadline(e){if(!e.completedAt)return;let n=this.runtimeGcKey(e.id);this.schedule(n,e.completedAt+this.runtimeGcMaxAgeMs(),()=>{let r=this.deps.sessions.get(e.id);if(!r||!r.completedAt)return;let i=this.runtimeGcMaxAgeMs();if(!this.deps.store.shouldGcActiveSession(r,Date.now(),i)){this.syncRuntimeGcDeadline(r);return}this.deps.removeRuntimeSession(e.id),this.deps.persistSession(r,{scheduleRuntimeGc:!1}),this.deps.clearRuntimeSessionState(e.id)})}cancelRuntimeGc(e){this.cancel(this.runtimeGcKey(e))}cancelPersistedMaintenance(e){let n=this.persistedMaintenanceRef(e);n&&this.cancelPrefix(`persisted:${n}:`)}syncPersistedSessionMaintenance(e){let n=this.persistedMaintenanceRef(e);if(!n)return;this.cancel(this.persistedMaintenanceKey(n,"worktree-reminder"));let r=this.deps.reminders.getNextReminderAt(e);r!=null?this.schedulePersistedWorktreeReminder(n,r):this.deps.reminders.clearResolvedReminderState(e),this.cancel(this.persistedMaintenanceKey(n,"worktree-retention"));let i=Fe(e,{activeSession:!1,includePrSync:e.worktreeLifecycle?.state==="pr_open"||!!e.worktreePrUrl}),o=this.resolvedAtIso(e),s=this.isLegacyResolvedWorktree(e);if((i.cleanupSafe||s)&&typeof o=="string"){let a=new Date(o).getTime();Number.isFinite(a)&&this.schedule(this.persistedMaintenanceKey(n,"worktree-retention"),a+Kd,()=>{let d=this.deps.store.getPersistedSession(n);d&&this.reconcileResolvedWorktreeRetention(d,Date.now())})}}reconcileResolvedWorktreeRetention(e,n){let r=Fe(e,{activeSession:!1,includePrSync:e.worktreeLifecycle?.state==="pr_open"||!!e.worktreePrUrl}),i=this.resolvedAtIso(e),o=i?new Date(i).getTime():0,s=this.isLegacyResolvedWorktree(e);if(!(!r.cleanupSafe&&!s||!o||n-o<Kd))try{if(!e.worktreePath&&!ie(e))return;let a=this.deps.resolveWorktreeRepoDir(e.workdir,e.worktreePath);if(!a)return;let d=ie(e)?!1:le(a,e.worktreePath);if(!ie(e)&&!d)return;for(let l of re(e))this.deps.updatePersistedSession(l,{worktreePath:void 0,worktreeBranch:void 0,worktreeState:"none",worktreeLifecycle:{...e.worktreeLifecycle??r.lifecycle,state:r.derivedState,updatedAt:new Date(n).toISOString(),resolvedAt:e.worktreeLifecycle?.resolvedAt??new Date(n).toISOString(),resolutionSource:e.worktreeLifecycle?.resolutionSource??"maintenance",notes:r.reasons}})}catch(a){`${e.worktreePath}${cg(a)}`}}syncActionTokenExpiryDeadline(){let e="tokens:expiry";this.cancel(e);let n=this.deps.store.getNextActionTokenExpiry();n!=null&&this.schedule(e,n,()=>{this.deps.store.purgeExpiredActionTokens(Date.now())})}syncTmpOutputCleanupDeadline(e=Date.now()){this.cancel(Ud);let n=this.deps.store.getNextTmpOutputCleanupAt(e);n!=null&&this.schedule(Ud,n,()=>{let r=Date.now();this.deps.store.cleanupTmpOutputFiles(r),this.syncTmpOutputCleanupDeadline(r)})}enforcePersistedRetention(){let e=this.deps.store.evictOldestPersisted(this.deps.getMaxPersistedSessions());for(let n of e)this.cancelPersistedMaintenance(n),n.sessionId&&this.cancelRuntimeGc(n.sessionId),this.cleanupOutputPathIfUnreferenced(n.outputPath)}dispose(){this.scheduler.dispose()}persistedMaintenanceRef(e){return e.sessionId??x(e)??e.harnessSessionId}runtimeGcKey(e){return`runtime-gc:${e}`}persistedMaintenanceKey(e,n){return`persisted:${e}:${n}`}runtimeGcMaxAgeMs(){return(C.sessionGcAgeMinutes??1440)*6e4}schedulePersistedWorktreeReminder(e,n){let r=this.persistedMaintenanceKey(e,"worktree-reminder");this.schedule(r,n,()=>{let i=this.deps.store.getPersistedSession(e);if(!i||this.deps.reminders.sendReminderIfDue(i,Date.now()))return;let s=this.deps.reminders.getNextReminderAt(i);s!=null&&this.schedulePersistedWorktreeReminder(e,Math.max(s,Date.now()+ug))})}cleanupOutputPathIfUnreferenced(e){if(!(!e||this.deps.store.hasOutputPathReference(e)))try{lg(e)}catch{}}resolvedAtIso(e){return e.worktreeLifecycle?.resolvedAt??e.worktreeMergedAt??e.worktreeDismissedAt??(e.completedAt?new Date(e.completedAt).toISOString():void 0)}isLegacyResolvedWorktree(e){return e.worktreeMerged===!0||e.worktreeDisposition==="dismissed"||e.worktreeDisposition==="no-change-cleaned"||e.worktreeState==="merged"||e.worktreeState==="dismissed"}};or();var Vd=new Set(["completed","failed","killed"]),pg=new Set(["starting","running"]),mg=5e3,Xr=class{registry;sessions;maxSessions;maxPersistedSessions;lastWaitingEventTimestamps=new Map;lastTurnCompleteMarkers=new Map;lastTerminalWakeMarkers=new Map;mergeQueue=new ht;pendingAskUserQuestions=new Map;store;metrics;wakeDispatcher;interactions;notifications;worktrees;questions;reminders;lifecycle;restore;stateSync;references;worktreeStrategy;worktreeDecisions;runtimeBootstrap;worktreeMessages;maintenance;constructor(e=20,n=50,r={}){this.maxSessions=e,this.maxPersistedSessions=n,this.registry=new zr,this.sessions=this.registry.sessions,this.store=new Cr(r.store),this.metrics=new Mr,this.wakeDispatcher=new Wr,this.interactions=new Nr(this.store.actionTokenStore,Ce),this.references=new kr(this.sessions,this.store),this.stateSync=new Sr({store:this.store,sessions:this.sessions,resolveSession:i=>this.references.resolveActive(i)}),this.notifications=new qr(this.wakeDispatcher,(i,o)=>this.stateSync.applySessionPatch(i,o),{getPersistedSession:i=>this.store.getPersistedSession(i)}),this.worktrees=new Kr,this.restore=new yr(i=>this.store.getPersistedSession(i)),this.worktreeMessages=new Qr,this.worktreeStrategy=new Pr({shouldRunWorktreeStrategy:i=>this.shouldRunWorktreeStrategy(i),isAlreadyMerged:i=>this.isAlreadyMerged(i),resolveWorktreeRepoDir:(i,o)=>this.resolveWorktreeRepoDir(i,o),getWorktreeCompletionState:(i,o,s,a)=>this.getWorktreeCompletionState(i,o,s,a),updatePersistedSession:(i,o)=>this.updatePersistedSession(i,o),dispatchSessionNotification:(i,o)=>this.dispatchSessionNotification(i,o),getOutputPreview:(i,o)=>this.getOutputPreview(i,o),originThreadLine:i=>this.originThreadLine(i),getWorktreeDecisionButtons:i=>this.getWorktreeDecisionButtons(i),makeOpenPrButton:i=>this.makeActionButton(i,"worktree-create-pr","Open PR"),worktreeSummaryProvider:r.worktreeSummaryProvider,worktreeMessages:this.worktreeMessages,enqueueMerge:(i,o,s)=>this.enqueueMerge(i,o,s),mergeBranch:Bn,spawnConflictResolver:async({session:i,worktreePath:o,prompt:s})=>this.spawn({prompt:s,workdir:o,name:`${i.name}-conflict-resolver`,harness:i.harnessName||ne(),model:i.model,reasoningEffort:i.reasoningEffort,fastMode:i.fastMode,permissionMode:"bypassPermissions",multiTurn:!0,worktreeStrategy:"off",autoMergeParentSessionId:i.id,route:i.route,originChannel:i.originChannel,originThreadId:i.originThreadId,originAgentId:i.originAgentId,originSessionKey:i.originSessionKey},{notifyLaunch:!1}),runAutoPr:async(i,o)=>{let{makeAgentPrTool:s}=await Promise.resolve().then(()=>(ar(),ma));return{success:(await s().execute("auto-pr",{session:i.id,base_branch:o}))?.meta?.success===!0}}}),this.questions=new Ur(this.pendingAskUserQuestions,(i,o)=>this.dispatchSessionNotification(i,o),i=>{this.lastWaitingEventTimestamps.delete(i)},(i,o)=>this.interactions.getQuestionButtons(i,o)),this.reminders=new Vr(i=>this.buildRoutingProxy(i),(i,o)=>this.notifications.dispatch(i,o),(i,o)=>this.updatePersistedSession(i,o),i=>this.getWorktreeDecisionButtons(i)),this.maintenance=new Zr({store:this.store,sessions:this.sessions,reminders:this.reminders,removeRuntimeSession:i=>this.registry.remove(i),persistSession:(i,o)=>this.persistSession(i,o),clearRuntimeSessionState:i=>{this.lastWaitingEventTimestamps.delete(i),this.lastTurnCompleteMarkers.delete(i),this.lastTerminalWakeMarkers.delete(i)},resolveWorktreeRepoDir:(i,o)=>this.resolveWorktreeRepoDir(i,o),updatePersistedSession:(i,o)=>this.updatePersistedSession(i,o),getMaxPersistedSessions:()=>this.maxPersistedSessions}),this.store.onActionTokensChanged(()=>this.syncActionTokenExpiryDeadline()),this.lifecycle=new Gr({persistSession:i=>this.persistSession(i),clearWaitingTimestamp:i=>{this.lastWaitingEventTimestamps.delete(i)},handleWorktreeStrategy:i=>this.handleWorktreeStrategy(i),resolveWorktreeRepoDir:(i,o)=>this.resolveWorktreeRepoDir(i,o),updatePersistedSession:(i,o)=>this.updatePersistedSession(i,o),dispatchSessionNotification:(i,o)=>this.dispatchSessionNotification(i,o),notifySession:(i,o,s)=>this.notifySession(i,o,s),clearRetryTimersForSession:i=>this.wakeDispatcher.clearRetryTimersForSession(i),hasTurnCompleteWakeMarker:i=>this.lastTurnCompleteMarkers.has(i),shouldEmitTurnCompleteWake:i=>this.shouldEmitTurnCompleteWake(i),shouldEmitTerminalWake:i=>this.shouldEmitTerminalWake(i),resolvePlanApprovalMode:i=>this.resolvePlanApprovalMode(i),getPlanApprovalButtons:(i,o)=>this.interactions.getPlanApprovalButtons(i,o),getResumeButtons:(i,o)=>this.interactions.getResumeButtons(i,o),getQuestionButtons:(i,o)=>this.interactions.getQuestionButtons(i,o),extractLastOutputLine:i=>this.extractLastOutputLine(i),getOutputPreview:(i,o)=>this.getOutputPreview(i,o),originThreadLine:i=>this.originThreadLine(i),debounceWaitingEvent:i=>this.debounceWaitingEvent(i),isAlreadyMerged:i=>this.isAlreadyMerged(i)}),this.worktreeDecisions=new jr({getPersistedSession:i=>this.store.getPersistedSession(i),resolveActiveSession:i=>this.references.resolveActive(i),resolveWorktreeRepoDir:(i,o)=>this.resolveWorktreeRepoDir(i,o),updatePersistedSession:(i,o)=>this.updatePersistedSession(i,o),dispatchNotification:(i,o)=>this.notifications.dispatch(i,o),buildRoutingProxy:i=>this.buildRoutingProxy(i)}),this.runtimeBootstrap=new Jr({hydrateSpawnedSession:(i,o,s)=>{this.restore.hydrateSpawnedSession(i,o,s)},markRunning:i=>{this.store.markRunning(i),this.onPersistedSessionChanged(this.store.getPersistedSession(i.id))},handleTerminal:async i=>this.onSessionTerminal(i),handleTurnEnd:(i,o)=>this.onTurnEnd(i,o),formatLaunchWorkdirLabel:i=>this.formatLaunchWorkdirLabel(i),notifySession:(i,o,s)=>this.notifySession(i,o,s)})}get persisted(){return this.store.persisted}get idIndex(){return this.store.idIndex}get nameIndex(){return this.store.nameIndex}uniqueName(e){return this.registry.uniqueName(e)}syncRuntimeGcDeadline(e){this.maintenance.syncRuntimeGcDeadline(e)}cancelPersistedMaintenance(e){this.maintenance.cancelPersistedMaintenance(e)}onPersistedSessionChanged(e){e&&(this.syncPersistedSessionMaintenance(e),this.enforcePersistedRetention())}syncPersistedSessionMaintenance(e){this.maintenance.syncPersistedSessionMaintenance(e)}reconcileResolvedWorktreeRetention(e,n){this.maintenance.reconcileResolvedWorktreeRetention(e,n)}syncActionTokenExpiryDeadline(){this.maintenance.syncActionTokenExpiryDeadline()}syncTmpOutputCleanupDeadline(e=Date.now()){this.maintenance.syncTmpOutputCleanupDeadline(e)}enforcePersistedRetention(){this.maintenance.enforcePersistedRetention()}bootstrapMaintenanceSchedules(){this.maintenance.bootstrapMaintenanceSchedules()}disposeMaintenance(){this.maintenance.dispose()}spawn(e,n={}){if(this.registry.activeSessionCount()>=this.maxSessions)throw new Error(`Max sessions reached (${this.maxSessions}). Use agent_sessions to list active sessions and agent_kill to end one.`);if(e.sessionIdOverride){let p=this.registry.get(e.sessionIdOverride);if(p?.status==="starting"||p?.status==="running")throw new Error(`Cannot reuse session ID ${e.sessionIdOverride}: that session is still ${p.status}.`);p&&this.registry.remove(p.id),this.lastWaitingEventTimestamps.delete(e.sessionIdOverride),this.lastTurnCompleteMarkers.delete(e.sessionIdOverride),this.lastTerminalWakeMarkers.delete(e.sessionIdOverride),this.maintenance.cancelRuntimeGc(e.sessionIdOverride)}let i=e.name||ls(e.prompt),o=this.uniqueName(i);if(o!==i&&`${i}${o}`,!e.route?.provider||!e.route.target)throw new Error(`Cannot launch session "${o}": missing explicit route metadata.`);let s=this.restore.prepareSpawn(e,o),a=e.harness??"claude-code",d=this,l,u=a==="claude-code"&&!e.canUseTool?async(p,f)=>{if(!l)throw new Error("canUseTool called before session ID was set");return d.handleAskUserQuestion(l,f)}:e.canUseTool,c=new Kn({...e,workdir:s.actualWorkdir,systemPrompt:s.effectiveSystemPrompt,canUseTool:u},o);return l=c.id,this.registry.add(c),this.metrics.incrementLaunched(),this.runtimeBootstrap.initializeSession(c,s,e,n)}async spawnAndAwaitRunning(e,n={}){let r=this.spawn(e,n);return await this.waitForRunningSession(r),r}async waitForRunningSession(e){if(e.status==="running")return;if(Vd.has(e.status))throw new Error(this.describeLaunchFailure(e));let n=e.on?.bind(e),r=e.off?.bind(e)??e.removeListener?.bind(e);if(!n||!r)throw new Error(`Session ${e.name} [${e.id}] did not expose lifecycle events during startup.`);await new Promise((i,o)=>{let s=(d,l)=>{if(l==="running"){a(),i();return}Vd.has(l)&&(a(),o(new Error(this.describeLaunchFailure(e))))},a=()=>{r("statusChange",s)};n("statusChange",s)})}describeLaunchFailure(e){let n=e.killReason?` (reason: ${e.killReason})`:"",r=e.error||e.result?.result||`status=${e.status}${n}`;return`Session ${e.name} [${e.id}] failed to start: ${r}`}formatLaunchResult(e,n){return en({prompt:e.prompt,workdir:e.workdir,harness:e.harness,permissionMode:e.permissionMode??C.permissionMode,planApproval:e.planApproval,resumeSessionId:e.resumeSessionId,forkSession:e.forkSession,forceNewSession:e.forceNewSession,clearedPersistedCodexResume:e.clearedPersistedCodexResume},n)}shouldRunWorktreeStrategy(e){let n=e.lifecycle;return!(n==="starting"||n==="awaiting_plan_decision"||n==="awaiting_user_input"||e.pendingPlanApproval)}makeActionButton(e,n,r,i={}){return this.interactions.makeActionButton(e,n,r,i)}consumeActionToken(e){return this.interactions.consumeActionToken(e)}getActionToken(e){return this.interactions.getActionToken(e)}clearPlanDecisionTokens(e,n){this.interactions.clearPlanDecisionTokens(e,n)}isCurrentPendingPlanDecision(e,n){let r=this.resolve(e)??this.getPersistedSession(e);return Zt(r,n)}dispatchPlanApprovalFallback(e,n,r){let i=new Date().toISOString();this.notifications.dispatch(e,{label:"plan-approval-fallback",idempotencyKey:`plan-approval:${e.id}:v${n??"unknown"}:fallback`,userMessage:zt({session:e,summary:r}),notifyUser:"always",shouldDispatch:()=>this.isCurrentPendingPlanDecision(e.id,n),hooks:{onNotifyStarted:()=>{this.updatePersistedSession(e.id,{approvalPromptRequiredVersion:n,approvalPromptVersion:n,approvalPromptStatus:"sending",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"explicit_fallback_text",approvalPromptLastAttemptAt:i})},onNotifySucceeded:()=>{this.updatePersistedSession(e.id,{approvalPromptRequiredVersion:n,approvalPromptVersion:n,approvalPromptStatus:"fallback_delivered",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"explicit_fallback_text",approvalPromptLastAttemptAt:i,approvalPromptDeliveredAt:new Date().toISOString(),approvalPromptFailedAt:void 0})},onNotifyFailed:()=>{this.updatePersistedSession(e.id,{approvalPromptRequiredVersion:n,approvalPromptVersion:n,approvalPromptStatus:"failed",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"explicit_fallback_text",approvalPromptLastAttemptAt:i,approvalPromptFailedAt:new Date().toISOString()})}},wakeMessageOnNotifySuccess:yt(e,n,!0),wakeMessageOnNotifyFailed:Hr({session:e,planDecisionVersion:n})})}getWorktreeDecisionButtons(e,n={}){let r=this.resolve(e)??this.getPersistedSession(e);if(!(!r||r.worktreeStrategy==="delegate"&&n.allowDelegate!==!0))return this.interactions.getWorktreeDecisionButtons(e,r)}getWorktreeCompletionState(e,n,r,i){return this.worktrees.getCompletionState(e,n,r,i)}notifyWorktreeOutcome(e,n,r){this.notifications.notifyWorktreeOutcome(e,n,r)}requestPlanApprovalFromUser(e,n){let r=n.trim();if(!r)return"Error: summary must not be empty.";let i=co(r),o=this.resolve(e),s=o?void 0:this.getPersistedSession(e),a=o??s;if(!a)return`Error: Session "${e}" not found.`;if(!a.pendingPlanApproval)return`Error: Session "${e}" is not awaiting plan approval.`;let d=D(o??s??{id:e})??e;if(this.resolvePlanApprovalMode(a)!=="delegate")return`Error: Session "${e}" already uses direct user plan approval. Do not send a duplicate approval prompt.`;let l=a.actionablePlanDecisionVersion??a.planDecisionVersion;if(Yt(a,l))return[`An actionable plan review prompt already exists for session ${a.name} [${d}].`,"Wait for the user's Approve, Revise, or Reject response.","Do not send a separate plain-text approval message."].join(" ");if(a.deliveryState==="notifying")return[`A plan approval prompt is already being delivered for session ${a.name} [${d}].`,"Wait for delivery to finish before retrying."].join(" ");let u=this.interactions.getPlanApprovalButtons(d,{...a,planDecisionVersion:l}),c=[`📋 [${a.name}] Plan v${l??"?"} needs your decision:`,"","Why this was escalated:","",i,"","Choose Approve, Revise, or Reject below."].join(`
|
|
243
|
-
`);return this.notifications.dispatch(this.buildRoutingProxy({id:d,name:a.name,sessionId:s?.sessionId,harnessSessionId:
|
|
244
|
-
`),buttons:[[this.makeActionButton(n,"worktree-create-pr","Open PR")]]})}
|
|
245
|
-
`),d=l=>
|
|
234
|
+
`),wakeMessageOnNotifyFailed:[`🔀 Worktree decision required for session \`${n.name}\``,"",u,`Commits: ${i.commits} | Files: ${i.filesChanged} | +${i.insertions} / -${i.deletions}`].join(`
|
|
235
|
+
`)}}buildDelegateNotification(e){let{session:n,branchName:r,baseBranch:o,diffSummary:i,originThreadLine:s}=e,a=i.commitMessages.slice(0,5).map(u=>`• ${u.hash} ${u.message} (${u.author})`),d=i.commits>5?`...and ${i.commits-5} more`:void 0,l=n.prompt?n.prompt.slice(0,500):"(no prompt)";return{label:"worktree-delegate",idempotencyKey:["worktree-delegate",n.id,r,o,i.commits,i.commitMessages.map(u=>u.hash).join(",")].join(":"),userMessage:[`🔀 Worktree decision pending for session \`${n.name}\``,"",`Branch: \`${r}\` → \`${o}\``,`Commits: ${i.commits} | Files: ${i.filesChanged} | +${i.insertions} / -${i.deletions}`,"","The delegated reviewer is deciding whether to merge, open a PR, or ask for your choice."].join(`
|
|
236
|
+
`),wakeMessage:vi({sessionName:n.name,sessionId:n.id,branchName:r,baseBranch:o,promptSnippet:l,commitLines:a,moreNote:d,originThreadLine:s,diffSummary:i}),notifyUser:"always"}}};function Zd(t,e=1e3){let n=!Number.isFinite(e),r=typeof t.getOutput=="function"?t.getOutput():[],o=n?r.join(`
|
|
237
|
+
`):wg(t);return n?o:o.length>e?Xd(t)?Rn(o,e):xs(o,e):o}function wg(t){let e=typeof t.getOutput=="function"?t.getOutput():[],n=e.join(`
|
|
238
|
+
`).trim();return n?Xd(t)?Pg(n)??n:e.slice(-20).join(`
|
|
239
|
+
`):""}function Xd(t){if(t.status==="completed"||t.killReason==="done")return!0;let e=t;return e.approvalState==="approved"||e.planModeApproved===!0||(e.planDecisionVersion??0)>0}function Pg(t){let n=t.split(/\n\s*\n+/).map(r=>r.trim()).filter(r=>/[A-Za-z0-9]/.test(r)).at(-1);if(n)return n.length>=120||n.includes(`
|
|
240
|
+
`)?n:void 0}ve();me();te();import{unlinkSync as bg}from"fs";var io=class t{timers=new Map;disposed=!1;static MAX_DELAY_MS=2147483647;schedule(e,n,r){if(this.disposed)return;this.cancel(e);let o=Math.max(0,n-Date.now()),i=setTimeout(()=>{if(this.timers.delete(e),!this.disposed){if(n-Date.now()>0){this.schedule(e,n,r);return}r()}},Math.min(o,t.MAX_DELAY_MS));i.unref?.(),this.timers.set(e,i)}cancel(e){let n=this.timers.get(e);n&&(clearTimeout(n),this.timers.delete(e))}cancelPrefix(e){for(let n of this.timers.keys())n.startsWith(e)&&this.cancel(n)}dispose(){this.disposed=!0;for(let e of this.timers.values())clearTimeout(e);this.timers.clear()}};Q();Vt();me();var el=10080*60*1e3,Ag=300*1e3,tl="tmp-output:cleanup";function Rg(t){return t instanceof Error?t.message:String(t)}var so=class{constructor(e){this.deps=e}deps;scheduler=new io;schedule(e,n,r){this.scheduler.schedule(e,n,r)}cancel(e){this.scheduler.cancel(e)}cancelPrefix(e){this.scheduler.cancelPrefix(e)}bootstrapMaintenanceSchedules(){let e=Date.now();this.deps.store.cleanupTmpOutputFiles(e);for(let n of this.deps.store.listPersistedSessions())this.syncPersistedSessionMaintenance(n);this.syncActionTokenExpiryDeadline(),this.deps.store.cleanupOrphanOutputFiles(),this.syncTmpOutputCleanupDeadline(e)}syncRuntimeGcDeadline(e){if(!e.completedAt)return;let n=this.runtimeGcKey(e.id);this.schedule(n,e.completedAt+this.runtimeGcMaxAgeMs(),()=>{let r=this.deps.sessions.get(e.id);if(!r||!r.completedAt)return;let o=this.runtimeGcMaxAgeMs();if(!this.deps.store.shouldGcActiveSession(r,Date.now(),o)){this.syncRuntimeGcDeadline(r);return}this.deps.removeRuntimeSession(e.id),this.deps.persistSession(r,{scheduleRuntimeGc:!1}),this.deps.clearRuntimeSessionState(e.id)})}cancelRuntimeGc(e){this.cancel(this.runtimeGcKey(e))}cancelPersistedMaintenance(e){let n=this.persistedMaintenanceRef(e);n&&this.cancelPrefix(`persisted:${n}:`)}syncPersistedSessionMaintenance(e){let n=this.persistedMaintenanceRef(e);if(!n)return;this.cancel(this.persistedMaintenanceKey(n,"worktree-reminder"));let r=this.deps.reminders.getNextReminderAt(e);r!=null?this.schedulePersistedWorktreeReminder(n,r):this.deps.reminders.clearResolvedReminderState(e),this.cancel(this.persistedMaintenanceKey(n,"worktree-retention"));let o=He(e,{activeSession:!1,includePrSync:e.worktreeLifecycle?.state==="pr_open"||!!e.worktreePrUrl}),i=this.resolvedAtIso(e),s=this.isLegacyResolvedWorktree(e);if((o.cleanupSafe||s)&&typeof i=="string"){let a=new Date(i).getTime();Number.isFinite(a)&&this.schedule(this.persistedMaintenanceKey(n,"worktree-retention"),a+el,()=>{let d=this.deps.store.getPersistedSession(n);d&&this.reconcileResolvedWorktreeRetention(d,Date.now())})}}reconcileResolvedWorktreeRetention(e,n){let r=He(e,{activeSession:!1,includePrSync:e.worktreeLifecycle?.state==="pr_open"||!!e.worktreePrUrl}),o=this.resolvedAtIso(e),i=o?new Date(o).getTime():0,s=this.isLegacyResolvedWorktree(e);if(!(!r.cleanupSafe&&!s||!i||n-i<el))try{if(!e.worktreePath&&!ne(e))return;let a=this.deps.resolveWorktreeRepoDir(e.workdir,e.worktreePath);if(!a)return;let d=ne(e)?!1:de(a,e.worktreePath);if(!ne(e)&&!d)return;for(let l of ae(e))this.deps.updatePersistedSession(l,{worktreePath:void 0,worktreeBranch:void 0,worktreeState:"none",worktreeLifecycle:{...e.worktreeLifecycle??r.lifecycle,state:r.derivedState,updatedAt:new Date(n).toISOString(),resolvedAt:e.worktreeLifecycle?.resolvedAt??new Date(n).toISOString(),resolutionSource:e.worktreeLifecycle?.resolutionSource??"maintenance",notes:r.reasons}})}catch(a){`${e.worktreePath}${Rg(a)}`}}syncActionTokenExpiryDeadline(){let e="tokens:expiry";this.cancel(e);let n=this.deps.store.getNextActionTokenExpiry();n!=null&&this.schedule(e,n,()=>{this.deps.store.purgeExpiredActionTokens(Date.now())})}syncTmpOutputCleanupDeadline(e=Date.now()){this.cancel(tl);let n=this.deps.store.getNextTmpOutputCleanupAt(e);n!=null&&this.schedule(tl,n,()=>{let r=Date.now();this.deps.store.cleanupTmpOutputFiles(r),this.syncTmpOutputCleanupDeadline(r)})}enforcePersistedRetention(){let e=this.deps.store.evictOldestPersisted(this.deps.getMaxPersistedSessions());for(let n of e)this.cancelPersistedMaintenance(n),n.sessionId&&this.cancelRuntimeGc(n.sessionId),this.cleanupOutputPathIfUnreferenced(n.outputPath)}dispose(){this.scheduler.dispose()}persistedMaintenanceRef(e){return e.sessionId??C(e)??e.harnessSessionId}runtimeGcKey(e){return`runtime-gc:${e}`}persistedMaintenanceKey(e,n){return`persisted:${e}:${n}`}runtimeGcMaxAgeMs(){return(E.sessionGcAgeMinutes??1440)*6e4}schedulePersistedWorktreeReminder(e,n){let r=this.persistedMaintenanceKey(e,"worktree-reminder");this.schedule(r,n,()=>{let o=this.deps.store.getPersistedSession(e);if(!o||this.deps.reminders.sendReminderIfDue(o,Date.now()))return;let s=this.deps.reminders.getNextReminderAt(o);s!=null&&this.schedulePersistedWorktreeReminder(e,Math.max(s,Date.now()+Ag))})}cleanupOutputPathIfUnreferenced(e){if(!(!e||this.deps.store.hasOutputPathReference(e)))try{bg(e)}catch{}}resolvedAtIso(e){return e.worktreeLifecycle?.resolvedAt??e.worktreeMergedAt??e.worktreeDismissedAt??(e.completedAt?new Date(e.completedAt).toISOString():void 0)}isLegacyResolvedWorktree(e){return e.worktreeMerged===!0||e.worktreeDisposition==="dismissed"||e.worktreeDisposition==="no-change-cleaned"||e.worktreeState==="merged"||e.worktreeState==="dismissed"}};cr();var nl=new Set(["completed","failed","killed"]),Ig=new Set(["starting","running"]),xg=5e3,ao=class t{registry;sessions;maxSessions;maxPersistedSessions;lastWaitingEventTimestamps=new Map;lastTurnCompleteMarkers=new Map;lastTerminalWakeMarkers=new Map;mergeQueue=new vt;pendingAskUserQuestions=new Map;store;metrics;wakeDispatcher;interactions;notifications;worktrees;questions;reminders;lifecycle;restore;stateSync;references;worktreeStrategy;worktreeDecisions;runtimeBootstrap;worktreeMessages;maintenance;constructor(e=20,n=50,r={}){this.maxSessions=e,this.maxPersistedSessions=n;let o=t.createServiceBundle(this,r);this.registry=o.registry,this.sessions=o.sessions,this.store=o.store,this.metrics=o.metrics,this.wakeDispatcher=o.wakeDispatcher,this.interactions=o.interactions,this.notifications=o.notifications,this.worktrees=o.worktrees,this.questions=o.questions,this.reminders=o.reminders,this.lifecycle=o.lifecycle,this.restore=o.restore,this.stateSync=o.stateSync,this.references=o.references,this.worktreeStrategy=o.worktreeStrategy,this.worktreeDecisions=o.worktreeDecisions,this.runtimeBootstrap=o.runtimeBootstrap,this.worktreeMessages=o.worktreeMessages,this.maintenance=o.maintenance}static createServiceBundle(e,n){let r=new no,o=r.sessions,i=new Nr(n.store),s=new Lr,a=new Vr,d=new Gr(i.actionTokenStore,$e),l=new xr(o,i),u=new Ir({store:i,sessions:o,resolveSession:S=>l.resolveActive(S)}),c=new Qr(a,(S,I)=>u.applySessionPatch(S,I),{getPersistedSession:S=>i.getPersistedSession(S)}),p=new Jr,f=new Rr(S=>i.getPersistedSession(S)),g=new oo,h=new Mr({shouldRunWorktreeStrategy:S=>e.shouldRunWorktreeStrategy(S),isAlreadyMerged:S=>e.isAlreadyMerged(S),resolveWorktreeRepoDir:(S,I)=>e.resolveWorktreeRepoDir(S,I),getWorktreeCompletionState:(S,I,J,T)=>e.getWorktreeCompletionState(S,I,J,T),updatePersistedSession:(S,I)=>e.updatePersistedSession(S,I),dispatchSessionNotification:(S,I)=>e.dispatchSessionNotification(S,I),getOutputPreview:(S,I)=>e.getOutputPreview(S,I),originThreadLine:S=>e.originThreadLine(S),getWorktreeDecisionButtons:S=>e.getWorktreeDecisionButtons(S),makeOpenPrButton:S=>e.makeActionButton(S,"worktree-create-pr","Open PR"),worktreeSummaryProvider:n.worktreeSummaryProvider,worktreeMessages:g,enqueueMerge:(S,I,J)=>e.enqueueMerge(S,I,J),mergeBranch:Kn,spawnConflictResolver:async({session:S,worktreePath:I,prompt:J})=>e.spawn({prompt:J,workdir:I,name:`${S.name}-conflict-resolver`,harness:S.harnessName||se(),model:S.model,reasoningEffort:S.reasoningEffort,fastMode:S.fastMode,permissionMode:"bypassPermissions",multiTurn:!0,worktreeStrategy:"off",autoMergeParentSessionId:S.id,route:S.route,originChannel:S.originChannel,originThreadId:S.originThreadId,originAgentId:S.originAgentId,originSessionKey:S.originSessionKey},{notifyLaunch:!1}),runAutoPr:async(S,I)=>{let{makeAgentPrTool:J}=await Promise.resolve().then(()=>(pr(),Ra));return{success:(await J().execute("auto-pr",{session:S.id,base_branch:I}))?.meta?.success===!0}}}),y=new Yr(e.pendingAskUserQuestions,(S,I)=>e.dispatchSessionNotification(S,I),S=>{e.lastWaitingEventTimestamps.delete(S)},(S,I)=>d.getQuestionButtons(S,I)),k=new Zr(S=>e.buildRoutingProxy(S),(S,I)=>c.dispatch(S,I),(S,I)=>e.updatePersistedSession(S,I),S=>e.getWorktreeDecisionButtons(S)),R=new so({store:i,sessions:o,reminders:k,removeRuntimeSession:S=>r.remove(S),persistSession:(S,I)=>e.persistSession(S,I),clearRuntimeSessionState:S=>{e.lastWaitingEventTimestamps.delete(S),e.lastTurnCompleteMarkers.delete(S),e.lastTerminalWakeMarkers.delete(S)},resolveWorktreeRepoDir:(S,I)=>e.resolveWorktreeRepoDir(S,I),updatePersistedSession:(S,I)=>e.updatePersistedSession(S,I),getMaxPersistedSessions:()=>e.maxPersistedSessions});i.onActionTokensChanged(()=>e.syncActionTokenExpiryDeadline());let b=new eo({persistSession:S=>e.persistSession(S),clearWaitingTimestamp:S=>{e.lastWaitingEventTimestamps.delete(S)},handleWorktreeStrategy:S=>e.handleWorktreeStrategy(S),resolveWorktreeRepoDir:(S,I)=>e.resolveWorktreeRepoDir(S,I),updatePersistedSession:(S,I)=>e.updatePersistedSession(S,I),dispatchSessionNotification:(S,I)=>e.dispatchSessionNotification(S,I),notifySession:(S,I,J)=>e.notifySession(S,I,J),clearRetryTimersForSession:S=>a.clearRetryTimersForSession(S),hasTurnCompleteWakeMarker:S=>e.lastTurnCompleteMarkers.has(S),shouldEmitTurnCompleteWake:S=>e.shouldEmitTurnCompleteWake(S),shouldEmitTerminalWake:S=>e.shouldEmitTerminalWake(S),resolvePlanApprovalMode:S=>e.resolvePlanApprovalMode(S),getPlanApprovalButtons:(S,I)=>d.getPlanApprovalButtons(S,I),getResumeButtons:(S,I)=>d.getResumeButtons(S,I),getQuestionButtons:(S,I)=>d.getQuestionButtons(S,I),extractLastOutputLine:S=>e.extractLastOutputLine(S),getOutputPreview:(S,I)=>e.getOutputPreview(S,I),originThreadLine:S=>e.originThreadLine(S),debounceWaitingEvent:S=>e.debounceWaitingEvent(S),isAlreadyMerged:S=>e.isAlreadyMerged(S)}),A=new to({getPersistedSession:S=>i.getPersistedSession(S),resolveActiveSession:S=>l.resolveActive(S),resolveWorktreeRepoDir:(S,I)=>e.resolveWorktreeRepoDir(S,I),updatePersistedSession:(S,I)=>e.updatePersistedSession(S,I),dispatchNotification:(S,I)=>c.dispatch(S,I),buildRoutingProxy:S=>e.buildRoutingProxy(S)}),N=new ro({hydrateSpawnedSession:(S,I,J)=>{f.hydrateSpawnedSession(S,I,J)},markRunning:S=>{i.markRunning(S),e.onPersistedSessionChanged(i.getPersistedSession(S.id))},handleTerminal:async S=>e.onSessionTerminal(S),handleTurnEnd:(S,I)=>b.handleTurnEnd(S,I),formatLaunchWorkdirLabel:S=>e.formatLaunchWorkdirLabel(S),notifySession:(S,I,J)=>e.notifySession(S,I,J)});return{registry:r,sessions:o,store:i,metrics:s,wakeDispatcher:a,interactions:d,notifications:c,worktrees:p,questions:y,reminders:k,lifecycle:b,restore:f,stateSync:u,references:l,worktreeStrategy:h,worktreeDecisions:A,runtimeBootstrap:N,worktreeMessages:g,maintenance:R}}get persisted(){return this.store.persisted}get idIndex(){return this.store.idIndex}get nameIndex(){return this.store.nameIndex}uniqueName(e){return this.registry.uniqueName(e)}syncRuntimeGcDeadline(e){this.maintenance.syncRuntimeGcDeadline(e)}onPersistedSessionChanged(e){e&&(this.syncPersistedSessionMaintenance(e),this.enforcePersistedRetention())}syncPersistedSessionMaintenance(e){this.maintenance.syncPersistedSessionMaintenance(e)}syncActionTokenExpiryDeadline(){this.maintenance.syncActionTokenExpiryDeadline()}syncTmpOutputCleanupDeadline(e=Date.now()){this.maintenance.syncTmpOutputCleanupDeadline(e)}enforcePersistedRetention(){this.maintenance.enforcePersistedRetention()}bootstrapMaintenanceSchedules(){this.maintenance.bootstrapMaintenanceSchedules()}disposeMaintenance(){this.maintenance.dispose()}spawn(e,n={}){if(this.registry.activeSessionCount()>=this.maxSessions)throw new Error(`Max sessions reached (${this.maxSessions}). Use agent_sessions to list active sessions and agent_kill to end one.`);if(e.sessionIdOverride){let p=this.registry.get(e.sessionIdOverride);if(p?.status==="starting"||p?.status==="running")throw new Error(`Cannot reuse session ID ${e.sessionIdOverride}: that session is still ${p.status}.`);p&&this.registry.remove(p.id),this.lastWaitingEventTimestamps.delete(e.sessionIdOverride),this.lastTurnCompleteMarkers.delete(e.sessionIdOverride),this.lastTerminalWakeMarkers.delete(e.sessionIdOverride),this.maintenance.cancelRuntimeGc(e.sessionIdOverride)}let o=e.name||Rs(e.prompt),i=this.uniqueName(o);if(i!==o&&`${o}${i}`,!e.route?.provider||!e.route.target)throw new Error(`Cannot launch session "${i}": missing explicit route metadata.`);let s=this.restore.prepareSpawn(e,i),a=e.harness??"claude-code",d=this,l,u=a==="claude-code"&&!e.canUseTool?async(p,f)=>{if(!l)throw new Error("canUseTool called before session ID was set");return d.handleAskUserQuestion(l,f)}:e.canUseTool,c=new Gn({...e,workdir:s.actualWorkdir,systemPrompt:s.effectiveSystemPrompt,canUseTool:u},i);return l=c.id,this.registry.add(c),this.metrics.incrementLaunched(),this.runtimeBootstrap.initializeSession(c,s,e,n)}async spawnAndAwaitRunning(e,n={}){let r=this.spawn(e,n);return await this.waitForRunningSession(r),r}async waitForRunningSession(e){if(e.status==="running")return;if(nl.has(e.status))throw new Error(this.describeLaunchFailure(e));let n=e.on?.bind(e),r=e.off?.bind(e)??e.removeListener?.bind(e);if(!n||!r)throw new Error(`Session ${e.name} [${e.id}] did not expose lifecycle events during startup.`);await new Promise((o,i)=>{let s=(d,l)=>{if(l==="running"){a(),o();return}nl.has(l)&&(a(),i(new Error(this.describeLaunchFailure(e))))},a=()=>{r("statusChange",s)};n("statusChange",s)})}describeLaunchFailure(e){let n=e.killReason?` (reason: ${e.killReason})`:"",r=e.error||e.result?.result||`status=${e.status}${n}`;return`Session ${e.name} [${e.id}] failed to start: ${r}`}formatLaunchResult(e,n){return on({prompt:e.prompt,workdir:e.workdir,harness:e.harness,permissionMode:e.permissionMode??E.permissionMode,planApproval:e.planApproval,resumeSessionId:e.resumeSessionId,forkSession:e.forkSession,forceNewSession:e.forceNewSession,clearedPersistedCodexResume:e.clearedPersistedCodexResume},n)}shouldRunWorktreeStrategy(e){let n=e.lifecycle;return!(n==="starting"||n==="awaiting_plan_decision"||n==="awaiting_user_input"||e.pendingPlanApproval)}makeActionButton(e,n,r,o={}){return this.interactions.makeActionButton(e,n,r,o)}consumeActionToken(e){return this.interactions.consumeActionToken(e)}getActionToken(e){return this.interactions.getActionToken(e)}clearPlanDecisionTokens(e,n){this.interactions.clearPlanDecisionTokens(e,n)}isCurrentPendingPlanDecision(e,n){let r=this.resolve(e)??this.getPersistedSession(e);return nn(r,n)}dispatchPlanApprovalFallback(e,n,r){let o=new Date().toISOString();this.notifications.dispatch(e,{label:"plan-approval-fallback",idempotencyKey:`plan-approval:${e.id}:v${n??"unknown"}:fallback`,userMessage:Zt({session:e,summary:r}),notifyUser:"always",shouldDispatch:()=>this.isCurrentPendingPlanDecision(e.id,n),hooks:{onNotifyStarted:()=>{this.updatePersistedSession(e.id,{approvalPromptRequiredVersion:n,approvalPromptVersion:n,approvalPromptStatus:"sending",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"explicit_fallback_text",approvalPromptLastAttemptAt:o})},onNotifySucceeded:()=>{this.updatePersistedSession(e.id,{approvalPromptRequiredVersion:n,approvalPromptVersion:n,approvalPromptStatus:"fallback_delivered",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"explicit_fallback_text",approvalPromptLastAttemptAt:o,approvalPromptDeliveredAt:new Date().toISOString(),approvalPromptFailedAt:void 0})},onNotifyFailed:()=>{this.updatePersistedSession(e.id,{approvalPromptRequiredVersion:n,approvalPromptVersion:n,approvalPromptStatus:"failed",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"explicit_fallback_text",approvalPromptLastAttemptAt:o,approvalPromptFailedAt:new Date().toISOString()})}},wakeMessageOnNotifySuccess:wt(e,n,!0),wakeMessageOnNotifyFailed:Xr({session:e,planDecisionVersion:n})})}getWorktreeDecisionButtons(e,n={}){let r=this.resolve(e)??this.getPersistedSession(e);if(!(!r||r.worktreeStrategy==="delegate"&&n.allowDelegate!==!0))return this.interactions.getWorktreeDecisionButtons(e,r)}getWorktreeCompletionState(e,n,r,o){return this.worktrees.getCompletionState(e,n,r,o)}notifyWorktreeOutcome(e,n,r){this.notifications.notifyWorktreeOutcome(e,n,r)}requestPlanApprovalFromUser(e,n){let r=n.trim();if(!r)return"Error: summary must not be empty.";let o=Ri(r),i=this.resolve(e),s=i?void 0:this.getPersistedSession(e),a=i??s;if(!a)return`Error: Session "${e}" not found.`;if(!a.pendingPlanApproval)return`Error: Session "${e}" is not awaiting plan approval.`;let d=W(i??s??{id:e})??e;if(this.resolvePlanApprovalMode(a)!=="delegate")return`Error: Session "${e}" already uses direct user plan approval. Do not send a duplicate approval prompt.`;let l=a.actionablePlanDecisionVersion??a.planDecisionVersion;if(tn(a,l))return[`An actionable plan review prompt already exists for session ${a.name} [${d}].`,"Wait for the user's Approve, Revise, or Reject response.","Do not send a separate plain-text approval message."].join(" ");if(a.deliveryState==="notifying")return[`A plan approval prompt is already being delivered for session ${a.name} [${d}].`,"Wait for delivery to finish before retrying."].join(" ");let u=this.interactions.getPlanApprovalButtons(d,{...a,planDecisionVersion:l}),c=[`📋 [${a.name}] Plan v${l??"?"} needs your decision:`,"","Why this was escalated:","",o,"","Choose Approve, Revise, or Reject below."].join(`
|
|
241
|
+
`);return this.notifications.dispatch(this.buildRoutingProxy({id:d,name:a.name,sessionId:s?.sessionId,harnessSessionId:i?.harnessSessionId??s?.harnessSessionId,backendRef:i?.backendRef??s?.backendRef,route:i?.route??s?.route}),{label:"plan-approval",idempotencyKey:`plan-approval:${d}:v${l??"unknown"}:canonical`,userMessage:c,notifyUser:"always",buttons:u,hooks:{onNotifyStarted:()=>{this.updatePersistedSession(d,{approvalPromptRequiredVersion:l,approvalPromptStatus:"sending",approvalPromptVersion:l,approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptLastAttemptAt:new Date().toISOString()})},onNotifySucceeded:()=>{this.updatePersistedSession(d,{canonicalPlanPromptVersion:l,approvalPromptRequiredVersion:l,approvalPromptVersion:l,approvalPromptStatus:"delivered",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptDeliveredAt:new Date().toISOString(),approvalPromptFailedAt:void 0})},onNotifyFailed:()=>{this.updatePersistedSession(d,{approvalPromptRequiredVersion:l,approvalPromptVersion:l,approvalPromptStatus:"failed",approvalPromptTransport:"direct-message",approvalPromptMessageKind:"canonical_buttons",approvalPromptFailedAt:new Date().toISOString()})}},shouldDispatch:()=>this.isCurrentPendingPlanDecision(d,l),onUserNotifyFailed:()=>this.dispatchPlanApprovalFallback(this.buildRoutingProxy({id:d,name:a.name,sessionId:s?.sessionId,harnessSessionId:i?.harnessSessionId??s?.harnessSessionId,backendRef:i?.backendRef??s?.backendRef,route:i?.route??s?.route}),l,o),wakeMessageOnNotifySuccess:wt({id:d,name:a.name},l)}),[`Canonical plan approval prompt sent for session ${a.name} [${d}].`,"Wait for the user's Approve, Revise, or Reject response.","Do not send a separate plain-text approval message."].join(" ")}requestWorktreeDecisionFromUser(e,n){let r=n.trim();if(!r)return"Error: summary must not be empty.";let o=this.resolve(e),i=this.getPersistedSession(e),s=o??i;if(!s)return`Error: Session "${e}" not found.`;if(s.worktreeStrategy!=="delegate")return`Error: Session "${e}" already uses direct user worktree decisions. Do not send a duplicate decision prompt.`;if(!(!!("pendingWorktreeDecisionSince"in s?s.pendingWorktreeDecisionSince:void 0)||s.worktreeState==="pending_decision"||s.worktreeLifecycle?.state==="pending_decision"))return`Error: Session "${e}" is not awaiting a delegated worktree decision.`;let l=W(o??i??{id:e})??e,u=o?.worktreePath??i?.worktreePath,c=o?.worktreeBranch??i?.worktreeBranch,p=this.resolveWorktreeRepoDir(o?.originalWorkdir??i?.workdir,u);if(!u)return`Error: Session "${e}" has no managed worktree path.`;if(!c)return`Error: Session "${e}" has no managed worktree branch.`;if(!p)return`Error: Session "${e}" has no resolvable repository root for worktree ${u}.`;let f=o?.worktreeBaseBranch??i?.worktreeBaseBranch??be(p),g=xe(p,c,f);if(!g)return`Error: Could not compute worktree diff summary for session "${e}".`;let h=this.getWorktreeDecisionButtons(l,{allowDelegate:!0});if(!h||h.length===0)return`Error: Could not create worktree decision buttons for session "${e}".`;let y=r.split(/\r?\n/).map(k=>k.replace(/^[-*]\s+/,"").trim()).filter(k=>k.length>0);return this.notifications.dispatch(this.buildRoutingProxy({id:l,name:s.name,sessionId:i?.sessionId,harnessSessionId:o?.harnessSessionId??i?.harnessSessionId,backendRef:o?.backendRef??i?.backendRef,route:o?.route??i?.route}),this.worktreeMessages.buildAskNotification({session:{id:l,name:s.name,worktreePrTargetRepo:o?.worktreePrTargetRepo??i?.worktreePrTargetRepo},branchName:c,baseBranch:f,diffSummary:g,summaryLines:y,buttons:h})),[`Canonical worktree decision prompt sent for session ${s.name} [${l}].`,"Wait for the user's Merge, Open PR, Later, or Discard response.","Do not send a separate plain-text worktree decision message."].join(" ")}buildRoutingProxy(e){return{id:W(e)??C(e)??e.harnessSessionId??"unknown-session",name:e.name,harnessSessionId:e.harnessSessionId,backendRef:e.backendRef?{...e.backendRef}:void 0,route:e.route}}resolveWorktreeRepoDir(e,n){return e&&(!n||!Ar(e,n))||!n?e:Bn(n)??e}formatLaunchWorkdirLabel(e){if(!e.worktreePath)return e.workdir;let n=this.resolveWorktreeRepoDir(e.originalWorkdir,e.worktreePath);return!n||n===e.worktreePath?e.worktreePath:`${e.worktreePath} (worktree of ${n})`}async dismissWorktree(e){return this.worktreeDecisions.dismissWorktree(e)}snoozeWorktreeDecision(e,n){return this.worktreeDecisions.snoozeWorktreeDecision(e,n)}async handleWorktreeStrategy(e){return this.worktreeStrategy.handleWorktreeStrategy(e)}async onSessionTerminal(e){if(e.autoMergeParentSessionId){await this.handleAutoMergeResolverTerminal(e);return}return this.lifecycle.handleSessionTerminal(e)}async handleAutoMergeResolverTerminal(e){this.persistSession(e),this.lastWaitingEventTimestamps.delete(e.id),this.wakeDispatcher.clearRetryTimersForSession(e.id);let n=e.autoMergeParentSessionId;if(!n)return;let r=this.resolve(n),o=this.getPersistedSession(n),i=r??(o?this.buildRoutingProxy({id:o.sessionId,name:o.name,sessionId:o.sessionId,harnessSessionId:o.harnessSessionId,backendRef:o.backendRef,route:o.route}):void 0);if(!i){`${e.id}${n}`;return}if(e.status==="completed"&&r){this.updatePersistedSession(n,{autoMergeResolverSessionId:void 0}),await this.handleWorktreeStrategy(r);return}let s=r?.worktreeBranch??o?.worktreeBranch??"unknown",a=r?.worktreePath??o?.worktreePath??"(unknown worktree)",d=r?.worktreeBaseBranch??o?.worktreeBaseBranch,l=r?.worktreePrTargetRepo??o?.worktreePrTargetRepo,u=r?.worktreePushRemote??o?.worktreePushRemote;this.updatePersistedSession(n,lr({worktreeBaseBranch:d,worktreePrTargetRepo:l,worktreePushRemote:u},{clearResolverSessionId:!0,notes:[e.status==="completed"?"auto_merge_conflict_resolver_completed_without_retry_target":"auto_merge_conflict_resolver_failed"]})),this.dispatchSessionNotification(i,{label:"worktree-merge-conflict-resolver-failed",idempotencyKey:`worktree-merge-conflict-resolver-failed:${n}:${e.id}`,userMessage:[`⚠️ [${i.name}] Auto-merge conflict resolution did not complete successfully.`,`Branch \`${s}\` was preserved for manual follow-up in ${a}.`,e.status==="completed"?"The resolver finished, but the original session could not be resumed for the merge retry.":`Resolver session ${e.name} ended with status=${e.status}.`].join(`
|
|
242
|
+
`),buttons:[[this.makeActionButton(n,"worktree-create-pr","Open PR")]]})}persistSession(e,n={}){let r=n.scheduleRuntimeGc??!0;this.store.hasRecordedSession(e.id)||this.metrics.recordSession(e),this.store.persistTerminal(e),r&&this.syncRuntimeGcDeadline(e),this.onPersistedSessionChanged(this.store.getPersistedSession(e.id)),this.syncTmpOutputCleanupDeadline()}getMetrics(){return this.metrics.getMetrics()}notifySession(e,n,r="notification"){this.dispatchSessionNotification(e,{label:r,idempotencyKey:r==="agent-respond"?void 0:`notify:${e.id}:${r}:${n}`,userMessage:n,notifyUser:"always"})}sendPlanOffer(e){let n=this.interactions.getPlanOfferButtons({offerId:e.offerId,route:e.route,planName:e.planName,planPrompt:e.planPrompt,planWorkdir:e.planWorkdir,planWorktreeStrategy:e.planWorktreeStrategy});this.dispatchSessionNotification(this.buildRoutingProxy({id:e.offerId,route:e.route}),{label:"plan-offer",idempotencyKey:`plan-offer:${e.offerId}`,userMessage:e.text,notifyUser:"always",buttons:n})}emitGoalTaskUpdate(e,n,r="goal-task"){let o=e.sessionId??e.id,i=this.buildRoutingProxy({id:o,name:e.sessionName??e.name,route:e.route});i.originChannel=e.originChannel,i.originThreadId=e.originThreadId,i.originSessionKey=e.originSessionKey;let s=r==="goal-task-succeeded",a=[`✅ [${e.name}] Goal task succeeded`,e.sessionId?`Session: ${e.sessionName??e.name} [${e.sessionId}]`:void 0].filter(l=>!!l).join(`
|
|
243
|
+
`),d=l=>Si({sessionId:o,sessionName:e.sessionName,taskName:e.name,summary:n,originThreadLine:It(i),canonicalStatusDelivered:l});this.dispatchSessionNotification(i,{label:r,idempotencyKey:`goal:${e.id}:${r}:${s?"success":n}`,userMessage:s?a:n,notifyUser:"always",completionSummary:s?{required:!0,producer:"goal",outcomeKey:`goal:${e.id}`}:void 0,completionWakeSummaryRequired:s,completionWakeOutcomeKey:s?`goal:${e.id}`:void 0,wakeMessageOnNotifySuccess:s?d(!0):void 0,wakeMessageOnNotifyFailed:s?d(!1):void 0})}launchPlanOffer(e){let n=e.route??{provider:"system",target:"system"};return this.spawn({prompt:e.prompt,workdir:e.workdir,name:e.name,harness:se(),permissionMode:"plan",planApproval:"ask",worktreeStrategy:e.worktreeStrategy??"off",multiTurn:!0,route:n,originChannel:this.originChannelFromRoute(n),originThreadId:n.threadId,originSessionKey:n.sessionKey})}dispatchSessionNotification(e,n){this.notifications.dispatch(e,n)}originChannelFromRoute(e){return e.accountId?`${e.provider}|${e.accountId}|${e.target}`:`${e.provider}|${e.target}`}debounceWaitingEvent(e){let n=Date.now(),r=this.lastWaitingEventTimestamps.get(e);return r&&n-r<xg?!1:(this.lastWaitingEventTimestamps.set(e,n),!0)}originThreadLine(e){return It(e)}extractLastOutputLine(e){return e.getOutput(3).filter(o=>o.trim()).pop()?.trim()||void 0}getOutputPreview(e,n=1e3){return Zd(e,n)}resolvePlanApprovalMode(e){return e.planApproval??E.planApproval??"delegate"}shouldEmitTurnCompleteWake(e){let n=`${e.result?.session_id??""}|${e.result?.num_turns??0}|${e.result?.duration_ms??0}`;return this.lastTurnCompleteMarkers.get(e.id)===n?(`${e.id}${n}`,!1):(this.lastTurnCompleteMarkers.set(e.id,n),!0)}shouldEmitTerminalWake(e){let n=`${e.status}|${e.completedAt??0}|${e.result?.session_id??""}|${e.result?.num_turns??0}|${e.killReason}`;return this.lastTerminalWakeMarkers.get(e.id)===n?!1:(this.lastTerminalWakeMarkers.set(e.id,n),!0)}resolve(e){return this.references.resolveActive(e)}get(e){return this.registry.get(e)}list(e){let n=this.registry.list();return e&&e!=="all"&&(n=n.filter(r=>r.status===e)),n.sort((r,o)=>o.startedAt-r.startedAt)}kill(e,n){let r=this.registry.get(e);if(!r)return!1;if(r.pendingPlanApproval){this.clearPlanDecisionTokens(r.id);let o={lifecycle:"terminal",runtimeState:"stopped",pendingPlanApproval:!1,planApprovalContext:void 0,approvalState:r.approvalState==="pending"?"rejected":r.approvalState,planDecisionVersion:(r.planDecisionVersion??0)+1,actionablePlanDecisionVersion:void 0,canonicalPlanPromptVersion:void 0,approvalPromptRequiredVersion:void 0,approvalPromptVersion:void 0,approvalPromptStatus:"not_sent",approvalPromptTransport:"none",approvalPromptMessageKind:"none",approvalPromptLastAttemptAt:void 0,approvalPromptDeliveredAt:void 0,approvalPromptFailedAt:void 0};r.applyControlPatch(o),Object.assign(r,o),this.updatePersistedSession(r.id,o)}return r.kill(n??"user"),!0}killAll(e="user"){for(let n of this.sessions.values())Ig.has(n.status)&&this.kill(n.id,e)}resolveBackendConversationId(e){return this.references.resolveBackendConversationId(e)}resolveHarnessSessionId(e){return this.resolveBackendConversationId(e)}getPersistedSession(e){return this.references.getPersistedSession(e)}isAlreadyMerged(e){if(!e)return!1;let n=this.store.getPersistedSession(e);return n?.worktreeMerged===!0||n?.worktreeLifecycle?.state==="merged"||n?.worktreeLifecycle?.state==="released"}async enqueueMerge(e,n,r){return this.mergeQueue.enqueue(e,n,r)}updatePersistedSession(e,n){let r=this.stateSync.applySessionPatch(e,n);return r&&this.onPersistedSessionChanged(this.store.getPersistedSession(e)),r}listPersistedSessions(){return this.store.listPersistedSessions()}async handleAskUserQuestion(e,n){let r=this.sessions.get(e);if(!r)throw new Error(`Session "${e}" not found for AskUserQuestion intercept`);return this.questions.handleAskUserQuestion(r,n)}resolveAskUserQuestion(e,n){this.questions.resolveAskUserQuestion(e,n)}async resolvePendingInputOption(e,n){let r=this.sessions.get(e);return r&&await r.submitPendingInputOption(n)?(this.lastWaitingEventTimestamps.delete(e),!0):(this.questions.resolveAskUserQuestion(e,n),!0)}dispose(){this.disposeMaintenance(),this.questions.dispose(),this.notifications.dispose()}};O();te();import{definePluginEntry as rl}from"openclaw/plugin-sdk/plugin-entry";function Eg(t){let e=parseInt(process.env.OPENCLAW_WORKTREE_CLEANUP_AGE_HOURS??"168",10)||168,n=e*60*60*1e3,r=Date.now()-n,o=new Set(t.listPersistedSessions().map(d=>d.worktreePath).filter(d=>typeof d=="string"&&d.length>0)),i=new Set,s=process.env.OPENCLAW_WORKTREE_DIR??E.worktreeDir;if(s)i.add(s);else for(let d of t.listPersistedSessions())if(d.workdir)try{let l=_g("git",["rev-parse","--show-toplevel"],{cwd:d.workdir,timeout:5e3,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();l&&i.add(ol(l,".worktrees"))}catch{}if(i.size===0)return;let a=0;for(let d of i)try{let l=Tg(d);for(let u of l){if(!u.startsWith("openclaw-worktree-"))continue;let c=ol(d,u);try{let p=Cg(c);if(!p.isDirectory()||p.mtimeMs>r||o.has(c))continue;Mg(c,{recursive:!0,force:!0}),a++}catch(p){`${c}${p instanceof Error?p.message:String(p)}`}}}catch{}a>0&&`${a}${e}`}function $g(t){let e=null,n=null,r=!1,o=!1,i=t.registerTool;dt(t.runtime);let s=c=>{if(r){c&&!o&&(dt(t.runtime,c.config),o=!0);return}let p=t.pluginConfig??{};Gi(p),c?(dt(t.runtime,c.config),o=!0):(dt(t.runtime),o=!1),e=new ao(E.maxSessions,E.maxPersistedSessions,{worktreeSummaryProvider:Rd()}),n=new br(e),fo(e),go(n),n.start(),Eg(e),e.bootstrapMaintenanceSchedules(),r=!0},a=()=>{n&&n.stop(),e&&e.killAll("shutdown"),e&&e.dispose(),n=null,e=null,r=!1,o=!1,dt(void 0),go(null),fo(null)},d=(c,p)=>{i(f=>(s(),c(f)),p)},l={...t,registerCommand(c){t.registerCommand({...c,handler:p=>(s(),c.handler(p))})}},u=c=>{let p=Ba(c);t.registerInteractiveHandler({...p,handler:async f=>(s(),p.handler(f))})};d(c=>$s(c),{optional:!1,name:"agent_launch"}),d(c=>ia(c),{optional:!1,name:"agent_sessions"}),d(c=>sa(c),{optional:!1,name:"agent_kill"}),d(c=>Jn(c),{optional:!1,name:"agent_output"}),d(c=>pa(c),{optional:!1,name:"agent_respond"}),d(c=>ma(c),{optional:!1,name:"agent_request_plan_approval"}),d(c=>fa(c),{optional:!1,name:"agent_request_worktree_decision"}),d(c=>ha(c),{optional:!1,name:"agent_send_plan_offer"}),d(c=>Sa(c),{optional:!1,name:"agent_stats"}),d(c=>or(c),{optional:!1,name:"agent_merge"}),d(c=>Qt(c),{optional:!1,name:"agent_pr"}),d(c=>Ia(c),{optional:!1,name:"agent_worktree_cleanup"}),d(c=>xa(c),{optional:!1,name:"agent_worktree_status"}),d(c=>Ta(c),{optional:!1,name:"goal_launch"}),d(c=>Ma(c),{optional:!1,name:"goal_status"}),d(c=>_a(c),{optional:!1,name:"goal_stop"}),d(c=>Ea(c),{optional:!1,name:"goal_edit"}),u("telegram"),u("discord"),qa(l),Ka(l),Ua(l),Va(l),Ga(l),Ha(l),za(l),Qa(l),Ja(l),Za(l),t.registerService({id:"openclaw-code-agent",start:s,stop:a})}var HA=rl({id:"openclaw-code-agent",name:"OpenClaw Code Agent",description:"Multi-session coding-agent orchestration from OpenClaw chat",register:$g});export{HA as default,$g as register};
|